]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Auto-format Python files with black
authorTom Krizek <tkrizek@isc.org>
Wed, 8 Jun 2022 11:34:19 +0000 (13:34 +0200)
committerTom Krizek <tkrizek@isc.org>
Wed, 8 Jun 2022 11:34:19 +0000 (13:34 +0200)
This patch is strictly the result of:
$ black $(git ls-files '*.py' '*.py.in')

There have been no manual changes.

48 files changed:
bin/python/dnssec-checkds.py.in
bin/python/dnssec-coverage.py.in
bin/python/dnssec-keymgr.py.in
bin/python/isc/__init__.py.in
bin/python/isc/checkds.py.in
bin/python/isc/coverage.py.in
bin/python/isc/dnskey.py.in
bin/python/isc/eventlist.py.in
bin/python/isc/keydict.py.in
bin/python/isc/keyevent.py.in
bin/python/isc/keymgr.py.in
bin/python/isc/keyseries.py.in
bin/python/isc/keyzone.py.in
bin/python/isc/policy.py.in
bin/python/isc/rndc.py.in
bin/python/isc/tests/dnskey_test.py.in
bin/python/isc/tests/policy_test.py.in
bin/python/isc/utils.py.in
bin/python/setup.py
bin/tests/system/addzone/tests_rndc_deadlock.py
bin/tests/system/chain/ans4/ans.py
bin/tests/system/checkds/tests-checkds.py
bin/tests/system/conftest.py
bin/tests/system/cookie/ans9/ans.py
bin/tests/system/dnssec/ans10/ans.py
bin/tests/system/dnstap/ydump.py
bin/tests/system/forward/ans11/ans.py
bin/tests/system/inline/tests_signed_zone_files.py
bin/tests/system/keymgr/testpolicy.py
bin/tests/system/pipelined/ans5/ans.py
bin/tests/system/pytest_custom_markers.py
bin/tests/system/qmin/ans2/ans.py
bin/tests/system/qmin/ans3/ans.py
bin/tests/system/qmin/ans4/ans.py
bin/tests/system/shutdown/tests-shutdown.py
bin/tests/system/statschannel/generic.py
bin/tests/system/statschannel/generic_dnspython.py
bin/tests/system/statschannel/tests-json.py
bin/tests/system/statschannel/tests-xml.py
bin/tests/system/tcp/ans6/ans.py
bin/tests/system/tcp/tests-tcp.py
bin/tests/system/timeouts/tests-tcp.py
bin/tests/system/wildcard/tests-wildcard.py
contrib/kasp/kasp2policy.py
dangerfile.py
doc/arm/conf.py
doc/man/conf.py
util/parse_tsan.py

index e01a882b8241e0bcfc71459ab7eadf4602186463..3ec15e2607542693428ac40a815dc85e55ccf331 100644 (file)
@@ -15,12 +15,16 @@ import os
 import sys
 
 sys.path.insert(0, os.path.dirname(sys.argv[0]))
-if os.name != 'nt':
-    if '@PYTHON_INSTALL_DIR@': # value of --with-python-install-dir
-        sys.path.insert(1, '@PYTHON_INSTALL_DIR@')
+if os.name != "nt":
+    if "@PYTHON_INSTALL_DIR@":  # value of --with-python-install-dir
+        sys.path.insert(1, "@PYTHON_INSTALL_DIR@")
     else:
-        sys.path.insert(1, os.path.join('@prefix@', 'lib',
-                        'python' + sys.version[:3], 'site-packages'))
+        sys.path.insert(
+            1,
+            os.path.join(
+                "@prefix@", "lib", "python" + sys.version[:3], "site-packages"
+            ),
+        )
 
 import isc.checkds
 
index 085d06426ef95f74c65914850a62f9382c8eee5c..a82dfe331817b1667432a67052ed4a1774d2038d 100644 (file)
@@ -15,12 +15,16 @@ import os
 import sys
 
 sys.path.insert(0, os.path.dirname(sys.argv[0]))
-if os.name != 'nt':
-    if '@PYTHON_INSTALL_DIR@': # value of --with-python-install-dir
-        sys.path.insert(1, '@PYTHON_INSTALL_DIR@')
+if os.name != "nt":
+    if "@PYTHON_INSTALL_DIR@":  # value of --with-python-install-dir
+        sys.path.insert(1, "@PYTHON_INSTALL_DIR@")
     else:
-        sys.path.insert(1, os.path.join('@prefix@', 'lib',
-                        'python' + sys.version[:3], 'site-packages'))
+        sys.path.insert(
+            1,
+            os.path.join(
+                "@prefix@", "lib", "python" + sys.version[:3], "site-packages"
+            ),
+        )
 
 import isc.coverage
 
index 410acbfa610ae2ebaee0a9d0a4ece8e02069bade..f8ee013acf160b2902b3761d4c105c6095af5e97 100644 (file)
@@ -15,12 +15,16 @@ import os
 import sys
 
 sys.path.insert(0, os.path.dirname(sys.argv[0]))
-if os.name != 'nt':
-    if '@PYTHON_INSTALL_DIR@': # value of --with-python-install-dir
-        sys.path.insert(1, '@PYTHON_INSTALL_DIR@')
+if os.name != "nt":
+    if "@PYTHON_INSTALL_DIR@":  # value of --with-python-install-dir
+        sys.path.insert(1, "@PYTHON_INSTALL_DIR@")
     else:
-        sys.path.insert(1, os.path.join('@prefix@', 'lib',
-                        'python' + sys.version[:3], 'site-packages'))
+        sys.path.insert(
+            1,
+            os.path.join(
+                "@prefix@", "lib", "python" + sys.version[:3], "site-packages"
+            ),
+        )
 
 import isc.keymgr
 
index c6d13a1df39408b88f88b323f49706ed2123499e..405c3d7cf7346fbd913c6cdf1502783e3e5151dc 100644 (file)
 # See the COPYRIGHT file distributed with this work for additional
 # information regarding copyright ownership.
 
-__all__ = ['checkds', 'coverage', 'keymgr', 'dnskey', 'eventlist',
-           'keydict', 'keyevent', 'keyseries', 'keyzone', 'policy',
-           'parsetab', 'rndc', 'utils']
+__all__ = [
+    "checkds",
+    "coverage",
+    "keymgr",
+    "dnskey",
+    "eventlist",
+    "keydict",
+    "keyevent",
+    "keyseries",
+    "keyzone",
+    "policy",
+    "parsetab",
+    "rndc",
+    "utils",
+]
 
 from isc.dnskey import *
 from isc.eventlist import *
index 7ea4b892d96f1edbf091b233e9728dfe1c85a69b..f2e6562567362051f33174cfac6ccdf259e2afe8 100644 (file)
@@ -14,9 +14,9 @@ import os
 import sys
 from subprocess import Popen, PIPE
 
-from isc.utils import prefix,version
+from isc.utils import prefix, version
 
-prog = 'dnssec-checkds'
+prog = "dnssec-checkds"
 
 
 ############################################################################
@@ -24,13 +24,13 @@ prog = 'dnssec-checkds'
 # Class for DS resource record
 ############################################################################
 class SECRR:
-    hashalgs = {1: 'SHA-1', 2: 'SHA-256', 3: 'GOST', 4: 'SHA-384'}
-    rrname = ''
-    rrclass = 'IN'
+    hashalgs = {1: "SHA-1", 2: "SHA-256", 3: "GOST", 4: "SHA-384"}
+    rrname = ""
+    rrclass = "IN"
     keyid = None
     keyalg = None
     hashalg = None
-    digest = ''
+    digest = ""
     ttl = 0
 
     def __init__(self, rrtext):
@@ -39,7 +39,7 @@ class SECRR:
 
         # 'str' does not have decode method in python3
         if type(rrtext) is not str:
-            fields = rrtext.decode('ascii').split()
+            fields = rrtext.decode("ascii").split()
         else:
             fields = rrtext.split()
         if len(fields) < 7:
@@ -49,7 +49,7 @@ class SECRR:
         self.rrname = fields[0].lower()
 
         fields = fields[1:]
-        if fields[0].upper() in ['IN', 'CH', 'HS']:
+        if fields[0].upper() in ["IN", "CH", "HS"]:
             self.rrclass = fields[0].upper()
             fields = fields[1:]
         else:
@@ -58,16 +58,21 @@ class SECRR:
             fields = fields[2:]
 
         if fields[0].upper() != self.rrtype:
-            raise Exception('%s does not match %s' %
-                            (fields[0].upper(), self.rrtype))
+            raise Exception("%s does not match %s" % (fields[0].upper(), self.rrtype))
 
         self.keyid, self.keyalg, self.hashalg = map(int, fields[1:4])
-        self.digest = ''.join(fields[4:]).upper()
+        self.digest = "".join(fields[4:]).upper()
 
     def __repr__(self):
-        return '%s %s %s %d %d %d %s' % \
-               (self.rrname, self.rrclass, self.rrtype,
-                self.keyid, self.keyalg, self.hashalg, self.digest)
+        return "%s %s %s %d %d %d %s" % (
+            self.rrname,
+            self.rrclass,
+            self.rrtype,
+            self.keyid,
+            self.keyalg,
+            self.hashalg,
+            self.digest,
+        )
 
     def __eq__(self, other):
         return self.__repr__() == other.__repr__()
@@ -90,7 +95,7 @@ def check(zone, args):
 
     for line in fp.splitlines():
         if type(line) is not str:
-            line = line.decode('ascii')
+            line = line.decode("ascii")
         rrlist.append(SECRR(line))
     rrlist = sorted(rrlist, key=lambda rr: (rr.keyid, rr.keyalg, rr.hashalg))
 
@@ -98,20 +103,21 @@ def check(zone, args):
 
     cmd = [args.dsfromkey]
     for algo in args.algo:
-        cmd += ['-a', algo]
+        cmd += ["-a", algo]
 
     if args.masterfile:
         cmd += ["-f", args.masterfile, zone]
         fp, _ = Popen(cmd, stdout=PIPE).communicate()
     else:
-        intods, _ = Popen([args.dig, "+noall", "+answer", "-t", "dnskey",
-                           "-q", zone], stdout=PIPE).communicate()
+        intods, _ = Popen(
+            [args.dig, "+noall", "+answer", "-t", "dnskey", "-q", zone], stdout=PIPE
+        ).communicate()
         cmd += ["-f", "-", zone]
         fp, _ = Popen(cmd, stdin=PIPE, stdout=PIPE).communicate(intods)
 
     for line in fp.splitlines():
         if type(line) is not str:
-            line = line.decode('ascii')
+            line = line.decode("ascii")
         klist.append(SECRR(line))
 
     if len(klist) < 1:
@@ -121,21 +127,42 @@ def check(zone, args):
     match = True
     for rr in rrlist:
         if rr not in klist:
-            print("KSK for %s %s/%03d/%05d (%s) missing from child" %
-                  (rr.rrtype, rr.rrname.strip('.'), rr.keyalg,
-                   rr.keyid, SECRR.hashalgs[rr.hashalg]))
+            print(
+                "KSK for %s %s/%03d/%05d (%s) missing from child"
+                % (
+                    rr.rrtype,
+                    rr.rrname.strip("."),
+                    rr.keyalg,
+                    rr.keyid,
+                    SECRR.hashalgs[rr.hashalg],
+                )
+            )
             match = False
     for rr in klist:
         if rr not in rrlist:
-            print("%s for KSK %s/%03d/%05d (%s) missing from parent" %
-                  (rr.rrtype, rr.rrname.strip('.'), rr.keyalg,
-                   rr.keyid, SECRR.hashalgs[rr.hashalg]))
+            print(
+                "%s for KSK %s/%03d/%05d (%s) missing from parent"
+                % (
+                    rr.rrtype,
+                    rr.rrname.strip("."),
+                    rr.keyalg,
+                    rr.keyid,
+                    SECRR.hashalgs[rr.hashalg],
+                )
+            )
             match = False
     for rr in klist:
         if rr in rrlist:
-            print("%s for KSK %s/%03d/%05d (%s) found in parent" %
-                  (rr.rrtype, rr.rrname.strip('.'), rr.keyalg,
-                   rr.keyid, SECRR.hashalgs[rr.hashalg]))
+            print(
+                "%s for KSK %s/%03d/%05d (%s) found in parent"
+                % (
+                    rr.rrtype,
+                    rr.rrname.strip("."),
+                    rr.keyalg,
+                    rr.keyid,
+                    SECRR.hashalgs[rr.hashalg],
+                )
+            )
 
     return match
 
@@ -145,30 +172,47 @@ def check(zone, args):
 # Read command line arguments, set global 'args' structure
 ############################################################################
 def parse_args():
-    parser = argparse.ArgumentParser(description=prog + ': checks DS coverage')
-
-    bindir = 'bin'
-    sbindir = 'bin' if os.name == 'nt' else 'sbin'
-
-    parser.add_argument('zone', type=str, help='zone to check')
-    parser.add_argument('-a', '--algo', dest='algo', action='append',
-                        default=[], type=str, help='DS digest algorithm')
-    parser.add_argument('-d', '--dig', dest='dig',
-                        default=os.path.join(prefix(bindir), 'dig'),
-                        type=str, help='path to \'dig\'')
-    parser.add_argument('-D', '--dsfromkey', dest='dsfromkey',
-                        default=os.path.join(prefix(sbindir),
-                                             'dnssec-dsfromkey'),
-                        type=str, help='path to \'dnssec-dsfromkey\'')
-    parser.add_argument('-f', '--file', dest='masterfile', type=str,
-                        help='zone master file')
-    parser.add_argument('-s', '--dsset', dest='dssetfile', type=str,
-                        help='prepared DSset file')
-    parser.add_argument('-v', '--version', action='version',
-                        version=version)
+    parser = argparse.ArgumentParser(description=prog + ": checks DS coverage")
+
+    bindir = "bin"
+    sbindir = "bin" if os.name == "nt" else "sbin"
+
+    parser.add_argument("zone", type=str, help="zone to check")
+    parser.add_argument(
+        "-a",
+        "--algo",
+        dest="algo",
+        action="append",
+        default=[],
+        type=str,
+        help="DS digest algorithm",
+    )
+    parser.add_argument(
+        "-d",
+        "--dig",
+        dest="dig",
+        default=os.path.join(prefix(bindir), "dig"),
+        type=str,
+        help="path to 'dig'",
+    )
+    parser.add_argument(
+        "-D",
+        "--dsfromkey",
+        dest="dsfromkey",
+        default=os.path.join(prefix(sbindir), "dnssec-dsfromkey"),
+        type=str,
+        help="path to 'dnssec-dsfromkey'",
+    )
+    parser.add_argument(
+        "-f", "--file", dest="masterfile", type=str, help="zone master file"
+    )
+    parser.add_argument(
+        "-s", "--dsset", dest="dssetfile", type=str, help="prepared DSset file"
+    )
+    parser.add_argument("-v", "--version", action="version", version=version)
     args = parser.parse_args()
 
-    args.zone = args.zone.strip('.')
+    args.zone = args.zone.strip(".")
 
     return args
 
index 21c493ca6b72542deb099b9a12a92e6780fb0cc9..1b2839614f672919c2aa46fa6f52a3c5ad805fe9 100644 (file)
@@ -20,7 +20,7 @@ import calendar
 import pprint
 from collections import defaultdict
 
-prog = 'dnssec-coverage'
+prog = "dnssec-coverage"
 
 from isc import dnskey, eventlist, keydict, keyevent, keyzone, utils
 
@@ -36,19 +36,21 @@ def fatal(*args, **kwargs):
 # output:
 ############################################################################
 _firstline = True
+
+
 def output(*args, **kwargs):
     """output text, adding a vertical space this is *not* the first
     first section being printed since a call to vreset()"""
     global _firstline
-    if 'skip' in kwargs:
-        skip = kwargs['skip']
-        kwargs.pop('skip', None)
+    if "skip" in kwargs:
+        skip = kwargs["skip"]
+        kwargs.pop("skip", None)
     else:
         skip = True
     if _firstline:
         _firstline = False
     elif skip:
-        print('')
+        print("")
     if args:
         print(*args, **kwargs)
 
@@ -63,7 +65,7 @@ def vreset():
 # parse_time
 ############################################################################
 def parse_time(s):
-    """ convert a formatted time (e.g., 1y, 6mo, 15mi, etc) into seconds
+    """convert a formatted time (e.g., 1y, 6mo, 15mi, etc) into seconds
     :param s: String with some text representing a time interval
     :return: Integer with the number of seconds in the time interval
     """
@@ -76,26 +78,26 @@ def parse_time(s):
         pass
 
     # try to parse as a number with a suffix indicating unit of time
-    r = re.compile(r'([0-9][0-9]*)\s*([A-Za-z]*)')
+    r = re.compile(r"([0-9][0-9]*)\s*([A-Za-z]*)")
     m = r.match(s)
     if not m:
         raise ValueError("Cannot parse %s" % s)
     n, unit = m.groups()
     n = int(n)
     unit = unit.lower()
-    if unit.startswith('y'):
+    if unit.startswith("y"):
         return n * 31536000
-    elif unit.startswith('mo'):
+    elif unit.startswith("mo"):
         return n * 2592000
-    elif unit.startswith('w'):
+    elif unit.startswith("w"):
         return n * 604800
-    elif unit.startswith('d'):
+    elif unit.startswith("d"):
         return n * 86400
-    elif unit.startswith('h'):
+    elif unit.startswith("h"):
         return n * 3600
-    elif unit.startswith('mi'):
+    elif unit.startswith("mi"):
         return n * 60
-    elif unit.startswith('s'):
+    elif unit.startswith("s"):
         return n
     else:
         raise ValueError("Invalid suffix %s" % unit)
@@ -105,7 +107,7 @@ def parse_time(s):
 # set_path:
 ############################################################################
 def set_path(command, default=None):
-    """ find the location of a specified command.  if a default is supplied
+    """find the location of a specified command.  if a default is supplied
     and it works, we use it; otherwise we search PATH for a match.
     :param command: string with a command to look for in the path
     :param default: default location to use
@@ -131,50 +133,89 @@ def set_path(command, default=None):
 ############################################################################
 def parse_args():
     """Read command line arguments, set global 'args' structure"""
-    compilezone = set_path('named-compilezone',
-                           os.path.join(utils.prefix('sbin'),
-                           'named-compilezone'))
-
-    parser = argparse.ArgumentParser(description=prog + ': checks future ' +
-                                     'DNSKEY coverage for a zone')
-
-    parser.add_argument('zone', type=str, nargs='*', default=None,
-                        help='zone(s) to check' +
-                        '(default: all zones in the directory)')
-    parser.add_argument('-K', dest='path', default='.', type=str,
-                        help='a directory containing keys to process',
-                        metavar='dir')
-    parser.add_argument('-f', dest='filename', type=str,
-                        help='zone master file', metavar='file')
-    parser.add_argument('-m', dest='maxttl', type=str,
-                        help='the longest TTL in the zone(s)',
-                        metavar='time')
-    parser.add_argument('-d', dest='keyttl', type=str,
-                        help='the DNSKEY TTL', metavar='time')
-    parser.add_argument('-r', dest='resign', default='1944000',
-                        type=str, help='the RRSIG refresh interval '
-                                       'in seconds [default: 22.5 days]',
-                        metavar='time')
-    parser.add_argument('-c', dest='compilezone',
-                        default=compilezone, type=str,
-                        help='path to \'named-compilezone\'',
-                        metavar='path')
-    parser.add_argument('-l', dest='checklimit',
-                        type=str, default='0',
-                        help='Length of time to check for '
-                             'DNSSEC coverage [default: 0 (unlimited)]',
-                        metavar='time')
-    parser.add_argument('-z', dest='no_ksk',
-                        action='store_true', default=False,
-                        help='Only check zone-signing keys (ZSKs)')
-    parser.add_argument('-k', dest='no_zsk',
-                        action='store_true', default=False,
-                        help='Only check key-signing keys (KSKs)')
-    parser.add_argument('-D', '--debug', dest='debug_mode',
-                        action='store_true', default=False,
-                        help='Turn on debugging output')
-    parser.add_argument('-v', '--version', action='version',
-                        version=utils.version)
+    compilezone = set_path(
+        "named-compilezone", os.path.join(utils.prefix("sbin"), "named-compilezone")
+    )
+
+    parser = argparse.ArgumentParser(
+        description=prog + ": checks future " + "DNSKEY coverage for a zone"
+    )
+
+    parser.add_argument(
+        "zone",
+        type=str,
+        nargs="*",
+        default=None,
+        help="zone(s) to check" + "(default: all zones in the directory)",
+    )
+    parser.add_argument(
+        "-K",
+        dest="path",
+        default=".",
+        type=str,
+        help="a directory containing keys to process",
+        metavar="dir",
+    )
+    parser.add_argument(
+        "-f", dest="filename", type=str, help="zone master file", metavar="file"
+    )
+    parser.add_argument(
+        "-m",
+        dest="maxttl",
+        type=str,
+        help="the longest TTL in the zone(s)",
+        metavar="time",
+    )
+    parser.add_argument(
+        "-d", dest="keyttl", type=str, help="the DNSKEY TTL", metavar="time"
+    )
+    parser.add_argument(
+        "-r",
+        dest="resign",
+        default="1944000",
+        type=str,
+        help="the RRSIG refresh interval " "in seconds [default: 22.5 days]",
+        metavar="time",
+    )
+    parser.add_argument(
+        "-c",
+        dest="compilezone",
+        default=compilezone,
+        type=str,
+        help="path to 'named-compilezone'",
+        metavar="path",
+    )
+    parser.add_argument(
+        "-l",
+        dest="checklimit",
+        type=str,
+        default="0",
+        help="Length of time to check for " "DNSSEC coverage [default: 0 (unlimited)]",
+        metavar="time",
+    )
+    parser.add_argument(
+        "-z",
+        dest="no_ksk",
+        action="store_true",
+        default=False,
+        help="Only check zone-signing keys (ZSKs)",
+    )
+    parser.add_argument(
+        "-k",
+        dest="no_zsk",
+        action="store_true",
+        default=False,
+        help="Only check key-signing keys (KSKs)",
+    )
+    parser.add_argument(
+        "-D",
+        "--debug",
+        dest="debug_mode",
+        action="store_true",
+        default=False,
+        help="Turn on debugging output",
+    )
+    parser.add_argument("-v", "--version", action="version", version=utils.version)
 
     args = parser.parse_args()
 
@@ -189,8 +230,7 @@ def parse_args():
         fatal("ERROR: -f can only be used with one zone.")
 
     # strip trailing dots if any
-    args.zone = [x[:-1] if (len(x) > 1 and x[-1] == '.') else x
-                        for x in args.zone]
+    args.zone = [x[:-1] if (len(x) > 1 and x[-1] == ".") else x for x in args.zone]
 
     # convert from time arguments to seconds
     try:
@@ -239,13 +279,16 @@ def parse_args():
             print("Unable to load zone data from %s: " % args.filename, e)
 
     if not args.maxttl:
-        output("WARNING: Maximum TTL value was not specified.  Using 1 week\n"
-               "\t (604800 seconds); re-run with the -m option to get more\n"
-               "\t accurate results.")
+        output(
+            "WARNING: Maximum TTL value was not specified.  Using 1 week\n"
+            "\t (604800 seconds); re-run with the -m option to get more\n"
+            "\t accurate results."
+        )
         args.maxttl = 604800
 
     return args
 
+
 ############################################################################
 # Main
 ############################################################################
@@ -257,7 +300,7 @@ def main():
     try:
         kd = keydict(path=args.path, zones=args.zone, keyttl=args.keyttl)
     except Exception as e:
-        fatal('ERROR: Unable to build key dictionary: ' + str(e))
+        fatal("ERROR: Unable to build key dictionary: " + str(e))
 
     for key in kd:
         key.check_prepub(output)
@@ -272,7 +315,7 @@ def main():
     try:
         elist = eventlist(kd)
     except Exception as e:
-        fatal('ERROR: Unable to build event list: ' + str(e))
+        fatal("ERROR: Unable to build event list: " + str(e))
 
     errors = False
     if not args.zone:
@@ -281,10 +324,9 @@ def main():
     else:
         for zone in args.zone:
             try:
-                if not elist.coverage(zone, args.keytype,
-                                      args.checklimit, output):
+                if not elist.coverage(zone, args.keytype, args.checklimit, output):
                     errors = True
             except:
-                output('ERROR: Coverage check failed for zone ' + zone)
+                output("ERROR: Coverage check failed for zone " + zone)
 
     sys.exit(1 if errors else 0)
index 605f03ef7c68dc57a11bcb29bf1d0b2e06814ca5..3165a8ba4aea1999fee38be0db6cf2939138d6ce 100644 (file)
@@ -19,48 +19,73 @@ from subprocess import Popen, PIPE
 ########################################################################
 class TimePast(Exception):
     def __init__(self, key, prop, value):
-        super(TimePast, self).__init__('%s time for key %s (%d) is already past'
-                                       % (prop, key, value))
+        super(TimePast, self).__init__(
+            "%s time for key %s (%d) is already past" % (prop, key, value)
+        )
+
 
 class dnskey:
     """An individual DNSSEC key.  Identified by path, name, algorithm, keyid.
     Contains a dictionary of metadata events."""
 
-    _PROPS = ('Created', 'Publish', 'Activate', 'Inactive', 'Delete',
-              'Revoke', 'DSPublish', 'SyncPublish', 'SyncDelete')
-    _OPTS = (None, '-P', '-A', '-I', '-D', '-R', None, '-Psync', '-Dsync')
-
-    _ALGNAMES = (None, 'RSAMD5', 'DH', 'DSA', None, 'RSASHA1',
-                 'NSEC3DSA', 'NSEC3RSASHA1', 'RSASHA256', None,
-                 'RSASHA512', None, 'ECCGOST', 'ECDSAP256SHA256',
-                 'ECDSAP384SHA384', 'ED25519', 'ED448')
+    _PROPS = (
+        "Created",
+        "Publish",
+        "Activate",
+        "Inactive",
+        "Delete",
+        "Revoke",
+        "DSPublish",
+        "SyncPublish",
+        "SyncDelete",
+    )
+    _OPTS = (None, "-P", "-A", "-I", "-D", "-R", None, "-Psync", "-Dsync")
+
+    _ALGNAMES = (
+        None,
+        "RSAMD5",
+        "DH",
+        "DSA",
+        None,
+        "RSASHA1",
+        "NSEC3DSA",
+        "NSEC3RSASHA1",
+        "RSASHA256",
+        None,
+        "RSASHA512",
+        None,
+        "ECCGOST",
+        "ECDSAP256SHA256",
+        "ECDSAP384SHA384",
+        "ED25519",
+        "ED448",
+    )
 
     def __init__(self, key, directory=None, keyttl=None):
         # this makes it possible to use algname as a class or instance method
         if isinstance(key, tuple) and len(key) == 3:
-            self._dir = directory or '.'
+            self._dir = directory or "."
             (name, alg, keyid) = key
             self.fromtuple(name, alg, keyid, keyttl)
 
-        self._dir = directory or os.path.dirname(key) or '.'
+        self._dir = directory or os.path.dirname(key) or "."
         key = os.path.basename(key)
-        (name, alg, keyid) = key.split('+')
+        (name, alg, keyid) = key.split("+")
         name = name[1:-1]
         alg = int(alg)
-        keyid = int(keyid.split('.')[0])
+        keyid = int(keyid.split(".")[0])
         self.fromtuple(name, alg, keyid, keyttl)
 
     def fromtuple(self, name, alg, keyid, keyttl):
-        if name.endswith('.'):
+        if name.endswith("."):
             fullname = name
-            name = name.rstrip('.')
+            name = name.rstrip(".")
         else:
-            fullname = name + '.'
+            fullname = name + "."
 
         keystr = "K%s+%03d+%05d" % (fullname, alg, keyid)
-        key_file = self._dir + (self._dir and os.sep or '') + keystr + ".key"
-        private_file = (self._dir + (self._dir and os.sep or '') +
-                        keystr + ".private")
+        key_file = self._dir + (self._dir and os.sep or "") + keystr + ".key"
+        private_file = self._dir + (self._dir and os.sep or "") + keystr + ".private"
 
         self.keystr = keystr
 
@@ -71,13 +96,13 @@ class dnskey:
 
         kfp = open(key_file, "r")
         for line in kfp:
-            if line[0] == ';':
+            if line[0] == ";":
                 continue
             tokens = line.split()
             if not tokens:
                 continue
 
-            if tokens[1].lower() in ('in', 'ch', 'hs'):
+            if tokens[1].lower() in ("in", "ch", "hs"):
                 septoken = 3
                 self.ttl = keyttl
             else:
@@ -103,9 +128,9 @@ class dnskey:
 
         for line in pfp:
             line = line.strip()
-            if not line or line[0] in ('!#'):
+            if not line or line[0] in ("!#"):
                 continue
-            punctuation = [line.find(c) for c in ':= '] + [len(line)]
+            punctuation = [line.find(c) for c in ":= "] + [len(line)]
             found = min([pos for pos in punctuation if pos != -1])
             name = line[:found].rstrip()
             value = line[found:].lstrip(":= ").rstrip()
@@ -128,7 +153,7 @@ class dnskey:
         pfp.close()
 
     def commit(self, settime_bin, **kwargs):
-        quiet = kwargs.get('quiet', False)
+        quiet = kwargs.get("quiet", False)
         cmd = []
         first = True
 
@@ -143,31 +168,48 @@ class dnskey:
             if prop in self._delete and self._delete[prop]:
                 delete = True
 
-            when = 'none' if delete else self._fmttime[prop]
+            when = "none" if delete else self._fmttime[prop]
             cmd += [opt, when]
             first = False
 
         if cmd:
-            fullcmd = [settime_bin, "-K", self._dir] + cmd + [self.keystr,]
+            fullcmd = (
+                [settime_bin, "-K", self._dir]
+                + cmd
+                + [
+                    self.keystr,
+                ]
+            )
             if not quiet:
-                print('# ' + ' '.join(fullcmd))
+                print("# " + " ".join(fullcmd))
             try:
                 p = Popen(fullcmd, stdout=PIPE, stderr=PIPE)
                 stdout, stderr = p.communicate()
                 if stderr:
                     raise Exception(str(stderr))
             except Exception as e:
-                raise Exception('unable to run %s: %s' %
-                                (settime_bin, str(e)))
+                raise Exception("unable to run %s: %s" % (settime_bin, str(e)))
             self._origttl = None
             for prop in dnskey._PROPS:
                 self._original[prop] = self._timestamps[prop]
                 self._changed[prop] = False
 
     @classmethod
-    def generate(cls, keygen_bin, randomdev, keys_dir, name, alg, keysize, sep,
-                 ttl, publish=None, activate=None, **kwargs):
-        quiet = kwargs.get('quiet', False)
+    def generate(
+        cls,
+        keygen_bin,
+        randomdev,
+        keys_dir,
+        name,
+        alg,
+        keysize,
+        sep,
+        ttl,
+        publish=None,
+        activate=None,
+        **kwargs
+    ):
+        quiet = kwargs.get("quiet", False)
 
         keygen_cmd = [keygen_bin, "-q", "-K", keys_dir, "-L", str(ttl)]
 
@@ -194,22 +236,22 @@ class dnskey:
         keygen_cmd.append(name)
 
         if not quiet:
-            print('# ' + ' '.join(keygen_cmd))
+            print("# " + " ".join(keygen_cmd))
 
         p = Popen(keygen_cmd, stdout=PIPE, stderr=PIPE)
         stdout, stderr = p.communicate()
         if stderr:
-            raise Exception('unable to generate key: ' + str(stderr))
+            raise Exception("unable to generate key: " + str(stderr))
 
         try:
-            keystr = stdout.splitlines()[0].decode('ascii')
+            keystr = stdout.splitlines()[0].decode("ascii")
             newkey = dnskey(keystr, keys_dir, ttl)
             return newkey
         except Exception as e:
-            raise Exception('unable to parse generated key: %s' % str(e))
+            raise Exception("unable to parse generated key: %s" % str(e))
 
     def generate_successor(self, keygen_bin, randomdev, prepublish, **kwargs):
-        quiet = kwargs.get('quiet', False)
+        quiet = kwargs.get("quiet", False)
 
         if not self.inactive():
             raise Exception("predecessor key %s has no inactive date" % self)
@@ -226,19 +268,19 @@ class dnskey:
             keygen_cmd += ["-i", str(prepublish)]
 
         if not quiet:
-            print('# ' + ' '.join(keygen_cmd))
+            print("# " + " ".join(keygen_cmd))
 
         p = Popen(keygen_cmd, stdout=PIPE, stderr=PIPE)
         stdout, stderr = p.communicate()
         if stderr:
-            raise Exception('unable to generate key: ' + stderr)
+            raise Exception("unable to generate key: " + stderr)
 
         try:
-            keystr = stdout.splitlines()[0].decode('ascii')
+            keystr = stdout.splitlines()[0].decode("ascii")
             newkey = dnskey(keystr, self._dir, self.ttl)
             return newkey
         except:
-            raise Exception('unable to generate successor for key %s' % self)
+            raise Exception("unable to generate successor for key %s" % self)
 
     @staticmethod
     def algstr(alg):
@@ -277,18 +319,20 @@ class dnskey:
         return time.strftime("%Y%m%d%H%M%S", t)
 
     def setmeta(self, prop, secs, now, **kwargs):
-        force = kwargs.get('force', False)
+        force = kwargs.get("force", False)
 
         if self._timestamps[prop] == secs:
             return
 
-        if self._original[prop] is not None and \
-           self._original[prop] < now and not force:
+        if (
+            self._original[prop] is not None
+            and self._original[prop] < now
+            and not force
+        ):
             raise TimePast(self, prop, self._original[prop])
 
         if secs is None:
-            self._changed[prop] = False \
-                if self._original[prop] is None else True
+            self._changed[prop] = False if self._original[prop] is None else True
 
             self._delete[prop] = True
             self._timestamps[prop] = None
@@ -300,8 +344,9 @@ class dnskey:
         self._timestamps[prop] = secs
         self._times[prop] = t
         self._fmttime[prop] = self.formattime(t)
-        self._changed[prop] = False if \
-            self._original[prop] == self._timestamps[prop] else True
+        self._changed[prop] = (
+            False if self._original[prop] == self._timestamps[prop] else True
+        )
 
     def gettime(self, prop):
         return self._times[prop]
@@ -370,19 +415,21 @@ class dnskey:
             self.ttl = ttl
 
     def keytype(self):
-        return ("KSK" if self.sep else "ZSK")
+        return "KSK" if self.sep else "ZSK"
 
     def __str__(self):
-        return ("%s/%s/%05d"
-                % (self.name, self.algname(), self.keyid))
+        return "%s/%s/%05d" % (self.name, self.algname(), self.keyid)
 
     def __repr__(self):
-        return ("%s/%s/%05d (%s)"
-                % (self.name, self.algname(), self.keyid,
-                   ("KSK" if self.sep else "ZSK")))
+        return "%s/%s/%05d (%s)" % (
+            self.name,
+            self.algname(),
+            self.keyid,
+            ("KSK" if self.sep else "ZSK"),
+        )
 
     def date(self):
-        return (self.activate() or self.publish() or self.created())
+        return self.activate() or self.publish() or self.created()
 
     # keys are sorted first by zone name, then by algorithm. within
     # the same name/algorithm, they are sorted according to their
@@ -396,7 +443,9 @@ class dnskey:
         return self.date() < other.date()
 
     def check_prepub(self, output=None):
-        def noop(*args, **kwargs): pass
+        def noop(*args, **kwargs):
+            pass
+
         if not output:
             output = noop
 
@@ -409,43 +458,47 @@ class dnskey:
 
         if not p:
             if a > now:
-                output("WARNING: Key %s is scheduled for\n"
-                       "\t activation but not for publication."
-                       % repr(self))
+                output(
+                    "WARNING: Key %s is scheduled for\n"
+                    "\t activation but not for publication." % repr(self)
+                )
             return False
 
         if p <= now and a <= now:
             return True
 
         if p == a:
-            output("WARNING: %s is scheduled to be\n"
-                   "\t published and activated at the same time. This\n"
-                   "\t could result in a coverage gap if the zone was\n"
-                   "\t previously signed. Activation should be at least\n"
-                   "\t %s after publication."
-                   % (repr(self),
-                       dnskey.duration(self.ttl) or 'one DNSKEY TTL'))
+            output(
+                "WARNING: %s is scheduled to be\n"
+                "\t published and activated at the same time. This\n"
+                "\t could result in a coverage gap if the zone was\n"
+                "\t previously signed. Activation should be at least\n"
+                "\t %s after publication."
+                % (repr(self), dnskey.duration(self.ttl) or "one DNSKEY TTL")
+            )
             return True
 
         if a < p:
-            output("WARNING: Key %s is active before it is published"
-                   % repr(self))
+            output("WARNING: Key %s is active before it is published" % repr(self))
             return False
 
         if self.ttl is not None and a - p < self.ttl:
-            output("WARNING: Key %s is activated too soon\n"
-                   "\t after publication; this could result in coverage \n"
-                   "\t gaps due to resolver caches containing old data.\n"
-                   "\t Activation should be at least %s after\n"
-                   "\t publication."
-                   % (repr(self),
-                      dnskey.duration(self.ttl) or 'one DNSKEY TTL'))
+            output(
+                "WARNING: Key %s is activated too soon\n"
+                "\t after publication; this could result in coverage \n"
+                "\t gaps due to resolver caches containing old data.\n"
+                "\t Activation should be at least %s after\n"
+                "\t publication."
+                % (repr(self), dnskey.duration(self.ttl) or "one DNSKEY TTL")
+            )
             return False
 
         return True
 
-    def check_postpub(self, output = None, timespan = None):
-        def noop(*args, **kwargs): pass
+    def check_postpub(self, output=None, timespan=None):
+        def noop(*args, **kwargs):
+            pass
+
         if output is None:
             output = noop
 
@@ -454,7 +507,7 @@ class dnskey:
 
         if timespan is None:
             output("WARNING: Key %s using default TTL." % repr(self))
-            timespan = (60*60*24)
+            timespan = 60 * 60 * 24
 
         now = time.time()
         d = self.delete()
@@ -465,26 +518,30 @@ class dnskey:
 
         if not i:
             if d > now:
-                output("WARNING: Key %s is scheduled for\n"
-                       "\t deletion but not for inactivation." % repr(self))
+                output(
+                    "WARNING: Key %s is scheduled for\n"
+                    "\t deletion but not for inactivation." % repr(self)
+                )
             return False
 
         if d < now and i < now:
             return True
 
         if d < i:
-            output("WARNING: Key %s is scheduled for\n"
-                   "\t deletion before inactivation."
-                   % repr(self))
+            output(
+                "WARNING: Key %s is scheduled for\n"
+                "\t deletion before inactivation." % repr(self)
+            )
             return False
 
         if d - i < timespan:
-            output("WARNING: Key %s scheduled for\n"
-                   "\t deletion too soon after deactivation; this may \n"
-                   "\t result in coverage gaps due to resolver caches\n"
-                   "\t containing old data.  Deletion should be at least\n"
-                   "\t %s after inactivation."
-                   % (repr(self), dnskey.duration(timespan)))
+            output(
+                "WARNING: Key %s scheduled for\n"
+                "\t deletion too soon after deactivation; this may \n"
+                "\t result in coverage gaps due to resolver caches\n"
+                "\t containing old data.  Deletion should be at least\n"
+                "\t %s after inactivation." % (repr(self), dnskey.duration(timespan))
+            )
             return False
 
         return True
@@ -494,12 +551,14 @@ class dnskey:
         if not secs:
             return None
 
-        units = [("year", 60*60*24*365),
-                 ("month", 60*60*24*30),
-                 ("day", 60*60*24),
-                 ("hour", 60*60),
-                 ("minute", 60),
-                 ("second", 1)]
+        units = [
+            ("year", 60 * 60 * 24 * 365),
+            ("month", 60 * 60 * 24 * 30),
+            ("day", 60 * 60 * 24),
+            ("hour", 60 * 60),
+            ("minute", 60),
+            ("second", 1),
+        ]
 
         output = []
         for unit in units:
@@ -508,4 +567,3 @@ class dnskey:
                 output.append("%d %s%s" % (v, unit[0], "s" if v > 1 else ""))
 
         return ", ".join(output)
-
index 9b5437fa5af03ed30f0924b41e428d9a9506c777..f2f26aaa5ebb4853bf142a3acd56538989cc5339 100644 (file)
@@ -22,8 +22,14 @@ class eventlist:
     _kdict = None
 
     def __init__(self, kdict):
-        properties = ["SyncPublish", "Publish", "SyncDelete",
-                      "Activate", "Inactive", "Delete"]
+        properties = [
+            "SyncPublish",
+            "Publish",
+            "SyncDelete",
+            "Activate",
+            "Inactive",
+            "Delete",
+        ]
         self._kdict = kdict
         for zone in kdict.zones():
             self._zones.add(zone)
@@ -39,15 +45,19 @@ class eventlist:
                         else:
                             self._Z[zone][alg].append(e)
 
-                self._K[zone][alg] = sorted(self._K[zone][alg],
-                                            key=lambda event: event.when)
-                self._Z[zone][alg] = sorted(self._Z[zone][alg],
-                                            key=lambda event: event.when)
+                self._K[zone][alg] = sorted(
+                    self._K[zone][alg], key=lambda event: event.when
+                )
+                self._Z[zone][alg] = sorted(
+                    self._Z[zone][alg], key=lambda event: event.when
+                )
 
     # scan events per zone, algorithm, and key type, in order of
     # occurrence, noting inconsistent states when found
-    def coverage(self, zone, keytype, until, output = None):
-        def noop(*args, **kwargs): pass
+    def coverage(self, zone, keytype, until, output=None):
+        def noop(*args, **kwargs):
+            pass
+
         if not output:
             output = noop
 
@@ -79,7 +89,7 @@ class eventlist:
             output("ERROR: No key events found")
             return False
 
-        return (kok and zok)
+        return kok and zok
 
     def checkzone(self, zone, keytype, until, output):
         allok = True
@@ -89,9 +99,10 @@ class eventlist:
             kz = self._Z[zone]
 
         for alg in kz.keys():
-            output("Checking scheduled %s events for zone %s, "
-                   "algorithm %s..." %
-                   (keytype, zone, dnskey.algstr(alg)))
+            output(
+                "Checking scheduled %s events for zone %s, "
+                "algorithm %s..." % (keytype, zone, dnskey.algstr(alg))
+            )
             ok = eventlist.checkset(kz[alg], keytype, until, output)
             if ok:
                 output("No errors found")
@@ -119,12 +130,12 @@ class eventlist:
             eventsfound = True
 
             # add event to current group
-            if (not group or group[0].when == event.when):
+            if not group or group[0].when == event.when:
                 group.append(event)
 
             # if we're at the end of the list, we're done.  if
             # we've found an event with a later time, start a new group
-            if (group[0].when != event.when):
+            if group[0].when != event.when:
                 groups.append(group)
                 group = list()
                 group.append(event)
@@ -138,10 +149,11 @@ class eventlist:
 
         active = published = None
         for group in groups:
-            if (until and calendar.timegm(group[0].when) > until):
-                output("Ignoring events after %s" %
-                      time.strftime("%a %b %d %H:%M:%S UTC %Y", 
-                          time.gmtime(until)))
+            if until and calendar.timegm(group[0].when) > until:
+                output(
+                    "Ignoring events after %s"
+                    % time.strftime("%a %b %d %H:%M:%S UTC %Y", time.gmtime(until))
+                )
                 return True
 
             for event in group:
@@ -154,13 +166,13 @@ class eventlist:
                 output("ERROR: No %s's are active after this event" % keytype)
                 return False
             elif not published:
-                output("ERROR: No %s's are published after this event"
-                        % keytype)
+                output("ERROR: No %s's are published after this event" % keytype)
                 return False
             elif not published.intersection(active):
-                output("ERROR: No %s's are both active and published "
-                       "after this event" % keytype)
+                output(
+                    "ERROR: No %s's are both active and published "
+                    "after this event" % keytype
+                )
                 return False
 
         return True
-
index 6486d88e417445c9627998469222d5624893501f..723a32a46290443cd930e03c0fccd91c6fd7dcc9 100644 (file)
@@ -19,47 +19,47 @@ import glob
 # Class keydict
 ########################################################################
 class keydict:
-    """ A dictionary of keys, indexed by name, algorithm, and key id """
+    """A dictionary of keys, indexed by name, algorithm, and key id"""
 
     _keydict = defaultdict(lambda: defaultdict(dict))
     _defttl = None
     _missing = []
 
     def __init__(self, dp=None, **kwargs):
-        self._defttl = kwargs.get('keyttl', None)
-        zones = kwargs.get('zones', None)
+        self._defttl = kwargs.get("keyttl", None)
+        zones = kwargs.get("zones", None)
 
         if not zones:
-            path = kwargs.get('path',None) or '.'
+            path = kwargs.get("path", None) or "."
             self.readall(path)
         else:
             for zone in zones:
-                if 'path' in kwargs and kwargs['path'] is not None:
-                    path = kwargs['path']
+                if "path" in kwargs and kwargs["path"] is not None:
+                    path = kwargs["path"]
                 else:
-                    path = dp and dp.policy(zone).directory or '.'
+                    path = dp and dp.policy(zone).directory or "."
                 if not self.readone(path, zone):
                     self._missing.append(zone)
 
     def readall(self, path):
-        files = glob.glob(os.path.join(path, '*.private'))
+        files = glob.glob(os.path.join(path, "*.private"))
 
         for infile in files:
             key = dnskey(infile, path, self._defttl)
             self._keydict[key.name][key.alg][key.keyid] = key
 
     def readone(self, path, zone):
-        if not zone.endswith('.'):
-            zone += '.'
-        match='K' + zone + '+*.private'
+        if not zone.endswith("."):
+            zone += "."
+        match = "K" + zone + "+*.private"
         files = glob.glob(os.path.join(path, match))
 
         found = False
         for infile in files:
             key = dnskey(infile, path, self._defttl)
-            if key.fullname != zone: # shouldn't ever happen
+            if key.fullname != zone:  # shouldn't ever happen
                 continue
-            keyname=key.name if zone != '.' else '.'
+            keyname = key.name if zone != "." else "."
             self._keydict[keyname][key.alg][key.keyid] = key
             found = True
 
@@ -75,13 +75,13 @@ class keydict:
         return self._keydict[name]
 
     def zones(self):
-        return (self._keydict.keys())
+        return self._keydict.keys()
 
     def algorithms(self, zone):
-        return (self._keydict[zone].keys())
+        return self._keydict[zone].keys()
 
     def keys(self, zone, alg):
-        return (self._keydict[zone][alg].keys())
+        return self._keydict[zone][alg].keys()
 
     def missing(self):
-        return (self._missing)
+        return self._missing
index 8ac9794ba86e9fc7731e837780d0cbafc1f8336a..d01c97aa7fd6c69b9b3f0d02a524ac480708a039 100644 (file)
@@ -16,7 +16,7 @@ import time
 # Class keyevent
 ########################################################################
 class keyevent:
-    """ A discrete key event, e.g., Publish, Activate, Inactive, Delete,
+    """A discrete key event, e.g., Publish, Activate, Inactive, Delete,
     etc. Stores the date of the event, and identifying information
     about the key to which the event will occur."""
 
