Simplified from my use case a bit, I'm trying to find all Kubernetes deployments whose image (you can assume the container at index 0) is contained in a list of images.
I understand I can subtract two arrays to get the the intersection of these, but what I'm left with is just the list of images; I'd like to keep the full Deployment spec for matches.
Example:
deployments.yaml:
apiVersion: v1
kind: List
metadata:
resourceVersion: ""
items:
- apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.14.2
ports:
- containerPort: 80
- apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp-deployment
labels:
app: myapp
spec:
replicas: 1
selector:
matchLabels:
app: myapp
template:
metadata:
labels:
app: myapp
spec:
containers:
- name: myapp
image: myapp:0.1.2
ports:
- containerPort: 8080
images.yaml
searchItems:
- nginx:1.13.1
- nginx:1.14.2
Using this, I can get the list of images for Deployments using one of the images in my list:
yq ea '[.items[].spec.template.spec.containers[0].image] - ([.items[].spec.template.spec.containers[0].image] - .searchItems) | unique' deployments.yaml images.yaml
Output:
- nginx:1.14.2
I'd like to get the entire Deployment object though, not just the image, for any matches.
I am using yq here, but any solution using jq would work fine for me too. I can also solve this by other means, like scripting it one by one, but I am curious about the solution with yq/jq.
You could just map
the .items
array to contain only those items that match.
Using mikefarah/yq:
yq '
(load("images.yaml").searchItems | unique) as $q | .items
| map(select(.spec.template.spec.containers[0].image == $q[]))
' deployments.yaml
Using kislyuk/yq:
yq -y '
(input.searchItems | unique) as $q | .items
| map(select(.spec.template.spec.containers[0].image == $q[]))
' deployments.yaml images.yaml
Using itchyny/gojq:
gojq --yaml-input --yaml-output '
(input.searchItems | unique) as $q | .items
| map(select(.spec.template.spec.containers[0].image == $q[]))
' deployments.yaml images.yaml