2015-02-03 06:22:04 -05:00
|
|
|
"""Let's Encrypt user-supplied configuration."""
|
2016-02-04 22:14:36 -05:00
|
|
|
import copy
|
2015-02-03 07:13:57 -05:00
|
|
|
import os
|
2015-05-09 15:19:34 -04:00
|
|
|
|
2016-02-07 00:43:52 -05:00
|
|
|
from six.moves.urllib import parse # pylint: disable=import-error
|
2015-02-03 06:22:04 -05:00
|
|
|
import zope.interface
|
|
|
|
|
|
2015-05-10 08:25:29 -04:00
|
|
|
from letsencrypt import constants
|
2015-10-14 13:30:03 -04:00
|
|
|
from letsencrypt import errors
|
2015-05-10 08:25:29 -04:00
|
|
|
from letsencrypt import interfaces
|
2015-12-07 08:07:27 -05:00
|
|
|
from letsencrypt import le_util
|
2015-02-03 06:22:04 -05:00
|
|
|
|
|
|
|
|
|
2016-02-20 01:08:40 -05:00
|
|
|
@zope.interface.implementer(interfaces.IConfig)
|
2015-02-03 06:22:04 -05:00
|
|
|
class NamespaceConfig(object):
|
2015-02-04 11:38:13 -05:00
|
|
|
"""Configuration wrapper around :class:`argparse.Namespace`.
|
|
|
|
|
|
|
|
|
|
For more documentation, including available attributes, please see
|
2015-05-10 08:25:29 -04:00
|
|
|
:class:`letsencrypt.interfaces.IConfig`. However, note that
|
2015-02-04 11:38:13 -05:00
|
|
|
the following attributes are dynamically resolved using
|
2015-05-10 08:25:29 -04:00
|
|
|
:attr:`~letsencrypt.interfaces.IConfig.work_dir` and relative
|
|
|
|
|
paths defined in :py:mod:`letsencrypt.constants`:
|
2015-02-04 11:38:13 -05:00
|
|
|
|
2015-06-01 19:25:57 -04:00
|
|
|
- `accounts_dir`
|
2015-09-26 01:26:32 -04:00
|
|
|
- `csr_dir`
|
2015-06-01 19:25:57 -04:00
|
|
|
- `in_progress_dir`
|
|
|
|
|
- `key_dir`
|
|
|
|
|
- `renewer_config_file`
|
|
|
|
|
- `temp_checkpoint_dir`
|
2015-02-04 11:38:13 -05:00
|
|
|
|
|
|
|
|
:ivar namespace: Namespace typically produced by
|
|
|
|
|
:meth:`argparse.ArgumentParser.parse_args`.
|
|
|
|
|
:type namespace: :class:`argparse.Namespace`
|
|
|
|
|
|
|
|
|
|
"""
|
2015-02-03 06:22:04 -05:00
|
|
|
|
|
|
|
|
def __init__(self, namespace):
|
|
|
|
|
self.namespace = namespace
|
2015-11-12 21:17:10 -05:00
|
|
|
|
|
|
|
|
self.namespace.config_dir = os.path.abspath(self.namespace.config_dir)
|
|
|
|
|
self.namespace.work_dir = os.path.abspath(self.namespace.work_dir)
|
|
|
|
|
self.namespace.logs_dir = os.path.abspath(self.namespace.logs_dir)
|
|
|
|
|
|
2015-11-09 19:18:51 -05:00
|
|
|
# Check command line parameters sanity, and error out in case of problem.
|
2015-11-08 15:26:01 -05:00
|
|
|
check_config_sanity(self)
|
2015-09-26 12:14:00 -04:00
|
|
|
|
2015-02-03 06:22:04 -05:00
|
|
|
def __getattr__(self, name):
|
|
|
|
|
return getattr(self.namespace, name)
|
|
|
|
|
|
2015-05-01 06:08:33 -04:00
|
|
|
@property
|
|
|
|
|
def server_path(self):
|
|
|
|
|
"""File path based on ``server``."""
|
2016-02-07 00:43:52 -05:00
|
|
|
parsed = parse.urlparse(self.namespace.server)
|
2015-05-09 15:19:34 -04:00
|
|
|
return (parsed.netloc + parsed.path).replace('/', os.path.sep)
|
2015-05-01 06:08:33 -04:00
|
|
|
|
2015-04-15 19:53:39 -04:00
|
|
|
@property
|
2015-09-06 05:20:11 -04:00
|
|
|
def accounts_dir(self): # pylint: disable=missing-docstring
|
2015-04-15 19:53:39 -04:00
|
|
|
return os.path.join(
|
2015-05-01 06:08:33 -04:00
|
|
|
self.namespace.config_dir, constants.ACCOUNTS_DIR, self.server_path)
|
2015-04-15 19:53:39 -04:00
|
|
|
|
2015-06-01 19:25:57 -04:00
|
|
|
@property
|
|
|
|
|
def backup_dir(self): # pylint: disable=missing-docstring
|
|
|
|
|
return os.path.join(self.namespace.work_dir, constants.BACKUP_DIR)
|
|
|
|
|
|
2015-06-25 08:58:44 -04:00
|
|
|
@property
|
2015-09-26 01:26:32 -04:00
|
|
|
def csr_dir(self): # pylint: disable=missing-docstring
|
|
|
|
|
return os.path.join(self.namespace.config_dir, constants.CSR_DIR)
|
2015-06-25 08:58:44 -04:00
|
|
|
|
2015-06-01 19:25:57 -04:00
|
|
|
@property
|
|
|
|
|
def in_progress_dir(self): # pylint: disable=missing-docstring
|
|
|
|
|
return os.path.join(self.namespace.work_dir, constants.IN_PROGRESS_DIR)
|
|
|
|
|
|
|
|
|
|
@property
|
|
|
|
|
def key_dir(self): # pylint: disable=missing-docstring
|
|
|
|
|
return os.path.join(self.namespace.config_dir, constants.KEY_DIR)
|
2015-04-15 19:53:39 -04:00
|
|
|
|
2015-06-01 19:25:57 -04:00
|
|
|
@property
|
|
|
|
|
def temp_checkpoint_dir(self): # pylint: disable=missing-docstring
|
|
|
|
|
return os.path.join(
|
|
|
|
|
self.namespace.work_dir, constants.TEMP_CHECKPOINT_DIR)
|
2015-06-02 08:10:22 -04:00
|
|
|
|
2016-02-04 22:14:36 -05:00
|
|
|
def __deepcopy__(self, _memo):
|
|
|
|
|
# Work around https://bugs.python.org/issue1515 for py26 tests :( :(
|
|
|
|
|
# https://travis-ci.org/letsencrypt/letsencrypt/jobs/106900743#L3276
|
|
|
|
|
new_ns = copy.deepcopy(self.namespace)
|
|
|
|
|
return type(self)(new_ns)
|
|
|
|
|
|
2015-06-02 08:10:22 -04:00
|
|
|
|
|
|
|
|
class RenewerConfiguration(object):
|
|
|
|
|
"""Configuration wrapper for renewer."""
|
|
|
|
|
|
|
|
|
|
def __init__(self, namespace):
|
|
|
|
|
self.namespace = namespace
|
|
|
|
|
|
|
|
|
|
def __getattr__(self, name):
|
|
|
|
|
return getattr(self.namespace, name)
|
|
|
|
|
|
|
|
|
|
@property
|
|
|
|
|
def archive_dir(self): # pylint: disable=missing-docstring
|
|
|
|
|
return os.path.join(self.namespace.config_dir, constants.ARCHIVE_DIR)
|
|
|
|
|
|
|
|
|
|
@property
|
|
|
|
|
def live_dir(self): # pylint: disable=missing-docstring
|
|
|
|
|
return os.path.join(self.namespace.config_dir, constants.LIVE_DIR)
|
|
|
|
|
|
|
|
|
|
@property
|
|
|
|
|
def renewal_configs_dir(self): # pylint: disable=missing-docstring
|
|
|
|
|
return os.path.join(
|
|
|
|
|
self.namespace.config_dir, constants.RENEWAL_CONFIGS_DIR)
|
|
|
|
|
|
|
|
|
|
@property
|
|
|
|
|
def renewer_config_file(self): # pylint: disable=missing-docstring
|
|
|
|
|
return os.path.join(
|
|
|
|
|
self.namespace.config_dir, constants.RENEWER_CONFIG_FILENAME)
|
2015-11-08 15:26:01 -05:00
|
|
|
|
|
|
|
|
|
|
|
|
|
def check_config_sanity(config):
|
|
|
|
|
"""Validate command line options and display error message if
|
|
|
|
|
requirements are not met.
|
|
|
|
|
|
|
|
|
|
:param config: IConfig instance holding user configuration
|
|
|
|
|
:type args: :class:`letsencrypt.interfaces.IConfig`
|
|
|
|
|
|
|
|
|
|
"""
|
2015-11-08 16:05:33 -05:00
|
|
|
# Port check
|
|
|
|
|
if config.http01_port == config.tls_sni_01_port:
|
2015-11-09 19:18:51 -05:00
|
|
|
raise errors.ConfigurationError(
|
2015-11-08 16:05:33 -05:00
|
|
|
"Trying to run http-01 and tls-sni-01 "
|
|
|
|
|
"on the same port ({0})".format(config.tls_sni_01_port))
|
|
|
|
|
|
2015-11-08 15:26:01 -05:00
|
|
|
# Domain checks
|
|
|
|
|
if config.namespace.domains is not None:
|
2015-12-07 08:07:27 -05:00
|
|
|
for domain in config.namespace.domains:
|
2016-02-01 22:27:47 -05:00
|
|
|
# This may be redundant, but let's be paranoid
|
|
|
|
|
le_util.enforce_domain_sanity(domain)
|