使用 Pysnmp 从代理端动态更新 SNMP 表

问题描述 投票:0回答:1

我一直在寻找一种在 SNMP Agent 运行期间使用 pysnmp 动态更新 SNMP 表的方法。但到目前为止还没有运气...

该表已在 MIB 文件中定义(见下文),但似乎我需要覆盖其“readGet()”方法,以便从当前系统状态返回正确的数据。

根据说明,我可以在 SNMP 代理启动之前和 SNMP 代理启动之后构建具有预定义值的静态表:

# Register an imaginary never-ending job to keep I/O dispatcher running forever
self.snmpEngine.transportDispatcher.jobStarted(1)
# Run I/O dispatcher which would receive queries and send responses
try:
    self.snmpEngine.transportDispatcher.runDispatcher()
except:
    self.snmpEngine.transportDispatcher.closeDispatcher()
    raise

它能够返回我期望的值。

但是对于我的系统,它会动态生成很多警报信息,这些信息需要更新到SNMP的MIB表中,以便其他SNMP管理器发送“get/getNext”从我的系统中获取警报信息。

所以我想知道

  • 有没有办法在 pysnmp 中做到这一点?
  • 或者我必须始终静态更新我的警报表?然后在每次更新操作后重新启动 SNMP 代理?
  • 或者我必须在 SNMP 代理启动期间使用所有可能的 2147483647 实例初始化我的警报表?并使用“name[-1]”从每个查询中获取索引/行号?

如果是这样,那么 getNext 查询怎么样?它会忽略那些空表行吗?或者它总是返回下一个,即使它是一个虚拟的?

  • 或者有没有更好的方法从查询消息中获取“索引/行”号?

@Ilya Etingof,pysnmp 专家。如果你有时间可以帮我做一下吗?

兄弟, -焦大鹏

1.

该报警表的MIB文件定义(删除了一些敏感信息)

alarmTable = MibTable((1, 3, 6, *, *, *, *, *, *, *, *, *, , 3))
alarmEntry = MibTableRow((1, 3, 6, *, *, *, *, *, *, *, *, *, , 3, 1)).setIndexNames((0, "MY-MIB", "alarmIndex"))
alarmIndex = MibTableColumn((1, 3, 6, *, *, *, *, *, *, *, *, *, , 3, 1, 1), Integer32().subtype(subtypeSpec=ValueRangeConstraint(1, 2147483647))).setMaxAccess("readonly")
alarmId = MibTableColumn((1, 3, 6, *, *, *, *, *, *, *, *, *, , 3, 1, 2), Integer32().subtype(subtypeSpec=ValueRangeConstraint(1, 2147483647))).setMaxAccess("readonly")
alarmName = MibTableColumn((1, 3, 6, *, *, *, *, *, *, *, *, *, , 3, 1, 3), DisplayString().subtype(subtypeSpec=ValueSizeConstraint(0, 255))).setMaxAccess("readonly")
alarmSeverity = MibTableColumn((1, 3, 6, *, *, *, *, *, *, *, *, *, , 3, 1, 4), AlarmSeverity()).setMaxAccess("readonly")
alarmTime = MibTableColumn((1, 3, 6, *, *, *, *, *, *, *, *, *, , 3, 1, 5), DateAndTime()).setMaxAccess("readonly")
alarmType = MibTableColumn((1, 3, 6, *, *, *, *, *, *, *, *, *, , 3, 1, 6), AlarmType()).setMaxAccess("readonly")
alarmSource = MibTableColumn((1, 3, 6, *, *, *, *, *, *, *, *, *, , 3, 1, 7), DisplayString().subtype(subtypeSpec=ValueSizeConstraint(0, 255))).setMaxAccess( "readonly")
alarmCategory = MibTableColumn((1, 3, 6, *, *, *, *, *, *, *, *, *, , 3, 1, 8), DisplayString().subtype(subtypeSpec=ValueSizeConstraint(0, 255))).setMaxAccess("readonly")
alarmProbableCause = MibTableColumn((1, 3, 6, *, *, *, *, *, *, *, *, *, , 3, 1, 9), ProbableCause()).setMaxAccess("readonly")
alarmComparable = MibTableColumn((1, 3, 6, *, *, *, *, *, *, *, *, *, , 3, 1, 10), DisplayString().subtype(subtypeSpec=ValueSizeConstraint(0, 255))).setMaxAccess("readonly")
alarmAdditionalText = MibTableColumn((1, 3, 6, *, *, *, *, *, *, *, *, *, , 3, 1, 11), DisplayString().subtype(subtypeSpec=ValueSizeConstraint(0, 255))).setMaxAccess("readonly")
snmp pysnmp
1个回答
2
投票

可以使用 pysnmp 维护动态 SNMP 表。解决这个问题有很多方法:

  1. 通过调用

    this
    示例脚本中的 mibInstrumentation.writeVars 定期更新表(通过表回调或专用线程)。后端包括提供新数据和查询的延迟(如果它们是在运行更新时出现的)。但不需要太多编码。

  2. 扩展

    MibTableColumn
    类并实现其
    readGet
    /
    readGetNext
    方法,以便在调用时查看数据并返回 OID/值对。这里的复杂之处在于,要处理 GETNEXT 查询,您需要维护 OID 的某种一致顺序并搜索下一个大于给定的值。

  3. 放弃整个 pysnmp 的 SMI 基础设施,并在您必须从中读取数据的任何数据源之上实现您自己的 MIB 控制器。您需要实现

    readGet
    (简单)和可能的
    readGetNext
    (更复杂,因为需要稳定的 OID 排序)方法。这样,您就可以从学习相当通用且复杂的 pysnmp SMI 实现的细节中解脱出来,并专注于您的最低需求。

回答您的其他问题:

  • 仅仅为了更新服务的日期而重新启动服务并不是一个好主意。
  • 您可以动态更新它(计时器回调或线程),除非您的 SNMP 表中确实有这么多 (2^31) 行。如果数量超过数百个,唯一的方法是将所有警报数据保留在当前位置,在查询到来时读取它并从中构建 SNMP 响应。
  • OID 的哪一部分属于 SNMP 表索引的知识属于
    MibTableRow
    MibTableColumn
    类。因此,如果你扩展它们,你就能弄清楚这一点。不过,有一些辅助方法可用于此目的。
© www.soinside.com 2019 - 2024. All rights reserved.