#!/bin/sh
#
# CheckService.sh
#
# Script to maintain SAP Cluster Services
#
# Written by Markus Guertler and Fabian Herschel (Novell Inc.)
# Last update: 09.09.2009
#
# Licence: GPL
#
#export EchoOrDo="echo"
export EchoOrDo=""

red="\033[31m"
norm="\033[m\017"
green="\033[32m"
yellow="\033[33m"
blue="\033[34m"


#
#  ClusterService --cmd RDN <resource-id>
#  ClusterService --cmd RUP <resource-id>
#  ClusterService --cmd RMI <resource-id> <node-name>
#  ClusterService --cmd RUM <resource-id>
#  ClusterService --cmd NSS <node-name>
#  ClusterService --cmd NSA <node-name>
#  ClusterService --cmd RSU <resource-id>
#  ClusterService --cmd RSM <resource-id>
#  ClusterService --cmd RCN <resource-id>
#  ClusterService --cmd RSF
#  ClusterService --cmd RSS
#  ClusterService --cmd RRF
#  ClusterService --cmd RCF
#  ClusterService --cmd CSS
#  ClusterService --cmd CSF
#  ClusterService --cmd CSH
#  ClusterService --cmd CSL
#
cmdline=0

while [ $# -gt 0 ]; do
	case "$1" in
		--help | -h | -? ) 
cat <<EOF
$0 [--help | --cmd command | command]
Commands are:
  ClusterService RDN | ResourceDown <resource-id>
  ClusterService RUP | ResourceUp   <resource-id>
  ClusterService RMI | ResourceMigrate <resource-id> <node-name>
  ClusterService RUM | ResourceUnmigrate <resource-id>
  ClusterService NSS | NodeSetStandby <node-name>
  ClusterService NSA | NodeSetActive <node-name>
  ClusterService RSU | ResourceSetUnmanaged <resource-id>
  ClusterService RSM | ResourceSetManaged <resource-id>
  ClusterService RCN | ResourceCleanup <resource-id>
  ClusterService RSF | ResourceShowFailcounts
  ClusterService RSS | ResourceShowScores
  ClusterService RRF | ResourceResetFailures
  ClusterService RCF | ResourceCleanFailures
  ClusterService CSS | ClusterShowStatus
  ClusterService CSF | ClusterShowFailures
  ClusterService CSH | ClusterShowHistory
  ClusterService CSL | ClusterShowLinks
EOF
			exit 0;
			;;
		--simul4test ) # must be used before --cmd
			export EchoOrDo="echo"
			;;
		--cmd ) # non interactive for batch mode
			cmdline=1 
			shift
			cmd="$1"; shift
			params="$*"
			;;
		* )
			cmdline=1
			cmd="$1"; shift
			params="$*"
			shift $#
			;;
	esac
	shift;
done

# Binaries and scripts
LISTFAILCOUNTS=/usr/sbin/list_failcounts
RESETFAILCOUNTS=/usr/sbin/reset_failcounts
CLUSTERSTATE=/usr/sbin/clusterstate
LINKSTATE=/usr/sbin/linkstate
CRMRESOURCE=/usr/sbin/crm_resource
CRMMON=/usr/sbin/crm_mon
CRMADMIN=/usr/sbin/crmadmin
CRMSTANDBY=/usr/sbin/crm_standby
CLSTATUS=/usr/bin/cl_status
SHOWSCORES=/usr/sbin/showscores

sure()
{
  test $cmdline -eq 1 && return 0
  echo " "
  echo -n "Are you sure (y/n)? "
  read really
  if [ "$really" = "y" ]
     then echo "Executing command..."
     else exit 1
  fi
}

presskey()
{
  test $cmdline -eq 1 && return 0
  echo " "
  echo -n "Command executed. Please press <enter>"
  read enter
}

start_resource()
{
  echo "-> Setting target role of resource $resource: target_role=\"started\""
  $EchoOrDo  $CRMRESOURCE -p "target_role" -v "started" -r "$resource" --meta -s "${resource}_meta_attrs" --meta
  return
}

stop_resource()
{
  echo "-> Setting target role of resource $resource: target_role=\"stopped\""
  $EchoOrDo  $CRMRESOURCE -p "target_role" -v "stopped" -r "$resource" --meta -s "${resource}_meta_attrs" --meta
  return
}

check_status_idle()
{
  dc=$($CRMADMIN -D | awk '{ print $4 }')
  status=$(crmadmin -S $dc -q 2>&1 |grep -v 'Status of crmd')
  if [ "$status" != "S_IDLE" ]
	then
		echo "Error: Please wait until the cluster transition status changes to S_IDLE!"
		presskey
  		return 1
	else
		return 0
	fi
}

cleanup_resource()
{
  echo "-> Deleting all status information from CIB for resource $resource on node $dest_node"
  $CRMRESOURCE -C -H $dest_node -r "$resource"
  return
}

