python netmiko 多线程巡检脚本



最新代码地址:https://gitee.com/feifei6779/python-net/blob/master/Excel/多线程查询-3.py

2021-11-12 代码,完成设备版本、开机时间的采集和输出

import threading
import time
import os
from openpyxl import Workbook
from openpyxl.styles import Color, PatternFill, Font, Border, Side 
from netmiko import ConnectHandler
import json

'''
多线程并发查询华三交换version,并写入同一表格内。
'''

os.chdir(os.path.dirname(__file__))			#将当前py文件路径设置为工作路径。
wb=Workbook()

def mkExcelFile(ip):      # 首先创建一个新表格,返回表格名;
    filetime=time.strftime('%Y-%m-%d_%H-%M-%S')   #以开始时间作为表格文件名;

    wb=Workbook()
    ws=wb.active
    font=Font(color='000000', bold=True, vertAlign=None, size=20)

    ws['A1']=filetime+' 记录巡检输出,表单名为设备的IP地址。'
    ws['A1'].font=font
    wb.save(filetime+'-'+ip+'.xlsx')

    fileName=filetime+'-'+ip+'.xlsx'

    return fileName

def getDevList(FilePath):   # 获取设备列表,输入文件路径,返回设备列表devList;
    f=open(FilePath)
    devList=[]
    for line in f.readlines():
        fLine=line.strip()
        sw={
            'device_type': fLine.split('---')[3],
            'ip': fLine.split('---')[0],
            'username': fLine.split('---')[1],
            'password': fLine.split('---')[2]
        }
        devList.append(sw)
    f.close

    return devList

def GetVersionInfo(devList, ListAppend):		# 定义实际要运行的函数,返回0;
    command='disp version'
    SW2={
        'device_type': devList['device_type'],
        'ip': devList['ip'],
        'username': devList['username'],
        'password': devList['password']
    }
    #使用netmiko连接设备:
    connect = ConnectHandler(**SW2)
    print('成功连接到设备 '+SW2['ip'])
    version = connect.send_command(command, use_textfsm=True)  #传递命令;
    list1=json.loads(json.dumps(version, indent=2))     #将命令输出的json字符串转为python对象;
    dict1=list1[0]
    RList=[devList['ip']]
    for item in dict1:
        RList.append(dict1.get(item))
    # RList.append(dict1.get('vrp_version'))
    # RList.append(dict1.get('product_version'))
    # RList.append(dict1.get('model'))
    ListAppend.append(RList)

def VersionExcel(InfoList):        #定义版本输出表格,传入设备信息列表;
    ws=wb.create_sheet('Version',0)

    list_title=['设备IP','设备版本','小版本','设备型号','本次运行时长','上次重启原因']
    ws.append(list_title)

    for Rows in InfoList:
        ws.append(Rows)

    yellowFill = PatternFill(start_color='FFFF00', end_color='FFFF00', fill_type='solid')
    RedRill = PatternFill(start_color='FF0000', end_color='9AFE2E', fill_type='solid')
    thin_border = Border(left=Side(style='thin'), right=Side(style='thin'), top=Side(style='thin'), bottom=Side(style='thin'))

    for cells in ws[1]:         #为第一行增加色彩填充;
        cells.fill=yellowFill

    for cell in ws['D']:
        if 'up' in str(cell.value).lower():     #判断单元格内容是否有“up”,如果有,就修改单元格样式;
            cell.fill=RedRill
    for cell in ws['E']:
        if '0 week' in str(cell.value).lower():     #判断单元格内容是否有“0 week”,如果有,就修改单元格样式;
            cell.fill=RedRill

    for row in ws.rows:         #为所有单元格增加边框; 
        for cells in row:
            cells.border=thin_border
            
    ws.column_dimensions['A'].width=18      #调整列宽;
    ws.column_dimensions['B'].width=10
    ws.column_dimensions['C'].width=14
    ws.column_dimensions['D'].width=20
    ws.column_dimensions['E'].width=40
    ws.column_dimensions['F'].width=15

