def page(self) -> cmk.gui.pages.PageResult: breadcrumb = make_simple_page_breadcrumb( mega_menu_registry["help_links"], _("Info")) make_header( html, self._title(), breadcrumb=breadcrumb, ) html.open_div(id_="info_title") html.h1(_("Your monitoring machine")) html.a( HTMLWriter.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.") % ( HTMLWriter.render_a( _("website"), "https://checkmk.com", target="_blank"), HTMLWriter.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 _page_not_found() -> Response: # TODO: This is a page handler. It should not be located in generic application # object. Move it to another place if request.has_var("_plain_error"): html.write_text(_("Page not found")) else: title = _("Page not found") make_header( html, title, Breadcrumb([ BreadcrumbItem( title="Nowhere", url=None, ), BreadcrumbItem( title=title, url="javascript:document.location.reload(false)", ), ]), ) html.show_error(_("This page was not found. Sorry.")) html.footer() return response
def show_log_list(): title = _("All problematic logfiles") breadcrumb = make_simple_page_breadcrumb( mega_menu_registry.menu_monitoring(), title) make_header(html, title, breadcrumb, _log_list_page_menu(breadcrumb)) if request.has_var("_ack") and not request.var("_do_actions") == _("No"): do_log_ack(site=None, host_name=None, file_name=None) return for site, host_name, logs in all_logs(): if not logs: continue all_logs_empty = not any( parse_file(site, host_name, file_name) for file_name in logs) if all_logs_empty: continue # Logfile vanished html.h3( HTMLWriter.render_a( host_name, href=makeuri( request, [("site", site), ("host", host_name)], ), ), class_="table", ) list_logs(site, host_name, logs) html.footer()
def page_add_snapin() -> None: if not user.may("general.configure_sidebar"): raise MKGeneralException( _("You are not allowed to change the sidebar.")) title = _("Add sidebar element") breadcrumb = make_simple_page_breadcrumb( mega_menu_registry.menu_customize(), title) make_header(html, title, breadcrumb, _add_snapins_page_menu(breadcrumb)) used_snapins = _used_snapins() html.open_div(class_=["add_snapin"]) for name, snapin_class in sorted(snapin_registry.items()): if name in used_snapins: continue if not snapin_class.may_see(): continue # not allowed for this user html.open_div( class_="snapinadder", onmouseover="this.style.cursor='pointer';", onclick="window.top.cmk.sidebar.add_snapin('%s')" % name, ) html.open_div(class_=["snapin_preview"]) html.div("", class_=["clickshield"]) SidebarRenderer().render_snapin( UserSidebarSnapin.from_snapin_type_id(name)) html.close_div() html.div(snapin_class.description(), class_=["description"]) html.close_div() html.close_div() html.footer()
def action(self) -> ActionResult: if request.var("_action") != "discard": return None if not transactions.check_transaction(): return None if not self._may_discard_changes(): return None if not self.has_changes(): return None # Now remove all currently pending changes by simply restoring the last automatically # taken snapshot. Then activate the configuration. This should revert all pending changes. file_to_restore = self._get_last_wato_snapshot_file() if not file_to_restore: raise MKUserError(None, _("There is no WATO snapshot to be restored.")) msg = _("Discarded pending changes (Restored %s)") % file_to_restore # All sites and domains can be affected by a restore: Better restart everything. _changes.add_change( "changes-discarded", msg, domains=ABCConfigDomain.enabled_domains(), need_restart=True, ) self._extract_snapshot(file_to_restore) activate_changes.execute_activate_changes([ d.get_domain_request([]) for d in ABCConfigDomain.enabled_domains() ]) for site_id in activation_sites(): self.confirm_site_changes(site_id) build_index_background() make_header( html, self.title(), breadcrumb=self.breadcrumb(), show_body_start=display_options.enabled(display_options.H), show_top_heading=display_options.enabled(display_options.T), ) html.open_div(class_="wato") html.show_message(_("Successfully discarded all pending changes.")) html.javascript("hide_changes_buttons();") html.footer() return FinalizeRequest(code=200)
def _show_page(self, acktime: float, failed_notifications: LivestatusResponse) -> None: title = _("Confirm failed notifications") breadcrumb = make_simple_page_breadcrumb(mega_menu_registry.menu_monitoring(), title) page_menu = self._page_menu(acktime, failed_notifications, breadcrumb) make_header(html, title, breadcrumb, page_menu) self._show_notification_table(failed_notifications) html.footer()
def show_topology(self, topology_settings: TopologySettings) -> None: visual_spec = ParentChildTopologyPage.visual_spec() breadcrumb = make_topic_breadcrumb( mega_menu_registry.menu_monitoring(), PagetypeTopics.get_topic(visual_spec["topic"]).title(), ) breadcrumb.append(make_current_page_breadcrumb_item(visual_spec["title"])) page_menu = PageMenu(breadcrumb=breadcrumb) self._extend_display_dropdown(page_menu, visual_spec["name"]) make_header(html, visual_spec["title"], breadcrumb, page_menu) self.show_topology_content(topology_settings=topology_settings)
def page(self) -> None: title = _("Replicate user profile") breadcrumb = make_simple_page_breadcrumb( mega_menu_registry.menu_user(), title) make_header(html, title, breadcrumb, self._page_menu(breadcrumb)) for message in get_flashed_messages(): html.show_message(message) # Now, if in distributed environment where users can login to remote sites, set the trigger for # pushing the new user profile to the remote sites asynchronously user_profile_async_replication_page( back_url=request.get_url_input("back", "user_profile.py"))
def page_werk(): load_werks() werk_id = request.get_integer_input_mandatory("werk") if werk_id not in g_werks: raise MKUserError("werk", _("This werk does not exist.")) werk = g_werks[werk_id] title = ("%s %s - %s") % (_("Werk"), render_werk_id( werk, with_link=False), werk["title"]) breadcrumb = make_main_menu_breadcrumb(mega_menu_registry["help_links"]) breadcrumb.append( BreadcrumbItem( title=_("Change log (Werks)"), url="change_log.py", )) breadcrumb.append(make_current_page_breadcrumb_item(title)) make_header(html, title, breadcrumb, _page_menu_werk(breadcrumb, werk)) html.open_table(class_=["data", "headerleft", "werks"]) def werk_table_row(caption, content, css=None): html.open_tr() html.th(caption) html.td(content, class_=css) html.close_tr() translator = cmk.utils.werks.WerkTranslator() werk_table_row(_("ID"), render_werk_id(werk, with_link=False)) werk_table_row(_("Title"), HTMLWriter.render_b(render_werk_title(werk))) werk_table_row(_("Component"), translator.component_of(werk)) werk_table_row(_("Date"), render_werk_date(werk)) werk_table_row(_("Checkmk Version"), werk["version"]) werk_table_row(_("Level"), translator.level_of(werk), css="werklevel werklevel%d" % werk["level"]) werk_table_row(_("Class"), translator.class_of(werk), css="werkclass werkclass%s" % werk["class"]) werk_table_row( _("Compatibility"), translator.compatibility_of(werk), css="werkcomp werkcomp%s" % werk["compatible"], ) werk_table_row(_("Description"), render_werk_description(werk), css="nowiki") html.close_table() html.footer()
def show_create_view_dialog(next_url=None): vs_ds = DatasourceSelection() ds = "services" # Default selection title = _("Create view") breadcrumb = visuals.visual_page_breadcrumb("views", title, "create") make_header( html, title, breadcrumb, make_simple_form_page_menu( _("View"), breadcrumb, form_name="create_view", button_name="_save", save_title=_("Continue"), ), ) if request.var("_save") and transactions.check_transaction(): try: ds = vs_ds.from_html_vars("ds") vs_ds.validate_value(ds, "ds") if not next_url: next_url = makeuri( request, [("datasource", ds)], filename="create_view_infos.py", ) else: next_url = next_url + "&datasource=%s" % ds raise HTTPRedirect(next_url) except MKUserError as e: html.user_error(e) html.begin_form("create_view") html.hidden_field("mode", "create") forms.header(_("Select Datasource")) forms.section(vs_ds.title()) vs_ds.render_input("ds", ds) html.help(vs_ds.help()) forms.end() html.hidden_fields() html.end_form() html.footer()
def show_host_log_list(site, host_name): title = _("Logfiles of host %s") % host_name breadcrumb = _host_log_list_breadcrumb(host_name, title) make_header(html, title, breadcrumb, _host_log_list_page_menu(breadcrumb, site, host_name)) if request.has_var("_ack") and not request.var("_do_actions") == _("No"): do_log_ack(site, host_name, file_name=None) return html.open_table(class_=["data"]) list_logs(site, host_name, logfiles_of_host(site, host_name)) html.close_table() html.footer()
def _render_exception(e: Exception, title: str) -> Response: if plain_error(): return Response( response=[ "%s%s\n" % (("%s: " % title) if title else "", e), ], mimetype="text/plain", ) if not fail_silently(): make_header(html, title, Breadcrumb()) html.show_error(str(e)) html.footer() return response
def _bi_map() -> None: aggr_name = request.var("aggr_name") layout_id = request.var("layout_id") title = _("BI visualization") breadcrumb = make_simple_page_breadcrumb(mega_menu_registry.menu_monitoring(), title) make_header(html, title, breadcrumb) div_id = "node_visualization" html.div("", id=div_id) html.javascript( "node_instance = new cmk.node_visualization.BIVisualization(%s);" % json.dumps(div_id) ) html.javascript( "node_instance.show_aggregations(%s, %s)" % (json.dumps([aggr_name]), json.dumps(layout_id)) )
def page(self) -> None: title = self._page_title() breadcrumb = self._breadcrumb() make_header(html, title, breadcrumb, self._page_menu(breadcrumb)) if transactions.check_transaction(): try: self._action() except MKUserError as e: user_errors.add(e) for message in get_flashed_messages(): html.show_message(message) html.show_user_errors() self._show_form()
def page(self) -> None: row = self._get_crash_row() crash_info = self._get_crash_info(row) title = _("Crash report: %s") % self._crash_id breadcrumb = self._breadcrumb(title) make_header(html, title, breadcrumb, self._page_menu(breadcrumb, crash_info)) # Do not reveal crash context information to unauthenticated users or not permitted # users to prevent disclosure of internal information if not user.may("general.see_crash_reports"): html.show_error("<b>%s:</b> %s" % (_("Internal error"), crash_info["exc_value"])) html.p( _("An internal error occurred while processing your request. " "You can report this issue to your Checkmk administrator. " "Detailed information can be found on the crash report page " "or in <tt>var/log/web.log</tt>.")) html.footer() return if request.has_var("_report") and transactions.check_transaction(): details = self._handle_report_form(crash_info) else: details = ReportSubmitDetails(name="", mail="") if crash_info["crash_type"] == "gui": html.show_error("<b>%s:</b> %s" % (_("Internal error"), crash_info["exc_value"])) html.p( _("An internal error occured while processing your request. " "You can report this issue to the Checkmk team to help " "fixing this issue. Please use the form below for reporting." )) self._warn_about_local_files(crash_info) self._show_report_form(crash_info, details) self._show_crash_report(crash_info) self._show_crash_report_details(crash_info, row) html.footer()
def page(self) -> None: acktime = request.get_float_input_mandatory("acktime", time.time()) if request.var("_confirm"): _acknowledge_failed_notifications(acktime, time.time()) if user.authorized_login_sites(): title = _("Replicate user profile") breadcrumb = make_simple_page_breadcrumb( mega_menu_registry.menu_monitoring(), title ) make_header(html, title, breadcrumb) for message in get_flashed_messages(): html.show_message(message) user_profile_async_replication_page(back_url="clear_failed_notifications.py") return failed_notifications = load_failed_notifications(before=acktime, after=acknowledged_time()) self._show_page(acktime, failed_notifications) if request.var("_confirm"): html.reload_whole_page()
def page(self) -> None: assert user.id is not None html.render_headfoot = False html.add_body_css_class("login") html.add_body_css_class("two_factor") make_header(html, _("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(self) -> cmk.gui.pages.PageResult: breadcrumb = make_simple_page_breadcrumb( mega_menu_registry["help_links"], self._title()) load_werks() werk_table_options = _werk_table_options_from_request() make_header( html, self._title(), breadcrumb, self._page_menu(breadcrumb, werk_table_options), ) for message in get_flashed_messages(): html.show_message(message) handle_acknowledgement() html.open_div(class_="wato") render_werks_table(werk_table_options) html.close_div() html.footer()
def show_file(site, host_name, file_name): int_filename = form_file_to_int(file_name) title = _("Logfiles of Host %s: %s") % (host_name, int_filename) breadcrumb = _show_file_breadcrumb(host_name, title) make_header( html, title, breadcrumb, _show_file_page_menu(breadcrumb, site, host_name, int_filename)) if request.has_var("_ack") and not request.var("_do_actions") == _("No"): do_log_ack(site, host_name, file_name) return try: log_chunks = parse_file(site, host_name, int_filename, hidecontext=request.var("_hidecontext", "no") == "yes") except Exception as e: if active_config.debug: raise html.show_error(_("Unable to show logfile: <b>%s</b>") % e) html.footer() return if log_chunks is None: html.show_error(_("The logfile does not exist on site.")) html.footer() return if log_chunks == []: html.show_message( _("This logfile contains no unacknowledged messages.")) html.footer() return html.open_div(id_="logwatch") for log in log_chunks: html.open_table(class_="groupheader") html.open_tr() html.td(form_level(log["level"]), class_=form_level(log["level"])) html.td(form_datetime(log["datetime"]), class_="date") html.close_tr() html.close_table() html.open_table(class_=["section"]) for line in log["lines"]: html.open_tr(class_=line["class"]) html.open_td(class_="lines") html.icon_button( analyse_url(site, host_name, int_filename, line["line"]), _("Analyze this line"), "analyze", ) html.write_text(line["line"].replace(" ", " ").replace( "\1", "<br>")) html.close_td() html.close_tr() html.close_table() html.close_div() html.footer()
def page(self) -> None: breadcrumb = make_simple_page_breadcrumb(mega_menu_registry.menu_user(), _("Messages")) make_header(html, self.title(), breadcrumb, self.page_menu(breadcrumb)) render_user_message_table("gui_hint")
def page(self) -> cmk.gui.pages.PageResult: """Renders an iframe to view the content of the RobotMK log file""" site_id, host_name, service_description = _get_mandatory_request_vars() breadcrumb: Breadcrumb = make_service_breadcrumb( HostName(host_name), service_description) title = self._title() + _(" of service %s on host %s") % ( service_description, host_name) try: content = _get_html_from_livestatus(self._report_type(), site_id, host_name, service_description) except MKLivestatusNotFoundError: make_header( html, title=title, breadcrumb=breadcrumb, ) html.user_error( MKUserError(None, _("You are not permitted to view this page"))) return if not content[0]: make_header( html, title=title, breadcrumb=breadcrumb, ) html.user_error(MKUserError(None, _("No logs could be found."))) return # Only render page menu with download option if content is not empty # and user is permitted make_header( html, title=title, breadcrumb=breadcrumb, page_menu=self._page_menu(breadcrumb, site_id, host_name, service_description), ) iframe: str = self._report_type() html.iframe( content="", src=makeuri_contextless( request, [ ("report_type", self._report_type()), ("site", site_id), ("host", host_name), ("service", service_description), ], filename="robotmk_report.py", ), name="%s_report" % self._report_type(), id_=iframe, ) html.javascript('cmk.utils.content_scrollbar("main_page_content");') html.javascript( "cmk.utils.add_height_to_simple_bar_content_of_iframe(%s);" % json.dumps(iframe))
def page_graph(): host_name = HostName(request.get_str_input_mandatory("host")) service = request.get_str_input_mandatory("service") dsname = request.get_str_input_mandatory("dsname") breadcrumb = make_service_breadcrumb(host_name, service) make_header( html, _("Prediction for %s - %s - %s") % (host_name, service, dsname), breadcrumb, ) # Get current value from perf_data via Livestatus current_value = get_current_perfdata(host_name, service, dsname) prediction_store = prediction.PredictionStore(host_name, service, dsname) timegroup, choices = _load_prediction_information( tg_name=request.var("timegroup"), prediction_store=prediction_store, ) html.begin_form("prediction") html.write_text(_("Show prediction for ")) html.dropdown("timegroup", choices, deflt=timegroup.name, onchange="document.prediction.submit();") html.hidden_fields() html.end_form() # Get prediction data tg_data = prediction_store.get_data(timegroup.name) if tg_data is None: raise MKGeneralException(_("Missing prediction data.")) swapped = swap_and_compute_levels(tg_data, timegroup.params) vertical_range = compute_vertical_range(swapped) legend = [ ("#000000", _("Reference")), ("#ffffff", _("OK area")), ("#ffff00", _("Warning area")), ("#ff0000", _("Critical area")), ] if current_value is not None: legend.append(("#0000ff", _("Current value: %.2f") % current_value)) create_graph(timegroup.name, graph_size, timegroup.range, vertical_range, legend) if "levels_upper" in timegroup.params: render_dual_area(swapped["upper_warn"], swapped["upper_crit"], "#fff000", 0.4) render_area_reverse(swapped["upper_crit"], "#ff0000", 0.1) if "levels_lower" in timegroup.params: render_dual_area(swapped["lower_crit"], swapped["lower_warn"], "#fff000", 0.4) render_area(swapped["lower_crit"], "#ff0000", 0.1) vscala_low = vertical_range[0] vscala_high = vertical_range[1] vert_scala = compute_vertical_scala(vscala_low, vscala_high) time_scala = [[timegroup.range[0] + i * 3600, "%02d:00" % i] for i in range(0, 25, 2)] render_coordinates(vert_scala, time_scala) if "levels_lower" in timegroup.params: render_dual_area(swapped["average"], swapped["lower_warn"], "#ffffff", 0.5) render_curve(swapped["lower_warn"], "#e0e000", square=True) render_curve(swapped["lower_crit"], "#f0b0a0", square=True) if "levels_upper" in timegroup.params: render_dual_area(swapped["upper_warn"], swapped["average"], "#ffffff", 0.5) render_curve(swapped["upper_warn"], "#e0e000", square=True) render_curve(swapped["upper_crit"], "#f0b0b0", square=True) render_curve(swapped["average"], "#000000") render_curve(swapped["average"], "#000000") # repetition makes line bolder # Try to get current RRD data and render it also from_time, until_time = timegroup.range now = time.time() if from_time <= now <= until_time: timeseries = prediction.get_rrd_data(host_name, service, dsname, "MAX", from_time, until_time) rrd_data = timeseries.values render_curve(rrd_data, "#0000ff", 2) if current_value is not None: rel_time = (now - prediction.timezone_at(now)) % timegroup.slice render_point(timegroup.range[0] + rel_time, current_value, "#0000ff") html.footer()