diff --git a/roles/ansible-server/files/dns_check.py b/roles/ansible-server/files/dns_check.py new file mode 100644 index 0000000000..786a25c8df --- /dev/null +++ b/roles/ansible-server/files/dns_check.py @@ -0,0 +1,104 @@ +#! /usr/bin/env python +import os +import re +import collections + +# constants +PING_HOST_RESPONSE = 0 +PING_COMMAND = "ping -c 1 -W 1 {0} > /dev/null 2>&1" +ZONE_REGEX = "(\S+)\s+IN\s+([A-Z]+)\s+(\S+)" +DNS_REGEX = "([a-z0-9._-]+)$" + +ZONE_FILENAMES = [ + "master/125.5.10.in-addr.arpa", + "master/126.5.10.in-addr.arpa", + "master/127.5.10.in-addr.arpa", + "master/phx2.fedoraproject.org" +] + +AddressRecord = collections.namedtuple('AddressRecord', 'host, type, value') + +def get_host_dict(fp, prefix): + hosts = dict() + + # get the hostnames from the file + pattern = re.compile(ZONE_REGEX) + for line in fp: + m = pattern.match(line) + if m: + full_host = prefix.format(m.group(1)) + if full_host[0] <> ';': + hosts[full_host] = AddressRecord._make( [full_host, m.group(2), m.group(3)] ) + return hosts + +def check_zones_match(fwd_hosts, rev_hosts): + results = {} + results["correct"] = [] + results["mismatch"] = [] + results["missing"] = [] + + for record in fwd_hosts.values(): + if record.type is 'A': + try: + rev_record = rev_hosts[record.value] + if record.host == rev_record.value: + results["correct"].append( (record, rev_record) ) + else: + results["mismatch"].append( (record, rev_record) ) + except KeyError: + results["missing"].append( (record, None) ) + return results + +# ping each host and record the result +def ping(hosts): + results = {} + for record in hosts.values(): + results[record] = os.system(PING_COMMAND.format(record.host) ) + return results + +def build_dns_suffix(filename, reverse=False): + m = re.search(DNS_REGEX, filename) + if m: + suffix = m.group(1) + if reverse: + parts = suffix.split(".") + return parts[2]+"."+parts[1]+"."+parts[0]+".{0}" + else: + return "{0}."+m.group(1)+"." + +def main(filenames, check_dns=True, ping_hosts=True, print_stats=False): + rev_hosts = {} + fwd_hosts = {} + + for filename in filenames: + is_reverse = filename.endswith(".in-addr.arpa") + suffix = build_dns_suffix(filename, is_reverse) + host_dict = get_host_dict(open(filename, "r"), suffix) + + type_dict = rev_hosts if is_reverse else fwd_hosts + type_dict.update(host_dict) + + if check_dns: + check_results = check_zones_match(fwd_hosts, rev_hosts) + + if print_stats: + print("reverse dns records") + print("records correct: {0}".format(len(check_results["correct"]))) + print("records incorrect: {0}".format(len(check_results["mismatch"]))) + print("records missing: {0}".format(len(check_results["missing"]))) + + for (fwd, rev) in check_results["mismatch"]: + print ("mismatched record: {0} -> {1} -> {2}".format(fwd.host, fwd.value, rev.value)) + + for (fwd, rev) in check_results["missing"]: + print ("missing record: {0} -> {1}").format(fwd.host, fwd.value) + + if ping_hosts: + results = ping(fwd_hosts) + + # print all the non-zero (error) results + for (host, result) in results.items(): + if result is not 0: + print ("ping failed: {0} (err {1})").format(host.host[:-1], result) + +main(ZONE_FILENAMES) diff --git a/roles/ansible-server/tasks/main.yml b/roles/ansible-server/tasks/main.yml index b9c778bed3..16136a938e 100644 --- a/roles/ansible-server/tasks/main.yml +++ b/roles/ansible-server/tasks/main.yml @@ -9,10 +9,17 @@ - git tags: - packages + - ansible-server - name: generate default ansible config template: src=ansible.cfg.j2 dest=/etc/ansible/ansible.cfg owner=root group=root mode=0644 + tags: + - ansible-server +- name: installing the phx2 dns check script + copy: src="{{ files }}/dns_check.py" dest=/usr/local/bin/dns_check owner=root mode=755 + tags: + - ansible-server # # TODO: # cgit?