Diff/compare router configs

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

Advertisement
Follow

Get every new post delivered to your Inbox.