网工Python之路之Netmiko+excle定时检测接口状态

admin 2022年10月19日11:27:49评论101 views字数 17804阅读59分20秒阅读模式

转载:知乎枫岚 

链接:https://zhuanlan.zhihu.com/p/566642937

网工Python之路之Netmiko+excle定时检测接口状态

往期回顾:

基础笔记:

网工Python之路之基础笔记(一)

网工Python之路之基础笔记(二)

paramiko模块实验:
网工Python之路之paramiko 模块实验(一)初来乍到
网工Python之路之paramiko 模块实验(二)循环遍历
网工Python之路之paramiko 模块实验(三)读取文件
网工Python之路之paramiko 模块实验(四)分组操作
网工Python之路之paramiko 模块实验(五)异常处理
网工Python之路之paramiko 模块实验(六)FTP推送备份文件
网工Python之路之paramiko 模块实验(七)回显保存成文件,Win中处理空行  

netmiko模块实验:

网工Python之路之netmiko模块实验(一)初来乍到
网工Python之路之netmiko模块实验(二)推送配置

      网工Python之路之netmiko模块实验(三)连接多机

python实用脚本:

【实用】python网络运维工具包
【实用】用Python实现快速Ping一个IP网段地址
python实用脚本:网络设备批量调试及备份
简单的Python脚本,实现批量设置重复性配置
简单的Python脚本,实现ssh登录配置路由器

Python通过FTP备份华为交换机配置文件

Python 网络自动化:批量备份网络设备配置文件

【实用工具】自动备份多品牌网络设备配置

【实用】网络工程师脚本批量生成工具

【实用】网络设备巡检的重要性!附工具

【实用】python网络运维工具包

【实用工具】网络自动化运维工具NetCfgTools

【大佬原创】cvTools超融合自动化运维工具

简单的Python端口扫描工具制作

Python GUI界面版端口扫描工具

一、前言:
在本人看着群里的大佬纷纷分享自己的文章和一些运维思路,深知只有用出来,写出来,分享出来,跟大家一起交流,这个程序和学习到的新知识才算真正掌握了。在这里非常感谢王印王老师 @弈心、朱嘉盛老师 @朱嘉盛以及群里的各位大佬不遗余力地分享着自己的文章。针对python的学习主要源于他们的专栏。

二、实验背景:

前一段时间,机房刚刚建完,但是弱电做的网线不太行,出现两次网线问题,这不是要了命了么。领导说,想办法如果交换机网线出问题了你得能知道。我想说,咱们用个运维平台不行吗,我又想我们今年手里的服务器资源只剩下4核,6G了。
行,那就写个脚本吧。本次实验以H3C设备为基础。

就是说写一个只要接口状态发生变化就能有邮件通知你,而且还有excle作为佐证。

我认为本次实验仅仅适用于十几二十台小环境的网络。(而且有点钱上个平台不比嘛强)

三、需求分析

首先首次使用脚本之后,excle里工作表收集的都是当前所有设备的UP的接口。

网工Python之路之Netmiko+excle定时检测接口状态

工作簿底下的工作表的是所有设备,以命名+IP的形式存在。

网工Python之路之Netmiko+excle定时检测接口状态

工作簿底下是所有的设备

然后如果有一个接口的状态出现了变化,只要有变化,Link这一列对应的状态就会变色,还会发邮件以工作簿为附件。

网工Python之路之Netmiko+excle定时检测接口状态

网工Python之路之Netmiko+excle定时检测接口状态

如果你是就想人为规划断开这个接口,不是链路的损坏,那么在下次执行这个脚本的时候,不是UP接口就不存在了。

网工Python之路之Netmiko+excle定时检测接口状态

如果这个接口从ADM状态又回复为UP,那么也会发邮件,并且携带工作簿为附件。

网工Python之路之Netmiko+excle定时检测接口状态

网工Python之路之Netmiko+excle定时检测接口状态

