Beispiel #1
0
def _validate_general_host_attributes(host_attributes, new):
    # inventory_failed and site are no "real" host_attributes (TODO: Clean this up!)
    all_host_attribute_names = list(
        host_attribute_registry.keys()) + ["inventory_failed", "site"]
    for name, value in host_attributes.items():
        if name not in all_host_attribute_names:
            raise MKUserError(
                None,
                _("Unknown attribute: %s") % escaping.escape_attribute(name))

        # For real host attributes validate the values
        try:
            attr = watolib.host_attribute(name)
        except KeyError:
            attr = None

        if attr is not None:
            if attr.needs_validation("host", new):
                attr.validate_input(value, "")

        # The site attribute gets an extra check
        if name == "site" and value not in config.allsites().keys():
            raise MKUserError(
                None,
                _("Unknown site %s") % escaping.escape_attribute(value))
Beispiel #2
0
 def _render_warnings(self, configuration_warnings):
     html_code = "<div class=warning>"
     html_code += "<b>%s</b>" % _("Warnings:")
     html_code += "<ul>"
     for domain, warnings in sorted(configuration_warnings.items()):
         for warning in warnings:
             html_code += "<li>%s: %s</li>" % \
                 (escaping.escape_attribute(domain), escaping.escape_attribute(warning))
     html_code += "</ul>"
     html_code += "</div>"
     return html_code
Beispiel #3
0
    def _show_row_cells(self, table, name, group):
        table.cell(_("Actions"), css="buttons")
        edit_url = watolib.folder_preserving_link([("mode", "edit_%s_group" % self.type_name),
                                                   ("edit", name)])
        delete_url = html.makeactionuri([("_delete", name)])
        clone_url = watolib.folder_preserving_link([("mode", "edit_%s_group" % self.type_name),
                                                    ("clone", name)])
        html.icon_button(edit_url, _("Properties"), "edit")
        html.icon_button(clone_url, _("Create a copy of this group"), "clone")
        html.icon_button(delete_url, _("Delete"), "delete")

        table.cell(_("Name"), escaping.escape_attribute(name))
        table.cell(_("Alias"), escaping.escape_attribute(group['alias']))
Beispiel #4
0
def _validate_host_tags(host_tags):
    for tag_group_id, tag_id in host_tags.items():
        for tag_group in config.tags.tag_groups:
            if tag_group.id == tag_group_id:
                for grouped_tag in tag_group.tags:
                    if grouped_tag.id == tag_id:
                        break
                else:
                    raise MKUserError(None, _("Unknown tag %s") % escaping.escape_attribute(tag_id))
                break
        else:
            raise MKUserError(None,
                              _("Unknown tag group %s") % escaping.escape_attribute(tag_group_id))
Beispiel #5
0
def page_index():
    html.write(
        '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN" "http://www.w3.org/TR/html4/frameset.dtd">\n'
        '<html><head>\n')
    html.default_html_headers()
    html.write("""<title>%s</title>
</head>
<frameset cols="280,*" frameborder="0" framespacing="0" border="0">
    <frame src="side.py" name="side" noresize scrolling="no">
    <frame src="%s" name="main" noresize>
</frameset>
</html>
""" % (escaping.escape_attribute(
        config.get_page_heading()), escaping.escape_attribute(_get_start_url())))
Beispiel #6
0
    def _show_crash_report(self, info):
        html.h2(_("Crash Report"))
        html.open_table(class_=["data", "crash_report"])

        _crash_row(_("Exception"),
                   "%s (%s)" % (info["exc_type"], info["exc_value"]),
                   odd=True,
                   pre=True)
        _crash_row(_("Traceback"),
                   self._format_traceback(info["exc_traceback"]),
                   odd=False,
                   pre=True)
        _crash_row(_("Local Variables"),
                   format_local_vars(info["local_vars"]) if "local_vars" in info else "",
                   odd=True,
                   pre=True)

        _crash_row(_("Crash Type"), info["crash_type"], odd=False, legend=True)
        _crash_row(_("Time"),
                   time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(info["time"])),
                   odd=True)
        _crash_row(_("Operating System"), info["os"], False)
        _crash_row(_("Checkmk Version"), info["version"], True)
        _crash_row(_("Edition"), info.get("edition", ""), False)
        _crash_row(_("Core"), info.get("core", ""), True)
        _crash_row(_("Python Version"), info.get("python_version", _("Unknown")), False)

        joined_paths = "<br>".join(
            [escaping.escape_attribute(p) for p in info.get("python_paths", [_("Unknown")])])
        _crash_row(_("Python Module Paths"), joined_paths, odd=False)

        html.close_table()