@@ -30,16 +30,17 @@ class keyevent:
         self.keyid = key.keyid
 
     def __repr__(self):
-        return repr((self.when, self.what, self.keyid, self.sep,
-                     self.zone, self.alg))
+        return repr((self.when, self.what, self.keyid, self.sep, self.zone, self.alg))
 
     def showtime(self):
         return time.strftime("%a %b %d %H:%M:%S UTC %Y", self.when)
 
     # update sets of active and published keys, based on
     # the contents of this keyevent
-    def status(self, active, published, output = None):
-        def noop(*args, **kwargs): pass
+    def status(self, active, published, output=None):
+        def noop(*args, **kwargs):
+            pass
+
         if not output:
             output = noop
 
@@ -54,17 +55,20 @@ class keyevent:
             published.add(self.keyid)
         elif self.what == "Inactive":
             if self.keyid not in active:
-                output("\tWARNING: %s scheduled to become inactive "
-                       "before it is active"
-                       % repr(self.key))
+                output(
+                    "\tWARNING: %s scheduled to become inactive "
+                    "before it is active" % repr(self.key)
+                )
             else:
                 active.remove(self.keyid)
         elif self.what == "Delete":
             if self.keyid in published:
                 published.remove(self.keyid)
             else:
-                output("WARNING: key %s is scheduled for deletion "
-                       "before it is published" % repr(self.key))
+                output(
+                    "WARNING: key %s is scheduled for deletion "
+                    "before it is published" % repr(self.key)
+                )
         elif self.what == "Revoke":
             # We don't need to worry about the logic of this one;
             # just stop counting this key as either active or published
index 0dc6c77b3b6b11246c58c960223ec60cacd5c665..c847b65caa813b395d88e379de9ddad55af443cb 100644 (file)
@@ -13,7 +13,7 @@ from __future__ import print_function
 import os, sys, argparse, glob, re, time, calendar, pprint
 from collections import defaultdict
 
-prog='dnssec-keymgr'
+prog = "dnssec-keymgr"
 
 from isc import dnskey, keydict, keyseries, policy, parsetab, utils
 
@@ -24,11 +24,12 @@ def fatal(*args, **kwargs):
     print(*args, **kwargs)
     sys.exit(1)
 
+
 ############################################################################
 # find the location of an external command
 ############################################################################
 def set_path(command, default=None):
-    """ find the location of a specified command. If a default is supplied,
+    """find the location of a specified command. If a default is supplied,
     exists and it's an executable, we use it; otherwise we search PATH
     for an alternative.
     :param command: command to look for
@@ -48,58 +49,103 @@ def set_path(command, default=None):
 
     return fpath
 
+
 ############################################################################
 # parse arguments
 ############################################################################
 def parse_args():
-    """ Read command line arguments, returns 'args' object
+    """Read command line arguments, returns 'args' object
     :return: args object properly prepared
     """
 
-    keygen = set_path('dnssec-keygen',
-                      os.path.join(utils.prefix('sbin'), 'dnssec-keygen'))
-    settime = set_path('dnssec-settime',
-                       os.path.join(utils.prefix('sbin'), 'dnssec-settime'))
-
-    parser = argparse.ArgumentParser(description=prog + ': schedule '
-                                     'DNSSEC key rollovers according to a '
-                                     'pre-defined policy')
-
-    parser.add_argument('zone', type=str, nargs='*', default=None,
-                        help='Zone(s) to which the policy should be applied ' +
-                        '(default: all zones in the directory)')
-    parser.add_argument('-K', dest='path', type=str,
-                        help='Directory containing keys', metavar='dir')
-    parser.add_argument('-c', dest='policyfile', type=str,
-                        help='Policy definition file', metavar='file')
-    parser.add_argument('-g', dest='keygen', default=keygen, type=str,
-                        help='Path to \'dnssec-keygen\'',
-                        metavar='path')
-    parser.add_argument('-r', dest='randomdev', type=str, default=None,
-                        help='DEPRECATED',
-                        metavar='path')
-    parser.add_argument('-s', dest='settime', default=settime, type=str,
-                        help='Path to \'dnssec-settime\'',
-                        metavar='path')
-    parser.add_argument('-k', dest='no_zsk',
-                        action='store_true', default=False,
-                        help='Only apply policy to key-signing keys (KSKs)')
-    parser.add_argument('-z', dest='no_ksk',
-                        action='store_true', default=False,
-                        help='Only apply policy to zone-signing keys (ZSKs)')
-    parser.add_argument('-f', '--force', dest='force', action='store_true',
-                        default=False, help='Force updates to key events '+
-                        'even if they are in the past')
-    parser.add_argument('-q', '--quiet', dest='quiet', action='store_true',
-                        default=False, help='Update keys silently')
-    parser.add_argument('-v', '--version', action='version',
-                        version=utils.version)
+    keygen = set_path(
+        "dnssec-keygen", os.path.join(utils.prefix("sbin"), "dnssec-keygen")
+    )
+    settime = set_path(
+        "dnssec-settime", os.path.join(utils.prefix("sbin"), "dnssec-settime")
+    )
+
+    parser = argparse.ArgumentParser(
+        description=prog + ": schedule "
+        "DNSSEC key rollovers according to a "
+        "pre-defined policy"
+    )
+
+    parser.add_argument(
+        "zone",
+        type=str,
+        nargs="*",
+        default=None,
+        help="Zone(s) to which the policy should be applied "
+        + "(default: all zones in the directory)",
+    )
+    parser.add_argument(
+        "-K", dest="path", type=str, help="Directory containing keys", metavar="dir"
+    )
+    parser.add_argument(
+        "-c", dest="policyfile", type=str, help="Policy definition file", metavar="file"
+    )
+    parser.add_argument(
+        "-g",
+        dest="keygen",
+        default=keygen,
+        type=str,
+        help="Path to 'dnssec-keygen'",
+        metavar="path",
+    )
+    parser.add_argument(
+        "-r",
+        dest="randomdev",
+        type=str,
+        default=None,
+        help="DEPRECATED",
+        metavar="path",
+    )
+    parser.add_argument(
+        "-s",
+        dest="settime",
+        default=settime,
+        type=str,
+        help="Path to 'dnssec-settime'",
+        metavar="path",
+    )
+    parser.add_argument(
+        "-k",
+        dest="no_zsk",
+        action="store_true",
+        default=False,
+        help="Only apply policy to key-signing keys (KSKs)",
+    )
+    parser.add_argument(
+        "-z",
+        dest="no_ksk",
+        action="store_true",
+        default=False,
+        help="Only apply policy to zone-signing keys (ZSKs)",
+    )
+    parser.add_argument(
+        "-f",
+        "--force",
+        dest="force",
+        action="store_true",
+        default=False,
+        help="Force updates to key events " + "even if they are in the past",
+    )
+    parser.add_argument(
+        "-q",
+        "--quiet",
+        dest="quiet",
+        action="store_true",
+        default=False,
+        help="Update keys silently",
+    )
+    parser.add_argument("-v", "--version", action="version", version=utils.version)
 
     args = parser.parse_args()
 
     if args.randomdev:
         fatal("ERROR: -r option has been deprecated.")
-    
+
     if args.no_zsk and args.no_ksk:
         fatal("ERROR: -z and -k cannot be used together.")
 
@@ -115,13 +161,13 @@ def parse_args():
         if not os.path.exists(args.policyfile):
             fatal('ERROR: Policy file "%s" not found' % args.policyfile)
     else:
-        args.policyfile = os.path.join(utils.sysconfdir,
-                                       'dnssec-policy.conf')
+        args.policyfile = os.path.join(utils.sysconfdir, "dnssec-policy.conf")
         if not os.path.exists(args.policyfile):
             args.policyfile = None
 
     return args
 
+
 ############################################################################
 # main
 ############################################################################
@@ -130,28 +176,31 @@ def main():
 
     # As we may have specific locations for the binaries, we put that info
     # into a context object that can be passed around
-    context = {'keygen_path': args.keygen,
-               'settime_path': args.settime,
-               'keys_path': args.path,
-               'randomdev': args.randomdev}
+    context = {
+        "keygen_path": args.keygen,
+        "settime_path": args.settime,
+        "keys_path": args.path,
+        "randomdev": args.randomdev,
+    }
 
     try:
         dp = policy.dnssec_policy(args.policyfile)
     except Exception as e:
-        fatal('Unable to load DNSSEC policy: ' + str(e))
+        fatal("Unable to load DNSSEC policy: " + str(e))
 
     try:
         kd = keydict(dp, path=args.path, zones=args.zone)
     except Exception as e:
-        fatal('Unable to build key dictionary: ' + str(e))
+        fatal("Unable to build key dictionary: " + str(e))
 
     try:
         ks = keyseries(kd, context=context)
     except Exception as e:
-        fatal('Unable to build key series: ' + str(e))
+        fatal("Unable to build key series: " + str(e))
 
     try:
-        ks.enforce_policy(dp, ksk=args.no_zsk, zsk=args.no_ksk,
-                          force=args.force, quiet=args.quiet)
+        ks.enforce_policy(
+            dp, ksk=args.no_zsk, zsk=args.no_ksk, force=args.force, quiet=args.quiet
+        )
     except Exception as e:
-        fatal('Unable to apply policy: ' + str(e))
+        fatal("Unable to apply policy: " + str(e))
index e051ff9cac8e6698f3b879fb38919b497193dd8b..e75f82b1ec986405cd7e032d5535b7d103a4aeed 100644 (file)
@@ -35,10 +35,10 @@ class keyseries:
                 for k in keys.values():
                     if k.sep:
                         if not (k.delete() and k.delete() < now):
-                          self._K[zone][alg].append(k)
+                            self._K[zone][alg].append(k)
                     else:
                         if not (k.delete() and k.delete() < now):
-                          self._Z[zone][alg].append(k)
+                            self._Z[zone][alg].append(k)
 
                 self._K[zone][alg].sort()
                 self._Z[zone][alg].sort()
@@ -57,7 +57,7 @@ class keyseries:
             print("%s" % repr(k))
 
     def fixseries(self, keys, policy, now, **kwargs):
-        force = kwargs.get('force', False)
+        force = kwargs.get("force", False)
         if not keys:
             return
 
@@ -148,14 +148,16 @@ class keyseries:
             prev = key
 
         # if we haven't got sufficient coverage, create successor key(s)
-        while rp and prev.inactive() and \
-              prev.inactive() < now + policy.coverage:
+        while rp and prev.inactive() and prev.inactive() < now + policy.coverage:
             # commit changes to predecessor: a successor can only be
             # generated if Inactive has been set in the predecessor key
-            prev.commit(self._context['settime_path'], **kwargs)
-            key = prev.generate_successor(self._context['keygen_path'],
-                                          self._context['randomdev'],
-                                          prepub, **kwargs)
+            prev.commit(self._context["settime_path"], **kwargs)
+            key = prev.generate_successor(
+                self._context["keygen_path"],
+                self._context["randomdev"],
+                prepub,
+                **kwargs
+            )
 
             key.setinactive(key.activate() + rp, **kwargs)
             key.setdelete(key.inactive() + postpub, **kwargs)
@@ -171,41 +173,50 @@ class keyseries:
 
         # commit changes
         for key in keys:
-            key.commit(self._context['settime_path'], **kwargs)
-
+            key.commit(self._context["settime_path"], **kwargs)
 
     def enforce_policy(self, policies, now=time.time(), **kwargs):
         # If zones is provided as a parameter, use that list.
         # If not, use what we have in this object
-        zones = kwargs.get('zones', self._zones)
-        keys_dir = kwargs.get('dir', self._context.get('keys_path', None))
-        force = kwargs.get('force', False)
+        zones = kwargs.get("zones", self._zones)
+        keys_dir = kwargs.get("dir", self._context.get("keys_path", None))
+        force = kwargs.get("force", False)
 
         for zone in zones:
             collections = []
             policy = policies.policy(zone)
-            keys_dir = keys_dir or policy.directory or '.'
+            keys_dir = keys_dir or policy.directory or "."
             alg = policy.algorithm
             algnum = dnskey.algnum(alg)
-            if 'ksk' not in kwargs or not kwargs['ksk']:
+            if "ksk" not in kwargs or not kwargs["ksk"]:
                 if len(self._Z[zone][algnum]) == 0:
-                    k = dnskey.generate(self._context['keygen_path'],
-                                        self._context['randomdev'],
-                                        keys_dir, zone, alg,
-                                        policy.zsk_keysize, False,
-                                        policy.keyttl or 3600,
-                                        **kwargs)
+                    k = dnskey.generate(
+                        self._context["keygen_path"],
+                        self._context["randomdev"],
+                        keys_dir,
+                        zone,
+                        alg,
+                        policy.zsk_keysize,
+                        False,
+                        policy.keyttl or 3600,
+                        **kwargs
+                    )
                     self._Z[zone][algnum].append(k)
                 collections.append(self._Z[zone])
 
-            if 'zsk' not in kwargs or not kwargs['zsk']:
+            if "zsk" not in kwargs or not kwargs["zsk"]:
                 if len(self._K[zone][algnum]) == 0:
-                    k = dnskey.generate(self._context['keygen_path'],
-                                        self._context['randomdev'],
-                                        keys_dir, zone, alg,
-                                        policy.ksk_keysize, True,
-                                        policy.keyttl or 3600,
-                                        **kwargs)
+                    k = dnskey.generate(
+                        self._context["keygen_path"],
+                        self._context["randomdev"],
+                        keys_dir,
+                        zone,
+                        alg,
+                        policy.ksk_keysize,
+                        True,
+                        policy.keyttl or 3600,
+                        **kwargs
+                    )
                     self._K[zone][algnum].append(k)
                 collections.append(self._K[zone])
 
@@ -216,5 +227,6 @@ class keyseries:
                     try:
                         self.fixseries(keys, policy, now, **kwargs)
                     except Exception as e:
-                        raise Exception('%s/%s: %s' %
-                                        (zone, dnskey.algstr(algnum), str(e)))
+                        raise Exception(
+                            "%s/%s: %s" % (zone, dnskey.algstr(algnum), str(e))
+                        )
index 0541ee75c330c098469067fadafb12e2604bd5b0..f5f1c3dc2c693729f4223af73cb835b260f237f9 100644 (file)
@@ -20,6 +20,7 @@ from subprocess import Popen, PIPE
 class KeyZoneException(Exception):
     pass
 
+
 ########################################################################
 # class keyzone
 ########################################################################
@@ -33,19 +34,19 @@ class keyzone:
         if not name:
             return
 
-        if not czpath or not os.path.isfile(czpath) \
-                or not os.access(czpath, os.X_OK):
+        if not czpath or not os.path.isfile(czpath) or not os.access(czpath, os.X_OK):
             raise KeyZoneException('"named-compilezone" not found')
             return
 
         maxttl = keyttl = None
 
-        fp, _ = Popen([czpath, "-o", "-", name, filename],
-                      stdout=PIPE, stderr=PIPE).communicate()
+        fp, _ = Popen(
+            [czpath, "-o", "-", name, filename], stdout=PIPE, stderr=PIPE
+        ).communicate()
         for line in fp.splitlines():
             if type(line) is not str:
-                line = line.decode('ascii')
-            if re.search('^[:space:]*;', line):
+                line = line.decode("ascii")
+            if re.search("^[:space:]*;", line):
                 continue
             fields = line.split()
             if not maxttl or int(fields[1]) > maxttl:
index 380af4da5ae0b56ae09a4ca6d07a94f0e527970c..0fa231c7061a860a7872a48786f42a9139d1acd5 100644 (file)
@@ -20,63 +20,71 @@ from copy import copy
 # PolicyLex: a lexer for the policy file syntax.
 ############################################################################
 class PolicyLex:
-    reserved = ('POLICY',
-                'ALGORITHM_POLICY',
-                'ZONE',
-                'ALGORITHM',
-                'DIRECTORY',
-                'KEYTTL',
-                'KEY_SIZE',
-                'ROLL_PERIOD',
-                'PRE_PUBLISH',
-                'POST_PUBLISH',
-                'COVERAGE',
-                'STANDBY',
-                'NONE')
-
-    tokens = reserved + ('DATESUFFIX',
-                         'KEYTYPE',
-                         'ALGNAME',
-                         'STR',
-                         'QSTRING',
-                         'NUMBER',
-                         'LBRACE',
-                         'RBRACE',
-                         'SEMI')
+    reserved = (
+        "POLICY",
+        "ALGORITHM_POLICY",
+        "ZONE",
+        "ALGORITHM",
+        "DIRECTORY",
+        "KEYTTL",
+        "KEY_SIZE",
+        "ROLL_PERIOD",
+        "PRE_PUBLISH",
+        "POST_PUBLISH",
+        "COVERAGE",
+        "STANDBY",
+        "NONE",
+    )
+
+    tokens = reserved + (
+        "DATESUFFIX",
+        "KEYTYPE",
+        "ALGNAME",
+        "STR",
+        "QSTRING",
+        "NUMBER",
+        "LBRACE",
+        "RBRACE",
+        "SEMI",
+    )
     reserved_map = {}
 
-    t_ignore           = ' \t'
-    t_ignore_olcomment = r'(//|\#).*'
+    t_ignore = " \t"
+    t_ignore_olcomment = r"(//|\#).*"
 
-    t_LBRACE           = r'\{'
-    t_RBRACE           = r'\}'
-    t_SEMI             = r';';
+    t_LBRACE = r"\{"
+    t_RBRACE = r"\}"
+    t_SEMI = r";"
 
     def t_newline(self, t):
-        r'\n+'
+        r"\n+"
         t.lexer.lineno += t.value.count("\n")
 
     def t_comment(self, t):
-        r'/\*(.|\n)*?\*/'
-        t.lexer.lineno += t.value.count('\n')
+        r"/\*(.|\n)*?\*/"
+        t.lexer.lineno += t.value.count("\n")
 
     def t_DATESUFFIX(self, t):
-        r'(?<=[0-9 \t])(y(?:ears|ear|ea|e)?|mo(?:nths|nth|nt|n)?|w(?:eeks|eek|ee|e)?|d(?:ays|ay|a)?|h(?:ours|our|ou|o)?|mi(?:nutes|nute|nut|nu|n)?|s(?:econds|econd|econ|eco|ec|e)?)\b'
-        t.value = re.match(r'(y|mo|w|d|h|mi|s)([a-z]*)', t.value, re.IGNORECASE).group(1).lower()
+        r"(?<=[0-9 \t])(y(?:ears|ear|ea|e)?|mo(?:nths|nth|nt|n)?|w(?:eeks|eek|ee|e)?|d(?:ays|ay|a)?|h(?:ours|our|ou|o)?|mi(?:nutes|nute|nut|nu|n)?|s(?:econds|econd|econ|eco|ec|e)?)\b"
+        t.value = (
+            re.match(r"(y|mo|w|d|h|mi|s)([a-z]*)", t.value, re.IGNORECASE)
+            .group(1)
+            .lower()
+        )
         return t
 
     def t_KEYTYPE(self, t):
-        r'\b(KSK|ZSK)\b'
+        r"\b(KSK|ZSK)\b"
         t.value = t.value.upper()
         return t
 
     def t_ALGNAME(self, t):
-        r'\b(DH|ECC|RSASHA1|NSEC3RSASHA1|RSASHA256|RSASHA512|ECDSAP256SHA256|ECDSAP384SHA384|ED25519|ED448)\b'
+        r"\b(DH|ECC|RSASHA1|NSEC3RSASHA1|RSASHA256|RSASHA512|ECDSAP256SHA256|ECDSAP384SHA384|ED25519|ED448)\b"
         t.value = t.value.upper()
         return t
 
     def t_STR(self, t):
-        r'[A-Za-z._-][\w._-]*'
+        r"[A-Za-z._-][\w._-]*"
         t.type = self.reserved_map.get(t.value, "STR")
         return t
 
@@ -87,7 +95,7 @@ class PolicyLex:
         return t
 
     def t_NUMBER(self, t):
-        r'\d+'
+        r"\d+"
         t.value = int(t.value)
         return t
 
@@ -96,13 +104,13 @@ class PolicyLex:
         t.lexer.skip(1)
 
     def __init__(self, **kwargs):
-        if 'maketrans' in dir(str):
-            trans = str.maketrans('_', '-')
+        if "maketrans" in dir(str):
+            trans = str.maketrans("_", "-")
         else:
-            trans = maketrans('_', '-')
+            trans = maketrans("_", "-")
         for r in self.reserved:
             self.reserved_map[r.lower().translate(trans)] = r
-        self.lexer = lex.lex(object=self, reflags=re.VERBOSE|re.IGNORECASE, **kwargs)
+        self.lexer = lex.lex(object=self, reflags=re.VERBOSE | re.IGNORECASE, **kwargs)
 
     def test(self, text):
         self.lexer.input(text)
@@ -112,6 +120,7 @@ class PolicyLex:
                 break
             print(t)
 
+
 ############################################################################
 # Policy: this object holds a set of DNSSEC policy settings.
 ############################################################################
@@ -132,14 +141,16 @@ class Policy:
     keyttl = None
     coverage = None
     directory = None
-    valid_key_sz_per_algo = {'RSASHA1': [1024, 4096],
-                             'NSEC3RSASHA1': [512, 4096],
-                             'RSASHA256': [1024, 4096],
-                             'RSASHA512': [1024, 4096],
-                             'ECDSAP256SHA256': None,
-                             'ECDSAP384SHA384': None,
-                             'ED25519': None,
-                             'ED448': None}
+    valid_key_sz_per_algo = {
+        "RSASHA1": [1024, 4096],
+        "NSEC3RSASHA1": [512, 4096],
+        "RSASHA256": [1024, 4096],
+        "RSASHA512": [1024, 4096],
+        "ECDSAP256SHA256": None,
+        "ECDSAP384SHA384": None,
+        "ED25519": None,
+        "ED448": None,
+    }
 
     def __init__(self, name=None, algorithm=None, parent=None):
         self.name = name
@@ -148,45 +159,54 @@ class Policy:
         pass
 
     def __repr__(self):
-        return ("%spolicy %s:\n"
-                "\tinherits %s\n"
-                "\tdirectory %s\n"
-                "\talgorithm %s\n"
-                "\tcoverage %s\n"
-                "\tksk_keysize %s\n"
-                "\tzsk_keysize %s\n"
-                "\tksk_rollperiod %s\n"
-                "\tzsk_rollperiod %s\n"
-                "\tksk_prepublish %s\n"
-                "\tksk_postpublish %s\n"
-                "\tzsk_prepublish %s\n"
-                "\tzsk_postpublish %s\n"
-                "\tksk_standby %s\n"
-                "\tzsk_standby %s\n"
-                "\tkeyttl %s\n"
-                %
-                ((self.is_constructed and 'constructed ' or \
-                  self.is_zone and 'zone ' or \
-                  self.is_alg and 'algorithm ' or ''),
-                 self.name or 'UNKNOWN',
-                 self.parent and self.parent.name or 'None',
-                 self.directory and ('"' + str(self.directory) + '"') or 'None',
-                 self.algorithm or 'None',
-                 self.coverage and str(self.coverage) or 'None',
-                 self.ksk_keysize and str(self.ksk_keysize) or 'None',
-                 self.zsk_keysize and str(self.zsk_keysize) or 'None',
-                 self.ksk_rollperiod and str(self.ksk_rollperiod) or 'None',
-                 self.zsk_rollperiod and str(self.zsk_rollperiod) or 'None',
-                 self.ksk_prepublish and str(self.ksk_prepublish) or 'None',
-                 self.ksk_postpublish and str(self.ksk_postpublish) or 'None',
-                 self.zsk_prepublish and str(self.zsk_prepublish) or 'None',
-                 self.zsk_postpublish and str(self.zsk_postpublish) or 'None',
-                 self.ksk_standby and str(self.ksk_standby) or 'None',
-                 self.zsk_standby and str(self.zsk_standby) or 'None',
-                 self.keyttl and str(self.keyttl) or 'None'))
+        return (
+            "%spolicy %s:\n"
+            "\tinherits %s\n"
+            "\tdirectory %s\n"
+            "\talgorithm %s\n"
+            "\tcoverage %s\n"
+            "\tksk_keysize %s\n"
+            "\tzsk_keysize %s\n"
+            "\tksk_rollperiod %s\n"
+            "\tzsk_rollperiod %s\n"
+            "\tksk_prepublish %s\n"
+            "\tksk_postpublish %s\n"
+            "\tzsk_prepublish %s\n"
+            "\tzsk_postpublish %s\n"
+            "\tksk_standby %s\n"
+            "\tzsk_standby %s\n"
+            "\tkeyttl %s\n"
+            % (
+                (
+                    self.is_constructed
+                    and "constructed "
+                    or self.is_zone
+                    and "zone "
+                    or self.is_alg
+                    and "algorithm "
+                    or ""
+                ),
+                self.name or "UNKNOWN",
+                self.parent and self.parent.name or "None",
+                self.directory and ('"' + str(self.directory) + '"') or "None",
+                self.algorithm or "None",
+                self.coverage and str(self.coverage) or "None",
+                self.ksk_keysize and str(self.ksk_keysize) or "None",
+                self.zsk_keysize and str(self.zsk_keysize) or "None",
+                self.ksk_rollperiod and str(self.ksk_rollperiod) or "None",
+                self.zsk_rollperiod and str(self.zsk_rollperiod) or "None",
+                self.ksk_prepublish and str(self.ksk_prepublish) or "None",
+                self.ksk_postpublish and str(self.ksk_postpublish) or "None",
+                self.zsk_prepublish and str(self.zsk_prepublish) or "None",
+                self.zsk_postpublish and str(self.zsk_postpublish) or "None",
+                self.ksk_standby and str(self.ksk_standby) or "None",
+                self.zsk_standby and str(self.zsk_standby) or "None",
+                self.keyttl and str(self.keyttl) or "None",
+            )
+        )
 
     def __verify_size(self, key_size, size_range):
-        return (size_range[0] <= key_size <= size_range[1])
+        return size_range[0] <= key_size <= size_range[1]
 
     def get_name(self):
         return self.name
@@ -195,57 +215,95 @@ class Policy:
         return self.is_constructed
 
     def validate(self):
-        """ Check if the values in the policy make sense
+        """Check if the values in the policy make sense
         :return: True/False if the policy passes validation
         """
