#!/usr/libexec/platform-python # version 2016/12/13 # writen by v.burov # Requirements: # you need to allow fillowing commands: # "/bin/ping","ip","sed" # Please pay attention that it's necessary to add access to sudoers file for /bin/ping if it is not SUID import os, stat, re, sys, time, argparse from subprocess import Popen, PIPE ellist='' redlist='' PING = '/bin/ping' SUDO = '/usr/bin/sudo' def check_sudo_usable(): """Checks that the SUDO program and path are correct and usable - that the program exists and is executable, otherwise exits with error.""" if not os.path.exists(SUDO): end(UNKNOWN, "%s cannot be found" % SUDO) elif not os.path.isfile(SUDO): end(UNKNOWN, "%s is not a file" % SUDO) elif not os.access(SUDO, os.X_OK): end(UNKNOWN, "%s is not executable" % SUDO) def get_server_ips(): # Python 2 version; #ips = Popen("ip -4 -o a|sed -e '/inet 127\|inet 10\\.\|inet 172\|inet 192\\.168/d' -e 's/.*inet \(.*\)\/.*/\\1/'", stdout=PIPE, shell=True).stdout.read().split('\n') ips = Popen("ip -4 -o a|sed -e '/inet 127\|inet 10\\.\|inet 100\\.100\\.0\\.\|inet 172\|inet 192\\.168/d' -e 's/.*inet \(.*\)\/.*/\\1/'", stdout=PIPE, shell=True).stdout.read().decode('UTF-8').split('\n') return ips def ping_to_float(s): try: return float(s) except ValueError: return 5000.1 def add_redlist(s): global redlist if redlist=='': redlist='CRITICAL - '+s else: redlist+=', '+s def add_ellist(s): global ellist if ellist=='': ellist='Warning - '+s else: ellist+=', '+s if __name__ == "__main__": parser = argparse.ArgumentParser() parser.add_argument("-v","--verbose", default=False, action="store_true", help="Extra output") parser.add_argument("destination", nargs='?', default="nagios.web-hosting.com", help="Destination") args = parser.parse_args() ips=[] ips=get_server_ips() #print(ips) pingoutputmatch=re.compile("icmp\S+=(\d+)\s+\S+\s+time=(\S+)\s+") destination = args.destination if args.verbose : print("Destination = {}".format(destination)) use_sudo = False if not os.stat(PING).st_mode & stat.S_ISUID: if args.verbose : print("/bin/ping is not SUID: have to use sudo") check_sudo_usable() use_sudo = True running_procs={} result={} for s in ips: if len(s) == 0: continue if use_sudo : running_procs[s]=Popen([SUDO, PING,'-I', s, '-A','-n','-c','3','-W','1',destination], stdout=PIPE, stderr=PIPE) else: running_procs[s]=Popen([PING,'-I', s, '-A', '-n', '-c', '3', '-W', '1', destination], stdout=PIPE, stderr=PIPE) result[s] = ['-','-','-'] i1=0 while running_procs : i1+=1 if i1>1000 : print("Script error: loop") sys.exit(3) for ip in running_procs.keys(): proc = running_procs[ip] retcode = proc.poll() if retcode is not None: # Process finished. del running_procs[ip] break else: # No process is done, wait a bit and check again. time.sleep(.1) continue retcode = proc.poll() if retcode is None: time.sleep(.1) continue i2=0 for output in iter(proc.stdout.readline,b'') : p=pingoutputmatch.search(output.decode('UTF-8')) if p: result[ip][int(p.group(1))-1] = p.group(2) if args.verbose : print("%{} seq={}s time={}s ms".format(ip, p.group(1), p.group(2))) for ip in result.keys(): if args.verbose : print("ip+{}{}{} ".format(result[ip][0],result[ip][1],result[ip][2])) if result[ip][0]=='-' and result[ip][1]=='-' and result[ip][2]=='-': add_redlist(ip) else: p1=ping_to_float(result[ip][0]) p2=ping_to_float(result[ip][1]) p3=ping_to_float(result[ip][2]) if p1>400 and p2>400 and p3>400 : add_redlist('%s(%s;%s;%s)' % (ip,result[ip][0],result[ip][1],result[ip][2])) elif p1>200 and p2>200 and p3>200 : add_ellist('%s(%s;%s;%s)' % (ip,result[ip][0],result[ip][1],result[ip][2])) if len(redlist)>0 : print("{}{}".format(redlist,ellist)) sys.exit(2) if len(ellist)>0 : print(ellist) sys.exit(1) print("OK")