def _connect(self): log.debug("TrapEventDispatcher: Connecting to %s:%d" % (self._remote_host, self._remote_port)) # create socket self._socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) if self._socket is None: # log Error log.error("TrapEventDispatcher: Unable to create socket") # close Socket self._close() return # set socket timeout self._socket.settimeout(self._socket_timeout) # connect to graphite server try: self._socket.connect((self._remote_host, self._remote_port)) # Log log.debug("TrapEventDispatcher: Established connection to %s:%d" % (self._remote_host, self._remote_port)) except: # Log Error log.exception("TrapEventDispatcher: Failed to connect to %s:%d" % (self._remote_host, self._remote_port)) # Close Socket self._close() return
def dispatch(self, event): # Log Event events_log.info(event.to_json()) # Enqueue TrapEvent self._events.append(event) log.debug("TrapEventDispatcherThread: Enqueued Event: %r" % (event)) return True
def __init__(self, config, mibs, callback): self._config = config self._mibs = mibs self._callback = callback # Create SNMP engine with autogenernated engineID and pre-bound to # socket transport dispatcher self._snmp_engine = pysnmp.entity.engine.SnmpEngine() log.debug("TrapReceiver: Initialized SNMP Engine") # Configure transport UDP over IPv4 if config['snmp']['transport']['udp']['enabled']: self._configure_udp_transport( config['snmp']['transport']['listen_address'], int(config['snmp']['transport']['listen_port'])) # Configure transport TCP over IPv4 if config['snmp']['transport']['tcp']['enabled']: # TODO: Implement TCP transport ? pass # Configure SNMPv2 if enabled if bool(self._config['snmp']['auth']['version2']['enabled']): self._configure_snmp_v2(self._config['snmp']['auth']['version2']['community']) # Configure SNMPv3 if enabled if bool(self._config['snmp']['auth']['version3']['enabled']): # TODO: configure SNMPv3 users from config file self._configure_snmp_v3(self._config['snmp']['auth']['version3']['users']) # configure pysnmp debugging #from pysnmp import debug #debug.setLogger(debug.Debug('io')) log.debug("TrapReceiver: Initialized")
def dispatch(self, event): log.debug("TrapEventDispatcher: Dispatching TrapEvent: %r" % (event)) try: self._connect() # Send event self._socket.sendall(event.to_json()) if self._config['dispatcher']['check_response']: # Receive event confirmation self._socket.setblocking(0) timer = int(time.time()) data = "" while (int(time.time()) - timer) < self._socket_timeout: try: data = self._socket.recv(512) break except socket.error, e: pass self._socket.setblocking(1) if len(data) <= 0 or data.strip() != "ok": log.error( "TrapEventDispatcher: Error dispatching event. Response was: %s" % (data)) return False log.info("TrapEventDispatcher: Dispatched TrapEvent: %r" % (event)) return True
def __init__(self, config): self._config = config self._remote_host = self._config['dispatcher']['host'] self._remote_port = int(self._config['dispatcher']['port']) self._socket_timeout = int(self._config['dispatcher']['timeout']) self._socket = None log.debug("TrapEventDispatcher: Initialized")
def _configure_mibs(self): try: self._mibs = MibResolver(self._config['mibs']['paths'], self._config['mibs']['mibs']) except Exception as e: LOG.debug(str(e)) raise
def dispatch(self, event): log.debug("TrapEventDispatcher: Dispatching TrapEvent: %r" % (event)) try: self._connect() # Send event self._socket.sendall(event.to_json()) if self._config['dispatcher']['check_response']: # Receive event confirmation self._socket.setblocking(0) timer = int(time.time()) data = "" while (int(time.time()) - timer) < self._socket_timeout: try: data = self._socket.recv(512) break except socket.error, e: pass self._socket.setblocking(1) if len(data) <= 0 or data.strip() != "ok": log.error("TrapEventDispatcher: Error dispatching event. Response was: %s" % (data)) return False log.info("TrapEventDispatcher: Dispatched TrapEvent: %r" % (event)) return True
def _notification_callback(self, snmp_engine, stateReference, contextEngineId, contextName, varBinds, cbCtx): """ Callback function for receiving notifications """ trap_oid = None trap_name = None trap_args = dict() try: # get the source address for this notification transportDomain, trap_source = snmp_engine.msgAndPduDsp.getTransportInfo( stateReference) log.debug("TrapReceiver: Notification received from %s, %s" % (trap_source[0], trap_source[1])) # read all the varBinds for oid, val in varBinds: # translate OID to mib symbol/modname (module, symbol) = self._mibs.lookup_oid(oid) if module == "SNMPv2-MIB" and symbol == "snmpTrapOID": # the SNMPv2-MIB::snmpTrapOID value is the trap oid trap_oid = val # load the mib symbol/modname for the trap oid (trap_symbol_name, trap_mod_name) = self._mibs.lookup_oid(trap_oid) else: # all other values should be converted to mib symbol/modname # and put in the trap_data dict trap_arg_oid = oid # convert value trap_arg_value = self._mibs.lookup_value( module, symbol, val) trap_args[trap_arg_oid] = trap_arg_value log.debug("TrapReceiver: Trap argument: %s, %s = %s" % (module, symbol, val)) # get trap source info trap_source_address, trap_source_port = trap_source trap_source_hostname, trap_source_domain = get_hostname_from_address( trap_source_address) # set trap propreties trap_properties = dict() trap_properties['hostname'] = trap_source_hostname trap_properties['ipaddress'] = trap_source_address trap_properties['domain'] = trap_source_domain # create trap trap = self._create_trap(trap_oid, trap_args, trap_properties) # now that everything has been parsed, trigger the callback self._callback(trap) except Exception, ex: log.exception("Error handling SNMP notification")
def __init__(self, config): self._config = config self._remote_host = self._config["dispatcher"]["host"] self._remote_port = int(self._config["dispatcher"]["port"]) self._socket_timeout = int(self._config["dispatcher"]["timeout"]) self._socket = None # Connect to Sensu self._connect() log.debug("TrapEventDispatcher: Initialized")
def _notification_callback(self, snmp_engine, stateReference, contextEngineId, contextName, varBinds, cbCtx): """ Callback function for receiving notifications """ trap_oid = None trap_name = None trap_args = dict() try: # get the source address for this notification transportDomain, trap_source = snmp_engine.msgAndPduDsp.getTransportInfo(stateReference) log.debug("TrapReceiver: Notification received from %s, %s" % (trap_source[0], trap_source[1])) # read all the varBinds for oid, val in varBinds: # translate OID to mib symbol/modname (module, symbol) = self._mibs.lookup_oid(oid) if module == "SNMPv2-MIB" and symbol == "snmpTrapOID": # the SNMPv2-MIB::snmpTrapOID value is the trap oid trap_oid = val # load the mib symbol/modname for the trap oid (trap_symbol_name, trap_mod_name) = self._mibs.lookup_oid(trap_oid) else: # all other values should be converted to mib symbol/modname # and put in the trap_data dict #trap_arg_oid = oid # For the case the faultIndex was added into the OID, we have to lookup # the original OID from MIB instead of using the OID in the received packet directly. trap_arg_oid = self._mibs.lookup(module, symbol) # convert value trap_arg_value = self._mibs.lookup_value(module, symbol, val) trap_args[trap_arg_oid] = trap_arg_value log.debug("TrapReceiver: Trap argument: %s, %s = %s" % (module, symbol, val)) # get trap source info trap_source_address, trap_source_port = trap_source trap_source_hostname, trap_source_domain = get_hostname_from_address(trap_source_address) # set trap propreties trap_properties = dict() trap_properties['hostname'] = trap_source_hostname trap_properties['ipaddress'] = trap_source_address trap_properties['domain'] = trap_source_domain # create trap trap = self._create_trap(trap_oid, trap_args, trap_properties) # now that everything has been parsed, trigger the callback self._callback(trap) except Exception, ex: log.exception("Error handling SNMP notification")
def _parse_trap_handlers(self, trap_file): # TODO: Support multiple trap files LOG.debug("SensuTrapServer: Parsing trap handler file: %s" % (trap_file)) trap_handlers = dict() try: fh = open(trap_file, 'r') trap_file_data = json.load(fh) for trap_handler_id, trap_handler_config in trap_file_data.items(): # Load TrapHandler trap_handler = self._load_trap_handler(trap_handler_id, trap_handler_config) trap_handlers[trap_handler_id] = trap_handler LOG.debug("SensuTrapServer: Parsed trap handler: %s" % (trap_handler_id)) finally: fh.close() return trap_handlers
def run(self): LOG.debug("SensuTrapServer: Started") self._run = True # Start TrapReceiverThread self._trap_receiver_thread.start() # Start TrapEventDispatcherThread self._trap_event_dispatcher_thread.start() while self._run: time.sleep(1) # Wait for our threads to stop self._trap_receiver_thread.join() self._trap_event_dispatcher_thread.join() LOG.debug("SensuTrapServer: Exiting")
def __init__(self, config): self._config = config self._run = False # Configure MIBs self._configure_mibs() # Initialize TrapReceiverThread self._trap_receiver_thread = TrapReceiverThread(self._config, self._mibs, self._handle_trap) # Initialize TrapEventDispatcher self._trap_event_dispatcher_thread = TrapEventDispatcherThread(self._config) # Configure Trap Handlers self._trap_handlers = self._parse_trap_handlers(self._config['daemon']['trap_file']) LOG.debug("SensuTrapServer: Initialized")
def _parse_trap_handlers(self, trap_path): LOG.debug( "SensuTrapServer: Parsing trap handler files in '%s' directory" % trap_path) trap_handlers = dict() files = [f for f in listdir(trap_path) if isfile(join(trap_path, f))] for trap_file in files: try: LOG.debug("SensuTrapServer: Parsing trap handler file: %s" % (trap_file)) fh = open(join(trap_path, trap_file), 'r') trap_file_data = json.load(fh) for trap_handler_id, trap_handler_config in trap_file_data.items( ): # Load TrapHandler trap_handler = self._load_trap_handler( trap_handler_id, trap_handler_config) trap_handlers[trap_handler_id] = trap_handler LOG.debug("SensuTrapServer: Parsed trap handler: %s" % (trap_handler_id)) finally: fh.close() return trap_handlers
def run(self): log.debug("%s: Started" % (self.name)) self._run = True backoff = 0 while self._run: if backoff <= 0: try: # pop event off queue event = self._events.popleft() # attempt to dispatch event if not self._trap_event_dispatcher.dispatch(event): # dispatch failed. put the event back on the queue self._events.appendleft(event) # back off backoff = int(self._config["dispatcher"]["backoff"]) log.debug("TrapDispatcherThread: back off for %d seconds" % (backoff)) except IndexError: # Nothing in queue pass else: backoff = backoff - 1 time.sleep(1) log.debug("%s: Exiting" % (self.name))
def _configure_snmp_v3(self, users): # configure snmp v3 users for user in users: auth = users[user]['authentication'] priv = users[user]['privacy'] auth_protocol = self.SNMPV3_AUTH_PROTOCOLS[auth['protocol']] priv_protocol = self.SNMPV3_PRIV_PROTOCOLS[priv['protocol']] if priv_protocol: pysnmp.entity.config.addV3User(self._snmp_engine, user, auth_protocol, auth['password'], priv_protocol, priv['password']) log.debug("TrapReceiver: Added SNMPv3 user: %s auth: %s, priv: %s" % (user, auth['protocol'], priv['protocol'])) else: pysnmp.entity.config.addV3User(self._snmp_engine, user, auth_protocol, auth['password']) log.debug("TrapReceiver: Added SNMPv3 user: %s auth: %s, priv: none" % (user, auth['protocol'])) log.debug("TrapReceiver: Initialized SNMPv3 Auth")
def run(self): log.debug("%s: Started" % (self.name)) self._run = True backoff = 0 while self._run: if backoff <= 0: try: # pop event off queue event = self._events.popleft() # attempt to dispatch event if not self._trap_event_dispatcher.dispatch(event): # dispatch failed. put the event back on the queue self._events.appendleft(event) # back off backoff = int(self._config['dispatcher']['backoff']) log.debug( "TrapDispatcherThread: back off for %d seconds" % (backoff)) except IndexError: # Nothing in queue pass else: backoff = backoff - 1 time.sleep(1) log.debug("%s: Exiting" % (self.name))
def _configure_snmp_v3(self, users): # configure snmp v3 users for user in users: auth = users[user]['authentication'] priv = users[user]['privacy'] auth_protocol = self.SNMPV3_AUTH_PROTOCOLS[auth['protocol']] priv_protocol = self.SNMPV3_PRIV_PROTOCOLS[priv['protocol']] if priv_protocol: pysnmp.entity.config.addV3User(self._snmp_engine, user, auth_protocol, auth['password'], priv_protocol, priv['password']) log.debug( "TrapReceiver: Added SNMPv3 user: %s auth: %s, priv: %s" % (user, auth['protocol'], priv['protocol'])) else: pysnmp.entity.config.addV3User(self._snmp_engine, user, auth_protocol, auth['password']) log.debug( "TrapReceiver: Added SNMPv3 user: %s auth: %s, priv: none" % (user, auth['protocol'])) log.debug("TrapReceiver: Initialized SNMPv3 Auth")
def __init__(self, mib_paths=None, mib_list=None): if mib_paths is None: mib_paths = [] if mib_list is None: mib_list = [] # Initialize mib MibBuilder self._mib_builder = pysnmp.smi.builder.MibBuilder() # Configure MIB sources self._mib_sources = self._mib_builder.getMibSources() # Load default mib dirs for path in self.DEFAULT_MIB_PATHS + mib_paths: self.load_mib_dir(path) # Load default mibs for mib in self.DEFAULT_MIB_LIST + mib_list: self.load_mib(mib) # Initialize MibViewController self._mib_view = pysnmp.smi.view.MibViewController(self._mib_builder) log.debug("MibResolver: Initialized")
def dispatch(self, event): # TODO: send event! log.debug("TrapEventDispatcher: Dispatching TrapEvent: %r" % (event)) try: # try to (re)connect if self._socket is None: log.debug("TrapEventDispatcher: Socket is not connected. Reconnecting") self._connect() if self._socket is not None: # Send event self._socket.sendall(event.to_json()) if self._config["dispatcher"]["check_response"]: # Receive event confirmation self._socket.setblocking(0) timer = int(time.time()) data = "" while (int(time.time()) - timer) < self._socket_timeout: try: data = self._socket.recv(512) break except socket.error, e: pass self._socket.setblocking(1) if len(data) <= 0 or data.strip() != "ok": log.error("TrapEventDispatcher: Error dispatching event. Response was: %s" % (data)) return False # TODO: send event! log.info("TrapEventDispatcher: Dispatched TrapEvent: %r" % (event)) return True except: self._close() log.exception("TrapEventDispatcher: Error dispatching event") return False
def __init__(self, config, mibs, callback): self._config = config self._mibs = mibs self._callback = callback # Create SNMP engine with autogenernated engineID and pre-bound to # socket transport dispatcher self._snmp_engine = pysnmp.entity.engine.SnmpEngine() log.debug("TrapReceiver: Initialized SNMP Engine") # Configure transport UDP over IPv4 if config['snmp']['transport']['udp']['enabled']: self._configure_udp_transport( config['snmp']['transport']['listen_address'], int(config['snmp']['transport']['listen_port'])) # Configure transport TCP over IPv4 if config['snmp']['transport']['tcp']['enabled']: # TODO: Implement TCP transport ? pass # Configure SNMPv2 if enabled if bool(self._config['snmp']['auth']['version2']['enabled']): self._configure_snmp_v2( self._config['snmp']['auth']['version2']['community']) # Configure SNMPv3 if enabled if bool(self._config['snmp']['auth']['version3']['enabled']): # TODO: configure SNMPv3 users from config file self._configure_snmp_v3( self._config['snmp']['auth']['version3']['users']) # configure pysnmp debugging #from pysnmp import debug #debug.setLogger(debug.Debug('io')) log.debug("TrapReceiver: Initialized")
def _parse_trap_handlers(self, trap_path): LOG.debug("SensuTrapServer: Parsing trap handler files in '%s' directory" % trap_path) trap_handlers = dict() files = [ f for f in listdir(trap_path) if isfile(join(trap_path,f)) ] for trap_file in files: try: LOG.debug("SensuTrapServer: Parsing trap handler file: %s" % (trap_file)) fh = open(join(trap_path, trap_file), 'r') trap_file_data = json.load(fh) for trap_handler_id, trap_handler_config in trap_file_data.items(): # Load TrapHandler trap_handler = self._load_trap_handler(trap_handler_id, trap_handler_config) trap_handlers[trap_handler_id] = trap_handler LOG.debug("SensuTrapServer: Parsed trap handler: %s" % (trap_handler_id)) finally: fh.close() return trap_handlers
def run(self): log.debug("%s: Started" % (self.name)) self._trap_receiver.run() log.debug("%s: Exiting" % (self.name))
def _configure_snmp_v2(self, community): # v1/2 setup pysnmp.entity.config.addV1System(self._snmp_engine, 'sensu-trapd-agent', community) log.debug("TrapReceiver: Initialized SNMPv1 Auth")
def _close(self): if self._socket is not None: log.debug("TrapEventDispatcher: Closing connection to %s:%d" % (self._remote_host, self._remote_port)) self._socket.close() self._socket = None
def load_mib(self, mib): self._mib_builder.loadModules(mib, ) log.debug("MibResolver: Loaded MIB: %s" % mib)
def load_mib_dir(self, path): self._mib_sources += (pysnmp.smi.builder.DirMibSource(path),) log.debug("MibResolver: Loaded MIB source: %s" % path) self._mib_builder.setMibSources(*self._mib_sources)