在 Ansible 中,向字典列表中的每个字典添加一个元素,但将其乘以现有条目

问题描述 投票:0回答:1

我有一个听写列表:

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 jinja2
1个回答
0
投票

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"
        }
    ]
}
© www.soinside.com 2019 - 2024. All rights reserved.