#!/bin/bash
if [ -z "$1" ]; then
    echo ''
    echo 'Usage: dsa_move <required> [optional]'
    echo ''
    echo 'required'
    echo '========'
    echo '-d,--dsm        - Activate agent with Manager at specified URL. Format must be "dsm://hostOrIp:port/", where port is the Manager heartbeat port.'
    echo '-i,--tenantid   - Activate agent with specified tenant.'
    echo '-t,--token      - Activate agent with specified activation token.'
    echo '-m,--moveid     - Activate agent with specified moveid to track it.'
    echo '-w,--workdir    - Working directory where data files are stored.'
    echo '-b,--bindir     - Agent installation directory.'
    echo '-c,--dsmpubca   - Manager public CA certificate file in PEM format.'
    echo ''
    echo 'optional'
    echo '========'
    echo '-p,--policyid   - Activate agent with specified policy. Must be an integer.'
    echo '-r,--relayid    - Activate agent within specified relay group. Must be an integer.'
    echo '-g,--groupid    - Activate agent within specified group. Must be an integer.'
    echo '-x,--dsmproxy   - Set the address of the proxy server which the agent uses to communicate with the DSM. URL format must be "dsm_proxy://hostOrIp:port/"'
    echo '-u,--dpcred     - Set the DSM proxy username and password. Format must be username:password'
    echo '-X,--relayproxy - Set the address of the proxy server which the agent uses to communicate with the relay. URL format must be "relay_proxy://hostOrIp:port/"'
    echo '-U,--rpcred     - Set the relay proxy username and password. Format must be username:password'
    echo '-a,--actwait    - Set the wait time in seconds for the agent to activate. Default 60.'
    echo ''
    exit 1
fi
echo `date` : Move Agent started
echo
echo `date` : Parameters
while [ $# -gt 0 ]; do
    key="$1"

    case $key in
        -d|--dsm)
            DSM_URL="$2"
            echo DSM_URL: $DSM_URL
            ;;
        -i|--tenantid)
            TENANT_ID=tenantID:"$2"
            echo TENANT_ID: $TENANT_ID
            ;;
        -t|--token)
            TOKEN=token:"$2"
            echo TOKEN: $TOKEN
            ;;
        -m|--moveid)
            MOVE_ID=moveID:"$2"
            echo MOVE_ID: $MOVE_ID
            ;;
        -w|--workdir)
            DSA_WORK_DIR="$2"
            echo DSA_WORK_DIR: $DSA_WORK_DIR
            ;;
        -b|--bindir)
            DSA_BIN_DIR="$2"
            echo DSA_BIN_DIR: $DSA_BIN_DIR
            ;;
        -c|--dsmpubca)
            DSM_PUB_CA_FILE="$2"
            echo DSM_PUB_CA_FILE: $DSM_PUB_CA_FILE
            ;;
        -p|--policyid)
            POLICY_ID=policyid:"$2"
            echo POLICY_ID: $POLICY_ID
            ;;
        -r|--relayid)
            RELAY_ID=relaygroupid:"$2"
            echo RELAY_ID: $RELAY_ID
            ;;
        -g|--groupid)
            GROUP_ID=groupid:"$2"
            echo GROUP_ID: $GROUP_ID
            ;;
        -x|--dsmproxy)
            DSM_PROXY="$2"
            echo DSM_PROXY: $DSM_PROXY
            ;;
        -u|--dpcred)
            DSM_PROXY_CRED="$2"
            echo DSM_PROXY_CRED: *****:*****
            ;;
        -X|--relayproxy)
            RELAY_PROXY="$2"
            echo RELAY_PROXY: $RELAY_PROXY
        ;;
        -U|--rpcred)
            RELAY_PROXY_CRED="$2"
            echo RELAY_PROXY_CRED *****:*****
        ;;
        -a|--actwait)
            ACTIVATION_WAIT_TIME="$2"
            echo ACTIVATION_WAIT_TIME: $ACTIVATION_WAIT_TIME
        ;;
        *)  # unknown option
            echo unknown option "$1"
            rm -f $DSM_PUB_CA_FILE
            exit 1
            ;;
    esac
    shift # past argument
    shift # past value
