Variables inside JSON Query – Ansible / Jinja filter

huangapple go评论59阅读模式
英文:

Variables inside JSON Query - Ansible / Jinja filter

问题

JSON查询动态生成列表的问题是这样的:

变量的状态是:

fabric:
  vrfs:
    - name: VRF-A
      description: Production-Network
      id: 10001
      vlan: 2002
      switches:
        - serial_number: 10.122.18.114
        - serial_number: 10.122.18.118
    - name: VRF-F
      description: Production-Network
      id: 10001
      vlan: 2022
      switches:
        - serial_number: 10.122.18.114
        - serial_number: 10.122.18.118

我想使用JSON查询来获取VRF-A中的交换机。当JSON查询硬编码时,它可以工作:

- name: JSON Query
  set_fact:
    switches: "{{ fabric | json_query('vrfs[?(@.name==`VRF-A`)].switches') }}"

但是当我使用变量时,Ansible返回一个空列表:

- name: JSON Query
  set_fact:
    switches: "{{ fabric | json_query('vrfs[?(@.name==`{{ the_vrf }}`)].switches') }}"

我漏掉了什么吗?有没有解决这个问题的方法?

英文:

I am trying to use JSON query to dynamically generate lists

The state of the variables is:


fabric:
  vrfs:
    - name: VRF-A 
      description: Production-Network
      id: 10001
      vlan: 2002
      switches:
        - serial_number: 10.122.18.114
        - serial_number: 10.122.18.118
    - name: VRF-F
      description: Production-Network
      id: 10001
      vlan: 2022
      switches:
        - serial_number: 10.122.18.114
        - serial_number: 10.122.18.118

I want to get the switches in the VRF-A using a JSON query. When the JSON query is hardcoded it works.

  - name: JSON Query
    set_fact:
      switches: "{{ fabric |json_query('vrfs[?(@.name==`VRF-A`)].switches') }}"

But when I use variables, Ansible returns an empty List


  - name: JSON Query
    set_fact:
      switches: "{{ fabric |json_query('vrfs[?(@.name==`{{ the_vrf }}`)].switches') }}"

Am I missing something? Is there any workaround for this?

答案1

得分: 1

Ansible不支持变量的嵌套扩展。您可以将查询放入单独的变量中(请参阅一行注释)。

  the_vrf: VRF-A
  switches_query: '[?name == `{{ the_vrf }}`].switches'
  switches: "{{ fabric.vrfs|json_query(switches_query) }}"

所需的结果如下:

  switches:
  - - serial_number: 10.122.18.114
    - serial_number: 10.122.18.118

注:

  • 您的示例中的查询可以简化。以下两种选项会产生相同的结果:
  switches: "{{ fabric.vrfs|json_query('[?name == `VRF-A`].switches') }}"
  switches_query: '[?name == `VRF-A`].switches'
  switches: "{{ fabric.vrfs|json_query(swiches_query) }}"
  • 查询字符串可以连接起来:
 switches_query: "{{ '[?name == `' ~ the_vrf ~ '`].switches' }}"

将得到相同的查询(在示例playbook中测试它):

  switches_query: '[?name == `VRF-A`].switches'

似乎这个字符串可能在一行内使用:

  switches: "{{ fabric.vrms|json_query('[?name == `' ~ the_vrf ~ '`].switches') }}"

不幸的是,这种方法不起作用,我无法确定可能需要的转义是什么(欢迎对此发表评论)。这个一行查询的结果是:

  switches: ''

一个用于测试的完整playbook示例如下:

- hosts: localhost

  vars:

    fabric:
      vrfs:
        - name: VRF-A 
          description: Production-Network
          id: 10001
          vlan: 2002
          switches:
            - serial_number: 10.122.18.114
            - serial_number: 10.122.18.118
        - name: VRF-F
          description: Production-Network
          id: 10001
          vlan: 2022
          switches:
            - serial_number: 10.122.18.114
            - serial_number: 10.122.18.118

    the_vrf: VRF-A
    switches_query: '[?name == `{{ the_vrf }}`].switches'

  tasks:

    - debug:
        var: switches_query
    - debug:
        var: switches
英文:

Ansible doesn't support the nested expansion of variables. You can put the query into a separate variable (see the note on the one-liner)

  the_vrf: VRF-A
  switches_query: '[?name == `{{ the_vrf }}`].switches'
  switches: "{{ fabric.vrfs|json_query(switches_query) }}"

give what you want

  switches:
  - - serial_number: 10.122.18.114
    - serial_number: 10.122.18.118

<hr>

Notes:

  • The query from your example can be simplified. Both options below give the same result
  switches: &quot;{{ fabric.vrfs|json_query(&#39;[?name == `VRF-A`].switches&#39;) }}&quot;
  switches_query: &#39;[?name == `VRF-A`].switches&#39;
  switches: &quot;{{ fabric.vrfs|json_query(swiches_query) }}&quot;
  • The query string can be concatenated
 switches_query: &quot;{{ &#39;[?name == `&#39; ~ the_vrf ~ &#39;`].switches&#39; }}&quot;

gives the same query (test it in the example playbook)

  switches_query: &#39;[?name == `VRF-A`].switches&#39;

It seems this string might be used in the one-liner

  switches: &quot;{{ fabric.vrms|json_query(&#39;[?name == `&#39; ~ the_vrf ~ &#39;`].switches&#39;) }}&quot;

Unfortunately, this doesn't work and I'm not able to figure out what escaping might be needed, if possible. (Comments on this are more than welcome.) The result of this one-liner is

  switches: &#39;&#39;
  • Example of a complete playbook for testing

<sup>

- hosts: localhost

  vars:

    fabric:
      vrfs:
        - name: VRF-A 
          description: Production-Network
          id: 10001
          vlan: 2002
          switches:
            - serial_number: 10.122.18.114
            - serial_number: 10.122.18.118
        - name: VRF-F
          description: Production-Network
          id: 10001
          vlan: 2022
          switches:
            - serial_number: 10.122.18.114
            - serial_number: 10.122.18.118

    # switches: &quot;{{ fabric.vrfs|json_query(&#39;[?name == `VRF-A`].switches&#39;) }}&quot;
    # switches_query: &#39;[?name == `VRF-A`].switches&#39;
    # switches: &quot;{{ fabric.vrfs|json_query(swiches_query) }}&quot;

    the_vrf: VRF-A
    # switches_query: &quot;{{ &#39;[?name == `&#39; ~ the_vrf ~ &#39;`].switches&#39; }}&quot;
    switches_query: &#39;[?name == `{{ the_vrf }}`].switches&#39;

    # switches: &quot;{{ fabric.vrms|json_query(&#39;[?name == `&#39; ~ the_vrf ~ &#39;`].switches&#39;) }}&quot;
    switches: &quot;{{ fabric.vrfs|json_query(switches_query) }}&quot;

  tasks:

    - debug:
        var: switches_query
    - debug:
        var: switches

</sup>

huangapple
  • 本文由 发表于 2023年2月24日 08:41:39
  • 转载请务必保留本文链接:https://go.coder-hub.com/75551657.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定