使用 yq 解析 属性 个文件数据模型

Use yq to parse property files data model

我有一个这样的 YAML 文件

apiVersion: "v1alpha1"
kind: "Druid"
metadata:
  name: druid-dev-cluster
spec:
  common.runtime.properties: |
    # Zookeeper
    druid.zk.service.host=cluster-zk-0.cluster-zk
    druid.zk.paths.base=/druid
    druid.zk.service.compress=false

我想替换 common.runtime.properties 中的其中一个属性。这是否支持使用 yq? 当我正常尝试时它失败了

property=.spec.common.runtime.properties.druid.zk.service.host=cluster-zk-0.cluster-zk
OVERLAY= deploy/overlays/aws/common-runtime-properties.yaml
yq e "${property}" "$OVERLAY"/"$propertyType"

Error: Parsing expression: Lexer error: could not match text starting at 1:55 failing at 1:57.
        unmatched text: "ti"

这适用于其他属性,例如

apiVersion: "v1alpha1"
kind: "Druid"
metadata:
  name: druid-dev-cluster
spec:
  nodes:
    brokers:
      nodeType: "broker"
      druid.port: 8088
      ingressAnnotations:
        kubernetes.io/ingress.class: "plb.v1"

问题是:

  • | 是一个 YAML 文字块标量。就 YAML 而言,它的内容是单个标量,因此您不能从 yq path-select 进入它。
  • 此外,| 的内容不是 YAML,但可能被解析为 Java 属性文件。因此,即使在标量上递归调用 yq 也无法解析它。
  • 此外,标量的路径不是 .spec.common.runtime.properties 而是 .spec."common.runtime.properties" – 请注意第二部分在 YAML 内容中是如何写为单个标量的,这不等同于具有多个 child 映射(尽管一些 Java 人似乎相信这一点)。

话虽这么说,你当然可以做类似的事情

export NEW_VALUE=droggeljug
UPDATED_CONTENT=$(\
    yq e '.spec."common.runtime.properties"' test.yaml | \
    sed -re 's/(druid.zk.service.host=)[^\n]*/'"$NEW_VALUE"'/g' \
) yq e '.spec."common.runtime.properties" = strenv(UPDATED_CONTENT)' test.yaml

这使用 yq 到 select 包含属性的标量(第 3 行),使用 sed 将值 druid.zk.service.host 更新为 [=19 的内容=](第 4 行),将结果存储在 UPDATED_CONTENT(第 2 行)中,然后再次调用 yq 将值更新为 UPDATED_CONTENT(第 5 行)的内容。