#!/bin/ksh93 
# IBM_PROLOG_BEGIN_TAG 
# This is an automatically generated prolog. 
#  
# 61haes_r720 src/43haes/usr/sbin/cluster/utilities/cl_restrict_prnet.sh 1.4 
#  
# Licensed Materials - Property of IBM 
#  
# Restricted Materials of IBM 
#  
# COPYRIGHT International Business Machines Corp. 2011,2015 
# 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 
# @(#)81      1.4  src/43haes/usr/sbin/cluster/utilities/cl_restrict_prnet.sh, hacmp, 61haes_r720, 1514B_hacmp720 3/6/15 00:21:12
######################################################################
#
# Name:
#       cl_restrict_prnet
#
# Function:
#       Restrict CAA usage of private networks
#
# Description:
#       CAA usage is restricted by interface.  This routine finds all
#	interfaces on the current node on private networks, and 
#	restricts CAA usage by listing them in /etc/cluster/ifrestrict.
#
# Usage:
#       cl_restrict_prnet -m -v
#	    -m	    Caller will run mkcluster, so this routine need not
#		    run clusterconf
#	    -v	    Provide verbose progress messages
#	    -l	    Log verbose progress messages to clutils.log
#
# Operation:
#       In case of multicast, the interfaces on private networks on the
#	current node are collected from the HACMPnetwork and HACMPadapter ODMs.
#	If these differ from the current contents of /etc/cluster/ifrestrict,
#	then /etc/cluster/ifrestrict is replaced with the new list.
#	/usr/sbin/clusterconf is run, if necessary, to update CAA
#
#	In case of unicast,just return with 1.
#
# Returns:
#       0   success
#       !0  failure return code from invoked command
#
# Questions?  Comments?  Expressions of Astonishment?  mailto:hafeedbk@us.ibm.com
#
######################################################################

if [[ $VERBOSE_LOGGING == "high" ]]
then
    set -x
    version="1.4"
fi

PROGNAME=${0##*/}

#
:   Check cluster heartbeattype.If heartbeattype is unicast, no need to do anything just return.
:   Since in case of unicast no need to restrict the interfaces.
#
if [[ $(clodmget -f heartbeattype -n HACMPcluster) == U* ]]
then
    return 0
fi

#
:   Parse operands
#
m_flag=""			#   mkcluster follows
v_flag=""			#   verbose output
CLUTILS_LOG=""			#   clutils.log path name
while getopts ':mvl' option 
do
    case $option in
	m ) :	mkcluster will be run by caller	;	m_flag="true"	;;
	v ) :	verbose output requested	;	v_flag="true"	;;
	l ) :	Set up path name for log
	    CLUTILS_LOG=$(/usr/es/sbin/cluster/utilities/clodmget -q "name = clutils.log" -f value -n HACMPlogs)
	    if [[ -z $CLUTILS_LOG || ! -d $CLUTILS_LOG ]]
	    then
		CLUTILS_LOG=$(/usr/es/sbin/cluster/utilities/clodmget -q "name = clutils.log" -f default -n HACMPlogs)
	    fi
	    if [[ -z $CLUTILS_LOG || ! -d $CLUTILS_LOG ]]
	    then
		CLUTILS_LOG="/var/hacmp/log"
	    fi
	    CLUTILS_LOG="${CLUTILS_LOG}/clutils.log"
	    ;;
	* ) :	Invalid option
	    USAGE='cl_restrict_prnet [-m] [-v] [-l]'
	    dspmsg -s 30 scripts.cat 1 "${PROGNAME}: Invalid option '$option'\n" $PROGNAME $option
	    print $USAGE
	    return -1
	    ;;
    esac
done

#
: First see if the local node has been configured
#
LOCAL_NODE=${LOCAL_NODE:-$(/usr/es/sbin/cluster/utilities/get_local_nodename)}
if [[ -z $LOCAL_NODE ]]
then
    #
    :   Local node is not defined - no chance of further success
    #
	dspmsg -s 30 scripts.cat 2 "${PROGNAME}: The local node name cannot be determined at this time.   Private network restrictions cannot be set.\n" $PROGNAME
	return 1
