#!/usr/bin/bash

# SHLINT:yes
# Copyright (c) 2020 by NetApp, Inc.
# All Rights Reserved.

#
# This scripts starts the embedded KMIP server
#

readonly KMIP_SERVER_DIR="/cfcard/kmip/server"
readonly KMIP_SERVER_LOG_DIR="/mroot/etc/log/mlog"

readonly KMIP_SERVER_CFG_FILE="${KMIP_SERVER_DIR}/server.cfg"
readonly KMIP_DB_FILE="${KMIP_SERVER_DIR}/kmip.db"

# for starting the KMIP server
readonly KMIP_SERVER="/usr/sbin/kmip_server"
readonly KMIP_SERVER_LOG="${KMIP_SERVER_LOG_DIR}/kmip_server_`date +%s`.log"
readonly SCRIPT_LOG="${KMIP_SERVER_DIR}/netapp_start_ekmip.log"
readonly RECOVER_SERVER_CFG="${KMIP_SERVER_DIR}/netapp_recover_server_cfg.sh"

readonly AWK="/usr/bin/awk"
readonly FILE="/usr/bin/file"
readonly GREP="/usr/bin/grep"
readonly PS="/bin/ps"

# for debugging
readonly DEBUG=1
readonly EXTRA_DEBUG=0

ARG=$1

PWD=`pwd`

if [ ${EXTRA_DEBUG} -eq 1 ]; then
    echo "DEBUG: **** netapp_start_ekmip.sh called at `date` (`date +%s`)"
fi

#
# This and the "trap" line that follow were added since we were
# seeing kmip_server crashes when ONTAP rebooted.
#
function kill_kmip_server_at_reboot
{
    process_id=`${PS} ax | ${GREP} "${KMIP_SERVER}" | ${GREP} -v "${GREP}" | ${AWK} '{print $1}'`
    sleep 1
    rebooting=`sysctl kern.init_stopping | ${GREP} -c 1`
    if [ ${rebooting} -eq 1 ]; then
        # rebooting...
        kill -s KILL ${process_id}
        echo "Sent KILL to ${process_id} at `date` (`date +%s`)" >> ${SCRIPT_LOG}
    fi
}

trap 'kill_kmip_server_at_reboot' 15

function check_prerequisites
{
    local retVal=0

    if [ ! -d ${KMIP_SERVER_DIR} ]; then
        retVal=1
    fi

    if [ ! -f ${KMIP_SERVER_CFG_FILE} ]; then
        retVal=2
    fi

    if [ ! -f ${KMIP_DB_FILE} ]; then
        retVal=3
    fi

    return $retVal
}

# check if file is an ASCII file (returns 0 if it is ASCII)
is_server_cfg_ascii()
{
    ${FILE} $1 | ${GREP} -q "ASCII text"

    echo -n $?
}

function check_server_cfg
{
    local retVal=0
    local is_corrupted

    is_corrupted=$(is_server_cfg_ascii ${KMIP_SERVER_CFG_FILE})
    # check if server.cfg needs to be recovered
    if [ ! -s ${KMIP_SERVER_CFG_FILE} ] || [ "${is_corrupted}" == "1" ]; then
	# need to recover server.cfg
	${RECOVER_SERVER_CFG}
	retVal=$?
    fi

    return $retVal
}

function start_server
{
    local retVal=0
    local args=""
    local wait=0

    if [ ${DEBUG} -eq 1 ]; then
        echo "starting kmip_server with args=$@ at `date` (`date +%s`)" >> ${SCRIPT_LOG}
    fi

    # among the arguments that kmip_server uses are:
    # debug ext_debug ssl_debug ssl_verbose whine verbose
    for var in "$@"
    do
        if [ "$var" == "wait" ]; then
            wait=1
        else
            args="${args} ${var}"
        fi
    done

    ${KMIP_SERVER} ${args} > ${KMIP_SERVER_LOG} 2>&1 &
    retVal=$?

    if [ ${EXTRA_DEBUG} -eq 1 ]; then
      echo "DEBUG: **** retVal from starting ${KMIP_SERVER} = ${retVal}" >> ${SCRIPT_LOG}
    fi

    # need to allow enough time for pid to show up in "ps"
    sleep 1

    process_id=`${PS} ax | ${GREP} "${KMIP_SERVER}" | ${GREP} -v "${GREP}" | ${AWK} '{print $1}'`
    if [ ${DEBUG} -eq 1 ]; then
      echo "DEBUG: **** kmip_server pid = ${process_id}" >> ${SCRIPT_LOG}
    fi

    if [ -n ${process_id} ] && [ "${wait}" == "1" ]; then
        wait ${process_id}
        if [ ${DEBUG} -eq 1 ]; then
            echo "DEBUG: **** wait for pid ${process_id} ended at `date` (`date +%s`)" >> ${SCRIPT_LOG}
        fi
    fi

    return $retVal
}

check_prerequisites
if [ $? -ne 0 ]; then
    exit $?
fi

cd ${KMIP_SERVER_DIR}

# needs to be done before kmip_server started up
check_server_cfg
ret=$?
if [[ $ret -ne 0 ]]; then
    cd $PWD
    echo "Error recovering ${KMIP_SERVER_CFG} at `date` (`date +%s`)" >> ${SCRIPT_LOG}
    exit $ret
fi

# for debuging remove comment
#start_server $@ debug ext_debug ssl_debug ssl_verbose whine verbose
start_server $@
if [ $? -ne 0 ]; then
    echo "${KMIP_SERVER} failed to start: $? at `date` (`data +%s`)" >> ${SCRIPT_LOG}
    cd $PWD
    exit $?
fi

cd $PWD
exit 0
