我正在使用pysnmp实现一个NTCIP代理,其中包含许多包含SNMPv2 RowStatus列的表。
我需要允许客户端在现有代理表上创建新的概念行,但是在创建之前无法知道这些行的索引。因此,我无法在pysnmp上创建此类RowStatus对象实例。没有这个实例,客户端没有对象发出SET命令,以便向表中添加概念行。
有没有办法在pysnmp上处理这个?也许是列通用回调机制或类似的东西。
答案 0 :(得分:1)
我想我发现了创建新行的问题。
原始(ASN.1)mib文件将所有RowStatus列定义为读写,但如果符号访问权限不是 read-create ,则pysnmp MibTableColumn createTest方法将失败。更改MIB源上的RowStatus定义解决了这个问题。
执行此操作后,我可以创建新行,但注意到另一个问题:在表上执行snmp会导致超时。问题是pysnmp不知道哪些值放在不是索引的新行元素上并且没有定义默认值,所以它放置None - 这导致在ASN.1模式对象上'尝试'__hash__“操作' PyAsn1Error。为了处理这个问题,客户端必须在获取它们之前向新创建的行中的每个字段发出SET命令,或者向列对象添加默认值(不确定,但默认值不会被mibdump填充为原始ASN.1 mibs永远不会根据定义,定义itens的默认值,这些默认值不是可选的。我的导出我的StaticTable类列的代码如下(不完整的代码,但我认为一些方法和属性名称可以自己说明。)
def add_create_test_callback(superclass, create_callback, error_callback=None):
"""Create a class based on superclass that calls callback function when element is changed"""
class VarCCb(superclass):
def createTest(self, name, val, idx, acInfo):
if create_callback and val in [4, 'createAndWait', 5, 'createAndGo']:
superclass.createTest(self, name, val, idx, acInfo)
create_callback(name, val, idx, acInfo)
else:
if error_callback:
error_callback(name, 'optionNotSupported')
raise error.NoCreationError(idx=idx, name=name)
return VarCCb
class StaticTable:
# ....
def config_cols(self):
"""Add callback do RowStatus columns and default values for other columns that are not indices"""
MibTableColumn, = self.mib_builder.importSymbols('SNMPv2-SMI', 'MibTableColumn')
_, column_symbols = self.import_column_symbols()
for index, symbol in enumerate(column_symbols):
if symbol.syntax.__class__.__name__ == 'DcmRowStatus':
# add callback for row creation on all row status columns
MibTableColumnWCb = add_create_test_callback(MibTableColumn, self.create_callback,
self.error_callback)
# setMaxAccess needs to be defined, otherwise symbol is defaulted as readonly
new_col = MibTableColumnWCb(symbol.name, symbol.syntax.clone()).setMaxAccess('readcreate')
named_col = {symbol.label: new_col}
elif index >= self.index_n and self.column_default_values:
new_col = MibTableColumn(symbol.name, symbol.syntax.clone(self.column_default_values[index]))
named_col = {symbol.label: new_col}
else:
new_col = None
named_col = None
if new_col:
self.mib_builder.unexportSymbols(self.mib_name, symbol.label)
self.mib_builder.exportSymbols(self.mib_name, **named_col)
# ...
不确定这是否是正确的方法,如果我错了请纠正我。也许我不应该在这里包括它,但它是解决原始问题的方法的一部分,可能会帮助其他人。
谢谢!
答案 1 :(得分:0)
我认为通常使用SNMP,您无法在不知道其索引的情况下远程创建表行。因为索引是传递SNMP代理的方式,所以该行的确切位于表中。
在技术术语中,要为列调用RowStatus
对象,您需要知道其索引(例如行ID)。
如果我弄错了,请解释一下这是怎么回事?
另一种情况是,您不是远程创建表行,而只是通过SNMP表机制公开SNMP代理中已有的数据。然后你可以从现有数据中建立索引。这不需要您的SNMP管理员事先知道索引。
如果您的SNMP代理公开了SNMP管理器可以用来为要创建的表行构建正确索引的一些信息,那么可能的中间方法就是这样。
总而言之,我认为讨论会受益于对您情况的更多暗示。 ; - )