居然把这篇内容给漏掉了,所以赶紧赶紧地把它补发出来。
目前来对网络设备进行数据收集这件事, 大家会去用好多不同的手段。这些手段里头, 有好多人常用的。比如说SSH这种方式。再比如说还有SNMP这种协议。还有一种做法就是通过设备自己或者控制器那边的API接口来获取信息。
在之前分享的内容里, 讲解过那种采集方式, 但是前提是设备必须支持这种协议, 如果设备本身不支持, 或者是工程师在一时之间很难接受这种情况的话, 我们就再来分享一个基于命令行的网络设备信息采集工具, 这个工具也是一个第三方包, 它是一个非常优秀的网络工具包。
使用ssh登录设备输入命令回显输出。常用的包有、、。个人推荐使用,封装的比较好,支持的厂商和型号(系列)比较多,也可以对Linux进行操作。
这就像是Linux系统一样, 在实际进行使用的时候, 是需要去进行一次二次开发, 或者是对要回显的特定字符串进行定制的, 举个例子而言, 就比如说每当我们在输入设备端敲入了一段show命令之后, 当我们看到那个“设备名#”这几个字样的提示符出现在屏幕上的时候,那就说明这一次命令的回显过程已经结束了, 而这个“设备名#”就是我们所需要指定的回显结束字符串。
相比经过了一些封装的情况, 这种状况能够比较好地进行自动的回显判断操作, 但是, 如果遇到需要分页的情况的话, 还是得依靠人工进行处理, 程序方面没有办法自行处理。
网络设备在执行具体命令的过程当中, 经常会出现分页的现象, 或者进入一些特殊模式之类的情况。所以, 针对网络设备的兼容性支持程度是有限的。
这个说法是基于二次封装来的。从名字的构成上看, 它包含了两个部分。(1) net 这个词代表的是网络方面 (2) miko 这个词代表的含义这里原文不完整。(3) 这种设计能够很好地适应各种网络设备的情况。(4) 它可以处理不同厂家设备在分页显示和特殊运行模式下的差异问题。
(5) 同时针对网络本身的某些特点加入了特定的功能。(6) 这些功能包括 save 操作。(7) 包括文件传输这样的环节。(8) 其中文件传输多用来做数据备份使用。(9)这些都是网络设备所特有的一些功能特性。
安装包
请安装, 这个方式简单粗暴, 是建议这么做。然后要记得, 软件版本要是点7及以上的版本。
你只需要在执行“pip”这个命令的时候, 按照正常的操作方式去运行它即可。
使用
from
这个符号代表的是三对单引号组合在一起的情况。
关于它的使用的方式, 其实还是建议你去仔细看看官方网站上面提供的那个具体的说明文档。
如果你想要使用那个比较简单的show这个命令的话, 就可以直接去用下面提供的那些代码就行, 而且在这里需要特别注意一下。
内置常用的有以下几个, 请注意一下左边的key值, 这是支持的一些设备系列。
= {
对于字符串类型的值, 目前的情况是空的, 什么都没有。
这里显示为一个逗号。
这里显示为一个逗号。
这里显示为一个逗号。
这里显示为一个逗号。
这里显示为一个逗号。
这里显示为一个逗号。
这里显示为一个逗号。
这里显示为一个逗号。
这里显示为一个逗号。
这里显示为一个逗号。
这里显示为一个逗号。
这里显示为一个逗号。
这里显示为一个逗号。
这里显示为一个逗号。
这里显示为一个逗号。
这里显示为一个逗号。
这里显示为一个逗号。
这里显示为一个逗号。
这里显示为一个逗号。
这里显示为一个逗号。
这里显示为一个逗号。
这里显示为一个逗号。
这里显示为一个逗号。
这里显示为一个逗号。
这里显示为一个逗号。
这里显示为一个逗号。
这里显示为一个逗号。
这里显示为一个逗号。
这里显示为一个逗号。
这里显示的是“eltex”, 后面跟着一个逗号。
这里显示为一个逗号。
这里显示为一个逗号。
这里显示为一个逗号。
这里显示为一个逗号。
这里显示为一个逗号。
这里显示为一个逗号。
这里显示为一个逗号。
这里显示为一个逗号。
这里显示为一个逗号。
这里显示为一个逗号。
这里显示为一个逗号。
这里显示为一个逗号。
'linux': ,
这里显示为一个逗号。
这里显示为一个逗号。
这里显示为一个逗号。
这里显示为一个逗号。
这里显示为一个逗号。
这里显示为一个逗号。
这里显示为一个逗号。
这里显示为一个逗号。
这里显示为一个逗号。
这里显示为一个逗号。
这里显示为一个逗号。
这里显示为一个逗号。
'vyos': ,
这个符号代表的是三对单引号组合在一起的情况。
定义一个函数, 这个函数的参数包括IP地址, 还有其他参数, 默认值是22。
当两个参数都为空, 并且它们都是空字符串的时候。
= {
这里显示为一个逗号。
这里有一个名为ip的标识符, 它的值就是ip。
'port': port,
这里显示为一个逗号。
'':
with (**) as :
=
for c in :
= .(c)
.()
if == '':
= {
这个内容目前是空的, 没有任何意义。
IP地址这个字段, 它的值是192.168.1.23。
'port': 22,
这玩意儿的意思就是, 在程序代码的那种字典或者对象格式里, 把双引号给替换成单引号了。
这个内容目前是空的, 没有任何意义。
'':
'show int'
= (**)
print()
当我看到设备类型支持得这么充足的时候, 由于我本人就在一个设备类型非常多的数据中心里头工作着, 我心里头肯定是动了感情了, 特别是华为和华三等这些国产的厂商都提供了支持, 这种感觉真是挺让人开心的。
这里有一句话得悄悄说, 那个叫做“的”的封装工作做得非常出色厉害程度非常之高, 它有能力直接去驱动非常多的网络设备, 但是这种驱动力并不是完全彻底的百分之百的那种样子。除此之外另外很多的驱动都是基于思科公司的一个底层的通用的驱动类这个基础来进行小小修改得到的结果。
关于这一段代码, 我们既可以从前方延伸出去, 也可以从后方继续扩充, 所以这里我拿出来一点东西作为引子供大家参考一下。
1、读取.csv文件, 然后去遍历那些设备, 接着执行这个函数, 并且把命令返回的结果保存到.txt文件里面去, 这难道不就等于说这是备份脚本吗?
2、把文本里面的内容给弄清楚了, 然后, 再把这个弄好的结果保存到那个电子表格软件里面去, 或者是保存到那个文档处理的软件里面去, 这难道就是人家所说的什么巡查任务自动运行的脚本程序吗?
3、读取这个csv文件, 然后去遍历那些设备, 接着执行那个函数之后就会进入到一个模式, 下文会讲解这个具体的内容, 再进一步执行命令操作, 这难道不就是把东西批量下发吗?
4、每隔一段时间就去登录设备, 然后去采集那个指标进行解析再把数据保存到数据库里面, 接着再把这些数据显示成图表的形式。这其实就是一点小小的监控功能。而且, 很多东西都是通过SNMP这个协议抓不到的。那怎么办? 那就不是要通过命令行工具来进行采集和解析了吗?
事实上, 这些都是非常初始的念头, 而在具体的实践过程中, 还得妥善应对一些特殊情况, 倘若认证工作需要实现动态调整的功能那就需要特别去处理, 再比如数据库表的结构设计问题, 针对各个层次的接口, 无论是向上还是向下, 都是可以叠加非常多的封装操作以及抽象概念的。
进行设备的配置
该设备的初始运行状态被设定为普通模式, 在这一模式下, 对设备进行写入数据的操作是不允许的, 不过需要指出的是, 不同种类的网络设备在这条规则的具体执行上可能会存在细微的差异, 但绝大多数设备都普遍遵循这样一个原则, 即只有当用户通过专门的命令行工具介入之后, 才具备执行写入操作的权限;另外, 出于对于信息以及系统安全的考虑, 系统在平常的状态下, 也会将查看性的显示操作与那些具有修改性质的命令操作明确地予以区分开来, 在这种情况下, 如果用户在当前的非特权状态下直接输入普通的命令行指令, 那么这些指令在大多数时候是不会产生任何实际效果的或者说会被系统忽略不计。
from ,
from
= {'': '',
'host': 'XXX',
'port': 'XXX',
'': 'admin',
'': 'XXX!', }
= (**)
= .()
print(' mode is :{}'.())
按照方法一, 先进入模型, 然后在里面的输入框里去写命令, 那个需要确定的字符的话, 可以是正则表达式形式, 最后把它给保存起来。
.()
.(' eth1/50',='.*#')
用逗号来进行拼接, 具体的写法是用单引号将需要连接的文本引起来, 然后在里面添加一个英文逗号。
.()
方法一
它是进入模式, 调用这个叫做函数的操作就可以了, 该函数会根据当前的状态, 自动输入对应的命令, 比如像是-view这样的指令。
我们在实际做操作的时候, 用那个发送命令的方式会发现后续操作提示符一直在变, 比如说在配端口的过程中提示符就变成“(-if)#”那样的样式了, 所以说我们写一个通配的正则匹配这种模式出来, 用它来保证脚本能够确认动作已经执行完成, 然后看实际应用出来的效果是这样子的, 当然在普通模式下发送命令是不会去修改提示符的。
最后一步是使用函数来进行配置的保存工作, 这一过程由系统自动完成处理, 并且可以根据具体的设备情况, 自动生成并输入相应的命令行代码, 以达到保存配置的目的。
方法二
其实, 还有更 的一种做法, 方法二零就是用函数来发送那些命令的集合, 这样做的话, 咱们就不需要先进入到某个地方去, 然而, 可是却还必须有某些特定的条件或者东西才行。
.(=
' eth1/50',' by in 2'
方法三
从文件中读取
不需要进去那个地方, 可是另外一方面还需要做某些事情。
方法3, 是通过文本文件来进行配置的。
将变量设置为字符串类型, 其内容是点后面跟着txt三个字。
自动判断设备的
在很多时候, 我们并不是特别清楚究竟应该选择哪一个选项,对于这个问题不需要感到困扰, 因为系统里面内置了一个具备全自动检测功能的函数可供使用, 接下来把相关的代码内容展示给大家看:
from ,
= {'': '',
'host': 'XXX',
'port': 'XXX',
这是一个空字符串, 它的值是根这个意思。
这是一个格式不完整的代码片段, 内容是用单引号包裹的字符串。
= (**)
= .()
执行打印操作, 输出的内容是空字符后跟随分号。
print('all is:{}'.(.))
''
=
= (**)
我们需要去获取那个回显的前缀, 同时呢, 也要把提示符给获得起来。
执行那个打印输出的代码行为, 把括号里面包含的那个正在发生的运算过程的结果, 放到引号里面的那个占位符的位置上去。
这个在简单show的时候可以使用, 因为常见设备的准确率还可以, 比如说笔者去用nxos和linux检测的时候结果很准。可是有时候推荐出来的东西不是能够用的这种情况, 我也经历过。
能够拿到提示符, 接着就能拿到设备名, 这里划一下重点, 爱动脑子的同学可能还会想别的事情出来, 我们把从那个地方取到的提示符拿来, 用正则表达式把设备名给提取出来, 这是否就可以跟CMDB系统里存在的相关信息做对照比对了, 我个人感觉到这是一个非常实际的运维使用场景, 完全有能力在咱们自己的内部把它扩展成为一个非常简单的小工具。
这个操作的本质, 是用遍历内置的一些适配的方式, 去执行命令, 看看符不符合预期, 最终会给一个准确度的值。由于它是采用遍历这种办法, 所以有时候会比较耗时。
我们去看卡这个
就是去执行命令, 然后根据回显的文本, 用一个正则表达式进行匹配, 匹配成功了就返回结果, 在这个地方返回的是这个字典里的Key值, 它是通过优先级来确定返回的内容。实际上, 我们可以对这个函数做个重写, 基于这个字典里丰富的内容, 按照我们自己的需要去做一些发现工作。
在我们刚刚开始尝试使用某个工具的时候, 无论怎么处理都可以, 然而, 随着我们使用的程度越来越深入, 需求也会越来越多, 我们会发现在某些时候, 必须去做一些必要的二次开发工作, 所以, 在后期阶段, 我也投入了大量的时间用来阅读源代码, 并且结合着我自身实际存在的状况, 继续进行封装处理, 这样做, 一方面是为了能够满足我自己那些非常特殊、甚至有些奇怪的需求, 比如说, 当有新的适配情况出现的时候怎么办, 或者是检测功能自动工作时结果不准确时又该怎么去进行调整。
一方面是为了让开发的步子迈得再快一些, 在过去的日子里, 你要是写上一个十来行的代码, 等用上了封装这种写法之后, 可能就只有区区三行了, 这速度就上去了。
所以, 我有时候在进行分享时, 会把内容的深度深入到源代码那一层里去。大家要是愿意看的话, 就可以看看, 只需要了解个基本情况就可以了。假如一些大型公司有特别的这种需要, 那么我们可以一起探讨一下, 互相都有收获, 彼此交换信息和经验。
比如说, 我们能够基于某些与 Web 框架有关的东西, 去实现类似于软件定义网络那类感觉的网络设备功能。然后可以通过应用程序接口来调用设备的各项信息, 把它作为一个微服务来处理。这样一来, 传统的网络设备也可以像 Nexus 交换机那样具备通过 api 接口的能力了。
大家在把传统网络转向SDN网络的那个过程里头, 肯定会遇到那种既要求灵活响应又要求稳定运行的状态混在一起的情况, 旧的设备和新的设备也会和平共处, 既然这样, 咱们就可以用这个方法去对传统网络进行改造, 让它也拥有那些只有SDN网络才有的功能, 从而让这两种网络的差别变小, 减少差距, 我个人认为这种做法会比别的做法更实用一些, 在后面的一段时间内, 我们还会从国内网络的角度出发, 来谈谈这个方案的好处和不足, 我们先在这里埋下伏笔。