Пример #1
0
def render_mobile_dataset(rows, view, group_cells, cells, num_columns,
                          show_checkboxes):
    if not is_mobile(request, response):
        html.show_error(_("This view can only be used in mobile mode."))
        return

    painter_options = PainterOptions.get_instance()
    painter_options.set("ts_format", "both")

    for row in rows:
        html.open_table(class_="dataset")
        for cell in cells:
            _tdclass, content = cell.render(row)
            if not content:
                continue  # Omit empty cells

            html.open_tr(class_="header")
            html.th(cell.title())
            html.close_tr()

            html.open_tr(class_="data")
            cell.paint(row)
            html.close_tr()

        html.close_table()
    html.javascript(
        '$("table.dataset > tbody > tr.data > td").addClass("ui-shadow").not(".state").addClass("nonstatus");\n'
        '$("table.dataset > tbody > tr.data a").attr("data-ajax", "false");\n')
Пример #2
0
def page_index() -> None:
    # Redirect to mobile GUI if we are a mobile device and the index is requested
    if is_mobile(request, response):
        raise HTTPRedirect(makeuri(request, [], filename="mobile.py"))

    title = get_page_heading()
    content = html.render_iframe("", src=_get_start_url(), name="main")
    SidebarRenderer().show(title, content)
Пример #3
0
def mock_livestatus(
    with_context: bool = False,
    with_html: bool = False
) -> Generator[MockLiveStatusConnection, None, None]:
    live = MockLiveStatusConnection()

    env = EnvironBuilder().get_environ()
    req = http.Request(env)
    resp = http.Response()

    app_context: ContextManager
    req_context: ContextManager
    if with_html:
        html_obj = None
    else:
        html_obj = HTMLGenerator(
            request=req,
            output_funnel=OutputFunnel(resp),
            output_format="html",
            mobile=is_mobile(req, resp),
        )
    if with_context:
        app_context = AppContext(None, stack=app_stack())
        req_context = RequestContext(
            html_obj=html_obj,
            req=req,
            resp=resp,
            funnel=OutputFunnel(resp),
            config_obj=make_config_object(get_default_config()),
            user=LoggedInNobody(),
            display_options=DisplayOptions(),
            prefix_logs_with_url=False,
            stack=request_stack(),
            url_filter=PrependURLFilter(),
        )
    else:
        app_context = contextlib.nullcontext()
        req_context = contextlib.nullcontext()

    with app_context, req_context, mock.patch(
            "cmk.gui.sites._get_enabled_and_disabled_sites",
            new=live.enabled_and_disabled_sites), mock.patch(
                "livestatus.MultiSiteConnection.expect_query",
                new=live.expect_query,
                create=True), mock.patch(
                    "livestatus.SingleSiteConnection._create_socket",
                    new=live.create_socket), mock.patch.dict(
                        os.environ, {
                            "OMD_ROOT": "/",
                            "OMD_SITE": "NO_SITE"
                        }):

        # We don't want to be polluted by other tests.
        omd_site.cache_clear()
        yield live
        # We don't want to pollute other tests.
        omd_site.cache_clear()
Пример #4
0
    def page(self) -> None:
        # Initialize the cmk.gui.i18n for the login dialog. This might be
        # overridden later after user login
        cmk.gui.i18n.localize(request.var("lang", config.default_language))

        self._do_login()

        if self._no_html_output:
            raise MKAuthException(_("Invalid login credentials."))

        if is_mobile(request, response):
            cmk.gui.mobile.page_login()
            return

        self._show_login_page()
Пример #5
0
    def render(self, what, row, tags, custom_vars):
        def may_see_hosts():
            return user.may("wato.use") and (user.may("wato.seeall") or user.may("wato.hosts"))

        if not may_see_hosts() or is_mobile(request, response):
            return None

        wato_folder = _wato_folder_from_filename(row["host_filename"])
        if wato_folder is None:
            return None

        if what == "host":
            return self._wato_link(wato_folder, row["site"], row["host_name"], "edithost")

        if row["service_description"] in ["Check_MK inventory", "Check_MK Discovery"]:
            return self._wato_link(wato_folder, row["site"], row["host_name"], "inventory")
Пример #6
0
 def from_exception(cls, details=None, type_specific_attributes=None):
     return super().from_exception(
         details={
             "page": requested_file_name(request) + ".py",
             "vars": {
                 key: "***" if value in ["password", "_password"] else value
                 for key, value in request.itervars()
             },
             "username": user.id,
             "user_agent": request.user_agent.string,
             "referer": request.referer,
             "is_mobile": is_mobile(request, response),
             "is_ssl_request": request.is_ssl_request,
             "language": cmk.gui.i18n.get_current_language(),
             "request_method": request.request_method,
         },
     )
