Files
vpp-snmp-agent/vpp-snmp-agent.py

518 lines
15 KiB
Python
Executable File

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from vppstats import VPPStats
from vppapi import VPPApi
import time
import pyagentx
import logging
import threading
class NullHandler(logging.Handler):
def emit(self, record):
pass
logger = logging.getLogger('pyagentx.vppstats')
logger.addHandler(NullHandler())
class ifName(pyagentx.Updater):
def update(self):
global vppstat
vppstat.connect()
for i in range(len(vppstat['/if/names'])):
self.set_OCTETSTRING(str(i + 1), vppstat['/if/names'][i])
class ifIndex(pyagentx.Updater):
def update(self):
global vppstat
vppstat.connect()
for i in range(len(vppstat['/if/names'])):
self.set_INTEGER(str(i + 1), i + 1)
class ifType(pyagentx.Updater):
def update(self):
global vppstat
vppstat.connect()
for i in range(len(vppstat['/if/names'])):
t = 6 # ethermet-csmacd
if vppstat['/if/names'][i].startswith("loop"):
t = 24 # softwareLoopback
self.set_INTEGER(str(i + 1), t)
class ifMtu(pyagentx.Updater):
def update(self):
global vppstat, vpp
vppstat.connect()
vpp.connect()
ifaces = vpp.get_ifaces()
for i in range(len(vppstat['/if/names'])):
ifname = vppstat['/if/names'][i]
mtu = 0
if not ifname in ifaces:
logger.warning("Could not get MTU for interface %s", ifname)
else:
mtu = ifaces[ifname].mtu[0]
self.set_INTEGER(str(i + 1), mtu)
class ifSpeed(pyagentx.Updater):
def update(self):
global vppstat, vpp
vppstat.connect()
vpp.connect()
ifaces = vpp.get_ifaces()
for i in range(len(vppstat['/if/names'])):
ifname = vppstat['/if/names'][i]
speed = 0
if ifname.startswith("loop") or ifname.startswith("tap"):
speed = 1000000000
elif not ifname in ifaces:
logger.warning("Could not get link speed for interface %s",
ifname)
else:
speed = ifaces[ifname].link_speed * 1000
if speed >= 2**32:
speed = 2**32 - 1
self.set_GAUGE32(str(i + 1), speed)
class ifAdminStatus(pyagentx.Updater):
def update(self):
global vppstat, vpp
vppstat.connect()
vpp.connect()
ifaces = vpp.get_ifaces()
for i in range(len(vppstat['/if/names'])):
ifname = vppstat['/if/names'][i]
state = 3 # testing
if not ifname in ifaces:
logger.warning("Could not get AdminStatus for interface %s",
ifname)
else:
if int(ifaces[ifname].flags) & 2:
state = 1 # up
else:
state = 2 # down
self.set_INTEGER(str(i + 1), state)
class ifOperStatus(pyagentx.Updater):
def update(self):
global vppstat, vpp
vppstat.connect()
vpp.connect()
ifaces = vpp.get_ifaces()
for i in range(len(vppstat['/if/names'])):
ifname = vppstat['/if/names'][i]
state = 3 # testing
if not ifname in ifaces:
logger.warning("Could not get OperStatus for interface %s",
ifname)
else:
if int(ifaces[ifname].flags) & 1:
state = 1 # up
else:
state = 2 # down
self.set_INTEGER(str(i + 1), state)
class ifPhysAddress(pyagentx.Updater):
def update(self):
global vppstat, vpp
vppstat.connect()
vpp.connect()
ifaces = vpp.get_ifaces()
for i in range(len(vppstat['/if/names'])):
ifname = vppstat['/if/names'][i]
mac = "00:00:00:00:00:00"
if not ifname in ifaces:
logger.warning("Could not get PhysAddress for interface %s",
ifname)
else:
mac = str(ifaces[ifname].l2_address)
self.set_OCTETSTRING(str(i + 1), mac)
class ifAlias(pyagentx.Updater):
def update(self):
global vppstat
vppstat.connect()
for i in range(len(vppstat['/if/names'])):
self.set_OCTETSTRING(str(i + 1), vppstat['/if/names'][i])
class ifInMulticastPkts(pyagentx.Updater):
def update(self):
global vppstat
vppstat.connect()
for i in range(len(vppstat['/if/names'])):
self.set_COUNTER32(
str(i + 1),
vppstat['/if/rx-multicast'][:, i].sum_packets() % 2**32)
class ifInBroadcastPkts(pyagentx.Updater):
def update(self):
global vppstat
vppstat.connect()
for i in range(len(vppstat['/if/names'])):
self.set_COUNTER32(
str(i + 1),
vppstat['/if/rx-broadcast'][:, i].sum_packets() % 2**32)
class ifOutMulticastPkts(pyagentx.Updater):
def update(self):
global vppstat
vppstat.connect()
for i in range(len(vppstat['/if/names'])):
self.set_COUNTER32(
str(i + 1),
vppstat['/if/tx-multicast'][:, i].sum_packets() % 2**32)
class ifOutBroadcastPkts(pyagentx.Updater):
def update(self):
global vppstat
vppstat.connect()
for i in range(len(vppstat['/if/names'])):
self.set_COUNTER32(
str(i + 1),
vppstat['/if/tx-broadcast'][:, i].sum_packets() % 2**32)
class ifHCInOctets(pyagentx.Updater):
def update(self):
global vppstat
vppstat.connect()
for i in range(len(vppstat['/if/names'])):
self.set_COUNTER64(str(i + 1), vppstat['/if/rx'][:,
i].sum_octets())
class ifHCInUcastPkts(pyagentx.Updater):
def update(self):
global vppstat
vppstat.connect()
for i in range(len(vppstat['/if/names'])):
self.set_COUNTER64(str(i + 1), vppstat['/if/rx'][:,
i].sum_packets())
class ifHCInMulticastPkts(pyagentx.Updater):
def update(self):
global vppstat
vppstat.connect()
for i in range(len(vppstat['/if/names'])):
self.set_COUNTER64(str(i + 1),
vppstat['/if/rx-multicast'][:, i].sum_packets())
class ifHCInBroadcastPkts(pyagentx.Updater):
def update(self):
global vppstat
vppstat.connect()
for i in range(len(vppstat['/if/names'])):
self.set_COUNTER64(str(i + 1),
vppstat['/if/rx-broadcast'][:, i].sum_packets())
class ifHCOutOctets(pyagentx.Updater):
def update(self):
global vppstat
vppstat.connect()
for i in range(len(vppstat['/if/names'])):
self.set_COUNTER64(str(i + 1), vppstat['/if/tx'][:,
i].sum_octets())
class ifHCOutUcastPkts(pyagentx.Updater):
def update(self):
global vppstat
vppstat.connect()
for i in range(len(vppstat['/if/names'])):
self.set_COUNTER64(str(i + 1), vppstat['/if/tx'][:,
i].sum_packets())
class ifHCOutMulticastPkts(pyagentx.Updater):
def update(self):
global vppstat
vppstat.connect()
for i in range(len(vppstat['/if/names'])):
self.set_COUNTER64(str(i + 1),
vppstat['/if/tx-multicast'][:, i].sum_packets())
class ifHCOutBroadcastPkts(pyagentx.Updater):
def update(self):
global vppstat
vppstat.connect()
for i in range(len(vppstat['/if/names'])):
self.set_COUNTER64(str(i + 1),
vppstat['/if/tx-broadcast'][:, i].sum_packets())
class ifHighSpeed(pyagentx.Updater):
def update(self):
global vppstat, vpp
vppstat.connect()
vpp.connect()
ifaces = vpp.get_ifaces()
for i in range(len(vppstat['/if/names'])):
ifname = vppstat['/if/names'][i]
speed = 0
if ifname.startswith("loop") or ifname.startswith("tap"):
speed = 1000
elif not ifname in ifaces:
logger.warning("Could not get link speed for interface %s",
ifname)
else:
speed = int(ifaces[ifname].link_speed / 1000)
self.set_GAUGE32(str(i + 1), speed)
class ifPromiscuousMode(pyagentx.Updater):
def update(self):
global vppstat
vppstat.connect()
for i in range(len(vppstat['/if/names'])):
# Hardcode to false(2)
self.set_INTEGER(str(i + 1), 2)
class ifConnectorPresent(pyagentx.Updater):
def update(self):
global vppstat
vppstat.connect()
for i in range(len(vppstat['/if/names'])):
# Hardcode to true(1)
self.set_INTEGER(str(i + 1), 1)
class ifCounterDiscontinuityTime(pyagentx.Updater):
def update(self):
global vppstat
vppstat.connect()
for i in range(len(vppstat['/if/names'])):
# Hardcode to Timeticks: (0) 0:00:00.00
self.set_TIMETICKS(str(i + 1), 0)
class ifInOctets(pyagentx.Updater):
def update(self):
global vppstat
vppstat.connect()
for i in range(len(vppstat['/if/names'])):
self.set_COUNTER32(str(i + 1),
vppstat['/if/rx'][:, i].sum_octets() % 2**32)
class ifInUcastPkts(pyagentx.Updater):
def update(self):
global vppstat
vppstat.connect()
for i in range(len(vppstat['/if/names'])):
self.set_COUNTER32(str(i + 1),
vppstat['/if/rx'][:, i].sum_packets() % 2**32)
class ifInNUcastPkts(pyagentx.Updater):
def update(self):
global vppstat
vppstat.connect()
for i in range(len(vppstat['/if/names'])):
self.set_COUNTER32(
str(i + 1),
vppstat['/if/rx-multicast'][:, i].sum_packets() % 2**32)
class ifInDiscards(pyagentx.Updater):
def update(self):
global vppstat
vppstat.connect()
for i in range(len(vppstat['/if/names'])):
self.set_COUNTER32(str(i + 1),
vppstat['/if/rx-no-buf'][:, i].sum() % 2**32)
class ifInErrors(pyagentx.Updater):
def update(self):
global vppstat
vppstat.connect()
for i in range(len(vppstat['/if/names'])):
self.set_COUNTER32(str(i + 1),
vppstat['/if/rx-error'][:, i].sum() % 2**32)
class ifOutOctets(pyagentx.Updater):
def update(self):
global vppstat
vppstat.connect()
for i in range(len(vppstat['/if/names'])):
self.set_COUNTER32(str(i + 1),
vppstat['/if/tx'][:, i].sum_octets() % 2**32)
class ifOutUcastPkts(pyagentx.Updater):
def update(self):
global vppstat
vppstat.connect()
for i in range(len(vppstat['/if/names'])):
self.set_COUNTER32(str(i + 1),
vppstat['/if/tx'][:, i].sum_packets() % 2**32)
class ifOutNUcastPkts(pyagentx.Updater):
def update(self):
global vppstat
vppstat.connect()
for i in range(len(vppstat['/if/names'])):
self.set_COUNTER32(
str(i + 1),
vppstat['/if/tx-multicast'][:, i].sum_packets() % 2**32)
class ifOutDiscards(pyagentx.Updater):
def update(self):
global vppstat
vppstat.connect()
for i in range(len(vppstat['/if/names'])):
self.set_COUNTER32(str(i + 1),
vppstat['/if/drops'][:, i].sum() % 2**32)
class ifOutErrors(pyagentx.Updater):
def update(self):
global vppstat
vppstat.connect()
for i in range(len(vppstat['/if/names'])):
self.set_COUNTER32(str(i + 1),
vppstat['/if/tx-error'][:, i].sum() % 2**32)
class MyAgent(pyagentx.Agent):
def setup(self):
# iso.org.dod.internet.mgmt.mib_2.interfaces.ifTable.ifEntry
self.register('1.3.6.1.2.1.2.2.1.1', ifIndex)
self.register('1.3.6.1.2.1.2.2.1.2', ifName)
self.register('1.3.6.1.2.1.2.2.1.3', ifType)
self.register('1.3.6.1.2.1.2.2.1.4', ifMtu)
self.register('1.3.6.1.2.1.2.2.1.5', ifSpeed)
self.register('1.3.6.1.2.1.2.2.1.6', ifPhysAddress)
self.register('1.3.6.1.2.1.2.2.1.7', ifAdminStatus)
self.register('1.3.6.1.2.1.2.2.1.8', ifOperStatus)
self.register('1.3.6.1.2.1.2.2.1.9', ifCounterDiscontinuityTime)
self.register('1.3.6.1.2.1.2.2.1.10', ifInOctets)
self.register('1.3.6.1.2.1.2.2.1.11', ifInUcastPkts)
self.register('1.3.6.1.2.1.2.2.1.12', ifInNUcastPkts)
self.register('1.3.6.1.2.1.2.2.1.13', ifInDiscards)
self.register('1.3.6.1.2.1.2.2.1.14', ifInErrors)
self.register('1.3.6.1.2.1.2.2.1.16', ifOutOctets)
self.register('1.3.6.1.2.1.2.2.1.17', ifOutUcastPkts)
self.register('1.3.6.1.2.1.2.2.1.18', ifOutNUcastPkts)
self.register('1.3.6.1.2.1.2.2.1.19', ifOutDiscards)
self.register('1.3.6.1.2.1.2.2.1.20', ifOutErrors)
# iso.org.dod.internet.mgmt.mib_2.ifMIB.ifMIBObjects.ifXTable.ifXEntry
self.register('1.3.6.1.2.1.31.1.1.1.1', ifName)
self.register('1.3.6.1.2.1.31.1.1.1.2', ifInMulticastPkts)
self.register('1.3.6.1.2.1.31.1.1.1.3', ifInBroadcastPkts)
self.register('1.3.6.1.2.1.31.1.1.1.4', ifOutMulticastPkts)
self.register('1.3.6.1.2.1.31.1.1.1.5', ifOutBroadcastPkts)
self.register('1.3.6.1.2.1.31.1.1.1.6', ifHCInOctets)
self.register('1.3.6.1.2.1.31.1.1.1.7', ifHCInUcastPkts)
self.register('1.3.6.1.2.1.31.1.1.1.8', ifHCInMulticastPkts)
self.register('1.3.6.1.2.1.31.1.1.1.9', ifHCInBroadcastPkts)
self.register('1.3.6.1.2.1.31.1.1.1.10', ifHCOutOctets)
self.register('1.3.6.1.2.1.31.1.1.1.11', ifHCOutUcastPkts)
self.register('1.3.6.1.2.1.31.1.1.1.12', ifHCOutMulticastPkts)
self.register('1.3.6.1.2.1.31.1.1.1.13', ifHCOutBroadcastPkts)
self.register('1.3.6.1.2.1.31.1.1.1.15', ifHighSpeed)
self.register('1.3.6.1.2.1.31.1.1.1.16', ifPromiscuousMode)
self.register('1.3.6.1.2.1.31.1.1.1.17', ifConnectorPresent)
self.register('1.3.6.1.2.1.31.1.1.1.18', ifAlias)
self.register('1.3.6.1.2.1.31.1.1.1.19', ifCounterDiscontinuityTime)
def main():
global vppstat, vpp, logger
pyagentx.setup_logging(debug=False)
vppstat = VPPStats(socketname='/run/vpp/stats.sock', timeout=2)
vppstat.connect()
vpp = VPPApi()
if not vpp.connect():
logger.error("Can't connect to VPP API, bailing")
return
try:
a = MyAgent(server_address='/run/vpp/agentx.sock')
a.start()
except Exception as e:
print("Unhandled exception:", e)
a.stop()
except KeyboardInterrupt:
a.stop()
vppstat.disconnect()
vpp.disconnect()
if __name__ == "__main__":
main()