mirror of
https://github.com/kyverno/kyverno.git
synced 2024-12-14 11:57:48 +00:00
fix: kyverno test doesn't fail when mutated YAML != patchedResource YAML (#8183)
* fix: kyverno test doesn't fail when mutated YAML != patchedResource YAML Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com> * fixes Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com> * fix Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com> * fix Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com> * fix Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com> * makefile Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com> --------- Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com>
This commit is contained in:
parent
fb166d4f0e
commit
31bed97806
1 changed files with 65 additions and 8 deletions
|
@ -6,6 +6,7 @@ import (
|
|||
"regexp"
|
||||
"strings"
|
||||
|
||||
jsonpatch "github.com/evanphx/json-patch/v5"
|
||||
"github.com/go-git/go-billy/v5"
|
||||
"github.com/kyverno/kyverno/api/kyverno"
|
||||
kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1"
|
||||
|
@ -599,6 +600,37 @@ func isNamespacedPolicy(policyNames string) (bool, error) {
|
|||
return regexp.MatchString("^[a-z]*/[a-z]*", policyNames)
|
||||
}
|
||||
|
||||
func tidyObject(obj interface{}) interface{} {
|
||||
switch typedPatternElement := obj.(type) {
|
||||
case map[string]interface{}:
|
||||
tidy := map[string]interface{}{}
|
||||
for k, v := range typedPatternElement {
|
||||
v = tidyObject(v)
|
||||
if v != nil {
|
||||
tidy[k] = v
|
||||
}
|
||||
}
|
||||
if len(tidy) == 0 {
|
||||
return nil
|
||||
}
|
||||
return tidy
|
||||
case []interface{}:
|
||||
var tidy []interface{}
|
||||
for _, v := range typedPatternElement {
|
||||
v = tidyObject(v)
|
||||
if v != nil {
|
||||
tidy = append(tidy, v)
|
||||
}
|
||||
}
|
||||
if len(tidy) == 0 {
|
||||
return nil
|
||||
}
|
||||
return tidy
|
||||
default:
|
||||
return obj
|
||||
}
|
||||
}
|
||||
|
||||
// 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 {
|
||||
|
@ -607,18 +639,43 @@ func getAndCompareResource(path string, engineResource unstructured.Unstructured
|
|||
if isGenerate {
|
||||
resourceType = "generatedResource"
|
||||
}
|
||||
|
||||
userResource, err := common.GetResourceFromPath(fs, path, isGit, policyResourcePath, resourceType)
|
||||
if err != nil {
|
||||
fmt.Printf("Error: failed to load resources\nCause: %s\n", err)
|
||||
fmt.Printf("Error: failed to load resources (%s)", err)
|
||||
return ""
|
||||
}
|
||||
matched, err := generate.ValidateResourceWithPattern(log.Log, engineResource.UnstructuredContent(), userResource.UnstructuredContent())
|
||||
if err != nil {
|
||||
log.Log.V(3).Info(resourceType+" mismatch", "error", err.Error())
|
||||
status = "fail"
|
||||
} else if matched == "" {
|
||||
status = "pass"
|
||||
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())
|
||||
status = "fail"
|
||||
} else if matched == "" {
|
||||
status = "pass"
|
||||
}
|
||||
} else {
|
||||
userResource = unstructured.Unstructured{Object: tidyObject(userResource.UnstructuredContent()).(map[string]interface{})}
|
||||
expected, err := userResource.MarshalJSON()
|
||||
if err != nil {
|
||||
fmt.Printf("Error: failed to convert patched resource to json (%s)\n", err)
|
||||
return status
|
||||
}
|
||||
engineResource = unstructured.Unstructured{Object: tidyObject(engineResource.UnstructuredContent()).(map[string]interface{})}
|
||||
actual, err := engineResource.MarshalJSON()
|
||||
if err != nil {
|
||||
fmt.Printf("Error: failed to convert engine resource to json (%s)\n", err)
|
||||
return status
|
||||
}
|
||||
patch, err := jsonpatch.CreateMergePatch(actual, expected)
|
||||
if err != nil {
|
||||
fmt.Printf("Error: failed to calculate diff between patched and engine resources (%s)\n", err)
|
||||
return status
|
||||
}
|
||||
if len(patch) > 2 {
|
||||
log.Log.V(3).Info("patchedResource mismatch", "actual", string(actual), "expected", string(expected), "patch", string(patch))
|
||||
status = "fail"
|
||||
} else {
|
||||
status = "pass"
|
||||
}
|
||||
}
|
||||
return status
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue