Home > Software engineering >  Parse Nested JSON Dictionary Ansible
Parse Nested JSON Dictionary Ansible

Time:10-29

I'm trying to get the names of interfaces that meet a certain criteria within a given JSON in Ansible, using jmesquery.

The thing is that the items in the list are named, it's not a list containing all values per item in it, and can't figure how to filter it.

With a condition that is vlan == "1" this JSON should give as output something like ['GigabitEthernet0/0', 'GigabitEthernet0/1']

After using dict2items (as @mdaniel suggested) I managed to apply the filter with conditions, but I'm struggling to retrieve the interface names which are now in key:

    - name: PRINT
      debug:
       msg: "{{ jsondata.interfaces | dict2items | json_query( query ) }}"
      vars:
       query: >-
        [][value][?vlan=='1']

JSON

        interfaces: {
               "GigabitEthernet0/0": {
                    "duplex_code": "auto",
                    "port_speed": "a-100",
                    "status": "connected",
                    "type": "10/100/1000BaseTX",
                    "vlan": "1"
              },
               "GigabitEthernet0/1": {
                    "duplex_code": "auto",
                    "port_speed": "a-100",
                    "status": "connected",
                    "type": "10/100/1000BaseTX",
                    "vlan": "1"
              } 
    }

JSON after applying jsondata.interfaces | dict2items

        [
           {
               "key": GigabitEthernet0/0",
               "value": {
                    "duplex_code": "auto",
                    "port_speed": "a-100",
                    "status": "connected",
                    "type": "10/100/1000BaseTX",
                    "vlan": "1"
                }
            },
            {
               "key": GigabitEthernet0/1",
               "value": {
                    "duplex_code": "auto",
                    "port_speed": "a-100",
                    "status": "connected",
                    "type": "10/100/1000BaseTX",
                    "vlan": "1"
                }
            }
        ]
              

Thank you in advance!

CodePudding user response:

one solution, you could use jinja2 to loop over json: (no need to use filtes dict2items or json_query)

- name: build
  set_fact:
    result: "{{ _request.strip(',').split(',') }}"
  vars:
    _query: "1"
    _request: >-
      {%- for k in jsondata.interfaces -%}
      {%-   if jsondata.interfaces[k].vlan == _query -%}
      {{ k }},
      {%-   endif  -%}
      {%- endfor  -%}  

result:

ok: [localhost] => 
  result:
  - GigabitEthernet0/0
  - GigabitEthernet0/1

another solution:

- name: set_fact 
  set_fact:
    result: "{{ result | d([])   [item.key] }}"
  loop: "{{ lookup('dict', jsondata.interfaces) }}"
  when: "'1' == item.value.vlan"

CodePudding user response:

For example, the task below does the job of listing the keys for vlan=='1'

    - debug:
        msg: "{{ interfaces|dict2items|
                 selectattr('value.vlan', 'eq', '1')|
                 map(attribute='key')|list }}"
  • Related