Trying to parse json output with a list of key-value pairs in ansible

时间:2019-04-17 00:08:01

标签: json ansible

I am trying to parse the JSON output from a module. I am interested in a couple key-value pairs in a list of an object attribute.

I need to go through a list like this, evaluating the value of key "aggr-availsize" and returning the value of key "aggr-name" if "aggr-availsize" meets a certain condition:

"ontap_facts": {
    "vserver_info": {
           "labserver01": {
                "vserver_aggr_info_list": {
                    "vserver_aggr_info": [
                        {
                            "aggr-availsize": "48624060522496", 
                            "aggr-is-cft-precommit": "false", 
                            "aggr-name": "aggr_sas_3_03"
                        }, 
                        {
                            "aggr-availsize": "32505113686016", 
                            "aggr-is-cft-precommit": "false", 
                            "aggr-name": "aggr_sas_3_04"
                        }, 
                        {
                            "aggr-availsize": "50852574732288", 
                            "aggr-is-cft-precommit": "false", 
                            "aggr-name": "aggr_sas_3_05"
                        }, 
                    ]
                }, 
            },
        },
    }

I tried several loop structures: with_items, with_dict or with_subelements without success:

Here is a code sample of what I am trying to do:

    register: result
    with_items: "{{ ontap_facts.vserver_info.labserver01.vserver_aggr_info_list.vserver_aggr_info.aggr-name }}"
    when:
      - "{{ ontap_facts.vserver_info.labserver01.vserver_aggr_info_list.vserver_aggr_info.aggr-availsize | int / 1024 / 1024 / 1024}} > {{ lun_size }}"
      - not item.startswith("aggr0")
      - item.startswith("aggr_{{ sc }}")
      - result is not defined or result.rc != 0

This prints all the key-value pairs in the list, but I can't get aggr-name and aggr-availsize.

  - name: Print aggr info
    debug:
      msg: "Aggregate {{ item.key }} size is {{ item.value }}"
    with_dict: "{{ ontap_facts.vserver_info.labserver01.vserver_aggr_info_list.vserver_aggr_info }}"

Getting output like this:

TASK [Print aggr info] **************************************************************************************************************************************
ok: [localhost] => (item={'value': u'12879040905216', 'key': u'aggr-availsize'}) => {
    "msg": "Aggregate aggr-availsize size is 12879040905216"
}
ok: [localhost] => (item={'value': u'aggr_sas_4_02', 'key': u'aggr-name'}) => {
    "msg": "Aggregate aggr-name size is aggr_sas_4_02"
}
ok: [localhost] => (item={'value': u'false', 'key': u'aggr-is-cft-precommit'}) => {
    "msg": "Aggregate aggr-is-cft-precommit size is false"
}
ok: [localhost] => (item={'value': u'31796620173312', 'key': u'aggr-availsize'}) => {
    "msg": "Aggregate aggr-availsize size is 31796620173312"
}
ok: [localhost] => (item={'value': u'aggr_sata_4_02', 'key': u'aggr-name'}) => {
    "msg": "Aggregate aggr-name size is aggr_sata_4_02"
}
ok: [localhost] => (item={'value': u'false', 'key': u'aggr-is-cft-precommit'}) => {
    "msg": "Aggregate aggr-is-cft-precommit size is false"
}

I am getting various errors depending on which loop construct I use and how I layout the objects.

1 个答案:

答案 0 :(得分:0)

If I have to guess, you were running into issues when trying to do item.aggr-name or similar. Ansible doesn't like dashes when you try to access dicts like that.

In that case, you'd need to access the dicts like so: item["aggr-name"]

Here is a working example (I converted your Json into yaml for my convenience, sorry):

---
- name: test
  hosts: localhost
  become: false
  gather_facts: false
  vars:
    ontap_facts:
      vserver_info:
        labserver01:
          vserver_aggr_info_list:
            vserver_aggr_info:
              - 
                  aggr-availsize: '48624060522496'
                  aggr-is-cft-precommit: 'false'
                  aggr-name: aggr_sas_3_03
              - 
                  aggr-availsize: '32505113686016'
                  aggr-is-cft-precommit: 'false'
                  aggr-name: aggr_sas_3_04
              - 
                  aggr-availsize: '50852574732288'
                  aggr-is-cft-precommit: 'false'
                  aggr-name: aggr_sas_3_05
  tasks:
    - name: test
      loop: "{{ ontap_facts.vserver_info.labserver01.vserver_aggr_info_list.vserver_aggr_info }}"
      when: '{{ item["aggr-availsize"] | int / 1024 / 1024 / 1024 }} < 45000'
      debug:
        msg: '{{ item["aggr-availsize"] | int / 1024 / 1024 / 1024}} | {{ item["aggr-name"] }}'

Now, the only issue here is that Ansible throws a warning about Jinja templating in the when: conditional, but I will let you deal with that one :)

Also of note: loop should be synonymous with with_items if you are using an older version of Ansible.