Skip to content

Commit d219994

Browse files
committed
vspherecluster: implement Ready, FailureDomainsReady, ClusterModulesReady and VCenterAvailable v1beta2 conditions for govmomi
1 parent 393a169 commit d219994

8 files changed

+225
-71
lines changed

.golangci.yml

-4
Original file line numberDiff line numberDiff line change
@@ -214,10 +214,6 @@ issues:
214214
- linters:
215215
- staticcheck
216216
text: "SA1019: \"sigs.k8s.io/cluster-api-provider-vsphere/apis/(v1alpha3|v1alpha4)\" is deprecated: This package will be removed in one of the next releases."
217-
# Deprecations for Cluster API's predicates.ClusterUnpausedAndInfrastructureReady
218-
- linters:
219-
- staticcheck
220-
text: "SA1019: predicates.ClusterUnpausedAndInfrastructureReady is deprecated: This predicate is deprecated and will be removed in a future version, use ClusterPausedTransitionsOrInfrastructureReady instead."
221217
- linters:
222218
- revive
223219
text: "exported: exported method .*\\.(Reconcile|SetupWithManager|SetupWebhookWithManager) should have comment or be unexported"

apis/v1beta1/vspherecluster_types.go

+73-1
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,78 @@ const (
2828
ClusterFinalizer = "vspherecluster.infrastructure.cluster.x-k8s.io"
2929
)
3030

