概述客户这里,有将近200台左右的接入
交换机,全部是
华为S57系列的。现在需要对交换机状态进行
巡检,检查交换机CPU,内存,电源,风扇状态。如果是人工巡检就得一台一台登录查看,效率非常低下。由于客户这里没有使用网管软件,全凭人肉运维。=。=现在想使用python来进行巡检,并把结果统计到一张表格里 客户这里,有将近200台左右的接入交换机,全部是华为S57系列的。现在需要对交换机状态进行巡检,检查交换机cpu,内存,电源,风扇状态。如果是人工巡检就得一台一台登录查看,效率非常低下。由于客户这里没有使用网管软件,全凭人肉运维。=。=现在想使用python来进行巡检,并把结果统计到一张表格里面,这样不就非常省事了么# 现状以下是设备资产列表,记录的设备的名称,管理地址等信息![image.png](http://www.icode9.com/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.icode9.com/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.icode9.com/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#confignet_connect.enable() # 输入启用模式net_connect.find_prompt() # 返回当前路由器提示符net_connect.commit() # 在Juniper和IOS#XR上执行提交 *** 作net_connect.disconnect() # 关闭连接net_connect.write_channel() # 通道的低级写入net_connect.read_channel() # 通道的低级写入## TextFSMTextFSM是Google开发的一种开源python模块,可以基于模板的状态机来解析半格式化文本,从而实现对网络设备Cli输出信息进行结构化数据处理,最终将文本内容输出为Python的字典或列表格式(或者是两者组合)。详细内容可以访问该模块的GitHub:https://github.com/Google/textfsm。关于TextFSM具体使用,还可以参考锐捷的资料https://www.ruijIE.com.cn/fa/xw-hlw/86889/我的TextFSM就是照着锐捷的模板借鉴使用## 相关脚本### 华为TextFSM- 解析fan```textValue SLOT_ID (\d/\d|\d)Value FAN_ID (\d)Value STATUS (\S+)Start ^Slot ${SLOT_ID}: Fan ${FAN_ID} is ${STATUS} -> Record```- 解析power```textValue POWER_ID (\d|\S+\d)Value STATUS (normal|Abnorma)Start ^SlotID\s+.* State ^\s+${POWER_ID}\s+.* ${STATUS} -> Record```- 解析温度```textValue ID (\d)Value TEMP (\d+)Start ^SlotID\s+CurrentTemperature ^\s+${ID}\s+${TEMP} -> Record```- 解析cpu和mem因为cpu和mem比较简单,可以直接使用正则表达式,无需使用TextFSM```pythonr'cpu utilization for five seconds:\s+\d+%'r'Memory Using Percentage Is:\s+\d+%'```## 脚本直接看注释把```pythonimport netmikoimport pandas as pdimport osimport timefrom textfsm import TextFSMimport reimport 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_statusdef 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.icode9.com/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.icode9.com/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.icode9.com/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.icode9.com/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解析华为交换机配置进行巡检全部内容,希望文章能够帮你解决python学习-使用textfsm解析华为交换机配置进行巡检所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
评论列表(0条)