def _process_notify_message(msg): msg['id'] = utils.gen_id() msg['time'] = time.time() # construct the list of recipients recipients = [] if isinstance(msg['dest'], str): dest_what = msg['dest'] else: dest_what = msg['dest'][0] if dest_what == 'broadcast': recipients = config.multisite_users.keys() elif dest_what == 'online': recipients = userdb.get_online_user_ids() elif dest_what == 'list': recipients = msg['dest'][1] num_recipients = len(recipients) num_success = {} for method in msg['methods']: num_success[method] = 0 # Now loop all notitification methods to send the notifications errors = {} for user_id in recipients: for method in msg['methods']: try: handler = _notify_methods()[method]['handler'] handler(user_id, msg) num_success[method] = num_success[method] + 1 except MKInternalError as e: errors.setdefault(method, []).append((user_id, e)) message = _('The notification has been sent via<br>') message += "<table>" for method in msg['methods']: message += "<tr><td>%s</td><td>to %d of %d recipients</td></tr>" %\ (_notify_methods()[method]["title"], num_success[method], num_recipients) message += "</table>" message += _('<p>Sent notification to: %s</p>') % ', '.join(recipients) message += '<a href="%s">%s</a>' % (html.makeuri([]), _('Back to previous page')) html.message(HTML(message)) if errors: error_message = "" for method, method_errors in errors.items(): error_message += _("Failed to send %s notifications to the following users:") % method table_rows = '' for user, exception in method_errors: table_rows += html.render_tr(html.render_td(html.render_tt(user))\ + html.render_td(exception)) error_message += html.render_table(table_rows) + html.render_br() html.show_error(HTML(error_message))
def _handle_report_form(self, crash_info): details = {} try: vs = self._vs_crash_report() details = vs.from_html_vars("_report") vs.validate_value(details, "_report") # Make the resulting page execute the crash report post request url_encoded_params = html.urlencode_vars( list(details.items()) + [ ("crashdump", base64.b64encode( _pack_crash_report( self._get_serialized_crash_report()))), ]) html.open_div(id_="pending_msg", style="display:none") html.show_message(_("Submitting crash report...")) html.close_div() html.open_div(id_="success_msg", style="display:none") html.show_message( _("Your crash report has been submitted (ID: ###ID###). Thanks for your participation, " "it is very important for the quality of Checkmk.<br><br>" "Please note:" "<ul>" "<li>In general we do <i>not</i> respond to crash reports, " "except we need further information from you.</li>" "<li>We read every feedback thoroughly, but this might happen " "not before a couple of weeks or even months have passed and is " "often aligned with our release cycle.</li>" "<li>If you are in need of a quick solution for your problem, then " "we can help you within the scope of professional support. If you " "already have a support contract, then please use your personal " "support email address to send us a mail refering to your crash " "report.<br>If you are interested in the details about support, " "you find details on <a href=\"https://checkmk.com/" "checkmk_support_contract.html\" target=\"_blank\">our website</a>." )) html.close_div() html.open_div(id_="fail_msg", style="display:none") report_url = html.makeuri_contextless( [ ("subject", "Checkmk Crash Report - " + self._get_version()), ], filename="mailto:" + self._get_crash_report_target(), ) html.show_error( _("Failed to send the crash report. Please download it manually and send it " "to <a href=\"%s\">%s</a>") % (report_url, self._get_crash_report_target())) html.close_div() html.javascript( "cmk.crash_reporting.submit(%s, %s);" % (json.dumps( config.crash_report_url), json.dumps(url_encoded_params))) except MKUserError as e: action_message = "%s" % e html.add_user_error(e.varname, action_message) return details
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) html.header(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 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 do_log_ack(site, host_name, file_name): sites.live().set_auth_domain("action") logs_to_ack = [] if not host_name and not file_name: # all logs on all hosts for this_site, this_host, logs in all_logs(): for int_filename in logs: file_display = form_file_to_ext(int_filename) logs_to_ack.append( (this_site, this_host, int_filename, file_display)) elif host_name and not file_name: # all logs on one host for int_filename in logfiles_of_host(site, host_name): file_display = form_file_to_ext(int_filename) logs_to_ack.append((site, host_name, int_filename, file_display)) elif host_name and file_name: # one log on one host int_filename = form_file_to_int(file_name) logs_to_ack = [(site, host_name, int_filename, form_file_to_ext(int_filename))] else: for this_site, this_host, logs in all_logs(): file_display = form_file_to_ext(file_name) if file_name in logs: logs_to_ack.append( (this_site, this_host, file_name, file_display)) ack_msg = _get_ack_msg(host_name, file_name) ack = request.var("_ack") if not user.may("general.act"): html.h1(_("Permission denied"), class_=["error"]) html.div(_("You are not allowed to acknowledge %s") % ack_msg, class_=["error"]) html.footer() return # filter invalid values if ack != "1": raise MKUserError("_ack", _("Invalid value for ack parameter.")) for this_site, this_host, int_filename, display_name in logs_to_ack: try: acknowledge_logfile(this_site, this_host, int_filename, display_name) except Exception as e: html.show_error( _("The log file <tt>%s</tt> of host <tt>%s</tt> could not be deleted: %s." ) % (display_name, this_host, e)) html.footer() return html.show_message("<b>%s</b><p>%s</p>" % (_("Acknowledged %s") % ack_msg, _("Acknowledged all messages in %s.") % ack_msg)) html.footer()
def _page_not_found(): # TODO: This is a page handler. It should not be located in generic application # object. Move it to another place if html.request.has_var("_plain_error"): html.write(_("Page not found")) else: html.header(_("Page not found")) html.show_error(_("This page was not found. Sorry.")) html.footer()
def edit_valuespec( vs, # type: Dictionary value, # type: Dict[str, Any] buttontext=None, # type: Optional[Text] method="GET", # type: str varprefix="", # type: str validate=None, # type: Optional[Callable[[Dict[str, Any]], None]] formname="form", # type: str consume_transid=True, # type: bool focus=None # type: Optional[str] ): # type: (...) -> Optional[Dict[str, Any]] if html.request.get_ascii_input( "filled_in") == formname and html.transaction_valid(): if consume_transid: html.check_transaction() messages = [] try: new_value = vs.from_html_vars(varprefix) vs.validate_value(new_value, varprefix) except MKUserError as e: messages.append("%s: %s" % (vs.title(), e.message)) html.add_user_error(e.varname, e.message) if validate and not html.has_user_errors(): try: validate(new_value) except MKUserError as e: messages.append(e.message) html.add_user_error(e.varname, e.message) if messages: html.show_error("".join(["%s<br>\n" % m for m in messages])) else: return new_value html.begin_form(formname, method=method) html.help(vs.help()) vs.render_input(varprefix, value) if buttontext is None: buttontext = _("Save") html.button("save", buttontext) # Should be ignored be hidden_fields, but I do not dare to change it there html.request.del_var("filled_in") html.hidden_fields() if focus: html.set_focus(focus) else: vs.set_focus(varprefix) html.end_form() return None
def _ajax_show_nagvis_maps_snapin(self): api_request = request.get_request() if api_request["type"] == "table": self._show_table(api_request) elif api_request["type"] == "tree": self._show_tree(api_request) elif api_request["type"] == "error": html.show_error(api_request["message"]) else: raise NotImplementedError() self._show_footnote_links()
def _render_exception(e, title=""): if title: title = "%s: " % title if _plain_error(): html.set_output_format("text") html.write("%s%s\n" % (title, e)) elif not _fail_silently(): html.header(title) html.show_error(e) html.footer()
def _render_exception(e: Exception, title: str) -> Response: if plain_error(): html.set_output_format("text") if title: title = "%s: " % title html.write("%s%s\n" % (title, e)) elif not fail_silently(): html.header(title, Breadcrumb()) html.show_error(str(e)) html.footer() return html.response
def call(name: str, *args: Any) -> None: n = 0 for hook in hooks.get(name, []): n += 1 try: hook.handler(*args) except Exception as e: if config.debug: t, v, tb = sys.exc_info() msg = "".join(traceback.format_exception(t, v, tb, None)) html.show_error("<h1>" + _("Error executing hook") + " %s #%d: %s</h1>" "<pre>%s</pre>" % (name, n, e, msg)) raise
def show(self) -> None: only_sites = snapin_site_choice("mkeventd_performance", get_event_console_site_choices()) try: entries = self._mkeventd_performance_entries(only_sites) except Exception as e: html.show_error("%s" % e) return html.open_table(class_=["mkeventd_performance"]) for _index, left, right in entries: html.tr(html.render_td("%s:" % left) + html.render_td(right)) html.close_table()
def _ajax_search(self): q = _maybe_strip(html.get_unicode_input('q')) if not q: return try: generate_results(q) except MKException as e: html.show_error(e) except Exception as e: logger.exception("error generating quicksearch results") if config.debug: raise html.show_error(traceback.format_exc())
def _show_crash_dump_message( crash: "GUICrashReport", plain_text: bool, fail_silently: bool, show_crash_link: Optional[bool] ) -> None: """Create a crash dump from a GUI exception and display a message to the user""" if show_crash_link is None: show_crash_link = user.may("general.see_crash_reports") title = _("Internal error") message = "%s: %s<br>\n<br>\n" % (title, crash.crash_info["exc_value"]) # Do not reveal crash context information to unauthenticated users or not permitted # users to prevent disclosure of internal information if not show_crash_link: message += _( "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>." ) else: crash_url = makeuri( request, [ ("site", omd_site()), ("crash_id", crash.ident_to_text()), ], filename="crash.py", ) message += ( _( "An internal error occured while processing your request. " "You can report this issue to the Checkmk team to help " 'fixing this issue. Please open the <a href="%s">crash report page</a> ' "and use the form for reporting the problem." ) % crash_url ) if plain_text: response.set_content_type("text/plain") response.set_data("%s\n" % escaping.strip_tags(message)) return if fail_silently: return html.header(title, Breadcrumb()) html.show_error(message) 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(): html.header(title, Breadcrumb()) html.show_error(str(e)) html.footer() return response
def call(name, *args): n = 0 for hook in hooks.get(name, []): n += 1 try: hook.handler(*args) except Exception as e: if config.debug: txt = StringIO.StringIO() t, v, tb = sys.exc_info() traceback.print_exception(t, v, tb, None, txt) html.show_error("<h1>" + _("Error executing hook") + " %s #%d: %s</h1>" "<pre>%s</pre>" % (name, n, e, txt.getvalue())) raise
def show(self): import imp try: cma_nav = imp.load_source("cma_nav", "/usr/lib/python2.7/cma_nav.py") except IOError: html.show_error(_("Unable to import cma_nav module")) return base_url = "/webconf/" self._iconlink(_("Main Menu"), base_url, "home") for url, icon, title, _descr in cma_nav.modules(): # type: ignore[attr-defined] url = base_url + url self._iconlink(title, url, icon)
def render_mobile_list(rows, view, group_cells, cells, num_columns, show_checkboxes): if not html.mobile: html.show_error(_("This view can only be used in mobile mode.")) return # Force relative timestamp always. This saves space. painter_options = PainterOptions.get_instance() painter_options.set("ts_format", "rel") html.open_ul(class_="mobilelist", **{"data-role": "listview"}) # Paint data rows for row in rows: html.open_li() rendered_cells = [cell.render(row) for cell in cells] if rendered_cells: # First cell (assumedly state) is left rendered_class, rendered_content = rendered_cells[0] html.open_p(class_=["ui-li-aside", "ui-li-desc", rendered_class]) html.write(rendered_content) html.close_p() if len(rendered_cells) > 1: content = HTML(" · ").join([ rendered_cell[1] for rendered_cell in rendered_cells[1:num_columns + 1] ]) html.h3(content) for rendered_cell, cell in zip( rendered_cells[num_columns + 1:], cells[num_columns + 1:]): rendered_class, rendered_content = rendered_cell html.open_p(class_="ui-li-desc") cell.paint_as_header() html.write_text(': ') html.open_span(class_=rendered_class) html.write(rendered_content) html.close_span() html.close_p() html.close_li() html.close_ul() html.javascript('$("ul.mobilelist a").attr("data-ajax", "false");')
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) html.header(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 _ajax_search(self) -> None: """Generate the search result list""" query = _maybe_strip(html.request.get_unicode_input('q')) if not query: return try: results = self._quicksearch_manager.generate_results(query) QuicksearchResultRenderer().show(results, query) except TooManyRowsError as e: html.show_warning(str(e)) except MKException as e: html.show_error("%s" % e) except Exception: logger.exception("error generating quicksearch results") if config.debug: raise html.show_error(traceback.format_exc())
def render_mobile_table(rows, view, group_cells, cells, num_columns, show_checkboxes): if not is_mobile(request, response): html.show_error(_("This view can only be used in mobile mode.")) return # Force relative timestamp always. This saves space. painter_options = PainterOptions.get_instance() painter_options.set("ts_format", "rel") odd = "odd" html.open_table(class_="mobile data") # Paint header if view.get("column_headers") != "off": html.open_tr() n = 0 for cell in cells: cell.paint_as_header() html.close_tr() # Paint data rows for row in rows: odd = "even" if odd == "odd" else "odd" html.open_tr(class_="%s0" % odd) for n, cell in enumerate(cells): if n > 0 and n % num_columns == 0: html.close_tr() html.open_tr(class_="%s0" % odd) if n == len(cells) - 1 and n % num_columns != (num_columns - 1): colspan = num_columns - (n % num_columns) else: colspan = None cell.paint(row, colspan=colspan) html.close_row() html.close_table() html.javascript('$("table.mobile a").attr("data-ajax", "false");')
def show(self): if not cmk_version.is_cma(): return # The cma_nav-Module is a Python 2.7 module that is already installed by the CMA OS. For # the future we should change this to some structured file format, but for the moment we # have to deal with existing firmwares. Use some py27 wrapper to produce the needed output. p = subprocess.Popen( # pylint:disable=consider-using-with ["/usr/bin/python2.7"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, encoding="utf-8", shell=False, close_fds=True, ) stdout, stderr = p.communicate( "\n".join( [ "import imp", 'cma_nav = imp.load_source("cma_nav", "/usr/lib/python2.7/cma_nav.py")', "print(cma_nav.modules())", ] ) ) if stderr: html.show_error(_("Failed to render navigation: %s") % stderr) return nav_modules = ast.literal_eval(stdout) base_url = "/webconf/" self._iconlink(_("Main Menu"), base_url, "home") for url, icon, title, _descr in nav_modules: url = base_url + url self._iconlink(title, url, icon)
def show_crash_dump_message(crash, plain_text, fail_silently): # type: (GUICrashReport, bool, bool) -> None """Create a crash dump from a GUI exception and display a message to the user""" title = _("Internal error") message = u"%s: %s<br>\n<br>\n" % (title, crash.crash_info["exc_value"]) # Do not reveal crash context information to unauthenticated users or not permitted # users to prevent disclosure of internal information if not config.user.may("general.see_crash_reports"): message += _( "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>.") else: crash_url = html.makeuri( [ ("site", config.omd_site()), ("crash_id", crash.ident_to_text()), ], filename="crash.py", ) message += _( "An internal error occured while processing your request. " "You can report this issue to the Checkmk team to help " "fixing this issue. Please open the <a href=\"%s\">crash report page</a> " "and use the form for reporting the problem.") % crash_url if plain_text: html.set_output_format("text") html.write("%s\n" % html.strip_tags(message)) return if fail_silently: return html.header(title) html.show_error(message) html.footer()
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 html.request.has_var("_plain_error"): html.write(_("Page not found")) else: title = _("Page not found") html.header( 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 html.response
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()
def render( self, rows: Rows, show_checkboxes: bool, num_columns: int, show_filters: List[Filter], unfiltered_amount_of_rows: int, ) -> None: view_spec = self.view.spec home = ("mobile.py", "Home", "home") page = html.request.var("page") if not page: if view_spec.get("mustsearch"): page = "filter" else: page = "data" title = views.view_title(self.view.spec, self.view.context) navbar = [("data", _("Results"), "grid", 'results_button'), ("filter", _("Filter"), "search", '')] if config.user.may("general.act"): navbar.append(("commands", _("Commands"), "gear", '')) # Should we show a page with context links? context_links = list( views.collect_context_links(self.view, rows, mobile=True, only_types=['views'])) if context_links: navbar.append(("context", _("Context"), "arrow-r", '')) page_id = "view_" + view_spec["name"] if page == "filter": jqm_page_header(_("Filter / Search"), left_button=home, id_="filter") _show_filter_form(show_filters) jqm_page_navfooter(navbar, 'filter', page_id) elif page == "commands": # Page: Commands if config.user.may("general.act"): jqm_page_header(_("Commands"), left_button=home, id_="commands") show_commands = True if html.request.has_var("_do_actions"): try: show_commands = do_commands( self.view.datasource.infos[0], rows) except MKUserError as e: html.show_error("%s" % e) html.add_user_error(e.varname, e) show_commands = True if show_commands: _show_command_form(self.view.datasource, rows) jqm_page_navfooter(navbar, 'commands', page_id) elif page == "data": # Page: data rows of view jqm_page_header( title, left_button=home, right_button=("javascript:document.location.reload();", _("Reload"), "refresh"), id_="data") html.open_div(id_="view_results") if len(rows) == 0: html.write(_("No hosts/services found.")) else: try: if cmk.gui.view_utils.row_limit_exceeded( unfiltered_amount_of_rows, self.view.row_limit): cmk.gui.view_utils.query_limit_exceeded_warn( self.view.row_limit, config.user) del rows[self.view.row_limit:] self.view.layout.render( rows, view_spec, self.view.group_cells, self.view.row_cells, num_columns, show_checkboxes and not html.do_actions(), ) except Exception as e: logger.exception("error rendering mobile view") html.write(_("Error showing view: %s") % e) html.close_div() jqm_page_navfooter(navbar, 'data', page_id) # Page: Context buttons elif page == "context": jqm_page_header(_("Context"), left_button=home, id_="context") _show_context_links(context_links) jqm_page_navfooter(navbar, 'context', page_id)
def edit_dictionaries( dictionaries: 'Sequence[Tuple[str, Union[Transform, Dictionary]]]', value: Dict[str, Any], focus: Optional[str] = None, hover_help: bool = True, validate: Optional[Callable[[Any], None]] = None, title: Optional[str] = None, method: str = "GET", preview: bool = False, varprefix: str = "", formname: str = "form", consume_transid: bool = True): if html.request.get_ascii_input( "filled_in") == formname and html.transaction_valid(): if not preview and consume_transid: html.check_transaction() messages: List[str] = [] new_value: Dict[str, Dict[str, Any]] = {} for keyname, vs_dict in dictionaries: dict_varprefix = varprefix + keyname new_value[keyname] = {} try: edited_value = vs_dict.from_html_vars(dict_varprefix) vs_dict.validate_value(edited_value, dict_varprefix) new_value[keyname].update(edited_value) except MKUserError as e: messages.append("%s: %s" % (vs_dict.title() or _("Properties"), e)) html.add_user_error(e.varname, e) except Exception as e: messages.append("%s: %s" % (vs_dict.title() or _("Properties"), e)) html.add_user_error(None, e) if validate and not html.has_user_errors(): try: validate(new_value[keyname]) except MKUserError as e: messages.append("%s" % e) html.add_user_error(e.varname, e) if messages: messages_joined = "".join(["%s<br>\n" % m for m in messages]) if not preview: html.show_error(messages_joined) else: raise MKUserError(None, messages_joined) else: return new_value html.begin_form(formname, method=method) for keyname, vs_dict in dictionaries: dict_varprefix = varprefix + keyname subvalue = value.get(keyname, {}) vs_dict.render_input_as_form(dict_varprefix, subvalue) end() # Should be ignored be hidden_fields, but I do not dare to change it there html.request.del_var("filled_in") html.hidden_fields() html.end_form()
def edit_dictionaries( dictionaries, # type: List[Tuple[str, Union[Transform, Dictionary]]] value, # type: Dict[str, Any] focus=None, # type: Optional[str] hover_help=True, # type: bool validate=None, # type: Optional[Callable[[Any], None]] buttontext=None, # type: Optional[Text] title=None, # type: Optional[Text] buttons=None, # type: List[Tuple[str, Text, str]] method="GET", # type: str preview=False, # type: bool varprefix="", # type: str formname="form", # type: str consume_transid=True # type: bool ): if html.request.get_ascii_input( "filled_in") == formname and html.transaction_valid(): if not preview and consume_transid: html.check_transaction() messages = [] # type: List[Text] new_value = {} # type: Dict[str, Dict[str, Any]] for keyname, vs_dict in dictionaries: dict_varprefix = varprefix + keyname new_value[keyname] = {} try: edited_value = vs_dict.from_html_vars(dict_varprefix) vs_dict.validate_value(edited_value, dict_varprefix) new_value[keyname].update(edited_value) except MKUserError as e: messages.append("%s: %s" % (vs_dict.title() or _("Properties"), e)) html.add_user_error(e.varname, e) except Exception as e: messages.append("%s: %s" % (vs_dict.title() or _("Properties"), e)) html.add_user_error(None, e) if validate and not html.has_user_errors(): try: validate(new_value[keyname]) except MKUserError as e: messages.append("%s" % e) html.add_user_error(e.varname, e) if messages: messages_joined = "".join(["%s<br>\n" % m for m in messages]) if not preview: html.show_error(messages_joined) else: raise MKUserError(None, messages_joined) else: return new_value html.begin_form(formname, method=method) for keyname, vs_dict in dictionaries: dict_varprefix = varprefix + keyname subvalue = value.get(keyname, {}) vs_dict.render_input_as_form(dict_varprefix, subvalue) end() if buttons: for name, button_title, _icon in buttons: html.button(name, button_title) else: if buttontext is None: buttontext = _("Save") html.button("save", buttontext) # Should be ignored be hidden_fields, but I do not dare to change it there html.request.del_var("filled_in") html.hidden_fields() html.end_form()
def do_log_ack(site, host_name, file_name): logs_to_ack = [] if not host_name and not file_name: # all logs on all hosts for this_site, this_host, logs in all_logs(): for int_filename in logs: file_display = form_file_to_ext(int_filename) logs_to_ack.append( (this_site, this_host, int_filename, file_display)) ack_msg = _('all logfiles on all hosts') elif host_name and not file_name: # all logs on one host for int_filename in logfiles_of_host(site, host_name): file_display = form_file_to_ext(int_filename) logs_to_ack.append((site, host_name, int_filename, file_display)) ack_msg = _('all logfiles of host %s') % host_name elif host_name and file_name: # one log on one host int_filename = form_file_to_int(file_name) logs_to_ack = [(site, host_name, int_filename, form_file_to_ext(int_filename))] ack_msg = _('the log file %s on host %s') % (file_name, host_name) else: for this_site, this_host, logs in all_logs(): file_display = form_file_to_ext(file_name) if file_name in logs: logs_to_ack.append( (this_site, this_host, file_name, file_display)) ack_msg = _('log file %s on all hosts') % file_name title = _("Acknowledge %s") % html.render_text(ack_msg) if host_name: breadcrumb = make_host_breadcrumb(host_name) else: breadcrumb = make_simple_page_breadcrumb(MegaMenuMonitoring, title) html.header(title, breadcrumb) html.begin_context_buttons() button_all_logfiles() if host_name: html.context_button(_("All Logfiles of Host"), html.makeuri([('file', '')])) if host_name and file_name: html.context_button(_("Back to Logfile"), html.makeuri([])) html.end_context_buttons() ack = html.request.var('_ack') if not html.confirm( _("Do you really want to acknowledge %s by <b>deleting</b> all stored messages?" ) % ack_msg): html.footer() return if not config.user.may("general.act"): html.h1(_('Permission denied'), class_=["error"]) html.div(_('You are not allowed to acknowledge %s') % ack_msg, class_=["error"]) html.footer() return # filter invalid values if ack != '1': raise MKUserError('_ack', _('Invalid value for ack parameter.')) for this_site, this_host, int_filename, display_name in logs_to_ack: try: acknowledge_logfile(this_site, this_host, int_filename, display_name) except Exception as e: html.show_error( _('The log file <tt>%s</tt> of host <tt>%s</tt> could not be deleted: %s.' ) % (display_name, this_host, e)) html.footer() return html.show_message('<b>%s</b><p>%s</p>' % (_('Acknowledged %s') % ack_msg, _('Acknowledged all messages in %s.') % ack_msg)) 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, file_name) html.header(title, make_host_breadcrumb(host_name)) html.begin_context_buttons() html.context_button(_("Services"), services_url(site, host_name), 'services') html.context_button(_("All Logfiles of Host"), html.makeuri([('file', '')])) button_all_logfiles() html.context_button(_("Analyze patterns"), analyse_url(site, host_name, file_name), 'analyze') if html.request.var('_hidecontext', 'no') == 'yes': hide_context_label = _('Show Context') hide_context_param = 'no' hide = True else: hide_context_label = _('Hide Context') hide_context_param = 'yes' hide = False try: log_chunks = parse_file(site, host_name, int_filename, hide) except Exception as e: if config.debug: raise html.end_context_buttons() html.show_error(_("Unable to show logfile: <b>%s</b>") % e) html.footer() return if log_chunks is None: html.end_context_buttons() html.show_error(_("The logfile does not exist.")) html.footer() return if log_chunks == []: html.end_context_buttons() html.show_message( _("This logfile contains no unacknowledged messages.")) html.footer() return ack_button(site, host_name, int_filename) html.context_button(hide_context_label, html.makeuri([('_hidecontext', hide_context_param)])) html.end_context_buttons() html.open_div(id_="logwatch") for log in log_chunks: html.open_div(class_=["chunk"]) html.open_table(class_=["section"]) 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() for line in log['lines']: html.open_p(class_=line['class']) html.icon_button( analyse_url(site, host_name, file_name, line['line']), _("Analyze this line"), "analyze") html.write_text(line['line'].replace(" ", " ").replace( "\1", "<br>")) html.close_p() html.close_div() html.close_div() html.footer()
def show_exception(connection_id: str, title: str, e: Exception, debug: bool = True) -> None: html.show_error("<b>" + connection_id + ' - ' + title + "</b>" "<pre>%s</pre>" % (debug and traceback.format_exc() or e))