From 6632ed1a234904d17b0b4ff950e78ec293954e5d Mon Sep 17 00:00:00 2001 From: Radostin Stoyanov Date: Wed, 23 Oct 2024 09:49:52 +0100 Subject: [PATCH] Recursively add metadata JSON fields to the tree MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Some annotations contain a JSON string. This string may include nested arrays and maps. This patch updates addPodInfoToTree() to recursively add these fields to the output tree using pretty print. Before: ├── kubectl.kubernetes.io/last-applied-configuration │ ├── metadata: map[annotations:map[] name:counter-pod namespace:default] │ ├── spec: map[containers:[map[args:[-c i=0; while true; do echo $i; i=$(expr $i + 1); sleep 1; done] command:[sh] image:busybox:latest name:counter-container]]] After: ├── kubectl.kubernetes.io/last-applied-configuration │ ├── apiVersion: v1 │ ├── kind: Pod │ ├── metadata: │ │ ├── annotations: │ │ ├── name: counter-pod │ │ └── namespace: default │ └── spec: │ └── containers: [ │ ├── [0]: │ │ ├── args: [ │ │ │ ├── [0]: -c │ │ │ ├── [1]: i=0; while true; do echo $i; i=$(expr $i + 1); sleep 1; done │ │ │ └── ] │ │ ├── command: [ │ │ │ ├── [0]: sh │ │ │ └── ] │ │ ├── image: busybox:latest │ │ └── name: counter-container │ └── ] Signed-off-by: Radostin Stoyanov --- internal/tree.go | 41 ++++++++++++++++++++++++++++++++++++++--- 1 file changed, 38 insertions(+), 3 deletions(-) diff --git a/internal/tree.go b/internal/tree.go index 6cff2b45..c9600bc0 100644 --- a/internal/tree.go +++ b/internal/tree.go @@ -335,9 +335,8 @@ func addPodInfoToTree(tree treeprint.Tree, info *checkpointInfo) { continue } localTree := annotationTree.AddBranch(key) - for labelKey := range local { - localTree.AddBranch(fmt.Sprintf("%s: %s", labelKey, local[labelKey])) - } + // Recursively add array/map JSON fields to the tree + addMapToTree(localTree, local) case "io.kubernetes.cri-o.Volumes": // We know that some annotations contain a JSON string we can pretty print var local []mountAnnotations @@ -359,3 +358,39 @@ func addPodInfoToTree(tree treeprint.Tree, info *checkpointInfo) { } } } + +func addMapToTree(tree treeprint.Tree, data map[string]interface{}) { + for key, value := range data { + switch v := value.(type) { + case map[string]interface{}: + // Recursively add nested maps + subTree := tree.AddBranch(fmt.Sprintf("%s:", key)) + addMapToTree(subTree, v) + case []interface{}: + // Handle arrays recursively + arrayTree := tree.AddBranch(fmt.Sprintf("%s: [", key)) + addArrayToTree(arrayTree, v) + arrayTree.AddBranch("]") + default: + tree.AddBranch(fmt.Sprintf("%s: %v", key, v)) + } + } +} + +func addArrayToTree(tree treeprint.Tree, data []interface{}) { + for i, value := range data { + switch v := value.(type) { + case map[string]interface{}: + // Recursively add maps inside arrays + subTree := tree.AddBranch(fmt.Sprintf("[%d]:", i)) + addMapToTree(subTree, v) + case []interface{}: + // Recursively add arrays inside arrays + subArrayTree := tree.AddBranch(fmt.Sprintf("[%d]: [", i)) + addArrayToTree(subArrayTree, v) + subArrayTree.AddBranch("]") + default: + tree.AddBranch(fmt.Sprintf("[%d]: %v", i, v)) + } + } +}