pysnmp 代理 table 实施
pysnmp agent table implementation
我是 snmp 新手。我正在使用 pysnmp 来编写 snmp 代理程序,我使用 mibdump.py 编译了 MIB,并使用以下示例获得了它 运行:http://www.nealc.com/blog/blog/2013/02/23/writing-an-snmp-agent-with-a-custom-mib-using-pysnmp/ http://www.cloud-rocket.com/2013/08/writing-custom-mib-for-pysnmp-agent/ 以及来自 de pysnmp 网页的一些文档。我可以使用不属于 table 的变量对我的代理进行获取、设置和步行。我不能在 table 上散步,我可以在一半的物体上行走,但我不能在其中任何物体上做一组。这是我在某些对象上尝试 get 或 set 时得到的结果。我认为这与我查询 table 的方式有关,但一个对象与另一个对象之间没有一致性,即使它们看起来完全相同。
pysnmp$ snmpset -v2c -c private localhost 1.3.6.1.4.1.1206.4.2.3.3.2.1.3.0 i 1
Error in packet.
Reason: notWritable (That object does not support modification)
Failed object: iso.3.6.1.4.1.1206.4.2.3.3.2.1.3.0
这是一个由 mibdump.py 定义的对象
fontName = MibTableColumn((1, 3, 6, 1, 4, 1, 1206, 4, 2, 3, 3, 2, 1, 3), DisplayString().subtype(subtypeSpec=ValueSizeConstraint(0, 64))).setMaxAccess("readwrite")
if mibBuilder.loadTexts: fontName.setStatus('mandatory')
现在这是另一个专栏
pysnmp$ snmpget -v2c -c public localhost 1.3.6.1.4.1.1206.4.2.3.3.2.1.5.0
iso.3.6.1.4.1.1206.4.2.3.3.2.1.5.0 = No Such Instance currently exists at this OID
这样定义
fontCharSpacing = MibTableColumn((1, 3, 6, 1, 4, 1, 1206, 4, 2, 3, 3, 2, 1, 5), Integer32().subtype(subtypeSpec=ValueRangeConstraint(0, 255))).setMaxAccess("readwrite")
if mibBuilder.loadTexts: fontCharSpacing.setStatus('mandatory')
这是调试器对同一对象上的集合的反馈,i 4 应该在范围内
ValueConstraintError: ConstraintsIntersection(ValueRangeConstraint(-2147483648, 2147483647), ValueRangeConstraint(1, 255)) failed at: ValueConstraintError('ValueRangeConstraint(1, 255) failed at: ValueConstraintError(0,)',) at Integer32
还有几个我认为相关的错误,对我来说似乎 MIB.py 文件没有被正确读取,可能是因为我在自定义 mib 时覆盖了一些代码。具有下一个功能
def createVariable(SuperClass, getValue, sValue, *args):
"""This is going to create a instance variable that we can export.
getValue is a function to call to retreive the value of the scalar
"""
class Var(SuperClass):
def readGet(self, name, *args):
print " Getting var..."
return name, self.syntax.clone(getValue())
def writeTest(self, name, *args ):
print " Testing var..."
def writeCommit(self, name, val, *args ):
print " Setting var..."
sValue(val)
return Var(*args)
我不明白 pysnmp 的结构,所以我无法追溯哪里出了问题,所以如果需要,我可以 post 剩下的代码,这个测试只有几百行。
感谢您提供的任何帮助
要实现动态 SNMP table(您可以通过 SNMP SET create/delete 行),您应该设置 MibTable
、MibTableRow
和 MibTableColumn
个对象:
(MibTable,
MibTableRow,
MibTableColumn,
MibScalarInstance) = mibBuilder.importSymbols(
'SNMPv2-SMI',
'MibTable',
'MibTableRow',
'MibTableColumn',
'MibScalarInstance'
)
并在反映对象层次结构的 OID 下使用 pysnmp 注册它们,例如:
RowStatus, = mibBuilder.importSymbols('SNMPv2-TC', 'RowStatus')
mibBuilder.exportSymbols(
'__EXAMPLE-MIB',
# table object
exampleTable=MibTable((1, 3, 6, 6, 1)).setMaxAccess('readcreate'),
# table row object, also carries references to table indices
exampleTableEntry=MibTableRow((1, 3, 6, 6, 1, 5)).setMaxAccess('readcreate').setIndexNames((0, '__EXAMPLE-MIB', 'exampleTableColumn1')),
# table column: string index
exampleTableColumn1=MibTableColumn((1, 3, 6, 6, 1, 5, 1), v2c.OctetString()).setMaxAccess('readcreate'),
# table column: string value
exampleTableColumn2=MibTableColumn((1, 3, 6, 6, 1, 5, 2), v2c.OctetString()).setMaxAccess('readcreate'),
# table column: integer value with default
exampleTableColumn3=MibTableColumn((1, 3, 6, 6, 1, 5, 3), v2c.Integer32(123)).setMaxAccess('readcreate'),
# table column: row status
exampleTableStatus=MibTableColumn((1, 3, 6, 6, 1, 5, 4), RowStatus('notExists')).setMaxAccess('readcreate')
)
确保说明 table 索引应该是什么样子,例如超过 MibTableColumn
OID 的 OID 尾部。您可以通过将一列或多列配置为 .setIndexNames()
.
如果你想 create/drop 一次拍摄整行,你需要在你的 table 中有一个专门的 status 列类型 RowStatus
的值。您可以在 RFC2579(搜索 RowStatus)中阅读有关 RowStatus
工作原理的详细信息。
此时您应该能够创建新行:
$ snmpset -v2c -c public 127.0.0.1 1.3.6.6.1.5.2.97.98.99 s “my value”
$ snmpset -v2c -c public 127.0.0.1 1.3.6.6.1.5.4.97.98.99 i 4
(OID 的 97.98.99
部分对应 abc
的 exampleTableColumn1
字符串值,这是一个示例索引值。
同时销毁整行:
$ snmpset -v2c -c public 127.0.0.1 1.3.6.6.1.5.4.97.98.99 i 6
当您以这种方式 create/destroy 列时,.createTest()
/createCommit()
和 destroyTest()
/destroyCommit()
方法会在 MibTableColumn
上被调用对象。 writeTest()
/writeCommit()
方法在值修改时被调用。
这些是您可能想要覆盖以控制 pysnmp 之外的东西的方法。
完整的示例脚本可以是 seen here.
请注意,到目前为止,我们还没有使用 mibdump.py
从 ASN.1 MIB 生成任何代码。
如果您需要更多有关代码的实践帮助,我建议您转到 GutHub 上的 pysnmp issues。
理论投篮
对于 SNMP,MIB 的使用有两方面。 SNMP 客户端(例如管理器)使用 MIB 作为“模式”来确定它们从 SNMP 服务器(例如代理)接收的数据。后者实际上是基于MIB schema(schema instance)实现具体的数据结构。
对于 pysnmp,我们使用同一组 Python 类 来实现这两个目的。
- 经理通常只使用架构对象(例如
MibTable
、MibTableRow
、MibTableColumn
和 MibScalar
)
- 当您打算在 运行 时间管理架构实例对象时,代理将其数据置于架构实例对象 (
MibScalarInstance
) 的控制之下,可能由架构对象操纵。
这有望解释为什么 pysnmp MIB 管理代码看起来与 manager/agent 实现相似。
我是 snmp 新手。我正在使用 pysnmp 来编写 snmp 代理程序,我使用 mibdump.py 编译了 MIB,并使用以下示例获得了它 运行:http://www.nealc.com/blog/blog/2013/02/23/writing-an-snmp-agent-with-a-custom-mib-using-pysnmp/ http://www.cloud-rocket.com/2013/08/writing-custom-mib-for-pysnmp-agent/ 以及来自 de pysnmp 网页的一些文档。我可以使用不属于 table 的变量对我的代理进行获取、设置和步行。我不能在 table 上散步,我可以在一半的物体上行走,但我不能在其中任何物体上做一组。这是我在某些对象上尝试 get 或 set 时得到的结果。我认为这与我查询 table 的方式有关,但一个对象与另一个对象之间没有一致性,即使它们看起来完全相同。
pysnmp$ snmpset -v2c -c private localhost 1.3.6.1.4.1.1206.4.2.3.3.2.1.3.0 i 1
Error in packet.
Reason: notWritable (That object does not support modification)
Failed object: iso.3.6.1.4.1.1206.4.2.3.3.2.1.3.0
这是一个由 mibdump.py 定义的对象
fontName = MibTableColumn((1, 3, 6, 1, 4, 1, 1206, 4, 2, 3, 3, 2, 1, 3), DisplayString().subtype(subtypeSpec=ValueSizeConstraint(0, 64))).setMaxAccess("readwrite")
if mibBuilder.loadTexts: fontName.setStatus('mandatory')
现在这是另一个专栏
pysnmp$ snmpget -v2c -c public localhost 1.3.6.1.4.1.1206.4.2.3.3.2.1.5.0
iso.3.6.1.4.1.1206.4.2.3.3.2.1.5.0 = No Such Instance currently exists at this OID
这样定义
fontCharSpacing = MibTableColumn((1, 3, 6, 1, 4, 1, 1206, 4, 2, 3, 3, 2, 1, 5), Integer32().subtype(subtypeSpec=ValueRangeConstraint(0, 255))).setMaxAccess("readwrite")
if mibBuilder.loadTexts: fontCharSpacing.setStatus('mandatory')
这是调试器对同一对象上的集合的反馈,i 4 应该在范围内
ValueConstraintError: ConstraintsIntersection(ValueRangeConstraint(-2147483648, 2147483647), ValueRangeConstraint(1, 255)) failed at: ValueConstraintError('ValueRangeConstraint(1, 255) failed at: ValueConstraintError(0,)',) at Integer32
还有几个我认为相关的错误,对我来说似乎 MIB.py 文件没有被正确读取,可能是因为我在自定义 mib 时覆盖了一些代码。具有下一个功能
def createVariable(SuperClass, getValue, sValue, *args):
"""This is going to create a instance variable that we can export.
getValue is a function to call to retreive the value of the scalar
"""
class Var(SuperClass):
def readGet(self, name, *args):
print " Getting var..."
return name, self.syntax.clone(getValue())
def writeTest(self, name, *args ):
print " Testing var..."
def writeCommit(self, name, val, *args ):
print " Setting var..."
sValue(val)
return Var(*args)
我不明白 pysnmp 的结构,所以我无法追溯哪里出了问题,所以如果需要,我可以 post 剩下的代码,这个测试只有几百行。
感谢您提供的任何帮助
要实现动态 SNMP table(您可以通过 SNMP SET create/delete 行),您应该设置 MibTable
、MibTableRow
和 MibTableColumn
个对象:
(MibTable,
MibTableRow,
MibTableColumn,
MibScalarInstance) = mibBuilder.importSymbols(
'SNMPv2-SMI',
'MibTable',
'MibTableRow',
'MibTableColumn',
'MibScalarInstance'
)
并在反映对象层次结构的 OID 下使用 pysnmp 注册它们,例如:
RowStatus, = mibBuilder.importSymbols('SNMPv2-TC', 'RowStatus')
mibBuilder.exportSymbols(
'__EXAMPLE-MIB',
# table object
exampleTable=MibTable((1, 3, 6, 6, 1)).setMaxAccess('readcreate'),
# table row object, also carries references to table indices
exampleTableEntry=MibTableRow((1, 3, 6, 6, 1, 5)).setMaxAccess('readcreate').setIndexNames((0, '__EXAMPLE-MIB', 'exampleTableColumn1')),
# table column: string index
exampleTableColumn1=MibTableColumn((1, 3, 6, 6, 1, 5, 1), v2c.OctetString()).setMaxAccess('readcreate'),
# table column: string value
exampleTableColumn2=MibTableColumn((1, 3, 6, 6, 1, 5, 2), v2c.OctetString()).setMaxAccess('readcreate'),
# table column: integer value with default
exampleTableColumn3=MibTableColumn((1, 3, 6, 6, 1, 5, 3), v2c.Integer32(123)).setMaxAccess('readcreate'),
# table column: row status
exampleTableStatus=MibTableColumn((1, 3, 6, 6, 1, 5, 4), RowStatus('notExists')).setMaxAccess('readcreate')
)
确保说明 table 索引应该是什么样子,例如超过 MibTableColumn
OID 的 OID 尾部。您可以通过将一列或多列配置为 .setIndexNames()
.
如果你想 create/drop 一次拍摄整行,你需要在你的 table 中有一个专门的 status 列类型 RowStatus
的值。您可以在 RFC2579(搜索 RowStatus)中阅读有关 RowStatus
工作原理的详细信息。
此时您应该能够创建新行:
$ snmpset -v2c -c public 127.0.0.1 1.3.6.6.1.5.2.97.98.99 s “my value”
$ snmpset -v2c -c public 127.0.0.1 1.3.6.6.1.5.4.97.98.99 i 4
(OID 的 97.98.99
部分对应 abc
的 exampleTableColumn1
字符串值,这是一个示例索引值。
同时销毁整行:
$ snmpset -v2c -c public 127.0.0.1 1.3.6.6.1.5.4.97.98.99 i 6
当您以这种方式 create/destroy 列时,.createTest()
/createCommit()
和 destroyTest()
/destroyCommit()
方法会在 MibTableColumn
上被调用对象。 writeTest()
/writeCommit()
方法在值修改时被调用。
这些是您可能想要覆盖以控制 pysnmp 之外的东西的方法。
完整的示例脚本可以是 seen here.
请注意,到目前为止,我们还没有使用 mibdump.py
从 ASN.1 MIB 生成任何代码。
如果您需要更多有关代码的实践帮助,我建议您转到 GutHub 上的 pysnmp issues。
理论投篮
对于 SNMP,MIB 的使用有两方面。 SNMP 客户端(例如管理器)使用 MIB 作为“模式”来确定它们从 SNMP 服务器(例如代理)接收的数据。后者实际上是基于MIB schema(schema instance)实现具体的数据结构。
对于 pysnmp,我们使用同一组 Python 类 来实现这两个目的。
- 经理通常只使用架构对象(例如
MibTable
、MibTableRow
、MibTableColumn
和MibScalar
) - 当您打算在 运行 时间管理架构实例对象时,代理将其数据置于架构实例对象 (
MibScalarInstance
) 的控制之下,可能由架构对象操纵。
这有望解释为什么 pysnmp MIB 管理代码看起来与 manager/agent 实现相似。