Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ Name | Description
[ansible.utils.param_list_compare](https://github.com/ansible-collections/ansible.utils/blob/main/docs/ansible.utils.param_list_compare_filter.rst)|Generate the final param list combining/comparing base and provided parameters.
[ansible.utils.previous_nth_usable](https://github.com/ansible-collections/ansible.utils/blob/main/docs/ansible.utils.previous_nth_usable_filter.rst)|This filter returns the previous nth usable ip within a network described by value.
[ansible.utils.reduce_on_network](https://github.com/ansible-collections/ansible.utils/blob/main/docs/ansible.utils.reduce_on_network_filter.rst)|This filter reduces a list of addresses to only the addresses that match a given network.
[ansible.utils.reduce_on_networks](https://github.com/ansible-collections/ansible.utils/blob/main/docs/ansible.utils.reduce_on_networks_filter.rst)|This filter reduces a list of addresses to only the addresses that match any of the given networks.
[ansible.utils.remove_keys](https://github.com/ansible-collections/ansible.utils/blob/main/docs/ansible.utils.remove_keys_filter.rst)|Remove specific keys from a data recursively.
[ansible.utils.replace_keys](https://github.com/ansible-collections/ansible.utils/blob/main/docs/ansible.utils.replace_keys_filter.rst)|Replaces specific keys with their after value from a data recursively.
[ansible.utils.slaac](https://github.com/ansible-collections/ansible.utils/blob/main/docs/ansible.utils.slaac_filter.rst)|This filter returns the SLAAC address within a network for a given HW/MAC address.
Expand Down
151 changes: 151 additions & 0 deletions docs/ansible.utils.reduce_on_networks_filter.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
.. _ansible.utils.reduce_on_networks_filter:


********************************
ansible.utils.reduce_on_networks
********************************

**This filter reduces a list of addresses to only the addresses that match any of the given networks.**


Version added: 6.0.0

.. contents::
:local:
:depth: 1


Synopsis
--------
- This filter reduces a list of addresses to only the addresses that match any of the given networks.
- To check whether multiple addresses belong to any of the networks, use the reduce_on_networks filter.
- To check which of the IP address of a host can be used to talk to another host, use the reduce_on_networks filter.




Parameters
----------

.. raw:: html

<table border=0 cellpadding=0 class="documentation-table">
<tr>
<th colspan="1">Parameter</th>
<th>Choices/<font color="blue">Defaults</font></th>
<th>Configuration</th>
<th width="100%">Comments</th>
</tr>
<tr>
<td colspan="1">
<div class="ansibleOptionAnchor" id="parameter-"></div>
<b>networks</b>
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
<div style="font-size: small">
<span style="color: purple">list</span>
/ <span style="color: purple">elements=string</span>
/ <span style="color: red">required</span>
</div>
</td>
<td>
</td>
<td>
</td>
<td>
<div>The networks to validate against.</div>
</td>
</tr>
<tr>
<td colspan="1">
<div class="ansibleOptionAnchor" id="parameter-"></div>
<b>value</b>
<a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a>
<div style="font-size: small">
<span style="color: purple">list</span>
/ <span style="color: purple">elements=string</span>
/ <span style="color: red">required</span>
</div>
</td>
<td>
</td>
<td>
</td>
<td>
<div>the list of addresses to filter on.</div>
</td>
</tr>
</table>
<br/>




Examples
--------

.. code-block:: yaml

- name: To check whether multiple addresses belong to any of the networks, use the reduce_on_networks filter.
debug:
msg: "{{ ['192.168.0.34', '10.3.0.3', '192.168.2.34'] | ansible.utils.reduce_on_networks( ['192.168.0.0/24', '192.128.0.0/9', '127.0.0.1/8'] ) }}"

# TASK [To check whether multiple addresses belong to any of the networks, use the reduce_on_networks filter.] ***********
# task path: /Users/amhatre/ansible-collections/playbooks/test_reduce_on_network.yaml:7
# Loading collection ansible.utils from /Users/amhatre/ansible-collections/collections/ansible_collections/ansible/utils
# ok: [localhost] => {
# "msg": {
# "192.168.0.34": [
# "192.168.0.0/24",
# "192.128.0.0/9"
# ],
# "192.168.2.34": [
# "192.128.0.0/9"
# ]
# }
# }



Return Values
-------------
Common return values are documented `here <https://docs.ansible.com/ansible/latest/reference_appendices/common_return_values.html#common-return-values>`_, the following are the fields unique to this filter:

.. raw:: html

<table border=0 cellpadding=0 class="documentation-table">
<tr>
<th colspan="1">Key</th>
<th>Returned</th>
<th width="100%">Description</th>
</tr>
<tr>
<td colspan="1">
<div class="ansibleOptionAnchor" id="return-"></div>
<b>data</b>
<a class="ansibleOptionLink" href="#return-" title="Permalink to this return value"></a>
<div style="font-size: small">
<span style="color: purple">dictionary</span>
</div>
</td>
<td></td>
<td>
<div>Returns the filtered addresses belonging to any of the networks. The dict&#x27;s key is the address, the value is a list of the matching networks</div>
<br/>
</td>
</tr>
</table>
<br/><br/>


Status
------


Authors
~~~~~~~

- Jonny007-MKD


.. hint::
Configuration entries for each entry type have a low to high priority order. For example, a variable that is lower in the list will override a variable that is higher up.
127 changes: 127 additions & 0 deletions plugins/filter/reduce_on_networks.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
# -*- coding: utf-8 -*-
# Copyright 2021 Red Hat
# GNU General Public License v3.0+
# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)

"""
filter plugin file for ipaddr filters: reduce_on_networks
"""
from __future__ import absolute_import, division, print_function

from functools import partial

from ansible.errors import AnsibleFilterError

from ansible_collections.ansible.utils.plugins.filter.reduce_on_network import (
reduce_on_network,
)
from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import (
AnsibleArgSpecValidator,
)


__metaclass__ = type


try:
from jinja2.filters import pass_environment
except ImportError:
from jinja2.filters import environmentfilter as pass_environment


DOCUMENTATION = """
name: reduce_on_networks
author: Jonny007-MKD
version_added: "6.0.0"
short_description: This filter reduces a list of addresses to only the addresses that match any of the given networks.
description:
- This filter reduces a list of addresses to only the addresses that match any of the given networks.
- To check whether multiple addresses belong to any of the networks, use the reduce_on_networks filter.
- To check which of the IP address of a host can be used to talk to another host, use the reduce_on_networks filter.
options:
value:
description: the list of addresses to filter on.
type: list
elements: str
required: True
networks:
description: The networks to validate against.
type: list
elements: str
required: True
notes:
"""

EXAMPLES = r"""

- name: To check whether multiple addresses belong to any of the networks, use the reduce_on_networks filter.
debug:
msg: "{{ ['192.168.0.34', '10.3.0.3', '192.168.2.34'] | ansible.utils.reduce_on_networks( ['192.168.0.0/24', '192.128.0.0/9', '127.0.0.1/8'] ) }}"

# TASK [To check whether multiple addresses belong to any of the networks, use the reduce_on_networks filter.] ***********
# task path: /Users/amhatre/ansible-collections/playbooks/test_reduce_on_network.yaml:7
# Loading collection ansible.utils from /Users/amhatre/ansible-collections/collections/ansible_collections/ansible/utils
# ok: [localhost] => {
# "msg": {
# "192.168.0.34": [
# "192.168.0.0/24",
# "192.128.0.0/9"
# ],
# "192.168.2.34": [
# "192.128.0.0/9"
# ]
# }
# }
"""

RETURN = """
data:
type: dict
key type: str
value type: list of str
description:
- Returns the filtered addresses belonging to any of the networks. The dict's key is the address, the value is a list of the matching networks
"""


@pass_environment
def _reduce_on_networks(*args, **kwargs):
"""This filter returns a dict of the filtered addresses belonging to any of the networks"""
keys = ["value", "networks"]
data = dict(zip(keys, args[1:]))
data.update(kwargs)
aav = AnsibleArgSpecValidator(data=data, schema=DOCUMENTATION, name="reduce_on_networks")
valid, errors, updated_data = aav.validate()
if not valid:
raise AnsibleFilterError(errors)
return reduce_on_networks(**updated_data)


def reduce_on_networks(value, networks):
"""
Reduces a list of addresses to only the addresses that match any of the given networks.
:param: value: The list of addresses to filter on.
:param: network: The list of networks to validate against.
:return: A dict of the reduced addresses and their networks.
"""

r = {}
for network in networks:
matches = reduce_on_network(value, network)
for match in matches:
match_networks = r.setdefault(match, [])
match_networks.append(network)
return r


class FilterModule(object):
"""IP address and network manipulation filters"""

filter_map = {
# IP addresses and networks
"reduce_on_networks": _reduce_on_networks,
}

def filters(self):
"""ipaddr filter"""
return self.filter_map
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
- name: Reduce_on_networks filter test1
ansible.builtin.set_fact:
result1: "{{ ['192.168.0.34', '10.3.0.3', '192.168.2.34'] | ansible.utils.reduce_on_network(['192.168.0.0/24', '127.0.0.0/8', '192.128.0.0/9']) }}"

- name: Assert result for reduce_on_network.
ansible.builtin.assert:
that: "{{ result1 == { '192.168.0.34': ['192.168.0.0/24', '192.128.0.0/9'], '192.168.2.34': ['192.128.0.0/9'], } }}
60 changes: 60 additions & 0 deletions tests/unit/plugins/filter/test_reduce_on_networks.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
# -*- coding: utf-8 -*-
# Copyright 2021 Red Hat
# GNU General Public License v3.0+
# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)

"""
Unit test file for reduce_on_networks filter plugin
"""

from __future__ import absolute_import, division, print_function


__metaclass__ = type

from unittest import TestCase

from ansible.errors import AnsibleError

from ansible_collections.ansible.utils.plugins.filter.reduce_on_networks import _reduce_on_networks


class Test_reduce_on_networks(TestCase):
def setUp(self):
pass

def test_invalid_data(self):
"""Check passing invalid argspec"""

# missing required arguments
args = [""]
kwargs = {}
with self.assertRaises(AnsibleError) as error:
_reduce_on_networks(*args, **kwargs)
self.assertIn("missing required arguments: value", str(error.exception))

# wrong input value type
args = ["", ""]
kwargs = {}
with self.assertRaises(AnsibleError) as error:
_reduce_on_networks(*args, **kwargs)
self.assertIn("missing required arguments: value", str(error.exception))

# wrong networks type
args = ["", ["192.168.0.0"], ""]
kwargs = {}
with self.assertRaises(AnsibleError) as error:
_reduce_on_networks(*args, **kwargs)
self.assertIn("missing required arguments: value", str(error.exception))

def test_reduce_on_networks_filter_1(self):
"""reduce_on_network filter"""
list1 = ["192.168.0.34", "10.3.0.3", "192.168.2.34"]
list2 = ["192.168.0.0/24", "127.0.0.0/8", "192.128.0.0/9"]
args = ["", list1, list2]
result = _reduce_on_network(*args)
expected = {
"192.168.0.34": ["192.168.0.0/24", "192.128.0.0/9"],
"192.168.2.34": ["192.128.0.0/9"],
}
self.assertEqual(result, expected)
Loading