summaryrefslogtreecommitdiff
path: root/tests/unit/modules
diff options
context:
space:
mode:
authoromnom62 <75066712+omnom62@users.noreply.github.com>2026-08-27 04:00:17 +1000
committerGitHub <noreply@github.com>2026-08-26 21:00:17 +0300
commit433a274ce636573953f8a4be9c68743a2ed1d0a5 (patch)
treeda9e545f9ffdf50289c1b94580450a456177d74b /tests/unit/modules
parent899a6bf7955592ec40670944a860a1bee97b432c (diff)
downloadvyos.vyos-433a274ce636573953f8a4be9c68743a2ed1d0a5.tar.gz
vyos.vyos-433a274ce636573953f8a4be9c68743a2ed1d0a5.zip
T8220: Firewall Zone Policy support (#447)
Add zone base policy firewall module
Diffstat (limited to 'tests/unit/modules')
-rw-r--r--tests/unit/modules/network/vyos/fixtures/vyos_firewall_global_config_v14.cfg6
-rw-r--r--tests/unit/modules/network/vyos/fixtures/vyos_firewall_global_config_v15.cfg11
-rw-r--r--tests/unit/modules/network/vyos/test_vyos_firewall_global14.py498
-rw-r--r--tests/unit/modules/network/vyos/test_vyos_firewall_global15.py132
4 files changed, 647 insertions, 0 deletions
diff --git a/tests/unit/modules/network/vyos/fixtures/vyos_firewall_global_config_v14.cfg b/tests/unit/modules/network/vyos/fixtures/vyos_firewall_global_config_v14.cfg
index c883ca78..f58f166c 100644
--- a/tests/unit/modules/network/vyos/fixtures/vyos_firewall_global_config_v14.cfg
+++ b/tests/unit/modules/network/vyos/fixtures/vyos_firewall_global_config_v14.cfg
@@ -22,3 +22,9 @@ set firewall global-options send-redirects 'enable'
set firewall zone ZONE-TEST interface 'eth0.1234'
set firewall zone ZONE-TEST description 'zone-test test description'
set firewall group address-group ZONE-TEST address '1.2.3.4'
+set firewall zone ZONE-IZF description 'zone for izf and sources delete path testing'
+set firewall zone ZONE-IZF intra-zone-filtering action 'drop'
+set firewall zone ZONE-IZF from zone-src firewall name 'existing-ruleset'
+set firewall name TESTRULESET-V4 default-action drop
+set firewall ipv6-name TESTRULESET-V6-LEGACY default-action drop
+set firewall ipv6 name TESTRULESET-V6-1_4PLUS default-action drop
diff --git a/tests/unit/modules/network/vyos/fixtures/vyos_firewall_global_config_v15.cfg b/tests/unit/modules/network/vyos/fixtures/vyos_firewall_global_config_v15.cfg
new file mode 100644
index 00000000..23dd9777
--- /dev/null
+++ b/tests/unit/modules/network/vyos/fixtures/vyos_firewall_global_config_v15.cfg
@@ -0,0 +1,11 @@
+# Intentionally minimal: represents a VyOS 1.5.0 device with one existing
+# zone already configured using the 1.5.0 'member interface' syntax. Used
+# to test parse_zone's unwrap logic in isolation. TestVyosFirewallRulesModule15's
+# other tests (e.g. test_01_merged) create a differently-named zone
+# (ZONE-15), so under 'merged' state this existing zone is never touched
+# and doesn't interfere.
+set firewall zone ZONE-15-EXISTING member interface eth2
+set firewall zone ZONE-15-EXISTING description 'existing 1.5.0 zone for facts parsing test'
+set firewall name TESTRULESET-V4 default-action drop
+set firewall ipv6-name TESTRULESET-V6-LEGACY default-action drop
+set firewall ipv6 name TESTRULESET-V6-1_4PLUS default-action drop
diff --git a/tests/unit/modules/network/vyos/test_vyos_firewall_global14.py b/tests/unit/modules/network/vyos/test_vyos_firewall_global14.py
index a7abfe8c..397ccfbd 100644
--- a/tests/unit/modules/network/vyos/test_vyos_firewall_global14.py
+++ b/tests/unit/modules/network/vyos/test_vyos_firewall_global14.py
@@ -158,6 +158,31 @@ class TestVyosFirewallRulesModule14(TestVyosModule):
),
],
),
+ zone=[
+ dict(
+ name="FZP-2",
+ default_action="reject",
+ default_log=True,
+ description="This is the Firewall zone fzp2",
+ interfaces=[
+ "eth2",
+ "lo0",
+ ],
+ local_zone=True,
+ sources=[
+ dict(
+ zone="fzp5",
+ firewall=dict(
+ name="fzp1",
+ ipv6_name="fzp1-v6",
+ ),
+ ),
+ ],
+ intra_zone_filtering=dict(
+ action="accept",
+ ),
+ ),
+ ],
),
state="merged",
),
@@ -195,6 +220,15 @@ class TestVyosFirewallRulesModule14(TestVyosModule):
"set firewall global-options twa-hazards-protection 'enable'",
"set firewall global-options syn-cookies 'enable'",
"set firewall global-options source-validation 'strict'",
+ "set firewall zone FZP-2 default-action 'reject'",
+ "set firewall zone FZP-2 default-log",
+ "set firewall zone FZP-2 description 'This is the Firewall zone fzp2'",
+ "set firewall zone FZP-2 from fzp5 firewall ipv6-name fzp1-v6",
+ "set firewall zone FZP-2 from fzp5 firewall name fzp1",
+ "set firewall zone FZP-2 interface eth2",
+ "set firewall zone FZP-2 interface lo0",
+ "set firewall zone FZP-2 intra-zone-filtering action accept",
+ "set firewall zone FZP-2 local-zone",
]
self.execute_module(changed=True, commands=commands)
@@ -321,6 +355,31 @@ class TestVyosFirewallRulesModule14(TestVyosModule):
),
],
),
+ zone=[
+ dict(
+ name="FZP-2",
+ default_action="drop",
+ default_log=True,
+ description="This is the Firewall zone fzp2",
+ interfaces=[
+ "eth2",
+ "lo0",
+ ],
+ local_zone=True,
+ sources=[
+ dict(
+ zone="fzp5",
+ firewall=dict(
+ name="fzp1",
+ ipv6_name="fzp1-v6",
+ ),
+ ),
+ ],
+ intra_zone_filtering=dict(
+ action="accept",
+ ),
+ ),
+ ],
),
state="replaced",
),
@@ -334,15 +393,26 @@ class TestVyosFirewallRulesModule14(TestVyosModule):
"delete firewall global-options state-policy related",
"delete firewall global-options ipv6-src-route",
"delete firewall global-options send-redirects",
+ "delete firewall zone ZONE-IZF",
"set firewall global-options state-policy invalid action 'reject'",
"set firewall group address-group RND-HOSTS address 192.0.2.7",
"set firewall group address-group RND-HOSTS address 192.0.2.9",
"set firewall group address-group ZONE-TEST description 'This is a new description for a address group name that is also in a zone'",
+ "delete firewall zone ZONE-TEST",
"delete firewall group network-group RND description",
"delete firewall group ipv6-address-group LOCAL-v6 address fdec:2503:89d6:59b3::1",
"set firewall group ipv6-address-group LOCAL-v6 address fdec:2503:89d6:59b3::2",
"delete firewall group port-group SSH port 22",
"set firewall group port-group SSH port 2222",
+ "set firewall zone FZP-2 default-action 'drop'",
+ "set firewall zone FZP-2 default-log",
+ "set firewall zone FZP-2 description 'This is the Firewall zone fzp2'",
+ "set firewall zone FZP-2 from fzp5 firewall ipv6-name fzp1-v6",
+ "set firewall zone FZP-2 from fzp5 firewall name fzp1",
+ "set firewall zone FZP-2 interface eth2",
+ "set firewall zone FZP-2 interface lo0",
+ "set firewall zone FZP-2 intra-zone-filtering action accept",
+ "set firewall zone FZP-2 local-zone",
]
self.execute_module(changed=True, commands=commands)
@@ -421,6 +491,24 @@ class TestVyosFirewallRulesModule14(TestVyosModule):
),
],
),
+ zone=[
+ dict(
+ name="ZONE-TEST",
+ description="zone-test test description",
+ interfaces=["eth0.1234"],
+ ),
+ dict(
+ name="ZONE-IZF",
+ description="zone for izf and sources delete path testing",
+ intra_zone_filtering=dict(action="drop"),
+ sources=[
+ dict(
+ zone="zone-src",
+ firewall=dict(name="existing-ruleset"),
+ ),
+ ],
+ ),
+ ],
),
state="replaced",
),
@@ -487,6 +575,15 @@ class TestVyosFirewallRulesModule14(TestVyosModule):
),
],
),
+ zone=[
+ dict(
+ name="ZONE-TEST",
+ description="zone-test test description",
+ interfaces=[
+ "lo",
+ ],
+ ),
+ ],
),
state="replaced",
),
@@ -496,6 +593,7 @@ class TestVyosFirewallRulesModule14(TestVyosModule):
"delete firewall group address-group RND-HOSTS address 192.0.2.3",
"delete firewall group address-group RND-HOSTS address 192.0.2.5",
"delete firewall group address-group ZONE-TEST address 1.2.3.4",
+ "delete firewall zone ZONE-IZF",
"delete firewall global-options all-ping",
"delete firewall global-options ipv6-src-route",
"delete firewall global-options send-redirects",
@@ -506,6 +604,8 @@ class TestVyosFirewallRulesModule14(TestVyosModule):
"set firewall group address-group RND-HOSTS address 192.0.2.7",
"set firewall group address-group RND-HOSTS address 192.0.2.9",
"set firewall group address-group ZONE-TEST address 4.3.2.1",
+ "delete firewall zone ZONE-TEST interface eth0.1234",
+ "set firewall zone ZONE-TEST interface lo",
"set firewall group address-group ZONE-TEST description 'This is a new description for a address group name that is also in a zone'",
"delete firewall group ipv6-address-group LOCAL-v6 address fdec:2503:89d6:59b3::1",
"set firewall group ipv6-address-group LOCAL-v6 address fdec:2503:89d6:59b3::2",
@@ -518,3 +618,401 @@ class TestVyosFirewallRulesModule14(TestVyosModule):
set_module_args(dict(config=dict(), state="deleted"))
commands = ["delete firewall"]
self.execute_module(changed=True, commands=commands)
+
+ def test_vyos_firewall_global_set_03_replaced_izf_action_change(self):
+ set_module_args(
+ dict(
+ config=dict(
+ ping=dict(all=True),
+ route_redirects=[
+ dict(ip_src_route=True, afi="ipv6"),
+ dict(icmp_redirects=dict(send=True), afi="ipv4"),
+ ],
+ state_policy=[
+ dict(connection_type="related", action="accept", log_level="alert"),
+ ],
+ group=dict(
+ address_group=[
+ dict(afi="ipv4", name="A-EMPTY"),
+ dict(
+ afi="ipv4",
+ name="RND-HOSTS",
+ description="This group has the Management hosts address lists",
+ members=[
+ dict(address="192.0.2.1"),
+ dict(address="192.0.2.3"),
+ dict(address="192.0.2.5"),
+ ],
+ ),
+ dict(
+ afi="ipv4",
+ name="DELETE-HOSTS",
+ description="The (single) last address from this group will be deleted in the tests",
+ members=[dict(address="1.2.3.4")],
+ ),
+ dict(
+ afi="ipv4",
+ name="ZONE-TEST",
+ members=[dict(address="1.2.3.4")],
+ ),
+ dict(
+ afi="ipv6",
+ name="LOCAL-v6",
+ description="This group has the hosts address lists of this machine",
+ members=[
+ dict(address="::1"),
+ dict(address="fdec:2503:89d6:59b3::1"),
+ ],
+ ),
+ ],
+ network_group=[
+ dict(
+ afi="ipv4",
+ name="RND",
+ description="This group has the Management network addresses",
+ members=[dict(address="192.0.2.0/24")],
+ ),
+ dict(
+ afi="ipv6",
+ name="UNIQUE-LOCAL-v6",
+ description="This group encompasses the ULA address space in IPv6",
+ members=[dict(address="fc00::/7")],
+ ),
+ ],
+ port_group=[
+ dict(
+ name="SSH",
+ description="This group has the ssh ports",
+ members=[dict(port="22")],
+ ),
+ ],
+ ),
+ zone=[
+ dict(
+ name="ZONE-TEST",
+ description="zone-test test description",
+ interfaces=["eth0.1234"],
+ ),
+ dict(
+ name="ZONE-IZF",
+ description="zone for izf and sources delete path testing",
+ intra_zone_filtering=dict(action="accept"), # was 'drop'
+ sources=[
+ dict(
+ zone="zone-src",
+ firewall=dict(name="existing-ruleset"),
+ ),
+ ],
+ ),
+ ],
+ ),
+ state="replaced",
+ ),
+ )
+ commands = [
+ "delete firewall zone ZONE-IZF intra-zone-filtering action",
+ "set firewall zone ZONE-IZF intra-zone-filtering action accept",
+ ]
+ self.execute_module(changed=True, commands=commands)
+
+ def test_vyos_firewall_global_set_04_replaced_sources_value_change(self):
+ # ZONE-IZF.sources[0].firewall.name changes from 'existing-ruleset'
+ # (fixture) to 'new-ruleset'. Exercises _render_sources' `not opr
+ # and hfw` (delete) branch. Pre-fix this leaked the old value into
+ # the delete command.
+ set_module_args(
+ dict(
+ config=dict(
+ ping=dict(all=True),
+ route_redirects=[
+ dict(ip_src_route=True, afi="ipv6"),
+ dict(icmp_redirects=dict(send=True), afi="ipv4"),
+ ],
+ state_policy=[
+ dict(connection_type="related", action="accept", log_level="alert"),
+ ],
+ group=dict(
+ address_group=[
+ dict(afi="ipv4", name="A-EMPTY"),
+ dict(
+ afi="ipv4",
+ name="RND-HOSTS",
+ description="This group has the Management hosts address lists",
+ members=[
+ dict(address="192.0.2.1"),
+ dict(address="192.0.2.3"),
+ dict(address="192.0.2.5"),
+ ],
+ ),
+ dict(
+ afi="ipv4",
+ name="DELETE-HOSTS",
+ description="The (single) last address from this group will be deleted in the tests",
+ members=[dict(address="1.2.3.4")],
+ ),
+ dict(
+ afi="ipv4",
+ name="ZONE-TEST",
+ members=[dict(address="1.2.3.4")],
+ ),
+ dict(
+ afi="ipv6",
+ name="LOCAL-v6",
+ description="This group has the hosts address lists of this machine",
+ members=[
+ dict(address="::1"),
+ dict(address="fdec:2503:89d6:59b3::1"),
+ ],
+ ),
+ ],
+ network_group=[
+ dict(
+ afi="ipv4",
+ name="RND",
+ description="This group has the Management network addresses",
+ members=[dict(address="192.0.2.0/24")],
+ ),
+ dict(
+ afi="ipv6",
+ name="UNIQUE-LOCAL-v6",
+ description="This group encompasses the ULA address space in IPv6",
+ members=[dict(address="fc00::/7")],
+ ),
+ ],
+ port_group=[
+ dict(
+ name="SSH",
+ description="This group has the ssh ports",
+ members=[dict(port="22")],
+ ),
+ ],
+ ),
+ zone=[
+ dict(
+ name="ZONE-TEST",
+ description="zone-test test description",
+ interfaces=["eth0.1234"],
+ ),
+ dict(
+ name="ZONE-IZF",
+ description="zone for izf and sources delete path testing",
+ intra_zone_filtering=dict(action="drop"),
+ sources=[
+ dict(
+ zone="zone-src",
+ firewall=dict(name="new-ruleset"), # was 'existing-ruleset'
+ ),
+ ],
+ ),
+ ],
+ ),
+ state="replaced",
+ ),
+ )
+ commands = [
+ "delete firewall zone ZONE-IZF from zone-src firewall name",
+ "set firewall zone ZONE-IZF from zone-src firewall name new-ruleset",
+ ]
+ self.execute_module(changed=True, commands=commands)
+
+ def test_vyos_firewall_global_set_05_replaced_sources_firewall_cleared(self):
+ # ZONE-IZF.sources[0] keeps the 'zone-src' key but drops the
+ # 'firewall' sub-dict entirely. Exercises _render_sources' `not opr
+ # and not hfw` branch -- unreachable before the fix, since it was
+ # guarded by `not have` instead of `not hfw`, and `have` can never
+ # be empty here (we're already inside `if zone in have_index`).
+ set_module_args(
+ dict(
+ config=dict(
+ ping=dict(all=True),
+ route_redirects=[
+ dict(ip_src_route=True, afi="ipv6"),
+ dict(icmp_redirects=dict(send=True), afi="ipv4"),
+ ],
+ state_policy=[
+ dict(connection_type="related", action="accept", log_level="alert"),
+ ],
+ group=dict(
+ address_group=[
+ dict(afi="ipv4", name="A-EMPTY"),
+ dict(
+ afi="ipv4",
+ name="RND-HOSTS",
+ description="This group has the Management hosts address lists",
+ members=[
+ dict(address="192.0.2.1"),
+ dict(address="192.0.2.3"),
+ dict(address="192.0.2.5"),
+ ],
+ ),
+ dict(
+ afi="ipv4",
+ name="DELETE-HOSTS",
+ description="The (single) last address from this group will be deleted in the tests",
+ members=[dict(address="1.2.3.4")],
+ ),
+ dict(
+ afi="ipv4",
+ name="ZONE-TEST",
+ members=[dict(address="1.2.3.4")],
+ ),
+ dict(
+ afi="ipv6",
+ name="LOCAL-v6",
+ description="This group has the hosts address lists of this machine",
+ members=[
+ dict(address="::1"),
+ dict(address="fdec:2503:89d6:59b3::1"),
+ ],
+ ),
+ ],
+ network_group=[
+ dict(
+ afi="ipv4",
+ name="RND",
+ description="This group has the Management network addresses",
+ members=[dict(address="192.0.2.0/24")],
+ ),
+ dict(
+ afi="ipv6",
+ name="UNIQUE-LOCAL-v6",
+ description="This group encompasses the ULA address space in IPv6",
+ members=[dict(address="fc00::/7")],
+ ),
+ ],
+ port_group=[
+ dict(
+ name="SSH",
+ description="This group has the ssh ports",
+ members=[dict(port="22")],
+ ),
+ ],
+ ),
+ zone=[
+ dict(
+ name="ZONE-TEST",
+ description="zone-test test description",
+ interfaces=["eth0.1234"],
+ ),
+ dict(
+ name="ZONE-IZF",
+ description="zone for izf and sources delete path testing",
+ intra_zone_filtering=dict(action="drop"),
+ sources=[
+ dict(zone="zone-src"), # firewall dropped entirely
+ ],
+ ),
+ ],
+ ),
+ state="replaced",
+ ),
+ )
+ commands = [
+ "delete firewall zone ZONE-IZF from zone-src",
+ ]
+ self.execute_module(changed=True, commands=commands)
+
+ def test_vyos_firewall_global_set_06_replaced_sources_entry_removed(self):
+ # ZONE-IZF's sources list drops the 'zone-src' entry entirely (not
+ # just its firewall sub-dict). Exercises the new `elif not opr:`
+ # branch -- previously this case emitted nothing at all.
+ set_module_args(
+ dict(
+ config=dict(
+ ping=dict(all=True),
+ route_redirects=[
+ dict(ip_src_route=True, afi="ipv6"),
+ dict(icmp_redirects=dict(send=True), afi="ipv4"),
+ ],
+ state_policy=[
+ dict(connection_type="related", action="accept", log_level="alert"),
+ ],
+ group=dict(
+ address_group=[
+ dict(afi="ipv4", name="A-EMPTY"),
+ dict(
+ afi="ipv4",
+ name="RND-HOSTS",
+ description="This group has the Management hosts address lists",
+ members=[
+ dict(address="192.0.2.1"),
+ dict(address="192.0.2.3"),
+ dict(address="192.0.2.5"),
+ ],
+ ),
+ dict(
+ afi="ipv4",
+ name="DELETE-HOSTS",
+ description="The (single) last address from this group will be deleted in the tests",
+ members=[dict(address="1.2.3.4")],
+ ),
+ dict(
+ afi="ipv4",
+ name="ZONE-TEST",
+ members=[dict(address="1.2.3.4")],
+ ),
+ dict(
+ afi="ipv6",
+ name="LOCAL-v6",
+ description="This group has the hosts address lists of this machine",
+ members=[
+ dict(address="::1"),
+ dict(address="fdec:2503:89d6:59b3::1"),
+ ],
+ ),
+ ],
+ network_group=[
+ dict(
+ afi="ipv4",
+ name="RND",
+ description="This group has the Management network addresses",
+ members=[dict(address="192.0.2.0/24")],
+ ),
+ dict(
+ afi="ipv6",
+ name="UNIQUE-LOCAL-v6",
+ description="This group encompasses the ULA address space in IPv6",
+ members=[dict(address="fc00::/7")],
+ ),
+ ],
+ port_group=[
+ dict(
+ name="SSH",
+ description="This group has the ssh ports",
+ members=[dict(port="22")],
+ ),
+ ],
+ ),
+ zone=[
+ dict(
+ name="ZONE-TEST",
+ description="zone-test test description",
+ interfaces=["eth0.1234"],
+ ),
+ dict(
+ name="ZONE-IZF",
+ description="zone for izf and sources delete path testing",
+ intra_zone_filtering=dict(action="drop"),
+ # sources omitted entirely
+ ),
+ ],
+ ),
+ state="replaced",
+ ),
+ )
+ commands = [
+ "delete firewall zone ZONE-IZF from zone-src",
+ ]
+ self.execute_module(changed=True, commands=commands)
+
+ def test_vyos_firewall_global_ruleset_lines_filtered_from_facts(self):
+ # Confirms render_config's pre-filter strips all three ruleset-line
+ # prefixes (IPv4 name, legacy hyphenated ipv6-name, and 1.4+
+ # space-separated "ipv6 name") before zone/global-options parsing
+ # runs, on a real 1.4.x-shaped fixture alongside existing zone data.
+ set_module_args(dict(config=dict(), state="gathered"))
+ result = self.execute_module(changed=False)
+ facts = result["gathered"]
+ self.assertNotIn("TESTRULESET-V4", str(facts))
+ self.assertNotIn("TESTRULESET-V6-LEGACY", str(facts))
+ self.assertNotIn("TESTRULESET-V6-1_4PLUS", str(facts))
diff --git a/tests/unit/modules/network/vyos/test_vyos_firewall_global15.py b/tests/unit/modules/network/vyos/test_vyos_firewall_global15.py
new file mode 100644
index 00000000..22ab5364
--- /dev/null
+++ b/tests/unit/modules/network/vyos/test_vyos_firewall_global15.py
@@ -0,0 +1,132 @@
+# (c) 2016 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/>.
+
+# Make coding more python3-ish
+from __future__ import absolute_import, division, print_function
+
+
+__metaclass__ = type
+
+from unittest.mock import patch
+
+from ansible_collections.vyos.vyos.plugins.modules import vyos_firewall_global
+from ansible_collections.vyos.vyos.tests.unit.modules.utils import set_module_args
+
+from .vyos_module import TestVyosModule, load_fixture
+
+
+class TestVyosFirewallRulesModule15(TestVyosModule):
+ module = vyos_firewall_global
+
+ def setUp(self):
+ super(TestVyosFirewallRulesModule15, self).setUp()
+ self.mock_get_config = patch(
+ "ansible_collections.ansible.netcommon.plugins.module_utils.network.common.network.Config.get_config",
+ )
+ self.get_config = self.mock_get_config.start()
+
+ self.mock_load_config = patch(
+ "ansible_collections.ansible.netcommon.plugins.module_utils.network.common.network.Config.load_config",
+ )
+ self.load_config = self.mock_load_config.start()
+
+ self.mock_get_resource_connection_config = patch(
+ "ansible_collections.ansible.netcommon.plugins.module_utils.network.common.cfg.base.get_resource_connection",
+ )
+ self.get_resource_connection_config = self.mock_get_resource_connection_config.start()
+
+ self.mock_get_resource_connection_facts = patch(
+ "ansible_collections.ansible.netcommon.plugins.module_utils.network.common.facts.facts.get_resource_connection",
+ )
+ self.get_resource_connection_facts = self.mock_get_resource_connection_facts.start()
+
+ self.mock_execute_show_command = patch(
+ "ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.facts.firewall_global.firewall_global.Firewall_globalFacts.get_device_data",
+ )
+
+ self.mock_get_os_version = patch(
+ "ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.config.firewall_global.firewall_global.get_os_version",
+ )
+ self.get_os_version = self.mock_get_os_version.start()
+ self.get_os_version.return_value = "1.5"
+
+ self.execute_show_command = self.mock_execute_show_command.start()
+ self.maxDiff = None
+
+ def tearDown(self):
+ super(TestVyosFirewallRulesModule15, self).tearDown()
+ self.mock_get_resource_connection_config.stop()
+ self.mock_get_resource_connection_facts.stop()
+ self.mock_get_config.stop()
+ self.mock_load_config.stop()
+ self.mock_execute_show_command.stop()
+ self.mock_get_os_version.stop()
+
+ def load_fixtures(self, commands=None, filename=None):
+ def load_from_file(*args, **kwargs):
+ return load_fixture("vyos_firewall_global_config_v15.cfg")
+
+ self.execute_show_command.side_effect = load_from_file
+
+ def test_vyos_firewall_global_set_01_merged_interface_uses_member_keyword(self):
+ # On a 1.5.0 device (empty fixture, no existing zone), merging a
+ # zone with an interface should render "member interface", not the
+ # bare "interface" used on 1.4.x / 1.5-rolling. This is the sole
+ # thing this class exists to prove right now -- the version-gate
+ # added to _render_interfaces.
+ set_module_args(
+ dict(
+ config=dict(
+ zone=[
+ dict(
+ name="ZONE-15",
+ interfaces=["eth1"],
+ ),
+ ],
+ ),
+ state="merged",
+ ),
+ )
+ commands = [
+ "set firewall zone ZONE-15 default-action 'drop'",
+ "set firewall zone ZONE-15 member interface eth1",
+ ]
+ self.execute_module(changed=True, commands=commands)
+
+ def test_vyos_firewall_global_set_02_gathered_member_interface_parsed(self):
+ # ZONE-15-EXISTING in the fixture uses 1.5.0's "member interface"
+ # syntax. Before the parse_zone fix, this misparsed into a bogus
+ # zone['member'] = "interface eth2" string field, and 'interfaces'
+ # was missing entirely. After the fix, it should land in
+ # 'interfaces' exactly like the pre-1.5.0 bare "interface" form.
+ set_module_args(dict(config=dict(), state="gathered"))
+ result = self.execute_module(changed=False)
+ zones = result["gathered"]["zone"]
+ zone = next(z for z in zones if z["name"] == "ZONE-15-EXISTING")
+ self.assertEqual(zone["interfaces"], ["eth2"])
+ self.assertEqual(zone["description"], "existing 1.5.0 zone for facts parsing test")
+ self.assertNotIn("member", zone)
+
+ def test_vyos_firewall_global_ruleset_lines_filtered_from_facts(self):
+ # Same coverage as the 1.4 version, confirmed independently on the
+ # 1.5.0 fixture/version path.
+ set_module_args(dict(config=dict(), state="gathered"))
+ result = self.execute_module(changed=False)
+ facts = result["gathered"]
+ self.assertNotIn("TESTRULESET-V4", str(facts))
+ self.assertNotIn("TESTRULESET-V6-LEGACY", str(facts))
+ self.assertNotIn("TESTRULESET-V6-1_4PLUS", str(facts))