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

