Warm tip: This article is reproduced from serverfault.com, please click

How to use json_query with integer

发布于 2020-11-30 23:58:12

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!

Questioner
Belabacsi
Viewed
0
Vladimir Botka 2020-12-01 18:00:11

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'}]"