fi

NONEN_IFRESTRICT_FILE="/var/hacmp/log/ifrestrict.nonen"
TMP_IFRESTRICT_FILE="/var/hacmp/log/ifrestrict.$$"
CAA_IFRESTRICT_FILE="/etc/cluster/ifrestrict"

#
:   Keep the backup of non en interfaces of ifrestrict file, These interfaces
:   will be added to ifrestrict file once ifrestrict file is updated with new interfaces.
:   Since we should not touch the non en interfaces which might be added to the ifrestrict
:   file  manually.
#
if [[ -s $CAA_IFRESTRICT_FILE ]]
then
    grep -v "^en" $CAA_IFRESTRICT_FILE > $NONEN_IFRESTRICT_FILE
fi

#
:   Local node is configured so there must be some semblance of a configuration
:   in place - now see if there are any interfaces defined as private on this
:   node
#
/usr/es/sbin/cluster/utilities/cllsif -cJ "|" 2>/dev/null |
            cut -f 5,6,9 -d"|" |
            grep "^private|$LOCAL_NODE" |
            cut -f3 -d"|" | sort -u >$TMP_IFRESTRICT_FILE

if [[ -s $TMP_IFRESTRICT_FILE ]]		#   Need to restrict some interfaces
then
    if [[ -s $CAA_IFRESTRICT_FILE ]]		#   Some interfaces currently restricted
    then
	#
	:   There are interfaces to restrict now, and some have been restricted in the past
	#
	if sort $CAA_IFRESTRICT_FILE | diff - $TMP_IFRESTRICT_FILE > /dev/null
	then
	    #
	    :	The list of restricted interfaces has not changed
	    #
	    m_flag="true"	#   No further processing needed, because no change
	    rm $TMP_IFRESTRICT_FILE
	else 
	    #
	    :	The list of restricted interfaces has changed
	    #
	    not_privates=$(sort $CAA_IFRESTRICT_FILE | comm -2 -3 - $TMP_IFRESTRICT_FILE)
	    if [[ -n $not_privates ]]
	    then
		if [[ $v_flag == "true" ]]
		then
		    #
		    :	Tell the user which interfaces are no longer private
		    #
		    msg_string=$(dspmsg -s 30 scripts.cat 3 "${PROGNAME}: Unrestricting the following interfaces on ${LOCAL_NODE}:" $PROGNAME $LOCAL_NODE)
		    printf "%s\n" "$msg_string"
		    print "$not_privates"
		fi
		if [[ -n $CLUTILS_LOG ]]
		then
		    msg_string=$(LC_ALL=C dspmsg -s 30 scripts.cat 3 "${PROGNAME}: Unrestricting the following interfaces on ${LOCAL_NODE}:" $PROGNAME $LOCAL_NODE)
		    not_privates=$(print -- "$not_privates" | paste -s -d, -)
		    printf "%s %s %s\n" "$(date)" "$msg_string" "$not_privates"  >> $CLUTILS_LOG
		fi
	    fi
	fi
    fi

    if [[ -s $TMP_IFRESTRICT_FILE ]]
    then
	#
	:   Replace the CAA file with the new list of restricted interfaces
	#
	mv $TMP_IFRESTRICT_FILE $CAA_IFRESTRICT_FILE
    fi
