LINUX.ORG.RU

SNMP + python не могу получить доступ к строке таблицы

 , , ,


1

1

Всем привет!

Есть агент snmp, написанный на python на основе библиотеки netsnmpagent. Со скалярными переменными всё работает, проблема с таблицами.

Сам агент

#!/usr/bin/env python36

import sys, os, signal, time
import optparse, threading, subprocess

sys.path.insert(0, os.path.dirname(os.getcwd()))
import netsnmpagent

prgname = sys.argv[0]

parser = optparse.OptionParser()
parser.add_option(
	"-i",
	"--interval",
	dest="interval",
	help="Set interval in seconds between data updates",
	default=30
)
parser.add_option(
	"-m",
	"--mastersocket",
	dest="mastersocket",
	help="Sets the transport specification for the master agent's AgentX socket",
	default="/var/run/agentx/master"
)
parser.add_option(
	"-p",
	"--persistencedir",
	dest="persistencedir",
	help="Sets the path to the persistence directory",
	default="/var/lib/net-snmp"
)
(options, args) = parser.parse_args()

headerlogged = 0
def LogMsg(msg):
	""" Writes a formatted log message with a timestamp to stdout. """

	global headerlogged

	if headerlogged == 0:
		print("{0:<8} {1:<90} {2}".format(
			"Time",
			"MainThread",
			"UpdateSNMPObjsThread"
		))
		print("{0:-^120}".format("-"))
		headerlogged = 1

	threadname = threading.currentThread().name

	funcname = sys._getframe(1).f_code.co_name
	if funcname == "<module>":
		funcname = "Main code path"
	elif funcname == "LogNetSnmpMsg":
		funcname = "net-snmp code"
	else:
		funcname = "{0}()".format(funcname)

	if threadname == "MainThread":
		logmsg = "{0} {1:<112.112}".format(
			time.strftime("%T", time.localtime(time.time())),
			"{0}: {1}".format(funcname, msg)
		)
	else:
		logmsg = "{0} {1:>112.112}".format(
			time.strftime("%T", time.localtime(time.time())),
			"{0}: {1}".format(funcname, msg)
		)
	print(logmsg)

def LogNetSnmpMsg(priority, msg):
	""" Log handler for log messages generated by net-snmp code. """

	LogMsg("[{0}] {1}.".format(priority, msg))

# Create an instance of the netsnmpAgent class
try:
	agent = netsnmpagent.netsnmpAgent(
		AgentName      = "ThreadingAgent",
		MasterSocket   = options.mastersocket,
		PersistenceDir = options.persistencedir,
                MIBFiles = ["/usr/share/snmp/mibs/roschat-m0-mib.mib"],
		LogHandler = LogNetSnmpMsg
	)
except netsnmpagent.netsnmpAgentException as e:
	print("{0}: {1}".format(prgname, e))
	sys.exit(1)


from params import Params
params = Params(agent) #здесь вызывается другой скрипт, в котором формируется таблица
params.register()

def UpdateSNMPObjs():
        """ Function that does the actual data update. """

        global threadingString

        LogMsg("Beginning data update.")
        data = ""
        params.update()
        LogMsg("Data update done, exiting thread.")

def UpdateSNMPObjsAsync():
	""" Starts UpdateSNMPObjs() in a separate thread. """

	if threading.active_count() == 1:
		LogMsg("Creating thread for UpdateSNMPObjs().")
		t = threading.Thread(target=UpdateSNMPObjs, name="UpdateSNMPObjsThread")
		t.daemon = True
		t.start()
	else:
		LogMsg("Data update still active, data update interval too low?")

try:
	agent.start()
except netsnmpagent.netsnmpAgentException as e:
	LogMsg("{0}: {1}".format(prgname, e))
	sys.exit(1)

LogMsg("Doing initial call to UpdateSNMPObjsAsync().")
UpdateSNMPObjsAsync()

def TermHandler(signum, frame):
	global loop
	loop = False
signal.signal(signal.SIGINT, TermHandler)
signal.signal(signal.SIGTERM, TermHandler)

