Cleaning up
This commit is contained in:
parent
190cbfda16
commit
ccecfa4e19
1 changed files with 92 additions and 80 deletions
172
main.py
172
main.py
|
@ -152,52 +152,28 @@ def write_dns_files(api_client):
|
||||||
with open(filename, 'w+') as f:
|
with open(filename, 'w+') as f:
|
||||||
f.write(zone_file_content)
|
f.write(zone_file_content)
|
||||||
|
|
||||||
def network_to_arpanets(nets):
|
|
||||||
"""En ipv4, on ne pouvait définir
|
|
||||||
que des plages reverse en /24, /16 ou /8. Cette fonction vise à retourner
|
|
||||||
une liste des plages en tenant compte de ce critère (donc de taille
|
|
||||||
32/24/16/8)
|
|
||||||
|
|
||||||
Ne touche à rien pour l'IPv6.
|
|
||||||
"""
|
|
||||||
subnets = []
|
|
||||||
for net in nets:
|
|
||||||
if not isinstance(net, netaddr.IPNetwork):
|
|
||||||
net = netaddr.IPNetwork(net)
|
|
||||||
# on fragmente les subnets
|
|
||||||
# dans les tailles qui vont bien.
|
|
||||||
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))
|
|
||||||
return subnets
|
|
||||||
|
|
||||||
|
|
||||||
def get_arpa(cidr):
|
|
||||||
"""
|
|
||||||
Renvoie la zone DNS inverse correspondant au réseau donné.
|
|
||||||
"""
|
|
||||||
net = netaddr.IPNetwork(cidr)
|
|
||||||
byte_size = 8 if net.version == 4 else 4
|
|
||||||
addr_bytes = 4 if net.version == 4 else 32
|
|
||||||
net_class = max(((net.prefixlen - 1) // byte_size) + 1, 1)
|
|
||||||
return ".".join(
|
|
||||||
netaddr.IPAddress(net.first).reverse_dns.split('.')[addr_bytes - net_class:]
|
|
||||||
)
|
|
||||||
|
|
||||||
def get_ip_reverse(ip, prefix_length):
|
def get_ip_reverse(ip, prefix_length):
|
||||||
|
""" Truncate an ip address given a prefix length """
|
||||||
ip = netaddr.IPAddress(ip)
|
ip = netaddr.IPAddress(ip)
|
||||||
return '.'.join(ip.reverse_dns.split('.')[:prefix_length])
|
return '.'.join(ip.reverse_dns.split('.')[:prefix_length])
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def write_dns_reverse_file(api_client):
|
def write_dns_reverse_file(api_client):
|
||||||
for zone in api_client.list("dns/reverse-zones"):
|
""" Generate the reverve file for each reverse zone (= IpType)
|
||||||
|
For each IpType, we generate both an Ipv4 reverse and a v6.
|
||||||
|
The main issue is that we have to aggregat some IpTypes together,
|
||||||
|
because a reverse file can only describe a /24,/16 or /8.
|
||||||
|
"""
|
||||||
|
|
||||||
|
# We need to rember which zone file we already created for the v6
|
||||||
|
# because some iptype may share the same prefix
|
||||||
|
# in which case we must append to the file zone already created
|
||||||
|
zone_v6 = []
|
||||||
|
|
||||||
|
for zone in api_client.list("dns/reverse-zones"):
|
||||||
|
# We start by defining the soa, ns, mx which are comon to v4/v6
|
||||||
now = datetime.datetime.now(datetime.timezone.utc)
|
now = datetime.datetime.now(datetime.timezone.utc)
|
||||||
serial = now.strftime("%Y%m%d") + str(int(100*(now.hour*3600 + now.minute*60 + now.second)/86400))
|
serial = now.strftime("%Y%m%d") + str(int(100*(now.hour*3600 + now.minute*60 + now.second)/86400))
|
||||||
|
|
||||||
|
@ -215,47 +191,70 @@ def write_dns_reverse_file(api_client):
|
||||||
target=x['target'])
|
target=x['target'])
|
||||||
for x in zone['mx_records']
|
for x in zone['mx_records']
|
||||||
)
|
)
|
||||||
|
|
||||||
### Start with ipv4 reverse
|
|
||||||
net = network_to_arpanets(zone['cidrs'])[0]
|
|
||||||
# Prend la première adresse ip de la plage, sauf si une est fournie
|
|
||||||
_address = netaddr.IPAddress(net.first)
|
|
||||||
# retourne le reverse splitté. (un reverse ressemble à 0.136.231.138.in-addr.arpa.)
|
|
||||||
rev_dns_a = _address.reverse_dns.split('.')[:-1]
|
|
||||||
|
|
||||||
# En v4, le reverse étant de la forme 0.136.231.138.in-addr.arpa., soit
|
|
||||||
# on a un /8, soit un /16, soit un /24.
|
|
||||||
if net.prefixlen == 8:
|
|
||||||
zone_name,prefix_length = ('.'.join(rev_dns_a[3:]), 3)
|
|
||||||
elif net.prefixlen == 16:
|
|
||||||
zone_name,prefix_length = ('.'.join(rev_dns_a[2:]), 2)
|
|
||||||
elif net.prefixlen == 24:
|
|
||||||
zone_name,prefix_length = ('.'.join(rev_dns_a[1:]), 1)
|
|
||||||
|
|
||||||
soa = template_soa.format(zone=zone_name,
|
### We start with the v4
|
||||||
mail=soa_mail,
|
# We setup the network from the cidrs of the IpType
|
||||||
serial=serial,
|
|
||||||
refresh=zone['soa']['refresh'],
|
# For the ipv4, we need to agregate the subnets together, because
|
||||||
retry=zone['soa']['retry'],
|
# we can only have reverse for /24, /16 and /8.
|
||||||
expire=zone['soa']['expire'],
|
subnets = []
|
||||||
ttl=zone['soa']['ttl'])
|
for net in zone['cidrs']:
|
||||||
ptr_records = "\n".join(
|
net = netaddr.IPNetwork(net)
|
||||||
template_ptr.format(hostname=host['hostname']+extension,
|
# on fragmente les subnets
|
||||||
target=get_ip_reverse(host['ipv4'],prefix_length))
|
# dans les tailles qui vont bien.
|
||||||
for host in zone['ptr_records'] if host['ipv4']
|
if net.prefixlen > 24:
|
||||||
)
|
subnets.extend(net.subnet(32))
|
||||||
zone_file_content = template_reverse.format(soa=soa,
|
elif net.prefixlen > 16:
|
||||||
ns_records=ns_records,
|
subnets.extend(net.subnet(24))
|
||||||
mx_records=mx_records,
|
elif net.prefixlen > 8:
|
||||||
ptr_records = ptr_records)
|
subnets.extend(net.subnet(16))
|
||||||
|
else:
|
||||||
|
subnets.extend(net.subnet(8))
|
||||||
|
|
||||||
|
for subnet in subnets:
|
||||||
|
# Then, using the first ip address of the subnet and the
|
||||||
|
# prefix length, we can obtain the name of the reverse zone
|
||||||
|
_address = netaddr.IPAddress(subnet.first)
|
||||||
|
rev_dns_a = _address.reverse_dns.split('.')[:-1]
|
||||||
|
if subnet.prefixlen == 8:
|
||||||
|
zone_name,prefix_length = ('.'.join(rev_dns_a[3:]), 3)
|
||||||
|
elif subnet.prefixlen == 16:
|
||||||
|
zone_name,prefix_length = ('.'.join(rev_dns_a[2:]), 2)
|
||||||
|
elif subnet.prefixlen == 24:
|
||||||
|
zone_name,prefix_length = ('.'.join(rev_dns_a[1:]), 1)
|
||||||
|
|
||||||
|
soa = template_soa.format(zone=zone_name,
|
||||||
|
mail=soa_mail,
|
||||||
|
serial=serial,
|
||||||
|
refresh=zone['soa']['refresh'],
|
||||||
|
retry=zone['soa']['retry'],
|
||||||
|
expire=zone['soa']['expire'],
|
||||||
|
ttl=zone['soa']['ttl'])
|
||||||
|
ptr_records = "\n".join(
|
||||||
|
template_ptr.format(hostname=host['hostname']+extension,
|
||||||
|
target=get_ip_reverse(host['ipv4'],prefix_length))
|
||||||
|
for host in zone['ptr_records'] if host['ipv4'] in subnet
|
||||||
|
)
|
||||||
|
zone_file_content = template_reverse.format(soa=soa,
|
||||||
|
ns_records=ns_records,
|
||||||
|
mx_records=mx_records,
|
||||||
|
ptr_records = ptr_records)
|
||||||
|
|
||||||
|
filename = 'dns.{zone}zone'.format(zone=zone_name)
|
||||||
|
with open(filename, 'w+') as f:
|
||||||
|
f.write(zone_file_content)
|
||||||
|
|
||||||
filename = 'dns.{zone}zone'.format(zone=zone_name)
|
|
||||||
with open(filename, 'w+') as f:
|
|
||||||
f.write(zone_file_content)
|
|
||||||
|
|
||||||
### Continue with the ipv6 reverse
|
### Continue with the ipv6 reverse
|
||||||
# hack because we do not have the /64 info
|
# hack because we do not have the /64 info
|
||||||
zone6_name = get_arpa(zone['prefix_v6']+"/64")
|
net = netaddr.IPNetwork(zone['prefix_v6']+"/64")
|
||||||
|
net_class = max(((net.prefixlen - 1) // 4) + 1, 1)
|
||||||
|
zone6_name = ".".join(
|
||||||
|
netaddr.IPAddress(net.first).reverse_dns.split('.')[32 - net_class:]
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
soa = template_soa.format(zone=zone6_name,
|
soa = template_soa.format(zone=zone6_name,
|
||||||
mail=soa_mail,
|
mail=soa_mail,
|
||||||
serial=serial,
|
serial=serial,
|
||||||
|
@ -271,16 +270,29 @@ def write_dns_reverse_file(api_client):
|
||||||
target=get_ip_reverse(ip['ipv6'],prefix_length))
|
target=get_ip_reverse(ip['ipv6'],prefix_length))
|
||||||
for host in zone['ptr_v6_records'] for ip in host['ipv6']
|
for host in zone['ptr_v6_records'] for ip in host['ipv6']
|
||||||
)
|
)
|
||||||
|
if zone6_name in zone_v6:
|
||||||
zone_file_content = template_reverse.format(soa=soa,
|
# we already created the file, we ignore the soa
|
||||||
ns_records=ns_records,
|
zone_file_content = template_reverse.format(soa="",
|
||||||
mx_records=mx_records,
|
ns_records=ns_records,
|
||||||
ptr_records = ptr_records)
|
mx_records=mx_records,
|
||||||
|
ptr_records = ptr_records)
|
||||||
|
|
||||||
|
|
||||||
filename = 'dns.{zone}zone'.format(zone=zone6_name)
|
filename = 'dns.{zone}zone'.format(zone=zone6_name)
|
||||||
with open(filename, 'w+') as f:
|
with open(filename, 'a') as f:
|
||||||
f.write(zone_file_content)
|
f.write(zone_file_content)
|
||||||
|
else:
|
||||||
|
# we create the file from scratch
|
||||||
|
zone_file_content = template_reverse.format(soa=soa,
|
||||||
|
ns_records=ns_records,
|
||||||
|
mx_records=mx_records,
|
||||||
|
ptr_records = ptr_records)
|
||||||
|
|
||||||
|
|
||||||
|
filename = 'dns.{zone}zone'.format(zone=zone6_name)
|
||||||
|
with open(filename, 'w+') as f:
|
||||||
|
f.write(zone_file_content)
|
||||||
|
zone_v6.append(zone6_name)
|
||||||
|
|
||||||
api_client = Re2oAPIClient(api_hostname, api_username, api_password)
|
api_client = Re2oAPIClient(api_hostname, api_username, api_password)
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue