Как добавить несколько строк таблицы с помощью индекса, а также извлечь эти строки с помощью агента PYSNMP динамически - PullRequest
0 голосов
/ 27 января 2020

Я внедряю таблицы SNMP с помощью агента PYSNMP. Успешно реализована программа, которая работает для одного ряда таблицы. Я хотел бы расширить эту программу, чтобы динамически добавлять несколько строк таблицы, используя индекс в качестве ссылки. Кроме того, необходимо извлечь строки таблицы на основе индекса.

http://snmplabs.com/pysnmp/examples/v3arch/asyncore/agent/cmdrsp/agent-side-mib-implementations.html

Используя ссылку «Выше», реализован небольшой прототип путем добавления строк со значениями stati c (жестко заданы).

Но я не уверен, как динамически добавлять и извлекать строки, используя приведенную ниже программу. Может ли кто-нибудь выдвинуть некоторые идеи или любые логики c для таблиц SNMP.

Программа

'''
Create an MIB agent that interacts with another monitor instance
'''
from pysnmp.entity import engine, config
from pysnmp import debug
from pysnmp.entity.rfc3413 import cmdrsp, context, ntforg
from pysnmp.carrier.asynsock.dgram import udp
from pysnmp.smi import builder
from pysnmp.proto.api import v2c

import threading
import collections
import sys
import time

MibObject = collections.namedtuple('MibObject', ['mibName',
                                   'objectType', 'valueFunc','valueSetFunc'])

TBL='TBL-MIB'

class Mib(object):

    def __init__(self):
        self._lock = threading.RLock()
        self.index = 1
        self.addr = 255
        self.multicastInterval = 1234
        self.maxRetry=5

    def getAddr(self):
        return self.addr

    def getMaxRetry(self):
        with self._lock:
            return self.maxRetry

    def setMaxRetry(self, value):
        with self._lock:
            self.maxRetry = value

    def getMulticastInterval(self):
        with self._lock:
            return self.multicastInterval

    def setMulticastInterval(self, value):
        with self._lock:
            self.multicastInterval = value
def createVariable(SuperClass, getValue, setValue, *args):
    """This is going to create a instance variable that we can export to the monitor. 
    getValue is a function to call to retreive the value of the scalar
    setValue is a function to set the value of a scalar
    """
    class Var(SuperClass):
        def readGet(self, name, *args):
                print "Getting obj"
                return name, self.syntax.clone(getValue())

        def writeCommit(self, name, val, *args ):
                print "Setting obj..."
                setValue(val)

    return Var(*args)


class SNMPAgent(object):
    """Implements an Agent that serves the custom MIB and
    can send a trap.
    """

    def __init__(self, mibObjects):
        """
        mibObjects - a list of MibObject tuples that this agent
        will serve
        """

        #each SNMP-based application has an engine
        self._snmpEngine = engine.SnmpEngine()

        config.addSocketTransport(self._snmpEngine, udp.domainName,
                                  udp.UdpTransport().openServerMode(('10.0.2.15', 161)))

        config.addV1System(self._snmpEngine, "agent", "public")
        config.addV1System(self._snmpEngine, 'my-write-area', 'private')

        config.addVacmUser(self._snmpEngine, 2, "agent", "noAuthNoPriv",
                           readSubTree=(1,3,6,1,4,1))

        config.addVacmUser(self._snmpEngine, 2, 'my-write-area', 'noAuthNoPriv', readSubTree=(1, 3, 6, 1, 4, 1), writeSubTree=(1, 3, 6, 1, 4, 1))

        #Create Agent context
        self._snmpContext = context.SnmpContext(self._snmpEngine)
mibBuilder = self._snmpContext.getMibInstrum().getMibBuilder()
        mibSources = mibBuilder.getMibSources() + (builder.DirMibSource('.'),)
        mibBuilder.setMibSources(*mibSources)

        (MibTable,
        MibTableRow,
        MibTableColumn,
        MibScalarInstance) = mibBuilder.importSymbols(
            'SNMPv2-SMI',
            'MibTable',
            'MibTableRow',
            'MibTableColumn',
            'MibScalarInstance')

        #export our custom mib
        for mibObject in mibObjects:

            nextVar, = mibBuilder.importSymbols(mibObject.mibName,
                                                mibObject.objectType)

            instance = createVariable(MibScalarInstance,
                                      mibObject.valueFunc,
                                      mibObject.valueSetFunc,
                                      nextVar.name, (0,),
                                      nextVar.syntax)
            #need to export as <var name>Instance
            instanceDict = {str(nextVar.name)+"Instance":instance}
            print instanceDict

            mibBuilder.exportSymbols(mibObject.mibName,
                                     **instanceDict)

        # tell pysnmp to respond to get, set, getnext, and getbulk
        cmdrsp.GetCommandResponder(self._snmpEngine, self._snmpContext)
        cmdrsp.SetCommandResponder(self._snmpEngine,self._snmpContext)
        cmdrsp.NextCommandResponder(self._snmpEngine, self._snmpContext)
        cmdrsp.BulkCommandResponder(self._snmpEngine, self._snmpContext)

    def serve_forever(self):
        print "Starting agent"
        self._snmpEngine.transportDispatcher.jobStarted(1)
        try:
           self._snmpEngine.transportDispatcher.runDispatcher()
        except:
            self._snmpEngine.transportDispatcher.closeDispatcher()
            raise