def AlarmHandler(signum, frame):
	global loop, timer_triggered

	LogMsg("Got triggered by SIGALRM.")

	if loop:
		timer_triggered = True

		UpdateSNMPObjsAsync()

		signal.signal(signal.SIGALRM, AlarmHandler)
		signal.setitimer(signal.ITIMER_REAL, float(options.interval))
msg = "Installing SIGALRM handler triggered every {0} seconds."
msg = msg.format(options.interval)
LogMsg(msg)
signal.signal(signal.SIGALRM, AlarmHandler)
signal.setitimer(signal.ITIMER_REAL, float(options.interval))

LogMsg("Now serving SNMP requests, press ^C to terminate.")

loop = True
while loop:
	timer_triggered = False
	res = agent.check_and_process()
	if res == -1 and not timer_triggered and loop:
		loop = False
		LogMsg("Error {0} in SNMP packet processing!".format(res))
	elif loop and timer_triggered:
		LogMsg("net-snmp's check_and_process() returned due to SIGALRM (res={0}), doing another loop.".format(res))
	elif loop:
		LogMsg("net-snmp's check_and_process() returned (res={0}), doing another loop.".format(res))

LogMsg("Terminating.")
agent.shutdown()

Скрипт params.py, в котором формируется таблица

import sys,os
from dbusclient import Dbusclient
import yaml
import json

if __name__ == '__main__':
    sys.exit(0)

config = yaml.safe_load(open('/etc/roschat-snmp/conf.d/default.yml'))['snmp']

