YAML 解析器 yq 使用过滤器就地修改文件

YAML parser yq modifying file in place with filter

背景

我准备了一个Kubernetes的manifest文件,在GitOps操作中从circleci构建了一个docker镜像,推送到ECR,同时发送镜像标签从circleci更改为[=32的PR =]

当时我也尝试在circleci作业中编辑manifest文件

问题,未知点

我尝试使用 yq 命令更改 yaml 文件。

yq -y -i  '.images |= map(select(.name=="XXXXXXXXXXXX.dkr.ecr.ap-northeast-1.amazonaws.com/backend-admin").newTag |= '$CIRCLE_SHA1')'  k8s/overlays/dev/bases/kustomization.yaml

清单文件

namespace: production

bases:
  - ../../../bases/admin

patchesStrategicMerge:
  - patch-admin.yaml

images:
  - name: nginx
    newTag: 1.15.2
  - name: XXXXXXXXXXXX.dkr.ecr.ap-northeast-1.amazonaws.com/backend
    newName: XXXXXXXXXXXX.dkr.ecr.ap-northeast-1.amazonaws.com/backend
    newTag: backend-tag
  - name: XXXXXXXXXXXX.dkr.ecr.ap-northeast-1.amazonaws.com/frontend
    newName: XXXXXXXXXXXX.dkr.ecr.ap-northeast-1.amazonaws.com/frontend
    newTag: latest

但是出现错误

jq: error: a99cce09747507feb74799e1e1c9459aba43d4a6/0 is not defined at <top-level>, line 1:
.images |= map(select(.name=="XXXXXXXXXXXX.dkr.ecr.ap-northeast-1.amazonaws.com/backend-admin").newTag |= a99cce09747507feb74799e1e1c9459aba43d4a6)

我认为原因是它包含在 我看到了各种文章,但其中 none 个找到了解决方案。

我想知道有没有人知道一些事情

单引号内不展开变量。请到外面去。

'$CIRCLE_SHA1' 

to

"'$CIRCLE_SHA1'"

生成的过滤器是正确的,但 RHS 上的更新运算符 |= 需要字符串类型或适当的对象类型才能存在。您所拥有的不会被解释为文字字符串。将标签放在引号 ".."

两边
yq -y '.images |= map(select(.name=="XXXXXXXXXXXX.dkr.ecr.ap-northeast-1.amazonaws.com/backend").newTag |= "a99cce09747507feb74799e1e1c9459aba43d4a6")'

另外 yq 与其前身 jq 一样支持传递要在过滤器中使用的参数字段,因此您可以

yq -y --arg tag "${CIRCLE_SHA1}" '.images |= map(select(.name=="XXXXXXXXXXXX.dkr.ecr.ap-northeast-1.amazonaws.com/backend").newTag |= $tag )'