循环迭代会覆盖字典列表中先前的值

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

其中一项任务会生成以下字典列表:

"ne_hosts": [
        {
            "instance_class": "docker_host",
            "ip": "10.11.12.15"
        },
        {
            "instance_class": "vm_host",
            "ip": "10.11.12.13"
        }
    ]

我想用额外的键值对更新每个字典,使其成为:

"ne_hosts_updated": [
        {
            "instance_class": "docker_host",
            "ip": "10.11.12.15",
            "ip_present": 1
        },
        {
            "instance_class": "vm_host",
            "ip": "10.11.12.13",
            "ip_present": 0
        }
    ]

启动以下两个任务:a)检查条件并生成辅助变量;b)根据满足的条件用键值对更新初始列表(如果在配置文件中找到 IP,则返回代码为 0,否则为1):

    - name: Check if host IP is present in a config file
      ansible.builtin.command: grep -q "{{ target_config_file_location }}" -e "{{ item.ip }}"
      loop: "{{ ne_hosts }}"
      ignore_errors: true
      register: ip_present

    - name: Update the IPs list
      set_fact:
        ne_hosts_updated: "{{ ne_hosts | default([]) | map('combine', {'ip_present': item.rc }) | list }}"
      loop: "{{ ip_present.results }}"

这些任务完成后,额外的键值对将添加到每个字典中。但是,

ip_present
键的值始终对应于最后检查的IP,因此:

"ne_hosts_updated": [
        {
            "instance_class": "docker_host",
            "ip": "10.11.12.15",
            "ip_present": 1
        },
        {
            "instance_class": "vm_host",
            "ip": "10.11.12.13",
            "ip_present": 1
        }
    ]

或:

"ne_hosts_updated": [
        {
            "instance_class": "docker_host",
            "ip": "10.11.12.15",
            "ip_present": 0
        },
        {
            "instance_class": "vm_host",
            "ip": "10.11.12.13",
            "ip_present": 0
        }
    ]

如何确保循环迭代不会覆盖之前的值并生成与当前检查的 IP 值相对应的值?

ansible ansible-2.x
1个回答
0
投票

例如,给定文件,

shell> cat /tmp/target.conf 
10.11.12.11
10.11.12.12
10.11.12.13

将内容读入变量更简单。 (还有其他选项/模块 fetchslurp ...为了简单起见,让我们保留模块 command)。

    - command: "cat {{ target_config_file_location }}"
      register: target_conf

给予

  target_conf.stdout:
    10.11.12.11
    10.11.12.12
    10.11.12.13

然后,在 Jinja 中使用它

  ne_hosts_updated: |
    {% for i in ne_hosts %}
    {% if i.ip in target_conf.stdout %}
    {{ i|combine({'ip_present': 0}) }}
    {% else %}
    {{ i|combine({'ip_present': 1}) }}
    {% endif %}
    {% endfor %}

给你想要的东西

  ne_hosts_updated:
    {'ip': '10.11.12.15', 'instance_class': 'docker_host', 'ip_present': 1}
    {'ip': '10.11.12.13', 'instance_class': 'vm_host', 'ip_present': 0}

用于测试的完整剧本示例

- hosts: all

  vars:

    ne_hosts:
      - {ip: 10.11.12.15, instance_class: docker_host}
      - {ip: 10.11.12.13, instance_class: vm_host}

    target_config_file_location: /tmp/target.conf
    ne_hosts_updated: |
      {% for i in ne_hosts %}
      {% if i.ip in target_conf.stdout %}
      {{ i|combine({'ip_present': 0}) }}
      {% else %}
      {{ i|combine({'ip_present': 1}) }}
      {% endif %}
      {% endfor %}

  tasks:

    - command: "cat {{ target_config_file_location }}"
      register: target_conf
    - debug:
        var: target_conf.stdout

    - debug:
        var: ne_hosts_updated
© www.soinside.com 2019 - 2024. All rights reserved.