ansible/roles/ansible-server/files/dns_check.py

105 lines
2.9 KiB
Python

#! /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/0.16.10.in-addr.arpa",
"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)