mirror of
https://github.com/certbot/certbot.git
synced 2026-06-06 23:32:06 -04:00
Setuptools entry_points plugins
This commit is contained in:
parent
197125bdda
commit
ff532469a5
9 changed files with 87 additions and 18 deletions
|
|
@ -7,6 +7,7 @@ Welcome to the Let's Encrypt client documentation!
|
|||
intro
|
||||
using
|
||||
contributing
|
||||
plugins
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
|
|
|||
5
docs/plugins.rst
Normal file
5
docs/plugins.rst
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
=======
|
||||
Plugins
|
||||
=======
|
||||
|
||||
You can find an example in ``examples/plugins/`` directory.
|
||||
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',
|
||||
],
|
||||
},
|
||||
)
|
||||
|
|
@ -1,11 +1,15 @@
|
|||
"""ACME protocol client class and helper functions."""
|
||||
import logging
|
||||
import os
|
||||
import pkg_resources
|
||||
import sys
|
||||
|
||||
import Crypto.PublicKey.RSA
|
||||
import M2Crypto
|
||||
|
||||
import zope.interface.exceptions
|
||||
import zope.interface.verify
|
||||
|
||||
from letsencrypt.acme import messages
|
||||
from letsencrypt.acme.jose import util as jose_util
|
||||
|
||||
|
|
@ -13,6 +17,7 @@ from letsencrypt.client import auth_handler
|
|||
from letsencrypt.client import client_authenticator
|
||||
from letsencrypt.client import crypto_util
|
||||
from letsencrypt.client import errors
|
||||
from letsencrypt.client import interfaces
|
||||
from letsencrypt.client import le_util
|
||||
from letsencrypt.client import network
|
||||
from letsencrypt.client import reverter
|
||||
|
|
@ -23,6 +28,28 @@ from letsencrypt.client.display import ops as display_ops
|
|||
from letsencrypt.client.display import enhancements
|
||||
|
||||
|
||||
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(
|
||||
'"%s" object does not provide IAuthenticator, skipping',
|
||||
entrypoint.name)
|
||||
else:
|
||||
auths[auth] = entrypoint.name
|
||||
return auths
|
||||
|
||||
|
||||
class Client(object):
|
||||
"""ACME protocol client.
|
||||
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -136,12 +136,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 = client.init_auths(config)
|
||||
logging.debug('Initialized authenticators: %s', all_auths)
|
||||
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,
|
||||
|
|
|
|||
Loading…
Reference in a new issue