Пример #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 js_dashlet(self, figure_type_name: str) -> None:
        fetch_url = "ajax_figure_dashlet_data.py"
        div_id = "%s_dashlet_%d" % (self.type_name(), self._dashlet_id)
        html.div("", id_=div_id)

        # TODO: Would be good to align this scheme with AjaxPage.webapi_request()
        # (a single HTTP variable "request=<json-body>".
        post_body = urlencode_vars(self._dashlet_http_variables())

        html.javascript(
            """
            let figure_%(dashlet_id)d = cmk.figures.figure_registry.get_figure(%(type_name)s);
            let %(instance_name)s = new figure_%(dashlet_id)d(%(div_selector)s);
            %(instance_name)s.set_post_url_and_body(%(url)s, %(body)s);
            %(instance_name)s.initialize();
            %(instance_name)s.scheduler.set_update_interval(%(update)d);
            %(instance_name)s.scheduler.enable();
            """ % {
                "type_name": json.dumps(figure_type_name),
                "dashlet_id": self._dashlet_id,
                "instance_name": self.instance_name,
                "div_selector": json.dumps("#%s" % div_id),
                "url": json.dumps(fetch_url),
                "body": json.dumps(post_body),
                "update": self.update_interval,
            })
Пример #3
0
    def show(self):
        html.open_div(class_="speedometer")
        html.img(theme.url("images/speedometer.svg"), id_="speedometerbg")
        html.canvas("", width=str(snapin_width), height="146", id_="speedometer")
        html.close_div()

        html.javascript("cmk.sidebar.speedometer_show_speed(0, 0, 0);")
Пример #4
0
def inpage_search_form(mode: Optional[str] = None, default_value: str = "") -> None:
    form_name = "inpage_search_form"
    reset_button_id = "%s_reset" % form_name
    was_submitted = request.get_ascii_input("filled_in") == form_name
    html.begin_form(form_name, add_transid=False)
    html.text_input(
        "search",
        size=32,
        default_value=default_value,
        placeholder=_("Filter"),
        required=True,
        title="",
    )
    html.hidden_fields()
    if mode:
        html.hidden_field("mode", mode, add_var=True)
    reset_url = request.get_ascii_input_mandatory("reset_url", requested_file_with_query(request))
    html.hidden_field("reset_url", reset_url, add_var=True)
    html.button("submit", "", cssclass="submit", help_=_("Apply"))
    html.buttonlink(reset_url, "", obj_id=reset_button_id, title=_("Reset"))
    html.end_form()
    html.javascript(
        "cmk.page_menu.inpage_search_init(%s, %s)"
        % (json.dumps(reset_button_id), json.dumps(was_submitted))
    )
Пример #5
0
def create_graph(name, size, bounds, v_range, legend):
    html.open_table(class_="prediction")
    html.open_tr()
    html.open_td()
    html.canvas(
        "",
        class_="prediction",
        id_="content_%s" % name,
        style="width: %dpx; height: %dpx;" %
        (int(size[0] / 2.0), int(size[1] / 2.0)),
        width=size[0],
        height=size[1],
    )
    html.close_td()
    html.close_tr()
    html.open_tr()
    html.open_td(class_="legend")
    for color, title in legend:
        html.div("", class_="color", style="background-color: %s" % color)
        html.div(title, class_="entry")
    html.close_td()
    html.close_tr()
    html.close_table()
    html.javascript(
        'cmk.prediction.create_graph("content_%s", %.4f, %.4f, %.4f, %.4f);' %
        (name, bounds[0], bounds[1], v_range[0], v_range[1]))
Пример #6
0
def _show_command_form(datasource: ABCDataSource, rows: Rows) -> None:
    what = datasource.infos[0]
    html.javascript(
        """
    $(document).ready(function() {
      $('.command_group').has('x').trigger('expand');
      $('x').children().css('background-color', '#f84');
    });
    """
    )

    one_shown = False
    html.open_div(**{"data-role": "collapsible-set"})
    for command_class in command_registry.values():
        command = command_class()
        if what in command.tables and user.may(command.permission.name):
            html.open_div(class_=["command_group"], **{"data-role": "collapsible"})
            html.h3(command.title)
            html.open_p()

            html.begin_form("actions")
            html.hidden_field("_do_actions", "yes")
            html.hidden_field("actions", "yes")
            command.render(what)
            html.hidden_fields()
            html.end_form()

            html.close_p()
            html.close_div()
            one_shown = True
    html.close_div()
    if not one_shown:
        html.write_text(_("No commands are possible in this view"))
Пример #7
0
def init_rowselect(selection_key: str) -> None:
    selected = user.get_rowselection(weblib.selection_id(), selection_key)
    selection_properties = {
        "page_id": selection_key,
        "selection_id": weblib.selection_id(),
        "selected_rows": selected,
    }
    html.javascript("cmk.selection.init_rowselect(%s);" %
                    (json.dumps(selection_properties)))
Пример #8
0
 def render_input(self, varprefix: str, value: CascadingDropdownChoiceValue) -> None:
     super().render_input(varprefix, value)
     root_prefix = varprefix[: varprefix.find(self._vs_name)]
     metric_ref_prefix = root_prefix + self._metric_vs_name
     # This will load an event listener between the unit and the metric valuespec
     html.javascript(
         "cmk.valuespecs.update_unit_selector(%s, %s)"
         % (json.dumps(varprefix), json.dumps(metric_ref_prefix))
     )
Пример #9
0
    def action(self) -> ActionResult:
        if request.var("_action") != "discard":
            return None

        if not transactions.check_transaction():
            return None

        if not self._may_discard_changes():
            return None

        if not self.has_changes():
            return None

        # Now remove all currently pending changes by simply restoring the last automatically
        # taken snapshot. Then activate the configuration. This should revert all pending changes.
        file_to_restore = self._get_last_wato_snapshot_file()

        if not file_to_restore:
            raise MKUserError(None,
                              _("There is no WATO snapshot to be restored."))

        msg = _("Discarded pending changes (Restored %s)") % file_to_restore

        # All sites and domains can be affected by a restore: Better restart everything.
        _changes.add_change(
            "changes-discarded",
            msg,
            domains=ABCConfigDomain.enabled_domains(),
            need_restart=True,
        )

        self._extract_snapshot(file_to_restore)
        activate_changes.execute_activate_changes([
            d.get_domain_request([])
            for d in ABCConfigDomain.enabled_domains()
        ])

        for site_id in activation_sites():
            self.confirm_site_changes(site_id)

        build_index_background()

        make_header(
            html,
            self.title(),
            breadcrumb=self.breadcrumb(),
            show_body_start=display_options.enabled(display_options.H),
            show_top_heading=display_options.enabled(display_options.T),
        )
        html.open_div(class_="wato")

        html.show_message(_("Successfully discarded all pending changes."))
        html.javascript("hide_changes_buttons();")
        html.footer()
        return FinalizeRequest(code=200)
Пример #10
0
    def show_topology_content(self, topology_settings: TopologySettings) -> None:
        div_id = "node_visualization"
        html.div("", id_=div_id)
        html.javascript(
            "topology_instance = new cmk.node_visualization.TopologyVisualization(%s);"
            % json.dumps(div_id)
        )

        html.javascript(
            "topology_instance.show_topology(%s)"
            % json.dumps(TopologySettingsJSON(**asdict(topology_settings)).to_json())
        )
Пример #11
0
    def _show_diagnose_output(self):
        if not request.var("_save"):
            html.show_message(
                _(
                    "You can diagnose the connection to a specific host using this dialog. "
                    "You can either test whether your current configuration is still working "
                    "or investigate in which ways a host can be reached. Simply configure the "
                    "connection options you like to try on the right side of the screen and "
                    'press the "Test" button. The results will be displayed here.'
                )
            )
            return

        if user_errors:
            html.show_user_errors()
            return

        # TODO: Insert any vs_host valuespec validation
        #       These tests can be called with invalid valuespec settings...
        # TODO: Replace hard coded icon paths with dynamic ones to old or new theme
        for ident, title in ModeDiagHost.diag_host_tests():
            html.h3(title)
            html.open_table(class_=["data", "test"])
            html.open_tr(class_=["data", "odd0"])

            html.open_td(class_="icons")
            html.open_div()
            html.icon("reload", id_="%s_img" % ident)
            html.open_a(href="")
            html.icon(
                "reload", title=_("Retry this test"), cssclass="retry", id_="%s_retry" % ident
            )
            html.close_a()
            html.close_div()
            html.close_td()

            html.open_td()
            html.div("", class_="log", id="%s_log" % ident)
            html.close_td()

            html.close_tr()
            html.close_table()
            html.javascript(
                "cmk.host_diagnose.start_test(%s, %s, %s)"
                % (
                    json.dumps(ident),
                    json.dumps(self._hostname),
                    json.dumps(transactions.fresh_transid()),
                )
            )
Пример #12
0
def _bi_map() -> None:
    aggr_name = request.var("aggr_name")
    layout_id = request.var("layout_id")
    title = _("BI visualization")
    breadcrumb = make_simple_page_breadcrumb(mega_menu_registry.menu_monitoring(), title)
    make_header(html, title, breadcrumb)
    div_id = "node_visualization"
    html.div("", id=div_id)
    html.javascript(
        "node_instance = new cmk.node_visualization.BIVisualization(%s);" % json.dumps(div_id)
    )

    html.javascript(
        "node_instance.show_aggregations(%s, %s)" % (json.dumps([aggr_name]), json.dumps(layout_id))
    )
Пример #13
0
def user_profile_async_replication_dialog(sites: Sequence[SiteId],
                                          back_url: str) -> None:
    html.p(
        _("In order to activate your changes available on all remote sites, your user profile needs "
          "to be replicated to the remote sites. This is done on this page now. Each site "
          "is being represented by a single image which is first shown gray and then fills "
          "to green during synchronisation."))

    html.h3(_("Replication States"))
    html.open_div(id_="profile_repl")
    num_replsites = 0
    for site_id in sites:
        site = active_config.sites[site_id]
        if "secret" not in site:
            status_txt = _("Not logged in.")
            start_sync = False
            icon = "repl_locked"
        else:
            status_txt = _("Waiting for replication to start")
            start_sync = True
            icon = "repl_pending"

        html.open_div(class_="site", id_="site-%s" % site_id)
        html.div("", title=status_txt, class_=["icon", "repl_status", icon])
        if start_sync:
            changes_manager = ActivateChanges()
            changes_manager.load()
            estimated_duration = changes_manager.get_activation_time(
                site_id, ACTIVATION_TIME_PROFILE_SYNC, 2.0)
            html.javascript("cmk.profile_replication.start(%s, %d, %s);" % (
                json.dumps(site_id),
                int(estimated_duration * 1000.0),
                json.dumps(_("Replication in progress")),
            ))
            num_replsites += 1
        else:
            _add_profile_replication_change(site_id, status_txt)
        html.span(site.get("alias", site_id))

        html.close_div()

    html.javascript("cmk.profile_replication.prepare(%d, %s);\n" %
                    (num_replsites, json.dumps(back_url)))

    html.close_div()
Пример #14
0
    def _show_snapin_bar(self, user_config: UserSidebarConfig) -> None:
        html.open_div(
            class_="scroll" if active_config.sidebar_show_scrollbar else None,
            id_="side_content")

        refresh_snapins, restart_snapins, static_snapins = self._show_snapins(
            user_config)
        self._show_add_snapin_button()

        html.close_div()

        html.javascript(
            "cmk.sidebar.initialize_sidebar(%0.2f, %s, %s, %s);\n" % (
                active_config.sidebar_update_interval,
                json.dumps(refresh_snapins),
                json.dumps(restart_snapins),
                json.dumps(static_snapins),
            ))
Пример #15
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(" &middot; ").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");')
Пример #16
0
    def show(self, menu: MegaMenu) -> None:
        more_id = "main_menu_" + menu.name

        show_more = user.get_show_more_setting(more_id)
        html.open_div(id_=more_id,
                      class_=["main_menu", "more" if show_more else "less"])
        hide_entries_js = "cmk.popup_menu.mega_menu_hide_entries('%s')" % more_id

        html.open_div(class_="navigation_bar")
        html.open_div(class_="search_bar")
        if menu.search:
            menu.search.show_search_field()
        html.close_div()
        if menu.info_line:
            html.span(menu.info_line(),
                      id_="info_line_%s" % menu.name,
                      class_="info_line")
        topics = menu.topics()
        if any_show_more_items(topics):
            html.open_div()
            html.more_button(id_=more_id,
                             dom_levels_up=3,
                             additional_js=hide_entries_js,
                             with_text=True)
            html.close_div()
        html.close_div()
        html.open_div(class_="content inner",
                      id="content_inner_%s" % menu.name)
        for topic in topics:
            if not topic.items:
                continue
            self._show_topic(topic, menu.name)
        html.close_div()
        html.close_div()
        html.javascript(hide_entries_js)
        html.javascript("cmk.popup_menu.initialize_mega_menus();")
        html.open_div(class_="content inner",
                      id="content_inner_%s_search" % menu.name)
        html.close_div()
Пример #17
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");')
Пример #18
0
    def _show_initial_iframe_container(self) -> None:
        iframe_url = self._get_iframe_url()
        if not iframe_url:
            return

        # Fix of iPad >:-P
        html.open_div(
            style="width: 100%; height: 100%; -webkit-overflow-scrolling:touch;"
        )
        html.iframe(
            "",
            src="about:blank" if self.reload_on_resize() else iframe_url,
            id_="dashlet_iframe_%d" % self._dashlet_id,
            allowTransparency="true",
            frameborder="0",
            width="100%",
            height="100%",
        )
        html.close_div()

        if self.reload_on_resize():
            html.javascript(
                "cmk.dashboard.set_reload_on_resize(%s, %s);" %
                (json.dumps(self._dashlet_id), json.dumps(iframe_url)))
Пример #19
0
    def page(self) -> cmk.gui.pages.PageResult:
        """Renders an iframe to view the content of the RobotMK log file"""
        site_id, host_name, service_description = _get_mandatory_request_vars()

        breadcrumb: Breadcrumb = make_service_breadcrumb(
            HostName(host_name), service_description)
        title = self._title() + _(" of service %s on host %s") % (
            service_description, host_name)
        try:
            content = _get_html_from_livestatus(self._report_type(), site_id,
                                                host_name, service_description)
        except MKLivestatusNotFoundError:
            make_header(
                html,
                title=title,
                breadcrumb=breadcrumb,
            )
            html.user_error(
                MKUserError(None,
                            _("You are not permitted to view this page")))
            return

        if not content[0]:
            make_header(
                html,
                title=title,
                breadcrumb=breadcrumb,
            )
            html.user_error(MKUserError(None, _("No logs could be found.")))
            return

        # Only render page menu with download option if content is not empty
        # and user is permitted
        make_header(
            html,
            title=title,
            breadcrumb=breadcrumb,
            page_menu=self._page_menu(breadcrumb, site_id, host_name,
                                      service_description),
        )

        iframe: str = self._report_type()
        html.iframe(
            content="",
            src=makeuri_contextless(
                request,
                [
                    ("report_type", self._report_type()),
                    ("site", site_id),
                    ("host", host_name),
                    ("service", service_description),
                ],
                filename="robotmk_report.py",
            ),
            name="%s_report" % self._report_type(),
            id_=iframe,
        )

        html.javascript('cmk.utils.content_scrollbar("main_page_content");')
        html.javascript(
            "cmk.utils.add_height_to_simple_bar_content_of_iframe(%s);" %
            json.dumps(iframe))
Пример #20
0
def render_coordinates(v_scala, t_scala):
    html.javascript("cmk.prediction.render_coordinates(%s, %s);" %
                    (json.dumps(v_scala), json.dumps(t_scala)))
