首页 > 其他分享 >netmiko+textfsm自动统计交换机端口模块型号数量与闲置模块

netmiko+textfsm自动统计交换机端口模块型号数量与闲置模块

时间:2022-12-11 10:55:49浏览次数:59  
标签:verbose netmiko db 模块 print eth textfsm 1000BASE port

统计和查找交换机模块是件很费时费力的事情,特别是需要掌握库存数量时,成百上千块模块一块一块统计没有两天的时间是不行的,且统计出的数据需要一定的格式化才能便捷的录入数据库

为此可以用netmiko模块自动执行命令,返回结果用textfsm来解析格式话,基于这两个模块以盛科交换机为对象做出了以下脚本

 

脚本运行环境

python 3.7 以上

netmiko 4.1.2

盛科交换机

 

安装netmiko,4.1.2版本会自动安装textfsm,ntc_templates

ntc_templates路径 /usr/local/lib/python3.8/dist-packages/ntc_templates 后面会用到

脚本如下

 

#!/usr/bin/env python
#-*-coding:utf-8-*-
from collections import Counter
from netmiko import ConnectHandler
import getpass,json,sys
def Module(host,username,port=22,verbose=False):
    passwd = getpass.getpass()
    ModuleCount = []
    ModuleStatus = {'free':[],'line':[]}
    portstatus = {}
    dev = {'device_type': 'centec_os',
        'host': host,
        'username': username,
        'password': passwd,
        'port': 22}
    with ConnectHandler(**dev) as conn:
        PortTran = conn.send_command('show transceiver detail',use_textfsm=True)
        ret = json.dumps(PortTran,indent=2)
        PortStatus = conn.send_command('show interface status',use_textfsm=True)
        for x in PortStatus:
            portstatus[x['port']]=x['status']
    if  verbose : print(ret) 
    for port in PortTran:
        flag = True if portstatus[port['port']] == 'up' else False
        info = ' '.join([port['moduletype'],port['wavelength'],port['linklength']])
        ModuleCount.append(info)
        db = port['db']
        if flag or(db and db!='-40.00'):
            ModuleStatus['line'].append(port['port']+' '+port['moduletype'])
        else:
            ModuleStatus['free'].append(port['port']+' '+port['moduletype'])
    ModuleCount = json.dumps(Counter(ModuleCount),indent=2)
    ModuleStatus = json.dumps(ModuleStatus,indent=2)
    return ModuleCount,ModuleStatus
if __name__ == '__main__':
    try:
        host,username = sys.argv[1],sys.argv[2]
        try:
            verbose = sys.argv[3]
            verbose = True if verbose =='verbose' else False
        except:
            verbose = False
    except:
        print('usage:')
        print('    <host> <username> <port> <verbose>')
        print('options:')
        print('    host: <device_ip>')
        print('    username: <ssh user>')
        print('    port: <default 22>')
        print('    verbose: <default False>')
        print('examples:')
        print('    ./centec 10.0.0.1 dark verbose')
    try:
        ModuleCount,ModuleStatus=Module(host,username,verbose=verbose)
        print('------------------模块数量统计-----------------')
        print(ModuleCount)
        print('------------------模块状态统计-----------------')
        print(ModuleStatus)
    except Exception as e:
        print(e)

 

 


其中两个自定义textfsm文件如下,需要放进ntc_templates目录

Value port (eth\S+)
Value status (\S+)

Start
  ^${port}\s+${status} -> Record
interfaces.textfsm
Value port (\S+)
Value moduletype (\S+\s?\S+)
Value sn (\S+)
Value wavelength (\S+\s?\S+)
Value linklength (\S+\s?\S+)
Value db (\S+)

Start
  ^Port ${port} transceiver info:
  ^Transceiver Type: ${moduletype}
  ^\s+Transceiver S/N         :\s${sn}
  ^Transceiver Output Wavelength: ${wavelength}
  ^      Link Length.*:\s+${linklength}
  ^eth\S+\s+${db}
  ^$$ -> Record
ModuleInfo.textfsm

脚本使用方法

# ./cent.py 10.0.0.1 admin verbose
or
# ./cent.py 10.0.0.1 admin

以上脚本打包后运行也需要运行机器上安装ntc_templates适配性不是很好,我们可以改动下,手动加载textfsm文件,如下

