#!/bin/bash
# $Copyright$
# Copyright (C) Fujitsu Technology Solutions 2010
# All rights reserved
#
#
# Copyright (C) Fujitsu Technology Solutions 2010
# All Rights Reserved
#

# Zweck:
# 	Diese Prozedur 
# 		luft im Kontext von Linux ServerView Agenten auf einem Blade eines BladeServers und
#		prft, ob alle Blades auer dem eigenen im Status down sind 
# Ablauf:
#	1. Einlesen der Optionen
#      (s.u.)
#	2. Bestimmen der IP Adresse des MMB (falls nicht explizit angegeben durch -a)
#      sc2UnitNodeAddress der Instanz mit der Klasse "management-blade" am lokalen Agenten
#	3. Abfrage der ServerBlade PowerStati (s31SrvCtrlPower) am MMB
#	   ist die Anzahl der Instanzen im Status != down gleich 1, wird angenommen, dass alle
#      Blades mit Ausnahme des eigenen im Status "down" sind
#	3a.Wird mit -l eine kommagetrennte Liste von Slotnumber angeben, dann wird geprft, 
#      ob alle Server der Liste im Status down sind 
# Vorraussetzungen
#	1. snmpget / snmpwalk sind verfgbar und im Pfad
#	2. MMB ist ber LAN erreichbar
#   3. SNMP ist lokal und zum MMB freigeschaltet (see iptables)
#   4. die community strings des lokalen Agenten und des MMB sind bekannt (default: public)  

# Options:
# 			-a <MMB_address>		default: request MMB_address via SNMP
#			-cm <MMB community>		default: public
#			-cl <local community>	default: public
#			-d <delay>				default: 3 seconds
#			-r <retries>			default: unendlich
#			-v 						[verbose]
#			-l <,listOfServers,>	default: empty
#			-w <n>					default: 1
#			-?						[usage]

# Return codes:
# 	0	alle Server mit Ausnahme des eigenen sind down
#	1	nicht alle Server sind down
#  	2   ERROR 
 
# Traces:
# 	1. Beginn, Ende und Fehler werden nach /var/log/messages geschrieben
#      Procedurname: srv_checkstatus  
#   2. mit -v werden verschieden Ausgaben auf stdout ausgegeben
#   3. mit -a kann die MMB IP Adresse explicit angegeben werden 
 
# set defaults
A=
D=3
R=60               # Timeout after 3 Min
CM=public
CL=public
L=
V=0
W=1
s31SrvCtrlPower=1.3.6.1.4.1.7244.1.1.1.4.1.1.1.5
S=3	# off
sc2UnitNodeClass=1.3.6.1.4.1.231.2.10.2.2.10.3.1.1.8
sc2UnitNodeAddress=1.3.6.1.4.1.231.2.10.2.2.10.3.1.1.4
 
# number of servers in status != down
Nup=0

#getOptions $*
getOptions() {

	while [ $# -gt 0 ]
	do
		case "$1" in
		-[?])	
			echo "Usage: $0 ..."
			exit 0
			;;
		-a)	
			A=$2; shift; shift
		;;
		-cm)	
			CM=$2; shift; shift
		;;
		-cl)	
			CL=$2; shift; shift
		;;
		-d)	
			D=$2; shift; shift
		;;
		-r)	
			R=$2; shift; shift
		;;
		-l)	
			L=`echo $2 | sed "s/,/ /g"`; shift; shift
		;;
		-v)	
			V=1; shift
		;;
		*)
			echo "Invalid argument [$1]; Usage: $0 ..."
			exit 0
		;;
		esac
	done
}
# getOptions $*

requestMMBIp () {

	addr=127.0.0.1
	#addr=172.17.52.166
	
	# find instance of class type 4=management-blade
	e1=`snmpwalk -v 1 -c $CL -Oen $addr $sc2UnitNodeClass |fgrep "INTEGER: 4"`
	[ $? -ne 0 ] && {
		echo "Error ... ... during snmp walk request: $addr, $sc2UnitNodeClass"
		logger -t srv_checkstatus "Error ... ... during snmp walk request: $addr, $sc2UnitNodeClass"
		return 2
	}
		# -> .1.3.6.1.4.1.231.2.10.2.2.10.3.1.1.8.1.2 = INTEGER: 4
	# extract OID
	e2=`echo $e1 | sed s/"= INTEGER.*"//`
		# -> .1.3.6.1.4.1.231.2.10.2.2.10.3.1.1.8.1.2
	# replace column 8 by 4 (sc2UnitNodeAddress)
	e3=`echo $e2 | sed s/231.2.10.2.2.10.3.1.1.8/231.2.10.2.2.10.3.1.1.4/`
	# -> .1.3.6.1.4.1.231.2.10.2.2.10.3.1.1.4.1.2
	# send get request
	rc=`snmpget -v 1 -c $CL -O qv $addr $e3`
	[ $? -ne 0 ] && {
		echo "Error ... ... during snmp get request $addr, $e3"
		logger -t srv_checkstatus "Error ... ... during snmp get request $addr, $e3"
		return 2
	}
	
	rc=${rc%%\"}; rc=${rc##\"}
    A=$rc
	return 0
}

requestStatus () {
	i=$R
	[ $V -eq 1 ] && echo "... start request with R= $R, and D= $D for A= '$A'"
	while [ $i -ne 0 ]
	do
		# return values only
		rc=`snmpwalk -v 1 -c $CM -O qve $A $s31SrvCtrlPower`
		[ $? -ne 0 ] && {
			echo "ERROR ...	... during snmp walk (all) request $A $s31SrvCtrlPOwer"
			logger -t srv_checkstatus "Error ... ... during snmp walk (all) request $A $s31SrvCtrlPower"
			return 2
		}
		Nup=0
		for x in $rc
		do
			[ $x -ne 3 ] && Nup=`expr $Nup + 1`
		done
		[ $V -eq 1 ] && echo "... ... Iteration: $i: Number of servers up: $Nup"
		[ $Nup -eq 0 ] && {
			echo "ERROR: ... ... internal error, unexpected all server down"
			logger -t srv_checkstatus "ERROR: ... ... internal error, unexpected all server down"
			return 2
		}
		[ $Nup -eq 1 ] && break
		i=`expr $i - 1`
		#let i=$i-1
		sleep $D
	done
	[ $V -eq 1 ] && echo "... ... current $Nup server not in status down"
	return 0
}
requestListStatus () {
	i=$R
	instance=""
	[ $V -eq 1 ] && echo "... start request with R= $R, and D= $D for A= '$A' and List '$L'"
	while [ $i -ne 0 ]
	do
		# returns oid value oid value ...
		rc=`snmpwalk -v 1 -c $CM -O enq $A $s31SrvCtrlPower`
		[ $? -ne 0 ] && {
			echo "ERROR ... ... during snmp walk (list) request $A, $s31SrvCtrlPower"
			logger -t srv_checkstatus "Error ... ... during snmp walk (list) request $A $s31SrvCtrlPower"
			return 2
		}
		Nup=0
		# writes result in array RC[instance] = value 
		for x in $rc
		do
			if [ $instance ]
			then
				RC[$instance]=$x
				instance=
			else
				instance=${x##.1.3.6.1.4.1.7244.1.1.1.4.1.1.1.5.}
			fi
		done
		# prfen, wieviel server der Liste noch nicht down sind
		for s in $L
		do
				[ ${RC[$s]} ] && [ ${RC[$s]} -ne 3 ] && Nup=`expr $Nup + 1`
		done
		[ $V -eq 1 ] && { echo "... ... Iteration: $i: Number of servers up: $Nup"
			for j in $L; do echo " ... ... $j: ${RC[$j]}"; done
			#for j in ${!RC[*]}; do echo " ... ... $j: ${RC[$j]}"; done
		}
		[ $Nup -eq 0 ] && break
		i=`expr $i - 1`
		#let i=$i-1
		sleep $D
	done
	[ $V -eq 1 ] && echo "... ... current $Nup server not in status down"
	return 0
}



# ---------------------------------------------------------------------------------
# doIt

# exit, if the appliance "svappliance" is missing
vmware-cmd -l|fgrep -i svappliance >/dev/null || exit 2

 # read options
getOptions $*
[ $V -eq 1 ] && echo "getOptions L=$L"
logger -t srv_checkstatus "start check with $R retries, serverlist='$L'"

# request MMB IP addr if required
[ $V -eq 1 ] && echo "get MMB IP address"
[ $A ] || {
	requestMMBIp || exit 2
	[ $A ] || {
		echo "error: can not find MMB Ip address"
		exit 2
	}
}
[ $V -eq 1 ] && echo "... MMB address: $A"
logger -t srv_checkstatus "MMB Address is $A"

# request status
[ $V -eq 1 ] && echo "get server status"
if [ -z "$L" ]
then
	# we check the guestinfo variable SVAppSDBlades
	sva=`vmware-cmd -l|fgrep svappliance` || exit 2
	L=`vmware-cmd $sva getguestinfo SVAppSDBlades 2>/dev/null`
	L=${L#*=}
	[ $V -eq 1 ] && echo "List of servers '$L'"
fi

[ -z "$L" ] && exit 0

# we have a list of server to check
requestListStatus || exit 2
[ $Nup -eq 0 ] && {
	[ $V -eq 1 ] && echo "... all server down"
	logger -t srv_checkstatus "finish check: all server down"
	exit 0
}

[ $V -eq 1 ] && echo "... $Nup server still up"
logger -t srv_checkstatus "finish check: $Nup server still up"

exit 1 