done

# checking for required options
[ -z "$DSM_URL" ] &&  MISSING_OPTS="$MISSING_OPTS --dsm,"
[ -z "$TENANT_ID" ] && MISSING_OPTS="$MISSING_OPTS --tenantid,"
[ -z "$TOKEN" ] && MISSING_OPTS="$MISSING_OPTS --token,"
[ -z "$MOVE_ID" ] && MISSING_OPTS="$MISSING_OPTS --moveid,"
[ -z "$DSA_WORK_DIR" ] && MISSING_OPTS="$MISSING_OPTS --workdir,"
[ -z "$DSA_BIN_DIR" ] && MISSING_OPTS="$MISSING_OPTS --bindir,"
[ -z "$DSM_PUB_CA_FILE" ] && MISSING_OPTS="$MISSING_OPTS --dsmpubca,"
if [ -n "$MISSING_OPTS" ]; then
    echo Missing option\(s\):$MISSING_OPTS
    rm -f $DSM_PUB_CA_FILE
    exit 1
fi

# set default activation wait time if not set
if [ -z "$ACTIVATION_WAIT_TIME" ]; then
    ACTIVATION_WAIT_TIME="60"
    echo ACTIVATION_WAIT_TIME: $ACTIVATION_WAIT_TIME
fi

OS=`uname`
DSA_CONTROL=$DSA_BIN_DIR/dsa_control
BACKUP_DIR=backup_`date '+%Y-%m-%d_%H:%M:%S'`

echo PLATFORM: $OS
echo BACKUP_DIR: $BACKUP_DIR
echo

is_agent_running() {
    if [ "$OS" = "SunOS" ]; then
        ps -e -o "pid ppid fname" | grep "ds_agent"
    else
        ps -e -o "%p %P %c" | grep "ds_agent"
    fi
}

is_agent_service_running() {
    if [ "$OS" = "Linux" ]; then
        if [ -f /etc/init.d/ds_agent ]; then
            /etc/init.d/ds_agent status
        else
            systemctl status ds_agent
        fi
    elif [ "$OS" = "SunOS" ]; then
        svcs -H -o STA svc:/application/ds_agent | grep ON

    elif [ "$OS" = "AIX" ]; then
        lssrc -s ds_agent | grep -E "active|stopping"
    fi
}

agent_kill() {
    echo `date` : Killing agent
    if [ "$OS" = "SunOS" ]; then
        PID=`ps -e -o "pid ppid fname" | grep "ds_agent" | awk '{print $1}' ORS=' '`
    else
        PID=`ps -e -o "%p %P %c" | grep "ds_agent" | awk '{print $1}' ORS=' '`
    fi
    kill -9 "$PID"
}

agent_stop() {
    echo `date` : Stopping agent
    # Stop agent service.
    if [ "$OS" = "Linux" ]; then
        if [ -f /etc/init.d/ds_agent ]; then
            /etc/init.d/ds_agent stop
        else
            systemctl stop ds_agent
        fi
    elif [ "$OS" = "SunOS" ]; then
        svcadm disable svc:/application/ds_agent
    elif [ "$OS" = "AIX" ]; then
        stopsrc -s ds_agent
    fi

    # Check agent service.
    RETRY=11
    SLEEP_TIME=5
    while [ $RETRY != "0" ]; do
        if ! is_agent_service_running; then
            break
        fi
        sleep $SLEEP_TIME
        RETRY=`expr $RETRY - 1`
        echo $RETRY
    done

    # Check agent process
    if is_agent_running; then
        echo `date` : Failed to stop Agent. Force kill agent process.
        agent_kill
        sleep $SLEEP_TIME
        if is_agent_running; then
            echo `date` : Failed to force kill agent.
            return 1
        fi
    fi
    echo `date` : Agent stopped
    return 0
}

