From 89f576babb88722f3273fe770971a4942b23ac96 Mon Sep 17 00:00:00 2001 From: Seth Schoen Date: Fri, 29 Jul 2016 16:51:33 -0700 Subject: [PATCH 01/22] Primarily simple s/apache/nginx/ and the like --- .../configurators/nginx/Dockerfile | 20 +++ .../configurators/nginx/__init__.py | 1 + .../configurators/nginx/common.py | 153 ++++++++++++++++++ .../certbot_compatibility_test/test_driver.py | 5 +- 4 files changed, 177 insertions(+), 2 deletions(-) create mode 100644 certbot-compatibility-test/certbot_compatibility_test/configurators/nginx/Dockerfile create mode 100644 certbot-compatibility-test/certbot_compatibility_test/configurators/nginx/__init__.py create mode 100644 certbot-compatibility-test/certbot_compatibility_test/configurators/nginx/common.py diff --git a/certbot-compatibility-test/certbot_compatibility_test/configurators/nginx/Dockerfile b/certbot-compatibility-test/certbot_compatibility_test/configurators/nginx/Dockerfile new file mode 100644 index 000000000..ea9bb857f --- /dev/null +++ b/certbot-compatibility-test/certbot_compatibility_test/configurators/nginx/Dockerfile @@ -0,0 +1,20 @@ +FROM httpd +MAINTAINER Brad Warren + +RUN mkdir /var/run/apache2 + +ENV APACHE_RUN_USER=daemon \ + APACHE_RUN_GROUP=daemon \ + APACHE_PID_FILE=/usr/local/apache2/logs/httpd.pid \ + APACHE_RUN_DIR=/var/run/apache2 \ + APACHE_LOCK_DIR=/var/lock \ + APACHE_LOG_DIR=/usr/local/apache2/logs + +COPY certbot-compatibility-test/certbot_compatibility_test/configurators/apache/a2enmod.sh /usr/local/bin/ +COPY certbot-compatibility-test/certbot_compatibility_test/configurators/apache/a2dismod.sh /usr/local/bin/ +COPY certbot-compatibility-test/certbot_compatibility_test/testdata/rsa1024_key2.pem /usr/local/apache2/conf/ +COPY certbot-compatibility-test/certbot_compatibility_test/testdata/empty_cert.pem /usr/local/apache2/conf/ + +# Note: this only exposes the port to other docker containers. You +# still have to bind to 443@host at runtime. +EXPOSE 443 diff --git a/certbot-compatibility-test/certbot_compatibility_test/configurators/nginx/__init__.py b/certbot-compatibility-test/certbot_compatibility_test/configurators/nginx/__init__.py new file mode 100644 index 000000000..d559d0645 --- /dev/null +++ b/certbot-compatibility-test/certbot_compatibility_test/configurators/nginx/__init__.py @@ -0,0 +1 @@ +"""Certbot compatibility test Apache configurators""" diff --git a/certbot-compatibility-test/certbot_compatibility_test/configurators/nginx/common.py b/certbot-compatibility-test/certbot_compatibility_test/configurators/nginx/common.py new file mode 100644 index 000000000..29f46ca4f --- /dev/null +++ b/certbot-compatibility-test/certbot_compatibility_test/configurators/nginx/common.py @@ -0,0 +1,153 @@ +"""Provides a common base for Apache proxies""" +import re +import os +import shutil +import subprocess + +import mock +import zope.interface + +from certbot import configuration +from certbot import errors as le_errors +from certbot_nginx import configurator +from certbot_nginx import constants +from certbot_compatibility_test import errors +from certbot_compatibility_test import interfaces +from certbot_compatibility_test import util +from certbot_compatibility_test.configurators import common as configurators_common + + +# APACHE_VERSION_REGEX = re.compile(r"Apache/([0-9\.]*)", re.IGNORECASE) +# XXX APACHE_COMMANDS = ["apachectl", "a2enmod", "a2dismod"] + + +@zope.interface.implementer(interfaces.IConfiguratorProxy) +class Proxy(configurators_common.Proxy): + # pylint: disable=too-many-instance-attributes + """A common base for Nginx test configurators""" + + def __init__(self, args): + # XXX: This is still apache-specific + """Initializes the plugin with the given command line args""" + super(Proxy, self).__init__(args) + self.le_config.apache_le_vhost_ext = "-le-ssl.conf" + + self.modules = self.server_root = self.test_conf = self.version = None + self._nginx_configurator = self._all_names = self._test_names = None + patch = mock.patch( + "certbot_apache.configurator.display_ops.select_vhost") + mock_display = patch.start() + mock_display.side_effect = le_errors.PluginError( + "Unable to determine vhost") + + def __getattr__(self, name): + """Wraps the Nginx Configurator methods""" + method = getattr(self._nginx_configurator, name, None) + if callable(method): + return method + else: + raise AttributeError() + + def load_config(self): + """Loads the next configuration for the plugin to test""" + + config = super(Proxy, self).load_config() + self._all_names, self._test_names = _get_names(config) + + server_root = _get_server_root(config) + # with open(os.path.join(config, "config_file")) as f: + # config_file = os.path.join(server_root, f.readline().rstrip()) + + # XXX: Deleting all of this is kind of scary unless the test + # instances really each have a complete configuration! + shutil.rmtree("/etc/nginx") + shutil.copytree(server_root, "/etc/nginx", symlinks=True) + + self._prepare_configurator() + + try: + subprocess.check_call("nginx".split()) + except errors.Error: + raise errors.Error( + "Nginx failed to load {0} before tests started".format( + config)) + + return config + + def _prepare_configurator(self): + """Prepares the Nginx plugin for testing""" + for k in constants.CLI_DEFAULTS.keys(): + setattr(self.le_config, "nginx_" + k, constants.os_constant(k)) + + # An alias + self.le_config.nginx_handle_modules = self.le_config.nginx_handle_mods + + self._nginx_configurator = configurator.NginxConfigurator( + config=configuration.NamespaceConfig(self.le_config), + name="nginx") + self._nginx_configurator.prepare() + + def cleanup_from_tests(self): + """Performs any necessary cleanup from running plugin tests""" + super(Proxy, self).cleanup_from_tests() + mock.patch.stopall() + + def get_all_names_answer(self): + """Returns the set of domain names that the plugin should find""" + if self._all_names: + return self._all_names + else: + raise errors.Error("No configuration file loaded") + + def get_testable_domain_names(self): + """Returns the set of domain names that can be tested against""" + if self._test_names: + return self._test_names + else: + return {"example.com"} + + def deploy_cert(self, domain, cert_path, key_path, chain_path=None, + fullchain_path=None): + """Installs cert""" + cert_path, key_path, chain_path = self.copy_certs_and_keys( + cert_path, key_path, chain_path) + self._nginx_configurator.deploy_cert( + domain, cert_path, key_path, chain_path, fullchain_path) + + +def _get_server_root(config): + """Returns the server root directory in config""" + subdirs = [ + name for name in os.listdir(config) + if os.path.isdir(os.path.join(config, name))] + + if len(subdirs) != 1: + errors.Error("Malformed configuration directory {0}".format(config)) + + return os.path.join(config, subdirs[0].rstrip()) + + +def _get_names(config): + """Returns all and testable domain names in config""" + # XXX: This is still Apache-specific + all_names = set() + non_ip_names = set() + with open(os.path.join(config, "vhosts")) as f: + for line in f: + # If parsing a specific vhost + if line[0].isspace(): + words = line.split() + if words[0] == "alias": + all_names.add(words[1]) + non_ip_names.add(words[1]) + # If for port 80 and not IP vhost + elif words[1] == "80" and not util.IP_REGEX.match(words[3]): + all_names.add(words[3]) + non_ip_names.add(words[3]) + elif "NameVirtualHost" not in line: + words = line.split() + if (words[0].endswith("*") or words[0].endswith("80") and + not util.IP_REGEX.match(words[1]) and + words[1].find(".") != -1): + all_names.add(words[1]) + return all_names, non_ip_names diff --git a/certbot-compatibility-test/certbot_compatibility_test/test_driver.py b/certbot-compatibility-test/certbot_compatibility_test/test_driver.py index 2c78eea1f..3d03f7771 100644 --- a/certbot-compatibility-test/certbot_compatibility_test/test_driver.py +++ b/certbot-compatibility-test/certbot_compatibility_test/test_driver.py @@ -22,7 +22,8 @@ from certbot_compatibility_test import errors from certbot_compatibility_test import util from certbot_compatibility_test import validator -from certbot_compatibility_test.configurators.apache import common +from certbot_compatibility_test.configurators.apache import common as a_common +from certbot_compatibility_test.configurators.nginx import common as n_common DESCRIPTION = """ @@ -32,7 +33,7 @@ tests that the plugin supports are performed. """ -PLUGINS = {"apache": common.Proxy} +PLUGINS = {"apache": a_common.Proxy, "nginx": n_common.Proxy} logger = logging.getLogger(__name__) From 7b67ba6797ce41aad1ec70e0ad894b90204c51f0 Mon Sep 17 00:00:00 2001 From: Seth Schoen Date: Fri, 29 Jul 2016 17:14:23 -0700 Subject: [PATCH 02/22] Remove unused Apache-related variables --- .../certbot_compatibility_test/configurators/apache/common.py | 4 ---- .../certbot_compatibility_test/configurators/nginx/common.py | 4 ---- 2 files changed, 8 deletions(-) diff --git a/certbot-compatibility-test/certbot_compatibility_test/configurators/apache/common.py b/certbot-compatibility-test/certbot_compatibility_test/configurators/apache/common.py index ed3d9d67a..0c53058de 100644 --- a/certbot-compatibility-test/certbot_compatibility_test/configurators/apache/common.py +++ b/certbot-compatibility-test/certbot_compatibility_test/configurators/apache/common.py @@ -17,10 +17,6 @@ from certbot_compatibility_test import util from certbot_compatibility_test.configurators import common as configurators_common -APACHE_VERSION_REGEX = re.compile(r"Apache/([0-9\.]*)", re.IGNORECASE) -APACHE_COMMANDS = ["apachectl", "a2enmod", "a2dismod"] - - @zope.interface.implementer(interfaces.IConfiguratorProxy) class Proxy(configurators_common.Proxy): # pylint: disable=too-many-instance-attributes diff --git a/certbot-compatibility-test/certbot_compatibility_test/configurators/nginx/common.py b/certbot-compatibility-test/certbot_compatibility_test/configurators/nginx/common.py index 29f46ca4f..c474d078c 100644 --- a/certbot-compatibility-test/certbot_compatibility_test/configurators/nginx/common.py +++ b/certbot-compatibility-test/certbot_compatibility_test/configurators/nginx/common.py @@ -17,10 +17,6 @@ from certbot_compatibility_test import util from certbot_compatibility_test.configurators import common as configurators_common -# APACHE_VERSION_REGEX = re.compile(r"Apache/([0-9\.]*)", re.IGNORECASE) -# XXX APACHE_COMMANDS = ["apachectl", "a2enmod", "a2dismod"] - - @zope.interface.implementer(interfaces.IConfiguratorProxy) class Proxy(configurators_common.Proxy): # pylint: disable=too-many-instance-attributes From 353cb6e6c627e680c8e573a101a3548c193fc769 Mon Sep 17 00:00:00 2001 From: Seth Schoen Date: Wed, 3 Aug 2016 17:10:20 -0700 Subject: [PATCH 03/22] New _get_names approach for nginx test --- .../configurators/nginx/common.py | 27 +++++-------------- 1 file changed, 7 insertions(+), 20 deletions(-) diff --git a/certbot-compatibility-test/certbot_compatibility_test/configurators/nginx/common.py b/certbot-compatibility-test/certbot_compatibility_test/configurators/nginx/common.py index c474d078c..779ba26a7 100644 --- a/certbot-compatibility-test/certbot_compatibility_test/configurators/nginx/common.py +++ b/certbot-compatibility-test/certbot_compatibility_test/configurators/nginx/common.py @@ -125,25 +125,12 @@ def _get_server_root(config): def _get_names(config): """Returns all and testable domain names in config""" - # XXX: This is still Apache-specific all_names = set() - non_ip_names = set() - with open(os.path.join(config, "vhosts")) as f: - for line in f: - # If parsing a specific vhost - if line[0].isspace(): - words = line.split() - if words[0] == "alias": - all_names.add(words[1]) - non_ip_names.add(words[1]) - # If for port 80 and not IP vhost - elif words[1] == "80" and not util.IP_REGEX.match(words[3]): - all_names.add(words[3]) - non_ip_names.add(words[3]) - elif "NameVirtualHost" not in line: - words = line.split() - if (words[0].endswith("*") or words[0].endswith("80") and - not util.IP_REGEX.match(words[1]) and - words[1].find(".") != -1): - all_names.add(words[1]) + for root, _dirs, files in os.walk(config): + for this_file in files: + for line in open(os.path.join(root, this_file)): + if line.strip().starts_with("server_name"): + names = line.partition("server_name")[2].rstrip(";") + [all_names.add(n) for n in names.split()] + non_ip_names = set(n for n in all_names if not util.IP_REGEX.match(n)) return all_names, non_ip_names From 2cd2228ca6a8e3e2b311d5974afa816084695bb7 Mon Sep 17 00:00:00 2001 From: Seth Schoen Date: Fri, 5 Aug 2016 15:07:35 -0700 Subject: [PATCH 04/22] starts_with is actually called startswith --- .../certbot_compatibility_test/configurators/nginx/common.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/certbot-compatibility-test/certbot_compatibility_test/configurators/nginx/common.py b/certbot-compatibility-test/certbot_compatibility_test/configurators/nginx/common.py index 779ba26a7..9fbb538e8 100644 --- a/certbot-compatibility-test/certbot_compatibility_test/configurators/nginx/common.py +++ b/certbot-compatibility-test/certbot_compatibility_test/configurators/nginx/common.py @@ -129,7 +129,7 @@ def _get_names(config): for root, _dirs, files in os.walk(config): for this_file in files: for line in open(os.path.join(root, this_file)): - if line.strip().starts_with("server_name"): + if line.strip().startswith("server_name"): names = line.partition("server_name")[2].rstrip(";") [all_names.add(n) for n in names.split()] non_ip_names = set(n for n in all_names if not util.IP_REGEX.match(n)) From ae6ca4d4ca932dd364b7c6367c96cff25987fad6 Mon Sep 17 00:00:00 2001 From: Seth Schoen Date: Fri, 5 Aug 2016 15:13:04 -0700 Subject: [PATCH 05/22] Minimal fake os_constant() for nginx constants.py --- certbot-nginx/certbot_nginx/constants.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/certbot-nginx/certbot_nginx/constants.py b/certbot-nginx/certbot_nginx/constants.py index 5dde30efc..453266878 100644 --- a/certbot-nginx/certbot_nginx/constants.py +++ b/certbot-nginx/certbot_nginx/constants.py @@ -16,3 +16,10 @@ MOD_SSL_CONF_SRC = pkg_resources.resource_filename( "certbot_nginx", "options-ssl-nginx.conf") """Path to the nginx mod_ssl config file found in the Certbot distribution.""" + +def os_constant(key): + # XXX TODO: In the future, this could return different constants + # based on what OS we are running under. To see an + # approach to how to handle different OSes, see the + # apache version of this file. + return CLI_DEFAULTS From e77a3ed7b968470c908960fb45079c9a2e9e8708 Mon Sep 17 00:00:00 2001 From: Seth Schoen Date: Mon, 8 Aug 2016 17:22:53 -0700 Subject: [PATCH 06/22] Return individual key, not entire config dictionary! --- certbot-nginx/certbot_nginx/constants.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/certbot-nginx/certbot_nginx/constants.py b/certbot-nginx/certbot_nginx/constants.py index 453266878..98f924b2b 100644 --- a/certbot-nginx/certbot_nginx/constants.py +++ b/certbot-nginx/certbot_nginx/constants.py @@ -22,4 +22,4 @@ def os_constant(key): # based on what OS we are running under. To see an # approach to how to handle different OSes, see the # apache version of this file. - return CLI_DEFAULTS + return CLI_DEFAULTS[key] From d41ceff86d22e8ec774771fdd4ab0ee093cb9b64 Mon Sep 17 00:00:00 2001 From: Seth Schoen Date: Mon, 8 Aug 2016 17:24:54 -0700 Subject: [PATCH 07/22] Various WIP on nginx compatibility test --- .../configurators/nginx/common.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/certbot-compatibility-test/certbot_compatibility_test/configurators/nginx/common.py b/certbot-compatibility-test/certbot_compatibility_test/configurators/nginx/common.py index 9fbb538e8..aff9d9467 100644 --- a/certbot-compatibility-test/certbot_compatibility_test/configurators/nginx/common.py +++ b/certbot-compatibility-test/certbot_compatibility_test/configurators/nginx/common.py @@ -75,12 +75,13 @@ class Proxy(configurators_common.Proxy): for k in constants.CLI_DEFAULTS.keys(): setattr(self.le_config, "nginx_" + k, constants.os_constant(k)) - # An alias - self.le_config.nginx_handle_modules = self.le_config.nginx_handle_mods + # This does not appear to exist in nginx (yet?) + # self.le_config.nginx_handle_modules = self.le_config.nginx_handle_mods + conf=configuration.NamespaceConfig(self.le_config) + zope.component.provideUtility(conf) self._nginx_configurator = configurator.NginxConfigurator( - config=configuration.NamespaceConfig(self.le_config), - name="nginx") + config=conf, name="nginx") self._nginx_configurator.prepare() def cleanup_from_tests(self): @@ -118,7 +119,7 @@ def _get_server_root(config): if os.path.isdir(os.path.join(config, name))] if len(subdirs) != 1: - errors.Error("Malformed configuration directory {0}".format(config)) + raise errors.Error("Malformed configuration directory {0}".format(config)) return os.path.join(config, subdirs[0].rstrip()) From 0504882e083252f2ed820bb96586235fdebd09d0 Mon Sep 17 00:00:00 2001 From: Peter Eckersley Date: Mon, 8 Aug 2016 17:50:20 -0700 Subject: [PATCH 08/22] Always newline config edits Even if they're transient --- certbot-nginx/certbot_nginx/tls_sni_01.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/certbot-nginx/certbot_nginx/tls_sni_01.py b/certbot-nginx/certbot_nginx/tls_sni_01.py index ebc92f5e3..c7ec80931 100644 --- a/certbot-nginx/certbot_nginx/tls_sni_01.py +++ b/certbot-nginx/certbot_nginx/tls_sni_01.py @@ -91,10 +91,10 @@ class NginxTlsSni01(common.TLSSNI01): # Add the 'include' statement for the challenges if it doesn't exist # already in the main config included = False - include_directive = ['include', ' ', self.challenge_conf] + include_directive = ['\n', 'include', ' ', self.challenge_conf] root = self.configurator.parser.loc["root"] - bucket_directive = ['server_names_hash_bucket_size', ' ', '128'] + bucket_directive = ['\n', 'server_names_hash_bucket_size', ' ', '128'] main = self.configurator.parser.parsed[root] for key, body in main: From 7d27c1f50020a3594b5bc05c0db023139aec8578 Mon Sep 17 00:00:00 2001 From: Seth Schoen Date: Mon, 8 Aug 2016 17:51:55 -0700 Subject: [PATCH 09/22] More correct parsing of lines containing trailing space --- .../certbot_compatibility_test/configurators/nginx/common.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/certbot-compatibility-test/certbot_compatibility_test/configurators/nginx/common.py b/certbot-compatibility-test/certbot_compatibility_test/configurators/nginx/common.py index aff9d9467..8e2899933 100644 --- a/certbot-compatibility-test/certbot_compatibility_test/configurators/nginx/common.py +++ b/certbot-compatibility-test/certbot_compatibility_test/configurators/nginx/common.py @@ -131,7 +131,7 @@ def _get_names(config): for this_file in files: for line in open(os.path.join(root, this_file)): if line.strip().startswith("server_name"): - names = line.partition("server_name")[2].rstrip(";") + names = line.partition("server_name")[2].rpartition(";")[0] [all_names.add(n) for n in names.split()] non_ip_names = set(n for n in all_names if not util.IP_REGEX.match(n)) return all_names, non_ip_names From 6e86c71259bfd0128f9d002aaec801768637df1f Mon Sep 17 00:00:00 2001 From: Seth Schoen Date: Mon, 8 Aug 2016 18:03:07 -0700 Subject: [PATCH 10/22] Provide a copy of the self-signed cert as the fullchain as well --- .../certbot_compatibility_test/test_driver.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/certbot-compatibility-test/certbot_compatibility_test/test_driver.py b/certbot-compatibility-test/certbot_compatibility_test/test_driver.py index 3d03f7771..b5e023f36 100644 --- a/certbot-compatibility-test/certbot_compatibility_test/test_driver.py +++ b/certbot-compatibility-test/certbot_compatibility_test/test_driver.py @@ -144,7 +144,7 @@ def test_deploy_cert(plugin, temp_dir, domains): for domain in domains: try: - plugin.deploy_cert(domain, cert_path, util.KEY_PATH, cert_path) + plugin.deploy_cert(domain, cert_path, util.KEY_PATH, cert_path, cert_path) plugin.save() # Needed by the Apache plugin except le_errors.Error as error: logger.error("Plugin failed to deploy ceritificate for %s:", domain) From 595e51551866d39593e0e61f2a0dcbe7fa7ad844 Mon Sep 17 00:00:00 2001 From: Seth Schoen Date: Wed, 10 Aug 2016 14:57:44 -0700 Subject: [PATCH 11/22] Restart web servers before beginning tests --- .../certbot_compatibility_test/configurators/apache/common.py | 2 +- .../certbot_compatibility_test/configurators/nginx/common.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/certbot-compatibility-test/certbot_compatibility_test/configurators/apache/common.py b/certbot-compatibility-test/certbot_compatibility_test/configurators/apache/common.py index 0c53058de..4e612bbd5 100644 --- a/certbot-compatibility-test/certbot_compatibility_test/configurators/apache/common.py +++ b/certbot-compatibility-test/certbot_compatibility_test/configurators/apache/common.py @@ -58,7 +58,7 @@ class Proxy(configurators_common.Proxy): self._prepare_configurator() try: - subprocess.check_call("apachectl -k start".split()) + subprocess.check_call("apachectl -k restart".split()) except errors.Error: raise errors.Error( "Apache failed to load {0} before tests started".format( diff --git a/certbot-compatibility-test/certbot_compatibility_test/configurators/nginx/common.py b/certbot-compatibility-test/certbot_compatibility_test/configurators/nginx/common.py index 8e2899933..0d72605b7 100644 --- a/certbot-compatibility-test/certbot_compatibility_test/configurators/nginx/common.py +++ b/certbot-compatibility-test/certbot_compatibility_test/configurators/nginx/common.py @@ -62,7 +62,7 @@ class Proxy(configurators_common.Proxy): self._prepare_configurator() try: - subprocess.check_call("nginx".split()) + subprocess.check_call("service nginx reload".split()) except errors.Error: raise errors.Error( "Nginx failed to load {0} before tests started".format( From 4c596311b068974fd090495be8355323d711c440 Mon Sep 17 00:00:00 2001 From: Brad Warren Date: Wed, 10 Aug 2016 15:39:35 -0700 Subject: [PATCH 12/22] Add nginx compatibility test data tarball --- .../testdata/nginx.tar.gz | Bin 0 -> 6625 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 certbot-compatibility-test/certbot_compatibility_test/testdata/nginx.tar.gz diff --git a/certbot-compatibility-test/certbot_compatibility_test/testdata/nginx.tar.gz b/certbot-compatibility-test/certbot_compatibility_test/testdata/nginx.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..4ca5cc9775a35f64534f90b1db4fb7ef272672a8 GIT binary patch literal 6625 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 literal 0 HcmV?d00001 From 2d099680d01c117fa3d2177e95bb297ff908c1b4 Mon Sep 17 00:00:00 2001 From: Brad Warren Date: Wed, 10 Aug 2016 15:39:59 -0700 Subject: [PATCH 13/22] Rename apache compatibility test tarball --- .../testdata/{configs.tar.gz => apache.tar.gz} | Bin 1 file changed, 0 insertions(+), 0 deletions(-) rename certbot-compatibility-test/certbot_compatibility_test/testdata/{configs.tar.gz => apache.tar.gz} (100%) diff --git a/certbot-compatibility-test/certbot_compatibility_test/testdata/configs.tar.gz b/certbot-compatibility-test/certbot_compatibility_test/testdata/apache.tar.gz similarity index 100% rename from certbot-compatibility-test/certbot_compatibility_test/testdata/configs.tar.gz rename to certbot-compatibility-test/certbot_compatibility_test/testdata/apache.tar.gz From a76c36bf1273320da724f727a26ebc73a663c8ff Mon Sep 17 00:00:00 2001 From: Brad Warren Date: Wed, 10 Aug 2016 15:52:33 -0700 Subject: [PATCH 14/22] Remove old Dockerfiles --- .../configurators/apache/Dockerfile | 20 ------------------- .../configurators/nginx/Dockerfile | 20 ------------------- 2 files changed, 40 deletions(-) delete mode 100644 certbot-compatibility-test/certbot_compatibility_test/configurators/apache/Dockerfile delete mode 100644 certbot-compatibility-test/certbot_compatibility_test/configurators/nginx/Dockerfile diff --git a/certbot-compatibility-test/certbot_compatibility_test/configurators/apache/Dockerfile b/certbot-compatibility-test/certbot_compatibility_test/configurators/apache/Dockerfile deleted file mode 100644 index ea9bb857f..000000000 --- a/certbot-compatibility-test/certbot_compatibility_test/configurators/apache/Dockerfile +++ /dev/null @@ -1,20 +0,0 @@ -FROM httpd -MAINTAINER Brad Warren - -RUN mkdir /var/run/apache2 - -ENV APACHE_RUN_USER=daemon \ - APACHE_RUN_GROUP=daemon \ - APACHE_PID_FILE=/usr/local/apache2/logs/httpd.pid \ - APACHE_RUN_DIR=/var/run/apache2 \ - APACHE_LOCK_DIR=/var/lock \ - APACHE_LOG_DIR=/usr/local/apache2/logs - -COPY certbot-compatibility-test/certbot_compatibility_test/configurators/apache/a2enmod.sh /usr/local/bin/ -COPY certbot-compatibility-test/certbot_compatibility_test/configurators/apache/a2dismod.sh /usr/local/bin/ -COPY certbot-compatibility-test/certbot_compatibility_test/testdata/rsa1024_key2.pem /usr/local/apache2/conf/ -COPY certbot-compatibility-test/certbot_compatibility_test/testdata/empty_cert.pem /usr/local/apache2/conf/ - -# Note: this only exposes the port to other docker containers. You -# still have to bind to 443@host at runtime. -EXPOSE 443 diff --git a/certbot-compatibility-test/certbot_compatibility_test/configurators/nginx/Dockerfile b/certbot-compatibility-test/certbot_compatibility_test/configurators/nginx/Dockerfile deleted file mode 100644 index ea9bb857f..000000000 --- a/certbot-compatibility-test/certbot_compatibility_test/configurators/nginx/Dockerfile +++ /dev/null @@ -1,20 +0,0 @@ -FROM httpd -MAINTAINER Brad Warren - -RUN mkdir /var/run/apache2 - -ENV APACHE_RUN_USER=daemon \ - APACHE_RUN_GROUP=daemon \ - APACHE_PID_FILE=/usr/local/apache2/logs/httpd.pid \ - APACHE_RUN_DIR=/var/run/apache2 \ - APACHE_LOCK_DIR=/var/lock \ - APACHE_LOG_DIR=/usr/local/apache2/logs - -COPY certbot-compatibility-test/certbot_compatibility_test/configurators/apache/a2enmod.sh /usr/local/bin/ -COPY certbot-compatibility-test/certbot_compatibility_test/configurators/apache/a2dismod.sh /usr/local/bin/ -COPY certbot-compatibility-test/certbot_compatibility_test/testdata/rsa1024_key2.pem /usr/local/apache2/conf/ -COPY certbot-compatibility-test/certbot_compatibility_test/testdata/empty_cert.pem /usr/local/apache2/conf/ - -# Note: this only exposes the port to other docker containers. You -# still have to bind to 443@host at runtime. -EXPOSE 443 From 0edb1f6792575d303d592acafd9441cf3ed17367 Mon Sep 17 00:00:00 2001 From: Brad Warren Date: Wed, 10 Aug 2016 16:08:30 -0700 Subject: [PATCH 15/22] Add certbot-compatibility-test Dockerfiles --- certbot-compatibility-test/Dockerfile | 51 ++++++++++++++++++++ certbot-compatibility-test/Dockerfile-apache | 6 +++ certbot-compatibility-test/Dockerfile-nginx | 6 +++ 3 files changed, 63 insertions(+) create mode 100644 certbot-compatibility-test/Dockerfile create mode 100644 certbot-compatibility-test/Dockerfile-apache create mode 100644 certbot-compatibility-test/Dockerfile-nginx diff --git a/certbot-compatibility-test/Dockerfile b/certbot-compatibility-test/Dockerfile new file mode 100644 index 000000000..d5ef9841c --- /dev/null +++ b/certbot-compatibility-test/Dockerfile @@ -0,0 +1,51 @@ +FROM debian:jessie +MAINTAINER Brad Warren + +WORKDIR /opt/certbot + +# no need to mkdir anything: +# https://docs.docker.com/reference/builder/#copy +# If doesn't exist, it is created along with all missing +# directories in its path. + +# TODO: Install non-default Python versions for tox. +# TODO: Install Apache/Nginx for plugin development. +COPY certbot-auto /opt/certbot/src/certbot-auto +RUN /opt/certbot/src/certbot-auto -n --os-packages-only + +# the above is not likely to change, so by putting it further up the +# Dockerfile we make sure we cache as much as possible + +COPY setup.py README.rst CHANGES.rst MANIFEST.in linter_plugin.py tox.cover.sh tox.ini pep8.travis.sh .pep8 .pylintrc /opt/certbot/src/ + +# all above files are necessary for setup.py, however, package source +# code directory has to be copied separately to a subdirectory... +# https://docs.docker.com/reference/builder/#copy: "If is a +# directory, the entire contents of the directory are copied, +# including filesystem metadata. Note: The directory itself is not +# copied, just its contents." Order again matters, three files are far +# more likely to be cached than the whole project directory + +COPY certbot /opt/certbot/src/certbot/ +COPY acme /opt/certbot/src/acme/ +COPY certbot-apache /opt/certbot/src/certbot-apache/ +COPY certbot-nginx /opt/certbot/src/certbot-nginx/ +COPY certbot-compatibility-test /opt/certbot/src/certbot-compatibility-test/ + +RUN virtualenv --no-site-packages -p python2 /opt/certbot/venv && \ + /opt/certbot/venv/bin/pip install -U setuptools && \ + /opt/certbot/venv/bin/pip install -U pip && \ + /opt/certbot/venv/bin/pip install \ + -e /opt/certbot/src/acme \ + -e /opt/certbot/src \ + -e /opt/certbot/src/certbot-apache \ + -e /opt/certbot/src/certbot-nginx \ + -e /opt/certbot/src/certbot-compatibility-test \ + -e /opt/certbot/src[dev,docs] + +# install in editable mode (-e) to save space: it's not possible to +# "rm -rf /opt/certbot/src" (it's stays in the underlaying image); +# this might also help in debugging: you can "docker run --entrypoint +# bash" and investigate, apply patches, etc. + +ENV PATH /opt/certbot/venv/bin:$PATH diff --git a/certbot-compatibility-test/Dockerfile-apache b/certbot-compatibility-test/Dockerfile-apache new file mode 100644 index 000000000..5c0495966 --- /dev/null +++ b/certbot-compatibility-test/Dockerfile-apache @@ -0,0 +1,6 @@ +FROM certbot-compatibility-test +MAINTAINER Brad Warren + +RUN apt-get install apache2 -y + +ENTRYPOINT [ "certbot-compatibility-test", "-p", "apache" ] diff --git a/certbot-compatibility-test/Dockerfile-nginx b/certbot-compatibility-test/Dockerfile-nginx new file mode 100644 index 000000000..4ade03065 --- /dev/null +++ b/certbot-compatibility-test/Dockerfile-nginx @@ -0,0 +1,6 @@ +FROM certbot-compatibility-test +MAINTAINER Brad Warren + +RUN apt-get install nginx -y + +ENTRYPOINT [ "certbot-compatibility-test", "-p", "nginx" ] From 07b85f9f90a12b3b52c19fb0b379955f728095ca Mon Sep 17 00:00:00 2001 From: Brad Warren Date: Wed, 10 Aug 2016 16:32:38 -0700 Subject: [PATCH 16/22] Make testdata the CWD of compatibility test dockerfiles --- certbot-compatibility-test/Dockerfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/certbot-compatibility-test/Dockerfile b/certbot-compatibility-test/Dockerfile index d5ef9841c..e445a3555 100644 --- a/certbot-compatibility-test/Dockerfile +++ b/certbot-compatibility-test/Dockerfile @@ -1,8 +1,6 @@ FROM debian:jessie MAINTAINER Brad Warren -WORKDIR /opt/certbot - # no need to mkdir anything: # https://docs.docker.com/reference/builder/#copy # If doesn't exist, it is created along with all missing @@ -48,4 +46,6 @@ RUN virtualenv --no-site-packages -p python2 /opt/certbot/venv && \ # this might also help in debugging: you can "docker run --entrypoint # bash" and investigate, apply patches, etc. +WORKDIR /opt/certbot/src/certbot-compatibility-test/certbot_compatibility_test/testdata + ENV PATH /opt/certbot/venv/bin:$PATH From fc86f869a71db80c613e60dbd206e2764908c354 Mon Sep 17 00:00:00 2001 From: Brad Warren Date: Wed, 10 Aug 2016 16:33:56 -0700 Subject: [PATCH 17/22] add compatibility tests to travis --- tox.ini | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/tox.ini b/tox.ini index 27979d9df..30c895199 100644 --- a/tox.ini +++ b/tox.ini @@ -79,7 +79,6 @@ commands = pip install -e acme -e .[dev] -e certbot-apache -e certbot-nginx -e certbot-compatibility-test -e letshelp-certbot {toxinidir}/certbot-apache/certbot_apache/tests/apache-conf-files/apache-conf-test --debian-modules - [testenv:le_auto] # At the moment, this tests under Python 2.7 only, as only that version is # readily available on the Trusty Docker image. @@ -89,3 +88,21 @@ commands = whitelist_externals = docker passenv = DOCKER_* + +[testenv:apache_compat] +commands = + docker build -t certbot-compatibility-test -f certbot-compatibility-test/Dockerfile . + docker build -t apache-compat -f certbot-compatibility-test/Dockerfile-apache . + docker run --rm -it apache-compat -c apache.tar.gz -vvvv +whitelist_externals = + docker +passenv = DOCKER_* + +[testenv:nginx_compat] +commands = + docker build -t certbot-compatibility-test -f certbot-compatibility-test/Dockerfile . + docker build -t nginx-compat -f certbot-compatibility-test/Dockerfile-nginx . + docker run --rm -it nginx-compat -c nginx.tar.gz -vvvv +whitelist_externals = + docker +passenv = DOCKER_* From f864cd0cfe29a1ec8caa82204fd6e71ca0e366dc Mon Sep 17 00:00:00 2001 From: Brad Warren Date: Wed, 10 Aug 2016 16:43:15 -0700 Subject: [PATCH 18/22] Add nginxroundtrip to tox --- tox.ini | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tox.ini b/tox.ini index 30c895199..64b5170db 100644 --- a/tox.ini +++ b/tox.ini @@ -79,6 +79,11 @@ commands = pip install -e acme -e .[dev] -e certbot-apache -e certbot-nginx -e certbot-compatibility-test -e letshelp-certbot {toxinidir}/certbot-apache/certbot_apache/tests/apache-conf-files/apache-conf-test --debian-modules +[testenv:nginxroundtrip] +commands = + pip install -e acme[dev] -e .[dev] -e certbot-nginx + python certbot-compatibility-test/nginx/roundtrip.py certbot-compatibility-test/nginx/nginx-roundtrip-testdata + [testenv:le_auto] # At the moment, this tests under Python 2.7 only, as only that version is # readily available on the Trusty Docker image. From 5dda27d757b5200651eaac83bc3e62b99b112880 Mon Sep 17 00:00:00 2001 From: Brad Warren Date: Wed, 10 Aug 2016 16:46:53 -0700 Subject: [PATCH 19/22] Add nginxroundtrip and compatibility-tests to travis --- .travis.yml | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/.travis.yml b/.travis.yml index 6f964dbec..5ccf39811 100644 --- a/.travis.yml +++ b/.travis.yml @@ -34,6 +34,8 @@ matrix: - python: "2.7" env: TOXENV=apacheconftest sudo: required + - python: "2.7" + env: TOXENV=nginxroundtrip - python: "2.7" env: TOXENV=py27 BOULDER_INTEGRATION=1 sudo: true @@ -53,6 +55,16 @@ matrix: services: docker before_install: addons: + - sudo: required + env: TOXENV=apache_compat + services: docker + before_install: + addons: + - sudo: required + env: TOXENV=nginx_compat + services: docker + before_install: + addons: - python: "2.7" env: TOXENV=cover - python: "3.3" From cfc8ce9db436d5a0265a9569bf73e1f887126431 Mon Sep 17 00:00:00 2001 From: Seth Schoen Date: Wed, 10 Aug 2016 17:01:34 -0700 Subject: [PATCH 20/22] Add function docstring --- certbot-nginx/certbot_nginx/constants.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/certbot-nginx/certbot_nginx/constants.py b/certbot-nginx/certbot_nginx/constants.py index 98f924b2b..8cf1f6bc9 100644 --- a/certbot-nginx/certbot_nginx/constants.py +++ b/certbot-nginx/certbot_nginx/constants.py @@ -21,5 +21,12 @@ def os_constant(key): # XXX TODO: In the future, this could return different constants # based on what OS we are running under. To see an # approach to how to handle different OSes, see the - # apache version of this file. + # apache version of this file. Currently, we do not + # actually have any OS-specific constants on Nginx. + """ + Get a constant value for operating system + + :param key: name of cli constant + :return: value of constant for active os + """ return CLI_DEFAULTS[key] From 4bbb12f182341c4d05fe808b03424467949e13b6 Mon Sep 17 00:00:00 2001 From: Seth Schoen Date: Wed, 10 Aug 2016 17:16:54 -0700 Subject: [PATCH 21/22] Satisfying some lint complaints --- .../configurators/apache/common.py | 1 - .../configurators/nginx/__init__.py | 2 +- .../configurators/nginx/common.py | 8 ++++---- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/certbot-compatibility-test/certbot_compatibility_test/configurators/apache/common.py b/certbot-compatibility-test/certbot_compatibility_test/configurators/apache/common.py index 4e612bbd5..b7b1f52c2 100644 --- a/certbot-compatibility-test/certbot_compatibility_test/configurators/apache/common.py +++ b/certbot-compatibility-test/certbot_compatibility_test/configurators/apache/common.py @@ -1,5 +1,4 @@ """Provides a common base for Apache proxies""" -import re import os import shutil import subprocess diff --git a/certbot-compatibility-test/certbot_compatibility_test/configurators/nginx/__init__.py b/certbot-compatibility-test/certbot_compatibility_test/configurators/nginx/__init__.py index d559d0645..ed294abe6 100644 --- a/certbot-compatibility-test/certbot_compatibility_test/configurators/nginx/__init__.py +++ b/certbot-compatibility-test/certbot_compatibility_test/configurators/nginx/__init__.py @@ -1 +1 @@ -"""Certbot compatibility test Apache configurators""" +"""Certbot compatibility test Nginx configurators""" diff --git a/certbot-compatibility-test/certbot_compatibility_test/configurators/nginx/common.py b/certbot-compatibility-test/certbot_compatibility_test/configurators/nginx/common.py index 0d72605b7..311ae4ba6 100644 --- a/certbot-compatibility-test/certbot_compatibility_test/configurators/nginx/common.py +++ b/certbot-compatibility-test/certbot_compatibility_test/configurators/nginx/common.py @@ -1,5 +1,4 @@ -"""Provides a common base for Apache proxies""" -import re +"""Provides a common base for Nginx proxies""" import os import shutil import subprocess @@ -78,7 +77,7 @@ class Proxy(configurators_common.Proxy): # This does not appear to exist in nginx (yet?) # self.le_config.nginx_handle_modules = self.le_config.nginx_handle_mods - conf=configuration.NamespaceConfig(self.le_config) + conf = configuration.NamespaceConfig(self.le_config) zope.component.provideUtility(conf) self._nginx_configurator = configurator.NginxConfigurator( config=conf, name="nginx") @@ -132,6 +131,7 @@ def _get_names(config): for line in open(os.path.join(root, this_file)): if line.strip().startswith("server_name"): names = line.partition("server_name")[2].rpartition(";")[0] - [all_names.add(n) for n in names.split()] + for n in names.split(): + all_names.add(n) non_ip_names = set(n for n in all_names if not util.IP_REGEX.match(n)) return all_names, non_ip_names From 1f471da7685a790d9bc4f0d66b5f359df0877025 Mon Sep 17 00:00:00 2001 From: Brad Warren Date: Wed, 10 Aug 2016 17:39:29 -0700 Subject: [PATCH 22/22] Remove code duplication to make pylint happy --- .../configurators/apache/common.py | 38 +------------ .../configurators/common.py | 35 ++++++++++++ .../configurators/nginx/common.py | 57 +------------------ 3 files changed, 39 insertions(+), 91 deletions(-) diff --git a/certbot-compatibility-test/certbot_compatibility_test/configurators/apache/common.py b/certbot-compatibility-test/certbot_compatibility_test/configurators/apache/common.py index b7b1f52c2..64170ca72 100644 --- a/certbot-compatibility-test/certbot_compatibility_test/configurators/apache/common.py +++ b/certbot-compatibility-test/certbot_compatibility_test/configurators/apache/common.py @@ -27,30 +27,18 @@ class Proxy(configurators_common.Proxy): self.le_config.apache_le_vhost_ext = "-le-ssl.conf" self.modules = self.server_root = self.test_conf = self.version = None - self._apache_configurator = self._all_names = self._test_names = None patch = mock.patch( "certbot_apache.configurator.display_ops.select_vhost") mock_display = patch.start() mock_display.side_effect = le_errors.PluginError( "Unable to determine vhost") - def __getattr__(self, name): - """Wraps the Apache Configurator methods""" - method = getattr(self._apache_configurator, name, None) - if callable(method): - return method - else: - raise AttributeError() - def load_config(self): """Loads the next configuration for the plugin to test""" - config = super(Proxy, self).load_config() self._all_names, self._test_names = _get_names(config) server_root = _get_server_root(config) - # with open(os.path.join(config, "config_file")) as f: - # config_file = os.path.join(server_root, f.readline().rstrip()) shutil.rmtree("/etc/apache2") shutil.copytree(server_root, "/etc/apache2", symlinks=True) @@ -73,38 +61,16 @@ class Proxy(configurators_common.Proxy): # An alias self.le_config.apache_handle_modules = self.le_config.apache_handle_mods - self._apache_configurator = configurator.ApacheConfigurator( + self._configurator = configurator.ApacheConfigurator( config=configuration.NamespaceConfig(self.le_config), name="apache") - self._apache_configurator.prepare() + self._configurator.prepare() def cleanup_from_tests(self): """Performs any necessary cleanup from running plugin tests""" super(Proxy, self).cleanup_from_tests() mock.patch.stopall() - def get_all_names_answer(self): - """Returns the set of domain names that the plugin should find""" - if self._all_names: - return self._all_names - else: - raise errors.Error("No configuration file loaded") - - def get_testable_domain_names(self): - """Returns the set of domain names that can be tested against""" - if self._test_names: - return self._test_names - else: - return {"example.com"} - - def deploy_cert(self, domain, cert_path, key_path, chain_path=None, - fullchain_path=None): - """Installs cert""" - cert_path, key_path, chain_path = self.copy_certs_and_keys( - cert_path, key_path, chain_path) - self._apache_configurator.deploy_cert( - domain, cert_path, key_path, chain_path, fullchain_path) - def _get_server_root(config): """Returns the server root directory in config""" diff --git a/certbot-compatibility-test/certbot_compatibility_test/configurators/common.py b/certbot-compatibility-test/certbot_compatibility_test/configurators/common.py index 03128cc86..2a800c1c2 100644 --- a/certbot-compatibility-test/certbot_compatibility_test/configurators/common.py +++ b/certbot-compatibility-test/certbot_compatibility_test/configurators/common.py @@ -5,6 +5,7 @@ import shutil import tempfile from certbot import constants +from certbot_compatibility_test import errors from certbot_compatibility_test import util @@ -31,6 +32,18 @@ class Proxy(object): self.args = args self.http_port = 80 self.https_port = 443 + self._configurator = self._all_names = self._test_names = None + + def __getattr__(self, name): + """Wraps the configurator methods""" + if self._configurator is None: + raise AttributeError() + + method = getattr(self._configurator, name, None) + if callable(method): + return method + else: + raise AttributeError() def has_more_configs(self): """Returns true if there are more configs to test""" @@ -63,3 +76,25 @@ class Proxy(object): chain = None return cert, key, chain + + def get_all_names_answer(self): + """Returns the set of domain names that the plugin should find""" + if self._all_names: + return self._all_names + else: + raise errors.Error("No configuration file loaded") + + def get_testable_domain_names(self): + """Returns the set of domain names that can be tested against""" + if self._test_names: + return self._test_names + else: + return {"example.com"} + + def deploy_cert(self, domain, cert_path, key_path, chain_path=None, + fullchain_path=None): + """Installs cert""" + cert_path, key_path, chain_path = self.copy_certs_and_keys( + cert_path, key_path, chain_path) + self._configurator.deploy_cert( + domain, cert_path, key_path, chain_path, fullchain_path) diff --git a/certbot-compatibility-test/certbot_compatibility_test/configurators/nginx/common.py b/certbot-compatibility-test/certbot_compatibility_test/configurators/nginx/common.py index 311ae4ba6..3622bee41 100644 --- a/certbot-compatibility-test/certbot_compatibility_test/configurators/nginx/common.py +++ b/certbot-compatibility-test/certbot_compatibility_test/configurators/nginx/common.py @@ -3,11 +3,9 @@ import os import shutil import subprocess -import mock import zope.interface from certbot import configuration -from certbot import errors as le_errors from certbot_nginx import configurator from certbot_nginx import constants from certbot_compatibility_test import errors @@ -22,36 +20,15 @@ class Proxy(configurators_common.Proxy): """A common base for Nginx test configurators""" def __init__(self, args): - # XXX: This is still apache-specific """Initializes the plugin with the given command line args""" super(Proxy, self).__init__(args) - self.le_config.apache_le_vhost_ext = "-le-ssl.conf" - - self.modules = self.server_root = self.test_conf = self.version = None - self._nginx_configurator = self._all_names = self._test_names = None - patch = mock.patch( - "certbot_apache.configurator.display_ops.select_vhost") - mock_display = patch.start() - mock_display.side_effect = le_errors.PluginError( - "Unable to determine vhost") - - def __getattr__(self, name): - """Wraps the Nginx Configurator methods""" - method = getattr(self._nginx_configurator, name, None) - if callable(method): - return method - else: - raise AttributeError() def load_config(self): """Loads the next configuration for the plugin to test""" - config = super(Proxy, self).load_config() self._all_names, self._test_names = _get_names(config) server_root = _get_server_root(config) - # with open(os.path.join(config, "config_file")) as f: - # config_file = os.path.join(server_root, f.readline().rstrip()) # XXX: Deleting all of this is kind of scary unless the test # instances really each have a complete configuration! @@ -74,41 +51,11 @@ class Proxy(configurators_common.Proxy): for k in constants.CLI_DEFAULTS.keys(): setattr(self.le_config, "nginx_" + k, constants.os_constant(k)) - # This does not appear to exist in nginx (yet?) - # self.le_config.nginx_handle_modules = self.le_config.nginx_handle_mods - conf = configuration.NamespaceConfig(self.le_config) zope.component.provideUtility(conf) - self._nginx_configurator = configurator.NginxConfigurator( + self._configurator = configurator.NginxConfigurator( config=conf, name="nginx") - self._nginx_configurator.prepare() - - def cleanup_from_tests(self): - """Performs any necessary cleanup from running plugin tests""" - super(Proxy, self).cleanup_from_tests() - mock.patch.stopall() - - def get_all_names_answer(self): - """Returns the set of domain names that the plugin should find""" - if self._all_names: - return self._all_names - else: - raise errors.Error("No configuration file loaded") - - def get_testable_domain_names(self): - """Returns the set of domain names that can be tested against""" - if self._test_names: - return self._test_names - else: - return {"example.com"} - - def deploy_cert(self, domain, cert_path, key_path, chain_path=None, - fullchain_path=None): - """Installs cert""" - cert_path, key_path, chain_path = self.copy_certs_and_keys( - cert_path, key_path, chain_path) - self._nginx_configurator.deploy_cert( - domain, cert_path, key_path, chain_path, fullchain_path) + self._configurator.prepare() def _get_server_root(config):