使用IPython下的Net-SNMP来管理类UNIX系统的教程


Posted in Python onApril 15, 2015

引言

对于简单网络管理协议 (SNMP),大多数系统管理员都具有一定的使用经验,或者至少听说过它。如果您正在一个数据中心工作,那么您每天都可能采用某种方式与 SNMP 进行交互。有许多给人印象深刻的、同等规模的网络管理系统 (NMS) 或者网络监视系统使用了 SNMP 监视,但本文并不打算介绍这些系统。本文主要涉及的是通过 Python? 语言来研究 SNMP,并亲自编写相关的代码。

一位朋友最近告诉我,有时候遇到的情况就像:只是希望沿着街道一路走到奶奶家,而不需要乘坐像 Saturn V 火箭一样飞快。有许多任务,如果利用或者配置大规模的 NMS,就好像是一个 Saturn V 火箭,在填满液氧罐之前,先尝试一下使用 Python,那么您将得到更好的服务。了解如何编写灵活的 Python 代码与 SNMP 进行交互,这可能是系统管理员可以获得的、最有趣且最高效的技能之一。尽管 SNMP 的设置和使用非常复杂,但本文中所讨论的内容将使它变得非常有趣。
安装和配置 Net-SNMP

要学习本文中的内容,您需要在您的 *nix 计算机中安装最新的 Python(即 Python 2.3 或者更高版本)。在撰写本文时,Python 2.5.1 是 Python 的最新版本。您还需要 IPython,以便以交互的方式使用带 Python 绑定的 Net-SNMP 库。Net-SNMP 团队对各种操作系统中的支持进行了详细测试,具体包括 AIX?、HP-UX?、GNU/Linux? 分发版(如 Red Hat)、Windows?,甚至 OS X?。

安装 IPython 是一项非常简单的工作。一个很好的选择是使用 Easy Install 来管理 Python 包。通过运行 ez_setup.py 脚本,您可以很容易地安装任何 Python 包。例如,您只需要键入以下命令:

easy_install ipython

其他可选的安装方式包括,使用您最喜欢的包管理系统、或者只需下载 IPython 并键入以下命令:

python setup.py install

请注意,干线 (trunk) 指的是版本控制系统中的根路径,其中保存了最近的代码副本。此外,干线还常常表示一个子版本和版本控制系统。有关更详细的内容,请参见参考资料部分中的子版本链接。

要学习本文中的内容,您需要确保您的客户端计算机、或者运行所有代码的计算机都安装了 NET-SNMP Version 5.4.x 或者更高版本,因为从这个源代码版本开始,包括了 Python 绑定。在大多数情况下,绑定的安装需要对源文件进行编译;然而,也可以使用 Red Hat Package Managers (RPM)。如果你有兴趣和时间,那么可以从 Net-SNMP Web 站点查看一下它的最新版本。

有许多编译选项可供使用,但主要的任务是对 NET-SNMP 进行正确编译,然后运行 Python 目录中的、独立的 Python 安装程序。另一个需要注意的问题是,当您进行编译并运行 ./configure 的时候,它将运行本地计算机(正在编译代理的计算机)的配置脚本。您不应该使用该配置脚本,对于本文而言,您只需要创建一个简单的配置脚本。

对 /etc/snmp/snmpd.conf 中所存储的配置文件进行备份,并构建下面这个非常基本的配置:

syslocation "My Local Machine"
syscontact me@localhost.com
rocommunity public

保存它,并重新启动 snmpd 守护进程。在大多数 *nix 系统中,可以使用 /etc/init.d/snmpd restart 来完成这项工作。

除非在不得已的情况下,否则最好不要对处于活动开发阶段的版本进行编译,因为这样做,您将需要自己动手修复有问题的代码。在 CentOS 5 或者 Red Hat Enterprise Linux 5 (RHEL 5) 中,您可以下载最新的、稳定的源文件 RPM(在撰写本文之时,是 5.4.1 版本)。请注意,您还需要使用 Python 源文件来构建绑定。因此,如果您正在使用一台基于 Red Hat 的计算机,那么请确保为特定的 *nix 操作系统安装了 python-dev(或者其等价物)和 Python Header 文件。如果您在从源文件构建 RPM 的过程中,需要任何帮助的话,请参考官方的 Red Hat 文档。从源文件构建包可能是一个非常复杂的主题,并且已经超出了本文的范围。如果您在使用 Python 绑定的时候遇到了麻烦,那么您应该在 Net-SNMP 邮件列表中请求帮助。
对代码进行分析

