Repository: metal3-io/baremetal-operator
Pull request #787 (2021-02-04 16:44:22)

Add inspect.metal3.io=disabled annotation
When inspect.metal3.io=disabled is specified as an annotation we skip
inspection and return complete immediately from the Inspecting state.

Partially-Implements: https://github.com/metal3-io/metal3-docs/pull/155


Patch:
diff --git a/controllers/metal3.io/baremetalhost_controller.go b/controllers/metal3.io/baremetalhost_controller.go
index 9e83904e..d6ebdf55 100644
--- a/controllers/metal3.io/baremetalhost_controller.go
+++ b/controllers/metal3.io/baremetalhost_controller.go
@@ -51,6 +51,7 @@ const (
 	unmanagedRetryDelay           = time.Minute * 10
 	provisionerNotReadyRetryDelay = time.Second * 30
 	rebootAnnotationPrefix        = "reboot.metal3.io"
+	inspectAnnotationPrefix       = "inspect.metal3.io"
 )
 
 // BareMetalHostReconciler reconciles a BareMetalHost object
@@ -364,6 +365,16 @@ func clearRebootAnnotations(host *metal3v1alpha1.BareMetalHost) (dirty bool) {
 	return
 }
 
+// inspectionDisabled checks for existence of inspect.metal3.io=disabled
+// which means we don't inspect even in Inspecting state
+func inspectionDisabled(host *metal3v1alpha1.BareMetalHost) bool {
+	annotations := host.GetAnnotations()
+	if annotations[inspectAnnotationPrefix] == "disabled" {
+		return true
+	}
+	return false
+}
+
 // clearError removes any existing error message.
 func clearError(host *metal3v1alpha1.BareMetalHost) (dirty bool) {
 	dirty = host.SetOperationalStatus(metal3v1alpha1.OperationalStatusOK)
@@ -499,6 +510,13 @@ func (r *BareMetalHostReconciler) registerHost(prov provisioner.Provisioner, inf
 
 // Ensure we have the information about the hardware on the host.
 func (r *BareMetalHostReconciler) actionInspecting(prov provisioner.Provisioner, info *reconcileInfo) actionResult {
+
+	if inspectionDisabled(info.host) {
+		info.log.Info("inspection disabled by annotation")
+		info.publishEvent("InspectionSkipped", "disabled by annotation")
+		return actionComplete{}
+	}
+
 	info.log.Info("inspecting hardware")
 
 	provResult, details, err := prov.InspectHardware(info.host.Status.ErrorType == metal3v1alpha1.InspectionError)


Test patch:
diff --git a/controllers/metal3.io/baremetalhost_controller_test.go b/controllers/metal3.io/baremetalhost_controller_test.go
index cf868410..55a5eca9 100644
--- a/controllers/metal3.io/baremetalhost_controller_test.go
+++ b/controllers/metal3.io/baremetalhost_controller_test.go
@@ -296,6 +296,25 @@ func TestPause(t *testing.T) {
 	)
 }
 
+// TestInspectDisabled ensures that Inspection is skipped when disabled
+func TestInspectDisabled(t *testing.T) {
+	host := newDefaultHost(t)
+	host.Annotations = map[string]string{
+		inspectAnnotationPrefix: "disabled",
+	}
+	r := newTestReconciler(host)
+	waitForProvisioningState(t, r, host, metal3v1alpha1.StateMatchProfile)
+	assert.Nil(t, host.Status.HardwareDetails)
+}
+
+// TestInspectEnabled ensures that Inspection is completed when not disabled
+func TestInspectEnabled(t *testing.T) {
+	host := newDefaultHost(t)
+	r := newTestReconciler(host)
+	waitForProvisioningState(t, r, host, metal3v1alpha1.StateMatchProfile)
+	assert.NotNil(t, host.Status.HardwareDetails)
+}
+
 // TestAddFinalizers ensures that the finalizers for the host are
 // updated as part of reconciling it.
 func TestAddFinalizers(t *testing.T) {
@@ -330,6 +349,16 @@ func TestSetLastUpdated(t *testing.T) {
 	)
 }
 
+func TestInspectionDisabledAnnotation(t *testing.T) {
+	host := newDefaultHost(t)
+	host.Annotations = make(map[string]string)
+
+	assert.False(t, inspectionDisabled(host))
+
+	host.Annotations[inspectAnnotationPrefix] = "disabled"
+	assert.True(t, inspectionDisabled(host))
+}
+
 func TestHasRebootAnnotation(t *testing.T) {
 	host := newDefaultHost(t)
 	host.Annotations = make(map[string]string)