最后设置成1分钟执行一次,放在服务器里。

每次执行程序只会维护第一次执行程序输出的这一张表,所以不用担心文件太多。

三、代码分析

3.1完整代码

先上完整代码,然后再进行分析。

# coding=gbk
import re
import smtplib
import threading
import time
from email.mime.application import MIMEApplication
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from pprint import pprint
from queue import Queue

from netmiko import ConnectHandler
from openpyxl.reader.excel import load_workbook
from openpyxl.workbook import Workbook
from openpyxl.styles import PatternFill, Border, Side, Font

threads=[]#用于多线程
ip_list=open('ip_file.txt')#IP地址先行放入文件中
dims = {}#用于对工作表中自动设置最大行宽
content=""#用于输出在邮箱中的内容
def ssh_seesion(ip, ouput,):
    global content, sheet
    # 这几个列表是写入工作表的先行条件,也就是工作表的每一列,先把想写入工作表的每一列的内容写入列表,然后再遍历列表把内容写入工作表
    interface_list = []
    link_list = []
    speed_list = []
    description_list = []

    connection_info = {'device_type':'hp_comware',
          'ip':ip,
          'username':'xxxxx',
          'password':'xxxxxx'}

    with ConnectHandler(**connection_info) as conn:
        output = conn.send_command("display interface brief",use_textfsm=True)
        sysname = conn.send_command('display current-configuration | include sysname ')
        name = re.search(r's+S+s+(S+)', sysname).groups()[0]
        #pprint(output)

    try:
        sheet = wb[name + '_' + ip]#调用自己的那一张表
        # 先给逼删了
        column_B = sheet['B']
        for i in column_B:
            # print(i.value)
            if i.value not in ('Link''UP'):
                num = re.search('d+', i.coordinate).group()  # 找到需要删的那一行
                print(num)
                sheet.delete_rows(int(num))
    except:
        pass

    #取出接口up的
    for i in output:
        if i.get('link')=='UP':
            interface_list.append(i.get('interface'))
            link_list.append(i.get('link'))
            speed_list.append(i.get('speed'))
            description_list.append(i.get('description'))
            # 判断这次interface跟上次也就是表格里的有没有区别 以是否是UP的为前提 不是UP的或者多了UP的 或者少了UP的 只要变化就要被记录


    if str(name + '_' + ip) in wb.sheetnames:  # 如果这个表存在 就让里原本有的接口进入列表
        sheet_pre = wb[name + '_' + ip]
        column_A = sheet_pre['A']#取出以前的表的第一列
        sheet_pre_A1 = [i.value for i in column_A]
        sheet_pre_A1.remove('Interfaces')#遍历第一列的时候会有抬头也就是Interfaces' 需要把这个去掉
        #print(sheet_pre_A1)#sheet_pre_A1里是上一次表格里有的接口列表
        #print(interface_list)#interface_list里是这一次想放入表格里的UP的接口的列表
        #取出两个列表的差集,这个差集是现在UP的和表里的差集
        sheet_dif=list(set(sheet_pre_A1)^(set(interface_list)))#把两个表中 变化的接口 放入sheet_dif这个列表里
        print(sheet_dif)#至此有变化的且不是UP的接口就进入列表了
        if len(sheet_dif)!=0:#如果这个列表里有数据就发邮箱
            content=content+f"{name}{str(sheet_dif)}接口发生了变化n'"#配合发邮件的

        for i in output:#为了把差集的接口情况写入列表
            for p in sheet_dif:
                if p == i.get('interface'and i.get('link')!='UP':#找到这个不是UP的接口 各种情况还写进去
                    interface_list.append(i.get('interface'))
                    link_list.append(i.get('link'))
                    speed_list.append(i.get('speed'))
                    description_list.append(i.get('description'))
                    content=content+i.get('interface')+'接口由UP变成了'+i.get('link')+'n'
                elif p == i.get('interface'and i.get('link') == 'UP':
                    content = content + i.get('interface') + '接口UP了'+'n'


    font = Font(name="微软雅黑",bold=True)#字体加粗
    yellowFill = PatternFill(start_color='FFFF00', end_color='FFFF00', fill_type='solid')#黄色
    thin_border = Border(left=Side(style='thin'), right=Side(style='thin'), top=Side(style='thin'),
                         bottom=Side(style='thin'))#有边框
    SpringGreen = PatternFill(start_color='3CB371', end_color='3CB371', fill_type='solid')  # 黄色

    if str(name + '_' + ip) in wb.sheetnames:#如果表格存在直接往里写
        row_numbers = list(range(2, len(output) + 2))  # 只能从第二行开始
        for interface, row in zip(interface_list, row_numbers):
            sheet.cell(row=row, column=1, value=interface)
        for link, row in zip(link_list, row_numbers):
            sheet.cell(row=row, column=2, value=link)
        for speed, row in zip(speed_list, row_numbers):
            sheet.cell(row=row, column=3, value=speed)
        for description, row in zip(description_list, row_numbers):
            sheet.cell(row=row, column=4, value=description)

        # 往里写完之后 查看B1这列 然后找到不是UP的 给赋值绿色
        column_B = sheet['B']
        for i in column_B:
            #print(i.value)
            if i.value not in ('Link','UP'):
                print(i.coordinate)#查找到接口有问题的坐标
                sheet[i.coordinate].fill = SpringGreen


    else:#如果表格不存在则创建表格
        sheet=wb.create_sheet(name+'_'+ip)#这里的sheet相当于JT-6-1F-DAS-1这个表格
        columns=['A1','B1','C1','D1']
        cells=['Interfaces','Link','Speed','Description']
        for i,p in zip(columns,cells):
        #放入表格中
            sheet[i] = p
            sheet[i].fill=yellowFill
            sheet[i].font=font

        row_numbers = list(range(2, len(output) + 2))  # 只能从第二行开始
        for interface, row in zip(interface_list, row_numbers):
            sheet.cell(row=row, column=1, value=interface)
        for link, row in zip(link_list, row_numbers):
            sheet.cell(row=row, column=2, value=link)
        for speed, row in zip(speed_list, row_numbers):
            sheet.cell(row=row, column=3, value=speed)
        for description, row in zip(description_list, row_numbers):
            sheet.cell(row=row, column=4, value=description)


    for row in sheet.rows:
        #print(row)
        for cell in row:
            #print(cell.value)
            cell.border = thin_border
            if cell.value:
                dims[cell.column_letter] = max((dims.get(cell.column_letter, 0), len(str(cell.value))))

    for col, value in dims.items():
        sheet.column_dimensions[col].width = value + 3


def send_email(sender,receicer,password,content):
    # 这份代码比较标准了,可以直接用了

    # 发件人邮箱
    sender = sender
    # 收件人邮箱
    receiver = receicer
    # 抄送人邮箱
    #acc = '[email protected]'
    # 邮件主题
    subject = '服务器运行情况'

    # 邮箱密码(授权码)
    password = password

    # 邮件设置
    msg = MIMEMultipart()
    msg['Subject'] = subject  # 主题
    msg['to'] = receiver  # 接收者
    #msg['acc']=acc#抄送者
    msg['from'] = "信息化员工"  # 发件人

    # 邮件正文
    content = content

    # 添加邮件正文:
    msg.attach(MIMEText(content, 'plain''utf-8'))  # content是正文内容,plain即格式为正文,utf-8是编码格式

    # 添加附件
    # 注意这里的文件路径是斜杠
    file_name = r'E:pythontesttest功能脚本接口up_downtest_openpyxl.xlsx'
    file_name_list = file_name.split('\')[-1]  # 获得文件的名字
    xlsxpart = MIMEApplication(open(file_name, 'rb').read())
    xlsxpart.add_header('Content-Disposition''attachment', filename=file_name_list)
    # 服务端向客户端游览器发送文件时,如果是浏览器支持的文件类型,一般会默认使用浏览器打开,比如txt、jpg等,会直接在浏览器中显示,如果需要提示用户保存,就要利用Content-Disposition进行一下处理,关键在于一定要加上attachment
    msg.attach(xlsxpart)

    # 设置邮箱服务器地址以及端口
    smtp_server = "smtp.qq.com"
    smtp = smtplib.SMTP(smtp_server,25)  # 'smtp.qq.com'是QQ邮箱发邮件的服务器,用新浪邮箱就是'smtp.sina.com',就是smtp加上你们邮箱账号@符号后面的内容。端口默认是25。
    #smtp.set_debuglevel(1)  # 显示出交互信息

    # 登陆邮箱
    smtp.login(sender, password)

    # 发送邮件
    smtp.sendmail(sender, receiver.split(',') , msg.as_string())
    # receiver.split(',')+acc.split(',')是['[email protected]', '[email protected]']

    # 断开服务器链接
    smtp.quit()

print(f"程序于{time.strftime('%X')} 执行开始n")
#记录开始时间
start_time = time.time()

#注意逻辑关系 先创建工作簿 再进入多线程 最后保存工作簿
try:#如果存在这个表格就直接打开,如果部存在就创建
    wb = load_workbook('test_openpyxl.xlsx')
    ws = wb.active
except:# 创建表格 如果存在 就不创建
    wb = Workbook()
    wb.remove(wb['Sheet'])
    ws = wb.active

for ips in ip_list.readlines():
    t=threading.Thread(target=ssh_seesion,args=(ips.strip(),Queue()))
    t.start()
    threads.append(t)


for i in threads:
    i.join()
    #加入检查功能


if len(content)!=0:
    print(content)
    send_email("[email protected]""[email protected]""jveyorpbogllijhj",content)


end_time = time.time()-start_time

wb.save('test_openpyxl.xlsx')  # 保存工作表
print (f'总共耗时{round(end_time,2)}秒')
print(f"程序于{time.strftime('%X')} 执行结束n")
TestFSM模板
Value Interface (S+)
Value Link (UP|DOWN|ADM|Stby)
Value Speed (.*G|auto)
Value Description (S+|s+)

Start
  ^s*$
{Interface}s+${Link}s+${Speed}((a)|s*)+s+S+s+S+s+S+s+${Description} -> Record

3.2分析

特别详细的分析写在了代码的注释中。这里只是对思路的分析。

首先就是登录设备,然后调用TestFSM模板做解析,再取出设备的名字。use_textfsm=True的用法参照朱嘉盛:《网络工程师的Python之路》(nornir实验10,联动Textfsm,ntc-template,华为)

def ssh_seesion(ip, ouput,):
    global content, sheet
    # 这几个列表是写入工作表的先行条件,也就是工作表的每一列,先把想写入工作表的每一列的内容写入列表,然后再遍历列表把内容写入工作表
    interface_list = []
    link_list = []
    speed_list = []
    description_list = []

    connection_info = {'device_type':'hp_comware',
          'ip':ip,
          'username':'xxxxxx',
          'password':'123'}

    with ConnectHandler(**connection_info) as conn:
        output = conn.send_command("display interface brief",use_textfsm=True)
        sysname = conn.send_command('display current-configuration | include sysname ')
        name = re.search(r's+S+s+(S+)', sysname).groups()[0]
        #pprint(output)

首先明确这个脚本是一分钟执行一次,然后是在工作簿中找到此次登录的设备的工作表,然后对其进行删除操作,删除工作表中存在的不是UP的接口的那一行,因为这个工作簿的目的是存接口为UP的接口的信息,那么之前存在不是UP的接口的内个工作簿呢?通过邮箱发出来了。因为如果第一次执行这个程序,那么肯定不存在这个表,所以用个try……except。

i.coordinate用来获取一个格子的坐标的。比如输出结果就是B11这样。

try:
        sheet = wb[name + '_' + ip]#调用自己的那一张表
        # 先给逼删了
        column_B = sheet['B']
        for i in column_B:
            # print(i.value)
            if i.value not in ('Link''UP'):
                num = re.search('d+', i.coordinate).group() # 找到需要删的那一行
                print(num)
                sheet.delete_rows(int(num))
    except:
        passtry:
        sheet = wb[name + '_' + ip]#调用自己的那一张表
        # 先给逼删了
        column_B = sheet['B']
        for i in column_B:
            # print(i.value)
            if i.value not in ('Link''UP'):
                num = re.search('d+', i.coordinate).group() # 找到需要删的那一行
                print(num)
                sheet.delete_rows(int(num))
    except:
        pass
def ssh_seesion(ip, ouput,):
    global content, sheet
    # 这几个列表是写入工作表的先行条件,也就是工作表的每一列,先把想写入工作表的每一列的内容写入列表,然后再遍历列表把内容写入工作表
    interface_list = []
    link_list = []
    speed_list = []
    description_list = []

    connection_info = {'device_type':'hp_comware',
          'ip':ip,
          'username':'xxxxxx',
          'password':'123'}

    with ConnectHandler(**connection_info) as conn:
        output = conn.send_command("display interface brief",use_textfsm=True)
        sysname = conn.send_command('display current-configuration | include sysname ')
        name = re.search(r's+S+s+(S+)', sysname).groups()[0]
        #pprint(output)
然后取出接口为UP的接口的信息,放入表格中,因为这个工作簿的目的是存接口为UP的接口的信息。
#取出接口up的
    for i in output:
        if i.get('link')=='UP':
            interface_list.append(i.get('interface'))
            link_list.append(i.get('link'))
            speed_list.append(i.get('speed'))
            description_list.append(i.get('description'))
            # 判断这次interface跟上次也就是表格里的有没有区别 以是否是UP的为前提 不是UP的或者多了UP的 或者少了UP的 只要变化就要被记录

再然后就是把表中原有的接口记录在sheet_pre_A1这个例表中,然后与刚才新构成的接口全为UP的列表interface_list取差集,差集包含什么?包含可能有新接口UP了,可能有旧接口不UP了。如果差集中有接口,就写入content中,为了发邮箱用。

然后判断差集里面接口的状态,是又其他状态变为UP,还是由UP变为了其他状态。还是写如content中,发邮箱用。

 if str(name + '_' + ip) in wb.sheetnames:  # 如果这个表存在 就让里原本有的接口进入列表
        sheet_pre = wb[name + '_' + ip]
        column_A = sheet_pre['A']#取出以前的表的第一列
        sheet_pre_A1 = [i.value for i in column_A]
        sheet_pre_A1.remove('Interfaces')#遍历第一列的时候会有抬头也就是Interfaces' 需要把这个去掉
        #print(sheet_pre_A1)#sheet_pre_A1里是上一次表格里有的接口列表
        #print(interface_list)#interface_list里是这一次想放入表格里的UP的接口的列表
        #取出两个列表的差集,这个差集是现在UP的和表里的差集
        sheet_dif=list(set(sheet_pre_A1)^(set(interface_list)))#把两个表中 变化的接口 放入sheet_dif这个列表里
        print(sheet_dif)#至此有变化的且不是UP的接口就进入列表了
        if len(sheet_dif)!=0:#如果这个列表里有数据就发邮箱
            content=content+f"{name}{str(sheet_dif)}接口发生了变化n'"#配合发邮件的

        for i in output:#为了把差集的接口情况写入列表
            for p in sheet_dif:
                if p == i.get('interface'and i.get('link')!='UP':#找到这个不是UP的接口 各种情况还写进去
                    interface_list.append(i.get('interface'))
                    link_list.append(i.get('link'))
                    speed_list.append(i.get('speed'))
                    description_list.append(i.get('description'))
                    content=content+i.get('interface')+'接口由UP变成了'+i.get('link')+'n'
                elif p == i.get('interface'and i.get('link') == 'UP':
                    content = content + i.get('interface') + '接口UP了'+'n'
第一行加粗并且黄色,有状态变化的那一格是绿色。
font = Font(name="微软雅黑",bold=True)#字体加粗
    yellowFill = PatternFill(start_color='FFFF00', end_color='FFFF00', fill_type='solid')#黄色
    thin_border = Border(left=Side(style='thin'), right=Side(style='thin'), top=Side(style='thin'),
                         bottom=Side(style='thin'))#有边框
    SpringGreen = PatternFill(start_color='3CB371', end_color='3CB371', fill_type='solid')  # 黄色
然后开始往工作表里写东西,如果工作表存在,那么直接写,相当于覆盖。
写完之后查看B1这一列,也就是Link这一列,不是UP的给赋值绿色。
if str(name + '_' + ip) in wb.sheetnames:#如果表格存在直接往里写
        #在写之前先删除    # 去表格里找,如果检测到上次接口不是up则把这个接口删掉,不是从python的列表里删掉,直接从表格里删掉

        row_numbers = list(range(2, len(output) + 2))  # 只能从第二行开始
        for interface, row in zip(interface_list, row_numbers):
            sheet.cell(row=row, column=1, value=interface)
        for link, row in zip(link_list, row_numbers):
            sheet.cell(row=row, column=2, value=link)
        for speed, row in zip(speed_list, row_numbers):
            sheet.cell(row=row, column=3, value=speed)
        for description, row in zip(description_list, row_numbers):
            sheet.cell(row=row, column=4, value=description)
        # 往里写完之后 查看B1这列 然后找到不是UP的 给赋值绿色
        column_B = sheet['B']
        for i in column_B:
            #print(i.value)
            if i.value not in ('Link','UP'):
                print(i.coordinate)#查找到接口有问题的坐标
                sheet[i.coordinate].fill = SpringGreen
如果表格不存在则创建表格再往里写,服务于第一次执行程序
else:#如果表格不存在则创建表格
        sheet=wb.create_sheet(name+'_'+ip)#这里的sheet相当于JT-6-1F-DAS-1这个表格
        columns=['A1','B1','C1','D1']
        cells=['Interfaces','Link','Speed','Description']
        for i,p in zip(columns,cells):
        #放入表格中
            sheet[i] = p
            sheet[i].fill=yellowFill
            sheet[i].font=font

        row_numbers = list(range(2, len(output) + 2))  # 只能从第二行开始
        for interface, row in zip(interface_list, row_numbers):
            sheet.cell(row=row, column=1, value=interface)
        for link, row in zip(link_list, row_numbers):
            sheet.cell(row=row, column=2, value=link)
        for speed, row in zip(speed_list, row_numbers):
            sheet.cell(row=row, column=3, value=speed)
        for description, row in zip(description_list, row_numbers):
            sheet.cell(row=row, column=4, value=description)
一段以一列中最宽的一格为标准,自动变换列宽的代码
  for row in sheet.rows:
        #print(row)
        for cell in row:
            #print(cell.value)
            cell.border = thin_border
            if cell.value:
                dims[cell.column_letter] = max((dims.get(cell.column_letter, 0), len(str(cell.value))))

    for col, value in dims.items():
        sheet.column_dimensions[col].width = value + 3
然后是发邮件的函数,就不做过多介绍了
  def send_email(sender,receicer,password,content):

最后执行主函数

先是创建工作簿,因为可能工作簿已经存在了,所以用try,然后用了多线程快一点,再然后判断content里是否有内容,只要接口发生了状态变化content中就有变化,content有变化就发邮件,邮件附件是工作簿。

  print(f"程序于{time.strftime('%X')} 执行开始n")
#记录开始时间
start_time = time.time()

#注意逻辑关系 先创建工作簿 再进入多线程 最后保存工作簿
try:#如果存在这个表格就直接打开,如果部存在就创建
    wb = load_workbook('test_openpyxl.xlsx')
    ws = wb.active
except:# 创建表格 如果存在 就不创建
    wb = Workbook()
    wb.remove(wb['Sheet'])
    ws = wb.active

for ips in ip_list.readlines():
    t=threading.Thread(target=ssh_seesion,args=(ips.strip(),Queue()))
    t.start()
    threads.append(t)


for i in threads:
    i.join()
    #加入检查功能


if len(content)!=0:
    print(content)
    send_email("[email protected]""[email protected]""jveyorpbogllijhj",content)


end_time = time.time()-start_time

wb.save('test_openpyxl.xlsx')  # 保存工作表
print (f'总共耗时{round(end_time,2)}秒')
print(f"程序于{time.strftime('%X')} 执行结束n")

3.3思路合集

网工Python之路之Netmiko+excle定时检测接口状态

四、测试

首先用四个设备做测试

网工Python之路之Netmiko+excle定时检测接口状态

第一次执行成功输出工作簿,下面的工作表示以名字_ip展现

网工Python之路之Netmiko+excle定时检测接口状态

然后然别断开两个设备的两个接口之后再执行一次程序

网工Python之路之Netmiko+excle定时检测接口状态

网工Python之路之Netmiko+excle定时检测接口状态

如果此时你就是想把这个接口认为donw掉,然后再执行一次程序,也不会有邮件发出,down掉的接口的那一行也被删除了

网工Python之路之Netmiko+excle定时检测接口状态

如果此时接口恢复UP,会发邮件通知,而且UP的接口也进入到工作表中了。

网工Python之路之Netmiko+excle定时检测接口状态

网工Python之路之Netmiko+excle定时检测接口状态

五、总结

最后把这个脚本仍在服务器里,一分钟执行一次,这样一个低成本的监控交换机接口状态变化的脚本就写完了,其实还有点小问题,比如果接口状态不是up了,在输出工作表时,不是UP的那一行就变为了最后一行。

在上大学有一门课叫软件工程,我记得老师教的一句话是”程序开发时要高内聚,低耦合。”然后再看一眼我的代码,真的是有些丑陋,写程序时常常思维不清晰,逻辑不准确。反正,这个脚本在我们现有的网络里能用。

套用群里大佬的一个表情包

网工Python之路之Netmiko+excle定时检测接口状态

【欢迎来稿】:

本公众号宗旨是一个公益性的平台,属于大家锻炼的平台,不能只展示我个人的,所以欢迎有才华的人士来稿。
大家写文档投稿,也需要占用一定的个人时间,且现在的生活节奏较快,能乐于分享,牺牲自己的宝贵时间,真的很难得。所以,小编决定根据个人经济情况及投稿文章质量,每次投稿,打赏的稿费定在5元-50元之间,请有兴趣者,不要介意钱太少,或者也可以采用赠送书籍的形式。

来稿邮箱:[email protected](也可添加小编微信:ShiRan_ZT)

来稿声明:须自己本人原创,否则后果自行承担。未在其他平台发布过。


边学边练,真正掌握使用uni-app开发项目

网工Python之路之Netmiko+excle定时检测接口状态

网工Python之路之Netmiko+excle定时检测接口状态

网工Python之路之Netmiko+excle定时检测接口状态

原文始发于微信公众号(释然IT杂谈):网工Python之路之Netmiko+excle定时检测接口状态

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2022年10月19日11:27:49
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   网工Python之路之Netmiko+excle定时检测接口状态http://cn-sec.com/archives/1358182.html

发表评论

匿名网友 填写信息