예제 #1
0
파일: bi.py 프로젝트: gugas1nwork/checkmk
    def _gen_node(self, tree, height, show_host):
        leaves: List[Any] = []
        for node in tree[3]:
            if not node[2].get("hidden"):
                leaves += self._gen_table(node, height - 1, show_host)

        with html.plugged():
            html.open_div(class_="aggr_tree")
            with self._show_node(tree, show_host):
                html.write_text(tree[2]["title"])
            html.close_div()
            content = HTML(html.drain())

        if leaves:
            leaves[0][2].append((len(leaves), content))

        return leaves
예제 #2
0
파일: roles.py 프로젝트: tboerger/checkmk
    def page(self):
        with table_element("roles") as table:

            users = userdb.load_users()
            for rid, role in sorted(self._roles.items(), key=lambda a: (a[1]["alias"], a[0])):
                table.row()

                # Actions
                table.cell(_("Actions"), css="buttons")
                edit_url = watolib.folder_preserving_link([("mode", "edit_role"), ("edit", rid)])
                clone_url = make_action_link([("mode", "roles"), ("_clone", rid)])
                delete_url = make_confirm_link(
                    url=make_action_link([("mode", "roles"), ("_delete", rid)]),
                    message=_("Do you really want to delete the role %s?") % rid,
                )
                html.icon_button(edit_url, _("Properties"), "edit")
                html.icon_button(clone_url, _("Clone"), "clone")
                if not role.get("builtin"):
                    html.icon_button(delete_url, _("Delete this role"), "delete")

                # ID
                table.text_cell(_("Name"), rid)

                # Alias
                table.text_cell(_("Alias"), role["alias"])

                # Type
                table.cell(_("Type"), _("builtin") if role.get("builtin") else _("custom"))

                # Modifications
                table.cell(
                    _("Modifications"), "<span title='%s'>%s</span>" %
                    (_("That many permissions do not use the factory defaults."),
                     len(role["permissions"])))

                # Users
                table.cell(
                    _("Users"),
                    HTML(", ").join([
                        html.render_a(
                            user.get("alias", user_id),
                            watolib.folder_preserving_link([("mode", "edit_user"),
                                                            ("edit", user_id)]))
                        for (user_id, user) in users.items()
                        if rid in user["roles"]
                    ]))
예제 #3
0
def render_graph_html(graph_artwork, graph_data_range,
                      graph_render_options) -> HTML:
    graph_render_options = artwork.add_default_render_options(
        graph_render_options)

    with output_funnel.plugged():
        _show_graph_html_content(graph_artwork, graph_data_range,
                                 graph_render_options)
        html_code = HTML(output_funnel.drain())

    return html.render_javascript(
        'cmk.graphs.create_graph(%s, %s, %s, %s);' %
        (json.dumps(html_code), json.dumps(graph_artwork),
         json.dumps(graph_render_options),
         json.dumps(
             graph_ajax_context(graph_artwork, graph_data_range,
                                graph_render_options))))
예제 #4
0
def render_werk_description(werk) -> HTML:
    with output_funnel.plugged():
        html.open_p()
        in_list = False
        in_code = False
        for line in werk["body"]:
            if line.startswith("LI:"):
                if not in_list:
                    html.open_ul()
                    in_list = True
                html.li(line[3:])
            else:
                if in_list:
                    html.close_ul()
                    in_list = False

                if line.startswith("H2:"):
                    html.h3(line[3:])
                elif line.startswith("C+:"):
                    html.open_pre(class_="code")
                    in_code = True
                elif line.startswith("F+:"):
                    file_name = line[3:]
                    if file_name:
                        html.div(file_name, class_="filename")
                    html.open_pre(class_="file")
                    in_code = True
                elif line.startswith("C-:") or line.startswith("F-:"):
                    html.close_pre()
                    in_code = False
                elif line.startswith("OM:"):
                    html.write_text("OMD[mysite]:~$ ")
                    html.b(line[3:])
                elif line.startswith("RP:"):
                    html.write_text("root@myhost:~# ")
                    html.b(line[3:])
                elif not line.strip() and not in_code:
                    html.p("")
                else:
                    html.write_text(line + "\n")

        if in_list:
            html.close_ul()

        html.close_p()
        return HTML(output_funnel.drain())