agent_start() {
    echo `date` : Starting agent
    if [ "$OS" = "Linux" ]; then
        if [ -f /etc/init.d/ds_agent ]; then
            /etc/init.d/ds_agent start
        else
            systemctl start ds_agent
        fi
    elif [ "$OS" = "SunOS" ]; then
        svcadm enable svc:/application/ds_agent
    elif [ "$OS" = "AIX" ]; then
        startsrc -s ds_agent
    fi

    # Check agent service
    RETRY=11
    SLEEP_TIME=5
    while [ $RETRY != "0" ]; do
        if is_agent_service_running; then
            break
        fi
        sleep $SLEEP_TIME
        RETRY=`expr $RETRY - 1`
        echo $RETRY
    done

    # Check agent process
    if ! is_agent_running; then
        echo `date` : Failed to start Agent.
        return 1
    fi
    echo `date` : Agent started
    return 0
}

echo `date` : Backup agent data.
pushd $DSA_WORK_DIR
    rm -rf backup_*
    mkdir -p $BACKUP_DIR
    # backup everything except diag, downloads and relay directories.
    ls | grep -v diag | grep -v downloads | grep -v relay | grep -v $BACKUP_DIR | xargs -I{} cp -r {} $BACKUP_DIR/
popd
echo

echo `date` : Reset agent.
$DSA_CONTROL -r
echo

sleep 5

if [ -n "$DSM_PROXY" ]; then
    echo `date` : Set DSM proxy.
    $DSA_CONTROL -x $DSM_PROXY
    if [ -n "$DSM_PROXY_CRED" ]; then
        echo `date` : Set DSM proxy credential.
        $DSA_CONTROL -u $DSM_PROXY_CRED
    fi
fi
if [ -n "$RELAY_PROXY" ]; then
    echo `date` : Set relay proxy.
    $DSA_CONTROL -y $RELAY_PROXY
    if [ -n "$RELAY_PROXY_CRED" ]; then
        echo `date` : Set relay proxy credential.
        $DSA_CONTROL -w $RELAY_PROXY_CRED
    fi
fi

echo `date` : Set C1WS public CA certificate.
rm $DSA_WORK_DIR/dsa_core/ds_agent_dsm_public_ca.crt
mv $DSM_PUB_CA_FILE $DSA_WORK_DIR/dsa_core/ds_agent_dsm_public_ca.crt
echo

echo `date` : Activate agent to C1WS.
($DSA_CONTROL -a $DSM_URL $TENANT_ID $TOKEN $MOVE_ID $POLICY_ID $RELAY_ID $GROUP_ID) &
pid=$!

# Kill dsa_control process after timeout
(sleep $ACTIVATION_WAIT_TIME; kill -9 $pid) &
killer_pid=$!

# Wait for dsa_control process to finish or killed by timeout
wait $pid
if [ "$?" = "0" ]; then
    kill $killer_pid
    echo `date` : Activated agent to C1WS successfully
else
    # Restore agent
    echo `date` : Activation failed
    echo
    echo `date` : Stop agent service
    if ! agent_stop; then
        echo `date` : Unable to stop the agent. Agent restore failed.
        rm $DSA_WORK_DIR/dsa_core/ds_agent_dsm_public_ca.crt
        exit 1
    fi
    echo
    echo `date` : Restore backup
    pushd $DSA_WORK_DIR
        ls | grep -v diag | grep -v downloads | grep -v relay | grep -v $BACKUP_DIR | xargs -I{} rm -rf {}
        cp -r $BACKUP_DIR/* .
    popd
    # Agent will trigger the heartbeat after agent start if following file is present.
    # DSM does not need to wait for schedule heartbeat to know the status.
    touch $DSA_WORK_DIR/dsa_move.failed
    echo
    echo `date` : Start agent service
    if ! agent_start; then
        echo `date` : Unable to start the agent. Agent restore failed.
        rm $DSA_WORK_DIR/dsa_move.failed
        exit 1
    fi
fi

rm -rf  $DSA_WORK_DIR/$BACKUP_DIR
