#!/bin/ksh93
# IBM_PROLOG_BEGIN_TAG 
# This is an automatically generated prolog. 
#  
# 61haes_r720 src/43haes/lib/ksh93/hacmp/KLIB_HACMP_get_host_info.sh 1.16 
#  
# Licensed Materials - Property of IBM 
#  
# COPYRIGHT International Business Machines Corp. 2010 
# 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 
# @(#)42	1.16  src/43haes/lib/ksh93/hacmp/KLIB_HACMP_get_host_info.sh, hacmp.assist, 61haes_r720, 1542B_hacmp720 9/29/15 17:42:35

#================================================
# The following, commented line enforces coding
# standards when this file is edited via vim.
#================================================
# vim:tabstop=4:shiftwidth=4:expandtab:smarttab
#================================================

# Start of POD-formatted documentation. Viewing suggestions:
#      perldoc <FILENAME>
#      pod2text -c <FILENAME>
#      pod2text -c --code <FILENAME>
#      pod2html <FILENAME>
function devDoc {
    : <<'=cut' >/dev/null 2>&1

=head1 NAME

 KLIB_HACMP_get_host_info

=head1 VERSION

 Version Number:  1.16
 Last Extracted:  10/15/15 19:21:00
 Last Changed:    9/29/15 17:42:35

 Path, Component, Release(, Level):
 src/43haes/lib/ksh93/hacmp/KLIB_HACMP_get_host_info.sh, hacmp.assist, 61haes_r720, 1542B_hacmp720

=head1 SYNOPSIS

 clmgr query host [ <node>[,<node#2>,...] ]

=head1 DESCRIPTION

Retrieves data for various components on the local host,
by default, or all specified nodes.

=head1 ARGUMENTS

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

 2. node [OPTIONAL] [string]
    A specific node whose host information is to be retrieved.

=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. 2005,2010
All Rights Reserved

=cut
} # End of POD-formatted documentation.


function KLIB_HACMP_get_host_info {
    LINENO=2 . $HALIBROOT/log_entry "$0()" "$CL"
    : version=1.16, src/43haes/lib/ksh93/hacmp/KLIB_HACMP_get_host_info.sh, hacmp.assist, 61haes_r720, 1542B_hacmp720
    : INPUTS: $*

    typeset -n properties=$1
    typeset nodes=${2//\"/}
            nodes=${nodes//,/ }

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

    #===================================
    : Declare and initialize variables
    #===================================
    typeset -i rc=$RC_UNKNOWN
    for k in ${!properties[*]}; do unset properties[$k]; done

    #=======================================
    : Make sure we have something to query
    #=======================================
    if [[ $nodes == *([[:space:]]) ]] && (( CLMGR_VERBOSE )); then
        nodes=$($HAUTILS/clnodename 2>>$CLMGR_TMPLOG)
    fi
    if [[ $nodes == *([[:space:]]) ]]; then
        nodes=${LOCAL_NODE%%\.*}
    fi
    if [[ $nodes == *([[:space:]]) ]]; then
        nodes=$(/usr/bin/hostname)
        nodes=${nodes%%\.*}
    fi
    typeset DATA=

    #========================================================================
    : Collecting OS levels is slow. So those retrievals are launched first
    : as backgrounded processes, so they can run while the rest of the host
    : data is being collected. 35% performance improvement.
    #========================================================================
    typeset OSLEVEL_PIDS=""
    typeset OSLEVEL_DATA="$TMPDIR/clmgr.KHghi.oslevel.$$"
    typeset -A NODE_IDS
    for node in $nodes; do
        #=====================================================================
        : Retrieve the ID number of node "$node". Note, however, that if the
        : cluster has never been synchronized with this node in it, then the
        : ID will likely be zero. In that case, a faux number will have to
        : be temporarily assigned to avoid having overwritten data.
        #=====================================================================
        print -- "$0()[$LINENO]($SECONDS): $HAUTILS/clodmget -q \"name=$node and object=COMMUNICATION_PATH\" -f node_id HACMPnode" >>$CLMGR_TMPLOG  # Always log commands
        NODEID=$($HAUTILS/clodmget -q "name=$node and object=COMMUNICATION_PATH" -f node_id HACMPnode)
        print "$0()[$LINENO]($SECONDS): clodmget RC: $?; NODEID == \"$NODEID\"" >>$CLMGR_TMPLOG  # Always log command result
        if [[ -z $NODEID ]] || (( NODEID == 0 )); then
            NODEID=$(print -- "$node" | /usr/bin/sum)
            NODEID=${NODEID%%+([[:space:]])*}
            if [[ $NODEID != +([[:digit:]]) ]]; then
                NODEID=$RANDOM
            fi
        fi
        NODE_IDS[$node]=$NODEID

        if [[ ${node%%\.*} == ${LOCAL_NODE%%\.*} ]]; then
            (
                print "properties[AIX_LEVEL$NODEID]=\"$(/usr/bin/oslevel -s)\"" 2>>$CLMGR_TMPLOG >> $OSLEVEL_DATA
            )&
        else
            (
                print "properties[AIX_LEVEL$NODEID]=\"$($CLRSH $node /usr/bin/oslevel -s)\"" 2>>$CLMGR_TMPLOG >> $OSLEVEL_DATA
            )&
        fi
        OSLEVEL_PIDS="$OSLEVEL_PIDS $!"
    done

    #================================================
    : Collect the host data for each node in $nodes
    #================================================
    for node in $nodes; do
        typeset NODEID=${NODE_IDS[$node]}

        #================================================================
        : Populate the return hash with the retrieved attributes/values
        #================================================================
        if [[ ${node%%\.*} == ${LOCAL_NODE%%\.*} ]]; then
            print "$0()[$LINENO]($SECONDS): LANG=C LC_ALL=C /usr/bin/host $(/usr/bin/hostname)" >>$CLMGR_TMPLOG  # Always log commands
            DATA=$(LANG=C LC_ALL=C /usr/bin/host $(/usr/bin/hostname))
        else
            print "$0()[$LINENO]($SECONDS): $CLRSH $node LANG=C LC_ALL=C /usr/bin/host $(/usr/bin/hostname)" >>$CLMGR_TMPLOG  # Always log commands
            DATA=$($CLRSH $node LANG=C LC_ALL=C /usr/bin/host $($CLRSH $node /usr/bin/hostname))
        fi
        rc=$?
        print "$0()[$LINENO]($SECONDS): host RC: $rc; DATA == \"$DATA\"" >>$CLMGR_TMPLOG  # Always log command result
        typeset FQDN=${DATA%%+([[:space:]])*}
        if [[ $FQDN != *\.* ]]; then
            : The first component of the /usr/bin/host output does not
            : look fully-qualified. This might mean there is an incorrect
            : /etc/hosts configuration. Checking aliases...
            typeset ALIASES=${DATA##*:}
            for FQDN in ${ALIASES//,/ }; do
                [[ $FQDN == *\.* ]] && break
            done

            if [[ $FQDN != *\.* || \
                  $FQDN == +([0-9])\.+([0-9])\.+([0-9])\.+([0-9]) ]]
            then
                : None of the aliases were fully-qualified either. There
                : is definitely something wrong with this configuration.
                : Defaulting to the output of the hostname utility.
                HOSTNAME=${DATA%%+([[:space:]])*}
            else
                HOSTNAME=$FQDN
            fi
        else
            HOSTNAME=$FQDN
        fi
        properties[HOSTNAME$NODEID]=$HOSTNAME
        DATA=${DATA%%,*}
        properties[IPADDRESS$NODEID]=${DATA##*+([[:space:]])}
        if [[ ${node%%\.*} == ${LOCAL_NODE%%\.*} ]]; then
            properties[LOCALHOST$NODEID]=true
        else
            properties[LOCALHOST$NODEID]=false
        fi

        #============================================
        : Get the version information for the node,
        : plus its current synchronization status 
        #============================================
        if [[ ${node%%\.*} == ${LOCAL_NODE%%\.*} ]]; then
            print "$0()[$LINENO]($SECONDS): /usr/bin/lslpp -L | /usr/bin/grep cluster.es.server.rte" >>$CLMGR_TMPLOG  # Always log commands
            typeset VRMF=$(/usr/bin/lslpp -L | /usr/bin/grep cluster.es.server.rte)
        else
            print "$0()[$LINENO]($SECONDS): $CLRSH $node /usr/bin/lslpp -L | /usr/bin/grep cluster.es.server.rte" >>$CLMGR_TMPLOG  # Always log commands
            typeset VRMF=$($CLRSH $node /usr/bin/lslpp -L | /usr/bin/grep cluster.es.server.rte)
        fi
        cmd_rc=$?
        print "$0()[$LINENO]($SECONDS): lslpp RC: $cmd_rc; VRMF == \"$VRMF\"" >>$CLMGR_TMPLOG  # Always log command result
        (( $rc == RC_SUCCESS )) && rc=$cmd_rc 
        VRMF=${VRMF//+([[:space:]])/ }
        VRMF=${VRMF# }
        VRMF=${VRMF#* }
        VRMF=${VRMF%% *}
        properties[HAVERSION$NODEID]="$VRMF"

        properties[VERSION_NUMBER$NODEID]=$(/usr/bin/grep CLUSTERVERSION= $HAETC/rc.cluster | /usr/bin/cut -d= -f2)

        properties[HAEDITION$NODEID]="STANDARD"
        CL=$LINENO isEnterprise $node
        (( $? == 1 )) && properties[HAEDITION$NODEID]="ENTERPRISE"

        #====================================================================
        : An invalid node name was provided. Delete the data. Report error.
        #====================================================================
        if [[ -z ${properties[HOSTNAME$NODEID]} ]]; then
            /usr/bin/dspmsg -s $CLMGR_SET $CLMGR_MSGS 102 "\nERROR: \"%1\$s\" does not appear to exist!\n\n" "$node" 1>&2
            rc=$RC_NOT_FOUND

            typeset key=
            for key in ${!properties[*]}; do
                [[ $key == *$NODEID ]] && unset properties[$key]
            done
        fi
    done

    #=====================================================================
    : Make sure the OS retrievals are complete, then collect any results
    #=====================================================================
    if [[ -n $OSLEVEL_PIDS ]]; then
        wait $OSLEVEL_PIDS
        if [[ -f $OSLEVEL_DATA && -s $OSLEVEL_DATA ]]; then
            typeset OSLEVELS=$(cat $OSLEVEL_DATA)
            [[ $OSLEVELS == *=* ]] && eval "$OSLEVELS"
        fi
    fi
    rm -f $OSLEVEL_DATA

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