Skip to content

Commit

Permalink
Replace ipaddr() with ips_in_ranges()
Browse files Browse the repository at this point in the history
This change implements a filter_plugin that is used in the
ceph-facts, ceph-validate roles and infrastucture-playbooks.
The new filter plugin will return a list of all IP address
that reside in any one of the given IP ranges. The new filter
replaces the use of the ipaddr filter.

ceph.conf already support a comma separated list of CIDRs
for the public_network and cluster_network options.

Changes: [1] and [2] introduced a regression in ceph-ansible
where public_network can no longer be a comma separated list
of cidrs.

With this change a comma separated list of subnet CIDRs can
also be used for monitor_address_block and radosgw_address_block.

[1] commit: d67230b
[2] commit: 20e4852

Related-To: https://bugs.launchpad.net/tripleo/+bug/1840030
Related-To: https://bugzilla.redhat.com/show_bug.cgi?id=1740283

Closes: ceph#4333
Please backport to stable-4.0

Signed-off-by: Harald Jensås <hjensas@redhat.com>
  • Loading branch information
hjensas authored and guits committed Sep 27, 2019
1 parent 74ab59c commit e695efc
Show file tree
Hide file tree
Showing 14 changed files with 85 additions and 16 deletions.
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,5 @@ install:
- pip install ansible-lint pytest
script:
- if [[ -n $(grep --exclude-dir=.git -P "\xa0" -r .) ]]; then echo 'NBSP characters found'; exit 1; fi
- pytest -vvvv library/
- pytest -vvvv library/ plugins/
- for i in $(ls -1 roles/); do ansible-lint -x 204 -v roles/$i/ ; done
1 change: 1 addition & 0 deletions ansible.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ ansible_managed = Please do not change this file directly since it is managed by
library = ./library
action_plugins = plugins/actions
callback_plugins = plugins/callback
filter_plugins = plugins/filter
roles_path = ./roles
# Be sure the user running Ansible has permissions on the logfile
log_path = $HOME/ansible/ansible.log
Expand Down
2 changes: 1 addition & 1 deletion infrastructure-playbooks/purge-cluster.yml
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@
run_once: true

- name: get all nfs-ganesha mount points
command: grep "{{ hostvars[item]['ansible_all_ipv4_addresses'] | ipaddr(public_network) | first }}" /proc/mounts
command: grep "{{ hostvars[item]['ansible_all_ipv4_addresses'] | ips_in_ranges(public_network.split(',')) | first }}" /proc/mounts
register: nfs_ganesha_mount_points
failed_when: false
with_items: "{{ groups[nfs_group_name] }}"
Expand Down
2 changes: 1 addition & 1 deletion infrastructure-playbooks/purge-docker-cluster.yml
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@
run_once: true

- name: get all nfs-ganesha mount points
command: grep "{{ hostvars[item]['ansible_all_ipv4_addresses'] | ipaddr(public_network) | first }}" /proc/mounts
command: grep "{{ hostvars[item]['ansible_all_ipv4_addresses'] | ips_in_ranges(public_network.split(',')) | first }}" /proc/mounts
register: nfs_ganesha_mount_points
failed_when: false
with_items: "{{ groups[nfs_group_name] }}"
Expand Down
Empty file added plugins/filter/__init__.py
Empty file.
30 changes: 30 additions & 0 deletions plugins/filter/ipaddrs_in_ranges.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
from ansible import errors

try:
import netaddr
except ImportError:
# in this case, we'll make the filter return an error message (see bottom)
netaddr = None


class FilterModule(object):
''' IP addresses within IP ranges '''

def ips_in_ranges(self, ip_addresses, ip_ranges):
ips_in_ranges = list()
for ip_addr in ip_addresses:
for ip_range in ip_ranges:
if netaddr.IPAddress(ip_addr) in netaddr.IPNetwork(ip_range):
ips_in_ranges.append(ip_addr)
return ips_in_ranges

def filters(self):
if netaddr:
return {
'ips_in_ranges': self.ips_in_ranges
}
else:
# Need to install python's netaddr for these filters to work
raise errors.AnsibleFilterError(
"The ips_in_ranges filter requires python's netaddr be "
"installed on the ansible controller.")
43 changes: 43 additions & 0 deletions plugins/filter/test_ipaddrs_in_ranges.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
from . import ipaddrs_in_ranges

filter_plugin = ipaddrs_in_ranges.FilterModule()

class TestIpaddrsInRanges(object):

def test_one_ip_one_range(self):
ips = ['10.10.10.1']
ranges = ['10.10.10.1/24']
result = filter_plugin.ips_in_ranges(ips, ranges)
assert ips[0] in result
assert len(result) == 1

