# frozen_string_literal: true module ForemanResourceQuota module ResourceOrigins class ComputeResourceOrigin < ResourceOrigin def extract_cpu_cores(param) param.cpus rescue StandardError nil end def extract_memory_mb(param) param.memory.to_i / ResourceQuotaHelper::FACTOR_B_TO_MB rescue StandardError nil end def extract_disk_gb(_) # FIXME: no disk given in VM (compare fog extensions) nil end def collect_resources!(resources_sum, missing_hosts_resources, _host_objects) compute_resource_to_hosts = group_hosts_by_compute_resource(missing_hosts_resources.keys) compute_resource_to_hosts.each do |compute_resource_id, hosts| next if compute_resource_id == :nil_compute_resource host_vms, vm_id_attr = filter_vms_by_hosts(hosts, compute_resource_id) next if host_vms.empty? hosts.each do |host| vm = host_vms.find { |obj| obj.send(vm_id_attr) == host.uuid } next unless vm process_host_vm!(resources_sum, missing_hosts_resources, host.name, vm) end end end # Groups hosts with the same compute resource. # Parameters: An array of host names. # Returns: A hash where keys represent compute resource IDs and values are the list of host objects. def group_hosts_by_compute_resource(host_names) Host::Managed.where(name: host_names).includes(:compute_resource).group_by do |host| host.compute_resource&.id || :nil_compute_resource end end # Filters VMs of a compute resource, given a list of hosts. # Parameters: # - hosts: An array of host objects. # - compute_resource_id: ID of the compute resource. # Returns: # - filtered_vms: An array of filtered virtual machine objects. # - id_attr: Attribute used for identifying virtual machines (either :vmid or :id). def filter_vms_by_hosts(hosts, compute_resource_id) host_uuids = hosts.map(&:uuid) vms = ComputeResource.find_by(id: compute_resource_id).vms.all id_attr = vms[0].respond_to?(:vmid) ? :vmid : :id filtered_vms = vms.select { |obj| host_uuids.include?(obj.send(id_attr)) } # reduce from all vms [filtered_vms, id_attr] end # Processes a host's virtual machines and updates resource allocation. # Parameters: # - resources_sum: Hash containing total resources sum. # - missing_hosts_resources: Hash containing missing resources per host. # - host_name: Name of the host. # - vm: Compute resource VM object of given host. # Returns: None. def process_host_vm!(resources_sum, missing_hosts_resources, host_name, host_vm) missing_hosts_resources[host_name].reverse_each do |resource_name| resource_value = process_resource(resource_name, host_vm) next unless resource_value resources_sum[resource_name] += resource_value missing_hosts_resources[host_name].delete(resource_name) end missing_hosts_resources.delete(host_name) if missing_hosts_resources[host_name].empty? end end end end