ascension

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

commit 714dd1a7629360ad72cdf4397dc01a9f803aecb4
parent 825192a3e9042f2d657f6e3e70e3bc934f1d5d5c
Author: Christian Grothoff <christian@grothoff.org>
Date:   Wed,  1 May 2019 14:39:08 +0200

restructure main loop for better error handling

Diffstat:
Mascension/ascension.py | 102++++++++++++++++++++++++++++++++++++++++----------------------------------------
1 file changed, 51 insertions(+), 51 deletions(-)

diff --git a/ascension/ascension.py b/ascension/ascension.py @@ -104,16 +104,6 @@ class Ascender(): Initialize the zone transfer generator :param serial: The serial to base the transfer on """ - if serial: - cls.zonegenerator = dns.query.xfr(cls.transferns, - cls.domain, - rdtype=dns.rdatatype.IXFR, - serial=serial, - port=cls.port) - else: - cls.zonegenerator = dns.query.xfr(cls.transferns, - cls.domain, - port=cls.port) @classmethod def bootstrap_zone(cls): @@ -175,34 +165,6 @@ class Ascender(): cls.transferns = str(soa_record[2].mname) return soa_record[2].serial - @classmethod - def mirror_zone(cls, gns_zone_serial): - """ - Extract necessary information from Generator - """ - dns_zone_serial = int(cls.get_dns_zone_serial(cls.domain, cls.transferns)) - if not gns_zone_serial: - logging.info("GNS zone does not exist yet, performing full transfer.") - try: - cls.zone = dns.zone.from_xfr(cls.zonegenerator, - check_origin=False) - except dns.zone.BadZone: - logging.critical("Malformed DNS Zone '%s'", cls.domain) - cls.soa = cls.get_zone_soa(cls.zone) - elif int(gns_zone_serial) < dns_zone_serial: - logging.info("GNS zone is out of date, performing incremental transfer.") - try: - cls.zone = dns.zone.from_xfr(cls.zonegenerator) - except dns.zone.BadZone: - logging.critical("Malformed DNS Zone '%s'", cls.domain) - cls.soa = cls.get_zone_soa(cls.zone) - elif int(gns_zone_serial) == dns_zone_serial: - logging.info("GNS zone is up to date.") - # should be unnecessary but AXFR SOA might not be equal to direct SOA - else: - # because it runs as a daemon, ignore this case but log it - logging.warning("SOA serial in GNS is bigger than SOA serial in DNS?") - logging.warning("GNS zone: %s, DNS zone: %s", gns_zone_serial, dns_zone_serial) @classmethod def add_records_to_gns(cls): @@ -737,24 +699,62 @@ def main(): # Initialize class instance ascender = Ascender(domain, transferns, port, flags, minimum) - # Event loop for actual daemon + # Set to defaults to use before we get a SOA for the first time + retry = 300 + refresh = None + # Main loop for actual daemon while True: - serial = ascender.get_gns_zone_serial() - ascender.initial_zone_transfer(serial) - ascender.mirror_zone(serial) - ascender.bootstrap_zone() - if ascender.zone is not None: - ascender.add_records_to_gns() - logging.info("Finished migration of the zone %s", ascender.domain) + gns_zone_serial = ascender.get_gns_zone_serial() + if gns_zone_serial: + ascender.zonegenerator = dns.query.xfr(ascender.transferns, + ascender.domain, + rdtype=dns.rdatatype.IXFR, + serial=gns_zone_serial, + port=ascender.port) else: - logging.info("Zone %s already up to date", ascender.domain) - # FIXME: use DNS SOA, from above, if fail retry time, if success refresh time - refresh = int(ascender.get_zone_refresh_time()) - retry = int(ascender.get_zone_retry_time()) + ascender.zonegenerator = dns.query.xfr(ascender.transferns, + ascender.domain, + port=ascender.port) + dns_zone_serial = int(ascender.get_dns_zone_serial(ascender.domain, ascender.transferns)) + if int(gns_zone_serial) == dns_zone_serial: + logging.info("GNS zone is up to date.") + if standalone: + return 0 + time.sleep(refresh) + continue + if int(gns_zone_serial) > dns_zone_serial: + logging.critical("SOA serial in GNS is bigger than SOA serial in DNS?") + logging.critical("GNS zone: %s, DNS zone: %s", gns_zone_serial, dns_zone_serial) + if standalone: + return 1 + time.sleep(retry) + continue + if not gns_zone_serial: + logging.info("GNS zone does not exist yet, performing full transfer.") + ascender.bootstrap_zone() + else + logging.info("GNS zone is out of date, performing incremental transfer.") + try: + ascender.zone = dns.zone.from_xfr(ascender.zonegenerator, + check_origin=False) + ascender.soa = ascender.get_zone_soa(ascender.zone) + # FIXME: use DNS SOA (ascender.soa), from above, if fail retry time, if success refresh time + refresh = int(ascender.get_zone_refresh_time()) + retry = int(ascender.get_zone_retry_time()) + except dns.zone.BadZone: + logging.critical("Malformed DNS Zone '%s'", ascender.domain) + if standalone: + return 2 + time.sleep(retry) + continue + + # FIXME: return value (or exception) to observe success/failure of operation! + ascender.add_records_to_gns() + logging.info("Finished migration of the zone %s", ascender.domain) if standalone: # FIXME: return non-zero on errors! return 0 - if not refresh: + if not refresh: # FIXME: if not successful with add_records_to_gns! logging.info("Unable to refresh zone, retrying in %ds", retry) time.sleep(retry) else: