def page(self):
        if not self._analyze_sites():
            html.show_message(
                _("Analyze configuration can only be used with the local site and "
                  "distributed WATO slave sites. You currently have no such site configured."
                  ))
            return

        results_by_category = self._perform_tests()

        site_ids = sorted(self._analyze_sites())

        for category_name, results_by_test in sorted(
                results_by_category.items(),
                key=lambda x: ACTestCategories.title(x[0])):
            with table_element(
                    title=ACTestCategories.title(category_name),
                    css="data analyze_config",
                    sortable=False,
                    searchable=False,
            ) as table:

                for test_id, test_results_by_site in sorted(
                        results_by_test.items(),
                        key=lambda x: x[1]["test"]["title"]):
                    self._show_test_row(table, test_id, test_results_by_site,
                                        site_ids)
Example #2
0
def do_commands(what: str, rows: Rows) -> bool:
    confirm_options, title, executor = views.core_command(what, rows[0], 0, len(rows),)[
        1:4
    ]  # just get confirm_options, title and executor

    confirm_title = _("Do you really want to %s") % title
    r = confirm_with_preview(confirm_title, confirm_options)
    if r is not True:
        return r is None  # Show commands on negative answer

    count = 0
    already_executed: Set[CommandSpec] = set()
    for nr, row in enumerate(rows):
        nagios_commands, _confirm_options, title, executor = views.core_command(
            what,
            row,
            nr,
            len(rows),
        )
        for command in nagios_commands:
            if command not in already_executed:
                executor(command, row["site"])
                already_executed.add(command)
                count += 1

    if count > 0:
        html.show_message(_("Successfully sent %d commands.") % count)
    return True  # Show commands again
Example #3
0
def do_log_ack(site, host_name, file_name):
    sites.live().set_auth_domain("action")

    logs_to_ack = []
    if not host_name and not file_name:  # all logs on all hosts
        for this_site, this_host, logs in all_logs():
            for int_filename in logs:
                file_display = form_file_to_ext(int_filename)
                logs_to_ack.append(
                    (this_site, this_host, int_filename, file_display))

    elif host_name and not file_name:  # all logs on one host
        for int_filename in logfiles_of_host(site, host_name):
            file_display = form_file_to_ext(int_filename)
            logs_to_ack.append((site, host_name, int_filename, file_display))

    elif host_name and file_name:  # one log on one host
        int_filename = form_file_to_int(file_name)
        logs_to_ack = [(site, host_name, int_filename,
                        form_file_to_ext(int_filename))]

    else:
        for this_site, this_host, logs in all_logs():
            file_display = form_file_to_ext(file_name)
            if file_name in logs:
                logs_to_ack.append(
                    (this_site, this_host, file_name, file_display))

    ack_msg = _get_ack_msg(host_name, file_name)
    ack = request.var("_ack")

    if not user.may("general.act"):
        html.h1(_("Permission denied"), class_=["error"])
        html.div(_("You are not allowed to acknowledge %s") % ack_msg,
                 class_=["error"])
        html.footer()
        return

    # filter invalid values
    if ack != "1":
        raise MKUserError("_ack", _("Invalid value for ack parameter."))

    for this_site, this_host, int_filename, display_name in logs_to_ack:
        try:
            acknowledge_logfile(this_site, this_host, int_filename,
                                display_name)
        except Exception as e:
            html.show_error(
                _("The log file <tt>%s</tt> of host <tt>%s</tt> could not be deleted: %s."
                  ) % (display_name, this_host, e))
            html.footer()
            return

    html.show_message("<b>%s</b><p>%s</p>" %
                      (_("Acknowledged %s") % ack_msg,
                       _("Acknowledged all messages in %s.") % ack_msg))
    html.footer()
Example #4
0
    def page(self):
        job_status_snapshot = self._job.get_status_snapshot()
        if job_status_snapshot.is_active():
            html.show_message(
                _('Parent scan currently running in <a href="%s">background</a>.')
                % self._job.detail_url()
            )
            return

        self._show_start_form()
Example #5
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)
Example #6
0
    def page(self):
        user.need_permission("wato.services")

        job_status_snapshot = self._job.get_status_snapshot()
        if job_status_snapshot.is_active():
            html.show_message(
                _('Bulk discovery currently running in <a href="%s">background</a>.'
                  ) % self._job.detail_url())
            return

        self._show_start_form()
Example #7
0
    def page(self):
        self._options.update(self._get_audit_log_options_from_request())

        audit = self._parse_audit_log()

        if not audit:
            html.show_message(_("Found no matching entry."))

        elif self._options["display"] == "daily":
            self._display_daily_audit_log(audit)

        else:
            self._display_multiple_days_audit_log(audit)
