From d0f6fe30bf1d2e46cc37af13d4443695e8829569 Mon Sep 17 00:00:00 2001 From: Joe Betz Date: Wed, 19 Mar 2025 22:48:28 -0400 Subject: [PATCH] Add k8s:minimum validation to Scale.spec.replicas This applies to all group version kinds of Scale. Validation-gen must be enabled for all at the same time since our testing checks that cross-GV declarative validation to matches. --- .../apps/v1beta1/zz_generated.validations.go | 37 +++++++++++++++++++ .../apps/v1beta2/zz_generated.validations.go | 37 +++++++++++++++++++ .../v1/zz_generated.validations.go | 37 +++++++++++++++++++ staging/src/k8s.io/api/apps/v1beta1/types.go | 3 ++ staging/src/k8s.io/api/apps/v1beta2/types.go | 3 ++ .../src/k8s.io/api/autoscaling/v1/types.go | 3 ++ .../k8s.io/api/extensions/v1beta1/types.go | 3 ++ .../v1beta1/zz_generated.validations.go | 36 ++++++++++++++++++ 8 files changed, 159 insertions(+) diff --git a/pkg/apis/apps/v1beta1/zz_generated.validations.go b/pkg/apis/apps/v1beta1/zz_generated.validations.go index 0b9e874b635..e6ae355719f 100644 --- a/pkg/apis/apps/v1beta1/zz_generated.validations.go +++ b/pkg/apis/apps/v1beta1/zz_generated.validations.go @@ -22,7 +22,14 @@ limitations under the License. package v1beta1 import ( + context "context" + + appsv1beta1 "k8s.io/api/apps/v1beta1" + operation "k8s.io/apimachinery/pkg/api/operation" + safe "k8s.io/apimachinery/pkg/api/safe" + validate "k8s.io/apimachinery/pkg/api/validate" runtime "k8s.io/apimachinery/pkg/runtime" + field "k8s.io/apimachinery/pkg/util/validation/field" ) func init() { localSchemeBuilder.Register(RegisterValidations) } @@ -30,5 +37,35 @@ func init() { localSchemeBuilder.Register(RegisterValidations) } // RegisterValidations adds validation functions to the given scheme. // Public to allow building arbitrary schemes. func RegisterValidations(scheme *runtime.Scheme) error { + scheme.AddValidationFunc((*appsv1beta1.Scale)(nil), func(ctx context.Context, op operation.Operation, obj, oldObj interface{}) field.ErrorList { + return Validate_Scale(ctx, op, nil /* fldPath */, obj.(*appsv1beta1.Scale), safe.Cast[*appsv1beta1.Scale](oldObj)) + }) return nil } + +func Validate_Scale(ctx context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj *appsv1beta1.Scale) (errs field.ErrorList) { + // field appsv1beta1.Scale.TypeMeta has no validation + // field appsv1beta1.Scale.ObjectMeta has no validation + + // field appsv1beta1.Scale.Spec + errs = append(errs, + func(fldPath *field.Path, obj, oldObj *appsv1beta1.ScaleSpec) (errs field.ErrorList) { + errs = append(errs, Validate_ScaleSpec(ctx, op, fldPath, obj, oldObj)...) + return + }(fldPath.Child("spec"), &obj.Spec, safe.Field(oldObj, func(oldObj *appsv1beta1.Scale) *appsv1beta1.ScaleSpec { return &oldObj.Spec }))...) + + // field appsv1beta1.Scale.Status has no validation + return errs +} + +func Validate_ScaleSpec(ctx context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj *appsv1beta1.ScaleSpec) (errs field.ErrorList) { + // field appsv1beta1.ScaleSpec.Replicas + errs = append(errs, + func(fldPath *field.Path, obj, oldObj *int32) (errs field.ErrorList) { + // optional value-type fields with zero-value defaults are purely documentation + errs = append(errs, validate.Minimum(ctx, op, fldPath, obj, oldObj, 0)...) + return + }(fldPath.Child("replicas"), &obj.Replicas, safe.Field(oldObj, func(oldObj *appsv1beta1.ScaleSpec) *int32 { return &oldObj.Replicas }))...) + + return errs +} diff --git a/pkg/apis/apps/v1beta2/zz_generated.validations.go b/pkg/apis/apps/v1beta2/zz_generated.validations.go index 2b709ed6643..ff771ea54e0 100644 --- a/pkg/apis/apps/v1beta2/zz_generated.validations.go +++ b/pkg/apis/apps/v1beta2/zz_generated.validations.go @@ -22,7 +22,14 @@ limitations under the License. package v1beta2 import ( + context "context" + + appsv1beta2 "k8s.io/api/apps/v1beta2" + operation "k8s.io/apimachinery/pkg/api/operation" + safe "k8s.io/apimachinery/pkg/api/safe" + validate "k8s.io/apimachinery/pkg/api/validate" runtime "k8s.io/apimachinery/pkg/runtime" + field "k8s.io/apimachinery/pkg/util/validation/field" ) func init() { localSchemeBuilder.Register(RegisterValidations) } @@ -30,5 +37,35 @@ func init() { localSchemeBuilder.Register(RegisterValidations) } // RegisterValidations adds validation functions to the given scheme. // Public to allow building arbitrary schemes. func RegisterValidations(scheme *runtime.Scheme) error { + scheme.AddValidationFunc((*appsv1beta2.Scale)(nil), func(ctx context.Context, op operation.Operation, obj, oldObj interface{}) field.ErrorList { + return Validate_Scale(ctx, op, nil /* fldPath */, obj.(*appsv1beta2.Scale), safe.Cast[*appsv1beta2.Scale](oldObj)) + }) return nil } + +func Validate_Scale(ctx context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj *appsv1beta2.Scale) (errs field.ErrorList) { + // field appsv1beta2.Scale.TypeMeta has no validation + // field appsv1beta2.Scale.ObjectMeta has no validation + + // field appsv1beta2.Scale.Spec + errs = append(errs, + func(fldPath *field.Path, obj, oldObj *appsv1beta2.ScaleSpec) (errs field.ErrorList) { + errs = append(errs, Validate_ScaleSpec(ctx, op, fldPath, obj, oldObj)...) + return + }(fldPath.Child("spec"), &obj.Spec, safe.Field(oldObj, func(oldObj *appsv1beta2.Scale) *appsv1beta2.ScaleSpec { return &oldObj.Spec }))...) + + // field appsv1beta2.Scale.Status has no validation + return errs +} + +func Validate_ScaleSpec(ctx context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj *appsv1beta2.ScaleSpec) (errs field.ErrorList) { + // field appsv1beta2.ScaleSpec.Replicas + errs = append(errs, + func(fldPath *field.Path, obj, oldObj *int32) (errs field.ErrorList) { + // optional value-type fields with zero-value defaults are purely documentation + errs = append(errs, validate.Minimum(ctx, op, fldPath, obj, oldObj, 0)...) + return + }(fldPath.Child("replicas"), &obj.Replicas, safe.Field(oldObj, func(oldObj *appsv1beta2.ScaleSpec) *int32 { return &oldObj.Replicas }))...) + + return errs +} diff --git a/pkg/apis/autoscaling/v1/zz_generated.validations.go b/pkg/apis/autoscaling/v1/zz_generated.validations.go index 73e28035dba..8299170609f 100644 --- a/pkg/apis/autoscaling/v1/zz_generated.validations.go +++ b/pkg/apis/autoscaling/v1/zz_generated.validations.go @@ -22,7 +22,14 @@ limitations under the License. package v1 import ( + context "context" + + autoscalingv1 "k8s.io/api/autoscaling/v1" + operation "k8s.io/apimachinery/pkg/api/operation" + safe "k8s.io/apimachinery/pkg/api/safe" + validate "k8s.io/apimachinery/pkg/api/validate" runtime "k8s.io/apimachinery/pkg/runtime" + field "k8s.io/apimachinery/pkg/util/validation/field" ) func init() { localSchemeBuilder.Register(RegisterValidations) } @@ -30,5 +37,35 @@ func init() { localSchemeBuilder.Register(RegisterValidations) } // RegisterValidations adds validation functions to the given scheme. // Public to allow building arbitrary schemes. func RegisterValidations(scheme *runtime.Scheme) error { + scheme.AddValidationFunc((*autoscalingv1.Scale)(nil), func(ctx context.Context, op operation.Operation, obj, oldObj interface{}) field.ErrorList { + return Validate_Scale(ctx, op, nil /* fldPath */, obj.(*autoscalingv1.Scale), safe.Cast[*autoscalingv1.Scale](oldObj)) + }) return nil } + +func Validate_Scale(ctx context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj *autoscalingv1.Scale) (errs field.ErrorList) { + // field autoscalingv1.Scale.TypeMeta has no validation + // field autoscalingv1.Scale.ObjectMeta has no validation + + // field autoscalingv1.Scale.Spec + errs = append(errs, + func(fldPath *field.Path, obj, oldObj *autoscalingv1.ScaleSpec) (errs field.ErrorList) { + errs = append(errs, Validate_ScaleSpec(ctx, op, fldPath, obj, oldObj)...) + return + }(fldPath.Child("spec"), &obj.Spec, safe.Field(oldObj, func(oldObj *autoscalingv1.Scale) *autoscalingv1.ScaleSpec { return &oldObj.Spec }))...) + + // field autoscalingv1.Scale.Status has no validation + return errs +} + +func Validate_ScaleSpec(ctx context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj *autoscalingv1.ScaleSpec) (errs field.ErrorList) { + // field autoscalingv1.ScaleSpec.Replicas + errs = append(errs, + func(fldPath *field.Path, obj, oldObj *int32) (errs field.ErrorList) { + // optional value-type fields with zero-value defaults are purely documentation + errs = append(errs, validate.Minimum(ctx, op, fldPath, obj, oldObj, 0)...) + return + }(fldPath.Child("replicas"), &obj.Replicas, safe.Field(oldObj, func(oldObj *autoscalingv1.ScaleSpec) *int32 { return &oldObj.Replicas }))...) + + return errs +} diff --git a/staging/src/k8s.io/api/apps/v1beta1/types.go b/staging/src/k8s.io/api/apps/v1beta1/types.go index 5530c990daa..5a863da2717 100644 --- a/staging/src/k8s.io/api/apps/v1beta1/types.go +++ b/staging/src/k8s.io/api/apps/v1beta1/types.go @@ -33,6 +33,9 @@ const ( type ScaleSpec struct { // replicas is the number of observed instances of the scaled object. // +optional + // +k8s:optional + // +default=0 + // +k8s:minimum=0 Replicas int32 `json:"replicas,omitempty" protobuf:"varint,1,opt,name=replicas"` } diff --git a/staging/src/k8s.io/api/apps/v1beta2/types.go b/staging/src/k8s.io/api/apps/v1beta2/types.go index 1472bfd109b..7f0438c5ed0 100644 --- a/staging/src/k8s.io/api/apps/v1beta2/types.go +++ b/staging/src/k8s.io/api/apps/v1beta2/types.go @@ -35,6 +35,9 @@ const ( type ScaleSpec struct { // desired number of instances for the scaled object. // +optional + // +k8s:optional + // +default=0 + // +k8s:minimum=0 Replicas int32 `json:"replicas,omitempty" protobuf:"varint,1,opt,name=replicas"` } diff --git a/staging/src/k8s.io/api/autoscaling/v1/types.go b/staging/src/k8s.io/api/autoscaling/v1/types.go index 85c609e5c77..b8941145e7f 100644 --- a/staging/src/k8s.io/api/autoscaling/v1/types.go +++ b/staging/src/k8s.io/api/autoscaling/v1/types.go @@ -138,6 +138,9 @@ type Scale struct { type ScaleSpec struct { // replicas is the desired number of instances for the scaled object. // +optional + // +k8s:optional + // +default=0 + // +k8s:minimum=0 Replicas int32 `json:"replicas,omitempty" protobuf:"varint,1,opt,name=replicas"` } diff --git a/staging/src/k8s.io/api/extensions/v1beta1/types.go b/staging/src/k8s.io/api/extensions/v1beta1/types.go index 2118f409a95..6b86b65756f 100644 --- a/staging/src/k8s.io/api/extensions/v1beta1/types.go +++ b/staging/src/k8s.io/api/extensions/v1beta1/types.go @@ -27,6 +27,9 @@ import ( type ScaleSpec struct { // desired number of instances for the scaled object. // +optional + // +k8s:optional + // +default=0 + // +k8s:minimum=0 Replicas int32 `json:"replicas,omitempty" protobuf:"varint,1,opt,name=replicas"` } diff --git a/staging/src/k8s.io/api/extensions/v1beta1/zz_generated.validations.go b/staging/src/k8s.io/api/extensions/v1beta1/zz_generated.validations.go index 0b9e874b635..32314c92a23 100644 --- a/staging/src/k8s.io/api/extensions/v1beta1/zz_generated.validations.go +++ b/staging/src/k8s.io/api/extensions/v1beta1/zz_generated.validations.go @@ -22,7 +22,13 @@ limitations under the License. package v1beta1 import ( + context "context" + + operation "k8s.io/apimachinery/pkg/api/operation" + safe "k8s.io/apimachinery/pkg/api/safe" + validate "k8s.io/apimachinery/pkg/api/validate" runtime "k8s.io/apimachinery/pkg/runtime" + field "k8s.io/apimachinery/pkg/util/validation/field" ) func init() { localSchemeBuilder.Register(RegisterValidations) } @@ -30,5 +36,35 @@ func init() { localSchemeBuilder.Register(RegisterValidations) } // RegisterValidations adds validation functions to the given scheme. // Public to allow building arbitrary schemes. func RegisterValidations(scheme *runtime.Scheme) error { + scheme.AddValidationFunc((*Scale)(nil), func(ctx context.Context, op operation.Operation, obj, oldObj interface{}) field.ErrorList { + return Validate_Scale(ctx, op, nil /* fldPath */, obj.(*Scale), safe.Cast[*Scale](oldObj)) + }) return nil } + +func Validate_Scale(ctx context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj *Scale) (errs field.ErrorList) { + // field Scale.TypeMeta has no validation + // field Scale.ObjectMeta has no validation + + // field Scale.Spec + errs = append(errs, + func(fldPath *field.Path, obj, oldObj *ScaleSpec) (errs field.ErrorList) { + errs = append(errs, Validate_ScaleSpec(ctx, op, fldPath, obj, oldObj)...) + return + }(fldPath.Child("spec"), &obj.Spec, safe.Field(oldObj, func(oldObj *Scale) *ScaleSpec { return &oldObj.Spec }))...) + + // field Scale.Status has no validation + return errs +} + +func Validate_ScaleSpec(ctx context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj *ScaleSpec) (errs field.ErrorList) { + // field ScaleSpec.Replicas + errs = append(errs, + func(fldPath *field.Path, obj, oldObj *int32) (errs field.ErrorList) { + // optional value-type fields with zero-value defaults are purely documentation + errs = append(errs, validate.Minimum(ctx, op, fldPath, obj, oldObj, 0)...) + return + }(fldPath.Child("replicas"), &obj.Replicas, safe.Field(oldObj, func(oldObj *ScaleSpec) *int32 { return &oldObj.Replicas }))...) + + return errs +}