Skip to content

⚠️ Change all *metav1.Time fields to metav1.Time #12518

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Jul 25, 2025
Merged
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
4 changes: 4 additions & 0 deletions .golangci-kal.yml
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,10 @@ linters:
text: "optionalfields: field (Status|Initialization) is optional and should (be a pointer|have the omitempty tag)"
linters:
- kubeapilinter
- path: "api/.*"
text: "optionalfields: field (LastAppliedTime|Expires|After|LastUpdated|CertificatesExpiryDate|NodeDrainStartTime|WaitForNodeVolumeDetachStartTime) is optional and should (be a pointer|have the omitempty tag)"
linters:
- kubeapilinter
- path: "api/bootstrap/kubeadm/v1beta2"
text: "optionalfields: field (Spec|NodeRegistration|LocalAPIEndpoint|Etcd|APIServer|ControllerManager|Scheduler|DNS|Discovery|ObjectMeta) is optional and should (be a pointer|have the omitempty tag)"
linters:
Expand Down
21 changes: 21 additions & 0 deletions api/addons/v1beta1/conversion.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (

metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
apimachineryconversion "k8s.io/apimachinery/pkg/conversion"
"k8s.io/utils/ptr"
"sigs.k8s.io/controller-runtime/pkg/conversion"

addonsv1 "sigs.k8s.io/cluster-api/api/addons/v1beta2"
Expand Down Expand Up @@ -122,6 +123,26 @@ func Convert_v1beta2_ResourceSetBinding_To_Pointer_v1beta1_ResourceSetBinding(in
return autoConvert_v1beta2_ResourceSetBinding_To_v1beta1_ResourceSetBinding(in, *out, s)
}

func Convert_v1beta1_ResourceBinding_To_v1beta2_ResourceBinding(in *ResourceBinding, out *addonsv1.ResourceBinding, s apimachineryconversion.Scope) error {
if err := autoConvert_v1beta1_ResourceBinding_To_v1beta2_ResourceBinding(in, out, s); err != nil {
return err
}
if in.LastAppliedTime != nil && !reflect.DeepEqual(in.LastAppliedTime, &metav1.Time{}) {
out.LastAppliedTime = *in.LastAppliedTime
}
return nil
}

func Convert_v1beta2_ResourceBinding_To_v1beta1_ResourceBinding(in *addonsv1.ResourceBinding, out *ResourceBinding, s apimachineryconversion.Scope) error {
if err := autoConvert_v1beta2_ResourceBinding_To_v1beta1_ResourceBinding(in, out, s); err != nil {
return err
}
if !reflect.DeepEqual(in.LastAppliedTime, metav1.Time{}) {
out.LastAppliedTime = ptr.To(in.LastAppliedTime)
}
return nil
}

// Implement local conversion func because conversion-gen is not aware of conversion func in other packages (see https://github.com/kubernetes/code-generator/issues/94)

func Convert_v1_Condition_To_v1beta1_Condition(in *metav1.Condition, out *clusterv1beta1.Condition, s apimachineryconversion.Scope) error {
Expand Down
8 changes: 8 additions & 0 deletions api/addons/v1beta1/conversion_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import (
"testing"

"k8s.io/apimachinery/pkg/api/apitesting/fuzzer"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
runtimeserializer "k8s.io/apimachinery/pkg/runtime/serializer"
"sigs.k8s.io/randfill"

Expand Down Expand Up @@ -86,5 +87,12 @@ func spokeClusterResourceSetBindingSpec(in *ClusterResourceSetBindingSpec, c ran
if b != nil && reflect.DeepEqual(*b, ResourceSetBinding{}) {
in.Bindings[i] = nil
}
if in.Bindings[i] != nil {
for j, r := range in.Bindings[i].Resources {
if reflect.DeepEqual(r.LastAppliedTime, &metav1.Time{}) {
in.Bindings[i].Resources[j].LastAppliedTime = nil
}
}
}
}
}
58 changes: 34 additions & 24 deletions api/addons/v1beta1/zz_generated.conversion.go

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

2 changes: 1 addition & 1 deletion api/addons/v1beta2/clusterresourcesetbinding_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ type ResourceBinding struct {

// lastAppliedTime identifies when this resource was last applied to the cluster.
// +optional
LastAppliedTime *metav1.Time `json:"lastAppliedTime,omitempty"`
LastAppliedTime metav1.Time `json:"lastAppliedTime,omitempty,omitzero"`

// applied is to track if a resource is applied to the cluster or not.
// +required
Expand Down
14 changes: 7 additions & 7 deletions api/addons/v1beta2/clusterresourcesetbinding_types_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,13 +45,13 @@ func TestIsResourceApplied(t *testing.T) {
ResourceRef: resourceRefApplySucceeded,
Applied: true,
Hash: "xyz",
LastAppliedTime: &metav1.Time{Time: time.Now().UTC()},
LastAppliedTime: metav1.Time{Time: time.Now().UTC()},
},
{
ResourceRef: resourceRefApplyFailed,
Applied: false,
Hash: "",
LastAppliedTime: &metav1.Time{Time: time.Now().UTC()},
LastAppliedTime: metav1.Time{Time: time.Now().UTC()},
},
},
}
Expand Down Expand Up @@ -108,7 +108,7 @@ func TestResourceSetBindingGetResourceBinding(t *testing.T) {
ResourceRef: resourceRefApplyFailed,
Applied: false,
Hash: "",
LastAppliedTime: &metav1.Time{Time: time.Now().UTC()},
LastAppliedTime: metav1.Time{Time: time.Now().UTC()},
}
crsBinding := &ResourceSetBinding{
ClusterResourceSetName: "test-clusterResourceSet",
Expand All @@ -117,7 +117,7 @@ func TestResourceSetBindingGetResourceBinding(t *testing.T) {
ResourceRef: resourceRefApplySucceeded,
Applied: true,
Hash: "xyz",
LastAppliedTime: &metav1.Time{Time: time.Now().UTC()},
LastAppliedTime: metav1.Time{Time: time.Now().UTC()},
},
resourceRefApplyFailedBinding,
},
Expand Down Expand Up @@ -163,15 +163,15 @@ func TestSetResourceBinding(t *testing.T) {
ResourceRef: resourceRefApplyFailed,
Applied: false,
Hash: "",
LastAppliedTime: &metav1.Time{Time: time.Now().UTC()},
LastAppliedTime: metav1.Time{Time: time.Now().UTC()},
},
},
}
updateFailedResourceBinding := ResourceBinding{
ResourceRef: resourceRefApplyFailed,
Applied: true,
Hash: "xyz",
LastAppliedTime: &metav1.Time{Time: time.Now().UTC()},
LastAppliedTime: metav1.Time{Time: time.Now().UTC()},
}