예제 #5
0
def _render_werk_options_form(werk_table_options: Dict[str, Any]) -> HTML:
    with output_funnel.plugged():
        html.begin_form("werks")
        html.hidden_field("wo_set", "set")

        _show_werk_options_controls()

        html.open_div(class_="side_popup_content")
        for name, height, vs, _default_value in _werk_table_option_entries():
            html.render_floating_option(name, height, "wo_", vs,
                                        werk_table_options[name])
        html.close_div()

        html.hidden_fields()
        html.end_form()

        return HTML(output_funnel.drain())
예제 #6
0
    def page(self):
        html.open_table(class_=["data", "headerleft"])

        html.open_tr()
        html.th(_("Title"))
        html.open_td()
        html.b(self._manpage["header"]["title"])
        html.close_td()
        html.close_tr()

        html.open_tr()
        html.th(_("Name of plugin"))
        html.open_td()
        html.tt(self._check_type)
        html.close_td()
        html.close_tr()

        html.open_tr()
        html.th(_("Description"))
        html.td(self._manpage_text(self._manpage["header"]["description"]))
        html.close_tr()

        if self._manpage["type"] == "check_mk":
            html.open_tr()
            html.th(_("Service name"))
            html.td(
                HTML(self._manpage["service_description"].replace(
                    "%s", "&#9744;")))
            html.close_tr()

            check_ruleset_name = self._manpage.get("check_ruleset_name")
            if check_ruleset_name is not None:
                self._show_ruleset("checkgroup_parameters:%s" %
                                   check_ruleset_name)

            cluster = self._manpage["header"].get("cluster")
            if cluster:
                html.open_tr()
                html.th(_("Cluster behaviour"))
                html.td(self._manpage_text(cluster))
                html.close_tr()
        else:
            self._show_ruleset("active_checks:%s" % self._check_type[6:])

        html.close_table()
예제 #7
0
    def _warn_about_local_files(self, crash_info):
        if crash_info["crash_type"] == "check":
            files = []
            for filepath, _lineno, _func, _line in crash_info["exc_traceback"]:
                if "/local/" in filepath:
                    files.append(filepath)

            if files:
                warn_text = _(
                    "The following files located in the local hierarchy of your site are involved in this exception:"
                )
                warn_text += html.render_ul(
                    HTML("\n").join(map(html.render_li, files)))
                warn_text += _(
                    "Maybe these files are not compatible with your current Checkmk "
                    "version. Please verify and only report this crash when you think "
                    "this should be working.")
                html.show_warning(warn_text)
예제 #8
0
def render_mobile_list(rows, view, group_cells, cells, num_columns,
                       show_checkboxes):
    if not html.mobile:
        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.open_p(class_=["ui-li-aside", "ui-li-desc", rendered_class])
            html.write(rendered_content)
            html.close_p()

            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.open_span(class_=rendered_class)
                    html.write(rendered_content)
                    html.close_span()
                    html.close_p()

        html.close_li()
    html.close_ul()
    html.javascript('$("ul.mobilelist a").attr("data-ajax", "false");')
예제 #9
0
    def action(self) -> ActionResult:
        renaming_config = self._vs_renaming_config().from_html_vars("")
        self._vs_renaming_config().validate_value(renaming_config, "")
        renamings = self._collect_host_renamings(renaming_config)

        if not renamings:
            flash(_("No matching host names"))
            return None

        warning = self._renaming_collision_error(renamings)
        if warning:
            flash(warning)
            return None

        message = _(
            "<b>Do you really want to rename to following hosts? This involves a restart of the monitoring core!</b>"
        )
        message += "<table>"
        for _folder, host_name, target_name in renamings:
            message += u"<tr><td>%s</td><td> → %s</td></tr>" % (host_name,
                                                                target_name)
        message += "</table>"

        nr_rename = len(renamings)
        c = _confirm(
            _("Confirm renaming of %d %s") %
            (nr_rename, ungettext("host", "hosts", nr_rename)), HTML(message))
        if c:
            title = _("Renaming of %s") % ", ".join(u"%s → %s" % x[1:]
                                                    for x in renamings)
            host_renaming_job = RenameHostsBackgroundJob(title=title)
            host_renaming_job.set_function(rename_hosts_background_job,
                                           renamings)

            try:
                host_renaming_job.start()
            except background_job.BackgroundJobAlreadyRunning as e:
                raise MKGeneralException(
                    _("Another host renaming job is already running: %s") % e)

            return redirect(host_renaming_job.detail_url())
        if c is False:  # not yet confirmed
            return FinalizeRequest(code=200)
        return None  # browser reload
