IConfig attributes. config/args separation

This commit is contained in:
Jakub Warmuz 2015-02-03 12:13:57 +00:00
parent 43e207f9d0
commit 207bd6c31c
No known key found for this signature in database
GPG key ID: 2A7BAD3A489B52EA
5 changed files with 84 additions and 45 deletions

View file

@ -421,7 +421,7 @@ def determine_installer(config):
logging.info("Unable to find a way to install the certificate.")
def rollback(config):
def rollback(checkpoints, config):
"""Revert configuration the specified number of checkpoints.
.. note:: If another installer uses something other than the reverter class
@ -436,6 +436,8 @@ def rollback(config):
of future installers. Perhaps the interface should define errors that
are thrown for the various functions.
:param int checkpoints: Number of checkpoints to revert.
:param config: Configuration.
:type config: :class:`letsencrypt.client.interfaces.IConfig`
@ -444,20 +446,22 @@ def rollback(config):
try:
installer = determine_installer(config)
except errors.LetsEncryptMisconfigurationError:
_misconfigured_rollback(config)
_misconfigured_rollback(checkpoints, config)
return
# No Errors occurred during init... proceed normally
# If installer is None... couldn't find an installer... there shouldn't be
# anything to rollback
if installer is not None:
installer.rollback_checkpoints(config.rollback)
installer.rollback_checkpoints(checkpoints)
installer.restart()
def _misconfigured_rollback(config):
def _misconfigured_rollback(checkpoints, config):
"""Handles the case where the Installer is misconfigured.
:param int checkpoints: Number of checkpoints to revert.
:param config: Configuration.
:type config: :class:`letsencrypt.client.interfaces.IConfig`
@ -477,7 +481,7 @@ def _misconfigured_rollback(config):
# Also... not sure how future installers will handle recovery.
rev = reverter.Reverter(config)
rev.recovery_routine()
rev.rollback_checkpoints(config.rollback)
rev.rollback_checkpoints(checkpoints)
# We should try to restart the server
try:

View file

@ -1,6 +1,8 @@
"""Let's Encrypt user-supplied configuration."""
import os
import zope.interface
from letsencrypt.client import constants
from letsencrypt.client import interfaces
@ -15,21 +17,21 @@ class NamespaceConfig(object):
return getattr(self.namespace, name)
@property
def temp_checkpoint_dir(self):
def temp_checkpoint_dir(self): # pylint: disable=missing-docstring
return os.path.join(
self.namespace.work_dir, constants.TEMP_CHECKPOINT_DIR_NAME)
@property
def in_progress_dir(self):
def in_progress_dir(self): # pylint: disable=missing-docstring
return os.path.join(
self.namespace.work_dir, constants.IN_PROGRESS_DIR_NAME)
@property
def cert_key_backup(self):
def cert_key_backup(self): # pylint: disable=missing-docstring
return os.path.join(
self.namespace.work_dir, constants.CERT_KEY_BACKUP_DIR_NAME)
@property
def rev_tokens_dir(self):
def rev_tokens_dir(self): # pylint: disable=missing-docstring
return os.path.join(
self.namespace.work_dir, constants.REV_TOKENS_DIR_NAME)

View file

@ -60,7 +60,44 @@ class IChallenge(zope.interface.Interface):
class IConfig(zope.interface.Interface):
"""Let's Encrypt uesr-supplied configuration."""
"""Let's Encrypt user-supplied configuration."""
acme_server = zope.interface.Attribute(
"CA hostname (and optionally :port). The server certificate must "
"be trusted in order to avoid further modifications to the client.")
rsa_key_size = zope.interface.Attribute("Size of the RSA key.")
config_dir = zope.interface.Attribute("Configuration directory.")
work_dir = zope.interface.Attribute("Working directory.")
backup_dir = zope.interface.Attribute("Configuration backups directory.")
temp_checkpoint_dir = zope.interface.Attribute(
"Temporary checkpoint directory.")
in_progress_dir = zope.interface.Attribute(
"Directory used before a permanent checkpoint is finalized.")
cert_key_backup = zope.interface.Attribute(
"Directory where all certificates and keys are stored. "
"Used for easy revocation.")
rev_tokens_dir = zope.interface.Attribute(
"Directory where all revocation tokens are saved.")
key_dir = zope.interface.Attribute("Keys storage.")
cert_dir = zope.interface.Attribute("Certificates storage.")
le_vhost_ext = zope.interface.Attribute(
"SSL vhost configuration extension.")
cert_path = zope.interface.Attribute("Let's Encrypt certificate file.")
chain_path = zope.interface.Attribute("Let's Encrypt chain file.")
apache_server_root = zope.interface.Attribute(
"Apache server root directory.")
apache_ctl = zope.interface.Attribute(
"Path to the 'apache2ctl' binary, used for 'configtest' and "
"retrieving Apache2 version number.")
apache_enmod = zope.interface.Attribute(
"Path to the Apache 'a2enmod' binary.")
apache_init_script = zope.interface.Attribute(
"Path to the Apache init script (used for server reload/restart).")
apache_mod_ssl_conf = zope.interface.Attribute(
"Contains standard Apache SSL directives.")
class IInstaller(zope.interface.Interface):

View file

@ -14,7 +14,7 @@ class RollbackTest(unittest.TestCase):
@classmethod
def _call(cls, checkpoints):
from letsencrypt.client.client import rollback
rollback(mock.MagicMock(rollback=checkpoints))
rollback(checkpoints, mock.MagicMock())
@mock.patch("letsencrypt.client.client.determine_installer")
def test_no_problems(self, mock_det):

