From e92cc6e78ddcd139dc19c9642c85043f5ec7bd8e Mon Sep 17 00:00:00 2001
From: Priyam Sahoo <42550351+priyamsahoo@users.noreply.github.com>
Date: Sat, 8 May 2021 00:00:00 +0530
Subject: [PATCH] Added ipv4 specefic test plugins (#69)
Added ipv4 specefic test plugins
Reviewed-by: https://github.com/apps/ansible-zuul
---
README.md | 4 +
.../fragments/add_netaddr_test_plugins_3.yml | 3 +
docs/ansible.utils.ipv4_address_test.rst | 150 ++++++++++++++++++
docs/ansible.utils.ipv4_hostmask_test.rst | 138 ++++++++++++++++
docs/ansible.utils.ipv4_netmask_test.rst | 150 ++++++++++++++++++
docs/ansible.utils.ipv4_test.rst | 150 ++++++++++++++++++
plugins/test/ipv4.py | 108 +++++++++++++
plugins/test/ipv4_address.py | 108 +++++++++++++
plugins/test/ipv4_hostmask.py | 96 +++++++++++
plugins/test/ipv4_netmask.py | 108 +++++++++++++
.../netaddr_test/tasks/include/ipv4.yml | 24 +++
.../tasks/include/ipv4_address.yml | 28 ++++
.../tasks/include/ipv4_hostmask.yml | 20 +++
.../tasks/include/ipv4_netmask.yml | 20 +++
tests/unit/plugins/test/test_ipv4.py | 43 +++++
tests/unit/plugins/test/test_ipv4_address.py | 45 ++++++
tests/unit/plugins/test/test_ipv4_hostmask.py | 45 ++++++
tests/unit/plugins/test/test_ipv4_netmask.py | 45 ++++++
18 files changed, 1285 insertions(+)
create mode 100644 changelogs/fragments/add_netaddr_test_plugins_3.yml
create mode 100644 docs/ansible.utils.ipv4_address_test.rst
create mode 100644 docs/ansible.utils.ipv4_hostmask_test.rst
create mode 100644 docs/ansible.utils.ipv4_netmask_test.rst
create mode 100644 docs/ansible.utils.ipv4_test.rst
create mode 100644 plugins/test/ipv4.py
create mode 100644 plugins/test/ipv4_address.py
create mode 100644 plugins/test/ipv4_hostmask.py
create mode 100644 plugins/test/ipv4_netmask.py
create mode 100644 tests/integration/targets/netaddr_test/tasks/include/ipv4.yml
create mode 100644 tests/integration/targets/netaddr_test/tasks/include/ipv4_address.yml
create mode 100644 tests/integration/targets/netaddr_test/tasks/include/ipv4_hostmask.yml
create mode 100644 tests/integration/targets/netaddr_test/tasks/include/ipv4_netmask.yml
create mode 100644 tests/unit/plugins/test/test_ipv4.py
create mode 100644 tests/unit/plugins/test/test_ipv4_address.py
create mode 100644 tests/unit/plugins/test/test_ipv4_hostmask.py
create mode 100644 tests/unit/plugins/test/test_ipv4_netmask.py
diff --git a/README.md b/README.md
index 98452b7..0fc2d12 100644
--- a/README.md
+++ b/README.md
@@ -52,6 +52,10 @@ Name | Description
[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.ipv4](https://github.com/ansible-collections/ansible.utils/blob/main/docs/ansible.utils.ipv4_test.rst)|Test if something is an IPv4 address or network
+[ansible.utils.ipv4_address](https://github.com/ansible-collections/ansible.utils/blob/main/docs/ansible.utils.ipv4_address_test.rst)|Test if something is an IPv4 address
+[ansible.utils.ipv4_hostmask](https://github.com/ansible-collections/ansible.utils/blob/main/docs/ansible.utils.ipv4_hostmask_test.rst)|Test if an address is a valid hostmask
+[ansible.utils.ipv4_netmask](https://github.com/ansible-collections/ansible.utils/blob/main/docs/ansible.utils.ipv4_netmask_test.rst)|Test if an address is a valid netmask
[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_3.yml b/changelogs/fragments/add_netaddr_test_plugins_3.yml
new file mode 100644
index 0000000..fdec7e2
--- /dev/null
+++ b/changelogs/fragments/add_netaddr_test_plugins_3.yml
@@ -0,0 +1,3 @@
+---
+minor_changes:
+ - Add ipv4, ipv4_address, ipv4_hostmask, ipv4_netmask test plugins
diff --git a/docs/ansible.utils.ipv4_address_test.rst b/docs/ansible.utils.ipv4_address_test.rst
new file mode 100644
index 0000000..357520a
--- /dev/null
+++ b/docs/ansible.utils.ipv4_address_test.rst
@@ -0,0 +1,150 @@
+.. _ansible.utils.ipv4_address_test:
+
+
+**************************
+ansible.utils.ipv4_address
+**************************
+
+**Test if something is an IPv4 address**
+
+
+Version added: 2.2.0
+
+.. contents::
+ :local:
+ :depth: 1
+
+
+Synopsis
+--------
+- This plugin checks if the provided value is a valid host IP address with IPv4 addressing scheme
+
+
+
+
+Parameters
+----------
+
+.. raw:: html
+
+
+
+ Parameter |
+ Choices/Defaults |
+ Configuration |
+ Comments |
+
+
+
+
+ ip
+
+
+ string
+ / required
+
+ |
+
+ |
+
+ |
+
+ A string that represents the value against which the test is going to be performed
+ {'For example': ['10.1.1.1', '10.0.0.0/8', 'fe80::216:3eff:fee4:16f3']}
+ |
+
+
+
+
+
+
+
+Examples
+--------
+
+.. code-block:: yaml
+
+ #### Simple examples
+
+ - name: Check if 10.1.1.1 is a valid IPv4 address
+ ansible.builtin.set_fact:
+ data: "{{ '10.1.1.1' is ansible.utils.ipv4_address }}"
+
+ # TASK [Check if 10.1.1.1 is a valid IPv4 address] *************************************
+ # ok: [localhost] => {
+ # "ansible_facts": {
+ # "data": true
+ # },
+ # "changed": false
+ # }
+
+ - name: Check if 10.1.1.1/31 is not a valid IPv4 address
+ ansible.builtin.set_fact:
+ data: "{{ '10.1.1.1/31' is not ansible.utils.ipv4_address }}"
+
+ # TASK [Check if 10.1.1.1/31 is a valid IPv4 address] **********************************
+ # ok: [localhost] => {
+ # "ansible_facts": {
+ # "data": true
+ # },
+ # "changed": false
+ # }
+
+ - name: Check if fe80::216:3eff:fee4:16f3 is not a valid IPv4 address
+ ansible.builtin.set_fact:
+ data: "{{ 'fe80::216:3eff:fee4:16f3' is not ansible.utils.ipv4_address }}"
+
+ # TASK [Check if fe80::216:3eff:fee4:16f3 is not a valid IPv4 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
+
+
+
+ Key |
+ Returned |
+ Description |
+
+
+
+
+ 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.ipv4_hostmask_test.rst b/docs/ansible.utils.ipv4_hostmask_test.rst
new file mode 100644
index 0000000..2df2a4d
--- /dev/null
+++ b/docs/ansible.utils.ipv4_hostmask_test.rst
@@ -0,0 +1,138 @@
+.. _ansible.utils.ipv4_hostmask_test:
+
+
+***************************
+ansible.utils.ipv4_hostmask
+***************************
+
+**Test if an address is a valid hostmask**
+
+
+Version added: 2.2.0
+
+.. contents::
+ :local:
+ :depth: 1
+
+
+Synopsis
+--------
+- This plugin checks if the provided ip address is a IPv4 hostmask or not
+
+
+
+
+Parameters
+----------
+
+.. raw:: html
+
+
+
+ Parameter |
+ Choices/Defaults |
+ Configuration |
+ Comments |
+
+
+
+
+ ip
+
+
+ string
+ / required
+
+ |
+
+ |
+
+ |
+
+ A string that represents the value against which the test is going to be performed
+ {'For example': ['0.1.255.255', '255.255.255.0']}
+ |
+
+
+
+
+
+
+
+Examples
+--------
+
+.. code-block:: yaml
+
+ #### Simple examples
+
+ - name: Check if 0.0.0.255 is a hostmask
+ ansible.builtin.set_fact:
+ data: "{{ '0.0.0.255' is ansible.utils.ipv4_hostmask }}"
+
+ # TASK [Check if 0.0.0.255 is a hostmask] ***********************************************
+ # ok: [localhost] => {
+ # "ansible_facts": {
+ # "data": true
+ # },
+ # "changed": false
+ # }
+
+ - name: Check if 255.255.255.0 is not a hostmask
+ ansible.builtin.set_fact:
+ data: "{{ '255.255.255.0' is not ansible.utils.ipv4_hostmask }}"
+
+ # TASK [Check if 255.255.255.0 is a hostmask] *********************************
+ # 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
+
+
+
+ Key |
+ Returned |
+ Description |
+
+
+
+
+ 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.ipv4_netmask_test.rst b/docs/ansible.utils.ipv4_netmask_test.rst
new file mode 100644
index 0000000..8ca045f
--- /dev/null
+++ b/docs/ansible.utils.ipv4_netmask_test.rst
@@ -0,0 +1,150 @@
+.. _ansible.utils.ipv4_netmask_test:
+
+
+**************************
+ansible.utils.ipv4_netmask
+**************************
+
+**Test if an address is a valid netmask**
+
+
+Version added: 2.2.0
+
+.. contents::
+ :local:
+ :depth: 1
+
+
+Synopsis
+--------
+- This plugin checks if the provided ip address is a valid IPv4 netmask or not
+
+
+
+
+Parameters
+----------
+
+.. raw:: html
+
+
+
+ Parameter |
+ Choices/Defaults |
+ Configuration |
+ Comments |
+
+
+
+
+ mask
+
+
+ string
+ / required
+
+ |
+
+ |
+
+ |
+
+ A string that represents the value against which the test is going to be performed
+ {'For example': ['0.1.255.255', '255.255.255.0']}
+ |
+
+
+
+
+
+
+
+Examples
+--------
+
+.. code-block:: yaml
+
+ #### Simple examples
+
+ - name: Check if 255.255.255.0 is a netmask
+ ansible.builtin.set_fact:
+ data: "{{ '255.255.255.0' is ansible.utils.ipv4_netmask }}"
+
+ # TASK [Check if 255.255.255.0 is a netmask] *******************************************
+ # ok: [localhost] => {
+ # "ansible_facts": {
+ # "data": true
+ # },
+ # "changed": false
+ # }
+
+ - name: Check if 255.255.255.128 is a netmask
+ ansible.builtin.set_fact:
+ data: "{{ '255.255.255.128' is ansible.utils.ipv4_netmask }}"
+
+ # TASK [Check if 255.255.255.128 is a netmask] *****************************************
+ # ok: [localhost] => {
+ # "ansible_facts": {
+ # "data": true
+ # },
+ # "changed": false
+ # }
+
+ - name: Check if 255.255.255.127 is not a netmask
+ ansible.builtin.set_fact:
+ data: "{{ '255.255.255.127' is not ansible.utils.ipv4_netmask }}"
+
+ # TASK [Check if 255.255.255.127 is not a netmask] *************************************
+ # 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
+
+
+
+ Key |
+ Returned |
+ Description |
+
+
+
+
+ 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.ipv4_test.rst b/docs/ansible.utils.ipv4_test.rst
new file mode 100644
index 0000000..f3f87ef
--- /dev/null
+++ b/docs/ansible.utils.ipv4_test.rst
@@ -0,0 +1,150 @@
+.. _ansible.utils.ipv4_test:
+
+
+******************
+ansible.utils.ipv4
+******************
+
+**Test if something is an IPv4 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 with IPv4 addressing scheme
+
+
+
+
+Parameters
+----------
+
+.. raw:: html
+
+
+
+ Parameter |
+ Choices/Defaults |
+ Configuration |
+ Comments |
+
+
+
+
+ ip
+
+
+ string
+ / required
+
+ |
+
+ |
+
+ |
+
+ A string that represents the value against which the test is going to be performed
+ {'For example': ['10.1.1.1', '10.0.0.0/8', 'fe80::216:3eff:fee4:16f3']}
+ |
+
+
+
+
+
+
+
+Examples
+--------
+
+.. code-block:: yaml
+
+ #### Simple examples
+
+ - name: Check if 10.0.0.0/8 is a valid IPv4 address
+ ansible.builtin.set_fact:
+ data: "{{ '10.0.0.0/8' is ansible.utils.ipv4 }}"
+
+ # TASK [Check if 10.0.0.0/8 is a valid IPv4 address] ***************************
+ # ok: [localhost] => {
+ # "ansible_facts": {
+ # "data": true
+ # },
+ # "changed": false
+ # }
+
+ - name: Check if 192.168.1.250 is a valid IPv4 address
+ ansible.builtin.set_fact:
+ data: "{{ '192.168.1.250' is ansible.utils.ipv4 }}"
+
+ # TASK [Check if 192.168.1.250 is a valid IPv4 address] ********************
+ # ok: [localhost] => {
+ # "ansible_facts": {
+ # "data": true
+ # },
+ # "changed": false
+ # }
+
+ - name: Check if fe80::216:3eff:fee4:16f3 is not a valid IPv4 address
+ ansible.builtin.set_fact:
+ data: "{{ 'fe80::216:3eff:fee4:16f3' is not ansible.utils.ipv4 }}"
+
+ # TASK [Check if fe80::216:3eff:fee4:16f3 is not a valid IPv4 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
+
+
+
+ Key |
+ Returned |
+ Description |
+
+
+
+
+ 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/ipv4.py b/plugins/test/ipv4.py
new file mode 100644
index 0000000..e66c3c6
--- /dev/null
+++ b/plugins/test/ipv4.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: ipv4
+"""
+
+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: ipv4
+ author: Priyam Sahoo (@priyamsahoo)
+ version_added: "2.2.0"
+ short_description: Test if something is an IPv4 address or network
+ description:
+ - This plugin checks if the provided value is a valid host or network IP address with IPv4 addressing scheme
+ options:
+ ip:
+ description:
+ - A string that represents the value against which the test is going to be performed
+ - For example:
+ - "10.1.1.1"
+ - "10.0.0.0/8"
+ - "fe80::216:3eff:fee4:16f3"
+ type: str
+ required: True
+ notes:
+"""
+
+EXAMPLES = r"""
+
+#### Simple examples
+
+- name: Check if 10.0.0.0/8 is a valid IPv4 address
+ ansible.builtin.set_fact:
+ data: "{{ '10.0.0.0/8' is ansible.utils.ipv4 }}"
+
+# TASK [Check if 10.0.0.0/8 is a valid IPv4 address] ***************************
+# ok: [localhost] => {
+# "ansible_facts": {
+# "data": true
+# },
+# "changed": false
+# }
+
+- name: Check if 192.168.1.250 is a valid IPv4 address
+ ansible.builtin.set_fact:
+ data: "{{ '192.168.1.250' is ansible.utils.ipv4 }}"
+
+# TASK [Check if 192.168.1.250 is a valid IPv4 address] ********************
+# ok: [localhost] => {
+# "ansible_facts": {
+# "data": true
+# },
+# "changed": false
+# }
+
+- name: Check if fe80::216:3eff:fee4:16f3 is not a valid IPv4 address
+ ansible.builtin.set_fact:
+ data: "{{ 'fe80::216:3eff:fee4:16f3' is not ansible.utils.ipv4 }}"
+
+# TASK [Check if fe80::216:3eff:fee4:16f3 is not a valid IPv4 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 _ipv4(ip):
+ """Test if something in an IPv4 address or network"""
+
+ params = {"ip": ip}
+ _validate_args("ipv4", DOCUMENTATION, params)
+
+ try:
+ return ip_network(ip).version == 4
+ except Exception:
+ return False
+
+
+class TestModule(object):
+ """ network jinja test"""
+
+ test_map = {"ipv4": _ipv4}
+
+ def tests(self):
+ return self.test_map
diff --git a/plugins/test/ipv4_address.py b/plugins/test/ipv4_address.py
new file mode 100644
index 0000000..bff6af4
--- /dev/null
+++ b/plugins/test/ipv4_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: ipv4_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: ipv4_address
+ author: Priyam Sahoo (@priyamsahoo)
+ version_added: "2.2.0"
+ short_description: Test if something is an IPv4 address
+ description:
+ - This plugin checks if the provided value is a valid host IP address with IPv4 addressing scheme
+ options:
+ ip:
+ description:
+ - A string that represents the value against which the test is going to be performed
+ - For example:
+ - "10.1.1.1"
+ - "10.0.0.0/8"
+ - "fe80::216:3eff:fee4:16f3"
+ type: str
+ required: True
+ notes:
+"""
+
+EXAMPLES = r"""
+
+#### Simple examples
+
+- name: Check if 10.1.1.1 is a valid IPv4 address
+ ansible.builtin.set_fact:
+ data: "{{ '10.1.1.1' is ansible.utils.ipv4_address }}"
+
+# TASK [Check if 10.1.1.1 is a valid IPv4 address] *************************************
+# ok: [localhost] => {
+# "ansible_facts": {
+# "data": true
+# },
+# "changed": false
+# }
+
+- name: Check if 10.1.1.1/31 is not a valid IPv4 address
+ ansible.builtin.set_fact:
+ data: "{{ '10.1.1.1/31' is not ansible.utils.ipv4_address }}"
+
+# TASK [Check if 10.1.1.1/31 is a valid IPv4 address] **********************************
+# ok: [localhost] => {
+# "ansible_facts": {
+# "data": true
+# },
+# "changed": false
+# }
+
+- name: Check if fe80::216:3eff:fee4:16f3 is not a valid IPv4 address
+ ansible.builtin.set_fact:
+ data: "{{ 'fe80::216:3eff:fee4:16f3' is not ansible.utils.ipv4_address }}"
+
+# TASK [Check if fe80::216:3eff:fee4:16f3 is not a valid IPv4 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 _ipv4_address(ip):
+ """Test if something in an IPv4 address"""
+
+ params = {"ip": ip}
+ _validate_args("ipv4_address", DOCUMENTATION, params)
+
+ try:
+ return ip_address(ip).version == 4
+ except Exception:
+ return False
+
+
+class TestModule(object):
+ """ network jinja test"""
+
+ test_map = {"ipv4_address": _ipv4_address}
+
+ def tests(self):
+ return self.test_map
diff --git a/plugins/test/ipv4_hostmask.py b/plugins/test/ipv4_hostmask.py
new file mode 100644
index 0000000..7c8040c
--- /dev/null
+++ b/plugins/test/ipv4_hostmask.py
@@ -0,0 +1,96 @@
+# -*- 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: ipv4_hostmask
+"""
+
+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: ipv4_hostmask
+ author: Priyam Sahoo (@priyamsahoo)
+ version_added: "2.2.0"
+ short_description: Test if an address is a valid hostmask
+ description:
+ - This plugin checks if the provided ip address is a IPv4 hostmask or not
+ options:
+ ip:
+ description:
+ - A string that represents the value against which the test is going to be performed
+ - For example:
+ - "0.1.255.255"
+ - "255.255.255.0"
+ type: str
+ required: True
+ notes:
+"""
+
+EXAMPLES = r"""
+
+#### Simple examples
+
+- name: Check if 0.0.0.255 is a hostmask
+ ansible.builtin.set_fact:
+ data: "{{ '0.0.0.255' is ansible.utils.ipv4_hostmask }}"
+
+# TASK [Check if 0.0.0.255 is a hostmask] ***********************************************
+# ok: [localhost] => {
+# "ansible_facts": {
+# "data": true
+# },
+# "changed": false
+# }
+
+- name: Check if 255.255.255.0 is not a hostmask
+ ansible.builtin.set_fact:
+ data: "{{ '255.255.255.0' is not ansible.utils.ipv4_hostmask }}"
+
+# TASK [Check if 255.255.255.0 is a hostmask] *********************************
+# 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 _ipv4_hostmask(ip):
+ """Test if an address is a hostmask"""
+
+ params = {"ip": ip}
+ _validate_args("ipv4_hostmask", DOCUMENTATION, params)
+
+ try:
+ ipaddr = ip_network("10.0.0.0/{ip}".format(ip=ip))
+ return str(ipaddr.hostmask) == ip
+ except Exception:
+ return False
+
+
+class TestModule(object):
+ """ network jinja test"""
+
+ test_map = {"ipv4_hostmask": _ipv4_hostmask}
+
+ def tests(self):
+ return self.test_map
diff --git a/plugins/test/ipv4_netmask.py b/plugins/test/ipv4_netmask.py
new file mode 100644
index 0000000..7ebdfc7
--- /dev/null
+++ b/plugins/test/ipv4_netmask.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: ipv4_netmask
+"""
+
+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: ipv4_netmask
+ author: Priyam Sahoo (@priyamsahoo)
+ version_added: "2.2.0"
+ short_description: Test if an address is a valid netmask
+ description:
+ - This plugin checks if the provided ip address is a valid IPv4 netmask or not
+ options:
+ mask:
+ description:
+ - A string that represents the value against which the test is going to be performed
+ - For example:
+ - "0.1.255.255"
+ - "255.255.255.0"
+ type: str
+ required: True
+ notes:
+"""
+
+EXAMPLES = r"""
+
+#### Simple examples
+
+- name: Check if 255.255.255.0 is a netmask
+ ansible.builtin.set_fact:
+ data: "{{ '255.255.255.0' is ansible.utils.ipv4_netmask }}"
+
+# TASK [Check if 255.255.255.0 is a netmask] *******************************************
+# ok: [localhost] => {
+# "ansible_facts": {
+# "data": true
+# },
+# "changed": false
+# }
+
+- name: Check if 255.255.255.128 is a netmask
+ ansible.builtin.set_fact:
+ data: "{{ '255.255.255.128' is ansible.utils.ipv4_netmask }}"
+
+# TASK [Check if 255.255.255.128 is a netmask] *****************************************
+# ok: [localhost] => {
+# "ansible_facts": {
+# "data": true
+# },
+# "changed": false
+# }
+
+- name: Check if 255.255.255.127 is not a netmask
+ ansible.builtin.set_fact:
+ data: "{{ '255.255.255.127' is not ansible.utils.ipv4_netmask }}"
+
+# TASK [Check if 255.255.255.127 is not a netmask] *************************************
+# 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 _ipv4_netmask(mask):
+ """ Test for a valid IPv4 netmask"""
+
+ params = {"mask": mask}
+ _validate_args("ipv4_netmask", DOCUMENTATION, params)
+
+ try:
+ network = ip_network("10.0.0.0/{mask}".format(mask=mask))
+ return str(network.netmask) == mask
+ except Exception:
+ return False
+
+
+class TestModule(object):
+ """ network jinja test"""
+
+ test_map = {"ipv4_netmask": _ipv4_netmask}
+
+ def tests(self):
+ return self.test_map
diff --git a/tests/integration/targets/netaddr_test/tasks/include/ipv4.yml b/tests/integration/targets/netaddr_test/tasks/include/ipv4.yml
new file mode 100644
index 0000000..dd8633c
--- /dev/null
+++ b/tests/integration/targets/netaddr_test/tasks/include/ipv4.yml
@@ -0,0 +1,24 @@
+---
+- name: "ipv4: Check if 10.0.0.0/8 is a valid IPV4 address"
+ assert:
+ that: "{{ '10.0.0.0/8' is ansible.utils.ipv4 }}"
+
+- name: "ipv4: Check if 192.168.1.250 is a valid IPV4 address"
+ assert:
+ that: "{{ '192.168.1.250' is ansible.utils.ipv4 }}"
+
+- name: "ipv4: Test invalidness"
+ ansible.builtin.set_fact:
+ criteria_check1: "{{ 'fe80::216:3eff:fee4:16f3' is ansible.utils.ipv4 }}"
+
+- name: "ipv4: Assert invalidness"
+ assert:
+ that: "{{ criteria_check1 == false }}"
+
+- name: "ipv4: Test invalidness"
+ ansible.builtin.set_fact:
+ criteria_check2: "{{ 'string' is ansible.utils.ipv4 }}"
+
+- name: "ipv4: Assert invalidness"
+ assert:
+ that: "{{ criteria_check2 == false }}"
diff --git a/tests/integration/targets/netaddr_test/tasks/include/ipv4_address.yml b/tests/integration/targets/netaddr_test/tasks/include/ipv4_address.yml
new file mode 100644
index 0000000..1ebfbf5
--- /dev/null
+++ b/tests/integration/targets/netaddr_test/tasks/include/ipv4_address.yml
@@ -0,0 +1,28 @@
+---
+- name: "ipv4_address: Check if 192.168.1.250 is a valid IPV4 address"
+ assert:
+ that: "{{ '192.168.1.250' is ansible.utils.ipv4_address }}"
+
+- name: "ipv4_address: Test invalidness"
+ ansible.builtin.set_fact:
+ criteria_check1: "{{ '10.0.0.0/8' is ansible.utils.ipv4_address }}"
+
+- name: "ipv4_address: Assert invalidness"
+ assert:
+ that: "{{ criteria_check1 == false }}"
+
+- name: "ipv4_address: Test invalidness"
+ ansible.builtin.set_fact:
+ criteria_check2: "{{ 'fe80::216:3eff:fee4:16f3' is ansible.utils.ipv4_address }}"
+
+- name: "ipv4_address: Assert invalidness"
+ assert:
+ that: "{{ criteria_check2 == false }}"
+
+- name: "ipv4_address: Test invalidness"
+ ansible.builtin.set_fact:
+ criteria_check3: "{{ 'string' is ansible.utils.ipv4_address }}"
+
+- name: "ipv4_address: Assert invalidness"
+ assert:
+ that: "{{ criteria_check3 == false }}"
diff --git a/tests/integration/targets/netaddr_test/tasks/include/ipv4_hostmask.yml b/tests/integration/targets/netaddr_test/tasks/include/ipv4_hostmask.yml
new file mode 100644
index 0000000..6252826
--- /dev/null
+++ b/tests/integration/targets/netaddr_test/tasks/include/ipv4_hostmask.yml
@@ -0,0 +1,20 @@
+---
+- name: "ipv4_hostmask: Check if 0.0.0.255 is a hostmask"
+ assert:
+ that: "{{ '0.0.0.255' is ansible.utils.ipv4_hostmask }}"
+
+- name: "ipv4_hostmask: Test invalidness"
+ ansible.builtin.set_fact:
+ criteria_check1: "{{ '255.255.255.0' is ansible.utils.ipv4_hostmask }}"
+
+- name: "ipv4_hostmask: Assert invalidness"
+ assert:
+ that: "{{ criteria_check1 == false }}"
+
+- name: "ipv4_hostmask: Test invalidness"
+ ansible.builtin.set_fact:
+ criteria_check2: "{{ '10.1.1.1' is ansible.utils.ipv4_hostmask }}"
+
+- name: "ipv4_hostmask: Assert invalidness"
+ assert:
+ that: "{{ criteria_check2 == false }}"
diff --git a/tests/integration/targets/netaddr_test/tasks/include/ipv4_netmask.yml b/tests/integration/targets/netaddr_test/tasks/include/ipv4_netmask.yml
new file mode 100644
index 0000000..eb51fb7
--- /dev/null
+++ b/tests/integration/targets/netaddr_test/tasks/include/ipv4_netmask.yml
@@ -0,0 +1,20 @@
+---
+- name: "ipv4_netmask: Check if 255.255.255.0 is a netmask"
+ assert:
+ that: "{{ '255.255.255.0' is ansible.utils.ipv4_netmask }}"
+
+- name: "ipv4_netmask: Test invalidness"
+ ansible.builtin.set_fact:
+ criteria_check1: "{{ '0.0.0.255' is ansible.utils.ipv4_netmask }}"
+
+- name: "ipv4_netmask: Assert invalidness"
+ assert:
+ that: "{{ criteria_check1 == false }}"
+
+- name: "ipv4_netmask: Test invalidness"
+ ansible.builtin.set_fact:
+ criteria_check2: "{{ '10.1.1.1' is ansible.utils.ipv4_netmask }}"
+
+- name: "ipv4_netmask: Assert invalidness"
+ assert:
+ that: "{{ criteria_check2 == false }}"
diff --git a/tests/unit/plugins/test/test_ipv4.py b/tests/unit/plugins/test/test_ipv4.py
new file mode 100644
index 0000000..ed951e9
--- /dev/null
+++ b/tests/unit/plugins/test/test_ipv4.py
@@ -0,0 +1,43 @@
+# -*- 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: ipv4
+"""
+
+from __future__ import absolute_import, division, print_function
+
+__metaclass__ = type
+
+import unittest
+from ansible_collections.ansible.utils.plugins.test.ipv4 import _ipv4
+
+
+class TestIpV4(unittest.TestCase):
+ def setUp(self):
+ pass
+
+ def test_invalid_data(self):
+ """Check passing invalid argspec"""
+
+ # missing argument
+ with self.assertRaises(TypeError) as error:
+ _ipv4()
+ self.assertIn("argument", str(error.exception))
+
+ def test_valid_data(self):
+ """Check passing valid data as per criteria"""
+
+ result = _ipv4(ip="10.1.1.1")
+ self.assertEqual(result, True)
+
+ result = _ipv4(ip="10.0.0.0/8")
+ self.assertEqual(result, True)
+
+ result = _ipv4(ip="2001:db8:a::123")
+ self.assertEqual(result, False)
+
+ result = _ipv4(ip="string")
+ self.assertEqual(result, False)
diff --git a/tests/unit/plugins/test/test_ipv4_address.py b/tests/unit/plugins/test/test_ipv4_address.py
new file mode 100644
index 0000000..59f8738
--- /dev/null
+++ b/tests/unit/plugins/test/test_ipv4_address.py
@@ -0,0 +1,45 @@
+# -*- 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: ipv4_address
+"""
+
+from __future__ import absolute_import, division, print_function
+
+__metaclass__ = type
+
+import unittest
+from ansible_collections.ansible.utils.plugins.test.ipv4_address import (
+ _ipv4_address,
+)
+
+
+class TestIpV4Address(unittest.TestCase):
+ def setUp(self):
+ pass
+
+ def test_invalid_data(self):
+ """Check passing invalid argspec"""
+
+ # missing argument
+ with self.assertRaises(TypeError) as error:
+ _ipv4_address()
+ self.assertIn("argument", str(error.exception))
+
+ def test_valid_data(self):
+ """Check passing valid data as per criteria"""
+
+ result = _ipv4_address(ip="10.1.1.1")
+ self.assertEqual(result, True)
+
+ result = _ipv4_address(ip="10.0.0.0/8")
+ self.assertEqual(result, False)
+
+ result = _ipv4_address(ip="2001:db8:a::123")
+ self.assertEqual(result, False)
+
+ result = _ipv4_address(ip="string")
+ self.assertEqual(result, False)
diff --git a/tests/unit/plugins/test/test_ipv4_hostmask.py b/tests/unit/plugins/test/test_ipv4_hostmask.py
new file mode 100644
index 0000000..1f28e57
--- /dev/null
+++ b/tests/unit/plugins/test/test_ipv4_hostmask.py
@@ -0,0 +1,45 @@
+# -*- 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: ipv4_hostmask
+"""
+
+from __future__ import absolute_import, division, print_function
+
+__metaclass__ = type
+
+import unittest
+from ansible_collections.ansible.utils.plugins.test.ipv4_hostmask import (
+ _ipv4_hostmask,
+)
+
+
+class TestIpV4Hostmask(unittest.TestCase):
+ def setUp(self):
+ pass
+
+ def test_invalid_data(self):
+ """Check passing invalid argspec"""
+
+ # missing argument
+ with self.assertRaises(TypeError) as error:
+ _ipv4_hostmask()
+ self.assertIn("argument", str(error.exception))
+
+ def test_valid_data(self):
+ """Check passing valid data as per criteria"""
+
+ result = _ipv4_hostmask(ip="0.1.255.255")
+ self.assertEqual(result, True)
+
+ result = _ipv4_hostmask(ip="255.255.255.0")
+ self.assertEqual(result, False)
+
+ result = _ipv4_hostmask(ip="10.1.1.1")
+ self.assertEqual(result, False)
+
+ result = _ipv4_hostmask(ip="string")
+ self.assertEqual(result, False)
diff --git a/tests/unit/plugins/test/test_ipv4_netmask.py b/tests/unit/plugins/test/test_ipv4_netmask.py
new file mode 100644
index 0000000..9408ab2
--- /dev/null
+++ b/tests/unit/plugins/test/test_ipv4_netmask.py
@@ -0,0 +1,45 @@
+# -*- 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: ipv4_netmask
+"""
+
+from __future__ import absolute_import, division, print_function
+
+__metaclass__ = type
+
+import unittest
+from ansible_collections.ansible.utils.plugins.test.ipv4_netmask import (
+ _ipv4_netmask,
+)
+
+
+class TestIpV4Netmask(unittest.TestCase):
+ def setUp(self):
+ pass
+
+ def test_invalid_data(self):
+ """Check passing invalid argspec"""
+
+ # missing argument
+ with self.assertRaises(TypeError) as error:
+ _ipv4_netmask()
+ self.assertIn("argument", str(error.exception))
+
+ def test_valid_data(self):
+ """Check passing valid data as per criteria"""
+
+ result = _ipv4_netmask(mask="255.255.255.0")
+ self.assertEqual(result, True)
+
+ result = _ipv4_netmask(mask="0.1.255.255")
+ self.assertEqual(result, False)
+
+ result = _ipv4_netmask(mask="10.1.1.1")
+ self.assertEqual(result, False)
+
+ result = _ipv4_netmask(mask="string")
+ self.assertEqual(result, False)