def MultiThread(DevFile):          #定义多线程函数,输入设备信息txt,输出设备信息列表;
    DevList=getDevList(DevFile)
    VersList=[]
    Threads=[]

    for i in DevList:
        t=threading.Thread(target=GetVersionInfo, args=(i, VersList))
        t.start()
        Threads.append(t)

    for i in Threads:
        i.join()

    return VersList

# print(VersList)
'''
输出为:
[['192.168.56.14', '7.1.075', 'Alpha 7571', 'S5820V2-54QS-GE', '0 weeks, 0 days, 1 hour, 3 minutes', 'User reboot'], 
['192.168.56.13', '7.1.075', 'Alpha 7571', 'S5820V2-54QS-GE', '0 weeks, 0 days, 1 hour, 4 minutes', 'User reboot'], 
['192.168.56.15', '7.1.075', 'Alpha 7571', 'S5820V2-54QS-GE', '0 weeks, 0 days, 1 hour, 3 minutes', 'User reboot'], 
['192.168.56.12', '7.1.075', 'Alpha 7571', 'S5820V2-54QS-GE', '0 weeks, 0 days, 1 hour, 3 minutes', 'User reboot'], 
['192.168.56.11', '7.1.075', 'Alpha 7571', 'S5820V2-54QS-GE', '0 weeks, 0 days, 1 hour, 4 minutes', 'User reboot']]
'''

def main(DevFile, OutFile):
    print('从文件 ' + DevFile + ' 中读取设备信息,并尝试连接。')
    InfoList=MultiThread(DevFile)      #使用多线程获取设备信息;
    print('表格信息写入中。')
    VersionExcel(InfoList)        #使用单线程将设备信息写入表格;
    wb.save(OutFile)
    print('表格信息写入完成,名为:', OutFile)

if __name__=='__main__':
    '''
    第一个参数为设备地址和用户等信息,第二个参数为要输出的excel文件名:
    '''
    main('../ip_list.txt', 'test_Get_Version.xlsx')

输出表格样式为:




2021-11-13 代码,改为字典传递命令和空列表,增加电源、风扇、cpu、内存的textfsm和信息获取


代码如下:

import threading
import time
import os
from openpyxl import Workbook
from openpyxl.styles import Color, PatternFill, Font, Border, Side 
from netmiko import ConnectHandler
import json

'''
多线程并发查询华三交换version,并写入同一表格内。
0.2 加入电源和风扇的参数。
0.3 计划使用字典传递命令和存储结果的列表清单。
'''

os.chdir(os.path.dirname(__file__))			#将当前py文件路径设置为工作路径。
wb=Workbook()
filetime=time.strftime('%Y-%m-%d_%H-%M-%S')   #以开始时间作为表格文件名;

# 定义表格样式:
yellowFill = PatternFill(start_color='FFFF00', end_color='FFFF00', fill_type='solid')
RedRill = PatternFill(start_color='FF0000', end_color='9AFE2E', fill_type='solid')
thin_border = Border(left=Side(style='thin'), right=Side(style='thin'), top=Side(style='thin'), bottom=Side(style='thin'))

def getDevList(FilePath):   # 获取设备列表。输入文件路径,返回设备列表devList;
    f=open(FilePath)
    devList=[]
    for line in f.readlines():
        fLine=line.strip()
        sw={
            'device_type': fLine.split('---')[5],
            'ip': fLine.split('---')[2],
            'username': fLine.split('---')[3],
            'password': fLine.split('---')[4],
            'SNum': fLine.split('---')[0],
            'DevName': fLine.split('---')[1]
        }
        devList.append(sw)
    f.close

    return devList

def GetDevInfo(devList, ComOutDict):		# 巡检获取信息。传递设备列表,"命令:输出"的字典;返回设备信息;
    SW2={
        'device_type': devList['device_type'],
        'ip': devList['ip'],
        'username': devList['username'],
        'password': devList['password']
    }
    #使用netmiko连接设备:
    connect = ConnectHandler(**SW2)
    print('成功连接到设备 '+SW2['ip'])
    
    for key in ComOutDict:
        version = connect.send_command(key, use_textfsm=True)  #从字典中获取“命令”;
        DevOutList=ComOutDict.get(key)                         #从字典中获取存储输出的“列表”;
        RList=[devList['SNum'], devList['DevName'], devList['ip']]  #每设备初始列表增加“序号、设备名、IP”;

        list1=json.loads(json.dumps(version, indent=2))     #将命令输出的json字符串转为python对象;

        for dict in list1:      #遍历命令输出,追加到列表中;
            for item in dict:
                RList.append(dict.get(item))
        print(key,' : ',RList)
        DevOutList.append(RList)

