#!/bin/bash
#< Enable, disable and check BIG-IP pool members

# pool.sh
#
# version 0.1	20061230	KWaldron	Base functionality	
# version 0.2	20070221	KWaldron	Added further error checking
#						Added ability to resolve hostnames
#
# Requires:
#  valip		- See http://www.zazzybob.com/bin/tars/valip.tar.gz
#  common_functions.sh	- See http://www.zazzybob.com/bin/tars/common_functions.sh.tar.gz


# Server is the remote server to connect to - i.e. the BIGIP
SERVER="192.168.0.1"
REMOTE_USER="root"

AWK="/usr/bin/awk"
BASENAME="/bin/basename"
BIGPIPE="/bin/bigpipe"
CUT="/usr/bin/cut"
ECHO="/bin/echo"
GREP="/bin/grep"
HOST="/usr/bin/host"
SSH="/usr/bin/ssh"

# Dependencies
COMMON_FUNCTIONS="./common_functions.sh"
VALIP="./valip"

THIS_PROG=$( ${BASENAME} $0 )

SUCCESS=0
ERROR=1

DEBUG=0

function usage {
   ${ECHO} "Usage: ${THIS_PROG} [-d] -p <pool> -m <ip>:<port> -a <action>" >&2
   ${ECHO} "   Where action is one of [enable|disable|check]" >&2
   ${ECHO} "   -d - Turn some debugging output on" >&2
}

function check_args {
   ERROR_COUNT=0
   if [ -z ${POOL_NAME} ]; then
      print_error "No pool specified" 
      (( ERROR_COUNT = ERROR_COUNT + 1 ))
   fi
   if [ -z ${MEMBER} ]; then
      print_error "No member specified" 
      (( ERROR_COUNT = ERROR_COUNT + 1 ))
   fi
   if [ -z ${ACTION} ]; then
      print_error "No action specified" 
      (( ERROR_COUNT = ERROR_COUNT + 1 ))
   fi
   if [ "${ERROR_COUNT}" -gt "0" ]; then
     exit ${ERROR}
   fi
}

function get_ip_and_port {
   IP_ADDRESS=$( ${ECHO} "${MEMBER}" | ${CUT} -d: -f1 )
   PORT=$( ${ECHO} "${MEMBER}" | ${CUT} -d: -f2 )
   (( DEBUG )) && {
      print_debug "IP address: ${IP_ADDRESS}"
      print_debug "Port:       ${PORT}"
   }
   ${ECHO} "${IP_ADDRESS}" | ${VALIP} >/dev/null 2>&1
   if [ "$?" -ne "0" ]; then
      # Let's see if we can resolve what we've been passed
      OUTPUT=$( ${HOST} "${IP_ADDRESS}" 2>&1 | ${AWK} '{print $NF}' ) 
      ${ECHO} "${OUTPUT}" | ${GREP} "3(NXDOMAIN)" >/dev/null 2>&1
      if [ "$?" -ne "0" ]; then
	 (( DEBUG )) && {
	    print_debug "Resolved ${IP_ADDRESS} to ${OUTPUT}"
	 }
         IP_ADDRESS="${OUTPUT}"
	 MEMBER="${IP_ADDRESS}:${PORT}"
      else
         print_error "Couldn't resolve ${IP_ADDRESS} into anything useful"
	 exit ${ERROR}
      fi
   fi
}

function check_pool_exists {
   OUTPUT=$( ${SSH} ${REMOTE_USER}@${SERVER} "${BIGPIPE} pool ${POOL_NAME} list 2>&1" )
   (( DEBUG )) && {
      print_debug "--[ check_pool_exists ]--"
      print_debug "${OUTPUT}"
   }
   ${ECHO} "${OUTPUT}" | ${GREP} "The requested pool.*was not found" >/dev/null 2>&1
   if [ "$?" -eq "0" ]; then
      print_error "pool ${POOL_NAME} does not exist"
      exit ${ERROR}
   fi
}

function check_pool_member {
   ${ECHO} "${OUTPUT}" | ${GREP} "The requested pool member.*was not found" >/dev/null 2>&1
   if [ "$?" -eq "0" ]; then
      print_error "member ${MEMBER} does not exist in pool ${POOL_NAME}"
      exit ${ERROR}
   fi
}

function enable_member {
   check_pool_exists
   OUTPUT=$( ${SSH} ${REMOTE_USER}@${SERVER} "${BIGPIPE} pool ${POOL_NAME} member ${MEMBER} session enable 2>&1" )
   check_pool_member
}

function disable_member {
   check_pool_exists
   OUTPUT=$( ${SSH} ${REMOTE_USER}@${SERVER} "${BIGPIPE} pool ${POOL_NAME} member ${MEMBER} session disable 2>&1" )
   check_pool_member
}

function check_member {
   check_pool_exists
   OUTPUT=$( ${SSH} ${REMOTE_USER}@${SERVER} "${BIGPIPE} pool ${POOL_NAME} member ${MEMBER} list 2>&1" )
   check_pool_member
   (( DEBUG )) && {
       print_debug "--[ check_member ]--"
       print_debug "${OUTPUT}"
   }
   ${ECHO} "${OUTPUT}" | ${GREP} "disable$" >/dev/null 2>&1
   if [ "$?" -eq "0" ]; then
      ${ECHO} "Disabled"
   else
      ${ECHO} "Enabled"
   fi
}

function check_dependencies {
   for DEPENDENT in ${VALIP}; do
      requires "${DEPENDENT}" || {
         print_error "could not find dependent ${DEPENDENT}"
         exit 255
      }
   done
   for EXECUTABLE in ${VALIP}; do
      is_exe "${EXECUTABLE}" || {
         print_error "${EXECUTABLE} found, but not executable"
    	 exit 255
      }
   done
}

function check_action {
   case ${ACTION} in
      "enable"  ) enable_member   ;;
      "disable" ) disable_member  ;;
      "check"   ) check_member    ;;
      *         ) print_error "Invalid action ${ACTION}"
                  exit "${ERROR}" ;;
   esac
}

if [ "$#" -lt "6" ]; then
   usage
   exit ${ERROR}
fi

. ${COMMON_FUNCTIONS} 2>/dev/null || {
   ${ECHO} "Error: Could not load common functions"
      exit 255
}

while getopts ":dp:m:a:" OPTION; do
   case ${OPTION} in
      "d" ) DEBUG=1
            ;;
      "p" ) POOL_NAME="${OPTARG}"
            ;;
      "m" ) MEMBER="${OPTARG}"
            ;;
      "a" ) ACTION="${OPTARG}"
            ;;
      *   ) usage
            exit ${ERROR}
            ;;
   esac
done

shift $(( ${OPTIND} - 1 ))

if [ "$#" -ne "0" ]; then
   usage
   exit "${ERROR}"
fi

check_dependencies
check_args
get_ip_and_port
check_action

exit "${SUCCESS}"