热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Python中的PySNMP模块

SNMP,简称简单网络管理协议,是SDN的必备工具,是软件控制设备的最佳选择。即使除此之外,应用内访问也是SNMP的主要目的。毫无疑问,所有监控

SNMP ,简称简单网络管理协议,是 SDN 的必备工具,是软件控制设备的最佳选择。即使除此之外,应用内访问也是 SNMP 的主要目的。毫无疑问,所有监控系统都利用 SNMP 来监控服务器和网络设备。在脚本中拥有来自 SNMP 的巨大力量将是惊人的。因此,我们将在本教程中讨论 SNMP 在 Python 编程语言中的使用。

但是在我们开始之前,让我们讨论一下 SNMP。

了解简单网络管理协议

SNMP ,也称为简单网络管理协议,是管理服务器和远程设备(代理)之间进行通信的标准方式。SNMP 的目标是让管理人员了解(甚至更改)代理上的数据。例如,管理器可以检查哪些接口是打开的,哪些是关闭的,或者更改远程设备的主机名。

SNMP module in Python

我们的脚本使管理站上的 Python 程序能够控制执行 SNMP 代理的远程设备。

SNMP 代理在一个特殊的表 MIB 中准备了管理器可以读取或更改的大部分细节。MIB 是一个树状结构,其中一个数字表示树中的每个节点。例如 1.3.6.1.2.1.1 表示系统的描述。如果我们中的一些人想知道这个数字链是从哪里来的,这就是整个树的结构!每个数字都与一个名字相关联。因此,我们可以把它翻译成更明确的iso . org . DOD . internet . mgmt . MIB-2 . system . SysDerse。

现在,让我们借助 Python PySNMP 模块来讨论 SNMP 在 Python 编程语言中的使用。

了解 PySNMP 模块

PySNMP 是 Python 的开源模块。与 telnet 或 HTTP 不同,Python 本身并不实现 SNMP。毕竟,仅仅是网络和系统工程师就需要工厂里有一个 Python 开发人员。 PySNMP 很好地弥补了原生 Python 的不足。总的来说,SNMP模块允许我们使用任何版本的 SNMP,既可以作为代理,也可以作为管理器。创建代理意味着我们正在构建应用或设备。然而,我们将只讨论 PySNMP 在管理远程设备中的使用。

而且,我们会了解 Python 中 PySNMP 的不同功能。本教程的主要目标是创建一个快速的 python 程序,使我们的工作变得简单。在程序中,我们将拥有所需的所有 SNMP 操作。

所以,让我们开始吧。

准备环境

首先我们要安装 PySNMP 模块。我们可以使用 pip 安装程序,在以下命令的帮助下安装所需的模块。

语法:


$ pip install pysnmp

该模块将作为 Python 和 pip 版本安装在系统中。

验证安装

为了检查模块是否已经正确安装在系统中,我们可以尝试导入模块并执行程序。

安装完成后,创建一个新的 Python 文件,并在其中键入以下语法。

示例:


# importing the required module
import pysnmp

现在,保存该文件并在命令提示符下使用以下命令运行该文件。

语法:


$ python .py

如果程序运行时没有出现任何导入错误,则模块安装正确。否则,建议重新安装该模块,并参考其官方文档。

理解 Python SNMP 获取操作

SNMP 的 Get 操作使我们能够检索 MIB 中单个对象的值。我们还可以利用它来获得单个对象的列表。我们可以开始写出如下所示的 get() 函数:

示例:


# importing the required module
from pysnmp import hlapi
# defining the get() function
def get(
target,
oids,
credentials,
port = 161,
engine = hlapi.SnmpEngine(),
cOntext= hlapi.ContextData()
):
handler = hlapi.getCmd(
engine,
credentials,
hlapi.UdpTransportTarget((target, port)),
context,
*construct_object_types(oids)
)
return fetch(handler, 1)[0]

说明:

从上面的代码片段中,我们可以观察到 PySNMP 的高级 API 的杠杆作用。我们定义了一个简单的函数 get() ,它首先需要一个目标(IP 或远程设备名)。然后,它需要我们需要获取的对象标识(oid)列表,然后是一组用于会话身份验证的凭据。如果需要,我们还可以指定一个不同的 UDP 端口,并利用流行的 SNMP 引擎或自定义上下文。我们可能需要对同一设备上的所有操作使用相同的引擎,这样可以节省资源。但是,对于一个简单的代码片段来说,这不是必需的,这样我们就可以忽略两个引擎以及上下文。

该函数为 SNMP 会话生成一个处理程序,并从中获取详细信息。为了实现这一点,它依赖于我们必须创建的两种方法:构造 对象 类型和获取。

