Example #1
0
File: mrt.py Project: gabrielat/noc
 def run_script(self, oid, script, args, span_id=0, bi_id=None):
     with Span(
         server="MRT",
         service="run_script",
         sample=int(config.mrt.enable_command_logging),
         in_label=bi_id or oid,
         parent=span_id,
         client=self.current_user,
     ) as span:
         try:
             yield self.write_chunk({"id": str(oid), "running": True})
             logger.debug("[%s] Run script %s %s %s", span.context, oid, script, args)
             r = yield self.service.sae.script(oid, script, args)
             metrics["mrt_success"] += 1
         except RPCRemoteError as e:
             span.error_code = getattr(e, "remote_code", 1)
             span.error_text = str(e)
             raise tornado.gen.Return({"id": str(oid), "error": str(e)})
         except RPCError as e:
             logger.error("RPC Error: %s" % str(e))
             span.error_code = getattr(e, "code", 1)
             span.error_text = str(e)
             raise tornado.gen.Return({"id": str(oid), "error": str(e)})
         except Exception as e:
             error_report()
             metrics["mrt_failed"] += 1
             span.error_code = 1
             span.error_text = str(e)
             raise tornado.gen.Return({"id": str(oid), "error": str(e)})
         if r["errors"]:
             span.error_code = 1
             span.error_text = r["output"]
             raise tornado.gen.Return({"id": str(oid), "error": r["output"]})
         span.out_label = r["output"]
         raise tornado.gen.Return({"id": str(oid), "result": r["output"]})
Example #2
0
 def handle(self, *args, **options):
     #
     parsers = []
     # Read config
     config = SafeConfigParser()
     for p in self.get_parsers():
         config.read(os.path.join("etc", "address", "%s.defaults" % p))
         config.read(os.path.join("etc", "address", "%s.conf" % p))
         if config.getboolean(p, "enabled"):
             m = __import__("noc.gis.parsers.address.%s" % p, {}, {}, "*")
             for l in dir(m):
                 a = getattr(m, l)
                 if inspect.isclass(a) and issubclass(
                         a, AddressParser) and a != AddressParser:
                     parsers += [a]
         else:
             print("Parser '%s' is not enabled. Skipping.." % p)
     # Initialize parsers
     parsers = [p(config, options) for p in parsers]
     # Download
     if options["download"]:
         for p in parsers:
             print("Downloading", p.name)
             if not p.download():
                 raise CommandError("Failed to download %s" % p.name)
     else:
         print("Skipping downloads")
     # Sync
     try:
         for p in parsers:
             print("Syncing", p.name)
             p.sync()
     except Exception:
         error_report()
Example #3
0
    def handle(self, *args, **options):
        if len(args) < 1:
            print("USAGE: %s <model> <object id> [.. <object id>]" %
                  sys.argv[0])
            sys.exit(1)
        m = args[0].replace("-", "_")
        connect()
        if m not in self.models:
            raise CommandError("Invalid model '%s'. Valid models are: %s" %
                               (m, ", ".join(self.models)))
        objects = []
        getter = getattr(self, "get_%s" % m)
        wiper = getattr(self, "wipe_%s" % m)
        # Get objects
        for o_id in args[1:]:
            o = getter(o_id)
            if not o:  # Not found
                raise CommandError("Object '%s' is not found" % o_id)
            objects += [o]
        # Wipe objects
        from noc.core.debug import error_report

        with bulk_datastream_changes():
            for o in objects:
                with self.log("Wiping '%s':" % unicode(o), True):
                    try:
                        wiper(o)
                    except KeyboardInterrupt:
                        raise CommandError(
                            "Interrupted. Wiping is not complete")
                    except Exception:
                        error_report()
Example #4
0
 def call_event_handlers(self, event):
     """
     Call handlers associated with event class
     :param event:
     :return:
     """
     if event.event_class.id not in self.handlers:
         return False
     event_id = event.id  # Temporary store id
     for h in self.handlers[event.event_class.id]:
         try:
             h(event)
         except Exception:
             error_report()
         if event.to_drop:
             self.logger.info(
                 "[%s|%s|%s] Dropped by handler",
                 event.id,
                 event.managed_object.name,
                 event.managed_object.address,
             )
             event.id = event_id  # Restore event id
             event.delete()
             metrics[CR_DELETED] += 1
             return True
     return False
Example #5
0
 async def error_handler(self, request, exc) -> Response:
     """
     Error handler for ServerErrorMiddleware
     :return:
     """
     error_report(logger=self.logger)
     return PlainTextResponse("Internal Server Error", status_code=500)