-        if self.ksk_rollperiod and \
-           self.ksk_prepublish is not None and \
-           self.ksk_prepublish > self.ksk_rollperiod:
+        if (
+            self.ksk_rollperiod
+            and self.ksk_prepublish is not None
+            and self.ksk_prepublish > self.ksk_rollperiod
+        ):
             print(self.ksk_rollperiod)
-            return (False,
-                    ('KSK pre-publish period (%d) exceeds rollover period %d'
-                     % (self.ksk_prepublish, self.ksk_rollperiod)))
-
-        if self.ksk_rollperiod and \
-           self.ksk_postpublish is not None and \
-           self.ksk_postpublish > self.ksk_rollperiod:
-            return (False,
-                    ('KSK post-publish period (%d) exceeds rollover period %d'
-                     % (self.ksk_postpublish, self.ksk_rollperiod)))
-
-        if self.zsk_rollperiod and \
-           self.zsk_prepublish is not None and \
-           self.zsk_prepublish >= self.zsk_rollperiod:
-            return (False,
-                    ('ZSK pre-publish period (%d) exceeds rollover period %d'
-                     % (self.zsk_prepublish, self.zsk_rollperiod)))
-
-        if self.zsk_rollperiod and \
-           self.zsk_postpublish is not None and \
-           self.zsk_postpublish >= self.zsk_rollperiod:
-            return (False,
-                    ('ZSK post-publish period (%d) exceeds rollover period %d'
-                     % (self.zsk_postpublish, self.zsk_rollperiod)))
-
-        if self.ksk_rollperiod and \
-           self.ksk_prepublish and self.ksk_postpublish and \
-           self.ksk_prepublish + self.ksk_postpublish >= self.ksk_rollperiod:
-            return (False,
-                    (('KSK pre/post-publish periods (%d/%d) ' +
-                      'combined exceed rollover period %d') %
-                     (self.ksk_prepublish,
-                      self.ksk_postpublish,
-                      self.ksk_rollperiod)))
-
-        if self.zsk_rollperiod and \
-           self.zsk_prepublish and self.zsk_postpublish and \
-           self.zsk_prepublish + self.zsk_postpublish >= self.zsk_rollperiod:
-            return (False,
-                    (('ZSK pre/post-publish periods (%d/%d) ' +
-                      'combined exceed rollover period %d') %
-                     (self.zsk_prepublish,
-                      self.zsk_postpublish,
-                      self.zsk_rollperiod)))
+            return (
+                False,
+                (
+                    "KSK pre-publish period (%d) exceeds rollover period %d"
+                    % (self.ksk_prepublish, self.ksk_rollperiod)
+                ),
+            )
+
+        if (
+            self.ksk_rollperiod
+            and self.ksk_postpublish is not None
+            and self.ksk_postpublish > self.ksk_rollperiod
+        ):
+            return (
+                False,
+                (
+                    "KSK post-publish period (%d) exceeds rollover period %d"
+                    % (self.ksk_postpublish, self.ksk_rollperiod)
+                ),
+            )
+
+        if (
+            self.zsk_rollperiod
+            and self.zsk_prepublish is not None
+            and self.zsk_prepublish >= self.zsk_rollperiod
+        ):
+            return (
+                False,
+                (
+                    "ZSK pre-publish period (%d) exceeds rollover period %d"
+                    % (self.zsk_prepublish, self.zsk_rollperiod)
+                ),
+            )
+
+        if (
+            self.zsk_rollperiod
+            and self.zsk_postpublish is not None
+            and self.zsk_postpublish >= self.zsk_rollperiod
+        ):
+            return (
+                False,
+                (
+                    "ZSK post-publish period (%d) exceeds rollover period %d"
+                    % (self.zsk_postpublish, self.zsk_rollperiod)
+                ),
+            )
+
+        if (
+            self.ksk_rollperiod
+            and self.ksk_prepublish
+            and self.ksk_postpublish
+            and self.ksk_prepublish + self.ksk_postpublish >= self.ksk_rollperiod
+        ):
+            return (
+                False,
+                (
+                    (
+                        "KSK pre/post-publish periods (%d/%d) "
+                        + "combined exceed rollover period %d"
+                    )
+                    % (self.ksk_prepublish, self.ksk_postpublish, self.ksk_rollperiod)
+                ),
+            )
+
+        if (
+            self.zsk_rollperiod
+            and self.zsk_prepublish
+            and self.zsk_postpublish
+            and self.zsk_prepublish + self.zsk_postpublish >= self.zsk_rollperiod
+        ):
+            return (
+                False,
+                (
+                    (
+                        "ZSK pre/post-publish periods (%d/%d) "
+                        + "combined exceed rollover period %d"
+                    )
+                    % (self.zsk_prepublish, self.zsk_postpublish, self.zsk_rollperiod)
+                ),
+            )
 
         if self.algorithm is not None:
             # Validate the key size
@@ -253,22 +311,29 @@ class Policy:
             if key_sz_range is not None:
                 # Verify KSK
                 if not self.__verify_size(self.ksk_keysize, key_sz_range):
-                    return False, 'KSK key size %d outside valid range %s' \
-                            % (self.ksk_keysize, key_sz_range)
+                    return False, "KSK key size %d outside valid range %s" % (
+                        self.ksk_keysize,
+                        key_sz_range,
+                    )
 
                 # Verify ZSK
                 if not self.__verify_size(self.zsk_keysize, key_sz_range):
-                    return False, 'ZSK key size %d outside valid range %s' \
-                            % (self.zsk_keysize, key_sz_range)
-
-            if self.algorithm in ['ECDSAP256SHA256', \
-                                  'ECDSAP384SHA384', \
-                                  'ED25519', \
-                                  'ED448']:
+                    return False, "ZSK key size %d outside valid range %s" % (
+                        self.zsk_keysize,
+                        key_sz_range,
+                    )
+
+            if self.algorithm in [
+                "ECDSAP256SHA256",
+                "ECDSAP384SHA384",
+                "ED25519",
+                "ED448",
+            ]:
                 self.ksk_keysize = None
                 self.zsk_keysize = None
 
-        return True, ''
+        return True, ""
+
 
 ############################################################################
 # dnssec_policy:
@@ -279,6 +344,7 @@ class Policy:
 class PolicyException(Exception):
     pass
 
+
 class dnssec_policy:
     alg_policy = {}
     named_policy = {}
@@ -290,14 +356,15 @@ class dnssec_policy:
     def __init__(self, filename=None, **kwargs):
         self.plex = PolicyLex()
         self.tokens = self.plex.tokens
-        if 'debug' not in kwargs:
-            kwargs['debug'] = False
-        if 'write_tables' not in kwargs:
-            kwargs['write_tables'] = False
+        if "debug" not in kwargs:
+            kwargs["debug"] = False
+        if "write_tables" not in kwargs:
+            kwargs["write_tables"] = False
         self.parser = yacc.yacc(module=self, **kwargs)
 
         # set defaults
-        self.setup('''policy global { algorithm rsasha256;
+        self.setup(
+            """policy global { algorithm rsasha256;
                                       key-size ksk 2048;
                                       key-size zsk 2048;
                                       roll-period ksk 0;
@@ -310,56 +377,57 @@ class dnssec_policy:
                                       standby zsk 0;
                                       keyttl 1h;
                                       coverage 6mo; };
-                      policy default { policy global; };''')
+                      policy default { policy global; };"""
+        )
 
         p = Policy()
         p.algorithm = None
         p.is_alg = True
-        p.ksk_keysize = 2048;
-        p.zsk_keysize = 2048;
+        p.ksk_keysize = 2048
+        p.zsk_keysize = 2048
 
         # set default algorithm policies
 
         # these can use default settings
-        self.alg_policy['RSASHA1'] = copy(p)
-        self.alg_policy['RSASHA1'].algorithm = "RSASHA1"
-        self.alg_policy['RSASHA1'].name = "RSASHA1"
-
-        self.alg_policy['NSEC3RSASHA1'] = copy(p)
-        self.alg_policy['NSEC3RSASHA1'].algorithm = "NSEC3RSASHA1"
-        self.alg_policy['NSEC3RSASHA1'].name = "NSEC3RSASHA1"
-
-        self.alg_policy['RSASHA256'] = copy(p)
-        self.alg_policy['RSASHA256'].algorithm = "RSASHA256"
-        self.alg_policy['RSASHA256'].name = "RSASHA256"
-
-        self.alg_policy['RSASHA512'] = copy(p)
-        self.alg_policy['RSASHA512'].algorithm = "RSASHA512"
-        self.alg_policy['RSASHA512'].name = "RSASHA512"
-
-        self.alg_policy['ECDSAP256SHA256'] = copy(p)
-        self.alg_policy['ECDSAP256SHA256'].algorithm = "ECDSAP256SHA256"
-        self.alg_policy['ECDSAP256SHA256'].name = "ECDSAP256SHA256"
-        self.alg_policy['ECDSAP256SHA256'].ksk_keysize = None;
-        self.alg_policy['ECDSAP256SHA256'].zsk_keysize = None;
-
-        self.alg_policy['ECDSAP384SHA384'] = copy(p)
-        self.alg_policy['ECDSAP384SHA384'].algorithm = "ECDSAP384SHA384"
-        self.alg_policy['ECDSAP384SHA384'].name = "ECDSAP384SHA384"
-        self.alg_policy['ECDSAP384SHA384'].ksk_keysize = None;
-        self.alg_policy['ECDSAP384SHA384'].zsk_keysize = None;
-
-        self.alg_policy['ED25519'] = copy(p)
-        self.alg_policy['ED25519'].algorithm = "ED25519"
-        self.alg_policy['ED25519'].name = "ED25519"
-        self.alg_policy['ED25519'].ksk_keysize = None;
-        self.alg_policy['ED25519'].zsk_keysize = None;
-
-        self.alg_policy['ED448'] = copy(p)
-        self.alg_policy['ED448'].algorithm = "ED448"
-        self.alg_policy['ED448'].name = "ED448"
-        self.alg_policy['ED448'].ksk_keysize = None;
-        self.alg_policy['ED448'].zsk_keysize = None;
+        self.alg_policy["RSASHA1"] = copy(p)
+        self.alg_policy["RSASHA1"].algorithm = "RSASHA1"
+        self.alg_policy["RSASHA1"].name = "RSASHA1"
+
+        self.alg_policy["NSEC3RSASHA1"] = copy(p)
+        self.alg_policy["NSEC3RSASHA1"].algorithm = "NSEC3RSASHA1"
+        self.alg_policy["NSEC3RSASHA1"].name = "NSEC3RSASHA1"
+
+        self.alg_policy["RSASHA256"] = copy(p)
+        self.alg_policy["RSASHA256"].algorithm = "RSASHA256"
+        self.alg_policy["RSASHA256"].name = "RSASHA256"
+
+        self.alg_policy["RSASHA512"] = copy(p)
+        self.alg_policy["RSASHA512"].algorithm = "RSASHA512"
+        self.alg_policy["RSASHA512"].name = "RSASHA512"
+
+        self.alg_policy["ECDSAP256SHA256"] = copy(p)
+        self.alg_policy["ECDSAP256SHA256"].algorithm = "ECDSAP256SHA256"
+        self.alg_policy["ECDSAP256SHA256"].name = "ECDSAP256SHA256"
+        self.alg_policy["ECDSAP256SHA256"].ksk_keysize = None
+        self.alg_policy["ECDSAP256SHA256"].zsk_keysize = None
+
+        self.alg_policy["ECDSAP384SHA384"] = copy(p)
+        self.alg_policy["ECDSAP384SHA384"].algorithm = "ECDSAP384SHA384"
+        self.alg_policy["ECDSAP384SHA384"].name = "ECDSAP384SHA384"
+        self.alg_policy["ECDSAP384SHA384"].ksk_keysize = None
+        self.alg_policy["ECDSAP384SHA384"].zsk_keysize = None
+
+        self.alg_policy["ED25519"] = copy(p)
+        self.alg_policy["ED25519"].algorithm = "ED25519"
+        self.alg_policy["ED25519"].name = "ED25519"
+        self.alg_policy["ED25519"].ksk_keysize = None
+        self.alg_policy["ED25519"].zsk_keysize = None
+
+        self.alg_policy["ED448"] = copy(p)
+        self.alg_policy["ED448"].algorithm = "ED448"
+        self.alg_policy["ED448"].name = "ED448"
+        self.alg_policy["ED448"].ksk_keysize = None
+        self.alg_policy["ED448"].zsk_keysize = None
 
         if filename:
             self.load(filename)
@@ -387,12 +455,12 @@ class dnssec_policy:
             p = self.zone_policy[z]
 
         if p is None:
-            p = copy(self.named_policy['default'])
+            p = copy(self.named_policy["default"])
             p.name = zone
             p.is_constructed = True
 
         if p.algorithm is None:
-            parent = p.parent or self.named_policy['default']
+            parent = p.parent or self.named_policy["default"]
             while parent and not parent.algorithm:
                 parent = parent.parent
             p.algorithm = parent and parent.algorithm or None
@@ -400,81 +468,75 @@ class dnssec_policy:
         if p.algorithm in self.alg_policy:
             ap = self.alg_policy[p.algorithm]
         else:
-            raise PolicyException('algorithm not found')
+            raise PolicyException("algorithm not found")
 
         if p.directory is None:
-            parent = p.parent or self.named_policy['default']
+            parent = p.parent or self.named_policy["default"]
             while parent is not None and not parent.directory:
                 parent = parent.parent
             p.directory = parent and parent.directory
 
         if p.coverage is None:
-            parent = p.parent or self.named_policy['default']
+            parent = p.parent or self.named_policy["default"]
             while parent and not parent.coverage:
                 parent = parent.parent
             p.coverage = parent and parent.coverage or ap.coverage
 
         if p.ksk_keysize is None:
-            parent = p.parent or self.named_policy['default']
+            parent = p.parent or self.named_policy["default"]
             while parent.parent and not parent.ksk_keysize:
                 parent = parent.parent
             p.ksk_keysize = parent and parent.ksk_keysize or ap.ksk_keysize
 
         if p.zsk_keysize is None:
-            parent = p.parent or self.named_policy['default']
+            parent = p.parent or self.named_policy["default"]
             while parent.parent and not parent.zsk_keysize:
                 parent = parent.parent
             p.zsk_keysize = parent and parent.zsk_keysize or ap.zsk_keysize
 
         if p.ksk_rollperiod is None:
-            parent = p.parent or self.named_policy['default']
+            parent = p.parent or self.named_policy["default"]
             while parent.parent and not parent.ksk_rollperiod:
                 parent = parent.parent
-            p.ksk_rollperiod = parent and \
-                parent.ksk_rollperiod or ap.ksk_rollperiod
+            p.ksk_rollperiod = parent and parent.ksk_rollperiod or ap.ksk_rollperiod
 
         if p.zsk_rollperiod is None:
-            parent = p.parent or self.named_policy['default']
+            parent = p.parent or self.named_policy["default"]
             while parent.parent and not parent.zsk_rollperiod:
                 parent = parent.parent
-            p.zsk_rollperiod = parent and \
-                parent.zsk_rollperiod or ap.zsk_rollperiod
+            p.zsk_rollperiod = parent and parent.zsk_rollperiod or ap.zsk_rollperiod
 
         if p.ksk_prepublish is None:
-            parent = p.parent or self.named_policy['default']
+            parent = p.parent or self.named_policy["default"]
             while parent.parent and not parent.ksk_prepublish:
                 parent = parent.parent
-            p.ksk_prepublish = parent and \
-                parent.ksk_prepublish or ap.ksk_prepublish
+            p.ksk_prepublish = parent and parent.ksk_prepublish or ap.ksk_prepublish
 
         if p.zsk_prepublish is None:
-            parent = p.parent or self.named_policy['default']
+            parent = p.parent or self.named_policy["default"]
             while parent.parent and not parent.zsk_prepublish:
                 parent = parent.parent
-            p.zsk_prepublish = parent and \
-                parent.zsk_prepublish or ap.zsk_prepublish
+            p.zsk_prepublish = parent and parent.zsk_prepublish or ap.zsk_prepublish
 
         if p.ksk_postpublish is None:
-            parent = p.parent or self.named_policy['default']
+            parent = p.parent or self.named_policy["default"]
             while parent.parent and not parent.ksk_postpublish:
                 parent = parent.parent
-            p.ksk_postpublish = parent and \
-                parent.ksk_postpublish or ap.ksk_postpublish
+            p.ksk_postpublish = parent and parent.ksk_postpublish or ap.ksk_postpublish
 
         if p.zsk_postpublish is None:
-            parent = p.parent or self.named_policy['default']
+            parent = p.parent or self.named_policy["default"]
             while parent.parent and not parent.zsk_postpublish:
                 parent = parent.parent
-            p.zsk_postpublish = parent and \
-                parent.zsk_postpublish or ap.zsk_postpublish
+            p.zsk_postpublish = parent and parent.zsk_postpublish or ap.zsk_postpublish
 
         if p.keyttl is None:
-            parent = p.parent or self.named_policy['default']
+            parent = p.parent or self.named_policy["default"]
             while parent is not None and not parent.keyttl:
                 parent = parent.parent
             p.keyttl = parent and parent.keyttl
 
-        if 'novalidate' not in kwargs or not kwargs['novalidate']:
+        if "novalidate" not in kwargs or not kwargs["novalidate"]:
             (valid, msg) = p.validate()
             if not valid:
                 raise PolicyException(msg)
@@ -482,10 +544,9 @@ class dnssec_policy:
 
         return p
 
-
     def p_policylist(self, p):
-        '''policylist : init policy
-                      | policylist policy'''
+        """policylist : init policy
+        | policylist policy"""
         pass
 
     def p_init(self, p):
@@ -493,26 +554,26 @@ class dnssec_policy:
         self.initial = False
 
     def p_policy(self, p):
-        '''policy : alg_policy
-                  | zone_policy
-                  | named_policy'''
+        """policy : alg_policy
+        | zone_policy
+        | named_policy"""
         pass
 
     def p_name(self, p):
-        '''name : STR
-                | KEYTYPE
-                | DATESUFFIX'''
+        """name : STR
+        | KEYTYPE
+        | DATESUFFIX"""
         p[0] = p[1]
         pass
 
     def p_domain(self, p):
-        '''domain : STR
-                  | QSTRING
-                  | KEYTYPE
-                  | DATESUFFIX'''
+        """domain : STR
+        | QSTRING
+        | KEYTYPE
+        | DATESUFFIX"""
         p[0] = p[1].strip()
-        if not re.match(r'^[\w.-][\w.-]*$', p[0]):
-            raise PolicyException('invalid domain')
+        if not re.match(r"^[\w.-][\w.-]*$", p[0]):
+            raise PolicyException("invalid domain")
         pass
 
     def p_new_policy(self, p):
@@ -528,9 +589,9 @@ class dnssec_policy:
 
     def p_zone_policy(self, p):
         "zone_policy : ZONE domain new_policy policy_option_group SEMI"
-        self.current.name = p[2].rstrip('.')
+        self.current.name = p[2].rstrip(".")
         self.current.is_zone = True
-        self.zone_policy[p[2].rstrip('.').lower()] = self.current
+        self.zone_policy[p[2].rstrip(".").lower()] = self.current
         pass
 
     def p_named_policy(self, p):
@@ -552,42 +613,42 @@ class dnssec_policy:
     def p_duration_3(self, p):
         "duration : NUMBER DATESUFFIX"
         if p[2] == "y":
-            p[0] = p[1] * 31536000 # year
+            p[0] = p[1] * 31536000  # year
         elif p[2] == "mo":
             p[0] = p[1] * 2592000  # month
         elif p[2] == "w":
-            p[0] = p[1] * 604800   # week
+            p[0] = p[1] * 604800  # week
         elif p[2] == "d":
-            p[0] = p[1] * 86400    # day
+            p[0] = p[1] * 86400  # day
         elif p[2] == "h":
-            p[0] = p[1] * 3600     # hour
+            p[0] = p[1] * 3600  # hour
         elif p[2] == "mi":
-            p[0] = p[1] * 60       # minute
+            p[0] = p[1] * 60  # minute
         elif p[2] == "s":
-            p[0] = p[1]            # second
+            p[0] = p[1]  # second
         else:
-            raise PolicyException('invalid duration')
+            raise PolicyException("invalid duration")
 
     def p_policy_option_group(self, p):
         "policy_option_group : LBRACE policy_option_list RBRACE"
         pass
 
     def p_policy_option_list(self, p):
-        '''policy_option_list : policy_option SEMI
-                              | policy_option_list policy_option SEMI'''
+        """policy_option_list : policy_option SEMI
+        | policy_option_list policy_option SEMI"""
         pass
 
     def p_policy_option(self, p):
-        '''policy_option : parent_option
-                         | directory_option
-                         | coverage_option
-                         | rollperiod_option
-                         | prepublish_option
-                         | postpublish_option
-                         | keysize_option
-                         | algorithm_option
-                         | keyttl_option
-                         | standby_option'''
+        """policy_option : parent_option
+        | directory_option
+        | coverage_option
+        | rollperiod_option
+        | prepublish_option
+        | postpublish_option
+        | keysize_option
+        | algorithm_option
+        | keyttl_option
+        | standby_option"""
         pass
 
     def p_alg_option_group(self, p):
@@ -595,18 +656,18 @@ class dnssec_policy:
         pass
 
     def p_alg_option_list(self, p):
-        '''alg_option_list : alg_option SEMI
-                           | alg_option_list alg_option SEMI'''
+        """alg_option_list : alg_option SEMI
+        | alg_option_list alg_option SEMI"""
         pass
 
     def p_alg_option(self, p):
-        '''alg_option : coverage_option
-                      | rollperiod_option
-                      | prepublish_option
-                      | postpublish_option
-                      | keyttl_option
-                      | keysize_option
-                      | standby_option'''
+        """alg_option : coverage_option
+        | rollperiod_option
+        | prepublish_option
+        | postpublish_option
+        | keyttl_option
+        | keysize_option
+        | standby_option"""
         pass
 
     def p_parent_option(self, p):
@@ -666,17 +727,25 @@ class dnssec_policy:
 
     def p_error(self, p):
         if p:
-            print("%s%s%d:syntax error near '%s'" %
-                    (self.filename or "", ":" if self.filename else "",
-                     p.lineno, p.value))
+            print(
+                "%s%s%d:syntax error near '%s'"
+                % (self.filename or "", ":" if self.filename else "", p.lineno, p.value)
+            )
         else:
             if not self.initial:
-                raise PolicyException("%s%s%d:unexpected end of input" %
-                    (self.filename or "", ":" if self.filename else "",
-                     p and p.lineno or 0))
+                raise PolicyException(
+                    "%s%s%d:unexpected end of input"
+                    % (
+                        self.filename or "",
+                        ":" if self.filename else "",
+                        p and p.lineno or 0,
+                    )
+                )
+
 
 if __name__ == "__main__":
     import sys
+
     if sys.argv[1] == "lex":
         file = open(sys.argv[2])
         text = file.read()
@@ -686,7 +755,7 @@ if __name__ == "__main__":
     elif sys.argv[1] == "parse":
         try:
             pp = dnssec_policy(sys.argv[2], write_tables=True, debug=True)
-            print(pp.named_policy['default'])
+            print(pp.named_policy["default"])
             print(pp.policy("nonexistent.zone"))
         except Exception as e:
             print(e.args[0])
index 8e138b8bcba08f79044df55c65ae24d5ac9b3e17..a8af767bf9f0156fd5222f9c2e62abeaa5764f76 100644 (file)
@@ -26,12 +26,15 @@ import socket
 
 class rndc(object):
     """RNDC protocol client library"""
-    __algos = {'md5':    157,
-               'sha1':   161,
-               'sha224': 162,
-               'sha256': 163,
-               'sha384': 164,
-               'sha512': 165}
+
+    __algos = {
+        "md5": 157,
+        "sha1": 161,
+        "sha224": 162,
+        "sha256": 163,
+        "sha384": 164,
+        "sha512": 165,
+    }
 
     def __init__(self, host, algo, secret):
         """Creates a persistent connection to RNDC and logs in