构造对象类型

正如我们之前讨论的,拥有更多的力量意味着更多的复杂性。因此, hlapi.getCmd() 函数需要一些特殊的 hlapi。ObjectType 对象,而不是简单的字符串 oid 列表。因此, construct_object_type 函数根据 PySNMP 的需要创建。如果没有时间,我们可以简单地复制并粘贴到代码中。然而,这应该是一个非常简单的功能;让我们来看看:

示例:


def construct_object_types(listOfOids):
objectTypes = []
for oid in listOfOids:
objectTypes.append(hlapi.ObjectType(hlapi.ObjectIdentity(oid)))
return objectTypes

说明:

上面的代码片段返回了一个列表,可以通过在前面加上一个*进行扩展,就像我们在 get() 方法中所做的那样。

正在获取数据

fetch() 函数是 Python SMP 教程的杰作。总的来说,我们编写它是为了可以将其重新用于基于 PySNMP 的其他功能,比如 get-bulk。它只是根据计数变量在处理程序上循环多次。如果出现任何错误,将停止该过程,并返回运行时间错误消息。在其他情况下,它将数据存储在字典列表中。

示例:


def fetch(handler, count):
res = []
for i in range(count):
try:
error_indication, error_status, error_index, var_binds = next(handler)
if not error_indication and not error_status:
items = {}
for var_bind in var_binds:
items[str(var_bind[0])] = cast(var_bind[1])
res.append(items)
else:
raise RuntimeError('Got SNMP error: {0}'.format(error_indication))
except StopIteration:
break
return res

说明:

在上面的代码片段中,我们构建了try-除了方法,为了特定的原因停止迭代。在用户指定的计数高于我们实际拥有的对象数量的情况下,我们只需停止并返回到目前为止得到的结果。这就是构造的目的。

返回字典列表的需求是什么?在每个 get 操作中,我们可以得到各种各样的对象 id。因此,每个字典都将由作为关键字的对象标识和作为该关键字值的管理信息库中的 OID 值组成。在一次获取中需要多个 oid 的场景中,我们将返回一个带有多个键的字典。但是,有什么必要列出清单呢?使用 get 操作,我们只能检索一次数据。然而,正如我们将在 get bulk 中看到的,我们可能需要在不同的实例上多次获得类似的细节。让我们考虑一个更好理解的例子。假设我们需要检查所有接口上的错误:信息总是错误;然而,我们有不同的实例(每个接口一个)。我们可以使用列表来可视化它,其中每个数据元素都是描述一个实例的字典。

注意:fetch()函数依赖于我们必须创建的另一个函数:cast()。该函数将从 PySNMP 接收的数据转换为 int、float 或 string。

让我们考虑下面的代码片段:

示例:


def cast(val):
try:
return int(val)
except (ValueError, TypeError):
try:
return float(val)
except (ValueError, TypeError):
try:
return str(val)
except (ValueError, TypeError):
pass
return val

说明:

在上面的代码片段中,我们定义了一个函数,其中我们使用了try-除了方法来检查任何引发的错误。

提供凭据

PySNMP 库的认证系统很强大,也很简单。没有理由在上面额外写一层,这样我们就可以直接利用它。 get() 函数与其他函数一样,在凭证变量中有一个特殊的身份验证对象。如果我们使用 SNMPv2c 或 SNMPv3,这个对象是变化的。

在 SNMPv2c(或更低)的情况下,我们必须指定社区。我们可以使用社区数据对象来实现,如下所示:

语法:


hlapi.CommunityData('JAVATPOINT')

相反,SNMPv3 很复杂。这是因为它利用了一个有两个密码和两个协议的用户:第一个用于身份验证,另一个用于加密。因此,我们必须指定用户名、验证密码、验证协议、加密密码和加密协议。我们可以使用 UsmUserData 类来实现。

为了更好地理解,让我们考虑下面的例子。

示例:


hlapi.UsmUserData(
'testuser',
authKey = 'authenticationkey',
privKey = 'encryptionkey',
authProtocol = hlapi.usmHMACSHAAuthProtocol,
privProtocol = hlapi.usmAesCfb128Protocol
)

说明:

在上面的代码片段中,我们使用了 UsmUserData 类并输入了所需的细节。它比看起来简单;我们必须知道远程设备的协议。然而,我们中的一些人可能会参考 UsmUserData 上的完整官方文档。

获取主机名

现在,让我们测试一下 get() 功能。我们将使用它来检索设备的主机名,即对象 1.3.6.1.2.1.1.5.0。我们可以简单地编写以下代码片段:

示例:


print(get('10.0.0.1', ['1.3.6.1.2.1.1.5.0'], hlapi.CommunityData('JAVATPOINT')))