Example #6
0
 def call_event_triggers(self, event):
     """
     Call triggers associated with event class
     :param event:
     :return:
     """
     if event.event_class.id not in self.triggers:
         return False
     event_id = event.id
     for t in self.triggers[event.event_class.id]:
         try:
             t.call(event)
         except Exception:
             error_report()
         if event.to_drop:
             # Delete event and stop processing
             self.logger.info(
                 "[%s|%s|%s] Dropped by trigger %s",
                 event_id,
                 event.managed_object.name,
                 event.managed_object.address,
                 t.name,
             )
             event.id = event_id  # Restore event id
             event.delete()
             metrics[CR_DELETED] += 1
             return True
     else:
         return False
Example #7
0
 def call(self, event):
     if not self.match(event):
         return
     logging.debug("Calling trigger '%s'" % self.name)
     # Notify if necessary
     if self.notification_group and self.template:
         subject = {}
         body = {}
         for lang in self.notification_group.languages:
             s = event.subject
             b = event.body
             subject[lang] = self.template.render_subject(LANG=lang,
                                                          event=event,
                                                          subject=s,
                                                          body=b)
             body[lang] = self.template.render_body(LANG=lang,
                                                    event=event,
                                                    subject=s,
                                                    body=b)
         self.notification_group.notify(subject=subject, body=body)
     # Call Handler
     if self.handler:
         try:
             self.handler(event)
         except Exception:
             error_report()
Example #8
0
 def start(self):
     """
     Run main server loop
     """
     parser = self.create_parser()
     self.add_arguments(parser)
     options = parser.parse_args(sys.argv[1:])
     cmd_options = vars(options)
     args = cmd_options.pop("args", ())
     # Bootstrap logging with --loglevel
     self.setup_logging(cmd_options["loglevel"])
     self.log_separator()
     # Setup timezone
     try:
         self.logger.info("Setting timezone to %s", config.timezone)
         setup_timezone()
     except ValueError as e:
         self.die(str(e))
     # Setup title
     self.set_proc_title()
     # Setup signal handlers
     self.setup_signal_handlers()
     self.on_start()
     # Starting IOLoop
     self.is_active = True
     if self.pooled:
         self.logger.warn(
             "Running service %s (pool: %s)",
             self.name, config.pool
         )
     else:
         self.logger.warn(
             "Running service %s", self.name
         )
     try:
         if config.features.use_uvlib:
             from tornaduv import UVLoop
             self.logger.warn("Using libuv")
             tornado.ioloop.IOLoop.configure(UVLoop)
         self.ioloop = tornado.ioloop.IOLoop.instance()
         # Initialize DCS
         self.dcs = get_dcs(cmd_options["dcs"], self.ioloop)
         # Activate service
         self.ioloop.add_callback(self.activate)
         self.logger.warn("Starting IOLoop")
         self.ioloop.start()
     except KeyboardInterrupt:
         self.logger.warn("Interrupted by Ctrl+C")
     except self.RegistrationError:
         self.logger.info("Registration failed")
     except Exception:
         error_report()
     finally:
         if self.ioloop:
             self.ioloop.add_callback(self.deactivate())
     for cb, args, kwargs in self.close_callbacks:
         cb(*args, **kwargs)
     self.logger.warn("Service %s has been terminated", self.name)
Example #9
0
    def run_from_argv(self, argv):
        """
        Execute command. Usually from script

        if __name__ == "__main__":
            import sys
            sys.exit(Command.run_from_argv())
        """
        parser = self.create_parser()
        self.add_default_arguments(parser)
        self.add_arguments(parser)
        options = parser.parse_args(argv)
        cmd_options = vars(options)
        args = cmd_options.pop("args", ())
        loglevel = cmd_options.pop("loglevel")
        if loglevel:
            self.setup_logging(loglevel)
        enable_profiling = cmd_options.pop("enable_profiling", False)
        show_metrics = cmd_options.pop("show_metrics", False)
        if enable_profiling:
            # Start profiler
            import yappi
            yappi.start()
        try:
            return self.handle(*args, **cmd_options) or 0
        except CommandError as e:
            self.print(str(e))
            return 1
        except KeyboardInterrupt:
            self.print("Ctrl+C")
            return 3
        except AssertionError as e:
            if e.args and e.args[0]:
                self.print("ERROR: %s" % e.args[0])
            else:
                self.print("Assertion error: %s" % e)
            return 4
        except Exception:
            from noc.core.debug import error_report
            error_report()
            return 2
        finally:
            if enable_profiling:
                i = yappi.get_func_stats()
                i.print_all(out=self.stdout,
                            columns={
                                0: ("name", 80),
                                1: ("ncall", 10),
                                2: ("tsub", 8),
                                3: ("ttot", 8),
                                4: ("tavg", 8)
                            })
            if show_metrics:
                from noc.core.perf import apply_metrics
                d = apply_metrics({})
                self.print("Internal metrics:")
                for k in d:
                    self.print("%40s : %s" % (k, d[k]))
