From f30794f6354d7d10d3f6eb67eb358a5ea46d6862 Mon Sep 17 00:00:00 2001 From: Otthorn Date: Sun, 4 Apr 2021 20:40:46 +0200 Subject: [PATCH] Better handlers (not tested yet) --- main.py | 203 +++++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 148 insertions(+), 55 deletions(-) diff --git a/main.py b/main.py index 2f1516e..9cbd87d 100644 --- a/main.py +++ b/main.py @@ -1,5 +1,6 @@ #! /bin/env python3 import argparse +import collections import configparser import dns.name @@ -7,8 +8,6 @@ import dns.rdataset import dns.rdatatype from dns.rdtypes import * -import collections - from re2oapi import Re2oAPIClient @@ -23,12 +22,13 @@ def format_rname(mail: str): Return a `dns.name.Name` object. """ - local, domain = mail.split('@') + local, domain = mail.split("@") rname = dns.name.Name((local, *dns.name.from_text(domain))) - + return rname -def format_mname(name : str): + +def format_mname(name: str): """ Format a zone name given by the re2o API to a mname dnspython object. @@ -37,54 +37,174 @@ def format_mname(name : str): Return a `dns.name.name` object. """ - - if name[0] == '.': + + if name[0] == ".": name = name[1:] mname = dns.name.from_text(name) return mname -def in_class_record(*args): - return dns.rdata.from_text(dns.rdataclass.IN, *args) +HANDLERS = { + "soa": soa_handler, + "originv4": originv4_handler, + "originv6": originv6_handler, + "ns_records": ns_records_handler, + "sshfp": sshfp_handler, + "mx_records": mx_records_handler, + "txt_records": txt_records_handler, + "srv_records": srv_records_handler, + "a_records": a_records_handler, + "aaaa_records": aaaa_records_handler, +} + +def soa_hanlder((zone, records): + soa = zone['soa'] + + records['@'].append( + dns.rdtypes.ANY.SOA.SOA( + dns.rdataclass.IN, + dns.rdatatype.SOA, + format_mname(soa["name"]), + format_rname(soa["mail"]), + soa["serial"], + soa["refresh"], + soa["retry"], + soa["expire"], + soa["ttl"], + ) + ) + +def originv4_hanlder(zone, records): + """Handler for the IPv4 origin""" + + ipv4_addr = zone["originv4"]["ipv4"] + records['@'].append( + dns.rdtypes.ANY.A.A( + dns.rdataclass.IN, + dns.rdatatypes.A, + ipv4_addr + ) + ) -def a_record(address): - return in_class_record(dns.rdataclass.A, address) +def originv6_handler(zone, records): + """Handler for the IPv6 origin""" + ipv6_addr = zone["originv6"] # Yes, re2o is this weird and inconsistent -def aaaa_record(address): - return in_class_record(dns.rdataclass.AAAA, address) + records['@'].append( + dns.rdtypes.ANY.AAAA.AAAA( + dns.rdataclass.IN, + dns.rdatatype.AAAA, + ipv6_addr + ) + ) +def ns_records_handler(zone, records): + """Handler for the NS record""" -def ns_record(address): - return in_class_record(dns.rdataclass.NS, address) + for record in zone["ns_records"]: + + target = record["target"] + records["@"].append( + dns.rdtypes.ANY.NS.NS( + dns.rdataclass.IN, + dns.rdatatype.NS, + target + ) + ) -def sshfp_record(algo_id, fp_type, fp): - return in_class_record(dns.rdatatype.SSHFP, algo_id, fp_type, fp) +def sshfp_record_handler(zone, records): + """Handler for the SSHFP record""" + for record in zone["sshfp"]: + for fp in record["sshfp"]: + + algorithm = fp["algo_id"] -def mx_record(priority, target): - return in_class_record(dns.rdatatype.MX, priority, target) + for fp_type in fp["hash"]: + fingerprint = fp["hash"][fp_type] -def txt_record(data): - return in_data_record(dns.rdatatype.TXT, data) + records[record["hostname"]].append( + dns.rdtype.ANY.SSHFP.SSHFP( + dns.rdataclass.IN, + dns.rdatatype.AAAA, + algorithm, + fp_type, + fingerprint + ) + ) +def txt_records_handler(zone, records): + """Handler for TXT record""" + + for record in zone["txt_records"]: + + zone_name = record["field1"] + + records[zone_name].append( + dns.rdtypes.ANY.TXT.TXT( + dns.rdataclass.IN, + dns.rdatatype.AAAA, + record["field2"] + ) + +def srv_records_handler(zone, records): + """Handler for SRV record""" + + for record in zone["srv_records"]: + name = dns.name.from_text(f"{record['service']}_{record['protocol']}") + + name_key = name.to_text() + + records[name_key].append( + dns.rdtypes.ANY.SRV.SRV( + dns.rdataclass.IN, + dns.rdatatype.SRV, + record['priority'], + record['weight'], + record['port'], + record['target'] + ) + ) + + +def a_records_handler(zone, recordds): + """Handler for A Record""" + + for record in zone["a_records"]: + records[record["hostname"]].append( + dns.rdtypes.ANY.A.A(( + dns.rdataclass.IN, + dns.rdatatype.A, + record["ipv4"], + ) + ) parser = argparse.ArgumentParser() -parser.add_argument("-c", "--config", help="Path to the config file", type=str, - default="config.ini") +parser.add_argument( + "-c", + "--config", + help="Path to the config file", + type=str, + default="config.ini", +) args = parser.parse_args() config = configparser.ConfigParser() config.read(args.config) -api_client = Re2oAPIClient(config['Re2o']['hostname'], config['Re2o']['username'], config['Re2o']['password'], - use_tls=False) +api_client = Re2oAPIClient( + config["Re2o"]["hostname"], + config["Re2o"]["username"], + config["Re2o"]["password"], + use_tls=False, +) zones = api_client.list("dns/zones") @@ -92,34 +212,7 @@ records = collections.defaultdict(list) # zone = zones[0] -HANDLERS = { - 'soa' : soa_handler, - 'originv4': originv4_handler, - 'originv6': originv6_handler, - 'sshfp': sshfp_handler, - 'mx_records': mx_records_handler, - 'txt_records': txt_records_handler, - 'srv_records': srv_records_handler, - 'a_records': a_records_handler, - 'aaaa_records': aaaa_records_handler, -} - -records['@'].append( - dns.rdtypes.ANY.SOA.SOA( - dns.rdataclass.IN, - dns.rdatatype.SOA, - format_mname(zone['soa']['name']), - format_rname(zone['soa']['mail']), - zone['soa']['serial'], - zone['soa']['refresh'], - zone['soa']['retry'], - zone['soa']['expire'], - zone['soa']['ttl'] - ) -) - -if zone['originv4'] is not None: - records['@'].append( - a_record(zone['originv4']['ipv4']) - ) +for zone in zones: + for entry in zone: + HANDLERS[entry](zone, records)