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.
This commit is contained in:
Joe Betz
2025-03-19 22:48:28 -04:00
parent ffb4e003f7
commit d0f6fe30bf
8 changed files with 159 additions and 0 deletions

View File

@@ -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
}

View File

@@ -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
}

View File

@@ -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
}

View File

@@ -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"`
}

View File

@@ -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"`
}

View File

@@ -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"`
}

View File

@@ -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"`
}

View File

@@ -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
}