Exemple #1
0
def render_mobile_dataset(rows, view, group_cells, cells, num_columns, show_checkboxes):
    if not is_mobile(request, response):
        html.show_error(_("This view can only be used in mobile mode."))
        return

    painter_options = PainterOptions.get_instance()
    painter_options.set("ts_format", "both")

    for row in rows:
        html.open_table(class_="dataset")
        for cell in cells:
            _tdclass, content = cell.render(row)
            if not content:
                continue  # Omit empty cells

            html.open_tr(class_="header")
            html.th(cell.title())
            html.close_tr()

            html.open_tr(class_="data")
            cell.paint(row)
            html.close_tr()

        html.close_table()
    html.javascript(
        '$("table.dataset > tbody > tr.data > td").addClass("ui-shadow").not(".state").addClass("nonstatus");\n'
        '$("table.dataset > tbody > tr.data a").attr("data-ajax", "false");\n')
Exemple #2
0
 def werk_table_row(caption, content, css=None):
     html.open_tr()
     html.th(caption)
     html.open_td(class_=css)
     html.write(content)
     html.close_td()
     html.close_tr()
Exemple #3
0
    def _show_header_line(self, cells, num_columns, show_checkboxes):
        html.open_tr()
        for n in range(1, num_columns + 1):
            if show_checkboxes:
                if n == 1:
                    render_group_checkbox_th()
                else:
                    html.th("")

            for cell in cells:
                cell.paint_as_header()

            if n < num_columns:
                html.td("", class_="gap")

        html.close_tr()
Exemple #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", "&#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()
Exemple #5
0
    def _show_ruleset(self, varname):
        if varname not in rulespec_registry:
            return

        rulespec = rulespec_registry[varname]
        url = makeuri_contextless(request, [("mode", "edit_ruleset"), ("varname", varname)])
        html.open_tr()
        html.th(_("Parameter rule set"))
        html.open_td()
        html.icon_button(url, _("Edit parameter rule set for this check type"), "check_parameters")
        html.a(rulespec.title, url)
        html.close_td()
        html.close_tr()
        html.open_tr()
        html.th(_("Example for Parameters"))
        html.open_td()
        vs = rulespec.valuespec
        vs.render_input("dummy", vs.default_value())
        html.close_td()
        html.close_tr()
    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()
 def show_job_row_headers(cls):
     html.open_tr()
     for header in cls.get_headers():
         html.th(header)
     html.close_tr()
    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;"
        )
Exemple #9
0
    def _show_rows(self):
        rows = self._get_rows()

        if bool([r for r in rows if r.stats is None]):
            html.center(_("No data from any site"))
            return

        html.open_table(class_=["content_center", "tacticaloverview"],
                        cellspacing="2",
                        cellpadding="0",
                        border="0")

        show_stales = self.parameters()["show_stale"] and config.user.may(
            "general.see_stales_in_tactical_overview")
        has_stale_objects = bool([r for r in rows if r.what != "events" and r.stats[-1]])

        for row in rows:
            if row.what == "events":
                amount, problems, unhandled_problems = row.stats
                stales = 0

                # no events open and disabled in local site: don't show events
                if amount == 0 and not config.mkeventd_enabled:
                    continue
            else:
                amount, problems, unhandled_problems, stales = row.stats

            context_vars = get_context_url_variables(row.context)

            html.open_tr()
            html.th(row.title)
            html.th(_("Problems"))
            html.th(_("Unhandled"))
            if show_stales and has_stale_objects:
                html.th(_("Stale"))
            html.close_tr()

            td_class = 'col4' if has_stale_objects else 'col3'

            html.open_tr()
            url = html.makeuri_contextless(row.views.total + context_vars, filename="view.py")
            html.open_td(class_=["total", td_class])
            html.a("%s" % amount, href=url, target="main")
            html.close_td()

            for value, ty in [(problems, "handled"), (unhandled_problems, "unhandled")]:
                url = html.makeuri_contextless(getattr(row.views, ty) + context_vars,
                                               filename="view.py")
                html.open_td(class_=[td_class, "states prob" if value != 0 else None])
                link(str(value), url)
                html.close_td()

            if show_stales and has_stale_objects:
                if row.views.stale:
                    url = html.makeuri_contextless(row.views.stale + context_vars,
                                                   filename="view.py")
                    html.open_td(class_=[td_class, "states prob" if stales != 0 else None])
                    link(str(stales), url)
                    html.close_td()
                else:
                    html.td(html.render_span("0"))

            html.close_tr()
        html.close_table()
