@@ -32,6 +32,7 @@ import (
32
32
clusterv1 "sigs.k8s.io/cluster-api/api/v1beta1"
33
33
capierrors "sigs.k8s.io/cluster-api/errors"
34
34
"sigs.k8s.io/cluster-api/internal/test/builder"
35
+ "sigs.k8s.io/cluster-api/util/conditions"
35
36
)
36
37
37
38
func TestClusterReconcilePhases (t * testing.T ) {
@@ -56,13 +57,30 @@ func TestClusterReconcilePhases(t *testing.T) {
56
57
},
57
58
},
58
59
}
60
+ clusterNoEndpoint := & clusterv1.Cluster {
61
+ ObjectMeta : metav1.ObjectMeta {
62
+ Name : "test-cluster" ,
63
+ Namespace : "test-namespace" ,
64
+ },
65
+ Status : clusterv1.ClusterStatus {
66
+ InfrastructureReady : true ,
67
+ },
68
+ Spec : clusterv1.ClusterSpec {
69
+ InfrastructureRef : & corev1.ObjectReference {
70
+ APIVersion : "infrastructure.cluster.x-k8s.io/v1beta1" ,
71
+ Kind : "GenericInfrastructureMachine" ,
72
+ Name : "test" ,
73
+ },
74
+ },
75
+ }
59
76
60
77
tests := []struct {
61
78
name string
62
79
cluster * clusterv1.Cluster
63
80
infraRef map [string ]interface {}
64
81
expectErr bool
65
82
expectResult ctrl.Result
83
+ check func (g * GomegaWithT , in * clusterv1.Cluster )
66
84
}{
67
85
{
68
86
name : "returns no error if infrastructure ref is nil" ,
@@ -104,7 +122,7 @@ func TestClusterReconcilePhases(t *testing.T) {
104
122
expectErr : false ,
105
123
},
106
124
{
107
- name : "returns error if infrastructure has the paused annotation" ,
125
+ name : "returns no error if infrastructure has the paused annotation" ,
108
126
cluster : cluster ,
109
127
infraRef : map [string ]interface {}{
110
128
"kind" : "GenericInfrastructureMachine" ,
@@ -119,6 +137,50 @@ func TestClusterReconcilePhases(t *testing.T) {
119
137
},
120
138
expectErr : false ,
121
139
},
140
+ {
141
+ name : "returns an error if the control plane endpoint is not yet set" ,
142
+ cluster : clusterNoEndpoint ,
143
+ infraRef : map [string ]interface {}{
144
+ "kind" : "GenericInfrastructureMachine" ,
145
+ "apiVersion" : "infrastructure.cluster.x-k8s.io/v1beta1" ,
146
+ "metadata" : map [string ]interface {}{
147
+ "name" : "test" ,
148
+ "namespace" : "test-namespace" ,
149
+ "deletionTimestamp" : "sometime" ,
150
+ },
151
+ "status" : map [string ]interface {}{
152
+ "ready" : true ,
153
+ },
154
+ },
155
+ expectErr : true ,
156
+ },
157
+ {
158
+ name : "should propagate the control plane endpoint once set" ,
159
+ cluster : clusterNoEndpoint ,
160
+ infraRef : map [string ]interface {}{
161
+ "kind" : "GenericInfrastructureMachine" ,
162
+ "apiVersion" : "infrastructure.cluster.x-k8s.io/v1beta1" ,
163
+ "metadata" : map [string ]interface {}{
164
+ "name" : "test" ,
165
+ "namespace" : "test-namespace" ,
166
+ "deletionTimestamp" : "sometime" ,
167
+ },
168
+ "spec" : map [string ]interface {}{
169
+ "controlPlaneEndpoint" : map [string ]interface {}{
170
+ "host" : "example.com" ,
171
+ "port" : int64 (6443 ),
172
+ },
173
+ },
174
+ "status" : map [string ]interface {}{
175
+ "ready" : true ,
176
+ },
177
+ },
178
+ expectErr : false ,
179
+ check : func (g * GomegaWithT , in * clusterv1.Cluster ) {
180
+ g .Expect (in .Spec .ControlPlaneEndpoint .Host ).To (Equal ("example.com" ))
181
+ g .Expect (in .Spec .ControlPlaneEndpoint .Port ).To (BeEquivalentTo (6443 ))
182
+ },
183
+ },
122
184
}
123
185
124
186
for _ , tt := range tests {
@@ -149,6 +211,202 @@ func TestClusterReconcilePhases(t *testing.T) {
149
211
} else {
150
212
g .Expect (err ).ToNot (HaveOccurred ())
151
213
}
214
+
215
+ if tt .check != nil {
216
+ tt .check (g , tt .cluster )
217
+ }
218
+ })
219
+ }
220
+ })
221
+
222
+ t .Run ("reconcile control plane ref" , func (t * testing.T ) {
223
+ cluster := & clusterv1.Cluster {
224
+ ObjectMeta : metav1.ObjectMeta {
225
+ Name : "test-cluster" ,
226
+ Namespace : "test-namespace" ,
227
+ },
228
+ Status : clusterv1.ClusterStatus {
229
+ InfrastructureReady : true ,
230
+ },
231
+ Spec : clusterv1.ClusterSpec {
232
+ ControlPlaneEndpoint : clusterv1.APIEndpoint {
233
+ Host : "1.2.3.4" ,
234
+ Port : 8443 ,
235
+ },
236
+ ControlPlaneRef : & corev1.ObjectReference {
237
+ APIVersion : "controlplane.cluster.x-k8s.io/v1beta1" ,
238
+ Kind : "GenericControlPlane" ,
239
+ Name : "test" ,
240
+ },
241
+ },
242
+ }
243
+ clusterNoEndpoint := & clusterv1.Cluster {
244
+ ObjectMeta : metav1.ObjectMeta {
245
+ Name : "test-cluster" ,
246
+ Namespace : "test-namespace" ,
247
+ },
248
+ Status : clusterv1.ClusterStatus {
249
+ InfrastructureReady : true ,
250
+ },
251
+ Spec : clusterv1.ClusterSpec {
252
+ ControlPlaneRef : & corev1.ObjectReference {
253
+ APIVersion : "controlplane.cluster.x-k8s.io/v1beta1" ,
254
+ Kind : "GenericControlPlane" ,
255
+ Name : "test" ,
256
+ },
257
+ },
258
+ }
259
+
260
+ tests := []struct {
261
+ name string
262
+ cluster * clusterv1.Cluster
263
+ cpRef map [string ]interface {}
264
+ expectErr bool
265
+ expectResult ctrl.Result
266
+ check func (g * GomegaWithT , in * clusterv1.Cluster )
267
+ }{
268
+ {
269
+ name : "returns no error if control plane ref is nil" ,
270
+ cluster : & clusterv1.Cluster {ObjectMeta : metav1.ObjectMeta {Name : "test-cluster" , Namespace : "test-namespace" }},
271
+ expectErr : false ,
272
+ },
273
+ {
274
+ name : "returns error if unable to reconcile control plane ref" ,
275
+ cluster : cluster ,
276
+ expectErr : false ,
277
+ expectResult : ctrl.Result {RequeueAfter : 30 * time .Second },
278
+ },
279
+ {
280
+ name : "returns no error if infra config is marked for deletion" ,
281
+ cluster : cluster ,
282
+ cpRef : map [string ]interface {}{
283
+ "kind" : "GenericControlPlane" ,
284
+ "apiVersion" : "controlplane.cluster.x-k8s.io/v1beta1" ,
285
+ "metadata" : map [string ]interface {}{
286
+ "name" : "test" ,
287
+ "namespace" : "test-namespace" ,
288
+ "deletionTimestamp" : "sometime" ,
289
+ },
290
+ },
291
+ expectErr : false ,
292
+ },
293
+ {
294
+ name : "returns no error if infrastructure has the paused annotation" ,
295
+ cluster : cluster ,
296
+ cpRef : map [string ]interface {}{
297
+ "kind" : "GenericControlPlane" ,
298
+ "apiVersion" : "controlplane.cluster.x-k8s.io/v1beta1" ,
299
+ "metadata" : map [string ]interface {}{
300
+ "name" : "test" ,
301
+ "namespace" : "test-namespace" ,
302
+ "annotations" : map [string ]interface {}{
303
+ "cluster.x-k8s.io/paused" : "true" ,
304
+ },
305
+ },
306
+ },
307
+ expectErr : false ,
308
+ },
309
+ {
310
+ name : "returns an error if the control plane endpoint is not yet set" ,
311
+ cluster : clusterNoEndpoint ,
312
+ cpRef : map [string ]interface {}{
313
+ "kind" : "GenericControlPlane" ,
314
+ "apiVersion" : "controlplane.cluster.x-k8s.io/v1beta1" ,
315
+ "metadata" : map [string ]interface {}{
316
+ "name" : "test" ,
317
+ "namespace" : "test-namespace" ,
318
+ "deletionTimestamp" : "sometime" ,
319
+ },
320
+ "status" : map [string ]interface {}{
321
+ "ready" : true ,
322
+ },
323
+ },
324
+ expectErr : true ,
325
+ },
326
+ {
327
+ name : "should propagate the control plane endpoint if set" ,
328
+ cluster : clusterNoEndpoint ,
329
+ cpRef : map [string ]interface {}{
330
+ "kind" : "GenericControlPlane" ,
331
+ "apiVersion" : "controlplane.cluster.x-k8s.io/v1beta1" ,
332
+ "metadata" : map [string ]interface {}{
333
+ "name" : "test" ,
334
+ "namespace" : "test-namespace" ,
335
+ "deletionTimestamp" : "sometime" ,
336
+ },
337
+ "spec" : map [string ]interface {}{
338
+ "controlPlaneEndpoint" : map [string ]interface {}{
339
+ "host" : "example.com" ,
340
+ "port" : int64 (6443 ),
341
+ },
342
+ },
343
+ "status" : map [string ]interface {}{
344
+ "ready" : true ,
345
+ },
346
+ },
347
+ expectErr : false ,
348
+ check : func (g * GomegaWithT , in * clusterv1.Cluster ) {
349
+ g .Expect (in .Spec .ControlPlaneEndpoint .Host ).To (Equal ("example.com" ))
350
+ g .Expect (in .Spec .ControlPlaneEndpoint .Port ).To (BeEquivalentTo (6443 ))
351
+ },
352
+ },
353
+ {
354
+ name : "should propagate the initialized and ready conditions" ,
355
+ cluster : clusterNoEndpoint ,
356
+ cpRef : map [string ]interface {}{
357
+ "kind" : "GenericControlPlane" ,
358
+ "apiVersion" : "controlplane.cluster.x-k8s.io/v1beta1" ,
359
+ "metadata" : map [string ]interface {}{
360
+ "name" : "test" ,
361
+ "namespace" : "test-namespace" ,
362
+ "deletionTimestamp" : "sometime" ,
363
+ },
364
+ "spec" : map [string ]interface {}{},
365
+ "status" : map [string ]interface {}{
366
+ "ready" : true ,
367
+ "initialized" : true ,
368
+ },
369
+ },
370
+ expectErr : false ,
371
+ check : func (g * GomegaWithT , in * clusterv1.Cluster ) {
372
+ g .Expect (conditions .IsTrue (in , clusterv1 .ControlPlaneReadyCondition )).To (BeTrue ())
373
+ g .Expect (conditions .IsTrue (in , clusterv1 .ControlPlaneInitializedCondition )).To (BeTrue ())
374
+ },
375
+ },
376
+ }
377
+
378
+ for _ , tt := range tests {
379
+ t .Run (tt .name , func (t * testing.T ) {
380
+ g := NewWithT (t )
381
+
382
+ var c client.Client
383
+ if tt .cpRef != nil {
384
+ infraConfig := & unstructured.Unstructured {Object : tt .cpRef }
385
+ c = fake .NewClientBuilder ().
386
+ WithObjects (builder .GenericControlPlaneCRD .DeepCopy (), tt .cluster , infraConfig ).
387
+ Build ()
388
+ } else {
389
+ c = fake .NewClientBuilder ().
390
+ WithObjects (builder .GenericControlPlaneCRD .DeepCopy (), tt .cluster ).
391
+ Build ()
392
+ }
393
+ r := & Reconciler {
394
+ Client : c ,
395
+ UnstructuredCachingClient : c ,
396
+ recorder : record .NewFakeRecorder (32 ),
397
+ }
398
+
399
+ res , err := r .reconcileControlPlane (ctx , tt .cluster )
400
+ g .Expect (res ).To (BeComparableTo (tt .expectResult ))
401
+ if tt .expectErr {
402
+ g .Expect (err ).To (HaveOccurred ())
403
+ } else {
404
+ g .Expect (err ).ToNot (HaveOccurred ())
405
+ }
406
+
407
+ if tt .check != nil {
408
+ tt .check (g , tt .cluster )
409
+ }
152
410
})
153
411
}
154
412
})
0 commit comments