
#!/bin/sh
# File	: cdot_lif_move.sh
# By	: Maarten.deBoer@Atos.net, 221219,250228
# Subject	: Script for moving LIFs
#(0.2),231026	: Upd
#(0.3),231218	: Mod.
#(0.4),250228	: Mod/Upd + LIST_BRO
# The idea is; 
# 1. to ping from the VSERVER (to be moved) LIF to another (not its own) IP address as 1st step (0 "meting")
# 2. Move the LIF to new node
#      "network interface migrate -vserver ${VSERVER} -lif ${LIF} -destination-node ${NEW_NODE}"
# 3. Ping again from LIF (on new node).
# When OK, then next LIF
# When NOT ok, then revert
#
PGM=`basename $0|cut -d\. -f1` 
VER="0.4"
TMP="/tmp/${PGM}.$$"
LOG="${HOME}/log/${PGM}.log"
SSH="/usr/bin/ssh -n"
RCFILE="${HOME}/etc/${PGM}.rc"

CLUSTER="nlnaf099"
#SFILTER="[?]*"
# Svm
SFILTER="mss"
# Liff
LFILTER="mss"
# Node
NFILTER="${CLUSTER}-05"
#NFILTER="${CLUSTER}-06"
#NFILTER="[?]*"
#NEW_NODE="${CLUSTER}-15"
# mss
#NEW_NODE="${CLUSTER}-08"
NEW_NODE="${CLUSTER}-15"
LIST_BRO=""

USAGE()
{
  echo "Usage: ${PGM} [options]"
  echo "  Version: ${VER}"
  echo "  options          :"
  echo "    -c             : Cluster (${CLUSTER})"
  echo "    -l             : Lif filter (${LFILTER})"
  echo "    -n             : Node filter (${NFILTER})"
  echo "    -s             : SVM filter (${SFILTER})"
  echo "    -h | --help    : this help"
  echo "    --new-node     : NEW_NODE (${NEW_NODE})"
  echo "    --list-bro     : List broadcast domain"
  echo "    -V             : Version"
  echo "    -x             : set -x"
}
if [ -f ${RCFILE} ]; then
  echo "  RCFILE (${RCFILE}) found. Eginx it"|tee -a ${LOG}
  . ${RCFILE}
fi  # RCFILE
# Check options
while [ ${#} -gt 0 ]
  do
  case ${1} in
    -c) CLUSTER=${2}; shift ;;
    -s) SFILTER=${2}; shift ;;
    -n) NFILTER=${2}; shift ;;
    -l) LFILTER=${2}; shift ;;
    --new-node) NEW_NODE=${2}; shift ;;
    --list-bro) LIST_BRO=1 ;;
    -h | --help) USAGE; exit 1 ;;
    -V) echo "${PGM}: v${VER}"; exit 3 ;;
    -x)  set -x ;;
    *)  echo "Option ${1} not known."; USAGE; exit 1 ;;
  esac
    shift
done

# By  ssh nlnaf100 'set -showseparator ";" ; netw inter show -field lif,curr-node,curr-port,address' > ${HOME}/data/${PGM}_input.csv
INPUTFILE="${HOME}/data/${PGM}_input_${CLUSTER}.csv"
# By  ssh nlnaf100..03 'set -showseparator ";" ; netw inter show -field lif,curr-node,curr-port,address' > ${HOME}/data/${PGM}_ping.csv
PINGFILE="${HOME}/data/${PGM}_ping.csv"

echo "`date` ${PGM} v${VER} started."|tee -a ${LOG}
echo "  CLUSTER=${CLUSTER}"
echo "  LFILTER=${LFILTER}"
echo "  NFILTER=${NFILTER}"
echo "  SFILTER=${SFILTER}"
echo "  NEW_NODE=${NEW_NODE}"
echo "  INPUTFILE=${INPUTFILE}"
echo "  PINGFILE=${PINGFILE}"
echo "  LIST_BRO=${LIST_BRO}"
sleep 1

if [ ! -f ${INPUTFILE} ]; then
  echo "  NO INPUTFILE ${INPUTFILE} found. Exiting ..."|tee -a ${LOG}
  echo "    Creating one ... and exit(4)"|tee -a ${LOG}
# Creating "dynamic" INPUTFILE
# By  ssh nlnaf100 'set -showseparator ";" ; netw inter show -field lif,curr-node,curr-port,address' > ${HOME}/data/${PGM}_input.csv
  ${SSH} ${CLUSTER} "set -showseparator \";\" ; network interface show -field lif,curr-node,curr-port,address"|egrep "vserver|${SFILTER}" > ${INPUTFILE}
  exit 4
fi
if [ ! -f ${PINGFILE} ]; then
  echo "  NO PINGFILE ${PINGFILE} found. Eme)xiting ..."|tee -a ${LOG}
  echo "    Creating one ... and exit(5)"|tee -a ${LOG}
# Creating "dynamic" INPUTFILE
# By  ssh nlnaf102 'set -showseparator ";" ; netw inter show -field lif,curr-node,curr-port,address' > ${HOME}/data/${PGM}_ping.csv
#
# With only (name)PART of LIFs
  LIF_PART=`echo ${LFILTER}|sed 's/[0-9]*//g'`
  echo "      LIF_PART=${LIF_PART}"
  ${SSH} ${CLUSTER} "set -showseparator \";\" ; network interface show  -field lif,curr-node,curr-port,address"|egrep "vserver|${LIF_PART}" > ${PINGFILE}
  exit 5
fi

# LIST-BRO
if [ ${LIST_BRO} ]; then
  ${SSH} ${CLUSTER} "network port broadcast-domain show -ipspace ${LFILTER}*"
  exit 6