@@ -41,7 +44,7 @@ class rndc(object):
         secret - HMAC secret, base64 encoded"""
         self.host = host
         algo = algo.lower()
-        if algo.startswith('hmac-'):
+        if algo.startswith("hmac-"):
             algo = algo[5:]
         self.algo = algo
         self.hlalgo = getattr(hashlib, algo)
@@ -54,26 +57,27 @@ class rndc(object):
         """Call a RNDC command, all parsing is done on the server side
         cmd - a complete string with a command (eg 'reload zone example.com')
         """
-        return dict(self.__command(type=cmd)['_data'])
+        return dict(self.__command(type=cmd)["_data"])
 
     def __serialize_dict(self, data, ignore_auth=False):
         rv = bytearray()
         for k, v in data.items():
-            if ignore_auth and k == '_auth':
+            if ignore_auth and k == "_auth":
                 continue
-            rv += struct.pack('B', len(k)) + k.encode('ascii')
+            rv += struct.pack("B", len(k)) + k.encode("ascii")
             if type(v) == str:
-                rv += struct.pack('>BI', 1, len(v)) + v.encode('ascii')
+                rv += struct.pack(">BI", 1, len(v)) + v.encode("ascii")
             elif type(v) == bytes:
-                rv += struct.pack('>BI', 1, len(v)) + v
+                rv += struct.pack(">BI", 1, len(v)) + v
             elif type(v) == bytearray:
-                rv += struct.pack('>BI', 1, len(v)) + v
+                rv += struct.pack(">BI", 1, len(v)) + v
             elif type(v) == OrderedDict:
                 sd = self.__serialize_dict(v)
-                rv += struct.pack('>BI', 2, len(sd)) + sd
+                rv += struct.pack(">BI", 2, len(sd)) + sd
             else:
-                raise NotImplementedError('Cannot serialize element of type %s'
-                                          % type(v))
+                raise NotImplementedError(
+                    "Cannot serialize element of type %s" % type(v)
+                )
         return rv
 
     def __prep_message(self, *args, **kwargs):
@@ -82,41 +86,42 @@ class rndc(object):
         data = OrderedDict(*args, **kwargs)
 
         d = OrderedDict()
-        d['_auth'] = OrderedDict()
-        d['_ctrl'] = OrderedDict()
-        d['_ctrl']['_ser'] = str(self.ser)
-        d['_ctrl']['_tim'] = str(now)
-        d['_ctrl']['_exp'] = str(now+60)
+        d["_auth"] = OrderedDict()
+        d["_ctrl"] = OrderedDict()
+        d["_ctrl"]["_ser"] = str(self.ser)
+        d["_ctrl"]["_tim"] = str(now)
+        d["_ctrl"]["_exp"] = str(now + 60)
         if self.nonce is not None:
-            d['_ctrl']['_nonce'] = self.nonce
-        d['_data'] = data
+            d["_ctrl"]["_nonce"] = self.nonce
+        d["_data"] = data
 
         msg = self.__serialize_dict(d, ignore_auth=True)
         hash = hmac.new(self.secret, msg, self.hlalgo).digest()
         bhash = base64.b64encode(hash)
-        if self.algo == 'md5':
-            d['_auth']['hmd5'] = struct.pack('22s', bhash)
+        if self.algo == "md5":
+            d["_auth"]["hmd5"] = struct.pack("22s", bhash)
         else:
-            d['_auth']['hsha'] = bytearray(struct.pack('B88s',
-                                             self.__algos[self.algo], bhash))
+            d["_auth"]["hsha"] = bytearray(
+                struct.pack("B88s", self.__algos[self.algo], bhash)
+            )
         msg = self.__serialize_dict(d)
-        msg = struct.pack('>II', len(msg) + 4, 1) + msg
+        msg = struct.pack(">II", len(msg) + 4, 1) + msg
         return msg
 
     def __verify_msg(self, msg):
-        if self.nonce is not None and msg['_ctrl']['_nonce'] != self.nonce:
+        if self.nonce is not None and msg["_ctrl"]["_nonce"] != self.nonce:
             return False
-        if self.algo == 'md5':
-            bhash = msg['_auth']['hmd5']
+        if self.algo == "md5":
+            bhash = msg["_auth"]["hmd5"]
         else:
-            bhash = msg['_auth']['hsha'][1:]
+            bhash = msg["_auth"]["hsha"][1:]
         if type(bhash) == bytes:
-            bhash = bhash.decode('ascii')
-        bhash += '=' * (4 - (len(bhash) % 4))
+            bhash = bhash.decode("ascii")
+        bhash += "=" * (4 - (len(bhash) % 4))
         remote_hash = base64.b64decode(bhash)
         my_msg = self.__serialize_dict(msg, ignore_auth=True)
         my_hash = hmac.new(self.secret, my_msg, self.hlalgo).digest()
-        return (my_hash == remote_hash)
+        return my_hash == remote_hash
 
     def __command(self, *args, **kwargs):
         msg = self.__prep_message(*args, **kwargs)
@@ -129,9 +134,9 @@ class rndc(object):
             # What should we throw here? Bad auth can cause this...
             raise IOError("Can't read response header")
 
-        length, version = struct.unpack('>II', header)
+        length, version = struct.unpack(">II", header)
         if version != 1:
-            raise NotImplementedError('Wrong message version %d' % version)
+            raise NotImplementedError("Wrong message version %d" % version)
 
         # it includes the header
         length -= 4
@@ -150,26 +155,26 @@ class rndc(object):
     def __connect_login(self):
         self.socket = socket.create_connection(self.host)
         self.nonce = None
-        msg = self.__command(type='null')
-        self.nonce = msg['_ctrl']['_nonce']
+        msg = self.__command(type="null")
+        self.nonce = msg["_ctrl"]["_nonce"]
 
     def __parse_element(self, input):
         pos = 0
         labellen = input[pos]
         pos += 1
-        label = input[pos:pos+labellen].decode('ascii')
+        label = input[pos : pos + labellen].decode("ascii")
         pos += labellen
         type = input[pos]
         pos += 1
-        datalen = struct.unpack('>I', input[pos:pos+4])[0]
+        datalen = struct.unpack(">I", input[pos : pos + 4])[0]
         pos += 4
-        data = input[pos:pos+datalen]
+        data = input[pos : pos + datalen]
         pos += datalen
         rest = input[pos:]
 
-        if type == 1:         # raw binary value
+        if type == 1:  # raw binary value
             return label, data, rest
-        elif type == 2:       # dictionary
+        elif type == 2:  # dictionary
             d = OrderedDict()
             while len(data) > 0:
                 ilabel, value, data = self.__parse_element(data)
@@ -177,7 +182,7 @@ class rndc(object):
             return label, d, rest
         # TODO type 3 - list
         else:
-            raise NotImplementedError('Unknown element type %d' % type)
+            raise NotImplementedError("Unknown element type %d" % type)
 
     def __parse_message(self, input):
         rv = OrderedDict()
index c587a0fe690a99618dd0bbdf8ab10283abc8d2a8..e3ce3f7680d7f5420e3bc157adc387e8f5940341 100644 (file)
@@ -11,7 +11,8 @@
 
 import sys
 import unittest
-sys.path.append('../..')
+
+sys.path.append("../..")
 from isc import *
 
 kdict = None
@@ -20,7 +21,7 @@ kdict = None
 def getkey():
     global kdict
     if not kdict:
-        kd = keydict(path='testdata')
+        kd = keydict(path="testdata")
     for key in kd:
         return key
 
@@ -39,14 +40,15 @@ class DnskeyTest(unittest.TestCase):
 
     def test_fmttime(self):
         key = getkey()
-        self.assertEqual(key.getfmttime('Created'), '20151120214047')
-        self.assertEqual(key.getfmttime('Publish'), '20151021214154')
-        self.assertEqual(key.getfmttime('Activate'), '20151120214154')
-        self.assertEqual(key.getfmttime('Revoke'), '20161119214154')
-        self.assertEqual(key.getfmttime('Inactive'), '20171119214154')
-        self.assertEqual(key.getfmttime('Delete'), '20181119214154')
-        self.assertEqual(key.getfmttime('SyncPublish'), '20150921214154')
-        self.assertEqual(key.getfmttime('SyncDelete'), '20151130214154')
+        self.assertEqual(key.getfmttime("Created"), "20151120214047")
+        self.assertEqual(key.getfmttime("Publish"), "20151021214154")
+        self.assertEqual(key.getfmttime("Activate"), "20151120214154")
+        self.assertEqual(key.getfmttime("Revoke"), "20161119214154")
+        self.assertEqual(key.getfmttime("Inactive"), "20171119214154")
+        self.assertEqual(key.getfmttime("Delete"), "20181119214154")
+        self.assertEqual(key.getfmttime("SyncPublish"), "20150921214154")
+        self.assertEqual(key.getfmttime("SyncDelete"), "20151130214154")
+
 
 if __name__ == "__main__":
     unittest.main()
index 9d80c35d3a8346288fa771c16fbe7bc11cc4a038..c115a31d87b87ea2a189702cd5c0a9a42888c275 100644 (file)
 
 import sys
 import unittest
-sys.path.append('../..')
+
+sys.path.append("../..")
 from isc import *
 
 
 class PolicyTest(unittest.TestCase):
     def test_keysize(self):
         pol = policy.dnssec_policy()
-        pol.load('test-policies/01-keysize.pol')
+        pol.load("test-policies/01-keysize.pol")
 
-        p = pol.policy('good_rsa.test', novalidate=True)
+        p = pol.policy("good_rsa.test", novalidate=True)
         self.assertEqual(p.get_name(), "good_rsa.test")
         self.assertEqual(p.constructed(), False)
         self.assertEqual(p.validate(), (True, ""))
 
     def test_prepublish(self):
         pol = policy.dnssec_policy()
-        pol.load('test-policies/02-prepublish.pol')
-        p = pol.policy('good_prepublish.test', novalidate=True)
+        pol.load("test-policies/02-prepublish.pol")
+        p = pol.policy("good_prepublish.test", novalidate=True)
         self.assertEqual(p.validate(), (True, ""))
 
-        p = pol.policy('bad_prepublish.test', novalidate=True)
-        self.assertEqual(p.validate(),
-                         (False, 'KSK pre/post-publish periods '
-                                 '(10368000/5184000) combined exceed '
-                                 'rollover period 10368000'))
+        p = pol.policy("bad_prepublish.test", novalidate=True)
+        self.assertEqual(
+            p.validate(),
+            (
+                False,
+                "KSK pre/post-publish periods "
+                "(10368000/5184000) combined exceed "
+                "rollover period 10368000",
+            ),
+        )
 
     def test_postpublish(self):
         pol = policy.dnssec_policy()
-        pol.load('test-policies/03-postpublish.pol')
+        pol.load("test-policies/03-postpublish.pol")
 
-        p = pol.policy('good_postpublish.test', novalidate=True)
+        p = pol.policy("good_postpublish.test", novalidate=True)
         self.assertEqual(p.validate(), (True, ""))
 
-        p = pol.policy('bad_postpublish.test', novalidate=True)
-        self.assertEqual(p.validate(),
-                         (False, 'KSK pre/post-publish periods '
-                                 '(10368000/5184000) combined exceed '
-                                 'rollover period 10368000'))
+        p = pol.policy("bad_postpublish.test", novalidate=True)
+        self.assertEqual(
+            p.validate(),
+            (
+                False,
+                "KSK pre/post-publish periods "
+                "(10368000/5184000) combined exceed "
+                "rollover period 10368000",
+            ),
+        )
 
     def test_combined_pre_post(self):
         pol = policy.dnssec_policy()
-        pol.load('test-policies/04-combined-pre-post.pol')
+        pol.load("test-policies/04-combined-pre-post.pol")
 
-        p = pol.policy('good_combined_pre_post_ksk.test', novalidate=True)
+        p = pol.policy("good_combined_pre_post_ksk.test", novalidate=True)
         self.assertEqual(p.validate(), (True, ""))
 
-        p = pol.policy('bad_combined_pre_post_ksk.test', novalidate=True)
-        self.assertEqual(p.validate(),
-                         (False, 'KSK pre/post-publish periods '
-                                 '(5184000/5184000) combined exceed '
-                                 'rollover period 10368000'))
-
-        p = pol.policy('good_combined_pre_post_zsk.test', novalidate=True)
-        self.assertEqual(p.validate(),
-                         (True, ""))
-        p = pol.policy('bad_combined_pre_post_zsk.test', novalidate=True)
-        self.assertEqual(p.validate(),
-                         (False, 'ZSK pre/post-publish periods '
-                                 '(5184000/5184000) combined exceed '
-                                 'rollover period 7776000'))
+        p = pol.policy("bad_combined_pre_post_ksk.test", novalidate=True)
+        self.assertEqual(
+            p.validate(),
+            (
+                False,
+                "KSK pre/post-publish periods "
+                "(5184000/5184000) combined exceed "
+                "rollover period 10368000",
+            ),
+        )
+
+        p = pol.policy("good_combined_pre_post_zsk.test", novalidate=True)
+        self.assertEqual(p.validate(), (True, ""))
+        p = pol.policy("bad_combined_pre_post_zsk.test", novalidate=True)
+        self.assertEqual(
+            p.validate(),
+            (
+                False,
+                "ZSK pre/post-publish periods "
+                "(5184000/5184000) combined exceed "
+                "rollover period 7776000",
+            ),
+        )
 
     def test_numeric_zone(self):
         pol = policy.dnssec_policy()
-        pol.load('test-policies/05-numeric-zone.pol')
+        pol.load("test-policies/05-numeric-zone.pol")
 
-        p = pol.policy('99example.test', novalidate=True)
+        p = pol.policy("99example.test", novalidate=True)
         self.assertEqual(p.validate(), (True, ""))
 
+
 if __name__ == "__main__":
     unittest.main()
index 6d7cb1c9ea60088acb030cfe882b0f3628a875ce..3ce4d4c87408d8a5e53085103eff2d0e70307736 100644 (file)
 import os
 
 # These routines permit platform-independent location of BIND 9 tools
-if os.name == 'nt':
+if os.name == "nt":
     import win32con
     import win32api
 
 
-def prefix(bindir=''):
-    if os.name != 'nt':
-        return os.path.join('@prefix@', bindir)
+def prefix(bindir=""):
+    if os.name != "nt":
+        return os.path.join("@prefix@", bindir)
 
     hklm = win32con.HKEY_LOCAL_MACHINE
     bind_subkey = "Software\\ISC\\BIND"
@@ -59,13 +59,13 @@ def prefix(bindir=''):
 
 
 def shellquote(s):
-    if os.name == 'nt':
+    if os.name == "nt":
         return '"' + s.replace('"', '"\\"') + '"'
     return "'" + s.replace("'", "'\\''") + "'"
 
 
-version = '@BIND9_VERSION@'
-if os.name != 'nt':
-    sysconfdir = '@expanded_sysconfdir@'
+version = "@BIND9_VERSION@"
+if os.name != "nt":
+    sysconfdir = "@expanded_sysconfdir@"
 else:
-    sysconfdir = prefix('etc')
+    sysconfdir = prefix("etc")
index cdef8bf266d521e4f6333cc7334b05f0c54668c2..4440b746424ef3c89962fe9a5b4243d71d756778 100644 (file)
@@ -15,12 +15,14 @@ except ImportError:
     # pylint: disable=deprecated-module
     from distutils.core import setup
 
-setup(name='isc',
-      version='2.0',
-      description='Python functions to support BIND utilities',
-      url='https://www.isc.org/bind',
-      author='Internet Systems Consortium, Inc',
-      author_email='info@isc.org',
-      license='MPL',
-      requires=['ply'],
-      packages=['isc'])
+setup(
+    name="isc",
+    version="2.0",
+    description="Python functions to support BIND utilities",
+    url="https://www.isc.org/bind",
+    author="Internet Systems Consortium, Inc",
+    author_email="info@isc.org",
+    license="MPL",
+    requires=["ply"],
+    packages=["isc"],
+)
index e733f93fa72832c720529c315d82b2986a410555..7f4bf633fb8cbba78608aeb385c3c50e68a9ac94 100755 (executable)
@@ -16,61 +16,63 @@ import time
 
 
 def run_rndc(server, rndc_command):
-    '''
+    """
     Send the specified 'rndc_command' to 'server' with a timeout of 10 seconds
-    '''
-    rndc = os.getenv('RNDC')
-    port = os.getenv('CONTROLPORT')
+    """
+    rndc = os.getenv("RNDC")
+    port = os.getenv("CONTROLPORT")
 
-    cmdline = [rndc, '-c', '../common/rndc.conf', '-p', port, '-s', server]
+    cmdline = [rndc, "-c", "../common/rndc.conf", "-p", port, "-s", server]
     cmdline.extend(rndc_command)
 
     subprocess.check_output(cmdline, stderr=subprocess.STDOUT, timeout=10)
 
 
 def rndc_loop(test_state, domain):
-    '''
+    """
     Run "rndc addzone", "rndc modzone", and "rndc delzone" in a tight loop
     until the test is considered finished, ignoring errors
-    '''
+    """
     rndc_commands = [
-        ['addzone', domain,
-         '{ type master; file "example.db"; };'],
-        ['modzone', domain,
-         '{ type master; file "example.db"; allow-transfer { any; }; };'],
-        ['delzone', domain],
+        ["addzone", domain, '{ type master; file "example.db"; };'],
+        [
+            "modzone",
+            domain,
+            '{ type master; file "example.db"; allow-transfer { any; }; };',
+        ],
+        ["delzone", domain],
     ]
 
-    while not test_state['finished']:
+    while not test_state["finished"]:
         for command in rndc_commands:
             try:
-                run_rndc('10.53.0.3', command)
+                run_rndc("10.53.0.3", command)
             except subprocess.SubprocessError:
                 pass
 
 
 def check_if_server_is_responsive():
-    '''
+    """
     Check if server status can be successfully retrieved using "rndc status"
-    '''
+    """
     try:
-        run_rndc('10.53.0.3', ['status'])
+        run_rndc("10.53.0.3", ["status"])
         return True
     except subprocess.SubprocessError:
         return False
 
 
 def test_rndc_deadlock():
-    '''
+    """
     Test whether running "rndc addzone", "rndc modzone", and "rndc delzone"
     commands concurrently does not trigger a deadlock
-    '''
-    test_state = {'finished': False}
+    """
+    test_state = {"finished": False}
 
     # Create 4 worker threads running "rndc" commands in a loop.
     with concurrent.futures.ThreadPoolExecutor() as executor:
         for i in range(1, 5):
-            domain = 'example%d' % i
+            domain = "example%d" % i
             executor.submit(rndc_loop, test_state, domain)
 
         # Run "rndc status" 10 times, with 1-second pauses between attempts.
@@ -84,7 +86,7 @@ def test_rndc_deadlock():
             time.sleep(1)
 
         # Signal worker threads that the test is finished.
-        test_state['finished'] = True
+        test_state["finished"] = True
 
     # Check whether all "rndc status" commands succeeded.
     assert server_is_responsive
index a5dad70edc13987247a98b1933fe647c4eaa40ab..4d17705ef135e394767ba31b75eb6cdaea484e27 100755 (executable)
@@ -69,18 +69,22 @@ from dns.name import *
 ############################################################################
 actions = []
 rrs = []
+
+
 def ctl_channel(msg):
     global actions, rrs
 
     msg = msg.splitlines().pop(0)
-    print ('received control message: %s' % msg)
+    print("received control message: %s" % msg)
 
-    msg = msg.split(b'|')
+    msg = msg.split(b"|")
     if len(msg) == 0:
         return
 
-    actions = [x.strip() for x in msg[0].split(b',')]
-    n = functools.reduce(lambda n, act: (n + (2 if act == b'dname' else 1)), [0] + actions)
+    actions = [x.strip() for x in msg[0].split(b",")]
+    n = functools.reduce(
+        lambda n, act: (n + (2 if act == b"dname" else 1)), [0] + actions
+    )
 
     if len(msg) == 1:
         rrs = []
@@ -89,29 +93,30 @@ def ctl_channel(msg):
                 rrs.append((i, b))
         return
 
-    rlist = [x.strip() for x in msg[1].split(b',')]
+    rlist = [x.strip() for x in msg[1].split(b",")]
     rrs = []
     for item in rlist:
-        if item[0] == b's'[0]:
+        if item[0] == b"s"[0]:
             i = int(item[1:].strip()) - 1
             if i > n:
-                print ('invalid index %d' + (i + 1))
+                print("invalid index %d" + (i + 1))
                 continue
             rrs.append((int(item[1:]) - 1, True))
         else:
             i = int(item) - 1
             if i > n:
-                print ('invalid index %d' % (i + 1))
+                print("invalid index %d" % (i + 1))
                 continue
             rrs.append((i, False))
 
+
 ############################################################################
 # Respond to a DNS query.
 ############################################################################
 def create_response(msg):
     m = dns.message.from_wire(msg)
     qname = m.question[0].name.to_text()
-    labels = qname.lower().split('.')
+    labels = qname.lower().split(".")
     wantsigs = True if m.ednsflags & dns.flags.DO else False
 
     # get qtype
@@ -124,27 +129,27 @@ def create_response(msg):
     # - sld is 'example'
     # - tld is 'com.'
     name = labels.pop(0)
-    domain = '.'.join(labels)
+    domain = ".".join(labels)
     sld = labels.pop(0)
-    tld = '.'.join(labels)
+    tld = ".".join(labels)
 
-    print ('query: ' + qname + '/' + typename)
-    print ('domain: ' + domain)
+    print("query: " + qname + "/" + typename)
+    print("domain: " + domain)
 
     # default answers, depending on QTYPE.
     # currently only A, AAAA, TXT and NS are supported.
     ttl = 86400
-    additionalA = '10.53.0.4'
-    additionalAAAA = 'fd92:7065:b8e:ffff::4'
-    if typename == 'A':
-        final = '10.53.0.4'
-    elif typename == 'AAAA':
-        final = 'fd92:7065:b8e:ffff::4'
-    elif typename == 'TXT':
-        final = 'Some\ text\ here'
-    elif typename == 'NS':
+    additionalA = "10.53.0.4"
+    additionalAAAA = "fd92:7065:b8e:ffff::4"
+    if typename == "A":
+        final = "10.53.0.4"
+    elif typename == "AAAA":
+        final = "fd92:7065:b8e:ffff::4"
+    elif typename == "TXT":
+        final = "Some\ text\ here"
+    elif typename == "NS":
         domain = qname
-        final = ('ns1.%s' % domain)
+        final = "ns1.%s" % domain
     else:
         final = None
 
@@ -153,9 +158,9 @@ def create_response(msg):
     delta = timedelta(30)
     t1 = t - delta
     t2 = t + delta
-    inception=t1.strftime('%Y%m%d000000')
-    expiry=t2.strftime('%Y%m%d000000')
-    sigdata='OCXH2De0yE4NMTl9UykvOsJ4IBGs/ZIpff2rpaVJrVG7jQfmj50otBAp A0Zo7dpBU4ofv0N/F2Ar6LznCncIojkWptEJIAKA5tHegf/jY39arEpO cevbGp6DKxFhlkLXNcw7k9o7DSw14OaRmgAjXdTFbrl4AiAa0zAttFko Tso='
+    inception = t1.strftime("%Y%m%d000000")
+    expiry = t2.strftime("%Y%m%d000000")
+    sigdata = "OCXH2De0yE4NMTl9UykvOsJ4IBGs/ZIpff2rpaVJrVG7jQfmj50otBAp A0Zo7dpBU4ofv0N/F2Ar6LznCncIojkWptEJIAKA5tHegf/jY39arEpO cevbGp6DKxFhlkLXNcw7k9o7DSw14OaRmgAjXdTFbrl4AiAa0zAttFko Tso="
 
     # construct answer set.
     answers = []
@@ -165,71 +170,97 @@ def create_response(msg):
     i = 0
 
     for action in actions:
-        if name != 'test':
+        if name != "test":
             continue
-        if action == b'xname':
-            owner = curname + '.' + curdom
-            newname = 'cname%d' % i
+        if action == b"xname":
+            owner = curname + "." + curdom
+            newname = "cname%d" % i
             i += 1
-            newdom = 'domain%d.%s' % (i, tld)
+            newdom = "domain%d.%s" % (i, tld)
             i += 1
-            target = newname + '.' + newdom
-            print ('add external CNAME %s to %s' % (owner, target))
+            target = newname + "." + newdom
+            print("add external CNAME %s to %s" % (owner, target))
             answers.append(dns.rrset.from_text(owner, ttl, IN, CNAME, target))
-            rrsig = 'CNAME 5 3 %d %s %s 12345 %s %s' % \
-               (ttl, expiry, inception, domain, sigdata)
-            print ('add external RRISG(CNAME) %s to %s' % (owner, target))
+            rrsig = "CNAME 5 3 %d %s %s 12345 %s %s" % (
+                ttl,
+                expiry,
+                inception,
+                domain,
+                sigdata,
+            )
+            print("add external RRISG(CNAME) %s to %s" % (owner, target))
             sigs.append(dns.rrset.from_text(owner, ttl, IN, RRSIG, rrsig))
             curname = newname
             curdom = newdom
             continue
 
-        if action == b'cname':
-            owner = curname + '.' + curdom
-            newname = 'cname%d' % i
-            target = newname + '.' + curdom
+        if action == b"cname":
+            owner = curname + "." + curdom
+            newname = "cname%d" % i
+            target = newname + "." + curdom
             i += 1
-            print ('add CNAME %s to %s' % (owner, target))
+            print("add CNAME %s to %s" % (owner, target))
             answers.append(dns.rrset.from_text(owner, ttl, IN, CNAME, target))
-            rrsig = 'CNAME 5 3 %d %s %s 12345 %s %s' % \
-                   (ttl, expiry, inception, domain, sigdata)
-            print ('add RRSIG(CNAME) %s to %s' % (owner, target))
+            rrsig = "CNAME 5 3 %d %s %s 12345 %s %s" % (
+                ttl,
+                expiry,
+                inception,
+                domain,
+                sigdata,
+            )
+            print("add RRSIG(CNAME) %s to %s" % (owner, target))
             sigs.append(dns.rrset.from_text(owner, ttl, IN, RRSIG, rrsig))
             curname = newname
             continue
 
-        if action == b'dname':
+        if action == b"dname":
             owner = curdom
-            newdom = 'domain%d.%s' % (i, tld)
+            newdom = "domain%d.%s" % (i, tld)
             i += 1
-            print ('add DNAME %s to %s' % (owner, newdom))
+            print("add DNAME %s to %s" % (owner, newdom))
             answers.append(dns.rrset.from_text(owner, ttl, IN, DNAME, newdom))
-            rrsig = 'DNAME 5 3 %d %s %s 12345 %s %s' % \
-                   (ttl, expiry, inception, domain, sigdata)
-            print ('add RRSIG(DNAME) %s to %s' % (owner, newdom))
+            rrsig = "DNAME 5 3 %d %s %s 12345 %s %s" % (
+                ttl,
+                expiry,
+                inception,
+                domain,
+                sigdata,
+            )
+            print("add RRSIG(DNAME) %s to %s" % (owner, newdom))
             sigs.append(dns.rrset.from_text(owner, ttl, IN, RRSIG, rrsig))
-            owner = curname + '.' + curdom
-            target = curname + '.' + newdom
-            print ('add synthesized CNAME %s to %s' % (owner, target))
+            owner = curname + "." + curdom
+            target = curname + "." + newdom
+            print("add synthesized CNAME %s to %s" % (owner, target))
             answers.append(dns.rrset.from_text(owner, ttl, IN, CNAME, target))
-            rrsig = 'CNAME 5 3 %d %s %s 12345 %s %s' % \
-                   (ttl, expiry, inception, domain, sigdata)
-            print ('add synthesized RRSIG(CNAME) %s to %s' % (owner, target))
+            rrsig = "CNAME 5 3 %d %s %s 12345 %s %s" % (
+                ttl,
+                expiry,
+                inception,
+                domain,
+                sigdata,
+            )
+            print("add synthesized RRSIG(CNAME) %s to %s" % (owner, target))
             sigs.append(dns.rrset.from_text(owner, ttl, IN, RRSIG, rrsig))
             curdom = newdom
             continue
 
     # now add the final answer
-    owner = curname + '.' + curdom
+    owner = curname + "." + curdom
     answers.append(dns.rrset.from_text(owner, ttl, IN, rrtype, final))
-    rrsig = '%s 5 3 %d %s %s 12345 %s %s' % \
-               (typename, ttl, expiry, inception, domain, sigdata)
+    rrsig = "%s 5 3 %d %s %s 12345 %s %s" % (
+        typename,
+        ttl,
+        expiry,
+        inception,
+        domain,
+        sigdata,
+    )
     sigs.append(dns.rrset.from_text(owner, ttl, IN, RRSIG, rrsig))
 
     # prepare the response and convert to wire format
     r = dns.message.make_response(m)
 
-    if name != 'test':
+    if name != "test":
         r.answer.append(answers[-1])
         if wantsigs:
             r.answer.append(sigs[-1])
@@ -242,24 +273,29 @@ def create_response(msg):
             else:
                 r.answer.append(answers[i])
 
-    if typename != 'NS':
-        r.authority.append(dns.rrset.from_text(domain, ttl, IN, "NS",
-                                               ("ns1.%s" % domain)))
-    r.additional.append(dns.rrset.from_text(('ns1.%s' % domain), 86400,
-                                             IN, A, additionalA))
-    r.additional.append(dns.rrset.from_text(('ns1.%s' % domain), 86400,
-                                             IN, AAAA, additionalAAAA))
+    if typename != "NS":
+        r.authority.append(
+            dns.rrset.from_text(domain, ttl, IN, "NS", ("ns1.%s" % domain))
+        )
+    r.additional.append(
+        dns.rrset.from_text(("ns1.%s" % domain), 86400, IN, A, additionalA)
+    )
+    r.additional.append(
+        dns.rrset.from_text(("ns1.%s" % domain), 86400, IN, AAAA, additionalAAAA)
+    )
 
     r.flags |= dns.flags.AA
     r.use_edns()
     return r.to_wire()
 
+
 def sigterm(signum, frame):
-    print ("Shutting down now...")
-    os.remove('ans.pid')
+    print("Shutting down now...")
+    os.remove("ans.pid")
     running = False
     sys.exit(0)
 
+
 ############################################################################
 # Main
 #
@@ -270,11 +306,15 @@ def sigterm(signum, frame):
 ip4 = "10.53.0.4"
 ip6 = "fd92:7065:b8e:ffff::4"
 
-try: port=int(os.environ['PORT'])
-except: port=5300
+try:
+    port = int(os.environ["PORT"])
+except:
+    port = 5300
 
-try: ctrlport=int(os.environ['EXTRAPORT1'])
-except: ctrlport=5300
+try:
+    ctrlport = int(os.environ["EXTRAPORT1"])
+except:
+    ctrlport = 5300
 
 query4_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
 query4_socket.bind((ip4, port))
@@ -296,18 +336,18 @@ ctrl_socket.listen(5)
 
 signal.signal(signal.SIGTERM, sigterm)
 
-f = open('ans.pid', 'w')
+f = open("ans.pid", "w")
 pid = os.getpid()
-print (pid, file=f)
+print(pid, file=f)
 f.close()
 
 running = True
 
-print ("Listening on %s port %d" % (ip4, port))
+print("Listening on %s port %d" % (ip4, port))
 if havev6:
-    print ("Listening on %s port %d" % (ip6, port))
-print ("Control channel on %s port %d" % (ip4, ctrlport))
-print ("Ctrl-c to quit")
+    print("Listening on %s port %d" % (ip6, port))
+print("Control channel on %s port %d" % (ip4, ctrlport))
+print("Ctrl-c to quit")
 
 if havev6:
     input = [query4_socket, query6_socket, ctrl_socket]
@@ -328,7 +368,7 @@ while running:
         if s == ctrl_socket:
             # Handle control channel input
             conn, addr = s.accept()
-            print ("Control channel connected")
+            print("Control channel connected")
             while True:
                 msg = conn.recv(65535)
                 if not msg:
@@ -336,8 +376,7 @@ while running:
                 ctl_channel(msg)
             conn.close()
         if s == query4_socket or s == query6_socket:
-            print ("Query received on %s" %
-                    (ip4 if s == query4_socket else ip6))
+            print("Query received on %s" % (ip4 if s == query4_socket else ip6))
             # Handle incoming queries
             msg = s.recvfrom(65535)
             rsp = create_response(msg[0])
index a463b72b5733b5a2f94f0e4794c0f956e8a770a8..5282e297983765ff8fa29cef548166ed672dfb9e 100755 (executable)
@@ -19,7 +19,7 @@ import time
 
 import pytest
 
-pytest.importorskip('dns', minversion='2.0.0')
+pytest.importorskip("dns", minversion="2.0.0")
 import dns.exception
 import dns.message
 import dns.name
@@ -55,18 +55,22 @@ def has_signed_apex_nsec(zone, response):
 
 
 def do_query(server, qname, qtype, tcp=False):
-    query = dns.message.make_query(qname, qtype, use_edns=True,
-                                   want_dnssec=True)
+    query = dns.message.make_query(qname, qtype, use_edns=True, want_dnssec=True)
     try:
         if tcp:
-            response = dns.query.tcp(query, server.nameservers[0], timeout=3,
-                                     port=server.port)
+            response = dns.query.tcp(
+                query, server.nameservers[0], timeout=3, port=server.port
+            )
         else:
-            response = dns.query.udp(query, server.nameservers[0], timeout=3,
-                                     port=server.port)
+            response = dns.query.udp(
+                query, server.nameservers[0], timeout=3, port=server.port
+            )
     except dns.exception.Timeout:
-        print("error: query timeout for query {} {} to {}".format(
-              qname, qtype, server.nameservers[0]))
+        print(
+            "error: query timeout for query {} {} to {}".format(
+                qname, qtype, server.nameservers[0]
+            )
+        )
         return None
 
     return response
@@ -77,10 +81,10 @@ def verify_zone(zone, transfer):
     assert verify is not None
 
     filename = "{}out".format(zone)
-    with open(filename, 'w', encoding='utf-8') as file:
+    with open(filename, "w", encoding="utf-8") as file:
         for rr in transfer.answer:
             file.write(rr.to_text())
-            file.write('\n')
+            file.write("\n")
 
     # dnssec-verify command with default arguments.
     verify_cmd = [verify, "-z", "-o", zone, filename]
@@ -108,30 +112,39 @@ def read_statefile(server, zone):
     if response.rcode() == dns.rcode.NOERROR:
         # fetch key id from response.
         for rr in response.answer:
-            if rr.match(dns.name.from_text(zone), dns.rdataclass.IN,
-                        dns.rdatatype.DS, dns.rdatatype.NONE):
+            if rr.match(
+                dns.name.from_text(zone),
+                dns.rdataclass.IN,
+                dns.rdatatype.DS,
+                dns.rdatatype.NONE,
+            ):
                 if count == 0:
                     keyid = list(dict(rr.items).items())[0][0].key_tag
                 count += 1
 
         if count != 1:
-            print("error: expected a single DS in response for {} from {},"
-                  "got {}".format(zone, addr, count))
+            print(
+                "error: expected a single DS in response for {} from {},"
+                "got {}".format(zone, addr, count)
+            )
             return {}
     else:
-        print("error: {} response for {} DNSKEY from {}".format(
-              dns.rcode.to_text(response.rcode()), zone, addr))
+        print(
+            "error: {} response for {} DNSKEY from {}".format(
+                dns.rcode.to_text(response.rcode()), zone, addr
+            )
+        )
         return {}
 
     filename = "ns9/K{}+013+{:05d}.state".format(zone, keyid)
     print("read state file {}".format(filename))
 
     try:
-        with open(filename, 'r', encoding='utf-8') as file:
+        with open(filename, "r", encoding="utf-8") as file:
             for line in file:
-                if line.startswith(';'):
+                if line.startswith(";"):
                     continue
-                key, val = line.strip().split(':', 1)
+                key, val = line.strip().split(":", 1)
                 state[key.strip()] = val.strip()
 
     except FileNotFoundError:
@@ -147,14 +160,17 @@ def zone_check(server, zone):
     # wait until zone is fully signed.
     signed = False
     for _ in range(10):
-        response = do_query(server, zone, 'NSEC')
+        response = do_query(server, zone, "NSEC")
         if not isinstance(response, dns.message.Message):
             print("error: no response for {} NSEC from {}".format(zone, addr))
         elif response.rcode() == dns.rcode.NOERROR:
             signed = has_signed_apex_nsec(zone, response)
         else:
-            print("error: {} response for {} NSEC from {}".format(
-                dns.rcode.to_text(response.rcode()), zone, addr))
+            print(
+                "error: {} response for {} NSEC from {}".format(
+                    dns.rcode.to_text(response.rcode()), zone, addr
+                )
+            )
 
         if signed:
             break
@@ -165,14 +181,17 @@ def zone_check(server, zone):
 
     # check if zone if DNSSEC valid.
     verified = False
-    transfer = do_query(server, zone, 'AXFR', tcp=True)
+    transfer = do_query(server, zone, "AXFR", tcp=True)
     if not isinstance(transfer, dns.message.Message):
         print("error: no response for {} AXFR from {}".format(zone, addr))
     elif transfer.rcode() == dns.rcode.NOERROR:
         verified = verify_zone(zone, transfer)
     else:
-        print("error: {} response for {} AXFR from {}".format(
-           dns.rcode.to_text(transfer.rcode()), zone, addr))
+        print(
+            "error: {} response for {} AXFR from {}".format(
+                dns.rcode.to_text(transfer.rcode()), zone, addr
+            )
+        )
 
     assert verified
 
@@ -182,7 +201,7 @@ def keystate_check(server, zone, key):
     deny = False
 
     search = key
-    if key.startswith('!'):
+    if key.startswith("!"):
         deny = True
         search = key[1:]
 
@@ -213,7 +232,7 @@ def wait_for_log(filename, log):
         print("read log file {}".format(filename))
 
         try:
-            with open(filename, 'r', encoding='utf-8') as file:
+            with open(filename, "r", encoding="utf-8") as file:
                 s = mmap.mmap(file.fileno(), 0, access=mmap.ACCESS_READ)
                 if s.find(bytes(log, "ascii")) != -1:
                     found = True
@@ -241,67 +260,89 @@ def test_checkds_dspublished(named_port):
 
     # DS correctly published in parent.
     zone_check(server, "dspublished.checkds.")
-    wait_for_log("ns9/named.run",
-                 "zone dspublished.checkds/IN (signed): checkds: "
-                 "DS response from 10.53.0.2")
+    wait_for_log(
+        "ns9/named.run",
+        "zone dspublished.checkds/IN (signed): checkds: " "DS response from 10.53.0.2",
+    )
     keystate_check(parent, "dspublished.checkds.", "DSPublish")
 
     # DS correctly published in parent (reference to parental-agent).
     zone_check(server, "reference.checkds.")
-    wait_for_log("ns9/named.run",
-                 "zone reference.checkds/IN (signed): checkds: "
-                 "DS response from 10.53.0.2")
+    wait_for_log(
+        "ns9/named.run",
+        "zone reference.checkds/IN (signed): checkds: " "DS response from 10.53.0.2",
+    )
     keystate_check(parent, "reference.checkds.", "DSPublish")
 
     # DS not published in parent.
     zone_check(server, "missing-dspublished.checkds.")
-    wait_for_log("ns9/named.run",
-                 "zone missing-dspublished.checkds/IN (signed): checkds: "
-                 "empty DS response from 10.53.0.5")
+    wait_for_log(
+        "ns9/named.run",
+        "zone missing-dspublished.checkds/IN (signed): checkds: "
+        "empty DS response from 10.53.0.5",
+    )
     keystate_check(parent, "missing-dspublished.checkds.", "!DSPublish")
 
     # Badly configured parent.
     zone_check(server, "bad-dspublished.checkds.")
-    wait_for_log("ns9/named.run",
-                 "zone bad-dspublished.checkds/IN (signed): checkds: "
-                 "bad DS response from 10.53.0.6")
+    wait_for_log(
+        "ns9/named.run",
+        "zone bad-dspublished.checkds/IN (signed): checkds: "
+        "bad DS response from 10.53.0.6",
+    )
     keystate_check(parent, "bad-dspublished.checkds.", "!DSPublish")
 
     # TBD: DS published in parent, but bogus signature.
 
     # DS correctly published in all parents.
     zone_check(server, "multiple-dspublished.checkds.")
-    wait_for_log("ns9/named.run",
-                 "zone multiple-dspublished.checkds/IN (signed): checkds: "
-                 "DS response from 10.53.0.2")
-    wait_for_log("ns9/named.run",
-                 "zone multiple-dspublished.checkds/IN (signed): checkds: "
-                 "DS response from 10.53.0.4")
+    wait_for_log(
+        "ns9/named.run",
+        "zone multiple-dspublished.checkds/IN (signed): checkds: "
+        "DS response from 10.53.0.2",
+    )
+    wait_for_log(
+        "ns9/named.run",
+        "zone multiple-dspublished.checkds/IN (signed): checkds: "
+        "DS response from 10.53.0.4",
+    )
     keystate_check(parent, "multiple-dspublished.checkds.", "DSPublish")
 
     # DS published in only one of multiple parents.
     zone_check(server, "incomplete-dspublished.checkds.")
-    wait_for_log("ns9/named.run",
-                 "zone incomplete-dspublished.checkds/IN (signed): checkds: "
-                 "DS response from 10.53.0.2")
-    wait_for_log("ns9/named.run",
-                 "zone incomplete-dspublished.checkds/IN (signed): checkds: "
-                 "DS response from 10.53.0.4")
-    wait_for_log("ns9/named.run",
-                 "zone incomplete-dspublished.checkds/IN (signed): checkds: "
-                 "empty DS response from 10.53.0.5")
+    wait_for_log(
+        "ns9/named.run",
+        "zone incomplete-dspublished.checkds/IN (signed): checkds: "
+        "DS response from 10.53.0.2",
+    )
+    wait_for_log(
+        "ns9/named.run",
+        "zone incomplete-dspublished.checkds/IN (signed): checkds: "
+        "DS response from 10.53.0.4",
+    )
+    wait_for_log(
+        "ns9/named.run",
+        "zone incomplete-dspublished.checkds/IN (signed): checkds: "
+        "empty DS response from 10.53.0.5",
+    )
     keystate_check(parent, "incomplete-dspublished.checkds.", "!DSPublish")
 
     # One of the parents is badly configured.
-    wait_for_log("ns9/named.run",
-                 "zone bad2-dspublished.checkds/IN (signed): checkds: "
-                 "DS response from 10.53.0.2")
-    wait_for_log("ns9/named.run",
-                 "zone bad2-dspublished.checkds/IN (signed): checkds: "
-                 "DS response from 10.53.0.4")
-    wait_for_log("ns9/named.run",
-                 "zone bad2-dspublished.checkds/IN (signed): checkds: "
-                 "bad DS response from 10.53.0.6")
+    wait_for_log(
+        "ns9/named.run",
+        "zone bad2-dspublished.checkds/IN (signed): checkds: "
+        "DS response from 10.53.0.2",
+    )
+    wait_for_log(
+        "ns9/named.run",
+        "zone bad2-dspublished.checkds/IN (signed): checkds: "
+        "DS response from 10.53.0.4",
+    )
+    wait_for_log(
+        "ns9/named.run",
+        "zone bad2-dspublished.checkds/IN (signed): checkds: "
+        "bad DS response from 10.53.0.6",
+    )
     keystate_check(parent, "bad2-dspublished.checkds.", "!DSPublish")
 
     # TBD: DS published in all parents, but one has bogus signature.
@@ -321,60 +362,82 @@ def test_checkds_dswithdrawn(named_port):
 
     # DS correctly published in single parent.
     zone_check(server, "dswithdrawn.checkds.")
-    wait_for_log("ns9/named.run",
-                 "zone dswithdrawn.checkds/IN (signed): checkds: "
-                 "empty DS response from 10.53.0.5")
+    wait_for_log(
+        "ns9/named.run",
+        "zone dswithdrawn.checkds/IN (signed): checkds: "
+        "empty DS response from 10.53.0.5",
+    )
     keystate_check(parent, "dswithdrawn.checkds.", "DSRemoved")
 
     # DS not withdrawn from parent.
     zone_check(server, "missing-dswithdrawn.checkds.")
-    wait_for_log("ns9/named.run",
-                 "zone missing-dswithdrawn.checkds/IN (signed): checkds: "
-                 "DS response from 10.53.0.2")
+    wait_for_log(
+        "ns9/named.run",
+        "zone missing-dswithdrawn.checkds/IN (signed): checkds: "
+        "DS response from 10.53.0.2",
+    )
     keystate_check(parent, "missing-dswithdrawn.checkds.", "!DSRemoved")
 
     # Badly configured parent.
     zone_check(server, "bad-dswithdrawn.checkds.")
-    wait_for_log("ns9/named.run",
-                 "zone bad-dswithdrawn.checkds/IN (signed): checkds: "
-                 "bad DS response from 10.53.0.6")
+    wait_for_log(
+        "ns9/named.run",
+        "zone bad-dswithdrawn.checkds/IN (signed): checkds: "
+        "bad DS response from 10.53.0.6",
+    )
     keystate_check(parent, "bad-dswithdrawn.checkds.", "!DSRemoved")
 
     # TBD: DS published in parent, but bogus signature.
 
     # DS correctly withdrawn from all parents.
     zone_check(server, "multiple-dswithdrawn.checkds.")
-    wait_for_log("ns9/named.run",
-                 "zone multiple-dswithdrawn.checkds/IN (signed): checkds: "
-                 "empty DS response from 10.53.0.5")
-    wait_for_log("ns9/named.run",
-                 "zone multiple-dswithdrawn.checkds/IN (signed): checkds: "
-                 "empty DS response from 10.53.0.7")
+    wait_for_log(
+        "ns9/named.run",
+        "zone multiple-dswithdrawn.checkds/IN (signed): checkds: "
+        "empty DS response from 10.53.0.5",
+    )
+    wait_for_log(
+        "ns9/named.run",
+        "zone multiple-dswithdrawn.checkds/IN (signed): checkds: "
+        "empty DS response from 10.53.0.7",
+    )
     keystate_check(parent, "multiple-dswithdrawn.checkds.", "DSRemoved")
 
     # DS withdrawn from only one of multiple parents.
     zone_check(server, "incomplete-dswithdrawn.checkds.")
-    wait_for_log("ns9/named.run",
-                 "zone incomplete-dswithdrawn.checkds/IN (signed): checkds: "
-                 "DS response from 10.53.0.2")
-    wait_for_log("ns9/named.run",
-                 "zone incomplete-dswithdrawn.checkds/IN (signed): checkds: "
-                 "empty DS response from 10.53.0.5")
-    wait_for_log("ns9/named.run",
-                 "zone incomplete-dswithdrawn.checkds/IN (signed): checkds: "
-                 "empty DS response from 10.53.0.7")
+    wait_for_log(
+        "ns9/named.run",
+        "zone incomplete-dswithdrawn.checkds/IN (signed): checkds: "
+        "DS response from 10.53.0.2",
+    )
+    wait_for_log(
+        "ns9/named.run",
+        "zone incomplete-dswithdrawn.checkds/IN (signed): checkds: "
+        "empty DS response from 10.53.0.5",
+    )
+    wait_for_log(
+        "ns9/named.run",
+        "zone incomplete-dswithdrawn.checkds/IN (signed): checkds: "
+        "empty DS response from 10.53.0.7",
+    )
     keystate_check(parent, "incomplete-dswithdrawn.checkds.", "!DSRemoved")
 
     # One of the parents is badly configured.
-    wait_for_log("ns9/named.run",
-                 "zone bad2-dswithdrawn.checkds/IN (signed): checkds: "
-                 "empty DS response from 10.53.0.5")
-    wait_for_log("ns9/named.run",
-                 "zone bad2-dswithdrawn.checkds/IN (signed): checkds: "
-                 "empty DS response from 10.53.0.7")
-    wait_for_log("ns9/named.run",
-                 "zone bad2-dswithdrawn.checkds/IN (signed): checkds: "
-                 "bad DS response from 10.53.0.6")
+    wait_for_log(
+        "ns9/named.run",
+        "zone bad2-dswithdrawn.checkds/IN (signed): checkds: "
+        "empty DS response from 10.53.0.5",
+    )
+    wait_for_log(
+        "ns9/named.run",
+        "zone bad2-dswithdrawn.checkds/IN (signed): checkds: "
+        "empty DS response from 10.53.0.7",
+    )
+    wait_for_log(
+        "ns9/named.run",
+        "zone bad2-dswithdrawn.checkds/IN (signed): checkds: "
+        "bad DS response from 10.53.0.6",
+    )
     keystate_check(parent, "bad2-dswithdrawn.checkds.", "!DSRemoved")
 
     # TBD: DS withdrawn from all parents, but one has bogus signature.
index 2fd05add7d1a9aa5e6e43e8c30e9ff441462acbf..8abf963926059bbb9f377b52c741e3d111d683c4 100644 (file)
@@ -16,16 +16,16 @@ import os
 import pytest
 
 
-@pytest.fixture(scope='session')
+@pytest.fixture(scope="session")
 def named_port():
-    return int(os.environ.get('PORT', default=5300))
+    return int(os.environ.get("PORT", default=5300))
 
 
-@pytest.fixture(scope='session')
+@pytest.fixture(scope="session")
 def named_tlsport():
-    return int(os.environ.get('TLSPORT', default=8853))
+    return int(os.environ.get("TLSPORT", default=8853))
 
 
-@pytest.fixture(scope='session')
+@pytest.fixture(scope="session")
 def control_port():
-    return int(os.environ.get('CONTROLPORT', default=9953))
+    return int(os.environ.get("CONTROLPORT", default=9953))
index abc6d36ee27fc4a414a319d26ac1529bd3a90e91..550909466a8887e2186d08082df00066881c99c8 100644 (file)
@@ -40,20 +40,17 @@ def logquery(type, qname):
     with open("qlog", "a") as f:
         f.write("%s %s\n", type, qname)
 
+
 # DNS 2.0 keyring specifies the algorithm
 try:
-    keyring = dns.tsigkeyring.from_text({ "foo" : {
-                                                   "hmac-sha256",
-                                                   "aaaaaaaaaaaa"
-                                                  } ,
-                                          "fake" : {
-                                                   "hmac-sha256",
-                                                   "aaaaaaaaaaaa"
-                                                  }
-                                         })
+    keyring = dns.tsigkeyring.from_text(
+        {
+            "foo": {"hmac-sha256", "aaaaaaaaaaaa"},
+            "fake": {"hmac-sha256", "aaaaaaaaaaaa"},
+        }
+    )
 except:
-    keyring = dns.tsigkeyring.from_text({ "foo" : "aaaaaaaaaaaa",
-                                           "fake" : "aaaaaaaaaaaa" })
+    keyring = dns.tsigkeyring.from_text({"foo": "aaaaaaaaaaaa", "fake": "aaaaaaaaaaaa"})
 
 dopass2 = False
 
@@ -81,7 +78,7 @@ def create_response(msg, tcp, first, ns10):
     m = dns.message.from_wire(msg, keyring=keyring)
     qname = m.question[0].name.to_text()
     lqname = qname.lower()
-    labels = lqname.split('.')
+    labels = lqname.split(".")
     rrtype = m.question[0].rdtype
     typename = dns.rdatatype.to_text(rrtype)
 
@@ -113,27 +110,31 @@ def create_response(msg, tcp, first, ns10):
     # Add a server cookie to the response
     if labels[0] != "nocookie":
         for o in m.options:
-            if o.otype == 10: # Use 10 instead of COOKIE
-                 if first and labels[0] == "withtsig" and not tcp:
-                     r.use_tsig(keyring = keyring,
-                                keyname = dns.name.from_text("fake"),
-                                algorithm = HMAC_SHA256)
-                 elif labels[0] != "tcponly" or tcp:
-                     cookie = o
-                     if len(o.data) == 8:
-                         cookie.data = o.data + o.data
-                     else:
-                         cookie.data = o.data
-                     r.use_edns(options=[cookie])
+            if o.otype == 10:  # Use 10 instead of COOKIE
+                if first and labels[0] == "withtsig" and not tcp:
+                    r.use_tsig(
+                        keyring=keyring,
+                        keyname=dns.name.from_text("fake"),
+                        algorithm=HMAC_SHA256,
+                    )
+                elif labels[0] != "tcponly" or tcp:
+                    cookie = o
+                    if len(o.data) == 8:
+                        cookie.data = o.data + o.data
+                    else:
+                        cookie.data = o.data
+                    r.use_edns(options=[cookie])
     r.flags |= dns.flags.AA
     return r
 
+
 def sigterm(signum, frame):
-    print ("Shutting down now...")
-    os.remove('ans.pid')
+    print("Shutting down now...")
+    os.remove("ans.pid")
     running = False
     sys.exit(0)
 
+
 ############################################################################
 # Main
 #
@@ -146,8 +147,10 @@ ip4_addr2 = "10.53.0.10"
 ip6_addr1 = "fd92:7065:b8e:ffff::9"
 ip6_addr2 = "fd92:7065:b8e:ffff::10"
 
-try: port=int(os.environ['PORT'])
-except: port=5300
+try:
+    port = int(os.environ["PORT"])
+except:
+    port = 5300
 
 query4_udp1 = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
 query4_udp1.bind((ip4_addr1, port))
@@ -195,24 +198,32 @@ except:
 
 signal.signal(signal.SIGTERM, sigterm)
 
-f = open('ans.pid', 'w')
+f = open("ans.pid", "w")
 pid = os.getpid()
-print (pid, file=f)
+print(pid, file=f)
 f.close()
 
 running = True
 
-print ("Using DNS version %s" % dns.version.version)
-print ("Listening on %s port %d" % (ip4_addr1, port))
-print ("Listening on %s port %d" % (ip4_addr2, port))
+print("Using DNS version %s" % dns.version.version)
+print("Listening on %s port %d" % (ip4_addr1, port))
+print("Listening on %s port %d" % (ip4_addr2, port))
 if havev6:
-    print ("Listening on %s port %d" % (ip6_addr1, port))
-    print ("Listening on %s port %d" % (ip6_addr2, port))
-print ("Ctrl-c to quit")
+    print("Listening on %s port %d" % (ip6_addr1, port))
+    print("Listening on %s port %d" % (ip6_addr2, port))
+print("Ctrl-c to quit")
 
 if havev6:
-    input = [query4_udp1, query6_udp1, query4_tcp1, query6_tcp1,
-             query4_udp2, query6_udp2, query4_tcp2, query6_tcp2]
+    input = [
+        query4_udp1,
+        query6_udp1,
+        query4_tcp1,
+        query6_tcp1,
+        query4_udp2,
+        query6_udp2,
+        query4_tcp2,
+        query6_tcp2,
+    ]
 else:
     input = [query4_udp1, query4_tcp1, query4_udp2, query4_tcp2]
 
@@ -228,14 +239,19 @@ while running:
 
     for s in inputready:
         ns10 = False
-        if s == query4_udp1 or s == query6_udp1 or \
-           s == query4_udp2 or s == query6_udp2:
+        if s == query4_udp1 or s == query6_udp1 or s == query4_udp2 or s == query6_udp2:
             if s == query4_udp1 or s == query6_udp1:
-                print ("UDP Query received on %s" %
-                       (ip4_addr1 if s == query4_udp1 else ip6_addr1), end=" ")
+                print(
+                    "UDP Query received on %s"
+                    % (ip4_addr1 if s == query4_udp1 else ip6_addr1),
+                    end=" ",
+                )
             if s == query4_udp2 or s == query6_udp2:
-                print ("UDP Query received on %s" %
-                       (ip4_addr2 if s == query4_udp2 else ip6_addr2), end=" ")
+                print(
+                    "UDP Query received on %s"
+                    % (ip4_addr2 if s == query4_udp2 else ip6_addr2),
+                    end=" ",
+                )
                 ns10 = True
             # Handle incoming queries
             msg = s.recvfrom(65535)
@@ -244,31 +260,36 @@ while running:
             print(dns.rcode.to_text(rsp.rcode()))
             s.sendto(rsp.to_wire(), msg[1])
             if dopass2:
-                print ("Sending second UDP response without TSIG", end=" ")
+                print("Sending second UDP response without TSIG", end=" ")
                 rsp = create_response(msg[0], False, False, ns10)
                 s.sendto(rsp.to_wire(), msg[1])
                 print(dns.rcode.to_text(rsp.rcode()))
 
-        if s == query4_tcp1 or s == query6_tcp1 or \
-           s == query4_tcp2 or s == query6_tcp2:
+        if s == query4_tcp1 or s == query6_tcp1 or s == query4_tcp2 or s == query6_tcp2:
             try:
                 (cs, _) = s.accept()
                 if s == query4_tcp1 or s == query6_tcp1:
-                    print ("TCP Query received on %s" %
-                           (ip4_addr1 if s == query4_tcp1 else ip6_addr1), end=" ")
+                    print(
+                        "TCP Query received on %s"
+                        % (ip4_addr1 if s == query4_tcp1 else ip6_addr1),
+                        end=" ",
+                    )
                 if s == query4_tcp2 or s == query6_tcp2:
-                    print ("TCP Query received on %s" %
-                           (ip4_addr2 if s == query4_tcp2 else ip6_addr2), end=" ")
+                    print(
+                        "TCP Query received on %s"
+                        % (ip4_addr2 if s == query4_tcp2 else ip6_addr2),
+                        end=" ",
+                    )
                     ns10 = True
                 # get TCP message length
                 buf = cs.recv(2)
-                length = struct.unpack('>H', buf[:2])[0]
+                length = struct.unpack(">H", buf[:2])[0]
                 # grep DNS message
                 msg = cs.recv(length)
                 rsp = create_response(msg, True, True, ns10)
                 print(dns.rcode.to_text(rsp.rcode()))
                 wire = rsp.to_wire()
-                cs.send(struct.pack('>H', len(wire)))
+                cs.send(struct.pack(">H", len(wire)))
                 cs.send(wire)
                 cs.close()
             except s.timeout:
index c7389785035e5701da3ee7173a211df4307ceb59..c2f60e68e536f96bbb7eea5a446a2985b05f3003 100644 (file)
@@ -30,6 +30,7 @@ def logquery(type, qname):
     with open("qlog", "a") as f:
         f.write("%s %s\n", type, qname)
 
+
 ############################################################################
 # Respond to a DNS query.
 # SOA gets a unsigned response.
@@ -54,10 +55,16 @@ def create_response(msg):
         now = datetime.today()
         expire = now + timedelta(days=30)
         inception = now - timedelta(days=1)
-        rrsig = "A 13 2 60 " + expire.strftime("%Y%m%d%H%M%S") + " " + \
-            inception.strftime("%Y%m%d%H%M%S") + " 12345 " + qname + \
-            " gB+eISXAhSPZU2i/II0W9ZUhC2SCIrb94mlNvP5092WAeXxqN/vG43/1nmDl" + \
-           "y2Qs7y5VCjSMOGn85bnaMoAc7w=="
+        rrsig = (
+            "A 13 2 60 "
+            + expire.strftime("%Y%m%d%H%M%S")
+            + " "
+            + inception.strftime("%Y%m%d%H%M%S")
+            + " 12345 "
+            + qname
+            + " gB+eISXAhSPZU2i/II0W9ZUhC2SCIrb94mlNvP5092WAeXxqN/vG43/1nmDl"
+            + "y2Qs7y5VCjSMOGn85bnaMoAc7w=="
+        )
         r.answer.append(dns.rrset.from_text(qname, 1, IN, A, "10.53.0.10"))
         r.answer.append(dns.rrset.from_text(qname, 1, IN, RRSIG, rrsig))
     elif rrtype == NS:
@@ -69,12 +76,14 @@ def create_response(msg):
     r.flags |= dns.flags.AA
     return r
 
+
 def sigterm(signum, frame):
-    print ("Shutting down now...")
-    os.remove('ans.pid')
+    print("Shutting down now...")
+    os.remove("ans.pid")
     running = False
     sys.exit(0)
 
+
 ############################################################################
 # Main
 #
@@ -85,8 +94,10 @@ def sigterm(signum, frame):
 ip4 = "10.53.0.10"
 ip6 = "fd92:7065:b8e:ffff::10"
 
-try: port=int(os.environ['PORT'])
-except: port=5300
+try:
+    port = int(os.environ["PORT"])
+except:
+    port = 5300
 
 query4_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
 query4_socket.bind((ip4, port))
@@ -102,17 +113,17 @@ except:
     havev6 = False
 signal.signal(signal.SIGTERM, sigterm)
 
-f = open('ans.pid', 'w')
+f = open("ans.pid", "w")
 pid = os.getpid()
-print (pid, file=f)
+print(pid, file=f)
 f.close()
 
 running = True
 
-print ("Listening on %s port %d" % (ip4, port))
+print("Listening on %s port %d" % (ip4, port))
 if havev6:
-    print ("Listening on %s port %d" % (ip6, port))
-print ("Ctrl-c to quit")
+    print("Listening on %s port %d" % (ip6, port))
+print("Ctrl-c to quit")
 
 if havev6:
     input = [query4_socket, query6_socket]
@@ -131,8 +142,9 @@ while running:
 
     for s in inputready:
         if s == query4_socket or s == query6_socket:
-            print ("Query received on %s" %
-                    (ip4 if s == query4_socket else ip6), end=" ")
+            print(
+                "Query received on %s" % (ip4 if s == query4_socket else ip6), end=" "
+            )
             # Handle incoming queries
             msg = s.recvfrom(65535)
             rsp = create_response(msg[0])
index 43cd227996cf392c4eae9905ab2bc467419ce4a5..ab7e3c9adad86cfc16003f69f1b5a289af21a8a0 100644 (file)
@@ -22,7 +22,7 @@ import pprint
 
 DNSTAP_READ = sys.argv[1]
 DATAFILE = sys.argv[2]
-ARGS = [DNSTAP_READ, '-y', DATAFILE]
+ARGS = [DNSTAP_READ, "-y", DATAFILE]
 
 with subprocess.Popen(ARGS, stdout=subprocess.PIPE) as f:
     for y in yaml.load_all(f.stdout, Loader=yaml.SafeLoader):
index 1d35b3d3f197f2393c9fcf6591069b4eec510fa3..c043558613908267de08c917b1bd39a879506757 100644 (file)
@@ -30,6 +30,7 @@ def logquery(type, qname):
     with open("qlog", "a") as f:
         f.write("%s %s\n", type, qname)
 
+
 ############################################################################
 # Respond to a DNS query.
 ############################################################################
@@ -46,8 +47,8 @@ def create_response(msg):
     r = dns.message.make_response(m)
     r.set_rcode(NOERROR)
     if rrtype == A:
-        tld=qname.split('.')[-2] + '.'
-        ns="local." + tld
+        tld = qname.split(".")[-2] + "."
+        ns = "local." + tld
         r.answer.append(dns.rrset.from_text(qname, 300, IN, A, "10.53.0.11"))
         r.answer.append(dns.rrset.from_text(tld, 300, IN, NS, "local." + tld))
         r.additional.append(dns.rrset.from_text(ns, 300, IN, A, "10.53.0.11"))
@@ -60,12 +61,14 @@ def create_response(msg):
     r.flags |= dns.flags.AA
     return r
 
+
 def sigterm(signum, frame):
-    print ("Shutting down now...")
-    os.remove('ans.pid')
+    print("Shutting down now...")
+    os.remove("ans.pid")
     running = False
     sys.exit(0)
 
+
 ############################################################################
 # Main
 #
@@ -76,8 +79,10 @@ def sigterm(signum, frame):
 ip4 = "10.53.0.11"
 ip6 = "fd92:7065:b8e:ffff::11"
 
-try: port=int(os.environ['PORT'])
-except: port=5300
+try:
+    port = int(os.environ["PORT"])
+except:
+    port = 5300
 
 query4_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
 query4_socket.bind((ip4, port))
@@ -93,17 +98,17 @@ except:
     havev6 = False
 signal.signal(signal.SIGTERM, sigterm)
 
-f = open('ans.pid', 'w')
+f = open("ans.pid", "w")
 pid = os.getpid()
-print (pid, file=f)
+print(pid, file=f)
 f.close()
 
 running = True
 
-print ("Listening on %s port %d" % (ip4, port))
+print("Listening on %s port %d" % (ip4, port))
 if havev6:
-    print ("Listening on %s port %d" % (ip6, port))
-print ("Ctrl-c to quit")
+    print("Listening on %s port %d" % (ip6, port))
+print("Ctrl-c to quit")
 
 if havev6:
     input = [query4_socket, query6_socket]
@@ -122,8 +127,9 @@ while running:
 
     for s in inputready:
         if s == query4_socket or s == query6_socket:
-            print ("Query received on %s" %
-                    (ip4 if s == query4_socket else ip6), end=" ")
+            print(
+                "Query received on %s" % (ip4 if s == query4_socket else ip6), end=" "
+            )
             # Handle incoming queries
             msg = s.recvfrom(65535)
             rsp = create_response(msg[0])
index 12ac675db5c09d583954d9ad6a8c7ddd458ac123..06806eeb7dc87946832a101be6488e1e684e2cf1 100755 (executable)
@@ -14,29 +14,29 @@ import struct
 
 
 class RawFormatHeader(dict):
-    '''
+    """
     A dictionary of raw-format header fields read from a zone file.
-    '''
+    """
 
     fields = [
-        'format',
-        'version',
-        'dumptime',
-        'flags',
-        'sourceserial',
-        'lastxfrin',
+        "format",
+        "version",
+        "dumptime",
+        "flags",
+        "sourceserial",
+        "lastxfrin",
     ]
 
     def __init__(self, file_name):