else				#   No Interfaces to restrict now
    #
    :	There are no interfaces defined on $LOCAL_NODE in any private networks
    #
    if [[ $v_flag == "true" ]]
    then
	    dspmsg -s 30 scripts.cat 4 "${PROGNAME}: There are no interfaces on private networks on ${LOCAL_NODE}\n" $PROGNAME $LOCAL_NODE
        #
        : User asked for verbose output, so let them know if there are any 
		: privates anywhere in this army
        #
        [[ -n $(/usr/es/sbin/cluster/utilities/cllsif -cJ "|" | cut -f 5 -d"|" |
 grep "^private") ]] &&
            dspmsg -s 30 scripts.cat 5 "${PROGNAME}: There are no private networks defined on this cluster\n" $PROGNAME

    fi
    if [[ -s $CAA_IFRESTRICT_FILE ]]
    then
	#
	:   Some interfaces used to be restricted, but no longer
	#
	if [[ $v_flag == "true" ]]
	then
	    msg_string=$(dspmsg -s 30 scripts.cat 3 "${PROGNAME}: Unrestricting the following interfaces on ${LOCAL_NODE}:" $PROGNAME $LOCAL_NODE)
	    printf "%s\n" "$msg_string"
	    cat $CAA_IFRESTRICT_FILE
	fi
	if [[ -n $CLUTILS_LOG ]]
	then
	    msg_string=$(LC_ALL=C dspmsg -s 30 scripts.cat 3 "${PROGNAME}: Unrestricting the following interfaces on ${LOCAL_NODE}:" $PROGNAME $LOCAL_NODE)
	    printf "%s %s %s\n" "$(date)" "$msg_string" "$(paste -s -d, $CAA_IFRESTRICT_FILE)"  >> $CLUTILS_LOG
	fi
	rm -rf $CAA_IFRESTRICT_FILE
    else
	#
	:   There never were any restriced interfaces
	#
	m_flag="true"		#   No further processing needed, because no change
    fi
fi

#
:   Now add the non en interfaces to the ifrestrict file.
#
if [[ -s $NONEN_IFRESTRICT_FILE ]]
then
    cat $NONEN_IFRESTRICT_FILE >> $CAA_IFRESTRICT_FILE
fi

# 
# all done with the tmp files
#
rm -f $TMP_IFRESTRICT_FILE $NONEN_IFRESTRICT_FILE

if [[ $m_flag != "true" ]]
then
    #
    :	The caller does not plan to run mkcluster.  This is presumably then an 'update'.
    :	Tell CAA about the new restrictions.
    #
	CC_OUT=$(/usr/sbin/clusterconf 2>&1)
	RC=$?
    if [[ $v_flag == "true" ]]
    then
	printf "%s %s\n" "${PROGNAME}:" "/usr/sbin/clusterconf"
	echo $CC_OUT
	echo "/usr/sbin/clusterconf completed with return code $RC"
    fi
    if [[ -n $CLUTILS_LOG ]]
    then
	printf "%s %s %s\n" "$(date)" "${PROGNAME}:" "/usr/sbin/clusterconf"  >> $CLUTILS_LOG
    echo $CC_OUT >>$CLUTILS_LOG 
	echo "/usr/sbin/clusterconf completed with return code $RC" >>$CLUTILS_LOG
    fi
fi

if [[ -s $CAA_IFRESTRICT_FILE ]]
then
    #
    :	If the caller requested verbose output we list the restricted 
    :	interfaces
    #
    if [[ $v_flag == "true" ]]
    then
	msg_string=$(dspmsg -s 30 scripts.cat 6 "${PROGNAME}: The following interfaces are now restricted on ${LOCAL_NODE}:" $PROGNAME $LOCAL_NODE)
	printf "%s\n" "$msg_string"
	cat $CAA_IFRESTRICT_FILE
	/usr/sbin/lscluster -i 2>/dev/null
    fi
    if [[ -n $CLUTILS_LOG ]]
    then
	msg_string=$(LC_ALL=C dspmsg -s 30 scripts.cat 6 "${PROGNAME}: The following interfaces are now restricted on ${LOCAL_NODE}:" $PROGNAME $LOCAL_NODE)
	printf "%s %s %s\n" "$(date)" "$msg_string" "$(paste -s -d, $CAA_IFRESTRICT_FILE)"  >> $CLUTILS_LOG
	/usr/sbin/lscluster -i >> $CLUTILS_LOG 2>&1
    fi
fi

exit 0
