diff --git a/letsencrypt/client/cli.py b/letsencrypt/client/cli.py index f49918bf2..221c51969 100644 --- a/letsencrypt/client/cli.py +++ b/letsencrypt/client/cli.py @@ -27,6 +27,8 @@ from letsencrypt.client.display import ops as display_ops from letsencrypt.client.plugins import disco as plugins_disco +from letsencrypt.client.plugins.apache import configurator as apache_configurator + def _common_run(args, config, authenticator, installer): if args.domains is None: @@ -296,7 +298,11 @@ def create_parser(): help="Revert configuration N number of checkpoints.") paths_parser(parser.add_argument_group("paths")) - apache_parser(parser.add_argument_group("apache")) + + # TODO: plugin_parser should be called for every detected plugin + plugin_parser( + parser.add_argument_group("apache"), prefix="apache", + plugin_cls=apache_configurator.ApacheConfigurator) return parser @@ -323,20 +329,11 @@ def paths_parser(parser): return parser -def apache_parser(parser): - # TODO: this should probably be moved to plugins/apache, in - # general all plugins should be able to inject config options - add = parser.add_argument - add("--apache-server-root", default=constants.DEFAULT_APACHE_SERVER_ROOT, - help=config_help("apache_server_root")) - add("--apache-mod-ssl-conf", default=constants.DEFAULT_APACHE_MOD_SSL_CONF, - help=config_help("apache_mod_ssl_conf")) - add("--apache-ctl", default=constants.DEFAULT_APACHE_CTL, - help=config_help("apache_ctl")) - add("--apache-enmod", default=constants.DEFAULT_APACHE_ENMOD, - help=config_help("apache_enmod")) - add("--apache-init-script", default=constants.DEFAULT_APACHE_INIT_SCRIPT, - help=config_help("apache_init_script")) +def plugin_parser(parser, prefix, plugin_cls): + def add(arg_name_no_prefix, *args, **kwargs): + parser.add_argument( + "--{0}-{1}".format(prefix, arg_name_no_prefix), *args, **kwargs) + plugin_cls.add_parser_arguments(add) return parser diff --git a/letsencrypt/client/constants.py b/letsencrypt/client/constants.py index 5c13ea1a3..6c8519196 100644 --- a/letsencrypt/client/constants.py +++ b/letsencrypt/client/constants.py @@ -22,11 +22,6 @@ DEFAULT_KEY_DIR = "/etc/letsencrypt/keys" DEFAULT_CERTS_DIR = "/etc/letsencrypt/certs" DEFAULT_CERT_PATH = "/etc/letsencrypt/certs/cert-letsencrypt.pem" DEFAULT_CHAIN_PATH = "/etc/letsencrypt/certs/chain-letsencrypt.pem" -DEFAULT_APACHE_SERVER_ROOT = "/etc/apache2" -DEFAULT_APACHE_MOD_SSL_CONF = "/etc/letsencrypt/options-ssl.conf" -DEFAULT_APACHE_CTL = "apache2ctl" -DEFAULT_APACHE_ENMOD = "a2enmod" -DEFAULT_APACHE_INIT_SCRIPT = "/etc/init.d/apache2" S_SIZE = 32 @@ -55,16 +50,6 @@ List of expected options parameters: """ -APACHE_MOD_SSL_CONF = pkg_resources.resource_filename( - "letsencrypt.client.plugins.apache", "options-ssl.conf") -"""Path to the Apache mod_ssl config file found in the Let's Encrypt -distribution.""" - -APACHE_REWRITE_HTTPS_ARGS = [ - "^.*$", "https://%{SERVER_NAME}%{REQUEST_URI}", "[L,R=permanent]"] -"""Apache rewrite rule arguments used for redirections to https vhost""" - - DVSNI_CHALLENGE_PORT = 443 """Port to perform DVSNI challenge.""" diff --git a/letsencrypt/client/interfaces.py b/letsencrypt/client/interfaces.py index 2390330b6..80a43f885 100644 --- a/letsencrypt/client/interfaces.py +++ b/letsencrypt/client/interfaces.py @@ -117,18 +117,6 @@ class IConfig(zope.interface.Interface): 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(IPlugin): """Generic Let's Encrypt Installer Interface. diff --git a/letsencrypt/client/plugins/apache/configurator.py b/letsencrypt/client/plugins/apache/configurator.py index e6104a559..55f7e2875 100644 --- a/letsencrypt/client/plugins/apache/configurator.py +++ b/letsencrypt/client/plugins/apache/configurator.py @@ -13,11 +13,11 @@ from letsencrypt.acme import challenges from letsencrypt.client import achallenges from letsencrypt.client import augeas_configurator -from letsencrypt.client import constants from letsencrypt.client import errors from letsencrypt.client import interfaces from letsencrypt.client import le_util +from letsencrypt.client.plugins.apache import constants from letsencrypt.client.plugins.apache import dvsni from letsencrypt.client.plugins.apache import obj from letsencrypt.client.plugins.apache import parser @@ -82,6 +82,20 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator): description = "Apache Web Server" + @classmethod + def add_parser_arguments(cls, add): + add("server-root", default=constants.DEFAULT_SERVER_ROOT, + help="Apache server root directory.") + add("mod-ssl-conf", default=constants.DEFAULT_MOD_SSL_CONF, + help="Contains standard Apache SSL directives.") + add("ctl", default=constants.DEFAULT_CTL, + help="Path to the 'apache2ctl' binary, used for 'configtest' and " + "retrieving Apache2 version number.") + add("enmod", default=constants.DEFAULT_ENMOD, + help="Path to the Apache 'a2enmod' binary.") + add("init-script", default=constants.DEFAULT_INIT_SCRIPT, + help="Path to the Apache init script (used for server reload/restart).") + def __init__(self, config, version=None): """Initialize an Apache Configurator. @@ -599,7 +613,7 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator): # Add directives to server self.parser.add_dir(general_v.path, "RewriteEngine", "On") self.parser.add_dir(general_v.path, "RewriteRule", - constants.APACHE_REWRITE_HTTPS_ARGS) + constants.REWRITE_HTTPS_ARGS) self.save_notes += ("Redirecting host in %s to ssl vhost in %s\n" % (general_v.filep, ssl_vhost.filep)) self.save() @@ -638,10 +652,10 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator): if not rewrite_path: # "No existing redirection for virtualhost" return False, -1 - if len(rewrite_path) == len(constants.APACHE_REWRITE_HTTPS_ARGS): + if len(rewrite_path) == len(constants.REWRITE_HTTPS_ARGS): for idx, match in enumerate(rewrite_path): if (self.aug.get(match) != - constants.APACHE_REWRITE_HTTPS_ARGS[idx]): + constants.REWRITE_HTTPS_ARGS[idx]): # Not a letsencrypt https rewrite return True, 2 # Existing letsencrypt https rewrite rule is in place @@ -693,7 +707,7 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator): "LogLevel warn\n" "\n" % (servername, serveralias, - " ".join(constants.APACHE_REWRITE_HTTPS_ARGS))) + " ".join(constants.REWRITE_HTTPS_ARGS))) # Write out the file # This is the default name @@ -1160,4 +1174,4 @@ def temp_install(options_ssl): # Check to make sure options-ssl.conf is installed if not os.path.isfile(options_ssl): - shutil.copyfile(constants.APACHE_MOD_SSL_CONF, options_ssl) + shutil.copyfile(constants.MOD_SSL_CONF, options_ssl) diff --git a/letsencrypt/client/plugins/apache/constants.py b/letsencrypt/client/plugins/apache/constants.py new file mode 100644 index 000000000..63b3bd148 --- /dev/null +++ b/letsencrypt/client/plugins/apache/constants.py @@ -0,0 +1,20 @@ +"""Apache plugin constants.""" +import pkg_resources + + +# CLI/IConfig defaults +DEFAULT_SERVER_ROOT = "/etc/apache2" +DEFAULT_MOD_SSL_CONF = "/etc/letsencrypt/options-ssl.conf" +DEFAULT_CTL = "apache2ctl" +DEFAULT_ENMOD = "a2enmod" +DEFAULT_INIT_SCRIPT = "/etc/init.d/apache2" + + +MOD_SSL_CONF = pkg_resources.resource_filename( + "letsencrypt.client.plugins.apache", "options-ssl.conf") +"""Path to the Apache mod_ssl config file found in the Let's Encrypt +distribution.""" + +REWRITE_HTTPS_ARGS = [ + "^.*$", "https://%{SERVER_NAME}%{REQUEST_URI}", "[L,R=permanent]"] +"""Apache rewrite rule arguments used for redirections to https vhost""" diff --git a/letsencrypt/client/plugins/apache/tests/util.py b/letsencrypt/client/plugins/apache/tests/util.py index d1ba17f5a..feeb9490e 100644 --- a/letsencrypt/client/plugins/apache/tests/util.py +++ b/letsencrypt/client/plugins/apache/tests/util.py @@ -7,8 +7,8 @@ import unittest import mock -from letsencrypt.client import constants from letsencrypt.client.plugins.apache import configurator +from letsencrypt.client.plugins.apache import constants from letsencrypt.client.plugins.apache import obj @@ -49,7 +49,7 @@ def dir_setup(test_dir="debian_apache_2_4/two_vhost_80"): def setup_apache_ssl_options(config_dir): """Move the ssl_options into position and return the path.""" option_path = os.path.join(config_dir, "options-ssl.conf") - shutil.copyfile(constants.APACHE_MOD_SSL_CONF, option_path) + shutil.copyfile(constants.MOD_SSL_CONF, option_path) return option_path