31+
// VSphereCluster's Ready condition and corresponding reasons that will be used in v1Beta2 API version.
32+
const (
33+
// VSphereClusterReadyV1Beta2Condition is true if the VSphereCluster's deletionTimestamp is not set, VSphereCluster's
34+
// FailureDomainsReady, VCenterAvailable and ClusterModulesReady conditions are true.
35+
VSphereClusterReadyV1Beta2Condition = clusterv1.ReadyV1Beta2Condition
36+
37+
// VSphereClusterReadyV1Beta2Reason surfaces when the VSphereCluster readiness criteria is met.
38+
VSphereClusterReadyV1Beta2Reason = clusterv1.ReadyV1Beta2Reason
39+
40+
// VSphereClusterNotReadyV1Beta2Reason surfaces when the VSphereCluster readiness criteria is not met.
41+
VSphereClusterNotReadyV1Beta2Reason = clusterv1.NotReadyV1Beta2Reason
42+
43+
// VSphereClusterReadyUnknownV1Beta2Reason surfaces when at least one VSphereCluster readiness criteria is unknown
44+
// and no VSphereCluster readiness criteria is not met.
45+
VSphereClusterReadyUnknownV1Beta2Reason = clusterv1.ReadyUnknownV1Beta2Reason
46+
)
47+
48+
// VSphereCluster's FailureDomainsReady condition and corresponding reasons that will be used in v1Beta2 API version.
49+
const (
50+
// VSphereClusterFailureDomainsReadyV1Beta2Condition documents the status of failure domains for a VSphereCluster.
51+
VSphereClusterFailureDomainsReadyV1Beta2Condition = "FailureDomainsReady"
52+
53+
// VSphereClusterFailureDomainsReadyV1Beta2Reason surfaces when the failure domains for a VSphereCluster are ready.
54+
VSphereClusterFailureDomainsReadyV1Beta2Reason = clusterv1.ReadyV1Beta2Reason
55+
56+
// VSphereClusterFailureDomainsWaitingForFailureDomainStatusV1Beta2Reason surfaces when not all VSphereFailureDomains for a VSphereCluster are ready.
57+
VSphereClusterFailureDomainsWaitingForFailureDomainStatusV1Beta2Reason = "WaitingForFailureDomainStatus"
58+
59+
// VSphereClusterFailureDomainsNotReadyV1Beta2Reason surfaces when the failure domains for a VSphereCluster are not ready.
60+
VSphereClusterFailureDomainsNotReadyV1Beta2Reason = clusterv1.NotReadyV1Beta2Reason
61+
62+
// VSphereClusterFailureDomainsDeletingV1Beta2Reason surfaces when the failure domains for a VSphereCluster are being deleted.
63+
VSphereClusterFailureDomainsDeletingV1Beta2Reason = clusterv1.DeletingV1Beta2Reason
64+
)
65+
66+
// VSphereCluster's VCenterAvailable condition and corresponding reasons that will be used in v1Beta2 API version.
67+
const (
68+
// VSphereClusterVCenterAvailableV1Beta2Condition documents the status of vCenter for a VSphereCluster.
69+
VSphereClusterVCenterAvailableV1Beta2Condition = "VCenterAvailable"
70+
71+
// VSphereClusterVCenterAvailableV1Beta2Reason surfaces when the vCenter for a VSphereCluster is available.
72+
VSphereClusterVCenterAvailableV1Beta2Reason = clusterv1.AvailableV1Beta2Reason
73+
74+
// VSphereClusterVCenterUnreachableV1Beta2Reason surfaces when the vCenter for a VSphereCluster is unreachable.
75+
VSphereClusterVCenterUnreachableV1Beta2Reason = "VCenterUnreachable"
76+
77+
// VSphereClusterVCenterNotAvailableV1Beta2Reason surfaces when the vCenter for a VSphereCluster is not available.
78+
VSphereClusterVCenterNotAvailableV1Beta2Reason = clusterv1.NotAvailableV1Beta2Reason
79+
80+
// VSphereClusterVCenterAvailableDeletingV1Beta2Reason surfaces when the VSphereCluster is being deleted.
81+
VSphereClusterVCenterAvailableDeletingV1Beta2Reason = clusterv1.DeletingV1Beta2Reason
82+
)
83+
84+
// VSphereCluster's ClusterModulesReady condition and corresponding reasons that will be used in v1Beta2 API version.
85+
const (
86+
// VSphereClusterClusterModulesReadyV1Beta2Condition documents the status of vCenter for a VSphereCluster.
87+
VSphereClusterClusterModulesReadyV1Beta2Condition = "ClusterModulesReady"
88+
89+
// VSphereClusterClusterModulesReadyV1Beta2Reason surfaces when the cluster modules for a VSphereCluster are ready.
90+
VSphereClusterClusterModulesReadyV1Beta2Reason = clusterv1.ReadyV1Beta2Reason
91+
92+
// VSphereClusterModulesInvalidVCenterVersionV1Beta2Reason surfaces when the cluster modules for a VSphereCluster can't be reconciled
93+
// due to an invalid vCenter version.
94+
VSphereClusterModulesInvalidVCenterVersionV1Beta2Reason = "InvalidVCenterVersion"
95+
96+
// VSphereClusterClusterModulesNotReadyV1Beta2Reason surfaces when the cluster modules for a VSphereCluster are not ready.
97+
VSphereClusterClusterModulesNotReadyV1Beta2Reason = clusterv1.NotReadyV1Beta2Reason
98+
99+
// VSphereClusterClusterModulesDeletingV1Beta2Reason surfaces when the cluster modules for a VSphereCluster are being deleted.
100+
VSphereClusterClusterModulesDeletingV1Beta2Reason = clusterv1.DeletingV1Beta2Reason
101+
)
102+
31103
// VCenterVersion conveys the API version of the vCenter instance.
32104
type VCenterVersion string
33105

