1
0
Fork 0
mirror of https://github.com/kyverno/kyverno.git synced 2024-12-14 11:57:48 +00:00
kyverno/pkg/engine/context/utils.go
Khaled Emara aafc4fe97e
fix(json-ctx): overwrite element each iteration (#10615)
Signed-off-by: Khaled Emara <khaled.emara@nirmata.com>
2024-07-05 15:06:48 +00:00

112 lines
2.6 KiB
Go

package context
import (
"reflect"
"k8s.io/apimachinery/pkg/runtime"
)
// AddJSONObject merges json data
func AddJSONObject(ctx Interface, data map[string]interface{}) error {
return ctx.addJSON(data, false)
}
func AddResource(ctx Interface, dataRaw []byte) error {
var data map[string]interface{}
if err := json.Unmarshal(dataRaw, &data); err != nil {
logger.Error(err, "failed to unmarshal the resource")
return err
}
return ctx.AddResource(data)
}
func AddOldResource(ctx Interface, dataRaw []byte) error {
var data map[string]interface{}
if err := json.Unmarshal(dataRaw, &data); err != nil {
logger.Error(err, "failed to unmarshal the resource")
return err
}
return ctx.AddOldResource(data)
}
func addToContext(ctx *context, data interface{}, overwriteMaps bool, tags ...string) error {
if v, err := convertStructs(data); err != nil {
return err
} else {
dataRaw := push(v, tags...)
return ctx.addJSON(dataRaw, overwriteMaps)
}
}
func clearLeafValue(data map[string]interface{}, tags ...string) bool {
if len(tags) == 0 {
return false
}
for i := 0; i < len(tags); i++ {
k := tags[i]
if i == len(tags)-1 {
delete(data, k)
return true
}
if nextMap, ok := data[k].(map[string]interface{}); ok {
data = nextMap
} else {
return false
}
}
return false
}
// convertStructs converts structs, and pointers-to-structs, to map[string]interface{}
func convertStructs(value interface{}) (interface{}, error) {
if value != nil {
v := reflect.ValueOf(value)
if v.Kind() == reflect.Struct {
return toUnstructured(value)
}
if v.Kind() == reflect.Ptr {
ptrVal := v.Elem()
if ptrVal.Kind() == reflect.Struct {
return toUnstructured(value)
}
}
}
return value, nil
}
func push(data interface{}, tags ...string) map[string]interface{} {
for i := len(tags) - 1; i >= 0; i-- {
data = map[string]interface{}{
tags[i]: data,
}
}
return data.(map[string]interface{})
}
// mergeMaps merges srcMap entries into destMap
func mergeMaps(srcMap, destMap map[string]interface{}, overwriteMaps bool) {
for k, v := range srcMap {
if nextSrcMap, ok := v.(map[string]interface{}); ok && !overwriteMaps {
if nextDestMap, ok := destMap[k].(map[string]interface{}); ok {
mergeMaps(nextSrcMap, nextDestMap, overwriteMaps)
} else {
destMap[k] = nextSrcMap
}
} else {
destMap[k] = v
}
}
}
// toUnstructured converts a struct with JSON tags to a map[string]interface{}
func toUnstructured(typedStruct interface{}) (map[string]interface{}, error) {
converter := runtime.DefaultUnstructuredConverter
u, err := converter.ToUnstructured(typedStruct)
return u, err
}