r1310 + fixed a regexp for long VLAN names
[racktables] / gateways / switchvlans / cisco.connector
1 #!/bin/sh
2
3 [ $# = 7 ] || exit 1
4
5 ENDPOINT=$1
6 HW=$2
7 SW=$3
8 COMMAND=$4
9 FILE1=$5
10 FILE2=$6
11 FILE3=$7
12
13 prepare_connect_commands()
14 {
15 [ $# = 1 ] || exit 2
16 local skip=yes cval found=no
17 while read line; do
18 if [ "$skip" = "yes" -a "$line" = "# S-T-A-R-T" ]; then
19 skip=no
20 continue
21 fi
22 if [ "$skip" = "no" -a "$line" = "# S-T-O-P" ]; then
23 skip=yes
24 continue
25 fi
26 [ "$skip" = "yes" ] && continue
27 # Allow comments.
28 [ -z "${line###*}" ] && continue
29
30 # First endpoint string/regexp match is sufficient for us.
31 cval=`echo $line | cut -s -d' ' -f1`
32 if [ -z "${1##$cval}" ]; then
33 found=yes
34 # Don't be too smart at the moment, just be able to handle
35 # the known-good case ;-)
36
37 echo $line | cut -s -d' ' -f6 > $CMDS1
38 echo en >> $CMDS1
39 echo $line | cut -s -d' ' -f7 >> $CMDS1
40 # same for ports
41 cat "$CMDS1" > "$CMDS2"
42 # ...and MAC addresses
43 cat "$CMDS1" > "$CMDS3"
44 break
45 fi
46 done < `dirname $0`/cisco.secrets.php
47 [ "$found" = "yes" ] && return
48 echo "E!connector could not find credentials for $1" >> "$FILE2"
49 exit 3
50 }
51
52 prepare_fetch_commands()
53 {
54 printf 'term len 0\nshow vlan brief\nquit\n' >> $CMDS1
55 printf 'term len 0\nshow int status\nquit\n' >> $CMDS2
56 printf 'term len 0\nshow mac-address-table dynamic\nquit\n' >> $CMDS3
57 }
58
59 prepare_push_commands()
60 {
61 printf 'term len 0\nconf t\n' >> $CMDS1
62 while read portname vlanid; do
63 if [ -z "$portname" -o -z "$vlanid" ]; then
64 echo "E!could not parse input in connector" >> "$FILE2"
65 continue
66 fi
67 if [ "$vlanid" = "trunk" ]; then
68 echo "E!trunking is not allowed" >> "$FILE2"
69 continue
70 fi
71 printf "int $portname\nswi access vlan $vlanid\nexit\n" >> $CMDS1
72 echo "I!Port $portname@$ENDPOINT has been assigned to VLAN $vlanid" >> "$FILE2"
73 done < "$FILE1"
74 printf "end\nwri\nquit\n" >> $CMDS1
75 }
76
77 do_fetch()
78 {
79 nc $ENDPOINT 23 < $CMDS1 > "$OUT1"
80 if fgrep -q '% Bad passwords' "$OUT1"; then
81 echo "E!password mismatch while trying to connect to $ENDPOINT" >> "$FILE2"
82 exit 4
83 fi
84 nc $ENDPOINT 23 < $CMDS2 > "$OUT2"
85 nc $ENDPOINT 23 < $CMDS3 > "$OUT3"
86 cat "$OUT1" | fgrep ' active ' | sed -E 's/^([[:digit:]]+)[[:space:]]+(.+)[[:space:]]+active (.*)/\1=\2/;s/[[:space:]]+$//' > $FILE1
87 cat "$OUT2" | egrep '^(Et|Fa|Gi|Te)' | sed -E 's/^([A-Za-z/0-9]+).+(connected|notconnect|disabled) +/\1=\2,/;s/,(trunk|([0-9]+)) .*$/,\1/' > $FILE2
88 # FIXME
89 # Here we need to distinguish between different platforms and IOS version,
90 # cause they produce output in different formats.
91 if [ "$SW" = "Cisco+IOS+12.0" ]; then
92 cat "$OUT3" | tr -d '\r' | fgrep Dynamic | sed -E 's/ +Dynamic +([0-9]+) +(.+)/=\1@\2/;s/FastEthernet/Fa/;s/GigabitEthernet/Gi/' > "$FILE3"
93 elif [ "$SW" = "Cisco+IOS+12.2" ]; then
94 case "$HW" in
95 Cisco+Catalyst+35*|Cisco+Catalyst+37*|Cisco+Catalyst+29*|Cisco+Catalyst+49*)
96 cat "$OUT3" | tr -d '\r' | fgrep DYNAMIC | \
97 sed -E 's/ +([0-9]+) +(.+) DYNAMIC +(.+)/\2=\1@\3/;s/FastEthernet/Fa/;s/GigabitEthernet/Gi/' > "$FILE3"
98 ;;
99 esac
100 fi
101 }
102
103 do_push()
104 {
105 nc $ENDPOINT 23 < $CMDS1 >/dev/null
106 }
107
108 remove_tempfiles()
109 {
110 [ -f "$CMDS1" ] && rm -f "$CMDS1"
111 [ -f "$CMDS2" ] && rm -f "$CMDS2"
112 [ -f "$CMDS3" ] && rm -f "$CMDS3"
113 [ -f "$OUT1" ] && rm -f "$OUT1"
114 [ -f "$OUT2" ] && rm -f "$OUT2"
115 [ -f "$OUT3" ] && rm -f "$OUT3"
116 }
117
118 create_tempfiles()
119 {
120 # This one is for VLAN list.
121 CMDS1=`mktemp /tmp/cisco.connector.XXXX`
122 # And this one holds ports list...
123 CMDS2=`mktemp /tmp/cisco.connector.XXXX`
124 # ...and one more for MAC address table
125 CMDS3=`mktemp /tmp/cisco.connector.XXXX`
126 # The following are buffers to hold the whole switch output
127 # before filtering.
128 OUT1=`mktemp /tmp/cisco.connector.XXXX`
129 OUT2=`mktemp /tmp/cisco.connector.XXXX`
130 OUT3=`mktemp /tmp/cisco.connector.XXXX`
131 [ -f "$CMDS1" -a -f "$CMDS2" -a -f "$CMDS3" -a -f "$OUT1" -a -f "$OUT2" -a -f "$OUT3" ] && return
132 echo "E!connector cannot create tempfiles" >> "$FILE2"
133 remove_tempfiles
134 exit 5
135 }
136
137 case $COMMAND in
138 fetch)
139 create_tempfiles
140 prepare_connect_commands $ENDPOINT
141 prepare_fetch_commands
142 do_fetch
143 remove_tempfiles
144 ;;
145 push)
146 create_tempfiles
147 prepare_connect_commands $ENDPOINT
148 prepare_push_commands
149 do_push
150 remove_tempfiles
151 ;;
152 *)
153 echo "E!unknown command for connector" >> "$FILE2"
154 exit 6
155 ;;
156 esac
157
158 exit 0