Example #10
0
 def handle(self, *args, **options):
     try:
         self._handle(*args, **options)
     except CommandError as why:
         raise CommandError(why)
     except SystemExit:
         pass
     except Exception:
         error_report()
Example #11
0
 def _check(self):
     """
     Perform object configuration check
     """
     self.logger.info("Checking %s", self.object)
     parser = self.object.get_parser()
     self.config = self.object.config.read()
     if not self.config:
         self.logger.error("No config for %s. Giving up", self.object)
         return
     # Parse facts
     self.logger.debug("Parsing facts")
     facts = list(parser.parse(self.config))
     self.logger.debug("%d facts are extracted", len(facts))
     self.interface_ranges = parser.interface_ranges
     self.logger.debug("%d interface sections detected",
                       len(self.interface_ranges))
     # Define default templates
     self.get_template(Error(None))
     self.get_template(Role(None))
     # Learn facts
     self.logger.debug("Learning facts")
     self.learn(facts)
     self.logger.debug("Learning complete")
     # Install rules
     rules = []
     for r in self.get_rules():
         if r.is_applicable():
             self.logger.debug("Using validation rule: %s", r.rule.name)
             try:
                 cfg = r.get_config()
                 r.prepare(**cfg)
             except clips.ClipsError as e:
                 self.logger.error("CLIPS Error: %s\n%s", e,
                                   clips.ErrorStream.Read())
                 continue
             except Exception:
                 error_report()
                 continue
             rules += [(r, cfg)]
     # Run python validators
     for r, cfg in rules:
         r.check(**cfg)
     # Run CLIPS engine
     while True:
         self.logger.debug("Running engine")
         n = self.run()
         self.logger.debug("%d rules matched", n)
         break  # @todo: Check for commands
     # Extract errors
     for e in self.iter_errors():
         self.logger.info("Error found: %s", e)
     # Store object's facts
     self.sync_facts()
     # Manage related alarms
     if self.AC_POLICY_VIOLATION:
         self.sync_alarms()
Example #12
0
 def run_round(self):
     self.logger.info("Running checks")
     now = time.time()
     for c in self.collectors:
         if not c.can_run_at(now):
             break  # Done
         with Span(sample=PARENT_SAMPLE, server="selfmon", service=c.name):
             try:
                 c.run()
             except Exception:
                 error_report()
         c.schedule_next()
     self.reorder()
Example #13
0
 def dispose_worker(self, message, event_id, event_hint=None):
     metrics["alarm_dispose"] += 1
     try:
         if event_hint:
             event = self.get_event_from_hint(event_hint)
         else:
             event = self.lookup_event(event_id)
         if event:
             self.dispose_event(event)
     except Exception:
         metrics["alarm_dispose_error"] += 1
         error_report()
     self.ioloop.add_callback(message.finish)
Example #14
0
 def run(self):
     if not self.is_enabled():
         self.logger.info("Check is disabled. Skipping")
         return
     if self.has_fatal_error():
         self.logger.info(
             "Check is disabled due to previous fatal error. Skipping")
         return
     if not self.has_required_artefacts():
         return
     with Span(server="discovery",
               service=self.name) as span, self.job.check_timer(self.name):
         # Check required scripts
         if not self.has_required_script():
             self.logger.info("%s script is not supported. Skipping",
                              self.required_script)
             return
         # Check required capabilities
         if not self.has_required_capabilities():
             return
         # Run check
         try:
             self.handler()
         except RPCRemoteError as e:
             self.logger.error("RPC Remote error (%s): %s", e.remote_code,
                               e)
             if e.remote_code:
                 message = "Remote error code %s" % e.remote_code
             else:
                 message = "Remote error code %s, message: %s" % (
                     e.remote_code, e)
             self.set_problem(alarm_class=self.error_map.get(e.remote_code),
                              message=message,
                              fatal=e.remote_code in self.fatal_errors)
             span.error_code = e.remote_code
             span.error_text = str(e)
         except RPCError as e:
             self.set_problem(alarm_class=self.error_map.get(
                 e.default_code),
                              message="RPC Error: %s" % e,
                              fatal=e.default_code in self.fatal_errors)
             self.logger.error("Terminated due RPC error: %s", e)
             span.error_code = e.default_code
             span.error_text = str(e)
         except Exception as e:
             self.set_problem(
                 alarm_class="Discovery | Error | Unhandled Exception",
                 message="Unhandled exception: %s" % e)
             error_report(logger=self.logger)
             span.error_code = ERR_UNKNOWN
             span.error_text = str(e)
