diff --git a/README.md b/README.md index 2bf1be3..98452b7 100644 --- a/README.md +++ b/README.md @@ -50,6 +50,8 @@ 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.ip](https://github.com/ansible-collections/ansible.utils/blob/main/docs/ansible.utils.ip_test.rst)|Test if something in an IP address or network +[ansible.utils.ip_address](https://github.com/ansible-collections/ansible.utils/blob/main/docs/ansible.utils.ip_address_test.rst)|Test if something in an IP address [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_2.yml b/changelogs/fragments/add_netaddr_test_plugins_2.yml new file mode 100644 index 0000000..f48486a --- /dev/null +++ b/changelogs/fragments/add_netaddr_test_plugins_2.yml @@ -0,0 +1,3 @@ +--- +minor_changes: + - Add ip, ip_address test plugins diff --git a/docs/ansible.utils.in_network_test.rst b/docs/ansible.utils.in_network_test.rst index 46b0d84..adf9cfa 100644 --- a/docs/ansible.utils.in_network_test.rst +++ b/docs/ansible.utils.in_network_test.rst @@ -100,7 +100,7 @@ Examples - 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": { diff --git a/docs/ansible.utils.ip_address_test.rst b/docs/ansible.utils.ip_address_test.rst new file mode 100644 index 0000000..4d59e09 --- /dev/null +++ b/docs/ansible.utils.ip_address_test.rst @@ -0,0 +1,150 @@ +.. _ansible.utils.ip_address_test: + + +************************ +ansible.utils.ip_address +************************ + +**Test if something in an IP address** + + +Version added: 2.2.0 + +.. contents:: + :local: + :depth: 1 + + +Synopsis +-------- +- This plugin checks if the provided value is a valid host IP address + + + + +Parameters +---------- + +.. raw:: html + + + + + + + + + + + + + + +
ParameterChoices/DefaultsConfigurationComments
+
+ ip + +
+ string + / required +
+
+ + +
A string that represents the value against which the test is going to be performed
+
{'For example': ['10.1.1.1', 'hello-world']}
+
+
+ + + + +Examples +-------- + +.. code-block:: yaml + + #### Simple examples + + - name: Check if 10.1.1.1 is a valid IP address + ansible.builtin.set_fact: + data: "{{ '10.1.1.1' is ansible.utils.ip_address }}" + + # TASK [Check if 10.1.1.1 is a valid IP address] ************************************* + # ok: [localhost] => { + # "ansible_facts": { + # "data": true + # }, + # "changed": false + # } + + - name: Check if "hello-world" is not a valid IP address + ansible.builtin.set_fact: + data: "{{ 'hello-world' is not ansible.utils.ip_address }}" + + # TASK [Check if "hello-world" is not a valid IP address] **************************** + # ok: [localhost] => { + # "ansible_facts": { + # "data": true + # }, + # "changed": false + # } + + - name: Check if 10.0.0.0/8 is a valid IP address + ansible.builtin.set_fact: + data: "{{ '10.0.0.0/8' is ansible.utils.ip_address }}" + + # TASK [Check if 10.0.0.0/8 is a valid IP address] *********************************** + # ok: [localhost] => { + # "ansible_facts": { + # "data": false + # }, + # "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.ip_test.rst b/docs/ansible.utils.ip_test.rst new file mode 100644 index 0000000..f4445de --- /dev/null +++ b/docs/ansible.utils.ip_test.rst @@ -0,0 +1,174 @@ +.. _ansible.utils.ip_test: + + +**************** +ansible.utils.ip +**************** + +**Test if something in an IP address or network** + + +Version added: 2.2.0 + +.. contents:: + :local: + :depth: 1 + + +Synopsis +-------- +- This plugin checks if the provided value is a valid host or network IP address + + + + +Parameters +---------- + +.. raw:: html + + + + + + + + + + + + + + +
ParameterChoices/DefaultsConfigurationComments
+
+ ip + +
+ string + / required +
+
+ + +
A string that represents the value against which the test is going to be performed
+
{'For example': ['10.1.1.1', '2001:db8:a::123', 'hello-world']}
+
+
+ + + + +Examples +-------- + +.. code-block:: yaml + + #### Simple examples + + - name: Check if 10.1.1.1 is a valid IP address + ansible.builtin.set_fact: + data: "{{ '10.1.1.1' is ansible.utils.ip }}" + + # TASK [Check if 10.1.1.1 is a valid IP address] ***************************** + # ok: [localhost] => { + # "ansible_facts": { + # "data": true + # }, + # "changed": false + # } + + - name: Check if 2001:db8:a::123 is a valid IP address + ansible.builtin.set_fact: + data: "{{ '2001:db8:a::123' is ansible.utils.ip }}" + + # TASK [Check if 2001:db8:a::123 is a valid IP address] ********************** + # ok: [localhost] => { + # "ansible_facts": { + # "data": true + # }, + # "changed": false + # } + + - name: Check if "hello-world" is not a valid IP address + ansible.builtin.set_fact: + data: "{{ 'hello-world' is not ansible.utils.ip }}" + + # TASK [Check if "hello-world" is not a valid IP address] ******************** + # ok: [localhost] => { + # "ansible_facts": { + # "data": true + # }, + # "changed": false + # } + + - name: Check if 300.1.1.1 is a valid IP address + ansible.builtin.set_fact: + data: "{{ '300.1.1.1' is ansible.utils.ip }}" + + # TASK [Check if 300.1.1.1 is a valid IP address] **************************** + # ok: [localhost] => { + # "ansible_facts": { + # "data": false + # }, + # "changed": false + # } + + - name: Check if 10.0.0.0/8 is a valid IP address + ansible.builtin.set_fact: + data: "{{ '10.0.0.0/8' is ansible.utils.ip }}" + + # TASK [Check if 10.0.0.0/8 is a valid IP address] *************************** + # 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/test/ip.py b/plugins/test/ip.py new file mode 100644 index 0000000..edca1b0 --- /dev/null +++ b/plugins/test/ip.py @@ -0,0 +1,133 @@ +# -*- 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: ip +""" + +from __future__ import absolute_import, division, print_function +from ansible_collections.ansible.utils.plugins.plugin_utils.base.ipaddress_utils import ( + ip_network, + _need_ipaddress, + _validate_args, +) + +__metaclass__ = type + +DOCUMENTATION = """ + name: ip + author: Priyam Sahoo (@priyamsahoo) + version_added: "2.2.0" + short_description: Test if something in an IP address or network + description: + - This plugin checks if the provided value is a valid host or network IP address + options: + ip: + description: + - A string that represents the value against which the test is going to be performed + - For example: + - "10.1.1.1" + - "2001:db8:a::123" + - "hello-world" + type: str + required: True + notes: +""" + +EXAMPLES = r""" + +#### Simple examples + +- name: Check if 10.1.1.1 is a valid IP address + ansible.builtin.set_fact: + data: "{{ '10.1.1.1' is ansible.utils.ip }}" + +# TASK [Check if 10.1.1.1 is a valid IP address] ***************************** +# ok: [localhost] => { +# "ansible_facts": { +# "data": true +# }, +# "changed": false +# } + +- name: Check if 2001:db8:a::123 is a valid IP address + ansible.builtin.set_fact: + data: "{{ '2001:db8:a::123' is ansible.utils.ip }}" + +# TASK [Check if 2001:db8:a::123 is a valid IP address] ********************** +# ok: [localhost] => { +# "ansible_facts": { +# "data": true +# }, +# "changed": false +# } + +- name: Check if "hello-world" is not a valid IP address + ansible.builtin.set_fact: + data: "{{ 'hello-world' is not ansible.utils.ip }}" + +# TASK [Check if "hello-world" is not a valid IP address] ******************** +# ok: [localhost] => { +# "ansible_facts": { +# "data": true +# }, +# "changed": false +# } + +- name: Check if 300.1.1.1 is a valid IP address + ansible.builtin.set_fact: + data: "{{ '300.1.1.1' is ansible.utils.ip }}" + +# TASK [Check if 300.1.1.1 is a valid IP address] **************************** +# ok: [localhost] => { +# "ansible_facts": { +# "data": false +# }, +# "changed": false +# } + +- name: Check if 10.0.0.0/8 is a valid IP address + ansible.builtin.set_fact: + data: "{{ '10.0.0.0/8' is ansible.utils.ip }}" + +# TASK [Check if 10.0.0.0/8 is a valid IP address] *************************** +# 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 _ip(ip): + """ Test if something in an IP address or network """ + + params = {"ip": ip} + _validate_args("ip", DOCUMENTATION, params) + + try: + ip_network(ip) + return True + except Exception: + return False + + +class TestModule(object): + """ network jinja test""" + + test_map = {"ip": _ip} + + def tests(self): + return self.test_map diff --git a/plugins/test/ip_address.py b/plugins/test/ip_address.py new file mode 100644 index 0000000..0de06ab --- /dev/null +++ b/plugins/test/ip_address.py @@ -0,0 +1,108 @@ +# -*- 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: ip_address +""" + +from __future__ import absolute_import, division, print_function +from ansible_collections.ansible.utils.plugins.plugin_utils.base.ipaddress_utils import ( + ip_address, + _need_ipaddress, + _validate_args, +) + +__metaclass__ = type + +DOCUMENTATION = """ + name: ip_address + author: Priyam Sahoo (@priyamsahoo) + version_added: "2.2.0" + short_description: Test if something in an IP address + description: + - This plugin checks if the provided value is a valid host IP address + options: + ip: + description: + - A string that represents the value against which the test is going to be performed + - For example: + - "10.1.1.1" + - "hello-world" + type: str + required: True + notes: +""" + +EXAMPLES = r""" + +#### Simple examples + +- name: Check if 10.1.1.1 is a valid IP address + ansible.builtin.set_fact: + data: "{{ '10.1.1.1' is ansible.utils.ip_address }}" + +# TASK [Check if 10.1.1.1 is a valid IP address] ************************************* +# ok: [localhost] => { +# "ansible_facts": { +# "data": true +# }, +# "changed": false +# } + +- name: Check if "hello-world" is not a valid IP address + ansible.builtin.set_fact: + data: "{{ 'hello-world' is not ansible.utils.ip_address }}" + +# TASK [Check if "hello-world" is not a valid IP address] **************************** +# ok: [localhost] => { +# "ansible_facts": { +# "data": true +# }, +# "changed": false +# } + +- name: Check if 10.0.0.0/8 is a valid IP address + ansible.builtin.set_fact: + data: "{{ '10.0.0.0/8' is ansible.utils.ip_address }}" + +# TASK [Check if 10.0.0.0/8 is a valid IP address] *********************************** +# ok: [localhost] => { +# "ansible_facts": { +# "data": false +# }, +# "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 _ip_address(ip): + """Test if something in an IP address""" + + params = {"ip": ip} + _validate_args("ip_address", DOCUMENTATION, params) + + try: + ip_address(ip) + return True + except Exception: + return False + + +class TestModule(object): + """ network jinja test""" + + test_map = {"ip_address": _ip_address} + + def tests(self): + return self.test_map diff --git a/tests/integration/targets/netaddr_test/tasks/include/in_network.yml b/tests/integration/targets/netaddr_test/tasks/include/in_network.yml index 8627f15..256df7b 100644 --- a/tests/integration/targets/netaddr_test/tasks/include/in_network.yml +++ b/tests/integration/targets/netaddr_test/tasks/include/in_network.yml @@ -26,7 +26,6 @@ - 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: diff --git a/tests/integration/targets/netaddr_test/tasks/include/ip.yml b/tests/integration/targets/netaddr_test/tasks/include/ip.yml new file mode 100644 index 0000000..11b76bd --- /dev/null +++ b/tests/integration/targets/netaddr_test/tasks/include/ip.yml @@ -0,0 +1,28 @@ +--- +- name: "ip: Check if 10.1.1.1 is a valid IP address" + assert: + that: "{{ '10.1.1.1' is ansible.utils.ip }}" + +- name: "ip: Check if 2001:db8:a::123 is a valid IP address" + assert: + that: "{{ '2001:db8:a::123' is ansible.utils.ip }}" + +- name: "ip: Check if 10.0.0.0/8 is a valid IP address" + assert: + that: "{{ '10.0.0.0/8' is ansible.utils.ip }}" + +- name: "ip: Test invalidness" + ansible.builtin.set_fact: + criteria_check1: "{{ 'string' is ansible.utils.ip }}" + +- name: "ip: Assert invalidness" + assert: + that: "{{ criteria_check1 == false }}" + +- name: "ip: Test invalidness" + ansible.builtin.set_fact: + criteria_check2: "{{ '300.1.1.1' is ansible.utils.ip }}" + +- name: "ip: Assert invalidness" + assert: + that: "{{ criteria_check2 == false }}" diff --git a/tests/integration/targets/netaddr_test/tasks/include/ip_address.yml b/tests/integration/targets/netaddr_test/tasks/include/ip_address.yml new file mode 100644 index 0000000..b92da2a --- /dev/null +++ b/tests/integration/targets/netaddr_test/tasks/include/ip_address.yml @@ -0,0 +1,32 @@ +--- +- name: "ip_address: Check if 10.1.1.1 is a valid IP address" + assert: + that: "{{ '10.1.1.1' is ansible.utils.ip_address }}" + +- name: "ip_address: Check if 2001:db8:a::123 is a valid IP address" + assert: + that: "{{ '2001:db8:a::123' is ansible.utils.ip_address }}" + +- name: "ip_address: Test invalidness" + ansible.builtin.set_fact: + criteria_check1: "{{ '10.0.0.0/8' is ansible.utils.ip_address }}" + +- name: "ip_address: Assert invalidness" + assert: + that: "{{ criteria_check1 == false }}" + +- name: "ip_address: Test invalidness" + ansible.builtin.set_fact: + criteria_check2: "{{ 'string' is ansible.utils.ip_address }}" + +- name: "ip_address: Assert invalidness" + assert: + that: "{{ criteria_check2 == false }}" + +- name: "ip_address: Test invalidness" + ansible.builtin.set_fact: + criteria_check3: "{{ '300.1.1.1' is ansible.utils.ip_address }}" + +- name: "ip_address: Assert invalidness" + assert: + that: "{{ criteria_check3 == false }}" diff --git a/tests/unit/plugins/test/test_in_any_network.py b/tests/unit/plugins/test/test_in_any_network.py index 3426d6b..802b3c1 100644 --- a/tests/unit/plugins/test/test_in_any_network.py +++ b/tests/unit/plugins/test/test_in_any_network.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright 2020 Red Hat +# Copyright 2021 Red Hat # GNU General Public License v3.0+ # (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) diff --git a/tests/unit/plugins/test/test_in_network.py b/tests/unit/plugins/test/test_in_network.py index 69b0e46..b9ac571 100644 --- a/tests/unit/plugins/test/test_in_network.py +++ b/tests/unit/plugins/test/test_in_network.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright 2020 Red Hat +# Copyright 2021 Red Hat # GNU General Public License v3.0+ # (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) diff --git a/tests/unit/plugins/test/test_in_one_network.py b/tests/unit/plugins/test/test_in_one_network.py index 53fd79e..dc00000 100644 --- a/tests/unit/plugins/test/test_in_one_network.py +++ b/tests/unit/plugins/test/test_in_one_network.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright 2020 Red Hat +# Copyright 2021 Red Hat # GNU General Public License v3.0+ # (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) diff --git a/tests/unit/plugins/test/test_ip.py b/tests/unit/plugins/test/test_ip.py new file mode 100644 index 0000000..f45f7f4 --- /dev/null +++ b/tests/unit/plugins/test/test_ip.py @@ -0,0 +1,46 @@ +# -*- 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 netaddr test plugin: ip +""" + +from __future__ import absolute_import, division, print_function + +__metaclass__ = type + +import unittest +from ansible_collections.ansible.utils.plugins.test.ip import _ip + + +class TestIp(unittest.TestCase): + def setUp(self): + pass + + def test_invalid_data(self): + """Check passing invalid argspec""" + + # missing argument + with self.assertRaises(TypeError) as error: + _ip() + self.assertIn("argument", str(error.exception)) + + def test_valid_data(self): + """Check passing valid data as per criteria""" + + result = _ip(ip="10.1.1.1") + self.assertEqual(result, True) + + result = _ip(ip="2001:db8:a::123") + self.assertEqual(result, True) + + result = _ip(ip="string") + self.assertEqual(result, False) + + result = _ip(ip="300.1.1.1") + self.assertEqual(result, False) + + result = _ip(ip="10.0.0.0/8") + self.assertEqual(result, True) diff --git a/tests/unit/plugins/test/test_ip_address.py b/tests/unit/plugins/test/test_ip_address.py new file mode 100644 index 0000000..de70213 --- /dev/null +++ b/tests/unit/plugins/test/test_ip_address.py @@ -0,0 +1,48 @@ +# -*- 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 netaddr test plugin: ip_address +""" + +from __future__ import absolute_import, division, print_function + +__metaclass__ = type + +import unittest +from ansible_collections.ansible.utils.plugins.test.ip_address import ( + _ip_address, +) + + +class TestIpAddress(unittest.TestCase): + def setUp(self): + pass + + def test_invalid_data(self): + """Check passing invalid argspec""" + + # missing argument + with self.assertRaises(TypeError) as error: + _ip_address() + self.assertIn("argument", str(error.exception)) + + def test_valid_data(self): + """Check passing valid data as per criteria""" + + result = _ip_address(ip="10.1.1.1") + self.assertEqual(result, True) + + result = _ip_address(ip="2001:db8:a::123") + self.assertEqual(result, True) + + result = _ip_address(ip="string") + self.assertEqual(result, False) + + result = _ip_address(ip="300.1.1.1") + self.assertEqual(result, False) + + result = _ip_address(ip="10.0.0.0/8") + self.assertEqual(result, False)