输出:

{'1.3.6.1.2.1.1.5.0': 'R1.sdn.local'}

说明:

在上面的代码片段中,我们打印了 get() 函数获取设备主机名的结果。

注意:在这里,我们没有得到字典的列表,而只是一个字典。这是经过深思熟虑的,get()函数在任何时候都是这样的。一般我们知道函数只执行一次;它不能创建多个实例。因此,我们返回从 fetch()获得的第一个元素。


理解 Python SNMP 批量获取

get_bulk() 方法检索同一个对象标识的多个实例,假设每个接口一个。当我们使用表时,这个函数变得可支持,比如接口一的路由表。它相当简单,功能类似于 get() 方法。但是它需要一些额外的细节:从哪个对象开始,以及我们需要获得的实例数量。我们在从开始发货,从算起。

让我们考虑以下代码片段来理解 get_bulk() 函数的工作原理。

示例:


def get_bulk(
target,
oids,
credentials,
count,
start_from = 0,
port = 161,
engine = hlapi.SnmpEngine(),
cOntext= hlapi.ContextData()):
handler = hlapi.bulkCmd(
engine,
credentials,
hlapi.UdpTransportTarget(( target, port )),
context,
start_from, count,
*construct_object_types( oids )
)
return fetch(handler, count)

说明:

在上面的代码片段中,我们定义了 get_bulk() 函数,在这里我们指定了处理程序。最后,我们返回了 fetch() 功能。因此,我们需要一个字典列表,所以我们不必像使用 get() 函数那样只提取第一个字典。

理解 Python SNMP 获取批量自动

get_bulk_auto() 功能是 get_bulk() 功能的改进版。假设我们想使用 get_bulk() 循环访问设备接口。我们如何知道接口的数量?这是必要的,因为 SNMP 需要知道迭代多少次。我们不能提前知道;但是,我们可以使用 SNMP 作为一个选项来查找这些信息。

我们可以使用 get_bulk_auto() 函数告诉代码从另一个 OID 中检索计数变量。因此,我们可以指定一个对象标识,而不是指定一个数字。该函数将获取该对象,并将其用作计数。

为了更好地理解,让我们考虑下面的例子。

示例:


def get_bulk_auto(
target,
oids,
credentials,
count_oid,
start_from = 0,
port = 161,
engine = hlapi.SnmpEngine(),
cOntext= hlapi.ContextData()):
count = get(
target,
[count_oid],
credentials,
port,
engine,
context
)[count_oid]
return get_bulk(target, oids, credentials, count, start_from, port, engine, context)

说明:

在上面的代码片段中,我们定义了 get_bulk_auto() 函数,并使用 get() 指定了计数变量,并返回 get_bulk() 函数。

使用 Python SNMP 批量获取和批量自动获取

让我们考虑执行下面的代码片段。

示例:


ele = get_bulk_auto(
'10.0.0.1',
['1.3.6.1.2.1.2.2.1.2 ', '1.3.6.1.2.1.31.1.1.1.18'],
hlapi.CommunityData('JAVATPOINT'),
'1.3.6.1.2.1.2.1.0')
for i in ele:
for x, y in i.items():
print("{0} = {1}".format(x, y))
print('')

输出:

1.3.6.1.2.1.2.2.1.2.1=FastEthernet1/0
1.3.6.1.2.1.31.1.1.1.18.1=
1.3.6.1.2.1.2.2.1.2.2=FastEthernet0/0
1.3.6.1.2.1.31.1.1.1.18.2=
1.3.6.1.2.1.2.2.1.2.3=FastEthernet0/1
1.3.6.1.2.1.31.1.1.1.18.3=Test Desc
1.3.6.1.2.1.2.2.1.2.4=Serial2/0
1.3.6.1.2.1.31.1.1.1.18.4=
1.3.6.1.2.1.2.2.1.2.5=Serial2/1
1.3.6.1.2.1.31.1.1.1.18.5=
1.3.6.1.2.1.2.2.1.2.6=Serial2/2
1.3.6.1.2.1.31.1.1.1.18.6=
1.3.6.1.2.1.2.2.1.2.7=Serial2/3
1.3.6.1.2.1.31.1.1.1.18.7=
1.3.6.1.2.1.2.2.1.2.9=Null0
1.3.6.1.2.1.31.1.1.1.18.9=



