def _serialize_single_downtime(downtime): links = [] if downtime["is_service"]: downtime_detail = f"service: {downtime['service_description']}" else: host_name = downtime["host_name"] downtime_detail = f"host: {host_name}" links.append( constructors.link_rel( rel="cmk/host_config", href=constructors.object_href("host_config", host_name), title="This host of this downtime.", method="get", ) ) downtime_id = downtime["id"] return constructors.domain_object( domain_type="downtime", identifier=str(downtime_id), title="Downtime for %s" % downtime_detail, extensions=_downtime_properties(downtime), links=[ constructors.link_rel( rel=".../delete", href=constructors.domain_type_action_href("downtime", "delete"), method="post", title="Delete the downtime", body_params={"delete_type": "by_id", "downtime_id": downtime_id}, ), ], editable=False, deletable=False, )
def serialize_host(host: watolib.CREHost, effective_attributes: bool): extensions = { "folder": host.folder().path(), "attributes": host.attributes(), "effective_attributes": host.effective_attributes() if effective_attributes else None, "is_cluster": host.is_cluster(), "is_offline": host.is_offline(), "cluster_nodes": host.cluster_nodes(), } agent_links = [] if not cmk_version.is_raw_edition(): import cmk.gui.cee.agent_bakery as agent_bakery # pylint: disable=no-name-in-module for agent_type in sorted(agent_bakery.agent_package_types().keys()): agent_links.append( constructors.link_rel( rel="cmk/download", href="{}?{}".format( constructors.domain_type_action_href( "agent", "download"), urlencode({ "os_type": agent_type, "host_name": host.id() }), ), method="get", title=f"Download the {agent_type} agent of the host.", )) return constructors.domain_object( domain_type="host_config", identifier=host.id(), title=host.alias() or host.name(), links=[ constructors.link_rel( rel="cmk/folder_config", href=constructors.object_href("folder_config", folder_slug(host.folder())), method="get", title="The folder config of the host.", ), ] + agent_links, extensions=extensions, )
def _serialize_single_downtime(downtime): links = [] if downtime["is_service"]: downtime_detail = f"service: {downtime['service_description']}" else: host_name = downtime['host_name'] downtime_detail = f"host: {host_name}" links.append( constructors.link_rel( rel='cmk/host_config', href=constructors.object_href('host_config', host_name), title='This host of this downtime.', method='get', )) downtime_id = downtime['id'] return constructors.domain_object( domain_type='downtime', identifier=downtime_id, title='Downtime for %s' % downtime_detail, extensions=_downtime_properties(downtime), links=[ constructors.link_rel( rel='.../delete', href=constructors.domain_type_action_href( 'downtime', 'delete'), method='post', title='Delete the downtime', body_params={ 'delete_type': 'by_id', 'downtime_id': downtime_id }, ), ], editable=False, deletable=False, )
permissions_required=permissions.Perm("wato.groups"), ) def create(params): """Create a host group""" 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, "host", group_details) group = fetch_group(name, "host") return serve_group(group, serialize_group("host_group_config")) @Endpoint( constructors.domain_type_action_href("host_group_config", "bulk-create"), "cmk/bulk_create", method="post", request_schema=request_schemas.BulkInputHostGroup, response_schema=response_schemas.DomainObjectCollection, permissions_required=permissions.Perm("wato.groups"), ) def bulk_create(params): """Bulk create host groups""" body = params["body"] entries = body["entries"] host_group_details = prepare_groups("host", entries) host_group_names = [] for group_name, group_details in host_group_details.items(): add_group(group_name, "host", group_details)
OS_TYPES_AVAILABLE_IN_RAW = ["linux_rpm", "linux_deb", "windows_msi"] OS_TYPE_RAW = { "os_type": fields.String( description=("The type of the operating system. May be one of " + ", ".join(OS_TYPES_AVAILABLE_IN_RAW)), enum=sorted(OS_TYPES_AVAILABLE_IN_RAW), example="linux_deb", required=True, ), } @Endpoint( constructors.domain_type_action_href("agent", "download"), "cmk/download", method="get", content_type="application/octet-stream", query_params=[OS_TYPE_RAW], ) def download_agent(params): """Download agents shipped with Checkmk""" os_type: str = params.get("os_type") if os_type == "windows_msi": agent_path = agent.packed_agent_path_windows_msi() elif os_type == "linux_rpm": agent_path = agent.packed_agent_path_linux_rpm() elif os_type == "linux_deb": agent_path = agent.packed_agent_path_linux_deb()
], output_empty=True) def delete_downtime(params): """Delete a scheduled downtime""" is_service = Query( [Downtimes.is_service], Downtimes.id.contains(params['downtime_id']), ).value(sites.live()) downtime_type = "SVC" if is_service else "HOST" command_delete = remove_downtime_command(downtime_type, params['downtime_id']) execute_livestatus_command(command_delete, params['host_name']) return Response(status=204) @endpoint_schema(constructors.domain_type_action_href('downtime', 'bulk-delete'), '.../delete', method='delete', request_schema=request_schemas.BulkDeleteDowntime, output_empty=True) def bulk_delete_downtimes(params): """Bulk delete downtimes""" live = sites.live() entries = params['entries'] not_found = [] downtimes: Dict[int, int] = Query( [Downtimes.id, Downtimes.is_service], And(*[Downtimes.id.equals(downtime_id) for downtime_id in entries]), ).to_dict(live)
method='post', etag='output', request_body_required=True, request_schema=request_schemas.InputServiceGroup, response_schema=response_schemas.DomainObject) def create(params): """Create a service-group""" body = params['body'] name = body['name'] alias = body.get('alias') add_group(name, 'service', {'alias': alias}) group = fetch_group(name, "service") return serve_group(group, serialize_group('service_group_config')) @endpoint_schema(constructors.domain_type_action_href('service_group_config', 'bulk-create'), 'cmk/bulk_create', method='post', request_schema=request_schemas.BulkInputServiceGroup, response_schema=response_schemas.DomainObjectCollection) def bulk_create(params): """Bulk create service groups""" body = params['body'] entries = body['entries'] service_group_details = load_groups("service", entries) service_group_names = [] for group_name, group_alias in service_group_details.items(): add_group(group_name, 'service', {'alias': group_alias}) service_group_names.append(group_name)
def set_acknowledgement_on_hostgroup(params): """Acknowledge for hosts of a host group""" body = params['body'] acknowledge_hostgroup_problem( sites.live(), params['hostgroup_name'], sticky=body['sticky'], notify=body['notify'], persistent=body['persistent'], user=config.user.ident, comment=body['comment'], ) return http.Response(status=204) @endpoint_schema(constructors.domain_type_action_href('host', 'bulk-acknowledge'), 'cmk/create', method='post', tag_group='Monitoring', request_schema=request_schemas.BulkAcknowledgeHostProblem, output_empty=True) def bulk_set_acknowledgement_on_hosts(params): """Bulk acknowledge for hosts""" live = sites.live() entries = params['entries'] hosts: Dict[str, int] = { host_name: host_state for host_name, host_state in Query( # pylint: disable=unnecessary-comprehension [Hosts.name, Hosts.state], And(*[Hosts.name.equals(host_name) for host_name in entries]),
return problem( status=404, title="The requested downtime was not found", detail=f"The downtime id {downtime_id} did not match any downtime", ) return _serve_downtime(downtime) def _serve_downtime(downtime_details): response = Response() response.set_data(json.dumps(_serialize_single_downtime(downtime_details))) response.set_content_type('application/json') return response @Endpoint(constructors.domain_type_action_href('downtime', 'delete'), '.../delete', method='post', tag_group='Monitoring', skip_locking=True, request_schema=request_schemas.DeleteDowntime, output_empty=True) def delete_downtime(params): """Delete a scheduled downtime""" body = params['body'] live = sites.live() delete_type = body['delete_type'] if delete_type == "query": downtime_commands.delete_downtime_with_query(live, body['query']) elif delete_type == "by_id": downtime_commands.delete_downtime(live, body['downtime_id'])
faulty_attributes.append(attribute) if faulty_attributes: return problem( status=400, title="The folder was not updated", detail=f"The following attributes did not exist and could therefore" f"not be removed: {', '.join(faulty_attributes)}") folder.edit(title, attributes) return _serve_folder(folder) @Endpoint( constructors.domain_type_action_href('folder_config', 'bulk-update'), 'cmk/bulk_update', method='put', response_schema=response_schemas.FolderCollection, request_schema=request_schemas.BulkUpdateFolder, ) 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 """ body = params['body'] entries = body['entries'] folders = []
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.""" body = params['body'] host_name = body['host_name'] body['folder'].create_hosts([(host_name, body['attributes'], body['nodes']) ]) host = watolib.Host.host(host_name) return _serve_host(host, False) @Endpoint(constructors.domain_type_action_href('host_config', 'bulk-create'), 'cmk/bulk_create', method='post', request_schema=request_schemas.BulkCreateHost, response_schema=response_schemas.DomainObjectCollection) def bulk_create_hosts(params): """Bulk create hosts""" body = params['body'] entries = body['entries'] failed_hosts = [] folder: watolib.CREFolder for folder, grouped_hosts in itertools.groupby( body['entries'], operator.itemgetter('folder')): validated_entries = [] folder.prepare_create_hosts()
aggregations = fields.Dict( description="The Aggregation state", example={}, ) missing_sites = fields.List( fields.String(), description="The missing sites", example=["beta", "heute"], ) missing_aggr = fields.List( fields.String(), description="the missing aggregations", example=["Host heute"] ) @Endpoint( constructors.domain_type_action_href("bi_aggregation", "aggregation_state"), "cmk/get_bi_aggregation_state", method="post", convert_response=False, request_schema=BIAggregationStateRequestSchema, response_schema=BIAggregationStateResponseSchema, permissions_required=RO_PERMISSIONS, ) def get_bi_aggregation_state(params): """Get the state of BI aggregations""" user.need_permission("wato.bi_rules") filter_config = params.get("body", {}) filter_names = filter_config.get("filter_names") filter_groups = filter_config.get("filter_groups") return constructors.serve_json( api_get_aggregation_state(filter_names=filter_names, filter_groups=filter_groups)
from cmk.gui.plugins.openapi.utils import ProblemException from cmk import fields ACTIVATION_ID = { "activation_id": fields.String( description="The activation-id.", example="d3b07384d113e0ec49eaa6238ad5ff00", required=True, ), } @Endpoint( constructors.domain_type_action_href("activation_run", "activate-changes"), "cmk/activate", method="post", status_descriptions={ 200: "The activation has been completed.", 302: ("The activation has been started and is still running. Redirecting to the " "'Wait for completion' endpoint."), 401: ("The API user may not activate another users changes, " "or the user may and activation was not forced explicitly."), 409: "Some sites could not be activated.", 422: "There are no changes to be activated.", 423:
required=False, description="The number of hosts to be handled at once.", example=False, load_default=10, ) ignore_errors = fields.Boolean( required=False, description= "The option whether to ignore errors in single check plugins.", example=False, load_default=True, ) @Endpoint( constructors.domain_type_action_href("discovery_run", "bulk-discovery-start"), "cmk/activate", method="post", status_descriptions={ 409: "A bulk discovery job is already active", }, additional_status_codes=[409], request_schema=BulkDiscovery, response_schema=response_schemas.DiscoveryBackgroundJobStatusObject, ) def execute_bulk_discovery(params) -> Response: """Start a bulk discovery job""" body = params["body"] job = BulkDiscoveryBackgroundJob() if job.is_active(): return Response(status=409)
if faulty_attributes: return problem( status=400, title="The folder was not updated", detail=f"The following attributes did not exist and could therefore" f"not be removed: {', '.join(faulty_attributes)}", ) folder.edit(title, attributes) return _serve_folder(folder) @Endpoint( constructors.domain_type_action_href("folder_config", "bulk-update"), "cmk/bulk_update", method="put", response_schema=response_schemas.FolderCollection, request_schema=request_schemas.BulkUpdateFolder, ) 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 """ body = params["body"] entries = body["entries"] folders = []
request_schemas, ) from cmk.gui.plugins.openapi.restful_objects.type_defs import LinkType from cmk.gui.plugins.openapi.utils import ProblemException ACTIVATION_ID = { 'activation_id': fields.String( description='The activation-id.', example='d3b07384d113e0ec49eaa6238ad5ff00', required=True, ), } @Endpoint(constructors.domain_type_action_href('activation_run', 'activate-changes'), 'cmk/activate', method='post', status_descriptions={ 200: "The activation has been completed.", 302: ("The activation is still running. Redirecting to the " "'Wait for completion' endpoint."), 422: "There are no changes to be activated.", }, additional_status_codes=[302, 422], request_schema=request_schemas.ActivateChanges, response_schema=response_schemas.DomainObject) def activate_changes(params): """Activate pending changes"""
if replace_attributes: attributes = replace_attributes if update_attributes: attributes.update(update_attributes) # FIXME # You can't update the attributes without updating the title, so the title is mandatory. # This shouldn't be the case though. folder.edit(title, attributes) return _serve_folder(folder) @endpoint_schema(constructors.domain_type_action_href('folder_config', 'bulk-update'), 'cmk/bulk_update', method='put', response_schema=response_schemas.FolderCollection, request_schema=request_schemas.BulkUpdateFolder) def bulk_update(params): """Bulk update folders""" body = params['body'] entries = body['entries'] folders = [] for update_details in entries: folder = update_details['folder'] title = update_details['title'] replace_attributes = update_details.get('attributes') update_attributes = update_details.get('update_attributes')
status=404, title="The requested downtime was not found", detail=f"The downtime id {downtime_id} did not match any downtime", ) return _serve_downtime(downtime) def _serve_downtime(downtime_details): response = Response() response.set_data(json.dumps(_serialize_single_downtime(downtime_details))) response.set_content_type("application/json") return response @Endpoint( constructors.domain_type_action_href("downtime", "delete"), ".../delete", method="post", tag_group="Monitoring", skip_locking=True, request_schema=request_schemas.DeleteDowntime, output_empty=True, ) def delete_downtime(params): """Delete a scheduled downtime""" body = params["body"] live = sites.live() delete_type = body["delete_type"] if delete_type == "query": downtime_commands.delete_downtime_with_query(live, body["query"]) elif delete_type == "by_id":