Skip to content

Commit df03a82

Browse files
authored
Added host details check for status disabled and trait COMPUTE_STATUS_DISABLED (#242)
- Disable hypervisor with `openstack_hypervisor.status != 'enabled'` - Disable hypervisor with trait `COMPUTE_STATUS_DISABLED` - Added left join to also include hosts without a resource provider (is this even possible, just noticed while adjusting the test?)
1 parent 393ed29 commit df03a82

File tree

3 files changed

+1228
-244
lines changed

3 files changed

+1228
-244
lines changed

internal/extractor/plugins/sap/host_details.sql

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,13 @@ WITH host_traits AS (
44
h.hypervisor_type,
55
h.running_vms,
66
h.state,
7+
h.status,
8+
h.service_disabled_reason,
79
STRING_AGG(t.name, ',') AS traits
810
FROM openstack_hypervisors h
9-
JOIN openstack_resource_provider_traits t
11+
LEFT JOIN openstack_resource_provider_traits t
1012
ON h.id = t.resource_provider_uuid
11-
GROUP BY h.service_host, h.hypervisor_type, h.running_vms, h.state
13+
GROUP BY h.service_host, h.hypervisor_type, h.running_vms, h.state, h.status, h.service_disabled_reason
1214
)
1315
SELECT
1416
ht.service_host AS compute_host,
@@ -33,13 +35,17 @@ SELECT
3335
CASE
3436
WHEN ht.traits LIKE '%CUSTOM_DECOMMISSIONING%' THEN false
3537
WHEN ht.traits LIKE '%CUSTOM_EXTERNAL_CUSTOMER_SUPPORTED%' THEN false
38+
WHEN ht.traits LIKE '%COMPUTE_STATUS_DISABLED%' THEN false
39+
WHEN ht.status != 'enabled' THEN false
3640
WHEN ht.state != 'up' THEN false
3741
ELSE true
3842
END AS enabled,
3943
CASE
4044
WHEN ht.traits LIKE '%CUSTOM_DECOMMISSIONING%' THEN 'decommissioning'
4145
WHEN ht.traits LIKE '%CUSTOM_EXTERNAL_CUSTOMER_SUPPORTED%' THEN 'external customer'
42-
WHEN ht.state != 'up' THEN 'not up'
46+
WHEN ht.traits LIKE '%COMPUTE_STATUS_DISABLED%' THEN '[compute status disabled trait] ' || COALESCE(ht.service_disabled_reason, '--')
47+
WHEN ht.status != 'enabled' THEN '[status: not enabled] ' || COALESCE(ht.service_disabled_reason, '--')
48+
WHEN ht.state != 'up' THEN '[state: not up] ' || COALESCE(ht.service_disabled_reason, '--')
4349
ELSE NULL
4450
END AS disabled_reason
4551
FROM host_traits ht

internal/extractor/plugins/sap/host_details_test.go

Lines changed: 40 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -51,16 +51,22 @@ func TestHostDetailsExtractor_Extract(t *testing.T) {
5151
t.Fatalf("expected no error, got %v", err)
5252
}
5353

54+
exampleServiceDisabledReason := "example reason"
55+
5456
// Insert mock data into the hypervisors and traits tables
5557
hypervisors := []any{
5658
// VMware host
57-
&nova.Hypervisor{ID: "uuid1", ServiceHost: "nova-compute-bb01", HypervisorType: "vcenter", RunningVMs: 5, State: "up"},
59+
&nova.Hypervisor{ID: "uuid1", ServiceHost: "nova-compute-bb01", HypervisorType: "vcenter", RunningVMs: 5, State: "up", Status: "enabled"},
5860
// KVM host
59-
&nova.Hypervisor{ID: "uuid2", ServiceHost: "node001-bb02", HypervisorType: "qemu", RunningVMs: 3, State: "down"},
61+
&nova.Hypervisor{ID: "uuid2", ServiceHost: "node001-bb02", HypervisorType: "qemu", RunningVMs: 3, State: "down", Status: "enabled"},
6062
// Ironic host (should be skipped)
61-
&nova.Hypervisor{ID: "uuid3", ServiceHost: "ironic-host-01", HypervisorType: "ironic", RunningVMs: 0, State: "up"},
63+
&nova.Hypervisor{ID: "uuid3", ServiceHost: "ironic-host-01", HypervisorType: "ironic", RunningVMs: 0, State: "up", Status: "enabled"},
6264
// Host with no special traits
63-
&nova.Hypervisor{ID: "uuid4", ServiceHost: "node002-bb03", HypervisorType: "test", RunningVMs: 2, State: "up"},
65+
&nova.Hypervisor{ID: "uuid4", ServiceHost: "node002-bb03", HypervisorType: "test", RunningVMs: 2, State: "up", Status: "enabled"},
66+
// Host with disabled status, no entry in the resource providers
67+
&nova.Hypervisor{ID: "uuid5", ServiceHost: "node003-bb03", HypervisorType: "test", RunningVMs: 2, State: "up", Status: "disabled", ServiceDisabledReason: &exampleServiceDisabledReason},
68+
// Host with disabled trait
69+
&nova.Hypervisor{ID: "uuid6", ServiceHost: "node004-bb03", HypervisorType: "test", RunningVMs: 2, State: "up", Status: "enabled", ServiceDisabledReason: &exampleServiceDisabledReason},
6470
}
6571

6672
if err := testDB.Insert(hypervisors...); err != nil {
@@ -74,10 +80,12 @@ func TestHostDetailsExtractor_Extract(t *testing.T) {
7480
&placement.Trait{ResourceProviderUUID: "uuid1", Name: "CUSTOM_EXTERNAL_CUSTOMER_SUPPORTED"},
7581
// KVM host traits
7682
&placement.Trait{ResourceProviderUUID: "uuid2", Name: "CUSTOM_NUMASIZE_C48_M729"},
77-
// Ironic host traits (should be ignored)
83+
// Ironic host traits
7884
&placement.Trait{ResourceProviderUUID: "uuid3", Name: "TRAIT_IGNORED"},
7985
// Disabled KVM host
8086
&placement.Trait{ResourceProviderUUID: "uuid4", Name: "CUSTOM_DECOMMISSIONING"},
87+
// Host with disabled trait
88+
&placement.Trait{ResourceProviderUUID: "uuid6", Name: "COMPUTE_STATUS_DISABLED"},
8189
}
8290

8391
if err := testDB.Insert(traits...); err != nil {
@@ -92,6 +100,8 @@ func TestHostDetailsExtractor_Extract(t *testing.T) {
92100
&shared.HostAZ{AvailabilityZone: nil, ComputeHost: "node001-bb02"},
93101
&shared.HostAZ{AvailabilityZone: &availabilityZone2, ComputeHost: "node002-bb03"},
94102
&shared.HostAZ{AvailabilityZone: &availabilityZone2, ComputeHost: "ironic-host-01"},
103+
&shared.HostAZ{AvailabilityZone: &availabilityZone2, ComputeHost: "node003-bb03"},
104+
&shared.HostAZ{AvailabilityZone: &availabilityZone2, ComputeHost: "node004-bb03"},
95105
}
96106

97107
if err := testDB.Insert(hostAvailabilityZones...); err != nil {
@@ -117,15 +127,6 @@ func TestHostDetailsExtractor_Extract(t *testing.T) {
117127
t.Fatalf("expected no error from Extract, got %v", err)
118128
}
119129

120-
// Only non-ironic hosts should be present
121-
if len(hostDetails) != 4 {
122-
t.Fatalf("expected 4 host details, got %d", len(hostDetails))
123-
}
124-
125-
disabledReasonExternal := "external customer"
126-
disabledReasonDecommissioning := "decommissioning"
127-
disabledReasonStateNotUp := "not up"
128-
129130
expected := []HostDetails{
130131
{
131132
ComputeHost: "nova-compute-bb01",
@@ -135,7 +136,7 @@ func TestHostDetailsExtractor_Extract(t *testing.T) {
135136
HypervisorFamily: "vmware",
136137
WorkloadType: "hana",
137138
Enabled: false,
138-
DisabledReason: &disabledReasonExternal,
139+
DisabledReason: &[]string{"external customer"}[0],
139140
RunningVMs: 5,
140141
},
141142
{
@@ -146,7 +147,7 @@ func TestHostDetailsExtractor_Extract(t *testing.T) {
146147
HypervisorFamily: "kvm",
147148
WorkloadType: "general-purpose",
148149
Enabled: false,
149-
DisabledReason: &disabledReasonStateNotUp,
150+
DisabledReason: &[]string{"[state: not up] --"}[0],
150151
RunningVMs: 3,
151152
},
152153
{
@@ -157,7 +158,7 @@ func TestHostDetailsExtractor_Extract(t *testing.T) {
157158
HypervisorType: "test",
158159
WorkloadType: "general-purpose",
159160
Enabled: false,
160-
DisabledReason: &disabledReasonDecommissioning,
161+
DisabledReason: &[]string{"decommissioning"}[0],
161162
RunningVMs: 2,
162163
},
163164
{
@@ -171,6 +172,28 @@ func TestHostDetailsExtractor_Extract(t *testing.T) {
171172
DisabledReason: nil,
172173
RunningVMs: 0,
173174
},
175+
{
176+
ComputeHost: "node003-bb03",
177+
AvailabilityZone: "az2",
178+
CPUArchitecture: "unknown",
179+
HypervisorType: "test",
180+
HypervisorFamily: "kvm",
181+
WorkloadType: "general-purpose",
182+
Enabled: false,
183+
DisabledReason: &[]string{"[status: not enabled] " + exampleServiceDisabledReason}[0],
184+
RunningVMs: 2,
185+
},
186+
{
187+
ComputeHost: "node004-bb03",
188+
AvailabilityZone: "az2",
189+
CPUArchitecture: "unknown",
190+
HypervisorType: "test",
191+
HypervisorFamily: "kvm",
192+
WorkloadType: "general-purpose",
193+
Enabled: false,
194+
DisabledReason: &[]string{"[compute status disabled trait] " + exampleServiceDisabledReason}[0],
195+
RunningVMs: 2,
196+
},
174197
}
175198

176199
// Map the host details by compute host name for easier comparison

0 commit comments

Comments
 (0)