fi  # LIST_BRO

# Select on Svm-filter & Lif-Filter
cat ${INPUTFILE}|grep -v ^#|grep "${SFILTER}"|grep "${LFILTER}"|while read LINE
do
#vserver(1);server(2);lif(3);vif(4);address(5);curr-node(6);curr-port(7);
  VSERVER=`echo ${LINE}|awk -F\; '{print $1}'`
  LIF=`echo ${LINE}|awk -F\; '{print $3}'|sed 's/ //g'`
  LIF_ADDR=`echo ${LINE}|awk -F\; '{print $5}'`
  NETWORK=`echo ${LINE}|awk -F\; '{print $5}'|awk -F\. '{print $1"."$2"."$3}'`
  CURR_NODE=`echo ${LINE}|awk -F\; '{print $6}'|sed 's/ //g'`
  CURR_PORT=`echo ${LINE}|awk -F\; '{print $7}'`
  VLAN=`echo ${LINE}|awk -F\; '{print $7}'|cut -d\- -f2`

  echo "-----"
  echo "  VSERVER=${VSERVER} LIF=${LIF} LIF_ADDR=${LIF_ADDR} NETWORK=${NETWORK} CURR_NODE=${CURR_NODE} CURR_PORT=${CURR_PORT}"|tee -a ${LOG}

  ${SSH} ${CLUSTER} "vserver show -vserver ${VSERVER} -operational-state running" 1> /dev/null
  EC=${?}
  if [ ${EC} -eq 0 ]; then
#    VSERVER_ADDR=`${SSH} ${CLUSTER} "network interface show -vserver ${VSERVER} -lif ${LIF} -field address"|grep ${VSERVER}|awk '{print $3}'`
#    echo "    VSERVER=${VSERVER} VLAN=${VLAN} NETWORK=${NETWORK}"

# Get Ping-IP-address (not its own)
    PING_ADDR=`grep "${NETWORK}" ${PINGFILE}|grep -v ^#|grep -v "${LIF_ADDR}"|awk -F\; '{print $5}'|head -1`
    echo "  LIF_ADDR=${LIF_ADDR} PING_ADDR=${PING_ADDR} "

# Get Curr node (maybe already moved)
    LIFE_CURR_NODE=`${SSH} ${CLUSTER} "network inter show -vserver ${VSERVER} -lif ${LIF} -field curr-node"|grep ${VSERVER}|awk '{print $3}'|sort -u`
    
    if [ "${LIFE_CURR_NODE}" != "" ] && [ "${LIFE_CURR_NODE}" != "${NEW_NODE}" ] && [ "${PING_ADDR}" != "" ]; then
      echo "    LIFE_CURR_NODE=${LIFE_CURR_NODE} NEW_NODE=${NEW_NODE} PING_ADDR=${PING_ADDR}"|tee -a ${LOG}

      ${SSH} ${CLUSTER} "ping -vserver ${VSERVER} -lif ${LIF} -dest ${PING_ADDR}" 1> /dev/null 2>&1
      EC=${?}
      if [ ${EC} -eq 0 ]; then
        echo "      Ping from LIF ${LIF} to ${PING_ADDR} is OK"|tee -a ${LOG}
        echo ""
        echo "        Moving LIF ${LIF} at port ${CURR_PORT} from ${LIFE_CURR_NODE} to ${NEW_NODE} ..."|tee -a ${LOG}
        sleep 2
# REAL MOVE / migrate
        ${SSH} ${CLUSTER} "network interface migrate -vserver ${VSERVER} -lif ${LIF} -destination-node ${NEW_NODE}"
        EC=${?}
        if [ ${EC} -ne 0 ]; then
          echo "        Move was NOT ok (EC=${EC})"|tee -a ${LOG}
          sleep 1
        else
          echo "        Move done (EC=${EC})"
          echo "        2nd ping from LIF ${LIF} (${LIF_ADDR}) to ${PING_ADDR}"
          ${SSH} ${CLUSTER} "ping -vserver ${VSERVER} -lif ${LIF} -dest ${PING_ADDR}" 
          EC=${?}
          if [ ${EC} -eq 0 ]; then
            echo "      Move ${VSERVER}:${LIF} to ${NEW_NODE} = ok"|tee -a ${LOG}
          else
            echo "!     Move ${VSERVER}:${LIF} to ${NEW_NODE} NOT ok (EC=${EC})"|tee -a ${LOG}
            echo "!   Revering back to ${CURR_NODE}"|tee -a ${LOG}
#            ${SSH} ${CLUSTER} "network interface migrate -vserver ${VSERVER} -lif ${LIF} -destination-node ${CURR_NODE}"
          
          fi  # PING EC} -eq 0

        fi  # MOVE EC} -ne 0

      fi  # VSERVER EC} -eq 0
    else
      echo "    NO move done. Due to"|tee -a ${LOG}
      echo "    LIFE_CURR_NODE(${LIFE_CURR_NODE}) == NEW_NODE(${NEW_NODE})"|tee -a ${LOG}
      echo "    Or PING_ADDR=${PING_ADDR}"|tee -a ${LOG}
    fi  # PING_ADDR}" != ""
  fi  # VSERVER running
done  # LINE

# Show Node-Ports
${SSH} ${CLUSTER} "network interface show -field home-node,home-port,curr-node,curr-port,lif"|egrep "vserver|${SFILTER}"| egrep "vserver|${LFILTER}"

echo "`date` ${PGM} v${VER} finished."|tee -a ${LOG}
exit 0

