package
0.5.9
Repository: https://github.com/kusionstack/karpor.git
Documentation: pkg.go.dev

# README

JSON Extracter

Extract specific field from JSON and output not only the field value but also its upstream structure.

A typical use case is to trim k8s objects in TransformingInformer to save informer memory.

Please refer to JSONPath Support to see JSONPath usage.

Example

Code:

package main

import (
	"encoding/json"
	"fmt"

	"kusionstack.io/kube-utils/jsonextracter"
)

var pod = []byte(`{
    "apiVersion": "v1",
    "kind": "Pod",
    "metadata": {
        "labels": {
            "name": "pause",
            "app": "pause"
        },
        "name": "pause",
        "namespace": "default"
    },
    "spec": {
        "containers": [
            {
                "image": "registry.k8s.io/pause:3.8",
                "imagePullPolicy": "IfNotPresent",
                "name": "pause1"
            },
            {
                "image": "registry.k8s.io/pause:3.8",
                "imagePullPolicy": "IfNotPresent",
                "name": "pause2"
            }
        ]
    }
}`)

func printJSON(data interface{}) {
	bytes, _ := json.Marshal(data)
	fmt.Println(string(bytes))
}

func main() {
	var podData map[string]interface{}
	json.Unmarshal(pod, &podData)

	kindPath := "{.kind}"
	kindExtracter, _ := jsonextracter.BuildExtracter(kindPath, false)

	kind, _ := kindExtracter.Extract(podData)
	printJSON(kind)

	nameImagePath := "{.spec.containers[*]['name', 'image']}"
	nameImageExtracter, _ := jsonextracter.BuildExtracter(nameImagePath, false)

	nameImage, _ := nameImageExtracter.Extract(podData)
	printJSON(nameImage)

	merged, _ := jsonextracter.Merge([]jsonextracter.Extracter{kindExtracter, nameImageExtracter}, podData)
	printJSON(merged)
}

Output:

{"kind":"Pod"}
{"spec":{"containers":[{"image":"registry.k8s.io/pause:3.8","name":"pause1"},{"image":"registry.k8s.io/pause:3.8","name":"pause2"}]}}
{"kind":"Pod","spec":{"containers":[{"image":"registry.k8s.io/pause:3.8","name":"pause1"},{"image":"registry.k8s.io/pause:3.8","name":"pause2"}]}}

Note

The merge behavior of the jsonextracter.Merge on the list is replacing. Therefore, if you retrieve the container name and image separately and merge them, the resulting output will not contain the image.

Code:

    ...
	namePath := "{.spec.containers[*].name}"
	nameExtracter, _ := jsonextracter.BuildExtracter(namePath, false)

	imagePath := "{.spec.containers[*].image}"
	imageExtracter, _ := jsonextracter.BuildExtracter(imagePath, false)

	merged, _ = jsonextracter.Merge([]jsonextracter.Extracter{imageExtracter, nameExtracter}, podData)
	printJSON(merged)
    ...

Output:

{"spec":{"containers":[{"name":"pause1"},{"name":"pause2"}]}}