skip to Main Content

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.

2

Answers


  1. 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]'
          ) }}
    
    Login or Signup to reply.
  2. Create the dictionary of the tags and clusters first

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

    gives

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

    Then, selectattr and map the key(s)

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

    gives

      tags_test:
      - a
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search