#!/usr/bin/ksh93
#  ALTRAN_PROLOG_BEGIN_TAG                                                    
#  This is an automatically generated prolog.                                  
#                                                                              
#  Copyright (C) Altran ACT S.A.S. 2018,2019,2021.  All rights reserved.  
#                                                                              
#  ALTRAN_PROLOG_END_TAG                                                      
#                                                                              
# IBM_PROLOG_BEGIN_TAG 
# This is an automatically generated prolog. 
#  
# 61haes_r720 src/43haes/usr/sbin/cluster/sa/dhcp/sbin/cl_dhcp_import.sh 1.2 
#  
# Licensed Materials - Property of IBM 
#  
# COPYRIGHT International Business Machines Corp. 2010,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 
# @(#)  7d4c34b 43haes/usr/sbin/cluster/sa/dhcp/sbin/cl_dhcp_import.sh, 726, 2147A_aha726, Feb 05 2021 09:50 PM
####################################################################################################
#
# Name: cl_dhcp_import
#
# DHCP Smart Assist import function for adding and removing resources.
#
# Syntax:
# cl_dhcp_import [-D | -v] [-M] {-a | -r}
#			-A <ApplicationName>
#			-o <DHCPowningNode>
#			-n <TakeoverNode1[:TakeoverNode2...]>
#			-l <ServiceLabel>
#			-P <PrefixLength>
# 
# Arguments:
#	-D	Turn on debug mode.
#
#	-A  	Application Name - Smart assistant application identifier
#
#	-v	Turn on verbose mode.
#
#	-a	Add/change all necessary resources for the DHCP Server.
#		If the resources already exist, they will be removed and then added.
#		This is the change/modify mode.
#
#	-r	Remove all resources for the specified DHCP Server.
#
#	-o	DHCP server owning node.  This is the node that has the
#		highest priority.
#
#	-n	DHCP takeover node(s).  These nodes will be appended to the
#		owning node and then passed to "claddgrp -n".  Takeover
#		nodelist is colon-separated.
#
#	-l	The TCP/IP service IP label.
#
# 	-M	Delete pre-existing configuration (modify mode)
#
#	-P	Netmask (IPv4) / Prefix Length (IPv6)
#
# Returns:
#	0 on Success (import completed without error)
#	1 on Warning (import completed with warning(s))
#	2 on Failure (import failed due to pre-verification failure)
#	3 on Failure (import failed due to failure in adding resource)
# 
####################################################################################################

. /usr/es/lib/ksh93/func_include

#
: Load the common variables
#
. /usr/es/sbin/cluster/sa/dhcp/sbin/cl_dhcp_common_variables

####################################################################################################
# Global Definitions:
####################################################################################################

RECOVERY_ODM=/tmp/cl_dhcp_RemRes_recovery_odm
RECOVERY_CMDS=/tmp/cl_dhcp_RemRes_recovery_cmds

PROGNAME=$(basename ${0})
PATH=$(/usr/es/sbin/cluster/utilities/cl_get_path all)
PATH=$PATH:/usr/bin:/etc:/usr/sbin:/usr/ucb:/sbin:/usr/es/sbin/cluster/sa/sbin
FPATH_BASE=/usr/es/lib/ksh93
FPATH=$FPATH_BASE/hacmp:$FPATH_BASE/sa:$FPATH_BASE/aix:$FPATH_BASE/aix/odm:$FPATH_BASE/util
export PATH FPATH
export ODMDIR=/etc/objrepos
DHCP_SA="/usr/es/sbin/cluster/sa/dhcp"
DHCP_SA_BIN_DIR="$DHCP_SA/sbin"
MANUAL_CONFIG_SCHEMA="$DHCP_SA/config/cl_dhcp_manual_config.xsd"

export DEBUG=${DEBUG:-"0"}
export VERBOSE=${VERBOSE:-"0"}
ADD_RESOURCES=0
REMOVE_RESOURCES=0
OWNING_NODE=""
TAKEOVER_NODES=""
SERVICE_LABEL=""
IS_NETWORK_PROVIDED=""
NETWORK_NAME=""
NETMASK_PREFIX_LEN=""
sa_type="SA_dhcp"
NODE2STOP=""
DHCP_CONFIG_FILE_COLLECTION_NAME="DHCP_CONFIG_FILES"

#
: Add or Remove
#
ACTION=""		

NUM_ARGS=$#
MODIFY_MODE=false

####################################################################################################
#
# Name:		usage
#
# Description:	Prints usage message and exits the program.
#
# Arguments:	N/A
#
# Returns:	N/A
#
####################################################################################################
function usage
{
	[[ "$VERBOSE_LOGGING" == "high" ]] && set -x

	KLIB_SA_logmsg WARN 8 1 dhcpsa.cat "Usage: cl_dhcp_import -A <ApplicationName>\n\
\t[-D | -v] {-a | -r} -o <InstanceOwningNode> -n <TakeoverNode1[:TakeoverNode2...]>\n\
\t-l <ServiceLabel> -P <PrefixLength> -f <Input XML file>\n\
\n\
	-A  Application Name.\n\
	-D  Turn on debug mode.\n\
	-v  Turn on verbose mode.\n\
	-a  Add/change all necessary PowerHA SystemMirror resources.\n\
	    If the resources already exist, they will be removed and then added.\n\
	-r  Remove all PowerHA SystemMirror resources for DHCP.\n\
	-o  DHCP owning node. This is the node that has the highest priority.\n\
	-n  DHCP takeover node(s).  These nodes will be appended to the instance\n\
	    owning node and then passed to \"claddgrp -n\". Takeover nodelist is colon-separated.\n\
	-l  The TCP/IP service IP label used by DHCP to communicate with other application\n\
	    tiers and/or clients.\n\
	-P  Netmask(IPv4)/Prefix Length(IPv6)\n\
	-M  Delete the pre-existing configuration (modify mode)\n\
	-f  Input XML file populated with required information for Manual Configuration."

    exit 1
}


