Ansible - 确保 IP 地址列表对网络列表有效

Ansible - Ensure list of IP addresses is valid against list of networks

给定一个 IP 地址列表,例如:

ip_addresses:
  - 192.168.10.198
  - 192.168.52.7
  - 192.168.109.78

网络列表,例如:

valid_networks:
  - 192.168.10.0/24
  - 192.168.22.0/23
  - 192.168.50.0/21
  - 192.168.202.0/23
  - 192.168.205.0/24
  - 192.168.222.0/24

我想声明 ip_addresses 列表中的所有条目在 valid_networks 列表中的网络之一中都是有效的 IP。

在上面的示例中,它应该会失败,因为 192.168.109.78 对任何 valid_networks.

都无效

像这样的东西会遍历嵌套列表,return 每次迭代都是真或假,但我需要把它变成有用的整体通过或失败输出。即,如果 IP 地址没有 true,它将失败并且 return 消息“IP 地址 x 无效”。我正在努力想出伴随的逻辑。

- debug:
    msg: "{{ item.1 | network_in_usable(item.0) }}"
  with_nested:
    - "{{ ip_addresses }}"
    - "{{ valid_networks }}"

非常感谢。

使用ansible.utils.ipaddr。例如

    - set_fact:
        vn_dict: "{{ vn_dict|d({})|
                     combine({item: ip_addresses|ansible.utils.ipaddr(item)}) }}"
      loop: "{{ valid_networks }}"

创建字典

  vn_dict:
    192.168.10.0/24: [192.168.10.198]
    192.168.202.0/23: []
    192.168.205.0/24: []
    192.168.22.0/23: []
    192.168.222.0/24: []
    192.168.50.0/21: [192.168.52.7]

这可用于获取有效 IP 地址列表

  vn_dict.values()|flatten:
  - 192.168.10.198
  - 192.168.52.7

那么,下面的任务

    - assert:
        that: item in valid_ips
        fail_msg: "IP address {{ item }} is not valid."
      loop: "{{ ip_addresses }}"
      vars:
        valid_ips: "{{ vn_dict.values()|flatten }}"

逐一测试IP地址的有效性

TASK [assert] *****************************************************
ok: [localhost] => (item=192.168.10.198) => changed=false 
  ansible_loop_var: item
  item: 192.168.10.198
  msg: All assertions passed
ok: [localhost] => (item=192.168.52.7) => changed=false 
  ansible_loop_var: item
  item: 192.168.52.7
  msg: All assertions passed
failed: [localhost] (item=192.168.109.78) => changed=false 
  ansible_loop_var: item
  assertion: item in valid_ips
  evaluated_to: false
  item: 192.168.109.78
  msg: “IP address 192.168.109.78 is not valid.”

可选地,断言 ip_addresses 列表中的所有条目都是 [=37= 中的一个网络中的有效 IP ]列表,下面的任务

    - assert:
        that: valid_ips_diff|length == 0
        fail_msg: "IP address(es) {{ valid_ips_diff }} not valid."
      vars:
        valid_ips: "{{ vn_dict.values()|flatten }}"
        valid_ips_diff: "{{ ip_addresses|difference(valid_ips) }}"

一步测试IP地址的有效性

TASK [assert] *****************************************************
fatal: [localhost]: FAILED! => changed=false 
  assertion: valid_ips_diff|length == 0
  evaluated_to: false
  msg: "IP address(es) ['192.168.109.78'] not valid."