#!/usr/bin/perl
use strict;
use warnings;
use Getopt::Long qw(:config no_ignore_case bundling);
#use Pod::Usage;
#use IO::Socket::INET;

use lib "/usr/lib/nagios/plugins";
#use POSIX ();
#use utils qw(%ERRORS);
use vars qw(%ERRORS);

my ($nodename, $username, $password, $option, $warn, $crit, $release, $version, $machine, $opt_V, $opt_h);

# -- hard coded error values to avoid path problems with utils.pm
%ERRORS = (
   'OK'       => 0,
   'WARNING'  => 1,
   'ERROR'    => 2,
   'CRITICAL' => 2,
   'UNKNOWN'  => 3,
);



my $usage = "
Usage: $0 [-H  host_addr] -o ipmi_option [-U ipmi_user] [-P ipmi_pass] [-w warning_level] [-c critical_level] \n
Example usage: check_neteye_status -H 192.168.0.1 -o FAN1 -U ADMIN -P ADMIN -w 4000 -c 3000 \n
Valid ipmi_options: \n
 - FAN1		-> Test CPU fan speed (warning and critical arise if value is lower) 
 - CPU		-> Test CPU temperature (warning and criticals arise if value is higer)
 - System	-> Test System temperature (warning and criticals arise if value is higer) 
 - Battery	-> Test Battery voltage (warning and criticals arise if value is lower)
 - CPU Core	-> Measure CPU core voltage (warning and criticals arise if value is lower) 
 - DIMM		-> Measure DIMMs voltage (warning and criticals arise if value is lower)
 - 3.3V		-> Measure 3.3V voltage (warning and criticals arise if value is lower) 
 - 5V		-> Measure 5V voltage (warning and criticals arise if value is lower)
 - 12V		-> Measure 12V voltage (warning and criticals arise if value is lower)

Connects to a NetEye IPMI and parses the IPMI system status values.\n\n";

GetOptions
        ("V"   => \$opt_V, "version"    => \$opt_V,
         "h"   => \$opt_h, "help"       => \$opt_h,
         "w=s" => \$warn, "warning=s"  => \$warn,
         "c=s" => \$crit, "critical=s" => \$crit,
         "H=s" => \$nodename, "hostname=s" => \$nodename,
         "U=s" => \$username, "username=s" => \$username,
         "P=s" => \$password, "password=s" => \$password,
	 "o=s" => \$option);

if (!$username){
	$username = "ADMIN";
}
if (!$password){
	$password = "ADMIN";
}
if (!$warn){
	$warn = 0;
}
if (!$crit){
	$crit = 0;
}

if (!$option) {
	$option="System";
}

my $result;

# Gets output of ipmi command, this is funny with IPMI v2, we *sometimes* get an Authentication type error.
if ((!$nodename) ||($nodename eq "")){
	$nodename="IPMI";
	$result = `/usr/bin/sudo /usr/bin/ipmitool sdr | grep -m1 $option | grep -v "Authentication"`;
} else {
	$result = `/usr/bin/ipmitool -I lan -H $nodename -U $username -P $password sdr | grep -m1 $option | grep -v "Authentication"`;
}

if ($result) {
my $status_text = "";
my $err_lvl = 0;
my $disabled = 0;
my $status;
my $perfdata = "| ";

#Checks fan speed. Warn and Critical alerts if RPMs are below value.
if (($option eq "FAN1")|| ($option eq "FAN2")||($option eq "FAN3")||($option eq "FAN4")){
	foreach my $line (split /\n/s, $result){

	        if (my @fields = split(/\|\s/,$line)){

                	#Removes signes at the end of string/array if known in INPUT_RECORD_SEPARATOR
	                #array index 4 is the fan speed
       		        chomp($status = $fields[1]);
	                my @fan_label = split( /\s/s, $fields[0]); #Array expected to contain one element

	                #Get value of fan speed
	                if ($status =~ m/^(\d*)\sRPM/g){
                        	if ($1 < $crit ){
                                	$err_lvl=2;
				} elsif ($1 < $warn ){
					$err_lvl=1;
				}
				$status_text .= "$nodename $fan_label[0] speed: $1 RPM";			
				$perfdata .= "$fan_label[0]=$1;$warn;$crit;0;10000";
			} else {
				$status_text .= "$line";
				$err_lvl = 3;
			}
		}
	}
prepare_exit_statement($err_lvl, $status_text, $perfdata);
exit $ERRORS{'UNKNOWN'}


#Checks Voltages of battery, and system. Warn and Critical alerts if Volt are below value.
} elsif (($option eq "Battery")||($option eq "Core")||($option eq "DIMM")||($option eq "3.3V")||($option eq "5V") || ($option eq "12V")){
foreach my $line (split /\n/s, $result){
	if (my @fields = split(/\|\s/,$line)){

		#Removes signes at the end of string/array if known in INPUT_RECORD_SEPARATOR
		#array index 4 is the fan speed
		chomp($status = $fields[1]);
		my @fan_label = split( /\s/s, $fields[0]); #Array expected to contain one element

		#Get value of Battery Voltage
		if ($status =~ m/^(\d*).(\d*)\sVolts\s/g){
			if ($1 < $crit){
				$err_lvl=2;
			} elsif ($1 < $warn){
				$err_lvl=1;
			}
			$status_text .= "$nodename $fan_label[0] Voltage is $1.$2";
			$perfdata .= "$fan_label[0]=$1.$2;$warn;$crit;0;10";
		} else {
			$status_text .= "$line";
			$err_lvl=3;
		}
	}
}
prepare_exit_statement($err_lvl, $status_text, $perfdata);
exit $ERRORS{'UNKNOWN'}

#Checks Temperatures of CPU and system. Warn and Critical alerts if Volt above passed value.
} elsif (($option eq "CPU")|| ($option eq "System")){
foreach my $line (split /\n/s, $result){
	if (my @fields = split(/\|\s/,$line)){

		#Removes signes at the end of string/array if known in INPUT_RECORD_SEPARATOR
		#array index 4 is the fan speed
		chomp($status = $fields[1]);
		my @fan_label = split( /\s/s, $fields[0]); #Array expected to contain one element
		#Get value of cpu or system degrees
		if ($status =~ m/^(\d*)\sdegrees C/g){
			if ($1 > $crit ){
				$err_lvl=2;
			} elsif ( $1 > $warn ){
				$err_lvl=1;
			}
			$status_text .= "$nodename $fan_label[0] temperature: $1 degrees C";
			$perfdata .= "$fan_label[0]=$1;$warn;$crit;0;100";
		} else{
			$status_text .= "$line";
			$err_lvl=3;
		}
	}
}
prepare_exit_statement($err_lvl, $status_text, $perfdata);
exit $ERRORS{'UNKNOWN'}
} 

#no option argument matched!
print ("Error. There has been passed no valid option argument. \n");
print $usage;
exit $ERRORS{'UNKNOWN'};

} else {
#ipmitool call failed
print "Wrong parameters used! \n\n";
exit $ERRORS{'UNKNOWN'};
}


sub prepare_exit_statement {
	my ($err_lvl, $status_text, $perfdata) = @_;

	if ($err_lvl == 3) {
		print "UNKNOWN: $status_text.";
		exit $ERRORS{'UNKNOWN'};
	} elsif ($err_lvl > 1){
		#print "CRITICAL: $status_text\b, $disabled fan sensors disabled. $perfdata\n";
	        print "CRITICAL: $status_text. $perfdata\n";
	        exit $ERRORS{'CRITICAL'}
	} elsif ($err_lvl == 1) {
		#print "CRITICAL: $status_text\b, $disabled fan sensors disabled. $perfdata\n";
	        print "WARNING: $status_text. $perfdata\n";
	        exit $ERRORS{'WARNING'}
	} else {
	        print "OK: $status_text. $perfdata\n";
	        exit $ERRORS{'OK'}
	}
}