def VersionExcel(InfoList):        #定义版本输出表格。传入设备信息列表;
    ws=wb.active
    ws.title='Version'

    list_title=['序号','设备名','设备IP','设备版本','小版本','设备型号','本次运行时长','上次重启原因']
    ws.append(list_title)

    for Rows in InfoList:       #将信息写入表格中;
        ws.append(Rows)

    for cells in ws[1]:         #为第一行增加色彩填充;
        cells.fill=yellowFill

    for cell in ws['G']:
        if '0 week' in str(cell.value).lower():     #判断单元格内容是否有“0 week”,如果有,就修改单元格样式;
            cell.fill=RedRill

    for row in ws.rows:         #为所有单元格增加边框; 
        for cells in row:
            cells.border=thin_border
            
    ws.column_dimensions['A'].width=5       #调整列宽;
    ws.column_dimensions['B'].width=25      #调整列宽;
    ws.column_dimensions['C'].width=18      #调整列宽;
    ws.column_dimensions['D'].width=10
    ws.column_dimensions['E'].width=14
    ws.column_dimensions['F'].width=20
    ws.column_dimensions['G'].width=40
    ws.column_dimensions['H'].width=15

def MultiThread(DevFile):          #多线程函数,定义巡检命令和保存设备输出信息的列表。输入设备信息txt,输出设备信息列表;
    DevList=getDevList(DevFile)
    Threads=[]

    VersList=[]         #保存设备输出信息的初始空列表;
    PowerList=[]
    FanList=[]
    CpuList=[]
    MemList=[]
    
    ComOutDict={        #定义传递给巡检函数的命令和列表;
        'disp version':VersList,
        'disp power':PowerList,
        'disp fan':FanList,
        'disp cpu':CpuList,
        'disp memory':MemList,
    }

    for i in DevList:
        t=threading.Thread(target=GetDevInfo, args=(i, ComOutDict))
        t.start()
        Threads.append(t)

    for i in Threads:
        i.join()

    return VersList,PowerList,FanList,CpuList,MemList

# print(VersList)
'''
输出为:
[['192.168.56.14', '7.1.075', 'Alpha 7571', 'S5820V2-54QS-GE', '0 weeks, 0 days, 1 hour, 3 minutes', 'User reboot'], 
['192.168.56.13', '7.1.075', 'Alpha 7571', 'S5820V2-54QS-GE', '0 weeks, 0 days, 1 hour, 4 minutes', 'User reboot'], 
['192.168.56.15', '7.1.075', 'Alpha 7571', 'S5820V2-54QS-GE', '0 weeks, 0 days, 1 hour, 3 minutes', 'User reboot'], 
['192.168.56.12', '7.1.075', 'Alpha 7571', 'S5820V2-54QS-GE', '0 weeks, 0 days, 1 hour, 3 minutes', 'User reboot'], 
['192.168.56.11', '7.1.075', 'Alpha 7571', 'S5820V2-54QS-GE', '0 weeks, 0 days, 1 hour, 4 minutes', 'User reboot']]
'''

def main(DevFile, OutFile):
    print('从文件 ' + DevFile + ' 中读取设备信息,并尝试连接。')
    VersList,PowerList,FanList,CpuList,MemList=MultiThread(DevFile)      #使用多线程获取设备信息;
    print('表格信息写入中。')
    VersionExcel(VersList)        #使用单线程将设备信息写入表格;
    wb.save(OutFile)
    print('表格信息写入完成,名为:', OutFile)
    print('PowerStatus:',PowerList,'\n\nFanStatus:',FanList,'\n\nCpuStatus:',CpuList,'\n\nMemStatus:',MemList,)

if __name__=='__main__':
    '''
    第一个参数为设备地址和用户等信息,第二个参数为要输出的excel文件名:
    '''
    main('../ip_list.txt', 'test_Get_Version211113.xlsx')

