Esempio n. 1
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(" ", " "), href=host_url)
                html.b(HTML("♦"), class_="bullet")

            if not service:
                html.a(_("Host status"), href=host_url)
            else:
                html.a(service.replace(" ", " "), href=service_url)
Esempio n. 2
0
    def page(self):

        header = self._manpage["header"]

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

        html.open_tr()
        html.th(_("Title"))
        html.open_td()
        html.b(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(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", "☐")))
            html.close_tr()

            discovery = header.get("discovery") or header.get("inventory")
            if discovery:
                html.open_tr()
                html.th(_("Discovery"))
                html.td(self._manpage_text(discovery))
                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 = 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()
Esempio n. 3
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())
Esempio n. 4
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", "☐")))
            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()
Esempio n. 5
0
    def page(self):
        # Show outcome of host validation. Do not validate new hosts
        errors = None
        if self._mode == "edit":
            errors = (watolib.validate_all_hosts([self._host.name()]).get(
                self._host.name(), []) + self._host.validation_errors())

        if errors:
            html.open_div(class_="info")
            html.open_table(class_="validationerror",
                            boder="0",
                            cellspacing="0",
                            cellpadding="0")
            html.open_tr()

            html.open_td(class_="img")
            html.icon("validation_error")
            html.close_td()

            html.open_td()
            html.open_p()
            html.h3(_("Warning: This host has an invalid configuration!"))
            html.open_ul()
            for error in errors:
                html.li(error)
            html.close_ul()
            html.close_p()

            if html.form_submitted():
                html.br()
                html.b(_("Your changes have been saved nevertheless."))
            html.close_td()

            html.close_tr()
            html.close_table()
            html.close_div()

        lock_message = ""
        locked_hosts = watolib.Folder.current().locked_hosts()
        if locked_hosts:
            if locked_hosts is True:
                lock_message = _(
                    "Host attributes locked (You cannot edit this host)")
            elif isinstance(locked_hosts, str):
                lock_message = locked_hosts
        if lock_message:
            html.div(lock_message, class_="info")

        html.begin_form("edit_host", method="POST")
        html.prevent_password_auto_completion()

        basic_attributes = [
            # attribute name, valuepec, default value
            ("host", self._vs_host_name(), self._host.name()),
        ]

        if self._is_cluster():
            basic_attributes += [
                # attribute name, valuepec, default value
                (
                    "nodes",
                    self._vs_cluster_nodes(),
                    self._host.cluster_nodes() if self._host else [],
                ),
            ]

        configure_attributes(
            new=self._mode != "edit",
            hosts={self._host.name(): self._host}
            if self._mode != "new" else {},
            for_what="host" if not self._is_cluster() else "cluster",
            parent=watolib.Folder.current(),
            basic_attributes=basic_attributes,
        )

        if self._mode != "edit":
            html.set_focus("host")

        forms.end()
        html.hidden_fields()
        html.end_form()
Esempio n. 6
0
    def render_snapin(self, snapin: UserSidebarSnapin) -> str:
        snapin_class = snapin.snapin_type
        name = snapin_class.type_name()
        snapin_instance = snapin_class()

        html.open_div(id_="snapin_container_%s" % name, class_="snapin")
        self._render_snapin_styles(snapin_instance)
        # When not permitted to open/close snapins, the snapins are always opened
        if snapin.visible == SnapinVisibility.OPEN or not config.user.may(
                "general.configure_sidebar"):
            style = None
        else:
            style = "display:none"

        toggle_url = "sidebar_openclose.py?name=%s&state=" % name

        # If the user may modify the sidebar then add code for dragging the snapin
        head_actions: Dict[str, str] = {}
        if config.user.may("general.configure_sidebar"):
            head_actions = {
                "onmouseover": "document.body.style.cursor='move';",
                "onmouseout ": "document.body.style.cursor='';",
                "onmousedown": "cmk.sidebar.snapin_start_drag(event)",
                "onmouseup": "cmk.sidebar.snapin_stop_drag(event)"
            }

        html.open_div(class_=["head", snapin.visible.value], **head_actions)

        if config.user.may("general.configure_sidebar"):
            # Icon for mini/maximizing
            html.div("",
                     class_="minisnapin",
                     title=_("Toggle this snapin"),
                     onclick="cmk.sidebar.toggle_sidebar_snapin(this, '%s')" %
                     toggle_url)

            # Button for closing (removing) a snapin
            html.open_div(class_="closesnapin")
            close_url = "sidebar_openclose.py?name=%s&state=off" % name
            html.icon_button(
                url=None,
                title=_("Remove this snapin"),
                icon="closesnapin",
                onclick="cmk.sidebar.remove_sidebar_snapin(this, '%s')" %
                close_url)
            html.close_div()

        # The heading. A click on the heading mini/maximizes the snapin
        toggle_actions: Dict[str, str] = {}
        if config.user.may("general.configure_sidebar"):
            toggle_actions = {
                "onclick":
                "cmk.sidebar.toggle_sidebar_snapin(this,'%s')" % toggle_url,
                "onmouseover": "this.style.cursor='pointer'",
                "onmouseout": "this.style.cursor='auto'"
            }
        html.b(snapin_class.title(), class_=["heading"], **toggle_actions)

        # End of header
        html.close_div()

        # Now comes the content
        html.open_div(class_="content", id_="snapin_%s" % name, style=style)
        refresh_url = ''
        try:
            # TODO: Refactor this confusing special case. Add deddicated method or something
            # to let the snapins make the sidebar know that there is a URL to fetch.
            url = snapin_instance.show()
            if url is not None:
                # Fetch the contents from an external URL. Don't render it on our own.
                refresh_url = url
                html.javascript(
                    "cmk.ajax.get_url(\"%s\", cmk.utils.update_contents, \"snapin_%s\")"
                    % (refresh_url, name))
        except Exception as e:
            logger.exception("error rendering snapin %s", name)
            write_snapin_exception(e)
        html.close_div()
        html.close_div()
        return refresh_url
Esempio n. 7
0
def _rename_tags_after_confirmation(operation):
    # type: (ABCOperation) -> Union[bool, str]
    """Handle renaming and deletion of tags

    Find affected hosts, folders and rules. Remove or fix those rules according
    the users' wishes.
    """
    repair_mode = html.request.var("_repair")
    if repair_mode is not None:
        try:
            mode = TagCleanupMode(repair_mode)
        except ValueError:
            raise MKUserError("_repair", "Invalid mode")

        if mode == TagCleanupMode.ABORT:
            raise MKUserError("id_0", _("Aborting change."))

        # make attribute unknown to system, important for save() operations
        if isinstance(operation, OperationRemoveTagGroup):
            watolib.host_attributes.undeclare_host_tag_attribute(
                operation.tag_group_id)

        affected_folders, affected_hosts, affected_rulesets = \
        _change_host_tags_in_folders(operation, mode, watolib.Folder.root_folder())

        return _("Modified folders: %d, modified hosts: %d, modified rulesets: %d") % \
            (len(affected_folders), len(affected_hosts), len(affected_rulesets))

    message = u""
    affected_folders, affected_hosts, affected_rulesets = \
        _change_host_tags_in_folders(operation, TagCleanupMode.CHECK, watolib.Folder.root_folder())

    if affected_folders:
        message += _("Affected folders with an explicit reference to this tag "
                     "group and that are affected by the change") + ":"
        with html.plugged():
            _show_affected_folders(affected_folders)
            message += html.drain()

    if affected_hosts:
        message += _("Hosts where this tag group is explicitely set "
                     "and that are effected by the change") + ":"
        with html.plugged():
            _show_affected_hosts(affected_hosts)
            message += html.drain()

    if affected_rulesets:
        message += _(
            "Rulesets that contain rules with references to the changed tags"
        ) + ":"
        with html.plugged():
            _show_affected_rulesets(affected_rulesets)
            message += html.drain()

    if message:
        wato_html_head(operation.confirm_title())
        html.open_div(class_="really")
        html.h3(_("Your modifications affect some objects"))
        html.write_text(message)
        html.br()
        html.write_text(
            _("WATO can repair things for you. It can rename tags in folders, host and rules. "
              "Removed tag groups will be removed from hosts and folders, removed tags will be "
              "replaced with the default value for the tag group (for hosts and folders). What "
              "rules concern, you have to decide how to proceed."))
        html.begin_form("confirm", method="POST")

        if affected_rulesets and _is_removing_tags(operation):
            html.br()
            html.b(
                _("Some tags that are used in rules have been removed by you. What "
                  "shall we do with that rules?"))
            html.open_ul()
            html.radiobutton(
                "_repair", "remove", True,
                _("Just remove the affected tags from the rules."))
            html.br()
            html.radiobutton(
                "_repair", "delete", False,
                _("Delete rules containing tags that have been removed, if tag is used in a positive sense. Just remove that tag if it's used negated."
                  ))
        else:
            html.open_ul()
            html.radiobutton("_repair", "repair", True,
                             _("Fix affected folders, hosts and rules."))

        html.br()
        html.radiobutton("_repair", "abort", False,
                         _("Abort your modifications."))
        html.close_ul()

        html.button("_do_confirm", _("Proceed"), "")
        html.hidden_fields(add_action_vars=True)
        html.end_form()
        html.close_div()
        return False

    return True
Esempio n. 8
0
    def _show_node(self, tree, show_host, mousecode=None, img_class=None):
        # Check if we have an assumed state: comparing assumed state (tree[1]) with state (tree[0])
        if tree[1] and tree[0] != tree[1]:
            addclass: Optional[str] = "assumed"
            effective_state = tree[1]
        else:
            addclass = None
            effective_state = tree[0]

        class_: List[Optional[str]] = [
            "content",  #
            "state",
            "state%d" % (effective_state["state"] if effective_state["state"] is not None else -1),
            addclass,
        ]
        html.open_span(class_=class_)
        html.write_text(self._render_bi_state(effective_state["state"]))
        html.close_span()

        if mousecode:
            if img_class:
                html.img(
                    src=theme.url("images/tree_closed.svg"),
                    class_=["treeangle", img_class],
                    onclick=mousecode,
                )

            html.open_span(class_=["content", "name"])

        icon_name, icon_title = None, None
        if tree[0]["in_downtime"] == 2:
            icon_name = "downtime"
            icon_title = _("This element is currently in a scheduled downtime.")

        elif tree[0]["in_downtime"] == 1:
            # only display host downtime if the service has no own downtime
            icon_name = "derived_downtime"
            icon_title = _("One of the subelements is in a scheduled downtime.")

        if tree[0]["acknowledged"]:
            icon_name = "ack"
            icon_title = _("This problem has been acknowledged.")

        if not tree[0]["in_service_period"]:
            icon_name = "outof_serviceperiod"
            icon_title = _("This element is currently not in its service period.")

        if icon_name and icon_title:
            html.icon(icon_name, title=icon_title, class_=["icon", "bi"])

        yield

        if mousecode:
            if str(effective_state["state"]) in tree[2].get("state_messages", {}):
                html.b(HTML("♦"), class_="bullet")
                html.write_text(tree[2]["state_messages"][str(effective_state["state"])])

            html.close_span()

        output: HTML = cmk.gui.view_utils.format_plugin_output(
            effective_state["output"], shall_escape=config.escape_plugin_output
        )
        if output:
            output = html.render_b(HTML("♦"), class_="bullet") + output
        else:
            output = HTML()

        html.span(output, class_=["content", "output"])
Esempio n. 9
0
def _rename_tags_after_confirmation(tag_id, operations):
    """Handle renaming and deletion of tags

    Find affected hosts, folders and rules. Remove or fix those rules according
    the the users' wishes. In case auf auxiliary tags the tag_id is None. In
    other cases it is the id of the tag group currently being edited.
    """
    mode = html.request.var("_repair")
    if mode == "abort":
        raise MKUserError("id_0", _("Aborting change."))

    elif mode:
        # make attribute unknown to system, important for save() operations
        if tag_id and isinstance(operations, list):
            watolib.host_attributes.undeclare_host_tag_attribute(tag_id)
        affected_folders, affected_hosts, affected_rulesets = \
        _change_host_tags_in_folders(tag_id, operations, mode, watolib.Folder.root_folder())
        return _("Modified folders: %d, modified hosts: %d, modified rulesets: %d") % \
            (len(affected_folders), len(affected_hosts), len(affected_rulesets))

    message = ""
    affected_folders, affected_hosts, affected_rulesets = \
        _change_host_tags_in_folders(tag_id, operations, "check", watolib.Folder.root_folder())

    if affected_folders:
        message += _("Affected folders with an explicit reference to this tag "
                     "group and that are affected by the change") + ":<ul>"
        for folder in affected_folders:
            message += '<li><a href="%s">%s</a></li>' % (folder.edit_url(), folder.alias_path())
        message += "</ul>"

    if affected_hosts:
        message += _("Hosts where this tag group is explicitely set "
                     "and that are effected by the change") + ":<ul><li>"
        for nr, host in enumerate(affected_hosts):
            if nr > 20:
                message += "... (%d more)" % (len(affected_hosts) - 20)
                break
            elif nr > 0:
                message += ", "

            message += '<a href="%s">%s</a>' % (host.edit_url(), host.name())
        message += "</li></ul>"

    if affected_rulesets:
        message += _("Rulesets that contain rules with references to the changed tags") + ":<ul>"
        for ruleset in affected_rulesets:
            message += '<li><a href="%s">%s</a></li>' % (watolib.folder_preserving_link(
                [("mode", "edit_ruleset"), ("varname", ruleset.name)]), ruleset.title())
        message += "</ul>"

    if not message and isinstance(operations, tuple):  # deletion of unused tag group
        html.open_div(class_="really")
        html.begin_form("confirm")
        html.write_text(_("Please confirm the deletion of the tag group."))
        html.button("_abort", _("Abort"))
        html.button("_do_confirm", _("Proceed"))
        html.hidden_fields(add_action_vars=True)
        html.end_form()
        html.close_div()

    elif message:
        if isinstance(operations, list):
            wato_html_head(_("Confirm tag deletion"))
        else:
            wato_html_head(_("Confirm tag modifications"))
        html.open_div(class_="really")
        html.h3(_("Your modifications affect some objects"))
        html.write_text(message)
        html.br()
        html.write_text(
            _("WATO can repair things for you. It can rename tags in folders, host and rules. "
              "Removed tag groups will be removed from hosts and folders, removed tags will be "
              "replaced with the default value for the tag group (for hosts and folders). What "
              "rules concern, you have to decide how to proceed."))
        html.begin_form("confirm")

        # Check if operations contains removal
        if isinstance(operations, list):
            have_removal = True
        else:
            have_removal = False
            for new_val in operations.values():
                if not new_val:
                    have_removal = True
                    break

        if affected_rulesets and have_removal:
            html.br()
            html.b(
                _("Some tags that are used in rules have been removed by you. What "
                  "shall we do with that rules?"))
            html.open_ul()
            html.radiobutton("_repair", "remove", True,
                             _("Just remove the affected tags from the rules."))
            html.br()
            html.radiobutton(
                "_repair", "delete", False,
                _("Delete rules containing tags that have been removed, if tag is used in a positive sense. Just remove that tag if it's used negated."
                 ))
        else:
            html.open_ul()
            html.radiobutton("_repair", "repair", True, _("Fix affected folders, hosts and rules."))

        html.br()
        html.radiobutton("_repair", "abort", False, _("Abort your modifications."))
        html.close_ul()

        html.button("_do_confirm", _("Proceed"), "")
        html.hidden_fields(add_action_vars=True)
        html.end_form()
        html.close_div()
        return False

    return True
Esempio n. 10
0
    def page(self):
        # Show outcome of host validation. Do not validate new hosts
        errors = None
        if self._mode != "edit":
            watolib.Folder.current().show_breadcrump()
        else:
            errors = watolib.validate_all_hosts([self._host.name()]).get(
                self._host.name(), []) + self._host.validation_errors()

        if errors:
            html.open_div(class_="info")
            html.open_table(class_="validationerror",
                            boder=0,
                            cellspacing=0,
                            cellpadding=0)
            html.open_tr()

            html.open_td(class_="img")
            html.icon(title=None, icon="validation_error")
            html.close_td()

            html.open_td()
            html.open_p()
            html.h3(_("Warning: This host has an invalid configuration!"))
            html.open_ul()
            for error in errors:
                html.li(error)
            html.close_ul()
            html.close_p()

            if html.form_submitted():
                html.br()
                html.b(_("Your changes have been saved nevertheless."))
            html.close_td()

            html.close_tr()
            html.close_table()
            html.close_div()

        lock_message = ""
        if watolib.Folder.current().locked_hosts():
            if watolib.Folder.current().locked_hosts() is True:
                lock_message = _(
                    "Host attributes locked (You cannot edit this host)")
            else:
                lock_message = watolib.Folder.current().locked_hosts()
        if len(lock_message) > 0:
            html.div(lock_message, class_="info")

        html.begin_form("edit_host", method="POST")
        html.prevent_password_auto_completion()

        forms.header(_("General Properties"))
        self._show_host_name()

        # Cluster: nodes
        if self._is_cluster():
            forms.section(_("Nodes"))
            self._vs_cluster_nodes().render_input(
                "nodes",
                self._host.cluster_nodes() if self._host else [])
            html.help(
                _('Enter the host names of the cluster nodes. These '
                  'hosts must be present in WATO. '))

        configure_attributes(
            new=self._mode != "edit",
            hosts={self._host.name(): self._host}
            if self._mode != "new" else {},
            for_what="host" if not self._is_cluster() else "cluster",
            parent=watolib.Folder.current())

        forms.end()
        if not watolib.Folder.current().locked_hosts():
            html.button("services", _("Save & go to Services"), "submit")
            html.button("save", _("Save & Finish"), "submit")
            if not self._is_cluster():
                html.button("diag_host", _("Save & Test"), "submit")
        html.hidden_fields()
        html.end_form()