Exemplo n.º 1
0
    def _discover_services(self, request):
        mode = request.get("mode", "new")
        hostname = request.get("hostname")

        check_hostname(hostname, should_exist=True)

        host = watolib.Host.host(hostname)

        host_attributes = host.effective_attributes()

        if host.is_cluster():
            # This is currently the only way to get some actual discovery statitics.
            # Start a dry-run -> Get statistics
            # Do an actual discovery on the nodes -> data is written
            try_result = watolib.check_mk_automation(host_attributes.get("site"), "try-inventory",
                                                     ["@scan"] + [hostname])

            new = 0
            old = 0
            for entry in try_result["check_table"]:
                if entry[0] == "new":
                    new += 1
                elif entry[0] == "old":
                    old += 1

            result = DiscoveryResult(self_new=new, self_kept=old, self_total=new + old)
            watolib.check_mk_automation(host_attributes.get("site"), "inventory",
                                        ["@scan", mode] + host.cluster_nodes())
        else:
            response = execute_automation_discovery(site_id=host_attributes.get("site"),
                                                    args=["@scan", mode, hostname])
            result = response.results[hostname]

        if result.error_text:
            if not host.discovery_failed():
                host.set_discovery_failed()
            raise MKUserError(None, _("Failed to discover %s: %s") % (hostname, result.error_text))

        if host.discovery_failed():
            host.clear_discovery_failed()

        if mode == "refresh":
            message = _("Refreshed check configuration of host [%s] with %d services") % (
                hostname, result.self_total)
            watolib.add_service_change(host, "refresh-autochecks", message)
        else:
            message = _("Saved check configuration of host [%s] with %d services") % (
                hostname, result.self_total)
            watolib.add_service_change(host, "set-autochecks", message)

        msg = _("Service discovery successful. Added %d, removed %d, kept %d, total %d services "
                "and %d new, %d total host labels") % (
                    result.self_new,
                    result.self_removed,
                    result.self_kept,
                    result.self_total,
                    result.self_new_host_labels,
                    result.self_total_host_labels,
                )
        return msg
Exemplo n.º 2
0
def update_host(params):
    """Update a host"""
    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: watolib.CREHost = watolib.Host.host(host_name)
    constructors.require_etag(constructors.etag_of_obj(host))

    if new_attributes:
        host.edit(new_attributes, None)

    if update_attributes:
        host.update_attributes(update_attributes)

    faulty_attributes = []
    for attribute in remove_attributes:
        try:
            host.remove_attribute(attribute)
        except KeyError:
            faulty_attributes.append(attribute)

    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, False)
Exemplo n.º 3
0
    def _discover_services(self, request):
        mode = request.get("mode", "new")
        hostname = request.get("hostname")

        check_hostname(hostname, should_exist=True)

        host = watolib.Host.host(hostname)

        host_attributes = host.effective_attributes()

        if host.is_cluster():
            # This is currently the only way to get some actual discovery statitics.
            # Start a dry-run -> Get statistics
            # Do an actual discovery on the nodes -> data is written
            result = watolib.check_mk_automation(host_attributes.get("site"), "try-inventory",
                                                 ["@scan"] + [hostname])
            counts = {"new": 0, "old": 0}
            for entry in result["check_table"]:
                if entry[0] in counts:
                    counts[entry[0]] += 1

            counts = {
                hostname: (
                    counts["new"],
                    0,  # this info is not available for clusters
                    counts["old"],
                    counts["new"] + counts["old"])
            }

            # A cluster cannot fail, just the nodes. This information is currently discarded
            failed_hosts = None
            watolib.check_mk_automation(host_attributes.get("site"), "inventory",
                                        ["@scan", mode] + host.cluster_nodes())
        else:
            counts, failed_hosts = watolib.check_mk_automation(host_attributes.get("site"),
                                                               "inventory",
                                                               ["@scan", mode] + [hostname])

        if failed_hosts:
            if not host.discovery_failed():
                host.set_discovery_failed()
            raise MKUserError(
                None,
                _("Failed to inventorize %s: %s") % (hostname, failed_hosts[hostname]))

        if host.discovery_failed():
            host.clear_discovery_failed()

        if mode == "refresh":
            message = _("Refreshed check configuration of host [%s] with %d services") % (
                hostname, counts[hostname][3])
            watolib.add_service_change(host, "refresh-autochecks", message)
        else:
            message = _("Saved check configuration of host [%s] with %d services") % (
                hostname, counts[hostname][3])
            watolib.add_service_change(host, "set-autochecks", message)

        msg = _("Service discovery successful. Added %d, removed %d, kept %d, total %d services "
                "and %d new, %d total host labels") % tuple(counts[hostname])
        return msg
