Пример #1
0
def move(params):
    """Move a host to another folder"""
    user.need_permission("wato.edit")
    user.need_permission("wato.move_hosts")
    host_name = params["host_name"]
    host: CREHost = Host.load_host(host_name)
    _require_host_etag(host)
    current_folder = host.folder()
    target_folder: CREFolder = params["body"]["target_folder"]
    if target_folder is current_folder:
        return problem(
            status=400,
            title="Invalid move action",
            detail="The host is already part of the specified target folder",
        )

    try:
        current_folder.move_hosts([host_name], target_folder)
    except MKUserError as exc:
        return problem(
            status=400,
            title="Problem moving host",
            detail=exc.message,
        )
    return _serve_host(host, effective_attributes=False)
Пример #2
0
def bulk_create_hosts(params):
    """Bulk create hosts"""
    user.need_permission("wato.edit")
    body = params["body"]
    entries = body["entries"]

    failed_hosts: Dict[HostName, str] = {}
    succeeded_hosts: List[HostName] = []
    folder: CREFolder
    for folder, grouped_hosts in itertools.groupby(
            entries, operator.itemgetter("folder")):
        validated_entries = []
        folder.prepare_create_hosts()
        for host in grouped_hosts:
            host_name = host["host_name"]
            attributes = host["attributes"]
            try:
                folder.verify_host_details(host_name, attributes)
                validated_entries.append((host_name, attributes, None))
            except (MKUserError, MKAuthException) as e:
                failed_hosts[host_name] = f"Validation failed: {e}"

        folder.create_validated_hosts(validated_entries, bake_hosts=False)
        succeeded_hosts.extend(entry[0] for entry in validated_entries)

    if params[BAKE_AGENT_PARAM_NAME]:
        bakery.try_bake_agents_for_hosts(succeeded_hosts)

    return _bulk_host_action_response(
        failed_hosts,
        [Host.load_host(host_name) for host_name in succeeded_hosts])
Пример #3
0
def bulk_delete(params):
    """Bulk delete hosts"""
    user.need_permission("wato.edit")
    body = params["body"]
    for host_name in body["entries"]:
        host = Host.load_host(host_name)
        host.folder().delete_hosts([host.name()], automation=delete_hosts)
    return Response(status=204)
Пример #4
0
def show_host(params) -> Response:
    """Show a host"""
    host = Host.load_host(params["host_name"])
    return constructors.serve_json(
        {
            "site": host.site_id(),
            "is_cluster": host.is_cluster(),
        }
    )
Пример #5
0
def delete(params):
    """Delete a host"""
    user.need_permission("wato.edit")
    host_name = params["host_name"]
    # Parameters can't be validated through marshmallow yet.
    check_hostname(host_name, should_exist=True)
    host: CREHost = Host.load_host(host_name)
    host.folder().delete_hosts([host.name()], automation=delete_hosts)
    return Response(status=204)
Пример #6
0
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)
Пример #7
0
def update_service_phase(params) -> Response:
    """Update the phase of a service"""
    body = params["body"]
    host = Host.load_host(params["host_name"])
    target_phase = body["target_phase"]
    check_type = body["check_type"]
    service_item = body["service_item"]
    _update_single_service_phase(
        SERVICE_DISCOVERY_PHASES[target_phase],
        host,
        check_type,
        service_item,
    )
    return Response(status=204)
Пример #8
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."""
    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)
Пример #9
0
def update_nodes(params):
    """Update the nodes of a cluster host"""
    user.need_permission("wato.edit")
    user.need_permission("wato.edit_hosts")
    host_name = params["host_name"]
    body = params["body"]
    nodes = body["nodes"]
    host: CREHost = Host.load_host(host_name)
    _require_host_etag(host)
    host.edit(host.attributes(), nodes)

    return constructors.serve_json(
        constructors.object_sub_property(
            domain_type="host_config",
            ident=host_name,
            name="nodes",
            value=host.cluster_nodes(),
        ))
Пример #10
0
    def _get_cluster_nodes(self):
        if not self._is_cluster():
            return None

        cluster_nodes = self._vs_cluster_nodes().from_html_vars("nodes")
        self._vs_cluster_nodes().validate_value(cluster_nodes, "nodes")
        if len(cluster_nodes) < 1:
            raise MKUserError("nodes_0",
                              _("The cluster must have at least one node"))

        # Fake a cluster host in order to get calculated tag groups via effective attributes...
        cluster_computed_datasources = cmk.utils.tags.compute_datasources(
            Host(
                Folder.current(),
                self._host.name(),
                collect_attributes("cluster", new=False),
                [],
            ).tag_groups())

        for nr, cluster_node in enumerate(cluster_nodes):
            if cluster_node == self._host.name():
                raise MKUserError(
                    "nodes_%d" % nr,
                    _("The cluster can not be a node of it's own"))

            if not Host.host_exists(cluster_node):
                raise MKUserError(
                    "nodes_%d" % nr,
                    _("The node <b>%s</b> does not exist "
                      " (must be a host that is configured with WATO)") %
                    cluster_node,
                )

            node_computed_datasources = cmk.utils.tags.compute_datasources(
                Host.load_host(cluster_node).tag_groups())

            if datasource_differences := cluster_computed_datasources.get_differences_to(
                    node_computed_datasources):
                raise MKUserError(
                    "nodes_%d" % nr,
                    _("Cluster and nodes must have the same datasource. ") +
                    self._format_datasource_differences(
                        cluster_node, datasource_differences),
                )
Пример #11
0
def bulk_update_hosts(params):
    """Bulk update hosts

    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_hosts")
    body = params["body"]
    entries = body["entries"]

    succeeded_hosts: List[CREHost] = []
    failed_hosts: Dict[HostName, str] = {}
    for update_detail in entries:
        host_name = update_detail["host_name"]
        new_attributes = update_detail["attributes"]
        update_attributes = update_detail["update_attributes"]
        remove_attributes = update_detail["remove_attributes"]
        check_hostname(host_name)
        host: CREHost = Host.load_host(host_name)
        if new_attributes:
            host.edit(new_attributes, None)

        if update_attributes:
            host.update_attributes(update_attributes)

        faulty_attributes = []
        for attribute in remove_attributes:
            if not host.has_explicit_attribute(attribute):
                faulty_attributes.append(attribute)

        if faulty_attributes:
            failed_hosts[
                host_name] = f"Failed to remove {', '.join(faulty_attributes)}"
            continue

        if remove_attributes:
            host.clean_attributes(remove_attributes)

        succeeded_hosts.append(host)

    return _bulk_host_action_response(failed_hosts, succeeded_hosts)
