源数据是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键的迭代器,然后在发生匹配的循环部分中返回该迭代器的值的方法。
您没有给出选择匹配键名的所有要求,但以下内容应该可以使您步入正轨。
要点:
dict2tems
filter将顶级字典转换为dict2tems
对象的列表{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) }}