mirror of
https://github.com/certbot/certbot.git
synced 2026-07-28 08:05:31 +02:00
Merge remote-tracking branch 'origin/denest' into experiment
This commit is contained in:
+59
-29
@@ -175,7 +175,7 @@ def _determine_account(config):
|
||||
acc = accounts[0]
|
||||
else: # no account registered yet
|
||||
if config.email is None and not config.register_unsafely_without_email:
|
||||
config.email = display_ops.get_email()
|
||||
config.namespace.email = display_ops.get_email()
|
||||
|
||||
def _tos_cb(regr):
|
||||
if config.tos:
|
||||
@@ -197,7 +197,7 @@ def _determine_account(config):
|
||||
raise errors.Error(
|
||||
"Unable to register an account with ACME server")
|
||||
|
||||
config.account = acc.id
|
||||
config.namespace.account = acc.id
|
||||
return acc, acme
|
||||
|
||||
|
||||
@@ -229,7 +229,7 @@ def _find_duplicative_certs(config, domains):
|
||||
candidate_lineage = storage.RenewableCert(renewal_file, cli_config)
|
||||
except (errors.CertStorageError, IOError):
|
||||
logger.warning("Renewal conf file %s is broken. Skipping.", renewal_file)
|
||||
logger.info("Traceback was:\n%s", traceback.format_exc())
|
||||
logger.debug("Traceback was:\n%s", traceback.format_exc())
|
||||
continue
|
||||
# TODO: Handle these differently depending on whether they are
|
||||
# expired or still valid?
|
||||
@@ -248,8 +248,10 @@ def _find_duplicative_certs(config, domains):
|
||||
|
||||
|
||||
def _treat_as_renewal(config, domains):
|
||||
"""Determine whether there are duplicated names and how to handle them
|
||||
(renew, reinstall, newcert, or no action).
|
||||
"""Determine whether there are duplicated names and how to handle
|
||||
them (renew, reinstall, newcert, or raising an error to stop
|
||||
the client run if the user chooses to cancel the operation when
|
||||
prompted).
|
||||
|
||||
:returns: Two-element tuple containing desired new-certificate behavior as
|
||||
a string token ("reinstall", "renew", or "newcert"), plus either
|
||||
@@ -457,8 +459,8 @@ def _auth_from_domains(le_client, config, domains, lineage=None):
|
||||
lineage.save_successor(
|
||||
lineage.latest_common_version(), OpenSSL.crypto.dump_certificate(
|
||||
OpenSSL.crypto.FILETYPE_PEM, new_certr.body.wrapped),
|
||||
new_key.pem, crypto_util.dump_pyopenssl_chain(new_chain))
|
||||
|
||||
new_key.pem, crypto_util.dump_pyopenssl_chain(new_chain),
|
||||
configuration.RenewerConfiguration(config.namespace))
|
||||
lineage.update_all_links_to(lineage.latest_common_version())
|
||||
# TODO: Check return value of save_successor
|
||||
# TODO: Also update lineage renewal config with any relevant
|
||||
@@ -725,7 +727,15 @@ def install(config, plugins):
|
||||
le_client.enhance_config(domains, config)
|
||||
|
||||
|
||||
def _restore_required_config_elements(full_path, config, renewalparams):
|
||||
def _restore_required_config_elements(config, renewalparams):
|
||||
"""Sets non-plugin specific values in config from renewalparams
|
||||
|
||||
:param configuration.NamespaceConfig config: configuration for the
|
||||
current lineage
|
||||
:param configobj.Section renewalparams: Parameters from the renewal
|
||||
configuration file that defines this lineage
|
||||
|
||||
"""
|
||||
# string-valued items to add if they're present
|
||||
for config_item in STR_CONFIG_ITEMS:
|
||||
if config_item in renewalparams:
|
||||
@@ -742,12 +752,18 @@ def _restore_required_config_elements(full_path, config, renewalparams):
|
||||
value = int(renewalparams[config_item])
|
||||
setattr(config.namespace, config_item, value)
|
||||
except ValueError:
|
||||
logger.warning("Renewal configuration file %s specifies "
|
||||
"a non-numeric value for %s. Skipping.",
|
||||
full_path, config_item)
|
||||
raise
|
||||
raise errors.Error(
|
||||
"Expected a numeric value for {0}".format(config_item))
|
||||
|
||||
def _restore_plugin_configs(config, renewalparams):
|
||||
"""Sets plugin specific values in config from renewalparams
|
||||
|
||||
:param configuration.NamespaceConfig config: configuration for the
|
||||
current lineage
|
||||
:param configobj.Section renewalparams: Parameters from the renewal
|
||||
configuration file that defines this lineage
|
||||
|
||||
"""
|
||||
# Now use parser to get plugin-prefixed items with correct types
|
||||
# XXX: the current approach of extracting only prefixed items
|
||||
# related to the actually-used installer and authenticator
|
||||
@@ -780,7 +796,7 @@ def _restore_plugin_configs(config, renewalparams):
|
||||
return True
|
||||
|
||||
|
||||
def _reconstitute(full_path, config):
|
||||
def _reconstitute(config, full_path):
|
||||
"""Try to instantiate a RenewableCert, updating config with relevant items.
|
||||
|
||||
This is specifically for use in renewal and enforces several checks
|
||||
@@ -788,12 +804,18 @@ def _reconstitute(full_path, config):
|
||||
request. The config argument is modified by including relevant options
|
||||
read from the renewal configuration file.
|
||||
|
||||
:param configuration.NamespaceConfig config: configuration for the
|
||||
current lineage
|
||||
:param str full_path: Absolute path to the configuration file that
|
||||
defines this lineage
|
||||
|
||||
:returns: the RenewableCert object or None if a fatal error occurred
|
||||
:rtype: `storage.RenewableCert` or NoneType
|
||||
"""
|
||||
|
||||
"""
|
||||
try:
|
||||
renewal_candidate = storage.RenewableCert(full_path, config)
|
||||
renewal_candidate = storage.RenewableCert(
|
||||
full_path, configuration.RenewerConfiguration(config))
|
||||
except (errors.CertStorageError, IOError):
|
||||
logger.warning("Renewal configuration file %s is broken. Skipping.", full_path)
|
||||
logger.info("Traceback was:\n%s", traceback.format_exc())
|
||||
@@ -810,11 +832,13 @@ def _reconstitute(full_path, config):
|
||||
# Now restore specific values along with their data types, if
|
||||
# those elements are present.
|
||||
try:
|
||||
_restore_required_config_elements(full_path, config, renewalparams)
|
||||
_restore_required_config_elements(config, renewalparams)
|
||||
_restore_plugin_configs(config, renewalparams)
|
||||
except ValueError:
|
||||
# There was a data type error which has already been
|
||||
# logged.
|
||||
except (ValueError, errors.Error) as error:
|
||||
logger.warning(
|
||||
"An error occured while parsing %s. The error was %s. "
|
||||
"Skipping the file.", full_path, error.message)
|
||||
logger.debug("Traceback was:\n%s", traceback.format_exc())
|
||||
return None
|
||||
|
||||
# webroot_map is, uniquely, a dict, and the general-purpose
|
||||
@@ -840,14 +864,13 @@ def _renewal_conf_files(config):
|
||||
"""Return /path/to/*.conf in the renewal conf directory"""
|
||||
return glob.glob(os.path.join(config.renewal_configs_dir, "*.conf"))
|
||||
|
||||
def _rc_from_config(config):
|
||||
def _copy_nsconfig(config):
|
||||
ns = copy.deepcopy(config.namespace)
|
||||
new_config = configuration.NamespaceConfig(ns)
|
||||
return configuration.RenewerConfiguration(new_config)
|
||||
return new_config
|
||||
|
||||
def renew(cli_config, unused_plugins):
|
||||
def renew(config, unused_plugins):
|
||||
"""Renew previously-obtained certificates."""
|
||||
config = _rc_from_config(cli_config)
|
||||
if config.domains != []:
|
||||
raise errors.Error("Currently, the renew verb is only capable of "
|
||||
"renewing all installed certificates that are due "
|
||||
@@ -856,19 +879,24 @@ def renew(cli_config, unused_plugins):
|
||||
"renew specific certificates, use the certonly "
|
||||
"command. The renew verb may provide other options "
|
||||
"for selecting certificates to renew in the future.")
|
||||
for renewal_file in _renewal_conf_files(config):
|
||||
if config.csr is not None:
|
||||
raise errors.Error("Currently, the renew verb cannot be used when "
|
||||
"specifying a CSR file. Please try the certonly "
|
||||
"command instead.")
|
||||
config.noninteractive_mode = True
|
||||
renewer_config = configuration.RenewerConfiguration(config)
|
||||
for renewal_file in _renewal_conf_files(renewer_config):
|
||||
if not renewal_file.endswith(".conf"):
|
||||
continue
|
||||
print("Processing " + renewal_file)
|
||||
# XXX: does this succeed in making a fully independent config object
|
||||
# each time?
|
||||
config = _rc_from_config(cli_config)
|
||||
config.noninteractive_mode = True
|
||||
lineage_config = _copy_nsconfig(config)
|
||||
|
||||
# Note that this modifies config (to add back the configuration
|
||||
# elements from within the renewal configuration file).
|
||||
try:
|
||||
renewal_candidate = _reconstitute(renewal_file, config)
|
||||
renewal_candidate = _reconstitute(lineage_config, renewal_file)
|
||||
except Exception as e: # pylint: disable=broad-except
|
||||
# reconstitute encountered an unanticipated problem.
|
||||
logger.warning("Renewal configuration file %s produced an "
|
||||
@@ -881,14 +909,14 @@ def renew(cli_config, unused_plugins):
|
||||
# already been logged. Go on to the next config.
|
||||
continue
|
||||
# XXX: ensure that each call here replaces the previous one
|
||||
zope.component.provideUtility(config)
|
||||
zope.component.provideUtility(lineage_config)
|
||||
|
||||
print("Trying...")
|
||||
# Because obtain_cert itself indirectly decides whether to renew
|
||||
# or not, we couldn't currently make a UI/logging distinction at
|
||||
# this stage to indicate whether renewal was actually attempted
|
||||
# (or successful).
|
||||
obtain_cert(config, plugins_disco.PluginsRegistry.find_all(),
|
||||
obtain_cert(lineage_config, plugins_disco.PluginsRegistry.find_all(),
|
||||
renewal_candidate)
|
||||
|
||||
def revoke(config, unused_plugins): # TODO: coop with renewal config
|
||||
@@ -1704,6 +1732,8 @@ def main(cli_args=sys.argv[1:]):
|
||||
displayer = display_util.NoninteractiveDisplay(sys.stdout)
|
||||
elif config.text_mode:
|
||||
displayer = display_util.FileDisplay(sys.stdout)
|
||||
elif config.verb == "renew":
|
||||
displayer = display_util.NoninteractiveDisplay(sys.stdout)
|
||||
else:
|
||||
displayer = display_util.NcursesDisplay()
|
||||
zope.component.provideUtility(displayer)
|
||||
|
||||
+5
-15
@@ -249,7 +249,7 @@ class Client(object):
|
||||
|
||||
`.register` must be called before `.obtain_certificate`
|
||||
|
||||
:param set domains: domains to get a certificate
|
||||
:param list domains: domains to get a certificate
|
||||
|
||||
:returns: `.CertificateResource`, certificate chain (as
|
||||
returned by `.fetch_chain`), and newly generated private key
|
||||
@@ -282,23 +282,13 @@ class Client(object):
|
||||
"""
|
||||
certr, chain, key, _ = self.obtain_certificate(domains)
|
||||
|
||||
# XXX: We clearly need a more general and correct way of getting
|
||||
# options into the configobj for the RenewableCert instance.
|
||||
# This is a quick-and-dirty way to do it to allow integration
|
||||
# testing to start. (Note that the config parameter to new_lineage
|
||||
# ideally should be a ConfigObj, but in this case a dict will be
|
||||
# accepted in practice.)
|
||||
params = vars(self.config.namespace)
|
||||
config = {}
|
||||
cli_config = configuration.RenewerConfiguration(self.config.namespace)
|
||||
|
||||
if (cli_config.config_dir != constants.CLI_DEFAULTS["config_dir"] or
|
||||
cli_config.work_dir != constants.CLI_DEFAULTS["work_dir"]):
|
||||
if (self.config.config_dir != constants.CLI_DEFAULTS["config_dir"] or
|
||||
self.config.work_dir != constants.CLI_DEFAULTS["work_dir"]):
|
||||
logger.warning(
|
||||
"Non-standard path(s), might not work with crontab installed "
|
||||
"by your operating system package manager")
|
||||
|
||||
if cli_config.dry_run:
|
||||
if self.config.dry_run:
|
||||
logger.info("Dry run: Skipping creating new lineage for %s",
|
||||
domains[0])
|
||||
return None
|
||||
@@ -307,7 +297,7 @@ class Client(object):
|
||||
domains[0], OpenSSL.crypto.dump_certificate(
|
||||
OpenSSL.crypto.FILETYPE_PEM, certr.body.wrapped),
|
||||
key.pem, crypto_util.dump_pyopenssl_chain(chain),
|
||||
params, config, cli_config)
|
||||
configuration.RenewerConfiguration(self.config.namespace))
|
||||
|
||||
def save_certificate(self, certr, chain_cert,
|
||||
cert_path, chain_path, fullchain_path):
|
||||
|
||||
@@ -84,15 +84,10 @@ class RenewerConfiguration(object):
|
||||
|
||||
def __init__(self, namespace):
|
||||
self.namespace = namespace
|
||||
# We're done setting up the attic. Now pull up the ladder after ourselves...
|
||||
self.__setattr__ = self.__setattr_implementation__
|
||||
|
||||
def __getattr__(self, name):
|
||||
return getattr(self.namespace, name)
|
||||
|
||||
def __setattr_implementation__(self, var, value):
|
||||
return self.namespace.__setattr__(var, value)
|
||||
|
||||
@property
|
||||
def archive_dir(self): # pylint: disable=missing-docstring
|
||||
return os.path.join(self.namespace.config_dir, constants.ARCHIVE_DIR)
|
||||
|
||||
+79
-31
@@ -50,6 +50,68 @@ def add_time_interval(base_time, interval, textparser=parsedatetime.Calendar()):
|
||||
return textparser.parseDT(interval, base_time, tzinfo=tzinfo)[0]
|
||||
|
||||
|
||||
def write_renewal_config(filename, target, cli_config):
|
||||
"""Writes a renewal config file with the specified name and values.
|
||||
|
||||
:param str filename: Absolute path to the config file
|
||||
:param dict target: Maps ALL_FOUR to their symlink paths
|
||||
:param .RenewerConfiguration cli_config: parsed command line
|
||||
arguments
|
||||
|
||||
:returns: Configuration object for the new config file
|
||||
:rtype: configobj.ConfigObj
|
||||
|
||||
"""
|
||||
# create_empty creates a new config file if filename does not exist
|
||||
config = configobj.ConfigObj(filename, create_empty=True)
|
||||
for kind in ALL_FOUR:
|
||||
config[kind] = target[kind]
|
||||
|
||||
# XXX: We clearly need a more general and correct way of getting
|
||||
# options into the configobj for the RenewableCert instance.
|
||||
# This is a quick-and-dirty way to do it to allow integration
|
||||
# testing to start. (Note that the config parameter to new_lineage
|
||||
# ideally should be a ConfigObj, but in this case a dict will be
|
||||
# accepted in practice.)
|
||||
renewalparams = vars(cli_config.namespace)
|
||||
if renewalparams:
|
||||
config["renewalparams"] = renewalparams
|
||||
config.comments["renewalparams"] = ["",
|
||||
"Options and defaults used"
|
||||
" in the renewal process"]
|
||||
|
||||
# TODO: add human-readable comments explaining other available
|
||||
# parameters
|
||||
logger.debug("Writing new config %s.", filename)
|
||||
config.write()
|
||||
return config
|
||||
|
||||
|
||||
def update_configuration(lineagename, target, cli_config):
|
||||
"""Modifies lineagename's config to contain the specified values.
|
||||
|
||||
:param str lineagename: Name of the lineage being modified
|
||||
:param dict target: Maps ALL_FOUR to their symlink paths
|
||||
:param .RenewerConfiguration cli_config: parsed command line
|
||||
arguments
|
||||
|
||||
:returns: Configuration object for the updated config file
|
||||
:rtype: configobj.ConfigObj
|
||||
|
||||
"""
|
||||
config_filename = os.path.join(
|
||||
cli_config.renewal_configs_dir, lineagename) + ".conf"
|
||||
temp_filename = config_filename + ".new"
|
||||
|
||||
# If an existing tempfile exists, delete it
|
||||
if os.path.exists(temp_filename):
|
||||
os.unlink(temp_filename)
|
||||
write_renewal_config(temp_filename, target, cli_config)
|
||||
os.rename(temp_filename, config_filename)
|
||||
|
||||
return configobj.ConfigObj(config_filename)
|
||||
|
||||
|
||||
class RenewableCert(object): # pylint: disable=too-many-instance-attributes
|
||||
"""Renewable certificate.
|
||||
|
||||
@@ -589,9 +651,8 @@ class RenewableCert(object): # pylint: disable=too-many-instance-attributes
|
||||
return False
|
||||
|
||||
@classmethod
|
||||
def new_lineage(cls, lineagename, cert, privkey, chain,
|
||||
renewalparams=None, config=None, cli_config=None):
|
||||
# pylint: disable=too-many-locals,too-many-arguments
|
||||
def new_lineage(cls, lineagename, cert, privkey, chain, cli_config):
|
||||
# pylint: disable=too-many-locals
|
||||
"""Create a new certificate lineage.
|
||||
|
||||
Attempts to create a certificate lineage -- enrolled for
|
||||
@@ -611,26 +672,13 @@ class RenewableCert(object): # pylint: disable=too-many-instance-attributes
|
||||
:param str cert: the initial certificate version in PEM format
|
||||
:param str privkey: the private key in PEM format
|
||||
:param str chain: the certificate chain in PEM format
|
||||
:param configobj.ConfigObj renewalparams: parameters that
|
||||
should be used when instantiating authenticator and installer
|
||||
objects in the future to attempt to renew this cert or deploy
|
||||
new versions of it
|
||||
:param configobj.ConfigObj config: renewal configuration
|
||||
defaults, affecting, for example, the locations of the
|
||||
directories where the associated files will be saved
|
||||
:param .RenewerConfiguration cli_config: parsed command line
|
||||
arguments
|
||||
|
||||
:returns: the newly-created RenewalCert object
|
||||
:rtype: :class:`storage.renewableCert`"""
|
||||
|
||||
config = config_with_defaults(config)
|
||||
# This attempts to read the renewer config file and augment or replace
|
||||
# the renewer defaults with any options contained in that file. If
|
||||
# renewer_config_file is undefined or if the file is nonexistent or
|
||||
# empty, this .merge() will have no effect.
|
||||
config.merge(configobj.ConfigObj(cli_config.renewer_config_file))
|
||||
:rtype: :class:`storage.renewableCert`
|
||||
|
||||
"""
|
||||
# Examine the configuration and find the new lineage's name
|
||||
for i in (cli_config.renewal_configs_dir, cli_config.archive_dir,
|
||||
cli_config.live_dir):
|
||||
@@ -685,21 +733,11 @@ class RenewableCert(object): # pylint: disable=too-many-instance-attributes
|
||||
|
||||
# Document what we've done in a new renewal config file
|
||||
config_file.close()
|
||||
new_config = configobj.ConfigObj(config_filename, create_empty=True)
|
||||
for kind in ALL_FOUR:
|
||||
new_config[kind] = target[kind]
|
||||
if renewalparams:
|
||||
new_config["renewalparams"] = renewalparams
|
||||
new_config.comments["renewalparams"] = ["",
|
||||
"Options and defaults used"
|
||||
" in the renewal process"]
|
||||
# TODO: add human-readable comments explaining other available
|
||||
# parameters
|
||||
logger.debug("Writing new config %s.", config_filename)
|
||||
new_config.write()
|
||||
new_config = write_renewal_config(config_filename, target, cli_config)
|
||||
return cls(new_config.filename, cli_config)
|
||||
|
||||
def save_successor(self, prior_version, new_cert, new_privkey, new_chain):
|
||||
def save_successor(self, prior_version, new_cert,
|
||||
new_privkey, new_chain, cli_config):
|
||||
"""Save new cert and chain as a successor of a prior version.
|
||||
|
||||
Returns the new version number that was created.
|
||||
@@ -715,6 +753,8 @@ class RenewableCert(object): # pylint: disable=too-many-instance-attributes
|
||||
:param str new_privkey: the new private key, in PEM format,
|
||||
or ``None``, if the private key has not changed
|
||||
:param str new_chain: the new chain, in PEM format
|
||||
:param .RenewerConfiguration cli_config: parsed command line
|
||||
arguments
|
||||
|
||||
:returns: the new version number that was created
|
||||
:rtype: int
|
||||
@@ -726,6 +766,7 @@ class RenewableCert(object): # pylint: disable=too-many-instance-attributes
|
||||
# if needed (ensuring their permissions are correct)
|
||||
# Figure out what the new version is and hence where to save things
|
||||
|
||||
self.cli_config = cli_config
|
||||
target_version = self.next_free_version()
|
||||
archive = self.cli_config.archive_dir
|
||||
# XXX if anyone ever moves a renewal configuration file, this will
|
||||
@@ -766,4 +807,11 @@ class RenewableCert(object): # pylint: disable=too-many-instance-attributes
|
||||
with open(target["fullchain"], "w") as f:
|
||||
logger.debug("Writing full chain to %s.", target["fullchain"])
|
||||
f.write(new_cert + new_chain)
|
||||
|
||||
symlinks = dict((kind, self.configuration[kind]) for kind in ALL_FOUR)
|
||||
# Update renewal config file
|
||||
self.configfile = update_configuration(
|
||||
self.lineagename, symlinks, cli_config)
|
||||
self.configuration = config_with_defaults(self.configfile)
|
||||
|
||||
return target_version
|
||||
|
||||
@@ -504,8 +504,9 @@ class RenewableCertTests(BaseRenewableCertTest):
|
||||
with open(where, "w") as f:
|
||||
f.write(kind)
|
||||
self.test_rc.update_all_links_to(3)
|
||||
self.assertEqual(6, self.test_rc.save_successor(3, "new cert", None,
|
||||
"new chain"))
|
||||
self.assertEqual(
|
||||
6, self.test_rc.save_successor(3, "new cert", None,
|
||||
"new chain", self.cli_config))
|
||||
with open(self.test_rc.version("cert", 6)) as f:
|
||||
self.assertEqual(f.read(), "new cert")
|
||||
with open(self.test_rc.version("chain", 6)) as f:
|
||||
@@ -516,10 +517,12 @@ class RenewableCertTests(BaseRenewableCertTest):
|
||||
self.assertFalse(os.path.islink(self.test_rc.version("privkey", 3)))
|
||||
self.assertTrue(os.path.islink(self.test_rc.version("privkey", 6)))
|
||||
# Let's try two more updates
|
||||
self.assertEqual(7, self.test_rc.save_successor(6, "again", None,
|
||||
"newer chain"))
|
||||
self.assertEqual(8, self.test_rc.save_successor(7, "hello", None,
|
||||
"other chain"))
|
||||
self.assertEqual(
|
||||
7, self.test_rc.save_successor(6, "again", None,
|
||||
"newer chain", self.cli_config))
|
||||
self.assertEqual(
|
||||
8, self.test_rc.save_successor(7, "hello", None,
|
||||
"other chain", self.cli_config))
|
||||
# All of the subsequent versions should link directly to the original
|
||||
# privkey.
|
||||
for i in (6, 7, 8):
|
||||
@@ -532,27 +535,33 @@ class RenewableCertTests(BaseRenewableCertTest):
|
||||
self.assertEqual(self.test_rc.current_version(kind), 3)
|
||||
# Test updating from latest version rather than old version
|
||||
self.test_rc.update_all_links_to(8)
|
||||
self.assertEqual(9, self.test_rc.save_successor(8, "last", None,
|
||||
"attempt"))
|
||||
self.assertEqual(
|
||||
9, self.test_rc.save_successor(8, "last", None,
|
||||
"attempt", self.cli_config))
|
||||
for kind in ALL_FOUR:
|
||||
self.assertEqual(self.test_rc.available_versions(kind),
|
||||
range(1, 10))
|
||||
self.assertEqual(self.test_rc.current_version(kind), 8)
|
||||
with open(self.test_rc.version("fullchain", 9)) as f:
|
||||
self.assertEqual(f.read(), "last" + "attempt")
|
||||
temp_config_file = os.path.join(self.cli_config.renewal_configs_dir,
|
||||
self.test_rc.lineagename) + ".conf.new"
|
||||
with open(temp_config_file, "w") as f:
|
||||
f.write("We previously crashed while writing me :(")
|
||||
# Test updating when providing a new privkey. The key should
|
||||
# be saved in a new file rather than creating a new symlink.
|
||||
self.assertEqual(10, self.test_rc.save_successor(9, "with", "a",
|
||||
"key"))
|
||||
self.assertEqual(
|
||||
10, self.test_rc.save_successor(9, "with", "a",
|
||||
"key", self.cli_config))
|
||||
self.assertTrue(os.path.exists(self.test_rc.version("privkey", 10)))
|
||||
self.assertFalse(os.path.islink(self.test_rc.version("privkey", 10)))
|
||||
self.assertFalse(os.path.exists(temp_config_file))
|
||||
|
||||
def test_new_lineage(self):
|
||||
"""Test for new_lineage() class method."""
|
||||
from letsencrypt import storage
|
||||
result = storage.RenewableCert.new_lineage(
|
||||
"the-lineage.com", "cert", "privkey", "chain", None,
|
||||
self.defaults, self.cli_config)
|
||||
"the-lineage.com", "cert", "privkey", "chain", self.cli_config)
|
||||
# This consistency check tests most relevant properties about the
|
||||
# newly created cert lineage.
|
||||
# pylint: disable=protected-access
|
||||
@@ -563,27 +572,23 @@ class RenewableCertTests(BaseRenewableCertTest):
|
||||
self.assertEqual(f.read(), "cert" + "chain")
|
||||
# Let's do it again and make sure it makes a different lineage
|
||||
result = storage.RenewableCert.new_lineage(
|
||||
"the-lineage.com", "cert2", "privkey2", "chain2", None,
|
||||
self.defaults, self.cli_config)
|
||||
"the-lineage.com", "cert2", "privkey2", "chain2", self.cli_config)
|
||||
self.assertTrue(os.path.exists(os.path.join(
|
||||
self.cli_config.renewal_configs_dir, "the-lineage.com-0001.conf")))
|
||||
# Now trigger the detection of already existing files
|
||||
os.mkdir(os.path.join(
|
||||
self.cli_config.live_dir, "the-lineage.com-0002"))
|
||||
self.assertRaises(errors.CertStorageError,
|
||||
storage.RenewableCert.new_lineage,
|
||||
"the-lineage.com", "cert3", "privkey3", "chain3",
|
||||
None, self.defaults, self.cli_config)
|
||||
storage.RenewableCert.new_lineage, "the-lineage.com",
|
||||
"cert3", "privkey3", "chain3", self.cli_config)
|
||||
os.mkdir(os.path.join(self.cli_config.archive_dir, "other-example.com"))
|
||||
self.assertRaises(errors.CertStorageError,
|
||||
storage.RenewableCert.new_lineage,
|
||||
"other-example.com", "cert4", "privkey4", "chain4",
|
||||
None, self.defaults, self.cli_config)
|
||||
"other-example.com", "cert4",
|
||||
"privkey4", "chain4", self.cli_config)
|
||||
# Make sure it can accept renewal parameters
|
||||
params = {"stuff": "properties of stuff", "great": "awesome"}
|
||||
result = storage.RenewableCert.new_lineage(
|
||||
"the-lineage.com", "cert2", "privkey2", "chain2",
|
||||
params, self.defaults, self.cli_config)
|
||||
"the-lineage.com", "cert2", "privkey2", "chain2", self.cli_config)
|
||||
# TODO: Conceivably we could test that the renewal parameters actually
|
||||
# got saved
|
||||
|
||||
@@ -595,8 +600,7 @@ class RenewableCertTests(BaseRenewableCertTest):
|
||||
shutil.rmtree(self.cli_config.live_dir)
|
||||
|
||||
storage.RenewableCert.new_lineage(
|
||||
"the-lineage.com", "cert2", "privkey2", "chain2",
|
||||
None, self.defaults, self.cli_config)
|
||||
"the-lineage.com", "cert2", "privkey2", "chain2", self.cli_config)
|
||||
self.assertTrue(os.path.exists(
|
||||
os.path.join(
|
||||
self.cli_config.renewal_configs_dir, "the-lineage.com.conf")))
|
||||
@@ -610,9 +614,8 @@ class RenewableCertTests(BaseRenewableCertTest):
|
||||
from letsencrypt import storage
|
||||
mock_uln.return_value = "this_does_not_end_with_dot_conf", "yikes"
|
||||
self.assertRaises(errors.CertStorageError,
|
||||
storage.RenewableCert.new_lineage,
|
||||
"example.com", "cert", "privkey", "chain",
|
||||
None, self.defaults, self.cli_config)
|
||||
storage.RenewableCert.new_lineage, "example.com",
|
||||
"cert", "privkey", "chain", self.cli_config)
|
||||
|
||||
def test_bad_kind(self):
|
||||
self.assertRaises(
|
||||
|
||||
@@ -51,7 +51,7 @@ common renew
|
||||
sed -i "4arenew_before_expiry = 10 years" "$root/conf/renewal/le1.wtf.conf"
|
||||
common renew
|
||||
|
||||
# letsencrypt-renewer $store_flags
|
||||
ls "$root/conf/archive/le1.wtf"
|
||||
# dir="$root/conf/archive/le1.wtf"
|
||||
# for x in cert chain fullchain privkey;
|
||||
# do
|
||||
|
||||
@@ -1,22 +1,55 @@
|
||||
#!/bin/bash -x
|
||||
|
||||
# $PUBLIC_IP $PRIVATE_IP $PUBLIC_HOSTNAME $BOULDER_URL are dynamically set at execution
|
||||
|
||||
# with curl, instance metadata available from EC2 metadata service:
|
||||
#public_host=$(curl -s http://169.254.169.254/2014-11-05/meta-data/public-hostname)
|
||||
#public_ip=$(curl -s http://169.254.169.254/2014-11-05/meta-data/public-ipv4)
|
||||
#private_ip=$(curl -s http://169.254.169.254/2014-11-05/meta-data/local-ipv4)
|
||||
# $OS_TYPE $PUBLIC_IP $PRIVATE_IP $PUBLIC_HOSTNAME $BOULDER_URL
|
||||
# are dynamically set at execution
|
||||
|
||||
# run letsencrypt-apache2 via letsencrypt-auto
|
||||
cd letsencrypt
|
||||
./letsencrypt-auto certonly -v --standalone --debug \
|
||||
--text --agree-dev-preview --agree-tos \
|
||||
--renew-by-default --redirect \
|
||||
--register-unsafely-without-email \
|
||||
--domain $PUBLIC_HOSTNAME --server $BOULDER_URL
|
||||
|
||||
./letsencrypt-auto renew --renew-by-default
|
||||
export SUDO=sudo
|
||||
if [ -f /etc/debian_version ] ; then
|
||||
echo "Bootstrapping dependencies for Debian-based OSes..."
|
||||
$SUDO bootstrap/_deb_common.sh
|
||||
elif [ -f /etc/redhat-release ] ; then
|
||||
echo "Bootstrapping dependencies for RedHat-based OSes..."
|
||||
$SUDO bootstrap/_rpm_common.sh
|
||||
else
|
||||
echo "Dont have bootstrapping for this OS!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
ls /etc/letsencrypt/archive/$PUBLIC_HOSTNAME | grep -q 2.pem
|
||||
bootstrap/dev/venv.sh
|
||||
sudo venv/bin/letsencrypt certonly --debug --standalone -t --agree-dev-preview --agree-tos \
|
||||
--renew-by-default --redirect --register-unsafely-without-email \
|
||||
--domain $PUBLIC_HOSTNAME --server $BOULDER_URL -v
|
||||
if [ $? -ne 0 ] ; then
|
||||
FAIL=1
|
||||
fi
|
||||
|
||||
if [ "$OS_TYPE" = "ubuntu" ] ; then
|
||||
venv/bin/tox -e apacheconftest
|
||||
else
|
||||
echo Not running hackish apache tests on $OS_TYPE
|
||||
fi
|
||||
|
||||
if [ $? -ne 0 ] ; then
|
||||
FAIL=1
|
||||
fi
|
||||
|
||||
sudo venv/bin/letsencrypt renew --renew-by-default
|
||||
|
||||
if [ $? -ne 0 ] ; then
|
||||
FAIL=1
|
||||
fi
|
||||
|
||||
|
||||
ls /etc/letsencrypt/archive/$PUBLIC_HOSTNAME | grep -q 2.pem
|
||||
|
||||
if [ $? -ne 0 ] ; then
|
||||
FAIL=1
|
||||
fi
|
||||
|
||||
# return error if any of the subtests failed
|
||||
if [ "$FAIL" = 1 ] ; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
Reference in New Issue
Block a user