使用textfsm解析华为交换机配置进行巡检

59次阅读
没有评论

一、概述

有将近200台左右的接入交换机,全部是华为S57系列的。现在需要对交换机状态进行巡检,检查交换机CPU,内存,电源,风扇状态。如果是人工巡检就得一台一台登录查看,效率非常低下。由于客户这里没有使用网管软件,全凭人肉运维。=。=现在想使用python来进行巡检,并把结果统计到一张表格里面,这样不就非常省事了么

二、现状

以下是设备资产列表,记录的设备的名称,管理地址等信息

使用textfsm解析华为交换机配置进行巡检

以下是交换机检查命令的输出结果,分别使用display fan,display cpu,display mem,display power,display enviroment

使用textfsm解析华为交换机配置进行巡检
使用textfsm解析华为交换机配置进行巡检

现在我们获取到这些状态了,接下的问题是如何解析这些文本并保存?

三、问题:

1.如何批量保存状态文本?
2.保存后如何解析这些文本?
3.解析文本出来后,如何格式存储到表格中?

针对如上问题,采取如下思路解决

四、思路:

1.使用pandas模块读取表格,获取需要ssh登录的设备信息
2.使用netmiko模块批量发送命令给交换机
3.将回显的结果批量保存到指定路径下
4.批量读取这些文本,使用textfsm解析文本,
5.将解析结果使用pandas模块分门别类的保存一张表格中的不同sheet

有了思路,就好解决了,为了实现以上的思路,需要了解python的一些模块的使用

五、第三方包

5.1 netmiko

此模块用于简化paramiko与网络设备之间的ssh连接,可在windows与Unix平台使用
常用方法

net_connect.send_command() # 向下发送命令,返回输出(基于模式)
net_connect.send_command_timing() # 沿通道发送命令,返回输出(基于时序)
net_connect.send_config_set() # 将配置命令发送到远程设备
net_connect.send_config_from_file() # 发送从文件加载的配置命令
net_connect.save_config() # 将running#config保存到startup#config
net_connect.enable() # 输入启用模式
net_connect.find_prompt() # 返回当前路由器提示符
net_connect.commit() # 在Juniper和IOS#XR上执行提交操作
net_connect.disconnect() # 关闭连接
net_connect.write_channel() # 通道的低级写入
net_connect.read_channel() # 通道的低级写入

5.2 TextFSM

TextFSM是Google开发的一种开源Python模块,可以基于模板的状态机来解析半格式化文本,从而实现对网络设备CLI输出信息进行结构化数据处理,最终将文本内容输出为Python的字典或列表格式(或者是两者组合)。
详细内容可以访问该模块的GitHub: https://github.com/google/textfsm

关于TextFSM具体使用,还可以参考锐捷的资料
 https://www.ruijie.com.cn/fa/xw-hlw/86889/

我的TextFSM就是照着锐捷的模板借鉴使用

5.3 相关脚本

华为TextFSM

解析fan


Value SLOT_ID (\d/\d|\d)
Value FAN_ID (\d)
Value STATUS (\S+)

Start
^Slot ${SLOT_ID}: Fan ${FAN_ID} is ${STATUS} -> Record

解析power

Value POWER_ID (\d|\S+\d)
Value STATUS (Normal|Abnorma)

Start
^SlotID\s+.* State
^\s+${POWER_ID}\s+.* ${STATUS} -> Record

解析温度

Value ID (\d)
Value TEMP (\d+)
Start
^SlotID\s+CurrentTemperature
^\s+${ID}\s+${TEMP} -> Record

解析cpu和mem
因为cpu和mem比较简单,可以直接使用正则表达式,无需使用TextFSM

r'CPU utilization for five seconds:\s+\d+%'
r'Memory Using Percentage Is:\s+\d+%'

脚本
直接看注释把

import netmiko
import pandas as pd
import os
import time
from textfsm import TextFSM
import re
import glob  #此模块是匹配路径下所有文件
class Conn():  #Conn类,同时netmiko模块ssh连接设备并发送命令

@property #将方法转换为属性,方便更改
def ip(self):
return self._ip
@ip.setter
def ip(self,ip):
self._ip=ip
@property
def device_name(self):
return self._device_name
@device_name.setter
def device_name(self,device_name):
self._device_name=device_name

