Python教程

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

本文主要是介绍python学习-使用textfsm解析华为交换机配置进行巡检,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
客户这里,有将近200台左右的接入交换机,全部是华为S57系列的。现在需要对交换机状态进行巡检,检查交换机CPU,内存,电源,风扇状态。如果是人工巡检就得一台一台登录查看,效率非常低下。由于客户这里没有使用网管软件,全凭人肉运维。=。=现在想使用python来进行巡检,并把结果统计到一张表格里面,这样不就非常省事了么 # 现状 以下是设备资产列表,记录的设备的名称,管理地址等信息 ![image.png](http://www.www.zyiz.net/i/li/?n=2&i=images/20210702/1625239371485010.png?,size_14,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_20,type_ZmFuZ3poZW5naGVpdGk=) 以下是交换机检查命令的输出结果,分别使用display fan,display cpu,display mem,display power,display enviroment ![image.png](http://www.www.zyiz.net/i/li/?n=2&i=images/20210702/1625237306170640.png?,size_14,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_20,type_ZmFuZ3poZW5naGVpdGk=) ![image.png](http://www.www.zyiz.net/i/li/?n=2&i=images/20210702/1625237385485393.png?,size_14,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_20,type_ZmFuZ3poZW5naGVpdGk=) 现在我们获取到这些状态了,接下的问题是如何解析这些文本并保存? ## 问题: 1.如何批量保存状态文本? 2.保存后如何解析这些文本? 3.解析文本出来后,如何格式存储到表格中? 针对如上问题,采取如下思路解决 ## 思路: 1.使用pandas模块读取表格,获取需要ssh登录的设备信息 2.使用netmiko模块批量发送命令给交换机 3.将回显的结果批量保存到指定路径下 4.批量读取这些文本,使用textfsm解析文本, 5.将解析结果使用pandas模块分门别类的保存一张表格中的不同sheet 有了思路,就好解决了,为了实现以上的思路,需要了解python的一些模块的使用 ## 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() # 通道的低级写入 ## TextFSM TextFSM是Google开发的一种开源Python模块,可以基于模板的状态机来解析半格式化文本,从而实现对网络设备CLI输出信息进行结构化数据处理,最终将文本内容输出为Python的字典或列表格式(或者是两者组合)。 详细内容可以访问该模块的GitHub:https://github.com/google/textfsm。 关于TextFSM具体使用,还可以参考锐捷的资料 https://www.ruijie.com.cn/fa/xw-hlw/86889/ 我的TextFSM就是照着锐捷的模板借鉴使用 ## 相关脚本 ### 华为TextFSM - 解析fan ```text Value SLOT_ID (\d/\d|\d) Value FAN_ID (\d) Value STATUS (\S+) Start ^Slot ${SLOT_ID}: Fan ${FAN_ID} is ${STATUS} -> Record ``` - 解析power ```text Value POWER_ID (\d|\S+\d) Value STATUS (Normal|Abnorma) Start ^SlotID\s+.* State ^\s+${POWER_ID}\s+.* ${STATUS} -> Record ``` - 解析温度 ```text Value ID (\d) Value TEMP (\d+) Start ^SlotID\s+CurrentTemperature ^\s+${ID}\s+${TEMP} -> Record ``` - 解析cpu和mem 因为cpu和mem比较简单,可以直接使用正则表达式,无需使用TextFSM ```python r'CPU utilization for five seconds:\s+\d+%' r'Memory Using Percentage Is:\s+\d+%' ``` ## 脚本 直接看注释把 ```python 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表格如下所示: ![image.png](http://www.www.zyiz.net/i/li/?n=2&i=images/20210702/1625240160619306.png?,size_14,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_20,type_ZmFuZ3poZW5naGVpdGk=) ![image.png](http://www.www.zyiz.net/i/li/?n=2&i=images/20210702/1625240193724568.png?,size_14,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_20,type_ZmFuZ3poZW5naGVpdGk=) ![image.png](http://www.www.zyiz.net/i/li/?n=2&i=images/20210702/1625240224836973.png?,size_14,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_20,type_ZmFuZ3poZW5naGVpdGk=) ![image.png](http://www.www.zyiz.net/i/li/?n=2&i=images/20210702/1625240254134739.png?,size_14,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_20,type_ZmFuZ3poZW5naGVpdGk=) 有了这张表,再人工筛选下表格,就能找出来那些设备有问题。 这样就实现了最简单的设备健康检查及巡检。 从结果来看,确认有交换机电源有问题。 ## 需要改进的地方 1. 单线程,运行起来比较慢,后续可以使用线程池实现多线程 2. 没有逻辑判断,需要人工检查哪些正常,哪些异常 3. 后续使用ntc-templates,并自定义模板,这样不用把信息保存到本地,可以省一个步骤 详细的脚本,见我代码库 https://gitee.com/yashirochaos/yangchao/blob/master/python3%E5%B7%A5%E4%BD%9C%E4%BD%BF%E7%94%A8/30%E4%BA%A4%E6%8D%A2%E6%9C%BA%E5%81%A5%E5%BA%B7%E6%A3%80%E6%9F%A5/2%E5%8D%8E%E4%B8%BA%E4%BA%A4%E6%8D%A2%E6%9C%BA%E6%A3%80%E6%9F%A5/check_switch_status_huawei_v3.py
这篇关于python学习-使用textfsm解析华为交换机配置进行巡检的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!