-        header = struct.Struct('>IIIIII')
-        with open(file_name, 'rb') as data:
+        header = struct.Struct(">IIIIII")
+        with open(file_name, "rb") as data:
             header_data = data.read(header.size)
         super().__init__(zip(self.fields, header.unpack_from(header_data)))
 
 
 def test_unsigned_serial_number():
 
-    '''
+    """
     Check whether all signed zone files in the "ns8" subdirectory contain the
     serial number of the unsigned version of the zone in the raw-format header.
     The test assumes that all "*.signed" files in the "ns8" subdirectory are in
@@ -51,18 +51,18 @@ def test_unsigned_serial_number():
 
       - example[0-9][0-9].com.db.signed files are initially signed by
         dnssec-signzone while the others - by named.
-    '''
+    """
 
     zones_with_unsigned_serial_missing = []
 
-    for signed_zone in sorted(glob.glob('ns8/*.signed')):
+    for signed_zone in sorted(glob.glob("ns8/*.signed")):
         raw_header = RawFormatHeader(signed_zone)
         # Ensure the unsigned serial number is placed where it is expected.
-        assert raw_header['format'] == 2
-        assert raw_header['version'] == 1
+        assert raw_header["format"] == 2
+        assert raw_header["version"] == 1
         # Check whether the header flags indicate that the unsigned serial
         # number is set and that the latter is indeed set.
-        if raw_header['flags'] & 0x02 == 0 or raw_header['sourceserial'] == 0:
+        if raw_header["flags"] & 0x02 == 0 or raw_header["sourceserial"] == 0:
             zones_with_unsigned_serial_missing.append(signed_zone)
 
     assert not zones_with_unsigned_serial_missing
index e8748dea2e1608580abf4ae05e00bf2db5b7814d..d63a0790b34361fc31aded9fe216dbc189bb4797 100644 (file)
@@ -14,26 +14,26 @@ from isc import policy
 
 PP = policy.dnssec_policy()
 # print the unmodified default and a generated zone policy
-print(PP.named_policy['default'])
-print(PP.named_policy['global'])
-print(PP.policy('example.com'))
+print(PP.named_policy["default"])
+print(PP.named_policy["global"])
+print(PP.policy("example.com"))
 
 if len(sys.argv) > 0:
     for policy_file in sys.argv[1:]:
         PP.load(policy_file)
 
         # now print the modified default and generated zone policies
-        print(PP.named_policy['default'])
-        print(PP.policy('example.com'))
-        print(PP.policy('example.org'))
-        print(PP.policy('example.net'))
+        print(PP.named_policy["default"])
+        print(PP.policy("example.com"))
+        print(PP.policy("example.org"))
+        print(PP.policy("example.net"))
 
         # print algorithm policies
-        print(PP.alg_policy['RSASHA1'])
-        print(PP.alg_policy['RSASHA256'])
-        print(PP.alg_policy['ECDSAP256SHA256'])
+        print(PP.alg_policy["RSASHA1"])
+        print(PP.alg_policy["RSASHA256"])
+        print(PP.alg_policy["ECDSAP256SHA256"])
 
         # print another named policy
-        print(PP.named_policy['extra'])
+        print(PP.named_policy["extra"])
 else:
     print("ERROR: Please provide an input file")
index 0a64033ecbf7666d86545ba72a7e7a9d3ce06890..bac5ed35d80d58ae092fbc2e8bb03996a9d423df 100644 (file)
@@ -47,25 +47,28 @@ import struct
 DELAY = 0.5
 THREADS = []
 
+
 def log(msg):
-    print(datetime.datetime.now().strftime('%d-%b-%Y %H:%M:%S.%f ') + msg)
+    print(datetime.datetime.now().strftime("%d-%b-%Y %H:%M:%S.%f ") + msg)
 
 
 def sigterm(*_):
-    log('SIGTERM received, shutting down')
+    log("SIGTERM received, shutting down")
     for thread in THREADS:
         thread.close()
         thread.join()
-    os.remove('ans.pid')
+    os.remove("ans.pid")
     sys.exit(0)
 
+
 class TCPDelayer(threading.Thread):
-    """ For a given TCP connection conn we open a connection to (ip, port),
-        and then we delay each incoming packet by DELAY by putting it in a
-        queue.
-        In the pipelined test TCP should not be used, but it's here for
-        completnes.
+    """For a given TCP connection conn we open a connection to (ip, port),
+    and then we delay each incoming packet by DELAY by putting it in a
+    queue.
+    In the pipelined test TCP should not be used, but it's here for
+    completnes.
     """
+
     def __init__(self, conn, ip, port):
         threading.Thread.__init__(self)
         self.conn = conn
@@ -81,13 +84,15 @@ class TCPDelayer(threading.Thread):
         while self.running:
             curr_timeout = 0.5
             try:
-                curr_timeout = self.queue[0][0]-time.time()
+                curr_timeout = self.queue[0][0] - time.time()
             except StopIteration:
                 pass
             if curr_timeout > 0:
                 if curr_timeout == 0:
                     curr_timeout = 0.5
-                rfds, _, _ = select.select([self.conn, self.cconn], [], [], curr_timeout)
+                rfds, _, _ = select.select(
+                    [self.conn, self.cconn], [], [], curr_timeout
+                )
                 if self.conn in rfds:
                     data = self.conn.recv(65535)
                     if not data:
@@ -99,17 +104,19 @@ class TCPDelayer(threading.Thread):
                         return
                     self.conn.send(data)
             try:
-                while self.queue[0][0]-time.time() < 0:
+                while self.queue[0][0] - time.time() < 0:
                     _, data = self.queue.pop(0)
                     self.cconn.send(data)
             except StopIteration:
                 pass
 
+
 class UDPDelayer(threading.Thread):