Example #15
0
File: card.py Project: nbashev/noc
    def get(self, card_type, card_id, *args, **kwargs):
        if not self.current_user:
            raise tornado.web.HTTPError(404, "Not found")
        is_ajax = card_id == "ajax"
        tpl = self.CARDS.get(card_type)
        if not tpl:
            raise tornado.web.HTTPError(404, "Card template not found")
        try:
            card = tpl(self, card_id)
            if is_ajax:
                data = card.get_ajax_data()
            else:
                data = card.render()
        except BaseCard.RedirectError as e:
            return self.redirect(e.args[0])
        except BaseCard.NotFoundError:
            raise tornado.web.HTTPError(404, "Not found")
        except Exception:
            error_report()
            raise tornado.web.HTTPError(500, "Internal server error")
        if not data:
            raise tornado.web.HTTPError(404, "Not found")
        self.set_header("Cache-Control", "no-cache, must-revalidate")
        if is_ajax:
            self.set_header("Content-Type", "text/json")
            self.write(
                orjson.dumps(data,
                             option=orjson.OPT_SERIALIZE_NUMPY
                             | orjson.OPT_NON_STR_KEYS))
        else:
            self.set_header("Content-Type", "text/html; charset=utf-8")
            refresh = self.get_argument("refresh", None)
            if refresh:
                try:
                    refresh = int(refresh)
                    self.set_header("Refresh", str(refresh))
                except ValueError:
                    pass

            self.write(self.get_card_template().render({
                "card_data":
                data,
                "card_title":
                str(card.object),
                "hashed":
                self.hashed,
                "card_js":
                card.card_js,
                "card_css":
                card.card_css,
            }))
Example #16
0
 def start(self):
     """
     Run main server loop
     """
     self.startup_ts = perf_counter()
     parser = self.create_parser()
     self.add_arguments(parser)
     options = parser.parse_args(sys.argv[1:])
     cmd_options = vars(options)
     cmd_options.pop("args", ())
     # Bootstrap logging with --loglevel
     self.setup_logging(cmd_options["loglevel"])
     self.log_separator()
     # Setup timezone
     try:
         self.logger.info("Setting timezone to %s", config.timezone)
         setup_timezone()
     except ValueError as e:
         self.die(str(e))
     # Setup title
     self.set_proc_title()
     # Setup signal handlers
     self.setup_signal_handlers()
     self.on_start()
     # Starting IOLoop
     self.is_active = True
     if self.pooled:
         self.logger.warning("Running service %s (pool: %s)", self.name,
                             config.pool)
     else:
         self.logger.warning("Running service %s", self.name)
     try:
         setup_asyncio()
         self.loop = asyncio.get_event_loop()
         # Initialize DCS
         self.dcs = get_dcs(cmd_options["dcs"])
         # Activate service
         self.loop.create_task(self.activate())
         self.logger.warning("Starting IOLoop")
         self.loop.run_forever()
     except KeyboardInterrupt:
         self.logger.warning("Interrupted by Ctrl+C")
     except self.RegistrationError:
         self.logger.info("Registration failed")
     except Exception:
         error_report()
     finally:
         if self.loop:
             self.loop.create_task(self.deactivate())
     self.logger.warning("Service %s has been terminated", self.name)
Example #17
0
 def on_complete(f):
     logger.debug("Completion slow operation %s", so.id)
     if f.exception():
         so.status = cls.STATUS_FAILED
         try:
             f.result()
         except Exception:
             error_report()
         so.pickled_result = dumps(f.exception(), HIGHEST_PROTOCOL)
     else:
         so.status = cls.STATUS_COMPLETE
         so.pickled_result = dumps(f.result(), HIGHEST_PROTOCOL)
     so.duration = time.time() - t0
     so.save()
Example #18
0
 def load(self, extractors=None):
     extractors = extractors or self.get_extractors()
     error = None
     try:
         self.get_handler().load(extractors)
     except Exception as e:
         error_report()
         error = str(e)
     self.last_load = datetime.datetime.now()
     if error:
         self.load_error = error
     else:
         self.last_successful_load = self.last_load
     self.save()