Beispiel #7
0
def _get_api_call():
    action = global_request.var('action')
    for cls in api_call_collection_registry.values():
        api_call = cls().get_api_calls().get(action)
        if api_call:
            return api_call
    raise MKUserError(None, "Unknown API action %s" % escaping.escape_attribute(action))
Beispiel #8
0
def _show_output_box(title, content):
    html.h3(title)
    html.open_div(class_="log_output")
    html.write(
        escaping.escape_attribute(content).replace("\n", "<br>").replace(
            ' ', '&nbsp;'))
    html.close_div()
Beispiel #9
0
    def run(self):
        # type: () -> Iterator[ACResult]
        self._executed = True
        try:
            # Do not merge results that have been gathered on one site for different sites
            results = list(self.execute())
            num_sites = len(set(r.site_id for r in results))
            if num_sites > 1:
                for result in results:
                    result.from_test(self)
                    yield result
                return

            # Merge multiple results produced for a single site
            total_result = ACResult.merge(*list(self.execute()))
            total_result.from_test(self)
            yield total_result
        except Exception:
            logger.exception("error executing configuration test %s",
                             self.__class__.__name__)
            result = ACResultCRIT(
                "<pre>%s</pre>" % _("Failed to execute the test %s: %s") %
                (escaping.escape_attribute(
                    self.__class__.__name__), traceback.format_exc()))
            result.from_test(self)
            yield result
