Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions api/v1beta1/awscluster_conversion.go
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,9 @@ func (src *AWSCluster) ConvertTo(dstRaw conversion.Hub) error {
}
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we should touch v1beta1 types at all.
Only v1beta2 ones

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@damdo just to make sure i’m understanding correctly about the v1beta1 conversion changes, should i remove the V1Beta3 restoration logic from awscluster_conversion.go? i followed the same pattern used for existing fields like ControlPlaneLoadBalancer, but i’m totally fine removing it if that’s not the direction we want to take.
wanted to confirm this part before i move on to the rest of the feedback. thanks

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As we are adding new fields in v1beta2 then we need to preserve roundtrip compatibility. So it will require that you update the conversions in v1beta1 like you have done here to restore the value.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A lot of people make the mistake of adding the new field to old api versions as well to make the conversions work. But restoring the value from the saved state is the correct way (like you are doing).

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As we are adding new fields in v1beta2 then we need to preserve roundtrip compatibility. So it will require that you update the conversions in v1beta1 like you have done here to restore the value.

Good point! Hadn't thought about that!

}

// Restore V1Beta2 status from annotations.
dst.Status.V1Beta2 = restored.Status.V1Beta2

return nil
}

Expand Down Expand Up @@ -230,3 +233,10 @@ func (r *AWSClusterList) ConvertFrom(srcRaw conversion.Hub) error {
func Convert_v1beta2_SubnetSpec_To_v1beta1_SubnetSpec(in *infrav1.SubnetSpec, out *SubnetSpec, s apiconversion.Scope) error {
return autoConvert_v1beta2_SubnetSpec_To_v1beta1_SubnetSpec(in, out, s)
}

// Convert_v1beta2_AWSClusterStatus_To_v1beta1_AWSClusterStatus handles the V1Beta2 field
// that doesn't exist in v1beta1. The V1Beta2 conditions are dropped during down-conversion
// and will be restored from annotations during up-conversion.
func Convert_v1beta2_AWSClusterStatus_To_v1beta1_AWSClusterStatus(in *infrav1.AWSClusterStatus, out *AWSClusterStatus, s apiconversion.Scope) error {
return autoConvert_v1beta2_AWSClusterStatus_To_v1beta1_AWSClusterStatus(in, out, s)
}
16 changes: 6 additions & 10 deletions api/v1beta1/zz_generated.conversion.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

35 changes: 35 additions & 0 deletions api/v1beta2/awscluster_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,23 @@ type AWSClusterStatus struct {
FailureDomains clusterv1beta1.FailureDomains `json:"failureDomains,omitempty"`
Bastion *Instance `json:"bastion,omitempty"`
Conditions clusterv1beta1.Conditions `json:"conditions,omitempty"`

// v1beta2 groups all the fields that will be added or modified in AWSCluster's status with the V1Beta2 CAPI contract version.
// +optional
V1Beta2 *AWSClusterV1Beta2Status `json:"v1beta2,omitempty"`
}

// AWSClusterV1Beta2Status groups all the fields that will be added or modified in AWSCluster with the V1Beta2 CAPI contract version.
// See https://github.com/kubernetes-sigs/cluster-api/blob/main/docs/proposals/20240916-improve-status-in-CAPI-resources.md for more context.
type AWSClusterV1Beta2Status struct {
// Conditions represents the observations of an AWSCluster's current state.
// Known condition types are Ready, VpcReady, SubnetsReady, InternetGatewayReady, NatGatewaysReady,
// RouteTablesReady, ClusterSecurityGroupsReady, BastionHostReady, LoadBalancerReady, and Paused.
// +optional
// +listType=map
// +listMapKey=type
// +kubebuilder:validation:MaxItems=32
Conditions []metav1.Condition `json:"conditions,omitempty"`
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are we only dealing with AWSCluster and Conditions here?
If we do it this granular we'll potentially end up with (number of API types) x (number of fields to add) PRs

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

my bad, i was initially planning to split these into separate prs to keep things smaller,. i agree it’s better to avoid creating too many prs for closely related changes.

Copy link
Copy Markdown
Contributor Author

@Arpit529Srivastava Arpit529Srivastava Feb 5, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

rethinking again, once we settle on the approach for v1beta1 conversions, #5854 (comment) i’ll add the same V1Beta3 status field to the other types as well (AWSMachine, AWSMachinePool, AWSManagedMachinePool, etc ...) in this same pr. just wanted to make sure we’re aligned on the pattern with AWSCluster first before rolling it out everywhere.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm happy either way. Smaller PRs always helps with review though.

}

// S3Bucket defines a supporting S3 bucket for the cluster, currently can be optionally used for Ignition.
Expand Down Expand Up @@ -355,6 +372,24 @@ func (r *AWSCluster) SetConditions(conditions clusterv1beta1.Conditions) {
r.Status.Conditions = conditions
}

// GetV1Beta2Conditions returns the set of conditions for this object.
// Note: GetV1Beta2Conditions will be renamed to GetConditions in a later stage of the transition to CAPI contract V1Beta2.
func (r *AWSCluster) GetV1Beta2Conditions() []metav1.Condition {
if r.Status.V1Beta2 == nil {
return nil
}
return r.Status.V1Beta2.Conditions
}

// SetV1Beta2Conditions sets conditions for an API object.
// Note: SetV1Beta2Conditions will be renamed to SetConditions in a later stage of the transition to CAPI contract V1Beta2.
func (r *AWSCluster) SetV1Beta2Conditions(conditions []metav1.Condition) {
if r.Status.V1Beta2 == nil {
r.Status.V1Beta2 = &AWSClusterV1Beta2Status{}
}
r.Status.V1Beta2.Conditions = conditions
}

func init() {
SchemeBuilder.Register(&AWSCluster{}, &AWSClusterList{})
}
27 changes: 27 additions & 0 deletions api/v1beta2/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

70 changes: 70 additions & 0 deletions config/crd/bases/infrastructure.cluster.x-k8s.io_awsclusters.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3159,6 +3159,76 @@ spec:
ready:
default: false
type: boolean
v1beta2:
description: v1beta2 groups all the fields that will be added or modified
in AWSCluster's status with the V1Beta2 CAPI contract version.
properties:
conditions:
description: |-
Conditions represents the observations of an AWSCluster's current state.
Known condition types are Ready, VpcReady, SubnetsReady, InternetGatewayReady, NatGatewaysReady,
RouteTablesReady, ClusterSecurityGroupsReady, BastionHostReady, LoadBalancerReady, and Paused.
items:
description: Condition contains details for one aspect of the
current state of this API Resource.
properties:
lastTransitionTime:
description: |-
lastTransitionTime is the last time the condition transitioned from one status to another.
This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable.
format: date-time
type: string
message:
description: |-
message is a human readable message indicating details about the transition.
This may be an empty string.
maxLength: 32768
type: string
observedGeneration:
description: |-
observedGeneration represents the .metadata.generation that the condition was set based upon.
For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date
with respect to the current state of the instance.
format: int64
minimum: 0
type: integer
reason:
description: |-
reason contains a programmatic identifier indicating the reason for the condition's last transition.
Producers of specific condition types may define expected values and meanings for this field,
and whether the values are considered a guaranteed API.
The value should be a CamelCase string.
This field may not be empty.
maxLength: 1024
minLength: 1
pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$
type: string
status:
description: status of the condition, one of True, False,
Unknown.
enum:
- "True"
- "False"
- Unknown
type: string
type:
description: type of condition in CamelCase or in foo.example.com/CamelCase.
maxLength: 316
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])$
type: string
required:
- lastTransitionTime
- message
- reason
- status
- type
type: object
maxItems: 32
type: array
x-kubernetes-list-map-keys:
- type
x-kubernetes-list-type: map
type: object
required:
- ready
type: object
Expand Down