This is somewhat similar to this: jq: how to filter an array of objects based on values in an inner array? but extended
I have a list of values I want to filter out but it is not 1:1 match. It's contained match.
Having such input (from file or from pipe):
{
"namespace": "namespace1",
"name": "some-pod1",
"images": [
"acr1.azurecr.io/some_project/some_project_image@sha256:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"docker.io/istio/proxyv2@sha256:57621adeb78e67c52e34ec1676d1ae898b252134838d60298c7446d0964551cc"
],
"initImages": [
"docker.io/istio/proxyv2@sha256:57621adeb78e67c52e34ec1676d1ae898b252134838d60298c7446d0964551cc"
]
}
{
"namespace": "namespace1",
"name": "some-pod2",
"images": [
"acr1.azurecr.io/some_project/some_project_image@sha256:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"docker.io/istio/proxyv2@sha256:57621adeb78e67c52e34ec1676d1ae898b252134838d60298c7446d0964551cc"
],
"initImages": [
"docker.io/istio/proxyv2@sha256:57621adeb78e67c52e34ec1676d1ae898b252134838d60298c7446d0964551cc"
]
}
and such query
jq -r '.[] as $pods | ["kube-system", "kube-public", "gatekeeper-system", "istio-system", "istio-operator"] as $excludedNamespaces | ["istio", "registry.k8s", "mcr.microsoft.com", "azurecr.io"] as $excludedImages | $pods | select((.initImages[] | contains("docker.io")) or (.images[] | contains("docker.io"))) | select(.namespace as $in | $excludedNamespaces | index($in) | not) | del(.images | select(contains($excludedImages))) ' pods.json
I need to do something like:
del(.images | select(contains("istio") or select(contains("registry.k8s") or ...))
Since I have already $excludedImages list I want to process it and if I would require to change it then I can do this in one place. I tried as above by passing whole list to contains fuction but it doesn't work as expected. I always see "istio" images in the output.
I just want to remove those values from list. And if images list is empty (same will apply to initImages) then I want to remove whole object from output.
The thing is that docker enabled some throttling on the docker hub and I want to find pods which are still not migrated to our own registry rather than docker hub directly. But there are some images which are excluded from throttling like for example istio. It can be pulled directly from docker hub. And that's the whole idea.
So I prepared lists of namespaces to exclude and images to exclude. Namespaces are 1:1 match so there's no issue but images... they contain those hashes so they will always change and I cannot provide it directly.
Your help will be pretty much appreciated.
I just want to remove those values from list. And if images list is empty (same will apply to initImages) then I want to remove whole object from output.
For the select
condition inside del
, use any
on all items instead of separate disjunctions with or
. To delete the entire object in case of an empty array, a simple select
will suffice, which defines what to keep. Here, I've also included any
as you probably want to keep objects if either one of the arrays in images
and initImages
is non-empty (i.e. only delete if both are empty).
Note that all items in your sample input unfortunately do contain either "istio"
or "azurecr.io"
, so eventually both objects will be removed. If you update your sample data to better exemplify the different cases, I'll also adapt this response to it.
["istio", "registry.k8s", "mcr.microsoft.com", "azurecr.io"] as $excludedImages
| del(.images[], .initImages[] | select(any(.; contains($excludedImages[]))))
| select(any(.images, .initImages; . != []))