我想用 ansible 更新列表,其中包含基于特定条件的字典项
例如:
list1:
- {"name": "test1", "uid": 100, "gid": 250}
- {"name": "test2", "uid": 101, "gid": 250}
- {"name": "test3", "uid": 103, "gid": 250}
- {"name": "test4", "uid": 104, "gid": 250}
list2: [100, 101]
list3: [102,103]
如果 uid 与 list2 中的项目匹配,它将更改 gid=300,如果与 list3 匹配,它将更新为 400,其余项目在 list1 中保持不变
请建议我如何根据上述条件生成列表 1
答案1
例如
- set_fact:
l4: "{{ l4|d([]) + [item|combine({'gid': _gid|from_yaml})] }}"
loop: "{{ list1 }}"
vars:
_gid: |
{% if item.uid in list2 %}
300
{% elif item.uid in list3 %}
400
{% else %}
{{ item.gid }}
{% endif %}
给出
l4|to_yaml: |-
- {gid: 300, name: test1, uid: 100}
- {gid: 300, name: test2, uid: 101}
- {gid: 400, name: test3, uid: 103}
- {gid: 250, name: test4, uid: 104}
更新
在 Ansible 2.12 及更高版本中,无需迭代列表。而是在管道中更新列表。以下表达式给出相同的结果
dict_default: "{{ list1|items2dict(key_name='uid', value_name='gid') }}"
dict_x: "{{ dict_default|
combine(dict(list2|product([300]) + list3|product([400]))) }}"
gid_x: "{{ list1|map(attribute='uid')|map('extract', dict_x)|list }}"
gid_x_update: "{{ gid_x|map('community.general.dict_kv', 'gid')|list }}"
list4: "{{ list1|zip(gid_x_update)|map('combine')|list }}"
细节
dict_default:
100: 250
101: 250
103: 250
104: 250
dict_x:
100: 300
101: 300
102: 400
103: 400
104: 250
gid_x:
- 300
- 300
- 400
- 250
gid_x_update:
- gid: 300
- gid: 300
- gid: 400
- gid: 250