####################################################################################################
# Name:		RemoveResources
#
# Description:	Removes (-r) PowerHA SystemMirror resources for DHCP Smart Assist.  This function
#		removes all the PowerHA SystemMirror resources its counterpart function, AddResources
#		added for DHCP.
# 		Entries added by AddResources in the HACMPsa_metadata ODM will also
#		be cleaned up.
#
#		This function, for the most part, will print out a warning and
#		continue removing other resources should it fails removing a
#		particular resource.
#
# Arguments:	N/A
#
# Returns:	0 on SUCCESS
#		1 on FAILURE
####################################################################################################

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

	REMOVE_ERROR=0  # set to 1 if any of the remove fails

	key="$APPLICATION_NAME"

	#
	: Determine if the DHCP resource group exists first prior to removing
	#
	typeset group=$(clodmget -q "sa_key=$key and sa_type=$sa_type" -f group \
-d "=" HACMPgroup)
	group=${group//\"/}

	typeset application_server=$COMPONENT_ID"_ApplicationServer" 

	MONITORS=$(clvt query application $application_server | \
                       grep ASSOCIATEDMONITORS | \
                       awk -F= '{print $2}' | sed -e "s/\"//g")
	[[ -n "$MONITORS" ]] && {
		for monitor in $MONITORS; do
			clvt delete application_monitor $monitor
			(( $? != 0 )) && {
                        KLIB_SA_logmsg ERROR 2 3 dhcpsa.cat "Failed removing Application monitor %1\$s" "$monitor"
                        REMOVE_ERROR=1
			}
		done
	}
	#
	: Now, we remove all entries from HACMP.
	: Remove Application Server from the HACMP Configuration
	#
	clvt query application $application_server > /dev/null 2>&1
	if (( $? == 0 ))
	then
		clvt delete application "$application_server"
		(( $? != 0 )) && {
			KLIB_SA_logmsg ERROR 2 4 dhcpsa.cat "Failed removing Application Server %1\$s from PowerHA SystemMirror" "$application_server"
			REMOVE_ERROR=1
		}
	fi

	#
	: Remove Service IP Label
	#
	service_label=$(clodmget -q ip_label=$SERVICE_LABEL HACMPadapter)
	name="SERVICE_LABEL"
	if [[ -n "$service_label" ]]; then
		clvt delete service_ip "$SERVICE_LABEL"
		if (( $? != 0 )); then
			KLIB_SA_logmsg ERROR 2 6 dhcpsa.cat "Failed removing DHCP \
Service IP Label from PowerHA SystemMirror"
			REMOVE_ERROR=1
		fi
	fi

	#
	: Remove Resource Group from the PowerHA SystemMirror configuration
	: All of the metadata will be removed at the time the RG
	: metadata is removed
	#
	if [[ -n $group ]]; then
		clvt delete resource_group $group
		if (( $? != 0 )); then
			KLIB_SA_logmsg ERROR 2 8 dhcpsa.cat "Failed removing DHCP \
Resource Group from PowerHA SystemMirror"
			REMOVE_ERROR=1
		fi
	fi


	#
	: Remove the file collection
	#
	clvt query file_collection $DHCP_CONFIG_FILE_COLLECTION_NAME 1>/dev/null 2>&1
	(( $? == 0 )) && {
		clvt delete file_collection $DHCP_CONFIG_FILE_COLLECTION_NAME 1>/dev/null 2>&1
		(( $? != 0 )) && {
			KLIB_SA_logmsg ERROR 2 7 dhcpsa.cat "Failed removing PowerHA SystemMirror \
file collection for DHCP configuration files"
			REMOVE_ERROR=1
		}
	}

	#
	: Remove the entries from HACMPsa_metadata.
	#
	if [[ -n $(clodmget -q "name=APPLICATION_NAME and value=SA_DHCP" HACMPsa_metadata 2>/dev/null) ]] ; then
		clrmsaapp -a $APPLICATION_NAME
	fi

	return $REMOVE_ERROR
}

