blob: 95e04d4073abaec4f9fe87bf0c75c6581715a3e0 [file] [log] [blame]
Steve McIntyre30bf4db2014-08-12 18:08:22 +01001#! /usr/bin/python
2
3# Copyright 2014 Linaro Limited
Steve McIntyre6103e982014-09-18 23:37:54 +01004
Steve McIntyre30bf4db2014-08-12 18:08:22 +01005#
6# This program is free software; you can redistribute it and/or modify
7# it under the terms of the GNU General Public License as published by
8# the Free Software Foundation; either version 2 of the License, or
9# (at your option) any later version.
10#
11# This program is distributed in the hope that it will be useful,
12# but WITHOUT ANY WARRANTY; without even the implied warranty of
13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14# GNU General Public License for more details.
15#
16# You should have received a copy of the GNU General Public License
17# along with this program; if not, write to the Free Software
18# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19# MA 02110-1301, USA.
20
21import time
22import logging
23
Steve McIntyre96f2c652015-02-12 04:25:55 +000024class SwitchErrors:
25 """ Error logging and statistics class """
26
27 def __init__(self):
28 self.errors_in = 0
29 self.errors_out = 0
30
31 def __repr__(self):
Steve McIntyrea67473a2015-02-12 08:26:33 +000032 return "<SwitchErrors: errors_in: %d, errors_out: %d>" % (self.errors_in, self.errors_out)
Steve McIntyre96f2c652015-02-12 04:25:55 +000033
34 # For now, just count the error. Later on we might add stats and
35 # analysis
36 def log_error_in(self, text):
37 self.errors_in += 1
38
39 # For now, just count the error. Later on we might add stats and
40 # analysis
41 def log_error_out(self, text):
42 self.errors_out += 1
43
Steve McIntyre30bf4db2014-08-12 18:08:22 +010044class SwitchDriver(object):
Steve McIntyre366046f2014-08-18 18:57:03 +010045
Steve McIntyre30bf4db2014-08-12 18:08:22 +010046 connection = None
47 hostname = ""
Steve McIntyre366046f2014-08-18 18:57:03 +010048 serial_number = ''
49
Steve McIntyre9936d002014-10-01 15:54:10 +010050 _allowed_port_modes = [ "trunk", "access" ]
Steve McIntyre366046f2014-08-18 18:57:03 +010051 _ports = []
Steve McIntyre1a7bad52015-07-20 15:21:42 +010052 _port_modes = {}
Steve McIntyre366046f2014-08-18 18:57:03 +010053 _prompt_name = ''
Steve McIntyre115350d2015-07-14 17:11:30 +010054 _username = ''
55 _password = ''
56 _enable_password = ''
57 _systemdata = []
Steve McIntyre30bf4db2014-08-12 18:08:22 +010058
Steve McIntyre2396f622015-07-14 15:35:03 +010059 def __init__ (self, switch_hostname, debug):
60
61 if debug:
62 # Configure logging for pexpect output if we have debug
63 # enabled
64
65 # get the logger
66 self.logger = logging.getLogger(switch_hostname)
67
68 # give the logger the methods required by pexpect
69 self.logger.write = self._log_write
70 self.logger.flush = self._log_do_nothing
71
72 else:
73 self.logger = None
74
Steve McIntyre37870ef2015-07-14 16:25:12 +010075 self.hostname = switch_hostname
76
77 # Connect to the switch and log in
78 def switch_connect(self, username, password, enablepassword):
79 self._username = username
80 self._password = password
81 self._enable_password = enablepassword
82 self._switch_connect()
83
84 # Log out of the switch and drop the connection and all state
85 def switch_disconnect(self):
86 self._logout()
87 logging.debug("Closing connection to %s", self.hostname)
88 self.connection.close(True)
89 self._ports = []
90 self._prompt_name = ''
91 self._systemdata = []
92 del(self)
93
Steve McIntyre5fa22652015-04-01 18:01:45 +010094 def dump_list(self, data):
Steve McIntyre30bf4db2014-08-12 18:08:22 +010095 i = 0
Steve McIntyre2b4c07b2014-12-22 16:10:04 +000096 for line in data:
Steve McIntyre30bf4db2014-08-12 18:08:22 +010097 print "%d: \"%s\"" % (i, line)
98 i += 1
99
100 def _delay(self):
101 time.sleep(0.5)
102
Steve McIntyre366046f2014-08-18 18:57:03 +0100103 # List the capabilities of the switch (and driver) - some things
104 # make no sense to abstract. Returns a dict of strings, each one
105 # describing an extra feature that that higher levels may care
106 # about
Steve McIntyre9b09b9d2014-09-24 15:08:10 +0100107 def switch_get_capabilities(self):
Steve McIntyre366046f2014-08-18 18:57:03 +0100108 return self._capabilities
109
110 # List the names of all the ports on the switch
Steve McIntyre9b09b9d2014-09-24 15:08:10 +0100111 def switch_get_port_names(self):
Steve McIntyre366046f2014-08-18 18:57:03 +0100112 return self._ports
113
114 def _is_port_name_valid(self, name):
Steve McIntyre366046f2014-08-18 18:57:03 +0100115 for port in self._ports:
116 if name == port:
117 return True
118 return False
119
120 def _is_port_mode_valid(self, mode):
Steve McIntyre366046f2014-08-18 18:57:03 +0100121 for allowed in self._allowed_port_modes:
122 if allowed == mode:
123 return True
124 return False
125
Steve McIntyre1a7bad52015-07-20 15:21:42 +0100126 # Try to look up a port mode in our cache. If not there, go ask
127 # the switch and cache the result
128 def port_get_mode(self, port):
129 if not self._is_port_name_valid(port):
130 raise InputError("Port name %s not recognised" % port)
131 if port in self._port_modes:
132 return self._port_modes[port]
133 else:
134 mode = self._port_get_mode(port)
135 self._port_modes[port] = mode
136 return mode
137
Steve McIntyre2396f622015-07-14 15:35:03 +0100138 # Wrappers to adapt logging for pexpect when we've configured on a
139 # switch.
140 # This will be the method called by the pexpect object to write a
141 # log message
142 def _log_write(self, *args, **kwargs):
143 # ignore other parameters, pexpect only uses one arg
144 content = args[0]
145
146 if content in [' ', '', '\n', '\r', '\r\n']:
147 return # don't log empty lines
148
149 # Split the output into multiple lines so we get a
150 # well-formatted logfile
151 for line in content.split('\r\n'):
152 logging.info(line)
153
154 # This is the flush method for pexpect
155 def _log_do_nothing(self):
156 pass
157