Пример #12
0
def show_services(params) -> Response:
    """Show all services of specific phase"""
    host = Host.load_host(params["host_name"])
    discovery_request = StartDiscoveryRequest(
        host=host,
        folder=host.folder(),
        options=DiscoveryOptions(
            action="",
            show_checkboxes=False,
            show_parameters=False,
            show_discovered_labels=False,
            show_plugin_names=False,
            ignore_errors=True,
        ),
    )
    discovery_result = get_check_table(discovery_request)
    return _serve_services(
        host,
        discovery_result.check_table,
        [params["discovery_phase"]],
    )
Пример #13
0
def execute(params) -> Response:
    """Execute a service discovery on a host"""
    host = Host.load_host(params["host_name"])
    body = params["body"]
    discovery_request = StartDiscoveryRequest(
        host=host,
        folder=host.folder(),
        options=DiscoveryOptions(
            action=DISCOVERY_ACTION[body["mode"]],
            show_checkboxes=False,
            show_parameters=False,
            show_discovered_labels=False,
            show_plugin_names=False,
            ignore_errors=True,
        ),
    )
    discovery_result = get_check_table(discovery_request)
    return _serve_services(
        host,
        discovery_result.check_table,
        list(SERVICE_DISCOVERY_PHASES.keys()),
    )
Пример #14
0
def update_host(params):
    """Update a host"""
    user.need_permission("wato.edit")
    user.need_permission("wato.edit_hosts")
    host_name = params["host_name"]
    body = params["body"]
    new_attributes = body["attributes"]
    update_attributes = body["update_attributes"]
    remove_attributes = body["remove_attributes"]
    check_hostname(host_name, should_exist=True)
    host: CREHost = Host.load_host(host_name)
    _require_host_etag(host)

    if new_attributes:
        new_attributes["meta_data"] = host.attributes().get("meta_data", {})
        host.edit(new_attributes, None)

    if update_attributes:
        host.update_attributes(update_attributes)

    faulty_attributes = []
    for attribute in remove_attributes:
        if not host.has_explicit_attribute(attribute):
            faulty_attributes.append(attribute)

    if remove_attributes:
        host.clean_attributes(
            remove_attributes)  # silently ignores missing attributes

    if faulty_attributes:
        return problem(
            status=400,
            title="Some attributes were not removed",
            detail=
            f"The following attributes were not removed since they didn't exist: {', '.join(faulty_attributes)}",
        )

    return _serve_host(host, effective_attributes=False)
Пример #15
0
def rename_host(params):
    """Rename a host"""
    user.need_permission("wato.edit")
    user.need_permission("wato.rename_hosts")
    if activate_changes.get_pending_changes_info():
        return problem(
            status=409,
            title="Pending changes are present",
            detail=
            "Please activate all pending changes before executing a host rename process",
        )
    host_name = params["host_name"]
    host: CREHost = Host.load_host(host_name)
    new_name = params["body"]["new_name"]
    _, auth_problems = perform_rename_hosts([(host.folder(), host_name,
                                              new_name)])
    if auth_problems:
        return problem(
            status=422,
            title="Rename process failed",
            detail=
            f"It was not possible to rename the host {host_name} to {new_name}",
        )
    return _serve_host(host, effective_attributes=False)
Пример #16
0
def show_host(params):
    """Show a host"""
    host_name = params["host_name"]
    host: CREHost = Host.load_host(host_name)
    return _serve_host(host,
                       effective_attributes=params["effective_attributes"])
Пример #17
0
def _check_host_editing_permissions(host_name: HostName) -> CREHost:
    host = Host.load_host(host_name)
    host.need_permission("write")
    return host