From 7a93d219ef598d018676237c0eed7663123c4c07 Mon Sep 17 00:00:00 2001 From: Joshua Tauberer Date: Sun, 29 Nov 2015 14:59:35 +0000 Subject: [PATCH] some cleanup in dns_update.py --- management/dns_update.py | 102 +++++++++------------------------------ 1 file changed, 24 insertions(+), 78 deletions(-) diff --git a/management/dns_update.py b/management/dns_update.py index 1e0cba9f..1ec88607 100755 --- a/management/dns_update.py +++ b/management/dns_update.py @@ -51,21 +51,13 @@ def get_dns_zones(env): return zonefiles def do_dns_update(env, force=False): - # What domains (and their zone filenames) should we build? - domains = get_dns_domains(env) - zonefiles = get_dns_zones(env) - - # Custom records to add to zones. - additional_records = list(get_custom_dns_config(env)) - from web_update import get_web_domains - www_redirect_domains = set(get_web_domains(env)) - set(get_web_domains(env, include_www_redirects=False)) - # Write zone files. os.makedirs('/etc/nsd/zones', exist_ok=True) + zonefiles = [] updated_domains = [] - for i, (domain, zonefile) in enumerate(zonefiles): - # Build the records to put in the zone. - records = build_zone(domain, domains, additional_records, www_redirect_domains, env) + for (domain, zonefile, records) in build_zones(env): + # The final set of files will be signed. + zonefiles.append((domain, zonefile + ".signed")) # See if the zone has changed, and if so update the serial number # and write the zone file. @@ -73,14 +65,6 @@ def do_dns_update(env, force=False): # Zone was not updated. There were no changes. continue - # If this is a .justtesting.email domain, then post the update. - try: - justtestingdotemail(domain, records) - except: - # Hmm. Might be a network issue. If we stop now, will we end - # up in an inconsistent state? Let's just continue. - pass - # Mark that we just updated this domain. updated_domains.append(domain) @@ -95,14 +79,8 @@ def do_dns_update(env, force=False): # and return True so we get a chance to re-sign it. sign_zone(domain, zonefile, env) - # Now that all zones are signed (some might not have changed and so didn't - # just get signed now, but were before) update the zone filename so nsd.conf - # uses the signed file. - for i in range(len(zonefiles)): - zonefiles[i][1] += ".signed" - # Write the main nsd.conf file. - if write_nsd_conf(zonefiles, additional_records, env): + if write_nsd_conf(zonefiles, list(get_custom_dns_config(env)), env): # Make sure updated_domains contains *something* if we wrote an updated # nsd.conf so that we know to restart nsd. if len(updated_domains) == 0: @@ -112,8 +90,8 @@ def do_dns_update(env, force=False): if len(updated_domains) > 0: shell('check_call', ["/usr/sbin/service", "nsd", "restart"]) - # Write the OpenDKIM configuration tables. - if write_opendkim_tables(domains, env): + # Write the OpenDKIM configuration tables for all of the domains. + if write_opendkim_tables([domain for domain, zonefile in zonefiles], env): # Settings changed. Kick opendkim. shell('check_call', ["/usr/sbin/service", "opendkim", "restart"]) if len(updated_domains) == 0: @@ -132,6 +110,22 @@ def do_dns_update(env, force=False): ######################################################################## +def build_zones(env): + # What domains (and their zone filenames) should we build? + domains = get_dns_domains(env) + zonefiles = get_dns_zones(env) + + # Custom records to add to zones. + additional_records = list(get_custom_dns_config(env)) + from web_update import get_web_domains + www_redirect_domains = set(get_web_domains(env)) - set(get_web_domains(env, include_www_redirects=False)) + + # Build DNS records for each zone. + for domain, zonefile in zonefiles: + # Build the records to put in the zone. + records = build_zone(domain, domains, additional_records, www_redirect_domains, env) + yield (domain, zonefile, records) + def build_zone(domain, all_domains, additional_records, www_redirect_domains, env, is_zone=True): records = [] @@ -861,57 +855,9 @@ def get_custom_dns_record(custom_dns, qname, rtype): ######################################################################## -def justtestingdotemail(domain, records): - # If the domain is a subdomain of justtesting.email, which we own, - # automatically populate the zone where it is set up on dns4e.com. - # Ideally if dns4e.com supported NS records we would just have it - # delegate DNS to us, but instead we will populate the whole zone. - - import subprocess, json, urllib.parse - - if not domain.endswith(".justtesting.email"): - return - - for subdomain, querytype, value, explanation in records: - if querytype in ("NS",): continue - if subdomain in ("www", "ns1", "ns2"): continue # don't do unnecessary things - - if subdomain == None: - subdomain = domain - else: - subdomain = subdomain + "." + domain - - if querytype == "TXT": - # nsd requires parentheses around txt records with multiple parts, - # but DNS4E requires there be no parentheses; also it goes into - # nsd with a newline and a tab, which we replace with a space here - value = re.sub("^\s*\(\s*([\w\W]*)\)", r"\1", value) - value = re.sub("\s+", " ", value) - else: - continue - - print("Updating DNS for %s/%s..." % (subdomain, querytype)) - resp = json.loads(subprocess.check_output([ - "curl", - "-s", - "https://api.dns4e.com/v7/%s/%s" % (urllib.parse.quote(subdomain), querytype.lower()), - "--user", "2ddbd8e88ed1495fa0ec:A97TDJV26CVUJS6hqAs0CKnhj4HvjTM7MwAAg8xb", - "--data", "record=%s" % urllib.parse.quote(value), - ]).decode("utf8")) - print("\t...", resp.get("message", "?")) - -######################################################################## - def build_recommended_dns(env): ret = [] - domains = get_dns_domains(env) - zonefiles = get_dns_zones(env) - additional_records = list(get_custom_dns_config(env)) - from web_update import get_web_domains - www_redirect_domains = set(get_web_domains(env)) - set(get_web_domains(env, include_www_redirects=False)) - for domain, zonefile in zonefiles: - records = build_zone(domain, domains, additional_records, www_redirect_domains, env) - + for (domain, zonefile, records) in build_zones(env): # remove records that we don't dislay records = [r for r in records if r[3] is not False]