diff options
author | GomathiselviS <gomathiselvi@gmail.com> | 2020-10-30 20:21:45 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-10-31 00:21:45 +0000 |
commit | de18ed01ddd7ac1db3bbde83a156624a972a43ae (patch) | |
tree | 6cf49ffa7c500d0ec0ff147326c5e079a7e570ab /plugins/module_utils/network | |
parent | f5e6f4e2111890012b4bce4ce5096912e2eb3094 (diff) | |
download | vyos-ansible-collection-de18ed01ddd7ac1db3bbde83a156624a972a43ae.tar.gz vyos-ansible-collection-de18ed01ddd7ac1db3bbde83a156624a972a43ae.zip |
Add ospf_interfaces resource module (#96)
Add ospf_interfaces resource module
Reviewed-by: https://github.com/apps/ansible-zuul
Diffstat (limited to 'plugins/module_utils/network')
10 files changed, 1109 insertions, 0 deletions
diff --git a/plugins/module_utils/network/__init__.py b/plugins/module_utils/network/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/plugins/module_utils/network/__init__.py diff --git a/plugins/module_utils/network/vyos/argspec/ospf_interfaces/__init__.py b/plugins/module_utils/network/vyos/argspec/ospf_interfaces/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/plugins/module_utils/network/vyos/argspec/ospf_interfaces/__init__.py diff --git a/plugins/module_utils/network/vyos/argspec/ospf_interfaces/ospf_interfaces.py b/plugins/module_utils/network/vyos/argspec/ospf_interfaces/ospf_interfaces.py new file mode 100644 index 0000000..e7dd10c --- /dev/null +++ b/plugins/module_utils/network/vyos/argspec/ospf_interfaces/ospf_interfaces.py @@ -0,0 +1,97 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 Red Hat +# GNU General Public License v3.0+ +# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function + +__metaclass__ = type + +############################################# +# WARNING # +############################################# +# +# This file is auto generated by the resource +# module builder playbook. +# +# Do not edit this file manually. +# +# Changes to this file will be over written +# by the resource module builder. +# +# Changes should be made in the model used to +# generate this file or in the resource module +# builder template. +# +############################################# + +""" +The arg spec for the vyos_ospf_interfaces module +""" + + +class Ospf_interfacesArgs(object): # pylint: disable=R0903 + """The arg spec for the vyos_ospf_interfaces module""" + + def __init__(self, **kwargs): + pass + + argument_spec = { + "running_config": {}, + "state": { + "default": "merged", + "type": "str", + "choices": [ + "merged", + "replaced", + "overridden", + "deleted", + "gathered", + "parsed", + "rendered", + ], + }, + "config": { + "elements": "dict", + "type": "list", + "options": { + "name": {"type": "str"}, + "address_family": { + "elements": "dict", + "type": "list", + "options": { + "passive": {"type": "bool"}, + "retransmit_interval": {"type": "int"}, + "cost": {"type": "int"}, + "afi": { + "required": True, + "type": "str", + "choices": ["ipv4", "ipv6"], + }, + "authentication": { + "type": "dict", + "options": { + "plaintext_password": {"type": "str"}, + "md5_key": { + "type": "dict", + "options": { + "key_id": {"type": "int"}, + "key": {"type": "str"}, + }, + }, + }, + }, + "mtu_ignore": {"type": "bool"}, + "priority": {"type": "int"}, + "instance": {"type": "str"}, + "bandwidth": {"type": "int"}, + "dead_interval": {"type": "int"}, + "ifmtu": {"type": "int"}, + "hello_interval": {"type": "int"}, + "transmit_delay": {"type": "int"}, + "network": {"type": "str"}, + }, + }, + }, + }, + } # pylint: disable=C0301 diff --git a/plugins/module_utils/network/vyos/config/ospf_interfaces/__init__.py b/plugins/module_utils/network/vyos/config/ospf_interfaces/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/plugins/module_utils/network/vyos/config/ospf_interfaces/__init__.py diff --git a/plugins/module_utils/network/vyos/config/ospf_interfaces/ospf_interfaces.py b/plugins/module_utils/network/vyos/config/ospf_interfaces/ospf_interfaces.py new file mode 100644 index 0000000..d01b1e0 --- /dev/null +++ b/plugins/module_utils/network/vyos/config/ospf_interfaces/ospf_interfaces.py @@ -0,0 +1,164 @@ +# +# -*- coding: utf-8 -*- +# Copyright 2020 Red Hat +# GNU General Public License v3.0+ +# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) +# + +from __future__ import absolute_import, division, print_function + +__metaclass__ = type +""" +The vyos_ospf_interfaces config file. +It is in this file where the current configuration (as dict) +is compared to the provided configuration (as dict) and the command set +necessary to bring the current configuration to its desired end-state is +created. +""" + +from ansible.module_utils.six import iteritems +from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.utils import ( + dict_merge, +) +from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.resource_module import ( + ResourceModule, +) +from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.facts.facts import ( + Facts, +) +from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.rm_templates.ospf_interfaces import ( + Ospf_interfacesTemplate, +) + + +class Ospf_interfaces(ResourceModule): + """ + The vyos_ospf_interfaces config class + """ + + def __init__(self, module): + super(Ospf_interfaces, self).__init__( + empty_fact_val={}, + facts_module=Facts(module), + module=module, + resource="ospf_interfaces", + tmplt=Ospf_interfacesTemplate(), + ) + self.parsers = [ + "authentication_password", + "authentication_md5", + "bandwidth", + "cost", + "hello_interval", + "dead_interval", + "mtu_ignore", + "network", + "priority", + "retransmit_interval", + "transmit_delay", + "ifmtu", + "instance", + "passive", + ] + + def execute_module(self): + """Execute the module + + :rtype: A dictionary + :returns: The result from module execution + """ + if self.state not in ["parsed", "gathered"]: + self.generate_commands() + self.run_commands() + return self.result + + def generate_commands(self): + """Generate configuration commands to send based on + want, have and desired state. + """ + wantd = {entry["name"]: entry for entry in self.want} + haved = {entry["name"]: entry for entry in self.have} + + # turn all lists of dicts into dicts prior to merge + for entry in wantd, haved: + self._ospf_int_list_to_dict(entry) + # if state is merged, merge want onto have and then compare + if self.state == "merged": + wantd = dict_merge(haved, wantd) + + # if state is deleted, empty out wantd and set haved to wantd + if self.state == "deleted": + haved = { + k: v for k, v in iteritems(haved) if k in wantd or not wantd + } + have_int = [] + for k, have in iteritems(haved): + if k in wantd: + have_int.append(k) + self._remove_ospf_int(have) + wantd = {} + + if self.state == "overridden": + have_int = [] + for k, have in iteritems(haved): + if k not in wantd: + have_int.append(k) + self._remove_ospf_int(have) + + # remove superfluous config for overridden and deleted + if self.state in ["overridden", "deleted"]: + # removing the interfaces from haved that are already negated + for interface in have_int: + haved.pop(interface) + for k, have in iteritems(haved): + if k not in wantd: + self._compare(want={}, have=have) + + for k, want in iteritems(wantd): + self._compare(want=want, have=haved.pop(k, {})) + + def _remove_ospf_int(self, entry): + int_name = entry.get("name", {}) + int_addr = entry.get("address_family", {}) + for k, addr in iteritems(int_addr): + rem_entry = {"name": int_name, "address_family": {"afi": k}} + self.addcmd(rem_entry, "ip_ospf", True) + + def _compare(self, want, have): + """Leverages the base class `compare()` method and + populates the list of commands to be run by comparing + the `want` and `have` data with the `parsers` defined + for the Ospf_interfaces network resource. + """ + self._compare_addr_family(want=want, have=have) + + def _compare_addr_family(self, want, have): + wdict = want.get("address_family", {}) + hdict = have.get("address_family", {}) + wname = want.get("name") + hname = have.get("name") + for name, entry in iteritems(wdict): + for key, param in iteritems(entry): + w_addr = {"afi": name, key: param} + h_addr = {} + if hdict.get(name): + h_addr = {"afi": name, key: hdict[name].pop(key, {})} + w = {"name": wname, "address_family": w_addr} + h = {"name": hname, "address_family": h_addr} + self.compare(parsers=self.parsers, want=w, have=h) + for name, entry in iteritems(hdict): + for key, param in iteritems(entry): + h_addr = {"afi": name, key: param} + w_addr = {} + w = {"name": wname, "address_family": w_addr} + h = {"name": hname, "address_family": h_addr} + self.compare(parsers=self.parsers, want=w, have=h) + + def _ospf_int_list_to_dict(self, entry): + for name, family in iteritems(entry): + if "address_family" in family: + family["address_family"] = { + entry["afi"]: entry + for entry in family.get("address_family", []) + } + self._ospf_int_list_to_dict(family["address_family"]) diff --git a/plugins/module_utils/network/vyos/facts/facts.py b/plugins/module_utils/network/vyos/facts/facts.py index caea5fe..c2766de 100644 --- a/plugins/module_utils/network/vyos/facts/facts.py +++ b/plugins/module_utils/network/vyos/facts/facts.py @@ -46,6 +46,9 @@ from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.facts.ospfv from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.facts.ospfv2.ospfv2 import ( Ospfv2Facts, ) +from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.facts.ospf_interfaces.ospf_interfaces import ( + Ospf_interfacesFacts, +) from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.facts.legacy.base import ( Default, Neighbors, @@ -66,6 +69,7 @@ FACT_RESOURCE_SUBSETS = dict( firewall_interfaces=Firewall_interfacesFacts, ospfv3=Ospfv3Facts, ospfv2=Ospfv2Facts, + ospf_interfaces=Ospf_interfacesFacts, ) diff --git a/plugins/module_utils/network/vyos/facts/ospf_interfaces/__init__.py b/plugins/module_utils/network/vyos/facts/ospf_interfaces/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/plugins/module_utils/network/vyos/facts/ospf_interfaces/__init__.py 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 new file mode 100644 index 0000000..15ac92a --- /dev/null +++ b/plugins/module_utils/network/vyos/facts/ospf_interfaces/ospf_interfaces.py @@ -0,0 +1,101 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 Red Hat +# GNU General Public License v3.0+ +# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function + +__metaclass__ = type + +""" +The vyos ospf_interfaces fact class +It is in this file the configuration is collected from the device +for a given resource, parsed, and the facts tree is populated +based on the configuration. +""" + +import re + +from ansible_collections.ansible.netcommon.plugins.module_utils.network.common import ( + utils, +) +from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.rm_templates.ospf_interfaces import ( + Ospf_interfacesTemplate, +) +from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.argspec.ospf_interfaces.ospf_interfaces import ( + Ospf_interfacesArgs, +) + + +class Ospf_interfacesFacts(object): + """The vyos ospf_interfaces facts class""" + + def __init__(self, module, subspec="config", options="options"): + self._module = module + self.argument_spec = Ospf_interfacesArgs.argument_spec + + def get_device_data(self, connection): + return connection.get( + 'show configuration commands | match "set interfaces"' + ) + + def get_config_set(self, data): + """ To classify the configurations beased on interface """ + interface_list = [] + config_set = [] + int_string = "" + for config_line in data.splitlines(): + ospf_int = re.search(r"set interfaces \S+ (\S+) .*", config_line) + if ospf_int: + if ospf_int.group(1) not in interface_list: + if int_string: + config_set.append(int_string) + interface_list.append(ospf_int.group(1)) + int_string = "" + int_string = int_string + config_line + "\n" + if int_string: + config_set.append(int_string) + return config_set + + def populate_facts(self, connection, ansible_facts, data=None): + """Populate the facts for Ospf_interfaces network resource + + :param connection: the device connection + :param ansible_facts: Facts dictionary + :param data: previously collected conf + + :rtype: dictionary + :returns: facts + """ + facts = {} + objs = [] + + if not data: + data = self.get_device_data(connection) + + # parse native config using the Ospf_interfaces template + ospf_interfaces_facts = [] + resources = self.get_config_set(data) + for resource in resources: + ospf_interfaces_parser = Ospf_interfacesTemplate( + lines=resource.split("\n") + ) + objs = ospf_interfaces_parser.parse() + for key, sortv in [("address_family", "afi")]: + 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( + utils.validate_config( + self.argument_spec, {"config": ospf_interfaces_facts} + ) + ) + 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/__init__.py b/plugins/module_utils/network/vyos/rm_templates/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/plugins/module_utils/network/vyos/rm_templates/__init__.py diff --git a/plugins/module_utils/network/vyos/rm_templates/ospf_interfaces.py b/plugins/module_utils/network/vyos/rm_templates/ospf_interfaces.py new file mode 100644 index 0000000..460e6b0 --- /dev/null +++ b/plugins/module_utils/network/vyos/rm_templates/ospf_interfaces.py @@ -0,0 +1,743 @@ +# -*- coding: utf-8 -*- +# Copyright 2020 Red Hat +# GNU General Public License v3.0+ +# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function + +__metaclass__ = type + +""" +The Ospf_interfaces parser templates file. This contains +a list of parser definitions and associated functions that +facilitates both facts gathering and native command generation for +the given network resource. +""" + +import re +from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.network_template import ( + NetworkTemplate, +) + +from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.utils.utils import ( + get_interface_type, +) + + +def _get_parameters(data): + if data["afi"] == "ipv6": + val = ["ospfv3", "ipv6"] + else: + val = ["ospf", "ip"] + return val + + +def _tmplt_ospf_int_delete(config_data): + int_type = get_interface_type(config_data["name"]) + params = _get_parameters(config_data["address_family"]) + command = ( + "interfaces " + + int_type + + " {name} ".format(**config_data) + + params[1] + + " " + + params[0] + ) + + return command + + +def _tmplt_ospf_int_cost(config_data): + int_type = get_interface_type(config_data["name"]) + params = _get_parameters(config_data["address_family"]) + command = ( + "interfaces " + + int_type + + " {name} ".format(**config_data) + + params[1] + + " " + + params[0] + + " cost {cost}".format(**config_data["address_family"]) + ) + + return command + + +def _tmplt_ospf_int_auth_password(config_data): + int_type = get_interface_type(config_data["name"]) + params = _get_parameters(config_data["address_family"]) + command = ( + "interfaces " + + int_type + + " {name} ".format(**config_data) + + params[1] + + " " + + params[0] + + " authentication plaintext-password {plaintext_password}".format( + **config_data["address_family"]["authentication"] + ) + ) + return command + + +def _tmplt_ospf_int_auth_md5(config_data): + int_type = get_interface_type(config_data["name"]) + params = _get_parameters(config_data["address_family"]) + command = ( + "interfaces " + + int_type + + " {name} ".format(**config_data) + + params[1] + + " " + + params[0] + + " authentication md5 key-id {key_id} ".format( + **config_data["address_family"]["authentication"]["md5_key"] + ) + + "md5-key {key}".format( + **config_data["address_family"]["authentication"]["md5_key"] + ) + ) + + return command + + +def _tmplt_ospf_int_auth_md5_delete(config_data): + int_type = get_interface_type(config_data["name"]) + params = _get_parameters(config_data["address_family"]) + command = ( + "interfaces " + + int_type + + " {name} ".format(**config_data) + + params[1] + + " " + + params[0] + + " authentication" + ) + + return command + + +def _tmplt_ospf_int_bw(config_data): + int_type = get_interface_type(config_data["name"]) + params = _get_parameters(config_data["address_family"]) + command = ( + "interfaces " + + int_type + + " {name} ".format(**config_data) + + params[1] + + " " + + params[0] + + " bandwidth {bandwidth}".format(**config_data["address_family"]) + ) + + return command + + +def _tmplt_ospf_int_hello_interval(config_data): + int_type = get_interface_type(config_data["name"]) + params = _get_parameters(config_data["address_family"]) + command = ( + "interfaces " + + int_type + + " {name} ".format(**config_data) + + params[1] + + " " + + params[0] + + " hello-interval {hello_interval}".format( + **config_data["address_family"] + ) + ) + + return command + + +def _tmplt_ospf_int_dead_interval(config_data): + int_type = get_interface_type(config_data["name"]) + params = _get_parameters(config_data["address_family"]) + command = ( + "interfaces " + + int_type + + " {name} ".format(**config_data) + + params[1] + + " " + + params[0] + + " dead-interval {dead_interval}".format( + **config_data["address_family"] + ) + ) + + return command + + +def _tmplt_ospf_int_mtu_ignore(config_data): + int_type = get_interface_type(config_data["name"]) + params = _get_parameters(config_data["address_family"]) + command = ( + "interfaces " + + int_type + + " {name} ".format(**config_data) + + params[1] + + " " + + params[0] + + " mtu-ignore" + ) + + return command + + +def _tmplt_ospf_int_network(config_data): + int_type = get_interface_type(config_data["name"]) + params = _get_parameters(config_data["address_family"]) + command = ( + "interfaces " + + int_type + + " {name} ".format(**config_data) + + params[1] + + " " + + params[0] + + " network {network}".format(**config_data["address_family"]) + ) + + return command + + +def _tmplt_ospf_int_priority(config_data): + int_type = get_interface_type(config_data["name"]) + params = _get_parameters(config_data["address_family"]) + command = ( + "interfaces " + + int_type + + " {name} ".format(**config_data) + + params[1] + + " " + + params[0] + + " priority {priority}".format(**config_data["address_family"]) + ) + + return command + + +def _tmplt_ospf_int_retransmit_interval(config_data): + int_type = get_interface_type(config_data["name"]) + params = _get_parameters(config_data["address_family"]) + command = ( + "interfaces " + + int_type + + " {name} ".format(**config_data) + + params[1] + + " " + + params[0] + + " retransmit-interval {retransmit_interval}".format( + **config_data["address_family"] + ) + ) + + return command + + +def _tmplt_ospf_int_transmit_delay(config_data): + int_type = get_interface_type(config_data["name"]) + params = _get_parameters(config_data["address_family"]) + command = ( + "interfaces " + + int_type + + " {name} ".format(**config_data) + + params[1] + + " " + + params[0] + + " transmit-delay {transmit_delay}".format( + **config_data["address_family"] + ) + ) + + return command + + +def _tmplt_ospf_int_ifmtu(config_data): + int_type = get_interface_type(config_data["name"]) + params = _get_parameters(config_data["address_family"]) + command = ( + "interfaces " + + int_type + + " {name} ".format(**config_data) + + params[1] + + " " + + params[0] + + " ifmtu {ifmtu}".format(**config_data["address_family"]) + ) + + return command + + +def _tmplt_ospf_int_instance(config_data): + int_type = get_interface_type(config_data["name"]) + params = _get_parameters(config_data["address_family"]) + command = ( + "interfaces " + + int_type + + " {name} ".format(**config_data) + + params[1] + + " " + + params[0] + + " instance-id {instance}".format(**config_data["address_family"]) + ) + + return command + + +def _tmplt_ospf_int_passive(config_data): + int_type = get_interface_type(config_data["name"]) + params = _get_parameters(config_data["address_family"]) + command = ( + "interfaces " + + int_type + + " {name} ".format(**config_data) + + params[1] + + " " + + params[0] + + " passive" + ) + + return command + + +class Ospf_interfacesTemplate(NetworkTemplate): + def __init__(self, lines=None): + prefix = {"set": "set", "remove": "delete"} + super(Ospf_interfacesTemplate, self).__init__( + lines=lines, tmplt=self, prefix=prefix + ) + + # fmt: off + PARSERS = [ + { + "name": "ip_ospf", + "getval": re.compile( + r""" + ^set + \s+interfaces + \s+(?P<type>\S+) + \s+(?P<name>\S+) + \s+(?P<afi>ip|ipv6) + \s+(?P<proto>ospf|ospfv3) + *$""", + re.VERBOSE, + ), + "remval": _tmplt_ospf_int_delete, + "compval": "address_family", + "result": { + "name": "{{ name }}", + "address_family": { + "{{ afi }}": { + "afi": '{{ "ipv4" if afi == "ip" else "ipv6" }}', + } + } + } + }, + { + "name": "authentication_password", + "getval": re.compile( + r""" + ^set + \s+interfaces + \s+(?P<type>\S+) + \s+(?P<name>\S+) + \s+(?P<afi>ip|ipv6) + \s+(?P<proto>ospf|ospfv3) + \s+authentication + \s+plaintext-password + \s+(?P<text>\S+) + *$""", + re.VERBOSE, + ), + "setval": _tmplt_ospf_int_auth_password, + "compval": "address_family.authentication", + "result": { + "name": "{{ name }}", + "address_family": { + "{{ afi }}": { + "afi": '{{ "ipv4" if afi == "ip" else "ipv6" }}', + "authentication": { + "plaintext_password": "{{ text }}" + } + } + } + } + }, + { + "name": "authentication_md5", + "getval": re.compile( + r""" + ^set + \s+interfaces + \s+(?P<type>\S+) + \s+(?P<name>\S+) + \s+(?P<afi>ip|ipv6) + \s+(?P<proto>ospf|ospfv3) + \s+authentication + \s+md5 + \s+key-id + \s+(?P<id>\d+) + \s+md5-key + \s+(?P<text>\S+) + *$""", + re.VERBOSE, + ), + "setval": _tmplt_ospf_int_auth_md5, + "remval": _tmplt_ospf_int_auth_md5_delete, + "compval": "address_family.authentication", + "result": { + "name": "{{ name }}", + "address_family": { + "{{ afi }}": { + "afi": '{{ "ipv4" if afi == "ip" else "ipv6" }}', + "authentication": { + "md5_key": { + "key_id": "{{ id }}", + "key": "{{ text }}" + } + } + } + } + } + }, + { + "name": "bandwidth", + "getval": re.compile( + r""" + ^set + \s+interfaces + \s+(?P<type>\S+) + \s+(?P<name>\S+) + \s+(?P<afi>ip|ipv6) + \s+(?P<proto>ospf|ospfv3) + \s+bandwidth + \s+(?P<bw>\'\d+\') + *$""", + re.VERBOSE, + ), + "setval": _tmplt_ospf_int_bw, + "compval": "address_family.bandwidth", + "result": { + "name": "{{ name }}", + "address_family": { + "{{ afi }}": { + "afi": '{{ "ipv4" if afi == "ip" else "ipv6" }}', + "bandwidth": "{{ bw }}" + } + } + } + }, + { + "name": "cost", + "getval": re.compile( + r""" + ^set + \s+interfaces + \s+(?P<type>\S+) + \s+(?P<name>\S+) + \s+(?P<afi>ip|ipv6) + \s+(?P<proto>ospf|ospfv3) + \s+cost + \s+(?P<val>\'\d+\') + *$""", + re.VERBOSE, + ), + "setval": _tmplt_ospf_int_cost, + "compval": "address_family.cost", + "result": { + "name": "{{ name }}", + "address_family": { + "{{ afi }}": { + "afi": '{{ "ipv4" if afi == "ip" else "ipv6" }}', + "cost": "{{ val }}" + } + } + } + }, + { + "name": "hello_interval", + "getval": re.compile( + r""" + ^set + \s+interfaces + \s+(?P<type>\S+) + \s+(?P<name>\S+) + \s+(?P<afi>ip|ipv6) + \s+(?P<proto>ospf|ospfv3) + \s+hello-interval + \s+(?P<val>\'\d+\') + *$""", + re.VERBOSE, + ), + "setval": _tmplt_ospf_int_hello_interval, + "compval": "address_family.hello_interval", + "result": { + "name": "{{ name }}", + "address_family": { + "{{ afi }}": { + "afi": '{{ "ipv4" if afi == "ip" else "ipv6" }}', + "hello_interval": "{{ val }}" + } + } + } + }, + { + "name": "dead_interval", + "getval": re.compile( + r""" + ^set + \s+interfaces + \s+(?P<type>\S+) + \s+(?P<name>\S+) + \s+(?P<afi>ip|ipv6) + \s+(?P<proto>ospf|ospfv3) + \s+dead-interval + \s+(?P<val>\'\d+\') + *$""", + re.VERBOSE, + ), + "setval": _tmplt_ospf_int_dead_interval, + "compval": "address_family.dead_interval", + "result": { + "name": "{{ name }}", + "address_family": { + "{{ afi }}": { + "afi": '{{ "ipv4" if afi == "ip" else "ipv6" }}', + "dead_interval": "{{ val }}" + } + } + } + }, + { + "name": "mtu_ignore", + "getval": re.compile( + r""" + ^set + \s+interfaces + \s+(?P<type>\S+) + \s+(?P<name>\S+) + \s+(?P<afi>ip|ipv6) + \s+(?P<proto>ospf|ospfv3) + \s+(?P<mtu>\'mtu-ignore\') + *$""", + re.VERBOSE, + ), + "setval": _tmplt_ospf_int_mtu_ignore, + "compval": "address_family.mtu_ignore", + "result": { + "name": "{{ name }}", + "address_family": { + "{{ afi }}": { + "afi": '{{ "ipv4" if afi == "ip" else "ipv6" }}', + "mtu_ignore": "{{ True if mtu is defined }}" + } + } + } + }, + { + "name": "network", + "getval": re.compile( + r""" + ^set + \s+interfaces + \s+(?P<type>\S+) + \s+(?P<name>\S+) + \s+(?P<afi>ip|ipv6) + \s+(?P<proto>ospf|ospfv3) + \s+network + \s+(?P<val>\S+) + *$""", + re.VERBOSE, + ), + "setval": _tmplt_ospf_int_network, + "compval": "address_family.network", + "result": { + "name": "{{ name }}", + "address_family": { + "{{ afi }}": { + "afi": '{{ "ipv4" if afi == "ip" else "ipv6" }}', + "network": "{{ val }}" + } + } + } + }, + { + "name": "priority", + "getval": re.compile( + r""" + ^set + \s+interfaces + \s+(?P<type>\S+) + \s+(?P<name>\S+) + \s+(?P<afi>ip|ipv6) + \s+(?P<proto>ospf|ospfv3) + \s+priority + \s+(?P<val>\'\d+\') + *$""", + re.VERBOSE, + ), + "setval": _tmplt_ospf_int_priority, + "compval": "address_family.priority", + "result": { + "name": "{{ name }}", + "address_family": { + "{{ afi }}": { + "afi": '{{ "ipv4" if afi == "ip" else "ipv6" }}', + "priority": "{{ val }}" + } + } + } + }, + { + "name": "retransmit_interval", + "getval": re.compile( + r""" + ^set + \s+interfaces + \s+(?P<type>\S+) + \s+(?P<name>\S+) + \s+(?P<afi>ip|ipv6) + \s+(?P<proto>ospf|ospfv3) + \s+retransmit-interval + \s+(?P<val>\'\d+\') + *$""", + re.VERBOSE, + ), + "setval": _tmplt_ospf_int_retransmit_interval, + "compval": "address_family.retransmit_interval", + "result": { + "name": "{{ name }}", + "address_family": { + "{{ afi }}": { + "afi": '{{ "ipv4" if afi == "ip" else "ipv6" }}', + "retransmit_interval": "{{ val }}" + } + } + } + }, + { + "name": "transmit_delay", + "getval": re.compile( + r""" + ^set + \s+interfaces + \s+(?P<type>\S+) + \s+(?P<name>\S+) + \s+(?P<afi>ip|ipv6) + \s+(?P<proto>ospf|ospfv3) + \s+transmit-delay + \s+(?P<val>\'\d+\') + *$""", + re.VERBOSE, + ), + "setval": _tmplt_ospf_int_transmit_delay, + "compval": "address_family.transmit_delay", + "result": { + "name": "{{ name }}", + "address_family": { + "{{ afi }}": { + "afi": '{{ "ipv4" if afi == "ip" else "ipv6" }}', + "transmit_delay": "{{ val }}" + } + } + } + }, + { + "name": "ifmtu", + "getval": re.compile( + r""" + ^set + \s+interfaces + \s+(?P<type>\S+) + \s+(?P<name>\S+) + \s+(?P<afi>ip|ipv6) + \s+(?P<proto>ospf|ospfv3) + \s+ifmtu + \s+(?P<val>\'\d+\') + *$""", + re.VERBOSE, + ), + "setval": _tmplt_ospf_int_ifmtu, + "compval": "address_family.ifmtu", + "result": { + "name": "{{ name }}", + "address_family": { + "{{ afi }}": { + "afi": '{{ "ipv4" if afi == "ip" else "ipv6" }}', + "ifmtu": "{{ val }}" + } + } + } + }, + { + "name": "instance", + "getval": re.compile( + r""" + ^set + \s+interfaces + \s+(?P<type>\S+) + \s+(?P<name>\S+) + \s+(?P<afi>ip|ipv6) + \s+(?P<proto>ospf|ospfv3) + \s+instance-id + \s+(?P<val>\'\d+\') + *$""", + re.VERBOSE, + ), + "setval": _tmplt_ospf_int_instance, + "compval": "address_family.instance", + "result": { + "name": "{{ name }}", + "address_family": { + "{{ afi }}": { + "afi": '{{ "ipv4" if afi == "ip" else "ipv6" }}', + "instance": "{{ val }}" + } + } + } + }, + { + "name": "passive", + "getval": re.compile( + r""" + ^set + \s+interfaces + \s+(?P<type>\S+) + \s+(?P<name>\S+) + \s+(?P<afi>ip|ipv6) + \s+(?P<proto>ospf|ospfv3) + \s+(?P<pass>\'passive\') + *$""", + re.VERBOSE, + ), + "setval": _tmplt_ospf_int_passive, + "compval": "address_family.passive", + "result": { + "name": "{{ name }}", + "address_family": { + "{{ afi }}": { + "afi": '{{ "ipv4" if afi == "ip" else "ipv6" }}', + "passive": "{{ True if pass is defined }}" + } + } + } + }, + { + "name": "interface_name", + "getval": re.compile( + r""" + ^set + \s+interfaces + \s+(?P<type>\S+) + \s+(?P<name>\S+) + .*$""", + re.VERBOSE, + ), + "setval": "set interface {{ type }} {{ name }}", + "result": { + "name": "{{ name }}", + } + }, + ] + # fmt: on |