ansible - 合并到嵌套的字典数组中
问题描述
我有这样的事情:
vars:
process_names:
- name: myprocess
exe:
- /usr/myexe
- name: myprocess1
exe:
- /usr/myexe1
update1:
- name: myprocess2
exe:
- /usr/myexe2
update2:
- name: myprocess1
exe:
- /opt/myexe1
考虑这process_names
是我想在 2 个不同场景中更新的原始数据。
- 场景 1:
update1
包含名称 asmyprocess2
并且该条目在 中不可用process_names
。因此添加该块。所以process_names
应该变成:
process_names:
- name: myprocess
exe:
- /usr/myexe
- name: myprocess1
exe:
- /usr/myexe1
- name: myprocess2
exe:
- /usr/myexe2
- 方案 2:
update2
包含名称,因为myprocess1
它已经在process_names
. 因此,现有块应该像这样更新:
process_names:
- name: myprocess
exe:
- /usr/myexe
- name: myprocess1
exe:
- /opt/myexe1
- name: myprocess2
exe:
- /usr/myexe2
我通过一个简单的数组连接实现了场景 1(+)
。但是,在我必须执行更新操作的场景 2中挣扎。
到目前为止,我已经尝试过combine
and union
,但没有运气。例如:{{ process_names | union(update2) }}
。需要指导和帮助。
解决方案
如果您将初始列表转换为字典以应用更改,这实际上变得更加容易并且对于这两种情况的操作完全相同。该名称成为唯一键,您只需与您的更新结合(也转换为 dict(s))。完成后,您可以转换回列表。
仅使用原始数据
以下示例process_update.yml
剧本:
---
- name: update a process list
hosts: localhost
gather_facts: false
vars:
process_names:
- name: myprocess
exe:
- /usr/myexe
- name: myprocess1
exe:
- /usr/myexe1
update1:
- name: myprocess2
exe:
- /usr/myexe2
update2:
- name: myprocess1
exe:
- /opt/myexe1
tasks:
- name: Show original list for comparison
debug:
var: process_names
- name: Apply updates to my list
vars:
process_dict: "{{ process_names | items2dict(key_name='name', value_name='exe') }}"
apply_updates:
- update1
- update2
my_dict_updates: "{{ apply_updates | map('extract', vars) | flatten | items2dict(key_name='name', value_name='exe')}}"
updated_process_names: "{{ process_dict | combine(my_dict_updates) | dict2items(key_name='name', value_name='exe') }}"
debug:
var: updated_process_names
给出:
$ ansible-playbook process_update.yml
PLAY [update a process list] ***********************************************************************************************************************************************************************************************************
TASK [Show original list for comparison] ***********************************************************************************************************************************************************************************************
ok: [localhost] => {
"process_names": [
{
"exe": [
"/usr/myexe"
],
"name": "myprocess"
},
{
"exe": [
"/usr/myexe1"
],
"name": "myprocess1"
}
]
}
TASK [Apply updates to my list] ********************************************************************************************************************************************************************************************************
ok: [localhost] => {
"updated_process_names": [
{
"exe": [
"/usr/myexe"
],
"name": "myprocess"
},
{
"exe": [
"/opt/myexe1"
],
"name": "myprocess1"
},
{
"exe": [
"/usr/myexe2"
],
"name": "myprocess2"
}
]
}
PLAY RECAP *****************************************************************************************************************************************************************************************************************************
localhost : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
走得更远
仅当您的列表元素包含 2 个键 (name
和exe
) 时,上述内容才有效。如果您向元素添加一个或多个键,它们将在 list => dict 转换期间丢失。
以下是解决此问题的示例。这绝对不是防弹的,最好的解决方案是 IMO 将您的原始结构从源代码转换为字典。
下面的process_update_revised.yml
剧本
---
- name: update a process list
hosts: localhost
gather_facts: false
vars:
process_names:
- name: myprocess
exe:
- /usr/myexe
a_key: some value
- name: myprocess1
exe:
- /usr/myexe1
a_key: other value
update1:
- name: myprocess2
exe:
- /usr/myexe2
a_key: no value
update2:
- name: myprocess1
exe:
- /opt/myexe1
a_key: changed value
tasks:
- name: Show original dict for comparison
debug:
var: process_names
- name: Apply updates to my list
vars:
process_dict: "{{ process_names | groupby('name') | map('flatten') | items2dict(key_name=0, value_name=1) }}"
apply_updates:
- update1
- update2
my_dict_updates: "{{ apply_updates | map('extract', vars) | flatten | groupby('name') | map('flatten') | items2dict(key_name=0, value_name=1) }}"
updated_process_names: "{{ process_dict | combine(my_dict_updates) | dict2items | map(attribute='value') }}"
debug:
var: updated_process_names
给出:
$ ansible-playbook process_update_revised.yml
PLAY [update a process list] ***********************************************************************************************************************************************************************************************************
TASK [Show original dict for comparison] ***********************************************************************************************************************************************************************************************
ok: [localhost] => {
"process_names": [
{
"a_key": "some value",
"exe": [
"/usr/myexe"
],
"name": "myprocess"
},
{
"a_key": "other value",
"exe": [
"/usr/myexe1"
],
"name": "myprocess1"
}
]
}
TASK [Apply updates to my list] ********************************************************************************************************************************************************************************************************
ok: [localhost] => {
"updated_process_names": [
{
"a_key": "some value",
"exe": [
"/usr/myexe"
],
"name": "myprocess"
},
{
"a_key": "changed value",
"exe": [
"/opt/myexe1"
],
"name": "myprocess1"
},
{
"a_key": "no value",
"exe": [
"/usr/myexe2"
],
"name": "myprocess2"
}
]
}
推荐阅读
- javascript - 将我通过 node.js 请求(https.get)获得的变量传输到另一个 js 文件
- python - 在 Huey 任务中运行 Scrapy 蜘蛛(django 项目)
- c# - 使用 HttpContent.ReadAsAsync 时代码停止
- postgresql - 备份 keycloak 数据库会备份所有内容吗?
- django - 如何将表单字段错误返回到在不同的 Django 视图中呈现的模板
- css - 如何为 SVG SMIL 动画添加缓动?
- twitter-bootstrap - Laravel 混合 | Bootstrap 弃用警告:不推荐使用 / 进行除法,并将被删除
- node.js - Mongoose 在测试中不抛出 E11000 重复键错误
- java - Volley CallBack 方法没有给出响应?
- vb.net - 除数而不四舍五入且不带小数