Exemple #1
0
def _sort_rows(rows, sort_col, sort_reverse):

    # remove and remind fixed rows, add to separate list
    fixed_rows = []
    for index, row_spec in enumerate(rows[:]):
        if row_spec[3] is True:
            rows.remove(row_spec)
            fixed_rows.append((index, row_spec))

    # Then use natural sorting to sort the list. Note: due to a
    # change in the number of columns of a table in different software
    # versions the cmp-function might fail. This is because the sorting
    # column is persisted in a user file. So we ignore exceptions during
    # sorting. This gives the user the chance to change the sorting and
    # see the table in the first place.
    try:
        rows.sort(cmp=lambda a, b: utils.cmp_num_split(
            html.strip_tags(a[0][sort_col][0]),
            html.strip_tags(b[0][sort_col][0])),
                  reverse=sort_reverse == 1)
    except IndexError:
        pass

    # Now re-add the removed "fixed" rows to the list again
    if fixed_rows:
        for index, row_spec in fixed_rows:
            rows.insert(index, row_spec)

    return rows
Exemple #2
0
    def render(self, rows, view, group_cells, cells, num_columns,
               show_checkboxes):
        painted_rows = []

        header_row = []
        for cell in cells:
            header_row.append(html.strip_tags(cell.export_title()))
        painted_rows.append(header_row)

        for row in rows:
            painted_row = []
            for cell in cells:
                joined_row = join_row(row, cell)
                content = cell.render_content(joined_row)[1]
                if isinstance(content, (list, dict)):
                    # Allow painters to return lists and dicts, then json encode them
                    # as such data structures without wrapping them into strings
                    pass

                else:
                    if isinstance(content, six.text_type):
                        content = content.encode("utf-8")
                    else:
                        content = "%s" % content
                    content = html.strip_tags(content.replace("<br>", "\n"))

                painted_row.append(content)

            painted_rows.append(painted_row)

        html.write(json.dumps(painted_rows, indent=True))
Exemple #3
0
    def _write_csv(self, csv_separator):

        rows = self.rows
        headers = self.headers
        limit = self.limit
        omit_headers = self.options["omit_headers"]

        # Apply limit after search / sorting etc.
        if limit is not None:
            rows = rows[:limit]

        # If we have no group headers then paint the headers now
        if not omit_headers and self.rows and self.rows[0][2] != "header":
            html.write(
                csv_separator.join([
                    html.strip_tags(header) or ""
                    for (header, _css, _help, _sortable) in headers
                ]) + "\n")

        for row_spec, _css, _state, _fixed, _attrs in rows:
            html.write(
                csv_separator.join([
                    html.strip_tags(cell_content)
                    for cell_content, _css_classes, _colspan in row_spec
                ]))
            html.write("\n")
Exemple #4
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()
            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])
Exemple #5
0
def do_site_login(site_id, name, password):
    sites = SiteManagementFactory().factory().load_sites()
    site = sites[site_id]
    if not name:
        raise MKUserError("_name", _("Please specify your administrator login on the remote site."))
    if not password:
        raise MKUserError("_passwd", _("Please specify your password."))

    # Trying basic auth AND form based auth to ensure the site login works.
    # Adding _ajaxid makes the web service fail silently with an HTTP code and
    # not output HTML code for an error screen.
    url = site["multisiteurl"] + 'login.py'
    post_data = {
        '_login': '******',
        '_username': name,
        '_password': password,
        '_origtarget': 'automation_login.py?_version=%s&_edition_short=%s' % (cmk.__version__,
                                                                              cmk.edition_short()),
        '_plain_error': '1',
    }
    response = get_url(
        url, site.get('insecure', False), auth=(name, password), data=post_data).strip()
    if '<html>' in response.lower():
        message = _("Authentication to web service failed.<br>Message:<br>%s") % \
            html.strip_tags(html.strip_scripts(response))
        if config.debug:
            message += "<br>" + _("Automation URL:") + " <tt>%s</tt><br>" % url
        raise MKAutomationException(message)
    elif not response:
        raise MKAutomationException(_("Empty response from web service"))
    else:
        try:
            return ast.literal_eval(response)
        except SyntaxError:
            raise MKAutomationException(response)
Exemple #6
0
 def _show_subfolder_hoverarea(self, subfolder):
     # Only make folder openable when permitted to edit
     if subfolder.may("read"):
         html.open_div(class_="hoverarea",
                       onmouseover="cmk.wato.toggle_folder(event, this, true);",
                       onmouseout="cmk.wato.toggle_folder(event, this, false);")
         self._show_subfolder_buttons(subfolder)
         html.close_div()  # hoverarea
     else:
         html.icon(html.strip_tags(subfolder.reason_why_may_not("read")),
                   "autherr",
                   class_=["autherr"])
         html.div('', class_="hoverarea")