-    """ Every incoming UDP packet is put in a queue for DELAY time, then
-        it's sent to (ip, port). We remember the query id to send the
-        response we get to a proper source, responses are not delayed.
+    """Every incoming UDP packet is put in a queue for DELAY time, then
+    it's sent to (ip, port). We remember the query id to send the
+    response we get to a proper source, responses are not delayed.
     """
+
     def __init__(self, usock, ip, port):
         threading.Thread.__init__(self)
         self.sock = usock
@@ -126,50 +133,56 @@ class UDPDelayer(threading.Thread):
         while self.running:
             curr_timeout = 0.5
             if self.queue:
-                curr_timeout = self.queue[0][0]-time.time()
+                curr_timeout = self.queue[0][0] - time.time()
             if curr_timeout >= 0:
                 if curr_timeout == 0:
                     curr_timeout = 0.5
-                rfds, _, _ = select.select([self.sock, self.csock], [], [], curr_timeout)
+                rfds, _, _ = select.select(
+                    [self.sock, self.csock], [], [], curr_timeout
+                )
                 if self.sock in rfds:
                     data, addr = self.sock.recvfrom(65535)
                     if not data:
                         return
                     self.queue.append((time.time() + DELAY, data))
-                    qid = struct.unpack('>H', data[:2])[0]
-                    log('Received a query from %s, queryid %d' % (str(addr), qid))
+                    qid = struct.unpack(">H", data[:2])[0]
+                    log("Received a query from %s, queryid %d" % (str(addr), qid))
                     self.qid_mapping[qid] = addr
                 if self.csock in rfds:
                     data, addr = self.csock.recvfrom(65535)
                     if not data:
                         return
-                    qid = struct.unpack('>H', data[:2])[0]
+                    qid = struct.unpack(">H", data[:2])[0]
                     dst = self.qid_mapping.get(qid)
                     if dst is not None:
                         self.sock.sendto(data, dst)
-                        log('Received a response from %s, queryid %d, sending to %s' % (str(addr), qid, str(dst)))
-            while self.queue and self.queue[0][0]-time.time() < 0:
+                        log(
+                            "Received a response from %s, queryid %d, sending to %s"
+                            % (str(addr), qid, str(dst))
+                        )
+            while self.queue and self.queue[0][0] - time.time() < 0:
                 _, data = self.queue.pop(0)
-                qid = struct.unpack('>H', data[:2])[0]
-                log('Sending a query to %s, queryid %d' % (str(self.dst), qid))
+                qid = struct.unpack(">H", data[:2])[0]
+                log("Sending a query to %s, queryid %d" % (str(self.dst), qid))
                 self.csock.sendto(data, self.dst)
 
+
 def main():
     signal.signal(signal.SIGTERM, sigterm)
     signal.signal(signal.SIGINT, sigterm)
 
-    with open('ans.pid', 'w') as pidfile:
+    with open("ans.pid", "w") as pidfile:
         print(os.getpid(), file=pidfile)
 
-    listenip = '10.53.0.5'
-    serverip = '10.53.0.2'
+    listenip = "10.53.0.5"
+    serverip = "10.53.0.2"
 
     try:
-        port = int(os.environ['PORT'])
+        port = int(os.environ["PORT"])
     except KeyError:
         port = 5300
 
-    log('Listening on %s:%d' % (listenip, port))
+    log("Listening on %s:%d" % (listenip, port))
 
     usock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
     usock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
@@ -187,12 +200,13 @@ def main():
     while True:
         try:
             (clientsock, _) = sock.accept()
-            log('Accepted connection from %s' % clientsock)
+            log("Accepted connection from %s" % clientsock)
             thread = TCPDelayer(clientsock, serverip, port)
             thread.start()
             THREADS.append(thread)
         except socket.timeout:
             pass
 
-if __name__ == '__main__':
+
+if __name__ == "__main__":
     main()
index 256fb7db8d6cd5091fa34c6e69b208d1bea4a637..55b02f6c58a0d6a830741c78ca7669e4cb22a9a1 100644 (file)
@@ -16,5 +16,6 @@ import os
 import pytest
 
 
-long_test = pytest.mark.skipif(not os.environ.get('CI_ENABLE_ALL_TESTS'),
-                               reason='CI_ENABLE_ALL_TESTS not set')
+long_test = pytest.mark.skipif(
+    not os.environ.get("CI_ENABLE_ALL_TESTS"), reason="CI_ENABLE_ALL_TESTS not set"
+)
index 583b388768e9e39b3c1e2a956d270f9f0d8a9b34..1994ff35db763d7166ed7049c8be8fc8d8149df4 100755 (executable)
@@ -31,9 +31,11 @@ def logquery(type, qname):
     with open("qlog", "a") as f:
         f.write("%s %s\n", type, qname)
 
+
 def endswith(domain, labels):
     return domain.endswith("." + labels) or domain == labels
 
+
 ############################################################################
 # Respond to a DNS query.
 # For good. it serves:
@@ -65,7 +67,7 @@ def create_response(msg):
     m = dns.message.from_wire(msg)
     qname = m.question[0].name.to_text()
     lqname = qname.lower()
-    labels = lqname.split('.')
+    labels = lqname.split(".")
 
     # get qtype
     rrtype = m.question[0].rdtype
@@ -88,22 +90,61 @@ def create_response(msg):
         # Direct query - give direct answer
         if endswith(lqname, "8.2.6.0.1.0.0.2.ip6.arpa."):
             # Delegate to ns3
-            r.authority.append(dns.rrset.from_text("8.2.6.0.1.0.0.2.ip6.arpa.", 60, IN, NS, "ns3.good."))
-            r.additional.append(dns.rrset.from_text("ns3.good.", 60, IN, A, "10.53.0.3"))
-        elif lqname == "1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.8.f.4.0.1.0.0.2.ip6.arpa." and rrtype == PTR:
+            r.authority.append(
+                dns.rrset.from_text(
+                    "8.2.6.0.1.0.0.2.ip6.arpa.", 60, IN, NS, "ns3.good."
+                )
+            )
+            r.additional.append(
+                dns.rrset.from_text("ns3.good.", 60, IN, A, "10.53.0.3")
+            )
+        elif (
+            lqname
+            == "1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.8.f.4.0.1.0.0.2.ip6.arpa."
+            and rrtype == PTR
+        ):
             # Direct query - give direct answer
-            r.answer.append(dns.rrset.from_text("1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.8.f.4.0.1.0.0.2.ip6.arpa.", 1, IN, PTR, "nee.com."))
+            r.answer.append(
+                dns.rrset.from_text(
+                    "1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.8.f.4.0.1.0.0.2.ip6.arpa.",
+                    1,
+                    IN,
+                    PTR,
+                    "nee.com.",
+                )
+            )
             r.flags |= dns.flags.AA
         elif lqname == "1.0.0.2.ip6.arpa." and rrtype == NS:
             # NS query at the apex
-            r.answer.append(dns.rrset.from_text("1.0.0.2.ip6.arpa.", 30, IN, NS, "ns2.good."))
+            r.answer.append(
+                dns.rrset.from_text("1.0.0.2.ip6.arpa.", 30, IN, NS, "ns2.good.")
+            )
             r.flags |= dns.flags.AA
-        elif endswith("1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.8.f.4.0.1.0.0.2.ip6.arpa.", lqname):
+        elif endswith(
+            "1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.8.f.4.0.1.0.0.2.ip6.arpa.",
+            lqname,
+        ):
             # NODATA answer
-            r.authority.append(dns.rrset.from_text("1.0.0.2.ip6.arpa.", 30, IN, SOA, "ns2.good. hostmaster.arpa. 2018050100 1 1 1 1"))
+            r.authority.append(
+                dns.rrset.from_text(
+                    "1.0.0.2.ip6.arpa.",
+                    30,
+                    IN,
+                    SOA,
+                    "ns2.good. hostmaster.arpa. 2018050100 1 1 1 1",
+                )
+            )
         else:
             # NXDOMAIN
-            r.authority.append(dns.rrset.from_text("1.0.0.2.ip6.arpa.", 30, IN, SOA, "ns2.good. hostmaster.arpa. 2018050100 1 1 1 1"))
+            r.authority.append(
+                dns.rrset.from_text(
+                    "1.0.0.2.ip6.arpa.",
+                    30,
+                    IN,
+                    SOA,
+                    "ns2.good. hostmaster.arpa. 2018050100 1 1 1 1",
+                )
+            )
             r.set_rcode(NXDOMAIN)
         return r
     elif endswith(lqname, "ip6.arpa."):
@@ -113,35 +154,71 @@ def create_response(msg):
             r.flags |= dns.flags.AA
         elif endswith("1.0.0.2.ip6.arpa.", lqname):
             # NODATA answer
-            r.authority.append(dns.rrset.from_text("ip6.arpa.", 30, IN, SOA, "ns2.good. hostmaster.arpa. 2018050100 1 1 1 1"))
+            r.authority.append(
+                dns.rrset.from_text(
+                    "ip6.arpa.",
+                    30,
+                    IN,
+                    SOA,
+                    "ns2.good. hostmaster.arpa. 2018050100 1 1 1 1",
+                )
+            )
         else:
             # NXDOMAIN
-            r.authority.append(dns.rrset.from_text("ip6.arpa.", 30, IN, SOA, "ns2.good. hostmaster.arpa. 2018050100 1 1 1 1"))
+            r.authority.append(
+                dns.rrset.from_text(
+                    "ip6.arpa.",
+                    30,
+                    IN,
+                    SOA,
+                    "ns2.good. hostmaster.arpa. 2018050100 1 1 1 1",
+                )
+            )
             r.set_rcode(NXDOMAIN)
         return r
     elif endswith(lqname, "stale."):
         if endswith(lqname, "a.b.stale."):
             # Delegate to ns.a.b.stale.
-            r.authority.append(dns.rrset.from_text("a.b.stale.", 2, IN, NS, "ns.a.b.stale."))
-            r.additional.append(dns.rrset.from_text("ns.a.b.stale.", 2, IN, A, "10.53.0.3"))
+            r.authority.append(
+                dns.rrset.from_text("a.b.stale.", 2, IN, NS, "ns.a.b.stale.")
+            )
+            r.additional.append(
+                dns.rrset.from_text("ns.a.b.stale.", 2, IN, A, "10.53.0.3")
+            )
         elif endswith(lqname, "b.stale."):
             # Delegate to ns.b.stale.
-            r.authority.append(dns.rrset.from_text("b.stale.", 2, IN, NS, "ns.b.stale."))
-            r.additional.append(dns.rrset.from_text("ns.b.stale.", 2, IN, A, "10.53.0.4"))
+            r.authority.append(
+                dns.rrset.from_text("b.stale.", 2, IN, NS, "ns.b.stale.")
+            )
+            r.additional.append(
+                dns.rrset.from_text("ns.b.stale.", 2, IN, A, "10.53.0.4")
+            )
         elif lqname == "stale." and rrtype == NS:
             # NS query at the apex.
             r.answer.append(dns.rrset.from_text("stale.", 2, IN, NS, "ns2.stale."))
             r.flags |= dns.flags.AA
         elif lqname == "stale." and rrtype == SOA:
             # SOA query at the apex.
-            r.answer.append(dns.rrset.from_text("stale.", 2, IN, SOA, "ns2.stale. hostmaster.stale. 1 2 3 4 5"))
+            r.answer.append(
+                dns.rrset.from_text(
+                    "stale.", 2, IN, SOA, "ns2.stale. hostmaster.stale. 1 2 3 4 5"
+                )
+            )
             r.flags |= dns.flags.AA
         elif lqname == "stale.":
             # NODATA answer
-            r.authority.append(dns.rrset.from_text("stale.", 2, IN, SOA, "ns2.stale. hostmaster.arpa. 1 2 3 4 5"))
+            r.authority.append(
+                dns.rrset.from_text(
+                    "stale.", 2, IN, SOA, "ns2.stale. hostmaster.arpa. 1 2 3 4 5"
+                )
+            )
         else:
             # NXDOMAIN
-            r.authority.append(dns.rrset.from_text("stale.", 2, IN, SOA, "ns2.stale. hostmaster.arpa. 1 2 3 4 5"))
+            r.authority.append(
+                dns.rrset.from_text(
+                    "stale.", 2, IN, SOA, "ns2.stale. hostmaster.arpa. 1 2 3 4 5"
+                )
+            )
             r.set_rcode(NXDOMAIN)
         return r
     elif endswith(lqname, "bad."):
@@ -168,43 +245,72 @@ def create_response(msg):
 
     # Good/bad/ugly differs only in how we treat non-empty terminals
     if endswith(lqname, "zoop.boing."):
-        r.authority.append(dns.rrset.from_text("zoop.boing." + suffix, 1, IN, NS, "ns3." + suffix))
-    elif lqname == "many.labels.a.b.c.d.e.f.g.h.i.j.k.l.m.n.o.p.q.r.s.t.u.v.w.x.y.z." and rrtype == A:
+        r.authority.append(
+            dns.rrset.from_text("zoop.boing." + suffix, 1, IN, NS, "ns3." + suffix)
+        )
+    elif (
+        lqname == "many.labels.a.b.c.d.e.f.g.h.i.j.k.l.m.n.o.p.q.r.s.t.u.v.w.x.y.z."
+        and rrtype == A
+    ):
         r.answer.append(dns.rrset.from_text(lqname + suffix, 1, IN, A, "192.0.2.2"))
         r.flags |= dns.flags.AA
     elif lqname == "" and rrtype == NS:
         r.answer.append(dns.rrset.from_text(suffix, 30, IN, NS, "ns2." + suffix))
         r.flags |= dns.flags.AA
     elif lqname == "ns2." and rrtype == A:
-        r.answer.append(dns.rrset.from_text("ns2."+suffix, 30, IN, A, "10.53.0.2"))
+        r.answer.append(dns.rrset.from_text("ns2." + suffix, 30, IN, A, "10.53.0.2"))
         r.flags |= dns.flags.AA
     elif lqname == "ns2." and rrtype == AAAA:
-        r.answer.append(dns.rrset.from_text("ns2."+suffix, 30, IN, AAAA, "fd92:7065:b8e:ffff::2"))
+        r.answer.append(
+            dns.rrset.from_text("ns2." + suffix, 30, IN, AAAA, "fd92:7065:b8e:ffff::2")
+        )
         r.flags |= dns.flags.AA
     elif lqname == "ns3." and rrtype == A:
-        r.answer.append(dns.rrset.from_text("ns3."+suffix, 30, IN, A, "10.53.0.3"))
+        r.answer.append(dns.rrset.from_text("ns3." + suffix, 30, IN, A, "10.53.0.3"))
         r.flags |= dns.flags.AA
     elif lqname == "ns3." and rrtype == AAAA:
-        r.answer.append(dns.rrset.from_text("ns3."+suffix, 30, IN, AAAA, "fd92:7065:b8e:ffff::3"))
+        r.answer.append(
+            dns.rrset.from_text("ns3." + suffix, 30, IN, AAAA, "fd92:7065:b8e:ffff::3")
+        )
         r.flags |= dns.flags.AA
     elif lqname == "ns4." and rrtype == A:
-        r.answer.append(dns.rrset.from_text("ns4."+suffix, 30, IN, A, "10.53.0.4"))
+        r.answer.append(dns.rrset.from_text("ns4." + suffix, 30, IN, A, "10.53.0.4"))
         r.flags |= dns.flags.AA
     elif lqname == "ns4." and rrtype == AAAA:
-        r.answer.append(dns.rrset.from_text("ns4."+suffix, 30, IN, AAAA, "fd92:7065:b8e:ffff::4"))
+        r.answer.append(
+            dns.rrset.from_text("ns4." + suffix, 30, IN, AAAA, "fd92:7065:b8e:ffff::4")
+        )
         r.flags |= dns.flags.AA
     elif lqname == "a.bit.longer.ns.name." and rrtype == A:
-        r.answer.append(dns.rrset.from_text("a.bit.longer.ns.name."+suffix, 1, IN, A, "10.53.0.4"))
+        r.answer.append(
+            dns.rrset.from_text("a.bit.longer.ns.name." + suffix, 1, IN, A, "10.53.0.4")
+        )
         r.flags |= dns.flags.AA
     elif lqname == "a.bit.longer.ns.name." and rrtype == AAAA:
-        r.answer.append(dns.rrset.from_text("a.bit.longer.ns.name."+suffix, 1, IN, AAAA, "fd92:7065:b8e:ffff::4"))
+        r.answer.append(
+            dns.rrset.from_text(
+                "a.bit.longer.ns.name." + suffix, 1, IN, AAAA, "fd92:7065:b8e:ffff::4"
+            )
+        )
         r.flags |= dns.flags.AA
     else:
-        r.authority.append(dns.rrset.from_text(suffix, 1, IN, SOA, "ns2." + suffix + " hostmaster.arpa. 2018050100 1 1 1 1"))
-        if bad or not \
-            (endswith("icky.icky.icky.ptang.zoop.boing.", lqname) or \
-             endswith("many.labels.a.b.c.d.e.f.g.h.i.j.k.l.m.n.o.p.q.r.s.t.u.v.w.x.y.z.", lqname) or \
-             endswith("a.bit.longer.ns.name.", lqname)):
+        r.authority.append(
+            dns.rrset.from_text(
+                suffix,
+                1,
+                IN,
+                SOA,
+                "ns2." + suffix + " hostmaster.arpa. 2018050100 1 1 1 1",
+            )
+        )
+        if bad or not (
+            endswith("icky.icky.icky.ptang.zoop.boing.", lqname)
+            or endswith(
+                "many.labels.a.b.c.d.e.f.g.h.i.j.k.l.m.n.o.p.q.r.s.t.u.v.w.x.y.z.",
+                lqname,
+            )
+            or endswith("a.bit.longer.ns.name.", lqname)
+        ):
             r.set_rcode(NXDOMAIN)
         if ugly:
             r.set_rcode(FORMERR)
@@ -214,11 +320,12 @@ def create_response(msg):
 
 
 def sigterm(signum, frame):
-    print ("Shutting down now...")
-    os.remove('ans.pid')
+    print("Shutting down now...")
+    os.remove("ans.pid")
     running = False
     sys.exit(0)
 
+
 ############################################################################
 # Main
 #
@@ -229,8 +336,10 @@ def sigterm(signum, frame):
 ip4 = "10.53.0.2"
 ip6 = "fd92:7065:b8e:ffff::2"
 
-try: port=int(os.environ['PORT'])
-except: port=5300
+try:
+    port = int(os.environ["PORT"])
+except:
+    port = 5300
 
 query4_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
 query4_socket.bind((ip4, port))
@@ -248,17 +357,17 @@ except:
 
 signal.signal(signal.SIGTERM, sigterm)
 
-f = open('ans.pid', 'w')
+f = open("ans.pid", "w")
 pid = os.getpid()
-print (pid, file=f)
+print(pid, file=f)
 f.close()
 
 running = True
 
-print ("Listening on %s port %d" % (ip4, port))
+print("Listening on %s port %d" % (ip4, port))
 if havev6:
-    print ("Listening on %s port %d" % (ip6, port))
-print ("Ctrl-c to quit")
+    print("Listening on %s port %d" % (ip6, port))
+print("Ctrl-c to quit")
 
 if havev6:
     input = [query4_socket, query6_socket]
@@ -277,8 +386,9 @@ while running:
 
     for s in inputready:
         if s == query4_socket or s == query6_socket:
-            print ("Query received on %s" %
-                    (ip4 if s == query4_socket else ip6), end=" ")
+            print(
+                "Query received on %s" % (ip4 if s == query4_socket else ip6), end=" "
+            )
             # Handle incoming queries
             msg = s.recvfrom(65535)
             rsp = create_response(msg[0])
index 7416e6f18f9cca4936f227d6862ab19509d8f939..b2883a1b7d6c31e784bb9e6ba0eace4248f4a7ee 100755 (executable)
@@ -31,9 +31,11 @@ def logquery(type, qname):
     with open("qlog", "a") as f:
         f.write("%s %s\n", type, qname)
 
+
 def endswith(domain, labels):
     return domain.endswith("." + labels) or domain == labels
 
+
 ############################################################################
 # Respond to a DNS query.
 # For good. it serves:
@@ -54,7 +56,7 @@ def create_response(msg):
     m = dns.message.from_wire(msg)
     qname = m.question[0].name.to_text()
     lqname = qname.lower()
-    labels = lqname.split('.')
+    labels = lqname.split(".")
 
     # get qtype
     rrtype = m.question[0].rdtype
@@ -101,17 +103,31 @@ def create_response(msg):
             elif rrtype == NS:
                 # NS a.b.
                 r.answer.append(dns.rrset.from_text(lqname, 1, IN, NS, "ns.a.b.stale."))
-                r.additional.append(dns.rrset.from_text("ns.a.b.stale.", 1, IN, A, "10.53.0.3"))
+                r.additional.append(
+                    dns.rrset.from_text("ns.a.b.stale.", 1, IN, A, "10.53.0.3")
+                )
                 r.flags |= dns.flags.AA
             elif rrtype == SOA:
                 # SOA a.b.
-                r.answer.append(dns.rrset.from_text(lqname, 1, IN, SOA, "a.b.stale. hostmaster.a.b.stale. 1 2 3 4 5"))
+                r.answer.append(
+                    dns.rrset.from_text(
+                        lqname, 1, IN, SOA, "a.b.stale. hostmaster.a.b.stale. 1 2 3 4 5"
+                    )
+                )
                 r.flags |= dns.flags.AA
             else:
                 # NODATA.
-                r.authority.append(dns.rrset.from_text(lqname, 1, IN, SOA, "a.b.stale. hostmaster.a.b.stale. 1 2 3 4 5"))
+                r.authority.append(
+                    dns.rrset.from_text(
+                        lqname, 1, IN, SOA, "a.b.stale. hostmaster.a.b.stale. 1 2 3 4 5"
+                    )
+                )
         else:
-            r.authority.append(dns.rrset.from_text(lqname, 1, IN, SOA, "a.b.stale. hostmaster.a.b.stale. 1 2 3 4 5"))
+            r.authority.append(
+                dns.rrset.from_text(
+                    lqname, 1, IN, SOA, "a.b.stale. hostmaster.a.b.stale. 1 2 3 4 5"
+                )
+            )
             r.set_rcode(NXDOMAIN)
             # NXDOMAIN.
         return r
@@ -121,21 +137,51 @@ def create_response(msg):
 
     # Good/bad differs only in how we treat non-empty terminals
     if lqname == "zoop.boing." and rrtype == NS:
-        r.answer.append(dns.rrset.from_text(lqname + suffix, 1, IN, NS, "ns3."+suffix))
+        r.answer.append(
+            dns.rrset.from_text(lqname + suffix, 1, IN, NS, "ns3." + suffix)
+        )
         r.flags |= dns.flags.AA
     elif endswith(lqname, "icky.ptang.zoop.boing."):
-        r.authority.append(dns.rrset.from_text("icky.ptang.zoop.boing." + suffix, 1, IN, NS, "a.bit.longer.ns.name." + suffix))
+        r.authority.append(
+            dns.rrset.from_text(
+                "icky.ptang.zoop.boing." + suffix,
+                1,
+                IN,
+                NS,
+                "a.bit.longer.ns.name." + suffix,
+            )
+        )
     elif endswith("icky.ptang.zoop.boing.", lqname):
-        r.authority.append(dns.rrset.from_text("zoop.boing." + suffix, 1, IN, SOA, "ns3." + suffix + " hostmaster.arpa. 2018050100 1 1 1 1"))
+        r.authority.append(
+            dns.rrset.from_text(
+                "zoop.boing." + suffix,
+                1,
+                IN,
+                SOA,
+                "ns3." + suffix + " hostmaster.arpa. 2018050100 1 1 1 1",
+            )
+        )
         if bad:
             r.set_rcode(NXDOMAIN)
         if ugly:
             r.set_rcode(FORMERR)
     elif endswith(lqname, "zoop.boing."):
-        r.authority.append(dns.rrset.from_text("zoop.boing." + suffix, 1, IN, SOA, "ns3." + suffix + " hostmaster.arpa. 2018050100 1 1 1 1"))
+        r.authority.append(
+            dns.rrset.from_text(
+                "zoop.boing." + suffix,
+                1,
+                IN,
+                SOA,
+                "ns3." + suffix + " hostmaster.arpa. 2018050100 1 1 1 1",
+            )
+        )
         r.set_rcode(NXDOMAIN)
     elif ip6req:
-        r.authority.append(dns.rrset.from_text("1.1.1.1.8.2.6.0.1.0.0.2.ip6.arpa.", 60, IN, NS, "ns4.good."))
+        r.authority.append(
+            dns.rrset.from_text(
+                "1.1.1.1.8.2.6.0.1.0.0.2.ip6.arpa.", 60, IN, NS, "ns4.good."
+            )
+        )
         r.additional.append(dns.rrset.from_text("ns4.good.", 60, IN, A, "10.53.0.4"))
     else:
         r.set_rcode(REFUSED)
@@ -146,11 +192,12 @@ def create_response(msg):
 
 
 def sigterm(signum, frame):
-    print ("Shutting down now...")
-    os.remove('ans.pid')
+    print("Shutting down now...")
+    os.remove("ans.pid")
     running = False
     sys.exit(0)
 
+
 ############################################################################
 # Main
 #
@@ -161,8 +208,10 @@ def sigterm(signum, frame):
 ip4 = "10.53.0.3"
 ip6 = "fd92:7065:b8e:ffff::3"
 
-try: port=int(os.environ['PORT'])
-except: port=5300
+try:
+    port = int(os.environ["PORT"])
+except:
+    port = 5300
 
 query4_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
 query4_socket.bind((ip4, port))
@@ -180,17 +229,17 @@ except:
 
 signal.signal(signal.SIGTERM, sigterm)
 
-f = open('ans.pid', 'w')
+f = open("ans.pid", "w")
 pid = os.getpid()
-print (pid, file=f)
+print(pid, file=f)
 f.close()
 
 running = True
 
-print ("Listening on %s port %d" % (ip4, port))
+print("Listening on %s port %d" % (ip4, port))
 if havev6:
-    print ("Listening on %s port %d" % (ip6, port))
-print ("Ctrl-c to quit")
+    print("Listening on %s port %d" % (ip6, port))
+print("Ctrl-c to quit")
 
 if havev6:
     input = [query4_socket, query6_socket]
@@ -209,8 +258,9 @@ while running:
 
     for s in inputready:
         if s == query4_socket or s == query6_socket:
-            print ("Query received on %s" %
-                    (ip4 if s == query4_socket else ip6), end=" ")
+            print(
+                "Query received on %s" % (ip4 if s == query4_socket else ip6), end=" "
+            )
             # Handle incoming queries
             msg = s.recvfrom(65535)
             rsp = create_response(msg[0])
index 2c672c8e7186146e2c532814845d2ef5c6657080..a4cc13c656e159b6b6fb6b919a442b2f5ea867ca 100755 (executable)
@@ -31,9 +31,11 @@ def logquery(type, qname):
     with open("qlog", "a") as f:
         f.write("%s %s\n", type, qname)
 
+
 def endswith(domain, labels):
     return domain.endswith("." + labels) or domain == labels
 
+
 ############################################################################
 # Respond to a DNS query.
 # For good. it serves:
@@ -55,7 +57,7 @@ def create_response(msg):
     m = dns.message.from_wire(msg)
     qname = m.question[0].name.to_text()
     lqname = qname.lower()
-    labels = lqname.split('.')
+    labels = lqname.split(".")
 
     # get qtype
     rrtype = m.question[0].rdtype
@@ -102,30 +104,54 @@ def create_response(msg):
             elif rrtype == NS:
                 # NS a.b.
                 r.answer.append(dns.rrset.from_text(lqname, 1, IN, NS, "ns.a.b.stale."))
-                r.additional.append(dns.rrset.from_text("ns.a.b.stale.", 1, IN, A, "10.53.0.3"))
+                r.additional.append(
+                    dns.rrset.from_text("ns.a.b.stale.", 1, IN, A, "10.53.0.3")
+                )
                 r.flags |= dns.flags.AA
             elif rrtype == SOA:
                 # SOA a.b.
-                r.answer.append(dns.rrset.from_text(lqname, 1, IN, SOA, "a.b.stale. hostmaster.a.b.stale. 1 2 3 4 5"))
+                r.answer.append(
+                    dns.rrset.from_text(
+                        lqname, 1, IN, SOA, "a.b.stale. hostmaster.a.b.stale. 1 2 3 4 5"
+                    )
+                )
                 r.flags |= dns.flags.AA
             else:
                 # NODATA.
-                r.authority.append(dns.rrset.from_text(lqname, 1, IN, SOA, "a.b.stale. hostmaster.a.b.stale. 1 2 3 4 5"))
+                r.authority.append(
+                    dns.rrset.from_text(
+                        lqname, 1, IN, SOA, "a.b.stale. hostmaster.a.b.stale. 1 2 3 4 5"
+                    )
+                )
         elif lqname == "b.stale.":
             if rrtype == NS:
                 # NS b.
                 r.answer.append(dns.rrset.from_text(lqname, 1, IN, NS, "ns.b.stale."))
-                r.additional.append(dns.rrset.from_text("ns.b.stale.", 1, IN, A, "10.53.0.4"))
+                r.additional.append(
+                    dns.rrset.from_text("ns.b.stale.", 1, IN, A, "10.53.0.4")
+                )
                 r.flags |= dns.flags.AA
             elif rrtype == SOA:
                 # SOA b.
-                r.answer.append(dns.rrset.from_text(lqname, 1, IN, SOA, "b.stale. hostmaster.b.stale. 1 2 3 4 5"))
+                r.answer.append(
+                    dns.rrset.from_text(
+                        lqname, 1, IN, SOA, "b.stale. hostmaster.b.stale. 1 2 3 4 5"
+                    )
+                )
                 r.flags |= dns.flags.AA
             else:
                 # NODATA.
-                r.authority.append(dns.rrset.from_text(lqname, 1, IN, SOA, "b.stale. hostmaster.b.stale. 1 2 3 4 5"))
+                r.authority.append(
+                    dns.rrset.from_text(
+                        lqname, 1, IN, SOA, "b.stale. hostmaster.b.stale. 1 2 3 4 5"
+                    )
+                )
         else:
-            r.authority.append(dns.rrset.from_text(lqname, 1, IN, SOA, "b.stale. hostmaster.b.stale. 1 2 3 4 5"))
+            r.authority.append(
+                dns.rrset.from_text(
+                    lqname, 1, IN, SOA, "b.stale. hostmaster.b.stale. 1 2 3 4 5"
+                )
+            )
             r.set_rcode(NXDOMAIN)
             # NXDOMAIN.
         return r
@@ -141,24 +167,67 @@ def create_response(msg):
         r.answer.append(dns.rrset.from_text(lqname + suffix, 1, IN, A, "192.0.2.2"))
         r.flags |= dns.flags.AA
     elif lqname == "icky.ptang.zoop.boing." and rrtype == NS:
-        r.answer.append(dns.rrset.from_text(lqname + suffix, 1, IN, NS, "a.bit.longer.ns.name."+suffix))
+        r.answer.append(
+            dns.rrset.from_text(
+                lqname + suffix, 1, IN, NS, "a.bit.longer.ns.name." + suffix
+            )
+        )
         r.flags |= dns.flags.AA
     elif endswith(lqname, "icky.ptang.zoop.boing."):
-        r.authority.append(dns.rrset.from_text("icky.ptang.zoop.boing." + suffix, 1, IN, SOA, "ns2." + suffix + " hostmaster.arpa. 2018050100 1 1 1 1"))
+        r.authority.append(
+            dns.rrset.from_text(
+                "icky.ptang.zoop.boing." + suffix,
+                1,
+                IN,
+                SOA,
+                "ns2." + suffix + " hostmaster.arpa. 2018050100 1 1 1 1",
+            )
+        )
         if bad or not endswith("more.icky.icky.icky.ptang.zoop.boing.", lqname):
             r.set_rcode(NXDOMAIN)
         if ugly:
             r.set_rcode(FORMERR)
     elif ip6req:
         r.flags |= dns.flags.AA
-        if lqname == "test1.test2.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.9.0.9.4.1.1.1.1.8.2.6.0.1.0.0.2.ip6.arpa." and rrtype == TXT:
-            r.answer.append(dns.rrset.from_text("test1.test2.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.9.0.9.4.1.1.1.1.8.2.6.0.1.0.0.2.ip6.arpa.", 1, IN, TXT, "long_ip6_name"))
-        elif endswith("0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.9.0.9.4.1.1.1.1.8.2.6.0.1.0.0.2.ip6.arpa.", lqname):
-            #NODATA answer
-            r.authority.append(dns.rrset.from_text("1.1.1.1.8.2.6.0.1.0.0.2.ip6.arpa.", 60, IN, SOA, "ns4.good. hostmaster.arpa. 2018050100 120 30 320 16"))
+        if (
+            lqname
+            == "test1.test2.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.9.0.9.4.1.1.1.1.8.2.6.0.1.0.0.2.ip6.arpa."
+            and rrtype == TXT
+        ):
+            r.answer.append(
+                dns.rrset.from_text(
+                    "test1.test2.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.9.0.9.4.1.1.1.1.8.2.6.0.1.0.0.2.ip6.arpa.",
+                    1,
+                    IN,
+                    TXT,
+                    "long_ip6_name",
+                )
+            )
+        elif endswith(
+            "0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.9.0.9.4.1.1.1.1.8.2.6.0.1.0.0.2.ip6.arpa.",
+            lqname,
+        ):
+            # NODATA answer
+            r.authority.append(
+                dns.rrset.from_text(
+                    "1.1.1.1.8.2.6.0.1.0.0.2.ip6.arpa.",
+                    60,
+                    IN,
+                    SOA,
+                    "ns4.good. hostmaster.arpa. 2018050100 120 30 320 16",
+                )
+            )
         else:
             # NXDOMAIN
-            r.authority.append(dns.rrset.from_text("1.1.1.1.8.2.6.0.1.0.0.2.ip6.arpa.", 60, IN, SOA, "ns4.good. hostmaster.arpa. 2018050100 120 30 320 16"))
+            r.authority.append(
+                dns.rrset.from_text(
+                    "1.1.1.1.8.2.6.0.1.0.0.2.ip6.arpa.",
+                    60,
+                    IN,
+                    SOA,
+                    "ns4.good. hostmaster.arpa. 2018050100 120 30 320 16",
+                )
+            )
             r.set_rcode(NXDOMAIN)
     else:
         r.set_rcode(REFUSED)
@@ -169,11 +238,12 @@ def create_response(msg):
 
 
 def sigterm(signum, frame):
-    print ("Shutting down now...")
-    os.remove('ans.pid')
+    print("Shutting down now...")
+    os.remove("ans.pid")
     running = False
     sys.exit(0)
 
+
 ############################################################################
 # Main
 #
@@ -184,8 +254,10 @@ def sigterm(signum, frame):
 ip4 = "10.53.0.4"
 ip6 = "fd92:7065:b8e:ffff::4"
 
-try: port=int(os.environ['PORT'])
-except: port=5300
+try:
+    port = int(os.environ["PORT"])
+except:
+    port = 5300
 
 query4_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
 query4_socket.bind((ip4, port))
@@ -203,17 +275,17 @@ except:
 
 signal.signal(signal.SIGTERM, sigterm)
 
-f = open('ans.pid', 'w')
+f = open("ans.pid", "w")
 pid = os.getpid()
-print (pid, file=f)
+print(pid, file=f)
 f.close()
 
 running = True
 
-print ("Listening on %s port %d" % (ip4, port))
+print("Listening on %s port %d" % (ip4, port))
 if havev6:
-    print ("Listening on %s port %d" % (ip6, port))
-print ("Ctrl-c to quit")
+    print("Listening on %s port %d" % (ip6, port))
+print("Ctrl-c to quit")
 
 if havev6:
     input = [query4_socket, query6_socket]
@@ -232,8 +304,9 @@ while running:
 
     for s in inputready:
         if s == query4_socket or s == query6_socket:
-            print ("Query received on %s" %
-                    (ip4 if s == query4_socket else ip6), end=" ")
+            print(
+                "Query received on %s" % (ip4 if s == query4_socket else ip6), end=" "
+            )
             # Handle incoming queries
             msg = s.recvfrom(65535)
             rsp = create_response(msg[0])
index 56077391008983c8949805392e320a6861970cac..2c8c446971dda5f7006290659996d2437c0fcfc3 100755 (executable)
@@ -21,47 +21,47 @@ import time
 
 import pytest
 
-pytest.importorskip('dns')
+pytest.importorskip("dns")
 import dns.exception
 import dns.resolver
 
 
 def do_work(named_proc, resolver, rndc_cmd, kill_method, n_workers, n_queries):
     """Creates a number of A queries to run in parallel
-       in order simulate a slightly more realistic test scenario.
+    in order simulate a slightly more realistic test scenario.
 
-       The main idea of this function is to create and send a bunch
-       of A queries to a target named instance and during this process
-       a request for shutting down named will be issued.
+    The main idea of this function is to create and send a bunch
+    of A queries to a target named instance and during this process
+    a request for shutting down named will be issued.
 
-       In the process of shutting down named, a couple control connections
-       are created (by launching rndc) to ensure that the crash was fixed.
+    In the process of shutting down named, a couple control connections
+    are created (by launching rndc) to ensure that the crash was fixed.
 
-       if kill_method=="rndc" named will be asked to shutdown by
-       means of rndc stop.
-       if kill_method=="sigterm" named will be killed by SIGTERM on
-       POSIX systems or by TerminateProcess() on Windows systems.
+    if kill_method=="rndc" named will be asked to shutdown by
+    means of rndc stop.
+    if kill_method=="sigterm" named will be killed by SIGTERM on
+    POSIX systems or by TerminateProcess() on Windows systems.
 
-       :param named_proc: named process instance
-       :type named_proc: subprocess.Popen
+    :param named_proc: named process instance
+    :type named_proc: subprocess.Popen
 
-       :param resolver: target resolver
-       :type resolver: dns.resolver.Resolver
+    :param resolver: target resolver
+    :type resolver: dns.resolver.Resolver
 
-       :param rndc_cmd: rndc command with default arguments
-       :type rndc_cmd: list of strings, e.g. ["rndc", "-p", "23750"]
+    :param rndc_cmd: rndc command with default arguments
+    :type rndc_cmd: list of strings, e.g. ["rndc", "-p", "23750"]
 
-       :kill_method: "rndc" or "sigterm"
-       :type kill_method: str
+    :kill_method: "rndc" or "sigterm"
+    :type kill_method: str
 
-       :param n_workers: Number of worker threads to create
-       :type n_workers: int
+    :param n_workers: Number of worker threads to create
+    :type n_workers: int
 
