Answer a question

I have a yml file called output.yml which contains a K8s Service, Deployment and Ingress resources like so (lots of fields omitted for brevity):

apiVersion: v1
kind: Service
metadata:
  labels:
    app.kubernetes.io/name: app-name
    app.kubernetes.io/instance: instance-name
spec:
  selector:
    app.kubernetes.io/name: app-name
    app.kubernetes.io/instance: instance-name
---
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app.kubernetes.io/name: app-name
    app.kubernetes.io/instance: instance-name
spec:
  selector:
    matchLabels:
      app.kubernetes.io/name: app-name
      app.kubernetes.io/instance: instance-name
  template:
    metadata:
      labels:
        app.kubernetes.io/name: app-name
        app.kubernetes.io/instance: instance-name
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  labels:
    app.kubernetes.io/name: app-name
    app.kubernetes.io/instance: instance-name

What I would like to do is, for all occurrences of where the key = app.kubernetes.io/instance, replace all values of instance-name with a different value say app-instance-name2. I have tried several things like using the select and has operators like so: yq eval '(.. | select(has("app.kubernetes.io/instance"))' but it returns all map keys instead of just the one I want to update and then I'm not really sure where to go from there.

At the moment, I am just updating each individual value like so:

yq e '.metadata.labels["app.kubernetes.io/instance"] = strenv(INSTANCE_NAME)' -i output.yml
yq e 'select(.kind == "Service").spec.selector["app.kubernetes.io/instance"] = strenv(INSTANCE_NAME)' -i output.yml
yq e 'select(.kind == "Deployment").spec.selector.matchLabels["app.kubernetes.io/instance"] = strenv(INSTANCE_NAME)' -i output.yml
yq e 'select(.kind == "Deployment").spec.template.metadata.labels["app.kubernetes.io/instance"] = strenv(INSTANCE_NAME)' -i output.yml

which works but is pretty verbose so I'd like if there was a succinct single line option?

I am using yq version 4.17.2 from https://mikefarah.gitbook.io/yq

Any advice is much appreciated

Answers

It can be accomplished by doing a recursive decent to identify keys matching your string and update their value part using |=

yq e '(..|select(has("app.kubernetes.io/instance")).["app.kubernetes.io/instance"]) |= "app-instance-name2"' output.yml

Starting v4.18.1, the eval flag is the default action, so the e flag can be avoided

Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