View file

@ -14,7 +14,6 @@ import zope.component
import letsencrypt
from letsencrypt.client import constants
from letsencrypt.client import configuration
from letsencrypt.client import client
from letsencrypt.client import display
@ -28,17 +27,16 @@ def create_parser():
description="letsencrypt client %s" % letsencrypt.__version__)
add = parser.add_argument
config_help = lambda name: interfaces.IConfig[name].__doc__
add("-d", "--domains", metavar="DOMAIN", nargs="+")
add("-s", "--acme-server", "--server", default="letsencrypt-demo.org:443",
help="CA hostname (and optionally :port). The server certificate must "
"be trusted in order to avoid further modifications to the "
"client.")
help=config_help("acme_server"))
add("-p", "--privkey", type=read_file,
help="Path to the private key file for certificate generation.")
add("-B", "--rsa-key-size", type=int, default=2048,
metavar="N", help="RSA key shall be sized N bits.")
add("-B", "--rsa-key-size", type=int, default=2048, metavar="N",
help=config_help("rsa_key_size"))
add("-k", "--revoke", action="store_true", help="Revoke a certificate.")
add("-b", "--rollback", type=int, default=0, metavar="N",
@ -56,33 +54,31 @@ def create_parser():
add("--test", action="store_true", help="Run in test mode.")
add("--config-dir", default="/etc/letsencrypt",
help="Configuration directory.")
help=config_help("config_dir"))
add("--work-dir", default="/var/lib/letsencrypt",
help="Working directory.")
help=config_help("work_dir"))
add("--backup-dir", default="/var/lib/letsencrypt/backups",
help="Configuration backups directory.")
add("--key-dir", default="/etc/letsencrypt/keys", help="Keys storage.")
help=config_help("backup_dir"))
add("--key-dir", default="/etc/letsencrypt/keys",
help=config_help("key_dir"))
add("--cert-dir", default="/etc/letsencrypt/certs",
help="Certificates storage.")
help=config_help("cert_dir"))
add("--le-vhost-ext", default="-le-ssl.conf",
help="SSL vhost configuration extension.")
help=config_help("le_vhost_ext"))
add("--cert-path", default="/etc/letsencrypt/certs/cert-letsencrypt.pem",
help="Let's Encrypt certificate file.")
help=config_help("cert_path"))
add("--chain-path", default="/etc/letsencrypt/certs/chain-letsencrypt.pem",
help="Let's Encrypt chain file.")
help=config_help("chain_path"))
add("--apache-ctl", default="apache2ctl",
help="Path to the 'apache2ctl' binary, used for 'configtest' and "
"retrieving Apache2 version number.")
add("--apache-enmod", default="a2enmod",
help="Path to the Apache 'a2enmod' binary.")
add("--apache-init-script", default="/etc/init.d/apache2",
help="Path to the Apache init script (used for server reload/restart).")
add("--apache-server-root", default="/etc/apache2",
help="Apache server root directory.")
help=config_help("apache_server_root"))
add("--apache-mod-ssl-conf", default="/etc/letsencrypt/options-ssl.conf",
help="Contains standard Apache SSL directives.")
help=config_help("apache_mod_ssl_conf"))
add("--apache-ctl", default="apache2ctl", help=config_help("apache_ctl"))
add("--apache-enmod", default="a2enmod", help=config_help("apache_enmod"))
add("--apache-init-script", default="/etc/init.d/apache2",
help=config_help("apache_init_script"))
return parser
@ -102,26 +98,26 @@ def main(): # pylint: disable=too-many-branches
# Set up logging
logger = logging.getLogger()
logger.setLevel(logging.INFO)
if config.use_curses:
if args.use_curses:
logger.addHandler(log.DialogHandler())
displayer = display.NcursesDisplay()
else:
displayer = display.FileDisplay(sys.stdout)
zope.component.provideUtility(displayer)
if config.view_config_changes:
if args.view_config_changes:
client.view_config_changes(config)
sys.exit()
if config.revoke:
if args.revoke:
client.revoke(config)
sys.exit()
if config.rollback > 0:
client.rollback(config)
if args.rollback > 0:
client.rollback(args.rollback, config)
sys.exit()
if not config.eula:
if not args.eula:
display_eula()
# Make sure we actually get an installer that is functioning properly
@ -140,14 +136,14 @@ def main(): # pylint: disable=too-many-branches
else:
auth = client.determine_authenticator(config)
if config.domains is None:
if args.domains is None:
domains = choose_names(installer)
# Prepare for init of Client
if config.privkey is None:
privkey = client.init_key(config.rsa_key_size, config.key_dir)
if args.privkey is None:
privkey = client.init_key(args.rsa_key_size, config.key_dir)
else:
privkey = client.Client.Key(config.privkey[0], config.privkey[1])
privkey = client.Client.Key(args.privkey[0], args.privkey[1])
acme = client.Client(config, privkey, auth, installer)
@ -163,7 +159,7 @@ def main(): # pylint: disable=too-many-branches
if installer is not None and cert_file is not None:
acme.deploy_certificate(domains, privkey, cert_file, chain_file)
if installer is not None:
acme.enhance_config(domains, config.redirect)
acme.enhance_config(domains, args.redirect)
def display_eula():