Home > Software design >  Ansible extract value from json_query
Ansible extract value from json_query

Time:01-07

I'm trying to extract the result from the value "mac_addr" and then register it (in this case 00:50:56:a2:57:c9)

The output I'm working with

"msg": [
        {
            "changed": false,
            "failed": false,
            "network_data": {
                "0": {
                    "allow_guest_ctl": true,
                    "connected": true,
                    "device_type": "test0",
                    "label": "test1",
                    "mac_addr": "00:50:56:a2:57:c9",
                    "name": "DVSwitch: ",
                    "start_connected": true,
                    "unit_number": 7,
                    "wake_onlan": true

I've tried different commands but I can get past the "0" value. Here the last commands I've tried.

    - name: show test result
      debug:
        msg:
         - "{{ test.network_data | json_query('0[*].mac_addr') }}"
      register: mac

AND

    - name: show test result
      debug:
        msg:
         - "{{ test.network_data.0 | json_query('mac_addr') }}"
      register: mac

The output is in the "test" variable

I'm a beginner in Ansible and JSON. Can you please tell what I'm doing wrong ?

I'm working with ansible 2.9.

Thanks

CodePudding user response:

JSON dictionary keys need to be strings, and the JMESPath parser interprets a bare 0 as an integer. To make it explicitly a string, you can quote it, giving you:

{{ test.network_data | json_query('"0".mac_addr') }}

Although for the data you've shown, you don't need to use json_query; you can just write:

{{ test.network_data["0"].mac_addr }}

Here's a playbook that demonstrates both options:

- hosts: localhost
  gather_facts: false
  vars:
    network_data:
      "0":
        "allow_guest_ctl": true,
        "connected": true,
        "device_type": "test0"
        "label": "test1"
        "mac_addr": "00:50:56:a2:57:c9"
        "name": "DVSwitch: "
        "start_connected": true
        "unit_number": 7
        "wake_onlan": true

  tasks:
    - name: extract value using json_query
      debug:
        msg:
          - >-
            {{ network_data | json_query('"0".mac_addr') }}

    - name: extract value using jinja syntax
      debug:
        msg:
          - >-
            {{ network_data["0"].mac_addr }}

That outputs:

PLAY [localhost] ***************************************************************

TASK [extract value using json_query] ******************************************
ok: [localhost] => {
    "msg": [
        "00:50:56:a2:57:c9"
    ]
}

TASK [extract value using jinja syntax] ****************************************
ok: [localhost] => {
    "msg": [
        "00:50:56:a2:57:c9"
    ]
}

PLAY RECAP *********************************************************************
localhost                  : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

Lastly, in your examples you're using register on your debug task. Don't do that -- if you want to extract data into a variable, use the set_fact module:

- name: extract mac address
  set_fact:
    mac: '{{ network_data["0"].mac_addr }}'
  • Related