Hi I would like to update a yaml like string into a yaml
i do have the following yaml file argocd.yaml
---
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
namespace: mynamespace
name:my-app
spec:
project: xxx
destination:
server: xxx
namespace: xxx
source:
repoURL: xxx
targetRevision: dev
path: yyy
helm:
values: |-
image:
tag: "mytag"
repository: "myrepo-image"
registry: "myregistry"
and ultimatively I want to replace the value of tag. Unfortunately this is a yaml in a yaml configuration.
My Idea so far was:
# get the yaml in the yaml and save as yaml
yq e .spec.source.helm.values argocd.yaml > helm_values.yaml
# replace the tag value
yq e '.image.tag=newtag' helm_values.yaml
and then I want to add the content of the helm_values.yaml
file as string into the argocd.yaml
I tried it the following but I can't get it work
# idea 1
###################
yq eval 'select(fileIndex==0).spec.source.helm.values = select(fileIndex==1) | select(fileIndex==0)' argocd.yaml values.yaml
# this does not update the values but add back slashes
values: "\nimage:\n tag: \"mytag\"\n repository: \"myrepo-image\"\n registry: \"myregistry\""
# idea 2
##################
yq eval '.spec.source.helm.values = "'"$(< values.yaml)"'"' argocd.yam
here i am not getting the quite escape correctly and it fails with
Error: Parsing expression: Lexer error: could not match text starting at 2:9 failing at 2:12.
unmatched text: "newtag"
Any Idea how to solve this or is there a better way to replace a value in such a file? I am using yq from https://mikefarah.gitbook.io/yq
Your second approach can work, but in a roundabout way, as mikefarah/yq does not support updating multi-line block literals yet
One way to solve this, with the existing constructs would be to do below, without having to create a temporary YAML file
o="$(yq e '.spec.source.helm.values' yaml | yq e '.image.tag="footag"' -)" yq e -i '.spec.source.helm.values = strenv(o)' argocd.yaml
The solution above relies on passing a user defined variable as a string, that can be used in the yq expression using strenv()
. The value for the variable o
is set by using Command substitution $(..) feature in bash. Inside the substitution construct, we extract the block literal content as a YAML object and apply another filter to modify the tag as we need. So at the end of substitution, the value of o
will be set to
image:
tag: "footag"
repository: "myrepo-image"
registry: "myregistry"
The obtained result above is now set to the value of .spec.source.helm.values
directly which the inplace modification flag (-i
) to apply the changes on the actual file
I have raised a feature request in the author's repo to provide a simpler way to do this Support for updating YAML multi-line strings #974