From f139bd20093084b84c5488d78e290acaad48aa4d Mon Sep 17 00:00:00 2001 From: Thomas Bellman <bellman@lysator.liu.se> Date: Sat, 24 Nov 2018 15:06:22 +0100 Subject: [PATCH] Add stub for new plugin check_ping_multiaddr. This adds the beginning of a new plugin, check_ping_multiaddr, which is intended to be used to check that a host respond is alive and responds to ping on all of its addresses, both IPv4 and IPv6, in a single call. What's added here is stub only implementing rudimentary argument parsing, to give an idea of the user interface. The intent is to use the fping(1) command for the actual pinging, since it is intended to be used by other programs (and thus has output reasonably easy to parse), and can check multiple addresses in parallel. (However, you need to use fping for IPv4 and fping6 for IPv6, so two invocations are needed.) There are of course already many Nagios plugins for checking that a host is alive out there, including the common 'check_ping' plugin from the official Nagios Plugins project, and several others at the Nagios Exchange, but none (that I have found) that can check both IPv4 and IPv6 addresses in a single call. Some alternatives examined and rejected: - check_mping Only supports IPv4, and checks the hosts in serial. - check_icmp Does check addresses in parallel, but only supports IPv4, and has uncertain copyright status (it is basically a hacked version of fping). It also needs to be installed setuid root. - check_fping Same as check_icmp. --- Makefile | 2 +- README | 5 +- check_ping_multiaddr.py | 117 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 121 insertions(+), 3 deletions(-) create mode 100755 check_ping_multiaddr.py diff --git a/Makefile b/Makefile index f928d0a..858fdb7 100644 --- a/Makefile +++ b/Makefile @@ -31,7 +31,7 @@ include Version.inc ######################################################################### # Internal variables, not intended to be overridden by users -_PYPLUGINS = check_ospf_nbr +_PYPLUGINS = check_ospf_nbr check_ping_multiaddr _PYLIBS = trh_nagioslib _MIBFILES = OSPFV3-MIB.txt _RPM_SPECFILE = $(PKGNAME)-$(VERSION).spec diff --git a/README b/README index 08688b8..c06129b 100644 --- a/README +++ b/README @@ -28,12 +28,13 @@ SNMP MIB files are likely to be licensed under different terms. ===== WHAT IS THIS ===== This is a collection of Nagios plugins, with a focus on network -monitoring. Currently only a single one, though: +monitoring. Currently only two, though: - check_ospf_nbr Check that an OSPF neighbour of a router is present and in state FULL. Both OSPF v2 (for IPv4) and OSPF v3 (for IPv6) is supported. - + - check_ping_multiaddr Check that multiple IP addresses (both IPv4 + and IPv6, at the same time) respond to ping. ===== INSTALLATION ===== diff --git a/check_ping_multiaddr.py b/check_ping_multiaddr.py new file mode 100755 index 0000000..e533c12 --- /dev/null +++ b/check_ping_multiaddr.py @@ -0,0 +1,117 @@ +#!/usr/bin/env python2 +# -*- coding: utf-8; indent-tabs-mode: nil -*- + +# Copyright © 2018 Thomas Bellman, Linköping, Sweden +# Licensed under the GNU LGPL v3+; see the README file for more information. + + +# Explicitly assign to __doc__ to avoid doc string being optimized out. +__doc__ = """\ +Check that one or more IP addresses responds to ping. + +Both IPv4 and IPv6 can be checked at the same time. +""" + +__version__ = '<#VERSION#>' + + +import sys +import re +import os +import optparse +import ipaddr +import socket +import subprocess + +import trh_nagioslib + + + +class ProgramFailure(Exception): + def __init__(self, status, msg): + Exception.__init__(self) + self.status = status + self.msg = msg + + +class Options(optparse.OptionParser): + + def __init__(self): + global __doc__, __version__ + optparse.OptionParser.__init__( + self, + usage="%prog {-4|-6} [options] -- address ...", + version=__version__, + description=__doc__) + self.add_option( + '-4', '--ipv4', action='store_true', default=False, + help=("Use IPv4 [default: %default]." + " At least one of --ipv4 and --ipv6 must be given.")) + self.add_option( + '-6', '--ipv6', action='store_true', default=False, + help=("Use IPv6 [default: %default]." + " At least one of --ipv4 and --ipv6 must be given.")) + self.add_option( + '-A', '--all-addresses', action='store_true', default=False, + help=("Check all addresses each hostname resolves to." + " By default, only the first address for each host is" + " checked.")) + + def get_version(self): + progname = self.get_prog_name() + pkgname = "<#PKGNAME#>" + version = self.version + vinfo = "%s (%s) version %s" % (progname, pkgname, version) + return vinfo + + def check_values(self, values, args): + if len(args) < 1: + self.error("At least one IP address is required") + if not values.ipv4 and not values.ipv6: + self.error("At least one IP version must be specified (-4, -6)") + return values,args + + def exit(self, status=0, msg=None): + if msg: + sys.stderr.write(msg) + # Exit with EX_USAGE, unless status==0 (which happens for --help) + raise ProgramFailure(status=(status and os.EX_USAGE), msg=msg) + + +OPTIONS,_ = Options().parse_args(['-A', '-6', '-4', '--', 'localhost']) + + +def fail(status, fmt, *args): + progname = os.path.basename(sys.argv[0] or "check_ospf_nbr") + msg = progname + ": " + fmt % args + "\n" + sys.stderr.write(msg) + raise ProgramFailure(status=status, msg=msg) + + + +def main(argv): + global OPTIONS + OPTIONS, arg_addresses = Options().parse_args(argv[1:]) + + ping_statuses = { + 'UNKNOWN': [ 'check_ping_multiaddr not yet implemented' ], + } + lvl,message = trh_nagioslib.nagios_report(ping_statuses) + sys.stdout.write(message) + return lvl + + + +if __name__ == '__main__': + try: + code = main(sys.argv) + sys.exit(code) + except ProgramFailure as failure: + sys.exit(failure.status) + except Exception: + # An exception would normally cause Python to exit with code == 1, + # but that would be a WARNING for Nagios. Avoid that. + (exc_type, exc_value, exc_traceback) = sys.exc_info() + import traceback + traceback.print_exception(exc_type, exc_value, exc_traceback) + sys.exit(os.EX_SOFTWARE) -- GitLab