From acf11925993d9471c4df9cf9d871c0c7722c1294 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Charles-Edouard=20Br=C3=A9t=C3=A9ch=C3=A9?= Date: Thu, 31 Aug 2023 02:24:41 +0200 Subject: [PATCH] fix: kyverno test generated resource inconsistency (#8189) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix: kyverno test renerated resource inconsistency Signed-off-by: Charles-Edouard Brétéché * unit test Signed-off-by: Charles-Edouard Brétéché * fix Signed-off-by: Charles-Edouard Brétéché * makefile Signed-off-by: Charles-Edouard Brétéché --------- Signed-off-by: Charles-Edouard Brétéché --- Makefile | 1 - cmd/cli/kubectl-kyverno/test/test.go | 24 +++--- .../utils/unstructured/unstructured.go | 24 +++++- .../utils/unstructured/unstructured_test.go | 77 +++++++++++++++++++ 4 files changed, 106 insertions(+), 20 deletions(-) diff --git a/Makefile b/Makefile index 531b56e73c..095a1fbe82 100644 --- a/Makefile +++ b/Makefile @@ -728,7 +728,6 @@ test-cli-registry: $(CLI_BIN) test-cli-scenarios-to-cli: $(CLI_BIN) @$(CLI_BIN) test ./test/cli/scenarios_to_cli --registry - ############# # HELM TEST # ############# diff --git a/cmd/cli/kubectl-kyverno/test/test.go b/cmd/cli/kubectl-kyverno/test/test.go index 591aadd536..1f9d1195da 100644 --- a/cmd/cli/kubectl-kyverno/test/test.go +++ b/cmd/cli/kubectl-kyverno/test/test.go @@ -602,34 +602,28 @@ func isNamespacedPolicy(policyNames string) (bool, error) { // getAndCompareResource --> Get the patchedResource or generatedResource from the path provided by user // And compare this resource with engine generated resource. -func getAndCompareResource(path string, engineResource unstructured.Unstructured, isGit bool, policyResourcePath string, fs billy.Filesystem, isGenerate bool) string { +func getAndCompareResource(path string, actualResource unstructured.Unstructured, isGit bool, policyResourcePath string, fs billy.Filesystem, isGenerate bool) string { var status string resourceType := "patchedResource" if isGenerate { resourceType = "generatedResource" } - userResource, err := common.GetResourceFromPath(fs, path, isGit, policyResourcePath, resourceType) + expectedResource, err := common.GetResourceFromPath(fs, path, isGit, policyResourcePath, resourceType) if err != nil { fmt.Printf("Error: failed to load resources (%s)", err) return "" } if isGenerate { - matched, err := generate.ValidateResourceWithPattern(log.Log, engineResource.UnstructuredContent(), userResource.UnstructuredContent()) - if err != nil { - log.Log.V(3).Info("generatedResource mismatch", "error", err.Error()) + unstructuredutils.FixupGenerateLabels(actualResource) + unstructuredutils.FixupGenerateLabels(expectedResource) + } + equals, err := unstructuredutils.Compare(actualResource, expectedResource, true) + if err == nil { + if !equals { status = "fail" - } else if matched == "" { + } else { status = "pass" } - } else { - equals, err := unstructuredutils.Compare(engineResource, userResource, true) - if err == nil { - if !equals { - status = "fail" - } else { - status = "pass" - } - } } return status } diff --git a/cmd/cli/kubectl-kyverno/utils/unstructured/unstructured.go b/cmd/cli/kubectl-kyverno/utils/unstructured/unstructured.go index bf4e4245a7..f3e461a9a3 100644 --- a/cmd/cli/kubectl-kyverno/utils/unstructured/unstructured.go +++ b/cmd/cli/kubectl-kyverno/utils/unstructured/unstructured.go @@ -1,6 +1,8 @@ package unstructured import ( + "strings" + jsonpatch "github.com/evanphx/json-patch/v5" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" ) @@ -45,16 +47,30 @@ func Tidy(obj unstructured.Unstructured) unstructured.Unstructured { } } -func Compare(a, b unstructured.Unstructured, tidy bool) (bool, error) { +func FixupGenerateLabels(obj unstructured.Unstructured) { + tidy := map[string]string{ + "app.kubernetes.io/managed-by": "kyverno", + } + if labels := obj.GetLabels(); labels != nil { + for k, v := range labels { + if !strings.HasPrefix(k, "generate.kyverno.io/") { + tidy[k] = v + } + } + } + obj.SetLabels(tidy) +} + +func Compare(a, e unstructured.Unstructured, tidy bool) (bool, error) { if tidy { a = Tidy(a) - b = Tidy(b) + e = Tidy(e) } - expected, err := a.MarshalJSON() + actual, err := a.MarshalJSON() if err != nil { return false, err } - actual, err := b.MarshalJSON() + expected, err := e.MarshalJSON() if err != nil { return false, err } diff --git a/cmd/cli/kubectl-kyverno/utils/unstructured/unstructured_test.go b/cmd/cli/kubectl-kyverno/utils/unstructured/unstructured_test.go index 3dbfbdad2c..6fdf22b1da 100644 --- a/cmd/cli/kubectl-kyverno/utils/unstructured/unstructured_test.go +++ b/cmd/cli/kubectl-kyverno/utils/unstructured/unstructured_test.go @@ -184,3 +184,80 @@ func TestCompare(t *testing.T) { }) } } + +func TestFixupGenerateLabels(t *testing.T) { + tests := []struct { + name string + obj unstructured.Unstructured + want unstructured.Unstructured + }{{ + name: "not set", + }, { + name: "empty", + obj: unstructured.Unstructured{Object: map[string]interface{}{}}, + want: unstructured.Unstructured{Object: map[string]interface{}{ + "metadata": map[string]interface{}{ + "labels": map[string]interface{}{ + "app.kubernetes.io/managed-by": "kyverno", + }, + }, + }}, + }, { + name: "with label", + obj: unstructured.Unstructured{ + Object: map[string]interface{}{ + "metadata": map[string]interface{}{ + "labels": map[string]interface{}{ + "app.kubernetes.io/managed-by": "kyverno", + }, + }, + }, + }, + want: unstructured.Unstructured{ + Object: map[string]interface{}{ + "metadata": map[string]interface{}{ + "labels": map[string]interface{}{ + "app.kubernetes.io/managed-by": "kyverno", + }, + }, + }, + }, + }, { + name: "with generate labels", + obj: unstructured.Unstructured{ + Object: map[string]interface{}{ + "metadata": map[string]interface{}{ + "labels": map[string]interface{}{ + "foo": "bar", + "generate.kyverno.io/policy-name": "add-networkpolicy", + "generate.kyverno.io/policy-namespace": "", + "generate.kyverno.io/rule-name": "default-deny", + "generate.kyverno.io/trigger-group": "", + "generate.kyverno.io/trigger-kind": "Namespace", + "generate.kyverno.io/trigger-name": "hello-world-namespace", + "generate.kyverno.io/trigger-namespace": "default", + "generate.kyverno.io/trigger-version": "v1", + }, + }, + }, + }, + want: unstructured.Unstructured{ + Object: map[string]interface{}{ + "metadata": map[string]interface{}{ + "labels": map[string]interface{}{ + "app.kubernetes.io/managed-by": "kyverno", + "foo": "bar", + }, + }, + }, + }, + }} + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + FixupGenerateLabels(tt.obj) + if !reflect.DeepEqual(tt.obj, tt.want) { + t.Errorf("FixupGenerateLabels() = %v, want %v", tt.obj, tt.want) + } + }) + } +}