277 lines
11 KiB
Python
277 lines
11 KiB
Python
# Licensed to the Apache Software Foundation (ASF) under one
|
|
# or more contributor license agreements. See the NOTICE file
|
|
# distributed with this work for additional information
|
|
# regarding copyright ownership. The ASF licenses this file
|
|
# to you under the Apache License, Version 2.0 (the
|
|
# "License"); you may not use this file except in compliance
|
|
# with the License. You may obtain a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing,
|
|
# software distributed under the License is distributed on an
|
|
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
# KIND, either express or implied. See the License for the
|
|
# specific language governing permissions and limitations
|
|
# under the License.
|
|
#
|
|
# $Id$
|
|
#
|
|
# What HP switches is this for? The configuration syntax does not
|
|
# not appear like it would work for Procurves. - stroucki 20100224
|
|
|
|
import os
|
|
import sys
|
|
import pexpect
|
|
import datetime
|
|
import thread
|
|
import time
|
|
import threading
|
|
|
|
|
|
from hwswitchinterface import HwSwitchInterface
|
|
from resourcequerysql import ResourceQuerySql
|
|
from util import logit
|
|
|
|
|
|
''' Using pexpect to control switches because couldn't get snmp to work
|
|
'''
|
|
|
|
class HwHPSwitch(HwSwitchInterface):
|
|
def __init__(self, config, host=None):
|
|
self.host = host
|
|
self.verbose = False
|
|
self.logFile = config['logFile']
|
|
|
|
|
|
def setVerbose(self, verbose):
|
|
self.verbose = verbose
|
|
|
|
def __login(self):
|
|
|
|
switchIp = "telnet " + self.host['hw_name']
|
|
child = pexpect.spawn(switchIp)
|
|
opt = child.expect(['Name:', 'password:', pexpect.EOF, pexpect.TIMEOUT])
|
|
#XXX Doesn't seem to do what I want:(
|
|
child.setecho(False)
|
|
if opt == 0:
|
|
child.sendline(self.host['hw_userid'])
|
|
|
|
# Be Verbose and print everything
|
|
if self.verbose:
|
|
child.logfile = sys.stdout
|
|
|
|
child.sendline(self.host['hw_password'])
|
|
i=child.expect(['Main#', pexpect.EOF, pexpect.TIMEOUT])
|
|
if i == 2:
|
|
mesg = "ERROR: Login failed\n"
|
|
logit(self.logFile, mesg)
|
|
|
|
sys.stderr.write()
|
|
exit(1)
|
|
return child
|
|
|
|
def __getPrsLabel(self):
|
|
dadate = datetime.datetime.now().strftime("%Y%m%d-%H%M-%S")
|
|
return "ZONI_" + dadate
|
|
|
|
def __saveConfig(self, child):
|
|
#child.logfile = sys.stdout
|
|
cmd = "save"
|
|
child.sendline(cmd)
|
|
opt = child.expect(["Confirm(.*)", "No save(.*)", pexpect.EOF, pexpect.TIMEOUT])
|
|
if opt == 0:
|
|
print "saving to flash"
|
|
child.sendline("y\n")
|
|
if opt == 1:
|
|
print "no save needed"
|
|
child.sendline('exit')
|
|
child.terminate()
|
|
|
|
def enableHostPort(self):
|
|
child = self.__login()
|
|
cmd = "/cfg/port " + str(self.host['hw_port']) + " /ena/apply "
|
|
child.sendline(cmd)
|
|
# testing this thread... Looks like this works ...
|
|
threading.Thread(target=self.__saveConfig(child)).start()
|
|
|
|
def disableHostPort(self):
|
|
child = self.__login()
|
|
cmd = "/cfg/port " + str(self.host['hw_port']) + " /dis/apply "
|
|
child.sendline(cmd)
|
|
threading.Thread(target=self.__saveConfig(child)).start()
|
|
|
|
def removeVlan(self, num):
|
|
print "removing vlan"
|
|
# Check for important vlans
|
|
child = self.__login()
|
|
|
|
cmd = "/cfg / l2 / vlan " + num + " / del / apply"
|
|
child.sendline(cmd)
|
|
opt = child.expect(["Confirm(.*)", pexpect.EOF, pexpect.TIMEOUT])
|
|
if opt == 0:
|
|
child.sendline("y\n")
|
|
threading.Thread(target=self.__saveConfig(child)).start()
|
|
|
|
|
|
def addVlanToTrunk(self, vlan):
|
|
print "NOT IMPLEMENTED"
|
|
print "No trunks to test @ MIMOS"
|
|
|
|
def createVlansThread(self, vlan, switch,host):
|
|
mesg = "Creating vlan " + str(vlan) + " on switch " + str(switch)
|
|
print "host is ", host
|
|
logit(self.logFile, mesg)
|
|
print "create"
|
|
self.createVlan(vlan)
|
|
print "cend"
|
|
self.addVlanToTrunk(vlan);
|
|
thread.exit()
|
|
|
|
def createVlans(self, vlan, switchlist, query):
|
|
for switch in switchlist:
|
|
#print "working on switch ", switch
|
|
#self.host = query.getSwitchInfo(switch)
|
|
#thread.start_new_thread(self.createVlansThread, (vlan, switch, self.host))
|
|
mesg = "Creating vlan " + str(vlan) + " on switch " + str(switch)
|
|
logit(self.logFile, mesg)
|
|
self.host = query.getSwitchInfo(switch)
|
|
self.createVlan(vlan)
|
|
self.addVlanToTrunk(vlan);
|
|
|
|
def removeVlans(self, vlan, switchlist, query):
|
|
for switch in switchlist:
|
|
mesg = "Deleting vlan " + str(vlan) + " on switch " + str(switch)
|
|
logit(self.logFile, mesg)
|
|
self.host = query.getSwitchInfo(switch)
|
|
self.removeVlan(vlan)
|
|
|
|
def createVlan(self, val):
|
|
|
|
vlanname = False
|
|
if ":" in val:
|
|
num = int(val.split(":")[0])
|
|
vlanname = val.split(":")[1]
|
|
else:
|
|
vlanname = self.__getPrsLabel()
|
|
num = int(val)
|
|
|
|
#if type(num) != int:
|
|
#mesg = "ERROR: Vlan must be a number (0-4095)\n"
|
|
#sys.stderr.write(mesg)
|
|
#exit(1)
|
|
if num > 4095 or num < 0:
|
|
mesg = "ERROR: Vlan out of range. Must be < 4095"
|
|
logit(self.logFile, mesg)
|
|
exit(1)
|
|
|
|
child = self.__login()
|
|
cmd = "/cfg / l2 / vlan " + str(num) + " / ena/ apply"
|
|
child.sendline(cmd)
|
|
cmd = "name " + str(vlanname) + " / apply"
|
|
child.sendline(cmd)
|
|
threading.Thread(target=self.__saveConfig(child)).start()
|
|
|
|
|
|
# Raw Switch commands. DEBUG ONLY!, Doesn't work!
|
|
def sendSwitchCommand(self, cmds):
|
|
if len(cmds) > 0:
|
|
child = self.__login()
|
|
child.logfile = sys.stdout
|
|
for cmd in cmds.split(";"):
|
|
child.sendline(cmd)
|
|
try:
|
|
i=child.expect(['console','sw', 'Name:', pexpect.EOF, pexpect.TIMEOUT], timeout=2)
|
|
i=child.expect(['console','sw', 'Name:', pexpect.EOF, pexpect.TIMEOUT], timeout=2)
|
|
|
|
except EOF:
|
|
print "EOF", i
|
|
#child.sendline()
|
|
except TIMEOUT:
|
|
print "TIMEOUT", i
|
|
#child.interact(escape_character='\x1d', input_filter=None, output_filter=None)
|
|
|
|
child.terminate()
|
|
#print "before", child.before
|
|
#print "after", child.after
|
|
|
|
def addNodeToVlan(self, vlan):
|
|
child = self.__login()
|
|
cmd = "/cfg/l2/vlan " + str(vlan) + " /add " + str(self.host['hw_port']) + " /apply "
|
|
child.sendline(cmd)
|
|
opt = child.expect(['(.*)#','(.*)needs to be enabled', pexpect.EOF, pexpect.TIMEOUT], timeout=2)
|
|
if opt == 1:
|
|
print "VLAN Created, Enabling..." + str(vlan)
|
|
cmd = "/cfg/l2/vlan " + str(vlan) + " /ena/apply "
|
|
child.sendline(cmd)
|
|
|
|
threading.Thread(target=self.__saveConfig(child)).start()
|
|
|
|
|
|
def removeNodeFromVlan(self, vlan):
|
|
child = self.__login()
|
|
cmd = "/cfg/l2/vlan " + str(vlan) + " /rem " + str(self.host['hw_port']) + "/apply"
|
|
child.sendline(cmd)
|
|
threading.Thread(target=self.__saveConfig(child)).start()
|
|
|
|
def setNativeVlan(self, vlan):
|
|
child = self.__login()
|
|
#child.logfile = sys.stdout
|
|
cmd = "/cfg/port " + str(self.host['hw_port']) + "/pvid " + str(vlan) + "/apply"
|
|
child.sendline(cmd)
|
|
threading.Thread(target=self.__saveConfig(child)).start()
|
|
|
|
# HP switches allow more free control. Example, if you set a port to a native vlan
|
|
# that doesn't exist, HP switches will happily create for you.
|
|
# However, if you delete a vlan that exists on many ports, it will still happily delete
|
|
# the vlan, forcing all the other ports to default to some other native vlan. Need
|
|
# to make sure we check before blasting vlans.
|
|
|
|
# Restore Native Vlan.
|
|
def restoreNativeVlan(self):
|
|
child = self.__login()
|
|
cmd = "/cfg/port " + str(self.host['hw_port']) + "/pvid 1/apply"
|
|
child.sendline(cmd)
|
|
threading.Thread(target=self.__saveConfig(child)).start()
|
|
|
|
# Setup the switch for node allocation
|
|
def allocateNode(self):
|
|
pass
|
|
|
|
# Remove all vlans from the interface
|
|
def removeAllVlans(self):
|
|
child = self.__login()
|
|
cmd = "/cfg/port " + str(self.host['hw_port']) + "/tag d/apply"
|
|
#child.logfile = sys.stdout
|
|
child.sendline(cmd)
|
|
|
|
def showInterfaceConfig(self):
|
|
print "\n---------------" + self.host['hw_make'] + "---------------------"
|
|
print "SWITCH - " + self.host['hw_name'] + "/" + str(self.host['hw_port'])
|
|
print "NODE - " + self.host['location']
|
|
print "------------------------------------\n"
|
|
# using run and parsing output. Still have issues an "rt" after the command. Fix later
|
|
#val = pexpect.run("telnet sw0-r4r1e1", withexitstatus=False, timeout=2, events=({'(?i)password:': "admin\r\n", "Main#": "info\r\n", "Info(.*)" : "port\r\n"})) #, "Info(.*)" : "exit\n"}))
|
|
# Just print everything for now, fix when back in the US
|
|
#print val
|
|
|
|
|
|
child = self.__login()
|
|
cmd = "/info/port " + str(self.host['hw_port'])
|
|
child.sendline(cmd)
|
|
child.logfile = sys.stdout
|
|
opt = child.expect(['Info(.*)', pexpect.EOF, pexpect.TIMEOUT])
|
|
|
|
# this needs to be removed or rewritten
|
|
def interactiveSwitchConfig(self):
|
|
switchIp = "telnet " + self.host['hw_name']
|
|
child = pexpect.spawn(switchIp)
|
|
child.setecho(False)
|
|
#child.expect('Name:')
|
|
#child.sendline(self.host['hw_userid'])
|
|
#i=child.expect(['test','password:','Password:', pexpect.EOF, pexpect.TIMEOUT])
|
|
#child.logfile = sys.stdout
|
|
child.sendline(self.host['hw_password'])
|
|
child.interact(escape_character='\x1d', input_filter=None, output_filter=None)
|
|
|
|
|