mirror of
https://github.com/kyverno/kyverno.git
synced 2025-01-20 18:52:16 +00:00
3af0e461f0
* fix: deepcopy patched resource to avoid indirect reversal of its elements Signed-off-by: Vishal Choudhary <vishal.choudhary@nirmata.com> * fix: copy elements while reversing Signed-off-by: Vishal Choudhary <vishal.choudhary@nirmata.com> * fix: copy resources inside foreach Signed-off-by: Vishal Choudhary <vishal.choudhary@nirmata.com> * add test Signed-off-by: Jim Bugwadia <jim@nirmata.com> * add test Signed-off-by: Jim Bugwadia <jim@nirmata.com> --------- Signed-off-by: Vishal Choudhary <vishal.choudhary@nirmata.com> Signed-off-by: Jim Bugwadia <jim@nirmata.com> Co-authored-by: Jim Bugwadia <jim@nirmata.com>
66 lines
2 KiB
Go
66 lines
2 KiB
Go
package utils
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
engineapi "github.com/kyverno/kyverno/pkg/engine/api"
|
|
enginecontext "github.com/kyverno/kyverno/pkg/engine/context"
|
|
"github.com/kyverno/kyverno/pkg/engine/jsonutils"
|
|
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
|
)
|
|
|
|
func EvaluateList(jmesPath string, ctx enginecontext.EvalInterface) ([]interface{}, error) {
|
|
i, err := ctx.Query(jmesPath)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
l, ok := i.([]interface{})
|
|
if !ok {
|
|
return []interface{}{i}, nil
|
|
}
|
|
|
|
return l, nil
|
|
}
|
|
|
|
// InvertElements inverts the order of elements for patchStrategicMerge policies
|
|
// as kustomize patch reverses the order of patch resources.
|
|
func InvertElements(elements []interface{}) []interface{} {
|
|
elementsCopy := make([]interface{}, len(elements))
|
|
for i := range elements {
|
|
elementsCopy[i] = elements[len(elements)-i-1]
|
|
}
|
|
return elementsCopy
|
|
}
|
|
|
|
func AddElementToContext(ctx engineapi.PolicyContext, element interface{}, index, nesting int, elementScope *bool) error {
|
|
data, err := jsonutils.DocumentToUntyped(element)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if err := ctx.JSONContext().AddElement(data, index, nesting); err != nil {
|
|
return fmt.Errorf("failed to add element (%v) to JSON context: %w", element, err)
|
|
}
|
|
dataMap, ok := data.(map[string]interface{})
|
|
// We set scoped to true by default if the data is a map
|
|
// otherwise we do not do element scoped foreach unless the user
|
|
// has explicitly set it to true
|
|
scoped := ok
|
|
|
|
// If the user has explicitly provided an element scope
|
|
// we check if data is a map or not. In case it is not a map and the user
|
|
// has set elementscoped to true, we throw an error.
|
|
// Otherwise we set the value to what is specified by the user.
|
|
if elementScope != nil {
|
|
if *elementScope && !ok {
|
|
return fmt.Errorf("cannot use elementScope=true foreach rules for elements that are not maps, expected type=map got type=%T", data)
|
|
}
|
|
scoped = *elementScope
|
|
}
|
|
if scoped {
|
|
u := unstructured.Unstructured{}
|
|
u.SetUnstructuredContent(dataMap)
|
|
ctx.SetElement(u)
|
|
}
|
|
return nil
|
|
}
|