【问题标题】:yq: how to read a sibling element value?yq:如何读取兄弟元素的值?
【发布时间】:2021-01-20 14:34:33
【问题描述】:

我正在探索 yq 来修改我的 YAML,我想在 name == openshift45 的 ImageStream 的 spec 下添加一个新元素

apiVersion: v1
items:
- apiVersion: image.openshift.io/v1
  kind: ImageStream
  metadata:
    annotations:
      openshift.io/generated-by: OpenShiftNewApp
    creationTimestamp: null
    labels:
      app: openshift45
      app.kubernetes.io/component: openshift45
      app.kubernetes.io/instance: openshift45
    name: nodejs-10
  spec:
    lookupPolicy:
      local: false
    tags:
    - annotations:
        openshift.io/imported-from: registry.access.redhat.com/ubi8/nodejs-10
      from:
        kind: DockerImage
        name: registry.access.redhat.com/ubi8/nodejs-10
      generation: null
      importPolicy: {}
      name: latest
      referencePolicy:
        type: ""
  status:
    dockerImageRepository: ""
- apiVersion: image.openshift.io/v1
  kind: ImageStream
  metadata:
    annotations:
      openshift.io/generated-by: OpenShiftNewApp
    creationTimestamp: null
    labels:
      app: openshift45
      app.kubernetes.io/component: openshift45
      app.kubernetes.io/instance: openshift45
    name: openshift45
  spec:
    lookupPolicy:
      local: false
  status:
    dockerImageRepository: ""

以下命令返回有效的metadata 元素。现在,我想移动到父级,然后选择specyq - https://github.com/mikefarah/yq 可以做到这一点吗?

yq r openshift45.yaml --printMode pv "items(kind==ImageStream).(name==openshift45)"

返回

items.[1].metadata:
  annotations:
    openshift.io/generated-by: OpenShiftNewApp
  creationTimestamp: null
  labels:
    app: openshift45
    app.kubernetes.io/component: openshift45
    app.kubernetes.io/instance: openshift45
  name: openshift45

预期输出:

apiVersion: v1
items:
- apiVersion: image.openshift.io/v1
  kind: ImageStream
  metadata:
    annotations:
      openshift.io/generated-by: OpenShiftNewApp
    creationTimestamp: null
    labels:
      app: openshift45
      app.kubernetes.io/component: openshift45
      app.kubernetes.io/instance: openshift45
    name: nodejs-10
  spec:
    lookupPolicy:
      local: false
    tags:
    - annotations:
        openshift.io/imported-from: registry.access.redhat.com/ubi8/nodejs-10
      from:
        kind: DockerImage
        name: registry.access.redhat.com/ubi8/nodejs-10
      generation: null
      importPolicy: {}
      name: latest
      referencePolicy:
        type: ""
  status:
    dockerImageRepository: ""
- apiVersion: image.openshift.io/v1
  kind: ImageStream
  metadata:
    annotations:
      openshift.io/generated-by: OpenShiftNewApp
    creationTimestamp: null
    labels:
      app: openshift45
      app.kubernetes.io/component: openshift45
      app.kubernetes.io/instance: openshift45
    name: openshift45
  spec:
    *dockerImageRepository: <$MYREGISTRY>/<$MYNAMESPACE>/<$MYPROJECT>*
    lookupPolicy:
      local: false
  status:
    dockerImageRepository: ""

【问题讨论】:

  • 你想要达到的预期输出是什么?
  • 如问题中所述,想在 ImageStream 规范中添加一个名为 openshift45 的新元素
  • 是的,但请更新准确所需的输出结构,而不是让人们假设输出
  • 用预期的输出更新了我的问题,并将 *...* 添加到要添加的元素中

标签: yaml yq


【解决方案1】:

Path Expressions in mikefarah/yq 没有完整的文档来展示如何使用多个条件来获取所需对象的真实示例。因此,对于有问题的 YAML,使用一种独特的条件,您可以执行以下操作。验证于yq version 3.3.2

yq w openshift45.yaml 'items.(metadata.name == openshift45).spec.dockerImageRepository' '<$MYREGISTRY>/<$MYNAMESPACE>/<$MYPROJECT>'

您可以使用 -i 标志和 write 来就地修改 YAML。见Updating files in-place

如果不希望这样做并且您需要多个条件选择来获得所需的对象,建议在 GitHub 页面上提出问题 - https://github.com/mikefarah/yq/issues 请求相同的正确语法。

【讨论】:

  • 工作就像一个魅力,但我必须添加 -i 来更新 YAML inline
  • @VidyasagarMachupalli:刚刚添加了相同的注释
  • 这是将 dockerImageRepository 添加到所有类型(服务、部署等)。我希望将它添加到仅 ImageStream 类型。谢谢
  • @VidyasagarMachupalli:我确实添加了一个关于这个的注释,对吧?在 mikefarah/yq 中没有完全记录多个条件表达式。让我再试一次
  • @VidyasagarMachupalli:到目前为止,yq 不可能 - github.com/mikefarah/yq/issues/513github.com/mikefarah/yq/issues/557
【解决方案2】:

目前在 yq 中是不可能的。您必须在变量中获取第一个命令的输出并将该变量传递给下一个。

yq 是 jq 的一个包装器,但它没有自定义函数的功能。自定义函数可以在一个地方使用文档的任何层次结构中的任何值。

感谢 Inian 指出 OP 没有使用包装器 yq 版本。不幸的是,使用的版本目前也不允许使用自定义函数。

【讨论】:

  • OP 使用的是github.com/mikefarah/yq,而不是作为jq 的包装器的python 版本。 jq 有两个版本
  • @Inian,感谢您的指出。不幸的是,它也不支持自定义函数。
  • 您不需要自定义函数,正确的路径表达式就足够了。看我的回答。同样就目前而言,您的答案可能会让未来的读者感到困惑。所以如果你没有明确的解决方案,建议删除这个
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-02
  • 1970-01-01
  • 1970-01-01
  • 2015-01-14
  • 2022-11-18
  • 2020-04-28
相关资源
最近更新 更多