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(): watolib.init_wato_datastructures(with_wato_lock=True) title = _('Replicate user profile') breadcrumb = make_simple_page_breadcrumb( mega_menu_registry.menu_monitoring(), title) html.header(title, breadcrumb) for message in get_flashed_messages(): html.show_message(message) # This local import is needed for the moment import cmk.gui.wato.user_profile # pylint: disable=redefined-outer-name cmk.gui.wato.user_profile.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 generate_data(target: EndpointTarget, validate: bool = True) -> Dict[str, Any]: endpoint: Endpoint methods = ["get", "put", "post", "delete"] # NOTE # This needs to be called on the very first request to create some important configuration # files with default values for them to be considered in the OpenAPI schema. If this wouldn't # be called, the schema would for example lack certain default tag groups. watolib.init_wato_datastructures(with_wato_lock=True) for endpoint in sorted( ENDPOINT_REGISTRY, key=lambda e: (e.func.__module__, methods.index(e.method)) ): if target in endpoint.blacklist_in: continue SPEC.path( path=endpoint.path, operations=endpoint.to_operation_dict(), ) generated_spec = SPEC.to_dict() # return generated_spec _add_cookie_auth(generated_spec) if not validate: return generated_spec # NOTE: deepcopy the dict because validate_spec modifies the SPEC in-place, leaving some # internal properties lying around, which leads to an invalid spec-file. check_dict = copy.deepcopy(generated_spec) validate_spec(check_dict) # NOTE: We want to modify the thing afterwards. The SPEC object would be a global reference # which would make modifying the spec very awkward, so we deepcopy again. return generated_spec
def page(self): watolib.init_wato_datastructures(with_wato_lock=True) config.user.need_permission("wato.activate") request = self.webapi_request() activate_until = request.get("activate_until") if not activate_until: raise MKUserError( "activate_until", _("Missing parameter \"%s\".") % "activate_until") manager = watolib.ActivateChangesManager() manager.load() affected_sites = request.get("sites", "").strip() if not affected_sites: affected_sites = manager.dirty_and_active_activation_sites() else: affected_sites = affected_sites.split(",") comment = request.get("comment", "").strip() if comment == "": comment = None activate_foreign = request.get("activate_foreign", "0") == "1" activation_id = manager.start(affected_sites, activate_until, comment, activate_foreign) return { "activation_id": activation_id, }
def page(self): # To prevent mixups in written files we use the same lock here as for # the normal WATO page processing. This might not be needed for some # special automation requests, like inventory e.g., but to keep it simple, # we request the lock in all cases. with watolib.exclusive_lock(): watolib.init_wato_datastructures(with_wato_lock=False) # TODO: Refactor these two calls to also use the automation_command_registry if self._command == "checkmk-automation": self._execute_cmk_automation() return elif self._command == "push-profile": self._execute_push_profile() return try: automation_command = watolib.automation_command_registry[ self._command] except KeyError: raise MKGeneralException( _("Invalid automation command: %s.") % self._command) self._execute_automation_command(automation_command)
def page(self) -> None: watolib.init_wato_datastructures(with_wato_lock=True) profile_changed = False if html.request.has_var('_save') and html.check_transaction(): try: profile_changed = self._action() except MKUserError as e: html.add_user_error(e.varname, e) if profile_changed and config.user.authorized_login_sites(): title = _('Replicate new user profile') else: title = self._page_title() breadcrumb = make_simple_page_breadcrumb( mega_menu_registry.menu_user(), title) html.header(title, breadcrumb, self._page_menu(breadcrumb)) # 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 if profile_changed and config.user.authorized_login_sites(): user_profile_async_replication_page() return self._show_form(profile_changed)
def _from_vars(self): # type: () -> None config.user.need_permission("wato.download_agent_output") host_name = html.request.var("host") if not host_name: raise MKGeneralException(_("The host is missing.")) ty = html.request.var("type") if ty not in ["walk", "agent"]: raise MKGeneralException(_("Invalid type specified.")) self._back_url = html.get_url_input("back_url", deflt="") or None watolib.init_wato_datastructures(with_wato_lock=True) host = watolib.Folder.current().host(host_name) if not host: raise MKGeneralException( _("Host is not managed by WATO. " "Click <a href=\"%s\">here</a> to go back.") % escape_attribute(self._back_url)) host.need_permission("read") self._request = FetchAgentOutputRequest(host=host, agent_type=ty)
def page_api(): 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) watolib.init_wato_datastructures( ) # Initialize host and site attributes 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") % e} 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 page(self) -> None: watolib.init_wato_datastructures(with_wato_lock=True) title = _('Replicate user profile') breadcrumb = make_simple_page_breadcrumb(mega_menu_registry.menu_user(), title) html.header(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=html.get_url_input("back", "user_profile.py"))
def page_api(): try: pretty_print = False if not html.request.has_var("output_format"): html.set_output_format("json") if html.output_format not in _FORMATTERS: html.set_output_format("python") 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_var = html.request.var("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) watolib.init_wato_datastructures( ) # Initialize host and site attributes request_object = _get_request(api_call) _check_formats(api_call, request_object) _check_request_keys(api_call, request_object) response = _execute_action(api_call, request_object) except MKAuthException as e: response = { "result_code": 1, "result": _("Authorization Error. Insufficent permissions for '%s'") % e } except MKException as e: response = { "result_code": 1, "result": _("Check_MK exception: %s") % e } except Exception as e: if config.debug: raise logger.exception() response = { "result_code": 1, "result": _("Unhandled exception: %s") % traceback.format_exc(), } html.write( _FORMATTERS[html.output_format][1 if pretty_print else 0](response))
def page(self): watolib.init_wato_datastructures(with_wato_lock=True) user.need_permission("wato.activate") api_request = self.webapi_request() activate_until = api_request.get("activate_until") if not activate_until: raise MKUserError("activate_until", _('Missing parameter "%s".') % "activate_until") manager = watolib.ActivateChangesManager() manager.load() affected_sites_request = ensure_str( api_request.get("sites", "").strip()) if not affected_sites_request: affected_sites = manager.dirty_and_active_activation_sites() else: affected_sites = affected_sites_request.split(",") comment: Optional[str] = api_request.get("comment", "").strip() activate_foreign = api_request.get("activate_foreign", "0") == "1" valuespec = _vs_activation("", manager.has_foreign_changes()) if valuespec: valuespec.validate_value( { "comment": comment, "foreign": activate_foreign, }, "activate", ) if comment == "": comment = None activation_id = manager.start( sites=affected_sites, activate_until=ensure_str(activate_until), comment=None if comment is None else ensure_str(comment), activate_foreign=activate_foreign, ) return { "activation_id": activation_id, }
def page(self): watolib.init_wato_datastructures(with_wato_lock=True) config.user.need_permission("wato.activate") request = self.webapi_request() activation_id = request.get("activation_id") if not activation_id: raise MKUserError("activation_id", _("Missing parameter \"%s\".") % "activation_id") manager = watolib.ActivateChangesManager() manager.load() manager.load_activation(activation_id) return manager.get_state()
def page(self) -> None: watolib.init_wato_datastructures(with_wato_lock=True) profile_changed = False if html.request.has_var('_save') and html.check_transaction(): try: profile_changed = self._action() except MKUserError as e: html.add_user_error(e.varname, e) # 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 if profile_changed and config.user.authorized_login_sites(): user_profile_async_replication_page() return self._show_form(profile_changed)
def page(self) -> None: watolib.init_wato_datastructures(with_wato_lock=True) title = self._page_title() breadcrumb = make_simple_page_breadcrumb(mega_menu_registry.menu_user(), title) html.header(title, breadcrumb, self._page_menu(breadcrumb)) if html.request.has_var('_save') and html.check_transaction(): try: self._action() except MKUserError as e: html.add_user_error(e.varname, e) for message in get_flashed_messages(): html.show_message(message) if html.has_user_errors(): html.show_user_errors() self._show_form()
def page(self): watolib.init_wato_datastructures(with_wato_lock=True) if not user.may("wato.diag_host"): raise MKAuthException(_("You are not permitted to perform this action.")) if not transactions.check_transaction(): raise MKAuthException(_("Invalid transaction")) api_request = self.webapi_request() hostname = api_request.get("host") if not hostname: raise MKGeneralException(_("The hostname is missing.")) host = watolib.Host.host(hostname) if not host: raise MKGeneralException(_("The given host does not exist.")) if host.is_cluster(): raise MKGeneralException(_("This view does not support cluster hosts.")) host.need_permission("read") _test = api_request.get("_test") if not _test: raise MKGeneralException(_("The test is missing.")) # Execute a specific test if _test not in dict(ModeDiagHost.diag_host_tests()).keys(): raise MKGeneralException(_("Invalid test.")) # TODO: Use ModeDiagHost._vs_rules() for processing/validation? args: List[str] = [""] * 13 for idx, what in enumerate( [ "ipaddress", "snmp_community", "agent_port", "snmp_timeout", "snmp_retries", "tcp_connect_timeout", ] ): args[idx] = api_request.get(what, "") if api_request.get("snmpv3_use"): snmpv3_use = { "0": "noAuthNoPriv", "1": "authNoPriv", "2": "authPriv", }.get(api_request.get("snmpv3_use", ""), "") args[7] = snmpv3_use if snmpv3_use != "noAuthNoPriv": snmpv3_auth_proto = { str(DropdownChoice.option_id("md5")): "md5", str(DropdownChoice.option_id("sha")): "sha", }.get(api_request.get("snmpv3_auth_proto", ""), "") args[8] = snmpv3_auth_proto args[9] = api_request.get("snmpv3_security_name", "") args[10] = api_request.get("snmpv3_security_password", "") if snmpv3_use == "authPriv": snmpv3_privacy_proto = { str(DropdownChoice.option_id("DES")): "DES", str(DropdownChoice.option_id("AES")): "AES", }.get(api_request.get("snmpv3_privacy_proto", ""), "") args[11] = snmpv3_privacy_proto args[12] = api_request.get("snmpv3_privacy_password", "") else: args[9] = api_request.get("snmpv3_security_name", "") result = watolib.diag_host( host.site_id(), hostname, _test, *args, ) return { "next_transid": transactions.fresh_transid(), "status_code": result.return_code, "output": ensure_str(result.response, errors="replace"), }
def _wato_page_handler(current_mode: str, mode_permissions: List[PermissionName], mode_class: Type[WatoMode]) -> None: try: init_wato_datastructures(with_wato_lock=not html.is_transaction()) except Exception: # Snapshot must work in any case if current_mode == 'snapshot': pass else: raise # Check general permission for this mode if mode_permissions is not None and not config.user.may("wato.seeall"): _ensure_mode_permissions(mode_permissions) mode = mode_class() # Do actions (might switch mode) action_message: Optional[str] = None if html.is_transaction(): try: config.user.need_permission("wato.edit") # Even if the user has seen this mode because auf "seeall", # he needs an explicit access permission for doing changes: if config.user.may("wato.seeall"): if mode_permissions: _ensure_mode_permissions(mode_permissions) if cmk.gui.watolib.read_only.is_enabled( ) and not cmk.gui.watolib.read_only.may_override(): raise MKUserError(None, cmk.gui.watolib.read_only.message()) result = mode.action() if isinstance(result, tuple): newmode, action_message = result else: newmode = result # We assume something has been modified and increase the config generation ID by one. update_config_generation() # If newmode is False, then we shall immediately abort. # This is e.g. the case, if the page outputted non-HTML # data, such as a tarball (in the export function). We must # be sure not to output *any* further data in that case. if newmode is False: return # if newmode is not None, then the mode has been changed if newmode is not None: assert not isinstance(newmode, bool) if newmode == "": # no further information: configuration dialog, etc. if action_message: html.show_message(action_message) wato_html_footer() return mode_permissions, mode_class = _get_mode_permission_and_class( newmode) current_mode = newmode mode = mode_class() html.request.set_var("mode", newmode) # will be used by makeuri # Check general permissions for the new mode if mode_permissions is not None and not config.user.may( "wato.seeall"): for pname in mode_permissions: if '.' not in pname: pname = "wato." + pname config.user.need_permission(pname) except MKUserError as e: action_message = "%s" % e html.add_user_error(e.varname, action_message) except MKAuthException as e: reason = e.args[0] action_message = reason html.add_user_error(None, reason) breadcrumb = make_main_menu_breadcrumb( mode.main_menu()) + mode.breadcrumb() page_menu = mode.page_menu(breadcrumb) wato_html_head(title=mode.title(), breadcrumb=breadcrumb, page_menu=page_menu, show_body_start=display_options.enabled(display_options.H), show_top_heading=display_options.enabled(display_options.T)) if not html.is_transaction() or (cmk.gui.watolib.read_only.is_enabled() and cmk.gui.watolib.read_only.may_override()): _show_read_only_warning() # Show outcome of action if html.has_user_errors(): html.show_user_errors() elif action_message: html.show_message(action_message) # Show content mode.handle_page() if is_sidebar_reload_needed(): html.reload_sidebar() if config.wato_use_git and html.is_transaction(): do_git_commit() wato_html_footer(show_footer=display_options.enabled(display_options.Z), show_body_end=display_options.enabled(display_options.H))
def page(self): watolib.init_wato_datastructures(with_wato_lock=True) if not config.user.may('wato.diag_host'): raise MKAuthException( _('You are not permitted to perform this action.')) if not html.check_transaction(): raise MKAuthException(_("Invalid transaction")) request = self.webapi_request() hostname = request.get("host") if not hostname: raise MKGeneralException(_('The hostname is missing.')) host = watolib.Host.host(hostname) if not host: raise MKGeneralException(_('The given host does not exist.')) if host.is_cluster(): raise MKGeneralException( _('This view does not support cluster hosts.')) host.need_permission("read") _test = request.get('_test') if not _test: raise MKGeneralException(_('The test is missing.')) # Execute a specific test if _test not in dict(ModeDiagHost.diag_host_tests()).keys(): raise MKGeneralException(_('Invalid test.')) # TODO: Use ModeDiagHost._vs_rules() for processing/validation? args = [u""] * 13 # type: List[Text] for idx, what in enumerate([ 'ipaddress', 'snmp_community', 'agent_port', 'snmp_timeout', 'snmp_retries', 'tcp_connect_timeout', ]): args[idx] = request.get(what, u"") if config.user.may('wato.add_or_modify_executables'): args[6] = request.get("datasource_program", "") if request.get("snmpv3_use"): snmpv3_use = { u"0": u"noAuthNoPriv", u"1": u"authNoPriv", u"2": u"authPriv", }.get(request.get("snmpv3_use", u""), u"") args[7] = snmpv3_use if snmpv3_use != u"noAuthNoPriv": snmpv3_auth_proto = { six.text_type(DropdownChoice.option_id("md5")): u"md5", six.text_type(DropdownChoice.option_id("sha")): u"sha" }.get(request.get("snmpv3_auth_proto", u""), u"") args[8] = snmpv3_auth_proto args[9] = request.get("snmpv3_security_name", u"") args[10] = request.get("snmpv3_security_password", u"") if snmpv3_use == "authPriv": snmpv3_privacy_proto = { six.text_type(DropdownChoice.option_id("DES")): u"DES", six.text_type(DropdownChoice.option_id("AES")): u"AES" }.get(request.get("snmpv3_privacy_proto", u""), u"") args[11] = snmpv3_privacy_proto args[12] = request.get("snmpv3_privacy_password", u"") else: args[9] = request.get("snmpv3_security_name", u"") result = watolib.check_mk_automation(host.site_id(), "diag-host", [hostname, _test] + args) return { "next_transid": html.transaction_manager.fresh_transid(), "status_code": result[0], "output": six.ensure_text(result[1], errors="replace"), }
def _show_page_user_profile(change_pw): start_async_replication = False if not config.user.id: raise MKUserError(None, _('Not logged in.')) if not config.user.may('general.edit_profile') and not config.user.may( 'general.change_password'): raise MKAuthException( _("You are not allowed to edit your user profile.")) if not config.wato_enabled: raise MKAuthException( _('User profiles can not be edited (WATO is disabled).')) success = None if html.request.has_var('_save') and html.check_transaction(): users = userdb.load_users(lock=True) try: # Profile edit (user options like language etc.) if config.user.may('general.edit_profile'): if not change_pw: set_lang = html.get_checkbox('_set_lang') language = html.request.var('language') # Set the users language if requested if set_lang: if language == '': language = None # Set custom language users[config.user.id]['language'] = language config.user.language = language html.set_language_cookie(language) else: # Remove the customized language if 'language' in users[config.user.id]: del users[config.user.id]['language'] config.user.reset_language() # load the new language cmk.gui.i18n.localize(config.user.language) user = users.get(config.user.id) if config.user.may('general.edit_notifications' ) and user.get("notifications_enabled"): value = forms.get_input( watolib.get_vs_flexible_notifications(), "notification_method") users[config.user.id]["notification_method"] = value # Custom attributes if config.user.may('general.edit_user_attributes'): for name, attr in userdb.get_user_attributes(): if attr.user_editable(): if not attr.permission() or config.user.may( attr.permission()): vs = attr.valuespec() value = vs.from_html_vars('ua_' + name) vs.validate_value(value, "ua_" + name) users[config.user.id][name] = value # Change the password if requested password_changed = False if config.user.may('general.change_password'): cur_password = html.request.var('cur_password') password = html.request.var('password') password2 = html.request.var('password2', '') if change_pw: # Force change pw mode if not cur_password: raise MKUserError( "cur_password", _("You need to provide your current password.")) if not password: raise MKUserError( "password", _("You need to change your password.")) if cur_password == password: raise MKUserError( "password", _("The new password must differ from your current one." )) if cur_password and password: if userdb.hook_login(config.user.id, cur_password) is False: raise MKUserError("cur_password", _("Your old password is wrong.")) if password2 and password != password2: raise MKUserError( "password2", _("The both new passwords do not match.")) watolib.verify_password_policy(password) users[config.user.id]['password'] = hash_password(password) users[config.user.id]['last_pw_change'] = int(time.time()) if change_pw: # Has been changed, remove enforcement flag del users[config.user.id]['enforce_pw_change'] # Increase serial to invalidate old cookies if 'serial' not in users[config.user.id]: users[config.user.id]['serial'] = 1 else: users[config.user.id]['serial'] += 1 password_changed = True # Now, if in distributed environment where users can login to remote sites, # set the trigger for pushing the new auth information to the slave sites # asynchronous if config.user.authorized_login_sites(): start_async_replication = True userdb.save_users(users) if password_changed: # Set the new cookie to prevent logout for the current user login.set_auth_cookie(config.user.id) success = True except MKUserError as e: html.add_user_error(e.varname, e) else: users = userdb.load_users() watolib.init_wato_datastructures(with_wato_lock=True) # When in distributed setup, display the replication dialog instead of the normal # profile edit dialog after changing the password. if start_async_replication: user_profile_async_replication_page() return if change_pw: title = _("Change Password") else: title = _("Edit User Profile") html.header(title) # Rule based notifications: The user currently cannot simply call the according # WATO module due to WATO permission issues. So we cannot show this button # right now. if not change_pw: rulebased_notifications = watolib.load_configuration_settings().get( "enable_rulebased_notifications") if rulebased_notifications and config.user.may( 'general.edit_notifications'): html.begin_context_buttons() url = "wato.py?mode=user_notifications_p" html.context_button(_("Notifications"), url, "notifications") html.end_context_buttons() else: reason = html.request.var('reason') if reason == 'expired': html.p( _('Your password is too old, you need to choose a new password.' )) else: html.p( _('You are required to change your password before proceeding.' )) if success: html.reload_sidebar() if change_pw: html.show_message(_("Your password has been changed.")) raise HTTPRedirect(html.request.var('_origtarget', 'index.py')) else: html.show_message(_("Successfully updated user profile.")) # Ensure theme changes are applied without additional user interaction html.immediate_browser_redirect(0.5, html.makeuri([])) if html.has_user_errors(): html.show_user_errors() user = users.get(config.user.id) if user is None: html.show_warning(_("Sorry, your user account does not exist.")) html.footer() return # Returns true if an attribute is locked and should be read only. Is only # checked when modifying an existing user locked_attributes = userdb.locked_attributes(user.get('connector')) def is_locked(attr): return attr in locked_attributes html.begin_form("profile", method="POST") html.prevent_password_auto_completion() html.open_div(class_="wato") forms.header(_("Personal Settings")) if not change_pw: forms.section(_("Name"), simple=True) html.write_text(user.get("alias", config.user.id)) if config.user.may( 'general.change_password') and not is_locked('password'): forms.section(_("Current Password")) html.password_input('cur_password', autocomplete="new-password") forms.section(_("New Password")) html.password_input('password', autocomplete="new-password") forms.section(_("New Password Confirmation")) html.password_input('password2', autocomplete="new-password") if not change_pw and config.user.may('general.edit_profile'): select_language(user) # Let the user configure how he wants to be notified if not rulebased_notifications \ and config.user.may('general.edit_notifications') \ and user.get("notifications_enabled"): forms.section(_("Notifications")) html.help( _("Here you can configure how you want to be notified about host and service problems and " "other monitoring events.")) watolib.get_vs_flexible_notifications().render_input( "notification_method", user.get("notification_method")) if config.user.may('general.edit_user_attributes'): for name, attr in userdb.get_user_attributes(): if attr.user_editable(): vs = attr.valuespec() forms.section(_u(vs.title())) value = user.get(name, vs.default_value()) if not attr.permission() or config.user.may( attr.permission()): vs.render_input("ua_" + name, value) html.help(_u(vs.help())) else: html.write(vs.value_to_text(value)) # Save button forms.end() html.button("_save", _("Save")) html.close_div() html.hidden_fields() html.end_form() html.footer()
def _wato_page_handler(current_mode: str, mode_permissions: Optional[List[PermissionName]], mode_class: Type[WatoMode]) -> None: try: init_wato_datastructures(with_wato_lock=not html.is_transaction()) except Exception: # Snapshot must work in any case if current_mode == 'snapshot': pass else: raise # Check general permission for this mode if mode_permissions is not None and not config.user.may("wato.seeall"): _ensure_mode_permissions(mode_permissions) mode = mode_class() # Do actions (might switch mode) if html.is_transaction(): try: config.user.need_permission("wato.edit") # Even if the user has seen this mode because auf "seeall", # he needs an explicit access permission for doing changes: if config.user.may("wato.seeall"): if mode_permissions: _ensure_mode_permissions(mode_permissions) if cmk.gui.watolib.read_only.is_enabled( ) and not cmk.gui.watolib.read_only.may_override(): raise MKUserError(None, cmk.gui.watolib.read_only.message()) result = mode.action() if isinstance(result, (tuple, str, bool)): raise MKGeneralException( f"WatoMode \"{current_mode}\" returns unsupported return value: {result!r}" ) # We assume something has been modified and increase the config generation ID by one. update_config_generation() if config.wato_use_git: do_git_commit() # Handle two cases: # a) Don't render the page content after action # (a confirm dialog is displayed by the action, or a non-HTML content was sent) # b) Redirect to another page if isinstance(result, FinalizeRequest): raise result except MKUserError as e: html.add_user_error(e.varname, str(e)) except MKAuthException as e: reason = e.args[0] html.add_user_error(None, reason) breadcrumb = make_main_menu_breadcrumb( mode.main_menu()) + mode.breadcrumb() page_menu = mode.page_menu(breadcrumb) wato_html_head(title=mode.title(), breadcrumb=breadcrumb, page_menu=page_menu, show_body_start=display_options.enabled(display_options.H), show_top_heading=display_options.enabled(display_options.T)) if not html.is_transaction() or (cmk.gui.watolib.read_only.is_enabled() and cmk.gui.watolib.read_only.may_override()): _show_read_only_warning() # Show outcome of failed action on this page if html.has_user_errors(): html.show_user_errors() # Show outcome of previous page (that redirected to this one) for message in get_flashed_messages(): html.show_message(message) # Show content mode.handle_page() if is_sidebar_reload_needed(): html.reload_whole_page() wato_html_footer(show_body_end=display_options.enabled(display_options.H))
#!/usr/bin/env python3 # -*- coding: utf-8 -*- # Copyright (C) 2021 tribe29 GmbH - License: GNU General Public License v2 # This file is part of Checkmk (https://checkmk.com). It is subject to the terms and # conditions defined in the file COPYING, which is part of this source code package. """Initialize the Checkmk default configuration in case it is necessary. """ # pylint: disable=cmk-module-layer-violation from cmk.gui import watolib from cmk.gui import main_modules from cmk.gui.utils.script_helpers import gui_context if __name__ == "__main__": main_modules.load_plugins() with gui_context(): watolib.init_wato_datastructures()
def execute_network_scan_job() -> None: init_wato_datastructures(with_wato_lock=True) if watolib.is_wato_slave_site(): return # Don't execute this job on slaves. folder = find_folder_to_scan() if not folder: return # Nothing to do. # We need to have the context of the user. The jobs are executed when # config.set_user_by_id() has not been executed yet. So there is no user context # available. Use the run_as attribute from the job config and revert # the previous state after completion. old_user = config.user.id run_as = folder.attribute("network_scan")["run_as"] if not userdb.user_exists(run_as): raise MKGeneralException( _("The user %s used by the network " "scan of the folder %s does not exist.") % (run_as, folder.title())) config.set_user_by_id(folder.attribute("network_scan")["run_as"]) result: NetworkScanResult = { "start": time.time(), "end": True, # means currently running "state": None, "output": "The scan is currently running.", } # Mark the scan in progress: Is important in case the request takes longer than # the interval of the cron job (1 minute). Otherwise the scan might be started # a second time before the first one finished. save_network_scan_result(folder, result) try: if config.site_is_local(folder.site_id()): found = cmk.gui.watolib.network_scan.do_network_scan(folder) else: found = watolib.do_remote_automation(config.site(folder.site_id()), "network-scan", [("folder", folder.path())]) if not isinstance(found, list): raise MKGeneralException(_("Received an invalid network scan result: %r") % found) add_scanned_hosts_to_folder(folder, found) result.update({ "state": True, "output": _("The network scan found %d new hosts.") % len(found), }) except Exception as e: result.update({ "state": False, "output": _("An exception occured: %s") % e, }) logger.error("Exception in network scan:\n%s", traceback.format_exc()) result["end"] = time.time() save_network_scan_result(folder, result) if old_user: config.set_user_by_id(old_user)
def execute_network_scan_job() -> None: """Executed by the multisite cron job once a minute. Is only executed in the central site. Finds the next folder to scan and starts it via WATO automation. The result is written to the folder in the master site.""" init_wato_datastructures(with_wato_lock=True) if is_wato_slave_site(): return # Don't execute this job on slaves. folder = _find_folder_to_scan() if not folder: return # Nothing to do. run_as = folder.attribute("network_scan")["run_as"] if not userdb.user_exists(run_as): raise MKGeneralException( _("The user %s used by the network " "scan of the folder %s does not exist.") % (run_as, folder.title())) with UserContext(run_as): result: NetworkScanResult = { "start": time.time(), "end": True, # means currently running "state": None, "output": "The scan is currently running.", } # Mark the scan in progress: Is important in case the request takes longer than # the interval of the cron job (1 minute). Otherwise the scan might be started # a second time before the first one finished. _save_network_scan_result(folder, result) try: if site_is_local(folder.site_id()): found = _do_network_scan(folder) else: found = do_remote_automation(get_site_config(folder.site_id()), "network-scan", [("folder", folder.path())]) if not isinstance(found, list): raise MKGeneralException( _("Received an invalid network scan result: %r") % found) _add_scanned_hosts_to_folder(folder, found) result.update({ "state": True, "output": _("The network scan found %d new hosts.") % len(found), }) except Exception as e: result.update({ "state": False, "output": _("An exception occured: %s") % e, }) logger.error("Exception in network scan:\n%s", traceback.format_exc()) result["end"] = time.time() _save_network_scan_result(folder, result)