mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-19 18:02:01 +00:00
Merge pull request #108889 from kevindelgado/validation-beta-flag
ServerSideFieldValidation Beta Graduation
This commit is contained in:
commit
ea0dc6ed41
@ -993,7 +993,7 @@ var defaultKubernetesFeatureGates = map[featuregate.Feature]featuregate.FeatureS
|
|||||||
genericfeatures.OpenAPIEnums: {Default: true, PreRelease: featuregate.Beta},
|
genericfeatures.OpenAPIEnums: {Default: true, PreRelease: featuregate.Beta},
|
||||||
genericfeatures.CustomResourceValidationExpressions: {Default: false, PreRelease: featuregate.Alpha},
|
genericfeatures.CustomResourceValidationExpressions: {Default: false, PreRelease: featuregate.Alpha},
|
||||||
genericfeatures.OpenAPIV3: {Default: false, PreRelease: featuregate.Alpha},
|
genericfeatures.OpenAPIV3: {Default: false, PreRelease: featuregate.Alpha},
|
||||||
genericfeatures.ServerSideFieldValidation: {Default: false, PreRelease: featuregate.Alpha},
|
genericfeatures.ServerSideFieldValidation: {Default: true, PreRelease: featuregate.Beta},
|
||||||
// features that enable backwards compatibility but are scheduled to be removed
|
// features that enable backwards compatibility but are scheduled to be removed
|
||||||
// ...
|
// ...
|
||||||
HPAScaleToZero: {Default: false, PreRelease: featuregate.Alpha},
|
HPAScaleToZero: {Default: false, PreRelease: featuregate.Alpha},
|
||||||
|
@ -174,6 +174,7 @@ const (
|
|||||||
// owner: @kevindelgado
|
// owner: @kevindelgado
|
||||||
// kep: http://kep.k8s.io/2885
|
// kep: http://kep.k8s.io/2885
|
||||||
// alpha: v1.23
|
// alpha: v1.23
|
||||||
|
// beta: v1.24
|
||||||
//
|
//
|
||||||
// Enables server-side field validation.
|
// Enables server-side field validation.
|
||||||
ServerSideFieldValidation featuregate.Feature = "ServerSideFieldValidation"
|
ServerSideFieldValidation featuregate.Feature = "ServerSideFieldValidation"
|
||||||
@ -205,5 +206,5 @@ var defaultKubernetesFeatureGates = map[featuregate.Feature]featuregate.FeatureS
|
|||||||
OpenAPIEnums: {Default: true, PreRelease: featuregate.Beta},
|
OpenAPIEnums: {Default: true, PreRelease: featuregate.Beta},
|
||||||
CustomResourceValidationExpressions: {Default: false, PreRelease: featuregate.Alpha},
|
CustomResourceValidationExpressions: {Default: false, PreRelease: featuregate.Alpha},
|
||||||
OpenAPIV3: {Default: false, PreRelease: featuregate.Alpha},
|
OpenAPIV3: {Default: false, PreRelease: featuregate.Alpha},
|
||||||
ServerSideFieldValidation: {Default: false, PreRelease: featuregate.Alpha},
|
ServerSideFieldValidation: {Default: true, PreRelease: featuregate.Beta},
|
||||||
}
|
}
|
||||||
|
20
test/conformance/testdata/conformance.yaml
vendored
20
test/conformance/testdata/conformance.yaml
vendored
@ -251,8 +251,8 @@
|
|||||||
works for CRD preserving unknown fields at the schema root [Conformance]'
|
works for CRD preserving unknown fields at the schema root [Conformance]'
|
||||||
description: Register a custom resource definition with x-preserve-unknown-fields
|
description: Register a custom resource definition with x-preserve-unknown-fields
|
||||||
in the schema root. Attempt to create and apply a change a custom resource, via
|
in the schema root. Attempt to create and apply a change a custom resource, via
|
||||||
kubectl; client-side validation MUST accept unknown properties. Attempt kubectl
|
kubectl; kubectl validation MUST accept unknown properties. Attempt kubectl explain;
|
||||||
explain; the output MUST show the custom resource KIND.
|
the output MUST show the custom resource KIND.
|
||||||
release: v1.16
|
release: v1.16
|
||||||
file: test/e2e/apimachinery/crd_publish_openapi.go
|
file: test/e2e/apimachinery/crd_publish_openapi.go
|
||||||
- testname: Custom Resource OpenAPI Publish, with x-preserve-unknown-fields in embedded
|
- testname: Custom Resource OpenAPI Publish, with x-preserve-unknown-fields in embedded
|
||||||
@ -261,7 +261,7 @@
|
|||||||
works for CRD preserving unknown fields in an embedded object [Conformance]'
|
works for CRD preserving unknown fields in an embedded object [Conformance]'
|
||||||
description: Register a custom resource definition with x-preserve-unknown-fields
|
description: Register a custom resource definition with x-preserve-unknown-fields
|
||||||
in an embedded object. Attempt to create and apply a change a custom resource,
|
in an embedded object. Attempt to create and apply a change a custom resource,
|
||||||
via kubectl; client-side validation MUST accept unknown properties. Attempt kubectl
|
via kubectl; kubectl validation MUST accept unknown properties. Attempt kubectl
|
||||||
explain; the output MUST show that x-preserve-unknown-properties is used on the
|
explain; the output MUST show that x-preserve-unknown-properties is used on the
|
||||||
nested field.
|
nested field.
|
||||||
release: v1.16
|
release: v1.16
|
||||||
@ -271,12 +271,12 @@
|
|||||||
works for CRD with validation schema [Conformance]'
|
works for CRD with validation schema [Conformance]'
|
||||||
description: Register a custom resource definition with a validating schema consisting
|
description: Register a custom resource definition with a validating schema consisting
|
||||||
of objects, arrays and primitives. Attempt to create and apply a change a custom
|
of objects, arrays and primitives. Attempt to create and apply a change a custom
|
||||||
resource using valid properties, via kubectl; client-side validation MUST pass.
|
resource using valid properties, via kubectl; kubectl validation MUST pass. Attempt
|
||||||
Attempt both operations with unknown properties and without required properties;
|
both operations with unknown properties and without required properties; kubectl
|
||||||
client-side validation MUST reject the operations. Attempt kubectl explain; the
|
validation MUST reject the operations. Attempt kubectl explain; the output MUST
|
||||||
output MUST explain the custom resource properties. Attempt kubectl explain on
|
explain the custom resource properties. Attempt kubectl explain on custom resource
|
||||||
custom resource properties; the output MUST explain the nested custom resource
|
properties; the output MUST explain the nested custom resource properties. All
|
||||||
properties.
|
validation should be the same.
|
||||||
release: v1.16
|
release: v1.16
|
||||||
file: test/e2e/apimachinery/crd_publish_openapi.go
|
file: test/e2e/apimachinery/crd_publish_openapi.go
|
||||||
- testname: Custom Resource OpenAPI Publish, with x-preserve-unknown-fields in object
|
- testname: Custom Resource OpenAPI Publish, with x-preserve-unknown-fields in object
|
||||||
@ -284,7 +284,7 @@
|
|||||||
works for CRD without validation schema [Conformance]'
|
works for CRD without validation schema [Conformance]'
|
||||||
description: Register a custom resource definition with x-preserve-unknown-fields
|
description: Register a custom resource definition with x-preserve-unknown-fields
|
||||||
in the top level object. Attempt to create and apply a change a custom resource,
|
in the top level object. Attempt to create and apply a change a custom resource,
|
||||||
via kubectl; client-side validation MUST accept unknown properties. Attempt kubectl
|
via kubectl; kubectl validation MUST accept unknown properties. Attempt kubectl
|
||||||
explain; the output MUST contain a valid DESCRIPTION stanza.
|
explain; the output MUST contain a valid DESCRIPTION stanza.
|
||||||
release: v1.16
|
release: v1.16
|
||||||
file: test/e2e/apimachinery/crd_publish_openapi.go
|
file: test/e2e/apimachinery/crd_publish_openapi.go
|
||||||
|
@ -58,10 +58,11 @@ var _ = SIGDescribe("CustomResourcePublishOpenAPI [Privileged:ClusterAdmin]", fu
|
|||||||
Testname: Custom Resource OpenAPI Publish, with validation schema
|
Testname: Custom Resource OpenAPI Publish, with validation schema
|
||||||
Description: Register a custom resource definition with a validating schema consisting of objects, arrays and
|
Description: Register a custom resource definition with a validating schema consisting of objects, arrays and
|
||||||
primitives. Attempt to create and apply a change a custom resource using valid properties, via kubectl;
|
primitives. Attempt to create and apply a change a custom resource using valid properties, via kubectl;
|
||||||
client-side validation MUST pass. Attempt both operations with unknown properties and without required
|
kubectl validation MUST pass. Attempt both operations with unknown properties and without required
|
||||||
properties; client-side validation MUST reject the operations. Attempt kubectl explain; the output MUST
|
properties; kubectl validation MUST reject the operations. Attempt kubectl explain; the output MUST
|
||||||
explain the custom resource properties. Attempt kubectl explain on custom resource properties; the output MUST
|
explain the custom resource properties. Attempt kubectl explain on custom resource properties; the output MUST
|
||||||
explain the nested custom resource properties.
|
explain the nested custom resource properties.
|
||||||
|
All validation should be the same.
|
||||||
*/
|
*/
|
||||||
framework.ConformanceIt("works for CRD with validation schema", func() {
|
framework.ConformanceIt("works for CRD with validation schema", func() {
|
||||||
crd, err := setupCRD(f, schemaFoo, "foo", "v1")
|
crd, err := setupCRD(f, schemaFoo, "foo", "v1")
|
||||||
@ -72,7 +73,7 @@ var _ = SIGDescribe("CustomResourcePublishOpenAPI [Privileged:ClusterAdmin]", fu
|
|||||||
meta := fmt.Sprintf(metaPattern, crd.Crd.Spec.Names.Kind, crd.Crd.Spec.Group, crd.Crd.Spec.Versions[0].Name, "test-foo")
|
meta := fmt.Sprintf(metaPattern, crd.Crd.Spec.Names.Kind, crd.Crd.Spec.Group, crd.Crd.Spec.Versions[0].Name, "test-foo")
|
||||||
ns := fmt.Sprintf("--namespace=%v", f.Namespace.Name)
|
ns := fmt.Sprintf("--namespace=%v", f.Namespace.Name)
|
||||||
|
|
||||||
ginkgo.By("client-side validation (kubectl create and apply) allows request with known and required properties")
|
ginkgo.By("kubectl validation (kubectl create and apply) allows request with known and required properties")
|
||||||
validCR := fmt.Sprintf(`{%s,"spec":{"bars":[{"name":"test-bar"}]}}`, meta)
|
validCR := fmt.Sprintf(`{%s,"spec":{"bars":[{"name":"test-bar"}]}}`, meta)
|
||||||
if _, err := framework.RunKubectlInput(f.Namespace.Name, validCR, ns, "create", "-f", "-"); err != nil {
|
if _, err := framework.RunKubectlInput(f.Namespace.Name, validCR, ns, "create", "-f", "-"); err != nil {
|
||||||
framework.Failf("failed to create valid CR %s: %v", validCR, err)
|
framework.Failf("failed to create valid CR %s: %v", validCR, err)
|
||||||
@ -87,13 +88,15 @@ var _ = SIGDescribe("CustomResourcePublishOpenAPI [Privileged:ClusterAdmin]", fu
|
|||||||
framework.Failf("failed to delete valid CR: %v", err)
|
framework.Failf("failed to delete valid CR: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
ginkgo.By("client-side validation (kubectl create and apply) rejects request with value outside defined enum values")
|
ginkgo.By("kubectl validation (kubectl create and apply) rejects request with value outside defined enum values")
|
||||||
badEnumValueCR := fmt.Sprintf(`{%s,"spec":{"bars":[{"name":"test-bar", "feeling":"NonExistentValue"}]}}`, meta)
|
badEnumValueCR := fmt.Sprintf(`{%s,"spec":{"bars":[{"name":"test-bar", "feeling":"NonExistentValue"}]}}`, meta)
|
||||||
if _, err := framework.RunKubectlInput(f.Namespace.Name, badEnumValueCR, ns, "create", "-f", "-"); err == nil || !strings.Contains(err.Error(), `Unsupported value: "NonExistentValue"`) {
|
if _, err := framework.RunKubectlInput(f.Namespace.Name, badEnumValueCR, ns, "create", "-f", "-"); err == nil || !strings.Contains(err.Error(), `Unsupported value: "NonExistentValue"`) {
|
||||||
framework.Failf("unexpected no error when creating CR with unknown enum value: %v", err)
|
framework.Failf("unexpected no error when creating CR with unknown enum value: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
ginkgo.By("client-side validation (kubectl create and apply) rejects request with unknown properties when disallowed by the schema")
|
// TODO: server-side validation and client-side validation produce slightly different error messages.
|
||||||
|
// Because server-side is default in beta but not GA yet, we will produce different behaviors in the default vs GA only conformance tests. We have made the error generic enough to pass both, but should go back and make the error more specific once server-side validation goes GA.
|
||||||
|
ginkgo.By("kubectl validation (kubectl create and apply) rejects request with unknown properties when disallowed by the schema")
|
||||||
unknownCR := fmt.Sprintf(`{%s,"spec":{"foo":true}}`, meta)
|
unknownCR := fmt.Sprintf(`{%s,"spec":{"foo":true}}`, meta)
|
||||||
if _, err := framework.RunKubectlInput(f.Namespace.Name, unknownCR, ns, "create", "-f", "-"); err == nil || (!strings.Contains(err.Error(), `unknown field "foo"`) && !strings.Contains(err.Error(), `unknown field "spec.foo"`)) {
|
if _, err := framework.RunKubectlInput(f.Namespace.Name, unknownCR, ns, "create", "-f", "-"); err == nil || (!strings.Contains(err.Error(), `unknown field "foo"`) && !strings.Contains(err.Error(), `unknown field "spec.foo"`)) {
|
||||||
framework.Failf("unexpected no error when creating CR with unknown field: %v", err)
|
framework.Failf("unexpected no error when creating CR with unknown field: %v", err)
|
||||||
@ -102,7 +105,8 @@ var _ = SIGDescribe("CustomResourcePublishOpenAPI [Privileged:ClusterAdmin]", fu
|
|||||||
framework.Failf("unexpected no error when applying CR with unknown field: %v", err)
|
framework.Failf("unexpected no error when applying CR with unknown field: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
ginkgo.By("client-side validation (kubectl create and apply) rejects request without required properties")
|
// TODO: see above note, we should check the value of the error once server-side validation is GA.
|
||||||
|
ginkgo.By("kubectl validation (kubectl create and apply) rejects request without required properties")
|
||||||
noRequireCR := fmt.Sprintf(`{%s,"spec":{"bars":[{"age":"10"}]}}`, meta)
|
noRequireCR := fmt.Sprintf(`{%s,"spec":{"bars":[{"age":"10"}]}}`, meta)
|
||||||
if _, err := framework.RunKubectlInput(f.Namespace.Name, noRequireCR, ns, "create", "-f", "-"); err == nil || (!strings.Contains(err.Error(), `missing required field "name"`) && !strings.Contains(err.Error(), `spec.bars[0].name: Required value`)) {
|
if _, err := framework.RunKubectlInput(f.Namespace.Name, noRequireCR, ns, "create", "-f", "-"); err == nil || (!strings.Contains(err.Error(), `missing required field "name"`) && !strings.Contains(err.Error(), `spec.bars[0].name: Required value`)) {
|
||||||
framework.Failf("unexpected no error when creating CR without required field: %v", err)
|
framework.Failf("unexpected no error when creating CR without required field: %v", err)
|
||||||
@ -141,7 +145,7 @@ var _ = SIGDescribe("CustomResourcePublishOpenAPI [Privileged:ClusterAdmin]", fu
|
|||||||
Release: v1.16
|
Release: v1.16
|
||||||
Testname: Custom Resource OpenAPI Publish, with x-preserve-unknown-fields in object
|
Testname: Custom Resource OpenAPI Publish, with x-preserve-unknown-fields in object
|
||||||
Description: Register a custom resource definition with x-preserve-unknown-fields in the top level object.
|
Description: Register a custom resource definition with x-preserve-unknown-fields in the top level object.
|
||||||
Attempt to create and apply a change a custom resource, via kubectl; client-side validation MUST accept unknown
|
Attempt to create and apply a change a custom resource, via kubectl; kubectl validation MUST accept unknown
|
||||||
properties. Attempt kubectl explain; the output MUST contain a valid DESCRIPTION stanza.
|
properties. Attempt kubectl explain; the output MUST contain a valid DESCRIPTION stanza.
|
||||||
*/
|
*/
|
||||||
framework.ConformanceIt("works for CRD without validation schema", func() {
|
framework.ConformanceIt("works for CRD without validation schema", func() {
|
||||||
@ -153,7 +157,7 @@ var _ = SIGDescribe("CustomResourcePublishOpenAPI [Privileged:ClusterAdmin]", fu
|
|||||||
meta := fmt.Sprintf(metaPattern, crd.Crd.Spec.Names.Kind, crd.Crd.Spec.Group, crd.Crd.Spec.Versions[0].Name, "test-cr")
|
meta := fmt.Sprintf(metaPattern, crd.Crd.Spec.Names.Kind, crd.Crd.Spec.Group, crd.Crd.Spec.Versions[0].Name, "test-cr")
|
||||||
ns := fmt.Sprintf("--namespace=%v", f.Namespace.Name)
|
ns := fmt.Sprintf("--namespace=%v", f.Namespace.Name)
|
||||||
|
|
||||||
ginkgo.By("client-side validation (kubectl create and apply) allows request with any unknown properties")
|
ginkgo.By("kubectl validation (kubectl create and apply) allows request with any unknown properties")
|
||||||
randomCR := fmt.Sprintf(`{%s,"a":{"b":[{"c":"d"}]}}`, meta)
|
randomCR := fmt.Sprintf(`{%s,"a":{"b":[{"c":"d"}]}}`, meta)
|
||||||
if _, err := framework.RunKubectlInput(f.Namespace.Name, randomCR, ns, "create", "-f", "-"); err != nil {
|
if _, err := framework.RunKubectlInput(f.Namespace.Name, randomCR, ns, "create", "-f", "-"); err != nil {
|
||||||
framework.Failf("failed to create random CR %s for CRD without schema: %v", randomCR, err)
|
framework.Failf("failed to create random CR %s for CRD without schema: %v", randomCR, err)
|
||||||
@ -182,7 +186,7 @@ var _ = SIGDescribe("CustomResourcePublishOpenAPI [Privileged:ClusterAdmin]", fu
|
|||||||
Release: v1.16
|
Release: v1.16
|
||||||
Testname: Custom Resource OpenAPI Publish, with x-preserve-unknown-fields at root
|
Testname: Custom Resource OpenAPI Publish, with x-preserve-unknown-fields at root
|
||||||
Description: Register a custom resource definition with x-preserve-unknown-fields in the schema root.
|
Description: Register a custom resource definition with x-preserve-unknown-fields in the schema root.
|
||||||
Attempt to create and apply a change a custom resource, via kubectl; client-side validation MUST accept unknown
|
Attempt to create and apply a change a custom resource, via kubectl; kubectl validation MUST accept unknown
|
||||||
properties. Attempt kubectl explain; the output MUST show the custom resource KIND.
|
properties. Attempt kubectl explain; the output MUST show the custom resource KIND.
|
||||||
*/
|
*/
|
||||||
framework.ConformanceIt("works for CRD preserving unknown fields at the schema root", func() {
|
framework.ConformanceIt("works for CRD preserving unknown fields at the schema root", func() {
|
||||||
@ -194,7 +198,7 @@ var _ = SIGDescribe("CustomResourcePublishOpenAPI [Privileged:ClusterAdmin]", fu
|
|||||||
meta := fmt.Sprintf(metaPattern, crd.Crd.Spec.Names.Kind, crd.Crd.Spec.Group, crd.Crd.Spec.Versions[0].Name, "test-cr")
|
meta := fmt.Sprintf(metaPattern, crd.Crd.Spec.Names.Kind, crd.Crd.Spec.Group, crd.Crd.Spec.Versions[0].Name, "test-cr")
|
||||||
ns := fmt.Sprintf("--namespace=%v", f.Namespace.Name)
|
ns := fmt.Sprintf("--namespace=%v", f.Namespace.Name)
|
||||||
|
|
||||||
ginkgo.By("client-side validation (kubectl create and apply) allows request with any unknown properties")
|
ginkgo.By("kubectl validation (kubectl create and apply) allows request with any unknown properties")
|
||||||
randomCR := fmt.Sprintf(`{%s,"a":{"b":[{"c":"d"}]}}`, meta)
|
randomCR := fmt.Sprintf(`{%s,"a":{"b":[{"c":"d"}]}}`, meta)
|
||||||
if _, err := framework.RunKubectlInput(f.Namespace.Name, randomCR, ns, "create", "-f", "-"); err != nil {
|
if _, err := framework.RunKubectlInput(f.Namespace.Name, randomCR, ns, "create", "-f", "-"); err != nil {
|
||||||
framework.Failf("failed to create random CR %s for CRD that allows unknown properties at the root: %v", randomCR, err)
|
framework.Failf("failed to create random CR %s for CRD that allows unknown properties at the root: %v", randomCR, err)
|
||||||
@ -223,7 +227,7 @@ var _ = SIGDescribe("CustomResourcePublishOpenAPI [Privileged:ClusterAdmin]", fu
|
|||||||
Release: v1.16
|
Release: v1.16
|
||||||
Testname: Custom Resource OpenAPI Publish, with x-preserve-unknown-fields in embedded object
|
Testname: Custom Resource OpenAPI Publish, with x-preserve-unknown-fields in embedded object
|
||||||
Description: Register a custom resource definition with x-preserve-unknown-fields in an embedded object.
|
Description: Register a custom resource definition with x-preserve-unknown-fields in an embedded object.
|
||||||
Attempt to create and apply a change a custom resource, via kubectl; client-side validation MUST accept unknown
|
Attempt to create and apply a change a custom resource, via kubectl; kubectl validation MUST accept unknown
|
||||||
properties. Attempt kubectl explain; the output MUST show that x-preserve-unknown-properties is used on the
|
properties. Attempt kubectl explain; the output MUST show that x-preserve-unknown-properties is used on the
|
||||||
nested field.
|
nested field.
|
||||||
*/
|
*/
|
||||||
@ -236,7 +240,7 @@ var _ = SIGDescribe("CustomResourcePublishOpenAPI [Privileged:ClusterAdmin]", fu
|
|||||||
meta := fmt.Sprintf(metaPattern, crd.Crd.Spec.Names.Kind, crd.Crd.Spec.Group, crd.Crd.Spec.Versions[0].Name, "test-cr")
|
meta := fmt.Sprintf(metaPattern, crd.Crd.Spec.Names.Kind, crd.Crd.Spec.Group, crd.Crd.Spec.Versions[0].Name, "test-cr")
|
||||||
ns := fmt.Sprintf("--namespace=%v", f.Namespace.Name)
|
ns := fmt.Sprintf("--namespace=%v", f.Namespace.Name)
|
||||||
|
|
||||||
ginkgo.By("client-side validation (kubectl create and apply) allows request with any unknown properties")
|
ginkgo.By("kubectl validation (kubectl create and apply) allows request with any unknown properties")
|
||||||
randomCR := fmt.Sprintf(`{%s,"spec":{"a":null,"b":[{"c":"d"}]}}`, meta)
|
randomCR := fmt.Sprintf(`{%s,"spec":{"a":null,"b":[{"c":"d"}]}}`, meta)
|
||||||
if _, err := framework.RunKubectlInput(f.Namespace.Name, randomCR, ns, "create", "-f", "-"); err != nil {
|
if _, err := framework.RunKubectlInput(f.Namespace.Name, randomCR, ns, "create", "-f", "-"); err != nil {
|
||||||
framework.Failf("failed to create random CR %s for CRD that allows unknown properties in a nested object: %v", randomCR, err)
|
framework.Failf("failed to create random CR %s for CRD that allows unknown properties in a nested object: %v", randomCR, err)
|
||||||
|
@ -1003,7 +1003,7 @@ metadata:
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
ginkgo.Describe("Kubectl client-side validation", func() {
|
ginkgo.Describe("Kubectl validation", func() {
|
||||||
ginkgo.It("should create/apply a CR with unknown fields for CRD with no validation schema", func() {
|
ginkgo.It("should create/apply a CR with unknown fields for CRD with no validation schema", func() {
|
||||||
ginkgo.By("create CRD with no validation schema")
|
ginkgo.By("create CRD with no validation schema")
|
||||||
crd, err := crd.CreateTestCRD(f)
|
crd, err := crd.CreateTestCRD(f)
|
||||||
@ -1048,7 +1048,7 @@ metadata:
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
ginkgo.It("should create/apply a valid CR with arbitrary-extra properties for CRD with partially-specified validation schema", func() {
|
ginkgo.It("should create/apply an invalid/valid CR with arbitrary-extra properties for CRD with partially-specified validation schema", func() {
|
||||||
ginkgo.By("prepare CRD with partially-specified validation schema")
|
ginkgo.By("prepare CRD with partially-specified validation schema")
|
||||||
crd, err := crd.CreateTestCRD(f, func(crd *apiextensionsv1.CustomResourceDefinition) {
|
crd, err := crd.CreateTestCRD(f, func(crd *apiextensionsv1.CustomResourceDefinition) {
|
||||||
props := &apiextensionsv1.JSONSchemaProps{}
|
props := &apiextensionsv1.JSONSchemaProps{}
|
||||||
@ -1074,6 +1074,15 @@ metadata:
|
|||||||
|
|
||||||
meta := fmt.Sprintf(metaPattern, crd.Crd.Spec.Names.Kind, crd.Crd.Spec.Group, crd.Crd.Spec.Versions[0].Name, "test-cr")
|
meta := fmt.Sprintf(metaPattern, crd.Crd.Spec.Names.Kind, crd.Crd.Spec.Group, crd.Crd.Spec.Versions[0].Name, "test-cr")
|
||||||
|
|
||||||
|
// XPreserveUnknownFields is defined on the root of the schema so unknown fields within the spec
|
||||||
|
// are still considered invalid
|
||||||
|
invalidArbitraryCR := fmt.Sprintf(`{%s,"spec":{"bars":[{"name":"test-bar"}],"extraProperty":"arbitrary-value"}}`, meta)
|
||||||
|
err = createApplyCustomResource(invalidArbitraryCR, f.Namespace.Name, "test-cr", crd)
|
||||||
|
framework.ExpectError(err, "creating custom resource")
|
||||||
|
if !strings.Contains(err.Error(), `unknown field "spec.extraProperty"`) {
|
||||||
|
framework.Failf("incorrect error from createApplyCustomResource: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
// unknown fields on the root are considered valid
|
// unknown fields on the root are considered valid
|
||||||
validArbitraryCR := fmt.Sprintf(`{%s,"spec":{"bars":[{"name":"test-bar"}]},"extraProperty":"arbitrary-value"}`, meta)
|
validArbitraryCR := fmt.Sprintf(`{%s,"spec":{"bars":[{"name":"test-bar"}]},"extraProperty":"arbitrary-value"}`, meta)
|
||||||
err = createApplyCustomResource(validArbitraryCR, f.Namespace.Name, "test-cr", crd)
|
err = createApplyCustomResource(validArbitraryCR, f.Namespace.Name, "test-cr", crd)
|
||||||
@ -2153,7 +2162,7 @@ func startLocalProxy() (srv *httptest.Server, logs *bytes.Buffer) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// createApplyCustomResource asserts that given CustomResource be created and applied
|
// createApplyCustomResource asserts that given CustomResource be created and applied
|
||||||
// without being rejected by client-side validation
|
// without being rejected by kubectl validation
|
||||||
func createApplyCustomResource(resource, namespace, name string, crd *crd.TestCrd) error {
|
func createApplyCustomResource(resource, namespace, name string, crd *crd.TestCrd) error {
|
||||||
ginkgo.By("successfully create CR")
|
ginkgo.By("successfully create CR")
|
||||||
if _, err := framework.RunKubectlInput(namespace, resource, "create", "--validate=true", "-f", "-"); err != nil {
|
if _, err := framework.RunKubectlInput(namespace, resource, "create", "--validate=true", "-f", "-"); err != nil {
|
||||||
|
Loading…
Reference in New Issue
Block a user