#!/bin/bash
#########################################################
#							#
#	HP/Compaq Insight Management Log Checker	#
#							#
# check_insight_log					#
# 	Version 3.14 (June 9th, 2016)			#
#							#
# Authored by Jason Leonard				#
# 	E-mail: jason_leonard@yahoo.com			#
#							#
# Version History					#	
#	3.14 (6/9/2016)	Rewrote for SNMPv3	#
#	3.0 (10/7/2011)	Made code compatible w/ Ubuntu	#
#	2.2 (10/25/10)	Cleaned up redundant code	#
#	2.11 (10/8/10)	Fixed "last log entry" text	#
#	2.1 (9/14/09)	Fixed exit status codes		#
#	2.0 (04/01/09)	Initial release			#
#							#
# Overview						#
# ----------------------------------------------------- #
# 	This script is a modification of Frank 		#
# Baschin's script for checking Insight Logs.		#
# I personally felt the behaviour of the original 	#
# plugin was not what I expected. It could only return  #
# a condition based on whether or not the logs had been #
# cleared. Even if all entries were okay, it could 	#
# still return critical. I don't always like to clear 	#
# logs after fixing something. Sometimes I keep them 	#
# around as history of what's gone wrong with the 	#
# server. I know that Insight logs can be saved, but I 	#
# thought this plugin should be able to handle any type	#
# of admin's behaviour (mine especially!) - lazy or 	#
# active :)   (I've come to discover not all admins	#
# tend to their Insight Logs!)				#
#							#
# 	Basically, what has changed is the script only 	#
# reports error if there is an entry in the log that is #
# CRITICAL and not has been repaired. The state is only #
# considered WARNING if the logs have record of a 	#
# system warning, but no errors. If everything		#		
# is cleared, or marked as repaired - then the plugin 	#
# returns OK. This way, the only thing an admin needs 	#
# to do on their system is fix errors when they occur,	#
# and mark them as repaired in Insight Log viewer. The	#
# plugin does let you know how many entries you have,	#
# and encourages you to clear the logs - but does not	#
# mandate it.						#
#							#
#	Also, I may have tried to make the code easier 	#
# to read and follow - just another one those things I 	#
# am obsessed with doing anytime I touch code!!! 	#
#							#
# This plugin is distributed under the GNU GPL license.	#
# You may re-destribute only according to the terms of 	#
# the GNU GPL v2.					#
#							#
#########################################################

#########################################################
##		     GLOBAL VARIABLES 		       ##
#########################################################
APPNAME=$(basename $0)
AUTHOR="Jason Leonard"
VERSION="3.14"

# Default settings for connection
COMMUNITY='public'
HOST_NAME='localhost'
SNMPVERSION='2c'

# State Variables
STATE_OK=0
STATE_WARN=1
STATE_CRIT=2
STATE_UNK=3

# Default Outputs
STATE=$STATE_OK
STATE_STRING=""
PERFDATA=""

#########################################################
#		Universal SNMP OIDS 			#
#########################################################
OID_cpqHeEventLogSupported="1.3.6.1.4.1.232.6.2.11.1"
OID_cpqHeEventLogEntryNumber="1.3.6.1.4.1.232.6.2.11.3.1.1"
OID_cpqHeEventLogErrorDesc="1.3.6.1.4.1.232.6.2.11.3.1.8"
OID_cpqHeEventLogEntrySeverity="1.3.6.1.4.1.232.6.2.11.3.1.2"

#########################################################
#			print_version			#
#########################################################
print_version() {

    echo "$APPNAME $VERSION"
	echo "$AUTHOR"
	echo ''
	
}

#########################################################
#			print_usage			#
#########################################################
print_usage(){

	echo ''
	echo 'Usage for SNMP v1/2c:'
	echo "	$APPNAME -H <host/IP> [-C <SNMP community>]"	
	echo ''
	echo 'Usage for SNMP v3:'
	echo "	$APPNAME -H <host/IP> -u <user> -x <protocol> -X <password> -a <protocol> -A <password> -l <security mode>"
	echo ''
	
}