class Params:
    def __init__(self, agent):
        self.agent = agent
        self.dbus = Dbusclient(config['object'], config['path'], config['iface'])
        self.state = None

    def register(self):
        mib = "ROSCHAT-M0-MIB::roschat-m0."
        self.publicNetwork = self.agent.Integer32(
            oidstr = mib+"publicNetwork",
            # BoolType (1 - no, 2 - yes)
            initval = 1
        )
        self.domainCertificate = self.agent.Integer32(
            oidstr = mib+"domainCertificate",
            initval = 1
        )
        self.domainCertificateTime = self.agent.TimeTicks(
            oidstr = mib+"domainCertificateTime"
        )
        self.userLicense = self.agent.Integer32(
            oidstr = mib+"userLicense",
            initval = 1
        )
        self.userLicenseLimit = self.agent.Integer32(
            oidstr = mib+"userLicenseLimit",
            initval = 0
        )
        self.userLicenseUsed = self.agent.Integer32(
            oidstr = mib+"userLicenseUsed",
            initval = 0
        )
        self.userLicenseTime = self.agent.TimeTicks(
            oidstr = mib+"userLicenseTime"
        )
        self.pushService = self.agent.Integer32(
            oidstr = mib+"pushService",
            initval = 1
        )
        self.pushServiceApple = self.agent.Integer32(
            oidstr = mib+"pushServiceApple",
            initval = 1
        )
        self.pushServiceGoogle = self.agent.Integer32(
            oidstr = mib+"pushServiceGoogle",
            initval = 1
        )
        self.finishElement = self.agent.Integer32(
            oidstr = mib+"finishElement",
            initval = 0
        )
        #здесь формируются столбцы таблицы
        self.serviceTable = self.agent.Table(
            oidstr  = mib+"serviceTable",
	    indexes = [
		self.agent.Integer32()
	    ],
	    columns = [
		(1, self.agent.Integer32(), True),
		(2, self.agent.DisplayString(""), True),
		(3, self.agent.Integer32(), True),
		(4, self.agent.TimeTicks(), True)
	    ],
            counterobj = self.agent.Unsigned32(
                    		#oidstr = "ROSCHAT-M0-MIB::serviceTable.serviceEntry"
                    		oidstr = "ROSCHAT-M0-MIB::serviceEntry"
            ),
	    extendable = True
        )
    # TODO: add providerTable
    def updateServiceTable(self, prev_services_state = [{"name": "", "running": False}]):
        print('UPDate service table')
        serviceState = 0
        serviceStateTime = 0
        self.serviceTable.clear()        
        for i, service in enumerate(self.state['services']):
            serviceName = service['name'].replace('.service', '')
            if service['running']:
                serviceState = 3
                serviceStateTime = service['uptime']
            else:
                serviceState = 1
                serviceStateTime = service['downtime']
            for prevservice in prev_services_state:
                if service['name'] == prevservice['name'] and not service['running'] == prevservice['running']:
                    print('Change service state')
                    if service['running']:
                        self.sendTrap(14, "serviceTable", "s", serviceName)
                    else:
                        self.sendTrap(13, "serviceTable", "s", serviceName)
            #Здесь формируются строки таблицы
            row = self.serviceTable.addRow([self.agent.Integer32(i)])
            row.setRowCell(1, self.agent.Integer32(i))
            row.setRowCell(2, self.agent.DisplayString(serviceName))
            row.setRowCell(3, self.agent.Integer32(serviceState))
            row.setRowCell(4, self.agent.TimeTicks(serviceStateTime))
            
            #return self.agent.serviceTable.value()

    def valueServiceTable(self):
        return self.agent.serviceTable.value()

    def sendTrap(self, trapcode=0, oid="", valuetype="s", value=""):
        config = json.loads(open("/opt/roschat-ms/settings/snmp/snmpConfig.json", "r").read())
        os.system("snmptrap -v 1 -c public  "+config['snmp_trap_host']+":"+config['snmp_trap_port']+" ROSCHAT-M0-MIB::roschat-m0 '' 6 "+str(trapcode)+" '0' ROSCHAT-M0-MIB::roschat-m0."+oid+" "+valuetype+" "+str(value))
            
    def update(self, data=None):
        # TODO: оптимизировать, убрать лишние if, etc
        prev_state = self.state
        if prev_state == None:
            prev_state = {
                "network": {"ok": False},
                "pushStatus": {"status": False},
                "certs": {"errors": []},
                "services": [{"name": "", "running": False}]
            }
        self.state = self.dbus.GetState()
        self.updateServiceTable(prev_state['services']).value()
        if self.state['network']['ok']:
            publicNetwork = 2 # True
            if not self.state['network']['ok'] == prev_state['network']['ok']:
                self.sendTrap(2, "publicNetwork", "i",  publicNetwork)
        else:
            publicNetwork = 1 # False
            if not self.state['network']['ok'] == prev_state['network']['ok']:
                self.sendTrap(1, "publicNetwork", "i",  publicNetwork)
        self.publicNetwork.update(publicNetwork)

        if 'certs' in self.state:
            domainCertificate = 2 # True
            if 'errors' in self.state['certs']:
                if len(self.state['certs']['errors']) > 0:
                    domainCertificate = 1 #False
                    if not self.state['certs']['errors'] == prev_state['certs']['errors']:
                        self.sendTrap(3, "domainCertificate", "i",  domainCertificate)
                else:
                    if not self.state['certs']['errors'] == prev_state['certs']['errors']:
                        self.sendTrap(4, "domainCertificate", "i",  domainCertificate)
            self.domainCertificate.update(domainCertificate)

        if 'pushStatus' in self.state and 'status' in self.state['pushStatus']:
            pushService = 2 # True
            if not self.state['pushStatus']['status'] == prev_state['pushStatus']['status']:
                self.sendTrap(8, "pushService", "i",  pushService)
        else:
            pushService = 1 # False
            if self.state['pushStatus'] and not self.state['pushStatus']['status'] == prev_state['pushStatus']['status']:
                self.sendTrap(7, "pushService", "i",  pushService)
        self.pushService.update(pushService)
            
        self.domainCertificateTime.update(2) # TODO: разобраться с типом данных
        self.userLicense.update(2) # TODO: Что это?
        self.userLicenseLimit.update(203) # TODO: И это тоже что?

Код не мой, поэтому не удивляйтесь комментариям в конце скрипта

MIB файл

ROSCHAT-M0-MIB DEFINITIONS ::= BEGIN
               
