def acknowledge_werks(werks, check_permission=True): if check_permission: user.need_permission("general.acknowledge_werks") ack_ids = load_acknowledgements() for werk in werks: ack_ids.append(werk["id"]) werk["compatible"] = "incomp_ack" save_acknowledgements(ack_ids)
def load_tag_config() -> TagConfig: """Load the tag config object based upon the most recently saved tag config file""" # This sometimes gets called on import-time where we don't have a request-context yet, so we # have to omit on checking the permissions there. if user: user.need_permission("wato.hosttags") # see cmk.gui.wato.pages.tags tag_config = cmk.utils.tags.TagConfig.from_config( TagConfigFile().load_for_modification()) return tag_config
def list_groups(params): """Show all service groups""" user.need_permission("wato.groups") collection = [{ "id": k, "alias": v["alias"] } for k, v in load_service_group_information().items()] return constructors.serve_json( serialize_group_list("service_group_config", collection))
def _check_permissions(api_call: APICallDefinitionDict) -> None: if not user.get_attribute("automation_secret"): raise MKAuthException("The API is only available for automation users") if not active_config.wato_enabled: raise MKUserError(None, _("Setup is disabled on this site.")) for permission in ["wato.use", "wato.api_allowed"] + api_call.get( "required_permissions", []): user.need_permission(permission)
def update(params): """Update a contact group""" user.need_permission("wato.edit") name = params["name"] group = fetch_group(name, "contact") constructors.require_etag(constructors.etag_of_dict(group)) edit_group(name, "contact", updated_group_details(name, "contact", params["body"])) group = fetch_group(name, "contact") return serve_group(group, serialize_group("contact_group_config"))
def show_time_period(params): """Show a time period""" user.need_permission("wato.timeperiods") name = params["name"] time_periods = load_timeperiods() if name not in time_periods: raise ProblemException(404, http.client.responses[404], f"Time period {name} not found") time_period = time_periods[name] return _serve_time_period(_to_api_format(time_period, name == "24X7"))
def page(self): user.need_permission("wato.services") job_status_snapshot = self._job.get_status_snapshot() if job_status_snapshot.is_active(): html.show_message( _('Bulk discovery currently running in <a href="%s">background</a>.' ) % self._job.detail_url()) return self._show_start_form()
def create(params): """Create a contact group""" user.need_permission("wato.edit") body = params["body"] name = body["name"] group_details = {"alias": body.get("alias")} if version.is_managed_edition(): group_details = update_customer_info(group_details, body["customer"]) add_group(name, "contact", group_details) group = fetch_group(name, "contact") return serve_group(group, serialize_group("contact_group_config"))
def list_users(params): """Show all users""" user.need_permission("wato.users") users = [] for user_id, attrs in userdb.load_users(False).items(): user_attributes = _internal_to_api_format(attrs) users.append( serialize_user(user_id, complement_customer(user_attributes))) return constructors.serve_json( constructors.collection_object(domain_type="user_config", value=users))
def bulk_update(params): """Bulk update folders Please be aware that when doing bulk updates, it is not possible to prevent the [Updating Values]("lost update problem"), which is normally prevented by the ETag locking mechanism. Use at your own risk """ user.need_permission("wato.edit") user.need_permission("wato.edit_folders") body = params["body"] entries = body["entries"] folders = [] faulty_folders = [] for update_details in entries: folder = update_details["folder"] current_title = folder.title() title = update_details.get("title", current_title) replace_attributes = update_details["attributes"] update_attributes = update_details["update_attributes"] remove_attributes = update_details["remove_attributes"] attributes = folder.attributes().copy() if replace_attributes: attributes = replace_attributes if update_attributes: attributes.update(update_attributes) faulty_attempt = False for attribute in remove_attributes: try: attributes.pop(attribute) except KeyError: faulty_attempt = True break if faulty_attempt: faulty_folders.append(current_title) continue folder.edit(title, attributes) folders.append(folder) if faulty_folders: return problem( status=400, title="Some folders were not updated", detail= f"The following folders were not updated since some of the provided remove attributes did not exist: {', '.join(faulty_folders)}", ) return constructors.serve_json(_folders_collection(folders, False))
def show_user(params): """Show a user""" user.need_permission("wato.users") username = params["username"] try: return serve_user(username) except KeyError: return problem( 404, f"User '{username}' is not known.", "The user you asked for is not known. Please check for eventual misspellings.", )
def delete(params): """Delete a time period""" user.need_permission("wato.edit") user.need_permission("wato.timeperiods") name = params["name"] time_periods = load_timeperiods() if name not in time_periods: raise ProblemException(404, http.client.responses[404], f"Time period {name} not found") del time_periods[name] save_timeperiods(time_periods) return Response(status=204)
def page(self): user.need_permission("general.see_crash_reports") filename = "Checkmk_Crash_%s_%s_%s.tar.gz" % ( urlencode(self._site_id), urlencode(self._crash_id), time.strftime("%Y-%m-%d_%H-%M-%S"), ) response.headers["Content-Disposition"] = "Attachment; filename=%s" % filename response.headers["Content-Type"] = "application/x-tar" response.set_data(_pack_crash_report(self._get_serialized_crash_report()))
def get_bi_rule(params): """Show a BI rule""" user.need_permission("wato.bi_rules") bi_packs = get_cached_bi_packs() bi_packs.load_config() try: bi_rule = bi_packs.get_rule_mandatory(params["rule_id"]) except MKGeneralException: _bailout_with_message("Unknown bi_rule: %s" % params["rule_id"]) data = {"pack_id": bi_rule.pack_id} data.update(BIRuleSchema().dump(bi_rule)) return constructors.serve_json(data)
def create_host(params): """Create a host""" user.need_permission("wato.edit") body = params["body"] host_name = body["host_name"] folder: CREFolder = body["folder"] # is_cluster is defined as "cluster_hosts is not None" folder.create_hosts([(host_name, body["attributes"], None)], bake_hosts=params[BAKE_AGENT_PARAM_NAME]) host = Host.load_host(host_name) return _serve_host(host, False)
def update_tag_config(tag_config: TagConfig): """Persist the tag config saving the information to the mk file and update the current environment Args: tag_config: The tag config object to persist """ if user: user.need_permission("wato.hosttags") TagConfigFile().save(tag_config.get_dict_format()) _update_tag_dependencies()
def get_bi_aggregation(params): """Get a BI aggregation""" user.need_permission("wato.bi_rules") bi_packs = get_cached_bi_packs() bi_packs.load_config() try: bi_aggregation = bi_packs.get_aggregation_mandatory(params["aggregation_id"]) except MKGeneralException: _bailout_with_message("Unknown bi_aggregation: %s" % params["aggregation_id"]) data = {"pack_id": bi_aggregation.pack_id} data.update(BIAggregationSchema().dump(bi_aggregation)) return constructors.serve_json(data)
def bulk_update(params): """Bulk update service groups Please be aware that when doing bulk updates, it is not possible to prevent the [Updating Values]("lost update problem"), which is normally prevented by the ETag locking mechanism. Use at your own risk. """ user.need_permission("wato.edit") body = params["body"] entries = body["entries"] updated_service_groups = update_groups("service", entries) return constructors.serve_json( serialize_group_list("service_group_config", updated_service_groups))
def check_modify_group_permissions(group_type: GroupType) -> None: required_permissions = { "contact": ["wato.users"], "host": ["wato.groups"], "service": ["wato.groups"], } # Check permissions perms = required_permissions.get(group_type) if perms is None: raise Exception("invalid group type %r" % (group_type, )) for permission in perms: user.need_permission(permission)
def page(self): check_csrf_token() user.need_permission("wato.activate") api_request = self.webapi_request() # ? type of activate_until is unclear activate_until = api_request.get("activate_until") if not activate_until: raise MKUserError("activate_until", _('Missing parameter "%s".') % "activate_until") manager = activate_changes.ActivateChangesManager() manager.load() # ? type of api_request is unclear affected_sites_request = ensure_str( # pylint: disable= six-ensure-str-bin-call api_request.get("sites", "").strip()) if not affected_sites_request: affected_sites = manager.dirty_and_active_activation_sites() else: affected_sites = [ SiteId(s) for s in 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), # pylint: disable= six-ensure-str-bin-call comment=comment, activate_foreign=activate_foreign, ) return { "activation_id": activation_id, }
def create_timeperiod(params): """Create a time period""" user.need_permission("wato.edit") user.need_permission("wato.timeperiods") body = params["body"] name = body["name"] exceptions = _format_exceptions(body.get("exceptions", [])) periods = _daily_time_ranges(body["active_time_ranges"]) time_period = _to_checkmk_format(alias=body["alias"], periods=periods, exceptions=exceptions, exclude=body.get("exclude", [])) save_timeperiod(name, time_period) return _serve_time_period(_to_api_format(load_timeperiod(name)))
def delete_password(params): """Delete a password""" user.need_permission("wato.edit") user.need_permission("wato.passwords") ident = params["name"] if ident not in load_passwords(): return problem( status=404, title='Password "{ident}" is not known.', detail= "The password you asked for is not known. Please check for eventual misspellings.", ) remove_password(ident) return Response(status=204)
def bulk_delete(params): """Bulk delete service groups""" user.need_permission("wato.edit") body = params["body"] entries = body["entries"] for group_name in entries: _group = fetch_group(group_name, "service", status=400, message="service group %s was not found" % group_name) for group_name in entries: groups.delete_group(group_name, group_type="service") return Response(status=204)
def show_password(params): """Show a password""" user.need_permission("wato.passwords") ident = params["name"] passwords = load_passwords() if ident not in passwords: return problem( status=404, title=f'Password "{ident}" is not known.', detail= "The password you asked for is not known. Please check for eventual misspellings.", ) password_details = passwords[ident] return _serve_password(ident, password_details)
def action(self) -> ActionResult: folder = Folder.current() if not transactions.check_transaction(): return redirect(mode_url("folder", folder=folder.path())) if request.var("_update_dns_cache") and self._should_use_dns_cache(): user.need_permission("wato.update_dns_cache") update_dns_cache_result = update_dns_cache(self._host.site_id()) infotext = (_("Successfully updated IP addresses of %d hosts.") % update_dns_cache_result.n_updated) if update_dns_cache_result.failed_hosts: infotext += "<br><br><b>Hostnames failed to lookup:</b> " + ", ".join( [ "<tt>%s</tt>" % h for h in update_dns_cache_result.failed_hosts ]) flash(infotext) return None if request.var("delete"): # Delete this host folder.delete_hosts([self._host.name()], automation=delete_hosts) return redirect(mode_url("folder", folder=folder.path())) if request.var("_remove_tls_registration"): remove_tls_registration( {self._host.site_id(): [self._host.name()]}) return None attributes = collect_attributes( "host" if not self._is_cluster() else "cluster", new=False) host = Host.host(self._host.name()) if host is None: flash(f"Host {self._host.name()} could not be found.") return None host.edit(attributes, self._get_cluster_nodes()) self._host = folder.load_host(self._host.name()) if request.var("_save"): return redirect( mode_url("inventory", folder=folder.path(), host=self._host.name())) if request.var("diag_host"): return redirect( mode_url("diag_host", folder=folder.path(), host=self._host.name(), _start_on_load="1")) return redirect(mode_url("folder", folder=folder.path()))
def add_service_comment( connection, host_name: str, service_description: str, comment: str, persistent: bool = False, user: str = "", ): """Add service comment Args: connection: A livestatus connection object host_name: The host-name where the service is located service_description: The service description for which the comment is for comment: The comment which will be stored for the service persistent: If set, the comment will persist across program restarts until it is deleted manually. If not set, the comment will be deleted the next time the Core is restarted. user: Examples: >>> from cmk.gui.livestatus_utils.testing import simple_expect >>> from cmk.gui.utils.script_helpers import application_and_request_context >>> from cmk.gui.logged_in import SuperUserContext >>> from cmk.gui.config import load_config >>> cmd = "COMMAND [...] ADD_SVC_COMMENT;example.com;CPU Load;0;;test" >>> expect = simple_expect(cmd, match_type="ellipsis") >>> with expect as live, application_and_request_context(), SuperUserContext(): ... load_config() ... add_service_comment(live, 'example.com', 'CPU Load', 'test') """ _user.need_permission("action.addcomment") return send_command( connection, "ADD_SVC_COMMENT", [host_name, service_description, int(persistent), user, comment], )
def page(self): user.need_permission("wato.activate") api_request = self.webapi_request() activation_id = api_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 _schedule_downtime( sites, command: LivestatusCommand, site_id, host_or_group: str, service_description: Optional[str], start_time: dt.datetime, end_time: dt.datetime, recur: RecurMode = "fixed", trigger_id: int = 0, duration: int = 0, user_id: str = "", comment: str = "", ): """Unified low level function See: * schedule_host_downtime * schedule_service_downtime """ # TODO: provide reference documents for recurring magic numbers _user.need_permission("action.downtimes") recur_mode = _recur_mode(recur, duration) if command == "SCHEDULE_HOST_DOWNTIME": params = [host_or_group] elif command == "SCHEDULE_SVC_DOWNTIME": if not service_description: raise ValueError("Service description necessary.") params = [host_or_group, service_description] else: raise ValueError(f"Unsupported command: {command}") return send_command( sites, command, [ *params, to_timestamp(start_time), to_timestamp(end_time), recur_mode, trigger_id, duration, user_id, comment.replace("\n", ""), ], site_id, )
def create_cluster_host(params): """Create a cluster host A cluster host groups many hosts (called nodes in this context) into a conceptual cluster. All the services of the individual nodes will be collated on the cluster host.""" user.need_permission("wato.edit") body = params["body"] host_name = body["host_name"] folder: CREFolder = body["folder"] folder.create_hosts([(host_name, body["attributes"], body["nodes"])], bake_hosts=params[BAKE_AGENT_PARAM_NAME]) host = Host.load_host(host_name) return _serve_host(host, effective_attributes=False)
def bulk_create(params): """Bulk create host groups""" user.need_permission("wato.edit") body = params["body"] entries = body["entries"] contact_group_details = prepare_groups("contact", entries) contact_group_names = [] for group_name, group_details in contact_group_details.items(): add_group(group_name, "contact", group_details) contact_group_names.append(group_name) contact_groups = fetch_specific_groups(contact_group_names, "contact") return constructors.serve_json( serialize_group_list("contact_group_config", contact_groups))