1
0
Fork 0

Use sendmail instead of SMTP

- remove the SMTP requirement to be able to work with /usr/lib/sendmail
  instead
- use f-strings where appropriate to improve readability
- use text-parameter to subprocess.run to avoid extra decode calls
add-secure1-alias-for-www1
Jan Dittberner 2 years ago committed by Gitea
parent d93300732b
commit 424bd7954f

@ -8,7 +8,6 @@ import tempfile
from subprocess import CalledProcessError, run from subprocess import CalledProcessError, run
from sys import stderr from sys import stderr
from email.message import EmailMessage, MIMEPart from email.message import EmailMessage, MIMEPart
from smtplib import SMTP
REFERENCE_BRANCH = "provisioned" REFERENCE_BRANCH = "provisioned"
DEFAULT_BRANCH = "origin/main" DEFAULT_BRANCH = "origin/main"
@ -28,12 +27,13 @@ def git_changed_files(reference_branch, target_branch):
"git", "git",
"diff", "diff",
"--name-only", "--name-only",
"{}..{}".format(reference_branch, target_branch), f"{reference_branch}..{target_branch}",
], ],
check=True, check=True,
capture_output=True, capture_output=True,
text=True,
) )
output = git_diff.stdout.decode("utf-8") output = git_diff.stdout.strip()
except CalledProcessError as e: except CalledProcessError as e:
print("git diff returned", e.returncode, file=stderr) print("git diff returned", e.returncode, file=stderr)
return [] return []
@ -46,13 +46,15 @@ def git_changed_files(reference_branch, target_branch):
def pdns_managed_zones(): def pdns_managed_zones():
try: try:
all_zones = run(["pdnsutil", "list-all-zones"], check=True, capture_output=True) all_zones = run(
zones = all_zones.stdout.decode("utf-8").strip().splitlines() ["pdnsutil", "list-all-zones"], check=True, capture_output=True, text=True
)
zones = all_zones.stdout.strip().splitlines()
except CalledProcessError as e: except CalledProcessError as e:
print( print(
"could not get list of zones from pdnsutil", "could not get list of zones from pdnsutil",
e.returncode, e.returncode,
e.stderr.decode("utf-8"), e.stderr,
file=stderr, file=stderr,
) )
return [] return []
@ -75,11 +77,12 @@ def calculate_changed_zones(files, zones):
def generate_diff(zone, reference_branch, target_branch): def generate_diff(zone, reference_branch, target_branch):
diffresult = run( diffresult = run(
["git", "diff", "{}..{}".format(reference_branch, target_branch), "--", zone], ["git", "diff", f"{reference_branch}..{target_branch}", "--", zone],
check=True, check=True,
capture_output=True, capture_output=True,
text=True,
) )
return diffresult.stdout.decode("utf-8").strip() return diffresult.stdout.strip()
def get_zone_data(zone, branch): def get_zone_data(zone, branch):
@ -87,19 +90,21 @@ def get_zone_data(zone, branch):
Get the zone data for the zone from target branch excluding SOA record. Get the zone data for the zone from target branch excluding SOA record.
""" """
result = run( result = run(
["git", "show", "{}:{}".format(branch, zone)], check=True, capture_output=True ["git", "show", f"{branch}:{zone}"], check=True, capture_output=True, text=True
) )
lines = result.stdout.decode("utf-8").strip().splitlines() lines = result.stdout.strip().splitlines()
soa = "\n".join([l for l in lines if "SOA" in l]) soa = "\n".join([l for l in lines if "SOA" in l])
non_soa = "\n".join([l for l in lines if not "SOA" in l]) non_soa = "\n".join([l for l in lines if not "SOA" in l])
return non_soa return non_soa
def list_zone(zone): def list_zone(zone):
result = run(["pdnsutil", "list-zone", zone], check=True, capture_output=True) result = run(
["pdnsutil", "list-zone", zone], check=True, capture_output=True, text=True
)
lines = result.stdout.decode("utf-8").strip().splitlines() lines = result.stdout.strip().splitlines()
soa = "\n".join([l for l in lines if "SOA" in l]) soa = "\n".join([l for l in lines if "SOA" in l])
non_soa = "\n".join([l for l in lines if not "SOA" in l]) non_soa = "\n".join([l for l in lines if not "SOA" in l])
return soa, non_soa return soa, non_soa
@ -116,46 +121,73 @@ def load_zone(zone, zonedata):
["pdnsutil", "load-zone", zone, zonefile.name], ["pdnsutil", "load-zone", zone, zonefile.name],
check=True, check=True,
capture_output=True, capture_output=True,
text=True,
) )
print(p.stdout.decode("utf-8").strip()) print(p.stdout.strip())
finally: finally:
os.unlink(zonefile.name) os.unlink(zonefile.name)
def check_zone(zone): def check_zone(zone):
p = run(["pdnsutil", "check-zone", zone], check=True, capture_output=True) p = run(
print(p.stdout.decode("utf-8").strip()) ["pdnsutil", "check-zone", zone], check=True, capture_output=True, text=True
)
print(p.stdout.strip())
def increase_serial(zone): def increase_serial(zone):
p = run(["pdnsutil", "increase-serial", zone], check=True, capture_output=True) p = run(
print(p.stdout.decode("utf-8").strip()) ["pdnsutil", "increase-serial", zone],
check=True,
capture_output=True,
text=True,
)
print(p.stdout.strip())
def rectify_zone(zone): def rectify_zone(zone):
p = run(["pdnsutil", "rectify-zone", zone], check=True, capture_output=True) p = run(
print(p.stdout.decode("utf-8").strip()) ["pdnsutil", "rectify-zone", zone], check=True, capture_output=True, text=True
)
print(p.stdout.strip())
def send_audit_mail(diffs, audit_email_address, audit_sender_address): def send_audit_mail(diffs, audit_email_address, audit_sender_address, changelog):
message = EmailMessage() message = EmailMessage()
message["Subject"] = "DNS changes applied" message["Subject"] = "DNS changes applied"
message["To"] = audit_email_address message["To"] = audit_email_address
message["From"] = audit_sender_address message["From"] = audit_sender_address
body = """The following zones have been changed: body = """A DNS change has been applied from git.
The following zones have been changed:
""" """
for zone, _ in diffs: for zone, _ in diffs:
body += "\n- {}".format(zone) body += f"\n - {zone}"
body += f"""
This is the change log for the applied commits:
{changelog}
"""
message.set_content(body) message.set_content(body)
for zone, diff in diffs: for zone, diff in diffs:
message.add_attachment(diff, filename="{}.diff".format(zone)) message.add_attachment(diff, filename=f"{zone}.diff")
server = SMTP("localhost") run(["/usr/lib/sendmail", "-t", "-oi"], input=message.as_bytes(), check=True)
server.send_message(message)
server.quit()
def get_changelog(reference_branch, target_branch):
r = run(
["git", "log", f"{reference_branch}..{target_branch}"],
check=True,
capture_output=True,
text=True,
)
return r.stdout.strip()
def main(reference_branch, target_branch, audit_email_address, audit_sender_address): def main(reference_branch, target_branch, audit_email_address, audit_sender_address):
@ -195,7 +227,7 @@ def main(reference_branch, target_branch, audit_email_address, audit_sender_addr
soa, old_zonedata = list_zone(zone) soa, old_zonedata = list_zone(zone)
zonedata = get_zone_data(zone=zone, branch=target_branch) zonedata = get_zone_data(zone=zone, branch=target_branch)
zonedata += "\n{}".format(soa) zonedata += f"\n{soa}"
try: try:
load_zone(zone, zonedata) load_zone(zone, zonedata)
@ -205,17 +237,19 @@ def main(reference_branch, target_branch, audit_email_address, audit_sender_addr
except CalledProcessError as pe: except CalledProcessError as pe:
print( print(
"process {} failed with return code {}:\n{}".format( "process {} failed with return code {}:\n{}".format(
" ".join(pe.cmd), pe.returncode, pe.stderr.decode("utf-8") " ".join(pe.cmd), pe.returncode, pe.stderr
), ),
file=stderr, file=stderr,
) )
print("reverting zone {}".format(zone), file=stderr) print(f"reverting zone {zone}", file=stderr)
load_zone(zone, "{}\n{}".format(old_zonedata, soa)) load_zone(zone, f"{old_zonedata}\n{soa}")
changelog = get_changelog(reference_branch, target_branch)
run(["git", "branch", "-d", reference_branch], check=True) run(["git", "branch", "-d", reference_branch], check=True)
run(["git", "branch", reference_branch, target_branch], check=True) run(["git", "branch", reference_branch, target_branch], check=True)
send_audit_mail(diffs, audit_email_address, audit_sender_address) send_audit_mail(diffs, audit_email_address, audit_sender_address, changelog)
if __name__ == "__main__": if __name__ == "__main__":

Loading…
Cancel
Save