[bind] Methodes pour manipuler des reverse d'ip dans la classe ZoneReverse

et pas qui trainent un peu partout
This commit is contained in:
Valentin Samir 2014-02-06 17:48:25 +01:00
parent e54919af92
commit dbf4496b78

View file

@ -33,25 +33,6 @@ disclamer = """//**************************************************************/
def short_name(fullhostname):
return fullhostname.split(".")[0]
def reverse(net, ip):
"""Renvoie la zone DNS inverse correspondant au réseau et à
l'adresse donnés, ainsi que le nombre d'éléments de l'ip a
mettre dans le fichier de zone."""
n = netaddr.IPNetwork(net)
a = netaddr.IPAddress(ip)
rev_dns_a = a.reverse_dns.split('.')[:-1]
assert a in n
if n.version == 4:
if n.prefixlen == 8:
return ('.'.join(rev_dns_a[3:]), 3)
elif n.prefixlen == 16:
return ('.'.join(rev_dns_a[2:]), 2)
else:
return ('.'.join(rev_dns_a[1:]), 1)
elif n.version == 6:
return ('.'.join(rev_dns_a[(128-n.prefixlen)/4:]), (128-n.prefixlen)/4)
class ResourceRecord(object):
def __init__(self, type, name, value, ttl=None):
self._type=type
@ -260,8 +241,10 @@ class Zone(ZoneBase):
class ZoneReverse(Zone):
def __init__(self, net, ttl, soa, ns_list):
if len(ZoneReverse.network_to_arpanets(net))!=1:
raise ValueError("%s n'est pas un réseau valide pour une zone de reverse dns" % net)
self.net = net
zone_name = reverse(net, net.split('/')[0])[0]
zone_name = ZoneReverse.reverse(net)[0]
if '.' in net:
ipv6=False
ipv4=True
@ -272,6 +255,55 @@ class ZoneReverse(Zone):
raise ValueError("net should be an ipv4 ou ipv6 network")
super(ZoneReverse, self).__init__(zone_name, ttl, soa, ns_list, ipv6=ipv6, ipv4=ipv4)
@staticmethod
def reverse(net, ip=None):
"""Renvoie la zone DNS inverse correspondant au réseau et à
l'adresse donnés, ainsi que le nombre d'éléments de l'ip a
mettre dans le fichier de zone si elle est fournie, n'importe
quoi sinon."""
n = netaddr.IPNetwork(net)
a = netaddr.IPAddress(ip if ip else n.ip)
rev_dns_a = a.reverse_dns.split('.')[:-1]
assert a in n
if n.version == 4:
if n.prefixlen == 8:
return ('.'.join(rev_dns_a[3:]), 3)
elif n.prefixlen == 16:
return ('.'.join(rev_dns_a[2:]), 2)
elif n.prefixlen == 24:
return ('.'.join(rev_dns_a[1:]), 1)
else:
raise ValueError("Bad network %s" % n)
elif n.version == 6:
return ('.'.join(rev_dns_a[(128-n.prefixlen)/4:]), (128-n.prefixlen)/4)
@staticmethod
def network_to_arpanets(nets):
"""
retourne une liste de reseaux ne contenant que
des préfixes de taille 32, 24, 16 ou 8 en ipv4
et laisse inchangé les réseaux ipv6.
"""
if not isinstance(nets, list):
nets = [nets]
subnets = []
for net in nets:
if not isinstance(net, netaddr.IPNetwork):
net = netaddr.IPNetwork(net)
if net.version == 4:
if net.prefixlen > 24:
subnets.extend(net.subnet(32))
elif net.prefixlen > 16:
subnets.extend(net.subnet(24))
elif net.prefixlen > 8:
subnets.extend(net.subnet(16))
else:
subnets.extend(net.subnet(8))
elif net.version == 6:
subnets.append(net)
return subnets
def add_machine(self, machine):
if machine['host']:
@ -283,7 +315,7 @@ class ZoneReverse(Zone):
raise ValueError("A reverse zone should be ipv6 or ipv6")
for ip in machine[attr]:
try:
zone, length = reverse(self.net, str(ip))
zone, length = ZoneReverse.reverse(self.net, str(ip))
nom = '.'.join(ip.value.reverse_dns.split('.')[:length])
if zone != self.zone_name:
continue
@ -402,22 +434,8 @@ class dns(gen_config) :
def gen_zones_reverse(self, ttl, ns_list, serial, zones={},
zones_reverse_v4=config.dns.zones_reverse, zones_reverse_v6=config.dns.zones_reverse_v6):
# reverse ipv4
for net in zones_reverse_v4:
net = netaddr.IPNetwork(net)
if net.prefixlen > 24:
subnets = net.subnet(32)
elif net.prefixlen > 16:
subnets = net.subnet(24)
elif net.prefixlen > 8:
subnets = net.subnet(16)
else:
subnets = net.subnet(8)
for subnet in subnets:
zones[str(subnet)]=ZoneReverse(str(subnet), ttl, self.gen_soa(ns_list, serial, ttl), ns_list)
# reverse ipv6
for net in zones_reverse_v6:
zones[net]=ZoneReverse(net, ttl, self.gen_soa(ns_list, serial, ttl), ns_list)
for net in ZoneReverse.network_to_arpanets(zones_reverse_v4 + zones_reverse_v6):
zones[str(net)]=ZoneReverse(str(net), ttl, self.gen_soa(ns_list, serial, ttl), ns_list)
return zones
def gen_zones_clone(self, ttl, ns_list, serial, zones={}):