信息输出如下:

从文件 ../ip_list.txt 中读取设备信息,并尝试连接。
成功连接到设备 192.168.56.12
成功连接到设备 192.168.56.11
成功连接到设备 192.168.56.14
成功连接到设备 192.168.56.15
成功连接到设备 192.168.56.13
disp version  :  ['2', 'DevName-2', '192.168.56.12', '7.1.075', 'Alpha 7571', 'S5820V2-54QS-GE', '0 weeks, 0 days, 0 hours, 23 minutes', 'User reboot']
disp version  :  ['1', 'DevName-1', '192.168.56.11', '7.1.075', 'Alpha 7571', 'S5820V2-54QS-GE', '0 weeks, 0 days, 0 hours, 23 minutes', 'User reboot']
disp version  :  ['4', 'DevName-4', '192.168.56.14', '7.1.075', 'Alpha 7571', 'S5820V2-54QS-GE', '0 weeks, 0 days, 0 hours, 23 minutes', 'User reboot']
disp version  :  ['5', 'DevName-5', '192.168.56.15', '7.1.075', 'Alpha 7571', 'S5820V2-54QS-GE', '0 weeks, 0 days, 0 hours, 23 minutes', 'User reboot']
disp version  :  ['3', 'DevName-3', '192.168.56.13', '7.1.075', 'Alpha 7571', 'S5820V2-54QS-GE', '0 weeks, 0 days, 0 hours, 23 minutes', 'User reboot']
disp power  :  ['1', 'DevName-1', '192.168.56.11', '1', 'Normal', '2', 'Normal']
disp power  :  ['4', 'DevName-4', '192.168.56.14', '1', 'Normal', '2', 'Normal']
disp power  :  ['2', 'DevName-2', '192.168.56.12', '1', 'Normal', '2', 'Normal']
disp power  :  ['5', 'DevName-5', '192.168.56.15', '1', 'Normal', '2', 'Normal']
disp power  :  ['3', 'DevName-3', '192.168.56.13', '1', 'Normal', '2', 'Normal']
disp fan  :  ['1', 'DevName-1', '192.168.56.11', '1', 'Normal', '2', 'Normal']
disp fan  :  ['2', 'DevName-2', '192.168.56.12', '1', 'Normal', '2', 'Normal']
disp fan  :  ['4', 'DevName-4', '192.168.56.14', '1', 'Normal', '2', 'Normal']
disp fan  :  ['5', 'DevName-5', '192.168.56.15', '1', 'Normal', '2', 'Normal']
disp fan  :  ['3', 'DevName-3', '192.168.56.13', '1', 'Normal', '2', 'Normal']
disp cpu  :  ['4', 'DevName-4', '192.168.56.14', '1', '0', '0', '0', '0']
disp cpu  :  ['2', 'DevName-2', '192.168.56.12', '1', '0', '1', '0', '0']
disp cpu  :  ['1', 'DevName-1', '192.168.56.11', '1', '0', '0', '0', '0']
disp cpu  :  ['5', 'DevName-5', '192.168.56.15', '1', '0', '0', '0', '0']
disp cpu  :  ['3', 'DevName-3', '192.168.56.13', '1', '0', '0', '0', '0']
disp memory  :  ['2', 'DevName-2', '192.168.56.12', '1', '512172', '305400', '40.4%']
disp memory  :  ['4', 'DevName-4', '192.168.56.14', '1', '512172', '296240', '42.2%']
disp memory  :  ['1', 'DevName-1', '192.168.56.11', '1', '512172', '294576', '42.6%']
disp memory  :  ['5', 'DevName-5', '192.168.56.15', '1', '512172', '296616', '42.1%']
disp memory  :  ['3', 'DevName-3', '192.168.56.13', '1', '512172', '299448', '41.6%']
表格信息写入中。
表格信息写入完成,名为: test_Get_Version211113.xlsx

posted @   飞飞6779  阅读(1377)  评论(0编辑  收藏  举报
编辑推荐:
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异
· 三行代码完成国际化适配,妙~啊~
点击右上角即可分享
微信分享提示