1
0
mirror of https://github.com/mail-in-a-box/mailinabox.git synced 2024-11-26 02:57:04 +00:00

some cleanup in dns_update.py

This commit is contained in:
Joshua Tauberer 2015-11-29 14:59:35 +00:00
parent 808522d895
commit 7a93d219ef

View File

@ -51,21 +51,13 @@ def get_dns_zones(env):
return zonefiles return zonefiles
def do_dns_update(env, force=False): 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. # Write zone files.
os.makedirs('/etc/nsd/zones', exist_ok=True) os.makedirs('/etc/nsd/zones', exist_ok=True)
zonefiles = []
updated_domains = [] updated_domains = []
for i, (domain, zonefile) in enumerate(zonefiles): for (domain, zonefile, records) in build_zones(env):
# Build the records to put in the zone. # The final set of files will be signed.
records = build_zone(domain, domains, additional_records, www_redirect_domains, env) zonefiles.append((domain, zonefile + ".signed"))
# See if the zone has changed, and if so update the serial number # See if the zone has changed, and if so update the serial number
# and write the zone file. # and write the zone file.
@ -73,14 +65,6 @@ def do_dns_update(env, force=False):
# Zone was not updated. There were no changes. # Zone was not updated. There were no changes.
continue 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. # Mark that we just updated this domain.
updated_domains.append(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. # and return True so we get a chance to re-sign it.
sign_zone(domain, zonefile, env) 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. # 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 # Make sure updated_domains contains *something* if we wrote an updated
# nsd.conf so that we know to restart nsd. # nsd.conf so that we know to restart nsd.
if len(updated_domains) == 0: if len(updated_domains) == 0:
@ -112,8 +90,8 @@ def do_dns_update(env, force=False):
if len(updated_domains) > 0: if len(updated_domains) > 0:
shell('check_call', ["/usr/sbin/service", "nsd", "restart"]) shell('check_call', ["/usr/sbin/service", "nsd", "restart"])
# Write the OpenDKIM configuration tables. # Write the OpenDKIM configuration tables for all of the domains.
if write_opendkim_tables(domains, env): if write_opendkim_tables([domain for domain, zonefile in zonefiles], env):
# Settings changed. Kick opendkim. # Settings changed. Kick opendkim.
shell('check_call', ["/usr/sbin/service", "opendkim", "restart"]) shell('check_call', ["/usr/sbin/service", "opendkim", "restart"])
if len(updated_domains) == 0: 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): def build_zone(domain, all_domains, additional_records, www_redirect_domains, env, is_zone=True):
records = [] 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): def build_recommended_dns(env):
ret = [] ret = []
domains = get_dns_domains(env) for (domain, zonefile, records) in build_zones(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)
# remove records that we don't dislay # remove records that we don't dislay
records = [r for r in records if r[3] is not False] records = [r for r in records if r[3] is not False]