diff --git a/helm/bundles/cortex-nova/templates/knowledges.yaml b/helm/bundles/cortex-nova/templates/knowledges.yaml index 223bc615f..8353052d2 100644 --- a/helm/bundles/cortex-nova/templates/knowledges.yaml +++ b/helm/bundles/cortex-nova/templates/knowledges.yaml @@ -178,15 +178,17 @@ spec: apiVersion: cortex.cloud/v1alpha1 kind: Knowledge metadata: - name: host-details + name: vmware-host-details spec: schedulingDomain: nova extractor: - name: sap_host_details_extractor + name: vmware_host_details_extractor description: | - This knowledge extracts SAP-specific host details information. + This knowledge extracts details of VMware compute hosts. KVM hosts are + served by a dedicated CRD and ironic hosts are excluded. recency: "60s" dependencies: datasources: - name: placement-resource-provider-traits + - name: placement-resource-provider-inventory-usages - name: nova-hypervisors diff --git a/helm/bundles/cortex-nova/templates/kpis.yaml b/helm/bundles/cortex-nova/templates/kpis.yaml index 418389e95..4c8dee11a 100644 --- a/helm/bundles/cortex-nova/templates/kpis.yaml +++ b/helm/bundles/cortex-nova/templates/kpis.yaml @@ -173,7 +173,7 @@ spec: - name: identity-projects - name: identity-domains knowledges: - - name: host-details + - name: vmware-host-details description: | This KPI tracks the resource utilization of projects running VMs on VMware hosts. --- @@ -203,7 +203,7 @@ spec: impl: vmware_host_capacity_kpi dependencies: knowledges: - - name: host-details + - name: vmware-host-details - name: host-utilization description: | This KPI tracks the capacity and utilization of VMware hosts in terms of CPU, RAM, and disk resources. \ No newline at end of file diff --git a/helm/bundles/cortex-nova/templates/kpis_kvm.yaml b/helm/bundles/cortex-nova/templates/kpis_kvm.yaml index 1ec5a2d2d..d9ad32d2e 100644 --- a/helm/bundles/cortex-nova/templates/kpis_kvm.yaml +++ b/helm/bundles/cortex-nova/templates/kpis_kvm.yaml @@ -9,7 +9,6 @@ spec: impl: kvm_host_capacity_kpi dependencies: knowledges: - - name: host-details - name: host-utilization description: | This KPI tracks the total, utilized, reserved and failover capacity of KVM hosts. diff --git a/internal/knowledge/extractor/controller_test.go b/internal/knowledge/extractor/controller_test.go index 8c5a40bf9..75ee4ee06 100644 --- a/internal/knowledge/extractor/controller_test.go +++ b/internal/knowledge/extractor/controller_test.go @@ -450,7 +450,7 @@ func TestKnowledgeReconciler_Reconcile_SupportedExtractors(t *testing.T) { "vm_life_span_histogram_extractor", "host_az_extractor", "host_pinned_projects_extractor", - "sap_host_details_extractor", + "vmware_host_details_extractor", } for _, extractorName := range supportedExtractors { diff --git a/internal/knowledge/extractor/plugins/compute/host_details.go b/internal/knowledge/extractor/plugins/compute/vmware_host_details.go similarity index 81% rename from internal/knowledge/extractor/plugins/compute/host_details.go rename to internal/knowledge/extractor/plugins/compute/vmware_host_details.go index ab6987821..14bca07ba 100644 --- a/internal/knowledge/extractor/plugins/compute/host_details.go +++ b/internal/knowledge/extractor/plugins/compute/vmware_host_details.go @@ -14,7 +14,10 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" ) -type HostDetails struct { +// VMwareHostDetails describes a single VMware compute host. Only VMware hosts +// are extracted here (KVM hosts are served by a dedicated CRD, and ironic hosts +// are excluded); the extractor SQL filters everything else out. +type VMwareHostDetails struct { // Name of the OpenStack compute host. ComputeHost string `db:"compute_host"` // Availability zone of the compute host. @@ -22,11 +25,6 @@ type HostDetails struct { // CPU Architecture of the compute host. // Can be "cascade-lake" or "sapphire-rapids" CPUArchitecture string `db:"cpu_architecture"` - // Hypervisor type of the compute host. - HypervisorType string `db:"hypervisor_type"` - // Hypervisor family of the compute host. - // Can be "kvm" or "vmware" - HypervisorFamily string `db:"hypervisor_family"` // Amount of VMs currently running on the compute host. RunningVMs int `db:"running_vms"` // Type of workload running on the compute host. @@ -45,28 +43,28 @@ type HostDetails struct { // Physical size category of a single host inside a VMware building block, // derived from the memory inventory and rounded to the nearest TiB // (e.g. "4TiB"), or to the nearest GiB (e.g. "512GiB") when smaller than - // 1 TiB. Only meaningful for VMware hosts; "unknown" otherwise. + // 1 TiB. "unknown" when the memory inventory is missing. PhysicalHostSize string `db:"physical_host_size"` } -type HostDetailsExtractor struct { +type VMwareHostDetailsExtractor struct { // Common base for all extractors that provides standard functionality. plugins.BaseExtractor[ - struct{}, // No options passed through yaml config - HostDetails, // Feature model + struct{}, // No options passed through yaml config + VMwareHostDetails, // Feature model ] } -//go:embed host_details.sql -var hostDetailsQuery string +//go:embed vmware_host_details.sql +var vmwareHostDetailsQuery string -// Extract the traits of a compute host from the database. -func (e *HostDetailsExtractor) Extract() ([]plugins.Feature, error) { +// Extract the details of the VMware compute hosts from the database. +func (e *VMwareHostDetailsExtractor) Extract() ([]plugins.Feature, error) { if e.DB == nil { return nil, errors.New("database connection is not initialized") } - var hostDetails []HostDetails - if _, err := e.DB.Select(&hostDetails, hostDetailsQuery); err != nil { + var hostDetails []VMwareHostDetails + if _, err := e.DB.Select(&hostDetails, vmwareHostDetailsQuery); err != nil { return nil, err } diff --git a/internal/knowledge/extractor/plugins/compute/host_details.sql b/internal/knowledge/extractor/plugins/compute/vmware_host_details.sql similarity index 74% rename from internal/knowledge/extractor/plugins/compute/host_details.sql rename to internal/knowledge/extractor/plugins/compute/vmware_host_details.sql index 959ebb392..6be4fe1b4 100644 --- a/internal/knowledge/extractor/plugins/compute/host_details.sql +++ b/internal/knowledge/extractor/plugins/compute/vmware_host_details.sql @@ -1,8 +1,11 @@ +-- Details of VMware compute hosts. Only VMware hosts are considered here: KVM +-- hosts are served by a dedicated CRD, and ironic hosts are excluded. The +-- WHERE clause keeps rows whose service host matches the VMware naming +-- convention (nova-compute-%) while dropping ironic ones (nova-compute-ironic-%). WITH host_traits AS ( SELECT h.id AS hypervisor_id, h.service_host, - h.hypervisor_type, h.running_vms, h.state, h.status, @@ -11,7 +14,9 @@ WITH host_traits AS ( FROM openstack_hypervisors h LEFT JOIN openstack_resource_provider_traits t ON h.id = t.resource_provider_uuid - GROUP BY h.id, h.service_host, h.hypervisor_type, h.running_vms, h.state, h.status, h.service_disabled_reason + WHERE h.service_host LIKE 'nova-compute-%' + AND h.service_host NOT LIKE 'nova-compute-ironic-%' + GROUP BY h.id, h.service_host, h.running_vms, h.state, h.status, h.service_disabled_reason ), -- Physical memory size (in MiB) of a single host inside a VMware building block. -- A building block pools multiple physical hosts into one resource provider, so @@ -37,12 +42,6 @@ SELECT WHEN ht.traits LIKE '%CUSTOM_HW_SAPPHIRE_RAPIDS%' THEN 'sapphire-rapids' ELSE 'cascade-lake' END AS cpu_architecture, - ht.hypervisor_type, - CASE - WHEN ht.service_host LIKE 'nova-compute-%' THEN 'vmware' - WHEN ht.service_host LIKE 'node%-bb%' THEN 'kvm' - ELSE 'unknown' - END AS hypervisor_family, CASE WHEN ht.traits LIKE '%CUSTOM_HANA_EXCLUSIVE_HOST%' THEN 'hana' ELSE 'general-purpose' @@ -67,10 +66,11 @@ SELECT WHEN ht.state != 'up' THEN '[down] ' || COALESCE(ht.service_disabled_reason, '--') ELSE NULL END AS disabled_reason, - -- Physical host size category. The size is first rounded to whole GiB; if - -- that is at least 1024 GiB it is reported in TiB ("TiB"), otherwise in - -- GiB ("GiB"). Rounding to GiB first avoids a value like 1023.6 GiB being - -- shown as "1024GiB" instead of "1TiB". + -- Physical host size category of a single host inside the building block. + -- The size is first rounded to whole GiB; if that is at least 1024 GiB it is + -- reported in TiB, otherwise in GiB. Rounding to GiB + -- first avoids a value like 1023.6 GiB being shown as "1024GiB" instead of + -- "1TiB". "unknown" when the memory inventory is missing. CASE WHEN hpm.physical_size_mb IS NULL THEN 'unknown' WHEN ROUND(hpm.physical_size_mb / 1024.0) >= 1024 @@ -79,4 +79,4 @@ SELECT END AS physical_host_size FROM host_traits ht LEFT JOIN host_physical_memory hpm - ON ht.hypervisor_id = hpm.resource_provider_uuid; \ No newline at end of file + ON ht.hypervisor_id = hpm.resource_provider_uuid; diff --git a/internal/knowledge/extractor/plugins/compute/host_details_test.go b/internal/knowledge/extractor/plugins/compute/vmware_host_details_test.go similarity index 67% rename from internal/knowledge/extractor/plugins/compute/host_details_test.go rename to internal/knowledge/extractor/plugins/compute/vmware_host_details_test.go index 490020ae1..d24b1c0b1 100644 --- a/internal/knowledge/extractor/plugins/compute/host_details_test.go +++ b/internal/knowledge/extractor/plugins/compute/vmware_host_details_test.go @@ -16,15 +16,15 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client/fake" ) -func TestHostDetailsExtractor_Init(t *testing.T) { - extractor := &HostDetailsExtractor{} +func TestVMwareHostDetailsExtractor_Init(t *testing.T) { + extractor := &VMwareHostDetailsExtractor{} config := v1alpha1.KnowledgeSpec{} if err := extractor.Init(nil, nil, config); err != nil { t.Fatalf("expected no error, got %v", err) } } -func TestHostDetailsExtractor_Extract(t *testing.T) { +func TestVMwareHostDetailsExtractor_Extract(t *testing.T) { dbEnv := testlibDB.SetupDBEnv(t) testDB := db.DB{DbMap: dbEnv.DbMap} defer dbEnv.Close() @@ -46,34 +46,29 @@ func TestHostDetailsExtractor_Extract(t *testing.T) { hostPinnedProjects, err := v1alpha1.BoxFeatureList([]any{ &HostPinnedProjects{ComputeHost: new("nova-compute-bb01"), Label: new("project-123")}, &HostPinnedProjects{ComputeHost: new("nova-compute-bb01"), Label: new("project-456")}, - &HostPinnedProjects{ComputeHost: new("node001-bb02"), Label: nil}, - // No entry for ironic-host-1 since it is excluded in the feature host pinned projects - &HostPinnedProjects{ComputeHost: new("node002-bb03"), Label: nil}, - &HostPinnedProjects{ComputeHost: new("node003-bb03"), Label: nil}, - &HostPinnedProjects{ComputeHost: new("node004-bb03"), Label: nil}, }) if err != nil { t.Fatalf("expected no error, got %v", err) } - // Insert mock data into the hypervisors and traits tables + // Insert mock data into the hypervisors and traits tables. Only VMware hosts + // (nova-compute-% and not nova-compute-ironic-%) are expected to survive the + // extractor's WHERE filter; KVM and ironic hosts must be dropped entirely. hypervisors := []any{ // VMware host &nova.Hypervisor{ID: "uuid1", ServiceHost: "nova-compute-bb01", HypervisorType: "vcenter", RunningVMs: 5, State: "up", Status: "enabled"}, - // KVM host + // KVM host (should be filtered out) &nova.Hypervisor{ID: "uuid2", ServiceHost: "node001-bb02", HypervisorType: "qemu", RunningVMs: 3, State: "down", Status: "enabled"}, - // Ironic host (should be skipped) - &nova.Hypervisor{ID: "uuid3", ServiceHost: "ironic-host-01", HypervisorType: "ironic", RunningVMs: 0, State: "up", Status: "enabled"}, - // Host with no special traits - &nova.Hypervisor{ID: "uuid4", ServiceHost: "node002-bb03", HypervisorType: "test", RunningVMs: 2, State: "up", Status: "enabled"}, - // Host with disabled status, no entry in the resource providers - &nova.Hypervisor{ID: "uuid5", ServiceHost: "node003-bb03", HypervisorType: "test", RunningVMs: 2, State: "up", Status: "disabled", ServiceDisabledReason: new("example reason")}, - // Host with disabled trait - &nova.Hypervisor{ID: "uuid6", ServiceHost: "node004-bb03", HypervisorType: "test", RunningVMs: 2, State: "up", Status: "enabled", ServiceDisabledReason: new("example reason")}, + // Ironic host (should be filtered out) + &nova.Hypervisor{ID: "uuid3", ServiceHost: "nova-compute-ironic-01", HypervisorType: "ironic", RunningVMs: 0, State: "up", Status: "enabled"}, // VMware host with a sub-TiB physical host size &nova.Hypervisor{ID: "uuid7", ServiceHost: "nova-compute-bb04", HypervisorType: "vcenter", RunningVMs: 1, State: "up", Status: "enabled"}, // VMware host just under 1 TiB that rounds up to a full TiB &nova.Hypervisor{ID: "uuid8", ServiceHost: "nova-compute-bb05", HypervisorType: "vcenter", RunningVMs: 1, State: "up", Status: "enabled"}, + // Disabled VMware host via status + &nova.Hypervisor{ID: "uuid9", ServiceHost: "nova-compute-bb06", HypervisorType: "vcenter", RunningVMs: 2, State: "up", Status: "disabled", ServiceDisabledReason: new("example reason")}, + // Disabled VMware host via trait + &nova.Hypervisor{ID: "uuid10", ServiceHost: "nova-compute-bb07", HypervisorType: "vcenter", RunningVMs: 2, State: "up", Status: "enabled", ServiceDisabledReason: new("example reason")}, } if err := testDB.Insert(hypervisors...); err != nil { @@ -85,14 +80,12 @@ func TestHostDetailsExtractor_Extract(t *testing.T) { &placement.Trait{ResourceProviderUUID: "uuid1", Name: "CUSTOM_HW_SAPPHIRE_RAPIDS"}, &placement.Trait{ResourceProviderUUID: "uuid1", Name: "CUSTOM_HANA_EXCLUSIVE_HOST"}, &placement.Trait{ResourceProviderUUID: "uuid1", Name: "CUSTOM_EXTERNAL_CUSTOMER_EXCLUSIVE"}, - // KVM host traits + // KVM host traits (filtered out) &placement.Trait{ResourceProviderUUID: "uuid2", Name: "CUSTOM_NUMASIZE_C48_M729"}, - // Ironic host traits + // Ironic host traits (filtered out) &placement.Trait{ResourceProviderUUID: "uuid3", Name: "TRAIT_IGNORED"}, - // Disabled KVM host - &placement.Trait{ResourceProviderUUID: "uuid4", Name: "CUSTOM_DECOMMISSIONING"}, - // Host with disabled trait - &placement.Trait{ResourceProviderUUID: "uuid6", Name: "COMPUTE_STATUS_DISABLED"}, + // Disabled VMware host via trait + &placement.Trait{ResourceProviderUUID: "uuid10", Name: "COMPUTE_STATUS_DISABLED"}, } if err := testDB.Insert(traits...); err != nil { @@ -137,19 +130,16 @@ func TestHostDetailsExtractor_Extract(t *testing.T) { hostAvailabilityZones, err := v1alpha1.BoxFeatureList([]any{ &HostAZ{AvailabilityZone: new("az1"), ComputeHost: "nova-compute-bb01"}, - &HostAZ{AvailabilityZone: nil, ComputeHost: "node001-bb02"}, - &HostAZ{AvailabilityZone: new("az2"), ComputeHost: "node002-bb03"}, - &HostAZ{AvailabilityZone: new("az2"), ComputeHost: "ironic-host-01"}, - &HostAZ{AvailabilityZone: new("az2"), ComputeHost: "node003-bb03"}, - &HostAZ{AvailabilityZone: new("az2"), ComputeHost: "node004-bb03"}, &HostAZ{AvailabilityZone: new("az1"), ComputeHost: "nova-compute-bb04"}, &HostAZ{AvailabilityZone: new("az1"), ComputeHost: "nova-compute-bb05"}, + &HostAZ{AvailabilityZone: new("az2"), ComputeHost: "nova-compute-bb06"}, + &HostAZ{AvailabilityZone: new("az2"), ComputeHost: "nova-compute-bb07"}, }) if err != nil { t.Fatalf("expected no error, got %v", err) } - extractor := &HostDetailsExtractor{} + extractor := &VMwareHostDetailsExtractor{} config := v1alpha1.KnowledgeSpec{} client := fake.NewClientBuilder(). WithScheme(scheme). @@ -170,58 +160,50 @@ func TestHostDetailsExtractor_Extract(t *testing.T) { t.Fatalf("expected no error, got %v", err) } - expected := []HostDetails{ + expected := []VMwareHostDetails{ { - ComputeHost: "ironic-host-01", - AvailabilityZone: "az2", - CPUArchitecture: "cascade-lake", - HypervisorType: "ironic", - HypervisorFamily: "unknown", - WorkloadType: "general-purpose", + ComputeHost: "nova-compute-bb01", + AvailabilityZone: "az1", + CPUArchitecture: "sapphire-rapids", + WorkloadType: "hana", Enabled: true, - ExternalCustomer: false, Decommissioned: false, + ExternalCustomer: true, DisabledReason: nil, - RunningVMs: 0, - PinnedProjects: nil, - PhysicalHostSize: "unknown", + RunningVMs: 5, + PinnedProjects: new("project-123,project-456"), + PhysicalHostSize: "4TiB", }, { - ComputeHost: "node001-bb02", - AvailabilityZone: "unknown", + ComputeHost: "nova-compute-bb04", + AvailabilityZone: "az1", CPUArchitecture: "cascade-lake", - HypervisorType: "qemu", - HypervisorFamily: "kvm", WorkloadType: "general-purpose", - Enabled: false, + Enabled: true, Decommissioned: false, ExternalCustomer: false, - DisabledReason: new("[down] --"), - RunningVMs: 3, + DisabledReason: nil, + RunningVMs: 1, PinnedProjects: nil, - PhysicalHostSize: "unknown", + PhysicalHostSize: "512GiB", }, { - ComputeHost: "node002-bb03", - AvailabilityZone: "az2", + ComputeHost: "nova-compute-bb05", + AvailabilityZone: "az1", CPUArchitecture: "cascade-lake", - HypervisorFamily: "kvm", - HypervisorType: "test", WorkloadType: "general-purpose", Enabled: true, - Decommissioned: true, + Decommissioned: false, ExternalCustomer: false, DisabledReason: nil, - RunningVMs: 2, + RunningVMs: 1, PinnedProjects: nil, - PhysicalHostSize: "unknown", + PhysicalHostSize: "1TiB", }, { - ComputeHost: "node003-bb03", + ComputeHost: "nova-compute-bb06", AvailabilityZone: "az2", CPUArchitecture: "cascade-lake", - HypervisorType: "test", - HypervisorFamily: "kvm", WorkloadType: "general-purpose", Enabled: false, Decommissioned: false, @@ -232,11 +214,9 @@ func TestHostDetailsExtractor_Extract(t *testing.T) { PhysicalHostSize: "unknown", }, { - ComputeHost: "node004-bb03", + ComputeHost: "nova-compute-bb07", AvailabilityZone: "az2", CPUArchitecture: "cascade-lake", - HypervisorType: "test", - HypervisorFamily: "kvm", WorkloadType: "general-purpose", Enabled: false, Decommissioned: false, @@ -246,54 +226,9 @@ func TestHostDetailsExtractor_Extract(t *testing.T) { PinnedProjects: nil, PhysicalHostSize: "unknown", }, - { - ComputeHost: "nova-compute-bb01", - AvailabilityZone: "az1", - CPUArchitecture: "sapphire-rapids", - HypervisorType: "vcenter", - HypervisorFamily: "vmware", - WorkloadType: "hana", - Enabled: true, - Decommissioned: false, - ExternalCustomer: true, - DisabledReason: nil, - RunningVMs: 5, - PinnedProjects: new("project-123,project-456"), - PhysicalHostSize: "4TiB", - }, - { - ComputeHost: "nova-compute-bb04", - AvailabilityZone: "az1", - CPUArchitecture: "cascade-lake", - HypervisorType: "vcenter", - HypervisorFamily: "vmware", - WorkloadType: "general-purpose", - Enabled: true, - Decommissioned: false, - ExternalCustomer: false, - DisabledReason: nil, - RunningVMs: 1, - PinnedProjects: nil, - PhysicalHostSize: "512GiB", - }, - { - ComputeHost: "nova-compute-bb05", - AvailabilityZone: "az1", - CPUArchitecture: "cascade-lake", - HypervisorType: "vcenter", - HypervisorFamily: "vmware", - WorkloadType: "general-purpose", - Enabled: true, - Decommissioned: false, - ExternalCustomer: false, - DisabledReason: nil, - RunningVMs: 1, - PinnedProjects: nil, - PhysicalHostSize: "1TiB", - }, } - // Check if the expected details match the extracted ones + // Only VMware hosts should be extracted; KVM and ironic hosts are filtered out. if len(features) != len(expected) { t.Fatalf("expected %d host details, got %d", len(expected), len(features)) } @@ -301,7 +236,7 @@ func TestHostDetailsExtractor_Extract(t *testing.T) { for _, expectedDetail := range expected { found := false for _, feature := range features { - extractedDetail := feature.(HostDetails) + extractedDetail := feature.(VMwareHostDetails) if extractedDetail.ComputeHost == expectedDetail.ComputeHost { found = true if !reflect.DeepEqual(extractedDetail, expectedDetail) { diff --git a/internal/knowledge/extractor/supported_extractors.go b/internal/knowledge/extractor/supported_extractors.go index 6f1cb2fd2..4cfcd006a 100644 --- a/internal/knowledge/extractor/supported_extractors.go +++ b/internal/knowledge/extractor/supported_extractors.go @@ -22,7 +22,7 @@ var supportedExtractors = map[string]plugins.FeatureExtractor{ "vm_life_span_histogram_extractor": &compute.VMLifeSpanHistogramExtractor{}, "host_az_extractor": &compute.HostAZExtractor{}, "host_pinned_projects_extractor": &compute.HostPinnedProjectsExtractor{}, - "sap_host_details_extractor": &compute.HostDetailsExtractor{}, + "vmware_host_details_extractor": &compute.VMwareHostDetailsExtractor{}, "flavor_groups": &compute.FlavorGroupExtractor{}, "netapp_storage_pool_cpu_usage_extractor": &storage.StoragePoolCPUUsageExtractor{}, diff --git a/internal/knowledge/kpis/plugins/infrastructure/shared.go b/internal/knowledge/kpis/plugins/infrastructure/shared.go index 9c246247d..d39790521 100644 --- a/internal/knowledge/kpis/plugins/infrastructure/shared.go +++ b/internal/knowledge/kpis/plugins/infrastructure/shared.go @@ -15,18 +15,16 @@ import ( ) const ( - hostDetailsKnowledgeName = "host-details" + vmwareHostDetailsKnowledgeName = "vmware-host-details" hostUtilizationKnowledgeName = "host-utilization" - vmwareIronicHypervisorType = "ironic" - hypervisorFamilyVMware = "vmware" vmwareComputeHostPattern = "nova-compute-%" vmwareIronicComputeHostPattern = "nova-compute-ironic-%" kvmComputeHostPattern = "node%-bb%" ) -// vmwareHost wraps HostDetails with Prometheus metric helpers. +// vmwareHost wraps VMwareHostDetails with Prometheus metric helpers. type vmwareHost struct { - compute.HostDetails + compute.VMwareHostDetails } func (h vmwareHost) getHostLabels() []string { diff --git a/internal/knowledge/kpis/plugins/infrastructure/shared_test.go b/internal/knowledge/kpis/plugins/infrastructure/shared_test.go index c756ab48e..8fe8c9d7b 100644 --- a/internal/knowledge/kpis/plugins/infrastructure/shared_test.go +++ b/internal/knowledge/kpis/plugins/infrastructure/shared_test.go @@ -58,7 +58,7 @@ func TestVMwareHost_GetHostLabels(t *testing.T) { }{ { name: "all optional fields nil", - host: vmwareHost{compute.HostDetails{ + host: vmwareHost{compute.VMwareHostDetails{ AvailabilityZone: "az1", ComputeHost: "nova-compute-1", CPUArchitecture: "cascade-lake", @@ -73,7 +73,7 @@ func TestVMwareHost_GetHostLabels(t *testing.T) { }, { name: "disabled reason set", - host: vmwareHost{compute.HostDetails{ + host: vmwareHost{compute.VMwareHostDetails{ AvailabilityZone: "az2", ComputeHost: "nova-compute-2", DisabledReason: str("scheduled-maintenance"), @@ -82,7 +82,7 @@ func TestVMwareHost_GetHostLabels(t *testing.T) { }, { name: "pinned projects set", - host: vmwareHost{compute.HostDetails{ + host: vmwareHost{compute.VMwareHostDetails{ AvailabilityZone: "az1", ComputeHost: "nova-compute-3", PinnedProjects: str("proj-a,proj-b"), @@ -91,7 +91,7 @@ func TestVMwareHost_GetHostLabels(t *testing.T) { }, { name: "decommissioned and external customer", - host: vmwareHost{compute.HostDetails{ + host: vmwareHost{compute.VMwareHostDetails{ AvailabilityZone: "az3", ComputeHost: "nova-compute-4", Decommissioned: true, @@ -101,7 +101,7 @@ func TestVMwareHost_GetHostLabels(t *testing.T) { }, { name: "physical host size set", - host: vmwareHost{compute.HostDetails{ + host: vmwareHost{compute.VMwareHostDetails{ AvailabilityZone: "az1", ComputeHost: "nova-compute-5", PhysicalHostSize: "4TiB", diff --git a/internal/knowledge/kpis/plugins/infrastructure/vmware_host_capacity.go b/internal/knowledge/kpis/plugins/infrastructure/vmware_host_capacity.go index c7976db3a..45508636f 100644 --- a/internal/knowledge/kpis/plugins/infrastructure/vmware_host_capacity.go +++ b/internal/knowledge/kpis/plugins/infrastructure/vmware_host_capacity.go @@ -81,19 +81,16 @@ func (k *VMwareHostCapacityKPI) Collect(ch chan<- prometheus.Metric) { func (k *VMwareHostCapacityKPI) getVMwareHosts() ([]vmwareHost, error) { knowledge := &v1alpha1.Knowledge{} - if err := k.Client.Get(context.Background(), client.ObjectKey{Name: hostDetailsKnowledgeName}, knowledge); err != nil { + if err := k.Client.Get(context.Background(), client.ObjectKey{Name: vmwareHostDetailsKnowledgeName}, knowledge); err != nil { return nil, err } - details, err := v1alpha1.UnboxFeatureList[compute.HostDetails](knowledge.Status.Raw) + details, err := v1alpha1.UnboxFeatureList[compute.VMwareHostDetails](knowledge.Status.Raw) if err != nil { return nil, err } hosts := make([]vmwareHost, 0, len(details)) for _, d := range details { - if d.HypervisorType == vmwareIronicHypervisorType || d.HypervisorFamily != hypervisorFamilyVMware { - continue - } - hosts = append(hosts, vmwareHost{HostDetails: d}) + hosts = append(hosts, vmwareHost{VMwareHostDetails: d}) } return hosts, nil } diff --git a/internal/knowledge/kpis/plugins/infrastructure/vmware_host_capacity_test.go b/internal/knowledge/kpis/plugins/infrastructure/vmware_host_capacity_test.go index f0a025db4..dd2f50637 100644 --- a/internal/knowledge/kpis/plugins/infrastructure/vmware_host_capacity_test.go +++ b/internal/knowledge/kpis/plugins/infrastructure/vmware_host_capacity_test.go @@ -18,7 +18,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client/fake" ) -func buildHostCapacityClient(t *testing.T, hostDetails []compute.HostDetails, utilizations []compute.HostUtilization) *fake.ClientBuilder { +func buildHostCapacityClient(t *testing.T, hostDetails []compute.VMwareHostDetails, utilizations []compute.HostUtilization) *fake.ClientBuilder { t.Helper() scheme, err := v1alpha1.SchemeBuilder.Build() if err != nil { @@ -34,7 +34,7 @@ func buildHostCapacityClient(t *testing.T, hostDetails []compute.HostDetails, ut } return fake.NewClientBuilder().WithScheme(scheme).WithRuntimeObjects( &v1alpha1.Knowledge{ - ObjectMeta: v1.ObjectMeta{Name: hostDetailsKnowledgeName}, + ObjectMeta: v1.ObjectMeta{Name: vmwareHostDetailsKnowledgeName}, Status: v1alpha1.KnowledgeStatus{Raw: rawDetails}, }, &v1alpha1.Knowledge{ @@ -55,11 +55,11 @@ func TestVMwareHostCapacityKPI_Init(t *testing.T) { } func TestVMwareHostCapacityKPI_getVMwareHosts(t *testing.T) { - hostDetails := []compute.HostDetails{ - {ComputeHost: "nova-compute-1", HypervisorFamily: hypervisorFamilyVMware}, - {ComputeHost: "nova-compute-2", HypervisorFamily: hypervisorFamilyVMware}, - {ComputeHost: "nova-compute-ironic-1", HypervisorType: vmwareIronicHypervisorType, HypervisorFamily: hypervisorFamilyVMware}, - {ComputeHost: "nova-compute-3", HypervisorFamily: "other"}, + // The extractor SQL is responsible for filtering out KVM and ironic hosts, + // so the KPI returns every host present in the knowledge unchanged. + hostDetails := []compute.VMwareHostDetails{ + {ComputeHost: "nova-compute-1"}, + {ComputeHost: "nova-compute-2"}, } client := buildHostCapacityClient(t, hostDetails, nil) @@ -155,14 +155,14 @@ func TestVMwareHostCapacityKPI_getHostUtilizations(t *testing.T) { func TestVMwareHostCapacityKPI_Collect(t *testing.T) { tests := []struct { name string - hostDetails []compute.HostDetails + hostDetails []compute.VMwareHostDetails utilizations []compute.HostUtilization expectedMetrics []collectedVMwareMetric }{ { name: "single host emits usage and total metrics", - hostDetails: []compute.HostDetails{ - {ComputeHost: "nova-compute-1", HypervisorFamily: hypervisorFamilyVMware, AvailabilityZone: "az1"}, + hostDetails: []compute.VMwareHostDetails{ + {ComputeHost: "nova-compute-1", AvailabilityZone: "az1"}, }, utilizations: []compute.HostUtilization{ { @@ -186,9 +186,9 @@ func TestVMwareHostCapacityKPI_Collect(t *testing.T) { }, { name: "multiple hosts each emit their own metrics", - hostDetails: []compute.HostDetails{ - {ComputeHost: "nova-compute-1", HypervisorFamily: hypervisorFamilyVMware, AvailabilityZone: "az1"}, - {ComputeHost: "nova-compute-2", HypervisorFamily: hypervisorFamilyVMware, AvailabilityZone: "az2"}, + hostDetails: []compute.VMwareHostDetails{ + {ComputeHost: "nova-compute-1", AvailabilityZone: "az1"}, + {ComputeHost: "nova-compute-2", AvailabilityZone: "az2"}, }, utilizations: []compute.HostUtilization{ {ComputeHost: "nova-compute-1", VCPUsUsed: 2, TotalVCPUsAllocatable: 8, RAMUsedMB: 512, TotalRAMAllocatableMB: 2048, DiskUsedGB: 10, TotalDiskAllocatableGB: 100}, @@ -209,56 +209,18 @@ func TestVMwareHostCapacityKPI_Collect(t *testing.T) { {Name: "cortex_vmware_host_capacity_total", Labels: hostCapacityLabels("nova-compute-2", "az2", "disk"), Value: 200 * 1024 * 1024 * 1024}, }, }, - { - name: "ironic hosts are excluded", - hostDetails: []compute.HostDetails{ - {ComputeHost: "nova-compute-1", HypervisorFamily: hypervisorFamilyVMware, AvailabilityZone: "az1"}, - {ComputeHost: "nova-compute-ironic-1", HypervisorType: vmwareIronicHypervisorType, HypervisorFamily: hypervisorFamilyVMware, AvailabilityZone: "az1"}, - }, - utilizations: []compute.HostUtilization{ - {ComputeHost: "nova-compute-1", VCPUsUsed: 2, TotalVCPUsAllocatable: 8, RAMUsedMB: 512, TotalRAMAllocatableMB: 2048, DiskUsedGB: 10, TotalDiskAllocatableGB: 100}, - {ComputeHost: "nova-compute-ironic-1", VCPUsUsed: 4, TotalVCPUsAllocatable: 16, RAMUsedMB: 1024, TotalRAMAllocatableMB: 4096, DiskUsedGB: 20, TotalDiskAllocatableGB: 200}, - }, - expectedMetrics: []collectedVMwareMetric{ - {Name: "cortex_vmware_host_capacity_usage", Labels: hostCapacityLabels("nova-compute-1", "az1", "cpu"), Value: 2}, - {Name: "cortex_vmware_host_capacity_usage", Labels: hostCapacityLabels("nova-compute-1", "az1", "ram"), Value: 512 * 1024 * 1024}, - {Name: "cortex_vmware_host_capacity_usage", Labels: hostCapacityLabels("nova-compute-1", "az1", "disk"), Value: 10 * 1024 * 1024 * 1024}, - {Name: "cortex_vmware_host_capacity_total", Labels: hostCapacityLabels("nova-compute-1", "az1", "cpu"), Value: 8}, - {Name: "cortex_vmware_host_capacity_total", Labels: hostCapacityLabels("nova-compute-1", "az1", "ram"), Value: 2048 * 1024 * 1024}, - {Name: "cortex_vmware_host_capacity_total", Labels: hostCapacityLabels("nova-compute-1", "az1", "disk"), Value: 100 * 1024 * 1024 * 1024}, - }, - }, - { - name: "non-vmware hosts are excluded", - hostDetails: []compute.HostDetails{ - {ComputeHost: "nova-compute-1", HypervisorFamily: hypervisorFamilyVMware, AvailabilityZone: "az1"}, - {ComputeHost: "nova-compute-2", HypervisorFamily: "kvm", AvailabilityZone: "az1"}, - }, - utilizations: []compute.HostUtilization{ - {ComputeHost: "nova-compute-1", VCPUsUsed: 2, TotalVCPUsAllocatable: 8, RAMUsedMB: 512, TotalRAMAllocatableMB: 2048, DiskUsedGB: 10, TotalDiskAllocatableGB: 100}, - {ComputeHost: "nova-compute-2", VCPUsUsed: 4, TotalVCPUsAllocatable: 16, RAMUsedMB: 1024, TotalRAMAllocatableMB: 4096, DiskUsedGB: 20, TotalDiskAllocatableGB: 200}, - }, - expectedMetrics: []collectedVMwareMetric{ - {Name: "cortex_vmware_host_capacity_usage", Labels: hostCapacityLabels("nova-compute-1", "az1", "cpu"), Value: 2}, - {Name: "cortex_vmware_host_capacity_usage", Labels: hostCapacityLabels("nova-compute-1", "az1", "ram"), Value: 512 * 1024 * 1024}, - {Name: "cortex_vmware_host_capacity_usage", Labels: hostCapacityLabels("nova-compute-1", "az1", "disk"), Value: 10 * 1024 * 1024 * 1024}, - {Name: "cortex_vmware_host_capacity_total", Labels: hostCapacityLabels("nova-compute-1", "az1", "cpu"), Value: 8}, - {Name: "cortex_vmware_host_capacity_total", Labels: hostCapacityLabels("nova-compute-1", "az1", "ram"), Value: 2048 * 1024 * 1024}, - {Name: "cortex_vmware_host_capacity_total", Labels: hostCapacityLabels("nova-compute-1", "az1", "disk"), Value: 100 * 1024 * 1024 * 1024}, - }, - }, { name: "host without matching utilization produces no metrics", - hostDetails: []compute.HostDetails{ - {ComputeHost: "nova-compute-1", HypervisorFamily: hypervisorFamilyVMware, AvailabilityZone: "az1"}, + hostDetails: []compute.VMwareHostDetails{ + {ComputeHost: "nova-compute-1", AvailabilityZone: "az1"}, }, utilizations: []compute.HostUtilization{}, expectedMetrics: []collectedVMwareMetric{}, }, { name: "utilization with zero allocatable resources is skipped", - hostDetails: []compute.HostDetails{ - {ComputeHost: "nova-compute-1", HypervisorFamily: hypervisorFamilyVMware, AvailabilityZone: "az1"}, + hostDetails: []compute.VMwareHostDetails{ + {ComputeHost: "nova-compute-1", AvailabilityZone: "az1"}, }, utilizations: []compute.HostUtilization{ {ComputeHost: "nova-compute-1", VCPUsUsed: 2, TotalVCPUsAllocatable: 0, RAMUsedMB: 512, TotalRAMAllocatableMB: 2048, DiskUsedGB: 10, TotalDiskAllocatableGB: 100}, @@ -267,7 +229,7 @@ func TestVMwareHostCapacityKPI_Collect(t *testing.T) { }, { name: "no hosts produces no metrics", - hostDetails: []compute.HostDetails{}, + hostDetails: []compute.VMwareHostDetails{}, utilizations: []compute.HostUtilization{}, expectedMetrics: []collectedVMwareMetric{}, }, diff --git a/internal/knowledge/kpis/plugins/infrastructure/vmware_project_utilization.go b/internal/knowledge/kpis/plugins/infrastructure/vmware_project_utilization.go index 6a85756ff..2459cb4c6 100644 --- a/internal/knowledge/kpis/plugins/infrastructure/vmware_project_utilization.go +++ b/internal/knowledge/kpis/plugins/infrastructure/vmware_project_utilization.go @@ -128,21 +128,18 @@ func (k *VMwareProjectUtilizationKPI) Collect(ch chan<- prometheus.Metric) { // getVMwareHosts retrieves the mapping of VMware hypervisors to their corresponding host information func (k *VMwareProjectUtilizationKPI) getVMwareHosts() (map[string]vmwareHost, error) { knowledge := &v1alpha1.Knowledge{} - if err := k.Client.Get(context.Background(), client.ObjectKey{Name: hostDetailsKnowledgeName}, knowledge); err != nil { + if err := k.Client.Get(context.Background(), client.ObjectKey{Name: vmwareHostDetailsKnowledgeName}, knowledge); err != nil { return nil, err } - hostDetails, err := v1alpha1.UnboxFeatureList[compute.HostDetails](knowledge.Status.Raw) + hostDetails, err := v1alpha1.UnboxFeatureList[compute.VMwareHostDetails](knowledge.Status.Raw) if err != nil { return nil, err } hostMapping := make(map[string]vmwareHost) for _, host := range hostDetails { - if host.HypervisorType == vmwareIronicHypervisorType || host.HypervisorFamily != hypervisorFamilyVMware { - continue - } - hostMapping[host.ComputeHost] = vmwareHost{HostDetails: host} + hostMapping[host.ComputeHost] = vmwareHost{VMwareHostDetails: host} } return hostMapping, nil diff --git a/internal/knowledge/kpis/plugins/infrastructure/vmware_project_utilization_test.go b/internal/knowledge/kpis/plugins/infrastructure/vmware_project_utilization_test.go index 15f18b894..6edd47e0c 100644 --- a/internal/knowledge/kpis/plugins/infrastructure/vmware_project_utilization_test.go +++ b/internal/knowledge/kpis/plugins/infrastructure/vmware_project_utilization_test.go @@ -53,7 +53,7 @@ func capacityMetric(computeHost, az, projectID, projectName, domainID, domainNam return collectedVMwareMetric{Name: "cortex_vmware_project_capacity_usage", Labels: labels, Value: value} } -func buildVMwareHostDetailsClient(t *testing.T, hostDetails []compute.HostDetails) *fake.ClientBuilder { +func buildVMwareHostDetailsClient(t *testing.T, hostDetails []compute.VMwareHostDetails) *fake.ClientBuilder { t.Helper() scheme, err := v1alpha1.SchemeBuilder.Build() if err != nil { @@ -65,7 +65,7 @@ func buildVMwareHostDetailsClient(t *testing.T, hostDetails []compute.HostDetail } return fake.NewClientBuilder().WithScheme(scheme).WithRuntimeObjects( &v1alpha1.Knowledge{ - ObjectMeta: v1.ObjectMeta{Name: "host-details"}, + ObjectMeta: v1.ObjectMeta{Name: vmwareHostDetailsKnowledgeName}, Status: v1alpha1.KnowledgeStatus{Raw: raw}, }, ) @@ -82,24 +82,11 @@ func TestVMwareProjectUtilizationKPI_Init(t *testing.T) { } func TestVMwareProjectUtilizationKPI_getVMwareHosts(t *testing.T) { - hostDetails := []compute.HostDetails{ - { - ComputeHost: "nova-compute-1", - HypervisorFamily: hypervisorFamilyVMware, - }, - { - ComputeHost: "nova-compute-2", - HypervisorFamily: hypervisorFamilyVMware, - }, - { - ComputeHost: "nova-compute-ironic-1", - HypervisorType: vmwareIronicHypervisorType, - HypervisorFamily: hypervisorFamilyVMware, - }, - { - ComputeHost: "nova-compute-3", - HypervisorFamily: "other", - }, + // Filtering of KVM and ironic hosts happens in the extractor SQL, so the KPI + // maps every host present in the knowledge. + hostDetails := []compute.VMwareHostDetails{ + {ComputeHost: "nova-compute-1"}, + {ComputeHost: "nova-compute-2"}, } clientBuilder := buildVMwareHostDetailsClient(t, hostDetails) @@ -112,8 +99,8 @@ func TestVMwareProjectUtilizationKPI_getVMwareHosts(t *testing.T) { } expectedHosts := map[string]vmwareHost{ - "nova-compute-1": {HostDetails: hostDetails[0]}, - "nova-compute-2": {HostDetails: hostDetails[1]}, + "nova-compute-1": {VMwareHostDetails: hostDetails[0]}, + "nova-compute-2": {VMwareHostDetails: hostDetails[1]}, } if len(hostMapping) != len(expectedHosts) { @@ -125,7 +112,7 @@ func TestVMwareProjectUtilizationKPI_getVMwareHosts(t *testing.T) { if !ok { t.Fatalf("expected host %s not found in mapping", computeHost) } - if host.ComputeHost != expectedHost.ComputeHost || host.HypervisorFamily != expectedHost.HypervisorFamily { + if host.ComputeHost != expectedHost.ComputeHost { t.Errorf("host details mismatch for %s: expected %+v, got %+v", computeHost, expectedHost, host) } } @@ -272,7 +259,7 @@ func TestVMwareProjectUtilizationKPI_queryProjectInstanceCount(t *testing.T) { } } - client := buildVMwareHostDetailsClient(t, []compute.HostDetails{}) + client := buildVMwareHostDetailsClient(t, []compute.VMwareHostDetails{}) kpi := &VMwareProjectUtilizationKPI{} if err := kpi.Init(&testDB, client.Build(), conf.NewRawOpts("{}")); err != nil { t.Fatalf("expected no error on Init, got %v", err) @@ -468,7 +455,7 @@ func TestVMwareProjectUtilizationKPI_queryProjectCapacityUsage(t *testing.T) { } } - client := buildVMwareHostDetailsClient(t, []compute.HostDetails{}) + client := buildVMwareHostDetailsClient(t, []compute.VMwareHostDetails{}) kpi := &VMwareProjectUtilizationKPI{} if err := kpi.Init(&testDB, client.Build(), conf.NewRawOpts("{}")); err != nil { t.Fatalf("expected no error on Init, got %v", err) @@ -503,7 +490,7 @@ func TestVMwareProjectUtilizationKPI_Collect(t *testing.T) { projects []identity.Project domains []identity.Domain flavors []nova.Flavor - hostDetails []compute.HostDetails + hostDetails []compute.VMwareHostDetails expectedMetrics []collectedVMwareMetric }{ { @@ -514,8 +501,8 @@ func TestVMwareProjectUtilizationKPI_Collect(t *testing.T) { projects: []identity.Project{{ID: "project-1", Name: "Project One", DomainID: "domain-1"}}, domains: []identity.Domain{{ID: "domain-1", Name: "Domain One"}}, flavors: []nova.Flavor{{ID: "f1", Name: "flavor-1", VCPUs: 2, RAM: 4096, Disk: 1}}, - hostDetails: []compute.HostDetails{ - {ComputeHost: "nova-compute-1", HypervisorFamily: hypervisorFamilyVMware, AvailabilityZone: "az1"}, + hostDetails: []compute.VMwareHostDetails{ + {ComputeHost: "nova-compute-1", AvailabilityZone: "az1"}, }, expectedMetrics: []collectedVMwareMetric{ instanceMetric("nova-compute-1", "az1", "project-1", "Project One", "domain-1", "Domain One", "flavor-1", 1), @@ -540,9 +527,9 @@ func TestVMwareProjectUtilizationKPI_Collect(t *testing.T) { {ID: "f1", Name: "flavor-1", VCPUs: 2, RAM: 4096, Disk: 1}, {ID: "f2", Name: "flavor-2", VCPUs: 4, RAM: 8192, Disk: 2}, }, - hostDetails: []compute.HostDetails{ - {ComputeHost: "nova-compute-1", HypervisorFamily: hypervisorFamilyVMware, AvailabilityZone: "az1"}, - {ComputeHost: "nova-compute-2", HypervisorFamily: hypervisorFamilyVMware, AvailabilityZone: "az2"}, + hostDetails: []compute.VMwareHostDetails{ + {ComputeHost: "nova-compute-1", AvailabilityZone: "az1"}, + {ComputeHost: "nova-compute-2", AvailabilityZone: "az2"}, }, expectedMetrics: []collectedVMwareMetric{ instanceMetric("nova-compute-1", "az1", "project-1", "Project One", "domain-1", "Domain One", "flavor-1", 1), @@ -568,8 +555,8 @@ func TestVMwareProjectUtilizationKPI_Collect(t *testing.T) { projects: []identity.Project{{ID: "project-1", Name: "Project One", DomainID: "domain-1"}}, domains: []identity.Domain{{ID: "domain-1", Name: "Domain One"}}, flavors: []nova.Flavor{{ID: "f1", Name: "flavor-1", VCPUs: 2, RAM: 4096, Disk: 1}}, - hostDetails: []compute.HostDetails{ - {ComputeHost: "nova-compute-1", HypervisorFamily: hypervisorFamilyVMware, AvailabilityZone: "az1"}, + hostDetails: []compute.VMwareHostDetails{ + {ComputeHost: "nova-compute-1", AvailabilityZone: "az1"}, }, expectedMetrics: []collectedVMwareMetric{ instanceMetric("nova-compute-1", "az1", "project-1", "Project One", "domain-1", "Domain One", "flavor-1", 1), @@ -592,8 +579,8 @@ func TestVMwareProjectUtilizationKPI_Collect(t *testing.T) { {ID: "f2", Name: "flavor-2", VCPUs: 4, RAM: 8192, Disk: 2}, {ID: "f3", Name: "flavor-3", VCPUs: 8, RAM: 16384, Disk: 4}, }, - hostDetails: []compute.HostDetails{ - {ComputeHost: "nova-compute-1", HypervisorFamily: hypervisorFamilyVMware, AvailabilityZone: "az1"}, + hostDetails: []compute.VMwareHostDetails{ + {ComputeHost: "nova-compute-1", AvailabilityZone: "az1"}, }, expectedMetrics: []collectedVMwareMetric{ instanceMetric("nova-compute-1", "az1", "project-1", "Project One", "domain-1", "Domain One", "flavor-3", 1), @@ -613,9 +600,9 @@ func TestVMwareProjectUtilizationKPI_Collect(t *testing.T) { projects: []identity.Project{{ID: "project-1", Name: "Project One", DomainID: "domain-1"}}, domains: []identity.Domain{{ID: "domain-1", Name: "Domain One"}}, flavors: []nova.Flavor{{ID: "f1", Name: "flavor-1", VCPUs: 2, RAM: 4096, Disk: 1}}, - hostDetails: []compute.HostDetails{ - {ComputeHost: "nova-compute-1", HypervisorFamily: hypervisorFamilyVMware, AvailabilityZone: "az1"}, - {ComputeHost: "nova-compute-2", HypervisorFamily: hypervisorFamilyVMware, AvailabilityZone: "az2"}, + hostDetails: []compute.VMwareHostDetails{ + {ComputeHost: "nova-compute-1", AvailabilityZone: "az1"}, + {ComputeHost: "nova-compute-2", AvailabilityZone: "az2"}, }, expectedMetrics: []collectedVMwareMetric{ instanceMetric("nova-compute-1", "az1", "project-1", "Project One", "domain-1", "Domain One", "flavor-1", 2), @@ -636,8 +623,8 @@ func TestVMwareProjectUtilizationKPI_Collect(t *testing.T) { projects: []identity.Project{{ID: "project-1", Name: "Project One", DomainID: "domain-unknown"}}, domains: []identity.Domain{}, flavors: []nova.Flavor{{ID: "f1", Name: "flavor-1", VCPUs: 2, RAM: 4096, Disk: 1}}, - hostDetails: []compute.HostDetails{ - {ComputeHost: "nova-compute-1", HypervisorFamily: hypervisorFamilyVMware, AvailabilityZone: "az1"}, + hostDetails: []compute.VMwareHostDetails{ + {ComputeHost: "nova-compute-1", AvailabilityZone: "az1"}, }, expectedMetrics: []collectedVMwareMetric{ // The domain_id is extracted from the project record, so it should be "domain-unknown" even though there is no matching domain entry @@ -655,8 +642,8 @@ func TestVMwareProjectUtilizationKPI_Collect(t *testing.T) { projects: []identity.Project{}, domains: []identity.Domain{}, flavors: []nova.Flavor{{ID: "f1", Name: "flavor-1", VCPUs: 2, RAM: 4096, Disk: 1}}, - hostDetails: []compute.HostDetails{ - {ComputeHost: "nova-compute-1", HypervisorFamily: hypervisorFamilyVMware, AvailabilityZone: "az1"}, + hostDetails: []compute.VMwareHostDetails{ + {ComputeHost: "nova-compute-1", AvailabilityZone: "az1"}, }, expectedMetrics: []collectedVMwareMetric{ instanceMetric("nova-compute-1", "az1", "project-1", "", "", "", "flavor-1", 1), @@ -673,8 +660,8 @@ func TestVMwareProjectUtilizationKPI_Collect(t *testing.T) { projects: []identity.Project{{ID: "project-1", Name: "Project One", DomainID: "domain-1"}}, domains: []identity.Domain{{ID: "domain-1", Name: "Domain One"}}, flavors: []nova.Flavor{}, - hostDetails: []compute.HostDetails{ - {ComputeHost: "nova-compute-1", HypervisorFamily: hypervisorFamilyVMware, AvailabilityZone: "az1"}, + hostDetails: []compute.VMwareHostDetails{ + {ComputeHost: "nova-compute-1", AvailabilityZone: "az1"}, }, expectedMetrics: []collectedVMwareMetric{ instanceMetric("nova-compute-1", "az1", "project-1", "Project One", "domain-1", "Domain One", "flavor-missing", 1), @@ -693,8 +680,8 @@ func TestVMwareProjectUtilizationKPI_Collect(t *testing.T) { flavors: []nova.Flavor{ {ID: "f1", Name: "flavor-1", VCPUs: 2, RAM: 4096, Disk: 1}, }, - hostDetails: []compute.HostDetails{ - {ComputeHost: "nova-compute-1", HypervisorFamily: hypervisorFamilyVMware, AvailabilityZone: "az1"}, + hostDetails: []compute.VMwareHostDetails{ + {ComputeHost: "nova-compute-1", AvailabilityZone: "az1"}, }, expectedMetrics: []collectedVMwareMetric{}, },