Ejemplo n.º 1
0
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,
    )
Ejemplo n.º 2
0
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,
    )
Ejemplo n.º 3
0
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,
    )
Ejemplo n.º 4
0
    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)
Ejemplo n.º 5
0
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()
Ejemplo n.º 6
0
                 ],
                 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)
Ejemplo n.º 7
0
                 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)
Ejemplo n.º 8
0
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]),
Ejemplo n.º 9
0
        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'])
Ejemplo n.º 10
0
            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 = []
Ejemplo n.º 11
0
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()
Ejemplo n.º 12
0
    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)
Ejemplo n.º 13
0
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:
Ejemplo n.º 14
0
        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)
Ejemplo n.º 15
0
    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 = []
Ejemplo n.º 16
0
    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"""
Ejemplo n.º 17
0
    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')
Ejemplo n.º 18
0
            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":