예제 #10
0
def query_limit_exceeded_warn(limit, user_config):
    # type: (Optional[int], LoggedInUser) -> None
    """Compare query reply against limits, warn in the GUI about incompleteness"""
    text = HTML(_("Your query produced more than %d results. ") % limit)

    if html.request.get_ascii_input(
            "limit", "soft") == "soft" and user_config.may("general.ignore_soft_limit"):
        text += html.render_a(_('Repeat query and allow more results.'),
                              target="_self",
                              href=html.makeuri([("limit", "hard")]))
    elif html.request.get_ascii_input("limit") == "hard" and user_config.may(
            "general.ignore_hard_limit"):
        text += html.render_a(_('Repeat query without limit.'),
                              target="_self",
                              href=html.makeuri([("limit", "none")]))

    text += " " + _(
        "<b>Note:</b> the shown results are incomplete and do not reflect the sort order.")
    html.show_warning(text)
예제 #11
0
    def _render_tag_tree_level(self, tree_spec, path, cwd, title, tree):
        if (not self._is_tag_subdir(path=path, cwd=cwd) and
                not self._is_tag_subdir(path=cwd, cwd=path)):
            return

        if path != cwd and self._is_tag_subdir(path, cwd):
            bullet = self._tag_tree_bullet(self._tag_tree_worst_state(tree), path, False)
            if self._tag_tree_has_svc_problems(tree):
                bullet += html.render_icon_button(
                    self._tag_tree_url(tree_spec, path, "svcproblems"),
                    _("Show the service problems contained in this branch"),
                    "svc_problems",
                    target="main")

            if path:
                html.begin_foldable_container("tag-tree", ".".join(map(str, path)), False,
                                              HTML(bullet + title))

        for (node_title, node_value), subtree in sorted(tree.get("_children", {}).items()):
            subpath = path + [node_value or ""]
            url = self._tag_tree_url(tree_spec, subpath, "allhosts")

            if "_num_hosts" in subtree:
                node_title += " (%d)" % subtree["_num_hosts"]

            node_title = html.render_a(node_title, href=url, target="main")

            if "_children" not in subtree:
                if self._is_tag_subdir(path, cwd):
                    html.write(self._tag_tree_bullet(subtree.get("_state", 0), subpath, True))
                    if subtree.get("_svc_problems"):
                        url = self._tag_tree_url(tree_spec, subpath, "svcproblems")
                        html.icon_button(url,
                                         _("Show the service problems contained in this branch"),
                                         "svc_problems",
                                         target="main")
                    html.write(node_title)
                    html.br()
            else:
                self._render_tag_tree_level(tree_spec, subpath, cwd, node_title, subtree)

        if path and path != cwd and self._is_tag_subdir(path, cwd):
            html.end_foldable_container()
예제 #12
0
def insert_manpage_links(text: str) -> HTML:
    parts = text.replace(",", " ").split()
    new_parts: List[HTML] = []
    check_regex = re.compile(r"[-_\.a-z0-9]")
    for part in parts:
        if check_regex.match(part) and os.path.exists(
                cmk.utils.paths.check_manpages_dir + "/" + part):
            url = makeuri_contextless(
                request,
                [
                    ("mode", "check_manpage"),
                    ("check_type", part),
                ],
                filename="wato.py",
            )
            new_parts.append(html.render_a(content=part, href=url))
        else:
            new_parts.append(escape_to_html(part))
    return HTML(" ").join(new_parts)
예제 #13
0
        def render_list(ids, links):
            n = 0
            for entry in links:
                n += 1
                try:
                    if isinstance(entry[1], type(True)):
                        idss = ids + [str(n)]
                        id_ = '/'.join(idss)
                        html.begin_foldable_container("customlinks",
                                                      id_,
                                                      isopen=entry[1],
                                                      title=entry[0],
                                                      icon="foldable_sidebar")
                        render_list(idss, entry[2])
                        html.end_foldable_container()
                    elif isinstance(entry[1], str):
                        frame = entry[3] if len(entry) > 3 else "main"

                        if len(entry) > 2 and entry[2]:
                            icon_file = entry[2]

                            # Old configs used files named "link_<name>.gif". Those .gif files have
                            # been removed from Checkmk. Replacing such images with the default icon
                            if icon_file.endswith(".gif"):
                                icon_name = "link"
                            else:
                                icon_name = icon_file.rsplit(".",
                                                             1)[0].replace(
                                                                 "icon_", "")
                        else:
                            icon_name = "link"

                        linktext = HTML(
                            html.render_icon(icon_name) + " " + entry[0])

                        simplelink(linktext, entry[1], frame)
                    else:
                        html.write_text(
                            _("Second part of tuple must be list or string, not %s\n"
                              ) % str(entry[1]))
                except Exception as e:
                    html.write_text(
                        _("invalid entry %s: %s<br>\n") % (entry, e))
