[英]merge dictionaries in Ansible that have the same keys
我再次尝试用 Ansible 完成一些事情。
我为每个看起来像这样的服务器构建了一个带有变量的自定义字典。
- name: Create and Add items to server_list
set_fact:
server_list: "{{ server_list | default({}) | combine ({ item.key : item.value }) }}"
with_items:
- { 'key': 'Servername' , 'value': "{{ ansible_hostname }}"}
- { 'key': 'IP-Adresse' , 'value': "{{ ansible_default_ipv4.address }}"}
- { 'key': 'OS' , 'value': "{{ ansible_os_family }} {{ ansible_distribution_major_version }}"}
- { 'key': 'Plattform' , 'value': "{{ ansible_system }}"}
- name: DEBUG server_list
debug:
var=server_list
那行得通。 但是现在 ansible 为每个服务器输出这个,如下所示:
ok: [XXX] => {
"server_list": {
"IP-Adresse": "x.x.x.x",
"OS": "Debian 11",
"Plattform": "Linux",
"Servername": "XXX"
}
}
ok: [YYY] => {
"server_list": {
"IP-Adresse": "x.x.x.y",
"OS": "Debian 11",
"Plattform": "Linux",
"Servername": "YYY"
}
}
...
我现在想要的是每个服务器都有一个完整的“全局”字典。 我认为这看起来像这样。 我想要的示例为 output (此处命名为server_list_dict
):
{
"server_list_dict": {
"0": {
"Servername": "XXX",
"IP-Adresse": "x.x.x.x",
"OS": "Debian 11",
"Plattform": "Linux"
},
"1": {
"Servername": "YYY",
"IP-Adresse": "x.x.x.y",
"OS": "Debian 11",
"Plattform": "Linux"
}
}
}
仅用于澄清我想要实现的目标
我稍后要做的是创建一个 html 表,它应该 output 是这样的。 我要创建的示例 html:
<table style="width:50%">
<!-- table header -->
<tr>
<th>Servername</th>
<th>IP</th>
<th>OS</th>
<th>Platform</th>
</tr>
<!-- table rows -->
<tr>
<td>Hostname1</td>
<td>X.X.X.X</td>
<td>Debian</td>
<td>Linux</td>
</tr>
<tr>
<td>Hostname2</td>
<td>X.X.X.Y</td>
<td>Debian</td>
<td>Linux</td>
</tr>
</table>
我已经有一个模板可以使用。 这将 go 通过我的“全局”字典与每个服务器一起使用,并使用其中的所有键和值。 (希望,无法测试它,因为 idk 如何合并我的听写)
<table style="width:100%">
<!-- table header -->
{% if server_list_dict %}
<tr>
{% for key in server_list_dict[0] %}
<th> {{ key }} </th>
{% endfor %}
</tr>
{% endif %}
<!-- table rows -->
{% for dict_item in server_list_dict %}
<tr>
{% for value in dict_item.values() %}
<td> {{ value }} </td>
{% endfor %}
</tr>
{% endfor %}
</table>
有人知道如何在完整的字典中合并具有相同键的字典吗? 我找不到任何有用的东西。 提前谢谢大家!
提取变量server_list的列表
server_lsts: "{{ ansible_play_hosts|
map('extract', hostvars, 'server_list')|list }}"
给
server_lsts:
- IP-Adresse: x.x.x.x
OS: Debian 11
Plattform: Linux
Servername: XXX
- IP-Adresse: x.x.x.y
OS: Debian 11
Plattform: Linux
Servername: YYY
并创建字典
server_dict: "{{ dict(ansible_play_hosts|zip(server_lsts)) }}"
给
server_dict:
XXX:
IP-Adresse: x.x.x.x
OS: Debian 11
Plattform: Linux
Servername: XXX
YYY:
IP-Adresse: x.x.x.y
OS: Debian 11
Plattform: Linux
Servername: YYY
- hosts: all vars: server_lsts: "{{ ansible_play_hosts| map('extract', hostvars, 'server_list')|list }}" server_dict: "{{ dict(ansible_play_hosts|zip(server_lsts)) }}" tasks: - debug: var: server_dict run_once: true
shell> cat group_vars/all.yml server_list: Servername: "{{ ansible_hostname }}" IP-Adresses: "{{ ansible_all_ipv4_addresses }}" OS: "{{ ansible_os_family }} {{ ansible_distribution_major_version }}" Plattform: "{{ ansible_system }}"
剧本
- hosts: test_11:test_12 vars: server_lsts: "{{ ansible_play_hosts| map('extract', hostvars, 'server_list')|list }}" server_dict: "{{ dict(ansible_play_hosts|zip(server_lsts)) }}" tasks: - debug: var: server_dict run_once: true
给
server_dict: test_11: IP-Adresses: - 10.1.0.61 OS: FreeBSD 13 Plattform: FreeBSD Servername: test_11 test_12: IP-Adresses: - 10.1.0.62 OS: FreeBSD 13 Plattform: FreeBSD Servername: test_12
shell> cat pb.yml - hosts: test_11:test_12 vars: server_lsts: "{{ ansible_play_hosts| map('extract', hostvars, 'server_list')|list }}" params: "start=0 count={{ ansible_play_hosts|length }}" server_dict: "{{ dict(q('sequence', params)|zip(server_lsts)) }}" tasks: - debug: var: server_dict run_once: true
给
server_dict: '0': IP-Adresses: - 10.1.0.61 OS: FreeBSD 13 Plattform: FreeBSD Servername: test_11 '1': IP-Adresses: - 10.1.0.62 OS: FreeBSD 13 Plattform: FreeBSD Servername: test_12
... Ansible 为每个服务器输出这个...我现在有多个 dicts (由于
set_fact
,每个服务器都有)...
这是因为gather_facts
模块 - 收集有关远程主机的事实和set_fact
模块 - 设置主机变量和事实在远程节点和预期行为上分布运行。
我现在想要的是每个服务器都有一个完整的“全局”字典。
我了解您的问题,您希望首先将事实委托给其中一个主机,即控制节点(部署主机或本地主机),您可以在其中创建文件或使用模板进行进一步分发。 在那里,所有信息都将聚合在一个数据结构(字典)中。
文档
您可以按预期直接使用 jinja 创建您的 var:
tasks:
- name: Create and Add items to server_list
set_fact:
server_list: >-
{%- set result = {} -%}
{%- for server in ansible_play_hosts -%}
{%- set idx = loop.index0 -%}
{%- set name = hostvars[server].ansible_hostname -%}
{%- set ip = hostvars[server].ansible_default_ipv4.address -%}
{%- set os = hostvars[server].ansible_os_family -%}
{%- set pf = hostvars[server].ansible_system -%}
{%- set _= result.update({idx:{"Servername": name, "IP": ip, "OS": os, "Platform": pf} }) -%}
{%- endfor -%}
{{ result }}
- debug:
msg: "{{server_list}}"
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.