还等什么呢?假设您已经安装了 Python 绑定和 IPython。现在,您已经做好了使用 IPython 的准备,并开始相关的工作。尽管在某些时候,您可能还需要浏览 IPython 文档。Jeff Rush 是当前的 Python Advocacy Coordinator,他为 IPython 提供了一些非常好的屏幕录像内容。好的,让我们开始进行编码。

让我们进行一次简单的查询,以便通过使用计算机的对象标识符 (OID) 值 sysDescr 来标识一台计算机。通过键入 ipython 启动 IPython,然后执行这个交互式会话:
清单 1. IPython 示例

       

In [1]: import netsnmp

    In [2]: oid = netsnmp.Varbind('sysDescr')

    In [3]: result = netsnmp.snmpwalk(oid,
    ...:             Version = 2,
    ...:             DestHost="localhost",
    ...:             Community="public")

    In [4]: result = netsnmp.snmpwalk(oid,
                Version = 2,
                DestHost="localhost",
                Community="public")

    In [16]: result
    Out[16]: ('Linux localhost 2.6.18-8.1.14.el5 #1 SMP Thu Sep 27 
    18:58:54 EDT 2007 i686',)

请注意,您所得到的 result 值与这里所显示的 result 值是不同的。如果您已经遵循了上面清单 1 中所显示的配置,那么所有其他的内容都应该是可用的。如果您对 SNMP 比较熟悉,那么您可能马上就能够明白这些内容的实际作用。

使用 IPython 来测试 SNMP 代码片段的好处之一是,它就好像是一个普通的 Shell,并且许多基本的、交互式 Shell 的概念“都可以起作用”,但需要说明的是,它们是以 python 方式进行工作的。编写 SNMP 代码可能是一项非常单调乏味的活动,但是通过 IPython 来使用 Net-SNMP 库将使其变得非常有趣。

正如您所看到的,要将结果转换为 Python 数据类型,这项任务是非常简单的。这就是为什么 IPython 和 Net-SNMP 可以很好地在一起工作的原因。现在,对于编写自定义脚本来说,只需要以交互方式分析 OID 的组合以进行查询。在理想的情况下,需要运行一个大规模的、易于配置的 NMS 设置脚本,自动地将新的计算机集成到网络中。

当然,并不存在这种理想的情况,您需要了解如何将一些好的 SNMP 代码组合到一起,对于一名系统管理员来说,这是非常有用的。下面给出一个示例情况,假设您刚刚将一个高速 DDR 转换为正在运行 Ubuntu Linux 的 2 TB RAID 0 服务器,因为您必须在一个小时的时间内解决问题,所以您不得不这样做。

现在,您遇到了很大的麻烦,并且您只有几分钟的时间来监视具体的问题,以了解是否需要开始发送简历、或者是否应该开始准备讲话并请求升职。让我们使用 IPython 中的编辑功能来编写脚本,并将它保存到文件中,然后在不离开 IPython 的情况下,在一个会话中运行它: ed snmpinput.py
清单 2. IPython 模块的创建

import netsnmp

class snmpSessionBaseClass(object):
  """A Base Class For a SNMP Session"""
  def __init__(self,
        oid="sysDescr",
        Version=2,
        DestHost="localhost",
        Community="public"):

    self.oid = oid
    self.Version = Version
    self.DestHost = DestHost
    self.Community = Community


  def query(self):
    """Creates SNMP query session"""
    try:
      result = netsnmp.snmpwalk(self.oid,
                  Version = self.Version,
                  DestHost = self.DestHost,
                  Community = self.Community)
    except:
      import sys
      print sys.exc_info()
      result = None

    return result

对 IPython 进行自定义以使用正确的编辑器

通过编辑 $HOME/.ipython/ipythonrc,您可以对 Ipython 进行自定义。首先需要进行自定义的内容之一是 %edit 命令,可以通过键入 ed 来调用该命令。在缺省情况下,它被设置为使用 vi,但是您可以更改它,以便使用其他编辑器,包括 Emacs。关于如何更改您的环境,本文给出了相应的指导。您还可以使用下面的命令来启动 Ipython,以便以硬编码的形式指定使用某个特定的编辑器: ipython -editor=vim。

继续执行,将下面的代码剪切并粘贴到您刚刚创建的文件中。当保存这个文件时,IPython 将自动地运行它,并将该类放置到您环境中相应的模块中。如果您键入 who,那么您将看到与以下所示类似的内容:

In [2]: who
netsnmp snmpSessionBaseClass

这项操作的功能非常强大,因为您可以获得使用您最喜欢的文本编辑器(也许是 Vim 或者 Emacs)的所有优点,然后在交互的 IPython Shell 会话中立即使用这些代码。请注意,如果您已经编写了一个模块,那么您还可以简单地键入并运行它,以获得相同的结果。执行和运行 IPython 中的模块,这就相当于运行其中的代码,并将其放入到 IPython 环境中。
以迭代的方式进行编码

现在通过使用 IPython,可以将 Python Shell、UNIX Shell 和您最喜欢的文本编辑器的最佳特性组合到一起。在与像 SNMP 库这样非常复杂的对象进行交互时,您需要使用可以获得的所有帮助,而在这个示例中,真正地展示了 IPython 的强大功能。

您可以动态地编写一些模块,并且您可以在稍后对其进行测试和使用。IPython 可以与任何编程风格很好地融合在一起,包括测试驱动的开发 (TDD) 或者测试增强的开发 (TED)。为了证明这种便利性,让我们转到您刚刚编写的模块。

既然已经有一个面向对象的 SNMP 接口,那么您就可以开始向本地计算机进行询问:
清单 3. IPython 迭代式编码

In [1]: run snmpinput

In [2]: who
netsnmp snmpSessionBaseClass  

In [3]: s = snmpSessionBaseClass()

In [4]: s.query()
Out[4]: ('Linux localhost 2.6.18-8.1.14.el5 #1 SMP Thu Sep 27 18:58:54 EDT 2007 i686',)

In [5]: result = s.query()

In [6]: len(result)
Out[6]: 1

通过使用这个模块获得相关的结果,这是非常容易的,但是您基本上只是在运行一个硬编码脚本,因此需要更改 OID 对象的值,以遍历系统子树:
清单 4. 更改 OID 对象的值

In [7]: s.oid
Out[7]: 'sysDescr'

In [8]: s.oid = ".1.3.6.1.2.1.1"

In [9]: result = s.query()

In [10]: print result
('Linux localhost 2.6.18-8.1.14.el5 #1 SMP Thu Sep 27 18:58:54 EDT 2007 i686', 
      '.1.3.6.1.4.1.8072.3.2.10', '121219', 'me@localhost.com', 
      'localhost', '"My Local 
Machine"', '0', '.1.3.6.1.6.3.10.3.1.1', '.1.3.6.1.6.3.11.3.1.1', 
'.1.3.6.1.6.3.15.2.1.1', 
'.1.3.6.1.6.3.1', '.1.3.6.1.2.1.49', '.1.3.6.1.2.1.4', '.1.3.6.1.2.1.50',
 '.1.3.6.1.6.3.16.2.2.1', 
'The SNMP Management Architecture MIB.', 'The MIB for Message Processing and
 Dispatching.', 'The management information definitions for the SNMP 
User-based Security Model.', 'The MIB module for SNMPv2 entities', 'The 
MIB module for managing TCP implementations', 'The MIB module for
managing IP and ICMP implementations', 'The MIB module for managing 
UDP implementations', 'View-based Access 
Control Model for SNMP.', '0', '0', '0', '0', '0', '0', '0', '0')

正如您可以看到的,要使用这个模块并开始分析整个网络(一次一台计算机),这项任务是非常容易的。请仔细地进行分析,并确定需要在网络中进行查询的内容。这是 IPython 的另一个有趣的特性,有必要对其进行深入研究。IPython 具有一个令人难以置信的特性,即允许您将 Python 代码片段作为后台进程来运行。幸运的是,进行这项操作非常简单。让我们再次运行相同的查询,但这一次将其作为后台进程运行(请参见清单 5)。
清单 5. IPython 迭代式编码示例——后台进程

In [11]: bg s.query()
Starting job # 0 in a separate thread.

In [12]: jobs[0].status
Out[12]: 'Completed'

In [16]: jobs[0].result
Out[16]: 
('Linux localhost 2.6.18-8.1.14.el5 #1 SMP Thu Sep 27 18:58:54 EDT 2007 i686',
 '.1.3.6.1.4.1.8072.3.2.10', '121219', 'me@localhost.com', 'localhost', '"My Local
 Machine"', '0', '.1.3.6.1.6.3.10.3.1.1', '.1.3.6.1.6.3.11.3.1.1', 
'.1.3.6.1.6.3.15.2.1.1', '.1.3.6.1.6.3.1', '.1.3.6.1.2.1.49', 
'.1.3.6.1.2.1.4', '.1.3.6.1.2.1.50', '.1.3.6.1.6.3.16.2.2.1',
 'The SNMP Management Architecture MIB.', 'The MIB for Message Processing and
 Dispatching.', 'The management information definitions for the SNMP User-based
 Security Model.', 'The MIB module for SNMPv2 entities', 'The MIB module for
 managing TCP implementations', 'The MIB module for managing IP and ICMP
 implementations', 'The MIB module for managing UDP implementations',
 'View-based Access Control Model for SNMP.', '0', '0', '0', '0', '0', '0', '0', '0')

令人激动的是,IPython 中的后台线程是一种非常有价值的功能,但它只能与支持异步线程的库一起工作。不幸的是,Net-SNMP 是同步的。如果您对这一点感兴趣,那么可以通过将 s.oid 值更改为 .iso 来进行测试。在查询完成之前,您应该可以注意到,IPython 解释器发生了“阻塞”或者“挂起”。尽管只是一个警告,但对整个 .iso 树的 SNMP 遍历可能会花费较长的时间,因此您可能会接受我的观点。

当然,还有另一种解决方案。您可以使用 Python 所提供的众多处理库中的其中一个,为这个阻塞的进程派生新的进程。Python Cheese Shop 提供了一些第三方库。如果您正在使用 easy_install,那么要安装一个包(如 Parallel Python)并使用 Net-SNMP 来测试这个库,将是相当简单的,因此这将由您来决定。

easy_install http://www.parallelpython.com/downloads/pp/pp-1.5.zip

这里要展示的最后一个特性是,在 IPython Shell 中运行单元测试。在对模块进行更改时,需要频繁地运行单元测试,而这也是非常容易的。您需要添加一个标记以运行 run -e,这样一来,您就可以在 IPython Shell 中避免回溯到单元测试模块。您可以在本文所附带的源文件中下载这个单元测试。

请注意,IPython 0.8.2 还有一个新的文档测试特性,它允许您在 IPython 中生成文档测试。文档测试是 Python 的一个很好的特性,因为与其他特性一起,它提供了一种为 API 创建可测试文档的方法。下面给出了一个示例,以说明如何在 IPython 中为我们的模块运行 doctest:
清单 6.以 doctest 模式运行 IPython

In [5]: %doctest_mode
*** Pasting of code with ">>>" or "..." has been enabled.
Exception reporting mode: Plain
Doctest mode is: ON
>>> from snmpinput import snmpSessionBaseClass

>>> s = snmpSessionBaseClass()

>>> s.query()
('Linux devmws2.racemi.com 2.6.9-55.0.2.EL #1 Tue Jun 26 14:08:18 EDT 2007 i686',)

因为 doctest 模式将不加分析地执行 Python 语句,所以您必须小心,不要在 doctest 中使用可能更改的值,就像上面所给出的值。如果您在模块的 docstring 中粘贴了数行代码,那么您可以通过使用下面的方法来测试您的 API 文档:

def _test():
  import doctest
  doctest.testmod()

if __name__ == "__main__":
  _test()

总结

在本文中,您已经了解了协同使用 Net-SNMP 和 IPython 将成为一种功能强大的组合。本文介绍了下面几个主要概念:

  •     Python 绑定:Net-SNMP 现在提供了 Python 绑定,这使得我们能够充分地利用 Python 的功能来处理 SNMP 协议。
  •     处理库:目前,Python 绑定是同步的,但是使用处理库可以为每个请求派生新的进程,从而解决这个问题。
  •     灵活的技术:对于系统管理员和软件工程师来说,IPython 是一种非常成熟、并且功能非常强大的工具。尽管本文只是简要地介绍了几种灵活的技术,如文档测试和单元测试,但是您可以应用这些技术,以进行任何以测试为中心的开发、或者以交互的方式编写和分析代码。
  •     SNMP 和 IPython:对于 SNMP 和 IPython 在单独或者共同使用时能够实现的功能,本文只是进行了简要介绍。

SNMP 非常复杂,它几乎使人们不敢想象编写任何有意义的代码,但是,我们希望本文所介绍的技术能够激发某些新的观点。如果您很好奇,想知道 SNMP 的 Python 实现究竟到了什么程度,那么可以研究一下 Zenoss,下载一个虚拟机,并对它进行测试。还有一个 API,您可以利用它来编写脚本,因此您可以将这里所学到的内容和全面的 Python NMS 相结合。当然,也适用于任何其他 NMS。

Python 相关文章推荐
用Python操作字符串之rindex()方法的使用
May 19 Python
Python下的常用下载安装工具pip的安装方法
Nov 13 Python
Python对列表中的各项进行关联详解
Aug 15 Python
Django框架静态文件使用/中间件/禁用ip功能实例详解
Jul 22 Python
django使用admin站点上传图片的实例
Jul 28 Python
python selenium 执行完毕关闭chromedriver进程示例
Nov 15 Python
python如何绘制疫情图
Sep 16 Python
Python使用struct处理二进制(pack和unpack用法)
Nov 12 Python
scrapy头部修改的方法详解
Dec 06 Python
python解包概念及实例
Feb 17 Python
Python道路车道线检测的实现
Jun 27 Python
Python绘制散点图之可视化神器pyecharts
Jul 07 Python
Python中的Matplotlib模块入门教程
Apr 15 #Python
使用Python编写类UNIX系统的命令行工具的教程
Apr 15 #Python
Python中的元类编程入门指引
Apr 15 #Python
在Python中进行自动化单元测试的教程
Apr 15 #Python
pygame学习笔记(6):完成一个简单的游戏
Apr 15 #Python
pygame学习笔记(5):游戏精灵
Apr 15 #Python
pygame学习笔记(4):声音控制
Apr 15 #Python
You might like
在WAMP环境下搭建ZendDebugger php调试工具的方法
2011/07/18 PHP
destoon实现底部添加你是第几位访问者的方法
2014/07/15 PHP
Zend Framework教程之Zend_Db_Table用法详解
2016/03/21 PHP
Yii2中使用asset压缩js,css文件的方法
2016/11/24 PHP
当jQuery遭遇CoffeeScript的时候 使用分享
2011/09/17 Javascript
Extjs4.0设置Ext.data.Store传参的请求方式(默认为GET)
2013/04/02 Javascript
JavaScript中检查对象property的存在性方法介绍
2014/12/30 Javascript
基于JQuery的$.ajax方法进行异步请求导致页面闪烁的解决办法
2016/05/10 Javascript
JavaScript的字符串方法汇总
2016/07/31 Javascript
H5移动端适配 Flexible方案
2016/10/24 Javascript
jquery+html仿翻页相册功能
2016/12/20 Javascript
微信小程序教程系列之设置标题栏和导航栏(7)
2020/06/29 Javascript
vue.js实现备忘录功能的方法
2017/07/10 Javascript
react-navigation 如何判断用户是否登录跳转到登录页的方法
2017/12/01 Javascript
详解JS实现系统登录页的登录和验证
2019/04/29 Javascript
微信小程序仿通讯录功能
2020/04/09 Javascript
python 调用HBase的简单实例
2016/12/18 Python
Python实现向服务器请求压缩数据及解压缩数据的方法示例
2017/06/09 Python
python实现输入任意一个大写字母生成金字塔的示例
2019/10/27 Python
opencv3/Python 稠密光流calcOpticalFlowFarneback详解
2019/12/11 Python
python3 动态模块导入与全局变量使用实例
2019/12/22 Python
python logging.basicConfig不生效的原因及解决
2020/02/20 Python
python3.x中安装web.py步骤方法
2020/06/23 Python
HTML5 用动画的表现形式装载图像
2016/03/08 HTML / CSS
Orvis官网:自1856年以来,优质服装、飞钓装备等
2018/12/17 全球购物
Java如何读取CLOB字段
2013/10/10 面试题
教师实习期自我鉴定
2013/10/06 职场文书
幼儿园教师备课制度
2014/01/12 职场文书
集团薪酬管理制度
2014/01/13 职场文书
告诉你怎样写创业计划书
2014/01/27 职场文书
校园安全检查制度
2014/02/03 职场文书
我的长生果教学反思
2014/04/28 职场文书
工程安全生产协议书
2014/11/21 职场文书
公司员工违纪检讨书
2015/05/05 职场文书
初中班主任工作随笔
2015/08/15 职场文书
用Python进行栅格数据的分区统计和批量提取
2021/05/27 Python