#!/bin/bash
# APC MasterSwitch VM PDU controller by some cluster people, partially cleaned up by robbat2
APCIP=$1
COMMUNITY_WRITE="RW-PASSWORD"
COMMUNITY_READ="RO-PASSWORD"
SNMP_COMMON_OPTS="-m ALL -v 1"
SNMPGET="snmpget ${SNMP_COMMON_OPTS} -c ${COMMUNITY_READ}"
SNMPSET="snmpset ${SNMP_COMMON_OPTS} -c ${COMMUNITY_WRITE}"

usage () {
	echo "Usage: apcVM {apc##} {on|off} {pdu} {outlet} <other outlets>"
	echo "Usage: apcVM {apc##} {allon|alloff|allreboot} {pdu} <other pdus>"
	echo "Usage: apcVM {apc##} {setpduname} {pdu} {name}"
	echo "Usage: apcVM {apc##} {setoutletname} {pdu} {outlet} {name}"
	echo "Usage: apcVM {apc##} status"
}

if [ -z $1 ] ; then
	usage
	exit 1
fi

/bin/ping -c 1 $APCIP -q 2>&1 &>/dev/null
if ! [ $? -eq 0 ]; then
	echo "Cannot reach MasterSwitch VM controller at $APCIP (ping)"
	usage
	exit 1
else
	echo "NUM_PDUS=${SNMPGET} ${APCIP} enterprises.apc.products.hardware.masterswitchVM.sPDUMasterStatusVM.sPDUMasterStatusVMTableSize.0 2>/dev/null | gawk -F ': ' '{ print $2 }'" 
	NUM_PDUS=`${SNMPGET} ${APCIP} enterprises.apc.products.hardware.masterswitchVM.sPDUMasterStatusVM.sPDUMasterStatusVMTableSize.0 2>/dev/null | gawk -F ': ' '{ print $2 }' `
	# Querying any host other than a VM unit will fail
	if [ -z $NUM_PDUS ]; then
		echo "Cannot reach MasterSwitch VM controller at $APCIP (snmp)"
		usage
		exit 1
	fi
fi

# Don't do a status query immediately after an outlet state update.
# This routine forces us to wait for a bit.
pause () {
	sleep 2
}

arg_check () {
	if [ -z $1 ]; then
		usage
		exit $POS_PARAMS_MISSING
	fi
}

run_status() {
	#color fgreen
	echo '================ APC MASTERSWITCH VM STATUS =============='
	echo $1

	COUNT=1

	while [ "$COUNT" -le "$NUM_PDUS" ]
		do
		echo "=========="
		echo -n "PDU $COUNT"
		PDU_NAME=`${SNMPGET} ${APCIP} enterprises.apc.products.hardware.masterswitchVM.sPDUMasterStatusVM.sPDUMasterStatusVMTable.sPDUMasterStatusVMEntry.sPDUMasterStatusVMName.$COUNT | gawk -F ': ' '{ print $2 }'`
		echo " ("$PDU_NAME")"

		CURRENT_LOAD=`${SNMPGET} ${APCIP} enterprises.apc.products.hardware.masterswitchVM.sPDUMasterStatusVM.sPDUMasterStatusVMTable.sPDUMasterStatusVMEntry.sPDUMasterStatusVMCurrentLoad.$COUNT | gawk -F ': ' '{ print $2 }' `
		MAX_LOAD=`${SNMPGET} ${APCIP} enterprises.apc.products.hardware.masterswitchVM.sPDUMasterStatusVM.sPDUMasterStatusVMTable.sPDUMasterStatusVMEntry.sPDUMasterStatusVMMaxLoad.$COUNT | gawk -F ': ' '{ print $2 }' `

		let current=$MAX_LOAD*$CURRENT_LOAD/100
		echo "Current Load = "$current" of "$MAX_LOAD" amps ("$CURRENT_LOAD"%)"

		NUM_OUTLETS=`${SNMPGET} ${APCIP} enterprises.apc.products.hardware.masterswitchVM.sPDUMasterStatusVM.sPDUMasterStatusVMTable.sPDUMasterStatusVMEntry.sPDUMasterStatusVMOutletCount.$COUNT | gawk -F ': ' '{ print $2 }' ` 

		echo "$NUM_OUTLETS total outlets."

		# Outlet status
		echo "Outlets:"
		echo "#: Name:      Status:"

		for ((outlet=1; outlet <= NUM_OUTLETS; outlet++)) ; do
			outlet_status=`${SNMPGET} ${APCIP} enterprises.apc.products.hardware.masterswitchVM.sPDUOutletStatusVM.sPDUOutletStatusVMTable.sPDUOutletStatusVMEntry.sPDUOutletStatusVMOutletState.$COUNT.1.$outlet | gawk -F ': ' '{ print $2 }' | sed 's/outletStatusVM\(.*\)(.*/\1/' `
			outlet_name=`${SNMPGET} ${APCIP} enterprises.apc.products.hardware.masterswitchVM.sPDUOutletStatusVM.sPDUOutletStatusVMTable.sPDUOutletStatusVMEntry.sPDUOutletStatusVMOutletName.$COUNT.1.$outlet | gawk -F ': ' '{ print $2 }' | sed 's/"//g' `
			#echo -e "\tNumber: $outlet"
			#echo -e "\tName:   $outlet_name"
			#echo -e "\tStatus: $outlet_status"
			printf "%1d  %-10s %4.4s\n" $outlet "$outlet_name" "$outlet_status"
			done
			COUNT=`expr $COUNT + 1`
		done

		#color reset
}