@@ -114,7 +186,7 @@ type VSphereClusterStatus struct {
114186
// See https://github.com/kubernetes-sigs/cluster-api/blob/main/docs/proposals/20240916-improve-status-in-CAPI-resources.md for more context.
115187
type VSphereClusterV1Beta2Status struct {
116188
// conditions represents the observations of a VSphereCluster's current state.
117-
// Known condition types are Paused.
189+
// Known condition types are Ready, FailureDomainsReady, VCenterAvailable, ClusterModulesReady and Paused.
118190
// +optional
119191
// +listType=map
120192
// +listMapKey=type

config/default/crd/bases/infrastructure.cluster.x-k8s.io_vsphereclusters.yaml

+1-1
Original file line numberDiff line numberDiff line change
@@ -856,7 +856,7 @@ spec:
856856
conditions:
857857
description: |-
858858
conditions represents the observations of a VSphereCluster's current state.
859-
Known condition types are Paused.
859+
Known condition types are Ready, FailureDomainsReady, VCenterAvailable, ClusterModulesReady and Paused.
860860
items:
861861
description: Condition contains details for one aspect of the
862862
current state of this API Resource.

controllers/clustermodule_reconciler.go

+18
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import (
2828
controlplanev1 "sigs.k8s.io/cluster-api/controlplane/kubeadm/api/v1beta1"
2929
"sigs.k8s.io/cluster-api/util"
3030
"sigs.k8s.io/cluster-api/util/conditions"
31+
v1beta2conditions "sigs.k8s.io/cluster-api/util/conditions/v1beta2"
3132
ctrl "sigs.k8s.io/controller-runtime"
3233
"sigs.k8s.io/controller-runtime/pkg/client"
3334
"sigs.k8s.io/controller-runtime/pkg/controller"
@@ -69,6 +70,12 @@ func (r Reconciler) Reconcile(ctx context.Context, clusterCtx *capvcontext.Clust
6970
if !clustermodule.IsClusterCompatible(clusterCtx) {
7071
conditions.MarkFalse(clusterCtx.VSphereCluster, infrav1.ClusterModulesAvailableCondition, infrav1.VCenterVersionIncompatibleReason, clusterv1.ConditionSeverityInfo,
7172
"vCenter version %s does not support cluster modules", clusterCtx.VSphereCluster.Status.VCenterVersion)
73+
v1beta2conditions.Set(clusterCtx.VSphereCluster, metav1.Condition{
74+
Type: infrav1.VSphereClusterClusterModulesReadyV1Beta2Condition,
75+
Status: metav1.ConditionFalse,
76+
Reason: infrav1.VSphereClusterModulesInvalidVCenterVersionV1Beta2Reason,
77+
Message: fmt.Sprintf("vCenter version %s does not support cluster modules", clusterCtx.VSphereCluster.Status.VCenterVersion),
78+
})
7279
log.V(5).Info(fmt.Sprintf("vCenter version %s does not support cluster modules to implement anti affinity (vCenter >= 7 required)", clusterCtx.VSphereCluster.Status.VCenterVersion))
7380
return reconcile.Result{}, nil
7481
}
@@ -170,11 +177,22 @@ func (r Reconciler) Reconcile(ctx context.Context, clusterCtx *capvcontext.Clust
170177
}
171178
conditions.MarkFalse(clusterCtx.VSphereCluster, infrav1.ClusterModulesAvailableCondition, infrav1.ClusterModuleSetupFailedReason,
172179
clusterv1.ConditionSeverityWarning, generateClusterModuleErrorMessage(modErrs))
180+
v1beta2conditions.Set(clusterCtx.VSphereCluster, metav1.Condition{
181+
Type: infrav1.VSphereClusterClusterModulesReadyV1Beta2Condition,
182+
Status: metav1.ConditionFalse,
183+
Reason: infrav1.VSphereClusterClusterModulesNotReadyV1Beta2Reason,
184+
Message: generateClusterModuleErrorMessage(modErrs),
185+
})
173186
case len(modErrs) == 0 && len(clusterModuleSpecs) > 0:
174187
conditions.MarkTrue(clusterCtx.VSphereCluster, infrav1.ClusterModulesAvailableCondition)
175188
default:
176189
conditions.Delete(clusterCtx.VSphereCluster, infrav1.ClusterModulesAvailableCondition)
177190
}
191+
v1beta2conditions.Set(clusterCtx.VSphereCluster, metav1.Condition{
192+
Type: infrav1.VSphereClusterClusterModulesReadyV1Beta2Condition,
193+
Status: metav1.ConditionTrue,
194+
Reason: infrav1.VSphereClusterClusterModulesReadyV1Beta2Reason,
195+
})
178196
return reconcile.Result{}, err
179197
}
180198

controllers/vspherecluster_reconciler.go

+131-9
Original file line numberDiff line numberDiff line change
@@ -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
}()
@@ -117,18 +118,90 @@ func (r *clusterReconciler) Reconcile(ctx context.Context, req ctrl.Request) (_
117118
return r.reconcileDelete(ctx, clusterContext)
118119
}
119120

120-
if cluster == nil {
121-
log.Info("Waiting for Cluster controller to set OwnerRef on VSphereCluster")
122-
return reconcile.Result{}, nil
123-
}
124-
125121
// Handle non-deleted clusters
126122
return r.reconcileNormal(ctx, clusterContext)
127123
}
128124