Пример #21
0
    def _handle_report_form(self,
                            crash_info: CrashInfo) -> ReportSubmitDetails:
        details: ReportSubmitDetails
        try:
            vs = self._vs_crash_report()
            details = vs.from_html_vars("_report")
            vs.validate_value(details, "_report")

            # Make the resulting page execute the crash report post request
            url_encoded_params = urlencode_vars([
                ("name", details["name"]),
                ("mail", details["mail"]),
                (
                    "crashdump",
                    base64.b64encode(
                        _pack_crash_report(
                            self._get_serialized_crash_report())).decode(
                                "ascii"),
                ),
            ])
            html.open_div(id_="pending_msg", style="display:none")
            html.show_message(_("Submitting crash report..."))
            html.close_div()
            html.open_div(id_="success_msg", style="display:none")
            html.show_message(
                _("Your crash report has been submitted (ID: ###ID###). Thanks for your participation, "
                  "it is very important for the quality of Checkmk.<br><br>"
                  "Please note:"
                  "<ul>"
                  "<li>In general we do <i>not</i> respond to crash reports, "
                  "except we need further information from you.</li>"
                  "<li>We read every feedback thoroughly, but this might happen "
                  "not before a couple of weeks or even months have passed and is "
                  "often aligned with our release cycle.</li>"
                  "<li>If you are in need of a quick solution for your problem, then "
                  "we can help you within the scope of professional support. If you "
                  "already have a support contract, then please use your personal "
                  "support email address to send us a mail refering to your crash "
                  "report.<br>If you are interested in the details about support, "
                  'you find details on <a href="https://checkmk.com/'
                  'checkmk_support_contract.html" target="_blank">our website</a>.'
                  ))
            html.close_div()
            html.open_div(id_="fail_msg", style="display:none")
            report_url = makeuri_contextless(
                request,
                [
                    ("subject",
                     "Checkmk Crash Report - " + self._get_version()),
                ],
                filename="mailto:" + self._get_crash_report_target(),
            )
            html.show_error(
                _("Failed to send the crash report. Please download it manually and send it "
                  'to <a href="%s">%s</a>') %
                (report_url, self._get_crash_report_target()))
            html.close_div()
            html.javascript("cmk.transfer.submit_crash_report(%s, %s);" %
                            (json.dumps(active_config.crash_report_url),
                             json.dumps(url_encoded_params)))
        except MKUserError as e:
            user_errors.add(e)

        return details
Пример #22
0
def render_point(t, v, color):
    html.javascript("cmk.prediction.render_point(%s, %s, %s);" %
                    (json.dumps(t), json.dumps(v), json.dumps(color)))
Пример #23
0
def render_curve(points, color, width=1, square=False):
    html.javascript(
        "cmk.prediction.render_curve(%s, %s, %d, %d);" %
        (json.dumps(points), json.dumps(color), width, square and 1 or 0))
Пример #24
0
def render_area_reverse(points, color, alpha=1.0):
    html.javascript("cmk.prediction.render_area_reverse(%s, %s, %f);" %
                    (json.dumps(points), json.dumps(color), alpha))
Пример #25
0
 def show(self):
     html.div(_("Loading maps..."), class_="loading")
     html.javascript("cmk.sidebar.fetch_nagvis_snapin_contents()")
