mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-23 19:56:01 +00:00
Merge pull request #110576 from DangerOnTheRanger/cel-e2e-part2
Add second set of additional CRD validation E2E tests
This commit is contained in:
commit
9d577d8a29
@ -61,17 +61,26 @@ var _ = SIGDescribe("CustomResourceValidationRules [Privileged:ClusterAdmin][Alp
|
||||
return &c
|
||||
}
|
||||
|
||||
// for all new CRD validation features that should be E2E-tested, add them
|
||||
// into this schema and then add CR requests to the end of the the test
|
||||
// below ("MUST NOT fail validation...") instead of writing a new and
|
||||
// separate test
|
||||
var schemaWithValidationExpression = unmarshallSchema([]byte(`{
|
||||
"type":"object",
|
||||
"properties":{
|
||||
"spec":{
|
||||
"type":"object",
|
||||
"x-kubernetes-validations":[
|
||||
{ "rule":"self.x + self.y > 0" }
|
||||
{ "rule":"self.x + self.y > 0" },
|
||||
{ "rule":"self.firstArray.isSorted() && self.secondArray.isSorted() && ((self.firstArray.sum() + self.secondArray.sum()) % 2 == 0)" },
|
||||
{ "rule":"self.largeArray.all(x, self.largeArray.all(y, y == x))" }
|
||||
],
|
||||
"properties":{
|
||||
"x":{ "type":"integer" },
|
||||
"y":{ "type":"integer" }
|
||||
"y":{ "type":"integer" },
|
||||
"firstArray":{ "type":"array", "maxItems": 1000, "items":{ "type": "integer"} },
|
||||
"secondArray":{ "type":"array", "maxItems": 1000, "items":{ "type": "integer"} },
|
||||
"largeArray":{ "type":"array", "maxItems": 725, "items":{ "type": "integer"} }
|
||||
}
|
||||
},
|
||||
"status":{
|
||||
@ -85,7 +94,7 @@ var _ = SIGDescribe("CustomResourceValidationRules [Privileged:ClusterAdmin][Alp
|
||||
}
|
||||
}
|
||||
}`))
|
||||
ginkgo.It("MUST NOT fail validation for create of a custom resource that satisfies the x-kubernetes-validator rules", func() {
|
||||
ginkgo.It("MUST NOT fail validation for create of a custom resource that satisfies the x-kubernetes-validations rules", func() {
|
||||
ginkgo.By("Creating a custom resource definition with validation rules")
|
||||
crd := fixtures.NewRandomNameV1CustomResourceDefinitionWithSchema(v1.NamespaceScoped, schemaWithValidationExpression, false)
|
||||
crd, err := fixtures.CreateNewV1CustomResourceDefinitionWatchUnsafe(crd, apiExtensionClient)
|
||||
@ -106,13 +115,16 @@ var _ = SIGDescribe("CustomResourceValidationRules [Privileged:ClusterAdmin][Alp
|
||||
"namespace": f.Namespace.Name,
|
||||
},
|
||||
"spec": map[string]interface{}{
|
||||
"x": int64(1),
|
||||
"y": int64(0),
|
||||
"x": int64(1),
|
||||
"y": int64(0),
|
||||
"firstArray": []int64{3, 4},
|
||||
"secondArray": []int64{5, 10},
|
||||
"largeArray": []int64{2, 2},
|
||||
},
|
||||
}}, metav1.CreateOptions{})
|
||||
framework.ExpectNoError(err, "validation rules satisfied")
|
||||
})
|
||||
ginkgo.It("MUST fail validation for create of a custom resource that does not satisfy the x-kubernetes-validator rules", func() {
|
||||
ginkgo.It("MUST fail validation for create of a custom resource that does not satisfy the x-kubernetes-validations rules", func() {
|
||||
ginkgo.By("Creating a custom resource definition with validation rules")
|
||||
crd := fixtures.NewRandomNameV1CustomResourceDefinitionWithSchema(v1.NamespaceScoped, schemaWithValidationExpression, false)
|
||||
crd, err := fixtures.CreateNewV1CustomResourceDefinitionWatchUnsafe(crd, apiExtensionClient)
|
||||
@ -144,7 +156,7 @@ var _ = SIGDescribe("CustomResourceValidationRules [Privileged:ClusterAdmin][Alp
|
||||
}
|
||||
})
|
||||
|
||||
ginkgo.It("MUST fail create of a custom resource definition that contains a x-kubernetes-validator rule that refers to a property that do not exist", func() {
|
||||
ginkgo.It("MUST fail create of a custom resource definition that contains a x-kubernetes-validations rule that refers to a property that do not exist", func() {
|
||||
ginkgo.By("Defining a custom resource definition with a validation rule that refers to a property that do not exist")
|
||||
var schemaWithInvalidValidationRule = unmarshallSchema([]byte(`{
|
||||
"type":"object",
|
||||
@ -223,4 +235,102 @@ var _ = SIGDescribe("CustomResourceValidationRules [Privileged:ClusterAdmin][Alp
|
||||
framework.Failf("expected error message to contain %q, got %q", expectedErrMsg, err.Error())
|
||||
}
|
||||
})
|
||||
|
||||
ginkgo.It("MUST fail create of a custom resource that exceeds the runtime cost limit for x-kubernetes-validations rule execution", func() {
|
||||
ginkgo.By("Defining a custom resource definition including an expensive rule on a large amount of data")
|
||||
crd := fixtures.NewRandomNameV1CustomResourceDefinitionWithSchema(v1.NamespaceScoped, schemaWithValidationExpression, false)
|
||||
_, err := fixtures.CreateNewV1CustomResourceDefinitionWatchUnsafe(crd, apiExtensionClient)
|
||||
framework.ExpectNoError(err, "creating CustomResourceDefinition including an expensive rule on a large amount of data")
|
||||
defer func() {
|
||||
err = fixtures.DeleteV1CustomResourceDefinition(crd, apiExtensionClient)
|
||||
framework.ExpectNoError(err, "deleting CustomResourceDefinition")
|
||||
}()
|
||||
ginkgo.By("Attempting to create a custom resource that will exceed the runtime cost limit")
|
||||
crClient, gvr := customResourceClient(crd)
|
||||
name1 := names.SimpleNameGenerator.GenerateName("cr-1")
|
||||
_, err = crClient.Namespace(f.Namespace.Name).Create(context.TODO(), &unstructured.Unstructured{Object: map[string]interface{}{
|
||||
"apiVersion": gvr.Group + "/" + gvr.Version,
|
||||
"kind": crd.Spec.Names.Kind,
|
||||
"metadata": map[string]interface{}{
|
||||
"name": name1,
|
||||
"namespace": f.Namespace.Name,
|
||||
},
|
||||
"spec": map[string]interface{}{
|
||||
"largeArray": genLargeArray(725, 20),
|
||||
},
|
||||
}}, metav1.CreateOptions{})
|
||||
framework.ExpectError(err, "custom resource creation should be prohibited by runtime cost limit")
|
||||
expectedErrMsg := "call cost exceeds limit"
|
||||
if !strings.Contains(err.Error(), expectedErrMsg) {
|
||||
framework.Failf("expect error contains %q, got %q", expectedErrMsg, err.Error())
|
||||
}
|
||||
})
|
||||
|
||||
ginkgo.It("MUST fail update of a custom resource that does not satisfy a x-kubernetes-validations transition rule", func() {
|
||||
ginkgo.By("Defining a custom resource definition with a x-kubernetes-validations transition rule")
|
||||
var schemaWithTransitionRule = unmarshallSchema([]byte(`{
|
||||
"type":"object",
|
||||
"properties":{
|
||||
"spec":{
|
||||
"type":"object",
|
||||
"properties":{
|
||||
"num":{
|
||||
"type":"integer",
|
||||
"x-kubernetes-validations":[
|
||||
{ "rule":"self > oldSelf" }
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}`))
|
||||
crd := fixtures.NewRandomNameV1CustomResourceDefinitionWithSchema(v1.NamespaceScoped, schemaWithTransitionRule, false)
|
||||
_, err := fixtures.CreateNewV1CustomResourceDefinitionWatchUnsafe(crd, apiExtensionClient)
|
||||
framework.ExpectNoError(err, "creating CustomResourceDefinition including an x-kubernetes-validations transition rule")
|
||||
defer func() {
|
||||
err = fixtures.DeleteV1CustomResourceDefinition(crd, apiExtensionClient)
|
||||
framework.ExpectNoError(err, "deleting CustomResourceDefinition")
|
||||
}()
|
||||
ginkgo.By("Attempting to create a custom resource")
|
||||
crClient, gvr := customResourceClient(crd)
|
||||
name1 := names.SimpleNameGenerator.GenerateName("cr-1")
|
||||
unstruct, err := crClient.Namespace(f.Namespace.Name).Create(context.TODO(), &unstructured.Unstructured{Object: map[string]interface{}{
|
||||
"apiVersion": gvr.Group + "/" + gvr.Version,
|
||||
"kind": crd.Spec.Names.Kind,
|
||||
"metadata": map[string]interface{}{
|
||||
"name": name1,
|
||||
"namespace": f.Namespace.Name,
|
||||
},
|
||||
"spec": map[string]interface{}{
|
||||
"num": int64(10),
|
||||
},
|
||||
}}, metav1.CreateOptions{})
|
||||
framework.ExpectNoError(err, "transition rules do not apply to create operations")
|
||||
ginkgo.By("Updating a custom resource with a value that does not satisfy an x-kubernetes-validations transition rule")
|
||||
_, err = crClient.Namespace(f.Namespace.Name).Update(context.TODO(), &unstructured.Unstructured{Object: map[string]interface{}{
|
||||
"apiVersion": gvr.Group + "/" + gvr.Version,
|
||||
"kind": crd.Spec.Names.Kind,
|
||||
"metadata": map[string]interface{}{
|
||||
"name": name1,
|
||||
"namespace": f.Namespace.Name,
|
||||
"resourceVersion": unstruct.GetResourceVersion(),
|
||||
},
|
||||
"spec": map[string]interface{}{
|
||||
"num": int64(9),
|
||||
},
|
||||
}}, metav1.UpdateOptions{})
|
||||
framework.ExpectError(err, "custom resource update should be prohibited by transition rule")
|
||||
expectedErrMsg := "failed rule"
|
||||
if !strings.Contains(err.Error(), expectedErrMsg) {
|
||||
framework.Failf("expect error contains %q, got %q", expectedErrMsg, err.Error())
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
func genLargeArray(n, x int64) []int64 {
|
||||
arr := make([]int64, n)
|
||||
for i := int64(0); i < n; i++ {
|
||||
arr[i] = x
|
||||
}
|
||||
return arr
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user