1
0
Fork 0
mirror of https://github.com/kyverno/kyverno.git synced 2025-03-06 16:06:56 +00:00
kyverno/pkg/engine/context/utils.go
Jim Bugwadia 46f02a8ba7
optimize JSON context processing using in-memory maps (#8322)
* optimize JSON context processing using in memory maps

Signed-off-by: Jim Bugwadia <jim@nirmata.com>

* fix excessive logs

Signed-off-by: Jim Bugwadia <jim@nirmata.com>

* fix mutate resource diff

Signed-off-by: Jim Bugwadia <jim@nirmata.com>

* uncomment tests

Signed-off-by: Jim Bugwadia <jim@nirmata.com>

* copy resource, as it can be modified

Signed-off-by: Jim Bugwadia <jim@nirmata.com>

* clear prior resource to prevent mutating original

Signed-off-by: Jim Bugwadia <jim@nirmata.com>

* linter fix

Signed-off-by: Jim Bugwadia <jim@nirmata.com>

* fix ImageInfo to unstructured conversion

Signed-off-by: Jim Bugwadia <jim@nirmata.com>

* fix custom image extractors

Signed-off-by: Jim Bugwadia <jim@nirmata.com>

* do not update mutated resource in JSON context

Signed-off-by: Jim Bugwadia <jim@nirmata.com>

* address review comments

Signed-off-by: Jim Bugwadia <jim@nirmata.com>

---------

Signed-off-by: Jim Bugwadia <jim@nirmata.com>
Signed-off-by: shuting <shuting@nirmata.com>
Co-authored-by: Vishal Choudhary <sendtovishalchoudhary@gmail.com>
Co-authored-by: shuting <shuting@nirmata.com>
2023-12-04 07:35:36 +00:00

112 lines
2.5 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)
}
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{}, tags ...string) error {
if v, err := convertStructs(data); err != nil {
return err
} else {
dataRaw := push(v, tags...)
return ctx.addJSON(dataRaw)
}
}
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{}) {
for k, v := range srcMap {
if nextSrcMap, ok := v.(map[string]interface{}); ok {
if nextDestMap, ok := destMap[k].(map[string]interface{}); ok {
mergeMaps(nextSrcMap, nextDestMap)
} 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
}