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
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)
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
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)
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)
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)
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)
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)
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)
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)
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
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)
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)])
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)
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 )
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(), ))
def _delete(self, request): hostname = request["hostname"] check_hostname(hostname, should_exist=True) host = watolib.Host.host(hostname) host.folder().delete_hosts([host.name()])