def user_profile_async_replication_dialog(sites: List[SiteId]) -> None: html.p( _('In order to activate your changes available on all remote sites, your user profile needs ' 'to be replicated to the remote sites. This is done on this page now. Each site ' 'is being represented by a single image which is first shown gray and then fills ' 'to green during synchronisation.')) html.h3(_('Replication States')) html.open_div(id_="profile_repl") num_replsites = 0 for site_id in sites: site = config.sites[site_id] if "secret" not in site: status_txt = _('Not logged in.') start_sync = False icon = 'repl_locked' else: status_txt = _('Waiting for replication to start') start_sync = True icon = 'repl_pending' html.open_div(class_="site", id_="site-%s" % site_id) html.div("", title=status_txt, class_=["icon", "repl_status", icon]) if start_sync: changes_manager = watolib.ActivateChanges() changes_manager.load() estimated_duration = changes_manager.get_activation_time( site_id, ACTIVATION_TIME_PROFILE_SYNC, 2.0) html.javascript( 'cmk.profile_replication.start(\'%s\', %d, \'%s\');' % (site_id, int(estimated_duration * 1000.0), _('Replication in progress'))) num_replsites += 1 else: _add_profile_replication_change(site_id, status_txt) html.span(site.get('alias', site_id)) html.close_div() html.javascript('cmk.profile_replication.prepare(%d);\n' % num_replsites) html.close_div()
def _download_table(self, title: str, paths: List[str]) -> None: forms.header(title) forms.container() for path in paths: os_path = path relpath = path.replace(cmk.utils.paths.agents_dir + '/', '') filename = path.split('/')[-1] file_size = os.stat(os_path).st_size # FIXME: Rename classes etc. to something generic html.open_div(class_="ruleset") html.open_div(style="width:300px;", class_="text") html.a(filename, href="agents/%s" % relpath, download=filename) html.span("." * 200, class_="dots") html.close_div() html.div(cmk.utils.render.fmt_bytes(file_size), style="width:60px;", class_="rulecount") html.close_div() html.close_div() forms.end()
def _show_sidebar_head(self): html.open_div(id_="side_header") html.open_a( href=user.start_url or config.start_url, target="main", title=_("Go to main page"), ) _render_header_icon() html.close_a() html.close_div() MainMenuRenderer().show() html.open_div(id_="side_fold", title=_("Toggle the sidebar"), onclick="cmk.sidebar.toggle_sidebar()") html.icon("sidebar_folded", class_="folded") html.icon("sidebar") if not user.get_attribute("nav_hide_icons_title"): html.div(_("Sidebar")) html.close_div()
def show_search_field(self) -> None: html.open_div( id_="mk_side_search_setup", class_="content_center", ) # TODO: Implement submit action (e.g. show all results of current query) html.begin_form(f"mk_side_{self.name}", add_transid=False, onsubmit="return false;") html.input(id_=f"mk_side_search_field_{self.name}", type_="text", name="search", autocomplete="off", placeholder=_("Search in Setup"), onkeydown="cmk.search.on_key_down('setup')", oninput="cmk.search.on_input_search('setup');") html.input(id_=f"mk_side_search_field_clear_{self.name}", name="reset", type_="button", onclick="cmk.search.on_click_reset('setup');") html.end_form() html.close_div() html.div('', id_="mk_side_clear")
def render(self, query: str) -> str: results = self._generate_results(query) with html.plugged(): for topic, search_results in results.items(): html.open_div(id_=topic, class_="topic") self._render_topic(topic) html.open_ul() for result in list( search_results)[:self._max_num_displayed_results]: self._render_result(result) # TODO: Remove this as soon as the index search does limit its search results if len(list( search_results)) >= self._max_num_displayed_results: html.div(content=_( f"Showing only first {self._max_num_displayed_results} results." )) html.close_ul() html.close_div() html.div(None, class_=["topic", "sentinel"]) html_text = html.drain() return html_text
def show(self, menu: MegaMenu) -> None: more_id = "main_menu_" + menu.name show_more = get_show_more_setting(more_id) html.open_div(id_=more_id, class_=["main_menu", "more" if show_more else "less"]) hide_entries_js = "cmk.popup_menu.mega_menu_hide_entries('%s')" % more_id topics = menu.topics() if any_advanced_items(topics): html.more_button(id_=more_id, dom_levels_up=1, additional_js=hide_entries_js) html.open_div(class_="content inner") for topic in topics: self._show_topic(topic, menu.name) html.div(None, class_="sentinel") html.close_div() html.close_div() html.javascript(hide_entries_js) html.javascript("cmk.popup_menu.initialize_mega_menus();")
def _show_table(self, request): html.open_table(class_="allhosts") html.open_tbody() for map_cfg in request["maps"]: html.open_tr() html.open_td() html.div("", class_=[ "statebullet", self._state_class(map_cfg), self._sub_state_class(map_cfg), self._stale_class(map_cfg) ], title=self._state_title(map_cfg)) html.a(map_cfg["alias"], href=map_cfg["url"], class_="link", target="main") html.close_td() html.close_tr() html.close_tbody() html.close_table()
def _show_sidebar_head(self): html.open_div(id_="side_header") html.open_a(href=config.user.get_attribute("start_url") or config.start_url, target="main", title=_("Go to main overview")) html.div("", id_="side_bg") html.close_a() html.close_div() MainMenuRenderer().show() html.open_div(id_="side_fold", title=_("Toggle the sidebar"), onclick="cmk.sidebar.toggle_sidebar()") html.icon("sidebar_folded", class_="folded") html.icon("sidebar") html.div(_("Sidebar")) html.close_div() if config.sidebar_show_version_in_sidebar: html.open_div(id_="side_version") html.open_a(href="version.py", target="main", title=_("Open release notes")) html.write(self._get_check_mk_edition_title()) html.br() html.write(cmk_version.__version__) if werks.may_acknowledge(): num_unacknowledged_werks = werks.num_unacknowledged_incompatible_werks( ) if num_unacknowledged_werks: html.span(num_unacknowledged_werks, class_="unack_werks", title=_("%d unacknowledged incompatible werks") % num_unacknowledged_werks) html.close_a() html.close_div()
def show(self, menu: MegaMenu) -> None: more_id = "main_menu_" + menu.name show_more = config.user.get_show_more_setting(more_id) html.open_div(id_=more_id, class_=["main_menu", "more" if show_more else "less"]) hide_entries_js = "cmk.popup_menu.mega_menu_hide_entries('%s')" % more_id html.open_div(class_="navigation_bar") html.open_div(class_="search_bar") if menu.search: menu.search.show_search_field() html.close_div() if menu.info_line: html.span(menu.info_line(), id_="info_line_%s" % menu.name, class_="info_line") topics = menu.topics() if any_show_more_items(topics): html.open_div() html.more_button(id_=more_id, dom_levels_up=3, additional_js=hide_entries_js, with_text=True) html.close_div() html.close_div() html.open_div(class_="content inner", id="content_inner_%s" % menu.name) for topic in topics: if not topic.items: continue self._show_topic(topic, menu.name) html.div(None, class_=["topic", "sentinel"]) html.close_div() html.close_div() html.javascript(hide_entries_js) html.javascript("cmk.popup_menu.initialize_mega_menus();") html.open_div(class_="content inner", id="content_inner_%s_search" % menu.name) html.close_div()
def page_login() -> None: title = _("Checkmk Mobile") mobile_html_head(title) jqm_page_header(title, id_="login") html.div(_("Welcome to Checkmk Mobile."), id_="loginhead") html.begin_form("login", method="POST", add_transid=False) # Keep information about original target URL default_origtarget = ("index.py" if requested_file_name(request) in ["login", "logout"] else makeuri(request, [])) origtarget = request.get_url_input("_origtarget", default_origtarget) html.hidden_field("_origtarget", escaping.escape_attribute(origtarget)) html.text_input("_username", label=_("Username:"******"username", id_="input_user") html.password_input( "_password", size=None, label=_("Password:"******"current-password", id_="input_pass", ) html.br() html.button("_login", _("Login")) html.set_focus("_username") html.end_form() html.open_div(id_="loginfoot") html.img("themes/facelift/images/logo_cmk_small.png", class_="logomk") html.div( HTML( _('© <a target="_blank" href="https://checkmk.com">tribe29 GmbH</a>' )), class_="copyright", ) html.close_div() # close content-div html.close_div() html.close_div() # close page-div mobile_html_foot()
def _major_page(self) -> None: html.header( self._title(), breadcrumb=_release_notes_breadcrumb(), page_state=_release_switch(major=True), ) html.open_div(id_="release_title") html.h1(escape_html(_("Everything")) + html.render_br() + escape_html(_("monitored"))) html.img(theme.url("images/tribe29.svg")) html.close_div() html.div(None, id_="release_underline") html.open_div(id_="release_content") for icon, headline, subline in [ ("release_deploy", _("Deploy in minutes"), _("From 0 to Monitoring in <10min")), ("release_scale", _("With unlimited scale"), _("Hundred thousands of hosts")), ("release_automated", _("Highly automated"), _("Let Checkmk do the work for you")), ]: html.open_div(class_="container") html.img(theme.url(f"images/{icon}.svg")) html.div(headline) html.div(subline) html.close_div() html.close_div() html.open_div(id_="release_footer") html.span(_("© 2020 tribe29 GmbH. All Rights Reserved.")) html.a(_("License aggreement"), href="https://checkmk.com/legal.html", target="_blank") html.a(_("Imprint"), href="https://checkmk.com/impressum.html", target="_blank") html.close_div()
def select_language(user): languages = [ l for l in cmk.gui.i18n.get_languages() if not config.hide_language(l[0]) ] if languages: active = 'language' in user forms.section(_("Language"), checkbox=('_set_lang', active, 'language')) default_label = _('Default: %s') % cmk.gui.i18n.get_language_alias( config.default_language) html.div(default_label, class_="inherited", id_="attr_default_language", style="display: none" if active else "") html.open_div(id_="attr_entry_language", style="display: none" if not active else "") language = user.get('language') if user.get( 'language') is not None else '' # Transform 'en' configured language to empty string for compatibility reasons if language == "en": language = "" html.dropdown("language", languages, deflt=language) html.close_div() html.help( _('Configure the default language ' 'to be used by the user in the user interface here. If you do not check ' 'the checkbox, then the system default will be used.<br><br>' 'Note: currently Multisite is internationalized ' 'but comes without any actual localisations (translations). If you want to ' 'create you own translation, you find <a href="%(url)s">documentation online</a>.' ) % { "url": "https://mathias-kettner.com/checkmk_multisite_cmk.gui.i18n.html" })
def _show_form(self) -> None: assert user.id is not None credentials = load_two_factor_credentials(user.id) webauthn_credentials = credentials["webauthn_credentials"] backup_codes = credentials["backup_codes"] html.begin_form("two_factor", method="POST") html.div("", id_="webauthn_message") forms.header(_("Credentials")) forms.section(_("Registered credentials"), simple=True) if webauthn_credentials: self._show_credentials(webauthn_credentials) else: html.i(_("No credentials registered")) forms.section(_("Backup codes"), simple=True) if backup_codes: html.p( _( "You have %d unused backup codes left. You can use them as one-time password " "if your key is not available." ) % len(backup_codes) ) html.i( _( "If you regenerate backup codes, you automatically invalidate the existing codes." ) ) else: html.i(_("No backup codes created yet.")) forms.end() html.hidden_fields() html.end_form() html.footer()
def page(self): if not self._attrs: html.div(_("No custom attributes are defined yet."), class_="info") return with table_element(self._type + "attrs") as table: for custom_attr in sorted(self._attrs, key=lambda x: x['title']): table.row() table.cell(_("Actions"), css="buttons") edit_url = watolib.folder_preserving_link([ ("mode", "edit_%s_attr" % self._type), ("edit", custom_attr['name']) ]) delete_url = html.makeactionuri([("_delete", custom_attr['name'])]) html.icon_button(edit_url, _("Properties"), "edit") html.icon_button(delete_url, _("Delete"), "delete") table.text_cell(_("Name"), custom_attr['name']) table.text_cell(_("Title"), custom_attr['title']) table.cell(_("Type"), dict(custom_attr_types())[custom_attr['type']])
def show_job_class_infos(cls, job_class_infos, **kwargs): """Renders all jobs from the job_class_infos in a single multi-table""" html.open_table(css="job_table data") for job_class, jobs_info in sorted(job_class_infos.items(), key=lambda x: x[0].gui_title()): html.open_tr() html.open_td(colspan=len(cls.get_headers())) html.h3(job_class.gui_title()) html.close_td() html.close_tr() if not jobs_info: html.open_tr() html.open_td(colspan=len(cls.get_headers())) html.div(_("No entries"), css="info") html.close_td() html.close_tr() continue cls.show_job_row_headers() odd = "even" for job_id, job_status in sorted(jobs_info.items(), reverse=True): cls.render_job_row(job_id, job_status, odd, **kwargs) odd = "even" if odd == "odd" else "odd"
def _show_sidebar(self) -> None: if not config.user.may("general.see_sidebar"): html.div("", id_="check_mk_navigation") return user_config = UserSidebarConfig(config.user, config.sidebar) html.open_div(id_="check_mk_navigation") self._show_sidebar_head() html.close_div() assert config.user.id is not None sidebar_position = cmk.gui.userdb.load_custom_attr( config.user.id, 'ui_sidebar_position', lambda x: None if x == "None" else "left") html.open_div(id_="check_mk_sidebar", class_=[sidebar_position]) self._show_shortcut_bar() self._show_snapin_bar(user_config) html.close_div() if user_config.folded: html.final_javascript("cmk.sidebar.fold_sidebar();")
def _show_sidebar_head(self): html.open_div(id_="side_header") html.open_a( href=config.user.get_attribute("start_url") or config.start_url, target="main", title=_("Go to main overview"), class_="min" if config.user.get_attribute("nav_hide_icons_title") else None, ) html.div("", id_="side_bg") html.close_a() html.close_div() MainMenuRenderer().show() html.open_div(id_="side_fold", title=_("Toggle the sidebar"), onclick="cmk.sidebar.toggle_sidebar()") html.icon("sidebar_folded", class_="folded") html.icon("sidebar") if not config.user.get_attribute("nav_hide_icons_title"): html.div(_("Sidebar")) html.close_div()
def show_topology_content(self, hostnames: List[HostName], mode: str, growth_auto_max_nodes: Optional[int] = None, max_nodes: int = 400, mesh_depth: int = 0) -> None: div_id = "node_visualization" html.div("", id=div_id) # Filters html.open_div(id="topology_filters") view, filters = self._get_topology_view_and_filters() html.request.set_var("topology_mesh_depth", str(mesh_depth)) html.request.set_var("topology_max_nodes", str(max_nodes)) cmk.gui.views.show_filter_form(view, filters) html.final_javascript("cmk.page_menu.open_popup('popup_filters');") html.close_div() html.javascript( "topology_instance = new cmk.node_visualization.TopologyVisualization(%s, %s);" % (json.dumps(div_id), json.dumps(mode))) if growth_auto_max_nodes: html.javascript("topology_instance.set_growth_auto_max_nodes(%d)" % growth_auto_max_nodes) html.javascript("topology_instance.set_max_nodes(%d)" % max_nodes) html.javascript("topology_instance.set_mesh_depth(%d)" % mesh_depth) html.javascript("topology_instance.set_theme(%s)" % json.dumps(html.get_theme())) overlay_config = self._get_overlay_config() if overlay_config: html.javascript( "topology_instance.set_initial_overlays_config(%s)" % json.dumps(overlay_config)) html.javascript("topology_instance.show_topology(%s)" % json.dumps(hostnames))
def show_topology_content(self, hostnames, mode, growth_auto_max_nodes=None, max_nodes=400, mesh_depth=0): # type: (List[HostName], str, Optional[int], int, int) -> None div_id = "node_visualization" html.div("", id=div_id) # Filters html.open_div(id="topology_filters") _view, filters = self._get_topology_view_and_filters() html.request.set_var("topology_mesh_depth", str(mesh_depth)) html.request.set_var("topology_max_nodes", str(max_nodes)) cmk.gui.views.show_filter_form(is_open=True, filters=filters) html.close_div() html.javascript( "topology_instance = new cmk.node_visualization.TopologyVisualization(%s, %s);" % (json.dumps(div_id), json.dumps(mode))) if growth_auto_max_nodes: html.javascript("topology_instance.set_growth_auto_max_nodes(%d)" % growth_auto_max_nodes) html.javascript("topology_instance.set_max_nodes(%d)" % max_nodes) html.javascript("topology_instance.set_mesh_depth(%d)" % mesh_depth) html.javascript("topology_instance.set_theme(%s)" % json.dumps(html.get_theme())) overlay_config = self._get_overlay_config() if overlay_config: html.javascript( "topology_instance.set_initial_overlays_config(%s)" % json.dumps(overlay_config)) html.javascript("topology_instance.show_topology(%s)" % json.dumps(hostnames))
def js_dashlet(self, fetch_url: str): div_id = "%s_dashlet_%d" % (self.type_name(), self._dashlet_id) html.div("", id_=div_id) args = dashlet_http_variables(self) body = html.urlencode_vars(args) html.javascript( """ let %(type_name)s_class_%(dashlet_id)d = cmk.figures.figure_registry.get_figure("%(type_name)s"); let %(instance_name)s = new %(type_name)s_class_%(dashlet_id)d(%(div_selector)s); %(instance_name)s.set_post_url_and_body(%(url)s, %(body)s); %(instance_name)s.initialize(); %(instance_name)s.scheduler.set_update_interval(%(update)d); %(instance_name)s.scheduler.enable(); """ % { "type_name": self.type_name(), "dashlet_id": self._dashlet_id, "instance_name": self.instance_name, "div_selector": json.dumps("#%s" % div_id), "url": json.dumps(fetch_url), "body": json.dumps(body), "update": self.update_interval, })
def create_graph(name, size, bounds, v_range, legend): html.open_table(class_="prediction") html.open_tr() html.open_td() html.canvas("", class_="prediction", id_="content_%s" % name, style="width: %dpx; height: %dpx;" % (int(size[0] / 2.0), int(size[1] / 2.0)), width=size[0], height=size[1]) html.close_td() html.close_tr() html.open_tr() html.open_td(class_="legend") for color, title in legend: html.div("", class_="color", style="background-color: %s" % color) html.div(title, class_="entry") html.close_td() html.close_tr() html.close_table() html.javascript( 'cmk.prediction.create_graph("content_%s", %.4f, %.4f, %.4f, %.4f);' % (name, bounds[0], bounds[1], v_range[0], v_range[1]))
def _render_results(self, results: SearchResultsByTopic) -> str: with html.plugged(): for topic, search_results in results: html.open_div(id_=topic, class_="topic") self._render_topic(topic) html.open_ul() for count, result in enumerate(list(search_results)): self._render_result( result, hidden=count >= self._max_num_displayed_results) # TODO: Remove this as soon as the index search does limit its search results if len(list( search_results)) >= self._max_num_displayed_results: html.input( name="show_all_results", value=_("Show all results"), type_="button", onclick= f"cmk.search.on_click_show_all_results('{topic}');") html.close_ul() html.close_div() html.div(None, class_=["topic", "sentinel"]) html_text = html.drain() return html_text
def render_timeline_bar(timeline_layout, style, timeline_nr=0): render_date = timeline_layout["render_date"] from_time, until_time = timeline_layout["range"] html.open_div(class_=["timelinerange", style]) if style == "standalone": html.div(render_date(from_time), class_="from") html.div(render_date(until_time), class_="until") if "time_choords" in timeline_layout: timebar_width = 500 # CSS width of inline timebar for position, title in timeline_layout["time_choords"]: pixel = timebar_width * position html.div('', title=title, class_="timelinechoord", style="left: %dpx" % pixel) html.open_table(id_="timeline_%d" % timeline_nr, class_=["timeline", style]) html.open_tr(class_="timeline") for row_nr, title, width, css in timeline_layout["spans"]: td_attrs = { "style": "width: %.3f%%" % width, "title": title, "class": css, } if row_nr is not None: td_attrs.update( {"id_": "timeline_%d_entry_%d" % (timeline_nr, row_nr)}) if style == "standalone": td_attrs.update({ "onmouseover": "cmk.availability.timeline_hover(%d, %d, 1);" % (timeline_nr, row_nr), "onmouseout": "cmk.availability.timeline_hover(%d, %d, 0);" % (timeline_nr, row_nr), }) html.td('', **td_attrs) html.close_tr() html.close_table() html.close_div()
def _page_no_groups(self) -> None: html.div(_("No groups are defined yet."), class_="info")
def show(self): html.div(_("Loading maps..."), class_="loading") html.javascript("cmk.sidebar.fetch_nagvis_snapin_contents()")
def page(self): # Show outcome of host validation. Do not validate new hosts errors = None if self._mode == "edit": errors = (watolib.validate_all_hosts([self._host.name()]).get( self._host.name(), []) + self._host.validation_errors()) if errors: html.open_div(class_="info") html.open_table(class_="validationerror", boder="0", cellspacing="0", cellpadding="0") html.open_tr() html.open_td(class_="img") html.icon("validation_error") html.close_td() html.open_td() html.open_p() html.h3(_("Warning: This host has an invalid configuration!")) html.open_ul() for error in errors: html.li(error) html.close_ul() html.close_p() if html.form_submitted(): html.br() html.b(_("Your changes have been saved nevertheless.")) html.close_td() html.close_tr() html.close_table() html.close_div() lock_message = "" locked_hosts = watolib.Folder.current().locked_hosts() if locked_hosts: if locked_hosts is True: lock_message = _( "Host attributes locked (You cannot edit this host)") elif isinstance(locked_hosts, str): lock_message = locked_hosts if lock_message: html.div(lock_message, class_="info") html.begin_form("edit_host", method="POST") html.prevent_password_auto_completion() basic_attributes = [ # attribute name, valuepec, default value ("host", self._vs_host_name(), self._host.name()), ] if self._is_cluster(): basic_attributes += [ # attribute name, valuepec, default value ( "nodes", self._vs_cluster_nodes(), self._host.cluster_nodes() if self._host else [], ), ] configure_attributes( new=self._mode != "edit", hosts={self._host.name(): self._host} if self._mode != "new" else {}, for_what="host" if not self._is_cluster() else "cluster", parent=watolib.Folder.current(), basic_attributes=basic_attributes, ) if self._mode != "edit": html.set_focus("host") forms.end() html.hidden_fields() html.end_form()
def _render_availability_timeline(what, av_entry, avoptions, timeline_nr): # type: (AVObjectType, AVEntry, AVOptions, int) -> None html.open_h3() html.write("%s %s" % (_("Timeline of"), availability.object_title(what, av_entry))) html.close_h3() timeline_rows = av_entry["timeline"] if not timeline_rows: html.div(_("No information available"), class_="info") return timeline_layout = availability.layout_timeline( what, timeline_rows, av_entry["considered_duration"], avoptions, "standalone", ) render_timeline_bar(timeline_layout, "standalone", timeline_nr) # Table with detailed events with table_element("av_timeline", "", css="timelineevents", sortable=False, searchable=False) as table: for row_nr, row in enumerate(timeline_layout["table"]): table.row( id_="timetable_%d_entry_%d" % (timeline_nr, row_nr), onmouseover="cmk.availability.timetable_hover(%d, %d, 1);" % (timeline_nr, row_nr), onmouseout="cmk.availability.timetable_hover(%d, %d, 0);" % (timeline_nr, row_nr)) table.cell(_("Links"), css="buttons") if what == "bi": url = html.makeuri([("timewarp", str(int(row["from"])))]) if html.request.var( "timewarp" ) and html.request.get_integer_input_mandatory( "timewarp") == int(row["from"]): html.disabled_icon_button("timewarp_off") else: html.icon_button( url, _("Time warp - show BI aggregate during this time period" ), "timewarp") else: url = html.makeuri([("anno_site", av_entry["site"]), ("anno_host", av_entry["host"]), ("anno_service", av_entry["service"]), ("anno_from", str(row["from"])), ("anno_until", str(row["until"]))]) html.icon_button(url, _("Create an annotation for this period"), "annotation") table.cell(_("From"), row["from_text"], css="nobr narrow") table.cell(_("Until"), row["until_text"], css="nobr narrow") table.cell(_("Duration"), row["duration_text"], css="narrow number") table.cell(_("State"), row["state_name"], css=row["css"] + " state narrow") if "omit_timeline_plugin_output" not in avoptions["labelling"]: table.cell( _("Last Known Plugin Output"), format_plugin_output(row.get("log_output", ""), row)) if "timeline_long_output" in avoptions["labelling"]: table.cell( _("Last Known Long Output"), format_plugin_output(row.get("long_log_output", ""), row)) # Legend for timeline if "display_timeline_legend" in avoptions["labelling"]: render_timeline_legend(what)
def render_timeline_legend(what): # type: (AVObjectType) -> None html.open_div(class_="avlegend timeline") html.h3(_('Timeline colors')) html.div(_("UP") if what == "host" else _("OK"), class_="state state0") if what != "host": html.div(_("WARN"), class_="state state1") html.div(_("DOWN") if what == "host" else _("CRIT"), class_="state state2") html.div(_("UNREACH") if what == "host" else _("UNKNOWN"), class_="state state3") html.div(_("Flapping"), class_="state flapping") if what != "host": html.div(_("H.Down"), class_="state hostdown") html.div(_("Downtime"), class_="state downtime") html.div(_("OO/Service"), class_="state ooservice") html.div(_("unmonitored"), class_="state unmonitored") html.close_div()
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_login_page(self) -> None: html.set_render_headfoot(False) html.add_body_css_class("login") html.header(config.get_page_heading(), Breadcrumb(), javascripts=[]) default_origtarget = ("index.py" if html.myfile in ["login", "logout"] else makeuri(global_request, [])) origtarget = html.get_url_input("_origtarget", default_origtarget) # Never allow the login page to be opened in the iframe. Redirect top page to login page. # This will result in a full screen login page. html.javascript('''if(top != self) { window.top.location.href = location; }''') # When someone calls the login page directly and is already authed redirect to main page if html.myfile == 'login' and _check_auth(html.request): raise HTTPRedirect(origtarget) html.open_div(id_="login") html.open_div(id_="login_window") html.div("" if "hide_version" in config.login_screen else cmk_version.__version__, id_="version") html.begin_form("login", method='POST', add_transid=False, action='login.py') html.hidden_field('_login', '1') html.hidden_field('_origtarget', origtarget) html.label("%s:" % _('Username'), id_="label_user", class_=["legend"], for_="_username") html.br() html.text_input("_username", id_="input_user") html.label("%s:" % _('Password'), id_="label_pass", class_=["legend"], for_="_password") html.br() html.password_input("_password", id_="input_pass", size=None) if html.has_user_errors(): html.open_div(id_="login_error") html.show_user_errors() html.close_div() html.open_div(id_="button_text") html.button("_login", _('Login')) html.close_div() html.close_div() html.open_div(id_="foot") if config.login_screen.get("login_message"): html.open_div(id_="login_message") html.show_message(config.login_screen["login_message"]) html.close_div() footer: List[Union[HTML, str]] = [] for title, url, target in config.login_screen.get("footer_links", []): footer.append(html.render_a(title, href=url, target=target)) if "hide_version" not in config.login_screen: footer.append("Version: %s" % cmk_version.__version__) footer.append("© %s" % html.render_a( "tribe29 GmbH", href="https://checkmk.com", target="_blank")) html.write(HTML(" - ").join(footer)) if cmk_version.is_raw_edition(): html.br() html.br() html.write( _('You can use, modify and distribute Check_MK under the terms of the <a href="%s" target="_blank">' 'GNU GPL Version 2</a>.') % "https://checkmk.com/gpl.html") html.close_div() html.set_focus('_username') html.hidden_fields() html.end_form() html.close_div() html.footer()