I'm going through a Kubernetes tutorial and am using jq to filter some of kubectl's exhaustive output.
One task that's coming up is to show what images are deployed to what pods, using kubectl get pods
. So far I have this:
kubectl get pods -o json | jq '.items[]|[.metadata.name,.spec.containers[].image]'
This gets me output like the this:
[
"kubernetes-bootcamp-5485cc6795-4blsd",
"gcr.io/google-samples/kubernetes-bootcamp:v1"
]
[
"kubernetes-bootcamp-5485cc6795-k824z",
"gcr.io/google-samples/kubernetes-bootcamp:v1"
]
This is nice, but if I get curious and want to see more information about a specific pod, I'd need to use its index in the .items
array. That's fine here where there are only two items in total, but I imagine a production Kubernetes cluster might have thousands. Is there any way I can include the item's index in the output? In other words, I want to see:
[
0,
"kubernetes-bootcamp-5485cc6795-4blsd",
"gcr.io/google-samples/kubernetes-bootcamp:v1"
]
[
1,
"kubernetes-bootcamp-5485cc6795-k824z",
"gcr.io/google-samples/kubernetes-bootcamp:v1"
]
I had tried using path(.)
in the array constructor, but it just results in an empty array instead of the path to that item. I've been reading through the jq man page but so far I'm stumped. Any help would be appreciated!
Here's a snippet from kubectl that can be used to reproduce the output in my question.
{
"items": [
{
"metadata": {
"name": "kubernetes-bootcamp-5485cc6795-4blsd"
},
"spec": {
"containers": [
{
"image": "gcr.io/google-samples/kubernetes-bootcamp:v1"
}
]
}
},
{
"metadata": {
"name": "kubernetes-bootcamp-5485cc6795-k824z"
},
"spec": {
"containers": [
{
"image": "gcr.io/google-samples/kubernetes-bootcamp:v1"
}
]
}
}
]
}
If you save this to output.json
for example, you can reproduce my problem with the command
cat output.json | jq '.items[]|[.metadata.name,.spec.containers[].image]'
You could use the to_entries
filter (see the manual) which turns an object into an array of objects containing each field's key and value. However, if applied to an array, the array's indices will be used as keys instead:
.items | to_entries[]
{
"key": 0,
"value": ...
}
{
"key": 1,
"value": ...
}
Thus, just create your output as before but with .key
and .value
in mind:
.items | to_entries[] | [.key, .value.metadata.name, .value.spec.containers[].image]
# or
.items | to_entries[] | [.key, (.value | .metadata.name, .spec.containers[].image)]
[
0,
"kubernetes-bootcamp-5485cc6795-4blsd",
"gcr.io/google-samples/kubernetes-bootcamp:v1"
]
[
1,
"kubernetes-bootcamp-5485cc6795-k824z",
"gcr.io/google-samples/kubernetes-bootcamp:v1"
]
You could create an index variable, e.g. as follows:
range(0; .items|length) as $i | .items[$i] | [$i, .metadata.name, .spec.containers[].image]
Alternatively, you could define a generic enumerate
function and use it as follows:
def enumerate(s): foreach s as $x (-1; .+1; [., $x]);
enumerate(.items[] | [.metadata.name, .spec.containers[].image]) | [first] + last
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With