@@ -19,6 +19,7 @@ package controllers
1919import (
2020 "fmt"
2121 "testing"
22+ "time"
2223
2324 . "github.com/onsi/gomega"
2425 corev1 "k8s.io/api/core/v1"
@@ -56,8 +57,9 @@ func TestEKSConfigReconciler(t *testing.T) {
5657 }
5758 t .Logf ("Calling reconcile on cluster '%s' and config '%s' should requeue" , cluster .Name , config .Name )
5859 g .Eventually (func (gomega Gomega ) {
59- err := reconciler .joinWorker (ctx , cluster , config , configOwner ("Machine" ))
60+ result , err := reconciler .joinWorker (ctx , cluster , config , configOwner ("Machine" ))
6061 gomega .Expect (err ).NotTo (HaveOccurred ())
62+ gomega .Expect (result .Requeue ).To (BeFalse ())
6163 }).Should (Succeed ())
6264
6365 t .Logf ("Secret '%s' should exist and be correct" , config .Name )
@@ -110,8 +112,9 @@ func TestEKSConfigReconciler(t *testing.T) {
110112 }
111113 t .Logf ("Calling reconcile on cluster '%s' and config '%s' should requeue" , cluster .Name , config .Name )
112114 g .Eventually (func (gomega Gomega ) {
113- err := reconciler .joinWorker (ctx , cluster , config , configOwner ("MachinePool" ))
115+ result , err := reconciler .joinWorker (ctx , cluster , config , configOwner ("MachinePool" ))
114116 gomega .Expect (err ).NotTo (HaveOccurred ())
117+ gomega .Expect (result .Requeue ).To (BeFalse ())
115118 }).Should (Succeed ())
116119
117120 t .Logf ("Secret '%s' should exist and be correct" , config .Name )
@@ -134,8 +137,9 @@ func TestEKSConfigReconciler(t *testing.T) {
134137 }
135138 t .Log (dump ("config" , config ))
136139 g .Eventually (func (gomega Gomega ) {
137- err := reconciler .joinWorker (ctx , cluster , config , configOwner ("MachinePool" ))
140+ result , err := reconciler .joinWorker (ctx , cluster , config , configOwner ("MachinePool" ))
138141 gomega .Expect (err ).NotTo (HaveOccurred ())
142+ gomega .Expect (result .Requeue ).To (BeFalse ())
139143 }).Should (Succeed ())
140144 t .Logf ("Secret '%s' should exist and be up to date" , config .Name )
141145
@@ -181,8 +185,9 @@ func TestEKSConfigReconciler(t *testing.T) {
181185 }
182186 t .Logf ("Calling reconcile on cluster '%s' and config '%s' should requeue" , cluster .Name , config .Name )
183187 g .Eventually (func (gomega Gomega ) {
184- err := reconciler .joinWorker (ctx , cluster , config , configOwner ("Machine" ))
188+ result , err := reconciler .joinWorker (ctx , cluster , config , configOwner ("Machine" ))
185189 gomega .Expect (err ).NotTo (HaveOccurred ())
190+ gomega .Expect (result .Requeue ).To (BeFalse ())
186191 }).Should (Succeed ())
187192
188193 t .Logf ("Secret '%s' should exist and be out of date" , config .Name )
@@ -199,6 +204,119 @@ func TestEKSConfigReconciler(t *testing.T) {
199204 gomega .Expect (string (secret .Data ["value" ])).To (Not (Equal (string (expectedUserData ))))
200205 }).Should (Succeed ())
201206 })
207+
208+ t .Run ("Should return requeue when control plane is not initialized" , func (t * testing.T ) {
209+ g := NewWithT (t )
210+ amcp := newAMCP ("test-cluster" )
211+ cluster := newCluster (amcp .Name )
212+ machine := newMachine (cluster , "test-machine" )
213+ config := newEKSConfig (machine )
214+
215+ // Set cluster status to infrastructure ready but control plane not initialized
216+ cluster .Status = clusterv1.ClusterStatus {
217+ InfrastructureReady : true ,
218+ ControlPlaneReady : false ,
219+ }
220+
221+ g .Expect (testEnv .Client .Create (ctx , amcp )).To (Succeed ())
222+
223+ reconciler := EKSConfigReconciler {
224+ Client : testEnv .Client ,
225+ }
226+
227+ // Should return requeue result when control plane is not initialized
228+ result , err := reconciler .joinWorker (ctx , cluster , config , configOwner ("Machine" ))
229+ g .Expect (err ).NotTo (HaveOccurred ())
230+ g .Expect (result .Requeue ).To (BeTrue ())
231+ g .Expect (result .RequeueAfter ).To (Equal (30 * time .Second ))
232+ })
233+
234+ t .Run ("Should generate AL2023 userdata for AL2023 AMI family" , func (t * testing.T ) {
235+ g := NewWithT (t )
236+ amcp := newAMCP ("test-cluster" )
237+ cluster := newCluster (amcp .Name )
238+ machine := newMachine (cluster , "test-machine" )
239+ config := newEKSConfig (machine )
240+
241+ // Set cluster status to ready
242+ cluster .Status = clusterv1.ClusterStatus {
243+ InfrastructureReady : true ,
244+ ControlPlaneReady : true ,
245+ }
246+
247+ // Set AMCP status with AL2023 AMI family
248+ amcp .Status = ekscontrolplanev1.AWSManagedControlPlaneStatus {
249+ Ready : true ,
250+ Initialized : true ,
251+ }
252+
253+ // Set config to use AL2023
254+ config .Spec .NodeType = "al2023"
255+ config .Spec .PreBootstrapCommands = []string {
256+ "echo 'Pre-bootstrap setup'" ,
257+ "systemctl enable docker" ,
258+ }
259+ config .Spec .PostBootstrapCommands = []string {
260+ "echo 'Post-bootstrap cleanup'" ,
261+ "systemctl restart kubelet" ,
262+ }
263+
264+ g .Expect (testEnv .Client .Create (ctx , amcp )).To (Succeed ())
265+
266+ reconciler := EKSConfigReconciler {
267+ Client : testEnv .Client ,
268+ }
269+
270+ // Should generate AL2023 userdata
271+ result , err := reconciler .joinWorker (ctx , cluster , config , configOwner ("Machine" ))
272+ g .Expect (err ).NotTo (HaveOccurred ())
273+ g .Expect (result .Requeue ).To (BeFalse ())
274+
275+ // Check that the secret was created with AL2023 userdata
276+ secret := & corev1.Secret {}
277+ g .Eventually (func (gomega Gomega ) {
278+ gomega .Expect (testEnv .Client .Get (ctx , client.ObjectKey {
279+ Name : config .Name ,
280+ Namespace : "default" ,
281+ }, secret )).To (Succeed ())
282+
283+ // Verify it's AL2023 multipart MIME format
284+ userData := string (secret .Data ["value" ])
285+ gomega .Expect (userData ).To (ContainSubstring ("MIME-Version: 1.0" ))
286+ gomega .Expect (userData ).To (ContainSubstring ("Content-Type: multipart/mixed" ))
287+ gomega .Expect (userData ).To (ContainSubstring ("apiVersion: node.eks.aws/v1alpha1" ))
288+ gomega .Expect (userData ).To (ContainSubstring ("kind: NodeConfig" ))
289+ gomega .Expect (userData ).To (ContainSubstring ("preKubeadmCommands:" ))
290+ gomega .Expect (userData ).To (ContainSubstring ("postKubeadmCommands:" ))
291+ gomega .Expect (userData ).To (ContainSubstring ("echo 'Pre-bootstrap setup'" ))
292+ gomega .Expect (userData ).To (ContainSubstring ("echo 'Post-bootstrap cleanup'" ))
293+ }).Should (Succeed ())
294+ })
295+
296+ t .Run ("Should handle missing AMCP gracefully" , func (t * testing.T ) {
297+ g := NewWithT (t )
298+ cluster := newCluster ("test-cluster" )
299+ machine := newMachine (cluster , "test-machine" )
300+ config := newEKSConfig (machine )
301+
302+ // Set cluster status to ready
303+ cluster .Status = clusterv1.ClusterStatus {
304+ InfrastructureReady : true ,
305+ ControlPlaneReady : true ,
306+ }
307+
308+ // Don't create AMCP - it should be missing
309+
310+ reconciler := EKSConfigReconciler {
311+ Client : testEnv .Client ,
312+ }
313+
314+ // Should return error when AMCP is missing
315+ result , err := reconciler .joinWorker (ctx , cluster , config , configOwner ("Machine" ))
316+ g .Expect (err ).To (HaveOccurred ())
317+ g .Expect (result .Requeue ).To (BeFalse ())
318+ })
319+
202320 t .Run ("Should Reconcile an EKSConfig with a secret file reference" , func (t * testing.T ) {
203321 g := NewWithT (t )
204322 amcp := newAMCP ("test-cluster" )
@@ -254,8 +372,9 @@ func TestEKSConfigReconciler(t *testing.T) {
254372 }
255373 t .Logf ("Calling reconcile on cluster '%s' and config '%s' should requeue" , cluster .Name , config .Name )
256374 g .Eventually (func (gomega Gomega ) {
257- err := reconciler .joinWorker (ctx , cluster , config , configOwner ("Machine" ))
375+ result , err := reconciler .joinWorker (ctx , cluster , config , configOwner ("Machine" ))
258376 gomega .Expect (err ).NotTo (HaveOccurred ())
377+ gomega .Expect (result .Requeue ).To (BeFalse ())
259378 }).Should (Succeed ())
260379
261380 secretList := & corev1.SecretList {}
0 commit comments