pvl.hosts: support alias4/6=... for A/AAAA CNAMES
--- a/bin/pvl.hosts-dns Tue Dec 17 17:44:47 2013 +0200
+++ b/bin/pvl.hosts-dns Wed Dec 18 22:35:48 2013 +0200
@@ -30,21 +30,45 @@
if host.ip :
yield pvl.dns.zone.ZoneRecord.A(host, host.ip)
+ if host.alias4 :
+ yield pvl.dns.zone.ZoneRecord.A(host.ALIAS4_FMT.format(host=host), host.ip)
+
+ if host.ip6 :
+ yield pvl.dns.zone.ZoneRecord.AAAA(host, host.ip6)
+
+ if host.alias6 :
+ yield pvl.dns.zone.ZoneRecord.AAAA(host.ALIAS6_FMT.format(host=host), host.ip6)
+
for alias in host.alias :
yield pvl.dns.zone.ZoneRecord.CNAME(alias, host)
+ for alias4 in host.alias4 :
+ yield pvl.dns.zone.ZoneRecord.CNAME(alias4, host.ALIAS4_FMT.format(host=host))
+
+ for alias6 in host.alias6 :
+ yield pvl.dns.zone.ZoneRecord.CNAME(alias6, host.ALIAS6_FMT.format(host=host))
+
def process_hosts_forward (options, hosts, domain) :
"""
Generate DNS ZoneRecords for the given domain's zone for hosts.
"""
by_name = dict()
+ by_name_type = dict()
+
+ # list of types thare are allowed to be present for a host
+ MULTI_TYPES = ('A', 'AAAA')
for rr in process_hosts_names(options, hosts, domain) :
- if rr.name in by_name :
+ if (rr.name, rr.type) in by_name_type :
+ raise ValueError("%s: duplicate name/type: %s: %s" % (rr.name, rr, by_name_type[(rr.name, rr.type)]))
+ elif rr.type in MULTI_TYPES :
+ by_name_type[(rr.name, rr.type)] = rr
+ elif rr.name in by_name :
raise ValueError("%s: duplicate name: %s: %s" % (rr.name, rr, by_name[rr.name]))
- else :
- by_name[rr.name] = rr
+
+ # always check these
+ by_name[rr.name] = rr
# preserve ordering
yield rr
--- a/pvl/dns/zone.py Tue Dec 17 17:44:47 2013 +0200
+++ b/pvl/dns/zone.py Wed Dec 18 22:35:48 2013 +0200
@@ -312,8 +312,12 @@
)
@classmethod
- def A (cls, name, ip, **opts) :
- return cls(str(name), 'A', [str(ip)], **opts)
+ def A (cls, name, ip4, **opts) :
+ return cls(str(name), 'A', [str(ip4)], **opts)
+
+ @classmethod
+ def AAAA (cls, name, ip6, **opts) :
+ return cls(str(name), 'AAAA', [str(ip6)], **opts)
@classmethod
def CNAME (cls, name, host, **opts) :
--- a/pvl/hosts.py Tue Dec 17 17:44:47 2013 +0200
+++ b/pvl/hosts.py Wed Dec 18 22:35:48 2013 +0200
@@ -21,6 +21,10 @@
return hosts
class Host (object) :
+ # the label used for alias4/6 hosts
+ ALIAS4_FMT = '{host}-ipv4'
+ ALIAS6_FMT = '{host}-ipv6'
+
@classmethod
def expand (cls, options, host, range, ip, **opts) :
host = pvl.dns.zone.parse_generate_field(host)
@@ -51,7 +55,7 @@
yield cls.build(options, host, ip=ip, **extra)
@classmethod
- def build (cls, options, host, domain=None, ip=None, ip6=None, owner=None, boot=None, alias=None, **extra) :
+ def build (cls, options, host, domain=None, ip=None, ip6=None, owner=None, boot=None, alias=None, alias4=None, alias6=None, **extra) :
"""
Return a Host from a config section's scalars.
"""
@@ -60,6 +64,16 @@
alias = alias.split()
else :
alias = ()
+
+ if alias4 :
+ alias4 = alias4.split()
+ else :
+ alias4 = ()
+
+ if alias6 :
+ alias6 = alias6.split()
+ else :
+ alias6 = ()
ethernet = { }
@@ -87,11 +101,13 @@
ip6 = ipaddr.IPv6Address(ip6) if ip6 else None,
ethernet = ethernet,
alias = alias,
+ alias4 = alias4,
+ alias6 = alias6,
owner = owner,
boot = boot,
)
- def __init__ (self, host, domain=None, ip=None, ip6=None, ethernet={ }, alias=(), owner=None, boot=None) :
+ def __init__ (self, host, domain=None, ip=None, ip6=None, ethernet={ }, alias=(), owner=None, boot=None, alias4=None, alias6=None) :
"""
host - str
domain - str
@@ -100,6 +116,8 @@
ethernet - { index: ethernet }
alias - list
owner - str: LDAP uid
+ alias4 - list (CNAME -> A)
+ alias6 - list (CNAME -> AAAA)
"""
self.host = host
self.domain = domain
@@ -107,6 +125,8 @@
self.ip6 = ip6
self.ethernet = ethernet
self.alias = alias
+ self.alias4 = alias4
+ self.alias6 = alias6
self.owner = owner
self.boot = boot