r3303 deviceconfig: initial cleanup round
authorDenis Ovsienko <infrastation@yandex.ru>
Mon, 1 Mar 2010 13:48:02 +0000 (13:48 +0000)
committerDenis Ovsienko <infrastation@yandex.ru>
Mon, 1 Mar 2010 13:48:02 +0000 (13:48 +0000)
gateways/deviceconfig/cisco.connector
gateways/deviceconfig/cisco.secrets.php-sample
gateways/deviceconfig/main

index 57f8bb7..2933d79 100755 (executable)
@@ -1,32 +1,14 @@
 #!/bin/sh
 
-[ $# = 7 ] || exit 1
+[ $# = 2 ] || exit 1
 
 ENDPOINT=$1
-HW=$2
-SW=$3
-COMMAND=$4
-FILE1=$5
-FILE2=$6
-FILE3=$7
-MYDIR=`dirname $0`
-ostype=`uname -s`
-case "$ostype" in
-       Linux)
-       SEDFLAG='-r'
-       ;;
-       FreeBSD)
-       SEDFLAG='-E'
-       ;;
-       *)
-       exit 7
-esac
-
+OUT1=$2
 
 prepare_connect_commands()
 {
        [ $# = 1 ] || exit 2
-       local skip=yes cval found=no
+       local skip=yes cval found=no MYDIR=`dirname $0`
        while read line; do
                if [ "$skip" = "yes" -a "$line" = "# S-T-A-R-T" ]; then
                        skip=no
@@ -37,16 +19,13 @@ prepare_connect_commands()
                        continue
                fi
                [ "$skip" = "yes" ] && continue
-               # Allow comments.
+               # ignore comments
                [ -z "${line###*}" ] && continue
 
                # First endpoint string/regexp match is sufficient for us.
                cval=`echo $line | cut -s -d' ' -f1`
                if [ -z "${1##$cval}" ]; then
                        found=yes
-                       # Don't be too smart at the moment, just be able to handle
-                       # the known-good case ;-)
-
                        username=`echo $line | cut -s -d' ' -f5`
                        [ "$username" != "-" ] && echo $username > $CMDS1
                        # access password
@@ -56,152 +35,21 @@ prepare_connect_commands()
                                echo en >> $CMDS1
                                echo $enable_password >> $CMDS1
                        }
-                       # same for ports
-                       cat "$CMDS1" > "$CMDS2"
-                       # ...and MAC addresses
-                       cat "$CMDS1" > "$CMDS3"
                        break
                fi
        done < "$MYDIR/cisco.secrets.php"
        [ "$found" = "yes" ] && return
-       echo "E!connector could not find credentials for $1" >> "$FILE2"
        exit 3
 }
 