Пример #26
0
    def _write_table(
        self,
        rows: TableRows,
        num_rows_unlimited: int,
        actions_enabled: bool,
        actions_visible: bool,
        search_term: Optional[str],
    ) -> None:
        if not self.options["omit_update_header"]:
            row_info = _("1 row") if len(
                rows) == 1 else _("%d rows") % num_rows_unlimited
            html.javascript("cmk.utils.update_row_info(%s);" %
                            json.dumps(row_info))

        table_id = self.id

        num_cols = self._get_num_cols(rows)

        empty_columns = self._get_empty_columns(rows, num_cols)
        if self.options["omit_empty_columns"]:
            num_cols -= len([v for v in empty_columns if v])

        html.open_table(class_=["data", "oddeven"] + self.css)

        # If we have no group headers then paint the headers now
        if self.rows and not isinstance(self.rows[0], GroupHeader):
            self._render_headers(
                actions_enabled,
                actions_visible,
                empty_columns,
            )

        if actions_enabled and actions_visible:
            html.open_tr(class_=["data", "even0", "actions"])
            html.open_td(colspan=num_cols)
            if not html.in_form():
                html.begin_form("%s_actions" % table_id)

            if request.has_var("_%s_sort" % table_id):
                html.open_div(class_=["sort"])
                html.button("_%s_reset_sorting" % table_id, _("Reset sorting"))
                html.close_div()

            if not html.in_form():
                html.begin_form("%s_actions" % table_id)

            html.hidden_fields()
            html.end_form()
            html.close_tr()

        for nr, row in enumerate(rows):
            # Intermediate header
            if isinstance(row, GroupHeader):
                # Show the header only, if at least one (non-header) row follows
                if nr < len(rows) - 1 and not isinstance(
                        rows[nr + 1], GroupHeader):
                    html.open_tr(class_="groupheader")
                    html.open_td(colspan=num_cols)
                    html.h3(row.title)
                    html.close_td()
                    html.close_tr()

                    self._render_headers(actions_enabled, actions_visible,
                                         empty_columns)
                continue

            oddeven_name = "even" if nr % 2 == 0 else "odd"
            class_ = ["data", "%s%d" % (oddeven_name, row.state)]

            if isinstance(row.css, list):
                class_.extend([c for c in row.css if c is not None])
            elif row.css is not None:
                class_.append(row.css)

            html.open_tr(class_=class_,
                         id_=row.id_,
                         onmouseover=row.onmouseover,
                         onmouseout=row.onmouseout)
            for col_index, cell in enumerate(row.cells):
                if self.options["omit_empty_columns"] and empty_columns[
                        col_index]:
                    continue

                html.td(cell.content, class_=cell.css, colspan=cell.colspan)
            html.close_tr()

        if not rows and search_term:
            html.open_tr(class_=["data", "odd0", "no_match"])
            html.td(
                _("Found no matching rows. Please try another search term."),
                colspan=num_cols)
            html.close_tr()

        html.close_table()
Пример #27
0
 def update(self):
     self._show_view_as_dashlet(self._get_view_spec())
     html.javascript(
         'cmk.utils.add_simplebar_scrollbar("dashlet_content_wrapper");')
Пример #28
0
def render_dual_area(lower_points, upper_points, color, alpha=1.0):
    html.javascript("cmk.prediction.render_dual_area(%s, %s, %s, %f);" %
                    (json.dumps(lower_points), json.dumps(upper_points),
                     json.dumps(color), alpha))
Пример #29
0
class UserLoginTwoFactor(Page):
    def page(self) -> None:
        assert user.id is not None

        html.render_headfoot = False
        html.add_body_css_class("login")
        html.add_body_css_class("two_factor")
        make_header(html,
                    _("Two-factor authentication"),
                    Breadcrumb(),
                    javascripts=[])

        html.open_div(id_="login")

        html.open_div(id_="login_window")

        html.open_a(href="https://checkmk.com")
        html.img(
            src=theme.detect_icon_path(icon_name="logo", prefix="mk-"),
            id_="logo",
            class_="custom" if theme.has_custom_logo() else None,
        )
        html.close_a()

        if not is_two_factor_login_enabled(user.id):
            raise MKGeneralException(
                _("Two-factor authentication not enabled"))

        html.begin_form("two_factor_login",
                        method="POST",
                        add_transid=False,
                        action="user_login_two_factor.py")
        html.prevent_password_auto_completion()
        html.hidden_field(
            "_origtarget", origtarget :=
            request.get_url_input("_origtarget", "index.py"))

        if backup_code := request.get_ascii_input("_backup_code"):
            if is_two_factor_backup_code_valid(user.id, backup_code):
                set_two_factor_completed()
                raise HTTPRedirect(origtarget)

        html.label(
            _("Two-factor authentication"),
            for_="webauthn_message",
            id_="label_2fa",
            class_="legend",
        )
        html.div("", id_="webauthn_message")

        with foldable_container(
                treename="webauthn_backup_codes",
                id_="backup_container",
                isopen=False,
                title=_("Use backup code"),
                indent=False,
                save_state=False,
        ):
            html.label(
                "%s:" % _("Backup code"),
                id_="label_pass",
                class_=["legend"],
                for_="_backup_code",
            )
            html.br()
            html.password_input("_backup_code", id_="input_pass", size=None)

            html.open_div(id_="button_text")
            html.button("_use_backup_code",
                        _("Use backup code"),
                        cssclass="hot")
            html.close_div()
            html.close_div()

        if user_errors:
            html.open_div(id_="login_error")
            html.show_user_errors()
            html.close_div()

        html.javascript("cmk.webauthn.login()")

        html.hidden_fields()
        html.end_form()
        html.close_div()
        html.footer()
