#!/usr/bin/perl -wT

# check_rrd_data plugin for nagios
#
# usage:
#    check_rrd machine_id perlexp_warn perlexp_crit perlexp_default [ds]
#
# Checks data from a RRD file. machine_id is normally an IP address, that has
# to be mapped to a RRD file, by means of the config file (by default
# /var/spool/nagios/rrd-files, a file with pairs of (machine_id,rrd_file),
# separated by whitespace). It can be a RRD file, too.
#
# The Perl expressions are expressions to be evaluated in the following cases:
#
# - perlexp_crit. The first one, to check if there is a critical situation. If
# it returns other than "", it will be a critical message.
# - perlexp_warn. The second one to be evaluated. If returns other than "", a
# warning will be issued to Nagios.
# - perlexp_default. If both of the above return "", it will be evaluated, and
# wathever returns this expression will be returned by the script. NOTE that
# this is different from the other two cases, to allow the user issue a
# warning or critical failure even if the other two don't return it.
#
# Use these hosts.cfg entries as examples
#
# command[check_ping]=$USER1$/check_rrd_data.pl $HOSTADDRESS$ \
#	'return "CHECK_CRICKET_PING: Warning\n" if ($value > 10);' 'return \
#	"CHECK_CRICKET_PING: Critical\n" if ($value > 100);' 'printf \
#	"PING OK - RTA = %.2fms\n", $value; return 0;' 1
# service[machine]=PING;0;24x7;3;5;1;router-admins;240;24x7;1;1;1;;check_ping
#
# initial version: 28 Nov 2000 by Esteban Manchado Velázquez
# current status: 0.1
#
# Copyright Notice: GPL
#

require 5.004;
use strict;
use lib utils.pm ;
use Plugin;
use Plugin::Parameter qw(:DEFAULT);

use vars qw($PROGNAME $opt_D $opt_t $opt_ds $opt_f $opt_w $opt_c $opt_d);

use utils qw(%ERRORS);

use RRD::File;

my $f_opt = new Plugin::Parameter(-name => "rrdfile", -flags => [ 'f', 'rrdfile' ],
				  -optional => "no", -valueoptional => "no", -type => "FILENAME",
				  -description => "RRD File name or machine_id");
my $w_opt = new Plugin::Parameter(-name => "warning", -flags => [ 'w', 'warning' ],
				  -optional => "no", -valueoptional => "no", -type => "PERLEXP",
				  -description => "Perl expression applied to current value of the data source - positive result gives warning");
my $c_opt = new Plugin::Parameter(-name => "critical", -flags => [ 'c', 'critical' ],
				  -optional => "no", -valueoptional => "no", -type => "PERLEXP",
				  -description => "Perl expression applied to current value of the data source - positive result gives critical");
my $d_opt = new Plugin::Parameter(-name => "default", -flags => [ 'd', 'default' ],
				  -optional => "yes", -valueoptional => "no", -type => "PERLEXP",
				  -default => sub { return ""; },
				  -description => "Perl expression evaluated if no warning or critical state detected");
my $ds_opt = new Plugin::Parameter(-name => "dataset", -flags => [ 'ds', 'dataset' ],
				   -optional => "yes", -valueoptional => "no", -type => "INTEGER",
				   -default => 0,
				   -description => "Which RRD dataset do we want to check");
my $D_opt = new Plugin::Parameter(-name => "directory", -flags => [ 'D', 'directory' ],
				  -optional => "yes", -valueoptional => "no", -type => "DIRECTORY",
				  -default => "/var/spool/nagios/rrd-files",
				  -description => "Path to RRD-Files for machinid matching");
my $plugin = new Plugin(-revision => '$Revision: 1.1.1.1 $',
			-copyright => "2000 Esteban Manchado Velázquez, 2004 Howard Wilkinson <howard\@cohtech.com>",
			-shortcomment => "Checks data from a RRD file. machine_id is normally an IP address, that has to be mapped to a RRD file, by means of the config file (by default /var/spool/nagios/rrd-files, a file with pairs of (machine_id,rrd_file), separated by whitespace). It can be a RRD file, too.",
			-parameterlists => [ [ $f_opt, $w_opt, $c_opt, $d_opt, $ds_opt, $D_opt, $t_opt ], $h_opts, $V_opts ]);


$plugin->init();

my $configfilepath = $opt_D;

my %hostfile;						# For storing config
my $rrdfile;						# RRD file to open

$ENV{'PATH'} = "/bin:/usr/bin";
$ENV{'ENV'} = "";

$plugin->start_timeout($opt_t, "HUNG while reading files");

# Check configuration file
open F, $configfilepath or do {
        $plugin->usage();
	utils::usage("$PROGNAME UNKNOWN: Can't open config file $configfilepath\n");
};
while (<F>) {
	next unless /(.+)\s+(.+)/;
	$hostfile{$1} = $2;
}
close F;

# Default
my $ds = $opt_ds;
$ds =~ s/\$//g;		# Sometimes Nagios gives 1$ as the last parameter

# Guess which RRD file have to be opened
$rrdfile = $opt_f if (-r $opt_f);		# First the parameter
$rrdfile = $hostfile{$opt_f} unless $rrdfile;	# Second, the config file

if (! $rrdfile) {
        $plugin->usage();
	utils::usage("$PROGNAME UNKNOWN: Can't open data file for $opt_f\n");
}

my $rrd = new RRD::File ( -file => $rrdfile );
$rrd->open();
if (! $rrd->loadHeader()) {
        $plugin->usage();
	utils::usage("$PROGNAME UNKNOWN: Couldn't read header from $rrdfile\n");
}
my $value = $rrd->getDSCurrentValue($ds);
$rrd->close();

# Perl expressions to evaluate
my ($perl_exp_warn, $perl_exp_crit, $perl_exp_default) =
		($opt_w, $opt_c, $opt_d);
my $result;	# Result of the expressions (will be printed)
my @data;	# Special data reserved for the expressions, to pass data

# We should force Nagios style output here but for backwards compatibility
# Allow anything!
# First check for critical errors
$perl_exp_crit =~ /(.*)/;
$perl_exp_crit = $1;
$result = eval $perl_exp_crit;
if ($result) {
	print $result;
	exit $ERRORS{'CRITICAL'};		# Critical
}

# Check for warnings
$perl_exp_warn =~ /(.*)/;
$perl_exp_warn = $1;
$result = eval $perl_exp_warn;
if ($result) {
	print $result;
	exit $ERRORS{'WARNING'};		# Warning
}

$perl_exp_default =~ /(.*)/;
$perl_exp_default = $1;
$result = eval $perl_exp_default;
print $result;
exit $ERRORS{'OK'};