Пример #7
0
def confirm_with_preview(msg: Union[str, HTML],
                         confirm_options: List[Tuple[str, str]],
                         method: str = "POST") -> Optional[bool]:
    """Show a confirm dialog to the user

    BE AWARE: In case you just want to have some action confirmed by the user, you
    should use the javascript powere confirm dialg (make_confirm, add_confirm_on_submit, ...).

    This method is used only in places where we explicitly need to show important information to the
    user before he can decide whether or not to confirm the action.

    The confirm dialog is normally not a dialog which need to be protected by a transid itselfs. It
    is only a intermediate step to the real action But there are use cases where the confirm dialog
    is used during rendering a normal page, for example when deleting a dashlet from a dashboard. In
    such cases, the transid must be added by the confirm dialog.
    """
    if html.request.var("_do_actions") == _("Cancel"):
        # User has pressed "Cancel", now invalidate the unused transid
        transactions.check_transaction()
        return None  # None --> "Cancel"

    if not any(
            html.request.has_var(varname)
            for _title, varname in confirm_options):
        mobile = is_mobile(request, response)
        if mobile:
            html.open_center()
        html.open_div(class_="really")
        html.write_text(msg)
        html.begin_form("confirm", method=method, add_transid=False)
        html.hidden_fields(add_action_vars=True)
        for title, varname in confirm_options:
            html.button(varname, title, "really")
        html.button("_do_actions", _("Cancel"))
        html.end_form()
        html.close_div()
        if mobile:
            html.close_center()

        return False  # False --> "Dialog shown, no answer yet"

    # Now check the transaction. True: "Yes", None --> Browser reload of "yes" page
    return True if transactions.check_transaction() else None
Пример #8
0
    def _pnp_icon(self, row, what):
        url = self._graph_icon_link(row, what)

        # Don't show the icon with Checkmk graphing. The hover makes no sense and there is no
        # mobile view for graphs, so the graphs on the bottom of the host/service view are enough
        # for the moment.
        if is_mobile(request, response):
            return

        return html.render_a(
            content=html.render_icon('graph', ''),
            href=url,
            onmouseout="cmk.hover.hide()",
            onmouseover=
            "cmk.graph_integration.show_hover_graphs(event, %s, %s, %s);" % (
                json.dumps(row['site']),
                json.dumps(row["host_name"]),
                json.dumps(row['service_description'] if what ==
                           "service" else '_HOST_'),
            ))
Пример #9
0
def render_mobile_list(rows, view, group_cells, cells, num_columns,
                       show_checkboxes):
    if not is_mobile(request, response):
        html.show_error(_("This view can only be used in mobile mode."))
        return

    # Force relative timestamp always. This saves space.
    painter_options = PainterOptions.get_instance()
    painter_options.set("ts_format", "rel")

    html.open_ul(class_="mobilelist", **{"data-role": "listview"})

    # Paint data rows
    for row in rows:
        html.open_li()
        rendered_cells = [cell.render(row) for cell in cells]
        if rendered_cells:  # First cell (assumedly state) is left
            rendered_class, rendered_content = rendered_cells[0]
            html.p(rendered_content,
                   class_=["ui-li-aside", "ui-li-desc", rendered_class])

            if len(rendered_cells) > 1:
                content = HTML(" · ").join([
                    rendered_cell[1]
                    for rendered_cell in rendered_cells[1:num_columns + 1]
                ])
                html.h3(content)

                for rendered_cell, cell in zip(
                        rendered_cells[num_columns + 1:],
                        cells[num_columns + 1:]):
                    rendered_class, rendered_content = rendered_cell
                    html.open_p(class_="ui-li-desc")
                    cell.paint_as_header()
                    html.write_text(": ")
                    html.span(rendered_content, class_=rendered_class)
                    html.close_p()

        html.close_li()
    html.close_ul()
    html.javascript('$("ul.mobilelist a").attr("data-ajax", "false");')
Пример #10
0
def render_mobile_table(rows, view, group_cells, cells, num_columns,
                        show_checkboxes):
    if not is_mobile(request, response):
        html.show_error(_("This view can only be used in mobile mode."))
        return

    # Force relative timestamp always. This saves space.
    painter_options = PainterOptions.get_instance()
    painter_options.set("ts_format", "rel")

    odd = "odd"
    html.open_table(class_="mobile data")

    # Paint header
    if view.get("column_headers") != "off":
        html.open_tr()
        n = 0
        for cell in cells:
            cell.paint_as_header()
        html.close_tr()

    # Paint data rows
    for row in rows:
        odd = "even" if odd == "odd" else "odd"
        html.open_tr(class_="%s0" % odd)
        for n, cell in enumerate(cells):
            if n > 0 and n % num_columns == 0:
                html.close_tr()
                html.open_tr(class_="%s0" % odd)

            if n == len(cells) - 1 and n % num_columns != (num_columns - 1):
                colspan = num_columns - (n % num_columns)
            else:
                colspan = None

            cell.paint(row, colspan=colspan)
        html.close_row()
    html.close_table()
    html.javascript('$("table.mobile a").attr("data-ajax", "false");')