####################################################################################################
#
# Name:		StopDHCP
#
# Description:	Checks the $NODE_LIST to make sure DHCP is not running
#		anywhere. If found running, an attempt will be made to stop it.
#
# Arguments:	N/A
#
# Returns: 	0 on SUCCESS
#		1 on FAILURE
####################################################################################################

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

	#
	: The product of these will dictate how long we wait for the
	: subsystem to stop.  We wait up to $TOTAL_SLEEP_TIME seconds for the
	: subsystem to stop.
	#
	typeset -i SLEEP_TIME=5	# in seconds
	typeset -i SLEEP_CYCLE=120
	typeset -i TOTAL_SLEEP_TIME
	(( TOTAL_SLEEP_TIME = $SLEEP_TIME * $SLEEP_CYCLE ))

	#
	: Verify and stop the DHCP server, if running.
	#
	for node in $NODE_LIST
	do
		cl_rsh $node "/usr/bin/lssrc -s dhcpsd | grep -iw active" > /dev/null 2>&1
		(( $? == 0 )) && {
			NODE2STOP="$node"
			KLIB_SA_logmsg INFO 2 9 dhcpsa.cat "Stopping \
DHCP server on node %1\$s" $NODE2STOP
			cl_rsh $NODE2STOP "$DHCP_SA_BIN_DIR/cl_dhcp_stop" > /dev/null 2>&1
		}
	done

	[[ -z $NODE2STOP ]] && {
		KLIB_SA_logmsg INFO 2 10 dhcpsa.cat "DHCP server \
daemon is not active on any node"
		return 0
	}

	#
	: Check to see if the DHCP server is stopped,
	: if not, cycle through a sleep to give it more time.
	#

	while (( $SLEEP_CYCLE > 0 ))
	do
		cl_rsh $NODE2STOP "/usr/bin/lssrc -s dhcpsd | grep -iw active" > /dev/null 2>&1
		if (( $? == 0 )); then 
			KLIB_SA_logmsg INFO 2 11 dhcpsa.cat "DHCP server on node %1\$s is still running" "$NODE2STOP"
			KLIB_SA_logmsg INFO 2 12 dhcpsa.cat "Sleeping for \
%1\$s seconds \(up to a total of %2\$s seconds\)...\n" $TOTAL_SLEEP_TIME $TOTAL_SLEEP_TIME

			sleep $SLEEP_TIME

			(( SLEEP_CYCLE = $SLEEP_CYCLE - 1 ))
		else
			KLIB_SA_logmsg INFO 2 13 dhcpsa.cat "DHCP server daemon \
on node \"%1\$s\" is stopped" $NODE2STOP
			return 0
		fi
	done

	KLIB_SA_logmsg ERROR 2 14 dhcpsa.cat "Failed stopping DHCP \
server daemon on node \"%1\$s\"" $NODE2STOP
	return 1
}

####################################################################################################
#
# Name:		CheckInputs
#
# Description:	Checks a number of basic conditions and inputs to make sure nothing major is
#		missing before adding any resources.
#
# Arguments:	N/A
#
# Returns:	0 on SUCCESS
#		1 on FAILURE
#
####################################################################################################
function CheckInputs
{
	[[ "$VERBOSE_LOGGING" == "high" ]] && set -x

	KLIB_SA_logmsg INFO 2 15 dhcpsa.cat "Verifying \
DHCP server input resources"

	#
	: Make sure the owning node is not also part of the takeover nodes
	#
	KLIB_SA_logmsg INFO 2 16 dhcpsa.cat "Verifying the owning node %1\$s is part of takeover node(s) %2\$s list" $OWNING_NODE "$TAKEOVER_NODES"
	#
	: assuming it is OK
	#
	NODE_LIST_OK=1
	for i in $TAKEOVER_NODES
	do
		[[ "$i" == "$OWNING_NODE" ]] && {
			NODE_LIST_OK=0
		}
	done

	(( $NODE_LIST_OK == "0" )) && {
	KLIB_SA_logmsg ERROR 2 17 dhcpsa.cat "The owning node %1\$s cannot be part of takeover node(s) %2\$s list" $OWNING_NODE "$TAKEOVER_NODES"
		exit 1
	}

	#
	: Make sure all cluster nodes primary and takeover are valid PowerHA SystemMirror nodes.
	#
	KLIB_SA_logmsg INFO 2 18 dhcpsa.cat "Verifying all supplied \
nodes are valid PowerHA SystemMirror nodes"
	for node in $OWNING_NODE $TAKEOVER_NODES
	do
		KLIB_HACMP_is_known_node $node
		(( $? != 0 )) && {
			KLIB_SA_logmsg ERROR 2 19 dhcpsa.cat "Node %1\$s \
is not a cluster node" $node
			KLIB_SA_logmsg ERROR 2 20 dhcpsa.cat "Both \
owning node and takeover node(s) must be cluster nodes"
			exit 1
		}
	done

	return 0
}

###############################################################################################
#
# Function:	verParameterizedDHCPfileset
#
# Purpose:	Prints a script that will validate the DHCP fileset
#
# Arguments:	N/A
#
# Returns:	N/A
#
###############################################################################################
function verParameterizedDHCPfileset
{
	[[ "$VERBOSE_LOGGING" == "high" ]] && set -x

	typeset TEST_ROOT=/usr/es/sbin/cluster/etc/config/verify
	typeset VERIFICATION_FILENAME=${APPLICATION_NAME}"_"${COMPONENT_ID}".ver"
	typeset localnode=$(get_local_nodename)

	FILESET_VERSION=$(/usr/bin/lslpp -cl bos.net.tcp.server | tail -1 | cut -d ":" -f 3)

	echo "#\n# PowerHA SystemMirror DHCP server Application" > $TEST_ROOT/$VERIFICATION_FILENAME
	echo "# Parameterized Verificiation check" >> $TEST_ROOT/$VERIFICATION_FILENAME
	echo "# Date: $(date)\n#" >> $TEST_ROOT/$VERIFICATION_FILENAME

	echo "Component.Name.DefaultName = \"DHCP\"" >> $TEST_ROOT/$VERIFICATION_FILENAME

	echo "Component.MsgCat.ID = 2" >> $TEST_ROOT/$VERIFICATION_FILENAME
	echo "Component.MsgCat.Set = 1" >> $TEST_ROOT/$VERIFICATION_FILENAME
	echo "Component.MsgCat.Catalog = \"dhcpsa.cat\"" >> $TEST_ROOT/$VERIFICATION_FILENAME
	echo "Component.Nodes = \"S=DHCP:A=$APPLICATION_NAME\"" >> $TEST_ROOT/$VERIFICATION_FILENAME

	echo "\n#\n# Perform validation for DHCP server fileset\n#" >> $TEST_ROOT/$VERIFICATION_FILENAME

	echo "HAVerify.Fileset.severity = \"ERROR\"" >> $TEST_ROOT/$VERIFICATION_FILENAME
	echo "HAVerify.Fileset.exists[0].name = \"bos.net.tcp.server\"" >> $TEST_ROOT/$VERIFICATION_FILENAME
	echo "HAVerify.Fileset.exists[0].version = \"$FILESET_VERSION\"" >> $TEST_ROOT/$VERIFICATION_FILENAME

	for node in $NODE_LIST; do
		[[ "$node" != "$localnode" ]] && {
			cl_rcp $TEST_ROOT/$VERIFICATION_FILENAME \
			$node:$TEST_ROOT/$VERIFICATION_FILENAME
		}
	done

	#
	: Adding parameterized verification configuration file to file collection
	#
	clvt modify file_collection $DHCP_CONFIG_FILE_COLLECTION_NAME ADD="$TEST_ROOT/$VERIFICATION_FILENAME" \
DESCRIPTION="DHCP server configuration file collection" \
ISPROPOGATEDFILEDURINGSYNC="true" ISPROPOGATEAUTOWHENDETECTED="true"
}

