示例#1
0
def page_add_snapin() -> None:
    if not user.may("general.configure_sidebar"):
        raise MKGeneralException(
            _("You are not allowed to change the sidebar."))

    title = _("Add sidebar element")
    breadcrumb = make_simple_page_breadcrumb(
        mega_menu_registry.menu_customize(), title)
    make_header(html, title, breadcrumb, _add_snapins_page_menu(breadcrumb))

    used_snapins = _used_snapins()

    html.open_div(class_=["add_snapin"])
    for name, snapin_class in sorted(snapin_registry.items()):
        if name in used_snapins:
            continue
        if not snapin_class.may_see():
            continue  # not allowed for this user

        html.open_div(
            class_="snapinadder",
            onmouseover="this.style.cursor='pointer';",
            onclick="window.top.cmk.sidebar.add_snapin('%s')" % name,
        )

        html.open_div(class_=["snapin_preview"])
        html.div("", class_=["clickshield"])
        SidebarRenderer().render_snapin(
            UserSidebarSnapin.from_snapin_type_id(name))
        html.close_div()
        html.div(snapin_class.description(), class_=["description"])
        html.close_div()

    html.close_div()
    html.footer()
示例#2
0
def show_log_list():
    title = _("All problematic logfiles")
    breadcrumb = make_simple_page_breadcrumb(
        mega_menu_registry.menu_monitoring(), title)
    make_header(html, title, breadcrumb, _log_list_page_menu(breadcrumb))

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

    for site, host_name, logs in all_logs():
        if not logs:
            continue

        all_logs_empty = not any(
            parse_file(site, host_name, file_name) for file_name in logs)

        if all_logs_empty:
            continue  # Logfile vanished

        html.h3(
            HTMLWriter.render_a(
                host_name,
                href=makeuri(
                    request,
                    [("site", site), ("host", host_name)],
                ),
            ),
            class_="table",
        )
        list_logs(site, host_name, logs)
    html.footer()
示例#3
0
def _page_not_found() -> Response:
    # TODO: This is a page handler. It should not be located in generic application
    # object. Move it to another place
    if request.has_var("_plain_error"):
        html.write_text(_("Page not found"))
    else:
        title = _("Page not found")
        make_header(
            html,
            title,
            Breadcrumb([
                BreadcrumbItem(
                    title="Nowhere",
                    url=None,
                ),
                BreadcrumbItem(
                    title=title,
                    url="javascript:document.location.reload(false)",
                ),
            ]),
        )
        html.show_error(_("This page was not found. Sorry."))
    html.footer()

    return response
示例#4
0
    def _action(self) -> None:
        assert user.id is not None

        users = userdb.load_users(lock=True)
        user_spec = users[user.id]

        language = request.get_ascii_input_mandatory("language", "")
        # Set the users language if requested to set it explicitly
        if language != "_default_":
            user_spec["language"] = language
            user.language = language
            set_language_cookie(request, response, language)

        else:
            if "language" in user_spec:
                del user_spec["language"]
            user.reset_language()

        # load the new language
        localize(user.language)

        if user.may("general.edit_notifications") and user_spec.get(
                "notifications_enabled"):
            value = _get_input(get_vs_flexible_notifications(),
                               "notification_method")
            user_spec["notification_method"] = value

        # Custom attributes
        if user.may("general.edit_user_attributes"):
            for name, attr in userdb.get_user_attributes():
                if not attr.user_editable():
                    continue

                perm_name = attr.permission()
                if perm_name and not user.may(perm_name):
                    continue

                vs = attr.valuespec()
                value = vs.from_html_vars("ua_" + name)
                vs.validate_value(value, "ua_" + name)
                # TODO: Dynamically fiddling around with a TypedDict is a bit questionable
                user_spec[name] = value  # type: ignore[literal-required]

        userdb.save_users(users, datetime.now())

        flash(_("Successfully updated user profile."))

        # In distributed setups with remote sites where the user can login, start the
        # user profile replication now which will redirect the user to the destination
        # page after completion. Otherwise directly open up the destination page.
        if user.authorized_login_sites():
            back_url = "user_profile_replicate.py?back=user_profile.py"
        else:
            back_url = "user_profile.py"

        # Ensure theme changes are applied without additional user interaction
        html.reload_whole_page(back_url)
        html.footer()

        raise FinalizeRequest(code=200)
