#!/bin/bash
# Check stack state of Netgear switches with SNMP
# (count physical number of units in the stack, with 
# "ENTITY-MIB" (1.3.6.1.2.1.47.1.1.1.1) )
#
# (c)2015 Komori-Chambon
# Jeremie LEGRAND
#
# Return codes:
#	0	OK
#	1	WARNING
#	2	CRITICAL
#	3	UNKNOWN
#
# Version: 1
#    Initial release

# Default SNMP community
COM=public

# Default SNMP version
VERS=2c

# Default SNMP port
PORT=161

# Constants
RET_OK=0
RET_WARN=1
RET_CRIT=2
RET_UNKN=3

#------
# Usage
#------
usage() {
	echo "Usage:"
	echo "    $0 -H host -e <switches_count> [-c community] [-v version] "
	echo "        [-s 'any_snmp_args'] [-V] [--help]"
	echo ""
	echo "Options :"
	echo "    -h, --help          This help"
	echo "    -H, --host          Checked switch virtual IP"
	echo "    -c, --community     SNMP MIB (default = $COM)"
	echo "    -e, --expected      Expected switches count"
	echo "    -p, --port          SNMP port (default = $PORT)"
	echo "    -s, --snmp-args     Any SNMP args you d'like to add to snmpwalk command"
	echo "                          (credentials for SNMPv3, or whatever)"
	echo "    -v, --version       SNMP version (default = $VERS)"
	echo "    -V, --verbose       Verbose output, mainly for debugging"
	echo ""
	exit $RET_UNKN
}
RET_CODE=$RET_OK
VERBOSE=0
EXPECTED=
WILD_ARGS=
OPTS=$(getopt -o hH:c:e:p:s:v:V --long help,host:,community:,expected:,port:,snmp-args:,version:,verbose -n "$0" -- "$@")
[ $? -ne 0 ] && usage
eval set -- "$OPTS"
while [ $# -gt 0 ]; do
    case $1 in
        -h|--help)			usage;			shift ;;
		-H|--host)			ADR=$2;			shift 2 ;;
		-c|--community)		COM=$2;			shift 2 ;;
		-e|--expected)		EXPECTED=$2;	shift 2 ;;
		-p|--port)			PORT=$2;		shift 2 ;;
		-s|--snmp-args)		WILD_ARGS="$2";	shift 2	;;
		-v|--version)		VERS=$2;		shift 2 ;;
		-V|--verbose)		VERBOSE=1;		shift ;;
        --) shift; break ;;
        *)  echo "Unknown argument: $1"
			usage
            ;;
    esac
done

[ -z "$ADR" ] && echo "Unspecified host." && usage
[ -z "$EXPECTED" ] && echo "Unspecified expected number of switches." && usage
[ -z "$COM" ] && echo "Unspecified SNMP community." && usage
[ -z "$VERS" ] && echo "Unspecified SNMP version." && usage
[ -z "$PORT" ] && echo "Unspecified connection port." && usage

# List all physical elements
resu=`snmpwalk -Oqv -v$VERS -c$COM $ADR:$PORT $WILD_ARGS 1.3.6.1.2.1.47.1.1.1.1.7 2>&1`
resu_code=$?

[ $VERBOSE -eq 1 ] && echo -e "$resu"

# SNMP error?
if [ $resu_code -ne 0 -o -n "`echo "$resu" | grep snmpwalk:`" ]; then
	echo "UNKNOWN - SNMP error (ret code $resu_code): $resu"
	exit $RET_UNKN
fi

# Limit results to "Unit" lines
lst=`echo "$resu" | grep -i Unit | sed -e s'~^\"\(.*\)\"$~\1~'`
if [ -z "`echo -n "$lst" | grep -i unit`" ]; then
	NB_OK=0
else
	NB_OK=`echo -e "$lst" | wc -l`
fi

# Got everybody?
if [ "$NB_OK" = "$EXPECTED" ]; then
	echo "OK - Stack full ($EXPECTED switches)"

# Missing somebody?
else
	FOUND_LIST=`echo "$lst" | tr "\n" , | sed -e s'~,~, ~g' | sed -e s'~, $~~'`
	if [ $NB_OK -eq 0 ]; then
		echo "CRITICAL - No active switch... is it really the good IP address?"
		RET_CODE=$RET_CRIT
	elif [ $NB_OK -eq 1 ]; then
		echo "WARNING - Only 1 active switch on $EXPECTED ($FOUND_LIST)"
		RET_CODE=$RET_WARN
	else
		echo "WARNING - $NB_OK actives switches on $EXPECTED ($FOUND_LIST)"
		RET_CODE=$RET_WARN
	fi
	exit $RET_CODE
fi
