1
0
mirror of https://github.com/Luzifer/dns.git synced 2024-09-19 23:32:56 +00:00
dns/generateZonefiles.py
Knut Ahlers c53cfe7330
Add zone file generator
Signed-off-by: Knut Ahlers <knut@ahlers.me>
2018-02-05 07:03:08 +01:00

100 lines
2.3 KiB
Python

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import os
# Third-party imports
import dns.resolver
import dns.rdatatype
import jinja2
import yaml
DEFAULT_TTL = 3600
def default(d, key, default=None):
if key in d:
return d[key]
return default
def resolve_alias(entry):
result = []
answers = []
answers.extend(dns.resolver.query(
entry['alias'], 'A', raise_on_no_answer=False))
answers.extend(dns.resolver.query(
entry['alias'], 'AAAA', raise_on_no_answer=False))
if len(answers) == 0:
raise Exception(
"Alias {} was not resolvable: No answers!".format(entry['alias']))
for rdata in answers:
new_entry = entry.copy()
del new_entry['alias']
new_entry['type'] = dns.rdatatype.to_text(rdata.rdtype)
new_entry['data'] = rdata.address
result.append(new_entry)
return result
def sanitize(entry):
result = []
if entry['name'] == '':
entry['name'] = '@'
if 'alias' in entry:
return resolve_alias(entry)
for rr in entry['records']:
new_entry = entry.copy()
del new_entry['records']
new_entry['data'] = rr
if new_entry['type'] == 'TXT' and new_entry['data'][0] != '"':
new_entry['data'] = '"{}"'.format(new_entry['data'])
result.append(new_entry)
return result
def write_zone(zone, ttl, soa, nameserver, mailserver, entries):
tpl = jinja2.Template(open("zone_template.j2").read())
zone_content = tpl.render({
"zone": zone,
"ttl": ttl,
"soa": soa,
"nameserver": nameserver,
"mailserver": mailserver,
"entries": entries,
})
with open("zones/tmp.{}".format(zone), 'w') as zf:
zf.write(zone_content)
# FIXME (kahlers): Check if contents changed
os.rename("zones/tmp.{}".format(zone), "zones/db.{}".format(zone))
def main():
zone_data = yaml.load(open("zones.yml"))
for zone, config in zone_data['zones'].items():
ttl = default(config, "default_ttl", DEFAULT_TTL)
entries = []
for entry in config['entries']:
entries.extend(sanitize(entry))
write_zone(zone, ttl, zone_data['soa'],
zone_data['nameserver'], default(config, 'mailserver', {}), entries)
if __name__ == "__main__":
main()