Add simple check script:
- check dns forward lookups - check reachability via icmpv4/icmpv6 echo request
This commit is contained in:
		
					parent
					
						
							
								224cc5606c
							
						
					
				
			
			
				commit
				
					
						5dbe872abf
					
				
			
		
					 1 changed files with 131 additions and 0 deletions
				
			
		
							
								
								
									
										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…
	
	Add table
		Add a link
		
	
		Reference in a new issue