case "$2" in
 on)
	arg_check $3
	pdu=$3
	arg_check $4
	#color fblue bold
	until [ -z $4 ]
	do
		${SNMPSET} ${APCIP} enterprises.apc.products.hardware.masterswitchVM.sPDUOutletControlVM.sPDUOutletControlVMTable.sPDUOutletControlVMEntry.sPDUOutletControlVMOutletCommand.$pdu.1.$4 i 1 >/dev/null || echo ERROR\!\!\!\!
		echo Outlet $4 on PDU $pdu turned on.
		shift
	done
	#color reset
	pause
        ;;

 allon)
	arg_check $3
	#color fblue bold
	until [ -z $3 ]
	do
		${SNMPSET} ${APCIP} enterprises.apc.products.hardware.masterswitchVM.sPDUMasterControlVM.sPDUMasterControlVMTable.sPDUMasterControlVMEntry.sPDUMasterControlVMCommand.$3 i 2 >/dev/null || echo ERROR\!\!\!\!
		echo All outlets on PDU $3 turned on.
		shift
	done
	#color reset
	pause
        ;;

 off)
	arg_check $3
	pdu=$3
	arg_check $4
	#color fred bold
	until [ -z $4 ]
	do
		${SNMPSET} ${APCIP} enterprises.apc.products.hardware.masterswitchVM.sPDUOutletControlVM.sPDUOutletControlVMTable.sPDUOutletControlVMEntry.sPDUOutletControlVMOutletCommand.$pdu.1.$4 i 2 >/dev/null || echo ERROR\!\!\!\!
		echo Outlet $4 on PDU $pdu turned off.
		shift
	done
	#color reset
	pause
        ;;
 reboot)
	arg_check $3
	pdu=$3
	arg_check $4
	#color forange bold
	until [ -z $4 ]
	do
		${SNMPSET} ${APCIP} enterprises.apc.products.hardware.masterswitchVM.sPDUOutletControlVM.sPDUOutletControlVMTable.sPDUOutletControlVMEntry.sPDUOutletControlVMOutletCommand.$pdu.1.$4 i 3 >/dev/null || echo ERROR\!\!\!\!
		echo Outlet $4 on PDU $pdu is being rebooted.
		shift
	done
	#color reset
	pause
        ;;

 alloff)
	arg_check $3
	#color fred bold
	until [ -z $3 ]
	do
		${SNMPSET} ${APCIP} enterprises.apc.products.hardware.masterswitchVM.sPDUMasterControlVM.sPDUMasterControlVMTable.sPDUMasterControlVMEntry.sPDUMasterControlVMCommand.$3 i 3 >/dev/null || echo ERROR\!\!\!\!
		echo All outlets on PDU $3 turned off.
		shift
	done
	#color reset
	pause
        ;;

 allreboot)
	arg_check $3
	#color forange bold
	until [ -z $3 ]
	do
		${SNMPSET} ${APCIP} enterprises.apc.products.hardware.masterswitchVM.sPDUMasterControlVM.sPDUMasterControlVMTable.sPDUMasterControlVMEntry.sPDUMasterControlVMCommand.$3 i 4 >/dev/null || echo ERROR\!\!\!\!
		echo All outlets on PDU $3 are now rebooting.
		shift
	done
	#color reset
	pause
        ;;

 setpduname)
	arg_check $3
	arg_check $4
	${SNMPSET} ${APCIP} enterprises.apc.products.hardware.masterswitchVM.sPDUMasterConfigVM.sPDUMasterConfigVMTable.sPDUMasterConfigVMEntry.sPDUMasterConfigVMName.$3 s $4 >/dev/null || echo ERROR\!\!\!\!
	#color fblue bold
	echo "PDU "$3"'s name changed to "$4"."
	#color reset
#	pause
	exit
	;;

 setoutletname)
	arg_check $3
	arg_check $4
	arg_check $5
	${SNMPSET} ${APCIP} enterprises.apc.products.hardware.masterswitchVM.sPDUOutletConfigVM.sPDUOutletConfigVMTable.sPDUOutletConfigVMEntry.sPDUOutletConfigVMOutletName.$3.1.$4 s $5 >/dev/null || echo ERROR\!\!\!\!
	#color fblue bold
	echo "Outlet "$4"'s name on PDU "$3" changed to "$5"."
	#color reset
#	pause
	exit
	;;

 status)
 	run_status $1
	;;
 *)
	usage
        exit 1
        ;;
esac

