#!/bin/ksh
#  ALTRAN_PROLOG_BEGIN_TAG
#  This is an automatically generated prolog.
#
#  Copyright (C) Altran ACT S.A.S. 2017,2021.  All rights reserved.
#
#  ALTRAN_PROLOG_END_TAG
#
# IBM_PROLOG_BEGIN_TAG 
# This is an automatically generated prolog. 
#  
# 61haes_r714 src/43haes/usr/sbin/cluster/events/release_takeover_addr.sh 1.4.9.1 
#  
# Licensed Materials - Property of IBM 
#  
# COPYRIGHT International Business Machines Corp. 1990,2013 
# All Rights Reserved 
#  
# US Government Users Restricted Rights - Use, duplication or 
# disclosure restricted by GSA ADP Schedule Contract with IBM Corp. 
#  
# IBM_PROLOG_END_TAG 
# @(#)  7d4c34b 43haes/usr/sbin/cluster/events/release_takeover_addr.sh, 726, 2147A_aha726, Feb 05 2021 09:50 PM
#########################################################################
#
#   COMPONENT_NAME: EVENTS
#
#   FUNCTIONS: none
#
#########################################################################

#########################################################################
#                                                                       #
#       Name:           release_takeover_addr                           #
#                                                                       #
#	Description:	This script is called if the local node has 	#
#			the remote node's service address on its	#
#			standby adapter, and either the remote node	#
#			re-joins the cluster or the local node 		#
#			leaves the cluster gracefully.			#
#									#
#	Called by:	node_down_local, node_up_remote			#
#									#
#       Calls to:       cl_swap_IP_address, cl_release_sna_dlc          #
#									#
#       Arguments:      takeover-address...                             #
#                                                                       #
#       Returns:        0       success                                 #
#                       1       failure                                 #
#                       2       bad argument                            #
#                                                                       #
#########################################################################
###############################################################################
# Name: get_inet_family
#
# The routines returns the internet family of the given IP label.
#
# Arguments: IP address
#
# Returns: unspec: unknown family
#          inet:   AF_INET family (IPv4 IP address)
#          inet6:  AF_INET6 family (IPv6 IP address)
#
###############################################################################
get_inet_family() {
    typeset PS4_FUNC="get_inet_family"
    [[ "$VERBOSE_LOGGING" = "high" ]] && set -x
    ip_label=$1
    inet_family=$(cllsif -J "$OP_SEP" -Sn $ip_label | awk -F"$OP_SEP" '{print $15}')
    case "$inet_family" in
    	AF_INET)
        	echo "inet"
        	return
        	;;
		AF_INET6)
		    echo "inet6"
        	return
        	;;
        *)
		dspmsg scripts.cat 9503 "\n$PROGNAME: ERROR: Invalid address \
family for IP address \"$ip_label\".\n" $PROGNAME $ip_label
			exit 1
			;;
	esac
}
#########################################################################

#
# This routine maps a label_address to the internet_textual_address.
# Thus, given a label_address, we do not require the name server
# to get its corresponding textual address.
#
name_to_addr () {
	typeset PS4_FUNC="name_to_addr"
        echo $(cllsif -J "$OP_SEP" -Sn $1 | cut -d"$OP_SEP" -f7\
                 | uniq)
        exit $?
}


get_list_head()
{
    typeset PS4_FUNC="get_list_head"
    echo $* | cut -f 1 -d : | sed 's/,/ /g' |read LIST
    print $LIST
}

get_list_tail()
{
    typeset PS4_FUNC="get_list_tail"
    case $* in
      *:* )
        echo $* | cut -f 2- -d : |read LIST
        print $LIST
        return
      ;;
      * )
       echo ""
      ;;
     esac
}


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

[[ "$VERBOSE_LOGGING" = "high" ]] && set -x
[[ "$VERBOSE_LOGGING" = "high" ]] && version='%I%'
OP_SEP="$(cl_get_path -S)"

STATUS=0

if [ ! -n "$EMULATE" ]
then
        EMULATE="REAL"
fi



