您现在的位置是: 网站首页 >Python Python
【telnetlib】使用Python登录Cisco交换机执行命令
admin2019年11月15日 11:35 【Python | Windows 】 1547人已围观
[telnetlib --- Telnet client](https://docs.python.org/zh-cn/3/library/telnetlib.html) 最近要对交换机端口进行控制,如果每次使用命令去操作确实挺麻烦的,就使用脚本一键实现,并有记录日志的功能。参考 https://blog.csdn.net/study_in/article/details/89338016 # Telnet对象 `Telnet.read_until(expected, timeout=None)` : #读取连接服务器后显示的内容,直到遇到同`expected`相同的字节串。或者等待时间大于`timeout`时直接向下运行。 `Telnet.read_very_eager()` : 读取从上次IO阻断到现在所有的内容,返回的是字节串,需要进行`decode()`编码。如果连接关闭或者没有可用数据时会抛出`EOFError`,如果没有其他可用的数据,返回的是`b""`,除非在IAC中间,否则不会阻碍。 `Telnet.open(host, port=23[, timeout])` : 连接到主机,端口号为第二个可选参数,默认为标准的Telnet端口(23),可选的`timeout`参数指定连接的超时时间,如果未指定,将使用全局默认超时设置。不要尝试去重新打开一个已经连接的实例对象。 `Telnet.close()` : 关闭连接。 `Telnet.write(buffer)` : # 将一个字节串(byte string)写进socket,如果连接被阻塞,这也会被阻塞,如果连接关闭,会抛出`OSError`。 `Telnet.interact()` : telnet的交互功能,下面用了一个死循环保证用户能够一直输入命令进行某些操作,也可以使用`Telnet.interact()`这个方法来使所连接终端持久化,不过官网说 (emulates a very dumb Telnet client)直译是一个非常愚蠢的客户端。 # 控制Cisco端口脚本 使用python实现对交换机端口关闭、打开功能。 ```python import telnetlib import time import datetime import logging def get_logger(filename='交换机端口管理日志.log'): """ 获取保存日志logger :param filename: 文件名,包含全绝对路径 :return: """ logger = logging.getLogger(__name__) logger.setLevel(level=logging.INFO) handler = logging.FileHandler(filename, encoding='utf-8') handler.setLevel(logging.INFO) formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') handler.setFormatter(formatter) logger.addHandler(handler) return logger logger = get_logger() class TelnetClient(object): def __init__(self, ip, user, pswd): self.tn = telnetlib.Telnet() self.host_ip = ip self.username = user self.password = pswd self.last_res = '' # 记录上次命令执行结果 # 此函数实现telnet登录主机 def login_host(self): try: # self.tn = telnetlib.Telnet(host_ip,port=23) self.tn.open(self.host_ip) except: text = '{} 网络连接失败'.format(self.host_ip) print(text) logger.info(text) return False # 等待login出现后输入用户名,最多等待10秒 self.tn.read_until(b'Username: ', timeout=10) self.tn.write(self.username.encode('ascii') + b'\n') # 等待Password出现后输入用户名,最多等待10秒 self.tn.read_until(b'Password: ', timeout=10) self.tn.write(self.password.encode('ascii') + b'\n') # 延时5秒再收取返回结果,给服务端足够响应时间 time.sleep(5) # 获取登录结果 # read_very_eager()获取到的是的是上次获取之后本次获取之前的所有输出 command_result = self.tn.read_very_eager().decode('utf-8') if 'Login invalid' in command_result: # Cisco交换登录失败提示语 text = '{} 登录失败,用户名或密码错误'.format(self.host_ip) print(text) logger.info(text) return False else: text = '{} 登录成功'.format(self.host_ip) print(text) logger.info(text) return True # 输入命令,并输出执行结果 def execute_some_command(self): # 执行命令 while True: command = input("请输入要执行的命令: ") if command == "exit" and 'config' not in self.last_res: print('不在配置模式下,退出登录') break self.tn.write(command.encode() + b'\n') time.sleep(1) # 获取命令结果 command_result = self.tn.read_very_eager().decode('utf-8') print('命令执行结果:%s' % command_result) self.last_res = command_result # 结果保存,用于下次输入exit判断是否退出登录 # 执行某一条命令 def execute_command(self, command, show_res=False): self.tn.write(command.encode() + b'\n') time.sleep(1) # 获取命令结果 command_result = self.tn.read_very_eager().decode('utf-8') if show_res: print('命令执行结果:%s' % command_result) return command_result # 退出telnet def logout_host(self): self.tn.write(b"exit\n") logger.info('本次操作结束,连接断开\n') def print_port_status(port, res): now_time = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S") text = '{}端口状态:'.format(port) if 'notconnect' in res: text += '无连接' elif 'connected' in res: text += '已连接' elif 'disabled' in res: text += '未启用' else: text += '端口状态为其他' print(text) logger.info(text) if __name__ == '__main__': # 指定连接的交换机管理IP ip = '192.168.96.140' # 查看指定端口状态 port1 = 'g1/0/10' port2 = 'g1/0/20' telnet_client = TelnetClient(ip=ip, user='admin', pswd='mypassword') # 如果登录结果返加True,则执行命令,然后退出 if telnet_client.login_host(): # 手动输入执行命令 # telnet_client.execute_some_command() # 执行指定命令 telnet_client.execute_command('en') # 进入特权模式 telnet_client.execute_command('mypassword') res1 = telnet_client.execute_command('show interfaces {} status'.format(port1)) print_port_status(port1, res1) res2 = telnet_client.execute_command('show interfaces {} status'.format(port2)) print_port_status(port2, res2) if 'disabled' in res1 or 'disabled' in res2: # 开启 telnet_client.execute_command('config t') telnet_client.execute_command('interface {}'.format(port1)) telnet_client.execute_command('no shutdown') telnet_client.execute_command('interface {}'.format(port2)) telnet_client.execute_command('no shutdown') else: # 关闭 telnet_client.execute_command('config t') telnet_client.execute_command('interface {}'.format(port1)) telnet_client.execute_command('shutdown') telnet_client.execute_command('interface {}'.format(port2)) telnet_client.execute_command('shutdown') telnet_client.execute_command('exit') # 退出端口配置 telnet_client.execute_command('exit') # 退出配置模式 text = '↑——更新端口状态——↓' print(text) logger.info(text) res1 = telnet_client.execute_command('show interfaces {} status'.format(port1)) print_port_status(port1, res1) res2 = telnet_client.execute_command('show interfaces {} status'.format(port2)) print_port_status(port2, res2) # 退出登录 telnet_client.logout_host() """ enable configure terminal hostname Test username admin password mypassword enable password mypassword line vty 0 4 login local int vlan 1 ip address 192.168.96.140 255.255.255.0 no shutdown exit ip default-gateway 192.168.96.1 snmp-server community XXXX ro services password-encryption end writ """ ``` # 打包成exe给Windows使用 ```bash # 安装相应的库 # pip install pywin32 # pip install -U pyinstaller # 执行 import os os.system("pyinstaller -F conn_cisco_sw_cmd_test.py -i img.ico") ```
很赞哦! (2)
相关文章
文章交流
- emoji