Ansible中实现嵌套字典内server_node_id与random_attr_name的映射
问题描述
我有如下数据结构:
"my": { "topology": [ { "management_topology": [ { "manager_id": "999999-abcd-1111-bbb-qwerty", "switch": [ { "dc_id": "datacenter-2", "id": "1111111-aaa", "server_node_id": [ "server1", "server2" ], "switch_name": "mgmt-switch" } ] } ], "random_attr_name": "new-mgmt-switch" }, { "management_topology": [ { "manager_id": "999999-abcd-1111-bbb-qwerty", "switch": [ { "dc_id": "datacenter-2", "id": "2222222-bbb", "server_node_id": [ "server3", "server4" ], "switch_name": "server-switch" } ] } ], "random_attr_name": "new-server-switch" }, { "management_topology": [ { "manager_id": "999999-abcd-1111-bbb-qwerty", "switch": [ { "dc_id": "datacenter-2", "id": "3333333-ccc", "server_node_id": [ "server5", "server6" ], "switch_name": "dmz-switch" } ] } ], "random_attr_name": "new-dmz-switch" } ] }
希望生成一个字典,将每个server_node_id的值映射到对应的random_attr_name的值,预期输出:
"some_new_var": { "server1": "new-mgmt-switch", "server2": "new-mgmt-switch", "server3": "new-server-switch", "server4": "new-server-switch", "server5": "new-dmz-switch", "server6": "new-dmz-switch" }
尝试过items2dict、nested_dict、subelements以及Jinja2模板等方法但未成功,需要指导。
解决方案
可以通过循环拓扑列表,结合set_fact逐个构建目标字典,逻辑简单直接,无需复杂过滤器:
- name: 构建server到switch的映射字典 hosts: localhost vars: my: topology: [ { "management_topology": [ { "manager_id": "999999-abcd-1111-bbb-qwerty", "switch": [ { "dc_id": "datacenter-2", "id": "1111111-aaa", "server_node_id": ["server1", "server2"], "switch_name": "mgmt-switch" } ] } ], "random_attr_name": "new-mgmt-switch" }, { "management_topology": [ { "manager_id": "999999-abcd-1111-bbb-qwerty", "switch": [ { "dc_id": "datacenter-2", "id": "2222222-bbb", "server_node_id": ["server3", "server4"], "switch_name": "server-switch" } ] } ], "random_attr_name": "new-server-switch" }, { "management_topology": [ { "manager_id": "999999-abcd-1111-bbb-qwerty", "switch": [ { "dc_id": "datacenter-2", "id": "3333333-ccc", "server_node_id": ["server5", "server6"], "switch_name": "dmz-switch" } ] } ], "random_attr_name": "new-dmz-switch" } ] tasks: - name: 初始化空字典 set_fact: some_new_var: {} - name: 遍历拓扑条目,填充映射关系 set_fact: some_new_var: "{{ some_new_var | combine(item_map) }}" loop: "{{ my.topology }}" vars: # 生成当前拓扑条目中所有server的映射键值对 item_map: "{{ dict(item.management_topology[0].switch[0].server_node_id | product([item.random_attr_name])) }}" - name: 打印结果 debug: var: some_new_var
关键逻辑说明:
- 先初始化一个空字典
some_new_var - 循环
my.topology中的每个条目:- 用
product过滤器把当前条目的server_node_id列表和random_attr_name(包装成单元素列表)做笛卡尔积,得到类似[("server1", "new-mgmt-switch"), ("server2", "new-mgmt-switch")]的结构 - 用
dict过滤器把笛卡尔积转换成临时字典item_map - 用
combine过滤器把临时字典合并到some_new_var中,逐步构建完整映射
- 用
执行后就能得到你需要的字典结构。
内容的提问来源于stack exchange,提问作者piercjs
相关产品推荐
相关产品推荐

