yamlyq

Use yq to add to a YAML file with anchors, aliases and arrays


I have a YAML file like this:

keys:
  - &node0001 ageXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
  - &node0002 ageYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY
creation_rules:
  - path_regex: secrets.yaml$
    key_groups:
      - age:
          - *node0001
          - *node0002

Now I want to add a new entry to the keys array and to the creation_rules array. I can't figure out what yq syntax to use to achieve this. So it becomes:

keys:
  - &node0001 ageXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
  - &node0002 ageYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY  
  - &node0003 ageZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ
creation_rules:
  - path_regex: secrets.yaml$
    key_groups:
      - age:
          - *node0001
          - *node0002
          - *node0003

I've tried:

yq '.keys += "ageZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ"' .sops.yaml

This adds a new entry to the keys array, but I don't know how to set the anchor. And:

yq '.creation_rules[0].key_groups[0].age += "node0003"' .sops.yaml

Also, this adds an entry to the list, but that entry should be an alias.

Any ideas how to achieve this? If all is possible with a single yq call, that would even be better.


Solution

  • Using mikefarah/yq, have a look at Anchor and Alias Operators in the manual. As for your example, perform both of your += operations in one go using the pipe operator |, then also set anchor and alias for the respective last items at .[-1].

    .keys += "ageZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ"
    | .creation_rules[0].key_groups[0].age += "node0003"
    | .keys[-1] anchor = .creation_rules[0].key_groups[0].age[-1]
    | .creation_rules[0].key_groups[0].age[-1] alias |= .
    

    Alternatively, to make it somewhat simpler, deal with .keys and its anchor together first, then rely on that when moving to the alias, combining it in a similar way.

    .keys += ("ageZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ" | . anchor = "node0003")
    | .creation_rules[0].key_groups[0].age += ((.keys[-1] | anchor) | . alias |= .)
    

    Both produce:

    keys:
      - &node0001 ageXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
      - &node0002 ageYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY
      - &node0003 ageZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ
    creation_rules:
      - path_regex: secrets.yaml$
        key_groups:
          - age:
              - *node0001
              - *node0002
              - *node0003