#!/bin/bash
#
# SAPHanaController
#
# Description:  Manages SAP Convergent Mediation Control Zone
#
##############################################################################
#
# SAPHanaController (short saphana)
# Author:       Fabian Herschel, October 2023
# Support:      linux@sap.com
# License:      GNU General Public License (GPL)
# Copyright:    (c) 2023 SUSE LLC
#
# An example usage:
#      See usage() function below for more details...
#
# OCF instance parameters:
#   OCF_RESKEY_USER             - the linux user to control the CM control-zone
#   OCF_RESKEY_SHUTDOWN_RETRIES (optional, do not mix-up with migration threshold)
#   OCF_RESKEY_VERBOSE_STATUS   (optional, defaults to no)
#
#######################################################################
SAPHanaControllerVersion="0.0.2"
#
# Initialization:
export raType="mz_"
OCF_FUNCTIONS_DIR="${OCF_FUNCTIONS_DIR:-${OCF_ROOT}/lib/heartbeat}"
# shellcheck source=/dev/null
source "${OCF_FUNCTIONS_DIR}/ocf-shellfuncs"
#
#######################################################################
#

function mz_call()
{
    # TODO: Check, if we need to switch user (su) for the mzshell action or if we (at least for status-check) could call it as user root to avoid problems with e.g. active directory
    # TODO: Implement 'timeout'
    local rc="$OCF_ERR_GENERIC" timeout=0, user="$mz_user", action="status", component="platform"
    while [ $# -gt 0 ]; do
        case "$1" in
            --user=* )  user=${1#*=} ;;
            --action=* )  action=${1#*=} ;;
            --timeout=* )  timeout=${1#*=} ;;
            --component=* )  component=${1#*=} ;;
        esac
        shift
    done

    case "$action" in
        status )
                # we might need 1-2 retries, lets check if we only need to retry, if the status runs into a timeout
                # can be called WITHOUT su
                if "$mz_shell"  status | grep -q "$component is running"; then
                    ocf_log info "mz_call: $component is running"
                    rc="$OCF_SUCCESS"
                else
                    ocf_log info "mz_call: $component is NOT running"
                    rc="$OCF_NOT_RUNNING"
                fi
                ;;
        startup )
                # needs to switch-user to <mzadmin>
                if su - "$user" "$mz_shell" startup "$component" | grep -qi "starting $component...done."; then
                    ocf_log info "mz_call: $component is started"
                    rc="$OCF_SUCCESS"
                else
                    ocf_log info "mz_call: $component is NOT started"
                    rc="$OCF_NOT_RUNNING"
                fi
                    ;;
        shutdown )
                # needs to switch-user to <mzadmin>
                if su - "$user" "$mz_shell" shutdown "$component" | grep -q "Shutting down $component...done."; then
                    ocf_log info "mz_call: $component is stopped"
                    rc="$OCF_SUCCESS"
                else
                    ocf_log info "mz_call: $component is still NOT stopped"
                    rc="$OCF_ERR_GENERIC"
                fi
                    ;;
        restart )
                # needs to switch-user to <mzadmin>
                if su - "$user" "$mz_shell" restart "$component" | grep -q "Starting $component...done."; then
                    rc="$OCF_SUCCESS"
                else
                    rc="$OCF_ERR_GENERIC"
                fi
                ;;
        kill )
                # needs to switch-user to <mzadmin>
                if su - "$user" "$mz_shell"  kill "$component" | grep -q "killing $component\.*done."; then
                    ocf_log info "mz_call: killing $component successful"
                    rc="$OCF_SUCCESS"
                else
                    ocf_log info "mz_call: killing $component NOT successful"
                    rc="$OCF_ERR_GENERIC"
                fi
                ;;
        * ) 
                # not implemented
                rc="$OCF_ERR_UNIMPLEMENTED"
    esac
    return "$rc"
}

function mz_usage()
{
    echo "usage: ..."
}

function mz_init()
{
    # TODO: init variables
    mz_user="${OCF_RESKEY_USER:-mzuser}"
    mz_shell="${OCF_RESKEY_MZSHELL:-/usr/bin/mzsh}"
    mz_component="${OCF_RESKEY_SERVICE:-platform}"
}

