File check_tw_cli.pl of Package monitoring-plugins-tw_cli
#! /usr/bin/perl -w
# check_tw_cli Copyright (C) 2006 Stephan Lauffer <lauffer@ph-freiburg.de>
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty
# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# you should have received a copy of the GNU General Public License
# along with this program (or with Nagios); if not, write to the
# Free Software Foundation, Inc., 59 Temple Place - Suite 330,
# Boston, MA 02111-1307, USA
use strict;
use Getopt::Long;
use vars qw($PROGNAME);
use lib "/usr/lib/nagios/plugins";
use utils qw ($TIMEOUT %ERRORS &print_revision &support);
sub print_help ();
sub print_usage ();
my (
# nagios plugin default options...
$opt_h,
$opt_V,
$opt_t,
$verbose,
# check_tw_cli options...
$opt_d,
$opt_r,
$opt_U,
# others...
$result,
$message,
$version,
$author,
# tw_cli related...
$tested_cli_version,
$tested_api_version,
$cli_version,
$api_version,
$tw_cli_bin,
$tw_cli_exec,
$tw_cli_version,
$tw_cli_unit,
$tw_cli_unittype,
$tw_cli_status,
$tw_cli_cmpl,
$tw_cli_port,
$tw_cli_cmd,
$tw_cli_critical_v1,
$tw_cli_critical_v2,
);
###########
#
# configuration
# PLEASE CHECK $tw_cli_bin AND $tw_cli_exec for your requirements! Any other variables should not be changed.
#
$tw_cli_bin = '/usr/local/sbin/tw_cli';
$tw_cli_exec = "/usr/bin/sudo";
$PROGNAME = "check_tw_cli";
$version = "0.3.1";
$author = 'Copyright (C) 2006 Stephan Lauffer <lauffer@ph-freiburg.de>';
$opt_r = "";
$opt_U = "";
$opt_d = "";
$message = "";
$result = "";
$tw_cli_unit = "";
$tw_cli_unittype = "";
$tw_cli_status = "";
$tw_cli_cmpl = "";
$tw_cli_port = "";
$tw_cli_critical_v1 = 'CORRUPT|INCOMPLETE|';
$tw_cli_critical_v2 = 'CORRUPT|INOPERABLE';
$tested_cli_version = '2\.00\..*'; # please use a regex syntax here. this test may be removed in the future
$tested_api_version = '2\.00\..*'; # please use a regex syntax here. this test may be removed in the future
$tw_cli_version = 'UNKNOWN';
$cli_version = 'UNKNOWN';
$api_version = 'UNKNOWN';
#
############
Getopt::Long::Configure('bundling');
GetOptions(
"V" => \$opt_V, "version" => \$opt_V,
"v" => \$verbose, "verbose" => \$verbose,
"h" => \$opt_h, "help" => \$opt_h,
"d" => \$opt_d, "detailed" => \$opt_d,
"r=f" => \$opt_r, "raid-controller-number=f" => \$opt_r,
"U=f" => \$opt_U, "unit-number=f" => \$opt_U,
);
############
# some checks...
#
# note:
# first "bad" return code wins although further test will follow
if ($opt_V) {
print_revision($PROGNAME, "$version $author");
exit $ERRORS{'OK'};
}
if ($opt_h) {
print_help();
exit $ERRORS{'OK'};
}
if ($opt_r eq "") {
$message .= "No raid controller number given\n";
$result or $result = 'UNKNOWN';
} elsif ($opt_r !~ /^\d$/) {
$message .= "$opt_r ist not a valid controller number\n";
$result or $result = 'UNKNOWN';
}
if ($opt_U eq "") {
$message .= "No unit number given\n";
$result or $result = 'UNKNOWN';
} elsif ($opt_U !~ /^\d$/) {
$message .= "$opt_r ist not a valid unit number\n";
$result or $result = 'UNKNOWN';
}
if ($tw_cli_exec and ! -f $tw_cli_exec) {
$message .= "$tw_cli_exec missing!\n";
$result or $result = 'UNKNOWN';
}
if (! -f $tw_cli_bin) {
$message .= "$tw_cli_bin missing!\n";
$result or $result = 'UNKNOWN';
}
$message and print $message;
$result and exit $ERRORS{$result};
#
############
############
# main
# start timeoutcheck
$SIG{'ALRM'} = sub {
print ("ERROR: No response from check_tw_cli (alarm)\n");
exit $ERRORS{"UNKNOWN"};
};
alarm($TIMEOUT);
# check tw_cli/cli/api version
$verbose and print "Testing tw_cli version...\n";
open (TW_CLI, "$tw_cli_exec $tw_cli_bin show ver 2>\&1|") or exit $ERRORS{"UNKNOWN"};
while (<TW_CLI>) {
chomp;
$verbose and print "$_\n";
# someone may have problem with his 3ware-tool (:
/^opendir: No such file or directory/ and last;
# "hack" to detect if this is a tw_cli v1...:
/^Unknown command 'show'/ and $tw_cli_version = "v1" and last;
if (/^CLI Version = ([\d+\.]+)/) {
$cli_version = $1;
if ($cli_version !~ /^$tested_cli_version/) {
$message .= "CLI Version $cli_version not supported by $PROGNAME $version\n";
$result or $result = 'UNKNOWN';
} else {
$tw_cli_version = "v2";
}
}
if (/^API Version = ([\d+\.]+)/) {
$api_version = $1;
if ($api_version !~ /^$tested_api_version/) {
$message .= "API Version $1 not supported by $PROGNAME $version\n";
$result or $result = 'UNKNOWN';
}
}
}
close TW_CLI;
$verbose and print "Test finished - CLI version: $cli_version, API versino: $api_version, tw_cli_version: $tw_cli_version\n\n";
# exit if tw_cli is not "known", does not work with this plugin
if ($cli_version eq "UNKNOWN" or $api_version eq "UNKNOWN" or $tw_cli_version eq "UNKNOWN") {
$tw_cli_version eq "UNKNOWN" and
$message = "Warning: your tw_cli does not work. See Q10166, Q11928 or other articles in the 3ware knowledge base.\n";
$message .= "tw_cli, API/CLI Version not known\n";
$result or $result = 'UNKNOWN';
exit $ERRORS{$result};
}
# go ahead with the raid status tests...
$result = "UNKNOWN"; # set state to unknow until we know a bit more...
# prepare the tw_cli command
if ($tw_cli_version eq "v1") {
$tw_cli_cmd = "/c${opt_r}/u${opt_U} show";
} elsif ($tw_cli_version eq "v2") {
$tw_cli_cmd = "info c${opt_r} u${opt_U}";
} else {
print "tw_cli_cmd not know for tw_cli_version $tw_cli_version!\n";
exit $ERRORS{$result};
}
# execute tw_cli
$verbose and print "Reading raid status (\"$tw_cli_exec $tw_cli_bin $tw_cli_cmd\")\n";
open (TW_CLI, "$tw_cli_exec $tw_cli_bin $tw_cli_cmd|") or exit $ERRORS{"UNKNOWN"};
while (<TW_CLI>) {
chomp;
$verbose and print "$_\n";
# checking v1 reports...
# note: the report results from tw_cli v1 are not well know by this plugin (please test && send reports)
# any not "OK" status causes a warning, every $tw_cli_critical_v2 match causes a CRITICAL check_tw_cli return
if ($tw_cli_version eq "v1") {
my $hot=0;
/^Controller\s+$opt_r,\s+Unit\s+$opt_U/ and $hot = 1;
$hot and /^Status:\s+(.{,12})/ and $tw_cli_status = $1; # sorry, I don't know all the return codes...
$hot and /^Unit Type:\s+(.{,12})/ and $tw_cli_unittype = $1; # sorry, I don't know...
if ($tw_cli_status and $tw_cli_unittype) {
$tw_cli_status ne "OK" and $result = "WARNING";
if ($tw_cli_status =~ /^($tw_cli_critical_v1)/) {
$result ='CRITICAL';
}
$message = "RAID Status on c$opt_r $tw_cli_unittype: $tw_cli_status";
last;
}
# checking v2 reports...
# note: the report results from tw_cli v2 are not well know by this plugin (please test && send reports)
# any not "OK" status causes a warning, every $tw_cli_critical_v2 match causes a CRITICAL check_tw_cli return
} elsif ($tw_cli_version eq "v2") {
# Unit UnitType Status %Cmpl Port
if (/^(u[\d\-]+)\s+([\w\-]+)\s+([\w\-]+)\s+([\w\-]+)\s+([\w\-]+)/) {
$tw_cli_unit = $1;
$tw_cli_unittype = $2;
$tw_cli_status = $3;
$tw_cli_cmpl = $4;
$tw_cli_port = $5;
$tw_cli_unittype =~ /^RAID/ and $result = $tw_cli_status;
$tw_cli_status ne "OK" and $result = "WARNING";
if ($tw_cli_status =~ /^($tw_cli_critical_v2)/) {
$result ='CRITICAL';
}
$tw_cli_unittype =~ /^RAID/ and $message = "RAID Status on c$opt_r $tw_cli_unit: $tw_cli_status";
if ($opt_d) {
$message .= " - UnitType: $tw_cli_unittype, Status: $tw_cli_status, ";
$tw_cli_cmpl ne "-" and $message .= "\%Cmpl $tw_cli_cmpl, ";
$tw_cli_port ne "-" and $message .= "Port: $tw_cli_port, ";
}
} else {
# $verbose and print "unknown tw_cli result:$_\n";
}
$message =~ s/, $//;
}
}
close TW_CLI;
# disable alarm
alarm(0);
# return message and exit with returncode
print "$message\n";
exit $ERRORS{$result};
#
############
############
# subs
sub print_usage () {
print "Usage:\n";
print " $PROGNAME [[-r <number>] [-U <number>]] [-v | --verbose] [ -d | --detailed]\n";
print " $PROGNAME [-h | --help]\n";
print " $PROGNAME [-V | --version]\n";
}
sub print_help () {
print_revision($PROGNAME, "$version");
print "$author\n\n";
print "$PROGNAME was written to read the status of a 3ware RAID on localhost.\n\n";
print_usage();
print "\n";
print " Example: ./check_tw_cli -r 0 -U 0\n";
print "\n";
support();
}
#
############
# eof