예제 #14
0
def jqm_page_index_topic_renderer(topic: str, items: Items) -> None:
    has_items_for_topic = any(i for i in items if i[0] == topic)
    if not has_items_for_topic:
        return

    html.p(topic)
    html.open_ul(**{"data-role": "listview", "data-inset": "true"})
    for top, href, title in items:
        if top == topic:
            html.open_li()
            html.open_a(href=href,
                        **{
                            "data-ajax": "false",
                            "data-transition": "flip"
                        })
            html.write_html(HTML(title))
            html.close_a()
            html.close_li()
    html.close_ul()
예제 #15
0
    def action(self):
        if html.request.var("_reset"):
            if not is_a_checkbox(self._valuespec):
                c = wato_confirm(
                    _("Resetting configuration variable"),
                    _("Do you really want to reset this configuration variable "
                      "back to its default value?"))
                if c is False:
                    return ""
                if c is None:
                    return None
            elif not html.check_transaction():
                return

            try:
                del self._current_settings[self._varname]
            except KeyError:
                pass

            msg: Union[
                HTML,
                str] = _("Resetted configuration variable %s to its default."
                         ) % self._varname
        else:
            new_value = self._valuespec.from_html_vars("ve")
            self._valuespec.validate_value(new_value, "ve")
            self._current_settings[self._varname] = new_value
            msg = _("Changed global configuration variable %s to %s.") \
                  % (self._varname, self._valuespec.value_to_text(new_value))
            # FIXME: THIS HTML(...) is needed because we do not know what we get from value_to_text!!
            msg = HTML(msg)

        self._save()
        watolib.add_change("edit-configvar",
                           msg,
                           sites=self._affected_sites(),
                           domains=[self._config_variable.domain()],
                           need_restart=self._config_variable.need_restart())

        page_menu = self.parent_mode()
        assert page_menu is not None
        return page_menu.name()
예제 #16
0
    def _sidebar_foot(self, user_config):
        html.open_div(id_="side_footer")
        if config.user.may("general.configure_sidebar"):
            html.icon_button("sidebar_add_snapin.py",
                             _("Add snapin to the sidebar"),
                             "sidebar_addsnapin",
                             target="main")
        # editing the profile is not possible on remote sites which are sync targets
        # of a central WATO system
        if config.wato_enabled and \
           (config.user.may("general.edit_profile") or config.user.may("general.change_password")):
            html.icon_button(
                "user_profile.py",
                _("Edit your personal settings, change your password"),
                "sidebar_settings",
                target="main")
        if config.user.may(
                "general.logout") and not config.auth_by_http_header:
            html.icon_button("logout.py",
                             _("Log out"),
                             "sidebar_logout",
                             target="_top")

        html.icon_button("return void();",
                         _("You have pending messages."),
                         "sidebar_messages",
                         onclick='cmk.sidebar.read_message()',
                         id_='msg_button',
                         style='display:none')
        html.open_div(style="display:none;", id_="messages")
        self.render_messages()
        html.close_div()

        html.open_div(class_=["copyright"])
        html.write(
            HTML("&copy; ") + html.render_a(
                "tribe29 GmbH", target="_blank", href="https://checkmk.com"))
        html.close_div()
        html.close_div()

        if user_config.folded:
            html.final_javascript("cmk.sidebar.fold_sidebar();")
예제 #17
0
def mobile_html_head(title: str) -> None:
    html.write_html(
        HTML(
            """<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">"""
        ))
    html.open_html()
    html.open_head()
    html.default_html_headers()
    html.meta(name="viewport", content="initial-scale=1.0")
    html.meta(name="apple-mobile-web-app-capable", content="yes")
    html.meta(name="apple-mobile-web-app-title", content="Check_MK")
    html.title(title)
    html.stylesheet(href="jquery/jquery.mobile-1.4.5.min.css")
    html.stylesheet(href="themes/facelift/theme.css")

    html.link(rel="apple-touch-icon", href="themes/facelift/images/ios_logo.png")
    html.javascript_file(src='js/mobile_min.js')

    html.close_head()
    html.open_body(class_="mobile")