IMPORTS
  OBJECT-TYPE
    FROM RFC1155-SMI
  roschat-m
    FROM ROSCHAT-M-MIB
  TRAP-TYPE
    FROM RFC-1215;
                  
roschat-m0   OBJECT IDENTIFIER ::= { roschat-m 1 }
                    
DisplayString  ::= OCTET STRING
DateTimeString ::= DisplayString (SIZE (0..20))
StateType      ::= INTEGER {
                       crush(1),
                       warning(2),
                       ok(3),
                       unknown(4)
                      }
                      
BoolType       ::= INTEGER {
                       no(1),
                       yes(2)
                      }
 --  MIB-II (same prefix as MIB-I)
                                                                         
-- *********************************************************************
-- **************** SCALAR OBJECTS *************************************
-- *********************************************************************
publicNetwork OBJECT-TYPE
      SYNTAX  BoolType
      ACCESS  read-only
      STATUS  mandatory
      DESCRIPTION
          "Status access to public network"
      ::= { roschat-m0 1 }
domainCertificate OBJECT-TYPE
      SYNTAX  BoolType
      ACCESS  read-only
      STATUS  mandatory
      DESCRIPTION
          "Validating domain certificate"
      ::= { roschat-m0 2 }
domainCertificateTime OBJECT-TYPE
      SYNTAX  TimeTicks
      ACCESS  read-only
      STATUS  mandatory
      DESCRIPTION
          "Time limit of domain certificate"
      ::= { roschat-m0 3 }
      
userLicense OBJECT-TYPE
      SYNTAX  BoolType
      ACCESS  read-only
      STATUS  mandatory
      DESCRIPTION
          "Validating license"
      ::= { roschat-m0 4 }
userLicenseLimit OBJECT-TYPE
      SYNTAX  INTEGER
      ACCESS  read-only
      STATUS  mandatory
      DESCRIPTION
          "User limit of license"
      ::= { roschat-m0 5 }
userLicenseUsed OBJECT-TYPE
      SYNTAX  INTEGER
      ACCESS  read-only
      STATUS  mandatory
      DESCRIPTION
          "Used user of license"
      ::= { roschat-m0 6 }
userLicenseTime OBJECT-TYPE
      SYNTAX  TimeTicks
      ACCESS  read-only
      STATUS  mandatory
      DESCRIPTION
          "Time limit of license"
      ::= { roschat-m0 7 }
      
pushService OBJECT-TYPE
      SYNTAX  BoolType
      ACCESS  read-only
      STATUS  mandatory
      DESCRIPTION
          "Status access to push service"
      ::= { roschat-m0 8 }
      
pushServiceApple OBJECT-TYPE
      SYNTAX  BoolType
      ACCESS  read-only
      STATUS  mandatory
      DESCRIPTION
          "Status access to push service Apple (APNS)"
      ::= { roschat-m0 9 }
      
pushServiceGoogle OBJECT-TYPE
      SYNTAX  BoolType
      ACCESS  read-only
      STATUS  mandatory
      DESCRIPTION
          "Status access to push service Google (GCM)"
      ::= { roschat-m0 10 }
finishElement OBJECT-TYPE
      SYNTAX  INTEGER
      ACCESS  read-only
      STATUS  mandatory
      DESCRIPTION
          "Terminated element"
      ::= { roschat-m0 32767 }
               
