def show(self) -> None: items = self._core_toggles() sites.update_site_states_from_dead_sites() site_status_info: Dict[sites.SiteId, List] = {} try: sites.live().set_prepend_site(True) for row in sites.live().query( "GET status\nColumns: %s" % " ".join([i[0] for i in items]) ): site_id, values = row[0], row[1:] site_status_info[site_id] = values finally: sites.live().set_prepend_site(False) for site_id, site_alias in sites.sorted_sites(): container: ContextManager[bool] = ( foldable_container( treename="master_control", id_=site_id, isopen=True, title=site_alias, icon="foldable_sidebar", ) if not sites.is_single_local_site() else nullcontext(False) ) with container: try: self._show_master_control_site(site_id, site_status_info, items) except Exception as e: logger.exception("error rendering master control for site %s", site_id) write_snapin_exception(e)
def render_tree_folder(tree_id, folder, js_func): subfolders = folder.get(".folders", {}).values() is_leaf = len(subfolders) == 0 # Suppress indentation for non-emtpy root folder if folder[".path"] == "" and is_leaf: html.open_ul() # empty root folder elif folder and folder[".path"] != "": html.open_ul(style="padding-left:0px;") title = html.render_a( "%s (%d)" % (folder["title"], folder[".num_hosts"]), href="#", class_="link", onclick="%s(this, '%s');" % (js_func, folder[".path"]), ) if not is_leaf: with foldable_container( treename=tree_id, id_="/" + folder[".path"], isopen=False, title=HTML(title), icon="foldable_sidebar", padding=6, ): for subfolder in sorted(subfolders, key=lambda x: x["title"].lower()): render_tree_folder(tree_id, subfolder, js_func) else: html.li(title) html.close_ul()
def _show_topic(treename: str, topic: TopicMenuTopic, show_item_icons: bool) -> None: if not topic.items: return with foldable_container( treename=treename, id_=topic.name, isopen=False, title=topic.title, indent=True, icon="foldable_sidebar", ): for item in topic.items: if show_item_icons: html.open_li(class_=[ "sidebar", "show_more_mode" if item.is_show_more else None ]) iconlink(item.title, item.url, item.icon or "icon_missing") html.close_li() else: bulletlink( item.title, item.url, onclick="return cmk.sidebar.wato_views_clicked(this)")
def _render_tag_tree_level(self, tree_spec, path, cwd, title, tree) -> None: if not self._is_tag_subdir( path=path, cwd=cwd) and not self._is_tag_subdir(path=cwd, cwd=path): return container: ContextManager[bool] = nullcontext(False) if path != cwd and self._is_tag_subdir(path, cwd): bullet = self._tag_tree_bullet(self._tag_tree_worst_state(tree), path, False) if self._tag_tree_has_svc_problems(tree): bullet += html.render_icon_button( self._tag_tree_url(tree_spec, path, "svcproblems"), _("Show the service problems contained in this branch"), "svc_problems", target="main", ) if path: container = foldable_container( treename="tag-tree", id_=".".join(map(str, path)), isopen=False, title=bullet + title, icon="foldable_sidebar", ) with container: for (node_title, node_value), subtree in sorted( tree.get("_children", {}).items()): subpath = path + [node_value or ""] url = self._tag_tree_url(tree_spec, subpath, "allhosts") if "_num_hosts" in subtree: node_title += " (%d)" % subtree["_num_hosts"] node_title = html.render_a(node_title, href=url, target="main") if "_children" not in subtree: if self._is_tag_subdir(path, cwd): html.write_html( self._tag_tree_bullet(subtree.get("_state", 0), subpath, True)) if subtree.get("_svc_problems"): url = self._tag_tree_url(tree_spec, subpath, "svcproblems") html.icon_button( url, _("Show the service problems contained in this branch" ), "svc_problems", target="main", ) html.write_html(node_title) html.br() else: self._render_tag_tree_level(tree_spec, subpath, cwd, node_title, subtree)
def _show_tree_nodes(self, maps, children): for map_name, map_cfg in maps.items(): html.open_li() if map_name in children: with foldable_container(treename="nagvis", id_=map_name, isopen=False, title=map_cfg["alias"], title_url=map_cfg["url"], title_target="main", indent=False, icon="foldable_sidebar"): self._show_tree_nodes(children[map_name], children) else: html.a(map_cfg["alias"], href=map_cfg["url"], target="main", class_="link") html.close_li()
def render_list(ids, links): n = 0 for entry in links: n += 1 try: if isinstance(entry[1], type(True)): idss = ids + [str(n)] id_ = '/'.join(idss) with foldable_container(treename="customlinks", id_=id_, isopen=entry[1], title=entry[0], icon="foldable_sidebar"): render_list(idss, entry[2]) elif isinstance(entry[1], str): frame = entry[3] if len(entry) > 3 else "main" if len(entry) > 2 and entry[2]: icon_file = entry[2] # Old configs used files named "link_<name>.gif". Those .gif files have # been removed from Checkmk. Replacing such images with the default icon if icon_file.endswith(".gif"): icon_name = "link" else: icon_name = icon_file.rsplit(".", 1)[0].replace( "icon_", "") else: icon_name = "link" linktext = html.render_icon(icon_name) + HTML( " ") + escape_html(entry[0]) simplelink(linktext, entry[1], frame) else: html.write_text( _("Second part of tuple must be list or string, not %s\n" ) % str(entry[1])) except Exception as e: html.write_text( _("invalid entry %s: %s<br>\n") % (entry, e))
def _end(self) -> None: if not self.rows and self.options["omit_if_empty"]: return if self.options["output_format"] == "csv": self._write_csv(csv_separator=request.get_str_input_mandatory( "csv_separator", ";")) return container: ContextManager[bool] = nullcontext(False) if self.title: if self.options["foldable"] in [ Foldable.FOLDABLE_SAVE_STATE, Foldable.FOLDABLE_STATELESS, ]: html.open_div(class_="foldable_wrapper") container = foldable_container( treename="table", id_=self.id, isopen=True, indent=False, title=html.render_h3(self.title, class_=["treeangle", "title"]), save_state=self.options["foldable"] == Foldable.FOLDABLE_SAVE_STATE, ) else: html.h3(self.title, class_="table") with container: if self.help: html.help(self.help) if not self.rows: html.div(self.empty_text, class_="info") return # Controls whether or not actions are available for a table rows, actions_visible, search_term = self._evaluate_user_opts() # Apply limit after search / sorting etc. num_rows_unlimited = len(rows) limit = self.limit if limit: # only use rows up to the limit plus the fixed rows limited_rows = [] for index in range(num_rows_unlimited): row = rows[index] if index < limit or isinstance(row, GroupHeader) or row.fixed: limited_rows.append(row) # Display corrected number of rows num_rows_unlimited -= len([ r for r in limited_rows if isinstance(row, GroupHeader) or r.fixed ]) rows = limited_rows # Render header if self.limit_hint is not None: num_rows_unlimited = self.limit_hint if limit and num_rows_unlimited > limit: html.show_message( _("This table is limited to show only %d of %d rows. " 'Click <a href="%s">here</a> to disable the limitation.') % (limit, num_rows_unlimited, makeuri(request, [("limit", "none")]))) self._write_table(rows, num_rows_unlimited, self._show_action_row(), actions_visible, search_term) if self.title and self.options["foldable"] in [ Foldable.FOLDABLE_SAVE_STATE, Foldable.FOLDABLE_STATELESS, ]: html.close_div() return
def _show_patterns(self): import cmk.gui.logwatch as logwatch collection = watolib.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>.' % watolib.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(watolib.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_html_permissive(self._match_txt[:match_start]) \ + html.render_span(self._match_txt[match_start:match_end], class_="match")\ + escape_html_permissive(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: List[str] = [] if match_class == 'match first': cls = ['state%d' % logwatch.level_state(state), 'fillbackground'] table.cell(_('State'), html.render_span(logwatch.level_name(state)), css=cls) table.cell(_('Pattern'), html.render_tt(pattern)) table.cell(_('Comment'), comment) table.cell(_('Matched line'), disp_match_txt) table.row(fixed=True) table.cell(colspan=5) edit_url = watolib.folder_preserving_link([ ("mode", "edit_rule"), ("varname", "logwatch_rules"), ("rulenr", rulenr), ("item", watolib.mk_repr(self._item).decode()), ("rule_folder", folder.path()), ("rule_id", rule.id), ]) html.icon_button(edit_url, _("Edit this rule"), "edit")