#########################################################
##		    print_help Function		       ##
#########################################################
# Prints out user help and gives examples of proper	#
# plugin usage						#
#########################################################
function print_help () {

	print_version
	echo 'Description:'
	echo "$APPNAME is a Nagios plugin to check the status of various components of Dell PowerConnect switches."
	echo ''
	echo 'This plugin is not developped by the Nagios Plugin group.'
	echo 'Please do not e-mail them for support on this plugin.'
	echo ''
	echo 'For contact info, please read the plugin script file.'
	print_usage
	echo "---------------------------------------------------------------------"
	echo ''
	echo 'OPTIONS:'
	echo '	-H|--host'
	echo '		Host name or IP address to check. Default is: localhost. REQUIRED OPTION'
	echo '	-v|--snmpversion { 1 | 2c | 3 }'
	echo "		Specifies the SNMP version to use. Default is '2c'. REQUIRED OPTION"
	echo '	-C|--community'
	echo "		SNMP v2 community string with Read access. Default is 'public'. REQUIRED OPTION"
	echo '	-u|--user'
	echo '		SNMP v3 username'
	echo '	-l|--privlevel { noAuthNoPriv | authNoPriv | authPriv }'
	echo '		SNMP v3 privilege level'
	echo '	-x|--privprotocol { DES | AES }'
	echo '		SNMP v3 privacy protocol'
	echo '	-X|--privpassword'
	echo '		SNMP v3 privacy password'
	echo '	-a|--authprotocol { MD5 | SHA }'	
	echo '		SNMP v3 authentication protocol'
	echo '	-A|--authpassword'
	echo '		SNMP v3 authentication password'
	echo '	-h|--help'
	echo '		Show this help screen'
	echo '	-V|--version'
	echo '		Show the current version of the plugin'
	echo ''
	echo 'Example:'
	echo "    $APPNAME -H 10.0.1.10 -C public"
	echo ''
	echo '---------------------------------------------------------------------'

	exit $STATE_UNK
}

###########################################################
##		 check_insight-log function     	 ##
###########################################################
function check_insight-log()
{
	local LOG_STATE=$STATE_OK
	local ARRAY_STATUS=""
	local LAST_LOG_INDEX=0
	local LAST_CRITICAL_INDEX=0
	local LAST_WARNING_INDEX=0
	local LAST_CRITICAL_MESSAGE=""
	local LAST_WARNING_MESSAGE=""
	local LAST_LOG_MESSAGE=""
	
	#Check if log entries are present or have been cleared
	local LOG_ARRAY=`walk_snmp $OID_cpqHeEventLogErrorDesc true`
	check_snmp_error "$?" "$LOG_ARRAY"
	
	local LOG_ARRAY_SIZE=$(echo "$LOG_ARRAY" | wc -l)

	if [ $LOG_ARRAY_SIZE -eq 1 ]; then
	# If we only have 1 entry, that should mean the logs have been cleared - let's not do anything more!
		STATE_STRING="HP Insight Manager Log OK. All entries have been cleared."
		return $LOG_STATE
	fi

	# Check all log entries
	ARRAY_STATUS=`walk_snmp $OID_cpqHeEventLogEntrySeverity false`
	check_snmp_error "$?" "$ARRAY_STATUS"
	
	# Determine the index for the latest entry of each type
	LAST_LOG_INDEX=`walk_snmp $OID_cpqHeEventLogEntryNumber true | tail -n 1`
	check_snmp_error "$?" "$LAST_LOG_INDEX"
	
	LAST_CRITICAL_INDEX=$(echo "$ARRAY_STATUS" | grep "INTEGER: 15" | awk -F. '{print $9}' | awk -F= '{print $1}' | tail -n 1)
	LAST_WARNING_INDEX=$(echo "$ARRAY_STATUS" | grep "INTEGER: 9" | awk -F. '{print $9}' | awk -F= '{print $1}' | tail -n 1)
	
	if [[ $LAST_CRITICAL_INDEX -gt $STATE_OK ]]; then
	# We have a CRITICAL - we want our status to reflect that
		LOG_STATE=$STATE_CRIT

		# Get description and status of the latest warning
		LAST_CRITICAL_MESSAGE=`walk_snmp $OID_cpqHeEventLogErrorDesc.$LAST_CRITICAL_INDEX true`
		check_snmp_error "$?" "$LAST_CRITICAL_MESSAGE"
	
	else
		# Nothing was critical - let's check and see if we have any WARNINGS
		if [[ $LAST_WARNING_INDEX -gt $STATE_OK ]]; then
			LOG_STATE=$STATE_WARN
			# Get description and status of the latest warning
			LAST_WARNING_MESSAGE=`walk_snmp $OID_cpqHeEventLogErrorDesc.$LAST_WARNING_INDEX true`
			check_snmp_error "$?" "$LAST_WARNING_MESSAGE"
		fi
	fi
	
	LAST_LOG_MESSAGE=`walk_snmp $OID_cpqHeEventLogErrorDesc.$LAST_LOG_INDEX true`
	check_snmp_error "$?" "$LAST_LOG_MESSAGE"
	
	# Repress any POST Error for Drive Arrays
	if [ $(echo $LAST_LOG_MESSAGE | grep -c "POST Error: 1785-Drive Array not Configured") -gt 0 ];	then
		LOG_STATE=$STATE_OK
	fi

	case "$LOG_STATE" in
		0)
		STATE_STRING="HP Insight Management Logs OK. But log has $LOG_ARRAY_SIZE uncleared entries. Last entry = \"$LAST_LOG_MESSAGE\""
		;;
		1)
		STATE_STRING="WARNING: Insight Management Logs has a warning message - $LAST_WARNING_MESSAGE. Please correct the failure, then mark the entry as Repaired or clear all Insight Manager Log entries."
		;;
		2)
		STATE_STRING="CRITICAL: Insight Management Logs has a critical error message - $LAST_CRITICAL_MESSAGE. Please correct the failure, then mark the entry as Repaired or clear all Insight Manager Log entries."
		;;
	esac
	
	return $LOG_STATE
}