Example #8
0
    def delete_job(self):
        job_id = request.var(self.delete_job_var)
        if not job_id:
            return

        job = GUIBackgroundJob(job_id=job_id)
        if not job.is_available():
            return

        if job.may_delete():
            job.delete()
            self._did_delete_job = True
            html.show_message(_("Background job has been deleted"))
Example #9
0
    def page(self) -> None:
        title = _("Replicate user profile")
        breadcrumb = make_simple_page_breadcrumb(
            mega_menu_registry.menu_user(), title)
        make_header(html, title, breadcrumb, self._page_menu(breadcrumb))

        for message in get_flashed_messages():
            html.show_message(message)

        # Now, if in distributed environment where users can login to remote sites, set the trigger for
        # pushing the new user profile to the remote sites asynchronously
        user_profile_async_replication_page(
            back_url=request.get_url_input("back", "user_profile.py"))
Example #10
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()),
                )
            )
Example #11
0
    def page(self) -> None:
        title = self._page_title()
        breadcrumb = self._breadcrumb()
        make_header(html, title, breadcrumb, self._page_menu(breadcrumb))

        if transactions.check_transaction():
            try:
                self._action()
            except MKUserError as e:
                user_errors.add(e)

        for message in get_flashed_messages():
            html.show_message(message)

        html.show_user_errors()

        self._show_form()
Example #12
0
    def stop_job(self):
        job_id = request.var(self.stop_job_var)
        if not job_id:
            return

        job = GUIBackgroundJob(job_id)
        if not job.is_available():
            return

        if not job.is_active():
            html.show_message(
                _("No longer able to stop job. Background job just finished."))
            return

        if job.may_stop():
            job.stop()
            self._did_stop_job = True
            html.show_message(_("Background job has been stopped"))
Example #13
0
    def page(self) -> None:
        acktime = request.get_float_input_mandatory("acktime", time.time())
        if request.var("_confirm"):
            _acknowledge_failed_notifications(acktime, time.time())

            if user.authorized_login_sites():
                title = _("Replicate user profile")
                breadcrumb = make_simple_page_breadcrumb(
                    mega_menu_registry.menu_monitoring(), title
                )
                make_header(html, title, breadcrumb)

                for message in get_flashed_messages():
                    html.show_message(message)
                user_profile_async_replication_page(back_url="clear_failed_notifications.py")
                return

        failed_notifications = load_failed_notifications(before=acktime, after=acknowledged_time())
        self._show_page(acktime, failed_notifications)
        if request.var("_confirm"):
            html.reload_whole_page()
Example #14
0
    def page(self) -> cmk.gui.pages.PageResult:
        breadcrumb = make_simple_page_breadcrumb(
            mega_menu_registry["help_links"], self._title())

        load_werks()
        werk_table_options = _werk_table_options_from_request()

        make_header(
            html,
            self._title(),
            breadcrumb,
            self._page_menu(breadcrumb, werk_table_options),
        )

        for message in get_flashed_messages():
            html.show_message(message)

        handle_acknowledgement()

        html.open_div(class_="wato")
        render_werks_table(werk_table_options)
        html.close_div()

        html.footer()
Example #15
0
def handle_acknowledgement():
    if not transactions.check_transaction():
        return

    if request.var("_werk_ack"):
        werk_id = request.get_integer_input_mandatory("_werk_ack")
        if werk_id not in g_werks:
            raise MKUserError("werk", _("This werk does not exist."))
        werk = g_werks[werk_id]

        if werk["compatible"] == "incomp_unack":
            acknowledge_werk(werk)
            html.show_message(
                _("Werk %s - %s has been acknowledged.") % (render_werk_id(
                    werk, with_link=True), render_werk_title(werk)))
            load_werks()  # reload ack states after modification
            render_unacknowleged_werks()

    elif request.var("_ack_all"):
        num = len(unacknowledged_incompatible_werks())
        acknowledge_all_werks()
        flash(_("%d incompatible Werks have been acknowledged.") % num)
        load_werks()  # reload ack states after modification
        html.reload_whole_page()