set_resource_managed()
{
  echo "-> Setting is_managed attribute of resource $resource: is_managed=\"true\""
  $CRMRESOURCE -p "is_managed" -v "true" -r "$resource" --meta -s "${resource}_meta_attrs" --meta
}

set_resource_unmanaged()
{
  echo "-> Setting is_managed attribute of resource $resource: is_managed=\"false\""
  $CRMRESOURCE -p "is_managed" -v "false" -r "$resource" --meta -s "${resource}_meta_attrs" --meta
}

select_destination_node()
{
  if [ $cmdline -eq 1 ]; then
      read dest_node rest <<<"$params"
      params=$rest
      return
  fi
  echo ""
  echo "Please select a destination node"
  echo ""
  arcount=1
  for selnode in $($CLSTATUS listnodes -n | sort)
     do
	echo " ${arcount} )	$selnode"
	nodelist[$arcount]="$selnode"
	((arcount++))
     done
  echo ""
  echo " 0 )	exit"
  echo ""
  echo -n "Please select: "

  read select

  if [ ! "${nodelist[$select]}" -o "$select" = "0" -o ! "$select" ]
     then
	exit 0	
     fi

  dest_node=${nodelist[$select]}

}

set_node_standby()
{
  echo "-> Setting node $dest_node standby"
  $CRMSTANDBY -U "$dest_node" -v "true"
  return
}

set_node_active()
{
  echo "-> Setting node $dest_node active"
  $CRMSTANDBY -U "$dest_node" -v "false"
  return
}

migrate_resource()
{
  echo "-> Inserting migration rule for resource $resource to node $dest_node"
  $CRMRESOURCE -M -f -r $resource -H $dest_node
  return
}

unmigrate_resource()
{
  echo "-> Deleting migration rule for resource $resource"
  $CRMRESOURCE -U -r $resource
  return
}

select_single_resource()
{
  if [ $cmdline -eq 1 ]; then
      read resource rest <<<"$params"
      params=$rest
      return
  fi
  echo ""
  echo "Please select a resource"
  echo ""
  arcount=1
  reslist=$(${CRMRESOURCE} -L | egrep -v "^Resource Group:|^Clone Set:" | awk '{ print $1 }')
  for res in $reslist
     do
	echo " ${arcount} )	$res"
	reslist[$arcount]="$res"
	((arcount++))
     done
  echo ""
  echo " 0 )	exit"
  echo ""
  echo -n "Please select: "

  read resselect

  if [ ! "${reslist[$resselect]}" -o "$resselect" = "0" -o ! "$resselect" ]
     then
	exit 0	
     fi

  resource=${reslist[$resselect]}
}

select_resource()
{
  if [ $cmdline -eq 1 ]; then
	action=$cmd
	read resource rest <<<"$params"
	params="$rest"
	return 0
  fi
  echo ""
  echo "Please select the resource type"
  echo ""
  echo " RG | 1 )	Resource Group"
  echo " SR | 2 )	Single Resource"
  echo " CS | 3 )	Clone Set"
  echo ""
  echo -n "Please select: "

  read select

  case $select in
     RG | 1 )  reslist=$(${CRMRESOURCE} -L | egrep "^Resource Group:" | sed 's/^Resource Group: //g')
	  ;;
     SR | 2 )  reslist=$(${CRMRESOURCE} -L | egrep -v "^Resource Group:|^Clone Set:" | awk '{ print $1 }')
	  ;;
     CS | 3 )  reslist=$(${CRMRESOURCE} -L | egrep "^Clone Set:" | sed 's/^Clone Set: //g')
	  ;;
     *)	 exit 0
	  ;;
  esac

  echo ""
  echo "Please select a resource"
  echo ""
  arcount=1
  for res in $reslist
     do
	echo " ${arcount} )	$res"
	reslist[$arcount]="$res"
	((arcount++))
     done
  echo ""
  echo " 0 )	exit"
  echo ""
  echo -n "Please select: "

  read resselect

  if [ ! "${reslist[$resselect]}" -o "$resselect" = "0" -o ! "$resselect" ]
     then
	exit 0	
     fi

  resource=${reslist[$resselect]}
}

print_menue()
{
  clear
  echo " Maintain cluster services on SAP Cluster"
  echo " ----------------------------------------"
  echo ""
  echo " Ressource Start / Stop"
  echo ""
  echo " RDN  )	Stop a Resource / Clone / Group"
  echo " RUP  )	Start a Resource / Clone / Group"
  echo ""
  echo " Ressource Migration"
  echo ""
  echo " RMI  )	Migrate a Resource / Clone / Group"
  echo " RUM  )	Delete Migration rules"
  echo ""
  echo " Cluster Maintenance"
  echo ""
  echo " NSS  )	Set node to standby"
  echo " NSA  )	Set node to active"
  echo ""
  echo " RSU  )	Set a Resource / Clone / Group to unmanaged"
  echo " RSM  )	Set a Resoruce / Clone / Group to managed"
  echo ""
  echo " RCN  )	Cleanup resource"
  echo ""
  echo " RSF  )	Show resource failcounts"
  echo " RSS  )     Resource show scores"
  echo " RRF  )	Reset resource failcounts"
  echo ""
  echo " RCF  )	Reset status / failcounts for all failed resources"
  echo ""
  echo " Cluster Monitoring"
  echo ""
  echo " CSS  )	Show resource status (crm_mon)"
  echo " CSF  )	Show detailed cluster failure status (clusterstate)"
  echo " CSH  )	Show detailed cluster action history (clusterstate)"
  echo " CSL  )	Show detailed heartbeat link status  (linkstate)"
  echo ""
  echo " EXIT )	Exit program"
  echo ""
  echo ""
}

