Ansible:从一个列表构建一个字典(其中的值是列表)



我需要一些看起来微不足道但我无法处理的东西

"ansible_mounts": [
{
"device": "/device1",
"mount": "/"
},
{
"device": "/device1",
"mount": "/home"
},
{
"device": "/device2",
"mount": "/boot"
}
]

我需要一本以设备为键、以挂载为值的字典。我不知道如何获得列表作为值,我只知道如何获得单个项目(因此在每个循环中,最后一个项目都被覆盖(:

- name: Getting all the mounted filesystems (by device)
ansible.builtin.set_fact: 
filesystems_by_device: "{{ item }}"
with_items:
- "{{ ansible_mounts | items2dict(key_name='device', value_name='mount') }}"

输出为:

"filesystems_by_device": {
"device2": "/boot",
"device1": "/home"
}

我需要:

"filesystems_by_device": {
"device2": [ "/boot" ],
"device1": [ "/", "/home" ]
}

例如,我了解如何从过滤后的列表中构建列表,我可能需要应用类似于我的字典的东西:

- name: List from filtered one
set_fact:
foo: "{{ foo + [item] }}"
with_items:
- "{{ ansible_mounts }}"
when: item.mount in another_list
vars:
foo: []

我尝试了很多东西,但我对这种语法感到困惑。

感谢的任何帮助

这实际上并不像看上去那么微不足道,我认为除非开发自定义过滤器,否则没有一个解决方案不在任务中循环(正如您已经尝试过的那样(。以下是我如何在简单的标准ansible中实现这一点。

  • 在列表中设备的唯一名称上创建一个循环
  • 每个项目的set_fact提取该设备的装载点的值

演示剧本:

---
- hosts: localhost
gather_facts: false
vars:
"ansible_mounts": [
{
"device": "/device1",
"mount": "/"
},
{
"device": "/device1",
"mount": "/home"
},
{
"device": "/device2",
"mount": "/boot"
}
]
tasks:
- name: Construct the needed datastructure
set_fact:
filesystems_by_device: >-
{{
filesystems_by_device | default({})
| combine({
item: ansible_mounts | selectattr('device', 'eq', item) | map(attribute='mount') | list
})
}}
loop: "{{ ansible_mounts | map(attribute='device') | unique | sort }}"
- name: Show result
debug:
var: filesystems_by_device

结果:

PLAY [localhost] ***********************************************************************************************************************************************************************************************************************
TASK [Construct the needed datastructure] **********************************************************************************************************************************************************************************************
ok: [localhost] => (item=/device1)
ok: [localhost] => (item=/device2)
TASK [Show result] *********************************************************************************************************************************************************************************************************************
ok: [localhost] => {
"filesystems_by_device": {
"/device1": [
"/",
"/home"
],
"/device2": [
"/boot"
]
}
}
PLAY RECAP *****************************************************************************************************************************************************************************************************************************
localhost                  : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

最新更新