Call conditional validation from create/update strategies

pull/564/head
Jordan Liggitt 2019-02-05 21:57:16 -05:00
parent 34ac165a44
commit 4271384966
18 changed files with 87 additions and 22 deletions

View File

@ -18,6 +18,7 @@ go_library(
"//pkg/api/pod:go_default_library",
"//pkg/apis/apps:go_default_library",
"//pkg/apis/apps/validation:go_default_library",
"//pkg/apis/core/validation:go_default_library",
"//staging/src/k8s.io/api/apps/v1beta2:go_default_library",
"//staging/src/k8s.io/api/extensions/v1beta1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/api/equality:go_default_library",

View File

@ -33,6 +33,7 @@ import (
"k8s.io/kubernetes/pkg/api/pod"
"k8s.io/kubernetes/pkg/apis/apps"
"k8s.io/kubernetes/pkg/apis/apps/validation"
corevalidation "k8s.io/kubernetes/pkg/apis/core/validation"
)
// daemonSetStrategy implements verification logic for daemon sets.
@ -115,7 +116,9 @@ func (daemonSetStrategy) PrepareForUpdate(ctx context.Context, obj, old runtime.
// Validate validates a new daemon set.
func (daemonSetStrategy) Validate(ctx context.Context, obj runtime.Object) field.ErrorList {
daemonSet := obj.(*apps.DaemonSet)
return validation.ValidateDaemonSet(daemonSet)
allErrs := validation.ValidateDaemonSet(daemonSet)
allErrs = append(allErrs, corevalidation.ValidateConditionalPodTemplate(&daemonSet.Spec.Template, nil, field.NewPath("spec.template"))...)
return allErrs
}
// Canonicalize normalizes the object after validation.
@ -134,6 +137,7 @@ func (daemonSetStrategy) ValidateUpdate(ctx context.Context, obj, old runtime.Ob
oldDaemonSet := old.(*apps.DaemonSet)
allErrs := validation.ValidateDaemonSet(obj.(*apps.DaemonSet))
allErrs = append(allErrs, validation.ValidateDaemonSetUpdate(newDaemonSet, oldDaemonSet)...)
allErrs = append(allErrs, corevalidation.ValidateConditionalPodTemplate(&newDaemonSet.Spec.Template, &oldDaemonSet.Spec.Template, field.NewPath("spec.template"))...)
// Update is not allowed to set Spec.Selector for apps/v1 and apps/v1beta2 (allowed for extensions/v1beta1).
// If RequestInfo is nil, it is better to revert to old behavior (i.e. allow update to set Spec.Selector)

View File

@ -18,6 +18,7 @@ go_library(
"//pkg/api/pod:go_default_library",
"//pkg/apis/apps:go_default_library",
"//pkg/apis/apps/validation:go_default_library",
"//pkg/apis/core/validation:go_default_library",
"//staging/src/k8s.io/api/apps/v1beta1:go_default_library",
"//staging/src/k8s.io/api/apps/v1beta2:go_default_library",
"//staging/src/k8s.io/api/extensions/v1beta1:go_default_library",

View File

@ -34,6 +34,7 @@ import (
"k8s.io/kubernetes/pkg/api/pod"
"k8s.io/kubernetes/pkg/apis/apps"
"k8s.io/kubernetes/pkg/apis/apps/validation"
corevalidation "k8s.io/kubernetes/pkg/apis/core/validation"
)
// deploymentStrategy implements behavior for Deployments.
@ -79,7 +80,9 @@ func (deploymentStrategy) PrepareForCreate(ctx context.Context, obj runtime.Obje
// Validate validates a new deployment.
func (deploymentStrategy) Validate(ctx context.Context, obj runtime.Object) field.ErrorList {
deployment := obj.(*apps.Deployment)
return validation.ValidateDeployment(deployment)
allErrs := validation.ValidateDeployment(deployment)
allErrs = append(allErrs, corevalidation.ValidateConditionalPodTemplate(&deployment.Spec.Template, nil, field.NewPath("spec.template"))...)
return allErrs
}
// Canonicalize normalizes the object after validation.
@ -113,6 +116,7 @@ func (deploymentStrategy) ValidateUpdate(ctx context.Context, obj, old runtime.O
newDeployment := obj.(*apps.Deployment)
oldDeployment := old.(*apps.Deployment)
allErrs := validation.ValidateDeploymentUpdate(newDeployment, oldDeployment)
allErrs = append(allErrs, corevalidation.ValidateConditionalPodTemplate(&newDeployment.Spec.Template, &oldDeployment.Spec.Template, field.NewPath("spec.template"))...)
// Update is not allowed to set Spec.Selector for all groups/versions except extensions/v1beta1.
// If RequestInfo is nil, it is better to revert to old behavior (i.e. allow update to set Spec.Selector)

View File

@ -18,6 +18,7 @@ go_library(
"//pkg/api/pod:go_default_library",
"//pkg/apis/apps:go_default_library",
"//pkg/apis/apps/validation:go_default_library",
"//pkg/apis/core/validation:go_default_library",
"//staging/src/k8s.io/api/apps/v1beta2:go_default_library",
"//staging/src/k8s.io/api/extensions/v1beta1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/api/equality:go_default_library",

View File

@ -41,6 +41,7 @@ import (
"k8s.io/kubernetes/pkg/api/pod"
"k8s.io/kubernetes/pkg/apis/apps"
"k8s.io/kubernetes/pkg/apis/apps/validation"
corevalidation "k8s.io/kubernetes/pkg/apis/core/validation"
)
// rsStrategy implements verification logic for ReplicaSets.
@ -108,7 +109,9 @@ func (rsStrategy) PrepareForUpdate(ctx context.Context, obj, old runtime.Object)
// Validate validates a new ReplicaSet.
func (rsStrategy) Validate(ctx context.Context, obj runtime.Object) field.ErrorList {
rs := obj.(*apps.ReplicaSet)
return validation.ValidateReplicaSet(rs)
allErrs := validation.ValidateReplicaSet(rs)
allErrs = append(allErrs, corevalidation.ValidateConditionalPodTemplate(&rs.Spec.Template, nil, field.NewPath("spec.template"))...)
return allErrs
}
// Canonicalize normalizes the object after validation.
@ -127,6 +130,7 @@ func (rsStrategy) ValidateUpdate(ctx context.Context, obj, old runtime.Object) f
oldReplicaSet := old.(*apps.ReplicaSet)
allErrs := validation.ValidateReplicaSet(obj.(*apps.ReplicaSet))
allErrs = append(allErrs, validation.ValidateReplicaSetUpdate(newReplicaSet, oldReplicaSet)...)
allErrs = append(allErrs, corevalidation.ValidateConditionalPodTemplate(&newReplicaSet.Spec.Template, &oldReplicaSet.Spec.Template, field.NewPath("spec.template"))...)
// Update is not allowed to set Spec.Selector for all groups/versions except extensions/v1beta1.
// If RequestInfo is nil, it is better to revert to old behavior (i.e. allow update to set Spec.Selector)

View File

@ -18,6 +18,7 @@ go_library(
"//pkg/api/pod:go_default_library",
"//pkg/apis/apps:go_default_library",
"//pkg/apis/apps/validation:go_default_library",
"//pkg/apis/core/validation:go_default_library",
"//staging/src/k8s.io/api/apps/v1beta1:go_default_library",
"//staging/src/k8s.io/api/apps/v1beta2:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/api/equality:go_default_library",

View File

@ -32,6 +32,7 @@ import (
"k8s.io/kubernetes/pkg/api/pod"
"k8s.io/kubernetes/pkg/apis/apps"
"k8s.io/kubernetes/pkg/apis/apps/validation"
corevalidation "k8s.io/kubernetes/pkg/apis/core/validation"
)
// statefulSetStrategy implements verification logic for Replication StatefulSets.
@ -96,7 +97,9 @@ func (statefulSetStrategy) PrepareForUpdate(ctx context.Context, obj, old runtim
// Validate validates a new StatefulSet.
func (statefulSetStrategy) Validate(ctx context.Context, obj runtime.Object) field.ErrorList {
statefulSet := obj.(*apps.StatefulSet)
return validation.ValidateStatefulSet(statefulSet)
allErrs := validation.ValidateStatefulSet(statefulSet)
allErrs = append(allErrs, corevalidation.ValidateConditionalPodTemplate(&statefulSet.Spec.Template, nil, field.NewPath("spec.template"))...)
return allErrs
}
// Canonicalize normalizes the object after validation.
@ -110,8 +113,11 @@ func (statefulSetStrategy) AllowCreateOnUpdate() bool {
// ValidateUpdate is the default update validation for an end user.
func (statefulSetStrategy) ValidateUpdate(ctx context.Context, obj, old runtime.Object) field.ErrorList {
validationErrorList := validation.ValidateStatefulSet(obj.(*apps.StatefulSet))
updateErrorList := validation.ValidateStatefulSetUpdate(obj.(*apps.StatefulSet), old.(*apps.StatefulSet))
newStatefulSet := obj.(*apps.StatefulSet)
oldStatefulSet := old.(*apps.StatefulSet)
validationErrorList := validation.ValidateStatefulSet(newStatefulSet)
updateErrorList := validation.ValidateStatefulSetUpdate(newStatefulSet, oldStatefulSet)
updateErrorList = append(updateErrorList, corevalidation.ValidateConditionalPodTemplate(&newStatefulSet.Spec.Template, &oldStatefulSet.Spec.Template, field.NewPath("spec.template"))...)
return append(validationErrorList, updateErrorList...)
}

View File

@ -18,6 +18,7 @@ go_library(
"//pkg/api/pod:go_default_library",
"//pkg/apis/batch:go_default_library",
"//pkg/apis/batch/validation:go_default_library",
"//pkg/apis/core/validation:go_default_library",
"//staging/src/k8s.io/api/batch/v1beta1:go_default_library",
"//staging/src/k8s.io/api/batch/v2alpha1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",

View File

@ -31,6 +31,7 @@ import (
"k8s.io/kubernetes/pkg/api/pod"
"k8s.io/kubernetes/pkg/apis/batch"
"k8s.io/kubernetes/pkg/apis/batch/validation"
corevalidation "k8s.io/kubernetes/pkg/apis/core/validation"
)
// cronJobStrategy implements verification logic for Replication Controllers.
@ -83,7 +84,9 @@ func (cronJobStrategy) PrepareForUpdate(ctx context.Context, obj, old runtime.Ob
// Validate validates a new scheduled job.
func (cronJobStrategy) Validate(ctx context.Context, obj runtime.Object) field.ErrorList {
cronJob := obj.(*batch.CronJob)
return validation.ValidateCronJob(cronJob)
allErrs := validation.ValidateCronJob(cronJob)
allErrs = append(allErrs, corevalidation.ValidateConditionalPodTemplate(&cronJob.Spec.JobTemplate.Spec.Template, nil, field.NewPath("spec.jobTemplate.spec.template"))...)
return allErrs
}
// Canonicalize normalizes the object after validation.
@ -101,7 +104,14 @@ func (cronJobStrategy) AllowCreateOnUpdate() bool {
// ValidateUpdate is the default update validation for an end user.
func (cronJobStrategy) ValidateUpdate(ctx context.Context, obj, old runtime.Object) field.ErrorList {
return validation.ValidateCronJobUpdate(obj.(*batch.CronJob), old.(*batch.CronJob))
newCronJob := obj.(*batch.CronJob)
oldCronJob := old.(*batch.CronJob)
allErrs := validation.ValidateCronJobUpdate(newCronJob, oldCronJob)
allErrs = append(allErrs, corevalidation.ValidateConditionalPodTemplate(
&newCronJob.Spec.JobTemplate.Spec.Template,
&oldCronJob.Spec.JobTemplate.Spec.Template,
field.NewPath("spec.jobTemplate.spec.template"))...)
return allErrs
}
type cronJobStatusStrategy struct {

View File

@ -18,6 +18,7 @@ go_library(
"//pkg/api/pod:go_default_library",
"//pkg/apis/batch:go_default_library",
"//pkg/apis/batch/validation:go_default_library",
"//pkg/apis/core/validation:go_default_library",
"//pkg/features:go_default_library",
"//staging/src/k8s.io/api/batch/v1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",

View File

@ -38,6 +38,7 @@ import (
"k8s.io/kubernetes/pkg/api/pod"
"k8s.io/kubernetes/pkg/apis/batch"
"k8s.io/kubernetes/pkg/apis/batch/validation"
corevalidation "k8s.io/kubernetes/pkg/apis/core/validation"
"k8s.io/kubernetes/pkg/features"
)
@ -103,7 +104,9 @@ func (jobStrategy) Validate(ctx context.Context, obj runtime.Object) field.Error
if job.Spec.ManualSelector == nil || *job.Spec.ManualSelector == false {
generateSelector(job)
}
return validation.ValidateJob(job)
allErrs := validation.ValidateJob(job)
allErrs = append(allErrs, corevalidation.ValidateConditionalPodTemplate(&job.Spec.Template, nil, field.NewPath("spec.template"))...)
return allErrs
}
// generateSelector adds a selector to a job and labels to its template
@ -171,8 +174,11 @@ func (jobStrategy) AllowCreateOnUpdate() bool {
// ValidateUpdate is the default update validation for an end user.
func (jobStrategy) ValidateUpdate(ctx context.Context, obj, old runtime.Object) field.ErrorList {
validationErrorList := validation.ValidateJob(obj.(*batch.Job))
updateErrorList := validation.ValidateJobUpdate(obj.(*batch.Job), old.(*batch.Job))
job := obj.(*batch.Job)
oldJob := old.(*batch.Job)
validationErrorList := validation.ValidateJob(job)
updateErrorList := validation.ValidateJobUpdate(job, oldJob)
updateErrorList = append(updateErrorList, corevalidation.ValidateConditionalPodTemplate(&job.Spec.Template, &oldJob.Spec.Template, field.NewPath("spec.template"))...)
return append(validationErrorList, updateErrorList...)
}

View File

@ -53,7 +53,9 @@ func (endpointsStrategy) PrepareForUpdate(ctx context.Context, obj, old runtime.
// Validate validates a new endpoints.
func (endpointsStrategy) Validate(ctx context.Context, obj runtime.Object) field.ErrorList {
return validation.ValidateEndpoints(obj.(*api.Endpoints))
allErrs := validation.ValidateEndpoints(obj.(*api.Endpoints))
allErrs = append(allErrs, validation.ValidateConditionalEndpoints(obj.(*api.Endpoints), nil)...)
return allErrs
}
// Canonicalize normalizes the object after validation.
@ -70,7 +72,9 @@ func (endpointsStrategy) AllowCreateOnUpdate() bool {
// ValidateUpdate is the default update validation for an end user.
func (endpointsStrategy) ValidateUpdate(ctx context.Context, obj, old runtime.Object) field.ErrorList {
errorList := validation.ValidateEndpoints(obj.(*api.Endpoints))
return append(errorList, validation.ValidateEndpointsUpdate(obj.(*api.Endpoints), old.(*api.Endpoints))...)
errorList = append(errorList, validation.ValidateEndpointsUpdate(obj.(*api.Endpoints), old.(*api.Endpoints))...)
errorList = append(errorList, validation.ValidateConditionalEndpoints(obj.(*api.Endpoints), old.(*api.Endpoints))...)
return errorList
}
func (endpointsStrategy) AllowUnconditionalUpdate() bool {

View File

@ -84,7 +84,9 @@ func (podStrategy) PrepareForUpdate(ctx context.Context, obj, old runtime.Object
// Validate validates a new pod.
func (podStrategy) Validate(ctx context.Context, obj runtime.Object) field.ErrorList {
pod := obj.(*api.Pod)
return validation.ValidatePod(pod)
allErrs := validation.ValidatePod(pod)
allErrs = append(allErrs, validation.ValidateConditionalPod(pod, nil, field.NewPath(""))...)
return allErrs
}
// Canonicalize normalizes the object after validation.
@ -99,7 +101,9 @@ func (podStrategy) AllowCreateOnUpdate() bool {
// ValidateUpdate is the default update validation for an end user.
func (podStrategy) ValidateUpdate(ctx context.Context, obj, old runtime.Object) field.ErrorList {
errorList := validation.ValidatePod(obj.(*api.Pod))
return append(errorList, validation.ValidatePodUpdate(obj.(*api.Pod), old.(*api.Pod))...)
errorList = append(errorList, validation.ValidatePodUpdate(obj.(*api.Pod), old.(*api.Pod))...)
errorList = append(errorList, validation.ValidateConditionalPod(obj.(*api.Pod), old.(*api.Pod), field.NewPath(""))...)
return errorList
}
// AllowUnconditionalUpdate allows pods to be overwritten

View File

@ -26,6 +26,7 @@ import (
"k8s.io/kubernetes/pkg/api/pod"
api "k8s.io/kubernetes/pkg/apis/core"
"k8s.io/kubernetes/pkg/apis/core/validation"
corevalidation "k8s.io/kubernetes/pkg/apis/core/validation"
)
// podTemplateStrategy implements behavior for PodTemplates
@ -52,8 +53,10 @@ func (podTemplateStrategy) PrepareForCreate(ctx context.Context, obj runtime.Obj
// Validate validates a new pod template.
func (podTemplateStrategy) Validate(ctx context.Context, obj runtime.Object) field.ErrorList {
pod := obj.(*api.PodTemplate)
return validation.ValidatePodTemplate(pod)
template := obj.(*api.PodTemplate)
allErrs := validation.ValidatePodTemplate(template)
allErrs = append(allErrs, corevalidation.ValidateConditionalPodTemplate(&template.Template, nil, field.NewPath("template"))...)
return allErrs
}
// Canonicalize normalizes the object after validation.
@ -75,7 +78,11 @@ func (podTemplateStrategy) PrepareForUpdate(ctx context.Context, obj, old runtim
// ValidateUpdate is the default update validation for an end user.
func (podTemplateStrategy) ValidateUpdate(ctx context.Context, obj, old runtime.Object) field.ErrorList {
return validation.ValidatePodTemplateUpdate(obj.(*api.PodTemplate), old.(*api.PodTemplate))
template := obj.(*api.PodTemplate)
oldTemplate := old.(*api.PodTemplate)
allErrs := validation.ValidatePodTemplateUpdate(template, oldTemplate)
allErrs = append(allErrs, corevalidation.ValidateConditionalPodTemplate(&template.Template, &oldTemplate.Template, field.NewPath("template"))...)
return allErrs
}
func (podTemplateStrategy) AllowUnconditionalUpdate() bool {

View File

@ -108,7 +108,9 @@ func (rcStrategy) PrepareForUpdate(ctx context.Context, obj, old runtime.Object)
// Validate validates a new replication controller.
func (rcStrategy) Validate(ctx context.Context, obj runtime.Object) field.ErrorList {
controller := obj.(*api.ReplicationController)
return validation.ValidateReplicationController(controller)
allErrs := validation.ValidateReplicationController(controller)
allErrs = append(allErrs, validation.ValidateConditionalPodTemplate(controller.Spec.Template, nil, field.NewPath("spec.template"))...)
return allErrs
}
// Canonicalize normalizes the object after validation.
@ -128,6 +130,7 @@ func (rcStrategy) ValidateUpdate(ctx context.Context, obj, old runtime.Object) f
validationErrorList := validation.ValidateReplicationController(newRc)
updateErrorList := validation.ValidateReplicationControllerUpdate(newRc, oldRc)
updateErrorList = append(updateErrorList, validation.ValidateConditionalPodTemplate(newRc.Spec.Template, oldRc.Spec.Template, field.NewPath("spec.template"))...)
errs := append(validationErrorList, updateErrorList...)
for key, value := range helper.NonConvertibleFields(oldRc.Annotations) {

View File

@ -59,7 +59,9 @@ func (svcStrategy) PrepareForUpdate(ctx context.Context, obj, old runtime.Object
// Validate validates a new service.
func (svcStrategy) Validate(ctx context.Context, obj runtime.Object) field.ErrorList {
service := obj.(*api.Service)
return validation.ValidateService(service)
allErrs := validation.ValidateService(service)
allErrs = append(allErrs, validation.ValidateConditionalService(service, nil)...)
return allErrs
}
// Canonicalize normalizes the object after validation.
@ -71,7 +73,9 @@ func (svcStrategy) AllowCreateOnUpdate() bool {
}
func (svcStrategy) ValidateUpdate(ctx context.Context, obj, old runtime.Object) field.ErrorList {
return validation.ValidateServiceUpdate(obj.(*api.Service), old.(*api.Service))
allErrs := validation.ValidateServiceUpdate(obj.(*api.Service), old.(*api.Service))
allErrs = append(allErrs, validation.ValidateConditionalService(obj.(*api.Service), old.(*api.Service))...)
return allErrs
}
func (svcStrategy) AllowUnconditionalUpdate() bool {

View File

@ -64,7 +64,9 @@ func (networkPolicyStrategy) PrepareForUpdate(ctx context.Context, obj, old runt
// Validate validates a new NetworkPolicy.
func (networkPolicyStrategy) Validate(ctx context.Context, obj runtime.Object) field.ErrorList {
networkPolicy := obj.(*networking.NetworkPolicy)
return validation.ValidateNetworkPolicy(networkPolicy)
allErrs := validation.ValidateNetworkPolicy(networkPolicy)
allErrs = append(allErrs, validation.ValidateConditionalNetworkPolicy(networkPolicy, nil)...)
return allErrs
}
// Canonicalize normalizes the object after validation.
@ -79,6 +81,7 @@ func (networkPolicyStrategy) AllowCreateOnUpdate() bool {
func (networkPolicyStrategy) ValidateUpdate(ctx context.Context, obj, old runtime.Object) field.ErrorList {
validationErrorList := validation.ValidateNetworkPolicy(obj.(*networking.NetworkPolicy))
updateErrorList := validation.ValidateNetworkPolicyUpdate(obj.(*networking.NetworkPolicy), old.(*networking.NetworkPolicy))
updateErrorList = append(updateErrorList, validation.ValidateConditionalNetworkPolicy(obj.(*networking.NetworkPolicy), old.(*networking.NetworkPolicy))...)
return append(validationErrorList, updateErrorList...)
}