Ansible jinja 测试列表是否包含有效的 IP 地址并生成模板

Ansible jinja test list if contains valid IP address and generate template

我在 Ansible 中有以下变量:

my_allowed_hosts2:
  - {host: patch, address: '202.167.24.50'}
  - {host:localhost, address: '::1/128', extra_field: trust}

my_ferm_groups:
  - firewall_whitelist1
  - firewall_whitelist2

我有一个任务是检查 my_allowed_hosts2 中是否有有效的 IP 地址,如果是,则为其生成一个模板(在这种情况下,我是 运行 剧本所针对的主机在我的清单中的 firewall_whitelist2 组中)。然后使用此模板生成 ferm/iptable 规则以允许 my_allowed_hosts2 中的 IP 地址访问主机。

但是,如果 my_allowed_hosts2 中没有有效地址,我不想为其生成模板 (firewall_whitelist_2),即使 myhost 是该组 - 因为如果它没有有效的 IP 地址,模板将变得无效。希望我到目前为止是有道理的。

相关任务:

- set_fact:
    valid_addresses: "{{ my_allowed_hosts2|json_query('[*].address')| map('ipaddr')|reject('match','^127.0.0.1|::1/128') | list }}"

- debug:
    msg: "{{ valid_addresses }}"


- name: Loop dictionary and copy group configs in place
  template: src=etc/ferm/ferm.d/{{ item }}.j2 dest=/etc/ferm/ferm.d/{{ item }}.conf owner=root group=root mode=0640
  when: item in my_ferm_groups
  with_items: "{{ group_names | reject ('match','^firewall_whitelist2$') if valid_addresses is not any }}"

如果在 my_allowed_hosts2 列表中没有测试 true 值,我在上面尝试做的是尝试从循环中删除 firewall_whitelist2 - 从而阻止它创建特定的模板。

但是,我收到以下错误:

fatal: [myhost]: FAILED! => {
   "msg": "the inline if-expression on line 1 evaluated to false and no else section was defined."
}

我所期待的(如果 valid_addresses 而不是 空)是类似于下面的内容。相应地复制模板:

ok: [myhost] => (item=firewall_whitelist1) => {"ansible_loop_var": "item", "changed": false, "checksum": "21f42490d91da92c6f404a30df6e34373266b72f", "dest": "/etc/ferm/ferm.d/firewall_whitelist1.j2", "gid": 0, "group": "root", "item": "firewall_whitelist1", "mode": "0640", "owner": "root", "path": "/etc/ferm/ferm.d/firewall_whitelist1.conf", "secontext": "system_u:object_r:etc_t:s0", "size": 570, "state": "file", "uid": 0}