Beispiel #10
0
def page_login() -> None:
    title = _("Check_MK Mobile")
    mobile_html_head(title)
    jqm_page_header(title, id_="login")
    html.div(_("Welcome to Check_MK Mobile."), id_="loginhead")

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

    html.text_input("_username", label=_("Username:"******"username")
    html.password_input("_password",
                        size=None,
                        label=_("Password:"******"current-password")
    html.br()
    html.button("_login", _('Login'))
    html.set_focus("_username")
    html.end_form()
    html.open_div(id_="loginfoot")
    html.img("themes/classic/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()
Beispiel #11
0
    def _from_vars(self):
        # type: () -> None
        config.user.need_permission("wato.download_agent_output")

        host_name = html.request.var("host")
        if not host_name:
            raise MKGeneralException(_("The host is missing."))

        ty = html.request.var("type")
        if ty not in ["walk", "agent"]:
            raise MKGeneralException(_("Invalid type specified."))

        self._back_url = html.get_url_input("back_url", deflt="") or None

        watolib.init_wato_datastructures(with_wato_lock=True)

        host = watolib.Folder.current().host(host_name)
        if not host:
            raise MKGeneralException(
                _("Host is not managed by WATO. "
                  "Click <a href=\"%s\">here</a> to go back.") %
                escape_attribute(self._back_url))
        host.need_permission("read")

        self._request = FetchAgentOutputRequest(host=host, agent_type=ty)
Beispiel #12
0
def compute_output_message(effective_state, rule):
    output = []
    if effective_state["output"]:
        output.append(effective_state["output"])

    str_state = str(effective_state["state"])
    if str_state in rule.get("state_messages", {}):
        output.append(escaping.escape_attribute(rule["state_messages"][str_state]))
    return ", ".join(output)
Beispiel #13
0
def time_series_math(operator_id, operands_evaluated):
    operators = time_series_operators()
    if operator_id not in operators:
        raise MKGeneralException(
            _("Undefined operator '%s' in graph expression") %
            escaping.escape_attribute(operator_id))
    _op_title, op_func = operators[operator_id]

    return [op_func_wrapper(op_func, tsp) for tsp in zip(*operands_evaluated)]
Beispiel #14
0
 def action(self, cmdtag, spec, row, row_index, num_rows):
     for s in [0, 1, 2, 3]:
         statename = html.request.var("_fake_%d" % s)
         if statename:
             pluginoutput = html.request.get_unicode_input_mandatory("_fake_output").strip()
             if not pluginoutput:
                 pluginoutput = _("Manually set to %s by %s") % (
                     escaping.escape_attribute(statename), config.user.id)
             perfdata = html.request.var("_fake_perfdata")
             if perfdata:
                 pluginoutput += "|" + perfdata
             if cmdtag == "SVC":
                 cmdtag = "SERVICE"
             command = "PROCESS_%s_CHECK_RESULT;%s;%s;%s" % (cmdtag, spec, s,
                                                             livestatus.lqencode(pluginoutput))
             title = _("<b>manually set check results to %s</b> for"
                      ) % escaping.escape_attribute(statename)
             return command, title
Beispiel #15
0
def log_audit(linkinfo, action, message, user_id=None):
    if config.wato_use_git:
        if isinstance(message, HTML):
            message = escaping.strip_tags(message.value)
        cmk.gui.watolib.git.add_message(message)
    # Using escape_attribute here is against our regular rule to do the escaping
    # at the last possible time: When rendering. But this here is the last
    # place where we can distinguish between HTML() encapsulated (already)
    # escaped / allowed HTML and strings to be escaped.
    message = escaping.escape_attribute(message).strip()
    log_entry(linkinfo, action, message, user_id)
Beispiel #16
0
def time_series_math(operator_id: Literal["+", "*", "-", "/", "MAX", "MIN", "AVERAGE", "MERGE"],
                     operands_evaluated: List[TimeSeries]) -> TimeSeries:
    operators = time_series_operators()
    if operator_id not in operators:
        raise MKGeneralException(
            _("Undefined operator '%s' in graph expression") %
            escaping.escape_attribute(operator_id))
    _op_title, op_func = operators[operator_id]
    twindow = operands_evaluated[0].twindow

    return TimeSeries([op_func_wrapper(op_func, tsp) for tsp in zip(*operands_evaluated)], twindow)
Beispiel #17
0
def format_plugin_output(output: CellContent,
                         row: 'Optional[Row]' = None,
                         shall_escape: bool = True) -> str:
    assert not isinstance(output, dict)
    ok_marker = '<b class="stmark state0">OK</b>'
    warn_marker = '<b class="stmark state1">WARN</b>'
    crit_marker = '<b class="stmark state2">CRIT</b>'
    unknown_marker = '<b class="stmark state3">UNKN</b>'

    # In case we have a host or service row use the optional custom attribute
    # ESCAPE_PLUGIN_OUTPUT (set by host / service ruleset) to override the global
    # setting.
    if row:
        custom_vars = row.get("service_custom_variables",
                              row.get("host_custom_variables", {}))
        if "ESCAPE_PLUGIN_OUTPUT" in custom_vars:
            shall_escape = custom_vars["ESCAPE_PLUGIN_OUTPUT"] == "1"

    if shall_escape:
        output = escaping.escape_attribute(output)
    else:
        output = "%s" % output

    output = output.replace("(!)", warn_marker) \
              .replace("(!!)", crit_marker) \
              .replace("(?)", unknown_marker) \
              .replace("(.)", ok_marker)

    if row and "[running on" in output:
        a = output.index("[running on")
        e = output.index("]", a)
        hosts = output[a + 12:e].replace(" ", "").split(",")
        h = get_host_list_links(row["site"], hosts)
        output = output[:a] + "running on " + ", ".join(h) + output[e + 1:]

    prevent_url_icons = (row.get("service_check_command", "")
                         == "check_mk-check_mk_agent_update"
                         if row is not None else False)
    if shall_escape and not prevent_url_icons:
        http_url = r"(http[s]?://[A-Za-z0-9\-._~:/?#\[\]@!$&'()*+,;=%]+)"
        # (?:&lt;A HREF=&quot;), (?: target=&quot;_blank&quot;&gt;)? and endswith(" </A>") is a special
        # handling for the HTML code produced by check_http when "clickable URL" option is active.
        output = re.sub(
            "(?:&lt;A HREF=&quot;)?" + http_url +
            "(?: target=&quot;_blank&quot;&gt;)?", lambda p: str(
                html.render_icon_button(
                    p.group(1).replace('&quot;', ''),
                    p.group(1).replace('&quot;', ''), "link")), output)

        if output.endswith(" &lt;/A&gt;"):
            output = output[:-11]

    return output
Beispiel #18
0
def check_aggregation_title_uniqueness(aggregations):
    known_titles: Set[Any] = set()
    for attrs in aggregations.values():
        title = attrs["title"]
        if title in known_titles:
            raise MKConfigError(
                _("Duplicate BI aggregation with the title \"<b>%s</b>\". "
                  "Please check your BI configuration and make sure that within each group no aggregation has "
                  "the same title as any other. Note: you can use arguments in the top level "
                  "aggregation rule, like <tt>Host $HOST$</tt>.") %
                (escaping.escape_attribute(title)))
        known_titles.add(title)
Beispiel #19
0
 def render_messages(self):
     for msg in notify.get_gui_messages():
         if 'gui_hint' in msg['methods']:
             html.open_div(id_="message-%s" % msg['id'], class_=["popup_msg"])
             html.a("x",
                    href="javascript:void(0)",
                    class_=["close"],
                    onclick="cmk.sidebar.message_close(\'%s\')" % msg['id'])
             html.write_text(msg['text'].replace('\n', '<br>\n'))
             html.close_div()
         if 'gui_popup' in msg['methods']:
             html.javascript(
                 'alert(\'%s\'); cmk.sidebar.mark_message_read("%s")' %
                 (escaping.escape_attribute(msg['text']).replace('\n', '\\n'), msg['id']))
Beispiel #20
0
    def _activate_changes(self, request):
        mode = request.get("mode", "dirty")
        if request.get("allow_foreign_changes"):
            allow_foreign_changes = bool(
                int(request.get("allow_foreign_changes")))
        else:
            allow_foreign_changes = False

        sites = request.get("sites")

        changes = watolib.ActivateChanges()
        changes.load()

        if changes.has_foreign_changes():
            if not config.user.may("wato.activateforeign"):
                raise MKAuthException(
                    _("You are not allowed to activate changes of other users."
                      ))
            if not allow_foreign_changes:
                raise MKAuthException(
                    _("There are changes from other users and foreign changes are not allowed in this API call."
                      ))

        if mode == "specific":
            for site in sites:
                if site not in config.allsites().keys():
                    raise MKUserError(
                        None,
                        _("Unknown site %s") % escaping.escape_attribute(site))

        manager = watolib.ActivateChangesManager()
        manager.load()

        if not manager.has_changes():
            raise MKUserError(None,
                              _("Currently there are no changes to activate."))

        if not sites:
            sites = manager.dirty_and_active_activation_sites()

        comment = request.get("comment", "").strip()
        if comment == "":
            comment = None

        manager.start(sites,
                      comment=comment,
                      activate_foreign=allow_foreign_changes)
        manager.wait_for_completion()
        return manager.get_state()
Beispiel #21
0
def check_title_uniqueness(forest):
    # Legacy, will be removed any decade from now
    # One aggregation cannot be in mutliple groups.
    known_titles: Set[Any] = set()
    for aggrs in forest.values():
        for aggr in aggrs:
            title = aggr["title"]
            if title in known_titles:
                raise MKConfigError(
                    _("Duplicate BI aggregation with the title \"<b>%s</b>\". "
                      "Please check your BI configuration and make sure that within each group no aggregation has "
                      "the same title as any other. Note: you can use arguments in the top level "
                      "aggregation rule, like <tt>Host $HOST$</tt>.") %
                    (escaping.escape_attribute(title)))
            known_titles.add(title)
Beispiel #22
0
    def _ajax_switch_masterstate(self):
        # type: () -> None
        html.set_output_format("text")

        if not config.user.may("sidesnap.master_control"):
            return

        if not html.check_transaction():
            return

        site = html.request.get_ascii_input_mandatory("site")
        column = html.request.get_ascii_input_mandatory("switch")
        state = html.request.get_integer_input_mandatory("state")
        commands = {
            ("enable_notifications", 1): "ENABLE_NOTIFICATIONS",
            ("enable_notifications", 0): "DISABLE_NOTIFICATIONS",
            ("execute_service_checks", 1): "START_EXECUTING_SVC_CHECKS",
            ("execute_service_checks", 0): "STOP_EXECUTING_SVC_CHECKS",
            ("execute_host_checks", 1): "START_EXECUTING_HOST_CHECKS",
            ("execute_host_checks", 0): "STOP_EXECUTING_HOST_CHECKS",
            ("enable_flap_detection", 1): "ENABLE_FLAP_DETECTION",
            ("enable_flap_detection", 0): "DISABLE_FLAP_DETECTION",
            ("process_performance_data", 1): "ENABLE_PERFORMANCE_DATA",
            ("process_performance_data", 0): "DISABLE_PERFORMANCE_DATA",
            ("enable_event_handlers", 1): "ENABLE_EVENT_HANDLERS",
            ("enable_event_handlers", 0): "DISABLE_EVENT_HANDLERS",
        }

        command = commands.get((column, state))
        if not command:
            html.write(
                _("Command %s/%d not found") %
                (escaping.escape_attribute(column), state))
            return

        sites.live().command("[%d] %s" % (int(time.time()), command), site)
        sites.live().set_only_sites([site])
        sites.live().query(
            "GET status\nWaitTrigger: program\nWaitTimeout: 10000\nWaitCondition: %s = %d\nColumns: %s\n"
            % (column, state, column))
        sites.live().set_only_sites()

        self.show()
Beispiel #23
0
def page_view() -> None:
    view_name = html.request.var("view_name")
    if not view_name:
        return page_index()

    view_spec = views.get_permitted_views().get(view_name)
    if not view_spec:
        raise MKUserError("view_name",
                          "No view defined with the name '%s'." % view_name)

    datasource = data_source_registry[view_spec["datasource"]]()
    context = visuals.get_merged_context(
        visuals.get_context_from_uri_vars(
            datasource.infos, single_infos=view_spec["single_infos"]),
        view_spec["context"],
    )

    view = views.View(view_name, view_spec, context)
    view.row_limit = views.get_limit()
    view.only_sites = visuals.get_only_sites_from_context(context)
    view.user_sorters = views.get_user_sorters()
    view.want_checkboxes = views.get_want_checkboxes()

    title = views.view_title(view.spec, view.context)
    mobile_html_head(title)

    # Need to be loaded before processing the painter_options below.
    # TODO: Make this dependency explicit
    display_options.load_from_html(html)

    painter_options = PainterOptions.get_instance()
    painter_options.load(view_name)

    try:
        views.process_view(MobileViewRenderer(view))
    except Exception as e:
        logger.exception("error showing mobile view")
        if config.debug:
            raise
        html.write("ERROR showing view: %s" %
                   escaping.escape_attribute(str(e)))

    mobile_html_foot()
Beispiel #24
0
    def _add_change_to_site(self, site_id, change_id, action_name, text, obj,
                            add_user, need_sync, need_restart, domains):
        # Individual changes may override the domain restart default value
        if need_restart is None:
            need_restart = any([d.needs_activation for d in domains])

        if need_sync is None:
            need_sync = any([d.needs_sync for d in domains])

        def serialize_object(obj):
            if obj is None:
                return None
            return obj.__class__.__name__, obj.ident()

        # Using attrencode here is against our regular rule to do the escaping
        # at the last possible time: When rendering. But this here is the last
        # place where we can distinguish between HTML() encapsulated (already)
        # escaped / allowed HTML and strings to be escaped.
        text = escaping.escape_attribute(text)

        SiteChanges(site_id).save_change({
            "id":
            change_id,
            "action_name":
            action_name,
            "text":
            "%s" % text,
            "object":
            serialize_object(obj),
            "user_id":
            config.user.id if add_user else None,
            "domains": [d.ident for d in domains],
            "time":
            time.time(),
            "need_sync":
            need_sync,
            "need_restart":
            need_restart,
        })
Beispiel #25
0
    def _push_snapshot_to_site(self):
        """Calls a remote automation call push-snapshot which is handled by AutomationPushSnapshot()"""
        site = config.site(self._site_id)

        url = html.makeuri_contextless(
            [
                ("command", "push-snapshot"),
                ("secret", site["secret"]),
                ("siteid", site["id"]),
                ("debug", config.debug and "1" or ""),
            ],
            filename=site["multisiteurl"] + "automation.py",
        )

        response_text = self._upload_file(url, site.get('insecure', False))

        try:
            return ast.literal_eval(response_text)
        except SyntaxError:
            raise cmk.gui.watolib.automations.MKAutomationException(
                _("Garbled automation response: <pre>%s</pre>") %
                (escaping.escape_attribute(response_text)))
Beispiel #26
0
def page_view() -> None:
    view_name = html.request.var("view_name")
    if not view_name:
        return page_index()

    view_spec = views.get_permitted_views().get(view_name)
    if not view_spec:
        raise MKUserError("view_name",
                          "No view defined with the name '%s'." % view_name)

    datasource = data_source_registry[view_spec["datasource"]]()
    context = visuals.get_merged_context(
        visuals.get_context_from_uri_vars(
            datasource.infos, single_infos=view_spec["single_infos"]),
        view_spec["context"],
    )

    view = views.View(view_name, view_spec, context)
    view.row_limit = views.get_limit()
    view.only_sites = views.get_only_sites()
    view.user_sorters = views.get_user_sorters()

    title = views.view_title(view_spec)
    mobile_html_head(title)

    painter_options = PainterOptions.get_instance()
    painter_options.load(view_name)

    try:
        view_renderer = MobileViewRenderer(view)
        views.show_view(view, view_renderer)
    except Exception as e:
        logger.exception("error showing mobile view")
        if config.debug:
            raise
        html.write("ERROR showing view: %s" %
                   escaping.escape_attribute(str(e)))

    mobile_html_foot()
Beispiel #27
0
def time_series_math(
        operator_id: Literal["+", "*", "-", "/", "MAX", "MIN", "AVERAGE",
                             "MERGE"],
        operands_evaluated: List[TimeSeries]) -> Optional[TimeSeries]:
    operators = time_series_operators()
    if operator_id not in operators:
        raise MKGeneralException(
            _("Undefined operator '%s' in graph expression") %
            escaping.escape_attribute(operator_id))
    # Test for correct arity on FOUND[evaluated] data
    if any((
            operator_id in ["-", "/"] and len(operands_evaluated) != 2,
            len(operands_evaluated) < 1,
    )):
        #raise MKGeneralException(_("Incorrect amount of data to correctly evaluate expression"))
        # Silently return so to get an empty graph slot
        return None

    _op_title, op_func = operators[operator_id]
    twindow = operands_evaluated[0].twindow

    return TimeSeries(
        [op_func_wrapper(op_func, tsp) for tsp in zip(*operands_evaluated)],
        twindow)
    def _show_test_row(self, table, test_id, test_results_by_site, site_ids):
        table.row()

        table.cell(_("Actions"), css="buttons", sortable=False)
        html.icon_button(
            None,
            _("Toggle result details"),
            "toggle_details",
            onclick="cmk.wato.toggle_container('test_result_details_%s')" %
            test_id)

        worst_result = sorted(test_results_by_site["site_results"].values(),
                              key=lambda result: result.status)[0]

        # Disabling of test in total
        is_test_disabled = self._is_test_disabled(test_id)
        if is_test_disabled:
            html.icon_button(
                html.makeactionuri([
                    ("_do", "enable"),
                    ("_test_id", worst_result.test_id),
                ]),
                _("Reenable this test"),
                "enable_test",
            )
        else:
            html.icon_button(
                html.makeactionuri([
                    ("_do", "disable"),
                    ("_test_id", worst_result.test_id),
                ]),
                _("Disable this test"),
                "disable_test",
            )

        # assume all have the same test meta information (title, help, ...)
        table.cell(_("Title"),
                   css="title " + "stale" if is_test_disabled else "")
        html.write_text(test_results_by_site["test"]["title"])

        # Now loop all sites to display their results
        for site_id in site_ids:
            if is_test_disabled:
                table.cell(site_id, "")
                table.cell("", "")
                continue

            result = test_results_by_site["site_results"].get(site_id)
            if result is None:
                table.cell(site_id, css="state state-1")
                table.cell("", css="buttons")
                continue

            is_acknowledged = self._is_acknowledged(result)

            if is_acknowledged or result.status == -1:
                css = "state stale"
            else:
                css = "state state%d" % result.status

            table.cell(site_id, css=css)
            html.open_div(title=result.text)
            html.write_text(result.status_name())
            html.close_div()

            table.cell("", css="buttons")

            if result.status != 0:
                if is_acknowledged:
                    html.icon_button(
                        html.makeactionuri([
                            ("_do", "unack"),
                            ("_site_id", result.site_id),
                            ("_status_id", result.status),
                            ("_test_id", result.test_id),
                        ]),
                        _("Unacknowledge this test result for site %s") %
                        site_id,
                        "unacknowledge_test",
                    )
                else:
                    html.icon_button(
                        html.makeactionuri([
                            ("_do", "ack"),
                            ("_site_id", result.site_id),
                            ("_status_id", result.status),
                            ("_test_id", result.test_id),
                        ]),
                        _("Acknowledge this test result for site %s") %
                        site_id,
                        "acknowledge_test",
                    )
            else:
                html.write("")

        # Add toggleable notitication context
        table.row(class_="ac_test_details hidden",
                  id_="test_result_details_%s" % test_id)
        table.cell(colspan=2 + 2 * len(site_ids))

        html.write_text(test_results_by_site["test"]["help"])

        if not is_test_disabled:
            html.open_table()
            for site_id in site_ids:
                result = test_results_by_site["site_results"].get(site_id)
                if result is None:
                    continue

                html.open_tr()
                html.td(escaping.escape_attribute(site_id))
                html.td("%s: %s" % (result.status_name(), result.text))
                html.close_tr()
            html.close_table()

        # This dummy row is needed for not destroying the odd/even row highlighting
        table.row(class_="hidden")
Beispiel #29
0
def heading(text):
    html.write("<h3>%s</h3>\n" % escaping.escape_attribute(text))
Beispiel #30
0
    def _show_host_row(self, rendered_hosts, table, hostname, search_text,
                       show_checkboxes, colspan, host_errors,
                       contact_group_names):
        if search_text and (search_text.lower() not in hostname.lower()):
            return

        host = self._folder.host(hostname)
        rendered_hosts.append(hostname)
        effective = host.effective_attributes()

        table.row()

        # Column with actions (buttons)

        if show_checkboxes:
            table.cell(html.render_input(
                "_toggle_group",
                type_="button",
                class_="checkgroup",
                onclick="cmk.selection.toggle_all_rows();",
                value='X'),
                       sortable=False,
                       css="checkbox")
            # Use CSS class "failed" in order to provide information about
            # selective toggling inventory-failed hosts for Javascript
            html.input(name="_c_%s" % hostname,
                       type_="checkbox",
                       value=colspan,
                       class_="failed" if host.discovery_failed() else None)
            html.label("", "_c_%s" % hostname)

        table.cell(_("Actions"), css="buttons", sortable=False)
        self._show_host_actions(host)

        # Hostname with link to details page (edit host)
        table.cell(_("Hostname"))
        errors = host_errors.get(hostname, []) + host.validation_errors()
        if errors:
            msg = _("Warning: This host has an invalid configuration: ")
            msg += ", ".join(errors)
            html.icon(msg, "validation_error")
            html.nbsp()

        if host.is_offline():
            html.icon(_("This host is disabled"), "disabled")
            html.nbsp()

        if host.is_cluster():
            html.icon(
                _("This host is a cluster of %s") %
                ", ".join(host.cluster_nodes()), "cluster")
            html.nbsp()

        html.a(hostname, href=host.edit_url())

        # Show attributes
        for attr in host_attribute_registry.attributes():
            if attr.show_in_table():
                attrname = attr.name()
                if attrname in host.attributes():
                    tdclass, tdcontent = attr.paint(
                        host.attributes()[attrname], hostname)
                else:
                    tdclass, tdcontent = attr.paint(effective.get(attrname),
                                                    hostname)
                    tdclass += " inherited"
                table.cell(attr.title(),
                           escaping.escape_attribute(tdcontent),
                           css=tdclass)

        # Am I authorized?
        reason = host.reason_why_may_not("read")
        if not reason:
            icon = "authok"
            title = _("You have permission to this host.")
        else:
            icon = "autherr"
            title = escaping.strip_tags(reason)

        table.cell(_('Auth'),
                   html.render_icon(icon, title),
                   css="buttons",
                   sortable=False)

        # Permissions and Contact groups - through complete recursion and inhertance
        permitted_groups, host_contact_groups, _use_for_services = host.groups(
        )
        table.cell(
            _("Permissions"),
            HTML(", ").join([
                self._render_contact_group(contact_group_names, g)
                for g in permitted_groups
            ]))
        table.cell(
            _("Contact Groups"),
            HTML(", ").join([
                self._render_contact_group(contact_group_names, g)
                for g in host_contact_groups
            ]))

        if not config.wato_hide_hosttags:
            table.cell(_("Tags"), css="tag-ellipsis")
            tag_groups, show_all_code = self._limit_labels(host.tag_groups())
            html.write(
                cmk.gui.view_utils.render_tag_groups(tag_groups,
                                                     "host",
                                                     with_links=False))
            html.write(show_all_code)

        table.cell(_("Explicit labels"), css="tag-ellipsis")
        labels, show_all_code = self._limit_labels(host.labels())
        html.write(
            cmk.gui.view_utils.render_labels(
                labels,
                "host",
                with_links=False,
                label_sources={k: "explicit"
                               for k in labels.keys()}))
        html.write(show_all_code)

        # Located in folder
        if self._folder.is_search_folder():
            table.cell(_("Folder"))
            html.a(host.folder().alias_path(), href=host.folder().url())