-prepare_fetch_commands()
-{
-       printf 'term len 0\nshow vlan brief\nquit\n' >> $CMDS1
-       printf 'term len 0\nshow int status\nquit\n' >> $CMDS2
-       printf 'term len 0\nshow mac-address-table\nquit\n' >> $CMDS3
-}
-
-prepare_push_commands()
-{
-       printf 'term len 0\nconf t\n' >> $CMDS1
-       while read portname vlanid; do
-               if [ -z "$portname" -o -z "$vlanid" ]; then
-                       echo "E!could not parse input in connector" >> "$FILE2"
-                       continue
-               fi
-               if [ "$vlanid" = "trunk" ]; then
-                       echo "E!trunking is not allowed" >> "$FILE2"
-                       continue
-               fi
-               printf "int $portname\n" >> $CMDS1
-               if [ $vlanid -lt 4096 ]; then
-                       printf "no description\n" >> $CMDS1
-               else
-                       printf "descr VLAN$vlanid\n" >> $CMDS1
-               fi
-               "$MYDIR/vlandecoder" $vlanid >> $CMDS1
-               printf "exit\n" >> $CMDS1
-               echo "C!64!$portname!$ENDPOINT!$vlanid" >> "$FILE2"
-       done < "$FILE1"
-       printf "end\nwri\nquit\n" >> $CMDS1
-}
-
-do_fetch()
-{
-       local tmp_ifname tmp_ifdescr tmp_status tmp_vlanid
-       nc $ENDPOINT 23 < $CMDS1 > "$OUT1"
-       if fgrep -q '% Bad passwords' "$OUT1"; then
-               echo "E!password mismatch while trying to connect to $ENDPOINT" >> "$FILE2"
-               exit 4
-       fi
-       nc $ENDPOINT 23 < $CMDS2 > "$OUT2a"
-       nc $ENDPOINT 23 < $CMDS3 > "$OUT3"
-       cat "$OUT1" | fgrep ' active    ' | sed $SEDFLAG 's/^([[:digit:]]+)[[:space:]]+(.+)[[:space:]]+active    (.*)/\1=\2/;s/[[:space:]]+$//' > $FILE1
-       # Add trunk data, if appropriate.
-       [ -s "$MYDIR/vlantable" ] && cat "$MYDIR/vlantable" >> $FILE1
-
-       # First extract structured info about VLAN membership, then map
-       # special descriptions into VLAN IDs.
-       cat "$OUT2a" | egrep '^(Et|Fa|Gi|Te)' | sed $SEDFLAG 's/[~%]/__RTTMP_percent_sign__/g;s/^([A-Za-z/0-9]+) +(.*) +(connected|notconnect|disabled|err-disabled|monitoring|suspended) +/\1~\2%\3%/;s/%(trunk|routed|([0-9]+)) .*$/%\1/;s/%(monitoring|suspended)%/%connected%/;s/%(err-disabled)%/%disabled%/;s/ +%/%/;s/~/%/' > $OUT2b
-       while read line; do
-               tmp_ifname=`echo $line | cut -d% -f1`
-               tmp_ifdescr=`echo $line | cut -d% -f2`
-               tmp_status=`echo $line | cut -d% -f3`
-               tmp_vlanid=`echo $line | cut -d% -f4`
-               # If the port has a description pretending to be a martian VLAN, map it onto the VLAN ID.
-               if [ -n "$tmp_ifdescr" -a -z "${tmp_ifdescr##VLAN*}" ]; then
-                       tmp_vlanid=${tmp_ifdescr##VLAN}
-               fi
-               echo "$tmp_ifname=$tmp_status,$tmp_vlanid" >> $FILE2
-       done < $OUT2b
-       # FIXME
-       # Here we need to distinguish between different platforms and IOS version,
-       # cause they produce output in different formats.
-       if [ "$SW" = "Cisco+IOS+12.0" ]; then
-               cat "$OUT3" | LC_ALL=C tr -d '\r' | fgrep Dynamic | sed $SEDFLAG 's/ +Dynamic +([0-9]+) +(.+)/=\1@\2/;s/FastEthernet/Fa/;s/GigabitEthernet/Gi/' > "$FILE3"
-       elif [ "$SW" = "Cisco+IOS+12.2" -o "$SW" = "Cisco+IOS+12.1" ]; then
-               case "$HW" in
-                       Cisco+Catalyst+35*|Cisco+Catalyst+37*|Cisco+Catalyst+29*)
-                               cat "$OUT3" | LC_ALL=C tr -d '\r' | egrep 'STATIC|DYNAMIC' | \
-                               sed $SEDFLAG 's/ +([0-9]+|All) +(.+)    (DYNAMIC|STATIC) +(.+)/\2=\1@\4/;s/FastEthernet/Fa/;s/GigabitEthernet/Gi/' > "$FILE3"
-                       ;;
-                       Cisco+Catalyst+49*)
-                               cat "$OUT3" | LC_ALL=C tr -d '\r' | fgrep dynamic | \
-                               sed $SEDFLAG 's/ +([0-9]+) +([0-9a-f\.]+)   dynamic ip +([a-zA-Z/0-9]+) */\2=\1@\3/;s/FastEthernet/Fa/;s/GigabitEthernet/Gi/;s/TenGi/Te/' > "$FILE3"
-                       ;;
-               esac
-       fi
-}
-
-do_push()
-{
-       nc $ENDPOINT 23 < $CMDS1 >/dev/null
-}
-
-remove_tempfiles()
-{
-       [ -f "$CMDS1" ] && rm -f "$CMDS1"
-       [ -f "$CMDS2" ] && rm -f "$CMDS2"
-       [ -f "$CMDS3" ] && rm -f "$CMDS3"
-       [ -f "$OUT1" ] && rm -f "$OUT1"
-       [ -f "$OUT2a" ] && rm -f "$OUT2a"
-       [ -f "$OUT2b" ] && rm -f "$OUT2b"
-       [ -f "$OUT3" ] && rm -f "$OUT3"
-}
-
-create_tempfiles()
-{
-       # This one is for VLAN list.
-       CMDS1=`mktemp /tmp/cisco.connector.XXXX`
-       # And this one holds ports list...
-       CMDS2=`mktemp /tmp/cisco.connector.XXXX`
-       # ...and one more for MAC address table
-       CMDS3=`mktemp /tmp/cisco.connector.XXXX`
-       # The following are buffers to hold the whole switch output
-       # before filtering.
-       OUT1=`mktemp /tmp/cisco.connector.XXXX`
-       OUT2a=`mktemp /tmp/cisco.connector.XXXX`
-       OUT2b=`mktemp /tmp/cisco.connector.XXXX`
-       OUT3=`mktemp /tmp/cisco.connector.XXXX`
-       [ -f "$CMDS1" -a -f "$CMDS2" -a -f "$CMDS3" -a -f "$OUT1" -a -f "$OUT2a" -a -f "$OUT2b" -a -f "$OUT3" ] && return
-       echo "E!connector cannot create tempfiles" >> "$FILE2"
-       remove_tempfiles
-       exit 5
-}
-
-case $COMMAND in
-       fetch)
-               create_tempfiles
-               prepare_connect_commands $ENDPOINT
-               prepare_fetch_commands
-               do_fetch
-               remove_tempfiles
-       ;;
-       push)
-               create_tempfiles
-               prepare_connect_commands $ENDPOINT
-               prepare_push_commands
-               do_push
-               remove_tempfiles
-       ;;
-       *)
-               echo "E!unknown command for connector" >> "$FILE2"
-               exit 6
-       ;;
-esac
-
+CMDS1=`mktemp /tmp/cisco.connector.XXXX`
+[ -f "$CMDS1" ] || exit 5
+prepare_connect_commands $ENDPOINT
+printf 'term len 0\nshow run\nquit\n' >> $CMDS1
+nc $ENDPOINT 23 < $CMDS1 > "$OUT1"
+if fgrep -q '% Bad passwords' "$OUT1"; then
+       rm -f "$CMDS1"
+       exit 4
+fi
+rm -f "$CMDS1"
 exit 0
