Ansible:如何从字典列表中提取含指定服务器的集群
问题:筛选包含指定服务器的集群字典列表
需求说明
我拥有一个服务器名称列表server_list,以及一个包含环境中所有集群的字典列表full_cluster_dict——每个集群字典包含key(集群名)和value(对应服务器列表)。需要生成仅包含server_list中服务器所在集群的字典列表needed_cluster_dict。
现有数据示例
full_cluster_dict
"full_cluster_dict": [ { "key": "cluster_a", "value": [ "ca_server1", "ca_server2", "ca_server3", "ca_server4", "ca_server5", "ca_server6", "ca_server7", "ca_server8" ] }, { "key": "cluster_b", "value": [ "cb_server1", "cb_server2", "cb_server3" ] }, { "key": "cluster_c", "value": [ "cc_server1", "cc_server2", "cc_server3", "cc_server4" ] } ]
server_list
"server_list": [ "ca_server1", "cb_server2", "ca_server6" ]
期望结果
"needed_cluster_dict": [ { "key": "cluster_a", "value": [ "ca_server1", "ca_server2", "ca_server3", "ca_server4", "ca_server5", "ca_server6", "ca_server7", "ca_server8" ] }, { "key": "cluster_b", "value" : [ "cb_server1", "cb_server2", "cb_server3" ] } ]
尝试的代码及问题
我尝试了以下Ansible代码:
- name: extract only relevant clusters based on the list of servers ansible.builtin.set_fact: needed_cluster_dict: "{{ needed_cluster_dict|d({}) | combine({item: cluster_filter}) }}" with_items: "{{ server_list }}" vars: cluster_filter: "{{ sds_dict|dict2items|json_query(_query) }}" _query: '[?value.contains(@, `{{ item }}`)].value'
但返回结果是以服务器名为键的字典,不符合预期:
needed_cluster_list: { "ca_server1": [ "ca_server1", "ca_server2", "ca_server3", "ca_server4" ], "ca_server2": [ "ca_server1", "ca_server2", "ca_server3", "ca_server4" ], ... }
解决方案
方法1:利用json_query直接筛选
通过json_query判断集群的服务器列表是否与server_list存在交集,一步完成筛选:
- name: Filter relevant clusters with json_query ansible.builtin.set_fact: needed_cluster_dict: "{{ full_cluster_dict | json_query('[?value[?@ in ' ~ server_list | to_json ~ ']]') | unique }}"
方法2:循环筛选+去重
通过遍历每个集群,判断该集群是否包含server_list中的任意服务器,符合条件则加入结果列表,最后去重避免重复:
- name: Initialize empty cluster list ansible.builtin.set_fact: needed_cluster_dict: [] - name: Add clusters containing target servers ansible.builtin.set_fact: needed_cluster_dict: "{{ needed_cluster_dict + [item] }}" loop: "{{ full_cluster_dict }}" when: item.value | intersect(server_list) | length > 0 - name: Remove duplicate clusters ansible.builtin.set_fact: needed_cluster_dict: "{{ needed_cluster_dict | unique }}"
说明
- 方法1代码更简洁,依赖
json_query的原生能力,适合场景简单的情况; - 方法2逻辑更清晰,便于后续扩展自定义判断规则;
- 两种方法都会确保结果仅保留包含目标服务器的集群,且不会出现重复条目。
内容的提问来源于stack exchange,提问作者piercjs
相关产品推荐
相关产品推荐

