'Ansible - Ensure list of IP addresses is valid against list of networks
Given a list of IP addresses, for example:
ip_addresses:
- 192.168.10.198
- 192.168.52.7
- 192.168.109.78
A list of networks, for example:
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
I'd like to assert that all entries in the ip_addresses list are a valid IP in one of the networks in the valid_networks list.
In the above example, it should fail because 192.168.109.78 isn't valid against any of the valid_networks.
Something like this will loop over the nested list and return true or false for each iteration, but I need to turn that into a useful overall pass or fail output. i.e., if there is no true for an IP address, it will fail and return the message “IP address x is not valid”. I'm struggling to come up with the accompanying logic.
- debug:
msg: "{{ item.1 | network_in_usable(item.0) }}"
with_nested:
- "{{ ip_addresses }}"
- "{{ valid_networks }}"
Many thanks in advance.
Solution 1:[1]
Use ansible.utils.ipaddr. For example
- set_fact:
vn_dict: "{{ vn_dict|d({})|
combine({item: ip_addresses|ansible.utils.ipaddr(item)}) }}"
loop: "{{ valid_networks }}"
creates the dictionary
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]
This can be used to get the list of valid IP addresses
vn_dict.values()|flatten:
- 192.168.10.198
- 192.168.52.7
Then, the task below
- assert:
that: item in valid_ips
fail_msg: "IP address {{ item }} is not valid."
loop: "{{ ip_addresses }}"
vars:
valid_ips: "{{ vn_dict.values()|flatten }}"
tests the validity of the IP addresses one by one
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.”
Optionally, to assert that all entries in the ip_addresses list are a valid IPs in one of the networks in the valid_networks list, the task below
- 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) }}"
tests the validity of the IP addresses in one step
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."
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 |