Example #16
0
def show_file(site, host_name, file_name):
    int_filename = form_file_to_int(file_name)

    title = _("Logfiles of Host %s: %s") % (host_name, int_filename)
    breadcrumb = _show_file_breadcrumb(host_name, title)
    make_header(
        html, title, breadcrumb,
        _show_file_page_menu(breadcrumb, site, host_name, int_filename))

    if request.has_var("_ack") and not request.var("_do_actions") == _("No"):
        do_log_ack(site, host_name, file_name)
        return

    try:
        log_chunks = parse_file(site,
                                host_name,
                                int_filename,
                                hidecontext=request.var("_hidecontext",
                                                        "no") == "yes")
    except Exception as e:
        if active_config.debug:
            raise
        html.show_error(_("Unable to show logfile: <b>%s</b>") % e)
        html.footer()
        return

    if log_chunks is None:
        html.show_error(_("The logfile does not exist on site."))
        html.footer()
        return

    if log_chunks == []:
        html.show_message(
            _("This logfile contains no unacknowledged messages."))
        html.footer()
        return

    html.open_div(id_="logwatch")
    for log in log_chunks:
        html.open_table(class_="groupheader")
        html.open_tr()
        html.td(form_level(log["level"]), class_=form_level(log["level"]))
        html.td(form_datetime(log["datetime"]), class_="date")
        html.close_tr()
        html.close_table()

        html.open_table(class_=["section"])
        for line in log["lines"]:
            html.open_tr(class_=line["class"])
            html.open_td(class_="lines")
            html.icon_button(
                analyse_url(site, host_name, int_filename, line["line"]),
                _("Analyze this line"),
                "analyze",
            )
            html.write_text(line["line"].replace(" ", "&nbsp;").replace(
                "\1", "<br>"))
            html.close_td()
            html.close_tr()

        html.close_table()

    html.close_div()
    html.footer()
Example #17
0
    def _show_configuration_variables(self) -> None:
        search = self._search

        at_least_one_painted = False
        html.open_div(class_="globalvars")
        for group, config_variables in self.iter_all_configuration_variables():
            header_is_painted = False  # needed for omitting empty groups

            for config_variable in config_variables:
                varname = config_variable.ident()
                valuespec = config_variable.valuespec()

                if self._show_only_modified and varname not in self._current_settings:
                    continue

                help_text = valuespec.help() or ""
                title_text = valuespec.title() or ""

                if (search and search not in group.title().lower() and search
                        not in config_variable.domain().ident().lower()
                        and search not in varname
                        and search not in help_text.lower()
                        and search not in title_text.lower()):
                    continue  # skip variable when search is performed and nothing matches
                at_least_one_painted = True

                if not header_is_painted:
                    # always open headers when searching
                    forms.header(group.title(),
                                 isopen=search or self._show_only_modified)
                    header_is_painted = True

                default_value = self._default_values[varname]

                edit_url = folder_preserving_link([
                    ("mode", self.edit_mode_name),
                    ("varname", varname),
                    ("site", request.var("site", "")),
                ])
                title = HTMLWriter.render_a(
                    title_text,
                    href=edit_url,
                    class_="modified"
                    if varname in self._current_settings else None,
                    title=escaping.strip_tags(help_text),
                )

                if varname in self._current_settings:
                    value = self._current_settings[varname]
                elif varname in self._global_settings:
                    value = self._global_settings[varname]
                else:
                    value = default_value

                try:
                    to_text = valuespec.value_to_html(value)
                except Exception:
                    logger.exception("error converting %r to text", value)
                    to_text = html.render_error(
                        _("Failed to render value: %r") % value)

                # Is this a simple (single) value or not? change styling in these cases...
                simple = True
                if "\n" in to_text or "<td>" in to_text:
                    simple = False
                forms.section(title, simple=simple)

                if varname in self._current_settings:
                    modified_cls = ["modified"]
                    value_title: Optional[str] = _(
                        "This option has been modified.")
                elif varname in self._global_settings:
                    modified_cls = ["modified globally"]
                    value_title = _(
                        "This option has been modified in global settings.")
                else:
                    modified_cls = []
                    value_title = None

                if is_a_checkbox(valuespec):
                    html.open_div(class_=["toggle_switch_container"] +
                                  modified_cls + (["on"] if value else []))
                    html.toggle_switch(
                        enabled=value,
                        help_txt=_("Immediately toggle this setting"),
                        href=makeactionuri(request, transactions,
                                           [("_action", "toggle"),
                                            ("_varname", varname)]),
                        class_=modified_cls,
                        title=value_title,
                    )
                    html.close_div()

                else:
                    html.a(to_text,
                           href=edit_url,
                           class_=modified_cls,
                           title=value_title)

            if header_is_painted:
                forms.end()
        if not at_least_one_painted and search:
            html.show_message(
                _("Did not find any global setting matching your search."))
        html.close_div()
