Search code examples
yamlnushell

How to use Nushell to update value of an item within an array by filtering by a specific property with a given value?


I have the following YAML (Kubernetes Deployment):

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
      - name: myapp
        image: some-app:latest
        ports:
        - containerPort: 80

Using only Nushell, I would like to update the image value of the container named "myapp" to "some-app:1.0.0".

Any ideas how to do this?

I'm fully aware that I can use multiple other tools such as kubectl and/or yq etc. -- This is more of a general problem of how to filter and set values in an array using Nushell rather than solving the actual problem stated above. The sample above is mainly provided to have something "concrete" to use as an example.

I have tried a few solutions, but none of them really worked. My goal would be not to have to write a very complicated script to achieve this, since it feels like I'm missing something.

I have tried, for instance, the following:

open ./deployment.yaml | get spec.template.spec.containers | where name == "myapp" | update image "some-app:1.0.0" | collect | save ./deployment.yaml -f

But that replaces the entire content of the file with:

- name: myapp
  image: some-app:1.0.0
  ports:
  - containerPort: 80

Solution

  • Here's one way: update the table under spec.template.spec.containers by iterating over each of its items where you only update the image field if the value in name matches your criteria:

    open … | update spec.template.spec.containers {
      each {if $in.name == "myapp" {update image "some-app:1.0.0"} else {}}
    } | save …