예제 #18
0
    def _add_cell(
        self,
        title: "HTMLContent" = "",
        text: "HTMLContent" = "",
        css: Optional["CSSSpec"] = None,
        help_txt: Optional[str] = None,
        colspan: Optional[int] = None,
        sortable: bool = True,
    ):
        if isinstance(text, HTML):
            content = text
        else:
            content = escape_to_html_permissive(
                str(text) if not isinstance(text, str) else text,
                escape_links=False)

        htmlcode: HTML = content + HTML(output_funnel.drain())

        if isinstance(title, HTML):
            header_title = title
        else:
            if title is None:
                title = ""
            header_title = escape_to_html_permissive(
                str(title) if not isinstance(title, str) else title,
                escape_links=False)

        if self.options["collect_headers"] is True:
            # small helper to make sorting introducion easier. Cells which contain
            # buttons are never sortable
            if css and "buttons" in css and sortable:
                sortable = False
            self.headers.append(
                TableHeader(title=header_title,
                            css=css,
                            help_txt=help_txt,
                            sortable=sortable))

        current_row = self.rows[-1]
        assert isinstance(current_row, TableRow)
        current_row.cells.append(CellSpec(htmlcode, css, colspan))
예제 #19
0
파일: bi.py 프로젝트: bsmr/tribe29-checkmk
    def _render_tree(self, tree):
        for group, attrs in tree.items():
            fetch_url = html.makeuri_contextless([
                ("view_name", "aggr_all"),
                ("aggr_group_tree", "/".join(attrs["__path__"])),
            ], "view.py")

            if attrs.get('__children__'):
                html.begin_foldable_container(
                    "bi_aggregation_group_trees", group, False,
                    HTML(html.render_a(
                        group,
                        href=fetch_url,
                        target="main",
                    )))
                self._render_tree(attrs['__children__'])
                html.end_foldable_container()
            else:
                html.open_ul()
                bulletlink(group, fetch_url)
                html.close_ul()
예제 #20
0
    def page(self):
        html.open_table(class_=["data", "headerleft"])

        html.open_tr()
        html.th(_("Title"))
        html.open_td()
        html.b(self._manpage["header"]["title"])
        html.close_td()
        html.close_tr()

        html.open_tr()
        html.th(_("Name of plugin"))
        html.open_td()
        html.tt(self._check_type)
        html.close_td()
        html.close_tr()

        html.open_tr()
        html.th(_("Description"))
        html.td(self._manpage_text(self._manpage["header"]["description"]))
        html.close_tr()

        if self._manpage["type"] == "check_mk":
            html.open_tr()
            html.th(_("Service name"))
            html.td(
                HTML(self._manpage["service_description"].replace(
                    "%s", "&#9744;")))
            html.close_tr()

            if self._manpage.get("group"):
                group = self._manpage["group"]
                varname = "checkgroup_parameters:" + group
                self._show_ruleset(varname)

        else:
            varname = "active_checks:" + self._check_type[6:]
            self._show_ruleset(varname)

        html.close_table()
