重构看的七七八八了,感觉应该练练手,自己打包一个SecureCRT的环境类。
SecureCRT提供的API很多时候用起来并不好用。
举个简单的例子,如果直接使用原生send函数,在发送多条命令时,如果设备比较卡,会看到多条命令已经发出去了(多条命令会同时显示出来),但回显却还没有显示完,而且原生send函数不包括得到回显的功能。
代码分为两个部分:
1. crt提供的所有API打包成类并放在一个单独的connectEnv.py文件下。
2. 主体逻辑放在一个script.py文件下。
这样做好处比较多:
1. 以后添加功能,只需要在connectEnv.py中添加,在script.py中调用即可。
2. 编写不同功能的脚本时,都可以调用connectEnv.py,而不需要每次都复制粘贴。
3. 更新connectEnv.py中的函数算法时,将会应用到所有调用该模块的脚本。
4. 如果以后不用crt了(可能xshell或者putty也支持脚本功能?),在script.py中只要修少量的几个地方就能将代码移植成功。
5. 符合高内聚,低耦合的原则。
script.py
# $language = "python"
# $interface = "1.0"
#--------------------------------------------------------------------------------------
import os
import sys
def getScriptPath():
return os.path.split(os.path.realpath(__file__))[0]
sys.path.append(getScriptPath())
import connectEnv
# 以上都是必须的
def main():
# 将crt的API传入connectEnv文件,这个是必须的
connectEnv.init(crt)
# 弹出一个测试MessageBox,用以测试crt的API是否传入成功(当然是成功的)
connectEnv.CrtEnv.messageBox("hello world", "test")
# 测试用。获取当前tab标签,并直接向设备发送命令,备份配置
device1 = connectEnv.CrtEnv()
# 发送命令
device1.send("terminal length 0")
# 设置log文件
device1.setLog("D:\\device1_log.txt")
# 开启log功能
device1.log(True)
# 发送命令并写入log文件
device1.send("show run")
# 关闭log功能
device1.log(False)
# 将show version信息的回显用MessageBox弹出(这里可以自行处理回显,比如提取个SN号)
connectEnv.CrtEnv.messageBox(device1.send("show version"), "version")
# 改变提示符的命令(一般这个命令是不许要回显什么的)
device1.changePrompt("conf t")
# 在全局配置模式下使用do show run 查看running-config信息
device1.send("do show run")
# 新登录一台设备
device2 = connectEnv.CrtEnv()
# 登录一个新的设备,参数为地址、用户名、密码(这里会自动检测是SSH还是telnet)
isLogin = device2.login("192.168.1.1","qw er","wqerqwer")
if not isLogin:
connectEnv.CrtEnv.messageBox("Login Failed", "Device")
# 这里表明是可以同时操作多个tab的。
# 你可以在tab1的设备中查询信息,然后把需要需要的信息提取出来,
# 放在tab2的命令中发送出去。(比如查询接入交换接口下的mac,然后在网关上查询arp得到mac的IP)
# 断开device1
device1.logout()
# 断开device2
if isLogin:
device2.logout()
main()
conncetEnv.py
global crt
def init(crtAPI):
global crt
crt = crtAPI
class CrtEnv():
@staticmethod
def promptBox(szMessage, szTitle):
return crt.Dialog.Prompt(szMessage, szTitle, "", True)
@staticmethod
def inputBox(szMessage, szTitle):
return crt.Dialog.Prompt(szMessage, szTitle, "", False)
@staticmethod
def messageBox(szMessage, szTitle):
crt.Dialog.MessageBox(szMessage, szTitle)
def __init__(self):
self.__oTab = None
self.__szPrompt = ""
self.__szInitPrompt = "#"
self.__szHostname = ""
def login(self, szHostname, szUsername, szPassword):
self.__szHostname = szHostname
if self.__ssh(szUsername,szPassword):
return True
if self.__telnet(szUsername,szPassword):
return True
return False
def logout(self):
self.__oTab.Session.Disconnect()
def send(self, szCMD):
self.__checkEnv()
self.__send(szCMD)
self.__oTab.Screen.WaitForString(szCMD)
return self.__getResult().encode('utf-8')
def changePrompt(self, szCMD):
self.__send(szCMD)
self.__oTab.Screen.WaitForString(szCMD, 1)
self.__oTab.Screen.WaitForString("Some String will not echo.", 1)
self.__updatePrompt()
def getTabName(self):
if self.__isTabEmpty():
self.__getCurrentTab()
return self.__oTab.Caption.encode('utf-8')
def getTab(self):
if self.__isTabEmpty():
self.__getCurrentTab()
return self.__oTab
def getPrompt(self):
return self.__szPrompt
def setPrompt(self, szPrompt):
self.__szPrompt = szPrompt
def setLog(self, szFileName):
self.__oTab.Session.LogFileName = szFileName
def log(self, isLog, isAppend = False):
self.__oTab.Session.Log(isLog, isAppend)
def getInitPrompt(self):
return self.__szInitPrompt
def setInitPrompt(self, szInitPrompt):
self.__szInitPrompt = szInitPrompt
def __ssh(self, szUsername, szPassword):
szConnectString = "/SSH2 /L \"%s\" /PASSWORD \"%s\" %s" % \
(szUsername, szPassword, self.__szHostname)
if self.__connect(szConnectString) == False:
return False
self.__oTab.Screen.Synchronous = True
self.__waitDeviceTabInit()
return True
def __telnet(self, szUsername, szPassword):
szConnectString = "/Telnet %s" % (self.__szHostname)
if self.__connect(szConnectString) == False:
return False
self.__oTab.Screen.Synchronous = True
self.__oTab.Screen.WaitForString("ame")
crt.Sleep(200)
self.__send(szUsername)
self.__oTab.Screen.WaitForString("assword")
crt.Sleep(200)
self.__send(szPassword)
self.__waitDeviceTabInit()
return True
def __connect(self, szConnectString):
try:
self.__oTab = crt.Session.ConnectInTab(szConnectString)
return True
except:
return False
def __waitDeviceTabInit(self):
crt.Sleep(300)
self.__oTab.Screen.WaitForString(self.getInitPrompt())
def __send(self, szCMD):
szCMD = szCMD + '\r'
self.__oTab.Screen.Send(szCMD)
def __checkEnv(self):
if self.__isTabEmpty():
self.__getCurrentTab()
self.__oTab.Screen.Synchronous = True
if self.__isPromptEmpty():
self.__updatePrompt()
def __isPromptEmpty(self):
if self.__szPrompt == "":
return True
return False
def __isTabEmpty(self):
if self.__oTab == None:
return True
return False
def __getCurrentTab(self):
self.__oTab = crt.GetActiveTab()
def __getResult(self):
return self.__oTab.Screen.ReadString(self.__szPrompt)
def __updatePrompt(self):
crt.Sleep(300)
rowIndex = self.__oTab.Screen.CurrentRow
colIndex = self.__oTab.Screen.CurrentColumn - 1
self.__szPrompt = self.__oTab.Screen.Get(rowIndex, 0, rowIndex, colIndex)
self.__szPrompt = self.__szPrompt.strip().encode('utf-8')
注意:要将这两个文件放在同一目录下,否则自行修改script.py中的sys.path.append(getScriptPath())代码。
注意:SecureCRT直接调用script.py即可