Exemple #10
0
    def show(self):
        pie_id = "dashlet_%d" % self._dashlet_id
        pie_diameter = 130
        pie_left_aspect = 0.5
        pie_right_aspect = 0.8
        table = self._table()

        filter_headers, only_sites = visuals.get_filter_headers(
            table=self._livestatus_table(),
            infos=self.infos(),
            context=self.context)

        query = "GET %s\n" % self._livestatus_table()
        for entry in table:
            query += entry[3]
        query += self._filter() + filter_headers

        if only_sites:
            try:
                sites.live().set_only_sites(only_sites)
                result = sites.live().query_row(query)
            finally:
                sites.live().set_only_sites()
        else:
            try:
                result = sites.live().query_summed_stats(query)
            except MKLivestatusNotFoundError:
                result = []

        pies = list(zip(table, result))
        total = sum([x[1] for x in pies])

        html.open_div(class_="stats")
        html.canvas('',
                    class_="pie",
                    id_="%s_stats" % pie_id,
                    width=pie_diameter,
                    height=pie_diameter,
                    style="float: left")
        html.img(html.theme_url("images/globe.png"), class_="globe")

        html.open_table(class_=["hoststats"] +
                        (["narrow"] if len(pies) > 0 else []),
                        style="float:left")

        table_entries = pies
        while len(table_entries) < 6:
            table_entries = table_entries + [(
                ("", None, [], ""), HTML("&nbsp;"))]
        table_entries.append(((_("Total"), "", [], ""), total))

        for (name, color, table_url_vars, query), count in table_entries:
            url_vars = [
                ("view_name", self._view_name()),
                ("filled_in", "filter"),
                ("search", "1"),
            ] + table_url_vars + self._dashlet_context_vars()
            url = html.makeuri_contextless(url_vars, filename="view.py")

            html.open_tr()
            html.th(html.render_a(name, href=url))
            html.td('',
                    class_="color",
                    style="background-color: %s" % color if color else '')
            html.td(html.render_a(count, href=url))
            html.close_tr()

        html.close_table()

        pie_parts = []
        if total > 0:
            # Count number of non-empty classes
            num_nonzero = 0
            for _info, value in pies:
                if value > 0:
                    num_nonzero += 1

            # Each non-zero class gets at least a view pixels of visible thickness.
            # We reserve that space right now. All computations are done in percent
            # of the radius.
            separator = 0.02  # 3% of radius
            remaining_separatorspace = num_nonzero * separator  # space for separators
            remaining_radius = 1 - remaining_separatorspace  # remaining space
            remaining_part = 1.0  # keep track of remaining part, 1.0 = 100%

            # Loop over classes, begin with most outer sphere. Inner spheres show
            # worse states and appear larger to the user (which is the reason we
            # are doing all this stuff in the first place)
            for (name, color, _unused, _q), value in pies[::1]:
                if value > 0 and remaining_part > 0:  # skip empty classes

                    # compute radius of this sphere *including all inner spheres!* The first
                    # sphere always gets a radius of 1.0, of course.
                    radius = remaining_separatorspace + remaining_radius * (
                        remaining_part**(1 / 3.0))
                    pie_parts.append('chart_pie("%s", %f, %f, %r, true);' %
                                     (pie_id, pie_right_aspect, radius, color))
                    pie_parts.append('chart_pie("%s", %f, %f, %r, false);' %
                                     (pie_id, pie_left_aspect, radius, color))

                    # compute relative part of this class
                    part = float(value) / total  # ranges from 0 to 1
                    remaining_part -= part
                    remaining_separatorspace -= separator

        html.close_div()

        html.javascript(
            """
function chart_pie(pie_id, x_scale, radius, color, right_side) {
    var context = document.getElementById(pie_id + "_stats").getContext('2d');
    if (!context)
        return;
    var pie_x = %(x)f;
    var pie_y = %(y)f;
    var pie_d = %(d)f;
    context.fillStyle = color;
    context.save();
    context.translate(pie_x, pie_y);
    context.scale(x_scale, 1);
    context.beginPath();
    if(right_side)
        context.arc(0, 0, (pie_d / 2) * radius, 1.5 * Math.PI, 0.5 * Math.PI, false);
    else
        context.arc(0, 0, (pie_d / 2) * radius, 0.5 * Math.PI, 1.5 * Math.PI, false);
    context.closePath();
    context.fill();
    context.restore();
    context = null;
}


if (cmk.dashboard.has_canvas_support()) {
    %(p)s
}
""" % {
                "x": int(pie_diameter / 2.0),
                "y": int(pie_diameter / 2.0),
                "d": pie_diameter,
                'p': '\n'.join(pie_parts)
            })
