Script Source Code for "SERVERinfo.ksh"

This document contains the source code for the Disaster Recovery script "SERVERinfo.ksh".



#!/usr/bin/ksh93
################################################################
function usagemsg {
  print ""
  print "Program: SERVERinfo.ksh"
  print ""
  print "This script gathers server information from "
  print "each AIX server and inserts this information into "
  print "the CMDB database."
  print ""
  print "Usage: ${1##*/} [-v] [-a] [-m machineName]"
  print ""
  print "    Where '-v' = Verbose mode."
  print "          '-a' = Gather server information from all"
  print "                 servers defined in the CMDB Server table"
  print "                 whose Operating System is defined as AIX."
  print "          '-m' = Requires a single argument specifying"
  print "                 the IP name of a machine from which to"
  print "                 gather server information."
  print ""
  print "\"AutoContent\" enabled"
  print ""
}
################################################################
#### 
#### Description:
#### 
#### This program gathers server information from AIX
#### servers, builds the appropriate SQL statements, then deletes 
#### and inserts records into the MYSQL CMDB test database running
#### on eperf.tu.com
#### 
#### The information gathered includes operating system name, 
#### OS version, and OS maintenance level.
#### 
#### Assumptions:
#### 
#### This program assumes there is a script called "tsql.sh" in
#### the current directory.  This script is expected to accept SQL
#### statements through standard input and perform all MSSQL database
#### communications.
#### 
#### The database table Server02 is assumed to already exist in the 
#### MSSQL database and is configured appropriately to accept the 
#### following fields -
#### 
#### Server02: name, osname, osversion, oslevel
#### 
#### See the database schema for further explanation of these fields.
#### 
#### Dependencies:
#### 
#### This script uses "rsh" to run commands on each machine that
#### generate the server information.  The user running this
#### script must have "rsh" access to all machines for which this
#### script will be executed.
#### 
#### The output of the MSSQL SQL processor is a specific format and
#### this script is expecting the data to exist in that format.  If
#### the SQL processor is changed, this script must be modified to 
#### correctly interpret the output from the SQL processor.
#### 
#### Products:
#### 
#### The product of this script is a list of SQL statements to
#### update the CMDB Server02 table.  The CMDB database is NOT
#### modified as a result of this script.  The SQL statements 
#### generated by this script must be executed by a separate
#### SQL processor.
#### 
#### Configured Usage:
#### 
#### This script is designed to be executed from the command line
#### or scheduled as a background process.
#### 
#### Details:
################################################################
TRUE="1"
FALSE="0"
VERBOSE="${FALSE}"
ALLMACH="${FALSE}"
MACHNAME=""
CMD_SQL="./tsql.sh"

while getopts ":vam:" OPTION
do
    case "${OPTION}" in
        'v') VERBOSE="${TRUE}";;
        'a') ALLMACH="${TRUE}";;
        'm') MACHNAME="${OPTARG}";;
        '?') usagemsg "${0}" && exit 1 ;;
        ':') print "ERROR: Option '-${OPTARG}' requires an argument:"
             usagemsg "${0}" && exit 2 ;;
    esac
done

shift $(( ${OPTIND} - 1 ))

trap "usagemsg ${0}" EXIT
if (( ALLMACH == FALSE )) && [[ "_${MACHNAME}" = "_" ]]
then
  print "ERROR: Either '-a' or '-m' must be specified"
  exit 3
fi
if (( ALLMACH == TRUE )) && [[ "_${MACHNAME}" != "_" ]]
then
  print "ERROR: Options '-a' and '-m' are mutually exclusive"
  exit 4
fi
if [[ "_${MACHNAME}" != "_" && "_${MACHNAME}" = _-? ]]
then
  print "ERROR: Invalid machine name \"${MACHNAME}\" specified"
  exit 5
fi
trap "-" EXIT

################################################################

TMPFILE01="/tmp/tmp${$}.out"

################################################################
#### 
#### Build a command to be executed on each remote machine
#### via "rsh"  This command will generate a series of shell 
#### variable assignment that will contain values representing the
#### current configuration of the server.
#### 
################################################################

CMD='print "SERVNAME=\"$( uname -n )\"\nOSNAME=\"$(uname -s )\"\nOSVERSION=\"$( oslevel )\"\nOSLEVEL=\"$( instfix -iv | grep _ML | tail -1 )\""'

################################################################
#### 
#### This script is currently configured to be executed from
#### a specific machine in a specific directory i.e.
#### 
#### eperf:/home/french/mysql
#### 
#### This will be changed in future iterations of the script, but
#### for now thats just the way it is.
#### 
################################################################

cd /home/french/mssql

################################################################
#### 
#### Check to see if the user identified a specific machine 
#### from which to gather user and group information, or 
#### requested the script to run gather infor for all machines.
#### Depending upon what the user specified, the server name
#### and database record number for each server is selected from
#### the database and output to a temporary file.
#### 
################################################################