示例#5
0
    def _show_form(self) -> None:
        assert user.id is not None

        credentials = load_two_factor_credentials(user.id)
        webauthn_credentials = credentials["webauthn_credentials"]
        backup_codes = credentials["backup_codes"]

        html.begin_form("two_factor", method="POST")
        html.div("", id_="webauthn_message")
        forms.header(_("Credentials"))

        forms.section(_("Registered credentials"), simple=True)
        if webauthn_credentials:
            self._show_credentials(webauthn_credentials)
        else:
            html.i(_("No credentials registered"))

        forms.section(_("Backup codes"), simple=True)
        if backup_codes:
            html.p(
                _("You have %d unused backup codes left. You can use them as one-time password "
                  "if your key is not available.") % len(backup_codes))
            html.i(
                _("If you regenerate backup codes, you automatically invalidate the existing codes."
                  ))
        else:
            html.i(_("No backup codes created yet."))

        forms.end()

        html.hidden_fields()
        html.end_form()
        html.footer()
示例#6
0
    def _show_form(self) -> None:
        assert user.id is not None
        credentials = load_two_factor_credentials(user.id)

        credential_id = request.get_ascii_input_mandatory("_edit")
        credential = credentials["webauthn_credentials"].get(credential_id)
        if credential is None:
            raise MKUserError("_edit", _("The credential does not exist"))

        html.begin_form("profile", method="POST")
        html.prevent_password_auto_completion()
        html.open_div(class_="wato")

        self._valuespec(credential).render_input(
            "profile",
            {
                "registered_at": credential["registered_at"],
                "alias": credential["alias"],
            },
        )

        forms.end()
        html.close_div()
        html.hidden_field("_edit", credential_id)
        html.hidden_fields()
        html.end_form()
        html.footer()
示例#7
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)
示例#8
0
    def _show_page(self, acktime: float, failed_notifications: LivestatusResponse) -> None:
        title = _("Confirm failed notifications")
        breadcrumb = make_simple_page_breadcrumb(mega_menu_registry.menu_monitoring(), title)

        page_menu = self._page_menu(acktime, failed_notifications, breadcrumb)

        make_header(html, title, breadcrumb, page_menu)

        self._show_notification_table(failed_notifications)

        html.footer()
示例#9
0
def page_werk():
    load_werks()
    werk_id = request.get_integer_input_mandatory("werk")
    if werk_id not in g_werks:
        raise MKUserError("werk", _("This werk does not exist."))
    werk = g_werks[werk_id]

    title = ("%s %s - %s") % (_("Werk"), render_werk_id(
        werk, with_link=False), werk["title"])

    breadcrumb = make_main_menu_breadcrumb(mega_menu_registry["help_links"])
    breadcrumb.append(
        BreadcrumbItem(
            title=_("Change log (Werks)"),
            url="change_log.py",
        ))
    breadcrumb.append(make_current_page_breadcrumb_item(title))
    make_header(html, title, breadcrumb, _page_menu_werk(breadcrumb, werk))

    html.open_table(class_=["data", "headerleft", "werks"])

    def werk_table_row(caption, content, css=None):
        html.open_tr()
        html.th(caption)
        html.td(content, class_=css)
        html.close_tr()

    translator = cmk.utils.werks.WerkTranslator()
    werk_table_row(_("ID"), render_werk_id(werk, with_link=False))
    werk_table_row(_("Title"), HTMLWriter.render_b(render_werk_title(werk)))
    werk_table_row(_("Component"), translator.component_of(werk))
    werk_table_row(_("Date"), render_werk_date(werk))
    werk_table_row(_("Checkmk Version"), werk["version"])
    werk_table_row(_("Level"),
                   translator.level_of(werk),
                   css="werklevel werklevel%d" % werk["level"])
    werk_table_row(_("Class"),
                   translator.class_of(werk),
                   css="werkclass werkclass%s" % werk["class"])
    werk_table_row(
        _("Compatibility"),
        translator.compatibility_of(werk),
        css="werkcomp werkcomp%s" % werk["compatible"],
    )
    werk_table_row(_("Description"),
                   render_werk_description(werk),
                   css="nowiki")

    html.close_table()

    html.footer()
示例#10
0
    def _show_form(self) -> None:
        assert user.id is not None

        users = userdb.load_users()

        user_spec: Optional[UserSpec] = users.get(user.id)
        if user_spec is None:
            html.show_warning(_("Sorry, your user account does not exist."))
            html.footer()
            return

        html.begin_form("profile", method="POST")
        html.prevent_password_auto_completion()
        html.open_div(class_="wato")
        forms.header(_("Personal settings"))

        forms.section(_("Username"), simple=True)
        html.write_text(user_spec.get("user_id", user.id))

        forms.section(_("Full name"), simple=True)
        html.write_text(user_spec.get("alias", ""))

        select_language(user_spec)

        # Let the user configure how he wants to be notified
        rulebased_notifications = rulebased_notifications_enabled()
        if (not rulebased_notifications
                and user.may("general.edit_notifications")
                and user_spec.get("notifications_enabled")):
            forms.section(_("Notifications"))
            html.help(
                _("Here you can configure how you want to be notified about host and service problems and "
                  "other monitoring events."))
            get_vs_flexible_notifications().render_input(
                "notification_method", user_spec.get("notification_method"))

        if user.may("general.edit_user_attributes"):
            custom_user_attr_topics = get_user_attributes_by_topic()
            _show_custom_user_attr(user_spec,
                                   custom_user_attr_topics.get("personal", []))
            forms.header(_("User interface settings"))
            _show_custom_user_attr(
                user_spec, custom_user_attr_topics.get("interface", []))

        forms.end()
        html.close_div()
        html.hidden_fields()
        html.end_form()
        html.footer()
