'How to parse json format output of : kubectl get pods using jsonpath

How to parse the json to retrieve a field from output of

kubectl get pods -o json

From the command line I need to obtain the system generated container name from a google cloud cluster ... Here are the salient bits of json output from above command : enter image description here

click here to see entire json output

So the top most json key is an array : items[] followed by metadata.labels.name where the search critera value of that compound key is "web" (see above image green marks). On a match, I then need to retrieve field

.items[].metadata.name  

which so happens to have value :

web-controller-5e6ij   // I need to retrieve this value

Here are docs on jsonpath

I want to avoid text parsing output of

kubectl get pods

which is

NAME                     READY     STATUS    RESTARTS   AGE
mongo-controller-h714w   1/1       Running   0          12m
web-controller-5e6ij     1/1       Running   0          9m

Following will correctly parse this get pods command yet I feel its too fragile

kubectl get pods | tail -1 | cut -d' ' -f1


Solution 1:[1]

After much battling this one liner does retrieve the container name :

kubectl get pods -o=jsonpath='{.items[?(@.metadata.labels.name=="web")].metadata.name}'

when this is the known search criteria :

items[].metadata.labels.name  == "web"

and this is the desired field to retrieve

items[].metadata.name  :  "web-controller-5e6ij"

Solution 2:[2]

If you want to filter by labels. You could just use the kubectl -l flag. The following will do the same:

kubectl get pods -l name=web -o=jsonpath='{.items..metadata.name}'

Solution 3:[3]

In addition to Scott Stensland answer, a way to format your results:

kubectl get pods -o=jsonpath='{range .items[?(@.metadata.labels.name=="web")]}{.metadata.name}{"/n"}'

This add newlines. You can also do {", "} to output comma with space.

Another solution:

Use JQ to get a nicely formatted json result:

kubectl get pods -o json | jq -r '.items[] | [filter] | [formatted result]' | jq -s '.'

Example of [filter]:

select(.metadata.labels.name=="web")

Example of [formatted result] (you can add more fields if your want):

{name: .metadata.name}

jq -s '.', for putting result objects in array.

To wrap it up:

kubectl get pods -o json | jq -r '.items[] | select(.metadata.labels.name=="web") | {name: .metadata.name}' | jq -s '.'

Then afterwards you can use this json data to get the desired output result.

Solution 4:[4]

There is a super easy way to do this with jq

Just pipe your output with parameters you have already given.

As your searched value is positioned as second, please put index in brackets. No index given, means list all fitting.

<output> | jq .items[1].metadata.name 

Example you have given ( i have put -r for raw output with no quotation)

curl -s https://gist.githubusercontent.com/scottstensland/278ce94dc6873aa54e44/raw/b2fc423bc4063a7cd16825f612e19d9a7faf5699/output%2520of%2520kubectl%2520get%2520pods%2520%2520-o%2520json| jq .items[1].metadata.name -r
web-controller-5e6ij

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 cizixs
Solution 2 P....
Solution 3
Solution 4