From c2cf82dfea4aa89e5aa9ba57b798bee030a9abbe Mon Sep 17 00:00:00 2001 From: Shawn Wilsher <656602+sdwilsh@users.noreply.github.com> Date: Mon, 20 Sep 2021 16:25:49 -0700 Subject: Add support for IPv6 `address_group` and `network_group` (#202) Add support for IPv6 `address_group` and `network_group` SUMMARY This adds support for ipv6 in network and address groups by adding an afi parameter, but defaulting it to ipv4 for backwards compatibility. Fixes #137. ISSUE TYPE Feature Pull Request COMPONENT NAME vyos_firewall_global Reviewed-by: GomathiselviS Reviewed-by: Shawn Wilsher Reviewed-by: None --- .../support_ipv6_address_and_network_groups.yaml | 4 + .../argspec/firewall_global/firewall_global.py | 10 +++ .../vyos/config/firewall_global/firewall_global.py | 9 +- .../vyos/facts/firewall_global/firewall_global.py | 26 ++++-- plugins/modules/vyos_firewall_global.py | 18 ++++ .../targets/vyos_firewall_global/vars/main.yaml | 9 ++ .../vyos/fixtures/vyos_firewall_global_config.cfg | 5 ++ .../network/vyos/test_vyos_firewall_global.py | 95 ++++++++++++++++++++-- 8 files changed, 162 insertions(+), 14 deletions(-) create mode 100644 changelogs/fragments/support_ipv6_address_and_network_groups.yaml diff --git a/changelogs/fragments/support_ipv6_address_and_network_groups.yaml b/changelogs/fragments/support_ipv6_address_and_network_groups.yaml new file mode 100644 index 0000000..9243490 --- /dev/null +++ b/changelogs/fragments/support_ipv6_address_and_network_groups.yaml @@ -0,0 +1,4 @@ +--- +minor_changes: + - Adds support for specifying an `afi` for an `address_group` for `vyos.vyos.firewall_global`. As a result, `address_group` now supports IPv6. + - Adds support for specifying an `afi` for an `network_group` for `vyos.vyos.firewall_global`. As a result, `network_group` now supports IPv6. diff --git a/plugins/module_utils/network/vyos/argspec/firewall_global/firewall_global.py b/plugins/module_utils/network/vyos/argspec/firewall_global/firewall_global.py index 92a0255..baafa89 100644 --- a/plugins/module_utils/network/vyos/argspec/firewall_global/firewall_global.py +++ b/plugins/module_utils/network/vyos/argspec/firewall_global/firewall_global.py @@ -45,6 +45,11 @@ class Firewall_globalArgs(object): # pylint: disable=R0903 "address_group": { "elements": "dict", "options": { + "afi": { + "choices": ["ipv4", "ipv6"], + "default": "ipv4", + "type": "str", + }, "description": {"type": "str"}, "members": { "elements": "dict", @@ -58,6 +63,11 @@ class Firewall_globalArgs(object): # pylint: disable=R0903 "network_group": { "elements": "dict", "options": { + "afi": { + "choices": ["ipv4", "ipv6"], + "default": "ipv4", + "type": "str", + }, "description": {"type": "str"}, "members": { "elements": "dict", diff --git a/plugins/module_utils/network/vyos/config/firewall_global/firewall_global.py b/plugins/module_utils/network/vyos/config/firewall_global/firewall_global.py index 29da3ec..be8b172 100644 --- a/plugins/module_utils/network/vyos/config/firewall_global/firewall_global.py +++ b/plugins/module_utils/network/vyos/config/firewall_global/firewall_global.py @@ -378,8 +378,15 @@ class Firewall_global(ConfigBase): if w_grp: for want in w_grp: - cmd = self._compute_command(key="group", attr=attr, opr=opr) h = self.search_attrib_in_have(h_grp, want, "name") + if "afi" in want and want["afi"] == "ipv6": + cmd = self._compute_command( + key="group", attr="ipv6-" + attr, opr=opr + ) + else: + cmd = self._compute_command( + key="group", attr=attr, opr=opr + ) for key, val in iteritems(want): if val: if ( diff --git a/plugins/module_utils/network/vyos/facts/firewall_global/firewall_global.py b/plugins/module_utils/network/vyos/facts/firewall_global/firewall_global.py index e6e42d7..1b1076c 100644 --- a/plugins/module_utils/network/vyos/facts/firewall_global/firewall_global.py +++ b/plugins/module_utils/network/vyos/facts/firewall_global/firewall_global.py @@ -207,17 +207,24 @@ class Firewall_globalFacts(object): :return: generated config dictionary. """ cfg_dict = {} - cfg_dict["port_group"] = self.parse_group_lst(conf, "port-group") - cfg_dict["address_group"] = self.parse_group_lst(conf, "address-group") - cfg_dict["network_group"] = self.parse_group_lst(conf, "network-group") + cfg_dict["port_group"] = self.parse_group_lst( + conf, "port-group", False + ) + cfg_dict["address_group"] = self.parse_group_lst( + conf, "address-group" + ) + self.parse_group_lst(conf, "ipv6-address-group") + cfg_dict["network_group"] = self.parse_group_lst( + conf, "network-group" + ) + self.parse_group_lst(conf, "ipv6-network-group") return cfg_dict - def parse_group_lst(self, conf, type): + def parse_group_lst(self, conf, type, include_afi=True): """ This function fetches the name of group and invoke function to parse group attributes'. :param conf: configuration data. :param type: type of group. + :param include_afi: if the afi should be included in the parsed object :return: generated group list configuration. """ g_lst = [] @@ -228,7 +235,16 @@ class Firewall_globalFacts(object): for gr in set(groups): gr_regex = r" %s .+$" % gr cfg = "\n".join(findall(gr_regex, conf, M)) - obj = self.parse_groups(cfg, type, gr) + if "ipv6" in type: + # fmt: off + obj = self.parse_groups(cfg, type[len("ipv6-"):], gr) + # fmt: on + if include_afi: + obj["afi"] = "ipv6" + else: + obj = self.parse_groups(cfg, type, gr) + if include_afi: + obj["afi"] = "ipv4" obj["name"] = gr.strip("'") if obj: rules_lst.append(obj) diff --git a/plugins/modules/vyos_firewall_global.py b/plugins/modules/vyos_firewall_global.py index 71dc4a6..91d97a9 100644 --- a/plugins/modules/vyos_firewall_global.py +++ b/plugins/modules/vyos_firewall_global.py @@ -123,6 +123,15 @@ options: type: list elements: dict suboptions: + afi: + description: + - Specifies IP address type + type: str + default: ipv4 + choices: + - ipv4 + - ipv6 + required: false name: description: - Name of the firewall address group. @@ -149,6 +158,15 @@ options: type: list elements: dict suboptions: + afi: + description: + - Specifies network address type + type: str + default: ipv4 + choices: + - ipv4 + - ipv6 + required: false name: description: - Name of the firewall network group. diff --git a/tests/integration/targets/vyos_firewall_global/vars/main.yaml b/tests/integration/targets/vyos_firewall_global/vars/main.yaml index 4a1e7a8..faa0ff1 100644 --- a/tests/integration/targets/vyos_firewall_global/vars/main.yaml +++ b/tests/integration/targets/vyos_firewall_global/vars/main.yaml @@ -35,11 +35,13 @@ merged: - address: 192.0.1.5 description: This group has the Management hosts address list name: MGMT-HOSTS + afi: ipv4 network_group: - members: - address: 192.0.1.0/24 description: This group has the Management network addresses name: MGMT + afi: ipv4 log_martians: true ping: all: true @@ -88,11 +90,13 @@ populate: - address: 192.0.1.1 - address: 192.0.1.3 - address: 192.0.1.5 + afi: ipv4 network_group: - name: MGMT description: This group has the Management network addresses members: - address: 192.0.1.0/24 + afi: ipv4 replaced: commands: - delete firewall group address-group MGMT-HOSTS @@ -116,17 +120,20 @@ replaced: - address: 192.0.3.2 description: Sales office hosts address list name: ENG-HOSTS + afi: ipv4 - members: - address: 192.0.2.1 - address: 192.0.2.2 - address: 192.0.2.3 description: Sales office hosts address list name: SALES-HOSTS + afi: ipv4 network_group: - members: - address: 192.0.1.0/24 description: This group has the Management network addresses name: MGMT + afi: ipv4 log_martians: true ping: all: true @@ -210,8 +217,10 @@ round_trip: - address: 192.0.1.1 - address: 192.0.1.3 - address: 192.0.1.5 + afi: ipv4 network_group: - name: MGMT description: This group has the Management network addresses members: - address: 192.0.1.0/24 + afi: ipv4 diff --git a/tests/unit/modules/network/vyos/fixtures/vyos_firewall_global_config.cfg b/tests/unit/modules/network/vyos/fixtures/vyos_firewall_global_config.cfg index 6c275a3..16b7a14 100644 --- a/tests/unit/modules/network/vyos/fixtures/vyos_firewall_global_config.cfg +++ b/tests/unit/modules/network/vyos/fixtures/vyos_firewall_global_config.cfg @@ -2,7 +2,12 @@ set firewall group address-group RND-HOSTS address 192.0.2.1 set firewall group address-group RND-HOSTS address 192.0.2.3 set firewall group address-group RND-HOSTS address 192.0.2.5 set firewall group address-group RND-HOSTS description 'This group has the Management hosts address lists' +set firewall group ipv6-address-group LOCAL-v6 address ::1 +set firewall group ipv6-address-group LOCAL-v6 address fdec:2503:89d6:59b3::1 +set firewall group ipv6-address-group LOCAL-v6 description 'This group has the hosts address lists of this machine' set firewall group network-group RND network 192.0.2.0/24 set firewall group network-group RND description 'This group has the Management network addresses' +set firewall group ipv6-network-group UNIQUE-LOCAL-v6 network fc00::/7 +set firewall group ipv6-network-group UNIQUE-LOCAL-v6 description 'This group encompasses the ULA address space in IPv6' set firewall group port-group SSH port 22 set firewall group port-group SSH description 'This group has the ssh ports' diff --git a/tests/unit/modules/network/vyos/test_vyos_firewall_global.py b/tests/unit/modules/network/vyos/test_vyos_firewall_global.py index fa40d7c..0e62be8 100644 --- a/tests/unit/modules/network/vyos/test_vyos_firewall_global.py +++ b/tests/unit/modules/network/vyos/test_vyos_firewall_global.py @@ -106,6 +106,7 @@ class TestVyosFirewallRulesModule(TestVyosModule): group=dict( address_group=[ dict( + afi="ipv4", name="MGMT-HOSTS", description="This group has the Management hosts address lists", members=[ @@ -113,14 +114,32 @@ class TestVyosFirewallRulesModule(TestVyosModule): dict(address="192.0.1.3"), dict(address="192.0.1.5"), ], - ) + ), + dict( + afi="ipv6", + name="GOOGLE-DNS-v6", + members=[ + dict(address="2001:4860:4860::8888"), + dict(address="2001:4860:4860::8844"), + ], + ), ], network_group=[ dict( + afi="ipv4", name="MGMT", description="This group has the Management network addresses", members=[dict(address="192.0.1.0/24")], - ) + ), + dict( + afi="ipv6", + name="DOCUMENTATION-v6", + description="IPv6 Addresses reserved for documentation per RFC 3849", + members=[ + dict(address="2001:0DB8::/32"), + dict(address="3FFF:FFFF::/32"), + ], + ), ], port_group=[ dict( @@ -140,9 +159,16 @@ class TestVyosFirewallRulesModule(TestVyosModule): "set firewall group address-group MGMT-HOSTS address 192.0.1.5", "set firewall group address-group MGMT-HOSTS description 'This group has the Management hosts address lists'", "set firewall group address-group MGMT-HOSTS", + "set firewall group ipv6-address-group GOOGLE-DNS-v6 address 2001:4860:4860::8888", + "set firewall group ipv6-address-group GOOGLE-DNS-v6 address 2001:4860:4860::8844", + "set firewall group ipv6-address-group GOOGLE-DNS-v6", "set firewall group network-group MGMT network 192.0.1.0/24", "set firewall group network-group MGMT description 'This group has the Management network addresses'", "set firewall group network-group MGMT", + "set firewall group ipv6-network-group DOCUMENTATION-v6 network 2001:0DB8::/32", + "set firewall group ipv6-network-group DOCUMENTATION-v6 network 3FFF:FFFF::/32", + "set firewall group ipv6-network-group DOCUMENTATION-v6 description 'IPv6 Addresses reserved for documentation per RFC 3849'", + "set firewall group ipv6-network-group DOCUMENTATION-v6", "set firewall group port-group TELNET port 23", "set firewall group port-group TELNET description 'This group has the telnet ports'", "set firewall group port-group TELNET", @@ -169,6 +195,7 @@ class TestVyosFirewallRulesModule(TestVyosModule): group=dict( address_group=[ dict( + afi="ipv4", name="RND-HOSTS", description="This group has the Management hosts address lists", members=[ @@ -176,14 +203,30 @@ class TestVyosFirewallRulesModule(TestVyosModule): dict(address="192.0.2.3"), dict(address="192.0.2.5"), ], - ) + ), + 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( @@ -206,6 +249,7 @@ class TestVyosFirewallRulesModule(TestVyosModule): group=dict( address_group=[ dict( + afi="ipv4", name="RND-HOSTS", description="This group has the Management hosts address lists", members=[ @@ -213,14 +257,30 @@ class TestVyosFirewallRulesModule(TestVyosModule): dict(address="192.0.2.7"), dict(address="192.0.2.9"), ], - ) + ), + 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::2"), + ], + ), ], 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( @@ -239,6 +299,8 @@ class TestVyosFirewallRulesModule(TestVyosModule): "delete firewall group address-group RND-HOSTS address 192.0.2.5", "set firewall group address-group RND-HOSTS address 192.0.2.7", "set firewall group address-group RND-HOSTS address 192.0.2.9", + "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", ] @@ -251,6 +313,7 @@ class TestVyosFirewallRulesModule(TestVyosModule): group=dict( address_group=[ dict( + afi="ipv4", name="RND-HOSTS", description="This group has the Management hosts address lists", members=[ @@ -258,14 +321,30 @@ class TestVyosFirewallRulesModule(TestVyosModule): dict(address="192.0.2.3"), dict(address="192.0.2.5"), ], - ) + ), + 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( -- cgit v1.2.3