Example #19
0
 def extract(self, extractors=None, quiet=False):
     extractors = extractors or self.get_extractors()
     error = None
     try:
         self.get_handler().extract(extractors)
     except Exception as e:
         if not quiet:
             raise e
         error_report()
         error = str(e)
     self.last_extract = datetime.datetime.now()
     if not error:
         self.last_successful_extract = self.last_extract
     self.extract_error = error
     self.save()
Example #20
0
 def send_reports(cls):
     """
     Calculate and send all reports for today
     :return:
     """
     subscriptions = list(ReportSubscription.objects.filter(is_active=True))
     for s in subscriptions:
         if s.can_run():
             try:
                 path = s.build_report()
             except Exception:
                 path = None
                 error_report()
             s.update_status(bool(path))
             if path and s.notification_group:
                 s.send_report(path)
Example #21
0
 def correlate(self, r, a):
     # Topology RCA
     if a.alarm_class.topology_rca:
         with self.topology_rca_lock:
             self.topology_rca(a)
     # Rule-based RCA
     with self.rca_lock:
         if a.alarm_class.id in self.rca_forward:
             # Check alarm is a consequence of existing one
             self.set_root_cause(a)
         if a.alarm_class.id in self.rca_reverse:
             # Check alarm is the root cause for existing ones
             self.set_reverse_root_cause(a)
     # Call handlers
     for h in a.alarm_class.get_handlers():
         try:
             has_root = bool(a.root)
             h(a)
             if not has_root and a.root:
                 self.logger.info(
                     "[%s|%s|%s] Set root to %s (handler %s)",
                     a.id,
                     a.managed_object.name,
                     a.managed_object.address,
                     a.root,
                     h,
                 )
         except:  # noqa. Can probable happens anything from handler
             error_report()
             metrics["error", ("type", "alarm_handler")] += 1
     # Call triggers if necessary
     if r.alarm_class.id in self.triggers:
         for t in self.triggers[r.alarm_class.id]:
             try:
                 t.call(a)
             except:  # noqa. Can probable happens anything from trigger
                 error_report()
     #
     if not a.severity:
         # Alarm severity has been reset to 0 by handlers
         # Silently drop alarm
         self.logger.debug("Alarm severity is 0, dropping")
         a.delete()
         metrics["alarm_drop"] += 1
         return
Example #22
0
 async def on_dispose_event(self, msg: Message) -> None:
     """
     Called on new dispose message
     """
     data = orjson.loads(msg.value)
     event_id = data["event_id"]
     hint = data["event"]
     self.logger.info("[%s] Receiving message", event_id)
     metrics["alarm_dispose"] += 1
     try:
         event = ActiveEvent.from_json(hint)
         event.timestamp = event.timestamp.replace(tzinfo=None)
         await self.dispose_event(event)
     except Exception:
         metrics["alarm_dispose_error"] += 1
         error_report()
     finally:
         if self.topo_rca_lock:
             # Release pending RCA Lock
             await self.topo_rca_lock.release()
             self.topo_rca_lock = None
Example #23
0
 def get_diag(alarm, cfg, state):
     mo = alarm.managed_object
     if not mo:
         return
     result = []
     for c in cfg:
         if c.get("header"):
             result += [c["header"].strip()]
         if "script" in c:
             logger.info("[%s] Running script %s", alarm.id, c["script"])
             try:
                 g = getattr(mo.scripts, c["script"])
                 result += [g()]
             except Exception as e:
                 error_report()
                 result += [str(e)]
         if "action" in c:
             logger.info("[%s] Running action %s", alarm.id, c["action"])
             try:
                 g = getattr(mo.actions, c["action"])
                 result += [g()]
             except Exception as e:
                 error_report()
                 result += [str(e)]
         if "handler" in c:
             logger.info("[%s] Running handler %s", alarm.id, c["handler"])
             try:
                 h = get_handler(c["handler"])
                 try:
                     result += [h(alarm)]
                 except Exception as e:
                     error_report()
                     result += [str(e)]
             except ImportError:
                 result += ["Invalid handler: %s" % c["handler"]]
     if result:
         AlarmDiagnostic.save_diagnostics(alarm, result, state)
