ascension

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

commit e5161d1423034ab2319fa9147e24f28ceaa068a9
parent ba3c40287c006334dcceac8502f351982bffde1b
Author: rexxnor <rexxnor+gnunet@brief.li>
Date:   Thu, 18 Oct 2018 10:28:50 +0200

fixed bugs

Diffstat:
Mgnsmigrator/gnsmigrator.py | 59++++++++++++++++++++++++++++++++++++++++++++---------------
1 file changed, 44 insertions(+), 15 deletions(-)

diff --git a/gnsmigrator/gnsmigrator.py b/gnsmigrator/gnsmigrator.py @@ -23,8 +23,6 @@ from ctypes import c_void_p from enum import Enum from dataclasses import dataclass import multiprocessing -import gzip -import pickle import queue import re import sys @@ -401,6 +399,29 @@ class BaseMigrator(): soa_answer = dns.resolver.query(domain, 'SOA') return soa_answer[0].serial + @staticmethod + def get_zone_serial(zonename): + """ + Extracts the current serial from a given zone + """ + if zonename[-1] == '.': + zonename = zonename[:-1] + try: + serial = sp.check_output([GNUNET_GNS_COMMAND, + '-t', 'SOA', + '-u', '@.%s' % zonename]) + serial = serial.decode() + except sp.CalledProcessError: + serial = "" + soa_serial = 0 + soapattern = re.compile(r'.+\s(\d+),\d+,+\d+,\d+,\d+', re.M) + if re.findall(soapattern, serial): + soa_serial = re.findall(soapattern, serial)[0] + else: + soa_serial = 0 + return soa_serial + + class ZoneMigrator(BaseMigrator): """ Class that migrates small zones efficiently @@ -456,12 +477,6 @@ class TLDMigrator(BaseMigrator): """ zone = None # And to unzip and unpickle: - try: - with gzip.open('%s.zone.gz' % cls.tld[:-1], 'rb') as zonefile: - zone = pickle.load(zonefile) - cls.zone = zone - except FileNotFoundError as filenotfound: - print(filenotfound) currentserial = cls.get_current_serial(cls.tld) zoneserial = 0 @@ -472,17 +487,30 @@ class TLDMigrator(BaseMigrator): else: if zoneserial == 0: cls.initial_zone_transfer() - if zoneserial < currentserial: cls.transfer_zone() + elif zoneserial < currentserial and zoneserial != 0: + cls.merge_zones() - # zip and pickle the zone - with gzip.open('%s.zone.gz' % cls.tld[:-1], 'wb') as zonefile: - pickle.dump(cls.zone, zonefile) + @classmethod + def merge_zones(cls): + """ + Fetch diff and merge zones + """ + currentzone = cls.zone + partialzone = dns.zone.from_xfr(cls.zonegenerator) + for rdata in partialzone.iterate_rdatasets(dns.rdatatype.NS): + name, rdataset = rdata + current_set = currentzone.get_rdataset(name, dns.rdatatype.NS, + create=True) + current_set.union_update(rdataset) + for soarecord in partialzone.iterate_rdatas(dns.rdatatype.SOA): + name, _, rdata = soarecord + if str(name) == '@': + super().add_soa_record_to_gns(soarecord, cls.tld[:-1], cls.tld) @classmethod def transfer_zone(cls, zone_factory=dns.zone.Zone, - relativize=True, check_origin=True - ): + relativize=True, check_origin=True): """ Do the actual zone transfer """ @@ -514,6 +542,7 @@ class TLDMigrator(BaseMigrator): cls.zone = zone except Exception as transferexception: print("Error occured during Zone transfer: %s" % transferexception) + raise @classmethod def multithreaded_add_records_to_gns(cls): @@ -613,7 +642,7 @@ def main(): if tld and transferns: migrator = TLDMigrator(tld, transferns) - serial = migrator.get_current_serial(tld) + serial = migrator.get_zone_serial(tld) migrator.initial_zone_transfer(serial) migrator.bootstrap_zone() migrator.mirror_zone()