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 }