ascension

Migrate DNS zones to the GNU Name System
Log | Files | Refs | README | LICENSE

commit ecd247943b01aa4da58643e2d3c8c04bb8638740
parent 666f93fac2cece64606f66d1b457ae0a009cd59a
Author: rexxnor <rexxnor+gnunet@brief.li>
Date:   Sat, 13 Oct 2018 21:03:58 +0200

finished refactoring, fixed a few bugs

Diffstat:
Mgnsmigrator/gnsmigrator.py | 137+++++++++++++++++++++++++++++++++++++++++++++++++------------------------------
1 file changed, 86 insertions(+), 51 deletions(-)

diff --git a/gnsmigrator/gnsmigrator.py b/gnsmigrator/gnsmigrator.py @@ -319,17 +319,18 @@ class BaseMigrator(): if not BaseMigrator.check_if_record_exists_in_zone(record, zonename): dnsname, ttl, rdata = record nameserver = str(rdata) - if nameserver[-1] == ".": - dnsresolver = nameserver[:-1] - else: - dnsresolver = "%s.%s" % (rdata, domain) - dnsresolver = nameserver[:-1] if str(dnsname)[-1] == ".": dnsname = str(dnsname)[:-1] if domain[-1] == ".": domain = domain[:-1] + if nameserver[-1] == ".": + dnsresolver = nameserver[:-1] + else: + dnsresolver = "%s.%s" % (rdata, domain) + + pkey_lookup = sp.Popen([GNUNET_ZONE_CREATION_COMMAND, '-d'], stdout=sp.PIPE) pkey_line = sp.Popen(['grep', str(dnsname)], @@ -399,9 +400,13 @@ class BaseMigrator(): """ if zonename[-1] == '.': zonename = zonename[:-1] - serial = sp.check_output([GNUNET_GNS_COMMAND, - '-t', 'SOA', - '-u', '@.%s' % zonename]) + try: + serial = sp.check_output([GNUNET_GNS_COMMAND, + '-t', 'SOA', + '-u', '@.%s' % zonename]) + except sp.CalledProcessError: + soa_serial = 0 + return soa_serial serial = serial.decode() soapattern = re.compile(r'.+\s(\d+),\d+,+\d+,\d+,\d+', re.M) if re.findall(soapattern, serial): @@ -460,8 +465,7 @@ class TLDMigrator(BaseMigrator): @classmethod - def mirror_zone(cls, zone_factory=dns.zone.Zone, - relativize=True, check_origin=True): + def mirror_zone(cls): """ Extract necessary information from Generator """ @@ -470,47 +474,58 @@ class TLDMigrator(BaseMigrator): try: with gzip.open('%s.zone.gz' % cls.tld[:-1], 'rb') as zonefile: zone = pickle.load(zonefile) - except Exception: - pass + cls.zone = zone + except FileNotFoundError as filenotfound: + print(filenotfound) currentserial = cls.get_current_serial(cls.tld) zoneserial = None if zone: - zoneserial = zone[0][2].split(' ')[2].split(',')[0] - if currentserial != zoneserial: - try: - for message in cls.zonegenerator: - origin = message.origin - rdclass = message.answer[0].rdclass - if zone is None: - if relativize: - origin = message.origin - else: - origin = message.answer[0].name - rdclass = message.answer[0].rdclass - zone = zone_factory(origin, rdclass, relativize=relativize) - for rrset in message.answer: - znode = zone.nodes.get(rrset.name) - if not znode: - znode = zone.node_factory() - zone.nodes[rrset.name] = znode - zrds = znode.find_rdataset(rrset.rdclass, rrset.rdtype, - rrset.covers, True) - zrds.update_ttl(rrset.ttl) - for record in rrset: - record.choose_relativity(zone.origin, relativize) - zrds.add(record) - if check_origin: - zone.check_origin() - cls.zone = zone - except Exception as transferexception: - print("Error occured during Zone transfer: %s" % transferexception) - - # To zip and pickle: + for record in zone.iterate_rdatas(rdtype=dns.rdatatype.SOA): + zoneserial = str(record[2]).split(' ')[2].split(',')[0] + break + else: + if currentserial != zoneserial: + cls.transfer_zone() + # zip and pickle the zone with gzip.open('%s.zone.gz' % cls.tld[:-1], 'wb') as zonefile: pickle.dump(zone, zonefile) @classmethod + def transfer_zone(cls, zone_factory=dns.zone.Zone, + relativize=True, check_origin=True): + """ + Do the actual zone transfer + """ + try: + for message in cls.zonegenerator: + origin = message.origin + rdclass = message.answer[0].rdclass + if zone is None: + if relativize: + origin = message.origin + else: + origin = message.answer[0].name + rdclass = message.answer[0].rdclass + zone = zone_factory(origin, rdclass, relativize=relativize) + for rrset in message.answer: + znode = zone.nodes.get(rrset.name) + if not znode: + znode = zone.node_factory() + zone.nodes[rrset.name] = znode + zrds = znode.find_rdataset(rrset.rdclass, rrset.rdtype, + rrset.covers, True) + zrds.update_ttl(rrset.ttl) + for record in rrset: + record.choose_relativity(zone.origin, relativize) + zrds.add(record) + if check_origin: + zone.check_origin() + cls.zone = zone + except Exception as transferexception: + print("Error occured during Zone transfer: %s" % transferexception) + + @classmethod def multithreaded_add_records_to_gns(cls): """ Extracts records from zone and adds them to GNS @@ -535,15 +550,8 @@ class TLDMigrator(BaseMigrator): # building gns record struct #GNUnetGNSRecordData() + cls.add_record_to_gns(record, zonename, cls.tld) - sp.run([GNUNET_NAMESTORE_COMMAND, - '-z', zonename, - '-a', '-n', str(dnsname), - '-t', 'GNS2DNS', - '-V', '%s.%s@%s' % (str(dnsname), - zonename, - str(authns)), - '-e', '%ds' % int(ttl)]) taskqueue.task_done() # Create threads @@ -566,6 +574,33 @@ class TLDMigrator(BaseMigrator): for thread in threads: thread.join() + @staticmethod + def add_record_to_gns(record, zonename, domain): + """ + Checks if records are present and adds them if not + :param record: record to add + :param zonename: zonename of zone to add records to + :param domain: full domain of zone + """ + dnsname_str = str(record[0]) + rtype_str = dns.rdatatype.to_text(record[2].rdtype) + if dnsname_str == '@': + if rtype_str == 'SOA': + BaseMigrator.add_soa_record_to_gns(record, zonename, domain) + else: + if rtype_str == 'NS' and dnsname_str != '@': + BaseMigrator.add_ns_record_to_gns(record, zonename, domain) + elif rtype_str == 'MX': + BaseMigrator.add_mx_record_to_gns(record, zonename) + #elif rtype_str == 'SRV': + # BaseMigrator.add_srv_record_to_gns(record, zonename) + elif rtype_str in ['A', 'AAAA']: + BaseMigrator.add_a_aaaa_record_to_gns(record, zonename, domain) + elif rtype_str in ['TXT', 'CNAME']: + BaseMigrator.add_gen_record_to_gns(record, zonename) + else: + print("Record type %s is not yet supported" % rtype_str) + def main(): """