#!/usr/bin/perl -w

# Version:    0.2
# Date:       Feb 5, 2021
# Author:     ivan.stetka@live.com
# Summary:    This is a Nagios plugin to check ping on balanced hosts

use strict;
use Getopt::Long qw(:config no_ignore_case bundling);
use Socket;

my %STATES = (
    OK       => 0,
    WARNING  => 1,
    CRITICAL => 2,
    UNKNOWN  => 3
);

my $hosts = '';
my $critLimit = '5000,100';
my $warn = 1;
my $crit = 2;
my $okCount = 0;
my $critCount = 0;
my $state = 3;
my $help = 0;
my $pluralOhost = 's are';
my $pluralChost = 's are';
my @a_hosts= ();
my @okHosts = ();
my @critHosts = ();
my @longText = ();
my @perfData = ();

GetOptions(
    'H|hosts:s'     => \$hosts,
    'C|critLimit:s' => \$critLimit, # critical
    'w|warning:n'   => \$warn,
    'c|critical:n'  => \$crit,
    'h|help'        => \$help
);

if ($help) {
    help();
    exit($STATES{OK});
}

if (defined($hosts)) {
    @a_hosts=split(/,/, $hosts);
}else {
    print "Hosts not defined\n";
    exit($STATES{CRITICAL});
}

my $a_hostsCount = @a_hosts;
my ($line, $pData1, $pData2, $stdout, $nameHosts, $ipDNS) = ('','','','','','');
foreach my $i (@a_hosts) {
    my $sOut = 'unreachable';
    $nameHosts = gethostbyaddr(inet_aton($i), AF_INET ) or $nameHosts = "no DNS";
    if ($nameHosts eq "no DNS") {
        $ipDNS = "$i";
    }else {
        $ipDNS = "$nameHosts";
    }
    open CHECK_PING,"/usr/lib/nagios/plugins/check_ping -H $i -w $critLimit% -c $critLimit% -p 1 | " or die "Could not open Ping plugin!";
    $line=<CHECK_PING>;
    $line =~ s/\n//;    
    if ($line =~ /PING OK - (.*)\|rta(=.*) pl(=.*)/) {
        $sOut = 'OK';
        $okCount++;
        $stdout = $1;
        $pData1 = $2;
        $pData2 = $3;
        push @okHosts, $ipDNS;
    }elsif ($line =~ /PING CRITICAL - (.*)\|rta(=.*) pl(=.*)/) {
        $sOut = 'CRITICAL';
        $critCount++;
        $stdout = $1;
        $pData1 = $2;
        $pData2 = $3;
        push @critHosts, $ipDNS;
    }else {
        $sOut = 'CRITICAL';
        $critCount++;
        $stdout = $line;
        $pData1 = "'No perf data.'";
        $pData2 = "'No perf data.'";
        push @critHosts, $ipDNS;
    }
    close CHECK_PING;
   push @longText, "Ping on the host $ipDNS is $sOut: $stdout";
   push @perfData, "\'RTA " . $ipDNS . "\'" . $pData1 . "\'PL " . $ipDNS . "\'" . $pData2;
}

if ($okCount == 1) {($pluralOhost = ' is');}
if ($critCount == 1) {($pluralChost = ' is');}

my $okHostJ = join ', ', @okHosts;
my $critHostJ = join ', ', @critHosts;

if ($okCount == $a_hostsCount)  {
    print "OK: Ping on $okCount host$pluralOhost OK: $okHostJ.\n";
    $state = ($STATES{OK});
} elsif (($okCount + $critCount) != $a_hostsCount)  {
    print "CRITICAL: Total hosts are $a_hostsCount but only $okCount host$pluralOhost OK and $critCount host$pluralChost CRITICAL.\n";
    $state = ($STATES{CRITICAL});
} elsif ($critCount >= $crit)  {
    print "CRITICAL: Ping on $critCount host$pluralChost CRITICAL: $critHostJ.\n";
    $state = ($STATES{CRITICAL});
} elsif ($critCount >= $warn)  {
    print "WARNING: Ping on $critCount host$pluralChost CRITICAL: $critHostJ.\n";
    $state = ($STATES{WARNING});
} else {
    print "CRITICAL: unexpected plugin error.\n";
    $state = ($STATES{CRITICAL});
}

print "$_\n" for @longText;
print "|";
print "$_ " for @perfData;
print "\n";
exit($state);

# Help
sub help {
    print <<HELP;
H E L P:

This is a nagios plugin to check ping on balanced hosts by plugin check_ping

-H, --hosts             # comma-separated list of IP addresses of balanced hosts
-C, --critLimit         # critical threshold for Ping check
-w, --warning           # number of critical hosts for the warning alert [default: 1]
-c, --critical          # number of critical hosts for the critical alert [default: 2]
-h, --help              # print this help

HELP
}