-- *********************************************************************
-- **************** TABLE OBJECTS **************************************
-- ********************************************************************* 
-- *********************************************************************
-- Service Table
-- *********************************************************************
serviceTable OBJECT-TYPE
      SYNTAX  SEQUENCE OF ServiceEntry
      ACCESS  not-accessible
      STATUS  mandatory
      DESCRIPTION
          "Service table"   
      ::= { roschat-m0 11 }
      serviceEntry OBJECT-TYPE
            SYNTAX  ServiceEntry
            ACCESS  not-accessible
            STATUS  mandatory
            INDEX { ServiceNum }        
      ::= { serviceTable 1 }
      ServiceEntry ::= SEQUENCE {
                               serviceNum         INTEGER,
                               serviceName        DisplayString,
                               serviceState       StateType,
                               serviceStateTime   DateTimeString
                              }
            serviceNum OBJECT-TYPE
                  SYNTAX  INTEGER
                  ACCESS  read-only
                  STATUS  mandatory
                  DESCRIPTION
                      "# Service"
                  ::= { serviceEntry 1 }
            serviceName  OBJECT-TYPE
                  SYNTAX  DisplayString (SIZE (0..255))
                  ACCESS  read-only
                  STATUS  mandatory
                  DESCRIPTION
                      "Service name"
                  ::= { serviceEntry 2 }
            serviceState  OBJECT-TYPE
                  SYNTAX  StateType
                  ACCESS  read-only
                  STATUS  mandatory
                  DESCRIPTION
                      "Service state"
                  ::= { serviceEntry 3 }
                                    
            serviceStateTime OBJECT-TYPE
                  SYNTAX  DateTimeString
                  ACCESS  read-only
                  STATUS  mandatory
                  DESCRIPTION
                      "Service setted time"
                  ::= { serviceEntry 4 }
                              
-- *********************************************************************
-- Provider Table
-- *********************************************************************                                             
providerTable OBJECT-TYPE
      SYNTAX  SEQUENCE OF ProviderEntry
      ACCESS  not-accessible
      STATUS  mandatory
      DESCRIPTION
          "Provider table"
      ::= { roschat-m0 12 }
      providerEntry OBJECT-TYPE
            SYNTAX  ProviderEntry
            ACCESS  not-accessible
            STATUS  mandatory
            INDEX { providerNum }
            ::= { providerTable 1 }
      ProviderEntry ::= SEQUENCE {
                               providerNum         INTEGER,
                               providerName        DisplayString,
                               providerDescription DisplayString,
                               providerAdress      DisplayString,
                               providerState       StateType,
                              }
            providerNum OBJECT-TYPE
                  SYNTAX  INTEGER
                  ACCESS  read-only
                  STATUS  mandatory
                  DESCRIPTION
                      "# Provider"
                  ::= { providerEntry 1 }
                  
            providerName  OBJECT-TYPE
                  SYNTAX  DisplayString (SIZE (1..255))
                  ACCESS  read-only
                  STATUS  mandatory
                  DESCRIPTION
                      "Provider name"
                  ::= { providerEntry 2 }
                  
            providerDescription  OBJECT-TYPE
                  SYNTAX  DisplayString
                  ACCESS  read-only
                  STATUS  mandatory
                  DESCRIPTION
                      "Provider description"
                  ::= { providerEntry 3 }
                  
            providerAdress  OBJECT-TYPE
                  SYNTAX  DisplayString (SIZE (0..32))
                  ACCESS  read-only
                  STATUS  mandatory
                  DESCRIPTION
                      "Provider adress"
                  ::= { providerEntry 4 }
            providerState  OBJECT-TYPE
                  SYNTAX  StateType
                  ACCESS  read-only
                  STATUS  mandatory
                  DESCRIPTION
                      "Provider state"
                  ::= { providerEntry 5 }
-- *********************************************************************
-- **************** TRAPS **********************************************
-- ********************************************************************* 
agentOffTrap TRAP-TYPE
        ENTERPRISE roschat-m0
        DESCRIPTION
                "Agent Off"
        ::= 1
agentOnTrap TRAP-TYPE
        ENTERPRISE roschat-m0
        DESCRIPTION
                "Agent On"
        ::= 2
        
publicNetworkNo  TRAP-TYPE
        ENTERPRISE roschat-m0
        VARIABLES { publicNetwork }
        DESCRIPTION
                "Denied access to public network"
        ::= 3
        
publicNetworkYes  TRAP-TYPE
        ENTERPRISE roschat-m0
        VARIABLES { publicNetwork }
        DESCRIPTION
                "Access to public network is present"
        ::= 4
        
domainCertificateInvalid TRAP-TYPE
        ENTERPRISE roschat-m0
        VARIABLES { domainCertificate }
        DESCRIPTION
                "Invalide domain certificate"
        ::= 5
        
