#!/bin/bash

# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.


#set -x

usage() {
  usage_content="
  The tool for stopping/starting running system vms and domain routers. It requires integration API port to be enabled.

  Usage: %s: [-d] [-u] [-p] [-m] [-s] [-r] [-a] [-n] [-t] [-l] [-z] [-v] [-i] [-j]

   -d - cloud DB server ip address, defaulted to localhost if not specified
   -u - user name to access cloud DB, defaulted to \"root\" if not specified
   -p - cloud DB user password, defaulted to no password if not specified
   -m - the ip address of management server, defaulted to localhost if not specified
   -s - stop then start all running SSVMs and Console Proxies
   -r - stop then start all running Virtual Routers
   -a - stop then start all running SSVMs, Console Proxies, and Virtual Routers
   -n - restart all Guest networks
   -t - number of parallel threads used for stopping Domain Routers. Default is 10
   -l - log file location. Default is cloud.log under current directory
   -z - do restart only for the instances in the specific zone. If not specified, restart will apply to instances in all zones
   -v - do restart all VPCs in the entire system
   -i - do restart on instances with specific IDs. Comma-separated instance IDs to be provided. Works only when restarting SSVMs, CPVMs or VRs
   -j - do restart on instances from the specified database table. If not specified, restart will apply on instances present in cloud.vm_instance database table. Works only when restarting SSVMs, CPVMs or VRs\n\n"
  printf "$usage_content" "$(basename $0)" >&2
}


system=
router=
all=
vpc=
db=localhost
ms=localhost
user=root
password=
help=
maxthreads=10
LOGFILE=cloud.log
zone=""
inzone=""
vmids=""
vmidsclause=""
withids=""
vmtable="vm_instance"
integrationport=0



while getopts 'sarhnvd:m:u:p:t:l:z:i:j:' OPTION
do
  case $OPTION in
  s)    system=1
        ;;
  r)    router=1
        ;;
  n)    redundant=1
        ;;
  a)    all=1
        ;;
  v)    vpc=1
        ;;
  d)    db="$OPTARG"
        ;;
  u)    user="$OPTARG"
        ;;
  p)    password="$OPTARG"
        ;;
  h)    help=1
        ;;
  m)    ms="$OPTARG"
  		;;
  t)	maxthreads="$OPTARG"
  		;;
  l)	LOGFILE="$OPTARG"
        ;;
  z)    zone=" AND data_center_id=""$OPTARG"
        inzone=" in zone id=""$OPTARG"
        ;;
  i)    vmids="$OPTARG"
        withids=" with id=""$OPTARG"
        ;;
  j)    vmtable="$OPTARG"
  esac
done


integrationport=(`mysql -h $db --user=$user --password=$password --skip-column-names -U cloud -e "SELECT value FROM configuration WHERE name='integration.api.port'"`)
if [ $integrationport -le 0 ]; then
    echo "Integration port is not enabled!"
    exit
fi

prepare_ids_clause() {
  if [[ ! -z "$vmidsclause" ]]; then
    return
  fi
  vmidsclause=""
  if [[ ! -z "$vmids" ]]; then
    vmidsclause=" AND uuid IN ('$vmids')"
    vmidsclause=${vmidsclause/,/"','"}
  fi
}