推荐阅读
  • 本文介绍了使用PHP实现断点续传乱序合并文件的方法和源码。由于网络原因,文件需要分割成多个部分发送,因此无法按顺序接收。文章中提供了merge2.php的源码,通过使用shuffle函数打乱文件读取顺序,实现了乱序合并文件的功能。同时,还介绍了filesize、glob、unlink、fopen等相关函数的使用。阅读本文可以了解如何使用PHP实现断点续传乱序合并文件的具体步骤。 ... [详细]
  • 本文介绍了Python高级网络编程及TCP/IP协议簇的OSI七层模型。首先简单介绍了七层模型的各层及其封装解封装过程。然后讨论了程序开发中涉及到的网络通信内容,主要包括TCP协议、UDP协议和IPV4协议。最后还介绍了socket编程、聊天socket实现、远程执行命令、上传文件、socketserver及其源码分析等相关内容。 ... [详细]
  • 本文分享了一个关于在C#中使用异步代码的问题,作者在控制台中运行时代码正常工作,但在Windows窗体中却无法正常工作。作者尝试搜索局域网上的主机,但在窗体中计数器没有减少。文章提供了相关的代码和解决思路。 ... [详细]
  • 本文介绍了Python爬虫技术基础篇面向对象高级编程(中)中的多重继承概念。通过继承,子类可以扩展父类的功能。文章以动物类层次的设计为例,讨论了按照不同分类方式设计类层次的复杂性和多重继承的优势。最后给出了哺乳动物和鸟类的设计示例,以及能跑、能飞、宠物类和非宠物类的增加对类数量的影响。 ... [详细]
  • Spring常用注解(绝对经典),全靠这份Java知识点PDF大全
    本文介绍了Spring常用注解和注入bean的注解,包括@Bean、@Autowired、@Inject等,同时提供了一个Java知识点PDF大全的资源链接。其中详细介绍了ColorFactoryBean的使用,以及@Autowired和@Inject的区别和用法。此外,还提到了@Required属性的配置和使用。 ... [详细]
  • 本文详细介绍了SQL日志收缩的方法,包括截断日志和删除不需要的旧日志记录。通过备份日志和使用DBCC SHRINKFILE命令可以实现日志的收缩。同时,还介绍了截断日志的原理和注意事项,包括不能截断事务日志的活动部分和MinLSN的确定方法。通过本文的方法,可以有效减小逻辑日志的大小,提高数据库的性能。 ... [详细]
  • Linux重启网络命令实例及关机和重启示例教程
    本文介绍了Linux系统中重启网络命令的实例,以及使用不同方式关机和重启系统的示例教程。包括使用图形界面和控制台访问系统的方法,以及使用shutdown命令进行系统关机和重启的句法和用法。 ... [详细]
  • Spring特性实现接口多类的动态调用详解
    本文详细介绍了如何使用Spring特性实现接口多类的动态调用。通过对Spring IoC容器的基础类BeanFactory和ApplicationContext的介绍,以及getBeansOfType方法的应用,解决了在实际工作中遇到的接口及多个实现类的问题。同时,文章还提到了SPI使用的不便之处,并介绍了借助ApplicationContext实现需求的方法。阅读本文,你将了解到Spring特性的实现原理和实际应用方式。 ... [详细]
  • 本文介绍了如何使用iptables添加非对称的NAT规则段,以实现内网穿透和端口转发的功能。通过查阅相关文章,得出了解决方案,即当匹配的端口在映射端口的区间内时,可以成功进行端口转发。详细的操作步骤和命令示例也在文章中给出。 ... [详细]
  • 本文介绍了计算机网络的定义和通信流程,包括客户端编译文件、二进制转换、三层路由设备等。同时,还介绍了计算机网络中常用的关键词,如MAC地址和IP地址。 ... [详细]
  • 拥抱Android Design Support Library新变化(导航视图、悬浮ActionBar)
    转载请注明明桑AndroidAndroid5.0Loollipop作为Android最重要的版本之一,为我们带来了全新的界面风格和设计语言。看起来很受欢迎࿰ ... [详细]
  • 在springmvc框架中,前台ajax调用方法,对图片批量下载,如何弹出提示保存位置选框?Controller方法 ... [详细]
  • 本文介绍了如何使用Express App提供静态文件,同时提到了一些不需要使用的文件,如package.json和/.ssh/known_hosts,并解释了为什么app.get('*')无法捕获所有请求以及为什么app.use(express.static(__dirname))可能会提供不需要的文件。 ... [详细]
  • node.jsrequire和ES6导入导出的区别原 ... [详细]
  • Python项目实战10.2:MySQL读写分离性能优化
    本文介绍了在Python项目实战中进行MySQL读写分离的性能优化,包括主从同步的配置和Django实现,以及在两台centos 7系统上安装和配置MySQL的步骤。同时还介绍了创建从数据库的用户和权限的方法。摘要长度为176字。 ... [详细]
author-avatar
用户0h2eqqbg44
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有