在Ansible中从嵌套字典中提取数据,并在列表中进行条件检查?

huangapple go评论65阅读模式
英文:

Extracting data from nested dict in ansible with conditional checks in the list?

问题

- 名称: "测试"
  主机: 本地主机
  收集事实: False

  变量:
  - 测试:
      - clusters:
          - 名称: "cluster1"
            id: "1"
          - 名称: "cluster2"
            id: "2"
        标签: "a"
      - clusters:
          - 名称: "cluster2"
            id: "3"
        标签: "b"

  - 设定事实:
      标签测试: "{{ test | community.general.json_query('[?clusters[].name==`cluster1`].tag') }}"

  - 调试:
      消息: "{{ 标签测试 }}"
英文:

I'm stuck with the following issue.
My JSON data looks like this:

[
   {
      "clusters":[
         {
            "id":"1",
            "name":"cluster1"
         },
         {
            "id":"2",
            "name":"cluster2"
         }
      ],
      "tag":"a"
   },
   {
      "clusters":[
         {
            "id":"3",
            "name":"cluster2"
         }
      ],
      "tag":"b"
   }
]

What I am trying to do is extracting the tag values which are connected to a certain cluster (say, cluster1). So, I need to check if cluster1 is in the list of clusters[*].name somehow.

Here is my playbook:

- name: "Test"
  hosts: localhost
  gather_facts: False

  vars:
  - test:
        - clusters:
            - name: "cluster1"
              id: "1"
            - name: "cluster2"
              id: "2"
          tag: "a"
        - clusters:
            - name: "cluster2"
              id: "3"
          tag: "b"

  - set_fact:
      tags_test: "{{ test | community.general.json_query('[?clusters[].name==`cluster1`].tag') }}"

  - debug:
      msg: "{{ tags_test }}"

What I am expecting to get is the tag value: "a".

This is the result:

TASK [debug] ******************************************************
ok: [localhost] => {
    "msg": []
}

I also tried combining json_query with selectattr, but, no luck.

答案1

得分: 2

使用 JMESPath 时,你必须嵌套你的条件,因为你在另一个数组中嵌套了一个名为 clusters 的 JSON 数组,你正在查找其中名为 cluster1 的对象:

- set_fact:
    tags_test: >-
      {{ test | community.general.json_query(
           '[?clusters[?name==`cluster1`]].tag|[0]'
      ) }}
英文:

With JMESPath you have to nest your conditions because you are looking for an object named cluster1 inside the the JSON array clusters which is nested in another array:

[?clusters[?name==`cluster1`]].tag|[0]

So as a task,

- set_fact:
    tags_test: >-
      {{ test | community.general.json_query(
           '[?clusters[?name==`cluster1`]].tag|[0]'
      ) }}

答案2

得分: 0

  创建标签和群集的字典

  ```yaml
  tag_clusters: "{{ test|json_query(tag_clusters_query)|items2dict }}"
  tag_clusters_query: '[].{key: tag, value: clusters[].name}'

输出

tag_clusters:
  a:
  - cluster1
  - cluster2
  b:
  - cluster2

然后,使用 selectattrmap 选择键

tags_test: "{{ tag_clusters|dict2items|
              selectattr('value', 'contains', 'cluster1')|
              map(attribute='key') }}"

输出

tags_test:
- a

<details>
<summary>英文:</summary>

Create the dictionary of the tags and clusters first

```yaml
  tag_clusters: &quot;{{ test|json_query(tag_clusters_query)|items2dict }}&quot;
  tag_clusters_query: &#39;[].{key: tag, value: clusters[].name}&#39;

gives

  tag_clusters:
    a:
    - cluster1
    - cluster2
    b:
    - cluster2

Then, selectattr and map the key(s)

  tags_test: &quot;{{ tag_clusters|dict2items|
                 selectattr(&#39;value&#39;, &#39;contains&#39;, &#39;cluster1&#39;)|
                 map(attribute=&#39;key&#39;) }}&quot;

gives

  tags_test:
  - a

huangapple
  • 本文由 发表于 2023年2月13日 23:12:12
  • 转载请务必保留本文链接:https://go.coder-hub.com/75437733.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定