Example #24
0
File: job.py Project: skripkar/noc
    def run(self):
        with Span(server=self.scheduler.name,
                  service=self.attrs[self.ATTR_CLASS],
                  sample=self.attrs.get(self.ATTR_SAMPLE, 0),
                  in_label=self.attrs.get(self.ATTR_KEY, "")):
            self.start_time = perf_counter()
            if self.is_retries_exceeded():
                self.logger.info("[%s|%s] Retries exceeded. Remove job",
                                 self.name, self.attrs[Job.ATTR_ID])
                self.remove_job()
                return
            self.logger.info(
                "[%s] Starting at %s (Lag %.2fms)", self.name,
                self.scheduler.scheduler_id,
                total_seconds(datetime.datetime.now() -
                              self.attrs[self.ATTR_TS]) * 1000.0)
            # Run handler
            status = self.E_EXCEPTION
            delay = None
            with Span(service="job.dereference"):
                try:
                    ds = self.dereference()
                    can_run = self.can_run()
                except Exception as e:
                    self.logger.error("Unknown error during dereference: %s",
                                      e)
                    ds = None
                    can_run = False

            if ds:
                with Span(service="job.run"):
                    if can_run:
                        try:
                            data = self.attrs.get(self.ATTR_DATA) or {}
                            result = self.handler(**data)
                            if tornado.gen.is_future(result):
                                # Wait for future
                                result = yield result
                            status = self.E_SUCCESS
                        except RetryAfter as e:
                            self.logger.info("Retry after %ss: %s", e.delay, e)
                            status = self.E_RETRY
                            delay = e.delay
                        except self.failed_exceptions:
                            status = self.E_FAILED
                        except Exception:
                            error_report()
                            status = self.E_EXCEPTION
                    else:
                        self.logger.info("Deferred")
                        status = self.E_DEFERRED
            elif ds is not None:
                self.logger.info("Cannot dereference")
                status = self.E_DEREFERENCE
            self.duration = perf_counter() - self.start_time
            self.logger.info("Completed. Status: %s (%.2fms)",
                             self.STATUS_MAP.get(status, status),
                             self.duration * 1000)
            # Schedule next run
            if delay is None:
                with Span(service="job.schedule_next"):
                    self.schedule_next(status)
            else:
                with Span(service="job.schedule_retry"):
                    # Retry
                    if self.context_version:
                        ctx = self.context or None
                        ctx_key = self.get_context_cache_key()
                    else:
                        ctx = None
                        ctx_key = None
                    self.scheduler.set_next_run(
                        self.attrs[self.ATTR_ID],
                        status=status,
                        ts=datetime.datetime.now() +
                        datetime.timedelta(seconds=delay),
                        duration=self.duration,
                        context_version=self.context_version,
                        context=ctx,
                        context_key=ctx_key)
Example #25
0
 def clear_alarm(self, message, ts=None, force=False):
     """
     Clear alarm
     :param message: Log clearing message
     :param ts: Clearing timestamp
     :param force: Clear ever if wait_tt seg
     """
     ts = ts or datetime.datetime.now()
     if self.wait_tt and not force:
         # Wait for escalated tt to close
         if not self.wait_ts:
             self.wait_ts = ts
             self.log_message("Waiting for TT to close")
             call_later(
                 "noc.services.escalator.wait_tt.wait_tt",
                 scheduler="escalator",
                 pool=self.managed_object.escalator_shard,
                 alarm_id=self.id
             )
         return
     if self.alarm_class.clear_handlers:
         # Process clear handlers
         for h in self.alarm_class.get_clear_handlers():
             try:
                 h(self)
             except Exception:
                 error_report()
     log = self.log + [AlarmLog(timestamp=ts, from_status="A",
                                to_status="C", message=message)]
     a = ArchivedAlarm(
         id=self.id,
         timestamp=self.timestamp,
         clear_timestamp=ts,
         managed_object=self.managed_object,
         alarm_class=self.alarm_class,
         severity=self.severity,
         vars=self.vars,
         log=log,
         root=self.root,
         escalation_ts=self.escalation_ts,
         escalation_tt=self.escalation_tt,
         escalation_error=self.escalation_error,
         escalation_ctx=self.escalation_ctx,
         opening_event=self.opening_event,
         closing_event=self.closing_event,
         discriminator=self.discriminator,
         reopens=self.reopens,
         direct_services=self.direct_services,
         direct_subscribers=self.direct_subscribers,
         total_objects=self.total_objects,
         total_services=self.total_services,
         total_subscribers=self.total_subscribers,
         adm_path=self.adm_path,
         segment_path=self.segment_path,
         container_path=self.container_path,
         uplinks=self.uplinks
     )
     ct = self.alarm_class.get_control_time(self.reopens)
     if ct:
         a.control_time = datetime.datetime.now() + datetime.timedelta(seconds=ct)
     a.save()
     # Send notifications
     if not a.root and not self.reopens:
         a.managed_object.event(a.managed_object.EV_ALARM_CLEARED, {
             "alarm": a,
             "subject": a.subject,
             "body": a.body,
             "symptoms": a.alarm_class.symptoms,
             "recommended_actions": a.alarm_class.recommended_actions,
             "probable_causes": a.alarm_class.probable_causes
         })
     elif ct:
         pass
     # Set checks on all consequences
     for d in self._get_collection().find({
         "root": self.id
     }, {"_id": 1, "alarm_class": 1}):
         ac = AlarmClass.get_by_id(d["alarm_class"])
         if not ac:
             continue
         t = ac.recover_time
         if not t:
             continue
         call_later(
             "noc.services.correlator.check.check_close_consequence",
             scheduler="correlator",
             pool=self.managed_object.pool.name,
             delay=t,
             alarm_id=d["_id"]
         )
     # Clear alarm
     self.delete()
     # Close TT
     # MUST be after .delete() to prevent race conditions
     if a.escalation_tt or self.clear_template:
         if self.clear_template:
             ctx = {
                 "alarm": a
             }
             subject = self.clear_template.render_subject(**ctx)
             body = self.clear_template.render_body(**ctx)
         else:
             subject = "Alarm cleared"
             body = "Alarm has been cleared"
         call_later(
             "noc.services.escalator.escalation.notify_close",
             scheduler="escalator",
             pool=self.managed_object.escalator_shard,
             max_runs=ALARM_CLOSE_RETRIES,
             alarm_id=self.id,
             tt_id=self.escalation_tt,
             subject=subject,
             body=body,
             notification_group_id=self.clear_notification_group.id if self.clear_notification_group else None,
             close_tt=self.close_tt
         )
     # Gather diagnostics
     AlarmDiagnosticConfig.on_clear(a)
     # Return archived
     return a