Exemplo n.º 4
0
def update_host(params):
    """Update a host"""
    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: watolib.CREHost = watolib.Host.host(host_name)
    constructors.require_etag(etag_of_host(host))

    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 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, False)
Exemplo n.º 5
0
def bulk_update_hosts(params):
    """Bulk update hosts"""
    body = params['body']
    entries = body['entries']

    hosts = []
    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: watolib.CREHost = watolib.Host.host(host_name)
        if new_attributes:
            host.edit(new_attributes, None)

        if update_attributes:
            host.update_attributes(update_attributes)

        for attribute in remove_attributes:
            host.remove_attribute(attribute)

        hosts.append(host)

    return host_collection(hosts)
Exemplo n.º 6
0
    def _edit(self, request):
        hostname = request.get("hostname")
        attributes = request.get("attributes", {})
        unset_attribute_names = request.get("unset_attributes", [])
        cluster_nodes = request.get("nodes")

        check_hostname(hostname, should_exist=True)

        host = watolib.Host.host(hostname)

        # Deprecated, but still supported
        # Nodes are now specified in an extra key
        if ".nodes" in attributes:
            cluster_nodes = attributes[".nodes"]
            del attributes[".nodes"]
        validate_host_attributes(attributes, new=False)

        # Update existing attributes. Add new, remove unset_attributes
        current_attributes = host.attributes().copy()
        for attrname in unset_attribute_names:
            if attrname in current_attributes:
                del current_attributes[attrname]
        current_attributes.update(attributes)

        if not cluster_nodes:
            cluster_nodes = host.cluster_nodes()

        if cluster_nodes:
            cluster_nodes = list(map(str, cluster_nodes))

        host.edit(current_attributes, cluster_nodes)
Exemplo n.º 7
0
def delete(params):
    hostname = params['hostname']
    check_hostname(hostname, should_exist=True)
    host = watolib.Host.host(hostname)
    constructors.require_etag(constructors.etag_of_obj(host))
    host.folder().delete_hosts([host.name()])
    return Response(status=204)
Exemplo n.º 8
0
def delete(params):
    """Delete a host"""
    host_name = params['host_name']
    # Parameters can't be validated through marshmallow yet.
    check_hostname(host_name, should_exist=True)
    host: watolib.CREHost = watolib.Host.host(host_name)
    host.folder().delete_hosts([host.name()])
    return Response(status=204)
Exemplo n.º 9
0
def delete(params):
    """Delete a host"""
    host_name = params['host_name']
    # Parameters can't be validated through marshmallow yet.
    check_hostname(host_name, should_exist=True)
    host = watolib.Host.host(host_name)
    constructors.require_etag(constructors.etag_of_obj(host))
    host.folder().delete_hosts([host.name()])
    return Response(status=204)