newResourceBinding := ResourceBinding{
Expand All @@ -181,7 +181,7 @@ func TestSetResourceBinding(t *testing.T) {
},
Applied: false,
Hash: "xyz",
LastAppliedTime: &metav1.Time{Time: time.Now().UTC()},
LastAppliedTime: metav1.Time{Time: time.Now().UTC()},
}

tests := []struct {
Expand Down
5 changes: 1 addition & 4 deletions api/addons/v1beta2/zz_generated.deepcopy.go

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

6 changes: 6 additions & 0 deletions api/bootstrap/kubeadm/v1beta1/conversion.go
Original file line number Diff line number Diff line change
Expand Up @@ -431,6 +431,9 @@ func Convert_v1beta2_BootstrapToken_To_v1beta1_BootstrapToken(in *bootstrapv1.Bo
return err
}
out.TTL = clusterv1.ConvertFromSeconds(in.TTLSeconds)
if !reflect.DeepEqual(in.Expires, metav1.Time{}) {
out.Expires = ptr.To(in.Expires)
}
return nil
}

Expand Down Expand Up @@ -535,6 +538,9 @@ func Convert_v1beta1_BootstrapToken_To_v1beta2_BootstrapToken(in *BootstrapToken
return err
}
out.TTLSeconds = clusterv1.ConvertToSeconds(in.TTL)
if in.Expires != nil && !reflect.DeepEqual(in.Expires, &metav1.Time{}) {
out.Expires = *in.Expires
}
return nil
}

Expand Down
3 changes: 3 additions & 0 deletions api/bootstrap/kubeadm/v1beta1/conversion_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,9 @@ func spokeBootstrapToken(in *BootstrapToken, c randfill.Continue) {
if in.TTL != nil {
in.TTL = ptr.To[metav1.Duration](metav1.Duration{Duration: time.Duration(c.Int31()) * time.Second})
}
if reflect.DeepEqual(in.Expires, &metav1.Time{}) {
in.Expires = nil
}
}

