#!/bin/ksh93
# IBM_PROLOG_BEGIN_TAG 
# This is an automatically generated prolog. 
#  
# 61haes_r721 src/43haes/lib/ksh93/hacmp/KLIB_HACMP_get_cod_attributes.sh 1.6.1.6 
#  
# Licensed Materials - Property of IBM 
#  
# Restricted Materials of IBM 
#  
# COPYRIGHT International Business Machines Corp. 2012,2016 
# All Rights Reserved 
#  
# US Government Users Restricted Rights - Use, duplication or 
# disclosure restricted by GSA ADP Schedule Contract with IBM Corp. 
#  
# IBM_PROLOG_END_TAG 
# @(#)67	1.6.1.6 src/43haes/lib/ksh93/hacmp/KLIB_HACMP_get_cod_attributes.sh, hacmp.assist, 61haes_r721, 1616B_hacmp721 4/20/16 03:01:11

#============================================================================
#
# Name:        KLIB_HACMP_get_cod_attributes
#
# Description: This is the main, FPATH function that is invoked by clmgr
#              to collect capacity on demand information. The cllsserv
#              utility is invoked to extract the necessary data.
#
# Inputs:      See the "devDoc()" function at the bottom of this file.
#
# Outputs:     The properties hash is populated. The only other outputs are
#              any error messages that might be needed.
#
# Returns:     Zero if no errors are detected. Otherwise, an appropriate
#              non-zero value is returned. Refer to the "RETURN" section
#              of the "devDoc()" function at the bottom of this file for
#              the standard return code values/meanings for clmgr.
#
#============================================================================
function KLIB_HACMP_get_cod_attributes {
    LINENO=2 . $HALIBROOT/log_entry "$0()" "$CL"
    : version=1.6.1.6, src/43haes/lib/ksh93/hacmp/KLIB_HACMP_get_cod_attributes.sh, hacmp.assist, 61haes_r721, 1616B_hacmp721
    : INPUTS: $*

    typeset application_controllers=${1//\"/}

    # Get the "properties" associative array reference, and initialize it
    if [[ -z $2 ]] || [[ -n $CLMGR_LOGGING && $2 == "|" ]]; then
        application_controllers=
        typeset -n properties=$1
    else
        typeset -n properties=$2
    fi

    [[ $clmgr_LOGGING == 'med' ]] && set +x  # Only trace param values

    #===================================
    : Declare and initialize variables
    #===================================
    for k in ${!properties[*]}; do unset properties[$k]; done
    typeset -i INDEX=0 rc=$RC_UNKNOWN
    typeset key= application_controller= APPLICATION_CONTROLLER= APPLICATION_CONTROLLERS=
    typeset name= start_script= stop_script=
    typeset use_desired= optimal_mem= optimal_cpu= optimal_pu= optimal_vp=
    typeset -i matches=0
    typeset -u attr= uc_key=
    typeset -A queries
    typeset -i i=0

    #===================================================
    : Check for any specified attribute=value pairs.
    : If any are found, use those to query the output.
    #===================================================
    while (( $# > 0 )); do
        value="$1"
        if [[ $value == *=* ]]; then
            attr=${value%%=*}  # "attr" makes this uppercase
            queries[$attr]="${value#*=}"
        fi
        shift
    done

    #================================================================
    : Check for a defined cluster. No need to continue without one.
    #================================================================
    CL=$LINENO isClusterDefined
    if (( $? != RC_SUCCESS )); then
        rc=$RC_MISSING_DEPENDENCY

    #=======================================
    : Make sure we have something to query
    #=======================================
    elif [[ -n $application_controllers ]]; then
        [[ $application_controllers != *,* ]] && unset INDEX
        for application_controller in ${application_controllers//,/ }; do
            CL=$LINENO KLIB_HACMP_is_known_cod "$application_controller"
            if (( $? != RC_SUCCESS )); then
                dspmsg -s $CLMGR_SET $CLMGR_MSGS 317 '\nERROR: "%1$s" is not configured for Resource Optimized High Availability services.\n\n' "$application_controller" 1>&2
                dspmsg -s $CLMGR_SET $CLMGR_MSGS 169 "Available Application Controllers Configured for Resource Optimized High Availability:\n\n" 1>&2

                typeset available
                CL=$LINENO KLIB_HACMP_list_cod available
                for (( i=0; i<${#available[*]}; i++ )); do
                            if [[ ${available[$i]} != *([[:space:]]) ]]; then
                                print -u2 "\t${available[$i]}"
                            fi
                done
                print -u2 ""
                rc=$RC_NOT_FOUND
            else
                CL=$LINENO KLIB_HACMP_is_known_appserver "$application_controller"
                if (( $? != RC_SUCCESS )); then
                    dspmsg -s $CLMGR_SET $CLMGR_MSGS 102 '\nERROR: "%1$s" does not appear to exist!\n\n' "$application_controller" 1>&2
                    dspmsg -s $CLMGR_SET $CLMGR_MSGS 140 "Available Application Controllers:\n\n" 1>&2

                    typeset available
                    CL=$LINENO KLIB_HACMP_list_appservers available
                    for (( i=0; i<${#available[*]}; i++ )); do
                                if [[ ${available[$i]} != *([[:space:]]) ]]; then
                                    print -u2 "\t${available[$i]}"
                                fi
                    done
                    print -u2 ""
                    rc=$RC_NOT_FOUND
                else
                    APPLICATION_CONTROLLERS="$APPLICATION_CONTROLLERS $application_controller"
                fi
            fi
        done

    elif (( CLMGR_VERBOSE || ${#queries[*]} > 0 )); then
        typeset available
        CL=$LINENO KLIB_HACMP_list_cod available
        rc=$?
        for (( i=0; i<${#available[*]}; i++ )); do
            APPLICATION_CONTROLLERS="$APPLICATION_CONTROLLERS ${available[$i]}"
        done
    else
        dspmsg -s $CLMGR_SET $CLMGR_MSGS 100 "\nERROR: a name/label must be provided.\n\n" 1>&2
        rc=$RC_MISSING_INPUT
    fi
    (( $rc != RC_SUCCESS && rc != RC_UNKNOWN )) && unset APPLICATION_CONTROLLERS

    #================================================================
    : Populate the return hash with the retrieved attributes/values
    #================================================================
    for APPLICATION_CONTROLLER in $APPLICATION_CONTROLLERS; do
        typeset APPLICATION_CONTROLLER_PROPERTIES=
        print -- "$0()[$LINENO]($SECONDS): cllsserv -cl -n $APPLICATION_CONTROLLER" >>$CLMGR_TMPLOG # Always log commands
        APPLICATION_CONTROLLER_PROPERTIES=$(cllsserv -cl -n $APPLICATION_CONTROLLER)
        rc=$?
        print -- "$0()[$LINENO]($SECONDS): cllsserv -cl -n $APPLICATION_CONTROLLER" >>$CLMGR_TMPLOG # Always log commands result
        if (( $rc == RC_SUCCESS )); then
            print -- "$APPLICATION_CONTROLLER_PROPERTIES" |\
                while IFS=: read name start_script stop_script use_desired optimal_mem optimal_cpu optimal_pu optimal_vp rem
              do
                  [[ $name == \#* ]] && continue  # Skip the column headers
                  properties[NAME$INDEX]=$APPLICATION_CONTROLLER
                  properties[USE_DESIRED$INDEX]=$use_desired
                  properties[OPTIMAL_MEM$INDEX]=$optimal_mem
                  properties[OPTIMAL_CPU$INDEX]=$optimal_cpu
                  properties[OPTIMAL_PU$INDEX]=$optimal_pu
                  properties[OPTIMAL_VP$INDEX]=$optimal_vp
                  break
              done
        fi

        #==============================================================
        : Even if there is no value for a given attribute, we want to
        : display a placeholder for it, so the customer always sees a
        : consistent, complete set of attributes.
        #==============================================================
        for key in ${_COLON_ATTR_ORDER[cod]}; do
            if [[ -z ${properties[$key$INDEX]} ]]; then
                properties[$key$INDEX]=""
            fi
        done

        (( INDEX++ ))
        [[ $INDEX == *0 ]] && (( INDEX++ ))
    done

    #==========================================================
    : If any searches/filters were specified, handle them now
    #==========================================================
    if (( $rc == RC_SUCCESS && ${#queries[*]} > 0 )); then
        CL=$LINENO search_properties queries properties
        rc=$?
    fi

    (( $rc == RC_SUCCESS )) && CL=$LINENO prune_indexes properties

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


#============================================================================
#
# Name:        devDoc
#
# Description: This is a never-to-be-called, wrapper function that all the
#              clmgr FPATH functions implement in order to hide embedded
#              syntax from trace logging. This information is implemented
#              in POD format, and can be viewed in a number of ways using
#              POD tools. Some viewing suggestions for this function's POD-
#              formatted information are:
#
#                  perldoc <FILENAME>
#                  pod2text -c <FILENAME>
#                  pod2text -c --code <FILENAME>
#                  pod2html <FILENAME>
#
#              However, the more important use for this information is that
#              it is parsed by clmgr to display the syntax for this file's
#              operation. The information in the "SYNOPSIS" section is used
#              for this purpose. This feature was originally implemented
#              using the man page information. However, in a code review it
#              was pointed out that this approach had to be changed because
#              customers do not have to install the man pages! Therefore, a
#              built-in dependency on man page information would break the
#              automatic help feature of clmgr. So the SYNPOSIS section must
#              be used instead.
#
#              IMPORTANT: As a result of this, it is imperative that the
#                         information in this SYNOPSIS be kept in sync
#                         with the man page information, which is owned
#                         by the IDD team.
#
# Inputs:      None.
#
# Outputs:     None.
#
# Returns:     n/a (not intended to be invoked)
#
#============================================================================
function devDoc {
    : <<'=cut' >/dev/null 2>&1

=head1 NAME

 KLIB_HACMP_get_cod_attributes

=head1 VERSION

 Version Number:  1.6.1.6
 Last Extracted:  4/21/16 18:18:25
 Last Changed:    4/20/16 03:01:11

 Path, Component, Release(, Level):
 src/43haes/lib/ksh93/hacmp/KLIB_HACMP_get_cod_attributes.sh, hacmp.assist, 61haes_r721, 1616B_hacmp721

=head1 SYNOPSIS

 clmgr query cod [<APPCTRL>[,<APPCTRL#2>,...]]
 clmgr -v query cod

 NOTE: the aliases for "cod" are "cuod", "dlpar" and "roha".

=head1 DESCRIPTION

 Retrieves the Resource Optimized High Availability data for one or more
 application controllers defined within the cluster configuration.

=head1 ARGUMENTS

 1. APPCTRL [REQUIRED] [string]
    The label of one or more application controllers (comma
    or space separated) that are to be queried.

 2. properties [REQUIRED] [hash ref]
    An associative array within which data about the
    queried objects can be returned to the caller.

=head1 RETURN

 0: no errors were detected; the operation appears to have been successful
 1: a general error has occurred
 2: a specified resource does not exist, or could not be found
 3: some required input was missing
 4: some detected input was incorrect in some way
 5: a required dependency does not exist
 6: a specified search failed to match any data

=head1 COPYRIGHT

COPYRIGHT International Business Machines Corp. 2012,2015 
All Rights Reserved 

=cut
} # End of the "devDoc()" function


#==============================================================================
# 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
#==============================================================================
