Add simple check script:
- check dns forward lookups - check reachability via icmpv4/icmpv6 echo request
This commit is contained in:
parent
224cc5606c
commit
5dbe872abf
131
scripts/check
Normal file
131
scripts/check
Normal file
|
@ -0,0 +1,131 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
import sys
|
||||
import os
|
||||
import socket
|
||||
import subprocess
|
||||
from optparse import OptionParser
|
||||
|
||||
|
||||
def error(*arg):
|
||||
print(*arg, file=sys.stderr)
|
||||
|
||||
|
||||
def check_host_lookup(hostname, port):
|
||||
try:
|
||||
return socket.getaddrinfo(hostname, port)
|
||||
except Exception as e:
|
||||
error("DNS Lookup for {hostname} failed".format(hostname=hostname))
|
||||
return []
|
||||
|
||||
|
||||
def check_reachability(host, family):
|
||||
if family is socket.AddressFamily.AF_INET:
|
||||
process_name = 'ping'
|
||||
else:
|
||||
process_name = 'ping6'
|
||||
child = subprocess.Popen([process_name, host, '-c', '1', '-W', '5'],
|
||||
stdout=subprocess.PIPE)
|
||||
child.communicate()
|
||||
if child.returncode:
|
||||
error("Host {host} is unreachable".format(host=host))
|
||||
return 0 if child.returncode == 0 else 1
|
||||
|
||||
|
||||
def get_hosts_data(srcdir):
|
||||
for fname in sorted(list(set(os.listdir(srcdir)))):
|
||||
if fname.startswith("."):
|
||||
continue
|
||||
|
||||
fpath = os.path.join(srcdir, fname)
|
||||
if os.path.isfile(fpath):
|
||||
with open(fpath) as f:
|
||||
ignore_key = False
|
||||
addresses = []
|
||||
port = 655 # tinc default port
|
||||
|
||||
for line in f.readlines():
|
||||
|
||||
if '-----BEGIN RSA PUBLIC KEY-----' in line:
|
||||
ignore_key = True
|
||||
elif '-----END RSA PUBLIC KEY-----' in line:
|
||||
ignore_key = False
|
||||
|
||||
if line.startswith("#") or ignore_key:
|
||||
continue
|
||||
|
||||
chunks = line.split("=")
|
||||
if len(chunks) == 2:
|
||||
import pdb
|
||||
# pdb.set_trace()
|
||||
(k, v) = (x.strip().lower() for x in chunks)
|
||||
|
||||
if k == "port":
|
||||
try:
|
||||
port = int(v)
|
||||
except ValueError:
|
||||
error("non-integer default port given")
|
||||
elif k == "address":
|
||||
if " " in v:
|
||||
parts = v.split(' ')
|
||||
if len(parts) != 2:
|
||||
error("unknown address format")
|
||||
try:
|
||||
int(parts[1])
|
||||
addresses.append(parts)
|
||||
except ValueError:
|
||||
error("non-integer port given")
|
||||
else:
|
||||
addresses.append((v, None))
|
||||
elif k in ('ecdsapublickey'):
|
||||
continue
|
||||
else:
|
||||
error("unknown key {key} with value {val}"
|
||||
.format(key=k, val=v))
|
||||
|
||||
# set explicit port for address/port pairs
|
||||
for i, addr in enumerate(addresses):
|
||||
if addr[1] is None:
|
||||
item = (addr[0], port)
|
||||
addresses[i] = item
|
||||
|
||||
yield(dict(community=fname, addresses=addresses))
|
||||
|
||||
|
||||
def do_checks(srcdir):
|
||||
errcnt = 0
|
||||
for host in get_hosts_data(srcdir):
|
||||
print("Checking {community}".format(community=host['community']))
|
||||
for address in host['addresses']:
|
||||
host, port = address
|
||||
|
||||
# dns lookup
|
||||
records = check_host_lookup(host, port)
|
||||
if not records:
|
||||
errcnt += 1
|
||||
else:
|
||||
for record in records:
|
||||
if record[1] is not socket.SocketType.SOCK_DGRAM:
|
||||
# we get SOCK_STREAM, SOCK_DGRAM and SOCK_RAW
|
||||
# for every IP/Port pair, lets just pick one
|
||||
# to have unique ip addresses
|
||||
continue
|
||||
errcnt += check_reachability(record[4][0], record[0])
|
||||
|
||||
print("{errcnt} errors".format(errcnt=errcnt))
|
||||
|
||||
return 0 if errcnt == 0 else 1
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
parser = OptionParser()
|
||||
parser.add_option("-s", "--sourcedir", dest="src",
|
||||
help="Location of tinc host files. Default: ../hosts",
|
||||
metavar="DIR",
|
||||
default="../hosts/")
|
||||
|
||||
(options, args) = parser.parse_args()
|
||||
|
||||
ret = do_checks(options.src)
|
||||
|
||||
sys.exit(ret)
|
Loading…
Reference in a new issue