if (( ALLMACH == TRUE ))
then
  print "SELECT DISTINCT name FROM Server02 WHERE osname LIKE '%AIX%'\ngo" |
  ${CMD_SQL} 2>/dev/null |
  egrep -v "^[0-9]>|^charset is|^name[[:blank:]]*$|^locale is" > "${TMPFILE01}"
else
  print "SELECT DISTINCT name FROM Server02 WHERE name = '${MACHNAME}'\ngo" |
  ${CMD_SQL} 2>/dev/null |
  egrep -v "^[0-9]>|^charset is|^name[[:blank:]]*$|^locale is" > "${TMPFILE01}"
fi

################################################################
#### 
#### Read each server ID number and server name from the temporary
#### file.
#### 
################################################################

while read SERVER
do

  (( VERBOSE == TRUE )) && print -u 2 "# Working on ${SERVER}"

################################################################
#### 
#### Unset the shell variable containing the configuration values
#### of the server to ensure values from previous iterations of
#### the loop are not carried forward.
#### 
################################################################

  unset SERVNAME OSNAME OSVERSION OSLEVEL

################################################################
#### 
#### A ping test is performed to determine if the target machine 
#### is network accessible.  If it can not be pinged, it is skipped.
#### 
################################################################

  if ping -c 2 -w 5 ${SERVER} > /dev/null 2>&1
  then

    (( VERBOSE == TRUE )) && print -u 2 "#   Successfully pinged ${SERVER}"

################################################################
#### 
#### If the ping test is successful, the previously built command
#### command is executed on the remote machine.  The result of
#### the command is a series of korn shell variable assignments.
#### These statements are redirected to a temporary file and the
#### temporary file will be execute to perform the assignments.
#### 
#### The 'rsh' command is performed in the background and this
#### script is told to sleep for 10 seconds while the rsh command
#### is executing.  After 10 seconds, if the rsh command is 
#### still executing, it is assumed to be hung and killed.  If 
#### the rsh command was hung, no update command is issued since
#### no values were returned.
################################################################

      (( VERBOSE == TRUE )) && print -u 2 "#   Executing remote command"
      rm -f /tmp/script${$}.tmp
      eval rsh ${SERVER} "\"\${CMD}\"" > /tmp/script${$}.tmp &
      sleep 10

################################################################
#### Gather a list of all grandchild processes so they may also
#### be killed if necessary.
#### 
################################################################

      GRANDCHILD=$( ps -ef | awk '{ print $2, $3 }' | grep "[[:blank:]]${!}$" | awk '{ print $1 }' )
      if kill -9 ${!} >/dev/null 2>&1
      then

################################################################
#### 
#### If the 'rsh' command does not return after 10 seconds, assume
#### it is hung and kill the process.  Also kill all grandchild
#### processes associated with this 'rsh' child process.
#### 
################################################################

          (( VERBOSE == TRUE )) && print -u 2 "#   killing child process ${!}"
          for PID in ${GRANDCHILD}
          do
            (( VERBOSE == TRUE )) && print -u 2 "#     killing grandchild process ${PID}"
            kill -9 ${PID}
          done

      else

################################################################
#### 
#### If the rsh command was successful, make the temporary file,
#### containing the korn shell variable assignments, executable
#### and execute it in the current shell environment.
#### 
################################################################

          (( VERBOSE == TRUE )) && print -u 2 "#   Initializing returned values"
          chmod 755 /tmp/script${$}.tmp
          . /tmp/script${$}.tmp

################################################################
#### 
#### If after the temporary file is executed the shell variable
#### 'SERVNAME' contains a value, generate an SQL command to
#### update the CMDB with the new values associated with the server.
#### 
################################################################

          if [[ "_${SERVNAME}" != "_" ]]
          then
            (( VERBOSE == TRUE )) && print -u 2 "#   Generating SQL UPDATE command"
              print "UPDATE Server02 set \
  name = '${SERVNAME}', \
  osname = '${OSNAME}', \
  osversion = '${OSVERSION}', \
  oslevel = '${OSLEVEL/#+([[:blank:]])/}' \
  WHERE name = '${SERVNAME}'\ngo"
          else
            (( VERBOSE == TRUE )) && print -u 2 "#   Invalid data returned from ${SERVER}"
          fi
      fi
  else
    (( VERBOSE == TRUE )) && print -u 2 "#   Unable to ping ${SERVER}"
  fi

################################################################
#### 
#### Continue with the next iteration of the loop which goes to
#### the next server in the list.
#### 
################################################################

done < "${TMPFILE01}"

################################################################
#### 
#### Cleanup any temporary files
#### 
################################################################

rm -f "${TMPFILE01}"
rm -f "/tmp/script${$}.tmp"

This file last modified 02/04/09