def ajax_graph(): response.set_content_type("application/json") try: context_var = request.get_str_input_mandatory("context") context = json.loads(context_var) response_data = render_ajax_graph(context) response.set_data(json.dumps(response_data)) except Exception as e: logger.error("Ajax call ajax_graph.py failed: %s\n%s", e, traceback.format_exc()) if config.debug: raise response.set_data("ERROR: %s" % e)
def page(self) -> None: if not user.may("wato.diagnostics"): raise MKAuthException( _("Sorry, you lack the permission for downloading diagnostics dumps.") ) site = request.get_ascii_input_mandatory("site") tarfile_name = request.get_ascii_input_mandatory("tarfile_name") file_content = self._get_diagnostics_dump_file(site, tarfile_name) response.set_content_type("application/x-tgz") response.headers["Content-Disposition"] = "Attachment; filename=%s" % tarfile_name response.set_data(file_content)
def _export_audit_log(self, audit: List[AuditLogStore.Entry]) -> ActionResult: response.set_content_type("text/csv") if self._options["display"] == "daily": filename = "wato-auditlog-%s_%s.csv" % ( render.date(time.time()), render.time_of_day(time.time()), ) else: filename = "wato-auditlog-%s_%s_days.csv" % ( render.date(time.time()), self._options["display"][1], ) response.headers["Content-Disposition"] = 'attachment; filename="%s"' % filename titles = [ _("Date"), _("Time"), _("Object type"), _("Object"), _("User"), _("Action"), _("Summary"), ] if self._show_details: titles.append(_("Details")) resp = [] resp.append(",".join(titles) + "\n") for entry in audit: columns = [ render.date(int(entry.time)), render.time_of_day(int(entry.time)), entry.object_ref.object_type.name if entry.object_ref else "", entry.object_ref.ident if entry.object_ref else "", entry.user_id, entry.action, '"' + escaping.strip_tags(entry.text).replace('"', "'") + '"', ] if self._show_details: columns.append('"' + escaping.strip_tags(entry.diff_text).replace('"', "'") + '"') resp.append(",".join(columns) + "\n") response.set_data("".join(resp)) return FinalizeRequest(code=200)
def page_api() -> None: try: if not request.has_var("output_format"): response.set_content_type("application/json") output_format = "json" else: output_format = request.get_ascii_input_mandatory("output_format", "json").lower() if output_format not in _FORMATTERS: response.set_content_type("text/plain") raise MKUserError( None, "Only %s are supported as output formats" % " and ".join('"%s"' % f for f in _FORMATTERS), ) # TODO: Add some kind of helper for boolean-valued variables? pretty_print = False pretty_print_var = request.get_str_input_mandatory("pretty_print", "no").lower() if pretty_print_var not in ("yes", "no"): raise MKUserError(None, 'pretty_print must be "yes" or "no"') pretty_print = pretty_print_var == "yes" api_call = _get_api_call() _check_permissions(api_call) request_object = _get_request(api_call) _check_formats(output_format, api_call, request_object) _check_request_keys(api_call, request_object) resp = _execute_action(api_call, request_object) except MKAuthException as e: resp = { "result_code": 1, "result": _("Authorization Error. Insufficent permissions for '%s'") % e, } except MKException as e: resp = { "result_code": 1, "result": _("Checkmk exception: %s\n%s") % (e, "".join(traceback.format_exc())), } except Exception: if config.debug: raise logger.exception("error handling web API call") resp = { "result_code": 1, "result": _("Unhandled exception: %s") % traceback.format_exc(), } response.set_data(_FORMATTERS[output_format][1 if pretty_print else 0](resp))
def ajax_graph_hover(): response.set_content_type("application/json") try: context_var = html.request.get_str_input_mandatory("context") context = json.loads(context_var) hover_time = html.request.get_integer_input_mandatory("hover_time") response_data = render_ajax_graph_hover(context, hover_time) html.write(json.dumps(response_data)) except Exception as e: logger.error("Ajax call ajax_graph_hover.py failed: %s\n%s", e, traceback.format_exc()) if config.debug: raise html.write("ERROR: %s" % e)
def ajax_snapin(): """Renders and returns the contents of the requested sidebar snapin(s) in JSON format""" response.set_content_type("application/json") user_config = UserSidebarConfig(user, config.sidebar) snapin_id = request.var("name") snapin_ids = ([snapin_id] if snapin_id else request.get_str_input_mandatory("names", "").split(",")) snapin_code: List[str] = [] for snapin_id in snapin_ids: try: snapin_instance = user_config.get_snapin(snapin_id).snapin_type() except KeyError: continue # Skip not existing snapins if not snapin_instance.may_see(): continue # When restart snapins are about to be refreshed, only render # them, when the core has been restarted after their initial # rendering if not snapin_instance.refresh_regularly( ) and snapin_instance.refresh_on_restart(): since = request.get_float_input_mandatory("since", 0) newest = since for site in sites.states().values(): prog_start = site.get("program_start", 0) if prog_start > newest: newest = prog_start if newest <= since: # no restart snapin_code.append("") continue with output_funnel.plugged(): try: snapin_instance.show() except Exception as e: write_snapin_exception(e) e_message = ( _("Exception during element refresh (element '%s')") % snapin_instance.type_name()) logger.error("%s %s: %s", request.requested_url, e_message, traceback.format_exc()) finally: snapin_code.append(output_funnel.drain()) response.set_data(json.dumps(snapin_code))
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 ajax_set_snapin_site(): response.set_content_type("application/json") ident = request.var("ident") if ident not in snapin_registry: raise MKUserError(None, _("Invalid ident")) site = request.var("site") site_choices = dict([("", _("All sites"))] + sites.get_configured_site_choices()) if site not in site_choices: raise MKUserError(None, _("Invalid site")) snapin_sites = user.load_file("sidebar_sites", {}, lock=True) snapin_sites[ident] = site user.save_file("sidebar_sites", snapin_sites)
def _export_audit_log(self, audit: List[AuditLogStore.Entry]) -> ActionResult: response.set_content_type("text/csv") if self._options["display"] == "daily": filename = "wato-auditlog-%s_%s.csv" % (render.date( time.time()), render.time_of_day(time.time())) else: filename = "wato-auditlog-%s_%s_days.csv" % (render.date( time.time()), self._options["display"][1]) response.headers[ "Content-Disposition"] = "attachment; filename=\"%s\"" % filename titles = [ _('Date'), _('Time'), _('Object type'), _('Object'), _('User'), _('Action'), _('Summary'), ] if self._show_details: titles.append(_('Details')) html.write(','.join(titles) + '\n') for entry in audit: columns = [ render.date(int(entry.time)), render.time_of_day(int(entry.time)), entry.object_ref.object_type.name if entry.object_ref else "", entry.object_ref.ident if entry.object_ref else "", entry.user_id, entry.action, '"' + escaping.strip_tags(entry.text).replace('"', "'") + '"', ] if self._show_details: columns.append( '"' + escaping.strip_tags(entry.diff_text).replace('"', "'") + '"') html.write(','.join(columns) + '\n') return FinalizeRequest(code=200)
def page(self): if not user.may("wato.automation"): raise MKAuthException( _("This account has no permission for automation.")) response.set_content_type("text/plain") _set_version_headers() # Parameter was added with 1.5.0p10 if not request.has_var("_version"): raise MKGeneralException( _("Your central site is incompatible with this remote site")) # - _version and _edition_short were added with 1.5.0p10 to the login call only # - x-checkmk-version and x-checkmk-edition were added with 2.0.0p1 # Prefer the headers and fall back to the request variables for now. central_version = (request.headers["x-checkmk-version"] if "x-checkmk-version" in request.headers else request.get_ascii_input_mandatory("_version")) central_edition_short = ( request.headers["x-checkmk-edition"] if "x-checkmk-edition" in request.headers else request.get_ascii_input_mandatory("_edition_short")) if not compatible_with_central_site( central_version, central_edition_short, cmk_version.__version__, cmk_version.edition().short, ): raise MKGeneralException( _("Your central site (Version: %s, Edition: %s) is incompatible with this " "remote site (Version: %s, Edition: %s)") % ( central_version, central_edition_short, cmk_version.__version__, cmk_version.edition().short, )) response.set_data( repr({ "version": cmk_version.__version__, "edition_short": cmk_version.edition().short, "login_secret": _get_login_secret(create_on_demand=True), }))
def page(self): if not user.may("wato.automation"): raise MKAuthException( _("This account has no permission for automation.")) response.set_content_type("text/plain") # Parameter was added with 1.5.0p10 if not request.has_var("_version"): raise MKGeneralException( _("Your central site is incompatible with this remote site")) response.set_data( repr({ "version": cmk_version.__version__, "edition_short": cmk_version.edition_short(), "login_secret": _get_login_secret(create_on_demand=True), }))
def page(self): if not config.user.may("wato.automation"): raise MKAuthException(_("This account has no permission for automation.")) response.set_content_type("text/plain") if not request.has_var("_version"): # Be compatible to calls from sites using versions before 1.5.0p10. # Deprecate with 1.7 by throwing an exception in this situation. resp = _get_login_secret(create_on_demand=True) else: resp = { "version": cmk_version.__version__, "edition_short": cmk_version.edition_short(), "login_secret": _get_login_secret(create_on_demand=True), } response.set_data(repr(resp))
def ajax_render_graph_content(): response.set_content_type("application/json") try: api_request = request.get_request() resp = { "result_code": 0, "result": render_graph_content_html(api_request["graph_recipe"], api_request["graph_data_range"], api_request["graph_render_options"]), } except Exception: logger.exception("could not render graph") resp = { "result_code": 1, "result": _("Unhandled exception: %s") % traceback.format_exc(), } response.set_data(json.dumps(resp))
def _ajax_switch_masterstate(self) -> None: response.set_content_type("text/plain") if not user.may("sidesnap.master_control"): return if not transactions.check_transaction(): return site = request.get_ascii_input_mandatory("site") column = request.get_ascii_input_mandatory("switch") state = request.get_integer_input_mandatory("state") commands = { ("enable_notifications", 1): "ENABLE_NOTIFICATIONS", ("enable_notifications", 0): "DISABLE_NOTIFICATIONS", ("execute_service_checks", 1): "START_EXECUTING_SVC_CHECKS", ("execute_service_checks", 0): "STOP_EXECUTING_SVC_CHECKS", ("execute_host_checks", 1): "START_EXECUTING_HOST_CHECKS", ("execute_host_checks", 0): "STOP_EXECUTING_HOST_CHECKS", ("enable_flap_detection", 1): "ENABLE_FLAP_DETECTION", ("enable_flap_detection", 0): "DISABLE_FLAP_DETECTION", ("process_performance_data", 1): "ENABLE_PERFORMANCE_DATA", ("process_performance_data", 0): "DISABLE_PERFORMANCE_DATA", ("enable_event_handlers", 1): "ENABLE_EVENT_HANDLERS", ("enable_event_handlers", 0): "DISABLE_EVENT_HANDLERS", } command = commands.get((column, state)) if not command: html.write_text(_("Command %s/%d not found") % (column, state)) return sites.live().command("[%d] %s" % (int(time.time()), command), site) sites.live().set_only_sites([site]) sites.live().query( "GET status\nWaitTrigger: program\nWaitTimeout: 10000\nWaitCondition: %s = %d\nColumns: %s\n" % (column, state, column) ) sites.live().set_only_sites() self.show()
def _ajax_switch_site(self): response.set_content_type("application/json") # _site_switch=sitename1:on,sitename2:off,... if not config.user.may("sidesnap.sitestatus"): return if not transactions.check_transaction(): return switch_var = request.var("_site_switch") if switch_var: for info in switch_var.split(","): sitename, onoff = info.split(":") if sitename not in config.sitenames(): continue if onoff == "on": config.user.enable_site(sitename) else: config.user.disable_site(sitename) config.user.save_site_config()
def handle_page(self) -> None: """The page handler, called by the page registry""" # FIXME: cyclical link between crash_reporting.py and pages.py from cmk.gui.crash_reporting import handle_exception_as_gui_crash_report response.set_content_type("application/json") try: action_response = self.page() resp = {"result_code": 0, "result": action_response, "severity": "success"} except MKMissingDataError as e: resp = {"result_code": 1, "result": str(e), "severity": "success"} except MKException as e: resp = {"result_code": 1, "result": str(e), "severity": "error"} except Exception as e: if config.debug: raise logger.exception("error calling AJAX page handler") handle_exception_as_gui_crash_report( plain_error=True, show_crash_link=getattr(g, "may_see_crash_reports", False), ) resp = {"result_code": 1, "result": str(e), "severity": "error"} response.set_data(json.dumps(resp))
def ajax_fold(): response.set_content_type("application/json") user_config = UserSidebarConfig(user, config.sidebar) user_config.folded = request.var("fold") == "yes" user_config.save()
def _serve_host(host): response.set_data(json.dumps(serialize_host(host))) response.set_content_type('application/json') response.headers.add('ETag', constructors.etag_of_obj(host).to_header()) return response._get_current_object()
def serve_group(group, serializer): response.set_data(json.dumps(serializer(group))) if response.status_code != 204: response.set_content_type('application/json') response.headers.add('ETag', constructors.etag_of_dict(group).to_header()) return response._get_current_object()