Exemple #1
0
    def _wsgi_app(self, environ: WSGIEnvironment, start_response):
        urls = self.url_map.bind_to_environ(environ)
        try:
            wsgi_app, path_args = urls.match()

            # Remove this again (see Submount above), so the validators don't go crazy.
            del path_args['_path']

            # This is an implicit dependency, as we only know the args at runtime, but the
            # function at setup-time.
            environ[ARGS_KEY] = path_args
            return wsgi_app(environ, start_response)
        except HTTPException as exc:
            # We don't want to log explicit HTTPExceptions as these are intentional.
            assert isinstance(exc.code, int)
            return problem(
                status=exc.code,
                title=http.client.responses[exc.code],
                detail=str(exc),
            )(environ, start_response)
        except MKException as exc:
            if self.debug:
                raise

            return problem(
                status=EXCEPTION_STATUS.get(type(exc), 500),
                title="An exception occurred.",
                detail=str(exc),
            )(environ, start_response)
        except Exception as exc:
            crash = APICrashReport.from_exception()
            crash_reporting.CrashReportStore().save(crash)
            logger.exception("Unhandled exception (Crash-ID: %s)",
                             crash.ident_to_text())
            if self.debug:
                raise

            crash_url = f"/{config.omd_site()}/check_mk/crash.py?" + urllib.parse.urlencode(
                [
                    ("crash_id", crash.ident_to_text()),
                    ("site", config.omd_site()),
                ], )

            return problem(
                status=500,
                title=str(exc),
                detail=
                "An internal error occured while processing your request.",
                ext={
                    'crash_report': {
                        'href': crash_url,
                        'method': 'get',
                        'rel': 'cmk/crash-report',
                        'type': 'text/html',
                    },
                    'crash_id': crash.ident_to_text(),
                })(environ, start_response)
Exemple #2
0
def test_base_crash_report_save():
    store = crash_reporting.CrashReportStore()
    try:
        raise ValueError("DINGELING")
    except Exception:
        crash = crash_reporting.CMKBaseCrashReport.from_exception()
        store.save(crash)

    crash2 = store.load_from_directory(crash.crash_dir())

    assert crash.crash_info["exc_type"] == crash2.crash_info["exc_type"]
    assert crash.crash_info["time"] == crash2.crash_info["time"]
Exemple #3
0
def test_gui_crash_report_get_packed(register_builtin_html):
    store = crash_reporting.CrashReportStore()
    try:
        raise ValueError("DINGELING")
    except Exception:
        crash = crash_reporting.GUICrashReport.from_exception()
        store.save(crash)
        crash_dir = crash.crash_dir()

    tgz = crash_reporting._pack_crash_report(store.load_serialized_from_directory(crash_dir))
    buf = io.BytesIO(tgz)
    with tarfile.open(mode="r:gz", fileobj=buf) as tar:
        assert tar.getnames() == ["crash.info"]
Exemple #4
0
    def log_error(self, exception):
        """Save the caught exception and store it.

        Args:
            exception: An exception instance

        Returns:
            A flask response to tell the user what happened.

        """
        # We only log a crash report when we have an unknown exception.
        crash = APICrashReport.from_exception()
        crash_reporting.CrashReportStore().save(crash)
        logger.exception("Unhandled exception (Crash-ID: %s)", crash.ident_to_text())

        # We need to return something for the user.
        return self._make_error_response(exception)
Exemple #5
0
def test_check_crash_report_save(monkeypatch):
    Scenario().apply(monkeypatch)
    store = crash_reporting.CrashReportStore()
    try:
        raise Exception("DING")
    except Exception:
        crash = crash_reporting.CheckCrashReport.from_exception_and_context(
            hostname=HostName("testhost"),
            check_plugin_name="uptime",
            check_plugin_kwargs={},
            is_manual_check=False,
            description="Uptime",
            text="Output",
        )
        store.save(crash)

    crash2 = store.load_from_directory(crash.crash_dir())
    assert crash2.crash_info["exc_value"] == "DING"
