0
votes

I've been reading and searching a lot and cannot overcome this issue. Can you please help ?

With the content below, I need to extract the attribute "ipAddress" and push to a list. Actual data is a dict of objects such as "host01" but for the example I reduced the data to one host.

    {
        "host01": {
            "fqdn": "host01.mydomain",
            "interface": {
                "Bundle-Ether1001": {
                    "ipAddress": "10.20.30.41",
                    "subnetMask": "255.255.255.252"
                },
                "Bundle-Ether1002": {
                    "ipAddress": "10.20.30.45",
                    "subnetMask": "255.255.255.252"
                }
            },
            "timestamp": 1545420334
        }
}

My playbook goes as follows:

---
- name : myplaybook 
  hosts: localhost
  vars:
    myjson: "{{ lookup('file', 'api.json') | from_json }}"


  tasks:
    - name: debug
      debug:
        msg: "{{myjson}}"

    - name: debugallip
      when: item.value.interface is defined
      debug:
        msg: "{{ item | selectattr('ipAddress', 'defined') | map('value.ipAddress') | list }}"
      with_dict: "{{ myjson }}"

Which returns an empty list ? :(

TASK [debugallip] ****************************************************************************************** ok: [localhost] => (item={'value': {u'interface': {u'Bundle-Ether1001': {u'subnetMask': u'255.255.255.252', u'ipAddress': u'10.20.30.41'}, u'Bundle-Ether1002': {u'subnetMask': u'255.255.255.252', u'ipAddress': u'10.20.30.45'}}, u'timestamp': 1545420334, u'fqdn': u'host01.mydomain'}, 'key': u'host01'}) => { "msg": [] }

What am I doing wrong ??

2

2 Answers

1
votes

The selectattr filter is incorrect, as the ipAddress is buried down in the structure, and not at the top-level of ... well, anything in your particular setup. One can very easily see the shape of item in the task output, so I have no idea why you would assume any other shape, but here we are. Your invocation of map is incorrect, too, since there is no such filter as value.ipAddress, which only would have actually exploded if your selectattr had been correct.

- debug:
    msg: '{{ item.value.interface | dict2items | map(attribute="value.ipAddress") | select("defined") }}'
  with_dict: '{{ myjson }}'

If you want all the ipAddress values buried in the host.interface structure, you'll need to essentially do another with_dict loop over the host.interface dict, which is what dict2items does. Then, you can save yourself some copy-pasta by going ahead and extracting .ipAddress, with the risk that it is not defined, and then toss out the undefined ones at the end

0
votes

An option would be to use json_query

- debug:
    msg: "{{ item.value.interface | dict2items | json_query('[].value.ipAddress') }}"