Python-交换机自动化巡检脚本笔记
python-交换机巡检自动化因为了解到python可以实现自动化的巡检功能,所以开始学习了《Python编程 从入门到实践》。通过一段时间的学习,将这本书的前11章看完,并开始搜索交换机巡检的相关模板,发现别人写的代码完全看不懂,很多模块,根本看不懂模块。经过一段时间的研究,要巡检,得学会以下几个模块:time、os、Netmiko、xlwt、re。我从开始学习到能ctrl+v出自己想要的脚本
python-交换机巡检自动化
因为了解到python可以实现自动化的巡检功能,所以开始学习了《Python编程 从入门到实践》。通过一段时间的学习,将这本书的前11章看完,并开始搜索交换机巡检的相关模板,发现别人写的代码完全看不懂,很多模块,根本看不懂模块。经过一段时间的研究,要巡检,得学会以下几个模块:time、os、Netmiko、xlwt、re。
关于交换机的交互模块,有些大神用的是pexpect模块,使用 pexpect.spawn.sendline() 来发送交换机的命令和 pexpect.swapn.expect() 来验证输出是否符合要求。而我这次所使用的就是 Netmiko
我从开始学习到能ctrl+v出自己想要的脚本的过程如下:
《Python编程 从入门到实践》——百度大神的脚本——了解大神脚本中模块的功能——根据需求自己写脚本
接下来我们开始了解编写脚本,所需要了解的模块吧
第一章、各模块介绍
1、time模块——生成时间相关
import time
>>> res = time.strftime("%Y-%m-%d %H:%M:%S",time.localtime())
>>> print(res)
2021-04-15 18:53:20
>>> res = time.strftime("%Y%m%d",time.localtime())
>>> print(res)
20210415
2、os模块的使用——创建目录
因为open模块只能创建文件,目录需要os模块来创建
import os
if not os.path.isdir("machine_learning"): #判定如何没有这个目录,就创建
os.makedirs("machine_learning") #创建
3、Netmiko-SSH巡检
通过ssh,巡检h3c的交换机。关键模块是ConnectHandler。
#!/usr/bin/python3
#H3c交换机
from netmiko import ConnectHandler
'''定义交换机,包括类型,密码,ip,主机名'''
ip_list = [
['交换机的sysname','交换机的管理ip'],
]
#这里定义了ssh要用到的参数
SW = {
'device_type':'hp_comware', #设备类型是netmiko预定义好的,现在用hp_comware是h3c的
'username':'admin',
'ip':'',
'password':"xxxxxx"
}
'''定义结束'''
'''交换机交互'''
for ip_item in ip_list:
SW['ip'] = ip_item[1]
connect = ConnectHandler(**SW)
print(log_time + 'Successfully connected to ' + ip_item[0])
output = connect.send_command('system view')
iproute = connect.send_command("display ip routing-table")
print(output) #验证
print(iproute) #验证
'''交换结束'''
3.2、Netmiko-telnet巡检
telnet与ssh的区别应该就在于,device_type中尾部添加_telnet,用的是Netmiko,而ssh用的是ConnectHandler。
我们的telnet分为h3c和cisco。
H3C
from netmiko import Netmiko
'''定义交换机,包括类型,密码,ip,主机名'''
ip_list = [
['交换机的sysname','交换机的ip地址'], #定义设备的用户名和管理地址
]
SW = {
'device_type':'hp_comware_telnet', #设备类型是netmiko预定义好的
'username':'admin',
'ip':'',
'password':"xxxxxx",
}
'''完成定义'''
'''与交换机交互'''
for ip_item in ip_list:
SW['ip'] = ip_item[1]
connect = Netmiko(**SW)
print(log_time + 'Successfully connected to ' + ip_item[0])
config = connect.send_command('dis cur')
fan = connect.send_command('dis fan')
print(config) #验证一下值是不是想要的
print(fan) #验证一下值是不是想要的
cisco
主要的不同是,cisco的telnet是需要enable的。
from netmiko import Netmiko
'''定义交换机,包括类型,密码,ip,主机名'''
ip_list = [
['交换机的hostname','交换机的ip'], #定义设备的用户名和管理地址
]
SW = {
'device_type':'cisco_iso_telnet', #设备类型是netmiko预定义好的
'username':'admin',
'ip':'',
'password':"xxxxxx", #telnet的密码
'secret':'xxxxx', #enable的密码
}
'''完成定义'''
'''与交换机交互'''
for ip_item in ip_list:
SW['ip'] = ip_item[1]
connect = Netmiko(**SW)
connect.enable() #注意这个地方!cisco是这样enable的
print(log_time + 'Successfully connected to ' + ip_item[0])
config = connect.send_command('shun run')
cpu = connect.send_command('sh process cpu')
print(config) #验证一下值是不是想要的
print(fan) #验证一下值是不是想要的
4、xlwt模块-创建excel
import xlwt
workbook = xlwt.Workbook()
worksheet = workbook.add_sheet('巡检报告第一次') #创建worksheet
worksheet.write(0,0,label = '设备名称') #对A1添加内容
worksheet.write(0,1,label = '属性') #对B1添加内容
worksheet.write(0,2,'值') #对C2添加内容
workbook.save('巡检报告生成.xls') #保存到excel,如果没有会创建。
5、re模块——正则表达式,截取想要的字段。
截取a-b之间的字符串:不包括ab
#注意有两种形式。一个匹配到第一个b,一个是匹配到最后一个b。
import re
number = "a123b456b"
print(re.findall(r"a(.+?)b", number)) #注意!匹配到第一个b。
#输出['123']
print(re.findall(r"a(.+)b", number)) #这个是匹配到最后一个b
#输出['123b456']
另外一种正则表达式的使用形式:
import re
number = "a123b456b"
pattern = re.complie("a(.+)b")
print(pattern.findall(number))
#输出['123b456']
从a开始截取到b为止: 包括ab
import re
number = "a123b456b"
print(re.findall(r"a.+?b", number)) #注意!匹配到第一个b。
#输出['a123b']
print(re.findall(r"a.+b", number)) #这个是匹配到最后一个b
#输出['a123b456b']
第二章、巡检脚本介绍
1、巡检并记录下txt
这里只自定义了一个h3c的交换机巡检模块,而cisco的大同小异,差别在于 ”使用不同的netmiko子模块“、“定义交换机时多一个enable密码”、”多了enable模块(在第一章—3.2——cisco中有说明))“
#!/usr/bin/python3
#H3c交换机
'''-------模块导入--------'''
import time
from netmiko import ConnectHandler
from netmiko import Netmiko
import os
import re
import xlwt
'''--------模块导入结束--------'''
'''----------------------创建文件夹-------------------------'''
time_str = time.strftime('%Y_%m_%d', time.localtime())
path = "D:\\Seafile\\2021年农林维护\\3-巡检"
title = "%s"%time_str
new_path = os.path.join(path, title) #创建基于日期命名的文件夹
log_path = "%s\\巡检文件"%new_path
config_path = "%s\\配置文件备份"%new_path
if not os.path.isdir(new_path):
os.makedirs(new_path)
if not os.path.isdir(log_path):
os.makedirs(log_path)
if not os.path.isdir(config_path):
os.makedirs(config_path)
'''----------------------------创建文件夹结束------------------'''
'''-------------------和学校h3c交换机交互,并保留文本用于后期筛选数据的模块-----------'''
def h3c_ssh_v7(sysname,ipadd):
ip_list = [
[sysname,ipadd],
]
SW = {
'device_type':'hp_comware',
'username':'用户名',
'ip':'',
'password':"密码",
}
for ip_item in ip_list:
SW['ip'] = ip_item[1]
connect = ConnectHandler(**SW)
print(time_str + 'Successfully connected to ' + ip_item[0])
config = connect.send_command('dis current-configuration')
fan = connect.send_command('dis fan')
'''-----这里我们只需要dis process cpu第一行的资料,进行预筛查----'''
cpu = connect.send_command('dis process cpu')
cpu = cpu.split('\n') #cpu show出来时纯字符串,我用split配合换行符分割。
cpu = cpu[0] #分割好只取第一行
'''-----------------------cpu内容预筛选结束-------------------'''
power = connect.send_command('dis power')
manager_ip = connect.send_command('dis ip int vlan 1 brief')
device = connect.send_command('dis device | exclude NONE')
'''-------------------同样时预筛查只需要前四行内容-----------------------'''
version = connect.send_command('dis version')
version = version.split('\n')
version = '\n'.join(version[0:4]) #因为version[0:4]出来的是一个列表,所以使用join,将列表内容拼接成字符串。
'''-------------------------预筛查结束--------------------------------'''
config_fo = open('%s\\%s-%s_config.txt'%(config_path,ip_item[0],ip_item[1]),'w',encoding='utf-8')#创建配置备份,文件名时sysname-ipadd的格式。记住这里一定要加入encoding=‘utf-8',不然有些h3c设备可能会报错。
fo = open('%s\\%s-%s.txt'%(log_path,ip_item[0],ip_item[1]),'w') #创建巡检的文件。存放巡检时候产生的数据
config_fo.write(config)
if cpu: #如果cpu有数据存在
fo.write(cpu) #把cpu的巡检结果写入巡检文件 以下类似
fo.write('\n') #换行,让文本看的清楚些用的。以下大概就这些消息,不逐一说了
fo.write('\n')
if fan:
fo.write(fan)
fo.write('\n')
fo.write('\n')
if power:
fo.write(power)
fo.write('\n')
fo.write('\n')
if version:
fo.write(version)
fo.write('\n')
fo.write('\n')
if manager_ip:
fo.write(manager_ip)
fo.write('\n')
fo.write('\n')
if device:
fo.write(device)
h3c_ssh_v7('设备的sysname','设备的ip地址')记得调用函数
"""------------------------------------巡检备份结束-------------------------------------------------------"""
2、分析文件并写入excel报告
因为楼宇,核心,服务器核心所生成的巡检文件有很大的不同所以我选择了分开写。
这里我只列了我们核心交换机的数据抓取。
"""-------------------承接上面的代码(因为要用到导入的模块和变量))---生成报告-------------------------------"""
y = 1 #这个是用来记录我的excel写到了哪一行的
def h3c_core_report(hostname,ipadd):
file = open('%s\\%s-%s.txt'%(log_path,hostname,ipadd))
listlist=file.readlines()
i=1 #注意:在下面'''分析提取数据并提取'''代码块最后有个i += 1 用于计数。当“我要抓取的数据在我能匹配到数据行的下一行。”的时候就会用到了。
'''------------------------分析数据并提取--------------------------------------------'''
for line in listlist:
if 'CPU utilization' in line:
pattern = re.compile('5.+%') #正则匹配的匹配规则
cpu_use_list = pattern.findall(line) #使用规则抓出数据,下面的代码都是大同小异的抓取
for cpu_use in cpu_use_list: #因为抓出的数据是列表,用for循环转换为字符。其实可以用cpu_use_list[0]。
print(cpu_use)
if 'weeks' in line:
run_time_list = re.findall("uptime is(.+?)\n",line)
for run_time in run_time_list:
print(run_time.strip())
if 'Chassis 1' in line: #因为用了H3C的IRF设备,有多行Chassis 1,显示chassis1上例如风扇、电源的状态
if 'Fan' in listlist[i]: #和上一行执行“与”操作,匹配到就抓取数据。
pattern = re.compile(':(.+)\n')
chassis_1_fan_list = pattern.findall(listlist[i]) #这个就是抓取匹配行的下一行
for chassis_1_fan in chassis_1_fan_list:
chassis_1_fan = chassis_1_fan.strip()
print(chassis_1_fan)
if 'Power' in listlist[i]: #和chassis 1行进行“与”操作,匹配就抓取需要的数据
pattern = re.compile(':(.+)\n')
chassis_1_power_0_state_list = pattern.findall(listlist[i])
for chassis_1_power_0_state in chassis_1_power_0_state_list:
chassis_1_power_0_state = chassis_1_power_0_state.strip()
print(chassis_1_power_0_state)
chassis_1_power_1_state_list = pattern.findall(listlist[i+1])
for chassis_1_power_1_state in chassis_1_power_1_state_list:
chassis_1_power_1_state = chassis_1_power_1_state.strip()
print(chassis_1_power_1_state)
chassis_1_power_2_state_list = pattern.findall(listlist[i+2])
for chassis_1_power_2_state in chassis_1_power_2_state_list:
chassis_1_power_2_state = chassis_1_power_2_state.strip()
print(chassis_1_power_2_state)
chassis_1_power_3_state_list = pattern.findall(listlist[i+3])
for chassis_1_power_3_state in chassis_1_power_3_state_list:
chassis_1_power_3_state = chassis_1_power_3_state.strip()
print(chassis_1_power_3_state)
chassis_1_power_4_state_list = pattern.findall(listlist[i+4])
for chassis_1_power_4_state in chassis_1_power_4_state_list:
chassis_1_power_4_state = chassis_1_power_4_state.strip()
print(chassis_1_power_4_state)
chassis_1_power_5_state_list = pattern.findall(listlist[i+5])
for chassis_1_power_5_state in chassis_1_power_5_state_list:
chassis_1_power_5_state = chassis_1_power_5_state.strip()
print(chassis_1_power_5_state)
if 'Chassis 2' in line: #这里就是抓取chassis 2上的数据
if 'Fan' in listlist[i]:
pattern = re.compile(':(.+)\n')
chassis_2_fan_list = pattern.findall(listlist[i])
for chassis_2_fan in chassis_2_fan_list:
chassis_2_fan = chassis_2_fan.strip()
print(chassis_2_fan)
if 'Power' in listlist[i]:
pattern = re.compile(':(.+)\n')
chassis_2_power_0_state_list = pattern.findall(listlist[i])
for chassis_2_power_0_state in chassis_2_power_0_state_list:
chassis_2_power_0_state = chassis_2_power_0_state.strip()
print(chassis_2_power_0_state)
chassis_2_power_1_state_list = pattern.findall(listlist[i+1])
for chassis_2_power_1_state in chassis_2_power_1_state_list:
chassis_2_power_1_state = chassis_2_power_1_state.strip()
print(chassis_2_power_1_state)
chassis_2_power_2_state_list = pattern.findall(listlist[i+2])
for chassis_2_power_2_state in chassis_2_power_2_state_list:
chassis_2_power_2_state = chassis_2_power_2_state.strip()
print(chassis_2_power_2_state)
chassis_2_power_3_state_list = pattern.findall(listlist[i+3])
for chassis_2_power_3_state in chassis_2_power_3_state_list:
chassis_2_power_3_state = chassis_2_power_3_state.strip()
print(chassis_2_power_3_state)
chassis_2_power_4_state_list = pattern.findall(listlist[i+4])
for chassis_2_power_4_state in chassis_2_power_4_state_list:
chassis_2_power_4_state = chassis_2_power_4_state.strip()
print(chassis_2_power_4_state)
chassis_2_power_5_state_list = pattern.findall(listlist[i+5])
for chassis_2_power_5_state in chassis_2_power_5_state_list:
chassis_2_power_5_state = chassis_2_power_5_state.strip()
print(chassis_2_power_5_state)
if '1/0' in line: #抓取板卡信息
slot1_1_list = line.split() #为了抓取状态值使用的手段,主要是将字段转成列表,然后再提取列表中的字符,以下其他板卡形式相同。
slot1_1_state = slot1_1_list[2]
print(f"1{slot1_1_state}")
if '1/4 LSUM1SUPC0' in line:
slot1_4_list = line.split()
slot1_4_state = slot1_4_list[2]
print(f"4{slot1_1_state}")
if '1/5 LSUM1SUPC0' in line:
slot1_5_list = line.split()
slot1_5_state = slot1_5_list[2]
print(slot1_5_state)
if '1/7 LSUM2TGS16SF0' in line:
slot1_7_list = line.split()
slot1_7_state = slot1_7_list[2]
print(slot1_7_state)
if '1/9 LSUM2GT24PTSSE0' in line:
slot1_9_list = line.split()
slot1_9_state = slot1_9_list[2]
print(slot1_9_state)
if '1/10 LSU1FAB08B0' in line:
slot1_10_list = line.split()
slot1_10_state = slot1_10_list[2]
print(f"10{slot1_10_state}")
if '1/11 LSU1FAB08B0' in line:
slot1_11_list = line.split()
slot1_11_state = slot1_11_list[2]
print(slot1_11_state)
if '1/12 LSU1FAB08B0' in line:
slot1_12_list = line.split()
slot1_12_state = slot1_12_list[2]
print(slot1_12_state)
if '1/13 LSU1FAB08B0' in line:
slot1_13_list = line.split()
slot1_13_state = slot1_13_list[2]
print(slot1_13_state)
if '2/0 LSUM2GT48SE0' in line:
slot2_1_list = line.split()
slot2_1_state = slot2_1_list[2]
print(slot2_1_state)
if '2/4 LSUM1SUPC0' in line:
slot2_4_list = line.split()
slot2_4_state = slot2_4_list[2]
print(slot2_4_state)
if '2/5 LSUM1SUPC0' in line:
slot2_5_list = line.split()
slot2_5_state = slot2_5_list[2]
print(slot2_5_state)
if '2/7 LSUM2TGS16SF0' in line:
slot2_7_list = line.split()
slot2_7_state = slot2_7_list[2]
print(slot2_7_state)
if '2/9 LSUM2GT24PTSSE0' in line:
slot2_9_list = line.split()
slot2_9_state = slot2_9_list[2]
print(slot2_9_state)
if '2/10 LSU1FAB08B0' in line:
slot2_10_list = line.split()
slot2_10_state = slot2_10_list[2]
print(slot2_10_state)
if '2/11 LSU1FAB08B0' in line:
slot2_11_list = line.split()
slot2_11_state = slot2_11_list[2]
print(slot2_11_state)
if '2/12 LSU1FAB08B0' in line:
slot2_12_list = line.split()
slot2_12_state = slot2_12_list[2]
print(slot2_12_state)
if '2/13 LSU1FAB08B0' in line:
slot2_13_list = line.split()
slot2_13_state = slot2_13_list[2]
print(slot2_13_state)
i += 1 #用来计数的。
'''-------------------------分析和提取数据结束----------------------------------'''
'''-----------------------开始写入excle数据------------------------------------'''
x = 0 #用来计算我这个交换机用了多少行。主要为合并单元格服务的
global y #计算整个excel使用了多少行。主要帮助程序从那里一行开始写入,合并单元格的时候也会用到。
worksheet.write(y,1,label = '管理地址')
worksheet.write(y,2,label = ipadd)
y = y + 1
x += 1
if cpu_use:
worksheet.write(y,1,label = 'CPU使用率')
worksheet.write(y,2,cpu_use)
y = y + 1
x += 1
if run_time:
worksheet.write(y,1,label = '运行时间')
worksheet.write(y,2,run_time)
y = y + 1
x += 1
if slot1_1_state:
worksheet.write(y,1,"slot1_1")
worksheet.write(y,2,slot1_1_state)
y = y + 1
x += 1
if slot1_4_state:
worksheet.write(y,1,"slot1_4")
worksheet.write(y,2,slot1_4_state)
y = y + 1
x += 1
if slot1_5_state:
worksheet.write(y,1,"slot1_5")
worksheet.write(y,2,slot1_5_state)
y = y + 1
x += 1
if slot1_7_state:
worksheet.write(y,1,"slot1_7")
worksheet.write(y,2,slot1_7_state)
y = y + 1
x += 1
if slot1_9_state:
worksheet.write(y,1,"slot1_9")
worksheet.write(y,2,slot1_9_state)
y = y + 1
x += 1
if slot1_10_state:
worksheet.write(y,1,"slot1_10")
worksheet.write(y,2,slot1_10_state)
y = y + 1
x += 1
if slot1_11_state:
worksheet.write(y,1,"slot1_11")
worksheet.write(y,2,slot1_11_state)
y = y + 1
x += 1
if slot1_12_state:
worksheet.write(y,1,"slot1_12")
worksheet.write(y,2,slot1_12_state)
y = y + 1
x += 1
if slot1_13_state:
worksheet.write(y,1,"slot1_12")
worksheet.write(y,2,slot1_13_state)
y = y + 1
x += 1
if slot1_1_state:
worksheet.write(y,1,"slot1_1")
worksheet.write(y,2,slot1_1_state)
y = y + 1
x += 1
if slot1_4_state:
worksheet.write(y,1,"slot1_4")
worksheet.write(y,2,slot1_4_state)
y = y + 1
x += 1
if slot1_5_state:
worksheet.write(y,1,"slot1_5")
worksheet.write(y,2,slot1_5_state)
y = y + 1
x += 1
if slot1_7_state:
worksheet.write(y,1,"slot1_7")
worksheet.write(y,2,slot1_7_state)
y = y + 1
x += 1
if slot1_9_state:
worksheet.write(y,1,"slot1_9")
worksheet.write(y,2,slot1_9_state)
y = y + 1
x += 1
if slot1_10_state:
worksheet.write(y,1,"slot1_10")
worksheet.write(y,2,slot1_10_state)
y = y + 1
x += 1
if slot1_11_state:
worksheet.write(y,1,"slot1_11")
worksheet.write(y,2,slot1_11_state)
y = y + 1
x += 1
if slot1_12_state:
worksheet.write(y,1,"slot1_12")
worksheet.write(y,2,slot1_12_state)
y = y + 1
x += 1
if slot1_13_state:
worksheet.write(y,1,"slot1_12")
worksheet.write(y,2,slot1_13_state)
y = y + 1
x += 1
worksheet.write_merge(y-x,y-1,0,0,hostname)
workbook.save('%s\\巡检报告生成.xls'%(log_path))
print(y)
print(x)
"""-------------------------------------------写入结束--------------------------------------------------"""
h3c_core_report('Dh_Tsg_1F_HeXin_S10508-V','10.27.0.1') #记得调用函数。
"""------------------------------------生成报告完成-------------------------------------------------------"""
脚本执行后的结果:
将上述的代码合并,在计算机任意位置执行,它就会自动生成一系列我们需要的文件。
excel巡检报告结果如图:此图我还是手动调整过的,因为在生成excel的时候没有,我没有定义style文件(因为懒),但是具体xwlt是可以实现的。
更多推荐
所有评论(0)