blob: 7706969775088253baee291cbe3902cced818b00 [file] [log] [blame]
Steve McIntyrecc297112014-08-11 18:46:58 +01001#! /usr/bin/python
2
3# Copyright 2014 Linaro Limited
4#
5# This program is free software; you can redistribute it and/or modify
6# it under the terms of the GNU General Public License as published by
7# the Free Software Foundation; either version 2 of the License, or
8# (at your option) any later version.
9#
10# This program is distributed in the hope that it will be useful,
11# but WITHOUT ANY WARRANTY; without even the implied warranty of
12# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13# GNU General Public License for more details.
14#
15# You should have received a copy of the GNU General Public License
16# along with this program; if not, write to the Free Software
17# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
18# MA 02110-1301, USA.
19
20import logging
21import pexpect
22import sys
23import time
24import re
25from common import SwitchDriver
26
Steve McIntyre72a8bce2015-01-23 18:02:19 +000027if __name__ == '__main__':
28 vlandpath = os.path.abspath(os.path.normpath(os.path.dirname(sys.argv[0])))
29 sys.path.insert(0, vlandpath)
30 sys.path.insert(0, "%s/.." % vlandpath)
31
32from errors import CriticalError, InputError
33
Steve McIntyrecc297112014-08-11 18:46:58 +010034class CiscoSX300(SwitchDriver):
35
36 connection = None
Steve McIntyre366046f2014-08-18 18:57:03 +010037
38 # No extra capabilities for this switch/driver yet
39 _capabilities = [
40 ]
41
Steve McIntyrecc297112014-08-11 18:46:58 +010042 # Regexp of expected hardware information - fail if we don't see
43 # this
Steve McIntyreb9783ff2014-12-23 16:36:35 +000044 _expected_descr_re = re.compile('.*\d+-Port.*Managed Switch.*')
Steve McIntyrecc297112014-08-11 18:46:58 +010045
Steve McIntyre16f02162014-08-14 17:47:36 +010046 logfile = None
Steve McIntyrecc297112014-08-11 18:46:58 +010047
Steve McIntyre48dc6ae2014-12-23 16:08:19 +000048 def __init__(self, switch_hostname, switch_telnetport=23, debug = False):
49 if debug:
Steve McIntyre9f5a0232014-12-23 16:14:28 +000050 self.logfile = sys.stderr
Steve McIntyrecc297112014-08-11 18:46:58 +010051 self.exec_string = "/usr/bin/telnet %s %d" % (switch_hostname, switch_telnetport)
52
53 ################################
54 ### Switch-level API functions
55 ################################
56
57 # Connect to the switch and log in
Steve McIntyrec1e42b72014-12-22 16:13:08 +000058 def switch_connect(self, username, password, enablepassword):
Steve McIntyrecc297112014-08-11 18:46:58 +010059 logging.debug("Connecting to Switch with: %s" % self.exec_string)
60 self.connection = pexpect.spawn(self.exec_string, logfile = self.logfile)
61 self._login(username, password)
62
Steve McIntyredd0c0012014-12-24 00:10:17 +000063 # Avoid paged output
64 self._cli("terminal datadump")
Steve McIntyre7ced0732014-08-12 18:07:56 +010065
Steve McIntyrecc297112014-08-11 18:46:58 +010066 # And grab details about the switch. in case we need it
Steve McIntyre366046f2014-08-18 18:57:03 +010067 self._get_systemdata()
Steve McIntyrecc297112014-08-11 18:46:58 +010068
69 # And also validate them - make sure we're driving a switch of
70 # the correct model! Also store the serial number
Steve McIntyreb9783ff2014-12-23 16:36:35 +000071 descr_regex = re.compile('System Description:.\s+(.*)')
Steve McIntyrecc297112014-08-11 18:46:58 +010072 sn_regex = re.compile('SN:\s+(\S_)')
73 descr = ""
74
Steve McIntyre366046f2014-08-18 18:57:03 +010075 for line in self._systemdata:
Steve McIntyrecc297112014-08-11 18:46:58 +010076 match = descr_regex.match(line)
77 if match:
78 descr = match.group(1)
79 match = sn_regex.match(line)
80 if match:
81 self.serial_number = match.group(1)
82
Steve McIntyre366046f2014-08-18 18:57:03 +010083 if not self._expected_descr_re.match(descr):
Steve McIntyrecc297112014-08-11 18:46:58 +010084 raise IOError("Switch %s not recognised by this driver: abort" % descr)
85
Steve McIntyre28d34ca2014-08-12 15:40:24 +010086 # Now build a list of our ports, for later sanity checking
Steve McIntyre366046f2014-08-18 18:57:03 +010087 self._ports = self._get_port_names()
88 if len(self._ports) < 4:
Steve McIntyre28d34ca2014-08-12 15:40:24 +010089 raise IOError("Not enough ports detected - problem!")
90
Steve McIntyrecc297112014-08-11 18:46:58 +010091 # Log out of the switch and drop the connection and all state
Steve McIntyre9b09b9d2014-09-24 15:08:10 +010092 def switch_disconnect(self):
Steve McIntyrecc297112014-08-11 18:46:58 +010093 self._logout()
94 logging.debug("Closing connection: %s" % self.connection)
95 self.connection.close(True)
Steve McIntyre11393992014-10-10 15:53:34 +010096 self._ports = []
97 self._prompt_name = ''
98 self._systemdata = []
Steve McIntyrecc297112014-08-11 18:46:58 +010099 del(self)
100
101 # Save the current running config into flash - we want config to
102 # remain across reboots
Steve McIntyre9b09b9d2014-09-24 15:08:10 +0100103 def switch_save_running_config(self):
Steve McIntyrecc297112014-08-11 18:46:58 +0100104 self._cli("copy running-config startup-config")
105 self.connection.expect("Y/N")
106 self._cli("y")
Steve McIntyre2b4c07b2014-12-22 16:10:04 +0000107 self.connection.expect("succeeded")
Steve McIntyrecc297112014-08-11 18:46:58 +0100108
Steve McIntyre095b4452014-12-19 17:53:43 +0000109 # Restart the switch - we need to reload config to do a
110 # roll-back. Do NOT save running-config first if the switch asks -
111 # we're trying to dump recent changes, not save them.
112 #
113 # This will also implicitly cause a connection to be closed
114 def switch_restart(self):
115 self._cli("reload")
116 index = self.connection.expect(['Are you sure', 'will reset'])
117 if index == 0:
118 self._cli("y") # Yes, continue without saving
119 self.connection.expect("reset the whole")
120
121 # Fall through
122 self._cli("y") # Yes, continue to reset
123 self.connection.close(True)
124
Steve McIntyrecc297112014-08-11 18:46:58 +0100125 ################################
126 ### VLAN API functions
127 ################################
128
129 # Create a VLAN with the specified tag
Steve McIntyre9b09b9d2014-09-24 15:08:10 +0100130 def vlan_create(self, tag):
Steve McIntyrecc297112014-08-11 18:46:58 +0100131 logging.debug("Creating VLAN %d" % tag)
132 self._configure()
133 self._cli("vlan database")
134 self._cli("vlan %d" % tag)
135 self._end_configure()
136
137 # Validate it happened
Steve McIntyre9b09b9d2014-09-24 15:08:10 +0100138 vlans = self.vlan_get_list()
Steve McIntyrecc297112014-08-11 18:46:58 +0100139 for vlan in vlans:
140 if vlan == tag:
141 return
142 raise IOError("Failed to create VLAN %d" % tag)
143
144 # Destroy a VLAN with the specified tag
Steve McIntyre9b09b9d2014-09-24 15:08:10 +0100145 def vlan_destroy(self, tag):
Steve McIntyrecc297112014-08-11 18:46:58 +0100146 logging.debug("Destroying VLAN %d" % tag)
147 self._configure()
148 self._cli("no vlan %d" % tag)
149 self._end_configure()
150
151 # Validate it happened
Steve McIntyre9b09b9d2014-09-24 15:08:10 +0100152 vlans = self.vlan_get_list()
Steve McIntyrecc297112014-08-11 18:46:58 +0100153 for vlan in vlans:
154 if vlan == tag:
155 raise IOError("Failed to destroy VLAN %d" % tag)
156
157 # Set the name of a VLAN
Steve McIntyre9b09b9d2014-09-24 15:08:10 +0100158 def vlan_set_name(self, tag, name):
Steve McIntyrecc297112014-08-11 18:46:58 +0100159 logging.debug("Setting name of VLAN %d to %s" % (tag, name))
160 self._configure()
161 self._cli("vlan %d" % tag)
162 self._cli("interface vlan %d" % tag)
163 self._cli("name %s" % name)
164 self._end_configure()
165
166 # Validate it happened
Steve McIntyre9b09b9d2014-09-24 15:08:10 +0100167 read_name = self.vlan_get_name(tag)
Steve McIntyrecc297112014-08-11 18:46:58 +0100168 if read_name != name:
169 raise IOError("Failed to set name for VLAN %d (name found is \"%s\", not \"%s\")"
170 % (tag, read_name, name))
171
172 # Get a list of the VLAN tags currently registered on the switch
Steve McIntyre9b09b9d2014-09-24 15:08:10 +0100173 def vlan_get_list(self):
Steve McIntyrecc297112014-08-11 18:46:58 +0100174 logging.debug("Grabbing list of VLANs")
175 vlans = []
176
177 regex = re.compile('^ *(\d+).*(D|S|G|R)')
178
179 self._cli("show vlan")
Steve McIntyrec68d6d72014-12-24 00:23:36 +0000180 for line in self._read_long_output():
Steve McIntyrecc297112014-08-11 18:46:58 +0100181 match = regex.match(line)
182 if match:
183 vlans.append(int(match.group(1)))
184 return vlans
185
186 # For a given VLAN tag, ask the switch what the associated name is
Steve McIntyre9b09b9d2014-09-24 15:08:10 +0100187 def vlan_get_name(self, tag):
Steve McIntyrecc297112014-08-11 18:46:58 +0100188 logging.debug("Grabbing the name of VLAN %d" % tag)
189 name = None
190 regex = re.compile('^ *\d+\s+(\S+).*(D|S|G|R)')
191 self._cli("show vlan tag %d" % tag)
Steve McIntyrec68d6d72014-12-24 00:23:36 +0000192 for line in self._read_long_output():
Steve McIntyrecc297112014-08-11 18:46:58 +0100193 match = regex.match(line)
194 if match:
195 name = match.group(1)
196 name.strip()
197 return name
198
199
200 ################################
201 ### Port API functions
202 ################################
203
Steve McIntyre9936d002014-10-01 15:54:10 +0100204 # Set the mode of a port: access or trunk
Steve McIntyre9b09b9d2014-09-24 15:08:10 +0100205 def port_set_mode(self, port, mode):
Steve McIntyrecc297112014-08-11 18:46:58 +0100206 logging.debug("Setting port %s to %s" % (port, mode))
207 if not self._is_port_mode_valid(mode):
Steve McIntyre72a8bce2015-01-23 18:02:19 +0000208 raise InputError("Port mode %s is not allowed" % mode)
Steve McIntyrecc297112014-08-11 18:46:58 +0100209 if not self._is_port_name_valid(port):
Steve McIntyre72a8bce2015-01-23 18:02:19 +0000210 raise InputError("Port name %s not recognised" % port)
Steve McIntyrecc297112014-08-11 18:46:58 +0100211 self._configure()
212 self._cli("interface %s" % port)
213 self._cli("switchport mode %s" % mode)
214 self._end_configure()
215
216 # Validate it happened
Steve McIntyre9b09b9d2014-09-24 15:08:10 +0100217 read_mode = self.port_get_mode(port)
Steve McIntyrecc297112014-08-11 18:46:58 +0100218 if read_mode != mode:
219 raise IOError("Failed to set mode for port %s" % port)
220
221
Steve McIntyre9936d002014-10-01 15:54:10 +0100222 # Get the mode of a port: access or trunk
Steve McIntyre9b09b9d2014-09-24 15:08:10 +0100223 def port_get_mode(self, port):
Steve McIntyrecc297112014-08-11 18:46:58 +0100224 logging.debug("Getting mode of port %s" % port)
225 mode = ''
226 if not self._is_port_name_valid(port):
Steve McIntyre72a8bce2015-01-23 18:02:19 +0000227 raise InputError("Port name %s not recognised" % port)
Steve McIntyrecc297112014-08-11 18:46:58 +0100228 regex = re.compile('Port Mode: (\S+)')
229 self._cli("show interfaces switchport %s" % port)
Steve McIntyrec68d6d72014-12-24 00:23:36 +0000230 for line in self._read_long_output():
Steve McIntyrecc297112014-08-11 18:46:58 +0100231 match = regex.match(line)
232 if match:
233 mode = match.group(1)
234 return mode.lower()
235
Steve McIntyre9936d002014-10-01 15:54:10 +0100236 # Set an access port to be in a specified VLAN (tag)
237 def port_set_access_vlan(self, port, tag):
238 logging.debug("Setting access port %s to VLAN %d" % (port, tag))
Steve McIntyrecc297112014-08-11 18:46:58 +0100239 if not self._is_port_name_valid(port):
Steve McIntyre72a8bce2015-01-23 18:02:19 +0000240 raise InputError("Port name %s not recognised" % port)
Steve McIntyre9936d002014-10-01 15:54:10 +0100241 if not (self.port_get_mode(port) == "access"):
Steve McIntyre72a8bce2015-01-23 18:02:19 +0000242 raise InputError("Port %s not in access mode" % port)
Steve McIntyrecc297112014-08-11 18:46:58 +0100243
Steve McIntyre9936d002014-10-01 15:54:10 +0100244 self._configure()
245 self._cli("interface %s" % port)
246 self._cli("switchport access vlan %d" % tag)
247 self._end_configure()
Steve McIntyrecc297112014-08-11 18:46:58 +0100248
Steve McIntyre9936d002014-10-01 15:54:10 +0100249 # Validate things worked
250 read_vlan = int(self.port_get_access_vlan(port))
Steve McIntyrecc297112014-08-11 18:46:58 +0100251 if read_vlan != tag:
Steve McIntyre9936d002014-10-01 15:54:10 +0100252 raise IOError("Failed to move access port %s to VLAN %d - got VLAN %d instead"
Steve McIntyrecc297112014-08-11 18:46:58 +0100253 % (port, tag, read_vlan))
254
Steve McIntyrecc297112014-08-11 18:46:58 +0100255 # Add a trunk port to a specified VLAN (tag)
Steve McIntyre9b09b9d2014-09-24 15:08:10 +0100256 def port_add_trunk_to_vlan(self, port, tag):
Steve McIntyrecc297112014-08-11 18:46:58 +0100257 logging.debug("Adding trunk port %s to VLAN %d" % (port, tag))
258 if not self._is_port_name_valid(port):
Steve McIntyre72a8bce2015-01-23 18:02:19 +0000259 raise InputError("Port name %s not recognised" % port)
Steve McIntyre9b09b9d2014-09-24 15:08:10 +0100260 if not (self.port_get_mode(port) == "trunk"):
Steve McIntyre72a8bce2015-01-23 18:02:19 +0000261 raise InputError("Port %s not in trunk mode" % port)
Steve McIntyrecc297112014-08-11 18:46:58 +0100262 self._configure()
263 self._cli("interface %s" % port)
264 self._cli("switchport trunk allowed vlan add %d" % tag)
265 self._end_configure()
266
267 # Validate it happened
Steve McIntyre9b09b9d2014-09-24 15:08:10 +0100268 read_vlans = self.port_get_trunk_vlan_list(port)
Steve McIntyrecc297112014-08-11 18:46:58 +0100269 for vlan in read_vlans:
270 if vlan == tag:
271 return
Steve McIntyre5b3ce212014-08-15 13:10:41 +0100272 raise IOError("Failed to add trunk port %s to VLAN %d" % (port, tag))
Steve McIntyrecc297112014-08-11 18:46:58 +0100273
274 # Remove a trunk port from a specified VLAN (tag)
Steve McIntyre9b09b9d2014-09-24 15:08:10 +0100275 def port_remove_trunk_from_vlan(self, port, tag):
Steve McIntyrecc297112014-08-11 18:46:58 +0100276 logging.debug("Removing trunk port %s from VLAN %d" % (port, tag))
277 if not self._is_port_name_valid(port):
Steve McIntyre72a8bce2015-01-23 18:02:19 +0000278 raise InputError("Port name %s not recognised" % port)
Steve McIntyre9b09b9d2014-09-24 15:08:10 +0100279 if not (self.port_get_mode(port) == "trunk"):
Steve McIntyre72a8bce2015-01-23 18:02:19 +0000280 raise InputError("Port %s not in trunk mode" % port)
Steve McIntyrecc297112014-08-11 18:46:58 +0100281 self._configure()
282 self._cli("interface %s" % port)
283 self._cli("switchport trunk allowed vlan remove %d" % tag)
284 self._end_configure()
285
286 # Validate it happened
Steve McIntyre9b09b9d2014-09-24 15:08:10 +0100287 read_vlans = self.port_get_trunk_vlan_list(port)
Steve McIntyrecc297112014-08-11 18:46:58 +0100288 for vlan in read_vlans:
289 if vlan == tag:
Steve McIntyre5b3ce212014-08-15 13:10:41 +0100290 raise IOError("Failed to remove trunk port %s from VLAN %d" % (port, tag))
Steve McIntyrecc297112014-08-11 18:46:58 +0100291
Steve McIntyre9936d002014-10-01 15:54:10 +0100292 # Get the configured VLAN tag for an access port (tag)
293 def port_get_access_vlan(self, port):
294 logging.debug("Getting VLAN for access port %s" % port)
Steve McIntyrecc297112014-08-11 18:46:58 +0100295 vlan = 1
296 if not self._is_port_name_valid(port):
Steve McIntyre72a8bce2015-01-23 18:02:19 +0000297 raise InputError("Port name %s not recognised" % port)
Steve McIntyre9936d002014-10-01 15:54:10 +0100298 if not (self.port_get_mode(port) == "access"):
Steve McIntyre72a8bce2015-01-23 18:02:19 +0000299 raise InputError("Port %s not in access mode" % port)
Steve McIntyre0f893602014-12-24 02:14:53 +0000300 regex = re.compile('(\d+)\s+\S+\s+Untagged\s+(Static|System)')
Steve McIntyrecc297112014-08-11 18:46:58 +0100301 self._cli("show interfaces switchport %s" % port)
Steve McIntyrec68d6d72014-12-24 00:23:36 +0000302 for line in self._read_long_output():
Steve McIntyrecc297112014-08-11 18:46:58 +0100303 match = regex.match(line)
304 if match:
305 vlan = match.group(1)
306 return int(vlan)
307
308 # Get the list of configured VLAN tags for a trunk port
Steve McIntyre9b09b9d2014-09-24 15:08:10 +0100309 def port_get_trunk_vlan_list(self, port):
Steve McIntyrecc297112014-08-11 18:46:58 +0100310 logging.debug("Getting VLANs for trunk port %s" % port)
311 vlans = [ ]
312 if not self._is_port_name_valid(port):
Steve McIntyre72a8bce2015-01-23 18:02:19 +0000313 raise InputError("Port name %s not recognised" % port)
Steve McIntyre9b09b9d2014-09-24 15:08:10 +0100314 if not (self.port_get_mode(port) == "trunk"):
Steve McIntyre72a8bce2015-01-23 18:02:19 +0000315 raise InputError("Port %s not in trunk mode" % port)
Steve McIntyrecc297112014-08-11 18:46:58 +0100316 regex = re.compile('(\d+)\s+\S+\s+(Tagged|Untagged)\s+Static')
317 self._cli("show interfaces switchport %s" % port)
Steve McIntyrec68d6d72014-12-24 00:23:36 +0000318 for line in self._read_long_output():
Steve McIntyrecc297112014-08-11 18:46:58 +0100319 match = regex.match(line)
320 if match:
321 vlans.append (int(match.group(1)))
322 return vlans
323
324 ################################
325 ### Internal functions
326 ################################
327
328 def _login(self, username, password):
329 logging.debug("attempting login with username %s, password %s" % (username, password))
330 self._cli("")
331 self.connection.expect("User Name:")
332 self._cli("%s" % username)
333 self.connection.expect("Password:")
334 self._cli("%s" % password, False)
Steve McIntyreca6c5a32014-12-23 15:34:29 +0000335 self.connection.expect("\*\*")
Steve McIntyrecc297112014-08-11 18:46:58 +0100336 while True:
Steve McIntyreca6c5a32014-12-23 15:34:29 +0000337 index = self.connection.expect(['User Name:', 'authentication failed', r'(.*)#', 'Password:', '.+'])
Steve McIntyrecc297112014-08-11 18:46:58 +0100338 if index == 0 or index == 1: # Failed to log in!
339 logging.error("Login failure: %s\n" % self.connection.match)
340 raise IOError
341 elif index == 2:
Steve McIntyre366046f2014-08-18 18:57:03 +0100342 self._prompt_name = self.connection.match.group(1).strip()
Steve McIntyreca6c5a32014-12-23 15:34:29 +0000343 logging.debug("Got prompt name %s" % self._prompt_name)
Steve McIntyrecc297112014-08-11 18:46:58 +0100344 return 0
Steve McIntyreca6c5a32014-12-23 15:34:29 +0000345 elif index == 3 or index == 4:
346 self._cli("", False)
Steve McIntyrecc297112014-08-11 18:46:58 +0100347
348 def _logout(self):
349 logging.debug("Logging out")
350 self._cli("exit", False)
351
Steve McIntyrecc297112014-08-11 18:46:58 +0100352 def _configure(self):
353 self._cli("configure terminal")
354
355 def _end_configure(self):
356 self._cli("end")
357
Steve McIntyrec68d6d72014-12-24 00:23:36 +0000358 def _read_long_output(self):
Steve McIntyre366046f2014-08-18 18:57:03 +0100359 prompt = self._prompt_name + '#'
Steve McIntyrec68d6d72014-12-24 00:23:36 +0000360 self.connection.expect(prompt)
Steve McIntyrea7cdefc2014-12-24 00:48:19 +0000361 buf = []
362 for line in self.connection.before.split('\r\n'):
363 buf.append(line.strip())
364 return buf
Steve McIntyrecc297112014-08-11 18:46:58 +0100365
366 def _get_port_names(self):
367 logging.debug("Grabbing list of ports")
368 interfaces = []
369
370 # Use "Up" or "Down" to only identify lines in the output that
371 # match interfaces that exist
372 regex = re.compile('^(\w+).*(Up|Down)')
373
374 self._cli("show interfaces status detailed")
Steve McIntyrec68d6d72014-12-24 00:23:36 +0000375 for line in self._read_long_output():
Steve McIntyrecc297112014-08-11 18:46:58 +0100376 match = regex.match(line)
377 if match:
378 interfaces.append(match.group(1))
379 return interfaces
380
Steve McIntyrecc297112014-08-11 18:46:58 +0100381 def _show_config(self):
382 logging.debug("Grabbing config")
383 self._cli("show running-config")
Steve McIntyrec68d6d72014-12-24 00:23:36 +0000384 return self._read_long_output()
Steve McIntyrecc297112014-08-11 18:46:58 +0100385
386 def _show_clock(self):
387 logging.debug("Grabbing time")
388 self._cli("show clock")
Steve McIntyrec68d6d72014-12-24 00:23:36 +0000389 return self._read_long_output()
Steve McIntyrecc297112014-08-11 18:46:58 +0100390
Steve McIntyrecc297112014-08-11 18:46:58 +0100391 def _get_systemdata(self):
Steve McIntyrecc297112014-08-11 18:46:58 +0100392
Steve McIntyreffb9b5a2014-10-10 16:31:58 +0100393 self._systemdata = []
394
Steve McIntyre28d34ca2014-08-12 15:40:24 +0100395 logging.debug("Grabbing system data")
Steve McIntyrecc297112014-08-11 18:46:58 +0100396 self._cli("show system")
Steve McIntyrec68d6d72014-12-24 00:23:36 +0000397 for line in self._read_long_output():
Steve McIntyre366046f2014-08-18 18:57:03 +0100398 self._systemdata.append(line)
Steve McIntyre28d34ca2014-08-12 15:40:24 +0100399
400 logging.debug("Grabbing system sw and hw versions")
401 self._cli("show version")
Steve McIntyrec68d6d72014-12-24 00:23:36 +0000402 for line in self._read_long_output():
Steve McIntyre366046f2014-08-18 18:57:03 +0100403 self._systemdata.append(line)
Steve McIntyrecc297112014-08-11 18:46:58 +0100404
Steve McIntyre16f02162014-08-14 17:47:36 +0100405 ######################################
406 # Internal port access helper methods
407 ######################################
408 # N.B. No parameter checking here, for speed reasons - if you're
409 # calling this internal API then you should already have validated
410 # things yourself! Equally, no post-set checks in here - do that
411 # at the higher level.
412 ######################################
413
Steve McIntyrecc297112014-08-11 18:46:58 +0100414 # Wrapper around connection.send - by default, expect() the same
415 # text we've sent, to remove it from the output from the
416 # switch. For the few cases where we don't need that, override
417 # this using echo=False.
418 # Horrible, but seems to work.
419 def _cli(self, text, echo=True):
420 self.connection.send(text + '\r')
421 if echo:
422 self.connection.expect(text)
423
424if __name__ == "__main__":
Steve McIntyref1699322014-08-19 22:49:43 +0100425# p = CiscoSX300('10.172.2.52', 23)
Steve McIntyre48dc6ae2014-12-23 16:08:19 +0000426
427 import optparse
428
429 switch = 'vlandswitch02'
430 parser = optparse.OptionParser()
431 parser.add_option("--switch",
432 dest = "switch",
433 action = "store",
434 nargs = 1,
435 type = "string",
436 help = "specify switch to connect to for testing",
437 metavar = "<switch>")
438 (opts, args) = parser.parse_args()
439 if opts.switch:
440 switch = opts.switch
441
442 p = CiscoSX300(switch, 23, debug = True)
Steve McIntyreaea995c2014-12-22 17:17:38 +0000443 p.switch_connect('cisco', 'cisco', None)
Steve McIntyrecc297112014-08-11 18:46:58 +0100444 #buf = p._show_clock()
445 #print "%s" % buf
446 #buf = p._show_config()
447 #p._dump_list(buf)
448
Steve McIntyre366046f2014-08-18 18:57:03 +0100449 print "System data:"
450 p._dump_list(p._systemdata)
Steve McIntyrecc297112014-08-11 18:46:58 +0100451
452 print "Creating VLANs for testing:"
453 for i in [ 2, 3, 4, 5, 20 ]:
Steve McIntyre9b09b9d2014-09-24 15:08:10 +0100454 p.vlan_create(i)
455 p.vlan_set_name(i, "test%d" % i)
Steve McIntyrecc297112014-08-11 18:46:58 +0100456 print " %d (test%d)" % (i, i)
457
458 #print "And dump config\n"
459 #buf = p._show_config()
460 #print "%s" % buf
461
462 #print "Destroying VLAN 2\n"
Steve McIntyre9b09b9d2014-09-24 15:08:10 +0100463 #p.vlan_destroy(2)
Steve McIntyrecc297112014-08-11 18:46:58 +0100464
465 #print "And dump config\n"
466 #buf = p._show_config()
467 #print "%s" % buf
468
469 #print "Port names are:"
Steve McIntyre9b09b9d2014-09-24 15:08:10 +0100470 #buf = p.switch_get_port_names()
Steve McIntyrecc297112014-08-11 18:46:58 +0100471 #p._dump_list(buf)
472
Steve McIntyre9b09b9d2014-09-24 15:08:10 +0100473 #buf = p.vlan_get_name(25)
Steve McIntyrecc297112014-08-11 18:46:58 +0100474 #print "VLAN with tag 25 is called \"%s\"" % buf
475
Steve McIntyre9b09b9d2014-09-24 15:08:10 +0100476 #p.vlan_set_name(35, "foo")
Steve McIntyrecc297112014-08-11 18:46:58 +0100477 #print "VLAN with tag 35 is called \"foo\""
478
Steve McIntyre9b09b9d2014-09-24 15:08:10 +0100479 #buf = p.port_get_mode("fa12")
Steve McIntyrecc297112014-08-11 18:46:58 +0100480 #print "Port fa12 is in %s mode" % buf
481
Steve McIntyre9936d002014-10-01 15:54:10 +0100482 # Test access stuff
483 print "Set fa6 to access mode"
484 p.port_set_mode("fa6", "access")
Steve McIntyre16f02162014-08-14 17:47:36 +0100485 print "Move fa6 to VLAN 2"
Steve McIntyre9936d002014-10-01 15:54:10 +0100486 p.port_set_access_vlan("fa6", 2)
487 buf = p.port_get_access_vlan("fa6")
Steve McIntyrecc297112014-08-11 18:46:58 +0100488 print "Read from switch: fa6 is on VLAN %s" % buf
Steve McIntyre16f02162014-08-14 17:47:36 +0100489 print "Move fa6 back to default VLAN 1"
Steve McIntyre9936d002014-10-01 15:54:10 +0100490 p.port_set_access_vlan("fa6", 1)
Steve McIntyrecc297112014-08-11 18:46:58 +0100491 #print "And move fa6 back to a trunk port"
Steve McIntyre9b09b9d2014-09-24 15:08:10 +0100492 #p.port_set_mode("fa6", "trunk")
493 #buf = p.port_get_mode("fa6")
Steve McIntyrecc297112014-08-11 18:46:58 +0100494 #print "Port fa6 is in %s mode" % buf
495
496 # Test trunk stuff
497 print "Set gi2 to trunk mode"
Steve McIntyre9b09b9d2014-09-24 15:08:10 +0100498 p.port_set_mode("gi2", "trunk")
Steve McIntyrecc297112014-08-11 18:46:58 +0100499 print "Add gi2 to VLAN 2"
Steve McIntyre9b09b9d2014-09-24 15:08:10 +0100500 p.port_add_trunk_to_vlan("gi2", 2)
Steve McIntyrecc297112014-08-11 18:46:58 +0100501 print "Add gi2 to VLAN 3"
Steve McIntyre9b09b9d2014-09-24 15:08:10 +0100502 p.port_add_trunk_to_vlan("gi2", 3)
Steve McIntyrecc297112014-08-11 18:46:58 +0100503 print "Add gi2 to VLAN 4"
Steve McIntyre9b09b9d2014-09-24 15:08:10 +0100504 p.port_add_trunk_to_vlan("gi2", 4)
Steve McIntyrecc297112014-08-11 18:46:58 +0100505 print "Read from switch: which VLANs is gi2 on?"
Steve McIntyre9b09b9d2014-09-24 15:08:10 +0100506 buf = p.port_get_trunk_vlan_list("gi2")
Steve McIntyrecc297112014-08-11 18:46:58 +0100507 p._dump_list(buf)
508
Steve McIntyre366046f2014-08-18 18:57:03 +0100509 print "Remove gi2 from VLANs 3,3,4"
Steve McIntyre9b09b9d2014-09-24 15:08:10 +0100510 p.port_remove_trunk_from_vlan("gi2", 3)
511 p.port_remove_trunk_from_vlan("gi2", 3)
512 p.port_remove_trunk_from_vlan("gi2", 4)
Steve McIntyrecc297112014-08-11 18:46:58 +0100513 print "Read from switch: which VLANs is gi2 on?"
Steve McIntyre9b09b9d2014-09-24 15:08:10 +0100514 buf = p.port_get_trunk_vlan_list("gi2")
Steve McIntyrecc297112014-08-11 18:46:58 +0100515 p._dump_list(buf)
516
517 # print "Adding lots of ports to VLANs"
Steve McIntyre9b09b9d2014-09-24 15:08:10 +0100518 # p.port_add_trunk_to_vlan("fa1", 2)
519 # p.port_add_trunk_to_vlan("fa3", 2)
520 # p.port_add_trunk_to_vlan("fa5", 2)
521 # p.port_add_trunk_to_vlan("fa7", 2)
522 # p.port_add_trunk_to_vlan("fa9", 2)
523 # p.port_add_trunk_to_vlan("fa11", 2)
524 # p.port_add_trunk_to_vlan("fa13", 2)
525 # p.port_add_trunk_to_vlan("fa15", 2)
526 # p.port_add_trunk_to_vlan("fa17", 2)
527 # p.port_add_trunk_to_vlan("fa19", 2)
528 # p.port_add_trunk_to_vlan("fa21", 2)
529 # p.port_add_trunk_to_vlan("fa23", 2)
530 # p.port_add_trunk_to_vlan("gi4", 2)
Steve McIntyrecc297112014-08-11 18:46:58 +0100531
532 print "VLANs are:"
Steve McIntyre9b09b9d2014-09-24 15:08:10 +0100533 buf = p.vlan_get_list()
Steve McIntyrecc297112014-08-11 18:46:58 +0100534 p._dump_list(buf)
535
Steve McIntyre7460d972014-12-23 14:45:30 +0000536# print 'Restarting switch, to explicitly reset config'
537# p.switch_restart()
Steve McIntyrecc297112014-08-11 18:46:58 +0100538
Steve McIntyrebf5dc882014-12-19 17:54:58 +0000539# p.switch_save_running_config()
Steve McIntyrecc297112014-08-11 18:46:58 +0100540# p._show_config()
541