index dfa18cd..67b3150 100644 (file)
@@ -1,6 +1,5 @@
 <?php
-echo "Unauthorized access attempt has been logged. Cheers.";
-exit();
+die "Unauthorized access attempt has been logged. Cheers.";
 /*
 
 # Syntax:
index 6399abd..518535a 100755 (executable)
@@ -1,31 +1,14 @@
 #!/bin/sh
 
-# This is a RackTables gateway for changing switch ports membership
-# across VLANs. It works accordingly to the gateway protocol described
-# in gateways.php and accepts the following commands on its stdin:
-#
-# * connect: connect to a switch, fetch all necessary data, store and
-#   disconnect
-#
-# * listvlans: list all VLANs found on the switch, propably filtering
-# out those administratively prohibited. Only the VLANs from this
-# list will be allowed as new destination for 'set' command.
-#
-# * listports: list all ports on the switch and their current status.
-#   Untagged (switchport mode access) ports will be shown with their
-#   VLAN ID and tagged ports will be shown as 'trunk' regardless of
-#   how many VLANs they are members of.
-#
-# * listmacs: output unsorted list of all dynamically learned MAC
-#   addresses present on the switch
+# This gateway retrieves the output of "show run" command (or its
+# equivalent) and prints it onto stdout. When run, it accepts the
+# only command on stdin:
 #
+# * retrieve <endpoint> <hardware> <software>: print text and terminate
 
 endpoint=
 hw=
 sw=
-user=
-handler=
-CONNECTED=0
 MYDIR=`dirname $0`
 
 decode_error()
@@ -61,15 +44,13 @@ decode_error()
        esac
 }
 
-# Not only connect, but gather all the data at once and remember the context.
-do_connect()
+do_work()
 {
        endpoint=`echo $args | cut -s -d' ' -f1`
        hw=`echo $args | cut -s -d' ' -f2`
        sw=`echo $args | cut -s -d' ' -f3`
-       user=`echo $args | cut -s -d' ' -f4`
        # sanity checks
-       if [ -z "$endpoint" -o -z "$hw" -o -z "$sw" -o -z "$user" ]; then
+       if [ -z "$endpoint" -o -z "$hw" -o -z "$sw" ]; then
                echo 'ERR!too few arguments to connect'
                return
        fi
@@ -83,31 +64,17 @@ do_connect()
                ;;
        esac
 
-       # prepare temp files
-       PORTINFO=`mktemp /tmp/racktables.XXXX`
-       if ! [ -f "$PORTINFO" ]; then
-               echo 'ERR!could not create portinfo tmpfile'
-               return
-       fi
-       VLANINFO=`mktemp /tmp/racktables.XXXX`
-       if ! [ -f "$VLANINFO" ]; then
-               echo 'ERR!could not create vlaninfo tmpfile'
-               rm -f "$PORTINFO"
-               return
-       fi
-       MACINFO=`mktemp /tmp/racktables.XXXX`
-       if ! [ -f "$MACINFO" ]; then
-               echo 'ERR!could not create MACinfo tmpfile'
-               rm -f "$PORTINFO" "$VLANINFO"
+       CONFTEXT=`mktemp /tmp/racktables.XXXX`
+       if ! [ -f "$CONFTEXT" ]; then
+               echo 'ERR!could not create tmpfile'
                return
        fi
 
-       # get the data
-       "$MYDIR/$handler.connector" $endpoint $hw $sw fetch "$VLANINFO" "$PORTINFO" "$MACINFO"
+       "$MYDIR/$handler.connector" $endpoint "$CONFTEXT"
        ret=$?
        if [ $ret = 0 ]; then
-               CONNECTED=1
-               echo "OK!connected to $endpoint";
+               echo "OK!connected to $endpoint"
+               cat "$CONFTEXT"
        else
                echo -n "ERR!Cannot connect to $endpoint ("
                decode_error $ret
@@ -115,125 +82,16 @@ do_connect()
        fi
 }
 
-do_listfile()
-{
-       local F=$1
-       if ! [ -f "$F" ]; then
-               echo "ERR!Lost temp file '$F' on the way"
-               return
-       fi
-       echo -n 'OK!'
-       local semicolon=''
-       # tr might do the work, but use our chance to perform filtering once more
-       cat "$F" | while read line; do
-               [ "$line" = "" ] && continue
-               echo -n "$semicolon$line"
-               semicolon=';'
-       done
-       echo
-}
-
-do_set()
-{
-       # sanity checks
-       local setline=$1
-       if [ -z "$setline" ]; then
-               echo 'ERR!missing set argument'
-               return
-       fi
-       local REQUESTS=`mktemp /tmp/racktables.XXXX`
-       local REPLIES=`mktemp /tmp/racktables.XXXX`
-       echo $1 | tr ';' '\n' | while read setexpr; do
-               portname=`echo $setexpr | cut -s -d'=' -f1`
-               newvlan=`echo $setexpr | cut -s -d'=' -f2`
-               curvlan=`egrep "^$portname=" $PORTINFO | cut -s -d'=' -f2 | cut -d',' -f2`
-               if [ -z "$curvlan" ]; then
-                       echo "C!167!$portname" >> "$REPLIES"
-                       continue
-               fi
-               if [ "$curvlan" = "trunk" ]; then
-                       echo "C!168!$portname" >> "$REPLIES"
-                       continue
-               fi
-               [ "$curvlan" = "$newvlan" ] && continue
-               echo "$portname $newvlan" >> "$REQUESTS"
-               cmembers=`grep -c ",$newvlan$" "$PORTINFO"`
-               if [ "$cmembers" = "0" -a $newvlan -lt 4096 ]; then
-                       echo "C!203!$portname!$newvlan" >> "$REPLIES"
-                       echo "C!204" >> "$REPLIES"
-               fi
-       done
-       nr=`egrep -c '^C!1.' "$REPLIES"`
-       if [ "$nr" -ge 1 ]; then
-               echo "C!205!$nr" >> "$REPLIES"
-       fi
-
-       nq=`egrep -c '^.' "$REQUESTS"`
-       if [ "$nq" -ge 1 ]; then
-               # Go!
-               "$MYDIR/$handler.connector" $endpoint $hw $sw push "$REQUESTS" "$REPLIES" "$MACINFO"
-               local ret=$?
-
-               if [ $ret != 0 ]; then
-                       echo "C!169!$endpoint!$ret"
-                       return
-               fi
-               echo "C!63!$nq" >> "$REPLIES"
-       fi
-       echo -n 'OK!'
-       local SEMICOLON=
-       while read reply; do
-               echo -n $SEMICOLON$reply
-               SEMICOLON=';'
-               timestamp=`date '+%Y-%m-%d %H:%M:%S'`
-               [ -w "$MYDIR/changes.log" ] && echo "$timestamp $user@$endpoint $reply" >> "$MYDIR/changes.log"
-       done < "$REPLIES"
-       echo
-       rm -f "$REQUESTS" "$REPLIES"
-}
-
-# main loop
 while read cmd args; do
        case $cmd in
-               connect)
-                       if [ $CONNECTED = 1 ]; then
-                               echo 'ERR!Already connected'
-                       else
-                               do_connect $args
-                       fi
-                       ;;
-               listvlans)
-                       if [ $CONNECTED = 1 ]; then
-                               do_listfile "$VLANINFO"
-                       else
-                               echo 'ERR!Not connected'
-                       fi
-                       ;;
-               listports)
-                       if [ $CONNECTED = 1 ]; then
-                               do_listfile "$PORTINFO"
-                       else
-                               echo 'ERR!Not connected'
-                       fi
-                       ;;
-               listmacs)
-                       if [ $CONNECTED = 1 ]; then
-                               do_listfile "$MACINFO"
-                       else
-                               echo 'ERR!Not connected'
-                       fi
-                       ;;
-               set)
-                       if [ $CONNECTED = 1 ]; then
-                               do_set $args
-                       else
-                               echo 'ERR!Not connected'
-                       fi
+               retrieve)
+                       do_work $args
+                       rm -f "$CONFTEXT"
+                       exit 0
                        ;;
                *)
                        echo "ERR!unknown command $cmd"
        esac
 done
 
-rm -f "$PORTINFO" "$VLANINFO" "$MACINFO"
 exit 0