From 0205adcedb596312a68eb796e0ecd57e42b5bf75 Mon Sep 17 00:00:00 2001 From: Bryan Boreham Date: Wed, 22 Nov 2017 11:17:50 +0000 Subject: [PATCH] Trim the JSON logged for Kubernetes objects by weave-npc Remove things like "args" and "env" which bulk the logs, aren't relevant to the function of weave-npc, and may include sensitive information. Use a black-list rather than a white-list because we can't be sure what information will be necessary in future. --- npc/json.go | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) 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) + } + } + } +}