Example #26
0
def handler500(request):
    error_report()
    return HttpResponseServerError("Internal Server Error")
Example #27
0
 def check(self, extractors=None):
     extractors = extractors or self.get_extractors()
     try:
         return self.get_handler().check(extractors)
     except Exception:
         error_report()
Example #28
0
        def inner(request, *args, **kwargs):
            def nq(s):
                """
                Convert var[]=xxxx to var=xxxx
                """
                if s.endswith("[]"):
                    return s[:-2]
                else:
                    return s

            try:
                v = view_map[request.method]
            except KeyError:
                logger.info("No handler for '%s' method", request.method)
                return HttpResponseNotFound("No handler for '%s' method" %
                                            request.method)
            if not request.user or not v.access.check(app, request.user):
                return HttpResponseForbidden()
            to_log_api_call = self.log_api_calls and hasattr(v,
                                                             "api") and v.api
            app_logger = v.__self__.logger
            try:
                # Validate requests
                if getattr(v, "validate", False):
                    # Additional validation
                    errors = None
                    if isinstance(v.validate, DictParameter):
                        # Validate via NOC interfaces
                        if request.method == "GET":
                            g = {
                                nq(k): v[0] if len(v) == 1 else v
                                for k, v in request.GET.lists() if k != "_dc"
                            }
                        else:
                            if self.is_json(request.META.get("CONTENT_TYPE")):
                                try:
                                    g = orjson.loads(request.body)
                                except ValueError as e:
                                    logger.error("Unable to decode JSON: %s",
                                                 e)
                                    errors = "Unable to decode JSON: %s" % e
                            else:
                                g = {
                                    k: v[0] if len(v) == 1 else v
                                    for k, v in request.POST.lists()
                                }
                        if not errors:
                            try:
                                kwargs.update(v.validate.clean(g))
                            except InterfaceTypeError as e:
                                errors = str(e)
                    if errors:
                        #
                        if to_log_api_call:
                            app_logger.error("ERROR: %s", errors)
                        # Return error response
                        ext_format = "__format=ext" in request.META[
                            "QUERY_STRING"].split("&")
                        r = orjson.dumps({"status": False, "errors": errors})
                        status = 200 if ext_format else 400  # OK or BAD_REQUEST
                        return HttpResponse(
                            r,
                            status=status,
                            content_type="text/json; charset=utf-8")
                # Log API call
                if to_log_api_call:
                    a = {}
                    if request.method in ("POST", "PUT"):
                        ct = request.META.get("CONTENT_TYPE")
                        if ct and ("text/json" in ct
                                   or "application/json" in ct):
                            a = orjson.loads(request.body)
                        else:
                            a = {
                                k: v[0] if len(v) == 1 else v
                                for k, v in request.POST.lists()
                            }
                    elif request.method == "GET":
                        a = {
                            k: v[0] if len(v) == 1 else v
                            for k, v in request.GET.lists()
                        }
                    app_logger.debug("API %s %s %s", request.method,
                                     request.path, a)
                # Call handler
                r = v(request, *args, **kwargs)
                # Dump SQL statements
                if self.log_sql_statements:
                    from django.db import connections

                    tsc = 0
                    sc = defaultdict(int)
                    for conn in connections.all():
                        for q in conn.queries:
                            stmt = q["sql"].strip().split(" ", 1)[0].upper()
                            sc[stmt] += 1
                            tsc += 1
                            app_logger.debug("SQL %(sql)s %(time)ss" % q)
                    x = ", ".join("%s: %d" % (k, cv) for k, cv in sc.items())
                    if x:
                        x = " (%s)" % x
                    app_logger.debug("SQL statements: %d%s" % (tsc, x))
            except PermissionDenied as e:
                return HttpResponseForbidden(e)
            except Http404 as e:
                return HttpResponseNotFound(e)
            except Exception:
                # Generate 500
                r = HttpResponse(
                    content=error_report(logger=app_logger),
                    status=500,
                    content_type="text/plain; charset=utf-8",
                )
            # Serialize response when necessary
            if not isinstance(r, HttpResponse):
                try:
                    r = HttpResponse(
                        orjson.dumps(
                            r,
                            option=orjson.OPT_SERIALIZE_NUMPY
                            | orjson.OPT_NON_STR_KEYS,
                            default=orjson_defaults,
                        ),
                        content_type="text/json; charset=utf-8",
                    )
                except Exception:
                    error_report(logger=app_logger)
                    r = HttpResponse(error_report(), status=500)
            r["Pragma"] = "no-cache"
            r["Cache-Control"] = "no-cache"
            r["Expires"] = "0"
            return r
