#!/bin/sh # # Analyze equipment configuration files and chain different phases # to build the network graph. # # Syntax: # $0 [-v] [-1] [-t] [eq ... eq] # # History : # 2004/06/08 : pda/jean : design # 2004/09/29 : pda/jean : remove generated files before new generation # 2006/06/01 : pda/jean : test snmp community # 2006/06/19 : pda/boggia : send sensors # 2007/07/17 : pda : rancid does not detect cisco access point model # 2008/10/01 : pda : add -1 mode ("at least once") # 2008/11/12 : pda/jean : add special equipment _vlan # 2010/11/17 : pda : adapt list-vlans # 2010/11/17 : pda/jean : stop sending sensors # 2010/11/23 : pda : remove status file # 2010/12/18 : pda : rework installation # 2012/01/18 : pda : rancidconfdir + ranciddb -> ranciddir # TMP=/tmp/topo.$$ TMPERR=/tmp/topoerr.$$ eval `%CONFPROG% \ ranciddir \ eqvirtdir \ eqgendir \ filterdir \ topograph \ topobindir \ checkrouterif \ ssidsensors \ topocpgraph \ ` vlanfile=$eqgendir/_vlan.eq VERBOSE=0 ############################################################################## # Utility functions ############################################################################## verbose () { if [ $VERBOSE != 0 ] then echo "$*" >&2 fi } usage () { echo "usage: anaconf [-v][-1][-t] [eq ...eq]" >&2 exit 1 } ############################################################################## # Phases to build the graph ############################################################################## # # Get equipment list in the rancid configuration file, and extract # equipment model from the equipment configuration file. # list_rancid () { verbose "calling 'list-rancid'" $topobindir/list-rancid $ranciddir/router.db $ranciddir/configs > $TMP return $? } # # Clean-up the generation directory. This handles the case where # old equipments have been removed from rancid. # cleanup_eqgen () { if [ $# = 0 ] then rm -f $eqgendir/* fi return 0 } # # Get vlans list. # list_vlans () { verbose "calling 'list-vlans'" $topobindir/list-vlans > $vlanfile return $? } # # Extract informations from equipment configuration files # analyze_conf () { if [ $# = 0 ] then analyze_eq < $TMP else for eq do if [ "$eq" = "_vlan" ] then : elif [ -f "$eqvirtdir/$eq.eq" ] then : elif grep "^$eq " $TMP | analyze_eq then : else echo "$eq not found in list-rancid result" >&2 fi done fi return 0 } # # Filter to rewrite equipement configuration file. # Original configuration is simply "piped" to a program # filter () { eqtype=$1 infile=$2 # The filter program is called only if it exists in "filterdir" directory ; # "filterdir" is a variable defined in the configuration file if [ -n "$filterdir" -a -f "$filterdir/$eqtype" ] ; then # The name of the program called is be the same as the equipment type # Example: /usr/lib/netmagis/filters/cisco $filterdir/$eqtype < $infile else cat $infile fi } analyze_eq () { r=1 # 1 if no equipment found while read name type model do # remove domain name n=`echo $name | sed 's/\..*//'` verbose "analyze $name" # for an unknown reason, rancid does not detect model for # some Cisco access points (not for all) if [ x"$model" = x ] then model="UNKNOWN" fi eqconf="/tmp/$name.$$" filter $type $ranciddir/configs/$name > $eqconf $topobindir/analyze $topobindir $type "$model" $eqconf $n \ > $eqgendir/$n.eq rm $eqconf r=0 # at least one equipment found done return $r } # # Equipments not managed by rancid, just copy files (virtual files) # copy_eqvirt () { for nameeq in `ls $eqvirtdir | grep '\.eq$'` do cp $eqvirtdir/$nameeq $eqgendir/$nameeq done return 0 } # # Local policy to get sensors for each ssid # ssidsensors () { if [ "$ssidsensors" = yes ] then $topobindir/ssidsensors else cat fi } # # Graph generation # build_graph () { verbose "graph generation" cat $eqgendir/* \ | ssidsensors \ | $topobindir/buildgraph > $topograph.tmp \ && mv $topograph.tmp $topograph return $? } # # Check that SNMP community is specified on all equipments # check_snmp () { verbose "SNMP community check" r=0 WITHOUTSNMP=`$topobindir/dumpgraph < $topograph \ | sed -n '/^eq .* snmp -$/s/eq \([^ ]*\) .*/\1/p'` if [ "$WITHOUTSNMP" != "" ] then ( echo "Warning : equipements without any SNMP community string" echo "$WITHOUTSNMP" | sed 's/^/ /' ) >&2 r=1 fi return $r } # # Check that router interfaces are declared in the DNS # (not activated here) # check_dns () { verbose "checking DNS declaration of router interfaces" if [ "checkrouterif" = "yes" ] then $topobindir/getnetif < $topograph | $topobindir/checkdns fi return 0 } # # Copy graph to another host if configured # copy_graph () { if [ -n "$topocpgraph" -a -n "$topograph" ] then userhost=`echo "$topocpgraph" | cut -f1 -d:` destfile=`echo "$topocpgraph" | cut -f2 -d:` scp -q $topograph $userhost:$destfile.new && \ ssh -q $userhost \ "mv $destfile $destfile.old;mv $destfile.new $destfile" fi return 0 } ############################################################################## # Phase chaining ############################################################################## chain () { list_rancid \ && cleanup_eqgen $* \ && list_vlans \ && analyze_conf $* \ && copy_eqvirt \ && build_graph \ && copy_graph \ && check_snmp \ && check_dns return $? } execute () { if [ "$ONCE" = true -o "$TESTONLY" = true ] then chain $* error=$? else rm -f $TMPERR chain $* 2> $TMPERR # # Distinguish true errors (return code != 0) from inconsistencies # detected by various tools (buildgraph for example): the last # do not prevent graph building. # error=$? if [ $error != 0 ] then if [ -s $TMPERR ] then NEWERR="`cat $TMPERR`" else NEWERR="Unknown error (no error message)" fi else if [ -s $TMPERR ] then NEWERR="`cat $TMPERR`" fi fi # # Display warning or error messages # if [ ! -z "$NEWERR" ] then echo "$NEWERR" fi fi return $error } ############################################################################## # Main program ############################################################################## # # Syntax checking # args=`getopt v1 $*` if [ $? != 0 ] then usage fi set -- $args TESTONLY=false for i in $* do case "$i" in -v) VERBOSE=1 shift ;; -1) ONCE=true shift ;; --) shift break ;; esac done if [ $? != 0 ] then usage fi # # Go! # execute $* error=$? # # Exit clean-up # rm -f $TMP $TMPERR exit $error