mirror of
https://github.com/kubernetes/kubernetes.git
synced 2026-06-13 10:50:56 -04:00
Merge pull request #139562 from yongruilin/dv-podspec-toleration
Add declarative validation for Toleration key format
This commit is contained in:
commit
66ad1618f1
65 changed files with 2855 additions and 434 deletions
|
|
@ -29,6 +29,7 @@ import (
|
|||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
runtimetest "k8s.io/apimachinery/pkg/runtime/testing"
|
||||
"k8s.io/apimachinery/pkg/test/coverage"
|
||||
"k8s.io/apimachinery/pkg/util/sets"
|
||||
"k8s.io/apimachinery/pkg/util/validation/field"
|
||||
genericapirequest "k8s.io/apiserver/pkg/endpoints/request"
|
||||
"k8s.io/apiserver/pkg/features"
|
||||
|
|
@ -55,6 +56,12 @@ func VerifyVersionedValidationEquivalence(t *testing.T, obj, old runtime.Object,
|
|||
// Accumulate errors from all versioned validation, per version.
|
||||
all := map[string]field.ErrorList{}
|
||||
accumulate := func(t *testing.T, gv string, errs field.ErrorList) {
|
||||
// Skip versions explicitly excluded from the equivalence sweep (e.g. a
|
||||
// deprecated, unserved group whose types are intentionally not validated
|
||||
// declaratively).
|
||||
if opts.SkipGroupVersions.Has(gv) {
|
||||
return
|
||||
}
|
||||
// If normalization rules are provided, apply them to the field paths of generated errors.
|
||||
// This allows comparing errors between API versions that have structural differences
|
||||
// (e.g. flattened vs nested fields).
|
||||
|
|
@ -222,6 +229,13 @@ type validationOption struct {
|
|||
|
||||
// Fuzzer is the fuzzer to use for generating test objects.
|
||||
Fuzzer *randfill.Filler
|
||||
|
||||
// SkipGroupVersions lists "group/version" strings to exclude from the
|
||||
// versioned validation equivalence sweep. This is for kinds whose internal
|
||||
// type is registered under a deprecated, unserved group (e.g. a workload
|
||||
// type that also exists in extensions/v1beta1) for which declarative
|
||||
// validation is intentionally not generated.
|
||||
SkipGroupVersions sets.Set[string]
|
||||
}
|
||||
|
||||
func WithSubResources(subResources ...string) ValidationTestConfig {
|
||||
|
|
@ -248,6 +262,16 @@ func WithFuzzer(fuzzer *randfill.Filler) ValidationTestConfig {
|
|||
}
|
||||
}
|
||||
|
||||
// WithSkipGroupVersions excludes the given "group/version" strings from the
|
||||
// versioned validation equivalence sweep. Use it for kinds whose internal type
|
||||
// is also registered under a deprecated, unserved group (e.g. extensions/v1beta1)
|
||||
// for which declarative validation is intentionally not generated.
|
||||
func WithSkipGroupVersions(groupVersions ...string) ValidationTestConfig {
|
||||
return func(o *validationOption) {
|
||||
o.SkipGroupVersions = sets.New(groupVersions...)
|
||||
}
|
||||
}
|
||||
|
||||
// VerifyValidationEquivalence provides a helper for testing the migration from
|
||||
// hand-written imperative validation to declarative validation. It ensures that
|
||||
// the validation logic remains consistent across enforcement modes.
|
||||
|
|
|
|||
374
pkg/apis/apps/v1/zz_generated.validations.go
generated
374
pkg/apis/apps/v1/zz_generated.validations.go
generated
|
|
@ -20,3 +20,377 @@ limitations under the License.
|
|||
// Code generated by validation-gen. DO NOT EDIT.
|
||||
|
||||
package v1
|
||||
|
||||
import (
|
||||
context "context"
|
||||
fmt "fmt"
|
||||
|
||||
appsv1 "k8s.io/api/apps/v1"
|
||||
apicorev1 "k8s.io/api/core/v1"
|
||||
equality "k8s.io/apimachinery/pkg/api/equality"
|
||||
operation "k8s.io/apimachinery/pkg/api/operation"
|
||||
safe "k8s.io/apimachinery/pkg/api/safe"
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
field "k8s.io/apimachinery/pkg/util/validation/field"
|
||||
corev1 "k8s.io/kubernetes/pkg/apis/core/v1"
|
||||
)
|
||||
|
||||
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 DaemonSet
|
||||
scheme.AddValidationFunc(
|
||||
(*appsv1.DaemonSet)(nil),
|
||||
func(ctx context.Context, op operation.Operation, obj, oldObj interface{}) field.ErrorList {
|
||||
switch op.Request.SubresourcePath() {
|
||||
case "/", "/status":
|
||||
return Validate_DaemonSet(
|
||||
ctx, op, nil, /* fldPath */
|
||||
obj.(*appsv1.DaemonSet),
|
||||
safe.Cast[*appsv1.DaemonSet](oldObj))
|
||||
}
|
||||
return field.ErrorList{
|
||||
field.InternalError(nil, fmt.Errorf("no validation found for %T, subresource: %v", obj, op.Request.SubresourcePath())),
|
||||
}
|
||||
})
|
||||
// type Deployment
|
||||
scheme.AddValidationFunc(
|
||||
(*appsv1.Deployment)(nil),
|
||||
func(ctx context.Context, op operation.Operation, obj, oldObj interface{}) field.ErrorList {
|
||||
switch op.Request.SubresourcePath() {
|
||||
case "/", "/scale", "/status":
|
||||
return Validate_Deployment(
|
||||
ctx, op, nil, /* fldPath */
|
||||
obj.(*appsv1.Deployment),
|
||||
safe.Cast[*appsv1.Deployment](oldObj))
|
||||
}
|
||||
return field.ErrorList{
|
||||
field.InternalError(nil, fmt.Errorf("no validation found for %T, subresource: %v", obj, op.Request.SubresourcePath())),
|
||||
}
|
||||
})
|
||||
// type ReplicaSet
|
||||
scheme.AddValidationFunc(
|
||||
(*appsv1.ReplicaSet)(nil),
|
||||
func(ctx context.Context, op operation.Operation, obj, oldObj interface{}) field.ErrorList {
|
||||
switch op.Request.SubresourcePath() {
|
||||
case "/", "/scale", "/status":
|
||||
return Validate_ReplicaSet(
|
||||
ctx, op, nil, /* fldPath */
|
||||
obj.(*appsv1.ReplicaSet),
|
||||
safe.Cast[*appsv1.ReplicaSet](oldObj))
|
||||
}
|
||||
return field.ErrorList{
|
||||
field.InternalError(nil, fmt.Errorf("no validation found for %T, subresource: %v", obj, op.Request.SubresourcePath())),
|
||||
}
|
||||
})
|
||||
// type StatefulSet
|
||||
scheme.AddValidationFunc(
|
||||
(*appsv1.StatefulSet)(nil),
|
||||
func(ctx context.Context, op operation.Operation, obj, oldObj interface{}) field.ErrorList {
|
||||
switch op.Request.SubresourcePath() {
|
||||
case "/", "/scale", "/status":
|
||||
return Validate_StatefulSet(
|
||||
ctx, op, nil, /* fldPath */
|
||||
obj.(*appsv1.StatefulSet),
|
||||
safe.Cast[*appsv1.StatefulSet](oldObj))
|
||||
}
|
||||
return field.ErrorList{
|
||||
field.InternalError(nil, fmt.Errorf("no validation found for %T, subresource: %v", obj, op.Request.SubresourcePath())),
|
||||
}
|
||||
})
|
||||
return nil
|
||||
}
|
||||
|
||||
// Validate_DaemonSet validates an instance of DaemonSet according
|
||||
// to declarative validation rules in the API schema.
|
||||
func Validate_DaemonSet(
|
||||
ctx context.Context, op operation.Operation, fldPath *field.Path,
|
||||
obj, oldObj *appsv1.DaemonSet) (errs field.ErrorList) {
|
||||
|
||||
// field appsv1.DaemonSet.TypeMeta has no validation
|
||||
// field appsv1.DaemonSet.ObjectMeta has no validation
|
||||
|
||||
{ // field appsv1.DaemonSet.Spec
|
||||
fn := func(
|
||||
fldPath *field.Path,
|
||||
obj, oldObj *appsv1.DaemonSetSpec,
|
||||
oldValueCorrelated bool) (errs field.ErrorList) {
|
||||
// don't revalidate unchanged data
|
||||
if oldValueCorrelated && op.Type == operation.Update {
|
||||
if equality.Semantic.DeepEqual(obj, oldObj) {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
// call the type's validation function
|
||||
errs = append(errs, Validate_DaemonSetSpec(ctx, op, fldPath, obj, oldObj)...)
|
||||
return
|
||||
}
|
||||
oldVal := safe.Field(oldObj,
|
||||
func(oldObj *appsv1.DaemonSet) *appsv1.DaemonSetSpec {
|
||||
return &oldObj.Spec
|
||||
})
|
||||
errs = append(errs, fn(fldPath.Child("spec"), &obj.Spec, oldVal, oldObj != nil)...)
|
||||
}
|
||||
|
||||
// field appsv1.DaemonSet.Status has no validation
|
||||
return errs
|
||||
}
|
||||
|
||||
// Validate_DaemonSetSpec validates an instance of DaemonSetSpec according
|
||||
// to declarative validation rules in the API schema.
|
||||
func Validate_DaemonSetSpec(
|
||||
ctx context.Context, op operation.Operation, fldPath *field.Path,
|
||||
obj, oldObj *appsv1.DaemonSetSpec) (errs field.ErrorList) {
|
||||
|
||||
// field appsv1.DaemonSetSpec.Selector has no validation
|
||||
|
||||
{ // field appsv1.DaemonSetSpec.Template
|
||||
fn := func(
|
||||
fldPath *field.Path,
|
||||
obj, oldObj *apicorev1.PodTemplateSpec,
|
||||
oldValueCorrelated bool) (errs field.ErrorList) {
|
||||
// don't revalidate unchanged data
|
||||
if oldValueCorrelated && op.Type == operation.Update {
|
||||
if equality.Semantic.DeepEqual(obj, oldObj) {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
// call the type's validation function
|
||||
errs = append(errs, corev1.Validate_PodTemplateSpec(ctx, op, fldPath, obj, oldObj)...)
|
||||
return
|
||||
}
|
||||
oldVal := safe.Field(oldObj,
|
||||
func(oldObj *appsv1.DaemonSetSpec) *apicorev1.PodTemplateSpec {
|
||||
return &oldObj.Template
|
||||
})
|
||||
errs = append(errs, fn(fldPath.Child("template"), &obj.Template, oldVal, oldObj != nil)...)
|
||||
}
|
||||
|
||||
// field appsv1.DaemonSetSpec.UpdateStrategy has no validation
|
||||
// field appsv1.DaemonSetSpec.MinReadySeconds has no validation
|
||||
// field appsv1.DaemonSetSpec.RevisionHistoryLimit has no validation
|
||||
return errs
|
||||
}
|
||||
|
||||
// Validate_Deployment validates an instance of Deployment according
|
||||
// to declarative validation rules in the API schema.
|
||||
func Validate_Deployment(
|
||||
ctx context.Context, op operation.Operation, fldPath *field.Path,
|
||||
obj, oldObj *appsv1.Deployment) (errs field.ErrorList) {
|
||||
|
||||
// field appsv1.Deployment.TypeMeta has no validation
|
||||
// field appsv1.Deployment.ObjectMeta has no validation
|
||||
|
||||
{ // field appsv1.Deployment.Spec
|
||||
fn := func(
|
||||
fldPath *field.Path,
|
||||
obj, oldObj *appsv1.DeploymentSpec,
|
||||
oldValueCorrelated bool) (errs field.ErrorList) {
|
||||
// don't revalidate unchanged data
|
||||
if oldValueCorrelated && op.Type == operation.Update {
|
||||
if equality.Semantic.DeepEqual(obj, oldObj) {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
// call the type's validation function
|
||||
errs = append(errs, Validate_DeploymentSpec(ctx, op, fldPath, obj, oldObj)...)
|
||||
return
|
||||
}
|
||||
oldVal := safe.Field(oldObj,
|
||||
func(oldObj *appsv1.Deployment) *appsv1.DeploymentSpec {
|
||||
return &oldObj.Spec
|
||||
})
|
||||
errs = append(errs, fn(fldPath.Child("spec"), &obj.Spec, oldVal, oldObj != nil)...)
|
||||
}
|
||||
|
||||
// field appsv1.Deployment.Status has no validation
|
||||
return errs
|
||||
}
|
||||
|
||||
// Validate_DeploymentSpec validates an instance of DeploymentSpec according
|
||||
// to declarative validation rules in the API schema.
|
||||
func Validate_DeploymentSpec(
|
||||
ctx context.Context, op operation.Operation, fldPath *field.Path,
|
||||
obj, oldObj *appsv1.DeploymentSpec) (errs field.ErrorList) {
|
||||
|
||||
// field appsv1.DeploymentSpec.Replicas has no validation
|
||||
// field appsv1.DeploymentSpec.Selector has no validation
|
||||
|
||||
{ // field appsv1.DeploymentSpec.Template
|
||||
fn := func(
|
||||
fldPath *field.Path,
|
||||
obj, oldObj *apicorev1.PodTemplateSpec,
|
||||
oldValueCorrelated bool) (errs field.ErrorList) {
|
||||
// don't revalidate unchanged data
|
||||
if oldValueCorrelated && op.Type == operation.Update {
|
||||
if equality.Semantic.DeepEqual(obj, oldObj) {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
// call the type's validation function
|
||||
errs = append(errs, corev1.Validate_PodTemplateSpec(ctx, op, fldPath, obj, oldObj)...)
|
||||
return
|
||||
}
|
||||
oldVal := safe.Field(oldObj,
|
||||
func(oldObj *appsv1.DeploymentSpec) *apicorev1.PodTemplateSpec {
|
||||
return &oldObj.Template
|
||||
})
|
||||
errs = append(errs, fn(fldPath.Child("template"), &obj.Template, oldVal, oldObj != nil)...)
|
||||
}
|
||||
|
||||
// field appsv1.DeploymentSpec.Strategy has no validation
|
||||
// field appsv1.DeploymentSpec.MinReadySeconds has no validation
|
||||
// field appsv1.DeploymentSpec.RevisionHistoryLimit has no validation
|
||||
// field appsv1.DeploymentSpec.Paused has no validation
|
||||
// field appsv1.DeploymentSpec.ProgressDeadlineSeconds has no validation
|
||||
return errs
|
||||
}
|
||||
|
||||
// Validate_ReplicaSet validates an instance of ReplicaSet according
|
||||
// to declarative validation rules in the API schema.
|
||||
func Validate_ReplicaSet(
|
||||
ctx context.Context, op operation.Operation, fldPath *field.Path,
|
||||
obj, oldObj *appsv1.ReplicaSet) (errs field.ErrorList) {
|
||||
|
||||
// field appsv1.ReplicaSet.TypeMeta has no validation
|
||||
// field appsv1.ReplicaSet.ObjectMeta has no validation
|
||||
|
||||
{ // field appsv1.ReplicaSet.Spec
|
||||
fn := func(
|
||||
fldPath *field.Path,
|
||||
obj, oldObj *appsv1.ReplicaSetSpec,
|
||||
oldValueCorrelated bool) (errs field.ErrorList) {
|
||||
// don't revalidate unchanged data
|
||||
if oldValueCorrelated && op.Type == operation.Update {
|
||||
if equality.Semantic.DeepEqual(obj, oldObj) {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
// call the type's validation function
|
||||
errs = append(errs, Validate_ReplicaSetSpec(ctx, op, fldPath, obj, oldObj)...)
|
||||
return
|
||||
}
|
||||
oldVal := safe.Field(oldObj,
|
||||
func(oldObj *appsv1.ReplicaSet) *appsv1.ReplicaSetSpec {
|
||||
return &oldObj.Spec
|
||||
})
|
||||
errs = append(errs, fn(fldPath.Child("spec"), &obj.Spec, oldVal, oldObj != nil)...)
|
||||
}
|
||||
|
||||
// field appsv1.ReplicaSet.Status has no validation
|
||||
return errs
|
||||
}
|
||||
|
||||
// Validate_ReplicaSetSpec validates an instance of ReplicaSetSpec according
|
||||
// to declarative validation rules in the API schema.
|
||||
func Validate_ReplicaSetSpec(
|
||||
ctx context.Context, op operation.Operation, fldPath *field.Path,
|
||||
obj, oldObj *appsv1.ReplicaSetSpec) (errs field.ErrorList) {
|
||||
|
||||
// field appsv1.ReplicaSetSpec.Replicas has no validation
|
||||
// field appsv1.ReplicaSetSpec.MinReadySeconds has no validation
|
||||
// field appsv1.ReplicaSetSpec.Selector has no validation
|
||||
|
||||
{ // field appsv1.ReplicaSetSpec.Template
|
||||
fn := func(
|
||||
fldPath *field.Path,
|
||||
obj, oldObj *apicorev1.PodTemplateSpec,
|
||||
oldValueCorrelated bool) (errs field.ErrorList) {
|
||||
// don't revalidate unchanged data
|
||||
if oldValueCorrelated && op.Type == operation.Update {
|
||||
if equality.Semantic.DeepEqual(obj, oldObj) {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
// call the type's validation function
|
||||
errs = append(errs, corev1.Validate_PodTemplateSpec(ctx, op, fldPath, obj, oldObj)...)
|
||||
return
|
||||
}
|
||||
oldVal := safe.Field(oldObj,
|
||||
func(oldObj *appsv1.ReplicaSetSpec) *apicorev1.PodTemplateSpec {
|
||||
return &oldObj.Template
|
||||
})
|
||||
errs = append(errs, fn(fldPath.Child("template"), &obj.Template, oldVal, oldObj != nil)...)
|
||||
}
|
||||
|
||||
return errs
|
||||
}
|
||||
|
||||
// Validate_StatefulSet validates an instance of StatefulSet according
|
||||
// to declarative validation rules in the API schema.
|
||||
func Validate_StatefulSet(
|
||||
ctx context.Context, op operation.Operation, fldPath *field.Path,
|
||||
obj, oldObj *appsv1.StatefulSet) (errs field.ErrorList) {
|
||||
|
||||
// field appsv1.StatefulSet.TypeMeta has no validation
|
||||
// field appsv1.StatefulSet.ObjectMeta has no validation
|
||||
|
||||
{ // field appsv1.StatefulSet.Spec
|
||||
fn := func(
|
||||
fldPath *field.Path,
|
||||
obj, oldObj *appsv1.StatefulSetSpec,
|
||||
oldValueCorrelated bool) (errs field.ErrorList) {
|
||||
// don't revalidate unchanged data
|
||||
if oldValueCorrelated && op.Type == operation.Update {
|
||||
if equality.Semantic.DeepEqual(obj, oldObj) {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
// call the type's validation function
|
||||
errs = append(errs, Validate_StatefulSetSpec(ctx, op, fldPath, obj, oldObj)...)
|
||||
return
|
||||
}
|
||||
oldVal := safe.Field(oldObj,
|
||||
func(oldObj *appsv1.StatefulSet) *appsv1.StatefulSetSpec {
|
||||
return &oldObj.Spec
|
||||
})
|
||||
errs = append(errs, fn(fldPath.Child("spec"), &obj.Spec, oldVal, oldObj != nil)...)
|
||||
}
|
||||
|
||||
// field appsv1.StatefulSet.Status has no validation
|
||||
return errs
|
||||
}
|
||||
|
||||
// Validate_StatefulSetSpec validates an instance of StatefulSetSpec according
|
||||
// to declarative validation rules in the API schema.
|
||||
func Validate_StatefulSetSpec(
|
||||
ctx context.Context, op operation.Operation, fldPath *field.Path,
|
||||
obj, oldObj *appsv1.StatefulSetSpec) (errs field.ErrorList) {
|
||||
|
||||
// field appsv1.StatefulSetSpec.Replicas has no validation
|
||||
// field appsv1.StatefulSetSpec.Selector has no validation
|
||||
|
||||
{ // field appsv1.StatefulSetSpec.Template
|
||||
fn := func(
|
||||
fldPath *field.Path,
|
||||
obj, oldObj *apicorev1.PodTemplateSpec,
|
||||
oldValueCorrelated bool) (errs field.ErrorList) {
|
||||
// don't revalidate unchanged data
|
||||
if oldValueCorrelated && op.Type == operation.Update {
|
||||
if equality.Semantic.DeepEqual(obj, oldObj) {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
// call the type's validation function
|
||||
errs = append(errs, corev1.Validate_PodTemplateSpec(ctx, op, fldPath, obj, oldObj)...)
|
||||
return
|
||||
}
|
||||
oldVal := safe.Field(oldObj,
|
||||
func(oldObj *appsv1.StatefulSetSpec) *apicorev1.PodTemplateSpec {
|
||||
return &oldObj.Template
|
||||
})
|
||||
errs = append(errs, fn(fldPath.Child("template"), &obj.Template, oldVal, oldObj != nil)...)
|
||||
}
|
||||
|
||||
// field appsv1.StatefulSetSpec.VolumeClaimTemplates has no validation
|
||||
// field appsv1.StatefulSetSpec.ServiceName has no validation
|
||||
// field appsv1.StatefulSetSpec.PodManagementPolicy has no validation
|
||||
// field appsv1.StatefulSetSpec.UpdateStrategy has no validation
|
||||
// field appsv1.StatefulSetSpec.RevisionHistoryLimit has no validation
|
||||
// field appsv1.StatefulSetSpec.MinReadySeconds has no validation
|
||||
// field appsv1.StatefulSetSpec.PersistentVolumeClaimRetentionPolicy has no validation
|
||||
// field appsv1.StatefulSetSpec.Ordinals has no validation
|
||||
return errs
|
||||
}
|
||||
|
|
|
|||
185
pkg/apis/apps/v1beta1/zz_generated.validations.go
generated
185
pkg/apis/apps/v1beta1/zz_generated.validations.go
generated
|
|
@ -26,11 +26,14 @@ import (
|
|||
fmt "fmt"
|
||||
|
||||
appsv1beta1 "k8s.io/api/apps/v1beta1"
|
||||
corev1 "k8s.io/api/core/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"
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
field "k8s.io/apimachinery/pkg/util/validation/field"
|
||||
v1 "k8s.io/kubernetes/pkg/apis/core/v1"
|
||||
)
|
||||
|
||||
func init() { localSchemeBuilder.Register(RegisterValidations) }
|
||||
|
|
@ -38,6 +41,21 @@ 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 Deployment
|
||||
scheme.AddValidationFunc(
|
||||
(*appsv1beta1.Deployment)(nil),
|
||||
func(ctx context.Context, op operation.Operation, obj, oldObj interface{}) field.ErrorList {
|
||||
switch op.Request.SubresourcePath() {
|
||||
case "/", "/scale", "/status":
|
||||
return Validate_Deployment(
|
||||
ctx, op, nil, /* fldPath */
|
||||
obj.(*appsv1beta1.Deployment),
|
||||
safe.Cast[*appsv1beta1.Deployment](oldObj))
|
||||
}
|
||||
return field.ErrorList{
|
||||
field.InternalError(nil, fmt.Errorf("no validation found for %T, subresource: %v", obj, op.Request.SubresourcePath())),
|
||||
}
|
||||
})
|
||||
// type Scale
|
||||
scheme.AddValidationFunc(
|
||||
(*appsv1beta1.Scale)(nil),
|
||||
|
|
@ -53,9 +71,99 @@ func RegisterValidations(scheme *runtime.Scheme) error {
|
|||
field.InternalError(nil, fmt.Errorf("no validation found for %T, subresource: %v", obj, op.Request.SubresourcePath())),
|
||||
}
|
||||
})
|
||||
// type StatefulSet
|
||||
scheme.AddValidationFunc(
|
||||
(*appsv1beta1.StatefulSet)(nil),
|
||||
func(ctx context.Context, op operation.Operation, obj, oldObj interface{}) field.ErrorList {
|
||||
switch op.Request.SubresourcePath() {
|
||||
case "/", "/scale", "/status":
|
||||
return Validate_StatefulSet(
|
||||
ctx, op, nil, /* fldPath */
|
||||
obj.(*appsv1beta1.StatefulSet),
|
||||
safe.Cast[*appsv1beta1.StatefulSet](oldObj))
|
||||
}
|
||||
return field.ErrorList{
|
||||
field.InternalError(nil, fmt.Errorf("no validation found for %T, subresource: %v", obj, op.Request.SubresourcePath())),
|
||||
}
|
||||
})
|
||||
return nil
|
||||
}
|
||||
|
||||
// Validate_Deployment validates an instance of Deployment according
|
||||
// to declarative validation rules in the API schema.
|
||||
func Validate_Deployment(
|
||||
ctx context.Context, op operation.Operation, fldPath *field.Path,
|
||||
obj, oldObj *appsv1beta1.Deployment) (errs field.ErrorList) {
|
||||
|
||||
// field appsv1beta1.Deployment.TypeMeta has no validation
|
||||
// field appsv1beta1.Deployment.ObjectMeta has no validation
|
||||
|
||||
{ // field appsv1beta1.Deployment.Spec
|
||||
fn := func(
|
||||
fldPath *field.Path,
|
||||
obj, oldObj *appsv1beta1.DeploymentSpec,
|
||||
oldValueCorrelated bool) (errs field.ErrorList) {
|
||||
// don't revalidate unchanged data
|
||||
if oldValueCorrelated && op.Type == operation.Update {
|
||||
if equality.Semantic.DeepEqual(obj, oldObj) {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
// call the type's validation function
|
||||
errs = append(errs, Validate_DeploymentSpec(ctx, op, fldPath, obj, oldObj)...)
|
||||
return
|
||||
}
|
||||
oldVal := safe.Field(oldObj,
|
||||
func(oldObj *appsv1beta1.Deployment) *appsv1beta1.DeploymentSpec {
|
||||
return &oldObj.Spec
|
||||
})
|
||||
errs = append(errs, fn(fldPath.Child("spec"), &obj.Spec, oldVal, oldObj != nil)...)
|
||||
}
|
||||
|
||||
// field appsv1beta1.Deployment.Status has no validation
|
||||
return errs
|
||||
}
|
||||
|
||||
// Validate_DeploymentSpec validates an instance of DeploymentSpec according
|
||||
// to declarative validation rules in the API schema.
|
||||
func Validate_DeploymentSpec(
|
||||
ctx context.Context, op operation.Operation, fldPath *field.Path,
|
||||
obj, oldObj *appsv1beta1.DeploymentSpec) (errs field.ErrorList) {
|
||||
|
||||
// field appsv1beta1.DeploymentSpec.Replicas has no validation
|
||||
// field appsv1beta1.DeploymentSpec.Selector has no validation
|
||||
|
||||
{ // field appsv1beta1.DeploymentSpec.Template
|
||||
fn := func(
|
||||
fldPath *field.Path,
|
||||
obj, oldObj *corev1.PodTemplateSpec,
|
||||
oldValueCorrelated bool) (errs field.ErrorList) {
|
||||
// don't revalidate unchanged data
|
||||
if oldValueCorrelated && op.Type == operation.Update {
|
||||
if equality.Semantic.DeepEqual(obj, oldObj) {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
// call the type's validation function
|
||||
errs = append(errs, v1.Validate_PodTemplateSpec(ctx, op, fldPath, obj, oldObj)...)
|
||||
return
|
||||
}
|
||||
oldVal := safe.Field(oldObj,
|
||||
func(oldObj *appsv1beta1.DeploymentSpec) *corev1.PodTemplateSpec {
|
||||
return &oldObj.Template
|
||||
})
|
||||
errs = append(errs, fn(fldPath.Child("template"), &obj.Template, oldVal, oldObj != nil)...)
|
||||
}
|
||||
|
||||
// field appsv1beta1.DeploymentSpec.Strategy has no validation
|
||||
// field appsv1beta1.DeploymentSpec.MinReadySeconds has no validation
|
||||
// field appsv1beta1.DeploymentSpec.RevisionHistoryLimit has no validation
|
||||
// field appsv1beta1.DeploymentSpec.Paused has no validation
|
||||
// field appsv1beta1.DeploymentSpec.RollbackTo has no validation
|
||||
// field appsv1beta1.DeploymentSpec.ProgressDeadlineSeconds has no validation
|
||||
return errs
|
||||
}
|
||||
|
||||
// Validate_Scale validates an instance of Scale according
|
||||
// to declarative validation rules in the API schema.
|
||||
func Validate_Scale(
|
||||
|
|
@ -124,3 +232,80 @@ func Validate_ScaleSpec(
|
|||
|
||||
return errs
|
||||
}
|
||||
|
||||
// Validate_StatefulSet validates an instance of StatefulSet according
|
||||
// to declarative validation rules in the API schema.
|
||||
func Validate_StatefulSet(
|
||||
ctx context.Context, op operation.Operation, fldPath *field.Path,
|
||||
obj, oldObj *appsv1beta1.StatefulSet) (errs field.ErrorList) {
|
||||
|
||||
// field appsv1beta1.StatefulSet.TypeMeta has no validation
|
||||
// field appsv1beta1.StatefulSet.ObjectMeta has no validation
|
||||
|
||||
{ // field appsv1beta1.StatefulSet.Spec
|
||||
fn := func(
|
||||
fldPath *field.Path,
|
||||
obj, oldObj *appsv1beta1.StatefulSetSpec,
|
||||
oldValueCorrelated bool) (errs field.ErrorList) {
|
||||
// don't revalidate unchanged data
|
||||
if oldValueCorrelated && op.Type == operation.Update {
|
||||
if equality.Semantic.DeepEqual(obj, oldObj) {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
// call the type's validation function
|
||||
errs = append(errs, Validate_StatefulSetSpec(ctx, op, fldPath, obj, oldObj)...)
|
||||
return
|
||||
}
|
||||
oldVal := safe.Field(oldObj,
|
||||
func(oldObj *appsv1beta1.StatefulSet) *appsv1beta1.StatefulSetSpec {
|
||||
return &oldObj.Spec
|
||||
})
|
||||
errs = append(errs, fn(fldPath.Child("spec"), &obj.Spec, oldVal, oldObj != nil)...)
|
||||
}
|
||||
|
||||
// field appsv1beta1.StatefulSet.Status has no validation
|
||||
return errs
|
||||
}
|
||||
|
||||
// Validate_StatefulSetSpec validates an instance of StatefulSetSpec according
|
||||
// to declarative validation rules in the API schema.
|
||||
func Validate_StatefulSetSpec(
|
||||
ctx context.Context, op operation.Operation, fldPath *field.Path,
|
||||
obj, oldObj *appsv1beta1.StatefulSetSpec) (errs field.ErrorList) {
|
||||
|
||||
// field appsv1beta1.StatefulSetSpec.Replicas has no validation
|
||||
// field appsv1beta1.StatefulSetSpec.Selector has no validation
|
||||
|
||||
{ // field appsv1beta1.StatefulSetSpec.Template
|
||||
fn := func(
|
||||
fldPath *field.Path,
|
||||
obj, oldObj *corev1.PodTemplateSpec,
|
||||
oldValueCorrelated bool) (errs field.ErrorList) {
|
||||
// don't revalidate unchanged data
|
||||
if oldValueCorrelated && op.Type == operation.Update {
|
||||
if equality.Semantic.DeepEqual(obj, oldObj) {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
// call the type's validation function
|
||||
errs = append(errs, v1.Validate_PodTemplateSpec(ctx, op, fldPath, obj, oldObj)...)
|
||||
return
|
||||
}
|
||||
oldVal := safe.Field(oldObj,
|
||||
func(oldObj *appsv1beta1.StatefulSetSpec) *corev1.PodTemplateSpec {
|
||||
return &oldObj.Template
|
||||
})
|
||||
errs = append(errs, fn(fldPath.Child("template"), &obj.Template, oldVal, oldObj != nil)...)
|
||||
}
|
||||
|
||||
// field appsv1beta1.StatefulSetSpec.VolumeClaimTemplates has no validation
|
||||
// field appsv1beta1.StatefulSetSpec.ServiceName has no validation
|
||||
// field appsv1beta1.StatefulSetSpec.PodManagementPolicy has no validation
|
||||
// field appsv1beta1.StatefulSetSpec.UpdateStrategy has no validation
|
||||
// field appsv1beta1.StatefulSetSpec.RevisionHistoryLimit has no validation
|
||||
// field appsv1beta1.StatefulSetSpec.MinReadySeconds has no validation
|
||||
// field appsv1beta1.StatefulSetSpec.PersistentVolumeClaimRetentionPolicy has no validation
|
||||
// field appsv1beta1.StatefulSetSpec.Ordinals has no validation
|
||||
return errs
|
||||
}
|
||||
|
|
|
|||
355
pkg/apis/apps/v1beta2/zz_generated.validations.go
generated
355
pkg/apis/apps/v1beta2/zz_generated.validations.go
generated
|
|
@ -26,11 +26,14 @@ import (
|
|||
fmt "fmt"
|
||||
|
||||
appsv1beta2 "k8s.io/api/apps/v1beta2"
|
||||
corev1 "k8s.io/api/core/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"
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
field "k8s.io/apimachinery/pkg/util/validation/field"
|
||||
v1 "k8s.io/kubernetes/pkg/apis/core/v1"
|
||||
)
|
||||
|
||||
func init() { localSchemeBuilder.Register(RegisterValidations) }
|
||||
|
|
@ -38,6 +41,51 @@ 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 DaemonSet
|
||||
scheme.AddValidationFunc(
|
||||
(*appsv1beta2.DaemonSet)(nil),
|
||||
func(ctx context.Context, op operation.Operation, obj, oldObj interface{}) field.ErrorList {
|
||||
switch op.Request.SubresourcePath() {
|
||||
case "/", "/status":
|
||||
return Validate_DaemonSet(
|
||||
ctx, op, nil, /* fldPath */
|
||||
obj.(*appsv1beta2.DaemonSet),
|
||||
safe.Cast[*appsv1beta2.DaemonSet](oldObj))
|
||||
}
|
||||
return field.ErrorList{
|
||||
field.InternalError(nil, fmt.Errorf("no validation found for %T, subresource: %v", obj, op.Request.SubresourcePath())),
|
||||
}
|
||||
})
|
||||
// type Deployment
|
||||
scheme.AddValidationFunc(
|
||||
(*appsv1beta2.Deployment)(nil),
|
||||
func(ctx context.Context, op operation.Operation, obj, oldObj interface{}) field.ErrorList {
|
||||
switch op.Request.SubresourcePath() {
|
||||
case "/", "/scale", "/status":
|
||||
return Validate_Deployment(
|
||||
ctx, op, nil, /* fldPath */
|
||||
obj.(*appsv1beta2.Deployment),
|
||||
safe.Cast[*appsv1beta2.Deployment](oldObj))
|
||||
}
|
||||
return field.ErrorList{
|
||||
field.InternalError(nil, fmt.Errorf("no validation found for %T, subresource: %v", obj, op.Request.SubresourcePath())),
|
||||
}
|
||||
})
|
||||
// type ReplicaSet
|
||||
scheme.AddValidationFunc(
|
||||
(*appsv1beta2.ReplicaSet)(nil),
|
||||
func(ctx context.Context, op operation.Operation, obj, oldObj interface{}) field.ErrorList {
|
||||
switch op.Request.SubresourcePath() {
|
||||
case "/", "/scale", "/status":
|
||||
return Validate_ReplicaSet(
|
||||
ctx, op, nil, /* fldPath */
|
||||
obj.(*appsv1beta2.ReplicaSet),
|
||||
safe.Cast[*appsv1beta2.ReplicaSet](oldObj))
|
||||
}
|
||||
return field.ErrorList{
|
||||
field.InternalError(nil, fmt.Errorf("no validation found for %T, subresource: %v", obj, op.Request.SubresourcePath())),
|
||||
}
|
||||
})
|
||||
// type Scale
|
||||
scheme.AddValidationFunc(
|
||||
(*appsv1beta2.Scale)(nil),
|
||||
|
|
@ -53,9 +101,239 @@ func RegisterValidations(scheme *runtime.Scheme) error {
|
|||
field.InternalError(nil, fmt.Errorf("no validation found for %T, subresource: %v", obj, op.Request.SubresourcePath())),
|
||||
}
|
||||
})
|
||||
// type StatefulSet
|
||||
scheme.AddValidationFunc(
|
||||
(*appsv1beta2.StatefulSet)(nil),
|
||||
func(ctx context.Context, op operation.Operation, obj, oldObj interface{}) field.ErrorList {
|
||||
switch op.Request.SubresourcePath() {
|
||||
case "/", "/scale", "/status":
|
||||
return Validate_StatefulSet(
|
||||
ctx, op, nil, /* fldPath */
|
||||
obj.(*appsv1beta2.StatefulSet),
|
||||
safe.Cast[*appsv1beta2.StatefulSet](oldObj))
|
||||
}
|
||||
return field.ErrorList{
|
||||
field.InternalError(nil, fmt.Errorf("no validation found for %T, subresource: %v", obj, op.Request.SubresourcePath())),
|
||||
}
|
||||
})
|
||||
return nil
|
||||
}
|
||||
|
||||
// Validate_DaemonSet validates an instance of DaemonSet according
|
||||
// to declarative validation rules in the API schema.
|
||||
func Validate_DaemonSet(
|
||||
ctx context.Context, op operation.Operation, fldPath *field.Path,
|
||||
obj, oldObj *appsv1beta2.DaemonSet) (errs field.ErrorList) {
|
||||
|
||||
// field appsv1beta2.DaemonSet.TypeMeta has no validation
|
||||
// field appsv1beta2.DaemonSet.ObjectMeta has no validation
|
||||
|
||||
{ // field appsv1beta2.DaemonSet.Spec
|
||||
fn := func(
|
||||
fldPath *field.Path,
|
||||
obj, oldObj *appsv1beta2.DaemonSetSpec,
|
||||
oldValueCorrelated bool) (errs field.ErrorList) {
|
||||
// don't revalidate unchanged data
|
||||
if oldValueCorrelated && op.Type == operation.Update {
|
||||
if equality.Semantic.DeepEqual(obj, oldObj) {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
// call the type's validation function
|
||||
errs = append(errs, Validate_DaemonSetSpec(ctx, op, fldPath, obj, oldObj)...)
|
||||
return
|
||||
}
|
||||
oldVal := safe.Field(oldObj,
|
||||
func(oldObj *appsv1beta2.DaemonSet) *appsv1beta2.DaemonSetSpec {
|
||||
return &oldObj.Spec
|
||||
})
|
||||
errs = append(errs, fn(fldPath.Child("spec"), &obj.Spec, oldVal, oldObj != nil)...)
|
||||
}
|
||||
|
||||
// field appsv1beta2.DaemonSet.Status has no validation
|
||||
return errs
|
||||
}
|
||||
|
||||
// Validate_DaemonSetSpec validates an instance of DaemonSetSpec according
|
||||
// to declarative validation rules in the API schema.
|
||||
func Validate_DaemonSetSpec(
|
||||
ctx context.Context, op operation.Operation, fldPath *field.Path,
|
||||
obj, oldObj *appsv1beta2.DaemonSetSpec) (errs field.ErrorList) {
|
||||
|
||||
// field appsv1beta2.DaemonSetSpec.Selector has no validation
|
||||
|
||||
{ // field appsv1beta2.DaemonSetSpec.Template
|
||||
fn := func(
|
||||
fldPath *field.Path,
|
||||
obj, oldObj *corev1.PodTemplateSpec,
|
||||
oldValueCorrelated bool) (errs field.ErrorList) {
|
||||
// don't revalidate unchanged data
|
||||
if oldValueCorrelated && op.Type == operation.Update {
|
||||
if equality.Semantic.DeepEqual(obj, oldObj) {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
// call the type's validation function
|
||||
errs = append(errs, v1.Validate_PodTemplateSpec(ctx, op, fldPath, obj, oldObj)...)
|
||||
return
|
||||
}
|
||||
oldVal := safe.Field(oldObj,
|
||||
func(oldObj *appsv1beta2.DaemonSetSpec) *corev1.PodTemplateSpec {
|
||||
return &oldObj.Template
|
||||
})
|
||||
errs = append(errs, fn(fldPath.Child("template"), &obj.Template, oldVal, oldObj != nil)...)
|
||||
}
|
||||
|
||||
// field appsv1beta2.DaemonSetSpec.UpdateStrategy has no validation
|
||||
// field appsv1beta2.DaemonSetSpec.MinReadySeconds has no validation
|
||||
// field appsv1beta2.DaemonSetSpec.RevisionHistoryLimit has no validation
|
||||
return errs
|
||||
}
|
||||
|
||||
// Validate_Deployment validates an instance of Deployment according
|
||||
// to declarative validation rules in the API schema.
|
||||
func Validate_Deployment(
|
||||
ctx context.Context, op operation.Operation, fldPath *field.Path,
|
||||
obj, oldObj *appsv1beta2.Deployment) (errs field.ErrorList) {
|
||||
|
||||
// field appsv1beta2.Deployment.TypeMeta has no validation
|
||||
// field appsv1beta2.Deployment.ObjectMeta has no validation
|
||||
|
||||
{ // field appsv1beta2.Deployment.Spec
|
||||
fn := func(
|
||||
fldPath *field.Path,
|
||||
obj, oldObj *appsv1beta2.DeploymentSpec,
|
||||
oldValueCorrelated bool) (errs field.ErrorList) {
|
||||
// don't revalidate unchanged data
|
||||
if oldValueCorrelated && op.Type == operation.Update {
|
||||
if equality.Semantic.DeepEqual(obj, oldObj) {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
// call the type's validation function
|
||||
errs = append(errs, Validate_DeploymentSpec(ctx, op, fldPath, obj, oldObj)...)
|
||||
return
|
||||
}
|
||||
oldVal := safe.Field(oldObj,
|
||||
func(oldObj *appsv1beta2.Deployment) *appsv1beta2.DeploymentSpec {
|
||||
return &oldObj.Spec
|
||||
})
|
||||
errs = append(errs, fn(fldPath.Child("spec"), &obj.Spec, oldVal, oldObj != nil)...)
|
||||
}
|
||||
|
||||
// field appsv1beta2.Deployment.Status has no validation
|
||||
return errs
|
||||
}
|
||||
|
||||
// Validate_DeploymentSpec validates an instance of DeploymentSpec according
|
||||
// to declarative validation rules in the API schema.
|
||||
func Validate_DeploymentSpec(
|
||||
ctx context.Context, op operation.Operation, fldPath *field.Path,
|
||||
obj, oldObj *appsv1beta2.DeploymentSpec) (errs field.ErrorList) {
|
||||
|
||||
// field appsv1beta2.DeploymentSpec.Replicas has no validation
|
||||
// field appsv1beta2.DeploymentSpec.Selector has no validation
|
||||
|
||||
{ // field appsv1beta2.DeploymentSpec.Template
|
||||
fn := func(
|
||||
fldPath *field.Path,
|
||||
obj, oldObj *corev1.PodTemplateSpec,
|
||||
oldValueCorrelated bool) (errs field.ErrorList) {
|
||||
// don't revalidate unchanged data
|
||||
if oldValueCorrelated && op.Type == operation.Update {
|
||||
if equality.Semantic.DeepEqual(obj, oldObj) {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
// call the type's validation function
|
||||
errs = append(errs, v1.Validate_PodTemplateSpec(ctx, op, fldPath, obj, oldObj)...)
|
||||
return
|
||||
}
|
||||
oldVal := safe.Field(oldObj,
|
||||
func(oldObj *appsv1beta2.DeploymentSpec) *corev1.PodTemplateSpec {
|
||||
return &oldObj.Template
|
||||
})
|
||||
errs = append(errs, fn(fldPath.Child("template"), &obj.Template, oldVal, oldObj != nil)...)
|
||||
}
|
||||
|
||||
// field appsv1beta2.DeploymentSpec.Strategy has no validation
|
||||
// field appsv1beta2.DeploymentSpec.MinReadySeconds has no validation
|
||||
// field appsv1beta2.DeploymentSpec.RevisionHistoryLimit has no validation
|
||||
// field appsv1beta2.DeploymentSpec.Paused has no validation
|
||||
// field appsv1beta2.DeploymentSpec.ProgressDeadlineSeconds has no validation
|
||||
return errs
|
||||
}
|
||||
|
||||
// Validate_ReplicaSet validates an instance of ReplicaSet according
|
||||
// to declarative validation rules in the API schema.
|
||||
func Validate_ReplicaSet(
|
||||
ctx context.Context, op operation.Operation, fldPath *field.Path,
|
||||
obj, oldObj *appsv1beta2.ReplicaSet) (errs field.ErrorList) {
|
||||
|
||||
// field appsv1beta2.ReplicaSet.TypeMeta has no validation
|
||||
// field appsv1beta2.ReplicaSet.ObjectMeta has no validation
|
||||
|
||||
{ // field appsv1beta2.ReplicaSet.Spec
|
||||
fn := func(
|
||||
fldPath *field.Path,
|
||||
obj, oldObj *appsv1beta2.ReplicaSetSpec,
|
||||
oldValueCorrelated bool) (errs field.ErrorList) {
|
||||
// don't revalidate unchanged data
|
||||
if oldValueCorrelated && op.Type == operation.Update {
|
||||
if equality.Semantic.DeepEqual(obj, oldObj) {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
// call the type's validation function
|
||||
errs = append(errs, Validate_ReplicaSetSpec(ctx, op, fldPath, obj, oldObj)...)
|
||||
return
|
||||
}
|
||||
oldVal := safe.Field(oldObj,
|
||||
func(oldObj *appsv1beta2.ReplicaSet) *appsv1beta2.ReplicaSetSpec {
|
||||
return &oldObj.Spec
|
||||
})
|
||||
errs = append(errs, fn(fldPath.Child("spec"), &obj.Spec, oldVal, oldObj != nil)...)
|
||||
}
|
||||
|
||||
// field appsv1beta2.ReplicaSet.Status has no validation
|
||||
return errs
|
||||
}
|
||||
|
||||
// Validate_ReplicaSetSpec validates an instance of ReplicaSetSpec according
|
||||
// to declarative validation rules in the API schema.
|
||||
func Validate_ReplicaSetSpec(
|
||||
ctx context.Context, op operation.Operation, fldPath *field.Path,
|
||||
obj, oldObj *appsv1beta2.ReplicaSetSpec) (errs field.ErrorList) {
|
||||
|
||||
// field appsv1beta2.ReplicaSetSpec.Replicas has no validation
|
||||
// field appsv1beta2.ReplicaSetSpec.MinReadySeconds has no validation
|
||||
// field appsv1beta2.ReplicaSetSpec.Selector has no validation
|
||||
|
||||
{ // field appsv1beta2.ReplicaSetSpec.Template
|
||||
fn := func(
|
||||
fldPath *field.Path,
|
||||
obj, oldObj *corev1.PodTemplateSpec,
|
||||
oldValueCorrelated bool) (errs field.ErrorList) {
|
||||
// don't revalidate unchanged data
|
||||
if oldValueCorrelated && op.Type == operation.Update {
|
||||
if equality.Semantic.DeepEqual(obj, oldObj) {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
// call the type's validation function
|
||||
errs = append(errs, v1.Validate_PodTemplateSpec(ctx, op, fldPath, obj, oldObj)...)
|
||||
return
|
||||
}
|
||||
oldVal := safe.Field(oldObj,
|
||||
func(oldObj *appsv1beta2.ReplicaSetSpec) *corev1.PodTemplateSpec {
|
||||
return &oldObj.Template
|
||||
})
|
||||
errs = append(errs, fn(fldPath.Child("template"), &obj.Template, oldVal, oldObj != nil)...)
|
||||
}
|
||||
|
||||
return errs
|
||||
}
|
||||
|
||||
// Validate_Scale validates an instance of Scale according
|
||||
// to declarative validation rules in the API schema.
|
||||
func Validate_Scale(
|
||||
|
|
@ -124,3 +402,80 @@ func Validate_ScaleSpec(
|
|||
|
||||
return errs
|
||||
}
|
||||
|
||||
// Validate_StatefulSet validates an instance of StatefulSet according
|
||||
// to declarative validation rules in the API schema.
|
||||
func Validate_StatefulSet(
|
||||
ctx context.Context, op operation.Operation, fldPath *field.Path,
|
||||
obj, oldObj *appsv1beta2.StatefulSet) (errs field.ErrorList) {
|
||||
|
||||
// field appsv1beta2.StatefulSet.TypeMeta has no validation
|
||||
// field appsv1beta2.StatefulSet.ObjectMeta has no validation
|
||||
|
||||
{ // field appsv1beta2.StatefulSet.Spec
|
||||
fn := func(
|
||||
fldPath *field.Path,
|
||||
obj, oldObj *appsv1beta2.StatefulSetSpec,
|
||||
oldValueCorrelated bool) (errs field.ErrorList) {
|
||||
// don't revalidate unchanged data
|
||||
if oldValueCorrelated && op.Type == operation.Update {
|
||||
if equality.Semantic.DeepEqual(obj, oldObj) {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
// call the type's validation function
|
||||
errs = append(errs, Validate_StatefulSetSpec(ctx, op, fldPath, obj, oldObj)...)
|
||||
return
|
||||
}
|
||||
oldVal := safe.Field(oldObj,
|
||||
func(oldObj *appsv1beta2.StatefulSet) *appsv1beta2.StatefulSetSpec {
|
||||
return &oldObj.Spec
|
||||
})
|
||||
errs = append(errs, fn(fldPath.Child("spec"), &obj.Spec, oldVal, oldObj != nil)...)
|
||||
}
|
||||
|
||||
// field appsv1beta2.StatefulSet.Status has no validation
|
||||
return errs
|
||||
}
|
||||
|
||||
// Validate_StatefulSetSpec validates an instance of StatefulSetSpec according
|
||||
// to declarative validation rules in the API schema.
|
||||
func Validate_StatefulSetSpec(
|
||||
ctx context.Context, op operation.Operation, fldPath *field.Path,
|
||||
obj, oldObj *appsv1beta2.StatefulSetSpec) (errs field.ErrorList) {
|
||||
|
||||
// field appsv1beta2.StatefulSetSpec.Replicas has no validation
|
||||
// field appsv1beta2.StatefulSetSpec.Selector has no validation
|
||||
|
||||
{ // field appsv1beta2.StatefulSetSpec.Template
|
||||
fn := func(
|
||||
fldPath *field.Path,
|
||||
obj, oldObj *corev1.PodTemplateSpec,
|
||||
oldValueCorrelated bool) (errs field.ErrorList) {
|
||||
// don't revalidate unchanged data
|
||||
if oldValueCorrelated && op.Type == operation.Update {
|
||||
if equality.Semantic.DeepEqual(obj, oldObj) {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
// call the type's validation function
|
||||
errs = append(errs, v1.Validate_PodTemplateSpec(ctx, op, fldPath, obj, oldObj)...)
|
||||
return
|
||||
}
|
||||
oldVal := safe.Field(oldObj,
|
||||
func(oldObj *appsv1beta2.StatefulSetSpec) *corev1.PodTemplateSpec {
|
||||
return &oldObj.Template
|
||||
})
|
||||
errs = append(errs, fn(fldPath.Child("template"), &obj.Template, oldVal, oldObj != nil)...)
|
||||
}
|
||||
|
||||
// field appsv1beta2.StatefulSetSpec.VolumeClaimTemplates has no validation
|
||||
// field appsv1beta2.StatefulSetSpec.ServiceName has no validation
|
||||
// field appsv1beta2.StatefulSetSpec.PodManagementPolicy has no validation
|
||||
// field appsv1beta2.StatefulSetSpec.UpdateStrategy has no validation
|
||||
// field appsv1beta2.StatefulSetSpec.RevisionHistoryLimit has no validation
|
||||
// field appsv1beta2.StatefulSetSpec.MinReadySeconds has no validation
|
||||
// field appsv1beta2.StatefulSetSpec.PersistentVolumeClaimRetentionPolicy has no validation
|
||||
// field appsv1beta2.StatefulSetSpec.Ordinals has no validation
|
||||
return errs
|
||||
}
|
||||
|
|
|
|||
26
pkg/apis/batch/v1/zz_generated.validations.go
generated
26
pkg/apis/batch/v1/zz_generated.validations.go
generated
|
|
@ -26,12 +26,14 @@ import (
|
|||
fmt "fmt"
|
||||
|
||||
batchv1 "k8s.io/api/batch/v1"
|
||||
apicorev1 "k8s.io/api/core/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"
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
field "k8s.io/apimachinery/pkg/util/validation/field"
|
||||
corev1 "k8s.io/kubernetes/pkg/apis/core/v1"
|
||||
)
|
||||
|
||||
func init() { localSchemeBuilder.Register(RegisterValidations) }
|
||||
|
|
@ -269,7 +271,29 @@ func Validate_JobSpec(
|
|||
|
||||
// field batchv1.JobSpec.Selector has no validation
|
||||
// field batchv1.JobSpec.ManualSelector has no validation
|
||||
// field batchv1.JobSpec.Template has no validation
|
||||
|
||||
{ // field batchv1.JobSpec.Template
|
||||
fn := func(
|
||||
fldPath *field.Path,
|
||||
obj, oldObj *apicorev1.PodTemplateSpec,
|
||||
oldValueCorrelated bool) (errs field.ErrorList) {
|
||||
// don't revalidate unchanged data
|
||||
if oldValueCorrelated && op.Type == operation.Update {
|
||||
if equality.Semantic.DeepEqual(obj, oldObj) {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
// call the type's validation function
|
||||
errs = append(errs, corev1.Validate_PodTemplateSpec(ctx, op, fldPath, obj, oldObj)...)
|
||||
return
|
||||
}
|
||||
oldVal := safe.Field(oldObj,
|
||||
func(oldObj *batchv1.JobSpec) *apicorev1.PodTemplateSpec {
|
||||
return &oldObj.Template
|
||||
})
|
||||
errs = append(errs, fn(fldPath.Child("template"), &obj.Template, oldVal, oldObj != nil)...)
|
||||
}
|
||||
|
||||
// field batchv1.JobSpec.TTLSecondsAfterFinished has no validation
|
||||
// field batchv1.JobSpec.CompletionMode has no validation
|
||||
// field batchv1.JobSpec.Suspend has no validation
|
||||
|
|
|
|||
291
pkg/apis/core/v1/zz_generated.validations.go
generated
291
pkg/apis/core/v1/zz_generated.validations.go
generated
|
|
@ -40,6 +40,36 @@ 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 Pod
|
||||
scheme.AddValidationFunc(
|
||||
(*corev1.Pod)(nil),
|
||||
func(ctx context.Context, op operation.Operation, obj, oldObj interface{}) field.ErrorList {
|
||||
switch op.Request.SubresourcePath() {
|
||||
case "/", "/ephemeralcontainers", "/eviction", "/resize", "/status":
|
||||
return Validate_Pod(
|
||||
ctx, op, nil, /* fldPath */
|
||||
obj.(*corev1.Pod),
|
||||
safe.Cast[*corev1.Pod](oldObj))
|
||||
}
|
||||
return field.ErrorList{
|
||||
field.InternalError(nil, fmt.Errorf("no validation found for %T, subresource: %v", obj, op.Request.SubresourcePath())),
|
||||
}
|
||||
})
|
||||
// type PodTemplate
|
||||
scheme.AddValidationFunc(
|
||||
(*corev1.PodTemplate)(nil),
|
||||
func(ctx context.Context, op operation.Operation, obj, oldObj interface{}) field.ErrorList {
|
||||
switch op.Request.SubresourcePath() {
|
||||
case "/":
|
||||
return Validate_PodTemplate(
|
||||
ctx, op, nil, /* fldPath */
|
||||
obj.(*corev1.PodTemplate),
|
||||
safe.Cast[*corev1.PodTemplate](oldObj))
|
||||
}
|
||||
return field.ErrorList{
|
||||
field.InternalError(nil, fmt.Errorf("no validation found for %T, subresource: %v", obj, op.Request.SubresourcePath())),
|
||||
}
|
||||
})
|
||||
// type ReplicationController
|
||||
scheme.AddValidationFunc(
|
||||
(*corev1.ReplicationController)(nil),
|
||||
|
|
@ -73,6 +103,191 @@ func RegisterValidations(scheme *runtime.Scheme) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// Validate_Pod validates an instance of Pod according
|
||||
// to declarative validation rules in the API schema.
|
||||
func Validate_Pod(
|
||||
ctx context.Context, op operation.Operation, fldPath *field.Path,
|
||||
obj, oldObj *corev1.Pod) (errs field.ErrorList) {
|
||||
|
||||
// field corev1.Pod.TypeMeta has no validation
|
||||
// field corev1.Pod.ObjectMeta has no validation
|
||||
|
||||
{ // field corev1.Pod.Spec
|
||||
fn := func(
|
||||
fldPath *field.Path,
|
||||
obj, oldObj *corev1.PodSpec,
|
||||
oldValueCorrelated bool) (errs field.ErrorList) {
|
||||
// don't revalidate unchanged data
|
||||
if oldValueCorrelated && op.Type == operation.Update {
|
||||
if equality.Semantic.DeepEqual(obj, oldObj) {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
// call the type's validation function
|
||||
errs = append(errs, Validate_PodSpec(ctx, op, fldPath, obj, oldObj)...)
|
||||
return
|
||||
}
|
||||
oldVal := safe.Field(oldObj,
|
||||
func(oldObj *corev1.Pod) *corev1.PodSpec {
|
||||
return &oldObj.Spec
|
||||
})
|
||||
errs = append(errs, fn(fldPath.Child("spec"), &obj.Spec, oldVal, oldObj != nil)...)
|
||||
}
|
||||
|
||||
// field corev1.Pod.Status has no validation
|
||||
return errs
|
||||
}
|
||||
|
||||
// Validate_PodSpec validates an instance of PodSpec according
|
||||
// to declarative validation rules in the API schema.
|
||||
func Validate_PodSpec(
|
||||
ctx context.Context, op operation.Operation, fldPath *field.Path,
|
||||
obj, oldObj *corev1.PodSpec) (errs field.ErrorList) {
|
||||
|
||||
// field corev1.PodSpec.Volumes has no validation
|
||||
// field corev1.PodSpec.InitContainers has no validation
|
||||
// field corev1.PodSpec.Containers has no validation
|
||||
// field corev1.PodSpec.EphemeralContainers has no validation
|
||||
// field corev1.PodSpec.RestartPolicy has no validation
|
||||
// field corev1.PodSpec.TerminationGracePeriodSeconds has no validation
|
||||
// field corev1.PodSpec.ActiveDeadlineSeconds has no validation
|
||||
// field corev1.PodSpec.DNSPolicy has no validation
|
||||
// field corev1.PodSpec.NodeSelector has no validation
|
||||
// field corev1.PodSpec.ServiceAccountName has no validation
|
||||
// field corev1.PodSpec.DeprecatedServiceAccount has no validation
|
||||
// field corev1.PodSpec.AutomountServiceAccountToken has no validation
|
||||
// field corev1.PodSpec.NodeName has no validation
|
||||
// field corev1.PodSpec.HostNetwork has no validation
|
||||
// field corev1.PodSpec.HostPID has no validation
|
||||
// field corev1.PodSpec.HostIPC has no validation
|
||||
// field corev1.PodSpec.ShareProcessNamespace has no validation
|
||||
// field corev1.PodSpec.SecurityContext has no validation
|
||||
// field corev1.PodSpec.ImagePullSecrets has no validation
|
||||
// field corev1.PodSpec.Hostname has no validation
|
||||
// field corev1.PodSpec.Subdomain has no validation
|
||||
// field corev1.PodSpec.Affinity has no validation
|
||||
// field corev1.PodSpec.SchedulerName has no validation
|
||||
|
||||
{ // field corev1.PodSpec.Tolerations
|
||||
fn := func(
|
||||
fldPath *field.Path,
|
||||
obj, oldObj []corev1.Toleration,
|
||||
oldValueCorrelated bool) (errs field.ErrorList) {
|
||||
// don't revalidate unchanged data
|
||||
if oldValueCorrelated && op.Type == operation.Update {
|
||||
if equality.Semantic.DeepEqual(obj, oldObj) {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
// call field-attached validations
|
||||
earlyReturn := false
|
||||
if e := validate.OptionalSlice(ctx, op, fldPath, obj, oldObj).MarkAlpha().MarkShortCircuit(); len(e) != 0 {
|
||||
earlyReturn = true
|
||||
}
|
||||
if earlyReturn {
|
||||
return // do not proceed
|
||||
}
|
||||
// iterate the list and call the type's validation function
|
||||
if e := validate.EachSliceVal(ctx, op, fldPath, obj, oldObj, nil, nil, Validate_Toleration); len(e) != 0 {
|
||||
errs = append(errs, e...)
|
||||
}
|
||||
return
|
||||
}
|
||||
oldVal := safe.Field(oldObj,
|
||||
func(oldObj *corev1.PodSpec) []corev1.Toleration {
|
||||
return oldObj.Tolerations
|
||||
})
|
||||
errs = append(errs, fn(fldPath.Child("tolerations"), obj.Tolerations, oldVal, oldObj != nil)...)
|
||||
}
|
||||
|
||||
// field corev1.PodSpec.HostAliases has no validation
|
||||
// field corev1.PodSpec.PriorityClassName has no validation
|
||||
// field corev1.PodSpec.Priority has no validation
|
||||
// field corev1.PodSpec.DNSConfig has no validation
|
||||
// field corev1.PodSpec.ReadinessGates has no validation
|
||||
// field corev1.PodSpec.RuntimeClassName has no validation
|
||||
// field corev1.PodSpec.EnableServiceLinks has no validation
|
||||
// field corev1.PodSpec.PreemptionPolicy has no validation
|
||||
// field corev1.PodSpec.Overhead has no validation
|
||||
// field corev1.PodSpec.TopologySpreadConstraints has no validation
|
||||
// field corev1.PodSpec.SetHostnameAsFQDN has no validation
|
||||
// field corev1.PodSpec.OS has no validation
|
||||
// field corev1.PodSpec.HostUsers has no validation
|
||||
// field corev1.PodSpec.SchedulingGates has no validation
|
||||
// field corev1.PodSpec.ResourceClaims has no validation
|
||||
// field corev1.PodSpec.Resources has no validation
|
||||
// field corev1.PodSpec.HostnameOverride has no validation
|
||||
// field corev1.PodSpec.SchedulingGroup has no validation
|
||||
return errs
|
||||
}
|
||||
|
||||
// Validate_PodTemplate validates an instance of PodTemplate according
|
||||
// to declarative validation rules in the API schema.
|
||||
func Validate_PodTemplate(
|
||||
ctx context.Context, op operation.Operation, fldPath *field.Path,
|
||||
obj, oldObj *corev1.PodTemplate) (errs field.ErrorList) {
|
||||
|
||||
// field corev1.PodTemplate.TypeMeta has no validation
|
||||
// field corev1.PodTemplate.ObjectMeta has no validation
|
||||
|
||||
{ // field corev1.PodTemplate.Template
|
||||
fn := func(
|
||||
fldPath *field.Path,
|
||||
obj, oldObj *corev1.PodTemplateSpec,
|
||||
oldValueCorrelated bool) (errs field.ErrorList) {
|
||||
// don't revalidate unchanged data
|
||||
if oldValueCorrelated && op.Type == operation.Update {
|
||||
if equality.Semantic.DeepEqual(obj, oldObj) {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
// call the type's validation function
|
||||
errs = append(errs, Validate_PodTemplateSpec(ctx, op, fldPath, obj, oldObj)...)
|
||||
return
|
||||
}
|
||||
oldVal := safe.Field(oldObj,
|
||||
func(oldObj *corev1.PodTemplate) *corev1.PodTemplateSpec {
|
||||
return &oldObj.Template
|
||||
})
|
||||
errs = append(errs, fn(fldPath.Child("template"), &obj.Template, oldVal, oldObj != nil)...)
|
||||
}
|
||||
|
||||
return errs
|
||||
}
|
||||
|
||||
// Validate_PodTemplateSpec validates an instance of PodTemplateSpec according
|
||||
// to declarative validation rules in the API schema.
|
||||
func Validate_PodTemplateSpec(
|
||||
ctx context.Context, op operation.Operation, fldPath *field.Path,
|
||||
obj, oldObj *corev1.PodTemplateSpec) (errs field.ErrorList) {
|
||||
|
||||
// field corev1.PodTemplateSpec.ObjectMeta has no validation
|
||||
|
||||
{ // field corev1.PodTemplateSpec.Spec
|
||||
fn := func(
|
||||
fldPath *field.Path,
|
||||
obj, oldObj *corev1.PodSpec,
|
||||
oldValueCorrelated bool) (errs field.ErrorList) {
|
||||
// don't revalidate unchanged data
|
||||
if oldValueCorrelated && op.Type == operation.Update {
|
||||
if equality.Semantic.DeepEqual(obj, oldObj) {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
// call the type's validation function
|
||||
errs = append(errs, Validate_PodSpec(ctx, op, fldPath, obj, oldObj)...)
|
||||
return
|
||||
}
|
||||
oldVal := safe.Field(oldObj,
|
||||
func(oldObj *corev1.PodTemplateSpec) *corev1.PodSpec {
|
||||
return &oldObj.Spec
|
||||
})
|
||||
errs = append(errs, fn(fldPath.Child("spec"), &obj.Spec, oldVal, oldObj != nil)...)
|
||||
}
|
||||
|
||||
return errs
|
||||
}
|
||||
|
||||
// Validate_ReplicationController validates an instance of ReplicationController according
|
||||
// to declarative validation rules in the API schema.
|
||||
func Validate_ReplicationController(
|
||||
|
|
@ -207,7 +422,37 @@ func Validate_ReplicationControllerSpec(
|
|||
}
|
||||
|
||||
// field corev1.ReplicationControllerSpec.Selector has no validation
|
||||
// field corev1.ReplicationControllerSpec.Template has no validation
|
||||
|
||||
{ // field corev1.ReplicationControllerSpec.Template
|
||||
fn := func(
|
||||
fldPath *field.Path,
|
||||
obj, oldObj *corev1.PodTemplateSpec,
|
||||
oldValueCorrelated bool) (errs field.ErrorList) {
|
||||
// don't revalidate unchanged data
|
||||
if oldValueCorrelated && op.Type == operation.Update {
|
||||
if equality.Semantic.DeepEqual(obj, oldObj) {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
// call field-attached validations
|
||||
earlyReturn := false
|
||||
if e := validate.OptionalPointer(ctx, op, fldPath, obj, oldObj).MarkAlpha().MarkShortCircuit(); len(e) != 0 {
|
||||
earlyReturn = true
|
||||
}
|
||||
if earlyReturn {
|
||||
return // do not proceed
|
||||
}
|
||||
// call the type's validation function
|
||||
errs = append(errs, Validate_PodTemplateSpec(ctx, op, fldPath, obj, oldObj)...)
|
||||
return
|
||||
}
|
||||
oldVal := safe.Field(oldObj,
|
||||
func(oldObj *corev1.ReplicationControllerSpec) *corev1.PodTemplateSpec {
|
||||
return oldObj.Template
|
||||
})
|
||||
errs = append(errs, fn(fldPath.Child("template"), obj.Template, oldVal, oldObj != nil)...)
|
||||
}
|
||||
|
||||
return errs
|
||||
}
|
||||
|
||||
|
|
@ -257,3 +502,47 @@ func Validate_Secret(
|
|||
|
||||
return errs
|
||||
}
|
||||
|
||||
// Validate_Toleration validates an instance of Toleration according
|
||||
// to declarative validation rules in the API schema.
|
||||
func Validate_Toleration(
|
||||
ctx context.Context, op operation.Operation, fldPath *field.Path,
|
||||
obj, oldObj *corev1.Toleration) (errs field.ErrorList) {
|
||||
|
||||
{ // field corev1.Toleration.Key
|
||||
fn := func(
|
||||
fldPath *field.Path,
|
||||
obj, oldObj *string,
|
||||
oldValueCorrelated bool) (errs field.ErrorList) {
|
||||
// don't revalidate unchanged data
|
||||
if oldValueCorrelated && op.Type == operation.Update {
|
||||
if obj == oldObj || (obj != nil && oldObj != nil && *obj == *oldObj) {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
// call field-attached validations
|
||||
earlyReturn := false
|
||||
if e := validate.OptionalValue(ctx, op, fldPath, obj, oldObj).MarkAlpha().MarkShortCircuit(); len(e) != 0 {
|
||||
earlyReturn = true
|
||||
}
|
||||
if earlyReturn {
|
||||
return // do not proceed
|
||||
}
|
||||
if e := validate.LabelKey(ctx, op, fldPath, obj, oldObj).MarkAlpha(); len(e) != 0 {
|
||||
errs = append(errs, e...)
|
||||
}
|
||||
return
|
||||
}
|
||||
oldVal := safe.Field(oldObj,
|
||||
func(oldObj *corev1.Toleration) *string {
|
||||
return &oldObj.Key
|
||||
})
|
||||
errs = append(errs, fn(fldPath.Child("key"), &obj.Key, oldVal, oldObj != nil)...)
|
||||
}
|
||||
|
||||
// field corev1.Toleration.Operator has no validation
|
||||
// field corev1.Toleration.Value has no validation
|
||||
// field corev1.Toleration.Effect has no validation
|
||||
// field corev1.Toleration.TolerationSeconds has no validation
|
||||
return errs
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4315,7 +4315,7 @@ func validateOnlyAddedTolerations(newTolerations []core.Toleration, oldToleratio
|
|||
}
|
||||
}
|
||||
|
||||
allErrs = append(allErrs, ValidateTolerations(newTolerations, fldPath, opts)...)
|
||||
allErrs = append(allErrs, ValidateTolerations(newTolerations, fldPath, opts, KeyFormatCovered)...)
|
||||
return allErrs
|
||||
}
|
||||
|
||||
|
|
@ -4352,14 +4352,34 @@ func ValidateHostAliases(hostAliases []core.HostAlias, fldPath *field.Path) fiel
|
|||
return allErrs
|
||||
}
|
||||
|
||||
// ValidateTolerationsOption is an option for ValidateTolerations that marks
|
||||
// which handwritten validation error messages are covered by declarative
|
||||
// validation.
|
||||
type ValidateTolerationsOption int
|
||||
|
||||
const (
|
||||
// KeyFormatCovered indicates the toleration key format check is
|
||||
// covered by declarative validation. It must only be passed by callers whose
|
||||
// tolerations are validated declaratively (the structured PodSpec.tolerations
|
||||
// and RuntimeClass.scheduling.tolerations fields). It must NOT be passed by
|
||||
// ValidateTolerationsInPodAnnotations, whose tolerations are parsed from an
|
||||
// annotation string and have no declarative counterpart.
|
||||
KeyFormatCovered ValidateTolerationsOption = iota
|
||||
)
|
||||
|
||||
// ValidateTolerations tests if given tolerations have valid data.
|
||||
func ValidateTolerations(tolerations []core.Toleration, fldPath *field.Path, opts PodValidationOptions) field.ErrorList {
|
||||
func ValidateTolerations(tolerations []core.Toleration, fldPath *field.Path, opts PodValidationOptions, validationOpts ...ValidateTolerationsOption) field.ErrorList {
|
||||
allErrors := field.ErrorList{}
|
||||
keyFormatCovered := slices.Contains(validationOpts, KeyFormatCovered)
|
||||
for i, toleration := range tolerations {
|
||||
idxPath := fldPath.Index(i)
|
||||
// validate the toleration key
|
||||
if len(toleration.Key) > 0 {
|
||||
allErrors = append(allErrors, unversionedvalidation.ValidateLabelName(toleration.Key, idxPath.Child("key"))...)
|
||||
keyErrs := unversionedvalidation.ValidateLabelName(toleration.Key, idxPath.Child("key"))
|
||||
if keyFormatCovered {
|
||||
keyErrs = keyErrs.MarkCoveredByDeclarative()
|
||||
}
|
||||
allErrors = append(allErrors, keyErrs...)
|
||||
}
|
||||
|
||||
// empty toleration key with Exists operator and empty value means match all taints
|
||||
|
|
@ -4688,7 +4708,7 @@ func ValidatePodSpec(spec *core.PodSpec, podMeta *metav1.ObjectMeta, fldPath *fi
|
|||
}
|
||||
|
||||
if len(spec.Tolerations) > 0 {
|
||||
allErrs = append(allErrs, ValidateTolerations(spec.Tolerations, fldPath.Child("tolerations"), opts)...)
|
||||
allErrs = append(allErrs, ValidateTolerations(spec.Tolerations, fldPath.Child("tolerations"), opts, KeyFormatCovered)...)
|
||||
}
|
||||
|
||||
if len(spec.HostAliases) > 0 {
|
||||
|
|
|
|||
78
pkg/apis/node/v1/zz_generated.validations.go
generated
78
pkg/apis/node/v1/zz_generated.validations.go
generated
|
|
@ -25,12 +25,15 @@ import (
|
|||
context "context"
|
||||
fmt "fmt"
|
||||
|
||||
apicorev1 "k8s.io/api/core/v1"
|
||||
nodev1 "k8s.io/api/node/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"
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
field "k8s.io/apimachinery/pkg/util/validation/field"
|
||||
corev1 "k8s.io/kubernetes/pkg/apis/core/v1"
|
||||
)
|
||||
|
||||
func init() { localSchemeBuilder.Register(RegisterValidations) }
|
||||
|
|
@ -102,6 +105,79 @@ func Validate_RuntimeClass(
|
|||
}
|
||||
|
||||
// field nodev1.RuntimeClass.Overhead has no validation
|
||||
// field nodev1.RuntimeClass.Scheduling has no validation
|
||||
|
||||
{ // field nodev1.RuntimeClass.Scheduling
|
||||
fn := func(
|
||||
fldPath *field.Path,
|
||||
obj, oldObj *nodev1.Scheduling,
|
||||
oldValueCorrelated bool) (errs field.ErrorList) {
|
||||
// don't revalidate unchanged data
|
||||
if oldValueCorrelated && op.Type == operation.Update {
|
||||
if equality.Semantic.DeepEqual(obj, oldObj) {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
// call field-attached validations
|
||||
earlyReturn := false
|
||||
if e := validate.OptionalPointer(ctx, op, fldPath, obj, oldObj).MarkAlpha().MarkShortCircuit(); len(e) != 0 {
|
||||
earlyReturn = true
|
||||
}
|
||||
if earlyReturn {
|
||||
return // do not proceed
|
||||
}
|
||||
// call the type's validation function
|
||||
errs = append(errs, Validate_Scheduling(ctx, op, fldPath, obj, oldObj)...)
|
||||
return
|
||||
}
|
||||
oldVal := safe.Field(oldObj,
|
||||
func(oldObj *nodev1.RuntimeClass) *nodev1.Scheduling {
|
||||
return oldObj.Scheduling
|
||||
})
|
||||
errs = append(errs, fn(fldPath.Child("scheduling"), obj.Scheduling, oldVal, oldObj != nil)...)
|
||||
}
|
||||
|
||||
return errs
|
||||
}
|
||||
|
||||
// Validate_Scheduling validates an instance of Scheduling according
|
||||
// to declarative validation rules in the API schema.
|
||||
func Validate_Scheduling(
|
||||
ctx context.Context, op operation.Operation, fldPath *field.Path,
|
||||
obj, oldObj *nodev1.Scheduling) (errs field.ErrorList) {
|
||||
|
||||
// field nodev1.Scheduling.NodeSelector has no validation
|
||||
|
||||
{ // field nodev1.Scheduling.Tolerations
|
||||
fn := func(
|
||||
fldPath *field.Path,
|
||||
obj, oldObj []apicorev1.Toleration,
|
||||
oldValueCorrelated bool) (errs field.ErrorList) {
|
||||
// don't revalidate unchanged data
|
||||
if oldValueCorrelated && op.Type == operation.Update {
|
||||
if equality.Semantic.DeepEqual(obj, oldObj) {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
// call field-attached validations
|
||||
earlyReturn := false
|
||||
if e := validate.OptionalSlice(ctx, op, fldPath, obj, oldObj).MarkAlpha().MarkShortCircuit(); len(e) != 0 {
|
||||
earlyReturn = true
|
||||
}
|
||||
if earlyReturn {
|
||||
return // do not proceed
|
||||
}
|
||||
// iterate the list and call the type's validation function
|
||||
if e := validate.EachSliceVal(ctx, op, fldPath, obj, oldObj, nil, nil, corev1.Validate_Toleration); len(e) != 0 {
|
||||
errs = append(errs, e...)
|
||||
}
|
||||
return
|
||||
}
|
||||
oldVal := safe.Field(oldObj,
|
||||
func(oldObj *nodev1.Scheduling) []apicorev1.Toleration {
|
||||
return oldObj.Tolerations
|
||||
})
|
||||
errs = append(errs, fn(fldPath.Child("tolerations"), obj.Tolerations, oldVal, oldObj != nil)...)
|
||||
}
|
||||
|
||||
return errs
|
||||
}
|
||||
|
|
|
|||
77
pkg/apis/node/v1alpha1/zz_generated.validations.go
generated
77
pkg/apis/node/v1alpha1/zz_generated.validations.go
generated
|
|
@ -25,6 +25,7 @@ import (
|
|||
context "context"
|
||||
fmt "fmt"
|
||||
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
nodev1alpha1 "k8s.io/api/node/v1alpha1"
|
||||
equality "k8s.io/apimachinery/pkg/api/equality"
|
||||
operation "k8s.io/apimachinery/pkg/api/operation"
|
||||
|
|
@ -32,6 +33,7 @@ import (
|
|||
validate "k8s.io/apimachinery/pkg/api/validate"
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
field "k8s.io/apimachinery/pkg/util/validation/field"
|
||||
v1 "k8s.io/kubernetes/pkg/apis/core/v1"
|
||||
)
|
||||
|
||||
func init() { localSchemeBuilder.Register(RegisterValidations) }
|
||||
|
|
@ -134,6 +136,79 @@ func Validate_RuntimeClassSpec(
|
|||
}
|
||||
|
||||
// field nodev1alpha1.RuntimeClassSpec.Overhead has no validation
|
||||
// field nodev1alpha1.RuntimeClassSpec.Scheduling has no validation
|
||||
|
||||
{ // field nodev1alpha1.RuntimeClassSpec.Scheduling
|
||||
fn := func(
|
||||
fldPath *field.Path,
|
||||
obj, oldObj *nodev1alpha1.Scheduling,
|
||||
oldValueCorrelated bool) (errs field.ErrorList) {
|
||||
// don't revalidate unchanged data
|
||||
if oldValueCorrelated && op.Type == operation.Update {
|
||||
if equality.Semantic.DeepEqual(obj, oldObj) {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
// call field-attached validations
|
||||
earlyReturn := false
|
||||
if e := validate.OptionalPointer(ctx, op, fldPath, obj, oldObj).MarkAlpha().MarkShortCircuit(); len(e) != 0 {
|
||||
earlyReturn = true
|
||||
}
|
||||
if earlyReturn {
|
||||
return // do not proceed
|
||||
}
|
||||
// call the type's validation function
|
||||
errs = append(errs, Validate_Scheduling(ctx, op, fldPath, obj, oldObj)...)
|
||||
return
|
||||
}
|
||||
oldVal := safe.Field(oldObj,
|
||||
func(oldObj *nodev1alpha1.RuntimeClassSpec) *nodev1alpha1.Scheduling {
|
||||
return oldObj.Scheduling
|
||||
})
|
||||
errs = append(errs, fn(fldPath.Child("scheduling"), obj.Scheduling, oldVal, oldObj != nil)...)
|
||||
}
|
||||
|
||||
return errs
|
||||
}
|
||||
|
||||
// Validate_Scheduling validates an instance of Scheduling according
|
||||
// to declarative validation rules in the API schema.
|
||||
func Validate_Scheduling(
|
||||
ctx context.Context, op operation.Operation, fldPath *field.Path,
|
||||
obj, oldObj *nodev1alpha1.Scheduling) (errs field.ErrorList) {
|
||||
|
||||
// field nodev1alpha1.Scheduling.NodeSelector has no validation
|
||||
|
||||
{ // field nodev1alpha1.Scheduling.Tolerations
|
||||
fn := func(
|
||||
fldPath *field.Path,
|
||||
obj, oldObj []corev1.Toleration,
|
||||
oldValueCorrelated bool) (errs field.ErrorList) {
|
||||
// don't revalidate unchanged data
|
||||
if oldValueCorrelated && op.Type == operation.Update {
|
||||
if equality.Semantic.DeepEqual(obj, oldObj) {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
// call field-attached validations
|
||||
earlyReturn := false
|
||||
if e := validate.OptionalSlice(ctx, op, fldPath, obj, oldObj).MarkAlpha().MarkShortCircuit(); len(e) != 0 {
|
||||
earlyReturn = true
|
||||
}
|
||||
if earlyReturn {
|
||||
return // do not proceed
|
||||
}
|
||||
// iterate the list and call the type's validation function
|
||||
if e := validate.EachSliceVal(ctx, op, fldPath, obj, oldObj, nil, nil, v1.Validate_Toleration); len(e) != 0 {
|
||||
errs = append(errs, e...)
|
||||
}
|
||||
return
|
||||
}
|
||||
oldVal := safe.Field(oldObj,
|
||||
func(oldObj *nodev1alpha1.Scheduling) []corev1.Toleration {
|
||||
return oldObj.Tolerations
|
||||
})
|
||||
errs = append(errs, fn(fldPath.Child("tolerations"), obj.Tolerations, oldVal, oldObj != nil)...)
|
||||
}
|
||||
|
||||
return errs
|
||||
}
|
||||
|
|
|
|||
78
pkg/apis/node/v1beta1/zz_generated.validations.go
generated
78
pkg/apis/node/v1beta1/zz_generated.validations.go
generated
|
|
@ -25,12 +25,15 @@ import (
|
|||
context "context"
|
||||
fmt "fmt"
|
||||
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
nodev1beta1 "k8s.io/api/node/v1beta1"
|
||||
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"
|
||||
v1 "k8s.io/kubernetes/pkg/apis/core/v1"
|
||||
)
|
||||
|
||||
func init() { localSchemeBuilder.Register(RegisterValidations) }
|
||||
|
|
@ -102,6 +105,79 @@ func Validate_RuntimeClass(
|
|||
}
|
||||
|
||||
// field nodev1beta1.RuntimeClass.Overhead has no validation
|
||||
// field nodev1beta1.RuntimeClass.Scheduling has no validation
|
||||
|
||||
{ // field nodev1beta1.RuntimeClass.Scheduling
|
||||
fn := func(
|
||||
fldPath *field.Path,
|
||||
obj, oldObj *nodev1beta1.Scheduling,
|
||||
oldValueCorrelated bool) (errs field.ErrorList) {
|
||||
// don't revalidate unchanged data
|
||||
if oldValueCorrelated && op.Type == operation.Update {
|
||||
if equality.Semantic.DeepEqual(obj, oldObj) {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
// call field-attached validations
|
||||
earlyReturn := false
|
||||
if e := validate.OptionalPointer(ctx, op, fldPath, obj, oldObj).MarkAlpha().MarkShortCircuit(); len(e) != 0 {
|
||||
earlyReturn = true
|
||||
}
|
||||
if earlyReturn {
|
||||
return // do not proceed
|
||||
}
|
||||
// call the type's validation function
|
||||
errs = append(errs, Validate_Scheduling(ctx, op, fldPath, obj, oldObj)...)
|
||||
return
|
||||
}
|
||||
oldVal := safe.Field(oldObj,
|
||||
func(oldObj *nodev1beta1.RuntimeClass) *nodev1beta1.Scheduling {
|
||||
return oldObj.Scheduling
|
||||
})
|
||||
errs = append(errs, fn(fldPath.Child("scheduling"), obj.Scheduling, oldVal, oldObj != nil)...)
|
||||
}
|
||||
|
||||
return errs
|
||||
}
|
||||
|
||||
// Validate_Scheduling validates an instance of Scheduling according
|
||||
// to declarative validation rules in the API schema.
|
||||
func Validate_Scheduling(
|
||||
ctx context.Context, op operation.Operation, fldPath *field.Path,
|
||||
obj, oldObj *nodev1beta1.Scheduling) (errs field.ErrorList) {
|
||||
|
||||
// field nodev1beta1.Scheduling.NodeSelector has no validation
|
||||
|
||||
{ // field nodev1beta1.Scheduling.Tolerations
|
||||
fn := func(
|
||||
fldPath *field.Path,
|
||||
obj, oldObj []corev1.Toleration,
|
||||
oldValueCorrelated bool) (errs field.ErrorList) {
|
||||
// don't revalidate unchanged data
|
||||
if oldValueCorrelated && op.Type == operation.Update {
|
||||
if equality.Semantic.DeepEqual(obj, oldObj) {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
// call field-attached validations
|
||||
earlyReturn := false
|
||||
if e := validate.OptionalSlice(ctx, op, fldPath, obj, oldObj).MarkAlpha().MarkShortCircuit(); len(e) != 0 {
|
||||
earlyReturn = true
|
||||
}
|
||||
if earlyReturn {
|
||||
return // do not proceed
|
||||
}
|
||||
// iterate the list and call the type's validation function
|
||||
if e := validate.EachSliceVal(ctx, op, fldPath, obj, oldObj, nil, nil, v1.Validate_Toleration); len(e) != 0 {
|
||||
errs = append(errs, e...)
|
||||
}
|
||||
return
|
||||
}
|
||||
oldVal := safe.Field(oldObj,
|
||||
func(oldObj *nodev1beta1.Scheduling) []corev1.Toleration {
|
||||
return oldObj.Tolerations
|
||||
})
|
||||
errs = append(errs, fn(fldPath.Child("tolerations"), obj.Tolerations, oldVal, oldObj != nil)...)
|
||||
}
|
||||
|
||||
return errs
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,13 +26,19 @@ import (
|
|||
"regexp"
|
||||
)
|
||||
|
||||
// Define normalization rules to handle field name differences across API versions
|
||||
// v1alpha1 uses "spec.runtimeHandler" while v1/v1beta1 use "handler"
|
||||
// Define normalization rules to handle field name differences across API versions.
|
||||
// v1alpha1 nests fields under "spec" (e.g. "spec.runtimeHandler", "spec.scheduling")
|
||||
// while v1/v1beta1 expose them at the top level ("handler", "scheduling"), matching
|
||||
// the internal type used by handwritten validation.
|
||||
var NodeNormalizationRules = []field.NormalizationRule{
|
||||
{
|
||||
Regexp: regexp.MustCompile(`^spec\.runtimeHandler(.*)$`),
|
||||
Replacement: "handler$1",
|
||||
},
|
||||
{
|
||||
Regexp: regexp.MustCompile(`^spec\.scheduling(.*)$`),
|
||||
Replacement: "scheduling$1",
|
||||
},
|
||||
}
|
||||
|
||||
// ValidateRuntimeClass validates the RuntimeClass
|
||||
|
|
@ -81,7 +87,7 @@ func validateScheduling(s *node.Scheduling, fldPath *field.Path) field.ErrorList
|
|||
}
|
||||
|
||||
func validateTolerations(tolerations []core.Toleration, fldPath *field.Path) field.ErrorList {
|
||||
allErrs := corevalidation.ValidateTolerations(tolerations, fldPath, corevalidation.PodValidationOptions{})
|
||||
allErrs := corevalidation.ValidateTolerations(tolerations, fldPath, corevalidation.PodValidationOptions{}, corevalidation.KeyFormatCovered)
|
||||
// Ensure uniquenes of tolerations.
|
||||
tolerationSet := map[core.Toleration]bool{}
|
||||
for i, t := range tolerations {
|
||||
|
|
|
|||
|
|
@ -228,6 +228,7 @@ message DaemonSetUpdateStrategy {
|
|||
}
|
||||
|
||||
// Deployment enables declarative updates for Pods and ReplicaSets.
|
||||
// +k8s:supportsSubresource="/scale"
|
||||
// +k8s:supportsSubresource="/status"
|
||||
message Deployment {
|
||||
// Standard object's metadata.
|
||||
|
|
@ -394,6 +395,7 @@ message DeploymentStrategy {
|
|||
}
|
||||
|
||||
// ReplicaSet ensures that a specified number of pod replicas are running at any given time.
|
||||
// +k8s:supportsSubresource="/scale"
|
||||
// +k8s:supportsSubresource="/status"
|
||||
message ReplicaSet {
|
||||
// If the Labels of a ReplicaSet are empty, they are defaulted to
|
||||
|
|
@ -619,6 +621,7 @@ message RollingUpdateStatefulSetStrategy {
|
|||
//
|
||||
// The StatefulSet guarantees that a given network identity will always
|
||||
// map to the same storage identity.
|
||||
// +k8s:supportsSubresource="/scale"
|
||||
// +k8s:supportsSubresource="/status"
|
||||
message StatefulSet {
|
||||
// Standard object's metadata.
|
||||
|
|
|
|||
|
|
@ -46,6 +46,7 @@ const (
|
|||
//
|
||||
// The StatefulSet guarantees that a given network identity will always
|
||||
// map to the same storage identity.
|
||||
// +k8s:supportsSubresource="/scale"
|
||||
// +k8s:supportsSubresource="/status"
|
||||
type StatefulSet struct {
|
||||
metav1.TypeMeta `json:""`
|
||||
|
|
@ -369,6 +370,7 @@ type StatefulSetList struct {
|
|||
// +k8s:prerelease-lifecycle-gen:introduced=1.9
|
||||
|
||||
// Deployment enables declarative updates for Pods and ReplicaSets.
|
||||
// +k8s:supportsSubresource="/scale"
|
||||
// +k8s:supportsSubresource="/status"
|
||||
type Deployment struct {
|
||||
metav1.TypeMeta `json:""`
|
||||
|
|
@ -838,6 +840,7 @@ type DaemonSetList struct {
|
|||
// +k8s:prerelease-lifecycle-gen:introduced=1.9
|
||||
|
||||
// ReplicaSet ensures that a specified number of pod replicas are running at any given time.
|
||||
// +k8s:supportsSubresource="/scale"
|
||||
// +k8s:supportsSubresource="/status"
|
||||
type ReplicaSet struct {
|
||||
metav1.TypeMeta `json:""`
|
||||
|
|
|
|||
|
|
@ -69,6 +69,7 @@ message ControllerRevisionList {
|
|||
// DEPRECATED - This group version of Deployment is deprecated by apps/v1beta2/Deployment. See the release notes for
|
||||
// more information.
|
||||
// Deployment enables declarative updates for Pods and ReplicaSets.
|
||||
// +k8s:supportsSubresource="/scale"
|
||||
// +k8s:supportsSubresource="/status"
|
||||
message Deployment {
|
||||
// Standard object metadata.
|
||||
|
|
@ -366,6 +367,7 @@ message ScaleStatus {
|
|||
//
|
||||
// The StatefulSet guarantees that a given network identity will always
|
||||
// map to the same storage identity.
|
||||
// +k8s:supportsSubresource="/scale"
|
||||
// +k8s:supportsSubresource="/status"
|
||||
message StatefulSet {
|
||||
// +optional
|
||||
|
|
|
|||
|
|
@ -98,6 +98,7 @@ type Scale struct {
|
|||
//
|
||||
// The StatefulSet guarantees that a given network identity will always
|
||||
// map to the same storage identity.
|
||||
// +k8s:supportsSubresource="/scale"
|
||||
// +k8s:supportsSubresource="/status"
|
||||
type StatefulSet struct {
|
||||
metav1.TypeMeta `json:""`
|
||||
|
|
@ -416,6 +417,7 @@ type StatefulSetList struct {
|
|||
// DEPRECATED - This group version of Deployment is deprecated by apps/v1beta2/Deployment. See the release notes for
|
||||
// more information.
|
||||
// Deployment enables declarative updates for Pods and ReplicaSets.
|
||||
// +k8s:supportsSubresource="/scale"
|
||||
// +k8s:supportsSubresource="/status"
|
||||
type Deployment struct {
|
||||
metav1.TypeMeta `json:""`
|
||||
|
|
|
|||
|
|
@ -234,6 +234,7 @@ message DaemonSetUpdateStrategy {
|
|||
// DEPRECATED - This group version of Deployment is deprecated by apps/v1/Deployment. See the release notes for
|
||||
// more information.
|
||||
// Deployment enables declarative updates for Pods and ReplicaSets.
|
||||
// +k8s:supportsSubresource="/scale"
|
||||
// +k8s:supportsSubresource="/status"
|
||||
message Deployment {
|
||||
// Standard object metadata.
|
||||
|
|
@ -401,6 +402,7 @@ message DeploymentStrategy {
|
|||
// DEPRECATED - This group version of ReplicaSet is deprecated by apps/v1/ReplicaSet. See the release notes for
|
||||
// more information.
|
||||
// ReplicaSet ensures that a specified number of pod replicas are running at any given time.
|
||||
// +k8s:supportsSubresource="/scale"
|
||||
// +k8s:supportsSubresource="/status"
|
||||
message ReplicaSet {
|
||||
// If the Labels of a ReplicaSet are empty, they are defaulted to
|
||||
|
|
@ -673,6 +675,7 @@ message ScaleStatus {
|
|||
//
|
||||
// The StatefulSet guarantees that a given network identity will always
|
||||
// map to the same storage identity.
|
||||
// +k8s:supportsSubresource="/scale"
|
||||
// +k8s:supportsSubresource="/status"
|
||||
message StatefulSet {
|
||||
// +optional
|
||||
|
|
|
|||
|
|
@ -104,6 +104,7 @@ type Scale struct {
|
|||
//
|
||||
// The StatefulSet guarantees that a given network identity will always
|
||||
// map to the same storage identity.
|
||||
// +k8s:supportsSubresource="/scale"
|
||||
// +k8s:supportsSubresource="/status"
|
||||
type StatefulSet struct {
|
||||
metav1.TypeMeta `json:""`
|
||||
|
|
@ -424,6 +425,7 @@ type StatefulSetList struct {
|
|||
// DEPRECATED - This group version of Deployment is deprecated by apps/v1/Deployment. See the release notes for
|
||||
// more information.
|
||||
// Deployment enables declarative updates for Pods and ReplicaSets.
|
||||
// +k8s:supportsSubresource="/scale"
|
||||
// +k8s:supportsSubresource="/status"
|
||||
type Deployment struct {
|
||||
metav1.TypeMeta `json:""`
|
||||
|
|
@ -903,6 +905,7 @@ type DaemonSetList struct {
|
|||
// DEPRECATED - This group version of ReplicaSet is deprecated by apps/v1/ReplicaSet. See the release notes for
|
||||
// more information.
|
||||
// ReplicaSet ensures that a specified number of pod replicas are running at any given time.
|
||||
// +k8s:supportsSubresource="/scale"
|
||||
// +k8s:supportsSubresource="/status"
|
||||
type ReplicaSet struct {
|
||||
metav1.TypeMeta `json:""`
|
||||
|
|
|
|||
|
|
@ -3686,6 +3686,8 @@ message PhotonPersistentDiskVolumeSource {
|
|||
// by clients and scheduled onto hosts.
|
||||
// +k8s:supportsSubresource="/status"
|
||||
// +k8s:supportsSubresource="/ephemeralcontainers"
|
||||
// +k8s:supportsSubresource="/resize"
|
||||
// +k8s:supportsSubresource="/eviction"
|
||||
message Pod {
|
||||
// Standard object's metadata.
|
||||
// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
|
||||
|
|
@ -4604,6 +4606,7 @@ message PodSpec {
|
|||
// If specified, the pod's tolerations.
|
||||
// +optional
|
||||
// +listType=atomic
|
||||
// +k8s:alpha(since: "1.37")=+k8s:optional
|
||||
repeated Toleration tolerations = 22;
|
||||
|
||||
// HostAliases is an optional list of hosts and IPs that will be injected into the pod's hosts
|
||||
|
|
@ -5452,6 +5455,7 @@ message ReplicationControllerSpec {
|
|||
// The only allowed template.spec.restartPolicy value is "Always".
|
||||
// More info: https://kubernetes.io/docs/concepts/workloads/controllers/replicationcontroller#pod-template
|
||||
// +optional
|
||||
// +k8s:alpha(since: "1.37")=+k8s:optional
|
||||
optional PodTemplateSpec template = 3;
|
||||
}
|
||||
|
||||
|
|
@ -6638,6 +6642,8 @@ message Toleration {
|
|||
// Key is the taint key that the toleration applies to. Empty means match all taint keys.
|
||||
// If the key is empty, operator must be Exists; this combination means to match all values and all keys.
|
||||
// +optional
|
||||
// +k8s:alpha(since: "1.37")=+k8s:optional
|
||||
// +k8s:alpha(since: "1.37")=+k8s:format=k8s-label-key
|
||||
optional string key = 1;
|
||||
|
||||
// Operator represents a key's relationship to the value.
|
||||
|
|
|
|||
|
|
@ -4094,6 +4094,8 @@ type Toleration struct {
|
|||
// Key is the taint key that the toleration applies to. Empty means match all taint keys.
|
||||
// If the key is empty, operator must be Exists; this combination means to match all values and all keys.
|
||||
// +optional
|
||||
// +k8s:alpha(since: "1.37")=+k8s:optional
|
||||
// +k8s:alpha(since: "1.37")=+k8s:format=k8s-label-key
|
||||
Key string `json:"key,omitempty" protobuf:"bytes,1,opt,name=key"`
|
||||
// Operator represents a key's relationship to the value.
|
||||
// Valid operators are Exists, Equal, Lt, and Gt. Defaults to Equal.
|
||||
|
|
@ -4295,6 +4297,7 @@ type PodSpec struct {
|
|||
// If specified, the pod's tolerations.
|
||||
// +optional
|
||||
// +listType=atomic
|
||||
// +k8s:alpha(since: "1.37")=+k8s:optional
|
||||
Tolerations []Toleration `json:"tolerations,omitempty" protobuf:"bytes,22,opt,name=tolerations"`
|
||||
// HostAliases is an optional list of hosts and IPs that will be injected into the pod's hosts
|
||||
// file if specified.
|
||||
|
|
@ -5492,6 +5495,8 @@ type PodStatus struct {
|
|||
// by clients and scheduled onto hosts.
|
||||
// +k8s:supportsSubresource="/status"
|
||||
// +k8s:supportsSubresource="/ephemeralcontainers"
|
||||
// +k8s:supportsSubresource="/resize"
|
||||
// +k8s:supportsSubresource="/eviction"
|
||||
type Pod struct {
|
||||
metav1.TypeMeta `json:""`
|
||||
// Standard object's metadata.
|
||||
|
|
@ -5616,6 +5621,7 @@ type ReplicationControllerSpec struct {
|
|||
// The only allowed template.spec.restartPolicy value is "Always".
|
||||
// More info: https://kubernetes.io/docs/concepts/workloads/controllers/replicationcontroller#pod-template
|
||||
// +optional
|
||||
// +k8s:alpha(since: "1.37")=+k8s:optional
|
||||
Template *PodTemplateSpec `json:"template,omitempty" protobuf:"bytes,3,opt,name=template"`
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -19,7 +19,8 @@ limitations under the License.
|
|||
// +k8s:openapi-gen=true
|
||||
// +k8s:prerelease-lifecycle-gen=true
|
||||
// +k8s:openapi-model-package=io.k8s.api.extensions.v1beta1
|
||||
// +k8s:validation-gen=TypeMeta
|
||||
// +k8s:validation-gen-input=k8s.io/api/extensions/v1beta1
|
||||
// extensions/v1beta1 is permanently unserved, so version-specific declarative
|
||||
// validation here is unreachable.
|
||||
// +k8s:validation-gen=false
|
||||
|
||||
package v1beta1
|
||||
|
|
|
|||
|
|
@ -1,418 +0,0 @@
|
|||
//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 v1beta1
|
||||
|
||||
import (
|
||||
context "context"
|
||||
fmt "fmt"
|
||||
|
||||
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 NetworkPolicy
|
||||
scheme.AddValidationFunc(
|
||||
(*NetworkPolicy)(nil),
|
||||
func(ctx context.Context, op operation.Operation, obj, oldObj interface{}) field.ErrorList {
|
||||
switch op.Request.SubresourcePath() {
|
||||
case "/":
|
||||
return Validate_NetworkPolicy(
|
||||
ctx, op, nil, /* fldPath */
|
||||
obj.(*NetworkPolicy),
|
||||
safe.Cast[*NetworkPolicy](oldObj))
|
||||
}
|
||||
return field.ErrorList{
|
||||
field.InternalError(nil, fmt.Errorf("no validation found for %T, subresource: %v", obj, op.Request.SubresourcePath())),
|
||||
}
|
||||
})
|
||||
// type Scale
|
||||
scheme.AddValidationFunc(
|
||||
(*Scale)(nil),
|
||||
func(ctx context.Context, op operation.Operation, obj, oldObj interface{}) field.ErrorList {
|
||||
switch op.Request.SubresourcePath() {
|
||||
case "/scale":
|
||||
return Validate_Scale(
|
||||
ctx, op, nil, /* fldPath */
|
||||
obj.(*Scale),
|
||||
safe.Cast[*Scale](oldObj))
|
||||
}
|
||||
return field.ErrorList{
|
||||
field.InternalError(nil, fmt.Errorf("no validation found for %T, subresource: %v", obj, op.Request.SubresourcePath())),
|
||||
}
|
||||
})
|
||||
return nil
|
||||
}
|
||||
|
||||
// Validate_IPBlock validates an instance of IPBlock according
|
||||
// to declarative validation rules in the API schema.
|
||||
func Validate_IPBlock(
|
||||
ctx context.Context, op operation.Operation, fldPath *field.Path,
|
||||
obj, oldObj *IPBlock) (errs field.ErrorList) {
|
||||
|
||||
{ // field IPBlock.CIDR
|
||||
fn := func(
|
||||
fldPath *field.Path,
|
||||
obj, oldObj *string,
|
||||
oldValueCorrelated bool) (errs field.ErrorList) {
|
||||
// don't revalidate unchanged data
|
||||
if oldValueCorrelated && op.Type == operation.Update {
|
||||
if 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).MarkAlpha().MarkShortCircuit(); len(e) != 0 {
|
||||
errs = append(errs, e...)
|
||||
earlyReturn = true
|
||||
}
|
||||
if earlyReturn {
|
||||
return // do not proceed
|
||||
}
|
||||
return
|
||||
}
|
||||
oldVal := safe.Field(oldObj,
|
||||
func(oldObj *IPBlock) *string {
|
||||
return &oldObj.CIDR
|
||||
})
|
||||
errs = append(errs, fn(fldPath.Child("cidr"), &obj.CIDR, oldVal, oldObj != nil)...)
|
||||
}
|
||||
|
||||
// field IPBlock.Except has no validation
|
||||
return errs
|
||||
}
|
||||
|
||||
// Validate_NetworkPolicy validates an instance of NetworkPolicy according
|
||||
// to declarative validation rules in the API schema.
|
||||
func Validate_NetworkPolicy(
|
||||
ctx context.Context, op operation.Operation, fldPath *field.Path,
|
||||
obj, oldObj *NetworkPolicy) (errs field.ErrorList) {
|
||||
|
||||
// field NetworkPolicy.TypeMeta has no validation
|
||||
// field NetworkPolicy.ObjectMeta has no validation
|
||||
|
||||
{ // field NetworkPolicy.Spec
|
||||
fn := func(
|
||||
fldPath *field.Path,
|
||||
obj, oldObj *NetworkPolicySpec,
|
||||
oldValueCorrelated bool) (errs field.ErrorList) {
|
||||
// don't revalidate unchanged data
|
||||
if oldValueCorrelated && op.Type == operation.Update {
|
||||
if equality.Semantic.DeepEqual(obj, oldObj) {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
// call the type's validation function
|
||||
errs = append(errs, Validate_NetworkPolicySpec(ctx, op, fldPath, obj, oldObj)...)
|
||||
return
|
||||
}
|
||||
oldVal := safe.Field(oldObj,
|
||||
func(oldObj *NetworkPolicy) *NetworkPolicySpec {
|
||||
return &oldObj.Spec
|
||||
})
|
||||
errs = append(errs, fn(fldPath.Child("spec"), &obj.Spec, oldVal, oldObj != nil)...)
|
||||
}
|
||||
|
||||
return errs
|
||||
}
|
||||
|
||||
// Validate_NetworkPolicyEgressRule validates an instance of NetworkPolicyEgressRule according
|
||||
// to declarative validation rules in the API schema.
|
||||
func Validate_NetworkPolicyEgressRule(
|
||||
ctx context.Context, op operation.Operation, fldPath *field.Path,
|
||||
obj, oldObj *NetworkPolicyEgressRule) (errs field.ErrorList) {
|
||||
|
||||
// field NetworkPolicyEgressRule.Ports has no validation
|
||||
|
||||
{ // field NetworkPolicyEgressRule.To
|
||||
fn := func(
|
||||
fldPath *field.Path,
|
||||
obj, oldObj []NetworkPolicyPeer,
|
||||
oldValueCorrelated bool) (errs field.ErrorList) {
|
||||
// don't revalidate unchanged data
|
||||
if oldValueCorrelated && op.Type == operation.Update {
|
||||
if equality.Semantic.DeepEqual(obj, oldObj) {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
// call field-attached validations
|
||||
earlyReturn := false
|
||||
if e := validate.OptionalSlice(ctx, op, fldPath, obj, oldObj).MarkAlpha().MarkShortCircuit(); len(e) != 0 {
|
||||
earlyReturn = true
|
||||
}
|
||||
if earlyReturn {
|
||||
return // do not proceed
|
||||
}
|
||||
// iterate the list and call the type's validation function
|
||||
if e := validate.EachSliceVal(ctx, op, fldPath, obj, oldObj, nil, nil, Validate_NetworkPolicyPeer); len(e) != 0 {
|
||||
errs = append(errs, e...)
|
||||
}
|
||||
return
|
||||
}
|
||||
oldVal := safe.Field(oldObj,
|
||||
func(oldObj *NetworkPolicyEgressRule) []NetworkPolicyPeer {
|
||||
return oldObj.To
|
||||
})
|
||||
errs = append(errs, fn(fldPath.Child("to"), obj.To, oldVal, oldObj != nil)...)
|
||||
}
|
||||
|
||||
return errs
|
||||
}
|
||||
|
||||
// Validate_NetworkPolicyIngressRule validates an instance of NetworkPolicyIngressRule according
|
||||
// to declarative validation rules in the API schema.
|
||||
func Validate_NetworkPolicyIngressRule(
|
||||
ctx context.Context, op operation.Operation, fldPath *field.Path,
|
||||
obj, oldObj *NetworkPolicyIngressRule) (errs field.ErrorList) {
|
||||
|
||||
// field NetworkPolicyIngressRule.Ports has no validation
|
||||
|
||||
{ // field NetworkPolicyIngressRule.From
|
||||
fn := func(
|
||||
fldPath *field.Path,
|
||||
obj, oldObj []NetworkPolicyPeer,
|
||||
oldValueCorrelated bool) (errs field.ErrorList) {
|
||||
// don't revalidate unchanged data
|
||||
if oldValueCorrelated && op.Type == operation.Update {
|
||||
if equality.Semantic.DeepEqual(obj, oldObj) {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
// call field-attached validations
|
||||
earlyReturn := false
|
||||
if e := validate.OptionalSlice(ctx, op, fldPath, obj, oldObj).MarkAlpha().MarkShortCircuit(); len(e) != 0 {
|
||||
earlyReturn = true
|
||||
}
|
||||
if earlyReturn {
|
||||
return // do not proceed
|
||||
}
|
||||
// iterate the list and call the type's validation function
|
||||
if e := validate.EachSliceVal(ctx, op, fldPath, obj, oldObj, nil, nil, Validate_NetworkPolicyPeer); len(e) != 0 {
|
||||
errs = append(errs, e...)
|
||||
}
|
||||
return
|
||||
}
|
||||
oldVal := safe.Field(oldObj,
|
||||
func(oldObj *NetworkPolicyIngressRule) []NetworkPolicyPeer {
|
||||
return oldObj.From
|
||||
})
|
||||
errs = append(errs, fn(fldPath.Child("from"), obj.From, oldVal, oldObj != nil)...)
|
||||
}
|
||||
|
||||
return errs
|
||||
}
|
||||
|
||||
// Validate_NetworkPolicyPeer validates an instance of NetworkPolicyPeer according
|
||||
// to declarative validation rules in the API schema.
|
||||
func Validate_NetworkPolicyPeer(
|
||||
ctx context.Context, op operation.Operation, fldPath *field.Path,
|
||||
obj, oldObj *NetworkPolicyPeer) (errs field.ErrorList) {
|
||||
|
||||
// field NetworkPolicyPeer.PodSelector has no validation
|
||||
// field NetworkPolicyPeer.NamespaceSelector has no validation
|
||||
|
||||
{ // field NetworkPolicyPeer.IPBlock
|
||||
fn := func(
|
||||
fldPath *field.Path,
|
||||
obj, oldObj *IPBlock,
|
||||
oldValueCorrelated bool) (errs field.ErrorList) {
|
||||
// don't revalidate unchanged data
|
||||
if oldValueCorrelated && op.Type == operation.Update {
|
||||
if equality.Semantic.DeepEqual(obj, oldObj) {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
// call field-attached validations
|
||||
earlyReturn := false
|
||||
if e := validate.OptionalPointer(ctx, op, fldPath, obj, oldObj).MarkAlpha().MarkShortCircuit(); len(e) != 0 {
|
||||
earlyReturn = true
|
||||
}
|
||||
if earlyReturn {
|
||||
return // do not proceed
|
||||
}
|
||||
// call the type's validation function
|
||||
errs = append(errs, Validate_IPBlock(ctx, op, fldPath, obj, oldObj)...)
|
||||
return
|
||||
}
|
||||
oldVal := safe.Field(oldObj,
|
||||
func(oldObj *NetworkPolicyPeer) *IPBlock {
|
||||
return oldObj.IPBlock
|
||||
})
|
||||
errs = append(errs, fn(fldPath.Child("ipBlock"), obj.IPBlock, oldVal, oldObj != nil)...)
|
||||
}
|
||||
|
||||
return errs
|
||||
}
|
||||
|
||||
// Validate_NetworkPolicySpec validates an instance of NetworkPolicySpec according
|
||||
// to declarative validation rules in the API schema.
|
||||
func Validate_NetworkPolicySpec(
|
||||
ctx context.Context, op operation.Operation, fldPath *field.Path,
|
||||
obj, oldObj *NetworkPolicySpec) (errs field.ErrorList) {
|
||||
|
||||
// field NetworkPolicySpec.PodSelector has no validation
|
||||
|
||||
{ // field NetworkPolicySpec.Ingress
|
||||
fn := func(
|
||||
fldPath *field.Path,
|
||||
obj, oldObj []NetworkPolicyIngressRule,
|
||||
oldValueCorrelated bool) (errs field.ErrorList) {
|
||||
// don't revalidate unchanged data
|
||||
if oldValueCorrelated && op.Type == operation.Update {
|
||||
if equality.Semantic.DeepEqual(obj, oldObj) {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
// call field-attached validations
|
||||
earlyReturn := false
|
||||
if e := validate.OptionalSlice(ctx, op, fldPath, obj, oldObj).MarkAlpha().MarkShortCircuit(); len(e) != 0 {
|
||||
earlyReturn = true
|
||||
}
|
||||
if earlyReturn {
|
||||
return // do not proceed
|
||||
}
|
||||
// iterate the list and call the type's validation function
|
||||
if e := validate.EachSliceVal(ctx, op, fldPath, obj, oldObj, nil, nil, Validate_NetworkPolicyIngressRule); len(e) != 0 {
|
||||
errs = append(errs, e...)
|
||||
}
|
||||
return
|
||||
}
|
||||
oldVal := safe.Field(oldObj,
|
||||
func(oldObj *NetworkPolicySpec) []NetworkPolicyIngressRule {
|
||||
return oldObj.Ingress
|
||||
})
|
||||
errs = append(errs, fn(fldPath.Child("ingress"), obj.Ingress, oldVal, oldObj != nil)...)
|
||||
}
|
||||
|
||||
{ // field NetworkPolicySpec.Egress
|
||||
fn := func(
|
||||
fldPath *field.Path,
|
||||
obj, oldObj []NetworkPolicyEgressRule,
|
||||
oldValueCorrelated bool) (errs field.ErrorList) {
|
||||
// don't revalidate unchanged data
|
||||
if oldValueCorrelated && op.Type == operation.Update {
|
||||
if equality.Semantic.DeepEqual(obj, oldObj) {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
// call field-attached validations
|
||||
earlyReturn := false
|
||||
if e := validate.OptionalSlice(ctx, op, fldPath, obj, oldObj).MarkAlpha().MarkShortCircuit(); len(e) != 0 {
|
||||
earlyReturn = true
|
||||
}
|
||||
if earlyReturn {
|
||||
return // do not proceed
|
||||
}
|
||||
// iterate the list and call the type's validation function
|
||||
if e := validate.EachSliceVal(ctx, op, fldPath, obj, oldObj, nil, nil, Validate_NetworkPolicyEgressRule); len(e) != 0 {
|
||||
errs = append(errs, e...)
|
||||
}
|
||||
return
|
||||
}
|
||||
oldVal := safe.Field(oldObj,
|
||||
func(oldObj *NetworkPolicySpec) []NetworkPolicyEgressRule {
|
||||
return oldObj.Egress
|
||||
})
|
||||
errs = append(errs, fn(fldPath.Child("egress"), obj.Egress, oldVal, oldObj != nil)...)
|
||||
}
|
||||
|
||||
// field NetworkPolicySpec.PolicyTypes 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 *Scale) (errs field.ErrorList) {
|
||||
|
||||
// field Scale.TypeMeta has no validation
|
||||
// field Scale.ObjectMeta has no validation
|
||||
|
||||
{ // field Scale.Spec
|
||||
fn := func(
|
||||
fldPath *field.Path,
|
||||
obj, oldObj *ScaleSpec,
|
||||
oldValueCorrelated bool) (errs field.ErrorList) {
|
||||
// don't revalidate unchanged data
|
||||
if oldValueCorrelated && op.Type == operation.Update {
|
||||
if obj == oldObj || (obj != nil && oldObj != nil && *obj == *oldObj) {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
// call the type's validation function
|
||||
errs = append(errs, Validate_ScaleSpec(ctx, op, fldPath, obj, oldObj)...)
|
||||
return
|
||||
}
|
||||
oldVal := safe.Field(oldObj,
|
||||
func(oldObj *Scale) *ScaleSpec {
|
||||
return &oldObj.Spec
|
||||
})
|
||||
errs = append(errs, fn(fldPath.Child("spec"), &obj.Spec, oldVal, oldObj != nil)...)
|
||||
}
|
||||
|
||||
// field Scale.Status has no validation
|
||||
return errs
|
||||
}
|
||||
|
||||
// Validate_ScaleSpec validates an instance of ScaleSpec according
|
||||
// to declarative validation rules in the API schema.
|
||||
func Validate_ScaleSpec(
|
||||
ctx context.Context, op operation.Operation, fldPath *field.Path,
|
||||
obj, oldObj *ScaleSpec) (errs field.ErrorList) {
|
||||
|
||||
{ // field ScaleSpec.Replicas
|
||||
fn := func(
|
||||
fldPath *field.Path,
|
||||
obj, oldObj *int32,
|
||||
oldValueCorrelated bool) (errs field.ErrorList) {
|
||||
// optional value-type fields with zero-value defaults are purely documentation
|
||||
// don't revalidate unchanged data
|
||||
if oldValueCorrelated && op.Type == operation.Update {
|
||||
if obj == oldObj || (obj != nil && oldObj != nil && *obj == *oldObj) {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
// call field-attached validations
|
||||
if e := validate.Minimum(ctx, op, fldPath, obj, oldObj, 0).MarkAlpha(); len(e) != 0 {
|
||||
errs = append(errs, e...)
|
||||
}
|
||||
return
|
||||
}
|
||||
oldVal := safe.Field(oldObj,
|
||||
func(oldObj *ScaleSpec) *int32 {
|
||||
return &oldObj.Replicas
|
||||
})
|
||||
errs = append(errs, fn(fldPath.Child("replicas"), &obj.Replicas, oldVal, oldObj != nil)...)
|
||||
}
|
||||
|
||||
return errs
|
||||
}
|
||||
|
|
@ -76,6 +76,7 @@ message RuntimeClass {
|
|||
// If scheduling is nil, this RuntimeClass is assumed to be supported by all
|
||||
// nodes.
|
||||
// +optional
|
||||
// +k8s:alpha(since: "1.37")=+k8s:optional
|
||||
optional Scheduling scheduling = 4;
|
||||
}
|
||||
|
||||
|
|
@ -107,6 +108,7 @@ message Scheduling {
|
|||
// tolerated by the pod and the RuntimeClass.
|
||||
// +optional
|
||||
// +listType=atomic
|
||||
// +k8s:alpha(since: "1.37")=+k8s:optional
|
||||
repeated .k8s.io.api.core.v1.Toleration tolerations = 2;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -67,6 +67,7 @@ type RuntimeClass struct {
|
|||
// If scheduling is nil, this RuntimeClass is assumed to be supported by all
|
||||
// nodes.
|
||||
// +optional
|
||||
// +k8s:alpha(since: "1.37")=+k8s:optional
|
||||
Scheduling *Scheduling `json:"scheduling,omitempty" protobuf:"bytes,4,opt,name=scheduling"`
|
||||
}
|
||||
|
||||
|
|
@ -94,6 +95,7 @@ type Scheduling struct {
|
|||
// tolerated by the pod and the RuntimeClass.
|
||||
// +optional
|
||||
// +listType=atomic
|
||||
// +k8s:alpha(since: "1.37")=+k8s:optional
|
||||
Tolerations []corev1.Toleration `json:"tolerations,omitempty" protobuf:"bytes,2,rep,name=tolerations"`
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -98,6 +98,7 @@ message RuntimeClassSpec {
|
|||
// If scheduling is nil, this RuntimeClass is assumed to be supported by all
|
||||
// nodes.
|
||||
// +optional
|
||||
// +k8s:alpha(since: "1.37")=+k8s:optional
|
||||
optional Scheduling scheduling = 3;
|
||||
}
|
||||
|
||||
|
|
@ -118,6 +119,7 @@ message Scheduling {
|
|||
// tolerated by the pod and the RuntimeClass.
|
||||
// +optional
|
||||
// +listType=atomic
|
||||
// +k8s:alpha(since: "1.37")=+k8s:optional
|
||||
repeated .k8s.io.api.core.v1.Toleration tolerations = 2;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -77,6 +77,7 @@ type RuntimeClassSpec struct {
|
|||
// If scheduling is nil, this RuntimeClass is assumed to be supported by all
|
||||
// nodes.
|
||||
// +optional
|
||||
// +k8s:alpha(since: "1.37")=+k8s:optional
|
||||
Scheduling *Scheduling `json:"scheduling,omitempty" protobuf:"bytes,3,opt,name=scheduling"`
|
||||
}
|
||||
|
||||
|
|
@ -104,6 +105,7 @@ type Scheduling struct {
|
|||
// tolerated by the pod and the RuntimeClass.
|
||||
// +optional
|
||||
// +listType=atomic
|
||||
// +k8s:alpha(since: "1.37")=+k8s:optional
|
||||
Tolerations []corev1.Toleration `json:"tolerations,omitempty" protobuf:"bytes,2,rep,name=tolerations"`
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -76,6 +76,7 @@ message RuntimeClass {
|
|||
// If scheduling is nil, this RuntimeClass is assumed to be supported by all
|
||||
// nodes.
|
||||
// +optional
|
||||
// +k8s:alpha(since: "1.37")=+k8s:optional
|
||||
optional Scheduling scheduling = 4;
|
||||
}
|
||||
|
||||
|
|
@ -107,6 +108,7 @@ message Scheduling {
|
|||
// tolerated by the pod and the RuntimeClass.
|
||||
// +optional
|
||||
// +listType=atomic
|
||||
// +k8s:alpha(since: "1.37")=+k8s:optional
|
||||
repeated .k8s.io.api.core.v1.Toleration tolerations = 2;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -68,6 +68,7 @@ type RuntimeClass struct {
|
|||
// If scheduling is nil, this RuntimeClass is assumed to be supported by all
|
||||
// nodes.
|
||||
// +optional
|
||||
// +k8s:alpha(since: "1.37")=+k8s:optional
|
||||
Scheduling *Scheduling `json:"scheduling,omitempty" protobuf:"bytes,4,opt,name=scheduling"`
|
||||
}
|
||||
|
||||
|
|
@ -95,6 +96,7 @@ type Scheduling struct {
|
|||
// tolerated by the pod and the RuntimeClass.
|
||||
// +optional
|
||||
// +listType=atomic
|
||||
// +k8s:alpha(since: "1.37")=+k8s:optional
|
||||
Tolerations []corev1.Toleration `json:"tolerations,omitempty" protobuf:"bytes,2,rep,name=tolerations"`
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,79 @@
|
|||
/*
|
||||
Copyright 2025 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 daemonset
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/util/validation/field"
|
||||
genericapirequest "k8s.io/apiserver/pkg/endpoints/request"
|
||||
podtest "k8s.io/kubernetes/pkg/api/pod/testing"
|
||||
apitesting "k8s.io/kubernetes/pkg/api/testing"
|
||||
"k8s.io/kubernetes/pkg/apis/apps"
|
||||
api "k8s.io/kubernetes/pkg/apis/core"
|
||||
registry "k8s.io/kubernetes/pkg/registry/apps/daemonset"
|
||||
)
|
||||
|
||||
func mkDaemonSet(tolerations ...api.Toleration) *apps.DaemonSet {
|
||||
return &apps.DaemonSet{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault},
|
||||
Spec: apps.DaemonSetSpec{
|
||||
Selector: &metav1.LabelSelector{MatchLabels: map[string]string{"name": "abc"}},
|
||||
UpdateStrategy: apps.DaemonSetUpdateStrategy{Type: apps.OnDeleteDaemonSetStrategyType},
|
||||
Template: api.PodTemplateSpec{
|
||||
ObjectMeta: metav1.ObjectMeta{Labels: map[string]string{"name": "abc"}},
|
||||
Spec: podtest.MakePodSpec(podtest.SetTolerations(tolerations...)),
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func TestDeclarativeValidate(t *testing.T) {
|
||||
for _, apiVersion := range apiVersions {
|
||||
ctx := genericapirequest.WithRequestInfo(genericapirequest.NewDefaultContext(), &genericapirequest.RequestInfo{
|
||||
APIGroup: "apps",
|
||||
APIVersion: apiVersion,
|
||||
})
|
||||
testCases := map[string]struct {
|
||||
input *apps.DaemonSet
|
||||
expectedErrs field.ErrorList
|
||||
}{
|
||||
"valid": {
|
||||
input: mkDaemonSet(),
|
||||
},
|
||||
"valid toleration key": {
|
||||
input: mkDaemonSet(api.Toleration{Key: "example.com/valid-key", Operator: api.TolerationOpExists}),
|
||||
},
|
||||
"valid toleration key without prefix": {
|
||||
input: mkDaemonSet(api.Toleration{Key: "simple-key", Operator: api.TolerationOpExists}),
|
||||
},
|
||||
"invalid toleration key format": {
|
||||
input: mkDaemonSet(api.Toleration{Key: "invalid key", Operator: api.TolerationOpExists}),
|
||||
expectedErrs: field.ErrorList{
|
||||
field.Invalid(field.NewPath("spec", "template", "spec", "tolerations").Index(0).Child("key"), nil, "").WithOrigin("format=k8s-label-key").MarkAlpha(),
|
||||
},
|
||||
},
|
||||
}
|
||||
for k, tc := range testCases {
|
||||
t.Run(k, func(t *testing.T) {
|
||||
apitesting.VerifyValidationEquivalence(t, ctx, tc.input, registry.Strategy, tc.expectedErrs,
|
||||
apitesting.WithSkipGroupVersions("extensions/v1beta1"))
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
43
test/declarative_validation/apps/daemonset/zz_generated.validations.main_test.go
generated
Normal file
43
test/declarative_validation/apps/daemonset/zz_generated.validations.main_test.go
generated
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
//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 daemonset
|
||||
|
||||
import (
|
||||
fmt "fmt"
|
||||
os "os"
|
||||
testing "testing"
|
||||
|
||||
coverage "k8s.io/apimachinery/pkg/test/coverage"
|
||||
)
|
||||
|
||||
var apiVersions = []string{"v1", "v1beta2"}
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
code := m.Run()
|
||||
if err := coverage.AssertDeclarativeCoverage(); err != nil {
|
||||
fmt.Fprintln(os.Stderr, err)
|
||||
if code == 0 {
|
||||
code = 1
|
||||
}
|
||||
}
|
||||
os.Exit(code)
|
||||
}
|
||||
38
test/declarative_validation/apps/daemonset/zz_generated.validations.v1_test.go
generated
Normal file
38
test/declarative_validation/apps/daemonset/zz_generated.validations.v1_test.go
generated
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
//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 daemonset
|
||||
|
||||
import (
|
||||
schema "k8s.io/apimachinery/pkg/runtime/schema"
|
||||
coverage "k8s.io/apimachinery/pkg/test/coverage"
|
||||
)
|
||||
|
||||
func init() {
|
||||
coverage.RegisterDeclaredRules(
|
||||
schema.GroupVersionKind{Group: "apps", Version: "v1", Kind: "DaemonSet"},
|
||||
coverage.FieldRules{
|
||||
"spec.template.spec.tolerations[*].key": {
|
||||
{ErrorType: "FieldValueInvalid", Origin: "format=k8s-label-key"},
|
||||
},
|
||||
},
|
||||
)
|
||||
}
|
||||
38
test/declarative_validation/apps/daemonset/zz_generated.validations.v1beta2_test.go
generated
Normal file
38
test/declarative_validation/apps/daemonset/zz_generated.validations.v1beta2_test.go
generated
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
//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 daemonset
|
||||
|
||||
import (
|
||||
schema "k8s.io/apimachinery/pkg/runtime/schema"
|
||||
coverage "k8s.io/apimachinery/pkg/test/coverage"
|
||||
)
|
||||
|
||||
func init() {
|
||||
coverage.RegisterDeclaredRules(
|
||||
schema.GroupVersionKind{Group: "apps", Version: "v1beta2", Kind: "DaemonSet"},
|
||||
coverage.FieldRules{
|
||||
"spec.template.spec.tolerations[*].key": {
|
||||
{ErrorType: "FieldValueInvalid", Origin: "format=k8s-label-key"},
|
||||
},
|
||||
},
|
||||
)
|
||||
}
|
||||
|
|
@ -0,0 +1,86 @@
|
|||
/*
|
||||
Copyright 2025 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 deployment
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/util/intstr"
|
||||
"k8s.io/apimachinery/pkg/util/validation/field"
|
||||
genericapirequest "k8s.io/apiserver/pkg/endpoints/request"
|
||||
podtest "k8s.io/kubernetes/pkg/api/pod/testing"
|
||||
apitesting "k8s.io/kubernetes/pkg/api/testing"
|
||||
"k8s.io/kubernetes/pkg/apis/apps"
|
||||
api "k8s.io/kubernetes/pkg/apis/core"
|
||||
registry "k8s.io/kubernetes/pkg/registry/apps/deployment"
|
||||
)
|
||||
|
||||
func mkDeployment(tolerations ...api.Toleration) *apps.Deployment {
|
||||
return &apps.Deployment{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault},
|
||||
Spec: apps.DeploymentSpec{
|
||||
Selector: &metav1.LabelSelector{MatchLabels: map[string]string{"name": "abc"}},
|
||||
Strategy: apps.DeploymentStrategy{
|
||||
Type: apps.RollingUpdateDeploymentStrategyType,
|
||||
RollingUpdate: &apps.RollingUpdateDeployment{
|
||||
MaxSurge: intstr.FromInt32(1),
|
||||
MaxUnavailable: intstr.FromInt32(1),
|
||||
},
|
||||
},
|
||||
Template: api.PodTemplateSpec{
|
||||
ObjectMeta: metav1.ObjectMeta{Labels: map[string]string{"name": "abc"}},
|
||||
Spec: podtest.MakePodSpec(podtest.SetTolerations(tolerations...)),
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func TestDeclarativeValidate(t *testing.T) {
|
||||
for _, apiVersion := range apiVersions {
|
||||
ctx := genericapirequest.WithRequestInfo(genericapirequest.NewDefaultContext(), &genericapirequest.RequestInfo{
|
||||
APIGroup: "apps",
|
||||
APIVersion: apiVersion,
|
||||
})
|
||||
testCases := map[string]struct {
|
||||
input *apps.Deployment
|
||||
expectedErrs field.ErrorList
|
||||
}{
|
||||
"valid": {
|
||||
input: mkDeployment(),
|
||||
},
|
||||
"valid toleration key": {
|
||||
input: mkDeployment(api.Toleration{Key: "example.com/valid-key", Operator: api.TolerationOpExists}),
|
||||
},
|
||||
"valid toleration key without prefix": {
|
||||
input: mkDeployment(api.Toleration{Key: "simple-key", Operator: api.TolerationOpExists}),
|
||||
},
|
||||
"invalid toleration key format": {
|
||||
input: mkDeployment(api.Toleration{Key: "invalid key", Operator: api.TolerationOpExists}),
|
||||
expectedErrs: field.ErrorList{
|
||||
field.Invalid(field.NewPath("spec", "template", "spec", "tolerations").Index(0).Child("key"), nil, "").WithOrigin("format=k8s-label-key").MarkAlpha(),
|
||||
},
|
||||
},
|
||||
}
|
||||
for k, tc := range testCases {
|
||||
t.Run(k, func(t *testing.T) {
|
||||
apitesting.VerifyValidationEquivalence(t, ctx, tc.input, registry.Strategy, tc.expectedErrs,
|
||||
apitesting.WithSkipGroupVersions("extensions/v1beta1"))
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
43
test/declarative_validation/apps/deployment/zz_generated.validations.main_test.go
generated
Normal file
43
test/declarative_validation/apps/deployment/zz_generated.validations.main_test.go
generated
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
//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 deployment
|
||||
|
||||
import (
|
||||
fmt "fmt"
|
||||
os "os"
|
||||
testing "testing"
|
||||
|
||||
coverage "k8s.io/apimachinery/pkg/test/coverage"
|
||||
)
|
||||
|
||||
var apiVersions = []string{"v1", "v1beta1", "v1beta2"}
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
code := m.Run()
|
||||
if err := coverage.AssertDeclarativeCoverage(); err != nil {
|
||||
fmt.Fprintln(os.Stderr, err)
|
||||
if code == 0 {
|
||||
code = 1
|
||||
}
|
||||
}
|
||||
os.Exit(code)
|
||||
}
|
||||
38
test/declarative_validation/apps/deployment/zz_generated.validations.v1_test.go
generated
Normal file
38
test/declarative_validation/apps/deployment/zz_generated.validations.v1_test.go
generated
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
//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 deployment
|
||||
|
||||
import (
|
||||
schema "k8s.io/apimachinery/pkg/runtime/schema"
|
||||
coverage "k8s.io/apimachinery/pkg/test/coverage"
|
||||
)
|
||||
|
||||
func init() {
|
||||
coverage.RegisterDeclaredRules(
|
||||
schema.GroupVersionKind{Group: "apps", Version: "v1", Kind: "Deployment"},
|
||||
coverage.FieldRules{
|
||||
"spec.template.spec.tolerations[*].key": {
|
||||
{ErrorType: "FieldValueInvalid", Origin: "format=k8s-label-key"},
|
||||
},
|
||||
},
|
||||
)
|
||||
}
|
||||
38
test/declarative_validation/apps/deployment/zz_generated.validations.v1beta1_test.go
generated
Normal file
38
test/declarative_validation/apps/deployment/zz_generated.validations.v1beta1_test.go
generated
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
//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 deployment
|
||||
|
||||
import (
|
||||
schema "k8s.io/apimachinery/pkg/runtime/schema"
|
||||
coverage "k8s.io/apimachinery/pkg/test/coverage"
|
||||
)
|
||||
|
||||
func init() {
|
||||
coverage.RegisterDeclaredRules(
|
||||
schema.GroupVersionKind{Group: "apps", Version: "v1beta1", Kind: "Deployment"},
|
||||
coverage.FieldRules{
|
||||
"spec.template.spec.tolerations[*].key": {
|
||||
{ErrorType: "FieldValueInvalid", Origin: "format=k8s-label-key"},
|
||||
},
|
||||
},
|
||||
)
|
||||
}
|
||||
38
test/declarative_validation/apps/deployment/zz_generated.validations.v1beta2_test.go
generated
Normal file
38
test/declarative_validation/apps/deployment/zz_generated.validations.v1beta2_test.go
generated
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
//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 deployment
|
||||
|
||||
import (
|
||||
schema "k8s.io/apimachinery/pkg/runtime/schema"
|
||||
coverage "k8s.io/apimachinery/pkg/test/coverage"
|
||||
)
|
||||
|
||||
func init() {
|
||||
coverage.RegisterDeclaredRules(
|
||||
schema.GroupVersionKind{Group: "apps", Version: "v1beta2", Kind: "Deployment"},
|
||||
coverage.FieldRules{
|
||||
"spec.template.spec.tolerations[*].key": {
|
||||
{ErrorType: "FieldValueInvalid", Origin: "format=k8s-label-key"},
|
||||
},
|
||||
},
|
||||
)
|
||||
}
|
||||
|
|
@ -0,0 +1,78 @@
|
|||
/*
|
||||
Copyright 2025 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 replicaset
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/util/validation/field"
|
||||
genericapirequest "k8s.io/apiserver/pkg/endpoints/request"
|
||||
podtest "k8s.io/kubernetes/pkg/api/pod/testing"
|
||||
apitesting "k8s.io/kubernetes/pkg/api/testing"
|
||||
"k8s.io/kubernetes/pkg/apis/apps"
|
||||
api "k8s.io/kubernetes/pkg/apis/core"
|
||||
registry "k8s.io/kubernetes/pkg/registry/apps/replicaset"
|
||||
)
|
||||
|
||||
func mkReplicaSet(tolerations ...api.Toleration) *apps.ReplicaSet {
|
||||
return &apps.ReplicaSet{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault},
|
||||
Spec: apps.ReplicaSetSpec{
|
||||
Selector: &metav1.LabelSelector{MatchLabels: map[string]string{"name": "abc"}},
|
||||
Template: api.PodTemplateSpec{
|
||||
ObjectMeta: metav1.ObjectMeta{Labels: map[string]string{"name": "abc"}},
|
||||
Spec: podtest.MakePodSpec(podtest.SetTolerations(tolerations...)),
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func TestDeclarativeValidate(t *testing.T) {
|
||||
for _, apiVersion := range apiVersions {
|
||||
ctx := genericapirequest.WithRequestInfo(genericapirequest.NewDefaultContext(), &genericapirequest.RequestInfo{
|
||||
APIGroup: "apps",
|
||||
APIVersion: apiVersion,
|
||||
})
|
||||
testCases := map[string]struct {
|
||||
input *apps.ReplicaSet
|
||||
expectedErrs field.ErrorList
|
||||
}{
|
||||
"valid": {
|
||||
input: mkReplicaSet(),
|
||||
},
|
||||
"valid toleration key": {
|
||||
input: mkReplicaSet(api.Toleration{Key: "example.com/valid-key", Operator: api.TolerationOpExists}),
|
||||
},
|
||||
"valid toleration key without prefix": {
|
||||
input: mkReplicaSet(api.Toleration{Key: "simple-key", Operator: api.TolerationOpExists}),
|
||||
},
|
||||
"invalid toleration key format": {
|
||||
input: mkReplicaSet(api.Toleration{Key: "invalid key", Operator: api.TolerationOpExists}),
|
||||
expectedErrs: field.ErrorList{
|
||||
field.Invalid(field.NewPath("spec", "template", "spec", "tolerations").Index(0).Child("key"), nil, "").WithOrigin("format=k8s-label-key").MarkAlpha(),
|
||||
},
|
||||
},
|
||||
}
|
||||
for k, tc := range testCases {
|
||||
t.Run(k, func(t *testing.T) {
|
||||
apitesting.VerifyValidationEquivalence(t, ctx, tc.input, registry.Strategy, tc.expectedErrs,
|
||||
apitesting.WithSkipGroupVersions("extensions/v1beta1"))
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
43
test/declarative_validation/apps/replicaset/zz_generated.validations.main_test.go
generated
Normal file
43
test/declarative_validation/apps/replicaset/zz_generated.validations.main_test.go
generated
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
//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 replicaset
|
||||
|
||||
import (
|
||||
fmt "fmt"
|
||||
os "os"
|
||||
testing "testing"
|
||||
|
||||
coverage "k8s.io/apimachinery/pkg/test/coverage"
|
||||
)
|
||||
|
||||
var apiVersions = []string{"v1", "v1beta2"}
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
code := m.Run()
|
||||
if err := coverage.AssertDeclarativeCoverage(); err != nil {
|
||||
fmt.Fprintln(os.Stderr, err)
|
||||
if code == 0 {
|
||||
code = 1
|
||||
}
|
||||
}
|
||||
os.Exit(code)
|
||||
}
|
||||
38
test/declarative_validation/apps/replicaset/zz_generated.validations.v1_test.go
generated
Normal file
38
test/declarative_validation/apps/replicaset/zz_generated.validations.v1_test.go
generated
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
//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 replicaset
|
||||
|
||||
import (
|
||||
schema "k8s.io/apimachinery/pkg/runtime/schema"
|
||||
coverage "k8s.io/apimachinery/pkg/test/coverage"
|
||||
)
|
||||
|
||||
func init() {
|
||||
coverage.RegisterDeclaredRules(
|
||||
schema.GroupVersionKind{Group: "apps", Version: "v1", Kind: "ReplicaSet"},
|
||||
coverage.FieldRules{
|
||||
"spec.template.spec.tolerations[*].key": {
|
||||
{ErrorType: "FieldValueInvalid", Origin: "format=k8s-label-key"},
|
||||
},
|
||||
},
|
||||
)
|
||||
}
|
||||
38
test/declarative_validation/apps/replicaset/zz_generated.validations.v1beta2_test.go
generated
Normal file
38
test/declarative_validation/apps/replicaset/zz_generated.validations.v1beta2_test.go
generated
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
//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 replicaset
|
||||
|
||||
import (
|
||||
schema "k8s.io/apimachinery/pkg/runtime/schema"
|
||||
coverage "k8s.io/apimachinery/pkg/test/coverage"
|
||||
)
|
||||
|
||||
func init() {
|
||||
coverage.RegisterDeclaredRules(
|
||||
schema.GroupVersionKind{Group: "apps", Version: "v1beta2", Kind: "ReplicaSet"},
|
||||
coverage.FieldRules{
|
||||
"spec.template.spec.tolerations[*].key": {
|
||||
{ErrorType: "FieldValueInvalid", Origin: "format=k8s-label-key"},
|
||||
},
|
||||
},
|
||||
)
|
||||
}
|
||||
|
|
@ -61,7 +61,7 @@ func TestDeclarativeValidateUpdate(t *testing.T) {
|
|||
t.Run(k, func(t *testing.T) {
|
||||
tc.old.ResourceVersion = "1"
|
||||
tc.update.ResourceVersion = "1"
|
||||
apitesting.VerifyUpdateValidationEquivalenceFunc(t, ctx, &tc.update, &tc.old, validateScale, tc.expectedErrs, apitesting.WithSubResources("scale"))
|
||||
apitesting.VerifyUpdateValidationEquivalenceFunc(t, ctx, &tc.update, &tc.old, validateScale, tc.expectedErrs, apitesting.WithSubResources("scale"), apitesting.WithSkipGroupVersions("extensions/v1beta1"))
|
||||
})
|
||||
}
|
||||
})
|
||||
|
|
|
|||
|
|
@ -0,0 +1,79 @@
|
|||
/*
|
||||
Copyright 2025 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 statefulset
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/util/validation/field"
|
||||
genericapirequest "k8s.io/apiserver/pkg/endpoints/request"
|
||||
podtest "k8s.io/kubernetes/pkg/api/pod/testing"
|
||||
apitesting "k8s.io/kubernetes/pkg/api/testing"
|
||||
"k8s.io/kubernetes/pkg/apis/apps"
|
||||
api "k8s.io/kubernetes/pkg/apis/core"
|
||||
registry "k8s.io/kubernetes/pkg/registry/apps/statefulset"
|
||||
)
|
||||
|
||||
func mkStatefulSet(tolerations ...api.Toleration) *apps.StatefulSet {
|
||||
return &apps.StatefulSet{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault},
|
||||
Spec: apps.StatefulSetSpec{
|
||||
PodManagementPolicy: apps.OrderedReadyPodManagement,
|
||||
Selector: &metav1.LabelSelector{MatchLabels: map[string]string{"a": "b"}},
|
||||
UpdateStrategy: apps.StatefulSetUpdateStrategy{Type: apps.RollingUpdateStatefulSetStrategyType},
|
||||
Template: api.PodTemplateSpec{
|
||||
ObjectMeta: metav1.ObjectMeta{Labels: map[string]string{"a": "b"}},
|
||||
Spec: podtest.MakePodSpec(podtest.SetTolerations(tolerations...)),
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func TestDeclarativeValidate(t *testing.T) {
|
||||
for _, apiVersion := range apiVersions {
|
||||
ctx := genericapirequest.WithRequestInfo(genericapirequest.NewDefaultContext(), &genericapirequest.RequestInfo{
|
||||
APIGroup: "apps",
|
||||
APIVersion: apiVersion,
|
||||
})
|
||||
testCases := map[string]struct {
|
||||
input *apps.StatefulSet
|
||||
expectedErrs field.ErrorList
|
||||
}{
|
||||
"valid": {
|
||||
input: mkStatefulSet(),
|
||||
},
|
||||
"valid toleration key": {
|
||||
input: mkStatefulSet(api.Toleration{Key: "example.com/valid-key", Operator: api.TolerationOpExists}),
|
||||
},
|
||||
"valid toleration key without prefix": {
|
||||
input: mkStatefulSet(api.Toleration{Key: "simple-key", Operator: api.TolerationOpExists}),
|
||||
},
|
||||
"invalid toleration key format": {
|
||||
input: mkStatefulSet(api.Toleration{Key: "invalid key", Operator: api.TolerationOpExists}),
|
||||
expectedErrs: field.ErrorList{
|
||||
field.Invalid(field.NewPath("spec", "template", "spec", "tolerations").Index(0).Child("key"), nil, "").WithOrigin("format=k8s-label-key").MarkAlpha(),
|
||||
},
|
||||
},
|
||||
}
|
||||
for k, tc := range testCases {
|
||||
t.Run(k, func(t *testing.T) {
|
||||
apitesting.VerifyValidationEquivalence(t, ctx, tc.input, registry.Strategy, tc.expectedErrs)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
43
test/declarative_validation/apps/statefulset/zz_generated.validations.main_test.go
generated
Normal file
43
test/declarative_validation/apps/statefulset/zz_generated.validations.main_test.go
generated
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
//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 statefulset
|
||||
|
||||
import (
|
||||
fmt "fmt"
|
||||
os "os"
|
||||
testing "testing"
|
||||
|
||||
coverage "k8s.io/apimachinery/pkg/test/coverage"
|
||||
)
|
||||
|
||||
var apiVersions = []string{"v1", "v1beta1", "v1beta2"}
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
code := m.Run()
|
||||
if err := coverage.AssertDeclarativeCoverage(); err != nil {
|
||||
fmt.Fprintln(os.Stderr, err)
|
||||
if code == 0 {
|
||||
code = 1
|
||||
}
|
||||
}
|
||||
os.Exit(code)
|
||||
}
|
||||
38
test/declarative_validation/apps/statefulset/zz_generated.validations.v1_test.go
generated
Normal file
38
test/declarative_validation/apps/statefulset/zz_generated.validations.v1_test.go
generated
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
//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 statefulset
|
||||
|
||||
import (
|
||||
schema "k8s.io/apimachinery/pkg/runtime/schema"
|
||||
coverage "k8s.io/apimachinery/pkg/test/coverage"
|
||||
)
|
||||
|
||||
func init() {
|
||||
coverage.RegisterDeclaredRules(
|
||||
schema.GroupVersionKind{Group: "apps", Version: "v1", Kind: "StatefulSet"},
|
||||
coverage.FieldRules{
|
||||
"spec.template.spec.tolerations[*].key": {
|
||||
{ErrorType: "FieldValueInvalid", Origin: "format=k8s-label-key"},
|
||||
},
|
||||
},
|
||||
)
|
||||
}
|
||||
38
test/declarative_validation/apps/statefulset/zz_generated.validations.v1beta1_test.go
generated
Normal file
38
test/declarative_validation/apps/statefulset/zz_generated.validations.v1beta1_test.go
generated
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
//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 statefulset
|
||||
|
||||
import (
|
||||
schema "k8s.io/apimachinery/pkg/runtime/schema"
|
||||
coverage "k8s.io/apimachinery/pkg/test/coverage"
|
||||
)
|
||||
|
||||
func init() {
|
||||
coverage.RegisterDeclaredRules(
|
||||
schema.GroupVersionKind{Group: "apps", Version: "v1beta1", Kind: "StatefulSet"},
|
||||
coverage.FieldRules{
|
||||
"spec.template.spec.tolerations[*].key": {
|
||||
{ErrorType: "FieldValueInvalid", Origin: "format=k8s-label-key"},
|
||||
},
|
||||
},
|
||||
)
|
||||
}
|
||||
38
test/declarative_validation/apps/statefulset/zz_generated.validations.v1beta2_test.go
generated
Normal file
38
test/declarative_validation/apps/statefulset/zz_generated.validations.v1beta2_test.go
generated
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
//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 statefulset
|
||||
|
||||
import (
|
||||
schema "k8s.io/apimachinery/pkg/runtime/schema"
|
||||
coverage "k8s.io/apimachinery/pkg/test/coverage"
|
||||
)
|
||||
|
||||
func init() {
|
||||
coverage.RegisterDeclaredRules(
|
||||
schema.GroupVersionKind{Group: "apps", Version: "v1beta2", Kind: "StatefulSet"},
|
||||
coverage.FieldRules{
|
||||
"spec.template.spec.tolerations[*].key": {
|
||||
{ErrorType: "FieldValueInvalid", Origin: "format=k8s-label-key"},
|
||||
},
|
||||
},
|
||||
)
|
||||
}
|
||||
|
|
@ -61,7 +61,7 @@ func TestDeclarativeValidateUpdate(t *testing.T) {
|
|||
t.Run(k, func(t *testing.T) {
|
||||
tc.old.ResourceVersion = "1"
|
||||
tc.update.ResourceVersion = "1"
|
||||
apitesting.VerifyUpdateValidationEquivalenceFunc(t, ctx, &tc.update, &tc.old, validateScale, tc.expectedErrs, apitesting.WithSubResources("scale"))
|
||||
apitesting.VerifyUpdateValidationEquivalenceFunc(t, ctx, &tc.update, &tc.old, validateScale, tc.expectedErrs, apitesting.WithSubResources("scale"), apitesting.WithSkipGroupVersions("extensions/v1beta1"))
|
||||
})
|
||||
}
|
||||
})
|
||||
|
|
|
|||
|
|
@ -66,6 +66,18 @@ func testDeclarativeValidate(t *testing.T, apiVersion string) {
|
|||
tweakJobTemplateBackoffLimitPerIndex(ptr.To[int32](1)),
|
||||
),
|
||||
},
|
||||
"tolerations: valid key": {
|
||||
input: mkCronJob(tweakTolerations(api.Toleration{Key: "example.com/valid-key", Operator: api.TolerationOpExists})),
|
||||
},
|
||||
"tolerations: valid key without prefix": {
|
||||
input: mkCronJob(tweakTolerations(api.Toleration{Key: "simple-key", Operator: api.TolerationOpExists})),
|
||||
},
|
||||
"tolerations: invalid key format": {
|
||||
input: mkCronJob(tweakTolerations(api.Toleration{Key: "invalid key", Operator: api.TolerationOpExists})),
|
||||
expectedErrs: field.ErrorList{
|
||||
field.Invalid(field.NewPath("spec", "jobTemplate", "spec", "template", "spec", "tolerations").Index(0).Child("key"), nil, "").WithOrigin("format=k8s-label-key").MarkAlpha(),
|
||||
},
|
||||
},
|
||||
}
|
||||
for k, tc := range testCases {
|
||||
t.Run(k, func(t *testing.T) {
|
||||
|
|
@ -146,6 +158,12 @@ func tweakJobTemplateBackoffLimitPerIndex(v *int32) func(*batch.CronJob) {
|
|||
}
|
||||
}
|
||||
|
||||
func tweakTolerations(tolerations ...api.Toleration) func(*batch.CronJob) {
|
||||
return func(job *batch.CronJob) {
|
||||
job.Spec.JobTemplate.Spec.Template.Spec.Tolerations = tolerations
|
||||
}
|
||||
}
|
||||
|
||||
var validCronjobSpec = batch.CronJobSpec{
|
||||
Schedule: "5 5 * * ?",
|
||||
ConcurrencyPolicy: batch.AllowConcurrent,
|
||||
|
|
|
|||
|
|
@ -33,6 +33,9 @@ func init() {
|
|||
"spec.jobTemplate.spec.backoffLimitPerIndex": {
|
||||
{ErrorType: "FieldValueRequired", Origin: "dependentRequired"},
|
||||
},
|
||||
"spec.jobTemplate.spec.template.spec.tolerations[*].key": {
|
||||
{ErrorType: "FieldValueInvalid", Origin: "format=k8s-label-key"},
|
||||
},
|
||||
"spec.schedule": {
|
||||
{ErrorType: "FieldValueRequired"},
|
||||
},
|
||||
|
|
|
|||
|
|
@ -33,6 +33,9 @@ func init() {
|
|||
"spec.jobTemplate.spec.backoffLimitPerIndex": {
|
||||
{ErrorType: "FieldValueRequired", Origin: "dependentRequired"},
|
||||
},
|
||||
"spec.jobTemplate.spec.template.spec.tolerations[*].key": {
|
||||
{ErrorType: "FieldValueInvalid", Origin: "format=k8s-label-key"},
|
||||
},
|
||||
"spec.schedule": {
|
||||
{ErrorType: "FieldValueRequired"},
|
||||
},
|
||||
|
|
|
|||
|
|
@ -46,6 +46,9 @@ func testDeclarativeValidate(t *testing.T, apiVersion string) {
|
|||
input batch.Job
|
||||
expectedErrs field.ErrorList
|
||||
}{
|
||||
"valid": {
|
||||
input: mkJob(),
|
||||
},
|
||||
"maxFailedIndexes and backoffLimitPerIndex both set": {
|
||||
input: mkJob(
|
||||
tweakMaxFailedIndexes(ptr.To[int32](5)),
|
||||
|
|
@ -58,6 +61,18 @@ func testDeclarativeValidate(t *testing.T, apiVersion string) {
|
|||
field.Required(field.NewPath("spec", "backoffLimitPerIndex"), "").WithOrigin("dependentRequired").MarkAlpha(),
|
||||
},
|
||||
},
|
||||
"valid toleration key": {
|
||||
input: mkJob(tweakTolerations(api.Toleration{Key: "example.com/valid-key", Operator: api.TolerationOpExists})),
|
||||
},
|
||||
"valid toleration key without prefix": {
|
||||
input: mkJob(tweakTolerations(api.Toleration{Key: "simple-key", Operator: api.TolerationOpExists})),
|
||||
},
|
||||
"invalid toleration key format": {
|
||||
input: mkJob(tweakTolerations(api.Toleration{Key: "invalid key", Operator: api.TolerationOpExists})),
|
||||
expectedErrs: field.ErrorList{
|
||||
field.Invalid(field.NewPath("spec", "template", "spec", "tolerations").Index(0).Child("key"), nil, "").WithOrigin("format=k8s-label-key").MarkAlpha(),
|
||||
},
|
||||
},
|
||||
}
|
||||
for k, tc := range testCases {
|
||||
t.Run(k, func(t *testing.T) {
|
||||
|
|
@ -93,6 +108,12 @@ func tweakBackoffLimitPerIndex(v *int32) func(*batch.Job) {
|
|||
}
|
||||
}
|
||||
|
||||
func tweakTolerations(tolerations ...api.Toleration) func(*batch.Job) {
|
||||
return func(job *batch.Job) {
|
||||
job.Spec.Template.Spec.Tolerations = tolerations
|
||||
}
|
||||
}
|
||||
|
||||
var validJobLabels = map[string]string{
|
||||
batch.ControllerUidLabel: "1a2b3c",
|
||||
batch.LegacyControllerUidLabel: "1a2b3c",
|
||||
|
|
|
|||
|
|
@ -33,6 +33,9 @@ func init() {
|
|||
"spec.backoffLimitPerIndex": {
|
||||
{ErrorType: "FieldValueRequired", Origin: "dependentRequired"},
|
||||
},
|
||||
"spec.template.spec.tolerations[*].key": {
|
||||
{ErrorType: "FieldValueInvalid", Origin: "format=k8s-label-key"},
|
||||
},
|
||||
},
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,73 @@
|
|||
/*
|
||||
Copyright 2025 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 pod
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"k8s.io/apimachinery/pkg/util/validation/field"
|
||||
genericapirequest "k8s.io/apiserver/pkg/endpoints/request"
|
||||
podtest "k8s.io/kubernetes/pkg/api/pod/testing"
|
||||
apitesting "k8s.io/kubernetes/pkg/api/testing"
|
||||
api "k8s.io/kubernetes/pkg/apis/core"
|
||||
registry "k8s.io/kubernetes/pkg/registry/core/pod"
|
||||
)
|
||||
|
||||
func TestDeclarativeValidate(t *testing.T) {
|
||||
for _, apiVersion := range apiVersions {
|
||||
ctx := genericapirequest.WithRequestInfo(genericapirequest.NewDefaultContext(), &genericapirequest.RequestInfo{
|
||||
APIGroup: "",
|
||||
APIVersion: apiVersion,
|
||||
})
|
||||
testCases := map[string]struct {
|
||||
input *api.Pod
|
||||
expectedErrs field.ErrorList
|
||||
}{
|
||||
"valid": {
|
||||
input: podtest.MakePod("foo"),
|
||||
},
|
||||
"valid toleration key": {
|
||||
input: podtest.MakePod("foo", podtest.SetTolerations(
|
||||
api.Toleration{Key: "example.com/valid-key", Operator: api.TolerationOpExists},
|
||||
)),
|
||||
},
|
||||
"valid toleration key without prefix": {
|
||||
input: podtest.MakePod("foo", podtest.SetTolerations(
|
||||
api.Toleration{Key: "simple-key", Operator: api.TolerationOpExists},
|
||||
)),
|
||||
},
|
||||
"empty toleration key (match all, skipped)": {
|
||||
input: podtest.MakePod("foo", podtest.SetTolerations(
|
||||
api.Toleration{Operator: api.TolerationOpExists},
|
||||
)),
|
||||
},
|
||||
"invalid toleration key format": {
|
||||
input: podtest.MakePod("foo", podtest.SetTolerations(
|
||||
api.Toleration{Key: "invalid key", Operator: api.TolerationOpExists},
|
||||
)),
|
||||
expectedErrs: field.ErrorList{
|
||||
field.Invalid(field.NewPath("spec", "tolerations").Index(0).Child("key"), nil, "").WithOrigin("format=k8s-label-key").MarkAlpha(),
|
||||
},
|
||||
},
|
||||
}
|
||||
for k, tc := range testCases {
|
||||
t.Run(k, func(t *testing.T) {
|
||||
apitesting.VerifyValidationEquivalence(t, ctx, tc.input, registry.Strategy, tc.expectedErrs)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
43
test/declarative_validation/core/pod/zz_generated.validations.main_test.go
generated
Normal file
43
test/declarative_validation/core/pod/zz_generated.validations.main_test.go
generated
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
//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 pod
|
||||
|
||||
import (
|
||||
fmt "fmt"
|
||||
os "os"
|
||||
testing "testing"
|
||||
|
||||
coverage "k8s.io/apimachinery/pkg/test/coverage"
|
||||
)
|
||||
|
||||
var apiVersions = []string{"v1"}
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
code := m.Run()
|
||||
if err := coverage.AssertDeclarativeCoverage(); err != nil {
|
||||
fmt.Fprintln(os.Stderr, err)
|
||||
if code == 0 {
|
||||
code = 1
|
||||
}
|
||||
}
|
||||
os.Exit(code)
|
||||
}
|
||||
38
test/declarative_validation/core/pod/zz_generated.validations.v1_test.go
generated
Normal file
38
test/declarative_validation/core/pod/zz_generated.validations.v1_test.go
generated
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
//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 pod
|
||||
|
||||
import (
|
||||
schema "k8s.io/apimachinery/pkg/runtime/schema"
|
||||
coverage "k8s.io/apimachinery/pkg/test/coverage"
|
||||
)
|
||||
|
||||
func init() {
|
||||
coverage.RegisterDeclaredRules(
|
||||
schema.GroupVersionKind{Group: "", Version: "v1", Kind: "Pod"},
|
||||
coverage.FieldRules{
|
||||
"spec.tolerations[*].key": {
|
||||
{ErrorType: "FieldValueInvalid", Origin: "format=k8s-label-key"},
|
||||
},
|
||||
},
|
||||
)
|
||||
}
|
||||
|
|
@ -0,0 +1,73 @@
|
|||
/*
|
||||
Copyright 2025 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 podtemplate
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/util/validation/field"
|
||||
genericapirequest "k8s.io/apiserver/pkg/endpoints/request"
|
||||
podtest "k8s.io/kubernetes/pkg/api/pod/testing"
|
||||
apitesting "k8s.io/kubernetes/pkg/api/testing"
|
||||
api "k8s.io/kubernetes/pkg/apis/core"
|
||||
registry "k8s.io/kubernetes/pkg/registry/core/podtemplate"
|
||||
)
|
||||
|
||||
func mkPodTemplate(tolerations ...api.Toleration) *api.PodTemplate {
|
||||
return &api.PodTemplate{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "foo", Namespace: metav1.NamespaceDefault},
|
||||
Template: api.PodTemplateSpec{
|
||||
ObjectMeta: metav1.ObjectMeta{Labels: map[string]string{"a": "b"}},
|
||||
Spec: podtest.MakePodSpec(podtest.SetTolerations(tolerations...)),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func TestDeclarativeValidate(t *testing.T) {
|
||||
for _, apiVersion := range apiVersions {
|
||||
ctx := genericapirequest.WithRequestInfo(genericapirequest.NewDefaultContext(), &genericapirequest.RequestInfo{
|
||||
APIGroup: "",
|
||||
APIVersion: apiVersion,
|
||||
})
|
||||
testCases := map[string]struct {
|
||||
input *api.PodTemplate
|
||||
expectedErrs field.ErrorList
|
||||
}{
|
||||
"valid": {
|
||||
input: mkPodTemplate(),
|
||||
},
|
||||
"valid toleration key": {
|
||||
input: mkPodTemplate(api.Toleration{Key: "example.com/valid-key", Operator: api.TolerationOpExists}),
|
||||
},
|
||||
"valid toleration key without prefix": {
|
||||
input: mkPodTemplate(api.Toleration{Key: "simple-key", Operator: api.TolerationOpExists}),
|
||||
},
|
||||
"invalid toleration key format": {
|
||||
input: mkPodTemplate(api.Toleration{Key: "invalid key", Operator: api.TolerationOpExists}),
|
||||
expectedErrs: field.ErrorList{
|
||||
field.Invalid(field.NewPath("template", "spec", "tolerations").Index(0).Child("key"), nil, "").WithOrigin("format=k8s-label-key").MarkAlpha(),
|
||||
},
|
||||
},
|
||||
}
|
||||
for k, tc := range testCases {
|
||||
t.Run(k, func(t *testing.T) {
|
||||
apitesting.VerifyValidationEquivalence(t, ctx, tc.input, registry.Strategy, tc.expectedErrs)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
43
test/declarative_validation/core/podtemplate/zz_generated.validations.main_test.go
generated
Normal file
43
test/declarative_validation/core/podtemplate/zz_generated.validations.main_test.go
generated
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
//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 podtemplate
|
||||
|
||||
import (
|
||||
fmt "fmt"
|
||||
os "os"
|
||||
testing "testing"
|
||||
|
||||
coverage "k8s.io/apimachinery/pkg/test/coverage"
|
||||
)
|
||||
|
||||
var apiVersions = []string{"v1"}
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
code := m.Run()
|
||||
if err := coverage.AssertDeclarativeCoverage(); err != nil {
|
||||
fmt.Fprintln(os.Stderr, err)
|
||||
if code == 0 {
|
||||
code = 1
|
||||
}
|
||||
}
|
||||
os.Exit(code)
|
||||
}
|
||||
38
test/declarative_validation/core/podtemplate/zz_generated.validations.v1_test.go
generated
Normal file
38
test/declarative_validation/core/podtemplate/zz_generated.validations.v1_test.go
generated
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
//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 podtemplate
|
||||
|
||||
import (
|
||||
schema "k8s.io/apimachinery/pkg/runtime/schema"
|
||||
coverage "k8s.io/apimachinery/pkg/test/coverage"
|
||||
)
|
||||
|
||||
func init() {
|
||||
coverage.RegisterDeclaredRules(
|
||||
schema.GroupVersionKind{Group: "", Version: "v1", Kind: "PodTemplate"},
|
||||
coverage.FieldRules{
|
||||
"template.spec.tolerations[*].key": {
|
||||
{ErrorType: "FieldValueInvalid", Origin: "format=k8s-label-key"},
|
||||
},
|
||||
},
|
||||
)
|
||||
}
|
||||
|
|
@ -187,6 +187,19 @@ func TestDeclarativeValidate(t *testing.T) {
|
|||
field.Invalid(field.NewPath("spec.minReadySeconds"), nil, "").WithOrigin("minimum").MarkAlpha(),
|
||||
},
|
||||
},
|
||||
// spec.template.spec.tolerations[*].key
|
||||
"tolerations: valid key": {
|
||||
input: mkValidReplicationController(setSpecTolerations(api.Toleration{Key: "example.com/valid-key", Operator: api.TolerationOpExists})),
|
||||
},
|
||||
"tolerations: valid key without prefix": {
|
||||
input: mkValidReplicationController(setSpecTolerations(api.Toleration{Key: "simple-key", Operator: api.TolerationOpExists})),
|
||||
},
|
||||
"tolerations: invalid key format": {
|
||||
input: mkValidReplicationController(setSpecTolerations(api.Toleration{Key: "invalid key", Operator: api.TolerationOpExists})),
|
||||
expectedErrs: field.ErrorList{
|
||||
field.Invalid(field.NewPath("spec.template.spec.tolerations").Index(0).Child("key"), nil, "").WithOrigin("format=k8s-label-key").MarkAlpha(),
|
||||
},
|
||||
},
|
||||
}
|
||||
for k, tc := range testCases {
|
||||
t.Run(k, func(t *testing.T) {
|
||||
|
|
@ -313,3 +326,9 @@ func setSpecMinReadySeconds(val int32) func(rc *api.ReplicationController) {
|
|||
rc.Spec.MinReadySeconds = val
|
||||
}
|
||||
}
|
||||
|
||||
func setSpecTolerations(tolerations ...api.Toleration) func(rc *api.ReplicationController) {
|
||||
return func(rc *api.ReplicationController) {
|
||||
rc.Spec.Template.Spec.Tolerations = tolerations
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -40,6 +40,9 @@ func init() {
|
|||
{ErrorType: "FieldValueInvalid", Origin: "minimum"},
|
||||
{ErrorType: "FieldValueRequired"},
|
||||
},
|
||||
"spec.template.spec.tolerations[*].key": {
|
||||
{ErrorType: "FieldValueInvalid", Origin: "format=k8s-label-key"},
|
||||
},
|
||||
},
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -80,6 +80,9 @@ func TestDeclarativeValidateIPBlockCIDR(t *testing.T) {
|
|||
&tc.input,
|
||||
registry.Strategy,
|
||||
tc.expectedErrs,
|
||||
// extensions/v1beta1 is unserved and no longer carries
|
||||
// declarative validation; skip it in the version sweep.
|
||||
apitesting.WithSkipGroupVersions("extensions/v1beta1"),
|
||||
)
|
||||
})
|
||||
}
|
||||
|
|
@ -148,6 +151,9 @@ func TestDeclarativeValidateIPBlockCIDRUpdate(t *testing.T) {
|
|||
&tc.oldObj,
|
||||
registry.Strategy,
|
||||
tc.expectedErrs,
|
||||
// extensions/v1beta1 is unserved and no longer carries
|
||||
// declarative validation; skip it in the version sweep.
|
||||
apitesting.WithSkipGroupVersions("extensions/v1beta1"),
|
||||
)
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ import (
|
|||
"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/core"
|
||||
node "k8s.io/kubernetes/pkg/apis/node"
|
||||
"k8s.io/kubernetes/pkg/apis/node/validation"
|
||||
registry "k8s.io/kubernetes/pkg/registry/node/runtimeclass"
|
||||
|
|
@ -97,6 +98,32 @@ func TestRuntimeClass_DeclarativeValidate_Create(t *testing.T) {
|
|||
"", "").WithOrigin("format=k8s-short-name").MarkAlpha(),
|
||||
},
|
||||
},
|
||||
"scheduling toleration with valid key": {
|
||||
obj: mkRuntimeClassHandlerOnly(func(rc *node.RuntimeClass) {
|
||||
rc.Scheduling = &node.Scheduling{
|
||||
Tolerations: []api.Toleration{{Key: "example.com/valid-key", Operator: api.TolerationOpExists}},
|
||||
}
|
||||
}),
|
||||
expectedErrs: field.ErrorList{},
|
||||
},
|
||||
"scheduling toleration with valid key without prefix": {
|
||||
obj: mkRuntimeClassHandlerOnly(func(rc *node.RuntimeClass) {
|
||||
rc.Scheduling = &node.Scheduling{
|
||||
Tolerations: []api.Toleration{{Key: "simple-key", Operator: api.TolerationOpExists}},
|
||||
}
|
||||
}),
|
||||
expectedErrs: field.ErrorList{},
|
||||
},
|
||||
"scheduling toleration with invalid key format": {
|
||||
obj: mkRuntimeClassHandlerOnly(func(rc *node.RuntimeClass) {
|
||||
rc.Scheduling = &node.Scheduling{
|
||||
Tolerations: []api.Toleration{{Key: "invalid key", Operator: api.TolerationOpExists}},
|
||||
}
|
||||
}),
|
||||
expectedErrs: field.ErrorList{
|
||||
field.Invalid(field.NewPath("scheduling", "tolerations").Index(0).Child("key"), nil, "").WithOrigin("format=k8s-label-key").MarkAlpha(),
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for name, tc := range tests {
|
||||
|
|
|
|||
|
|
@ -35,6 +35,9 @@ func init() {
|
|||
{ErrorType: "FieldValueInvalid", Origin: "immutable"},
|
||||
{ErrorType: "FieldValueRequired"},
|
||||
},
|
||||
"scheduling.tolerations[*].key": {
|
||||
{ErrorType: "FieldValueInvalid", Origin: "format=k8s-label-key"},
|
||||
},
|
||||
},
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -35,6 +35,9 @@ func init() {
|
|||
{ErrorType: "FieldValueInvalid", Origin: "immutable"},
|
||||
{ErrorType: "FieldValueRequired"},
|
||||
},
|
||||
"spec.scheduling.tolerations[*].key": {
|
||||
{ErrorType: "FieldValueInvalid", Origin: "format=k8s-label-key"},
|
||||
},
|
||||
},
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -35,6 +35,9 @@ func init() {
|
|||
{ErrorType: "FieldValueInvalid", Origin: "immutable"},
|
||||
{ErrorType: "FieldValueRequired"},
|
||||
},
|
||||
"scheduling.tolerations[*].key": {
|
||||
{ErrorType: "FieldValueInvalid", Origin: "format=k8s-label-key"},
|
||||
},
|
||||
},
|
||||
)
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue