cleanup: move unstructured check earlier in status update

This commit is contained in:
Alexander Zielenski 2023-10-18 15:08:43 -07:00
parent d151f22780
commit 31a1c00e49
2 changed files with 14 additions and 34 deletions

View File

@ -18,6 +18,7 @@ package customresource
import ( import (
"context" "context"
"fmt"
"sigs.k8s.io/structured-merge-diff/v4/fieldpath" "sigs.k8s.io/structured-merge-diff/v4/fieldpath"
@ -84,24 +85,21 @@ func (a statusStrategy) PrepareForUpdate(ctx context.Context, obj, old runtime.O
// ValidateUpdate is the default update validation for an end user updating status. // ValidateUpdate is the default update validation for an end user updating status.
func (a statusStrategy) ValidateUpdate(ctx context.Context, obj, old runtime.Object) field.ErrorList { func (a statusStrategy) ValidateUpdate(ctx context.Context, obj, old runtime.Object) field.ErrorList {
var errs field.ErrorList
errs = append(errs, a.customResourceStrategy.validator.ValidateStatusUpdate(ctx, obj, old, a.scale)...)
uNew, ok := obj.(*unstructured.Unstructured) uNew, ok := obj.(*unstructured.Unstructured)
if !ok { if !ok {
return errs return field.ErrorList{field.Invalid(field.NewPath(""), obj, fmt.Sprintf("has type %T. Must be a pointer to an Unstructured type", obj))}
} }
uOld, ok := old.(*unstructured.Unstructured) uOld, ok := old.(*unstructured.Unstructured)
var oldObject map[string]interface{}
if !ok { if !ok {
oldObject = nil return field.ErrorList{field.Invalid(field.NewPath(""), old, fmt.Sprintf("has type %T. Must be a pointer to an Unstructured type", old))}
} else {
oldObject = uOld.Object
} }
var errs field.ErrorList
errs = append(errs, a.customResourceStrategy.validator.ValidateStatusUpdate(ctx, uNew, uOld, a.scale)...)
// ratcheting validation of x-kubernetes-list-type value map and set // ratcheting validation of x-kubernetes-list-type value map and set
if newErrs := structurallisttype.ValidateListSetsAndMaps(nil, a.structuralSchema, uNew.Object); len(newErrs) > 0 { if newErrs := structurallisttype.ValidateListSetsAndMaps(nil, a.structuralSchema, uNew.Object); len(newErrs) > 0 {
if oldErrs := structurallisttype.ValidateListSetsAndMaps(nil, a.structuralSchema, oldObject); len(oldErrs) == 0 { if oldErrs := structurallisttype.ValidateListSetsAndMaps(nil, a.structuralSchema, uOld.Object); len(oldErrs) == 0 {
errs = append(errs, newErrs...) errs = append(errs, newErrs...)
} }
} }
@ -111,7 +109,7 @@ func (a statusStrategy) ValidateUpdate(ctx context.Context, obj, old runtime.Obj
if has, err := hasBlockingErr(errs); has { if has, err := hasBlockingErr(errs); has {
errs = append(errs, err) errs = append(errs, err)
} else { } else {
err, _ := celValidator.Validate(ctx, nil, a.customResourceStrategy.structuralSchema, uNew.Object, oldObject, celconfig.RuntimeCELCostBudget) err, _ := celValidator.Validate(ctx, nil, a.customResourceStrategy.structuralSchema, uNew.Object, uOld.Object, celconfig.RuntimeCELCostBudget)
errs = append(errs, err...) errs = append(errs, err...)
} }
} }

View File

@ -27,7 +27,6 @@ import (
"k8s.io/apimachinery/pkg/api/validation" "k8s.io/apimachinery/pkg/api/validation"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/util/sets" "k8s.io/apimachinery/pkg/util/sets"
apimachineryvalidation "k8s.io/apimachinery/pkg/util/validation" apimachineryvalidation "k8s.io/apimachinery/pkg/util/validation"
@ -93,35 +92,18 @@ func validateKubeFinalizerName(stringValue string, fldPath *field.Path) []string
return allWarnings return allWarnings
} }
func (a customResourceValidator) ValidateStatusUpdate(ctx context.Context, obj, old runtime.Object, scale *apiextensions.CustomResourceSubresourceScale) field.ErrorList { func (a customResourceValidator) ValidateStatusUpdate(ctx context.Context, obj, old *unstructured.Unstructured, scale *apiextensions.CustomResourceSubresourceScale) field.ErrorList {
u, ok := obj.(*unstructured.Unstructured) if errs := a.ValidateTypeMeta(ctx, obj); len(errs) > 0 {
if !ok {
return field.ErrorList{field.Invalid(field.NewPath(""), u, fmt.Sprintf("has type %T. Must be a pointer to an Unstructured type", u))}
}
oldU, ok := old.(*unstructured.Unstructured)
if !ok {
return field.ErrorList{field.Invalid(field.NewPath(""), old, fmt.Sprintf("has type %T. Must be a pointer to an Unstructured type", u))}
}
objAccessor, err := meta.Accessor(obj)
if err != nil {
return field.ErrorList{field.Invalid(field.NewPath("metadata"), nil, err.Error())}
}
oldAccessor, err := meta.Accessor(old)
if err != nil {
return field.ErrorList{field.Invalid(field.NewPath("metadata"), nil, err.Error())}
}
if errs := a.ValidateTypeMeta(ctx, u); len(errs) > 0 {
return errs return errs
} }
var allErrs field.ErrorList var allErrs field.ErrorList
allErrs = append(allErrs, validation.ValidateObjectMetaAccessorUpdate(objAccessor, oldAccessor, field.NewPath("metadata"))...) allErrs = append(allErrs, validation.ValidateObjectMetaAccessorUpdate(obj, old, field.NewPath("metadata"))...)
if status, hasStatus := u.UnstructuredContent()["status"]; hasStatus { if status, hasStatus := obj.UnstructuredContent()["status"]; hasStatus {
allErrs = append(allErrs, apiextensionsvalidation.ValidateCustomResourceUpdate(nil, status, oldU.UnstructuredContent()["status"], a.statusSchemaValidator)...) allErrs = append(allErrs, apiextensionsvalidation.ValidateCustomResourceUpdate(nil, status, old.UnstructuredContent()["status"], a.statusSchemaValidator)...)
} }
allErrs = append(allErrs, a.ValidateScaleStatus(ctx, u, scale)...) allErrs = append(allErrs, a.ValidateScaleStatus(ctx, obj, scale)...)
return allErrs return allErrs
} }