###############################################################################################
#
# Function:     RunRecoveryScript
#
# Description:  Run the recovery script and recover to PIT prior to removal
#
# Arguments:    N/A
#
# Global Variables:
#               RECOVERY_CMDS
#               RECOVERY_ODM
#
# Returns:      0 if successful
#               !0 if a failure occurred
#
###############################################################################################
function RunRecoveryScript
{
    set +u
    [[ "$VERBOSE_LOGGING" == "high" ]] && set -x
    set -u

    /usr/bin/ksh93 $RECOVERY_CMDS 2>/dev/null
    /usr/bin/odmadd $RECOVERY_ODM 2>/dev/null
}

###############################################################################################
#
# Function:     RemoveRecoveryScript
#
# Description:  Remove the recovery script files from /tmp/
#               prior to exiting
#
# Arguments:    N/A
#
# Global Variables:
#               RECOVERY_CMDS
#               RECOVERY_ODM
#
# Returns:      0 if successful
#               !0 if a failure occurred
#
###############################################################################################
function RemoveRecoveryScript
{
    set +u
    [[ "$VERBOSE_LOGGING" == "high" ]] && set -x
    set -u

    rm -f $RECOVERY_ODM $RECOVERY_CMDS
}

############################################################################
# Function:     GenerateRecoveryScript
#
# Description:  Run the recovery script and recover to PIT prior to removal
#
# Arguments:    N/A
#
# Global Variables:
#               RECOVERY_CMDS
#               RECOVERY_ODM
#
# Returns:      0 if successful
#               !0 if a failure occurred
############################################################################
function GenerateRecoveryScript
{
    [[ "$VERBOSE_LOGGING" == "high" ]] && set -x

    typeset key="$APPLICATION_NAME"
    typeset group=$(clodmget -q "sa_key=$key and sa_type=$sa_type and group=$RG_NAME" -f group -d "=" HACMPgroup)
    group=${group//\"/}
    typeset service_label=$(clodmget -q "name=SERVICE_LABEL and group=$group" -f value -d "=" HACMPresource)
    service_label=${service_label//\"/}
    typeset application_server=$(KLIB_HACMP_get_appserver $group)

    echo "/usr/bin/odmdelete -o HACMPgroup -q group=$group" > $RECOVERY_CMDS
    echo "/usr/bin/odmdelete -o HACMPresource -q group=$group" >> $RECOVERY_CMDS
    echo "/usr/bin/odmdelete -o HACMPsa_metadata -q application_id=$APPLICATION_NAME" >> $RECOVERY_CMDS
    echo "/usr/bin/odmdelete -o HACMPserver -q name=$application_server" >> $RECOVERY_CMDS
    echo "/usr/bin/odmdelete -o HACMPadapter -q ip_label=$service_label" >> $RECOVERY_CMDS
    MONITORS=$(LC_ALL=C clvt query application $application_server | \
                       grep ASSOCIATEDMONITORS | \
                       awk -F= '{print $2}' | sed -e "s/\"//g")
    for app_mon in $MONITORS
    do
        echo "/usr/bin/odmdelete -o HACMPmonitor -q monitor=$app_mon" >> $RECOVERY_CMDS
    done
    echo "/usr/bin/odmdelete -o HACMPfilecollection -q name=$DHCP_CONFIG_FILE_COLLECTION_NAME" >> $RECOVERY_CMDS
    echo "/usr/bin/odmdelete -o HACMPfcfile -q fc_name=$DHCP_CONFIG_FILE_COLLECTION_NAME" >> $RECOVERY_CMDS

    /usr/bin/odmget -q group=$group HACMPgroup > $RECOVERY_ODM
    /usr/bin/odmget -q group=$group HACMPresource >> $RECOVERY_ODM
    /usr/bin/odmget -q "application_id=$APPLICATION_NAME" HACMPsa_metadata >> $RECOVERY_ODM
    /usr/bin/odmget -q "name=$application_server" HACMPserver  >> $RECOVERY_ODM
    /usr/bin/odmget -q "ip_label=$service_label" HACMPadapter >> $RECOVERY_ODM
    for app_mon in $MONITORS
    do
        /usr/bin/odmget -q "monitor=$app_mon" HACMPmonitor >> $RECOVERY_ODM
    done
    /usr/bin/odmget -q "name=$DHCP_CONFIG_FILE_COLLECTION_NAME" HACMPfilecollection >> $RECOVERY_ODM
    /usr/bin/odmget -q "fc_name=$DHCP_CONFIG_FILE_COLLECTION_NAME" HACMPfcfile >> $RECOVERY_ODM

    #
    # Providing execute permissions
    #
    /usr/bin/chmod u+x $RECOVERY_CMDS
    /usr/bin/chmod u+x $RECOVERY_ODM
}
####################################################################################################
#
# Name:		AddResources
#
# Description:	Adds (-a) PowerHA SystemMirror resources for DHCP server. If the resources
#		already exist, they will be removed and then added.  Entries will
#		also be added to the HACMPsa_metadata ODM. Application Discovery
#		will remove the resources constructed by this function
#
# Arguments:	N/A
# 
# Returns:	0 on SUCCESS
#		1 on FAILURE
#
####################################################################################################
function AddResources
{
	[[ "$VERBOSE_LOGGING" == "high" ]] && set -x


	#
	: First remove any pre-existing resources for this application id
	#
	RemoveResources
	(( $? != 0 )) && {
		KLIB_SA_logmsg ERROR 2 21 dhcpsa.cat "Removal of one or more resources \
failed"
		return 1
	}

	#
	: Add an entry into the HACMPsa_metadata ODM for the application id
	: and SMARTASSIST_ID and COMPONENT_ID
	#
	claddsaapp -a "$APPLICATION_NAME" SMARTASSIST_ID='DHCP' \
COMPONENT_ID="$COMPONENT_ID" APPLICATION_NAME="$APPLICATION_NAME" 

	#
	: Create the Service IP Label
	#
	if [[ "$IS_NETWORK_PROVIDED" == "true" ]]; then
		clmgr add service_ip $SERVICE_LABEL NETWORK=$NETWORK_NAME PREFIX=$NETMASK_PREFIX_LEN
		(( $? != 0 )) && {
			KLIB_SA_logmsg ERROR 2 22 dhcpsa.cat "Failed creating PowerHA SystemMirror Service IP Label"
			return 1
		}
	else
		KLIB_SA_add_ServiceLabel $SERVICE_LABEL $NETMASK_PREFIX_LEN || {
			KLIB_SA_logmsg ERROR 2 22 dhcpsa.cat "Failed creating PowerHA SystemMirror Service IP Label"
			return 1
		}
	fi

	#
	: Create the DHCP Application Server
	#
	claddserv -s $COMPONENT_ID"_ApplicationServer" \
		-b "$DHCP_SA_BIN_DIR/cl_dhcp_start" \
		-e "$DHCP_SA_BIN_DIR/cl_dhcp_stop"
	(( $? != 0 )) && {
		KLIB_SA_logmsg ERROR 2 23 dhcpsa.cat "Failed creating \
PowerHA SystemMirror Application Server for DHCP"
		return 1
	}

	#
	: Create the DHCP server Process Monitor
	#
	claddappmon MONITOR_TYPE=process name="${COMPONENT_ID}_ProcessMonitor" \
		RESOURCE_TO_MONITOR="${COMPONENT_ID}_ApplicationServer" \
		INVOCATION='longrunning' \
		PROCESSES='dhcpsd' \
		PROCESS_OWNER="root" \
		INSTANCE_COUNT='1' \
		STABILIZATION_INTERVAL='240' \
		RESTART_COUNT='3' \
		RESTART_INTERVAL='1440' \
		FAILURE_ACTION='fallover' \
		CLEANUP_METHOD="$DHCP_SA_BIN_DIR/cl_dhcp_stop" \
		RESTART_METHOD="$DHCP_SA_BIN_DIR/cl_dhcp_start"
	(( $? != 0 )) && {
		KLIB_SA_logmsg ERROR 2 25 dhcpsa.cat "Failed creating \
PowerHA SystemMirror Process Monitor for DHCP server"
		return 1
	}
		
	#
	: Create the DHCP Resource Group
	#
	claddgrp -g "$RG_NAME" -n "$NODE_LIST" \
		-S 'OHN' -O 'FNPN' -B 'NFB' \
		-A $sa_type -K ${APPLICATION_NAME}
	(( $? != 0 )) && {
		KLIB_SA_logmsg ERROR 2 26 dhcpsa.cat "Failed creating PowerHA \
SystemMirror Resource Group for DHCP server"
		return 1
	}

	#
	: Add the required resources to
	: DHCP resource group
	#
	clvt modify resource_group "$RG_NAME" \
		SERVICE_LABEL="$SERVICE_LABEL" \
                APPLICATIONS="${COMPONENT_ID}_ApplicationServer" || {
			KLIB_SA_logmsg ERROR 2 27 dhcpsa.cat "Failed adding resources to Resource Group"
			return 1
		}

	#
	: Adding SQL Monitor to HACMPsa_metadata ODM
	#
	claddsaapp -a "$APPLICATION_NAME" \
		SQL_MONITOR="${COMPONENT_ID}_SQLMonitor" || {
			KLIB_SA_logmsg ERROR 2 28 dhcpsa.cat "Failed adding PowerHA SystemMirror \
SQL Monitor to the Meta Database"
			return 1
	}


	#
	: Adding Process Monitor to HACMPsa_metadata ODM
	#
	claddsaapp -a $APPLICATION_NAME \
		PROCESS_MONITOR="${COMPONENT_ID}_ProcessMonitor" || {
			KLIB_SA_logmsg ERROR 2 29 dhcpsa.cat "Failed adding PowerHA SystemMirror \
Process Monitor to the Meta Database"
			return 1
	}

	#
        : Adding Application Server to HACMPsa_metadata ODM
        #
	claddsaapp -a $APPLICATION_NAME \
		APPLICATION_SERVER="${COMPONENT_ID}_ApplicationServer" || {
			KLIB_SA_logmsg ERROR 2 5 dhcpsa.cat "Failed adding PowerHA SystemMirror \
Application Controller to the Meta Database"
			return 1
	}


	#
	: Adding Resource Group information to HACMPsa_metadata ODM
	#
	claddsaapp -a $APPLICATION_NAME \
		RESOURCE_GROUP="$RG_NAME" || {
	                KLIB_SA_logmsg ERROR 2 30 dhcpsa.cat "Failed adding PowerHA \
SystemMirror Resource Group to the Meta Database"
	                return 1
	}

	#
        : Adding file collections to propagate configuration files information
        : of DHCP server across all participating nodes in DHCP Resource Group.
        #
        [[ -z $DHCP_SERVER_CONFIG_FILE ]] && {
                DHCP_SERVER_CONFIG_FILE="/etc/dhcpsd.cnf"
        }

        #
        : Find out the existence of DHCP server configuration file
        #
        [[ ! -f $DHCP_SERVER_CONFIG_FILE ]] && {
                KLIB_SA_logmsg ERROR 2 34 dhcpsa.cat "The DHCP server configuration file %1\$s \
doesn't exist" $DHCP_SERVER_CONFIG_FILE

		return 1
        }

	#
	: Adding DHCP server configuration file information to HACMPsa_metadata ODM
	#
	claddsaapp -a $APPLICATION_NAME \
		DHCP_SERVER_CONFIG_FILE="$DHCP_SERVER_CONFIG_FILE" || {
			KLIB_SA_logmsg ERROR 2 41 dhcpsa.cat "Failed adding DHCP server configuration file \
information to the Meta Database"
			return 1
	}

        	
	#
        : Creating a PowerHA SystemMirror file collection
        #
	clvt add file_collection $DHCP_CONFIG_FILE_COLLECTION_NAME DESCRIPTION="DHCP server configuration file collection" \
ISPROPOGATEDFILEDURINGSYNC="true" ISPROPOGATEAUTOWHENDETECTED="true"
        (( $? != 0 )) && {
                KLIB_SA_logmsg ERROR 2 42 dhcpsa.cat "Failed creating file collection for propagating DHCP \
server configuration files"

                return 1
        }

	#
        : Adding required directory to file collection
        #
	clvt modify file_collection $DHCP_CONFIG_FILE_COLLECTION_NAME ADD="$DHCP_SERVER_CONFIG_FILE" \
DESCRIPTION="DHCP server configuration file collection" \
ISPROPOGATEDFILEDURINGSYNC="true" ISPROPOGATEAUTOWHENDETECTED="true"
        (( $? != 0 )) && {
                KLIB_SA_logmsg ERROR 2 43 dhcpsa.cat "Failed adding DHCP server configuration file %1\$s to file collection %2\$s" \
 $DHCP_SERVER_CONFIG_FILE "$DHCP_CONFIG_FILE_COLLECTION_NAME"

                return 1
        }

	verParameterizedDHCPfileset

	#
        : Adding DHCP file collection information to HACMPsa_metadata ODM
        #
	claddsaapp -a $APPLICATION_NAME \
                FILE_COLLECTION="$DHCP_CONFIG_FILE_COLLECTION_NAME" || {
			return 1
	}

	return 0
}

#################################################################################
#
# Name:         importConfigFromFile
#
# Description:	This function will read the supplied config file and create powerHA
#               SystemMirror resources to configure DHCP server for high availability.
#
# Arguments:	N/A
#
# Returns:	0 - on success
#               1 - on failure
#
#################################################################################
function importConfigFromFile
{
        [[ "$VERBOSE_LOGGING" == "high" ]] && set -x

        MANUAL_CONFIG=""
        #
        : configure=yes, interested in manual configuration mode with input XML file
        #
        MANUAL_CONFIG=$(clsaxmlutil -s -x $CONFIG_FILE -m $MANUAL_CONFIG_SCHEMA -t $COMPONENT_ID -a configure)
        (( $? != 0 )) && {
                KLIB_SA_logmsg ERROR 2 33 dhcpsa.cat "Problem with %1\$s information in XML file supplied.\n" "configure"
                KLIB_SA_logmsg ERROR 2 32 dhcpsa.cat "Problem with XML configuration file. Ensure a valid XML file supplied.\n"
                exit 1
        }
        [[ "$MANUAL_CONFIG" != "yes" ]] && {
                return
        }

        #
        : Finding out primary node information from supplied XML file
        #
        primary_node=$(clsaxmlutil -s -x $CONFIG_FILE -m $MANUAL_CONFIG_SCHEMA -t $COMPONENT_ID | grep PrimaryNode)
        (( $? != 0 )) && {
                KLIB_SA_logmsg ERROR 2 33 dhcpsa.cat "Problem with %1\$s information in XML file supplied.\n" "PrimaryNode"
                KLIB_SA_logmsg ERROR 2 32 dhcpsa.cat "Problem with XML configuration file. Ensure a valid XML file supplied.\n"
                exit 1
        }
        primary_node=$(echo $primary_node | cut -d"=" -f2)
        KLIB_HACMP_is_known_node $primary_node
        (( $? != 0 )) && {
                KLIB_SA_logmsg ERROR 2 19 dhcpsa.cat "Node %1\$s is not a cluster node\n" "$node"
                exit 1
        }
        PRIMARY_NODE=$primary_node

	  #
        : Finding out list of Takeover nodes information from supplied XML file
        #
        takover_nodes=$(clsaxmlutil -s -x $CONFIG_FILE -m $MANUAL_CONFIG_SCHEMA -t $COMPONENT_ID | grep TakeoverNodes)
        (( $? != 0 )) && {
                KLIB_SA_logmsg ERROR 2 33 dhcpsa.cat "Problem with %1\$s information in XML file supplied.\n" "TakeoverNodes"
                KLIB_SA_logmsg ERROR 2 32 dhcpsa.cat "Problem with XML configuration file. Ensure a valid XML file supplied.\n"
                exit 1
        }
        takover_nodes=$(echo $takover_nodes | cut -d"=" -f2)
        takeover_nodes=$(echo $takover_nodes  | tr ',' ' ')
        for tnode in $takeover_nodes
        do
                KLIB_HACMP_is_known_node $tnode
                (( $? != 0 )) && {
                        KLIB_SA_logmsg ERROR 2 19 dhcpsa.cat "Node %1\$s is not a cluster node\n" "$node"
                        exit 1
                }
        done

        TAKEOVER_NODES=$(echo $takeover_nodes | sed -e "s/ /\:/g")

        #
        : Find out service IP label information from supplied XML file
        #
        addrs=$(clsaxmlutil -s -x $CONFIG_FILE -m $MANUAL_CONFIG_SCHEMA -t $COMPONENT_ID | grep IPAddress_or_name)
        (( $? != 0 )) && {
                KLIB_SA_logmsg ERROR 2 33 dhcpsa.cat "Problem with %1\$s information in XML file supplied.\n" "IPAddress_or_name"
                KLIB_SA_logmsg ERROR 2 32 dhcpsa.cat "Problem with XML configuration file. Ensure a valid XML file supplied.\n"
                exit 1
        }

        addrs=$(echo $addrs | cut -d"=" -f2)

        SERVICE_LABEL=$addrs

        #
        : Find out Service Network information from supplied XML file
        #
        NETWORK_NAME=$(clsaxmlutil -s -x $CONFIG_FILE -m $MANUAL_CONFIG_SCHEMA -t $COMPONENT_ID | grep Service_Network)
        (( $? != 0 )) && {
                 KLIB_SA_logmsg ERROR 2 33 dhcpsa.cat "Problem with %1\$s information in XML file supplied.\n" "Service_Network"
                 KLIB_SA_logmsg ERROR 2 32 dhcpsa.cat "Problem with XML configuration file. Ensure a valid XML file supplied.\n"
                 exit 1
        }

        NETWORK_NAME=$(echo $NETWORK_NAME | cut -d"=" -f2)

        #
        : Find out netmask or prefix length information from supplied XML file
        #
        netmask=$(clsaxmlutil -s -x $CONFIG_FILE -m $MANUAL_CONFIG_SCHEMA -t $COMPONENT_ID | grep Prefix_or_Netmask)
        (( $? != 0 )) && {
                KLIB_SA_logmsg ERROR 2 33 dhcpsa.cat "Problem with %1\$s information in XML file supplied.\n" "Prefix_or_Netmask"
                KLIB_SA_logmsg ERROR 2 32 dhcpsa.cat "Problem with XML configuration file. Ensure a valid XML file supplied.\n"
                exit 1
        }
        NETMASK_PREFIX_LEN=""
        NETMASK_PREFIX_LEN=$(echo $netmask | cut -d"=" -f2)

        APPLICATION_NAME="SA_DHCP"

        ARGUMENTS="-a -v -A $APPLICATION_NAME -l $SERVICE_LABEL -o $PRIMARY_NODE -n $TAKEOVER_NODES"

        [[ -n $NETMASK_PREFIX_LEN ]] && {
                ARGUMENTS="$ARGUMENTS -P \"$NETMASK_PREFIX_LEN\""
        }

        [[ -n $NETWORK_NAME ]] && {
                ARGUMENTS="$ARGUMENTS -N $NETWORK_NAME"
        }
        /usr/es/sbin/cluster/sa/dhcp/sbin/cl_dhcp_import $ARGUMENTS

}
####################################################################################################
# Main:
####################################################################################################


umask -S u=rw,g=,o=

(( $NUM_ARGS == 0 )) && usage

while getopts DA:Mvaro:n:P:l:f:N: option
do
	case $option in
		D)
			#
			: Verbose on + Debug on
			#
			VERBOSE=1
			DEBUG=1
			;;
		A)
			#
			: application name
			#
			APPLICATION_NAME=$OPTARG
			;;
		v)
			#
			: Verbose on
			#
			VERBOSE=1
			;;
		a)
			#
			: Add Resources
			#
			if [[ "$REMOVE_RESOURCES" == "1" ]]; then
				usage
			fi
			ACTION="add"
			ADD_RESOURCES=1
			;;
		r)
			#
			: Remove Resources
			#
			if [[ "$ADD_RESOURCES" == "1" ]]; then
				usage
			fi
			ACTION="remove"
			REMOVE_RESOURCES=1
			;;
		o)
			#
			: Primary cluster node that owns the DHCP
			: server
			#
			OWNING_NODE=$OPTARG
			;;
		n)
			#
			: Standby cluster nodes that is/are capable
			: of hosting the DHCP Server 
			#
			TAKEOVER_NODES="$OPTARG"
			TAKEOVER_NODES=$(echo $TAKEOVER_NODES | sed -e "s/\:/ /g")
			;;
		l)
			#
			: Service IP label for DHCP Server
			#
			SERVICE_LABEL=$OPTARG
			;;
		P)
			#
			: Netmask / Prefix Length
			#
			NETMASK_PREFIX_LEN=$OPTARG
			;;
		M)
			#
			: Delete the pre-existing configuration - modify mode
			#
			MODIFY_MODE=true
			;;
		f)
			#
			: Manual configuration mode, where input XML file
			: populated with require information.
			#
			MANUAL_CONFIG=true
			CONFIG_FILE=$OPTARG
			;;
		N)
			#
			:User provided network
			#
			IS_NETWORK_PROVIDED=true
			NETWORK_NAME=$OPTARG
			;;
		*)
			usage
	esac
