#!/usr/bin/perl
#
# check_ibm_v7000 Nagios check
#
# Requires IBM's SVC.pm
#  http://www.alphaworks.ibm.com/tech/svctools
#
# Requires you configure an ssh key for logins to your V7000 storage array.
#
# Mike Austin <mga@uvm.edu>, 1/21/2011
#
# Version 1.0, initial release
#
# ----------------------------------------------------------------------------------------------------
#
# In etc/check_commands.cfg, define a command like:
#
# define command{
#        command_name    check_ibm_v7000
#        command_line    $USER1$/check_ibm_v7000 -cluster=$HOSTADDRESS$ -keyfile=$ARG1$ -ssh=ssh
#        }
#
# In your nagios service, have a service check like:
#
#        check_command                   check_ibm_v7000!path_to_ssh_key
#
#  where path_to_ssh_key is the actual path to your ssh key for the V7000.
#
# ----------------------------------------------------------------------------------------------------
#

use strict;
use IBM::SVC;
use Getopt::Long;

# list of error codes that are really warnings:
my @warnings = ("Array mdisk is not protected by sufficient spares",
		"The operation requested could not be performed because software upgrade is in progress",
		"some other error that is actually OK",
		"ERROR: 256 : CMMVC5772E The operation requested could not be performed because software upgrade is in progress.");

my %OPTS = (
   debug    => 0,
   );

GetOptions (
   "cluster=s"      => \$OPTS{hostname},
   "keyfile=s"      => \$OPTS{keyfile},
   "verbose"        => \$OPTS{verbose},
   "debug"          => \$OPTS{debug},
   "ssh=s"          => \$OPTS{ssh},
   ) 
or usage_error("");

# Nagios exit states
our %states = (
        OK       => 0,
        WARNING  => 1,
        CRITICAL => 2,
        UNKNOWN  => 3
);

# Nagios state names
our %state_names = (
        0 => 'OK',
        1 => 'WARNING',
        2 => 'CRITICAL',
        3 => 'UNKNOWN'
);


# Create the options hash for IBM::SVC
my %svc_opts = (
   cluster_name => $OPTS{hostname},
   debug => $OPTS{debug},
);
$svc_opts{keyfile} = $OPTS{keyfile} if ($OPTS{keyfile} ne '');
$svc_opts{ssh_method} =  $OPTS{ssh} if ( $OPTS{ssh} ne '');

my $message = "";
my $state = "";

my $svc = IBM::SVC->new(\%svc_opts);

print "- Getting information for $OPTS{hostname}\n" if ($OPTS{verbose});

my $svcerror = svctask($svc,"finderr");
chomp $svcerror;

if ($svcerror eq "There are no unfixed errors") {

	$message = "OK - array status is normal";
        $state = 'OK';

} else {
	my $description = "";

	# get error code

	my $errorcode = $svcerror;
	$errorcode =~ s/.*\[//g;
	$errorcode =~ s/]//g;

	# get eventlog dump

	my $svcevent = svcinfo($svc,"lseventlog -message no -fixed no");


	# get count for total number of errors
	my $count = scalar @$svcevent;

	# get description of highest priority unfixed error
	foreach my $line (@{$svcevent}) {
		chomp $line;
		if ($line->{'error_code'} eq "$errorcode") {
			$description = $line->{'description'};
			$message = "$description, $count system errors.";
			last;
		}
	}

	# is the error really a warning?

	$state = warnorerror($description);
}

print $message."\n";
exit $states{$state};


sub svcinfo {
   my $svc = shift;
   my ($rc, $result) = $svc->svcinfo(@_);
   assert("$rc : $result",!$rc);
   return $result;
}

sub svctask {
   my $svc = shift;
   my ($rc, $result) = $svc->svctask(@_);
   assert("$rc : $result",!$rc);
   return $result;
}
sub assert {
   return if ($_[1]);
   $message = "ERROR: ".$_[0];
   chop $message;
   $state = warnorerror($message);
   print $message."\n";
   exit $states{$state};
}
sub usage_error {
   my $msg = shift;
   print STDERR $msg."\n";
   exit 1;
}
sub warnorerror {
   my $msg = shift;
	# is the error really a warning?

	if ( grep ( /^$msg$/,@warnings ) ) {
		$state = 'WARNING';
	}
	else {
		$state = 'CRITICAL';
	}
   return $state;
} 