#!/usr/bin/env python
#-*-coding:utf-8-*-
from collections import Counter
from netmiko import ConnectHandler
import getpass,json,sys,textfsm,os
def Module(host,username,verbose=False,port=22):
    BasePath = os.path.dirname(sys.argv[0])
    InterFaceFsm=BasePath+'/interfaces.textfsm'
    TranFsm=BasePath+'/ModuleInfo.textfsm'
    passwd = getpass.getpass()
    ModuleCount = []
    ModuleStatus = {'free':[],'line':[]}
    portstatus = {}
    dev = {'device_type': 'centec_os',
        'host': host,
        'username': username,
        'password': passwd,
        'port': 22}
    with ConnectHandler(**dev) as conn:
        PortTran = conn.send_command('show transceiver detail')
        
        PortStatus = conn.send_command('show interface status')
        with open(InterFaceFsm) as tem:
            fsm = textfsm.TextFSM(template=tem)
            PortStatus = fsm.ParseTextToDicts(PortStatus)
        with open(TranFsm) as tem:
            fsm = textfsm.TextFSM(template=tem)
            PortTran = fsm.ParseTextToDicts(PortTran)
    for x in PortStatus:
        portstatus[x['port']]=x['status']
    if verbose : print(json.dumps(PortTran,indent=2))
    for port in PortTran:
        flag = True if portstatus[port['port']] == 'up' else False
        info = ' '.join([port['moduletype'],port['wavelength'],port['linklength']])
        ModuleCount.append(info)
        db = port['db']
        if flag or(db and db!='-40.00'):
            ModuleStatus['line'].append(port['port']+' '+port['moduletype'])
        else:
            ModuleStatus['free'].append(port['port']+' '+port['moduletype'])
    ModuleCount = json.dumps(Counter(ModuleCount),indent=2)
    ModuleStatus = json.dumps(ModuleStatus,indent=2)
    return ModuleCount,ModuleStatus
if __name__ == '__main__':
    try:
        host,username = sys.argv[1],sys.argv[2]
        try:
            verbose = sys.argv[3]
            verbose = True if verbose =='verbose' else False
            print(verbose)
        except:
            verbose = False
        try:
            ModuleCount,ModuleStatus=Module(host,username,verbose=verbose)
            print('------------------模块数量统计-----------------')
            print(ModuleCount)
            print('------------------模块状态统计-----------------')
            print(ModuleStatus)
        except Exception as e:
            print(e)
    except:
        print('usage:')
        print('    <host> <username> <verbose>')
        print('options:')
        print('    host: <device_ip>')
        print('    username: <ssh user>')
        print('    verbose: <default False>')
        print('examples:')
        print('    ./centec 10.0.0.1 dark verbose')

 

执行效果,sn信息已遮挡

[
  {
    "port": "eth-0-1",
    "moduletype": "1000BASE-LX",
    "sn": "XXXXXX",
    "wavelength": "1310 nm",
    "linklength": "10 km",
    "db": "-10.57"
  },
  {
    "port": "eth-0-2",
    "moduletype": "1000BASE-T_SFP",
    "sn": "XXXXXX",
    "wavelength": "N/A",
    "linklength": "100 m",
    "db": ""
  },
  {
    "port": "eth-0-3",
    "moduletype": "1000BASE-T_SFP",
    "sn": "XXXXXX",
    "wavelength": "N/A",
    "linklength": "100 m",
    "db": ""
  },
  {
    "port": "eth-0-7",
    "moduletype": "1000BASE-T_SFP",
    "sn": "XXXXXX",
    "wavelength": "N/A",
    "linklength": "100 m",
    "db": ""
  },
  {
    "port": "eth-0-8",
    "moduletype": "1000BASE-T_SFP",
    "sn": "XXXXXX",
    "wavelength": "N/A",
    "linklength": "100 m",
    "db": ""
  },
  {
    "port": "eth-0-9",
    "moduletype": "1000BASE-LX",
    "sn": "XXXXXX",
    "wavelength": "1310 nm",
    "linklength": "10 km",
    "db": "-40.00"
  },
  {
    "port": "eth-0-10",
    "moduletype": "1000BASE-T_SFP",
    "sn": "XXXXXX",
    "wavelength": "N/A",
    "linklength": "100 m",
    "db": ""
  },
  {
    "port": "eth-0-18",
    "moduletype": "1000BASE-T_SFP",
    "sn": "XXXXXX",
    "wavelength": "N/A",
    "linklength": "100 m",
    "db": ""
  },
  {
    "port": "eth-0-31",
    "moduletype": "1000BASE-LX",
    "sn": "XXXXXX",
    "wavelength": "1310 nm",
    "linklength": "20 km",
    "db": "-5.13"
  },
  {
    "port": "eth-0-35",
    "moduletype": "1000BASE-T_SFP",
    "sn": "XXXXXX",
    "wavelength": "N/A",
    "linklength": "100 m",
    "db": ""
  },
  {
    "port": "eth-0-47",
    "moduletype": "1000BASE-T_SFP",
    "sn": "XXXXXX",
    "wavelength": "N/A",
    "linklength": "100 m",
    "db": ""
  }
]
------------------模块数量统计-----------------
{
  "1000BASE-LX 1310 nm 10 km": 2,
  "1000BASE-T_SFP N/A 100 m": 8,
  "1000BASE-LX 1310 nm 20 km": 1
}
------------------模块状态统计-----------------
{
  "free": [
    "eth-0-9 1000BASE-LX",
    "eth-0-18 1000BASE-T_SFP",
    "eth-0-47 1000BASE-T_SFP"
  ],
  "line": [
    "eth-0-1 1000BASE-LX",
    "eth-0-2 1000BASE-T_SFP",
    "eth-0-3 1000BASE-T_SFP",
    "eth-0-7 1000BASE-T_SFP",
    "eth-0-8 1000BASE-T_SFP",
    "eth-0-10 1000BASE-T_SFP",
    "eth-0-31 1000BASE-LX",
    "eth-0-35 1000BASE-T_SFP"
  ]
}

 