done

#
: Set the component id to DHCP here
#
COMPONENT_ID="DHCP"

#
: Before handling anything else, check if we have to configure from XML
#
if [[ "$MANUAL_CONFIG" == "true" ]]; then
    if [[ ! -f $CONFIG_FILE ]]; then
        dspmsg -s 51 cluster.cat 26 "Unable to read the configuration file. Please ensure the correct path\n"
        return 1
    fi
    importConfigFromFile
    exit 0
fi

export NODE_LIST="$OWNING_NODE $TAKEOVER_NODES"
RG_NAME="${COMPONENT_ID}_ResourceGroup"

if (( $ADD_RESOURCES == 0 )) && (( $REMOVE_RESOURCES == 0 )); then
	KLIB_SA_logmsg ERROR 2 35 dhcpsa.cat "Missing required argument(s) to import\n"
	usage
fi


if [[ "$ACTION" == "add" ]]; then
	clsapre

	#
	: Remove the pre-existing configuration - modify mode
	#
	[[ "$MODIFY_MODE" == "true" ]] && {
		GenerateRecoveryScript
		set -a
		eval $(clquerysaapp -a $APPLICATION_NAME RESOURCE_GROUP)
		set +a
		clvt delete resource_group $RESOURCE_GROUP
		clrmsaapp -a $APPLICATION_NAME
	}

	#
	: Check to ensure another resource group with the same application name has not been
	: created
	#
	clquerysaapp -a $APPLICATION_NAME > /dev/null 2>&1
	(( $? == 0 )) && {
		KLIB_SA_logmsg ERROR 2 36 dhcpsa.cat "Please choose a different application name, as configuration is already exist with the application name \"%1\$s\"" "$APPLICATION_NAME"
		exit 1
	}

	#
	: Determine if the DHCP server we are attempting to add is already part of an
	: PowerHA SystemMirror configuration
	#
	application=$(clodmget -q "name=RESOURCE_GROUP and value=$RG_NAME" \
-f application_id -d "=" HACMPsa_metadata)
	application=${application//\"/}
	dhcp_rg_config_info=$(clodmget -q group="$RG_NAME" HACMPgroup)

	[[ -n $application ]] && {
		KLIB_SA_logmsg ERROR 2 37 dhcpsa.cat "The DHCP server \
is already defined to the PowerHA SystemMirror\n\
cluster configuration with application \"%1\$s\"" $application
		exit 1
	}

	[[ -n "$dhcp_rg_config_info" ]] && {
		KLIB_SA_logmsg ERROR 2 2 dhcpsa.cat "Resource group %1\$s is already defined to the PowerHA SystemMirror cluster" "$RG_NAME"
		exit 1
	}
	
	#
	: Stop the DHCP server
	#
	stopDHCP
	(( $? != 0 )) && {
		KLIB_SA_logmsg ERROR 2 38 dhcpsa.cat "DHCP server daemon on \
node \"%1\$s\" should be manually stopped before continuing" NODE2STOP
		exit 1
	}

	#
	: Verify the input information
	#
	CheckInputs
	(( $? != 0 )) && {
		KLIB_SA_logmsg ERROR 2 39 dhcpsa.cat "Validation of one or more required \
resources failed\n"
		exit 1
	}


	#
	: Create and Add required resources to resource group
	#
	AddResources
	(( $? != 0 )) && {
		KLIB_SA_logmsg ERROR 2 40 dhcpsa.cat "Resource creation or adding required \
resources to resource group failed.\n"

		#
		: Remove the resources from configuration created so far.
		#
		RemoveResources

		#
		# When something went wrong while adding resources
		# during change of application, we are restoring
		# back the original configuration.
		#
		[[ "$MODIFY_MODE" == "true" ]] && {
			RunRecoveryScript
			RemoveRecoveryScript
		}

		exit 1
	}

	[[ "$MODIFY_MODE" == "true" ]] && {
		RemoveRecoveryScript
	}

	#
	: Run the verification after application instance is added
	#
	clsapost -v
	(( $? != 0 )) && exit 1

else
	KLIB_SA_logmsg ERROR 2 1 dhcpsa.cat "Unexpected DHCP import action encountered\n"
	exit 1
fi

exit 0
