ascension

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

commit b1d0acc7981cf5ce2baa8d29cca713caaeff6cd1
parent a057889a86c15c3bb8b3262b7a49caa204de041e
Author: rexxnor <rexxnor+gnunet@brief.li>
Date:   Thu, 13 Dec 2018 15:24:33 +0100

unify all records under label, added SUPPORTED_RECORDS global

Diffstat:
Mgnsmigrator/gnsmigrator.py | 265++++++++++++++++++++++++++-----------------------------------------------------
1 file changed, 87 insertions(+), 178 deletions(-)

diff --git a/gnsmigrator/gnsmigrator.py b/gnsmigrator/gnsmigrator.py @@ -35,6 +35,9 @@ GNUNET_ZONE_CREATION_COMMAND = 'gnunet-identity' GNUNET_NAMESTORE_COMMAND = 'gnunet-namestore' GNUNET_GNS_COMMAND = 'gnunet-gns' GNUNET_ARM_COMMAND = 'gnunet-arm' +SUPPORTED_RECORD_TYPES = [ + "A", "AAAA", "NS", "MX", "SOA", "SRV", "TXT", "CNAME" +] class GNSMigrator(): """ @@ -184,7 +187,7 @@ class GNSMigrator(): elif zoneserial == currentserial: logging.warning("Nothing to do!") sys.exit(0) - # should be unnecessary but AXFR SOA is not equal to direct SOA + # should be unnecessary but AXFR SOA might not equal to direct SOA else: logging.critical("SOA serial is bigger than zone serial?") print(zoneserial, currentserial) @@ -207,31 +210,44 @@ class GNSMigrator(): recordline = [] label = "" - rdataset = taskqueue.get() - if rdataset is None: + labelrecords = taskqueue.get() + # break if taskqueue is empty + if labelrecords is None: break + # execute thing to run on item - label, rdata = rdataset - for record in rdata: - rdtype = dns.rdatatype.to_text(record.rdtype) - ttl = rdata.ttl - value = str(record) - - # modify value to fit gns syntax - rdtype, value = cls.transform_to_gns_format(record, - rdtype, - zonename, - cls.domain, - label) - - # build recordline - recordline.append("-R") - recordline.append("%d %s %s %s" % - (int(ttl), rdtype, flags, value)) - - #cls.add_record_to_gns(record, zonename, cls.domain) + label, listofrdatasets = labelrecords + + for rdataset in listofrdatasets: + for test in rdataset: + rdtype = dns.rdatatype.to_text(test.rdtype) + if rdtype not in SUPPORTED_RECORD_TYPES: + continue + try: + ttl = rdataset.ttl + except AttributeError: + ttl = 3600 + + value = str(test) + + # modify value to fit gns syntax + rdtype, value = cls.transform_to_gns_format(test, + rdtype, + zonename, + cls.domain, + label) + # skip record if value is none + if value is None: + continue + + # build recordline + recordline.append("-R") + recordline.append("%d %s %s %s" % + (int(ttl), rdtype, flags, value)) + # add recordline to gns - cls.add_recordline_to_gns(recordline, zonename, label) + if len(recordline) > 1: + cls.add_recordline_to_gns(recordline, zonename, label) taskqueue.task_done() @@ -248,8 +264,21 @@ class GNSMigrator(): #for nsrecord in cls.zone.iterate_rdatasets(rdtype=dns.rdatatype.NS): # taskqueue.put(nsrecord) # Add remaining records to zone + customrdataset = dict() for remaining in cls.zone.iterate_rdatasets(): - taskqueue.put(remaining) + rdataset = remaining[1] + if customrdataset.get(str(remaining[0])) is None: + work = list() + work.append(rdataset) + customrdataset[str(remaining[0])] = work + else: + customrdataset[str(remaining[0])].append(rdataset) + + for label in customrdataset.keys(): + value = customrdataset.get(label) + if value is None: + continue + taskqueue.put((label, value)) # Block until all tasks are done taskqueue.join() @@ -259,9 +288,9 @@ class GNSMigrator(): thread.join() # Add soa record to GNS once completed (updates the previous one) - soa = cls.get_zone_soa(cls.zone) - cls.add_soa_record_to_gns(soa, zonename, cls.domain) - logging.info("All records have been added!") + #soa = cls.get_zone_soa(cls.zone) + #cls.add_soa_record_to_gns(soa, zonename, cls.domain) + #logging.info("All records have been added!") @staticmethod def add_recordline_to_gns(recordline, zonename, label): @@ -271,12 +300,15 @@ class GNSMigrator(): :param zonename: zonename of zone to add records to :param label: label under which to add the records """ - logging.info("adding %d records with name %s", len(recordline)/2, label) + logging.info("trying to add %d records with name %s", len(recordline)/2, label) ret = sp.run([GNUNET_NAMESTORE_COMMAND, '-z', zonename, '-n', str(label), ] + recordline) - logging.info("executed command: %s", " ".join(ret.args)) + if ret.returncode != 0: + logging.warning("failed adding record with name %s", ' '.join(ret.args)) + else: + logging.info("successfully added record with name %s", ' '.join(ret.args)) @staticmethod def transform_to_gns_format(record, rdtype, zonename, domain, label): @@ -292,6 +324,7 @@ class GNSMigrator(): if rdtype == 'SOA': zonetuple = str(value).split(' ') domain = str(".".join(domain.split('.')[:-1])) + print(zonetuple) authns, owner, serial, refresh, retry, expiry, irefresh = zonetuple if authns[-1] == '.': authns = authns[:-1] @@ -305,7 +338,10 @@ class GNSMigrator(): elif rdtype in ['TXT', 'CNAME']: if value[-1] == ".": value = value[:-1] - elif rdtype == 'NS' and label != "@": + elif rdtype == 'NS': + if label == '@': + logging.info("ignoring NS record for itself") + return (rdtype, None) nameserver = str(record) if value[-1] == ".": value = value[:-1] @@ -316,52 +352,39 @@ class GNSMigrator(): else: dnsresolver = "%s.%s" % (nameserver, domain) value = '%s.%s@%s' % (str(label), zonename, dnsresolver) - rdtype = 'GNS2DNS' logging.info("transformed %s record to GNS2DNS format", rdtype) + rdtype = 'GNS2DNS' elif rdtype == 'MX': priority, mailserver = str(value).split(' ') if mailserver[-1] == ".": mailserver = mailserver[:-1] value = '%s,%s' % (priority, mailserver) logging.info("transformed %s record to GNS format", rdtype) - # TODO add SRV records - #elif rdtype == 'SRV': - # GNSMigrator.add_srv_record_to_gns(record, zonename) + elif rdtype == 'SRV': + # this is the number for a SRV record + rdtype = 'BOX' + srv = 33 + protocols = {'_tcp': 6, '_udp': 17} + + # tearing the record apart + _, proto = str(label).split('.') + priority, weight, destport, target = value.split(' ') + + protonum = protocols.get(proto) + if protonum is None: + logging.warning("invalid protocol: %s", proto) + return (rdtype, None) + + #pr w por target + #100 1 443 sipdir.online.lync.com. + value = '%s %s %s %s %s %s %s' % ( + destport, protonum, srv, priority, weight, destport, target + ) else: logging.info("Did not transform record of type: %s", rdtype) return (rdtype, value) @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) - logging.info("adding %s record with name %s", rtype_str, dnsname_str) - if dnsname_str == '@': - if rtype_str == 'SOA': - GNSMigrator.add_soa_record_to_gns(record, zonename, domain) - else: - if rtype_str == 'NS' and dnsname_str != '@': - GNSMigrator.add_ns_record_to_gns(record, zonename, domain) - elif rtype_str == 'MX': - GNSMigrator.add_mx_record_to_gns(record, zonename) - #elif rtype_str == 'SRV': - # GNSMigrator.add_srv_record_to_gns(record, zonename) - elif rtype_str in ['A', 'AAAA']: - GNSMigrator.add_a_aaaa_record_to_gns(record, zonename, domain) - elif rtype_str in ['TXT', 'CNAME']: - GNSMigrator.add_gen_record_to_gns(record, zonename) - else: - logging.warning("Unsupported record type: %s", rtype_str) - - - - @staticmethod def get_zone_serial(zonename): """ Extracts the current serial from a given zone @@ -396,25 +419,6 @@ class GNSMigrator(): return ret @staticmethod - def add_gen_record_to_gns(record, zonename): - """ - Adds a generic record to GNS - """ - if not GNSMigrator.check_if_record_exists_in_zone(record, zonename): - dnsname, ttl, rdata = record - rtype_str = str(dns.rdatatype.to_text(rdata.rdtype)) - ret = sp.run([GNUNET_NAMESTORE_COMMAND, - '-z', zonename, - '-a', '-n', str(dnsname), - '-t', rtype_str, - '-V', str(rdata), - '-e', '%ds' % ttl]) - logging.info("executed command: %s", " ".join(ret.args)) - if ret.returncode != 0: - logging.warning("failed to add %s record %s", - rtype_str, str(dnsname)) - - @staticmethod def add_srv_record_to_gns(record, zonename): # TODO Add support for SRV records """ @@ -443,35 +447,6 @@ class GNSMigrator(): rtype_str, dnsname_str) @staticmethod - def add_a_aaaa_record_to_gns(record, zonename, domain): - """ - Adds A and AAAA records to GNS - """ - if not GNSMigrator.check_if_record_exists_in_zone(record, zonename): - dnsname, ttl, rdata = record - rtype_str = str(dns.rdatatype.to_text(rdata.rdtype)) - ret = sp.run([GNUNET_NAMESTORE_COMMAND, - '-z', zonename, - '-a', '-n', str(dnsname), - '-t', rtype_str, - '-V', str(rdata), - '-e', '%ds' % ttl]) - logging.info("executed command: %s", " ".join(ret.args)) - if ret.returncode != 0: - logging.warning("failed to add %s record %s", - rtype_str, str(dnsname)) - ret = sp.run([GNUNET_NAMESTORE_COMMAND, - '-z', zonename, - '-a', '-n', str(dnsname), - '-t', 'LEHO', - '-V', '%s.%s' % (str(dnsname), domain), - '-e', '%ds' % ttl]) - logging.info("executed command: %s", " ".join(ret.args)) - if ret.returncode != 0: - logging.warning("failed to add %s record %s", - "LEHO", str(dnsname)) - - @staticmethod def add_soa_record_to_gns(record, zonename, domain): """ Adds a SOA record to GNS @@ -499,72 +474,6 @@ class GNSMigrator(): if ret.returncode != 0: logging.warning("failed to add %s record %s", "SOA", "@") - @staticmethod - def add_ns_record_to_gns(record, zonename, domain): - """ - Adds a GNS2DNS record to GNS - """ - if not GNSMigrator.check_if_record_exists_in_zone(record, zonename): - dnsname, ttl, rdata = record - nameserver = str(rdata) - - 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)], - stdin=pkey_lookup.stdout, - stdout=sp.PIPE) - pkey_zone = sp.check_output(['cut', '-d', ' ', '-f3'], - stdin=pkey_line - .stdout) - pkey_zone = pkey_zone.decode().strip() - if not pkey_zone: - ret = sp.run([GNUNET_GNS_COMMAND, - '-t', 'GNS2DNS', - '-u', '%s.%s' % (str(dnsname), zonename)], - stdout=sp.PIPE) - logging.info("executed command: %s", " ".join(ret.args)) - if 'Got'.encode() not in ret.stdout: - ret = sp.run([GNUNET_NAMESTORE_COMMAND, - '-z', zonename, - '-a', '-n', str(dnsname), - '-t', 'GNS2DNS', - '-V', '%s.%s@%s' % - (str(dnsname), domain, dnsresolver), - '-e', '%ds' % ttl]) - if ret.returncode != 0: - logging.warning("failed to add %s record %s", - "GNS2DNS", str(dnsname)) - - @staticmethod - def add_mx_record_to_gns(record, zonename): - """ - Adds an MX to GNS - """ - dnsname, ttl, rdata = record - if not GNSMigrator.check_if_record_exists_in_zone(record, zonename): - rdatalist = str(rdata).split(' ') - value = '%s,%s' % (rdatalist[0], rdatalist[1]) - ret = sp.run([GNUNET_NAMESTORE_COMMAND, - '-z', zonename, - '-a', '-n', str(dnsname), - '-t', dns.rdatatype.to_text(rdata.rdtype), - '-V', value, - '-e', '%ds' % int(ttl)]) - logging.info("executed command: %s", " ".join(ret.args)) - if ret.returncode != 0: - logging.warning("failed to add %s record %s", - "GNS2DNS", str(dnsname)) @staticmethod def check_if_record_exists_in_zone(record, zonename):