PROC_RES=false

# if JOB_TYPE is set, and it doesn't equal to "GROUP", then 
# we are processing for process_resources
if [[ ${JOB_TYPE:-0} != 0 && $JOB_TYPE != "GROUP" ]]; then
   PROC_RES=true
   _SNA_CONNECTIONS=$COMMUNICATION_LINKS
   _IP_LABELS=$IP_LABELS

else
    if [ $# -eq 0 ]
    then
	    cl_echo 1029 "Usage: $PROGNAME takeover-address..\n" $PROGNAME
	    exit 2
    fi

    export RESOURCE_GROUPS=$GROUPNAME
 
fi




#########################################################################
#
#  main routine
#
#########################################################################

# Change NSORDER
saveNSORDER=${NSORDER:-UNDEFINED}
NSORDER=local; export NSORDER

#set -u

#
# go through all resource groups
# for serial groups, this will be once only
for GROUPNAME in $RESOURCE_GROUPS ; do
    
    export GROUPNAME

    if [[ $PROC_RES = true ]]; then
	get_list_head $IP_LABELS | read SERVICELABELS
	get_list_tail $IP_LABELS | read IP_LABELS
        
	get_list_head $_SNA_CONNECTIONS |read SNA_CONNECTIONS
	export SNA_CONNECTIONS
	get_list_tail $_SNA_CONNECTIONS | read _SNA_CONNECTIONS
    else
	SERVICELABELS=$*
    fi

    # update the resource manager with this operation
    ALLSRVADDRS="All_service_addrs"
    if [ "$EMULATE" = "EMUL" ]
    then
	cl_echo 3020 "NOTICE >>>> The following command was not executed <<<<  \n"
	echo "cl_RMupdate resource_releasing $ALLSRVADDRS $PROGNAME \n"
    else
        cl_RMupdate resource_releasing $ALLSRVADDRS $PROGNAME
    fi

    for addr in $SERVICELABELS
    do
	#
	# Determine if address is already unconfigured.  If not, try to
	# release it. If hostname or interface not found, clgetif will
	# print error. If hostname not found fail event.
	#
	LC_ALL=C clgetif -a $addr
	return_code=$?
	if [ $return_code -ne 0 ]
	then
	    # Only fail the event if hostname not found (return_code = 1)
	    # If interface not found then already unconfigured so drop through
	    if [ $return_code -eq 1 ]
	    then
                if [[ $PROC_RES = true ]]; then
		    if [ "$EMULATE" = "EMUL" ]
		    then
			cl_echo 3020 "NOTICE >>>> The following command was not executed <<<<  \n"
			echo "cl_RMupdate resource_error $addr $PROGNAME \n"
		    else
                        cl_RMupdate resource_error $addr $PROGNAME
		    fi
                    STATUS=11
                    continue
		else
            # If interface not found error comes (rc=3), then it means
            # and address was not configure on interface, so during clstop
            # we just need to ignore that
            if [[ $return_code == 3 ]]
            then
                exit 0
            else
		        exit 1
            fi
		fi
	    fi
	else
	    STBY_IP_ADDR=""
	    addr_textual_addr=$(name_to_addr $addr)
	    
	    #
	    # Get the standby interface to which the remote service address is mapped.
	    #
	    STBY_INTERFACE=$(LC_ALL=C clgetif -a $addr_textual_addr)
	    
	    if [ "$STBY_INTERFACE" = "" ]
	    then
		cl_echo 318 "No service address $addr was taken by this node." $addr
		continue
	    fi
	    
	    # Release SNA resources if part of resource group
	    #

	    if [[ $PROC_RES = false ]]; then
		set -a
		eval $(clsetenvres $GROUPNAME $PROGNAME)
		set +a
	    fi

	    # Before we release or acquire any SNA links, we must first
	    # filter out the WAN communications links list.  We only need
	    # to call cl_release_sna_dlc or cl_acquire_sna_dlc for
	    # SNA over LAN type links.
	    SNA_LAN_LINKS=""
	    for link in $SNA_CONNECTIONS
	    do
		LINKTYPE=$(cllscommlinks -C -t All \
		  | awk -F: '($1 == "'$link'") {print $2}')
		if [[ $LINKTYPE = "snalan" ]]; then
		    SNA_LAN_LINKS="$SNA_LAN_LINKS $link"
		fi
	    done
	    SNA_CONNECTIONS=$SNA_LAN_LINKS	    

	    if [[ -n "$SNA_CONNECTIONS" ]]
	    then
		if [ "$EMULATE" = "EMUL" ]
		then
		    cl_echo 3020 "NOTICE >>>> The following command was not executed <<<<  \n"
		    echo "cl_release_sna_dlc $STBY_INTERFACE \n"
		else
		    # cl_release_sna_dlc checks to make sure interface is SNA
		    cl_release_sna_dlc $STBY_INTERFACE
		fi
	    fi
	    
	    if [ $? -ne 0 ]
	    then
		cl_echo 4170 "$PROGNAME: Failure occurred while releasing SNA DLC profiles.\nManual intervention required.\n" $PROGNAME
                
		if [[ $PROC_RES = true ]]; then
		    if [ "$EMULATE" = "EMUL" ]
		    then
			cl_echo 3020 "NOTICE >>>> The following command was not executed <<<<  \n"
			echo "cl_RMupdate resource_error $addr $PROGNAME \n"
		    else
                        cl_RMupdate resource_error $addr $PROGNAME
		    fi
                    STATUS=11
                    continue
                else
		    STATUS=1
		fi
	    fi
	    
	    #
	    # Get the netmask for invocation of swap_IP_address
	    #
	    NETMASK=$(LC_ALL=C clgetif -n $addr_textual_addr)
	    
	    #
	    # Reconfigure the standby.
	    #
	    # pass the service as both parameters to cl_swap_IP_address -
	    # it will discover the standby address to put back on the intf
	    STBY_IP_ADDR=$addr_textual_addr
	    
	    if [ "$EMULATE" = "EMUL" ]
	    then
		    cl_echo 3020 "NOTICE >>>> The following command was not executed <<<<  \n"
		    echo "cl_swap_IP_address cascading release $STBY_INTERFACE $STBY_IP_ADDR $addr_textual_addr $NETMASK \n"
	    else
		INET_FAMILY=$(get_inet_family $addr_textual_addr)
            	if [[ "$INET_FAMILY" = "inet6" ]]  
            	then
                	cl_swap_IPv6_address cascading release $STBY_INTERFACE \
                    		$STBY_IP_ADDR $addr_textual_addr
            	else
                	cl_swap_IP_address cascading release $STBY_INTERFACE \
                    		$STBY_IP_ADDR $addr_textual_addr $NETMASK
            	fi  
	    fi

	    RC=$?

	    # Check return code
	    if [ $RC -ne 0 ]
	    then
		if [[ $PROC_RES = true ]]; then
			if [[ $RC != 11 ]]; then
			    if [ "$EMULATE" = "EMUL" ]
			    then
				cl_echo 3020 "NOTICE >>>> The following command was not executed <<<<  \n"
				echo "cl_RMupdate resource_error $addr $PROGNAME \n"
			    else
			        cl_RMupdate resource_error $addr $PROGNAME
			    fi
			fi
			
			STATUS=11
			
	    	else
			STATUS=1
		 fi
	    fi
	fi
    done
    # update the resource manager with the results
    ALLNOERRSRV="All_nonerror_service_addrs"
    if [ "$EMULATE" = "EMUL" ]
    then
	cl_echo 3020 "NOTICE >>>> The following command was not executed <<<<  \n"
	echo "cl_RMupdate resource_down $ALLNOERRSRV $PROGNAME \n"
    else
        cl_RMupdate resource_down $ALLNOERRSRV $PROGNAME
    fi

done #for GROUPNAME in RESOURCE_GROUPS

if [[ $saveNSORDER != UNDEFINED ]]; then
  export NSORDER=$saveNSORDER
else
  export NSORDER=""
fi

exit $STATUS

