diff --git a/check_ping_multiaddr.py b/check_ping_multiaddr.py index ca7460315d99d884801403663a8e0d4cc9e26cd4..1a297dc4e398662e10805c69bc8e9d45ea4241d1 100755 --- a/check_ping_multiaddr.py +++ b/check_ping_multiaddr.py @@ -145,6 +145,63 @@ def collect_addresses(hosts, all_addresses, do_v4, do_v6): +__fping_parser_re = re.compile(r"^([0-9a-f.:]+) is ([a-z]+)$") + +def parse_fping_output(output, expected_addrs): + alive = set() + unreachable = set() + for line in filter(bool, output): + match = __fping_parser_re.match(line) + if not match: + continue + ip = ipaddr.IPAddress(match.group(1)) + status = match.group(2) + if status == 'alive': + alive.add(ip) + elif status == 'unreachable': + unreachable.add(ip) + else: + raise RuntimeError( + "Unexpected status line from fping, " + repr(line)) + not_reported = expected_addrs - alive - unreachable + unexpected = (alive | unreachable) - expected_addrs + + return (alive, unreachable, not_reported, unexpected) + + +def ping_addresses(addresses): + fpingcmds = { + 4: ['fping'], + 6: ['fping6'], + } + fpingflags = [ + # These settings gives ca 5 seconds timeout for unreachable addresses + '-i10', # -i10 is the fastest fping allows without being root + '-t250', + '-B1.125', + '-r9', + ] + all_output = [] + for ipver,addrs in addresses.items(): + if not addrs: + continue + cmd = fpingcmds[ipver] + fpingflags + map(str, addrs) + chatter(1, "Running %r", cmd) + p = subprocess.Popen( + cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + output,errors = p.communicate() + output = output.split("\n"); errors = errors.split("\n") + chatter(3, "Received output %r", output) + chatter(3, "Received errors %r", errors) + all_output += output + + alive, unreachable, not_reported, unexpected = parse_fping_output( + all_output, set().union(*addresses.values())) + + return (alive, unreachable, not_reported, unexpected) + + + def main(argv): global OPTIONS OPTIONS, arg_addresses = Options().parse_args(argv[1:]) @@ -155,8 +212,15 @@ def main(argv): for ipver,addrs in addresses.items(): chatter(2, "IPv%d addresses: %s", ipver, " ".join(map(str, addrs))) + (alive, unreachable, not_reported, unexpected) = \ + ping_addresses(addresses) + + # XXX: Better messages ping_statuses = { - 'UNKNOWN': [ 'check_ping_multiaddr not yet implemented' ], + 'OK': map(str, alive), + 'WARNING': map(str, unexpected), + 'CRITICAL': map(str, unreachable), + 'UNKNOWN': map(str, not_reported), } lvl,message = trh_nagioslib.nagios_report(ping_statuses) sys.stdout.write(message)