-       :param n_queries: Total number of queries to send
-       :type n_queries: int
+    :param n_queries: Total number of queries to send
+    :type n_queries: int
     """
-# pylint: disable-msg=too-many-arguments
-# pylint: disable-msg=too-many-locals
+    # pylint: disable-msg=too-many-arguments
+    # pylint: disable-msg=too-many-locals
 
     # helper function, args must be a list or tuple with arguments to rndc.
     def launch_rndc(args):
@@ -91,21 +91,22 @@ def do_work(named_proc, resolver, rndc_cmd, kill_method, n_workers, n_queries):
                 else:
                     tag = "bad"
                     length = random.randint(4, 10)
-                    relname = "".join(letters[
-                        random.randrange(len(letters))] for i in range(length))
+                    relname = "".join(
+                        letters[random.randrange(len(letters))] for i in range(length)
+                    )
 
                 qname = relname + ".test"
-                futures[executor.submit(resolver.query, qname, 'A')] = tag
+                futures[executor.submit(resolver.query, qname, "A")] = tag
             elif shutdown:  # We attempt to stop named in the middle
                 shutdown = False
                 if kill_method == "rndc":
-                    futures[executor.submit(launch_rndc, ['stop'])] = 'stop'
+                    futures[executor.submit(launch_rndc, ["stop"])] = "stop"
                 else:
-                    futures[executor.submit(named_proc.terminate)] = 'kill'
+                    futures[executor.submit(named_proc.terminate)] = "kill"
             else:
                 # We attempt to send couple rndc commands while named is
                 # being shutdown
-                futures[executor.submit(launch_rndc, ['status'])] = 'status'
+                futures[executor.submit(launch_rndc, ["status"])] = "status"
 
         ret_code = -1
         for future in as_completed(futures):
@@ -120,9 +121,11 @@ def do_work(named_proc, resolver, rndc_cmd, kill_method, n_workers, n_queries):
                 if futures[future] == "stop":
                     ret_code = result
 
-            except (dns.resolver.NXDOMAIN,
-                    dns.resolver.NoNameservers,
-                    dns.exception.Timeout):
+            except (
+                dns.resolver.NXDOMAIN,
+                dns.resolver.NoNameservers,
+                dns.exception.Timeout,
+            ):
                 pass
 
         if kill_method == "rndc":
@@ -151,12 +154,11 @@ def test_named_shutdown(named_port, control_port):
     assert os.path.isfile(rndc_cfg)
 
     # rndc command with default arguments.
-    rndc_cmd = [rndc, "-c", rndc_cfg, "-p", str(control_port),
-                "-s", "10.53.0.3"]
+    rndc_cmd = [rndc, "-c", rndc_cfg, "-p", str(control_port), "-s", "10.53.0.3"]
 
     # We create a resolver instance that will be used to send queries.
     resolver = dns.resolver.Resolver()
-    resolver.nameservers = ['10.53.0.3']
+    resolver.nameservers = ["10.53.0.3"]
     resolver.port = named_port
 
     # We test named shutting down using two methods:
@@ -171,13 +173,14 @@ def test_named_shutdown(named_port, control_port):
             # wait for named to finish loading
             for _ in range(10):
                 try:
-                    resolver.query('version.bind', 'TXT', 'CH')
+                    resolver.query("version.bind", "TXT", "CH")
                     break
                 except (dns.resolver.NoNameservers, dns.exception.Timeout):
                     time.sleep(1)
 
-            do_work(named_proc, resolver, rndc_cmd,
-                    kill_method, n_workers=12, n_queries=16)
+            do_work(
+                named_proc, resolver, rndc_cmd, kill_method, n_workers=12, n_queries=16
+            )
 
             # Wait named to exit for a maximum of MAX_TIMEOUT seconds.
             MAX_TIMEOUT = 10
index e4cf82cec563e45127c8b2f295902218ec329df3..6688ff6db0a89d28690bda1346a94e438ab65daf 100644 (file)
@@ -14,7 +14,7 @@ import os
 
 
 # ISO datetime format without msec
-fmt = '%Y-%m-%dT%H:%M:%SZ'
+fmt = "%Y-%m-%dT%H:%M:%SZ"
 
 # The constants were taken from BIND 9 source code (lib/dns/zone.c)
 max_refresh = timedelta(seconds=2419200)  # 4 weeks
@@ -71,9 +71,9 @@ def zone_mtime(zonedir, name):
 
 def test_zone_timers_primary(fetch_zones, load_timers, **kwargs):
 
-    statsip = kwargs['statsip']
-    statsport = kwargs['statsport']
-    zonedir = kwargs['zonedir']
+    statsip = kwargs["statsip"]
+    statsport = kwargs["statsport"]
+    zonedir = kwargs["zonedir"]
 
     zones = fetch_zones(statsip, statsport)
 
@@ -85,9 +85,9 @@ def test_zone_timers_primary(fetch_zones, load_timers, **kwargs):
 
 def test_zone_timers_secondary(fetch_zones, load_timers, **kwargs):
 
-    statsip = kwargs['statsip']
-    statsport = kwargs['statsport']
-    zonedir = kwargs['zonedir']
+    statsip = kwargs["statsip"]
+    statsport = kwargs["statsport"]
+    zonedir = kwargs["zonedir"]
 
     zones = fetch_zones(statsip, statsport)
 
@@ -99,12 +99,12 @@ def test_zone_timers_secondary(fetch_zones, load_timers, **kwargs):
 
 def test_zone_with_many_keys(fetch_zones, load_zone, **kwargs):
 
-    statsip = kwargs['statsip']
-    statsport = kwargs['statsport']
+    statsip = kwargs["statsip"]
+    statsport = kwargs["statsport"]
 
     zones = fetch_zones(statsip, statsport)
 
     for zone in zones:
         name = load_zone(zone)
-        if name == 'manykeys':
+        if name == "manykeys":
             check_manykeys(name)
index 88dabbca084f669335fa0de3831d2576bb630519..37e6e89f14bf212947e97890af96c260d53b6b9d 100644 (file)
@@ -20,8 +20,9 @@ TIMEOUT = 10
 
 
 def create_msg(qname, qtype):
-    msg = dns.message.make_query(qname, qtype, want_dnssec=True,
-                                 use_edns=0, payload=4096)
+    msg = dns.message.make_query(
+        qname, qtype, want_dnssec=True, use_edns=0, payload=4096
+    )
 
     return msg
 
@@ -43,15 +44,16 @@ def tcp_query(ip, port, msg):
 
 
 def create_expected(data):
-    expected = {"dns-tcp-requests-sizes-received-ipv4": defaultdict(int),
-                "dns-tcp-responses-sizes-sent-ipv4": defaultdict(int),
-                "dns-tcp-requests-sizes-received-ipv6": defaultdict(int),
-                "dns-tcp-responses-sizes-sent-ipv6": defaultdict(int),
-                "dns-udp-requests-sizes-received-ipv4": defaultdict(int),
-                "dns-udp-requests-sizes-received-ipv6": defaultdict(int),
-                "dns-udp-responses-sizes-sent-ipv4": defaultdict(int),
-                "dns-udp-responses-sizes-sent-ipv6": defaultdict(int),
-                }
+    expected = {
+        "dns-tcp-requests-sizes-received-ipv4": defaultdict(int),
+        "dns-tcp-responses-sizes-sent-ipv4": defaultdict(int),
+        "dns-tcp-requests-sizes-received-ipv6": defaultdict(int),
+        "dns-tcp-responses-sizes-sent-ipv6": defaultdict(int),
+        "dns-udp-requests-sizes-received-ipv4": defaultdict(int),
+        "dns-udp-requests-sizes-received-ipv6": defaultdict(int),
+        "dns-udp-responses-sizes-sent-ipv4": defaultdict(int),
+        "dns-udp-responses-sizes-sent-ipv6": defaultdict(int),
+    }
 
     for k, v in data.items():
         for kk, vv in v.items():
@@ -89,9 +91,9 @@ def check_traffic(data, expected):
 
 def test_traffic(fetch_traffic, **kwargs):
 
-    statsip = kwargs['statsip']
-    statsport = kwargs['statsport']
-    port = kwargs['port']
+    statsip = kwargs["statsip"]
+    statsport = kwargs["statsport"]
+    port = kwargs["port"]
 
     data = fetch_traffic(statsip, statsport)
     exp = create_expected(data)
index 373f98d30bc323b690deef8ea8e0c52356ca44db..d94a32f7da23c63271f956652cb5ebffb37c8fbb 100755 (executable)
@@ -19,16 +19,18 @@ import pytest
 
 import generic
 
-pytestmark = pytest.mark.skipif(not os.environ.get('HAVEJSONSTATS'),
-                                reason='json-c support disabled in the build')
-requests = pytest.importorskip('requests')
+pytestmark = pytest.mark.skipif(
+    not os.environ.get("HAVEJSONSTATS"), reason="json-c support disabled in the build"
+)
+requests = pytest.importorskip("requests")
 
 
 # JSON helper functions
 def fetch_zones_json(statsip, statsport):
 
-    r = requests.get("http://{}:{}/json/v1/zones".format(statsip, statsport),
-                     timeout=600)
+    r = requests.get(
+        "http://{}:{}/json/v1/zones".format(statsip, statsport), timeout=600
+    )
     assert r.status_code == 200
 
     data = r.json()
@@ -37,8 +39,9 @@ def fetch_zones_json(statsip, statsport):
 
 def fetch_traffic_json(statsip, statsport):
 
-    r = requests.get("http://{}:{}/json/v1/traffic".format(statsip, statsport),
-                     timeout=600)
+    r = requests.get(
+        "http://{}:{}/json/v1/traffic".format(statsip, statsport), timeout=600
+    )
     assert r.status_code == 200
 
     data = r.json()
@@ -48,52 +51,61 @@ def fetch_traffic_json(statsip, statsport):
 
 def load_timers_json(zone, primary=True):
 
-    name = zone['name']
+    name = zone["name"]
 
     # Check if the primary zone timer exists
-    assert 'loaded' in zone
-    loaded = datetime.strptime(zone['loaded'], generic.fmt)
+    assert "loaded" in zone
+    loaded = datetime.strptime(zone["loaded"], generic.fmt)
 
     if primary:
         # Check if the secondary zone timers does not exist
-        assert 'expires' not in zone
-        assert 'refresh' not in zone
+        assert "expires" not in zone
+        assert "refresh" not in zone
         expires = None
         refresh = None
     else:
-        assert 'expires' in zone
-        assert 'refresh' in zone
-        expires = datetime.strptime(zone['expires'], generic.fmt)
-        refresh = datetime.strptime(zone['refresh'], generic.fmt)
+        assert "expires" in zone
+        assert "refresh" in zone
+        expires = datetime.strptime(zone["expires"], generic.fmt)
+        refresh = datetime.strptime(zone["refresh"], generic.fmt)
 
     return (name, loaded, expires, refresh)
 
 
 def load_zone_json(zone):
-    name = zone['name']
+    name = zone["name"]
 
     return name
 
 
 def test_zone_timers_primary_json(statsport):
-    generic.test_zone_timers_primary(fetch_zones_json, load_timers_json,
-                                     statsip="10.53.0.1", statsport=statsport,
-                                     zonedir="ns1")
+    generic.test_zone_timers_primary(
+        fetch_zones_json,
+        load_timers_json,
+        statsip="10.53.0.1",
+        statsport=statsport,
+        zonedir="ns1",
+    )
 
 
 def test_zone_timers_secondary_json(statsport):
-    generic.test_zone_timers_secondary(fetch_zones_json, load_timers_json,
-                                       statsip="10.53.0.3", statsport=statsport,
-                                       zonedir="ns3")
+    generic.test_zone_timers_secondary(
+        fetch_zones_json,
+        load_timers_json,
+        statsip="10.53.0.3",
+        statsport=statsport,
+        zonedir="ns3",
+    )
 
 
 def test_zone_with_many_keys_json(statsport):
-    generic.test_zone_with_many_keys(fetch_zones_json, load_zone_json,
-                                     statsip="10.53.0.2", statsport=statsport)
+    generic.test_zone_with_many_keys(
+        fetch_zones_json, load_zone_json, statsip="10.53.0.2", statsport=statsport
+    )
 
 
 def test_traffic_json(named_port, statsport):
-    generic_dnspython = pytest.importorskip('generic_dnspython')
-    generic_dnspython.test_traffic(fetch_traffic_json,
-                                   statsip="10.53.0.2", statsport=statsport,
-                                   port=named_port)
+    generic_dnspython = pytest.importorskip("generic_dnspython")
+    generic_dnspython.test_traffic(
+        fetch_traffic_json, statsip="10.53.0.2", statsport=statsport, port=named_port
+    )
index 73b6e909f3cd64076e42d688c17d10319c0baaa6..423754916ab964b7ee82f9db6ef68bbe048e3944 100755 (executable)
@@ -20,41 +20,43 @@ import pytest
 
 import generic
 
-pytestmark = pytest.mark.skipif(not os.environ.get('HAVEXMLSTATS'),
-                                reason='libxml2 support disabled in the build')
-requests = pytest.importorskip('requests')
+pytestmark = pytest.mark.skipif(
+    not os.environ.get("HAVEXMLSTATS"), reason="libxml2 support disabled in the build"
+)
+requests = pytest.importorskip("requests")
 
 
 # XML helper functions
 def fetch_zones_xml(statsip, statsport):
 
-    r = requests.get("http://{}:{}/xml/v3/zones".format(statsip, statsport),
-                     timeout=600)
+    r = requests.get(
+        "http://{}:{}/xml/v3/zones".format(statsip, statsport), timeout=600
+    )
     assert r.status_code == 200
 
     root = ET.fromstring(r.text)
 
     default_view = None
-    for view in root.find('views').iter('view'):
-        if view.attrib['name'] == "_default":
+    for view in root.find("views").iter("view"):
+        if view.attrib["name"] == "_default":
             default_view = view
             break
     assert default_view is not None
 
-    return default_view.find('zones').findall('zone')
+    return default_view.find("zones").findall("zone")
 
 
 def fetch_traffic_xml(statsip, statsport):
-
     def load_counters(data):
         out = {}
         for counter in data.findall("counter"):
-            out[counter.attrib['name']] = int(counter.text)
+            out[counter.attrib["name"]] = int(counter.text)
 
         return out
 
-    r = requests.get("http://{}:{}/xml/v3/traffic".format(statsip, statsport),
-                     timeout=600)
+    r = requests.get(
+        "http://{}:{}/xml/v3/traffic".format(statsip, statsport), timeout=600
+    )
     assert r.status_code == 200
 
     root = ET.fromstring(r.text)
@@ -64,7 +66,7 @@ def fetch_traffic_xml(statsip, statsport):
         for proto in ["udp", "tcp"]:
             proto_root = root.find("traffic").find(ip).find(proto)
             for counters in proto_root.findall("counters"):
-                if counters.attrib['type'] == "request-size":
+                if counters.attrib["type"] == "request-size":
                     key = "dns-{}-requests-sizes-received-{}".format(proto, ip)
                 else:
                     key = "dns-{}-responses-sizes-sent-{}".format(proto, ip)
@@ -77,14 +79,14 @@ def fetch_traffic_xml(statsip, statsport):
 
 def load_timers_xml(zone, primary=True):
 
-    name = zone.attrib['name']
+    name = zone.attrib["name"]
 
-    loaded_el = zone.find('loaded')
+    loaded_el = zone.find("loaded")
     assert loaded_el is not None
     loaded = datetime.strptime(loaded_el.text, generic.fmt)
 
-    expires_el = zone.find('expires')
-    refresh_el = zone.find('refresh')
+    expires_el = zone.find("expires")
+    refresh_el = zone.find("refresh")
     if primary:
         assert expires_el is None
         assert refresh_el is None
@@ -100,30 +102,39 @@ def load_timers_xml(zone, primary=True):
 
 
 def load_zone_xml(zone):
-    name = zone.attrib['name']
+    name = zone.attrib["name"]
 
     return name
 
 
 def test_zone_timers_primary_xml(statsport):
-    generic.test_zone_timers_primary(fetch_zones_xml, load_timers_xml,
-                                     statsip="10.53.0.1", statsport=statsport,
-                                     zonedir="ns1")
+    generic.test_zone_timers_primary(
+        fetch_zones_xml,
+        load_timers_xml,
+        statsip="10.53.0.1",
+        statsport=statsport,
+        zonedir="ns1",
+    )
 
 
 def test_zone_timers_secondary_xml(statsport):
-    generic.test_zone_timers_secondary(fetch_zones_xml, load_timers_xml,
-                                       statsip="10.53.0.3", statsport=statsport,
-                                       zonedir="ns3")
+    generic.test_zone_timers_secondary(
+        fetch_zones_xml,
+        load_timers_xml,
+        statsip="10.53.0.3",
+        statsport=statsport,
+        zonedir="ns3",
+    )
 
 
 def test_zone_with_many_keys_xml(statsport):
-    generic.test_zone_with_many_keys(fetch_zones_xml, load_zone_xml,
-                                     statsip="10.53.0.2", statsport=statsport)
+    generic.test_zone_with_many_keys(
+        fetch_zones_xml, load_zone_xml, statsip="10.53.0.2", statsport=statsport
+    )
 
 
 def test_traffic_xml(named_port, statsport):
-    generic_dnspython = pytest.importorskip('generic_dnspython')
-    generic_dnspython.test_traffic(fetch_traffic_xml,
-                                   statsip="10.53.0.2", statsport=statsport,
-                                   port=named_port)
+    generic_dnspython = pytest.importorskip("generic_dnspython")
+    generic_dnspython.test_traffic(
+        fetch_traffic_xml, statsip="10.53.0.2", statsport=statsport, port=named_port
+    )
index 5cc98538fbd314704c5aeac65bc81171fe8ae0b6..4595ddcd07dd4732ad9cb18ce4a6d38aa1fd7576 100644 (file)
@@ -42,10 +42,11 @@ import time
 
 # Timeout for establishing all connections requested by a single 'open' command.
 OPEN_TIMEOUT = 2
-VERSION_QUERY = b'\x00\x1e\xaf\xb8\x01\x00\x00\x01\x00\x00\x00\x00\x00\x00\x07version\x04bind\x00\x00\x10\x00\x03'
+VERSION_QUERY = b"\x00\x1e\xaf\xb8\x01\x00\x00\x01\x00\x00\x00\x00\x00\x00\x07version\x04bind\x00\x00\x10\x00\x03"
+
 
 def log(msg):
-    print(datetime.datetime.now().strftime('%d-%b-%Y %H:%M:%S.%f ') + msg)
+    print(datetime.datetime.now().strftime("%d-%b-%Y %H:%M:%S.%f ") + msg)
 
 
 def open_connections(active_conns, count, host, port):
@@ -58,14 +59,14 @@ def open_connections(active_conns, count, host, port):
     except socket.error:
         family = socket.AF_INET6
 
-    log('Opening %d connections...' % count)
+    log("Opening %d connections..." % count)
 
     for _ in range(count):
         sock = socket.socket(family, socket.SOCK_STREAM)
         sock.setblocking(0)
         err = sock.connect_ex((host, port))
         if err not in (0, errno.EINPROGRESS):
-            log('%s on connect for socket %s' % (errno.errorcode[err], sock))
+            log("%s on connect for socket %s" % (errno.errorcode[err], sock))
             errors.append(sock)
         else:
             queued.append(sock)
@@ -81,35 +82,35 @@ def open_connections(active_conns, count, host, port):
             queued.remove(sock)
             err = sock.getsockopt(socket.SOL_SOCKET, socket.SO_ERROR)
             if err:
-                log('%s for socket %s' % (errno.errorcode[err], sock))
+                log("%s for socket %s" % (errno.errorcode[err], sock))
                 errors.append(sock)
             else:
                 sock.send(VERSION_QUERY)
                 active_conns.append(sock)
 
     if errors:
-        log('result=FAIL: %d connection(s) failed' % len(errors))
+        log("result=FAIL: %d connection(s) failed" % len(errors))
     elif queued:
-        log('result=FAIL: Timed out, aborting %d pending connections' % len(queued))
+        log("result=FAIL: Timed out, aborting %d pending connections" % len(queued))
         for sock in queued:
             sock.close()
     else:
-        log('result=OK: Successfully opened %d connections' % count)
+        log("result=OK: Successfully opened %d connections" % count)
 
 
 def close_connections(active_conns, count):
-    log('Closing %s connections...' % "all" if count == 0 else str(count))
+    log("Closing %s connections..." % "all" if count == 0 else str(count))
     if count == 0:
         count = len(active_conns)
     for _ in range(count):
         sock = active_conns.pop(0)
         sock.close()
-    log('result=OK: Successfully closed %d connections' % count)
+    log("result=OK: Successfully closed %d connections" % count)
 
 
 def sigterm(*_):
-    log('SIGTERM received, shutting down')
-    os.remove('ans.pid')
+    log("SIGTERM received, shutting down")
+    os.remove("ans.pid")
     sys.exit(0)
 
 
@@ -118,16 +119,16 @@ def main():
 
     signal.signal(signal.SIGTERM, sigterm)
 
-    with open('ans.pid', 'w') as pidfile:
+    with open("ans.pid", "w") as pidfile:
         print(os.getpid(), file=pidfile)
 
-    listenip = '10.53.0.6'
+    listenip = "10.53.0.6"
     try:
-        port = int(os.environ['CONTROLPORT'])
+        port = int(os.environ["CONTROLPORT"])
     except KeyError:
         port = 5309
 
-    log('Listening on %s:%d' % (listenip, port))
+    log("Listening on %s:%d" % (listenip, port))
 
     ctlsock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
     ctlsock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
@@ -136,21 +137,21 @@ def main():
 
     while True:
         (clientsock, _) = ctlsock.accept()
-        log('Accepted control connection from %s' % clientsock)
-        cmdline = clientsock.recv(512).decode('ascii').strip()
+        log("Accepted control connection from %s" % clientsock)
+        cmdline = clientsock.recv(512).decode("ascii").strip()
         if cmdline:
-            log('Received command: %s' % cmdline)
+            log("Received command: %s" % cmdline)
             cmd = cmdline.split()
-            if cmd[0] == 'open':
+            if cmd[0] == "open":
                 count, host, port = cmd[1:]
                 open_connections(active_conns, int(count), host, int(port))
-            elif cmd[0] == 'close':
-                (count, ) = cmd[1:]
+            elif cmd[0] == "close":
+                (count,) = cmd[1:]
                 close_connections(active_conns, int(count))
             else:
-                log('result=FAIL: Unknown command')
+                log("result=FAIL: Unknown command")
         clientsock.close()
 
 
-if __name__ == '__main__':
+if __name__ == "__main__":
     main()
index 41659f74396020a3e19e7e29640872287d45112c..6a8e4b74c93a1697c3cd73b03915f05a8d0f8ca7 100644 (file)
@@ -18,7 +18,7 @@ import time
 
 import pytest
 
-pytest.importorskip('dns', minversion='2.0.0')
+pytest.importorskip("dns", minversion="2.0.0")
 import dns.message
 import dns.query
 
@@ -48,8 +48,7 @@ def test_close_wait(named_port):
         (sbytes, stime) = dns.query.send_tcp(sock, msg, timeout())
         (response, rtime) = dns.query.receive_tcp(sock, timeout())
 
-        msg = dns.message.make_query("a.example.", "A", use_edns=0,
-                                     payload=1232)
+        msg = dns.message.make_query("a.example.", "A", use_edns=0, payload=1232)
         (sbytes, stime) = dns.query.send_tcp(sock, msg, timeout())
 
         # Shutdown the socket, but ignore the other side closing the socket
index 74d7cb695f8b2d038def94e21538953e453fdd69..994a9d746ccea77e12cc169a499c520ffc4727d0 100644 (file)
@@ -18,7 +18,7 @@ import time
 
 import pytest
 
-pytest.importorskip('dns', minversion='2.0.0')
+pytest.importorskip("dns", minversion="2.0.0")
 import dns.edns
 import dns.message
 import dns.name
@@ -33,8 +33,9 @@ TIMEOUT = 10
 
 
 def create_msg(qname, qtype):
-    msg = dns.message.make_query(qname, qtype, want_dnssec=True,
-                                 use_edns=0, payload=4096)
+    msg = dns.message.make_query(
+        qname, qtype, want_dnssec=True, use_edns=0, payload=4096
+    )
     return msg
 
 
@@ -94,7 +95,7 @@ def test_keepalive_timeout(named_port):
     # Keepalive is 7 seconds, so the third message should succeed.
     #
     msg = create_msg("example.", "A")
-    kopt = dns.edns.GenericOption(11, b'\x00')
+    kopt = dns.edns.GenericOption(11, b"\x00")
     msg.use_edns(edns=True, payload=4096, options=[kopt])
 
     with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:
@@ -163,18 +164,22 @@ def test_long_axfr(named_port):
         (sbytes, stime) = dns.query.send_tcp(sock, msg, timeout())
 
         # Receive the initial DNS message with SOA
-        (response, rtime) = dns.query.receive_tcp(sock, timeout(),
-                                                  one_rr_per_rrset=True)
-        soa = response.get_rrset(dns.message.ANSWER, name,
-                                 dns.rdataclass.IN, dns.rdatatype.SOA)
+        (response, rtime) = dns.query.receive_tcp(
+            sock, timeout(), one_rr_per_rrset=True
+        )
+        soa = response.get_rrset(
+            dns.message.ANSWER, name, dns.rdataclass.IN, dns.rdatatype.SOA
+        )
         assert soa is not None
 
         # Pull DNS message from wire until the second SOA is received
         while True:
-            (response, rtime) = dns.query.receive_tcp(sock, timeout(),
-                                                      one_rr_per_rrset=True)
-            soa = response.get_rrset(dns.message.ANSWER, name,
-                                     dns.rdataclass.IN, dns.rdatatype.SOA)
+            (response, rtime) = dns.query.receive_tcp(
+                sock, timeout(), one_rr_per_rrset=True
+            )
+            soa = response.get_rrset(
+                dns.message.ANSWER, name, dns.rdataclass.IN, dns.rdatatype.SOA
+            )
             if soa is not None:
                 break
         assert soa is not None
@@ -216,10 +221,12 @@ def test_max_transfer_idle_out(named_port):
         (sbytes, stime) = dns.query.send_tcp(sock, msg, timeout())
 
         # Receive the initial DNS message with SOA
-        (response, rtime) = dns.query.receive_tcp(sock, timeout(),
-                                                  one_rr_per_rrset=True)
-        soa = response.get_rrset(dns.message.ANSWER, name,
-                                 dns.rdataclass.IN, dns.rdatatype.SOA)
+        (response, rtime) = dns.query.receive_tcp(
+            sock, timeout(), one_rr_per_rrset=True
+        )
+        soa = response.get_rrset(
+            dns.message.ANSWER, name, dns.rdataclass.IN, dns.rdatatype.SOA
+        )
         assert soa is not None
 
         time.sleep(61)  # max-transfer-idle-out is 1 minute
@@ -227,11 +234,12 @@ def test_max_transfer_idle_out(named_port):
         with pytest.raises(ConnectionResetError):
             # Process queued TCP messages
             while True:
-                (response, rtime) = \
-                    dns.query.receive_tcp(sock, timeout(),
-                                          one_rr_per_rrset=True)
-                soa = response.get_rrset(dns.message.ANSWER, name,
-                                         dns.rdataclass.IN, dns.rdatatype.SOA)
+                (response, rtime) = dns.query.receive_tcp(
+                    sock, timeout(), one_rr_per_rrset=True
+                )
+                soa = response.get_rrset(
+                    dns.message.ANSWER, name, dns.rdataclass.IN, dns.rdatatype.SOA
+                )
                 if soa is not None:
                     break
             assert soa is None
@@ -247,21 +255,24 @@ def test_max_transfer_time_out(named_port):
         (sbytes, stime) = dns.query.send_tcp(sock, msg, timeout())
 
         # Receive the initial DNS message with SOA
-        (response, rtime) = dns.query.receive_tcp(sock, timeout(),
-                                                  one_rr_per_rrset=True)
-        soa = response.get_rrset(dns.message.ANSWER, name,
-                                 dns.rdataclass.IN, dns.rdatatype.SOA)
+        (response, rtime) = dns.query.receive_tcp(
+            sock, timeout(), one_rr_per_rrset=True
+        )
+        soa = response.get_rrset(
+            dns.message.ANSWER, name, dns.rdataclass.IN, dns.rdatatype.SOA
+        )
         assert soa is not None
 
         # The loop should timeout at the 5 minutes (max-transfer-time-out)
         with pytest.raises(EOFError):
             while True:
                 time.sleep(1)
-                (response, rtime) = \
-                    dns.query.receive_tcp(sock, timeout(),
-                                          one_rr_per_rrset=True)
-                soa = response.get_rrset(dns.message.ANSWER, name,
-                                         dns.rdataclass.IN, dns.rdatatype.SOA)
+                (response, rtime) = dns.query.receive_tcp(
+                    sock, timeout(), one_rr_per_rrset=True
+                )
+                soa = response.get_rrset(
+                    dns.message.ANSWER, name, dns.rdataclass.IN, dns.rdatatype.SOA
+                )
                 if soa is not None:
                     break
         assert soa is None
index f4134225e1223e66a9ab4f881f12ee0de73aacb9..66166f2a9e7ac56799deea108560b7fe8f40fcd4 100755 (executable)
@@ -45,19 +45,21 @@ from hypothesis.strategies import binary, integers
 
 
 # labels of a zone with * A 192.0.2.1 wildcard
-WILDCARD_ZONE = ('allwild', 'test', '')
+WILDCARD_ZONE = ("allwild", "test", "")
 WILDCARD_RDTYPE = dns.rdatatype.A
-WILDCARD_RDATA = '192.0.2.1'
-IPADDR = '10.53.0.1'
+WILDCARD_RDATA = "192.0.2.1"
+IPADDR = "10.53.0.1"
 TIMEOUT = 5  # seconds, just a sanity check
 
 
 # Helpers
 def is_nonexpanding_rdtype(rdtype):
     """skip meta types to avoid weird rcodes caused by AXFR etc.; RFC 6895"""
-    return not(rdtype == WILDCARD_RDTYPE
-               or dns.rdatatype.is_metatype(rdtype)  # known metatypes: OPT ...
-               or 128 <= rdtype <= 255)  # unknown meta types
+    return not (
+        rdtype == WILDCARD_RDTYPE
+        or dns.rdatatype.is_metatype(rdtype)  # known metatypes: OPT ...
+        or 128 <= rdtype <= 255
+    )  # unknown meta types
 
 
 def tcp_query(where, port, qname, qtype):
@@ -67,15 +69,16 @@ def tcp_query(where, port, qname, qtype):
 
 
 def query(where, port, label, rdtype):
-    labels = (label, ) + WILDCARD_ZONE
+    labels = (label,) + WILDCARD_ZONE
     qname = dns.name.Name(labels)
     return tcp_query(where, port, qname, rdtype)
 
 
 # Tests
-@given(label=binary(min_size=1, max_size=63),
-       rdtype=integers(min_value=0, max_value=65535).filter(
-           is_nonexpanding_rdtype))
+@given(
+    label=binary(min_size=1, max_size=63),
+    rdtype=integers(min_value=0, max_value=65535).filter(is_nonexpanding_rdtype),
+)
 def test_wildcard_rdtype_mismatch(label, rdtype, named_port):
     """any label non-matching rdtype must result in to NODATA"""
     check_answer_nodata(*query(IPADDR, named_port, label, rdtype))
@@ -97,10 +100,13 @@ def check_answer_noerror(querymsg, answer):
     assert querymsg.is_response(answer), str(answer)
     assert answer.rcode() == dns.rcode.NOERROR, str(answer)
     assert len(querymsg.question) == 1, str(answer)
-    expected_answer = [dns.rrset.from_text(
-                            querymsg.question[0].name,
-                            300,  # TTL, ignored by dnspython comparison
-                            dns.rdataclass.IN,
-                            WILDCARD_RDTYPE,
-                            WILDCARD_RDATA)]
+    expected_answer = [
+        dns.rrset.from_text(
+            querymsg.question[0].name,
+            300,  # TTL, ignored by dnspython comparison
+            dns.rdataclass.IN,
+            WILDCARD_RDTYPE,
+            WILDCARD_RDATA,
+        )
+    ]
     assert answer.answer == expected_answer, str(answer)
index fe0c208b8f2e78da15a9aad22c4a5c681a9160a6..a2536a7928852a5389e6bd09694bd8c0e66bd9ce 100644 (file)
@@ -28,19 +28,19 @@ class KaspTime:
     class KTLex:
         # pylint: disable=invalid-name
 
-        tokens = ('P', 'T', 'Y', 'M', 'D', 'H', 'S', 'NUM')
+        tokens = ("P", "T", "Y", "M", "D", "H", "S", "NUM")
 
-        t_P = r'(?i)P'
-        t_T = r'(?i)T'
-        t_Y = r'(?i)Y'
-        t_M = r'(?i)M'
-        t_D = r'(?i)D'
-        t_H = r'(?i)H'
-        t_S = r'(?i)S'
+        t_P = r"(?i)P"
+        t_T = r"(?i)T"
+        t_Y = r"(?i)Y"
+        t_M = r"(?i)M"
+        t_D = r"(?i)D"
+        t_H = r"(?i)H"
+        t_S = r"(?i)S"
 
         @staticmethod
         def t_NUM(t):
-            r'\d+'
+            r"\d+"
             t.value = int(t.value)
             return t
 
@@ -98,26 +98,26 @@ class KaspTime:
 
     @staticmethod
     def p_period(p):
-        '''period : NUM Y
-                  | NUM M
-                  | NUM D'''
-        if p[2].lower() == 'y':
+        """period : NUM Y
+        | NUM M
+        | NUM D"""
+        if p[2].lower() == "y":
             p[0] = int(p[1]) * 31536000
-        elif p[2].lower() == 'm':
+        elif p[2].lower() == "m":
             p[0] = int(p[1]) * 2592000
-        elif p[2].lower() == 'd':
+        elif p[2].lower() == "d":
             p[0] += int(p[1]) * 86400
 
     @staticmethod
     def p_time(p):
-        '''time : NUM H
-                | NUM M
-                | NUM S'''
-        if p[2].lower() == 'h':
+        """time : NUM H
+        | NUM M
+        | NUM S"""
+        if p[2].lower() == "h":
             p[0] = int(p[1]) * 3600
-        elif p[2].lower() == 'm':
+        elif p[2].lower() == "m":
             p[0] = int(p[1]) * 60
-        elif p[2].lower() == 's':
+        elif p[2].lower() == "s":
             p[0] = int(p[1])
 
     @staticmethod
@@ -128,7 +128,7 @@ class KaspTime:
 ############################################################################
 # Load the contents of a KASP XML file as a python dictionary
 ############################################################################
-class Kasp():
+class Kasp:
     # pylint: disable=invalid-name
 
     @staticmethod
@@ -143,12 +143,12 @@ class Kasp():
             k = {k: v[0] if len(v) == 1 else v for k, v in dd.items()}
             d = {t.tag: k}
         if t.attrib:
-            d[t.tag].update(('@' + k, v) for k, v in t.attrib.iteritems())
+            d[t.tag].update(("@" + k, v) for k, v in t.attrib.iteritems())
         if t.text:
             text = t.text.strip()
             if children or t.attrib:
                 if text:
-                    d[t.tag]['#text'] = text
+                    d[t.tag]["#text"] = text
             else:
                 d[t.tag] = text
         return d
@@ -189,35 +189,35 @@ if __name__ == "__main__":
     KT = KaspTime()
     FIRST = True
 
-    for policy in KINFO['KASP']['Policy']:
-        if not policy['@name'] or not policy['Keys']:
+    for policy in KINFO["KASP"]["Policy"]:
+        if not policy["@name"] or not policy["Keys"]:
             continue
         if not FIRST:
             print("")
         FIRST = False
-        if policy['Description']:
-            desc = policy['Description'].strip()
+        if policy["Description"]:
+            desc = policy["Description"].strip()
             print("# %s" % re.sub(r"\n\s*", "\n# ", desc))
-        print("policy %s {" % policy['@name'])
-        ksk = policy['Keys']['KSK']
-        zsk = policy['Keys']['ZSK']
-        kalg = ksk['Algorithm']
-        zalg = zsk['Algorithm']
-        algnum = kalg['#text'] or zalg['#text']
+        print("policy %s {" % policy["@name"])
+        ksk = policy["Keys"]["KSK"]
+        zsk = policy["Keys"]["ZSK"]
+        kalg = ksk["Algorithm"]
+        zalg = zsk["Algorithm"]
+        algnum = kalg["#text"] or zalg["#text"]
         if algnum:
             print("\talgorithm %s;" % dnskey.algstr(int(algnum)))
-        if policy['Keys']['TTL']:
-            print("\tkeyttl %d;" % KT.parse(policy['Keys']['TTL']))
-        if kalg['@length']:
-            print("\tkey-size ksk %d;" % int(kalg['@length']))
-        if zalg['@length']:
-            print("\tkey-size zsk %d;" % int(zalg['@length']))
-        if ksk['Lifetime']:
-            print("\troll-period ksk %d;" % KT.parse(ksk['Lifetime']))
-        if zsk['Lifetime']:
-            print("\troll-period zsk %d;" % KT.parse(zsk['Lifetime']))
-        if ksk['Standby']:
-            print("\tstandby ksk %d;" % int(ksk['Standby']))
-        if zsk['Standby']:
-            print("\tstandby zsk %d;" % int(zsk['Standby']))
+        if policy["Keys"]["TTL"]:
+            print("\tkeyttl %d;" % KT.parse(policy["Keys"]["TTL"]))
+        if kalg["@length"]:
+            print("\tkey-size ksk %d;" % int(kalg["@length"]))
+        if zalg["@length"]:
+            print("\tkey-size zsk %d;" % int(zalg["@length"]))
+        if ksk["Lifetime"]:
+            print("\troll-period ksk %d;" % KT.parse(ksk["Lifetime"]))
+        if zsk["Lifetime"]:
+            print("\troll-period zsk %d;" % KT.parse(zsk["Lifetime"]))
+        if ksk["Standby"]:
+            print("\tstandby ksk %d;" % int(ksk["Standby"]))
+        if zsk["Standby"]:
+            print("\tstandby zsk %d;" % int(zsk["Standby"]))
         print("};")
index fe13a191dac051d724e116b426a967665404ddf5..1eecc6b72f95e72a5bca5aae0862d2500001fc1a 100644 (file)
@@ -13,24 +13,30 @@ import re
 
 # Helper functions and variables
 
+
 def added_lines(target_branch, paths):
     import subprocess
-    subprocess.check_output(['/usr/bin/git', 'fetch', '--depth', '1', 'origin',
-                             target_branch])
-    diff = subprocess.check_output(['/usr/bin/git', 'diff', 'FETCH_HEAD..',
-                                    '--'] + paths)
+
+    subprocess.check_output(
+        ["/usr/bin/git", "fetch", "--depth", "1", "origin", target_branch]
+    )
+    diff = subprocess.check_output(
+        ["/usr/bin/git", "diff", "FETCH_HEAD..", "--"] + paths
+    )
     added_lines = []
     for line in diff.splitlines():
-        if line.startswith(b'+') and not line.startswith(b'+++'):
+        if line.startswith(b"+") and not line.startswith(b"+++"):
             added_lines.append(line)
     return added_lines
 
+
 def lines_containing(lines, string):
-    return [l for l in lines if bytes(string, 'utf-8') in l]
+    return [l for l in lines if bytes(string, "utf-8") in l]
+
 
-changes_issue_or_mr_id_regex = re.compile(br'\[(GL [#!]|RT #)[0-9]+\]')
-relnotes_issue_or_mr_id_regex = re.compile(br':gl:`[#!][0-9]+`')
-release_notes_regex = re.compile(r'doc/(arm|notes)/notes-.*\.(rst|xml)')
+changes_issue_or_mr_id_regex = re.compile(rb"\[(GL [#!]|RT #)[0-9]+\]")
+relnotes_issue_or_mr_id_regex = re.compile(rb":gl:`[#!][0-9]+`")
+release_notes_regex = re.compile(r"doc/(arm|notes)/notes-.*\.(rst|xml)")
 
 modified_files = danger.git.modified_files
 mr_labels = danger.gitlab.mr.labels
@@ -73,33 +79,39 @@ fixup_error_logged = False
 for commit in danger.git.commits:
     message_lines = commit.message.splitlines()
     subject = message_lines[0]
-    if (not fixup_error_logged and
-            (subject.startswith('fixup!') or
-             subject.startswith('Apply suggestion'))):
-        fail('Fixup commits are still present in this merge request. '
-             'Please squash them before merging.')
+    if not fixup_error_logged and (
+        subject.startswith("fixup!") or subject.startswith("Apply suggestion")
+    ):
+        fail(
+            "Fixup commits are still present in this merge request. "
+            "Please squash them before merging."
+        )
         fixup_error_logged = True
-    if len(subject) > 72 and not subject.startswith('Merge branch '):
+    if len(subject) > 72 and not subject.startswith("Merge branch "):
         warn(
-            f'Subject line for commit {commit.sha} is too long: '
-            f'```{subject}``` ({len(subject)} > 72 characters).'
+            f"Subject line for commit {commit.sha} is too long: "
+            f"```{subject}``` ({len(subject)} > 72 characters)."
         )
-    if subject[-1] == '.':
-        fail(f'Trailing dot found in the subject of commit {commit.sha}.')
+    if subject[-1] == ".":
+        fail(f"Trailing dot found in the subject of commit {commit.sha}.")
     if len(message_lines) > 1 and message_lines[1]:
-        fail(f'No empty line after subject for commit {commit.sha}.')
-    if (len(message_lines) < 3 and
-            'fixup! ' not in subject and
-            ' CHANGES ' not in subject and
-            ' release note' not in subject):
-        warn(f'Please write a log message for commit {commit.sha}.')
+        fail(f"No empty line after subject for commit {commit.sha}.")
+    if (
+        len(message_lines) < 3
+        and "fixup! " not in subject
+        and " CHANGES " not in subject
+        and " release note" not in subject
+    ):
+        warn(f"Please write a log message for commit {commit.sha}.")
     for line in message_lines[2:]:
-        if (len(line) > 72 and
-                not line.startswith('    ') and
-                not re.match(r'\[[0-9]+\]', line)):
+        if (
+            len(line) > 72
+            and not line.startswith("    ")
+            and not re.match(r"\[[0-9]+\]", line)
+        ):
             warn(
-                f'Line too long in log message for commit {commit.sha}: '
-                f'```{line}``` ({len(line)} > 72 characters).'
+                f"Line too long in log message for commit {commit.sha}: "
+                f"```{line}``` ({len(line)} > 72 characters)."
             )
 
 ###############################################################################
@@ -109,7 +121,7 @@ for commit in danger.git.commits:
 # FAIL if the merge request is not assigned to any milestone.
 
 if not danger.gitlab.mr.milestone:
-    fail('Please assign this merge request to a milestone.')
+    fail("Please assign this merge request to a milestone.")
 
 ###############################################################################
 # VERSION LABELS
@@ -127,15 +139,19 @@ if not danger.gitlab.mr.milestone:
 #   request is not a backport, version labels are used for indicating
 #   backporting preferences.)
 
-backport_label_set = 'Backport' in mr_labels
-version_labels = [l for l in mr_labels if l.startswith('v9.')]
+backport_label_set = "Backport" in mr_labels
+version_labels = [l for l in mr_labels if l.startswith("v9.")]
 if backport_label_set and len(version_labels) != 1:
-    fail('The *Backport* label is set for this merge request. '
-         'Please also set exactly one version label (*v9.x*).')
+    fail(
+        "The *Backport* label is set for this merge request. "
+        "Please also set exactly one version label (*v9.x*)."
+    )
 if not backport_label_set and not version_labels:
-    fail('If this merge request is a backport, set the *Backport* label and '
-         'a single version label (*v9.x*) indicating the target branch. '
-         'If not, set version labels for all targeted backport branches.')
+    fail(
+        "If this merge request is a backport, set the *Backport* label and "
+        "a single version label (*v9.x*) indicating the target branch. "
+        "If not, set version labels for all targeted backport branches."
+    )
 
 ###############################################################################
 # OTHER LABELS
@@ -149,12 +165,16 @@ if not backport_label_set and not version_labels:
 #   remind developers about the need to set the latter on merge requests which
 #   passed review.)
 
-if 'Review' not in mr_labels:
-    warn('This merge request does not have the *Review* label set. '
-         'Please set it if you would like the merge request to be reviewed.')
-elif 'LGTM (Merge OK)' not in mr_labels:
-    warn('This merge request is currently in review. '
-         'It should not be merged until it is marked with the *LGTM* label.')
+if "Review" not in mr_labels:
+    warn(
+        "This merge request does not have the *Review* label set. "
+        "Please set it if you would like the merge request to be reviewed."
+    )
+elif "LGTM (Merge OK)" not in mr_labels:
+    warn(
+        "This merge request is currently in review. "
+        "It should not be merged until it is marked with the *LGTM* label."
+    )
 
 ###############################################################################
 # 'CHANGES' FILE
@@ -176,25 +196,31 @@ elif 'LGTM (Merge OK)' not in mr_labels:
 # * The merge request adds a new CHANGES entry that is not a placeholder and
 #   does not contain any GitLab/RT issue/MR identifiers.
 
-changes_modified = 'CHANGES' in modified_files
-no_changes_label_set = 'No CHANGES' in mr_labels
+changes_modified = "CHANGES" in modified_files
+no_changes_label_set = "No CHANGES" in mr_labels
 if not changes_modified and not no_changes_label_set:
-    fail('This merge request does not modify `CHANGES`. '
-         'Add a `CHANGES` entry or set the *No CHANGES* label.')
+    fail(
+        "This merge request does not modify `CHANGES`. "
+        "Add a `CHANGES` entry or set the *No CHANGES* label."
+    )
 if changes_modified and no_changes_label_set:
-    fail('This merge request modifies `CHANGES`. '
-         'Revert `CHANGES` modifications or unset the *No Changes* label.')
+    fail(
+        "This merge request modifies `CHANGES`. "
+        "Revert `CHANGES` modifications or unset the *No Changes* label."
+    )
 
-changes_added_lines = added_lines(target_branch, ['CHANGES'])
-placeholders_added = lines_containing(changes_added_lines, '[placeholder]')
+changes_added_lines = added_lines(target_branch, ["CHANGES"])
+placeholders_added = lines_containing(changes_added_lines, "[placeholder]")
 identifiers_found = filter(changes_issue_or_mr_id_regex.search, changes_added_lines)
 if changes_added_lines:
     if placeholders_added:
-        if target_branch != 'main':
-            fail('This MR adds at least one placeholder entry to `CHANGES`. '
-                 'It should be targeting the `main` branch.')
+        if target_branch != "main":
+            fail(
+                "This MR adds at least one placeholder entry to `CHANGES`. "
+                "It should be targeting the `main` branch."
+            )
     elif not any(identifiers_found):
-        fail('No valid issue/MR identifiers found in added `CHANGES` entries.')
+        fail("No valid issue/MR identifiers found in added `CHANGES` entries.")
 
 ###############################################################################
 # RELEASE NOTES
@@ -219,25 +245,31 @@ if changes_added_lines:
 #       identifiers are found in the lines added to the release notes by this
 #       MR.
 
-release_notes_regex = re.compile(r'doc/(arm|notes)/notes-.*\.(rst|xml)')
+release_notes_regex = re.compile(r"doc/(arm|notes)/notes-.*\.(rst|xml)")
 release_notes_changed = list(filter(release_notes_regex.match, modified_files))
-release_notes_label_set = 'Release Notes' in mr_labels
+release_notes_label_set = "Release Notes" in mr_labels
 if not release_notes_changed:
     if release_notes_label_set:
-        fail('This merge request has the *Release Notes* label set. '
-             'Add a release note or unset the *Release Notes* label.')
-    elif 'Customer' in mr_labels:
-        warn('This merge request has the *Customer* label set. '
-             'Add a release note unless the changes introduced are trivial.')
+        fail(
+            "This merge request has the *Release Notes* label set. "
+            "Add a release note or unset the *Release Notes* label."
+        )
+    elif "Customer" in mr_labels:
+        warn(
+            "This merge request has the *Customer* label set. "
+            "Add a release note unless the changes introduced are trivial."
+        )
 if release_notes_changed and not release_notes_label_set:
-    fail('This merge request modifies release notes. '
-         'Revert release note modifications or set the *Release Notes* label.')
+    fail(
+        "This merge request modifies release notes. "
+        "Revert release note modifications or set the *Release Notes* label."
+    )
 
 if release_notes_changed:
     notes_added_lines = added_lines(target_branch, release_notes_changed)
     identifiers_found = filter(relnotes_issue_or_mr_id_regex.search, notes_added_lines)
     if notes_added_lines and not any(identifiers_found):
-        warn('No valid issue/MR identifiers found in added release notes.')
+        warn("No valid issue/MR identifiers found in added release notes.")
 else:
     notes_added_lines = []
 
@@ -249,13 +281,17 @@ else:
 # identifier is missing from either the added CHANGES entry or the added
 # release note.
 
-if lines_containing(changes_added_lines, '[security]'):
-    if not lines_containing(changes_added_lines, '(CVE-20'):
-        fail('This merge request fixes a security issue. '
-             'Please add a CHANGES entry which includes a CVE identifier.')
-    if not lines_containing(notes_added_lines, 'CVE-20'):
-        fail('This merge request fixes a security issue. '
-             'Please add a release note which includes a CVE identifier.')
+if lines_containing(changes_added_lines, "[security]"):
+    if not lines_containing(changes_added_lines, "(CVE-20"):
+        fail(
+            "This merge request fixes a security issue. "
+            "Please add a CHANGES entry which includes a CVE identifier."
+        )
+    if not lines_containing(notes_added_lines, "CVE-20"):
+        fail(
+            "This merge request fixes a security issue. "
+            "Please add a release note which includes a CVE identifier."
+        )
 
 ###############################################################################
 # PAIRWISE TESTING
@@ -264,13 +300,16 @@ if lines_containing(changes_added_lines, '[security]'):
 # FAIL if the merge request adds any new ./configure switch without an
 # associated annotation used for pairwise testing.
 
-configure_added_lines = added_lines(target_branch, ['configure.ac'])
-switches_added = (lines_containing(configure_added_lines, 'AC_ARG_ENABLE') +
-                  lines_containing(configure_added_lines, 'AC_ARG_WITH'))
-annotations_added = lines_containing(configure_added_lines, '# [pairwise: ')
+configure_added_lines = added_lines(target_branch, ["configure.ac"])
+switches_added = lines_containing(
+    configure_added_lines, "AC_ARG_ENABLE"
+) + lines_containing(configure_added_lines, "AC_ARG_WITH")
+annotations_added = lines_containing(configure_added_lines, "# [pairwise: ")
 if len(switches_added) > len(annotations_added):
-    fail('This merge request adds at least one new `./configure` switch that '
-         'is not annotated for pairwise testing purposes.')
+    fail(
+        "This merge request adds at least one new `./configure` switch that "
+        "is not annotated for pairwise testing purposes."
+    )
 
 ###############################################################################
 # USER-VISIBLE LOG LEVELS
@@ -279,16 +318,18 @@ if len(switches_added) > len(annotations_added):
 # WARN if the merge request adds new user-visible log messages (INFO or above)
 
 user_visible_log_levels = [
-    'ISC_LOG_INFO',
-    'ISC_LOG_NOTICE',
-    'ISC_LOG_WARNING',
-    'ISC_LOG_ERROR',
-    'ISC_LOG_CRITICAL',
+    "ISC_LOG_INFO",
+    "ISC_LOG_NOTICE",
+    "ISC_LOG_WARNING",
+    "ISC_LOG_ERROR",
+    "ISC_LOG_CRITICAL",
 ]
-source_added_lines = added_lines(target_branch, ['*.[ch]'])
+source_added_lines = added_lines(target_branch, ["*.[ch]"])
 for log_level in user_visible_log_levels:
-    if (lines_containing(source_added_lines, log_level)):
-        warn('This merge request adds new user-visible log messages with '
-             'level INFO or above. Please double-check log levels and make '
-             'sure none of the messages added is a leftover debug message.')
+    if lines_containing(source_added_lines, log_level):
+        warn(
+            "This merge request adds new user-visible log messages with "
+            "level INFO or above. Please double-check log levels and make "
+            "sure none of the messages added is a leftover debug message."
+        )
         break
index 87957f243dde35a5a211d4cc73a36dd908e86538..504e348adbf43e8cbec2135326c06d292ba8b1d9 100644 (file)
@@ -26,17 +26,18 @@ try:
 except ImportError:
     # pylint: disable=too-few-public-methods
     class ReferenceRole(roles.GenericRole):
-        '''
+        """
         The ReferenceRole class (used as a base class by GitLabRefRole
         below) is only defined in Sphinx >= 2.0.0.  For older Sphinx
         versions, this stub version of the ReferenceRole class is used
         instead.
