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 mtxdoc.mtxia.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. #### #### mtxdoc:/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 11/02/10