Move IAuthenticators and IInstallers into plugins dir

This commit is contained in:
James Kasten 2015-03-26 17:23:17 -07:00
parent 1b206e495b
commit 2d848994f4
57 changed files with 173 additions and 138 deletions

View file

@ -1 +0,0 @@
"""Let's Encrypt client.apache."""

View file

@ -23,7 +23,7 @@ from letsencrypt.client import network
from letsencrypt.client import reverter
from letsencrypt.client import revoker
from letsencrypt.client.apache import configurator
from letsencrypt.client.plugins.apache import configurator
from letsencrypt.client.display import ops as display_ops
from letsencrypt.client.display import enhancements

View file

@ -31,7 +31,7 @@ List of expected options parameters:
APACHE_MOD_SSL_CONF = pkg_resources.resource_filename(
"letsencrypt.client.apache", "options-ssl.conf")
"letsencrypt.client.plugins.apache", "options-ssl.conf")
"""Path to the Apache mod_ssl config file found in the Let's Encrypt
distribution."""

View file

@ -0,0 +1 @@
"""Let's Encrypt client.plugins."""

View file

@ -0,0 +1 @@
"""Let's Encrypt client.plugins.apache."""

View file

@ -18,9 +18,9 @@ from letsencrypt.client import errors
from letsencrypt.client import interfaces
from letsencrypt.client import le_util
from letsencrypt.client.apache import dvsni
from letsencrypt.client.apache import obj
from letsencrypt.client.apache import parser
from letsencrypt.client.plugins.apache import dvsni
from letsencrypt.client.plugins.apache import obj
from letsencrypt.client.plugins.apache import parser
# TODO: Augeas sections ie. <VirtualHost>, <IfModule> beginning and closing
@ -68,11 +68,12 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator):
:type config: :class:`~letsencrypt.client.interfaces.IConfig`
:ivar parser: Handles low level parsing
:type parser: :class:`letsencrypt.client.apache.parser`
:type parser: :class:`letsencrypt.client.plugins.apache.parser`
:ivar tup version: version of Apache
:ivar list vhosts: All vhosts found in the configuration
(:class:`list` of :class:`letsencrypt.client.apache.obj.VirtualHost`)
(:class:`list` of
:class:`letsencrypt.client.plugins.apache.obj.VirtualHost`)
:ivar dict assoc: Mapping between domains and vhosts
@ -203,7 +204,7 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator):
:param str target_name: domain name
:returns: ssl vhost associated with name
:rtype: :class:`letsencrypt.client.apache.obj.VirtualHost`
:rtype: :class:`letsencrypt.client.plugins.apache.obj.VirtualHost`
"""
# Allows for domain names to be associated with a virtual host
@ -244,7 +245,7 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator):
:param str domain: domain name to associate
:param vhost: virtual host to associate with domain
:type vhost: :class:`letsencrypt.client.apache.obj.VirtualHost`
:type vhost: :class:`letsencrypt.client.plugins.apache.obj.VirtualHost`
"""
self.assoc[domain] = vhost
@ -281,7 +282,7 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator):
"""Helper function for get_virtual_hosts().
:param host: In progress vhost whose names will be added
:type host: :class:`letsencrypt.client.apache.obj.VirtualHost`
:type host: :class:`letsencrypt.client.plugins.apache.obj.VirtualHost`
"""
name_match = self.aug.match(("%s//*[self::directive=~regexp('%s')] | "
@ -302,7 +303,7 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator):
:param str path: Augeas path to virtual host
:returns: newly created vhost
:rtype: :class:`letsencrypt.client.apache.obj.VirtualHost`
:rtype: :class:`letsencrypt.client.plugins.apache.obj.VirtualHost`
"""
addrs = set()
@ -326,7 +327,7 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator):
"""Returns list of virtual hosts found in the Apache configuration.
:returns: List of
:class:`letsencrypt.client.apache.obj.VirtualHost` objects
:class:`letsencrypt.client.plugins.apache.obj.VirtualHost` objects
found in configuration
:rtype: list
@ -404,7 +405,7 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator):
"""Checks to see if the server is ready for SNI challenges.
:param vhost: VirtualHost to check SNI compatibility
:type vhost: :class:`letsencrypt.client.apache.obj.VirtualHost`
:type vhost: :class:`letsencrypt.client.plugins.apache.obj.VirtualHost`
:param str default_addr: TODO - investigate function further
@ -436,10 +437,10 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator):
.. note:: This function saves the configuration
:param nonssl_vhost: Valid VH that doesn't have SSLEngine on
:type nonssl_vhost: :class:`letsencrypt.client.apache.obj.VirtualHost`
:type nonssl_vhost: :class:`~apache.obj.VirtualHost`
:returns: SSL vhost
:rtype: :class:`letsencrypt.client.apache.obj.VirtualHost`
:rtype: :class:`letsencrypt.client.plugins.apache.obj.VirtualHost`
"""
avail_fp = nonssl_vhost.filep
@ -559,13 +560,13 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator):
.. note:: This function saves the configuration
:param ssl_vhost: Destination of traffic, an ssl enabled vhost
:type ssl_vhost: :class:`letsencrypt.client.apache.obj.VirtualHost`
:type ssl_vhost: :class:`~apache.obj.VirtualHost`
:param unused_options: Not currently used
:type unused_options: Not Available
:returns: Success, general_vhost (HTTP vhost)
:rtype: (bool, :class:`letsencrypt.client.apache.obj.VirtualHost`)
:rtype: (bool, :class:`~apache.obj.VirtualHost`)
"""
if not mod_loaded("rewrite_module", self.config.apache_ctl):
@ -617,7 +618,7 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator):
-1 is also returned in case of no redirection/rewrite directives
:param vhost: vhost to check
:type vhost: :class:`letsencrypt.client.apache.obj.VirtualHost`
:type vhost: :class:`letsencrypt.client.plugins.apache.obj.VirtualHost`
:returns: Success, code value... see documentation
:rtype: bool, int
@ -649,10 +650,10 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator):
"""Creates an http_vhost specifically to redirect for the ssl_vhost.
:param ssl_vhost: ssl vhost
:type ssl_vhost: :class:`letsencrypt.client.apache.obj.VirtualHost`
:type ssl_vhost: :class:`~apache.obj.VirtualHost`
:returns: Success, vhost
:rtype: (bool, :class:`letsencrypt.client.apache.obj.VirtualHost`)
:rtype: (bool, :class:`~apache.obj.VirtualHost`)
"""
# Consider changing this to a dictionary check
@ -734,7 +735,7 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator):
if not conflict: returns space separated list of new host addrs
:param ssl_vhost: SSL Vhost to check for possible port 80 redirection
:type ssl_vhost: :class:`letsencrypt.client.apache.obj.VirtualHost`
:type ssl_vhost: :class:`~apache.obj.VirtualHost`
:returns: TODO
:rtype: TODO
@ -767,10 +768,10 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator):
Consider changing this into a dict check
:param ssl_vhost: ssl vhost to check
:type ssl_vhost: :class:`letsencrypt.client.apache.obj.VirtualHost`
:type ssl_vhost: :class:`~apache.obj.VirtualHost`
:returns: HTTP vhost or None if unsuccessful
:rtype: :class:`letsencrypt.client.apache.obj.VirtualHost` or None
:rtype: :class:`~apache.obj.VirtualHost` or None
"""
# _default_:443 check
@ -860,7 +861,7 @@ class ApacheConfigurator(augeas_configurator.AugeasConfigurator):
.. todo:: Make sure link is not broken...
:param vhost: vhost to enable
:type vhost: :class:`letsencrypt.client.apache.obj.VirtualHost`
:type vhost: :class:`~apache.obj.VirtualHost`
:returns: Success
:rtype: bool

