#!/bin/ksh93
#  ALTRAN_PROLOG_BEGIN_TAG
#  This is an automatically generated prolog.
#
#  Copyright (C) Altran ACT S.A.S. 2017,2018,2019,2020,2021.  All rights reserved.
#
#  ALTRAN_PROLOG_END_TAG
#
# @(#)  7d4c34b 43haes/usr/sbin/cluster/events/admin_op.sh, 726, 2147A_aha726, Feb 05 2021 09:50 PM


#########################################################################
#                                                                       
#       Name:           admin_op                               
#                                                                     
#       Description:    Administrators interact with PowerHA through a
#                       few different interfaces including clmgr, smit
#                       and some command line utilities. These administrative
#                       operations allow for starting and stopping cluster
#                       services, suspend/resume application monitoring, etc.
#                       This event is run in response to administrator
#                       operations and allows for configuration of 
#                       pre/post and notify methods for the event: this 
#                       allows for additional notifications to be run when
#                       an administrator runs a command. 
#                       Note that any error returned by a pre/post or notify
#                       method will effectively "cancel" the administrator
#                       operation, that is, no event will occur in response.
#                                                                     
#       Called by:      cluster manager                              
#                                                                   
#       Calls to:       None                                       
#                                                                 
#       Arguments:      operation type - the type of operation requested
#                       serial number - serial number for the event
#                       operation valid - boolean indication the admin op
#                                         passed validation
#
#
#       Returns:        This script always returns 0
#
#########################################################################

#########################################################################
#                                                                       
#       Name:           sigint_handler                               
#                                                                     
#       Description:    Catches an INT signal
#
#       Arguments:      None
#
#       Returns:        Always exits 0
#
#########################################################################
sigint_handler ()
{

    typeset PS4_FUNC="sigint_handler"
    # this is not expected, so there is no nls enabled message
    echo "Internal error occurred processing $PROGNAME\nPlease contact IBM support\n"
    exit 0
}