stop_start_system() {
    prepare_ids_clause
    secondary=(`mysql -h $db --user=$user --password=$password --skip-column-names -U cloud -e "select uuid from $vmtable where state=\"Running\" and type=\"SecondaryStorageVm\"$zone$vmidsclause"`)
    console=(`mysql -h $db --user=$user --password=$password --skip-column-names -U cloud -e "select uuid from $vmtable where state=\"Running\" and type=\"ConsoleProxy\"$zone$vmidsclause"`)
    length_secondary=(${#secondary[@]})
    length_console=(${#console[@]})


    echo -e "\nStopping and starting $length_secondary secondary storage vm(s)$inzone$withids..."
    echo -e "[$(date "+%Y.%m.%d-%H.%M.%S")] Stopping and starting $length_secondary secondary storage vm(s)$inzone$withids..." >>$LOGFILE

    for d in "${secondary[@]}"; do
        echo "[$(date "+%Y.%m.%d-%H.%M.%S")] INFO: Stopping secondary storage vm with id $d" >>$LOGFILE
        jobresult=$(send_request stopSystemVm $d)
        if [ "$jobresult" != "1" ]; then
            echo -e "ERROR: Failed to stop secondary storage vm with id $d \n"
          echo "[$(date "+%Y.%m.%d-%H.%M.%S")] ERROR: Failed to stop secondary storage vm with id $d" >>$LOGFILE
        else
            echo "[$(date "+%Y.%m.%d-%H.%M.%S")] INFO: Starting secondary storage vm with id $d" >>$LOGFILE
            jobresult=$(send_request startSystemVm $d SSVM)
            if [ "$jobresult" != "1" ]; then
                echo "[$(date "+%Y.%m.%d-%H.%M.%S")] ERROR: Failed to start secondary storage vm with id $d" >>$LOGFILE
                echo "[$(date "+%Y.%m.%d-%H.%M.%S")] ERROR: Failed to start secondary storage vm with id $d" >>$LOGFILE
            fi
        fi
    done

    if [ "$length_secondary" == "0" ];then
        echo -e "No running secondary storage vms found \n"
    else
        echo -e "Done stopping and starting secondary storage vm(s)$inzone$withids"
        echo -e "[$(date "+%Y.%m.%d-%H.%M.%S")] Done stopping and starting secondary storage vm(s)$inzone$withids." >>$LOGFILE
    fi

    echo -e "\nStopping and starting $length_console console proxy vm(s)$inzone$withids..."
    echo -e "[$(date "+%Y.%m.%d-%H.%M.%S")] Stopping and starting $length_console console proxy vm(s)$inzone$withids..." >>$LOGFILE

    for d in "${console[@]}"; do
        echo "[$(date "+%Y.%m.%d-%H.%M.%S")] INFO: Stopping console proxy with id $d" >>$LOGFILE
        jobresult=$(send_request stopSystemVm $d)
        if [ "$jobresult" != "1" ]; then
            echo -e "ERROR: Failed to stop console proxy vm with id $d \n"
            echo "[$(date "+%Y.%m.%d-%H.%M.%S")] ERROR: Failed to stop console proxy vm with id $d" >>$LOGFILE
        else
            echo "[$(date "+%Y.%m.%d-%H.%M.%S")] INFO: Starting console proxy vm with id $d" >>$LOGFILE
            jobresult=$(send_request startSystemVm $d consoleProxy)
            if [ "$jobresult" != "1" ]; then
                echo -e "ERROR: Failed to start console proxy vm with id $d \n"
                echo "[$(date "+%Y.%m.%d-%H.%M.%S")] ERROR: Failed to start console proxy vm with id $d" >>$LOGFILE
            fi
        fi
    done

    if [ "$length_console" == "0" ];then
            echo -e "No running console proxy vms found \n"
    else
            echo "Done stopping and starting console proxy vm(s) $inzone$withids."
        echo "[$(date "+%Y.%m.%d-%H.%M.%S")] Done stopping and starting console proxy vm(s) $inzone$withids." >>$LOGFILE
    fi
}

stop_start_router() {
    prepare_ids_clause
    router=(`mysql -h $db --user=$user --password=$password --skip-column-names -U cloud -e "select uuid from vm_instance where state=\"Running\" and type=\"DomainRouter\"$zone$vmidsclause"`)
    length_router=${#router[@]}

    echo -e "\nStopping and starting $length_router running routing vm(s)$inzone$withids... "
    echo -e "[$(date "+%Y.%m.%d-%H.%M.%S")] Stopping and starting $length_router running routing vm(s)$inzone$withids... " >>$LOGFILE

    #Spawn reboot router in parallel - run commands in <n> chunks - number of threads is configurable

    if [ $maxthreads -gt $length_router ]; then
        maxthreads=$length_router
    fi
    pids=()
    for d in "${router[@]}"; do

        reboot_router $d &

        pids=( "${pids[@]}" $! )
        length_pids=${#pids[@]}

        if [ $length_pids -ge $maxthreads ]; then
            # Wait for $maxthreads number of processes to finish
            wait
            # Clear the pids array for the next batch
            pids=()
        fi

    done

    if [ "$length_router" == "0" ];then
        echo -e "[$(date "+%Y.%m.%d-%H.%M.%S")] No running router vms found \n" >>$LOGFILE
    else
        # Wait for the remaining background processes to finish
        wait

        echo -e "Done restarting router(s)$inzone$withids. \n"
        echo -e "[$(date "+%Y.%m.%d-%H.%M.%S")] Done restarting router(s)$inzone$withids. \n" >>$LOGFILE

    fi
}

stop_start_all() {
    stop_start_system
    stop_start_router
}

send_request(){
    jobid=`curl -sS "http://$ms:$integrationport/?command=$1&id=$2&response=json" | sed 's/\"//g' | sed 's/ //g' | sed 's/{//g' | sed 's/}//g' | awk -F: {'print $3'}`
    if [ "$jobid" == "" ]; then
        echo 2
        return
    fi
    jobresult=$(query_async_job_result $jobid)
    if [ "$jobresult" != "1" ]; then
        echo -e "ERROR: Failed to $1 id=$2; jobId is $jobid \n"
        echo "[$(date "+%Y.%m.%d-%H.%M.%S")] ERROR: Failed to $1 id=$2; jobId is $jobid" >>$LOGFILE
    fi
    echo $jobresult
}


reboot_router(){
    echo "[$(date "+%Y.%m.%d-%H.%M.%S")] INFO: Restarting router with id $1" >>$LOGFILE
    jobid=`curl -sS "http://$ms:$integrationport/?command=rebootRouter&id=$1&response=json" | sed 's/\"//g' | sed 's/ //g' | sed 's/{//g' | sed 's/}//g' | awk -F: {'print $3'}`
    if [ "$jobid" == "" ]; then
        echo "[$(date "+%Y.%m.%d-%H.%M.%S")] ERROR: Failed to restart domainRouter with id $1; unable to submit the job" >>$LOGFILE
        echo 2
        return
    fi

    jobresult=$(query_async_job_result $jobid)

    if [ "$jobresult" != "1" ]; then
        echo -e "ERROR: Failed to restart domainRouter with id $1 \n"
        echo "[$(date "+%Y.%m.%d-%H.%M.%S")] ERROR: Failed to restart domainRouter with id $1; jobId $jobid" >>$LOGFILE
        exit 0
    else
        echo "[$(date "+%Y.%m.%d-%H.%M.%S")] INFO: Successfully restarted domainRouter with id $1; jobId $jobid" >>$LOGFILE
        exit 0
    fi
}

restart_networks(){
    networks=(`mysql -h $db --user=$user --password=$password --skip-column-names -U cloud -e "select n.id
    from networks n, network_offerings no where n.network_offering_id = no.id and no.system_only = 0 and n.removed is null$zone"`)
    length_networks=${#networks[@]}

    echo -e "\nRestarting $length_networks networks$inzone... "
    echo -e "[$(date "+%Y.%m.%d-%H.%M.%S")] Restarting $length_networks networks$inzone... " >>$LOGFILE

    #Spawn restart network in parallel - run commands in <n> chunks - number of threads is configurable

    if [ $maxthreads -gt $length_networks ]; then
        maxthreads=$length_networks
    fi
    pids=()
    for d in "${networks[@]}"; do

        restart_network $d &

        pids=( "${pids[@]}" $! )
        length_pids=${#pids[@]}

        if [ $length_pids -ge $maxthreads ]; then
            # Wait for $maxthreads number of processes to finish
            wait
            # Clear the pids array for the next batch
            pids=()
        fi

    done


    if [ "$length_networks" == "0" ];then
        echo -e "[$(date "+%Y.%m.%d-%H.%M.%S")] No networks found \n" >>$LOGFILE
    else
        # Wait for the remaining background processes to finish
        wait

        echo -e "Done restarting networks$inzone. \n"
        echo -e "[$(date "+%Y.%m.%d-%H.%M.%S")] Done restarting networks$inzone. \n" >>$LOGFILE

    fi
}

restart_network(){
    jobid=`curl -sS "http://$ms:$integrationport/?command=restartNetwork&id=$1&response=json" | sed 's/\"//g' | sed 's/ //g' | sed 's/{//g' | sed 's/}//g' | awk -F: {'print $3'}`
    if [ "$jobid" == "" ]; then
        echo "[$(date "+%Y.%m.%d-%H.%M.%S")] ERROR: Failed to restart network with id $1; unable to submit the job" >>$LOGFILE
        echo 2
        return
    fi

    jobresult=$(query_async_job_result $jobid)

    if [ "$jobresult" != "1" ]; then
        echo "[$(date "+%Y.%m.%d-%H.%M.%S")] ERROR: Failed to restart network with id $1; jobId $jobid" >>$LOGFILE
    else
        echo "[$(date "+%Y.%m.%d-%H.%M.%S")] INFO: Successfully restarted network with id $1; jobId $jobid" >>$LOGFILE
    fi

}


restart_vpc(){
    echo -e "INFO: Restarting vpc with id $1"
    echo "[$(date "+%Y.%m.%d-%H.%M.%S")] INFO: Restarting vpc with id $1" >>$LOGFILE
    jobid=`curl -sS "http://$ms:$integrationport/?command=restartVPC&id=$1&response=json" | sed 's/\"//g' | sed 's/ //g' | sed 's/{//g' | sed 's/}//g' | awk -F: {'print $3'}`
    if [ "$jobid" == "" ]; then
        echo "[$(date "+%Y.%m.%d-%H.%M.%S")] ERROR: Failed to restart vpc with id $1; unable to submit the job" >>$LOGFILE
        echo 2
        return
    fi

    jobresult=$(query_async_job_result $jobid)

    if [ "$jobresult" != "1" ]; then
        echo -e "ERROR: Failed to restart vpc with id $1 \n"
        echo "[$(date "+%Y.%m.%d-%H.%M.%S")] ERROR: Failed to restart vpc with id $1; jobId $jobid" >>$LOGFILE
    else
        echo -e "INFO: Successfully restarted vpc with id $1 \n"
        echo "[$(date "+%Y.%m.%d-%H.%M.%S")] INFO: Successfully restarted vpc with id $1; jobId $jobid" >>$LOGFILE
    fi
}


restart_vpcs(){
    vpcs=(`mysql -h $db --user=$user --password=$password --skip-column-names -U cloud -e "select uuid from vpc WHERE removed is null$zone"`)
    length_vpcs=${#vpcs[@]}

    echo -e "\nRestarting $length_vpcs vpcs... "
    echo -e "[$(date "+%Y.%m.%d-%H.%M.%S")] Restarting $length_vpcs vpcs... " >>$LOGFILE

    #Spawn restart vpcs in parallel - run commands in <n> chunks - number of threads is configurable

    if [ $maxthreads -gt $length_vpcs ]; then
        maxthreads=$length_vpcs
    fi
    pids=()
    for d in "${vpcs[@]}"; do

        restart_vpc $d &

        pids=( "${pids[@]}" $! )
        length_pids=${#pids[@]}

        if [ $length_pids -ge $maxthreads ]; then
            # Wait for $maxthreads number of processes to finish
            wait
            # Clear the pids array for the next batch
            pids=()
        fi

    done


    if [ "$length_vpcs" == "0" ];then
        echo -e "[$(date "+%Y.%m.%d-%H.%M.%S")] No vpcs found \n" >>$LOGFILE
    else
        # Wait for the remaining background processes to finish
        wait

        echo -e "Done restarting vpcs$inzone. \n"
        echo -e "[$(date "+%Y.%m.%d-%H.%M.%S")] Done restarting vpcs$inzone. \n" >>$LOGFILE

    fi
}

query_async_job_result() {
    while [ 1 ]
    do
        jobstatus=`curl -sS "http://$ms:$integrationport/?command=queryAsyncJobResult&jobId=$1&response=json" | sed 's/\"//g' | sed 's/ //g' | sed 's/{//g' | sed 's/}//g' | awk -F, {'print $7'} | awk -F: {'print $2'}`
        if [ "$jobstatus" != "0" ]; then
            echo $jobstatus
            break
        fi
    sleep 5
    done
}

if [ "$system$router$all$help$redundant$vpc" == "" ]
then
    usage
    exit
fi

if  [ "$help" == "1" ]
then
    usage
    exit
fi

if [ "$all" == "1" ]
then
      stop_start_all
      exit
fi

if [ "$system" == "1" ]
then
      stop_start_system
fi

if [ "$router" == "1" ]
then
      stop_start_router
fi

if [ "$redundant" == "1" ]
then
      restart_networks
fi

if [ "$vpc" == "1" ]
then
      restart_vpcs
fi
