--- a/pvl/hosts/__init__.py Mon Mar 09 18:00:18 2015 +0200
+++ b/pvl/hosts/__init__.py Mon Mar 09 19:47:10 2015 +0200
@@ -7,4 +7,5 @@
from pvl.hosts.host import (
HostError,
Host,
+ extension,
)
--- a/pvl/hosts/host.py Mon Mar 09 18:00:18 2015 +0200
+++ b/pvl/hosts/host.py Mon Mar 09 19:47:10 2015 +0200
@@ -154,10 +154,18 @@
A host is a network node that can have multiple ethernet interfaces, and multiple IP addresses in different domains.
"""
- # the label used for alias4/6 hosts
- ALIAS4_FMT = '{host}-ipv4'
- ALIAS6_FMT = '{host}-ipv6'
-
+ EXTENSIONS = { }
+
+ @classmethod
+ def build_extensions(cls, extensions):
+ for extension, value in extensions.iteritems():
+ extension_cls = cls.EXTENSIONS.get(extension)
+
+ if extension_cls:
+ yield extension, extension_cls.build(**value)
+ else:
+ log.warning("skip unknown extension: %s", extension)
+
@classmethod
def build (cls, name, domain,
ip=None, ip6=None,
@@ -181,6 +189,7 @@
ip = {label: (ip4.get(label), ip6.get(label)) for label in set(ip4) | set(ip6)}
+
return cls(name,
domain = domain,
ip4 = ip4.get(None),
@@ -196,7 +205,7 @@
reverse = parse_str(reverse),
down = parse_bool(down),
boot = parse_dhcp_boot(boot),
- extensions = extensions,
+ extensions = dict(cls.build_extensions(extensions)),
)
def __init__ (self, name, domain,
@@ -260,6 +269,23 @@
# sorts first
return ipaddr.IPAddress(0)
+ def addresses (self):
+ """
+ Yield (sublabel, ipaddr) records.
+ """
+
+ for sublabel, (ip4, ip6) in self.ip.iteritems():
+
+ if ip4:
+ yield sublabel, ip4
+
+ if ip6:
+ yield sublabel, ip6
+
+ for extension in self.extensions.itervalues():
+ for sublabel, ip in extension.addresses():
+ yield sublabel, ip
+
def fqdn (self):
if self.domain:
return pvl.dns.fqdn(self.name, self.domain)
@@ -270,3 +296,19 @@
return "{self.name}@{domain}".format(self=self,
domain = self.domain or '',
)
+
+class HostExtension (object):
+ """
+ Extension hooks
+ """
+
+ def addresses (self):
+ return ()
+
+def extension (cls):
+ """
+ Register an extension class
+ """
+
+ Host.EXTENSIONS[cls.EXTENSION] = cls
+
--- a/pvl/hosts/zone.py Mon Mar 09 18:00:18 2015 +0200
+++ b/pvl/hosts/zone.py Mon Mar 09 19:47:10 2015 +0200
@@ -31,21 +31,24 @@
elif host.forward is None:
# forward
- for sublabel, (ip4, ip6) in host.ip.iteritems():
+ for sublabel, ip in host.addresses():
if sublabel:
sublabel = pvl.dns.join(sublabel, label)
else:
sublabel = label
- if ip4:
- log.info("%s: ip: %s@%s A %s", host, sublabel, origin, ip4)
+ if ip.version == 4:
+ log.info("%s: ip: %s@%s A %s", host, sublabel, origin, ip)
- yield pvl.dns.ZoneRecord.A(sublabel, ip4)
+ yield pvl.dns.ZoneRecord.A(sublabel, ip)
- if ip6:
- log.info("%s: ip6: %s@%s AAAA %s", host, label, origin, ip6)
+ elif ip.version == 6:
+ log.info("%s: ip6: %s@%s AAAA %s", host, label, origin, ip)
- yield pvl.dns.ZoneRecord.AAAA(sublabel, ip6)
+ yield pvl.dns.ZoneRecord.AAAA(sublabel, ip)
+
+ else:
+ raise ValueError(ip)
else:
log.info("%s: skip forward", host)
@@ -79,30 +82,22 @@
Yield (ipaddr.IPAddress, ZoneRecord) tuples for host within given prefix's reverse-dns zone.
"""
- for sublabel, (ip4, ip6) in host.ip.iteritems():
- if prefix.version == 4:
- ip = ip4
-
- # reverse= is IPv4-only
- reverse = host.reverse
-
- elif prefix.version == 6:
- ip = ip6
-
- # if reverse= is set, always omit, for lack of reverse6=
- reverse = None if host.reverse is None else False
-
- else:
- raise ValueError("%s: unknown ip version: %s" % (prefix, prefix.version))
-
- if not ip:
- log.debug("%s: no ip%d", host, prefix.version)
+ for sublabel, ip in host.addresses():
+ if ip.version != prefix.version:
continue
if ip not in prefix:
log.debug("%s: %s out of prefix: %s", host, ip, prefix)
continue
-
+
+ if ip.version == 4:
+ # reverse= is IPv4-only
+ reverse = host.reverse
+
+ elif prefix.version == 6:
+ # if reverse= is set, always omit, for lack of reverse6=
+ reverse = None if host.reverse is None else False
+
# relative label
label = pvl.dns.reverse_label(prefix, ip)