示例#11
0
def show_create_view_dialog(next_url=None):
    vs_ds = DatasourceSelection()

    ds = "services"  # Default selection

    title = _("Create view")
    breadcrumb = visuals.visual_page_breadcrumb("views", title, "create")
    make_header(
        html,
        title,
        breadcrumb,
        make_simple_form_page_menu(
            _("View"),
            breadcrumb,
            form_name="create_view",
            button_name="_save",
            save_title=_("Continue"),
        ),
    )

    if request.var("_save") and transactions.check_transaction():
        try:
            ds = vs_ds.from_html_vars("ds")
            vs_ds.validate_value(ds, "ds")

            if not next_url:
                next_url = makeuri(
                    request,
                    [("datasource", ds)],
                    filename="create_view_infos.py",
                )
            else:
                next_url = next_url + "&datasource=%s" % ds
            raise HTTPRedirect(next_url)
        except MKUserError as e:
            html.user_error(e)

    html.begin_form("create_view")
    html.hidden_field("mode", "create")

    forms.header(_("Select Datasource"))
    forms.section(vs_ds.title())
    vs_ds.render_input("ds", ds)
    html.help(vs_ds.help())
    forms.end()

    html.hidden_fields()
    html.end_form()
    html.footer()
示例#12
0
def show_host_log_list(site, host_name):
    title = _("Logfiles of host %s") % host_name
    breadcrumb = _host_log_list_breadcrumb(host_name, title)
    make_header(html, title, breadcrumb,
                _host_log_list_page_menu(breadcrumb, site, host_name))

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

    html.open_table(class_=["data"])
    list_logs(site, host_name, logfiles_of_host(site, host_name))
    html.close_table()

    html.footer()
示例#13
0
def _render_exception(e: Exception, title: str) -> Response:
    if plain_error():
        return Response(
            response=[
                "%s%s\n" % (("%s: " % title) if title else "", e),
            ],
            mimetype="text/plain",
        )

    if not fail_silently():
        make_header(html, title, Breadcrumb())
        html.show_error(str(e))
        html.footer()

    return response
示例#14
0
    def _show_form(self) -> None:
        assert user.id is not None

        users = userdb.load_users()

        change_reason = request.get_ascii_input("reason")

        if change_reason == "expired":
            html.p(_("Your password is too old, you need to choose a new password."))
        elif change_reason == "enforced":
            html.p(_("You are required to change your password before proceeding."))

        user_spec = users.get(user.id)
        if user_spec is None:
            html.show_warning(_("Sorry, your user account does not exist."))
            html.footer()
            return

        locked_attributes = userdb.locked_attributes(user_spec.get("connector"))
        if "password" in locked_attributes:
            raise MKUserError(
                "cur_password",
                _("You can not change your password, because it is " "managed by another system."),
            )

        html.begin_form("profile", method="POST")
        html.prevent_password_auto_completion()
        html.open_div(class_="wato")
        forms.header(self._page_title())

        forms.section(_("Current Password"))
        html.password_input("cur_password", autocomplete="new-password")

        forms.section(_("New Password"))
        html.password_input("password", autocomplete="new-password")

        forms.section(_("New Password Confirmation"))
        html.password_input("password2", autocomplete="new-password")

        forms.end()
        html.close_div()
        html.hidden_fields()
        html.end_form()
        html.footer()
示例#15
0
    def page(self) -> None:
        row = self._get_crash_row()
        crash_info = self._get_crash_info(row)

        title = _("Crash report: %s") % self._crash_id
        breadcrumb = self._breadcrumb(title)
        make_header(html, title, breadcrumb,
                    self._page_menu(breadcrumb, crash_info))

        # Do not reveal crash context information to unauthenticated users or not permitted
        # users to prevent disclosure of internal information
        if not user.may("general.see_crash_reports"):
            html.show_error("<b>%s:</b> %s" %
                            (_("Internal error"), crash_info["exc_value"]))
            html.p(
                _("An internal error occurred while processing your request. "
                  "You can report this issue to your Checkmk administrator. "
                  "Detailed information can be found on the crash report page "
                  "or in <tt>var/log/web.log</tt>."))
            html.footer()
            return

        if request.has_var("_report") and transactions.check_transaction():
            details = self._handle_report_form(crash_info)
        else:
            details = ReportSubmitDetails(name="", mail="")

        if crash_info["crash_type"] == "gui":
            html.show_error("<b>%s:</b> %s" %
                            (_("Internal error"), crash_info["exc_value"]))
            html.p(
                _("An internal error occured while processing your request. "
                  "You can report this issue to the Checkmk team to help "
                  "fixing this issue. Please use the form below for reporting."
                  ))

        self._warn_about_local_files(crash_info)
        self._show_report_form(crash_info, details)
        self._show_crash_report(crash_info)
        self._show_crash_report_details(crash_info, row)

        html.footer()
