#!/bin/ksh93
#  ALTRAN_PROLOG_BEGIN_TAG                                                    
#  This is an automatically generated prolog.                                  
#                                                                              
#  Copyright (C) Altran ACT S.A.S. 2018,2021.  All rights reserved.  
#                                                                              
#  ALTRAN_PROLOG_END_TAG                                                      
#                                                                              
# IBM_PROLOG_BEGIN_TAG 
# This is an automatically generated prolog. 
#  
# 61haes_r721 src/43haes/usr/sbin/cluster/events/release_service_addr.sh 1.44 
#  
# Licensed Materials - Property of IBM 
#  
# COPYRIGHT International Business Machines Corp. 1990,2016 
# 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_service_addr.sh, 726, 2147A_aha726, Feb 05 2021 09:50 PM
#########################################################################
#                                                                       
# Name:           release_service_addr                            
#                                                                       
# Description:  This script is called when the local node leaves the
#               cluster or a remote node with higher priority joins the 
#               cluster and does the initial processing for releasing 
#               any service IP addresses.
#
# Arguments:    service_address
#
# Returns:      0   success
#               1   fatal error
#               2   bad argument
#               11  recoverable error
#
#########################################################################

#########################################################################
#
# Name:        get_list_head and get_list_tail
#
# Description: utility functions to pull items from the head or tail
#              of a colon delimited list
#
# Inputs:      the list to work on
#
#
# Outputs:     head or tail list of items
#
# Returns:     none
#
#########################################################################
function get_list_head {
    echo $* | cut -f 1 -d : | sed 's/,/ /g' |read LIST
    print $LIST
}

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

#########################################################################
#
# MAIN Main main
#
#########################################################################

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

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

STATUS=0
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
   _IP_LABELS=$IP_LABELS
else
  if (( $# == 0 ))
  then
        cl_echo 1028  "Usage: $PROGNAME service_address...\n" $PROGNAME
	exit 2
  fi
  export RESOURCE_GROUPS=$GROUPNAME  
  
fi

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


# 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
    else
	SERVICELABELS=$*
    fi

    # update the resource manager with this operation
    cl_RMupdate resource_releasing "All_service_addrs" $PROGNAME

    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
	integer return_code=$?
	if (( $return_code ))
	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 == 1 ))
	    then
		if [[ $saveNSORDER != UNDEFINED ]]; then
		    export NSORDER=$saveNSORDER
		else
		    export NSORDER=""
		fi

                if [[ $PROC_RES == true ]]; then
                        cl_RMupdate resource_error $addr $PROGNAME
                    STATUS=11
                    continue
                else
		    exit 1
		fi
	    fi
	else
            textual_addr=$(cllsif -J "$OP_SEP" -Sn $addr | cut -d"$OP_SEP" -f7 | uniq)
	    INTERFACE=$(LC_ALL=C clgetif -a $textual_addr)
	    if [[ -z "$INTERFACE" ]]
	    then
		#
		# No interface found for the service, shouldn't happen, error.
		#
		if [[ $saveNSORDER != UNDEFINED ]]; then
		    export NSORDER=$saveNSORDER
		else
		    export NSORDER=""
		fi

                if [[ $PROC_RES == true ]]; then
                        cl_RMupdate resource_error $addr $PROGNAME
                    STATUS=11
                    continue
                else
		    exit 1
		fi
	      
	    fi

	    NETMASK=$(LC_ALL=C clgetif -n $textual_addr)
	    NETWORK=$(cllsif -J "$OP_SEP" | \
	               grep -wF $textual_addr | cut -d"$OP_SEP" -f3 | sort -u)
			
	    #
	    # Find a boot address on the same network as the service
	    #
	    BOOT=$(cllsif -J "$OP_SEP" -Si $LOCALNODENAME |  \
	           grep "${OP_SEP}boot${OP_SEP}" | cut -d"$OP_SEP" -f3,7 | \
	           grep ^$NETWORK${OP_SEP} | cut -d"$OP_SEP" -f2 | tail -1)
		
	    if [[ -z "$BOOT" ]]
	    then
		#
		# No corresponding boot found, shouldn't happen, error.
		#
		if [[ $saveNSORDER != UNDEFINED ]]; then
		    export NSORDER=$saveNSORDER
		else
		    export NSORDER=""
		fi

                if [[ $PROC_RES == true ]]; then
                        cl_RMupdate resource_error $textual_addr $PROGNAME
                    STATUS=11
                    continue
                else
		    exit 1
		fi
	    fi
        
	    # swap service address back to boot address
	    if [[ -n "$INTERFACE" ]]
	    then
                if [[ $(cllsif -J "$OP_SEP" -Sn $textual_addr | cut -f15 -d"$OP_SEP") == "AF_INET6" ]]  
                then
                    cl_swap_IPv6_address rotating release $INTERFACE $BOOT \
                        $textual_addr 	
                else	
                    cl_swap_IP_address rotating release $INTERFACE $BOOT \
                        $textual_addr $NETMASK
                fi

	        RC=$?
            # Check return code
	        if [[ $RC != 0 ]]
	        then
                    if [[ $PROC_RES == true ]]; then
		        if [[ $RC != 11 ]]; then
			    cl_RMupdate resource_error $textual_addr $PROGNAME
		        fi
		    
		        STATUS=11
		    
                    else
		        STATUS=1
		    fi
	        fi
	  fi
	fi
    done
    
    # update the resource manager with the results
    cl_RMupdate resource_down "All_nonerror_service_addrs" $PROGNAME

done #for GROUPNAME in RESOURCE_GROUPS

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

exit $STATUS
