pvl.hosts-dns: support short-form --reverse-host=...
--- a/bin/pvl.hosts-dns Thu Dec 19 01:20:33 2013 +0200
+++ b/bin/pvl.hosts-dns Thu Dec 19 01:46:59 2013 +0200
@@ -93,6 +93,64 @@
# preserve ordering
yield rr
+def split_ipv6_parts (prefix) :
+ for hextet in prefix.rstrip(':').split(':') :
+ for nibble in hextet.rjust(4, '0') :
+ yield nibble
+
+def build_ipv6_parts (parts) :
+ for i in xrange(0, len(parts), 4) :
+ yield ''.join(parts[i:i+4])
+
+ # suffix ::
+ if len(parts) < 32 :
+ yield ''
+ yield ''
+
+def parse_prefix (prefix) :
+ """
+ Return an ipaddr.IPNetwork from given IPv4/IPv6 prefix.
+
+ >>> parse_prefix('127.0.0.0/8')
+ IPv4Network('127.0.0.0/8')
+ >>> parse_prefix('127.')
+ IPv4Network('127.0.0.0/8')
+ >>> parse_prefix('10')
+ IPv4Network('10.0.0.0/8')
+ >>> parse_prefix('192.168')
+ IPv4Network('192.168.0.0/16')
+ >>> parse_prefix('fe80:')
+ IPv6Network('fe80::/16')
+ >>> parse_prefix('2001:db8::')
+ IPv6Network('2001:db8::/32')
+ >>> parse_prefix('2001:db8:1:2')
+ IPv6Network('2001:db8:1:2::/64')
+ """
+
+ if '/' in prefix :
+ return ipaddr.IPNetwork(prefix)
+
+ elif '.' in prefix or prefix.isdigit() :
+ parts = prefix.rstrip('.').split('.')
+ prefixlen = len(parts) * 8
+
+ return ipaddr.IPv4Network('{prefix}/{prefixlen}'.format(
+ prefix = '.'.join(parts + ['0' for i in xrange(4 - len(parts))]),
+ prefixlen = prefixlen,
+ ))
+
+ elif ':' in prefix :
+ parts = list(split_ipv6_parts(prefix))
+ prefixlen = len(parts) * 4
+
+ return ipaddr.IPv6Network('{prefix}/{prefixlen}'.format(
+ prefix = ':'.join(build_ipv6_parts(parts)),
+ prefixlen = prefixlen,
+ ))
+
+ else :
+ raise ValueError("Unrecognized IP prefix string: %s" % (prefix, ))
+
def process_hosts_ips (options, hosts, prefix) :
"""
Yield (ip, fqnd) for hosts within given prefix.
@@ -174,7 +232,7 @@
help="Generate forward zone for domain")
parser.add_option('--reverse-zone', metavar='PREFIX',
- help="Generate reverse zone for prefx")
+ help="Generate reverse zone for prefix")
parser.add_option('--unknown-host', metavar='NAME',
help="Generate records for unused IPs")
@@ -193,7 +251,7 @@
if options.reverse_zone :
apply_zone(options,
- process_hosts_reverse(options, hosts, ipaddr.IPNetwork(options.reverse_zone)),
+ process_hosts_reverse(options, hosts, parse_prefix(options.reverse_zone)),
)
if __name__ == '__main__':