]> mj.ucw.cz Git - pynsc.git/commitdiff
Improve status command
authorMartin Mares <mj@ucw.cz>
Mon, 22 Apr 2024 12:21:11 +0000 (14:21 +0200)
committerMartin Mares <mj@ucw.cz>
Mon, 22 Apr 2024 12:21:11 +0000 (14:21 +0200)
TODO
example/__init__.py
nsconfig/cli.py
nsconfig/core.py
nsconfig/sink.py [new file with mode: 0644]

diff --git a/TODO b/TODO
index 783852aee21096c03dc9397a3192744505566e7b..b4b14c5132f88194397a8012993bcd7a69864829 100644 (file)
--- a/TODO
+++ b/TODO
@@ -3,3 +3,4 @@
 - Blackhole zones
 - DNSSEC
 - Logging
+- fix parse_name to know @
index 557ba093c5dd7593353b056984f740efd16c3b8f..8c6fd28c9bee242d577b2734672add20a74ef9e3 100644 (file)
@@ -1,4 +1,5 @@
 from nsconfig import Nsc
+import nsconfig.sink
 from nsconfig.daemon.bind import NscDaemonBind
 
 nsc = Nsc(
@@ -7,6 +8,9 @@ nsc = Nsc(
     daemon=NscDaemonBind(control_command='echo'),
 )
 
+nsconfig.sink.generate_localhost(nsc)
+nsconfig.sink.generate_blackhole(nsc)
+
 for rev in ['10.1.0.0/16', '10.2.0.0/16', 'fd12:3456:789a::/48']:
     rz = nsc.add_zone(reverse_for=rev)
     rz[""].NS('ns1.example.org', 'ns2.example.org')
index 6e9fcdce957d2b95682143896e217d9c50081981..8367aa211a78226c001b91ac793564d7d6974d32 100644 (file)
@@ -1,4 +1,5 @@
 import argparse
+from argparse import Namespace
 from pathlib import Path
 from texttable import Texttable
 
@@ -36,10 +37,9 @@ def do_test(nsc: Nsc) -> None:
             nsc.daemon.dump_config(file=f)
 
 
-def do_status(nsc: Nsc) -> None:
+def do_status(nsc: Nsc, args: Namespace) -> None:
     table = Texttable(max_width=0)
-    table.header(['Zone', 'Old serial', 'Old hash', 'New serial', 'New hash', 'S'])
-    table.set_cols_dtype(['t', 'i', 't', 'i', 't', 't'])
+    table.header(['S', 'Zone', 'Type', 'Status'])
     table.set_deco(Texttable.HEADER)
 
     for z in nsc.get_zones():
@@ -47,21 +47,20 @@ def do_status(nsc: Nsc) -> None:
             action = '*'
         else:
             action = ""
+        do_show = args.all
         if isinstance(z, NscZonePrimary):
-            table.add_row([
-                z.name,
-                z.prev_state.serial,
-                z.prev_state.hash,
-                z.state.serial,
-                z.state.hash,
-                action,
-            ])
+            status = f'serial {z.prev_state.serial}'
+            if z.is_changed():
+                status += f' -> {z.state.serial}'
+            do_show = True
         elif isinstance(z, NscZoneSecondary):
-            table.add_row([z.name, 'secondary', "", "", "", action])
+            status = f'from {z.primary_server}'
         elif isinstance(z, NscZoneAlias):
-            table.add_row([z.name, 'alias', "", "", "", action])
+            status = f'to {z.alias_for.name}'
         else:
             raise NotImplementedError()
+        if do_show:
+            table.add_row([action, z.name, z.zone_type.name, status])
 
     print(table.draw())
 
@@ -88,6 +87,7 @@ def main(nsc: Nsc) -> None:
     test_parser = subparsers.add_parser('test', help='test new configuration', description='Test new configuration')
 
     status_parser = subparsers.add_parser('status', help='list status of zones', description='List status of zones')
+    status_parser.add_argument('-a', '--all', default=False, action='store_true', help='show non-primary zones')
 
     update_parser = subparsers.add_parser('update', help='update configuration', description='Update zone files and daemon configuration as needed')
 
@@ -98,6 +98,6 @@ def main(nsc: Nsc) -> None:
     if args.action == 'test':
         do_test(nsc)
     elif args.action == 'status':
-        do_status(nsc)
+        do_status(nsc, args)
     elif args.action == 'update':
         do_update(nsc)
index beb9655e13c3087fc8f27a217a90e3feb3361a89..885a460e727233bf1858cb0842cf92a96e9625bc 100644 (file)
@@ -64,7 +64,7 @@ class NscNode:
             else:
                 self._add(dns.rdtypes.IN.AAAA.AAAA(RdataClass.IN, RdataType.AAAA, str(a)))
             if reverse:
-                self.nsc_zone.nsc._add_reverse_mapping(a, parse_name(self.name + '.' + self.nsc_zone.name))
+                self.nsc_zone.nsc._add_reverse_mapping(a, parse_name(self.name + '.' + self.nsc_zone.name) if self.name != "" else parse_name(self.nsc_zone.name + '.'))
         return self
 
     def MX(self, pri: int, name: str) -> Self:
diff --git a/nsconfig/sink.py b/nsconfig/sink.py
new file mode 100644 (file)
index 0000000..8bd23cb
--- /dev/null
@@ -0,0 +1,49 @@
+from typing import List, Optional
+
+from nsconfig.core import Nsc, NscZonePrimary
+from nsconfig.util import IPNetwork, parse_network
+
+# Networks which should have blackhole reverse zones as recommended by RFC 6303
+BLACKHOLE_NETWORKS = [
+    '0.0.0.0/8',                # IPv4 reserved
+    '10.0.0.0/8',               # IPv4 private
+    '169.254.0.0/16',           # IPv4 link-local
+    '192.0.2.0/24',             # IPv4 test
+    '192.168.0.0/16',           # IPv4 private
+    '198.51.100.0/24',          # IPv4 test
+    '203.0.113.0/24',           # IPv4 test
+    '255.255.255.255/32',       # IPv4 broadcast
+    '::0/128',                  # IPv6 unspecified
+    '2001:0db8::/32',           # IPv6 example
+    'fd00::/8',                 # IPv6 unique local
+    'fe80::/12',                # IPv6 link-local
+    'fe90::/12',
+    'fea0::/12',
+    'feb0::/12',
+] + [f'172.{i}.0.0/16' for i in range(16, 32)]  # IPv4 private
+
+
+def generate_localhost(nsc) -> None:
+    z = nsc.add_zone('localhost')
+    (z[""]
+        .NS(z.config.origin_server)
+        .A('127.0.0.1', '::1'))
+
+    r4 = nsc.add_zone(reverse_for='127.0.0.0/8')
+    r4[""].NS(z.config.origin_server)
+
+    r6 = nsc.add_zone(reverse_for='::1/128')
+    r6[""].NS(z.config.origin_server)
+
+
+def generate_blackhole(nsc: Nsc,
+                       use_zone: Optional[NscZonePrimary] = None,
+                       skip_networks: List[IPNetwork] = [],
+                       ) -> None:
+    if use_zone is None:
+        use_zone = nsc.add_zone('invalid')
+        assert isinstance(use_zone, NscZonePrimary)
+    for raw_net in BLACKHOLE_NETWORKS:
+        net = parse_network(raw_net)
+        if net not in skip_networks:
+            z = nsc.add_zone(reverse_for=net, alias_for=use_zone)