mirror of
https://github.com/certbot/certbot.git
synced 2026-08-02 19:31:51 +02:00
Setuptools entry_points plugins
This commit is contained in:
@@ -7,6 +7,7 @@ Welcome to the Let's Encrypt client documentation!
|
|||||||
intro
|
intro
|
||||||
using
|
using
|
||||||
contributing
|
contributing
|
||||||
|
plugins
|
||||||
|
|
||||||
.. toctree::
|
.. toctree::
|
||||||
:maxdepth: 1
|
:maxdepth: 1
|
||||||
|
|||||||
@@ -0,0 +1,5 @@
|
|||||||
|
=======
|
||||||
|
Plugins
|
||||||
|
=======
|
||||||
|
|
||||||
|
You can find an example in ``examples/plugins/`` directory.
|
||||||
@@ -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)...
|
||||||
@@ -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."""
|
"""ACME protocol client class and helper functions."""
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
|
import pkg_resources
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
import Crypto.PublicKey.RSA
|
import Crypto.PublicKey.RSA
|
||||||
import M2Crypto
|
import M2Crypto
|
||||||
|
|
||||||
|
import zope.interface.exceptions
|
||||||
|
import zope.interface.verify
|
||||||
|
|
||||||
from letsencrypt.acme import messages
|
from letsencrypt.acme import messages
|
||||||
from letsencrypt.acme.jose import util as jose_util
|
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 client_authenticator
|
||||||
from letsencrypt.client import crypto_util
|
from letsencrypt.client import crypto_util
|
||||||
from letsencrypt.client import errors
|
from letsencrypt.client import errors
|
||||||
|
from letsencrypt.client import interfaces
|
||||||
from letsencrypt.client import le_util
|
from letsencrypt.client import le_util
|
||||||
from letsencrypt.client import network
|
from letsencrypt.client import network
|
||||||
from letsencrypt.client import reverter
|
from letsencrypt.client import reverter
|
||||||
@@ -23,6 +28,28 @@ from letsencrypt.client.display import ops as display_ops
|
|||||||
from letsencrypt.client.display import enhancements
|
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):
|
class Client(object):
|
||||||
"""ACME protocol client.
|
"""ACME protocol client.
|
||||||
|
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ class StandaloneAuthenticator(object):
|
|||||||
|
|
||||||
description = "Standalone Authenticator"
|
description = "Standalone Authenticator"
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self, unused_config):
|
||||||
self.child_pid = None
|
self.child_pid = None
|
||||||
self.parent_pid = os.getpid()
|
self.parent_pid = os.getpid()
|
||||||
self.subproc_state = None
|
self.subproc_state = None
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ class ChallPrefTest(unittest.TestCase):
|
|||||||
def setUp(self):
|
def setUp(self):
|
||||||
from letsencrypt.client.standalone_authenticator import \
|
from letsencrypt.client.standalone_authenticator import \
|
||||||
StandaloneAuthenticator
|
StandaloneAuthenticator
|
||||||
self.authenticator = StandaloneAuthenticator()
|
self.authenticator = StandaloneAuthenticator(None)
|
||||||
|
|
||||||
def test_chall_pref(self):
|
def test_chall_pref(self):
|
||||||
self.assertEqual(self.authenticator.get_chall_pref("example.com"),
|
self.assertEqual(self.authenticator.get_chall_pref("example.com"),
|
||||||
@@ -63,7 +63,7 @@ class SNICallbackTest(unittest.TestCase):
|
|||||||
def setUp(self):
|
def setUp(self):
|
||||||
from letsencrypt.client.standalone_authenticator import \
|
from letsencrypt.client.standalone_authenticator import \
|
||||||
StandaloneAuthenticator
|
StandaloneAuthenticator
|
||||||
self.authenticator = StandaloneAuthenticator()
|
self.authenticator = StandaloneAuthenticator(None)
|
||||||
test_key = pkg_resources.resource_string(
|
test_key = pkg_resources.resource_string(
|
||||||
__name__, "testdata/rsa256_key.pem")
|
__name__, "testdata/rsa256_key.pem")
|
||||||
key = le_util.Key("foo", test_key)
|
key = le_util.Key("foo", test_key)
|
||||||
@@ -106,7 +106,7 @@ class ClientSignalHandlerTest(unittest.TestCase):
|
|||||||
def setUp(self):
|
def setUp(self):
|
||||||
from letsencrypt.client.standalone_authenticator import \
|
from letsencrypt.client.standalone_authenticator import \
|
||||||
StandaloneAuthenticator
|
StandaloneAuthenticator
|
||||||
self.authenticator = StandaloneAuthenticator()
|
self.authenticator = StandaloneAuthenticator(None)
|
||||||
self.authenticator.tasks = {"foononce.acme.invalid": "stuff"}
|
self.authenticator.tasks = {"foononce.acme.invalid": "stuff"}
|
||||||
self.authenticator.child_pid = 12345
|
self.authenticator.child_pid = 12345
|
||||||
|
|
||||||
@@ -135,7 +135,7 @@ class SubprocSignalHandlerTest(unittest.TestCase):
|
|||||||
def setUp(self):
|
def setUp(self):
|
||||||
from letsencrypt.client.standalone_authenticator import \
|
from letsencrypt.client.standalone_authenticator import \
|
||||||
StandaloneAuthenticator
|
StandaloneAuthenticator
|
||||||
self.authenticator = StandaloneAuthenticator()
|
self.authenticator = StandaloneAuthenticator(None)
|
||||||
self.authenticator.tasks = {"foononce.acme.invalid": "stuff"}
|
self.authenticator.tasks = {"foononce.acme.invalid": "stuff"}
|
||||||
self.authenticator.child_pid = 12345
|
self.authenticator.child_pid = 12345
|
||||||
self.authenticator.parent_pid = 23456
|
self.authenticator.parent_pid = 23456
|
||||||
@@ -187,7 +187,7 @@ class AlreadyListeningTest(unittest.TestCase):
|
|||||||
def setUp(self):
|
def setUp(self):
|
||||||
from letsencrypt.client.standalone_authenticator import \
|
from letsencrypt.client.standalone_authenticator import \
|
||||||
StandaloneAuthenticator
|
StandaloneAuthenticator
|
||||||
self.authenticator = StandaloneAuthenticator()
|
self.authenticator = StandaloneAuthenticator(None)
|
||||||
|
|
||||||
@mock.patch("letsencrypt.client.standalone_authenticator.psutil."
|
@mock.patch("letsencrypt.client.standalone_authenticator.psutil."
|
||||||
"net_connections")
|
"net_connections")
|
||||||
@@ -290,7 +290,7 @@ class PerformTest(unittest.TestCase):
|
|||||||
def setUp(self):
|
def setUp(self):
|
||||||
from letsencrypt.client.standalone_authenticator import \
|
from letsencrypt.client.standalone_authenticator import \
|
||||||
StandaloneAuthenticator
|
StandaloneAuthenticator
|
||||||
self.authenticator = StandaloneAuthenticator()
|
self.authenticator = StandaloneAuthenticator(None)
|
||||||
|
|
||||||
test_key = pkg_resources.resource_string(
|
test_key = pkg_resources.resource_string(
|
||||||
__name__, "testdata/rsa256_key.pem")
|
__name__, "testdata/rsa256_key.pem")
|
||||||
@@ -367,7 +367,7 @@ class StartListenerTest(unittest.TestCase):
|
|||||||
def setUp(self):
|
def setUp(self):
|
||||||
from letsencrypt.client.standalone_authenticator import \
|
from letsencrypt.client.standalone_authenticator import \
|
||||||
StandaloneAuthenticator
|
StandaloneAuthenticator
|
||||||
self.authenticator = StandaloneAuthenticator()
|
self.authenticator = StandaloneAuthenticator(None)
|
||||||
|
|
||||||
@mock.patch("letsencrypt.client.standalone_authenticator."
|
@mock.patch("letsencrypt.client.standalone_authenticator."
|
||||||
"Crypto.Random.atfork")
|
"Crypto.Random.atfork")
|
||||||
@@ -402,7 +402,7 @@ class DoParentProcessTest(unittest.TestCase):
|
|||||||
def setUp(self):
|
def setUp(self):
|
||||||
from letsencrypt.client.standalone_authenticator import \
|
from letsencrypt.client.standalone_authenticator import \
|
||||||
StandaloneAuthenticator
|
StandaloneAuthenticator
|
||||||
self.authenticator = StandaloneAuthenticator()
|
self.authenticator = StandaloneAuthenticator(None)
|
||||||
|
|
||||||
@mock.patch("letsencrypt.client.standalone_authenticator.signal.signal")
|
@mock.patch("letsencrypt.client.standalone_authenticator.signal.signal")
|
||||||
@mock.patch("letsencrypt.client.standalone_authenticator."
|
@mock.patch("letsencrypt.client.standalone_authenticator."
|
||||||
@@ -452,7 +452,7 @@ class DoChildProcessTest(unittest.TestCase):
|
|||||||
def setUp(self):
|
def setUp(self):
|
||||||
from letsencrypt.client.standalone_authenticator import \
|
from letsencrypt.client.standalone_authenticator import \
|
||||||
StandaloneAuthenticator
|
StandaloneAuthenticator
|
||||||
self.authenticator = StandaloneAuthenticator()
|
self.authenticator = StandaloneAuthenticator(None)
|
||||||
test_key = pkg_resources.resource_string(
|
test_key = pkg_resources.resource_string(
|
||||||
__name__, "testdata/rsa256_key.pem")
|
__name__, "testdata/rsa256_key.pem")
|
||||||
key = le_util.Key("foo", test_key)
|
key = le_util.Key("foo", test_key)
|
||||||
@@ -545,7 +545,7 @@ class CleanupTest(unittest.TestCase):
|
|||||||
def setUp(self):
|
def setUp(self):
|
||||||
from letsencrypt.client.standalone_authenticator import \
|
from letsencrypt.client.standalone_authenticator import \
|
||||||
StandaloneAuthenticator
|
StandaloneAuthenticator
|
||||||
self.authenticator = StandaloneAuthenticator()
|
self.authenticator = StandaloneAuthenticator(None)
|
||||||
self.achall = achallenges.DVSNI(
|
self.achall = achallenges.DVSNI(
|
||||||
chall=challenges.DVSNI(r="whee", nonce="foononce"),
|
chall=challenges.DVSNI(r="whee", nonce="foononce"),
|
||||||
domain="foo.example.com", key="key")
|
domain="foo.example.com", key="key")
|
||||||
@@ -575,7 +575,7 @@ class MoreInfoTest(unittest.TestCase):
|
|||||||
def setUp(self):
|
def setUp(self):
|
||||||
from letsencrypt.client.standalone_authenticator import (
|
from letsencrypt.client.standalone_authenticator import (
|
||||||
StandaloneAuthenticator)
|
StandaloneAuthenticator)
|
||||||
self.authenticator = StandaloneAuthenticator()
|
self.authenticator = StandaloneAuthenticator(None)
|
||||||
|
|
||||||
def test_more_info(self):
|
def test_more_info(self):
|
||||||
"""Make sure exceptions aren't raised."""
|
"""Make sure exceptions aren't raised."""
|
||||||
@@ -587,7 +587,7 @@ class InitTest(unittest.TestCase):
|
|||||||
def setUp(self):
|
def setUp(self):
|
||||||
from letsencrypt.client.standalone_authenticator import (
|
from letsencrypt.client.standalone_authenticator import (
|
||||||
StandaloneAuthenticator)
|
StandaloneAuthenticator)
|
||||||
self.authenticator = StandaloneAuthenticator()
|
self.authenticator = StandaloneAuthenticator(None)
|
||||||
|
|
||||||
def test_prepare(self):
|
def test_prepare(self):
|
||||||
"""Make sure exceptions aren't raised.
|
"""Make sure exceptions aren't raised.
|
||||||
|
|||||||
@@ -136,12 +136,10 @@ def main(): # pylint: disable=too-many-branches, too-many-statements
|
|||||||
if not args.eula:
|
if not args.eula:
|
||||||
display_eula()
|
display_eula()
|
||||||
|
|
||||||
all_auths = [
|
all_auths = client.init_auths(config)
|
||||||
configurator.ApacheConfigurator(config),
|
logging.debug('Initialized authenticators: %s', all_auths)
|
||||||
standalone.StandaloneAuthenticator(),
|
|
||||||
]
|
|
||||||
try:
|
try:
|
||||||
auth = client.determine_authenticator(all_auths)
|
auth = client.determine_authenticator(all_auths.keys())
|
||||||
except errors.LetsEncryptClientError:
|
except errors.LetsEncryptClientError:
|
||||||
logging.critical("No authentication mechanisms were found on your "
|
logging.critical("No authentication mechanisms were found on your "
|
||||||
"system.")
|
"system.")
|
||||||
|
|||||||
@@ -119,6 +119,12 @@ setup(
|
|||||||
'letsencrypt = letsencrypt.scripts.main:main',
|
'letsencrypt = letsencrypt.scripts.main:main',
|
||||||
'jws = letsencrypt.acme.jose.jws:CLI.run',
|
'jws = letsencrypt.acme.jose.jws:CLI.run',
|
||||||
],
|
],
|
||||||
|
'letsencrypt.authenticators': [
|
||||||
|
'apache = letsencrypt.client.apache.configurator'
|
||||||
|
':ApacheConfigurator',
|
||||||
|
'standalone = letsencrypt.client.standalone_authenticator'
|
||||||
|
':StandaloneAuthenticator',
|
||||||
|
],
|
||||||
},
|
},
|
||||||
|
|
||||||
zip_safe=False,
|
zip_safe=False,
|
||||||
|
|||||||
Reference in New Issue
Block a user