From c09bbacdbc1953cdd020579d360d024cf46fe657 Mon Sep 17 00:00:00 2001 From: Priyam Sahoo <42550351+priyamsahoo@users.noreply.github.com> Date: Mon, 3 May 2021 19:52:35 +0530 Subject: [PATCH] Added 'in_any_network', 'in_network', 'in_one_network' test plugins (#66) Added 'in_any_network', 'in_network', 'in_one_network' test plugins Reviewed-by: https://github.com/apps/ansible-zuul --- README.md | 3 + .../fragments/add_netaddr_test_plugins_1.yml | 3 + docs/ansible.utils.in_any_network_test.rst | 170 ++++++++++++++++ docs/ansible.utils.in_network_test.rst | 183 ++++++++++++++++++ docs/ansible.utils.in_one_network_test.rst | 168 ++++++++++++++++ plugins/plugin_utils/base/ipaddress_utils.py | 86 ++++++++ plugins/test/in_any_network.py | 112 +++++++++++ plugins/test/in_network.py | 128 ++++++++++++ plugins/test/in_one_network.py | 111 +++++++++++ test-requirements.txt | 1 + .../tasks/include/in_any_network.yml | 17 ++ .../netaddr_test/tasks/include/in_network.yml | 33 ++++ .../tasks/include/in_one_network.yml | 16 ++ .../targets/netaddr_test/tasks/main.yaml | 13 ++ .../targets/netaddr_test/vars/main.yaml | 5 + .../unit/plugins/test/test_in_any_network.py | 50 +++++ tests/unit/plugins/test/test_in_network.py | 45 +++++ .../unit/plugins/test/test_in_one_network.py | 50 +++++ 18 files changed, 1194 insertions(+) create mode 100644 changelogs/fragments/add_netaddr_test_plugins_1.yml create mode 100644 docs/ansible.utils.in_any_network_test.rst create mode 100644 docs/ansible.utils.in_network_test.rst create mode 100644 docs/ansible.utils.in_one_network_test.rst create mode 100644 plugins/plugin_utils/base/ipaddress_utils.py create mode 100644 plugins/test/in_any_network.py create mode 100644 plugins/test/in_network.py create mode 100644 plugins/test/in_one_network.py create mode 100644 tests/integration/targets/netaddr_test/tasks/include/in_any_network.yml create mode 100644 tests/integration/targets/netaddr_test/tasks/include/in_network.yml create mode 100644 tests/integration/targets/netaddr_test/tasks/include/in_one_network.yml create mode 100644 tests/integration/targets/netaddr_test/tasks/main.yaml create mode 100644 tests/integration/targets/netaddr_test/vars/main.yaml create mode 100644 tests/unit/plugins/test/test_in_any_network.py create mode 100644 tests/unit/plugins/test/test_in_network.py create mode 100644 tests/unit/plugins/test/test_in_one_network.py diff --git a/README.md b/README.md index f67ddfe..2bf1be3 100644 --- a/README.md +++ b/README.md @@ -47,6 +47,9 @@ Name | Description ### Test plugins Name | Description --- | --- +[ansible.utils.in_any_network](https://github.com/ansible-collections/ansible.utils/blob/main/docs/ansible.utils.in_any_network_test.rst)|Test if Test if an IP or network falls in any network +[ansible.utils.in_network](https://github.com/ansible-collections/ansible.utils/blob/main/docs/ansible.utils.in_network_test.rst)|Test if IP address falls in the network +[ansible.utils.in_one_network](https://github.com/ansible-collections/ansible.utils/blob/main/docs/ansible.utils.in_one_network_test.rst)|Test if IP address belongs in any one of the networks in the list [ansible.utils.validate](https://github.com/ansible-collections/ansible.utils/blob/main/docs/ansible.utils.validate_test.rst)|Validate data with provided criteria diff --git a/changelogs/fragments/add_netaddr_test_plugins_1.yml b/changelogs/fragments/add_netaddr_test_plugins_1.yml new file mode 100644 index 0000000..95f1ed1 --- /dev/null +++ b/changelogs/fragments/add_netaddr_test_plugins_1.yml @@ -0,0 +1,3 @@ +--- +minor_changes: + - Add in_any_network, in_network, in_one_network test plugins diff --git a/docs/ansible.utils.in_any_network_test.rst b/docs/ansible.utils.in_any_network_test.rst new file mode 100644 index 0000000..43c804c --- /dev/null +++ b/docs/ansible.utils.in_any_network_test.rst @@ -0,0 +1,170 @@ +.. _ansible.utils.in_any_network_test: + + +**************************** +ansible.utils.in_any_network +**************************** + +**Test if Test if an IP or network falls in any network** + + +Version added: 2.2.0 + +.. contents:: + :local: + :depth: 1 + + +Synopsis +-------- +- This plugin checks if the provided IP or network address belongs to the provided list network addresses + + + + +Parameters +---------- + +.. raw:: html + + + + + + + + + + + + + + + + + + + + +
ParameterChoices/DefaultsConfigurationComments
+
+ ip + +
+ string + / required +
+
+ + +
A string that represents an IP address of a host or network
+
{'For example': '10.1.1.1'}
+
+
+ networks + +
+ list + / required +
+
+ + +
A list of string and each string represents a network address in CIDR form
+
{'For example': ['10.0.0.0/8', '192.168.1.0/24']}
+
+
+ + + + +Examples +-------- + +.. code-block:: yaml + + #### Simple examples + + - name: Set network list + ansible.builtin.set_fact: + networks: + - "10.0.0.0/8" + - "192.168.1.0/24" + + - name: Check if 10.1.1.1 is in the provided network list + ansible.builtin.set_fact: + data: "{{ '10.1.1.1' is ansible.utils.in_any_network networks }}" + + # TASK [Check if 10.1.1.1 is in the provided network list] ************************** + # ok: [localhost] => { + # "ansible_facts": { + # "data": true + # }, + # "changed": false + # } + + - name: Set network list + ansible.builtin.set_fact: + networks: + - "10.0.0.0/8" + - "192.168.1.0/24" + - "172.16.0.0/16" + + - name: Check if 8.8.8.8 is not in the provided network list + ansible.builtin.set_fact: + data: "{{ '8.8.8.8' is not ansible.utils.in_any_network networks }}" + + # TASK [Check if 8.8.8.8 is not in the provided network list] ************************ + # ok: [localhost] => { + # "ansible_facts": { + # "data": true + # }, + # "changed": false + # } + + + +Return Values +------------- +Common return values are documented `here `_, the following are the fields unique to this test: + +.. raw:: html + + + + + + + + + + + + +
KeyReturnedDescription
+
+ data + +
+ - +
+
+
If jinja test satisfies plugin expression true
+
If jinja test does not satisfy plugin expression false
+
+
+

+ + +Status +------ + + +Authors +~~~~~~~ + +- Priyam Sahoo (@priyamsahoo) + + +.. 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. diff --git a/docs/ansible.utils.in_network_test.rst b/docs/ansible.utils.in_network_test.rst new file mode 100644 index 0000000..46b0d84 --- /dev/null +++ b/docs/ansible.utils.in_network_test.rst @@ -0,0 +1,183 @@ +.. _ansible.utils.in_network_test: + + +************************ +ansible.utils.in_network +************************ + +**Test if IP address falls in the network** + + +Version added: 2.2.0 + +.. contents:: + :local: + :depth: 1 + + +Synopsis +-------- +- This plugin checks if the provided IP address belongs to the provided network + + + + +Parameters +---------- + +.. raw:: html + + + + + + + + + + + + + + + + + + + + +
ParameterChoices/DefaultsConfigurationComments
+
+ ip + +
+ string + / required +
+
+ + +
A string that represents an IP address
+
{'For example': '10.1.1.1'}
+
+
+ network + +
+ string + / required +
+
+ + +
A string that represents the network address in CIDR form
+
{'For example': '10.0.0.0/8'}
+
+
+ + + + +Examples +-------- + +.. code-block:: yaml + + #### Simple examples + + - name: Check if 10.1.1.1 is in 10.0.0.0/8 + ansible.builtin.set_fact: + data: "{{ '10.1.1.1' is ansible.utils.in_network '10.0.0.0/8' }}" + + # TASK [Check if 10.1.1.1 is in 10.0.0.0/8] *********************************** + # ok: [localhost] => { + # "ansible_facts": { + # "data": true + # }, + # "changed": false + # } + + - name: Check if 10.1.1.1 is not in 192.168.1.0/24 + ansible.builtin.set_fact: + data: "{{ '10.1.1.1' is not ansible.utils.in_network '192.168.1.0/24' }}" + + # TASK [Check if 10.1.1.1 is not in 192.168.1.0/24] **************************** + # ok: [localhost] => { + # "ansible_facts": { + # "data": true + # }, + # "changed": false + # } + + - name: Check if 2001:db8:a::123 is in 2001:db8:a::/64 + ansible.builtin.set_fact: + data: "{{ '2001:db8:a::123' is ansible.utils.in_network '2001:db8:a::/64' }}" + + # TASK [Check if 2001:db8:a::123 is in 2001:db8:a::/64] **************************** + # task path: /home/prsahoo/playbooks/collections/localhost_test/utils_in_network.yml:16 + # ok: [localhost] => { + # "ansible_facts": { + # "data": true + # }, + # "changed": false + # } + + - name: Check if 2001:db8:a::123 is not in 10.0.0.0/8 + ansible.builtin.set_fact: + data: "{{ '2001:db8:a::123' is not ansible.utils.in_network '10.0.0.0/8' }}" + + # TASK [Check if 2001:db8:a::123 is not in 10.0.0.0/8] ********************************* + # task path: /home/prsahoo/playbooks/collections/localhost_test/utils_in_network.yml:20 + # ok: [localhost] => { + # "ansible_facts": { + # "data": true + # }, + # "changed": false + # } + + + +Return Values +------------- +Common return values are documented `here `_, the following are the fields unique to this test: + +.. raw:: html + + + + + + + + + + + + +
KeyReturnedDescription
+
+ data + +
+ - +
+
+
If jinja test satisfies plugin expression true
+
If jinja test does not satisfy plugin expression false
+
+
+

+ + +Status +------ + + +Authors +~~~~~~~ + +- Priyam Sahoo (@priyamsahoo) + + +.. 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. diff --git a/docs/ansible.utils.in_one_network_test.rst b/docs/ansible.utils.in_one_network_test.rst new file mode 100644 index 0000000..c697da3 --- /dev/null +++ b/docs/ansible.utils.in_one_network_test.rst @@ -0,0 +1,168 @@ +.. _ansible.utils.in_one_network_test: + + +**************************** +ansible.utils.in_one_network +**************************** + +**Test if IP address belongs in any one of the networks in the list** + + +Version added: 2.2.0 + +.. contents:: + :local: + :depth: 1 + + +Synopsis +-------- +- This plugin checks if the provided IP address belongs to the provided list network addresses + + + + +Parameters +---------- + +.. raw:: html + + + + + + + + + + + + + + + + + + + + +
ParameterChoices/DefaultsConfigurationComments
+
+ ip + +
+ string + / required +
+
+ + +
A string that represents an IP address
+
{'For example': '10.1.1.1'}
+
+
+ networks + +
+ list + / required +
+
+ + +
A list of string and each string represents a network address in CIDR form
+
{'For example': ['10.0.0.0/8', '192.168.1.0/24']}
+
+
+ + + + +Examples +-------- + +.. code-block:: yaml + + #### Simple examples + + - name: Set network list + ansible.builtin.set_fact: + networks: + - "10.0.0.0/8" + - "192.168.1.0/24" + + - name: Check if 10.1.1.1 is in the provided network list + ansible.builtin.set_fact: + data: "{{ '10.1.1.1' is ansible.utils.in_one_network networks }}" + + # TASK [Check if 10.1.1.1 is in the provided network list] ********************** + # ok: [localhost] => { + # "ansible_facts": { + # "data": true + # }, + # "changed": false + + - name: Set network list + ansible.builtin.set_fact: + networks: + - "10.0.0.0/8" + - "10.1.1.0/24" + + - name: Check if 10.1.1.1 is not in the provided network list + ansible.builtin.set_fact: + data: "{{ '10.1.1.1' is not ansible.utils.in_one_network networks }}" + + # TASK [Check if 10.1.1.1 is in not the provided network list] ************************ + # ok: [localhost] => { + # "ansible_facts": { + # "data": true + # }, + # "changed": false + # } + + + +Return Values +------------- +Common return values are documented `here `_, the following are the fields unique to this test: + +.. raw:: html + + + + + + + + + + + + +
KeyReturnedDescription
+
+ data + +
+ - +
+
+
If jinja test satisfies plugin expression true
+
If jinja test does not satisfy plugin expression false
+
+
+

+ + +Status +------ + + +Authors +~~~~~~~ + +- Priyam Sahoo (@priyamsahoo) + + +.. 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. diff --git a/plugins/plugin_utils/base/ipaddress_utils.py b/plugins/plugin_utils/base/ipaddress_utils.py new file mode 100644 index 0000000..25f7bc6 --- /dev/null +++ b/plugins/plugin_utils/base/ipaddress_utils.py @@ -0,0 +1,86 @@ +# -*- 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) + +""" +The utils file for all netaddr tests +""" + +from __future__ import absolute_import, division, print_function + +__metaclass__ = type + +from ansible.errors import AnsibleError +from ansible.module_utils.basic import missing_required_lib +from ansible.module_utils.six import ensure_text +from functools import wraps +from ansible_collections.ansible.utils.plugins.module_utils.common.argspec_validate import ( + check_argspec, +) + +try: + import ipaddress + + HAS_IPADDRESS = True +except ImportError: + HAS_IPADDRESS = False + + +def ip_network(ip): + """ PY2 compat shim, PY2 requires unicode + """ + + if not HAS_IPADDRESS: + raise AnsibleError(missing_required_lib("ipaddress")) + + return ipaddress.ip_network(ensure_text(ip)) + + +def ip_address(ip): + """ PY2 compat shim, PY2 requires unicode + """ + + if not HAS_IPADDRESS: + raise AnsibleError(missing_required_lib("ipaddress")) + + return ipaddress.ip_address(ensure_text(ip)) + + +def _need_ipaddress(func): + @wraps(func) + def wrapper(*args, **kwargs): + if not HAS_IPADDRESS: + raise AnsibleError(missing_required_lib("ipaddress")) + return func(*args, **kwargs) + + return wrapper + + +def _is_subnet_of(network_a, network_b): + try: + if network_a._version != network_b._version: + return False + return ( + network_b.network_address <= network_a.network_address + and network_b.broadcast_address >= network_a.broadcast_address + ) + except Exception: + return False + + +def _validate_args(plugin, doc, params): + """ argspec validator utility function + """ + + valid, argspec_result, updated_params = check_argspec( + doc, plugin + " test", **params + ) + + if not valid: + raise AnsibleError( + "{argspec_result} with errors: {argspec_errors}".format( + argspec_result=argspec_result.get("msg"), + argspec_errors=argspec_result.get("errors"), + ) + ) diff --git a/plugins/test/in_any_network.py b/plugins/test/in_any_network.py new file mode 100644 index 0000000..882cac4 --- /dev/null +++ b/plugins/test/in_any_network.py @@ -0,0 +1,112 @@ +# -*- 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) + +""" +Test plugin file for netaddr tests: in_any_network +""" + +from __future__ import absolute_import, division, print_function +from ansible_collections.ansible.utils.plugins.test.in_network import ( + _in_network, +) +from ansible_collections.ansible.utils.plugins.plugin_utils.base.ipaddress_utils import ( + _validate_args, +) + +__metaclass__ = type + +DOCUMENTATION = """ + name: in_any_network + author: Priyam Sahoo (@priyamsahoo) + version_added: "2.2.0" + short_description: Test if Test if an IP or network falls in any network + description: + - This plugin checks if the provided IP or network address belongs to the provided list network addresses + options: + ip: + description: + - A string that represents an IP address of a host or network + - For example: "10.1.1.1" + type: str + required: True + networks: + description: + - A list of string and each string represents a network address in CIDR form + - For example: ['10.0.0.0/8', '192.168.1.0/24'] + type: list + required: True + notes: +""" + +EXAMPLES = r""" + +#### Simple examples + +- name: Set network list + ansible.builtin.set_fact: + networks: + - "10.0.0.0/8" + - "192.168.1.0/24" + +- name: Check if 10.1.1.1 is in the provided network list + ansible.builtin.set_fact: + data: "{{ '10.1.1.1' is ansible.utils.in_any_network networks }}" + +# TASK [Check if 10.1.1.1 is in the provided network list] ************************** +# ok: [localhost] => { +# "ansible_facts": { +# "data": true +# }, +# "changed": false +# } + +- name: Set network list + ansible.builtin.set_fact: + networks: + - "10.0.0.0/8" + - "192.168.1.0/24" + - "172.16.0.0/16" + +- name: Check if 8.8.8.8 is not in the provided network list + ansible.builtin.set_fact: + data: "{{ '8.8.8.8' is not ansible.utils.in_any_network networks }}" + +# TASK [Check if 8.8.8.8 is not in the provided network list] ************************ +# ok: [localhost] => { +# "ansible_facts": { +# "data": true +# }, +# "changed": false +# } + +""" + +RETURN = """ + data: + description: + - If jinja test satisfies plugin expression C(true) + - If jinja test does not satisfy plugin expression C(false) +""" + + +def _in_any_network(ip, networks): + """Test if an IP or network is in any network""" + + params = {"ip": ip, "networks": networks} + _validate_args("in_any_network", DOCUMENTATION, params) + + bools = [_in_network(ip, network) for network in networks] + if True in bools: + return True + return False + + +class TestModule(object): + """ network jinja test""" + + test_map = {"in_any_network": _in_any_network} + + def tests(self): + return self.test_map diff --git a/plugins/test/in_network.py b/plugins/test/in_network.py new file mode 100644 index 0000000..ef3f0ad --- /dev/null +++ b/plugins/test/in_network.py @@ -0,0 +1,128 @@ +# -*- 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) + +""" +Test plugin file for netaddr tests: in_network +""" + +from __future__ import absolute_import, division, print_function +from ansible_collections.ansible.utils.plugins.plugin_utils.base.ipaddress_utils import ( + ip_network, + _is_subnet_of, + _need_ipaddress, +) +from ansible_collections.ansible.utils.plugins.plugin_utils.base.ipaddress_utils import ( + _validate_args, +) + +__metaclass__ = type + +DOCUMENTATION = """ + name: in_network + author: Priyam Sahoo (@priyamsahoo) + version_added: "2.2.0" + short_description: Test if IP address falls in the network + description: + - This plugin checks if the provided IP address belongs to the provided network + options: + ip: + description: + - A string that represents an IP address + - For example: "10.1.1.1" + type: str + required: True + network: + description: + - A string that represents the network address in CIDR form + - For example: "10.0.0.0/8" + type: str + required: True + notes: +""" + +EXAMPLES = r""" + +#### Simple examples + +- name: Check if 10.1.1.1 is in 10.0.0.0/8 + ansible.builtin.set_fact: + data: "{{ '10.1.1.1' is ansible.utils.in_network '10.0.0.0/8' }}" + +# TASK [Check if 10.1.1.1 is in 10.0.0.0/8] *********************************** +# ok: [localhost] => { +# "ansible_facts": { +# "data": true +# }, +# "changed": false +# } + +- name: Check if 10.1.1.1 is not in 192.168.1.0/24 + ansible.builtin.set_fact: + data: "{{ '10.1.1.1' is not ansible.utils.in_network '192.168.1.0/24' }}" + +# TASK [Check if 10.1.1.1 is not in 192.168.1.0/24] **************************** +# ok: [localhost] => { +# "ansible_facts": { +# "data": true +# }, +# "changed": false +# } + +- name: Check if 2001:db8:a::123 is in 2001:db8:a::/64 + ansible.builtin.set_fact: + data: "{{ '2001:db8:a::123' is ansible.utils.in_network '2001:db8:a::/64' }}" + +# TASK [Check if 2001:db8:a::123 is in 2001:db8:a::/64] **************************** +# task path: /home/prsahoo/playbooks/collections/localhost_test/utils_in_network.yml:16 +# ok: [localhost] => { +# "ansible_facts": { +# "data": true +# }, +# "changed": false +# } + +- name: Check if 2001:db8:a::123 is not in 10.0.0.0/8 + ansible.builtin.set_fact: + data: "{{ '2001:db8:a::123' is not ansible.utils.in_network '10.0.0.0/8' }}" + +# TASK [Check if 2001:db8:a::123 is not in 10.0.0.0/8] ********************************* +# task path: /home/prsahoo/playbooks/collections/localhost_test/utils_in_network.yml:20 +# ok: [localhost] => { +# "ansible_facts": { +# "data": true +# }, +# "changed": false +# } + +""" + +RETURN = """ + data: + description: + - If jinja test satisfies plugin expression C(true) + - If jinja test does not satisfy plugin expression C(false) +""" + + +@_need_ipaddress +def _in_network(ip, network): + """Test if an address or network is in a network""" + + params = {"ip": ip, "network": network} + _validate_args("in_network", DOCUMENTATION, params) + + try: + return _is_subnet_of(ip_network(ip), ip_network(network)) + except Exception: + return False + + +class TestModule(object): + """ network jinja test""" + + test_map = {"in_network": _in_network} + + def tests(self): + return self.test_map diff --git a/plugins/test/in_one_network.py b/plugins/test/in_one_network.py new file mode 100644 index 0000000..7850252 --- /dev/null +++ b/plugins/test/in_one_network.py @@ -0,0 +1,111 @@ +# -*- 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) + +""" +Test plugin file for netaddr tests: in_one_network +""" + +from __future__ import absolute_import, division, print_function +from ansible_collections.ansible.utils.plugins.test.in_network import ( + _in_network, +) +from ansible_collections.ansible.utils.plugins.plugin_utils.base.ipaddress_utils import ( + _validate_args, +) + + +__metaclass__ = type + +DOCUMENTATION = """ + name: in_one_network + author: Priyam Sahoo (@priyamsahoo) + version_added: "2.2.0" + short_description: Test if IP address belongs in any one of the networks in the list + description: + - This plugin checks if the provided IP address belongs to the provided list network addresses + options: + ip: + description: + - A string that represents an IP address + - For example: "10.1.1.1" + type: str + required: True + networks: + description: + - A list of string and each string represents a network address in CIDR form + - For example: ['10.0.0.0/8', '192.168.1.0/24'] + type: list + required: True + notes: +""" + +EXAMPLES = r""" + +#### Simple examples + +- name: Set network list + ansible.builtin.set_fact: + networks: + - "10.0.0.0/8" + - "192.168.1.0/24" + +- name: Check if 10.1.1.1 is in the provided network list + ansible.builtin.set_fact: + data: "{{ '10.1.1.1' is ansible.utils.in_one_network networks }}" + +# TASK [Check if 10.1.1.1 is in the provided network list] ********************** +# ok: [localhost] => { +# "ansible_facts": { +# "data": true +# }, +# "changed": false + +- name: Set network list + ansible.builtin.set_fact: + networks: + - "10.0.0.0/8" + - "10.1.1.0/24" + +- name: Check if 10.1.1.1 is not in the provided network list + ansible.builtin.set_fact: + data: "{{ '10.1.1.1' is not ansible.utils.in_one_network networks }}" + +# TASK [Check if 10.1.1.1 is in not the provided network list] ************************ +# ok: [localhost] => { +# "ansible_facts": { +# "data": true +# }, +# "changed": false +# } + +""" + +RETURN = """ + data: + description: + - If jinja test satisfies plugin expression C(true) + - If jinja test does not satisfy plugin expression C(false) +""" + + +def _in_one_network(ip, networks): + """Test if an IP or network is in one network""" + + params = {"ip": ip, "networks": networks} + _validate_args("in_one_network", DOCUMENTATION, params) + + bools = [_in_network(ip, network) for network in networks] + if bools.count(True) == 1: + return True + return False + + +class TestModule(object): + """ network jinja test""" + + test_map = {"in_one_network": _in_one_network} + + def tests(self): + return self.test_map diff --git a/test-requirements.txt b/test-requirements.txt index 538e15f..e454ff0 100644 --- a/test-requirements.txt +++ b/test-requirements.txt @@ -1,6 +1,7 @@ black==19.3b0 ; python_version > '3.5' coverage==4.5.4 flake8 +ipaddress ; python_version < '3.0' mock ; python_version < '3.5' pytest-xdist yamllint diff --git a/tests/integration/targets/netaddr_test/tasks/include/in_any_network.yml b/tests/integration/targets/netaddr_test/tasks/include/in_any_network.yml new file mode 100644 index 0000000..0c69b04 --- /dev/null +++ b/tests/integration/targets/netaddr_test/tasks/include/in_any_network.yml @@ -0,0 +1,17 @@ +--- +- name: "in_any_network: :Check if 10.1.1.1 is in the provided network list" + assert: + that: + - "{{ '10.1.1.1' is ansible.utils.in_any_network networks }}" + +- name: "in_any_network: Check if 8.8.8.8 is not in the provided network list" + assert: + that: "{{ '8.8.8.8' is not ansible.utils.in_any_network networks }}" + +- name: "in_any_network: Test invalidness" + ansible.builtin.set_fact: + criteria_check: "{{ '192.168.4.56' is ansible.utils.in_any_network networks }}" + +- name: "in_any_network: Assert invalidness" + assert: + that: "{{ criteria_check == false }}" diff --git a/tests/integration/targets/netaddr_test/tasks/include/in_network.yml b/tests/integration/targets/netaddr_test/tasks/include/in_network.yml new file mode 100644 index 0000000..8627f15 --- /dev/null +++ b/tests/integration/targets/netaddr_test/tasks/include/in_network.yml @@ -0,0 +1,33 @@ +--- +- name: "in_network: Check if 10.1.1.1 is in 10.0.0.0/8" + assert: + that: "{{ '10.1.1.1' is ansible.utils.in_network '10.0.0.0/8' }}" + +- name: "in_network: Check if 10.1.1.1 is not in 192.168.1.0/24" + assert: + that: "{{ '10.1.1.1' is not ansible.utils.in_network '192.168.1.0/24' }}" + +- name: "in_network: Test invalidness" + ansible.builtin.set_fact: + criteria_check1: "{{ '8.8.8.8' is ansible.utils.in_network '10.0.0.0/8' }}" + +- name: "in_network: Assert invalidness" + assert: + that: "{{ criteria_check1 == false }}" + +- name: "in_network: Check if 2001:db8:a::123 is in 2001:db8:a::/64" + assert: + that: "{{ '2001:db8:a::123' is ansible.utils.in_network '2001:db8:a::/64' }}" + +- name: "in_network: Check if 2001:db8:a::123 is not in 10.0.0.0/8" + assert: + that: "{{ '2001:db8:a::123' is not ansible.utils.in_network '10.0.0.0/8' }}" + +- name: "in_network: Test invalidness" + ansible.builtin.set_fact: + criteria_check2: "{{ '2001:db8:a::123' is not ansible.utils.in_network '2001:db8:a::/64' }}" + register: result2 + +- name: "in_network: Assert invalidness" + assert: + that: "{{ criteria_check2 == false }}" diff --git a/tests/integration/targets/netaddr_test/tasks/include/in_one_network.yml b/tests/integration/targets/netaddr_test/tasks/include/in_one_network.yml new file mode 100644 index 0000000..cb08c35 --- /dev/null +++ b/tests/integration/targets/netaddr_test/tasks/include/in_one_network.yml @@ -0,0 +1,16 @@ +--- +- name: "in_one_network: Check if 10.1.1.1 is in the provided network list" + assert: + that: "{{ '10.1.1.1' is ansible.utils.in_one_network networks }}" + +- name: "in_one_network: Check if 192.168.3.5 is not in the provided network list" + assert: + that: "{{ '192.168.3.5' is not ansible.utils.in_one_network networks }}" + +- name: "in_one_network: Test invalidness" + ansible.builtin.set_fact: + criteria_check: "{{ '172.168.2.16' is ansible.utils.in_one_network networks }}" + +- name: "in_one_network: Assert invalidness" + assert: + that: "{{ criteria_check == false }}" diff --git a/tests/integration/targets/netaddr_test/tasks/main.yaml b/tests/integration/targets/netaddr_test/tasks/main.yaml new file mode 100644 index 0000000..4274d75 --- /dev/null +++ b/tests/integration/targets/netaddr_test/tasks/main.yaml @@ -0,0 +1,13 @@ +--- +- name: Recursively find all test files + find: + file_type: file + paths: "{{ role_path }}/tasks/include" + recurse: true + use_regex: true + patterns: + - '^(?!_).+$' + register: found + +- include: "{{ item.path }}" + loop: "{{ found.files }}" diff --git a/tests/integration/targets/netaddr_test/vars/main.yaml b/tests/integration/targets/netaddr_test/vars/main.yaml new file mode 100644 index 0000000..ae08764 --- /dev/null +++ b/tests/integration/targets/netaddr_test/vars/main.yaml @@ -0,0 +1,5 @@ +--- +networks: + - "10.0.0.0/8" + - "192.168.1.0/24" + - "172.16.0.0/16" diff --git a/tests/unit/plugins/test/test_in_any_network.py b/tests/unit/plugins/test/test_in_any_network.py new file mode 100644 index 0000000..3426d6b --- /dev/null +++ b/tests/unit/plugins/test/test_in_any_network.py @@ -0,0 +1,50 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 Red Hat +# GNU General Public License v3.0+ +# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +""" +Unit test file for netaddr test plugin: in_any_network +""" + +from __future__ import absolute_import, division, print_function + +__metaclass__ = type + +import unittest +from ansible.errors import AnsibleError +from ansible_collections.ansible.utils.plugins.test.in_any_network import ( + _in_any_network, +) + + +class TestInAnyNetwork(unittest.TestCase): + def setUp(self): + pass + + def test_invalid_data(self): + """Check passing invalid argspec""" + + # invalid argument + with self.assertRaises(AnsibleError) as error: + _in_any_network( + ip="10.1.1.1", + networks={ + "name": "networks", + "value": ["10.0.0.0/8", "192.168.1.0/24"], + }, + ) + self.assertIn("unable to convert to list", str(error.exception)) + + def test_valid_data(self): + """Check passing valid data as per criteria""" + + result = _in_any_network( + ip="10.1.1.1", networks=["10.0.0.0/8", "192.168.1.0/24"] + ) + self.assertEqual(result, True) + + result = _in_any_network( + ip="8.8.8.8", networks=["10.0.0.0/8", "192.168.1.0/24"] + ) + self.assertEqual(result, False) diff --git a/tests/unit/plugins/test/test_in_network.py b/tests/unit/plugins/test/test_in_network.py new file mode 100644 index 0000000..69b0e46 --- /dev/null +++ b/tests/unit/plugins/test/test_in_network.py @@ -0,0 +1,45 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 Red Hat +# GNU General Public License v3.0+ +# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +""" +Unit test file for netaddr test plugin: in_network +""" + +from __future__ import absolute_import, division, print_function + +__metaclass__ = type + +import unittest +from ansible_collections.ansible.utils.plugins.test.in_network import ( + _in_network, +) + + +class TestInNetwork(unittest.TestCase): + def setUp(self): + pass + + def test_invalid_data(self): + """Check passing invalid argspec""" + + # invalid argument + with self.assertRaises(TypeError) as error: + _in_network(ip="10.1.1.1") + self.assertIn("argument", str(error.exception)) + + def test_valid_data(self): + """Check passing valid data as per criteria""" + + result = _in_network(ip="10.1.1.1", network="10.0.0.0/8") + self.assertEqual(result, True) + + result = _in_network(ip="8.8.8.8", network="192.168.1.0/24") + self.assertEqual(result, False) + + result = _in_network(ip="2001:db8:a::123", network="2001:db8:a::/64") + self.assertEqual(result, True) + + result = _in_network(ip="2001:db8:a::123", network="10.0.0.0/8") + self.assertEqual(result, False) diff --git a/tests/unit/plugins/test/test_in_one_network.py b/tests/unit/plugins/test/test_in_one_network.py new file mode 100644 index 0000000..53fd79e --- /dev/null +++ b/tests/unit/plugins/test/test_in_one_network.py @@ -0,0 +1,50 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 Red Hat +# GNU General Public License v3.0+ +# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +""" +Unit test file for netaddr test plugin: in_one_network +""" + +from __future__ import absolute_import, division, print_function + +__metaclass__ = type + +import unittest +from ansible.errors import AnsibleError +from ansible_collections.ansible.utils.plugins.test.in_one_network import ( + _in_one_network, +) + + +class TestInOneNetwork(unittest.TestCase): + def setUp(self): + pass + + def test_invalid_data(self): + """Check passing invalid argspec""" + + # invalid argument + with self.assertRaises(AnsibleError) as error: + _in_one_network( + ip="10.1.1.1", + networks={ + "name": "networks", + "value": ["10.0.0.0/8", "192.168.1.0/24"], + }, + ) + self.assertIn("unable to convert to list", str(error.exception)) + + def test_valid_data(self): + """Check passing valid data as per criteria""" + + result = _in_one_network( + ip="10.1.1.1", networks=["10.0.0.0/8", "192.168.1.0/24"] + ) + self.assertEqual(result, True) + + result = _in_one_network( + ip="8.8.8.8", networks=["10.0.0.0/8", "10.1.1.0/24"] + ) + self.assertEqual(result, False)