def api_json(self, request, id): event = get_event(id) if not event: self.response_not_found() # Get event class e_class = None if event.status in ("A", "S"): for l in event.log: match = self.rx_parse_log.match(l.message) if match: e_class = match.group(1) r = ["["] r += [" {"] r += [' "profile": "%s",' % json_escape(event.managed_object.profile.name)] if e_class: r += [' "event_class__name": "%s",' % e_class] r += [' "raw_vars": {'] rr = [] for k in event.raw_vars: if k in ("collector", "severity", "facility"): continue rr += [' "%s": "%s"' % (json_escape(k), json_escape(str(event.raw_vars[k])))] r += [",\n".join(rr)] r += [" }"] r += [" }"] r += ["]"] return "\n".join(r)
def api_from_event(self, request, event_id): """ Create classification rule from event :param request: :param event_id: :return: """ event = get_event(event_id) if not event: self.response_not_found() event_name = " | ".join( event.managed_object.profile.name.split(".")) + " | <name> " if event.source == "syslog": event_name += "(SYSLOG)" elif event.source == "SNMP Trap": event_name += "(SNMP)" data = {"name": event_name, "preference": 1000} if event.source == "syslog": data["description"] = event.raw_vars["message"] elif event.source == "SNMP Trap" and "SNMPv2-MIB::snmpTrapOID.0" in event.resolved_vars: data["description"] = event.resolved_vars[ "SNMPv2-MIB::snmpTrapOID.0"] patterns = {"source": event.source} for k in event.raw_vars: if k not in ("collector", "facility", "severity"): patterns[k] = event.raw_vars[k] if hasattr(event, "resolved_vars"): for k in event.resolved_vars: if k not in self.IGNORED_OIDS and not is_oid(k): patterns[k] = event.resolved_vars[k] data["patterns"] = [{ "key_re": "^%s$" % k, "value_re": "^%s$" % patterns[k] } for k in patterns] return data
def api_reclassify(self, request, id): event = get_event(id) if not event: self.response_not_found() if event.status == "N": return False event.mark_as_new("Event reclassification has been requested " "by user %s" % request.user.username) return True
def api_from_event(self, request, event_id): """ Create ignore pattern rule from event :param request: :param event_id: :return: """ event = get_event(event_id) if not event: self.response_not_found() data = {"is_active": True} if event.source == "syslog": data["description"] = event.raw_vars["message"] data["source"] = "syslog" elif event.source == "SNMP Trap" and "SNMPv2-MIB::snmpTrapOID.0" in event.resolved_vars: data["description"] = event.resolved_vars["SNMPv2-MIB::snmpTrapOID.0"] data["source"] = "SNMP Trap" if "message" in event.raw_vars: data["pattern"] = event.raw_vars["message"] return data
def api_json(self, request, id): event = get_event(id) if not event: self.response_not_found() # Get event class e_class = None if event.status in ("A", "S"): for ll in event.log: match = self.rx_parse_log.match(ll.message) if match: e_class = match.group(1) r = {"profile": event.managed_object.profile.name} if e_class: r["event_class__name"] = "%s" % e_class r["raw_vars"] = { json_escape(k): json_escape(str(event.raw_vars[k])) for k in event.raw_vars if k not in {"collector", "severity", "facility"} } if event.source: r["raw_vars"]["source"] = event.source return smart_text(orjson.dumps(r, option=orjson.OPT_INDENT_2))
def api_post(self, request, id, msg): event = get_event(id) if not event: self.response_not_found() event.log_message("%s: %s" % (request.user.username, msg)) return True
def api_event(self, request, id): event = get_event(id) if not event: return self.response_not_found() d = self.instance_to_dict(event) dd = dict( (v, None) for v in ( "body", "symptoms", "probable_causes", "recommended_actions", "log", "vars", "resolved_vars", "raw_vars", ) ) if event.status in ("A", "S"): dd["body"] = event.body dd["symptoms"] = event.event_class.symptoms dd["probable_causes"] = event.event_class.probable_causes dd["recommended_actions"] = event.event_class.recommended_actions # Fill vars left = set(event.vars) vars = [] for ev in event.event_class.vars: if ev.name in event.vars: vars += [(ev.name, event.vars[ev.name], ev.description)] left.remove(ev.name) vars += [(v, event.vars[v], None) for v in sorted(left)] dd["vars"] = vars # Fill resolved vars vars = [] is_trap = event.raw_vars.get("source") == "SNMP Trap" for v in sorted(event.resolved_vars): desc = None if is_trap and "::" in v: desc = MIB.get_description(v) vars += [(v, event.resolved_vars[v], desc)] dd["resolved_vars"] = vars dd["raw_vars"] = sorted(event.raw_vars.items()) # Managed object properties mo = event.managed_object d["managed_object_address"] = mo.address d["managed_object_profile"] = mo.profile.name d["managed_object_platform"] = mo.platform.name if mo.platform else "" d["managed_object_version"] = mo.version.version if mo.version else "" d["segment"] = mo.segment.name d["segment_id"] = str(mo.segment.id) d["tags"] = mo.tags # Log if event.log: dd["log"] = [ { "timestamp": self.to_json(l.timestamp), "from_status": l.from_status, "to_status": l.to_status, "message": l.message, } for l in event.log ] # d.update(dd) # Get alarms if event.status in ("A", "S"): alarms = [] for a_id in event.alarms: a = get_alarm(a_id) if not a: continue if a.opening_event == event.id: role = "O" elif a.closing_event == event.id: role = "C" else: role = "" alarms += [ { "id": str(a.id), "status": a.status, "alarm_class": str(a.alarm_class.id), "alarm_class__label": a.alarm_class.name, "subject": a.subject, "role": role, "timestamp": self.to_json(a.timestamp), } ] d["alarms"] = alarms # Apply plugins if event.status in ("A", "S") and event.event_class.plugins: plugins = [] for p in event.event_class.plugins: if p.name in self.plugins: plugin = self.plugins[p.name] dd = plugin.get_data(event, p.config) if "plugins" in dd: plugins += dd["plugins"] del dd["plugins"] d.update(dd) if plugins: d["plugins"] = plugins elif event.status == "F": # Enable traceback plugin for failed events d["traceback"] = event.traceback d["plugins"] = [("NOC.fm.event.plugins.Traceback", {})] return d
def api_test(self, request): q = self.deserialize(request.raw_post_data) errors = [] patterns = [] result = False # Get data data = {} vars = {} required_vars = set() r_patterns = [] event_class = None subject = None body = None if "data" in q: if is_objectid(q["data"]): event = get_event(q["data"]) if event: data = event.raw_vars.copy() data["profile"] = event.managed_object.profile.name data["source"] = event.source else: errors += ["Event not found: %s" % q["data"]] else: # Decode json try: e = self.deserialize(q["data"]) except Exception: errors += ["Cannot decode JSON"] e = None if isinstance(e, list): e = e[0] if not isinstance(e, dict) or "raw_vars" not in e: errors += ["Invalid JSON data"] else: data = e["raw_vars"] if "profile" in e: data["profile"] = e["profile"] if "source" in e: data["source"] = e["source"] if data.get("source") == "SNMP Trap": # Resolve MIBs data.update(MIB.resolve_vars(data)) # Check event class if "event_class" in q: event_class = self.get_object_or_404(EventClass, id=q["event_class"]) for v in event_class.vars: if v.required: required_vars.add(v.name) vars[v.name] = "MISSED!" # Check patterns if "patterns" in q: for p in q["patterns"]: if "key_re" in p and "value_re" in p: k = None v = None try: k = re.compile(p["key_re"]) except re.error as why: errors += [ "Invalid key regular expression <<<%s>>>: %s" % (p["key_re"], why) ] try: v = re.compile(p["value_re"]) except re.error as why: errors += [ "Invalid value regular expression <<<%s>>>: %s" % (p["value_re"], why) ] if k and v: patterns += [(k, v)] # Try to match rule if patterns and not errors: s_patterns = [] i_patterns = [] for pkey, pvalue in patterns: matched = False for k in data: k_match = pkey.search(k) if k_match: v_match = pvalue.search(data[k]) if v_match: # Line match # Update vars v = {} v.update(k_match.groupdict()) v.update(v_match.groupdict()) vars.update(v) # Save patterns s_patterns += [{ "status": True, "key": k, "value": data[k], "key_re": pkey.pattern, "value_re": pvalue.pattern, "vars": [{ "key": k, "value": v[k] } for k in v] }] else: i_patterns += [{ "status": False, "key": k, "value": data[k], "key_re": pkey.pattern, "value_re": pvalue.pattern, "vars": {} }] matched = True break if not matched: i_patterns += [{ "status": False, "key": None, "value": None, "key_re": pkey.pattern, "value_re": pvalue.pattern, "vars": {} }] if s_patterns and not i_patterns: result = True r_patterns = s_patterns + i_patterns # Calculate rule variables if "vars" in q and q["vars"]: for v in q["vars"]: if v["value"].startswith("="): # Evaluate try: vars[v["name"]] = eval(v["value"][1:], {}, vars) except Exception as why: errors += [ "Error when evaluating '%s': %s" % (v["name"], why) ] else: vars[v["name"]] = v["value"] # Check required variables for rvars in required_vars: if rvars not in vars: errors += ["Missed required variable: %s" % rvars] # Fill event class template if event_class: # lang = "en" ctx = Context(vars) subject = Template(event_class.subject_template).render(ctx) body = Template(event_class.body_template).render(ctx) # Check expression r = {"result": result} if errors: r["errors"] = errors if vars: r["vars"] = [{"key": k, "value": vars[k]} for k in vars] if r_patterns: r["patterns"] = r_patterns if subject: r["subject"] = subject if body: r["body"] = body return r