def init(self):


'''
构造属性,定义登录设备的账户密码信息
'''
self.username='admin'
self.password='xxxxx'

def save_config(self):


'''
保存配置方法
'''       ssh_login=netmiko.Netmiko(ip=self._ip,username=self.username,password=self.password,device_type='huawei') #初始化连接
path='backup/' #定义保存的文本的路径
config=ssh_login.send_command('di cu') #发送命令
config_file=self._device_name+'-'+self._ip+'.txt' #定义文本文件名称
backup_file=os.path.join(path,config_file) #拼接路径
with open (backup_file,'w') as f: #保存写入
f.write(config)

def check_status(self,path):


'''
获取状态信息的方法,获取cpu,fan等信息
'''
ssh_login=netmiko.Netmiko(ip=self._ip,username=self.username,password=self.password,device_type='huawei')
command=['display fan','display cpu','display environment','display power','display memory-usage','display temperature all']  #批量发送命令
status=ssh_login.send_config_set(command)
filename=self._device_name+'-'+self._ip+'.txt'
status_file=os.path.join(path,filename)
with open (status_file,'w') as f:
f.write(status)

#使用text-fsm检查交换机配置状态
#生成表格

list_device_name=[] #定义列表保存信息
list_fans_status=[]
list_power_status=[]
list_cpu_status=[]
list_mem_status=[]
list_temp_status=[]
count_fan_dict={}  #定义字典,保存状态信息
count_power_dict={}
count_cpumem_dict={}
count_temp_dict={}

class CHCEK():
'''
解析状态的类
'''
def **init**(self,file):
self._file=None
with open(file,'r',encoding='utf-8') as f: #构造初始化方法,定义读取文件,即保存的状态信息
self.dev_text=f.read()

def fans_status_S86X(self):


'''
解析fan
'''
temp_fans_status=TextFSM(open(r'textfsm/huawei_display_fan_dis.textfsm')) #读取textfsm模板解析
info_fans_status=temp_fans_status.ParseTextToDicts(self.dev_text) #保存为列表
print (info_fans_status)
return info_fans_status

def power_status_S86X(self): #解析power
temp_power_status=TextFSM(open(r'textfsm/huawei_display_power_dis.textfsm'))
info_power_status=temp_power_status.ParseTextToDicts(self.dev_text)
print (info_power_status)
return info_power_status

def cpu_status_S86X(self):
'''
temp_power_status = TextFSM(open(r'textfsm/ruijie_show_cpu_S86X.textfsm'))
self.info_power_status = temp_power_status.ParseTextToDicts(self.dev_text)
'''
cpu_status=re.findall(r'CPU utilization for five seconds:\s+\d+%',self.dev_text) #使用正则表达式解析cpu
cpu_status=''.join(cpu_status)
info_cpu_status=re.findall(r'\d+%',cpu_status) #第二次匹配,更加准确
print(info_cpu_status)
return info_cpu_status
def mem_status_X86x(self): #解析内存利用率
mem_status=re.findall(r'Memory Using Percentage Is:\s+\d+%',self.dev_text) #正则匹配
mem_status=''.join(mem_status)
info_mem_status=re.findall(r'\d+%',mem_status)
print (info_mem_status)
return info_mem_status

def temp_status_S86X(self):


'''
解析温度
'''
temp_temp_status = TextFSM(open(r'textfsm/huawei_display_temp_dis.textfsm'))
info_temp_status = temp_temp_status.ParseTextToDicts(self.dev_text)
print(info_temp_status)
return info_temp_status

def handle(path):
'''
处理解析出来的信息
'''
filelocation=glob.glob(path) #获取路径下的所有文件
for file in filelocation:
print(file)
device_name=file.split('.txt')[0].split(r'\\')[-1] #读取文件名,字符拆分为设备名
device_name=device_name.replace('check_status_dis\\','')
print (device_name)
list_device_name.append(device_name) #添加到设备名列表
check=CHCEK(file=file) #实例化化CHECK()对象
fans_status=check.fans_status_S86X() #获取fan信息
list_fans_status.append(fans_status) #保存fan信息,以下类似
power_status=check.power_status_S86X()
list_power_status.append(power_status)
cpu_status=check.cpu_status_S86X()
list_cpu_status.append(cpu_status)
mem_status=check.mem_status_X86x()
list_mem_status.append(mem_status)
temp_status=check.temp_status_S86X()
list_temp_status.append(temp_status)

