@@ -34,6 +34,7 @@ import (
34
34
clusterv1 "sigs.k8s.io/cluster-api/api/v1beta1"
35
35
clusterutilv1 "sigs.k8s.io/cluster-api/util"
36
36
"sigs.k8s.io/cluster-api/util/conditions"
37
+ v1beta2conditions "sigs.k8s.io/cluster-api/util/conditions/v1beta2"
37
38
"sigs.k8s.io/cluster-api/util/finalizers"
38
39
"sigs.k8s.io/cluster-api/util/patch"
39
40
"sigs.k8s.io/cluster-api/util/paused"
@@ -107,7 +108,7 @@ func (r *clusterReconciler) Reconcile(ctx context.Context, req ctrl.Request) (_
107
108
// Always issue a patch when exiting this function so changes to the
108
109
// resource are patched back to the API server.
109
110
defer func () {
110
- if err := clusterContext . Patch (ctx ); err != nil {
111
+ if err := r . patch (ctx , clusterContext ); err != nil {
111
112
reterr = kerrors .NewAggregate ([]error {reterr , err })
112
113
}
113
114
}()
@@ -126,9 +127,71 @@ func (r *clusterReconciler) Reconcile(ctx context.Context, req ctrl.Request) (_
126
127
return r .reconcileNormal (ctx , clusterContext )
127
128
}
128
129
130
+ // patch updates the VSphereCluster and its status on the API server.
131
+ func (r * clusterReconciler ) patch (ctx context.Context , clusterCtx * capvcontext.ClusterContext ) error {
132
+ // always update the readyCondition.
133
+ conditions .SetSummary (clusterCtx .VSphereCluster ,
134
+ conditions .WithConditions (
135
+ infrav1 .VCenterAvailableCondition ,
136
+ ),
137
+ )
138
+
139
+ if err := v1beta2conditions .SetSummaryCondition (clusterCtx .VSphereCluster , clusterCtx .VSphereCluster , infrav1 .VSphereClusterReadyV1Beta2Condition ,
140
+ v1beta2conditions.ForConditionTypes {
141
+ infrav1 .VSphereClusterVCenterAvailableV1Beta2Condition ,
142
+ // FailureDomainsReady and ClusterModuelsReady may not be always set.
143
+ infrav1 .VSphereClusterFailureDomainsReadyV1Beta2Condition ,
144
+ infrav1 .VSphereClusterClusterModulesReadyV1Beta2Condition ,
145
+ },
146
+ v1beta2conditions.IgnoreTypesIfMissing {
147
+ infrav1 .VSphereClusterFailureDomainsReadyV1Beta2Condition ,
148
+ infrav1 .VSphereClusterClusterModulesReadyV1Beta2Condition ,
149
+ },
150
+ // Using a custom merge strategy to override reasons applied during merge.
151
+ v1beta2conditions.CustomMergeStrategy {
152
+ MergeStrategy : v1beta2conditions .DefaultMergeStrategy (
153
+ // Use custom reasons.
154
+ v1beta2conditions .ComputeReasonFunc (v1beta2conditions .GetDefaultComputeMergeReasonFunc (
155
+ infrav1 .VSphereClusterNotReadyV1Beta2Reason ,
156
+ infrav1 .VSphereClusterReadyUnknownV1Beta2Reason ,
157
+ infrav1 .VSphereClusterReadyV1Beta2Reason ,
158
+ )),
159
+ ),
160
+ },
161
+ ); err != nil {
162
+ return pkgerrors .Wrapf (err , "failed to set %s condition" , infrav1 .VSphereClusterReadyV1Beta2Condition )
163
+ }
164
+
165
+ return clusterCtx .PatchHelper .Patch (ctx , clusterCtx .VSphereCluster ,
166
+ patch.WithOwnedV1Beta2Conditions {Conditions : []string {
167
+ clusterv1 .PausedV1Beta2Condition ,
168
+ infrav1 .VSphereClusterReadyV1Beta2Condition ,
169
+ infrav1 .VSphereClusterFailureDomainsReadyV1Beta2Condition ,
170
+ infrav1 .VSphereClusterVCenterAvailableV1Beta2Condition ,
171
+ infrav1 .VSphereClusterClusterModulesReadyV1Beta2Condition ,
172
+ }},
173
+ )
174
+ }
175
+
129
176
func (r * clusterReconciler ) reconcileDelete (ctx context.Context , clusterCtx * capvcontext.ClusterContext ) (reconcile.Result , error ) {
130
177
log := ctrl .LoggerFrom (ctx )
131
178
179
+ v1beta2conditions .Set (clusterCtx .VSphereCluster , metav1.Condition {
180
+ Type : infrav1 .VSphereClusterVCenterAvailableV1Beta2Condition ,
181
+ Status : metav1 .ConditionFalse ,
182
+ Reason : infrav1 .VSphereClusterVCenterAvailableDeletingV1Beta2Reason ,
183
+ })
184
+ v1beta2conditions .Set (clusterCtx .VSphereCluster , metav1.Condition {
185
+ Type : infrav1 .VSphereClusterClusterModulesReadyV1Beta2Condition ,
186
+ Status : metav1 .ConditionFalse ,
187
+ Reason : infrav1 .VSphereClusterClusterModulesDeletingV1Beta2Reason ,
188
+ })
189
+ v1beta2conditions .Set (clusterCtx .VSphereCluster , metav1.Condition {
190
+ Type : infrav1 .VSphereClusterFailureDomainsReadyV1Beta2Condition ,
191
+ Status : metav1 .ConditionFalse ,
192
+ Reason : infrav1 .VSphereClusterFailureDomainsDeletingV1Beta2Reason ,
193
+ })
194
+
132
195
var vsphereMachines []client.Object
133
196
var err error
134
197
if clusterCtx .Cluster != nil {
@@ -191,37 +254,74 @@ func (r *clusterReconciler) reconcileDelete(ctx context.Context, clusterCtx *cap
191
254
func (r * clusterReconciler ) reconcileNormal (ctx context.Context , clusterCtx * capvcontext.ClusterContext ) (reconcile.Result , error ) {
192
255
log := ctrl .LoggerFrom (ctx )
193
256
257
+ // Reconcile failure domains.
194
258
ok , err := r .reconcileDeploymentZones (ctx , clusterCtx )
195
259
if err != nil {
260
+ v1beta2conditions .Set (clusterCtx .VSphereCluster , metav1.Condition {
261
+ Type : infrav1 .VSphereClusterFailureDomainsReadyV1Beta2Condition ,
262
+ Status : metav1 .ConditionFalse ,
263
+ Reason : infrav1 .VSphereClusterFailureDomainsNotReadyV1Beta2Reason ,
264
+ Message : err .Error (),
265
+ })
196
266
return reconcile.Result {}, err
197
267
}
198
268
if ! ok {
199
- log .Info ("Waiting for failure domains to be reconciled" )
200
269
return reconcile.Result {RequeueAfter : 10 * time .Second }, nil
201
270
}
202
271
272
+ // Reconcile vCenter availability.
203
273
if err := r .reconcileIdentitySecret (ctx , clusterCtx ); err != nil {
204
274
conditions .MarkFalse (clusterCtx .VSphereCluster , infrav1 .VCenterAvailableCondition , infrav1 .VCenterUnreachableReason , clusterv1 .ConditionSeverityError , err .Error ())
275
+ v1beta2conditions .Set (clusterCtx .VSphereCluster , metav1.Condition {
276
+ Type : infrav1 .VSphereClusterVCenterAvailableV1Beta2Condition ,
277
+ Status : metav1 .ConditionFalse ,
278
+ Reason : infrav1 .VSphereClusterVCenterUnreachableV1Beta2Reason ,
279
+ Message : err .Error (),
280
+ })
205
281
return reconcile.Result {}, err
206
282
}
207
283
208
284
vcenterSession , err := r .reconcileVCenterConnectivity (ctx , clusterCtx )
209
285
if err != nil {
210
286
conditions .MarkFalse (clusterCtx .VSphereCluster , infrav1 .VCenterAvailableCondition , infrav1 .VCenterUnreachableReason , clusterv1 .ConditionSeverityError , err .Error ())
287
+ v1beta2conditions .Set (clusterCtx .VSphereCluster , metav1.Condition {
288
+ Type : infrav1 .VSphereClusterVCenterAvailableV1Beta2Condition ,
289
+ Status : metav1 .ConditionFalse ,
290
+ Reason : infrav1 .VSphereClusterVCenterUnreachableV1Beta2Reason ,
291
+ Message : err .Error (),
292
+ })
211
293
return reconcile.Result {}, pkgerrors .Wrapf (err ,
212
294
"unexpected error while probing vcenter for %s" , clusterCtx )
213
295
}
214
296
conditions .MarkTrue (clusterCtx .VSphereCluster , infrav1 .VCenterAvailableCondition )
297
+ v1beta2conditions .Set (clusterCtx .VSphereCluster , metav1.Condition {
298
+ Type : infrav1 .VSphereClusterVCenterAvailableV1Beta2Condition ,
299
+ Status : metav1 .ConditionTrue ,
300
+ Reason : infrav1 .VSphereClusterVCenterAvailableV1Beta2Reason ,
301
+ })
215
302
303
+ // Reconcile cluster modules.
216
304
err = r .reconcileVCenterVersion (clusterCtx , vcenterSession )
217
305
if err != nil || clusterCtx .VSphereCluster .Status .VCenterVersion == "" {
218
- conditions .MarkFalse (clusterCtx .VSphereCluster , infrav1 .ClusterModulesAvailableCondition , infrav1 .MissingVCenterVersionReason , clusterv1 .ConditionSeverityWarning , "vCenter version not set" )
306
+ conditions .MarkFalse (clusterCtx .VSphereCluster , infrav1 .ClusterModulesAvailableCondition , infrav1 .MissingVCenterVersionReason , clusterv1 .ConditionSeverityWarning , err .Error ())
307
+ v1beta2conditions .Set (clusterCtx .VSphereCluster , metav1.Condition {
308
+ Type : infrav1 .VSphereClusterClusterModulesReadyV1Beta2Condition ,
309
+ Status : metav1 .ConditionFalse ,
310
+ Reason : infrav1 .VSphereClusterModulesInvalidVCenterVersionV1Beta2Reason ,
311
+ Message : err .Error (),
312
+ })
219
313
log .Error (err , "could not reconcile vCenter version" )
220
314
}
221
315
222
316
affinityReconcileResult , err := r .reconcileClusterModules (ctx , clusterCtx )
223
317
if err != nil {
224
318
conditions .MarkFalse (clusterCtx .VSphereCluster , infrav1 .ClusterModulesAvailableCondition , infrav1 .ClusterModuleSetupFailedReason , clusterv1 .ConditionSeverityWarning , err .Error ())
319
+ v1beta2conditions .Set (clusterCtx .VSphereCluster , metav1.Condition {
320
+ Type : infrav1 .VSphereClusterClusterModulesReadyV1Beta2Condition ,
321
+ Status : metav1 .ConditionFalse ,
322
+ Reason : infrav1 .VSphereClusterClusterModulesNotReadyV1Beta2Reason ,
323
+ Message : err .Error (),
324
+ })
225
325
return affinityReconcileResult , err
226
326
}
227
327
@@ -295,13 +395,14 @@ func (r *clusterReconciler) reconcileVCenterConnectivity(ctx context.Context, cl
295
395
func (r * clusterReconciler ) reconcileVCenterVersion (clusterCtx * capvcontext.ClusterContext , s * session.Session ) error {
296
396
version , err := s .GetVersion ()
297
397
if err != nil {
298
- return err
398
+ return pkgerrors . Wrapf ( err , "invalid vCenter version" )
299
399
}
300
400
clusterCtx .VSphereCluster .Status .VCenterVersion = version
301
401
return nil
302
402
}
303
403
304
404
func (r * clusterReconciler ) reconcileDeploymentZones (ctx context.Context , clusterCtx * capvcontext.ClusterContext ) (bool , error ) {
405
+ log := ctrl .LoggerFrom (ctx )
305
406
// If there is no failure domain selector, skip reconciliation
306
407
if clusterCtx .VSphereCluster .Spec .FailureDomainSelector == nil {
307
408
return true , nil
@@ -346,15 +447,33 @@ func (r *clusterReconciler) reconcileDeploymentZones(ctx context.Context, cluste
346
447
347
448
clusterCtx .VSphereCluster .Status .FailureDomains = failureDomains
348
449
if readyNotReported > 0 {
450
+ log .Info ("Waiting for failure domains to be reconciled" )
349
451
conditions .MarkFalse (clusterCtx .VSphereCluster , infrav1 .FailureDomainsAvailableCondition , infrav1 .WaitingForFailureDomainStatusReason , clusterv1 .ConditionSeverityInfo , "waiting for failure domains to report ready status" )
452
+ v1beta2conditions .Set (clusterCtx .VSphereCluster , metav1.Condition {
453
+ Type : infrav1 .VSphereClusterFailureDomainsReadyV1Beta2Condition ,
454
+ Status : metav1 .ConditionFalse ,
455
+ Reason : infrav1 .VSphereClusterFailureDomainsNotReadyV1Beta2Reason ,
456
+ Message : "Waiting for failure domains to report ready status" ,
457
+ })
350
458
return false , nil
351
459
}
352
460
353
461
if len (failureDomains ) > 0 {
354
462
if notReady > 0 {
355
463
conditions .MarkFalse (clusterCtx .VSphereCluster , infrav1 .FailureDomainsAvailableCondition , infrav1 .FailureDomainsSkippedReason , clusterv1 .ConditionSeverityInfo , "one or more failure domains are not ready" )
464
+ v1beta2conditions .Set (clusterCtx .VSphereCluster , metav1.Condition {
465
+ Type : infrav1 .VSphereClusterFailureDomainsReadyV1Beta2Condition ,
466
+ Status : metav1 .ConditionFalse ,
467
+ Reason : infrav1 .VSphereClusterFailureDomainsNotReadyV1Beta2Reason ,
468
+ Message : "One or more failure domains are not ready" ,
469
+ })
356
470
} else {
357
471
conditions .MarkTrue (clusterCtx .VSphereCluster , infrav1 .FailureDomainsAvailableCondition )
472
+ v1beta2conditions .Set (clusterCtx .VSphereCluster , metav1.Condition {
473
+ Type : infrav1 .VSphereClusterFailureDomainsReadyV1Beta2Condition ,
474
+ Status : metav1 .ConditionTrue ,
475
+ Reason : infrav1 .VSphereClusterFailureDomainsReadyV1Beta2Reason ,
476
+ })
358
477
}
359
478
} else {
360
479
// Remove the condition if failure domains do not exist
0 commit comments