def paint(self, value, hostname): value = convert_cgroups_from_tuple(value) texts: List[HTML] = [] self.load_data() if self._contactgroups is None: # conditional caused by horrible API raise Exception("invalid contact groups") items = self._contactgroups.items() for name, cgroup in sorted(items, key=lambda x: x[1]["alias"]): if name in value["groups"]: display_name = cgroup.get("alias", name) texts.append( HTMLWriter.render_a( display_name, href=makeuri_contextless( request, [("mode", "edit_contact_group"), ("edit", name)], filename="wato.py", ), )) result: HTML = HTML(", ").join(texts) if texts and value["use"]: result += HTMLWriter.render_span( HTMLWriter.render_b("*"), title= _("These contact groups are also used in the monitoring configuration." ), ) return "", result
def _paint_aggr_state_short(state, assumed=False): if state is None: return "", "" name = short_service_state_name(state["state"], "") classes = "state svcstate state%s" % state["state"] if assumed: classes += " assumed" return classes, HTMLWriter.render_span(name, class_=["state_rounded_fill"])
def page(self): with table_element("roles") as table: users = userdb.load_users() for rid, role in sorted(self._roles.items(), key=lambda a: (a[1]["alias"], a[0])): table.row() # Actions table.cell(_("Actions"), css=["buttons"]) edit_url = folder_preserving_link([("mode", "edit_role"), ("edit", rid)]) clone_url = make_action_link([("mode", "roles"), ("_clone", rid)]) delete_url = make_confirm_link( url=make_action_link([("mode", "roles"), ("_delete", rid)]), message=_("Do you really want to delete the role %s?") % rid, ) html.icon_button(edit_url, _("Properties"), "edit") html.icon_button(clone_url, _("Clone"), "clone") if not role.get("builtin"): html.icon_button(delete_url, _("Delete this role"), "delete") # ID table.cell(_("Name"), rid) # Alias table.cell(_("Alias"), role["alias"]) # Type table.cell(_("Type"), _("builtin") if role.get("builtin") else _("custom")) # Modifications table.cell( _("Modifications"), HTMLWriter.render_span( str(len(role["permissions"])), title=_("That many permissions do not use the factory defaults."), ), ) # Users table.cell( _("Users"), HTML(", ").join( [ HTMLWriter.render_a( user.get("alias", user_id), folder_preserving_link([("mode", "edit_user"), ("edit", user_id)]), ) for (user_id, user) in users.items() if rid in user["roles"] ] ), )
def _render_tag_group( tag_group_id_or_label_key: Union[TaggroupID, str], tag_id_or_label_value: Union[TagID, str], object_type: str, with_link: bool, label_type: str, label_source: str, ) -> HTML: span = HTMLWriter.render_tag( HTMLWriter.render_div( HTMLWriter.render_span( "%s:%s" % ( tag_group_id_or_label_key, tag_id_or_label_value, ), class_=["tagify__tag-text"], ) ), class_=["tagify--noAnim", label_source], ) if not with_link: return span if label_type == "tag_group": type_filter_vars: HTTPVariables = [ ("%s_tag_0_grp" % object_type, tag_group_id_or_label_key), ("%s_tag_0_op" % object_type, "is"), ("%s_tag_0_val" % object_type, tag_id_or_label_value), ] elif label_type == "label": type_filter_vars = [ ( "%s_label" % object_type, json.dumps( [{"value": "%s:%s" % (tag_group_id_or_label_key, tag_id_or_label_value)}] ), ), ] else: raise NotImplementedError() url_vars: HTTPVariables = [ ("filled_in", "filter"), ("search", "Search"), ("view_name", "searchhost" if object_type == "host" else "searchsvc"), ] url = makeuri_contextless(request, url_vars + type_filter_vars, filename="view.py") return HTMLWriter.render_a(span, href=url)
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_=["tacticaloverview"], cellspacing="2", cellpadding="0", border="0") show_stales = self.parameters()["show_stale"] and 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 active_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"), class_="show_more_mode") html.th( HTMLWriter.render_span(_("Unhandled"), class_="more") + HTMLWriter.render_span(_("Unhandled p."), class_="less") ) 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 = makeuri_contextless(request, 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 = makeuri_contextless( request, getattr(row.views, ty) + context_vars, filename="view.py", ) html.open_td( class_=[td_class] + ([] if value == 0 else ["states prob"]) + ["show_more_mode" if ty == "handled" else "basic"] ) link(str(value), url) html.close_td() if show_stales and has_stale_objects: if row.views.stale: url = makeuri_contextless( request, row.views.stale + context_vars, filename="view.py", ) html.open_td(class_=[td_class] + ([] if stales == 0 else ["states prob"])) link(str(stales), url) html.close_td() else: html.td(HTMLWriter.render_span("0")) html.close_tr() html.close_table()
def _render_headers(self, actions_enabled: bool, actions_visible: bool, empty_columns: List[bool]) -> None: if self.options["omit_headers"]: return table_id = self.id html.open_tr() first_col = True for nr, header in enumerate(self.headers): if self.options["omit_empty_columns"] and empty_columns[nr]: continue if header.help_txt: header_title: HTML = HTMLWriter.render_span( header.title, title=header.help_txt) else: header_title = header.title if not isinstance(header.css, list): css_class: "CSSSpec" = [header.css] else: css_class = header.css assert isinstance(css_class, list) css_class = [("header_%s" % c) for c in css_class if c is not None] if not self.options["sortable"] or not header.sortable: html.open_th(class_=css_class) else: css_class.insert(0, "sort") reverse = 0 sort = request.get_ascii_input("_%s_sort" % table_id) if sort: sort_col, sort_reverse = map(int, sort.split(",", 1)) if sort_col == nr: reverse = 1 if sort_reverse == 0 else 0 action_uri = makeactionuri(request, transactions, [("_%s_sort" % table_id, "%d,%d" % (nr, reverse))]) html.open_th( class_=css_class, title=_("Sort by %s") % header.title, onclick="location.href='%s'" % action_uri, ) # Add the table action link if first_col: first_col = False if actions_enabled: if not header_title: header_title = HTML( " " ) # Fixes layout problem with white triangle if actions_visible: state = "0" help_txt = _("Hide table actions") img = "table_actions_on" else: state = "1" help_txt = _("Display table actions") img = "table_actions_off" html.open_div(class_=["toggle_actions"]) html.icon_button( makeuri(request, [("_%s_actions" % table_id, state)]), help_txt, img, cssclass="toggle_actions", ) html.span(header_title) html.close_div() else: html.write_text(header_title) else: html.write_text(header_title) html.close_th() html.close_tr()
def render_job_row(cls, job_id, job_status, odd, job_details_back_url=None): html.open_tr(css="data %s0" % odd) # Actions html.open_td(css="job_actions") if job_status.get("may_stop"): html.icon_button( makeactionuri(request, transactions, [(ActionHandler.stop_job_var, job_id)]), _("Stop this job"), "disable_test", ) if job_status.get("may_delete"): html.icon_button( makeactionuri(request, transactions, [(ActionHandler.delete_job_var, job_id)]), _("Delete this job"), "delete", ) html.close_td() # Job ID html.open_td(css="job_id") uri = makeuri_contextless( request, [ ("mode", "background_job_details"), ("back_url", job_details_back_url), ("job_id", job_id), ], filename="wato.py", ) html.a(job_id, href=uri) html.close_td() # Title html.td(job_status.get("title", _("Background Job")), css="job_title") # State html.td( HTMLWriter.render_span(job_status["state"]), css=cls.get_css_for_jobstate(job_status["state"]), ) # Started html.td(cmk.utils.render.date_and_time(job_status["started"]), css="job_started") # Owner html.td(job_status.get("user", _("Unknown user")), css="job_owner") # PID html.td(job_status["pid"] or "", css="job_pid") # Druation html.td(cmk.utils.render.timespan(job_status.get("duration", 0)), css="job_runtime") # Progress info loginfo = job_status.get("loginfo") if loginfo: if job_status.get( "state") == background_job.JobStatusStates.EXCEPTION: html.td(HTML("<br>".join(loginfo["JobException"])), css="job_last_progress") else: progress_text = "" if loginfo["JobProgressUpdate"]: progress_text += "%s" % loginfo["JobProgressUpdate"][-1] html.td(HTML(progress_text), css="job_last_progress") html.td(HTML("<br>".join(loginfo["JobResult"])), css="job_result") else: html.td("", css="job_last_progress") html.td("", css="job_result")
def _show_patterns(self): import cmk.gui.logwatch as logwatch collection = SingleRulesetRecursively("logwatch_rules") collection.load() ruleset = collection.get("logwatch_rules") html.h3(_("Logfile patterns")) if ruleset.is_empty(): html.open_div(class_="info") html.write_text( "There are no logfile patterns defined. You may create " 'logfile patterns using the <a href="%s">Rule Editor</a>.' % folder_preserving_link([ ("mode", "edit_ruleset"), ("varname", "logwatch_rules"), ])) html.close_div() # Loop all rules for this ruleset already_matched = False abs_rulenr = 0 for folder, rulenr, rule in ruleset.get_rules(): # Check if this rule applies to the given host/service if self._hostname: service_desc = self._get_service_description( self._hostname, "logwatch", self._item) # If hostname (and maybe filename) try match it rule_matches = rule.matches_host_and_item( Folder.current(), self._hostname, self._item, service_desc) else: # If no host/file given match all rules rule_matches = True with foldable_container( treename="rule", id_=str(abs_rulenr), isopen=True, title=HTML("<b>Rule #%d</b>" % (abs_rulenr + 1)), indent=False, ), table_element("pattern_editor_rule_%d" % abs_rulenr, sortable=False, css="logwatch") as table: abs_rulenr += 1 # TODO: What's this? pattern_list = rule.value if isinstance(pattern_list, dict): pattern_list = pattern_list["reclassify_patterns"] # Each rule can hold no, one or several patterns. Loop them all here for state, pattern, comment in pattern_list: match_class = "" disp_match_txt = HTML("") match_img = "" if rule_matches: # Applies to the given host/service matched = re.search(pattern, self._match_txt) if matched: # Prepare highlighted search txt match_start = matched.start() match_end = matched.end() disp_match_txt = ( escape_to_html(self._match_txt[:match_start]) + HTMLWriter.render_span( self._match_txt[match_start:match_end], class_="match") + escape_to_html(self._match_txt[match_end:])) if not already_matched: # First match match_class = "match first" match_img = "match" match_title = _( "This logfile pattern matches first and will be used for " "defining the state of the given line.") already_matched = True else: # subsequent match match_class = "match" match_img = "imatch" match_title = _( "This logfile pattern matches but another matched first." ) else: match_img = "nmatch" match_title = _( "This logfile pattern does not match the given string." ) else: # rule does not match match_img = "nmatch" match_title = _("The rule conditions do not match.") table.row() table.cell(_("Match")) html.icon("rule%s" % match_img, match_title) cls = ([ "state%d" % logwatch.level_state(state), "fillbackground" ] if match_class == "match first" else []) table.cell(_("State"), HTMLWriter.render_span( logwatch.level_name(state)), css=cls) table.cell(_("Pattern"), HTMLWriter.render_tt(pattern)) table.cell(_("Comment"), comment) table.cell(_("Matched line"), disp_match_txt) table.row(fixed=True) table.cell(colspan=5) edit_url = folder_preserving_link([ ("mode", "edit_rule"), ("varname", "logwatch_rules"), ("rulenr", rulenr), ("item", mk_repr(self._item).decode()), ("rule_folder", folder.path()), ("rule_id", rule.id), ]) html.icon_button(edit_url, _("Edit this rule"), "edit")