Ansible:如何从外部数据源将字典列表填充至嵌套字典ixes
实现方法:从PeeringDB数据填充IX邻居列表
需求说明
现有Ansible变量ixes,需从外部数据源peeringdb_response_net中提取符合条件的记录,填充ixes下各条目的ix_neighbors字段,要求:
- 仅保留
status为ok、operational为true,且ixlan_id与ixes对应条目匹配的记录 - 为每条匹配记录生成按序号命名的
ix_neighbor_short_name(如rs1、rs2)
原始数据结构
目标变量ixes
vars: ixes: ix_id_001: ix_short_name: 'ix1' ixlan_id: '331' ix_neighbors: ix_id_002: ix_short_name: 'ix2' ixlan_id: '222' ix_neighbors:
数据源peeringdb_response_net
{"peeringdb_response_net": { "data": [ { "aka": "BIX.BG", "netixlan_set": [ { "asn": 15669, "ipaddr4": "193.169.199.10", "ipaddr6": "2001:7f8:58::3d35:0:2", "ixlan_id": 331, "operational": true, "status": "ok" }, { "asn": 15669, "ipaddr4": "193.169.198.10", "ipaddr6": "2001:7f8:58::3d35:0:1", "ixlan_id": 331, "operational": true, "status": "ok" } ] } ] }}
具体实现(Ansible任务)
步骤1:预处理有效Netixlan条目
先筛选出所有符合基础条件的Netixlan记录,避免后续重复过滤:
- name: 提取PeeringDB中有效Netixlan条目 set_fact: valid_netixlans: "{{ peeringdb_response_net.data | json_query('[].netixlan_set[]') | selectattr('status', 'equalto', 'ok') | selectattr('operational', 'equalto', true) | list }}"
步骤2:遍历填充ixes的ix_neighbors
遍历ixes的每个条目,匹配对应ixlan_id的有效记录,生成带序号的邻居列表并更新变量:
- name: 填充IX邻居列表 set_fact: ixes: "{{ ixes | combine({ item.key: item.value | combine({ 'ix_neighbors': _neighbors }) }, recursive=True) }}" loop: "{{ ixes | dict2items }}" vars: # 匹配当前IX对应的Netixlan条目(注意类型转换:ixes中ixlan_id是字符串,需转int) _matching_netixlans: "{{ valid_netixlans | selectattr('ixlan_id', 'equalto', item.value.ixlan_id | int) | list }}" # 生成带序号的邻居字典列表 _neighbors: "{{ _matching_netixlans | enumerate(start=1) | map('combine', {'value': {'ix_neighbor_short_name': 'rs' ~ (item.0 + 1)}}) | map(attribute='value') | map('json_query', '{ix_neighbor_ipv4_addr: ipaddr4, ix_neighbor_short_name: ix_neighbor_short_name}') | list }}"
最终效果
执行上述任务后,ixes将更新为目标结构:
vars: ixes: ix_id_001: ix_short_name: 'ix1' ixlan_id: '331' ix_neighbors: - { ix_neighbor_ipv4_addr: '193.169.199.10', ix_neighbor_short_name: 'rs1' } - { ix_neighbor_ipv4_addr: '193.169.198.10', ix_neighbor_short_name: 'rs2' } ix_id_002: ix_short_name: 'ix2' ixlan_id: '222' ix_neighbors:
内容的提问来源于stack exchange,提问作者Andrey Grigorian
相关产品推荐
相关产品推荐