-        '''
+        """
+
         def __init__(self):
-            super().__init__('', nodes.strong)
+            super().__init__("", nodes.strong)
 
 
-GITLAB_BASE_URL = 'https://gitlab.isc.org/isc-projects/bind9/-/'
+GITLAB_BASE_URL = "https://gitlab.isc.org/isc-projects/bind9/-/"
 
 
 # Custom Sphinx role enabling automatic hyperlinking to GitLab issues/MRs.
@@ -46,25 +47,26 @@ class GitLabRefRole(ReferenceRole):
         super().__init__()
 
     def run(self) -> Tuple[List[Node], List[system_message]]:
-        gl_identifier = '[GL %s]' % self.target
+        gl_identifier = "[GL %s]" % self.target
 
-        target_id = 'index-%s' % self.env.new_serialno('index')
-        entries = [('single', 'GitLab; ' + gl_identifier, target_id, '', None)]
+        target_id = "index-%s" % self.env.new_serialno("index")
+        entries = [("single", "GitLab; " + gl_identifier, target_id, "", None)]
 
         index = addnodes.index(entries=entries)
-        target = nodes.target('', '', ids=[target_id])
+        target = nodes.target("", "", ids=[target_id])
         self.inliner.document.note_explicit_target(target)
 
         try:
             refuri = self.build_uri()
-            reference = nodes.reference('', '', internal=False, refuri=refuri,
-                                        classes=['gl'])
+            reference = nodes.reference(
+                "", "", internal=False, refuri=refuri, classes=["gl"]
+            )
             if self.has_explicit_title:
                 reference += nodes.strong(self.title, self.title)
             else:
                 reference += nodes.strong(gl_identifier, gl_identifier)
         except ValueError:
-            error_text = 'invalid GitLab identifier %s' % self.target
+            error_text = "invalid GitLab identifier %s" % self.target
             msg = self.inliner.reporter.error(error_text, line=self.lineno)
             prb = self.inliner.problematic(self.rawtext, self.rawtext, msg)
             return [prb], [msg]
@@ -72,18 +74,19 @@ class GitLabRefRole(ReferenceRole):
         return [index, target, reference], []
 
     def build_uri(self):
-        if self.target[0] == '#':
-            return self.base_url + 'issues/%d' % int(self.target[1:])
-        if self.target[0] == '!':
-            return self.base_url + 'merge_requests/%d' % int(self.target[1:])
+        if self.target[0] == "#":
+            return self.base_url + "issues/%d" % int(self.target[1:])
+        if self.target[0] == "!":
+            return self.base_url + "merge_requests/%d" % int(self.target[1:])
         raise ValueError
 
 
 def setup(app):
-    roles.register_local_role('gl', GitLabRefRole(GITLAB_BASE_URL))
-    app.add_crossref_type('iscman', 'iscman', 'pair: %s; manual page')
+    roles.register_local_role("gl", GitLabRefRole(GITLAB_BASE_URL))
+    app.add_crossref_type("iscman", "iscman", "pair: %s; manual page")
     # ignore :option: references to simplify doc backports to v9_16 branch
-    app.add_role_to_domain('std', 'option', roles.code_role)
+    app.add_role_to_domain("std", "option", roles.code_role)
+
 
 #
 # Configuration file for the Sphinx documentation builder.
@@ -105,25 +108,25 @@ def setup(app):
 
 # -- Project information -----------------------------------------------------
 
-project = 'BIND 9'
+project = "BIND 9"
 # pylint: disable=redefined-builtin
-copyright = '2022, Internet Systems Consortium'
-author = 'Internet Systems Consortium'
+copyright = "2022, Internet Systems Consortium"
+author = "Internet Systems Consortium"
 
 version_vars = {}
-with open('../../version', encoding='utf-8') as version_file:
+with open("../../version", encoding="utf-8") as version_file:
     for line in version_file:
-        match = re.match(r'(?P<key>[A-Z]+)=(?P<val>.*)', line)
+        match = re.match(r"(?P<key>[A-Z]+)=(?P<val>.*)", line)
         if match:
-            version_vars[match.group('key')] = match.group('val')
-
-version = '%s.%s.%s%s%s%s' % (
-    version_vars['MAJORVER'],
-    version_vars['MINORVER'],
-    version_vars['PATCHVER'],
-    version_vars['RELEASETYPE'],
-    version_vars['RELEASEVER'],
-    version_vars['EXTENSIONS'],
+            version_vars[match.group("key")] = match.group("val")
+
+version = "%s.%s.%s%s%s%s" % (
+    version_vars["MAJORVER"],
+    version_vars["MINORVER"],
+    version_vars["PATCHVER"],
+    version_vars["RELEASETYPE"],
+    version_vars["RELEASEVER"],
+    version_vars["EXTENSIONS"],
 )
 release = version
 
@@ -135,49 +138,53 @@ release = version
 extensions = []
 
 # Add any paths that contain templates here, relative to this directory.
-templates_path = ['_templates']
+templates_path = ["_templates"]
 
 # List of patterns, relative to source directory, that match files and
 # directories to ignore when looking for source files.
 # This pattern also affects html_static_path and html_extra_path.
 exclude_patterns = [
-    '_build',
-    'Thumbs.db',
-    '.DS_Store',
-    '*.grammar.rst',
-    '*.zoneopts.rst',
-    'build.rst',
-    'catz.rst',
-    'dlz.rst',
-    'dnssec.rst',
-    'dyndb.rst',
-    'logging-categories.rst',
-    'managed-keys.rst',
-    'pkcs11.rst',
-    'platforms.rst',
-    'plugins.rst'
-    ]
+    "_build",
+    "Thumbs.db",
+    ".DS_Store",
+    "*.grammar.rst",
+    "*.zoneopts.rst",
+    "build.rst",
+    "catz.rst",
+    "dlz.rst",
+    "dnssec.rst",
+    "dyndb.rst",
+    "logging-categories.rst",
+    "managed-keys.rst",
+    "pkcs11.rst",
+    "platforms.rst",
+    "plugins.rst",
+]
 
 # The master toctree document.
-master_doc = 'index'
+master_doc = "index"
 
 # -- Options for HTML output -------------------------------------------------
 
 # The theme to use for HTML and HTML Help pages.  See the documentation for
 # a list of builtin themes.
 #
-html_theme = 'sphinx_rtd_theme'
-html_static_path = ['_static']
-html_css_files = [
-    'custom.css'
-]
+html_theme = "sphinx_rtd_theme"
+html_static_path = ["_static"]
+html_css_files = ["custom.css"]
 
 # -- Options for LaTeX output ------------------------------------------------
-latex_engine = 'xelatex'
+latex_engine = "xelatex"
 
 # pylint disable=line-too-long
 latex_documents = [
-    (master_doc, 'Bv9ARM.tex', 'BIND 9 Administrator Reference Manual', author, 'manual'),
-    ]
+    (
+        master_doc,
+        "Bv9ARM.tex",
+        "BIND 9 Administrator Reference Manual",
+        author,
+        "manual",
+    ),
+]
 
 latex_logo = "isc-logo.pdf"
index c38b558054e18f2bfb65dd972150fbeac480c6b3..8a52d7704eae69c79a2de89abc99d8bf794c7dc4 100644 (file)
@@ -32,12 +32,12 @@ from docutils.parsers.rst import roles
 
 # -- Project information -----------------------------------------------------
 
-project = 'BIND 9'
+project = "BIND 9"
 # pylint: disable=wrong-import-position
 year = datetime.datetime.now().year
 # pylint: disable=redefined-builtin
 copyright = "%d, Internet Systems Consortium" % year
-author = 'Internet Systems Consortium'
+author = "Internet Systems Consortium"
 
 # -- General configuration ---------------------------------------------------
 
@@ -51,64 +51,167 @@ man_make_section_directory = False
 extensions = []
 
 # Add any paths that contain templates here, relative to this directory.
-templates_path = ['../arm/_templates']
+templates_path = ["../arm/_templates"]
 
 # List of patterns, relative to source directory, that match files and
 # directories to ignore when looking for source files.
 # This pattern also affects html_static_path and html_extra_path.
 exclude_patterns = [
-    '_build',
-    'Thumbs.db',
-    '.DS_Store',
-    ]
+    "_build",
+    "Thumbs.db",
+    ".DS_Store",
+]
 
 # The master toctree document.
-master_doc = 'index'
+master_doc = "index"
 
 # pylint: disable=line-too-long
 man_pages = [
-    ('arpaname', 'arpaname', 'translate IP addresses to the corresponding ARPA names', author, 1),
-    ('ddns-confgen', 'ddns-confgen', 'ddns key generation tool', author, 8),
-    ('delv', 'delv', 'DNS lookup and validation utility', author, 1),
-    ('dig', 'dig', 'DNS lookup utility', author, 1),
-    ('dnssec-cds', 'dnssec-cds', 'change DS records for a child zone based on CDS/CDNSKEY', author, 8),
-    ('dnssec-checkds', 'dnssec-checkds', 'DNSSEC delegation consistency checking tool', author, 8),
-    ('dnssec-coverage', 'dnssec-coverage', 'checks future DNSKEY coverage for a zone', author, 8),
-    ('dnssec-dsfromkey', 'dnssec-dsfromkey', 'DNSSEC DS RR generation tool', author, 8),
-    ('dnssec-importkey', 'dnssec-importkey', 'import DNSKEY records from external systems so they can be managed', author, 8),
-    ('dnssec-keyfromlabel', 'dnssec-keyfromlabel', 'DNSSEC key generation tool', author, 8),
-    ('dnssec-keygen', 'dnssec-keygen', 'DNSSEC key generation tool', author, 8),
-    ('dnssec-keymgr', 'dnssec-keymgr', 'ensure correct DNSKEY coverage based on a defined policy', author, 8),
-    ('dnssec-revoke', 'dnssec-revoke', 'set the REVOKED bit on a DNSSEC key', author, 8),
-    ('dnssec-settime', 'dnssec-settime', 'set the key timing metadata for a DNSSEC key', author, 8),
-    ('dnssec-signzone', 'dnssec-signzone', 'DNSSEC zone signing tool', author, 8),
-    ('dnssec-verify', 'dnssec-verify', 'DNSSEC zone verification tool', author, 8),
-    ('dnstap-read', 'dnstap-read', 'print dnstap data in human-readable form', author, 1),
-    ('filter-aaaa', 'filter-aaaa', 'filter AAAA in DNS responses when A is present', author, 8),
-    ('host', 'host', 'DNS lookup utility', author, 1),
-    ('mdig', 'mdig', 'DNS pipelined lookup utility', author, 1),
-    ('named-checkconf', 'named-checkconf', 'named configuration file syntax checking tool', author, 8),
-    ('named-checkzone', 'named-checkzone', 'zone file validity checking or converting tool', author, 8),
-    ('named-compilezone', 'named-compilezone', 'zone file validity checking or converting tool', author, 8),
-    ('named-journalprint', 'named-journalprint', 'print zone journal in human-readable form', author, 8),
-    ('named-nzd2nzf', 'named-nzd2nzf', 'convert an NZD database to NZF text format', author, 8),
-    ('named-rrchecker', 'named-rrchecker', 'syntax checker for individual DNS resource records', author, 1),
-    ('named.conf', 'named.conf', 'configuration file for **named**', author, 5),
-    ('named', 'named', 'Internet domain name server', author, 8),
-    ('nsec3hash', 'nsec3hash', 'generate NSEC3 hash', author, 8),
-    ('nslookup', 'nslookup', 'query Internet name servers interactively', author, 1),
-    ('nsupdate', 'nsupdate', 'dynamic DNS update utility', author, 1),
-    ('pkcs11-destroy', 'pkcs11-destroy', 'destroy PKCS#11 objects', author, 8),
-    ('pkcs11-keygen', 'pkcs11-keygen', 'generate keys on a PKCS#11 device', author, 8),
-    ('pkcs11-list', 'pkcs11-list', 'list PKCS#11 objects', author, 8),
-    ('pkcs11-tokens', 'pkcs11-tokens', 'list PKCS#11 available tokens', author, 8),
-    ('rndc-confgen', 'rndc-confgen', 'rndc key generation tool', author, 8),
-    ('rndc.conf', 'rndc.conf', 'rndc configuration file', author, 5),
-    ('rndc', 'rndc', 'name server control utility', author, 8),
-    ('tsig-keygen', 'tsig-keygen', 'TSIG key generation tool', author, 8),
-    ]
+    (
+        "arpaname",
+        "arpaname",
+        "translate IP addresses to the corresponding ARPA names",
+        author,
+        1,
+    ),
+    ("ddns-confgen", "ddns-confgen", "ddns key generation tool", author, 8),
+    ("delv", "delv", "DNS lookup and validation utility", author, 1),
+    ("dig", "dig", "DNS lookup utility", author, 1),
+    (
+        "dnssec-cds",
+        "dnssec-cds",
+        "change DS records for a child zone based on CDS/CDNSKEY",
+        author,
+        8,
+    ),
+    (
+        "dnssec-checkds",
+        "dnssec-checkds",
+        "DNSSEC delegation consistency checking tool",
+        author,
+        8,
+    ),
+    (
+        "dnssec-coverage",
+        "dnssec-coverage",
+        "checks future DNSKEY coverage for a zone",
+        author,
+        8,
+    ),
+    ("dnssec-dsfromkey", "dnssec-dsfromkey", "DNSSEC DS RR generation tool", author, 8),
+    (
+        "dnssec-importkey",
+        "dnssec-importkey",
+        "import DNSKEY records from external systems so they can be managed",
+        author,
+        8,
+    ),
+    (
+        "dnssec-keyfromlabel",
+        "dnssec-keyfromlabel",
+        "DNSSEC key generation tool",
+        author,
+        8,
+    ),
+    ("dnssec-keygen", "dnssec-keygen", "DNSSEC key generation tool", author, 8),
+    (
+        "dnssec-keymgr",
+        "dnssec-keymgr",
+        "ensure correct DNSKEY coverage based on a defined policy",
+        author,
+        8,
+    ),
+    (
+        "dnssec-revoke",
+        "dnssec-revoke",
+        "set the REVOKED bit on a DNSSEC key",
+        author,
+        8,
+    ),
+    (
+        "dnssec-settime",
+        "dnssec-settime",
+        "set the key timing metadata for a DNSSEC key",
+        author,
+        8,
+    ),
+    ("dnssec-signzone", "dnssec-signzone", "DNSSEC zone signing tool", author, 8),
+    ("dnssec-verify", "dnssec-verify", "DNSSEC zone verification tool", author, 8),
+    (
+        "dnstap-read",
+        "dnstap-read",
+        "print dnstap data in human-readable form",
+        author,
+        1,
+    ),
+    (
+        "filter-aaaa",
+        "filter-aaaa",
+        "filter AAAA in DNS responses when A is present",
+        author,
+        8,
+    ),
+    ("host", "host", "DNS lookup utility", author, 1),
+    ("mdig", "mdig", "DNS pipelined lookup utility", author, 1),
+    (
+        "named-checkconf",
+        "named-checkconf",
+        "named configuration file syntax checking tool",
+        author,
+        8,
+    ),
+    (
+        "named-checkzone",
+        "named-checkzone",
+        "zone file validity checking or converting tool",
+        author,
+        8,
+    ),
+    (
+        "named-compilezone",
+        "named-compilezone",
+        "zone file validity checking or converting tool",
+        author,
+        8,
+    ),
+    (
+        "named-journalprint",
+        "named-journalprint",
+        "print zone journal in human-readable form",
+        author,
+        8,
+    ),
+    (
+        "named-nzd2nzf",
+        "named-nzd2nzf",
+        "convert an NZD database to NZF text format",
+        author,
+        8,
+    ),
+    (
+        "named-rrchecker",
+        "named-rrchecker",
+        "syntax checker for individual DNS resource records",
+        author,
+        1,
+    ),
+    ("named.conf", "named.conf", "configuration file for **named**", author, 5),
+    ("named", "named", "Internet domain name server", author, 8),
+    ("nsec3hash", "nsec3hash", "generate NSEC3 hash", author, 8),
+    ("nslookup", "nslookup", "query Internet name servers interactively", author, 1),
+    ("nsupdate", "nsupdate", "dynamic DNS update utility", author, 1),
+    ("pkcs11-destroy", "pkcs11-destroy", "destroy PKCS#11 objects", author, 8),
+    ("pkcs11-keygen", "pkcs11-keygen", "generate keys on a PKCS#11 device", author, 8),
+    ("pkcs11-list", "pkcs11-list", "list PKCS#11 objects", author, 8),
+    ("pkcs11-tokens", "pkcs11-tokens", "list PKCS#11 available tokens", author, 8),
+    ("rndc-confgen", "rndc-confgen", "rndc key generation tool", author, 8),
+    ("rndc.conf", "rndc.conf", "rndc configuration file", author, 5),
+    ("rndc", "rndc", "name server control utility", author, 8),
+    ("tsig-keygen", "tsig-keygen", "TSIG key generation tool", author, 8),
+]
+
 
 def setup(app):
-    app.add_crossref_type('iscman', 'iscman', 'pair: %s; manual page')
+    app.add_crossref_type("iscman", "iscman", "pair: %s; manual page")
     # ignore :option: references to simplify doc backports to v9_16 branch
-    app.add_role_to_domain('std', 'option', roles.code_role)
+    app.add_role_to_domain("std", "option", roles.code_role)
index 7dfde3b13bddd532597ed8a36ae029bb29d85f79..ba47f8fe143f45587e77d2c08ed75dedfdb76bd3 100755 (executable)
@@ -75,20 +75,20 @@ PATH = re.compile(TOP + "/")
 
 S = State()
 
-with open(sys.argv[1], "r", encoding='utf-8') as f:
+with open(sys.argv[1], "r", encoding="utf-8") as f:
     for line in f.readlines():
         if line == "==================\n":
             if not S.inside:
                 S.inside = True
             else:
-                DNAME = sha256(S.last_line.encode('utf-8')).hexdigest()
+                DNAME = sha256(S.last_line.encode("utf-8")).hexdigest()
                 DNAME = os.path.join(OUT, DNAME)
                 if not os.path.isdir(DNAME):
                     os.mkdir(DNAME)
-                FNAME = sha256(S.block.encode('utf-8')).hexdigest() + ".txt"
+                FNAME = sha256(S.block.encode("utf-8")).hexdigest() + ".txt"
                 FNAME = os.path.join(DNAME, FNAME)
                 if not os.path.isfile(FNAME):
-                    with open(FNAME, "w", encoding='utf-8') as w:
+                    with open(FNAME, "w", encoding="utf-8") as w:
                         w.write(S.block)
                 S.reset()
         else: