#!/usr/bin/perl
# This plugin checks the status of Dell servers with IPMI activated
# By SirCharlo :)
# www.interwebplus.com/blog/

# Check for proper args....
if ($#ARGV <= 5){
	&print_help();
}

my %status = (	'UNKNOWN'	=> '-1',
				'OK'			 => '0',
				'WARNING'	=> '1',
				'CRITICAL' => '2' );
				
				
pars_args();

$currentStatus = `ipmi-sensors -h $ip -u $username -p $password -C -Q`;
chomp $currentStatus;
@statusList = split("\n", $currentStatus);

if ($mode =~/ps/) {	# Power supply redundancy
	$searchText = "PS Red";
} elsif ($mode =~/temp/) { # Ambient temperature
	$searchText = "Ambient";
	if (!$warn) {
		$warn = 30;
	}
	if (!$crit) {
		$crit = 40;
	}
	$performance = "yes";
} elsif ($mode =~/cmos/) { # CMOS battery
	$searchText = "CMOS";
} elsif ($mode =~/fan-speed/) { # Fan state
	$searchText = "Fan";
	if (!$warn) {
		$warn = 5000;
	}
	if (!$crit) {
		$crit = 6000;
	}
	$performance = "yes";
} elsif ($mode =~/fans/) { # Fan redundancy
	$searchText = "Fan R";
} else {
	&print_help();
}

if ($warn && $crit && $warn > $crit) {
	$crit = $warn * 1.2; # Try to correct human error
}

$i = 0;
foreach my $val (@statusList) {
	if ($val =~ /$searchText/i) {
		if ($mode =~/fan-speed/) { # Need to do some magic if we're looking at fan RPMs..
			if (index(uc $val, "REDUND") == -1) {
				@rpmCalculator = split(",", $val);
				# print $val."\n";
				@fanNumber[$i] = @rpmCalculator[1];
				@rpm[$i] = @rpmCalculator[3];
				@unit[$i] = @rpmCalculator[4];
				$i = $i + 1;
			}
			#print scalar(grep {defined $_} @rpm), "\n"; 
		} else {
			@resultArray = split(",", $val);
			$checkName = @resultArray[1];
			$checkStatus = @resultArray[5];
			$checkStatus =~ s/'//g; # Remove single quotes from result
			
			if (@resultArray[3] != "N/A") {
				$checkReturnValue = @resultArray[3];
				$checkReturnUnits = @resultArray[4];
			}
			$string = $checkName.": ";
			if ($checkReturnValue) {
				$string .= $checkReturnValue." ".$checkReturnUnits;
			} else {
				$string .= $checkStatus;
			}
		}
	}
}

if ($mode =~/fan-speed/) { # Need to do some magic if we're looking at fan RPMs..
	$string = "Fan Speeds: ";
	for ($count = 0; $count < scalar(grep {defined $_} @fanNumber); $count++ ) {
		@fanNumber[$count] =~s/ RPM//;
		if ($count > 0) {
			$string = $string." / "
		} 
		$string = $string.@fanNumber[$count]." - ".@rpm[$count].@unit[$count];
		if (@rpm[$count]>=$warn) {
			$warnToggle = 1;
		}
		if (@rpm[$count]>=$crit) {
			$critToggle = 1;
		}
	}
}


# Let's calculate if the result is OK, WARNING, or CRITICAL now..
my $string_errors="";

if (!$checkReturnValue) {
	if ($checkStatus eq "OK") {
		$unitstate = "OK";
	} elsif ($checkStatus =~/Fully/) {
		$unitstate = "OK";
	} elsif ($critToggle == 1) {
		$unitstate="CRITICAL";
	} elsif ($warnToggle == 1) {
		$unitstate="WARNING";	
	} else {
		$unitstate = "OK";
	}
	$state = $unitstate;
} elsif ($checkReturnValue) {
	my $unitstate="OK";
	if ($checkReturnValue >= $warn) {
		$unitstate="WARNING";	
	}
	if ($checkReturnValue >= $crit) {
		$unitstate="CRITICAL";
	}
	$state = $unitstate;
} 

if ($string) {
	$string = $state." - ".$string;

	my $perfstring="";
	if ( $performance eq "yes" ) {
		if ($mode =~/fan-speed/) { # Special perfdata if we're dealing with fans!
			$perfstring="| ";
			$count = 0;
			foreach my $perfValue (@fanNumber) {
				$perfstring=$perfstring."'".@fanNumber[$count]." ".@unit[$count]."'=".@rpm[$count].";".$warn.";".$crit.";0 ";
				$count = $count + 1;
			}
		} else {
			$perfstring="| $checkName=".$checkReturnValue;
			$perfstring.=";".$warn.";".$crit;
		}
	}
	$string = $string.$perfstring;	

	if($string =~/uknw/) {
		$state = "UNKNOWN";
	}
	if($string =~/WARNING/) {
		$state = "WARNING";
	}
	if($string =~/down/) {
		$state = "CRITICAL";
	}
	if($string =~ m/critical/i) {
		$state = "CRITICAL";
	}
	print $string."\n";
} elsif ($mode =~/fan[0-9]/) {
	print "WARNING: Specified fan does not seem to exist\n";
	$state = "WARNING";
} else {
	print "\nUnknown error\n";
	&print_help();
}

exit($status{$state});


sub pars_args
{
	while(@ARGV)
	{
		if($ARGV[0] =~/^-H/) 
		{
			$ip = $ARGV[1];
			shift @ARGV;
			shift @ARGV;
			next;
		}
		if($ARGV[0] =~/^-U/) 
		{
			$username = $ARGV[1];
			shift @ARGV;
			shift @ARGV;
			next;
		}
		if($ARGV[0] =~/^-P/) 
		{
			$password = $ARGV[1];
			shift @ARGV;
			shift @ARGV;
			next;
		}
		if($ARGV[0] =~/^-m|^--mode/) 
		{
			$mode = $ARGV[1];
			shift @ARGV;
			shift @ARGV;
			next;
		}
		if(index($ARGV[0], "-w") != -1) 
		{
			if(index($ARGV[1], "-") == -1) {
				$warn = $ARGV[1];
			}
			shift @ARGV;
			shift @ARGV;
			next;
		}
		if(index($ARGV[0], "-c") != -1) 
		{
			if(index($ARGV[1], "-") == -1) {
				$crit = $ARGV[1];
			}
			shift @ARGV;
			shift @ARGV;
			next;
		}
	}
	return ("yes"); 
} 

sub print_help() {
	print "\n";
	print "Usage: check_dell -H hostname -U username -P password -m mode [-w XX] [-c XX]\n\n";

	print "Options:\n\n";

	print " -H, --host hostname (or IP address)\n";
	print "	Check the specified Dell server.\n\n";
	
	print " -U, --username username\n";
	print "	Log in to IPMI using this username (usually the same as for the DRAC).\n\n";

	print " -P, --password password\n";
	print "	Log in to IPMI using this password (also usually the same as for the DRAC).\n\n";
	
	print " -m, --mode STRING\n";
	print "	What to check\n";
	print "	Valid values are:\n";
	print "		ps			Returns the state of the power supplies\n";
	print "		temp		Returns the ambient temperature\n";
	print "		cmos		Returns the state of the CMOS battery\n\n";
	print "		fan-speed	Returns the speed of all fans\n\n";
	print "		fans		Specifies if all fans are fully redundant\n\n";

	print " -w, --warn XX\n";
	print "	Nagios warning threshold\n";
	print "	RPM value for \"fan-speed\" mode\n";
	print "	Default: 5000RPM\n";
	print "	Degree value for \"temp\" mode\n";
	print "	Default: 30 degrees Celsius\n\n";
	
	print " -c, --crit XX\n";
	print "	Nagios warning threshold\n";
	print "	RPM value for \"fan-speed\" mode\n";
	print "	Default: 6000RPM\n";
	print "	Degree value for \"temp\" mode\n";
	print "	Default: 40 degrees Celsius\n\n";
	
	exit($status{"UNKNOWN"});
}