r1776 + don't waste PDO resources for sequental SELECT queries in one function
[racktables] / gateways / switchvlans / cisco.connector
CommitLineData
533aefb8
DO
1#!/bin/sh
2
fc11a02c 3[ $# = 7 ] || exit 1
533aefb8
DO
4
5ENDPOINT=$1
fc11a02c
DO
6HW=$2
7SW=$3
8COMMAND=$4
9FILE1=$5
10FILE2=$6
11FILE3=$7
1b354441 12MYDIR=`dirname $0`
533aefb8 13
697a123b 14prepare_connect_commands()
533aefb8 15{
697a123b
DO
16 [ $# = 1 ] || exit 2
17 local skip=yes cval found=no
533aefb8
DO
18 while read line; do
19 if [ "$skip" = "yes" -a "$line" = "# S-T-A-R-T" ]; then
20 skip=no
21 continue
22 fi
23 if [ "$skip" = "no" -a "$line" = "# S-T-O-P" ]; then
24 skip=yes
25 continue
26 fi
27 [ "$skip" = "yes" ] && continue
28 # Allow comments.
29 [ -z "${line###*}" ] && continue
30
31 # First endpoint string/regexp match is sufficient for us.
32 cval=`echo $line | cut -s -d' ' -f1`
33 if [ -z "${1##$cval}" ]; then
697a123b 34 found=yes
533aefb8
DO
35 # Don't be too smart at the moment, just be able to handle
36 # the known-good case ;-)
37
38 echo $line | cut -s -d' ' -f6 > $CMDS1
39 echo en >> $CMDS1
40 echo $line | cut -s -d' ' -f7 >> $CMDS1
533aefb8 41 # same for ports
9e76e210
DO
42 cat "$CMDS1" > "$CMDS2"
43 # ...and MAC addresses
44 cat "$CMDS1" > "$CMDS3"
533aefb8
DO
45 break
46 fi
1b354441 47 done < "$MYDIR/cisco.secrets.php"
697a123b
DO
48 [ "$found" = "yes" ] && return
49 echo "E!connector could not find credentials for $1" >> "$FILE2"
50 exit 3
51}
52
53prepare_fetch_commands()
54{
533aefb8
DO
55 printf 'term len 0\nshow vlan brief\nquit\n' >> $CMDS1
56 printf 'term len 0\nshow int status\nquit\n' >> $CMDS2
fc11a02c 57 printf 'term len 0\nshow mac-address-table dynamic\nquit\n' >> $CMDS3
533aefb8
DO
58}
59
7865c525 60prepare_push_commands()
533aefb8 61{
5b6704b5
DO
62 printf 'term len 0\nconf t\n' >> $CMDS1
63 while read portname vlanid; do
64 if [ -z "$portname" -o -z "$vlanid" ]; then
65 echo "E!could not parse input in connector" >> "$FILE2"
66 continue
67 fi
68 if [ "$vlanid" = "trunk" ]; then
69 echo "E!trunking is not allowed" >> "$FILE2"
70 continue
71 fi
1b354441
DO
72 printf "int $portname\n" >> $CMDS1
73 if [ $vlanid -lt 4096 ]; then
74 printf "swi access vlan $vlanid\nswi mode access\n" >> $CMDS1
22f2bc98 75 printf "no description\n" >> $CMDS1
1b354441
DO
76 else
77 printf "descr VLAN$vlanid\n" >> $CMDS1
22f2bc98 78 printf "swi trunk encap dot1q\nswi mode trunk\n" >> $CMDS1
1b354441
DO
79 "$MYDIR/trunkdecoder" $vlanid >> $CMDS1
80 fi
81 printf "exit\n" >> $CMDS1
5b6704b5
DO
82 echo "I!Port $portname@$ENDPOINT has been assigned to VLAN $vlanid" >> "$FILE2"
83 done < "$FILE1"
be6ae134 84 printf "end\nwri\nquit\n" >> $CMDS1
7865c525
DO
85}
86
87do_fetch()
88{
1b354441 89 local tmp_ifname tmp_ifdescr tmp_status tmp_vlanid
697a123b
DO
90 nc $ENDPOINT 23 < $CMDS1 > "$OUT1"
91 if fgrep -q '% Bad passwords' "$OUT1"; then
92 echo "E!password mismatch while trying to connect to $ENDPOINT" >> "$FILE2"
93 exit 4
94 fi
1b354441 95 nc $ENDPOINT 23 < $CMDS2 > "$OUT2a"
fc11a02c 96 nc $ENDPOINT 23 < $CMDS3 > "$OUT3"
c882b87d 97 cat "$OUT1" | fgrep ' active ' | sed -E 's/^([[:digit:]]+)[[:space:]]+(.+)[[:space:]]+active (.*)/\1=\2/;s/[[:space:]]+$//' > $FILE1
1b354441
DO
98 # Add trunk data, if appropriate.
99 [ -s "$MYDIR/trunktable" ] && cat "$MYDIR/trunktable" >> $FILE1
100
101 # First extract structured info about VLAN membership, then map
102 # special descriptions into VLAN IDs.
ff99f589 103 cat "$OUT2a" | egrep '^(Et|Fa|Gi|Te)' | sed -E 's/^([A-Za-z/0-9]+) +(.*) +(connected|notconnect|disabled|monitoring|suspended) +/\1~\2%\3%/;s/%(trunk|([0-9]+)) .*$/%\1/;s/=(monitoring|suspended)%/=connected%/;s/ +%/%/;s/~/%/' > $OUT2b
1b354441
DO
104 while read line; do
105 tmp_ifname=`echo $line | cut -d% -f1`
106 tmp_ifdescr=`echo $line | cut -d% -f2`
107 tmp_status=`echo $line | cut -d% -f3`
108 tmp_vlanid=`echo $line | cut -d% -f4`
109 # If the port has a description pretending to be a martian VLAN, map it onto the VLAN ID.
110 if [ -n "$tmp_ifdescr" -a -z "${tmp_ifdescr##VLAN*}" ]; then
111 tmp_vlanid=${tmp_ifdescr##VLAN}
112 fi
113 echo "$tmp_ifname=$tmp_status,$tmp_vlanid" >> $FILE2
114 done < $OUT2b
fc11a02c 115 # FIXME
9e76e210
DO
116 # Here we need to distinguish between different platforms and IOS version,
117 # cause they produce output in different formats.
118 if [ "$SW" = "Cisco+IOS+12.0" ]; then
119 cat "$OUT3" | tr -d '\r' | fgrep Dynamic | sed -E 's/ +Dynamic +([0-9]+) +(.+)/=\1@\2/;s/FastEthernet/Fa/;s/GigabitEthernet/Gi/' > "$FILE3"
1b354441 120 elif [ "$SW" = "Cisco+IOS+12.2" -o "$SW" = "Cisco+IOS+12.1" ]; then
2a078c28 121 case "$HW" in
9a8ce4df 122 Cisco+Catalyst+35*|Cisco+Catalyst+37*|Cisco+Catalyst+29*|Cisco+Catalyst+49*)
2a078c28
DO
123 cat "$OUT3" | tr -d '\r' | fgrep DYNAMIC | \
124 sed -E 's/ +([0-9]+) +(.+) DYNAMIC +(.+)/\2=\1@\3/;s/FastEthernet/Fa/;s/GigabitEthernet/Gi/' > "$FILE3"
125 ;;
126 esac
9e76e210 127 fi
7865c525
DO
128}
129
130do_push()
131{
5b6704b5 132 nc $ENDPOINT 23 < $CMDS1 >/dev/null
533aefb8
DO
133}
134
697a123b
DO
135remove_tempfiles()
136{
137 [ -f "$CMDS1" ] && rm -f "$CMDS1"
138 [ -f "$CMDS2" ] && rm -f "$CMDS2"
fc11a02c 139 [ -f "$CMDS3" ] && rm -f "$CMDS3"
697a123b 140 [ -f "$OUT1" ] && rm -f "$OUT1"
1b354441
DO
141 [ -f "$OUT2a" ] && rm -f "$OUT2a"
142 [ -f "$OUT2b" ] && rm -f "$OUT2b"
fc11a02c 143 [ -f "$OUT3" ] && rm -f "$OUT3"
697a123b 144}
533aefb8 145
697a123b
DO
146create_tempfiles()
147{
148 # This one is for VLAN list.
149 CMDS1=`mktemp /tmp/cisco.connector.XXXX`
fc11a02c 150 # And this one holds ports list...
697a123b 151 CMDS2=`mktemp /tmp/cisco.connector.XXXX`
fc11a02c
DO
152 # ...and one more for MAC address table
153 CMDS3=`mktemp /tmp/cisco.connector.XXXX`
154 # The following are buffers to hold the whole switch output
697a123b
DO
155 # before filtering.
156 OUT1=`mktemp /tmp/cisco.connector.XXXX`
1b354441
DO
157 OUT2a=`mktemp /tmp/cisco.connector.XXXX`
158 OUT2b=`mktemp /tmp/cisco.connector.XXXX`
fc11a02c 159 OUT3=`mktemp /tmp/cisco.connector.XXXX`
1b354441 160 [ -f "$CMDS1" -a -f "$CMDS2" -a -f "$CMDS3" -a -f "$OUT1" -a -f "$OUT2a" -a -f "$OUT2b" -a -f "$OUT3" ] && return
697a123b
DO
161 echo "E!connector cannot create tempfiles" >> "$FILE2"
162 remove_tempfiles
163 exit 5
164}
533aefb8
DO
165
166case $COMMAND in
7865c525 167 fetch)
697a123b
DO
168 create_tempfiles
169 prepare_connect_commands $ENDPOINT
170 prepare_fetch_commands
7865c525 171 do_fetch
697a123b 172 remove_tempfiles
533aefb8 173 ;;
7865c525 174 push)
697a123b
DO
175 create_tempfiles
176 prepare_connect_commands $ENDPOINT
177 prepare_push_commands
7865c525 178 do_push
697a123b 179 remove_tempfiles
533aefb8
DO
180 ;;
181 *)
697a123b
DO
182 echo "E!unknown command for connector" >> "$FILE2"
183 exit 6
533aefb8
DO
184 ;;
185esac
186
533aefb8 187exit 0