Hello community,
here is the log from the commit of package python-certbot-dns-rfc2136 for
openSUSE:Factory checked in at 2020-01-03 17:39:22
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-certbot-dns-rfc2136 (Old)
and /work/SRC/openSUSE:Factory/.python-certbot-dns-rfc2136.new.6675 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-certbot-dns-rfc2136"
Fri Jan 3 17:39:22 2020 rev:15 rq:760664 version:1.0.0
Changes:
--------
---
/work/SRC/openSUSE:Factory/python-certbot-dns-rfc2136/python-certbot-dns-rfc2136.changes
2019-11-15 00:28:41.219775262 +0100
+++
/work/SRC/openSUSE:Factory/.python-certbot-dns-rfc2136.new.6675/python-certbot-dns-rfc2136.changes
2020-01-03 17:39:42.255379438 +0100
@@ -1,0 +2,6 @@
+Fri Jan 3 13:13:13 UTC 2020 - Marketa Calabkova <[email protected]>
+
+- update to version 1.0.0
+ * sync with main certbot package
+
+-------------------------------------------------------------------
Old:
----
certbot-dns-rfc2136-0.40.1.tar.gz
New:
----
certbot-dns-rfc2136-1.0.0.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ python-certbot-dns-rfc2136.spec ++++++
--- /var/tmp/diff_new_pack.uAJCc0/_old 2020-01-03 17:39:43.187379917 +0100
+++ /var/tmp/diff_new_pack.uAJCc0/_new 2020-01-03 17:39:43.187379917 +0100
@@ -1,7 +1,7 @@
#
# spec file for package python-certbot-dns-rfc2136
#
-# Copyright (c) 2019 SUSE LLC.
+# Copyright (c) 2020 SUSE LLC
#
# All modifications and additions to the file contributed by third parties
# remain the property of their copyright owners, unless otherwise agreed
@@ -18,20 +18,21 @@
%{?!python_module:%define python_module() python-%{**} python3-%{**}}
Name: python-certbot-dns-rfc2136
-Version: 0.40.1
+Version: 1.0.0
Release: 0
Summary: RFC 2136 DNS Authenticator plugin for Certbot
License: Apache-2.0
URL: https://github.com/certbot/certbot
Source:
https://files.pythonhosted.org/packages/source/c/certbot-dns-rfc2136/certbot-dns-rfc2136-%{version}.tar.gz
-BuildRequires: %{python_module certbot >= 0.39.0}
+BuildRequires: %{python_module certbot >= 1.0.0}
BuildRequires: %{python_module dnspython}
BuildRequires: %{python_module mock}
+BuildRequires: %{python_module pytest}
BuildRequires: %{python_module setuptools}
BuildRequires: fdupes
BuildRequires: python-rpm-macros
Requires: python-acme >= 0.29.0
-Requires: python-certbot >= 0.39.0
+Requires: python-certbot >= 1.0.0
Requires: python-dnspython
Requires: python-zope.interface
BuildArch: noarch
++++++ certbot-dns-rfc2136-0.40.1.tar.gz -> certbot-dns-rfc2136-1.0.0.tar.gz
++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/certbot-dns-rfc2136-0.40.1/MANIFEST.in
new/certbot-dns-rfc2136-1.0.0/MANIFEST.in
--- old/certbot-dns-rfc2136-0.40.1/MANIFEST.in 2019-11-06 03:24:51.000000000
+0100
+++ new/certbot-dns-rfc2136-1.0.0/MANIFEST.in 2019-12-03 18:20:30.000000000
+0100
@@ -1,3 +1,6 @@
include LICENSE.txt
include README.rst
recursive-include docs *
+recursive-include tests *
+global-exclude __pycache__
+global-exclude *.py[cod]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/certbot-dns-rfc2136-0.40.1/PKG-INFO
new/certbot-dns-rfc2136-1.0.0/PKG-INFO
--- old/certbot-dns-rfc2136-0.40.1/PKG-INFO 2019-11-06 03:25:24.000000000
+0100
+++ new/certbot-dns-rfc2136-1.0.0/PKG-INFO 2019-12-03 18:21:15.000000000
+0100
@@ -1,6 +1,6 @@
Metadata-Version: 2.1
Name: certbot-dns-rfc2136
-Version: 0.40.1
+Version: 1.0.0
Summary: RFC 2136 DNS Authenticator plugin for Certbot
Home-page: https://github.com/certbot/certbot
Author: Certbot Project
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/certbot-dns-rfc2136-0.40.1/certbot_dns_rfc2136/_internal/__init__.py
new/certbot-dns-rfc2136-1.0.0/certbot_dns_rfc2136/_internal/__init__.py
--- old/certbot-dns-rfc2136-0.40.1/certbot_dns_rfc2136/_internal/__init__.py
1970-01-01 01:00:00.000000000 +0100
+++ new/certbot-dns-rfc2136-1.0.0/certbot_dns_rfc2136/_internal/__init__.py
2019-12-03 18:20:30.000000000 +0100
@@ -0,0 +1 @@
+"""Internal implementation of `~certbot_dns_rfc2136.dns_rfc2136` plugin."""
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/certbot-dns-rfc2136-0.40.1/certbot_dns_rfc2136/_internal/dns_rfc2136.py
new/certbot-dns-rfc2136-1.0.0/certbot_dns_rfc2136/_internal/dns_rfc2136.py
--- old/certbot-dns-rfc2136-0.40.1/certbot_dns_rfc2136/_internal/dns_rfc2136.py
1970-01-01 01:00:00.000000000 +0100
+++ new/certbot-dns-rfc2136-1.0.0/certbot_dns_rfc2136/_internal/dns_rfc2136.py
2019-12-03 18:20:30.000000000 +0100
@@ -0,0 +1,226 @@
+"""DNS Authenticator using RFC 2136 Dynamic Updates."""
+import logging
+
+import dns.flags
+import dns.message
+import dns.name
+import dns.query
+import dns.rdataclass
+import dns.rdatatype
+import dns.tsig
+import dns.tsigkeyring
+import dns.update
+import zope.interface
+
+from certbot import errors
+from certbot import interfaces
+from certbot.plugins import dns_common
+
+logger = logging.getLogger(__name__)
+
+
[email protected](interfaces.IAuthenticator)
[email protected](interfaces.IPluginFactory)
+class Authenticator(dns_common.DNSAuthenticator):
+ """DNS Authenticator using RFC 2136 Dynamic Updates
+
+ This Authenticator uses RFC 2136 Dynamic Updates to fulfull a dns-01
challenge.
+ """
+
+ ALGORITHMS = {
+ 'HMAC-MD5': dns.tsig.HMAC_MD5,
+ 'HMAC-SHA1': dns.tsig.HMAC_SHA1,
+ 'HMAC-SHA224': dns.tsig.HMAC_SHA224,
+ 'HMAC-SHA256': dns.tsig.HMAC_SHA256,
+ 'HMAC-SHA384': dns.tsig.HMAC_SHA384,
+ 'HMAC-SHA512': dns.tsig.HMAC_SHA512
+ }
+
+ PORT = 53
+
+ description = 'Obtain certificates using a DNS TXT record (if you are
using BIND for DNS).'
+ ttl = 120
+
+ def __init__(self, *args, **kwargs):
+ super(Authenticator, self).__init__(*args, **kwargs)
+ self.credentials = None
+
+ @classmethod
+ def add_parser_arguments(cls, add): # pylint: disable=arguments-differ
+ super(Authenticator, cls).add_parser_arguments(add,
default_propagation_seconds=60)
+ add('credentials', help='RFC 2136 credentials INI file.')
+
+ def more_info(self): # pylint: disable=missing-docstring,no-self-use
+ return 'This plugin configures a DNS TXT record to respond to a dns-01
challenge using ' + \
+ 'RFC 2136 Dynamic Updates.'
+
+ def _validate_algorithm(self, credentials):
+ algorithm = credentials.conf('algorithm')
+ if algorithm:
+ if not self.ALGORITHMS.get(algorithm.upper()):
+ raise errors.PluginError("Unknown algorithm:
{0}.".format(algorithm))
+
+ def _setup_credentials(self):
+ self.credentials = self._configure_credentials(
+ 'credentials',
+ 'RFC 2136 credentials INI file',
+ {
+ 'name': 'TSIG key name',
+ 'secret': 'TSIG key secret',
+ 'server': 'The target DNS server'
+ },
+ self._validate_algorithm
+ )
+
+ def _perform(self, _domain, validation_name, validation):
+ self._get_rfc2136_client().add_txt_record(validation_name, validation,
self.ttl)
+
+ def _cleanup(self, _domain, validation_name, validation):
+ self._get_rfc2136_client().del_txt_record(validation_name, validation)
+
+ def _get_rfc2136_client(self):
+ return _RFC2136Client(self.credentials.conf('server'),
+ int(self.credentials.conf('port') or self.PORT),
+ self.credentials.conf('name'),
+ self.credentials.conf('secret'),
+
self.ALGORITHMS.get(self.credentials.conf('algorithm'),
+ dns.tsig.HMAC_MD5))
+
+
+class _RFC2136Client(object):
+ """
+ Encapsulates all communication with the target DNS server.
+ """
+ def __init__(self, server, port, key_name, key_secret, key_algorithm):
+ self.server = server
+ self.port = port
+ self.keyring = dns.tsigkeyring.from_text({
+ key_name: key_secret
+ })
+ self.algorithm = key_algorithm
+
+ def add_txt_record(self, record_name, record_content, record_ttl):
+ """
+ Add a TXT record using the supplied information.
+
+ :param str record_name: The record name (typically beginning with
'_acme-challenge.').
+ :param str record_content: The record content (typically the challenge
validation).
+ :param int record_ttl: The record TTL (number of seconds that the
record may be cached).
+ :raises certbot.errors.PluginError: if an error occurs communicating
with the DNS server
+ """
+
+ domain = self._find_domain(record_name)
+
+ n = dns.name.from_text(record_name)
+ o = dns.name.from_text(domain)
+ rel = n.relativize(o)
+
+ update = dns.update.Update(
+ domain,
+ keyring=self.keyring,
+ keyalgorithm=self.algorithm)
+ update.add(rel, record_ttl, dns.rdatatype.TXT, record_content)
+
+ try:
+ response = dns.query.tcp(update, self.server, port=self.port)
+ except Exception as e:
+ raise errors.PluginError('Encountered error adding TXT record: {0}'
+ .format(e))
+ rcode = response.rcode()
+
+ if rcode == dns.rcode.NOERROR:
+ logger.debug('Successfully added TXT record')
+ else:
+ raise errors.PluginError('Received response from server: {0}'
+ .format(dns.rcode.to_text(rcode)))
+
+ def del_txt_record(self, record_name, record_content):
+ """
+ Delete a TXT record using the supplied information.
+
+ :param str record_name: The record name (typically beginning with
'_acme-challenge.').
+ :param str record_content: The record content (typically the challenge
validation).
+ :param int record_ttl: The record TTL (number of seconds that the
record may be cached).
+ :raises certbot.errors.PluginError: if an error occurs communicating
with the DNS server
+ """
+
+ domain = self._find_domain(record_name)
+
+ n = dns.name.from_text(record_name)
+ o = dns.name.from_text(domain)
+ rel = n.relativize(o)
+
+ update = dns.update.Update(
+ domain,
+ keyring=self.keyring,
+ keyalgorithm=self.algorithm)
+ update.delete(rel, dns.rdatatype.TXT, record_content)
+
+ try:
+ response = dns.query.tcp(update, self.server, port=self.port)
+ except Exception as e:
+ raise errors.PluginError('Encountered error deleting TXT record:
{0}'
+ .format(e))
+ rcode = response.rcode()
+
+ if rcode == dns.rcode.NOERROR:
+ logger.debug('Successfully deleted TXT record')
+ else:
+ raise errors.PluginError('Received response from server: {0}'
+ .format(dns.rcode.to_text(rcode)))
+
+ def _find_domain(self, record_name):
+ """
+ Find the closest domain with an SOA record for a given domain name.
+
+ :param str record_name: The record name for which to find the closest
SOA record.
+ :returns: The domain, if found.
+ :rtype: str
+ :raises certbot.errors.PluginError: if no SOA record can be found.
+ """
+
+ domain_name_guesses = dns_common.base_domain_name_guesses(record_name)
+
+ # Loop through until we find an authoritative SOA record
+ for guess in domain_name_guesses:
+ if self._query_soa(guess):
+ return guess
+
+ raise errors.PluginError('Unable to determine base domain for {0}
using names: {1}.'
+ .format(record_name, domain_name_guesses))
+
+ def _query_soa(self, domain_name):
+ """
+ Query a domain name for an authoritative SOA record.
+
+ :param str domain_name: The domain name to query for an SOA record.
+ :returns: True if found, False otherwise.
+ :rtype: bool
+ :raises certbot.errors.PluginError: if no response is received.
+ """
+
+ domain = dns.name.from_text(domain_name)
+
+ request = dns.message.make_query(domain, dns.rdatatype.SOA,
dns.rdataclass.IN)
+ # Turn off Recursion Desired bit in query
+ request.flags ^= dns.flags.RD
+
+ try:
+ try:
+ response = dns.query.tcp(request, self.server, port=self.port)
+ except OSError as e:
+ logger.debug('TCP query failed, fallback to UDP: %s', e)
+ response = dns.query.udp(request, self.server, port=self.port)
+ rcode = response.rcode()
+
+ # Authoritative Answer bit should be set
+ if (rcode == dns.rcode.NOERROR and
response.get_rrset(response.answer,
+ domain, dns.rdataclass.IN, dns.rdatatype.SOA) and
response.flags & dns.flags.AA):
+ logger.debug('Received authoritative SOA response for %s',
domain_name)
+ return True
+
+ logger.debug('No authoritative SOA record found for %s',
domain_name)
+ return False
+ except Exception as e:
+ raise errors.PluginError('Encountered error when making query: {0}'
+ .format(e))
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/certbot-dns-rfc2136-0.40.1/certbot_dns_rfc2136/dns_rfc2136.py
new/certbot-dns-rfc2136-1.0.0/certbot_dns_rfc2136/dns_rfc2136.py
--- old/certbot-dns-rfc2136-0.40.1/certbot_dns_rfc2136/dns_rfc2136.py
2019-11-06 03:24:51.000000000 +0100
+++ new/certbot-dns-rfc2136-1.0.0/certbot_dns_rfc2136/dns_rfc2136.py
1970-01-01 01:00:00.000000000 +0100
@@ -1,222 +0,0 @@
-"""DNS Authenticator using RFC 2136 Dynamic Updates."""
-import logging
-
-import dns.flags
-import dns.message
-import dns.name
-import dns.query
-import dns.rdataclass
-import dns.rdatatype
-import dns.tsig
-import dns.tsigkeyring
-import dns.update
-import zope.interface
-
-from certbot import errors
-from certbot import interfaces
-from certbot.plugins import dns_common
-
-logger = logging.getLogger(__name__)
-
-
[email protected](interfaces.IAuthenticator)
[email protected](interfaces.IPluginFactory)
-class Authenticator(dns_common.DNSAuthenticator):
- """DNS Authenticator using RFC 2136 Dynamic Updates
-
- This Authenticator uses RFC 2136 Dynamic Updates to fulfull a dns-01
challenge.
- """
-
- ALGORITHMS = {
- 'HMAC-MD5': dns.tsig.HMAC_MD5,
- 'HMAC-SHA1': dns.tsig.HMAC_SHA1,
- 'HMAC-SHA224': dns.tsig.HMAC_SHA224,
- 'HMAC-SHA256': dns.tsig.HMAC_SHA256,
- 'HMAC-SHA384': dns.tsig.HMAC_SHA384,
- 'HMAC-SHA512': dns.tsig.HMAC_SHA512
- }
-
- PORT = 53
-
- description = 'Obtain certificates using a DNS TXT record (if you are
using BIND for DNS).'
- ttl = 120
-
- def __init__(self, *args, **kwargs):
- super(Authenticator, self).__init__(*args, **kwargs)
- self.credentials = None
-
- @classmethod
- def add_parser_arguments(cls, add): # pylint: disable=arguments-differ
- super(Authenticator, cls).add_parser_arguments(add,
default_propagation_seconds=60)
- add('credentials', help='RFC 2136 credentials INI file.')
-
- def more_info(self): # pylint: disable=missing-docstring,no-self-use
- return 'This plugin configures a DNS TXT record to respond to a dns-01
challenge using ' + \
- 'RFC 2136 Dynamic Updates.'
-
- def _validate_algorithm(self, credentials):
- algorithm = credentials.conf('algorithm')
- if algorithm:
- if not self.ALGORITHMS.get(algorithm.upper()):
- raise errors.PluginError("Unknown algorithm:
{0}.".format(algorithm))
-
- def _setup_credentials(self):
- self.credentials = self._configure_credentials(
- 'credentials',
- 'RFC 2136 credentials INI file',
- {
- 'name': 'TSIG key name',
- 'secret': 'TSIG key secret',
- 'server': 'The target DNS server'
- },
- self._validate_algorithm
- )
-
- def _perform(self, _domain, validation_name, validation):
- self._get_rfc2136_client().add_txt_record(validation_name, validation,
self.ttl)
-
- def _cleanup(self, _domain, validation_name, validation):
- self._get_rfc2136_client().del_txt_record(validation_name, validation)
-
- def _get_rfc2136_client(self):
- return _RFC2136Client(self.credentials.conf('server'),
- int(self.credentials.conf('port') or self.PORT),
- self.credentials.conf('name'),
- self.credentials.conf('secret'),
-
self.ALGORITHMS.get(self.credentials.conf('algorithm'),
- dns.tsig.HMAC_MD5))
-
-
-class _RFC2136Client(object):
- """
- Encapsulates all communication with the target DNS server.
- """
- def __init__(self, server, port, key_name, key_secret, key_algorithm):
- self.server = server
- self.port = port
- self.keyring = dns.tsigkeyring.from_text({
- key_name: key_secret
- })
- self.algorithm = key_algorithm
-
- def add_txt_record(self, record_name, record_content, record_ttl):
- """
- Add a TXT record using the supplied information.
-
- :param str record_name: The record name (typically beginning with
'_acme-challenge.').
- :param str record_content: The record content (typically the challenge
validation).
- :param int record_ttl: The record TTL (number of seconds that the
record may be cached).
- :raises certbot.errors.PluginError: if an error occurs communicating
with the DNS server
- """
-
- domain = self._find_domain(record_name)
-
- n = dns.name.from_text(record_name)
- o = dns.name.from_text(domain)
- rel = n.relativize(o)
-
- update = dns.update.Update(
- domain,
- keyring=self.keyring,
- keyalgorithm=self.algorithm)
- update.add(rel, record_ttl, dns.rdatatype.TXT, record_content)
-
- try:
- response = dns.query.tcp(update, self.server, port=self.port)
- except Exception as e:
- raise errors.PluginError('Encountered error adding TXT record: {0}'
- .format(e))
- rcode = response.rcode()
-
- if rcode == dns.rcode.NOERROR:
- logger.debug('Successfully added TXT record')
- else:
- raise errors.PluginError('Received response from server: {0}'
- .format(dns.rcode.to_text(rcode)))
-
- def del_txt_record(self, record_name, record_content):
- """
- Delete a TXT record using the supplied information.
-
- :param str record_name: The record name (typically beginning with
'_acme-challenge.').
- :param str record_content: The record content (typically the challenge
validation).
- :param int record_ttl: The record TTL (number of seconds that the
record may be cached).
- :raises certbot.errors.PluginError: if an error occurs communicating
with the DNS server
- """
-
- domain = self._find_domain(record_name)
-
- n = dns.name.from_text(record_name)
- o = dns.name.from_text(domain)
- rel = n.relativize(o)
-
- update = dns.update.Update(
- domain,
- keyring=self.keyring,
- keyalgorithm=self.algorithm)
- update.delete(rel, dns.rdatatype.TXT, record_content)
-
- try:
- response = dns.query.tcp(update, self.server, port=self.port)
- except Exception as e:
- raise errors.PluginError('Encountered error deleting TXT record:
{0}'
- .format(e))
- rcode = response.rcode()
-
- if rcode == dns.rcode.NOERROR:
- logger.debug('Successfully deleted TXT record')
- else:
- raise errors.PluginError('Received response from server: {0}'
- .format(dns.rcode.to_text(rcode)))
-
- def _find_domain(self, record_name):
- """
- Find the closest domain with an SOA record for a given domain name.
-
- :param str record_name: The record name for which to find the closest
SOA record.
- :returns: The domain, if found.
- :rtype: str
- :raises certbot.errors.PluginError: if no SOA record can be found.
- """
-
- domain_name_guesses = dns_common.base_domain_name_guesses(record_name)
-
- # Loop through until we find an authoritative SOA record
- for guess in domain_name_guesses:
- if self._query_soa(guess):
- return guess
-
- raise errors.PluginError('Unable to determine base domain for {0}
using names: {1}.'
- .format(record_name, domain_name_guesses))
-
- def _query_soa(self, domain_name):
- """
- Query a domain name for an authoritative SOA record.
-
- :param str domain_name: The domain name to query for an SOA record.
- :returns: True if found, False otherwise.
- :rtype: bool
- :raises certbot.errors.PluginError: if no response is received.
- """
-
- domain = dns.name.from_text(domain_name)
-
- request = dns.message.make_query(domain, dns.rdatatype.SOA,
dns.rdataclass.IN)
- # Turn off Recursion Desired bit in query
- request.flags ^= dns.flags.RD
-
- try:
- response = dns.query.udp(request, self.server, port=self.port)
- rcode = response.rcode()
-
- # Authoritative Answer bit should be set
- if (rcode == dns.rcode.NOERROR and
response.get_rrset(response.answer,
- domain, dns.rdataclass.IN, dns.rdatatype.SOA) and
response.flags & dns.flags.AA):
- logger.debug('Received authoritative SOA response for %s',
domain_name)
- return True
-
- logger.debug('No authoritative SOA record found for %s',
domain_name)
- return False
- except Exception as e:
- raise errors.PluginError('Encountered error when making query: {0}'
- .format(e))
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/certbot-dns-rfc2136-0.40.1/certbot_dns_rfc2136/dns_rfc2136_test.py
new/certbot-dns-rfc2136-1.0.0/certbot_dns_rfc2136/dns_rfc2136_test.py
--- old/certbot-dns-rfc2136-0.40.1/certbot_dns_rfc2136/dns_rfc2136_test.py
2019-11-06 03:24:51.000000000 +0100
+++ new/certbot-dns-rfc2136-1.0.0/certbot_dns_rfc2136/dns_rfc2136_test.py
1970-01-01 01:00:00.000000000 +0100
@@ -1,198 +0,0 @@
-"""Tests for certbot_dns_rfc2136.dns_rfc2136."""
-
-import unittest
-
-import dns.flags
-import dns.rcode
-import dns.tsig
-import mock
-
-from certbot import errors
-from certbot.compat import os
-from certbot.plugins import dns_test_common
-from certbot.plugins.dns_test_common import DOMAIN
-from certbot.tests import util as test_util
-
-SERVER = '192.0.2.1'
-PORT = 53
-NAME = 'a-tsig-key.'
-SECRET = 'SSB3b25kZXIgd2hvIHdpbGwgYm90aGVyIHRvIGRlY29kZSB0aGlzIHRleHQK'
-VALID_CONFIG = {"rfc2136_server": SERVER, "rfc2136_name": NAME,
"rfc2136_secret": SECRET}
-
-
-class AuthenticatorTest(test_util.TempDirTestCase,
dns_test_common.BaseAuthenticatorTest):
-
- def setUp(self):
- from certbot_dns_rfc2136.dns_rfc2136 import Authenticator
-
- super(AuthenticatorTest, self).setUp()
-
- path = os.path.join(self.tempdir, 'file.ini')
- dns_test_common.write(VALID_CONFIG, path)
-
- self.config = mock.MagicMock(rfc2136_credentials=path,
- rfc2136_propagation_seconds=0) # don't
wait during tests
-
- self.auth = Authenticator(self.config, "rfc2136")
-
- self.mock_client = mock.MagicMock()
- # _get_rfc2136_client | pylint: disable=protected-access
- self.auth._get_rfc2136_client =
mock.MagicMock(return_value=self.mock_client)
-
- def test_perform(self):
- self.auth.perform([self.achall])
-
- expected = [mock.call.add_txt_record('_acme-challenge.'+DOMAIN,
mock.ANY, mock.ANY)]
- self.assertEqual(expected, self.mock_client.mock_calls)
-
- def test_cleanup(self):
- # _attempt_cleanup | pylint: disable=protected-access
- self.auth._attempt_cleanup = True
- self.auth.cleanup([self.achall])
-
- expected = [mock.call.del_txt_record('_acme-challenge.'+DOMAIN,
mock.ANY)]
- self.assertEqual(expected, self.mock_client.mock_calls)
-
- def test_invalid_algorithm_raises(self):
- config = VALID_CONFIG.copy()
- config["rfc2136_algorithm"] = "INVALID"
- dns_test_common.write(config, self.config.rfc2136_credentials)
-
- self.assertRaises(errors.PluginError,
- self.auth.perform,
- [self.achall])
-
- def test_valid_algorithm_passes(self):
- config = VALID_CONFIG.copy()
- config["rfc2136_algorithm"] = "HMAC-sha512"
- dns_test_common.write(config, self.config.rfc2136_credentials)
-
- self.auth.perform([self.achall])
-
-
-class RFC2136ClientTest(unittest.TestCase):
-
- def setUp(self):
- from certbot_dns_rfc2136.dns_rfc2136 import _RFC2136Client
-
- self.rfc2136_client = _RFC2136Client(SERVER, PORT, NAME, SECRET,
dns.tsig.HMAC_MD5)
-
- @mock.patch("dns.query.tcp")
- def test_add_txt_record(self, query_mock):
- query_mock.return_value.rcode.return_value = dns.rcode.NOERROR
- # _find_domain | pylint: disable=protected-access
- self.rfc2136_client._find_domain =
mock.MagicMock(return_value="example.com")
-
- self.rfc2136_client.add_txt_record("bar", "baz", 42)
-
- query_mock.assert_called_with(mock.ANY, SERVER, port=PORT)
- self.assertTrue("bar. 42 IN TXT \"baz\"" in
str(query_mock.call_args[0][0]))
-
- @mock.patch("dns.query.tcp")
- def test_add_txt_record_wraps_errors(self, query_mock):
- query_mock.side_effect = Exception
- # _find_domain | pylint: disable=protected-access
- self.rfc2136_client._find_domain =
mock.MagicMock(return_value="example.com")
-
- self.assertRaises(
- errors.PluginError,
- self.rfc2136_client.add_txt_record,
- "bar", "baz", 42)
-
- @mock.patch("dns.query.tcp")
- def test_add_txt_record_server_error(self, query_mock):
- query_mock.return_value.rcode.return_value = dns.rcode.NXDOMAIN
- # _find_domain | pylint: disable=protected-access
- self.rfc2136_client._find_domain =
mock.MagicMock(return_value="example.com")
-
- self.assertRaises(
- errors.PluginError,
- self.rfc2136_client.add_txt_record,
- "bar", "baz", 42)
-
- @mock.patch("dns.query.tcp")
- def test_del_txt_record(self, query_mock):
- query_mock.return_value.rcode.return_value = dns.rcode.NOERROR
- # _find_domain | pylint: disable=protected-access
- self.rfc2136_client._find_domain =
mock.MagicMock(return_value="example.com")
-
- self.rfc2136_client.del_txt_record("bar", "baz")
-
- query_mock.assert_called_with(mock.ANY, SERVER, port=PORT)
- self.assertTrue("bar. 0 NONE TXT \"baz\"" in
str(query_mock.call_args[0][0]))
-
- @mock.patch("dns.query.tcp")
- def test_del_txt_record_wraps_errors(self, query_mock):
- query_mock.side_effect = Exception
- # _find_domain | pylint: disable=protected-access
- self.rfc2136_client._find_domain =
mock.MagicMock(return_value="example.com")
-
- self.assertRaises(
- errors.PluginError,
- self.rfc2136_client.del_txt_record,
- "bar", "baz")
-
- @mock.patch("dns.query.tcp")
- def test_del_txt_record_server_error(self, query_mock):
- query_mock.return_value.rcode.return_value = dns.rcode.NXDOMAIN
- # _find_domain | pylint: disable=protected-access
- self.rfc2136_client._find_domain =
mock.MagicMock(return_value="example.com")
-
- self.assertRaises(
- errors.PluginError,
- self.rfc2136_client.del_txt_record,
- "bar", "baz")
-
- def test_find_domain(self):
- # _query_soa | pylint: disable=protected-access
- self.rfc2136_client._query_soa = mock.MagicMock(side_effect=[False,
False, True])
-
- # _find_domain | pylint: disable=protected-access
- domain = self.rfc2136_client._find_domain('foo.bar.'+DOMAIN)
-
- self.assertTrue(domain == DOMAIN)
-
- def test_find_domain_wraps_errors(self):
- # _query_soa | pylint: disable=protected-access
- self.rfc2136_client._query_soa = mock.MagicMock(return_value=False)
-
- self.assertRaises(
- errors.PluginError,
- # _find_domain | pylint: disable=protected-access
- self.rfc2136_client._find_domain,
- 'foo.bar.'+DOMAIN)
-
- @mock.patch("dns.query.udp")
- def test_query_soa_found(self, query_mock):
- query_mock.return_value = mock.MagicMock(answer=[mock.MagicMock()],
flags=dns.flags.AA)
- query_mock.return_value.rcode.return_value = dns.rcode.NOERROR
-
- # _query_soa | pylint: disable=protected-access
- result = self.rfc2136_client._query_soa(DOMAIN)
-
- query_mock.assert_called_with(mock.ANY, SERVER, port=PORT)
- self.assertTrue(result)
-
- @mock.patch("dns.query.udp")
- def test_query_soa_not_found(self, query_mock):
- query_mock.return_value.rcode.return_value = dns.rcode.NXDOMAIN
-
- # _query_soa | pylint: disable=protected-access
- result = self.rfc2136_client._query_soa(DOMAIN)
-
- query_mock.assert_called_with(mock.ANY, SERVER, port=PORT)
- self.assertFalse(result)
-
- @mock.patch("dns.query.udp")
- def test_query_soa_wraps_errors(self, query_mock):
- query_mock.side_effect = Exception
-
- self.assertRaises(
- errors.PluginError,
- # _query_soa | pylint: disable=protected-access
- self.rfc2136_client._query_soa,
- DOMAIN)
-
-
-if __name__ == "__main__":
- unittest.main() # pragma: no cover
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/certbot-dns-rfc2136-0.40.1/certbot_dns_rfc2136.egg-info/PKG-INFO
new/certbot-dns-rfc2136-1.0.0/certbot_dns_rfc2136.egg-info/PKG-INFO
--- old/certbot-dns-rfc2136-0.40.1/certbot_dns_rfc2136.egg-info/PKG-INFO
2019-11-06 03:25:24.000000000 +0100
+++ new/certbot-dns-rfc2136-1.0.0/certbot_dns_rfc2136.egg-info/PKG-INFO
2019-12-03 18:21:15.000000000 +0100
@@ -1,6 +1,6 @@
Metadata-Version: 2.1
Name: certbot-dns-rfc2136
-Version: 0.40.1
+Version: 1.0.0
Summary: RFC 2136 DNS Authenticator plugin for Certbot
Home-page: https://github.com/certbot/certbot
Author: Certbot Project
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/certbot-dns-rfc2136-0.40.1/certbot_dns_rfc2136.egg-info/SOURCES.txt
new/certbot-dns-rfc2136-1.0.0/certbot_dns_rfc2136.egg-info/SOURCES.txt
--- old/certbot-dns-rfc2136-0.40.1/certbot_dns_rfc2136.egg-info/SOURCES.txt
2019-11-06 03:25:24.000000000 +0100
+++ new/certbot-dns-rfc2136-1.0.0/certbot_dns_rfc2136.egg-info/SOURCES.txt
2019-12-03 18:21:15.000000000 +0100
@@ -4,18 +4,18 @@
setup.cfg
setup.py
certbot_dns_rfc2136/__init__.py
-certbot_dns_rfc2136/dns_rfc2136.py
-certbot_dns_rfc2136/dns_rfc2136_test.py
certbot_dns_rfc2136.egg-info/PKG-INFO
certbot_dns_rfc2136.egg-info/SOURCES.txt
certbot_dns_rfc2136.egg-info/dependency_links.txt
certbot_dns_rfc2136.egg-info/entry_points.txt
certbot_dns_rfc2136.egg-info/requires.txt
certbot_dns_rfc2136.egg-info/top_level.txt
+certbot_dns_rfc2136/_internal/__init__.py
+certbot_dns_rfc2136/_internal/dns_rfc2136.py
docs/.gitignore
docs/Makefile
docs/api.rst
docs/conf.py
docs/index.rst
docs/make.bat
-docs/api/dns_rfc2136.rst
\ No newline at end of file
+tests/dns_rfc2136_test.py
\ No newline at end of file
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/certbot-dns-rfc2136-0.40.1/certbot_dns_rfc2136.egg-info/entry_points.txt
new/certbot-dns-rfc2136-1.0.0/certbot_dns_rfc2136.egg-info/entry_points.txt
---
old/certbot-dns-rfc2136-0.40.1/certbot_dns_rfc2136.egg-info/entry_points.txt
2019-11-06 03:25:24.000000000 +0100
+++ new/certbot-dns-rfc2136-1.0.0/certbot_dns_rfc2136.egg-info/entry_points.txt
2019-12-03 18:21:15.000000000 +0100
@@ -1,3 +1,3 @@
[certbot.plugins]
-dns-rfc2136 = certbot_dns_rfc2136.dns_rfc2136:Authenticator
+dns-rfc2136 = certbot_dns_rfc2136._internal.dns_rfc2136:Authenticator
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/certbot-dns-rfc2136-0.40.1/docs/api/dns_rfc2136.rst
new/certbot-dns-rfc2136-1.0.0/docs/api/dns_rfc2136.rst
--- old/certbot-dns-rfc2136-0.40.1/docs/api/dns_rfc2136.rst 2019-11-06
03:24:51.000000000 +0100
+++ new/certbot-dns-rfc2136-1.0.0/docs/api/dns_rfc2136.rst 1970-01-01
01:00:00.000000000 +0100
@@ -1,5 +0,0 @@
-:mod:`certbot_dns_rfc2136.dns_rfc2136`
---------------------------------------
-
-.. automodule:: certbot_dns_rfc2136.dns_rfc2136
- :members:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/certbot-dns-rfc2136-0.40.1/docs/api.rst
new/certbot-dns-rfc2136-1.0.0/docs/api.rst
--- old/certbot-dns-rfc2136-0.40.1/docs/api.rst 2019-11-06 03:24:51.000000000
+0100
+++ new/certbot-dns-rfc2136-1.0.0/docs/api.rst 2019-12-03 18:20:30.000000000
+0100
@@ -2,7 +2,4 @@
API Documentation
=================
-.. toctree::
- :glob:
-
- api/**
+Certbot plugins implement the Certbot plugins API, and do not otherwise have
an external API.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/certbot-dns-rfc2136-0.40.1/setup.py
new/certbot-dns-rfc2136-1.0.0/setup.py
--- old/certbot-dns-rfc2136-0.40.1/setup.py 2019-11-06 03:24:52.000000000
+0100
+++ new/certbot-dns-rfc2136-1.0.0/setup.py 2019-12-03 18:20:32.000000000
+0100
@@ -1,8 +1,10 @@
from setuptools import setup
from setuptools import find_packages
+from setuptools.command.test import test as TestCommand
+import sys
-version = '0.40.1'
+version = '1.0.0'
# Remember to update local-oldest-requirements.txt when changing the minimum
# acme/certbot version.
@@ -20,6 +22,20 @@
'sphinx_rtd_theme',
]
+class PyTest(TestCommand):
+ user_options = []
+
+ def initialize_options(self):
+ TestCommand.initialize_options(self)
+ self.pytest_args = ''
+
+ def run_tests(self):
+ import shlex
+ # import here, cause outside the eggs aren't loaded
+ import pytest
+ errno = pytest.main(shlex.split(self.pytest_args))
+ sys.exit(errno)
+
setup(
name='certbot-dns-rfc2136',
version=version,
@@ -60,8 +76,10 @@
},
entry_points={
'certbot.plugins': [
- 'dns-rfc2136 = certbot_dns_rfc2136.dns_rfc2136:Authenticator',
+ 'dns-rfc2136 =
certbot_dns_rfc2136._internal.dns_rfc2136:Authenticator',
],
},
+ tests_require=["pytest"],
test_suite='certbot_dns_rfc2136',
+ cmdclass={"test": PyTest},
)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/certbot-dns-rfc2136-0.40.1/tests/dns_rfc2136_test.py
new/certbot-dns-rfc2136-1.0.0/tests/dns_rfc2136_test.py
--- old/certbot-dns-rfc2136-0.40.1/tests/dns_rfc2136_test.py 1970-01-01
01:00:00.000000000 +0100
+++ new/certbot-dns-rfc2136-1.0.0/tests/dns_rfc2136_test.py 2019-12-03
18:20:30.000000000 +0100
@@ -0,0 +1,212 @@
+"""Tests for certbot_dns_rfc2136._internal.dns_rfc2136."""
+
+import unittest
+
+import dns.flags
+import dns.rcode
+import dns.tsig
+import mock
+
+from certbot import errors
+from certbot.compat import os
+from certbot.plugins import dns_test_common
+from certbot.plugins.dns_test_common import DOMAIN
+from certbot.tests import util as test_util
+
+SERVER = '192.0.2.1'
+PORT = 53
+NAME = 'a-tsig-key.'
+SECRET = 'SSB3b25kZXIgd2hvIHdpbGwgYm90aGVyIHRvIGRlY29kZSB0aGlzIHRleHQK'
+VALID_CONFIG = {"rfc2136_server": SERVER, "rfc2136_name": NAME,
"rfc2136_secret": SECRET}
+
+
+class AuthenticatorTest(test_util.TempDirTestCase,
dns_test_common.BaseAuthenticatorTest):
+
+ def setUp(self):
+ from certbot_dns_rfc2136._internal.dns_rfc2136 import Authenticator
+
+ super(AuthenticatorTest, self).setUp()
+
+ path = os.path.join(self.tempdir, 'file.ini')
+ dns_test_common.write(VALID_CONFIG, path)
+
+ self.config = mock.MagicMock(rfc2136_credentials=path,
+ rfc2136_propagation_seconds=0) # don't
wait during tests
+
+ self.auth = Authenticator(self.config, "rfc2136")
+
+ self.mock_client = mock.MagicMock()
+ # _get_rfc2136_client | pylint: disable=protected-access
+ self.auth._get_rfc2136_client =
mock.MagicMock(return_value=self.mock_client)
+
+ def test_perform(self):
+ self.auth.perform([self.achall])
+
+ expected = [mock.call.add_txt_record('_acme-challenge.'+DOMAIN,
mock.ANY, mock.ANY)]
+ self.assertEqual(expected, self.mock_client.mock_calls)
+
+ def test_cleanup(self):
+ # _attempt_cleanup | pylint: disable=protected-access
+ self.auth._attempt_cleanup = True
+ self.auth.cleanup([self.achall])
+
+ expected = [mock.call.del_txt_record('_acme-challenge.'+DOMAIN,
mock.ANY)]
+ self.assertEqual(expected, self.mock_client.mock_calls)
+
+ def test_invalid_algorithm_raises(self):
+ config = VALID_CONFIG.copy()
+ config["rfc2136_algorithm"] = "INVALID"
+ dns_test_common.write(config, self.config.rfc2136_credentials)
+
+ self.assertRaises(errors.PluginError,
+ self.auth.perform,
+ [self.achall])
+
+ def test_valid_algorithm_passes(self):
+ config = VALID_CONFIG.copy()
+ config["rfc2136_algorithm"] = "HMAC-sha512"
+ dns_test_common.write(config, self.config.rfc2136_credentials)
+
+ self.auth.perform([self.achall])
+
+
+class RFC2136ClientTest(unittest.TestCase):
+
+ def setUp(self):
+ from certbot_dns_rfc2136._internal.dns_rfc2136 import _RFC2136Client
+
+ self.rfc2136_client = _RFC2136Client(SERVER, PORT, NAME, SECRET,
dns.tsig.HMAC_MD5)
+
+ @mock.patch("dns.query.tcp")
+ def test_add_txt_record(self, query_mock):
+ query_mock.return_value.rcode.return_value = dns.rcode.NOERROR
+ # _find_domain | pylint: disable=protected-access
+ self.rfc2136_client._find_domain =
mock.MagicMock(return_value="example.com")
+
+ self.rfc2136_client.add_txt_record("bar", "baz", 42)
+
+ query_mock.assert_called_with(mock.ANY, SERVER, port=PORT)
+ self.assertTrue("bar. 42 IN TXT \"baz\"" in
str(query_mock.call_args[0][0]))
+
+ @mock.patch("dns.query.tcp")
+ def test_add_txt_record_wraps_errors(self, query_mock):
+ query_mock.side_effect = Exception
+ # _find_domain | pylint: disable=protected-access
+ self.rfc2136_client._find_domain =
mock.MagicMock(return_value="example.com")
+
+ self.assertRaises(
+ errors.PluginError,
+ self.rfc2136_client.add_txt_record,
+ "bar", "baz", 42)
+
+ @mock.patch("dns.query.tcp")
+ def test_add_txt_record_server_error(self, query_mock):
+ query_mock.return_value.rcode.return_value = dns.rcode.NXDOMAIN
+ # _find_domain | pylint: disable=protected-access
+ self.rfc2136_client._find_domain =
mock.MagicMock(return_value="example.com")
+
+ self.assertRaises(
+ errors.PluginError,
+ self.rfc2136_client.add_txt_record,
+ "bar", "baz", 42)
+
+ @mock.patch("dns.query.tcp")
+ def test_del_txt_record(self, query_mock):
+ query_mock.return_value.rcode.return_value = dns.rcode.NOERROR
+ # _find_domain | pylint: disable=protected-access
+ self.rfc2136_client._find_domain =
mock.MagicMock(return_value="example.com")
+
+ self.rfc2136_client.del_txt_record("bar", "baz")
+
+ query_mock.assert_called_with(mock.ANY, SERVER, port=PORT)
+ self.assertTrue("bar. 0 NONE TXT \"baz\"" in
str(query_mock.call_args[0][0]))
+
+ @mock.patch("dns.query.tcp")
+ def test_del_txt_record_wraps_errors(self, query_mock):
+ query_mock.side_effect = Exception
+ # _find_domain | pylint: disable=protected-access
+ self.rfc2136_client._find_domain =
mock.MagicMock(return_value="example.com")
+
+ self.assertRaises(
+ errors.PluginError,
+ self.rfc2136_client.del_txt_record,
+ "bar", "baz")
+
+ @mock.patch("dns.query.tcp")
+ def test_del_txt_record_server_error(self, query_mock):
+ query_mock.return_value.rcode.return_value = dns.rcode.NXDOMAIN
+ # _find_domain | pylint: disable=protected-access
+ self.rfc2136_client._find_domain =
mock.MagicMock(return_value="example.com")
+
+ self.assertRaises(
+ errors.PluginError,
+ self.rfc2136_client.del_txt_record,
+ "bar", "baz")
+
+ def test_find_domain(self):
+ # _query_soa | pylint: disable=protected-access
+ self.rfc2136_client._query_soa = mock.MagicMock(side_effect=[False,
False, True])
+
+ # _find_domain | pylint: disable=protected-access
+ domain = self.rfc2136_client._find_domain('foo.bar.'+DOMAIN)
+
+ self.assertTrue(domain == DOMAIN)
+
+ def test_find_domain_wraps_errors(self):
+ # _query_soa | pylint: disable=protected-access
+ self.rfc2136_client._query_soa = mock.MagicMock(return_value=False)
+
+ self.assertRaises(
+ errors.PluginError,
+ # _find_domain | pylint: disable=protected-access
+ self.rfc2136_client._find_domain,
+ 'foo.bar.'+DOMAIN)
+
+ @mock.patch("dns.query.tcp")
+ def test_query_soa_found(self, query_mock):
+ query_mock.return_value = mock.MagicMock(answer=[mock.MagicMock()],
flags=dns.flags.AA)
+ query_mock.return_value.rcode.return_value = dns.rcode.NOERROR
+
+ # _query_soa | pylint: disable=protected-access
+ result = self.rfc2136_client._query_soa(DOMAIN)
+
+ query_mock.assert_called_with(mock.ANY, SERVER, port=PORT)
+ self.assertTrue(result)
+
+ @mock.patch("dns.query.tcp")
+ def test_query_soa_not_found(self, query_mock):
+ query_mock.return_value.rcode.return_value = dns.rcode.NXDOMAIN
+
+ # _query_soa | pylint: disable=protected-access
+ result = self.rfc2136_client._query_soa(DOMAIN)
+
+ query_mock.assert_called_with(mock.ANY, SERVER, port=PORT)
+ self.assertFalse(result)
+
+ @mock.patch("dns.query.tcp")
+ def test_query_soa_wraps_errors(self, query_mock):
+ query_mock.side_effect = Exception
+
+ self.assertRaises(
+ errors.PluginError,
+ # _query_soa | pylint: disable=protected-access
+ self.rfc2136_client._query_soa,
+ DOMAIN)
+
+ @mock.patch("dns.query.udp")
+ @mock.patch("dns.query.tcp")
+ def test_query_soa_fallback_to_udp(self, tcp_mock, udp_mock):
+ tcp_mock.side_effect = OSError
+ udp_mock.return_value = mock.MagicMock(answer=[mock.MagicMock()],
flags=dns.flags.AA)
+ udp_mock.return_value.rcode.return_value = dns.rcode.NOERROR
+
+ # _query_soa | pylint: disable=protected-access
+ result = self.rfc2136_client._query_soa(DOMAIN)
+
+ tcp_mock.assert_called_with(mock.ANY, SERVER, port=PORT)
+ udp_mock.assert_called_with(mock.ANY, SERVER, port=PORT)
+ self.assertTrue(result)
+
+
+if __name__ == "__main__":
+ unittest.main() # pragma: no cover