Skip to content

Commit eac7a3c

Browse files
🌱 Add v1beta2 conditions to vSphereCluster, supervisor mode (#3383)
* Add v1beta2 conditions to vSphereCluster, supervisor mode # Conflicts: # controllers/vmware/vspherecluster_reconciler.go * Run generators * Fix unit tests * Add ProviderServiceAccountsReady and ServiceDiscoveryReady conditions * Fix imports after rebase * Make generate * Address feedback
1 parent c6b4700 commit eac7a3c

14 files changed

+478
-25
lines changed

‎apis/vmware/v1beta1/vspherecluster_types.go‎

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,95 @@ const (
3434
ProviderServiceAccountFinalizer = "providerserviceaccount.vmware.infrastructure.cluster.x-k8s.io"
3535
)
3636

37+
// VSphereCluster's Ready condition and corresponding reasons that will be used in v1Beta2 API version.
38+
const (
39+
// VSphereClusterReadyV1Beta2Condition is true if the VSphereCluster's deletionTimestamp is not set, VSphereCluster's
40+
// ResourcePolicyReady, NetworkReady, LoadBalancerReady, ProviderServiceAccountsReady and ServiceDiscoveryReady conditions are true.
41+
VSphereClusterReadyV1Beta2Condition = clusterv1.ReadyV1Beta2Condition
42+
43+
// VSphereClusterReadyV1Beta2Reason surfaces when the VSphereCluster readiness criteria is met.
44+
VSphereClusterReadyV1Beta2Reason = clusterv1.ReadyV1Beta2Reason
45+
46+
// VSphereClusterNotReadyV1Beta2Reason surfaces when the VSphereCluster readiness criteria is not met.
47+
VSphereClusterNotReadyV1Beta2Reason = clusterv1.NotReadyV1Beta2Reason
48+
49+
// VSphereClusterReadyUnknownV1Beta2Reason surfaces when at least one VSphereCluster readiness criteria is unknown
50+
// and no VSphereCluster readiness criteria is not met.
51+
VSphereClusterReadyUnknownV1Beta2Reason = clusterv1.ReadyUnknownV1Beta2Reason
52+
)
53+
54+
// VSphereCluster's ResourcePolicyReady condition and corresponding reasons that will be used in v1Beta2 API version.
55+
const (
56+
// VSphereClusterResourcePolicyReadyV1Beta2Condition documents the status of the ResourcePolicy for a VSphereCluster.
57+
VSphereClusterResourcePolicyReadyV1Beta2Condition = "ResourcePolicyReady"
58+
59+
// VSphereClusterResourcePolicyReadyV1Beta2Reason surfaces when the ResourcePolicy for a VSphereCluster is ready.
60+
VSphereClusterResourcePolicyReadyV1Beta2Reason = clusterv1.ReadyV1Beta2Reason
61+
62+
// VSphereClusterResourcePolicyNotReadyV1Beta2Reason surfaces when the ResourcePolicy for a VSphereCluster is not ready.
63+
VSphereClusterResourcePolicyNotReadyV1Beta2Reason = clusterv1.NotReadyV1Beta2Reason
64+
65+
// VSphereClusterResourcePolicyReadyDeletingV1Beta2Reason surfaces when the resource policy for a VSphereCluster is being deleted.
66+
VSphereClusterResourcePolicyReadyDeletingV1Beta2Reason = clusterv1.DeletingV1Beta2Reason
67+
)
68+
69+
// VSphereCluster's NetworkReady condition and corresponding reasons that will be used in v1Beta2 API version.
70+
const (
71+
// VSphereClusterNetworkReadyV1Beta2Condition documents the status of the network for a VSphereCluster.
72+
VSphereClusterNetworkReadyV1Beta2Condition = "NetworkReady"
73+
74+
// VSphereClusterNetworkReadyV1Beta2Reason surfaces when the network for a VSphereCluster is ready.
75+
VSphereClusterNetworkReadyV1Beta2Reason = clusterv1.ReadyV1Beta2Reason
76+
77+
// VSphereClusterNetworkNotReadyV1Beta2Reason surfaces when the network for a VSphereCluster is not ready.
78+
VSphereClusterNetworkNotReadyV1Beta2Reason = clusterv1.NotReadyV1Beta2Reason
79+
80+
// VSphereClusterNetworkReadyDeletingV1Beta2Reason surfaces when the network for a VSphereCluster is being deleted.
81+
VSphereClusterNetworkReadyDeletingV1Beta2Reason = clusterv1.DeletingV1Beta2Reason
82+
)
83+
84+
// VSphereCluster's LoadBalancerReady condition and corresponding reasons that will be used in v1Beta2 API version.
85+
const (
86+
// VSphereClusterLoadBalancerReadyV1Beta2Condition documents the status of the LoadBalancer for a VSphereCluster.
87+
VSphereClusterLoadBalancerReadyV1Beta2Condition = "LoadBalancerReady"
88+
89+
// VSphereClusterLoadBalancerReadyV1Beta2Reason surfaces when the LoadBalancer for a VSphereCluster is ready.
90+
VSphereClusterLoadBalancerReadyV1Beta2Reason = clusterv1.ReadyV1Beta2Reason
91+
92+
// VSphereClusterLoadBalancerNotReadyV1Beta2Reason surfaces when the LoadBalancer for a VSphereCluster is not ready.
93+
VSphereClusterLoadBalancerNotReadyV1Beta2Reason = clusterv1.NotReadyV1Beta2Reason
94+
95+
// VSphereClusterLoadBalancerWaitingForIPV1Beta2Reason surfaces when the LoadBalancer for a VSphereCluster is waiting for an IP to be assigned.
96+
VSphereClusterLoadBalancerWaitingForIPV1Beta2Reason = "WaitingForIP"
97+
98+
// VSphereClusterLoadBalancerDeletingV1Beta2Reason surfaces when the LoadBalancer for a VSphereCluster is being deleted.
99+
VSphereClusterLoadBalancerDeletingV1Beta2Reason = clusterv1.DeletingV1Beta2Reason
100+
)
101+
102+
// VSphereCluster's ProviderServiceAccountsReady condition and corresponding reasons that will be used in v1Beta2 API version.
103+
const (
104+
// VSphereClusterProviderServiceAccountsReadyV1Beta2Condition documents the status of the provider service accounts for a VSphereCluster.
105+
VSphereClusterProviderServiceAccountsReadyV1Beta2Condition = "ProviderServiceAccountsReady"
106+
107+
// VSphereClusterProviderServiceAccountsReadyV1Beta2Reason surfaces when the provider service accounts for a VSphereCluster is ready.
108+
VSphereClusterProviderServiceAccountsReadyV1Beta2Reason = clusterv1.ReadyV1Beta2Reason
109+
110+
// VSphereClusterProviderServiceAccountsNotReadyV1Beta2Reason surfaces when the provider service accounts for a VSphereCluster is not ready.
111+
VSphereClusterProviderServiceAccountsNotReadyV1Beta2Reason = clusterv1.NotReadyV1Beta2Reason
112+
)
113+
114+
// VSphereCluster's ServiceDiscoveryReady condition and corresponding reasons that will be used in v1Beta2 API version.
115+
const (
116+
// VSphereClusterServiceDiscoveryReadyV1Beta2Condition documents the status of the service discovery for a VSphereCluster.
117+
VSphereClusterServiceDiscoveryReadyV1Beta2Condition = "ServiceDiscoveryReady"
118+
119+
// VSphereClusterServiceDiscoveryReadyV1Beta2Reason surfaces when the service discovery for a VSphereCluster is ready.
120+
VSphereClusterServiceDiscoveryReadyV1Beta2Reason = clusterv1.ReadyV1Beta2Reason
121+
122+
// VSphereClusterServiceDiscoveryNotReadyV1Beta2Reason surfaces when the service discovery for a VSphereCluster is not ready.
123+
VSphereClusterServiceDiscoveryNotReadyV1Beta2Reason = clusterv1.NotReadyV1Beta2Reason
124+
)
125+
37126
// VSphereClusterSpec defines the desired state of VSphereCluster.
38127
type VSphereClusterSpec struct {
39128
// +optional
@@ -59,6 +148,23 @@ type VSphereClusterStatus struct {
59148
// FailureDomains is a list of failure domain objects synced from the
60149
// infrastructure provider.
61150
FailureDomains clusterv1.FailureDomains `json:"failureDomains,omitempty"`
151+
152+
// v1beta2 groups all the fields that will be added or modified in VSphereCluster's status with the V1Beta2 version.
153+
// +optional
154+
V1Beta2 *VSphereClusterV1Beta2Status `json:"v1beta2,omitempty"`
155+
}
156+
157+
// VSphereClusterV1Beta2Status groups all the fields that will be added or modified in VSphereClusterStatus with the V1Beta2 version.
158+
// See https://github.com/kubernetes-sigs/cluster-api/blob/main/docs/proposals/20240916-improve-status-in-CAPI-resources.md for more context.
159+
type VSphereClusterV1Beta2Status struct {
160+
// conditions represents the observations of a VSphereCluster's current state.
161+
// Known condition types are Ready, ResourcePolicyReady, NetworkReady, LoadBalancerReady,
162+
// ProviderServiceAccountsReady and ServiceDiscoveryReady conditions.
163+
// +optional
164+
// +listType=map
165+
// +listMapKey=type
166+
// +kubebuilder:validation:MaxItems=32
167+
Conditions []metav1.Condition `json:"conditions,omitempty"`
62168
}
63169

64170
// +kubebuilder:object:root=true
@@ -94,6 +200,22 @@ func (r *VSphereCluster) SetConditions(conditions clusterv1.Conditions) {
94200
r.Status.Conditions = conditions
95201
}
96202

203+
// GetV1Beta2Conditions returns the set of conditions for this object.
204+
func (r *VSphereCluster) GetV1Beta2Conditions() []metav1.Condition {
205+
if r.Status.V1Beta2 == nil {
206+
return nil
207+
}
208+
return r.Status.V1Beta2.Conditions
209+
}
210+
211+
// SetV1Beta2Conditions sets conditions for an API object.
212+
func (r *VSphereCluster) SetV1Beta2Conditions(conditions []metav1.Condition) {
213+
if r.Status.V1Beta2 == nil {
214+
r.Status.V1Beta2 = &VSphereClusterV1Beta2Status{}
215+
}
216+
r.Status.V1Beta2.Conditions = conditions
217+
}
218+
97219
func init() {
98220
objectTypes = append(objectTypes, &VSphereCluster{}, &VSphereClusterList{})
99221
}

‎apis/vmware/v1beta1/zz_generated.deepcopy.go‎

Lines changed: 28 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎config/supervisor/crd/bases/vmware.infrastructure.cluster.x-k8s.io_vsphereclusters.yaml‎

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,76 @@ spec:
135135
ResourcePolicyName is the name of the VirtualMachineSetResourcePolicy for
136136
the cluster, if one exists
137137
type: string
138+
v1beta2:
139+
description: v1beta2 groups all the fields that will be added or modified
140+
in VSphereCluster's status with the V1Beta2 version.
141+
properties:
142+
conditions:
143+
description: |-
144+
conditions represents the observations of a VSphereCluster's current state.
145+
Known condition types are Ready, ResourcePolicyReady, NetworkReady, LoadBalancerReady,
146+
ProviderServiceAccountsReady and ServiceDiscoveryReady conditions.
147+
items:
148+
description: Condition contains details for one aspect of the
149+
current state of this API Resource.
150+
properties:
151+
lastTransitionTime:
152+
description: |-
153+
lastTransitionTime is the last time the condition transitioned from one status to another.
154+
This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable.
155+
format: date-time
156+
type: string
157+
message:
158+
description: |-
159+
message is a human readable message indicating details about the transition.
160+
This may be an empty string.
161+
maxLength: 32768
162+
type: string
163+
observedGeneration:
164+
description: |-
165+
observedGeneration represents the .metadata.generation that the condition was set based upon.
166+
For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date
167+
with respect to the current state of the instance.
168+
format: int64
169+
minimum: 0
170+
type: integer
171+
reason:
172+
description: |-
173+
reason contains a programmatic identifier indicating the reason for the condition's last transition.
174+
Producers of specific condition types may define expected values and meanings for this field,
175+
and whether the values are considered a guaranteed API.
176+
The value should be a CamelCase string.
177+
This field may not be empty.
178+
maxLength: 1024
179+
minLength: 1
180+
pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$
181+
type: string
182+
status:
183+
description: status of the condition, one of True, False,
184+
Unknown.
185+
enum:
186+
- "True"
187+
- "False"
188+
- Unknown
189+
type: string
190+
type:
191+
description: type of condition in CamelCase or in foo.example.com/CamelCase.
192+
maxLength: 316
193+
pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$
194+
type: string
195+
required:
196+
- lastTransitionTime
197+
- message
198+
- reason
199+
- status
200+
- type
201+
type: object
202+
maxItems: 32
203+
type: array
204+
x-kubernetes-list-map-keys:
205+
- type
206+
x-kubernetes-list-type: map
207+
type: object
138208
type: object
139209
type: object
140210
served: true

‎controllers/vmware/serviceaccount_controller.go‎

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ import (
3636
clusterutilv1 "sigs.k8s.io/cluster-api/util"
3737
"sigs.k8s.io/cluster-api/util/annotations"
3838
"sigs.k8s.io/cluster-api/util/conditions"
39+
v1beta2conditions "sigs.k8s.io/cluster-api/util/conditions/v1beta2"
3940
"sigs.k8s.io/cluster-api/util/patch"
4041
"sigs.k8s.io/cluster-api/util/predicates"
4142
ctrl "sigs.k8s.io/controller-runtime"
@@ -150,7 +151,7 @@ func (r *ServiceAccountReconciler) Reconcile(ctx context.Context, req reconcile.
150151
// Always issue a patch when exiting this function so changes to the
151152
// resource are patched back to the API server.
152153
defer func() {
153-
if err := clusterContext.Patch(ctx); err != nil {
154+
if err := r.patch(ctx, clusterContext); err != nil {
154155
reterr = kerrors.NewAggregate([]error{reterr, err})
155156
}
156157
}()
@@ -188,14 +189,37 @@ func (r *ServiceAccountReconciler) Reconcile(ctx context.Context, req reconcile.
188189
})
189190
}
190191

192+
func (r *ServiceAccountReconciler) patch(ctx context.Context, clusterCtx *vmwarecontext.ClusterContext) error {
193+
// NOTE: this controller only owns the ProviderServiceAccountsReady condition on the VSphereCluster object.
194+
return clusterCtx.PatchHelper.Patch(ctx, clusterCtx.VSphereCluster,
195+
patch.WithOwnedConditions{Conditions: []clusterv1.ConditionType{
196+
vmwarev1.ProviderServiceAccountsReadyCondition,
197+
}},
198+
patch.WithOwnedV1Beta2Conditions{Conditions: []string{
199+
vmwarev1.VSphereClusterProviderServiceAccountsReadyV1Beta2Condition,
200+
}},
201+
)
202+
}
203+
191204
// reconcileNormal handles create and update events for ProviderServiceAccounts.
192205
func (r *ServiceAccountReconciler) reconcileNormal(ctx context.Context, guestClusterCtx *vmwarecontext.GuestClusterContext) (_ reconcile.Result, reterr error) {
193206
defer func() {
194207
if reterr != nil {
195208
conditions.MarkFalse(guestClusterCtx.VSphereCluster, vmwarev1.ProviderServiceAccountsReadyCondition, vmwarev1.ProviderServiceAccountsReconciliationFailedReason,
196209
clusterv1.ConditionSeverityWarning, reterr.Error())
210+
v1beta2conditions.Set(guestClusterCtx.VSphereCluster, metav1.Condition{
211+
Type: vmwarev1.VSphereClusterProviderServiceAccountsReadyV1Beta2Condition,
212+
Status: metav1.ConditionFalse,
213+
Reason: vmwarev1.VSphereClusterProviderServiceAccountsNotReadyV1Beta2Reason,
214+
Message: reterr.Error(),
215+
})
197216
} else {
198217
conditions.MarkTrue(guestClusterCtx.VSphereCluster, vmwarev1.ProviderServiceAccountsReadyCondition)
218+
v1beta2conditions.Set(guestClusterCtx.VSphereCluster, metav1.Condition{
219+
Type: vmwarev1.VSphereClusterProviderServiceAccountsReadyV1Beta2Condition,
220+
Status: metav1.ConditionTrue,
221+
Reason: vmwarev1.VSphereClusterProviderServiceAccountsReadyV1Beta2Reason,
222+
})
199223
}
200224
}()
201225

‎controllers/vmware/servicediscovery_controller.go‎

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ import (
4141
clusterutilv1 "sigs.k8s.io/cluster-api/util"
4242
"sigs.k8s.io/cluster-api/util/annotations"
4343
"sigs.k8s.io/cluster-api/util/conditions"
44+
v1beta2conditions "sigs.k8s.io/cluster-api/util/conditions/v1beta2"
4445
"sigs.k8s.io/cluster-api/util/patch"
4546
"sigs.k8s.io/cluster-api/util/predicates"
4647
ctrl "sigs.k8s.io/controller-runtime"
@@ -194,7 +195,7 @@ func (r *serviceDiscoveryReconciler) Reconcile(ctx context.Context, req reconcil
194195
// Always issue a patch when exiting this function so changes to the
195196
// resource are patched back to the API server.
196197
defer func() {
197-
if err := clusterContext.Patch(ctx); err != nil {
198+
if err := r.patch(ctx, clusterContext); err != nil {
198199
reterr = kerrors.NewAggregate([]error{reterr, err})
199200
}
200201
}()
@@ -223,10 +224,28 @@ func (r *serviceDiscoveryReconciler) Reconcile(ctx context.Context, req reconcil
223224
})
224225
}
225226

227+
func (r *serviceDiscoveryReconciler) patch(ctx context.Context, clusterCtx *vmwarecontext.ClusterContext) error {
228+
// NOTE: this controller only owns the ServiceDiscoveryReady condition on the VSphereCluster object.
229+
return clusterCtx.PatchHelper.Patch(ctx, clusterCtx.VSphereCluster,
230+
patch.WithOwnedConditions{Conditions: []clusterv1.ConditionType{
231+
vmwarev1.ServiceDiscoveryReadyCondition,
232+
}},
233+
patch.WithOwnedV1Beta2Conditions{Conditions: []string{
234+
vmwarev1.VSphereClusterServiceDiscoveryReadyV1Beta2Condition,
235+
}},
236+
)
237+
}
238+
226239
func (r *serviceDiscoveryReconciler) reconcileNormal(ctx context.Context, guestClusterCtx *vmwarecontext.GuestClusterContext) error {
227240
if err := r.reconcileSupervisorHeadlessService(ctx, guestClusterCtx); err != nil {
228241
conditions.MarkFalse(guestClusterCtx.VSphereCluster, vmwarev1.ServiceDiscoveryReadyCondition, vmwarev1.SupervisorHeadlessServiceSetupFailedReason,
229242
clusterv1.ConditionSeverityWarning, err.Error())
243+
v1beta2conditions.Set(guestClusterCtx.VSphereCluster, metav1.Condition{
244+
Type: vmwarev1.VSphereClusterServiceDiscoveryReadyV1Beta2Condition,
245+
Status: metav1.ConditionFalse,
246+
Reason: vmwarev1.VSphereClusterServiceDiscoveryNotReadyV1Beta2Reason,
247+
Message: err.Error(),
248+
})
230249
return errors.Wrapf(err, "failed to reconcile supervisor headless Service")
231250
}
232251

@@ -265,6 +284,12 @@ func (r *serviceDiscoveryReconciler) reconcileSupervisorHeadlessService(ctx cont
265284
// There is no need to return an error to keep re-trying.
266285
conditions.MarkFalse(guestClusterCtx.VSphereCluster, vmwarev1.ServiceDiscoveryReadyCondition, vmwarev1.SupervisorHeadlessServiceSetupFailedReason,
267286
clusterv1.ConditionSeverityWarning, err.Error())
287+
v1beta2conditions.Set(guestClusterCtx.VSphereCluster, metav1.Condition{
288+
Type: vmwarev1.VSphereClusterServiceDiscoveryReadyV1Beta2Condition,
289+
Status: metav1.ConditionFalse,
290+
Reason: vmwarev1.VSphereClusterServiceDiscoveryNotReadyV1Beta2Reason,
291+
Message: err.Error(),
292+
})
268293
return nil
269294
}
270295

@@ -314,6 +339,11 @@ func (r *serviceDiscoveryReconciler) reconcileSupervisorHeadlessService(ctx cont
314339
}
315340

316341
conditions.MarkTrue(guestClusterCtx.VSphereCluster, vmwarev1.ServiceDiscoveryReadyCondition)
342+
v1beta2conditions.Set(guestClusterCtx.VSphereCluster, metav1.Condition{
343+
Type: vmwarev1.VSphereClusterServiceDiscoveryReadyV1Beta2Condition,
344+
Status: metav1.ConditionTrue,
345+
Reason: vmwarev1.VSphereClusterServiceDiscoveryReadyV1Beta2Reason,
346+
})
317347
return nil
318348
}
319349

0 commit comments

Comments
 (0)