pvl.dns-zone: --serial
authorTero Marttila <terom@paivola.fi>
Wed, 11 Sep 2013 14:23:26 +0300
changeset 252 0ea4450fdd40
parent 251 d250f200dd7e
child 253 8f59ee92583d
pvl.dns-zone: --serial
bin/pvl.dns-zone
pvl/dns/zone.py
--- a/bin/pvl.dns-zone	Wed Sep 11 14:06:16 2013 +0300
+++ b/bin/pvl.dns-zone	Wed Sep 11 14:23:26 2013 +0300
@@ -78,6 +78,10 @@
     parser.add_option('--reverse-zone',         metavar='NET',
             help="Generate forward zone for given subnet (x.z.y | a:b:c:d)")
 
+    # other
+    parser.add_option('--serial',               metavar='YYMMDDXX',
+            help="Set serial for SOA record")
+
     # defaults
     parser.set_defaults(
         # XXX: combine
@@ -139,6 +143,20 @@
 
     return fail
 
+def process_zone_soa (soa, serial) :
+    return pvl.dns.zone.SOA(
+        soa.master, soa.contact,
+        serial, soa.refresh, soa.retry, soa.expire, soa.nxttl
+    )
+
+def process_zone_serial (zone, serial) :
+    for rr in zone :
+        if rr.type == 'SOA' :
+            # XXX: as SOA record..
+            yield process_zone_soa(pvl.dns.zone.SOA.parse(rr.line), serial)
+        else :
+            yield rr
+
 def process_zone_forwards (zone, txt=False, mx=False) :
     """
         Process zone data -> forward zone data.
@@ -278,6 +296,11 @@
         else :
             log.info("Hosts check OK")
 
+    if options.serial :
+        log.info("Set zone serial: %s", options.serial)
+
+        zone = list(process_zone_serial(zone, serial=options.serial))
+
     # output file
     output = open_file(options.output, 'w', options.output_charset)
 
--- a/pvl/dns/zone.py	Wed Sep 11 14:06:16 2013 +0300
+++ b/pvl/dns/zone.py	Wed Sep 11 14:23:26 2013 +0300
@@ -191,7 +191,7 @@
                 
             else :
                 # normal record?
-                record = ZoneRecord.build(line, origin=origin)
+                record = ZoneRecord.parse(line, origin=origin)
 
                 if record :
                     yield record
@@ -201,7 +201,7 @@
                     log.warning("%s: skip unknown line: %s", line, line.line)
      
     @classmethod
-    def build (cls, line, parts=None, origin=None) :
+    def parse (cls, line, parts=None, **opts) :
         """
             Build a ZoneRecord from a ZoneLine.
         """
@@ -220,8 +220,6 @@
         else :
             name = parts.pop(0)
         
-        log.debug("  name=%r, origin=%r", name, origin)
-
         if len(parts) < 2 :
             raise ZoneLineError(line, "Too few parts to parse: {0!r}", line.data)
 
@@ -242,11 +240,15 @@
 
         log.debug("  ttl=%r, cls=%r, type=%r, data=%r", ttl, _cls, type, data)
 
-        return cls(name, type, data,
-            origin  = origin,
+        return cls.build(line, name, ttl, _cls, type, data, **opts)
+    
+    @classmethod
+    def build (_cls, line, name, ttl, cls, type, data, **opts) :
+        return _cls(name, type, data,
             ttl     = ttl,
-            cls     = _cls,
+            cls     = cls,
             line    = line,
+            **opts
         )
 
     @classmethod
@@ -301,6 +303,32 @@
             self.name, self.type, self.data
         )))
 
+class SOA (ZoneRecord) :
+    @classmethod
+    def build (_cls, line, name, ttl, cls, type, data, **opts) :
+        assert name == '@'
+
+        return _cls(*data,
+            ttl     = ttl,
+            cls     = cls,
+            line    = line,
+            **opts
+        )
+
+    def __init__ (self, master, contact, serial, refresh, retry, expire, nxttl, **opts) :
+        super(SOA, self).__init__('@', 'SOA',
+            [master, contact, serial, refresh, retry, expire, nxttl],
+            **opts
+        )
+
+        self.master = master
+        self.contact = contact
+        self.serial = serial
+        self.refresh = refresh
+        self.retry = retry
+        self.expire = expire
+        self.nxttl = nxttl
+
 class OffsetValue (object) :
     """
         Magic for $GENERATE offsets.
@@ -453,7 +481,7 @@
         log.debug(" %03d: %r", i, parts)
 
         # parse
-        yield ZoneRecord.build(line, parts=parts, origin=origin)
+        yield ZoneRecord.parse(line, parts=parts, origin=origin)
 
    
 def reverse_ipv4 (ip) :