【问题标题】:Multiple json_query in Ansible?Ansible中有多个json_query?
【发布时间】:2023-03-25 03:07:02
【问题描述】:

我有以下 yaml 文件。

resources:
  - apiVersion: v1
    kind: Deployment
    metadata:
      labels:
        app: test
      name: test-cluster-operator
      namespace: destiny001
    spec:
      selector:
        matchLabels:
          name: test-cluster-operator
          test.io/kind: cluster-operator
      strategy:
        type: Recreate
      template:
        metadata:
          labels:
            name: test-cluster-operator
            test.io/kind: cluster-operator
        spec:
          containers:
          - args:
            - /path/test/bin/cluster_operator_run.sh
            env:
            - name: MY_NAMESPACE
              valueFrom:
                fieldRef:
                  apiVersion: v1
                  fieldPath: metadata.namespace
            imagePullPolicy: IfNotPresent
            livenessProbe:
              failureThreshold: 3
              httpGet:
                path: /healthy
                port: 8080
                scheme: HTTP
              initialDelaySeconds: 10
              periodSeconds: 30
              successThreshold: 1
              timeoutSeconds: 1
            name: test-cluster-operator
            readinessProbe:
              failureThreshold: 3
              httpGet:
                path: /ready
                port: 8080
                scheme: HTTP
              initialDelaySeconds: 10
              periodSeconds: 30
              successThreshold: 1
              timeoutSeconds: 1
            resources:
              limits:
                cpu: '1'
                memory: 256Mi
              requests:
                cpu: 200m
                memory: 256Mi
            terminationMessagePath: /dev/termination-log
            terminationMessagePolicy: File
            volumeMounts:
            - mountPath: /var/data
              name: data-cluster-operator
          dnsPolicy: ClusterFirst
          restartPolicy: Always
          schedulerName: default-scheduler
          securityContext: {}
          serviceAccount: test-cluster-operator
          serviceAccountName: test-cluster-operator
          terminationGracePeriodSeconds: 30
          volumes:
          - name: data-cluster-operator
            persistentVolumeClaim:
              claimName: data-cluster-operator

我正在尝试获取名为 MY_NAMESPACE 的环境变量的值。 这是我在 Ansible 中尝试获取 env 树路径的方法。

- name: "set test fact"
  set_fact:
    myresult: "{{ yaml_file_variable | json_query(\"resources[?metadata.name=='test-cluster-operator'].spec.template.spec\") | json_query(\"containers[?name=='test-cluster-operator'].env\") }}"

- name: "debug"
  debug:
    msg: "{{ myresult }}"

这会产生一个空列表,但第一个 json_query 运行良好。

在这种情况下如何正确使用 json_query? 我可以只用一个 json_query 来实现吗?

编辑: 我似乎更接近解决方案,但结果是一个列表而不是字符串,我觉得这很烦人。

- name: "set test fact"
  set_fact:
    myresult: "{{ yaml_file_variable | json_query(\"resources[?metadata.name=='test-cluster-operator'].spec.template.spec\") | json_query(\"[].containers[?name=='test-cluster-operator']\") | json_query(\"[].env[?name=='MY_NAMESPACE'].name\") }}"

这将打印- - MY_NAMESPACE 而不仅仅是MY_NAMESPACE

json_query 之后每次都必须使用first 过滤器吗?我确定只有一个 containers 元素。我不明白为什么 json_query 返回一个列表。

这终于奏效了,但不知道这是否是正确的方法。

- name: "set test fact"
  set_fact:
    myresult: "{{ yaml_file_variable | json_query(\"resources[?metadata.name=='test-cluster-operator'].spec.template.spec\") | first | json_query(\"containers[?name=='test-cluster-operator']\") | first | json_query(\"env[?name=='MY_NAMESPACE'].valueFrom \") | first }}"

【问题讨论】:

    标签: ansible json-query


    【解决方案1】:

    json_query 使用 jmespath 并且 jmespath 总是返回一个列表。这就是为什么您的第一个示例不起作用的原因。第一个查询返回一个列表,但第二个查询试图查询一个键。您已在第二次使用[]. 更正了这一点

    您还缺少 jmespath 管道表达式:|,它的使用几乎与您预期的一样 - 第一个查询的结果可以通过管道传输到新的查询中。请注意,这与使用相同字符的 ansible 过滤器是分开的。

    这个查询:

    resources[?metadata.name=='test-cluster-operator'].spec.template.spec | [].containers[?name=='test-cluster-operator'][].env[].valueFrom
    

    应该给你以下输出:

    [
      {
        "fieldRef": {
          "apiVersion": "v1",
          "fieldPath": "metadata.namespace"
        }
      }
    ]
    

    你的任务应该是这样的:

    - name: "set test fact"
      set_fact:
        myresult: "{{ yaml_file_variable | json_query(\"resources[?metadata.name=='test-cluster-operator'].spec.template.spec | [].containers[?name=='test-cluster-operator'][].env[].valueFrom\") | first }}"
    

    要回答您的其他问题,是的,您需要使用first 过滤器。如前所述,jmespath 将始终返回一个列表,因此如果您只想要一个键的值,则需要将其拉出。

    【讨论】:

      猜你喜欢
      • 2020-11-25
      • 2020-05-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-23
      • 2020-02-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多