def to_excel(): #保存到表格
count_fan_dict['device_name']=list_device_name #字典,定义键名 device_name,值为列表,设备信息,以下类似
count_fan_dict['fans_status']=list_fans_status
count_power_dict['device_name']=list_device_name
count_power_dict['powers_status']=list_power_status
count_cpumem_dict['device_name']=list_device_name
count_cpumem_dict['cpu_status']=list_cpu_status
count_cpumem_dict['mem_status']=list_mem_status
count_temp_dict['device_name'] = list_device_name
count_temp_dict['temp_status']=list_temp_status
df1=pd.DataFrame.from_dict(count_fan_dict,orient='index') #pandas方法,把字典转换为DATAFRAME,保持索引
df1=df1.T #行类转换,以下类似
df2=pd.DataFrame.from_dict(count_power_dict,orient='index')
df2=df2.T
df3=pd.DataFrame.from_dict(count_cpumem_dict,orient='index')
df3=df3.T
df4=pd.DataFrame.from_dict(count_temp_dict,orient='index')
df4=df4.T
with pd.ExcelWriter('result-dis.xls') as w: #保存到excel表格
df1.to_excel(w,sheet_name='fans_status',index='SN') #保存到sheet ,名称为fans_status,索引名称为SN,代表序号,以下类似
df2.to_excel(w, sheet_name='power_status', index='SN')
df3.to_excel(w, sheet_name='cpu&mem_status', index='SN')
df4.to_excel(w, sheet_name='temp', index='SN')

if **name**=='**main**':
clock=time.strftime("%a %b %d %H:%M:%S %Y", time.localtime()) #定义时间格式

conn=Conn() #实例化Conn(),登录设备
df = pd.DataFrame(pd.read_excel('交换机信息-汇聚.xls')) #读取设备配置信息
df_dict = df.groupby(['设备名称'])['MGT地址'].sum() #分组保存列,形成,以设备名为键,管理地址为值的字典
dict_device =df_dict.to_dict() # 保存为字典
path=r'check_status_dis/' #定义输出结果路径

for k,v in dict_device.items(): #循环字典
print (k)
print (v)
try:
conn.ip=v #赋值地址信息给属性
conn.device_name=k

conn.save_config()

    conn.check_status(path) #调用check_status方法,开始从发送命令并保存
    print(' device_name:{}--ip:{} is download status file ok!!!time is {}'.format(k, v, clock))
except Exception as e :
     print('{} is loss , msg:-{},time is {}'.format(k, e, clock), file=open('back_error_log.txt', 'a'))  #将无法登录的设备信息保存到文本中

handle(path=path+'*.txt') #进行处理
to_excel() #结果保存到excel

保存完成后,输出的excel表格如下所示:

使用textfsm解析华为交换机配置进行巡检
使用textfsm解析华为交换机配置进行巡检
使用textfsm解析华为交换机配置进行巡检
使用textfsm解析华为交换机配置进行巡检

有了这张表,再人工筛选下表格,就能找出来那些设备有问题。
这样就实现了最简单的设备健康检查及巡检。

从结果来看,确认有交换机电源有问题。

六、需要改进的地方

单线程,运行起来比较慢,后续可以使用线程池实现多线程
没有逻辑判断,需要人工检查哪些正常,哪些异常
后续使用ntc-templates,并自定义模板,这样不用把信息保存到本地,可以省一个步骤
详细的脚本,见我代码库 https://gitee.com/yashirochaos/yangchao/blob/master/python3工作使用/30交换机健康检查/2华为交换机检查/check_switch_status_huawei_v3.py

使用textfsm解析华为交换机配置进行巡检

正文完
 
oakcdrom
版权声明:本站原创文章,由 oakcdrom 2022-06-13发表,共计7557字。
转载说明:转载请注明出处。
评论(没有评论)