View file

@ -2,20 +2,19 @@
import logging
import os
from letsencrypt.client.apache import parser
from letsencrypt.client.plugins.apache import parser
class ApacheDvsni(object):
"""Class performs DVSNI challenges within the Apache configurator.
:ivar configurator: ApacheConfigurator object
:type configurator:
:class:`letsencrypt.client.apache.configurator.ApacheConfigurator`
:type configurator: :class:`~apache.configurator.ApacheConfigurator`
:ivar list achalls: Annotated :class:`~letsencrypt.client.achallenges.DVSNI`
challenges.
:param list indicies: Meant to hold indices of challenges in a
:param list indices: Meant to hold indices of challenges in a
larger array. ApacheDvsni is capable of solving many challenges
at once which causes an indexing issue within ApacheConfigurator
who must return all responses in order. Imagine ApacheConfigurator
@ -129,7 +128,7 @@ class ApacheDvsni(object):
Result: Apache config includes virtual servers for issued challs
:param list ll_addrs: list of list of
:class:`letsencrypt.client.apache.obj.Addr` to apply
:class:`letsencrypt.client.plugins.apache.obj.Addr` to apply
"""
# TODO: Use ip address of existing vhost instead of relying on FQDN
@ -168,7 +167,7 @@ class ApacheDvsni(object):
:type achall: :class:`letsencrypt.client.achallenges.DVSNI`
:param list ip_addrs: addresses of challenged domain
:class:`list` of type :class:`letsencrypt.client.apache.obj.Addr`
:class:`list` of type :class:`~apache.obj.Addr`
:returns: virtual host configuration text
:rtype: str

View file

