aboutsummaryrefslogtreecommitdiff
path: root/Vland/drivers/common.py
diff options
context:
space:
mode:
Diffstat (limited to 'Vland/drivers/common.py')
-rw-r--r--Vland/drivers/common.py167
1 files changed, 167 insertions, 0 deletions
diff --git a/Vland/drivers/common.py b/Vland/drivers/common.py
new file mode 100644
index 0000000..e564c9e
--- /dev/null
+++ b/Vland/drivers/common.py
@@ -0,0 +1,167 @@
+#! /usr/bin/python
+
+# Copyright 2014-2015 Linaro Limited
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+# MA 02110-1301, USA.
+
+import time
+import logging
+
+from errors import InputError, PExpectError
+
+class SwitchErrors:
+ """ Error logging and statistics class """
+
+ def __init__(self):
+ self.errors_in = 0
+ self.errors_out = 0
+
+ def __repr__(self):
+ return "<SwitchErrors: errors_in: %d, errors_out: %d>" % (self.errors_in, self.errors_out)
+
+ # For now, just count the error. Later on we might add stats and
+ # analysis
+ def log_error_in(self, text):
+ self.errors_in += 1
+
+ # For now, just count the error. Later on we might add stats and
+ # analysis
+ def log_error_out(self, text):
+ self.errors_out += 1
+
+class SwitchDriver(object):
+
+ connection = None
+ hostname = ""
+ serial_number = ''
+
+ _allowed_port_modes = [ "trunk", "access" ]
+ _ports = []
+ _port_modes = {}
+ _port_numbers = {}
+ _prompt_name = ''
+ _username = ''
+ _password = ''
+ _enable_password = ''
+ _systemdata = []
+
+ def __init__ (self, switch_hostname, debug):
+
+ if debug:
+ # Configure logging for pexpect output if we have debug
+ # enabled
+
+ # get the logger
+ self.logger = logging.getLogger(switch_hostname)
+
+ # give the logger the methods required by pexpect
+ self.logger.write = self._log_write
+ self.logger.flush = self._log_do_nothing
+
+ else:
+ self.logger = None
+
+ self.hostname = switch_hostname
+
+ # Connect to the switch and log in
+ def switch_connect(self, username, password, enablepassword):
+ self._username = username
+ self._password = password
+ self._enable_password = enablepassword
+ self._switch_connect()
+
+ # Log out of the switch and drop the connection and all state
+ def switch_disconnect(self):
+ self._logout()
+ logging.debug("Closing connection to %s", self.hostname)
+ self._ports = []
+ self._port_modes.clear()
+ self._port_numbers.clear()
+ self._prompt_name = ''
+ self._systemdata = []
+ del(self)
+
+ def dump_list(self, data):
+ i = 0
+ for line in data:
+ print "%d: \"%s\"" % (i, line)
+ i += 1
+
+ def _delay(self):
+ time.sleep(0.5)
+
+ # List the capabilities of the switch (and driver) - some things
+ # make no sense to abstract. Returns a dict of strings, each one
+ # describing an extra feature that that higher levels may care
+ # about
+ def switch_get_capabilities(self):
+ return self._capabilities
+
+ # List the names of all the ports on the switch
+ def switch_get_port_names(self):
+ return self._ports
+
+ def _is_port_name_valid(self, name):
+ for port in self._ports:
+ if name == port:
+ return True
+ return False
+
+ def _is_port_mode_valid(self, mode):
+ for allowed in self._allowed_port_modes:
+ if allowed == mode:
+ return True
+ return False
+
+ # Try to look up a port mode in our cache. If not there, go ask
+ # the switch and cache the result
+ def port_get_mode(self, port):
+ if not self._is_port_name_valid(port):
+ raise InputError("Port name %s not recognised" % port)
+ if port in self._port_modes:
+ logging.debug("port_get_mode: returning mode %s from cache for port %s", self._port_modes[port], port)
+ return self._port_modes[port]
+ else:
+ mode = self._port_get_mode(port)
+ self._port_modes[port] = mode
+ logging.debug("port_get_mode: found mode %s for port %s, adding to cache", self._port_modes[port], port)
+ return mode
+
+ def port_map_name_to_number(self, port_name):
+ if not self._is_port_name_valid(port_name):
+ raise InputError("Port name %s not recognised" % port_name)
+ logging.debug("port_map_name_to_number: returning %d for port_name %s", self._port_numbers[port_name], port_name)
+ return self._port_numbers[port_name]
+
+ # Wrappers to adapt logging for pexpect when we've configured on a
+ # switch.
+ # This will be the method called by the pexpect object to write a
+ # log message
+ def _log_write(self, *args, **kwargs):
+ # ignore other parameters, pexpect only uses one arg
+ content = args[0]
+
+ if content in [' ', '', '\n', '\r', '\r\n']:
+ return # don't log empty lines
+
+ # Split the output into multiple lines so we get a
+ # well-formatted logfile
+ for line in content.split('\r\n'):
+ logging.info(line)
+
+ # This is the flush method for pexpect
+ def _log_do_nothing(self):
+ pass