@@ -34,6 +34,7 @@ import (
3434 clusterv1 "sigs.k8s.io/cluster-api/api/v1beta1"
3535 clusterutilv1 "sigs.k8s.io/cluster-api/util"
3636 "sigs.k8s.io/cluster-api/util/conditions"
37+ v1beta2conditions "sigs.k8s.io/cluster-api/util/conditions/v1beta2"
3738 "sigs.k8s.io/cluster-api/util/finalizers"
3839 "sigs.k8s.io/cluster-api/util/patch"
3940 "sigs.k8s.io/cluster-api/util/paused"
@@ -107,7 +108,7 @@ func (r *clusterReconciler) Reconcile(ctx context.Context, req ctrl.Request) (_
107108 // Always issue a patch when exiting this function so changes to the
108109 // resource are patched back to the API server.
109110 defer func () {
110- if err := clusterContext . Patch (ctx ); err != nil {
111+ if err := r . patch (ctx , clusterContext ); err != nil {
111112 reterr = kerrors .NewAggregate ([]error {reterr , err })
112113 }
113114 }()
@@ -126,9 +127,71 @@ func (r *clusterReconciler) Reconcile(ctx context.Context, req ctrl.Request) (_
126127 return r .reconcileNormal (ctx , clusterContext )
127128}
128129
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+
129176func (r * clusterReconciler ) reconcileDelete (ctx context.Context , clusterCtx * capvcontext.ClusterContext ) (reconcile.Result , error ) {
130177 log := ctrl .LoggerFrom (ctx )
131178
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+
132195 var vsphereMachines []client.Object
133196 var err error
134197 if clusterCtx .Cluster != nil {
@@ -191,37 +254,74 @@ func (r *clusterReconciler) reconcileDelete(ctx context.Context, clusterCtx *cap
191254func (r * clusterReconciler ) reconcileNormal (ctx context.Context , clusterCtx * capvcontext.ClusterContext ) (reconcile.Result , error ) {
192255 log := ctrl .LoggerFrom (ctx )
193256
257+ // Reconcile failure domains.
194258 ok , err := r .reconcileDeploymentZones (ctx , clusterCtx )
195259 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+ })
196266 return reconcile.Result {}, err
197267 }
198268 if ! ok {
199- log .Info ("Waiting for failure domains to be reconciled" )
200269 return reconcile.Result {RequeueAfter : 10 * time .Second }, nil
201270 }
202271
272+ // Reconcile vCenter availability.
203273 if err := r .reconcileIdentitySecret (ctx , clusterCtx ); err != nil {
204274 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+ })
205281 return reconcile.Result {}, err
206282 }
207283
208284 vcenterSession , err := r .reconcileVCenterConnectivity (ctx , clusterCtx )
209285 if err != nil {
210286 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+ })
211293 return reconcile.Result {}, pkgerrors .Wrapf (err ,
212294 "unexpected error while probing vcenter for %s" , clusterCtx )
213295 }
214296 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+ })
215302
303+ // Reconcile cluster modules.
216304 err = r .reconcileVCenterVersion (clusterCtx , vcenterSession )
217305 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+ })
219313 log .Error (err , "could not reconcile vCenter version" )
220314 }
221315
222316 affinityReconcileResult , err := r .reconcileClusterModules (ctx , clusterCtx )
223317 if err != nil {
224318 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+ })
225325 return affinityReconcileResult , err
226326 }
227327
@@ -295,13 +395,14 @@ func (r *clusterReconciler) reconcileVCenterConnectivity(ctx context.Context, cl
295395func (r * clusterReconciler ) reconcileVCenterVersion (clusterCtx * capvcontext.ClusterContext , s * session.Session ) error {
296396 version , err := s .GetVersion ()
297397 if err != nil {
298- return err
398+ return pkgerrors . Wrapf ( err , "invalid vCenter version" )
299399 }
300400 clusterCtx .VSphereCluster .Status .VCenterVersion = version
301401 return nil
302402}
303403
304404func (r * clusterReconciler ) reconcileDeploymentZones (ctx context.Context , clusterCtx * capvcontext.ClusterContext ) (bool , error ) {
405+ log := ctrl .LoggerFrom (ctx )
305406 // If there is no failure domain selector, skip reconciliation
306407 if clusterCtx .VSphereCluster .Spec .FailureDomainSelector == nil {
307408 return true , nil
@@ -346,15 +447,33 @@ func (r *clusterReconciler) reconcileDeploymentZones(ctx context.Context, cluste
346447
347448 clusterCtx .VSphereCluster .Status .FailureDomains = failureDomains
348449 if readyNotReported > 0 {
450+ log .Info ("Waiting for failure domains to be reconciled" )
349451 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+ })
350458 return false , nil
351459 }
352460
353461 if len (failureDomains ) > 0 {
354462 if notReady > 0 {
355463 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+ })
356470 } else {
357471 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+ })
358477 }
359478 } else {
360479 // Remove the condition if failure domains do not exist
0 commit comments