Exemple #7
0
 def render(self, rows, view, group_cells, cells, num_columns,
            show_checkboxes):
     html.write_text("[\n")
     html.write(repr([cell.export_title() for cell in cells]))
     html.write_text(",\n")
     for row in rows:
         html.write_text("[")
         for cell in cells:
             joined_row = join_row(row, cell)
             _tdclass, content = cell.render_content(joined_row)
             html.write(repr(html.strip_tags(content)))
             html.write_text(",")
         html.write_text("],")
     html.write_text("\n]\n")
Exemple #8
0
def section(title=None,
            checkbox=None,
            section_id=None,
            simple=False,
            hide=False,
            legend=True,
            css=None):
    global g_section_open
    if g_section_open:
        html.close_td()
        html.close_tr()
    html.open_tr(id_=section_id,
                 class_=[css],
                 style="display:none;" if hide else None)

    if legend:
        html.open_td(class_=["legend", "simple" if simple else None])
        if title:
            html.open_div(
                class_=["title", "withcheckbox" if checkbox else None],
                title=html.strip_tags(title))
            html.write(html.permissive_attrencode(title))
            html.span('.' * 100, class_="dots")
            html.close_div()
        if checkbox:
            html.open_div(class_="checkbox")
            if isinstance(checkbox, six.string_types + (HTML, )):
                html.write(checkbox)
            else:
                name, active, attrname = checkbox
                html.checkbox(
                    name,
                    active,
                    onclick='cmk.wato.toggle_attribute(this, \'%s\')' %
                    attrname)
            html.close_div()
        html.close_td()
    html.open_td(class_=["content", "simple" if simple else None])
    g_section_open = True
Exemple #9
0
def show_crash_dump_message(crash, plain_text, fail_silently):
    # type: (GUICrashReport, bool, bool) -> None
    """Create a crash dump from a GUI exception and display a message to the user"""

    title = _("Internal error")
    message = u"%s: %s<br>\n<br>\n" % (title, crash.crash_info["exc_value"])
    # Do not reveal crash context information to unauthenticated users or not permitted
    # users to prevent disclosure of internal information
    if not config.user.may("general.see_crash_reports"):
        message += _(
            "An internal error occurred while processing your request. "
            "You can report this issue to your Checkmk administrator. "
            "Detailed information can be found on the crash report page "
            "or in <tt>var/log/web.log</tt>.")
    else:
        crash_url = html.makeuri(
            [
                ("site", config.omd_site()),
                ("crash_id", crash.ident_to_text()),
            ],
            filename="crash.py",
        )
        message += _(
            "An internal error occured while processing your request. "
            "You can report this issue to the Checkmk team to help "
            "fixing this issue. Please open the <a href=\"%s\">crash report page</a> "
            "and use the form for reporting the problem.") % crash_url

    if plain_text:
        html.set_output_format("text")
        html.write("%s\n" % html.strip_tags(message))
        return

    if fail_silently:
        return

    html.header(title)
    html.show_error(message)
    html.footer()
Exemple #10
0
def log_audit(linkinfo, action, message, user_id=None):
    if config.wato_use_git:
        if isinstance(message, HTML):
            message = html.strip_tags(message.value)
        cmk.gui.watolib.git.add_message(message)
    log_entry(linkinfo, action, message, user_id)
Exemple #11
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(),
                           html.attrencode(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 = html.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())
Exemple #12
0
 def _format_for_csv(self, raw_data):
     # raw_data can also be int, float
     content = "%s" % raw_data
     stripped = html.strip_tags(content).replace('\n',
                                                 '').replace('"', '""')
     return stripped.encode("utf-8")
Exemple #13
0
    def _show_configuration_variables(self, groups):
        search_form(_("Search for settings:"))
        search = self._search

        html.open_div(class_="filter_buttons")
        if self._show_only_modified:
            html.buttonlink(html.makeuri([], delvars=["show_only_modified"]),
                            _("Show all settings"))
        else:
            html.buttonlink(html.makeuri([("show_only_modified", "1")]),
                            _("Show only modified settings"))
        html.close_div()

        at_least_one_painted = False
        html.open_div(class_="globalvars")
        for group in sorted(groups, key=lambda g: g.sort_index()):
            header_is_painted = False  # needed for omitting empty groups

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

                if not config_variable.domain().enabled():
                    continue

                if config_variable.domain(
                ) == watolib.ConfigDomainCore and varname not in self._default_values:
                    if config.debug:
                        raise MKGeneralException(
                            "The configuration variable <tt>%s</tt> is unknown to "
                            "your local Check_MK installation" % varname)
                    else:
                        continue

                if not config_variable.in_global_settings():
                    continue

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

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

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

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

                default_value = self._default_values[varname]

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

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

                try:
                    to_text = valuespec.value_to_text(value)
                except Exception:
                    logger.exception()
                    to_text = html.render_error(
                        _("Failed to render value: %r") % value)

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

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

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

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

            if header_is_painted:
                forms.end()
        if not at_least_one_painted and search:
            html.message(
                _('Did not find any global setting matching your search.'))
        html.close_div()