100% configurator coverage

This commit is contained in:
James Kasten 2015-07-24 03:22:35 -07:00
parent aecb7b71d7
commit 647caba164
4 changed files with 317 additions and 94 deletions

View file

@ -88,6 +88,9 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator):
private_ips_regex = re.compile(
r"(^127\.0\.0\.1)|(^10\.)|(^172\.1[6-9]\.)|"
r"(^172\.2[0-9]\.)|(^172\.3[0-1]\.)|(^192\.168\.)")
hostname_regex = re.compile(
r"^(([a-z0-9]|[a-z0-9][a-z0-9\-]*[a-z0-9])\.)*[a-z]+$", re.IGNORECASE)
@classmethod
def add_parser_arguments(cls, add):
@ -121,8 +124,8 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator):
# Add name_server association dict
self.assoc = dict()
# Add number of outstanding challenges
self._chall_out = 0
# Outstanding challenges
self._chall_out = set()
# These will be set in the prepare function
self.parser = None
@ -147,7 +150,10 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator):
# Set Version
if self.version is None:
self.version = self.get_version() # pragma: no cover
self.version = self.get_version()
if self.version < (2, 2):
raise errors.NotSupportedError(
"Apache Version %s not supported.", str(self.version))
# Get all of the available vhosts
self.vhosts = self.get_virtual_hosts()
@ -208,11 +214,12 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator):
self.aug.set(path["chain_path"][-1], chain_path)
# Save notes about the transaction that took place
self.save_notes += ("Changed vhost at %s with addresses of %s\n" %
self.save_notes += ("Changed vhost at %s with addresses of %s\n"
"\tSSLCertificateFile %s\n"
"\tSSLCertificateKeyFile %s\n" %
(vhost.filep,
", ".join(str(addr) for addr in vhost.addrs)))
self.save_notes += "\tSSLCertificateFile %s\n" % cert_path
self.save_notes += "\tSSLCertificateKeyFile %s\n" % key_path
", ".join(str(addr) for addr in vhost.addrs),
cert_path, key_path))
if chain_path is not None:
self.save_notes += "\tSSLCertificateChainFile %s\n" % chain_path
@ -285,7 +292,8 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator):
points = 1
else:
# No points given if names can't be found.
continue
# This gets hit but doesn't register
continue # pragma: no cover
if vhost.ssl:
points += 2
@ -309,19 +317,6 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator):
addr.get_addr() == "_default_" for addr in vh.addrs
)]
def create_dn_server_assoc(self, domain, vhost):
"""Create an association between a domain name and virtual host.
Helps to choose an appropriate vhost
:param str domain: domain name to associate
:param vhost: virtual host to associate with domain
:type vhost: :class:`~letsencrypt_apache.obj.VirtualHost`
"""
self.assoc[domain] = vhost
def get_all_names(self):
"""Returns all names found in the Apache Configuration.
@ -334,10 +329,14 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator):
for vhost in self.vhosts:
all_names.update(vhost.get_names())
for addr in vhost.addrs:
name = self.get_name_from_ip(addr)
if name:
all_names.add(name)
if ApacheConfigurator.hostname_regex.match(addr.get_addr()):
all_names.add(addr.get_addr())
else:
name = self.get_name_from_ip(addr)
if name:
all_names.add(name)
return all_names
@ -460,14 +459,17 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator):
"""
loc = parser.get_aug_path(self.parser.loc["name"])
if addr.get_port == "443":
if addr.get_port() == "443":
path = self.parser.add_dir_to_ifmodssl(
loc, "NameVirtualHost", [str(addr)])
else:
path = self.parser.add_dir(loc, "NameVirtualHost", [str(addr)])
self.save_notes += "Setting %s to be NameBasedVirtualHost\n" % addr
self.save_notes += "\tDirective added to %s\n" % path
msg = ("Setting %s to be NameBasedVirtualHost\n"
"\tDirective added to %s\n" % (addr, path))
logger.debug(msg)
self.save_notes += msg
def prepare_server_https(self, port):
"""Prepare the server for HTTPS.
@ -515,17 +517,6 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator):
if self.version >= (2, 4):
return
# TODO: Review this 3-year old demo code
# Check for NameVirtualHost
# First see if any of the vhost addresses is a _default_ addr
for addr in addrs:
if addr.get_addr() == "_default_":
if not self.is_name_vhost(default_addr):
logger.debug("Setting all VirtualHosts on %s to be "
"name based vhosts", default_addr)
self.add_name_vhost(default_addr)
# No default addresses... so set each one individually
for addr in addrs:
if not self.is_name_vhost(addr):
logger.debug("Setting VirtualHost at %s to be a name "
@ -661,9 +652,11 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator):
need_to_save = False
# See if the exact address appears in any other vhost
# Remember 1.1.1.1:* == 1.1.1.1 -> hence any()
for addr in vhost.addrs:
for test_vh in self.vhosts:
if (vhost.filep != test_vh.filep and addr in test_vh.addrs and
if (vhost.filep != test_vh.filep and
any(test_addr == addr for test_addr in test_vh.addrs) and
not self.is_name_vhost(addr)):
self.add_name_vhost(addr)
logger.info("Enabling NameVirtualHosts on %s", addr)
@ -739,7 +732,7 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator):
"Unable to create one as intended addresses conflict; "
"Current configuration does not support automated "
"redirection")
self._create_redirect_vhost(redirect_addrs)
self._create_redirect_vhost(ssl_vhost)
else:
# Check if redirection already exists
self._verify_no_redirects(general_vh)
@ -817,6 +810,7 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator):
serveralias = ""
servername = ""
if ssl_vhost.name is not None:
servername = "ServerName " + ssl_vhost.name
if ssl_vhost.aliases:
@ -833,9 +827,10 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator):
"ErrorLog /var/log/apache2/redirect.error.log\n"
"LogLevel warn\n"
"</VirtualHost>\n"
% (" ".join(self._get_redirect_addrs(ssl_vhost)),
servername, serveralias,
" ".join(constants.REWRITE_HTTPS_ARGS)))
% (
" ".join(str(addr) for addr in self._get_redirect_addrs(ssl_vhost)),
servername, serveralias,
" ".join(constants.REWRITE_HTTPS_ARGS)))
def _write_out_redirect(self, ssl_vhost, text):
# This is the default name
@ -845,7 +840,7 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator):
if ssl_vhost.name is not None:
# make sure servername doesn't exceed filename length restriction
if len(ssl_vhost.name) < (255 - (len(redirect_filename) + 1)):
redirect_filename = "le-redirect-%s.conf" % ssl_vhost.servername
redirect_filename = "le-redirect-%s.conf" % ssl_vhost.name
redirect_filepath = os.path.join(
self.parser.root, "sites-available", redirect_filename)
@ -900,9 +895,9 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator):
for vhost in self.vhosts:
if vhost.ssl:
cert_path = self.parser.find_dir(
"SSLCertificateFile", None, vhost.path)
"SSLCertificateFile", None, vhost.path, exclude=False)
key_path = self.parser.find_dir(
"SSLCertificateKeyFile", None, vhost.path)
"SSLCertificateKeyFile", None, vhost.path, exclude=False)
if cert_path and key_path:
cert = os.path.abspath(self.parser.get_arg(cert_path[-1]))
@ -940,12 +935,9 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator):
:param vhost: vhost to enable
:type vhost: :class:`~letsencrypt_apache.obj.VirtualHost`
:returns: Success
:rtype: bool
"""
if self.is_site_enabled(vhost.filep):
return True
return
if vhost.ssl:
# TODO: Make this based on addresses
@ -961,8 +953,10 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator):
vhost.enabled = True
logger.info("Enabling available site: %s", vhost.filep)
self.save_notes += "Enabled site %s\n" % vhost.filep
return True
return False
else:
raise errors.MisconfigurationError(
"Unsupported filesystem layout. "
"sites-available/enabled expected.")
def enable_mod(self, mod_name):
"""Enables module in Apache.
@ -976,7 +970,7 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator):
if (not os.path.isdir(os.path.join(self.parser.root, "mods-available"))
or not os.path.isdir(
os.path.join(self.parser.root, "mods-enabled"))):
raise errors.MisconfigurationError(
raise errors.NotSupportedError(
"Unsupported directory layout. You may try to enable mod %s "
"and try again." % mod_name)
@ -1001,7 +995,7 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator):
elif mod_name == "rewrite":
self._enable_mod_debian_files(["rewrite.load"], "rewrite_module")
else:
raise NotImplementedError
raise errors.NotSupportedError
def _enable_mod_debian_files(self, filenames, mod_name):
"""Move over all required files into mods-enabled."""
@ -1011,7 +1005,7 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator):
# Check to see all files are available.
for filename in filenames:
if not os.path.isfile(os.path.join(mods_available, filename)):
raise errors.MisconfigurationError(
raise errors.NoInstallationError(
"Unable to enable module. Required files missing from "
"mods-available. %s" % str(filenames))
@ -1029,6 +1023,8 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator):
def restart(self):
"""Restarts apache server.
.. todo:: This function will be converted to using reload
:returns: Success
:rtype: bool
@ -1053,28 +1049,11 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator):
raise errors.PluginError("Unable to run apache2ctl")
if proc.returncode != 0:
print proc.returncode
# Enter recovery routine...
logger.error("Apache Configtest failed\n%s\n%s", stdout, stderr)
raise errors.MisconfigurationError(
"Apache Configtest failure:\n%s\n%s" % (stdout, stderr))
def verify_setup(self):
"""Verify the setup to ensure safe operating environment.
Make sure that files/directories are setup with appropriate permissions
Aim for defensive coding... make sure all input files
have permissions of root
"""
uid = os.geteuid()
le_util.make_or_verify_dir(
self.config.config_dir, core_constants.CONFIG_DIRS_MODE, uid)
le_util.make_or_verify_dir(
self.config.work_dir, core_constants.CONFIG_DIRS_MODE, uid)
le_util.make_or_verify_dir(
self.config.backup_dir, core_constants.CONFIG_DIRS_MODE, uid)
def get_version(self):
"""Return version of Apache Server.
@ -1129,7 +1108,7 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator):
outstanding challenges will have to be designed better.
"""
self._chall_out += len(achalls)
self._chall_out.update(achalls)
responses = [None] * len(achalls)
apache_dvsni = dvsni.ApacheDvsni(self)
@ -1157,10 +1136,10 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator):
def cleanup(self, achalls):
"""Revert all challenges."""
self._chall_out -= len(achalls)
self._chall_out.difference_update(achalls)
# If all of the challenges have been finished, clean up everything
if self._chall_out <= 0:
if not self._chall_out:
self.revert_challenge_config()
self.restart()
@ -1192,7 +1171,7 @@ def apache_restart(apache_init_script):
except (OSError, ValueError):
logger.fatal(
"Unable to restart the Apache process with %s", apache_init_script)
raise errors.PluginError(
raise errors.MisconfigurationError(
"Unable to restart Apache process with %s" % apache_init_script)
stdout, stderr = proc.communicate()

View file

@ -1,6 +1,7 @@
"""Test for letsencrypt_apache.configurator."""
import os
import shutil
import socket
import unittest
import mock
@ -36,6 +37,15 @@ class TwoVhost80Test(util.ApacheTest):
shutil.rmtree(self.config_dir)
shutil.rmtree(self.work_dir)
@mock.patch("letsencrypt_apache.parser.ApacheParser")
def test_prepare_version(self, mock_parser):
self.config.version = None
self.config.config_test = mock.Mock()
self.config.get_version = mock.Mock(return_value=(1, 1))
self.assertRaises(
errors.NotSupportedError, self.config.prepare)
def test_add_parser_arguments(self):
from letsencrypt_apache.configurator import ApacheConfigurator
# Weak test..
@ -46,6 +56,31 @@ class TwoVhost80Test(util.ApacheTest):
self.assertEqual(names, set(
["letsencrypt.demo", "encryption-example.demo", "ip-172-30-0-17"]))
@mock.patch("letsencrypt_apache.configurator.socket.gethostbyaddr")
def test_get_all_names_addrs(self, mock_gethost):
mock_gethost.side_effect = [("google.com","",""), socket.error]
vh = obj.VirtualHost(
"fp", "ap",
set([obj.Addr(("8.8.8.8", "443")),
obj.Addr(("zombo.com",)),
obj.Addr(("192.168.1.2"))]),
True, False)
self.config.vhosts.append(vh)
names = self.config.get_all_names()
self.assertEqual(len(names), 5)
self.assertTrue("zombo.com" in names)
self.assertTrue("google.com" in names)
self.assertTrue("letsencrypt.demo" in names)
def test_add_servernames_alias(self):
self.config.parser.add_dir(
self.vh_truth[2].path, "ServerAlias", ["*.le.co"])
self.config._add_servernames(self.vh_truth[2]) # pylint: disable=protected-access
self.assertEqual(
self.vh_truth[2].get_names(), set(["*.le.co", "ip-172-30-0-17"]))
def test_get_virtual_hosts(self):
"""Make sure all vhosts are being properly found.
@ -88,6 +123,13 @@ class TwoVhost80Test(util.ApacheTest):
self.assertTrue(
self.config._find_best_vhost("does-not-exist.com") is None)
def test_find_best_vhost_variety(self):
ssl_vh = obj.VirtualHost(
"fp", "ap", set([obj.Addr(("*", "443")), obj.Addr(("zombo.com",))]),
True, False)
self.config.vhosts.append(ssl_vh)
self.assertEqual(self.config._find_best_vhost("zombo.com"), ssl_vh)
def test_find_best_vhost_default(self):
# Assume only the two default vhosts.
self.config.vhosts = [vh for vh in self.config.vhosts
@ -129,6 +171,27 @@ class TwoVhost80Test(util.ApacheTest):
self.assertTrue("ssl_module" in self.config.parser.modules)
self.assertTrue("mod_ssl.c" in self.config.parser.modules)
def test_enable_mod_unsupported_dirs(self):
os.removedirs(os.path.join(self.config.parser.root, "mods-enabled"))
self.assertRaises(
errors.NotSupportedError, self.config.enable_mod, "ssl")
def test_enable_mod_unsupported_mod(self):
self.assertRaises(
errors.NotSupportedError, self.config.enable_mod, "unknown")
def test_enable_mod_not_installed(self):
os.remove(os.path.join(
self.config.parser.root, "mods-available", "ssl.load"))
self.assertRaises(
errors.NoInstallationError, self.config.enable_mod, "ssl")
def test_enable_mod_files_already_exist(self):
path = os.path.join(self.config.parser.root, "mods-enabled", "ssl.load")
open(path, "w").close()
self.assertRaises(
errors.PluginError, self.config.enable_mod, "ssl")
@mock.patch("letsencrypt_apache.parser.subprocess.Popen")
def test_enable_site(self, mock_popen):
mock_popen().returncode = 0
@ -139,6 +202,15 @@ class TwoVhost80Test(util.ApacheTest):
self.config.enable_site(self.vh_truth[1])
self.assertTrue(self.vh_truth[1].enabled)
# Go again to make sure nothing fails
self.config.enable_site(self.vh_truth[1])
def test_enable_site_failure(self):
self.assertRaises(
errors.MisconfigurationError,
self.config.enable_site,
obj.VirtualHost("asdf", "afsaf", set(), False, False))
@mock.patch("letsencrypt_apache.parser.subprocess.Popen")
def test_deploy_cert(self, mock_popen):
mock_popen().returncode = 0
@ -204,8 +276,11 @@ class TwoVhost80Test(util.ApacheTest):
def test_add_name_vhost(self):
self.config.add_name_vhost(obj.Addr.fromstring("*:443"))
self.config.add_name_vhost(obj.Addr.fromstring("*:80"))
self.assertTrue(self.config.parser.find_dir(
"NameVirtualHost", "*:443"))
"NameVirtualHost", "*:443", exclude=False))
self.assertTrue(self.config.parser.find_dir(
"NameVirtualHost", "*:80"))
def test_prepare_server_https(self):
self.config.parser.modules.add("ssl_module")
@ -218,7 +293,8 @@ class TwoVhost80Test(util.ApacheTest):
self.config.parser.add_dir_to_ifmodssl = mock_add_dir
self.config.prepare_server_https("443")
self.assertTrue(mock_add_dir.called)
self.config.prepare_server_https("8080")
self.assertEqual(mock_add_dir.call_count, 2)
def test_make_vhost_ssl(self):
ssl_vhost = self.config.make_vhost_ssl(self.vh_truth[0])
@ -246,26 +322,37 @@ class TwoVhost80Test(util.ApacheTest):
self.assertEqual(len(self.config.vhosts), 5)
def test_make_vhost_ssl_extra_vhs(self):
self.config.aug.match = mock.Mock(return_value=["p1", "p2"])
self.assertRaises(
errors.PluginError, self.config.make_vhost_ssl, self.vh_truth[0])
def test_make_vhost_ssl_bad_write(self):
mock_open = mock.mock_open()
# This calls open
self.config.reverter.register_file_creation = mock.Mock()
mock_open.side_effect = IOError
with mock.patch("__builtin__.open", mock_open):
self.assertRaises(
errors.PluginError,
self.config.make_vhost_ssl, self.vh_truth[0])
def test_get_ssl_vhost_path(self):
self.assertTrue(
self.config._get_ssl_vhost_path("example_path").endswith(".conf"))
def test_add_name_vhost_if_necessary(self):
self.config.save = mock.Mock()
self.config.version = (2, 2)
self.config._add_name_vhost_if_necessary(self.vh_truth[0])
self.assertTrue(self.config.save.called)
@mock.patch("letsencrypt_apache.configurator.dvsni.ApacheDvsni.perform")
@mock.patch("letsencrypt_apache.configurator.ApacheConfigurator.restart")
def test_perform(self, mock_restart, mock_dvsni_perform):
# Only tests functionality specific to configurator.perform
# Note: As more challenges are offered this will have to be expanded
auth_key = le_util.Key(self.rsa256_file, self.rsa256_pem)
achall1 = achallenges.DVSNI(
challb=acme_util.chall_to_challb(
challenges.DVSNI(
r="jIq_Xy1mXGN37tb4L6Xj_es58fW571ZNyXekdZzhh7Q",
nonce="37bc5eb75d3e00a19b4f6355845e5a18"),
"pending"),
domain="encryption-example.demo", key=auth_key)
achall2 = achallenges.DVSNI(
challb=acme_util.chall_to_challb(
challenges.DVSNI(
r="uqnaPzxtrndteOqtrXb0Asl5gOJfWAnnx6QJyvcmlDU",
nonce="59ed014cac95f77057b1d7a1b2c596ba"),
"pending"),
domain="letsencrypt.demo", key=auth_key)
auth_key, achall1, achall2 = self.get_achalls()
dvsni_ret_val = [
challenges.DVSNIResponse(s="randomS1"),
@ -280,6 +367,31 @@ class TwoVhost80Test(util.ApacheTest):
self.assertEqual(mock_restart.call_count, 1)
@mock.patch("letsencrypt_apache.configurator.ApacheConfigurator.restart")
def test_cleanup(self, mock_restart):
auth_key, achall1, achall2 = self.get_achalls()
self.config._chall_out.add(achall1)
self.config._chall_out.add(achall2)
self.config.cleanup([achall1])
self.assertFalse(mock_restart.called)
self.config.cleanup([achall2])
self.assertTrue(mock_restart.called)
@mock.patch("letsencrypt_apache.configurator.ApacheConfigurator.restart")
def test_cleanup_no_errors(self, mock_restart):
auth_key, achall1, achall2 = self.get_achalls()
self.config._chall_out.add(achall1)
self.config.cleanup([achall2])
self.assertFalse(mock_restart.called)
self.config.cleanup([achall1, achall2])
self.assertTrue(mock_restart.called)
@mock.patch("letsencrypt_apache.configurator.subprocess.Popen")
def test_get_version(self, mock_popen):
mock_popen().communicate.return_value = (
@ -301,7 +413,79 @@ class TwoVhost80Test(util.ApacheTest):
mock_popen.side_effect = OSError("Can't find program")
self.assertRaises(errors.PluginError, self.config.get_version)
@mock.patch("letsencrypt_apache.configurator.subprocess.Popen")
def test_restart(self, mock_popen):
"""These will be changed soon enough with reload."""
mock_popen().returncode = 0
mock_popen().communicate.return_value = ("", "")
self.config.restart()
@mock.patch("letsencrypt_apache.configurator.subprocess.Popen")
def test_restart_bad_process(self, mock_popen):
mock_popen.side_effect = OSError
self.assertRaises(errors.MisconfigurationError, self.config.restart)
@mock.patch("letsencrypt_apache.configurator.subprocess.Popen")
def test_restart_failure(self, mock_popen):
mock_popen().communicate.return_value = ("", "")
mock_popen.returncode=1
self.assertRaises(errors.MisconfigurationError, self.config.restart)
@mock.patch("letsencrypt_apache.configurator.subprocess.Popen")
def test_config_test(self, mock_popen):
mock_popen().communicate.return_value = ("a", "b")
mock_popen().returncode = 0
self.config.config_test()
@mock.patch("letsencrypt_apache.configurator.subprocess.Popen")
def test_config_test_bad_process(self, mock_popen):
mock_popen.side_effect = ValueError
self.assertRaises(errors.PluginError, self.config.config_test)
@mock.patch("letsencrypt_apache.configurator.subprocess.Popen")
def test_config_test_failure(self, mock_popen):
mock_popen().communicate.return_value = ("", "")
mock_popen().returncode = -1
self.assertRaises(errors.MisconfigurationError, self.config.config_test)
def test_get_all_certs_keys(self):
c_k = self.config.get_all_certs_keys()
self.assertEqual(len(c_k), 1)
cert, key, path = next(iter(c_k))
self.assertTrue("cert" in cert)
self.assertTrue("key" in key)
self.assertTrue("default-ssl.conf" in path)
def test_get_all_certs_keys_malformed_conf(self):
self.config.parser.find_dir = mock.Mock(side_effect=[["path"], []])
c_k = self.config.get_all_certs_keys()
self.assertFalse(c_k)
def test_more_info(self):
self.assertTrue(self.config.more_info())
def test_get_chall_pref(self):
self.assertTrue(isinstance(self.config.get_chall_pref(""), list))
def test_temp_install(self):
from letsencrypt_apache.configurator import temp_install
path = os.path.join(self.work_dir, "test_it")
temp_install(path)
self.assertTrue(os.path.isfile(path))
# TEST ENHANCEMENTS
def test_supported_enhancements(self):
self.assertTrue(isinstance(self.config.supported_enhancements(), list))
def test_enhance_unknown_enhancement(self):
self.assertRaises(
errors.PluginError,
@ -329,6 +513,17 @@ class TwoVhost80Test(util.ApacheTest):
self.assertTrue("rewrite_module" in self.config.parser.modules)
def test_redirect_with_conflict(self):
self.config.parser.modules.add("rewrite_module")
ssl_vh = obj.VirtualHost(
"fp", "ap", set([obj.Addr(("*", "443")), obj.Addr(("zombo.com",))]),
True, False)
# No names ^ this guy should conflict.
# pylint: disable=protected-access
self.assertRaises(
errors.PluginError, self.config._enable_redirect, ssl_vh, "")
def test_redirect_twice(self):
# Skip the enable mod
self.config.parser.modules.add("rewrite_module")
@ -346,6 +541,15 @@ class TwoVhost80Test(util.ApacheTest):
self.assertRaises(
errors.PluginError,
self.config.enhance, "letsencrypt.demo", "redirect")
def test_unknown_rewrite2(self):
# Skip the enable mod
self.config.parser.modules.add("rewrite_module")
self.config.parser.add_dir(
self.vh_truth[3].path, "RewriteRule", ["Unknown", "2", "3"])
self.config.save()
self.assertRaises(
errors.PluginError,
self.config.enhance, "letsencrypt.demo", "redirect")
def test_unknown_redirect(self):
# Skip the enable mod
@ -357,6 +561,43 @@ class TwoVhost80Test(util.ApacheTest):
errors.PluginError,
self.config.enhance, "letsencrypt.demo", "redirect")
def test_create_own_redirect(self):
self.config.parser.modules.add("rewrite_module")
# For full testing... give names...
self.vh_truth[1].name = "default.com"
self.vh_truth[1].aliases = set(["yes.default.com"])
self.config._enable_redirect(self.vh_truth[1], "") # pylint: disable=protected-access
self.assertEqual(len(self.config.vhosts), 5)
def get_achalls(self):
auth_key = le_util.Key(self.rsa256_file, self.rsa256_pem)
achall1 = achallenges.DVSNI(
challb=acme_util.chall_to_challb(
challenges.DVSNI(
r="jIq_Xy1mXGN37tb4L6Xj_es58fW571ZNyXekdZzhh7Q",
nonce="37bc5eb75d3e00a19b4f6355845e5a18"),
"pending"),
domain="encryption-example.demo", key=auth_key)
achall2 = achallenges.DVSNI(
challb=acme_util.chall_to_challb(
challenges.DVSNI(
r="uqnaPzxtrndteOqtrXb0Asl5gOJfWAnnx6QJyvcmlDU",
nonce="59ed014cac95f77057b1d7a1b2c596ba"),
"pending"),
domain="letsencrypt.demo", key=auth_key)
return auth_key, achall1, achall2
def test_make_addrs_sni_ready(self):
self.config.version = (2, 2)
self.config.make_addrs_sni_ready(
set([obj.Addr.fromstring("*:443"), obj.Addr.fromstring("*:80")]))
self.assertTrue(self.config.parser.find_dir(
"NameVirtualHost", "*:80", exclude=False))
self.assertTrue(self.config.parser.find_dir(
"NameVirtualHost", "*:443", exclude=False))
if __name__ == "__main__":
unittest.main() # pragma: no cover

View file

@ -172,7 +172,7 @@ def run(args, config, plugins):
authenticator = display_ops.pick_authenticator(
config, args.authenticator, plugins)
else:
# TODO: this assume that user doesn't want to pick authenticator
# TODO: this assumes that user doesn't want to pick authenticator
# and installer separately...
authenticator = installer = display_ops.pick_configurator(
config, args.configurator, plugins)

View file

@ -65,6 +65,9 @@ class NoInstallationError(PluginError):
class MisconfigurationError(PluginError):
"""Let's Encrypt Misconfiguration error."""
class NotSupportedError(PluginError):
"""Let's Encrypt Plugin function not supported error."""
class RevokerError(Error):
"""Let's Encrypt Revoker error."""