Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Retrieving value from json array where attribute equals variable with Ansible

I'm trying to get the value of an attribute in a json array with Ansible. Example data:

"domains.json.data": [
        {
            "axfr_ips": [],
            "description": "",
            "domain": "mydomain.net",
            "expire_sec": 0,
            "group": "",
            "id": 687088,
        },
        {
            "axfr_ips": [],
            "description": "",
            "domain": "myotherdomain.net",
            "expire_sec": 0,
            "group": "",
            "id": 687089,
        }
    ]
}

So I tried with json query:

"{{ domains.json.data | json_query(\"data[?domain=='{{ server_domain }}'].id\") }}"

or with:

- set_fact:
    domain_id: "{{ domains | json_query(query) | first }}"
  vars:
    query: "domains.json[?name=='{{ server_domain }}'].id"

Also tried with selectattrib:

"{{ linode_domains.json.data | selectattr(\"domain\", \"{{ server_domain }}\") | list }}"

So what I need is to get the id of the domain I got in {{ server_domain }}.

like image 393
willemdh Avatar asked Mar 04 '23 08:03

willemdh


2 Answers

The query can't work because there is no attribute name in the dictionary

        query: "domains.json[?name=='{{ server_domain }}'].id"

Use the attribute domain. For example the task below

    - debug:
        msg: "{{ domains.json.data|json_query(query) }}"
      vars:
        server_domain: 'mydomain.net'
        query: "[?domain=='{{ server_domain }}'].id"

gives

    "msg": [
        687088
    ]

Notes

  • json_query returns a list.
  • use filter first to get the first element of a list
        msg: "{{ domains.json.data|json_query(query)|first }}"
like image 140
Vladimir Botka Avatar answered Apr 28 '23 09:04

Vladimir Botka


You can use selectattr to filter and use map to get the id value. Below is the sample you can try.

- name: Retrieve value from JSON array
  debug:
    msg: "{{ test.domains | selectattr('domain', 'equalto', server_domain) | map(attribute='id') | join(',') }}"

As map returns list, I have used join to convert to string.

I have set server_domain value to myotherdomain.net for testing.

Below is the output of the command

TASK [Retrieve value from JSON array] **************************
ok: [localhost] => {
    "msg": "687089"
}

EDIT: equalto was introduced in v2.8 of jinja2. If you get TemplateRuntimeError: no test named 'equalto', update the jinja2.

To check version use pip list | grep Jinja2. To update use following command pip install --upgrade Jinja2.

like image 29
Sriram Avatar answered Apr 28 '23 10:04

Sriram