aboutsummaryrefslogtreecommitdiff
path: root/check_nrpe_cluster
blob: dadbc6c583dc2a56f0baa60cc6f1323a582b5ed8 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
#!/usr/bin/env perl

#
# Run two or more NRPE checks and return a status based on their aggregated
# results, similar to check_cluster. fork(2)s ahoy!
#
# Author: Tom Ryder <tom@sanctum.geek.nz>
# Copyright: 2015
#
# $Id$
#
package Nagios::Plugin::NRPE::Cluster;

# Force me to write this properly
use strict;
use warnings;
use utf8;
use autodie qw(:all);

# Require at least Perl 5.10
use 5.010;

# Decree package version
our $VERSION = 1.0;

# Import required modules
use English qw(-no_match_vars);    # dpkg: perl-core
use IPC::Run3;                     # dpkg: libipc-run3-perl
use Nagios::Plugin;                # dpkg: libnagios-plugin-perl

# Find path to Nagios' plugins
my $plugins_dir =
  exists $ENV{NAGIOS_PLUGINS_DIR}
  ? $ENV{NAGIOS_PLUGINS_DIR}
  : '/usr/local/nagios/libexec';

# Build Nagios::Plugin object
my $np = Nagios::Plugin->new(
    usage => 'Usage: %s [-w THRESHOLD] [-c THRESHOLD] '
      . 'HOSTNAME1:CHECK1,HOSTNAME2:CHECK2[,HOSTNAME3:CHECK3...]',
    version => $VERSION,
);

# Add warning and critical options
$np->add_arg(
    spec => 'warning|w=s',
    help => "-w, --warning=THRESHOLD\n"
      . '   Warning threshold for the number of OK checks',
);
$np->add_arg(
    spec => 'critical|c=s',
    help => "-c, --critical=THRESHOLD\n"
      . '   Critical threshold for the number of OK checks',
);

# Read options
$np->getopts();

# Need one of --warning or --critical
if ( !$np->opts->warning && !$np->opts->critical ) {
    $np->nagios_die(q{Need one/both of --warning or --critical});
}

# Verify we have at least two host:check pairs
my @pairs;
if (@ARGV) {
    @pairs = split m{,}msx, $ARGV[0];
}
if ( @pairs < 2 ) {
    $np->nagios_die(q{Need at least two HOSTNAME:CHECK definitions});
}

# Verify all of the arguments are in the expected format
my @invalids = grep { !m{[^:]+:[^:]+}msx } @ARGV;
if (@invalids) {
    $np->nagios_die( q{Argument(s) %s are not in HOSTNAME:CHECK format},
        join q{,}, @invalids );
}

# Start counting down to timeout
alarm $np->opts->timeout;

# Run the checks and collect a list of successes and failures
my ( @pass, @fail );
foreach my $pair (@pairs) {
    my ( $hostname, $command ) = split m{:}msx, $pair;
    my $cmd = [ $plugins_dir . '/check_nrpe', '-H', $hostname, '-c', $command ];
    run3 $cmd, \undef, \undef, \undef;
    if ( $CHILD_ERROR == 0 ) {
        push @pass, $pair;
    }
    else {
        push @fail, $pair;
    }
}

# Compare the check results to the failures
my $code = $np->check_threshold(
    check    => scalar @pass,
    warning  => $np->opts->warning,
    critical => $np->opts->critical,
);
$np->nagios_exit( $code, sprintf 'All checks run, %u passes, %u failures',
    scalar @pass, scalar @fail );

# This should never happen, but if it does we may as well be explicit about it
$np->nagios_die(q{Couldn't work out how to aggregate checks});