From 651de2dd2fea9c79caae96d039f2570518735bdc Mon Sep 17 00:00:00 2001 From: Adrien Ferrand Date: Thu, 10 Jan 2019 20:36:15 +0100 Subject: [PATCH] Update Certbot dependency to Lexicon to 3.x (#6593) This PR updates Lexicon dependency to the latest version available, 3.0.6, for every lexicon-based DNS plugins. It updates also the provider construction to use the new ConfigResolverobject, and to remove the legacy configuration process. --- CHANGELOG.md | 12 +++++- .../certbot_dns_cloudxns/dns_cloudxns.py | 8 ++-- .../local-oldest-requirements.txt | 4 +- certbot-dns-cloudxns/setup.py | 6 +-- .../certbot_dns_dnsimple/dns_dnsimple.py | 8 ++-- .../local-oldest-requirements.txt | 5 ++- certbot-dns-dnsimple/setup.py | 6 +-- .../dns_dnsmadeeasy.py | 8 ++-- .../local-oldest-requirements.txt | 4 +- certbot-dns-dnsmadeeasy/setup.py | 6 +-- .../certbot_dns_gehirn/dns_gehirn.py | 8 ++-- .../local-oldest-requirements.txt | 2 + certbot-dns-gehirn/setup.py | 4 +- .../certbot_dns_linode/dns_linode.py | 9 +++-- .../local-oldest-requirements.txt | 4 +- certbot-dns-linode/setup.py | 4 +- .../certbot_dns_luadns/dns_luadns.py | 8 ++-- .../local-oldest-requirements.txt | 4 +- certbot-dns-luadns/setup.py | 6 +-- .../certbot_dns_nsone/dns_nsone.py | 8 ++-- .../local-oldest-requirements.txt | 4 +- certbot-dns-nsone/setup.py | 6 +-- certbot-dns-ovh/certbot_dns_ovh/dns_ovh.py | 8 ++-- certbot-dns-ovh/local-oldest-requirements.txt | 4 +- certbot-dns-ovh/setup.py | 6 +-- .../dns_sakuracloud.py | 8 ++-- .../local-oldest-requirements.txt | 2 + certbot-dns-sakuracloud/setup.py | 4 +- certbot/plugins/dns_common_lexicon.py | 37 ++++++++++++++++++- tools/dev_constraints.txt | 2 +- tools/oldest_constraints.txt | 6 +++ 31 files changed, 143 insertions(+), 68 deletions(-) create mode 100644 certbot-dns-gehirn/local-oldest-requirements.txt create mode 100644 certbot-dns-sakuracloud/local-oldest-requirements.txt diff --git a/CHANGELOG.md b/CHANGELOG.md index 07d00e3fa..1ca22f830 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,7 +11,8 @@ Certbot adheres to [Semantic Versioning](https://semver.org/). ### Changed -* +* Lexicon-based DNS plugins are now fully compatible with Lexicon 3.x (support + on 2.x branch is maintained). ### Fixed @@ -24,6 +25,15 @@ package with changes other than its version number was: * acme * certbot +* certbot-dns-cloudxns +* certbot-dns-dnsimple +* certbot-dns-dnsmadeeasy +* certbot-dns-gehirn +* certbot-dns-linode +* certbot-dns-luadns +* certbot-dns-nsone +* certbot-dns-ovh +* certbot-dns-sakuracloud More details about these changes can be found on our GitHub repo. diff --git a/certbot-dns-cloudxns/certbot_dns_cloudxns/dns_cloudxns.py b/certbot-dns-cloudxns/certbot_dns_cloudxns/dns_cloudxns.py index 658db6072..5132137f8 100644 --- a/certbot-dns-cloudxns/certbot_dns_cloudxns/dns_cloudxns.py +++ b/certbot-dns-cloudxns/certbot_dns_cloudxns/dns_cloudxns.py @@ -69,13 +69,15 @@ class _CloudXNSLexiconClient(dns_common_lexicon.LexiconClient): def __init__(self, api_key, secret_key, ttl): super(_CloudXNSLexiconClient, self).__init__() - self.provider = cloudxns.Provider({ - 'provider_name': 'cloudxns', + config = dns_common_lexicon.build_lexicon_config('cloudxns', { + 'ttl': ttl, + }, { 'auth_username': api_key, 'auth_token': secret_key, - 'ttl': ttl, }) + self.provider = cloudxns.Provider(config) + def _handle_http_error(self, e, domain_name): hint = None if str(e).startswith('400 Client Error:'): diff --git a/certbot-dns-cloudxns/local-oldest-requirements.txt b/certbot-dns-cloudxns/local-oldest-requirements.txt index 8368d266e..65f5a758e 100644 --- a/certbot-dns-cloudxns/local-oldest-requirements.txt +++ b/certbot-dns-cloudxns/local-oldest-requirements.txt @@ -1,2 +1,2 @@ -acme[dev]==0.21.1 -certbot[dev]==0.21.1 +-e acme[dev] +-e .[dev] diff --git a/certbot-dns-cloudxns/setup.py b/certbot-dns-cloudxns/setup.py index 5c8709445..1a6f900d8 100644 --- a/certbot-dns-cloudxns/setup.py +++ b/certbot-dns-cloudxns/setup.py @@ -7,9 +7,9 @@ version = '0.31.0.dev0' # Remember to update local-oldest-requirements.txt when changing the minimum # acme/certbot version. install_requires = [ - 'acme>=0.21.1', - 'certbot>=0.21.1', - 'dns-lexicon>=2.2.1', # Support for >1 TXT record per name + 'acme>=0.31.0.dev0', + 'certbot>=0.31.0.dev0', + 'dns-lexicon>=2.2.1', # Support for >1 TXT record per name 'mock', 'setuptools', 'zope.interface', diff --git a/certbot-dns-dnsimple/certbot_dns_dnsimple/dns_dnsimple.py b/certbot-dns-dnsimple/certbot_dns_dnsimple/dns_dnsimple.py index 3eb56e37c..ad2a3fa30 100644 --- a/certbot-dns-dnsimple/certbot_dns_dnsimple/dns_dnsimple.py +++ b/certbot-dns-dnsimple/certbot_dns_dnsimple/dns_dnsimple.py @@ -65,12 +65,14 @@ class _DNSimpleLexiconClient(dns_common_lexicon.LexiconClient): def __init__(self, token, ttl): super(_DNSimpleLexiconClient, self).__init__() - self.provider = dnsimple.Provider({ - 'provider_name': 'dnssimple', - 'auth_token': token, + config = dns_common_lexicon.build_lexicon_config('dnssimple', { 'ttl': ttl, + }, { + 'auth_token': token, }) + self.provider = dnsimple.Provider(config) + def _handle_http_error(self, e, domain_name): hint = None if str(e).startswith('401 Client Error: Unauthorized for url:'): diff --git a/certbot-dns-dnsimple/local-oldest-requirements.txt b/certbot-dns-dnsimple/local-oldest-requirements.txt index 8368d266e..5ecd3cbc7 100644 --- a/certbot-dns-dnsimple/local-oldest-requirements.txt +++ b/certbot-dns-dnsimple/local-oldest-requirements.txt @@ -1,2 +1,3 @@ -acme[dev]==0.21.1 -certbot[dev]==0.21.1 +-e acme[dev] +-e .[dev] +dns-lexicon==2.2.1 \ No newline at end of file diff --git a/certbot-dns-dnsimple/setup.py b/certbot-dns-dnsimple/setup.py index 3bb43cf5d..1a2ce5d92 100644 --- a/certbot-dns-dnsimple/setup.py +++ b/certbot-dns-dnsimple/setup.py @@ -7,9 +7,9 @@ version = '0.31.0.dev0' # Remember to update local-oldest-requirements.txt when changing the minimum # acme/certbot version. install_requires = [ - 'acme>=0.21.1', - 'certbot>=0.21.1', - 'dns-lexicon>=2.2.1', # Support for >1 TXT record per name + 'acme>=0.31.0.dev0', + 'certbot>=0.31.0.dev0', + 'dns-lexicon>=2.2.1', # Support for >1 TXT record per name 'mock', 'setuptools', 'zope.interface', diff --git a/certbot-dns-dnsmadeeasy/certbot_dns_dnsmadeeasy/dns_dnsmadeeasy.py b/certbot-dns-dnsmadeeasy/certbot_dns_dnsmadeeasy/dns_dnsmadeeasy.py index 4236ce37a..4b63cb4b5 100644 --- a/certbot-dns-dnsmadeeasy/certbot_dns_dnsmadeeasy/dns_dnsmadeeasy.py +++ b/certbot-dns-dnsmadeeasy/certbot_dns_dnsmadeeasy/dns_dnsmadeeasy.py @@ -71,13 +71,15 @@ class _DNSMadeEasyLexiconClient(dns_common_lexicon.LexiconClient): def __init__(self, api_key, secret_key, ttl): super(_DNSMadeEasyLexiconClient, self).__init__() - self.provider = dnsmadeeasy.Provider({ - 'provider_name': 'dnsmadeeasy', + config = dns_common_lexicon.build_lexicon_config('dnsmadeeasy', { + 'ttl': ttl, + }, { 'auth_username': api_key, 'auth_token': secret_key, - 'ttl': ttl, }) + self.provider = dnsmadeeasy.Provider(config) + def _handle_http_error(self, e, domain_name): if domain_name in str(e) and str(e).startswith('404 Client Error: Not Found for url:'): return diff --git a/certbot-dns-dnsmadeeasy/local-oldest-requirements.txt b/certbot-dns-dnsmadeeasy/local-oldest-requirements.txt index 8368d266e..65f5a758e 100644 --- a/certbot-dns-dnsmadeeasy/local-oldest-requirements.txt +++ b/certbot-dns-dnsmadeeasy/local-oldest-requirements.txt @@ -1,2 +1,2 @@ -acme[dev]==0.21.1 -certbot[dev]==0.21.1 +-e acme[dev] +-e .[dev] diff --git a/certbot-dns-dnsmadeeasy/setup.py b/certbot-dns-dnsmadeeasy/setup.py index 599cec486..0a99f452d 100644 --- a/certbot-dns-dnsmadeeasy/setup.py +++ b/certbot-dns-dnsmadeeasy/setup.py @@ -7,9 +7,9 @@ version = '0.31.0.dev0' # Remember to update local-oldest-requirements.txt when changing the minimum # acme/certbot version. install_requires = [ - 'acme>=0.21.1', - 'certbot>=0.21.1', - 'dns-lexicon>=2.2.1', # Support for >1 TXT record per name + 'acme>=0.31.0.dev0', + 'certbot>=0.31.0.dev0', + 'dns-lexicon>=2.2.1', # Support for >1 TXT record per name 'mock', 'setuptools', 'zope.interface', diff --git a/certbot-dns-gehirn/certbot_dns_gehirn/dns_gehirn.py b/certbot-dns-gehirn/certbot_dns_gehirn/dns_gehirn.py index 9c35e72ab..edf530072 100644 --- a/certbot-dns-gehirn/certbot_dns_gehirn/dns_gehirn.py +++ b/certbot-dns-gehirn/certbot_dns_gehirn/dns_gehirn.py @@ -72,13 +72,15 @@ class _GehirnLexiconClient(dns_common_lexicon.LexiconClient): def __init__(self, api_token, api_secret, ttl): super(_GehirnLexiconClient, self).__init__() - self.provider = gehirn.Provider({ - 'provider_name': 'gehirn', + config = dns_common_lexicon.build_lexicon_config('gehirn', { + 'ttl': ttl, + }, { 'auth_token': api_token, 'auth_secret': api_secret, - 'ttl': ttl, }) + self.provider = gehirn.Provider(config) + def _handle_http_error(self, e, domain_name): if domain_name in str(e) and (str(e).startswith('404 Client Error: Not Found for url:')): return # Expected errors when zone name guess is wrong diff --git a/certbot-dns-gehirn/local-oldest-requirements.txt b/certbot-dns-gehirn/local-oldest-requirements.txt new file mode 100644 index 000000000..65f5a758e --- /dev/null +++ b/certbot-dns-gehirn/local-oldest-requirements.txt @@ -0,0 +1,2 @@ +-e acme[dev] +-e .[dev] diff --git a/certbot-dns-gehirn/setup.py b/certbot-dns-gehirn/setup.py index 894d809ac..f4a75379c 100644 --- a/certbot-dns-gehirn/setup.py +++ b/certbot-dns-gehirn/setup.py @@ -6,8 +6,8 @@ version = '0.31.0.dev0' # Please update tox.ini when modifying dependency version requirements install_requires = [ - 'acme>=0.21.1', - 'certbot>=0.21.1', + 'acme>=0.31.0.dev0', + 'certbot>=0.31.0.dev0', 'dns-lexicon>=2.1.22', 'mock', 'setuptools', diff --git a/certbot-dns-linode/certbot_dns_linode/dns_linode.py b/certbot-dns-linode/certbot_dns_linode/dns_linode.py index 01da2cf60..4e0500fa0 100644 --- a/certbot-dns-linode/certbot_dns_linode/dns_linode.py +++ b/certbot-dns-linode/certbot_dns_linode/dns_linode.py @@ -54,6 +54,7 @@ class Authenticator(dns_common.DNSAuthenticator): def _get_linode_client(self): return _LinodeLexiconClient(self.credentials.conf('key')) + class _LinodeLexiconClient(dns_common_lexicon.LexiconClient): """ Encapsulates all communication with the Linode API. @@ -61,11 +62,13 @@ class _LinodeLexiconClient(dns_common_lexicon.LexiconClient): def __init__(self, api_key): super(_LinodeLexiconClient, self).__init__() - self.provider = linode.Provider({ - 'provider_name': 'linode', - 'auth_token': api_key + + config = dns_common_lexicon.build_lexicon_config('linode', {}, { + 'auth_token': api_key, }) + self.provider = linode.Provider(config) + 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}' diff --git a/certbot-dns-linode/local-oldest-requirements.txt b/certbot-dns-linode/local-oldest-requirements.txt index 8368d266e..65f5a758e 100644 --- a/certbot-dns-linode/local-oldest-requirements.txt +++ b/certbot-dns-linode/local-oldest-requirements.txt @@ -1,2 +1,2 @@ -acme[dev]==0.21.1 -certbot[dev]==0.21.1 +-e acme[dev] +-e .[dev] diff --git a/certbot-dns-linode/setup.py b/certbot-dns-linode/setup.py index 588b6a40a..31c2c20bc 100644 --- a/certbot-dns-linode/setup.py +++ b/certbot-dns-linode/setup.py @@ -5,8 +5,8 @@ version = '0.31.0.dev0' # Please update tox.ini when modifying dependency version requirements install_requires = [ - 'acme>=0.21.1', - 'certbot>=0.21.1', + 'acme>=0.31.0.dev0', + 'certbot>=0.31.0.dev0', 'dns-lexicon>=2.2.1', 'mock', 'setuptools', diff --git a/certbot-dns-luadns/certbot_dns_luadns/dns_luadns.py b/certbot-dns-luadns/certbot_dns_luadns/dns_luadns.py index bd6a16f69..7cdd4c8e1 100644 --- a/certbot-dns-luadns/certbot_dns_luadns/dns_luadns.py +++ b/certbot-dns-luadns/certbot_dns_luadns/dns_luadns.py @@ -68,13 +68,15 @@ class _LuaDNSLexiconClient(dns_common_lexicon.LexiconClient): def __init__(self, email, token, ttl): super(_LuaDNSLexiconClient, self).__init__() - self.provider = luadns.Provider({ - 'provider_name': 'luadns', + config = dns_common_lexicon.build_lexicon_config('luadns', { + 'ttl': ttl, + }, { 'auth_username': email, 'auth_token': token, - 'ttl': ttl, }) + self.provider = luadns.Provider(config) + def _handle_http_error(self, e, domain_name): hint = None if str(e).startswith('401 Client Error: Unauthorized for url:'): diff --git a/certbot-dns-luadns/local-oldest-requirements.txt b/certbot-dns-luadns/local-oldest-requirements.txt index 8368d266e..65f5a758e 100644 --- a/certbot-dns-luadns/local-oldest-requirements.txt +++ b/certbot-dns-luadns/local-oldest-requirements.txt @@ -1,2 +1,2 @@ -acme[dev]==0.21.1 -certbot[dev]==0.21.1 +-e acme[dev] +-e .[dev] diff --git a/certbot-dns-luadns/setup.py b/certbot-dns-luadns/setup.py index b09a09762..31472e8cf 100644 --- a/certbot-dns-luadns/setup.py +++ b/certbot-dns-luadns/setup.py @@ -7,9 +7,9 @@ version = '0.31.0.dev0' # Remember to update local-oldest-requirements.txt when changing the minimum # acme/certbot version. install_requires = [ - 'acme>=0.21.1', - 'certbot>=0.21.1', - 'dns-lexicon>=2.2.1', # Support for >1 TXT record per name + 'acme>=0.31.0.dev0', + 'certbot>=0.31.0.dev0', + 'dns-lexicon>=2.2.1', # Support for >1 TXT record per name 'mock', 'setuptools', 'zope.interface', diff --git a/certbot-dns-nsone/certbot_dns_nsone/dns_nsone.py b/certbot-dns-nsone/certbot_dns_nsone/dns_nsone.py index 5f33efbba..3e23df11c 100644 --- a/certbot-dns-nsone/certbot_dns_nsone/dns_nsone.py +++ b/certbot-dns-nsone/certbot_dns_nsone/dns_nsone.py @@ -65,12 +65,14 @@ class _NS1LexiconClient(dns_common_lexicon.LexiconClient): def __init__(self, api_key, ttl): super(_NS1LexiconClient, self).__init__() - self.provider = nsone.Provider({ - 'provider_name': 'nsone', - 'auth_token': api_key, + config = dns_common_lexicon.build_lexicon_config('nsone', { 'ttl': ttl, + }, { + 'auth_token': api_key, }) + self.provider = nsone.Provider(config) + def _handle_http_error(self, e, domain_name): if domain_name in str(e) and (str(e).startswith('404 Client Error: Not Found for url:') or \ str(e).startswith("400 Client Error: Bad Request for url:")): diff --git a/certbot-dns-nsone/local-oldest-requirements.txt b/certbot-dns-nsone/local-oldest-requirements.txt index 8368d266e..65f5a758e 100644 --- a/certbot-dns-nsone/local-oldest-requirements.txt +++ b/certbot-dns-nsone/local-oldest-requirements.txt @@ -1,2 +1,2 @@ -acme[dev]==0.21.1 -certbot[dev]==0.21.1 +-e acme[dev] +-e .[dev] diff --git a/certbot-dns-nsone/setup.py b/certbot-dns-nsone/setup.py index e48428191..41b99cc73 100644 --- a/certbot-dns-nsone/setup.py +++ b/certbot-dns-nsone/setup.py @@ -7,9 +7,9 @@ version = '0.31.0.dev0' # Remember to update local-oldest-requirements.txt when changing the minimum # acme/certbot version. install_requires = [ - 'acme>=0.21.1', - 'certbot>=0.21.1', - 'dns-lexicon>=2.2.1', # Support for >1 TXT record per name + 'acme>=0.31.0.dev0', + 'certbot>=0.31.0.dev0', + 'dns-lexicon>=2.2.1', # Support for >1 TXT record per name 'mock', 'setuptools', 'zope.interface', diff --git a/certbot-dns-ovh/certbot_dns_ovh/dns_ovh.py b/certbot-dns-ovh/certbot_dns_ovh/dns_ovh.py index 578ee8e89..84771b0a8 100644 --- a/certbot-dns-ovh/certbot_dns_ovh/dns_ovh.py +++ b/certbot-dns-ovh/certbot_dns_ovh/dns_ovh.py @@ -77,15 +77,17 @@ class _OVHLexiconClient(dns_common_lexicon.LexiconClient): def __init__(self, endpoint, application_key, application_secret, consumer_key, ttl): super(_OVHLexiconClient, self).__init__() - self.provider = ovh.Provider({ - 'provider_name': 'ovh', + config = dns_common_lexicon.build_lexicon_config('ovh', { + 'ttl': ttl, + }, { 'auth_entrypoint': endpoint, 'auth_application_key': application_key, 'auth_application_secret': application_secret, 'auth_consumer_key': consumer_key, - 'ttl': ttl, }) + self.provider = ovh.Provider(config) + def _handle_http_error(self, e, domain_name): hint = None if str(e).startswith('400 Client Error:'): diff --git a/certbot-dns-ovh/local-oldest-requirements.txt b/certbot-dns-ovh/local-oldest-requirements.txt index 8368d266e..65f5a758e 100644 --- a/certbot-dns-ovh/local-oldest-requirements.txt +++ b/certbot-dns-ovh/local-oldest-requirements.txt @@ -1,2 +1,2 @@ -acme[dev]==0.21.1 -certbot[dev]==0.21.1 +-e acme[dev] +-e .[dev] diff --git a/certbot-dns-ovh/setup.py b/certbot-dns-ovh/setup.py index 8b6d73d33..5b3329568 100644 --- a/certbot-dns-ovh/setup.py +++ b/certbot-dns-ovh/setup.py @@ -7,9 +7,9 @@ version = '0.31.0.dev0' # Remember to update local-oldest-requirements.txt when changing the minimum # acme/certbot version. install_requires = [ - 'acme>=0.21.1', - 'certbot>=0.21.1', - 'dns-lexicon>=2.7.14', # Correct proxy use on OVH provider + 'acme>=0.31.0.dev0', + 'certbot>=0.31.0.dev0', + 'dns-lexicon>=2.7.14', # Correct proxy use on OVH provider 'mock', 'setuptools', 'zope.interface', diff --git a/certbot-dns-sakuracloud/certbot_dns_sakuracloud/dns_sakuracloud.py b/certbot-dns-sakuracloud/certbot_dns_sakuracloud/dns_sakuracloud.py index b892330f5..7fd6d3ef5 100644 --- a/certbot-dns-sakuracloud/certbot_dns_sakuracloud/dns_sakuracloud.py +++ b/certbot-dns-sakuracloud/certbot_dns_sakuracloud/dns_sakuracloud.py @@ -75,13 +75,15 @@ class _SakuraCloudLexiconClient(dns_common_lexicon.LexiconClient): def __init__(self, api_token, api_secret, ttl): super(_SakuraCloudLexiconClient, self).__init__() - self.provider = sakuracloud.Provider({ - 'provider_name': 'sakuracloud', + config = dns_common_lexicon.build_lexicon_config('sakuracloud', { + 'ttl': ttl, + }, { 'auth_token': api_token, 'auth_secret': api_secret, - 'ttl': ttl, }) + self.provider = sakuracloud.Provider(config) + def _handle_http_error(self, e, domain_name): if domain_name in str(e) and (str(e).startswith('404 Client Error: Not Found for url:')): return # Expected errors when zone name guess is wrong diff --git a/certbot-dns-sakuracloud/local-oldest-requirements.txt b/certbot-dns-sakuracloud/local-oldest-requirements.txt new file mode 100644 index 000000000..65f5a758e --- /dev/null +++ b/certbot-dns-sakuracloud/local-oldest-requirements.txt @@ -0,0 +1,2 @@ +-e acme[dev] +-e .[dev] diff --git a/certbot-dns-sakuracloud/setup.py b/certbot-dns-sakuracloud/setup.py index 05843d2ed..4ebfc6e1d 100644 --- a/certbot-dns-sakuracloud/setup.py +++ b/certbot-dns-sakuracloud/setup.py @@ -6,8 +6,8 @@ version = '0.31.0.dev0' # Please update tox.ini when modifying dependency version requirements install_requires = [ - 'acme>=0.21.1', - 'certbot>=0.21.1', + 'acme>=0.31.0.dev0', + 'certbot>=0.31.0.dev0', 'dns-lexicon>=2.1.23', 'mock', 'setuptools', diff --git a/certbot/plugins/dns_common_lexicon.py b/certbot/plugins/dns_common_lexicon.py index f9610b816..5b50cc285 100644 --- a/certbot/plugins/dns_common_lexicon.py +++ b/certbot/plugins/dns_common_lexicon.py @@ -1,12 +1,22 @@ """Common code for DNS Authenticator Plugins built on Lexicon.""" - import logging from requests.exceptions import HTTPError, RequestException +from acme.magic_typing import Union, Dict, Any # pylint: disable=unused-import,no-name-in-module from certbot import errors from certbot.plugins import dns_common +# Lexicon is not declared as a dependency in Certbot itself, +# but in the Certbot plugins backed by Lexicon. +# So we catch import error here to allow this module to be +# always importable, even if it does not make sense to use it +# if Lexicon is not available, obviously. +try: + from lexicon.config import ConfigResolver +except ImportError: + ConfigResolver = None # type: ignore + logger = logging.getLogger(__name__) @@ -100,3 +110,28 @@ class LexiconClient(object): if not str(e).startswith('No domain found'): return errors.PluginError('Unexpected error determining zone identifier for {0}: {1}' .format(domain_name, e)) + + +def build_lexicon_config(lexicon_provider_name, lexicon_options, provider_options): + # type: (str, Dict, Dict) -> Union[ConfigResolver, Dict] + """ + Convenient function to build a Lexicon 2.x/3.x config object. + :param str lexicon_provider_name: the name of the lexicon provider to use + :param dict lexicon_options: options specific to lexicon + :param dict provider_options: options specific to provider + :return: configuration to apply to the provider + :rtype: ConfigurationResolver or dict + """ + config = {'provider_name': lexicon_provider_name} # type: Dict[str, Any] + config.update(lexicon_options) + if not ConfigResolver: + # Lexicon 2.x + config.update(provider_options) + else: + # Lexicon 3.x + provider_config = {} + provider_config.update(provider_options) + config[lexicon_provider_name] = provider_config + config = ConfigResolver().with_dict(config).with_env() + + return config diff --git a/tools/dev_constraints.txt b/tools/dev_constraints.txt index 778012d31..111dc5495 100644 --- a/tools/dev_constraints.txt +++ b/tools/dev_constraints.txt @@ -12,7 +12,7 @@ botocore==1.12.36 cloudflare==1.5.1 coverage==4.4.2 decorator==4.1.2 -dns-lexicon==2.7.14 +dns-lexicon==3.0.8 dnspython==1.15.0 docutils==0.12 execnet==1.5.0 diff --git a/tools/oldest_constraints.txt b/tools/oldest_constraints.txt index 20fa0672a..642af660e 100644 --- a/tools/oldest_constraints.txt +++ b/tools/oldest_constraints.txt @@ -50,6 +50,12 @@ ConfigArgParse==0.10.0 funcsigs==0.4 zope.hookable==4.0.4 +# Ubuntu Bionic constraints +# Formerly only lexicon==2.2.1 is available on Bionic. But we cannot put that here because some +# DNS plugins require higher versions. We put to the least minimal Lexicon version to ensure +# that Lexicon 2.x works with Certbot. +dns-lexicon==2.7.14 + # Plugin constraints # These aren't necessarily the oldest versions we need to support # Tracking at https://github.com/certbot/certbot/issues/6473