print_status()
{
  echo -n "Cluster transition status (crm): "
  dc=$($CRMADMIN -D | awk '{ print $4 }'); $CRMADMIN -S $dc -q >/dev/null
  echo -n "Cluster failure status: "
  fhstatus=$($CLUSTERSTATE -l -s)
  case "$fhstatus" in 
	GREEN )
		fhcolor=$green
		;;
	RED )
		fhcolor=$red
		;;
	YELLOW )
		fhcolor=$yellow;
		;;
  esac
  printf "${fhcolor}${fhstatus}${norm}\n"
  echo -n "Heartbeat link status		: "
  $LINKSTATE -s
  echo ""
}


#if [ $USER != "root" ]; then
#  echo "$0 can only be used by user root"
#  exit 1
#fi

while true
do
  if [ $cmdline -eq 1 ]; then
	action=$cmd
  else
	print_menue
	print_status
	  echo -n "Please choose (or press enter for status update) : "
	  read action rest
  fi
  actionu=$(echo "$action" | tr '[[:lower:]]' '[[:upper:]]')

  case $actionu in
     RDN | RESOURCEDOWN ) # resource down 
	  select_resource
          stop_resource
          presskey
          ;;
     RUP | RESOURCEUP   ) # resource up 
	  select_resource
          start_resource
          presskey
          ;;
     RMI | RESOURCEMIGRATE ) # migrate rsc
          select_resource
          select_destination_node
          sure
          migrate_resource
          presskey
          ;;
     RUM | RESOURCEUNMIGRATE ) # unmigrate rsc 
	  select_resource
          sure
          unmigrate_resource
          presskey
          ;;
     NSS | NODESETSTANDBY ) # set node standby
          select_destination_node
          sure
          set_node_standby
          presskey
          ;;
     NSA | NODESETACTIVE ) # set_node_active 
	  select_destination_node
          sure
          set_node_active
          presskey
          ;;
     RSU | RESOURCESETUNMANAGED ) # set resource unmanaged 
          select_resource
          sure
          set_resource_unmanaged
          presskey
          ;;
     RSM | RESOURCESETMANAGED ) # set resource managed 
          select_resource
          sure
          set_resource_managed
          presskey
          ;;
     RCN | RESOURCECLEANUP ) # cleanup rsc
          if [ "$?" -eq "0" ]
          	then
          		select_single_resource
          		# select_destination_node
          		sure
  			for dest_node in $($CLSTATUS listnodes -n | sort)
     			      do
          			cleanup_resource
     			      done
          		presskey
		fi
          ;;
    RSS | RESOURCESHOWSCORES ) # list scores
	  $SHOWSCORES
	  presskey
          ;;
    RSF | RESOURCESHOWFAILURES )  # list fail counts 
	  $LISTFAILCOUNTS
          presskey
          ;;
    RRF | RESOURCERESETFAILCOUNTS )  # reset fail counts 
	  $RESETFAILCOUNTS
          presskey
          ;;
    RCF | RESOURCECLEANFAILURES ) # CLEANUP  
	  echo ""
	  echo "Warning: This function will cleanup the status for all failed resources as well as"
          echo "         reset all failcounts. This is only useful if you have analyzed and fixed"
          echo "         all problems, that lead into these errors!"
	  sure
          echo "* Clean up all failed resources"
          for resource in `$CLUSTERSTATE -l | grep "Status RED: Failed to" | awk  '{ print $7 }'`
              do
		echo "Cleaning up resource: $resource"
  		for dest_node in `$CLSTATUS listnodes -n | sort`
     		      do
          		cleanup_resource
     		      done
              done
          echo "* Reset failcounts"
          $RESETFAILCOUNTS >/dev/null
          presskey
          ;;
    CSS | CLUSTERSHOWSTATUS )  # cluster status
	  $CRMMON -1 -r
          presskey
          ;;
    CSF | CLUSTERSHOWFAILURES ) $CLUSTERSTATE -l
          presskey
          ;;
    CSH | CLUSTERSHOWHISTORY ) $CLUSTERSTATE -l -r
          presskey
          ;;
    CSL | CLUSTERSHOWLINKS ) $LINKSTATE -d
          presskey
	  ;;
    EXIT ) exit 0
	  ;;
  esac
  if [ $cmdline -eq 1 ]
  then
	exit 0;
  fi
done
