diff --git a/npc/json.go b/npc/json.go index fd975554..c5946718 100644 --- a/npc/json.go +++ b/npc/json.go @@ -4,7 +4,56 @@ import ( "encoding/json" ) +// Return JSON suitable for logging an API object. func js(v interface{}) string { + // Get the raw JSON a, _ := json.Marshal(v) + // Convert this back into a tree of key-value maps + var m map[string]interface{} + if err := json.Unmarshal(a, &m); err != nil { + // If that didn't work, just return the raw version + return string(a) + } + // Trim some bulk, and potentially sensitive areas + withMap(m["metadata"], func(status map[string]interface{}) { + delete(status, "ownerReferences") + }) + withMap(m["spec"], func(spec map[string]interface{}) { + delete(spec, "tolerations") + delete(spec, "volumes") + rangeSlice(spec["containers"], func(container map[string]interface{}) { + delete(container, "args") + delete(container, "command") + delete(container, "env") + delete(container, "livenessProbe") + delete(container, "resources") + delete(container, "securityContext") + delete(container, "volumeMounts") + }) + }) + withMap(m["status"], func(status map[string]interface{}) { + delete(status, "containerStatuses") + }) + // Now marshall what's left to JSON + a, _ = json.Marshal(m) return string(a) } + +// Helper function: operate on a map node from a tree of key-value maps +func withMap(m interface{}, f func(map[string]interface{})) { + if v, ok := m.(map[string]interface{}); ok { + f(v) + } +} + +// Helper function: operate on all nodes under i which is a slice in a +// tree of key-value maps +func rangeSlice(i interface{}, f func(map[string]interface{})) { + if s, ok := i.([]interface{}); ok { + for _, v := range s { + if m, ok := v.(map[string]interface{}); ok { + f(m) + } + } + } +}