diff options
26 files changed, 1743 insertions, 205 deletions
| diff --git a/plugins/module_utils/network/vyos/argspec/ospfv3/ospfv3.py b/plugins/module_utils/network/vyos/argspec/ospfv3/ospfv3.py index 60e208c3..66aaa8c4 100644 --- a/plugins/module_utils/network/vyos/argspec/ospfv3/ospfv3.py +++ b/plugins/module_utils/network/vyos/argspec/ospfv3/ospfv3.py @@ -29,80 +29,66 @@ The arg spec for the vyos_ospfv3 module  class Ospfv3Args(object):  # pylint: disable=R0903      """The arg spec for the vyos_ospfv3 module      """ +      def __init__(self, **kwargs):          pass      argument_spec = { -        'config': { -            'options': { -                'areas': { -                    'elements': 'dict', -                    'options': { -                        'area_id': { -                            'type': 'str' -                        }, -                        'export_list': { -                            'type': 'str' -                        }, -                        'import_list': { -                            'type': 'str' -                        }, -                        'range': { -                            'elements': 'dict', -                            'options': { -                                'address': { -                                    'type': 'str' -                                }, -                                'advertise': { -                                    'type': 'bool' -                                }, -                                'not_advertise': { -                                    'type': 'bool' -                                } +        "config": { +            "options": { +                "areas": { +                    "elements": "dict", +                    "options": { +                        "area_id": {"type": "str"}, +                        "export_list": {"type": "str"}, +                        "import_list": {"type": "str"}, +                        "range": { +                            "elements": "dict", +                            "options": { +                                "address": {"type": "str"}, +                                "advertise": {"type": "bool"}, +                                "not_advertise": {"type": "bool"},                              }, -                            'type': 'list' -                        } +                            "type": "list", +                        },                      }, -                    'type': 'list' +                    "type": "list",                  }, -                'parameters': { -                    'options': { -                        'router_id': { -                            'type': 'str' -                        } -                    }, -                    'type': 'dict' +                "parameters": { +                    "options": {"router_id": {"type": "str"}}, +                    "type": "dict",                  }, -                'redistribute': { -                    'elements': 'dict', -                    'options': { -                        'route_map': { -                            'type': 'str' +                "redistribute": { +                    "elements": "dict", +                    "options": { +                        "route_map": {"type": "str"}, +                        "route_type": { +                            "choices": [ +                                "bgp", +                                "connected", +                                "kernel", +                                "ripng", +                                "static", +                            ], +                            "type": "str",                          }, -                        'route_type': { -                            'choices': -                            ['bgp', 'connected', 'kernel', 'ripng', 'static'], -                            'type': -                            'str' -                        }                      }, -                    'type': 'list' -                } +                    "type": "list", +                },              }, -            'type': 'dict' -        }, -        'running_config': { -            'type': 'str' +            "type": "dict",          },          "running_config": {"type": "str"}, -        'state': { -            'choices': [ -                'merged', 'replaced', 'deleted', 'parsed', 'gathered', -                'rendered' +        "state": { +            "choices": [ +                "merged", +                "replaced", +                "deleted", +                "parsed", +                "gathered", +                "rendered",              ], -            'default': -            'merged', -            'type': -            'str' -        } +            "default": "merged", +            "type": "str", +        },      }  # pylint: disable=C0301 diff --git a/plugins/module_utils/network/vyos/config/ospfv3/ospfv3.py b/plugins/module_utils/network/vyos/config/ospfv3/ospfv3.py index 38757639..de972bc1 100644 --- a/plugins/module_utils/network/vyos/config/ospfv3/ospfv3.py +++ b/plugins/module_utils/network/vyos/config/ospfv3/ospfv3.py @@ -11,9 +11,8 @@ necessary to bring the current configuration to it's desired end-state is  created  """  from __future__ import absolute_import, division, print_function -__metaclass__ = type -import q +__metaclass__ = type  from copy import deepcopy  from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.cfg.base import ( @@ -22,27 +21,33 @@ from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.c  from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.utils import (      to_list,      remove_empties, -    search_obj_in_list +    search_obj_in_list, +) +from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.facts.facts import ( +    Facts,  ) -from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.facts.facts import Facts  from ansible.module_utils.six import iteritems  from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.utils.utils import ( -    list_diff_want_only, _in_target, _is_w_same, _bool_to_str +    list_diff_want_only, +    _in_target, +    _is_w_same, +    _bool_to_str,  ) +  class Ospfv3(ConfigBase):      """      The vyos_ospfv3 class      """      gather_subset = [ -        '!all', -        '!min', +        "!all", +        "!min",      ]      gather_network_resources = [ -        'ospfv3', +        "ospfv3",      ]      def __init__(self, module): @@ -54,10 +59,10 @@ class Ospfv3(ConfigBase):          :rtype: A dictionary          :returns: The current configuration as a dictionary          """ -        facts, _warnings = Facts(self._module).get_facts(self.gather_subset, self.gather_network_resources, data=data) -        ospfv3_facts = facts['ansible_network_resources'].get('ospfv3') -        if not ospfv3_facts: -            return [] +        facts, _warnings = Facts(self._module).get_facts( +            self.gather_subset, self.gather_network_resources, data=data +        ) +        ospfv3_facts = facts["ansible_network_resources"].get("ospfv3", {})          return ospfv3_facts      def execute_module(self): @@ -66,14 +71,14 @@ class Ospfv3(ConfigBase):          :rtype: A dictionary          :returns: The result from module execution          """ -        result = {'changed': False} +        result = {"changed": False}          warnings = list()          commands = list()          if self.state in self.ACTION_STATES:              existing_ospfv3_facts = self.get_ospfv3_facts()          else: -            existing_ospfv3_facts = [] +            existing_ospfv3_facts = {}          if self.state in self.ACTION_STATES or self.state == "rendered":              commands.extend(self.set_config(existing_ospfv3_facts)) @@ -96,11 +101,9 @@ class Ospfv3(ConfigBase):                  self._module.fail_json(                      msg="value of running_config parameter must not be empty for state parsed"                  ) -            result["parsed"] = self.get_ospfv3_facts( -                data=running_config -            ) +            result["parsed"] = self.get_ospfv3_facts(data=running_config)          else: -            changed_ospfv3_facts = [] +            changed_ospfv3_facts = {}          if self.state in self.ACTION_STATES:              result["before"] = existing_ospfv3_facts @@ -120,7 +123,7 @@ class Ospfv3(ConfigBase):          :returns: the commands necessary to migrate the current configuration                    to the desired configuration          """ -        want = self._module.params['config'] +        want = self._module.params["config"]          have = existing_ospfv3_facts          resp = self.set_state(want, have)          return to_list(resp) @@ -135,15 +138,16 @@ class Ospfv3(ConfigBase):                    to the desired configuration          """          commands = [] -        if self.state in ("merged", "replaced", "overridden", "rendered") and not w: +        if ( +            self.state in ("merged", "replaced", "overridden", "rendered") +            and not w +        ):              self._module.fail_json(                  msg="value of config parameter must not be empty for state {0}".format(                      self.state                  )              ) -        if self.state == "overridden": -            commands.extend(self._state_overridden(w, h)) -        elif self.state == "deleted": +        if self.state == "deleted":              commands.extend(self._state_deleted(w, h))          elif self.state in ("merged", "rendered"):              commands.extend(self._state_merged(w, h)) @@ -151,30 +155,6 @@ class Ospfv3(ConfigBase):              commands.extend(self._state_replaced(w, h))          return commands -    ''' -    def search_obj_in_have(self, have, w_name, key): -        """ -        This function  returns the rule-set/rule if it is present in target config. -        :param have: target config. -        :param w_name: rule-set name. -        :param type: rule_sets/rule/r_list. -        :return: rule-set/rule. -        """ -        if have: -            for item in have: -                if item[key] == w_name[key]: -                    return item -        return None - -    def search_obj_in_list(name, lst, key="name"): -        if not lst: -            return None -        else: -            for item in lst: -                if item.get(key) == name: -                    return item -    ''' -      def _state_replaced(self, want, have):          """ The command generator when state is replaced @@ -207,16 +187,8 @@ class Ospfv3(ConfigBase):                    of the provided objects          """          commands = [] -        if want: -            if have: -                if have: -                    for key, val in iteritems(want): -                        if key in have: -                            if key == 'areas': -                                key = 'area' -                            commands.append(self._compute_command(attr=key, opr=False)) -        elif have: -            commands.append('delete protocols ospfv3') +        if have: +            commands.append("delete protocols ospfv3")          return commands      def _render_ospf_param(self, want, have, opr=True): @@ -233,7 +205,7 @@ class Ospfv3(ConfigBase):          w = deepcopy(remove_empties(want))          if w:              for key, val in iteritems(w): -                    commands.extend(self._render_child_param(w, have, key, opr)) +                commands.extend(self._render_child_param(w, have, key, opr))          return commands      def _render_child_param(self, w, h, key, opr=True): @@ -247,11 +219,11 @@ class Ospfv3(ConfigBase):          :return: list of commands.          """          commands = [] -        if key == 'areas': +        if key == "areas":              commands.extend(self._render_areas(key, w, h, opr=opr)) -        elif key == 'parameters': +        elif key == "parameters":              commands.extend(self._render_dict_param(key, w, h, opr=opr)) -        elif key == 'redistribute': +        elif key == "redistribute":              commands.extend(self._render_list_dict_param(key, w, h, opr=opr))          return commands @@ -271,13 +243,23 @@ class Ospfv3(ConfigBase):          if not opr and not h:              commands.append(self._form_attr_cmd(attr=attr, opr=opr))          elif want[attr]: -            leaf_dict = {'parameters': "router_id"} +            leaf_dict = {"parameters": "router_id"}              leaf = leaf_dict[attr]              for item, value in iteritems(want[attr]): -                if opr and item in leaf and not _is_w_same(want[attr], h, item): -                    commands.append(self._form_attr_cmd(key=attr, attr=item, val=value, opr=opr)) +                if ( +                    opr +                    and item in leaf +                    and not _is_w_same(want[attr], h, item) +                ): +                    commands.append( +                        self._form_attr_cmd( +                            key=attr, attr=item, val=value, opr=opr +                        ) +                    )                  elif not opr and item in leaf and not _in_target(h, item): -                    commands.append(self._form_attr_cmd(key=attr, attr=item, opr=opr)) +                    commands.append( +                        self._form_attr_cmd(key=attr, attr=item, opr=opr) +                    )          return commands      def _render_list_dict_param(self, attr, want, have, cmd=None, opr=True): @@ -293,12 +275,14 @@ class Ospfv3(ConfigBase):          """          commands = []          h = [] -        name = {'redistribute': 'route_type', -                'range': 'address', -                } -        leaf_dict = {'redistribute': ("route_map", "route_type"), -                     'range': ("address", "advertise", "not_advertise") -                     } +        name = { +            "redistribute": "route_type", +            "range": "address", +        } +        leaf_dict = { +            "redistribute": ("route_map", "route_type"), +            "range": ("address", "advertise", "not_advertise"), +        }          leaf = leaf_dict[attr]          w = want.get(attr) or []          if have: @@ -308,27 +292,54 @@ class Ospfv3(ConfigBase):          elif w:              for w_item in w:                  for key, val in iteritems(w_item): -                    q(key) -                    q(val) -                    q(name[attr]) -                    q(w_item) -                    q(attr)                      if not cmd:                          cmd = self._compute_command(opr=opr) -                    h_item = search_obj_in_list(w_item[name[attr]], h, name[attr]) -                    if opr and key in leaf and not _is_w_same(w_item, h_item, key): -                        if key == 'route_type' or (key == 'address' and not ('advertise', 'not-advertise') not in w_item): -                            commands.append(cmd + attr + ' ' + str(val)) -                        elif key in leaf_dict['range'] and key != 'address': -                            commands.append(cmd + attr + ' ' + w_item[name[attr]] + ' ' + key.replace("_", "-")) -                        elif key == 'route_map': -                            commands.append(cmd + attr + ' ' + w_item[name[attr]] + ' ' + key.replace("_", "-") + ' ' + str(val)) -                    elif not opr and key in leaf and not _in_target(h_item, key): -                        if key in ('route_type', 'address'): -                            commands.append(cmd + attr + ' ' + str(val)) +                    h_item = search_obj_in_list( +                        w_item[name[attr]], h, name[attr] +                    ) +                    if ( +                        opr +                        and key in leaf +                        and not _is_w_same(w_item, h_item, key) +                    ): +                        if key == "route_type" or ( +                            key == "address" +                            and "advertise" not in w_item +                            and "not-advertise" not in w_item +                        ): +                            if not val: +                                cmd = cmd.replace("set", "delete") +                            commands.append(cmd + attr + " " + str(val)) +                        elif key in leaf_dict["range"] and key != "address": +                            commands.append( +                                cmd +                                + attr +                                + " " +                                + w_item[name[attr]] +                                + " " +                                + key.replace("_", "-") +                            ) +                        elif key == "route_map": +                            commands.append( +                                cmd +                                + attr +                                + " " +                                + w_item[name[attr]] +                                + " " +                                + key.replace("_", "-") +                                + " " +                                + str(val) +                            ) +                    elif ( +                        not opr and key in leaf and not _in_target(h_item, key) +                    ): +                        if key in ("route_type", "address"): +                            commands.append(cmd + attr + " " + str(val))                          else: -                            commands.append(cmd + (attr + ' ' + w_item[name[attr]] + ' ' + key)) -                    q(commands) +                            commands.append( +                                cmd +                                + (attr + " " + w_item[name[attr]] + " " + key) +                            )          return commands      def _render_areas(self, attr, want, have, opr=True): @@ -344,32 +355,68 @@ class Ospfv3(ConfigBase):          commands = []          h_lst = {}          w_lst = want.get(attr) or [] -        l_set = ("area_id, export_list, import_list") +        l_set = ("area_id", "export_list", "import_list")          if have:              h_lst = have.get(attr) or []          if not opr and not h_lst: -            commands.append(self._form_attr_cmd(attr='area', opr=opr)) +            commands.append(self._form_attr_cmd(attr="area", opr=opr))          elif w_lst:              for w_area in w_lst: -                cmd = self._compute_command(key='area', attr=_bool_to_str(w_area['area_id']), opr=opr) + ' ' -                h_area = search_obj_in_list(w_area['area_id'], h_lst, 'area_id') +                cmd = ( +                    self._compute_command( +                        key="area", +                        attr=_bool_to_str(w_area["area_id"]), +                        opr=opr, +                    ) +                    + " " +                ) +                h_area = search_obj_in_list( +                    w_area["area_id"], h_lst, "area_id" +                )                  if not opr and not h_area: -                    commands.append(self._form_attr_cmd(key='area', attr=w_area['area_id'], opr=opr)) +                    commands.append( +                        self._form_attr_cmd( +                            key="area", attr=w_area["area_id"], opr=opr +                        ) +                    )                  else:                      for key, val in iteritems(w_area): -                        if opr and key in l_set and not _is_w_same(w_area, h_area, key): -                            if key == 'area_id': -                                commands.append(self._form_attr_cmd(attr='area', val=_bool_to_str(val), opr=opr)) +                        if ( +                            opr +                            and key in l_set +                            and not _is_w_same(w_area, h_area, key) +                        ): +                            if key == "area_id": +                                commands.append( +                                    self._form_attr_cmd( +                                        attr="area", +                                        val=_bool_to_str(val), +                                        opr=opr, +                                    ) +                                )                              else: -                                commands.append(cmd + key.replace("_", "-") + ' ' + _bool_to_str(val).replace("_", "-")) +                                commands.append( +                                    cmd +                                    + key.replace("_", "-") +                                    + " " +                                    + _bool_to_str(val).replace("_", "-") +                                )                          elif not opr and key in l_set: -                            if key == 'area_id' and not _in_target(h_area, key): +                            if key == "area_id" and not _in_target( +                                h_area, key +                            ):                                  commands.append(cmd)                                  continue -                            elif key != 'area_id' and not _in_target(h_area, key): -                                commands.append(cmd + val + ' ' + key) -                        elif key == 'range': -                            commands.extend(self._render_list_dict_param(key, w_area, h_area, cmd, opr)) +                            elif key != "area_id" and not _in_target( +                                h_area, key +                            ): +                                commands.append(cmd + val + " " + key) +                        elif key == "range": +                            commands.extend( +                                self._render_list_dict_param( +                                    key, w_area, h_area, cmd, opr +                                ) +                            )          return commands      def _form_attr_cmd(self, key=None, attr=None, val=None, opr=True): @@ -381,9 +428,13 @@ class Ospfv3(ConfigBase):          :param opr: True/False.          :return: generated command.          """ -        return self._compute_command(key, attr=self._map_attrib(attr), val=val, opr=opr) +        return self._compute_command( +            key, attr=self._map_attrib(attr), val=val, opr=opr +        ) -    def _compute_command(self, key=None, attr=None, val=None, remove=False, opr=True): +    def _compute_command( +        self, key=None, attr=None, val=None, remove=False, opr=True +    ):          """          This function construct the add/delete command based on passed attributes.          :param key: parent key. @@ -411,4 +462,4 @@ class Ospfv3(ConfigBase):          :param attrib: attribute          :return: regex string          """ -        return 'disable' if attrib == 'disabled' else attrib.replace("_","-") +        return "disable" if attrib == "disabled" else attrib.replace("_", "-") diff --git a/plugins/module_utils/network/vyos/facts/facts.py b/plugins/module_utils/network/vyos/facts/facts.py index 6ead7fe7..3c87be6b 100644 --- a/plugins/module_utils/network/vyos/facts/facts.py +++ b/plugins/module_utils/network/vyos/facts/facts.py @@ -41,7 +41,7 @@ from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.facts.firew      Firewall_interfacesFacts,  )  from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.facts.ospfv3.ospfv3 import ( -   Ospfv3Facts, +    Ospfv3Facts,  )  from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.facts.legacy.base import (      Default, @@ -61,7 +61,7 @@ FACT_RESOURCE_SUBSETS = dict(      firewall_rules=Firewall_rulesFacts,      firewall_global=Firewall_globalFacts,      firewall_interfaces=Firewall_interfacesFacts, -    ospfv3=Ospfv3Facts +    ospfv3=Ospfv3Facts,  ) diff --git a/plugins/module_utils/network/vyos/facts/ospfv3/ospfv3.py b/plugins/module_utils/network/vyos/facts/ospfv3/ospfv3.py index a26f9e79..457a9636 100644 --- a/plugins/module_utils/network/vyos/facts/ospfv3/ospfv3.py +++ b/plugins/module_utils/network/vyos/facts/ospfv3/ospfv3.py @@ -9,19 +9,25 @@ 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.  """ +from __future__ import absolute_import, division, print_function + +__metaclass__ = type +  from re import findall, search, M  from copy import deepcopy  from ansible_collections.ansible.netcommon.plugins.module_utils.network.common import (      utils,  ) -from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.argspec.ospfv3.ospfv3 import Ospfv3Args +from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.argspec.ospfv3.ospfv3 import ( +    Ospfv3Args, +)  class Ospfv3Facts(object):      """ The vyos ospfv3 fact class      """ -    def __init__(self, module, subspec='config', options='options'): +    def __init__(self, module, subspec="config", options="options"):          self._module = module          self.argument_spec = Ospfv3Args.argument_spec          spec = deepcopy(self.argument_spec) @@ -56,9 +62,9 @@ class Ospfv3Facts(object):          if ospfv3:              objs = self.render_config(ospfv3)          facts = {} -        params = utils.validate_config(self.argument_spec, {'config': objs}) -        facts['ospfv3'] = utils.remove_empties(params['config']) -        ansible_facts['ansible_network_resources'].update(facts) +        params = utils.validate_config(self.argument_spec, {"config": objs}) +        facts["ospfv3"] = utils.remove_empties(params["config"]) +        ansible_facts["ansible_network_resources"].update(facts)          return ansible_facts      def render_config(self, conf): @@ -70,9 +76,13 @@ class Ospfv3Facts(object):          """          conf = "\n".join(filter(lambda x: x, conf))          config = {} -        config["parameters"] = self.parse_attrib(conf, "parameters", "parameters") +        config["parameters"] = self.parse_attrib( +            conf, "parameters", "parameters" +        )          config["areas"] = self.parse_attrib_list(conf, "area", "area_id") -        config["redistribute"] = self.parse_attrib_list(conf, "redistribute", "route_type") +        config["redistribute"] = self.parse_attrib_list( +            conf, "redistribute", "route_type" +        )          return config      def parse_attrib_list(self, conf, attrib, param): @@ -86,15 +96,15 @@ class Ospfv3Facts(object):          """          r_lst = []          if attrib == "area": -            items = findall(r"^" + attrib + " (?:\'*)(\\S+)(?:\'*)", conf, M) +            items = findall(r"^" + attrib + " (?:'*)(\\S+)(?:'*)", conf, M)          else: -            items = findall(r"" + attrib + " (?:\'*)(\\S+)(?:\'*)", conf, M) +            items = findall(r"" + attrib + " (?:'*)(\\S+)(?:'*)", conf, M)          if items:              a_lst = []              for item in set(items):                  i_regex = r" %s .+$" % item                  cfg = "\n".join(findall(i_regex, conf, M)) -                if attrib == 'area': +                if attrib == "area":                      obj = self.parse_area(cfg, item)                  else:                      obj = self.parse_attrib(cfg, attrib) @@ -112,8 +122,8 @@ class Ospfv3Facts(object):          :return: generated rule configuration dictionary.          """ -        rule = self.parse_attrib(conf, 'area_id', match=area_id) -        r_sub = {'range': self.parse_attrib_list(conf, 'range', 'address')} +        rule = self.parse_attrib(conf, "area_id", match=area_id) +        r_sub = {"range": self.parse_attrib_list(conf, "range", "address")}          rule.update(r_sub)          return rule @@ -124,11 +134,11 @@ class Ospfv3Facts(object):          :return: generated configuration dictionary          """          param_lst = { -            'area_id': ['export_list', 'import_list'], -            'redistribute': ["route_map"], -            'range': ["advertise", "not_advertise"], -            'parameters': ["router_id"] -            } +            "area_id": ["export_list", "import_list"], +            "redistribute": ["route_map"], +            "range": ["advertise", "not_advertise"], +            "parameters": ["router_id"], +        }          cfg_dict = self.parse_attr(conf, param_lst[param], match)          return cfg_dict @@ -176,7 +186,13 @@ class Ospfv3Facts(object):          :param attrib: attribute          :return: regex string          """ -        return 'disable' if attrib == "disabled" else 'enable' if attrib == "enabled" else attrib.replace("_","-") +        return ( +            "disable" +            if attrib == "disabled" +            else "enable" +            if attrib == "enabled" +            else attrib.replace("_", "-") +        )      def is_bool(self, attrib):          """ @@ -193,5 +209,5 @@ class Ospfv3Facts(object):          :param attrib: attribute.          :return: True/false.          """ -        num_set = ("ospf") +        num_set = "ospf"          return True if attrib in num_set else False diff --git a/plugins/module_utils/network/vyos/utils/utils.py b/plugins/module_utils/network/vyos/utils/utils.py index 2d5b74b7..f2986aa5 100644 --- a/plugins/module_utils/network/vyos/utils/utils.py +++ b/plugins/module_utils/network/vyos/utils/utils.py @@ -232,13 +232,21 @@ def get_route_type(address):      elif version == 4:          return "route" +  def _bool_to_str(val):      """      This function converts the bool value into string.      :param val: bool value.      :return: enable/disable.      """ -    return "enable" if str(val) == "True" else "disable" if str(val) == "False" else val +    return ( +        "enable" +        if str(val) == "True" +        else "disable" +        if str(val) == "False" +        else val +    ) +  def _is_w_same(w, h, key):      """ @@ -251,6 +259,7 @@ def _is_w_same(w, h, key):      """      return True if h and key in h and h[key] == w[key] else False +  def _in_target(h, key):      """      This function checks whether the target exist and key present in target config. diff --git a/plugins/modules/vyos_ospfv3.py b/plugins/modules/vyos_ospfv3.py index e620fe10..ae93500a 100644 --- a/plugins/modules/vyos_ospfv3.py +++ b/plugins/modules/vyos_ospfv3.py @@ -27,21 +27,23 @@ The module file for vyos_ospfv3  """  from __future__ import absolute_import, division, print_function +  __metaclass__ = type -ANSIBLE_METADATA = { -    'metadata_version': '1.1', -    'status': ['preview'], -    'supported_by': 'network' -} +ANSIBLE_METADATA = {"metadata_version": "1.1", "supported_by": "Ansible"}  DOCUMENTATION = """  ---  module: vyos_ospfv3  version_added: 2.10 -short_description: OSPFv3 resource module. +short_description: OSPFV3 resource module.  description: This resource module configures and manages attributes of OSPFv3 routes on VyOS network devices. -author: Rohit Thakur (@rohitthakur2590) +version_added: "1.0.0" +notes: +  - Tested against VyOS 1.1.8 (helium). +  - This module works with connection C(network_cli). See L(the VyOS OS Platform Options,../network/user_guide/platform_vyos.html). +author: +- Rohit Thakur (@rohitthakur2590)  options:    config:      description: A provided OSPFv3 route configuration. @@ -96,7 +98,12 @@ options:              type: str     running_config:      description: -      - The configuration to be parsed. +      - This option is used only with state I(parsed). +      - The value of this option should be the output received from the VyOS device by executing +        the command B(show configuration commands | grep ospfv3). +      - 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: @@ -112,22 +119,493 @@ options:      default: merged  """  EXAMPLES = """ +# Using merged +# +# Before state: +# ------------- +# +# vyos@vyos# run show  configuration commands | grep ospfv3 +# +# +- name: Merge the provided configuration with the exisiting running configuration +      vyos.vyos.vyos_ospfv3: +        config: +           redistribute: +             - route_type: 'bgp' +           parameters: +             router_id: '192.0.2.10' +           areas: +             - area_id: '2' +               export_list: 'export1' +               import_list: 'import1' +               range: +                 - address: '2001:db10::/32' +                 - address: '2001:db20::/32' +                 - address: '2001:db30::/32' +             - area_id: '3' +               range: +                 - address: '2001:db40::/32' +        state: merged +# +# +# ------------------------- +# Module Execution Result +# ------------------------- +# +# before": {} +# +#    "commands": [ +#       "set protocols ospfv3 redistribute bgp", +#       "set protocols ospfv3 parameters router-id '192.0.2.10'", +#       "set protocols ospfv3 area 2 range 2001:db10::/32", +#       "set protocols ospfv3 area 2 range 2001:db20::/32", +#       "set protocols ospfv3 area 2 range 2001:db30::/32", +#       "set protocols ospfv3 area '2'", +#       "set protocols ospfv3 area 2 export-list export1", +#       "set protocols ospfv3 area 2 import-list import1", +#       "set protocols ospfv3 area '3'", +#       "set protocols ospfv3 area 3 range 2001:db40::/32" +#    ] +# +# "after": { +#        "areas": [ +#            { +#                "area_id": "2", +#                "export_list": "export1", +#                "import_list": "import1", +#                "range": [ +#                    { +#                        "address": "2001:db10::/32" +#                    }, +#                    { +#                        "address": "2001:db20::/32" +#                    }, +#                    { +#                        "address": "2001:db30::/32" +#                    } +#                ] +#            }, +#            { +#                "area_id": "3", +#                "range": [ +#                    { +#                        "address": "2001:db40::/32" +#                    } +#                ] +#            } +#        ], +#        "parameters": { +#            "router_id": "192.0.2.10" +#        }, +#        "redistribute": [ +#            { +#                "route_type": "bgp" +#            } +#        ] +#    } +# +# After state: +# ------------- +# +# vyos@192# run show configuration commands | grep ospfv3 +# set protocols ospfv3 area 2 export-list 'export1' +# set protocols ospfv3 area 2 import-list 'import1' +# set protocols ospfv3 area 2 range '2001:db10::/32' +# set protocols ospfv3 area 2 range '2001:db20::/32' +# set protocols ospfv3 area 2 range '2001:db30::/32' +# set protocols ospfv3 area 3 range '2001:db40::/32' +# set protocols ospfv3 parameters router-id '192.0.2.10' +# set protocols ospfv3 redistribute 'bgp' +# Using replaced +# +# Before state: +# ------------- +# +# vyos@192# run show configuration commands | grep ospfv3 +# set protocols ospfv3 area 2 export-list 'export1' +# set protocols ospfv3 area 2 import-list 'import1' +# set protocols ospfv3 area 2 range '2001:db10::/32' +# set protocols ospfv3 area 2 range '2001:db20::/32' +# set protocols ospfv3 area 2 range '2001:db30::/32' +# set protocols ospfv3 area 3 range '2001:db40::/32' +# set protocols ospfv3 parameters router-id '192.0.2.10' +# set protocols ospfv3 redistribute 'bgp' +# +- name: Replace ospfv3 routes attributes configuration. +      vyos.vyos.vyos_ospfv3: +        config: +           redistribute: +             - route_type: 'bgp' +           parameters: +             router_id: '192.0.2.10' +           areas: +             - area_id: '2' +               export_list: 'export1' +               import_list: 'import1' +               range: +                 - address: '2001:db10::/32' +                 - address: '2001:db30::/32' +                 - address: '2001:db50::/32' +             - area_id: '4' +               range: +                 - address: '2001:db60::/32' +        state: replaced +# +# +# ------------------------- +# Module Execution Result +# ------------------------- +# +#    "before": { +#        "areas": [ +#            { +#                "area_id": "2", +#                "export_list": "export1", +#                "import_list": "import1", +#                "range": [ +#                    { +#                        "address": "2001:db10::/32" +#                    }, +#                    { +#                        "address": "2001:db20::/32" +#                    }, +#                    { +#                        "address": "2001:db30::/32" +#                    } +#                ] +#            }, +#            { +#                "area_id": "3", +#                "range": [ +#                    { +#                        "address": "2001:db40::/32" +#                    } +#                ] +#            } +#        ], +#        "parameters": { +#            "router_id": "192.0.2.10" +#        }, +#        "redistribute": [ +#            { +#                "route_type": "bgp" +#            } +#        ] +#    } +# +# "commands": [ +#     "delete protocols ospfv3 area 2 range 2001:db20::/32", +#     "delete protocols ospfv3 area 3", +#     "set protocols ospfv3 area 2 range 2001:db50::/32", +#     "set protocols ospfv3 area '4'", +#     "set protocols ospfv3 area 4 range 2001:db60::/32" +#    ] +# +#    "after": { +#        "areas": [ +#            { +#                "area_id": "2", +#                "export_list": "export1", +#                "import_list": "import1", +#                "range": [ +#                    { +#                        "address": "2001:db10::/32" +#                    }, +#                    { +#                        "address": "2001:db30::/32" +#                    }, +#                    { +#                        "address": "2001:db50::/32" +#                    } +#                ] +#            }, +#            { +#                "area_id": "4", +#                "range": [ +#                    { +#                        "address": "2001:db60::/32" +#                    } +#                ] +#            } +#        ], +#        "parameters": { +#            "router_id": "192.0.2.10" +#        }, +#        "redistribute": [ +#            { +#                "route_type": "bgp" +#            } +#        ] +#    } +# +# After state: +# ------------- +# +# vyos@192# run show configuration commands | grep ospfv3 +# set protocols ospfv3 area 2 export-list 'export1' +# set protocols ospfv3 area 2 import-list 'import1' +# set protocols ospfv3 area 2 range '2001:db10::/32' +# set protocols ospfv3 area 2 range '2001:db30::/32' +# set protocols ospfv3 area 2 range '2001:db50::/32' +# set protocols ospfv3 area 4 range '2001:db60::/32' +# set protocols ospfv3 parameters router-id '192.0.2.10' +# set protocols ospfv3 redistribute 'bgp' +# Using rendered +# +# +- name: Render the commands for provided  configuration +      vyos.vyos.vyos_ospfv3: +        config: +           redistribute: +             - route_type: 'bgp' +           parameters: +             router_id: '192.0.2.10' +           areas: +             - area_id: '2' +               export_list: 'export1' +               import_list: 'import1' +               range: +                 - address: '2001:db10::/32' +                 - address: '2001:db20::/32' +                 - address: '2001:db30::/32' +             - area_id: '3' +               range: +                 - address: '2001:db40::/32' +        state: rendered +# +# +# ------------------------- +# Module Execution Result +# ------------------------- +# +# +# "rendered": [ +#        [ +#       "set protocols ospfv3 redistribute bgp", +#       "set protocols ospfv3 parameters router-id '192.0.2.10'", +#       "set protocols ospfv3 area 2 range 2001:db10::/32", +#       "set protocols ospfv3 area 2 range 2001:db20::/32", +#       "set protocols ospfv3 area 2 range 2001:db30::/32", +#       "set protocols ospfv3 area '2'", +#       "set protocols ospfv3 area 2 export-list export1", +#       "set protocols ospfv3 area 2 import-list import1", +#       "set protocols ospfv3 area '3'", +#       "set protocols ospfv3 area 3 range 2001:db40::/32" +#    ] +# Using parsed +# +# +- name: Parse the commands to provide structured configuration. +      vyos.vyos.vyos_ospfv3: +        running_config: +          "set protocols ospfv3 area 2 export-list 'export1' +set protocols ospfv3 area 2 import-list 'import1' +set protocols ospfv3 area 2 range '2001:db10::/32' +set protocols ospfv3 area 2 range '2001:db20::/32' +set protocols ospfv3 area 2 range '2001:db30::/32' +set protocols ospfv3 area 3 range '2001:db40::/32' +set protocols ospfv3 parameters router-id '192.0.2.10' +set protocols ospfv3 redistribute 'bgp'" +        state: parsed +# +# +# ------------------------- +# Module Execution Result +# ------------------------- +# +# +# "parsed": { +#        "areas": [ +#            { +#                "area_id": "2", +#                "export_list": "export1", +#                "import_list": "import1", +#                "range": [ +#                    { +#                        "address": "2001:db10::/32" +#                    }, +#                    { +#                        "address": "2001:db20::/32" +#                    }, +#                    { +#                        "address": "2001:db30::/32" +#                    } +#                ] +#            }, +#            { +#                "area_id": "3", +#                "range": [ +#                    { +#                        "address": "2001:db40::/32" +#                    } +#                ] +#            } +#        ], +#        "parameters": { +#            "router_id": "192.0.2.10" +#        }, +#        "redistribute": [ +#            { +#                "route_type": "bgp" +#            } +#        ] +#    } +# Using gathered +# +# Before state: +# ------------- +# +# vyos@192# run show configuration commands | grep ospfv3 +# set protocols ospfv3 area 2 export-list 'export1' +# set protocols ospfv3 area 2 import-list 'import1' +# set protocols ospfv3 area 2 range '2001:db10::/32' +# set protocols ospfv3 area 2 range '2001:db20::/32' +# set protocols ospfv3 area 2 range '2001:db30::/32' +# set protocols ospfv3 area 3 range '2001:db40::/32' +# set protocols ospfv3 parameters router-id '192.0.2.10' +# set protocols ospfv3 redistribute 'bgp' +# +- name: Gather ospfv3 routes config with provided configurations +      vyos.vyos.vyos_ospfv3: +          config: +          state: gathered +# +# +# ------------------------- +# Module Execution Result +# ------------------------- +# +#    "gathered": { +#        "areas": [ +#            { +#                "area_id": "2", +#                "export_list": "export1", +#                "import_list": "import1", +#                "range": [ +#                    { +#                        "address": "2001:db10::/32" +#                    }, +#                    { +#                        "address": "2001:db20::/32" +#                    }, +#                    { +#                        "address": "2001:db30::/32" +#                    } +#                ] +#            }, +#            { +#                "area_id": "3", +#                "range": [ +#                    { +#                        "address": "2001:db40::/32" +#                    } +#                ] +#            } +#        ], +#        "parameters": { +#            "router_id": "192.0.2.10" +#        }, +#        "redistribute": [ +#            { +#                "route_type": "bgp" +#            } +#        ] +#    } +# +# After state: +# ------------- +# +# vyos@192# run show configuration commands | grep ospfv3 +# set protocols ospfv3 area 2 export-list 'export1' +# set protocols ospfv3 area 2 import-list 'import1' +# set protocols ospfv3 area 2 range '2001:db10::/32' +# set protocols ospfv3 area 2 range '2001:db20::/32' +# set protocols ospfv3 area 2 range '2001:db30::/32' +# set protocols ospfv3 area 3 range '2001:db40::/32' +# set protocols ospfv3 parameters router-id '192.0.2.10' +# set protocols ospfv3 redistribute 'bgp' - - - +# Using deleted +# +# Before state +# ------------- +# +# vyos@192# run show configuration commands | grep ospfv3 +# set protocols ospfv3 area 2 export-list 'export1' +# set protocols ospfv3 area 2 import-list 'import1' +# set protocols ospfv3 area 2 range '2001:db10::/32' +# set protocols ospfv3 area 2 range '2001:db20::/32' +# set protocols ospfv3 area 2 range '2001:db30::/32' +# set protocols ospfv3 area 3 range '2001:db40::/32' +# set protocols ospfv3 parameters router-id '192.0.2.10' +# set protocols ospfv3 redistribute 'bgp' +# +- name: Delete attributes of ospfv3 routes. +      vyos.vyos.vyos_ospfv3: +        config: +        state: deleted +# +# +# ------------------------ +# Module Execution Results +# ------------------------ +# +#    "before": { +#        "areas": [ +#            { +#                "area_id": "2", +#                "export_list": "export1", +#                "import_list": "import1", +#                "range": [ +#                    { +#                        "address": "2001:db10::/32" +#                    }, +#                    { +#                        "address": "2001:db20::/32" +#                    }, +#                    { +#                        "address": "2001:db30::/32" +#                    } +#                ] +#            }, +#            { +#                "area_id": "3", +#                "range": [ +#                    { +#                        "address": "2001:db40::/32" +#                    } +#                ] +#            } +#        ], +#        "parameters": { +#            "router_id": "192.0.2.10" +#        }, +#        "redistribute": [ +#            { +#                "route_type": "bgp" +#            } +#        ] +#    } +# "commands": [ +#        "delete protocols ospfv3" +#    ] +# +# "after": {} +# After state +# ------------ +# vyos@192# run show configuration commands | grep ospfv3  """ @@ -135,12 +613,14 @@ RETURN = """  before:    description: The configuration prior to the model invocation.    returned: always +  type: dict    sample: >      The configuration returned will always be in the same format       of the parameters above.  after:    description: The resulting configuration model invocation.    returned: when changed +  type: dict    sample: >      The configuration returned will always be in the same format       of the parameters above. @@ -148,13 +628,18 @@ commands:    description: The set of commands pushed to the remote device.    returned: always    type: list -  sample: ['command 1', 'command 2', 'command 3'] +  sample: ['set protocols ospf parameters router-id 192.0.1.1', +           'set protocols ospfv3 area 2 range '2001:db10::/32']  """  from ansible.module_utils.basic import AnsibleModule -from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.argspec.ospfv3.ospfv3 import Ospfv3Args -from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.config.ospfv3.ospfv3 import Ospfv3 +from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.argspec.ospfv3.ospfv3 import ( +    Ospfv3Args, +) +from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.config.ospfv3.ospfv3 import ( +    Ospfv3, +)  def main(): @@ -166,6 +651,7 @@ def main():      required_if = [          ("state", "merged", ("config",)),          ("state", "replaced", ("config",)), +        ("state", "rendered", ("config",)),          ("state", "parsed", ("running_config",)),      ]      mutually_exclusive = [("config", "running_config")] @@ -180,5 +666,5 @@ def main():      module.exit_json(**result) -if __name__ == '__main__': +if __name__ == "__main__":      main() diff --git a/tests/integration/targets/vyos_ospfv3/defaults/main.yaml b/tests/integration/targets/vyos_ospfv3/defaults/main.yaml new file mode 100644 index 00000000..852a6bee --- /dev/null +++ b/tests/integration/targets/vyos_ospfv3/defaults/main.yaml @@ -0,0 +1,3 @@ +--- +testcase: '[^_].*' +test_items: [] diff --git a/tests/integration/targets/vyos_ospfv3/meta/main.yaml b/tests/integration/targets/vyos_ospfv3/meta/main.yaml new file mode 100644 index 00000000..7413320e --- /dev/null +++ b/tests/integration/targets/vyos_ospfv3/meta/main.yaml @@ -0,0 +1,3 @@ +--- +dependencies: +  - prepare_vyos_tests diff --git a/tests/integration/targets/vyos_ospfv3/tasks/cli.yaml b/tests/integration/targets/vyos_ospfv3/tasks/cli.yaml new file mode 100644 index 00000000..93eb2fe4 --- /dev/null +++ b/tests/integration/targets/vyos_ospfv3/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_ospfv3/tasks/main.yaml b/tests/integration/targets/vyos_ospfv3/tasks/main.yaml new file mode 100644 index 00000000..a3db933e --- /dev/null +++ b/tests/integration/targets/vyos_ospfv3/tasks/main.yaml @@ -0,0 +1,4 @@ +--- +- include: cli.yaml +  tags: +    - cli diff --git a/tests/integration/targets/vyos_ospfv3/tests/cli/_parsed_config.cfg b/tests/integration/targets/vyos_ospfv3/tests/cli/_parsed_config.cfg new file mode 100644 index 00000000..5e012d5a --- /dev/null +++ b/tests/integration/targets/vyos_ospfv3/tests/cli/_parsed_config.cfg @@ -0,0 +1,8 @@ +set protocols ospfv3 area 2 export-list 'export1' +set protocols ospfv3 area 2 import-list 'import1' +set protocols ospfv3 area 2 range '2001:db10::/32' +set protocols ospfv3 area 2 range '2001:db20::/32' +set protocols ospfv3 area 2 range '2001:db30::/32' +set protocols ospfv3 area 3 range '2001:db40::/32' +set protocols ospfv3 parameters router-id '192.0.2.10' +set protocols ospfv3 redistribute 'bgp' diff --git a/tests/integration/targets/vyos_ospfv3/tests/cli/_populate.yaml b/tests/integration/targets/vyos_ospfv3/tests/cli/_populate.yaml new file mode 100644 index 00000000..fb66d0a5 --- /dev/null +++ b/tests/integration/targets/vyos_ospfv3/tests/cli/_populate.yaml @@ -0,0 +1,13 @@ +--- +- name: Setup +  vars: +    lines: "set protocols ospfv3 area 2 export-list 'export1' \n +            set protocols ospfv3 area 2 import-list 'import1' \n +            set protocols ospfv3 area 2 range '2001:db10::/32' \n +            set protocols ospfv3 area 2 range '2001:db20::/32' \n +            set protocols ospfv3 area 2 range '2001:db30::/32' \n +            set protocols ospfv3 area 3 range '2001:db40::/32' \n +            set protocols ospfv3 parameters router-id '192.0.2.10' \n +            set protocols ospfv3 redistribute 'bgp'" +  ansible.netcommon.cli_config: +    config: '{{ lines }}' diff --git a/tests/integration/targets/vyos_ospfv3/tests/cli/_remove_config.yaml b/tests/integration/targets/vyos_ospfv3/tests/cli/_remove_config.yaml new file mode 100644 index 00000000..2a475050 --- /dev/null +++ b/tests/integration/targets/vyos_ospfv3/tests/cli/_remove_config.yaml @@ -0,0 +1,6 @@ +--- +- name: Remove Config +  vars: +    lines: "delete protocols ospfv3\n" +  ansible.netcommon.cli_config: +    config: '{{ lines }}' diff --git a/tests/integration/targets/vyos_ospfv3/tests/cli/deleted.yaml b/tests/integration/targets/vyos_ospfv3/tests/cli/deleted.yaml new file mode 100644 index 00000000..d400ff18 --- /dev/null +++ b/tests/integration/targets/vyos_ospfv3/tests/cli/deleted.yaml @@ -0,0 +1,48 @@ +--- +- debug: +    msg: Start vyos_ospfv3 deleted integration tests ansible_connection={{ +      ansible_connection }} + +- include_tasks: _populate.yaml + +- block: + +    - name: Delete attributes of firewall. +      register: result +      vyos.vyos.vyos_ospfv3: &id001 +        config: +        state: deleted + +    - name: Assert that the before dicts were correctly generated +      assert: +        that: +          - "{{ populate == result['before'] }}" + +    - name: Assert that the correct set of commands were generated +      assert: +        that: +          - "{{ deleted['commands'] | symmetric_difference(result['commands']) |length\ +            \ == 0 }}" + +    - name: Assert that the after dicts were correctly generated +      assert: +        that: +          - "{{ deleted['after'] == result['after'] }}" + +    - name: Delete attributes of given interfaces (IDEMPOTENT) +      register: result +      vyos.vyos.vyos_ospfv3: *id001 + +    - name: Assert that the previous task was idempotent +      assert: +        that: +          - result.changed == false +          - result.commands|length == 0 + +    - name: Assert that the before dicts were correctly generated +      assert: +        that: +          - "{{ deleted['after'] == result['before'] }}" +  always: + +    - include_tasks: _remove_config.yaml diff --git a/tests/integration/targets/vyos_ospfv3/tests/cli/empty_config.yaml b/tests/integration/targets/vyos_ospfv3/tests/cli/empty_config.yaml new file mode 100644 index 00000000..fec61abf --- /dev/null +++ b/tests/integration/targets/vyos_ospfv3/tests/cli/empty_config.yaml @@ -0,0 +1,49 @@ +--- +- debug: +    msg: START vyos_ospfv3 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_ospfv3: +    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_ospfv3: +    config: +    state: replaced + +- assert: +    that: +      - result.msg == 'value of config parameter must not be empty for state replaced' + +- name: Parsed with empty running_config should give appropriate error message +  register: result +  ignore_errors: true +  vyos.vyos.vyos_ospfv3: +    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_ospfv3: +    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_ospfv3/tests/cli/gathered.yaml b/tests/integration/targets/vyos_ospfv3/tests/cli/gathered.yaml new file mode 100644 index 00000000..6645b99f --- /dev/null +++ b/tests/integration/targets/vyos_ospfv3/tests/cli/gathered.yaml @@ -0,0 +1,25 @@ +--- +- debug: +    msg: START vyos_ospfv3 gathered integration tests on connection={{ +      ansible_connection }} + +- include_tasks: _remove_config.yaml + +- include_tasks: _populate.yaml + +- block: + +    - name: Gather the provided configuration with the exisiting running configuration +      register: result +      vyos.vyos.vyos_ospfv3: +        config: +        state: gathered + +    - name: Assert that gathered dicts was correctly generated +      assert: +        that: +          - "{{ populate  == result['gathered'] }}" + +  always: + +    - include_tasks: _remove_config.yaml diff --git a/tests/integration/targets/vyos_ospfv3/tests/cli/merged.yaml b/tests/integration/targets/vyos_ospfv3/tests/cli/merged.yaml new file mode 100644 index 00000000..93095009 --- /dev/null +++ b/tests/integration/targets/vyos_ospfv3/tests/cli/merged.yaml @@ -0,0 +1,62 @@ +--- +- debug: +    msg: START vyos_ospfv3 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_ospfv3: &id001 +        config: +          areas: +            - area_id: '2' +              export_list: 'export1' +              import_list: 'import1' +              range: +                - address: '2001:db10::/32' +                - address: '2001:db20::/32' +                - address: '2001:db30::/32' +            - area_id: '3' +              range: +                - address: '2001:db40::/32' +          parameters: +            router_id: '192.0.2.10' +          redistribute: +            - route_type: 'bgp' +        state: merged + +    - name: Assert that before dicts were correctly generated +      assert: +        that: "{{ merged['before'] == result['before'] }}" + +    - name: Assert that correct set of commands were generated +      assert: +        that: +          - "{{ merged['commands'] | symmetric_difference(result['commands']) |length\ +            \ == 0 }}" + +    - name: Assert that after dicts was correctly generated +      assert: +        that: +          - "{{ merged['after'] == result['after'] }}" + +    - name: Merge the provided configuration with the existing running configuration +        (IDEMPOTENT) +      register: result +      vyos.vyos.vyos_ospfv3: *id001 + +    - name: Assert that the previous task was idempotent +      assert: +        that: +          - result['changed'] == false + +    - name: Assert that before dicts were correctly generated +      assert: +        that: +          - "{{ merged['after'] == result['before'] }}" +  always: + +    - include_tasks: _remove_config.yaml diff --git a/tests/integration/targets/vyos_ospfv3/tests/cli/merged_update.yaml b/tests/integration/targets/vyos_ospfv3/tests/cli/merged_update.yaml new file mode 100644 index 00000000..a65cfaf4 --- /dev/null +++ b/tests/integration/targets/vyos_ospfv3/tests/cli/merged_update.yaml @@ -0,0 +1,61 @@ +--- +- debug: +    msg: START vyos_ospfv3 merged integration tests on connection={{ ansible_connection +      }} + +- include_tasks: _remove_config.yaml + +- include_tasks: _populate.yaml + +- block: + +    - name: Merge the provided configuration with the exisiting running configuration +      register: result +      vyos.vyos.vyos_ospfv3: &id001 +        config: +          areas: +            - area_id: '2' +              range: +                - address: '2001:db10::/32' +            - area_id: '3' +              range: +                - address: '2001:db40::/32' +                - address: '2001:db70::/32' +          parameters: +            router_id: '192.0.2.10' +          redistribute: +            - route_type: 'bgp' +        state: merged + +    - name: Assert that before dicts were correctly generated +      assert: +        that: "{{ populate == result['before'] }}" + +    - name: Assert that correct set of commands were generated +      assert: +        that: +          - "{{ merged_update['commands'] | symmetric_difference(result['commands']) |length\ +            \ == 0 }}" + +    - name: Assert that after dicts was correctly generated +      assert: +        that: +          - "{{ merged_update['after'] == result['after'] }}" + +    - name: Merge the provided configuration with the existing running configuration +        (IDEMPOTENT) +      register: result +      vyos.vyos.vyos_ospfv3: *id001 + +    - name: Assert that the previous task was idempotent +      assert: +        that: +          - result['changed'] == false + +    - name: Assert that before dicts were correctly generated +      assert: +        that: +          - "{{ merged_update['after'] == result['before'] }}" +  always: + +    - include_tasks: _remove_config.yaml
\ No newline at end of file diff --git a/tests/integration/targets/vyos_ospfv3/tests/cli/parsed.yaml b/tests/integration/targets/vyos_ospfv3/tests/cli/parsed.yaml new file mode 100644 index 00000000..62870831 --- /dev/null +++ b/tests/integration/targets/vyos_ospfv3/tests/cli/parsed.yaml @@ -0,0 +1,15 @@ +--- +- debug: +    msg: START vyos_ospfv3 parsed integration tests on connection={{ ansible_connection +      }} + +- name: Parse externally provided ospfv3 config to agnostic model +  register: result +  vyos.vyos.vyos_ospfv3: +    running_config: "{{ lookup('file', '_parsed_config.cfg') }}" +    state: parsed + +- name: Assert that config was correctly parsed +  assert: +    that: +      - "{{ parsed['after'] == result['parsed'] }}" diff --git a/tests/integration/targets/vyos_ospfv3/tests/cli/rendered.yaml b/tests/integration/targets/vyos_ospfv3/tests/cli/rendered.yaml new file mode 100644 index 00000000..3f714ced --- /dev/null +++ b/tests/integration/targets/vyos_ospfv3/tests/cli/rendered.yaml @@ -0,0 +1,38 @@ +--- +- debug: +    msg: START vyos_ospfv3 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_ospfv3: +        config: +          redistribute: +            - route_type: 'bgp' +          parameters: +            router_id: '192.0.2.10' +          areas: +            - area_id: '2' +              export_list: 'export1' +              import_list: 'import1' +              range: +                - address: '2001:db10::/32' +                - address: '2001:db20::/32' +                - address: '2001:db30::/32' +            - area_id: '3' +              range: +                - address: '2001:db40::/32' +        state: rendered + +    - name: Assert that correct set of commands were generated +      assert: +        that: +          - "{{ rendered['commands'] | symmetric_difference(result['rendered'])\ +            \ |length == 0 }}" + +- debug: +    msg: END vyos_ospfv3 rendered integration tests on connection={{ ansible_connection }} diff --git a/tests/integration/targets/vyos_ospfv3/tests/cli/replaced.yaml b/tests/integration/targets/vyos_ospfv3/tests/cli/replaced.yaml new file mode 100644 index 00000000..74d25dbf --- /dev/null +++ b/tests/integration/targets/vyos_ospfv3/tests/cli/replaced.yaml @@ -0,0 +1,66 @@ +--- +- debug: +    msg: START vyos_ospfv3 replaced integration tests on connection={{ +      ansible_connection }} + +- include_tasks: _remove_config.yaml + +- include_tasks: _populate.yaml + +- block: + +    - name: Replace device configurations of listed ospfv3 routes with provided configurations +      register: result +      vyos.vyos.vyos_ospfv3: &id001 +        config: +          redistribute: +            - route_type: 'bgp' +          parameters: +            router_id: '192.0.2.10' +          areas: +            - area_id: '2' +              export_list: 'export1' +              import_list: 'import1' + +              range: +                - address: '2001:db10::/32' +                - address: '2001:db30::/32' +                - address: '2001:db50::/32' +            - area_id: '4' +              range: +                - address: '2001:db60::/32' +        state: replaced + +    - name: Assert that correct set of commands were generated +      assert: +        that: +          - "{{ replaced['commands'] | symmetric_difference(result['commands'])\ +            \ |length == 0 }}" + +    - name: Assert that before dicts are correctly generated +      assert: +        that: +          - "{{ populate == result['before'] }}" + +    - name: Assert that after dict is correctly generated +      assert: +        that: +          - "{{ replaced['after'] == result['after'] }}" + +    - name: Replace device configurations of listed ospfv3 routes with provided configurarions +        (IDEMPOTENT) +      register: result +      vyos.vyos.vyos_ospfv3: *id001 + +    - name: Assert that task was idempotent +      assert: +        that: +          - result['changed'] == false + +    - name: Assert that before dict is correctly generated +      assert: +        that: +          - "{{ replaced['after'] == result['before'] }}" +  always: + +    - include_tasks: _remove_config.yaml diff --git a/tests/integration/targets/vyos_ospfv3/tests/cli/rtt.yaml b/tests/integration/targets/vyos_ospfv3/tests/cli/rtt.yaml new file mode 100644 index 00000000..d8175540 --- /dev/null +++ b/tests/integration/targets/vyos_ospfv3/tests/cli/rtt.yaml @@ -0,0 +1,75 @@ +--- +- debug: +    msg: START vyos_ospfv3 round trip integration tests on connection={{ +      ansible_connection }} + +- include_tasks: _remove_config.yaml + +- block: + +    - name: Apply the provided configuration (base config) +      register: base_config +      vyos.vyos.vyos_ospfv3: +        config: +          areas: +            - area_id: '2' +              export_list: 'export1' +              import_list: 'import1' +              range: +                - address: '2001:db10::/32' +                - address: '2001:db20::/32' +                - address: '2001:db30::/32' +            - area_id: '3' +              range: +                - address: '2001:db40::/32' +          parameters: +            router_id: '192.0.2.10' +          redistribute: +            - route_type: 'bgp' +        state: merged + +    - name: Gather ospfv3 facts +      vyos.vyos.vyos_facts: +        gather_subset: +          - default +        gather_network_resources: +          - ospfv3 + +    - name: Apply the provided configuration (config to be reverted) +      register: result +      vyos.vyos.vyos_ospfv3: +        config: +          redistribute: +            - route_type: 'bgp' +          parameters: +            router_id: '192.0.2.10' +          areas: +            - area_id: '2' +              export_list: 'export1' +              import_list: 'import1' + +              range: +                - address: '2001:db10::/32' +                - address: '2001:db30::/32' +                - address: '2001:db50::/32' +            - area_id: '4' +              range: +                - address: '2001:db60::/32' +        state: replaced + +    - name: Assert that changes were applied +      assert: +        that: "{{ round_trip['after'] == result['after'] }}" + +    - name: Revert back to base config using facts round trip +      register: revert +      vyos.vyos.vyos_ospfv3: +        config: "{{ ansible_facts['network_resources']['ospfv3'] }}" +        state: replaced + +    - name: Assert that config was reverted +      assert: +        that: "{{ base_config['after'] == revert['after']}}" +  always: + +    - include_tasks: _remove_config.yaml diff --git a/tests/integration/targets/vyos_ospfv3/vars/main.yaml b/tests/integration/targets/vyos_ospfv3/vars/main.yaml new file mode 100644 index 00000000..d384e2a1 --- /dev/null +++ b/tests/integration/targets/vyos_ospfv3/vars/main.yaml @@ -0,0 +1,140 @@ +--- +merged: +  before: {} +  commands: +    - set protocols ospfv3 redistribute bgp +    - set protocols ospfv3 parameters router-id '192.0.2.10' +    - set protocols ospfv3 area 2 range 2001:db10::/32 +    - set protocols ospfv3 area 2 range 2001:db20::/32 +    - set protocols ospfv3 area 2 range 2001:db30::/32 +    - set protocols ospfv3 area '2' +    - set protocols ospfv3 area 2 export-list export1 +    - set protocols ospfv3 area 2 import-list import1 +    - set protocols ospfv3 area '3' +    - set protocols ospfv3 area 3 range 2001:db40::/32 +  after: +      areas: +        - area_id: '2' +          export_list: 'export1' +          import_list: 'import1' +          range: +            - address: '2001:db10::/32' +            - address: '2001:db20::/32' +            - address: '2001:db30::/32' +        - area_id: '3' +          range: +            - address: '2001:db40::/32' +      parameters: +        router_id: '192.0.2.10' +      redistribute: +        - route_type: 'bgp' + +merged_update: +  commands: +    - set protocols ospfv3 area 3 range 2001:db70::/32 +  after: +      areas: +        - area_id: '2' +          export_list: 'export1' +          import_list: 'import1' +          range: +            - address: '2001:db10::/32' +            - address: '2001:db20::/32' +            - address: '2001:db30::/32' +        - area_id: '3' +          range: +            - address: '2001:db40::/32' +            - address: '2001:db70::/32' +      parameters: +        router_id: '192.0.2.10' +      redistribute: +        - route_type: 'bgp' +populate: +  areas: +    - area_id: '2' +      export_list: 'export1' +      import_list: 'import1' +      range: +        - address: '2001:db10::/32' +        - address: '2001:db20::/32' +        - address: '2001:db30::/32' +    - area_id: '3' +      range: +        - address: '2001:db40::/32' +  parameters: +    router_id: '192.0.2.10' +  redistribute: +    - route_type: 'bgp' +replaced: +  commands: +    - delete protocols ospfv3 area 2 range 2001:db20::/32 +    - delete protocols ospfv3 area 3 +    - set protocols ospfv3 area 2 range 2001:db50::/32 +    - set protocols ospfv3 area '4' +    - set protocols ospfv3 area 4 range 2001:db60::/32 +  after: +    areas: +      - area_id: '2' +        export_list: 'export1' +        import_list: 'import1' +        range: +          - address: '2001:db10::/32' +          - address: '2001:db30::/32' +          - address: '2001:db50::/32' +      - area_id: '4' +        range: +          - address: '2001:db60::/32' +    parameters: +      router_id: '192.0.2.10' +    redistribute: +      - route_type: 'bgp' +rendered: +  commands: +    - set protocols ospfv3 redistribute bgp +    - set protocols ospfv3 parameters router-id '192.0.2.10' +    - set protocols ospfv3 area 2 range 2001:db10::/32 +    - set protocols ospfv3 area 2 range 2001:db20::/32 +    - set protocols ospfv3 area 2 range 2001:db30::/32 +    - set protocols ospfv3 area '2' +    - set protocols ospfv3 area 2 export-list export1 +    - set protocols ospfv3 area 2 import-list import1 +    - set protocols ospfv3 area '3' +    - set protocols ospfv3 area 3 range 2001:db40::/32 +parsed: +  after: +    areas: +      - area_id: '2' +        export_list: 'export1' +        import_list: 'import1' +        range: +          - address: '2001:db10::/32' +          - address: '2001:db20::/32' +          - address: '2001:db30::/32' +      - area_id: '3' +        range: +          - address: '2001:db40::/32' +    parameters: +      router_id: '192.0.2.10' +    redistribute: +      - route_type: 'bgp' +deleted: +  commands: +    - 'delete protocols ospfv3' +  after: {} +round_trip: +  after: +    areas: +      - area_id: '2' +        export_list: 'export1' +        import_list: 'import1' +        range: +          - address: '2001:db10::/32' +          - address: '2001:db30::/32' +          - address: '2001:db50::/32' +      - area_id: '4' +        range: +          - address: '2001:db60::/32' +    parameters: +      router_id: '192.0.2.10' +    redistribute: +      - route_type: 'bgp' diff --git a/tests/unit/modules/network/vyos/fixtures/vyos_ospfv3_config.cfg b/tests/unit/modules/network/vyos/fixtures/vyos_ospfv3_config.cfg new file mode 100644 index 00000000..060b9b33 --- /dev/null +++ b/tests/unit/modules/network/vyos/fixtures/vyos_ospfv3_config.cfg @@ -0,0 +1,6 @@ +set protocols ospfv3 area 12 export-list 'export1' +set protocols ospfv3 area 12 import-list 'import1' +set protocols ospfv3 area 12 range '2001:db11::/32' +set protocols ospfv3 area 12 range '2001:db22::/32' +set protocols ospfv3 area 12 range '2001:db33::/32' +set protocols ospfv3 area 13 range '2001:db44::/32'
\ No newline at end of file diff --git a/tests/unit/modules/network/vyos/test_vyos_ospfv3.py b/tests/unit/modules/network/vyos/test_vyos_ospfv3.py new file mode 100644 index 00000000..1d9cb3ab --- /dev/null +++ b/tests/unit/modules/network/vyos/test_vyos_ospfv3.py @@ -0,0 +1,348 @@ +# (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_ospfv3 +from ansible_collections.vyos.vyos.tests.unit.modules.utils import ( +    set_module_args, +) +from .vyos_module import TestVyosModule, load_fixture + + +class TestVyosFirewallRulesModule(TestVyosModule): + +    module = vyos_ospfv3 + +    def setUp(self): +        super(TestVyosFirewallRulesModule, self).setUp() +        self.mock_get_config = patch( +            "ansible_collections.ansible.netcommon.plugins.module_utils.network.common.network.Config.get_config" +        ) +        self.get_config = self.mock_get_config.start() + +        self.mock_load_config = patch( +            "ansible_collections.ansible.netcommon.plugins.module_utils.network.common.network.Config.load_config" +        ) +        self.load_config = self.mock_load_config.start() + +        self.mock_get_resource_connection_config = patch( +            "ansible_collections.ansible.netcommon.plugins.module_utils.network.common.cfg.base.get_resource_connection" +        ) +        self.get_resource_connection_config = ( +            self.mock_get_resource_connection_config.start() +        ) + +        self.mock_get_resource_connection_facts = patch( +            "ansible_collections.ansible.netcommon.plugins.module_utils.network.common.facts.facts.get_resource_connection" +        ) +        self.get_resource_connection_facts = ( +            self.mock_get_resource_connection_facts.start() +        ) + +        self.mock_execute_show_command = patch( +            "ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.facts.ospfv3.ospfv3.Ospfv3Facts.get_device_data" +        ) + +        self.execute_show_command = self.mock_execute_show_command.start() + +    def tearDown(self): +        super(TestVyosFirewallRulesModule, self).tearDown() +        self.mock_get_resource_connection_config.stop() +        self.mock_get_resource_connection_facts.stop() +        self.mock_get_config.stop() +        self.mock_load_config.stop() +        self.mock_execute_show_command.stop() + +    def load_fixtures(self, commands=None, transport="cli", filename=None): +        if filename is None: +            filename = "vyos_ospfv3_config.cfg" + +        def load_from_file(*args, **kwargs): +            output = load_fixture(filename) +            return output + +        self.execute_show_command.side_effect = load_from_file + +    def test_vyos_ospfv3_merged_new_config(self): +        set_module_args( +            dict( +                config=dict( +                    redistribute=[dict(route_type="bgp")], +                    parameters=dict(router_id="192.0.2.10"), +                    areas=[ +                        dict( +                            area_id="2", +                            export_list="export1", +                            import_list="import1", +                            range=[ +                                dict(address="2001:db10::/32"), +                                dict(address="2001:db20::/32"), +                                dict(address="2001:db30::/32"), +                            ], +                        ), +                        dict( +                            area_id="3", +                            range=[dict(address="2001:db40::/32"),], +                        ), +                    ], +                ), +                state="merged", +            ) +        ) +        commands = [ +            "set protocols ospfv3 redistribute bgp", +            "set protocols ospfv3 parameters router-id '192.0.2.10'", +            "set protocols ospfv3 area 2 range 2001:db10::/32", +            "set protocols ospfv3 area 2 range 2001:db20::/32", +            "set protocols ospfv3 area 2 range 2001:db30::/32", +            "set protocols ospfv3 area '2'", +            "set protocols ospfv3 area 2 export-list export1", +            "set protocols ospfv3 area 2 import-list import1", +            "set protocols ospfv3 area '3'", +            "set protocols ospfv3 area 3 range 2001:db40::/32", +        ] +        self.execute_module(changed=True, commands=commands) + +    def test_vyos_ospfv3_merged_idem(self): +        set_module_args( +            dict( +                config=dict( +                    areas=[ +                        dict( +                            area_id="12", +                            export_list="export1", +                            import_list="import1", +                            range=[ +                                dict(address="2001:db11::/32"), +                                dict(address="2001:db22::/32"), +                                dict(address="2001:db33::/32"), +                            ], +                        ), +                        dict( +                            area_id="13", +                            range=[dict(address="2001:db44::/32"),], +                        ), +                    ], +                ), +                state="merged", +            ) +        ) +        self.execute_module(changed=False, commands=[]) + +    def test_vyos_ospfv3_merged_update_existing(self): +        set_module_args( +            dict( +                config=dict( +                    redistribute=[dict(route_type="bgp")], +                    parameters=dict(router_id="192.0.2.10"), +                    areas=[ +                        dict( +                            area_id="12", +                            export_list="export1", +                            import_list="import1", +                            range=[ +                                dict(address="2001:db11::/32"), +                                dict(address="2001:db22::/32"), +                                dict(address="2001:db33::/32"), +                            ], +                        ), +                        dict( +                            area_id="13", +                            range=[ +                                dict(address="2001:db44::/32"), +                                dict(address="2001:db55::/32"), +                            ], +                        ), +                    ], +                ), +                state="merged", +            ) +        ) +        commands = [ +            "set protocols ospfv3 redistribute bgp", +            "set protocols ospfv3 parameters router-id '192.0.2.10'", +            "set protocols ospfv3 area 13 range 2001:db55::/32", +        ] +        self.execute_module(changed=True, commands=commands) + +    def test_vyos_ospfv3_replaced(self): +        set_module_args( +            dict( +                config=dict( +                    redistribute=[dict(route_type="bgp")], +                    parameters=dict(router_id="192.0.2.10"), +                    areas=[ +                        dict( +                            area_id="12", +                            export_list="export1", +                            import_list="import1", +                            range=[ +                                dict(address="2001:db10::/32"), +                                dict(address="2001:db22::/32"), +                                dict(address="2001:db33::/32"), +                            ], +                        ), +                        dict( +                            area_id="14", +                            range=[dict(address="2001:db40::/32"),], +                        ), +                    ], +                ), +                state="replaced", +            ) +        ) +        commands = [ +            "set protocols ospfv3 redistribute bgp", +            "set protocols ospfv3 parameters router-id '192.0.2.10'", +            "delete protocols ospfv3 area 12 range 2001:db11::/32", +            "set protocols ospfv3 area 12 range 2001:db10::/32", +            "delete protocols ospfv3 area 13", +            "set protocols ospfv3 area '14'", +            "set protocols ospfv3 area 14 range 2001:db40::/32", +        ] +        self.execute_module(changed=True, commands=commands) + +    def test_vyos_ospfv3_replaced_idem(self): +        set_module_args( +            dict( +                config=dict( +                    areas=[ +                        dict( +                            area_id="12", +                            export_list="export1", +                            import_list="import1", +                            range=[ +                                dict(address="2001:db11::/32"), +                                dict(address="2001:db22::/32"), +                                dict(address="2001:db33::/32"), +                            ], +                        ), +                        dict( +                            area_id="13", +                            range=[dict(address="2001:db44::/32"),], +                        ), +                    ], +                ), +                state="replaced", +            ) +        ) +        self.execute_module(changed=False, commands=[]) + +    def test_vyos_ospfv3_deleted_no_config(self): +        set_module_args(dict(config=None, state="deleted")) +        commands = ["delete protocols ospfv3"] +        self.execute_module(changed=True, commands=commands) + +    def test_vyos_ospfv3_gathered(self): +        set_module_args(dict(state="gathered")) +        result = self.execute_module( +            changed=False, filename="vyos_ospfv3_config.cfg" +        ) +        gather_dict = { +            "areas": [ +                { +                    "area_id": "12", +                    "export_list": "export1", +                    "import_list": "import1", +                    "range": [ +                        {"address": "2001:db11::/32"}, +                        {"address": "2001:db22::/32"}, +                        {"address": "2001:db33::/32"}, +                    ], +                }, +                {"area_id": "13", "range": [{"address": "2001:db44::/32"}]}, +            ], +        } +        self.assertEqual(sorted(gather_dict), sorted(result["gathered"])) + +    def test_vyos_ospfv3_parsed(self): +        parsed_str = """set protocols ospfv3 area 2 export-list 'export1' +set protocols ospfv3 area 2 import-list 'import1' +set protocols ospfv3 area 2 range '2001:db10::/32' +set protocols ospfv3 area 2 range '2001:db20::/32' +set protocols ospfv3 area 2 range '2001:db30::/32' +set protocols ospfv3 area 3 range '2001:db40::/32' +set protocols ospfv3 parameters router-id '192.0.2.10' +set protocols ospfv3 redistribute 'bgp'""" +        set_module_args(dict(running_config=parsed_str, state="parsed")) +        result = self.execute_module(changed=False) +        parsed_dict = { +            "areas": [ +                { +                    "area_id": "2", +                    "export_list": "export1", +                    "import_list": "import1", +                    "range": [ +                        {"address": "2001:db10::/32"}, +                        {"address": "2001:db20::/32"}, +                        {"address": "2001:db30::/32"}, +                    ], +                }, +                {"area_id": "3", "range": [{"address": "2001:db40::/32"}]}, +            ], +            "parameters": {"router_id": "192.0.2.10"}, +            "redistribute": [{"route_type": "bgp"}], +        } +        self.assertEqual(sorted(parsed_dict), sorted(result["parsed"])) + +    def test_vyos_ospfv3_rendered(self): +        set_module_args( +            dict( +                config=dict( +                    redistribute=[dict(route_type="bgp")], +                    parameters=dict(router_id="192.0.2.10"), +                    areas=[ +                        dict( +                            area_id="2", +                            export_list="export1", +                            import_list="import1", +                            range=[ +                                dict(address="2001:db10::/32"), +                                dict(address="2001:db20::/32"), +                                dict(address="2001:db30::/32"), +                            ], +                        ), +                        dict( +                            area_id="3", +                            range=[dict(address="2001:db40::/32"),], +                        ), +                    ], +                ), +                state="rendered", +            ) +        ) +        commands = [ +            "set protocols ospfv3 redistribute bgp", +            "set protocols ospfv3 parameters router-id '192.0.2.10'", +            "set protocols ospfv3 area 2 range 2001:db10::/32", +            "set protocols ospfv3 area 2 range 2001:db20::/32", +            "set protocols ospfv3 area 2 range 2001:db30::/32", +            "set protocols ospfv3 area '2'", +            "set protocols ospfv3 area 2 export-list export1", +            "set protocols ospfv3 area 2 import-list import1", +            "set protocols ospfv3 area '3'", +            "set protocols ospfv3 area 3 range 2001:db40::/32", +        ] +        result = self.execute_module(changed=False) +        self.assertEqual( +            sorted(result["rendered"]), sorted(commands), result["rendered"] +        ) diff --git a/tests/unit/modules/network/vyos/vyos_module.py b/tests/unit/modules/network/vyos/vyos_module.py index fb15c715..49d46522 100644 --- a/tests/unit/modules/network/vyos/vyos_module.py +++ b/tests/unit/modules/network/vyos/vyos_module.py @@ -60,6 +60,7 @@ class TestVyosModule(ModuleTestCase):          commands=None,          sort=True,          defaults=False, +        filename=None,      ):          self.load_fixtures(commands) | 