125+
// patch updates the VSphereCluster and its status on the API server.
126+
func (r *clusterReconciler) patch(ctx context.Context, clusterCtx *capvcontext.ClusterContext) error {
127+
// always update the readyCondition.
128+
conditions.SetSummary(clusterCtx.VSphereCluster,
129+
conditions.WithConditions(
130+
infrav1.VCenterAvailableCondition,
131+
),
132+
)
133+
134+
if !v1beta2conditions.Has(clusterCtx.VSphereCluster, infrav1.VSphereClusterVCenterAvailableV1Beta2Condition) {
135+
v1beta2conditions.Set(clusterCtx.VSphereCluster, metav1.Condition{
136+
Type: infrav1.VSphereClusterVCenterAvailableV1Beta2Condition,
137+
Status: metav1.ConditionFalse,
138+
Reason: infrav1.VSphereClusterVCenterNotAvailableV1Beta2Reason,
139+
Message: "did not observe VCenterAvailable status",
140+
})
141+
}
142+
143+
if !v1beta2conditions.Has(clusterCtx.VSphereCluster, infrav1.VSphereClusterClusterModulesReadyV1Beta2Condition) {
144+
v1beta2conditions.Set(clusterCtx.VSphereCluster, metav1.Condition{
145+
Type: infrav1.VSphereClusterClusterModulesReadyV1Beta2Condition,
146+
Status: metav1.ConditionFalse,
147+
Reason: infrav1.VSphereClusterClusterModulesNotReadyV1Beta2Reason,
148+
Message: "did not observe cluster module status",
149+
})
150+
}
151+
152+
if err := v1beta2conditions.SetSummaryCondition(clusterCtx.VSphereCluster, clusterCtx.VSphereCluster, infrav1.VSphereClusterReadyV1Beta2Condition,
153+
v1beta2conditions.ForConditionTypes{
154+
infrav1.VSphereClusterFailureDomainsReadyV1Beta2Condition,
155+
infrav1.VSphereClusterVCenterAvailableV1Beta2Condition,
156+
infrav1.VSphereClusterClusterModulesReadyV1Beta2Condition,
157+
},
158+
// Using a custom merge strategy to override reasons applied during merge.
159+
v1beta2conditions.CustomMergeStrategy{
160+
MergeStrategy: v1beta2conditions.DefaultMergeStrategy(
161+
// Use custom reasons.
162+
v1beta2conditions.ComputeReasonFunc(v1beta2conditions.GetDefaultComputeMergeReasonFunc(
163+
infrav1.VSphereClusterNotReadyV1Beta2Reason,
164+
infrav1.VSphereClusterReadyUnknownV1Beta2Reason,
165+
infrav1.VSphereClusterReadyV1Beta2Reason,
166+
)),
167+
),
168+
},
169+
); err != nil {
170+
return pkgerrors.Wrapf(err, "failed to set %s condition", infrav1.VSphereClusterReadyV1Beta2Condition)
171+
}
172+
173+
return clusterCtx.PatchHelper.Patch(ctx, clusterCtx.VSphereCluster,
174+
patch.WithOwnedConditions{Conditions: []clusterv1.ConditionType{}},
175+
patch.WithOwnedV1Beta2Conditions{Conditions: []string{
176+
infrav1.VSphereClusterReadyV1Beta2Condition,
177+
infrav1.VSphereClusterFailureDomainsReadyV1Beta2Condition,
178+
infrav1.VSphereClusterVCenterAvailableV1Beta2Condition,
179+
infrav1.VSphereClusterClusterModulesReadyV1Beta2Condition,
180+
}},
181+
)
182+
}
183+
129184
func (r *clusterReconciler) reconcileDelete(ctx context.Context, clusterCtx *capvcontext.ClusterContext) (reconcile.Result, error) {
130185
log := ctrl.LoggerFrom(ctx)
131186

187+
v1beta2conditions.Set(clusterCtx.VSphereCluster, metav1.Condition{
188+
Type: infrav1.VSphereClusterVCenterAvailableV1Beta2Condition,
189+
Status: metav1.ConditionFalse,
190+
Reason: infrav1.VSphereClusterVCenterAvailableDeletingV1Beta2Reason,
191+
})
192+
193+
v1beta2conditions.Set(clusterCtx.VSphereCluster, metav1.Condition{
194+
Type: infrav1.VSphereClusterClusterModulesReadyV1Beta2Condition,
195+
Status: metav1.ConditionFalse,
196+
Reason: infrav1.VSphereClusterClusterModulesDeletingV1Beta2Reason,
197+
})
198+
199+
v1beta2conditions.Set(clusterCtx.VSphereCluster, metav1.Condition{
200+
Type: infrav1.VSphereClusterFailureDomainsReadyV1Beta2Condition,
201+
Status: metav1.ConditionFalse,
202+
Reason: infrav1.VSphereClusterFailureDomainsDeletingV1Beta2Reason,
203+
})
204+
132205
var vsphereMachines []client.Object
133206
var err error
134207
if clusterCtx.Cluster != nil {
@@ -193,35 +266,82 @@ func (r *clusterReconciler) reconcileNormal(ctx context.Context, clusterCtx *cap
193266

194267
ok, err := r.reconcileDeploymentZones(ctx, clusterCtx)
195268
if err != nil {
269+
v1beta2conditions.Set(clusterCtx.VSphereCluster, metav1.Condition{
270+
Type: infrav1.VSphereClusterFailureDomainsReadyV1Beta2Condition,
271+
Status: metav1.ConditionFalse,
272+
Reason: infrav1.VSphereClusterFailureDomainsNotReadyV1Beta2Reason,
273+
Message: err.Error(),
274+
})
196275
return reconcile.Result{}, err
197276
}
198277
if !ok {
199-
log.Info("Waiting for failure domains to be reconciled")
278+
v1beta2conditions.Set(clusterCtx.VSphereCluster, metav1.Condition{
279+
Type: infrav1.VSphereClusterFailureDomainsReadyV1Beta2Condition,
280+
Status: metav1.ConditionFalse,
281+
Reason: infrav1.VSphereClusterFailureDomainsWaitingForFailureDomainStatusV1Beta2Reason,
282+
Message: "waiting for failure domains to report ready status",
283+
})
200284
return reconcile.Result{RequeueAfter: 10 * time.Second}, nil
201285
}
286+
v1beta2conditions.Set(clusterCtx.VSphereCluster, metav1.Condition{
287+
Type: infrav1.VSphereClusterFailureDomainsReadyV1Beta2Condition,
288+
Status: metav1.ConditionTrue,
289+
Reason: infrav1.VSphereClusterFailureDomainsReadyV1Beta2Reason,
290+
})
291+
292+
// TODO check all occurencies of infrav1.VCenterAvailableCondition and infrav1.ClusterModulesAvailable/ready condition
202293

203294
if err := r.reconcileIdentitySecret(ctx, clusterCtx); err != nil {
204295
conditions.MarkFalse(clusterCtx.VSphereCluster, infrav1.VCenterAvailableCondition, infrav1.VCenterUnreachableReason, clusterv1.ConditionSeverityError, err.Error())
296+
v1beta2conditions.Set(clusterCtx.VSphereCluster, metav1.Condition{
297+
Type: infrav1.VSphereClusterVCenterAvailableV1Beta2Condition,
298+
Status: metav1.ConditionFalse,
299+
Reason: infrav1.VSphereClusterVCenterUnreachableV1Beta2Reason,
300+
Message: err.Error(),
301+
})
205302
return reconcile.Result{}, err
206303
}
207304

208305
vcenterSession, err := r.reconcileVCenterConnectivity(ctx, clusterCtx)
209306
if err != nil {
210307
conditions.MarkFalse(clusterCtx.VSphereCluster, infrav1.VCenterAvailableCondition, infrav1.VCenterUnreachableReason, clusterv1.ConditionSeverityError, err.Error())
308+
v1beta2conditions.Set(clusterCtx.VSphereCluster, metav1.Condition{
309+
Type: infrav1.VSphereClusterVCenterAvailableV1Beta2Condition,
310+
Status: metav1.ConditionFalse,
311+
Reason: infrav1.VSphereClusterVCenterUnreachableV1Beta2Reason,
312+
Message: err.Error(),
313+
})
211314
return reconcile.Result{}, pkgerrors.Wrapf(err,
212315
"unexpected error while probing vcenter for %s", clusterCtx)
213316
}
214317
conditions.MarkTrue(clusterCtx.VSphereCluster, infrav1.VCenterAvailableCondition)
318+
v1beta2conditions.Set(clusterCtx.VSphereCluster, metav1.Condition{
319+
Type: infrav1.VSphereClusterVCenterAvailableV1Beta2Condition,
320+
Status: metav1.ConditionTrue,
321+
Reason: infrav1.VSphereClusterVCenterAvailableV1Beta2Reason,
322+
})
215323

216324
err = r.reconcileVCenterVersion(clusterCtx, vcenterSession)
217325
if err != nil || clusterCtx.VSphereCluster.Status.VCenterVersion == "" {
218-
conditions.MarkFalse(clusterCtx.VSphereCluster, infrav1.ClusterModulesAvailableCondition, infrav1.MissingVCenterVersionReason, clusterv1.ConditionSeverityWarning, "vCenter version not set")
326+
conditions.MarkFalse(clusterCtx.VSphereCluster, infrav1.ClusterModulesAvailableCondition, infrav1.MissingVCenterVersionReason, clusterv1.ConditionSeverityWarning, err.Error())
327+
v1beta2conditions.Set(clusterCtx.VSphereCluster, metav1.Condition{
328+
Type: infrav1.VSphereClusterClusterModulesReadyV1Beta2Condition,
329+
Status: metav1.ConditionFalse,
330+
Reason: infrav1.VSphereClusterModulesInvalidVCenterVersionV1Beta2Reason,
331+
Message: err.Error(),
332+
})
219333
log.Error(err, "could not reconcile vCenter version")
220334
}
221335

222336
affinityReconcileResult, err := r.reconcileClusterModules(ctx, clusterCtx)
223337
if err != nil {
224338
conditions.MarkFalse(clusterCtx.VSphereCluster, infrav1.ClusterModulesAvailableCondition, infrav1.ClusterModuleSetupFailedReason, clusterv1.ConditionSeverityWarning, err.Error())
339+
v1beta2conditions.Set(clusterCtx.VSphereCluster, metav1.Condition{
340+
Type: infrav1.VSphereClusterClusterModulesReadyV1Beta2Condition,
341+
Status: metav1.ConditionFalse,
342+
Reason: infrav1.VSphereClusterClusterModulesNotReadyV1Beta2Reason,
343+
Message: err.Error(),
344+
})
225345
return affinityReconcileResult, err
226346
}
227347

@@ -295,13 +415,14 @@ func (r *clusterReconciler) reconcileVCenterConnectivity(ctx context.Context, cl
295415
func (r *clusterReconciler) reconcileVCenterVersion(clusterCtx *capvcontext.ClusterContext, s *session.Session) error {
296416
version, err := s.GetVersion()
297417
if err != nil {
298-
return err
418+
return pkgerrors.Wrapf(err, "invalid vCenter version")
299419
}
300420
clusterCtx.VSphereCluster.Status.VCenterVersion = version
301421
return nil
302422
}
303423

304424
func (r *clusterReconciler) reconcileDeploymentZones(ctx context.Context, clusterCtx *capvcontext.ClusterContext) (bool, error) {
425+
log := ctrl.LoggerFrom(ctx)
305426
// If there is no failure domain selector, skip reconciliation
306427
if clusterCtx.VSphereCluster.Spec.FailureDomainSelector == nil {
307428
return true, nil
@@ -346,6 +467,7 @@ func (r *clusterReconciler) reconcileDeploymentZones(ctx context.Context, cluste
346467

347468
clusterCtx.VSphereCluster.Status.FailureDomains = failureDomains
348469
if readyNotReported > 0 {
470+
log.Info("Waiting for failure domains to be reconciled")
349471
conditions.MarkFalse(clusterCtx.VSphereCluster, infrav1.FailureDomainsAvailableCondition, infrav1.WaitingForFailureDomainStatusReason, clusterv1.ConditionSeverityInfo, "waiting for failure domains to report ready status")
350472
return false, nil
351473
}

0 commit comments

Comments
 (0)