#########################################################################
# Main
#########################################################################
PROGNAME=${0##*/}
export PATH="$(/usr/es/sbin/cluster/utilities/cl_get_path all)"

#
# Some admin ops like "apply snapshot" can be run before there is
# an initial config, in which case the local node name will not be
# set - in that case we avoid cllsparam and use our own defaults
#
if [[ -n $LOCALNODENAME ]]
then
    set -a
    eval $(cllsparam -n $LOCALNODENAME)
    set +a
else
    export VERBOSE_LOGGING="high"
    export LC_ALL='C'
fi

#
# Common definitions (initialize prior to tracing)
#
USER_RG_MOVE=1
USER_RG_ONLINE=2
USER_RG_OFFLINE=3
USER_RG_ONLINE_SECONDARY=4
USER_RG_OFFLINE_SECONDARY=5
USER_RG_MOVE_SECONDARY=6
USER_RG_MOVE_CROSS_SITE=7
USER_RG_MOVE_CROSS_SITE_SECONDARY=8
USER_RG_ONLINE_CROSS_SITE=9
USER_RG_OFFLINE_CROSS_SITE=10
USER_RG_ONLINE_CROSS_SITE_SECONDARY=11
USER_RG_OFFLINE_CROSS_SITE_SECONDARY=12

# catch undefined variables
set -u

[[ "$VERBOSE_LOGGING" == "high" ]] && {
    set -x
}

# setup signal handler 
trap sigint_handler INT

#
# Accumulate the inputs - this is only called from clstrmgr so there is
# no checking
#
typeset OP_TYPE=$1
integer SERIAL=$2
integer INVALID=$3


#
# Want to avoid double output of messages when tracing is on
#
set +x

dspmsg -s 42 scripts.cat 42 "The administrator initiated the following action at $(LC_ALL=C date)\nCheck smit.log and clutils.log for additional details.\n" $(LC_ALL=C date)

#
# The clstrmgr does some checking to make sure the operation is valid, e.g.
# stopping cluster services only if services are active - if that validation
# failed we still log it, but with and explanatory message
#
if (( INVALID ))
then
    dspmsg -s 106 events.cat 1 "The following administrative operation is not valid.\n"
    # additional information is logged below
fi

#
# Log specific actions
#
case $OP_TYPE in
    #
    # Variations on start cluster services
    #
    clrm_start_request) 
        dspmsg -s 2 ezupdate.cat 7 "Starting PowerHA cluster services on node: %1\$s in %2\$s mode...\n" $LOCALNODENAME "normal"
    ;;
    clrm_inactive_start_request)
        dspmsg -s 2 ezupdate.cat 7 "Starting PowerHA cluster services on node: %1\$s in %2\$s mode...\n" $LOCALNODENAME "inactive startup"
    ;;
    clrm_manual_start_request) 
        dspmsg -s 2 ezupdate.cat 7 "Starting PowerHA cluster services on node: %1\$s in %2\$s mode...\n" $LOCALNODENAME "manual startup"
    ;;
    clrm_manual_nfs_start_request) 
        dspmsg -s 2 ezupdate.cat 7 "Starting PowerHA cluster services on node: %1\$s in %2\$s mode...\n" $LOCALNODENAME "normal with nfs processing"
    ;;

    #
    # Variations on stop cluster services
    #
    clrm_stop_request) # stop mode is taken from the environment
        dspmsg -s 2 ezupdate.cat 1 "Stopping PowerHA cluster services on node: %1\$s in %2\$s mode...\n" $LOCALNODENAME $ADMIN_OP_MISC_DATA
    ;;

    # User requested resource group move
    user_rg_move) # rg move parameters are taken from the environment
        dspmsg -s 50 cluster.cat 3 "Move a Resource Group to Another Node / Site"
        echo $ADMIN_OP_MISC_DATA | read \
            GROUP_ID MOVE_TYPE TARGET RESTORE REST

        #
        # Translate ids to strings
        #
        rg=$(clodmget -q "id = $GROUP_ID" -f group -n HACMPgroup)
        node=$(clodmget -q "node_id = $TARGET AND object = VERBOSE_LOGGING" -f name -n HACMPnode)
        restore="true"
        [[ $RESTORE == "0" ]] && restore="false"

        #
        # first, an informational message telling what we will be trying
        #
        if [[ $MOVE_TYPE == $USER_RG_MOVE ||
              $MOVE_TYPE == $USER_RG_MOVE_SECONDARY ]]; then
            if [[ $restore == "true" ]]; then
                dspmsg scripts.cat 9314 \
                    "Attempting to move resource group $rg to the highest priority\n\
available node.\n" $rg
            else
                dspmsg scripts.cat 9315 \
                    "Attempting to move resource group $rg to node $node.\n" \
                    $rg $node
            fi
        elif [[ $MOVE_TYPE == $USER_RG_MOVE_CROSS_SITE ||
                $MOVE_TYPE == $USER_RG_MOVE_CROSS_SITE_SECONDARY ]]; then
            if [[ $restore == "true" ]]; then
                dspmsg scripts.cat 9358 \
                    "Attempting to move resource group $rg to the highest priority\n\
available site.\n" \
                    $rg
            else
                # in this case target is a site id
                site=$(clodmget -q "id = $TARGET" -f name -n HACMPsite)
                if [[ $MOVE_TYPE == $USER_RG_MOVE_CROSS_SITE ]]; then
                    dspmsg scripts.cat 9359 \
                        "Attempting to move resource group $rg to site $site.\n" \
                        $rg $site
                else
                    dspmsg scripts.cat 9368 \
                        "Attempting to move secondary instance(s) of resource group\n\
$rg to site $site.\n" \
                        $rg $site
                fi
            fi
        elif [[ $MOVE_TYPE == $USER_RG_ONLINE ]]; then
            if [[ $restore == "true" ]]; then
                dspmsg scripts.cat 9316 \
                    "Attempting to bring group $rg online on the highest\n\
priority available node.\n" \
                    $rg
            else
                dspmsg scripts.cat 9317 \
                    "Attempting to bring group $rg online on node $node.\n" \
                    $rg $node
            fi
        elif [[ $MOVE_TYPE == $USER_RG_ONLINE_SECONDARY ]]; then

            if [[ $restore == "true" ]]; then
                dspmsg scripts.cat 9366 \
                    "Attempting to bring group $rg online secondary on\n\
the highest priority available node.\n" \
                    $rg
            else
                dspmsg scripts.cat 9367 \
                    "Attempting to bring group $rg online secondary\n\
on node $node.\n" \
                    $rg $node
            fi
        elif [[ $MOVE_TYPE == $USER_RG_OFFLINE ||
                $MOVE_TYPE == $USER_RG_OFFLINE_SECONDARY ]]; then
            [[ $node != -1 ]] && dspmsg scripts.cat 9318 \
                "Attempting to bring group $rg offline on node $node.\n" \
                $rg $node
        fi # done printing informative message
    ;;
    #
    # Suspend and resume applicaiton monitoring
    #
    suspend_appmon) # suspend 
        dspmsg -s 14 cluster.cat 216 "Suspend Application Monitor(s) for Application Controller"

        # misc data contains the monitor id and list of nodes or "ALL"
        app_id=$(echo $ADMIN_OP_MISC_DATA | cut -f1 -d" ")
        clodmget -q"name = APPLICATIONS AND id = $app_id" -f value HACMPresource
        if [[ $(echo $ADMIN_OP_MISC_DATA | cut -f2 -d" ") == "ALL" ]]
        then
            dspmsg -s 107 events.cat 1 "on ALL nodes\n"
        else
            dspmsg -s 107 events.cat 2 "on the following nodes:\n"
            echo ${ADMIN_OP_MISC_DATA##*" "}
        fi

    ;;
    resume_appmon) # resume 
        dspmsg -s 14 cluster.cat 217 "Resume Application Monitor(s) for Application Controller"

        # misc data contains the monitor id and list of nodes or "ALL"
        app_id=$(echo $ADMIN_OP_MISC_DATA | cut -f1 -d" ")
        clodmget -q"name = APPLICATIONS AND id = $app_id" -f value HACMPresource
        if [[ $(echo $ADMIN_OP_MISC_DATA | cut -f2 -d" ") == "ALL" ]]
        then
            dspmsg -s 107 events.cat 1 "on ALL nodes\n"
        else
            dspmsg -s 107 events.cat 2 "on the following nodes:\n"
            echo ${ADMIN_OP_MISC_DATA##*" "}
        fi

    ;;

    # Dynamic Active Reconfiguration Event (DARE)
    clrm_refresh_request) # If the request is valid, call the utility which
        # compares the current and incoming configurations - the output is 
        # not pretty, but we will at least capture the details of the change
        dspmsg -s 107 events.cat 6 "Dynamic Automatic Reconfiguration Event (DARE)\n"
        (( ! INVALID )) && VERBOSE_LOGGING="false" cl_dare_compare -c
    ;;

    # Set the clstrmgr debug level
    clrm_set_debug_level) 
        dspmsg -s 107 events.cat 5 "Set clstrmgr daemon debug level to $ADMIN_OP_MISC_DATA" $ADMIN_OP_MISC_DATA
    ;;

    #
    # Variations on clruncmd
    #
    clrm_recover_script) # clruncmd - recover
        dspmsg -s 104 events.cat 122 "Recover From PowerHA SystemMirror Script Failure"
        dspmsg -s 107 events.cat 3 "and continue current event processing.\n"
    ;;
    clrm_cancel_script) # clruncmd - cancel
        dspmsg -s 104 events.cat 122 "Recover From PowerHA SystemMirror Script Failure"
        dspmsg -s 107 events.cat 4 "and cancel all pending events.\n"
    ;;

    clrm_apply_snapshot) # apply snapshot
        dspmsg -s 107 events.cat 7 "Administrator applied snapshot $ADMIN_OP_MISC_DATA\n" $ADMIN_OP_MISC_DATA
        # Capture state and ps output so we can tell who is running snapshot
        echo ""
        lssrc -ls clstrmgrES
        echo ""
        ps -ef
    ;;
esac


# 
# If the operation is not valid, the code will tell us why
#
if (( INVALID )) 
then
    case $INVALID in
        1 ) 
            dspmsg -s 106 events.cat 2 "Cluster services are in the wrong state for this operation.\n"
        ;;
        2 ) 
            dspmsg -s 106 events.cat 3 "Application monitoring is in the wrong state for this operation.\n"
        ;;
        3 ) 
            dspmsg -s 106 events.cat 4 "The specified Application Monitor could not be found.\n"
        ;;
        4 ) 
            dspmsg -s 106 events.cat 7 "The specified mode is not one of the supported modes.\n"
        ;;
        5 ) 
            dspmsg -s 106 events.cat 5 "Another administrative operation is already being processed.\n"
        ;;
        255 ) 
            dspmsg -s 1 evsum.cat 669 "An internal error occured processing the operation.\nContact IBM support for further assistance.\n"
        ;;

    esac

    # 
    # And a final message to let them know that this operation is ignored
    #
    dspmsg -s 106 events.cat 30 "No events will be run in response.\n"
fi

#
# Notify the clstrmgr that we are done
#
clRMupdate clrm_clcallev_exit 0 $SERIAL

#
# Always exit 0
#
exit 0