Exemple #11
0
    def show(self):
        # pie_id, what, table, filter, dashlet):
        pie_id = "dashlet_%d" % self._dashlet_id
        pie_diameter = 130
        pie_left_aspect = 0.5
        pie_right_aspect = 0.8
        what = self._livestatus_table()
        table = self._table()
        filter_ = self._filter()

        if what == 'hosts':
            info = 'host'
            infos = [info]
        else:
            info = 'service'
            infos = ['host', 'service']
        use_filters = visuals.filters_of_visual(self._dashlet_spec, infos)
        for filt in use_filters:
            if filt.available() and not isinstance(filt, FilterCRESite):
                filter_ += filt.filter(info)

        query = "GET %s\n" % what
        for entry in table:
            query += entry[3]
        query += filter_

        site = self._dashlet_spec['context'].get('siteopt', {}).get('site')
        if site:
            sites.live().set_only_sites([site])
            result = sites.live().query_row(query)
            sites.live().set_only_sites()
        else:
            try:
                result = sites.live().query_summed_stats(query)
            except MKLivestatusNotFoundError:
                result = []

        pies = zip(table, result)
        total = sum([x[1] for x in pies])

        html.open_div(class_="stats")
        html.canvas('',
                    class_="pie",
                    id_="%s_stats" % pie_id,
                    width=pie_diameter,
                    height=pie_diameter,
                    style="float: left")
        html.img(html.theme_url("images/globe.png"), class_="globe")

        html.open_table(class_=["hoststats"] +
                        (["narrow"] if len(pies) > 0 else []),
                        style="float:left")

        table_entries = pies
        while len(table_entries) < 6:
            table_entries = table_entries + [(
                ("", None, "", ""), HTML("&nbsp;"))]
        table_entries.append(((_("Total"), "", "all%s" % what, ""), total))

        for (name, color, viewurl, query), count in table_entries:
            url = "view.py?view_name=" + viewurl + "&filled_in=filter&search=1"
            for filter_name, url_params in self._dashlet_spec['context'].items(
            ):
                if filter_name == "wato_folder" and html.request.has_var(
                        "wato_folder"):
                    url += "&wato_folder=" + html.request.var("wato_folder")

                elif filter_name == "svcstate":
                    # The svcstate filter URL vars are controlled by dashlet
                    continue

                else:
                    url += '&' + html.urlencode_vars(url_params.items())

            html.open_tr()
            html.th(html.render_a(name, href=url))
            html.td('',
                    class_="color",
                    style="background-color: %s" % color if color else '')
            html.td(html.render_a(count, href=url))
            html.close_tr()

        html.close_table()

        pie_parts = []
        if total > 0:
            # Count number of non-empty classes
            num_nonzero = 0
            for info, value in pies:
                if value > 0:
                    num_nonzero += 1

            # Each non-zero class gets at least a view pixels of visible thickness.
            # We reserve that space right now. All computations are done in percent
            # of the radius.
            separator = 0.02  # 3% of radius
            remaining_separatorspace = num_nonzero * separator  # space for separators
            remaining_radius = 1 - remaining_separatorspace  # remaining space
            remaining_part = 1.0  # keep track of remaining part, 1.0 = 100%

            # Loop over classes, begin with most outer sphere. Inner spheres show
            # worse states and appear larger to the user (which is the reason we
            # are doing all this stuff in the first place)
            for (name, color, viewurl, _q), value in pies[::1]:
                if value > 0 and remaining_part > 0:  # skip empty classes

                    # compute radius of this sphere *including all inner spheres!* The first
                    # sphere always gets a radius of 1.0, of course.
                    radius = remaining_separatorspace + remaining_radius * (
                        remaining_part**(1 / 3.0))
                    pie_parts.append('chart_pie("%s", %f, %f, %r, true);' %
                                     (pie_id, pie_right_aspect, radius, color))
                    pie_parts.append('chart_pie("%s", %f, %f, %r, false);' %
                                     (pie_id, pie_left_aspect, radius, color))

                    # compute relative part of this class
                    part = float(value) / total  # ranges from 0 to 1
                    remaining_part -= part
                    remaining_separatorspace -= separator

        html.close_div()

        html.javascript(
            """
function chart_pie(pie_id, x_scale, radius, color, right_side) {
    var context = document.getElementById(pie_id + "_stats").getContext('2d');
    if (!context)
        return;
    var pie_x = %(x)f;
    var pie_y = %(y)f;
    var pie_d = %(d)f;
    context.fillStyle = color;
    context.save();
    context.translate(pie_x, pie_y);
    context.scale(x_scale, 1);
    context.beginPath();
    if(right_side)
        context.arc(0, 0, (pie_d / 2) * radius, 1.5 * Math.PI, 0.5 * Math.PI, false);
    else
        context.arc(0, 0, (pie_d / 2) * radius, 0.5 * Math.PI, 1.5 * Math.PI, false);
    context.closePath();
    context.fill();
    context.restore();
    context = null;
}


if (cmk.dashboard.has_canvas_support()) {
    %(p)s
}
""" % {
                "x": int(pie_diameter / 2.0),
                "y": int(pie_diameter / 2.0),
                "d": pie_diameter,
                'p': '\n'.join(pie_parts)
            })
