From 16f6bb5eabc27c48a328e148a5208cab4b17b108 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ma=C3=ABl=20Kervella?= Date: Sat, 23 Jun 2018 21:01:00 +0000 Subject: [PATCH] Basic generataion of full DNS zone files --- .gitignore | 4 ++ config.ini.example | 4 ++ main.py | 150 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 158 insertions(+) create mode 100644 .gitignore create mode 100644 config.ini.example create mode 100644 main.py diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e663f98 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +config.ini +**/__pycache__/** +**.zone +**.reverse diff --git a/config.ini.example b/config.ini.example new file mode 100644 index 0000000..60a6b33 --- /dev/null +++ b/config.ini.example @@ -0,0 +1,4 @@ +[Re2o] +hostname = re2o.example.net +username = my_api_username +password = my_api_password diff --git a/main.py b/main.py new file mode 100644 index 0000000..1949299 --- /dev/null +++ b/main.py @@ -0,0 +1,150 @@ +from configparser import ConfigParser +import socket +import datetime + +from re2oapi import Re2oAPIClient + +config = ConfigParser() +config.read('config.ini') + +api_hostname = config.get('Re2o', 'hostname') +api_password = config.get('Re2o', 'password') +api_username = config.get('Re2o', 'username') + +template_soa = ("{zone} IN SOA ns.{zone}. {mail} (\n" + " {serial} ; serial\n" + " {refresh} ; refresh\n" + " {retry} ; retry\n" + " {expire} ; expire\n" + " {ttl} ; ttl\n" + ")") +template_originv4 = "@ IN A {ipv4}" +template_originv6 = "@ IN AAAA {ipv6}" +template_ns = "@ IN NS {target}" +template_mx = "@ IN MX {priority} {target}" +template_txt = "{field1} IN TXT {field2}" +template_srv = "_{service}._{protocol}.{zone} {ttl} IN SRV {priority} {weight} {port} {target}" +template_a = "{hostname} IN A {ipv4}" +template_aaaa = "{hostname} IN AAAA {ipv6}" +template_cname = "{hostname} IN CNAME {alias}{extension}" + +template_zone = ("{soa}\n" + "\n" + "{originv4}\n" + "{originv6}\n" + "\n" + "{ns_records}\n" + "\n" + "{mx_records}\n" + "\n" + "{txt_records}\n" + "\n" + "{srv_records}\n" + "\n" + "{a_records}\n" + "\n" + "{aaaa_records}\n" + "\n" + "{cname_records}") + + +def regen_dns(api_client): + for zone in api_client.list_dnszones(): + zone_name = zone['name'][1:] + + 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)) + + soa_mail_fields = zone['soa']['mail'].split('@') + soa_mail = "{}.{}.".format(soa_mail_fields[0].replace('.', '\\.'), + soa_mail_fields[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']) + + originv4 = template_originv4.format(ipv4=zone['originv4']['ipv4']) + if zone['originv6'] is not None: + originv6 = template_originv6.format(ipv6=zone['originv6']) + else: + originv6 = "" + + ns_records = "\n".join( + template_ns.format(target=x['target']) + for x in zone['ns_records'] + ) + + mx_records = "\n".join( + template_mx.format(priority=x['priority'], + target=x['target']) + for x in zone['mx_records'] + ) + + txt_records = "\n".join( + template_txt.format(field1=x['field1'], + field2=x['field2']) + for x in zone['txt_records'] + ) + + srv_records = "\n".join( + template_srv.format(service=x['service'], + protocol=x['protocol'], + zone=zone_name, + ttl=x['ttl'], + priority=x['priority'], + weight=x['weight'], + port=x['port'], + target=x['target']) + for x in zone['srv_records'] + ) + + a_records = "\n".join( + template_a.format(hostname=x['hostname'], + ipv4=x['ipv4']) + for x in zone['a_records'] + ) + + aaaa_records = "\n".join( + template_aaaa.format(hostname=x['hostname'], + ipv6=x['ipv6']) + for x in zone['aaaa_records'] if x['ipv6'] is not None + ) + + cname_records = "\n".join( + template_cname.format(hostname=x['hostname'], + alias=x['alias'], + extension=x['extension']) + for x in zone['cname_records'] + ) + + zone_file_content = template_zone.format(soa=soa, + originv4=originv4, + originv6=originv6, + ns_records=ns_records, + mx_records=mx_records, + txt_records=txt_records, + srv_records=srv_records, + a_records=a_records, + aaaa_records=aaaa_records, + cname_records=cname_records) + + filename = 'dns.{zone}.zone'.format(zone=zone_name) + with open(filename, 'w+') as f: + f.write(zone_file_content) + + + +api_client = Re2oAPIClient(api_hostname, api_username, api_password) + +client_hostname = socket.gethostname().split('.', 1)[0] + +for service in api_client.list_servicesregen(): +# if service['hostname'] == client_hostname and \ +# service['service_name'] == 'dns' and \ +# service['need_regen']: + regen_dns(api_client) +# api_client.patch(service['api_url'], data={'need_regen': False})