@ -1,4 +1,4 @@
"""Test for letsencrypt.client.apache.configurator."""
"""Test for letsencrypt.client.plugins.apache.configurator."""
import os
import re
import shutil
@ -12,11 +12,11 @@ from letsencrypt.client import achallenges
from letsencrypt.client import errors
from letsencrypt.client import le_util
from letsencrypt.client.apache import configurator
from letsencrypt.client.apache import obj
from letsencrypt.client.apache import parser
from letsencrypt.client.plugins.apache import configurator
from letsencrypt.client.plugins.apache import obj
from letsencrypt.client.plugins.apache import parser
from letsencrypt.client.tests.apache import util
from letsencrypt.client.plugins.apache.tests import util
class TwoVhost80Test(util.ApacheTest):
@ -25,7 +25,7 @@ class TwoVhost80Test(util.ApacheTest):
def setUp(self):
super(TwoVhost80Test, self).setUp()
with mock.patch("letsencrypt.client.apache.configurator."
with mock.patch("letsencrypt.client.plugins.apache.configurator."
"mod_loaded") as mock_load:
mock_load.return_value = True
self.config = util.get_apache_configurator(
@ -46,6 +46,12 @@ class TwoVhost80Test(util.ApacheTest):
['letsencrypt.demo', 'encryption-example.demo', 'ip-172-30-0-17']))
def test_get_virtual_hosts(self):
"""Make sure all vhosts are being properly found.
.. note:: If test fails, only finding 1 Vhost... it is likely that
it is a problem with is_enabled.
"""
vhs = self.config.get_virtual_hosts()
self.assertEqual(len(vhs), 4)
found = 0
@ -59,6 +65,14 @@ class TwoVhost80Test(util.ApacheTest):
self.assertEqual(found, 4)
def test_is_site_enabled(self):
"""Test if site is enabled.
.. note:: This test currently fails for hard links
(which may happen if you move dirs incorrectly)
.. warning:: This test does not work when running using the
unittest.main() function. It incorrectly copies symlinks.
"""
self.assertTrue(self.config.is_site_enabled(self.vh_truth[0].filep))
self.assertFalse(self.config.is_site_enabled(self.vh_truth[1].filep))
self.assertTrue(self.config.is_site_enabled(self.vh_truth[2].filep))
@ -134,9 +148,9 @@ class TwoVhost80Test(util.ApacheTest):
self.assertEqual(len(self.config.vhosts), 5)
@mock.patch("letsencrypt.client.apache.configurator."
@mock.patch("letsencrypt.client.plugins.apache.configurator."
"dvsni.ApacheDvsni.perform")
@mock.patch("letsencrypt.client.apache.configurator."
@mock.patch("letsencrypt.client.plugins.apache.configurator."
"ApacheConfigurator.restart")
def test_perform(self, mock_restart, mock_dvsni_perform):
# Only tests functionality specific to configurator.perform
@ -166,7 +180,7 @@ class TwoVhost80Test(util.ApacheTest):
self.assertEqual(mock_restart.call_count, 1)
@mock.patch("letsencrypt.client.apache.configurator."
@mock.patch("letsencrypt.client.plugins.apache.configurator."
"subprocess.Popen")
def test_get_version(self, mock_popen):
mock_popen().communicate.return_value = (

View file

@ -1,4 +1,4 @@
"""Test for letsencrypt.client.apache.dvsni."""
"""Test for letsencrypt.client.plugins.apache.dvsni."""
import pkg_resources
import unittest
import shutil
@ -10,9 +10,9 @@ from letsencrypt.acme import challenges
from letsencrypt.client import achallenges
from letsencrypt.client import le_util
from letsencrypt.client.apache.obj import Addr
from letsencrypt.client.plugins.apache.obj import Addr
from letsencrypt.client.tests.apache import util
from letsencrypt.client.plugins.apache.tests import util
class DvsniPerformTest(util.ApacheTest):
@ -21,20 +21,20 @@ class DvsniPerformTest(util.ApacheTest):
def setUp(self):
super(DvsniPerformTest, self).setUp()
with mock.patch("letsencrypt.client.apache.configurator."
with mock.patch("letsencrypt.client.plugins.apache.configurator."
"mod_loaded") as mock_load:
mock_load.return_value = True
config = util.get_apache_configurator(
self.config_path, self.config_dir, self.work_dir,
self.ssl_options)
from letsencrypt.client.apache import dvsni
from letsencrypt.client.plugins.apache import dvsni
self.sni = dvsni.ApacheDvsni(config)
rsa256_file = pkg_resources.resource_filename(
"letsencrypt.client.tests", 'testdata/rsa256_key.pem')
"letsencrypt.client.tests", "testdata/rsa256_key.pem")
rsa256_pem = pkg_resources.resource_string(
"letsencrypt.client.tests", 'testdata/rsa256_key.pem')
"letsencrypt.client.tests", "testdata/rsa256_key.pem")
auth_key = le_util.Key(rsa256_file, rsa256_pem)
self.achalls = [
@ -74,7 +74,7 @@ class DvsniPerformTest(util.ApacheTest):
nonce_domain=self.achalls[0].nonce_domain)
achall.gen_cert_and_response.return_value = ("pem", response)
with mock.patch("letsencrypt.client.apache.dvsni.open",
with mock.patch("letsencrypt.client.plugins.apache.dvsni.open",
m_open, create=True):
# pylint: disable=protected-access
self.assertEqual(response, self.sni._setup_challenge_cert(
@ -82,7 +82,7 @@ class DvsniPerformTest(util.ApacheTest):
self.assertTrue(m_open.called)
self.assertEqual(
m_open.call_args[0], (self.sni.get_cert_file(achall), 'w'))
m_open.call_args[0], (self.sni.get_cert_file(achall), "w"))
self.assertEqual(m_open().write.call_args[0][0], "pem")
def test_perform1(self):
@ -166,5 +166,5 @@ class DvsniPerformTest(util.ApacheTest):
set([self.achalls[1].nonce_domain]))
if __name__ == '__main__':
if __name__ == "__main__":
unittest.main()

View file

@ -1,11 +1,11 @@
"""Test the helper objects in apache.obj.py."""
"""Test the helper objects in letsencrypt.client.plugins.apache.obj."""
import unittest
class AddrTest(unittest.TestCase):
"""Test the Addr class."""
def setUp(self):
from letsencrypt.client.apache.obj import Addr
from letsencrypt.client.plugins.apache.obj import Addr
self.addr1 = Addr.fromstring("192.168.1.1")
self.addr2 = Addr.fromstring("192.168.1.1:*")
self.addr3 = Addr.fromstring("192.168.1.1:80")
@ -34,7 +34,7 @@ class AddrTest(unittest.TestCase):
self.assertFalse(self.addr1 == 3333)
def test_set_inclusion(self):
from letsencrypt.client.apache.obj import Addr
from letsencrypt.client.plugins.apache.obj import Addr
set_a = set([self.addr1, self.addr2])
addr1b = Addr.fromstring("192.168.1.1")
addr2b = Addr.fromstring("192.168.1.1:*")
@ -46,15 +46,15 @@ class AddrTest(unittest.TestCase):
class VirtualHostTest(unittest.TestCase):
"""Test the VirtualHost class."""
def setUp(self):
from letsencrypt.client.apache.obj import VirtualHost
from letsencrypt.client.apache.obj import Addr
from letsencrypt.client.plugins.apache.obj import VirtualHost
from letsencrypt.client.plugins.apache.obj import Addr
self.vhost1 = VirtualHost(
"filep", "vh_path",
set([Addr.fromstring("localhost")]), False, False)
def test_eq(self):
from letsencrypt.client.apache.obj import Addr
from letsencrypt.client.apache.obj import VirtualHost
from letsencrypt.client.plugins.apache.obj import Addr
from letsencrypt.client.plugins.apache.obj import VirtualHost
vhost1b = VirtualHost(
"filep", "vh_path",
set([Addr.fromstring("localhost")]), False, False)

View file

@ -1,4 +1,4 @@
"""Tests the ApacheParser class."""
"""Tests for letsencrypt.client.plugins.apache.parser."""
import os
import shutil
import sys
@ -11,7 +11,7 @@ import zope.component
from letsencrypt.client import errors
from letsencrypt.client.display import util as display_util
from letsencrypt.client.tests.apache import util
from letsencrypt.client.plugins.apache.tests import util
class ApacheParserTest(util.ApacheTest):
@ -22,7 +22,7 @@ class ApacheParserTest(util.ApacheTest):
zope.component.provideUtility(display_util.FileDisplay(sys.stdout))
from letsencrypt.client.apache.parser import ApacheParser
from letsencrypt.client.plugins.apache.parser import ApacheParser
self.aug = augeas.Augeas(flags=augeas.Augeas.NONE)
self.parser = ApacheParser(self.aug, self.config_path, self.ssl_options)
@ -32,19 +32,19 @@ class ApacheParserTest(util.ApacheTest):
shutil.rmtree(self.work_dir)
def test_root_normalized(self):
from letsencrypt.client.apache.parser import ApacheParser
from letsencrypt.client.plugins.apache.parser import ApacheParser
path = os.path.join(self.temp_dir, "debian_apache_2_4/////"
"two_vhost_80/../two_vhost_80/apache2")
parser = ApacheParser(self.aug, path, None)
self.assertEqual(parser.root, self.config_path)
def test_root_absolute(self):
from letsencrypt.client.apache.parser import ApacheParser
from letsencrypt.client.plugins.apache.parser import ApacheParser
parser = ApacheParser(self.aug, os.path.relpath(self.config_path), None)
self.assertEqual(parser.root, self.config_path)
def test_root_no_trailing_slash(self):
from letsencrypt.client.apache.parser import ApacheParser
from letsencrypt.client.plugins.apache.parser import ApacheParser
parser = ApacheParser(self.aug, self.config_path + os.path.sep, None)
self.assertEqual(parser.root, self.config_path)
@ -67,7 +67,7 @@ class ApacheParserTest(util.ApacheTest):
self.assertTrue(matches)
def test_find_dir(self):
from letsencrypt.client.apache.parser import case_i
from letsencrypt.client.plugins.apache.parser import case_i
test = self.parser.find_dir(case_i("Listen"), "443")
# This will only look in enabled hosts
test2 = self.parser.find_dir(case_i("documentroot"))
@ -92,7 +92,7 @@ class ApacheParserTest(util.ApacheTest):
Path must be valid before attempting to add to augeas
"""
from letsencrypt.client.apache.parser import get_aug_path
from letsencrypt.client.plugins.apache.parser import get_aug_path
self.parser.add_dir_to_ifmodssl(
get_aug_path(self.parser.loc["default"]),
"FakeDirective", "123")
@ -103,11 +103,11 @@ class ApacheParserTest(util.ApacheTest):
self.assertTrue("IfModule" in matches[0])
def test_get_aug_path(self):
from letsencrypt.client.apache.parser import get_aug_path
from letsencrypt.client.plugins.apache.parser import get_aug_path
self.assertEqual("/files/etc/apache", get_aug_path("/etc/apache"))
def test_set_locations(self):
with mock.patch("letsencrypt.client.apache.parser."
with mock.patch("letsencrypt.client.plugins.apache.parser."
"os.path") as mock_path:
mock_path.isfile.return_value = False

View file

@ -1,4 +1,4 @@
"""Common utilities for letsencrypt.client.apache."""
"""Common utilities for letsencrypt.client.plugins.apache."""
import os
import pkg_resources
import shutil
@ -8,8 +8,8 @@ import unittest
import mock
from letsencrypt.client import constants
from letsencrypt.client.apache import configurator
from letsencrypt.client.apache import obj
from letsencrypt.client.plugins.apache import configurator
from letsencrypt.client.plugins.apache import obj
class ApacheTest(unittest.TestCase): # pylint: disable=too-few-public-methods
@ -26,9 +26,9 @@ class ApacheTest(unittest.TestCase): # pylint: disable=too-few-public-methods
self.temp_dir, "debian_apache_2_4/two_vhost_80/apache2")
self.rsa256_file = pkg_resources.resource_filename(
"letsencrypt.client.tests", 'testdata/rsa256_key.pem')
"letsencrypt.client.tests", "testdata/rsa256_key.pem")
self.rsa256_pem = pkg_resources.resource_string(
"letsencrypt.client.tests", 'testdata/rsa256_key.pem')
"letsencrypt.client.tests", "testdata/rsa256_key.pem")
def dir_setup(test_dir="debian_apache_2_4/two_vhost_80"):
@ -38,7 +38,7 @@ def dir_setup(test_dir="debian_apache_2_4/two_vhost_80"):
work_dir = tempfile.mkdtemp("work")
test_configs = pkg_resources.resource_filename(
"letsencrypt.client.tests", "testdata/%s" % test_dir)
"letsencrypt.client.plugins.apache.tests", "testdata/%s" % test_dir)
shutil.copytree(
test_configs, os.path.join(temp_dir, test_dir), symlinks=True)
@ -59,7 +59,7 @@ def get_apache_configurator(
backups = os.path.join(work_dir, "backups")
with mock.patch("letsencrypt.client.apache.configurator."
with mock.patch("letsencrypt.client.plugins.apache.configurator."
"subprocess.Popen") as mock_popen:
# This just states that the ssl module is already loaded
mock_popen().communicate.return_value = ("ssl_module", "")

View file

@ -0,0 +1 @@
"""Let's Encrypt client.plugins.standalone."""

View file

@ -0,0 +1 @@
"""Let's Encrypt Standalone Tests"""

View file

@ -1,4 +1,4 @@
"""Tests for letsencrypt.client.standalone_authenticator."""
"""Tests for letsencrypt.client.plugins.standalone.authenticator."""
import os
import pkg_resources
import psutil
@ -49,7 +49,7 @@ class CallableExhausted(Exception):
class ChallPrefTest(unittest.TestCase):
"""Tests for chall_pref() method."""
def setUp(self):
from letsencrypt.client.standalone_authenticator import \
from letsencrypt.client.plugins.standalone.authenticator import \
StandaloneAuthenticator
self.authenticator = StandaloneAuthenticator(None)
@ -61,11 +61,11 @@ class ChallPrefTest(unittest.TestCase):
class SNICallbackTest(unittest.TestCase):
"""Tests for sni_callback() method."""
def setUp(self):
from letsencrypt.client.standalone_authenticator import \
from letsencrypt.client.plugins.standalone.authenticator import \
StandaloneAuthenticator
self.authenticator = StandaloneAuthenticator(None)
test_key = pkg_resources.resource_string(
__name__, "testdata/rsa256_key.pem")
"letsencrypt.client.tests", "testdata/rsa256_key.pem")
key = le_util.Key("foo", test_key)
self.cert = achallenges.DVSNI(
chall=challenges.DVSNI(r="x"*32, nonce="abcdef"),
@ -104,7 +104,7 @@ class SNICallbackTest(unittest.TestCase):
class ClientSignalHandlerTest(unittest.TestCase):
"""Tests for client_signal_handler() method."""
def setUp(self):
from letsencrypt.client.standalone_authenticator import \
from letsencrypt.client.plugins.standalone.authenticator import \
StandaloneAuthenticator
self.authenticator = StandaloneAuthenticator(None)
self.authenticator.tasks = {"foononce.acme.invalid": "stuff"}
@ -133,15 +133,15 @@ class ClientSignalHandlerTest(unittest.TestCase):
class SubprocSignalHandlerTest(unittest.TestCase):
"""Tests for subproc_signal_handler() method."""
def setUp(self):
from letsencrypt.client.standalone_authenticator import \
from letsencrypt.client.plugins.standalone.authenticator import \
StandaloneAuthenticator
self.authenticator = StandaloneAuthenticator(None)
self.authenticator.tasks = {"foononce.acme.invalid": "stuff"}
self.authenticator.child_pid = 12345
self.authenticator.parent_pid = 23456
@mock.patch("letsencrypt.client.standalone_authenticator.os.kill")
@mock.patch("letsencrypt.client.standalone_authenticator.sys.exit")
@mock.patch("letsencrypt.client.plugins.standalone.authenticator.os.kill")
@mock.patch("letsencrypt.client.plugins.standalone.authenticator.sys.exit")
def test_subproc_signal_handler(self, mock_exit, mock_kill):
self.authenticator.ssl_conn = mock.MagicMock()
self.authenticator.connection = mock.MagicMock()
@ -155,8 +155,8 @@ class SubprocSignalHandlerTest(unittest.TestCase):
self.authenticator.parent_pid, signal.SIGUSR1)
mock_exit.assert_called_once_with(0)
@mock.patch("letsencrypt.client.standalone_authenticator.os.kill")
@mock.patch("letsencrypt.client.standalone_authenticator.sys.exit")
@mock.patch("letsencrypt.client.plugins.standalone.authenticator.os.kill")
@mock.patch("letsencrypt.client.plugins.standalone.authenticator.sys.exit")
def test_subproc_signal_handler_trouble(self, mock_exit, mock_kill):
"""Test attempting to shut down a non-existent connection.
@ -185,14 +185,15 @@ class SubprocSignalHandlerTest(unittest.TestCase):
class AlreadyListeningTest(unittest.TestCase):
"""Tests for already_listening() method."""
def setUp(self):
from letsencrypt.client.standalone_authenticator import \
from letsencrypt.client.plugins.standalone.authenticator import \
StandaloneAuthenticator
self.authenticator = StandaloneAuthenticator(None)
@mock.patch("letsencrypt.client.standalone_authenticator.psutil."
@mock.patch("letsencrypt.client.plugins.standalone.authenticator.psutil."
"net_connections")
@mock.patch("letsencrypt.client.standalone_authenticator.psutil.Process")
@mock.patch("letsencrypt.client.standalone_authenticator."
@mock.patch("letsencrypt.client.plugins.standalone.authenticator."
"psutil.Process")
@mock.patch("letsencrypt.client.plugins.standalone.authenticator."
"zope.component.getUtility")
def test_race_condition(self, mock_get_utility, mock_process, mock_net):
# This tests a race condition, or permission problem, or OS
@ -216,10 +217,11 @@ class AlreadyListeningTest(unittest.TestCase):
self.assertEqual(mock_get_utility.generic_notification.call_count, 0)
mock_process.assert_called_once_with(4416)
@mock.patch("letsencrypt.client.standalone_authenticator.psutil."
@mock.patch("letsencrypt.client.plugins.standalone.authenticator.psutil."
"net_connections")
@mock.patch("letsencrypt.client.standalone_authenticator.psutil.Process")
@mock.patch("letsencrypt.client.standalone_authenticator."
@mock.patch("letsencrypt.client.plugins.standalone.authenticator."
"psutil.Process")
@mock.patch("letsencrypt.client.plugins.standalone.authenticator."
"zope.component.getUtility")
def test_not_listening(self, mock_get_utility, mock_process, mock_net):
from psutil._common import sconn
@ -236,10 +238,11 @@ class AlreadyListeningTest(unittest.TestCase):
self.assertEqual(mock_get_utility.generic_notification.call_count, 0)
self.assertEqual(mock_process.call_count, 0)
@mock.patch("letsencrypt.client.standalone_authenticator.psutil."
@mock.patch("letsencrypt.client.plugins.standalone.authenticator.psutil."
"net_connections")
@mock.patch("letsencrypt.client.standalone_authenticator.psutil.Process")
@mock.patch("letsencrypt.client.standalone_authenticator."
@mock.patch("letsencrypt.client.plugins.standalone.authenticator."
"psutil.Process")
@mock.patch("letsencrypt.client.plugins.standalone.authenticator."
"zope.component.getUtility")
def test_listening_ipv4(self, mock_get_utility, mock_process, mock_net):
from psutil._common import sconn
@ -259,10 +262,11 @@ class AlreadyListeningTest(unittest.TestCase):
self.assertEqual(mock_get_utility.call_count, 1)
mock_process.assert_called_once_with(4416)
@mock.patch("letsencrypt.client.standalone_authenticator.psutil."
@mock.patch("letsencrypt.client.plugins.standalone.authenticator.psutil."
"net_connections")
@mock.patch("letsencrypt.client.standalone_authenticator.psutil.Process")
@mock.patch("letsencrypt.client.standalone_authenticator."
@mock.patch("letsencrypt.client.plugins.standalone.authenticator."
"psutil.Process")
@mock.patch("letsencrypt.client.plugins.standalone.authenticator."
"zope.component.getUtility")
def test_listening_ipv6(self, mock_get_utility, mock_process, mock_net):
from psutil._common import sconn
@ -288,12 +292,12 @@ class AlreadyListeningTest(unittest.TestCase):
class PerformTest(unittest.TestCase):
"""Tests for perform() method."""
def setUp(self):
from letsencrypt.client.standalone_authenticator import \
from letsencrypt.client.plugins.standalone.authenticator import \
StandaloneAuthenticator
self.authenticator = StandaloneAuthenticator(None)
test_key = pkg_resources.resource_string(
__name__, "testdata/rsa256_key.pem")
"letsencrypt.client.tests", "testdata/rsa256_key.pem")
self.key = le_util.Key("something", test_key)
self.achall1 = achallenges.DVSNI(
@ -365,13 +369,13 @@ class PerformTest(unittest.TestCase):
class StartListenerTest(unittest.TestCase):
"""Tests for start_listener() method."""
def setUp(self):
from letsencrypt.client.standalone_authenticator import \
from letsencrypt.client.plugins.standalone.authenticator import \
StandaloneAuthenticator
self.authenticator = StandaloneAuthenticator(None)
@mock.patch("letsencrypt.client.standalone_authenticator."
@mock.patch("letsencrypt.client.plugins.standalone.authenticator."
"Crypto.Random.atfork")
@mock.patch("letsencrypt.client.standalone_authenticator.os.fork")
@mock.patch("letsencrypt.client.plugins.standalone.authenticator.os.fork")
def test_start_listener_fork_parent(self, mock_fork, mock_atfork):
self.authenticator.do_parent_process = mock.Mock()
self.authenticator.do_parent_process.return_value = True
@ -384,9 +388,9 @@ class StartListenerTest(unittest.TestCase):
self.authenticator.do_parent_process.assert_called_once_with(1717)
mock_atfork.assert_called_once_with()
@mock.patch("letsencrypt.client.standalone_authenticator."
@mock.patch("letsencrypt.client.plugins.standalone.authenticator."
"Crypto.Random.atfork")
@mock.patch("letsencrypt.client.standalone_authenticator.os.fork")
@mock.patch("letsencrypt.client.plugins.standalone.authenticator.os.fork")
def test_start_listener_fork_child(self, mock_fork, mock_atfork):
self.authenticator.do_parent_process = mock.Mock()
self.authenticator.do_child_process = mock.Mock()
@ -400,12 +404,13 @@ class StartListenerTest(unittest.TestCase):
class DoParentProcessTest(unittest.TestCase):
"""Tests for do_parent_process() method."""
def setUp(self):
from letsencrypt.client.standalone_authenticator import \
from letsencrypt.client.plugins.standalone.authenticator import \
StandaloneAuthenticator
self.authenticator = StandaloneAuthenticator(None)
@mock.patch("letsencrypt.client.standalone_authenticator.signal.signal")
@mock.patch("letsencrypt.client.standalone_authenticator."
@mock.patch("letsencrypt.client.plugins.standalone.authenticator."
"signal.signal")
@mock.patch("letsencrypt.client.plugins.standalone.authenticator."
"zope.component.getUtility")
def test_do_parent_process_ok(self, mock_get_utility, mock_signal):
self.authenticator.subproc_state = "ready"
@ -414,8 +419,9 @@ class DoParentProcessTest(unittest.TestCase):
self.assertEqual(mock_get_utility.call_count, 1)
self.assertEqual(mock_signal.call_count, 3)
@mock.patch("letsencrypt.client.standalone_authenticator.signal.signal")
@mock.patch("letsencrypt.client.standalone_authenticator."
@mock.patch("letsencrypt.client.plugins.standalone.authenticator."
"signal.signal")
@mock.patch("letsencrypt.client.plugins.standalone.authenticator."
"zope.component.getUtility")
def test_do_parent_process_inuse(self, mock_get_utility, mock_signal):
self.authenticator.subproc_state = "inuse"
@ -424,8 +430,9 @@ class DoParentProcessTest(unittest.TestCase):
self.assertEqual(mock_get_utility.call_count, 1)
self.assertEqual(mock_signal.call_count, 3)
@mock.patch("letsencrypt.client.standalone_authenticator.signal.signal")
@mock.patch("letsencrypt.client.standalone_authenticator."
@mock.patch("letsencrypt.client.plugins.standalone.authenticator."
"signal.signal")
@mock.patch("letsencrypt.client.plugins.standalone.authenticator."
"zope.component.getUtility")
def test_do_parent_process_cantbind(self, mock_get_utility, mock_signal):
self.authenticator.subproc_state = "cantbind"
@ -434,8 +441,9 @@ class DoParentProcessTest(unittest.TestCase):
self.assertEqual(mock_get_utility.call_count, 1)
self.assertEqual(mock_signal.call_count, 3)
@mock.patch("letsencrypt.client.standalone_authenticator.signal.signal")
@mock.patch("letsencrypt.client.standalone_authenticator."
@mock.patch("letsencrypt.client.plugins.standalone.authenticator."
"signal.signal")
@mock.patch("letsencrypt.client.plugins.standalone.authenticator."
"zope.component.getUtility")
def test_do_parent_process_timeout(self, mock_get_utility, mock_signal):
# Normally times out in 5 seconds and returns False. We can
@ -450,11 +458,11 @@ class DoParentProcessTest(unittest.TestCase):
class DoChildProcessTest(unittest.TestCase):
"""Tests for do_child_process() method."""
def setUp(self):
from letsencrypt.client.standalone_authenticator import \
from letsencrypt.client.plugins.standalone.authenticator import \
StandaloneAuthenticator
self.authenticator = StandaloneAuthenticator(None)
test_key = pkg_resources.resource_string(
__name__, "testdata/rsa256_key.pem")
"letsencrypt.client.tests", "testdata/rsa256_key.pem")
key = le_util.Key("foo", test_key)
self.key = key
self.cert = achallenges.DVSNI(
@ -466,9 +474,10 @@ class DoChildProcessTest(unittest.TestCase):
self.authenticator.tasks = {"abcdef.acme.invalid": self.cert}
self.authenticator.parent_pid = 12345
@mock.patch("letsencrypt.client.standalone_authenticator.socket.socket")
@mock.patch("letsencrypt.client.standalone_authenticator.os.kill")
@mock.patch("letsencrypt.client.standalone_authenticator.sys.exit")
@mock.patch("letsencrypt.client.plugins.standalone.authenticator."
"socket.socket")
@mock.patch("letsencrypt.client.plugins.standalone.authenticator.os.kill")
@mock.patch("letsencrypt.client.plugins.standalone.authenticator.sys.exit")
def test_do_child_process_cantbind1(
self, mock_exit, mock_kill, mock_socket):
mock_exit.side_effect = IndentationError("subprocess would exit here")
@ -488,9 +497,10 @@ class DoChildProcessTest(unittest.TestCase):
mock_exit.assert_called_once_with(1)
mock_kill.assert_called_once_with(12345, signal.SIGUSR2)
@mock.patch("letsencrypt.client.standalone_authenticator.socket.socket")
@mock.patch("letsencrypt.client.standalone_authenticator.os.kill")
@mock.patch("letsencrypt.client.standalone_authenticator.sys.exit")
@mock.patch("letsencrypt.client.plugins.standalone.authenticator."
"socket.socket")
@mock.patch("letsencrypt.client.plugins.standalone.authenticator.os.kill")
@mock.patch("letsencrypt.client.plugins.standalone.authenticator.sys.exit")
def test_do_child_process_cantbind2(self, mock_exit, mock_kill,
mock_socket):
mock_exit.side_effect = IndentationError("subprocess would exit here")
@ -504,7 +514,8 @@ class DoChildProcessTest(unittest.TestCase):
mock_exit.assert_called_once_with(1)
mock_kill.assert_called_once_with(12345, signal.SIGUSR1)
@mock.patch("letsencrypt.client.standalone_authenticator.socket.socket")
@mock.patch("letsencrypt.client.plugins.standalone.authenticator."
"socket.socket")
def test_do_child_process_cantbind3(self, mock_socket):
"""Test case where attempt to bind socket results in an unhandled
socket error. (The expected behavior is arguably wrong because it
@ -517,10 +528,11 @@ class DoChildProcessTest(unittest.TestCase):
self.assertRaises(
socket.error, self.authenticator.do_child_process, 1717, self.key)
@mock.patch("letsencrypt.client.standalone_authenticator."
@mock.patch("letsencrypt.client.plugins.standalone.authenticator."
"OpenSSL.SSL.Connection")
@mock.patch("letsencrypt.client.standalone_authenticator.socket.socket")
@mock.patch("letsencrypt.client.standalone_authenticator.os.kill")
@mock.patch("letsencrypt.client.plugins.standalone.authenticator."
"socket.socket")
@mock.patch("letsencrypt.client.plugins.standalone.authenticator.os.kill")
def test_do_child_process_success(
self, mock_kill, mock_socket, mock_connection):
sample_socket = mock.MagicMock()
@ -543,7 +555,7 @@ class DoChildProcessTest(unittest.TestCase):
class CleanupTest(unittest.TestCase):
"""Tests for cleanup() method."""
def setUp(self):
from letsencrypt.client.standalone_authenticator import \
from letsencrypt.client.plugins.standalone.authenticator import \
StandaloneAuthenticator
self.authenticator = StandaloneAuthenticator(None)
self.achall = achallenges.DVSNI(
@ -552,8 +564,9 @@ class CleanupTest(unittest.TestCase):
self.authenticator.tasks = {self.achall.nonce_domain: "stuff"}
self.authenticator.child_pid = 12345
@mock.patch("letsencrypt.client.standalone_authenticator.os.kill")
@mock.patch("letsencrypt.client.standalone_authenticator.time.sleep")
@mock.patch("letsencrypt.client.plugins.standalone.authenticator.os.kill")
@mock.patch("letsencrypt.client.plugins.standalone.authenticator."
"time.sleep")
def test_cleanup(self, mock_sleep, mock_kill):
mock_sleep.return_value = None
mock_kill.return_value = None
@ -573,7 +586,7 @@ class CleanupTest(unittest.TestCase):
class MoreInfoTest(unittest.TestCase):
"""Tests for more_info() method. (trivially)"""
def setUp(self):
from letsencrypt.client.standalone_authenticator import (
from letsencrypt.client.plugins.standalone.authenticator import (
StandaloneAuthenticator)
self.authenticator = StandaloneAuthenticator(None)
@ -585,7 +598,7 @@ class MoreInfoTest(unittest.TestCase):
class InitTest(unittest.TestCase):
"""Tests for more_info() method. (trivially)"""
def setUp(self):
from letsencrypt.client.standalone_authenticator import (
from letsencrypt.client.plugins.standalone.authenticator import (
StandaloneAuthenticator)
self.authenticator = StandaloneAuthenticator(None)

View file

@ -8,8 +8,9 @@ from letsencrypt.client import errors
class DetermineAuthenticatorTest(unittest.TestCase):
def setUp(self):
from letsencrypt.client.apache.configurator import ApacheConfigurator
from letsencrypt.client.standalone_authenticator import (
from letsencrypt.client.plugins.apache.configurator import (
ApacheConfigurator)
from letsencrypt.client.plugins.standalone.authenticator import (
StandaloneAuthenticator)
self.mock_stand = mock.MagicMock(
@ -65,7 +66,8 @@ class DetermineAuthenticatorTest(unittest.TestCase):
class RollbackTest(unittest.TestCase):
"""Test the rollback function."""
def setUp(self):
from letsencrypt.client.apache.configurator import ApacheConfigurator
from letsencrypt.client.plugins.apache.configurator import (
ApacheConfigurator)
self.m_install = mock.MagicMock(spec=ApacheConfigurator)
@classmethod

View file

@ -10,7 +10,7 @@ import mock
from letsencrypt.client import errors
from letsencrypt.client import le_util
from letsencrypt.client.apache import configurator
from letsencrypt.client.plugins.apache import configurator
from letsencrypt.client.display import util as display_util

View file

@ -96,10 +96,13 @@ setup(
'letsencrypt.acme',
'letsencrypt.acme.jose',
'letsencrypt.client',
'letsencrypt.client.apache',
'letsencrypt.client.display',
'letsencrypt.client.plugins',
'letsencrypt.client.plugins.apache',
'letsencrypt.client.plugins.apache.tests',
'letsencrypt.client.plugins.standalone',
'letsencrypt.client.plugins.standalone.tests',
'letsencrypt.client.tests',
'letsencrypt.client.tests.apache',
'letsencrypt.client.tests.display',
'letsencrypt.scripts',
],
@ -120,9 +123,9 @@ setup(
'jws = letsencrypt.acme.jose.jws:CLI.run',
],
'letsencrypt.authenticators': [
'apache = letsencrypt.client.apache.configurator'
'apache = letsencrypt.client.plugins.apache.configurator'
':ApacheConfigurator',
'standalone = letsencrypt.client.standalone_authenticator'
'standalone = letsencrypt.client.plugins.standalone.authenticator'
':StandaloneAuthenticator',
],
},