Replace the pyagentx threaded version with a much simpler, non-threaded version.
This commit is contained in:
		@@ -8,27 +8,22 @@ from __future__ import (
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import logging
 | 
					import logging
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from pyagentx.updater import Updater
 | 
					from agentx.agent import Agent
 | 
				
			||||||
from pyagentx.agent import Agent
 | 
					from agentx.dataset import DataSet
 | 
				
			||||||
from pyagentx.sethandler import SetHandler, SetHandlerError
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
def setup_logging(debug=False):
 | 
					def setup_logging(debug=False):
 | 
				
			||||||
    if debug:
 | 
					    if debug:
 | 
				
			||||||
        level = logging.DEBUG
 | 
					        level = logging.DEBUG
 | 
				
			||||||
    else:
 | 
					    else:
 | 
				
			||||||
        level = logging.INFO
 | 
					        level = logging.INFO
 | 
				
			||||||
    logger = logging.getLogger('pyagentx')
 | 
					    logger = logging.getLogger('agentx')
 | 
				
			||||||
    logger.setLevel(level)
 | 
					    logger.setLevel(level)
 | 
				
			||||||
    #    formatter = logging.Formatter('%(asctime)s - %(name)20s - %(levelname)s - %(message)s')
 | 
					    formatter = logging.Formatter('[%(levelname)-8s] %(name)17s - %(funcName)-15s: %(message)s')
 | 
				
			||||||
    formatter = logging.Formatter(
 | 
					 | 
				
			||||||
        '[%(levelname)-8s] %(name)17s - %(funcName)-15s: %(message)s')
 | 
					 | 
				
			||||||
    ch = logging.StreamHandler()
 | 
					    ch = logging.StreamHandler()
 | 
				
			||||||
    ch.setLevel(level)
 | 
					    ch.setLevel(level)
 | 
				
			||||||
    ch.setFormatter(formatter)
 | 
					    ch.setFormatter(formatter)
 | 
				
			||||||
    logger.addHandler(ch)
 | 
					    logger.addHandler(ch)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
AGENTX_EMPTY_PDU = 1
 | 
					AGENTX_EMPTY_PDU = 1
 | 
				
			||||||
AGENTX_OPEN_PDU = 1
 | 
					AGENTX_OPEN_PDU = 1
 | 
				
			||||||
AGENTX_CLOSE_PDU = 2
 | 
					AGENTX_CLOSE_PDU = 2
 | 
				
			||||||
							
								
								
									
										89
									
								
								agentx/agent.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										89
									
								
								agentx/agent.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,89 @@
 | 
				
			|||||||
 | 
					#!/usr/bin/env python
 | 
				
			||||||
 | 
					# -*- coding: utf-8 -*-
 | 
				
			||||||
 | 
					from __future__ import (
 | 
				
			||||||
 | 
					    absolute_import,
 | 
				
			||||||
 | 
					    division,
 | 
				
			||||||
 | 
					    print_function,
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# --------------------------------------------
 | 
				
			||||||
 | 
					import logging
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class NullHandler(logging.Handler):
 | 
				
			||||||
 | 
					    def emit(self, record):
 | 
				
			||||||
 | 
					        pass
 | 
				
			||||||
 | 
					# --------------------------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import time
 | 
				
			||||||
 | 
					import agentx
 | 
				
			||||||
 | 
					from agentx.dataset import DataSet
 | 
				
			||||||
 | 
					from agentx.network import Network
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class AgentError(Exception):
 | 
				
			||||||
 | 
					    pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Agent(object):
 | 
				
			||||||
 | 
					    def __init__(self, server_address='/var/agentx/master', freq=5):
 | 
				
			||||||
 | 
					        self.logger = logging.getLogger('agentx.agent')
 | 
				
			||||||
 | 
					        self.logger.addHandler(NullHandler())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self._servingset = DataSet()
 | 
				
			||||||
 | 
					        self._workingset = DataSet()
 | 
				
			||||||
 | 
					        self._lastupdate = 0
 | 
				
			||||||
 | 
					        self._update_freq = freq
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self._net = Network(server_address = server_address)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self._oid_list = []
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def _update(self):
 | 
				
			||||||
 | 
					        ds = self.update()
 | 
				
			||||||
 | 
					        self._net.update(ds._data)
 | 
				
			||||||
 | 
					        self._lastupdate = time.time()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def run(self):
 | 
				
			||||||
 | 
					        self.logger.info('Calling setup')
 | 
				
			||||||
 | 
					        self.setup()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.logger.info('Initial update')
 | 
				
			||||||
 | 
					        self._update()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        while True:
 | 
				
			||||||
 | 
					            if not self._net.is_connected():
 | 
				
			||||||
 | 
					              self.logger.info('Opening AgentX connection')
 | 
				
			||||||
 | 
					              self._net.start(self._oid_list)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if time.time() - self._lastupdate > self._update_freq:
 | 
				
			||||||
 | 
					                self._update()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            try:
 | 
				
			||||||
 | 
					                self._net.run()
 | 
				
			||||||
 | 
					            except Exception as e:
 | 
				
			||||||
 | 
					                self.logger.error('An exception occurred: %s' % e)
 | 
				
			||||||
 | 
					                time.sleep(1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def stop(self):
 | 
				
			||||||
 | 
					        self.logger.debug('Stopping')
 | 
				
			||||||
 | 
					        self._net.disconnect()
 | 
				
			||||||
 | 
					        pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def setup(self):
 | 
				
			||||||
 | 
					        # Override this
 | 
				
			||||||
 | 
					        pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def update(self):
 | 
				
			||||||
 | 
					        # Override this
 | 
				
			||||||
 | 
					        pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def register(self, oid_list):
 | 
				
			||||||
 | 
					        if not isinstance(oid_list, list):
 | 
				
			||||||
 | 
					            oid_list = [oid_list]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        for oid in oid_list:
 | 
				
			||||||
 | 
					            if not oid in self._oid_list:
 | 
				
			||||||
 | 
					                self.logger.debug('Adding %s to list' % oid)
 | 
				
			||||||
 | 
					                self._oid_list.append(oid)
 | 
				
			||||||
							
								
								
									
										57
									
								
								agentx/dataset.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										57
									
								
								agentx/dataset.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,57 @@
 | 
				
			|||||||
 | 
					#!/usr/bin/env python
 | 
				
			||||||
 | 
					# -*- coding: utf-8 -*-
 | 
				
			||||||
 | 
					from __future__ import (
 | 
				
			||||||
 | 
					    absolute_import,
 | 
				
			||||||
 | 
					    division,
 | 
				
			||||||
 | 
					    print_function,
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# --------------------------------------------
 | 
				
			||||||
 | 
					import logging
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class NullHandler(logging.Handler):
 | 
				
			||||||
 | 
					    def emit(self, record):
 | 
				
			||||||
 | 
					        pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					logger = logging.getLogger('agentx.dataset')
 | 
				
			||||||
 | 
					logger.addHandler(NullHandler())
 | 
				
			||||||
 | 
					# --------------------------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import time
 | 
				
			||||||
 | 
					import agentx
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class DataSet():
 | 
				
			||||||
 | 
					    def __init__(self):
 | 
				
			||||||
 | 
					        self._data = {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def set(self, oid, oid_type, value):
 | 
				
			||||||
 | 
					        if oid_type.startswith('int'):
 | 
				
			||||||
 | 
					            t = agentx.TYPE_INTEGER
 | 
				
			||||||
 | 
					        elif oid_type.startswith('str'):
 | 
				
			||||||
 | 
					            t = agentx.TYPE_OCTETSTRING
 | 
				
			||||||
 | 
					        elif oid_type.startswith('oid'):
 | 
				
			||||||
 | 
					            t = agentx.TYPE_OBJECTIDENTIFIER
 | 
				
			||||||
 | 
					        elif oid_type.startswith('ip'):
 | 
				
			||||||
 | 
					            t = agentx.TYPE_IPADDRESS
 | 
				
			||||||
 | 
					        elif oid_type == 'counter32' or oid_type == 'uint32' or oid_type == 'u32':
 | 
				
			||||||
 | 
					            t = agentx.TYPE_COUNTER32
 | 
				
			||||||
 | 
					        elif oid_type == 'gauge32':
 | 
				
			||||||
 | 
					            t = agentx.TYPE_GAUGE32
 | 
				
			||||||
 | 
					        elif oid_type.startswith('time') or oid_type.startswith('tick'):
 | 
				
			||||||
 | 
					            t = agentx.TYPE_TIMETICKS
 | 
				
			||||||
 | 
					        elif oid_type.startswith('opaque'):
 | 
				
			||||||
 | 
					            t = agentx.TYPE_OPAQUE
 | 
				
			||||||
 | 
					        elif oid_type == 'counter64' or oid_type == 'uint64' or oid_type == 'u64':
 | 
				
			||||||
 | 
					            t = agentx.TYPE_COUNTER64
 | 
				
			||||||
 | 
					        else:
 | 
				
			||||||
 | 
					            logger.error('Invalid oid_type: %s' % (oid_type))
 | 
				
			||||||
 | 
					            return
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self._data[oid] = {
 | 
				
			||||||
 | 
					            'name': oid,
 | 
				
			||||||
 | 
					            'type': t,
 | 
				
			||||||
 | 
					            'value': value
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
							
								
								
									
										220
									
								
								agentx/network.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										220
									
								
								agentx/network.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,220 @@
 | 
				
			|||||||
 | 
					#!/usr/bin/env python
 | 
				
			||||||
 | 
					# -*- coding: utf-8 -*-
 | 
				
			||||||
 | 
					from __future__ import (
 | 
				
			||||||
 | 
					    absolute_import,
 | 
				
			||||||
 | 
					    division,
 | 
				
			||||||
 | 
					    print_function,
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# --------------------------------------------
 | 
				
			||||||
 | 
					import logging
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class NullHandler(logging.Handler):
 | 
				
			||||||
 | 
					    def emit(self, record):
 | 
				
			||||||
 | 
					        pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					logger = logging.getLogger('agentx.network')
 | 
				
			||||||
 | 
					logger.addHandler(NullHandler())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class NetworkError(Exception):
 | 
				
			||||||
 | 
					    pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# --------------------------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import socket
 | 
				
			||||||
 | 
					import time
 | 
				
			||||||
 | 
					import agentx
 | 
				
			||||||
 | 
					from agentx.pdu import PDU
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Network():
 | 
				
			||||||
 | 
					    def __init__(self, server_address = '/var/agentx/master'):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.session_id = 0
 | 
				
			||||||
 | 
					        self.transaction_id = 0
 | 
				
			||||||
 | 
					        self.debug = 1
 | 
				
			||||||
 | 
					        # Data Related Variables
 | 
				
			||||||
 | 
					        self.data = {}
 | 
				
			||||||
 | 
					        self.data_idx = []
 | 
				
			||||||
 | 
					        self._connected = False
 | 
				
			||||||
 | 
					        self._server_address = server_address
 | 
				
			||||||
 | 
					        self._timeout = 0.1 # Seconds
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def connect(self):
 | 
				
			||||||
 | 
					        if self._connected:
 | 
				
			||||||
 | 
					            return
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        try:
 | 
				
			||||||
 | 
					            logger.info("Connecting to %s" % self._server_address)
 | 
				
			||||||
 | 
					            if self._server_address.startswith('/'):
 | 
				
			||||||
 | 
					                self.socket = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
 | 
				
			||||||
 | 
					                self.socket.connect(self._server_address)
 | 
				
			||||||
 | 
					            else:
 | 
				
			||||||
 | 
					                self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
 | 
				
			||||||
 | 
					                self.socket.connect(self._server_address.split(':'))
 | 
				
			||||||
 | 
					            self.socket.settimeout(self._timeout)
 | 
				
			||||||
 | 
					            self._connected = True
 | 
				
			||||||
 | 
					        except socket.error:
 | 
				
			||||||
 | 
					            logger.error("Failed to connect to %s" % self._server_address)
 | 
				
			||||||
 | 
					            self._connected = False
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def disconnect(self):
 | 
				
			||||||
 | 
					        if not self._connected:
 | 
				
			||||||
 | 
					            return
 | 
				
			||||||
 | 
					        logger.info("Disconnecting from %s" % self._server_address)
 | 
				
			||||||
 | 
					        self.socket.close()
 | 
				
			||||||
 | 
					        self.socket = None
 | 
				
			||||||
 | 
					        self._connected = False
 | 
				
			||||||
 | 
					        return
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def update(self, newdata):
 | 
				
			||||||
 | 
					        if len(self.data) == 0:
 | 
				
			||||||
 | 
					            logger.debug("Setting initial serving dataset (%d OIDs)" % len(newdata))
 | 
				
			||||||
 | 
					        else:
 | 
				
			||||||
 | 
					            logger.debug("Replacing serving dataset (%d OIDs)" % len(newdata))
 | 
				
			||||||
 | 
					        self.data = newdata
 | 
				
			||||||
 | 
					        self.data_idx = sorted(self.data.keys(), key=lambda k: tuple(int(part) for part in k.split('.')))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def new_pdu(self, type):
 | 
				
			||||||
 | 
					        pdu = PDU(type)
 | 
				
			||||||
 | 
					        pdu.session_id = self.session_id
 | 
				
			||||||
 | 
					        pdu.transaction_id = self.transaction_id
 | 
				
			||||||
 | 
					        self.transaction_id += 1
 | 
				
			||||||
 | 
					        return pdu
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def response_pdu(self, org_pdu):
 | 
				
			||||||
 | 
					        pdu = PDU(agentx.AGENTX_RESPONSE_PDU)
 | 
				
			||||||
 | 
					        pdu.session_id = org_pdu.session_id
 | 
				
			||||||
 | 
					        pdu.transaction_id = org_pdu.transaction_id
 | 
				
			||||||
 | 
					        pdu.packet_id = org_pdu.packet_id
 | 
				
			||||||
 | 
					        return pdu
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def send_pdu(self, pdu):
 | 
				
			||||||
 | 
					        if self.debug: pdu.dump()
 | 
				
			||||||
 | 
					        self.socket.send(pdu.encode())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def recv_pdu(self):
 | 
				
			||||||
 | 
					        buf = self.socket.recv(1024)
 | 
				
			||||||
 | 
					        if not buf: return None
 | 
				
			||||||
 | 
					        pdu = PDU()
 | 
				
			||||||
 | 
					        pdu.decode(buf)
 | 
				
			||||||
 | 
					        if self.debug: pdu.dump()
 | 
				
			||||||
 | 
					        return pdu
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # =========================================
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def _get_next_oid(self, oid, endoid):
 | 
				
			||||||
 | 
					        if oid in self.data:
 | 
				
			||||||
 | 
					            # Exact match found
 | 
				
			||||||
 | 
					            #logger.debug('get_next_oid, exact match of %s' % oid)
 | 
				
			||||||
 | 
					            idx = self.data_idx.index(oid)
 | 
				
			||||||
 | 
					            if idx == (len(self.data_idx) - 1):
 | 
				
			||||||
 | 
					                # Last Item in MIB, No match!
 | 
				
			||||||
 | 
					                return None
 | 
				
			||||||
 | 
					            return self.data_idx[idx + 1]
 | 
				
			||||||
 | 
					        else:
 | 
				
			||||||
 | 
					            # No exact match, find prefix
 | 
				
			||||||
 | 
					            #logger.debug('get_next_oid, no exact match of %s' % oid)
 | 
				
			||||||
 | 
					            slist = oid.split('.')
 | 
				
			||||||
 | 
					            elist = endoid.split('.')
 | 
				
			||||||
 | 
					            for tmp_oid in self.data_idx:
 | 
				
			||||||
 | 
					                tlist = tmp_oid.split('.')
 | 
				
			||||||
 | 
					                for i in range(len(tlist)):
 | 
				
			||||||
 | 
					                    try:
 | 
				
			||||||
 | 
					                        sok = int(slist[i]) <= int(tlist[i])
 | 
				
			||||||
 | 
					                        eok = int(elist[i]) >= int(tlist[i])
 | 
				
			||||||
 | 
					                        if not (sok and eok):
 | 
				
			||||||
 | 
					                            break
 | 
				
			||||||
 | 
					                    except IndexError:
 | 
				
			||||||
 | 
					                        pass
 | 
				
			||||||
 | 
					                if sok and eok:
 | 
				
			||||||
 | 
					                    return tmp_oid
 | 
				
			||||||
 | 
					            return None  # No match!
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def start(self, oid_list):
 | 
				
			||||||
 | 
					        self.connect()
 | 
				
			||||||
 | 
					        if not self._connected:
 | 
				
			||||||
 | 
					            return
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        logger.debug("==== Open PDU ====")
 | 
				
			||||||
 | 
					        pdu = self.new_pdu(agentx.AGENTX_OPEN_PDU)
 | 
				
			||||||
 | 
					        self.send_pdu(pdu)
 | 
				
			||||||
 | 
					        pdu = self.recv_pdu()
 | 
				
			||||||
 | 
					        self.session_id = pdu.session_id
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        logger.debug("==== Ping PDU ====")
 | 
				
			||||||
 | 
					        pdu = self.new_pdu(agentx.AGENTX_PING_PDU)
 | 
				
			||||||
 | 
					        self.send_pdu(pdu)
 | 
				
			||||||
 | 
					        pdu = self.recv_pdu()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        logger.debug("==== Register PDU ====")
 | 
				
			||||||
 | 
					        for oid in oid_list:
 | 
				
			||||||
 | 
					            logger.info("Registering: %s" % (oid))
 | 
				
			||||||
 | 
					            pdu = self.new_pdu(agentx.AGENTX_REGISTER_PDU)
 | 
				
			||||||
 | 
					            pdu.oid = oid
 | 
				
			||||||
 | 
					            self.send_pdu(pdu)
 | 
				
			||||||
 | 
					            pdu = self.recv_pdu()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def stop(self):
 | 
				
			||||||
 | 
					        self.disconnect()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def is_connected(self):
 | 
				
			||||||
 | 
					        return self._connected
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def run(self, timeout = 0.1):
 | 
				
			||||||
 | 
					        if not self._connected:
 | 
				
			||||||
 | 
					            raise NetworkError('Not connected')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if timeout != self._timeout:
 | 
				
			||||||
 | 
					          self.socket.settimeout(timeout)
 | 
				
			||||||
 | 
					          self._timeout = timeout
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        try:
 | 
				
			||||||
 | 
					            request = self.recv_pdu()
 | 
				
			||||||
 | 
					        except socket.timeout:
 | 
				
			||||||
 | 
					            return
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if not request:
 | 
				
			||||||
 | 
					            logger.error("Empty PDU, connection closed!")
 | 
				
			||||||
 | 
					            self.disconnect()
 | 
				
			||||||
 | 
					            raise NetworkError("Empty PDU, disconnecting")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        response = self.response_pdu(request)
 | 
				
			||||||
 | 
					        if request.type == agentx.AGENTX_GET_PDU:
 | 
				
			||||||
 | 
					            logger.debug("Received GET PDU")
 | 
				
			||||||
 | 
					            for rvalue in request.range_list:
 | 
				
			||||||
 | 
					                oid = rvalue[0]
 | 
				
			||||||
 | 
					                logger.debug("OID: %s" % (oid))
 | 
				
			||||||
 | 
					                if oid in self.data:
 | 
				
			||||||
 | 
					                    logger.debug("OID Found")
 | 
				
			||||||
 | 
					                    response.values.append(self.data[oid])
 | 
				
			||||||
 | 
					                else:
 | 
				
			||||||
 | 
					                    logger.debug("OID Not Found!")
 | 
				
			||||||
 | 
					                    response.values.append({
 | 
				
			||||||
 | 
					                        'type': agentx.TYPE_NOSUCHOBJECT,
 | 
				
			||||||
 | 
					                        'name': rvalue[0],
 | 
				
			||||||
 | 
					                        'value': 0
 | 
				
			||||||
 | 
					                    })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        elif request.type == agentx.AGENTX_GETNEXT_PDU:
 | 
				
			||||||
 | 
					            logger.debug("Received GET_NEXT PDU")
 | 
				
			||||||
 | 
					            for rvalue in request.range_list:
 | 
				
			||||||
 | 
					                oid = self._get_next_oid(rvalue[0], rvalue[1])
 | 
				
			||||||
 | 
					                logger.debug("GET_NEXT: %s => %s" % (rvalue[0], oid))
 | 
				
			||||||
 | 
					                if oid:
 | 
				
			||||||
 | 
					                    response.values.append(self.data[oid])
 | 
				
			||||||
 | 
					                else:
 | 
				
			||||||
 | 
					                    response.values.append({
 | 
				
			||||||
 | 
					                        'type': agentx.TYPE_ENDOFMIBVIEW,
 | 
				
			||||||
 | 
					                        'name': rvalue[0],
 | 
				
			||||||
 | 
					                        'value': 0
 | 
				
			||||||
 | 
					                    })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        else:
 | 
				
			||||||
 | 
					            logger.warn("Received unsupported PDU %d" % request.type)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.send_pdu(response)
 | 
				
			||||||
@@ -15,14 +15,14 @@ class NullHandler(logging.Handler):
 | 
				
			|||||||
        pass
 | 
					        pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
logger = logging.getLogger('pyagentx.pdu')
 | 
					logger = logging.getLogger('agentx.pdu')
 | 
				
			||||||
logger.addHandler(NullHandler())
 | 
					logger.addHandler(NullHandler())
 | 
				
			||||||
# --------------------------------------------
 | 
					# --------------------------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import struct
 | 
					import struct
 | 
				
			||||||
import pprint
 | 
					import pprint
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import pyagentx
 | 
					import agentx
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class PDU(object):
 | 
					class PDU(object):
 | 
				
			||||||
@@ -31,14 +31,14 @@ class PDU(object):
 | 
				
			|||||||
        self.session_id = 0
 | 
					        self.session_id = 0
 | 
				
			||||||
        self.transaction_id = 0
 | 
					        self.transaction_id = 0
 | 
				
			||||||
        self.packet_id = 0
 | 
					        self.packet_id = 0
 | 
				
			||||||
        self.error = pyagentx.ERROR_NOAGENTXERROR
 | 
					        self.error = agentx.ERROR_NOAGENTXERROR
 | 
				
			||||||
        self.error_index = 0
 | 
					        self.error_index = 0
 | 
				
			||||||
        self.decode_buf = ''
 | 
					        self.decode_buf = ''
 | 
				
			||||||
        self.state = {}
 | 
					        self.state = {}
 | 
				
			||||||
        self.values = []
 | 
					        self.values = []
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def dump(self):
 | 
					    def dump(self):
 | 
				
			||||||
        name = pyagentx.PDU_TYPE_NAME[self.type]
 | 
					        name = agentx.PDU_TYPE_NAME[self.type]
 | 
				
			||||||
        logger.debug('PDU DUMP: New PDU')
 | 
					        logger.debug('PDU DUMP: New PDU')
 | 
				
			||||||
        logger.debug(
 | 
					        logger.debug(
 | 
				
			||||||
            'PDU DUMP: Meta      : [%s: %d %d %d]' %
 | 
					            'PDU DUMP: Meta      : [%s: %d %d %d]' %
 | 
				
			||||||
@@ -85,25 +85,25 @@ class PDU(object):
 | 
				
			|||||||
    def encode_value(self, type, name, value):
 | 
					    def encode_value(self, type, name, value):
 | 
				
			||||||
        buf = struct.pack('!HH', type, 0)
 | 
					        buf = struct.pack('!HH', type, 0)
 | 
				
			||||||
        buf += self.encode_oid(name)
 | 
					        buf += self.encode_oid(name)
 | 
				
			||||||
        if type in [pyagentx.TYPE_INTEGER]:
 | 
					        if type in [agentx.TYPE_INTEGER]:
 | 
				
			||||||
            buf += struct.pack('!l', value)
 | 
					            buf += struct.pack('!l', value)
 | 
				
			||||||
        elif type in [
 | 
					        elif type in [
 | 
				
			||||||
                pyagentx.TYPE_COUNTER32, pyagentx.TYPE_GAUGE32,
 | 
					                agentx.TYPE_COUNTER32, agentx.TYPE_GAUGE32,
 | 
				
			||||||
                pyagentx.TYPE_TIMETICKS
 | 
					                agentx.TYPE_TIMETICKS
 | 
				
			||||||
        ]:
 | 
					        ]:
 | 
				
			||||||
            buf += struct.pack('!L', value)
 | 
					            buf += struct.pack('!L', value)
 | 
				
			||||||
        elif type in [pyagentx.TYPE_COUNTER64]:
 | 
					        elif type in [agentx.TYPE_COUNTER64]:
 | 
				
			||||||
            buf += struct.pack('!Q', value)
 | 
					            buf += struct.pack('!Q', value)
 | 
				
			||||||
        elif type in [pyagentx.TYPE_OBJECTIDENTIFIER]:
 | 
					        elif type in [agentx.TYPE_OBJECTIDENTIFIER]:
 | 
				
			||||||
            buf += self.encode_oid(value)
 | 
					            buf += self.encode_oid(value)
 | 
				
			||||||
        elif type in [
 | 
					        elif type in [
 | 
				
			||||||
                pyagentx.TYPE_IPADDRESS, pyagentx.TYPE_OPAQUE,
 | 
					                agentx.TYPE_IPADDRESS, agentx.TYPE_OPAQUE,
 | 
				
			||||||
                pyagentx.TYPE_OCTETSTRING
 | 
					                agentx.TYPE_OCTETSTRING
 | 
				
			||||||
        ]:
 | 
					        ]:
 | 
				
			||||||
            buf += self.encode_octet(value)
 | 
					            buf += self.encode_octet(value)
 | 
				
			||||||
        elif type in [
 | 
					        elif type in [
 | 
				
			||||||
                pyagentx.TYPE_NULL, pyagentx.TYPE_NOSUCHOBJECT,
 | 
					                agentx.TYPE_NULL, agentx.TYPE_NOSUCHOBJECT,
 | 
				
			||||||
                pyagentx.TYPE_NOSUCHINSTANCE, pyagentx.TYPE_ENDOFMIBVIEW
 | 
					                agentx.TYPE_NOSUCHINSTANCE, agentx.TYPE_ENDOFMIBVIEW
 | 
				
			||||||
        ]:
 | 
					        ]:
 | 
				
			||||||
            # No data
 | 
					            # No data
 | 
				
			||||||
            pass
 | 
					            pass
 | 
				
			||||||
@@ -122,7 +122,7 @@ class PDU(object):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    def encode(self):
 | 
					    def encode(self):
 | 
				
			||||||
        buf = b''
 | 
					        buf = b''
 | 
				
			||||||
        if self.type == pyagentx.AGENTX_OPEN_PDU:
 | 
					        if self.type == agentx.AGENTX_OPEN_PDU:
 | 
				
			||||||
            # timeout
 | 
					            # timeout
 | 
				
			||||||
            buf += struct.pack('!BBBB', 5, 0, 0, 0)
 | 
					            buf += struct.pack('!BBBB', 5, 0, 0, 0)
 | 
				
			||||||
            # agent OID
 | 
					            # agent OID
 | 
				
			||||||
@@ -130,11 +130,11 @@ class PDU(object):
 | 
				
			|||||||
            # Agent Desc
 | 
					            # Agent Desc
 | 
				
			||||||
            buf += self.encode_octet('MyAgent')
 | 
					            buf += self.encode_octet('MyAgent')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        elif self.type == pyagentx.AGENTX_PING_PDU:
 | 
					        elif self.type == agentx.AGENTX_PING_PDU:
 | 
				
			||||||
            # No extra data
 | 
					            # No extra data
 | 
				
			||||||
            pass
 | 
					            pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        elif self.type == pyagentx.AGENTX_REGISTER_PDU:
 | 
					        elif self.type == agentx.AGENTX_REGISTER_PDU:
 | 
				
			||||||
            range_subid = 0
 | 
					            range_subid = 0
 | 
				
			||||||
            timeout = 5
 | 
					            timeout = 5
 | 
				
			||||||
            priority = 127
 | 
					            priority = 127
 | 
				
			||||||
@@ -142,7 +142,7 @@ class PDU(object):
 | 
				
			|||||||
            # Sub Tree
 | 
					            # Sub Tree
 | 
				
			||||||
            buf += self.encode_oid(self.oid)
 | 
					            buf += self.encode_oid(self.oid)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        elif self.type == pyagentx.AGENTX_RESPONSE_PDU:
 | 
					        elif self.type == agentx.AGENTX_RESPONSE_PDU:
 | 
				
			||||||
            buf += struct.pack('!LHH', 0, self.error, self.error_index)
 | 
					            buf += struct.pack('!LHH', 0, self.error, self.error_index)
 | 
				
			||||||
            for value in self.values:
 | 
					            for value in self.values:
 | 
				
			||||||
                buf += self.encode_value(value['type'], value['name'],
 | 
					                buf += self.encode_value(value['type'], value['name'],
 | 
				
			||||||
@@ -217,26 +217,26 @@ class PDU(object):
 | 
				
			|||||||
            logger.exception('Invalid packing value header')
 | 
					            logger.exception('Invalid packing value header')
 | 
				
			||||||
        oid, _ = self.decode_oid()
 | 
					        oid, _ = self.decode_oid()
 | 
				
			||||||
        if vtype in [
 | 
					        if vtype in [
 | 
				
			||||||
                pyagentx.TYPE_INTEGER, pyagentx.TYPE_COUNTER32,
 | 
					                agentx.TYPE_INTEGER, agentx.TYPE_COUNTER32,
 | 
				
			||||||
                pyagentx.TYPE_GAUGE32, pyagentx.TYPE_TIMETICKS
 | 
					                agentx.TYPE_GAUGE32, agentx.TYPE_TIMETICKS
 | 
				
			||||||
        ]:
 | 
					        ]:
 | 
				
			||||||
            data = struct.unpack('!L', self.decode_buf[:4])
 | 
					            data = struct.unpack('!L', self.decode_buf[:4])
 | 
				
			||||||
            data = data[0]
 | 
					            data = data[0]
 | 
				
			||||||
            self.decode_buf = self.decode_buf[4:]
 | 
					            self.decode_buf = self.decode_buf[4:]
 | 
				
			||||||
        elif vtype in [pyagentx.TYPE_COUNTER64]:
 | 
					        elif vtype in [agentx.TYPE_COUNTER64]:
 | 
				
			||||||
            data = struct.unpack('!Q', self.decode_buf[:8])
 | 
					            data = struct.unpack('!Q', self.decode_buf[:8])
 | 
				
			||||||
            data = data[0]
 | 
					            data = data[0]
 | 
				
			||||||
            self.decode_buf = self.decode_buf[8:]
 | 
					            self.decode_buf = self.decode_buf[8:]
 | 
				
			||||||
        elif vtype in [pyagentx.TYPE_OBJECTIDENTIFIER]:
 | 
					        elif vtype in [agentx.TYPE_OBJECTIDENTIFIER]:
 | 
				
			||||||
            data, _ = self.decode_oid()
 | 
					            data, _ = self.decode_oid()
 | 
				
			||||||
        elif vtype in [
 | 
					        elif vtype in [
 | 
				
			||||||
                pyagentx.TYPE_IPADDRESS, pyagentx.TYPE_OPAQUE,
 | 
					                agentx.TYPE_IPADDRESS, agentx.TYPE_OPAQUE,
 | 
				
			||||||
                pyagentx.TYPE_OCTETSTRING
 | 
					                agentx.TYPE_OCTETSTRING
 | 
				
			||||||
        ]:
 | 
					        ]:
 | 
				
			||||||
            data = self.decode_octet()
 | 
					            data = self.decode_octet()
 | 
				
			||||||
        elif vtype in [
 | 
					        elif vtype in [
 | 
				
			||||||
                pyagentx.TYPE_NULL, pyagentx.TYPE_NOSUCHOBJECT,
 | 
					                agentx.TYPE_NULL, agentx.TYPE_NOSUCHOBJECT,
 | 
				
			||||||
                pyagentx.TYPE_NOSUCHINSTANCE, pyagentx.TYPE_ENDOFMIBVIEW
 | 
					                agentx.TYPE_NOSUCHINSTANCE, agentx.TYPE_ENDOFMIBVIEW
 | 
				
			||||||
        ]:
 | 
					        ]:
 | 
				
			||||||
            # No data
 | 
					            # No data
 | 
				
			||||||
            data = None
 | 
					            data = None
 | 
				
			||||||
@@ -251,7 +251,7 @@ class PDU(object):
 | 
				
			|||||||
            ret = {
 | 
					            ret = {
 | 
				
			||||||
                'version': t[0],
 | 
					                'version': t[0],
 | 
				
			||||||
                'pdu_type': t[1],
 | 
					                'pdu_type': t[1],
 | 
				
			||||||
                'pdu_type_name': pyagentx.PDU_TYPE_NAME[t[1]],
 | 
					                'pdu_type_name': agentx.PDU_TYPE_NAME[t[1]],
 | 
				
			||||||
                'flags': t[2],
 | 
					                'flags': t[2],
 | 
				
			||||||
                'reserved': t[3],
 | 
					                'reserved': t[3],
 | 
				
			||||||
                'session_id': t[4],
 | 
					                'session_id': t[4],
 | 
				
			||||||
@@ -276,14 +276,14 @@ class PDU(object):
 | 
				
			|||||||
    def decode(self, buf):
 | 
					    def decode(self, buf):
 | 
				
			||||||
        self.set_decode_buf(buf)
 | 
					        self.set_decode_buf(buf)
 | 
				
			||||||
        ret = self.decode_header()
 | 
					        ret = self.decode_header()
 | 
				
			||||||
        if ret['pdu_type'] == pyagentx.AGENTX_RESPONSE_PDU:
 | 
					        if ret['pdu_type'] == agentx.AGENTX_RESPONSE_PDU:
 | 
				
			||||||
            # Decode Response Header
 | 
					            # Decode Response Header
 | 
				
			||||||
            t = struct.unpack('!LHH', self.decode_buf[:8])
 | 
					            t = struct.unpack('!LHH', self.decode_buf[:8])
 | 
				
			||||||
            self.decode_buf = self.decode_buf[8:]
 | 
					            self.decode_buf = self.decode_buf[8:]
 | 
				
			||||||
            self.response = {
 | 
					            self.response = {
 | 
				
			||||||
                'sysUpTime': t[0],
 | 
					                'sysUpTime': t[0],
 | 
				
			||||||
                'error': t[1],
 | 
					                'error': t[1],
 | 
				
			||||||
                'error_name': pyagentx.ERROR_NAMES[t[1]],
 | 
					                'error_name': agentx.ERROR_NAMES[t[1]],
 | 
				
			||||||
                'index': t[2],
 | 
					                'index': t[2],
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            # Decode VarBindList
 | 
					            # Decode VarBindList
 | 
				
			||||||
@@ -291,23 +291,23 @@ class PDU(object):
 | 
				
			|||||||
            while len(self.decode_buf):
 | 
					            while len(self.decode_buf):
 | 
				
			||||||
                self.values.append(self.decode_value())
 | 
					                self.values.append(self.decode_value())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        elif ret['pdu_type'] == pyagentx.AGENTX_GET_PDU:
 | 
					        elif ret['pdu_type'] == agentx.AGENTX_GET_PDU:
 | 
				
			||||||
            self.range_list = self.decode_search_range_list()
 | 
					            self.range_list = self.decode_search_range_list()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        elif ret['pdu_type'] == pyagentx.AGENTX_GETNEXT_PDU:
 | 
					        elif ret['pdu_type'] == agentx.AGENTX_GETNEXT_PDU:
 | 
				
			||||||
            self.range_list = self.decode_search_range_list()
 | 
					            self.range_list = self.decode_search_range_list()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        elif ret['pdu_type'] == pyagentx.AGENTX_TESTSET_PDU:
 | 
					        elif ret['pdu_type'] == agentx.AGENTX_TESTSET_PDU:
 | 
				
			||||||
            # Decode VarBindList
 | 
					            # Decode VarBindList
 | 
				
			||||||
            self.values = []
 | 
					            self.values = []
 | 
				
			||||||
            while len(self.decode_buf):
 | 
					            while len(self.decode_buf):
 | 
				
			||||||
                self.values.append(self.decode_value())
 | 
					                self.values.append(self.decode_value())
 | 
				
			||||||
        elif ret['pdu_type'] in [
 | 
					        elif ret['pdu_type'] in [
 | 
				
			||||||
                pyagentx.AGENTX_COMMITSET_PDU, pyagentx.AGENTX_UNDOSET_PDU,
 | 
					                agentx.AGENTX_COMMITSET_PDU, agentx.AGENTX_UNDOSET_PDU,
 | 
				
			||||||
                pyagentx.AGENTX_CLEANUPSET_PDU
 | 
					                agentx.AGENTX_CLEANUPSET_PDU
 | 
				
			||||||
        ]:
 | 
					        ]:
 | 
				
			||||||
            pass
 | 
					            pass
 | 
				
			||||||
        else:
 | 
					        else:
 | 
				
			||||||
            pdu_type_str = pyagentx.PDU_TYPE_NAME.get(
 | 
					            pdu_type_str = agentx.PDU_TYPE_NAME.get(
 | 
				
			||||||
                ret['pdu_type'], 'Unknown:' + str(ret['pdu_type']))
 | 
					                ret['pdu_type'], 'Unknown:' + str(ret['pdu_type']))
 | 
				
			||||||
            logger.error('Unsupported PDU type:' + pdu_type_str)
 | 
					            logger.error('Unsupported PDU type:' + pdu_type_str)
 | 
				
			||||||
							
								
								
									
										1
									
								
								pyagentx/.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								pyagentx/.gitignore
									
									
									
									
										vendored
									
									
								
							@@ -1 +0,0 @@
 | 
				
			|||||||
__pycache__
 | 
					 | 
				
			||||||
@@ -1,97 +0,0 @@
 | 
				
			|||||||
#!/usr/bin/env python
 | 
					 | 
				
			||||||
# -*- coding: utf-8 -*-
 | 
					 | 
				
			||||||
from __future__ import (
 | 
					 | 
				
			||||||
    absolute_import,
 | 
					 | 
				
			||||||
    division,
 | 
					 | 
				
			||||||
    print_function,
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# --------------------------------------------
 | 
					 | 
				
			||||||
import logging
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class NullHandler(logging.Handler):
 | 
					 | 
				
			||||||
    def emit(self, record):
 | 
					 | 
				
			||||||
        pass
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
logger = logging.getLogger('pyagentx.agent')
 | 
					 | 
				
			||||||
logger.addHandler(NullHandler())
 | 
					 | 
				
			||||||
# --------------------------------------------
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import time
 | 
					 | 
				
			||||||
import inspect
 | 
					 | 
				
			||||||
try:
 | 
					 | 
				
			||||||
    import queue
 | 
					 | 
				
			||||||
except ImportError:
 | 
					 | 
				
			||||||
    import Queue as queue
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import pyagentx
 | 
					 | 
				
			||||||
from pyagentx.updater import Updater
 | 
					 | 
				
			||||||
from pyagentx.network import Network
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class AgentError(Exception):
 | 
					 | 
				
			||||||
    pass
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class Agent(object):
 | 
					 | 
				
			||||||
    def __init__(self, server_address='/var/agentx/master'):
 | 
					 | 
				
			||||||
        self._updater_list = []
 | 
					 | 
				
			||||||
        self._sethandlers = {}
 | 
					 | 
				
			||||||
        self._threads = []
 | 
					 | 
				
			||||||
        self._server_address = server_address
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def register(self, oid, class_, freq=10):
 | 
					 | 
				
			||||||
        if Updater not in inspect.getmro(class_):
 | 
					 | 
				
			||||||
            raise AgentError('Class given isn\'t an updater')
 | 
					 | 
				
			||||||
        # cleanup and test oid
 | 
					 | 
				
			||||||
        try:
 | 
					 | 
				
			||||||
            oid = oid.strip(' .')
 | 
					 | 
				
			||||||
            [int(i) for i in oid.split('.')]
 | 
					 | 
				
			||||||
        except ValueError:
 | 
					 | 
				
			||||||
            raise AgentError('OID isn\'t valid')
 | 
					 | 
				
			||||||
        self._updater_list.append({'oid': oid, 'class': class_, 'freq': freq})
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def register_set(self, oid, class_):
 | 
					 | 
				
			||||||
        if pyagentx.SetHandler not in class_.__bases__:
 | 
					 | 
				
			||||||
            raise AgentError('Class given isn\'t a SetHandler')
 | 
					 | 
				
			||||||
        # cleanup and test oid
 | 
					 | 
				
			||||||
        try:
 | 
					 | 
				
			||||||
            oid = oid.strip(' .')
 | 
					 | 
				
			||||||
            [int(i) for i in oid.split('.')]
 | 
					 | 
				
			||||||
        except ValueError:
 | 
					 | 
				
			||||||
            raise AgentError('OID isn\'t valid')
 | 
					 | 
				
			||||||
        self._sethandlers[oid] = class_()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def setup(self):
 | 
					 | 
				
			||||||
        # Override this
 | 
					 | 
				
			||||||
        pass
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def start(self):
 | 
					 | 
				
			||||||
        update_queue = queue.Queue(maxsize=20000) # 1000 interfaces, 20 variables each
 | 
					 | 
				
			||||||
        self.setup()
 | 
					 | 
				
			||||||
        # Start Updaters
 | 
					 | 
				
			||||||
        for u in self._updater_list:
 | 
					 | 
				
			||||||
            logger.debug('Starting updater [%s]' % u['oid'])
 | 
					 | 
				
			||||||
            t = u['class']()
 | 
					 | 
				
			||||||
            t.agent_setup(update_queue, u['oid'], u['freq'])
 | 
					 | 
				
			||||||
            t.start()
 | 
					 | 
				
			||||||
            self._threads.append(t)
 | 
					 | 
				
			||||||
        # Start Network
 | 
					 | 
				
			||||||
        oid_list = [u['oid'] for u in self._updater_list]
 | 
					 | 
				
			||||||
        t = Network(update_queue, oid_list, self._sethandlers, self._server_address)
 | 
					 | 
				
			||||||
        t.start()
 | 
					 | 
				
			||||||
        self._threads.append(t)
 | 
					 | 
				
			||||||
        # Do nothing ... just wait for someone to stop you
 | 
					 | 
				
			||||||
        while True:
 | 
					 | 
				
			||||||
            #logger.debug('Agent Sleeping ...')
 | 
					 | 
				
			||||||
            time.sleep(1)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def stop(self):
 | 
					 | 
				
			||||||
        logger.debug('Stop threads')
 | 
					 | 
				
			||||||
        for t in self._threads:
 | 
					 | 
				
			||||||
            t.stop.set()
 | 
					 | 
				
			||||||
        logger.debug('Wait for updater')
 | 
					 | 
				
			||||||
        for t in self._threads:
 | 
					 | 
				
			||||||
            t.join()
 | 
					 | 
				
			||||||
@@ -1,272 +0,0 @@
 | 
				
			|||||||
#!/usr/bin/env python
 | 
					 | 
				
			||||||
# -*- coding: utf-8 -*-
 | 
					 | 
				
			||||||
from __future__ import (
 | 
					 | 
				
			||||||
    absolute_import,
 | 
					 | 
				
			||||||
    division,
 | 
					 | 
				
			||||||
    print_function,
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# --------------------------------------------
 | 
					 | 
				
			||||||
import logging
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class NullHandler(logging.Handler):
 | 
					 | 
				
			||||||
    def emit(self, record):
 | 
					 | 
				
			||||||
        pass
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
logger = logging.getLogger('pyagentx.network')
 | 
					 | 
				
			||||||
logger.addHandler(NullHandler())
 | 
					 | 
				
			||||||
# --------------------------------------------
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import socket
 | 
					 | 
				
			||||||
import time
 | 
					 | 
				
			||||||
import threading
 | 
					 | 
				
			||||||
try:
 | 
					 | 
				
			||||||
    import queue
 | 
					 | 
				
			||||||
except ImportError:
 | 
					 | 
				
			||||||
    import Queue as queue
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import pyagentx
 | 
					 | 
				
			||||||
from pyagentx.pdu import PDU
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class Network(threading.Thread):
 | 
					 | 
				
			||||||
    def __init__(self, update_queue, oid_list, sethandlers, server_address):
 | 
					 | 
				
			||||||
        threading.Thread.__init__(self)
 | 
					 | 
				
			||||||
        self.stop = threading.Event()
 | 
					 | 
				
			||||||
        self._queue = update_queue
 | 
					 | 
				
			||||||
        self._oid_list = oid_list
 | 
					 | 
				
			||||||
        self._sethandlers = sethandlers
 | 
					 | 
				
			||||||
        self._server_address = server_address
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        self.session_id = 0
 | 
					 | 
				
			||||||
        self.transaction_id = 0
 | 
					 | 
				
			||||||
        self.debug = 1
 | 
					 | 
				
			||||||
        # Data Related Variables
 | 
					 | 
				
			||||||
        self.data = {}
 | 
					 | 
				
			||||||
        self.data_idx = []
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def _connect(self):
 | 
					 | 
				
			||||||
        while True:
 | 
					 | 
				
			||||||
            try:
 | 
					 | 
				
			||||||
                logger.info("Connecting to %s", self._server_address)
 | 
					 | 
				
			||||||
                if self._server_address.startswith('/'):
 | 
					 | 
				
			||||||
                    self.socket = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
 | 
					 | 
				
			||||||
                    self.socket.connect(self._server_address)
 | 
					 | 
				
			||||||
                else:
 | 
					 | 
				
			||||||
                    self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
 | 
					 | 
				
			||||||
                    self.socket.connect(self._server_address.split(':'))
 | 
					 | 
				
			||||||
                self.socket.settimeout(0.1)
 | 
					 | 
				
			||||||
                return
 | 
					 | 
				
			||||||
            except socket.error:
 | 
					 | 
				
			||||||
                logger.error("Failed to connect, sleeping and retrying later")
 | 
					 | 
				
			||||||
                time.sleep(2)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def new_pdu(self, type):
 | 
					 | 
				
			||||||
        pdu = PDU(type)
 | 
					 | 
				
			||||||
        pdu.session_id = self.session_id
 | 
					 | 
				
			||||||
        pdu.transaction_id = self.transaction_id
 | 
					 | 
				
			||||||
        self.transaction_id += 1
 | 
					 | 
				
			||||||
        return pdu
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def response_pdu(self, org_pdu):
 | 
					 | 
				
			||||||
        pdu = PDU(pyagentx.AGENTX_RESPONSE_PDU)
 | 
					 | 
				
			||||||
        pdu.session_id = org_pdu.session_id
 | 
					 | 
				
			||||||
        pdu.transaction_id = org_pdu.transaction_id
 | 
					 | 
				
			||||||
        pdu.packet_id = org_pdu.packet_id
 | 
					 | 
				
			||||||
        return pdu
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def send_pdu(self, pdu):
 | 
					 | 
				
			||||||
        if self.debug: pdu.dump()
 | 
					 | 
				
			||||||
        self.socket.send(pdu.encode())
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def recv_pdu(self):
 | 
					 | 
				
			||||||
        buf = self.socket.recv(1024)
 | 
					 | 
				
			||||||
        if not buf: return None
 | 
					 | 
				
			||||||
        pdu = PDU()
 | 
					 | 
				
			||||||
        pdu.decode(buf)
 | 
					 | 
				
			||||||
        if self.debug: pdu.dump()
 | 
					 | 
				
			||||||
        return pdu
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    # =========================================
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def _get_updates(self):
 | 
					 | 
				
			||||||
        while True:
 | 
					 | 
				
			||||||
            try:
 | 
					 | 
				
			||||||
                item = self._queue.get_nowait()
 | 
					 | 
				
			||||||
                logger.debug('New update')
 | 
					 | 
				
			||||||
                update_oid = item['oid']
 | 
					 | 
				
			||||||
                update_data = item['data']
 | 
					 | 
				
			||||||
                # clear values with prefix oid
 | 
					 | 
				
			||||||
                for oid in list(self.data.keys()):
 | 
					 | 
				
			||||||
                    if oid.startswith(update_oid):
 | 
					 | 
				
			||||||
                        del (self.data[oid])
 | 
					 | 
				
			||||||
                # insert updated value
 | 
					 | 
				
			||||||
                for row in update_data.values():
 | 
					 | 
				
			||||||
                    oid = "%s.%s" % (update_oid, row['name'])
 | 
					 | 
				
			||||||
                    self.data[oid] = {
 | 
					 | 
				
			||||||
                        'name': oid,
 | 
					 | 
				
			||||||
                        'type': row['type'],
 | 
					 | 
				
			||||||
                        'value': row['value']
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                # recalculate reverse index if data changed
 | 
					 | 
				
			||||||
                self.data_idx = sorted(
 | 
					 | 
				
			||||||
                    self.data.keys(),
 | 
					 | 
				
			||||||
                    key=lambda k: tuple(int(part) for part in k.split('.')))
 | 
					 | 
				
			||||||
            except queue.Empty:
 | 
					 | 
				
			||||||
                break
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def _get_next_oid(self, oid, endoid):
 | 
					 | 
				
			||||||
        if oid in self.data:
 | 
					 | 
				
			||||||
            # Exact match found
 | 
					 | 
				
			||||||
            #logger.debug('get_next_oid, exact match of %s' % oid)
 | 
					 | 
				
			||||||
            idx = self.data_idx.index(oid)
 | 
					 | 
				
			||||||
            if idx == (len(self.data_idx) - 1):
 | 
					 | 
				
			||||||
                # Last Item in MIB, No match!
 | 
					 | 
				
			||||||
                return None
 | 
					 | 
				
			||||||
            return self.data_idx[idx + 1]
 | 
					 | 
				
			||||||
        else:
 | 
					 | 
				
			||||||
            # No exact match, find prefix
 | 
					 | 
				
			||||||
            #logger.debug('get_next_oid, no exact match of %s' % oid)
 | 
					 | 
				
			||||||
            slist = oid.split('.')
 | 
					 | 
				
			||||||
            elist = endoid.split('.')
 | 
					 | 
				
			||||||
            for tmp_oid in self.data_idx:
 | 
					 | 
				
			||||||
                tlist = tmp_oid.split('.')
 | 
					 | 
				
			||||||
                for i in range(len(tlist)):
 | 
					 | 
				
			||||||
                    try:
 | 
					 | 
				
			||||||
                        sok = int(slist[i]) <= int(tlist[i])
 | 
					 | 
				
			||||||
                        eok = int(elist[i]) >= int(tlist[i])
 | 
					 | 
				
			||||||
                        if not (sok and eok):
 | 
					 | 
				
			||||||
                            break
 | 
					 | 
				
			||||||
                    except IndexError:
 | 
					 | 
				
			||||||
                        pass
 | 
					 | 
				
			||||||
                if sok and eok:
 | 
					 | 
				
			||||||
                    return tmp_oid
 | 
					 | 
				
			||||||
            return None  # No match!
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def start(self):
 | 
					 | 
				
			||||||
        while True:
 | 
					 | 
				
			||||||
            try:
 | 
					 | 
				
			||||||
                self._start_network()
 | 
					 | 
				
			||||||
            except socket.error:
 | 
					 | 
				
			||||||
                logger.error("Network error, master disconnect?!")
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def _start_network(self):
 | 
					 | 
				
			||||||
        self._connect()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        logger.info("==== Open PDU ====")
 | 
					 | 
				
			||||||
        pdu = self.new_pdu(pyagentx.AGENTX_OPEN_PDU)
 | 
					 | 
				
			||||||
        self.send_pdu(pdu)
 | 
					 | 
				
			||||||
        pdu = self.recv_pdu()
 | 
					 | 
				
			||||||
        self.session_id = pdu.session_id
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        logger.info("==== Ping PDU ====")
 | 
					 | 
				
			||||||
        pdu = self.new_pdu(pyagentx.AGENTX_PING_PDU)
 | 
					 | 
				
			||||||
        self.send_pdu(pdu)
 | 
					 | 
				
			||||||
        pdu = self.recv_pdu()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        logger.info("==== Register PDU ====")
 | 
					 | 
				
			||||||
        for oid in self._oid_list:
 | 
					 | 
				
			||||||
            logger.info("Registering: %s" % (oid))
 | 
					 | 
				
			||||||
            pdu = self.new_pdu(pyagentx.AGENTX_REGISTER_PDU)
 | 
					 | 
				
			||||||
            pdu.oid = oid
 | 
					 | 
				
			||||||
            self.send_pdu(pdu)
 | 
					 | 
				
			||||||
            pdu = self.recv_pdu()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        logger.info("==== Waiting for PDU ====")
 | 
					 | 
				
			||||||
        while True:
 | 
					 | 
				
			||||||
            try:
 | 
					 | 
				
			||||||
                self._get_updates()
 | 
					 | 
				
			||||||
                request = self.recv_pdu()
 | 
					 | 
				
			||||||
            except socket.timeout:
 | 
					 | 
				
			||||||
                continue
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            if not request:
 | 
					 | 
				
			||||||
                logger.error("Empty PDU, connection closed!")
 | 
					 | 
				
			||||||
                raise socket.error
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            response = self.response_pdu(request)
 | 
					 | 
				
			||||||
            if request.type == pyagentx.AGENTX_GET_PDU:
 | 
					 | 
				
			||||||
                logger.debug("Received GET PDU")
 | 
					 | 
				
			||||||
                for rvalue in request.range_list:
 | 
					 | 
				
			||||||
                    oid = rvalue[0]
 | 
					 | 
				
			||||||
                    logger.debug("OID: %s" % (oid))
 | 
					 | 
				
			||||||
                    if oid in self.data:
 | 
					 | 
				
			||||||
                        logger.debug("OID Found")
 | 
					 | 
				
			||||||
                        response.values.append(self.data[oid])
 | 
					 | 
				
			||||||
                    else:
 | 
					 | 
				
			||||||
                        logger.debug("OID Not Found!")
 | 
					 | 
				
			||||||
                        response.values.append({
 | 
					 | 
				
			||||||
                            'type': pyagentx.TYPE_NOSUCHOBJECT,
 | 
					 | 
				
			||||||
                            'name': rvalue[0],
 | 
					 | 
				
			||||||
                            'value': 0
 | 
					 | 
				
			||||||
                        })
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            elif request.type == pyagentx.AGENTX_GETNEXT_PDU:
 | 
					 | 
				
			||||||
                logger.debug("Received GET_NEXT PDU")
 | 
					 | 
				
			||||||
                for rvalue in request.range_list:
 | 
					 | 
				
			||||||
                    oid = self._get_next_oid(rvalue[0], rvalue[1])
 | 
					 | 
				
			||||||
                    logger.debug("GET_NEXT: %s => %s" % (rvalue[0], oid))
 | 
					 | 
				
			||||||
                    if oid:
 | 
					 | 
				
			||||||
                        response.values.append(self.data[oid])
 | 
					 | 
				
			||||||
                    else:
 | 
					 | 
				
			||||||
                        response.values.append({
 | 
					 | 
				
			||||||
                            'type': pyagentx.TYPE_ENDOFMIBVIEW,
 | 
					 | 
				
			||||||
                            'name': rvalue[0],
 | 
					 | 
				
			||||||
                            'value': 0
 | 
					 | 
				
			||||||
                        })
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            elif request.type == pyagentx.AGENTX_TESTSET_PDU:
 | 
					 | 
				
			||||||
                logger.info("Received TESTSET PDU")
 | 
					 | 
				
			||||||
                idx = 0
 | 
					 | 
				
			||||||
                for row in request.values:
 | 
					 | 
				
			||||||
                    idx += 1
 | 
					 | 
				
			||||||
                    oid = row['name']
 | 
					 | 
				
			||||||
                    type_ = pyagentx.TYPE_NAME.get(row['type'], 'Unknown type')
 | 
					 | 
				
			||||||
                    value = row['data']
 | 
					 | 
				
			||||||
                    logger.info("Name: [%s] Type: [%s] Value: [%s]" %
 | 
					 | 
				
			||||||
                                (oid, type_, value))
 | 
					 | 
				
			||||||
                    # Find matching sethandler
 | 
					 | 
				
			||||||
                    matching_oid = ''
 | 
					 | 
				
			||||||
                    for target_oid in self._sethandlers:
 | 
					 | 
				
			||||||
                        if oid.startswith(target_oid):
 | 
					 | 
				
			||||||
                            matching_oid = target_oid
 | 
					 | 
				
			||||||
                            break
 | 
					 | 
				
			||||||
                    if matching_oid == '':
 | 
					 | 
				
			||||||
                        logger.debug(
 | 
					 | 
				
			||||||
                            'TestSet request failed: not writeable #%s' % idx)
 | 
					 | 
				
			||||||
                        response.error = pyagentx.ERROR_NOTWRITABLE
 | 
					 | 
				
			||||||
                        response.error_index = idx
 | 
					 | 
				
			||||||
                        break
 | 
					 | 
				
			||||||
                    try:
 | 
					 | 
				
			||||||
                        self._sethandlers[matching_oid].network_test(
 | 
					 | 
				
			||||||
                            request.session_id, request.transaction_id, oid,
 | 
					 | 
				
			||||||
                            row['data'])
 | 
					 | 
				
			||||||
                    except pyagentx.SetHandlerError:
 | 
					 | 
				
			||||||
                        logger.debug(
 | 
					 | 
				
			||||||
                            'TestSet request failed: wrong value #%s' % idx)
 | 
					 | 
				
			||||||
                        response.error = pyagentx.ERROR_WRONGVALUE
 | 
					 | 
				
			||||||
                        response.error_index = idx
 | 
					 | 
				
			||||||
                        break
 | 
					 | 
				
			||||||
                logger.debug('TestSet request passed')
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            elif request.type == pyagentx.AGENTX_COMMITSET_PDU:
 | 
					 | 
				
			||||||
                for handler in self._sethandlers.values():
 | 
					 | 
				
			||||||
                    handler.network_commit(request.session_id,
 | 
					 | 
				
			||||||
                                           request.transaction_id)
 | 
					 | 
				
			||||||
                logger.info("Received COMMITSET PDU")
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            elif request.type == pyagentx.AGENTX_UNDOSET_PDU:
 | 
					 | 
				
			||||||
                for handler in self._sethandlers.values():
 | 
					 | 
				
			||||||
                    handler.network_undo(request.session_id,
 | 
					 | 
				
			||||||
                                         request.transaction_id)
 | 
					 | 
				
			||||||
                logger.info("Received UNDOSET PDU")
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            elif request.type == pyagentx.AGENTX_CLEANUPSET_PDU:
 | 
					 | 
				
			||||||
                for handler in self._sethandlers.values():
 | 
					 | 
				
			||||||
                    handler.network_cleanup(request.session_id,
 | 
					 | 
				
			||||||
                                            request.transaction_id)
 | 
					 | 
				
			||||||
                logger.info("Received CLEANUP PDU")
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            self.send_pdu(response)
 | 
					 | 
				
			||||||
@@ -1,67 +0,0 @@
 | 
				
			|||||||
#!/usr/bin/env python
 | 
					 | 
				
			||||||
# -*- coding: utf-8 -*-
 | 
					 | 
				
			||||||
from __future__ import (
 | 
					 | 
				
			||||||
    absolute_import,
 | 
					 | 
				
			||||||
    division,
 | 
					 | 
				
			||||||
    print_function,
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# --------------------------------------------
 | 
					 | 
				
			||||||
import logging
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class NullHandler(logging.Handler):
 | 
					 | 
				
			||||||
    def emit(self, record):
 | 
					 | 
				
			||||||
        pass
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
logger = logging.getLogger('pyagentx.sethandler')
 | 
					 | 
				
			||||||
logger.addHandler(NullHandler())
 | 
					 | 
				
			||||||
# --------------------------------------------
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class SetHandlerError(Exception):
 | 
					 | 
				
			||||||
    pass
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class SetHandler(object):
 | 
					 | 
				
			||||||
    def __init__(self):
 | 
					 | 
				
			||||||
        self.transactions = {}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def network_test(self, session_id, transaction_id, oid, data):
 | 
					 | 
				
			||||||
        tid = "%s_%s" % (session_id, transaction_id)
 | 
					 | 
				
			||||||
        if tid in self.transactions:
 | 
					 | 
				
			||||||
            del (self.transactions[tid])
 | 
					 | 
				
			||||||
        try:
 | 
					 | 
				
			||||||
            self.test(oid, data)
 | 
					 | 
				
			||||||
            self.transactions[tid] = oid, data
 | 
					 | 
				
			||||||
        except SetHandler as e:
 | 
					 | 
				
			||||||
            logger.error('TestSet failed')
 | 
					 | 
				
			||||||
            raise e
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def network_commit(self, session_id, transaction_id):
 | 
					 | 
				
			||||||
        tid = "%s_%s" % (session_id, transaction_id)
 | 
					 | 
				
			||||||
        try:
 | 
					 | 
				
			||||||
            oid, data = self.transactions[tid]
 | 
					 | 
				
			||||||
            self.commit(oid, data)
 | 
					 | 
				
			||||||
            if tid in self.transactions:
 | 
					 | 
				
			||||||
                del (self.transactions[tid])
 | 
					 | 
				
			||||||
        except:
 | 
					 | 
				
			||||||
            logger.error('CommitSet failed')
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def network_undo(self, session_id, transaction_id):
 | 
					 | 
				
			||||||
        tid = "%s_%s" % (session_id, transaction_id)
 | 
					 | 
				
			||||||
        if tid in self.transactions:
 | 
					 | 
				
			||||||
            del (self.transactions[tid])
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def network_cleanup(self, session_id, transaction_id):
 | 
					 | 
				
			||||||
        tid = "%s_%s" % (session_id, transaction_id)
 | 
					 | 
				
			||||||
        if tid in self.transactions:
 | 
					 | 
				
			||||||
            del (self.transactions[tid])
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    # User override these
 | 
					 | 
				
			||||||
    def test(self, oid, data):
 | 
					 | 
				
			||||||
        pass
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def commit(self, oid, data):
 | 
					 | 
				
			||||||
        pass
 | 
					 | 
				
			||||||
@@ -1,137 +0,0 @@
 | 
				
			|||||||
#!/usr/bin/env python
 | 
					 | 
				
			||||||
# -*- coding: utf-8 -*-
 | 
					 | 
				
			||||||
from __future__ import (
 | 
					 | 
				
			||||||
    absolute_import,
 | 
					 | 
				
			||||||
    division,
 | 
					 | 
				
			||||||
    print_function,
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# --------------------------------------------
 | 
					 | 
				
			||||||
import logging
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class NullHandler(logging.Handler):
 | 
					 | 
				
			||||||
    def emit(self, record):
 | 
					 | 
				
			||||||
        pass
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
logger = logging.getLogger('pyagentx.updater')
 | 
					 | 
				
			||||||
logger.addHandler(NullHandler())
 | 
					 | 
				
			||||||
# --------------------------------------------
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import time
 | 
					 | 
				
			||||||
import threading
 | 
					 | 
				
			||||||
try:
 | 
					 | 
				
			||||||
    import queue
 | 
					 | 
				
			||||||
except ImportError:
 | 
					 | 
				
			||||||
    import Queue as queue
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import pyagentx
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class Updater(threading.Thread):
 | 
					 | 
				
			||||||
    def agent_setup(self, queue, oid, freq):
 | 
					 | 
				
			||||||
        self.stop = threading.Event()
 | 
					 | 
				
			||||||
        self._queue = queue
 | 
					 | 
				
			||||||
        self._oid = oid
 | 
					 | 
				
			||||||
        self._freq = freq
 | 
					 | 
				
			||||||
        self._data = {}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def run(self):
 | 
					 | 
				
			||||||
        start_time = 0
 | 
					 | 
				
			||||||
        while True:
 | 
					 | 
				
			||||||
            if self.stop.is_set(): break
 | 
					 | 
				
			||||||
            now = time.time()
 | 
					 | 
				
			||||||
            if now - start_time > self._freq:
 | 
					 | 
				
			||||||
                logger.info('Updating : %s (%s)' %
 | 
					 | 
				
			||||||
                            (self.__class__.__name__, self._oid))
 | 
					 | 
				
			||||||
                start_time = now
 | 
					 | 
				
			||||||
                self._data = {}
 | 
					 | 
				
			||||||
                try:
 | 
					 | 
				
			||||||
                    self.update()
 | 
					 | 
				
			||||||
                    self._queue.put_nowait({
 | 
					 | 
				
			||||||
                        'oid': self._oid,
 | 
					 | 
				
			||||||
                        'data': self._data
 | 
					 | 
				
			||||||
                    })
 | 
					 | 
				
			||||||
                except queue.Full:
 | 
					 | 
				
			||||||
                    logger.error('Queue full')
 | 
					 | 
				
			||||||
                except:
 | 
					 | 
				
			||||||
                    logger.exception('Unhandled update exception')
 | 
					 | 
				
			||||||
            time.sleep(0.1)
 | 
					 | 
				
			||||||
        logger.info('Updater stopping')
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    # Override this
 | 
					 | 
				
			||||||
    def update(self):
 | 
					 | 
				
			||||||
        pass
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def set_INTEGER(self, oid, value):
 | 
					 | 
				
			||||||
        logger.debug('Setting INTEGER %s = %s' % (oid, value))
 | 
					 | 
				
			||||||
        self._data[oid] = {
 | 
					 | 
				
			||||||
            'name': oid,
 | 
					 | 
				
			||||||
            'type': pyagentx.TYPE_INTEGER,
 | 
					 | 
				
			||||||
            'value': value
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def set_OCTETSTRING(self, oid, value):
 | 
					 | 
				
			||||||
        logger.debug('Setting OCTETSTRING %s = %s' % (oid, value))
 | 
					 | 
				
			||||||
        self._data[oid] = {
 | 
					 | 
				
			||||||
            'name': oid,
 | 
					 | 
				
			||||||
            'type': pyagentx.TYPE_OCTETSTRING,
 | 
					 | 
				
			||||||
            'value': value
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def set_OBJECTIDENTIFIER(self, oid, value):
 | 
					 | 
				
			||||||
        logger.debug('Setting OBJECTIDENTIFIER %s = %s' % (oid, value))
 | 
					 | 
				
			||||||
        self._data[oid] = {
 | 
					 | 
				
			||||||
            'name': oid,
 | 
					 | 
				
			||||||
            'type': pyagentx.TYPE_OBJECTIDENTIFIER,
 | 
					 | 
				
			||||||
            'value': value
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def set_IPADDRESS(self, oid, value):
 | 
					 | 
				
			||||||
        logger.debug('Setting IPADDRESS %s = %s' % (oid, value))
 | 
					 | 
				
			||||||
        self._data[oid] = {
 | 
					 | 
				
			||||||
            'name': oid,
 | 
					 | 
				
			||||||
            'type': pyagentx.TYPE_IPADDRESS,
 | 
					 | 
				
			||||||
            'value': value
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def set_COUNTER32(self, oid, value):
 | 
					 | 
				
			||||||
        logger.debug('Setting COUNTER32 %s = %s' % (oid, value))
 | 
					 | 
				
			||||||
        self._data[oid] = {
 | 
					 | 
				
			||||||
            'name': oid,
 | 
					 | 
				
			||||||
            'type': pyagentx.TYPE_COUNTER32,
 | 
					 | 
				
			||||||
            'value': value
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def set_GAUGE32(self, oid, value):
 | 
					 | 
				
			||||||
        logger.debug('Setting GAUGE32 %s = %s' % (oid, value))
 | 
					 | 
				
			||||||
        self._data[oid] = {
 | 
					 | 
				
			||||||
            'name': oid,
 | 
					 | 
				
			||||||
            'type': pyagentx.TYPE_GAUGE32,
 | 
					 | 
				
			||||||
            'value': value
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def set_TIMETICKS(self, oid, value):
 | 
					 | 
				
			||||||
        logger.debug('Setting TIMETICKS %s = %s' % (oid, value))
 | 
					 | 
				
			||||||
        self._data[oid] = {
 | 
					 | 
				
			||||||
            'name': oid,
 | 
					 | 
				
			||||||
            'type': pyagentx.TYPE_TIMETICKS,
 | 
					 | 
				
			||||||
            'value': value
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def set_OPAQUE(self, oid, value):
 | 
					 | 
				
			||||||
        logger.debug('Setting OPAQUE %s = %s' % (oid, value))
 | 
					 | 
				
			||||||
        self._data[oid] = {
 | 
					 | 
				
			||||||
            'name': oid,
 | 
					 | 
				
			||||||
            'type': pyagentx.TYPE_OPAQUE,
 | 
					 | 
				
			||||||
            'value': value
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def set_COUNTER64(self, oid, value):
 | 
					 | 
				
			||||||
        logger.debug('Setting COUNTER64 %s = %s' % (oid, value))
 | 
					 | 
				
			||||||
        self._data[oid] = {
 | 
					 | 
				
			||||||
            'name': oid,
 | 
					 | 
				
			||||||
            'type': pyagentx.TYPE_COUNTER64,
 | 
					 | 
				
			||||||
            'value': value
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
@@ -3,515 +3,151 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
from vppstats import VPPStats
 | 
					from vppstats import VPPStats
 | 
				
			||||||
from vppapi import VPPApi
 | 
					from vppapi import VPPApi
 | 
				
			||||||
import time
 | 
					import agentx
 | 
				
			||||||
import pyagentx
 | 
					
 | 
				
			||||||
import logging
 | 
					class MyAgent(agentx.Agent):
 | 
				
			||||||
import threading
 | 
					    def setup(self):
 | 
				
			||||||
 | 
					        global vppstat, vpp, logger
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.logger.info("Connecting to VPP Stats...")
 | 
				
			||||||
 | 
					        vppstat = VPPStats(socketname='/run/vpp/stats.sock', timeout=2)
 | 
				
			||||||
 | 
					        if not vppstat.connect():
 | 
				
			||||||
 | 
					            self.logger.error("Can't connect to VPP Stats API, bailing")
 | 
				
			||||||
 | 
					            return False
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        vpp = VPPApi(clientname='vpp-snmp-agent')
 | 
				
			||||||
 | 
					        if not vpp.connect():
 | 
				
			||||||
 | 
					            logger.error("Can't connect to VPP API, bailing")
 | 
				
			||||||
 | 
					            return False
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.register('1.3.6.1.2.1.2.2.1')
 | 
				
			||||||
 | 
					        self.register('1.3.6.1.2.1.31.1.1.1')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return True
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
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):
 | 
					    def update(self):
 | 
				
			||||||
        global vppstat, vpp
 | 
					        global vppstat, vpp
 | 
				
			||||||
        vppstat.connect()
 | 
					        vppstat.connect()
 | 
				
			||||||
        vpp.connect()
 | 
					        vpp.connect()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        ds = agentx.DataSet()
 | 
				
			||||||
        ifaces = vpp.get_ifaces()
 | 
					        ifaces = vpp.get_ifaces()
 | 
				
			||||||
 | 
					        self.logger.debug("%d VPP interfaces retrieved" % len(ifaces))
 | 
				
			||||||
 | 
					        self.logger.debug("%d VPP Stats interfaces retrieved" % len(vppstat['/if/names']))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        for i in range(len(vppstat['/if/names'])):
 | 
					        for i in range(len(vppstat['/if/names'])):
 | 
				
			||||||
            ifname = vppstat['/if/names'][i]
 | 
					            ifname = vppstat['/if/names'][i]
 | 
				
			||||||
 | 
					            idx = 1000+i
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            ds.set('1.3.6.1.2.1.2.2.1.1.%u' % (idx), 'int', idx)
 | 
				
			||||||
 | 
					            ds.set('1.3.6.1.2.1.2.2.1.2.%u' % (idx), 'str', ifname)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if ifname.startswith("loop"):
 | 
				
			||||||
 | 
					                ds.set('1.3.6.1.2.1.2.2.1.3.%u' % (idx), 'int', 24)  # softwareLoopback
 | 
				
			||||||
 | 
					            else:
 | 
				
			||||||
 | 
					                ds.set('1.3.6.1.2.1.2.2.1.3.%u' % (idx), 'int', 6)   # ethermet-csmacd
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            mtu = 0
 | 
					            mtu = 0
 | 
				
			||||||
            if not ifname in ifaces:
 | 
					            if not ifname in ifaces:
 | 
				
			||||||
                logger.warning("Could not get MTU for interface %s", ifname)
 | 
					                self.logger.warning("Could not get MTU for interface %s", ifname)
 | 
				
			||||||
            else:
 | 
					            else:
 | 
				
			||||||
                mtu = ifaces[ifname].mtu[0]
 | 
					                mtu = ifaces[ifname].mtu[0]
 | 
				
			||||||
            self.set_INTEGER(str(i + 1), mtu)
 | 
					            ds.set('1.3.6.1.2.1.2.2.1.4.%u' % (idx), 'int', 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
 | 
					            speed = 0
 | 
				
			||||||
            if ifname.startswith("loop") or ifname.startswith("tap"):
 | 
					            if ifname.startswith("loop") or ifname.startswith("tap"):
 | 
				
			||||||
                speed = 1000000000
 | 
					                speed = 1000000000
 | 
				
			||||||
            elif not ifname in ifaces:
 | 
					            elif not ifname in ifaces:
 | 
				
			||||||
                logger.warning("Could not get link speed for interface %s",
 | 
					                self.logger.warning("Could not get link speed for interface %s", ifname)
 | 
				
			||||||
                               ifname)
 | 
					 | 
				
			||||||
            else:
 | 
					            else:
 | 
				
			||||||
                speed = ifaces[ifname].link_speed * 1000
 | 
					                speed = ifaces[ifname].link_speed * 1000
 | 
				
			||||||
            if speed >= 2**32:
 | 
					            if speed >= 2**32:
 | 
				
			||||||
                speed = 2**32 - 1
 | 
					                speed = 2**32 - 1
 | 
				
			||||||
            self.set_GAUGE32(str(i + 1), speed)
 | 
					            ds.set('1.3.6.1.2.1.2.2.1.5.%u' % (idx), 'gauge32', 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"
 | 
					            mac = "00:00:00:00:00:00"
 | 
				
			||||||
            if not ifname in ifaces:
 | 
					            if not ifname in ifaces:
 | 
				
			||||||
                logger.warning("Could not get PhysAddress for interface %s",
 | 
					                self.logger.warning("Could not get PhysAddress for interface %s", ifname)
 | 
				
			||||||
                               ifname)
 | 
					 | 
				
			||||||
            else:
 | 
					            else:
 | 
				
			||||||
                mac = str(ifaces[ifname].l2_address)
 | 
					                mac = str(ifaces[ifname].l2_address)
 | 
				
			||||||
            self.set_OCTETSTRING(str(i + 1), mac)
 | 
					            ds.set('1.3.6.1.2.1.2.2.1.6.%u' % (idx), 'str', mac)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            admin_status = 3  # testing
 | 
				
			||||||
 | 
					            if not ifname in ifaces:
 | 
				
			||||||
 | 
					                self.logger.warning("Could not get AdminStatus for interface %s", ifname)
 | 
				
			||||||
 | 
					            else:
 | 
				
			||||||
 | 
					                if int(ifaces[ifname].flags) & 2:
 | 
				
			||||||
 | 
					                    admin_status = 1  # up
 | 
				
			||||||
 | 
					                else:
 | 
				
			||||||
 | 
					                    admin_status = 2  # down
 | 
				
			||||||
 | 
					            ds.set('1.3.6.1.2.1.2.2.1.7.%u' % (idx), 'int', admin_status)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class ifAlias(pyagentx.Updater):
 | 
					            oper_status = 3  # testing
 | 
				
			||||||
    def update(self):
 | 
					            if not ifname in ifaces:
 | 
				
			||||||
        global vppstat
 | 
					                self.logger.warning("Could not get OperStatus for interface %s", ifname)
 | 
				
			||||||
        vppstat.connect()
 | 
					            else:
 | 
				
			||||||
 | 
					                if int(ifaces[ifname].flags) & 1:
 | 
				
			||||||
 | 
					                    oper_status = 1  # up
 | 
				
			||||||
 | 
					                else:
 | 
				
			||||||
 | 
					                    oper_status = 2  # down
 | 
				
			||||||
 | 
					            ds.set('1.3.6.1.2.1.2.2.1.8.%u' % (idx), 'int', oper_status)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        for i in range(len(vppstat['/if/names'])):
 | 
					            ds.set('1.3.6.1.2.1.2.2.1.9.%u' % (idx), 'ticks', 0)
 | 
				
			||||||
            self.set_OCTETSTRING(str(i + 1), vppstat['/if/names'][i])
 | 
					            ds.set('1.3.6.1.2.1.2.2.1.10.%u' % (idx), 'u32', vppstat['/if/rx'][:, i].sum_octets() % 2**32)
 | 
				
			||||||
 | 
					            ds.set('1.3.6.1.2.1.2.2.1.11.%u' % (idx), 'u32', vppstat['/if/rx'][:, i].sum_packets() % 2**32)
 | 
				
			||||||
 | 
					            ds.set('1.3.6.1.2.1.2.2.1.12.%u' % (idx), 'u32', vppstat['/if/rx-multicast'][:, i].sum_packets() % 2**32)
 | 
				
			||||||
 | 
					            ds.set('1.3.6.1.2.1.2.2.1.13.%u' % (idx), 'u32', vppstat['/if/rx-no-buf'][:, i].sum() % 2**32)
 | 
				
			||||||
 | 
					            ds.set('1.3.6.1.2.1.2.2.1.14.%u' % (idx), 'u32', vppstat['/if/rx-error'][:, i].sum() % 2**32)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            ds.set('1.3.6.1.2.1.2.2.1.16.%u' % (idx), 'u32', vppstat['/if/tx'][:, i].sum_octets() % 2**32)
 | 
				
			||||||
 | 
					            ds.set('1.3.6.1.2.1.2.2.1.17.%u' % (idx), 'u32', vppstat['/if/tx'][:, i].sum_packets() % 2**32)
 | 
				
			||||||
 | 
					            ds.set('1.3.6.1.2.1.2.2.1.18.%u' % (idx), 'u32', vppstat['/if/tx-multicast'][:, i].sum_packets() % 2**32)
 | 
				
			||||||
 | 
					            ds.set('1.3.6.1.2.1.2.2.1.19.%u' % (idx), 'u32', vppstat['/if/drops'][:, i].sum() % 2**32)
 | 
				
			||||||
 | 
					            ds.set('1.3.6.1.2.1.2.2.1.20.%u' % (idx), 'u32', vppstat['/if/tx-error'][:, i].sum() % 2**32)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class ifInMulticastPkts(pyagentx.Updater):
 | 
					            ds.set('1.3.6.1.2.1.31.1.1.1.1.%u' % (idx), 'str', ifname)
 | 
				
			||||||
    def update(self):
 | 
					            ds.set('1.3.6.1.2.1.31.1.1.1.2.%u' % (idx), 'u32', vppstat['/if/rx-multicast'][:, i].sum_packets() % 2**32)
 | 
				
			||||||
        global vppstat
 | 
					            ds.set('1.3.6.1.2.1.31.1.1.1.3.%u' % (idx), 'u32', vppstat['/if/rx-broadcast'][:, i].sum_packets() % 2**32)
 | 
				
			||||||
        vppstat.connect()
 | 
					            ds.set('1.3.6.1.2.1.31.1.1.1.4.%u' % (idx), 'u32', vppstat['/if/tx-multicast'][:, i].sum_packets() % 2**32)
 | 
				
			||||||
 | 
					            ds.set('1.3.6.1.2.1.31.1.1.1.5.%u' % (idx), 'u32', vppstat['/if/tx-broadcast'][:, i].sum_packets() % 2**32)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        for i in range(len(vppstat['/if/names'])):
 | 
					            ds.set('1.3.6.1.2.1.31.1.1.1.6.%u' % (idx), 'u64', vppstat['/if/rx'][:, i].sum_octets())
 | 
				
			||||||
            self.set_COUNTER32(
 | 
					            ds.set('1.3.6.1.2.1.31.1.1.1.7.%u' % (idx), 'u64', vppstat['/if/rx'][:, i].sum_packets())
 | 
				
			||||||
                str(i + 1),
 | 
					            ds.set('1.3.6.1.2.1.31.1.1.1.8.%u' % (idx), 'u64', vppstat['/if/rx-multicast'][:, i].sum_packets())
 | 
				
			||||||
                vppstat['/if/rx-multicast'][:, i].sum_packets() % 2**32)
 | 
					            ds.set('1.3.6.1.2.1.31.1.1.1.9.%u' % (idx), 'u64', vppstat['/if/rx-broadcast'][:, i].sum_packets())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            ds.set('1.3.6.1.2.1.31.1.1.1.10.%u' % (idx), 'u64', vppstat['/if/tx'][:, i].sum_octets())
 | 
				
			||||||
 | 
					            ds.set('1.3.6.1.2.1.31.1.1.1.11.%u' % (idx), 'u64', vppstat['/if/tx'][:, i].sum_packets())
 | 
				
			||||||
 | 
					            ds.set('1.3.6.1.2.1.31.1.1.1.12.%u' % (idx), 'u64', vppstat['/if/tx-multicast'][:, i].sum_packets())
 | 
				
			||||||
 | 
					            ds.set('1.3.6.1.2.1.31.1.1.1.13.%u' % (idx), 'u64', vppstat['/if/tx-broadcast'][:, i].sum_packets())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
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
 | 
					            speed = 0
 | 
				
			||||||
            if ifname.startswith("loop") or ifname.startswith("tap"):
 | 
					            if ifname.startswith("loop") or ifname.startswith("tap"):
 | 
				
			||||||
                speed = 1000
 | 
					                speed = 1000
 | 
				
			||||||
            elif not ifname in ifaces:
 | 
					            elif not ifname in ifaces:
 | 
				
			||||||
                logger.warning("Could not get link speed for interface %s",
 | 
					                self.logger.warning("Could not get link speed for interface %s", ifname)
 | 
				
			||||||
                               ifname)
 | 
					 | 
				
			||||||
            else:
 | 
					            else:
 | 
				
			||||||
                speed = int(ifaces[ifname].link_speed / 1000)
 | 
					                speed = int(ifaces[ifname].link_speed / 1000)
 | 
				
			||||||
            self.set_GAUGE32(str(i + 1), speed)
 | 
					            ds.set('1.3.6.1.2.1.31.1.1.1.15.%u' % (idx), 'gauge32', 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)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            ds.set('1.3.6.1.2.1.31.1.1.1.16.%u' % (idx), 'int', 2)   # Hardcode to false(2)
 | 
				
			||||||
 | 
					            ds.set('1.3.6.1.2.1.31.1.1.1.17.%u' % (idx), 'int', 1)   # Hardcode to true(1)
 | 
				
			||||||
 | 
					            ds.set('1.3.6.1.2.1.31.1.1.1.18.%u' % (idx), 'str', ifname)
 | 
				
			||||||
 | 
					            ds.set('1.3.6.1.2.1.31.1.1.1.19.%u' % (idx), 'ticks', 0)  # Hardcode to Timeticks: (0) 0:00:00.00
 | 
				
			||||||
 | 
					        return ds
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def main():
 | 
					def main():
 | 
				
			||||||
    global vppstat, vpp, logger
 | 
					    agentx.setup_logging(debug=False)
 | 
				
			||||||
 | 
					 | 
				
			||||||
    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:
 | 
					    try:
 | 
				
			||||||
        a = MyAgent(server_address='/run/vpp/agentx.sock')
 | 
					        a = MyAgent(server_address='/run/vpp/agentx.sock')
 | 
				
			||||||
        a.start()
 | 
					        a.run()
 | 
				
			||||||
    except Exception as e:
 | 
					    except Exception as e:
 | 
				
			||||||
        print("Unhandled exception:", e)
 | 
					        print("Unhandled exception:", e)
 | 
				
			||||||
        a.stop()
 | 
					        a.stop()
 | 
				
			||||||
    except KeyboardInterrupt:
 | 
					    except KeyboardInterrupt:
 | 
				
			||||||
        a.stop()
 | 
					        a.stop()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    vppstat.disconnect()
 | 
					 | 
				
			||||||
    vpp.disconnect()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
if __name__ == "__main__":
 | 
					if __name__ == "__main__":
 | 
				
			||||||
    main()
 | 
					    main()
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										18
									
								
								vppapi.py
									
									
									
									
									
								
							
							
						
						
									
										18
									
								
								vppapi.py
									
									
									
									
									
								
							@@ -7,7 +7,6 @@ from vpp_papi import VPPApiClient
 | 
				
			|||||||
import os
 | 
					import os
 | 
				
			||||||
import fnmatch
 | 
					import fnmatch
 | 
				
			||||||
import logging
 | 
					import logging
 | 
				
			||||||
import threading
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class NullHandler(logging.Handler):
 | 
					class NullHandler(logging.Handler):
 | 
				
			||||||
@@ -16,18 +15,16 @@ class NullHandler(logging.Handler):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class VPPApi():
 | 
					class VPPApi():
 | 
				
			||||||
    def __init__(self, address='/run/vpp/api.sock'):
 | 
					    def __init__(self, address='/run/vpp/api.sock', clientname='vppapi-client'):
 | 
				
			||||||
        self.address = address
 | 
					        self.address = address
 | 
				
			||||||
        self.lock = threading.Lock()
 | 
					 | 
				
			||||||
        self.connected = False
 | 
					        self.connected = False
 | 
				
			||||||
        self.logger = logging.getLogger('pyagentx.vppapi')
 | 
					        self.logger = logging.getLogger('agentx.vppapi')
 | 
				
			||||||
        self.logger.addHandler(NullHandler())
 | 
					        self.logger.addHandler(NullHandler())
 | 
				
			||||||
 | 
					        self.clientname = clientname
 | 
				
			||||||
        self.vpp = None
 | 
					        self.vpp = None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def connect(self):
 | 
					    def connect(self):
 | 
				
			||||||
        self.lock.acquire()
 | 
					 | 
				
			||||||
        if self.connected:
 | 
					        if self.connected:
 | 
				
			||||||
            self.lock.release()
 | 
					 | 
				
			||||||
            return True
 | 
					            return True
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        vpp_json_dir = '/usr/share/vpp/api/'
 | 
					        vpp_json_dir = '/usr/share/vpp/api/'
 | 
				
			||||||
@@ -40,23 +37,20 @@ class VPPApi():
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        if not jsonfiles:
 | 
					        if not jsonfiles:
 | 
				
			||||||
            self.logger.error('no json api files found')
 | 
					            self.logger.error('no json api files found')
 | 
				
			||||||
            self.lock.release()
 | 
					 | 
				
			||||||
            return False
 | 
					            return False
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self.vpp = VPPApiClient(apifiles=jsonfiles,
 | 
					        self.vpp = VPPApiClient(apifiles=jsonfiles,
 | 
				
			||||||
                                server_address=self.address)
 | 
					                                server_address=self.address)
 | 
				
			||||||
        try:
 | 
					        try:
 | 
				
			||||||
            self.logger.info('Connecting to VPP')
 | 
					            self.logger.info('Connecting to VPP')
 | 
				
			||||||
            self.vpp.connect('vpp-snmp-agent')
 | 
					            self.vpp.connect(self.clientname)
 | 
				
			||||||
        except:
 | 
					        except:
 | 
				
			||||||
            self.lock.release()
 | 
					 | 
				
			||||||
            return False
 | 
					            return False
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        v = self.vpp.api.show_version()
 | 
					        v = self.vpp.api.show_version()
 | 
				
			||||||
        self.logger.info('VPP version is %s' % v.version)
 | 
					        self.logger.info('VPP version is %s' % v.version)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self.connected = True
 | 
					        self.connected = True
 | 
				
			||||||
        self.lock.release()
 | 
					 | 
				
			||||||
        return True
 | 
					        return True
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def disconnect(self):
 | 
					    def disconnect(self):
 | 
				
			||||||
@@ -71,23 +65,19 @@ class VPPApi():
 | 
				
			|||||||
        if not self.connected:
 | 
					        if not self.connected:
 | 
				
			||||||
            return ret
 | 
					            return ret
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self.lock.acquire()
 | 
					 | 
				
			||||||
        try:
 | 
					        try:
 | 
				
			||||||
            iface_list = self.vpp.api.sw_interface_dump()
 | 
					            iface_list = self.vpp.api.sw_interface_dump()
 | 
				
			||||||
        except Exception as e:
 | 
					        except Exception as e:
 | 
				
			||||||
            self.logger.error("VPP communication error, disconnecting", e)
 | 
					            self.logger.error("VPP communication error, disconnecting", e)
 | 
				
			||||||
            self.vpp.disconnect()
 | 
					            self.vpp.disconnect()
 | 
				
			||||||
            self.connected = False
 | 
					            self.connected = False
 | 
				
			||||||
            self.lock.release()
 | 
					 | 
				
			||||||
            return ret
 | 
					            return ret
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if not iface_list:
 | 
					        if not iface_list:
 | 
				
			||||||
            self.logger.error("Can't get interface list")
 | 
					            self.logger.error("Can't get interface list")
 | 
				
			||||||
            self.lock.release()
 | 
					 | 
				
			||||||
            return ret
 | 
					            return ret
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        for iface in iface_list:
 | 
					        for iface in iface_list:
 | 
				
			||||||
            ret[iface.interface_name] = iface
 | 
					            ret[iface.interface_name] = iface
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self.lock.release()
 | 
					 | 
				
			||||||
        return ret
 | 
					        return ret
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										11
									
								
								vppstats.py
									
									
									
									
									
								
							
							
						
						
									
										11
									
								
								vppstats.py
									
									
									
									
									
								
							@@ -110,9 +110,12 @@ class VPPStats():
 | 
				
			|||||||
    def connect(self):
 | 
					    def connect(self):
 | 
				
			||||||
        '''Connect to stats segment'''
 | 
					        '''Connect to stats segment'''
 | 
				
			||||||
        if self.connected:
 | 
					        if self.connected:
 | 
				
			||||||
            return
 | 
					            return True
 | 
				
			||||||
        sock = socket.socket(socket.AF_UNIX, socket.SOCK_SEQPACKET)
 | 
					        try:
 | 
				
			||||||
        sock.connect(self.socketname)
 | 
					          sock = socket.socket(socket.AF_UNIX, socket.SOCK_SEQPACKET)
 | 
				
			||||||
 | 
					          sock.connect(self.socketname)
 | 
				
			||||||
 | 
					        except:
 | 
				
			||||||
 | 
					            return False
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Get file descriptor for memory map
 | 
					        # Get file descriptor for memory map
 | 
				
			||||||
        fds = array.array("i")  # Array of ints
 | 
					        fds = array.array("i")  # Array of ints
 | 
				
			||||||
@@ -133,9 +136,11 @@ class VPPStats():
 | 
				
			|||||||
        if self.version != 2:
 | 
					        if self.version != 2:
 | 
				
			||||||
            raise Exception('Incompatbile stat segment version {}'.format(
 | 
					            raise Exception('Incompatbile stat segment version {}'.format(
 | 
				
			||||||
                self.version))
 | 
					                self.version))
 | 
				
			||||||
 | 
					            return False
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self.refresh()
 | 
					        self.refresh()
 | 
				
			||||||
        self.connected = True
 | 
					        self.connected = True
 | 
				
			||||||
 | 
					        return True
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def disconnect(self):
 | 
					    def disconnect(self):
 | 
				
			||||||
        '''Disconnect from stats segment'''
 | 
					        '''Disconnect from stats segment'''
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user