Renaming Managed Device Objects in ZENworks Linux Management 7
Novell Cool Solutions: Feature
By Jason Brothers
Digg This -
Slashdot This
Posted: 8 Jun 2006 |
PROBLEM: With the current ZLM 7 offering there is no mechanism built in to automatically rename Managed Device objects in the case of a hostname change.
SOLUTION: This script shows the power of what a little scripting can do in your ZLM 7 environment. The provided script is limited to a certain configuration (only deals with Servers folder and managed device naming of hostname - OS), however, with a bit of imagination it could be modified to fit your environment.
This script can be placed in a Remote Execute Policy and automatically run on your ZLM Primary Server.
#!/bin/bash ################################################################################### # Name: rename # Version: 0.1 # Purpose: To rename objects based on the data contained in the database and # the following registration format: hostname - ostarget ################################################################################### ######## Variables ######## #Number of days the device has last contacted. LASTCONTACT=2 #Location where the file hibernate.cfg.xml can be found for the system. DBCONNECT=/etc/opt/novell/zenworks/hibernate.cfg.xml #Location where temporary work files are stored WORKDIR=/tmp LOCKFILE=/etc/opt/novell/zenworks/zlm-rename.lock LOGFILE=/var/opt/novell/log/zenworks/zlm-rename.log #Exclusion List #Any device in this list will be excluded from the rename operations. #This variable has the following requirements: # 1) Each name is terminated with a line feed (\n) # 2) Any device that is not in the root Server folder needs to have the folder prepended # to the path # 3) Slashes (/) in the path need to be escaped with five back-slashes (\). # # Worst case example: # EXCLUDED="server 1\n # test\\\\\/server 2\n" EXCLUDED="server1\n folder\\\\\/server2\n " ######## Functions ######## #Used to validate the credentials stored in ~.zlmanrc are present and correct. function PassCheck { zlman ping >/dev/null if [ "$?" != "0" ]; then echo The username or password set in ~.zlmanrc echo Please verify the credentials in ~.zlmanrc exit 1 fi } #Setup the Database connection function InitDB { #Parse the information from hibernate.xml.cfg DBUSER=`fgrep "connection.username" $DBCONNECT |awk -F \> '{print $2}' | awk -F \< '{print $1}'` DBPASS=`fgrep "connection.password" $DBCONNECT |awk -F \> '{print $2}' | awk -F \< '{print $1}'` DBURL=`fgrep "connection.url" $DBCONNECT |awk -F \> '{print $2}' | awk -F \< '{print $1}'` declare -a DBINFO=(`echo $DBURL\ | sed 's/\/\///g' \ |sed 's/\// /' \ |sed 's/:/ /g' \ | cut -d " " -f 3-`) #DBHOST=${DBINFO[0]} #DBPORT=${DBINFO[1]} #DBNAME=${DBINFO[2]} export PGPASSWORD=$DBPASS export PGCONNECT="psql -d ${DBINFO[2]} -h ${DBINFO[0]} -p ${DBINFO[1]} -U $DBUSER" } #Create a file that contains a master list of the Managed Servers in the zone. function BuildList { #Use zlman to build the list, remove whitespace from the output, and then printout the full path to the object. zlman sl -r \ | sed 's/ *| */|/g' \ |sed 's/ *$//g' \ | awk -F \| '{if (match($2, "Server")>0){ print $3 "/" $1 }}' \ | sed 's/\/Devices\/Servers\///g' > $WORKDIR/Renamelist.txt #Remove the Excluded Servers from the file. ScrubList $WORKDIR/Renamelist.txt } #Determine if there are any duplicate alias names, if so, build the list so they can be handled. function IdentDups { #This will return all of the duplicate alias names. $PGCONNECT -o $WORKDIR/RenameDUPS.txt -A -t -c "SELECT alias FROM zen_device WHERE role='Server' group by alias having ( count(alias) > 1 );" sed -i '/^ *$/d' $WORKDIR/RenameDUPS.txt #Remove the Excluded Servers from the file ScrubList $WORKDIR/RenameDUPS.txt } #Does the work of removing the Excluded servers from the passed in file. function ScrubList { echo -e $EXCLUDED | sed '/^ *$/d' \ | while read line; do sed -i "/$line/d" $1 done } #Process the duplicate alias names. Need to cross reference the GUID stored in the DB with the Device object. #Duplicate entries are processed separately for two reasons: # 1) It is necessary to perform an additional zlman query (zlman si) to verify the correct object is being dealt with. # The deviceguid value is used as a cross reference. # 2) Compared to straight database queries, zlman si is relatively slow and the script could take a very long time on a large zone. function ProcessDups { cat $WORKDIR/RenameDUPS.txt | while read line; do #Build up the desired name for alias based on the naming rule of "hostname - ostarget". #Return all devices with the exception of Orphans. Only return Orphan devices that have not contacted the server in $LASTCONTACT days. if [ -z "`echo "$line"| grep -E '^ORPHAN'`" ]; then RESULT="`$PGCONNECT -A -t -c "SELECT deviceguid, hostname || ' - ' || name FROM zen_device z, os_targets o WHERE z.osid=o.osid AND role='Server' AND alias='$line';"`" else RESULT="`$PGCONNECT -A -t -c "SELECT deviceguid, hostname || ' - ' || name FROM zen_device z, os_targets o WHERE z.osid=o.osid AND role='Server' AND alias='$line' AND last_contact > now() - '$LASTCONTACT day'::interval;"`" fi echo "$RESULT" \ | sed '/^ *$/d' \ | while read info; do GUID=`echo "$info" | cut -d \| -f 1` NAME=`echo "$info" | cut -d \| -f 2` #Determine if the current value for alias matches the desired value. export alias=`$PGCONNECT -A -t -c "SELECT alias FROM zen_device WHERE alias!='$NAME' AND deviceguid='$GUID';"\ | sed '/^ *$/d'` #If the desired name does not match the current name, then rename the object with zlman. if [ "$alias" ]; then grep -E "$alias$" $WORKDIR/Renamelist.txt \ | while read serverloc; do result=`zlman si "$serverloc"\ | grep GUID \ | sed 's/ *| */|/g' \ | sed 's/ *$//g' \ | cut -d \| -f 2` if [ "$result" == "$GUID" ]; then $DRYRUN zlman srn "$serverloc" "$NAME" | sed "s/$alias$/$alias to $NAME/" | sed '/Fatal Error:/d' >> $LOGFILE #Should implement a case statement to catch all errors. if [ "$?" == "101" ] && ["$alias" != "$NAME-$GUID"]; then #Object must exist already, retry $DRYRUN zlman srn "$serverloc" "$NAME-$GUID" | sed "s/$alias$/$alias to $NAME-$GUID/" | sed '/Fatal Error:/d' >> $LOGFILE fi fi done fi done done } function RenameObject { #Rename any Managed Server object that has not contacted the server in $LASTCONTACT days. $PGCONNECT -A -t -c "SELECT deviceguid, hostname || ' - ' || name FROM zen_device z, os_targets o WHERE z.osid=o.osid AND role='Server' AND (alias NOT LIKE 'ORPHAN-%' OR (alias like 'ORPHAN-%' AND last_contact > now() - '$LASTCONTACT day'::interval));" \ | sed '/^ *$/d' \ | while read info; do GUID=`echo "$info" | cut -d \| -f 1` NAME=`echo "$info" | cut -d \| -f 2` alias=`$PGCONNECT -A -t -c "SELECT alias FROM zen_device WHERE alias!='$NAME' AND deviceguid='$GUID';"\ | sed '/^ *$/d'` serverloc="`grep -E "(^|/)$alias$" $WORKDIR/Renamelist.txt`" if [ "$serverloc" ]; then $DRYRUN zlman srn "$serverloc" "$NAME" | sed "s/$alias$/$alias to $NAME/" | sed '/Fatal Error:/d' >> $LOGFILE if [ "$?" == "101" ] && [ "$alias" != "$NAME-$GUID" ]; then #Object must exist already, retry $DRYRUN zlman srn "$serverloc" "$NAME-$GUID" | sed "s/$alias$/$alias to $NAME-$GUID/" | sed '/Fatal Error:/d' >> $LOGFILE fi fi done } ######## Main Script ######## if [ "$1" ]; then case "$1" in "--help" | "-h" ) echo echo "Usage: rename <options>" echo echo "The following options are supported:" echo -e "--help, -h\t\t This help page" echo -e "--dry, -d\t\t Performs a dry run only" exit 0 ;; "--dry" | "-d" ) export DRYRUN="echo Would have performed ..." ;; * ) echo Unknown option exit 1 ;; esac fi if ( set -o noclobber; echo "$$" > "$LOCKFILE") 2> /dev/null; then trap 'rm -f "$LOCKFILE"; exit $?' INT TERM EXIT echo "Process started `date`" >> $LOGFILE PassCheck InitDB BuildList IdentDups if [ `cat $WORKDIR/RenameDUPS.txt | wc -l` -gt 0 ]; then ProcessDups fi RenameObject echo "Process ended `date`" >> $LOGFILE rm -f "$LOCKFILE" trap - INT TERM EXIT else echo "Failed to acquire lockfile: $LOCKFILE." >> $LOGFILE echo "Held by $(cat $LOCKFILE)" >> $LOGFILE fi
If you have any questions you may contact Jason at jbrothers@novell.com

Novell Cool Solutions (corporate web communities) are produced by WebWise Solutions. www.webwiseone.com