Search code examples
jsonansiblejinja2json-query

How to use json_query with integer


Hello Developer Community!

I'm currently working on developing some Ansible playbooks to manage Citrix NetScaler configuration and would like to ask for some help about the following. I have the following data structure defined in a variable file named nsadc_config_file_textfsm_nsadc_vlan_binding_parsed

[
    {
        "bind_vlan_NotParsed": "",
        "bind_vlan_id": "1042",
        "bind_vlan_ifnum": "",
        "bind_vlan_ipaddress": "10.162.5.120",
        "bind_vlan_netmask": "255.255.255.128",
        "bind_vlan_ownergroup": "",
        "bind_vlan_tagged": "",
        "bind_vlan_td": ""
    },
    {
        "bind_vlan_NotParsed": "",
        "bind_vlan_id": "1050",
        "bind_vlan_ifnum": "",
        "bind_vlan_ipaddress": "10.162.5.250",
        "bind_vlan_netmask": "255.255.255.128",
        "bind_vlan_ownergroup": "",
        "bind_vlan_tagged": "",
        "bind_vlan_td": ""
    }
]

I would like to query this JSON structure with json_query in a Jinja file using a loop to get the record for a specific VLAN ID:

{% if (nsadc_config_file_textfsm_nsadc_vlan_binding_parsed | json_query('[?bind_vlan_id == `' + item_0.add_vlan_id + '`]')) %}

But unfortunately, the query does not work, I always get an empty result. Both variables bind_vlan_id and add_vlan_id are integer, but according to my understanding, JSON structure contains string key:value by default. I believe, this could be the cause of the issue: integer vs string. I have already tried a lot of scenarios, but with no luck.

 - json_query('[?bind_vlan_id == `' + item_0.add_vlan_id + '`]')
 - json_query('[?bind_vlan_id == `' + item_0.add_vlan_id | string + '`]')
 - json_query('[?bind_vlan_id == item_0.add_vlan_id]')
 - json_query('[?bind_vlan_id == item_0.add_vlan_id | string]')
 - json_query('[?bind_vlan_id == `item_0.add_vlan_id`]')
 - json_query('[?bind_vlan_id == ''item_0.add_vlan_id'']')

Could anyone please point me to the right direction, how json_query should work in case of integer value as the condition? Thank You very much in advance!


Solution

  • Given simplified data for testing

        nsadc:
          - id: "1042"
            ipaddress: "10.162.5.120"
          - id: "1050"
            ipaddress: "10.162.5.250"
    

    Q: "Loop to get the record for a specific ID."

    A: Put the query into a variable. This will simplify the quoting and escaping. For example

    - debug:
        msg: "{{ nsadc|json_query(query) }}"
      loop: ["1042", "1050", "9999"]
      vars:
        query: "[?id == '{{ item }}']"
    

    gives

    ok: [localhost] => (item=1042) => {
        "msg": [
            {
                "id": "1042",
                "ipaddress": "10.162.5.120"
            }
        ]
    }
    ok: [localhost] => (item=1050) => {
        "msg": [
            {
                "id": "1050",
                "ipaddress": "10.162.5.250"
            }
        ]
    }
    ok: [localhost] => (item=9999) => {
        "msg": []
    }
    

    • The attribute id is not an integer
    - debug:
        msg: "{{ nsadc.0.id|type_debug }}"
    

    gives

        "msg": "AnsibleUnicode"
    

    An integer is declared without quotes. For example

    
            id: 1042
    

    would give

        "msg": "int"
    

    Q: "Jinja template error"

    {% set query = '[?id == '{{ item_0.id }}']' %}
    

    A: If you insist on creating the query in Jinja then the string must be concatenated. For example

        - debug:
            msg: >-
              {% set query = "[?id == '" ~ item_0.id ~ "']" %}
              {{ nsadc|json_query(query) }}
          vars:
            item_0:
              id: "1042"
    

    gives

        "msg": " [{'id': '1042', 'ipaddress': '10.162.5.120'}]"