ascension

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

commit 5959ec4b5c25879af265cb4e0ce251bd6c69b457
parent f977d102c9e6f7fcb642236e358b3ec915ed8787
Author: Martin Schanzenbach <schanzen@gnunet.org>
Date:   Tue, 22 Oct 2024 21:31:02 +0200

update recent minor changes

Diffstat:
Mascension/ascension.py | 27++++++++++++++++++++++++---
Mascension/util/classes.py | 28++++++++++++++++++++++++++--
2 files changed, 50 insertions(+), 5 deletions(-)

diff --git a/ascension/ascension.py b/ascension/ascension.py @@ -114,7 +114,7 @@ class Ascension(): self.dnszone ) - + def add_records_to_gns(self) -> None: """ @@ -225,7 +225,7 @@ class Ascension(): payload = record_data if not record_data.data: self.logger.warning("Empty record %s", record_data) - return + return "", None #self.logger.debug("Payload: %s", payload.to_json()) # Replace the records already present in GNS as old ones are not deleted @@ -259,12 +259,25 @@ class Ascension(): setcount = len(self.dnszone.zone.nodes.items()) pp_set = {} rrcount = 0 + # TODO: + # So, what we want to do here is to get all "dirty" + # record sets. Dirty record sets are records that were + # modified during the last pass (should here always be + # > 0 since serial changed) + # We may have just been given an AXFR even though IXFR was + # requested. + # So, after we add the records with the new serial, we + # should delete all records with the old. + # CAREFUL: This would mean that if the did receive an IXFR, + # we have to update all serial numbers in the DB! for name, rdatasets in self.dnszone.zone.nodes.items(): # log if the rdataset is empty for some reason if not rdatasets: print("Empty Rdataset!") continue name,payload = worker((name, rdatasets)) + if payload == None: + continue pp_set[name] = payload if payload: rrcount += len(payload.data) @@ -400,7 +413,7 @@ class Ascension(): # Create missing zones (and add to dict) for GNS zones that are NOT DNS # zones ("." in a label is not a zone-cut in DNS, but always in GNS). - # Only add the records that there are no NS records for + # Only add the records for which there are no NS records for remaining_nsrecords = set(filter(lambda name: not name.is_absolute(), nameserverlist)) remaining = set(filter(lambda name: name not in remaining_nsrecords, @@ -443,6 +456,10 @@ class Ascension(): self.ns_process.stdin.close() self.ns_process.wait() +def purge_subzones(self): + for zname, zvalue in self.subzonedict: + self.gnszone.delete_zone(zname) + def main(): """ Initializes the Ascension class, handles arguments and daemon @@ -535,6 +552,10 @@ def main(): time.sleep(retry) continue + # FIXME: IXFR would require a "merge" + # FIXME: AXFR would require a GNS zone "purge" + # For now, even if we IXFR update the zone, perform a full update + ascender.gnszone.purge_records() ascender.add_records_to_gns() first_run = False diff --git a/ascension/util/classes.py b/ascension/util/classes.py @@ -27,6 +27,7 @@ import json import re import subprocess +import dns.exception import dns.rdatatype import dns.resolver import dns.query @@ -94,6 +95,27 @@ class GNSZone(): elif res.returncode != 0: self.logger.error("Failed to create identity %s", self.domain) + def delete_zone(self, zone): + """ + Deletes the zone in gnunet + """ + self.purge_records(zone) + self.logger.warning("Deleting zone %s", zone) + res = subprocess.run(["gnunet-identity", "-D", zone]) + if res.returncode != 0: + self.logger.error("Failed to delete zone %s", self.domain) + + def purge_records(self, zone=None): + """ + Purges the zone in gnunet + """ + if zone == None: + zone = self.domain + self.logger.warning("Purging records of zone %s", zone) + res = subprocess.run(["gnunet-namestore", "-X", "-z", zone]) + if res.returncode != 0: + self.logger.error("Failed to purge zone %s", self.domain) + def get_gns_zone_serial(self) -> int: """ Fetches the zones latest (highest) serial from GNS @@ -127,7 +149,7 @@ class GNSZone(): :param zonename: The label name of the zone :returns: str of pubkey of created or existing GNUnet zone """ - self.logger.info('Creating zone ' + zonename) + self.logger.info('Creating zone ' + zonename) # This is needed including the argument for subzones res = subprocess.run(["gnunet-identity", "-X", "-C", zonename]) if res.returncode == 201: @@ -274,7 +296,9 @@ class DNSZone: """ Transfers the DNS Zone via AXFR or IXFR should gns_zone_serial be available """ - self.zone = dns.zone.Zone(self.domain) + if gns_zone_serial == 0: + self.zone = dns.zone.Zone(self.domain) + assert self.zone != None self.logger.info("Preparing zonegenerator for transferring %s", self.domain) zonegenerator, _ = dns.xfr.make_query( self.zone,