Пример #11
0
def make_request_context(
        environ: Optional[Mapping[str, Any]] = None) -> RequestContext:
    req = Request(
        dict(create_environ(), REQUEST_URI="") if environ is None else environ)
    resp = Response(mimetype="text/html")
    funnel = OutputFunnel(resp)
    return RequestContext(
        req=req,
        resp=resp,
        funnel=funnel,
        config_obj=make_config_object(get_default_config()),
        user=LoggedInNobody(),
        html_obj=HTMLGenerator(req,
                               funnel,
                               output_format="html",
                               mobile=is_mobile(req, resp)),
        display_options=DisplayOptions(),
        timeout_manager=TimeoutManager(),
        theme=Theme(),
        prefix_logs_with_url=False,
        stack=request_stack(),
        url_filter=PrependURLFilter(),
    )
Пример #12
0
    def __call__(self, environ: WSGIEnvironment,
                 start_response: StartResponse) -> WSGIResponse:
        req = http.Request(environ)

        output_format = get_output_format(
            req.get_ascii_input_mandatory("output_format", "html").lower())
        mime_type = get_mime_type_from_output_format(output_format)

        resp = Response(headers=default_response_headers(req),
                        mimetype=mime_type)
        funnel = OutputFunnel(resp)

        timeout_manager = TimeoutManager()
        timeout_manager.enable_timeout(req.request_timeout)

        theme = Theme()
        config_obj = config_module.make_config_object(
            config_module.get_default_config())

        with AppContext(self, stack=app_stack()), RequestContext(
                req=req,
                resp=resp,
                funnel=funnel,
                config_obj=config_obj,
                user=LoggedInNobody(),
                html_obj=HTMLGenerator(req, funnel, output_format,
                                       is_mobile(req, resp)),
                timeout_manager=timeout_manager,
                display_options=DisplayOptions(),
                theme=theme,
                stack=request_stack(),
                url_filter=PrependURLFilter(),
        ), patch_json(json):
            config_module.initialize()
            theme.from_config(active_config.ui_theme)
            return self.wsgi_app(environ, start_response)
Пример #13
0
def paint_time_graph_cmk(row, cell, override_graph_render_options=None):
    graph_identification = (
        "template",
        {
            "site": row["site"],
            "host_name": row["host_name"],
            "service_description": row.get("service_description", "_HOST_"),
        },
    )

    # Load the graph render options from
    # a) the painter parameters configured in the view
    # b) the painter options set per user and view

    painter_params = cell.painter_parameters()
    painter_params = _transform_old_graph_render_options(painter_params)

    graph_render_options = painter_params["graph_render_options"]

    if override_graph_render_options is not None:
        graph_render_options.update(override_graph_render_options)

    painter_options = PainterOptions.get_instance()
    options = painter_options.get_without_default("graph_render_options")
    if options is not None:
        graph_render_options.update(options)

    graph_data_range = {}

    now = time.time()
    if "set_default_time_range" in painter_params:
        duration = painter_params["set_default_time_range"]
        graph_data_range["time_range"] = now - duration, now
    else:
        graph_data_range["time_range"] = now - 3600 * 4, now

    # Load timerange from painter option (overrides the defaults, if set by the user)
    painter_option_pnp_timerange = painter_options.get_without_default(
        "pnp_timerange")
    if painter_option_pnp_timerange is not None:
        graph_data_range[
            "time_range"] = get_graph_timerange_from_painter_options()

    if is_mobile(request, response):
        graph_render_options.update({
            "interaction": False,
            "show_controls": False,
            "show_pin": False,
            "show_graph_time": False,
            "show_time_range_previews": False,
            "show_legend": False,
            # Would be much better to autodetect the possible size (like on dashboard)
            "size": (27, 18),  # ex
        })

    if "host_metrics" in row:
        available_metrics = row["host_metrics"]
        perf_data = row["host_perf_data"]
    else:
        available_metrics = row["service_metrics"]
        perf_data = row["service_perf_data"]

    if not available_metrics and perf_data:
        return "", _(
            "No historic metrics recorded but performance data is available. "
            "Maybe performance data processing is disabled.")

    return "", html_render.render_graphs_from_specification_html(
        graph_identification, graph_data_range, graph_render_options)