예제 #21
0
def page_login() -> None:
    title = _("Checkmk Mobile")
    mobile_html_head(title)
    jqm_page_header(title, id_="login")
    html.div(_("Welcome to Checkmk Mobile."), id_="loginhead")

    html.begin_form("login", method="POST", add_transid=False)
    # Keep information about original target URL
    default_origtarget = ("index.py" if requested_file_name(request)
                          in ["login", "logout"] else makeuri(request, []))
    origtarget = request.get_url_input("_origtarget", default_origtarget)
    html.hidden_field("_origtarget", escaping.escape_attribute(origtarget))

    html.text_input("_username",
                    label=_("Username:"******"username",
                    id_="input_user")
    html.password_input(
        "_password",
        size=None,
        label=_("Password:"******"current-password",
        id_="input_pass",
    )
    html.br()
    html.button("_login", _("Login"))
    html.set_focus("_username")
    html.end_form()
    html.open_div(id_="loginfoot")
    html.img("themes/facelift/images/logo_cmk_small.png", class_="logomk")
    html.div(
        HTML(
            _('&copy; <a target="_blank" href="https://checkmk.com">tribe29 GmbH</a>'
              )),
        class_="copyright",
    )
    html.close_div()  # close content-div
    html.close_div()
    html.close_div()  # close page-div
    mobile_html_foot()
예제 #22
0
def render_graphs_from_definitions(graph_recipes,
                                   graph_data_range,
                                   graph_render_options,
                                   render_async=True) -> HTML:
    # Estimate step. Step is the number of seconds each fetched data point represents.
    # It does not make sense to fetch the data in *much* greater precision than our
    # display has. A *bit* more precision is useful for better optical zoom.
    graph_data_range.setdefault(
        "step",
        estimate_graph_step_for_html(graph_data_range["time_range"],
                                     graph_render_options))

    output = HTML()
    for graph_recipe in graph_recipes:
        if render_async:
            output += render_graph_container_html(graph_recipe,
                                                  graph_data_range,
                                                  graph_render_options)
        else:
            output += render_graph_content_html(graph_recipe, graph_data_range,
                                                graph_render_options)
    return output
예제 #23
0
    def render(self, row, cell):
        classes = ["perfometer"]
        if is_stale(row):
            classes.append("stale")

        try:
            title, h = Perfometer(row).render()
            if title is None and h is None:
                return "", ""
        except Exception as e:
            logger.exception("error rendering performeter")
            if config.debug:
                raise
            return " ".join(classes), _("Exception: %s") % e

        content = html.render_div(HTML(h), class_=["content"]) \
                + html.render_div(title, class_=["title"]) \
                + html.render_div("", class_=["glass"])

        # pnpgraph_present: -1 means unknown (path not configured), 0: no, 1: yes
        if display_options.enabled(display_options.X) \
           and row["service_pnpgraph_present"] != 0:
            if metrics.cmk_graphs_possible():
                import cmk.gui.cee.plugins.views.graphs
                url = cmk.gui.cee.plugins.views.graphs.cmk_graph_url(
                    row, "service")
            else:
                url = pnp_url(row, "service")
            disabled = False
        else:
            url = "javascript:void(0)"
            disabled = True

        return " ".join(classes), \
            html.render_a(content=content, href=url, title=html.strip_tags(title),
                          class_=["disabled" if disabled else None])
예제 #24
0
def render_tree_folder(tree_id, folder, js_func):
    subfolders = folder.get(".folders", {}).values()
    is_leaf = len(subfolders) == 0

    # Suppress indentation for non-emtpy root folder
    if folder['.path'] == '' and is_leaf:
        html.open_ul()  # empty root folder
    elif folder and folder['.path'] != '':
        html.open_ul(style="padding-left:0px;")

    title = html.render_a("%s (%d)" % (folder["title"], folder[".num_hosts"]),
                          href="#",
                          class_="link",
                          onclick="%s(this, \'%s\');" % (js_func, folder[".path"]))

    if not is_leaf:
        html.begin_foldable_container(tree_id, "/" + folder[".path"], False, HTML(title))
        for subfolder in sorted(subfolders, key=lambda x: x["title"].lower()):
            render_tree_folder(tree_id, subfolder, js_func)
        html.end_foldable_container()
    else:
        html.li(title)

    html.close_ul()
예제 #25
0
    def _show_leaf(self, tree, show_host):
        site, host = tree[2]["host"]
        service = tree[2].get("service")

        # Four cases:
        # (1) zbghora17 . Host status   (show_host == True, service is None)
        # (2) zbghora17 . CPU load      (show_host == True, service is not None)
        # (3) Host Status               (show_host == False, service is None)
        # (4) CPU load                  (show_host == False, service is not None)

        if show_host or not service:
            host_url = makeuri_contextless(
                request,
                [("view_name", "hoststatus"), ("site", site), ("host", host)],
                filename="view.py",
            )

        if service:
            service_url = makeuri_contextless(
                request,
                [("view_name", "service"), ("site", site), ("host", host),
                 ("service", service)],
                filename="view.py",
            )

        with self._show_node(tree, show_host):
            self._assume_icon(site, host, service)

            if show_host:
                html.a(host.replace(" ", "&nbsp;"), href=host_url)
                html.b(HTML("&diams;"), class_="bullet")

            if not service:
                html.a(_("Host&nbsp;status"), href=host_url)
            else:
                html.a(service.replace(" ", "&nbsp;"), href=service_url)
예제 #26
0
파일: bi.py 프로젝트: PLUTEX/checkmk
    def render(self, row: Row, cell: Cell) -> CellSpec:
        single_url = "view.py?" + urlencode_vars(
            [("view_name", "aggr_single"), ("aggr_name", row["aggr_name"])]
        )
        avail_url = single_url + "&mode=availability"

        bi_map_url = "bi_map.py?" + urlencode_vars(
            [
                ("aggr_name", row["aggr_name"]),
            ]
        )

        with output_funnel.plugged():
            html.icon_button(bi_map_url, _("Visualize this aggregation"), "aggr")
            html.icon_button(single_url, _("Show only this aggregation"), "showbi")
            html.icon_button(
                avail_url, _("Analyse availability of this aggregation"), "availability"
            )
            if row["aggr_effective_state"]["in_downtime"] != 0:
                html.icon(
                    "derived_downtime", _("A service or host in this aggregation is in downtime.")
                )
            if row["aggr_effective_state"]["acknowledged"]:
                html.icon(
                    "ack",
                    _(
                        "The critical problems that make this aggregation non-OK have been acknowledged."
                    ),
                )
            if not row["aggr_effective_state"]["in_service_period"]:
                html.icon(
                    "outof_serviceperiod",
                    _("This aggregation is currently out of its service period."),
                )
            code = HTML(output_funnel.drain())
        return "buttons", code
예제 #27
0
class TestRuleConditionRenderer:
    @pytest.mark.parametrize(
        "taggroup_id, tag_spec, rendered_condition",
        [
            pytest.param(
                "tag_grp_1",
                "grp_1_tg_1",
                HTML("Host: Tag group 1 is <b>Tag 1.1</b>"),
                id="grouped tag",
            ),
            pytest.param(
                "tag_grp_1",
                {"$ne": "grp_1_tg_1"},
                HTML("Host: Tag group 1 is <b>not</b> <b>Tag 1.1</b>"),
                id="negated grouped tag",
            ),
            pytest.param(
                "aux_tag_1",
                "aux_tag_1",
                HTML("Host has tag <b>Auxiliary tag 1</b>"),
                id="auxiliary tag",
            ),
            pytest.param(
                "aux_tag_1",
                {"$ne": "aux_tag_1"},
                HTML("Host does not have tag <b>Auxiliary tag 1</b>"),
                id="negated auxiliary tag",
            ),
            pytest.param(
                "xyz",
                "a",
                HTML("Unknown tag: Host has the tag <tt>a</tt>"),
                id="unknown tag group",
            ),
            pytest.param(
                "xyz",
                "grp_1_tg_1",
                HTML("Unknown tag: Host has the tag <tt>grp_1_tg_1</tt>"),
                id="unknown tag",
            ),
        ],
    )
    def test_single_tag_condition(
        self,
        taggroup_id: TaggroupID,
        tag_spec: Union[Optional[TagID], TagConditionNE],
        rendered_condition: HTML,
    ) -> None:
        assert RuleConditionRenderer()._single_tag_condition(
            taggroup_id,
            tag_spec,
        ) == rendered_condition

    def test_tag_condition(self) -> None:
        assert list(RuleConditionRenderer()._tag_conditions({
            "tag_grp_1": {
                "$or": [
                    "grp_1_tg_1",
                    "grp_1_tg_2",
                ]
            },
            "tag_grp_2": {
                "$nor": [
                    "grp_2_tg_1",
                    "grp_2_tg_2",
                ]
            },
            "tag_grp_3": "grp_3_tg_1",
            "aux_tag_1": {
                "$ne": "aux_tag_1"
            },
        })) == [
            HTML(
                "Host: Tag group 1 is <b>Tag 1.1</b> <i>or</i> Host: Tag group 1 is <b>Tag 1.2</b>"
            ),
            HTML(
                "Neither Host: Tag group 2 is <b>Tag 2.1</b> <i>nor</i> Host: Tag group 2 is <b>Tag 2.2</b>"
            ),
            HTML("Host: Tag group 3 is <b>Tag 3.1</b>"),
            HTML("Host does not have tag <b>Auxiliary tag 1</b>"),
        ]
예제 #28
0
    def render_job_row(cls,
                       job_id,
                       job_status,
                       odd,
                       job_details_back_url=None):
        html.open_tr(css="data %s0" % odd)

        # Actions
        html.open_td(css="job_actions")
        if job_status.get("may_stop"):
            html.icon_button(
                html.makeactionuri([(ActionHandler.stop_job_var, job_id)]),
                _("Stop this job"), "disable_test")
        if job_status.get("may_delete"):
            html.icon_button(
                html.makeactionuri([(ActionHandler.delete_job_var, job_id)]),
                _("Delete this job"), "delete")
        html.close_td()

        # Job ID
        html.open_td(css="job_id")
        uri = makeuri_contextless(
            request,
            [
                ("mode", "background_job_details"),
                ("back_url", job_details_back_url),
                ("job_id", job_id),
            ],
            filename="wato.py",
        )
        html.a(job_id, href=uri)
        html.close_td()

        # Title
        html.td(job_status.get("title", _("Background Job")), css="job_title")

        # State
        html.td(job_status["state"],
                css=cls.get_css_for_jobstate(job_status["state"]))

        # Started
        html.td(cmk.utils.render.date_and_time(job_status["started"]),
                css="job_started")

        # Owner
        html.td(job_status.get("user", _("Unknown user")), css="job_owner")

        # PID
        html.td(job_status["pid"] or "", css="job_pid")

        # Druation
        html.td(cmk.utils.render.timespan(job_status.get("duration", 0)),
                css="job_runtime")

        # Progress info
        loginfo = job_status.get("loginfo")
        if loginfo:
            if job_status.get(
                    "state") == background_job.JobStatusStates.EXCEPTION:
                html.td(HTML("<br>".join(loginfo["JobException"])),
                        css="job_last_progress")
            else:
                progress_text = ""
                if loginfo["JobProgressUpdate"]:
                    progress_text += "%s" % loginfo["JobProgressUpdate"][-1]
                html.td(HTML(progress_text), css="job_last_progress")

            html.td(HTML("<br>".join(loginfo["JobResult"])), css="job_result")
        else:
            html.td("", css="job_last_progress")
            html.td("", css="job_result")
예제 #29
0
    def show_job_details(cls, job_id, job_status):
        """Renders the complete job details in a single table with left headers"""
        html.open_table(class_=["data", "headerleft", "job_details"])

        # Static info
        for left, right in [
            (_("ID"), job_id),
            (_("Title"), job_status.get("title", "")),
            (_("Started"),
             cmk.utils.render.date_and_time(job_status["started"])),
            (_("Owner"), job_status.get("user", "")),
        ]:
            html.open_tr()
            html.th(left)
            html.td(right)
            html.close_tr()

        # Actions
        html.open_tr()
        html.th(_("Actions"))
        html.open_td()
        if job_status.get("may_stop"):
            html.icon_button(
                html.makeactionuri([(ActionHandler.stop_job_var, job_id)]),
                _("Stop this job"),
                "disable_test",
            )
        if job_status.get("may_delete"):
            html.icon_button(
                html.makeactionuri([(ActionHandler.delete_job_var, job_id)]),
                _("Delete this job"),
                "delete",
            )
        html.close_td()
        html.close_tr()

        # Job state
        html.open_tr()
        html.th(_("State"))
        html.td(job_status["state"],
                css=cls.get_css_for_jobstate(job_status["state"]))
        html.close_tr()

        if job_status["state"] == background_job.JobStatusStates.EXCEPTION:
            html.open_tr()
            html.th(_("Acknowledged by"))
            html.td(job_status.get("acknowledged_by", ""))
            html.close_tr()

        # Dynamic data
        loginfo = job_status.get("loginfo")
        runtime_info = ensure_str(
            cmk.utils.render.timespan(job_status.get("duration", 0)))
        if job_status["state"] == background_job.JobStatusStates.RUNNING \
            and job_status.get("estimated_duration") is not None:
            runtime_info += u" (%s: %s)" % (
                _("estimated duration"),
                ensure_str(
                    cmk.utils.render.timespan(
                        job_status["estimated_duration"])))
        for left, right in [
            (_("Runtime"), runtime_info),
            (_("PID"), job_status["pid"] or ""),
            (_("Result"), "<br>".join(loginfo["JobResult"])),
        ]:
            if right is None:
                continue
            html.open_tr()
            html.th(left)
            html.td(HTML(right))
            html.close_tr()

        # Exceptions
        exceptions = loginfo["JobException"]
        if exceptions:
            html.open_tr()
            html.th(_("Exceptions"))
            html.open_td()
            if exceptions and "logfile_path" in job_status:
                exceptions.append(
                    _("More information can be found in %s") %
                    job_status["logfile_path"])
            html.open_div(class_="log_output", id_="exception_log")
            html.pre("\n".join(exceptions))
            html.close_div()
            html.close_td()
            html.close_tr()

        # Progress Update
        html.open_tr()
        html.th(_("Progress Info"))
        html.open_td()
        html.open_div(class_="log_output",
                      style="height: 400px;",
                      id_="progress_log")
        html.pre(HTML("\n").join(loginfo["JobProgressUpdate"]))
        html.close_div()
        html.close_td()
        html.close_tr()

        html.close_table()
        html.javascript(
            "var log = document.getElementById('progress_log'); log.scrollTop = log.scrollHeight;"
        )
예제 #30
0
 def _render_filter_form(self) -> HTML:
     with output_funnel.plugged():
         self._display_audit_log_options()
         return HTML(output_funnel.drain())