#########################################################
#		Subroutine: walk_snmp			#
#########################################################
walk_snmp(){

	if [ $2 = true ]; then
		OUTPUT_OPTIONS="-Oavq"
	else
		OUTPUT_OPTIONS="-Oa"		 
	fi
		
	if [[ $SNMPVERSION = 3 ]]; then
		RESULT_TEXT=`snmpwalk -v $SNMPVERSION $OUTPUT_OPTIONS -u $SNMPUSER -l $PRIVILEGELEVEL -x $PRIVACYPROTOCOL -X $PRIVACYPASSWORD -a $AUTHPROTOCOL -A $AUTHPASSWORD $HOST_NAME $1`
		RESULT_CODE=$?
	else
		# Check if community was also set
		RESULT_TEXT=`snmpwalk -v $SNMPVERSION $OUTPUT_OPTIONS -c $COMMUNITY $HOST_NAME $1`
		RESULT_CODE=$?
	fi

	if [[ $RESULT_CODE -ne 0 ]]; then
		echo "Plugin $APPNAME failure - snmpwalk command error."
		echo "$RESULT_TEXT"
		exit $STATE_UNK
	fi

	if [ $2 = true ]; then
		echo "$RESULT_TEXT" | sed -e 's/^[[:space:]]*//' | tr -d "\""
	else
		echo "$RESULT_TEXT" 
	fi
	
}

#########################################################
#		Subroutine: check_snmp_error			#
#########################################################
# Tests errors returned by function operations		#
#########################################################
check_snmp_error(){

	 if [[ $1 -ne 0 ]]; then
		echo $2
		exit $STATE_UNK
	fi
	
}

#########################################################
##			  MAIN CODE		       ##
#########################################################

# Check that all required binaries for the script are available
# 	EXIT with an UNKNOWN status if not
binaries="snmpwalk awk grep tail wc"

for required_binary in $binaries
do
	which $required_binary > /dev/null
	if [ "$?" != '0' ];then
		echo "UNKNOWN: $APPNAME: No usable '$required_binary' binary in '$PATH'"
		exit $STATE_UNK
	fi
done

# Check to see if any parameters were passed
if [[ $# -eq 0 ]]; then
	print_usage
	exit $STATE_UNK
fi

# Parse our options as passed, and make sure things are peachy
while test -n "$1"; do

	case "$1" in
		--host|-H)
			HOST_NAME=$2
			shift
			;;
		--comunity|-C)
			COMMUNITY=$2
			shift
			;;
		--snmpversion|-v)
			SNMPVERSION=$2
			shift
			;;
		--user|-u)
			SNMPUSER=$2
			shift
			;;			
		--privelegelevel|-l)
			PRIVILEGELEVEL=$2
			shift
			;;			
		--authprotocol|-a)
			AUTHPROTOCOL=$2
			shift
			;;			
		--authpassword|-A)
			AUTHPASSWORD=$2
			shift
			;;			
		--privacyprotocol|-x)
			PRIVACYPROTOCOL=$2
			shift
			;;			
		--privacypassword|-X)
			PRIVACYPASSWORD=$2
			shift
			;;			
		--help|-h)
			print_help
			;;
		--version|-V)
			print_version
			exit $STATE
			;;			
		  *)
			echo "Unknown argument: $1"
			print_usage
			exit $STATE_UNK
			;;

	esac
	
	shift
	
done
		
LOG_SUPPORTED=`walk_snmp $OID_cpqHeEventLogSupported true`
check_snmp_error "$?" "$LOG_SUPPORTED"

# Check if Insight Logs are supported to begin with
if [ $LOG_SUPPORTED -lt 3 ]; then
	# Insight Logs are not supported, usually meaning it isn't installed
	STATE_STRING="CRITICAL! HP Insight Management Log not supported or not installed for this system."
	STATE=$STATE_CRIT
else
	# Everything is supported, so let's check the logs
	check_insight-log
	STATE=$?
fi

echo "$STATE_STRING"

exit $STATE