def test_two_ip_one_range(self):
ips = ['192.168.1.1', '10.10.10.1']
ranges = ['10.10.10.1/24']
result = filter_plugin.ips_in_ranges(ips, ranges)
assert ips[0] not in result
assert ips[1] in result
assert len(result) == 1

def test_one_ip_two_ranges(self):
ips = ['10.10.10.1']
ranges = ['192.168.1.0/24', '10.10.10.1/24']
result = filter_plugin.ips_in_ranges(ips, ranges)
assert ips[0] in result
assert len(result) == 1

def test_multiple_ips_multiple_ranges(self):
ips = ['10.10.10.1', '192.168.1.1', '172.16.10.1']
ranges = ['192.168.1.0/24', '10.10.10.1/24', '172.16.17.0/24']
result = filter_plugin.ips_in_ranges(ips, ranges)
assert ips[0] in result
assert ips[1] in result
assert ips[2] not in result
assert len(result) == 2

def test_no_ips_in_ranges(self):
ips = ['10.10.20.1', '192.168.2.1', '172.16.10.1']
ranges = ['192.168.1.0/24', '10.10.10.1/24', '172.16.17.0/24']
result = filter_plugin.ips_in_ranges(ips, ranges)
assert result == []

4 changes: 2 additions & 2 deletions roles/ceph-facts/tasks/facts.yml
Original file line number Diff line number Diff line change
Expand Up @@ -313,7 +313,7 @@

- name: set grafana_server_addr fact - ipv4
set_fact:
grafana_server_addr: "{{ hostvars[inventory_hostname]['ansible_all_ipv4_addresses'] | ipaddr(public_network) | first }}"
grafana_server_addr: "{{ hostvars[inventory_hostname]['ansible_all_ipv4_addresses'] | ips_in_ranges(public_network.split(',')) | first }}"
when:
- groups.get(grafana_server_group_name, []) | length > 0
- ip_version == 'ipv4'
Expand All @@ -322,7 +322,7 @@

- name: set grafana_server_addr fact - ipv6
set_fact:
grafana_server_addr: "{{ hostvars[inventory_hostname]['ansible_all_ipv6_addresses'] | ipaddr(public_network) | last | ipwrap }}"
grafana_server_addr: "{{ hostvars[inventory_hostname]['ansible_all_ipv6_addresses'] | ips_in_ranges(public_network.split(',')) | last | ipwrap }}"
when:
- groups.get(grafana_server_group_name, []) | length > 0
- ip_version == 'ipv6'
Expand Down
4 changes: 2 additions & 2 deletions roles/ceph-facts/tasks/set_monitor_address.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
- name: set_fact _monitor_address to monitor_address_block ipv4
set_fact:
_monitor_addresses: "{{ _monitor_addresses | default([]) + [{ 'name': item, 'addr': hostvars[item]['ansible_all_ipv4_addresses'] | ipaddr(hostvars[item]['monitor_address_block']) | first }] }}"
_monitor_addresses: "{{ _monitor_addresses | default([]) + [{ 'name': item, 'addr': hostvars[item]['ansible_all_ipv4_addresses'] | ips_in_ranges(hostvars[item]['monitor_address_block'].split(',')) | first }] }}"
with_items: "{{ groups.get(mon_group_name, []) }}"
when:
- "item not in _monitor_addresses | default([]) | selectattr('name', 'defined') | map(attribute='name') | list"
Expand All @@ -11,7 +11,7 @@

- name: set_fact _monitor_address to monitor_address_block ipv6
set_fact:
_monitor_addresses: "{{ _monitor_addresses | default([]) + [{ 'name': item, 'addr': hostvars[item]['ansible_all_ipv6_addresses'] | ipaddr(hostvars[item]['monitor_address_block']) | last | ipwrap }] }}"
_monitor_addresses: "{{ _monitor_addresses | default([]) + [{ 'name': item, 'addr': hostvars[item]['ansible_all_ipv6_addresses'] | ips_in_ranges(hostvars[item]['monitor_address_block'].split(',')) | last | ipwrap }] }}"
with_items: "{{ groups.get(mon_group_name, []) }}"
when:
- "item not in _monitor_addresses | default([]) | selectattr('name', 'defined') | map(attribute='name') | list"
Expand Down
4 changes: 2 additions & 2 deletions roles/ceph-facts/tasks/set_radosgw_address.yml
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
---
- name: set_fact _radosgw_address to radosgw_address_block ipv4
set_fact:
_radosgw_address: "{{ hostvars[inventory_hostname]['ansible_all_ipv4_addresses'] | ipaddr(radosgw_address_block) | first }}"
_radosgw_address: "{{ hostvars[inventory_hostname]['ansible_all_ipv4_addresses'] | ips_in_ranges(hostvars[item]['radosgw_address_block'].split(',')) | first }}"
when:
- radosgw_address_block is defined
- radosgw_address_block != 'subnet'
- ip_version == 'ipv4'

