commit 65d94cf4300305b946f8ab5b78d8a082c6deb3a4
parent e6cdf76f0f93a9aca8bedc5216e098ca844ff583
Author: rexxnor <rexxnor+gnunet@brief.li>
Date: Wed, 24 Oct 2018 21:28:30 +0200
unstable version, port specification possible
Diffstat:
1 file changed, 57 insertions(+), 49 deletions(-)
diff --git a/gnsmigrator/gnsmigrator.py b/gnsmigrator/gnsmigrator.py
@@ -3,11 +3,15 @@
Usage:
gnsmigrator.py -t <tld> -ns <transferns>
+ gnsmigrator.py -t <tld> -ns <transferns> -p <port>
gnsmigrator.py -f <txtfile>
+ gnsmigrator.py -f <txtfile> -p <port>
+ gnsmigrator.py -f <txtfile> -p <port> -ns <transferns>
gnsmigrator.py -h | --help
gnsmigrator.py -v | --version
Options:
+ <port> Port specification
<tld> Top level domain to migrate
<txtfile> Text File containing domains to transfer
<transferns> DNS Server that does the zone transfer
@@ -64,12 +68,13 @@ class BaseMigrator():
Base class for migration
"""
@classmethod
- def __init__(cls, domainlist):
+ def __init__(cls, domainlist, port=53):
cls.domainlist = domainlist
+ cls.port = port
cls.zones = {}
@classmethod
- def initial_zone_transfer(cls):
+ def initial_zone_transfer(cls, resolver=None):
"""
Fetch all the zones via zone transfer
"""
@@ -83,20 +88,35 @@ class BaseMigrator():
master_answer = dns.resolver.query(soa_answer[0].mname, 'A')
try:
- zone = dns.zone.from_xfr(dns.query.xfr(
- master_answer[0].address, domain))
+ if resolver:
+ zone = dns.zone.from_xfr(dns.query.xfr(
+ resolver, domain, port=cls.port))
+ else:
+ zone = dns.zone.from_xfr(dns.query.xfr(
+ master_answer[0].address, domain,
+ port=cls.port))
except dns.resolver.NoAnswer:
print("nameserver for '%s' did not answer" % domain)
continue
except dns.exception.FormError:
print("domain '%s' does not allow xfr requests" % domain)
continue
- cls.zones[domain] = (zone,
- (master_answer[0].address,
- domain,
- zone.get_rdataset('@', dns.rdatatype.SOA).ttl,
- 0)
- )
+ if resolver:
+ cls.zones[domain] = (zone,
+ (resolver,
+ domain,
+ zone.get_rdataset('@',
+ dns.rdatatype.SOA).ttl,
+ 0)
+ )
+ else:
+ cls.zones[domain] = (zone,
+ (master_answer[0].address,
+ domain,
+ zone.get_rdataset('@',
+ dns.rdatatype.SOA).ttl,
+ 0)
+ )
@classmethod
def refresh_zone(cls, domain, zonetuple):
@@ -120,20 +140,16 @@ class BaseMigrator():
.split(' ')[5])
xfrinfo[3] = 1
- # A normal BIND9 returns a normal AXFR response with the entire zone
- # if the serial is newer. This is why there is no real incremental
- # zone transfer using bind. This makes the merger_zones function
- # unnecessary. Furthermore this try except block updates only if
- # there is a newer zone availible (according to serial). The IXFR
- # returns only a SOA record with a new serial if it has not changed
try:
newzone = dns.zone.from_xfr(dns.query.xfr(xfrinfo[0],
xfrinfo[1],
rdtype=dns.rdatatype.IXFR,
serial=oldserial))
- cls.zones[domain] = (newzone, (xfrinfo[0],
- xfrinfo[1],
- zone.get_rdataset('@', dns.rdatatype.SOA).ttl))
+ cls.zones[domain] = (newzone,
+ (xfrinfo[0],
+ xfrinfo[1],
+ zone.get_rdataset('@',
+ dns.rdatatype.SOA).ttl))
except dns.zone.NoNS:
print('the zone for domain %s was not updated' % domain)
@@ -213,6 +229,7 @@ class BaseMigrator():
BaseMigrator.add_ns_record_to_gns(record, zonename, domain)
elif rtype_str == 'MX':
BaseMigrator.add_mx_record_to_gns(record, zonename)
+ # TODO Add support for SRV records
#elif rtype_str == 'SRV':
# BaseMigrator.add_srv_record_to_gns(record, zonename)
elif rtype_str in ['A', 'AAAA']:
@@ -390,12 +407,13 @@ class BaseMigrator():
"""
return domain.split('.')[0]
- @staticmethod
- def get_current_serial(domain, resolver=None):
+ @classmethod
+ def get_current_serial(cls, domain, resolver=None):
"""
Gets the current serial for a given zone
"""
- # this seems to be different from the data via AXFR
+ # SOA is different if taken directly from SOA record
+ # compared to AXFR/IXFR - changed to respect this
try:
soa_answer = dns.resolver.query(domain, 'SOA')
except dns.resolver.NoAnswer:
@@ -404,10 +422,11 @@ class BaseMigrator():
try:
if resolver:
zone = dns.zone.from_xfr(dns.query.xfr(
- resolver, domain))
+ resolver, domain, port=cls.port))
else:
zone = dns.zone.from_xfr(dns.query.xfr(
- master_answer[0].address, domain))
+ master_answer[0].address, domain,
+ port=cls.port))
except dns.resolver.NoAnswer:
print("nameserver for '%s' did not answer" % domain)
except dns.exception.FormError:
@@ -443,16 +462,16 @@ class ZoneMigrator(BaseMigrator):
Class that migrates small zones efficiently
"""
@classmethod
- def __init__(cls, domainlist):
- BaseMigrator.__init__(domainlist)
+ def __init__(cls, domainlist, port=53):
+ BaseMigrator.__init__(domainlist, port)
class TLDMigrator(BaseMigrator):
"""
Class that migrates big zones (TLDs) efficiently
"""
@classmethod
- def __init__(cls, tld, transferns):
- BaseMigrator.__init__(tld)
+ def __init__(cls, tld, transferns, port=53):
+ BaseMigrator.__init__(tld, port)
cls.soa = None
cls.tld = tld
cls.transferns = transferns
@@ -468,7 +487,8 @@ class TLDMigrator(BaseMigrator):
cls.zonegenerator = dns.query.xfr(cls.transferns,
cls.tld,
rdtype=dns.rdatatype.IXFR,
- serial=serial)
+ serial=serial,
+ port=cls.port)
else:
cls.zonegenerator = dns.query.xfr(cls.transferns, cls.tld,)
@@ -518,28 +538,14 @@ class TLDMigrator(BaseMigrator):
elif zoneserial == currentserial:
print("Nothing to do!")
sys.exit(0)
- # this case should be unnecessary but AXFR SOA is not equal to direct SOA
+ # should be unnecessary but AXFR SOA is not equal to direct SOA
else:
print("SOA serial is bigger than zone serial?")
print(zoneserial, currentserial)
sys.exit(0)
- #@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)
-
@classmethod
- def transfer_zone(cls, zone_factory=dns.zone.Zone,
- relativize=True):
+ def transfer_zone(cls, zone_factory=dns.zone.Zone, relativize=True):
"""
Do the actual zone transfer
"""
@@ -595,7 +601,7 @@ class TLDMigrator(BaseMigrator):
authns = "%s.%s" % (authns, zonename)
# building gns record struct
- #GNUnetGNSRecordData()
+ # GNUnetGNSRecordData()
cls.add_record_to_gns(record, zonename, cls.tld)
taskqueue.task_done()
@@ -623,6 +629,7 @@ class TLDMigrator(BaseMigrator):
# Add soa record to GNS once completed
soa = cls.get_zone_soa(cls.zone)
super().add_soa_record_to_gns(soa, cls.tld[:-1], cls.tld)
+ print("All records have been added!")
@staticmethod
def add_record_to_gns(record, zonename, domain):
@@ -670,9 +677,10 @@ def main():
tld = args.get('<tld>', None)
transferns = args.get('<transferns>', None)
txtfile = args.get('<txtfile>', None)
+ port = int(args.get('<port>', None))
if tld and transferns:
- migrator = TLDMigrator(tld, transferns)
+ migrator = TLDMigrator(tld, transferns, port)
serial = migrator.get_zone_serial(tld)
migrator.initial_zone_transfer(serial)
migrator.bootstrap_zone()
@@ -684,8 +692,8 @@ def main():
with open(txtfile, 'r') as openedtxt:
for line in openedtxt:
domainlist.append(line.rstrip())
- zonemigrator = ZoneMigrator(domainlist)
- zonemigrator.initial_zone_transfer()
+ zonemigrator = ZoneMigrator(domainlist, port=port)
+ zonemigrator.initial_zone_transfer(resolver=transferns)
zonemigrator.bootstrap_zones()
for domain, zonetuple in zonemigrator.zones.items():
zonemigrator.refresh_zone(domain, zonetuple)