我有一个听写列表:
vars:
sites:
- name: "Tampa"
site_number: 0
- name: "Miami"
site_number: 1
- name: "Daytona"
site_number: 2
我想向此列表中的每个字典添加一个条目,但将其乘以一个值。我尝试过以下方法:
- set_fact:
sites: >-
{{
sites | map('combine', {
'site_subnet': '172.16.0.' + (item.site_number*8)|string + '/29',
'test1': item.site_number
}) | list
}}
loop: "{{ sites }}"
- debug: var=sites
现在,结果输出显示
sites[n].test1
始终为 2,当然,site_subnet
始终为 172.16.0.16/29。我的代码有什么问题?
Ansible 通常不是用于修改数据结构的好工具。您可以通过创建一个 new 变量来获得你想要的东西,如下所示:
- hosts: localhost
gather_facts: false
vars:
sites:
- name: "Tampa"
site_number: 0
- name: "Miami"
site_number: 1
- name: "Daytona"
site_number: 2
tasks:
- set_fact:
new_sites: >-
{{
new_sites + [item | combine({
'site_subnet': '172.16.0.' ~ (item.site_number*8) ~ '/29',
'test1': item.site_number
})]
}}
loop: "{{ sites }}"
vars:
new_sites: []
- debug:
var: new_sites
这会产生以下输出(这是我认为你想要的):
TASK [debug] *************************************************************************************************************************************************************
ok: [localhost] => {
"new_sites": [
{
"name": "Tampa",
"site_number": 0,
"site_subnet": "172.16.0.0/29",
"test1": 0
},
{
"name": "Miami",
"site_number": 1,
"site_subnet": "172.16.0.8/29",
"test1": 1
},
{
"name": "Daytona",
"site_number": 2,
"site_subnet": "172.16.0.16/29",
"test1": 2
}
]
}
对于任何类型的复杂逻辑,我总是发现使用自定义过滤器更易于管理。我会将以下内容放入
filter_plugins/filters.py
:
def filter_update_sites(sites):
return [
site | {
"site_subnet": f"172.16.0.{site['site_number']*8}/29"
}
for site in sites
]
class FilterModule:
def filters(self):
return {
"update_sites": filter_update_sites,
}
然后像这样编写剧本:
- hosts: localhost
gather_facts: false
vars:
sites:
- name: "Tampa"
site_number: 0
- name: "Miami"
site_number: 1
- name: "Daytona"
site_number: 2
tasks:
- set_fact:
new_sites: "{{ sites | update_sites }}"
- debug:
var: new_sites
产生:
TASK [debug] *************************************************************************************************************************************************************
ok: [localhost] => {
"new_sites": [
{
"name": "Tampa",
"site_number": 0,
"site_subnet": "172.16.0.0/29"
},
{
"name": "Miami",
"site_number": 1,
"site_subnet": "172.16.0.8/29"
},
{
"name": "Daytona",
"site_number": 2,
"site_subnet": "172.16.0.16/29"
}
]
}