domainCertificateValid TRAP-TYPE
        ENTERPRISE roschat-m0
        VARIABLES { domainCertificate }
        DESCRIPTION
                "Valide domain certificate"
        ::= 6
        
userLicenseInvalid TRAP-TYPE
        ENTERPRISE roschat-m0
        VARIABLES { userLicense }
        DESCRIPTION
                "Invalide user license"
        ::= 7
        
domainCertificateValid TRAP-TYPE
        ENTERPRISE roschat-m0
        VARIABLES { userLicense }
        DESCRIPTION
                "Valide user license"
        ::= 8
        
pushServiceNo  TRAP-TYPE
        ENTERPRISE roschat-m0
        VARIABLES { pushService }
        DESCRIPTION
                "Denied access to push service"
        ::= 9
        
pushServiceYes  TRAP-TYPE
        ENTERPRISE roschat-m0
        VARIABLES { pushService }
        DESCRIPTION
                "Denied access to push service"
        ::= 10
        
pushServiceAplleNo  TRAP-TYPE
        ENTERPRISE roschat-m0
        VARIABLES { pushServiceApple }
        DESCRIPTION
                "Denied access to push service Aplle"
        ::= 11
        
pushServiceAplleYes  TRAP-TYPE
        ENTERPRISE roschat-m0
        VARIABLES { pushServiceApple }
        DESCRIPTION
                "Denied access to push service Aplle"
        ::= 12
        
pushServiceGoogleNo  TRAP-TYPE
        ENTERPRISE roschat-m0
        VARIABLES { pushServiceGoogle }
        DESCRIPTION
                "Denied access to push service Google"
        ::= 13
        
pushServiceGoogleYes  TRAP-TYPE
        ENTERPRISE roschat-m0
        VARIABLES { pushServiceGoogle }
        DESCRIPTION
                "Denied access to push service Google"
        ::= 14
                
serviceStateCrush  TRAP-TYPE
        ENTERPRISE roschat-m0
        VARIABLES { serviceState }
        DESCRIPTION
                "Service state is Crush"
        ::= 15
        
serviceStateOk  TRAP-TYPE
        ENTERPRISE roschat-m0
        VARIABLES { serviceState }
        DESCRIPTION
                "Service state is Ok"
        ::= 16
                
providerStateCrush  TRAP-TYPE
        ENTERPRISE roschat-m0
        VARIABLES { providerState }
        DESCRIPTION
                "Provider state is Crush"
        ::= 17
        
providerStateOk  TRAP-TYPE
        ENTERPRISE roschat-m0
        VARIABLES { providerState }
        DESCRIPTION
                "Provider state is Ok"
        ::= 18
END

При запросе таблицы всё отображается корректно вроде бы

snmptable -v 1 -c public localhost ROSCHAT-M0-MIB::serviceTable
SNMP table: ROSCHAT-M0-MIB::serviceTable

 serviceNum    serviceName serviceState serviceStateTime
          0     "kamailio"           ok   29:20:04:34.51
          1    "rtpengine"           ok   32:12:46:35.84
          2   "roschat-ms"           ok   130:5:18:26.04
          3         "wlan"           ok    9:11:53:49.05
          4   "turnserver"           ok  283:13:26:41.34
          5   "roschat-db"           ok  283:13:21:41.17
          6 "roschat-snmp"           ok     0:3:12:37.02
          7   "gw-booster"        crush    52:5:49:14.66

Дерево таблицы тоже выстраивается

