diff options
| author | ansible-zuul[bot] <48994755+ansible-zuul[bot]@users.noreply.github.com> | 2019-08-24 11:44:42 +0000 | 
|---|---|---|
| committer | GitHub <noreply@github.com> | 2019-08-24 11:44:42 +0000 | 
| commit | 74e4990a7ff571f361d5c238da10f347329546fb (patch) | |
| tree | e4422fabb09a8801a035592b7264efce1bb83f9c | |
| parent | ffd898f5dc0d1233bb05fce342d91e14bffed4b5 (diff) | |
| parent | e2a6e043664ef340aa474b0d3ab9d24865d0efdf (diff) | |
| download | vyos.vyos-74e4990a7ff571f361d5c238da10f347329546fb.tar.gz vyos.vyos-74e4990a7ff571f361d5c238da10f347329546fb.zip | |
Merge pull request #26 from CaptTrews/ansible/collections-sync
Updated from network content collector
Reviewed-by: https://github.com/apps/ansible-zuul
42 files changed, 1994 insertions, 269 deletions
| diff --git a/plugins/module_utils/network/vyos/argspec/facts/facts.py b/plugins/module_utils/network/vyos/argspec/facts/facts.py index 31b1aa9a..1dd15105 100644 --- a/plugins/module_utils/network/vyos/argspec/facts/facts.py +++ b/plugins/module_utils/network/vyos/argspec/facts/facts.py @@ -26,6 +26,8 @@ class FactsArgs(object):  # pylint: disable=R0903          "!lag_interfaces",          "lldp_global",          "!lldp_global", +        "lldp_interfaces", +        "!lldp_interfaces",      ]      argument_spec = { diff --git a/plugins/module_utils/network/vyos/argspec/lldp_interfaces/__init__.py b/plugins/module_utils/network/vyos/argspec/lldp_interfaces/__init__.py new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/plugins/module_utils/network/vyos/argspec/lldp_interfaces/__init__.py diff --git a/plugins/module_utils/network/vyos/argspec/lldp_interfaces/lldp_interfaces.py b/plugins/module_utils/network/vyos/argspec/lldp_interfaces/lldp_interfaces.py new file mode 100644 index 00000000..2976fc09 --- /dev/null +++ b/plugins/module_utils/network/vyos/argspec/lldp_interfaces/lldp_interfaces.py @@ -0,0 +1,89 @@ +# +# -*- coding: utf-8 -*- +# Copyright 2019 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 arg spec for the vyos_lldp_interfaces module +""" + +from __future__ import absolute_import, division, print_function + +__metaclass__ = type + + +class Lldp_interfacesArgs(object):  # pylint: disable=R0903 +    """The arg spec for the vyos_lldp_interfaces module +    """ + +    def __init__(self, **kwargs): +        pass + +    argument_spec = { +        "config": { +            "elements": "dict", +            "options": { +                "enable": {"default": True, "type": "bool"}, +                "location": { +                    "options": { +                        "civic_based": { +                            "options": { +                                "ca_info": { +                                    "elements": "dict", +                                    "options": { +                                        "ca_type": {"type": "int"}, +                                        "ca_value": {"type": "str"}, +                                    }, +                                    "type": "list", +                                }, +                                "country_code": { +                                    "required": True, +                                    "type": "str", +                                }, +                            }, +                            "type": "dict", +                        }, +                        "coordinate_based": { +                            "options": { +                                "altitude": {"type": "int"}, +                                "datum": { +                                    "choices": ["WGS84", "NAD83", "MLLW"], +                                    "type": "str", +                                }, +                                "latitude": {"required": True, "type": "str"}, +                                "longitude": {"required": True, "type": "str"}, +                            }, +                            "type": "dict", +                        }, +                        "elin": {"type": "str"}, +                    }, +                    "type": "dict", +                }, +                "name": {"required": True, "type": "str"}, +            }, +            "type": "list", +        }, +        "state": { +            "choices": ["merged", "replaced", "overridden", "deleted"], +            "default": "merged", +            "type": "str", +        }, +    }  # pylint: disable=C0301 diff --git a/plugins/module_utils/network/vyos/config/lldp_interfaces/__init__.py b/plugins/module_utils/network/vyos/config/lldp_interfaces/__init__.py new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/plugins/module_utils/network/vyos/config/lldp_interfaces/__init__.py diff --git a/plugins/module_utils/network/vyos/config/lldp_interfaces/lldp_interfaces.py b/plugins/module_utils/network/vyos/config/lldp_interfaces/lldp_interfaces.py new file mode 100644 index 00000000..a22c27e5 --- /dev/null +++ b/plugins/module_utils/network/vyos/config/lldp_interfaces/lldp_interfaces.py @@ -0,0 +1,422 @@ +# +# -*- coding: utf-8 -*- +# Copyright 2019 Red Hat +# GNU General Public License v3.0+ +# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) +""" +The vyos_lldp_interfaces class +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 it's desired end-state is +created +""" + +from __future__ import absolute_import, division, print_function + +__metaclass__ = type + + +from ansible.module_utils.network.common.cfg.base import ConfigBase +from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.facts.facts import ( +    Facts, +) +from ansible.module_utils.network.common.utils import to_list, dict_diff +from ansible.module_utils.six import iteritems +from ansible.module_utils.network.vyos.utils.utils import ( +    search_obj_in_list, +    search_dict_tv_in_list, +    key_value_in_dict, +    is_dict_element_present, +) + + +class Lldp_interfaces(ConfigBase): +    """ +    The vyos_lldp_interfaces class +    """ + +    gather_subset = ["!all", "!min"] + +    gather_network_resources = ["lldp_interfaces"] + +    params = ["enable", "location", "name"] + +    def __init__(self, module): +        super(Lldp_interfaces, self).__init__(module) + +    def get_lldp_interfaces_facts(self): +        """ Get the 'facts' (the current configuration) + +        :rtype: A dictionary +        :returns: The current configuration as a dictionary +        """ +        facts, _warnings = Facts(self._module).get_facts( +            self.gather_subset, self.gather_network_resources +        ) +        lldp_interfaces_facts = facts["ansible_network_resources"].get( +            "lldp_interfaces" +        ) +        if not lldp_interfaces_facts: +            return [] +        return lldp_interfaces_facts + +    def execute_module(self): +        """ Execute the module + +        :rtype: A dictionary +        :returns: The result from module execution +        """ +        result = {"changed": False} +        commands = list() +        warnings = list() +        existing_lldp_interfaces_facts = self.get_lldp_interfaces_facts() +        commands.extend(self.set_config(existing_lldp_interfaces_facts)) +        if commands: +            if self._module.check_mode: +                resp = self._connection.edit_config(commands, commit=False) +            else: +                resp = self._connection.edit_config(commands) +            result["changed"] = True + +        result["commands"] = commands + +        if self._module._diff: +            result["diff"] = resp["diff"] if result["changed"] else None + +        changed_lldp_interfaces_facts = self.get_lldp_interfaces_facts() +        result["before"] = existing_lldp_interfaces_facts +        if result["changed"]: +            result["after"] = changed_lldp_interfaces_facts + +        result["warnings"] = warnings +        return result + +    def set_config(self, existing_lldp_interfaces_facts): +        """ Collect the configuration from the args passed to the module, +            collect the current configuration (as a dict from facts) + +        :rtype: A list +        :returns: the commands necessary to migrate the current configuration +                  to the desired configuration +        """ +        want = self._module.params["config"] +        have = existing_lldp_interfaces_facts +        resp = self.set_state(want, have) +        return to_list(resp) + +    def set_state(self, want, have): +        """ Select the appropriate function based on the state provided + +        :param want: the desired configuration as a dictionary +        :param have: the current configuration as a dictionary +        :rtype: A list +        :returns: the commands necessary to migrate the current configuration +                  to the desired configuration +        """ +        commands = [] +        state = self._module.params["state"] +        if state == "overridden": +            commands.extend(self._state_overridden(want=want, have=have)) +        elif state == "deleted": +            if want: +                for item in want: +                    name = item["name"] +                    have_item = search_obj_in_list(name, have) +                    commands.extend( +                        self._state_deleted(want=None, have=have_item) +                    ) +            else: +                for have_item in have: +                    commands.extend( +                        self._state_deleted(want=None, have=have_item) +                    ) +        else: +            for want_item in want: +                name = want_item["name"] +                have_item = search_obj_in_list(name, have) +                if state == "merged": +                    commands.extend( +                        self._state_merged(want=want_item, have=have_item) +                    ) +                else: +                    commands.extend( +                        self._state_replaced(want=want_item, have=have_item) +                    ) +        return commands + +    def _state_replaced(self, want, have): +        """ The command generator when state is replaced + +        :rtype: A list +        :returns: the commands necessary to migrate the current configuration +                  to the desired configuration +        """ +        commands = [] +        if have: +            commands.extend(self._state_deleted(want, have)) +        commands.extend(self._state_merged(want, have)) +        return commands + +    def _state_overridden(self, want, have): +        """ The command generator when state is overridden + +        :rtype: A list +        :returns: the commands necessary to migrate the current configuration +                  to the desired configuration +        """ +        commands = [] +        for have_item in have: +            lldp_name = have_item["name"] +            lldp_in_want = search_obj_in_list(lldp_name, want) +            if not lldp_in_want: +                commands.append( +                    self._compute_command(have_item["name"], remove=True) +                ) + +        for want_item in want: +            name = want_item["name"] +            lldp_in_have = search_obj_in_list(name, have) +            commands.extend(self._state_replaced(want_item, lldp_in_have)) +        return commands + +    def _state_merged(self, want, have): +        """ The command generator when state is merged + +        :rtype: A list +        :returns: the commands necessary to merge the provided into +                  the current configuration +        """ +        commands = [] +        if have: +            commands.extend(self._render_updates(want, have)) +        else: +            commands.extend(self._render_set_commands(want)) +        return commands + +    def _state_deleted(self, want, have): +        """ The command generator when state is deleted + +        :rtype: A list +        :returns: the commands necessary to remove the current configuration +                  of the provided objects +        """ +        commands = [] +        if want: +            params = Lldp_interfaces.params +            for attrib in params: +                if attrib == "location": +                    commands.extend( +                        self._update_location(have["name"], want, have) +                    ) + +        elif have: +            commands.append(self._compute_command(have["name"], remove=True)) +        return commands + +    def _render_updates(self, want, have): +        commands = [] +        lldp_name = have["name"] +        commands.extend(self._configure_status(lldp_name, want, have)) +        commands.extend(self._add_location(lldp_name, want, have)) + +        return commands + +    def _render_set_commands(self, want): +        commands = [] +        have = {} +        lldp_name = want["name"] +        params = Lldp_interfaces.params + +        commands.extend(self._add_location(lldp_name, want, have)) +        for attrib in params: +            value = want[attrib] +            if value: +                if attrib == "location": +                    commands.extend(self._add_location(lldp_name, want, have)) +                elif attrib == "enable": +                    if not value: +                        commands.append( +                            self._compute_command(lldp_name, value="disable") +                        ) +                else: +                    commands.append(self._compute_command(lldp_name)) + +        return commands + +    def _configure_status(self, name, want_item, have_item): +        commands = [] +        if is_dict_element_present(have_item, "enable"): +            temp_have_item = False +        else: +            temp_have_item = True +        if want_item["enable"] != temp_have_item: +            if want_item["enable"]: +                commands.append( +                    self._compute_command(name, value="disable", remove=True) +                ) +            else: +                commands.append(self._compute_command(name, value="disable")) +        return commands + +    def _add_location(self, name, want_item, have_item): +        commands = [] +        have_dict = {} +        have_ca = {} +        set_cmd = name + " location " +        want_location_type = want_item.get("location") or {} +        have_location_type = have_item.get("location") or {} + +        if want_location_type["coordinate_based"]: +            want_dict = want_location_type.get("coordinate_based") or {} +            if is_dict_element_present(have_location_type, "coordinate_based"): +                have_dict = have_location_type.get("coordinate_based") or {} +            location_type = "coordinate-based" +            updates = dict_diff(have_dict, want_dict) +            for key, value in iteritems(updates): +                if value: +                    commands.append( +                        self._compute_command( +                            set_cmd + location_type, key, str(value) +                        ) +                    ) + +        elif want_location_type["civic_based"]: +            location_type = "civic-based" +            want_dict = want_location_type.get("civic_based") or {} +            want_ca = want_dict.get("ca_info") or [] +            if is_dict_element_present(have_location_type, "civic_based"): +                have_dict = have_location_type.get("civic_based") or {} +                have_ca = have_dict.get("ca_info") or [] +                if want_dict["country_code"] != have_dict["country_code"]: +                    commands.append( +                        self._compute_command( +                            set_cmd + location_type, +                            "country-code", +                            str(want_dict["country_code"]), +                        ) +                    ) +            else: +                commands.append( +                    self._compute_command( +                        set_cmd + location_type, +                        "country-code", +                        str(want_dict["country_code"]), +                    ) +                ) +            commands.extend(self._add_civic_address(name, want_ca, have_ca)) + +        elif want_location_type["elin"]: +            location_type = "elin" +            if is_dict_element_present(have_location_type, "elin"): +                if want_location_type.get("elin") != have_location_type.get( +                    "elin" +                ): +                    commands.append( +                        self._compute_command( +                            set_cmd + location_type, +                            value=str(want_location_type["elin"]), +                        ) +                    ) +            else: +                commands.append( +                    self._compute_command( +                        set_cmd + location_type, +                        value=str(want_location_type["elin"]), +                    ) +                ) +        return commands + +    def _update_location(self, name, want_item, have_item): +        commands = [] +        del_cmd = name + " location" +        want_location_type = want_item.get("location") or {} +        have_location_type = have_item.get("location") or {} + +        if want_location_type["coordinate_based"]: +            want_dict = want_location_type.get("coordinate_based") or {} +            if is_dict_element_present(have_location_type, "coordinate_based"): +                have_dict = have_location_type.get("coordinate_based") or {} +                location_type = "coordinate-based" +                for key, value in iteritems(have_dict): +                    only_in_have = key_value_in_dict(key, value, want_dict) +                    if not only_in_have: +                        commands.append( +                            self._compute_command( +                                del_cmd + location_type, key, str(value), True +                            ) +                        ) +            else: +                commands.append(self._compute_command(del_cmd, remove=True)) + +        elif want_location_type["civic_based"]: +            want_dict = want_location_type.get("civic_based") or {} +            want_ca = want_dict.get("ca_info") or [] +            if is_dict_element_present(have_location_type, "civic_based"): +                have_dict = have_location_type.get("civic_based") or {} +                have_ca = have_dict.get("ca_info") +                commands.extend( +                    self._update_civic_address(name, want_ca, have_ca) +                ) +            else: +                commands.append(self._compute_command(del_cmd, remove=True)) + +        else: +            if is_dict_element_present(have_location_type, "elin"): +                if want_location_type.get("elin") != have_location_type.get( +                    "elin" +                ): +                    commands.append( +                        self._compute_command(del_cmd, remove=True) +                    ) +            else: +                commands.append(self._compute_command(del_cmd, remove=True)) +        return commands + +    def _add_civic_address(self, name, want, have): +        commands = [] +        for item in want: +            ca_type = item["ca_type"] +            ca_value = item["ca_value"] +            obj_in_have = search_dict_tv_in_list( +                ca_type, ca_value, have, "ca_type", "ca_value" +            ) +            if not obj_in_have: +                commands.append( +                    self._compute_command( +                        key=name + " location civic-based ca-type", +                        attrib=str(ca_type) + " ca-value", +                        value=ca_value, +                    ) +                ) +        return commands + +    def _update_civic_address(self, name, want, have): +        commands = [] +        for item in have: +            ca_type = item["ca_type"] +            ca_value = item["ca_value"] +            in_want = search_dict_tv_in_list( +                ca_type, ca_value, want, "ca_type", "ca_value" +            ) +            if not in_want: +                commands.append( +                    self._compute_command( +                        name, +                        "location civic-based ca-type", +                        str(ca_type), +                        remove=True, +                    ) +                ) +        return commands + +    def _compute_command(self, key, attrib=None, value=None, remove=False): +        if remove: +            cmd = "delete service lldp interface " +        else: +            cmd = "set service lldp interface " +        cmd += key +        if attrib: +            cmd += " " + attrib +        if value: +            cmd += " '" + value + "'" +        return cmd diff --git a/plugins/module_utils/network/vyos/facts/facts.py b/plugins/module_utils/network/vyos/facts/facts.py index fb05f2ac..d4aec706 100644 --- a/plugins/module_utils/network/vyos/facts/facts.py +++ b/plugins/module_utils/network/vyos/facts/facts.py @@ -25,6 +25,9 @@ from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.facts.lag_i  from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.facts.lldp_global.lldp_global import (      Lldp_globalFacts,  ) +from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.facts.lldp_interfaces.lldp_interfaces import ( +    Lldp_interfacesFacts, +)  from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.facts.legacy.base import (      Default,      Neighbors, @@ -38,6 +41,7 @@ FACT_RESOURCE_SUBSETS = dict(      l3_interfaces=L3_interfacesFacts,      lag_interfaces=Lag_interfacesFacts,      lldp_global=Lldp_globalFacts, +    lldp_interfaces=Lldp_interfacesFacts,  ) @@ -55,7 +59,6 @@ class Facts(FactsBase):          self, legacy_facts_type=None, resource_facts_type=None, data=None      ):          """ Collect the facts for vyos -          :param legacy_facts_type: List of legacy facts types          :param resource_facts_type: List of resource fact types          :param data: previously collected conf diff --git a/plugins/module_utils/network/vyos/facts/lldp_interfaces/__init__.py b/plugins/module_utils/network/vyos/facts/lldp_interfaces/__init__.py new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/plugins/module_utils/network/vyos/facts/lldp_interfaces/__init__.py diff --git a/plugins/module_utils/network/vyos/facts/lldp_interfaces/lldp_interfaces.py b/plugins/module_utils/network/vyos/facts/lldp_interfaces/lldp_interfaces.py new file mode 100644 index 00000000..72629ed1 --- /dev/null +++ b/plugins/module_utils/network/vyos/facts/lldp_interfaces/lldp_interfaces.py @@ -0,0 +1,153 @@ +# +# -*- coding: utf-8 -*- +# Copyright 2019 Red Hat +# GNU General Public License v3.0+ +# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) +""" +The vyos lldp_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. +""" + +from __future__ import absolute_import, division, print_function + +__metaclass__ = type + + +from re import findall, search, M +from copy import deepcopy + +from ansible.module_utils.network.common import utils +from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.argspec.lldp_interfaces.lldp_interfaces import ( +    Lldp_interfacesArgs, +) + + +class Lldp_interfacesFacts(object): +    """ The vyos lldp_interfaces fact class +    """ + +    def __init__(self, module, subspec="config", options="options"): +        self._module = module +        self.argument_spec = Lldp_interfacesArgs.argument_spec +        spec = deepcopy(self.argument_spec) +        if subspec: +            if options: +                facts_argument_spec = spec[subspec][options] +            else: +                facts_argument_spec = spec[subspec] +        else: +            facts_argument_spec = spec + +        self.generated_spec = utils.generate_dict(facts_argument_spec) + +    def populate_facts(self, connection, ansible_facts, data=None): +        """ Populate the facts for lldp_interfaces +        :param connection: the device connection +        :param ansible_facts: Facts dictionary +        :param data: previously collected conf +        :rtype: dictionary +        :returns: facts +        """ +        if not data: +            data = connection.get_config() + +        objs = [] +        lldp_names = findall(r"^set service lldp interface (\S+)", data, M) +        if lldp_names: +            for lldp in set(lldp_names): +                lldp_regex = r" %s .+$" % lldp +                cfg = findall(lldp_regex, data, M) +                obj = self.render_config(cfg) +                obj["name"] = lldp.strip("'") +                if obj: +                    objs.append(obj) +        facts = {} +        if objs: +            facts["lldp_interfaces"] = objs +            ansible_facts["ansible_network_resources"].update(facts) + +        ansible_facts["ansible_network_resources"].update(facts) +        return ansible_facts + +    def render_config(self, conf): +        """ +        Render config as dictionary structure and delete keys +          from spec for null values + +        :param spec: The facts tree, generated from the argspec +        :param conf: The configuration +        :rtype: dictionary +        :returns: The generated config +        """ +        config = {} +        location = {} + +        civic_conf = "\n".join(filter(lambda x: ("civic-based" in x), conf)) +        elin_conf = "\n".join(filter(lambda x: ("elin" in x), conf)) +        coordinate_conf = "\n".join( +            filter(lambda x: ("coordinate-based" in x), conf) +        ) +        disable = "\n".join(filter(lambda x: ("disable" in x), conf)) + +        coordinate_based_conf = self.parse_attribs( +            ["altitude", "datum", "longitude", "latitude"], coordinate_conf +        ) +        elin_based_conf = self.parse_lldp_elin_based(elin_conf) +        civic_based_conf = self.parse_lldp_civic_based(civic_conf) +        if disable: +            config["enable"] = False +        if coordinate_conf: +            location["coordinate_based"] = coordinate_based_conf +            config["location"] = location +        elif civic_based_conf: +            location["civic_based"] = civic_based_conf +            config["location"] = location +        elif elin_conf: +            location["elin"] = elin_based_conf +            config["location"] = location + +        return utils.remove_empties(config) + +    def parse_attribs(self, attribs, conf): +        config = {} +        for item in attribs: +            value = utils.parse_conf_arg(conf, item) +            if value: +                value = value.strip("'") +                if item == "altitude": +                    value = int(value) +                config[item] = value +            else: +                config[item] = None +        return utils.remove_empties(config) + +    def parse_lldp_civic_based(self, conf): +        civic_based = None +        if conf: +            civic_info_list = [] +            civic_add_list = findall(r"^.*civic-based ca-type (.+)", conf, M) +            if civic_add_list: +                for civic_add in civic_add_list: +                    ca = civic_add.split(" ") +                    c_add = {} +                    c_add["ca_type"] = int(ca[0].strip("'")) +                    c_add["ca_value"] = ca[2].strip("'") +                    civic_info_list.append(c_add) + +                country_code = search( +                    r"^.*civic-based country-code (.+)", conf, M +                ) +                civic_based = {} +                civic_based["ca_info"] = civic_info_list +                civic_based["country_code"] = country_code.group(1).strip("'") +        return civic_based + +    def parse_lldp_elin_based(self, conf): +        elin_based = None +        if conf: +            e_num = search(r"^.* elin (.+)", conf, M) +            elin_based = e_num.group(1).strip("'") + +        return elin_based diff --git a/plugins/module_utils/network/vyos/utils/utils.py b/plugins/module_utils/network/vyos/utils/utils.py index 1968cccd..6504bcd9 100644 --- a/plugins/module_utils/network/vyos/utils/utils.py +++ b/plugins/module_utils/network/vyos/utils/utils.py @@ -7,6 +7,7 @@  from __future__ import absolute_import, division, print_function  __metaclass__ = type +from ansible.module_utils.six import iteritems  def search_obj_in_list(name, lst, key="name"): @@ -126,3 +127,54 @@ def list_diff_want_only(want_list, have_list):              if i in want_list and i not in have_list          ]      return diff + + +def search_dict_tv_in_list(d_val1, d_val2, lst, key1, key2): +    """ +    This function return the dict object if it exist in list. +    :param d_val1: +    :param d_val2: +    :param lst: +    :param key1: +    :param key2: +    :return: +    """ +    obj = next( +        ( +            item +            for item in lst +            if item[key1] == d_val1 and item[key2] == d_val2 +        ), +        None, +    ) +    if obj: +        return obj +    else: +        return None + + +def key_value_in_dict(have_key, have_value, want_dict): +    """ +    This function checks whether the key and values exist in dict +    :param have_key: +    :param have_value: +    :param want_dict: +    :return: +    """ +    for key, value in iteritems(want_dict): +        if key == have_key and value == have_value: +            return True +    return False + + +def is_dict_element_present(dict, key): +    """ +    This function checks whether the key is present in dict. +    :param dict: +    :param key: +    :return: +    """ +    for item in dict: +        if item == key: +            return True +    return False diff --git a/plugins/modules/_vyos_lldp_interface.py b/plugins/modules/_vyos_lldp_interface.py new file mode 100644 index 00000000..6705d575 --- /dev/null +++ b/plugins/modules/_vyos_lldp_interface.py @@ -0,0 +1,260 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# (c) 2017, Ansible by Red Hat, inc +# +# This file is part of Ansible by Red Hat +# +# 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/>. +# + + +ANSIBLE_METADATA = { +    "metadata_version": "1.1", +    "status": ["deprecated"], +    "supported_by": "network", +} + + +DOCUMENTATION = """ +--- +module: vyos_lldp_interface +version_added: "2.4" +author: "Ricardo Carrillo Cruz (@rcarrillocruz)" +short_description: Manage LLDP interfaces configuration on VyOS network devices +description: +  - This module provides declarative management of LLDP interfaces +    configuration on VyOS network devices. +deprecated: +  removed_in: '2.13' +  alternative: vyos_lldp_interfaces +  why: Updated modules released with more functionality. +notes: +  - Tested against VYOS 1.1.7 +options: +  name: +    description: +      - Name of the interface LLDP should be configured on. +    type: str +  aggregate: +    description: List of interfaces LLDP should be configured on. +    type: list +  state: +    description: +      - State of the LLDP configuration. +    default: present +    choices: ['present', 'absent', 'enabled', 'disabled'] +    type: str +extends_documentation_fragment: vyos +""" + +EXAMPLES = """ +- name: Enable LLDP on eth1 +  net_lldp_interface: +    state: present + +- name: Enable LLDP on specific interfaces +  net_lldp_interface: +    interfaces: +      - eth1 +      - eth2 +    state: present + +- name: Disable LLDP globally +  net_lldp_interface: +    state: disabled + +- name: Create aggregate of LLDP interface configurations +  vyos_lldp_interface: +    aggregate: +    - name: eth1 +    - name: eth2 +    state: present + +- name: Delete aggregate of LLDP interface configurations +  vyos_lldp_interface: +    aggregate: +    - name: eth1 +    - name: eth2 +    state: absent +""" + +RETURN = """ +commands: +  description: The list of configuration mode commands to send to the device +  returned: always, except for the platforms that use Netconf transport to manage the device. +  type: list +  sample: +    - set service lldp eth1 +    - set service lldp eth2 disable +""" + + +from copy import deepcopy + +from ansible.module_utils.basic import AnsibleModule +from ansible.module_utils.network.common.utils import remove_default_spec +from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.vyos import ( +    get_config, +    load_config, +) +from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.vyos import ( +    vyos_argument_spec, +) + + +def search_obj_in_list(name, lst): +    for o in lst: +        if o["name"] == name: +            return o + +    return None + + +def map_obj_to_commands(updates, module): +    commands = list() +    want, have = updates + +    for w in want: +        name = w["name"] +        state = w["state"] + +        obj_in_have = search_obj_in_list(name, have) + +        if state == "absent" and obj_in_have: +            commands.append("delete service lldp interface " + name) +        elif state in ("present", "enabled"): +            if not obj_in_have: +                commands.append("set service lldp interface " + name) +            elif ( +                obj_in_have +                and obj_in_have["state"] == "disabled" +                and state == "enabled" +            ): +                commands.append( +                    "delete service lldp interface " + name + " disable" +                ) +        elif state == "disabled": +            if not obj_in_have: +                commands.append("set service lldp interface " + name) +                commands.append( +                    "set service lldp interface " + name + " disable" +                ) +            elif obj_in_have and obj_in_have["state"] != "disabled": +                commands.append( +                    "set service lldp interface " + name + " disable" +                ) + +    return commands + + +def map_config_to_obj(module): +    obj = [] +    config = get_config(module).splitlines() + +    output = [c for c in config if c.startswith("set service lldp interface")] + +    for i in output: +        splitted_line = i.split() + +        if len(splitted_line) > 5: +            new_obj = {"name": splitted_line[4]} + +            if splitted_line[5] == "'disable'": +                new_obj["state"] = "disabled" +        else: +            new_obj = {"name": splitted_line[4][1:-1]} +            new_obj["state"] = "present" + +        obj.append(new_obj) + +    return obj + + +def map_params_to_obj(module): +    obj = [] + +    aggregate = module.params.get("aggregate") +    if aggregate: +        for item in aggregate: +            for key in item: +                if item.get(key) is None: +                    item[key] = module.params[key] + +            obj.append(item.copy()) +    else: +        obj.append( +            {"name": module.params["name"], "state": module.params["state"]} +        ) + +    return obj + + +def main(): +    """ main entry point for module execution +    """ +    element_spec = dict( +        name=dict(), +        state=dict( +            default="present", +            choices=["present", "absent", "enabled", "disabled"], +        ), +    ) + +    aggregate_spec = deepcopy(element_spec) +    aggregate_spec["name"] = dict(required=True) + +    # remove default in aggregate spec, to handle common arguments +    remove_default_spec(aggregate_spec) + +    argument_spec = dict( +        aggregate=dict(type="list", elements="dict", options=aggregate_spec) +    ) + +    argument_spec.update(element_spec) +    argument_spec.update(vyos_argument_spec) + +    required_one_of = [["name", "aggregate"]] +    mutually_exclusive = [["name", "aggregate"]] + +    module = AnsibleModule( +        argument_spec=argument_spec, +        required_one_of=required_one_of, +        mutually_exclusive=mutually_exclusive, +        supports_check_mode=True, +    ) + +    warnings = list() + +    result = {"changed": False} + +    if warnings: +        result["warnings"] = warnings + +    want = map_params_to_obj(module) +    have = map_config_to_obj(module) + +    commands = map_obj_to_commands((want, have), module) +    result["commands"] = commands + +    if commands: +        commit = not module.check_mode +        load_config(module, commands, commit=commit) +        result["changed"] = True + +    module.exit_json(**result) + + +if __name__ == "__main__": +    main() diff --git a/plugins/modules/vyos_banner.py b/plugins/modules/vyos_banner.py index 39801b55..81a985d4 100644 --- a/plugins/modules/vyos_banner.py +++ b/plugins/modules/vyos_banner.py @@ -36,7 +36,8 @@ description:      devices running VyOS. It allows playbooks to add or remote      banner text from the active running configuration.  notes: -  - Tested against VYOS 1.1.7 +  - 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).  options:    banner:      description: diff --git a/plugins/modules/vyos_command.py b/plugins/modules/vyos_command.py index 892e853a..6da7352e 100644 --- a/plugins/modules/vyos_command.py +++ b/plugins/modules/vyos_command.py @@ -83,11 +83,12 @@ options:      default: 1  notes: -  - Tested against VYOS 1.1.7 +  - Tested against VyOS 1.1.8 (helium).    - Running C(show system boot-messages all) will cause the module to hang since      VyOS is using a custom pager setting to display the output of that command.    - If a command sent to the device requires answering a prompt, it is possible      to pass a dict containing I(command), I(answer) and I(prompt). See examples. +  - This module works with connection C(network_cli). See L(the VyOS OS Platform Options,../network/user_guide/platform_vyos.html).  """  EXAMPLES = """ diff --git a/plugins/modules/vyos_config.py b/plugins/modules/vyos_config.py index 9ffc654c..7c9f3ab1 100644 --- a/plugins/modules/vyos_config.py +++ b/plugins/modules/vyos_config.py @@ -37,9 +37,8 @@ description:      in the device configuration.  extends_documentation_fragment: vyos  notes: -  - Tested against VYOS 1.1.7 -  - Abbreviated commands are NOT idempotent, see -    L(Network FAQ,../network/user_guide/faq.html#why-do-the-config-modules-always-return-changed-true-with-abbreviated-commands). +  - 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).  options:    lines:      description: diff --git a/plugins/modules/vyos_facts.py b/plugins/modules/vyos_facts.py index 561b149e..40010b1a 100644 --- a/plugins/modules/vyos_facts.py +++ b/plugins/modules/vyos_facts.py @@ -32,7 +32,8 @@ author:    - Rohit Thakur (@rohitthakur2590)  extends_documentation_fragment: vyos  notes: -  - Tested against VyOS 1.1.8 +  - 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).  options:    gather_subset:      description: @@ -54,7 +55,8 @@ options:          specific subset should not be collected.      required: false      version_added: "2.9" -    choices: ['all', 'interfaces', '!interfaces', 'l3_interfaces', '!l3_interfaces', 'lag_interfaces', '!lag_interfaces', 'lldp_global', '!lldp_global'] +    choices: ['all', 'interfaces', '!interfaces', 'l3_interfaces', '!l3_interfaces','lag_interfaces', '!lag_interfaces', +             'lldp_global', '!lldp_global','lldp_interfaces', '!lldp_interfaces']  """  EXAMPLES = """ diff --git a/plugins/modules/vyos_interfaces.py b/plugins/modules/vyos_interfaces.py index bc179ed4..9ea06999 100644 --- a/plugins/modules/vyos_interfaces.py +++ b/plugins/modules/vyos_interfaces.py @@ -45,6 +45,9 @@ description:    - This module manages the interface attributes on VyOS network devices.    - This module supports managing base attributes of Ethernet, Bonding,      VXLAN, Loopback and Virtual Tunnel Interfaces. +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: Nilashish Chakraborty (@nilashishc)  options:    config: diff --git a/plugins/modules/vyos_l3_interfaces.py b/plugins/modules/vyos_l3_interfaces.py index 25a57d30..e79d5d50 100644 --- a/plugins/modules/vyos_l3_interfaces.py +++ b/plugins/modules/vyos_l3_interfaces.py @@ -42,6 +42,9 @@ module: vyos_l3_interfaces  version_added: 2.9  short_description: Manages L3 interface attributes of VyOS network devices.  description: This module manages the L3 interface attributes on VyOS network devices. +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: Nilashish Chakraborty (@NilashishC)  options:    config: diff --git a/plugins/modules/vyos_lag_interfaces.py b/plugins/modules/vyos_lag_interfaces.py index 9707f2e0..d9b007ac 100644 --- a/plugins/modules/vyos_lag_interfaces.py +++ b/plugins/modules/vyos_lag_interfaces.py @@ -44,7 +44,7 @@ short_description: Manages attributes of link aggregation groups on VyOS network  description: This module manages attributes of link aggregation groups on VyOS network devices.  notes:    - Tested against VyOS 1.1.8 (helium). -  - This module works with connection C(network_cli). +  - 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: diff --git a/plugins/modules/vyos_lldp_global.py b/plugins/modules/vyos_lldp_global.py index 3783dcbc..d080e822 100644 --- a/plugins/modules/vyos_lldp_global.py +++ b/plugins/modules/vyos_lldp_global.py @@ -44,7 +44,7 @@ short_description: Manage link layer discovery protocol (LLDP) attributes on VyO  description: This module manages link layer discovery protocol (LLDP) attributes on VyOS devices.  notes:    - Tested against VyOS 1.1.8 (helium). -  - This module works with connection C(network_cli). +  - 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: diff --git a/plugins/modules/vyos_lldp_interface.py b/plugins/modules/vyos_lldp_interface.py index 494fac46..7847a588 100644..120000 --- a/plugins/modules/vyos_lldp_interface.py +++ b/plugins/modules/vyos_lldp_interface.py @@ -1,250 +1 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# (c) 2017, Ansible by Red Hat, inc -# -# This file is part of Ansible by Red Hat -# -# 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/>. -# - -ANSIBLE_METADATA = { -    "metadata_version": "1.1", -    "status": ["preview"], -    "supported_by": "network", -} - - -DOCUMENTATION = """ ---- -module: vyos_lldp_interface -version_added: "2.4" -author: "Ricardo Carrillo Cruz (@rcarrillocruz)" -short_description: Manage LLDP interfaces configuration on VyOS network devices -description: -  - This module provides declarative management of LLDP interfaces -    configuration on VyOS network devices. -notes: -  - Tested against VYOS 1.1.7 -options: -  name: -    description: -      - Name of the interface LLDP should be configured on. -  aggregate: -    description: List of interfaces LLDP should be configured on. -  state: -    description: -      - State of the LLDP configuration. -    default: present -    choices: ['present', 'absent', 'enabled', 'disabled'] -extends_documentation_fragment: vyos -""" - -EXAMPLES = """ -- name: Enable LLDP on eth1 -  net_lldp_interface: -    state: present - -- name: Enable LLDP on specific interfaces -  net_lldp_interface: -    interfaces: -      - eth1 -      - eth2 -    state: present - -- name: Disable LLDP globally -  net_lldp_interface: -    state: disabled - -- name: Create aggregate of LLDP interface configurations -  vyos_lldp_interface: -    aggregate: -    - name: eth1 -    - name: eth2 -    state: present - -- name: Delete aggregate of LLDP interface configurations -  vyos_lldp_interface: -    aggregate: -    - name: eth1 -    - name: eth2 -    state: absent -""" - -RETURN = """ -commands: -  description: The list of configuration mode commands to send to the device -  returned: always, except for the platforms that use Netconf transport to manage the device. -  type: list -  sample: -    - set service lldp eth1 -    - set service lldp eth2 disable -""" -from copy import deepcopy - -from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils.network.common.utils import remove_default_spec -from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.vyos import ( -    get_config, -    load_config, -) -from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.vyos import ( -    vyos_argument_spec, -) - - -def search_obj_in_list(name, lst): -    for o in lst: -        if o["name"] == name: -            return o - -    return None - - -def map_obj_to_commands(updates, module): -    commands = list() -    want, have = updates - -    for w in want: -        name = w["name"] -        state = w["state"] - -        obj_in_have = search_obj_in_list(name, have) - -        if state == "absent" and obj_in_have: -            commands.append("delete service lldp interface " + name) -        elif state in ("present", "enabled"): -            if not obj_in_have: -                commands.append("set service lldp interface " + name) -            elif ( -                obj_in_have -                and obj_in_have["state"] == "disabled" -                and state == "enabled" -            ): -                commands.append( -                    "delete service lldp interface " + name + " disable" -                ) -        elif state == "disabled": -            if not obj_in_have: -                commands.append("set service lldp interface " + name) -                commands.append( -                    "set service lldp interface " + name + " disable" -                ) -            elif obj_in_have and obj_in_have["state"] != "disabled": -                commands.append( -                    "set service lldp interface " + name + " disable" -                ) - -    return commands - - -def map_config_to_obj(module): -    obj = [] -    config = get_config(module).splitlines() - -    output = [c for c in config if c.startswith("set service lldp interface")] - -    for i in output: -        splitted_line = i.split() - -        if len(splitted_line) > 5: -            new_obj = {"name": splitted_line[4]} - -            if splitted_line[5] == "'disable'": -                new_obj["state"] = "disabled" -        else: -            new_obj = {"name": splitted_line[4][1:-1]} -            new_obj["state"] = "present" - -        obj.append(new_obj) - -    return obj - - -def map_params_to_obj(module): -    obj = [] - -    aggregate = module.params.get("aggregate") -    if aggregate: -        for item in aggregate: -            for key in item: -                if item.get(key) is None: -                    item[key] = module.params[key] - -            obj.append(item.copy()) -    else: -        obj.append( -            {"name": module.params["name"], "state": module.params["state"]} -        ) - -    return obj - - -def main(): -    """ main entry point for module execution -    """ -    element_spec = dict( -        name=dict(), -        state=dict( -            default="present", -            choices=["present", "absent", "enabled", "disabled"], -        ), -    ) - -    aggregate_spec = deepcopy(element_spec) -    aggregate_spec["name"] = dict(required=True) - -    # remove default in aggregate spec, to handle common arguments -    remove_default_spec(aggregate_spec) - -    argument_spec = dict( -        aggregate=dict(type="list", elements="dict", options=aggregate_spec) -    ) - -    argument_spec.update(element_spec) -    argument_spec.update(vyos_argument_spec) - -    required_one_of = [["name", "aggregate"]] -    mutually_exclusive = [["name", "aggregate"]] - -    module = AnsibleModule( -        argument_spec=argument_spec, -        required_one_of=required_one_of, -        mutually_exclusive=mutually_exclusive, -        supports_check_mode=True, -    ) - -    warnings = list() - -    result = {"changed": False} - -    if warnings: -        result["warnings"] = warnings - -    want = map_params_to_obj(module) -    have = map_config_to_obj(module) - -    commands = map_obj_to_commands((want, have), module) -    result["commands"] = commands - -    if commands: -        commit = not module.check_mode -        load_config(module, commands, commit=commit) -        result["changed"] = True - -    module.exit_json(**result) - - -if __name__ == "__main__": -    main() +_vyos_lldp_interface.py
\ No newline at end of file diff --git a/plugins/modules/vyos_lldp_interfaces.py b/plugins/modules/vyos_lldp_interfaces.py new file mode 100644 index 00000000..7fe6d23e --- /dev/null +++ b/plugins/modules/vyos_lldp_interfaces.py @@ -0,0 +1,517 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- +# Copyright 2019 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_lldp_interfaces +""" + +from __future__ import absolute_import, division, print_function + +__metaclass__ = type + +ANSIBLE_METADATA = { +    "metadata_version": "1.1", +    "status": ["preview"], +    "supported_by": "network", +} + +DOCUMENTATION = """ +--- +module: vyos_lldp_interfaces +version_added: 2.9 +short_description: Manages attributes of lldp interfaces on VyOS devices. +description: This module manages attributes of lldp interfaces on VyOS network devices. +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 list of lldp interfaces configurations. +    type: list +    suboptions: +      name: +        description: +          - Name of the  lldp interface. +        type: str +        required: True +      enable: +        description: +          - to disable lldp on the interface. +        type: bool +        default: True +      location: +        description: +          - LLDP-MED location data. +        type: dict +        suboptions: +          civic_based: +            description: +              - Civic-based location data. +            type: dict +            suboptions: +              ca_info: +                 description: LLDP-MED address info +                 type: list +                 suboptions: +                   ca_type: +                     description: LLDP-MED Civic Address type. +                     type: int +                     required: True +                   ca_value: +                     description: LLDP-MED Civic Address value. +                     type: str +                     required: True +              country_code: +                description: Country Code +                type: str +                required: True +          coordinate_based: +            description: +              - Coordinate-based location. +            type: dict +            suboptions: +              altitude: +                description: Altitude in meters. +                type: int +              datum: +                description: Coordinate datum type. +                type: str +                choices: +                  - WGS84 +                  - NAD83 +                  - MLLW +              latitude: +                description: Latitude. +                type: str +                required: True +              longitude: +                description: Longitude. +                type: str +                required: True +          elin: +            description: Emergency Call Service ELIN number (between 10-25 numbers). +            type: str +  state: +    description: +      - The state the configuration should be left in. +    type: str +    choices: +    - merged +    - replaced +    - overridden +    - deleted +    default: merged + +""" +EXAMPLES = """ +# Using merged +# +# Before state: +# ------------- +# +# vyos@vyos:~$ show configuration  commands | grep lldp +# +- name: Merge provided configuration with device configuration +  vyos_lldp_interfaces: +    config: +      - name: 'eth1' +        location: +          civic_based: +            country_code: 'US' +            ca_info: +              - ca_type: 0 +                ca_value: 'ENGLISH' + +      - name: 'eth2' +        location: +          coordinate_based: +           altitude: 2200 +           datum: 'WGS84' +           longitude: '222.267255W' +           latitude: '33.524449N' +    state: merged +# +# +# ------------------------- +# Module Execution Result +# ------------------------- +# +# before": [] +# +#    "commands": [ +#        "set service lldp interface eth1 location civic-based country-code 'US'", +#        "set service lldp interface eth1 location civic-based ca-type 0 ca-value 'ENGLISH'", +#        "set service lldp interface eth1", +#        "set service lldp interface eth2 location coordinate-based latitude '33.524449N'", +#        "set service lldp interface eth2 location coordinate-based altitude '2200'", +#        "set service lldp interface eth2 location coordinate-based datum 'WGS84'", +#        "set service lldp interface eth2 location coordinate-based longitude '222.267255W'", +#        "set service lldp interface eth2 location coordinate-based latitude '33.524449N'", +#        "set service lldp interface eth2 location coordinate-based altitude '2200'", +#        "set service lldp interface eth2 location coordinate-based datum 'WGS84'", +#        "set service lldp interface eth2 location coordinate-based longitude '222.267255W'", +#        "set service lldp interface eth2" +# +# "after": [ +#        { +#            "location": { +#                "coordinate_based": { +#                    "altitude": 2200, +#                    "datum": "WGS84", +#                    "latitude": "33.524449N", +#                    "longitude": "222.267255W" +#                } +#            }, +#            "name": "eth2" +#        }, +#        { +#            "location": { +#                "civic_based": { +#                    "ca_info": [ +#                        { +#                            "ca_type": 0, +#                            "ca_value": "ENGLISH" +#                        } +#                    ], +#                    "country_code": "US" +#                } +#            }, +#            "name": "eth1" +#        } +#    ], +# +# After state: +# ------------- +# +# vyos@vyos:~$ show configuration commands | grep lldp +# set service lldp interface eth1 location civic-based ca-type 0 ca-value 'ENGLISH' +# set service lldp interface eth1 location civic-based country-code 'US' +# set service lldp interface eth2 location coordinate-based altitude '2200' +# set service lldp interface eth2 location coordinate-based datum 'WGS84' +# set service lldp interface eth2 location coordinate-based latitude '33.524449N' +# set service lldp interface eth2 location coordinate-based longitude '222.267255W' + + +# Using replaced +# +# Before state: +# ------------- +# +# vyos@vyos:~$ show configuration commands | grep lldp +# set service lldp interface eth1 location civic-based ca-type 0 ca-value 'ENGLISH' +# set service lldp interface eth1 location civic-based country-code 'US' +# set service lldp interface eth2 location coordinate-based altitude '2200' +# set service lldp interface eth2 location coordinate-based datum 'WGS84' +# set service lldp interface eth2 location coordinate-based latitude '33.524449N' +# set service lldp interface eth2 location coordinate-based longitude '222.267255W' +# +- name: Replace device configurations of listed LLDP interfaces with provided configurations +  vyos_lldp_interfaces: +    config: +      - name: 'eth2' +        location: +          civic_based: +            country_code: 'US' +            ca_info: +              - ca_type: 0 +                ca_value: 'ENGLISH' + +      - name: 'eth1' +        location: +          coordinate_based: +           altitude: 2200 +           datum: 'WGS84' +           longitude: '222.267255W' +           latitude: '33.524449N' +    state: replaced +# +# +# ------------------------- +# Module Execution Result +# ------------------------- +# +#    "before": [ +#        { +#            "location": { +#                "coordinate_based": { +#                    "altitude": 2200, +#                    "datum": "WGS84", +#                    "latitude": "33.524449N", +#                    "longitude": "222.267255W" +#                } +#            }, +#            "name": "eth2" +#        }, +#        { +#            "location": { +#                "civic_based": { +#                    "ca_info": [ +#                        { +#                            "ca_type": 0, +#                            "ca_value": "ENGLISH" +#                        } +#                    ], +#                    "country_code": "US" +#                } +#            }, +#            "name": "eth1" +#        } +#    ] +# +#    "commands": [ +#        "delete service lldp interface eth2 location", +#        "set service lldp interface eth2 'disable'", +#        "set service lldp interface eth2 location civic-based country-code 'US'", +#        "set service lldp interface eth2 location civic-based ca-type 0 ca-value 'ENGLISH'", +#        "delete service lldp interface eth1 location", +#        "set service lldp interface eth1 'disable'", +#        "set service lldp interface eth1 location coordinate-based latitude '33.524449N'", +#        "set service lldp interface eth1 location coordinate-based altitude '2200'", +#        "set service lldp interface eth1 location coordinate-based datum 'WGS84'", +#        "set service lldp interface eth1 location coordinate-based longitude '222.267255W'" +#    ] +# +#    "after": [ +#        { +#            "location": { +#                "civic_based": { +#                    "ca_info": [ +#                        { +#                            "ca_type": 0, +#                            "ca_value": "ENGLISH" +#                        } +#                    ], +#                    "country_code": "US" +#                } +#            }, +#            "name": "eth2" +#        }, +#        { +#            "location": { +#                "coordinate_based": { +#                    "altitude": 2200, +#                    "datum": "WGS84", +#                    "latitude": "33.524449N", +#                    "longitude": "222.267255W" +#                } +#            }, +#            "name": "eth1" +#        } +#    ] +# +# After state: +# ------------- +# +# vyos@vyos:~$ show configuration commands | grep lldp +# set service lldp interface eth1 'disable' +# set service lldp interface eth1 location coordinate-based altitude '2200' +# set service lldp interface eth1 location coordinate-based datum 'WGS84' +# set service lldp interface eth1 location coordinate-based latitude '33.524449N' +# set service lldp interface eth1 location coordinate-based longitude '222.267255W' +# set service lldp interface eth2 'disable' +# set service lldp interface eth2 location civic-based ca-type 0 ca-value 'ENGLISH' +# set service lldp interface eth2 location civic-based country-code 'US' + + +# Using overridden +# +# Before state +# -------------- +# +# vyos@vyos:~$ show configuration commands | grep lldp +# set service lldp interface eth1 'disable' +# set service lldp interface eth1 location coordinate-based altitude '2200' +# set service lldp interface eth1 location coordinate-based datum 'WGS84' +# set service lldp interface eth1 location coordinate-based latitude '33.524449N' +# set service lldp interface eth1 location coordinate-based longitude '222.267255W' +# set service lldp interface eth2 'disable' +# set service lldp interface eth2 location civic-based ca-type 0 ca-value 'ENGLISH' +# set service lldp interface eth2 location civic-based country-code 'US' +# +- name: Overrides all device configuration with provided configuration +  vyos_lag_interfaces: +    config: +     - name: 'eth2' +       location: +         elin: 0000000911 + +    state: overridden +# +# +# ------------------------- +# Module Execution Result +# ------------------------- +# +# "before": [ +#        { +#            "enable": false, +#            "location": { +#                "civic_based": { +#                    "ca_info": [ +#                        { +#                            "ca_type": 0, +#                            "ca_value": "ENGLISH" +#                        } +#                    ], +#                    "country_code": "US" +#                } +#            }, +#            "name": "eth2" +#        }, +#        { +#            "enable": false, +#            "location": { +#                "coordinate_based": { +#                    "altitude": 2200, +#                    "datum": "WGS84", +#                    "latitude": "33.524449N", +#                    "longitude": "222.267255W" +#                } +#            }, +#            "name": "eth1" +#        } +#    ] +# +#    "commands": [ +#        "delete service lldp interface eth2 location", +#        "delete service lldp interface eth2 disable", +#        "set service lldp interface eth2 location elin 0000000911" +# +# +#    "after": [ +#        { +#            "location": { +#                "elin": 0000000911 +#            }, +#            "name": "eth2" +#        } +#    ] +# +# +# After state +# ------------ +# +# vyos@vyos# run show configuration commands | grep lldp +# set service lldp interface eth2 location elin '0000000911' + + +# Using deleted +# +# Before state +# ------------- +# +# vyos@vyos# run show configuration commands | grep lldp +# set service lldp interface eth2 location elin '0000000911' +# +- name: Delete lldp  interface attributes of given interfaces. +  vyos_lag_interfaces: +    config: +     - name: 'eth2' +    state: deleted +# +# +# ------------------------ +# Module Execution Results +# ------------------------ +# +    "before": [ +        { +            "location": { +                "elin": 0000000911 +            }, +            "name": "eth2" +        } +    ] +# "commands": [ +#    "commands": [ +#        "delete service lldp interface eth2" +#    ] +# +# "after": [] +# After state +# ------------ +# vyos@vyos# run show configuration commands | grep lldp +# set service 'lldp' + + +""" +RETURN = """ +before: +  description: The configuration prior to the model invocation. +  returned: always +  type: list +  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: list +  sample: > +    The configuration returned will always be in the same format +     of the parameters above. +commands: +  description: The set of commands pushed to the remote device. +  returned: always +  type: list +  sample: +    - "set service lldp interface eth2 'disable'" +    - "delete service lldp interface eth1 location" +""" + + +from ansible.module_utils.basic import AnsibleModule +from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.argspec.lldp_interfaces.lldp_interfaces import ( +    Lldp_interfacesArgs, +) +from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.config.lldp_interfaces.lldp_interfaces import ( +    Lldp_interfaces, +) + + +def main(): +    """ +    Main entry point for module execution + +    :returns: the result form module invocation +    """ +    required_if = [ +        ("state", "merged", ("config",)), +        ("state", "replaced", ("config",)), +        ("state", "overridden", ("config",)), +    ] +    module = AnsibleModule( +        argument_spec=Lldp_interfacesArgs.argument_spec, +        required_if=required_if, +        supports_check_mode=True, +    ) + +    result = Lldp_interfaces(module).execute_module() +    module.exit_json(**result) + + +if __name__ == "__main__": +    main() diff --git a/plugins/modules/vyos_logging.py b/plugins/modules/vyos_logging.py index 8eb5777a..6c2f9f7a 100644 --- a/plugins/modules/vyos_logging.py +++ b/plugins/modules/vyos_logging.py @@ -35,7 +35,8 @@ description:    - This module provides declarative management of logging      on Vyatta Vyos devices.  notes: -  - Tested against VYOS 1.1.7 +  - 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).  options:    dest:      description: diff --git a/plugins/modules/vyos_ping.py b/plugins/modules/vyos_ping.py index 4b21927c..82710490 100644 --- a/plugins/modules/vyos_ping.py +++ b/plugins/modules/vyos_ping.py @@ -73,9 +73,11 @@ options:      choices: [ absent, present ]      default: present  notes: +  - Tested against VyOS 1.1.8 (helium).    - For a general purpose network module, see the M(net_ping) module.    - For Windows targets, use the M(win_ping) module instead.    - For targets running Python, use the M(ping) module instead. +  - This module works with connection C(network_cli). See L(the VyOS OS Platform Options,../network/user_guide/platform_vyos.html).  extends_documentation_fragment: vyos  """ diff --git a/plugins/modules/vyos_static_route.py b/plugins/modules/vyos_static_route.py index b7307ef4..564a2574 100644 --- a/plugins/modules/vyos_static_route.py +++ b/plugins/modules/vyos_static_route.py @@ -36,7 +36,8 @@ description:    - This module provides declarative management of static      IP routes on Vyatta VyOS network devices.  notes: -  - Tested against VYOS 1.1.7 +  - 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).  options:    prefix:      description: diff --git a/plugins/modules/vyos_system.py b/plugins/modules/vyos_system.py index 9fee88f6..30694a61 100644 --- a/plugins/modules/vyos_system.py +++ b/plugins/modules/vyos_system.py @@ -36,7 +36,8 @@ description:      returning successfully.  extends_documentation_fragment: vyos  notes: -  - Tested against VYOS 1.1.7 +  - 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).  options:    host_name:      description: diff --git a/plugins/modules/vyos_user.py b/plugins/modules/vyos_user.py index 2a1181a6..eb71c583 100644 --- a/plugins/modules/vyos_user.py +++ b/plugins/modules/vyos_user.py @@ -38,7 +38,8 @@ description:      current running config. It also supports purging usernames from the      configuration that are not explicitly defined.  notes: -  - Tested against VYOS 1.1.7 +  - 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).  options:    aggregate:      description: diff --git a/plugins/modules/vyos_vlan.py b/plugins/modules/vyos_vlan.py index 10eaecd6..4564749e 100644 --- a/plugins/modules/vyos_vlan.py +++ b/plugins/modules/vyos_vlan.py @@ -25,7 +25,8 @@ description:    - This module provides declarative management of VLANs      on VyOS network devices.  notes: -  - Tested against VYOS 1.1.7 +  - 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).  options:    name:      description: diff --git a/test/integration/integration_config.yml b/test/integration/integration_config.yml deleted file mode 100644 index 6b47a35d..00000000 --- a/test/integration/integration_config.yml +++ /dev/null @@ -1,3 +0,0 @@ ---- -win_output_dir: 'C:\ansible_testing' -output_dir: ~/ansible_testing diff --git a/test/integration/target-prefixes.network b/test/integration/target-prefixes.network index 2d0f40cd..0c45ebaf 100644 --- a/test/integration/target-prefixes.network +++ b/test/integration/target-prefixes.network @@ -1 +1 @@ -vyos +vyos
\ No newline at end of file diff --git a/test/integration/targets/prepare_vyos_tests/tasks/main.yaml b/test/integration/targets/prepare_vyos_tests/tasks/main.yaml index a156ea47..1a81fb17 100644 --- a/test/integration/targets/prepare_vyos_tests/tasks/main.yaml +++ b/test/integration/targets/prepare_vyos_tests/tasks/main.yaml @@ -5,6 +5,8 @@    vars:      lines: |        set interfaces ethernet eth0 address dhcp +      set interfaces ethernet eth0 speed auto +      set interfaces ethernet eth0 duplex auto        set interfaces ethernet eth1        set interfaces ethernet eth2        delete interfaces loopback lo diff --git a/test/integration/targets/vyos_lldp_interfaces/defaults/main.yaml b/test/integration/targets/vyos_lldp_interfaces/defaults/main.yaml new file mode 100644 index 00000000..164afead --- /dev/null +++ b/test/integration/targets/vyos_lldp_interfaces/defaults/main.yaml @@ -0,0 +1,3 @@ +--- +testcase: "[^_].*" +test_items: [] diff --git a/test/integration/targets/vyos_lldp_interfaces/meta/main.yaml b/test/integration/targets/vyos_lldp_interfaces/meta/main.yaml new file mode 100644 index 00000000..f88bce55 --- /dev/null +++ b/test/integration/targets/vyos_lldp_interfaces/meta/main.yaml @@ -0,0 +1,2 @@ +dependencies: +  - prepare_vyos_tests diff --git a/test/integration/targets/vyos_lldp_interfaces/tasks/cli.yaml b/test/integration/targets/vyos_lldp_interfaces/tasks/cli.yaml new file mode 100644 index 00000000..655e51ee --- /dev/null +++ b/test/integration/targets/vyos_lldp_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=network_cli) +  include: "{{ test_case_to_run }}" +  vars: +    ansible_connection: network_cli +  with_items: "{{ test_items }}" +  loop_control: +    loop_var: test_case_to_run diff --git a/test/integration/targets/vyos_lldp_interfaces/tasks/main.yaml b/test/integration/targets/vyos_lldp_interfaces/tasks/main.yaml new file mode 100644 index 00000000..415c99d8 --- /dev/null +++ b/test/integration/targets/vyos_lldp_interfaces/tasks/main.yaml @@ -0,0 +1,2 @@ +--- +- { include: cli.yaml, tags: ['cli'] } diff --git a/test/integration/targets/vyos_lldp_interfaces/tests/cli/_populate.yaml b/test/integration/targets/vyos_lldp_interfaces/tests/cli/_populate.yaml new file mode 100644 index 00000000..80f7d1a1 --- /dev/null +++ b/test/integration/targets/vyos_lldp_interfaces/tests/cli/_populate.yaml @@ -0,0 +1,14 @@ +--- +- name: Setup +  network.cli.cli_config: +    config: "{{ lines }}" +  vars: +    lines: | +      set service lldp interface eth1 +      set service lldp interface eth1 location civic-based country-code US +      set service lldp interface eth1 location civic-based ca-type 0 ca-value ENGLISH +      set service lldp interface eth2 +      set service lldp interface eth2 location coordinate-based latitude 33.524449N +      set service lldp interface eth2 location coordinate-based altitude 2200 +      set service lldp interface eth2 location coordinate-based datum WGS84 +      set service lldp interface eth2 location coordinate-based longitude 222.267255W diff --git a/test/integration/targets/vyos_lldp_interfaces/tests/cli/_populate_intf.yaml b/test/integration/targets/vyos_lldp_interfaces/tests/cli/_populate_intf.yaml new file mode 100644 index 00000000..ee9a9bda --- /dev/null +++ b/test/integration/targets/vyos_lldp_interfaces/tests/cli/_populate_intf.yaml @@ -0,0 +1,10 @@ +--- +- name: Setup +  network.cli.cli_config: +    config: "{{ lines }}" +  vars: +    lines: | +      set service lldp interface eth2 +      set service lldp interface eth2 location civic-based country-code US +      set service lldp interface eth2 location civic-based ca-type 0 ca-value ENGLISH +      set service lldp interface eth2 disable diff --git a/test/integration/targets/vyos_lldp_interfaces/tests/cli/_remove_config.yaml b/test/integration/targets/vyos_lldp_interfaces/tests/cli/_remove_config.yaml new file mode 100644 index 00000000..e3abbdb3 --- /dev/null +++ b/test/integration/targets/vyos_lldp_interfaces/tests/cli/_remove_config.yaml @@ -0,0 +1,8 @@ +--- +- name: Remove Config +  network.cli.cli_config: +    config: "{{ lines }}" +  vars: +    lines: | +      delete service lldp interface +      delete service lldp  diff --git a/test/integration/targets/vyos_lldp_interfaces/tests/cli/deleted.yaml b/test/integration/targets/vyos_lldp_interfaces/tests/cli/deleted.yaml new file mode 100644 index 00000000..bd7c713f --- /dev/null +++ b/test/integration/targets/vyos_lldp_interfaces/tests/cli/deleted.yaml @@ -0,0 +1,46 @@ +--- +- debug: +    msg: "Start vyos_lldp_interfaces deleted integration tests ansible_connection={{ ansible_connection }}" + +- include_tasks: _populate.yaml + +- block: +  - name: Delete attributes of given LLDP interfaces. +    vyos.vyos.vyos_lldp_interfaces: &deleted +      config: +        - name: 'eth1' +        - name: 'eth2' +      state: deleted +    register: result + +  - name: Assert that the before dicts were correctly generated +    assert: +      that: +        - "{{ populate | symmetric_difference(result['before']) |length == 0 }}" + +  - 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'] | symmetric_difference(result['after']) |length == 0 }}" + +  - name: Delete attributes of given interfaces (IDEMPOTENT) +    vyos.vyos.vyos_lldp_interfaces: *deleted +    register: result + +  - 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'] | symmetric_difference(result['before']) |length == 0 }}" +  always: +  - include_tasks: _remove_config.yaml diff --git a/test/integration/targets/vyos_lldp_interfaces/tests/cli/merged.yaml b/test/integration/targets/vyos_lldp_interfaces/tests/cli/merged.yaml new file mode 100644 index 00000000..ae5b10b2 --- /dev/null +++ b/test/integration/targets/vyos_lldp_interfaces/tests/cli/merged.yaml @@ -0,0 +1,58 @@ +--- +- debug: +      msg: "START vyos_lldp_interfaces merged integration tests on connection={{ ansible_connection }}" + +- include_tasks: _remove_config.yaml + +- block: +  - name: Merge the provided configuration with the exisiting running configuration +    vyos.vyos.vyos_lldp_interfaces: &merged +        config: +           - name: 'eth1' +             location: +               civic_based:  +                 country_code: 'US'  +                 ca_info: +                   - ca_type: 0  +                     ca_value: 'ENGLISH'   + +           - name: 'eth2' +             location: +               coordinate_based:  +                altitude: 2200  +                datum: 'WGS84' +                longitude: '222.267255W' +                latitude: '33.524449N'       +        state: merged +    register: result + +  - name: Assert that before dicts were correctly generated +    assert: +        that: "{{ merged['before'] | symmetric_difference(result['before']) |length == 0 }}" + +  - 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'] | symmetric_difference(result['after']) |length == 0 }}" + +  - name: Merge the provided configuration with the existing running configuration (IDEMPOTENT) +    vyos.vyos.vyos_lldp_interfaces: *merged +    register: result + +  - 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'] | symmetric_difference(result['before']) |length == 0 }}" + +  always: +  - include_tasks: _remove_config.yaml diff --git a/test/integration/targets/vyos_lldp_interfaces/tests/cli/overridden.yaml b/test/integration/targets/vyos_lldp_interfaces/tests/cli/overridden.yaml new file mode 100644 index 00000000..eedb563e --- /dev/null +++ b/test/integration/targets/vyos_lldp_interfaces/tests/cli/overridden.yaml @@ -0,0 +1,49 @@ +--- +- debug: +      msg: "START vyos_lldp_interfaces overridden integration tests on connection={{ ansible_connection }}" + +- include_tasks: _remove_config.yaml + +- include_tasks: _populate_intf.yaml + +- block: +  - name: Overrides all device configuration with provided configuration +    vyos.vyos.vyos_lldp_interfaces: &overridden +       config: +        - name: 'eth2' +          location: +            elin: '0000000911' +       state: overridden +    register: result + +  - name: Assert that before dicts were correctly generated +    assert: +        that: +            - "{{ populate_intf | symmetric_difference(result['before']) |length == 0 }}" + +  - name: Assert that correct commands were generated +    assert: +        that: +            - "{{ overridden['commands'] | symmetric_difference(result['commands']) |length == 0 }}" + +  - name: Assert that after dicts were correctly generated +    assert: +        that: +            - "{{ overridden['after'] | symmetric_difference(result['after']) |length == 0 }}" + +  - name: Overrides all device configuration with provided configurations (IDEMPOTENT) +    vyos.vyos.vyos_lldp_interfaces: *overridden +    register: result + +  - name: Assert that the previous task was idempotent +    assert: +        that: +            - "result['changed'] == false" + +  - name: Assert that before dicts were correctly generated +    assert: +        that: +            - "{{ overridden['after'] | symmetric_difference(result['before']) |length == 0 }}" + +  always: +  - include_tasks: _remove_config.yaml diff --git a/test/integration/targets/vyos_lldp_interfaces/tests/cli/replaced.yaml b/test/integration/targets/vyos_lldp_interfaces/tests/cli/replaced.yaml new file mode 100644 index 00000000..07fec9ed --- /dev/null +++ b/test/integration/targets/vyos_lldp_interfaces/tests/cli/replaced.yaml @@ -0,0 +1,63 @@ +--- +- debug: +      msg: "START vyos_lldp_interfaces replaced integration tests on connection={{ ansible_connection }}" + +- include_tasks: _remove_config.yaml + +- include_tasks: _populate.yaml + +- block: +  - name: Replace device configurations of listed LLDP interfaces with provided configurations +    vyos.vyos.vyos_lldp_interfaces: &replaced +        config: +           - name: 'eth2' +             enable: false +             location: +               civic_based:  +                 country_code: 'US'  +                 ca_info: +                   - ca_type: 0  +                     ca_value: 'ENGLISH' + +           - name: 'eth1' +             enable: false +             location: +               coordinate_based:  +                altitude: 2200  +                datum: 'WGS84' +                longitude: '222.267255W' +                latitude: '33.524449N' +        state: replaced +    register: result + +  - 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 | symmetric_difference(result['before']) |length == 0 }}" + +  - name: Assert that after dict is correctly generated +    assert: +        that: +            - "{{ replaced['after'] | symmetric_difference(result['after']) |length == 0 }}" + +  - name: Replace device configurations of listed LLDP interfaces with provided configurarions (IDEMPOTENT) +    vyos.vyos.vyos_lldp_interfaces: *replaced +    register: result + +  - name: Assert that task was idempotent +    assert: +        that: +            - "result['changed'] == false" + +  - name: Assert that before dict is correctly generated +    assert: +        that: +            - "{{ replaced['after'] | symmetric_difference(result['before']) |length == 0 }}" + +  always: +  - include_tasks: _remove_config.yaml diff --git a/test/integration/targets/vyos_lldp_interfaces/tests/cli/rtt.yaml b/test/integration/targets/vyos_lldp_interfaces/tests/cli/rtt.yaml new file mode 100644 index 00000000..d97cf9c4 --- /dev/null +++ b/test/integration/targets/vyos_lldp_interfaces/tests/cli/rtt.yaml @@ -0,0 +1,57 @@ +--- +- debug: +    msg: "START vyos_lldp_interfaces round trip integration tests on connection={{ ansible_connection }}" + +- include_tasks: _remove_config.yaml + +- block: +  - name: Apply the provided configuration (base config) +    vyos.vyos.vyos_lldp_interfaces: +      config: +        - name: 'eth1' +          location: +            civic_based:  +              country_code: 'US'  +              ca_info: +                - ca_type: 0  +                  ca_value: 'ENGLISH' + +      state: merged +    register: base_config + +  - name: Gather lldp_interfaces facts +    vyos.vyos.vyos_facts: +      gather_subset: +        - default +      gather_network_resources: +        - lldp_interfaces + +  - name: Apply the provided configuration (config to be reverted) +    vyos.vyos.vyos_lldp_interfaces: +      config: +        - name: 'eth2' +          location: +            coordinate_based:  +             altitude: 2200  +             datum: 'WGS84' +             longitude: '222.267255W' +             latitude: '33.524449N'         +      state: merged +    register: result + +  - name: Assert that changes were applied +    assert: +      that: "{{ round_trip['after'] | symmetric_difference(result['after']) |length == 0 }}" + +  - name: Revert back to base config using facts round trip +    vyos.vyos.vyos_lldp_interfaces: +      config: "{{ ansible_facts['network_resources']['lldp_interfaces'] }}" +      state: overridden +    register: revert + +  - name: Assert that config was reverted +    assert: +      that: "{{ base_config['after'] | symmetric_difference(revert['after']) |length == 0 }}" + +  always: +  - include_tasks: _remove_config.yaml diff --git a/test/integration/targets/vyos_lldp_interfaces/vars/main.yaml b/test/integration/targets/vyos_lldp_interfaces/vars/main.yaml new file mode 100644 index 00000000..6f33343c --- /dev/null +++ b/test/integration/targets/vyos_lldp_interfaces/vars/main.yaml @@ -0,0 +1,130 @@ +--- +merged: +  before: [] + + +  commands: +    - "set service lldp interface eth1 location civic-based country-code 'US'" +    - "set service lldp interface eth1 location civic-based ca-type 0 ca-value 'ENGLISH'" +    - "set service lldp interface eth1" +    - "set service lldp interface eth2 location coordinate-based latitude '33.524449N'" +    - "set service lldp interface eth2 location coordinate-based altitude '2200'" +    - "set service lldp interface eth2 location coordinate-based datum 'WGS84'" +    - "set service lldp interface eth2 location coordinate-based longitude '222.267255W'" +    - "set service lldp interface eth2 location coordinate-based latitude '33.524449N'" +    - "set service lldp interface eth2 location coordinate-based altitude '2200'" +    - "set service lldp interface eth2 location coordinate-based datum 'WGS84'" +    - "set service lldp interface eth2 location coordinate-based longitude '222.267255W'" +    - "set service lldp interface eth2" + +  after: +    - name: 'eth1' +      location: +        civic_based:  +          country_code: 'US'  +          ca_info: +            - ca_type: 0  +              ca_value: 'ENGLISH'   + +    - name: 'eth2' +      location: +        coordinate_based:  +         altitude: 2200  +         datum: 'WGS84' +         longitude: '222.267255W' +         latitude: '33.524449N'   + +populate: +  - name: 'eth1' +    location: +      civic_based:  +        country_code: 'US'  +        ca_info: +          - ca_type: 0  +            ca_value: 'ENGLISH'   + +  - name: 'eth2' +    location: +      coordinate_based:  +       altitude: 2200  +       datum: 'WGS84' +       longitude: '222.267255W' +       latitude: '33.524449N'   + +replaced: +  commands: +    - "delete service lldp interface eth2 location" +    - "set service lldp interface eth2 'disable'" +    - "set service lldp interface eth2 location civic-based country-code 'US'" +    - "set service lldp interface eth2 location civic-based ca-type 0 ca-value 'ENGLISH'" +    - "delete service lldp interface eth1 location" +    - "set service lldp interface eth1 'disable'" +    - "set service lldp interface eth1 location coordinate-based latitude '33.524449N'" +    - "set service lldp interface eth1 location coordinate-based altitude '2200'" +    - "set service lldp interface eth1 location coordinate-based datum 'WGS84'" +    - "set service lldp interface eth1 location coordinate-based longitude '222.267255W'" + +  after: +    - name: 'eth2' +      enable: false +      location: +        civic_based:  +          country_code: 'US'  +          ca_info: +            - ca_type: 0  +              ca_value: 'ENGLISH'   + +    - name: 'eth1' +      enable: false +      location: +        coordinate_based:  +         altitude: 2200  +         datum: 'WGS84' +         longitude: '222.267255W' +         latitude: '33.524449N'   + +populate_intf: +  - name: 'eth2' +    enable: false +    location: +      civic_based:  +        country_code: 'US'  +        ca_info: +          - ca_type: 0  +            ca_value: 'ENGLISH'   + +overridden: +  commands: +    - "delete service lldp interface eth2 location"  +    - "delete service lldp interface eth2 'disable'"  +    - "set service lldp interface eth2 location elin '0000000911'" + +  after: +    - name: 'eth2' +      location: +        elin: 0000000911 + +deleted: +  commands: +    - "delete service lldp interface eth1" +    - "delete service lldp interface eth2" + +  after: [] + +round_trip: +  after: +    - name: 'eth1' +      location: +        civic_based:  +          country_code: 'US'  +          ca_info: +            - ca_type: 0  +              ca_value: 'ENGLISH' + +    - name: 'eth2' +      location: +        coordinate_based:  +         altitude: 2200  +         datum: 'WGS84' +         longitude: '222.267255W' +         latitude: '33.524449N' | 
