代码之家  ›  专栏  ›  技术社区  ›  Luiz Fernando Schrickte

如果在创建表时不知道新行索引,如何在pysnmp上启用/使用SNMPv2 RowStatus特性?

  •  1
  • Luiz Fernando Schrickte  · 技术社区  · 7 年前

    我正在使用pysnmp实现一个NTCIP代理,其中有许多表包含SNMPv2 RowStatus列。

    我需要允许客户端在现有代理表上创建新的概念行,但是在创建这些行之前,无法知道这些行的索引。因此,我无法在pysnmp上创建这样的RowStatus对象实例。如果没有此实例,客户端就没有对象可以发出SET命令来向表中添加概念行。

    有没有办法在pysnmp上处理这个问题?可能是一种列通用回调机制或类似的机制。

    2 回复  |  直到 7 年前
        1
  •  1
  •   Luiz Fernando Schrickte    7 年前

    我想我已经发现了创建新行的问题。

    原始(ASN.1)mib文件将所有RowStatus列定义为 读写操作 ,但如果没有符号访问权限,则pysnmp MibTableColumn createTest方法将失败 读取创建 . 更改MIB源上的行状态定义解决了此问题。

    这样做之后,我可以创建新行,但注意到另一个问题:表上的snmp遍历导致超时。问题是pysnmp不知道在新行元素上放置哪些值,这些新行元素不是索引,也没有定义默认值,因此它不放置任何值,这会导致在ASN上进行“尝试的”\uu hash\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu。1架构对象“PyAsn1Error”。为了处理此问题,客户端必须在获取新创建行中的每个字段之前,向其发出SET命令,或向列对象添加默认值(对此不确定,但默认值不是由mibdump作为原始ASN填充的。1 MIB从不定义ITEN的默认值,根据定义,ITEN是非可选的)。下面是我为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)
    
        # ...
    

    不确定这是不是正确的方法,如果我错了,请纠正我。也许我不应该在这里包括这一点,但这是解决原始问题的一部分,可能会帮助其他人。

    谢谢

        2
  •  0
  •   Ilya Etingof    7 年前

    我认为,一般来说,使用SNMP,您无法在不知道表行的索引的情况下远程创建表行。因为索引是传递SNMP代理信息的方式,该行在表中的确切位置。

    从技术角度来说 RowStatus 对象,您需要知道其索引(例如行ID)。

    如果我错了,请解释一下这是怎么回事?

    另一种情况是,您不是远程创建表行,而是通过SNMP表机制公开SNMP代理中已有的数据。然后,您可以仅从现有数据中构建索引。这不需要SNMP管理器事先知道索引。

    如果您的SNMP代理公开了一些信息,SNMP管理器可以使用这些信息为要创建的表行建立适当的索引,那么可能的中间方法就是。

    总而言之,我认为讨论会从你的情况中得到更多提示