Example #18
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
Example #19
0
    def _end(self) -> None:
        if not self.rows and self.options["omit_if_empty"]:
            return

        if self.options["output_format"] == "csv":
            self._write_csv(csv_separator=request.get_str_input_mandatory(
                "csv_separator", ";"))
            return

        container: ContextManager[bool] = nullcontext(False)
        if self.title:
            if self.options["foldable"] in [
                    Foldable.FOLDABLE_SAVE_STATE,
                    Foldable.FOLDABLE_STATELESS,
            ]:
                html.open_div(class_="foldable_wrapper")
                container = foldable_container(
                    treename="table",
                    id_=self.id,
                    isopen=self.isopen,
                    indent=False,
                    title=HTMLWriter.render_h3(self.title,
                                               class_=["treeangle", "title"]),
                    save_state=self.options["foldable"] ==
                    Foldable.FOLDABLE_SAVE_STATE,
                )
            else:
                html.h3(self.title, class_="table")

        with container:
            if self.help:
                html.help(self.help)

            if not self.rows:
                html.div(self.empty_text, class_="info")
                return

            # Controls whether or not actions are available for a table
            rows, actions_visible, search_term = self._evaluate_user_opts()

            # Apply limit after search / sorting etc.
            num_rows_unlimited = len(rows)
            limit = self.limit
            if limit:
                # only use rows up to the limit plus the fixed rows
                limited_rows = []
                for index in range(num_rows_unlimited):
                    row = rows[index]
                    if index < limit or isinstance(row,
                                                   GroupHeader) or row.fixed:
                        limited_rows.append(row)
                # Display corrected number of rows
                num_rows_unlimited -= len([
                    r for r in limited_rows
                    if isinstance(row, GroupHeader) or r.fixed
                ])
                rows = limited_rows

            # Render header
            if self.limit_hint is not None:
                num_rows_unlimited = self.limit_hint

            if limit and num_rows_unlimited > limit:

                html.show_message(
                    _("This table is limited to show only %d of %d rows. "
                      'Click <a href="%s">here</a> to disable the limitation.')
                    % (limit, num_rows_unlimited,
                       makeuri(request, [("limit", "none")])))

            self._write_table(rows, num_rows_unlimited,
                              self._show_action_row(), actions_visible,
                              search_term)

        if self.title and self.options["foldable"] in [
                Foldable.FOLDABLE_SAVE_STATE,
                Foldable.FOLDABLE_STATELESS,
        ]:
            html.close_div()

        return
Example #20
0
def _wato_page_handler(current_mode: str,
                       mode_permissions: Optional[List[PermissionName]],
                       mode_class: Type[WatoMode]) -> None:
    # Check general permission for this mode
    if mode_permissions is not None and not user.may("wato.seeall"):
        _ensure_mode_permissions(mode_permissions)

    mode = mode_class()

    # Do actions (might switch mode)
    if transactions.is_transaction():
        try:
            user.need_permission("wato.edit")

            # Even if the user has seen this mode because auf "seeall",
            # he needs an explicit access permission for doing changes:
            if user.may("wato.seeall"):
                if mode_permissions:
                    _ensure_mode_permissions(mode_permissions)

            if (cmk.gui.watolib.read_only.is_enabled()
                    and not cmk.gui.watolib.read_only.may_override()):
                raise MKUserError(None, cmk.gui.watolib.read_only.message())

            result = mode.action()
            if isinstance(result, (tuple, str, bool)):
                raise MKGeneralException(
                    f'WatoMode "{current_mode}" returns unsupported return value: {result!r}'
                )

            # We assume something has been modified and increase the config generation ID by one.
            update_config_generation()

            if active_config.wato_use_git:
                do_git_commit()

            # Handle two cases:
            # a) Don't render the page content after action
            #    (a confirm dialog is displayed by the action, or a non-HTML content was sent)
            # b) Redirect to another page
            if isinstance(result, FinalizeRequest):
                raise result

        except MKUserError as e:
            user_errors.add(e)

        except MKAuthException as e:
            user_errors.add(MKUserError(None, e.args[0]))

    breadcrumb = make_main_menu_breadcrumb(
        mode.main_menu()) + mode.breadcrumb()
    page_menu = mode.page_menu(breadcrumb)
    wato_html_head(
        title=mode.title(),
        breadcrumb=breadcrumb,
        page_menu=page_menu,
        show_body_start=display_options.enabled(display_options.H),
        show_top_heading=display_options.enabled(display_options.T),
    )

    if not transactions.is_transaction() or (
            cmk.gui.watolib.read_only.is_enabled()
            and cmk.gui.watolib.read_only.may_override()):
        _show_read_only_warning()

    # Show outcome of failed action on this page
    html.show_user_errors()

    # Show outcome of previous page (that redirected to this one)
    for message in get_flashed_messages():
        html.show_message(message)

    # Show content
    mode.handle_page()

    if is_sidebar_reload_needed():
        html.reload_whole_page()

    wato_html_footer(show_body_end=display_options.enabled(display_options.H))
