def setUp(self): self.generator = Generator() setup_logging() self.hosts = {} self.applications = {} coshsh.application.Application.init_classes([ os.path.join(os.path.dirname(__file__), '../recipes/default/classes'), os.path.join(os.path.dirname(__file__), 'recipes/test10/classes')]) MonitoringDetail.init_classes([ os.path.join(os.path.dirname(__file__), '../recipes/default/classes'), os.path.join(os.path.dirname(__file__), 'recipes/test10/classes')]) pass row = ['drivelsrv', '11.120.9.10', 'Server', 'Red Hat 6.0', '', 'vs', '7x24', '2nd floor', 'ps'] final_row = { } for (index, value) in enumerate(['host_name', 'address', 'type', 'os', 'hardware', 'virtual', 'notification_period', 'location', 'department']): final_row[value] = [None if row[index] == "" else row[index]][0] h = coshsh.host.Host(final_row) self.hosts[h.host_name] = h row = ['drivel', 'mysql', '', '', '', 'drivelsrv', '7x24'] final_row = { } for (index, value) in enumerate(['name', 'type', 'component', 'version', 'patchlevel', 'host_name', 'check_period']): final_row[value] = [None if row[index] == "" else row[index]][0] a = coshsh.application.Application(final_row) #a.__init__(final_row) self.applications[a.fingerprint()] = a setattr(a, "host", self.hosts[a.host_name])
def setUp(self): self.generator = Generator() self.generator.setup_logging() self.hosts = {} self.applications = {} coshsh.application.Application.init_classes([ os.path.join(os.path.dirname(__file__), '../recipes/default/classes'), os.path.join(os.path.dirname(__file__), 'recipes/test10/classes')]) MonitoringDetail.init_classes([ os.path.join(os.path.dirname(__file__), '../recipes/default/classes'), os.path.join(os.path.dirname(__file__), 'recipes/test10/classes')]) pass row = ['drivelsrv', '11.120.9.10', 'Server', 'Red Hat 6.0', '', 'vs', '7x24', '2nd floor', 'ps'] final_row = { } for (index, value) in enumerate(['host_name', 'address', 'type', 'os', 'hardware', 'virtual', 'notification_period', 'location', 'department']): final_row[value] = [None if row[index] == "" else row[index]][0] h = coshsh.host.Host(final_row) self.hosts[h.host_name] = h row = ['drivel', 'mysql', '', '', '', 'drivelsrv', '7x24'] final_row = { } for (index, value) in enumerate(['name', 'type', 'component', 'version', 'patchlevel', 'host_name', 'check_period']): final_row[value] = [None if row[index] == "" else row[index]][0] a = coshsh.application.Application(final_row) #a.__init__(final_row) self.applications[a.fingerprint()] = a setattr(a, "host", self.hosts[a.host_name])
def init_class_cache(self): Datasource.init_classes(self.classes_path) logger.debug("init Datasource classes (%d)" % len(Datasource.class_factory)) Datarecipient.init_classes(self.classes_path) logger.debug("init Datarecipient classes (%d)" % len(Datarecipient.class_factory)) Application.init_classes(self.classes_path) logger.debug("init Application classes (%d)" % len(Application.class_factory)) MonitoringDetail.init_classes(self.classes_path) logger.debug("init MonitoringDetail classes (%d)" % len(MonitoringDetail.class_factory))
def test_mygeneric_app(self): self.print_header() self.generator.add_recipe(name='test34', **dict(self.config.items('recipe_test34'))) self.config.set("datasource_SIMPLESAMPLE", "name", "simplesample") cfg = self.config.items("datasource_SIMPLESAMPLE") self.generator.recipes['test34'].add_datasource(**dict(cfg)) self.generator.recipes['test34'].datasources[0].objects = self.generator.recipes['test34'].objects host = Host({ 'host_name': 'testhost', 'address': '127.0.0.1', }) self.generator.recipes['test34'].datasources[0].add('hosts', host) app = Application({ 'host_name': 'testhost', 'name': 'noname', 'type': 'arschknarsch', }) self.generator.recipes['test34'].datasources[0].add('applications', app) self.generator.recipes['test34'].datasources[0].add('details', MonitoringDetail({ 'host_name': 'testhost', 'name': 'noname', 'type': 'arschknarsch', 'monitoring_type': 'FILESYSTEM', 'monitoring_0': '/', 'monitoring_1': 90, 'monitoring_2': 95, })) self.generator.recipes['test34'].datasources[0].add('details', MonitoringDetail({ 'host_name': 'testhost', 'name': 'noname', 'type': 'arschknarsch', 'monitoring_type': 'PORT', 'monitoring_0': 80, 'monitoring_1': 1, 'monitoring_2': 5, })) self.generator.recipes['test34'].collect() self.generator.recipes['test34'].assemble() self.generator.recipes['test34'].render() self.assert_(len(self.generator.recipes['test34'].objects['applications']) == 1) self.assert_(self.generator.recipes['test34'].datasources[0].getall('applications')[0] == app) self.assert_(self.generator.recipes['test34'].datasources[0].getall('applications')[0].__class__.__name__ == "MyGenericApplication") self.generator.recipes['test34'].output() self.assert_(os.path.exists("var/objects/test33/dynamic/hosts/testhost/host.cfg")) self.assert_(os.path.exists("var/objects/test33/dynamic/hosts/testhost/app_my_generic_fs.cfg")) self.assert_(os.path.exists("var/objects/test33/dynamic/hosts/testhost/app_my_generic_ports.cfg"))
svcmib, ]) if hasattr(application, "agent_addresses"): for agent_address in application.agent_addresses: mobj.add_agent([ agent_address, application.host_name, application.trap_service_prefix, svcmib, ]) if trap_events: application.monitoring_details.append(MonitoringDetail({ 'host_name': application.host_name, 'application_name': application.name, 'application_type': application.type, 'monitoring_type': 'KEYVALUES', 'monitoring_0': 'trap_events', 'monitoring_1': trap_events, })) for mib in self.getall('mibconfigs'): mib.sort_agents() # An diesem Host werden die scan-Services fuer # var/log/snmp/traps.log festgemacht. trapdest = Host({ 'host_name': self.trapdest, 'address': '127.0.0.1', }) self.add('hosts', trapdest)
def read(self, filter=None, objects={}, force=False, **kwargs): self.pp = pprint.PrettyPrinter(indent=4) self.objects = objects if filter: for f in [filt.strip() for filt in filter.split(',')]: if f.startswith('trapdest='): self.trapdest = f.replace("trapdest=", "") mib_traps = {} # empty_mibs lists snmptt files without trap definitions empty_mibs = [] snmpttfiles = [ f for f in listdir(self.dir) if isfile(join(self.dir, f)) and f.endswith('.snmptt') ] eventname_pat = re.compile(r'^EVENT (.*) ([\.\d]+) .*?([\-\w]+)$') recovers_pat = re.compile(r'^RECOVERS (.*)$') eventtext_pat = re.compile(r'^FORMAT (.*)') match_pat = re.compile(r'^MATCH (\$.*)') matchmode_pat = re.compile(r'^MATCH MODE=(.*)') edesc_pat = re.compile(r'^EDESC') for ttfile in snmpttfiles: unsorted_traps = {} mib = ttfile.replace('.snmptt', '') logger.info("process snmptt file " + ttfile) last_eventname = None last_name = None last_matchmode = 'and' last_recovers = None # # Namenlose Events von 1.3.6.1.4.1.1981_ bekommen # EventName="EventMonitorTrapError" with open(os.path.join(self.dir, ttfile)) as f: for line in f.readlines(): eventname_m = eventname_pat.search(line) recovers_m = recovers_pat.search(line) eventtext_m = eventtext_pat.search(line) match_m = match_pat.search(line) matchmode_m = matchmode_pat.search(line) edesc_m = edesc_pat.search(line) if eventname_m: if last_eventname: # save the last event if there is one if last_match: last_match.append( last_eventtext ) # add the format of this match try: mib_traps[mib].append({ 'name': last_eventname, 'oid': last_oid, 'text': last_eventtext, 'recovers': last_recovers, 'match': last_match, 'nagioslevel': last_nagios, }) except Exception: mib_traps[mib] = [{ 'name': last_eventname, 'oid': last_oid, 'text': last_eventtext, 'recovers': last_recovers, 'match': last_match, 'nagioslevel': last_nagios, }] last_eventname = eventname_m.group(1).replace(' ', '') last_oid = eventname_m.group(2) last_severity = eventname_m.group(3).upper() try: last_nagios = { 'NORMAL': 0, # return to normal state, this is the default. # Yes, the default is OK! So immediately change this in your snmptt files # some Mibs have --#SEVERITY hints 'INFORMATIONAL': 0, 'INFO': 0, 'EVENT': 0, # many possible severities, you decide 'AUTHENTICATION': 0, # sucess or failed. you decide 'CONFIGURATION CHANGE': 0, # same here 'CHANGE': 0, # because only the last word matches 'MINOR': 1, 'MAJOR': 2, 'FATAL': 2, 'NON-RECOVERABLE': 2, # manually edited severities. The best you can do. 'OK': 0, 'WARNING': 1, 'CRITICAL': 2, 'UNKNOWN': 3, 'HIDDEN': -1, }[last_severity] except Exception as e: logger.debug('trap severity %s unknown' % eventname_m.group(3)) last_nagios = 2 last_eventtext = None last_match = None last_recovers = None elif eventtext_m: last_eventtext = eventtext_m.group(1).replace("'", '"') elif match_m: if last_match: last_match = [ last_nagios, last_matchmode, last_match[2] + '____' + match_m.group(1) ] else: last_match = [ last_nagios, last_matchmode, match_m.group(1) ] elif matchmode_m: last_matchmode = matchmode_m.group(1) elif recovers_m: last_recovers = recovers_m.group(1) if last_eventname: # save the last event if there is one try: mib_traps[mib].append({ 'name': last_eventname, 'oid': last_oid, 'text': last_eventtext, 'recovers': last_recovers, 'match': last_match, 'nagioslevel': last_nagios, }) except Exception: mib_traps[mib] = [{ 'name': last_eventname, 'oid': last_oid, 'text': last_eventtext, 'recovers': last_recovers, 'match': last_match, 'nagioslevel': last_nagios, }] try: logger.debug('mib %s counts %d traps' % (mib, len(mib_traps[mib]))) except Exception as e: logger.debug('mib %s counts 0 traps' % mib) empty_mibs.append(mib) for mib in mib_traps: m = MIB(mib=mib, miblabel=mib.replace('-', ''), extcmd=self.extcmd, events=[]) unique_names = {} for event in mib_traps[mib]: # search.name, search.oid, search.text try: unique_names[event['name']] += 1 except Exception: unique_names[event['name']] = 0 # Ueblich ist, mehrere Eintraege fuer einen Event in der # in der snmptt-Datei zu haben. Zuerst welche mit MATCH-Regeln # und zuletzt einer, der den Rest aufsammelt. # Das MIB-Objekt bekommt eine Liste von Events, wobei nicht # die EVENT-Abschnitte aus der snmptt-Datei 1:1 uebernommen werden. # Die zusammengehoerigen Abschnitte werden eingedampft, so dass # ein Event uebrigbleibt, der ggf. ein Attribut "matches" hat, # welches die genauer spezifizierten Sub-Events aufnimmt. # matches = {} for event in mib_traps[mib]: event['mib'] = mib if event['match']: try: matches[event['name']].append(event['match']) except Exception: matches[event['name']] = [event['match']] if unique_names[event['name']] == 0: if event['name'] in matches: # existiert genau einmal und zwar mit MATCH. pass m.events.append(event) # Jetzt haben wir: # - Events, die nur einmal vorkommen, sind in MIB.events # - Events mit einer MATCH-Regel sind in matches[eventname] for event in reversed(mib_traps[mib]): # Rueckwaerts, denn jetzt brauchen wir den Sammelevent bzw. dessen nagioslevel if unique_names[event['name']] > 0: unique_names[event['name']] = 0 event[ 'matches'] = [] if not event['name'] in matches else [ match for match in matches[event['name']] ] m.events.append(event) else: pass if event['recovers'] and event['recovers'] not in unique_names: logger.warning('%s tries to recover an unknown trap %s' % (event['name'], event['recovers'])) event['recovers'] = None # Jetzt haben wir: # - Events, die mehrfach vorkommen, sind auch in MIB.events # und haben ein Attribut "matches" mit den Sub-Events try: m.common_prefix = os.path.commonprefix([ event['oid'].replace('.', '\.').replace('*', '.*?') for event in m.events ]) except Exception as e: m.common_prefix = '.*' self.add('mibconfigs', m) # Eine Fake-MIB dient dazu, unbekannte Traps (welche nicht ueber # application.implemented_mibs identifiziert werden kann, an einen # Lumpensammlerservice weiterzuleiten ragpicker = RagpickerMIB(mib="RAGPICKER-MIB", miblabel="RAGPICKERMIB", extcmd=self.extcmd, events=[], unexpected_level=self.unexpected_level) self.add('mibconfigs', ragpicker) mib_traps["RAGPICKER-MIB"] = [] hosts_with_ragpicker_mib = {} hosts_with_known_oids = [] for host in self.getall('hosts'): if hasattr(host, 'implements_mibs' ) and "RAGPICKER-MIB" in host.implements_mibs: hosts_with_ragpicker_mib[host.address] = host.host_name for application in self.getall('applications'): # hier werden applikationen um ein hash mit mibs -> events # versorgt, welches in *traps.tpl die services erzeugt # # Details muessen resolved werden, denn es kann z.b. ein Detail bgp:True geben, welches # dazu fuehrt, dass in wemustrepeat noch eine Mib an implements_mibs angehaengt wird application.resolve_monitoring_details() if hasattr(application, 'implements_mibs'): logger.debug( "app %s implements %s" % (application.fingerprint(), application.implements_mibs)) if not hasattr(application, 'trap_service_prefix'): setattr(application, 'trap_service_prefix', str(application.__module__).split('.')[0]) # list of (alias for svcdesc, snmptt name) application_mibs = [ m.split(':') if ':' in m else (m, m) for m in application.implements_mibs ] application_mibs_unknown = [ m for m in application_mibs if m[1] not in mib_traps and m[1] not in empty_mibs ] application_mibs_known = [ m for m in application_mibs if m[1] in mib_traps and m[1] not in empty_mibs ] if application_mibs_unknown: logger.error('application %s implements unknown mibs %s' % (application.fingerprint(), ', '.join( [m[1] for m in application_mibs_unknown]))) # Bereinigen, so dass ggf. Aliase in der implements_mibs stehen. # In trap_events sind die tatsaechlichen Events aus der # Original-MIB application.implements_mibs = [ m[0] for m in application_mibs_known ] trap_events = {} address = self.get('hosts', application.host_name).address for svcmib, mib in application_mibs_known: mobj = self.get('mibconfigs', mib) trap_events[svcmib] = [e for e in mobj.events] mobj.add_agent([ address, application.host_name, application.trap_service_prefix, svcmib, ]) if hasattr(application, "agent_addresses"): for agent_address in application.agent_addresses: mobj.add_agent([ agent_address, application.host_name, application.trap_service_prefix, svcmib, ]) if trap_events: application.monitoring_details.append( MonitoringDetail({ 'host_name': application.host_name, 'application_name': application.name, 'application_type': application.type, 'monitoring_type': 'KEYVALUES', 'monitoring_0': 'trap_events', 'monitoring_1': trap_events, })) if "RAGPICKER-MIB" in application.implements_mibs: hosts_with_ragpicker_mib[address] = application.host_name if address in hosts_with_ragpicker_mib: # through an application setting in the line above # or through a host setting before the app loop for mib in trap_events: for event in trap_events[mib]: ragpicker.add_ip_oid_combi(address, event["oid"]) if hasattr(application, "agent_addresses"): for agent_address in application.agent_addresses: ragpicker.add_ip_oid_combi( agent_address, event["oid"]) for address, host_name in list(hosts_with_ragpicker_mib.items()): ragpicker.add_agent([ address, host_name, "app_snmp_agent", "RAGPICKER-MIB", ]) # this app renders a tpl with a ragpicker service snmp_agent_for_unexpected_traps = Application({ 'host_name': host_name, 'name': 'app_snmp_agent', 'type': 'snmp_agent_for_unexpected_traps', }) self.add('applications', snmp_agent_for_unexpected_traps) ragpicker.sort_ip_oid_combis() for mib in self.getall('mibconfigs'): mib.sort_agents() # An diesem Host werden die scan-Services fuer # var/log/snmp/traps.log festgemacht. trapdest = Host({ 'host_name': self.trapdest, 'address': '127.0.0.1', }) self.add('hosts', trapdest) trapdest.templates.append('generic-host') # Die Applikation snmptrapdlog bekommt einen Service pro Mib. snmptrapdlog = Application({ 'host_name': self.trapdest, 'name': 'snmptrapdlog', 'type': 'snmptrapdlog', }) self.add('applications', snmptrapdlog) snmptrapdlog.monitoring_details.append( MonitoringDetail({ 'host_name': self.trapdest, 'name': 'snmptrapdlog', 'type': 'snmptrapdlog', 'monitoring_type': 'KEYVALUES', 'monitoring_0': 'mibs', 'monitoring_1': list(mib_traps.keys()), }))