mirror of
https://github.com/certbot/certbot.git
synced 2026-01-21 19:01:07 +03:00
Merge branch 'plugins' of git://github.com/kuba/lets-encrypt-preview into kuba-plugins
This commit is contained in:
@@ -7,6 +7,7 @@ Welcome to the Let's Encrypt client documentation!
|
||||
intro
|
||||
using
|
||||
contributing
|
||||
plugins
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
13
docs/plugins.rst
Normal file
13
docs/plugins.rst
Normal file
@@ -0,0 +1,13 @@
|
||||
=======
|
||||
Plugins
|
||||
=======
|
||||
|
||||
Let's Encrypt client supports dynamic discovery of plugins through the
|
||||
`setuptools entry points`_. This way you can, for example, create a
|
||||
custom implementation of
|
||||
`~letsencrypt.client.interfaces.IAuthenticator` without having to
|
||||
merge it with the core upstream source code. Example is provided in
|
||||
``examples/plugins/`` directory.
|
||||
|
||||
.. _`setuptools entry points`:
|
||||
https://pythonhosted.org/setuptools/setuptools.html#dynamic-discovery-of-services-and-plugins
|
||||
16
examples/plugins/letsencrypt_example_plugins.py
Normal file
16
examples/plugins/letsencrypt_example_plugins.py
Normal file
@@ -0,0 +1,16 @@
|
||||
"""Example Let's Encrypt plugins."""
|
||||
import zope.interface
|
||||
|
||||
from letsencrypt.client import interfaces
|
||||
|
||||
|
||||
class Authenticator(object):
|
||||
zope.interface.implements(interfaces.IAuthenticator)
|
||||
|
||||
description = 'Example Authenticator plugin'
|
||||
|
||||
def __init__(self, config):
|
||||
self.config = config
|
||||
|
||||
# Implement all methods from IAuthenticator, remembering to add
|
||||
# "self" as first argument, e.g. def prepare(self)...
|
||||
16
examples/plugins/setup.py
Normal file
16
examples/plugins/setup.py
Normal file
@@ -0,0 +1,16 @@
|
||||
from setuptools import setup
|
||||
|
||||
|
||||
setup(
|
||||
name='letsencrypt-example-plugins',
|
||||
package='letsencrypt_example_plugins.py',
|
||||
install_requires=[
|
||||
'letsencrypt',
|
||||
'zope.interface',
|
||||
],
|
||||
entry_points={
|
||||
'letsencrypt.authenticators': [
|
||||
'example = letsencrypt_example_plugins:Authenticator',
|
||||
],
|
||||
},
|
||||
)
|
||||
@@ -33,7 +33,7 @@ class StandaloneAuthenticator(object):
|
||||
|
||||
description = "Standalone Authenticator"
|
||||
|
||||
def __init__(self):
|
||||
def __init__(self, unused_config):
|
||||
self.child_pid = None
|
||||
self.parent_pid = os.getpid()
|
||||
self.subproc_state = None
|
||||
|
||||
@@ -51,7 +51,7 @@ class ChallPrefTest(unittest.TestCase):
|
||||
def setUp(self):
|
||||
from letsencrypt.client.standalone_authenticator import \
|
||||
StandaloneAuthenticator
|
||||
self.authenticator = StandaloneAuthenticator()
|
||||
self.authenticator = StandaloneAuthenticator(None)
|
||||
|
||||
def test_chall_pref(self):
|
||||
self.assertEqual(self.authenticator.get_chall_pref("example.com"),
|
||||
@@ -63,7 +63,7 @@ class SNICallbackTest(unittest.TestCase):
|
||||
def setUp(self):
|
||||
from letsencrypt.client.standalone_authenticator import \
|
||||
StandaloneAuthenticator
|
||||
self.authenticator = StandaloneAuthenticator()
|
||||
self.authenticator = StandaloneAuthenticator(None)
|
||||
test_key = pkg_resources.resource_string(
|
||||
__name__, "testdata/rsa256_key.pem")
|
||||
key = le_util.Key("foo", test_key)
|
||||
@@ -106,7 +106,7 @@ class ClientSignalHandlerTest(unittest.TestCase):
|
||||
def setUp(self):
|
||||
from letsencrypt.client.standalone_authenticator import \
|
||||
StandaloneAuthenticator
|
||||
self.authenticator = StandaloneAuthenticator()
|
||||
self.authenticator = StandaloneAuthenticator(None)
|
||||
self.authenticator.tasks = {"foononce.acme.invalid": "stuff"}
|
||||
self.authenticator.child_pid = 12345
|
||||
|
||||
@@ -135,7 +135,7 @@ class SubprocSignalHandlerTest(unittest.TestCase):
|
||||
def setUp(self):
|
||||
from letsencrypt.client.standalone_authenticator import \
|
||||
StandaloneAuthenticator
|
||||
self.authenticator = StandaloneAuthenticator()
|
||||
self.authenticator = StandaloneAuthenticator(None)
|
||||
self.authenticator.tasks = {"foononce.acme.invalid": "stuff"}
|
||||
self.authenticator.child_pid = 12345
|
||||
self.authenticator.parent_pid = 23456
|
||||
@@ -187,7 +187,7 @@ class AlreadyListeningTest(unittest.TestCase):
|
||||
def setUp(self):
|
||||
from letsencrypt.client.standalone_authenticator import \
|
||||
StandaloneAuthenticator
|
||||
self.authenticator = StandaloneAuthenticator()
|
||||
self.authenticator = StandaloneAuthenticator(None)
|
||||
|
||||
@mock.patch("letsencrypt.client.standalone_authenticator.psutil."
|
||||
"net_connections")
|
||||
@@ -290,7 +290,7 @@ class PerformTest(unittest.TestCase):
|
||||
def setUp(self):
|
||||
from letsencrypt.client.standalone_authenticator import \
|
||||
StandaloneAuthenticator
|
||||
self.authenticator = StandaloneAuthenticator()
|
||||
self.authenticator = StandaloneAuthenticator(None)
|
||||
|
||||
test_key = pkg_resources.resource_string(
|
||||
__name__, "testdata/rsa256_key.pem")
|
||||
@@ -367,7 +367,7 @@ class StartListenerTest(unittest.TestCase):
|
||||
def setUp(self):
|
||||
from letsencrypt.client.standalone_authenticator import \
|
||||
StandaloneAuthenticator
|
||||
self.authenticator = StandaloneAuthenticator()
|
||||
self.authenticator = StandaloneAuthenticator(None)
|
||||
|
||||
@mock.patch("letsencrypt.client.standalone_authenticator."
|
||||
"Crypto.Random.atfork")
|
||||
@@ -402,7 +402,7 @@ class DoParentProcessTest(unittest.TestCase):
|
||||
def setUp(self):
|
||||
from letsencrypt.client.standalone_authenticator import \
|
||||
StandaloneAuthenticator
|
||||
self.authenticator = StandaloneAuthenticator()
|
||||
self.authenticator = StandaloneAuthenticator(None)
|
||||
|
||||
@mock.patch("letsencrypt.client.standalone_authenticator.signal.signal")
|
||||
@mock.patch("letsencrypt.client.standalone_authenticator."
|
||||
@@ -452,7 +452,7 @@ class DoChildProcessTest(unittest.TestCase):
|
||||
def setUp(self):
|
||||
from letsencrypt.client.standalone_authenticator import \
|
||||
StandaloneAuthenticator
|
||||
self.authenticator = StandaloneAuthenticator()
|
||||
self.authenticator = StandaloneAuthenticator(None)
|
||||
test_key = pkg_resources.resource_string(
|
||||
__name__, "testdata/rsa256_key.pem")
|
||||
key = le_util.Key("foo", test_key)
|
||||
@@ -545,7 +545,7 @@ class CleanupTest(unittest.TestCase):
|
||||
def setUp(self):
|
||||
from letsencrypt.client.standalone_authenticator import \
|
||||
StandaloneAuthenticator
|
||||
self.authenticator = StandaloneAuthenticator()
|
||||
self.authenticator = StandaloneAuthenticator(None)
|
||||
self.achall = achallenges.DVSNI(
|
||||
chall=challenges.DVSNI(r="whee", nonce="foononce"),
|
||||
domain="foo.example.com", key="key")
|
||||
@@ -575,7 +575,7 @@ class MoreInfoTest(unittest.TestCase):
|
||||
def setUp(self):
|
||||
from letsencrypt.client.standalone_authenticator import (
|
||||
StandaloneAuthenticator)
|
||||
self.authenticator = StandaloneAuthenticator()
|
||||
self.authenticator = StandaloneAuthenticator(None)
|
||||
|
||||
def test_more_info(self):
|
||||
"""Make sure exceptions aren't raised."""
|
||||
@@ -587,7 +587,7 @@ class InitTest(unittest.TestCase):
|
||||
def setUp(self):
|
||||
from letsencrypt.client.standalone_authenticator import (
|
||||
StandaloneAuthenticator)
|
||||
self.authenticator = StandaloneAuthenticator()
|
||||
self.authenticator = StandaloneAuthenticator(None)
|
||||
|
||||
def test_prepare(self):
|
||||
"""Make sure exceptions aren't raised.
|
||||
|
||||
@@ -11,6 +11,8 @@ import sys
|
||||
|
||||
import confargparse
|
||||
import zope.component
|
||||
import zope.interface.exceptions
|
||||
import zope.interface.verify
|
||||
|
||||
import letsencrypt
|
||||
|
||||
@@ -20,12 +22,32 @@ from letsencrypt.client import errors
|
||||
from letsencrypt.client import interfaces
|
||||
from letsencrypt.client import le_util
|
||||
from letsencrypt.client import log
|
||||
from letsencrypt.client import standalone_authenticator as standalone
|
||||
from letsencrypt.client.apache import configurator
|
||||
from letsencrypt.client.display import util as display_util
|
||||
from letsencrypt.client.display import ops as display_ops
|
||||
|
||||
|
||||
SETUPTOOLS_AUTHENTICATORS_ENTRY_POINT = "letsencrypt.authenticators"
|
||||
"""Setuptools entry point group name for Authenticator plugins."""
|
||||
|
||||
|
||||
def init_auths(config):
|
||||
"""Find (setuptools entry points) and initialize Authenticators."""
|
||||
auths = {}
|
||||
for entrypoint in pkg_resources.iter_entry_points(
|
||||
SETUPTOOLS_AUTHENTICATORS_ENTRY_POINT):
|
||||
auth_cls = entrypoint.load()
|
||||
auth = auth_cls(config)
|
||||
try:
|
||||
zope.interface.verify.verifyObject(interfaces.IAuthenticator, auth)
|
||||
except zope.interface.exceptions.BrokenImplementation:
|
||||
logging.debug(
|
||||
"%r object does not provide IAuthenticator, skipping",
|
||||
entrypoint.name)
|
||||
else:
|
||||
auths[auth] = entrypoint.name
|
||||
return auths
|
||||
|
||||
|
||||
def create_parser():
|
||||
"""Create parser."""
|
||||
parser = confargparse.ConfArgParser(
|
||||
@@ -136,12 +158,10 @@ def main(): # pylint: disable=too-many-branches, too-many-statements
|
||||
if not args.eula:
|
||||
display_eula()
|
||||
|
||||
all_auths = [
|
||||
configurator.ApacheConfigurator(config),
|
||||
standalone.StandaloneAuthenticator(),
|
||||
]
|
||||
all_auths = init_auths(config)
|
||||
logging.debug('Initialized authenticators: %s', all_auths.values())
|
||||
try:
|
||||
auth = client.determine_authenticator(all_auths)
|
||||
auth = client.determine_authenticator(all_auths.keys())
|
||||
except errors.LetsEncryptClientError:
|
||||
logging.critical("No authentication mechanisms were found on your "
|
||||
"system.")
|
||||
|
||||
6
setup.py
6
setup.py
@@ -119,6 +119,12 @@ setup(
|
||||
'letsencrypt = letsencrypt.scripts.main:main',
|
||||
'jws = letsencrypt.acme.jose.jws:CLI.run',
|
||||
],
|
||||
'letsencrypt.authenticators': [
|
||||
'apache = letsencrypt.client.apache.configurator'
|
||||
':ApacheConfigurator',
|
||||
'standalone = letsencrypt.client.standalone_authenticator'
|
||||
':StandaloneAuthenticator',
|
||||
],
|
||||
},
|
||||
|
||||
zip_safe=False,
|
||||
|
||||
Reference in New Issue
Block a user