if __name__ == '__main__':
    mib = Mib()

    objects = [
        MibObject(TBL, 'addr', mib.getAddr, ''),
        MibObject(TBL, 'maxRetry', mib.getMaxRetry,
                  mib.setMaxRetry),
        MibObject(TBL, 'multicastInterval', mib.getMulticastInterval,
                  mib.setMulticastInterval)
          ]

    agent = SNMPAgent(objects)
    try:
        agent.serve_forever()
    except KeyboardInterrupt:
        print "Shutting down"

TBL-MIB.py

 # PySNMP MIB module TBL-MIB (http://snmplabs.com/pysmi)
    # ASN.1 source file:///PYSNMP_AGENT/TBL-MIB
    # Produced by pysmi-0.3.4 at Mon Jan 27 11:35:51 2020
    # On host HS-CLONE platform Linux version 5.0.0-38-generic by user root
    # Using Python version 2.7.16 (default, Oct  7 2019, 17:36:04) 
    #
    Integer, ObjectIdentifier, OctetString = mibBuilder.importSymbols("ASN1", "Integer", "ObjectIdentifier", "OctetString")
    NamedValues, = mibBuilder.importSymbols("ASN1-ENUMERATION", "NamedValues")
    ConstraintsUnion, SingleValueConstraint, ConstraintsIntersection, ValueSizeConstraint, ValueRangeConstraint = mibBuilder.importSymbols("ASN1-REFINEMENT", "ConstraintsUnion", "SingleValueConstraint", "ConstraintsIntersection", "ValueSizeConstraint", "ValueRangeConstraint")
    netSnmpPlaypen, = mibBuilder.importSymbols("NET-SNMP-MIB", "netSnmpPlaypen")
    NotificationGroup, ModuleCompliance = mibBuilder.importSymbols("SNMPv2-CONF", "NotificationGroup", "ModuleCompliance")
    Integer32, MibScalar, MibTable, MibTableRow, MibTableColumn, NotificationType, MibIdentifier, IpAddress, TimeTicks, Counter64, Unsigned32, ModuleIdentity, Gauge32, iso, ObjectIdentity, Bits, Counter32 = mibBuilder.importSymbols("SNMPv2-SMI", "Integer32", "MibScalar", "MibTable", "MibTableRow", "MibTableColumn", "NotificationType", "MibIdentifier", "IpAddress", "TimeTicks", "Counter64", "Unsigned32", "ModuleIdentity", "Gauge32", "iso", "ObjectIdentity", "Bits", "Counter32")
    DisplayString, TextualConvention = mibBuilder.importSymbols("SNMPv2-TC", "DisplayString", "TextualConvention")
    sample = ModuleIdentity((1, 3, 6, 1, 4, 1, 8072, 9999, 9999, 1))
    sample.setRevisions(('2019-09-21 00:00',))
    if mibBuilder.loadTexts: sample.setLastUpdated('201909210000Z')
    if mibBuilder.loadTexts: sample.setOrganization('xxx')
    acctStatsTable = MibTable((1, 3, 6, 1, 4, 1, 8072, 9999, 9999, 1, 1), )
    if mibBuilder.loadTexts: acctStatsTable.setStatus('current')
    acctStatsEntry = MibTableRow((1, 3, 6, 1, 4, 1, 8072, 9999, 9999, 1, 1, 1), ).setIndexNames((0, "TBL-MIB", "index"))
    if mibBuilder.loadTexts: acctStatsEntry.setStatus('current')
    index = MibTableColumn((1, 3, 6, 1, 4, 1, 8072, 9999, 9999, 1, 1, 1, 1), Unsigned32())
    if mibBuilder.loadTexts: index.setStatus('current')
    addr = MibTableColumn((1, 3, 6, 1, 4, 1, 8072, 9999, 9999, 1, 1, 1, 2), Unsigned32().subtype(subtypeSpec=ValueRangeConstraint(0, 255))).setMaxAccess("readonly")
    if mibBuilder.loadTexts: addr.setStatus('current')
    maxRetry = MibTableColumn((1, 3, 6, 1, 4, 1, 8072, 9999, 9999, 1, 1, 1, 3), Unsigned32()).setMaxAccess("readwrite")
    if mibBuilder.loadTexts: maxRetry.setStatus('current')
    multicastInterval = MibTableColumn((1, 3, 6, 1, 4, 1, 8072, 9999, 9999, 1, 1, 1, 4), Unsigned32()).setMaxAccess("readwrite")
    if mibBuilder.loadTexts: multicastInterval.setStatus('current')
    mibBuilder.exportSymbols("TBL-MIB", maxRetry=maxRetry, index=index, addr=addr, acctStatsTable=acctStatsTable, sample=sample, acctStatsEntry=acctStatsEntry, PYSNMP_MODULE_ID=sample, multicastInterval=multicastInterval)

Из анализа я нашел фрагмент кода. Но не уверен, как добавить / передать индекс здесь.

 instanceDict = {str(nextVar.name)+"Instance":instance}
...