def _retrieve_group( ident: str, groups: GroupSpecs, status: int, message: Optional[str], ) -> GroupSpec: try: group = groups[ident].copy() except KeyError as exc: if message is None: message = str(exc) raise ProblemException(status, http.client.responses[status], message) return group
def require_etag(etag: ETags) -> None: """Ensure the current request matches the given ETag. Args: etag: An Werkzeug ETag instance to compare the global request instance to. Raises: ProblemException: When If-Match missing or ETag doesn't match. """ etags_required = config.rest_api_etag_locking if not request.if_match: if not etags_required: return raise ProblemException( HTTPStatus.PRECONDITION_REQUIRED, "Precondition required", "If-Match header required for this operation. See documentation.") if request.if_match.as_set() != etag.as_set(): raise ProblemException( HTTPStatus.PRECONDITION_FAILED, "Precondition failed", "ETag didn't match. Probable cause: Object changed by another user.", )
def show_activation(params): """Show the activation status""" activation_id = params["activation_id"] manager = watolib.ActivateChangesManager() manager.load() try: manager.load_activation(activation_id) except MKUserError: raise ProblemException( status=404, title=f"Activation {activation_id!r} not found.", ) return _serve_activation_run(activation_id, is_running=manager.is_running())
def require_etag(etag: ETags) -> None: """Ensure the current request matches the given ETag. Args: etag: An Werkzeug ETag instance to compare the global request instance to. Raises: ProblemException: When ETag doesn't match. """ if request.if_match.as_set() != etag.as_set(): raise ProblemException( 412, "Precondition failed", "ETag didn't match. Probable cause: Object changed by another user.", )
def _verify_groups_exist(group_type: str, entries: List[Dict[str, Any]]): specific_existing_groups = load_group_information()[group_type] missing_groups = [] for details in entries: name = details['name'] if name not in specific_existing_groups: missing_groups.append(name) if missing_groups: raise ProblemException( status=400, title=f"Some {group_type} groups do not exist", detail= f"The following {group_type} groups do not exist: {', '.join(missing_groups)}" )
def create(params): """Create a folder""" put_body = params['body'] name = put_body['name'] title = put_body['title'] parent_folder = put_body['parent'] attributes = put_body.get('attributes', {}) if parent_folder.has_subfolder(name): raise ProblemException( status=400, title="Path already exists", detail=f"The path '{parent_folder.name()}/{name}' already exists.") folder = parent_folder.create_subfolder(name, title, attributes) return _serve_folder(folder)
def etag_of_obj(obj): """Build an ETag from an objects last updated time. Args: obj: An object with a `updated_at` method. Returns: The value which the method returns, else raises a `ProblemException`. """ updated_at = obj.updated_at() assert updated_at is not None if updated_at is None: raise ProblemException(500, "Object %r has no meta_data." % (obj.name(),), "Can't create ETag.") return ETags(strong_etags=[str(updated_at)])
def show_ruleset(param): """Show a ruleset""" ruleset_name = param["ruleset_name"] user.need_permission("wato.rulesets") collection = SingleRulesetRecursively(ruleset_name) try: collection.load() ruleset = collection.get(ruleset_name) except KeyError: raise ProblemException( title="Unknown ruleset.", detail=f"The ruleset of name {ruleset_name!r} is not known.", status=404, ) return serve_json(_serialize_ruleset(ruleset))
def show_time_period(params): """Show a time period""" 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] time_period_readable: Dict[str, Any] = {key: time_period[key] for key in ("alias", "exclude")} active_time_ranges = _active_time_ranges_readable( {key: time_period[key] for key in defines.weekday_ids()}) time_period_readable["active_time_ranges"] = active_time_ranges time_period_readable["exceptions"] = _exceptions_readable({ key: time_period[key] for key in time_period if key not in ['alias', 'exclude', *defines.weekday_ids()] }) return _serve_time_period(time_period_readable)
def create(params): """Create a folder""" put_body = params["body"] name = put_body["name"] title = put_body["title"] parent_folder = put_body["parent"] attributes = put_body.get("attributes", {}) if parent_folder.has_subfolder(name): raise ProblemException( status=400, title="Path already exists", detail=f"The path '{parent_folder.name()}/{name}' already exists.", ) folder = parent_folder.create_subfolder(name, title, attributes) return _serve_folder(folder)
def move(params): """Move a folder""" folder: watolib.CREFolder = params["folder"] folder_id = folder.id() constructors.require_etag(etag_of_folder(folder)) dest_folder: watolib.CREFolder = params["body"]["destination"] try: folder.parent().move_subfolder_to(folder, dest_folder) except MKUserError as exc: raise ProblemException( title="Problem moving folder.", detail=exc.message, status=400, ) folder = fields.FolderField.load_folder(folder_id) return _serve_folder(folder)
def load_groups(group_type: str, entries: List[Dict[str, Any]]) -> Dict[str, Optional[str]]: specific_existing_groups = load_group_information()[group_type] group_details = {} already_existing = [] for details in entries: name = details['name'] if name in specific_existing_groups: already_existing.append(name) continue group_details[name] = details.get('alias') if already_existing: raise ProblemException( status=400, title=f"Some {group_type} groups already exist", detail= f"The following {group_type} group names already exist: {', '.join(already_existing)}", ) return group_details
def activate_changes_wait_for_completion(params): """Wait for activation completion This endpoint will periodically redirect on itself to prevent timeouts. """ activation_id = params['activation_id'] manager = watolib.ActivateChangesManager() manager.load() try: manager.load_activation(activation_id) except MKUserError: raise ProblemException( status=404, title=f"Activation {activation_id!r} not found.") done = manager.wait_for_completion(timeout=request.request_timeout - 10) if not done: response = Response(status=302) response.location = request.url return response return Response(status=204)
def prepare_groups(group_type: GroupType, entries: List[Dict[str, Any]]) -> GroupSpecs: specific_existing_groups = load_group_information()[group_type] groups: GroupSpecs = {} already_existing = [] for details in entries: name = details["name"] if name in specific_existing_groups: already_existing.append(name) continue group_details: GroupSpec = {"alias": details["alias"]} if version.is_managed_edition(): group_details = update_customer_info(group_details, details["customer"]) groups[name] = group_details if already_existing: raise ProblemException( status=400, title=f"Some {group_type} groups already exist", detail=f"The following {group_type} group names already exist: {', '.join(already_existing)}", ) return groups
def _get_rule_by_id(rule_uuid: str, all_rulesets=None) -> RuleEntry: if all_rulesets is None: all_rulesets = AllRulesets() all_rulesets.load() for ruleset in all_rulesets.get_rulesets().values(): folder: CREFolder index: int rule: Rule for folder, index, rule in ruleset.get_rules(): if rule.id == rule_uuid: return RuleEntry( index_nr=index, rule=rule, folder=folder, ruleset=ruleset, all_rulesets=all_rulesets, ) raise ProblemException( status=400, title="Unknown rule.", detail=f"Rule with UUID {rule_uuid} was not found.", )
def set_acknowledgement_on_hosts(params): """Set acknowledgement on related hosts""" body = params['body'] live = sites.live() sticky = body['sticky'] notify = body['notify'] persistent = body['persistent'] comment = body['comment'] acknowledge_type = body['acknowledge_type'] if acknowledge_type == 'host': name = body['host_name'] host_state = Query([Hosts.state], Hosts.name == name).value(live) if not host_state: raise ProblemException( status=422, title=f'Host {name!r} has no problem.', ) acknowledge_host_problem( live, name, sticky=sticky, notify=notify, persistent=persistent, user=config.user.ident, comment=comment, ) elif acknowledge_type == 'hostgroup': host_group = body['hostgroup_name'] try: acknowledge_hostgroup_problem( live, host_group, sticky=sticky, notify=notify, persistent=persistent, user=config.user.ident, comment=comment, ) except ValueError: raise ProblemException( 404, title="Hostgroup could not be found.", detail=f"Unknown hostgroup: {host_group}", ) elif acknowledge_type == 'host_by_query': query = body['query'] hosts = Query([Hosts.name], query).fetchall(live) if not hosts: raise ProblemException( status=422, title="The provided query returned no monitored hosts", ) for host in hosts: acknowledge_host_problem( live, host.name, sticky=sticky, notify=notify, persistent=persistent, user=config.user.ident, comment=comment, ) else: raise ProblemException( status=400, title="Unhandled acknowledge-type.", detail= f"The acknowledge-type {acknowledge_type!r} is not supported.", ) return http.Response(status=204)
def set_acknowledgement_on_services(params): """Set acknowledgement on related services""" body = params['body'] live = sites.live() sticky = body['sticky'] notify = body['notify'] persistent = body['persistent'] comment = body['comment'] acknowledge_type = body['acknowledge_type'] if acknowledge_type == 'service': description = unquote(body['service_description']) host_name = body['host_name'] service = Query( [Services.host_name, Services.description, Services.state], And(Services.host_name == host_name, Services.description == description)).first(live) if not service: raise ProblemException( status=404, title= f'Service {description!r}@{host_name!r} could not be found.', ) if not service.state: raise ProblemException( status=422, title=f'Service {description!r}@{host_name!r} has no problem.', ) acknowledge_service_problem( live, service.host_name, service.description, sticky=sticky, notify=notify, persistent=persistent, user=config.user.ident, comment=comment, ) elif acknowledge_type == 'servicegroup': service_group = body['servicegroup_name'] try: acknowledge_servicegroup_problem( live, service_group, sticky=sticky, notify=notify, persistent=persistent, user=config.user.ident, comment=comment, ) except ValueError: raise ProblemException( status=404, title="Servicegroup could not be found.", detail=f"Unknown servicegroup: {service_group}", ) elif acknowledge_type == 'service_by_query': services = Query( [Services.host_name, Services.description, Services.state], body['query'], ).fetchall(live) if not services: raise ProblemException( status=422, title='No services with problems found.', detail='All queried services are OK.', ) for service in services: if not service.state: continue acknowledge_service_problem( live, service.host_name, service.description, sticky=sticky, notify=notify, persistent=persistent, user=config.user.ident, comment=comment, ) else: raise ProblemException( status=400, title="Unhandled acknowledge-type.", detail= f"The acknowledge-type {acknowledge_type!r} is not supported.", ) return http.Response(status=204)
def set_acknowledgement_on_services(params): """Set acknowledgement on related services""" body = params["body"] live = sites.live() sticky = body["sticky"] notify = body["notify"] persistent = body["persistent"] comment = body["comment"] acknowledge_type = body["acknowledge_type"] if acknowledge_type == "service": description = unquote(body["service_description"]) host_name = body["host_name"] service = Query( [Services.host_name, Services.description, Services.state], And(Services.host_name == host_name, Services.description == description), ).first(live) if not service: raise ProblemException( status=400, title= f"Service {description!r}@{host_name!r} could not be found.", ) if not service.state: raise ProblemException( status=422, title=f"Service {description!r}@{host_name!r} has no problem.", ) acknowledge_service_problem( live, service.host_name, service.description, sticky=sticky, notify=notify, persistent=persistent, user=user.ident, comment=comment, ) elif acknowledge_type == "servicegroup": service_group = body["servicegroup_name"] try: acknowledge_servicegroup_problem( live, service_group, sticky=sticky, notify=notify, persistent=persistent, user=user.ident, comment=comment, ) except ValueError: raise ProblemException( status=400, title="Service group could not be found.", detail=f"Unknown service group: {service_group}", ) elif acknowledge_type == "service_by_query": services = Query( [Services.host_name, Services.description, Services.state], body["query"], ).fetchall(live) if not services: raise ProblemException( status=422, title="No services with problems found.", detail="All queried services are OK.", ) for service in services: if not service.state: continue acknowledge_service_problem( live, service.host_name, service.description, sticky=sticky, notify=notify, persistent=persistent, user=user.ident, comment=comment, ) else: raise ProblemException( status=400, title="Unhandled acknowledge-type.", detail= f"The acknowledge-type {acknowledge_type!r} is not supported.", ) return http.Response(status=204)
def _bailout_with_message(message): raise ProblemException(404, http.client.responses[404], message)