Skip to content

Commit dbf58b5

Browse files
committed
Allow recovering hardware details from existing HardwareData
This allows external inspection without an annotation. Signed-off-by: Dmitry Tantsur <[email protected]>
1 parent 064bc7a commit dbf58b5

File tree

2 files changed

+87
-6
lines changed

2 files changed

+87
-6
lines changed

internal/controller/metal3.io/baremetalhost_controller.go

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -274,17 +274,31 @@ func (r *BareMetalHostReconciler) Reconcile(ctx context.Context, request ctrl.Re
274274
func (r *BareMetalHostReconciler) updateHardwareDetails(ctx context.Context, request ctrl.Request, host *metal3api.BareMetalHost) (bool, error) {
275275
updated := false
276276
if host.Status.HardwareDetails == nil || host.InspectionDisabled() {
277-
objHardwareDetails, err := r.getHardwareDetailsFromAnnotation(host)
278-
if err != nil {
279-
return updated, fmt.Errorf("error parsing HardwareDetails from annotation: %w", err)
277+
hardwareData := &metal3api.HardwareData{}
278+
hardwareDataKey := client.ObjectKey{
279+
Name: host.Name,
280+
Namespace: host.Namespace,
281+
}
282+
err := r.Client.Get(ctx, hardwareDataKey, hardwareData)
283+
if err != nil && !k8serrors.IsNotFound(err) {
284+
return updated, fmt.Errorf("error loading HardwareData: %w", err)
280285
}
281-
if objHardwareDetails != nil {
286+
objHardwareDetails := hardwareData.Spec.HardwareDetails
287+
288+
if objHardwareDetails == nil {
289+
objHardwareDetails, err = r.getHardwareDetailsFromAnnotation(host)
290+
if err != nil {
291+
return updated, fmt.Errorf("error parsing HardwareDetails from annotation: %w", err)
292+
}
293+
}
294+
295+
if objHardwareDetails != nil && !reflect.DeepEqual(host.Status.HardwareDetails, objHardwareDetails) {
282296
host.Status.HardwareDetails = objHardwareDetails
283297
err = r.saveHostStatus(ctx, host)
284298
if err != nil {
285-
return updated, fmt.Errorf("could not update hardwaredetails from annotation: %w", err)
299+
return updated, fmt.Errorf("could not update hardwaredetails from existing hardware data or annotation: %w", err)
286300
}
287-
r.publishEvent(ctx, request, host.NewEvent("UpdateHardwareDetails", "Set HardwareDetails from annotation"))
301+
r.publishEvent(ctx, request, host.NewEvent("UpdateHardwareDetails", "Set HardwareDetails from hardware data or annotation"))
288302
updated = true
289303
}
290304
}

internal/controller/metal3.io/baremetalhost_controller_test.go

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,36 @@ func TestHardwareDetails_EmptyStatus(t *testing.T) {
274274
)
275275
}
276276

277+
// TestHardwareDetails_FromHardwareData ensures that hardware details in
278+
// the status field are populated when the HardwareData object
279+
// is present and no existing HarwareDetails are present.
280+
func TestHardwareDetails_FromHardwareData(t *testing.T) {
281+
host := newDefaultHost(t)
282+
hwdata := &metal3api.HardwareData{
283+
ObjectMeta: metav1.ObjectMeta{
284+
Name: host.Name,
285+
Namespace: host.Namespace,
286+
},
287+
Spec: metal3api.HardwareDataSpec{
288+
HardwareDetails: &metal3api.HardwareDetails{},
289+
},
290+
}
291+
err := json.Unmarshal([]byte(hwdAnnotation), hwdata.Spec.HardwareDetails)
292+
require.NoError(t, err)
293+
294+
r := newTestReconciler(t, host, hwdata)
295+
296+
tryReconcile(t, r, host,
297+
func(host *metal3api.BareMetalHost, result reconcile.Result) bool {
298+
_, found := host.Annotations[metal3api.HardwareDetailsAnnotation]
299+
if host.Status.HardwareDetails != nil && host.Status.HardwareDetails.Hostname == "hwdAnnotation-0" && !found {
300+
return true
301+
}
302+
return false
303+
},
304+
)
305+
}
306+
277307
// TestHardwareDetails_StatusPresent ensures that hardware details in
278308
// the hardwaredetails annotation is ignored with existing Status.
279309
func TestHardwareDetails_StatusPresent(t *testing.T) {
@@ -328,6 +358,43 @@ func TestHardwareDetails_StatusPresentInspectDisabled(t *testing.T) {
328358
)
329359
}
330360

361+
// TestHardwareDetails_StatusPresentInspectDisabled ensures that
362+
// hardware details in the HardwareData object are consumed
363+
// even when existing status exists, when inspection is disabled.
364+
func TestHardwareDetails_HardwareDataStatusPresentInspectDisabled(t *testing.T) {
365+
host := newDefaultHost(t)
366+
host.Spec.InspectionMode = metal3api.InspectionModeDisabled
367+
time := metav1.Now()
368+
host.Status.LastUpdated = &time
369+
hwd := metal3api.HardwareDetails{}
370+
hwd.Hostname = "existinghost"
371+
host.Status.HardwareDetails = &hwd
372+
373+
hwdata := &metal3api.HardwareData{
374+
ObjectMeta: metav1.ObjectMeta{
375+
Name: host.Name,
376+
Namespace: host.Namespace,
377+
},
378+
Spec: metal3api.HardwareDataSpec{
379+
HardwareDetails: &metal3api.HardwareDetails{},
380+
},
381+
}
382+
err := json.Unmarshal([]byte(hwdAnnotation), hwdata.Spec.HardwareDetails)
383+
require.NoError(t, err)
384+
385+
r := newTestReconciler(t, host, hwdata)
386+
387+
tryReconcile(t, r, host,
388+
func(host *metal3api.BareMetalHost, result reconcile.Result) bool {
389+
_, found := host.Annotations[metal3api.HardwareDetailsAnnotation]
390+
if host.Status.HardwareDetails != nil && host.Status.HardwareDetails.Hostname == "hwdAnnotation-0" && !found {
391+
return true
392+
}
393+
return false
394+
},
395+
)
396+
}
397+
331398
// TestHardwareDetails_Invalid
332399
// Tests scenario where the hardwaredetails value is invalid.
333400
func TestHardwareDetails_Invalid(t *testing.T) {

0 commit comments

Comments
 (0)