diff options
author | Aaron LI <aly@aaronly.me> | 2018-02-28 13:05:52 +0800 |
---|---|---|
committer | Aaron LI <aly@aaronly.me> | 2018-03-14 11:28:44 +0800 |
commit | 67fa5be1b042fd6ace7e140939f58ea3680efd8c (patch) | |
tree | 8a69b4375086efbca40ced86d3f9bbe5fec867e5 | |
parent | 2d8ca670d9148c7de2a95c8448985f74238d7cdb (diff) | |
download | ansible-dfly-vps-67fa5be1b042fd6ace7e140939f58ea3680efd8c.tar.bz2 |
Add filter_plugins/dns.py with "next_serial" to DNS SOA record
Credit: https://github.com/kgaughan/zones
-rw-r--r-- | filter_plugins/dns.py | 74 |
1 files changed, 74 insertions, 0 deletions
diff --git a/filter_plugins/dns.py b/filter_plugins/dns.py new file mode 100644 index 0000000..9fdca29 --- /dev/null +++ b/filter_plugins/dns.py @@ -0,0 +1,74 @@ +# Credit: https://github.com/kgaughan/zones + +""" +Custom Ansible template filters for DNS management. +""" + +import os +import datetime +import random +import shlex +import subprocess + + +def which(cmd): + for path in os.environ["PATH"].split(os.pathsep): + full_path = os.path.join(path, cmd) + if os.access(full_path, os.X_OK): + return full_path + return None + + +def run_query(cmd, rtype, fqdn, ns=None): + if not fqdn.endswith("."): + fqdn += "." + args = [cmd, fqdn, rtype] + if ns: + args.append("@" + ns) + + output = subprocess.check_output(args, universal_newlines=True) + for line in output.split("\n"): + if line.startswith(";"): + continue + parsed = shlex.split(line) + if len(parsed) > 0 and parsed[0] == fqdn and parsed[3] == rtype: + yield parsed[4:] + + +def next_serial(fqdn): + cmd = "drill" + cmd_path = which(cmd) + if cmd_path is None: + raise Exception("Cannot find %s" % cmd) + + def query_nameservers(fqdn, ns=None): + return [line[0] for line in run_query(cmd_path, "NS", fqdn, ns)] + + # Get a registry nameserver. + reg_ns = random.choice(query_nameservers(".".join(fqdn.split(".")[1:]))) + + nss = query_nameservers(fqdn, reg_ns) + random.shuffle(nss) + + current_serial = None + for ns in nss: + try: + for line in run_query(cmd_path, "SOA", fqdn, ns): + current_serial = line[2] + break + except subprocess.CalledProcessError as e: + if e.returncode not in [9]: + raise + if current_serial is not None: + break + + today = datetime.datetime.utcnow().strftime("%Y%m%d") + if current_serial is None or current_serial[:8] != today: + return today + "00" + else: + return str(int(current_serial) + 1) + + +class FilterModule(object): + def filters(self): + return {"next_serial": next_serial} |