Ansible + JMESPath:包含与嵌套数据的匹配项时返回键的名称

问题描述 投票:0回答:1

源数据是JSON字典,其中顶级键名是不可预测的。当嵌套的数据与我拥有的字符串匹配时,我需要该TL键的名称。

我正在使用Ansible 2.9中的json_query过滤器进行尝试。

我尝试了各种JMESPath查询并搜索了它们的文档,但是我发现的所有内容似乎都要求提前知道这些键的名称。

这里是样本数据-它是从ansible ios_facts模块针对接口输出的:

{
        "GigabitEthernet0/9": {
            "description": "server",
            "ipv4": [],
            "macaddress": "b8zz.xxxx.7709",
            "type": "Gigabit Ethernet"
        },
        "Vlan13": {
            "description": null,
            "ipv4": [
                {
                    "address": "10.20.30.19",
                    "subnet": "24"
                }
            ],
            "macaddress": "b8zz.xxx.yy41",
            "type": "EtherSVI"
        }
}

这里是我正在使用的剧本:

---
- name: Cisco IOS - Mgmt Int
  connection: network_cli
  gather_facts: false
  hosts: switch01
  vars:
     netdb: "{{ hostvars[inventory_hostname]['ansible_net_interfaces'] }}"
  tasks:
    - name: get ios facts
      ios_facts:
        gather_subset: interfaces
    - name: json_query
      set_fact:
        mgmtinf: "{{ netdb | json_query(query) }}"
      vars:
        # this gets me true/false
        query: "[Vlan13.ipv4[0].address.contains(@, '10.20.30.19')]"
    - name: output json_query
      debug:
        var: mgmtinf

如果结果匹配,上面的方法将返回true / false。问题是我已经手动定义了接口来查看“ Vlan13”。因此,我需要一种用于该TL键的迭代器,然后在发生匹配的循环部分中返回该迭代器的值的方法。

ansible jmespath
1个回答
1
投票

您没有给出选择匹配键名的所有要求,但以下内容应该可以使您步入正轨。

要点:

  • 使用dict2tems filter将顶级字典转换为dict2tems对象的列表
  • 使用jmespath可以:
    1. 过滤掉对应于VLAN的元素(我在示例中使用了“ Vlan *”)
    2. 滤除每个{key: X, value: Y}元素的IP列表,使其仅匹配您所需的IP。

Note:我的表达式中的ipv4是克服ansible与jmespath(字符串类型映射)之间的通信中的to_json | from_json所必需的。

这里是说明上述情况的示例任务。

current bug

以及我用您当前的值得到的结果:

    - name: Filter out specific ip elements on my vlans
      vars:
        vals: {
          "GigabitEthernet0/9": {
            "description": "server",
            "ipv4": [],
            "macaddress": "b8zz.xxxx.7709",
            "type": "Gigabit Ethernet"
          },
          "Vlan13": {
            "description": null,
            "ipv4": [
            {
              "address": "10.20.30.19",
              "subnet": "24"
            }
            ],
            "macaddress": "b8zz.xxx.yy41",
            "type": "EtherSVI"
          }
        }
        query: >-
          [?starts_with(key, 'Vlan')].value.ipv4[] | [?contains(address, '10.20.30.19')]
      debug:
        msg: >-
          {{ vals | dict2items | to_json | from_json | json_query(query) }}

推荐问答