Example #29
0
 def post(self, *args, **kwargs):
     span_ctx = self.request.headers.get("X-NOC-Span-Ctx", 0)
     span_id = self.request.headers.get("X-NOC-Span", 0)
     sample = 1 if span_ctx and span_id else 0
     # Parse JSON
     try:
         req = ujson.loads(self.request.body)
     except ValueError as e:
         self.api_error(e)
         raise tornado.gen.Return()
     # Parse request
     id = req.get("id")
     params = req.get("params", [])
     method = req.get("method")
     if not method or not hasattr(self.api_class, method):
         self.api_error(
             "Invalid method: '%s'" % method,
             id=id
         )
         raise tornado.gen.Return()
     api = self.api_class(self.service, self.request, self)
     h = getattr(api, method)
     if not getattr(h, "api", False):
         self.api_error(
             "Method is not callable: '%s'" % method,
             id=id
         )
         raise tornado.gen.Return()
     calling_service = self.request.headers.get(
         self.CALLING_SERVICE_HEADER,
         "unknown"
     )
     self.service.logger.debug(
         "[RPC call from %s] %s.%s(%s)",
         calling_service, api.name, method, params
     )
     in_label = None
     if config.features.forensic:
         lh = getattr(api, "%s_get_label" % method, None)
         if lh:
             in_label = lh(*params)
     with Span(server=self.service.name,
               service="api.%s" % method, sample=sample,
               parent=span_id, context=span_ctx,
               in_label=in_label) as span:
         try:
             if getattr(h, "executor", ""):
                 # Threadpool version
                 executor = self.service.get_executor(h.executor)
                 result = executor.submit(h, *params)
             else:
                 # Serialized version
                 result = h(*params)
             if tornado.gen.is_future(result):
                 result = yield result
             if isinstance(result, Redirect):
                 # Redirect protocol extension
                 self.set_status(307, "Redirect")
                 self.set_header("Location", result.location)
                 self.write(ujson.dumps({
                     "id": id,
                     "method": result.method,
                     "params": result.params
                 }))
             else:
                 # Dump output
                 self.write(ujson.dumps({
                     "id": id,
                     "error": None,
                     "result": result
                 }))
         except NOCError as e:
             span.error_code = e.code
             span.error_text = str(e)
             self.api_error(
                 "Failed: %s" % e,
                 id=id,
                 code=e.code
             )
         except Exception as e:
             error_report()
             span.error_code = ERR_UNKNOWN
             span.error_text = str(e)
             self.api_error(
                 "Failed: %s" % e,
                 id=id
             )