function mz_meta_data()
{
   echo '<?xml version="1.0"?>
<!DOCTYPE resource-agent SYSTEM "ra-api-1.dtd">
<resource-agent name="SAPCMControlZone" version="$raVersion">
<version>1.1</version>
<shortdesc lang="en">Manages SAP convergent Mediation Control Zone.</shortdesc>
<longdesc lang="en">Manages SAP convergent Mediation Control Zone.</longdesc>
<parameters>
<parameter name="USER" unique="0" required="1">
    <longdesc lang="en">Linux user to control the CM component.</longdesc>
    <shortdesc lang="en">Linux user to control the CM component.</shortdesc>
    <content type="string" default="" />
</parameter>
<parameter name="SERVICE" unique="0" required="1">
    <longdesc lang="en">convergent mediation service/component</longdesc>
    <shortdesc lang="en">convergent mediation service/component</shortdesc>
    <content type="string" default="" />
</parameter>
</parameters>
<actions>
    <action name="start"   timeout="120" />
    <action name="stop"    timeout="120" />
    <action name="monitor" timeout="60" interval="120" />
    <action name="validate-all" timeout="5" />
    <action name="meta-data" timeout="5" />
    <action name="methods" timeout="5" />
    <action name="reload" timeout="5" />
</actions>
</resource-agent>
   '
}

function mz_check_params()
{
    local rc="$OCF_SUCCESS"
    # TODO: Change this fucntion to check the really needed parameters
    #if  [ -z "$OCF_RESKEY_SID" ]
    #then
    #    ocf_log err "ACT: Please set parameter SID!"
    #    exit "$OCF_ERR_ARGS"
    #fi
    return "$rc"
}

function mz_start()
{
    local rc="$OCF_SUCCESS"
    mz_call --timeout=60 --action=startup --component="$mz_component" --user="$mz_user"; rc="$?"
    # TODO; map to cluster return code (OCF_*)
    return "$rc"
}

function mz_stop()
{
    local rc="$OCF_SUCCESS"
    # TODO: retry 
    mz_call --timeout=60 --action=shutdown --component="$mz_component" --user="$mz_user"; rc="$?"
    # TODO; map to cluster return code (OCF_*)
    return "$rc"
}

function mz_reload()
{
    local rc="$OCF_SUCCESS"
    return "$rc"
}

function mz_monitor()
{
    local rc="$OCF_SUCCESS"
    # TODO: retry 
    mz_call --timeout=60 --action=status --component="$mz_component" --user="$mz_user"; rc="$?"
    # TODO; map to cluster return code (OCF_*)
    return "$rc"
}

# function: main - main function to operate
# params:   ACTION
# globals:  OCF_*(r), CLACT(w), ra_rc(rw), $0(r)
#

if [ "$#" != "1" ]
then
    "${raType}"usage
    exit "$OCF_ERR_ARGS"
fi

ACTION="$1"
if [ "$ACTION" = "status" ]; then
    ACTION=monitor
fi

# These operations don't require OCF parameters to be set
case "$ACTION" in
    usage|methods)  "${raType}""$ACTION"
                    exit "$OCF_SUCCESS";;
    meta-data)      "${raType}"meta_data
                    exit "$OCF_SUCCESS";;
    notify)         # just ignore
                    exit "$OCF_SUCCESS";;
esac
"${raType}"init

# check for root user
if ! ocf_is_root
then
    ocf_log err "ACT: $0 must be run as root"
    exit "$OCF_ERR_PERM"
fi


# parameter check
"${raType}check_params"
ra_rc="$OCF_ERR_UNIMPLEMENTED"
case "$ACTION" in
    start|stop|monitor|promote|demote) # Standard controlling actions
        "${raType}""$ACTION$CLACT"
        ra_rc="$?"
        ;;
    validate-all)
        "${raType}"validate
        ra_rc="$?"
        ;;
    reload)
        ra_rc="$OCF_SUCCESS"
        ;;
    *)  # seems to be an unknown request
        "${raType}"methods
        ra_rc="$OCF_ERR_UNIMPLEMENTED"
        ;;
esac
exit "${ra_rc}"
# set ts=4 sw=4 sts=4 et