Пример #30
0
    def _activation_status(self):
        with table_element(
                "site-status",
                title=_("Activation status"),
                searchable=False,
                sortable=False,
                css="activation",
                foldable=Foldable.FOLDABLE_STATELESS,
        ) as table:

            for site_id, site in sort_sites(activation_sites()):
                table.row()

                site_status, status = self._get_site_status(site_id, site)

                is_online = self._site_is_online(status)
                is_logged_in = self._site_is_logged_in(site_id, site)
                has_foreign = self._site_has_foreign_changes(site_id)
                can_activate_all = not has_foreign or user.may(
                    "wato.activateforeign")

                # Disable actions for offline sites and not logged in sites
                if not is_online or not is_logged_in:
                    can_activate_all = False

                need_restart = self._is_activate_needed(site_id)
                need_sync = self.is_sync_needed(site_id)
                need_action = need_restart or need_sync
                nr_changes = len(self._changes_of_site(site_id))

                # Activation checkbox
                table.cell("", css=["buttons"])
                if can_activate_all and nr_changes:
                    html.checkbox("site_%s" % site_id,
                                  need_action,
                                  cssclass="site_checkbox")

                # Iconbuttons
                table.cell(_("Actions"), css=["buttons"])

                if user.may("wato.sites"):
                    edit_url = folder_preserving_link([("mode", "edit_site"),
                                                       ("site", site_id)])
                    html.icon_button(edit_url,
                                     _("Edit the properties of this site"),
                                     "edit")

                # State
                if can_activate_all and need_sync:
                    html.icon_button(
                        url="javascript:void(0)",
                        id_="activate_%s" % site_id,
                        cssclass="activate_site",
                        title=
                        _("This site is not update and needs a replication. Start it now."
                          ),
                        icon="need_replicate",
                        onclick='cmk.activation.activate_changes("site", "%s")'
                        % site_id,
                    )

                if can_activate_all and need_restart:
                    html.icon_button(
                        url="javascript:void(0)",
                        id_="activate_%s" % site_id,
                        cssclass="activate_site",
                        title=
                        _("This site needs a restart for activating the changes. Start it now."
                          ),
                        icon="need_restart",
                        onclick='cmk.activation.activate_changes("site", "%s")'
                        % site_id,
                    )

                if can_activate_all and not need_action:
                    html.icon("siteuptodate", _("This site is up-to-date."))

                site_url = site.get("multisiteurl")
                if site_url:
                    html.icon_button(
                        site_url,
                        _("Open this site's local web user interface"),
                        "url",
                        target="_blank",
                    )

                table.cell(_("Site"),
                           site.get("alias", site_id),
                           css=["narrow nobr"])

                # Livestatus
                table.cell(_("Status"), css=["narrow nobr"])
                html.status_label(content=status,
                                  status=status,
                                  title=_("This site is %s") % status)

                # Livestatus-/Checkmk-Version
                table.cell(_("Version"),
                           site_status.get("livestatus_version", ""),
                           css=["narrow nobr"])

                table.cell(_("Changes"),
                           "%d" % nr_changes,
                           css=["number narrow nobr"])

                table.cell(_("Progress"), css=["repprogress"])
                html.open_div(id_="site_%s_status" % site_id, class_=["msg"])
                html.close_div()
                html.open_div(id_="site_%s_progress" % site_id,
                              class_=["progress"])
                html.close_div()

                table.cell(_("Details"), css=["details"])
                html.open_div(id_="site_%s_details" % site_id)

                last_state = self._last_activation_state(site_id)

                if not is_logged_in:
                    html.write_text(_("Is not logged in.") + " ")

                if not last_state:
                    html.write_text(_("Has never been activated"))
                elif need_action and last_state[
                        "_state"] == activate_changes.STATE_SUCCESS:
                    html.write_text(_("Activation needed"))
                else:
                    html.javascript(
                        "cmk.activation.update_site_activation_state(%s);" %
                        json.dumps(last_state))

                html.close_div()