mirror of
				https://github.com/mail-in-a-box/mailinabox.git
				synced 2025-11-03 19:30:54 +00:00 
			
		
		
		
	some cleanup in dns_update.py
This commit is contained in:
		
							parent
							
								
									808522d895
								
							
						
					
					
						commit
						7a93d219ef
					
				@ -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]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user