Exemplo n.º 10
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.
    """
    body = params["body"]
    entries = body["entries"]

    hosts = []
    faulty_hosts = []
    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: watolib.CREHost = watolib.Host.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:
            faulty_hosts.append(
                f"{host_name} ({', '.join(faulty_attributes)})")
            continue

        if remove_attributes:
            host.clean_attributes(remove_attributes)

        hosts.append(host)

    if faulty_hosts:
        return problem(
            status=400,
            title="Some attributes could not be removed",
            detail=
            f"The attributes of the following hosts could not be removed: {', '.join(faulty_hosts)}",
        )

    return host_collection(hosts)
Exemplo n.º 11
0
    def _get(self, request):
        hostname = request.get("hostname")

        check_hostname(hostname, should_exist=True)

        host = watolib.Host.host(hostname)
        host.need_permission("read")
        if bool(int(request.get("effective_attributes", "0"))):
            attributes = host.effective_attributes()
        else:
            attributes = host.attributes()

        response = {"attributes": attributes, "path": host.folder().path(), "hostname": host.name()}
        if host.is_cluster():
            response["nodes"] = host.cluster_nodes()
        return response
Exemplo n.º 12
0
def update_host(params):
    """Update a host"""
    host_name = params['host_name']
    body = params['body']
    new_attributes = body['attributes']
    update_attributes = body['attributes']
    check_hostname(host_name, should_exist=True)
    host: watolib.CREHost = watolib.Host.host(host_name)
    constructors.require_etag(constructors.etag_of_obj(host))

    if new_attributes:
        host.edit(new_attributes, None)

    if update_attributes:
        host.update_attributes(update_attributes)

    return _serve_host(host)
Exemplo n.º 13
0
    def _add(self, request):
        create_parent_folders_var = request.get(
            "create_parent_folders", request.get("create_folders", "1"))
        create_parent_folders = bool(int(create_parent_folders_var))

        # Werk #10863: In 1.6 some hosts / rulesets were saved as unicode
        # strings.  After reading the config into the GUI ensure we really
        # process the host names as str. TODO: Can be removed with Python 3.
        hostname = str(request.get("hostname"))
        folder_path = str(request.get("folder"))
        attributes = request.get("attributes", {})
        cluster_nodes = request.get("nodes")

        check_hostname(hostname, should_exist=False)

        # Validate folder
        if folder_path not in ('', '/'):
            folders = folder_path.split("/")
            for foldername in folders:
                watolib.check_wato_foldername(None, foldername, just_name=True)
        else:
            folder_path = ""
            folders = [""]

        # Deprecated, but still supported
        # Nodes are now specified in an extra key
        if ".nodes" in attributes:
            cluster_nodes = attributes[".nodes"]
            del attributes[".nodes"]
        validate_host_attributes(attributes, new=True)

        # Create folder(s)
        if not watolib.Folder.folder_exists(folder_path):
            if not create_parent_folders:
                raise MKUserError(None,
                                  _("Unable to create parent folder(s)."))
            watolib.Folder.create_missing_folders(folder_path)

        # Add host
        if cluster_nodes:
            cluster_nodes = list(map(str, cluster_nodes))
        watolib.Folder.folder(folder_path).create_hosts([(hostname, attributes,
                                                          cluster_nodes)])
Exemplo n.º 14
0
def create(params):
    body = params['body']
    hostname = body['hostname']
    folder_id = body['folder']
    attributes = body.get('attributes', {})
    cluster_nodes = None

    check_hostname(hostname, should_exist=False)
    validate_host_attributes(attributes, new=True)

    if folder_id == 'root':
        folder = watolib.Folder.root_folder()
    else:
        folder = load_folder(folder_id, status=400)

    folder.create_hosts([(hostname, attributes, cluster_nodes)])

    host = watolib.Host.host(hostname)
    return _serve_host(host)
Exemplo n.º 15
0
    def _add(self, request, bake_hosts=True):
        create_parent_folders_var = request.get(
            "create_parent_folders", request.get("create_folders", "1")
        )
        create_parent_folders = bool(int(create_parent_folders_var))

        hostname = request["hostname"]
        folder_path = request.get("folder", "")
        attributes = request.get("attributes", {})
        cluster_nodes = request.get("nodes")

        check_hostname(hostname, should_exist=False)

        # Validate folder
        if folder_path not in ("", "/"):
            folders = folder_path.split("/")
            for foldername in folders:
                watolib.check_wato_foldername(None, foldername, just_name=True)
        else:
            folder_path = ""
            folders = [""]

        # Deprecated, but still supported
        # Nodes are now specified in an extra key
        if ".nodes" in attributes:
            cluster_nodes = attributes[".nodes"]
            del attributes[".nodes"]
        validate_host_attributes(attributes, new=True)

        # Create folder(s)
        if not watolib.Folder.folder_exists(folder_path):
            if not create_parent_folders:
                raise MKUserError(None, _("Unable to create parent folder(s)."))
            watolib.Folder.create_missing_folders(folder_path)

        # Add host
        if cluster_nodes:
            cluster_nodes = list(map(str, cluster_nodes))
        watolib.Folder.folder(folder_path).create_hosts(
            [(hostname, attributes, cluster_nodes)], bake_hosts=bake_hosts
        )
Exemplo n.º 16
0
def update_nodes(params):
    """Update the nodes of a cluster host"""
    host_name = params['host_name']
    body = params['body']
    nodes = body['nodes']
    check_hostname(host_name, should_exist=True)
    for node in nodes:
        check_hostname(node, should_exist=True)

    host: watolib.CREHost = watolib.Host.host(host_name)
    if not host.is_cluster():
        return problem(status=400,
                       title="Trying to change nodes of a regular host.",
                       detail="nodes can only be changed on cluster hosts.")
    constructors.require_etag(constructors.etag_of_obj(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(),
        ))
Exemplo n.º 17
0
    def _delete(self, request):
        hostname = request["hostname"]
        check_hostname(hostname, should_exist=True)

        host = watolib.Host.host(hostname)
        host.folder().delete_hosts([host.name()])