changed: [myhost] => (item=firewall_whitelist2) => {"ansible_loop_var": "item", "changed": false, "checksum": "985d207faa196b285c20c7f60f6aa69b23f908b9", "dest": "/etc/ferm/ferm.d/firewall_whitelist2.j2, "gid": 0, "group": "root", "item": "firewall_whitelist2", "mode": "0640", "owner": "root", "path": "/etc/ferm/ferm.d/firewall_whitelist2.conf", "secontext": "system_u:object_r:etc_t:s0", "size": 705, "state": "file", "uid": 0}

我也尝试过将 firewall_whitelist2 添加到列表中,这样只有当 valid_addresses 不为空时才会生成模板:

- name: Loop dictionary and copy group configs in place
  template: src=etc/ferm/ferm.d/{{ item }}.j2 dest=/etc/ferm/ferm.d/{{ item }}.conf owner=root group=root mode=0640
  when: item in my_ferm_groups
  loop: "{{ group_names + 'firewall_whitelist2' if valid_addresses|length > 0 else group_names }}"

但是这个错误与

FAILED! => {"msg": "Unexpected templating type error occurred on ({{ group_names + 'firewall_whitelist2' if valid_addresses|length > 0 else group_names }}): can only concatenate list (not \"str\") to list"}`

知道我怎样才能完成这项工作吗?
基本上,我试图找到一种方法,仅在条件匹配时才为 firewall_whitelist_2 生成该模板(在 my_allowed_hosts2 中检测到有效的 IP 地址)。
任何朝着正确方向的推动都会有所帮助。

下面的任务

    - set_fact:
        valid_addresses: "{{ my_allowed_hosts2|
                             json_query('[].address')|
                             map('ipaddr')|
                             difference(['127.0.0.1', '::1/128']) }}"
    - debug:
        var: valid_addresses

给予

    "valid_addresses": [
        "202.167.24.50"
    ]

这可能是您正在寻找的循环吗?

    - debug:
        var: item
      loop: "{{ group_names|difference(['firewall_whitelist2']) }}"
      when:
        - item in my_ferm_groups
        - valid_addresses|length > 0

让我觉得你正在努力适应 loop 应该在 when 中的内容。

所以最终你可能会在一个空数组上循环,而你也可以在填充列表上循环并跳过所有项目。

当移动 when 中的所有这些条件时,我们最终可能会得到:

- template: 
    src: /etc/ferm/ferm.d/{{ item }}.j2 
    dest: /etc/ferm/ferm.d/{{ item }}.conf 
    owner: root 
    group: root 
    mode: 0640
  when:
    - item in my_ferm_groups
    - item != 'firewall_whitelist2' or valid_addresses|length > 0
  loop: "{{ group_names }}"

这里有两个例子:

  • 当没有匹配的IP时
    - hosts: all
      gather_facts: no
    
      tasks:
        - debug:
            msg: "{{ item }}"
          when:
            - item in my_ferm_groups
            - item != 'firewall_whitelist2' or valid_addresses|length > 0
          loop: "{{ group_names }}"
          vars:
            valid_addresses: []
            group_names:
              - firewall_whitelist1
              - firewall_whitelist2
              - firewall_whitelist3 
              - firewall_whitelist4
            my_ferm_groups:
              - firewall_whitelist1
              - firewall_whitelist2
              - firewall_whitelist3 
    
    这给出了回顾:
    PLAY [all] *******************************************************************************************************
    
    TASK [debug] *****************************************************************************************************
    ok: [localhost] => (item=firewall_whitelist1) => {
        "msg": "firewall_whitelist1"
    }
    skipping: [localhost] => (item=firewall_whitelist2) 
    ok: [localhost] => (item=firewall_whitelist3) => {
        "msg": "firewall_whitelist3"
    }
    skipping: [localhost] => (item=firewall_whitelist4) 
    
    PLAY RECAP *******************************************************************************************************
    localhost                  : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
    
  • 当有匹配的IP时
    - hosts: all
      gather_facts: no
    
      tasks:
        - debug:
            msg: "{{ item }}"
          when:
            - item in my_ferm_groups 
            - item != 'firewall_whitelist2' or valid_addresses|length > 0
          loop: "{{ group_names }}"
          vars:
            valid_addresses:
              - 10.1.1.1
            group_names:
              - firewall_whitelist1
              - firewall_whitelist2
              - firewall_whitelist3 
              - firewall_whitelist4
            my_ferm_groups:
              - firewall_whitelist1
              - firewall_whitelist2
              - firewall_whitelist3 
    
    这给出了回顾:
    PLAY [all] *******************************************************************************************************
    
    TASK [debug] *****************************************************************************************************
    ok: [localhost] => (item=firewall_whitelist1) => {
        "msg": "firewall_whitelist1"
    }
    ok: [localhost] => (item=firewall_whitelist2) => {
        "msg": "firewall_whitelist2"
    } 
    ok: [localhost] => (item=firewall_whitelist3) => {
        "msg": "firewall_whitelist3"
    }
    skipping: [localhost] => (item=firewall_whitelist4) 
    
    PLAY RECAP *******************************************************************************************************
    localhost                  : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
    

有了这一切,您正在填充的 valid_addresses 将保持原样。