Skip to content

Commit

Permalink
Merge pull request kubernetes#118990 from alexzielenski/apiserver/api…
Browse files Browse the repository at this point in the history
…extensions/crd-validation-ratcheting

CRD Validation Ratcheting alpha implementation
  • Loading branch information
k8s-ci-robot committed Jul 18, 2023
2 parents 31d662e + bfb2c6a commit c684de5
Show file tree
Hide file tree
Showing 13 changed files with 2,245 additions and 33 deletions.
6 changes: 6 additions & 0 deletions pkg/features/kube_features.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ limitations under the License.
package features

import (
apiextensionsfeatures "k8s.io/apiextensions-apiserver/pkg/features"
"k8s.io/apimachinery/pkg/util/runtime"
genericfeatures "k8s.io/apiserver/pkg/features"
utilfeature "k8s.io/apiserver/pkg/util/feature"
Expand Down Expand Up @@ -1191,6 +1192,11 @@ var defaultKubernetesFeatureGates = map[featuregate.Feature]featuregate.FeatureS

genericfeatures.ServerSideFieldValidation: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.29

// inherited features from apiextensions-apiserver, relisted here to get a conflict if it is changed
// unintentionally on either side:

apiextensionsfeatures.CRDValidationRatcheting: {Default: false, PreRelease: featuregate.Alpha},

// features that enable backwards compatibility but are scheduled to be removed
// ...
HPAScaleToZero: {Default: false, PreRelease: featuregate.Alpha},
Expand Down
2 changes: 1 addition & 1 deletion staging/src/k8s.io/apiextensions-apiserver/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ go 1.20

require (
github.com/emicklei/go-restful/v3 v3.9.0
github.com/evanphx/json-patch v5.6.0+incompatible
github.com/gogo/protobuf v1.3.2
github.com/google/cel-go v0.16.0
github.com/google/gnostic-models v0.6.8
Expand Down Expand Up @@ -49,7 +50,6 @@ require (
github.com/coreos/go-systemd/v22 v22.5.0 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/dustin/go-humanize v1.0.1 // indirect
github.com/evanphx/json-patch v5.6.0+incompatible // indirect
github.com/felixge/httpsnoop v1.0.3 // indirect
github.com/fsnotify/fsnotify v1.6.0 // indirect
github.com/go-logr/logr v1.2.4 // indirect
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -825,7 +825,7 @@ func validateCustomResourceDefinitionValidation(ctx context.Context, customResou

// if validation passed otherwise, make sure we can actually construct a schema validator from this custom resource validation.
if len(allErrs) == 0 {
if _, _, err := apiservervalidation.NewSchemaValidator(customResourceValidation); err != nil {
if _, _, err := apiservervalidation.NewSchemaValidator(customResourceValidation.OpenAPIV3Schema); err != nil {
allErrs = append(allErrs, field.Invalid(fldPath, "", fmt.Sprintf("error building validator: %v", err)))
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,8 +79,6 @@ import (
"k8s.io/klog/v2"
"k8s.io/kube-openapi/pkg/spec3"
"k8s.io/kube-openapi/pkg/validation/spec"
"k8s.io/kube-openapi/pkg/validation/strfmt"
"k8s.io/kube-openapi/pkg/validation/validate"
)

// crdHandler serves the `/apis` endpoint.
Expand Down Expand Up @@ -739,20 +737,22 @@ func (r *crdHandler) getOrCreateServingInfoFor(uid types.UID, name string) (*crd
utilruntime.HandleError(err)
return nil, fmt.Errorf("the server could not properly serve the CR schema")
}
var internalSchemaProps *apiextensionsinternal.JSONSchemaProps
var internalValidationSchema *apiextensionsinternal.CustomResourceValidation
if validationSchema != nil {
internalValidationSchema = &apiextensionsinternal.CustomResourceValidation{}
if err := apiextensionsv1.Convert_v1_CustomResourceValidation_To_apiextensions_CustomResourceValidation(validationSchema, internalValidationSchema, nil); err != nil {
return nil, fmt.Errorf("failed to convert CRD validation to internal version: %v", err)
}
internalSchemaProps = internalValidationSchema.OpenAPIV3Schema
}
validator, _, err := apiservervalidation.NewSchemaValidator(internalValidationSchema)
validator, _, err := apiservervalidation.NewSchemaValidator(internalSchemaProps)
if err != nil {
return nil, err
}

var statusSpec *apiextensionsinternal.CustomResourceSubresourceStatus
var statusValidator *validate.SchemaValidator
var statusValidator apiservervalidation.SchemaValidator
subresources, err := apiextensionshelpers.GetSubresourcesForVersion(crd, v.Name)
if err != nil {
utilruntime.HandleError(err)
Expand All @@ -767,11 +767,10 @@ func (r *crdHandler) getOrCreateServingInfoFor(uid types.UID, name string) (*crd
// for the status subresource, validate only against the status schema
if internalValidationSchema != nil && internalValidationSchema.OpenAPIV3Schema != nil && internalValidationSchema.OpenAPIV3Schema.Properties != nil {
if statusSchema, ok := internalValidationSchema.OpenAPIV3Schema.Properties["status"]; ok {
openapiSchema := &spec.Schema{}
if err := apiservervalidation.ConvertJSONSchemaPropsWithPostProcess(&statusSchema, openapiSchema, apiservervalidation.StripUnsupportedFormatsPostProcess); err != nil {
statusValidator, _, err = apiservervalidation.NewSchemaValidator(&statusSchema)
if err != nil {
return nil, err
}
statusValidator = validate.NewSchemaValidator(openapiSchema, nil, "", strfmt.Default)
}
}
}
Expand Down
Loading

0 comments on commit c684de5

Please sign in to comment.