blob: a66c4d4d7b3663f2d0b41077da3075df4d385880 [file] [log] [blame]
#! /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