From 9a6bd2f99c91d81391fbff8a32b7b6f3ee3b5e57 Mon Sep 17 00:00:00 2001 From: omnom62 <75066712+omnom62@users.noreply.github.com> Date: Thu, 3 Apr 2025 08:11:36 +1000 Subject: T6831 OSPF VIF (#400) * t6831_ospf_vif init * ospf_vif 1.3 provisioning workflow * changelog * ospf-interface unit tests fix * parser tests * ospf vif parsers updated * added vif unt test cases for ospf_interfaces * ospf vif integration tests * fixing eth names and utils func * ospf vif prep/demolih updates * added new vif test cases --- .../vyos/facts/ospf_interfaces/ospf_interfaces.py | 28 +++-- .../network/vyos/rm_templates/ospf_interfaces.py | 139 ++++++++++++++------- plugins/module_utils/network/vyos/utils/utils.py | 12 ++ 3 files changed, 118 insertions(+), 61 deletions(-) (limited to 'plugins') diff --git a/plugins/module_utils/network/vyos/facts/ospf_interfaces/ospf_interfaces.py b/plugins/module_utils/network/vyos/facts/ospf_interfaces/ospf_interfaces.py index 852e1da7..2160fc71 100644 --- a/plugins/module_utils/network/vyos/facts/ospf_interfaces/ospf_interfaces.py +++ b/plugins/module_utils/network/vyos/facts/ospf_interfaces/ospf_interfaces.py @@ -23,17 +23,16 @@ from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.argspec.osp Ospf_interfacesArgs, ) from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.rm_templates.ospf_interfaces import ( - Ospf_interfacesTemplate + Ospf_interfacesTemplate, ) - from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.rm_templates.ospf_interfaces_14 import ( - Ospf_interfacesTemplate14 + Ospf_interfacesTemplate14, +) +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 -from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.utils.version import LooseVersion - class Ospf_interfacesFacts(object): """The vyos ospf_interfaces facts class""" @@ -54,7 +53,9 @@ class Ospf_interfacesFacts(object): for config_line in data.splitlines(): ospf_int = re.search(r"set protocols (?:ospf|ospfv3) interface (\S+).*", config_line) if ospf_int: - config_dict[ospf_int.group(1)] = config_dict.get(ospf_int.group(1), "") + config_line + "\n" + config_dict[ospf_int.group(1)] = ( + config_dict.get(ospf_int.group(1), "") + config_line + "\n" + ) return list(config_dict.values()) def get_config_set_1_2(self, data): @@ -63,12 +64,15 @@ class Ospf_interfacesFacts(object): config_set = [] int_string = "" for config_line in data.splitlines(): - ospf_int = re.search(r"set interfaces \S+ (\S+) .*", config_line) + ospf_int_raw = re.findall(r"^set interfaces \S+ (\S+)", config_line, re.M) + ospf_int_vif = re.findall(r"^set interfaces \S+ (\S+) vif (\d+)", config_line, re.M) + + ospf_int = ospf_int_raw + ospf_int_vif if ospf_int: - if ospf_int.group(1) not in interface_list: + if ospf_int not in interface_list: if int_string: config_set.append(int_string) - interface_list.append(ospf_int.group(1)) + interface_list.append(ospf_int) int_string = "" int_string = int_string + config_line + "\n" if int_string: @@ -115,7 +119,6 @@ class Ospf_interfacesFacts(object): if key in objs and objs[key]: objs[key] = list(objs[key].values()) ospf_interfaces_facts.append(objs) - ansible_facts["ansible_network_resources"].pop("ospf_interfaces", None) facts = {"ospf_interfaces": []} params = utils.remove_empties( @@ -123,11 +126,10 @@ class Ospf_interfacesFacts(object): self.argument_spec, {"config": ospf_interfaces_facts}, redact=True, - ) + ), ) if params.get("config"): for cfg in params["config"]: facts["ospf_interfaces"].append(utils.remove_empties(cfg)) ansible_facts["ansible_network_resources"].update(facts) - return ansible_facts diff --git a/plugins/module_utils/network/vyos/rm_templates/ospf_interfaces.py b/plugins/module_utils/network/vyos/rm_templates/ospf_interfaces.py index 0d7eaf84..134effca 100644 --- a/plugins/module_utils/network/vyos/rm_templates/ospf_interfaces.py +++ b/plugins/module_utils/network/vyos/rm_templates/ospf_interfaces.py @@ -23,6 +23,7 @@ from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.r from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.utils.utils import ( get_interface_type, + get_interface_with_vif, ) @@ -36,21 +37,23 @@ def _get_parameters(data): def _tmplt_ospf_int_delete(config_data): int_type = get_interface_type(config_data["name"]) + name = get_interface_with_vif(config_data["name"]) params = _get_parameters(config_data["address_family"]) - command = ( - "interfaces " + int_type + " {name} ".format(**config_data) + params[1] + " " + params[0] - ) + command = "interfaces " + int_type + " " + name + " " + params[1] + " " + params[0] return command def _tmplt_ospf_int_cost(config_data): int_type = get_interface_type(config_data["name"]) + name = get_interface_with_vif(config_data["name"]) params = _get_parameters(config_data["address_family"]) command = ( "interfaces " + int_type - + " {name} ".format(**config_data) + + " " + + name + + " " + params[1] + " " + params[0] @@ -62,11 +65,14 @@ def _tmplt_ospf_int_cost(config_data): def _tmplt_ospf_int_auth_password(config_data): int_type = get_interface_type(config_data["name"]) + name = get_interface_with_vif(config_data["name"]) params = _get_parameters(config_data["address_family"]) command = ( "interfaces " + int_type - + " {name} ".format(**config_data) + + " " + + name + + " " + params[1] + " " + params[0] @@ -79,11 +85,14 @@ def _tmplt_ospf_int_auth_password(config_data): def _tmplt_ospf_int_auth_md5(config_data): int_type = get_interface_type(config_data["name"]) + name = get_interface_with_vif(config_data["name"]) params = _get_parameters(config_data["address_family"]) command = ( "interfaces " + int_type - + " {name} ".format(**config_data) + + " " + + name + + " " + params[1] + " " + params[0] @@ -98,11 +107,14 @@ def _tmplt_ospf_int_auth_md5(config_data): def _tmplt_ospf_int_auth_md5_delete(config_data): int_type = get_interface_type(config_data["name"]) + name = get_interface_with_vif(config_data["name"]) params = _get_parameters(config_data["address_family"]) command = ( "interfaces " + int_type - + " {name} ".format(**config_data) + + " " + + name + + " " + params[1] + " " + params[0] @@ -114,11 +126,14 @@ def _tmplt_ospf_int_auth_md5_delete(config_data): def _tmplt_ospf_int_bw(config_data): int_type = get_interface_type(config_data["name"]) + name = get_interface_with_vif(config_data["name"]) params = _get_parameters(config_data["address_family"]) command = ( "interfaces " + int_type - + " {name} ".format(**config_data) + + " " + + name + + " " + params[1] + " " + params[0] @@ -130,11 +145,14 @@ def _tmplt_ospf_int_bw(config_data): def _tmplt_ospf_int_hello_interval(config_data): int_type = get_interface_type(config_data["name"]) + name = get_interface_with_vif(config_data["name"]) params = _get_parameters(config_data["address_family"]) command = ( "interfaces " + int_type - + " {name} ".format(**config_data) + + " " + + name + + " " + params[1] + " " + params[0] @@ -146,11 +164,14 @@ def _tmplt_ospf_int_hello_interval(config_data): def _tmplt_ospf_int_dead_interval(config_data): int_type = get_interface_type(config_data["name"]) + name = get_interface_with_vif(config_data["name"]) params = _get_parameters(config_data["address_family"]) command = ( "interfaces " + int_type - + " {name} ".format(**config_data) + + " " + + name + + " " + params[1] + " " + params[0] @@ -162,15 +183,10 @@ def _tmplt_ospf_int_dead_interval(config_data): def _tmplt_ospf_int_mtu_ignore(config_data): int_type = get_interface_type(config_data["name"]) + name = get_interface_with_vif(config_data["name"]) params = _get_parameters(config_data["address_family"]) command = ( - "interfaces " - + int_type - + " {name} ".format(**config_data) - + params[1] - + " " - + params[0] - + " mtu-ignore" + "interfaces " + int_type + " " + name + " " + params[1] + " " + params[0] + " mtu-ignore" ) return command @@ -178,11 +194,14 @@ def _tmplt_ospf_int_mtu_ignore(config_data): def _tmplt_ospf_int_network(config_data): int_type = get_interface_type(config_data["name"]) + name = get_interface_with_vif(config_data["name"]) params = _get_parameters(config_data["address_family"]) command = ( "interfaces " + int_type - + " {name} ".format(**config_data) + + " " + + name + + " " + params[1] + " " + params[0] @@ -194,11 +213,14 @@ def _tmplt_ospf_int_network(config_data): def _tmplt_ospf_int_priority(config_data): int_type = get_interface_type(config_data["name"]) + name = get_interface_with_vif(config_data["name"]) params = _get_parameters(config_data["address_family"]) command = ( "interfaces " + int_type - + " {name} ".format(**config_data) + + " " + + name + + " " + params[1] + " " + params[0] @@ -210,11 +232,14 @@ def _tmplt_ospf_int_priority(config_data): def _tmplt_ospf_int_retransmit_interval(config_data): int_type = get_interface_type(config_data["name"]) + name = get_interface_with_vif(config_data["name"]) params = _get_parameters(config_data["address_family"]) command = ( "interfaces " + int_type - + " {name} ".format(**config_data) + + " " + + name + + " " + params[1] + " " + params[0] @@ -226,11 +251,14 @@ def _tmplt_ospf_int_retransmit_interval(config_data): def _tmplt_ospf_int_transmit_delay(config_data): int_type = get_interface_type(config_data["name"]) + name = get_interface_with_vif(config_data["name"]) params = _get_parameters(config_data["address_family"]) command = ( "interfaces " + int_type - + " {name} ".format(**config_data) + + " " + + name + + " " + params[1] + " " + params[0] @@ -242,11 +270,14 @@ def _tmplt_ospf_int_transmit_delay(config_data): def _tmplt_ospf_int_ifmtu(config_data): int_type = get_interface_type(config_data["name"]) + name = get_interface_with_vif(config_data["name"]) params = _get_parameters(config_data["address_family"]) command = ( "interfaces " + int_type - + " {name} ".format(**config_data) + + " " + + name + + " " + params[1] + " " + params[0] @@ -258,11 +289,14 @@ def _tmplt_ospf_int_ifmtu(config_data): def _tmplt_ospf_int_instance(config_data): int_type = get_interface_type(config_data["name"]) + name = get_interface_with_vif(config_data["name"]) params = _get_parameters(config_data["address_family"]) command = ( "interfaces " + int_type - + " {name} ".format(**config_data) + + " " + + name + + " " + params[1] + " " + params[0] @@ -274,16 +308,9 @@ def _tmplt_ospf_int_instance(config_data): def _tmplt_ospf_int_passive(config_data): int_type = get_interface_type(config_data["name"]) + name = get_interface_with_vif(config_data["name"]) params = _get_parameters(config_data["address_family"]) - command = ( - "interfaces " - + int_type - + " {name} ".format(**config_data) - + params[1] - + " " - + params[0] - + " passive" - ) + command = "interfaces " + int_type + " " + name + " " + params[1] + " " + params[0] + " passive" return command @@ -308,6 +335,7 @@ class Ospf_interfacesTemplate(NetworkTemplate): \s+interfaces \s+(?P\S+) \s+(?P\S+) + (?:\s+vif\s+(?P\d+))? \s+(?Pip|ipv6) \s+(?Pospf|ospfv3) *$""", @@ -316,7 +344,7 @@ class Ospf_interfacesTemplate(NetworkTemplate): "remval": _tmplt_ospf_int_delete, "compval": "address_family", "result": { - "name": "{{ name }}", + "name": "{{ name + '.' + vif if vif is defined else name }}", "address_family": { "{{ afi }}": { "afi": '{{ "ipv4" if afi == "ip" else "ipv6" }}', @@ -332,6 +360,7 @@ class Ospf_interfacesTemplate(NetworkTemplate): \s+interfaces \s+(?P\S+) \s+(?P\S+) + (?:\s+vif\s+(?P\d+))? \s+(?Pip|ipv6) \s+(?Pospf|ospfv3) \s+authentication @@ -343,7 +372,7 @@ class Ospf_interfacesTemplate(NetworkTemplate): "setval": _tmplt_ospf_int_auth_password, "compval": "address_family.authentication", "result": { - "name": "{{ name }}", + "name": "{{ name + '.' + vif if vif is defined else name }}", "address_family": { "{{ afi }}": { "afi": '{{ "ipv4" if afi == "ip" else "ipv6" }}', @@ -362,6 +391,7 @@ class Ospf_interfacesTemplate(NetworkTemplate): \s+interfaces \s+(?P\S+) \s+(?P\S+) + (?:\s+vif\s+(?P\d+))? \s+(?Pip|ipv6) \s+(?Pospf|ospfv3) \s+authentication @@ -377,7 +407,7 @@ class Ospf_interfacesTemplate(NetworkTemplate): "remval": _tmplt_ospf_int_auth_md5_delete, "compval": "address_family.authentication", "result": { - "name": "{{ name }}", + "name": "{{ name + '.' + vif if vif is defined else name }}", "address_family": { "{{ afi }}": { "afi": '{{ "ipv4" if afi == "ip" else "ipv6" }}', @@ -399,6 +429,7 @@ class Ospf_interfacesTemplate(NetworkTemplate): \s+interfaces \s+(?P\S+) \s+(?P\S+) + (?:\s+vif\s+(?P\d+))? \s+(?Pip|ipv6) \s+(?Pospf|ospfv3) \s+bandwidth @@ -409,7 +440,7 @@ class Ospf_interfacesTemplate(NetworkTemplate): "setval": _tmplt_ospf_int_bw, "compval": "address_family.bandwidth", "result": { - "name": "{{ name }}", + "name": "{{ name + '.' + vif if vif is defined else name }}", "address_family": { "{{ afi }}": { "afi": '{{ "ipv4" if afi == "ip" else "ipv6" }}', @@ -426,6 +457,7 @@ class Ospf_interfacesTemplate(NetworkTemplate): \s+interfaces \s+(?P\S+) \s+(?P\S+) + (?:\s+vif\s+(?P\d+))? \s+(?Pip|ipv6) \s+(?Pospf|ospfv3) \s+cost @@ -436,7 +468,7 @@ class Ospf_interfacesTemplate(NetworkTemplate): "setval": _tmplt_ospf_int_cost, "compval": "address_family.cost", "result": { - "name": "{{ name }}", + "name": "{{ name + '.' + vif if vif is defined else name }}", "address_family": { "{{ afi }}": { "afi": '{{ "ipv4" if afi == "ip" else "ipv6" }}', @@ -453,6 +485,7 @@ class Ospf_interfacesTemplate(NetworkTemplate): \s+interfaces \s+(?P\S+) \s+(?P\S+) + (?:\s+vif\s+(?P\d+))? \s+(?Pip|ipv6) \s+(?Pospf|ospfv3) \s+hello-interval @@ -463,7 +496,7 @@ class Ospf_interfacesTemplate(NetworkTemplate): "setval": _tmplt_ospf_int_hello_interval, "compval": "address_family.hello_interval", "result": { - "name": "{{ name }}", + "name": "{{ name + '.' + vif if vif is defined else name }}", "address_family": { "{{ afi }}": { "afi": '{{ "ipv4" if afi == "ip" else "ipv6" }}', @@ -480,6 +513,7 @@ class Ospf_interfacesTemplate(NetworkTemplate): \s+interfaces \s+(?P\S+) \s+(?P\S+) + (?:\s+vif\s+(?P\d+))? \s+(?Pip|ipv6) \s+(?Pospf|ospfv3) \s+dead-interval @@ -490,7 +524,7 @@ class Ospf_interfacesTemplate(NetworkTemplate): "setval": _tmplt_ospf_int_dead_interval, "compval": "address_family.dead_interval", "result": { - "name": "{{ name }}", + "name": "{{ name + '.' + vif if vif is defined else name }}", "address_family": { "{{ afi }}": { "afi": '{{ "ipv4" if afi == "ip" else "ipv6" }}', @@ -507,6 +541,7 @@ class Ospf_interfacesTemplate(NetworkTemplate): \s+interfaces \s+(?P\S+) \s+(?P\S+) + (?:\s+vif\s+(?P\d+))? \s+(?Pip|ipv6) \s+(?Pospf|ospfv3) \s+(?Pmtu-ignore) @@ -516,7 +551,7 @@ class Ospf_interfacesTemplate(NetworkTemplate): "setval": _tmplt_ospf_int_mtu_ignore, "compval": "address_family.mtu_ignore", "result": { - "name": "{{ name }}", + "name": "{{ name + '.' + vif if vif is defined else name }}", "address_family": { "{{ afi }}": { "afi": '{{ "ipv4" if afi == "ip" else "ipv6" }}', @@ -533,6 +568,7 @@ class Ospf_interfacesTemplate(NetworkTemplate): \s+interfaces \s+(?P\S+) \s+(?P\S+) + (?:\s+vif\s+(?P\d+))? \s+(?Pip|ipv6) \s+(?Pospf|ospfv3) \s+network @@ -543,7 +579,7 @@ class Ospf_interfacesTemplate(NetworkTemplate): "setval": _tmplt_ospf_int_network, "compval": "address_family.network", "result": { - "name": "{{ name }}", + "name": "{{ name + '.' + vif if vif is defined else name }}", "address_family": { "{{ afi }}": { "afi": '{{ "ipv4" if afi == "ip" else "ipv6" }}', @@ -560,6 +596,7 @@ class Ospf_interfacesTemplate(NetworkTemplate): \s+interfaces \s+(?P\S+) \s+(?P\S+) + (?:\s+vif\s+(?P\d+))? \s+(?Pip|ipv6) \s+(?Pospf|ospfv3) \s+priority @@ -570,7 +607,7 @@ class Ospf_interfacesTemplate(NetworkTemplate): "setval": _tmplt_ospf_int_priority, "compval": "address_family.priority", "result": { - "name": "{{ name }}", + "name": "{{ name + '.' + vif if vif is defined else name }}", "address_family": { "{{ afi }}": { "afi": '{{ "ipv4" if afi == "ip" else "ipv6" }}', @@ -587,6 +624,7 @@ class Ospf_interfacesTemplate(NetworkTemplate): \s+interfaces \s+(?P\S+) \s+(?P\S+) + (?:\s+vif\s+(?P\d+))? \s+(?Pip|ipv6) \s+(?Pospf|ospfv3) \s+retransmit-interval @@ -597,7 +635,7 @@ class Ospf_interfacesTemplate(NetworkTemplate): "setval": _tmplt_ospf_int_retransmit_interval, "compval": "address_family.retransmit_interval", "result": { - "name": "{{ name }}", + "name": "{{ name + '.' + vif if vif is defined else name }}", "address_family": { "{{ afi }}": { "afi": '{{ "ipv4" if afi == "ip" else "ipv6" }}', @@ -614,6 +652,7 @@ class Ospf_interfacesTemplate(NetworkTemplate): \s+interfaces \s+(?P\S+) \s+(?P\S+) + (?:\s+vif\s+(?P\d+))? \s+(?Pip|ipv6) \s+(?Pospf|ospfv3) \s+transmit-delay @@ -624,7 +663,7 @@ class Ospf_interfacesTemplate(NetworkTemplate): "setval": _tmplt_ospf_int_transmit_delay, "compval": "address_family.transmit_delay", "result": { - "name": "{{ name }}", + "name": "{{ name + '.' + vif if vif is defined else name }}", "address_family": { "{{ afi }}": { "afi": '{{ "ipv4" if afi == "ip" else "ipv6" }}', @@ -641,6 +680,7 @@ class Ospf_interfacesTemplate(NetworkTemplate): \s+interfaces \s+(?P\S+) \s+(?P\S+) + (?:\s+vif\s+(?P\d+))? \s+(?Pip|ipv6) \s+(?Pospf|ospfv3) \s+ifmtu @@ -651,7 +691,7 @@ class Ospf_interfacesTemplate(NetworkTemplate): "setval": _tmplt_ospf_int_ifmtu, "compval": "address_family.ifmtu", "result": { - "name": "{{ name }}", + "name": "{{ name + '.' + vif if vif is defined else name }}", "address_family": { "{{ afi }}": { "afi": '{{ "ipv4" if afi == "ip" else "ipv6" }}', @@ -668,6 +708,7 @@ class Ospf_interfacesTemplate(NetworkTemplate): \s+interfaces \s+(?P\S+) \s+(?P\S+) + (?:\s+vif\s+(?P\d+))? \s+(?Pip|ipv6) \s+(?Pospf|ospfv3) \s+instance-id @@ -678,7 +719,7 @@ class Ospf_interfacesTemplate(NetworkTemplate): "setval": _tmplt_ospf_int_instance, "compval": "address_family.instance", "result": { - "name": "{{ name }}", + "name": "{{ name + '.' + vif if vif is defined else name }}", "address_family": { "{{ afi }}": { "afi": '{{ "ipv4" if afi == "ip" else "ipv6" }}', @@ -695,6 +736,7 @@ class Ospf_interfacesTemplate(NetworkTemplate): \s+interfaces \s+(?P\S+) \s+(?P\S+) + (?:\s+vif\s+(?P\d+))? \s+(?Pip|ipv6) \s+(?Pospf|ospfv3) \s+(?Ppassive) @@ -704,7 +746,7 @@ class Ospf_interfacesTemplate(NetworkTemplate): "setval": _tmplt_ospf_int_passive, "compval": "address_family.passive", "result": { - "name": "{{ name }}", + "name": "{{ name + '.' + vif if vif is defined else name }}", "address_family": { "{{ afi }}": { "afi": '{{ "ipv4" if afi == "ip" else "ipv6" }}', @@ -721,12 +763,13 @@ class Ospf_interfacesTemplate(NetworkTemplate): \s+interfaces \s+(?P\S+) \s+(?P\S+) + (?:\s+vif\s+(?P\d+))? .*$""", re.VERBOSE, ), "setval": "set interface {{ type }} {{ name }}", "result": { - "name": "{{ name }}", + "name": "{{ name + '.' + vif if vif is defined else name }}", }, }, ] diff --git a/plugins/module_utils/network/vyos/utils/utils.py b/plugins/module_utils/network/vyos/utils/utils.py index 8722251e..a6b03c80 100644 --- a/plugins/module_utils/network/vyos/utils/utils.py +++ b/plugins/module_utils/network/vyos/utils/utils.py @@ -50,6 +50,18 @@ def get_interface_type(interface): return "dummy" +def get_interface_with_vif(interface): + """Gets virtual interface if any or return as is""" + vlan = None + interface_real = interface + if "." in interface: + interface_real, vlan = interface.split(".") + + if vlan is not None: + interface_real = interface_real + " vif " + vlan + return interface_real + + def dict_delete(base, comparable): """ This function generates a dict containing key, value pairs for keys -- cgit v1.2.3