示例#16
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()
示例#17
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()
示例#18
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()
示例#19
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()
示例#20
0
def page_graph():
    host_name = HostName(request.get_str_input_mandatory("host"))
    service = request.get_str_input_mandatory("service")
    dsname = request.get_str_input_mandatory("dsname")

    breadcrumb = make_service_breadcrumb(host_name, service)
    make_header(
        html,
        _("Prediction for %s - %s - %s") % (host_name, service, dsname),
        breadcrumb,
    )

    # Get current value from perf_data via Livestatus
    current_value = get_current_perfdata(host_name, service, dsname)

    prediction_store = prediction.PredictionStore(host_name, service, dsname)

    timegroup, choices = _load_prediction_information(
        tg_name=request.var("timegroup"),
        prediction_store=prediction_store,
    )

    html.begin_form("prediction")
    html.write_text(_("Show prediction for "))
    html.dropdown("timegroup",
                  choices,
                  deflt=timegroup.name,
                  onchange="document.prediction.submit();")
    html.hidden_fields()
    html.end_form()

    # Get prediction data
    tg_data = prediction_store.get_data(timegroup.name)
    if tg_data is None:
        raise MKGeneralException(_("Missing prediction data."))

    swapped = swap_and_compute_levels(tg_data, timegroup.params)
    vertical_range = compute_vertical_range(swapped)
    legend = [
        ("#000000", _("Reference")),
        ("#ffffff", _("OK area")),
        ("#ffff00", _("Warning area")),
        ("#ff0000", _("Critical area")),
    ]
    if current_value is not None:
        legend.append(("#0000ff", _("Current value: %.2f") % current_value))

    create_graph(timegroup.name, graph_size, timegroup.range, vertical_range,
                 legend)

    if "levels_upper" in timegroup.params:
        render_dual_area(swapped["upper_warn"], swapped["upper_crit"],
                         "#fff000", 0.4)
        render_area_reverse(swapped["upper_crit"], "#ff0000", 0.1)

    if "levels_lower" in timegroup.params:
        render_dual_area(swapped["lower_crit"], swapped["lower_warn"],
                         "#fff000", 0.4)
        render_area(swapped["lower_crit"], "#ff0000", 0.1)

    vscala_low = vertical_range[0]
    vscala_high = vertical_range[1]
    vert_scala = compute_vertical_scala(vscala_low, vscala_high)
    time_scala = [[timegroup.range[0] + i * 3600,
                   "%02d:00" % i] for i in range(0, 25, 2)]
    render_coordinates(vert_scala, time_scala)

    if "levels_lower" in timegroup.params:
        render_dual_area(swapped["average"], swapped["lower_warn"], "#ffffff",
                         0.5)
        render_curve(swapped["lower_warn"], "#e0e000", square=True)
        render_curve(swapped["lower_crit"], "#f0b0a0", square=True)

    if "levels_upper" in timegroup.params:
        render_dual_area(swapped["upper_warn"], swapped["average"], "#ffffff",
                         0.5)
        render_curve(swapped["upper_warn"], "#e0e000", square=True)
        render_curve(swapped["upper_crit"], "#f0b0b0", square=True)
    render_curve(swapped["average"], "#000000")
    render_curve(swapped["average"], "#000000")  # repetition makes line bolder

    # Try to get current RRD data and render it also
    from_time, until_time = timegroup.range
    now = time.time()
    if from_time <= now <= until_time:
        timeseries = prediction.get_rrd_data(host_name, service, dsname, "MAX",
                                             from_time, until_time)
        rrd_data = timeseries.values

        render_curve(rrd_data, "#0000ff", 2)
        if current_value is not None:
            rel_time = (now - prediction.timezone_at(now)) % timegroup.slice
            render_point(timegroup.range[0] + rel_time, current_value,
                         "#0000ff")

    html.footer()
示例#21
0
def user_profile_async_replication_page(back_url: str) -> None:
    sites = list(user.authorized_login_sites().keys())
    user_profile_async_replication_dialog(sites=sites, back_url=back_url)

    html.footer()