summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--changelogs/fragments/vyos_ospf_interfaces_rm.yaml3
-rw-r--r--meta/runtime.yml6
-rw-r--r--plugins/filter/__init__.py0
-rw-r--r--plugins/inventory/__init__.py0
-rw-r--r--plugins/module_utils/network/__init__.py0
-rw-r--r--plugins/module_utils/network/vyos/argspec/ospf_interfaces/__init__.py0
-rw-r--r--plugins/module_utils/network/vyos/argspec/ospf_interfaces/ospf_interfaces.py97
-rw-r--r--plugins/module_utils/network/vyos/config/ospf_interfaces/__init__.py0
-rw-r--r--plugins/module_utils/network/vyos/config/ospf_interfaces/ospf_interfaces.py164
-rw-r--r--plugins/module_utils/network/vyos/facts/facts.py4
-rw-r--r--plugins/module_utils/network/vyos/facts/ospf_interfaces/__init__.py0
-rw-r--r--plugins/module_utils/network/vyos/facts/ospf_interfaces/ospf_interfaces.py101
-rw-r--r--plugins/module_utils/network/vyos/rm_templates/__init__.py0
-rw-r--r--plugins/module_utils/network/vyos/rm_templates/ospf_interfaces.py743
-rw-r--r--plugins/modules/vyos_ospf_interfaces.py917
-rw-r--r--tests/integration/targets/vyos_ospf_interfaces/defaults/main.yaml3
-rw-r--r--tests/integration/targets/vyos_ospf_interfaces/meta/main.yaml3
-rw-r--r--tests/integration/targets/vyos_ospf_interfaces/tasks/cli.yaml19
-rw-r--r--tests/integration/targets/vyos_ospf_interfaces/tasks/main.yaml4
-rw-r--r--tests/integration/targets/vyos_ospf_interfaces/tests/cli/_parsed.cfg6
-rw-r--r--tests/integration/targets/vyos_ospf_interfaces/tests/cli/_parsed_config.cfg10
-rw-r--r--tests/integration/targets/vyos_ospf_interfaces/tests/cli/_populate.yaml13
-rw-r--r--tests/integration/targets/vyos_ospf_interfaces/tests/cli/_remove_config.yaml15
-rw-r--r--tests/integration/targets/vyos_ospf_interfaces/tests/cli/deleted.yaml42
-rw-r--r--tests/integration/targets/vyos_ospf_interfaces/tests/cli/empty_config.yaml60
-rw-r--r--tests/integration/targets/vyos_ospf_interfaces/tests/cli/gathered.yaml24
-rw-r--r--tests/integration/targets/vyos_ospf_interfaces/tests/cli/merged.yaml53
-rw-r--r--tests/integration/targets/vyos_ospf_interfaces/tests/cli/overridden.yaml49
-rw-r--r--tests/integration/targets/vyos_ospf_interfaces/tests/cli/parsed.yaml16
-rw-r--r--tests/integration/targets/vyos_ospf_interfaces/tests/cli/rendered.yaml33
-rw-r--r--tests/integration/targets/vyos_ospf_interfaces/tests/cli/replaced.yaml60
-rw-r--r--tests/integration/targets/vyos_ospf_interfaces/tests/cli/rtt.yaml70
-rw-r--r--tests/integration/targets/vyos_ospf_interfaces/vars/main.yaml133
-rw-r--r--tests/unit/modules/network/vyos/fixtures/vyos_ospf_interfaces_config.cfg4
-rw-r--r--tests/unit/modules/network/vyos/test_vyos_ospf_interfaces.py461
35 files changed, 3113 insertions, 0 deletions
diff --git a/changelogs/fragments/vyos_ospf_interfaces_rm.yaml b/changelogs/fragments/vyos_ospf_interfaces_rm.yaml
new file mode 100644
index 0000000..c2dcdc2
--- /dev/null
+++ b/changelogs/fragments/vyos_ospf_interfaces_rm.yaml
@@ -0,0 +1,3 @@
+---
+minor_changes:
+ - Added ospf_interfaces resource module.
diff --git a/meta/runtime.yml b/meta/runtime.yml
index 949a04f..00bbaca 100644
--- a/meta/runtime.yml
+++ b/meta/runtime.yml
@@ -82,6 +82,10 @@ plugin_routing:
redirect: vyos.vyos.vyos
ospfv3:
redirect: vyos.vyos.vyos
+ vyos_ospf_interfaces:
+ redirect: vyos.vyos.vyos
+ ospf_interfaces:
+ redirect: vyos.vyos.vyos
vyos_ping:
redirect: vyos.vyos.vyos
ping:
@@ -182,6 +186,8 @@ plugin_routing:
redirect: vyos.vyos.vyos_ospfv2
ospfv3:
redirect: vyos.vyos.vyos_ospfv3
+ ospf_interfaces:
+ redirect: vyos.vyos.vyos_ospf_interfaces
ping:
redirect: vyos.vyos.vyos_ping
static_route:
diff --git a/plugins/filter/__init__.py b/plugins/filter/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/plugins/filter/__init__.py
diff --git a/plugins/inventory/__init__.py b/plugins/inventory/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/plugins/inventory/__init__.py
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
diff --git a/plugins/modules/vyos_ospf_interfaces.py b/plugins/modules/vyos_ospf_interfaces.py
new file mode 100644
index 0000000..732a5e7
--- /dev/null
+++ b/plugins/modules/vyos_ospf_interfaces.py
@@ -0,0 +1,917 @@
+#!/usr/bin/python
+# -*- 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)
+
+#############################################
+# 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 module file for vyos_ospf_interfaces
+"""
+
+from __future__ import absolute_import, division, print_function
+
+__metaclass__ = type
+
+DOCUMENTATION = """
+module: vyos_ospf_interfaces
+version_added: 1.2.0
+short_description: OSPF Interfaces Resource Module.
+description:
+- This module manages OSPF configuration of interfaces on devices running VYOS.
+author: Gomathi Selvi Srinivasan (@GomathiselviS)
+options:
+ config:
+ description: A list of OSPF configuration for interfaces.
+ type: list
+ elements: dict
+ suboptions:
+ name:
+ description:
+ - Name/Identifier of the interface.
+ type: str
+ address_family:
+ description:
+ - OSPF settings on the interfaces in address-family context.
+ type: list
+ elements: dict
+ suboptions:
+ afi:
+ description:
+ - Address Family Identifier (AFI) for OSPF settings on the interfaces.
+ type: str
+ choices: ['ipv4', 'ipv6']
+ required: True
+ authentication:
+ description:
+ - Authentication settings on the interface.
+ type: dict
+ suboptions:
+ plaintext_password:
+ description:
+ - Plain Text password.
+ type: str
+ md5_key:
+ description:
+ - md5 parameters.
+ type: dict
+ suboptions:
+ key_id:
+ description:
+ - key id.
+ type: int
+ key:
+ description:
+ - md5 key.
+ type: str
+ bandwidth:
+ description:
+ - Bandwidth of interface (kilobits/sec)
+ type: int
+ cost:
+ description:
+ - metric associated with interface.
+ type: int
+ dead_interval:
+ description:
+ - Time interval to detect a dead router.
+ type: int
+ hello_interval:
+ description:
+ - Timer interval between transmission of hello packets.
+ type: int
+ mtu_ignore:
+ description:
+ - if True, Disable MTU check for Database Description packets.
+ type: bool
+ network:
+ description:
+ - Interface type.
+ type: str
+ priority:
+ description:
+ - Interface priority.
+ type: int
+ retransmit_interval:
+ description:
+ - LSA retransmission interval.
+ type: int
+ transmit_delay:
+ description:
+ - LSA transmission delay.
+ type: int
+ ifmtu:
+ description:
+ - interface MTU.
+ type: int
+ instance:
+ description:
+ - Instance ID.
+ type: str
+ passive:
+ description:
+ - If True, disables forming adjacency.
+ type: bool
+ running_config:
+ description:
+ - This option is used only with state I(parsed).
+ - The value of this option should be the output received from the IOS device by
+ executing the command B(sh running-config | section ^interface).
+ - The state I(parsed) reads the configuration from C(running_config) option and
+ transforms it into Ansible structured data as per the resource module's argspec
+ and the value is then returned in the I(parsed) key within the result.
+ type: str
+ state:
+ description:
+ - The state the configuration should be left in.
+ type: str
+ choices:
+ - merged
+ - replaced
+ - overridden
+ - deleted
+ - gathered
+ - parsed
+ - rendered
+ default: merged
+"""
+EXAMPLES = """
+# Using merged
+#
+# Before state:
+# -------------
+#
+
+# @vyos:~$ show configuration commands | match "ospf"
+
+ - name: Merge provided configuration with device configuration
+ vyos.vyos.vyos_ospf_interfaces:
+ config:
+ - name: "eth1"
+ address_family:
+ - afi: "ipv4"
+ transmit_delay: 50
+ priority: 26
+ network: "point-to-point"
+ - afi: "ipv6"
+ dead_interval: 39
+ - name: "bond2"
+ address_family:
+ - afi: "ipv4"
+ transmit_delay: 45
+ bandwidth: 70
+ authentication:
+ md5_key:
+ key_id: 10
+ key: "1111111111232345"
+ - afi: "ipv6"
+ passive: True
+ state: merged
+
+# After State:
+# --------------
+
+# vyos@vyos:~$ show configuration commands | match "ospf"
+# set interfaces bonding bond2 ip ospf authentication md5 key-id 10 md5-key '1111111111232345'
+# set interfaces bonding bond2 ip ospf bandwidth '70'
+# set interfaces bonding bond2 ip ospf transmit-delay '45'
+# set interfaces bonding bond2 ipv6 ospfv3 'passive'
+# set interfaces ethernet eth1 ip ospf network 'point-to-point'
+# set interfaces ethernet eth1 ip ospf priority '26'
+# set interfaces ethernet eth1 ip ospf transmit-delay '50'
+# set interfaces ethernet eth1 ipv6 ospfv3 dead-interval '39'
+
+# "after": [
+# "
+# "address_family": [
+# {
+# "afi": "ipv4",
+# "authentication": {
+# "md5_key": {
+# "key": "1111111111232345",
+# "key_id": 10
+# }
+# },
+# "bandwidth": 70,
+# "transmit_delay": 45
+# },
+# {
+# "afi": "ipv6",
+# "passive": true
+# }
+# ],
+# "name": "bond2"
+# },
+# {
+# "name": "eth0"
+# },
+# {
+# "address_family": [
+# {
+# "afi": "ipv4",
+# "network": "point-to-point",
+# "priority": 26,
+# "transmit_delay": 50
+# },
+# {
+# "afi": "ipv6",
+# "dead_interval": 39
+# }
+# ],
+# "name": "eth1"
+# },
+# {
+# "name": "eth2"
+# },
+# {
+# "name": "eth3"
+# }
+# ],
+# "before": [
+# {
+# "name": "eth0"
+# },
+# {
+# "name": "eth1"
+# },
+# {
+# "name": "eth2"
+# },
+# {
+# "name": "eth3"
+# }
+# ],
+# "changed": true,
+# "commands": [
+# "set interfaces ethernet eth1 ip ospf transmit-delay 50",
+# "set interfaces ethernet eth1 ip ospf priority 26",
+# "set interfaces ethernet eth1 ip ospf network point-to-point",
+# "set interfaces ethernet eth1 ipv6 ospfv3 dead-interval 39",
+# "set interfaces bonding bond2 ip ospf transmit-delay 45",
+# "set interfaces bonding bond2 ip ospf bandwidth 70",
+# "set interfaces bonding bond2 ip ospf authentication md5 key-id 10 md5-key 1111111111232345",
+# "set interfaces bonding bond2 ipv6 ospfv3 passive"
+# ],
+
+
+
+
+# Using replaced:
+
+# Before State:
+# ------------
+
+# vyos@vyos:~$ show configuration commands | match "ospf"
+# set interfaces bonding bond2 ip ospf authentication md5 key-id 10 md5-key '1111111111232345'
+# set interfaces bonding bond2 ip ospf bandwidth '70'
+# set interfaces bonding bond2 ip ospf transmit-delay '45'
+# set interfaces bonding bond2 ipv6 ospfv3 'passive'
+# set interfaces ethernet eth1 ip ospf network 'point-to-point'
+# set interfaces ethernet eth1 ip ospf priority '26'
+# set interfaces ethernet eth1 ip ospf transmit-delay '50'
+# set interfaces ethernet eth1 ipv6 ospfv3 dead-interval '39'
+
+ - name: Replace provided configuration with device configuration
+ vyos.vyos.vyos_ospf_interfaces:
+ config:
+ - name: "eth1"
+ address_family:
+ - afi: "ipv4"
+ cost: 100
+ - afi: "ipv6"
+ ifmtu: 33
+ - name: "bond2"
+ address_family:
+ - afi: "ipv4"
+ transmit_delay: 45
+ - afi: "ipv6"
+ passive: True
+ state: replaced
+
+# After State:
+# -----------
+
+# vyos@vyos:~$ show configuration commands | match "ospf"
+# set interfaces bonding bond2 ip ospf transmit-delay '45'
+# set interfaces bonding bond2 ipv6 ospfv3 'passive'
+# set interfaces ethernet eth1 ip ospf cost '100'
+# set interfaces ethernet eth1 ipv6 ospfv3 ifmtu '33'
+# vyos@vyos:~$
+
+# Module Execution
+# ----------------
+# "after": [
+# {
+# "address_family": [
+# {
+# "afi": "ipv4",
+# "transmit_delay": 45
+# },
+# {
+# "afi": "ipv6",
+# "passive": true
+# }
+# ],
+# "name": "bond2"
+# },
+# {
+# "name": "eth0"
+# },
+# {
+# "address_family": [
+# {
+# "afi": "ipv4",
+# "cost": 100
+# },
+# {
+# "afi": "ipv6",
+# "ifmtu": 33
+# }
+# ],
+# "name": "eth1"
+# },
+# {
+# "name": "eth2"
+# },
+# {
+# "name": "eth3"
+# }
+# ],
+# "before": [
+# {
+# "address_family": [
+# {
+# "afi": "ipv4",
+# "authentication": {
+# "md5_key": {
+# "key": "1111111111232345",
+# "key_id": 10
+# }
+# },
+# "bandwidth": 70,
+# "transmit_delay": 45
+# },
+# {
+# "afi": "ipv6",
+# "passive": true
+# }
+# ],
+# "name": "bond2"
+# },
+# {
+# "name": "eth0"
+# },
+# {
+# "address_family": [
+# {
+# "afi": "ipv4",
+# "network": "point-to-point",
+# "priority": 26,
+# "transmit_delay": 50
+# },
+# {
+# "afi": "ipv6",
+# "dead_interval": 39
+# }
+# ],
+# "name": "eth1"
+# },
+# {
+# "name": "eth2"
+# },
+# {
+# "name": "eth3"
+# }
+# ],
+# "changed": true,
+# "commands": [
+# "set interfaces ethernet eth1 ip ospf cost 100",
+# "set interfaces ethernet eth1 ipv6 ospfv3 ifmtu 33",
+# "delete interfaces ethernet eth1 ip ospf network point-to-point",
+# "delete interfaces ethernet eth1 ip ospf priority 26",
+# "delete interfaces ethernet eth1 ip ospf transmit-delay 50",
+# "delete interfaces ethernet eth1 ipv6 ospfv3 dead-interval 39",
+# "delete interfaces bonding bond2 ip ospf authentication",
+# "delete interfaces bonding bond2 ip ospf bandwidth 70"
+# ],
+#
+
+# Using Overridden:
+# -----------------
+
+# Before State:
+# ------------
+
+# vyos@vyos:~$ show configuration commands | match "ospf"
+# set interfaces bonding bond2 ip ospf authentication md5 key-id 10 md5-key '1111111111232345'
+# set interfaces bonding bond2 ip ospf bandwidth '70'
+# set interfaces bonding bond2 ip ospf transmit-delay '45'
+# set interfaces bonding bond2 ipv6 ospfv3 'passive'
+# set interfaces ethernet eth1 ip ospf cost '100'
+# set interfaces ethernet eth1 ip ospf network 'point-to-point'
+# set interfaces ethernet eth1 ip ospf priority '26'
+# set interfaces ethernet eth1 ip ospf transmit-delay '50'
+# set interfaces ethernet eth1 ipv6 ospfv3 dead-interval '39'
+# set interfaces ethernet eth1 ipv6 ospfv3 ifmtu '33'
+# vyos@vyos:~$
+
+ - name: Override device configuration with provided configuration
+ vyos.vyos.vyos_ospf_interfaces:
+ config:
+ - name: "eth0"
+ address_family:
+ - afi: "ipv4"
+ cost: 100
+ - afi: "ipv6"
+ ifmtu: 33
+ passive: True
+ state: overridden
+# After State:
+# -----------
+
+# 200~vyos@vyos:~$ show configuration commands | match "ospf"
+# set interfaces ethernet eth0 ip ospf cost '100'
+# set interfaces ethernet eth0 ipv6 ospfv3 ifmtu '33'
+# set interfaces ethernet eth0 ipv6 ospfv3 'passive'
+# vyos@vyos:~$
+#
+#
+# "after": [
+# {
+# "name": "bond2"
+# },
+# {
+# "address_family": [
+# {
+# "afi": "ipv4",
+# "cost": 100
+# },
+# {
+# "afi": "ipv6",
+# "ifmtu": 33,
+# "passive": true
+# }
+# ],
+# "name": "eth0"
+# },
+# {
+# "name": "eth1"
+# },
+# {
+# "name": "eth2"
+# },
+# {
+# "name": "eth3"
+# }
+# ],
+# "before": [
+# {
+# "address_family": [
+# {
+# "afi": "ipv4",
+# "authentication": {
+# "md5_key": {
+# "key": "1111111111232345",
+# "key_id": 10
+# }
+# },
+# "bandwidth": 70,
+# "transmit_delay": 45
+# },
+# {
+# "afi": "ipv6",
+# "passive": true
+# }
+# ],
+# "name": "bond2"
+# },
+# {
+# "name": "eth0"
+# },
+# {
+# "address_family": [
+# {
+# "afi": "ipv4",
+# "cost": 100,
+# "network": "point-to-point",
+# "priority": 26,
+# "transmit_delay": 50
+# },
+# {
+# "afi": "ipv6",
+# "dead_interval": 39,
+# "ifmtu": 33
+# }
+# ],
+# "name": "eth1"
+# },
+# {
+# "name": "eth2"
+# },
+# {
+# "name": "eth3"
+# }
+# ],
+# "changed": true,
+# "commands": [
+# "delete interfaces bonding bond2 ip ospf",
+# "delete interfaces bonding bond2 ipv6 ospfv3",
+# "delete interfaces ethernet eth1 ip ospf",
+# "delete interfaces ethernet eth1 ipv6 ospfv3",
+# "set interfaces ethernet eth0 ip ospf cost 100",
+# "set interfaces ethernet eth0 ipv6 ospfv3 ifmtu 33",
+# "set interfaces ethernet eth0 ipv6 ospfv3 passive"
+# ],
+#
+
+# Using deleted:
+# -------------
+
+# before state:
+# -------------
+
+# vyos@vyos:~$ show configuration commands | match "ospf"
+# set interfaces bonding bond2 ip ospf authentication md5 key-id 10 md5-key '1111111111232345'
+# set interfaces bonding bond2 ip ospf bandwidth '70'
+# set interfaces bonding bond2 ip ospf transmit-delay '45'
+# set interfaces bonding bond2 ipv6 ospfv3 'passive'
+# set interfaces ethernet eth0 ip ospf cost '100'
+# set interfaces ethernet eth0 ipv6 ospfv3 ifmtu '33'
+# set interfaces ethernet eth0 ipv6 ospfv3 'passive'
+# set interfaces ethernet eth1 ip ospf network 'point-to-point'
+# set interfaces ethernet eth1 ip ospf priority '26'
+# set interfaces ethernet eth1 ip ospf transmit-delay '50'
+# set interfaces ethernet eth1 ipv6 ospfv3 dead-interval '39'
+# vyos@vyos:~$
+
+ - name: Delete device configuration
+ vyos.vyos.vyos_ospf_interfaces:
+ config:
+ - name: "eth0"
+ state: deleted
+
+# After State:
+# -----------
+
+# vyos@vyos:~$ show configuration commands | match "ospf"
+# set interfaces bonding bond2 ip ospf authentication md5 key-id 10 md5-key '1111111111232345'
+# set interfaces bonding bond2 ip ospf bandwidth '70'
+# set interfaces bonding bond2 ip ospf transmit-delay '45'
+# set interfaces bonding bond2 ipv6 ospfv3 'passive'
+# set interfaces ethernet eth1 ip ospf network 'point-to-point'
+# set interfaces ethernet eth1 ip ospf priority '26'
+# set interfaces ethernet eth1 ip ospf transmit-delay '50'
+# set interfaces ethernet eth1 ipv6 ospfv3 dead-interval '39'
+# vyos@vyos:~$
+#
+#
+# "after": [
+# {
+# "address_family": [
+# {
+# "afi": "ipv4",
+# "authentication": {
+# "md5_key": {
+# "key": "1111111111232345",
+# "key_id": 10
+# }
+# },
+# "bandwidth": 70,
+# "transmit_delay": 45
+# },
+# {
+# "afi": "ipv6",
+# "passive": true
+# }
+# ],
+# "name": "bond2"
+# },
+# {
+# "name": "eth0"
+# },
+# {
+# "address_family": [
+# {
+# "afi": "ipv4",
+# "network": "point-to-point",
+# "priority": 26,
+# "transmit_delay": 50
+# },
+# {
+# "afi": "ipv6",
+# "dead_interval": 39
+# }
+# ],
+# "name": "eth1"
+# },
+# {
+# "name": "eth2"
+# },
+# {
+# "name": "eth3"
+# }
+# ],
+# "before": [
+# {
+# "address_family": [
+# {
+# "afi": "ipv4",
+# "authentication": {
+# "md5_key": {
+# "key": "1111111111232345",
+# "key_id": 10
+# }
+# },
+# "bandwidth": 70,
+# "transmit_delay": 45
+# },
+# {
+# "afi": "ipv6",
+# "passive": true
+# }
+# ],
+# "name": "bond2"
+# },
+# {
+# "address_family": [
+# {
+# "afi": "ipv4",
+# "cost": 100
+# },
+# {
+# "afi": "ipv6",
+# "ifmtu": 33,
+# "passive": true
+# }
+# ],
+# "name": "eth0"
+# },
+# {
+# "address_family": [
+# {
+# "afi": "ipv4",
+# "network": "point-to-point",
+# "priority": 26,
+# "transmit_delay": 50
+# },
+# {
+# "afi": "ipv6",
+# "dead_interval": 39
+# }
+# ],
+# "name": "eth1"
+# },
+# {
+# "name": "eth2"
+# },
+# {
+# "name": "eth3"
+# }
+# ],
+# "changed": true,
+# "commands": [
+# "delete interfaces ethernet eth0 ip ospf",
+# "delete interfaces ethernet eth0 ipv6 ospfv3"
+# ],
+#
+# Using parsed:
+# parsed.cfg:
+
+# set interfaces bonding bond2 ip ospf authentication md5 key-id 10 md5-key '1111111111232345'
+# set interfaces bonding bond2 ip ospf bandwidth '70'
+# set interfaces bonding bond2 ip ospf transmit-delay '45'
+# set interfaces bonding bond2 ipv6 ospfv3 'passive'
+# set interfaces ethernet eth0 ip ospf cost '50'
+# set interfaces ethernet eth0 ip ospf priority '26'
+# set interfaces ethernet eth0 ipv6 ospfv3 instance-id '33'
+# set interfaces ethernet eth0 ipv6 ospfv3 'mtu-ignore'
+# set interfaces ethernet eth1 ip ospf network 'point-to-point'
+# set interfaces ethernet eth1 ip ospf priority '26'
+# set interfaces ethernet eth1 ip ospf transmit-delay '50'
+# set interfaces ethernet eth1 ipv6 ospfv3 dead-interval '39'
+#
+
+ - name: parse configs
+ vyos.vyos.vyos_ospf_interfaces:
+ running_config: "{{ lookup('file', './parsed.cfg') }}"
+ state: parsed
+
+# Module Execution:
+# ----------------
+
+# "parsed": [
+# {
+# "address_family": [
+# {
+# "afi": "ipv4",
+# "authentication": {
+# "md5_key": {
+# "key": "1111111111232345",
+# "key_id": 10
+# }
+# },
+# "bandwidth": 70,
+# "transmit_delay": 45
+# },
+# {
+# "afi": "ipv6",
+# "passive": true
+# }
+# ],
+# "name": "bond2"
+# },
+# {
+# "address_family": [
+# {
+# "afi": "ipv4",
+# "cost": 50,
+# "priority": 26
+# },
+# {
+# "afi": "ipv6",
+# "instance": "33",
+# "mtu_ignore": true
+# }
+# ],
+# "name": "eth0"
+# },
+# {
+# "address_family": [
+# {
+# "afi": "ipv4",
+# "network": "point-to-point",
+# "priority": 26,
+# "transmit_delay": 50
+# },
+# {
+# "afi": "ipv6",
+# "dead_interval": 39
+# }
+# ],
+# "name": "eth1"
+# }
+# ]
+
+# Using rendered:
+# --------------
+
+ - name: Render
+ vyos.vyos.vyos_ospf_interfaces:
+ config:
+ - name: "eth1"
+ address_family:
+ - afi: "ipv4"
+ transmit_delay: 50
+ priority: 26
+ network: "point-to-point"
+ - afi: "ipv6"
+ dead_interval: 39
+ - name: "bond2"
+ address_family:
+ - afi: "ipv4"
+ transmit_delay: 45
+ bandwidth: 70
+ authentication:
+ md5_key:
+ key_id: 10
+ key: "1111111111232345"
+ - afi: "ipv6"
+ passive: True
+ state: rendered
+
+# Module Execution:
+# ----------------
+
+# "rendered": [
+# "set interfaces ethernet eth1 ip ospf transmit-delay 50",
+# "set interfaces ethernet eth1 ip ospf priority 26",
+# "set interfaces ethernet eth1 ip ospf network point-to-point",
+# "set interfaces ethernet eth1 ipv6 ospfv3 dead-interval 39",
+# "set interfaces bonding bond2 ip ospf transmit-delay 45",
+# "set interfaces bonding bond2 ip ospf bandwidth 70",
+# "set interfaces bonding bond2 ip ospf authentication md5 key-id 10 md5-key 1111111111232345",
+# "set interfaces bonding bond2 ipv6 ospfv3 passive"
+# ]
+#
+
+# Using Gathered:
+# --------------
+
+# Native Config:
+
+# vyos@vyos:~$ show configuration commands | match "ospf"
+# set interfaces bonding bond2 ip ospf authentication md5 key-id 10 md5-key '1111111111232345'
+# set interfaces bonding bond2 ip ospf bandwidth '70'
+# set interfaces bonding bond2 ip ospf transmit-delay '45'
+# set interfaces bonding bond2 ipv6 ospfv3 'passive'
+# set interfaces ethernet eth1 ip ospf network 'point-to-point'
+# set interfaces ethernet eth1 ip ospf priority '26'
+# set interfaces ethernet eth1 ip ospf transmit-delay '50'
+# set interfaces ethernet eth1 ipv6 ospfv3 dead-interval '39'
+# vyos@vyos:~$
+
+ - name: gather configs
+ vyos.vyos.vyos_ospf_interfaces:
+ state: gathered
+
+# Module Execution:
+# -----------------
+
+# "gathered": [
+# {
+# "address_family": [
+# {
+# "afi": "ipv4",
+# "authentication": {
+# "md5_key": {
+# "key": "1111111111232345",
+# "key_id": 10
+# }
+# },
+# "bandwidth": 70,
+# "transmit_delay": 45
+# },
+# {
+# "afi": "ipv6",
+# "passive": true
+# }
+# ],
+# "name": "bond2"
+# },
+# {
+# "name": "eth0"
+# },
+# {
+# "address_family": [
+# {
+# "afi": "ipv4",
+# "network": "point-to-point",
+# "priority": 26,
+# "transmit_delay": 50
+# },
+# {
+# "afi": "ipv6",
+# "dead_interval": 39
+# }
+# ],
+# "name": "eth1"
+# },
+# {
+# "name": "eth2"
+# },
+# {
+# "name": "eth3"
+# }
+# ],
+
+
+
+
+
+"""
+
+from ansible.module_utils.basic import AnsibleModule
+from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.argspec.ospf_interfaces.ospf_interfaces import (
+ Ospf_interfacesArgs,
+)
+from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.config.ospf_interfaces.ospf_interfaces import (
+ Ospf_interfaces,
+)
+
+
+def main():
+ """
+ Main entry point for module execution
+
+ :returns: the result form module invocation
+ """
+ module = AnsibleModule(
+ argument_spec=Ospf_interfacesArgs.argument_spec,
+ mutually_exclusive=[],
+ required_if=[],
+ supports_check_mode=False,
+ )
+
+ result = Ospf_interfaces(module).execute_module()
+ module.exit_json(**result)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/tests/integration/targets/vyos_ospf_interfaces/defaults/main.yaml b/tests/integration/targets/vyos_ospf_interfaces/defaults/main.yaml
new file mode 100644
index 0000000..852a6be
--- /dev/null
+++ b/tests/integration/targets/vyos_ospf_interfaces/defaults/main.yaml
@@ -0,0 +1,3 @@
+---
+testcase: '[^_].*'
+test_items: []
diff --git a/tests/integration/targets/vyos_ospf_interfaces/meta/main.yaml b/tests/integration/targets/vyos_ospf_interfaces/meta/main.yaml
new file mode 100644
index 0000000..7413320
--- /dev/null
+++ b/tests/integration/targets/vyos_ospf_interfaces/meta/main.yaml
@@ -0,0 +1,3 @@
+---
+dependencies:
+ - prepare_vyos_tests
diff --git a/tests/integration/targets/vyos_ospf_interfaces/tasks/cli.yaml b/tests/integration/targets/vyos_ospf_interfaces/tasks/cli.yaml
new file mode 100644
index 0000000..93eb2fe
--- /dev/null
+++ b/tests/integration/targets/vyos_ospf_interfaces/tasks/cli.yaml
@@ -0,0 +1,19 @@
+---
+- name: Collect all cli test cases
+ find:
+ paths: '{{ role_path }}/tests/cli'
+ patterns: '{{ testcase }}.yaml'
+ use_regex: true
+ register: test_cases
+ delegate_to: localhost
+
+- name: Set test_items
+ set_fact: test_items="{{ test_cases.files | map(attribute='path') | list }}"
+
+- name: Run test case (connection=ansible.netcommon.network_cli)
+ include: '{{ test_case_to_run }}'
+ vars:
+ ansible_connection: ansible.netcommon.network_cli
+ with_items: '{{ test_items }}'
+ loop_control:
+ loop_var: test_case_to_run
diff --git a/tests/integration/targets/vyos_ospf_interfaces/tasks/main.yaml b/tests/integration/targets/vyos_ospf_interfaces/tasks/main.yaml
new file mode 100644
index 0000000..b957d2f
--- /dev/null
+++ b/tests/integration/targets/vyos_ospf_interfaces/tasks/main.yaml
@@ -0,0 +1,4 @@
+---
+- include: cli.yaml
+ tags:
+ - network_cli
diff --git a/tests/integration/targets/vyos_ospf_interfaces/tests/cli/_parsed.cfg b/tests/integration/targets/vyos_ospf_interfaces/tests/cli/_parsed.cfg
new file mode 100644
index 0000000..aa57677
--- /dev/null
+++ b/tests/integration/targets/vyos_ospf_interfaces/tests/cli/_parsed.cfg
@@ -0,0 +1,6 @@
+set interfaces ethernet eth0 ip ospf cost '50'
+set interfaces ethernet eth0 ip ospf priority '26'
+set interfaces ethernet eth0 ipv6 ospfv3 'mtu-ignore'
+set interfaces ethernet eth0 ipv6 ospfv3 instance-id '33'
+set interfaces bonding bond2 ip ospf transmit-delay '45'
+set interfaces bonding bond2 ipv6 ospfv3 'passive'
diff --git a/tests/integration/targets/vyos_ospf_interfaces/tests/cli/_parsed_config.cfg b/tests/integration/targets/vyos_ospf_interfaces/tests/cli/_parsed_config.cfg
new file mode 100644
index 0000000..54696e8
--- /dev/null
+++ b/tests/integration/targets/vyos_ospf_interfaces/tests/cli/_parsed_config.cfg
@@ -0,0 +1,10 @@
+set interfaces ethernet eth1 firewall in name 'INBOUND'
+set interfaces ethernet eth1 firewall out name 'OUTBOUND'
+set interfaces ethernet eth1 firewall local name 'LOCAL'
+set interfaces ethernet eth1 firewall local ipv6-name 'V6-LOCAL'
+set interfaces ethernet eth2 firewall in name 'INBOUND'
+set interfaces ethernet eth2 firewall out name 'OUTBOUND'
+set interfaces ethernet eth2 firewall local name 'LOCAL'
+set interfaces ethernet eth2 firewall local ipv6-name 'V6-LOCAL'
+set interfaces ethernet eth0
+
diff --git a/tests/integration/targets/vyos_ospf_interfaces/tests/cli/_populate.yaml b/tests/integration/targets/vyos_ospf_interfaces/tests/cli/_populate.yaml
new file mode 100644
index 0000000..c4749d3
--- /dev/null
+++ b/tests/integration/targets/vyos_ospf_interfaces/tests/cli/_populate.yaml
@@ -0,0 +1,13 @@
+---
+- name: setup
+ vyos.vyos.vyos_config:
+ lines:
+ - set interfaces ethernet eth0 ip ospf cost 50
+ - set interfaces ethernet eth0 ip ospf priority 26
+ - set interfaces ethernet eth0 ipv6 ospfv3 mtu-ignore
+ - set interfaces ethernet eth0 ipv6 ospfv3 instance-id 33
+ - set interfaces bonding bond2 ip ospf transmit-delay 45
+ - set interfaces bonding bond2 ipv6 ospfv3 passive
+ ignore_errors: true
+ vars:
+ ansible_connection: ansible.netcommon.network_cli
diff --git a/tests/integration/targets/vyos_ospf_interfaces/tests/cli/_remove_config.yaml b/tests/integration/targets/vyos_ospf_interfaces/tests/cli/_remove_config.yaml
new file mode 100644
index 0000000..9a2e699
--- /dev/null
+++ b/tests/integration/targets/vyos_ospf_interfaces/tests/cli/_remove_config.yaml
@@ -0,0 +1,15 @@
+---
+- name: Remove pre-existing OSPF processes
+ vyos.vyos.vyos_config:
+ lines:
+ - delete interfaces ethernet eth0 ip ospf
+ - delete interfaces ethernet eth0 ipv6 ospfv3
+ - delete interfaces ethernet eth1 ip ospf
+ - delete interfaces ethernet eth1 ipv6 ospfv3
+ - delete interfaces bonding bond1 ip ospf
+ - delete interfaces bonding bond1 ipv6 ospfv3
+ - delete interfaces bonding bond2 ip ospf
+ - delete interfaces bonding bond2 ipv6 ospfv3
+ ignore_errors: true
+ vars:
+ ansible_connection: ansible.netcommon.network_cli
diff --git a/tests/integration/targets/vyos_ospf_interfaces/tests/cli/deleted.yaml b/tests/integration/targets/vyos_ospf_interfaces/tests/cli/deleted.yaml
new file mode 100644
index 0000000..573e611
--- /dev/null
+++ b/tests/integration/targets/vyos_ospf_interfaces/tests/cli/deleted.yaml
@@ -0,0 +1,42 @@
+---
+- debug:
+ msg: START vyos_ospf_interfaces deleted integration tests on connection={{
+ ansible_connection }}
+
+- include_tasks: _remove_config.yaml
+
+- include_tasks: _populate.yaml
+
+- block:
+
+ - name: Delete the provided configuration
+ register: result
+ vyos.vyos.vyos_ospf_interfaces: &id001
+ config:
+ - name: "bond2"
+ state: deleted
+
+ - become: true
+ vyos.vyos.vyos_facts:
+ gather_network_resources: ospf_interfaces
+
+ - assert:
+ that:
+ - result.commands|length == 2
+ - result.changed == true
+ - result.commands|symmetric_difference(deleted.commands) == []
+ - result.after|symmetric_difference(ansible_facts['network_resources']['ospf_interfaces']) == []
+
+ - name: Delete the existing configuration with the provided running configuration
+ (IDEMPOTENT)
+ register: result
+ vyos.vyos.vyos_ospf_interfaces: *id001
+
+ - name: Assert that the previous task was idempotent
+ assert:
+ that:
+ - result['changed'] == false
+
+ always:
+
+ - include_tasks: _remove_config.yaml
diff --git a/tests/integration/targets/vyos_ospf_interfaces/tests/cli/empty_config.yaml b/tests/integration/targets/vyos_ospf_interfaces/tests/cli/empty_config.yaml
new file mode 100644
index 0000000..aff0f66
--- /dev/null
+++ b/tests/integration/targets/vyos_ospf_interfaces/tests/cli/empty_config.yaml
@@ -0,0 +1,60 @@
+---
+- debug:
+ msg: START vyos_ospf_interfaces empty_config integration tests on connection={{
+ ansible_connection }}
+
+- name: Merged with empty config should give appropriate error message
+ register: result
+ ignore_errors: true
+ vyos.vyos.vyos_ospf_interfaces:
+ config:
+ state: merged
+
+- assert:
+ that:
+ - result.msg == 'value of config parameter must not be empty for state merged'
+
+- name: Replaced with empty config should give appropriate error message
+ register: result
+ ignore_errors: true
+ vyos.vyos.vyos_ospf_interfaces:
+ config:
+ state: replaced
+
+- assert:
+ that:
+ - result.msg == 'value of config parameter must not be empty for state replaced'
+
+- name: Overridden with empty config should give appropriate error message
+ register: result
+ ignore_errors: true
+ vyos.vyos.vyos_ospf_interfaces:
+ config:
+ state: overridden
+
+- assert:
+ that:
+ - result.msg == 'value of config parameter must not be empty for state overridden'
+
+- name: Parsed with empty running_config should give appropriate error message
+ register: result
+ ignore_errors: true
+ vyos.vyos.vyos_ospf_interfaces:
+ running_config:
+ state: parsed
+
+- assert:
+ that:
+ - result.msg == 'value of running_config parameter must not be empty for state
+ parsed'
+
+- name: Rendered with empty config should give appropriate error message
+ register: result
+ ignore_errors: true
+ vyos.vyos.vyos_ospf_interfaces:
+ config:
+ state: rendered
+
+- assert:
+ that:
+ - result.msg == 'value of config parameter must not be empty for state rendered'
diff --git a/tests/integration/targets/vyos_ospf_interfaces/tests/cli/gathered.yaml b/tests/integration/targets/vyos_ospf_interfaces/tests/cli/gathered.yaml
new file mode 100644
index 0000000..ec320c3
--- /dev/null
+++ b/tests/integration/targets/vyos_ospf_interfaces/tests/cli/gathered.yaml
@@ -0,0 +1,24 @@
+---
+- debug:
+ msg: START vyos_ospf_interfaces gathered integration tests on connection={{
+ ansible_connection }}
+
+- include_tasks: _remove_config.yaml
+
+- include_tasks: _populate.yaml
+
+- block:
+
+ - name: Gather config from the device in structured format.
+ register: result
+ vyos.vyos.vyos_ospf_interfaces:
+ state: gathered
+
+ - become: true
+ vyos.vyos.vyos_facts:
+ gather_network_resources: ospf_interfaces
+
+ - assert:
+ that:
+ - result.changed == false
+ - result.gathered|symmetric_difference(ansible_facts['network_resources']['ospf_interfaces']) == []
diff --git a/tests/integration/targets/vyos_ospf_interfaces/tests/cli/merged.yaml b/tests/integration/targets/vyos_ospf_interfaces/tests/cli/merged.yaml
new file mode 100644
index 0000000..294b6f1
--- /dev/null
+++ b/tests/integration/targets/vyos_ospf_interfaces/tests/cli/merged.yaml
@@ -0,0 +1,53 @@
+---
+- debug:
+ msg: START vyos_ospf_interfaces merged integration tests on connection={{
+ ansible_connection }}
+
+- include_tasks: _remove_config.yaml
+
+- block:
+
+ - name: Merge the provided configuration with the exisiting running configuration
+ register: result
+ vyos.vyos.vyos_ospf_interfaces: &id001
+ config:
+ - name: "eth0"
+ address_family:
+ - afi: "ipv4"
+ cost: 50
+ priority: 26
+ - afi: "ipv6"
+ mtu_ignore: true
+ instance: 33
+ - name: "bond2"
+ address_family:
+ - afi: "ipv4"
+ transmit_delay: 45
+ - afi: "ipv6"
+ passive: true
+ state: merged
+
+ - become: true
+ vyos.vyos.vyos_facts:
+ gather_network_resources: ospf_interfaces
+
+ - assert:
+ that:
+ - result.commands|length == 6
+ - result.changed == true
+ - result.commands|symmetric_difference(merged.commands) == []
+ - result.after|symmetric_difference(ansible_facts['network_resources']['ospf_interfaces']) == []
+
+ - name: Merge the provided configuration with the existing running configuration
+ (IDEMPOTENT)
+ register: result
+ vyos.vyos.vyos_ospf_interfaces: *id001
+
+ - name: Assert that the previous task was idempotent
+ assert:
+ that:
+ - result['changed'] == false
+
+ always:
+
+ - include_tasks: _remove_config.yaml
diff --git a/tests/integration/targets/vyos_ospf_interfaces/tests/cli/overridden.yaml b/tests/integration/targets/vyos_ospf_interfaces/tests/cli/overridden.yaml
new file mode 100644
index 0000000..67bbca1
--- /dev/null
+++ b/tests/integration/targets/vyos_ospf_interfaces/tests/cli/overridden.yaml
@@ -0,0 +1,49 @@
+---
+- debug:
+ msg: START vyos_ospf_interfaces overridden integration tests on connection={{
+ ansible_connection }}
+
+- include_tasks: _remove_config.yaml
+
+- include_tasks: _populate.yaml
+
+- block:
+
+ - name: Override the existing configuration with the provided running configuration
+ register: result
+ vyos.vyos.vyos_ospf_interfaces: &id001
+ config:
+ - name: "eth0"
+ address_family:
+ - afi: "ipv4"
+ transmit_delay: 50
+ priority: 26
+ network: "point-to-point"
+ - afi: "ipv6"
+ dead_interval: 39
+ state: overridden
+
+ - become: true
+ vyos.vyos.vyos_facts:
+ gather_network_resources: ospf_interfaces
+
+ - assert:
+ that:
+ - result.commands|length == 8
+ - result.changed == true
+ - result.commands|symmetric_difference(overridden.commands) == []
+ - result.after|symmetric_difference(ansible_facts['network_resources']['ospf_interfaces']) == []
+
+ - name: Override the existing configuration with the provided running configuration
+ (IDEMPOTENT)
+ register: result
+ vyos.vyos.vyos_ospf_interfaces: *id001
+
+ - name: Assert that the previous task was idempotent
+ assert:
+ that:
+ - result['changed'] == false
+
+ always:
+
+ - include_tasks: _remove_config.yaml
diff --git a/tests/integration/targets/vyos_ospf_interfaces/tests/cli/parsed.yaml b/tests/integration/targets/vyos_ospf_interfaces/tests/cli/parsed.yaml
new file mode 100644
index 0000000..a065a00
--- /dev/null
+++ b/tests/integration/targets/vyos_ospf_interfaces/tests/cli/parsed.yaml
@@ -0,0 +1,16 @@
+---
+- debug:
+ msg: START vyos_ospfv3_interfaces parsed integration tests on connection={{ ansible_connection
+ }}
+
+- name: Provide the running configuration for parsing (config to be parsed)
+ become: true
+ register: result
+ vyos.vyos.vyos_ospf_interfaces:
+ running_config: "{{ lookup('file', '_parsed.cfg') }}"
+ state: parsed
+
+- assert:
+ that:
+ - result.changed == false
+ - result.parsed|symmetric_difference(merged.after) == []
diff --git a/tests/integration/targets/vyos_ospf_interfaces/tests/cli/rendered.yaml b/tests/integration/targets/vyos_ospf_interfaces/tests/cli/rendered.yaml
new file mode 100644
index 0000000..328406b
--- /dev/null
+++ b/tests/integration/targets/vyos_ospf_interfaces/tests/cli/rendered.yaml
@@ -0,0 +1,33 @@
+---
+- debug:
+ msg: START vyos_ospf_interfaces rendered integration tests on connection={{
+ ansible_connection }}
+
+- include_tasks: _remove_config.yaml
+
+- block:
+
+ - name: Structure provided configuration into device specific commands
+ register: result
+ vyos.vyos.vyos_ospf_interfaces:
+ config:
+ - name: "eth0"
+ address_family:
+ - afi: "ipv4"
+ cost: 50
+ priority: 26
+ - afi: "ipv6"
+ mtu_ignore: true
+ instance: 33
+ - name: "bond2"
+ address_family:
+ - afi: "ipv4"
+ transmit_delay: 45
+ - afi: "ipv6"
+ passive: true
+ state: rendered
+
+ - assert:
+ that:
+ - result.changed == false
+ - result.rendered|symmetric_difference(merged.commands) == []
diff --git a/tests/integration/targets/vyos_ospf_interfaces/tests/cli/replaced.yaml b/tests/integration/targets/vyos_ospf_interfaces/tests/cli/replaced.yaml
new file mode 100644
index 0000000..ff32012
--- /dev/null
+++ b/tests/integration/targets/vyos_ospf_interfaces/tests/cli/replaced.yaml
@@ -0,0 +1,60 @@
+---
+- debug:
+ msg: START vyos_ospf_interfaces replaced integration tests on connection={{
+ ansible_connection }}
+
+- include_tasks: _remove_config.yaml
+
+- include_tasks: _populate.yaml
+
+- block:
+
+ - name: Replace the existing configuration with the provided running configuration
+ register: result
+ vyos.vyos.vyos_ospf_interfaces: &id001
+ config:
+ - name: "eth0"
+ address_family:
+ - afi: "ipv4"
+ transmit_delay: 50
+ priority: 26
+ network: "point-to-point"
+ - afi: "ipv6"
+ dead_interval: 39
+ - name: "bond2"
+ address_family:
+ - afi: "ipv4"
+ transmit_delay: 45
+ bandwidth: 70
+ authentication:
+ md5_key:
+ key_id: 10
+ key: "1111111111232345"
+ - afi: "ipv6"
+ passive: true
+ state: replaced
+
+ - become: true
+ vyos.vyos.vyos_facts:
+ gather_network_resources: ospf_interfaces
+
+ - assert:
+ that:
+ - result.commands|length == 8
+ - result.changed == true
+ - result.commands|symmetric_difference(replaced.commands) == []
+ - result.after|symmetric_difference(ansible_facts['network_resources']['ospf_interfaces']) == []
+
+ - name: Replace the existing configuration with the provided running configuration
+ (IDEMPOTENT)
+ register: result
+ vyos.vyos.vyos_ospf_interfaces: *id001
+
+ - name: Assert that the previous task was idempotent
+ assert:
+ that:
+ - result['changed'] == false
+
+ always:
+
+ - include_tasks: _remove_config.yaml
diff --git a/tests/integration/targets/vyos_ospf_interfaces/tests/cli/rtt.yaml b/tests/integration/targets/vyos_ospf_interfaces/tests/cli/rtt.yaml
new file mode 100644
index 0000000..46eb79d
--- /dev/null
+++ b/tests/integration/targets/vyos_ospf_interfaces/tests/cli/rtt.yaml
@@ -0,0 +1,70 @@
+---
+- debug:
+ msg: START vyos_ospf_interfaces rtt integration tests on connection={{
+ ansible_connection }}
+
+- include_tasks: _remove_config.yaml
+
+
+- block:
+
+ - name: Merge the provided configuration with the exisiting running configuration
+ register: baseconfig
+ vyos.vyos.vyos_ospf_interfaces: &id001
+ config:
+ - name: "eth0"
+ address_family:
+ - afi: "ipv4"
+ cost: 50
+ priority: 26
+ - afi: "ipv6"
+ mtu_ignore: true
+ instance: 33
+ - name: "bond2"
+ address_family:
+ - afi: "ipv4"
+ transmit_delay: 45
+ - afi: "ipv6"
+ passive: true
+ state: merged
+
+ - become: true
+ vyos.vyos.vyos_facts:
+ gather_network_resources: ospf_interfaces
+
+ - assert:
+ that:
+ - baseconfig.commands|length == 6
+ - baseconfig.changed == true
+ - baseconfig.commands|symmetric_difference(merged.commands) == []
+ - baseconfig.after|symmetric_difference(ansible_facts['network_resources']['ospf_interfaces']) == []
+
+ - name: Apply the provided configuration (config to be reverted)
+ become: true
+ register: result
+ vyos.vyos.vyos_ospf_interfaces:
+ config:
+ - name: "eth0"
+ address_family:
+ - afi: "ipv4"
+ transmit_delay: 50
+ priority: 26
+ network: "point-to-point"
+ - afi: "ipv6"
+ dead_interval: 39
+
+
+ - name: Revert back to base config using facts round trip
+ become: true
+ register: revert
+ vyos.vyos.vyos_ospf_interfaces:
+ config: "{{ ansible_facts['network_resources']['ospf_interfaces'] }}"
+ state: overridden
+
+ - name: Assert that config was reverted
+ assert:
+ that: baseconfig.after == revert.after
+
+ always:
+
+ - include_tasks: _remove_config.yaml
diff --git a/tests/integration/targets/vyos_ospf_interfaces/vars/main.yaml b/tests/integration/targets/vyos_ospf_interfaces/vars/main.yaml
new file mode 100644
index 0000000..a98d351
--- /dev/null
+++ b/tests/integration/targets/vyos_ospf_interfaces/vars/main.yaml
@@ -0,0 +1,133 @@
+---
+merged:
+ commands:
+ - set interfaces ethernet eth0 ip ospf cost 50
+ - set interfaces ethernet eth0 ip ospf priority 26
+ - set interfaces ethernet eth0 ipv6 ospfv3 mtu-ignore
+ - set interfaces ethernet eth0 ipv6 ospfv3 instance-id 33
+ - set interfaces bonding bond2 ip ospf transmit-delay 45
+ - set interfaces bonding bond2 ipv6 ospfv3 passive
+ after:
+ - address_family:
+ - afi: "ipv4"
+ transmit_delay: 45
+ - afi: "ipv6"
+ passive: true
+ name: "bond2"
+ - address_family:
+ - afi: "ipv4"
+ cost: 50
+ priority: 26
+ - afi: "ipv6"
+ instance: "33"
+ mtu_ignore: true
+ name: "eth0"
+
+replaced:
+ commands:
+ - set interfaces ethernet eth0 ip ospf transmit-delay 50
+ - set interfaces ethernet eth0 ip ospf network point-to-point
+ - set interfaces ethernet eth0 ipv6 ospfv3 dead-interval 39
+ - delete interfaces ethernet eth0 ip ospf cost 50
+ - delete interfaces ethernet eth0 ipv6 ospfv3 instance-id 33
+ - delete interfaces ethernet eth0 ipv6 ospfv3 mtu-ignore
+ - set interfaces bonding bond2 ip ospf bandwidth 70
+ - set interfaces bonding bond2 ip ospf authentication md5 key-id 10 md5-key 1111111111232345
+
+ after:
+ - address_family:
+ - afi: "ipv4"
+ authentication:
+ md5_key:
+ key: "1111111111232345"
+ key_id: 10
+ bandwidth: 70
+ transmit_delay: 45
+ - afi: "ipv6"
+ passive: true
+ name: "bond2"
+ - address_family:
+ - afi: "ipv4"
+ network: "point-to-point"
+ priority: 26
+ transmit_delay: 50
+ - afi: "ipv6"
+ dead_interval: 39
+ name: "eth0"
+
+overridden:
+ commands:
+ - delete interfaces bonding bond2 ip ospf
+ - delete interfaces bonding bond2 ipv6 ospfv3
+ - set interfaces ethernet eth0 ip ospf transmit-delay 50
+ - set interfaces ethernet eth0 ip ospf network point-to-point
+ - set interfaces ethernet eth0 ipv6 ospfv3 dead-interval 39
+ - delete interfaces ethernet eth0 ip ospf cost 50
+ - delete interfaces ethernet eth0 ipv6 ospfv3 instance-id 33
+ - delete interfaces ethernet eth0 ipv6 ospfv3 mtu-ignore
+
+ after:
+ - address_family:
+ - afi: "ipv4"
+ network: "point-to-point"
+ priority: 26
+ transmit_delay: 50
+ - afi: "ipv6"
+ dead_interval: 39
+ name: "eth0"
+
+deleted:
+ commands:
+ - delete interfaces bonding bond2 ip ospf
+ - delete interfaces bonding bond2 ipv6 ospfv3
+ after:
+ - address_family:
+ - afi: "ipv4"
+ cost: 50
+ priority: 26
+ - afi: "ipv6"
+ instance: "33"
+ mtu_ignore: true
+ name: "eth0"
+
+rendered:
+ commands:
+ - set interfaces ethernet eth1 firewall in name 'INBOUND'
+ - set interfaces ethernet eth1 firewall out name 'OUTBOUND'
+ - set interfaces ethernet eth1 firewall local name 'LOCAL'
+ - set interfaces ethernet eth1 firewall local ipv6-name 'V6-LOCAL'
+ - set interfaces ethernet eth2 firewall in name 'INBOUND'
+ - set interfaces ethernet eth2 firewall out name 'OUTBOUND'
+ - set interfaces ethernet eth2 firewall local name 'LOCAL'
+ - set interfaces ethernet eth2 firewall local ipv6-name 'V6-LOCAL'
+round_trip:
+ after:
+ - name: eth0
+ - access_rules:
+ - afi: ipv4
+ rules:
+ - direction: in
+ name: INBOUND
+ - direction: local
+ name: LOCAL
+ - direction: out
+ name: OUTBOUND
+ - afi: ipv6
+ rules:
+ - direction: local
+ name: V6-LOCAL
+ name: eth1
+ - name: eth2
+ access_rules:
+ - afi: ipv4
+ rules:
+ - direction: in
+ name: INBOUND
+ - direction: local
+ name: LOCAL
+ - direction: out
+ name: OUTBOUND
+ - afi: ipv6
+ rules:
+ - direction: local
+ name: V6-LOCAL
diff --git a/tests/unit/modules/network/vyos/fixtures/vyos_ospf_interfaces_config.cfg b/tests/unit/modules/network/vyos/fixtures/vyos_ospf_interfaces_config.cfg
new file mode 100644
index 0000000..1fab55e
--- /dev/null
+++ b/tests/unit/modules/network/vyos/fixtures/vyos_ospf_interfaces_config.cfg
@@ -0,0 +1,4 @@
+set interfaces ethernet eth0 ipv6 ospfv3 instance-id '33'
+set interfaces ethernet eth0 ipv6 ospfv3 'mtu-ignore'
+set interfaces ethernet eth1 ip ospf cost '100'
+set interfaces ethernet eth1 ipv6 ospfv3 ifmtu '33'
diff --git a/tests/unit/modules/network/vyos/test_vyos_ospf_interfaces.py b/tests/unit/modules/network/vyos/test_vyos_ospf_interfaces.py
new file mode 100644
index 0000000..3250d11
--- /dev/null
+++ b/tests/unit/modules/network/vyos/test_vyos_ospf_interfaces.py
@@ -0,0 +1,461 @@
+# (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 ansible_collections.vyos.vyos.tests.unit.compat.mock import patch
+from ansible_collections.vyos.vyos.plugins.modules import vyos_ospf_interfaces
+from ansible_collections.vyos.vyos.tests.unit.modules.utils import (
+ set_module_args,
+)
+from .vyos_module import TestVyosModule, load_fixture
+
+
+class TestVyosOspfInterfacesModule(TestVyosModule):
+
+ module = vyos_ospf_interfaces
+
+ def setUp(self):
+ super(TestVyosOspfInterfacesModule, self).setUp()
+ self.mock_get_resource_connection_config = patch(
+ "ansible_collections.ansible.netcommon.plugins.module_utils.network.common.resource_module.get_resource_connection"
+ )
+ self.get_resource_connection_config = (
+ self.mock_get_resource_connection_config.start()
+ )
+
+ self.mock_execute_show_command = patch(
+ "ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.facts.ospf_interfaces.ospf_interfaces.Ospf_interfacesFacts.get_device_data"
+ )
+ self.execute_show_command = self.mock_execute_show_command.start()
+
+ def tearDown(self):
+ super(TestVyosOspfInterfacesModule, self).tearDown()
+ self.mock_get_resource_connection_config.stop()
+ self.mock_execute_show_command.stop()
+
+ def load_fixtures(self, commands=None, transport="cli", filename=None):
+ if filename is None:
+ filename = "vyos_ospf_interfaces_config.cfg"
+
+ def load_from_file(*args, **kwargs):
+ output = load_fixture(filename)
+ return output
+
+ self.execute_show_command.side_effect = load_from_file
+
+ def sort_address_family(self, entry_list):
+ for entry in entry_list:
+ if entry.get("address_family"):
+ entry["address_family"].sort(key=lambda i: i.get("afi"))
+
+ def test_vyos_ospf_interfaces_merged_new_config(self):
+ set_module_args(
+ dict(
+ config=[
+ dict(
+ name="eth0",
+ address_family=[
+ dict(
+ afi="ipv4",
+ cost=100,
+ authentication=dict(
+ plaintext_password="abcdefg!"
+ ),
+ priority=55,
+ ),
+ dict(afi="ipv6", mtu_ignore=True, instance=20),
+ ],
+ ),
+ dict(
+ name="bond2",
+ address_family=[
+ dict(
+ afi="ipv4",
+ transmit_delay=9,
+ ),
+ dict(afi="ipv6", passive=True),
+ ],
+ ),
+ ],
+ state="merged",
+ )
+ )
+ commands = [
+ "set interfaces bonding bond2 ip ospf transmit-delay 9",
+ "set interfaces bonding bond2 ipv6 ospfv3 passive",
+ "set interfaces ethernet eth0 ip ospf cost 100",
+ "set interfaces ethernet eth0 ip ospf priority 55",
+ "set interfaces ethernet eth0 ip ospf authentication plaintext-password abcdefg!",
+ "set interfaces ethernet eth0 ipv6 ospfv3 instance-id 20",
+ ]
+ self.execute_module(changed=True, commands=commands)
+
+ def test_vyos_ospf_interfaces_merged_idempotent(self):
+ set_module_args(
+ dict(
+ config=[
+ dict(
+ name="eth0",
+ address_family=[
+ dict(afi="ipv6", mtu_ignore=True, instance=33),
+ ],
+ ),
+ dict(
+ name="eth1",
+ address_family=[
+ dict(
+ afi="ipv4",
+ cost=100,
+ ),
+ dict(afi="ipv6", ifmtu=33),
+ ],
+ ),
+ ],
+ )
+ )
+ self.execute_module(changed=False, commands=[])
+
+ def test_vyos_ospf_interfaces_existing_config_merged(self):
+ set_module_args(
+ dict(
+ config=[
+ dict(
+ name="eth0",
+ address_family=[
+ dict(afi="ipv6", cost=500),
+ ],
+ ),
+ dict(
+ name="eth1",
+ address_family=[
+ dict(
+ afi="ipv4",
+ priority=100,
+ ),
+ dict(afi="ipv6", ifmtu=25),
+ ],
+ ),
+ ],
+ )
+ )
+ commands = [
+ "set interfaces ethernet eth0 ipv6 ospfv3 cost 500",
+ "set interfaces ethernet eth1 ip ospf priority 100",
+ "set interfaces ethernet eth1 ipv6 ospfv3 ifmtu 25",
+ ]
+ self.execute_module(changed=True, commands=commands)
+
+ def test_vyos_ospf_interfaces_replaced(self):
+ set_module_args(
+ dict(
+ config=[
+ dict(
+ name="eth0",
+ address_family=[
+ dict(
+ afi="ipv4",
+ cost=100,
+ authentication=dict(
+ plaintext_password="abcdefg!"
+ ),
+ priority=55,
+ ),
+ ],
+ ),
+ dict(
+ name="bond2",
+ address_family=[
+ dict(
+ afi="ipv4",
+ transmit_delay=9,
+ ),
+ dict(afi="ipv6", passive=True),
+ ],
+ ),
+ ],
+ state="replaced",
+ )
+ )
+ commands = [
+ "set interfaces bonding bond2 ip ospf transmit-delay 9",
+ "set interfaces bonding bond2 ipv6 ospfv3 passive",
+ "set interfaces ethernet eth0 ip ospf cost 100",
+ "set interfaces ethernet eth0 ip ospf priority 55",
+ "set interfaces ethernet eth0 ip ospf authentication plaintext-password abcdefg!",
+ "delete interfaces ethernet eth0 ipv6 ospfv3 instance-id 33",
+ "delete interfaces ethernet eth0 ipv6 ospfv3 mtu-ignore",
+ ]
+ self.execute_module(changed=True, commands=commands)
+
+ def test_vyos_ospf_interfaces_replaced_idempotent(self):
+ set_module_args(
+ dict(
+ config=[
+ dict(
+ name="eth0",
+ address_family=[
+ dict(afi="ipv6", mtu_ignore=True, instance=33),
+ ],
+ ),
+ dict(
+ name="eth1",
+ address_family=[
+ dict(
+ afi="ipv4",
+ cost=100,
+ ),
+ dict(afi="ipv6", ifmtu=33),
+ ],
+ ),
+ ],
+ state="replaced",
+ )
+ )
+ self.execute_module(changed=False, commands=[])
+
+ def test_vyos_ospf_interfaces_overridden(self):
+ set_module_args(
+ dict(
+ config=[
+ dict(
+ name="eth0",
+ address_family=[
+ dict(
+ afi="ipv4",
+ cost=100,
+ authentication=dict(
+ plaintext_password="abcdefg!"
+ ),
+ priority=55,
+ ),
+ ],
+ ),
+ dict(
+ name="bond2",
+ address_family=[
+ dict(
+ afi="ipv4",
+ transmit_delay=9,
+ ),
+ dict(afi="ipv6", passive=True),
+ ],
+ ),
+ ],
+ state="overridden",
+ )
+ )
+ commands = [
+ "set interfaces bonding bond2 ip ospf transmit-delay 9",
+ "set interfaces bonding bond2 ipv6 ospfv3 passive",
+ "set interfaces ethernet eth0 ip ospf cost 100",
+ "set interfaces ethernet eth0 ip ospf priority 55",
+ "set interfaces ethernet eth0 ip ospf authentication plaintext-password abcdefg!",
+ "delete interfaces ethernet eth1 ip ospf",
+ "delete interfaces ethernet eth1 ipv6 ospfv3",
+ "delete interfaces ethernet eth0 ipv6 ospfv3 mtu-ignore",
+ "delete interfaces ethernet eth0 ipv6 ospfv3 instance-id 33",
+ ]
+ self.execute_module(changed=True, commands=commands)
+
+ def test_vyos_ospf_interfaces_overridden_idempotent(self):
+ set_module_args(
+ dict(
+ config=[
+ dict(
+ name="eth0",
+ address_family=[
+ dict(afi="ipv6", mtu_ignore=True, instance=33),
+ ],
+ ),
+ dict(
+ name="eth1",
+ address_family=[
+ dict(
+ afi="ipv4",
+ cost=100,
+ ),
+ dict(afi="ipv6", ifmtu=33),
+ ],
+ ),
+ ],
+ state="overridden",
+ )
+ )
+ self.execute_module(changed=False, commands=[])
+
+ def test_vyos_ospf_interfaces_deleted(self):
+ set_module_args(
+ dict(
+ config=[
+ dict(
+ name="eth0",
+ ),
+ ],
+ state="deleted",
+ )
+ )
+ commands = ["delete interfaces ethernet eth0 ipv6 ospfv3"]
+ self.execute_module(changed=True, commands=commands)
+
+ def test_vyos_ospf_interfaces_notpresent_deleted(self):
+ set_module_args(
+ dict(
+ config=[
+ dict(
+ name="eth3",
+ ),
+ ],
+ state="deleted",
+ )
+ )
+ self.execute_module(changed=False, commands=[])
+
+ def test_vyos_ospf_interfaces_rendered(self):
+ set_module_args(
+ dict(
+ config=[
+ dict(
+ name="eth0",
+ address_family=[
+ dict(
+ afi="ipv4",
+ cost=100,
+ authentication=dict(
+ plaintext_password="abcdefg!"
+ ),
+ priority=55,
+ ),
+ dict(afi="ipv6", mtu_ignore=True, instance=20),
+ ],
+ ),
+ dict(
+ name="bond2",
+ address_family=[
+ dict(
+ afi="ipv4",
+ transmit_delay=9,
+ ),
+ dict(afi="ipv6", passive=True),
+ ],
+ ),
+ ],
+ state="rendered",
+ )
+ )
+ commands = [
+ "set interfaces ethernet eth0 ip ospf cost 100",
+ "set interfaces ethernet eth0 ip ospf authentication plaintext-password abcdefg!",
+ "set interfaces ethernet eth0 ip ospf priority 55",
+ "set interfaces ethernet eth0 ipv6 ospfv3 mtu-ignore",
+ "set interfaces ethernet eth0 ipv6 ospfv3 instance-id 20",
+ "set interfaces bonding bond2 ip ospf transmit-delay 9",
+ "set interfaces bonding bond2 ipv6 ospfv3 passive",
+ ]
+ result = self.execute_module(changed=False)
+ self.assertEqual(
+ sorted(result["rendered"]), sorted(commands), result["rendered"]
+ )
+
+ def test_vyos_ospf_interfaces_parsed(self):
+ commands = [
+ "set interfaces bonding bond2 ip ospf authentication md5 key-id 10 md5-key '1111111111232345'",
+ "set interfaces bonding bond2 ip ospf bandwidth '70'",
+ "set interfaces bonding bond2 ip ospf transmit-delay '45'",
+ "set interfaces bonding bond2 ipv6 ospfv3 'passive'",
+ "set interfaces ethernet eth0 ip ospf cost '50'",
+ "set interfaces ethernet eth0 ip ospf priority '26'",
+ "set interfaces ethernet eth0 ipv6 ospfv3 instance-id '33'",
+ "set interfaces ethernet eth0 ipv6 ospfv3 'mtu-ignore'",
+ "set interfaces ethernet eth1 ip ospf network 'point-to-point'",
+ "set interfaces ethernet eth1 ip ospf priority '26'",
+ "set interfaces ethernet eth1 ip ospf transmit-delay '50'",
+ "set interfaces ethernet eth1 ipv6 ospfv3 dead-interval '39'",
+ ]
+
+ parsed_str = "\n".join(commands)
+ set_module_args(dict(running_config=parsed_str, state="parsed"))
+ result = self.execute_module(changed=False)
+ parsed_list = [
+ {
+ "address_family": [
+ {
+ "afi": "ipv4",
+ "authentication": {
+ "md5_key": {
+ "key": "1111111111232345",
+ "key_id": 10,
+ }
+ },
+ "bandwidth": 70,
+ "transmit_delay": 45,
+ },
+ {"afi": "ipv6", "passive": True},
+ ],
+ "name": "bond2",
+ },
+ {
+ "address_family": [
+ {"afi": "ipv4", "cost": 50, "priority": 26},
+ {"afi": "ipv6", "instance": "33", "mtu_ignore": True},
+ ],
+ "name": "eth0",
+ },
+ {
+ "address_family": [
+ {
+ "afi": "ipv4",
+ "network": "point-to-point",
+ "priority": 26,
+ "transmit_delay": 50,
+ },
+ {"afi": "ipv6", "dead_interval": 39},
+ ],
+ "name": "eth1",
+ },
+ ]
+ result_list = self.sort_address_family(result["parsed"])
+ given_list = self.sort_address_family(parsed_list)
+ self.assertEqual(result_list, given_list)
+
+ def test_vyos_ospf_interfaces_gathered(self):
+ set_module_args(dict(state="gathered"))
+ result = self.execute_module(
+ changed=False, filename="vyos_ospf_interfaces_config.cfg"
+ )
+ gathered_list = [
+ {
+ "address_family": [
+ {"afi": "ipv6", "instance": "33", "mtu_ignore": True}
+ ],
+ "name": "eth0",
+ },
+ {
+ "address_family": [
+ {"afi": "ipv4", "cost": 100},
+ {"afi": "ipv6", "ifmtu": 33},
+ ],
+ "name": "eth1",
+ },
+ ]
+
+ result_list = self.sort_address_family(result["gathered"])
+ given_list = self.sort_address_family(gathered_list)
+ self.assertEqual(result_list, given_list)