def render_topic(topic, entries): first = True for t, title, name, is_view in entries: if is_view and config.visible_views and name not in config.visible_views: continue if is_view and config.hidden_views and name in config.hidden_views: continue if t == topic: if first: html.begin_foldable_container("views", topic, False, topic, indent=True) first = False if is_view: bulletlink(title, "view.py?view_name=%s" % name, onclick="return cmk.sidebar.wato_views_clicked(this)") elif "?name=" in name: bulletlink(title, name) else: bulletlink(title, 'dashboard.py?name=%s' % name, onclick="return cmk.sidebar.wato_views_clicked(this)") # TODO: One day pagestypes should handle the complete snapin. # for page_type in pagetypes.all_page_types().values(): # if issubclass(page_type, pagetypes.PageRenderer): # for t, title, url in page_type.sidebar_links(): # if t == topic: # bulletlink(title, url) if not first: # at least one item rendered html.end_foldable_container()
def _show_topic(treename: str, topic: TopicMenuTopic, show_item_icons: bool) -> None: if not topic.items: return html.begin_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)") html.end_foldable_container()
def show(self): html.javascript(""" function add_bookmark() { url = parent.frames[1].location; title = parent.frames[1].document.title; cmk.ajax.get_url("add_bookmark.py?title=" + encodeURIComponent(title) + "&url=" + encodeURIComponent(url), cmk.utils.update_contents, "snapin_bookmarks"); }""") for topic, bookmarks in self._get_bookmarks_by_topic(): html.begin_foldable_container("bookmarks", topic, False, topic) for bookmark in bookmarks: icon = bookmark["icon"] if not icon: icon = "kdict" iconlink(bookmark["title"], bookmark["url"], icon) html.end_foldable_container() begin_footnote_links() link(_("Add Bookmark"), "javascript:void(0)", onclick="add_bookmark()") link(_("Edit"), "bookmark_lists.py") end_footnote_links()
def show(self): for topic, bookmarks in self._get_bookmarks_by_topic(): html.begin_foldable_container( treename="bookmarks", id_=topic, isopen=False, title=topic, indent=False, icon="foldable_sidebar", ) for bookmark in bookmarks: icon = bookmark["icon"] if not icon: icon = "bookmark_list" iconlink(bookmark["title"], bookmark["url"], icon) html.end_foldable_container() begin_footnote_links() link(_("Add Bookmark"), "javascript:void(0)", onclick="cmk.sidebar.add_bookmark()") link(_("Edit"), "bookmark_lists.py") end_footnote_links()
def show(self): # type: () -> None items = self._core_toggles() sites.update_site_states_from_dead_sites() site_status_info = {} # type: 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 config.sorted_sites(): if not config.is_single_local_site(): html.begin_foldable_container("master_control", site_id, True, site_alias) 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) finally: if not config.is_single_local_site(): html.end_foldable_container()
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: html.begin_foldable_container(tree_id, "/" + folder[".path"], False, HTML(title)) for subfolder in sorted(subfolders, key=lambda x: x["title"].lower()): render_tree_folder(tree_id, subfolder, js_func) html.end_foldable_container() else: html.li(title) html.close_ul()
def _render_topic(self, topic, entries): # type: (str, List[ViewMenuItem]) -> None container_id = ensure_str(re.sub('[^a-zA-Z]', '', topic)) html.begin_foldable_container(treename="views", id_=container_id, isopen=False, title=topic, indent=True) for item in entries: if item.is_view: bulletlink( item.title, item.url, onclick="return cmk.sidebar.wato_views_clicked(this)") elif "?name=" in item.name: bulletlink(item.title, item.url) else: bulletlink( item.title, item.url, onclick="return cmk.sidebar.wato_views_clicked(this)") # TODO: One day pagestypes should handle the complete snapin. # for page_type in pagetypes.all_page_types().values(): # if issubclass(page_type, pagetypes.PageRenderer): # for t, title, url in page_type.sidebar_links(): # if t == topic: # bulletlink(title, url) html.end_foldable_container()
def page(self): role_list = sorted(userdb.load_roles().items(), key=lambda a: (a[1]["alias"], a[0])) for section in permission_section_registry.get_sorted_sections(): html.begin_foldable_container( "perm_matrix", section.name, section.name == "general", section.title, indent=True) with table_element(section.name) as table: for perm in permission_registry.get_sorted_permissions(section): table.row() table.cell(_("Permission"), perm.title, css="wide") html.help(perm.description) for role_id, role in role_list: base_on_id = role.get('basedon', role_id) pvalue = role["permissions"].get(perm.name) if pvalue is None: if base_on_id in perm.defaults: icon_name = "perm_yes_default" else: icon_name = None else: icon_name = "perm_%s" % (pvalue and "yes" or "no") table.cell(role_id, css="center") if icon_name: html.icon(None, icon_name) html.end_foldable_container() html.close_table()
def _render_tree(self, tree): for group, attrs in tree.items(): fetch_url = makeuri_contextless( request, [ ("view_name", "aggr_all"), ("aggr_group_tree", "/".join(attrs["__path__"])), ], filename="view.py", ) if attrs.get('__children__'): html.begin_foldable_container( "bi_aggregation_group_trees", group, False, HTML(html.render_a( group, href=fetch_url, target="main", ))) self._render_tree(attrs['__children__']) html.end_foldable_container() else: html.open_ul() bulletlink(group, fetch_url) html.close_ul()
def _render_werk_table_options(): werk_table_options = {} # type: Dict[str, Any] for name, height, vs, default_value in _werk_table_option_entries(): value = default_value try: if html.request.has_var("wo_set"): value = vs.from_html_vars("wo_" + name) vs.validate_value(value, "wo_" + name) except MKUserError as e: html.user_error(e) werk_table_options.setdefault(name, value) html.begin_foldable_container("werks", "options", isopen=True, title=_("Searching and Filtering"), indent=False) html.begin_form("werks") html.hidden_field("wo_set", "set") html.begin_floating_options("werks", is_open=True) for name, height, vs, default_value in _werk_table_option_entries(): html.render_floating_option(name, height, "wo_", vs, werk_table_options[name]) html.end_floating_options(reset_url=html.makeuri([], remove_prefix="")) html.hidden_fields() html.end_form() html.end_foldable_container() from_date, until_date = Timerange().compute_range( werk_table_options["date"])[0] werk_table_options["date_range"] = from_date, until_date return werk_table_options
def end() -> None: global g_header_open g_header_open = False section_close() html.end_foldable_container() html.tr(html.render_td('', colspan=2), class_=["bottom"]) html.close_tbody() html.close_table()
def _end(self): if not self.rows and self.options["omit_if_empty"]: return if self.options["output_format"] == "csv": self._write_csv(csv_separator=html.request.var("csv_separator", ";")) return if self.title: if self.options["foldable"]: html.begin_foldable_container(treename="table", id_=self.id, isopen=True, indent=False, title=html.render_h3(self.title, class_=["treeangle", "title"])) else: html.open_h3() html.write(self.title) html.close_h3() 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_enabled, actions_visible, search_term, user_opts = self._evaluate_user_opts() # Apply limit after search / sorting etc. num_rows_unlimited = len(rows) limit = self.limit if limit is not None: # only use rows up to the limit plus the fixed rows rows = [rows[i] for i in range(num_rows_unlimited) if i < limit or rows[i][3]] # Display corrected number of rows num_rows_unlimited -= len([r for r in rows if r[3]]) # Render header show_action_row = self.options["searchable"] or (self.options["sortable"] and self._get_sort_column(user_opts[self.id])) self._write_table(rows, show_action_row, actions_visible, search_term) if self.title and self.options["foldable"]: html.end_foldable_container() if limit is not None and num_rows_unlimited > limit: html.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, html.makeuri([('limit', 'none')]))) if actions_enabled: config.user.save_file("tableoptions", user_opts) return
def _render_tag_tree_level(self, tree_spec, path, cwd, title, tree): if (not self._is_tag_subdir(path=path, cwd=cwd) and not self._is_tag_subdir(path=cwd, cwd=path)): return 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: html.begin_foldable_container( "tag-tree", ".".join(map(str, path)), False, HTML(bullet + title), icon="foldable_sidebar", ) 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( 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(node_title) html.br() else: self._render_tag_tree_level(tree_spec, subpath, cwd, node_title, subtree) if path and path != cwd and self._is_tag_subdir(path, cwd): html.end_foldable_container()
def end(): global g_header_open g_header_open = False if g_section_open: html.close_td() html.close_tr() html.end_foldable_container() html.tr(html.render_td('', colspan=2), class_=["bottom", "open" if g_section_isopen else "closed"]) html.close_table()
def _show_tree_nodes(self, maps, children): for map_name, map_cfg in maps.items(): html.open_li() if map_name in children: html.begin_foldable_container(treename="nagvis", id_=map_name, isopen=False, title=map_cfg["alias"], title_url=map_cfg["url"], title_target="main", indent=False) self._show_tree_nodes(children[map_name], children) html.end_foldable_container() 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) html.begin_foldable_container("customlinks", id_, isopen=entry[1], title=entry[0], icon="foldable_sidebar") render_list(idss, entry[2]) html.end_foldable_container() 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( html.render_icon(icon_name) + " " + 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 render_topic(topic, s, foldable=True): first = True for t, title, name, _is_view in s: if t == topic: if first: if foldable: html.begin_foldable_container("dashboards", topic, False, topic, indent=True) else: html.open_ul() first = False bulletlink(title, 'dashboard.py?name=%s' % name, onclick="return cmk.sidebar.wato_views_clicked(this)") if not first: # at least one item rendered if foldable: html.end_foldable_container() else: html.open_ul()
def show(self): filename = cmk.utils.paths.omd_root + '/var/dokuwiki/data/pages/sidebar.txt' html.javascript(""" function wiki_search() { var oInput = document.getElementById('wiki_search_field'); top.frames["main"].location.href = "/%s/wiki/doku.php?do=search&id=" + escape(oInput.value); } """ % config.omd_site()) html.open_form(id_="wiki_search", onsubmit="wiki_search();") html.input(id_="wiki_search_field", type_="text", name="wikisearch") html.icon_button("#", _("Search"), "wikisearch", onclick="wiki_search();") html.close_form() html.div('', id_="wiki_side_clear") start_ul = True ul_started = False try: title = None for line in file(filename).readlines(): line = line.strip() if line == "": if ul_started: html.end_foldable_container() start_ul = True ul_started = False elif line.endswith(":"): title = line[:-1] elif line == "----": pass # html.br() elif line.startswith("*"): if start_ul: if title: html.begin_foldable_container("wikisnapin", title, True, title, indent=True) else: html.open_ul() start_ul = False ul_started = True erg = re.findall(r'\[\[(.*)\]\]', line) if len(erg) == 0: continue erg = erg[0].split('|') if len(erg) > 1: link = erg[0] name = erg[1] else: link = erg[0] name = erg[0] if link.startswith("http://") or link.startswith( "https://"): simplelink(name, link, "_blank") else: erg = name.split(':') if len(erg) > 0: name = erg[-1] else: name = erg[0] bulletlink( name, "/%s/wiki/doku.php?id=%s" % (config.omd_site(), link)) else: html.write_text(line) if ul_started: html.close_ul() except IOError: sidebar = html.render_a("sidebar", href="/%s/wiki/doku.php?id=%s" % (config.omd_site(), _("sidebar")), target="main") html.write_html("<p>To get a navigation menu, you have to create a %s in your wiki first.</p>"\ % sidebar)
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 html.begin_foldable_container("rule", "%s" % abs_rulenr, True, HTML("<b>Rule #%d</b>" % (abs_rulenr + 1)), indent=False) with table_element("pattern_editor_rule_%d" % abs_rulenr, sortable=False) 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 reason_class = 'reason' matched = re.search(pattern, self._match_txt) if matched: # Prepare highlighted search txt match_start = matched.start() match_end = matched.end() disp_match_txt = html.render_text(self._match_txt[:match_start]) \ + html.render_span(self._match_txt[match_start:match_end], class_="match")\ + html.render_text(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 reason_class = 'noreason' match_img = 'nmatch' match_title = _('The rule conditions do not match.') table.row(css=reason_class) table.cell(_('Match')) html.icon(match_title, "rule%s" % match_img) cls = '' if match_class == 'match first': cls = 'svcstate state%d' % logwatch.level_state(state) table.cell(_('State'), logwatch.level_name(state), css=cls) table.cell(_('Pattern'), html.render_tt(pattern)) table.cell(_('Comment'), html.render_text(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), ("host", self._hostname), ("item", ensure_str(watolib.mk_repr(self._item))), ("rule_folder", folder.path()), ]) html.icon_button(edit_url, _("Edit this rule"), "edit") html.end_foldable_container()
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=html.request.get_str_input_mandatory( "csv_separator", ";")) return if self.title: if self.options["foldable"]: html.begin_foldable_container( treename="table", id_=self.id, isopen=True, indent=False, title=html.render_h3(self.title, class_=["treeangle", "title"])) else: html.open_h3() html.write(self.title) html.close_h3() 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 is not None: # 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 self._write_table(rows, num_rows_unlimited, self._show_action_row(), actions_visible, search_term) if self.title and self.options["foldable"]: html.end_foldable_container() if limit is not None 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, html.makeuri([('limit', 'none')]))) return
def show(self): items = [ ("enable_notifications", _("Notifications")), ("execute_service_checks", _("Service checks")), ("execute_host_checks", _("Host checks")), ("enable_flap_detection", _("Flap Detection")), ("enable_event_handlers", _("Event handlers")), ("process_performance_data", _("Performance data")), ("enable_event_handlers", _("Alert handlers")), ] sites.update_site_states_from_dead_sites() site_status_info = {} 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) def _render_master_control_site(site_id): site_state = sites.states().get(site_id) if site_state["state"] == "dead": html.show_error(site_state["exception"]) elif site_state["state"] == "disabled": html.show_message(_("Site is disabled")) elif site_state["state"] == "unknown": if site_state.get("exception"): html.show_error(site_state["exception"]) else: html.show_error(_("Site state is unknown")) else: is_cmc = site_state["program_version"].startswith("Check_MK ") try: site_info = site_status_info[site_id] except KeyError: site_info = None html.open_table(class_="master_control") for i, (colname, title) in enumerate(items): # Do not show event handlers on Check_MK Micro Core if is_cmc and title == _("Event handlers"): continue elif not is_cmc and title == _("Alert handlers"): continue colvalue = site_info[i] url = html.makeactionuri_contextless( [ ("site", site_id), ("switch", colname), ("state", "%d" % (1 - colvalue)), ], filename="switch_master_state.py") onclick = "cmk.ajax.get_url('%s', cmk.utils.update_contents, 'snapin_master_control')" % url html.open_tr() html.td(title, class_="left") html.open_td() html.toggle_switch( enabled=colvalue, help_txt=_("Switch '%s' to '%s'") % (title, _("off") if colvalue else _("on")), onclick=onclick, ) html.close_td() html.close_tr() html.close_table() for site_id, site_alias in config.sorted_sites(): if not config.is_single_local_site(): html.begin_foldable_container("master_control", site_id, True, site_alias) try: _render_master_control_site(site_id) except Exception as e: logger.exception("error rendering master control for site %s", site_id) write_snapin_exception(e) finally: if not config.is_single_local_site(): html.end_foldable_container()
def show(self): # type: () -> None filename = Path(cmk.utils.paths.omd_root).joinpath( 'var/dokuwiki/data/pages/sidebar.txt') html.open_form(id_="wiki_search", onsubmit="cmk.sidebar.wiki_search('%s');" % config.omd_site()) html.input(id_="wiki_search_field", type_="text", name="wikisearch") html.icon_button("#", _("Search"), "wikisearch", onclick="cmk.sidebar.wiki_search('%s');" % config.omd_site()) html.close_form() html.div('', id_="wiki_side_clear") start_ul = True ul_started = False try: title = None for line in filename.open(encoding="utf-8").readlines(): line = line.strip() if line == "": if ul_started: html.end_foldable_container() start_ul = True ul_started = False elif line.endswith(":"): title = line[:-1] elif line == "----": pass # html.br() elif line.startswith("*"): if start_ul: if title: html.begin_foldable_container("wikisnapin", title, True, title, indent=True) else: html.open_ul() start_ul = False ul_started = True erg = re.findall(r'\[\[(.*)\]\]', line) if len(erg) == 0: continue erg = erg[0].split('|') if len(erg) > 1: link = erg[0] name = erg[1] else: link = erg[0] name = erg[0] if link.startswith("http://") or link.startswith( "https://"): simplelink(name, link, "_blank") else: erg = name.split(':') if len(erg) > 0: name = erg[-1] else: name = erg[0] bulletlink( name, "/%s/wiki/doku.php?id=%s" % (config.omd_site(), link)) else: html.write_text(line) if ul_started: html.close_ul() except IOError: html.write_html( html.render_p( html.render_text( "To get a navigation menu, you have to create a ") + html.render_a("sidebar", href="/%s/wiki/doku.php?id=%s" % (config.omd_site(), _("sidebar")), target="main") + # html.render_text(" in your wiki first.")))