diff options
Diffstat (limited to 'certbot-dns-linode/certbot_dns_linode')
-rw-r--r-- | certbot-dns-linode/certbot_dns_linode/__init__.py | 4 | ||||
-rw-r--r-- | certbot-dns-linode/certbot_dns_linode/_internal/__init__.py | 1 | ||||
-rw-r--r-- | certbot-dns-linode/certbot_dns_linode/_internal/dns_linode.py (renamed from certbot-dns-linode/certbot_dns_linode/dns_linode.py) | 50 | ||||
-rw-r--r-- | certbot-dns-linode/certbot_dns_linode/dns_linode_test.py | 47 |
4 files changed, 45 insertions, 57 deletions
diff --git a/certbot-dns-linode/certbot_dns_linode/__init__.py b/certbot-dns-linode/certbot_dns_linode/__init__.py index 0a6ccec61..107781a13 100644 --- a/certbot-dns-linode/certbot_dns_linode/__init__.py +++ b/certbot-dns-linode/certbot_dns_linode/__init__.py @@ -27,7 +27,8 @@ Credentials Use of this plugin requires a configuration file containing Linode API credentials, obtained from your Linode account's `Applications & API -Tokens page <https://manager.linode.com/profile/api>`_. +Tokens page (legacy) <https://manager.linode.com/profile/api>`_ or `Applications +& API Tokens page (new) <https://cloud.linode.com/profile/tokens>`_. .. code-block:: ini :name: credentials.ini @@ -35,6 +36,7 @@ Tokens page <https://manager.linode.com/profile/api>`_. # Linode API credentials used by Certbot dns_linode_key = 0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ64 + dns_linode_version = [<blank>|3|4] The path to this file can be provided interactively or using the ``--dns-linode-credentials`` command-line argument. Certbot records the path diff --git a/certbot-dns-linode/certbot_dns_linode/_internal/__init__.py b/certbot-dns-linode/certbot_dns_linode/_internal/__init__.py new file mode 100644 index 000000000..9090d92d3 --- /dev/null +++ b/certbot-dns-linode/certbot_dns_linode/_internal/__init__.py @@ -0,0 +1 @@ +"""Internal implementation of `~certbot_dns_linode.dns_linode` plugin.""" diff --git a/certbot-dns-linode/certbot_dns_linode/dns_linode.py b/certbot-dns-linode/certbot_dns_linode/_internal/dns_linode.py index 4e0500fa0..ea6046849 100644 --- a/certbot-dns-linode/certbot_dns_linode/dns_linode.py +++ b/certbot-dns-linode/certbot_dns_linode/_internal/dns_linode.py @@ -1,8 +1,10 @@ """DNS Authenticator for Linode.""" import logging +import re -import zope.interface from lexicon.providers import linode +from lexicon.providers import linode4 +import zope.interface from certbot import errors from certbot import interfaces @@ -12,6 +14,7 @@ from certbot.plugins import dns_common_lexicon logger = logging.getLogger(__name__) API_KEY_URL = 'https://manager.linode.com/profile/api' +API_KEY_URL_V4 = 'https://cloud.linode.com/profile/tokens' @zope.interface.implementer(interfaces.IAuthenticator) @zope.interface.provider(interfaces.IPluginFactory) @@ -41,7 +44,8 @@ class Authenticator(dns_common.DNSAuthenticator): 'credentials', 'Linode credentials INI file', { - 'key': 'API key for Linode account, obtained from {0}'.format(API_KEY_URL) + 'key': 'API key for Linode account, obtained from {0} or {1}' + .format(API_KEY_URL, API_KEY_URL_V4) } ) @@ -52,7 +56,23 @@ class Authenticator(dns_common.DNSAuthenticator): self._get_linode_client().del_txt_record(domain, validation_name, validation) def _get_linode_client(self): - return _LinodeLexiconClient(self.credentials.conf('key')) + api_key = self.credentials.conf('key') + api_version = self.credentials.conf('version') + if api_version == '': + api_version = None + + if not api_version: + api_version = 3 + + # Match for v4 api key + regex_v4 = re.compile('^[0-9a-f]{64}$') + regex_match = regex_v4.match(api_key) + if regex_match: + api_version = 4 + else: + api_version = int(api_version) + + return _LinodeLexiconClient(api_key, api_version) class _LinodeLexiconClient(dns_common_lexicon.LexiconClient): @@ -60,17 +80,29 @@ class _LinodeLexiconClient(dns_common_lexicon.LexiconClient): Encapsulates all communication with the Linode API. """ - def __init__(self, api_key): + def __init__(self, api_key, api_version): super(_LinodeLexiconClient, self).__init__() - config = dns_common_lexicon.build_lexicon_config('linode', {}, { - 'auth_token': api_key, - }) + self.api_version = api_version + + if api_version == 3: + config = dns_common_lexicon.build_lexicon_config('linode', {}, { + 'auth_token': api_key, + }) - self.provider = linode.Provider(config) + self.provider = linode.Provider(config) + elif api_version == 4: + config = dns_common_lexicon.build_lexicon_config('linode4', {}, { + 'auth_token': api_key, + }) + + self.provider = linode4.Provider(config) + else: + raise errors.PluginError('Invalid api version specified: {0}. (Supported: 3, 4)' + .format(api_version)) def _handle_general_error(self, e, domain_name): if not str(e).startswith('Domain not found'): return errors.PluginError('Unexpected error determining zone identifier for {0}: {1}' .format(domain_name, e)) - + return None diff --git a/certbot-dns-linode/certbot_dns_linode/dns_linode_test.py b/certbot-dns-linode/certbot_dns_linode/dns_linode_test.py deleted file mode 100644 index 2a0ee49f7..000000000 --- a/certbot-dns-linode/certbot_dns_linode/dns_linode_test.py +++ /dev/null @@ -1,47 +0,0 @@ -"""Tests for certbot_dns_linode.dns_linode.""" - -import os -import unittest - -import mock - -from certbot.plugins import dns_test_common -from certbot.plugins import dns_test_common_lexicon -from certbot.tests import util as test_util - -TOKEN = 'a-token' - -class AuthenticatorTest(test_util.TempDirTestCase, - dns_test_common_lexicon.BaseLexiconAuthenticatorTest): - - def setUp(self): - super(AuthenticatorTest, self).setUp() - - from certbot_dns_linode.dns_linode import Authenticator - - path = os.path.join(self.tempdir, 'file.ini') - dns_test_common.write({"linode_key": TOKEN}, path) - - self.config = mock.MagicMock(linode_credentials=path, - linode_propagation_seconds=0) # don't wait during tests - - self.auth = Authenticator(self.config, "linode") - - self.mock_client = mock.MagicMock() - # _get_linode_client | pylint: disable=protected-access - self.auth._get_linode_client = mock.MagicMock(return_value=self.mock_client) - -class LinodeLexiconClientTest(unittest.TestCase, dns_test_common_lexicon.BaseLexiconClientTest): - - DOMAIN_NOT_FOUND = Exception('Domain not found') - - def setUp(self): - from certbot_dns_linode.dns_linode import _LinodeLexiconClient - - self.client = _LinodeLexiconClient(TOKEN) - - self.provider_mock = mock.MagicMock() - self.client.provider = self.provider_mock - -if __name__ == "__main__": - unittest.main() # pragma: no cover |