标签:verbose,netmiko,db,模块,print,eth,textfsm,1000BASE,port
From: https://www.cnblogs.com/darkchen/p/16969427.html

相关文章

  • 007爬虫之requests模块进阶
    前面基本将爬虫的基础知识学习得差不多了,今天最后深入下requests模块,这个写完之后,一般的网站大家都可以去爬取了,后面会慢慢给大家分享一些烧脑的东西,今天还是先说说request......
  • FPGA串口发送模块
    1、串口原理通用异步收发传输器(UniversalAsynchronousReceiver/Transmitter,UART)是一种异步收发传输器,其在数据发送时将并行数据转换成串行数据来传输,在数据接收时将接......
  • Python实战案例,tkinter+random模块,实现课堂随机抽选提问并语音播报学生姓名
    先看运行结果前言今天给大家介绍Python实现课堂随机抽选提问并语音播报学生姓名实战案例,废话不多说直接开整~开发工具Python版本:3.8相关模块:tkinter模块time模块......
  • Python模块fileinput操作文件和目录操作总结
    前言之前介绍Python的pathlib模块可以有效的路径及文件查找等方便操作,本篇介绍一个相对readlines()获取文件内容更高效的用法fileinput模块对一个或者多个文件的内容迭......
  • ubuntu内核模块编译
    1、hello.c:1#include<linux/module.h>2#include<linux/kernel.h>3#include<linux/init.h>4MODULE_LICENSE("GPL");5//__init是属性标志,意思是将函数放入.i......
  • Python如何导入自定义模块?
    在C语言里为了工程文件的主程序main代码简洁的效果,我们经常用include“XXX”的来导入其.h文件在Python里Import自己的自定义模块需要注意几个坑以main主函数和需要导入的......
  • Torch.nn模块学习-池化
    OverridetheentrypointofanimageIntroducedinGitLabandGitLabRunner9.4.Readmoreaboutthe extendedconfigurationoptions.Beforeexplainingtheav......
  • Python | time和datetime模块详解
    对时间进行处理 python与时间处理相关的模块有两个:time模块和datetime模块(python的内置标准库,不需要去下载)datetime模块,常用类4个(date,time,datetime,timedelta)......
  • 关于python opencv报错问题,找不到cv2模块啊,直接卸载重装,马上解决问题,网上一大堆配置
    卸载包命令pipuninstallopencv-python卸载包命令pipuninstallopencv-contrib-python主要就是这两个包;然后再安装pipinstallopencv-pythonpipinstallopencv-c......
  • Scrapy 模块
    Scrapy模块目录Scrapy模块1Scrapy简介1.1安装1.2Scrapy全局命令1.3Scrapy项目命令2Scrapy操作2.1创建项目操作2.2配置项目文件1.4数据解析1.5持久化存储3......