mirror of
https://github.com/k3s-io/kubernetes.git
synced 2026-07-23 10:26:22 +00:00
HPA: Enable DV support for MaxReplicas (#135412)
Signed-off-by: Omer Aplatony <omerap12@gmail.com>
This commit is contained in:
80
pkg/apis/autoscaling/v1/zz_generated.validations.go
generated
80
pkg/apis/autoscaling/v1/zz_generated.validations.go
generated
@@ -26,6 +26,7 @@ import (
|
||||
fmt "fmt"
|
||||
|
||||
autoscalingv1 "k8s.io/api/autoscaling/v1"
|
||||
equality "k8s.io/apimachinery/pkg/api/equality"
|
||||
operation "k8s.io/apimachinery/pkg/api/operation"
|
||||
safe "k8s.io/apimachinery/pkg/api/safe"
|
||||
validate "k8s.io/apimachinery/pkg/api/validate"
|
||||
@@ -38,6 +39,14 @@ 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 {
|
||||
// type HorizontalPodAutoscaler
|
||||
scheme.AddValidationFunc((*autoscalingv1.HorizontalPodAutoscaler)(nil), func(ctx context.Context, op operation.Operation, obj, oldObj interface{}) field.ErrorList {
|
||||
switch op.Request.SubresourcePath() {
|
||||
case "/":
|
||||
return Validate_HorizontalPodAutoscaler(ctx, op, nil /* fldPath */, obj.(*autoscalingv1.HorizontalPodAutoscaler), safe.Cast[*autoscalingv1.HorizontalPodAutoscaler](oldObj))
|
||||
}
|
||||
return field.ErrorList{field.InternalError(nil, fmt.Errorf("no validation found for %T, subresource: %v", obj, op.Request.SubresourcePath()))}
|
||||
})
|
||||
// type Scale
|
||||
scheme.AddValidationFunc((*autoscalingv1.Scale)(nil), func(ctx context.Context, op operation.Operation, obj, oldObj interface{}) field.ErrorList {
|
||||
switch op.Request.SubresourcePath() {
|
||||
@@ -49,6 +58,77 @@ func RegisterValidations(scheme *runtime.Scheme) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Validate_HorizontalPodAutoscaler validates an instance of HorizontalPodAutoscaler according
|
||||
// to declarative validation rules in the API schema.
|
||||
func Validate_HorizontalPodAutoscaler(ctx context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj *autoscalingv1.HorizontalPodAutoscaler) (errs field.ErrorList) {
|
||||
// field autoscalingv1.HorizontalPodAutoscaler.TypeMeta has no validation
|
||||
// field autoscalingv1.HorizontalPodAutoscaler.ObjectMeta has no validation
|
||||
|
||||
// field autoscalingv1.HorizontalPodAutoscaler.Spec
|
||||
errs = append(errs,
|
||||
func(fldPath *field.Path, obj, oldObj *autoscalingv1.HorizontalPodAutoscalerSpec, oldValueCorrelated bool) (errs field.ErrorList) {
|
||||
// don't revalidate unchanged data
|
||||
if oldValueCorrelated && op.Type == operation.Update && equality.Semantic.DeepEqual(obj, oldObj) {
|
||||
return nil
|
||||
}
|
||||
// call the type's validation function
|
||||
errs = append(errs, Validate_HorizontalPodAutoscalerSpec(ctx, op, fldPath, obj, oldObj)...)
|
||||
return
|
||||
}(fldPath.Child("spec"), &obj.Spec, safe.Field(oldObj, func(oldObj *autoscalingv1.HorizontalPodAutoscaler) *autoscalingv1.HorizontalPodAutoscalerSpec {
|
||||
return &oldObj.Spec
|
||||
}), oldObj != nil)...)
|
||||
|
||||
// field autoscalingv1.HorizontalPodAutoscaler.Status has no validation
|
||||
return errs
|
||||
}
|
||||
|
||||
// Validate_HorizontalPodAutoscalerSpec validates an instance of HorizontalPodAutoscalerSpec according
|
||||
// to declarative validation rules in the API schema.
|
||||
func Validate_HorizontalPodAutoscalerSpec(ctx context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj *autoscalingv1.HorizontalPodAutoscalerSpec) (errs field.ErrorList) {
|
||||
// field autoscalingv1.HorizontalPodAutoscalerSpec.ScaleTargetRef has no validation
|
||||
|
||||
// field autoscalingv1.HorizontalPodAutoscalerSpec.MinReplicas
|
||||
errs = append(errs,
|
||||
func(fldPath *field.Path, obj, oldObj *int32, oldValueCorrelated bool) (errs field.ErrorList) {
|
||||
// don't revalidate unchanged data
|
||||
if oldValueCorrelated && op.Type == operation.Update && (obj == oldObj || (obj != nil && oldObj != nil && *obj == *oldObj)) {
|
||||
return nil
|
||||
}
|
||||
// call field-attached validations
|
||||
earlyReturn := false
|
||||
if e := validate.OptionalPointer(ctx, op, fldPath, obj, oldObj); len(e) != 0 {
|
||||
earlyReturn = true
|
||||
}
|
||||
if earlyReturn {
|
||||
return // do not proceed
|
||||
}
|
||||
return
|
||||
}(fldPath.Child("minReplicas"), obj.MinReplicas, safe.Field(oldObj, func(oldObj *autoscalingv1.HorizontalPodAutoscalerSpec) *int32 { return oldObj.MinReplicas }), oldObj != nil)...)
|
||||
|
||||
// field autoscalingv1.HorizontalPodAutoscalerSpec.MaxReplicas
|
||||
errs = append(errs,
|
||||
func(fldPath *field.Path, obj, oldObj *int32, oldValueCorrelated bool) (errs field.ErrorList) {
|
||||
// don't revalidate unchanged data
|
||||
if oldValueCorrelated && op.Type == operation.Update && (obj == oldObj || (obj != nil && oldObj != nil && *obj == *oldObj)) {
|
||||
return nil
|
||||
}
|
||||
// call field-attached validations
|
||||
earlyReturn := false
|
||||
if e := validate.RequiredValue(ctx, op, fldPath, obj, oldObj); len(e) != 0 {
|
||||
errs = append(errs, e...)
|
||||
earlyReturn = true
|
||||
}
|
||||
if earlyReturn {
|
||||
return // do not proceed
|
||||
}
|
||||
errs = append(errs, validate.Minimum(ctx, op, fldPath, obj, oldObj, 1)...)
|
||||
return
|
||||
}(fldPath.Child("maxReplicas"), &obj.MaxReplicas, safe.Field(oldObj, func(oldObj *autoscalingv1.HorizontalPodAutoscalerSpec) *int32 { return &oldObj.MaxReplicas }), oldObj != nil)...)
|
||||
|
||||
// field autoscalingv1.HorizontalPodAutoscalerSpec.TargetCPUUtilizationPercentage has no validation
|
||||
return errs
|
||||
}
|
||||
|
||||
// Validate_Scale validates an instance of Scale according
|
||||
// to declarative validation rules in the API schema.
|
||||
func Validate_Scale(ctx context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj *autoscalingv1.Scale) (errs field.ErrorList) {
|
||||
|
||||
@@ -18,5 +18,7 @@ limitations under the License.
|
||||
// +k8s:conversion-gen-external-types=k8s.io/api/autoscaling/v2
|
||||
// +k8s:defaulter-gen=TypeMeta
|
||||
// +k8s:defaulter-gen-input=k8s.io/api/autoscaling/v2
|
||||
// +k8s:validation-gen=TypeMeta
|
||||
// +k8s:validation-gen-input=k8s.io/api/autoscaling/v2
|
||||
|
||||
package v2
|
||||
|
||||
123
pkg/apis/autoscaling/v2/zz_generated.validations.go
generated
Normal file
123
pkg/apis/autoscaling/v2/zz_generated.validations.go
generated
Normal file
@@ -0,0 +1,123 @@
|
||||
//go:build !ignore_autogenerated
|
||||
// +build !ignore_autogenerated
|
||||
|
||||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by validation-gen. DO NOT EDIT.
|
||||
|
||||
package v2
|
||||
|
||||
import (
|
||||
context "context"
|
||||
fmt "fmt"
|
||||
|
||||
autoscalingv2 "k8s.io/api/autoscaling/v2"
|
||||
equality "k8s.io/apimachinery/pkg/api/equality"
|
||||
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) }
|
||||
|
||||
// RegisterValidations adds validation functions to the given scheme.
|
||||
// Public to allow building arbitrary schemes.
|
||||
func RegisterValidations(scheme *runtime.Scheme) error {
|
||||
// type HorizontalPodAutoscaler
|
||||
scheme.AddValidationFunc((*autoscalingv2.HorizontalPodAutoscaler)(nil), func(ctx context.Context, op operation.Operation, obj, oldObj interface{}) field.ErrorList {
|
||||
switch op.Request.SubresourcePath() {
|
||||
case "/":
|
||||
return Validate_HorizontalPodAutoscaler(ctx, op, nil /* fldPath */, obj.(*autoscalingv2.HorizontalPodAutoscaler), safe.Cast[*autoscalingv2.HorizontalPodAutoscaler](oldObj))
|
||||
}
|
||||
return field.ErrorList{field.InternalError(nil, fmt.Errorf("no validation found for %T, subresource: %v", obj, op.Request.SubresourcePath()))}
|
||||
})
|
||||
return nil
|
||||
}
|
||||
|
||||
// Validate_HorizontalPodAutoscaler validates an instance of HorizontalPodAutoscaler according
|
||||
// to declarative validation rules in the API schema.
|
||||
func Validate_HorizontalPodAutoscaler(ctx context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj *autoscalingv2.HorizontalPodAutoscaler) (errs field.ErrorList) {
|
||||
// field autoscalingv2.HorizontalPodAutoscaler.TypeMeta has no validation
|
||||
// field autoscalingv2.HorizontalPodAutoscaler.ObjectMeta has no validation
|
||||
|
||||
// field autoscalingv2.HorizontalPodAutoscaler.Spec
|
||||
errs = append(errs,
|
||||
func(fldPath *field.Path, obj, oldObj *autoscalingv2.HorizontalPodAutoscalerSpec, oldValueCorrelated bool) (errs field.ErrorList) {
|
||||
// don't revalidate unchanged data
|
||||
if oldValueCorrelated && op.Type == operation.Update && equality.Semantic.DeepEqual(obj, oldObj) {
|
||||
return nil
|
||||
}
|
||||
// call the type's validation function
|
||||
errs = append(errs, Validate_HorizontalPodAutoscalerSpec(ctx, op, fldPath, obj, oldObj)...)
|
||||
return
|
||||
}(fldPath.Child("spec"), &obj.Spec, safe.Field(oldObj, func(oldObj *autoscalingv2.HorizontalPodAutoscaler) *autoscalingv2.HorizontalPodAutoscalerSpec {
|
||||
return &oldObj.Spec
|
||||
}), oldObj != nil)...)
|
||||
|
||||
// field autoscalingv2.HorizontalPodAutoscaler.Status has no validation
|
||||
return errs
|
||||
}
|
||||
|
||||
// Validate_HorizontalPodAutoscalerSpec validates an instance of HorizontalPodAutoscalerSpec according
|
||||
// to declarative validation rules in the API schema.
|
||||
func Validate_HorizontalPodAutoscalerSpec(ctx context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj *autoscalingv2.HorizontalPodAutoscalerSpec) (errs field.ErrorList) {
|
||||
// field autoscalingv2.HorizontalPodAutoscalerSpec.ScaleTargetRef has no validation
|
||||
|
||||
// field autoscalingv2.HorizontalPodAutoscalerSpec.MinReplicas
|
||||
errs = append(errs,
|
||||
func(fldPath *field.Path, obj, oldObj *int32, oldValueCorrelated bool) (errs field.ErrorList) {
|
||||
// don't revalidate unchanged data
|
||||
if oldValueCorrelated && op.Type == operation.Update && (obj == oldObj || (obj != nil && oldObj != nil && *obj == *oldObj)) {
|
||||
return nil
|
||||
}
|
||||
// call field-attached validations
|
||||
earlyReturn := false
|
||||
if e := validate.OptionalPointer(ctx, op, fldPath, obj, oldObj); len(e) != 0 {
|
||||
earlyReturn = true
|
||||
}
|
||||
if earlyReturn {
|
||||
return // do not proceed
|
||||
}
|
||||
return
|
||||
}(fldPath.Child("minReplicas"), obj.MinReplicas, safe.Field(oldObj, func(oldObj *autoscalingv2.HorizontalPodAutoscalerSpec) *int32 { return oldObj.MinReplicas }), oldObj != nil)...)
|
||||
|
||||
// field autoscalingv2.HorizontalPodAutoscalerSpec.MaxReplicas
|
||||
errs = append(errs,
|
||||
func(fldPath *field.Path, obj, oldObj *int32, oldValueCorrelated bool) (errs field.ErrorList) {
|
||||
// don't revalidate unchanged data
|
||||
if oldValueCorrelated && op.Type == operation.Update && (obj == oldObj || (obj != nil && oldObj != nil && *obj == *oldObj)) {
|
||||
return nil
|
||||
}
|
||||
// call field-attached validations
|
||||
earlyReturn := false
|
||||
if e := validate.RequiredValue(ctx, op, fldPath, obj, oldObj); len(e) != 0 {
|
||||
errs = append(errs, e...)
|
||||
earlyReturn = true
|
||||
}
|
||||
if earlyReturn {
|
||||
return // do not proceed
|
||||
}
|
||||
errs = append(errs, validate.Minimum(ctx, op, fldPath, obj, oldObj, 1)...)
|
||||
return
|
||||
}(fldPath.Child("maxReplicas"), &obj.MaxReplicas, safe.Field(oldObj, func(oldObj *autoscalingv2.HorizontalPodAutoscalerSpec) *int32 { return &oldObj.MaxReplicas }), oldObj != nil)...)
|
||||
|
||||
// field autoscalingv2.HorizontalPodAutoscalerSpec.Metrics has no validation
|
||||
// field autoscalingv2.HorizontalPodAutoscalerSpec.Behavior has no validation
|
||||
return errs
|
||||
}
|
||||
@@ -59,8 +59,10 @@ func validateHorizontalPodAutoscalerSpec(autoscaler autoscaling.HorizontalPodAut
|
||||
allErrs = append(allErrs, field.Invalid(fldPath.Child("minReplicas"), *autoscaler.MinReplicas,
|
||||
fmt.Sprintf("must be greater than or equal to %d", opts.MinReplicasLowerBound)))
|
||||
}
|
||||
if autoscaler.MaxReplicas < 1 {
|
||||
allErrs = append(allErrs, field.Invalid(fldPath.Child("maxReplicas"), autoscaler.MaxReplicas, "must be greater than 0"))
|
||||
if autoscaler.MaxReplicas == 0 {
|
||||
allErrs = append(allErrs, field.Required(fldPath.Child("maxReplicas"), "must be set and greater than 0").MarkCoveredByDeclarative())
|
||||
} else if autoscaler.MaxReplicas < 0 {
|
||||
allErrs = append(allErrs, field.Invalid(fldPath.Child("maxReplicas"), autoscaler.MaxReplicas, "must be greater than or equal to 1").WithOrigin("minimum").MarkCoveredByDeclarative())
|
||||
}
|
||||
if autoscaler.MinReplicas != nil && autoscaler.MaxReplicas < *autoscaler.MinReplicas {
|
||||
allErrs = append(allErrs, field.Invalid(fldPath.Child("maxReplicas"), autoscaler.MaxReplicas, "must be greater than or equal to `minReplicas`"))
|
||||
|
||||
@@ -0,0 +1,157 @@
|
||||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package horizontalpodautoscaler
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/util/validation/field"
|
||||
genericapirequest "k8s.io/apiserver/pkg/endpoints/request"
|
||||
apitesting "k8s.io/kubernetes/pkg/api/testing"
|
||||
api "k8s.io/kubernetes/pkg/apis/autoscaling"
|
||||
)
|
||||
|
||||
var apiVersions = []string{"v1", "v2"}
|
||||
|
||||
func TestDeclarativeValidate(t *testing.T) {
|
||||
for _, apiVersion := range apiVersions {
|
||||
testDeclarativeValidate(t, apiVersion)
|
||||
}
|
||||
}
|
||||
|
||||
func testDeclarativeValidate(t *testing.T, apiVersion string) {
|
||||
ctx := genericapirequest.WithRequestInfo(genericapirequest.NewDefaultContext(), &genericapirequest.RequestInfo{
|
||||
APIGroup: "autoscaling",
|
||||
APIVersion: apiVersion,
|
||||
Resource: "horizontalpodautoscalers",
|
||||
})
|
||||
testCases := map[string]struct {
|
||||
input api.HorizontalPodAutoscaler
|
||||
expectedErrs field.ErrorList
|
||||
}{
|
||||
"valid: minReplicas = 5": {
|
||||
input: makeValidHPA(tweakMinReplicas(5)),
|
||||
},
|
||||
"valid: minReplicas not set (nil)": {
|
||||
input: makeValidHPA(), // Default, no minReplicas set
|
||||
},
|
||||
"invalid: maxReplicas = 0 (required)": {
|
||||
input: makeValidHPA(tweakMaxReplicas(0)),
|
||||
expectedErrs: field.ErrorList{
|
||||
field.Required(field.NewPath("spec", "maxReplicas"), ""),
|
||||
},
|
||||
},
|
||||
"invalid: maxReplicas negative": {
|
||||
input: makeValidHPA(tweakMaxReplicas(-1)),
|
||||
expectedErrs: field.ErrorList{
|
||||
field.Invalid(field.NewPath("spec", "maxReplicas"), int32(-1), "must be greater than or equal to 1").WithOrigin("minimum"),
|
||||
},
|
||||
},
|
||||
}
|
||||
for name, tc := range testCases {
|
||||
t.Run(name, func(t *testing.T) {
|
||||
apitesting.VerifyValidationEquivalence(t, ctx, &tc.input, Strategy.Validate, tc.expectedErrs)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestDeclarativeValidateUpdate(t *testing.T) {
|
||||
for _, apiVersion := range apiVersions {
|
||||
t.Run(apiVersion, func(t *testing.T) {
|
||||
testDeclarativeValidateUpdate(t, apiVersion)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func testDeclarativeValidateUpdate(t *testing.T, apiVersion string) {
|
||||
testCases := map[string]struct {
|
||||
oldObj api.HorizontalPodAutoscaler
|
||||
updateObj api.HorizontalPodAutoscaler
|
||||
expectedErrs field.ErrorList
|
||||
}{
|
||||
"valid update": {
|
||||
oldObj: makeValidHPA(),
|
||||
updateObj: makeValidHPA(tweakMaxReplicas(20)),
|
||||
},
|
||||
"valid update: change minReplicas": {
|
||||
oldObj: makeValidHPA(tweakMinReplicas(1)),
|
||||
updateObj: makeValidHPA(tweakMinReplicas(5)),
|
||||
},
|
||||
"invalid update: maxReplicas = 0 (required)": {
|
||||
oldObj: makeValidHPA(),
|
||||
updateObj: makeValidHPA(tweakMaxReplicas(0)),
|
||||
expectedErrs: field.ErrorList{
|
||||
field.Required(field.NewPath("spec", "maxReplicas"), ""),
|
||||
},
|
||||
},
|
||||
"invalid update: maxReplicas negative": {
|
||||
oldObj: makeValidHPA(),
|
||||
updateObj: makeValidHPA(tweakMaxReplicas(-1)),
|
||||
expectedErrs: field.ErrorList{
|
||||
field.Invalid(field.NewPath("spec", "maxReplicas"), int32(-1), "must be greater than or equal to 1").WithOrigin("minimum"),
|
||||
},
|
||||
},
|
||||
}
|
||||
for name, tc := range testCases {
|
||||
t.Run(name, func(t *testing.T) {
|
||||
ctx := genericapirequest.WithRequestInfo(genericapirequest.NewDefaultContext(), &genericapirequest.RequestInfo{
|
||||
APIGroup: "autoscaling",
|
||||
APIVersion: apiVersion,
|
||||
Resource: "horizontalpodautoscalers",
|
||||
Name: "test-hpa",
|
||||
IsResourceRequest: true,
|
||||
Verb: "update",
|
||||
})
|
||||
apitesting.VerifyUpdateValidationEquivalence(t, ctx, &tc.updateObj, &tc.oldObj, Strategy.ValidateUpdate, tc.expectedErrs)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func makeValidHPA(mutators ...func(*api.HorizontalPodAutoscaler)) api.HorizontalPodAutoscaler {
|
||||
hpa := api.HorizontalPodAutoscaler{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "test-hpa",
|
||||
Namespace: "default",
|
||||
ResourceVersion: "1",
|
||||
},
|
||||
Spec: api.HorizontalPodAutoscalerSpec{
|
||||
ScaleTargetRef: api.CrossVersionObjectReference{
|
||||
Kind: "Deployment",
|
||||
Name: "test-deployment",
|
||||
APIVersion: "apps/v1",
|
||||
},
|
||||
MaxReplicas: 10,
|
||||
},
|
||||
}
|
||||
for _, mutate := range mutators {
|
||||
mutate(&hpa)
|
||||
}
|
||||
return hpa
|
||||
}
|
||||
|
||||
func tweakMinReplicas(replicas int32) func(*api.HorizontalPodAutoscaler) {
|
||||
return func(hpa *api.HorizontalPodAutoscaler) {
|
||||
hpa.Spec.MinReplicas = &replicas
|
||||
}
|
||||
}
|
||||
|
||||
func tweakMaxReplicas(replicas int32) func(*api.HorizontalPodAutoscaler) {
|
||||
return func(hpa *api.HorizontalPodAutoscaler) {
|
||||
hpa.Spec.MaxReplicas = replicas
|
||||
}
|
||||
}
|
||||
@@ -19,8 +19,10 @@ package horizontalpodautoscaler
|
||||
import (
|
||||
"context"
|
||||
|
||||
"k8s.io/apimachinery/pkg/api/operation"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/util/validation/field"
|
||||
"k8s.io/apiserver/pkg/registry/rest"
|
||||
"k8s.io/apiserver/pkg/storage/names"
|
||||
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
||||
"k8s.io/kubernetes/pkg/api/legacyscheme"
|
||||
@@ -74,7 +76,8 @@ func (autoscalerStrategy) PrepareForCreate(ctx context.Context, obj runtime.Obje
|
||||
func (autoscalerStrategy) Validate(ctx context.Context, obj runtime.Object) field.ErrorList {
|
||||
autoscaler := obj.(*autoscaling.HorizontalPodAutoscaler)
|
||||
opts := validationOptionsForHorizontalPodAutoscaler(autoscaler, nil)
|
||||
return validation.ValidateHorizontalPodAutoscaler(autoscaler, opts)
|
||||
allErrs := validation.ValidateHorizontalPodAutoscaler(autoscaler, opts)
|
||||
return rest.ValidateDeclarativelyWithMigrationChecks(ctx, legacyscheme.Scheme, autoscaler, nil, allErrs, operation.Create)
|
||||
}
|
||||
|
||||
// WarningsOnCreate returns warnings for the creation of the given object.
|
||||
@@ -106,7 +109,8 @@ func (autoscalerStrategy) ValidateUpdate(ctx context.Context, obj, old runtime.O
|
||||
newHPA := obj.(*autoscaling.HorizontalPodAutoscaler)
|
||||
oldHPA := old.(*autoscaling.HorizontalPodAutoscaler)
|
||||
opts := validationOptionsForHorizontalPodAutoscaler(newHPA, oldHPA)
|
||||
return validation.ValidateHorizontalPodAutoscalerUpdate(newHPA, oldHPA, opts)
|
||||
errs := validation.ValidateHorizontalPodAutoscalerUpdate(newHPA, oldHPA, opts)
|
||||
return rest.ValidateDeclarativelyWithMigrationChecks(ctx, legacyscheme.Scheme, newHPA, oldHPA, errs, operation.Update)
|
||||
}
|
||||
|
||||
// WarningsOnUpdate returns warnings for the given update.
|
||||
|
||||
@@ -202,9 +202,13 @@ message HorizontalPodAutoscalerSpec {
|
||||
// metric is configured. Scaling is active as long as at least one metric value is
|
||||
// available.
|
||||
// +optional
|
||||
// +k8s:optional
|
||||
optional int32 minReplicas = 2;
|
||||
|
||||
// maxReplicas is the upper limit for the number of pods that can be set by the autoscaler; cannot be smaller than MinReplicas.
|
||||
// +required
|
||||
// +k8s:required
|
||||
// +k8s:minimum=1
|
||||
optional int32 maxReplicas = 3;
|
||||
|
||||
// targetCPUUtilizationPercentage is the target average CPU utilization (represented as a percentage of requested CPU) over all the pods;
|
||||
|
||||
@@ -47,9 +47,13 @@ type HorizontalPodAutoscalerSpec struct {
|
||||
// metric is configured. Scaling is active as long as at least one metric value is
|
||||
// available.
|
||||
// +optional
|
||||
// +k8s:optional
|
||||
MinReplicas *int32 `json:"minReplicas,omitempty" protobuf:"varint,2,opt,name=minReplicas"`
|
||||
|
||||
// maxReplicas is the upper limit for the number of pods that can be set by the autoscaler; cannot be smaller than MinReplicas.
|
||||
// +required
|
||||
// +k8s:required
|
||||
// +k8s:minimum=1
|
||||
MaxReplicas int32 `json:"maxReplicas" protobuf:"varint,3,opt,name=maxReplicas"`
|
||||
|
||||
// targetCPUUtilizationPercentage is the target average CPU utilization (represented as a percentage of requested CPU) over all the pods;
|
||||
|
||||
@@ -248,10 +248,14 @@ message HorizontalPodAutoscalerSpec {
|
||||
// metric is configured. Scaling is active as long as at least one metric value is
|
||||
// available.
|
||||
// +optional
|
||||
// +k8s:optional
|
||||
optional int32 minReplicas = 2;
|
||||
|
||||
// maxReplicas is the upper limit for the number of replicas to which the autoscaler can scale up.
|
||||
// It cannot be less that minReplicas.
|
||||
// +required
|
||||
// +k8s:required
|
||||
// +k8s:minimum=1
|
||||
optional int32 maxReplicas = 3;
|
||||
|
||||
// metrics contains the specifications for which to use to calculate the
|
||||
|
||||
@@ -59,10 +59,14 @@ type HorizontalPodAutoscalerSpec struct {
|
||||
// metric is configured. Scaling is active as long as at least one metric value is
|
||||
// available.
|
||||
// +optional
|
||||
// +k8s:optional
|
||||
MinReplicas *int32 `json:"minReplicas,omitempty" protobuf:"varint,2,opt,name=minReplicas"`
|
||||
|
||||
// maxReplicas is the upper limit for the number of replicas to which the autoscaler can scale up.
|
||||
// It cannot be less that minReplicas.
|
||||
// +required
|
||||
// +k8s:required
|
||||
// +k8s:minimum=1
|
||||
MaxReplicas int32 `json:"maxReplicas" protobuf:"varint,3,opt,name=maxReplicas"`
|
||||
|
||||
// metrics contains the specifications for which to use to calculate the
|
||||
|
||||
Reference in New Issue
Block a user