Exemple #12
0
def _show_graph_legend(graph_artwork, graph_render_options) -> None:
    """Render legend that describe the metrics"""
    graph_width = graph_render_options["size"][0] * html_size_per_ex
    font_size_style = "font-size: %dpt;" % graph_render_options["font_size"]

    scalars = get_scalars(graph_artwork, graph_render_options)

    if graph_render_options["show_vertical_axis"] or graph_render_options[
            "show_controls"]:
        legend_margin_left = 49
    else:
        legend_margin_left = 0

    style = []
    legend_width = graph_width - legend_margin_left

    # In case there is no margin show: Add some to the legend since it looks
    # ugly when there is no space between the outer graph border and the legend
    if not graph_render_options["show_margin"]:
        legend_width -= 5 * 2
        style.append("margin: 8px 5px 5px 5px")

    style.append("width:%dpx" % legend_width)

    if legend_margin_left:
        style.append("margin-left:%dpx" % legend_margin_left)

    html.open_table(class_="legend", style=style)

    # Render the title row
    html.open_tr()
    html.th("")
    for scalar, title, inactive in scalars:
        classes = ["scalar", scalar]
        if inactive and graph_artwork["step"] != 60:
            descr = _(
                "This graph is based on data consolidated with the function \"%s\". The "
                "values in this column are the \"%s\" values of the \"%s\" values "
                "aggregated in %s steps. Assuming a check interval of 1 minute, the %s "
                "values here are based on the %s value out of %d raw values."
            ) % (
                graph_artwork["definition"]["consolidation_function"],
                scalar,
                graph_artwork["definition"]["consolidation_function"],
                artwork.get_step_label(graph_artwork["step"]),
                scalar,
                graph_artwork["definition"]["consolidation_function"],
                (graph_artwork["step"] / 60),
            )

            descr += "\n\n" + _("Click here to change the graphs "
                                "consolidation function to \"%s\".") % scalar

            classes.append("inactive")
        else:
            descr = ""

        html.th(title, class_=classes, style=font_size_style, title=descr)
    html.close_tr()

    # Render the curve related rows
    for curve in graph_curves(graph_artwork):
        html.open_tr()
        html.open_td(style=font_size_style)
        html.write_html(render_color_icon(curve["color"]))
        html.write_text(curve["title"])
        html.close_td()

        for scalar, title, inactive in scalars:
            if scalar == "pin" and not show_pin_time(graph_artwork,
                                                     graph_render_options):
                continue

            if inactive and graph_artwork["step"] != 60:
                inactive_cls: Optional[str] = "inactive"
            else:
                inactive_cls = None

            html.td(curve["scalars"][scalar][1],
                    class_=inactive_cls,
                    style=font_size_style)

        html.close_tr()

    # Render scalar values
    if graph_artwork["horizontal_rules"]:
        first = True
        for _value, readable, color, title in graph_artwork[
                "horizontal_rules"]:
            html.open_tr(class_=["scalar", "first" if first else None])
            html.open_td(style=font_size_style)
            html.write_html(render_color_icon(color))
            html.write_text(title)
            html.close_td()

            # A colspan of 5 has to be used here, since the pin that is added by a click into
            # the graph introduces a new column.
            html.td(readable,
                    colspan=5,
                    class_="scalar",
                    style=font_size_style)
            html.close_tr()
            first = False

    html.close_table()