#!/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                                                      
#                                                                              
# @(#)  d82b234 43haes/usr/sbin/cluster/events/resource_add.sh, 726, 2147A_aha726, Apr 29 2021 12:22 AM 


###############################################################################
#
# Name:  createClassDependents
#
# Description: this function is part of the automatic requisite creation
#              system (a.k.a. the clmgr "dependency" system). When an
#              operation fails, an attempt will be made to remove any 
#              dependencies that were automatically created in support of 
#              the operation. This is done by building a list (array) of
#              of dependent objects to be created, then creating sequentially.
#              If any failure occurs, all previous operations are undone by
#              walking backwards through the list and calling the appropriate
#              delete operation.
#
# Inputs:      The class dependency array and any substitutions to be made in 
#              the environment when calling the associated function.
#
# Outputs:     Any output from the individual functions called
#
# Returns:     If any operation fails, return the exit code from that
#              operation, otherwise return 0
#
###############################################################################
function createClassDependents {
    . $HALIBROOT/log_entry "$0()" "$CL" max

    [[ -n $1 ]] && typeset -n classDep=$1
    [[ -n $2 ]] && typeset -n substitutions=$2

    typeset -i rc=0
    typeset func= index= value=

    if [[ -n $1 && -n $2 ]]; then
        for index in ${!classDep[*]}; do
            func="${classDep[$index]} "
            typeset extra_subs=$func
            substitutions="$substitutions ${extra_subs#*+([[:space:]])}"

            for var in $substitutions; do
                value=${_ENV_ARGS[$var]}
                if [[ -n $value ]]; then
                    func=${func/[[:space:]]${var}[[:space:]]/ $value }
                else
                    func=${func/[[:space:]]${var}[[:space:]]/ $value}
                fi

                # Slow down the loop a fraction, to avoid spiking the CPU
                LANG=C sleep .001
            done

            #==========================================
            # Invoke the dependency-checking function
            #==========================================
            CL=$LINENO $func
            if (( $? != 0 )); then
                rc=$RC_ERROR
                break
            fi

            # Slow down the loop a fraction, to avoid spiking the CPU
            LANG=C sleep .001
        done

        if (( rc == RC_ERROR )); then
            if (( ${#unwind[*]} > 0 )); then
                cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 1107 '\nERROR:  the primary operation (%1$s) failed, so an attempt will be made to remove any dependencies that were automatically created in support of the operation.\n\n' "${CLMGR_COMMAND/ -T $CLMGR_TRANSACTION_ID}" 1>&2
                integer i=${#unwind[*]}-1
                for (( ; i>=0; i-- )); do
                    eval CL=$LINENO ${unwind[$i]}
                done
                unset unwind i
            fi
        fi
    fi

    log_return_msg "$rc" "$0()" "$LINENO"
    return $?
} # End of "createClassDependents()"


###############################################################################
#
# Name:        is_cluster_defined
#
# Description: this function is part of the automatic requisite creation
#              system (a.k.a. the clmgr "dependency" system). It attempts
#              to ensure that a cluster is defined. If so, it returns, and
#              takes no further action. If not, it attempts to create a
#              basic cluster using the information that it has in hand.
#
# Inputs:      If any nodes were specified, they serve as the only input.
#
# Outputs:     If a cluster is already defined, there is no output at all.
#              If a cluster must be constructed, an appropriate message is
#              displayed just prior to the construction attempt.
#
# Returns:     Zero if a cluster exists, or was successfully constructed.
#              Otherwise a non-zero is returned to indicate that there
#              is no cluster.
#
###############################################################################
function is_cluster_defined {
    . $HALIBROOT/log_entry "$0()" "$CL" max

    typeset nodes=$*

    typeset -A list
    typeset -i status=$RC_UNKNOWN

    typeset CLUSTER_NAME=$($HAUTILS/clodmget -f name -n HACMPcluster 2>>$CLMGR_TMPLOG)
    if [[ $CLUSTER_NAME == *([[:space:]]) ]]; then
        typeset CLUSTER_NAME=$CLMGR_DEFAULT_CLUSTER_NAME
        if [[ $nodes != *([[:space:]]) ]]; then
            CLUSTER_NAME=${nodes%%,*}
            CLUSTER_NAME="${CLUSTER_NAME}_cluster"
        fi

        cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 24 'The current operation requires a PowerHA SystemMirror cluster, but a cluster\nhas not yet been created. Therefore, a cluster named "%1$s"\nwill now be created automatically.\n' "$CLUSTER_NAME"

        if [[ $nodes != *([[:space:]]) ]]; then
            CL=$LINENO KLIB_HACMP_add_cluster list $CLUSTER_NAME $nodes
        else
            CL=$LINENO KLIB_HACMP_add_cluster list $CLUSTER_NAME ""
        fi
        status=$?

        if (( status == RC_SUCCESS )); then
            unwind[unwind_idx++]="KLIB_HACMP_delete_cluster"
        fi
    else
        : A cluster is defined
        status=$RC_SUCCESS
    fi

    log_return_msg "$status" "$0()" "$LINENO"
    return $?
} # End of "is_cluster_defined()"


###############################################################################
#
# Name:        are_nodes_defined
#
# Description: this function is part of the automatic requisite creation
#              system (a.k.a. the clmgr "dependency" system). It attempts
#              to ensure that specified nodes are defined. If so, it returns,
#              and takes no further action. If not, it attempts to create a
#              simple default node using the information that it has in hand.
#              In this latter case, the _ENV_ARGS list will be updated with
#              the name of the successfully created node, so that any/all
#              remaining operations have accurate information . One last
#              condition that is tested for is the case where no nodes have
#              been specified, but nodes are already defined in the cluster.
#              In that case, the local node is used, and inserted into the
#             _ENV_ARGS list.
#
# Inputs:      If any nodes were specified, they serve as the only input.
#
# Outputs:     If the nodes are already defined, there is no output at all.
#              If any nodes have to be constructed, an appropriate message
#              is displayed just prior to the construction attempt.
#
# Returns:     Zero if all nodes exist, or were successfully constructed.
#              Otherwise a non-zero is returned to indicate that at least
#              one of the nodes is not defined.
#
###############################################################################
function are_nodes_defined {
    . $HALIBROOT/log_entry "$0()" "$CL" max

    typeset nodes=$*
    nodes=${nodes//,/ }

    typeset node=
    typeset -A list
    typeset -i status=$RC_UNKNOWN

    if [[ -n ${nodes//[[:space:]]/} ]]; then
        for node in $nodes; do
            if [[ -n $node ]]; then
                CL=$LINENO KLIB_HACMP_is_known_node $node >>$CLMGR_TMPLOG 2>&1
                if (( $? != RC_SUCCESS )); then
                    typeset -i CREATE_NEW_NODE=1

                    #=======================================================
                    : Before attempting to add this new node, first see if
                    : is already a known node, simply by some other name.
                    #=======================================================
                    typeset HOST_DATA=$(LC_ALL=C host $node 2>>$CLMGR_TMPLOG)
                    if (( $? == 0 )); then
                        typeset HOST="" JUNK="" ADDRESS="" ALIASES=""
                        print -- "$HOST_DATA" | read HOST JUNK ADDRESS JUNK ALIASES

                        typeset NODE="" NODE_IFS=""
                        typeset -i BREAK=0
                        for NODE in $($HAUTILS/clnodename); do
                            : Collect all communication paths for $NODE
                            clodmget -n -q "name=$NODE AND object=COMMUNICATION_PATH" -f value HACMPnode >$TMPDIR/clmgr.rc.and.$$
                            clodmget -n -q "nodename=$NODE" -f ip_label HACMPadapter >>$TMPDIR/clmgr.rc.and.$$
                            clodmget -n -q "nodename=$NODE" -f identifier HACMPadapter >>$TMPDIR/clmgr.rc.and.$$

                            NODE_IFS=$(cat $TMPDIR/clmgr.rc.and.$$)
                            rm -f $TMPDIR/clmgr.rc.and.$$
                            NODE_IFS=${NODE_IFS//$NL/ }

                            for COMM in $HOST ${ADDRESS%,} ${ALIASES//,/ }; do
                                if [[ " $NODE_IFS " == *\ $COMM\ * ]]; then
                                    cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 1108 '\n*** Warning: "%1$s" is not defined as a node within this cluster. However, "%1$s" uses the same communication path as node "%2$s" (%3$s). So "%2$s" will be used instead of "%1$s".\n\n' "$node" "$NODE" "$COMM"
                                    CREATE_NEW_NODE=0
                                    BREAK=1

                                    #======================================
                                    : Make the updates to the user inputs
                                    #======================================
                                    for key in NODE NODES PRIMARYNODES SECONDARYNODES; do
                                        if [[ ${_ENV_ARGS[$key]} != *([[:space:]]) ]]; then
                                            _ENV_ARGS[$key]=" ${_ENV_ARGS[$key]} "
                                            if [[ ${_ENV_ARGS[$key]} == *,* ]]; then
                                                _ENV_ARGS[$key]=${_ENV_ARGS[$key]//,/ }
                                                _ENV_ARGS[$key]=${_ENV_ARGS[$key]/ $node / $NODE }
                                                _ENV_ARGS[$key]=${_ENV_ARGS[$key]// /,}
                                                _ENV_ARGS[$key]=${_ENV_ARGS[$key]#,}
                                                _ENV_ARGS[$key]=${_ENV_ARGS[$key]%,}
                                            else
                                                _ENV_ARGS[$key]=${_ENV_ARGS[$key]/ $node / $NODE }
                                                _ENV_ARGS[$key]=${_ENV_ARGS[$key]# }
                                                _ENV_ARGS[$key]=${_ENV_ARGS[$key]% }
                                            fi
                                        fi
                                    done

                                    break
                                fi
                            done
                            (( BREAK )) && break
                        done
                    fi

                    if (( CREATE_NEW_NODE )); then
                        : Node $node does not exist, so try to create it
                        cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 25 'The current operation requires a PowerHA SystemMirror node named "%1$s", but that node does not appear to exist. An attempt will be made to create that node now...\n' "$node"

                        CL=$LINENO KLIB_HACMP_add_node list "$node"
                        status=$?
                        (( status )) && break

                        if (( status == RC_SUCCESS )); then
                            unwind[unwind_idx++]="KLIB_HACMP_delete_node $node"
                        fi
                    fi
                fi
            fi

            # Slow down the loop a fraction, to avoid spiking the CPU
            LANG=C sleep .001
        done

        (( $status == RC_UNKNOWN )) && status=$RC_SUCCESS  # All nodes exist

    else
        typeset -i NEED_NODE=0
        typeset -i NEED_NODES=0
        typeset -u SUPPORTED_PARAMS=${_CLASS_PROCESSORS[$RESOURCE_CLASS]}
        if [[ $SUPPORTED_PARAMS == *([[:space:]]) ]]; then
            NEED_NODE=1
        elif [[ $SUPPORTED_PARAMS == *NODES\+* ]]; then
            NEED_NODES=1
        elif [[ $SUPPORTED_PARAMS == *NODE\+* ]]; then
            NEED_NODE=1
        elif [[ $RESOURCE_CLASS == @(resource_group) && \
                $SUPPORTED_PARAMS == *NODES* ]]
        then
            NEED_NODES=1
        fi

        if (( NEED_NODES )); then
            : No nodes were specified, but the signature of this function
            : indicates that multiple nodes are needed. Attempt to use
            : clnodename to get a node list.
            nodes=$($HAUTILS/clnodename 2>>$CLMGR_TMPLOG)
            if [[ $nodes != *([[:space:]]) ]]; then
                nodes=${nodes//+([[:space:]])/,}
                cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 1109 'The current operation requires a PowerHA SystemMirror node, but no node was specified. Defaulting to "%1$s"...\n' "$nodes"
                status=$RC_SUCCESS
            fi
        fi

        if (( $status == RC_UNKNOWN )) && \
           (( NEED_NODES || NEED_NODE ))
        then
            nodes=$(CL=$LINENO get_local_node_label 2>>$CLMGR_TMPLOG)

            if [[ $nodes != *([[:space:]]) ]]; then
                cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 1109 'The current operation requires a PowerHA SystemMirror node, but no node\nwas specified. Defaulting to "%1$s"...\n' "$nodes"
                status=$RC_SUCCESS

            else
                nodes=$(hostname)
                nodes=${nodes%%\.*}

                cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 27 'The current operation requires a PowerHA SystemMirror node, but no nodes are currently defined. An attempt will be made to create a node on this system now, named "%1$s"...\n' "$node"

                CL=$LINENO KLIB_HACMP_add_node list "$node"
                status=$?

                if (( status == RC_SUCCESS )); then
                    unwind[unwind_idx++]="KLIB_HACMP_delete_node $node"
                fi
            fi
        fi

        if (( $status == RC_SUCCESS )) && \
           [[ $nodes != *([[:space:]]) ]]
        then
            for var in NODE NODES PRIMARYNODES; do
                _ENV_ARGS[$var]=$nodes
            done
        fi

        if (( ! NEED_NODES && ! NEED_NODE )); then
            status=$RC_SUCCESS
        fi
    fi

    log_return_msg "$status" "$0()" "$LINENO"
    return $?
} # End of "are_nodes_defined()"


###############################################################################
#
# Name:        are_rgs_defined
#
# Description: this function is part of the automatic requisite creation
#              system (a.k.a. the clmgr "dependency" system). It attempts
#              to ensure that specified resource groups are defined. If so,
#              it returns, and takes no further action. If not, it attempts
#              to create each missing RG in the simplest fashion using the
#              information that it has in hand.
#
# Inputs:      If any resource groups were specified, they serve as the
#              only input.
#
# Outputs:     If the resource groups are already defined, there is no
#              output at all. If any resource groups have to be constructed,
#              an appropriate message is displayed just prior to the
#              construction attempt.
#
# Returns:     Zero if all resource groups exist, or were successfully
#              constructed. Otherwise a non-zero is returned to indicate
#              that at least one of the resource groups is not defined.
#
###############################################################################
function are_rgs_defined {
    . $HALIBROOT/log_entry "$0()" "$CL" max

    typeset rgs=$*
            rgs=${rgs//,/ }

    typeset rg=
    typeset -A list NODES
    typeset -i status=$RC_UNKNOWN

    NODES[nodes]=$($HAUTILS/clnodename -c)
    NODES[nodes]=${NODES[nodes]//:/,}

    if [[ -n ${rgs//[[:space:]]/} ]]; then
        for rg in $rgs; do
            if [[ -n $rg ]]; then
                CL=$LINENO KLIB_HACMP_is_known_rg $rg 2>>$CLMGR_TMPLOG || {
                    : RG "$rg" does not exist, so try to create it
                    cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 1110 'The current operation requires a PowerHA SystemMirror resource group named "%1$s", but that resource group does not appear to exist. An attempt will be made to create that resource group now...\n' "$rg"

                    CL=$LINENO KLIB_HACMP_add_resourcegroup list "$rg" NODES "" ""
                    status=$?
                    (( status )) && break

                    if (( status == RC_SUCCESS )); then
                        unwind[unwind_idx++]="KLIB_HACMP_delete_resourcegroup $rg"
                    fi
                }
            fi

            # Slow down the loop a fraction, to avoid spiking the CPU
            LANG=C sleep .001
        done

        (( $status == RC_UNKNOWN )) && status=$RC_SUCCESS  # All RGs exist

    else
        cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 1111 "The current operation requires one or more PowerHA SystemMirror resource groups,\nbut no resource groups are currently defined.\n"
        status=$RC_ERROR
    fi

    log_return_msg "$status" "$0()" "$LINENO"
    return $?
} # End of "are_rgs_defined()"


###############################################################################
#
# Name:        is_network_defined
#
# Description: this function is part of the automatic requisite creation
#              system (a.k.a. the clmgr "dependency" system). It attempts
#              to ensure that the specified network(s) are defined. If the
#              network(s) already exist, this function returns, and takes
#              no further action. If not, the function attempts to create
#              the missing network(s).
#
# Inputs:      networks   The network(s) to validate/create.
#
# Outputs:     If the network(s) are already defined, there is no output at
#              all. If a network must be constructed, an appropriate message
#              is displayed just prior to the construction attempt.
#
# Returns:     Zero if the network exists, or was successfully constructed.
#              Otherwise a non-zero is returned.
#
###############################################################################
function is_network_defined {
    . $HALIBROOT/log_entry "$0()" "$CL" max

    typeset networks=$*

    typeset -A list
    typeset -i status=$RC_UNKNOWN

    if [[ -n ${networks//[[:space:]]/} ]]; then
        for network in $networks; do
            if [[ -n $network ]]; then
                CL=$LINENO KLIB_HACMP_is_known_network $network 2>>$CLMGR_TMPLOG || {
                    : Network "$network" does not exist, so try to create it
                    dspmsg -s $CLMGR_SET $CLMGR_MSGS 28 "The current operation requires a PowerHA SystemMirror network, but a\nnetwork has not yet been created. A network named \"%1\$s\" will\nbe automatically created.\n" "$network"

                    CL=$LINENO KLIB_HACMP_add_network list "$network" "ether"
                    status=$?
                    (( status )) && break

                    if (( status == RC_SUCCESS )); then
                        unwind[unwind_idx++]="KLIB_HACMP_delete_network $network"
                    fi
                }
            fi

            # Slow down the loop a fraction, to avoid spiking the CPU
            LANG=C sleep .001
        done

        (( $status == RC_UNKNOWN )) && status=$RC_SUCCESS  # All networks exist

    else  # No network specified, so just attempt to create one
        print "$0()[$LINENO]($SECONDS): The current operation requires a PowerHA SystemMirror network, but no network was specified. Attempting to identify a suitable network automatically...\n" >>$CLMGR_TMPLOG

        CL=$LINENO KLIB_HACMP_list_networks list 2>>$CLMGR_TMPLOG
        if (( ${#list[*]} > 0 )); then
            for (( i=0; i<${#list[*]}; i++ )); do
                 typeset -A attrs
                 CL=$LINENO KLIB_HACMP_get_network_attributes ${list[$i]} attrs
                 typeset var=
                 for var in ${!attrs[*]}; do
                     [[ $var == TYPE* ]] && break

                     # Slow down the loop a fraction, to avoid spiking the CPU
                     LANG=C sleep .001
                 done
                 if [[ ${attrs[$var]} == "ether" ]]; then

                     if [[ $RESOURCE_CLASS == "persistent_ip" ]]
                     then
                         : Skip networks that already hove a persistent IP
                         typeset PI_TMP="$TMPDIR/clmgr.ra.$$"
                         print "$0()[$LINENO]($SECONDS): clmgr query persistent_ip NETWORK=${list[$i]}" >>$CLMGR_TMPLOG
                         ( clmgr query persistent_ip NETWORK=${list[$i]} >$PI_TMP )  # Run in sub-shell to avoid interference
                         typeset EXISTING=$(cat $PI_TMP)
                         print "$0()[$LINENO]($SECONDS): clmgr query persistent_ip NETWORK=${list[$i]}:  \"$EXISTING\"" >>$CLMGR_TMPLOG
                         rm -f $PI_TMP

                         if [[ $EXISTING != *([[:space:]]) ]]
                         then
                             print "$0()[$LINENO]($SECONDS): Persistent IP \"$EXISTING\" is already defined on network \"${list[$i]}\". Skipping." >>$CLMGR_TMPLOG
                             continue
                         fi
                     fi

                     network=${list[$i]}
                     status=$RC_SUCCESS

                     dspmsg -s $CLMGR_SET $CLMGR_MSGS 29 "The current operation requires a PowerHA SystemMirror network, but no\nnetwork was specified. Defaulting to network \"%1\$s\"...\n" "$network"
                     printf "$0()[$LINENO]($SECONDS): The current operation requires a PowerHA SystemMirror network, but no\nnetwork was specified. Defaulting to network \"%1\$s\"...\n" "$network" >> $CLMGR_TMPLOG
                     break
                 fi

                 # Slow down the loop a fraction, to avoid spiking the CPU
                 LANG=C sleep .001
            done
        else
            network=net_ether_01

            dspmsg -s $CLMGR_SET $CLMGR_MSGS 30 "The current operation requires a PowerHA SystemMirror network, but no\nnetworks are currently defined. An attempt will now be made create an\nEthernet network in the cluster named \"%1\$s\"...\n" "$network"

            CL=$LINENO KLIB_HACMP_add_network list "$network" "ether"
            status=$?

            if (( status == RC_SUCCESS )); then
                unwind[unwind_idx++]="KLIB_HACMP_delete_network $network"
            fi
        fi

        (( status == $RC_SUCCESS )) && _ENV_ARGS[NETWORK]=$network
    fi

    log_return_msg "$status" "$0()" "$LINENO"
    return $?
} # End of "is_network_defined()"


#========================================================================
#
# Name:  add_cluster
#
# !!! IMPORTANT !!!
#
# If the signature of add cluster needs to be changed, make sure that
# the same changes are done in resource_modify, KLIB_HACMP_add_cluster,
# and KLIB_HACMP_modify_cluster, as needed.
#
#========================================================================
function add_cluster {
    . $HALIBROOT/log_entry "$0()" "$CL" max

    typeset -n properties=$1
    typeset name=$2

    if [[ ${_ENV_ARGS[TYPE]} == *([[:space:]]) ]]; then
        #====================================================================
        : Default to a non-site cluster, "NSC", since no type was specified
        #====================================================================
        _ENV_ARGS[TYPE]="NSC"
    fi

    CL=$LINENO KLIB_HACMP_add_cluster properties \
                           "$name" \
                           "${_ENV_ARGS[NODES]}" \
                           "${_ENV_ARGS[FC_SYNC_INTERVAL]}" \
                           "${_ENV_ARGS[RG_SETTLING_TIME]}" \
                           "${_ENV_ARGS[RG_DIST_POLICY]}" \
                           "${_ENV_ARGS[MAX_EVENT_TIME]}" \
                           "${_ENV_ARGS[MAX_RG_PROCESSING_TIME]}" \
                           "${_ENV_ARGS[SITE_POLICY_FAILURE_ACTION]}" \
                           "${_ENV_ARGS[SITE_POLICY_NOTIFY_METHOD]}" \
                           "${_ENV_ARGS[DAILY_VERIFICATION]}" \
                           "${_ENV_ARGS[VERIFICATION_NODE]}" \
                           "${_ENV_ARGS[VERIFICATION_HOUR]}" \
                           "${_ENV_ARGS[VERIFICATION_DEBUGGING]}" \
                           "${_ENV_ARGS[REPOSITORIES]}" \
                           "${_ENV_ARGS[CLUSTER_IP]}" \
                           "${_ENV_ARGS[HEARTBEAT_FREQUENCY]}" \
                           "${_ENV_ARGS[GRACE_PERIOD]}" \
                           "${_ENV_ARGS[SITE_HEARTBEAT_CYCLE]}" \
                           "${_ENV_ARGS[SITE_GRACE_PERIOD]}" \
                           "${_ENV_ARGS[TYPE]}" \
                           "${_ENV_ARGS[HEARTBEAT_TYPE]}" \
                           "${_ENV_ARGS[TEMP_HOSTNAME]}" \
                           "${_ENV_ARGS[LPM_POLICY]}" \
                           "${_ENV_ARGS[HEARTBEAT_FREQUENCY_DURING_LPM]}" \
                           "${_ENV_ARGS[NETWORK_FAILURE_DETECTION_TIME]}" \
                           "${_ENV_ARGS[CAA_AUTO_START_DR]}" \
                           "${_ENV_ARGS[CAA_REPOS_MODE]}" \
                           "${_ENV_ARGS[CAA_CONFIG_TIMEOUT]}" \
                           "${_ENV_ARGS[LVM_PREFERRED_READ]}" \
                           "${_ENV_ARGS[CRIT_DAEMON_RESTART_GRACE_PERIOD]}" \
                           "${_ENV_ARGS[SKIP_EVENT_PROCESSING_MANAGE_MODE]}"
    log_return_msg "$?" "$0()" "$LINENO"
    return $?
} # End of "add_cluster()"


#
# Name:  add_repository
#
function add_repository {
    . $HALIBROOT/log_entry "$0()" "$CL" max

    typeset -n properties=$1
    typeset disks=$2

    CL=$LINENO KLIB_HACMP_add_repository properties \
                              "$disks" \
                              "${_ENV_ARGS[SITE]}" \
                              "${_ENV_ARGS[NODE]}" \
                              "${_ENV_ARGS[DISABLE_VALIDATION]}"
    log_return_msg "$?" "$0()" "$LINENO"
    return $?
} # End of "add_repository()"


#
# Name:  add_site
#
function add_site {
    . $HALIBROOT/log_entry "$0()" "$CL" max

    typeset -n properties=$1
    typeset name=$2

    CL=$LINENO KLIB_HACMP_add_site properties \
                        "$name" \
                        "${_ENV_ARGS[NODES]}" \
                        "${_ENV_ARGS[SITE_IP]}" \
                        "${_ENV_ARGS[RECOVERY_PRIORITY]}" \
                        "${_ENV_ARGS[REPOSITORIES]}"
    log_return_msg "$?" "$0()" "$LINENO"
    return $?
} # End of "add_site()"


#
# Name:  add_node
#
function add_node {
    . $HALIBROOT/log_entry "$0()" "$CL" max

    typeset -n properties=$1
    typeset name=$2

    CL=$LINENO KLIB_HACMP_add_node properties \
                        "$name" \
                        "${_ENV_ARGS[COMMPATH]}" \
                        "${_ENV_ARGS[RUN_DISCOVERY]}" \
                        "${_ENV_ARGS[PERSISTENT_IP]}" \
                        "${_ENV_ARGS[NETWORK]}" \
                        "${_ENV_ARGS[PREFIX]}" \
                        "${_ENV_ARGS[NETMASK]}" \
                        "${_ENV_ARGS[START_ON_BOOT]}" \
                        "${_ENV_ARGS[BROADCAST_ON_START]}" \
                        "${_ENV_ARGS[CLINFO_ON_START]}" \
                        "${_ENV_ARGS[SITE]}" \
                        "${_ENV_ARGS[CRIT_DAEMON_RESTART_GRACE_PERIOD]}"
    log_return_msg "$?" "$0()" "$LINENO"
    return $?
} # End of "add_node()"


#
# Name:  add_network
#
function add_network {
    . $HALIBROOT/log_entry "$0()" "$CL" max

    typeset -n properties=$1
    typeset name=$2

    CL=$LINENO KLIB_HACMP_add_network properties \
                           "$name" \
                           "${_ENV_ARGS[TYPE]}" \
                           "${_ENV_ARGS[NETMASK]}" \
                           "${_ENV_ARGS[PREFIX]}" \
                           "${_ENV_ARGS[PUBLIC]}" \
                           "${_ENV_ARGS[UNSTABLE_THRESHOLD]}" \
                           "${_ENV_ARGS[UNSTABLE_PERIOD]}"

    log_return_msg "$?" "$0()" "$LINENO"
    return $?
} # End of "add_network()"


#
# Name:  add_interface
#
function add_interface {
    . $HALIBROOT/log_entry "$0()" "$CL" max

    typeset -n properties=$1
    typeset name=$2

    CL=$LINENO KLIB_HACMP_add_interface properties \
                             "$name" \
                             "${_ENV_ARGS[TYPE]}" \
                             "${_ENV_ARGS[NETWORK]}" \
                             "${_ENV_ARGS[NODE]}" \
                             "${_ENV_ARGS[INTERFACE]}"
    log_return_msg "$?" "$0()" "$LINENO"
    return $?
} # End of "add_interface()"


#
# Name:  add_persistent_ip
#
function add_persistent_ip {
    . $HALIBROOT/log_entry "$0()" "$CL" max

    typeset -n properties=$1
    typeset name=$2

    CL=$LINENO KLIB_HACMP_add_persistent_ip properties   \
                                 "$name"                 \
                                 "${_ENV_ARGS[NETWORK]}" \
                                 "${_ENV_ARGS[NODE]}"    \
                                 "${_ENV_ARGS[NETMASK]}" \
                                 "${_ENV_ARGS[PREFIX]}"
    log_return_msg "$?" "$0()" "$LINENO"
    return $?
} # End of "add_persistent_ip()"


#
# Name:  add_resource_group
#
function add_resource_group {
    . $HALIBROOT/log_entry "$0()" "$CL" max

    typeset -n properties=$1
    typeset name=$2

    typeset -u FO=${_ENV_ARGS[FALLOVER]}
    typeset -u FB=${_ENV_ARGS[FALLBACK]}
    typeset -u ST=${_ENV_ARGS[STARTUP]}

    typeset -A nodelist
    typeset -A behavior
    behavior=(
        [fallover]=$FO
        [fallback]=$FB
        [startup]=$ST
    )

    nodelist=(
        [nodes]=${_ENV_ARGS[NODES]}
        [primary]=${_ENV_ARGS[PRIMARYNODES]}
        [secondary]=${_ENV_ARGS[SECONDARYNODES]}
    )

    typeset resource_env="FALLBACK_AT SERVICE_LABEL APPLICATIONS \
VOLUME_GROUP FORCED_VARYON VG_AUTO_IMPORT FILESYSTEM FSCHECK_TOOL \
RECOVERY_METHOD FS_BEFORE_IPADDR EXPORT_FILESYSTEM EXPORT_FILESYSTEM_V4 \
MOUNT_FILESYSTEM STABLE_STORAGE_PATH WPAR_NAME \
NFS_NETWORK SHARED_TAPE_RESOURCES DISK AIX_FAST_CONNECT_SERVICES \
COMMUNICATION_LINKS WLM_PRIMARY WLM_SECONDARY MISC_DATA \
NODE_PRIORITY_POLICY NODE_PRIORITY_POLICY_SCRIPT \
NODE_PRIORITY_POLICY_TIMEOUT CONCURRENT_VOLUME_GROUP"
    typeset attr
    typeset -A attributes
    typeset -A policies

    for attr1 in ${!_ENV_ARGS[@]} ; do
        for attr2 in $resource_env; do
            [[ $attr1 == $attr2 ]] &&
                attributes[$attr1]="${_ENV_ARGS[$attr1]}"
        done
    done

    for attr1 in ${!_ENV_ARGS[@]} ; do
        for attr2 in $policy_env; do
            [[ $attr1 == $attr2 ]] &&
                policies[$attr1]=${_ENV_ARGS[$attr1]}
        done
    done

    CL=$LINENO KLIB_HACMP_add_resourcegroup properties \
                                 "$name" \
                                 nodelist \
                                 behavior \
                                 attributes \
                                 "${_ENV_ARGS[SITE_POLICY]}" \
                                 "${_ENV_ARGS[MIRROR_GROUP]}"
    log_return_msg "$?" "$0()" "$LINENO"
    return $?
} # End of "add_resource_group()"


#
# Name:  add_appserver
#
function add_appserver {
    . $HALIBROOT/log_entry "$0()" "$CL" max

    typeset -n properties=$1
    typeset name=$2

    CL=$LINENO KLIB_HACMP_add_appserver properties \
                             "$name" \
                             "${_ENV_ARGS[STARTSCRIPT]}" \
                             "${_ENV_ARGS[STOPSCRIPT]}" \
                             "${_ENV_ARGS[MONITORS]}" \
                             "${_ENV_ARGS[STARTUP_MODE]}" \
                             "${_ENV_ARGS[CPU_USAGE_MONITOR]}" \
                             "${_ENV_ARGS[PROCESS_TO_MONITOR_CPU_USAGE]}" \
                             "${_ENV_ARGS[CPU_USAGE_MONITOR_INTERVAL]}"

    log_return_msg "$?" "$0()" "$LINENO"
    return $?
} # End of "add_appserver()"


#
# Name:  add_appmonitor
#
function add_appmonitor {
    . $HALIBROOT/log_entry "$0()" "$CL" max

    typeset -n properties=$1
    typeset name=$2

    typeset -A args
    for i in ${!_ENV_ARGS[*]}
    do
        args[$i]=${_ENV_ARGS[$i]}
    done

    CL=$LINENO KLIB_HACMP_add_appmonitor properties \
                              "$name" \
                              args
    log_return_msg "$?" "$0()" "$LINENO"
    return $?
} # End of "add_appmonitor()"


#
# Name:  add_service_ip
#
function add_service_ip {
    . $HALIBROOT/log_entry "$0()" "$CL" max

    typeset -n properties=$1
    typeset name=$2

    CL=$LINENO KLIB_HACMP_add_service_ip properties \
                                 "$name" \
                                 "${_ENV_ARGS[NETWORK]}" \
                                 "${_ENV_ARGS[NETMASK]}" \
                                 "${_ENV_ARGS[PREFIX]}"  \
                                 "${_ENV_ARGS[HWADDR]}"  \
                                 "${_ENV_ARGS[SITE]}"
    log_return_msg "$?" "$0()" "$LINENO"
    return $?
} # End of "add_service_ip()"


#
# Name:  add_tape
#
function add_tape {
    . $HALIBROOT/log_entry "$0()" "$CL" max

    typeset -n properties=$1
    typeset name=$2

    CL=$LINENO KLIB_HACMP_add_tape properties                          \
                        "$name"                             \
                        "${_ENV_ARGS[DEVICE]}"              \
                        "${_ENV_ARGS[DESCRIPTION]}"         \
                        "${_ENV_ARGS[STARTSCRIPT]}"         \
                        "${_ENV_ARGS[START_SYNCHRONOUSLY]}" \
                        "${_ENV_ARGS[STOPSCRIPT]}"          \
                        "${_ENV_ARGS[STOP_SYNCHRONOUSLY]}"
    log_return_msg "$?" "$0()" "$LINENO"
    return $?
} # End of "add_tape()"


#
# Name:  add_file_system
#
function add_file_system {
    . $HALIBROOT/log_entry "$0()" "$CL" max

    typeset -n properties=$1
    typeset name=$2

    CL=$LINENO KLIB_HACMP_add_file_system properties                \
                                  "$name"                           \
                                  "${_ENV_ARGS[VOLUME_GROUP]}"      \
                                  "${_ENV_ARGS[TYPE]}"              \
                                  "${_ENV_ARGS[UNITS]}"             \
                                  "${_ENV_ARGS[SIZE_PER_UNIT]}"     \
                                  "${_ENV_ARGS[PERMISSIONS]}"       \
                                  "${_ENV_ARGS[OPTIONS]}"           \
                                  "${_ENV_ARGS[BLOCK_SIZE]}"        \
                                  "${_ENV_ARGS[LV_FOR_LOG]}"        \
                                  "${_ENV_ARGS[INLINE_LOG_SIZE]}"   \
                                  "${_ENV_ARGS[EXT_ATTR_FORMAT]}"   \
                                  "${_ENV_ARGS[ENABLE_QUOTA_MGMT]}" \
                                  "${_ENV_ARGS[EFS]}"               \
                                  "${_ENV_ARGS[DISK_ACCOUNTING]}"   \
                                  "${_ENV_ARGS[FRAGMENT_SIZE]}"     \
                                  "${_ENV_ARGS[BYTES_PER_INODE]}"   \
                                  "${_ENV_ARGS[ALLOC_GROUP_SIZE]}"  \
                                  "${_ENV_ARGS[LOGICAL_VOLUME]}"    
    log_return_msg "$?" "$0()" "$LINENO"
    return $?
} # End of "add_file_system()"


#
# Name:  add_logical_volume
#
function add_logical_volume {
    . $HALIBROOT/log_entry "$0()" "$CL" max

    typeset -n properties=$1
    typeset name=$2

    CL=$LINENO KLIB_HACMP_add_logical_volume properties                   \
                                  "$name"                                 \
                                  "${_ENV_ARGS[VOLUME_GROUP]}"            \
                                  "${_ENV_ARGS[LOGICAL_PARTITIONS]}"      \
                                  "${_ENV_ARGS[PHYSICAL_VOLUMES]}"        \
                                  "${_ENV_ARGS[TYPE]}"                    \
                                  "${_ENV_ARGS[POSITION]}"                \
                                  "${_ENV_ARGS[PV_RANGE]}"                \
                                  "${_ENV_ARGS[MAX_PVS_FOR_NEW_ALLOC]}"   \
                                  "${_ENV_ARGS[LPART_COPIES]}"            \
                                  "${_ENV_ARGS[WRITE_CONSISTENCY]}"       \
                                  "${_ENV_ARGS[LPARTS_ON_SEPARATE_PVS]}"  \
                                  "${_ENV_ARGS[RELOCATE]}"                \
                                  "${_ENV_ARGS[MAX_LPARTS]}"              \
                                  "${_ENV_ARGS[BAD_BLOCK_RELOCATION]}"    \
                                  "${_ENV_ARGS[SCHEDULING_POLICY]}"       \
                                  "${_ENV_ARGS[VERIFY_WRITES]}"           \
                                  "${_ENV_ARGS[ALLOCATION_MAP]}"          \
                                  "${_ENV_ARGS[STRIPE_SIZE]}"             \
                                  "${_ENV_ARGS[SERIALIZE_IO]}"            \
                                  "${_ENV_ARGS[FIRST_BLOCK_AVAILABLE]}"   \
                                  "${_ENV_ARGS[FIRST_COPY_MIRROR_POOL]}"  \
                                  "${_ENV_ARGS[SECOND_COPY_MIRROR_POOL]}" \
                                  "${_ENV_ARGS[THIRD_COPY_MIRROR_POOL]}"  \
                                  "${_ENV_ARGS[GROUP]}"                   \
                                  "${_ENV_ARGS[PERMISSIONS]}"             \
                                  "${_ENV_ARGS[LABEL]}"                   \
                                  "${_ENV_ARGS[NODE]}"                    \
                                  "${_ENV_ARGS[ENABLE_LV_ENCRYPTION]}"       \
                                  "${_ENV_ARGS[AUTH_METHOD]}"             \
                                  "${_ENV_ARGS[METHOD_DETAILS]}"          \
                                  "${_ENV_ARGS[AUTH_METHOD_NAME]}"  
    log_return_msg "$?" "$0()" "$LINENO"
    return $?
} # End of "add_logical_volume()"


#
# Name:  add_volume_group
#
function add_volume_group {
    . $HALIBROOT/log_entry "$0()" "$CL" max

    typeset -n properties=$1
    typeset name=$2

    CL=$LINENO KLIB_HACMP_add_volume_group properties                   \
                                "$name"                                 \
                                "${_ENV_ARGS[NODES]}"                   \
                                "${_ENV_ARGS[PHYSICAL_VOLUMES]}"        \
                                "${_ENV_ARGS[TYPE]}"                    \
                                "${_ENV_ARGS[RESOURCE_GROUP]}"          \
                                "${_ENV_ARGS[PPART_SIZE]}"              \
                                "${_ENV_ARGS[MAJOR_NUMBER]}"            \
                                "${_ENV_ARGS[ACTIVATE_ON_RESTART]}"     \
                                "${_ENV_ARGS[QUORUM_NEEDED]}"           \
                                "${_ENV_ARGS[LTG_SIZE]}"                \
                                "${_ENV_ARGS[MIGRATE_FAILED_DISKS]}"    \
                                "${_ENV_ARGS[MAX_PHYSICAL_PARTITIONS]}" \
                                "${_ENV_ARGS[MAX_LOGICAL_VOLUMES]}"     \
                                "${_ENV_ARGS[MIRROR_POOL_NAME]}"        \
                                "${_ENV_ARGS[STRICT_MIRROR_POOLS]}"     \
                                "${_ENV_ARGS[CRITICAL]}"                \
                                "${_ENV_ARGS[FAILUREACTION]}"           \
                                "${_ENV_ARGS[NOTIFYMETHOD]}"            \
                                "${_ENV_ARGS[LVM_PREFERRED_READ]}"      \
                                "${_ENV_ARGS[ENABLE_LV_ENCRYPTION]}"
    log_return_msg "$?" "$0()" "$LINENO"
    return $?
} # End of "add_volume_group()"


#
# Name:  add_mirror_pool
#
function add_mirror_pool {
    . $HALIBROOT/log_entry "$0()" "$CL" max

    typeset -n properties=$1
    typeset name=$2

    CL=$LINENO KLIB_HACMP_add_mirror_pool properties             \
                                "$name"                          \
                                "${_ENV_ARGS[VOLUME_GROUP]}"     \
                                "${_ENV_ARGS[PHYSICAL_VOLUMES]}" \
                                "${_ENV_ARGS[STORAGE_LOCATION]}"     \
                                "${_ENV_ARGS[MODE]}"             \
                                "${_ENV_ARGS[ASYNC_CACHE_LV]}"   \
                                "${_ENV_ARGS[ASYNC_CACHE_HW_MARK]}"
    log_return_msg "$?" "$0()" "$LINENO"
    return $?
} # End of "add_mirror_pool()"


#
# Name:  add_file_collection
#
function add_file_collection {
    . $HALIBROOT/log_entry "$0()" "$CL" max

    typeset -n properties=$1
    typeset name=$2
    typeset files=${_ENV_ARGS["FILES"]}

    CL=$LINENO KLIB_HACMP_add_filecollection properties \
                                  "$name" \
                                  files \
                                  "${_ENV_ARGS[SYNC_WITH_CLUSTER]}" \
                                  "${_ENV_ARGS[SYNC_WHEN_CHANGED]}" \
                                  "${_ENV_ARGS[DESCRIPTION]}"
    log_return_msg "$?" "$0()" "$LINENO"
    return $?
} # End of "add_file_collection()"


#
# Name:  add_dependency
#
function add_dependency {
    . $HALIBROOT/log_entry "$0()" "$CL" max

    CL=$LINENO KLIB_HACMP_add_dependency \
        "${_ENV_ARGS[PARENT]}" \
        "${_ENV_ARGS[CHILD]}" \
        "${_ENV_ARGS[SAME]}" \
        "${_ENV_ARGS[GROUPS]}" \
        "${_ENV_ARGS[HIGH]}" \
        "${_ENV_ARGS[INTERMEDIATE]}" \
        "${_ENV_ARGS[LOW]}" \
        "${_ENV_ARGS[STOP]}" \
        "${_ENV_ARGS[START]}" \
        "${_ENV_ARGS[AFTER]}" \
        "${_ENV_ARGS[TYPE]}" \
        "${_ENV_ARGS[SERIAL]}" \
        "${_ENV_ARGS[PARALLEL]}"
    log_return_msg "$?" "$0()" "$LINENO"
    return $?
} # End of "add_dependency()"


#
# Name:  add_snapshot
#
function add_snapshot {
    . $HALIBROOT/log_entry "$0()" "$CL" max

    typeset -n properties=$1
    typeset name=$2

    CL=$LINENO KLIB_HACMP_add_snapshot properties \
                            "$name" \
                            "${_ENV_ARGS[DESCRIPTION]}" \
                            "${_ENV_ARGS[METHODS]}" \
                            "${_ENV_ARGS[MISC_INFO]}"
    log_return_msg "$?" "$0()" "$LINENO"
    return $?
} # End of "add_snapshot()"


#
# Name:  add_method
#
function add_method {
    . $HALIBROOT/log_entry "$0()" "$CL" max

    typeset -n properties=$1
    typeset name=$2

    CL=$LINENO KLIB_HACMP_add_method properties \
                          "$name" \
                          "${_ENV_ARGS[TYPE]}" \
                          "${_ENV_ARGS[DESCRIPTION]}" \
                          "${_ENV_ARGS[FILE]}" \
                          "${_ENV_ARGS[CONTACT]}" \
                          "${_ENV_ARGS[EVENTS]}" \
                          "${_ENV_ARGS[NODES]}" \
                          "${_ENV_ARGS[RETRY]}" \
                          "${_ENV_ARGS[TIMEOUT]}" \
                          "${_ENV_ARGS[SOURCE]}"
    log_return_msg "$?" "$0()" "$LINENO"
    return $?
} # End of "add_method()"


#
# Name:  add_fallback_timer
#
function add_fallback_timer {
    . $HALIBROOT/log_entry "$0()" "$CL" max

    typeset -n properties=$1
    typeset name=$2

    CL=$LINENO KLIB_HACMP_add_fallback_timer properties \
                                  "$name" \
                                  "${_ENV_ARGS[YEAR]}" \
                                  "${_ENV_ARGS[MONTH]}" \
                                  "${_ENV_ARGS[DAY_OF_MONTH]}" \
                                  "${_ENV_ARGS[DAY_OF_WEEK]}" \
                                  "${_ENV_ARGS[HOUR]}" \
                                  "${_ENV_ARGS[MINUTE]}"
    log_return_msg "$?" "$0()" "$LINENO"
    return $?
} # End of "add_fallback_timer()"


#
# Name:  add_ldap_server
#
function add_ldap_server {
    . $HALIBROOT/log_entry "$0()" "$CL" max

    typeset -n properties=$1
    typeset name=$2

    CL=$LINENO KLIB_HACMP_add_ldap_server properties \
                               "$name" \
                               "${_ENV_ARGS[ADMIN_DN]}" \
                               "${_ENV_ARGS[PASSWORD]}" \
                               "${_ENV_ARGS[BASE_DN]}" \
                               "${_ENV_ARGS[SSL_KEY]}" \
                               "${_ENV_ARGS[SSL_PASSWORD]}" \
                               "${_ENV_ARGS[PORT]}" \
                               "${_ENV_ARGS[SCHEMA]}" \
                               "${_ENV_ARGS[VERSION]}" \
                               "${_ENV_ARGS[DB2_INSTANCE_PASSWORD]}" \
                               "${_ENV_ARGS[ENCRYPTION_SEED]}"
    log_return_msg "$?" "$0()" "$LINENO"
    return $?
} # End of "add_ldap_server()"


#
# Name:  add_ldap_client
#
function add_ldap_client {
    . $HALIBROOT/log_entry "$0()" "$CL" max

    typeset -n properties=$1

    CL=$LINENO KLIB_HACMP_add_ldap_client properties \
                               "${_ENV_ARGS[SERVERS]}" \
                               "${_ENV_ARGS[BIND_DN]}" \
                               "${_ENV_ARGS[PASSWORD]}" \
                               "${_ENV_ARGS[BASE_DN]}" \
                               "${_ENV_ARGS[SSL_KEY]}" \
                               "${_ENV_ARGS[SSL_PASSWORD]}" \
                               "${_ENV_ARGS[PORT]}"
    log_return_msg "$?" "$0()" "$LINENO"
    return $?
} # End of "add_ldap_client()"


#
# Name:  add_user
#
function add_user {
    . $HALIBROOT/log_entry "$0()" "$CL" max

    typeset -n properties=$1
    typeset name=$2

    CL=$LINENO KLIB_HACMP_add_user properties \
                        "$name" \
                        "${_ENV_ARGS[RESOURCE_GROUP]}" \
                        "${_ENV_ARGS[ID]}" \
                        "${_ENV_ARGS[KEYSTORE_ACCESS]}" \
                        "${_ENV_ARGS[ADMIN_KEYSTORE_ACCESS]}" \
                        "${_ENV_ARGS[KEYSTORE_MODE]}" \
                        "${_ENV_ARGS[ALLOW_MODE_CHANGE]}" \
                        "${_ENV_ARGS[KEYSTORE_ENCRYPTION]}" \
                        "${_ENV_ARGS[FILE_ENCRYPTION]}" \
                        "${_ENV_ARGS[REGISTRY]}" \
                        "${_ENV_ARGS[AUTHENTICATION]}" \
                        "${_ENV_ARGS[GROUPS]}" \
                        "${_ENV_ARGS[PRIMARY]}" \
                        "${_ENV_ARGS[ADMIN_GROUPS]}" \
                        "${_ENV_ARGS[ROLES]}" \
                        "${_ENV_ARGS[SWITCH_USER]}" \
                        "${_ENV_ARGS[SU_GROUPS]}" \
                        "${_ENV_ARGS[HOME]}" \
                        "${_ENV_ARGS[SHELL]}" \
                        "${_ENV_ARGS[INFO]}" \
                        "${_ENV_ARGS[EXPIRATION]}" \
                        "${_ENV_ARGS[LOCKED]}" \
                        "${_ENV_ARGS[LOGIN]}" \
                        "${_ENV_ARGS[REMOTE_LOGIN]}" \
                        "${_ENV_ARGS[SCHEDULE]}" \
                        "${_ENV_ARGS[MAX_FAILED_LOGINS]}" \
                        "${_ENV_ARGS[ALLOWED_TTYS]}" \
                        "${_ENV_ARGS[DAYS_TO_WARN]}" \
                        "${_ENV_ARGS[PASSWORD_VALIDATION_METHODS]}" \
                        "${_ENV_ARGS[PASSWORD_FILTERS]}" \
                        "${_ENV_ARGS[MIN_PASSWORDS]}" \
                        "${_ENV_ARGS[REUSE_TIME]}" \
                        "${_ENV_ARGS[LOCKOUT_DELAY]}" \
                        "${_ENV_ARGS[MAX_PASSWORD_AGE]}" \
                        "${_ENV_ARGS[MIN_PASSWORD_AGE]}" \
                        "${_ENV_ARGS[MIN_PASSWORD_LENGTH]}" \
                        "${_ENV_ARGS[MIN_PASSWORD_ALPHAS]}" \
                        "${_ENV_ARGS[MIN_PASSWORD_OTHERS]}" \
                        "${_ENV_ARGS[MAX_PASSWORD_REPEATED_CHARS]}" \
                        "${_ENV_ARGS[MIN_PASSWORD_DIFFERENT]}" \
                        "${_ENV_ARGS[UMASK]}" \
                        "${_ENV_ARGS[AUDIT_CLASSES]}" \
                        "${_ENV_ARGS[TRUSTED_PATH]}" \
                        "${_ENV_ARGS[PRIMARY_AUTH]}" \
                        "${_ENV_ARGS[SECONDARY_AUTH]}" \
                        "${_ENV_ARGS[PROJECTS]}" \
                        "${_ENV_ARGS[ADMINISTRATIVE]}" \
                        "${_ENV_ARGS[PASSWORD]}" \
                        "${_ENV_ARGS[CHANGE_ON_NEXT_LOGIN]}" \
                        "${_ENV_ARGS[ALLOW_PASSWORD_CHANGE]}"
    log_return_msg "$?" "$0()" "$LINENO"
    return $?
} # End of "add_user()"


#
# Name:  add_group
#
function add_group {
    . $HALIBROOT/log_entry "$0()" "$CL" max

    typeset -n properties=$1
    typeset name=$2

    CL=$LINENO KLIB_HACMP_add_group properties \
                         "$name" \
                         "${_ENV_ARGS[RESOURCE_GROUP]}" \
                         "${_ENV_ARGS[ID]}" \
                         "${_ENV_ARGS[ADMINISTRATIVE]}" \
                         "${_ENV_ARGS[USERS]}" \
                         "${_ENV_ARGS[ADMINS]}" \
                         "${_ENV_ARGS[PROJECTS]}" \
                         "${_ENV_ARGS[KEYSTORE_MODE]}" \
                         "${_ENV_ARGS[KEYSTORE_ENCRYPTION]}" \
                         "${_ENV_ARGS[KEYSTORE_ACCESS]}" \
                         "${_ENV_ARGS[REGISTRY]}"
    log_return_msg "$?" "$0()" "$LINENO"
    return $?
} # End of "add_group()"


#
# Name:  add_efs
#
function add_efs {
    . $HALIBROOT/log_entry "$0()" "$CL" max

    typeset -n properties=$1

    CL=$LINENO KLIB_HACMP_add_efs properties \
                       "${_ENV_ARGS[MODE]}" \
                       "${_ENV_ARGS[VOLUME_GROUP]}" \
                       "${_ENV_ARGS[SERVICE_IP]}" \
                       "${_ENV_ARGS[PASSWORD]}"
    log_return_msg "$?" "$0()" "$LINENO"
    return $?
} # End of "add_efs()"


#
# Name:  add_storage_agent
#
function add_storage_agent {
    . $HALIBROOT/log_entry "$0()" "$CL" max

    typeset -n properties=$1
    typeset name=$2

    CL=$LINENO KLIB_HACMP_add_storage_agent properties \
                                 "$name" \
                                 "${_ENV_ARGS[TYPE]}" \
                                 "${_ENV_ARGS[ADDRESSES]}" \
                                 "${_ENV_ARGS[USER]}" \
                                 "${_ENV_ARGS[PASSWORD]}" \
                                 "${_ENV_ARGS[ATTRIBUTES]}"
    log_return_msg "$?" "$0()" "$LINENO"
    return $?
} # End of "add_storage_agent()"


#
# Name:  add_storage_system
#
function add_storage_system {
    . $HALIBROOT/log_entry "$0()" "$CL" max

    typeset -n properties=$1
    typeset name=$2

    CL=$LINENO KLIB_HACMP_add_storage_system properties \
                                  "$name" \
                                  "${_ENV_ARGS[TYPE]}" \
                                  "${_ENV_ARGS[AGENTS]}" \
                                  "${_ENV_ARGS[SITE]}" \
                                  "${_ENV_ARGS[VENDOR_ID]}" \
                                  "${_ENV_ARGS[WWNN]}" \
                                  "${_ENV_ARGS[ROLE]}" \
                                  "${_ENV_ARGS[ADDRESSES]}" \
                                  "${_ENV_ARGS[PARTNER]}" \
                                  "${_ENV_ARGS[ATTRIBUTES]}" \
                                  "${_ENV_ARGS[USER]}" \
                                  "${_ENV_ARGS[BACKUP_PROFILE]}" 
    log_return_msg "$?" "$0()" "$LINENO"
    return $?
} # End of "add_storage_system()"


#
# Name:  add_mirror_pair
#
function add_mirror_pair {
    . $HALIBROOT/log_entry "$0()" "$CL" max

    typeset -n properties=$1
    typeset name=$2

    CL=$LINENO KLIB_HACMP_add_mirror_pair properties \
                               "$name" \
                               "${_ENV_ARGS[FIRST_DISK]}" \
                               "${_ENV_ARGS[SECOND_DISK]}"
    log_return_msg "$?" "$0()" "$LINENO"
    return $?
} # End of "add_mirror_pair()"


#
# Name:  add_mirror_group
#
function add_mirror_group {
    . $HALIBROOT/log_entry "$0()" "$CL" max

    typeset -n properties=$1
    typeset name=$2

    CL=$LINENO KLIB_HACMP_add_mirror_group properties \
                                "$name" \
                                "${_ENV_ARGS[TYPE]}" \
                                "${_ENV_ARGS[MODE]}" \
                                "${_ENV_ARGS[RECOVERY]}" \
                                "${_ENV_ARGS[STORAGE_SYSTEMS]}" \
                                "${_ENV_ARGS[MIRROR_PAIRS]}" \
                                "${_ENV_ARGS[CONSISTENT]}" \
                                "${_ENV_ARGS[VENDOR_ID]}" \
                                "${_ENV_ARGS[HORCM_INSTANCE]}" \
                                "${_ENV_ARGS[HORCM_TIMEOUT]}" \
                                "${_ENV_ARGS[PAIR_EVENT_TIMEOUT]}" \
                                "${_ENV_ARGS[VOLUME_GROUPS]}" \
                                "${_ENV_ARGS[DISKS]}" \
                                "${_ENV_ARGS[HYPERSWAP_ENABLED]}" \
                                "${_ENV_ARGS[HYPERSWAP_PRIORITY]}" \
                                "${_ENV_ARGS[UNPLANNED_HS_TIMEOUT]}" \
                                "${_ENV_ARGS[MG_TYPE]}" \
                                "${_ENV_ARGS[NODE]}" \
                                "${_ENV_ARGS[SITE]}" \
                                "${_ENV_ARGS[NON_HS_DISK]}" \
                                "${_ENV_ARGS[HS_DISK]}" \
                                "${_ENV_ARGS[ATTRIBUTES]}" \
                                "${_ENV_ARGS[RESYNC]}"
    log_return_msg "$?" "$0()" "$LINENO"
    return $?
} # End of "add_mirror_group()"


#
# Name:  add_event
#
function add_event {
    . $HALIBROOT/log_entry "$0()" "$CL" max

    typeset -n properties=$1
    typeset name=$2

    CL=$LINENO KLIB_HACMP_add_event properties \
                         "$name" \
                         "${_ENV_ARGS[FILE]}" \
                         "${_ENV_ARGS[DESCRIPTION]}"
    log_return_msg "$?" "$0()" "$LINENO"
    return $?
} # End of "add_event()"


#
# Name:  add_hmc
#
function add_hmc {
    . $HALIBROOT/log_entry "$0()" "$CL" max

    typeset -n properties=$1
    typeset name=$2

    CL=$LINENO KLIB_HACMP_add_hmc properties \
                         "$name" \
                         "${_ENV_ARGS[TIMEOUT]}" \
                         "${_ENV_ARGS[RETRY_COUNT]}" \
                         "${_ENV_ARGS[RETRY_DELAY]}" \
                         "${_ENV_ARGS[NODES]}"  \
                         "${_ENV_ARGS[SITES]}"  \
                         "${_ENV_ARGS[CHECK_HMC]}" \
                         "${_ENV_ARGS[USER_NAME]}" \
                         "${_ENV_ARGS[PASSWORD]}" 

    log_return_msg "$?" "$0()" "$LINENO"
    return $?
} # End of "add_hmc()"

#
# Name:  add_nova
#
function add_nova {
    . $HALIBROOT/log_entry "$0()" "$CL" max

    typeset -n properties=$1
    typeset name=$2

    CL=$LINENO KLIB_HACMP_add_nova properties \
                         "$name" \
                         "${_ENV_ARGS[TIMEOUT]}" \
                         "${_ENV_ARGS[RETRY_COUNT]}" \
                         "${_ENV_ARGS[RETRY_DELAY]}" \
                         "${_ENV_ARGS[USER_NAME]}" \
                         "${_ENV_ARGS[PASSWORD]}" 

    log_return_msg "$?" "$0()" "$LINENO"
    return $?
} # End of "add_nova()"


#
# Name:  add_cod
#
function add_cod {
    . $HALIBROOT/log_entry "$0()" "$CL" max

    typeset -n properties=$1
    typeset name=$2

    CL=$LINENO KLIB_HACMP_add_cod properties \
                         "$name" \
                         "${_ENV_ARGS[USE_DESIRED]}" \
                         "${_ENV_ARGS[OPTIMAL_MEM]}" \
                         "${_ENV_ARGS[OPTIMAL_CPU]}" \
                         "${_ENV_ARGS[OPTIMAL_PU]}"  \
                         "${_ENV_ARGS[OPTIMAL_VP]}"
    log_return_msg "$?" "$0()" "$LINENO"
    return $?
} # End of "add_cod()"

#
# Name:  add_backup
#
function add_backup {
    . $HALIBROOT/log_entry "$0()" "$CL" max

    typeset -n properties=$1
    typeset name=$2

    CL=$LINENO KLIB_HACMP_add_backup properties \
                                        "$name"
    log_return_msg "$?" "$0()" "$LINENO"
    return $?
} # End of "add_backup()"

#
# Name:  add_backup_profile
#
function add_backup_profile {
    . $HALIBROOT/log_entry "$0()" "$CL" max

    typeset -n properties=$1
    typeset name=$2

    CL=$LINENO KLIB_HACMP_add_backup_profile properties                           \
                                                "$name"                              \
                                                "${_ENV_ARGS[ENABLE_BACKUP]}"        \
                                                "${_ENV_ARGS[VOLUME_GROUP]}"         \
                                                "${_ENV_ARGS[REPLICATED_RESOURCES]}"             \
                                                "${_ENV_ARGS[STORAGE_NAME]}"      \
                                                "${_ENV_ARGS[BUCKET_NAME]}"      \
                                                "${_ENV_ARGS[TARGET_LOCATION]}"      \
                                                "${_ENV_ARGS[BACKUP_METHOD]}"        \
                                                "${_ENV_ARGS[CLOUD_SERVICE]}"        \
                                                "${_ENV_ARGS[COMPRESSION]}"          \
                                                "${_ENV_ARGS[BACKUP_FREQUENCY]}"     \
                                                "${_ENV_ARGS[BACKUP_SCHEDULE]}"      \
                                                "${_ENV_ARGS[INC_BACKUP_FREQ]}"      \
                                                "${_ENV_ARGS[NOTIFYMETHOD]}"         \
                                                "${_ENV_ARGS[ENCRYPTION]}"
    log_return_msg "$?" "$0()" "$LINENO"
    return $?
} # End of "add_backup_profile()"

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

. $HALIBROOT/log_entry resource_add "$CL" max
: version=@(#)  d82b234 43haes/usr/sbin/cluster/events/resource_add.sh, 726, 2147A_aha726, Apr 29 2021 12:22 AM

#########################################################################
# Global Declarations
#########################################################################
integer unwind_idx=0
export unwind_idx unwind

#=========================================================================
# This is the list of functions we need to call to determine if there
# are dependencies for any of these resources.  If we can automatically
# construct any of these resources before attempting to call the KLIB
# function do so.  If any of these dependencies fail, we won't construct
# the HACMP resource
#=========================================================================
typeset -A _CLASS_DEPENDENTS_null
typeset -A _CLASS_DEPENDENTS_root
typeset -A _CLASS_DEPENDENTS_default
typeset -A _CLASS_DEPENDENTS_resource_group
typeset -A _CLASS_DEPENDENTS_need_rgs
typeset -A _CLASS_DEPENDENTS_interface
typeset -A _CLASS_DEPENDENTS_xd
if (( ! CLMGR_DISABLE_DEPENDENCIES )); then
    _CLASS_DEPENDENTS_root=(
        [_DEFAULT_]="_CLASS_DEPENDENTS_default"
        [cluster]="_CLASS_DEPENDENTS_null"
        [repository]="_CLASS_DEPENDENTS_default"
        [site]="_CLASS_DEPENDENTS_default"
        [node]="_CLASS_DEPENDENTS_default"
        [network]="_CLASS_DEPENDENTS_default"
        [interface]="_CLASS_DEPENDENTS_interface"
        [service_ip]="_CLASS_DEPENDENTS_interface"
        [persistent_ip]="_CLASS_DEPENDENTS_interface"
        [resource_group]="_CLASS_DEPENDENTS_resource_group"
        [dependency]="_CLASS_DEPENDENTS_need_rgs"
        [application_monitor]="_CLASS_DEPDENDENTS_default"
        [application_controller]="_CLASS_DEPENDENTS_default"
        [fallback_timer]="_CLASS_DEPENDENTS_default"
        [file_collection]="_CLASS_DEPENDENTS_default"
        [snapshot]="_CLASS_DEPENDENTS_default"
        [user]="_CLASS_DEPENDENTS_default"
        [group]="_CLASS_DEPENDENTS_default"
        [ldap_server]="_CLASS_DEPENDENTS_default"
        [ldap_client]="_CLASS_DEPENDENTS_default"
        [storage_agent]="_CLASS_DEPENDENTS_xd"
        [storage_systems]="_CLASS_DEPENDENTS_xd"
        [mirror_pair]="_CLASS_DEPENDENTS_xd"
        [mirror_group]="_CLASS_DEPENDENTS_xd"
    )

    _CLASS_DEPENDENTS_default=(
        [0]="is_cluster_defined NODE NODES SECONDARYNODES"
    )

    _CLASS_DEPENDENTS_resource_group=(
        [0]="is_cluster_defined NODE NODES SECONDARYNODES"
        [1]="are_nodes_defined NODE NODES SECONDARYNODES"
    )

    _CLASS_DEPENDENTS_need_rgs=(
        [0]="is_cluster_defined NODE NODES SECONDARYNODES"
        [1]="are_nodes_defined NODE NODES SECONDARYNODES"
        [2]="are_rgs_defined PARENT CHILD STOP START AFTER GROUPS HIGH INTERMEDIATE LOW SERIAL PARALLEL"
    )

    _CLASS_DEPENDENTS_interface=(
        [0]="is_cluster_defined NODE NODES SECONDARYNODES"
        [1]="are_nodes_defined NODE NODES SECONDARYNODES"
        [2]="is_network_defined NETWORK"
    )

    _CLASS_DEPENDENTS_xd=(
        [0]="is_cluster_defined NODE NODES SECONDARYNODES"
        [1]="is_enterprise"
    )
fi

#==========================================
# Source the file with common definitions
#==========================================
CL=$LINENO . $HAEVENTS/resource_common "$@"

#===================================
# Create any required dependencies
#===================================
if (( ! CLMGR_DISABLE_DEPENDENCIES )); then
    typeset classDep=
    if [[ $RESOURCE_CLASS == *([[:space:]]) ]]; then
        classDep=${_CLASS_DEPENDENTS_root[_DEFAULT_]}
    else
        classDep=${_CLASS_DEPENDENTS_root[$RESOURCE_CLASS]}
    fi
    CL=$LINENO createClassDependents "$classDep" _VAR_SUBSTITUTIONS
    (( $? != RC_SUCCESS )) && exit $RC_MISSING_DEPENDENCY
fi

unset _CLASS_DEPENDENTS_root _CLASS_DEPENDENTS_xd _CLASS_DEPENDENTS_interface _CLASS_DEPENDENTS_default _CLASS_DEPENDENTS_resource_group _CLASS_DEPENDENTS_need_rgs _CLASS_DEPENDENTS_null

typeset -A properties
CL=$LINENO runClassProcessor "$RESOURCE_CLASS" _VAR_SUBSTITUTIONS _ENV_ARGS properties
typeset -i rc=$?

if (( rc != RC_SUCCESS )); then
    if (( ${#unwind[*]} > 0 )); then
        cl_dspmsg -s $CLMGR_SET $CLMGR_MSGS 1107 '\nERROR:  the primary operation (%1$s) failed, so an attempt will be made to remove any dependencies that were automatically created in support of the operation.\n\n' "${CLMGR_COMMAND/ -T $CLMGR_TRANSACTION_ID}" 1>&2
        integer i=${#unwind[*]}-1
        for (( ; i>=0; i-- )); do
            eval CL=$LINENO ${unwind[$i]} 1>&2
        done
        unset unwind i
    fi
fi

#======================================================================
# If output from this operation was requested, display it now, adding
# a "distinctive" divider to help separate the command(s) output from
# the attributes output in scripts.
#======================================================================
if (( rc == 0 )) && \
   [[ ${_CLASS_PROCESSORS[$RESOURCE_CLASS]} == *+([[:space:]])properties* ]]
then
    if (( CLMGR_VERBOSE )) || [[ -n $CLMGR_ATTRS ]]; then
        dspmsg -s 2 command.cat 9 "\nProperties:\n"
        CL=$LINENO SerializeAsAssociativeArray properties "$RESOURCE_CLASS"
    fi
fi

log_return_msg "$rc" resource_add "$LINENO"
exit $?


#==============================================================================
# The following, comment block attempts to enforce coding standards when this
# file is edited via emacs or vim. This block _must_ appear at the very end
# of the file, or the editor will not find it, and it will be ignored.
#==============================================================================
# Local Variables:
# indent-tabs-mode: nil
# tab-width: 4
# End:
#==============================================================================
# vim: tabstop=4 shiftwidth=4 expandtab
#==============================================================================