func spokeDiscovery(in *Discovery, c randfill.Continue) {
Expand Down
4 changes: 2 additions & 2 deletions api/bootstrap/kubeadm/v1beta1/zz_generated.conversion.go

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

2 changes: 1 addition & 1 deletion api/bootstrap/kubeadm/v1beta2/kubeadm_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -410,7 +410,7 @@ type BootstrapToken struct {
// expires specifies the timestamp when this token expires. Defaults to being set
// dynamically at runtime based on the ttlSeconds. Expires and ttlSeconds are mutually exclusive.
// +optional
Expires *metav1.Time `json:"expires,omitempty"`
Expires metav1.Time `json:"expires,omitempty,omitzero"`

// usages describes the ways in which this token can be used. Can by default be used
// for establishing bidirectional trust, but that can be changed here.
Expand Down
5 changes: 1 addition & 4 deletions api/bootstrap/kubeadm/v1beta2/zz_generated.deepcopy.go

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

16 changes: 12 additions & 4 deletions api/controlplane/kubeadm/v1beta1/conversion.go
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,9 @@ func Convert_v1beta2_KubeadmControlPlaneSpec_To_v1beta1_KubeadmControlPlaneSpec(
out.RolloutBefore = &RolloutBefore{}
out.RolloutBefore.CertificatesExpiryDays = ptr.To(in.Rollout.Before.CertificatesExpiryDays)
}
out.RolloutAfter = in.Rollout.After
if !reflect.DeepEqual(in.Rollout.After, metav1.Time{}) {
out.RolloutAfter = ptr.To(in.Rollout.After)
}
if !reflect.DeepEqual(in.Rollout.Strategy, controlplanev1.KubeadmControlPlaneRolloutStrategy{}) {
out.RolloutStrategy = &RolloutStrategy{}
out.RolloutStrategy.Type = RolloutStrategyType(in.Rollout.Strategy.Type)
Expand All @@ -199,7 +201,9 @@ func Convert_v1beta1_KubeadmControlPlaneSpec_To_v1beta2_KubeadmControlPlaneSpec(
if in.RolloutBefore != nil && in.RolloutBefore.CertificatesExpiryDays != nil {
out.Rollout.Before.CertificatesExpiryDays = *in.RolloutBefore.CertificatesExpiryDays
}
out.Rollout.After = in.RolloutAfter
if in.RolloutAfter != nil && !reflect.DeepEqual(in.RolloutAfter, &metav1.Time{}) {
out.Rollout.After = *in.RolloutAfter
}
if in.RolloutStrategy != nil {
out.Rollout.Strategy.Type = controlplanev1.KubeadmControlPlaneRolloutStrategyType(in.RolloutStrategy.Type)
if in.RolloutStrategy.RollingUpdate != nil && in.RolloutStrategy.RollingUpdate.MaxSurge != nil {
Expand Down Expand Up @@ -232,7 +236,9 @@ func Convert_v1beta2_KubeadmControlPlaneTemplateResourceSpec_To_v1beta1_KubeadmC
out.RolloutBefore = &RolloutBefore{}
out.RolloutBefore.CertificatesExpiryDays = ptr.To(in.Rollout.Before.CertificatesExpiryDays)
}
out.RolloutAfter = in.Rollout.After
if !reflect.DeepEqual(in.Rollout.After, metav1.Time{}) {
out.RolloutAfter = ptr.To(in.Rollout.After)
}
if !reflect.DeepEqual(in.Rollout.Strategy, controlplanev1.KubeadmControlPlaneRolloutStrategy{}) {
out.RolloutStrategy = &RolloutStrategy{}
out.RolloutStrategy.Type = RolloutStrategyType(in.Rollout.Strategy.Type)
Expand Down Expand Up @@ -264,7 +270,9 @@ func Convert_v1beta1_KubeadmControlPlaneTemplateResourceSpec_To_v1beta2_KubeadmC
if in.RolloutBefore != nil && in.RolloutBefore.CertificatesExpiryDays != nil {
out.Rollout.Before.CertificatesExpiryDays = *in.RolloutBefore.CertificatesExpiryDays
}
out.Rollout.After = in.RolloutAfter
if in.RolloutAfter != nil && !reflect.DeepEqual(in.RolloutAfter, &metav1.Time{}) {
out.Rollout.After = *in.RolloutAfter
}
if in.RolloutStrategy != nil {
out.Rollout.Strategy.Type = controlplanev1.KubeadmControlPlaneRolloutStrategyType(in.RolloutStrategy.Type)
if in.RolloutStrategy.RollingUpdate != nil && in.RolloutStrategy.RollingUpdate.MaxSurge != nil {
Expand Down
Loading