Реализация таблицы в агенте PySNMP

Я реализую таблицу, используя PySNMP в качестве агента SNMP.

Я следовал архитектуре (источник PySNMP) с использованием автоматически сгенерированного файла TRS-MIB.py и вручную написанного файла __TRS-MIB.py, который содержит реализацию.

Я сделал рабочую (2-строчную) таблицу, но код действительно уродлив, поэтому должен быть лучший способ сделать это. (Кроме того, обе строки всегда будут иметь одинаковые значения, что является ошибкой.)

__TRS-MIB.py:

# Imported just in case new ASN.1 types would be created
from pyasn1.type import constraint, namedval
import time

# Imports

( Integer,
  ObjectIdentifier,
  OctetString, ) = mibBuilder.importSymbols(
  "ASN1",
  "Integer",
  "ObjectIdentifier",
  "OctetString"
  )
( Bits,
  Integer32,
  ModuleIdentity,
  MibIdentifier,
  MibScalar,
  MibScalarInstance,
  TimeTicks, ) = mibBuilder.importSymbols(
  "SNMPv2-SMI",
  "Bits",
  "Integer32",
  "ModuleIdentity",
  "MibIdentifier",
  "MibScalar",
  "MibScalarInstance",
  "TimeTicks"
  )

class TrsDeliveryTime(Integer32):
  def clone(self, **kwargs):
    if 'value' not in kwargs:
      kwargs['value'] = int(time.time())
    return Integer32.clone(self, **kwargs)

class TrsMessagesPerHour(Integer32):
  def clone(self, **kwargs):
    if 'value' not in kwargs:
      kwargs['value'] = -int(time.time())
    return Integer32.clone(self, **kwargs)

class TrsGatewayIndex(Integer32):
  def clone(self, **kwargs):
    if 'value' not in kwargs:
      kwargs['value'] = 0
    return Integer32.clone(self, **kwargs)

class TrsGatewayName(OctetString):
  def clone(self, **kwargs):
    if 'value' not in kwargs:
      kwargs['value'] = 'SMG0'
    return OctetString.clone(self, **kwargs)

class TrsGatewayState(OctetString):
  def clone(self, **kwargs):
    if 'value' not in kwargs:
      kwargs['value'] = 'UP' + str(int(time.time()))
    return OctetString.clone(self, **kwargs)

# Objects
( trsDeliveryTime,
  trsMessagesPerHour,
  trsGatewayTable,
  trsGatewayEntry,
  trsGatewayIndex,
  trsGatewayName,
  trsGatewayState, ) = mibBuilder.importSymbols(
  'TRS-MIB',
  'trsDeliveryTime',
  'trsMessagesPerHour',
  'trsGatewayTable',
  'trsGatewayEntry',
  'trsGatewayIndex',
  'trsGatewayName',
  'trsGatewayState', 
  )
__trsDeliveryTime = MibScalarInstance(trsDeliveryTime.name, (0,), TrsDeliveryTime(0))
__trsMessagesPerHour = MibScalarInstance(trsMessagesPerHour.name, (0,), TrsMessagesPerHour(0))
__trsGatewayIndex0 = MibScalarInstance(trsGatewayIndex.name, (0,), TrsGatewayIndex(0))
__trsGatewayName0 = MibScalarInstance(trsGatewayName.name, (0,), TrsGatewayName(0))
__trsGatewayState0 = MibScalarInstance(trsGatewayState.name, (0,), TrsGatewayState(0))
__trsGatewayIndex1 = MibScalarInstance(trsGatewayIndex.name, (1,), TrsGatewayIndex(0))
__trsGatewayName1 = MibScalarInstance(trsGatewayName.name, (1,), TrsGatewayName(0))
__trsGatewayState1 = MibScalarInstance(trsGatewayState.name, (1,), TrsGatewayState(0))


# Augmentions

# Exports

# Objects
mibBuilder.exportSymbols("__TRS-MIB",
                         trsDeliveryTime=__trsDeliveryTime,
                         trsMessagesPerHour=__trsMessagesPerHour,
                         trsGatewayTable=trsGatewayTable,
                         trsGatewayIndex0=__trsGatewayIndex0,
                         trsGatewayName0=__trsGatewayName0,
                         trsGatewayState0=__trsGatewayState0,
                         trsGatewayIndex1=__trsGatewayIndex1,
                         trsGatewayName1=__trsGatewayName1,
                         trsGatewayState1=__trsGatewayState1,
                         )

person fadedbee    schedule 12.09.2012    source источник


Ответы (1)


Не притворяясь, что это красивый код, вот небольшая оптимизация вашей первоначальной версии. Это не проверено, так как у меня нет под рукой вашего файла TRS-MIB.

Идея состоит в том, чтобы специализировать класс MibScalarInstance (чтобы он обслуживал разные столбцы), переопределив его метод readGet(), который возвращает пару var-bind для отправки обратно диспетчеру SNMP.