snmpwalk -v 2c -c public localhost ROSCHAT-M0-MIB::serviceTable
ROSCHAT-M0-MIB::serviceEntry.0 = Gauge32: 8
ROSCHAT-M0-MIB::serviceNum.0 = INTEGER: 0
ROSCHAT-M0-MIB::serviceNum.1 = INTEGER: 1
ROSCHAT-M0-MIB::serviceNum.2 = INTEGER: 2
ROSCHAT-M0-MIB::serviceNum.3 = INTEGER: 3
ROSCHAT-M0-MIB::serviceNum.4 = INTEGER: 4
ROSCHAT-M0-MIB::serviceNum.5 = INTEGER: 5
ROSCHAT-M0-MIB::serviceNum.6 = INTEGER: 6
ROSCHAT-M0-MIB::serviceNum.7 = INTEGER: 7
ROSCHAT-M0-MIB::serviceName.0 = STRING: "kamailio"
ROSCHAT-M0-MIB::serviceName.1 = STRING: "rtpengine"
ROSCHAT-M0-MIB::serviceName.2 = STRING: "roschat-ms"
ROSCHAT-M0-MIB::serviceName.3 = STRING: "wlan"
ROSCHAT-M0-MIB::serviceName.4 = STRING: "turnserver"
ROSCHAT-M0-MIB::serviceName.5 = STRING: "roschat-db"
ROSCHAT-M0-MIB::serviceName.6 = STRING: "roschat-snmp"
ROSCHAT-M0-MIB::serviceName.7 = STRING: "gw-booster"
ROSCHAT-M0-MIB::serviceState.0 = INTEGER: ok(3)
ROSCHAT-M0-MIB::serviceState.1 = INTEGER: ok(3)
ROSCHAT-M0-MIB::serviceState.2 = INTEGER: ok(3)
ROSCHAT-M0-MIB::serviceState.3 = INTEGER: ok(3)
ROSCHAT-M0-MIB::serviceState.4 = INTEGER: ok(3)
ROSCHAT-M0-MIB::serviceState.5 = INTEGER: ok(3)
ROSCHAT-M0-MIB::serviceState.6 = INTEGER: ok(3)
ROSCHAT-M0-MIB::serviceState.7 = INTEGER: crush(1)
ROSCHAT-M0-MIB::serviceStateTime.0 = Timeticks: (257848363) 29 days, 20:14:43.63
ROSCHAT-M0-MIB::serviceStateTime.1 = Timeticks: (281140496) 32 days, 12:56:44.96
ROSCHAT-M0-MIB::serviceStateTime.2 = Timeticks: (1125171516) 130 days, 5:28:35.16
ROSCHAT-M0-MIB::serviceStateTime.3 = Timeticks: (82103817) 9 days, 12:03:58.17
ROSCHAT-M0-MIB::serviceStateTime.4 = Timeticks: (2450021046) 283 days, 13:36:50.46
ROSCHAT-M0-MIB::serviceStateTime.5 = Timeticks: (2449991029) 283 days, 13:31:50.29
ROSCHAT-M0-MIB::serviceStateTime.6 = Timeticks: (59773) 0:09:57.73
ROSCHAT-M0-MIB::serviceStateTime.7 = Timeticks: (451436378) 52 days, 5:59:23.78

Но вот, когда запрашиваю конкретный OID, получаю ошибку

snmpget -v 1 -c public localhost ROSCHAT-M0-MIB::serviceState.2
Error in packet
Reason: (noSuchName) There is no such variable name in this MIB.
Failed object: ROSCHAT-M0-MIB::serviceState.2

Подскажите, как формировать таблицу, чтобы получить доступ к OID таблице?

Подскажите, как формировать таблицу, чтобы получить доступ к OID таблице?

Да вроде нормальная таблица.
А по числовому OID удается получить значение поля?

Я бы что еще сделал:
1) Попробовал (сильно) другую версию snmp-net;
2) Попробовал почистить MIB от trap'ов и вообще от всего, не относящегося к искомой таблице. Посмотрел, заработало бы так (нет ли конфликтов каких).

Tayler ★★ ()
Ответ на: комментарий от Tayler

Разобрались

После долгих и мучительных разбирательств, заработало. Нужно было сделать так

self.serviceTable = self.agent.Table(
            oidstr  = mib+"serviceTable",
	    indexes = [
		self.agent.Integer32()
	    ],
	    columns = [
		(1, self.agent.Integer32(), True),
		(2, self.agent.DisplayString(""), True),
		(3, self.agent.Integer32(), True),
		(4, self.agent.TimeTicks(), True)
	    ],            
	    extendable = True
        )
pbezpal ()