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


Reply via email to