yq - issue adding yaml into yaml



你好,我想把一个类似yaml的字符串更新为一个yaml

我确实有以下yaml文件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"

,最终我想替换tag的值。不幸的是,这是一个yaml配置中的yaml。

到目前为止我的想法是:

  1. 将value提取到另一个values.yaml
  2. 更新标签
  3. 计算参数中的值。使用值。Yaml所以起作用的是:
# 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

,然后我想将helm_values.yaml文件的内容作为字符串添加到argocd.yaml中我试了下面的方法,但我不能让它工作

# 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"

任何想法如何解决这个问题,或者有更好的方法来替换这样一个文件中的值?我使用yq从https://mikefarah.gitbook.io/yq

第二种方法可以工作,但是以一种迂回的方式,因为mikefarah/yq还不支持更新多行块文字

解决这个问题的一种方法是,使用现有的结构,执行下面的操作,而不必创建临时的YAML文件
o="$(yq e '.spec.source.helm.values' yaml | yq e '.image.tag="footag"' -)" yq e -i '.spec.source.helm.values = strenv(o)' argocd.yaml

上面的解决方案依赖于将用户定义的变量作为字符串传递,该字符串可以在使用strenv()的yq表达式中使用。变量o的值是通过bash中的命令替换$(..)特性设置的。在替换构造中,我们提取块文字内容作为YAML对象,并应用另一个过滤器根据需要修改标记。因此,在替换结束时,o的值将被设置为

image:
tag: "footag"
repository: "myrepo-image"
registry: "myregistry"

上面获得的结果现在直接设置为.spec.source.helm.values的值,该值是就地修改标志(-i),用于将更改应用于实际文件


我已经在作者的repo中提出了一个功能请求,以提供一种更简单的方法来做到这一点支持更新YAML多行字符串#974

更新:您现在可以通过from_yaml/to_yaml操作符来完成此操作,详细信息请参见此处。

yq e -i '.spec.source.helm.values |= (from_yaml | .tag = "cool" | to_yaml) argocd.yaml

披露:我写了yq

最新更新