diff options
author | omnom62 <75066712+omnom62@users.noreply.github.com> | 2025-03-03 09:10:38 +1000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-03-03 09:10:38 +1000 |
commit | 41e4b0734ca961d18c0a016a50b3c6e598a10dff (patch) | |
tree | 4a8a944a951eec56087dc842f4ab24ac3a77b88e | |
parent | 241de488727ba60af9b883ef8ed31571a119b856 (diff) | |
download | vyos.vyos-main.tar.gz vyos.vyos-main.zip |
* 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
8 files changed, 166 insertions, 5 deletions
diff --git a/changelogs/fragments/T6829-ospfv3-v1.3-area-interfacces.yml b/changelogs/fragments/T6829-ospfv3-v1.3-area-interfacces.yml new file mode 100644 index 00000000..7a969007 --- /dev/null +++ b/changelogs/fragments/T6829-ospfv3-v1.3-area-interfacces.yml @@ -0,0 +1,6 @@ +--- +bugfixes: + - vyos_ospfv3 - added support for adding interfaces to areas +trivial: + - vyos_ospfv3 - updated unit test suites to include area interfaces + - vyos_ospfv3 - added v1.4 unit test diff --git a/docs/vyos.vyos.vyos_ospfv3_module.rst b/docs/vyos.vyos.vyos_ospfv3_module.rst index 2bc2f504..6957b77d 100644 --- a/docs/vyos.vyos.vyos_ospfv3_module.rst +++ b/docs/vyos.vyos.vyos_ospfv3_module.rst @@ -121,6 +121,44 @@ Parameters <td class="elbow-placeholder"></td> <td colspan="2"> <div class="ansibleOptionAnchor" id="parameter-"></div> + <b>interface</b> + <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a> + <div style="font-size: small"> + <span style="color: purple">list</span> + / <span style="color: purple">elements=dictionary</span> + </div> + </td> + <td> + </td> + <td> + <div>Enable OSPVv3 on an interface for this area.</div> + <div style="font-size: small; color: darkgreen"><br/>aliases: interfaces</div> + </td> + </tr> + <tr> + <td class="elbow-placeholder"></td> + <td class="elbow-placeholder"></td> + <td class="elbow-placeholder"></td> + <td colspan="1"> + <div class="ansibleOptionAnchor" id="parameter-"></div> + <b>name</b> + <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a> + <div style="font-size: small"> + <span style="color: purple">string</span> + </div> + </td> + <td> + </td> + <td> + <div>Interface name.</div> + </td> + </tr> + + <tr> + <td class="elbow-placeholder"></td> + <td class="elbow-placeholder"></td> + <td colspan="2"> + <div class="ansibleOptionAnchor" id="parameter-"></div> <b>range</b> <a class="ansibleOptionLink" href="#parameter-" title="Permalink to this option"></a> <div style="font-size: small"> diff --git a/plugins/module_utils/network/vyos/argspec/ospfv3/ospfv3.py b/plugins/module_utils/network/vyos/argspec/ospfv3/ospfv3.py index a59606dd..61704345 100644 --- a/plugins/module_utils/network/vyos/argspec/ospfv3/ospfv3.py +++ b/plugins/module_utils/network/vyos/argspec/ospfv3/ospfv3.py @@ -47,6 +47,12 @@ class Ospfv3Args(object): # pylint: disable=R0903 "area_id": {"type": "str"}, "export_list": {"type": "str"}, "import_list": {"type": "str"}, + "interface": { + "aliases": ["interfaces"], + "type": "list", + "elements": "dict", + "options": {"name": {"type": "str"}}, + }, "range": { "elements": "dict", "options": { diff --git a/plugins/module_utils/network/vyos/config/ospfv3/ospfv3.py b/plugins/module_utils/network/vyos/config/ospfv3/ospfv3.py index 25d9a0ea..2538a6f5 100644 --- a/plugins/module_utils/network/vyos/config/ospfv3/ospfv3.py +++ b/plugins/module_utils/network/vyos/config/ospfv3/ospfv3.py @@ -33,6 +33,10 @@ from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.utils.utils _in_target, _is_w_same, ) +from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.utils.version import ( + LooseVersion, +) +from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.vyos import get_os_version class Ospfv3(ConfigBase): @@ -264,10 +268,12 @@ class Ospfv3(ConfigBase): name = { "redistribute": "route_type", "range": "address", + "interface": "name", } leaf_dict = { "redistribute": ("route_map", "route_type"), "range": ("address", "advertise", "not_advertise"), + "interface": ("name"), } leaf = leaf_dict[attr] w = want.get(attr) or [] @@ -282,14 +288,26 @@ class Ospfv3(ConfigBase): cmd = self._compute_command(opr=opr) h_item = search_obj_in_list(w_item[name[attr]], h, name[attr]) if opr and key in leaf and not _is_w_same(w_item, h_item, key): - if key == "route_type" or ( + if key in ["route_type", "name"] or ( key == "address" and "advertise" not in w_item and "not-advertise" not in w_item ): if not val: cmd = cmd.replace("set", "delete") - commands.append(cmd + attr + " " + str(val)) + if ( + LooseVersion(get_os_version(self._module)) >= LooseVersion("1.4") + and attr == "interface" + ): + words = cmd.split() + cmd14_list = [] + for word in words: + cmd14_list.append(word) + if word == "ospfv3": + cmd14_list.append(attr + " " + str(val)) + commands.append(" ".join(cmd14_list)) + else: + commands.append(cmd + attr + " " + str(val)) elif key in leaf_dict["range"] and key != "address": commands.append( cmd + attr + " " + w_item[name[attr]] + " " + key.replace("_", "-"), @@ -306,8 +324,20 @@ class Ospfv3(ConfigBase): + str(val), ) elif not opr and key in leaf and not _in_target(h_item, key): - if key in ("route_type", "address"): - commands.append(cmd + attr + " " + str(val)) + if key in ("route_type", "address", "name"): + if ( + LooseVersion(get_os_version(self._module)) >= LooseVersion("1.4") + and attr == "interface" + ): + words = cmd.split() + cmd14_list = [] + for word in words: + cmd14_list.append(word) + if word == "ospfv3": + cmd14_list.append(attr + " " + str(val)) + commands.append(" ".join(cmd14_list)) + else: + commands.append(cmd + attr + " " + str(val)) else: commands.append(cmd + (attr + " " + w_item[name[attr]] + " " + key)) return commands @@ -373,6 +403,10 @@ class Ospfv3(ConfigBase): commands.extend( self._render_list_dict_param(key, w_area, h_area, cmd, opr), ) + elif key == "interface": + commands.extend( + self._render_list_dict_param(key, w_area, h_area, cmd, opr), + ) return commands def _form_attr_cmd(self, key=None, attr=None, val=None, opr=True): diff --git a/plugins/module_utils/network/vyos/facts/ospfv3/ospfv3.py b/plugins/module_utils/network/vyos/facts/ospfv3/ospfv3.py index 547ff793..ae67a4b6 100644 --- a/plugins/module_utils/network/vyos/facts/ospfv3/ospfv3.py +++ b/plugins/module_utils/network/vyos/facts/ospfv3/ospfv3.py @@ -22,6 +22,10 @@ from ansible_collections.ansible.netcommon.plugins.module_utils.network.common i from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.argspec.ospfv3.ospfv3 import ( Ospfv3Args, ) +from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.utils.version import ( + LooseVersion, +) +from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.vyos import get_os_version class Ospfv3Facts(object): @@ -100,6 +104,9 @@ class Ospfv3Facts(object): for item in set(items): i_regex = r" %s .+$" % item cfg = "\n".join(findall(i_regex, conf, M)) + if LooseVersion(get_os_version(self._module)) >= LooseVersion("1.4"): + cfg14 = findall(r"(interface .+) area '%s'$" % item, conf, M) + cfg += "\n " + item + " " + " ".join(cfg14) if attrib == "area": obj = self.parse_area(cfg, item) else: @@ -121,6 +128,8 @@ class Ospfv3Facts(object): rule = self.parse_attrib(conf, "area_id", match=area_id) r_sub = {"range": self.parse_attrib_list(conf, "range", "address")} rule.update(r_sub) + r_int = {"interface": self.parse_attrib_list(conf, "interface", "name")} + rule.update(r_int) return rule def parse_attrib(self, conf, param, match=None): @@ -133,6 +142,7 @@ class Ospfv3Facts(object): "area_id": ["export_list", "import_list"], "redistribute": ["route_map"], "range": ["advertise", "not_advertise"], + "interface": ["name"], "parameters": ["router_id"], } cfg_dict = self.parse_attr(conf, param_lst[param], match) diff --git a/plugins/modules/vyos_ospfv3.py b/plugins/modules/vyos_ospfv3.py index 81b26327..dbe9a857 100644 --- a/plugins/modules/vyos_ospfv3.py +++ b/plugins/modules/vyos_ospfv3.py @@ -68,6 +68,15 @@ options: import_list: description: Name of import-list. type: str + interface: + description: Enable OSPVv3 on an interface for this area. + aliases: ['interfaces'] + type: list + elements: dict + suboptions: + name: + description: Interface name. + type: str range: description: Summarize routes matching prefix (border routers only). type: list diff --git a/tests/integration/targets/vyos_ospf_interfaces/tests/cli/_get_version.yaml b/tests/integration/targets/vyos_ospf_interfaces/tests/cli/_get_version.yaml index a7691499..50b0ec61 100644 --- a/tests/integration/targets/vyos_ospf_interfaces/tests/cli/_get_version.yaml +++ b/tests/integration/targets/vyos_ospf_interfaces/tests/cli/_get_version.yaml @@ -26,6 +26,5 @@ - name: include correct vars include_vars: v1_4.yaml when: vyos_version is version('1.4.0', '>=', version_type='semver') - # - name: include common vars # include_vars: main.yaml diff --git a/tests/unit/modules/network/vyos/test_vyos_ospfv3.py b/tests/unit/modules/network/vyos/test_vyos_ospfv3.py index 1cf02601..bdd93612 100644 --- a/tests/unit/modules/network/vyos/test_vyos_ospfv3.py +++ b/tests/unit/modules/network/vyos/test_vyos_ospfv3.py @@ -60,6 +60,20 @@ class TestVyosOspfv3Module(TestVyosModule): self.execute_show_command = self.mock_execute_show_command.start() + self.mock_get_os_version = patch( + "ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.config.ospfv3.ospfv3.get_os_version", + ) + + self.test_version = "1.3" + self.get_os_version = self.mock_get_os_version.start() + self.get_os_version.return_value = self.test_version + self.mock_facts_get_os_version = patch( + "ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.facts.ospfv3.ospfv3.get_os_version", + ) + self.get_facts_os_version = self.mock_facts_get_os_version.start() + self.get_facts_os_version.return_value = self.test_version + self.maxDiff = None + def tearDown(self): super(TestVyosOspfv3Module, self).tearDown() self.mock_get_resource_connection_config.stop() @@ -94,6 +108,50 @@ class TestVyosOspfv3Module(TestVyosModule): dict(address="2001:db20::/32"), dict(address="2001:db30::/32"), ], + interfaces=[dict(name="eth0")], + ), + dict( + area_id="3", + range=[dict(address="2001:db40::/32")], + ), + ], + ), + state="merged", + ), + ) + commands = [ + "set protocols ospfv3 redistribute bgp", + "set protocols ospfv3 parameters router-id '192.0.2.10'", + "set protocols ospfv3 area 2 range 2001:db10::/32", + "set protocols ospfv3 area 2 range 2001:db20::/32", + "set protocols ospfv3 area 2 range 2001:db30::/32", + "set protocols ospfv3 area '2'", + "set protocols ospfv3 area 2 interface eth0", + "set protocols ospfv3 area 2 export-list export1", + "set protocols ospfv3 area 2 import-list import1", + "set protocols ospfv3 area '3'", + "set protocols ospfv3 area 3 range 2001:db40::/32", + ] + self.execute_module(changed=True, commands=commands) + + def test_vyos_ospfv3_merged_new_config14(self): + self.get_os_version.return_value = "1.4" + set_module_args( + dict( + config=dict( + redistribute=[dict(route_type="bgp")], + parameters=dict(router_id="192.0.2.10"), + areas=[ + dict( + area_id="2", + export_list="export1", + import_list="import1", + range=[ + dict(address="2001:db10::/32"), + dict(address="2001:db20::/32"), + dict(address="2001:db30::/32"), + ], + interfaces=[dict(name="eth0")], ), dict( area_id="3", @@ -111,6 +169,7 @@ class TestVyosOspfv3Module(TestVyosModule): "set protocols ospfv3 area 2 range 2001:db20::/32", "set protocols ospfv3 area 2 range 2001:db30::/32", "set protocols ospfv3 area '2'", + "set protocols ospfv3 interface eth0 area 2", "set protocols ospfv3 area 2 export-list export1", "set protocols ospfv3 area 2 import-list import1", "set protocols ospfv3 area '3'", |