- name: set_fact _radosgw_address to radosgw_address_block ipv6
set_fact:
_radosgw_address: "{{ hostvars[inventory_hostname]['ansible_all_ipv6_addresses'] | ipaddr(radosgw_address_block) | last | ipwrap }}"
_radosgw_address: "{{ hostvars[inventory_hostname]['ansible_all_ipv6_addresses'] | ips_in_ranges(hostvars[item]['radosgw_address_block'].split(',')) | last | ipwrap }}"
when:
- radosgw_address_block is defined
- radosgw_address_block != 'subnet'
Expand Down
2 changes: 1 addition & 1 deletion roles/ceph-validate/tasks/check_ipaddr_mon.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@
- name: "fail if {{ inventory_hostname }} does not have any {{ ip_version }} address on {{ monitor_address_block }}"
fail:
msg: "{{ inventory_hostname }} does not have any {{ ip_version }} address on {{ monitor_address_block }}"
when: hostvars[inventory_hostname]['ansible_all_' + ip_version + '_addresses'] | ipaddr(hostvars[inventory_hostname]['monitor_address_block']) | length == 0
when: hostvars[inventory_hostname]['ansible_all_' + ip_version + '_addresses'] | ips_in_ranges(hostvars[inventory_hostname]['monitor_address_block'].split(',')) | length == 0
2 changes: 0 additions & 2 deletions tox-podman.ini
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,6 @@ sitepackages=True
setenv=
ANSIBLE_SSH_ARGS = -F {changedir}/vagrant_ssh_config -o ControlMaster=auto -o ControlPersist=600s -o PreferredAuthentications=publickey
ANSIBLE_CONFIG = {toxinidir}/ansible.cfg
ANSIBLE_ACTION_PLUGINS = {toxinidir}/plugins/actions
ANSIBLE_CALLBACK_PLUGINS = {toxinidir}/plugins/callback
ANSIBLE_CALLBACK_WHITELIST = profile_tasks
ANSIBLE_KEEP_REMOTE_FILES = 1
ANSIBLE_CACHE_PLUGIN = memory
Expand Down
2 changes: 0 additions & 2 deletions tox-update.ini
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,6 @@ passenv=*
setenv=
ANSIBLE_SSH_ARGS = -F {changedir}/vagrant_ssh_config -o ControlMaster=auto -o ControlPersist=600s -o PreferredAuthentications=publickey
ANSIBLE_CONFIG = {toxinidir}/ansible.cfg
ANSIBLE_ACTION_PLUGINS = {toxinidir}/plugins/actions
ANSIBLE_CALLBACK_PLUGINS = {toxinidir}/plugins/callback
ANSIBLE_CALLBACK_WHITELIST = profile_tasks
ANSIBLE_CACHE_PLUGIN = memory
ANSIBLE_GATHERING = implicit
Expand Down
3 changes: 1 addition & 2 deletions tox.ini
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ setenv=
ANSIBLE_ACTION_PLUGINS = {toxinidir}/plugins/actions
ANSIBLE_CALLBACK_PLUGINS = {toxinidir}/plugins/callback
ANSIBLE_CALLBACK_WHITELIST = profile_tasks
ANSIBLE_FILTER_PLUGINS = {toxinidir}/plugins/filter
CEPH_STABLE_RELEASE = luminous
# only available for ansible >= 2.5
ANSIBLE_STDOUT_CALLBACK = yaml
Expand Down Expand Up @@ -370,8 +371,6 @@ sitepackages=True
setenv=
ANSIBLE_SSH_ARGS = -F {changedir}/vagrant_ssh_config -o ControlMaster=auto -o ControlPersist=600s -o PreferredAuthentications=publickey
ANSIBLE_CONFIG = {toxinidir}/ansible.cfg
ANSIBLE_ACTION_PLUGINS = {toxinidir}/plugins/actions
ANSIBLE_CALLBACK_PLUGINS = {toxinidir}/plugins/callback
ANSIBLE_CALLBACK_WHITELIST = profile_tasks
ANSIBLE_KEEP_REMOTE_FILES = 1
ANSIBLE_CACHE_PLUGIN = memory
Expand Down

0 comments on commit e695efc

Please sign in to comment.