summaryrefslogtreecommitdiff
path: root/tests/unit/modules
diff options
context:
space:
mode:
authoromnom62 <75066712+omnom62@users.noreply.github.com>2026-03-04 19:51:16 +1000
committerGitHub <noreply@github.com>2026-03-04 09:51:16 +0000
commita8e5dac21090e9b0ddf876214a9a1522079ecde1 (patch)
tree9865a8b7ad796f8b201b8fea9e93f3c395a5e71f /tests/unit/modules
parente539028c2f9d062e7684abda5dd32affd92e9f08 (diff)
downloadvyos.vyos-a8e5dac21090e9b0ddf876214a9a1522079ecde1.tar.gz
vyos.vyos-a8e5dac21090e9b0ddf876214a9a1522079ecde1.zip
T6836 VRF module (#408)
* t6836 vfr module init * argspec facts module for VRF * T6834 static_route module to support interface_route (#398) * t6834 init * facts fixes, WIP * T6834 - facts updates * static_routes 1.3- config, facts, args and sanit and unit tests * changelog * changelog updates * static_routes 1.4+ * static_routes v1.4 unit tests * comment removed * T6829 (area interfaces in OSPFv3 1.3-1.5) re-init (#399) * T6829 re-init * re-init T6829 ospfv3 area interface for 1.3- * changelog * changelog fix * Doc is updated * adding 1.4+ support * ospfv3 area interfaces for 1.4+ * fixed ospfv3 facts and added area interface unit test for 1.4 * ospfv3 clean-up * doc updates * Resolve merge conflicts * vrf parsers set_table * more vrf paresers added * vrf facts main code * vrf data structures * simple vrf config push * simple vrf config push * some work on vrf * basic facts done * vrf instance parsers wif * ongoing parser testing * vrf dev work * testing with paresers * all basic settings * merged for vrf * more states for VRF * vrf deleted, overriden * overriden * sanity * rst for vrf * changelog * fix changelog * doc fix * vrf delete idempotent * deleted and overridden for VFR * overriden * overriden vrf idempotency * asdvanced vrf settings * afi for VRF facts * VRF AFI config * VRF AFI tests * vrf dev work * afi dev work * afi and deep_merge fixes for VRF * afi basic provisioning * changelog * vrf sanity fixes * VRF AFI protocols and route-maps * vrf parsed, gathered, rendered fixes * docstrings VRF * docstrings VRF * docstring VRF * module doc update * vrf module examples * VRF doc examples * linter * VRF unit tests init * VRF unit tests init * VRF unit tests updates * fixed VRF overridden and deleted unit test cases * VRF integration tests init * VRF int tests rtt, merged, replaced * VRF int testt gathered, rendered * VRF int tests deleted, rendered, overridden and empty_config * linter * VRF int test misc fixes * VRF global idepmotency * fixing py3.13 runner deps * fixing lint * fixing sanity * reverting previous fixes * VRF protocols load_module and provisioning flow * fixes to bgp VRF protocol methods * VRF protocol facts init * VRF protocol load_module works * reworked VRF load_module routine * vrf protocl static fixed * Fixed static and ospf VRF protocol provisioning * Fixed static and ospf VRF protocol provisioning * VRF doc update * VRF docs update * VRF doc updates * unit tests for VRF protocols * VRF BGP protcol sanity check * VRF protocol fixed sanity checks (DOCUMENTATION) * sanity and doc for VRF fixed * VRF unit tests mock * VRF protocol integration parsed, rtt and merged init * VRF protocols - rendered, overridden * VRF protocols replaced * fix accidental changes to test_vyos_config.py * PR description * fix image * README fix * Fixing linter * Mid-result UAT overriden VRF * Mid-result for VRF UAT * VRF uat * VRF obsolete features removed
Diffstat (limited to 'tests/unit/modules')
-rw-r--r--tests/unit/modules/network/vyos/fixtures/vyos_vrf_config.cfg15
-rw-r--r--tests/unit/modules/network/vyos/test_vyos_vrf.py689
2 files changed, 704 insertions, 0 deletions
diff --git a/tests/unit/modules/network/vyos/fixtures/vyos_vrf_config.cfg b/tests/unit/modules/network/vyos/fixtures/vyos_vrf_config.cfg
new file mode 100644
index 00000000..094b7cf3
--- /dev/null
+++ b/tests/unit/modules/network/vyos/fixtures/vyos_vrf_config.cfg
@@ -0,0 +1,15 @@
+set vrf bind-to-all
+set vrf name vrf-blue description 'blue-vrf'
+set vrf name vrf-blue table '100'
+set vrf name vrf-blue vni '1000'
+set vrf name vrf-red description 'red-vrf'
+set vrf name vrf-red disable
+set vrf name vrf-red ip disable-forwarding
+set vrf name vrf-red ip protocol rip route-map 'rm1'
+set vrf name vrf-red ipv6 nht no-resolve-via-default
+set vrf name vrf-red table '101'
+set vrf name vrf-red vni '1001'
+set vrf name vrf-red protocols bgp system-as 65000
+set vrf name vrf-red protocols bgp neighbor 192.0.2.1 remote-as 65002
+set vrf name vrf-red protocols bgp neighbor 1.1.1.3 passive
+set vrf name vrf-red protocols bgp neighbor 1.1.1.3 remote-as 400
diff --git a/tests/unit/modules/network/vyos/test_vyos_vrf.py b/tests/unit/modules/network/vyos/test_vyos_vrf.py
new file mode 100644
index 00000000..e86227a9
--- /dev/null
+++ b/tests/unit/modules/network/vyos/test_vyos_vrf.py
@@ -0,0 +1,689 @@
+# (c) 2021 Red Hat Inc.
+#
+# This file is part of Ansible
+#
+# Ansible is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# Ansible is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
+
+
+from __future__ import absolute_import, division, print_function
+
+
+__metaclass__ = type
+
+from unittest.mock import MagicMock, patch
+
+from ansible_collections.vyos.vyos.plugins.modules import vyos_vrf
+from ansible_collections.vyos.vyos.tests.unit.modules.utils import set_module_args
+
+from .vyos_module import TestVyosModule, load_fixture
+
+
+class TestVyosVrfModule(TestVyosModule):
+ module = vyos_vrf
+
+ def setUp(self):
+ super(TestVyosVrfModule, self).setUp()
+
+ self.fake_connection = MagicMock()
+ self.fake_connection.get.return_value = "{}"
+
+ self.fake_connection.get_device_info.return_value = {
+ "version": "1.5",
+ }
+
+ self.fake_connection.get_device_info.return_value = {
+ "network_os_major_version": "1.5",
+ }
+ patch(
+ "ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.vyos.get_connection",
+ return_value=self.fake_connection,
+ ).start()
+
+ def _get_resource_connection_side_effect(module, *args, **kwargs):
+ module._connection = self.fake_connection
+ return self.fake_connection
+
+ patch(
+ "ansible_collections.ansible.netcommon.plugins.module_utils.network.common.rm_base.resource_module_base.get_resource_connection",
+ side_effect=_get_resource_connection_side_effect,
+ ).start()
+
+ patch(
+ "ansible_collections.ansible.netcommon.plugins.module_utils.network.common.facts.facts.get_resource_connection",
+ side_effect=_get_resource_connection_side_effect,
+ ).start()
+
+ self.mock_execute_show_command = patch(
+ "ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.facts.vrf.vrf.VrfFacts.get_config",
+ ).start()
+
+ patch(
+ "ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.config.vrf.vrf.get_os_version",
+ return_value="1.5",
+ ).start()
+
+ patch(
+ "ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.config.bgp_global.bgp_global.get_os_version",
+ return_value="1.5",
+ ).start()
+
+ self.maxDiff = None
+
+ def tearDown(self):
+ super(TestVyosVrfModule, self).tearDown()
+ patch.stopall()
+
+ def load_fixtures(self, commands=None, filename=None):
+ if filename is None:
+ filename = "vyos_vrf_config.cfg"
+
+ def load_from_file(*args, **kwargs):
+ return load_fixture(filename)
+
+ self.mock_execute_show_command.side_effect = load_from_file
+
+ def test_vrf_merged_idempotent(self):
+ set_module_args(
+ dict(
+ config=dict(
+ bind_to_all=True,
+ instances=[
+ dict(
+ name="vrf-blue",
+ description="blue-vrf",
+ disable=False,
+ table_id=100,
+ vni=1000,
+ ),
+ dict(
+ name="vrf-red",
+ description="red-vrf",
+ disable=True,
+ table_id=101,
+ vni=1001,
+ address_family=[
+ dict(
+ afi="ipv4",
+ disable_forwarding=True,
+ route_maps=[
+ dict(rm_name="rm1", protocol="rip"),
+ ],
+ ),
+ dict(
+ afi="ipv6",
+ nht_no_resolve_via_default=True,
+ ),
+ ],
+ protocols=dict(
+ bgp=dict(
+ as_number=65000,
+ neighbor=[
+ dict(
+ address="192.0.2.1",
+ remote_as=65002,
+ ),
+ dict(
+ address="1.1.1.3",
+ remote_as=400,
+ passive=True,
+ ),
+ ],
+ ),
+ ),
+ ),
+ ],
+ ),
+ state="merged",
+ ),
+ )
+
+ self.execute_module(changed=False, commands=[])
+
+ def test_vrf_merged(self):
+ set_module_args(
+ dict(
+ config=dict(
+ bind_to_all=False,
+ instances=[
+ dict(
+ name="vrf-green",
+ description="green-vrf",
+ table_id=110,
+ vni=1010,
+ protocols=dict(
+ ospf=dict(
+ log_adjacency_changes="detail",
+ max_metric=dict(
+ router_lsa=dict(
+ administrative=True,
+ on_shutdown=10,
+ on_startup=10,
+ ),
+ ),
+ default_information=dict(
+ originate=dict(
+ always=True,
+ metric=10,
+ metric_type=2,
+ ),
+ ),
+ auto_cost=dict(
+ reference_bandwidth=2,
+ ),
+ neighbor=[
+ dict(
+ neighbor_id="192.0.11.12",
+ poll_interval=10,
+ priority=2,
+ ),
+ ],
+ redistribute=[
+ dict(
+ route_type="bgp",
+ metric=10,
+ metric_type=2,
+ ),
+ ],
+ parameters=dict(
+ router_id="192.0.1.1",
+ rfc1583_compatibility=True,
+ abr_type="cisco",
+ ),
+ areas=[
+ dict(
+ area_id="2",
+ area_type=dict(
+ normal=True,
+ ),
+ authentication="plaintext-password",
+ shortcut="enable",
+ ),
+ dict(
+ area_id="3",
+ area_type=dict(
+ nssa=dict(
+ set=True,
+ ),
+ ),
+ ),
+ dict(
+ area_id="4",
+ area_type=dict(
+ stub=dict(
+ default_cost=20,
+ ),
+ ),
+ network=[
+ dict(
+ address="192.0.2.0/24",
+ ),
+ ],
+ range=[
+ dict(
+ address="192.0.3.0/24",
+ cost=10,
+ ),
+ dict(
+ address="192.0.4.0/24",
+ cost=12,
+ ),
+ ],
+ ),
+ ],
+ ),
+ ),
+ ),
+ ],
+ ),
+ state="merged",
+ ),
+ )
+
+ commands = [
+ "delete vrf bind-to-all",
+ "set vrf name vrf-green table 110",
+ "set vrf name vrf-green vni 1010",
+ "set vrf name vrf-green description green-vrf",
+ "set vrf name vrf-green protocols ospf log-adjacency-changes 'detail'",
+ "set vrf name vrf-green protocols ospf max-metric router-lsa administrative",
+ "set vrf name vrf-green protocols ospf max-metric router-lsa on-shutdown 10",
+ "set vrf name vrf-green protocols ospf max-metric router-lsa on-startup 10",
+ "set vrf name vrf-green protocols ospf default-information originate always",
+ "set vrf name vrf-green protocols ospf default-information originate metric 10",
+ "set vrf name vrf-green protocols ospf default-information originate metric-type 2",
+ "set vrf name vrf-green protocols ospf auto-cost reference-bandwidth '2'",
+ "set vrf name vrf-green protocols ospf neighbor 192.0.11.12",
+ "set vrf name vrf-green protocols ospf neighbor 192.0.11.12 poll-interval 10",
+ "set vrf name vrf-green protocols ospf neighbor 192.0.11.12 priority 2",
+ "set vrf name vrf-green protocols ospf redistribute bgp",
+ "set vrf name vrf-green protocols ospf redistribute bgp metric 10",
+ "set vrf name vrf-green protocols ospf redistribute bgp metric-type 2",
+ "set vrf name vrf-green protocols ospf parameters router-id '192.0.1.1'",
+ "set vrf name vrf-green protocols ospf parameters rfc1583-compatibility",
+ "set vrf name vrf-green protocols ospf parameters abr-type 'cisco'",
+ "set vrf name vrf-green protocols ospf area '2'",
+ "set vrf name vrf-green protocols ospf area 2 area-type normal",
+ "set vrf name vrf-green protocols ospf area 2 authentication plaintext-password",
+ "set vrf name vrf-green protocols ospf area 2 shortcut enable",
+ "set vrf name vrf-green protocols ospf area '3'",
+ "set vrf name vrf-green protocols ospf area 3 area-type nssa",
+ "set vrf name vrf-green protocols ospf area '4'",
+ "set vrf name vrf-green protocols ospf area 4 area-type stub default-cost 20",
+ "set vrf name vrf-green protocols ospf area 4 network 192.0.2.0/24",
+ "set vrf name vrf-green protocols ospf area 4 range 192.0.3.0/24",
+ "set vrf name vrf-green protocols ospf area 4 range 192.0.3.0/24 cost 10",
+ "set vrf name vrf-green protocols ospf area 4 range 192.0.4.0/24",
+ "set vrf name vrf-green protocols ospf area 4 range 192.0.4.0/24 cost 12",
+ ]
+
+ self.execute_module(changed=True, commands=commands)
+
+ def test_vrf_replaced(self):
+ set_module_args(
+ dict(
+ config=dict(
+ bind_to_all=True,
+ instances=[
+ dict(
+ name="vrf-blue",
+ description="blue-vrf-replaced",
+ disable=True,
+ table_id=100,
+ vni=1000,
+ ),
+ dict(
+ name="vrf-red",
+ description="red-vrf",
+ disable=True,
+ table_id=101,
+ vni=1001,
+ address_family=[
+ dict(
+ afi="ipv4",
+ disable_forwarding=False,
+ route_maps=[
+ dict(rm_name="rm1", protocol="rip"),
+ ],
+ ),
+ dict(
+ afi="ipv6",
+ nht_no_resolve_via_default=False,
+ ),
+ ],
+ ),
+ ],
+ ),
+ state="replaced",
+ ),
+ )
+ commands = [
+ "set vrf name vrf-blue description blue-vrf-replaced",
+ "set vrf name vrf-blue disable",
+ "delete vrf name vrf-red ip disable-forwarding",
+ "delete vrf name vrf-red ipv6 nht no-resolve-via-default",
+ ]
+ self.execute_module(changed=True, commands=commands)
+
+ def test_vrf_replaced_idempotent(self):
+ set_module_args(
+ dict(
+ config=dict(
+ bind_to_all=True,
+ instances=[
+ dict(
+ name="vrf-blue",
+ description="blue-vrf",
+ disable=False,
+ table_id=100,
+ vni=1000,
+ ),
+ dict(
+ name="vrf-red",
+ description="red-vrf",
+ disable=True,
+ table_id=101,
+ vni=1001,
+ address_family=[
+ dict(
+ afi="ipv4",
+ disable_forwarding=True,
+ route_maps=[
+ dict(rm_name="rm1", protocol="rip"),
+ ],
+ ),
+ dict(
+ afi="ipv6",
+ nht_no_resolve_via_default=True,
+ ),
+ ],
+ ),
+ ],
+ ),
+ state="replaced",
+ ),
+ )
+ self.execute_module(changed=False, commands=[])
+
+ def test_vrf_overridden(self):
+ set_module_args(
+ dict(
+ config=dict(
+ instances=[
+ dict(
+ name="vrf-blue",
+ description="blue-vrf",
+ disable=True,
+ table_id=103,
+ vni=1002,
+ ),
+ dict(
+ name="vrf-red",
+ description="red-vrf",
+ disable=True,
+ table_id=101,
+ vni=1001,
+ protocols=dict(
+ bgp=dict(
+ as_number=65000,
+ neighbor=[
+ dict(
+ address="192.0.2.1",
+ remote_as=65003,
+ ),
+ ],
+ ),
+ ),
+ ),
+ ],
+ ),
+ state="overridden",
+ ),
+ )
+ commands = [
+ "delete vrf name vrf-blue",
+ "commit",
+ "delete vrf name vrf-red",
+ "commit",
+ "set vrf name vrf-blue table 103",
+ "set vrf name vrf-blue vni 1002",
+ "set vrf name vrf-blue description blue-vrf",
+ "set vrf name vrf-blue disable",
+ "set vrf name vrf-red table 101",
+ "set vrf name vrf-red vni 1001",
+ "set vrf name vrf-red description red-vrf",
+ "set vrf name vrf-red disable",
+ "set vrf name vrf-red protocols bgp system-as 65000",
+ "set vrf name vrf-red protocols bgp neighbor 192.0.2.1 remote-as 65003",
+ "delete vrf bind-to-all",
+ ]
+ self.execute_module(changed=True, commands=commands)
+
+ def test_vrf_overridden_idempotent(self):
+ set_module_args(
+ dict(
+ config=dict(
+ bind_to_all=True,
+ instances=[
+ dict(
+ name="vrf-blue",
+ description="blue-vrf",
+ disable=False,
+ table_id=100,
+ vni=1000,
+ ),
+ dict(
+ name="vrf-red",
+ description="red-vrf",
+ disable=True,
+ table_id=101,
+ vni=1001,
+ address_family=[
+ dict(
+ afi="ipv4",
+ disable_forwarding=True,
+ nht_no_resolve_via_default=False,
+ route_maps=[
+ dict(rm_name="rm1", protocol="rip"),
+ ],
+ ),
+ dict(
+ afi="ipv6",
+ disable_forwarding=False,
+ nht_no_resolve_via_default=True,
+ ),
+ ],
+ protocols=dict(
+ bgp=dict(
+ as_number=65000,
+ neighbor=[
+ dict(
+ address="192.0.2.1",
+ remote_as=65002,
+ ),
+ dict(
+ address="1.1.1.3",
+ remote_as=400,
+ passive=True,
+ ),
+ ],
+ ),
+ ),
+ ),
+ ],
+ ),
+ state="overridden",
+ ),
+ )
+ self.execute_module(changed=False, commands=[])
+
+ def test_vrf_rendered(self):
+ set_module_args(
+ dict(
+ config=dict(
+ bind_to_all=True,
+ instances=[
+ dict(
+ name="vrf-green",
+ description="green-vrf",
+ disabled=True,
+ table_id=105,
+ vni=1000,
+ ),
+ dict(
+ name="vrf-amber",
+ description="amber-vrf",
+ disable=False,
+ table_id=111,
+ vni=1001,
+ address_family=[
+ dict(
+ afi="ipv4",
+ disable_forwarding=True,
+ route_maps=[
+ dict(rm_name="rm1", protocol="ospf"),
+ ],
+ ),
+ dict(
+ afi="ipv6",
+ nht_no_resolve_via_default=False,
+ ),
+ ],
+ ),
+ ],
+ ),
+ state="rendered",
+ ),
+ )
+ rendered_commands = [
+ "set vrf bind-to-all",
+ "set vrf name vrf-green table 105",
+ "set vrf name vrf-green vni 1000",
+ "set vrf name vrf-green description green-vrf",
+ "set vrf name vrf-green disable",
+ "set vrf name vrf-amber table 111",
+ "set vrf name vrf-amber vni 1001",
+ "set vrf name vrf-amber description amber-vrf",
+ "set vrf name vrf-amber ip protocol ospf route-map rm1",
+ "set vrf name vrf-amber ip disable-forwarding",
+ ]
+ result = self.execute_module(changed=False)
+ self.assertEqual(
+ sorted(result["rendered"]),
+ sorted(rendered_commands),
+ result["rendered"],
+ )
+
+ def test_vrf_parsed(self):
+ commands = (
+ "set vrf bind-to-all",
+ "set vrf name vrf1 description 'red'",
+ "set vrf name vrf1 disable",
+ "set vrf name vrf1 table 101",
+ "set vrf name vrf1 vni 501",
+ "set vrf name vrf2 description 'green'",
+ "set vrf name vrf2 disable",
+ "set vrf name vrf2 table 102",
+ "set vrf name vrf2 vni 102",
+ "set vrf name vrf1 ip disable-forwarding",
+ "set vrf name vrf1 ip nht no-resolve-via-default",
+ "set vrf name vrf-red ip protocol ospf route-map 'rm1'",
+ "set vrf name vrf-red ipv6 nht no-resolve-via-default",
+ )
+ parsed_str = "\n".join(commands)
+ set_module_args(dict(running_config=parsed_str, state="parsed"))
+ result = self.execute_module(changed=False)
+ parsed_list = {
+ "bind_to_all": True,
+ "instances": [
+ {
+ "address_family": [
+ {
+ "afi": "ipv4",
+ "disable_forwarding": True,
+ "nht_no_resolve_via_default": True,
+ },
+ ],
+ "description": "red",
+ "disable": True,
+ "name": "vrf1",
+ },
+ {
+ "description": "green",
+ "disable": True,
+ "name": "vrf2",
+ },
+ {
+ "address_family": [
+ {
+ "afi": "ipv4",
+ "disable_forwarding": False,
+ "nht_no_resolve_via_default": False,
+ "route_maps": [
+ {
+ "protocol": "ospf",
+ "rm_name": "rm1",
+ },
+ ],
+ },
+ {
+ "afi": "ipv6",
+ "disable_forwarding": False,
+ "nht_no_resolve_via_default": True,
+ },
+ ],
+ "disable": False,
+ "name": "vrf-red",
+ },
+ ],
+ }
+ self.assertEqual(parsed_list, result["parsed"])
+
+ def test_vrf_gathered(self):
+ set_module_args(dict(state="gathered"))
+ result = self.execute_module(changed=False)
+ gathered_list = {
+ "bind_to_all": True,
+ "instances": [
+ {
+ "description": "blue-vrf",
+ "disable": False,
+ "name": "vrf-blue",
+ "table_id": 100,
+ "vni": 1000,
+ },
+ {
+ "address_family": [
+ {
+ "afi": "ipv4",
+ "disable_forwarding": True,
+ "nht_no_resolve_via_default": False,
+ "route_maps": [
+ {"protocol": "rip", "rm_name": "rm1"},
+ ],
+ },
+ {
+ "afi": "ipv6",
+ "disable_forwarding": False,
+ "nht_no_resolve_via_default": True,
+ },
+ ],
+ "description": "red-vrf",
+ "disable": True,
+ "name": "vrf-red",
+ "protocols": {
+ "bgp": {
+ "as_number": 65000,
+ "neighbor": [
+ {"address": "1.1.1.3", "passive": True, "remote_as": 400},
+ {"address": "192.0.2.1", "remote_as": 65002},
+ ],
+ },
+ },
+ "table_id": 101,
+ "vni": 1001,
+ },
+ ],
+ }
+ self.assertEqual(gathered_list, result["gathered"])
+
+ def test_vrf_deleted(self):
+ set_module_args(
+ dict(
+ config=dict(
+ bind_to_all=True,
+ instances=[
+ dict(
+ name="vrf-blue",
+ ),
+ ],
+ ),
+ state="deleted",
+ ),
+ )
+ commands = [
+ "delete vrf bind-to-all",
+ "delete vrf name vrf-blue",
+ ]
+ self.execute_module(changed=True, commands=commands)
+
+ def test_vrf_all_deleted(self):
+ set_module_args(
+ dict(
+ state="deleted",
+ ),
+ )
+ commands = [
+ "delete vrf",
+ ]
+ self.execute_module(changed=True, commands=commands)