From 7e258bf54bd7d56cf5d17e7800e2e2b3ff026ac9 Mon Sep 17 00:00:00 2001 From: Max Goncharenko Date: Thu, 9 Sep 2021 18:55:20 +0300 Subject: [PATCH] add new test; remove unnecessary anchors (#2217) * add new test; remove unnecessary anchors Signed-off-by: Maxim Goncharenko * added several test to e2e Signed-off-by: Max Goncharenko * remove unused variable Signed-off-by: Maxim Goncharenko * added comment to expected result Signed-off-by: Maxim Goncharenko --- go.sum | 3 + pkg/engine/mutate/strategicPreprocessing.go | 5 +- .../mutate/strategicPreprocessing_test.go | 93 +++++++ test/e2e/mutate/config.go | 47 ++++ test/e2e/mutate/mutate_test.go | 231 ++++++++++++++++-- test/e2e/mutate/resources.go | 104 +++++++- test/e2e/utils.go | 3 +- 7 files changed, 455 insertions(+), 31 deletions(-) diff --git a/go.sum b/go.sum index 2a82308e59..b058538c9b 100644 --- a/go.sum +++ b/go.sum @@ -481,6 +481,9 @@ github.com/denverdino/aliyungo v0.0.0-20190125010748-a747050bb1ba/go.mod h1:dV8l github.com/devigned/tab v0.1.1/go.mod h1:XG9mPq0dFghrYvoBF3xdRrJzSTX1b7IQrvaL9mzjeJY= github.com/dgrijalva/jwt-go v0.0.0-20170104182250-a601269ab70c/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= +github.com/dgryski/go-gk v0.0.0-20140819190930-201884a44051/go.mod h1:qm+vckxRlDt0aOla0RYJJVeqHZlWfOm2UIxHaqPB46E= +github.com/dgryski/go-gk v0.0.0-20200319235926-a69029f61654/go.mod h1:qm+vckxRlDt0aOla0RYJJVeqHZlWfOm2UIxHaqPB46E= +github.com/dgryski/go-lttb v0.0.0-20180810165845-318fcdf10a77/go.mod h1:Va5MyIzkU0rAM92tn3hb3Anb7oz7KcnixF49+2wOMe4= github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= github.com/dimchansky/utfbom v1.1.0/go.mod h1:rO41eb7gLfo8SF1jd9F8HplJm1Fewwi4mQvIirEdv+8= github.com/dimchansky/utfbom v1.1.1/go.mod h1:SxdoEBH5qIqFocHMyGOXVAybYJdr71b1Q/j0mACtrfE= diff --git a/pkg/engine/mutate/strategicPreprocessing.go b/pkg/engine/mutate/strategicPreprocessing.go index d3a8a25a71..d67d3d6fc4 100644 --- a/pkg/engine/mutate/strategicPreprocessing.go +++ b/pkg/engine/mutate/strategicPreprocessing.go @@ -400,6 +400,7 @@ func deleteAnchorsInMap(node *yaml.RNode) (bool, error) { } // Go further through the map elements. + hasOnlyAnchors := true for _, field := range fields { ok, err := deleteAnchors(node.Field(field).Value) if err != nil { @@ -409,11 +410,11 @@ func deleteAnchorsInMap(node *yaml.RNode) (bool, error) { // If we have at least one element without annchor, // then we don't need to delete this element. if !ok { - return false, nil + hasOnlyAnchors = false } } - return true, nil + return hasOnlyAnchors, nil } func deleteAnchorsInList(node *yaml.RNode) (bool, error) { diff --git a/pkg/engine/mutate/strategicPreprocessing_test.go b/pkg/engine/mutate/strategicPreprocessing_test.go index e26db296ab..a7f3df4249 100644 --- a/pkg/engine/mutate/strategicPreprocessing_test.go +++ b/pkg/engine/mutate/strategicPreprocessing_test.go @@ -735,6 +735,99 @@ func Test_preProcessStrategicMergePatch_multipleAnchors(t *testing.T) { } }`), }, + { + rawPolicy: []byte(`{ + "spec": { + "securityContext": { + "runAsNonRoot": true + }, + "initContainers": [ + { + "(name)": "*", + "securityContext": { + "runAsNonRoot": true + } + } + ], + "containers": [ + { + "(name)": "*", + "securityContext": { + "runAsNonRoot": true + } + } + ] + } + }`), + rawResource: []byte(`{ + "spec":{ + "initContainers":[ + { + "name":"initbusy", + "image":"busybox:1.28", + "command":[ + "sleep", + "9999" + ] + } + ], + "containers":[ + { + "image":"busybox:1.28", + "name":"busybox", + "command":[ + "sleep", + "9999" + ] + } + ], + "affinity":{ + "podAntiAffinity":{ + "requiredDuringSchedulingIgnoredDuringExecution":[ + { + "labelSelector":{ + "matchExpressions":[ + { + "key":"app", + "operator":"In", + "values":[ + "foo", + "bar" + ] + } + ] + }, + "topologyKey":"kubernetes.io/hostname" + } + ] + } + } + } + }`), + expectedPatch: []byte(`{ + "spec": { + "securityContext": { + "runAsNonRoot": true + }, + "initContainers": [ + { + "name": "initbusy", + "securityContext": { + "runAsNonRoot": true + } + } + ], + "containers": [ + { + "name": "busybox", + "securityContext": { + "runAsNonRoot": true + } + } + ] + } + }`), + }, } for i, test := range testCases { diff --git a/test/e2e/mutate/config.go b/test/e2e/mutate/config.go index 3469ada885..6ef8e456aa 100644 --- a/test/e2e/mutate/config.go +++ b/test/e2e/mutate/config.go @@ -1,5 +1,9 @@ package mutate +import ( + "k8s.io/apimachinery/pkg/runtime/schema" +) + // MutateTests is E2E Test Config for mutation var MutateTests = []struct { //TestName - Name of the Test @@ -31,6 +35,49 @@ var MutateTests = []struct { }, } +// Note: sometimes deleting namespaces takes time. +// Using different names for namespaces prevents collisions. +var tests = []struct { + //TestDescription - Description of the Test + TestDescription string + // PolicyName - Name of the Policy + PolicyName string + // PolicyRaw - The Yaml file of the ClusterPolicy + PolicyRaw []byte + // ResourceName - Name of the Resource + ResourceName string + // ResourceNamespace - Namespace of the Resource + ResourceNamespace string + // ResourceGVR - GVR of the Resource + ResourceGVR schema.GroupVersionResource + // ResourceRaw - The Yaml file of the ClusterPolicy + ResourceRaw []byte + // ExpectedPatternRaw - The Yaml file that contains validate pattern for the expected result + // This is not the final result. It is just used to validate the result from the engine. + ExpectedPatternRaw []byte +}{ + { + TestDescription: "checks that runAsNonRoot is added to security context and containers elements security context", + PolicyName: "set-runasnonroot-true", + PolicyRaw: setRunAsNonRootTrue, + ResourceName: "foo", + ResourceNamespace: "test-mutate", + ResourceGVR: podGVR, + ResourceRaw: podWithContainers, + ExpectedPatternRaw: podWithContainersPattern, + }, + { + TestDescription: "checks that runAsNonRoot is added to security context and containers elements security context and initContainers elements security context", + PolicyName: "set-runasnonroot-true", + PolicyRaw: setRunAsNonRootTrue, + ResourceName: "foo", + ResourceNamespace: "test-mutate1", + ResourceGVR: podGVR, + ResourceRaw: podWithContainersAndInitContainers, + ExpectedPatternRaw: podWithContainersAndInitContainersPattern, + }, +} + var ingressTests = struct { testNamesapce string cpol []byte diff --git a/test/e2e/mutate/mutate_test.go b/test/e2e/mutate/mutate_test.go index 368578dc63..8ff5874ede 100644 --- a/test/e2e/mutate/mutate_test.go +++ b/test/e2e/mutate/mutate_test.go @@ -7,26 +7,26 @@ import ( "testing" "time" + "github.com/kyverno/kyverno/pkg/engine/validate" "github.com/kyverno/kyverno/test/e2e" commonE2E "github.com/kyverno/kyverno/test/e2e/common" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" + "gopkg.in/yaml.v2" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "sigs.k8s.io/controller-runtime/pkg/log" ) var ( // Cluster Policy GVR - clPolGVR = e2e.GetGVR("kyverno.io", "v1", "clusterpolicies") + policyGVR = e2e.GetGVR("kyverno.io", "v1", "clusterpolicies") // Namespace GVR - nsGVR = e2e.GetGVR("", "v1", "namespaces") + namespaceGVR = e2e.GetGVR("", "v1", "namespaces") // ConfigMap GVR - cmGVR = e2e.GetGVR("", "v1", "configmaps") + configMapGVR = e2e.GetGVR("", "v1", "configmaps") // ClusterPolicy Namespace - clPolNS = "" - // Namespace Name - // Hardcoded in YAML Definition - // nspace = "test-mutate" + policyNamespace = "" ) func Test_Mutate_Sets(t *testing.T) { @@ -43,15 +43,15 @@ func Test_Mutate_Sets(t *testing.T) { // Clean up Resources By("Cleaning Cluster Policies") - _ = e2eClient.CleanClusterPolicies(clPolGVR) + _ = e2eClient.CleanClusterPolicies(policyGVR) // Clear Namespace By(fmt.Sprintf("Deleting Namespace : %s", tests.ResourceNamespace)) - _ = e2eClient.DeleteClusteredResource(nsGVR, tests.ResourceNamespace) + _ = e2eClient.DeleteClusteredResource(namespaceGVR, tests.ResourceNamespace) // Wait Till Deletion of Namespace err = e2e.GetWithRetry(1*time.Second, 15, func() error { - _, err := e2eClient.GetClusteredResource(nsGVR, tests.ResourceNamespace) + _, err := e2eClient.GetClusteredResource(namespaceGVR, tests.ResourceNamespace) if err != nil { return nil } @@ -60,13 +60,13 @@ func Test_Mutate_Sets(t *testing.T) { Expect(err).NotTo(HaveOccurred()) // Create Namespace - By(fmt.Sprintf("Creating Namespace %s", clPolNS)) - _, err = e2eClient.CreateClusteredResourceYaml(nsGVR, newNamespaceYaml("test-mutate")) + By(fmt.Sprintf("Creating Namespace %s", policyNamespace)) + _, err = e2eClient.CreateClusteredResourceYaml(namespaceGVR, newNamespaceYaml("test-mutate")) Expect(err).NotTo(HaveOccurred()) // Wait Till Creation of Namespace err = e2e.GetWithRetry(1*time.Second, 15, func() error { - _, err := e2eClient.GetClusteredResource(nsGVR, tests.ResourceNamespace) + _, err := e2eClient.GetClusteredResource(namespaceGVR, tests.ResourceNamespace) if err != nil { return err } @@ -77,12 +77,12 @@ func Test_Mutate_Sets(t *testing.T) { // Create source CM By(fmt.Sprintf("\nCreating source ConfigMap in %s", tests.ResourceNamespace)) - _, err = e2eClient.CreateNamespacedResourceYaml(cmGVR, tests.ResourceNamespace, sourceConfigMapYaml) + _, err = e2eClient.CreateNamespacedResourceYaml(configMapGVR, tests.ResourceNamespace, sourceConfigMapYaml) Expect(err).NotTo(HaveOccurred()) // Create CM Policy - By(fmt.Sprintf("\nCreating Mutate ConfigMap Policy in %s", clPolNS)) - _, err = e2eClient.CreateNamespacedResourceYaml(clPolGVR, clPolNS, tests.Data) + By(fmt.Sprintf("\nCreating Mutate ConfigMap Policy in %s", policyNamespace)) + _, err = e2eClient.CreateNamespacedResourceYaml(policyGVR, policyNamespace, tests.Data) Expect(err).NotTo(HaveOccurred()) err = commonE2E.PolicyCreated(tests.PolicyName) @@ -90,14 +90,14 @@ func Test_Mutate_Sets(t *testing.T) { // Create target CM By(fmt.Sprintf("\nCreating target ConfigMap in %s", tests.ResourceNamespace)) - _, err = e2eClient.CreateNamespacedResourceYaml(cmGVR, tests.ResourceNamespace, targetConfigMapYaml) + _, err = e2eClient.CreateNamespacedResourceYaml(configMapGVR, tests.ResourceNamespace, targetConfigMapYaml) Expect(err).NotTo(HaveOccurred()) // Verify created ConfigMap By(fmt.Sprintf("Verifying ConfigMap in the Namespace : %s", tests.ResourceNamespace)) // Wait Till Creation of ConfigMap err = e2e.GetWithRetry(1*time.Second, 15, func() error { - _, err := e2eClient.GetNamespacedResource(cmGVR, tests.ResourceNamespace, "target") + _, err := e2eClient.GetNamespacedResource(configMapGVR, tests.ResourceNamespace, "target") if err != nil { return err } @@ -105,7 +105,7 @@ func Test_Mutate_Sets(t *testing.T) { return nil }) - cmRes, err := e2eClient.GetNamespacedResource(cmGVR, tests.ResourceNamespace, "target") + cmRes, err := e2eClient.GetNamespacedResource(configMapGVR, tests.ResourceNamespace, "target") c, _ := json.Marshal(cmRes) By(fmt.Sprintf("configMap : %s", string(c))) @@ -113,14 +113,14 @@ func Test_Mutate_Sets(t *testing.T) { Expect(cmRes.GetLabels()["kyverno.key/copy-me"]).To(Equal("sample-value")) //CleanUp Resources - _ = e2eClient.CleanClusterPolicies(clPolGVR) + _ = e2eClient.CleanClusterPolicies(policyGVR) // Clear Namespace - _ = e2eClient.DeleteClusteredResource(nsGVR, tests.ResourceNamespace) + _ = e2eClient.DeleteClusteredResource(namespaceGVR, tests.ResourceNamespace) // Wait Till Deletion of Namespace err = e2e.GetWithRetry(1*time.Second, 15, func() error { - _, err := e2eClient.GetClusteredResource(nsGVR, tests.ResourceNamespace) + _, err := e2eClient.GetClusteredResource(namespaceGVR, tests.ResourceNamespace) if err != nil { return nil } @@ -132,6 +132,120 @@ func Test_Mutate_Sets(t *testing.T) { } } +func Test_Mutate(t *testing.T) { + RegisterTestingT(t) + if os.Getenv("E2E") == "" { + t.Skip("Skipping E2E Test") + } + + e2eClient, err := e2e.NewE2EClient() + Expect(err).To(BeNil()) + + for _, test := range tests { + By(fmt.Sprintf("Mutation Test: %s", test.TestDescription)) + + By("Deleting Cluster Policies...") + _ = e2eClient.CleanClusterPolicies(policyGVR) + + By("Deleting Resource...") + _ = e2eClient.DeleteNamespacedResource(test.ResourceGVR, test.ResourceNamespace, test.ResourceName) + + By("Deleting Namespace...") + By(fmt.Sprintf("Deleting Namespace: %s...", test.ResourceNamespace)) + _ = e2eClient.DeleteClusteredResource(namespaceGVR, test.ResourceNamespace) + + By("Wait Till Deletion of Namespace...") + err = e2e.GetWithRetry(1*time.Second, 15, func() error { + _, err := e2eClient.GetClusteredResource(namespaceGVR, test.ResourceNamespace) + if err != nil { + return nil + } + return fmt.Errorf("failed to delete namespace: %v", err) + }) + Expect(err).NotTo(HaveOccurred()) + + By(fmt.Sprintf("Creating Namespace: %s...", policyNamespace)) + _, err = e2eClient.CreateClusteredResourceYaml(namespaceGVR, newNamespaceYaml(test.ResourceNamespace)) + Expect(err).NotTo(HaveOccurred()) + + By("Wait Till Creation of Namespace...") + err = e2e.GetWithRetry(1*time.Second, 15, func() error { + _, err := e2eClient.GetClusteredResource(namespaceGVR, test.ResourceNamespace) + if err != nil { + return err + } + + return nil + }) + Expect(err).NotTo(HaveOccurred()) + + By("Creating Policy...") + _, err = e2eClient.CreateNamespacedResourceYaml(policyGVR, policyNamespace, test.PolicyRaw) + Expect(err).NotTo(HaveOccurred()) + + err = commonE2E.PolicyCreated(test.PolicyName) + Expect(err).NotTo(HaveOccurred()) + + By("Creating Resource...") + _, err = e2eClient.CreateNamespacedResourceYaml(test.ResourceGVR, test.ResourceNamespace, test.ResourceRaw) + Expect(err).NotTo(HaveOccurred()) + + By("Checking that resource is created...") + err = e2e.GetWithRetry(1*time.Second, 15, func() error { + _, err := e2eClient.GetNamespacedResource(test.ResourceGVR, test.ResourceNamespace, test.ResourceName) + if err != nil { + return err + } + + return nil + }) + Expect(err).NotTo(HaveOccurred()) + + res, err := e2eClient.GetNamespacedResource(test.ResourceGVR, test.ResourceNamespace, test.ResourceName) + Expect(err).NotTo(HaveOccurred()) + + actualJSON, err := json.Marshal(res) + Expect(err).NotTo(HaveOccurred()) + + var actual interface{} + + err = json.Unmarshal(actualJSON, &actual) + Expect(err).NotTo(HaveOccurred()) + + expected, err := rawYAMLToJSONInterface(test.ExpectedPatternRaw) + Expect(err).NotTo(HaveOccurred()) + + By("Validating created resource with the expected pattern...") + _, err = validate.ValidateResourceWithPattern(log.Log, actual, expected) + Expect(err).NotTo(HaveOccurred()) + + By("Deleting Cluster Policies...") + err = e2eClient.CleanClusterPolicies(policyGVR) + Expect(err).NotTo(HaveOccurred()) + + By("Deleting Resource...") + err = e2eClient.DeleteNamespacedResource(test.ResourceGVR, test.ResourceNamespace, test.ResourceName) + Expect(err).NotTo(HaveOccurred()) + + By("Deleting Namespace...") + err = e2eClient.DeleteClusteredResource(namespaceGVR, test.ResourceNamespace) + Expect(err).NotTo(HaveOccurred()) + + By("Wait Till Creation of Namespace...") + err = e2e.GetWithRetry(1*time.Second, 15, func() error { + _, err := e2eClient.GetClusteredResource(namespaceGVR, test.ResourceNamespace) + if err != nil { + return nil + } + return fmt.Errorf("failed to delete namespace: %v", err) + }) + + // Do not fail if waiting fails. Sometimes namespace needs time to be deleted. + + By("Done") + } +} + func Test_Mutate_Ingress(t *testing.T) { RegisterTestingT(t) if os.Getenv("E2E") == "" { @@ -144,14 +258,14 @@ func Test_Mutate_Ingress(t *testing.T) { nspace := ingressTests.testNamesapce By(fmt.Sprintf("Cleaning Cluster Policies")) - _ = e2eClient.CleanClusterPolicies(clPolGVR) + _ = e2eClient.CleanClusterPolicies(policyGVR) By(fmt.Sprintf("Deleting Namespace : %s", nspace)) - _ = e2eClient.DeleteClusteredResource(nsGVR, nspace) + _ = e2eClient.DeleteClusteredResource(namespaceGVR, nspace) // Wait Till Deletion of Namespace err = e2e.GetWithRetry(1*time.Second, 15, func() error { - _, err := e2eClient.GetClusteredResource(nsGVR, nspace) + _, err := e2eClient.GetClusteredResource(namespaceGVR, nspace) if err != nil { return nil } @@ -160,14 +274,14 @@ func Test_Mutate_Ingress(t *testing.T) { Expect(err).To(BeNil()) By(fmt.Sprintf("Creating mutate ClusterPolicy ")) - _, err = e2eClient.CreateClusteredResourceYaml(clPolGVR, ingressTests.cpol) + _, err = e2eClient.CreateClusteredResourceYaml(policyGVR, ingressTests.cpol) Expect(err).NotTo(HaveOccurred()) err = commonE2E.PolicyCreated(ingressTests.policyName) Expect(err).NotTo(HaveOccurred()) By(fmt.Sprintf("Creating Namespace %s", nspace)) - _, err = e2eClient.CreateClusteredResourceYaml(nsGVR, newNamespaceYaml(nspace)) + _, err = e2eClient.CreateClusteredResourceYaml(namespaceGVR, newNamespaceYaml(nspace)) Expect(err).NotTo(HaveOccurred()) for _, test := range ingressTests.tests { @@ -198,3 +312,66 @@ func Test_Mutate_Ingress(t *testing.T) { Expect(host).To(Equal("kuard.mycompany.com")) } } + +func rawYAMLToJSONInterface(y []byte) (interface{}, error) { + var temp, result interface{} + var err error + + err = UnmarshalYAML(y, &temp) + if err != nil { + return nil, err + } + + jsonRaw, err := json.Marshal(temp) + if err != nil { + return nil, err + } + + json.Unmarshal(jsonRaw, &result) + if err != nil { + return nil, err + } + + return result, nil +} + +// UnmarshalYAML unmarshals YAML to map[string]interface{} instead of map[interface{}]interface{}. +func UnmarshalYAML(in []byte, out interface{}) error { + var res interface{} + + if err := yaml.Unmarshal(in, &res); err != nil { + return err + } + *out.(*interface{}) = cleanupMapValue(res) + + return nil +} + +func cleanupInterfaceArray(in []interface{}) []interface{} { + res := make([]interface{}, len(in)) + for i, v := range in { + res[i] = cleanupMapValue(v) + } + return res +} + +func cleanupInterfaceMap(in map[interface{}]interface{}) map[string]interface{} { + res := make(map[string]interface{}) + for k, v := range in { + res[fmt.Sprintf("%v", k)] = cleanupMapValue(v) + } + return res +} + +func cleanupMapValue(v interface{}) interface{} { + switch v := v.(type) { + case []interface{}: + return cleanupInterfaceArray(v) + case map[interface{}]interface{}: + return cleanupInterfaceMap(v) + case string: + return v + default: + return fmt.Sprintf("%v", v) + } +} diff --git a/test/e2e/mutate/resources.go b/test/e2e/mutate/resources.go index 165f669431..c61e55dcc3 100644 --- a/test/e2e/mutate/resources.go +++ b/test/e2e/mutate/resources.go @@ -1,6 +1,12 @@ package mutate -import "fmt" +import ( + "fmt" + + "github.com/kyverno/kyverno/test/e2e" +) + +var podGVR = e2e.GetGVR("", "v1", "pods") func newNamespaceYaml(name string) []byte { ns := fmt.Sprintf(` @@ -205,3 +211,99 @@ spec: - hosts: - kuard `) + +var setRunAsNonRootTrue = []byte(` +apiVersion: kyverno.io/v1 +kind: ClusterPolicy +metadata: + name: set-runasnonroot-true +spec: + rules: + - name: set-runasnonroot-true + match: + resources: + kinds: + - Pod + mutate: + patchStrategicMerge: + spec: + securityContext: + runAsNonRoot: true + initContainers: + - (name): "*" + securityContext: + runAsNonRoot: true + containers: + - (name): "*" + securityContext: + runAsNonRoot: true +`) + +var podWithContainers = []byte(` +apiVersion: v1 +kind: Pod +metadata: + name: foo + namespace: test-mutate + labels: + app: foo +spec: + containers: + - image: abc:1.28 + name: busybox +`) + +var podWithContainersPattern = []byte(` +apiVersion: v1 +kind: Pod +metadata: + name: foo + namespace: test-mutate + labels: + app: foo +spec: + securityContext: + runAsNonRoot: true + containers: + - (name): "*" + securityContext: + runAsNonRoot: true +`) + +var podWithContainersAndInitContainers = []byte(` +apiVersion: v1 +kind: Pod +metadata: + name: foo + namespace: test-mutate1 + labels: + app: foo +spec: + containers: + - image: abc:1.28 + name: busybox + initContainers: + - image: bcd:1.29 + name: nginx +`) + +var podWithContainersAndInitContainersPattern = []byte(` +apiVersion: v1 +kind: Pod +metadata: + name: foo + namespace: test-mutate1 + labels: + app: foo +spec: + securityContext: + runAsNonRoot: true + containers: + - (name): "*" + securityContext: + runAsNonRoot: true + initContainers: + - (name): "*" + securityContext: + runAsNonRoot: true +`) diff --git a/test/e2e/utils.go b/test/e2e/utils.go index 81c1938ee3..4495065848 100644 --- a/test/e2e/utils.go +++ b/test/e2e/utils.go @@ -96,7 +96,8 @@ func (e2e *E2EClient) DeleteNamespacedResource(gvr schema.GroupVersionResource, // DeleteClusteredResource ... func (e2e *E2EClient) DeleteClusteredResource(gvr schema.GroupVersionResource, name string) error { - return e2e.Client.Resource(gvr).Delete(context.TODO(), name, metav1.DeleteOptions{}) + var force int64 = 0 + return e2e.Client.Resource(gvr).Delete(context.TODO(), name, metav1.DeleteOptions{GracePeriodSeconds: &force}) } // CreateNamespacedResource ...