![Ansible - 如何有条件地更改列表中的项目](https://linux22.com/image/792204/Ansible%20-%20%E5%A6%82%E4%BD%95%E6%9C%89%E6%9D%A1%E4%BB%B6%E5%9C%B0%E6%9B%B4%E6%94%B9%E5%88%97%E8%A1%A8%E4%B8%AD%E7%9A%84%E9%A1%B9%E7%9B%AE.png)
我有两个清单:
"combo_all": [
[
null,
"3",
"210
],
[
"r0004",
"65",
"212"
]
和
"zone_name_list": [
{
"dns_zone_id": 10423,
"name": "212.18.172.in-addr.arpa."
},
{
"dns_zone_id": 10424,
"name": ""210.18.172.in-addr.arpa."."
}
每当“名称”中的第一个八位字节与第一个列表中的第三项(210, 212)匹配时,如何用“dns_zone_id”数字(来自第二个列表)替换“combo_all”(第一个列表)中的第三项?
答案1
创建词典octet1_id
dns_zone_id: "{{ zone_name_list|map(attribute='dns_zone_id') }}"
octet1: "{{ zone_name_list|map(attribute='name')
|map('split', '.')
|map('first') }}"
octet1_id: "{{ dict(octet1|zip(dns_zone_id)) }}"
给出
octet1_id:
'210': 10424
'212': 10423
然后创建一个列表
- set_fact:
combo_id: "{{ combo_id|d([]) + [item[:-1] + [octet1_id[item[-1]]]] }}"
loop: "{{ combo_all }}"
给出
combo_id:
- [null, '3', 10424]
- [r0004, '65', 10423]
完整测试剧本的示例
- hosts: all
vars:
combo_all:
- [ null, "3", "210"]
- [ "r0004", "65", "212"]
zone_name_list:
- {dns_zone_id: 10423, name: 212.18.172.in-addr.arpa.}
- {dns_zone_id: 10424, name: 210.18.172.in-addr.arpa.}
dns_zone_id: "{{ zone_name_list|map(attribute='dns_zone_id') }}"
octet1: "{{ zone_name_list|map(attribute='name')
|map('split', '.')
|map('first') }}"
octet1_id: "{{ dict(octet1|zip(dns_zone_id)) }}"
tasks:
- debug:
var: dns_zone_id
- debug:
var: octet1
- debug:
var: octet1_id
- set_fact:
combo_id: "{{ combo_id|d([]) + [item[:-1] + [octet1_id[item[-1]]]] }}"
loop: "{{ combo_all }}"
- debug:
var: combo_id|to_yaml
答案2
总体而言,Ansible 不是一个很好的工具修改数据结构。您可以通过创建新的通过执行以下操作,将变量更改为您想要的内容:
- hosts: localhost
gather_facts: false
vars:
"combo_all": [
[ null, "3", "210" ],
[ "r0004", "65", "212" ]
]
"zone_name_list": [
{
"dns_zone_id": 10423,
"name": "212.18.172.in-addr.arpa."
},
{
"dns_zone_id": 10424,
"name": "210.18.172.in-addr.arpa."
}
]
tasks:
- vars:
new_combo_all: []
prefix: "{{ item[1]['name'].split('.')[0] }}"
set_fact:
new_combo_all: >
{{ new_combo_all + [[item[0][0], item[0][1], item[1]['dns_zone_id']]] }}
loop: "{{ combo_all | product(zone_name_list) }}"
when: prefix == item[0][2]
- debug:
var: new_combo_all
这将设置new_combo_all
为:
ok: [localhost] => {
"new_combo_all": [
[
null,
"3",
10424
],
[
"r0004",
"65",
10423
]
]
}
combo_all
它的工作原理是迭代和的笛卡尔积zone_name_list
,仅选择name
前缀八位字节等于的子列表的第三个成员的那些对combo_all
,并使用它来生成new_combo_all
变量。