@@ -15,6 +15,7 @@ import (
1515 k8serrors "k8s.io/apimachinery/pkg/api/errors"
1616 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
1717 "k8s.io/apimachinery/pkg/types"
18+ "sigs.k8s.io/controller-runtime/pkg/client"
1819 "sigs.k8s.io/cluster-api/test/framework"
1920)
2021
@@ -107,7 +108,102 @@ var _ = Describe("Create as externally provisioned, deprovision", Label("require
107108 By ("Waiting for the secret to be deleted" )
108109 Eventually (func () bool {
109110 err := clusterProxy .GetClient ().Get (ctx , types.NamespacedName {
110- Name : "bmc-credentials" ,
111+ Name : secretName ,
112+ Namespace : namespace .Name ,
113+ }, & corev1.Secret {})
114+ return k8serrors .IsNotFound (err )
115+ }, e2eConfig .GetIntervals (specName , "wait-secret-deletion" )... ).Should (BeTrue ())
116+ })
117+
118+ It ("transitions from Available to ExternallyProvisioned" , func () {
119+ testSecretName := secretName + "-available-to-ext"
120+ By ("Creating a secret with BMH credentials" )
121+ bmcCredentialsData := map [string ]string {
122+ "username" : bmc .User ,
123+ "password" : bmc .Password ,
124+ }
125+ CreateSecret (ctx , clusterProxy .GetClient (), namespace .Name , testSecretName , bmcCredentialsData )
126+
127+ By ("Creating a BMH without ExternallyProvisioned to allow inspection" )
128+ bmh := metal3api.BareMetalHost {
129+ ObjectMeta : metav1.ObjectMeta {
130+ Name : specName + "-available-to-ext" ,
131+ Namespace : namespace .Name ,
132+ },
133+ Spec : metal3api.BareMetalHostSpec {
134+ BMC : metal3api.BMCDetails {
135+ Address : bmc .Address ,
136+ CredentialsName : testSecretName ,
137+ DisableCertificateVerification : bmc .DisableCertificateVerification ,
138+ },
139+ BootMode : metal3api .BootMode (e2eConfig .GetVariable ("BOOT_MODE" )),
140+ BootMACAddress : bmc .BootMacAddress ,
141+ ExternallyProvisioned : false , // Start with false to allow inspection
142+ },
143+ }
144+ err := clusterProxy .GetClient ().Create (ctx , & bmh )
145+ Expect (err ).NotTo (HaveOccurred ())
146+
147+ By ("waiting for the BMH to be in inspecting state" )
148+ WaitForBmhInProvisioningState (ctx , WaitForBmhInProvisioningStateInput {
149+ Client : clusterProxy .GetClient (),
150+ Bmh : bmh ,
151+ State : metal3api .StateInspecting ,
152+ }, e2eConfig .GetIntervals (specName , "wait-inspecting" )... )
153+
154+ By ("Waiting for the BMH to complete inspection and reach Available state" )
155+ WaitForBmhInProvisioningState (ctx , WaitForBmhInProvisioningStateInput {
156+ Client : clusterProxy .GetClient (),
157+ Bmh : bmh ,
158+ State : metal3api .StateAvailable ,
159+ }, e2eConfig .GetIntervals (specName , "wait-available" )... )
160+
161+ By ("Retrieving the BMH to verify inspection completed" )
162+ err = clusterProxy .GetClient ().Get (ctx , types.NamespacedName {
163+ Name : bmh .Name ,
164+ Namespace : bmh .Namespace ,
165+ }, & bmh )
166+ Expect (err ).NotTo (HaveOccurred ())
167+
168+ By ("Verifying that inspection was performed" )
169+ Expect (bmh .Status .OperationHistory .Inspect .Start .IsZero ()).To (BeFalse (), "Inspection should have been performed" )
170+ Expect (bmh .Status .HardwareDetails ).NotTo (BeNil (), "Hardware details should be available after inspection" )
171+
172+ By ("Setting ExternallyProvisioned to true from Available state (allowed by webhook)" )
173+ patch := client .MergeFrom (bmh .DeepCopy ())
174+ bmh .Spec .ExternallyProvisioned = true
175+ err = clusterProxy .GetClient ().Patch (ctx , & bmh , patch )
176+ Expect (err ).NotTo (HaveOccurred ())
177+
178+ By ("Waiting for the BMH to transition to ExternallyProvisioned state" )
179+ WaitForBmhInProvisioningState (ctx , WaitForBmhInProvisioningStateInput {
180+ Client : clusterProxy .GetClient (),
181+ Bmh : bmh ,
182+ State : metal3api .StateExternallyProvisioned ,
183+ }, e2eConfig .GetIntervals (specName , "wait-externally-provisioned" )... )
184+
185+ By ("Verifying that no BMO provisioning occurred after transition" )
186+ err = clusterProxy .GetClient ().Get (ctx , types.NamespacedName {
187+ Name : bmh .Name ,
188+ Namespace : bmh .Namespace ,
189+ }, & bmh )
190+ Expect (err ).NotTo (HaveOccurred ())
191+ Expect (bmh .Status .OperationHistory .Provision .Start .IsZero ()).To (BeTrue (), "BMO provisioning should not have occurred" )
192+
193+ By ("Cleaning up the BMH" )
194+ err = clusterProxy .GetClient ().Delete (ctx , & bmh )
195+ Expect (err ).NotTo (HaveOccurred ())
196+
197+ WaitForBmhDeleted (ctx , WaitForBmhDeletedInput {
198+ Client : clusterProxy .GetClient (),
199+ BmhName : bmh .Name ,
200+ Namespace : bmh .Namespace ,
201+ }, e2eConfig .GetIntervals (specName , "wait-bmh-deleted" )... )
202+
203+ By ("Waiting for the secret to be deleted" )
204+ Eventually (func () bool {
205+ err := clusterProxy .GetClient ().Get (ctx , types.NamespacedName {
206+ Name : testSecretName ,
111207 Namespace : namespace .Name ,
112208 }, & corev1.Secret {})
113209 return k8serrors .IsNotFound (err )
0 commit comments