Diff/compare router configs
By: rusiawan
Tags: cisco, configuration, diff, shell script, solaris
Category: Komputer dan Internet
Comparing or making diff of NE (Network Element) configurations is one of useful thing in Operation (configuration) management. There are many tools/application which facilitate that function. One of popular FOSS app is RANCID. Some new routers even have been already featuring embedded configuration diff (e.g Cisco IOS XR).
Sometime it is possible that RANCID is not available and its installation might not be an option (e.g because of strict server install/policy ). In that case, we have to write custom script to do that.
The use of GNU diff is obvious. But if we are dealing with Solaris environment we need to be a little bit creative since Solaris diff is somewhat basic and does not offer as many feature as GNU diff.
Below is my script to achieve that function. The script is also capable of filtering router configuration from raw capture (in the case of the admin should capture additional information within the same output, i.e device health, and do not want to poll/capture separately due to efficiency consideration), and also excluding specific pattern from diff.
Note: it’s tested on Solaris 5.10, Bourne Shell (sh), dealing with Cisco configurations, additional capture in the raw results is ”admin show platform” (IOS XR).
Enjoy!, adjust accordingly in case you want to use it in your environment.
#!/usr/bin/sh
#################################
##Andi Rusiawan (c)2011 ##
##arusiawa@cisco.com ##
##This script is provided as-is##
#################################
##date on solaris is very poor, calc manually##
#d=`date +%d`
#dmin1=`expr $d – 1`
#dmin2=`expr $d – 2`
##use TZ tricks for more valid date
TZ=”WIB+17″
export TZ
yestd=`date +%Y-%m-%d`
unset TZ
TZ=”WIB+41″
export TZ
yestd1=`date +%Y-%m-%d`
unset TZ
TZ=”WIB-7″
export TZ
today=`date +%Y-%m-%d`
##place to define which configs to diff
#old=$yestd1
#new=$yestd
old=$yestd
new=$today
##let’s extract router config from raw capture available in /root/tools/config_backup/output
rawdir=/root/tools/config_backup/output
confdir=/root/tools/config_diff/configs
exclude=/root/tools/config_diff/exclude.list
logfile=/root/tools/config_diff/confdiff.log
if [ ! -d $confdir/$old ]; then
mkdir -p $confdir/$old
fi
if [ ! -d $confdir/$new ]; then
mkdir -p $confdir/$new
fi
##empty logfile
echo “” > $logfile
##in this case config file characterized by its existence beetween string “Building configuration” and “platform”
cd $rawdir/$old
for h in *.txt ; do
verify1=`awk ‘/^end\r$/’ $h | wc -l`
if [ $verify1 -gt 0 ]; then
cat $h | awk ‘/Building configuration/,/platform/’ | grep -v “Building configuration” | grep -v platform | /usr/xpg4/bin/grep -Fv -f $exclude > $confdir/$old/$h.config | sh
echo “extract configs from $rawdir/$old/$h to $confdir/$old/$h.config” >> $logfile
fi
done
cd $rawdir/$new
for i in *.txt ; do
verify2=`awk ‘/^end\r$/’ $i | wc -l`
if [ $verify2 -gt 0 ]; then
cat $i | awk ‘/Building configuration/,/platform/’ | grep -v “Building configuration” | grep -v platform | /usr/xpg4/bin/grep -Fv -f $exclude > $confdir/$new/$i.config | sh
echo “extract configs from $rawdir/$new/$i to $confdir/$new/$i.config” >> $logfile
fi
done
trgtdir=/root/tools/config_diff/output
output=config_diff_$new.txt
dir1=$confdir/$old
dir2=$confdir/$new
if [ ! -d $trgtdir ]; then
mkdir -p $trgtdir
fi
##check missing configs
Nmiss=`find $confdir/$new -type f -size 0 | wc -l`
echo “
Missing configs:
There are possibly $Nmiss missing configs file ” > $trgtdir/$output
echo “Please check on log files, there are possibly $Nmiss missing configs file ” >> $logfile
find $confdir/$new -type f -size 0 | awk -F/ ‘{print $6,$7}’ >> $logfile
find $confdir/$new -type f -size 0 | awk -F/ ‘{print $6,$7}’ >> $trgtdir/$output
echo “========================================================================================================” >> $logfile
##check incomplete configs
echo “
Incomplete configs:
Diff might be invalid on these devices due to incomplete config ” >> $trgtdir/$output
cd $rawdir/$old
for x in *.txt; do
incomp=`awk ‘/^end\r$/’ $x | wc -l`
if [ $incomp -eq 0 ]; then
echo “$old $x” >> $trgtdir/$output
fi
done
cd $rawdir/$new
for y in *.txt; do
incomp=`awk ‘/^end\r$/’ $y | wc -l`
if [ $incomp -eq 0 ]; then
echo “$new $y” >> $trgtdir/$output
fi
done
echo “configs extraction are done, starting to diff ……………” >> $logfile
##write list of hostname which config is changed
diffN=`dircmp -w120 -s $dir1 $dir2 | grep -v ‘^$’ | awk -F. ‘{print $2}’ | sed ‘s=/==g’ | grep -v ‘^$’ | wc -l`
echo “
Diff results:
There are $diffN routers which backup configs changed” >> $trgtdir/$output
echo “========================================================================================================” >> $trgtdir/$output
dircmp -w120 -s $dir1 $dir2 | grep -v ‘^$’ | awk -F. ‘{print $2}’ | sed ‘s=/==g’ | grep -v ‘^$’ | awk ‘{print NR “\t” $0}’ >> $trgtdir/$output
echo “========================================================================================================
” >> $trgtdir/$output
#diff -bitwr -C2 $dir1 $dir2 | grep -v bitwr | sed ‘s=/root/tools/==g’ >> $trgtdir/$output
##diff process, no need to diff identical and incomplete file configs
hostnames=`dircmp -w120 -s $dir1 $dir2 | grep -v ‘^$’ | awk -F. ‘{print $2}’ | sed ‘s=/==g’ | grep -v ‘^$’`
for j in $hostnames; do
if [ -f $dir1/$j.txt.config ] && [ -f $dir2/$j.txt.config ]; then
verify=`awk ‘/^end\r$/’ $dir1/$j.txt.config | wc -l`
if [ $verify -gt 0 ]; then
echo “
Filtered result (eligible to diffs]:
############################## START CONFIG DIFF: $j ##############################” >> $trgtdir/$output
diff -bitsw -C2 $dir1/$j.txt.config $dir2/$j.txt.config | sed ‘s=/root/tools/==g’ >> $trgtdir/$output
echo “Diffing configuration of $j” >> $logfile
echo “############################## END CONFIG DIFF: $j ##############################
” >> $trgtdir/$output
fi
fi
done
echo “Done!, diff info can be found in $trgtdir/$output” >> $logfile