Вы должны иметь возможность запускать этот MIB со стандартным CommandResponder, просто не забудьте загрузить свой MIB при запуске.

import time

# Import managed objects
( trsDeliveryTime,
  trsMessagesPerHour,
  trsGatewayIndex,
  trsGatewayName,
  trsGatewayState, ) = mibBuilder.importSymbols(
  'TRS-MIB',
  'trsDeliveryTime',
  'trsMessagesPerHour',
  'trsGatewayIndex',
  'trsGatewayName',
  'trsGatewayState', 
  )

# Columnar managed objects instances implementation

class TrsDeliveryTimeInstance(MibScalarInstance):
  def readGet(self, name, val, *args):
    if name[-1] == 0:  # Row #0
      return self.name, self.syntax(int(time.time()))
    elif name[-1] == 1: # Row #1
      return self.name, self.syntax(time.time()//2)
    else:
      MibScalarInstance.readGet(self, name, val, *args)

class TrsMessagesPerHourInstance(MibScalarInstance):
  def readGet(self, name, val, *args):
    if name[-1] == 0: # Row #0
      return self.name, self.syntax(-int(time.time()))
    elif name[-1] == 1: # Row #1
      return self.name, self.syntax(-time.time()//2)
    else:
      MibScalarInstance.readGet(self, name, val, *args)

class TrsGatewayIndexInstance(MibScalarInstance):
  def readGet(self, name, val, *args):
    if name[-1] == 0: # Row #0
      return self.name, self.syntax(0)
    elif name[-1] == 1: # Row #1
      return self.name, self.syntax(1)
    else:
      MibScalarInstance.readGet(self, name, val, *args)

class TrsGatewayNameInstance(MibScalarInstance):
  def readGet(self, name, val, *args):
    if name[-1] == 0: # Row #0
      return self.name, self.syntax('SMG0')
    elif name[-1] == 1: # Row #1
      return self.name, self.syntax('SMG1')
    else:
      MibScalarInstance.readGet(self, name, val, *args)

class TrsGatewayStateInstance(MibScalarInstance):
  def readGet(self, name, val, *args):
    if name[-1] == 0: # Row #0
      return self.name, self.syntax('UP' + str(time.time()))
    elif name[-1] == 1: # Row #1
      return self.name, self.syntax('DOWN' + str(time.time()))
    else:
      MibScalarInstance.readGet(self, name, val, *args)

# Instantiate and export managed objects instances
mibBuilder.exportSymbols(
  "__TRS-MIB",
  # Row #0
  TrsDeliveryTimeInstance(trsDeliveryTime.getName(), 0, trsDeliveryTime.getSyntax()),
  TrsMessagesPerHourInstance(trsMessagesPerHour.getName(), 0, trsMessagesPerHour.getSyntax()),
  TrsGatewayIndexInstance(trsGatewayIndex.getName(), 0, trsGatewayIndex.getSyntax()),
  TrsGatewayNameInstance(trsGatewayName.getName(), 0, trsGatewayName.getSyntax()),
  TrsGatewayStateInstance(trsGatewayState.getName(), 0, trsGatewayState.getSyntax()),
  # Row #1
  TrsDeliveryTimeInstance(trsDeliveryTime.getName(), 1, trsDeliveryTime.getSyntax()),
  TrsMessagesPerHourInstance(trsMessagesPerHour.getName(), 1, trsMessagesPerHour.getSyntax()),
  TrsGatewayIndexInstance(trsGatewayIndex.getName(), 1, trsGatewayIndex.getSyntax()),
  TrsGatewayNameInstance(trsGatewayName.getName(), 1, trsGatewayName.getSyntax()),
  TrsGatewayStateInstance(trsGatewayState.getName(), 1, trsGatewayState.getSyntax())
)
person Ilya Etingof    schedule 12.09.2012
comment
Спасибо, это очень полезно. Когда я использую это, я получаю сообщение об ошибке AttributeError: Integer32 instance has no __call__ method во время запроса значения столбца индекса. Если я запрашиваю одно из значений столбца Octet Strings, я получаю AttributeError: OctetString instance has no __call__ method. Похоже, что есть еще один уровень вызова функции, чем ожидалось, или что-то подобное. - person fadedbee; 12.09.2012
comment
P.S. Мне пришлось заменить ...getName(), 0, trs... на ...getName(), (0,), trs..., чтобы он заработал. - person fadedbee; 12.09.2012
comment
П.П.С. Изменение 0 на (0,) только заставило его запуститься, код по-прежнему выдает ошибку атрибута при запросе. - person fadedbee; 12.09.2012
comment
П.П.П.С. Похоже, виноваты вызовы self.syntax(...). - person fadedbee; 12.09.2012
comment
P.P.P.P.S Замена всех вызовов self.syntax(...) на self.syntax.clone(...) устраняет проблему, и теперь у меня есть рабочие таблицы. Большое спасибо за вашу помощь в этом. - person fadedbee; 12.09.2012