自学python后的第一个能用于实践的成果,有点小成就感,加油!!!
根据学习的相关语法,参考网络上相关资料,整理完成交换机批量配置的脚本,后期有遇到情况,再做变更。
代码部分可能看起来比较乱,因为包含了修改过程,在一点点的完善。保留了注释,为了以后方便查看。怕时间久了会忘记,^_^
##批量修改交换机的某一项配置:比如:新建或删除或修改账号
import paramiko
import time
import getpass
import sys
import socket #为了使用try-except来应对网络设备不可达引起的socket.error,这里我们必须import socket
username=input('请输入用户名:')
password=input('Password:')
'''
#password=getpass.getpass()
getpass()在Linux或CMD中可正常显示,在pycharm中无法直接运行。
使用交互式输入用户名和密码,其中用户名使用input()函数,明文;密码使用getpass模块的方法,密文。
'''
'''
创建一个文本文件,把我们需要登录的交换机ip全部写进去,
然后用for...in...语句,配合open()函数来批量登录所有交换机
'''
ip_file=sys.argv[1]
cmd_file=sys.argv[2]
'''
使用sys模块里的argv[],「argv」是「argument variable」参数变量的简写形式,这个变量返回的是一个列表,
argv[0] 一般是被调用的脚本的文件名或全路径,从argv[1]开始就是传入的数据了
在终端中执行:
[root@localhost]#python sw.py h3c_v5_ip.txt h3c_v5_cmd.txt
这里argv=['sw.py','h3c_v5_ip.txt','h3c_v5_cmd.txt']
ip_file=sys.argv[1]就=h3c_v5_ip.txt
cmd_file=sys.argv[2]就=h3c_v5_cmd.txt
'''
switch_with_authentication_issue={}
switch_not_reachable={}
'''创建两个空字典, 分别在脚本最后配合for循环来统计有哪些设备是因为认证问题无法登录,
有哪些是因为设备本身不可达而无法登录
'''
ip_list=open(ip_file,'r')
for line in ip_list.readlines():
try:
lst = line.split()
hostname = lst[0].strip() #strip()去掉空格
ip = lst[1].strip()
#将IP地址和主机名分离出来
client=paramiko.SSHClient() #调用SSHClient()方法并赋给变量client
client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) #设置host_key机制,使用paramiko自动机制,没有这条会报错找不到主机,无法登录设备
client.connect(hostname=ip,username=username,password=password,compress=True) #调用connect()方法
print('-----------------欢迎登陆交换机',hostname,ip,'---------------------')
command=client.invoke_shell() #调用paramiko的invoke_shell()方法,将其assign给command这个变量。
cmdlist=open(cmd_file,'r')
cmdlist.seek(0)
for cmd in cmdlist.readlines():
command.send(cmd)
time.sleep(1)
cmdlist.close()
output=command.recv(65535)
print(output.decode(encoding='utf-8'))
print('------------------命令执行完毕-----------------------')
except paramiko.ssh_exception.AuthenticationException:
print('User authentication failed for' + ip + '.')
switch_with_authentication_issue[hostname]=ip
except socket.error:
print(ip + 'is not reachable')
switch_not_reachable[hostname]=ip
'''
在for循环下使用try-except, 用excpet paramiko.ssh_exception.AuthenticationException:来
应对用户名/密码不匹配时返回的错误代码,将出现该错误的交换机的管理IP地址当做value值,主机名做key
添加到switch_with_authentication_issue这个字典中;
同理用except socket.error:来应对交换机不可达时返回的错误代码,
将出现该错误的交换机的管理IP地址做value值,主机名做key,添加到switch_not_reachable这个字典中。
'''
'''本段是简单配置,将命令行写到代码中,实际环境下设备命令格式多样化,这种方法不适用
# command.send('system-view\n')
# command.send('int GigabitEthernet 0/0/2\n')
# command.send('des test\n')
# command.send('quit\n')
# command.send('quit\n')
# command.send('quit\n') #让command配合send()这个函数来对交换机下发配置,注意末尾要有换行符\n,相当于敲回车
# print('------------------命令执行完毕-----------------------')
# time.sleep(2) #交换机运行命令可能有延时,让系统延后2秒运行下面的内容
# out=command.recv(65535)
# #mylog=open('log.txt','w')
# #print(out.decode(encoding='utf-8'),file=mylog) #将回显信息保存到mylog文件中
# print(out.decode(encoding='utf-8')) #输出的内容默认是二进制字符格式,需要解码成字节,显示内容才和交换机的一样
#stdin,stdout,stderr=client.exec_command('display vlan')
'''
ip_list.close()
client.close()
print('User authentication failed for below swtiches:')
for i in switch_with_authentication_issue:
print(i,switch_with_authentication_issue[i])
print('Below swtiches are not reachable:')
for i in switch_not_reachable:
print(i,switch_not_reachable[i])
'''
在最后将两种错误的主机列表打印出来
'''