def page_login() -> None: title = _("Check_MK Mobile") mobile_html_head(title) jqm_page_header(title, id_="login") html.div(_("Welcome to Check_MK Mobile."), id_="loginhead") html.begin_form("login", method='POST', add_transid=False) # Keep information about original target URL default_origtarget = "index.py" if html.myfile in ["login", "logout" ] else html.makeuri([]) origtarget = html.get_url_input("_origtarget", default_origtarget) html.hidden_field('_origtarget', escaping.escape_attribute(origtarget)) html.text_input("_username", label=_("Username:"******"username") html.password_input("_password", size=None, label=_("Password:"******"current-password") html.br() html.button("_login", _('Login')) html.set_focus("_username") html.end_form() html.open_div(id_="loginfoot") html.img("themes/classic/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 page(self) -> None: assert user.id is not None html.set_render_headfoot(False) html.add_body_css_class("login") html.add_body_css_class("two_factor") html.header(_("Two-factor authentication"), Breadcrumb(), javascripts=[]) html.open_div(id_="login") html.open_div(id_="login_window") html.open_a(href="https://checkmk.com") html.img( src=theme.detect_icon_path(icon_name="logo", prefix="mk-"), id_="logo", class_="custom" if theme.has_custom_logo() else None, ) html.close_a() if not is_two_factor_login_enabled(user.id): raise MKGeneralException(_("Two-factor authentication not enabled")) html.begin_form( "two_factor_login", method="POST", add_transid=False, action="user_login_two_factor.py" ) html.prevent_password_auto_completion() html.hidden_field( "_origtarget", origtarget := request.get_url_input("_origtarget", "index.py") ) if backup_code := request.get_ascii_input("_backup_code"): if is_two_factor_backup_code_valid(user.id, backup_code): set_two_factor_completed() raise HTTPRedirect(origtarget)
def page_login(): title = _("Check_MK Mobile") mobile_html_head(title) jqm_page_header(title, id_="login") html.div(_("Welcome to Check_MK Mobile."), id_="loginhead") html.begin_form("login", method='POST', add_transid=False) # Keep information about original target URL origtarget = html.request.var('_origtarget', '') if not origtarget and not html.myfile == 'login': origtarget = html.request.requested_url html.hidden_field('_origtarget', html.attrencode(origtarget)) html.text_input("_username", label=_("Username:"******"_password", size=None, label=_("Password:"******"_login", _('Login')) html.set_focus("_username") html.end_form() html.open_div(id_="loginfoot") html.img("themes/classic/images/logo_cmk_small.png", class_="logomk") html.div(HTML( _("© <a target=\"_blank\" href=\"https://checkmk.com\">tribe29 GmbH</a>" )), class_="copyright") jqm_page_footer() mobile_html_foot()
def _table_head( treename: str, id_: str, isopen: bool, title: str, show_more_toggle: bool, help_text: Union[str, HTML, None] = None, ) -> None: onclick = foldable_container_onclick(treename, id_, fetch_url=None) img_id = foldable_container_img_id(treename, id_) html.open_thead() html.open_tr(class_="heading") html.open_td(id_="nform.%s.%s" % (treename, id_), onclick=onclick, colspan=2) html.img( id_=img_id, class_=["treeangle", "nform", "open" if isopen else "closed"], src=theme.url("images/tree_closed.svg"), align="absbottom", ) html.write_text(title) html.help(help_text) if show_more_toggle: html.more_button("foldable_" + id_, dom_levels_up=4, with_text=True) html.close_td() html.close_tr() html.close_thead()
def show(self): html.open_div(class_="speedometer") html.img(html.theme_url("images/speedometer.svg"), id_="speedometerbg") html.canvas('', width="228", height="146", id_="speedometer") html.close_div() html.javascript("cmk.sidebar.speedometer_show_speed(0, 0, 0);")
def _table_head( treename: str, id_: str, isopen: bool, title: str, show_more_toggle: bool, ) -> None: onclick = html.foldable_container_onclick(treename, id_, fetch_url=None) img_id = html.foldable_container_img_id(treename, id_) html.open_thead() html.open_tr(class_="heading") html.open_td(id_="nform.%s.%s" % (treename, id_), onclick=onclick, colspan=2) html.img(id_=img_id, class_=["treeangle", "nform", "open" if isopen else "closed"], src="themes/%s/images/tree_closed.png" % (html.get_theme()), align="absbottom") html.write_text(title) if show_more_toggle: html.more_button("foldable_" + id_, dom_levels_up=4) html.close_td() html.close_tr() html.close_thead()
def _show_graph_html_content(graph_artwork, graph_data_range, graph_render_options) -> None: """Render the HTML code of a graph without its container That is a canvas object for drawing the actual graph and also legend, buttons, resize handle, etc. """ graph_render_options = artwork.add_default_render_options( graph_render_options) html.open_div( class_=[ "graph", "preview" if graph_render_options["preview"] else None ], style="font-size: %.1fpt;%s" % (graph_render_options["font_size"], _graph_padding_styles(graph_render_options)), ) if graph_render_options["show_controls"]: _show_graph_add_to_icon_for_popup(graph_artwork, graph_data_range, graph_render_options) v_axis_label = graph_artwork["vertical_axis"]["axis_label"] if v_axis_label: html.div(v_axis_label, class_="v_axis_label") # Add the floating elements if graph_render_options[ "show_graph_time"] and not graph_render_options["preview"]: html.div( graph_artwork["time_axis"]["title"] or "", css=[ "time", "inline" if graph_render_options["show_title"] == "inline" else None ], ) if graph_render_options["show_controls"] and graph_render_options[ "resizable"]: html.img(src=theme.url("images/resize_graph.png"), class_="resize") _show_html_graph_title(graph_artwork, graph_render_options) _show_graph_canvas(graph_render_options) # Note: due to "omit_zero_metrics" the graph might not have any curves if _graph_legend_enabled(graph_render_options, graph_artwork): _show_graph_legend(graph_artwork, graph_render_options) model_params_repr = graph_artwork["definition"].get("model_params_repr") model_params_display = (graph_artwork["definition"].get( "model_params", {}).get("display_model_parametrization")) if model_params_repr and model_params_display: html.open_div(align="center") html.h2(_("Forecast Parametrization")) html.write_html(model_params_repr) html.close_div() html.close_div()
def page(self) -> cmk.gui.pages.PageResult: breadcrumb = make_simple_page_breadcrumb( mega_menu_registry["help_links"], _("Info")) html.header( self._title(), breadcrumb=breadcrumb, ) html.open_div(id_="info_title") html.h1(_("Your monitoring machine")) html.a(html.render_img(theme.url("images/tribe29.svg")), "https://tribe29.com", target="_blank") html.close_div() html.div(None, id_="info_underline") html.open_div(id_="info_intro_text") html.span(_("Open. Effective. Awesome.")) html.span( _("May we present? Monitoring as it's supposed to be: " "incredibly quick to install, infinetely scalable, highly customizable and " "designed for admins.")) html.span( _("Visit our %s to learn more about Checkmk and about the %s.") % ( html.render_a( _("website"), "https://checkmk.com", target="_blank"), html.render_a( _("latest version"), "https://checkmk.com/product/latest-version", target="_blank", ), )) html.close_div() version_major_minor = re.sub(r".\d+$", "", Version(__version__).version_base) if version_major_minor: current_version_link = "https://checkmk.com/product/checkmk-%s" % version_major_minor else: current_version_link = "https://checkmk.com/product/latest-version" html.open_div(id="info_image") html.open_a(href=current_version_link, target="_blank") html.img(theme.url("images/monitoring-machine.png")) html.close_a() html.close_div() html.close_div() html.open_div(id_="info_footer") html.span( _("© %s tribe29 GmbH. All Rights Reserved.") % time.strftime("%Y")) html.a(_("License agreement"), href="https://checkmk.com/legal.html", target="_blank") html.close_div()
def show(self): html.open_div(class_="speedometer") html.img(theme.url("images/speedometer.svg"), id_="speedometerbg") html.canvas("", width=str(snapin_width), height="146", id_="speedometer") html.close_div() html.javascript("cmk.sidebar.speedometer_show_speed(0, 0, 0);")
def grouped_row_title(index, group_spec, num_rows, trclass, num_cells): is_open = html.foldable_container_is_open("grouped_rows", index, False) html.open_tr( class_=["data", "grouped_row_header", "closed" if not is_open else '', "%s0" % trclass]) html.open_td(colspan=num_cells, onclick="cmk.views.toggle_grouped_rows('grouped_rows', '%s', this, %d)" % (index, num_rows)) html.img(html.theme_url("images/tree_closed.png"), align="absbottom", class_=["treeangle", "nform", "open" if is_open else "closed"]) html.write_text("%s (%d)" % (group_spec["title"], num_rows)) html.close_td() html.close_tr() return not is_open
def show(self): html.open_table(class_="dashlet_overview") html.open_tr() html.open_td(valign="top") html.open_a(href="https://checkmk.com/") html.img(html.theme_url("images/check_mk.trans.120.png"), style="margin-right: 30px;") html.close_a() html.close_td() html.open_td() html.h2("CheckMK") html.write_text( _('Welcome to Checkmk. If you want to learn more about Checkmk, please visit ' 'our <a href="https://checkmk.com/" target="_blank">user manual</a>.')) html.close_td() html.close_tr() html.close_table()
def _render_header_icon() -> None: if user.get_attribute("nav_hide_icons_title"): if theme.has_custom_logo(): html.img(theme.detect_icon_path(icon_name="logo", prefix="mk-"), class_="custom") else: html.img(theme.detect_icon_path(icon_name="icon_min", prefix="tribe29_")) else: if theme.has_custom_logo(): html.img(theme.detect_icon_path(icon_name="logo", prefix="mk-")) else: html.img(theme.detect_icon_path(icon_name="icon", prefix="tribe29_"))
def show(self): html.open_table(class_="dashlet_overview") html.open_tr() html.open_td(valign="top") html.open_a(href="https://mathias-kettner.com/check_mk.html") html.img(html.theme_url("images/check_mk.trans.120.png"), style="margin-right: 30px;") html.close_a() html.close_td() html.open_td() html.h2("Check_MK Multisite") html.write_html( 'Welcome to Check_MK Multisite. If you want to learn more about Multisite, please visit ' 'our <a href="https://mathias-kettner.com/checkmk_multisite.html">online documentation</a>. ' 'Multisite is part of <a href="https://mathias-kettner.com/check_mk.html">Check_MK</a> - an Open Source ' 'project by <a href="https://mathias-kettner.com">Mathias Kettner</a>.' ) html.close_td() html.close_tr() html.close_table()
def _show_sidebar_head(self): html.open_div(id_="side_header") html.open_a( href=config.user.start_url or config.start_url, target="main", title=_("Go to main page"), ) if config.user.get_attribute("nav_hide_icons_title"): html.img(html.theme_url('images/tribe29_icon_min.svg')) else: html.img(html.theme_url('images/tribe29_icon.svg')) 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(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(" "))] 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) })
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.img(src=html.theme_url("images/mk-logo.svg"), id_="logo") 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'), cssclass="hot") 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()
def foldable_container( *, treename: str, id_: str, isopen: bool, title: HTMLContent, indent: Union[str, None, bool] = True, first: bool = False, icon: Optional[str] = None, fetch_url: Optional[str] = None, title_url: Optional[str] = None, title_target: Optional[str] = None, padding: int = 15, save_state: bool = True, ) -> Iterator[bool]: isopen = user.get_tree_state(treename, id_, isopen) onclick = foldable_container_onclick(treename, id_, fetch_url, save_state) img_id = foldable_container_img_id(treename, id_) container_id = foldable_container_id(treename, id_) html.open_div(class_=["foldable", "open" if isopen else "closed"]) html.open_div(class_="foldable_header", onclick=None if title_url else onclick) if isinstance(title, HTML): # custom HTML code html.write_text(title) else: html.open_b(class_=["treeangle", "title"]) if title_url: html.a(title, href=title_url, target=title_target) else: html.write_text(title) html.close_b() if icon: html.img( id_=img_id, class_=[ "treeangle", "title", # Although foldable_sidebar is given via the argument icon it should not be # displayed as big as an icon. "icon" if icon != "foldable_sidebar" else None, "open" if isopen else "closed", ], src=theme.detect_icon_path(icon, "icon_"), onclick=onclick if title_url else None, ) else: html.img( id_=img_id, class_=["treeangle", "open" if isopen else "closed"], src=theme.url("images/tree_closed.svg"), onclick=onclick if title_url else None, ) html.close_div() indent_style = "padding-left: %dpx; " % (padding if indent else 0) if indent == "form": html.close_td() html.close_tr() html.close_table() indent_style += "margin: 0; " html.open_ul( id_=container_id, class_=["treeangle", "open" if isopen else "closed"], style=indent_style ) yield isopen html.close_ul() html.close_div()
def show(self): html.open_a(href="https://checkmk.com/", target="_blank") html.img(theme.url("images/check_mk.trans.120.png"), style="margin-right: 30px;") html.close_a()
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(" "))] 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) })
def _show_login_page(self) -> None: html.set_render_headfoot(False) html.add_body_css_class("login") html.header(get_page_heading(), Breadcrumb(), javascripts=[]) default_origtarget = ("index.py" if requested_file_name(request) in ["login", "logout"] else makeuri(request, [])) origtarget = request.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 requested_file_name(request) == "login" and _check_auth(request): raise HTTPRedirect(origtarget) html.open_div(id_="login") html.open_div(id_="login_window") html.open_a(href="https://checkmk.com") html.img( src=theme.detect_icon_path(icon_name="logo", prefix="mk-"), id_="logo", class_="custom" if theme.has_custom_logo() else None, ) html.close_a() 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 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"), cssclass="hot") 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[HTML] = [] 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(escape_html("Version: %s" % cmk_version.__version__)) footer.append( HTML("© %s" % html.render_a( "tribe29 GmbH", href="https://tribe29.com", target="_blank"))) html.write_html(HTML(" - ").join(footer)) if cmk_version.is_raw_edition(): html.br() html.br() html.write_text( _('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()
def show(self): html.open_a(href="https://mathias-kettner.com/check_mk.html") html.img(html.theme_url("images/check_mk.trans.120.png"), style="margin-right: 30px;") html.close_a()
def _show_node(self, tree, show_host, mousecode=None, img_class=None): # Check if we have an assumed state: comparing assumed state (tree[1]) with state (tree[0]) if tree[1] and tree[0] != tree[1]: addclass: Optional[str] = "assumed" effective_state = tree[1] else: addclass = None effective_state = tree[0] class_: List[Optional[str]] = [ "content", # "state", "state%d" % (effective_state["state"] if effective_state["state"] is not None else -1), addclass, ] html.open_span(class_=class_) html.write_text(self._render_bi_state(effective_state["state"])) html.close_span() if mousecode: if img_class: html.img( src=theme.url("images/tree_closed.svg"), class_=["treeangle", img_class], onclick=mousecode, ) html.open_span(class_=["content", "name"]) icon_name, icon_title = None, None if tree[0]["in_downtime"] == 2: icon_name = "downtime" icon_title = _("This element is currently in a scheduled downtime.") elif tree[0]["in_downtime"] == 1: # only display host downtime if the service has no own downtime icon_name = "derived_downtime" icon_title = _("One of the subelements is in a scheduled downtime.") if tree[0]["acknowledged"]: icon_name = "ack" icon_title = _("This problem has been acknowledged.") if not tree[0]["in_service_period"]: icon_name = "outof_serviceperiod" icon_title = _("This element is currently not in its service period.") if icon_name and icon_title: html.icon(icon_name, title=icon_title, class_=["icon", "bi"]) yield if mousecode: if str(effective_state["state"]) in tree[2].get("state_messages", {}): html.b(HTML("♦"), class_="bullet") html.write_text(tree[2]["state_messages"][str(effective_state["state"])]) html.close_span() output: HTML = cmk.gui.view_utils.format_plugin_output( effective_state["output"], shall_escape=config.escape_plugin_output ) if output: output = html.render_b(HTML("♦"), class_="bullet") + output else: output = HTML() html.span(output, class_=["content", "output"])
def show(self): html.open_div(class_="speedometer") html.img(html.theme_url("images/speedometer.png"), id_="speedometerbg") html.canvas('', width="228", height="136", id_="speedometer") html.close_div() html.javascript(""" function show_speed(percentage) { var canvas = document.getElementById('speedometer'); if (!canvas) return; var context = canvas.getContext('2d'); if (!context) return; if (percentage > 100.0) percentage = 100.0; var orig_x = 116; var orig_y = 181; var angle_0 = 232.0; var angle_100 = 307.0; var angle = angle_0 + (angle_100 - angle_0) * percentage / 100.0; var angle_rad = angle / 360.0 * Math.PI * 2; var length = 120; var end_x = orig_x + (Math.cos(angle_rad) * length); var end_y = orig_y + (Math.sin(angle_rad) * length); context.clearRect(0, 0, 228, 136); context.beginPath(); context.moveTo(orig_x, orig_y); context.lineTo(end_x, end_y); context.closePath(); context.shadowOffsetX = 2; context.shadowOffsetY = 2; context.shadowBlur = 2; context.strokeStyle = "#000000"; context.stroke(); } function speedometer_show_speed(last_perc, program_start, scheduled_rate) { var url = "sidebar_ajax_speedometer.py" + "?last_perc=" + last_perc + "&scheduled_rate=" + scheduled_rate + "&program_start=" + program_start; cmk.ajax.call_ajax(url, { response_handler: function(handler_data, response_body) { try { var data = JSON.parse(response_body); oDiv = document.getElementById('speedometer'); // Terminate reschedule when the speedometer div does not exist anymore // (e.g. the snapin has been removed) if (!oDiv) return; oDiv.title = data.title oDiv = document.getElementById('speedometerbg'); oDiv.title = data.title move_needle(data.last_perc, data.percentage); // 50 * 100ms = 5s = refresh time } catch(ie) { // Ignore errors during re-rendering. Proceed with reschedule... var data = handler_data; } setTimeout(function(data) { return function() { speedometer_show_speed(data.percentage, data.program_start, data.scheduled_rate); }; }(data), 5000); }, error_handler : function(handler_data, status_code, error_msg) { setTimeout(function(data) { return function() { return speedometer_show_speed(data.percentage, data.program_start, data.scheduled_rate); }; }(handler_data), 5000); }, method : "GET", handler_data : { "percentage" : last_perc, "last_perc" : last_perc, "program_start" : program_start, "scheduled_rate" : scheduled_rate } }); } var g_needle_timeout = null; function move_needle(from_perc, to_perc) { var new_perc = from_perc * 0.9 + to_perc * 0.1; show_speed(new_perc); if (g_needle_timeout != null) clearTimeout(g_needle_timeout); g_needle_timeout = setTimeout(function(new_perc, to_perc) { return function() { move_needle(new_perc, to_perc); }; }(new_perc, to_perc), 50); } speedometer_show_speed(0, 0, 0); """)