Exemple #6
0
    def _wsgi_app(self, environ: WSGIEnvironment,
                  start_response: StartResponse) -> WSGIResponse:
        urls = self.url_map.bind_to_environ(environ)
        endpoint: Optional[Endpoint] = None
        try:
            result: Tuple[str, Mapping[str,
                                       Any]] = urls.match(return_rule=False)
            endpoint_ident, matched_path_args = result  # pylint: disable=unpacking-non-sequence
            wsgi_app = self.endpoints[endpoint_ident]
            if isinstance(wsgi_app, Authenticate):
                endpoint = wsgi_app.endpoint

            # Remove _path again (see Submount above), so the validators don't go crazy.
            path_args = {
                key: value
                for key, value in matched_path_args.items() if key != "_path"
            }

            # This is an implicit dependency, as we only know the args at runtime, but the
            # function at setup-time.
            environ[ARGS_KEY] = path_args

            req = Request(environ)
            resp = Response()
            with AppContext(self, stack=app_stack()), RequestContext(
                    req=req,
                    resp=resp,
                    funnel=OutputFunnel(resp),
                    config_obj=config.make_config_object(
                        config.get_default_config()),
                    endpoint=endpoint,
                    user=LoggedInNobody(),
                    display_options=DisplayOptions(),
                    stack=request_stack(),
                    url_filter=PrependURLFilter(),
            ), cmk.utils.store.cleanup_locks(), sites.cleanup_connections():
                config.initialize()
                load_dynamic_permissions()
                return wsgi_app(environ, start_response)
        except ProblemException as exc:
            return exc(environ, start_response)
        except HTTPException as exc:
            # We don't want to log explicit HTTPExceptions as these are intentional.
            assert isinstance(exc.code, int)
            return problem(
                status=exc.code,
                title=http.client.responses[exc.code],
                detail=str(exc),
            )(environ, start_response)
        except MKException as exc:
            if self.debug:
                raise

            return problem(
                status=EXCEPTION_STATUS.get(type(exc), 500),
                title="An exception occurred.",
                detail=str(exc),
            )(environ, start_response)
        except Exception as exc:
            crash = APICrashReport.from_exception()
            crash_reporting.CrashReportStore().save(crash)
            logger.exception("Unhandled exception (Crash-ID: %s)",
                             crash.ident_to_text())
            if self.debug:
                raise

            request = Request(environ)
            site = config.omd_site()
            query_string = urllib.parse.urlencode([
                ("crash_id", (crash.ident_to_text())),
                ("site", site),
            ])
            crash_url = f"{request.host_url}{site}/check_mk/crash.py?{query_string}"
            crash_details = {
                "crash_id": (crash.ident_to_text()),
                "crash_report": {
                    "href": crash_url,
                    "method": "get",
                    "rel": "cmk/crash-report",
                    "type": "text/html",
                },
            }
            if user.may("general.see_crash_reports"):
                crash_details["stack_trace"] = traceback.format_exc().split(
                    "\n")

            return problem(
                status=500,
                title=http.client.responses[500],
                detail=str(exc),
                ext=crash_details,
            )(environ, start_response)
Exemple #7
0
    def _wsgi_app(self, environ: WSGIEnvironment, start_response):
        urls = self.url_map.bind_to_environ(environ)
        try:
            wsgi_app, path_args = urls.match()

            # Remove this again (see Submount above), so the validators don't go crazy.
            del path_args["_path"]

            # This is an implicit dependency, as we only know the args at runtime, but the
            # function at setup-time.
            environ[ARGS_KEY] = path_args
            return wsgi_app(environ, start_response)
        except HTTPException as exc:
            # We don't want to log explicit HTTPExceptions as these are intentional.
            assert isinstance(exc.code, int)
            return problem(
                status=exc.code,
                title=http.client.responses[exc.code],
                detail=str(exc),
            )(environ, start_response)
        except MKException as exc:
            if self.debug:
                raise

            return problem(
                status=EXCEPTION_STATUS.get(type(exc), 500),
                title="An exception occurred.",
                detail=str(exc),
            )(environ, start_response)
        except Exception as exc:
            crash = APICrashReport.from_exception()
            crash_reporting.CrashReportStore().save(crash)
            logger.exception("Unhandled exception (Crash-ID: %s)", crash.ident_to_text())
            if self.debug:
                raise

            request = Request(environ)
            site = config.omd_site()
            query_string = urllib.parse.urlencode(
                [
                    ("crash_id", (crash.ident_to_text())),
                    ("site", site),
                ]
            )
            crash_url = f"{request.host_url}{site}/check_mk/crash.py?{query_string}"
            crash_details = {
                "crash_id": (crash.ident_to_text()),
                "crash_report": {
                    "href": crash_url,
                    "method": "get",
                    "rel": "cmk/crash-report",
                    "type": "text/html",
                },
            }
            if user.may("general.see_crash_reports"):
                crash_details["stack_trace"] = traceback.format_exc().split("\n")

            return problem(
                status=500,
                title=http.client.responses[500],
                detail=str(exc),
                ext=crash_details,
            )(environ, start_response)