Example #21
0
    def page(self):
        html.open_div(id_="ldap")
        html.open_table()
        html.open_tr()

        html.open_td()
        html.begin_form("connection", method="POST")
        html.prevent_password_auto_completion()
        vs = self._valuespec()
        vs.render_input("connection", self._connection_cfg)
        vs.set_focus("connection")
        html.hidden_fields()
        html.end_form()
        html.close_td()

        html.open_td(style="padding-left:10px;vertical-align:top")
        html.h2(_("Diagnostics"))
        if not request.var("_test") or not self._connection_id:
            html.show_message(
                HTML("<p>%s</p><p>%s</p>" % (
                    _("You can verify the single parts of your ldap configuration using this "
                      "dialog. Simply make your configuration in the form on the left side and "
                      'hit the "Save & Test" button to execute the tests. After '
                      "the page reload, you should see the results of the test here."
                      ),
                    _("If you need help during configuration or experience problems, please refer "
                      'to the <a target="_blank" '
                      'href="https://checkmk.com/checkmk_multisite_ldap_integration.html">'
                      "LDAP Documentation</a>."),
                )))
        else:
            connection = userdb.get_connection(self._connection_id)
            assert isinstance(connection, LDAPUserConnector)

            for address in connection.servers():
                html.h3("%s: %s" % (_("Server"), address))
                with table_element("test", searchable=False) as table:
                    for title, test_func in self._tests():
                        table.row()
                        try:
                            state, msg = test_func(connection, address)
                        except Exception as e:
                            state = False
                            msg = _("Exception: %s") % e
                            logger.exception("error testing LDAP %s for %s",
                                             title, address)

                        if state:
                            img = html.render_icon("success", _("Success"))
                        else:
                            img = html.render_icon("failed", _("Failed"))

                        table.cell(_("Test"), title)
                        table.cell(_("State"), img)
                        table.cell(_("Details"), msg)

            connection.disconnect()

        html.close_td()
        html.close_tr()
        html.close_table()
        html.close_div()
Example #22
0
    def _show_master_control_site(
        self,
        site_id: sites.SiteId,
        site_status_info: Dict[sites.SiteId, List],
        items: List[Tuple[str, str]],
    ) -> None:
        site_state = sites.states().get(site_id)

        if not site_state:
            html.show_error(_("Site state is unknown"))
            return

        if site_state["state"] == "dead":
            html.show_error(str(site_state["exception"]))
            return

        if site_state["state"] == "disabled":
            html.show_message(_("Site is disabled"))
            return

        if site_state["state"] == "unknown":
            if site_state.get("exception"):
                html.show_error(str(site_state["exception"]))
            else:
                html.show_error(_("Site state is unknown"))
            return

        is_cmc = site_state["program_version"].startswith("Check_MK ")

        try:
            site_info = site_status_info[site_id]
        except KeyError:
            html.show_error(_("Site state is unknown"))
            return

        html.open_table(class_="master_control")
        for i, (colname, title) in enumerate(items):
            # Do not show event handlers on Checkmk Micro Core
            if is_cmc and title == _("Event handlers"):
                continue

            if not is_cmc and title == _("Alert handlers"):
                continue

            colvalue = site_info[i]
            url = makeactionuri_contextless(
                request,
                transactions,
                [
                    ("site", site_id),
                    ("switch", colname),
                    ("state", "%d" % (1 - colvalue)),
                ],
                filename="switch_master_state.py",
            )
            onclick = (
                "cmk.ajax.get_url('%s', cmk.utils.update_contents, 'snapin_master_control')" % url
            )

            html.open_tr()
            html.td(title, class_="left")
            html.open_td()
            html.toggle_switch(
                enabled=colvalue,
                help_txt=_("Switch '%s' to '%s'") % (title, _("off") if colvalue else _("on")),
                onclick=onclick,
            )
            html.close_td()
            html.close_tr()

        html.close_table()
Example #23
0
 def _activation_msg(self):
     html.open_div(id_="async_progress_msg")
     if message := self._get_initial_message():
         html.show_message(message)