Codebase list python-certbot-dns-dnsimple / 2601514
Merge tag 'upstream/1.3.0' Upstream version 1.3.0 Harlan Lieberman-Berg 3 years ago
15 changed file(s) with 194 addition(s) and 167 deletion(s). Raw diff Collapse all Expand all
00 include LICENSE.txt
11 include README.rst
22 recursive-include docs *
3 recursive-include tests *
4 global-exclude __pycache__
5 global-exclude *.py[cod]
00 Metadata-Version: 2.1
11 Name: certbot-dns-dnsimple
2 Version: 0.31.0
2 Version: 1.3.0
33 Summary: DNSimple DNS Authenticator plugin for Certbot
44 Home-page: https://github.com/certbot/certbot
55 Author: Certbot Project
77 License: Apache License 2.0
88 Description: UNKNOWN
99 Platform: UNKNOWN
10 Classifier: Development Status :: 3 - Alpha
10 Classifier: Development Status :: 5 - Production/Stable
1111 Classifier: Environment :: Plugins
1212 Classifier: Intended Audience :: System Administrators
1313 Classifier: License :: OSI Approved :: Apache Software License
1616 Classifier: Programming Language :: Python :: 2
1717 Classifier: Programming Language :: Python :: 2.7
1818 Classifier: Programming Language :: Python :: 3
19 Classifier: Programming Language :: Python :: 3.4
2019 Classifier: Programming Language :: Python :: 3.5
2120 Classifier: Programming Language :: Python :: 3.6
2221 Classifier: Programming Language :: Python :: 3.7
22 Classifier: Programming Language :: Python :: 3.8
2323 Classifier: Topic :: Internet :: WWW/HTTP
2424 Classifier: Topic :: Security
2525 Classifier: Topic :: System :: Installation/Setup
2626 Classifier: Topic :: System :: Networking
2727 Classifier: Topic :: System :: Systems Administration
2828 Classifier: Topic :: Utilities
29 Requires-Python: >=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*
29 Requires-Python: >=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*
3030 Provides-Extra: docs
0 """Internal implementation of `~certbot_dns_dnsimple.dns_dnsimple` plugin."""
0 """DNS Authenticator for DNSimple DNS."""
1 import logging
2
3 from lexicon.providers import dnsimple
4 import zope.interface
5
6 from certbot import errors
7 from certbot import interfaces
8 from certbot.plugins import dns_common
9 from certbot.plugins import dns_common_lexicon
10
11 logger = logging.getLogger(__name__)
12
13 ACCOUNT_URL = 'https://dnsimple.com/user'
14
15
16 @zope.interface.implementer(interfaces.IAuthenticator)
17 @zope.interface.provider(interfaces.IPluginFactory)
18 class Authenticator(dns_common.DNSAuthenticator):
19 """DNS Authenticator for DNSimple
20
21 This Authenticator uses the DNSimple v2 API to fulfill a dns-01 challenge.
22 """
23
24 description = 'Obtain certificates using a DNS TXT record (if you are using DNSimple for DNS).'
25 ttl = 60
26
27 def __init__(self, *args, **kwargs):
28 super(Authenticator, self).__init__(*args, **kwargs)
29 self.credentials = None
30
31 @classmethod
32 def add_parser_arguments(cls, add): # pylint: disable=arguments-differ
33 super(Authenticator, cls).add_parser_arguments(add, default_propagation_seconds=30)
34 add('credentials', help='DNSimple credentials INI file.')
35
36 def more_info(self): # pylint: disable=missing-function-docstring
37 return 'This plugin configures a DNS TXT record to respond to a dns-01 challenge using ' + \
38 'the DNSimple API.'
39
40 def _setup_credentials(self):
41 self.credentials = self._configure_credentials(
42 'credentials',
43 'DNSimple credentials INI file',
44 {
45 'token': 'User access token for DNSimple v2 API. (See {0}.)'.format(ACCOUNT_URL)
46 }
47 )
48
49 def _perform(self, domain, validation_name, validation):
50 self._get_dnsimple_client().add_txt_record(domain, validation_name, validation)
51
52 def _cleanup(self, domain, validation_name, validation):
53 self._get_dnsimple_client().del_txt_record(domain, validation_name, validation)
54
55 def _get_dnsimple_client(self):
56 return _DNSimpleLexiconClient(self.credentials.conf('token'), self.ttl)
57
58
59 class _DNSimpleLexiconClient(dns_common_lexicon.LexiconClient):
60 """
61 Encapsulates all communication with the DNSimple via Lexicon.
62 """
63
64 def __init__(self, token, ttl):
65 super(_DNSimpleLexiconClient, self).__init__()
66
67 config = dns_common_lexicon.build_lexicon_config('dnssimple', {
68 'ttl': ttl,
69 }, {
70 'auth_token': token,
71 })
72
73 self.provider = dnsimple.Provider(config)
74
75 def _handle_http_error(self, e, domain_name):
76 hint = None
77 if str(e).startswith('401 Client Error: Unauthorized for url:'):
78 hint = 'Is your API token value correct?'
79
80 return errors.PluginError('Error determining zone identifier for {0}: {1}.{2}'
81 .format(domain_name, e, ' ({0})'.format(hint) if hint else ''))
+0
-82
certbot_dns_dnsimple/dns_dnsimple.py less more
0 """DNS Authenticator for DNSimple DNS."""
1 import logging
2
3 import zope.interface
4 from lexicon.providers import dnsimple
5
6 from certbot import errors
7 from certbot import interfaces
8 from certbot.plugins import dns_common
9 from certbot.plugins import dns_common_lexicon
10
11 logger = logging.getLogger(__name__)
12
13 ACCOUNT_URL = 'https://dnsimple.com/user'
14
15
16 @zope.interface.implementer(interfaces.IAuthenticator)
17 @zope.interface.provider(interfaces.IPluginFactory)
18 class Authenticator(dns_common.DNSAuthenticator):
19 """DNS Authenticator for DNSimple
20
21 This Authenticator uses the DNSimple v2 API to fulfill a dns-01 challenge.
22 """
23
24 description = 'Obtain certificates using a DNS TXT record (if you are using DNSimple for DNS).'
25 ttl = 60
26
27 def __init__(self, *args, **kwargs):
28 super(Authenticator, self).__init__(*args, **kwargs)
29 self.credentials = None
30
31 @classmethod
32 def add_parser_arguments(cls, add): # pylint: disable=arguments-differ
33 super(Authenticator, cls).add_parser_arguments(add, default_propagation_seconds=30)
34 add('credentials', help='DNSimple credentials INI file.')
35
36 def more_info(self): # pylint: disable=missing-docstring,no-self-use
37 return 'This plugin configures a DNS TXT record to respond to a dns-01 challenge using ' + \
38 'the DNSimple API.'
39
40 def _setup_credentials(self):
41 self.credentials = self._configure_credentials(
42 'credentials',
43 'DNSimple credentials INI file',
44 {
45 'token': 'User access token for DNSimple v2 API. (See {0}.)'.format(ACCOUNT_URL)
46 }
47 )
48
49 def _perform(self, domain, validation_name, validation):
50 self._get_dnsimple_client().add_txt_record(domain, validation_name, validation)
51
52 def _cleanup(self, domain, validation_name, validation):
53 self._get_dnsimple_client().del_txt_record(domain, validation_name, validation)
54
55 def _get_dnsimple_client(self):
56 return _DNSimpleLexiconClient(self.credentials.conf('token'), self.ttl)
57
58
59 class _DNSimpleLexiconClient(dns_common_lexicon.LexiconClient):
60 """
61 Encapsulates all communication with the DNSimple via Lexicon.
62 """
63
64 def __init__(self, token, ttl):
65 super(_DNSimpleLexiconClient, self).__init__()
66
67 config = dns_common_lexicon.build_lexicon_config('dnssimple', {
68 'ttl': ttl,
69 }, {
70 'auth_token': token,
71 })
72
73 self.provider = dnsimple.Provider(config)
74
75 def _handle_http_error(self, e, domain_name):
76 hint = None
77 if str(e).startswith('401 Client Error: Unauthorized for url:'):
78 hint = 'Is your API token value correct?'
79
80 return errors.PluginError('Error determining zone identifier for {0}: {1}.{2}'
81 .format(domain_name, e, ' ({0})'.format(hint) if hint else ''))
+0
-51
certbot_dns_dnsimple/dns_dnsimple_test.py less more
0 """Tests for certbot_dns_dnsimple.dns_dnsimple."""
1
2 import os
3 import unittest
4
5 import mock
6 from requests.exceptions import HTTPError
7
8 from certbot.plugins import dns_test_common
9 from certbot.plugins import dns_test_common_lexicon
10 from certbot.tests import util as test_util
11
12 TOKEN = 'foo'
13
14
15 class AuthenticatorTest(test_util.TempDirTestCase,
16 dns_test_common_lexicon.BaseLexiconAuthenticatorTest):
17
18 def setUp(self):
19 super(AuthenticatorTest, self).setUp()
20
21 from certbot_dns_dnsimple.dns_dnsimple import Authenticator
22
23 path = os.path.join(self.tempdir, 'file.ini')
24 dns_test_common.write({"dnsimple_token": TOKEN}, path)
25
26 self.config = mock.MagicMock(dnsimple_credentials=path,
27 dnsimple_propagation_seconds=0) # don't wait during tests
28
29 self.auth = Authenticator(self.config, "dnsimple")
30
31 self.mock_client = mock.MagicMock()
32 # _get_dnsimple_client | pylint: disable=protected-access
33 self.auth._get_dnsimple_client = mock.MagicMock(return_value=self.mock_client)
34
35
36 class DNSimpleLexiconClientTest(unittest.TestCase, dns_test_common_lexicon.BaseLexiconClientTest):
37
38 LOGIN_ERROR = HTTPError('401 Client Error: Unauthorized for url: ...')
39
40 def setUp(self):
41 from certbot_dns_dnsimple.dns_dnsimple import _DNSimpleLexiconClient
42
43 self.client = _DNSimpleLexiconClient(TOKEN, 0)
44
45 self.provider_mock = mock.MagicMock()
46 self.client.provider = self.provider_mock
47
48
49 if __name__ == "__main__":
50 unittest.main() # pragma: no cover
00 Metadata-Version: 2.1
11 Name: certbot-dns-dnsimple
2 Version: 0.31.0
2 Version: 1.3.0
33 Summary: DNSimple DNS Authenticator plugin for Certbot
44 Home-page: https://github.com/certbot/certbot
55 Author: Certbot Project
77 License: Apache License 2.0
88 Description: UNKNOWN
99 Platform: UNKNOWN
10 Classifier: Development Status :: 3 - Alpha
10 Classifier: Development Status :: 5 - Production/Stable
1111 Classifier: Environment :: Plugins
1212 Classifier: Intended Audience :: System Administrators
1313 Classifier: License :: OSI Approved :: Apache Software License
1616 Classifier: Programming Language :: Python :: 2
1717 Classifier: Programming Language :: Python :: 2.7
1818 Classifier: Programming Language :: Python :: 3
19 Classifier: Programming Language :: Python :: 3.4
2019 Classifier: Programming Language :: Python :: 3.5
2120 Classifier: Programming Language :: Python :: 3.6
2221 Classifier: Programming Language :: Python :: 3.7
22 Classifier: Programming Language :: Python :: 3.8
2323 Classifier: Topic :: Internet :: WWW/HTTP
2424 Classifier: Topic :: Security
2525 Classifier: Topic :: System :: Installation/Setup
2626 Classifier: Topic :: System :: Networking
2727 Classifier: Topic :: System :: Systems Administration
2828 Classifier: Topic :: Utilities
29 Requires-Python: >=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*
29 Requires-Python: >=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*
3030 Provides-Extra: docs
33 setup.cfg
44 setup.py
55 certbot_dns_dnsimple/__init__.py
6 certbot_dns_dnsimple/dns_dnsimple.py
7 certbot_dns_dnsimple/dns_dnsimple_test.py
86 certbot_dns_dnsimple.egg-info/PKG-INFO
97 certbot_dns_dnsimple.egg-info/SOURCES.txt
108 certbot_dns_dnsimple.egg-info/dependency_links.txt
119 certbot_dns_dnsimple.egg-info/entry_points.txt
1210 certbot_dns_dnsimple.egg-info/requires.txt
1311 certbot_dns_dnsimple.egg-info/top_level.txt
12 certbot_dns_dnsimple/_internal/__init__.py
13 certbot_dns_dnsimple/_internal/dns_dnsimple.py
1414 docs/.gitignore
1515 docs/Makefile
1616 docs/api.rst
1717 docs/conf.py
1818 docs/index.rst
1919 docs/make.bat
20 docs/api/dns_dnsimple.rst
20 tests/dns_dnsimple_test.py
00 [certbot.plugins]
1 dns-dnsimple = certbot_dns_dnsimple.dns_dnsimple:Authenticator
1 dns-dnsimple = certbot_dns_dnsimple._internal.dns_dnsimple:Authenticator
22
00 acme>=0.31.0
1 certbot>=0.31.0
2 dns-lexicon>=2.2.1
1 certbot>=1.1.0
32 mock
43 setuptools
54 zope.interface
5 dns-lexicon>=3.2.1
66
77 [docs]
88 Sphinx>=1.0
+0
-5
docs/api/dns_dnsimple.rst less more
0 :mod:`certbot_dns_dnsimple.dns_dnsimple`
1 ----------------------------------------
2
3 .. automodule:: certbot_dns_dnsimple.dns_dnsimple
4 :members:
11 API Documentation
22 =================
33
4 .. toctree::
5 :glob:
6
7 api/**
4 Certbot plugins implement the Certbot plugins API, and do not otherwise have an external API.
1616 # documentation root, use os.path.abspath to make it absolute, like shown here.
1717 #
1818 import os
19
1920 # import sys
2021 # sys.path.insert(0, os.path.abspath('.'))
2122
3637 'sphinx.ext.viewcode']
3738
3839 autodoc_member_order = 'bysource'
39 autodoc_default_flags = ['show-inheritance', 'private-members']
40 autodoc_default_flags = ['show-inheritance']
4041
4142 # Add any paths that contain templates here, relative to this directory.
4243 templates_path = ['_templates']
8283 pygments_style = 'sphinx'
8384
8485 # If true, `todo` and `todoList` produce output, else they produce nothing.
85 todo_include_todos = True
86 todo_include_todos = False
8687
8788
8889 # -- Options for HTML output ----------------------------------------------
0 import os
1 import sys
2
3 from setuptools import find_packages
04 from setuptools import setup
1 from setuptools import find_packages
5 from setuptools.command.test import test as TestCommand
26
3
4 version = '0.31.0'
7 version = '1.3.0'
58
69 # Remember to update local-oldest-requirements.txt when changing the minimum
710 # acme/certbot version.
811 install_requires = [
912 'acme>=0.31.0',
10 'certbot>=0.31.0',
11 'dns-lexicon>=2.2.1', # Support for >1 TXT record per name
13 'certbot>=1.1.0',
1214 'mock',
1315 'setuptools',
1416 'zope.interface',
1517 ]
1618
19 # This package normally depends on dns-lexicon>=3.2.1 to address the
20 # problem described in https://github.com/AnalogJ/lexicon/issues/387,
21 # however, the fix there has been backported to older versions of
22 # lexicon found in various Linux distros. This conditional helps us test
23 # that we've maintained compatibility with these versions of lexicon
24 # which allows us to potentially upgrade our packages in these distros
25 # as necessary.
26 if os.environ.get('CERTBOT_OLDEST') == '1':
27 install_requires.append('dns-lexicon>=2.2.1')
28 else:
29 install_requires.append('dns-lexicon>=3.2.1')
30
1731 docs_extras = [
1832 'Sphinx>=1.0', # autodoc_member_order = 'bysource', autodoc_default_flags
1933 'sphinx_rtd_theme',
2034 ]
35
36 class PyTest(TestCommand):
37 user_options = []
38
39 def initialize_options(self):
40 TestCommand.initialize_options(self)
41 self.pytest_args = ''
42
43 def run_tests(self):
44 import shlex
45 # import here, cause outside the eggs aren't loaded
46 import pytest
47 errno = pytest.main(shlex.split(self.pytest_args))
48 sys.exit(errno)
2149
2250 setup(
2351 name='certbot-dns-dnsimple',
2755 author="Certbot Project",
2856 author_email='client-dev@letsencrypt.org',
2957 license='Apache License 2.0',
30 python_requires='>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*',
58 python_requires='>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*',
3159 classifiers=[
32 'Development Status :: 3 - Alpha',
60 'Development Status :: 5 - Production/Stable',
3361 'Environment :: Plugins',
3462 'Intended Audience :: System Administrators',
3563 'License :: OSI Approved :: Apache Software License',
3866 'Programming Language :: Python :: 2',
3967 'Programming Language :: Python :: 2.7',
4068 'Programming Language :: Python :: 3',
41 'Programming Language :: Python :: 3.4',
4269 'Programming Language :: Python :: 3.5',
4370 'Programming Language :: Python :: 3.6',
4471 'Programming Language :: Python :: 3.7',
72 'Programming Language :: Python :: 3.8',
4573 'Topic :: Internet :: WWW/HTTP',
4674 'Topic :: Security',
4775 'Topic :: System :: Installation/Setup',
5886 },
5987 entry_points={
6088 'certbot.plugins': [
61 'dns-dnsimple = certbot_dns_dnsimple.dns_dnsimple:Authenticator',
89 'dns-dnsimple = certbot_dns_dnsimple._internal.dns_dnsimple:Authenticator',
6290 ],
6391 },
92 tests_require=["pytest"],
6493 test_suite='certbot_dns_dnsimple',
94 cmdclass={"test": PyTest},
6595 )
0 """Tests for certbot_dns_dnsimple._internal.dns_dnsimple."""
1
2 import unittest
3
4 import mock
5 from requests.exceptions import HTTPError
6
7 from certbot.compat import os
8 from certbot.plugins import dns_test_common
9 from certbot.plugins import dns_test_common_lexicon
10 from certbot.tests import util as test_util
11
12 TOKEN = 'foo'
13
14
15 class AuthenticatorTest(test_util.TempDirTestCase,
16 dns_test_common_lexicon.BaseLexiconAuthenticatorTest):
17
18 def setUp(self):
19 super(AuthenticatorTest, self).setUp()
20
21 from certbot_dns_dnsimple._internal.dns_dnsimple import Authenticator
22
23 path = os.path.join(self.tempdir, 'file.ini')
24 dns_test_common.write({"dnsimple_token": TOKEN}, path)
25
26 self.config = mock.MagicMock(dnsimple_credentials=path,
27 dnsimple_propagation_seconds=0) # don't wait during tests
28
29 self.auth = Authenticator(self.config, "dnsimple")
30
31 self.mock_client = mock.MagicMock()
32 # _get_dnsimple_client | pylint: disable=protected-access
33 self.auth._get_dnsimple_client = mock.MagicMock(return_value=self.mock_client)
34
35
36 class DNSimpleLexiconClientTest(unittest.TestCase, dns_test_common_lexicon.BaseLexiconClientTest):
37
38 LOGIN_ERROR = HTTPError('401 Client Error: Unauthorized for url: ...')
39
40 def setUp(self):
41 from certbot_dns_dnsimple._internal.dns_dnsimple import _DNSimpleLexiconClient
42
43 self.client = _DNSimpleLexiconClient(TOKEN, 0)
44
45 self.provider_mock = mock.MagicMock()
46 self.client.provider = self.provider_mock
47
48
49 if __name__ == "__main__":
50 unittest.main() # pragma: no cover