#!/usr/bin/perl -w
#
# check_lsi
#   Nagios script to check lsi controller via SNMP
#
# 
#
# 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; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
#
# Credit:
# I modified someone else's code to make this work, however, I don't remember
# who's and can't find it after searching. Let me know if this looks like your 
# code and you would like credit.
#
# For this script to work, snmp must work on the target machine. For example:
# snmpwalk -v2c -c public web1 1.3.6.1.4.1.674.10893.1.20.130.4.1.4.1


use strict;
use warnings;
use File::Basename;
use Nagios::Plugin ;
use Net::SNMP;

use vars qw($VERSION $PROGNAME  $verbose $warn $critical $timeout $result $result_code $status);
$VERSION = "0.1";
$PROGNAME = basename($0);
my %lsiOIDs = (
		Raid_Array => '.1.3.6.1.4.1.1458.100.23.1.7.',
		Disk  => '.1.3.6.1.4.1.1458.100.22.1.10.',
		Array_Outstanding_IOs => '.1.3.6.1.4.1.1458.100.20.1.20.',
		Array_IOs_Per_Sec => '.1.3.6.1.4.1.1458.100.20.1.23.',
	);
	
my %result_codes_path = (
		Raid_Array => \&raid_result,
		Disk  => \&disk_result,
		Array_Outstanding_IOs => \&out_io_result,
		Array_IOs_Per_Sec => \&io_p_sec_result,
	);	
		
##############################################################################
# define and get the command line options.
#   see the command line option guidelines at
#   http://nagiosplug.sourceforge.net/developer-guidelines.html#PLUGOPTIONS


# Instantiate Nagios::Plugin object (the 'usage' parameter is mandatory)
my $plugin = Nagios::Plugin->new(
    usage => "Usage: %s [ -v|--verbose ]",
    version => $VERSION,
    blurb => 'Check LSI 9750 via SNMP',
    extra => ""
    );
	
# Define and document the valid command line options
# usage, help, version, timeout and verbose are defined by default.

$plugin->add_arg(
	spec => 'host|H=s',
	help =>
qq{-H, --host=STRING
   SNMP host name. },
   default => 'localhost',
);

$plugin->add_arg(
	spec => 'port|P=s',
	help =>
qq{-P, --port=INTEGER
   SNMP port. },
   default => 161,
);

$plugin->add_arg(
	spec => 'community|C=s',
	help =>
qq{-C, --community=STRING
   SNMP community. },
   default => 'public',
);

$plugin->add_arg(
	spec => 'what|W=s',
	help =>
qq{-W, --what=STRING. },
   default => 'Raid_Array_1',
);

$plugin->add_arg(
	spec => 'result|r=f',
	help =>
qq{-r, --result=INTEGER
   Specify the result on the command line rather than generating a
   random number.  For testing.},
);

$plugin->add_arg(
	spec => 'number|N=s',
	help =>
qq{-N, --number=STRING. },
   default => '1',
);

# Parse arguments and process standard ones (e.g. usage, help, version)
$plugin->getopts;


# perform sanity checking on command line options
if ( (defined $plugin->opts->result) && ($plugin->opts->result < 0 || $plugin->opts->result > 20) )  {
    $plugin->nagios_die( " invalid number supplied for the -r option " );
}

#unless ( defined $plugin->opts->warning || defined $plugin->opts->critical ) {
#	$plugin->nagios_die( " you didn't supply a threshold argument " );
#}


##############################################################################
# check stuff.

# THIS is where you'd do your actual checking to get a real value for $result
my $result;
my $what;
my $number;
if (defined $plugin->opts->number)
	{ $number = $plugin->opts->number; }
if (defined $plugin->opts->what)
	{ $what = $plugin->opts->what; }
if (defined $plugin->opts->result)
	{  # you got a 'result' option from the command line options
	$result = $plugin->opts->result;
	print " using supplied result $result from command line \n" if $plugin->opts->verbose;
	}
else
	{
	my $host = $plugin->opts->host;
	my $community = $plugin->opts->community;
	my $port = $plugin->opts->port;

	my $oid = $lsiOIDs{$what} . $number; 
	if (!defined ($oid))
		{ $plugin->nagios_die (message => "Don't know how to check '$what'"); }

	my ($session, $error) = Net::SNMP->session(
		-hostname  => $host,
		-community => $community,
		-port      => $port
		);
	if (!defined($session))
		{ $plugin->nagios_die (message => "snmpError, '$error'"); }

	my $snmpResult = $session->get_request(
		-varbindlist => [$oid]
		);
	if (!defined ($snmpResult))
		{ $plugin->nagios_die (message => "SNMP ERROR, '" . $session->error . "'"); }
		$result = $snmpResult->{$oid};
		
	print "$what($oid)  on $host is  $result\n " if $plugin->opts->verbose;
	$session->close;
	}

	$result_codes_path{$what}->();
	
	sub raid_result {
		if ($result == "0 but true")
			{$result_code = 0, $status = "is OK";
			}
		elsif ($result == 1)	
			{$result_code = 1, $status = "is Verifying";
			}
		elsif ($result == 2)	
			{$result_code = 1, $status = "is Initializing";
			}
		elsif ($result == 3)	
			{$result_code = 2, $status = "is Degraded";
			}
		elsif ($result == 4)	
			{$result_code = 1, $status = "is Rebuilding";
			}
		elsif ($result == 5)	
			{$result_code = 1, $status = "is Recovering";
			}
		elsif ($result == 6)	
			{$result_code = 1, $status = "is Migrating";
			}
		elsif ($result == 7)	
			{$result_code = 2, $status = "is Inoperable";
			}
		else
			{$result_code = 3, $status = "Status is Unknown";
			}
	}
	
	sub disk_result {
		if ($result == "0 but true")
			{$result_code = 2, $status = "is Offline";
			}
		elsif ($result == 1)	
			{$result_code = 2, $status = "is Offline JBOD";
			}
		elsif ($result == 217)	
			{$result_code = 1, $status = "is Unconverted DCB";
			}
		elsif ($result == 219)	
			{$result_code = 2, $status = "is Unsupported DCB";
			}
		elsif ($result == 221)	
			{$result_code = 1, $status = "DCB Data Check";
			}
		elsif ($result == 223)	
			{$result_code = 1, $status = "is DCB Orphan";
			}
		elsif ($result == 236)	
			{$result_code = 2, $status = "DCB Read Failure";
			}
		elsif ($result == 238)	
			{$result_code = 1, $status = "DCB Read Timeout";
			}
		elsif ($result == 254)	
			{$result_code = 2, $status = "is Unsupported";
			}	
		elsif ($result == 255)	
			{$result_code = 0, $status = "is OK";
			}	
		else
			{$result_code = 3, $status = "Status is Unknown";
			}
	}
	
	sub out_io_result {
			$result_code = 0
	}
	
	sub io_p_sec_result {
			$result_code = 0
	}
	
##############################################################################
# check the result against the defined warning and critical thresholds,
# output the result and exit
$plugin->nagios_exit(
	 return_code => $result_code,
	 message => " $what"."_"."$number $status return code is $result_code Result code is $result"
);	