diff options
238 files changed, 6452 insertions, 3684 deletions
diff --git a/plugins/action/__init__.py b/plugins/action/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/plugins/action/__init__.py diff --git a/plugins/action/vyos.py b/plugins/action/vyos.py new file mode 100644 index 0000000..cab2f3f --- /dev/null +++ b/plugins/action/vyos.py @@ -0,0 +1,129 @@ +# +# (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/>. +# +from __future__ import absolute_import, division, print_function + +__metaclass__ = type + +import sys +import copy + +from ansible_collections.ansible.netcommon.plugins.action.network import ( + ActionModule as ActionNetworkModule, +) +from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.utils import ( + load_provider, +) +from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.vyos import ( + vyos_provider_spec, +) +from ansible.utils.display import Display + +display = Display() + + +class ActionModule(ActionNetworkModule): + def run(self, tmp=None, task_vars=None): + del tmp # tmp no longer has any effect + + module_name = self._task.action.split(".")[-1] + self._config_module = True if module_name == "vyos_config" else False + persistent_connection = self._play_context.connection.split(".")[-1] + warnings = [] + + if persistent_connection == "network_cli": + provider = self._task.args.get("provider", {}) + if any(provider.values()): + display.warning( + "provider is unnecessary when using network_cli and will be ignored" + ) + del self._task.args["provider"] + elif self._play_context.connection == "local": + provider = load_provider(vyos_provider_spec, self._task.args) + pc = copy.deepcopy(self._play_context) + pc.connection = "ansible.netcommon.network_cli" + pc.network_os = "vyos.vyos.vyos" + pc.remote_addr = provider["host"] or self._play_context.remote_addr + pc.port = int(provider["port"] or self._play_context.port or 22) + pc.remote_user = ( + provider["username"] or self._play_context.connection_user + ) + pc.password = provider["password"] or self._play_context.password + pc.private_key_file = ( + provider["ssh_keyfile"] or self._play_context.private_key_file + ) + + connection = self._shared_loader_obj.connection_loader.get( + "ansible.netcommon.persistent", + pc, + sys.stdin, + task_uuid=self._task._uuid, + ) + + # TODO: Remove below code after ansible minimal is cut out + if connection is None: + pc.connection = "network_cli" + pc.network_os = "vyos" + connection = self._shared_loader_obj.connection_loader.get( + "persistent", pc, sys.stdin, task_uuid=self._task._uuid + ) + + display.vvv( + "using connection plugin %s (was local)" % pc.connection, + pc.remote_addr, + ) + + command_timeout = ( + int(provider["timeout"]) + if provider["timeout"] + else connection.get_option("persistent_command_timeout") + ) + connection.set_options( + direct={"persistent_command_timeout": command_timeout} + ) + + socket_path = connection.run() + display.vvvv("socket_path: %s" % socket_path, pc.remote_addr) + if not socket_path: + return { + "failed": True, + "msg": "unable to open shell. Please see: " + + "https://docs.ansible.com/ansible/network_debug_troubleshooting.html#unable-to-open-shell", + } + + task_vars["ansible_socket"] = socket_path + warnings.append( + [ + "connection local support for this module is deprecated and will be removed in version 2.14, use connection %s" + % pc.connection + ] + ) + else: + return { + "failed": True, + "msg": "Connection type %s is not valid for this module" + % self._play_context.connection, + } + + result = super(ActionModule, self).run(task_vars=task_vars) + if warnings: + if "warnings" in result: + result["warnings"].extend(warnings) + else: + result["warnings"] = warnings + return result diff --git a/plugins/cliconf/__init__.py b/plugins/cliconf/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/plugins/cliconf/__init__.py diff --git a/plugins/cliconf/vyos.py b/plugins/cliconf/vyos.py new file mode 100644 index 0000000..3033603 --- /dev/null +++ b/plugins/cliconf/vyos.py @@ -0,0 +1,342 @@ +# +# (c) 2017 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/>. +# +from __future__ import absolute_import, division, print_function + +__metaclass__ = type + +DOCUMENTATION = """ +--- +author: Ansible Networking Team +cliconf: vyos +short_description: Use vyos cliconf to run command on VyOS platform +description: + - This vyos plugin provides low level abstraction apis for + sending and receiving CLI commands from VyOS network devices. +version_added: "2.4" +""" + +import re +import json + +from ansible.errors import AnsibleConnectionFailure +from ansible.module_utils._text import to_text +from ansible.module_utils.common._collections_compat import Mapping +from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.config import ( + NetworkConfig, +) +from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.utils import ( + to_list, +) +from ansible.plugins.cliconf import CliconfBase + + +class Cliconf(CliconfBase): + def get_device_info(self): + device_info = {} + + device_info["network_os"] = "vyos" + reply = self.get("show version") + data = to_text(reply, errors="surrogate_or_strict").strip() + + match = re.search(r"Version:\s*(.*)", data) + if match: + device_info["network_os_version"] = match.group(1) + + match = re.search(r"HW model:\s*(\S+)", data) + if match: + device_info["network_os_model"] = match.group(1) + + reply = self.get("show host name") + device_info["network_os_hostname"] = to_text( + reply, errors="surrogate_or_strict" + ).strip() + + return device_info + + def get_config(self, flags=None, format=None): + if format: + option_values = self.get_option_values() + if format not in option_values["format"]: + raise ValueError( + "'format' value %s is invalid. Valid values of format are %s" + % (format, ", ".join(option_values["format"])) + ) + + if not flags: + flags = [] + + if format == "text": + command = "show configuration" + else: + command = "show configuration commands" + + command += " ".join(to_list(flags)) + command = command.strip() + + out = self.send_command(command) + return out + + def edit_config( + self, candidate=None, commit=True, replace=None, comment=None + ): + resp = {} + operations = self.get_device_operations() + self.check_edit_config_capability( + operations, candidate, commit, replace, comment + ) + + results = [] + requests = [] + self.send_command("configure") + for cmd in to_list(candidate): + if not isinstance(cmd, Mapping): + cmd = {"command": cmd} + + results.append(self.send_command(**cmd)) + requests.append(cmd["command"]) + out = self.get("compare") + out = to_text(out, errors="surrogate_or_strict") + diff_config = out if not out.startswith("No changes") else None + + if diff_config: + if commit: + try: + self.commit(comment) + except AnsibleConnectionFailure as e: + msg = "commit failed: %s" % e.message + self.discard_changes() + raise AnsibleConnectionFailure(msg) + else: + self.send_command("exit") + else: + self.discard_changes() + else: + self.send_command("exit") + if ( + to_text( + self._connection.get_prompt(), errors="surrogate_or_strict" + ) + .strip() + .endswith("#") + ): + self.discard_changes() + + if diff_config: + resp["diff"] = diff_config + resp["response"] = results + resp["request"] = requests + return resp + + def get( + self, + command=None, + prompt=None, + answer=None, + sendonly=False, + output=None, + newline=True, + check_all=False, + ): + if not command: + raise ValueError("must provide value of command to execute") + if output: + raise ValueError( + "'output' value %s is not supported for get" % output + ) + + return self.send_command( + command=command, + prompt=prompt, + answer=answer, + sendonly=sendonly, + newline=newline, + check_all=check_all, + ) + + def commit(self, comment=None): + if comment: + command = 'commit comment "{0}"'.format(comment) + else: + command = "commit" + self.send_command(command) + + def discard_changes(self): + self.send_command("exit discard") + + def get_diff( + self, + candidate=None, + running=None, + diff_match="line", + diff_ignore_lines=None, + path=None, + diff_replace=None, + ): + diff = {} + device_operations = self.get_device_operations() + option_values = self.get_option_values() + + if candidate is None and device_operations["supports_generate_diff"]: + raise ValueError( + "candidate configuration is required to generate diff" + ) + + if diff_match not in option_values["diff_match"]: + raise ValueError( + "'match' value %s in invalid, valid values are %s" + % (diff_match, ", ".join(option_values["diff_match"])) + ) + + if diff_replace: + raise ValueError("'replace' in diff is not supported") + + if diff_ignore_lines: + raise ValueError("'diff_ignore_lines' in diff is not supported") + + if path: + raise ValueError("'path' in diff is not supported") + + set_format = candidate.startswith("set") or candidate.startswith( + "delete" + ) + candidate_obj = NetworkConfig(indent=4, contents=candidate) + if not set_format: + config = [c.line for c in candidate_obj.items] + commands = list() + # this filters out less specific lines + for item in config: + for index, entry in enumerate(commands): + if item.startswith(entry): + del commands[index] + break + commands.append(item) + + candidate_commands = [ + "set %s" % cmd.replace(" {", "") for cmd in commands + ] + + else: + candidate_commands = str(candidate).strip().split("\n") + + if diff_match == "none": + diff["config_diff"] = list(candidate_commands) + return diff + + running_commands = [ + str(c).replace("'", "") for c in running.splitlines() + ] + + updates = list() + visited = set() + + for line in candidate_commands: + item = str(line).replace("'", "") + + if not item.startswith("set") and not item.startswith("delete"): + raise ValueError( + "line must start with either `set` or `delete`" + ) + + elif item.startswith("set") and item not in running_commands: + updates.append(line) + + elif item.startswith("delete"): + if not running_commands: + updates.append(line) + else: + item = re.sub(r"delete", "set", item) + for entry in running_commands: + if entry.startswith(item) and line not in visited: + updates.append(line) + visited.add(line) + + diff["config_diff"] = list(updates) + return diff + + def run_commands(self, commands=None, check_rc=True): + if commands is None: + raise ValueError("'commands' value is required") + + responses = list() + for cmd in to_list(commands): + if not isinstance(cmd, Mapping): + cmd = {"command": cmd} + + output = cmd.pop("output", None) + if output: + raise ValueError( + "'output' value %s is not supported for run_commands" + % output + ) + + try: + out = self.send_command(**cmd) + except AnsibleConnectionFailure as e: + if check_rc: + raise + out = getattr(e, "err", e) + + responses.append(out) + + return responses + + def get_device_operations(self): + return { + "supports_diff_replace": False, + "supports_commit": True, + "supports_rollback": False, + "supports_defaults": False, + "supports_onbox_diff": True, + "supports_commit_comment": True, + "supports_multiline_delimiter": False, + "supports_diff_match": True, + "supports_diff_ignore_lines": False, + "supports_generate_diff": False, + "supports_replace": False, + } + + def get_option_values(self): + return { + "format": ["text", "set"], + "diff_match": ["line", "none"], + "diff_replace": [], + "output": [], + } + + def get_capabilities(self): + result = super(Cliconf, self).get_capabilities() + result["rpc"] += [ + "commit", + "discard_changes", + "get_diff", + "run_commands", + ] + result["device_operations"] = self.get_device_operations() + result.update(self.get_option_values()) + return json.dumps(result) + + def set_cli_prompt_context(self): + """ + Make sure we are in the operational cli mode + :return: None + """ + if self._connection.connected: + self._update_cli_prompt_context( + config_context="#", exit_command="exit discard" + ) diff --git a/plugins/doc_fragments/__init__.py b/plugins/doc_fragments/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/plugins/doc_fragments/__init__.py diff --git a/plugins/doc_fragments/vyos.py b/plugins/doc_fragments/vyos.py new file mode 100644 index 0000000..094963f --- /dev/null +++ b/plugins/doc_fragments/vyos.py @@ -0,0 +1,63 @@ +# -*- coding: utf-8 -*- + +# Copyright: (c) 2015, Peter Sprygada <psprygada@ansible.com> +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + + +class ModuleDocFragment(object): + + # Standard files documentation fragment + DOCUMENTATION = r"""options: + provider: + description: + - B(Deprecated) + - 'Starting with Ansible 2.5 we recommend using C(connection: network_cli).' + - For more information please see the L(Network Guide, ../network/getting_started/network_differences.html#multiple-communication-protocols). + - HORIZONTALLINE + - A dict object containing connection details. + type: dict + suboptions: + host: + description: + - Specifies the DNS host name or address for connecting to the remote device + over the specified transport. The value of host is used as the destination + address for the transport. + type: str + required: true + port: + description: + - Specifies the port to use when building the connection to the remote device. + type: int + default: 22 + username: + description: + - Configures the username to use to authenticate the connection to the remote + device. This value is used to authenticate the SSH session. If the value + is not specified in the task, the value of environment variable C(ANSIBLE_NET_USERNAME) + will be used instead. + type: str + password: + description: + - Specifies the password to use to authenticate the connection to the remote + device. This value is used to authenticate the SSH session. If the value + is not specified in the task, the value of environment variable C(ANSIBLE_NET_PASSWORD) + will be used instead. + type: str + timeout: + description: + - Specifies the timeout in seconds for communicating with the network device + for either connecting or sending commands. If the timeout is exceeded before + the operation is completed, the module will error. + type: int + default: 10 + ssh_keyfile: + description: + - Specifies the SSH key to use to authenticate the connection to the remote + device. This value is the path to the key used to authenticate the SSH + session. If the value is not specified in the task, the value of environment + variable C(ANSIBLE_NET_SSH_KEYFILE) will be used instead. + type: path +notes: +- For more information on using Ansible to manage network devices see the :ref:`Ansible + Network Guide <network_guide>` +""" diff --git a/plugins/module_utils/__init__.py b/plugins/module_utils/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/plugins/module_utils/__init__.py diff --git a/plugins/module_utils/network/vyos/config/interfaces/interfaces.py b/plugins/module_utils/network/vyos/config/interfaces/interfaces.py index d781fd0..deb504c 100644 --- a/plugins/module_utils/network/vyos/config/interfaces/interfaces.py +++ b/plugins/module_utils/network/vyos/config/interfaces/interfaces.py @@ -15,8 +15,10 @@ __metaclass__ = type from copy import deepcopy -from ansible.module_utils.network.common.cfg.base import ConfigBase -from ansible.module_utils.network.common.utils import ( +from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.cfg.base import ( + ConfigBase, +) +from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.utils import ( to_list, dict_diff, remove_empties, @@ -37,7 +39,10 @@ class Interfaces(ConfigBase): The vyos_interfaces class """ - gather_subset = ["!all", "!min"] + gather_subset = [ + "!all", + "!min", + ] gather_network_resources = ["interfaces"] diff --git a/plugins/module_utils/network/vyos/config/l3_interfaces/l3_interfaces.py b/plugins/module_utils/network/vyos/config/l3_interfaces/l3_interfaces.py index fb7dbdc..a23e417 100644 --- a/plugins/module_utils/network/vyos/config/l3_interfaces/l3_interfaces.py +++ b/plugins/module_utils/network/vyos/config/l3_interfaces/l3_interfaces.py @@ -17,8 +17,13 @@ __metaclass__ = type from copy import deepcopy -from ansible.module_utils.network.common.cfg.base import ConfigBase -from ansible.module_utils.network.common.utils import to_list, remove_empties +from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.cfg.base import ( + ConfigBase, +) +from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.utils import ( + to_list, + remove_empties, +) from ansible.module_utils.six import iteritems from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.facts.facts import ( Facts, @@ -35,9 +40,14 @@ class L3_interfaces(ConfigBase): The vyos_l3_interfaces class """ - gather_subset = ["!all", "!min"] + gather_subset = [ + "!all", + "!min", + ] - gather_network_resources = ["l3_interfaces"] + gather_network_resources = [ + "l3_interfaces", + ] def __init__(self, module): super(L3_interfaces, self).__init__(module) diff --git a/plugins/module_utils/network/vyos/config/lag_interfaces/lag_interfaces.py b/plugins/module_utils/network/vyos/config/lag_interfaces/lag_interfaces.py index 290f3b3..2a9efd9 100644 --- a/plugins/module_utils/network/vyos/config/lag_interfaces/lag_interfaces.py +++ b/plugins/module_utils/network/vyos/config/lag_interfaces/lag_interfaces.py @@ -11,11 +11,16 @@ created from __future__ import absolute_import, division, print_function __metaclass__ = type -from ansible.module_utils.network.common.cfg.base import ConfigBase +from ansible_collections.ansible.netcommon.plugins.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_collections.ansible.netcommon.plugins.module_utils.network.common.utils import ( + to_list, + dict_diff, +) from ansible.module_utils.six import iteritems from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.utils.utils import ( search_obj_in_list, @@ -30,9 +35,14 @@ class Lag_interfaces(ConfigBase): The vyos_lag_interfaces class """ - gather_subset = ["!all", "!min"] + gather_subset = [ + "!all", + "!min", + ] - gather_network_resources = ["lag_interfaces"] + gather_network_resources = [ + "lag_interfaces", + ] params = [ "arp_monitor", diff --git a/plugins/module_utils/network/vyos/config/lldp_global/lldp_global.py b/plugins/module_utils/network/vyos/config/lldp_global/lldp_global.py index 303d46a..010e96d 100644 --- a/plugins/module_utils/network/vyos/config/lldp_global/lldp_global.py +++ b/plugins/module_utils/network/vyos/config/lldp_global/lldp_global.py @@ -11,8 +11,13 @@ created from __future__ import absolute_import, division, print_function __metaclass__ = type -from ansible.module_utils.network.common.cfg.base import ConfigBase -from ansible.module_utils.network.common.utils import to_list, dict_diff +from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.cfg.base import ( + ConfigBase, +) +from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.utils import ( + to_list, + dict_diff, +) from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.facts.facts import ( Facts, ) @@ -28,9 +33,14 @@ class Lldp_global(ConfigBase): The vyos_lldp_global class """ - gather_subset = ["!all", "!min"] + gather_subset = [ + "!all", + "!min", + ] - gather_network_resources = ["lldp_global"] + gather_network_resources = [ + "lldp_global", + ] params = ["enable", "address", "snmp", "legacy_protocols"] 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 index aa0bd36..377fec9 100644 --- a/plugins/module_utils/network/vyos/config/lldp_interfaces/lldp_interfaces.py +++ b/plugins/module_utils/network/vyos/config/lldp_interfaces/lldp_interfaces.py @@ -16,13 +16,18 @@ from __future__ import absolute_import, division, print_function __metaclass__ = type -from ansible.module_utils.network.common.cfg.base import ConfigBase +from ansible_collections.ansible.netcommon.plugins.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_collections.ansible.netcommon.plugins.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 ( +from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.utils.utils import ( search_obj_in_list, search_dict_tv_in_list, key_value_in_dict, @@ -35,9 +40,14 @@ class Lldp_interfaces(ConfigBase): The vyos_lldp_interfaces class """ - gather_subset = ["!all", "!min"] + gather_subset = [ + "!all", + "!min", + ] - gather_network_resources = ["lldp_interfaces"] + gather_network_resources = [ + "lldp_interfaces", + ] params = ["enable", "location", "name"] diff --git a/plugins/module_utils/network/vyos/facts/facts.py b/plugins/module_utils/network/vyos/facts/facts.py index bb292e1..b5816c2 100644 --- a/plugins/module_utils/network/vyos/facts/facts.py +++ b/plugins/module_utils/network/vyos/facts/facts.py @@ -9,7 +9,9 @@ calls the appropriate facts gathering function from __future__ import absolute_import, division, print_function __metaclass__ = type -from ansible.module_utils.network.common.facts.facts import FactsBase +from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.facts.facts import ( + FactsBase, +) from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.facts.interfaces.interfaces import ( InterfacesFacts, ) diff --git a/plugins/module_utils/network/vyos/facts/interfaces/interfaces.py b/plugins/module_utils/network/vyos/facts/interfaces/interfaces.py index 7b73b9b..4b24803 100644 --- a/plugins/module_utils/network/vyos/facts/interfaces/interfaces.py +++ b/plugins/module_utils/network/vyos/facts/interfaces/interfaces.py @@ -17,7 +17,9 @@ __metaclass__ = type from re import findall, M from copy import deepcopy -from ansible.module_utils.network.common import utils +from ansible_collections.ansible.netcommon.plugins.module_utils.network.common import ( + utils, +) from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.argspec.interfaces.interfaces import ( InterfacesArgs, ) diff --git a/plugins/module_utils/network/vyos/facts/l3_interfaces/l3_interfaces.py b/plugins/module_utils/network/vyos/facts/l3_interfaces/l3_interfaces.py index 05973ba..babfc85 100644 --- a/plugins/module_utils/network/vyos/facts/l3_interfaces/l3_interfaces.py +++ b/plugins/module_utils/network/vyos/facts/l3_interfaces/l3_interfaces.py @@ -17,7 +17,9 @@ __metaclass__ = type import re from copy import deepcopy -from ansible.module_utils.network.common import utils +from ansible_collections.ansible.netcommon.plugins.module_utils.network.common import ( + utils, +) from ansible.module_utils.six import iteritems from ansible.module_utils.compat import ipaddress from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.argspec.l3_interfaces.l3_interfaces import ( diff --git a/plugins/module_utils/network/vyos/facts/lag_interfaces/lag_interfaces.py b/plugins/module_utils/network/vyos/facts/lag_interfaces/lag_interfaces.py index 6ae780f..9201e5c 100644 --- a/plugins/module_utils/network/vyos/facts/lag_interfaces/lag_interfaces.py +++ b/plugins/module_utils/network/vyos/facts/lag_interfaces/lag_interfaces.py @@ -15,7 +15,9 @@ __metaclass__ = type from re import findall, search, M from copy import deepcopy -from ansible.module_utils.network.common import utils +from ansible_collections.ansible.netcommon.plugins.module_utils.network.common import ( + utils, +) from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.argspec.lag_interfaces.lag_interfaces import ( Lag_interfacesArgs, ) diff --git a/plugins/module_utils/network/vyos/facts/legacy/base.py b/plugins/module_utils/network/vyos/facts/legacy/base.py index dce93aa..f6b343e 100644 --- a/plugins/module_utils/network/vyos/facts/legacy/base.py +++ b/plugins/module_utils/network/vyos/facts/legacy/base.py @@ -14,7 +14,7 @@ from __future__ import absolute_import, division, print_function __metaclass__ = type import platform import re -from ansible.module_utils.network.vyos.vyos import ( +from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.vyos import ( run_commands, get_capabilities, ) @@ -36,7 +36,9 @@ class LegacyFactsBase(object): class Default(LegacyFactsBase): - COMMANDS = ["show version"] + COMMANDS = [ + "show version", + ] def populate(self): super(Default, self).populate() @@ -70,7 +72,10 @@ class Default(LegacyFactsBase): class Config(LegacyFactsBase): - COMMANDS = ["show configuration commands", "show system commit"] + COMMANDS = [ + "show configuration commands", + "show system commit", + ] def populate(self): super(Config, self).populate() @@ -102,7 +107,10 @@ class Config(LegacyFactsBase): class Neighbors(LegacyFactsBase): - COMMANDS = ["show lldp neighbors", "show lldp neighbors detail"] + COMMANDS = [ + "show lldp neighbors", + "show lldp neighbors detail", + ] def populate(self): super(Neighbors, self).populate() diff --git a/plugins/module_utils/network/vyos/facts/lldp_global/lldp_global.py b/plugins/module_utils/network/vyos/facts/lldp_global/lldp_global.py index 8954393..3c7e2f9 100644 --- a/plugins/module_utils/network/vyos/facts/lldp_global/lldp_global.py +++ b/plugins/module_utils/network/vyos/facts/lldp_global/lldp_global.py @@ -16,7 +16,9 @@ __metaclass__ = type from re import findall, M from copy import deepcopy -from ansible.module_utils.network.common import utils +from ansible_collections.ansible.netcommon.plugins.module_utils.network.common import ( + utils, +) from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.argspec.lldp_global.lldp_global import ( Lldp_globalArgs, ) 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 index 72629ed..dcfbc6e 100644 --- a/plugins/module_utils/network/vyos/facts/lldp_interfaces/lldp_interfaces.py +++ b/plugins/module_utils/network/vyos/facts/lldp_interfaces/lldp_interfaces.py @@ -18,7 +18,9 @@ __metaclass__ = type from re import findall, search, M from copy import deepcopy -from ansible.module_utils.network.common import utils +from ansible_collections.ansible.netcommon.plugins.module_utils.network.common import ( + utils, +) from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.argspec.lldp_interfaces.lldp_interfaces import ( Lldp_interfacesArgs, ) diff --git a/plugins/module_utils/network/vyos/vyos.py b/plugins/module_utils/network/vyos/vyos.py index 1d2c508..908395a 100644 --- a/plugins/module_utils/network/vyos/vyos.py +++ b/plugins/module_utils/network/vyos/vyos.py @@ -46,7 +46,9 @@ vyos_provider_spec = { "timeout": dict(type="int"), } vyos_argument_spec = { - "provider": dict(type="dict", options=vyos_provider_spec) + "provider": dict( + type="dict", options=vyos_provider_spec, removed_in_version=2.14 + ), } diff --git a/plugins/modules/_vyos_interface.py b/plugins/modules/_vyos_interface.py deleted file mode 100644 index 71a98c5..0000000 --- a/plugins/modules/_vyos_interface.py +++ /dev/null @@ -1,468 +0,0 @@ -#!/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_interface -version_added: "2.4" -author: "Ganesh Nalawade (@ganeshrn)" -short_description: Manage Interface on VyOS network devices -description: - - This module provides declarative management of Interfaces - on VyOS network devices. -deprecated: - removed_in: '2.13' - alternative: vyos_interfaces - why: Updated modules released with more functionality. -notes: - - Tested against VYOS 1.1.7 -options: - name: - description: - - Name of the Interface. - required: true - description: - description: - - Description of Interface. - enabled: - description: - - Interface link status. - type: bool - speed: - description: - - Interface link speed. - mtu: - description: - - Maximum size of transmit packet. - duplex: - description: - - Interface link status. - default: auto - choices: ['full', 'half', 'auto'] - delay: - description: - - Time in seconds to wait before checking for the operational state on remote - device. This wait is applicable for operational state argument which are - I(state) with values C(up)/C(down) and I(neighbors). - default: 10 - neighbors: - description: - - Check the operational state of given interface C(name) for LLDP neighbor. - - The following suboptions are available. - suboptions: - host: - description: - - "LLDP neighbor host for given interface C(name)." - port: - description: - - "LLDP neighbor port to which given interface C(name) is connected." - version_added: 2.5 - aggregate: - description: List of Interfaces definitions. - state: - description: - - State of the Interface configuration, C(up) means present and - operationally up and C(down) means present and operationally C(down) - default: present - choices: ['present', 'absent', 'up', 'down'] -extends_documentation_fragment: vyos -""" - -EXAMPLES = """ -- name: configure interface - vyos_interface: - name: eth0 - description: test-interface - -- name: remove interface - vyos_interface: - name: eth0 - state: absent - -- name: make interface down - vyos_interface: - name: eth0 - enabled: False - -- name: make interface up - vyos_interface: - name: eth0 - enabled: True - -- name: Configure interface speed, mtu, duplex - vyos_interface: - name: eth5 - state: present - speed: 100 - mtu: 256 - duplex: full - -- name: Set interface using aggregate - vyos_interface: - aggregate: - - { name: eth1, description: test-interface-1, speed: 100, duplex: half, mtu: 512} - - { name: eth2, description: test-interface-2, speed: 1000, duplex: full, mtu: 256} - -- name: Disable interface on aggregate - net_interface: - aggregate: - - name: eth1 - - name: eth2 - enabled: False - -- name: Delete interface using aggregate - net_interface: - aggregate: - - name: eth1 - - name: eth2 - state: absent - -- name: Check lldp neighbors intent arguments - vyos_interface: - name: eth0 - neighbors: - - port: eth0 - host: netdev - -- name: Config + intent - vyos_interface: - name: eth1 - enabled: False - state: down -""" - -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 interfaces ethernet eth0 description "test-interface" - - set interfaces ethernet eth0 speed 100 - - set interfaces ethernet eth0 mtu 256 - - set interfaces ethernet eth0 duplex full -""" -import re - -from copy import deepcopy -from time import sleep - -from ansible.module_utils._text import to_text -from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils.connection import exec_command -from ansible.module_utils.network.common.utils import ( - conditional, - remove_default_spec, -) -from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.vyos import ( - load_config, - get_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): - commands = list() - want, have = updates - - params = ("speed", "description", "duplex", "mtu") - for w in want: - name = w["name"] - disable = w["disable"] - state = w["state"] - - obj_in_have = search_obj_in_list(name, have) - set_interface = "set interfaces ethernet " + name - delete_interface = "delete interfaces ethernet " + name - - if state == "absent" and obj_in_have: - commands.append(delete_interface) - elif state in ("present", "up", "down"): - if obj_in_have: - for item in params: - value = w.get(item) - - if value and value != obj_in_have.get(item): - if item == "description": - value = "'" + str(value) + "'" - commands.append( - set_interface + " " + item + " " + str(value) - ) - - if disable and not obj_in_have.get("disable", False): - commands.append(set_interface + " disable") - elif not disable and obj_in_have.get("disable", False): - commands.append(delete_interface + " disable") - else: - commands.append(set_interface) - for item in params: - value = w.get(item) - if value: - if item == "description": - value = "'" + str(value) + "'" - commands.append( - set_interface + " " + item + " " + str(value) - ) - - if disable: - commands.append(set_interface + " disable") - return commands - - -def map_config_to_obj(module): - data = get_config(module, flags=["| grep interface"]) - obj = [] - for line in data.split("\n"): - if line.startswith("set interfaces ethernet"): - match = re.search(r"set interfaces ethernet (\S+)", line, re.M) - name = match.group(1) - if name: - interface = {} - for item in obj: - if item["name"] == name: - interface = item - break - - if not interface: - interface = {"name": name} - obj.append(interface) - - match = re.search(r"%s (\S+)" % name, line, re.M) - if match: - param = match.group(1) - if param == "description": - match = re.search(r"description (.+)", line, re.M) - description = match.group(1).strip("'") - interface["description"] = description - elif param == "speed": - match = re.search(r"speed (\S+)", line, re.M) - speed = match.group(1).strip("'") - interface["speed"] = speed - elif param == "mtu": - match = re.search(r"mtu (\S+)", line, re.M) - mtu = match.group(1).strip("'") - interface["mtu"] = int(mtu) - elif param == "duplex": - match = re.search(r"duplex (\S+)", line, re.M) - duplex = match.group(1).strip("'") - interface["duplex"] = duplex - elif param.strip("'") == "disable": - interface["disable"] = True - - 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] - - d = item.copy() - if d["enabled"]: - d["disable"] = False - else: - d["disable"] = True - - obj.append(d) - else: - params = { - "name": module.params["name"], - "description": module.params["description"], - "speed": module.params["speed"], - "mtu": module.params["mtu"], - "duplex": module.params["duplex"], - "delay": module.params["delay"], - "state": module.params["state"], - "neighbors": module.params["neighbors"], - } - - if module.params["enabled"]: - params.update({"disable": False}) - else: - params.update({"disable": True}) - - obj.append(params) - return obj - - -def check_declarative_intent_params(module, want, result): - failed_conditions = [] - have_neighbors = None - for w in want: - want_state = w.get("state") - want_neighbors = w.get("neighbors") - - if want_state not in ("up", "down") and not want_neighbors: - continue - - if result["changed"]: - sleep(w["delay"]) - - command = "show interfaces ethernet %s" % w["name"] - rc, out, err = exec_command(module, command) - if rc != 0: - module.fail_json( - msg=to_text(err, errors="surrogate_then_replace"), - command=command, - rc=rc, - ) - - if want_state in ("up", "down"): - match = re.search(r"%s (\w+)" % "state", out, re.M) - have_state = None - if match: - have_state = match.group(1) - if have_state is None or not conditional( - want_state, have_state.strip().lower() - ): - failed_conditions.append("state " + "eq(%s)" % want_state) - - if want_neighbors: - have_host = [] - have_port = [] - if have_neighbors is None: - rc, have_neighbors, err = exec_command( - module, "show lldp neighbors detail" - ) - if rc != 0: - module.fail_json( - msg=to_text(err, errors="surrogate_then_replace"), - command=command, - rc=rc, - ) - - if have_neighbors: - lines = have_neighbors.strip().split("Interface: ") - for line in lines: - field = line.split("\n") - if field[0].split(",")[0].strip() == w["name"]: - for item in field: - if item.strip().startswith("SysName:"): - have_host.append(item.split(":")[1].strip()) - if item.strip().startswith("PortDescr:"): - have_port.append(item.split(":")[1].strip()) - for item in want_neighbors: - host = item.get("host") - port = item.get("port") - if host and host not in have_host: - failed_conditions.append("host " + host) - if port and port not in have_port: - failed_conditions.append("port " + port) - - return failed_conditions - - -def main(): - """ main entry point for module execution - """ - neighbors_spec = dict(host=dict(), port=dict()) - - element_spec = dict( - name=dict(), - description=dict(), - speed=dict(), - mtu=dict(type="int"), - duplex=dict(choices=["full", "half", "auto"]), - enabled=dict(default=True, type="bool"), - neighbors=dict(type="list", elements="dict", options=neighbors_spec), - delay=dict(default=10, type="int"), - state=dict( - default="present", choices=["present", "absent", "up", "down"] - ), - ) - - 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"]] - - required_together = [["speed", "duplex"]] - module = AnsibleModule( - argument_spec=argument_spec, - required_one_of=required_one_of, - mutually_exclusive=mutually_exclusive, - required_together=required_together, - 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)) - result["commands"] = commands - - if commands: - commit = not module.check_mode - diff = load_config(module, commands, commit=commit) - if diff: - if module._diff: - result["diff"] = {"prepared": diff} - result["changed"] = True - - failed_conditions = check_declarative_intent_params(module, want, result) - - if failed_conditions: - msg = "One or more conditional statements have not been satisfied" - module.fail_json(msg=msg, failed_conditions=failed_conditions) - module.exit_json(**result) - - -if __name__ == "__main__": - main() diff --git a/plugins/modules/_vyos_l3_interface.py b/plugins/modules/_vyos_l3_interface.py deleted file mode 100644 index 054d810..0000000 --- a/plugins/modules/_vyos_l3_interface.py +++ /dev/null @@ -1,328 +0,0 @@ -#!/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_l3_interface -version_added: "2.4" -author: "Ricardo Carrillo Cruz (@rcarrillocruz)" -short_description: Manage L3 interfaces on VyOS network devices -description: - - This module provides declarative management of L3 interfaces - on VyOS network devices. -deprecated: - removed_in: '2.13' - alternative: vyos_l3_interfaces - why: Updated modules released with more functionality. -notes: - - Tested against VYOS 1.1.7 -options: - name: - description: - - Name of the L3 interface. - ipv4: - description: - - IPv4 of the L3 interface. - ipv6: - description: - - IPv6 of the L3 interface. - aggregate: - description: List of L3 interfaces definitions - state: - description: - - State of the L3 interface configuration. - default: present - choices: ['present', 'absent'] -extends_documentation_fragment: vyos -""" - -EXAMPLES = """ -- name: Set eth0 IPv4 address - vyos_l3_interface: - name: eth0 - ipv4: 192.168.0.1/24 - -- name: Remove eth0 IPv4 address - vyos_l3_interface: - name: eth0 - state: absent - -- name: Set IP addresses on aggregate - vyos_l3_interface: - aggregate: - - { name: eth1, ipv4: 192.168.2.10/24 } - - { name: eth2, ipv4: 192.168.3.10/24, ipv6: "fd5d:12c9:2201:1::1/64" } - -- name: Remove IP addresses on aggregate - vyos_l3_interface: - aggregate: - - { name: eth1, ipv4: 192.168.2.10/24 } - - { name: eth2, ipv4: 192.168.3.10/24, ipv6: "fd5d:12c9:2201:1::1/64" } - 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 interfaces ethernet eth0 address '192.168.0.1/24' -""" - -import socket -import re - -from copy import deepcopy - -from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils.network.common.utils import ( - is_masklen, - validate_ip_address, -) -from ansible.module_utils.network.common.utils import remove_default_spec -from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.vyos import ( - load_config, - run_commands, -) -from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.vyos import ( - vyos_argument_spec, -) - - -def is_ipv4(value): - if value: - address = value.split("/") - if is_masklen(address[1]) and validate_ip_address(address[0]): - return True - return False - - -def is_ipv6(value): - if value: - address = value.split("/") - if 0 <= int(address[1]) <= 128: - try: - socket.inet_pton(socket.AF_INET6, address[0]) - except socket.error: - return False - return True - return False - - -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"] - ipv4 = w["ipv4"] - ipv6 = w["ipv6"] - state = w["state"] - - obj_in_have = search_obj_in_list(name, have) - - if state == "absent" and obj_in_have: - if ( - not ipv4 - and not ipv6 - and (obj_in_have["ipv4"] or obj_in_have["ipv6"]) - ): - if name == "lo": - commands.append("delete interfaces loopback lo address") - else: - commands.append( - "delete interfaces ethernet " + name + " address" - ) - else: - if ipv4 and ipv4 in obj_in_have["ipv4"]: - if name == "lo": - commands.append( - "delete interfaces loopback lo address " + ipv4 - ) - else: - commands.append( - "delete interfaces ethernet " - + name - + " address " - + ipv4 - ) - if ipv6 and ipv6 in obj_in_have["ipv6"]: - if name == "lo": - commands.append( - "delete interfaces loopback lo address " + ipv6 - ) - else: - commands.append( - "delete interfaces ethernet " - + name - + " address " - + ipv6 - ) - elif state == "present" and obj_in_have: - if ipv4 and ipv4 not in obj_in_have["ipv4"]: - if name == "lo": - commands.append( - "set interfaces loopback lo address " + ipv4 - ) - else: - commands.append( - "set interfaces ethernet " + name + " address " + ipv4 - ) - - if ipv6 and ipv6 not in obj_in_have["ipv6"]: - if name == "lo": - commands.append( - "set interfaces loopback lo address " + ipv6 - ) - else: - commands.append( - "set interfaces ethernet " + name + " address " + ipv6 - ) - - return commands - - -def map_config_to_obj(module): - obj = [] - output = run_commands(module, ["show interfaces"]) - lines = re.split(r"\n[e|l]", output[0])[1:] - - if len(lines) > 0: - for line in lines: - splitted_line = line.split() - - if len(splitted_line) > 0: - ipv4 = [] - ipv6 = [] - - if splitted_line[0].lower().startswith("th"): - name = "e" + splitted_line[0].lower() - elif splitted_line[0].lower().startswith("o"): - name = "l" + splitted_line[0].lower() - - for i in splitted_line[1:]: - if ("." in i or ":" in i) and "/" in i: - value = i.split(r"\n")[0] - if is_ipv4(value): - ipv4.append(value) - elif is_ipv6(value): - ipv6.append(value) - - obj.append({"name": name, "ipv4": ipv4, "ipv6": ipv6}) - - 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"], - "ipv4": module.params["ipv4"], - "ipv6": module.params["ipv6"], - "state": module.params["state"], - } - ) - - return obj - - -def main(): - """ main entry point for module execution - """ - element_spec = dict( - name=dict(), - ipv4=dict(), - ipv6=dict(), - state=dict(default="present", choices=["present", "absent"]), - ) - - 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_linkagg.py b/plugins/modules/_vyos_linkagg.py deleted file mode 100644 index 95fbae9..0000000 --- a/plugins/modules/_vyos_linkagg.py +++ /dev/null @@ -1,317 +0,0 @@ -#!/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_linkagg -version_added: "2.4" -author: "Ricardo Carrillo Cruz (@rcarrillocruz)" -short_description: Manage link aggregation groups on VyOS network devices -description: - - This module provides declarative management of link aggregation groups - on VyOS network devices. -deprecated: - removed_in: '2.13' - alternative: vyos_lag_interfaces - why: Updated modules released with more functionality. -notes: - - Tested against VYOS 1.1.7 -options: - name: - description: - - Name of the link aggregation group. - required: true - type: str - mode: - description: - - Mode of the link aggregation group. - choices: ['802.3ad', 'active-backup', 'broadcast', - 'round-robin', 'transmit-load-balance', - 'adaptive-load-balance', 'xor-hash', 'on'] - type: str - members: - description: - - List of members of the link aggregation group. - type: list - aggregate: - description: List of link aggregation definitions. - type: list - state: - description: - - State of the link aggregation group. - default: present - choices: ['present', 'absent', 'up', 'down'] - type: str -extends_documentation_fragment: vyos -""" - -EXAMPLES = """ -- name: configure link aggregation group - vyos_linkagg: - name: bond0 - members: - - eth0 - - eth1 - -- name: remove configuration - vyos_linkagg: - name: bond0 - state: absent - -- name: Create aggregate of linkagg definitions - vyos_linkagg: - aggregate: - - { name: bond0, members: [eth1] } - - { name: bond1, members: [eth2] } - -- name: Remove aggregate of linkagg definitions - vyos_linkagg: - aggregate: - - name: bond0 - - name: bond1 - 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 interfaces bonding bond0 - - set interfaces ethernet eth0 bond-group 'bond0' - - set interfaces ethernet eth1 bond-group 'bond0' -""" -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 ( - load_config, - run_commands, -) -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"] - members = w.get("members") or [] - mode = w["mode"] - - if mode == "on": - mode = "802.3ad" - - state = w["state"] - - obj_in_have = search_obj_in_list(name, have) - - if state == "absent": - if obj_in_have: - for m in obj_in_have["members"]: - commands.append( - "delete interfaces ethernet " + m + " bond-group" - ) - - commands.append("delete interfaces bonding " + name) - else: - if not obj_in_have: - commands.append( - "set interfaces bonding " + name + " mode " + mode - ) - - for m in members: - commands.append( - "set interfaces ethernet " + m + " bond-group " + name - ) - - if state == "down": - commands.append( - "set interfaces bonding " + name + " disable" - ) - else: - if mode != obj_in_have["mode"]: - commands.append( - "set interfaces bonding " + name + " mode " + mode - ) - - missing_members = list( - set(members) - set(obj_in_have["members"]) - ) - for m in missing_members: - commands.append( - "set interfaces ethernet " + m + " bond-group " + name - ) - - if state == "down" and obj_in_have["state"] == "up": - commands.append( - "set interfaces bonding " + name + " disable" - ) - elif state == "up" and obj_in_have["state"] == "down": - commands.append( - "delete interfaces bonding " + name + " disable" - ) - - return commands - - -def map_config_to_obj(module): - obj = [] - output = run_commands(module, ["show interfaces bonding slaves"]) - lines = output[0].splitlines() - - if len(lines) > 1: - for line in lines[1:]: - splitted_line = line.split() - - name = splitted_line[0] - mode = splitted_line[1] - state = splitted_line[2] - - if len(splitted_line) > 4: - members = splitted_line[4:] - else: - members = [] - - obj.append( - { - "name": name, - "mode": mode, - "members": members, - "state": state, - } - ) - - 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"], - "mode": module.params["mode"], - "members": module.params["members"], - "state": module.params["state"], - } - ) - - return obj - - -def main(): - """ main entry point for module execution - """ - element_spec = dict( - name=dict(), - mode=dict( - choices=[ - "802.3ad", - "active-backup", - "broadcast", - "round-robin", - "transmit-load-balance", - "adaptive-load-balance", - "xor-hash", - "on", - ], - default="802.3ad", - ), - members=dict(type="list"), - state=dict( - default="present", choices=["present", "absent", "up", "down"] - ), - ) - - 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_lldp.py b/plugins/modules/_vyos_lldp.py deleted file mode 100644 index 6978754..0000000 --- a/plugins/modules/_vyos_lldp.py +++ /dev/null @@ -1,144 +0,0 @@ -#!/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/>. -# - -from __future__ import absolute_import, division, print_function - -__metaclass__ = type - - -ANSIBLE_METADATA = { - "metadata_version": "1.1", - "status": ["deprecated"], - "supported_by": "network", -} - - -DOCUMENTATION = """ ---- -module: vyos_lldp -version_added: "2.4" -author: "Ricardo Carrillo Cruz (@rcarrillocruz)" -short_description: Manage LLDP configuration on VyOS network devices -description: - - This module provides declarative management of LLDP service - on VyOS network devices. -deprecated: - removed_in: '2.13' - alternative: vyos_lldp_global - why: Updated modules released with more functionality. -notes: - - Tested against VYOS 1.1.7 -options: - interfaces: - description: - - Name of the interfaces. - type: list - state: - description: - - State of the link aggregation group. - default: present - choices: ['present', 'absent', 'enabled', 'disabled'] - type: str -extends_documentation_fragment: vyos -""" - -EXAMPLES = """ -- name: Enable LLDP service - vyos_lldp: - state: present - -- name: Disable LLDP service - vyos_lldp: - 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 -""" -from ansible.module_utils.basic import AnsibleModule -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 has_lldp(module): - config = get_config(module).splitlines() - - if "set service 'lldp'" in config or "set service lldp" in config: - return True - else: - return False - - -def main(): - """ main entry point for module execution - """ - argument_spec = dict( - interfaces=dict(type="list"), - state=dict( - default="present", - choices=["present", "absent", "enabled", "disabled"], - ), - ) - - argument_spec.update(vyos_argument_spec) - - module = AnsibleModule( - argument_spec=argument_spec, supports_check_mode=True - ) - - warnings = list() - - result = {"changed": False} - - if warnings: - result["warnings"] = warnings - - HAS_LLDP = has_lldp(module) - - commands = [] - - if module.params["state"] == "absent" and HAS_LLDP: - commands.append("delete service lldp") - elif module.params["state"] == "present" and not HAS_LLDP: - commands.append("set service lldp") - - 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_lldp_interface.py b/plugins/modules/_vyos_lldp_interface.py deleted file mode 100644 index 6705d57..0000000 --- a/plugins/modules/_vyos_lldp_interface.py +++ /dev/null @@ -1,260 +0,0 @@ -#!/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 81a985d..b08fb73 100644 --- a/plugins/modules/vyos_banner.py +++ b/plugins/modules/vyos_banner.py @@ -25,38 +25,37 @@ ANSIBLE_METADATA = { "supported_by": "network", } -DOCUMENTATION = """ ---- -module: vyos_banner -version_added: "2.4" -author: "Trishna Guha (@trishnaguha)" +DOCUMENTATION = """module: vyos_banner +author: Trishna Guha (@trishnaguha) short_description: Manage multiline banners on VyOS devices description: - - This will configure both pre-login and post-login banners on remote - devices running VyOS. It allows playbooks to add or remote - banner text from the active running configuration. +- This will configure both pre-login and post-login banners on remote devices running + VyOS. It allows playbooks to add or remote banner text from the active running configuration. 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). +- 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: - - Specifies which banner that should be - configured on the remote device. + - Specifies which banner that should be configured on the remote device. required: true - choices: ['pre-login', 'post-login'] + choices: + - pre-login + - post-login text: description: - - The banner text that should be - present in the remote device running configuration. This argument - accepts a multiline string, with no empty lines. Requires I(state=present). + - The banner text that should be present in the remote device running configuration. + This argument accepts a multiline string, with no empty lines. Requires I(state=present). state: description: - - Specifies whether or not the configuration is present in the current - devices active running configuration. + - Specifies whether or not the configuration is present in the current devices + active running configuration. default: present - choices: ['present', 'absent'] -extends_documentation_fragment: vyos + choices: + - present + - absent +extends_documentation_fragment: +- vyos.vyos.vyos """ EXAMPLES = """ diff --git a/plugins/modules/vyos_command.py b/plugins/modules/vyos_command.py index 6da7352..1853849 100644 --- a/plugins/modules/vyos_command.py +++ b/plugins/modules/vyos_command.py @@ -23,72 +23,64 @@ ANSIBLE_METADATA = { } -DOCUMENTATION = """ ---- -module: vyos_command -version_added: "2.2" -author: "Nathaniel Case (@Qalthos)" +DOCUMENTATION = """module: vyos_command +author: Nathaniel Case (@Qalthos) short_description: Run one or more commands on VyOS devices description: - - The command module allows running one or more commands on remote - devices running VyOS. This module can also be introspected - to validate key parameters before returning successfully. If the - conditional statements are not met in the wait period, the task - fails. - - Certain C(show) commands in VyOS produce many lines of output and - use a custom pager that can cause this module to hang. If the - value of the environment variable C(ANSIBLE_VYOS_TERMINAL_LENGTH) - is not set, the default number of 10000 is used. -extends_documentation_fragment: vyos +- The command module allows running one or more commands on remote devices running + VyOS. This module can also be introspected to validate key parameters before returning + successfully. If the conditional statements are not met in the wait period, the + task fails. +- Certain C(show) commands in VyOS produce many lines of output and use a custom pager + that can cause this module to hang. If the value of the environment variable C(ANSIBLE_VYOS_TERMINAL_LENGTH) + is not set, the default number of 10000 is used. +extends_documentation_fragment: +- vyos.vyos.vyos options: commands: description: - - The ordered set of commands to execute on the remote device - running VyOS. The output from the command execution is - returned to the playbook. If the I(wait_for) argument is - provided, the module is not returned until the condition is - satisfied or the number of retries has been exceeded. + - The ordered set of commands to execute on the remote device running VyOS. The + output from the command execution is returned to the playbook. If the I(wait_for) + argument is provided, the module is not returned until the condition is satisfied + or the number of retries has been exceeded. required: true wait_for: description: - - Specifies what to evaluate from the output of the command - and what conditionals to apply. This argument will cause - the task to wait for a particular conditional to be true - before moving forward. If the conditional is not true - by the configured I(retries), the task fails. See examples. - aliases: ['waitfor'] + - Specifies what to evaluate from the output of the command and what conditionals + to apply. This argument will cause the task to wait for a particular conditional + to be true before moving forward. If the conditional is not true by the configured + I(retries), the task fails. See examples. + aliases: + - waitfor match: description: - - The I(match) argument is used in conjunction with the - I(wait_for) argument to specify the match policy. Valid - values are C(all) or C(any). If the value is set to C(all) - then all conditionals in the wait_for must be satisfied. If - the value is set to C(any) then only one of the values must be - satisfied. + - The I(match) argument is used in conjunction with the I(wait_for) argument to + specify the match policy. Valid values are C(all) or C(any). If the value is + set to C(all) then all conditionals in the wait_for must be satisfied. If the + value is set to C(any) then only one of the values must be satisfied. default: all - choices: ['any', 'all'] + choices: + - any + - all retries: description: - - Specifies the number of retries a command should be tried - before it is considered failed. The command is run on the - target device every retry and evaluated against the I(wait_for) - conditionals. + - Specifies the number of retries a command should be tried before it is considered + failed. The command is run on the target device every retry and evaluated against + the I(wait_for) conditionals. default: 10 interval: description: - - Configures the interval in seconds to wait between I(retries) - of the command. If the command does not pass the specified - conditions, the interval indicates how long to wait before - trying the command again. + - Configures the interval in seconds to wait between I(retries) of the command. + If the command does not pass the specified conditions, the interval indicates + how long to wait before trying the command again. default: 1 - notes: - - 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). +- 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 = """ @@ -143,8 +135,10 @@ import time from ansible.module_utils._text import to_text from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils.network.common.parsing import Conditional -from ansible.module_utils.network.common.utils import ( +from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.parsing import ( + Conditional, +) +from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.utils import ( transform_commands, to_lines, ) @@ -219,7 +213,7 @@ def main(): module.fail_json(msg=msg, failed_conditions=failed_conditions) result.update( - {"stdout": responses, "stdout_lines": list(to_lines(responses))} + {"stdout": responses, "stdout_lines": list(to_lines(responses)),} ) module.exit_json(**result) diff --git a/plugins/modules/vyos_config.py b/plugins/modules/vyos_config.py index 7c9f3ab..24fa161 100644 --- a/plugins/modules/vyos_config.py +++ b/plugins/modules/vyos_config.py @@ -23,96 +23,89 @@ ANSIBLE_METADATA = { } -DOCUMENTATION = """ ---- -module: vyos_config -version_added: "2.2" -author: "Nathaniel Case (@Qalthos)" +DOCUMENTATION = """module: vyos_config +author: Nathaniel Case (@Qalthos) short_description: Manage VyOS configuration on remote device description: - - This module provides configuration file management of VyOS - devices. It provides arguments for managing both the - configuration file and state of the active configuration. All - configuration statements are based on `set` and `delete` commands - in the device configuration. -extends_documentation_fragment: vyos +- This module provides configuration file management of VyOS devices. It provides + arguments for managing both the configuration file and state of the active configuration. + All configuration statements are based on `set` and `delete` commands in the device + configuration. +extends_documentation_fragment: +- vyos.vyos.vyos 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). +- 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: - - The ordered set of configuration lines to be managed and - compared with the existing configuration on the remote - device. + - The ordered set of configuration lines to be managed and compared with the existing + configuration on the remote device. src: description: - - The C(src) argument specifies the path to the source config - file to load. The source config file can either be in - bracket format or set format. The source file can include - Jinja2 template variables. + - The C(src) argument specifies the path to the source config file to load. The + source config file can either be in bracket format or set format. The source + file can include Jinja2 template variables. match: description: - - The C(match) argument controls the method used to match - against the current active configuration. By default, the - desired config is matched against the active config and the - deltas are loaded. If the C(match) argument is set to C(none) - the active configuration is ignored and the configuration is - always loaded. + - The C(match) argument controls the method used to match against the current + active configuration. By default, the desired config is matched against the + active config and the deltas are loaded. If the C(match) argument is set to + C(none) the active configuration is ignored and the configuration is always + loaded. default: line - choices: ['line', 'none'] + choices: + - line + - none backup: description: - - The C(backup) argument will backup the current devices active - configuration to the Ansible control host prior to making any - changes. If the C(backup_options) value is not given, the - backup file will be located in the backup folder in the playbook - root directory or role root directory, if playbook is part of an - ansible role. If the directory does not exist, it is created. + - The C(backup) argument will backup the current devices active configuration + to the Ansible control host prior to making any changes. If the C(backup_options) + value is not given, the backup file will be located in the backup folder in + the playbook root directory or role root directory, if playbook is part of an + ansible role. If the directory does not exist, it is created. type: bool default: 'no' comment: description: - - Allows a commit description to be specified to be included - when the configuration is committed. If the configuration is - not changed or committed, this argument is ignored. - default: 'configured by vyos_config' + - Allows a commit description to be specified to be included when the configuration + is committed. If the configuration is not changed or committed, this argument + is ignored. + default: configured by vyos_config config: description: - - The C(config) argument specifies the base configuration to use - to compare against the desired configuration. If this value - is not specified, the module will automatically retrieve the - current active configuration from the remote device. + - The C(config) argument specifies the base configuration to use to compare against + the desired configuration. If this value is not specified, the module will + automatically retrieve the current active configuration from the remote device. save: description: - - The C(save) argument controls whether or not changes made - to the active configuration are saved to disk. This is - independent of committing the config. When set to True, the - active configuration is saved. + - The C(save) argument controls whether or not changes made to the active configuration + are saved to disk. This is independent of committing the config. When set + to True, the active configuration is saved. type: bool default: 'no' backup_options: description: - - This is a dict object containing configurable options related to backup file path. - The value of this option is read only when C(backup) is set to I(yes), if C(backup) is set - to I(no) this option will be silently ignored. + - This is a dict object containing configurable options related to backup file + path. The value of this option is read only when C(backup) is set to I(yes), + if C(backup) is set to I(no) this option will be silently ignored. suboptions: filename: description: - - The filename to be used to store the backup configuration. If the the filename - is not given it will be generated based on the hostname, current time and date - in format defined by <hostname>_config.<current-date>@<current-time> + - The filename to be used to store the backup configuration. If the the filename + is not given it will be generated based on the hostname, current time and + date in format defined by <hostname>_config.<current-date>@<current-time> dir_path: description: - - This option provides the path ending with directory name in which the backup - configuration file will be stored. If the directory does not exist it will be first - created and the filename is either the value of C(filename) or default filename - as described in C(filename) options description. If the path value is not given - in that case a I(backup) directory will be created in the current working directory - and backup configuration will be copied in C(filename) within I(backup) directory. + - This option provides the path ending with directory name in which the backup + configuration file will be stored. If the directory does not exist it will + be first created and the filename is either the value of C(filename) or + default filename as described in C(filename) options description. If the + path value is not given in that case a I(backup) directory will be created + in the current working directory and backup configuration will be copied + in C(filename) within I(backup) directory. type: path type: dict - version_added: "2.8" """ EXAMPLES = """ @@ -217,7 +210,17 @@ def get_candidate(module): def format_commands(commands): - return [line for line in commands if len(line.strip()) > 0] + """ + This function format the input commands and removes the prepend white spaces + for command lines having 'set' or 'delete' and it skips empty lines. + :param commands: + :return: list of commands + """ + return [ + line.strip() if line.split()[0] in ("set", "delete") else line + for line in commands + if len(line.strip()) > 0 + ] def diff_config(commands, config): diff --git a/plugins/modules/vyos_facts.py b/plugins/modules/vyos_facts.py index 125b256..9eaa278 100644 --- a/plugins/modules/vyos_facts.py +++ b/plugins/modules/vyos_facts.py @@ -15,48 +15,40 @@ ANSIBLE_METADATA = { } -DOCUMENTATION = """ ---- -module: vyos_facts -version_added: 2.2 +DOCUMENTATION = """module: vyos_facts short_description: Get facts about vyos devices. description: - - Collects facts from network devices running the vyos operating - system. This module places the facts gathered in the fact tree keyed by the - respective resource name. The facts module will always collect a - base set of facts from the device and can enable or disable - collection of additional facts. +- Collects facts from network devices running the vyos operating system. This module + places the facts gathered in the fact tree keyed by the respective resource name. The + facts module will always collect a base set of facts from the device and can enable + or disable collection of additional facts. author: - - Nathaniel Case (@qalthos) - - Nilashish Chakraborty (@Nilashishc) - - Rohit Thakur (@rohitthakur2590) -extends_documentation_fragment: vyos +- Nathaniel Case (@qalthos) +- Nilashish Chakraborty (@Nilashishc) +- Rohit Thakur (@rohitthakur2590) +extends_documentation_fragment: +- vyos.vyos.vyos 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). +- 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: - - When supplied, this argument will restrict the facts collected - to a given subset. Possible values for this argument include - all, default, config, and neighbors. Can specify a list of - values to include a larger subset. Values can also be used - with an initial C(M(!)) to specify that a specific subset should - not be collected. + - When supplied, this argument will restrict the facts collected to a given subset. Possible + values for this argument include all, default, config, and neighbors. Can specify + a list of values to include a larger subset. Values can also be used with an + initial C(M(!)) to specify that a specific subset should not be collected. required: false - default: "!config" + default: '!config' gather_network_resources: description: - - When supplied, this argument will restrict the facts collected - to a given subset. Possible values for this argument include - all and the resources like interfaces. - Can specify a list of values to include a larger subset. Values - can also be used with an initial C(M(!)) to specify that a - specific subset should not be collected. - Valid subsets are 'all', 'interfaces', 'l3_interfaces', 'lag_interfaces', - 'lldp_global', 'lldp_interfaces'. + - When supplied, this argument will restrict the facts collected to a given subset. + Possible values for this argument include all and the resources like interfaces. + Can specify a list of values to include a larger subset. Values can also be + used with an initial C(M(!)) to specify that a specific subset should not be + collected. Valid subsets are 'all', 'interfaces', 'l3_interfaces', 'lag_interfaces', + 'lldp_global', 'lldp_interfaces'. required: false - version_added: "2.9" """ EXAMPLES = """ @@ -158,17 +150,17 @@ def main(): :returns: ansible_facts """ argument_spec = FactsArgs.argument_spec - argument_spec.update(vyos_argument_spec) module = AnsibleModule( argument_spec=argument_spec, supports_check_mode=True ) - warnings = [ - "default value for `gather_subset` " - "will be changed to `min` from `!config` v2.11 onwards" - ] + warnings = [] + if module.params["gather_subset"] == "!config": + warnings.append( + "default value for `gather_subset` will be changed to `min` from `!config` v2.11 onwards" + ) result = Facts(module).get_facts() diff --git a/plugins/modules/vyos_interface.py b/plugins/modules/vyos_interface.py index 3459fa1..175cf3b 120000..100644 --- a/plugins/modules/vyos_interface.py +++ b/plugins/modules/vyos_interface.py @@ -1 +1,471 @@ -_vyos_interface.py
\ No newline at end of file +#!/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_interface +author: Ganesh Nalawade (@ganeshrn) +short_description: Manage Interface on VyOS network devices +description: +- This module provides declarative management of Interfaces on VyOS network devices. +deprecated: + removed_in: '2.13' + alternative: vyos_interfaces + why: Updated modules released with more functionality. +notes: +- Tested against VYOS 1.1.7 +options: + name: + description: + - Name of the Interface. + required: true + description: + description: + - Description of Interface. + enabled: + description: + - Interface link status. + type: bool + speed: + description: + - Interface link speed. + mtu: + description: + - Maximum size of transmit packet. + duplex: + description: + - Interface link status. + default: auto + choices: + - full + - half + - auto + delay: + description: + - Time in seconds to wait before checking for the operational state on remote + device. This wait is applicable for operational state argument which are I(state) + with values C(up)/C(down) and I(neighbors). + default: 10 + neighbors: + description: + - Check the operational state of given interface C(name) for LLDP neighbor. + - The following suboptions are available. + suboptions: + host: + description: + - LLDP neighbor host for given interface C(name). + port: + description: + - LLDP neighbor port to which given interface C(name) is connected. + aggregate: + description: List of Interfaces definitions. + state: + description: + - State of the Interface configuration, C(up) means present and operationally + up and C(down) means present and operationally C(down) + default: present + choices: + - present + - absent + - up + - down +extends_documentation_fragment: +- vyos.vyos.vyos +""" + +EXAMPLES = """ +- name: configure interface + vyos_interface: + name: eth0 + description: test-interface + +- name: remove interface + vyos_interface: + name: eth0 + state: absent + +- name: make interface down + vyos_interface: + name: eth0 + enabled: False + +- name: make interface up + vyos_interface: + name: eth0 + enabled: True + +- name: Configure interface speed, mtu, duplex + vyos_interface: + name: eth5 + state: present + speed: 100 + mtu: 256 + duplex: full + +- name: Set interface using aggregate + vyos_interface: + aggregate: + - { name: eth1, description: test-interface-1, speed: 100, duplex: half, mtu: 512} + - { name: eth2, description: test-interface-2, speed: 1000, duplex: full, mtu: 256} + +- name: Disable interface on aggregate + net_interface: + aggregate: + - name: eth1 + - name: eth2 + enabled: False + +- name: Delete interface using aggregate + net_interface: + aggregate: + - name: eth1 + - name: eth2 + state: absent + +- name: Check lldp neighbors intent arguments + vyos_interface: + name: eth0 + neighbors: + - port: eth0 + host: netdev + +- name: Config + intent + vyos_interface: + name: eth1 + enabled: False + state: down +""" + +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 interfaces ethernet eth0 description "test-interface" + - set interfaces ethernet eth0 speed 100 + - set interfaces ethernet eth0 mtu 256 + - set interfaces ethernet eth0 duplex full +""" +import re + +from copy import deepcopy +from time import sleep + +from ansible.module_utils._text import to_text +from ansible.module_utils.basic import AnsibleModule +from ansible.module_utils.connection import exec_command +from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.utils import ( + conditional, + remove_default_spec, +) +from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.vyos import ( + load_config, + get_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): + commands = list() + want, have = updates + + params = ("speed", "description", "duplex", "mtu") + for w in want: + name = w["name"] + disable = w["disable"] + state = w["state"] + + obj_in_have = search_obj_in_list(name, have) + set_interface = "set interfaces ethernet " + name + delete_interface = "delete interfaces ethernet " + name + + if state == "absent" and obj_in_have: + commands.append(delete_interface) + elif state in ("present", "up", "down"): + if obj_in_have: + for item in params: + value = w.get(item) + + if value and value != obj_in_have.get(item): + if item == "description": + value = "'" + str(value) + "'" + commands.append( + set_interface + " " + item + " " + str(value) + ) + + if disable and not obj_in_have.get("disable", False): + commands.append(set_interface + " disable") + elif not disable and obj_in_have.get("disable", False): + commands.append(delete_interface + " disable") + else: + commands.append(set_interface) + for item in params: + value = w.get(item) + if value: + if item == "description": + value = "'" + str(value) + "'" + commands.append( + set_interface + " " + item + " " + str(value) + ) + + if disable: + commands.append(set_interface + " disable") + return commands + + +def map_config_to_obj(module): + data = get_config(module, flags=["| grep interface"]) + obj = [] + for line in data.split("\n"): + if line.startswith("set interfaces ethernet"): + match = re.search(r"set interfaces ethernet (\S+)", line, re.M) + name = match.group(1) + if name: + interface = {} + for item in obj: + if item["name"] == name: + interface = item + break + + if not interface: + interface = {"name": name} + obj.append(interface) + + match = re.search(r"%s (\S+)" % name, line, re.M) + if match: + param = match.group(1) + if param == "description": + match = re.search(r"description (.+)", line, re.M) + description = match.group(1).strip("'") + interface["description"] = description + elif param == "speed": + match = re.search(r"speed (\S+)", line, re.M) + speed = match.group(1).strip("'") + interface["speed"] = speed + elif param == "mtu": + match = re.search(r"mtu (\S+)", line, re.M) + mtu = match.group(1).strip("'") + interface["mtu"] = int(mtu) + elif param == "duplex": + match = re.search(r"duplex (\S+)", line, re.M) + duplex = match.group(1).strip("'") + interface["duplex"] = duplex + elif param.strip("'") == "disable": + interface["disable"] = True + + 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] + + d = item.copy() + if d["enabled"]: + d["disable"] = False + else: + d["disable"] = True + + obj.append(d) + else: + params = { + "name": module.params["name"], + "description": module.params["description"], + "speed": module.params["speed"], + "mtu": module.params["mtu"], + "duplex": module.params["duplex"], + "delay": module.params["delay"], + "state": module.params["state"], + "neighbors": module.params["neighbors"], + } + + if module.params["enabled"]: + params.update({"disable": False}) + else: + params.update({"disable": True}) + + obj.append(params) + return obj + + +def check_declarative_intent_params(module, want, result): + failed_conditions = [] + have_neighbors = None + for w in want: + want_state = w.get("state") + want_neighbors = w.get("neighbors") + + if want_state not in ("up", "down") and not want_neighbors: + continue + + if result["changed"]: + sleep(w["delay"]) + + command = "show interfaces ethernet %s" % w["name"] + rc, out, err = exec_command(module, command) + if rc != 0: + module.fail_json( + msg=to_text(err, errors="surrogate_then_replace"), + command=command, + rc=rc, + ) + + if want_state in ("up", "down"): + match = re.search(r"%s (\w+)" % "state", out, re.M) + have_state = None + if match: + have_state = match.group(1) + if have_state is None or not conditional( + want_state, have_state.strip().lower() + ): + failed_conditions.append("state " + "eq(%s)" % want_state) + + if want_neighbors: + have_host = [] + have_port = [] + if have_neighbors is None: + rc, have_neighbors, err = exec_command( + module, "show lldp neighbors detail" + ) + if rc != 0: + module.fail_json( + msg=to_text(err, errors="surrogate_then_replace"), + command=command, + rc=rc, + ) + + if have_neighbors: + lines = have_neighbors.strip().split("Interface: ") + for line in lines: + field = line.split("\n") + if field[0].split(",")[0].strip() == w["name"]: + for item in field: + if item.strip().startswith("SysName:"): + have_host.append(item.split(":")[1].strip()) + if item.strip().startswith("PortDescr:"): + have_port.append(item.split(":")[1].strip()) + for item in want_neighbors: + host = item.get("host") + port = item.get("port") + if host and host not in have_host: + failed_conditions.append("host " + host) + if port and port not in have_port: + failed_conditions.append("port " + port) + + return failed_conditions + + +def main(): + """ main entry point for module execution + """ + neighbors_spec = dict(host=dict(), port=dict()) + + element_spec = dict( + name=dict(), + description=dict(), + speed=dict(), + mtu=dict(type="int"), + duplex=dict(choices=["full", "half", "auto"]), + enabled=dict(default=True, type="bool"), + neighbors=dict(type="list", elements="dict", options=neighbors_spec), + delay=dict(default=10, type="int"), + state=dict( + default="present", choices=["present", "absent", "up", "down"] + ), + ) + + 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"]] + + required_together = [["speed", "duplex"]] + module = AnsibleModule( + argument_spec=argument_spec, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, + required_together=required_together, + 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)) + result["commands"] = commands + + if commands: + commit = not module.check_mode + diff = load_config(module, commands, commit=commit) + if diff: + if module._diff: + result["diff"] = {"prepared": diff} + result["changed"] = True + + failed_conditions = check_declarative_intent_params(module, want, result) + + if failed_conditions: + msg = "One or more conditional statements have not been satisfied" + module.fail_json(msg=msg, failed_conditions=failed_conditions) + module.exit_json(**result) + + +if __name__ == "__main__": + main() diff --git a/plugins/modules/vyos_interfaces.py b/plugins/modules/vyos_interfaces.py index 096fd1f..93df4e4 100644 --- a/plugins/modules/vyos_interfaces.py +++ b/plugins/modules/vyos_interfaces.py @@ -36,18 +36,15 @@ ANSIBLE_METADATA = { "supported_by": "network", } -DOCUMENTATION = """ ---- -module: vyos_interfaces -version_added: 2.9 +DOCUMENTATION = """module: vyos_interfaces short_description: Manages interface attributes of VyOS network devices. 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. +- 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). +- 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: @@ -58,64 +55,73 @@ options: description: - Full name of the interface, e.g. eth0, eth1, bond0, vti1, vxlan2. type: str - required: True + required: true description: description: - - Interface description. + - Interface description. type: str duplex: description: - - Interface duplex mode. - - Applicable for Ethernet interfaces only. - choices: ['full', 'half', 'auto'] + - Interface duplex mode. + - Applicable for Ethernet interfaces only. + choices: + - full + - half + - auto type: str enabled: - default: True + default: true description: - - Administrative state of the interface. - - Set the value to C(true) to administratively enable - the interface or C(false) to disable it. + - Administrative state of the interface. + - Set the value to C(true) to administratively enable the interface or C(false) + to disable it. type: bool mtu: description: - - MTU for a specific interface. Refer to vendor documentation for valid values. - - Applicable for Ethernet, Bonding, VXLAN and Virtual Tunnel interfaces. + - MTU for a specific interface. Refer to vendor documentation for valid values. + - Applicable for Ethernet, Bonding, VXLAN and Virtual Tunnel interfaces. type: int speed: description: - - Interface link speed. - - Applicable for Ethernet interfaces only. + - Interface link speed. + - Applicable for Ethernet interfaces only. type: str - choices: ['auto', '10', '100', '1000', '2500', '10000'] + choices: + - auto + - '10' + - '100' + - '1000' + - '2500' + - '10000' vifs: description: - - Virtual sub-interfaces related configuration. - - 802.1Q VLAN interfaces are represented as virtual sub-interfaces in VyOS. + - Virtual sub-interfaces related configuration. + - 802.1Q VLAN interfaces are represented as virtual sub-interfaces in VyOS. type: list suboptions: vlan_id: description: - - Identifier for the virtual sub-interface. + - Identifier for the virtual sub-interface. type: int description: description: - - Virtual sub-interface description. + - Virtual sub-interface description. type: str enabled: description: - - Administrative state of the virtual sub-interface. - - Set the value to C(true) to administratively enable - the interface or C(false) to disable it. + - Administrative state of the virtual sub-interface. + - Set the value to C(true) to administratively enable the interface or + C(false) to disable it. type: bool - default: True + default: true mtu: description: - - MTU for the virtual sub-interface. - - Refer to vendor documentation for valid values. + - MTU for the virtual sub-interface. + - Refer to vendor documentation for valid values. type: int state: description: - - The state of the configuration after module completion. + - The state of the configuration after module completion. type: str choices: - merged diff --git a/plugins/modules/vyos_l3_interface.py b/plugins/modules/vyos_l3_interface.py index 961ef4e..faa9629 120000..100644 --- a/plugins/modules/vyos_l3_interface.py +++ b/plugins/modules/vyos_l3_interface.py @@ -1 +1,329 @@ -_vyos_l3_interface.py
\ No newline at end of file +#!/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_l3_interface +author: Ricardo Carrillo Cruz (@rcarrillocruz) +short_description: Manage L3 interfaces on VyOS network devices +description: +- This module provides declarative management of L3 interfaces on VyOS network devices. +deprecated: + removed_in: '2.13' + alternative: vyos_l3_interfaces + why: Updated modules released with more functionality. +notes: +- Tested against VYOS 1.1.7 +options: + name: + description: + - Name of the L3 interface. + ipv4: + description: + - IPv4 of the L3 interface. + ipv6: + description: + - IPv6 of the L3 interface. + aggregate: + description: List of L3 interfaces definitions + state: + description: + - State of the L3 interface configuration. + default: present + choices: + - present + - absent +extends_documentation_fragment: +- vyos.vyos.vyos +""" + +EXAMPLES = """ +- name: Set eth0 IPv4 address + vyos_l3_interface: + name: eth0 + ipv4: 192.168.0.1/24 + +- name: Remove eth0 IPv4 address + vyos_l3_interface: + name: eth0 + state: absent + +- name: Set IP addresses on aggregate + vyos_l3_interface: + aggregate: + - { name: eth1, ipv4: 192.168.2.10/24 } + - { name: eth2, ipv4: 192.168.3.10/24, ipv6: "fd5d:12c9:2201:1::1/64" } + +- name: Remove IP addresses on aggregate + vyos_l3_interface: + aggregate: + - { name: eth1, ipv4: 192.168.2.10/24 } + - { name: eth2, ipv4: 192.168.3.10/24, ipv6: "fd5d:12c9:2201:1::1/64" } + 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 interfaces ethernet eth0 address '192.168.0.1/24' +""" + +import socket +import re + +from copy import deepcopy + +from ansible.module_utils.basic import AnsibleModule +from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.utils import ( + is_masklen, + validate_ip_address, +) +from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.utils import ( + remove_default_spec, +) +from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.vyos import ( + load_config, + run_commands, +) +from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.vyos import ( + vyos_argument_spec, +) + + +def is_ipv4(value): + if value: + address = value.split("/") + if is_masklen(address[1]) and validate_ip_address(address[0]): + return True + return False + + +def is_ipv6(value): + if value: + address = value.split("/") + if 0 <= int(address[1]) <= 128: + try: + socket.inet_pton(socket.AF_INET6, address[0]) + except socket.error: + return False + return True + return False + + +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"] + ipv4 = w["ipv4"] + ipv6 = w["ipv6"] + state = w["state"] + + obj_in_have = search_obj_in_list(name, have) + + if state == "absent" and obj_in_have: + if ( + not ipv4 + and not ipv6 + and (obj_in_have["ipv4"] or obj_in_have["ipv6"]) + ): + if name == "lo": + commands.append("delete interfaces loopback lo address") + else: + commands.append( + "delete interfaces ethernet " + name + " address" + ) + else: + if ipv4 and ipv4 in obj_in_have["ipv4"]: + if name == "lo": + commands.append( + "delete interfaces loopback lo address " + ipv4 + ) + else: + commands.append( + "delete interfaces ethernet " + + name + + " address " + + ipv4 + ) + if ipv6 and ipv6 in obj_in_have["ipv6"]: + if name == "lo": + commands.append( + "delete interfaces loopback lo address " + ipv6 + ) + else: + commands.append( + "delete interfaces ethernet " + + name + + " address " + + ipv6 + ) + elif state == "present" and obj_in_have: + if ipv4 and ipv4 not in obj_in_have["ipv4"]: + if name == "lo": + commands.append( + "set interfaces loopback lo address " + ipv4 + ) + else: + commands.append( + "set interfaces ethernet " + name + " address " + ipv4 + ) + + if ipv6 and ipv6 not in obj_in_have["ipv6"]: + if name == "lo": + commands.append( + "set interfaces loopback lo address " + ipv6 + ) + else: + commands.append( + "set interfaces ethernet " + name + " address " + ipv6 + ) + + return commands + + +def map_config_to_obj(module): + obj = [] + output = run_commands(module, ["show interfaces"]) + lines = re.split(r"\n[e|l]", output[0])[1:] + + if len(lines) > 0: + for line in lines: + splitted_line = line.split() + + if len(splitted_line) > 0: + ipv4 = [] + ipv6 = [] + + if splitted_line[0].lower().startswith("th"): + name = "e" + splitted_line[0].lower() + elif splitted_line[0].lower().startswith("o"): + name = "l" + splitted_line[0].lower() + + for i in splitted_line[1:]: + if ("." in i or ":" in i) and "/" in i: + value = i.split(r"\n")[0] + if is_ipv4(value): + ipv4.append(value) + elif is_ipv6(value): + ipv6.append(value) + + obj.append({"name": name, "ipv4": ipv4, "ipv6": ipv6}) + + 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"], + "ipv4": module.params["ipv4"], + "ipv6": module.params["ipv6"], + "state": module.params["state"], + } + ) + + return obj + + +def main(): + """ main entry point for module execution + """ + element_spec = dict( + name=dict(), + ipv4=dict(), + ipv6=dict(), + state=dict(default="present", choices=["present", "absent"]), + ) + + 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_l3_interfaces.py b/plugins/modules/vyos_l3_interfaces.py index 113ea53..a77ecaf 100644 --- a/plugins/modules/vyos_l3_interfaces.py +++ b/plugins/modules/vyos_l3_interfaces.py @@ -36,15 +36,12 @@ ANSIBLE_METADATA = { "supported_by": "network", } -DOCUMENTATION = """ ---- -module: vyos_l3_interfaces -version_added: 2.9 +DOCUMENTATION = """module: vyos_l3_interfaces 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). +- 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: @@ -54,62 +51,62 @@ options: suboptions: name: description: - - Full name of the interface, e.g. eth0, eth1. + - Full name of the interface, e.g. eth0, eth1. type: str - required: True + required: true ipv4: description: - - List of IPv4 addresses of the interface. + - List of IPv4 addresses of the interface. type: list elements: dict suboptions: address: description: - - IPv4 address of the interface. + - IPv4 address of the interface. type: str ipv6: description: - - List of IPv6 addresses of the interface. + - List of IPv6 addresses of the interface. type: list elements: dict suboptions: address: description: - - IPv6 address of the interface. + - IPv6 address of the interface. type: str vifs: description: - - Virtual sub-interfaces L3 configurations. + - Virtual sub-interfaces L3 configurations. elements: dict type: list suboptions: vlan_id: description: - - Identifier for the virtual sub-interface. + - Identifier for the virtual sub-interface. type: int ipv4: description: - - List of IPv4 addresses of the virtual interface. + - List of IPv4 addresses of the virtual interface. type: list elements: dict suboptions: address: description: - - IPv4 address of the virtual interface. + - IPv4 address of the virtual interface. type: str ipv6: description: - - List of IPv6 addresses of the virtual interface. + - List of IPv6 addresses of the virtual interface. type: list elements: dict suboptions: address: description: - - IPv6 address of the virtual interface. + - IPv6 address of the virtual interface. type: str state: description: - - The state of the configuration after module completion. + - The state of the configuration after module completion. type: str choices: - merged @@ -117,7 +114,6 @@ options: - overridden - deleted default: merged - """ EXAMPLES = """ # Using merged diff --git a/plugins/modules/vyos_lag_interfaces.py b/plugins/modules/vyos_lag_interfaces.py index 5c9b4c1..84f3d01 100644 --- a/plugins/modules/vyos_lag_interfaces.py +++ b/plugins/modules/vyos_lag_interfaces.py @@ -36,15 +36,13 @@ ANSIBLE_METADATA = { "supported_by": "network", } -DOCUMENTATION = """ ---- -module: vyos_lag_interfaces -version_added: 2.9 +DOCUMENTATION = """module: vyos_lag_interfaces short_description: Manages attributes of link aggregation groups on VyOS network devices. -description: This module manages attributes of link aggregation groups on VyOS network devices. +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). See L(the VyOS OS Platform Options,../network/user_guide/platform_vyos.html). +- 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: @@ -53,58 +51,58 @@ options: suboptions: name: description: - - Name of the link aggregation group (LAG) or bond. + - Name of the link aggregation group (LAG) or bond. type: str - required: True + required: true mode: description: - - LAG or bond mode. + - LAG or bond mode. type: str choices: - - 802.3ad - - active-backup - - broadcast - - round-robin - - transmit-load-balance - - adaptive-load-balance - - xor-hash + - 802.3ad + - active-backup + - broadcast + - round-robin + - transmit-load-balance + - adaptive-load-balance + - xor-hash members: description: - - List of member interfaces for the LAG (bond). + - List of member interfaces for the LAG (bond). type: list suboptions: member: description: - - Name of the member interface. + - Name of the member interface. type: str primary: description: - - Primary device interfaces for the LAG (bond). + - Primary device interfaces for the LAG (bond). type: str hash_policy: description: - - LAG or bonding transmit hash policy. + - LAG or bonding transmit hash policy. type: str choices: - - layer2 - - layer2+3 - - layer3+4 + - layer2 + - layer2+3 + - layer3+4 arp_monitor: description: - - ARP Link monitoring parameters. + - ARP Link monitoring parameters. type: dict suboptions: interval: description: - - ARP link monitoring frequency in milliseconds. + - ARP link monitoring frequency in milliseconds. type: int target: description: - - IP address to use for ARP monitoring. + - IP address to use for ARP monitoring. type: list state: description: - - The state of the configuration after module completion. + - The state of the configuration after module completion. type: str choices: - merged @@ -112,7 +110,6 @@ options: - overridden - deleted default: merged - """ EXAMPLES = """ # Using merged diff --git a/plugins/modules/vyos_linkagg.py b/plugins/modules/vyos_linkagg.py index 294bec1..6810a54 120000..100644 --- a/plugins/modules/vyos_linkagg.py +++ b/plugins/modules/vyos_linkagg.py @@ -1 +1,327 @@ -_vyos_linkagg.py
\ No newline at end of file +#!/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_linkagg +author: Ricardo Carrillo Cruz (@rcarrillocruz) +short_description: Manage link aggregation groups on VyOS network devices +description: +- This module provides declarative management of link aggregation groups on VyOS network + devices. +deprecated: + removed_in: '2.13' + alternative: vyos_lag_interfaces + why: Updated modules released with more functionality. +notes: +- Tested against VYOS 1.1.7 +options: + name: + description: + - Name of the link aggregation group. + required: true + type: str + mode: + description: + - Mode of the link aggregation group. + choices: + - 802.3ad + - active-backup + - broadcast + - round-robin + - transmit-load-balance + - adaptive-load-balance + - xor-hash + - 'on' + type: str + members: + description: + - List of members of the link aggregation group. + type: list + aggregate: + description: List of link aggregation definitions. + type: list + state: + description: + - State of the link aggregation group. + default: present + choices: + - present + - absent + - up + - down + type: str +extends_documentation_fragment: +- vyos.vyos.vyos +""" + +EXAMPLES = """ +- name: configure link aggregation group + vyos_linkagg: + name: bond0 + members: + - eth0 + - eth1 + +- name: remove configuration + vyos_linkagg: + name: bond0 + state: absent + +- name: Create aggregate of linkagg definitions + vyos_linkagg: + aggregate: + - { name: bond0, members: [eth1] } + - { name: bond1, members: [eth2] } + +- name: Remove aggregate of linkagg definitions + vyos_linkagg: + aggregate: + - name: bond0 + - name: bond1 + 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 interfaces bonding bond0 + - set interfaces ethernet eth0 bond-group 'bond0' + - set interfaces ethernet eth1 bond-group 'bond0' +""" +from copy import deepcopy + +from ansible.module_utils.basic import AnsibleModule +from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.utils import ( + remove_default_spec, +) +from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.vyos import ( + load_config, + run_commands, +) +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"] + members = w.get("members") or [] + mode = w["mode"] + + if mode == "on": + mode = "802.3ad" + + state = w["state"] + + obj_in_have = search_obj_in_list(name, have) + + if state == "absent": + if obj_in_have: + for m in obj_in_have["members"]: + commands.append( + "delete interfaces ethernet " + m + " bond-group" + ) + + commands.append("delete interfaces bonding " + name) + else: + if not obj_in_have: + commands.append( + "set interfaces bonding " + name + " mode " + mode + ) + + for m in members: + commands.append( + "set interfaces ethernet " + m + " bond-group " + name + ) + + if state == "down": + commands.append( + "set interfaces bonding " + name + " disable" + ) + else: + if mode != obj_in_have["mode"]: + commands.append( + "set interfaces bonding " + name + " mode " + mode + ) + + missing_members = list( + set(members) - set(obj_in_have["members"]) + ) + for m in missing_members: + commands.append( + "set interfaces ethernet " + m + " bond-group " + name + ) + + if state == "down" and obj_in_have["state"] == "up": + commands.append( + "set interfaces bonding " + name + " disable" + ) + elif state == "up" and obj_in_have["state"] == "down": + commands.append( + "delete interfaces bonding " + name + " disable" + ) + + return commands + + +def map_config_to_obj(module): + obj = [] + output = run_commands(module, ["show interfaces bonding slaves"]) + lines = output[0].splitlines() + + if len(lines) > 1: + for line in lines[1:]: + splitted_line = line.split() + + name = splitted_line[0] + mode = splitted_line[1] + state = splitted_line[2] + + if len(splitted_line) > 4: + members = splitted_line[4:] + else: + members = [] + + obj.append( + { + "name": name, + "mode": mode, + "members": members, + "state": state, + } + ) + + 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"], + "mode": module.params["mode"], + "members": module.params["members"], + "state": module.params["state"], + } + ) + + return obj + + +def main(): + """ main entry point for module execution + """ + element_spec = dict( + name=dict(), + mode=dict( + choices=[ + "802.3ad", + "active-backup", + "broadcast", + "round-robin", + "transmit-load-balance", + "adaptive-load-balance", + "xor-hash", + "on", + ], + default="802.3ad", + ), + members=dict(type="list"), + state=dict( + default="present", choices=["present", "absent", "up", "down"] + ), + ) + + 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_lldp.py b/plugins/modules/vyos_lldp.py index 259de8c..aa7a316 120000..100644 --- a/plugins/modules/vyos_lldp.py +++ b/plugins/modules/vyos_lldp.py @@ -1 +1,145 @@ -_vyos_lldp.py
\ No newline at end of file +#!/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/>. +# + +from __future__ import absolute_import, division, print_function + +__metaclass__ = type + + +ANSIBLE_METADATA = { + "metadata_version": "1.1", + "status": ["deprecated"], + "supported_by": "network", +} + + +DOCUMENTATION = """module: vyos_lldp +author: Ricardo Carrillo Cruz (@rcarrillocruz) +short_description: Manage LLDP configuration on VyOS network devices +description: +- This module provides declarative management of LLDP service on VyOS network devices. +deprecated: + removed_in: '2.13' + alternative: vyos_lldp_global + why: Updated modules released with more functionality. +notes: +- Tested against VYOS 1.1.7 +options: + interfaces: + description: + - Name of the interfaces. + type: list + state: + description: + - State of the link aggregation group. + default: present + choices: + - present + - absent + - enabled + - disabled + type: str +extends_documentation_fragment: +- vyos.vyos.vyos +""" + +EXAMPLES = """ +- name: Enable LLDP service + vyos_lldp: + state: present + +- name: Disable LLDP service + vyos_lldp: + 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 +""" +from ansible.module_utils.basic import AnsibleModule +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 has_lldp(module): + config = get_config(module).splitlines() + + if "set service 'lldp'" in config or "set service lldp" in config: + return True + else: + return False + + +def main(): + """ main entry point for module execution + """ + argument_spec = dict( + interfaces=dict(type="list"), + state=dict( + default="present", + choices=["present", "absent", "enabled", "disabled"], + ), + ) + + argument_spec.update(vyos_argument_spec) + + module = AnsibleModule( + argument_spec=argument_spec, supports_check_mode=True + ) + + warnings = list() + + result = {"changed": False} + + if warnings: + result["warnings"] = warnings + + HAS_LLDP = has_lldp(module) + + commands = [] + + if module.params["state"] == "absent" and HAS_LLDP: + commands.append("delete service lldp") + elif module.params["state"] == "present" and not HAS_LLDP: + commands.append("set service lldp") + + 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_lldp_global.py b/plugins/modules/vyos_lldp_global.py index 55b1a1a..08eb113 100644 --- a/plugins/modules/vyos_lldp_global.py +++ b/plugins/modules/vyos_lldp_global.py @@ -36,17 +36,16 @@ ANSIBLE_METADATA = { "supported_by": "network", } -DOCUMENTATION = """ ---- -module: vyos_lldp_global -version_added: 2.9 -short_description: Manage link layer discovery protocol (LLDP) attributes on VyOS devices.. -description: This module manages link layer discovery protocol (LLDP) attributes on VyOS devices. +DOCUMENTATION = """module: vyos_lldp_global +short_description: Manage link layer discovery protocol (LLDP) attributes on VyOS + devices.. +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). See L(the VyOS OS Platform Options,../network/user_guide/platform_vyos.html). +- 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) +- Rohit Thakur (@rohitthakur2590) options: config: description: The provided link layer discovery protocol (LLDP) configuration. @@ -54,28 +53,28 @@ options: suboptions: enable: description: - - This argument is a boolean value to enable or disable LLDP. + - This argument is a boolean value to enable or disable LLDP. type: bool address: description: - - This argument defines management-address. + - This argument defines management-address. type: str snmp: description: - - This argument enable the SNMP queries to LLDP database. + - This argument enable the SNMP queries to LLDP database. type: str legacy_protocols: description: - - List of the supported legacy protocols. + - List of the supported legacy protocols. type: list choices: - - cdp - - edp - - fdp - - sonmp + - cdp + - edp + - fdp + - sonmp state: description: - - The state of the configuration after module completion. + - The state of the configuration after module completion. type: str choices: - merged diff --git a/plugins/modules/vyos_lldp_interface.py b/plugins/modules/vyos_lldp_interface.py index 7847a58..402facf 120000..100644 --- a/plugins/modules/vyos_lldp_interface.py +++ b/plugins/modules/vyos_lldp_interface.py @@ -1 +1,264 @@ -_vyos_lldp_interface.py
\ No newline at end of file +#!/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 +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.vyos.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_collections.ansible.netcommon.plugins.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_lldp_interfaces.py b/plugins/modules/vyos_lldp_interfaces.py index 70ceed8..8fe572b 100644 --- a/plugins/modules/vyos_lldp_interfaces.py +++ b/plugins/modules/vyos_lldp_interfaces.py @@ -36,17 +36,14 @@ ANSIBLE_METADATA = { "supported_by": "network", } -DOCUMENTATION = """ ---- -module: vyos_lldp_interfaces -version_added: 2.9 +DOCUMENTATION = """module: vyos_lldp_interfaces 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). +- 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) +- Rohit Thakur (@rohitthakur2590) options: config: description: A list of lldp interfaces configurations. @@ -54,43 +51,43 @@ options: suboptions: name: description: - - Name of the lldp interface. + - Name of the lldp interface. type: str - required: True + required: true enable: description: - - to disable lldp on the interface. + - to disable lldp on the interface. type: bool - default: True + default: true location: description: - - LLDP-MED location data. + - LLDP-MED location data. type: dict suboptions: civic_based: description: - - Civic-based location data. + - 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 + 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 + required: true coordinate_based: description: - - Coordinate-based location. + - Coordinate-based location. type: dict suboptions: altitude: @@ -100,23 +97,23 @@ options: description: Coordinate datum type. type: str choices: - - WGS84 - - NAD83 - - MLLW + - WGS84 + - NAD83 + - MLLW latitude: description: Latitude. type: str - required: True + required: true longitude: description: Longitude. type: str - required: True + required: true elin: description: Emergency Call Service ELIN number (between 10-25 numbers). type: str state: description: - - The state of the configuration after module completion. + - The state of the configuration after module completion. type: str choices: - merged @@ -124,7 +121,6 @@ options: - overridden - deleted default: merged - """ EXAMPLES = """ # Using merged diff --git a/plugins/modules/vyos_logging.py b/plugins/modules/vyos_logging.py index 6c2f9f7..9f81eb9 100644 --- a/plugins/modules/vyos_logging.py +++ b/plugins/modules/vyos_logging.py @@ -25,42 +25,45 @@ ANSIBLE_METADATA = { "supported_by": "network", } -DOCUMENTATION = """ ---- -module: vyos_logging -version_added: "2.4" -author: "Trishna Guha (@trishnaguha)" +DOCUMENTATION = """module: vyos_logging +author: Trishna Guha (@trishnaguha) short_description: Manage logging on network devices description: - - This module provides declarative management of logging - on Vyatta Vyos devices. +- This module provides declarative management of logging on Vyatta Vyos 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). +- 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: - - Destination of the logs. - choices: ['console', 'file', 'global', 'host', 'user'] + - Destination of the logs. + choices: + - console + - file + - global + - host + - user name: description: - - If value of C(dest) is I(file) it indicates file-name, - for I(user) it indicates username and for I(host) indicates - the host name to be notified. + - If value of C(dest) is I(file) it indicates file-name, for I(user) it indicates + username and for I(host) indicates the host name to be notified. facility: description: - - Set logging facility. + - Set logging facility. level: description: - - Set logging severity levels. + - Set logging severity levels. aggregate: description: List of logging definitions. state: description: - - State of the logging configuration. + - State of the logging configuration. default: present - choices: ['present', 'absent'] -extends_documentation_fragment: vyos + choices: + - present + - absent +extends_documentation_fragment: +- vyos.vyos.vyos """ EXAMPLES = """ @@ -112,7 +115,9 @@ import re 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.ansible.netcommon.plugins.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, @@ -252,7 +257,7 @@ def main(): remove_default_spec(aggregate_spec) argument_spec = dict( - aggregate=dict(type="list", elements="dict", options=aggregate_spec) + aggregate=dict(type="list", elements="dict", options=aggregate_spec), ) argument_spec.update(element_spec) diff --git a/plugins/modules/vyos_ping.py b/plugins/modules/vyos_ping.py index 8271049..3d5a903 100644 --- a/plugins/modules/vyos_ping.py +++ b/plugins/modules/vyos_ping.py @@ -29,56 +29,56 @@ ANSIBLE_METADATA = { "supported_by": "community", } -DOCUMENTATION = """ ---- -module: vyos_ping +DOCUMENTATION = """module: vyos_ping short_description: Tests reachability using ping from VyOS network devices description: - - Tests reachability using ping from a VyOS device to a remote destination. - - 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. +- Tests reachability using ping from a VyOS device to a remote destination. +- 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. author: - - Nilashish Chakraborty (@NilashishC) -version_added: '2.8' +- Nilashish Chakraborty (@NilashishC) options: dest: description: - - The IP Address or hostname (resolvable by the device) of the remote node. + - The IP Address or hostname (resolvable by the device) of the remote node. required: true count: description: - - Number of packets to send to check reachability. + - Number of packets to send to check reachability. type: int default: 5 source: description: - - The source interface or IP Address to use while sending the ping packet(s). + - The source interface or IP Address to use while sending the ping packet(s). ttl: description: - - The time-to-live value for the ICMP packet(s). + - The time-to-live value for the ICMP packet(s). type: int size: description: - - Determines the size (in bytes) of the ping packet(s). + - Determines the size (in bytes) of the ping packet(s). type: int interval: description: - - Determines the interval (in seconds) between consecutive pings. + - Determines the interval (in seconds) between consecutive pings. type: int state: description: - - Determines if the expected result is success or fail. - choices: [ absent, present ] + - Determines if the expected result is success or fail. + 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 +- 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.vyos.vyos """ EXAMPLES = """ diff --git a/plugins/modules/vyos_static_route.py b/plugins/modules/vyos_static_route.py index 564a257..e0c40e7 100644 --- a/plugins/modules/vyos_static_route.py +++ b/plugins/modules/vyos_static_route.py @@ -26,41 +26,40 @@ ANSIBLE_METADATA = { } -DOCUMENTATION = """ ---- -module: vyos_static_route -version_added: "2.4" -author: "Trishna Guha (@trishnaguha)" +DOCUMENTATION = """module: vyos_static_route +author: Trishna Guha (@trishnaguha) short_description: Manage static IP routes on Vyatta VyOS network devices description: - - This module provides declarative management of static - IP routes on Vyatta VyOS network devices. +- This module provides declarative management of static IP routes on Vyatta 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). +- 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: - - Network prefix of the static route. - C(mask) param should be ignored if C(prefix) is provided - with C(mask) value C(prefix/mask). + - Network prefix of the static route. C(mask) param should be ignored if C(prefix) + is provided with C(mask) value C(prefix/mask). mask: description: - - Network prefix mask of the static route. + - Network prefix mask of the static route. next_hop: description: - - Next hop IP of the static route. + - Next hop IP of the static route. admin_distance: description: - - Admin distance of the static route. + - Admin distance of the static route. aggregate: description: List of static route definitions state: description: - - State of the static route configuration. + - State of the static route configuration. default: present - choices: ['present', 'absent'] -extends_documentation_fragment: vyos + choices: + - present + - absent +extends_documentation_fragment: +- vyos.vyos.vyos """ EXAMPLES = """ @@ -110,7 +109,9 @@ import re 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.ansible.netcommon.plugins.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, @@ -250,7 +251,7 @@ def main(): remove_default_spec(aggregate_spec) argument_spec = dict( - aggregate=dict(type="list", elements="dict", options=aggregate_spec) + aggregate=dict(type="list", elements="dict", options=aggregate_spec), ) argument_spec.update(element_spec) diff --git a/plugins/modules/vyos_system.py b/plugins/modules/vyos_system.py index 30694a6..b49462b 100644 --- a/plugins/modules/vyos_system.py +++ b/plugins/modules/vyos_system.py @@ -24,41 +24,39 @@ ANSIBLE_METADATA = { } -DOCUMENTATION = """ ---- -module: "vyos_system" -version_added: "2.3" -author: "Nathaniel Case (@Qalthos)" +DOCUMENTATION = """module: vyos_system +author: Nathaniel Case (@Qalthos) short_description: Run `set system` commands on VyOS devices description: - - Runs one or more commands on remote devices running VyOS. - This module can also be introspected to validate key parameters before - returning successfully. -extends_documentation_fragment: vyos +- Runs one or more commands on remote devices running VyOS. This module can also be + introspected to validate key parameters before returning successfully. +extends_documentation_fragment: +- vyos.vyos.vyos 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). +- 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: - - Configure the device hostname parameter. This option takes an ASCII string value. + - Configure the device hostname parameter. This option takes an ASCII string value. domain_name: description: - - The new domain name to apply to the device. + - The new domain name to apply to the device. name_servers: description: - - A list of name servers to use with the device. Mutually exclusive with - I(domain_search) - aliases: ['name_server'] + - A list of name servers to use with the device. Mutually exclusive with I(domain_search) + aliases: + - name_server domain_search: description: - - A list of domain names to search. Mutually exclusive with - I(name_server) + - A list of domain names to search. Mutually exclusive with I(name_server) state: description: - - Whether to apply (C(present)) or remove (C(absent)) the settings. + - Whether to apply (C(present)) or remove (C(absent)) the settings. default: present - choices: ['present', 'absent'] + choices: + - present + - absent """ RETURN = """ diff --git a/plugins/modules/vyos_user.py b/plugins/modules/vyos_user.py index 5a766ee..d619524 100644 --- a/plugins/modules/vyos_user.py +++ b/plugins/modules/vyos_user.py @@ -25,78 +25,75 @@ ANSIBLE_METADATA = { "supported_by": "network", } -DOCUMENTATION = """ ---- -module: vyos_user -version_added: "2.4" -author: "Trishna Guha (@trishnaguha)" +DOCUMENTATION = """module: vyos_user +author: Trishna Guha (@trishnaguha) short_description: Manage the collection of local users on VyOS device description: - - This module provides declarative management of the local usernames - configured on network devices. It allows playbooks to manage - either individual usernames or the collection of usernames in the - current running config. It also supports purging usernames from the - configuration that are not explicitly defined. +- This module provides declarative management of the local usernames configured on + network devices. It allows playbooks to manage either individual usernames or the + collection of usernames in the current running config. It also supports purging + usernames from the configuration that are not explicitly defined. 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). +- 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: - - The set of username objects to be configured on the remote - VyOS device. The list entries can either be the username or - a hash of username and properties. This argument is mutually - exclusive with the C(name) argument. - aliases: ['users', 'collection'] + - The set of username objects to be configured on the remote VyOS device. The + list entries can either be the username or a hash of username and properties. + This argument is mutually exclusive with the C(name) argument. + aliases: + - users + - collection name: description: - - The username to be configured on the VyOS device. - This argument accepts a string value and is mutually exclusive - with the C(aggregate) argument. - Please note that this option is not same as C(provider username). + - The username to be configured on the VyOS device. This argument accepts a string + value and is mutually exclusive with the C(aggregate) argument. Please note + that this option is not same as C(provider username). full_name: description: - - The C(full_name) argument provides the full name of the user - account to be created on the remote device. This argument accepts - any text string value. + - The C(full_name) argument provides the full name of the user account to be created + on the remote device. This argument accepts any text string value. configured_password: description: - - The password to be configured on the VyOS device. The - password needs to be provided in clear and it will be encrypted - on the device. - Please note that this option is not same as C(provider password). + - The password to be configured on the VyOS device. The password needs to be provided + in clear and it will be encrypted on the device. Please note that this option + is not same as C(provider password). update_password: description: - - Since passwords are encrypted in the device running config, this - argument will instruct the module when to change the password. When - set to C(always), the password will always be updated in the device - and when set to C(on_create) the password will be updated only if - the username is created. + - Since passwords are encrypted in the device running config, this argument will + instruct the module when to change the password. When set to C(always), the + password will always be updated in the device and when set to C(on_create) the + password will be updated only if the username is created. default: always - choices: ['on_create', 'always'] + choices: + - on_create + - always level: description: - - The C(level) argument configures the level of the user when logged - into the system. This argument accepts string values admin or operator. - aliases: ['role'] + - The C(level) argument configures the level of the user when logged into the + system. This argument accepts string values admin or operator. + aliases: + - role purge: description: - - Instructs the module to consider the - resource definition absolute. It will remove any previously - configured usernames on the device with the exception of the - `admin` user (the current defined set of users). + - Instructs the module to consider the resource definition absolute. It will remove + any previously configured usernames on the device with the exception of the + `admin` user (the current defined set of users). type: bool default: false state: description: - - Configures the state of the username definition - as it relates to the device operational configuration. When set - to I(present), the username(s) should be configured in the device active - configuration and when set to I(absent) the username(s) should not be - in the device active configuration + - Configures the state of the username definition as it relates to the device + operational configuration. When set to I(present), the username(s) should be + configured in the device active configuration and when set to I(absent) the + username(s) should not be in the device active configuration default: present - choices: ['present', 'absent'] -extends_documentation_fragment: vyos + choices: + - present + - absent +extends_documentation_fragment: +- vyos.vyos.vyos """ EXAMPLES = """ @@ -139,7 +136,9 @@ from copy import deepcopy from functools import partial from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils.network.common.utils import remove_default_spec +from ansible_collections.ansible.netcommon.plugins.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, diff --git a/plugins/modules/vyos_vlan.py b/plugins/modules/vyos_vlan.py index 4564749..a0aafb5 100644 --- a/plugins/modules/vyos_vlan.py +++ b/plugins/modules/vyos_vlan.py @@ -15,56 +15,55 @@ ANSIBLE_METADATA = { "supported_by": "network", } -DOCUMENTATION = """ ---- -module: vyos_vlan -version_added: "2.5" -author: "Trishna Guha (@trishnaguha)" +DOCUMENTATION = """module: vyos_vlan +author: Trishna Guha (@trishnaguha) short_description: Manage VLANs on VyOS network devices description: - - This module provides declarative management of VLANs - on VyOS network devices. +- This module provides declarative management of VLANs 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). +- 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: - - Name of the VLAN. + - Name of the VLAN. address: description: - - Configure Virtual interface address. + - Configure Virtual interface address. vlan_id: description: - - ID of the VLAN. Range 0-4094. + - ID of the VLAN. Range 0-4094. required: true interfaces: description: - - List of interfaces that should be associated to the VLAN. + - List of interfaces that should be associated to the VLAN. required: true associated_interfaces: description: - - This is a intent option and checks the operational state of the for given vlan C(name) - for associated interfaces. If the value in the C(associated_interfaces) does not match with - the operational state of vlan on device it will result in failure. - version_added: "2.5" + - This is a intent option and checks the operational state of the for given vlan + C(name) for associated interfaces. If the value in the C(associated_interfaces) + does not match with the operational state of vlan on device it will result in + failure. delay: description: - - Delay the play should wait to check for declarative intent params values. + - Delay the play should wait to check for declarative intent params values. default: 10 aggregate: description: List of VLANs definitions. purge: description: - - Purge VLANs not defined in the I(aggregate) parameter. - default: no + - Purge VLANs not defined in the I(aggregate) parameter. + default: false type: bool state: description: - - State of the VLAN configuration. + - State of the VLAN configuration. default: present - choices: ['present', 'absent'] -extends_documentation_fragment: vyos + choices: + - present + - absent +extends_documentation_fragment: +- vyos.vyos.vyos """ EXAMPLES = """ @@ -125,7 +124,9 @@ import time 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.ansible.netcommon.plugins.module_utils.network.common.utils import ( + remove_default_spec, +) from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.vyos import ( load_config, run_commands, diff --git a/plugins/terminal/__init__.py b/plugins/terminal/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/plugins/terminal/__init__.py diff --git a/plugins/terminal/vyos.py b/plugins/terminal/vyos.py new file mode 100644 index 0000000..fe7712f --- /dev/null +++ b/plugins/terminal/vyos.py @@ -0,0 +1,53 @@ +# +# (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/>. +# +from __future__ import absolute_import, division, print_function + +__metaclass__ = type + +import os +import re + +from ansible.plugins.terminal import TerminalBase +from ansible.errors import AnsibleConnectionFailure + + +class TerminalModule(TerminalBase): + + terminal_stdout_re = [ + re.compile(br"[\r\n]?[\w+\-\.:\/\[\]]+(?:\([^\)]+\)){,3}(?:>|#) ?$"), + re.compile(br"\@[\w\-\.]+:\S+?[>#\$] ?$"), + ] + + terminal_stderr_re = [ + re.compile(br"\n\s*Invalid command:"), + re.compile(br"\nCommit failed"), + re.compile(br"\n\s+Set failed"), + ] + + terminal_length = os.getenv("ANSIBLE_VYOS_TERMINAL_LENGTH", 10000) + + def on_open_shell(self): + try: + for cmd in (b"set terminal length 0", b"set terminal width 512"): + self._exec_cli_command(cmd) + self._exec_cli_command( + b"set terminal length %d" % self.terminal_length + ) + except AnsibleConnectionFailure: + raise AnsibleConnectionFailure("unable to set terminal parameters") diff --git a/tests/.gitignore b/tests/.gitignore new file mode 100644 index 0000000..ea1472e --- /dev/null +++ b/tests/.gitignore @@ -0,0 +1 @@ +output/ diff --git a/tests/integration/targets/prepare_vyos_tests/tasks/main.yaml b/tests/integration/targets/prepare_vyos_tests/tasks/main.yaml index 5813284..afbc291 100644 --- a/tests/integration/targets/prepare_vyos_tests/tasks/main.yaml +++ b/tests/integration/targets/prepare_vyos_tests/tasks/main.yaml @@ -1,13 +1,9 @@ --- - name: Ensure required interfaces are present in running-config - network.cli.cli_config: - config: "{{ lines }}" 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 + lines: "set interfaces ethernet eth0 address dhcp\nset interfaces ethernet eth0\ + \ speed auto\nset interfaces ethernet eth0 duplex auto\nset interfaces ethernet\ + \ eth1\nset interfaces ethernet eth2\ndelete interfaces loopback lo\n" ignore_errors: true + ansible.netcommon.cli_config: + config: '{{ lines }}' diff --git a/tests/integration/targets/vyos_banner/defaults/main.yaml b/tests/integration/targets/vyos_banner/defaults/main.yaml index 9ef5ba5..a845c24 100644 --- a/tests/integration/targets/vyos_banner/defaults/main.yaml +++ b/tests/integration/targets/vyos_banner/defaults/main.yaml @@ -1,3 +1,3 @@ --- -testcase: "*" +testcase: '*' test_items: [] diff --git a/tests/integration/targets/vyos_banner/tasks/cli.yaml b/tests/integration/targets/vyos_banner/tasks/cli.yaml index 890d3ac..90f265f 100644 --- a/tests/integration/targets/vyos_banner/tasks/cli.yaml +++ b/tests/integration/targets/vyos_banner/tasks/cli.yaml @@ -1,22 +1,22 @@ --- - name: collect all cli test cases find: - paths: "{{ role_path }}/tests/cli" - patterns: "{{ testcase }}.yaml" + paths: '{{ role_path }}/tests/cli' + patterns: '{{ testcase }}.yaml' 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 }} ansible_connection=network_cli" - with_items: "{{ test_items }}" +- name: run test case (connection=ansible.netcommon.network_cli) + include: '{{ test_case_to_run }} ansible_connection=ansible.netcommon.network_cli' + with_items: '{{ test_items }}' loop_control: loop_var: test_case_to_run - name: run test case (connection=local) - include: "{{ test_case_to_run }} ansible_connection=local" - with_first_found: "{{ test_items }}" + include: '{{ test_case_to_run }} ansible_connection=local' + with_first_found: '{{ test_items }}' loop_control: loop_var: test_case_to_run diff --git a/tests/integration/targets/vyos_banner/tasks/main.yaml b/tests/integration/targets/vyos_banner/tasks/main.yaml index d4cf26f..a3db933 100644 --- a/tests/integration/targets/vyos_banner/tasks/main.yaml +++ b/tests/integration/targets/vyos_banner/tasks/main.yaml @@ -1,2 +1,4 @@ --- -- {include: cli.yaml, tags: ['cli']} +- include: cli.yaml + tags: + - cli diff --git a/tests/integration/targets/vyos_banner/tests/cli/basic-no-login.yaml b/tests/integration/targets/vyos_banner/tests/cli/basic-no-login.yaml index 5efdf8e..1ade232 100644 --- a/tests/integration/targets/vyos_banner/tests/cli/basic-no-login.yaml +++ b/tests/integration/targets/vyos_banner/tests/cli/basic-no-login.yaml @@ -1,41 +1,34 @@ --- - debug: - msg: "cli/basic-no-login.yaml on connection={{ ansible_connection }}" + msg: cli/basic-no-login.yaml on connection={{ ansible_connection }} - name: Setup vyos.vyos.vyos_banner: banner: pre-login - text: | - Junk pre-login banner - over multiple lines + text: "Junk pre-login banner\nover multiple lines\n" state: present - name: remove pre-login + register: result vyos.vyos.vyos_banner: banner: pre-login state: absent - register: result - debug: - msg: "{{ result }}" + msg: '{{ result }}' - assert: that: - - "result.changed == true" + - result.changed == true - "'delete system login banner pre-login' in result.commands" - name: remove pre-login (idempotent) + register: result vyos.vyos.vyos_banner: banner: pre-login state: absent - register: result - assert: that: - - "result.changed == false" - - "result.commands | length == 0" - - -# FIXME add in tests for everything defined in docs -# FIXME Test state:absent + test: -# FIXME Without powers ensure "privileged mode required" + - result.changed == false + - result.commands | length == 0 diff --git a/tests/integration/targets/vyos_banner/tests/cli/basic-post-login.yaml b/tests/integration/targets/vyos_banner/tests/cli/basic-post-login.yaml index ff6cbad..17cc07d 100644 --- a/tests/integration/targets/vyos_banner/tests/cli/basic-post-login.yaml +++ b/tests/integration/targets/vyos_banner/tests/cli/basic-post-login.yaml @@ -1,6 +1,6 @@ --- - debug: - msg: "cli/basic-post-login.yaml on connection={{ ansible_connection }}" + msg: cli/basic-post-login.yaml on connection={{ ansible_connection }} - name: setup - remove post-login vyos.vyos.vyos_banner: @@ -8,40 +8,29 @@ state: absent - name: Set post-login + register: result vyos.vyos.vyos_banner: banner: post-login - text: | - this is my post-login banner - that has a multiline - string + text: "this is my post-login banner\nthat has a multiline\nstring\n" state: present - register: result - debug: - msg: "{{ result }}" + msg: '{{ result }}' - assert: that: - - "result.changed == true" + - result.changed == true - "'this is my post-login banner' in result.commands[0]" - "'that has a multiline' in result.commands[0]" - name: Set post-login again (idempotent) + register: result vyos.vyos.vyos_banner: banner: post-login - text: | - this is my post-login banner - that has a multiline - string + text: "this is my post-login banner\nthat has a multiline\nstring\n" state: present - register: result - assert: that: - - "result.changed == false" - - "result.commands | length == 0" - - -# FIXME add in tests for everything defined in docs -# FIXME Test state:absent + test: -# FIXME Without powers ensure "privileged mode required" + - result.changed == false + - result.commands | length == 0 diff --git a/tests/integration/targets/vyos_banner/tests/cli/basic-pre-login.yaml b/tests/integration/targets/vyos_banner/tests/cli/basic-pre-login.yaml index 8489d87..526c657 100644 --- a/tests/integration/targets/vyos_banner/tests/cli/basic-pre-login.yaml +++ b/tests/integration/targets/vyos_banner/tests/cli/basic-pre-login.yaml @@ -1,6 +1,6 @@ --- - debug: - msg: "cli/basic-pre-login.yaml on connection={{ ansible_connection }}" + msg: cli/basic-pre-login.yaml on connection={{ ansible_connection }} - name: setup - remove pre-login vyos.vyos.vyos_banner: @@ -8,40 +8,29 @@ state: absent - name: Set pre-login + register: result vyos.vyos.vyos_banner: banner: pre-login - text: | - this is my pre-login banner - that has a multiline - string + text: "this is my pre-login banner\nthat has a multiline\nstring\n" state: present - register: result - debug: - msg: "{{ result }}" + msg: '{{ result }}' - assert: that: - - "result.changed == true" + - result.changed == true - "'this is my pre-login banner' in result.commands[0]" - "'that has a multiline' in result.commands[0]" - name: Set pre-login again (idempotent) + register: result vyos.vyos.vyos_banner: banner: pre-login - text: | - this is my pre-login banner - that has a multiline - string + text: "this is my pre-login banner\nthat has a multiline\nstring\n" state: present - register: result - assert: that: - - "result.changed == false" - - "result.commands | length == 0" - - -# FIXME add in tests for everything defined in docs -# FIXME Test state:absent + test: -# FIXME Without powers ensure "privileged mode required" + - result.changed == false + - result.commands | length == 0 diff --git a/tests/integration/targets/vyos_command/defaults/main.yaml b/tests/integration/targets/vyos_command/defaults/main.yaml index 9ef5ba5..a845c24 100644 --- a/tests/integration/targets/vyos_command/defaults/main.yaml +++ b/tests/integration/targets/vyos_command/defaults/main.yaml @@ -1,3 +1,3 @@ --- -testcase: "*" +testcase: '*' test_items: [] diff --git a/tests/integration/targets/vyos_command/tasks/cli.yaml b/tests/integration/targets/vyos_command/tasks/cli.yaml index 890d3ac..90f265f 100644 --- a/tests/integration/targets/vyos_command/tasks/cli.yaml +++ b/tests/integration/targets/vyos_command/tasks/cli.yaml @@ -1,22 +1,22 @@ --- - name: collect all cli test cases find: - paths: "{{ role_path }}/tests/cli" - patterns: "{{ testcase }}.yaml" + paths: '{{ role_path }}/tests/cli' + patterns: '{{ testcase }}.yaml' 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 }} ansible_connection=network_cli" - with_items: "{{ test_items }}" +- name: run test case (connection=ansible.netcommon.network_cli) + include: '{{ test_case_to_run }} ansible_connection=ansible.netcommon.network_cli' + with_items: '{{ test_items }}' loop_control: loop_var: test_case_to_run - name: run test case (connection=local) - include: "{{ test_case_to_run }} ansible_connection=local" - with_first_found: "{{ test_items }}" + include: '{{ test_case_to_run }} ansible_connection=local' + with_first_found: '{{ test_items }}' loop_control: loop_var: test_case_to_run diff --git a/tests/integration/targets/vyos_command/tasks/main.yaml b/tests/integration/targets/vyos_command/tasks/main.yaml index d4cf26f..a3db933 100644 --- a/tests/integration/targets/vyos_command/tasks/main.yaml +++ b/tests/integration/targets/vyos_command/tasks/main.yaml @@ -1,2 +1,4 @@ --- -- {include: cli.yaml, tags: ['cli']} +- include: cli.yaml + tags: + - cli diff --git a/tests/integration/targets/vyos_command/tests/cli/bad_operator.yaml b/tests/integration/targets/vyos_command/tests/cli/bad_operator.yaml index 5ff72fa..690937f 100644 --- a/tests/integration/targets/vyos_command/tests/cli/bad_operator.yaml +++ b/tests/integration/targets/vyos_command/tests/cli/bad_operator.yaml @@ -2,14 +2,14 @@ - debug: msg="START cli/bad_operator.yaml on connection={{ ansible_connection }}" - name: test bad operator + register: result + ignore_errors: true vyos.vyos.vyos_command: commands: - show version - show interfaces wait_for: - result[0] is 'VyOS' - register: result - ignore_errors: true - assert: that: diff --git a/tests/integration/targets/vyos_command/tests/cli/cli_command.yaml b/tests/integration/targets/vyos_command/tests/cli/cli_command.yaml index a10f2bc..61ed054 100644 --- a/tests/integration/targets/vyos_command/tests/cli/cli_command.yaml +++ b/tests/integration/targets/vyos_command/tests/cli/cli_command.yaml @@ -1,41 +1,43 @@ --- - debug: - msg: "START cli/cli_command.yaml on connection={{ ansible_connection }}" + msg: START cli/cli_command.yaml on connection={{ ansible_connection }} - block: + - name: get output for single command - network.cli.cli_command: - command: show version register: result + ansible.netcommon.cli_command: + command: show version - assert: that: - - "result.changed == false" - - "result.stdout is defined" + - result.changed == false + - result.stdout is defined - name: send invalid command - network.cli.cli_command: - command: 'show foo' register: result ignore_errors: true + ansible.netcommon.cli_command: + command: show foo - assert: that: - - "result.failed == true" - - "result.msg is defined" - when: "ansible_connection == 'network_cli'" + - result.failed == true + - result.msg is defined + when: ansible_connection == 'ansible.netcommon.network_cli' - block: + - name: test failure for local connection - network.cli.cli_command: - command: show version register: result ignore_errors: true + ansible.netcommon.cli_command: + command: show version - assert: that: - - 'result.failed == true' + - result.failed == true - "'Connection type local is not valid for this module' in result.msg" - when: "ansible_connection == 'local'" + when: ansible_connection == 'local' - debug: msg="END cli/cli_command.yaml on connection={{ ansible_connection }}" diff --git a/tests/integration/targets/vyos_command/tests/cli/contains.yaml b/tests/integration/targets/vyos_command/tests/cli/contains.yaml index b8665fa..efaf811 100644 --- a/tests/integration/targets/vyos_command/tests/cli/contains.yaml +++ b/tests/integration/targets/vyos_command/tests/cli/contains.yaml @@ -2,6 +2,7 @@ - debug: msg="START cli/contains.yaml on connection={{ ansible_connection }}" - name: test contains operator + register: result vyos.vyos.vyos_command: commands: - show version @@ -9,7 +10,6 @@ wait_for: - result[0] contains VyOS - result[1] contains eth0 - register: result - assert: that: diff --git a/tests/integration/targets/vyos_command/tests/cli/invalid.yaml b/tests/integration/targets/vyos_command/tests/cli/invalid.yaml index 04d203d..ac8af3f 100644 --- a/tests/integration/targets/vyos_command/tests/cli/invalid.yaml +++ b/tests/integration/targets/vyos_command/tests/cli/invalid.yaml @@ -2,21 +2,23 @@ - debug: msg="START cli/invalid.yaml on connection={{ ansible_connection }}" - name: run invalid command - vyos.vyos.vyos_command: - commands: show foo register: result ignore_errors: true + vyos.vyos.vyos_command: + commands: show foo -- assert: {that: result.failed} +- assert: + that: result.failed - name: run commands that include invalid command + register: result + ignore_errors: true vyos.vyos.vyos_command: commands: - show version - show foo - register: result - ignore_errors: true -- assert: {that: result.failed} +- assert: + that: result.failed - debug: msg="END cli/invalid.yaml on connection={{ ansible_connection }}" diff --git a/tests/integration/targets/vyos_command/tests/cli/output.yaml b/tests/integration/targets/vyos_command/tests/cli/output.yaml index 1bc0dc6..9ed1906 100644 --- a/tests/integration/targets/vyos_command/tests/cli/output.yaml +++ b/tests/integration/targets/vyos_command/tests/cli/output.yaml @@ -2,9 +2,9 @@ - debug: msg="START cli/output.yaml on connection={{ ansible_connection }}" - name: get output for single command + register: result vyos.vyos.vyos_command: commands: show version - register: result - assert: that: @@ -13,11 +13,11 @@ - result.stdout_lines is defined - name: get output for multiple commands + register: result vyos.vyos.vyos_command: commands: - show version - show interfaces - register: result - assert: that: @@ -26,14 +26,12 @@ - result.stdout | length == 2 - name: Get output for multiple commands that call less explicitly + register: result vyos.vyos.vyos_command: commands: - # NOTE: We only test show commands that will output <ANSIBLE_VYOS_TERMINAL_LENGTH - # Otherwise you will get ": "command timeout triggered" - show hardware cpu detail - show hardware mem - show license - register: result - assert: that: diff --git a/tests/integration/targets/vyos_command/tests/cli/timeout.yaml b/tests/integration/targets/vyos_command/tests/cli/timeout.yaml index 57120ac..fceea5c 100644 --- a/tests/integration/targets/vyos_command/tests/cli/timeout.yaml +++ b/tests/integration/targets/vyos_command/tests/cli/timeout.yaml @@ -2,13 +2,13 @@ - debug: msg="START cli/timeout.yaml on connection={{ ansible_connection }}" - name: test bad condition + register: result + ignore_errors: true vyos.vyos.vyos_command: commands: - show version wait_for: - result[0] contains bad_value_string - register: result - ignore_errors: true - assert: that: diff --git a/tests/integration/targets/vyos_config/defaults/main.yaml b/tests/integration/targets/vyos_config/defaults/main.yaml index 9ef5ba5..a845c24 100644 --- a/tests/integration/targets/vyos_config/defaults/main.yaml +++ b/tests/integration/targets/vyos_config/defaults/main.yaml @@ -1,3 +1,3 @@ --- -testcase: "*" +testcase: '*' test_items: [] diff --git a/tests/integration/targets/vyos_config/tasks/cli.yaml b/tests/integration/targets/vyos_config/tasks/cli.yaml index 890d3ac..90f265f 100644 --- a/tests/integration/targets/vyos_config/tasks/cli.yaml +++ b/tests/integration/targets/vyos_config/tasks/cli.yaml @@ -1,22 +1,22 @@ --- - name: collect all cli test cases find: - paths: "{{ role_path }}/tests/cli" - patterns: "{{ testcase }}.yaml" + paths: '{{ role_path }}/tests/cli' + patterns: '{{ testcase }}.yaml' 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 }} ansible_connection=network_cli" - with_items: "{{ test_items }}" +- name: run test case (connection=ansible.netcommon.network_cli) + include: '{{ test_case_to_run }} ansible_connection=ansible.netcommon.network_cli' + with_items: '{{ test_items }}' loop_control: loop_var: test_case_to_run - name: run test case (connection=local) - include: "{{ test_case_to_run }} ansible_connection=local" - with_first_found: "{{ test_items }}" + include: '{{ test_case_to_run }} ansible_connection=local' + with_first_found: '{{ test_items }}' loop_control: loop_var: test_case_to_run diff --git a/tests/integration/targets/vyos_config/tasks/cli_config.yaml b/tests/integration/targets/vyos_config/tasks/cli_config.yaml index f5d5b55..98bd1fc 100644 --- a/tests/integration/targets/vyos_config/tasks/cli_config.yaml +++ b/tests/integration/targets/vyos_config/tasks/cli_config.yaml @@ -1,16 +1,16 @@ --- - name: collect all cli_config test cases find: - paths: "{{ role_path }}/tests/cli_config" - patterns: "{{ testcase }}.yaml" + paths: '{{ role_path }}/tests/cli_config' + patterns: '{{ testcase }}.yaml' 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 }} ansible_connection=network_cli" - with_items: "{{ test_items }}" +- name: run test case (connection=ansible.netcommon.network_cli) + include: '{{ test_case_to_run }} 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_config/tasks/main.yaml b/tests/integration/targets/vyos_config/tasks/main.yaml index 13977a4..8d10ebb 100644 --- a/tests/integration/targets/vyos_config/tasks/main.yaml +++ b/tests/integration/targets/vyos_config/tasks/main.yaml @@ -1,3 +1,8 @@ --- -- {include: cli.yaml, tags: ['cli']} -- {include: cli_config.yaml, tags: ['cli_config']} +- include: cli.yaml + tags: + - cli + +- include: cli_config.yaml + tags: + - cli_config diff --git a/tests/integration/targets/vyos_config/tests/cli/backup.yaml b/tests/integration/targets/vyos_config/tests/cli/backup.yaml index af6a772..ae59a0d 100644 --- a/tests/integration/targets/vyos_config/tests/cli/backup.yaml +++ b/tests/integration/targets/vyos_config/tests/cli/backup.yaml @@ -3,111 +3,111 @@ - name: collect any backup files find: - paths: "{{ role_path }}/backup" - pattern: "{{ inventory_hostname_short }}_config*" + paths: '{{ role_path }}/backup' + pattern: '{{ inventory_hostname_short }}_config*' register: backup_files connection: local - name: delete backup files file: - path: "{{ item.path }}" + path: '{{ item.path }}' state: absent - with_items: "{{backup_files.files|default([])}}" + with_items: '{{backup_files.files|default([])}}' - name: take configure backup + register: result vyos.vyos.vyos_config: backup: true - register: result - assert: that: - - "result.changed == true" + - result.changed == true - name: collect any backup files find: - paths: "{{ role_path }}/backup" - pattern: "{{ inventory_hostname_short }}_config*" + paths: '{{ role_path }}/backup' + pattern: '{{ inventory_hostname_short }}_config*' register: backup_files connection: local - assert: that: - - "backup_files.files is defined" + - backup_files.files is defined - name: delete configurable backup file path file: - path: "{{ item }}" + path: '{{ item }}' state: absent with_items: - - "{{ role_path }}/backup_test_dir/" - - "{{ role_path }}/backup/backup.cfg" + - '{{ role_path }}/backup_test_dir/' + - '{{ role_path }}/backup/backup.cfg' - name: take configuration backup in custom filename and directory path + become: true + register: result vyos.vyos.vyos_config: backup: true backup_options: filename: backup.cfg - dir_path: "{{ role_path }}/backup_test_dir/{{ inventory_hostname_short }}" - become: true - register: result + dir_path: '{{ role_path }}/backup_test_dir/{{ inventory_hostname_short }}' - assert: that: - - "result.changed == true" + - result.changed == true - name: check if the backup file-1 exist find: - paths: "{{ role_path }}/backup_test_dir/{{ inventory_hostname_short }}/backup.cfg" + paths: '{{ role_path }}/backup_test_dir/{{ inventory_hostname_short }}/backup.cfg' register: backup_file connection: local - assert: that: - - "backup_file.files is defined" + - backup_file.files is defined - name: take configuration backup in custom filename + become: true + register: result vyos.vyos.vyos_config: backup: true backup_options: filename: backup.cfg - become: true - register: result - assert: that: - - "result.changed == true" + - result.changed == true - name: check if the backup file-2 exist find: - paths: "{{ role_path }}/backup/backup.cfg" + paths: '{{ role_path }}/backup/backup.cfg' register: backup_file connection: local - assert: that: - - "backup_file.files is defined" + - backup_file.files is defined - name: take configuration backup in custom path and default filename + become: true + register: result vyos.vyos.vyos_config: backup: true backup_options: - dir_path: "{{ role_path }}/backup_test_dir/{{ inventory_hostname_short }}" - become: true - register: result + dir_path: '{{ role_path }}/backup_test_dir/{{ inventory_hostname_short }}' - assert: that: - - "result.changed == true" + - result.changed == true - name: check if the backup file-3 exist find: - paths: "{{ role_path }}/backup_test_dir/{{ inventory_hostname_short }}" - pattern: "{{ inventory_hostname_short }}_config*" + paths: '{{ role_path }}/backup_test_dir/{{ inventory_hostname_short }}' + pattern: '{{ inventory_hostname_short }}_config*' register: backup_file connection: local - assert: that: - - "backup_file.files is defined" + - backup_file.files is defined - debug: msg="END vyos/backup.yaml on connection={{ ansible_connection }}" diff --git a/tests/integration/targets/vyos_config/tests/cli/check_config.yaml b/tests/integration/targets/vyos_config/tests/cli/check_config.yaml index f1ddc71..4300c10 100644 --- a/tests/integration/targets/vyos_config/tests/cli/check_config.yaml +++ b/tests/integration/targets/vyos_config/tests/cli/check_config.yaml @@ -6,58 +6,52 @@ lines: delete interfaces loopback lo - name: setup- create interface + register: result vyos.vyos.vyos_config: lines: - interfaces - interfaces loopback lo - interfaces loopback lo description test - register: result - -# note collapsing the duplicate lines doesn't work if -# lines: -# - interfaces loopback lo description test -# - interfaces loopback lo -# - interfaces - name: Check that multiple duplicate lines collapse into a single commands assert: that: - - "{{ result.commands|length }} == 1" + - '{{ result.commands|length }} == 1' - name: Check that set is correctly prepended assert: that: - - "result.commands[0] == 'set interfaces loopback lo description test'" + - result.commands[0] == 'set interfaces loopback lo description test' - name: configure config_check config command + register: result vyos.vyos.vyos_config: lines: delete interfaces loopback lo - register: result - assert: that: - - "result.changed == true" + - result.changed == true - name: check config_check config command idempontent + register: result vyos.vyos.vyos_config: lines: delete interfaces loopback lo - register: result - assert: that: - - "result.changed == false" + - result.changed == false - name: check multiple line config filter is working + register: result vyos.vyos.vyos_config: lines: - set system login user esa level admin - set system login user esa authentication encrypted-password '!abc!' - set system login user vyos level admin - set system login user vyos authentication encrypted-password 'abc' - register: result - assert: that: - - "{{ result.filtered|length }} == 2" + - '{{ result.filtered|length }} == 2' - debug: msg="END cli/config_check.yaml on connection={{ ansible_connection }}" diff --git a/tests/integration/targets/vyos_config/tests/cli/comment.yaml b/tests/integration/targets/vyos_config/tests/cli/comment.yaml index 2cd1350..3032585 100644 --- a/tests/integration/targets/vyos_config/tests/cli/comment.yaml +++ b/tests/integration/targets/vyos_config/tests/cli/comment.yaml @@ -7,20 +7,20 @@ match: none - name: configure using comment + register: result vyos.vyos.vyos_config: lines: set system host-name foo comment: this is a test - register: result - assert: that: - - "result.changed == true" + - result.changed == true - "'set system host-name foo' in result.commands" - name: collect system commits + register: result vyos.vyos.vyos_command: commands: show system commit - register: result - assert: that: diff --git a/tests/integration/targets/vyos_config/tests/cli/config.cfg b/tests/integration/targets/vyos_config/tests/cli/config.cfg new file mode 100644 index 0000000..36c98f1 --- /dev/null +++ b/tests/integration/targets/vyos_config/tests/cli/config.cfg @@ -0,0 +1,3 @@ + set service lldp + set protocols static + diff --git a/tests/integration/targets/vyos_config/tests/cli/save.yaml b/tests/integration/targets/vyos_config/tests/cli/save.yaml index d8e45e2..e8a9035 100644 --- a/tests/integration/targets/vyos_config/tests/cli/save.yaml +++ b/tests/integration/targets/vyos_config/tests/cli/save.yaml @@ -7,43 +7,43 @@ match: none - name: configure hostaname and save + register: result vyos.vyos.vyos_config: lines: set system host-name foo save: true - register: result - assert: that: - - "result.changed == true" + - result.changed == true - "'set system host-name foo' in result.commands" - name: configure hostaname and don't save + register: result vyos.vyos.vyos_config: lines: set system host-name bar - register: result - assert: that: - - "result.changed == true" + - result.changed == true - "'set system host-name bar' in result.commands" - name: save config + register: result vyos.vyos.vyos_config: save: true - register: result - assert: that: - - "result.changed == true" + - result.changed == true - name: save config again + register: result vyos.vyos.vyos_config: save: true - register: result - assert: that: - - "result.changed == false" + - result.changed == false - name: teardown vyos.vyos.vyos_config: diff --git a/tests/integration/targets/vyos_config/tests/cli/simple.yaml b/tests/integration/targets/vyos_config/tests/cli/simple.yaml index af211f5..4e2db4e 100644 --- a/tests/integration/targets/vyos_config/tests/cli/simple.yaml +++ b/tests/integration/targets/vyos_config/tests/cli/simple.yaml @@ -7,23 +7,43 @@ match: none - name: configure simple config command + register: result vyos.vyos.vyos_config: lines: set system host-name foo - register: result - assert: that: - - "result.changed == true" + - result.changed == true - "'set system host-name foo' in result.commands" - name: check simple config command idempontent + register: result vyos.vyos.vyos_config: lines: set system host-name foo + +- assert: + that: + - result.changed == false + +- name: Delete services + vyos.vyos.vyos_config: &id001 + lines: + - delete service lldp + - delete protocols static + +- name: Configuring when commands starts with whitespaces register: result + vyos.vyos.vyos_config: + src: '{{ role_path }}/tests/cli/config.cfg' - assert: that: - - "result.changed == false" + - result.changed == true + - '"set service lldp" in result.commands' + - '"set protocols static" in result.commands' + +- name: Delete services + vyos.vyos.vyos_config: *id001 - name: teardown vyos.vyos.vyos_config: diff --git a/tests/integration/targets/vyos_config/tests/cli_config/cli_backup.yaml b/tests/integration/targets/vyos_config/tests/cli_config/cli_backup.yaml index a573d6c..3880a04 100644 --- a/tests/integration/targets/vyos_config/tests/cli_config/cli_backup.yaml +++ b/tests/integration/targets/vyos_config/tests/cli_config/cli_backup.yaml @@ -3,112 +3,112 @@ - name: delete configurable backup file path file: - path: "{{ item }}" + path: '{{ item }}' state: absent with_items: - - "{{ role_path }}/backup_test_dir/" - - "{{ role_path }}/backup/backup.cfg" + - '{{ role_path }}/backup_test_dir/' + - '{{ role_path }}/backup/backup.cfg' - name: collect any backup files find: - paths: "{{ role_path }}/backup" - pattern: "{{ inventory_hostname_short }}_config*" + paths: '{{ role_path }}/backup' + pattern: '{{ inventory_hostname_short }}_config*' register: backup_files connection: local - name: delete backup files file: - path: "{{ item.path }}" + path: '{{ item.path }}' state: absent - with_items: "{{backup_files.files|default([])}}" + with_items: '{{backup_files.files|default([])}}' - name: take config backup - network.cli.cli_config: - backup: true become: true register: result + ansible.netcommon.cli_config: + backup: true - assert: that: - - "result.changed == true" + - result.changed == true - name: collect any backup files find: - paths: "{{ role_path }}/backup" - pattern: "{{ inventory_hostname_short }}_config*" + paths: '{{ role_path }}/backup' + pattern: '{{ inventory_hostname_short }}_config*' register: backup_files connection: local - assert: that: - - "backup_files.files is defined" + - backup_files.files is defined - name: take configuration backup in custom filename and directory path - network.cli.cli_config: + become: true + register: result + ansible.netcommon.cli_config: backup: true backup_options: filename: backup.cfg - dir_path: "{{ role_path }}/backup_test_dir/{{ inventory_hostname_short }}" - become: true - register: result + dir_path: '{{ role_path }}/backup_test_dir/{{ inventory_hostname_short }}' - assert: that: - - "result.changed == true" + - result.changed == true - name: check if the backup file-1 exist find: - paths: "{{ role_path }}/backup_test_dir/{{ inventory_hostname_short }}/backup.cfg" + paths: '{{ role_path }}/backup_test_dir/{{ inventory_hostname_short }}/backup.cfg' register: backup_file connection: local - assert: that: - - "backup_file.files is defined" + - backup_file.files is defined - name: take configuration backup in custom filename - network.cli.cli_config: + become: true + register: result + ansible.netcommon.cli_config: backup: true backup_options: filename: backup.cfg - become: true - register: result - assert: that: - - "result.changed == true" + - result.changed == true - name: check if the backup file-2 exist find: - paths: "{{ role_path }}/backup/backup.cfg" + paths: '{{ role_path }}/backup/backup.cfg' register: backup_file connection: local - assert: that: - - "backup_file.files is defined" + - backup_file.files is defined - name: take configuration backup in custom path and default filename - network.cli.cli_config: - backup: true - backup_options: - dir_path: "{{ role_path }}/backup_test_dir/{{ inventory_hostname_short }}" become: true register: result + ansible.netcommon.cli_config: + backup: true + backup_options: + dir_path: '{{ role_path }}/backup_test_dir/{{ inventory_hostname_short }}' - assert: that: - - "result.changed == true" + - result.changed == true - name: check if the backup file-3 exist find: - paths: "{{ role_path }}/backup_test_dir/{{ inventory_hostname_short }}" - pattern: "{{ inventory_hostname_short }}_config*" + paths: '{{ role_path }}/backup_test_dir/{{ inventory_hostname_short }}' + pattern: '{{ inventory_hostname_short }}_config*' register: backup_file connection: local - assert: that: - - "backup_file.files is defined" + - backup_file.files is defined - debug: msg="END cli_config/backup.yaml on connection={{ ansible_connection }}" diff --git a/tests/integration/targets/vyos_config/tests/cli_config/cli_basic.yaml b/tests/integration/targets/vyos_config/tests/cli_config/cli_basic.yaml index e5e3edb..6b71144 100644 --- a/tests/integration/targets/vyos_config/tests/cli_config/cli_basic.yaml +++ b/tests/integration/targets/vyos_config/tests/cli_config/cli_basic.yaml @@ -1,28 +1,30 @@ --- -- debug: msg="START cli_config/cli_basic.yaml on connection={{ ansible_connection }}" +- debug: msg="START cli_config/cli_basic.yaml on connection={{ ansible_connection + }}" - name: setup - remove interface description - network.cli.cli_config: &rm + ansible.netcommon.cli_config: &id002 config: delete interfaces loopback lo description - name: configure device with config - network.cli.cli_config: &conf - config: set interfaces loopback lo description 'this is a test' register: result + ansible.netcommon.cli_config: &id001 + config: set interfaces loopback lo description 'this is a test' - assert: that: - - "result.changed == true" + - result.changed == true - name: Idempotence - network.cli.cli_config: *conf register: result + ansible.netcommon.cli_config: *id001 - assert: that: - - "result.changed == false" + - result.changed == false - name: teardown - network.cli.cli_config: *rm + ansible.netcommon.cli_config: *id002 -- debug: msg="END cli_config/cli_basic.yaml on connection={{ ansible_connection }}" +- debug: msg="END cli_config/cli_basic.yaml on connection={{ ansible_connection + }}" diff --git a/tests/integration/targets/vyos_config/tests/cli_config/cli_comment.yaml b/tests/integration/targets/vyos_config/tests/cli_config/cli_comment.yaml index ecc9e8c..030b75d 100644 --- a/tests/integration/targets/vyos_config/tests/cli_config/cli_comment.yaml +++ b/tests/integration/targets/vyos_config/tests/cli_config/cli_comment.yaml @@ -1,30 +1,32 @@ --- -- debug: msg="START cli_config/cli_comment.yaml on connection={{ ansible_connection }}" +- debug: msg="START cli_config/cli_comment.yaml on connection={{ ansible_connection + }}" - name: setup - network.cli.cli_config: &rm + ansible.netcommon.cli_config: &id001 config: set system host-name {{ inventory_hostname_short }} - name: configure using comment - network.cli.cli_config: + register: result + ansible.netcommon.cli_config: config: set system host-name foo commit_comment: this is a test - register: result - assert: that: - - "result.changed == true" + - result.changed == true - name: collect system commits + register: result vyos.vyos.vyos_command: commands: show system commit - register: result - assert: that: - "'this is a test' in result.stdout_lines[0][1]" - name: teardown - network.cli.cli_config: *rm + ansible.netcommon.cli_config: *id001 -- debug: msg="END cli_config/cli_comment.yaml on connection={{ ansible_connection }}" +- debug: msg="END cli_config/cli_comment.yaml on connection={{ ansible_connection + }}" diff --git a/tests/integration/targets/vyos_facts/defaults/main.yaml b/tests/integration/targets/vyos_facts/defaults/main.yaml index 9ef5ba5..a845c24 100644 --- a/tests/integration/targets/vyos_facts/defaults/main.yaml +++ b/tests/integration/targets/vyos_facts/defaults/main.yaml @@ -1,3 +1,3 @@ --- -testcase: "*" +testcase: '*' test_items: [] diff --git a/tests/integration/targets/vyos_facts/tasks/cli.yaml b/tests/integration/targets/vyos_facts/tasks/cli.yaml index 890d3ac..90f265f 100644 --- a/tests/integration/targets/vyos_facts/tasks/cli.yaml +++ b/tests/integration/targets/vyos_facts/tasks/cli.yaml @@ -1,22 +1,22 @@ --- - name: collect all cli test cases find: - paths: "{{ role_path }}/tests/cli" - patterns: "{{ testcase }}.yaml" + paths: '{{ role_path }}/tests/cli' + patterns: '{{ testcase }}.yaml' 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 }} ansible_connection=network_cli" - with_items: "{{ test_items }}" +- name: run test case (connection=ansible.netcommon.network_cli) + include: '{{ test_case_to_run }} ansible_connection=ansible.netcommon.network_cli' + with_items: '{{ test_items }}' loop_control: loop_var: test_case_to_run - name: run test case (connection=local) - include: "{{ test_case_to_run }} ansible_connection=local" - with_first_found: "{{ test_items }}" + include: '{{ test_case_to_run }} ansible_connection=local' + with_first_found: '{{ test_items }}' loop_control: loop_var: test_case_to_run diff --git a/tests/integration/targets/vyos_facts/tasks/main.yaml b/tests/integration/targets/vyos_facts/tasks/main.yaml index d4cf26f..a3db933 100644 --- a/tests/integration/targets/vyos_facts/tasks/main.yaml +++ b/tests/integration/targets/vyos_facts/tasks/main.yaml @@ -1,2 +1,4 @@ --- -- {include: cli.yaml, tags: ['cli']} +- include: cli.yaml + tags: + - cli diff --git a/tests/integration/targets/vyos_facts/tests/cli/basic_facts.yaml b/tests/integration/targets/vyos_facts/tests/cli/basic_facts.yaml index 33382ea..5802f73 100644 --- a/tests/integration/targets/vyos_facts/tests/cli/basic_facts.yaml +++ b/tests/integration/targets/vyos_facts/tests/cli/basic_facts.yaml @@ -1,46 +1,42 @@ --- - name: get host name + register: vyos_host vyos.vyos.vyos_command: commands: - show host name - register: vyos_host - name: get version info + register: vyos_version vyos.vyos.vyos_command: commands: - show version - register: vyos_version - name: collect all facts from the device + register: result vyos.vyos.vyos_facts: gather_subset: all - register: result -- name: "check that hostname is present" +- name: check that hostname is present assert: that: - # hostname - result.ansible_facts.ansible_net_hostname == vyos_host.stdout[0] -- name: "check that subsets are present" +- name: check that subsets are present assert: that: - # subsets - "'neighbors' in result.ansible_facts.ansible_net_gather_subset" - "'default' in result.ansible_facts.ansible_net_gather_subset" - "'config' in result.ansible_facts.ansible_net_gather_subset" -- name: "check that version info is present" +- name: check that version info is present assert: that: - # version info - result.ansible_facts.ansible_net_version in vyos_version.stdout_lines[0][0] - result.ansible_facts.ansible_net_model in vyos_version.stdout_lines[0][9] - result.ansible_facts.ansible_net_serialnum in vyos_version.stdout_lines[0][10] -- name: "check that config info is present" +- name: check that config info is present assert: that: - # config info - result.ansible_facts.ansible_net_commits is defined - result.ansible_facts.ansible_net_config is defined diff --git a/tests/integration/targets/vyos_interface/defaults/main.yaml b/tests/integration/targets/vyos_interface/defaults/main.yaml index 9ef5ba5..a845c24 100644 --- a/tests/integration/targets/vyos_interface/defaults/main.yaml +++ b/tests/integration/targets/vyos_interface/defaults/main.yaml @@ -1,3 +1,3 @@ --- -testcase: "*" +testcase: '*' test_items: [] diff --git a/tests/integration/targets/vyos_interface/tasks/cli.yaml b/tests/integration/targets/vyos_interface/tasks/cli.yaml index 890d3ac..90f265f 100644 --- a/tests/integration/targets/vyos_interface/tasks/cli.yaml +++ b/tests/integration/targets/vyos_interface/tasks/cli.yaml @@ -1,22 +1,22 @@ --- - name: collect all cli test cases find: - paths: "{{ role_path }}/tests/cli" - patterns: "{{ testcase }}.yaml" + paths: '{{ role_path }}/tests/cli' + patterns: '{{ testcase }}.yaml' 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 }} ansible_connection=network_cli" - with_items: "{{ test_items }}" +- name: run test case (connection=ansible.netcommon.network_cli) + include: '{{ test_case_to_run }} ansible_connection=ansible.netcommon.network_cli' + with_items: '{{ test_items }}' loop_control: loop_var: test_case_to_run - name: run test case (connection=local) - include: "{{ test_case_to_run }} ansible_connection=local" - with_first_found: "{{ test_items }}" + include: '{{ test_case_to_run }} ansible_connection=local' + with_first_found: '{{ test_items }}' loop_control: loop_var: test_case_to_run diff --git a/tests/integration/targets/vyos_interface/tasks/main.yaml b/tests/integration/targets/vyos_interface/tasks/main.yaml index d4cf26f..a3db933 100644 --- a/tests/integration/targets/vyos_interface/tasks/main.yaml +++ b/tests/integration/targets/vyos_interface/tasks/main.yaml @@ -1,2 +1,4 @@ --- -- {include: cli.yaml, tags: ['cli']} +- include: cli.yaml + tags: + - cli diff --git a/tests/integration/targets/vyos_interface/tests/cli/basic.yaml b/tests/integration/targets/vyos_interface/tests/cli/basic.yaml index 168d666..b50d7da 100644 --- a/tests/integration/targets/vyos_interface/tests/cli/basic.yaml +++ b/tests/integration/targets/vyos_interface/tests/cli/basic.yaml @@ -2,10 +2,10 @@ - debug: msg="START cli/basic.yaml on connection={{ ansible_connection }}" - name: Run vyos lsmod command + register: lsmod_out vyos.vyos.vyos_command: commands: - lsmod - register: lsmod_out - name: Set up - delete interface vyos.vyos.vyos_interface: @@ -13,19 +13,21 @@ state: absent - name: Set up - Create interface + register: result vyos.vyos.vyos_interface: name: eth1 state: present description: test-interface - register: result - assert: that: - - 'result.changed == true' + - result.changed == true - '"set interfaces ethernet eth1" in result.commands' - - '"set interfaces ethernet eth1 description ''test-interface''" in result.commands' + - "\"set interfaces ethernet eth1 description 'test-interface'\" in result.commands" - name: Configure interface params + when: "'virtio_net' not in lsmod_out.stdout[0]" + register: result vyos.vyos.vyos_interface: name: eth1 state: present @@ -33,19 +35,19 @@ speed: 100 duplex: half mtu: 256 - when: "'virtio_net' not in lsmod_out.stdout[0]" - register: result - assert: that: - - 'result.changed == true' - - '"set interfaces ethernet eth1 description ''test-interface-1''" in result.commands' + - result.changed == true + - "\"set interfaces ethernet eth1 description 'test-interface-1'\" in result.commands" - '"set interfaces ethernet eth1 speed 100" in result.commands' - '"set interfaces ethernet eth1 duplex half" in result.commands' - '"set interfaces ethernet eth1 mtu 256" in result.commands' when: "'virtio_net' not in lsmod_out.stdout[0]" - name: Configure interface params (idempotent) + register: result + when: "'virtio_net' not in lsmod_out.stdout[0]" vyos.vyos.vyos_interface: name: eth1 state: present @@ -53,15 +55,15 @@ speed: 100 duplex: half mtu: 256 - register: result - when: "'virtio_net' not in lsmod_out.stdout[0]" - assert: that: - - 'result.changed == false' + - result.changed == false when: "'virtio' not in lsmod_out.stdout[0]" - name: Change interface params + register: result + when: "'virtio_net' not in lsmod_out.stdout[0]" vyos.vyos.vyos_interface: name: eth1 state: present @@ -69,152 +71,178 @@ speed: 1000 duplex: full mtu: 512 - register: result - when: "'virtio_net' not in lsmod_out.stdout[0]" - assert: that: - - 'result.changed == true' - - '"set interfaces ethernet eth1 description ''test-interface-2''" in result.commands' + - result.changed == true + - "\"set interfaces ethernet eth1 description 'test-interface-2'\" in result.commands" - '"set interfaces ethernet eth1 speed 1000" in result.commands' - '"set interfaces ethernet eth1 duplex full" in result.commands' - '"set interfaces ethernet eth1 mtu 512" in result.commands' when: "'virtio_net' not in lsmod_out.stdout[0]" - name: Disable interface + register: result vyos.vyos.vyos_interface: name: eth1 enabled: false - register: result - assert: that: - - 'result.changed == true' + - result.changed == true - '"set interfaces ethernet eth1 disable" in result.commands' - name: Enable interface + register: result vyos.vyos.vyos_interface: name: eth1 enabled: true - register: result - assert: that: - - 'result.changed == true' + - result.changed == true - '"delete interfaces ethernet eth1 disable" in result.commands' - name: Delete interface + register: result vyos.vyos.vyos_interface: name: eth1 state: absent - register: result - assert: that: - - 'result.changed == true' + - result.changed == true - '"delete interfaces ethernet eth1" in result.commands' - name: Delete interface (idempotent) + register: result vyos.vyos.vyos_interface: name: eth1 state: absent - register: result - assert: that: - - 'result.changed == false' + - result.changed == false - name: Aggregate setup- delete interface + register: result vyos.vyos.vyos_interface: name: eth2 state: absent - register: result - name: Set interface on aggregate - vyos.vyos.vyos_interface: - aggregate: - - {name: eth1, description: test-interface-1, speed: 100, duplex: half, mtu: 512} - - {name: eth2, description: test-interface-2, speed: 1000, duplex: full, mtu: 256} register: result when: "'virtio_net' not in lsmod_out.stdout[0]" + vyos.vyos.vyos_interface: + aggregate: + + - name: eth1 + description: test-interface-1 + speed: 100 + duplex: half + mtu: 512 + + - name: eth2 + description: test-interface-2 + speed: 1000 + duplex: full + mtu: 256 - assert: that: - - 'result.changed == true' - - '"set interfaces ethernet eth1 description ''test-interface-1''" in result.commands' + - result.changed == true + - "\"set interfaces ethernet eth1 description 'test-interface-1'\" in result.commands" - '"set interfaces ethernet eth1 speed 100" in result.commands' - '"set interfaces ethernet eth1 duplex half" in result.commands' - '"set interfaces ethernet eth1 mtu 512" in result.commands' - - '"set interfaces ethernet eth2 description ''test-interface-2''" in result.commands' + - "\"set interfaces ethernet eth2 description 'test-interface-2'\" in result.commands" - '"set interfaces ethernet eth2 speed 1000" in result.commands' - '"set interfaces ethernet eth2 duplex full" in result.commands' - '"set interfaces ethernet eth2 mtu 256" in result.commands' when: "'virtio_net' not in lsmod_out.stdout[0]" - name: Set interface on aggregate (idempotent) - vyos.vyos.vyos_interface: - aggregate: - - {name: eth1, description: test-interface-1, speed: 100, duplex: half, mtu: 512} - - {name: eth2, description: test-interface-2, speed: 1000, duplex: full, mtu: 256} register: result when: "'virtio_net' not in lsmod_out.stdout[0]" + vyos.vyos.vyos_interface: + aggregate: + + - name: eth1 + description: test-interface-1 + speed: 100 + duplex: half + mtu: 512 + + - name: eth2 + description: test-interface-2 + speed: 1000 + duplex: full + mtu: 256 - assert: that: - - 'result.changed == false' + - result.changed == false when: "'virtio_net' not in lsmod_out.stdout[0]" - name: Disable interface on aggregate + register: result vyos.vyos.vyos_interface: aggregate: + - name: eth1 + - name: eth2 description: test-interface enabled: false - register: result - assert: that: - - 'result.changed == true' + - result.changed == true - '"set interfaces ethernet eth1 disable" in result.commands' - '"set interfaces ethernet eth2 disable" in result.commands' - name: Enable interface on aggregate + register: result vyos.vyos.vyos_interface: aggregate: + - name: eth1 + - name: eth2 enabled: true - register: result - assert: that: - - 'result.changed == true' + - result.changed == true - '"delete interfaces ethernet eth1 disable" in result.commands' - '"delete interfaces ethernet eth2 disable" in result.commands' - name: Delete interface aggregate + register: result vyos.vyos.vyos_interface: aggregate: + - name: eth1 + - name: eth2 state: absent - register: result - assert: that: - - 'result.changed == true' + - result.changed == true - '"delete interfaces ethernet eth1" in result.commands' - '"delete interfaces ethernet eth2" in result.commands' - name: Delete interface aggregate (idempotent) + register: result vyos.vyos.vyos_interface: aggregate: + - name: eth1 + - name: eth2 state: absent - register: result - assert: that: - - 'result.changed == false' + - result.changed == false diff --git a/tests/integration/targets/vyos_interface/tests/cli/intent.yaml b/tests/integration/targets/vyos_interface/tests/cli/intent.yaml index 1c14a7b..69ab779 100644 --- a/tests/integration/targets/vyos_interface/tests/cli/intent.yaml +++ b/tests/integration/targets/vyos_interface/tests/cli/intent.yaml @@ -1,157 +1,160 @@ --- - debug: msg="START cli/intent.yaml on connection={{ ansible_connection }}" -# To be able to run the lldp test we need to have a neighbor configured to talk to -# In DCI & Zuul we (currently) only spin up a single network VM, so we can't configure a neighbor -# In the future when we have multi-network-nodes running we can run these tests again -# https://github.com/ansible/ansible/issues/39667 - - name: Detect if we have existing lldp neighbors configured + register: neighbors_out vyos.vyos.vyos_command: commands: - show lldp neighbors detail - register: neighbors_out - name: Should we run lldp tests? set_fact: run_lldp_tests: "'PortDescr: eth0' in neighbors_out.stdout[0]" - name: Enable LLDP service + when: run_lldp_tests vyos.vyos.vyos_lldp: state: present - when: run_lldp_tests - name: Create LLDP configuration + when: run_lldp_tests vyos.vyos.vyos_lldp_interface: name: eth1 state: present - when: run_lldp_tests - name: Setup (interface is up) + register: result vyos.vyos.vyos_interface: name: eth1 enabled: true state: present - register: result - name: Check intent arguments + register: result vyos.vyos.vyos_interface: name: eth1 state: up - register: result - assert: that: - - "result.failed == false" + - result.failed == false - name: Check lldp neighbors intent arguments + when: run_lldp_tests + register: result vyos.vyos.vyos_interface: name: eth0 neighbors: + - port: eth0 - when: run_lldp_tests - register: result - assert: that: - - "result.failed == false" + - result.failed == false when: run_lldp_tests - name: Check intent arguments (failed condition) + ignore_errors: true + register: result vyos.vyos.vyos_interface: name: eth1 state: down - ignore_errors: true - register: result - assert: that: - - "result.failed == true" + - result.failed == true - "'state eq(down)' in result.failed_conditions" - name: Check lldp neighbors intent arguments (failed) + ignore_errors: true + when: run_lldp_tests + register: result vyos.vyos.vyos_interface: name: eth0 neighbors: + - port: dummy_port host: dummy_host - ignore_errors: true - when: run_lldp_tests - register: result - assert: that: - - "result.failed == true" + - result.failed == true - "'host dummy_host' in result.failed_conditions" - "'port dummy_port' in result.failed_conditions" when: run_lldp_tests - name: Config + intent + register: result vyos.vyos.vyos_interface: name: eth1 enabled: false state: down - register: result - assert: that: - - "result.failed == false" + - result.failed == false - name: Config + intent (fail) + ignore_errors: true + register: result vyos.vyos.vyos_interface: name: eth1 enabled: false state: up - ignore_errors: true - register: result - assert: that: - - "result.failed == true" + - result.failed == true - "'state eq(up)' in result.failed_conditions" - name: Aggregate config + intent (pass) + ignore_errors: true + register: result vyos.vyos.vyos_interface: aggregate: + - name: eth1 enabled: true state: up - ignore_errors: true - register: result - assert: that: - - "result.failed == false" + - result.failed == false - name: Check lldp neighbors intent aggregate arguments + when: run_lldp_tests + register: result vyos.vyos.vyos_interface: aggregate: + - name: eth0 neighbors: + - port: eth0 - when: run_lldp_tests - register: result - assert: that: - - "result.failed == false" + - result.failed == false when: run_lldp_tests - name: Check lldp neighbors intent aggregate arguments (failed) + ignore_errors: true + when: run_lldp_tests + register: result vyos.vyos.vyos_interface: aggregate: + - name: eth0 neighbors: + - port: eth0 + - port: dummy_port host: dummy_host - ignore_errors: true - when: run_lldp_tests - register: result - assert: that: - - "result.failed == true" + - result.failed == true - "'host dummy_host' in result.failed_conditions" - "'port dummy_port' in result.failed_conditions" when: run_lldp_tests diff --git a/tests/integration/targets/vyos_interface/tests/cli/net_interface.yaml b/tests/integration/targets/vyos_interface/tests/cli/net_interface.yaml index 4bdb6ec..045daa2 100644 --- a/tests/integration/targets/vyos_interface/tests/cli/net_interface.yaml +++ b/tests/integration/targets/vyos_interface/tests/cli/net_interface.yaml @@ -1,56 +1,55 @@ --- -- debug: msg="START vyos cli/net_interface.yaml on connection={{ ansible_connection }}" - -# Add minimal testcase to check args are passed correctly to -# implementation module and module run is successful. +- debug: msg="START vyos cli/net_interface.yaml on connection={{ ansible_connection + }}" - name: Run vyos lsmod command + register: lsmod_out vyos.vyos.vyos_command: commands: - lsmod - register: lsmod_out - name: Set up - delete interface - net_interface: + ansible.netcommon.net_interface: name: eth1 state: absent - name: Create interface using platform agnostic module - net_interface: + register: result + ansible.netcommon.net_interface: name: eth1 state: present description: test-interface - register: result - assert: that: - - 'result.changed == true' + - result.changed == true - '"set interfaces ethernet eth1" in result.commands' - - '"set interfaces ethernet eth1 description ''test-interface''" in result.commands' + - "\"set interfaces ethernet eth1 description 'test-interface'\" in result.commands" - name: Configure interface params using platform agnostic module - net_interface: + when: "'virtio_net' not in lsmod_out.stdout[0]" + register: result + ansible.netcommon.net_interface: name: eth1 state: present description: test-interface-1 speed: 100 duplex: half mtu: 256 - when: "'virtio_net' not in lsmod_out.stdout[0]" - register: result - assert: that: - - 'result.changed == true' - - '"set interfaces ethernet eth1 description ''test-interface-1''" in result.commands' + - result.changed == true + - "\"set interfaces ethernet eth1 description 'test-interface-1'\" in result.commands" - '"set interfaces ethernet eth1 speed 100" in result.commands' - '"set interfaces ethernet eth1 duplex half" in result.commands' - '"set interfaces ethernet eth1 mtu 256" in result.commands' when: "'virtio_net' not in lsmod_out.stdout[0]" - name: teardown - delete interface - net_interface: + ansible.netcommon.net_interface: name: eth1 state: absent -- debug: msg="END vyos cli/net_interface.yaml on connection={{ ansible_connection }}" +- debug: msg="END vyos cli/net_interface.yaml on connection={{ ansible_connection + }}" diff --git a/tests/integration/targets/vyos_interfaces/defaults/main.yaml b/tests/integration/targets/vyos_interfaces/defaults/main.yaml index 164afea..852a6be 100644 --- a/tests/integration/targets/vyos_interfaces/defaults/main.yaml +++ b/tests/integration/targets/vyos_interfaces/defaults/main.yaml @@ -1,3 +1,3 @@ --- -testcase: "[^_].*" +testcase: '[^_].*' test_items: [] diff --git a/tests/integration/targets/vyos_interfaces/tasks/cli.yaml b/tests/integration/targets/vyos_interfaces/tasks/cli.yaml index 655e51e..93eb2fe 100644 --- a/tests/integration/targets/vyos_interfaces/tasks/cli.yaml +++ b/tests/integration/targets/vyos_interfaces/tasks/cli.yaml @@ -1,8 +1,8 @@ --- - name: Collect all cli test cases find: - paths: "{{ role_path }}/tests/cli" - patterns: "{{ testcase }}.yaml" + paths: '{{ role_path }}/tests/cli' + patterns: '{{ testcase }}.yaml' use_regex: true register: test_cases delegate_to: localhost @@ -10,10 +10,10 @@ - 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 }}" +- name: Run test case (connection=ansible.netcommon.network_cli) + include: '{{ test_case_to_run }}' vars: - ansible_connection: network_cli - with_items: "{{ test_items }}" + 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_interfaces/tasks/main.yaml b/tests/integration/targets/vyos_interfaces/tasks/main.yaml index d4cf26f..a3db933 100644 --- a/tests/integration/targets/vyos_interfaces/tasks/main.yaml +++ b/tests/integration/targets/vyos_interfaces/tasks/main.yaml @@ -1,2 +1,4 @@ --- -- {include: cli.yaml, tags: ['cli']} +- include: cli.yaml + tags: + - cli diff --git a/tests/integration/targets/vyos_interfaces/tests/cli/_populate.yaml b/tests/integration/targets/vyos_interfaces/tests/cli/_populate.yaml index 4dd5f18..686236f 100644 --- a/tests/integration/targets/vyos_interfaces/tests/cli/_populate.yaml +++ b/tests/integration/targets/vyos_interfaces/tests/cli/_populate.yaml @@ -1,17 +1,15 @@ --- - name: Setup - network.cli.cli_config: - config: "{{ lines }}" vars: - lines: | - set interfaces ethernet "{{ intf }}" description 'Configured by Ansible' - set interfaces ethernet "{{ intf }}" speed 'auto' - set interfaces ethernet "{{ intf }}" duplex 'auto' - set interfaces ethernet "{{ intf }}" mtu '1500' - set interfaces ethernet "{{ intf }}" vif 200 - set interfaces ethernet "{{ intf }}" vif 200 description 'VIF - 200' + lines: "set interfaces ethernet \"{{ intf }}\" description 'Configured by Ansible'\n\ + set interfaces ethernet \"{{ intf }}\" speed 'auto'\nset interfaces ethernet\ + \ \"{{ intf }}\" duplex 'auto'\nset interfaces ethernet \"{{ intf }}\" mtu\ + \ '1500'\nset interfaces ethernet \"{{ intf }}\" vif 200\nset interfaces ethernet\ + \ \"{{ intf }}\" vif 200 description 'VIF - 200'\n" loop: - eth1 - eth2 loop_control: loop_var: intf + ansible.netcommon.cli_config: + config: '{{ lines }}' diff --git a/tests/integration/targets/vyos_interfaces/tests/cli/_remove_config.yaml b/tests/integration/targets/vyos_interfaces/tests/cli/_remove_config.yaml index 9157f55..298cf5d 100644 --- a/tests/integration/targets/vyos_interfaces/tests/cli/_remove_config.yaml +++ b/tests/integration/targets/vyos_interfaces/tests/cli/_remove_config.yaml @@ -1,17 +1,15 @@ --- - name: Remove Config - network.cli.cli_config: - config: "{{ lines }}" vars: - lines: | - delete interfaces ethernet "{{ intf }}" description - delete interfaces ethernet "{{ intf }}" speed - delete interfaces ethernet "{{ intf }}" duplex - delete interfaces ethernet "{{ intf }}" mtu - delete interfaces ethernet "{{ intf }}" disable - delete interfaces ethernet "{{ intf }}" vif + lines: "delete interfaces ethernet \"{{ intf }}\" description\ndelete interfaces\ + \ ethernet \"{{ intf }}\" speed\ndelete interfaces ethernet \"{{ intf }}\"\ + \ duplex\ndelete interfaces ethernet \"{{ intf }}\" mtu\ndelete interfaces\ + \ ethernet \"{{ intf }}\" disable\ndelete interfaces ethernet \"{{ intf }}\"\ + \ vif\n" loop: - eth1 - eth2 loop_control: loop_var: intf + ansible.netcommon.cli_config: + config: '{{ lines }}' diff --git a/tests/integration/targets/vyos_interfaces/tests/cli/deleted.yaml b/tests/integration/targets/vyos_interfaces/tests/cli/deleted.yaml index fc86ca7..56e747a 100644 --- a/tests/integration/targets/vyos_interfaces/tests/cli/deleted.yaml +++ b/tests/integration/targets/vyos_interfaces/tests/cli/deleted.yaml @@ -1,17 +1,21 @@ --- - debug: - msg: "Start vyos_interfaces deleted integration tests ansible_connection={{ ansible_connection }}" + msg: Start vyos_interfaces deleted integration tests ansible_connection={{ ansible_connection + }} - include_tasks: _populate.yaml - block: + - name: Delete attributes of given interfaces - vyos.vyos.vyos_interfaces: &deleted + register: result + vyos.vyos.vyos_interfaces: &id001 config: + - name: eth1 + - name: eth2 state: deleted - register: result - name: Assert that the before dicts were correctly generated assert: @@ -21,26 +25,29 @@ - name: Assert that the correct set of commands were generated assert: that: - - "{{ deleted['commands'] | symmetric_difference(result['commands']) |length == 0 }}" + - "{{ 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 }}" + - "{{ deleted['after'] | symmetric_difference(result['after']) |length\ + \ == 0 }}" - name: Delete attributes of given interfaces (IDEMPOTENT) - vyos.vyos.vyos_interfaces: *deleted register: result + vyos.vyos.vyos_interfaces: *id001 - name: Assert that the previous task was idempotent assert: that: - - "result.changed == false" + - result.changed == false - name: Assert that the before dicts were correctly generated assert: that: - - "{{ deleted['after'] | symmetric_difference(result['before']) |length == 0 }}" - + - "{{ deleted['after'] | symmetric_difference(result['before']) |length\ + \ == 0 }}" always: + - include_tasks: _remove_config.yaml diff --git a/tests/integration/targets/vyos_interfaces/tests/cli/empty_config.yaml b/tests/integration/targets/vyos_interfaces/tests/cli/empty_config.yaml index 4a72c8a..e1e154d 100644 --- a/tests/integration/targets/vyos_interfaces/tests/cli/empty_config.yaml +++ b/tests/integration/targets/vyos_interfaces/tests/cli/empty_config.yaml @@ -1,35 +1,36 @@ --- - debug: - msg: "START vyos_interfaces empty_config integration tests on connection={{ ansible_connection }}" + msg: START vyos_interfaces empty_config integration tests on connection={{ ansible_connection + }} - name: Merged with empty config should give appropriate error message + register: result + ignore_errors: true vyos.vyos.vyos_interfaces: config: state: merged - register: result - ignore_errors: true - 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_interfaces: config: state: replaced - register: result - ignore_errors: true - assert: that: - result.msg == 'value of config parameter must not be empty for state replaced' - name: Overridden with empty config should give appropriate error message + register: result + ignore_errors: true vyos.vyos.vyos_interfaces: config: state: overridden - register: result - ignore_errors: true - assert: that: diff --git a/tests/integration/targets/vyos_interfaces/tests/cli/merged.yaml b/tests/integration/targets/vyos_interfaces/tests/cli/merged.yaml index 50e4936..e0fa0b9 100644 --- a/tests/integration/targets/vyos_interfaces/tests/cli/merged.yaml +++ b/tests/integration/targets/vyos_interfaces/tests/cli/merged.yaml @@ -1,59 +1,69 @@ --- - debug: - msg: "START vyos_interfaces merged integration tests on connection={{ ansible_connection }}" + msg: START vyos_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_interfaces: &merged + register: result + vyos.vyos.vyos_interfaces: &id001 config: + - name: eth1 - description: "Configured by Ansible - Interface 1" + description: Configured by Ansible - Interface 1 mtu: 1500 speed: auto duplex: auto vifs: + - vlan_id: 100 - description: "Eth1 - VIF 100" + description: Eth1 - VIF 100 mtu: 400 - vlan_id: 101 - description: "Eth1 - VIF 101" + description: Eth1 - VIF 101 - name: eth2 - description: "Configured by Ansible - Interface 2 (ADMIN DOWN)" + description: Configured by Ansible - Interface 2 (ADMIN DOWN) mtu: 600 enabled: false state: merged - register: result - name: Assert that before dicts were correctly generated assert: - that: "{{ merged['before'] | symmetric_difference(result['before']) |length == 0 }}" + 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 }}" + - "{{ 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 }}" + - "{{ merged['after'] | symmetric_difference(result['after']) |length\ + \ == 0 }}" - - name: Merge the provided configuration with the existing running configuration (IDEMPOTENT) - vyos.vyos.vyos_interfaces: *merged + - name: Merge the provided configuration with the existing running configuration + (IDEMPOTENT) register: result + vyos.vyos.vyos_interfaces: *id001 - name: Assert that the previous task was idempotent assert: that: - - "result['changed'] == false" + - result['changed'] == false - name: Assert that before dicts were correctly generated assert: that: - - "{{ merged['after'] | symmetric_difference(result['before']) |length == 0 }}" + - "{{ merged['after'] | symmetric_difference(result['before']) |length\ + \ == 0 }}" always: + - include_tasks: _remove_config.yaml diff --git a/tests/integration/targets/vyos_interfaces/tests/cli/overridden.yaml b/tests/integration/targets/vyos_interfaces/tests/cli/overridden.yaml index 74669f7..9921e5d 100644 --- a/tests/integration/targets/vyos_interfaces/tests/cli/overridden.yaml +++ b/tests/integration/targets/vyos_interfaces/tests/cli/overridden.yaml @@ -1,23 +1,27 @@ --- - debug: - msg: "START vyos_interfaces overridden integration tests on connection={{ ansible_connection }}" + msg: START vyos_interfaces overridden integration tests on connection={{ ansible_connection + }} - include_tasks: _remove_config.yaml - include_tasks: _populate.yaml - block: + - name: Overrides all device configuration with provided configuration - vyos.vyos.vyos_interfaces: &overridden + register: result + vyos.vyos.vyos_interfaces: &id001 config: + - name: eth0 - speed: "auto" - duplex: "auto" + speed: auto + duplex: auto + - name: eth2 - description: "Overridden by Ansible" + description: Overridden by Ansible mtu: 1200 state: overridden - register: result - name: Assert that before dicts were correctly generated assert: @@ -27,26 +31,29 @@ - name: Assert that correct commands were generated assert: that: - - "{{ overridden['commands'] | symmetric_difference(result['commands']) |length == 0 }}" + - "{{ 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 }}" + - "{{ overridden['after'] | symmetric_difference(result['after']) |length\ + \ == 0 }}" - name: Overrides all device configuration with provided configurations (IDEMPOTENT) - vyos.vyos.vyos_interfaces: *overridden register: result + vyos.vyos.vyos_interfaces: *id001 - name: Assert that the previous task was idempotent assert: that: - - "result['changed'] == false" + - result['changed'] == false - name: Assert that before dicts were correctly generated assert: that: - - "{{ overridden['after'] | symmetric_difference(result['before']) |length == 0 }}" - + - "{{ overridden['after'] | symmetric_difference(result['before']) |length\ + \ == 0 }}" always: + - include_tasks: _remove_config.yaml diff --git a/tests/integration/targets/vyos_interfaces/tests/cli/replaced.yaml b/tests/integration/targets/vyos_interfaces/tests/cli/replaced.yaml index 64510d7..8b68c5a 100644 --- a/tests/integration/targets/vyos_interfaces/tests/cli/replaced.yaml +++ b/tests/integration/targets/vyos_interfaces/tests/cli/replaced.yaml @@ -1,31 +1,36 @@ --- - debug: - msg: "START vyos_interfaces replaced integration tests on connection={{ ansible_connection }}" + msg: START vyos_interfaces replaced integration tests on connection={{ ansible_connection + }} - include_tasks: _remove_config.yaml - include_tasks: _populate.yaml - block: + - name: Replace device configurations of listed interfaces with provided configurations - vyos.vyos.vyos_interfaces: &replaced + register: result + vyos.vyos.vyos_interfaces: &id001 config: + - name: eth1 - description: "Replaced by Ansible" + description: Replaced by Ansible vifs: + - vlan_id: 100 - description: "VIF 100 - Replaced by Ansible" + description: VIF 100 - Replaced by Ansible - name: eth2 mtu: 1400 - description: "Replaced by Ansible" + description: Replaced by Ansible state: replaced - register: result - name: Assert that correct set of commands were generated assert: that: - - "{{ replaced['commands'] | symmetric_difference(result['commands']) |length == 0 }}" + - "{{ replaced['commands'] | symmetric_difference(result['commands'])\ + \ |length == 0 }}" - name: Assert that before dicts are correctly generated assert: @@ -35,21 +40,24 @@ - name: Assert that after dict is correctly generated assert: that: - - "{{ replaced['after'] | symmetric_difference(result['after']) |length == 0 }}" + - "{{ replaced['after'] | symmetric_difference(result['after']) |length\ + \ == 0 }}" - - name: Replace device configurations of listed interfaces with provided configurarions (IDEMPOTENT) - vyos.vyos.vyos_interfaces: *replaced + - name: Replace device configurations of listed interfaces with provided configurarions + (IDEMPOTENT) register: result + vyos.vyos.vyos_interfaces: *id001 - name: Assert that task was idempotent assert: that: - - "result['changed'] == false" + - result['changed'] == false - name: Assert that before dict is correctly generated assert: that: - - "{{ replaced['after'] | symmetric_difference(result['before']) |length == 0 }}" - + - "{{ replaced['after'] | symmetric_difference(result['before']) |length\ + \ == 0 }}" always: + - include_tasks: _remove_config.yaml diff --git a/tests/integration/targets/vyos_interfaces/tests/cli/rtt.yaml b/tests/integration/targets/vyos_interfaces/tests/cli/rtt.yaml index f947513..f003c0b 100644 --- a/tests/integration/targets/vyos_interfaces/tests/cli/rtt.yaml +++ b/tests/integration/targets/vyos_interfaces/tests/cli/rtt.yaml @@ -1,35 +1,39 @@ --- - debug: - msg: "START vyos_interfaces round trip integration tests on connection={{ ansible_connection }}" + msg: START vyos_interfaces 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_interfaces: config: + - name: eth0 enabled: true - duplex: "auto" - speed: "auto" + duplex: auto + speed: auto - name: eth1 - description: "Interface - 1" + description: Interface - 1 mtu: 1500 vifs: + - vlan_id: 100 - description: "Eth1 - VIF 100" + description: Eth1 - VIF 100 mtu: 200 - vlan_id: 101 enabled: false - name: eth2 - description: "Interface - 2" + description: Interface - 2 enabled: true mtu: 900 state: merged - register: base_config - name: Gather interfaces facts vyos.vyos.vyos_facts: @@ -39,40 +43,44 @@ - interfaces - name: Apply the provided configuration (config to be reverted) + register: result vyos.vyos.vyos_interfaces: config: + - name: eth1 - description: "Interface 1 - Description (WILL BE REVERTED)" + description: Interface 1 - Description (WILL BE REVERTED) mtu: 1200 vifs: + - vlan_id: 100 - description: "Eth1 - VIF 100 (WILL BE REVERTED)" + description: Eth1 - VIF 100 (WILL BE REVERTED) mtu: 400 - vlan_id: 101 - description: "Eth1 - VIF 101 (WILL BE REMOVED)" + description: Eth1 - VIF 101 (WILL BE REMOVED) enabled: true - name: eth2 - description: "Interface 2 (ADMIN DOWN) (WILL BE REVERTED)" + description: Interface 2 (ADMIN DOWN) (WILL BE REVERTED) mtu: 600 enabled: false state: merged - register: result - name: Assert that changes were applied assert: - that: "{{ round_trip['after'] | symmetric_difference(result['after']) |length == 0 }}" + that: "{{ round_trip['after'] | symmetric_difference(result['after']) |length\ + \ == 0 }}" - name: Revert back to base config using facts round trip + register: revert vyos.vyos.vyos_interfaces: config: "{{ ansible_facts['network_resources']['interfaces'] }}" state: replaced - register: revert - name: Assert that config was reverted assert: - that: "{{ base_config['after'] | symmetric_difference(revert['after']) |length == 0 }}" - + that: "{{ base_config['after'] | symmetric_difference(revert['after']) |length\ + \ == 0 }}" always: + - include_tasks: _remove_config.yaml diff --git a/tests/integration/targets/vyos_interfaces/vars/main.yaml b/tests/integration/targets/vyos_interfaces/vars/main.yaml index b973752..b730080 100644 --- a/tests/integration/targets/vyos_interfaces/vars/main.yaml +++ b/tests/integration/targets/vyos_interfaces/vars/main.yaml @@ -1,209 +1,184 @@ --- merged: before: - - name: "eth0" + - name: eth0 enabled: true - speed: "auto" - duplex: "auto" - - - name: "eth1" + speed: auto + duplex: auto + - name: eth1 enabled: true - - - name: "eth2" + - name: eth2 enabled: true - commands: - - "set interfaces ethernet eth1 description 'Configured by Ansible - Interface 1'" - - "set interfaces ethernet eth1 mtu '1500'" - - "set interfaces ethernet eth1 duplex 'auto'" - - "set interfaces ethernet eth1 speed 'auto'" - - "set interfaces ethernet eth1 vif 100 description 'Eth1 - VIF 100'" - - "set interfaces ethernet eth1 vif 100 mtu '400'" - - "set interfaces ethernet eth1 vif 101 description 'Eth1 - VIF 101'" - - "set interfaces ethernet eth2 description 'Configured by Ansible - Interface 2 (ADMIN DOWN)'" - - "set interfaces ethernet eth2 mtu '600'" - - "set interfaces ethernet eth2 disable" - + - set interfaces ethernet eth1 description 'Configured by Ansible - Interface + 1' + - set interfaces ethernet eth1 mtu '1500' + - set interfaces ethernet eth1 duplex 'auto' + - set interfaces ethernet eth1 speed 'auto' + - set interfaces ethernet eth1 vif 100 description 'Eth1 - VIF 100' + - set interfaces ethernet eth1 vif 100 mtu '400' + - set interfaces ethernet eth1 vif 101 description 'Eth1 - VIF 101' + - set interfaces ethernet eth2 description 'Configured by Ansible - Interface + 2 (ADMIN DOWN)' + - set interfaces ethernet eth2 mtu '600' + - set interfaces ethernet eth2 disable after: - - name: "eth0" + - name: eth0 enabled: true - duplex: "auto" - speed: "auto" - - - name: "eth1" - description: "Configured by Ansible - Interface 1" + duplex: auto + speed: auto + - name: eth1 + description: Configured by Ansible - Interface 1 mtu: 1500 - speed: "auto" - duplex: "auto" + speed: auto + duplex: auto enabled: true vifs: - vlan_id: 100 - description: "Eth1 - VIF 100" + description: Eth1 - VIF 100 mtu: 400 enabled: true - - vlan_id: 101 - description: "Eth1 - VIF 101" + description: Eth1 - VIF 101 enabled: true - - - name: "eth2" - description: "Configured by Ansible - Interface 2 (ADMIN DOWN)" + - name: eth2 + description: Configured by Ansible - Interface 2 (ADMIN DOWN) mtu: 600 enabled: false - populate: - - name: "eth1" + - name: eth1 enabled: true - speed: "auto" - duplex: "auto" - description: "Configured by Ansible" + speed: auto + duplex: auto + description: Configured by Ansible mtu: 1500 vifs: - vlan_id: 200 enabled: true - description: "VIF - 200" - - - name: "eth2" + description: VIF - 200 + - name: eth2 enabled: true - speed: "auto" - duplex: "auto" - description: "Configured by Ansible" + speed: auto + duplex: auto + description: Configured by Ansible mtu: 1500 vifs: - vlan_id: 200 enabled: true - description: "VIF - 200" - - - name: "eth0" + description: VIF - 200 + - name: eth0 enabled: true - duplex: "auto" - speed: "auto" - + duplex: auto + speed: auto replaced: commands: - - "delete interfaces ethernet eth1 mtu" - - "delete interfaces ethernet eth1 speed" - - "delete interfaces ethernet eth1 duplex" - - "delete interfaces ethernet eth1 vif 200 description" - - "set interfaces ethernet eth1 description 'Replaced by Ansible'" - - "set interfaces ethernet eth1 vif 100 description 'VIF 100 - Replaced by Ansible'" - - "delete interfaces ethernet eth2 speed" - - "delete interfaces ethernet eth2 duplex" - - "delete interfaces ethernet eth2 vif 200 description" - - "set interfaces ethernet eth2 description 'Replaced by Ansible'" - - "set interfaces ethernet eth2 mtu '1400'" - + - delete interfaces ethernet eth1 mtu + - delete interfaces ethernet eth1 speed + - delete interfaces ethernet eth1 duplex + - delete interfaces ethernet eth1 vif 200 description + - set interfaces ethernet eth1 description 'Replaced by Ansible' + - set interfaces ethernet eth1 vif 100 description 'VIF 100 - Replaced by Ansible' + - delete interfaces ethernet eth2 speed + - delete interfaces ethernet eth2 duplex + - delete interfaces ethernet eth2 vif 200 description + - set interfaces ethernet eth2 description 'Replaced by Ansible' + - set interfaces ethernet eth2 mtu '1400' after: - - name: "eth1" - description: "Replaced by Ansible" + - name: eth1 + description: Replaced by Ansible enabled: true vifs: - vlan_id: 100 enabled: true - description: "VIF 100 - Replaced by Ansible" - + description: VIF 100 - Replaced by Ansible - vlan_id: 200 enabled: true - - - name: "eth2" + - name: eth2 mtu: 1400 - description: "Replaced by Ansible" + description: Replaced by Ansible enabled: true vifs: - vlan_id: 200 enabled: true - - - name: "eth0" + - name: eth0 enabled: true - duplex: "auto" - speed: "auto" - + duplex: auto + speed: auto overridden: commands: - - "delete interfaces ethernet eth1 description" - - "delete interfaces ethernet eth1 speed" - - "delete interfaces ethernet eth1 duplex" - - "delete interfaces ethernet eth1 mtu" - - "delete interfaces ethernet eth1 vif 200 description" - - "delete interfaces ethernet eth2 speed" - - "delete interfaces ethernet eth2 duplex" - - "delete interfaces ethernet eth2 vif 200 description" - - "set interfaces ethernet eth2 description 'Overridden by Ansible'" - - "set interfaces ethernet eth2 mtu '1200'" - + - delete interfaces ethernet eth1 description + - delete interfaces ethernet eth1 speed + - delete interfaces ethernet eth1 duplex + - delete interfaces ethernet eth1 mtu + - delete interfaces ethernet eth1 vif 200 description + - delete interfaces ethernet eth2 speed + - delete interfaces ethernet eth2 duplex + - delete interfaces ethernet eth2 vif 200 description + - set interfaces ethernet eth2 description 'Overridden by Ansible' + - set interfaces ethernet eth2 mtu '1200' after: - - name: "eth0" + - name: eth0 enabled: true - speed: "auto" - duplex: "auto" - - - name: "eth1" + speed: auto + duplex: auto + - name: eth1 enabled: true vifs: - vlan_id: 200 enabled: true - - - name: "eth2" + - name: eth2 enabled: true - description: "Overridden by Ansible" + description: Overridden by Ansible mtu: 1200 vifs: - vlan_id: 200 enabled: true - deleted: commands: - - "delete interfaces ethernet eth1 description" - - "delete interfaces ethernet eth1 speed" - - "delete interfaces ethernet eth1 duplex" - - "delete interfaces ethernet eth1 mtu" - - "delete interfaces ethernet eth1 vif 200 description" - - "delete interfaces ethernet eth2 description" - - "delete interfaces ethernet eth2 speed" - - "delete interfaces ethernet eth2 duplex" - - "delete interfaces ethernet eth2 mtu" - - "delete interfaces ethernet eth2 vif 200 description" - + - delete interfaces ethernet eth1 description + - delete interfaces ethernet eth1 speed + - delete interfaces ethernet eth1 duplex + - delete interfaces ethernet eth1 mtu + - delete interfaces ethernet eth1 vif 200 description + - delete interfaces ethernet eth2 description + - delete interfaces ethernet eth2 speed + - delete interfaces ethernet eth2 duplex + - delete interfaces ethernet eth2 mtu + - delete interfaces ethernet eth2 vif 200 description after: - - name: "eth0" + - name: eth0 enabled: true - speed: "auto" - duplex: "auto" - - - name: "eth1" + speed: auto + duplex: auto + - name: eth1 enabled: true vifs: - vlan_id: 200 enabled: true - - - name: "eth2" + - name: eth2 enabled: true vifs: - vlan_id: 200 enabled: true - round_trip: after: - - name: "eth0" + - name: eth0 enabled: true - speed: "auto" - duplex: "auto" - - - name: "eth1" - description: "Interface 1 - Description (WILL BE REVERTED)" + speed: auto + duplex: auto + - name: eth1 + description: Interface 1 - Description (WILL BE REVERTED) enabled: true mtu: 1200 vifs: - vlan_id: 100 - description: "Eth1 - VIF 100 (WILL BE REVERTED)" + description: Eth1 - VIF 100 (WILL BE REVERTED) mtu: 400 enabled: true - - vlan_id: 101 - description: "Eth1 - VIF 101 (WILL BE REMOVED)" + description: Eth1 - VIF 101 (WILL BE REMOVED) enabled: true - - - name: "eth2" - description: "Interface 2 (ADMIN DOWN) (WILL BE REVERTED)" + - name: eth2 + description: Interface 2 (ADMIN DOWN) (WILL BE REVERTED) mtu: 600 enabled: false diff --git a/tests/integration/targets/vyos_l3_interface/defaults/main.yaml b/tests/integration/targets/vyos_l3_interface/defaults/main.yaml index 9ef5ba5..a845c24 100644 --- a/tests/integration/targets/vyos_l3_interface/defaults/main.yaml +++ b/tests/integration/targets/vyos_l3_interface/defaults/main.yaml @@ -1,3 +1,3 @@ --- -testcase: "*" +testcase: '*' test_items: [] diff --git a/tests/integration/targets/vyos_l3_interface/tasks/cli.yaml b/tests/integration/targets/vyos_l3_interface/tasks/cli.yaml index 890d3ac..90f265f 100644 --- a/tests/integration/targets/vyos_l3_interface/tasks/cli.yaml +++ b/tests/integration/targets/vyos_l3_interface/tasks/cli.yaml @@ -1,22 +1,22 @@ --- - name: collect all cli test cases find: - paths: "{{ role_path }}/tests/cli" - patterns: "{{ testcase }}.yaml" + paths: '{{ role_path }}/tests/cli' + patterns: '{{ testcase }}.yaml' 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 }} ansible_connection=network_cli" - with_items: "{{ test_items }}" +- name: run test case (connection=ansible.netcommon.network_cli) + include: '{{ test_case_to_run }} ansible_connection=ansible.netcommon.network_cli' + with_items: '{{ test_items }}' loop_control: loop_var: test_case_to_run - name: run test case (connection=local) - include: "{{ test_case_to_run }} ansible_connection=local" - with_first_found: "{{ test_items }}" + include: '{{ test_case_to_run }} ansible_connection=local' + with_first_found: '{{ test_items }}' loop_control: loop_var: test_case_to_run diff --git a/tests/integration/targets/vyos_l3_interface/tasks/main.yaml b/tests/integration/targets/vyos_l3_interface/tasks/main.yaml index d4cf26f..a3db933 100644 --- a/tests/integration/targets/vyos_l3_interface/tasks/main.yaml +++ b/tests/integration/targets/vyos_l3_interface/tasks/main.yaml @@ -1,2 +1,4 @@ --- -- {include: cli.yaml, tags: ['cli']} +- include: cli.yaml + tags: + - cli diff --git a/tests/integration/targets/vyos_l3_interface/tests/cli/basic.yaml b/tests/integration/targets/vyos_l3_interface/tests/cli/basic.yaml index 3c24b11..2ffb1ab 100644 --- a/tests/integration/targets/vyos_l3_interface/tests/cli/basic.yaml +++ b/tests/integration/targets/vyos_l3_interface/tests/cli/basic.yaml @@ -12,192 +12,220 @@ state: absent - name: Set IPv4 address + register: result vyos.vyos.vyos_l3_interface: name: eth1 ipv4: 192.168.2.10/24 - register: result - assert: that: - - 'result.changed == true' + - result.changed == true - '"set interfaces ethernet eth1 address 192.168.2.10/24" in result.commands' - name: Set IPv4 address (idempotent) + register: result vyos.vyos.vyos_l3_interface: name: eth1 ipv4: 192.168.2.10/24 - register: result - assert: that: - - 'result.changed == false' + - result.changed == false - name: Set IPv6 address + register: result vyos.vyos.vyos_l3_interface: name: eth1 ipv6: fd5d:12c9:2201:1::1/64 - register: result - assert: that: - - 'result.changed == true' + - result.changed == true - '"set interfaces ethernet eth1 address fd5d:12c9:2201:1::1/64" in result.commands' - name: Set IPv6 address (idempotent) + register: result vyos.vyos.vyos_l3_interface: name: eth1 ipv6: fd5d:12c9:2201:1::1/64 - register: result - assert: that: - - 'result.changed == false' + - result.changed == false - name: Remove all IP addresses + register: result vyos.vyos.vyos_l3_interface: name: eth1 state: absent - register: result - assert: that: - - 'result.changed == true' + - result.changed == true - '"delete interfaces ethernet eth1 address" in result.commands' - name: Remove all IP addresses again (idempotent) + register: result vyos.vyos.vyos_l3_interface: name: eth1 state: absent - register: result - assert: that: - - 'result.changed == false' + - result.changed == false - name: Set IPv4 and IPv6 address + register: result vyos.vyos.vyos_l3_interface: name: eth1 ipv4: 192.168.2.10/24 ipv6: fd5d:12c9:2201:1::1/64 - register: result - assert: that: - - 'result.changed == true' + - result.changed == true - '"set interfaces ethernet eth1 address 192.168.2.10/24" in result.commands' - '"set interfaces ethernet eth1 address fd5d:12c9:2201:1::1/64" in result.commands' - name: Set IPv4 and IPv6 address again (idempotent) + register: result vyos.vyos.vyos_l3_interface: name: eth1 ipv4: 192.168.2.10/24 ipv6: fd5d:12c9:2201:1::1/64 - register: result - assert: that: - - 'result.changed == false' + - result.changed == false - name: Remove IPv4 address + register: result vyos.vyos.vyos_l3_interface: name: eth1 ipv4: 192.168.2.10/24 state: absent - register: result - assert: that: - - 'result.changed == true' + - result.changed == true - '"delete interfaces ethernet eth1 address 192.168.2.10/24" in result.commands' - name: Remove IPv4 address again (idempotent) + register: result vyos.vyos.vyos_l3_interface: name: eth1 ipv4: 192.168.2.10/24 state: absent - register: result - assert: that: - - 'result.changed == false' + - result.changed == false - name: Remove IPv6 address + register: result vyos.vyos.vyos_l3_interface: name: eth1 ipv6: fd5d:12c9:2201:1::1/64 state: absent - register: result - assert: that: - - 'result.changed == true' + - result.changed == true - '"delete interfaces ethernet eth1 address fd5d:12c9:2201:1::1/64" in result.commands' - name: Remove IPv6 address again (idempotent) + register: result vyos.vyos.vyos_l3_interface: name: eth1 ipv6: fd5d:12c9:2201:1::1/64 state: absent - register: result - assert: that: - - 'result.changed == false' + - result.changed == false - name: Set IP addresses on aggregate + register: result vyos.vyos.vyos_l3_interface: aggregate: - - {name: eth1, ipv4: 192.168.2.10/24} - - {name: eth2, ipv4: 192.168.3.10/24, ipv6: "fd5d:12c9:2201:1::1/64"} - - {name: eth2, ipv4: 192.168.4.10/24} - register: result + + - name: eth1 + ipv4: 192.168.2.10/24 + + - name: eth2 + ipv4: 192.168.3.10/24 + ipv6: fd5d:12c9:2201:1::1/64 + + - name: eth2 + ipv4: 192.168.4.10/24 - assert: that: - - 'result.changed == true' + - result.changed == true - '"set interfaces ethernet eth1 address 192.168.2.10/24" in result.commands' - '"set interfaces ethernet eth2 address 192.168.3.10/24" in result.commands' - '"set interfaces ethernet eth2 address fd5d:12c9:2201:1::1/64" in result.commands' - '"set interfaces ethernet eth2 address 192.168.4.10/24" in result.commands' - name: Set IP addresses on aggregate (idempotent) + register: result vyos.vyos.vyos_l3_interface: aggregate: - - {name: eth1, ipv4: 192.168.2.10/24} - - {name: eth2, ipv4: 192.168.3.10/24, ipv6: "fd5d:12c9:2201:1::1/64"} - - {name: eth2, ipv4: 192.168.4.10/24} - register: result + + - name: eth1 + ipv4: 192.168.2.10/24 + + - name: eth2 + ipv4: 192.168.3.10/24 + ipv6: fd5d:12c9:2201:1::1/64 + + - name: eth2 + ipv4: 192.168.4.10/24 - assert: that: - - 'result.changed == false' + - result.changed == false - name: Remove IP addresses on aggregate + register: result vyos.vyos.vyos_l3_interface: aggregate: - - {name: eth1, ipv4: 192.168.2.10/24} - - {name: eth2, ipv4: 192.168.3.10/24, ipv6: "fd5d:12c9:2201:1::1/64"} - - {name: eth2, ipv4: 192.168.4.10/24} + + - name: eth1 + ipv4: 192.168.2.10/24 + + - name: eth2 + ipv4: 192.168.3.10/24 + ipv6: fd5d:12c9:2201:1::1/64 + + - name: eth2 + ipv4: 192.168.4.10/24 state: absent - register: result - assert: that: - - 'result.changed == true' + - result.changed == true - '"delete interfaces ethernet eth1 address 192.168.2.10/24" in result.commands' - '"delete interfaces ethernet eth2 address 192.168.3.10/24" in result.commands' - '"delete interfaces ethernet eth2 address fd5d:12c9:2201:1::1/64" in result.commands' - '"delete interfaces ethernet eth2 address 192.168.4.10/24" in result.commands' - name: Remove IP addresses on aggregate (idempotent) + register: result vyos.vyos.vyos_l3_interface: aggregate: - - {name: eth1, ipv4: 192.168.2.10/24} - - {name: eth2, ipv4: 192.168.3.10/24, ipv6: "fd5d:12c9:2201:1::1/64"} - - {name: eth2, ipv4: 192.168.4.10/24} + + - name: eth1 + ipv4: 192.168.2.10/24 + + - name: eth2 + ipv4: 192.168.3.10/24 + ipv6: fd5d:12c9:2201:1::1/64 + + - name: eth2 + ipv4: 192.168.4.10/24 state: absent - register: result - assert: that: - - 'result.changed == false' + - result.changed == false diff --git a/tests/integration/targets/vyos_l3_interfaces/defaults/main.yaml b/tests/integration/targets/vyos_l3_interfaces/defaults/main.yaml index 164afea..852a6be 100644 --- a/tests/integration/targets/vyos_l3_interfaces/defaults/main.yaml +++ b/tests/integration/targets/vyos_l3_interfaces/defaults/main.yaml @@ -1,3 +1,3 @@ --- -testcase: "[^_].*" +testcase: '[^_].*' test_items: [] diff --git a/tests/integration/targets/vyos_l3_interfaces/tasks/cli.yaml b/tests/integration/targets/vyos_l3_interfaces/tasks/cli.yaml index 337e341..f622cf9 100644 --- a/tests/integration/targets/vyos_l3_interfaces/tasks/cli.yaml +++ b/tests/integration/targets/vyos_l3_interfaces/tasks/cli.yaml @@ -1,8 +1,8 @@ --- - name: Collect all cli test cases find: - paths: "{{ role_path }}/tests/cli" - patterns: "{{ testcase }}.yaml" + paths: '{{ role_path }}/tests/cli' + patterns: '{{ testcase }}.yaml' use_regex: true register: test_cases delegate_to: localhost @@ -11,10 +11,10 @@ set_fact: test_items="{{ test_cases.files | map(attribute='path') | list }}" delegate_to: localhost -- name: Run test case (connection=network_cli) - include: "{{ test_case_to_run }}" +- name: Run test case (connection=ansible.netcommon.network_cli) + include: '{{ test_case_to_run }}' vars: - ansible_connection: network_cli - with_items: "{{ test_items }}" + 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_l3_interfaces/tasks/main.yaml b/tests/integration/targets/vyos_l3_interfaces/tasks/main.yaml index d4cf26f..a3db933 100644 --- a/tests/integration/targets/vyos_l3_interfaces/tasks/main.yaml +++ b/tests/integration/targets/vyos_l3_interfaces/tasks/main.yaml @@ -1,2 +1,4 @@ --- -- {include: cli.yaml, tags: ['cli']} +- include: cli.yaml + tags: + - cli diff --git a/tests/integration/targets/vyos_l3_interfaces/tests/cli/_populate.yaml b/tests/integration/targets/vyos_l3_interfaces/tests/cli/_populate.yaml index d598c42..563b1d7 100644 --- a/tests/integration/targets/vyos_l3_interfaces/tests/cli/_populate.yaml +++ b/tests/integration/targets/vyos_l3_interfaces/tests/cli/_populate.yaml @@ -1,11 +1,9 @@ --- - name: Setup - network.cli.cli_config: - config: "{{ lines }}" vars: - lines: | - set interfaces ethernet eth1 address '192.0.2.14/24' - set interfaces ethernet eth2 address '192.0.2.10/24' - set interfaces ethernet eth2 address '192.0.2.11/24' - set interfaces ethernet eth2 address '2001:db8::10/32' - set interfaces ethernet eth2 address '2001:db8::12/32' + lines: "set interfaces ethernet eth1 address '192.0.2.14/24'\nset interfaces\ + \ ethernet eth2 address '192.0.2.10/24'\nset interfaces ethernet eth2 address\ + \ '192.0.2.11/24'\nset interfaces ethernet eth2 address '2001:db8::10/32'\n\ + set interfaces ethernet eth2 address '2001:db8::12/32'\n" + ansible.netcommon.cli_config: + config: '{{ lines }}' diff --git a/tests/integration/targets/vyos_l3_interfaces/tests/cli/_remove_config.yaml b/tests/integration/targets/vyos_l3_interfaces/tests/cli/_remove_config.yaml index 95b2b8c..1fb0dd3 100644 --- a/tests/integration/targets/vyos_l3_interfaces/tests/cli/_remove_config.yaml +++ b/tests/integration/targets/vyos_l3_interfaces/tests/cli/_remove_config.yaml @@ -1,13 +1,12 @@ --- - name: Remove Config - network.cli.cli_config: - config: "{{ lines }}" vars: - lines: | - delete interfaces ethernet "{{ intf }}" address - delete interfaces ethernet "{{ intf }}" vif + lines: "delete interfaces ethernet \"{{ intf }}\" address\ndelete interfaces\ + \ ethernet \"{{ intf }}\" vif\n" loop: - eth1 - eth2 loop_control: loop_var: intf + ansible.netcommon.cli_config: + config: '{{ lines }}' diff --git a/tests/integration/targets/vyos_l3_interfaces/tests/cli/deleted.yaml b/tests/integration/targets/vyos_l3_interfaces/tests/cli/deleted.yaml index b95bcdb..ff4aabf 100644 --- a/tests/integration/targets/vyos_l3_interfaces/tests/cli/deleted.yaml +++ b/tests/integration/targets/vyos_l3_interfaces/tests/cli/deleted.yaml @@ -1,19 +1,23 @@ --- - debug: - msg: "Start vyos_interfaces deleted integration tests ansible_connection={{ ansible_connection }}" + msg: Start vyos_interfaces deleted integration tests ansible_connection={{ ansible_connection + }} - include_tasks: _remove_config.yaml - block: + - include_tasks: _populate.yaml - name: Delete attributes of given interfaces - vyos.vyos.vyos_l3_interfaces: &deleted + register: result + vyos.vyos.vyos_l3_interfaces: &id001 config: + - name: eth1 + - name: eth2 state: deleted - register: result - name: Assert that the before dicts were correctly generated assert: @@ -23,26 +27,29 @@ - name: Assert that the correct set of commands were generated assert: that: - - "{{ deleted['commands'] | symmetric_difference(result['commands']) |length == 0 }}" + - "{{ 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 }}" + - "{{ deleted['after'] | symmetric_difference(result['after']) |length\ + \ == 0 }}" - name: Delete attributes of given interfaces (IDEMPOTENT) - vyos.vyos.vyos_l3_interfaces: *deleted register: result + vyos.vyos.vyos_l3_interfaces: *id001 - name: Assert that the previous task was idempotent assert: that: - - "result.changed == false" + - result.changed == false - name: Assert that the before dicts were correctly generated assert: that: - - "{{ deleted['after'] | symmetric_difference(result['before']) |length == 0 }}" - + - "{{ deleted['after'] | symmetric_difference(result['before']) |length\ + \ == 0 }}" always: + - include_tasks: _remove_config.yaml diff --git a/tests/integration/targets/vyos_l3_interfaces/tests/cli/empty_config.yaml b/tests/integration/targets/vyos_l3_interfaces/tests/cli/empty_config.yaml index 7b1f100..96d4cda 100644 --- a/tests/integration/targets/vyos_l3_interfaces/tests/cli/empty_config.yaml +++ b/tests/integration/targets/vyos_l3_interfaces/tests/cli/empty_config.yaml @@ -1,35 +1,36 @@ --- - debug: - msg: "START vyos_l3_interfaces empty_config integration tests on connection={{ ansible_connection }}" + msg: START vyos_l3_interfaces empty_config integration tests on connection={{ + ansible_connection }} - name: Merged with empty config should give appropriate error message + register: result + ignore_errors: true vyos.vyos.vyos_l3_interfaces: config: state: merged - register: result - ignore_errors: true - 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_l3_interfaces: config: state: replaced - register: result - ignore_errors: true - assert: that: - result.msg == 'value of config parameter must not be empty for state replaced' - name: Overridden with empty config should give appropriate error message + register: result + ignore_errors: true vyos.vyos.vyos_l3_interfaces: config: state: overridden - register: result - ignore_errors: true - assert: that: diff --git a/tests/integration/targets/vyos_l3_interfaces/tests/cli/merged.yaml b/tests/integration/targets/vyos_l3_interfaces/tests/cli/merged.yaml index 1b3b9ea..99fb552 100644 --- a/tests/integration/targets/vyos_l3_interfaces/tests/cli/merged.yaml +++ b/tests/integration/targets/vyos_l3_interfaces/tests/cli/merged.yaml @@ -1,58 +1,72 @@ --- - debug: - msg: "START vyos_l3_interfaces merged integration tests on connection={{ ansible_connection }}" + msg: START vyos_l3_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_l3_interfaces: &merged + register: result + vyos.vyos.vyos_l3_interfaces: &id001 config: + - name: eth1 ipv4: + - address: 192.0.2.10/24 ipv6: + - address: 2001:db8::10/32 - name: eth2 ipv4: + - address: 198.51.100.10/24 vifs: + - vlan_id: 101 ipv4: + - address: 198.51.100.130/25 ipv6: + - address: 2001:db8::20/32 state: merged - register: result - name: Assert that before dicts were correctly generated assert: - that: "{{ merged['before'] | symmetric_difference(result['before']) |length == 0 }}" + 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 }}" + - "{{ 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 }}" + - "{{ merged['after'] | symmetric_difference(result['after']) |length\ + \ == 0 }}" - - name: Merge the provided configuration with the existing running configuration (IDEMPOTENT) - vyos.vyos.vyos_l3_interfaces: *merged + - name: Merge the provided configuration with the existing running configuration + (IDEMPOTENT) register: result + vyos.vyos.vyos_l3_interfaces: *id001 - name: Assert that the previous task was idempotent assert: that: - - "result['changed'] == false" + - result['changed'] == false - name: Assert that before dicts were correctly generated assert: that: - - "{{ merged['after'] | symmetric_difference(result['before']) |length == 0 }}" - + - "{{ merged['after'] | symmetric_difference(result['before']) |length\ + \ == 0 }}" always: + - include_tasks: _remove_config.yaml diff --git a/tests/integration/targets/vyos_l3_interfaces/tests/cli/overridden.yaml b/tests/integration/targets/vyos_l3_interfaces/tests/cli/overridden.yaml index 06d6fc7..644fe08 100644 --- a/tests/integration/targets/vyos_l3_interfaces/tests/cli/overridden.yaml +++ b/tests/integration/targets/vyos_l3_interfaces/tests/cli/overridden.yaml @@ -1,23 +1,29 @@ --- - debug: - msg: "START vyos_l3_interfaces merged integration tests on connection={{ ansible_connection }}" + msg: START vyos_l3_interfaces merged integration tests on connection={{ ansible_connection + }} - include_tasks: _remove_config.yaml - block: + - include_tasks: _populate.yaml - name: Overrides all device configuration with provided configuration - vyos.vyos.vyos_l3_interfaces: &overridden + register: result + vyos.vyos.vyos_l3_interfaces: &id001 config: + - name: eth0 ipv4: + - address: dhcp + - name: eth1 ipv4: - - address: "192.0.2.15/24" + + - address: 192.0.2.15/24 state: overridden - register: result - name: Assert that before dicts were correctly generated assert: @@ -27,26 +33,29 @@ - name: Assert that correct commands were generated assert: that: - - "{{ overridden['commands'] | symmetric_difference(result['commands']) |length == 0 }}" + - "{{ 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 }}" + - "{{ overridden['after'] | symmetric_difference(result['after']) |length\ + \ == 0 }}" - name: Overrides all device configuration with provided configurations (IDEMPOTENT) - vyos.vyos.vyos_l3_interfaces: *overridden register: result + vyos.vyos.vyos_l3_interfaces: *id001 - name: Assert that the previous task was idempotent assert: that: - - "result['changed'] == false" + - result['changed'] == false - name: Assert that before dicts were correctly generated assert: that: - - "{{ overridden['after'] | symmetric_difference(result['before']) |length == 0 }}" - + - "{{ overridden['after'] | symmetric_difference(result['before']) |length\ + \ == 0 }}" always: + - include_tasks: _remove_config.yaml diff --git a/tests/integration/targets/vyos_l3_interfaces/tests/cli/replaced.yaml b/tests/integration/targets/vyos_l3_interfaces/tests/cli/replaced.yaml index 6f1228a..2c664bb 100644 --- a/tests/integration/targets/vyos_l3_interfaces/tests/cli/replaced.yaml +++ b/tests/integration/targets/vyos_l3_interfaces/tests/cli/replaced.yaml @@ -1,28 +1,35 @@ --- - debug: - msg: "START vyos_l3_interfaces replaced integration tests on connection={{ ansible_connection }}" + msg: START vyos_l3_interfaces replaced integration tests on connection={{ ansible_connection + }} - include_tasks: _remove_config.yaml - block: + - include_tasks: _populate.yaml - name: Replace device configurations of listed interfaces with provided configurations - vyos.vyos.vyos_l3_interfaces: &replaced + register: result + vyos.vyos.vyos_l3_interfaces: &id001 config: + - name: eth1 ipv4: + - address: 192.0.2.19/24 + - name: eth2 ipv6: + - address: 2001:db8::11/32 state: replaced - register: result - name: Assert that correct set of commands were generated assert: that: - - "{{ replaced['commands'] | symmetric_difference(result['commands']) |length == 0 }}" + - "{{ replaced['commands'] | symmetric_difference(result['commands'])\ + \ |length == 0 }}" - name: Assert that before dicts are correctly generated assert: @@ -32,21 +39,24 @@ - name: Assert that after dict is correctly generated assert: that: - - "{{ replaced['after'] | symmetric_difference(result['after']) |length == 0 }}" + - "{{ replaced['after'] | symmetric_difference(result['after']) |length\ + \ == 0 }}" - - name: Replace device configurations of listed interfaces with provided configurarions (IDEMPOTENT) - vyos.vyos.vyos_l3_interfaces: *replaced + - name: Replace device configurations of listed interfaces with provided configurarions + (IDEMPOTENT) register: result + vyos.vyos.vyos_l3_interfaces: *id001 - name: Assert that task was idempotent assert: that: - - "result['changed'] == false" + - result['changed'] == false - name: Assert that before dict is correctly generated assert: that: - - "{{ replaced['after'] | symmetric_difference(result['before']) |length == 0 }}" - + - "{{ replaced['after'] | symmetric_difference(result['before']) |length\ + \ == 0 }}" always: + - include_tasks: _remove_config.yaml diff --git a/tests/integration/targets/vyos_l3_interfaces/vars/main.yaml b/tests/integration/targets/vyos_l3_interfaces/vars/main.yaml index 1241763..ee329d3 100644 --- a/tests/integration/targets/vyos_l3_interfaces/vars/main.yaml +++ b/tests/integration/targets/vyos_l3_interfaces/vars/main.yaml @@ -1,82 +1,68 @@ --- merged: before: - - name: "eth0" + - name: eth0 ipv4: - - address: "dhcp" - - - name: "eth1" - - - name: "eth2" - + - address: dhcp + - name: eth1 + - name: eth2 commands: - - "set interfaces ethernet eth1 address '192.0.2.10/24'" - - "set interfaces ethernet eth1 address '2001:db8::10/32'" - - "set interfaces ethernet eth2 address '198.51.100.10/24'" - - "set interfaces ethernet eth2 vif 101 address '198.51.100.130/25'" - - "set interfaces ethernet eth2 vif 101 address '2001:db8::20/32'" - + - set interfaces ethernet eth1 address '192.0.2.10/24' + - set interfaces ethernet eth1 address '2001:db8::10/32' + - set interfaces ethernet eth2 address '198.51.100.10/24' + - set interfaces ethernet eth2 vif 101 address '198.51.100.130/25' + - set interfaces ethernet eth2 vif 101 address '2001:db8::20/32' after: - - name: "eth0" + - name: eth0 ipv4: - - address: "dhcp" - - - name: "eth1" + - address: dhcp + - name: eth1 ipv4: - - address: "192.0.2.10/24" + - address: 192.0.2.10/24 ipv6: - - address: "2001:db8::10/32" - - - name: "eth2" + - address: 2001:db8::10/32 + - name: eth2 ipv4: - - address: "198.51.100.10/24" + - address: 198.51.100.10/24 vifs: - vlan_id: 101 ipv4: - - address: "198.51.100.130/25" + - address: 198.51.100.130/25 ipv6: - - address: "2001:db8::20/32" - + - address: 2001:db8::20/32 populate: - - name: "eth1" + - name: eth1 ipv4: - - address: "192.0.2.14/24" - - - name: "eth2" + - address: 192.0.2.14/24 + - name: eth2 ipv4: - - address: "192.0.2.10/24" - - address: "192.0.2.11/24" + - address: 192.0.2.10/24 + - address: 192.0.2.11/24 ipv6: - - address: "2001:db8::10/32" - - address: "2001:db8::12/32" - - - name: "eth0" + - address: 2001:db8::10/32 + - address: 2001:db8::12/32 + - name: eth0 ipv4: - - address: "dhcp" - + - address: dhcp replaced: commands: - - "delete interfaces ethernet eth2 address '192.0.2.10/24'" - - "delete interfaces ethernet eth2 address '192.0.2.11/24'" - - "delete interfaces ethernet eth2 address '2001:db8::10/32'" - - "delete interfaces ethernet eth2 address '2001:db8::12/32'" - - "set interfaces ethernet eth2 address '2001:db8::11/32'" - - "delete interfaces ethernet eth1 address '192.0.2.14/24'" - - "set interfaces ethernet eth1 address '192.0.2.19/24'" - + - delete interfaces ethernet eth2 address '192.0.2.10/24' + - delete interfaces ethernet eth2 address '192.0.2.11/24' + - delete interfaces ethernet eth2 address '2001:db8::10/32' + - delete interfaces ethernet eth2 address '2001:db8::12/32' + - set interfaces ethernet eth2 address '2001:db8::11/32' + - delete interfaces ethernet eth1 address '192.0.2.14/24' + - set interfaces ethernet eth1 address '192.0.2.19/24' after: - - name: "eth2" + - name: eth2 ipv6: - - address: "2001:db8::11/32" - - - name: "eth1" + - address: 2001:db8::11/32 + - name: eth1 ipv4: - - address: "192.0.2.19/24" - - - name: "eth0" + - address: 192.0.2.19/24 + - name: eth0 ipv4: - - address: "dhcp" - + - address: dhcp overridden: commands: - delete interfaces ethernet eth1 address '192.0.2.14/24' @@ -85,18 +71,14 @@ overridden: - delete interfaces ethernet eth2 address '192.0.2.11/24' - delete interfaces ethernet eth2 address '2001:db8::10/32' - delete interfaces ethernet eth2 address '2001:db8::12/32' - after: - - name: "eth0" + - name: eth0 ipv4: - - address: "dhcp" - - - name: "eth1" + - address: dhcp + - name: eth1 ipv4: - - address: "192.0.2.15/24" - - - name: "eth2" - + - address: 192.0.2.15/24 + - name: eth2 deleted: commands: - delete interfaces ethernet eth1 address '192.0.2.14/24' @@ -105,10 +87,8 @@ deleted: - delete interfaces ethernet eth2 address '2001:db8::10/32' - delete interfaces ethernet eth2 address '2001:db8::12/32' after: - - name: "eth0" + - name: eth0 ipv4: - - address: "dhcp" - - - name: "eth1" - - - name: "eth2" + - address: dhcp + - name: eth1 + - name: eth2 diff --git a/tests/integration/targets/vyos_lag_interfaces/defaults/main.yaml b/tests/integration/targets/vyos_lag_interfaces/defaults/main.yaml index 164afea..852a6be 100644 --- a/tests/integration/targets/vyos_lag_interfaces/defaults/main.yaml +++ b/tests/integration/targets/vyos_lag_interfaces/defaults/main.yaml @@ -1,3 +1,3 @@ --- -testcase: "[^_].*" +testcase: '[^_].*' test_items: [] diff --git a/tests/integration/targets/vyos_lag_interfaces/tasks/cli.yaml b/tests/integration/targets/vyos_lag_interfaces/tasks/cli.yaml index 655e51e..93eb2fe 100644 --- a/tests/integration/targets/vyos_lag_interfaces/tasks/cli.yaml +++ b/tests/integration/targets/vyos_lag_interfaces/tasks/cli.yaml @@ -1,8 +1,8 @@ --- - name: Collect all cli test cases find: - paths: "{{ role_path }}/tests/cli" - patterns: "{{ testcase }}.yaml" + paths: '{{ role_path }}/tests/cli' + patterns: '{{ testcase }}.yaml' use_regex: true register: test_cases delegate_to: localhost @@ -10,10 +10,10 @@ - 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 }}" +- name: Run test case (connection=ansible.netcommon.network_cli) + include: '{{ test_case_to_run }}' vars: - ansible_connection: network_cli - with_items: "{{ test_items }}" + 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_lag_interfaces/tasks/main.yaml b/tests/integration/targets/vyos_lag_interfaces/tasks/main.yaml index d4cf26f..a3db933 100644 --- a/tests/integration/targets/vyos_lag_interfaces/tasks/main.yaml +++ b/tests/integration/targets/vyos_lag_interfaces/tasks/main.yaml @@ -1,2 +1,4 @@ --- -- {include: cli.yaml, tags: ['cli']} +- include: cli.yaml + tags: + - cli diff --git a/tests/integration/targets/vyos_lag_interfaces/tests/cli/_add_bond.yaml b/tests/integration/targets/vyos_lag_interfaces/tests/cli/_add_bond.yaml index adacb0c..927a6ce 100644 --- a/tests/integration/targets/vyos_lag_interfaces/tests/cli/_add_bond.yaml +++ b/tests/integration/targets/vyos_lag_interfaces/tests/cli/_add_bond.yaml @@ -1,8 +1,6 @@ --- - name: Add Bond - network.cli.cli_config: - config: "{{ lines }}" vars: - lines: | - set interfaces bonding bond0 - set interfaces bonding bond1 + lines: "set interfaces bonding bond0\nset interfaces bonding bond1\n" + ansible.netcommon.cli_config: + config: '{{ lines }}' diff --git a/tests/integration/targets/vyos_lag_interfaces/tests/cli/_populate.yaml b/tests/integration/targets/vyos_lag_interfaces/tests/cli/_populate.yaml index 6139508..f646742 100644 --- a/tests/integration/targets/vyos_lag_interfaces/tests/cli/_populate.yaml +++ b/tests/integration/targets/vyos_lag_interfaces/tests/cli/_populate.yaml @@ -1,16 +1,11 @@ --- - name: Setup - network.cli.cli_config: - config: "{{ lines }}" vars: - lines: | - set interfaces bonding bond0 - set interfaces bonding bond0 hash-policy 'layer2' - set interfaces bonding bond0 mode 'active-backup' - set interfaces ethernet eth1 bond-group bond0 - set interfaces bonding bond1 - set interfaces bonding bond0 primary 'eth1' - set interfaces bonding bond1 hash-policy 'layer2+3' - set interfaces bonding bond1 mode 'active-backup' - set interfaces ethernet eth2 bond-group bond1 - set interfaces bonding bond1 primary 'eth2' + lines: "set interfaces bonding bond0\nset interfaces bonding bond0 hash-policy\ + \ 'layer2'\nset interfaces bonding bond0 mode 'active-backup'\nset interfaces\ + \ ethernet eth1 bond-group bond0\nset interfaces bonding bond1\nset interfaces\ + \ bonding bond0 primary 'eth1'\nset interfaces bonding bond1 hash-policy 'layer2+3'\n\ + set interfaces bonding bond1 mode 'active-backup'\nset interfaces ethernet\ + \ eth2 bond-group bond1\nset interfaces bonding bond1 primary 'eth2'\n" + ansible.netcommon.cli_config: + config: '{{ lines }}' diff --git a/tests/integration/targets/vyos_lag_interfaces/tests/cli/_remove_bond.yaml b/tests/integration/targets/vyos_lag_interfaces/tests/cli/_remove_bond.yaml index 29085bd..6679d6a 100644 --- a/tests/integration/targets/vyos_lag_interfaces/tests/cli/_remove_bond.yaml +++ b/tests/integration/targets/vyos_lag_interfaces/tests/cli/_remove_bond.yaml @@ -1,8 +1,6 @@ --- - name: Remove Bond - network.cli.cli_config: - config: "{{ lines }}" vars: - lines: | - delete interfaces bonding bond0 - delete interfaces bonding bond1 + lines: "delete interfaces bonding bond0\ndelete interfaces bonding bond1\n" + ansible.netcommon.cli_config: + config: '{{ lines }}' diff --git a/tests/integration/targets/vyos_lag_interfaces/tests/cli/_remove_config.yaml b/tests/integration/targets/vyos_lag_interfaces/tests/cli/_remove_config.yaml index c5d3657..5469bf5 100644 --- a/tests/integration/targets/vyos_lag_interfaces/tests/cli/_remove_config.yaml +++ b/tests/integration/targets/vyos_lag_interfaces/tests/cli/_remove_config.yaml @@ -1,14 +1,10 @@ --- - name: Remove Config - network.cli.cli_config: - config: "{{ lines }}" vars: - lines: | - delete interfaces bonding bond0 hash-policy - delete interfaces ethernet eth1 bond-group bond0 - delete interfaces bonding bond0 mode - delete interfaces bonding bond0 primary - delete interfaces bonding bond1 hash-policy - delete interfaces ethernet eth2 bond-group bond1 - delete interfaces bonding bond1 mode - delete interfaces bonding bond1 primary + lines: "delete interfaces bonding bond0 hash-policy\ndelete interfaces ethernet\ + \ eth1 bond-group bond0\ndelete interfaces bonding bond0 mode\ndelete interfaces\ + \ bonding bond0 primary\ndelete interfaces bonding bond1 hash-policy\ndelete\ + \ interfaces ethernet eth2 bond-group bond1\ndelete interfaces bonding bond1\ + \ mode\ndelete interfaces bonding bond1 primary\n" + ansible.netcommon.cli_config: + config: '{{ lines }}' diff --git a/tests/integration/targets/vyos_lag_interfaces/tests/cli/deleted.yaml b/tests/integration/targets/vyos_lag_interfaces/tests/cli/deleted.yaml index af6e632..ac8204f 100644 --- a/tests/integration/targets/vyos_lag_interfaces/tests/cli/deleted.yaml +++ b/tests/integration/targets/vyos_lag_interfaces/tests/cli/deleted.yaml @@ -1,17 +1,21 @@ --- - debug: - msg: "Start vyos_lag_interfaces deleted integration tests ansible_connection={{ ansible_connection }}" + msg: Start vyos_lag_interfaces deleted integration tests ansible_connection={{ + ansible_connection }} - include_tasks: _populate.yaml - block: + - name: Delete attributes of given LAG interfaces. - vyos.vyos.vyos_lag_interfaces: &deleted + register: result + vyos.vyos.vyos_lag_interfaces: &id001 config: + - name: bond0 + - name: bond1 state: deleted - register: result - name: Assert that the before dicts were correctly generated assert: @@ -21,26 +25,29 @@ - name: Assert that the correct set of commands were generated assert: that: - - "{{ deleted['commands'] | symmetric_difference(result['commands']) |length == 0 }}" + - "{{ 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 }}" + - "{{ deleted['after'] | symmetric_difference(result['after']) |length\ + \ == 0 }}" - name: Delete attributes of given interfaces (IDEMPOTENT) - vyos.vyos.vyos_lag_interfaces: *deleted register: result + vyos.vyos.vyos_lag_interfaces: *id001 - name: Assert that the previous task was idempotent assert: that: - - "result.changed == false" + - result.changed == false - name: Assert that the before dicts were correctly generated assert: that: - - "{{ deleted['after'] | symmetric_difference(result['before']) |length == 0 }}" - + - "{{ deleted['after'] | symmetric_difference(result['before']) |length\ + \ == 0 }}" always: + - include_tasks: _remove_config.yaml diff --git a/tests/integration/targets/vyos_lag_interfaces/tests/cli/empty_config.yaml b/tests/integration/targets/vyos_lag_interfaces/tests/cli/empty_config.yaml index 74d3466..3894fb5 100644 --- a/tests/integration/targets/vyos_lag_interfaces/tests/cli/empty_config.yaml +++ b/tests/integration/targets/vyos_lag_interfaces/tests/cli/empty_config.yaml @@ -1,35 +1,36 @@ --- - debug: - msg: "START vyos_lag_interfaces empty_config integration tests on connection={{ ansible_connection }}" + msg: START vyos_lag_interfaces empty_config integration tests on connection={{ + ansible_connection }} - name: Merged with empty config should give appropriate error message + register: result + ignore_errors: true vyos.vyos.vyos_lag_interfaces: config: state: merged - register: result - ignore_errors: true - 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_lag_interfaces: config: state: replaced - register: result - ignore_errors: true - assert: that: - result.msg == 'value of config parameter must not be empty for state replaced' - name: Overridden with empty config should give appropriate error message + register: result + ignore_errors: true vyos.vyos.vyos_lag_interfaces: config: state: overridden - register: result - ignore_errors: true - assert: that: diff --git a/tests/integration/targets/vyos_lag_interfaces/tests/cli/merged.yaml b/tests/integration/targets/vyos_lag_interfaces/tests/cli/merged.yaml index 7b1931f..35f1e35 100644 --- a/tests/integration/targets/vyos_lag_interfaces/tests/cli/merged.yaml +++ b/tests/integration/targets/vyos_lag_interfaces/tests/cli/merged.yaml @@ -1,6 +1,7 @@ --- - debug: - msg: "START vyos_lag_interfaces merged integration tests on connection={{ ansible_connection }}" + msg: START vyos_lag_interfaces merged integration tests on connection={{ ansible_connection + }} - include_tasks: _remove_config.yaml @@ -9,52 +10,61 @@ - include_tasks: _add_bond.yaml - block: + - name: Merge the provided configuration with the exisiting running configuration - vyos.vyos.vyos_lag_interfaces: &merged + register: result + vyos.vyos.vyos_lag_interfaces: &id001 config: + - name: bond0 - hash_policy: "layer2" - mode: "active-backup" + hash_policy: layer2 + mode: active-backup members: + - member: eth1 primary: eth1 - name: bond1 - hash_policy: "layer2+3" - mode: "active-backup" + hash_policy: layer2+3 + mode: active-backup members: + - member: eth2 primary: eth2 state: merged - register: result - name: Assert that before dicts were correctly generated assert: - that: "{{ merged['before'] | symmetric_difference(result['before']) |length == 0 }}" + 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 }}" + - "{{ 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 }}" + - "{{ merged['after'] | symmetric_difference(result['after']) |length\ + \ == 0 }}" - - name: Merge the provided configuration with the existing running configuration (IDEMPOTENT) - vyos.vyos.vyos_lag_interfaces: *merged + - name: Merge the provided configuration with the existing running configuration + (IDEMPOTENT) register: result + vyos.vyos.vyos_lag_interfaces: *id001 - name: Assert that the previous task was idempotent assert: that: - - "result['changed'] == false" + - result['changed'] == false - name: Assert that before dicts were correctly generated assert: that: - - "{{ merged['after'] | symmetric_difference(result['before']) |length == 0 }}" - + - "{{ merged['after'] | symmetric_difference(result['before']) |length\ + \ == 0 }}" always: + - include_tasks: _remove_config.yaml diff --git a/tests/integration/targets/vyos_lag_interfaces/tests/cli/overridden.yaml b/tests/integration/targets/vyos_lag_interfaces/tests/cli/overridden.yaml index c44cc33..aa6e247 100644 --- a/tests/integration/targets/vyos_lag_interfaces/tests/cli/overridden.yaml +++ b/tests/integration/targets/vyos_lag_interfaces/tests/cli/overridden.yaml @@ -1,6 +1,7 @@ --- - debug: - msg: "START vyos_lag_interfaces overridden integration tests on connection={{ ansible_connection }}" + msg: START vyos_lag_interfaces overridden integration tests on connection={{ + ansible_connection }} - include_tasks: _remove_config.yaml @@ -9,17 +10,20 @@ - include_tasks: _populate.yaml - block: + - name: Overrides all device configuration with provided configuration - vyos.vyos.vyos_lag_interfaces: &overridden + register: result + vyos.vyos.vyos_lag_interfaces: &id001 config: + - name: bond1 - mode: "active-backup" + mode: active-backup members: + - member: eth2 primary: eth2 hash_policy: layer2 state: overridden - register: result - name: Assert that before dicts were correctly generated assert: @@ -29,26 +33,29 @@ - name: Assert that correct commands were generated assert: that: - - "{{ overridden['commands'] | symmetric_difference(result['commands']) |length == 0 }}" + - "{{ 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 }}" + - "{{ overridden['after'] | symmetric_difference(result['after']) |length\ + \ == 0 }}" - name: Overrides all device configuration with provided configurations (IDEMPOTENT) - vyos.vyos.vyos_lag_interfaces: *overridden register: result + vyos.vyos.vyos_lag_interfaces: *id001 - name: Assert that the previous task was idempotent assert: that: - - "result['changed'] == false" + - result['changed'] == false - name: Assert that before dicts were correctly generated assert: that: - - "{{ overridden['after'] | symmetric_difference(result['before']) |length == 0 }}" - + - "{{ overridden['after'] | symmetric_difference(result['before']) |length\ + \ == 0 }}" always: + - include_tasks: _remove_config.yaml diff --git a/tests/integration/targets/vyos_lag_interfaces/tests/cli/replaced.yaml b/tests/integration/targets/vyos_lag_interfaces/tests/cli/replaced.yaml index 894d505..c080056 100644 --- a/tests/integration/targets/vyos_lag_interfaces/tests/cli/replaced.yaml +++ b/tests/integration/targets/vyos_lag_interfaces/tests/cli/replaced.yaml @@ -1,27 +1,33 @@ --- - debug: - msg: "START vyos_lag_interfaces replaced integration tests on connection={{ ansible_connection }}" + msg: START vyos_lag_interfaces replaced integration tests on connection={{ ansible_connection + }} - include_tasks: _remove_config.yaml - include_tasks: _populate.yaml - block: - - name: Replace device configurations of listed LAG interfaces with provided configurations - vyos.vyos.vyos_lag_interfaces: &replaced + + - name: Replace device configurations of listed LAG interfaces with provided + configurations + register: result + vyos.vyos.vyos_lag_interfaces: &id001 config: + - name: bond1 - mode: "802.3ad" - hash_policy: "layer2" + mode: 802.3ad + hash_policy: layer2 members: + - member: eth2 state: replaced - register: result - name: Assert that correct set of commands were generated assert: that: - - "{{ replaced['commands'] | symmetric_difference(result['commands']) |length == 0 }}" + - "{{ replaced['commands'] | symmetric_difference(result['commands'])\ + \ |length == 0 }}" - name: Assert that before dicts are correctly generated assert: @@ -31,21 +37,24 @@ - name: Assert that after dict is correctly generated assert: that: - - "{{ replaced['after'] | symmetric_difference(result['after']) |length == 0 }}" + - "{{ replaced['after'] | symmetric_difference(result['after']) |length\ + \ == 0 }}" - - name: Replace device configurations of listed LAG interfaces with provided configurarions (IDEMPOTENT) - vyos.vyos.vyos_lag_interfaces: *replaced + - name: Replace device configurations of listed LAG interfaces with provided + configurarions (IDEMPOTENT) register: result + vyos.vyos.vyos_lag_interfaces: *id001 - name: Assert that task was idempotent assert: that: - - "result['changed'] == false" + - result['changed'] == false - name: Assert that before dict is correctly generated assert: that: - - "{{ replaced['after'] | symmetric_difference(result['before']) |length == 0 }}" - + - "{{ replaced['after'] | symmetric_difference(result['before']) |length\ + \ == 0 }}" always: + - include_tasks: _remove_config.yaml diff --git a/tests/integration/targets/vyos_lag_interfaces/tests/cli/rtt.yaml b/tests/integration/targets/vyos_lag_interfaces/tests/cli/rtt.yaml index 3095a12..55e2bbf 100644 --- a/tests/integration/targets/vyos_lag_interfaces/tests/cli/rtt.yaml +++ b/tests/integration/targets/vyos_lag_interfaces/tests/cli/rtt.yaml @@ -1,31 +1,35 @@ --- - debug: - msg: "START vyos_lag_interfaces round trip integration tests on connection={{ ansible_connection }}" + msg: START vyos_lag_interfaces round trip integration tests on connection={{ + ansible_connection }} - include_tasks: _remove_config.yaml - include_tasks: _remove_bond.yaml - block: + - name: Apply the provided configuration (base config) + register: base_config vyos.vyos.vyos_lag_interfaces: config: + - name: bond0 - hash_policy: "layer2" - mode: "active-backup" + hash_policy: layer2 + mode: active-backup members: + - member: eth1 primary: eth1 - name: bond1 - hash_policy: "layer2+3" - mode: "active-backup" + hash_policy: layer2+3 + mode: active-backup members: + - member: eth2 primary: eth2 - state: merged - register: base_config - name: Gather lag_interfaces facts vyos.vyos.vyos_facts: @@ -35,35 +39,40 @@ - lag_interfaces - name: Apply the provided configuration (config to be reverted) + register: result vyos.vyos.vyos_lag_interfaces: config: + - name: bond0 - hash_policy: "layer2+3" - mode: "802.3ad" + hash_policy: layer2+3 + mode: 802.3ad members: + - member: eth1 - name: bond1 - hash_policy: "layer2" - mode: "xor-hash" + hash_policy: layer2 + mode: xor-hash members: + - member: eth2 state: merged - register: result - name: Assert that changes were applied assert: - that: "{{ round_trip['after'] | symmetric_difference(result['after']) |length == 0 }}" + that: "{{ round_trip['after'] | symmetric_difference(result['after']) |length\ + \ == 0 }}" - name: Revert back to base config using facts round trip + register: revert vyos.vyos.vyos_lag_interfaces: config: "{{ ansible_facts['network_resources']['lag_interfaces'] }}" state: overridden - register: revert - name: Assert that config was reverted assert: - that: "{{ base_config['after'] | symmetric_difference(revert['after']) |length == 0 }}" - + that: "{{ base_config['after'] | symmetric_difference(revert['after']) |length\ + \ == 0 }}" always: + - include_tasks: _remove_config.yaml diff --git a/tests/integration/targets/vyos_lag_interfaces/vars/main.yaml b/tests/integration/targets/vyos_lag_interfaces/vars/main.yaml index 8726e39..5783693 100644 --- a/tests/integration/targets/vyos_lag_interfaces/vars/main.yaml +++ b/tests/integration/targets/vyos_lag_interfaces/vars/main.yaml @@ -1,115 +1,99 @@ --- merged: before: - - name: "bond0" - - - name: "bond1" - + - name: bond0 + - name: bond1 commands: - - "set interfaces bonding bond0 hash-policy 'layer2'" - - "set interfaces bonding bond0 mode 'active-backup'" - - "set interfaces ethernet eth1 bond-group 'bond0'" - - "set interfaces bonding bond0 primary 'eth1'" - - "set interfaces bonding bond1 hash-policy 'layer2+3'" - - "set interfaces bonding bond1 mode 'active-backup'" - - "set interfaces ethernet eth2 bond-group 'bond1'" - - "set interfaces bonding bond1 primary 'eth2'" - + - set interfaces bonding bond0 hash-policy 'layer2' + - set interfaces bonding bond0 mode 'active-backup' + - set interfaces ethernet eth1 bond-group 'bond0' + - set interfaces bonding bond0 primary 'eth1' + - set interfaces bonding bond1 hash-policy 'layer2+3' + - set interfaces bonding bond1 mode 'active-backup' + - set interfaces ethernet eth2 bond-group 'bond1' + - set interfaces bonding bond1 primary 'eth2' after: - - name: "bond0" - hash_policy: "layer2" + - name: bond0 + hash_policy: layer2 members: - member: eth1 - mode: "active-backup" + mode: active-backup primary: eth1 - - - name: "bond1" - hash_policy: "layer2+3" + - name: bond1 + hash_policy: layer2+3 members: - member: eth2 - mode: "active-backup" + mode: active-backup primary: eth2 - populate: - - name: "bond0" - hash_policy: "layer2" + - name: bond0 + hash_policy: layer2 members: - member: eth1 - mode: "active-backup" + mode: active-backup primary: eth1 - - - name: "bond1" - hash_policy: "layer2+3" + - name: bond1 + hash_policy: layer2+3 members: - member: eth2 - mode: "active-backup" + mode: active-backup primary: eth2 - replaced: commands: - - "delete interfaces bonding bond1 primary" - - "set interfaces bonding bond1 hash-policy 'layer2'" - - "set interfaces bonding bond1 mode '802.3ad'" - + - delete interfaces bonding bond1 primary + - set interfaces bonding bond1 hash-policy 'layer2' + - set interfaces bonding bond1 mode '802.3ad' after: - - name: "bond0" - hash_policy: "layer2" + - name: bond0 + hash_policy: layer2 members: - member: eth1 - mode: "active-backup" + mode: active-backup primary: eth1 - - - name: "bond1" - hash_policy: "layer2" + - name: bond1 + hash_policy: layer2 members: - member: eth2 - mode: "802.3ad" - + mode: 802.3ad overridden: commands: - - "delete interfaces bonding bond0 hash-policy" - - "delete interfaces ethernet eth1 bond-group 'bond0'" - - "delete interfaces bonding bond0 mode" - - "delete interfaces bonding bond0 primary" - - "set interfaces bonding bond1 hash-policy 'layer2'" - + - delete interfaces bonding bond0 hash-policy + - delete interfaces ethernet eth1 bond-group 'bond0' + - delete interfaces bonding bond0 mode + - delete interfaces bonding bond0 primary + - set interfaces bonding bond1 hash-policy 'layer2' after: - - name: "bond0" - - name: "bond1" - hash_policy: "layer2" + - name: bond0 + - name: bond1 + hash_policy: layer2 members: - member: eth2 - mode: "active-backup" + mode: active-backup primary: eth2 - deleted: commands: - - "delete interfaces bonding bond0 hash-policy" - - "delete interfaces ethernet eth1 bond-group 'bond0'" - - "delete interfaces bonding bond0 mode" - - "delete interfaces bonding bond0 primary" - - "delete interfaces bonding bond1 hash-policy" - - "delete interfaces ethernet eth2 bond-group 'bond1'" - - "delete interfaces bonding bond1 mode" - - "delete interfaces bonding bond1 primary" - + - delete interfaces bonding bond0 hash-policy + - delete interfaces ethernet eth1 bond-group 'bond0' + - delete interfaces bonding bond0 mode + - delete interfaces bonding bond0 primary + - delete interfaces bonding bond1 hash-policy + - delete interfaces ethernet eth2 bond-group 'bond1' + - delete interfaces bonding bond1 mode + - delete interfaces bonding bond1 primary after: - - name: "bond0" - - - name: "bond1" - + - name: bond0 + - name: bond1 round_trip: after: - - name: "bond0" - hash_policy: "layer2+3" + - name: bond0 + hash_policy: layer2+3 members: - member: eth1 - mode: "802.3ad" + mode: 802.3ad primary: eth1 - - - name: "bond1" - hash_policy: "layer2" + - name: bond1 + hash_policy: layer2 members: - member: eth2 - mode: "xor-hash" + mode: xor-hash primary: eth2 diff --git a/tests/integration/targets/vyos_linkagg/defaults/main.yaml b/tests/integration/targets/vyos_linkagg/defaults/main.yaml index 9ef5ba5..a845c24 100644 --- a/tests/integration/targets/vyos_linkagg/defaults/main.yaml +++ b/tests/integration/targets/vyos_linkagg/defaults/main.yaml @@ -1,3 +1,3 @@ --- -testcase: "*" +testcase: '*' test_items: [] diff --git a/tests/integration/targets/vyos_linkagg/tasks/cli.yaml b/tests/integration/targets/vyos_linkagg/tasks/cli.yaml index 890d3ac..90f265f 100644 --- a/tests/integration/targets/vyos_linkagg/tasks/cli.yaml +++ b/tests/integration/targets/vyos_linkagg/tasks/cli.yaml @@ -1,22 +1,22 @@ --- - name: collect all cli test cases find: - paths: "{{ role_path }}/tests/cli" - patterns: "{{ testcase }}.yaml" + paths: '{{ role_path }}/tests/cli' + patterns: '{{ testcase }}.yaml' 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 }} ansible_connection=network_cli" - with_items: "{{ test_items }}" +- name: run test case (connection=ansible.netcommon.network_cli) + include: '{{ test_case_to_run }} ansible_connection=ansible.netcommon.network_cli' + with_items: '{{ test_items }}' loop_control: loop_var: test_case_to_run - name: run test case (connection=local) - include: "{{ test_case_to_run }} ansible_connection=local" - with_first_found: "{{ test_items }}" + include: '{{ test_case_to_run }} ansible_connection=local' + with_first_found: '{{ test_items }}' loop_control: loop_var: test_case_to_run diff --git a/tests/integration/targets/vyos_linkagg/tasks/main.yaml b/tests/integration/targets/vyos_linkagg/tasks/main.yaml index d4cf26f..a3db933 100644 --- a/tests/integration/targets/vyos_linkagg/tasks/main.yaml +++ b/tests/integration/targets/vyos_linkagg/tasks/main.yaml @@ -1,2 +1,4 @@ --- -- {include: cli.yaml, tags: ['cli']} +- include: cli.yaml + tags: + - cli diff --git a/tests/integration/targets/vyos_linkagg/tests/cli/basic.yaml b/tests/integration/targets/vyos_linkagg/tests/cli/basic.yaml index fadbbd7..ffe0c42 100644 --- a/tests/integration/targets/vyos_linkagg/tests/cli/basic.yaml +++ b/tests/integration/targets/vyos_linkagg/tests/cli/basic.yaml @@ -12,173 +12,189 @@ state: absent - name: Create linkagg + register: result vyos.vyos.vyos_linkagg: name: bond0 members: - eth1 state: present - register: result - assert: that: - - 'result.changed == true' + - result.changed == true - '"set interfaces bonding bond0 mode 802.3ad" in result.commands' - '"set interfaces ethernet eth1 bond-group bond0" in result.commands' - name: Create linkagg again (idempotent) + register: result vyos.vyos.vyos_linkagg: name: bond0 members: - eth1 state: present - register: result - assert: that: - - 'result.changed == false' + - result.changed == false - name: Add linkagg member + register: result vyos.vyos.vyos_linkagg: name: bond0 members: - eth2 state: present - register: result - assert: that: - - 'result.changed == true' + - result.changed == true - '"set interfaces ethernet eth2 bond-group bond0" in result.commands' - name: Add linkagg member again (idempotent) + register: result vyos.vyos.vyos_linkagg: name: bond0 members: - eth2 state: present - register: result - assert: that: - - 'result.changed == false' + - result.changed == false - name: Disable linkagg + register: result vyos.vyos.vyos_linkagg: name: bond0 state: down - register: result - assert: that: - - 'result.changed == true' + - result.changed == true - '"set interfaces bonding bond0 disable" in result.commands' - name: Disable linkagg again (idempotent) + register: result vyos.vyos.vyos_linkagg: name: bond0 state: down - register: result - assert: that: - - 'result.changed == false' + - result.changed == false - name: Enable linkagg + register: result vyos.vyos.vyos_linkagg: name: bond0 state: up - register: result - assert: that: - - 'result.changed == true' + - result.changed == true - '"delete interfaces bonding bond0 disable" in result.commands[0]' - name: Enable linkagg again (idempotent) + register: result vyos.vyos.vyos_linkagg: name: bond0 state: up - register: result - assert: that: - - 'result.changed == false' + - result.changed == false - name: Remove linkagg + register: result vyos.vyos.vyos_linkagg: name: bond0 state: absent - register: result - assert: that: - - 'result.changed == true' + - result.changed == true - '"delete interfaces ethernet eth1 bond-group" in result.commands' - '"delete interfaces ethernet eth2 bond-group" in result.commands' - '"delete interfaces bonding bond0" in result.commands' - name: Remove linkagg again (idempotent) + register: result vyos.vyos.vyos_linkagg: name: bond0 state: absent - register: result - assert: that: - - 'result.changed == false' + - result.changed == false - name: Create collection of linkagg definitions + register: result vyos.vyos.vyos_linkagg: aggregate: - - {name: bond0, members: [eth1]} - - {name: bond1, members: [eth2]} + + - name: bond0 + members: + - eth1 + + - name: bond1 + members: + - eth2 state: present - register: result - assert: that: - - 'result.changed == true' + - result.changed == true - '"set interfaces bonding bond0 mode 802.3ad" in result.commands' - '"set interfaces ethernet eth1 bond-group bond0" in result.commands' - '"set interfaces bonding bond1 mode 802.3ad" in result.commands' - '"set interfaces ethernet eth2 bond-group bond1" in result.commands' - name: Create collection of linkagg definitions again (idempotent) + register: result vyos.vyos.vyos_linkagg: aggregate: - - {name: bond0, members: [eth1]} - - {name: bond1, members: [eth2]} + + - name: bond0 + members: + - eth1 + + - name: bond1 + members: + - eth2 state: present - register: result - assert: that: - - 'result.changed == false' + - result.changed == false - name: Remove collection of linkagg definitions + register: result vyos.vyos.vyos_linkagg: aggregate: + - name: bond0 + - name: bond1 state: absent - register: result - assert: that: - - 'result.changed == true' + - result.changed == true - '"delete interfaces ethernet eth1 bond-group" in result.commands' - '"delete interfaces bonding bond0" in result.commands' - '"delete interfaces ethernet eth2 bond-group" in result.commands' - '"delete interfaces bonding bond1" in result.commands' - name: Remove collection of linkagg definitions again (idempotent) + register: result vyos.vyos.vyos_linkagg: aggregate: + - name: bond0 + - name: bond1 state: absent - register: result - assert: that: - - 'result.changed == false' + - result.changed == false diff --git a/tests/integration/targets/vyos_linkagg/tests/cli/net_linkagg.yaml b/tests/integration/targets/vyos_linkagg/tests/cli/net_linkagg.yaml index 93f98e7..8178f92 100644 --- a/tests/integration/targets/vyos_linkagg/tests/cli/net_linkagg.yaml +++ b/tests/integration/targets/vyos_linkagg/tests/cli/net_linkagg.yaml @@ -1,31 +1,30 @@ --- -- debug: msg="START vyos cli/net_linkagg.yaml on connection={{ ansible_connection }}" - -# Add minimal testcase to check args are passed correctly to -# implementation module and module run is successful. +- debug: msg="START vyos cli/net_linkagg.yaml on connection={{ ansible_connection + }}" - name: Remove linkagg - set - net_linkagg: + ansible.netcommon.net_linkagg: name: bond0 state: absent - name: Create linkagg using platform agnostic module - net_linkagg: + register: result + ansible.netcommon.net_linkagg: name: bond0 members: - eth1 state: present - register: result - assert: that: - - 'result.changed == true' + - result.changed == true - '"set interfaces bonding bond0 mode 802.3ad" in result.commands' - '"set interfaces ethernet eth1 bond-group bond0" in result.commands' - name: Remove linkagg - teardown - net_linkagg: + ansible.netcommon.net_linkagg: name: bond0 state: absent -- debug: msg="END vyos cli/net_linkagg.yaml on connection={{ ansible_connection }}" +- debug: msg="END vyos cli/net_linkagg.yaml on connection={{ ansible_connection + }}" diff --git a/tests/integration/targets/vyos_lldp/defaults/main.yaml b/tests/integration/targets/vyos_lldp/defaults/main.yaml index 9ef5ba5..a845c24 100644 --- a/tests/integration/targets/vyos_lldp/defaults/main.yaml +++ b/tests/integration/targets/vyos_lldp/defaults/main.yaml @@ -1,3 +1,3 @@ --- -testcase: "*" +testcase: '*' test_items: [] diff --git a/tests/integration/targets/vyos_lldp/tasks/cli.yaml b/tests/integration/targets/vyos_lldp/tasks/cli.yaml index 890d3ac..90f265f 100644 --- a/tests/integration/targets/vyos_lldp/tasks/cli.yaml +++ b/tests/integration/targets/vyos_lldp/tasks/cli.yaml @@ -1,22 +1,22 @@ --- - name: collect all cli test cases find: - paths: "{{ role_path }}/tests/cli" - patterns: "{{ testcase }}.yaml" + paths: '{{ role_path }}/tests/cli' + patterns: '{{ testcase }}.yaml' 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 }} ansible_connection=network_cli" - with_items: "{{ test_items }}" +- name: run test case (connection=ansible.netcommon.network_cli) + include: '{{ test_case_to_run }} ansible_connection=ansible.netcommon.network_cli' + with_items: '{{ test_items }}' loop_control: loop_var: test_case_to_run - name: run test case (connection=local) - include: "{{ test_case_to_run }} ansible_connection=local" - with_first_found: "{{ test_items }}" + include: '{{ test_case_to_run }} ansible_connection=local' + with_first_found: '{{ test_items }}' loop_control: loop_var: test_case_to_run diff --git a/tests/integration/targets/vyos_lldp/tasks/main.yaml b/tests/integration/targets/vyos_lldp/tasks/main.yaml index d4cf26f..a3db933 100644 --- a/tests/integration/targets/vyos_lldp/tasks/main.yaml +++ b/tests/integration/targets/vyos_lldp/tasks/main.yaml @@ -1,2 +1,4 @@ --- -- {include: cli.yaml, tags: ['cli']} +- include: cli.yaml + tags: + - cli diff --git a/tests/integration/targets/vyos_lldp/tests/cli/basic.yaml b/tests/integration/targets/vyos_lldp/tests/cli/basic.yaml index badd3a9..b108bbf 100644 --- a/tests/integration/targets/vyos_lldp/tests/cli/basic.yaml +++ b/tests/integration/targets/vyos_lldp/tests/cli/basic.yaml @@ -6,39 +6,39 @@ lines: delete service lldp - name: Enable LLDP service + register: result vyos.vyos.vyos_lldp: state: present - register: result - assert: that: - - 'result.changed == true' + - result.changed == true - '"set service lldp" in result.commands' - name: Enable LLDP service again (idempotent) + register: result vyos.vyos.vyos_lldp: state: present - register: result - assert: that: - - 'result.changed == false' + - result.changed == false - name: Disable LLDP service + register: result vyos.vyos.vyos_lldp: state: absent - register: result - assert: that: - - 'result.changed == true' + - result.changed == true - '"delete service lldp" in result.commands' - name: + register: result vyos.vyos.vyos_lldp: state: absent - register: result - assert: that: - - 'result.changed == false' + - result.changed == false diff --git a/tests/integration/targets/vyos_lldp/tests/cli/net_lldp.yaml b/tests/integration/targets/vyos_lldp/tests/cli/net_lldp.yaml index e68d5a6..d19b126 100644 --- a/tests/integration/targets/vyos_lldp/tests/cli/net_lldp.yaml +++ b/tests/integration/targets/vyos_lldp/tests/cli/net_lldp.yaml @@ -1,21 +1,18 @@ --- - debug: msg="START vyos cli/net_lldp.yaml on connection={{ ansible_connection }}" -# Add minimal testcase to check args are passed correctly to -# implementation module and module run is successful. - - name: Make sure LLDP is not running - setup vyos.vyos.vyos_config: lines: delete service lldp - name: Enable LLDP service using platform agnostic module - net_lldp: - state: present register: result + ansible.netcommon.net_lldp: + state: present - assert: that: - - 'result.changed == true' + - result.changed == true - '"set service lldp" in result.commands' - name: Make sure LLDP is not running - teardown diff --git a/tests/integration/targets/vyos_lldp_global/defaults/main.yaml b/tests/integration/targets/vyos_lldp_global/defaults/main.yaml index 164afea..852a6be 100644 --- a/tests/integration/targets/vyos_lldp_global/defaults/main.yaml +++ b/tests/integration/targets/vyos_lldp_global/defaults/main.yaml @@ -1,3 +1,3 @@ --- -testcase: "[^_].*" +testcase: '[^_].*' test_items: [] diff --git a/tests/integration/targets/vyos_lldp_global/tasks/cli.yaml b/tests/integration/targets/vyos_lldp_global/tasks/cli.yaml index 655e51e..93eb2fe 100644 --- a/tests/integration/targets/vyos_lldp_global/tasks/cli.yaml +++ b/tests/integration/targets/vyos_lldp_global/tasks/cli.yaml @@ -1,8 +1,8 @@ --- - name: Collect all cli test cases find: - paths: "{{ role_path }}/tests/cli" - patterns: "{{ testcase }}.yaml" + paths: '{{ role_path }}/tests/cli' + patterns: '{{ testcase }}.yaml' use_regex: true register: test_cases delegate_to: localhost @@ -10,10 +10,10 @@ - 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 }}" +- name: Run test case (connection=ansible.netcommon.network_cli) + include: '{{ test_case_to_run }}' vars: - ansible_connection: network_cli - with_items: "{{ test_items }}" + 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_lldp_global/tasks/main.yaml b/tests/integration/targets/vyos_lldp_global/tasks/main.yaml index d4cf26f..a3db933 100644 --- a/tests/integration/targets/vyos_lldp_global/tasks/main.yaml +++ b/tests/integration/targets/vyos_lldp_global/tasks/main.yaml @@ -1,2 +1,4 @@ --- -- {include: cli.yaml, tags: ['cli']} +- include: cli.yaml + tags: + - cli diff --git a/tests/integration/targets/vyos_lldp_global/tests/cli/_populate.yaml b/tests/integration/targets/vyos_lldp_global/tests/cli/_populate.yaml index 088aa7b..e439242 100644 --- a/tests/integration/targets/vyos_lldp_global/tests/cli/_populate.yaml +++ b/tests/integration/targets/vyos_lldp_global/tests/cli/_populate.yaml @@ -1,9 +1,7 @@ --- - name: Setup - network.cli.cli_config: - config: "{{ lines }}" vars: - lines: | - set service lldp - set service lldp legacy-protocols 'cdp' - set service lldp management-address '192.0.2.17' + lines: "set service lldp\nset service lldp legacy-protocols 'cdp'\nset service\ + \ lldp management-address '192.0.2.17'\n" + ansible.netcommon.cli_config: + config: '{{ lines }}' diff --git a/tests/integration/targets/vyos_lldp_global/tests/cli/_remove_config.yaml b/tests/integration/targets/vyos_lldp_global/tests/cli/_remove_config.yaml index b000a94..b823449 100644 --- a/tests/integration/targets/vyos_lldp_global/tests/cli/_remove_config.yaml +++ b/tests/integration/targets/vyos_lldp_global/tests/cli/_remove_config.yaml @@ -1,9 +1,7 @@ --- - name: Remove Config - network.cli.cli_config: - config: "{{ lines }}" vars: - lines: | - delete service lldp legacy-protocols - delete service lldp management-address - delete service lldp + lines: "delete service lldp legacy-protocols\ndelete service lldp management-address\n\ + delete service lldp\n" + ansible.netcommon.cli_config: + config: '{{ lines }}' diff --git a/tests/integration/targets/vyos_lldp_global/tests/cli/deleted.yaml b/tests/integration/targets/vyos_lldp_global/tests/cli/deleted.yaml index 8017e93..f4c6cbc 100644 --- a/tests/integration/targets/vyos_lldp_global/tests/cli/deleted.yaml +++ b/tests/integration/targets/vyos_lldp_global/tests/cli/deleted.yaml @@ -1,15 +1,17 @@ --- - debug: - msg: "Start vyos_lldp_global deleted integration tests ansible_connection={{ ansible_connection }}" + msg: Start vyos_lldp_global deleted integration tests ansible_connection={{ + ansible_connection }} - include_tasks: _populate.yaml - block: + - name: Delete attributes of LLDP service. - vyos.vyos.vyos_lldp_global: &deleted + register: result + vyos.vyos.vyos_lldp_global: &id001 config: state: deleted - register: result - name: Assert that the before dicts were correctly generated assert: @@ -19,7 +21,8 @@ - name: Assert that the correct set of commands were generated assert: that: - - "{{ deleted['commands'] | symmetric_difference(result['commands']) |length == 0 }}" + - "{{ deleted['commands'] | symmetric_difference(result['commands']) |length\ + \ == 0 }}" - name: Assert that the after dicts were correctly generated assert: @@ -27,18 +30,18 @@ - "{{ deleted['after'] == result['after']}}" - name: Delete attributes of given interfaces (IDEMPOTENT) - vyos.vyos.vyos_lldp_global: *deleted register: result + vyos.vyos.vyos_lldp_global: *id001 - name: Assert that the previous task was idempotent assert: that: - - "result.changed == false" + - result.changed == false - 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_lldp_global/tests/cli/empty_config.yaml b/tests/integration/targets/vyos_lldp_global/tests/cli/empty_config.yaml index 05609b6..a197c45 100644 --- a/tests/integration/targets/vyos_lldp_global/tests/cli/empty_config.yaml +++ b/tests/integration/targets/vyos_lldp_global/tests/cli/empty_config.yaml @@ -1,24 +1,25 @@ --- - debug: - msg: "START vyos_lldp_global empty_config integration tests on connection={{ ansible_connection }}" + msg: START vyos_lldp_global 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_lldp_global: config: state: merged - register: result - ignore_errors: true - 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_lldp_global: config: state: replaced - register: result - ignore_errors: true - assert: that: diff --git a/tests/integration/targets/vyos_lldp_global/tests/cli/merged.yaml b/tests/integration/targets/vyos_lldp_global/tests/cli/merged.yaml index a17bd61..aeabc9f 100644 --- a/tests/integration/targets/vyos_lldp_global/tests/cli/merged.yaml +++ b/tests/integration/targets/vyos_lldp_global/tests/cli/merged.yaml @@ -1,21 +1,23 @@ --- - debug: - msg: "START vyos_lldp_global merged integration tests on connection={{ ansible_connection }}" + msg: START vyos_lldp_global 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 - vyos.vyos.vyos_lldp_global: &merged + register: result + vyos.vyos.vyos_lldp_global: &id001 config: legacy_protocols: - - 'fdp' - - 'cdp' + - fdp + - cdp address: 192.0.2.11 state: merged - register: result - name: Assert that before dicts were correctly generated assert: @@ -24,26 +26,28 @@ - name: Assert that correct set of commands were generated assert: that: - - "{{ merged['commands'] | symmetric_difference(result['commands']) |length == 0 }}" + - "{{ 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) - vyos.vyos.vyos_lldp_global: *merged + - name: Merge the provided configuration with the existing running configuration + (IDEMPOTENT) register: result + vyos.vyos.vyos_lldp_global: *id001 - name: Assert that the previous task was idempotent assert: that: - - "result['changed'] == false" + - 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_lldp_global/tests/cli/replaced.yaml b/tests/integration/targets/vyos_lldp_global/tests/cli/replaced.yaml index 371e7f3..9a833f5 100644 --- a/tests/integration/targets/vyos_lldp_global/tests/cli/replaced.yaml +++ b/tests/integration/targets/vyos_lldp_global/tests/cli/replaced.yaml @@ -1,27 +1,30 @@ --- - debug: - msg: "START vyos_lldp_global replaced integration tests on connection={{ ansible_connection }}" + msg: START vyos_lldp_global replaced integration tests on connection={{ ansible_connection + }} - include_tasks: _remove_config.yaml - include_tasks: _populate.yaml - block: + - name: Replace device configurations of LLDP service with provided configurations - vyos.vyos.vyos_lldp_global: &replaced + register: result + vyos.vyos.vyos_lldp_global: &id001 config: legacy_protocols: - - 'edp' - - 'sonmp' - - 'cdp' + - edp + - sonmp + - cdp address: 192.0.2.14 state: replaced - register: result - name: Assert that correct set of commands were generated assert: that: - - "{{ replaced['commands'] | symmetric_difference(result['commands']) |length == 0 }}" + - "{{ replaced['commands'] | symmetric_difference(result['commands'])\ + \ |length == 0 }}" - name: Assert that before dicts are correctly generated assert: @@ -33,19 +36,20 @@ that: - "{{ replaced['after'] == result['after'] }}" - - name: Replace device configurations of LLDP service with provided configurarions (IDEMPOTENT) - vyos.vyos.vyos_lldp_global: *replaced + - name: Replace device configurations of LLDP service with provided configurarions + (IDEMPOTENT) register: result + vyos.vyos.vyos_lldp_global: *id001 - name: Assert that task was idempotent assert: that: - - "result['changed'] == false" + - 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_lldp_global/tests/cli/rtt.yaml b/tests/integration/targets/vyos_lldp_global/tests/cli/rtt.yaml index 02902bc..2e8284f 100644 --- a/tests/integration/targets/vyos_lldp_global/tests/cli/rtt.yaml +++ b/tests/integration/targets/vyos_lldp_global/tests/cli/rtt.yaml @@ -1,19 +1,21 @@ --- - debug: - msg: "START vyos_lldp_global round trip integration tests on connection={{ ansible_connection }}" + msg: START vyos_lldp_global 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_lldp_global: config: legacy_protocols: - - 'fdp' - - 'cdp' + - fdp + - cdp address: 192.0.2.11 state: merged - register: base_config - name: Gather vyos_lldp_global facts vyos.vyos.vyos_facts: @@ -23,29 +25,29 @@ - lldp_global - name: Apply the provided configuration (config to be reverted) + register: result vyos.vyos.vyos_lldp_global: config: legacy_protocols: - - 'edp' - - 'sonmp' - - 'cdp' + - edp + - sonmp + - cdp address: 192.0.2.14 state: merged - register: result - 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_lldp_global: config: "{{ ansible_facts['network_resources']['lldp_global'] }}" state: replaced - register: revert - 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_lldp_global/vars/main.yaml b/tests/integration/targets/vyos_lldp_global/vars/main.yaml index 420b2b4..81e71be 100644 --- a/tests/integration/targets/vyos_lldp_global/vars/main.yaml +++ b/tests/integration/targets/vyos_lldp_global/vars/main.yaml @@ -1,56 +1,48 @@ --- merged: before: - address: '192.0.2.17' + address: 192.0.2.17 enable: true legacy_protocols: - - 'cdp' - + - cdp commands: - - "set service lldp management-address '192.0.2.11'" - - "set service lldp legacy-protocols 'fdp'" - + - set service lldp management-address '192.0.2.11' + - set service lldp legacy-protocols 'fdp' after: - address: '192.0.2.11' + address: 192.0.2.11 enable: true legacy_protocols: - - 'cdp' - - 'fdp' - + - cdp + - fdp populate: - address: '192.0.2.17' + address: 192.0.2.17 enable: true legacy_protocols: - - 'cdp' - + - cdp replaced: commands: - - "set service lldp legacy-protocols 'edp'" - - "set service lldp legacy-protocols 'sonmp'" - - "set service lldp management-address '192.0.2.14'" - + - set service lldp legacy-protocols 'edp' + - set service lldp legacy-protocols 'sonmp' + - set service lldp management-address '192.0.2.14' after: - address: '192.0.2.14' + address: 192.0.2.14 enable: true legacy_protocols: - - 'cdp' - - 'edp' - - 'sonmp' - + - cdp + - edp + - sonmp deleted: commands: - - "delete service lldp management-address" - - "delete service lldp legacy-protocols" - + - delete service lldp management-address + - delete service lldp legacy-protocols after: - "enable": true - + enable: true round_trip: after: - address: '192.0.2.14' + address: 192.0.2.14 enable: true legacy_protocols: - - 'cdp' - - 'edp' - - 'fdp' - - 'sonmp' + - cdp + - edp + - fdp + - sonmp diff --git a/tests/integration/targets/vyos_lldp_interface/defaults/main.yaml b/tests/integration/targets/vyos_lldp_interface/defaults/main.yaml index 9ef5ba5..a845c24 100644 --- a/tests/integration/targets/vyos_lldp_interface/defaults/main.yaml +++ b/tests/integration/targets/vyos_lldp_interface/defaults/main.yaml @@ -1,3 +1,3 @@ --- -testcase: "*" +testcase: '*' test_items: [] diff --git a/tests/integration/targets/vyos_lldp_interface/tasks/cli.yaml b/tests/integration/targets/vyos_lldp_interface/tasks/cli.yaml index 890d3ac..90f265f 100644 --- a/tests/integration/targets/vyos_lldp_interface/tasks/cli.yaml +++ b/tests/integration/targets/vyos_lldp_interface/tasks/cli.yaml @@ -1,22 +1,22 @@ --- - name: collect all cli test cases find: - paths: "{{ role_path }}/tests/cli" - patterns: "{{ testcase }}.yaml" + paths: '{{ role_path }}/tests/cli' + patterns: '{{ testcase }}.yaml' 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 }} ansible_connection=network_cli" - with_items: "{{ test_items }}" +- name: run test case (connection=ansible.netcommon.network_cli) + include: '{{ test_case_to_run }} ansible_connection=ansible.netcommon.network_cli' + with_items: '{{ test_items }}' loop_control: loop_var: test_case_to_run - name: run test case (connection=local) - include: "{{ test_case_to_run }} ansible_connection=local" - with_first_found: "{{ test_items }}" + include: '{{ test_case_to_run }} ansible_connection=local' + with_first_found: '{{ test_items }}' loop_control: loop_var: test_case_to_run diff --git a/tests/integration/targets/vyos_lldp_interface/tasks/main.yaml b/tests/integration/targets/vyos_lldp_interface/tasks/main.yaml index d4cf26f..a3db933 100644 --- a/tests/integration/targets/vyos_lldp_interface/tasks/main.yaml +++ b/tests/integration/targets/vyos_lldp_interface/tasks/main.yaml @@ -1,2 +1,4 @@ --- -- {include: cli.yaml, tags: ['cli']} +- include: cli.yaml + tags: + - cli diff --git a/tests/integration/targets/vyos_lldp_interface/tests/cli/basic.yaml b/tests/integration/targets/vyos_lldp_interface/tests/cli/basic.yaml index 0690e9e..2697f48 100644 --- a/tests/integration/targets/vyos_lldp_interface/tests/cli/basic.yaml +++ b/tests/integration/targets/vyos_lldp_interface/tests/cli/basic.yaml @@ -6,162 +6,176 @@ lines: delete service lldp - name: Create LLDP configuration + register: result vyos.vyos.vyos_lldp_interface: name: eth1 state: present - register: result - assert: that: - - 'result.changed == true' + - result.changed == true - '"set service lldp interface eth1" in result.commands' - name: Create LLDP configuration again (idempotent) + register: result vyos.vyos.vyos_lldp_interface: name: eth1 state: present - register: result - assert: that: - - 'result.changed == false' + - result.changed == false - name: Disable LLDP configuration + register: result vyos.vyos.vyos_lldp_interface: name: eth1 state: disabled - register: result - assert: that: - - 'result.changed == true' + - result.changed == true - '"set service lldp interface eth1 disable" in result.commands' - name: Disable LLDP configuration again (idempotent) + register: result vyos.vyos.vyos_lldp_interface: name: eth1 state: disabled - register: result - assert: that: - - 'result.changed == false' + - result.changed == false - name: Enable LLDP configuration + register: result vyos.vyos.vyos_lldp_interface: name: eth1 state: enabled - register: result - assert: that: - - 'result.changed == true' + - result.changed == true - '"delete service lldp interface eth1 disable" in result.commands' - name: Enable LLDP configuration again (idempotent) + register: result vyos.vyos.vyos_lldp_interface: name: eth1 state: enabled - register: result - assert: that: - - 'result.changed == false' + - result.changed == false - name: Delete LLDP configuration + register: result vyos.vyos.vyos_lldp_interface: name: eth1 state: absent - register: result - assert: that: - - 'result.changed == true' + - result.changed == true - '"delete service lldp interface eth1" in result.commands' - name: Delete LLDP configuration again (idempotent) + register: result vyos.vyos.vyos_lldp_interface: name: eth1 state: absent - register: result - assert: that: - - 'result.changed == false' + - result.changed == false - name: Create aggregate of LLDP interface configurations + register: result vyos.vyos.vyos_lldp_interface: aggregate: + - name: eth1 + - name: eth2 state: present - register: result - assert: that: - - 'result.changed == true' + - result.changed == true - '"set service lldp interface eth1" in result.commands' - '"set service lldp interface eth2" in result.commands' - name: Create aggregate of LLDP interface configurations again (idempotent) + register: result vyos.vyos.vyos_lldp_interface: aggregate: + - name: eth1 + - name: eth2 state: present - register: result - assert: that: - - 'result.changed == false' + - result.changed == false - name: Override LLDP interface configuration on aggregate + register: result vyos.vyos.vyos_lldp_interface: aggregate: + - name: eth1 - - {name: eth2, state: disabled} + + - name: eth2 + state: disabled state: present - register: result - assert: that: - - 'result.changed == true' + - result.changed == true - '"set service lldp interface eth2 disable" in result.commands' - name: Override LLDP interface configuration on aggregate again (idempotent) + register: result vyos.vyos.vyos_lldp_interface: aggregate: + - name: eth1 - - {name: eth2, state: disabled} + + - name: eth2 + state: disabled state: present - register: result - assert: that: - - 'result.changed == false' + - result.changed == false - name: Delete aggregate of LLDP interface configurations + register: result vyos.vyos.vyos_lldp_interface: aggregate: + - name: eth1 + - name: eth2 state: absent - register: result - assert: that: - - 'result.changed == true' + - result.changed == true - '"delete service lldp interface eth1" in result.commands' - '"delete service lldp interface eth2" in result.commands' - name: Delete aggregate of LLDP interface configurations (idempotent) + register: result vyos.vyos.vyos_lldp_interface: aggregate: + - name: eth1 + - name: eth2 state: absent - register: result - assert: that: - - 'result.changed == false' + - result.changed == false diff --git a/tests/integration/targets/vyos_lldp_interface/tests/cli/net_lldp_interface.yaml b/tests/integration/targets/vyos_lldp_interface/tests/cli/net_lldp_interface.yaml index 1710b7e..98fc93a 100644 --- a/tests/integration/targets/vyos_lldp_interface/tests/cli/net_lldp_interface.yaml +++ b/tests/integration/targets/vyos_lldp_interface/tests/cli/net_lldp_interface.yaml @@ -1,26 +1,25 @@ --- -- debug: msg="START vyos cli/net_lldp_interface.yaml on connection={{ ansible_connection }}" - -# Add minimal testcase to check args are passed correctly to -# implementation module and module run is successful. +- debug: msg="START vyos cli/net_lldp_interface.yaml on connection={{ ansible_connection + }}" - name: Make sure LLDP is not running - setup vyos.vyos.vyos_config: lines: delete service lldp - name: Create LLDP configuration using platform agnostic module - net_lldp_interface: + register: result + ansible.netcommon.net_lldp_interface: name: eth1 state: present - register: result - assert: that: - - 'result.changed == true' + - result.changed == true - '"set service lldp interface eth1" in result.commands' - name: Make sure LLDP is not running - teardown vyos.vyos.vyos_config: lines: delete service lldp -- debug: msg="END vyos cli/net_lldp_interface.yaml on connection={{ ansible_connection }}" +- debug: msg="END vyos cli/net_lldp_interface.yaml on connection={{ ansible_connection + }}" diff --git a/tests/integration/targets/vyos_lldp_interfaces/defaults/main.yaml b/tests/integration/targets/vyos_lldp_interfaces/defaults/main.yaml index 164afea..852a6be 100644 --- a/tests/integration/targets/vyos_lldp_interfaces/defaults/main.yaml +++ b/tests/integration/targets/vyos_lldp_interfaces/defaults/main.yaml @@ -1,3 +1,3 @@ --- -testcase: "[^_].*" +testcase: '[^_].*' test_items: [] diff --git a/tests/integration/targets/vyos_lldp_interfaces/tasks/cli.yaml b/tests/integration/targets/vyos_lldp_interfaces/tasks/cli.yaml index 655e51e..93eb2fe 100644 --- a/tests/integration/targets/vyos_lldp_interfaces/tasks/cli.yaml +++ b/tests/integration/targets/vyos_lldp_interfaces/tasks/cli.yaml @@ -1,8 +1,8 @@ --- - name: Collect all cli test cases find: - paths: "{{ role_path }}/tests/cli" - patterns: "{{ testcase }}.yaml" + paths: '{{ role_path }}/tests/cli' + patterns: '{{ testcase }}.yaml' use_regex: true register: test_cases delegate_to: localhost @@ -10,10 +10,10 @@ - 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 }}" +- name: Run test case (connection=ansible.netcommon.network_cli) + include: '{{ test_case_to_run }}' vars: - ansible_connection: network_cli - with_items: "{{ test_items }}" + 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_lldp_interfaces/tasks/main.yaml b/tests/integration/targets/vyos_lldp_interfaces/tasks/main.yaml index d4cf26f..a3db933 100644 --- a/tests/integration/targets/vyos_lldp_interfaces/tasks/main.yaml +++ b/tests/integration/targets/vyos_lldp_interfaces/tasks/main.yaml @@ -1,2 +1,4 @@ --- -- {include: cli.yaml, tags: ['cli']} +- include: cli.yaml + tags: + - cli diff --git a/tests/integration/targets/vyos_lldp_interfaces/tests/cli/_populate.yaml b/tests/integration/targets/vyos_lldp_interfaces/tests/cli/_populate.yaml index 80f7d1a..4353cec 100644 --- a/tests/integration/targets/vyos_lldp_interfaces/tests/cli/_populate.yaml +++ b/tests/integration/targets/vyos_lldp_interfaces/tests/cli/_populate.yaml @@ -1,14 +1,12 @@ --- - 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 + lines: "set service lldp interface eth1\nset service lldp interface eth1 location\ + \ civic-based country-code US\nset service lldp interface eth1 location civic-based\ + \ ca-type 0 ca-value ENGLISH\nset service lldp interface eth2\nset service\ + \ lldp interface eth2 location coordinate-based latitude 33.524449N\nset service\ + \ lldp interface eth2 location coordinate-based altitude 2200\nset service\ + \ lldp interface eth2 location coordinate-based datum WGS84\nset service lldp\ + \ interface eth2 location coordinate-based longitude 222.267255W\n" + ansible.netcommon.cli_config: + config: '{{ lines }}' diff --git a/tests/integration/targets/vyos_lldp_interfaces/tests/cli/_populate_intf.yaml b/tests/integration/targets/vyos_lldp_interfaces/tests/cli/_populate_intf.yaml index ee9a9bd..11e2940 100644 --- a/tests/integration/targets/vyos_lldp_interfaces/tests/cli/_populate_intf.yaml +++ b/tests/integration/targets/vyos_lldp_interfaces/tests/cli/_populate_intf.yaml @@ -1,10 +1,8 @@ --- - 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 + lines: "set service lldp interface eth2\nset service lldp interface eth2 location\ + \ civic-based country-code US\nset service lldp interface eth2 location civic-based\ + \ ca-type 0 ca-value ENGLISH\nset service lldp interface eth2 disable\n" + ansible.netcommon.cli_config: + config: '{{ lines }}' diff --git a/tests/integration/targets/vyos_lldp_interfaces/tests/cli/_remove_config.yaml b/tests/integration/targets/vyos_lldp_interfaces/tests/cli/_remove_config.yaml index d012f7b..a885f01 100644 --- a/tests/integration/targets/vyos_lldp_interfaces/tests/cli/_remove_config.yaml +++ b/tests/integration/targets/vyos_lldp_interfaces/tests/cli/_remove_config.yaml @@ -1,8 +1,6 @@ --- - name: Remove Config - network.cli.cli_config: - config: "{{ lines }}" vars: - lines: | - delete service lldp interface - delete service lldp + lines: "delete service lldp interface\ndelete service lldp\n" + ansible.netcommon.cli_config: + config: '{{ lines }}' diff --git a/tests/integration/targets/vyos_lldp_interfaces/tests/cli/deleted.yaml b/tests/integration/targets/vyos_lldp_interfaces/tests/cli/deleted.yaml index 7b2d53a..21bf96d 100644 --- a/tests/integration/targets/vyos_lldp_interfaces/tests/cli/deleted.yaml +++ b/tests/integration/targets/vyos_lldp_interfaces/tests/cli/deleted.yaml @@ -1,17 +1,21 @@ --- - debug: - msg: "Start vyos_lldp_interfaces deleted integration tests ansible_connection={{ ansible_connection }}" + 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 + register: result + vyos.vyos.vyos_lldp_interfaces: &id001 config: - - name: 'eth1' - - name: 'eth2' + + - name: eth1 + + - name: eth2 state: deleted - register: result - name: Assert that the before dicts were correctly generated assert: @@ -21,26 +25,30 @@ - name: Assert that the correct set of commands were generated assert: that: - - "{{ deleted['commands'] | symmetric_difference(result['commands']) |length == 0 }}" + - "{{ 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 }}" + - "{{ deleted['after'] | symmetric_difference(result['after']) |length\ + \ == 0 }}" - name: Delete attributes of given interfaces (IDEMPOTENT) - vyos.vyos.vyos_lldp_interfaces: *deleted register: result + vyos.vyos.vyos_lldp_interfaces: *id001 - name: Assert that the previous task was idempotent assert: that: - - "result.changed == false" - - "result.commands|length == 0" + - 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 }}" + - "{{ deleted['after'] | symmetric_difference(result['before']) |length\ + \ == 0 }}" always: + - include_tasks: _remove_config.yaml diff --git a/tests/integration/targets/vyos_lldp_interfaces/tests/cli/empty_config.yaml b/tests/integration/targets/vyos_lldp_interfaces/tests/cli/empty_config.yaml index 44c0b89..a5ff0a8 100644 --- a/tests/integration/targets/vyos_lldp_interfaces/tests/cli/empty_config.yaml +++ b/tests/integration/targets/vyos_lldp_interfaces/tests/cli/empty_config.yaml @@ -1,35 +1,36 @@ --- - debug: - msg: "START vyos_lldp_interfaces empty_config integration tests on connection={{ ansible_connection }}" + msg: START vyos_lldp_interfaces empty_config integration tests on connection={{ + ansible_connection }} - name: Merged with empty config should give appropriate error message + register: result + ignore_errors: true vyos.vyos.vyos_lldp_interfaces: config: state: merged - register: result - ignore_errors: true - 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_lldp_interfaces: config: state: replaced - register: result - ignore_errors: true - assert: that: - result.msg == 'value of config parameter must not be empty for state replaced' - name: Overridden with empty config should give appropriate error message + register: result + ignore_errors: true vyos.vyos.vyos_lldp_interfaces: config: state: overridden - register: result - ignore_errors: true - assert: that: diff --git a/tests/integration/targets/vyos_lldp_interfaces/tests/cli/merged.yaml b/tests/integration/targets/vyos_lldp_interfaces/tests/cli/merged.yaml index bf968b2..657961f 100644 --- a/tests/integration/targets/vyos_lldp_interfaces/tests/cli/merged.yaml +++ b/tests/integration/targets/vyos_lldp_interfaces/tests/cli/merged.yaml @@ -1,58 +1,67 @@ --- - debug: - msg: "START vyos_lldp_interfaces merged integration tests on connection={{ ansible_connection }}" + 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 + register: result + vyos.vyos.vyos_lldp_interfaces: &id001 config: - - name: 'eth1' + + - name: eth1 location: civic_based: - country_code: 'US' + country_code: US ca_info: + - ca_type: 0 - ca_value: 'ENGLISH' + ca_value: ENGLISH - - name: 'eth2' + - name: eth2 location: coordinate_based: altitude: 2200 - datum: 'WGS84' - longitude: '222.267255W' - latitude: '33.524449N' + 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 }}" + 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 }}" + - "{{ 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 }}" + - "{{ 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 + - name: Merge the provided configuration with the existing running configuration + (IDEMPOTENT) register: result + vyos.vyos.vyos_lldp_interfaces: *id001 - name: Assert that the previous task was idempotent assert: that: - - "result['changed'] == false" + - result['changed'] == false - name: Assert that before dicts were correctly generated assert: that: - - "{{ merged['after'] | symmetric_difference(result['before']) |length == 0 }}" - + - "{{ merged['after'] | symmetric_difference(result['before']) |length\ + \ == 0 }}" always: + - include_tasks: _remove_config.yaml diff --git a/tests/integration/targets/vyos_lldp_interfaces/tests/cli/overridden.yaml b/tests/integration/targets/vyos_lldp_interfaces/tests/cli/overridden.yaml index 8cf038c..3e6ce40 100644 --- a/tests/integration/targets/vyos_lldp_interfaces/tests/cli/overridden.yaml +++ b/tests/integration/targets/vyos_lldp_interfaces/tests/cli/overridden.yaml @@ -1,49 +1,56 @@ --- - debug: - msg: "START vyos_lldp_interfaces overridden integration tests on connection={{ ansible_connection }}" + 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 + register: result + vyos.vyos.vyos_lldp_interfaces: &id001 config: - - name: 'eth2' + + - name: eth2 location: - elin: '0000000911' + elin: 0000000911 state: overridden - register: result - name: Assert that before dicts were correctly generated assert: that: - - "{{ populate_intf | symmetric_difference(result['before']) |length == 0 }}" + - "{{ 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 }}" + - "{{ 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 }}" + - "{{ 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 + vyos.vyos.vyos_lldp_interfaces: *id001 - name: Assert that the previous task was idempotent assert: that: - - "result['changed'] == false" + - result['changed'] == false - name: Assert that before dicts were correctly generated assert: that: - - "{{ overridden['after'] | symmetric_difference(result['before']) |length == 0 }}" - + - "{{ overridden['after'] | symmetric_difference(result['before']) |length\ + \ == 0 }}" always: + - include_tasks: _remove_config.yaml diff --git a/tests/integration/targets/vyos_lldp_interfaces/tests/cli/replaced.yaml b/tests/integration/targets/vyos_lldp_interfaces/tests/cli/replaced.yaml index 17acf06..3218e80 100644 --- a/tests/integration/targets/vyos_lldp_interfaces/tests/cli/replaced.yaml +++ b/tests/integration/targets/vyos_lldp_interfaces/tests/cli/replaced.yaml @@ -1,39 +1,45 @@ --- - debug: - msg: "START vyos_lldp_interfaces replaced integration tests on connection={{ ansible_connection }}" + 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 + + - name: Replace device configurations of listed LLDP interfaces with provided + configurations + register: result + vyos.vyos.vyos_lldp_interfaces: &id001 config: - - name: 'eth2' + + - name: eth2 enable: false location: civic_based: - country_code: 'US' + country_code: US ca_info: + - ca_type: 0 - ca_value: 'ENGLISH' + ca_value: ENGLISH - - name: 'eth1' + - name: eth1 enable: false location: coordinate_based: altitude: 2200 - datum: 'WGS84' - longitude: '222.267255W' - latitude: '33.524449N' + 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 }}" + - "{{ replaced['commands'] | symmetric_difference(result['commands'])\ + \ |length == 0 }}" - name: Assert that before dicts are correctly generated assert: @@ -43,21 +49,24 @@ - name: Assert that after dict is correctly generated assert: that: - - "{{ replaced['after'] | symmetric_difference(result['after']) |length == 0 }}" + - "{{ 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 + - name: Replace device configurations of listed LLDP interfaces with provided + configurarions (IDEMPOTENT) register: result + vyos.vyos.vyos_lldp_interfaces: *id001 - name: Assert that task was idempotent assert: that: - - "result['changed'] == false" + - result['changed'] == false - name: Assert that before dict is correctly generated assert: that: - - "{{ replaced['after'] | symmetric_difference(result['before']) |length == 0 }}" - + - "{{ replaced['after'] | symmetric_difference(result['before']) |length\ + \ == 0 }}" always: + - include_tasks: _remove_config.yaml diff --git a/tests/integration/targets/vyos_lldp_interfaces/tests/cli/rtt.yaml b/tests/integration/targets/vyos_lldp_interfaces/tests/cli/rtt.yaml index 4d4cf82..e6189a3 100644 --- a/tests/integration/targets/vyos_lldp_interfaces/tests/cli/rtt.yaml +++ b/tests/integration/targets/vyos_lldp_interfaces/tests/cli/rtt.yaml @@ -1,23 +1,26 @@ --- - debug: - msg: "START vyos_lldp_interfaces round trip integration tests on connection={{ ansible_connection }}" + 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) + register: base_config vyos.vyos.vyos_lldp_interfaces: config: - - name: 'eth1' + + - name: eth1 location: civic_based: - country_code: 'US' + country_code: US ca_info: - - ca_type: 0 - ca_value: 'ENGLISH' + - ca_type: 0 + ca_value: ENGLISH state: merged - register: base_config - name: Gather lldp_interfaces facts vyos.vyos.vyos_facts: @@ -27,31 +30,34 @@ - lldp_interfaces - name: Apply the provided configuration (config to be reverted) + register: result vyos.vyos.vyos_lldp_interfaces: config: - - name: 'eth2' + + - name: eth2 location: coordinate_based: altitude: 2200 - datum: 'WGS84' - longitude: '222.267255W' - latitude: '33.524449N' + 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 }}" + that: "{{ round_trip['after'] | symmetric_difference(result['after']) |length\ + \ == 0 }}" - name: Revert back to base config using facts round trip + register: revert 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 }}" - + that: "{{ base_config['after'] | symmetric_difference(revert['after']) |length\ + \ == 0 }}" always: + - include_tasks: _remove_config.yaml diff --git a/tests/integration/targets/vyos_lldp_interfaces/vars/main.yaml b/tests/integration/targets/vyos_lldp_interfaces/vars/main.yaml index 169b0d5..3cb684e 100644 --- a/tests/integration/targets/vyos_lldp_interfaces/vars/main.yaml +++ b/tests/integration/targets/vyos_lldp_interfaces/vars/main.yaml @@ -1,130 +1,114 @@ --- 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" - + - 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' + - name: eth1 location: civic_based: - country_code: 'US' + country_code: US ca_info: - ca_type: 0 - ca_value: 'ENGLISH' - - - name: 'eth2' + ca_value: ENGLISH + - name: eth2 location: coordinate_based: altitude: 2200 - datum: 'WGS84' - longitude: '222.267255W' - latitude: '33.524449N' - + datum: WGS84 + longitude: 222.267255W + latitude: 33.524449N populate: - - name: 'eth1' + - name: eth1 location: civic_based: - country_code: 'US' + country_code: US ca_info: - ca_type: 0 - ca_value: 'ENGLISH' - - - name: 'eth2' + ca_value: ENGLISH + - name: eth2 location: coordinate_based: altitude: 2200 - datum: 'WGS84' - longitude: '222.267255W' - latitude: '33.524449N' - + 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'" - + - 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' + - name: eth2 enable: false location: civic_based: - country_code: 'US' + country_code: US ca_info: - ca_type: 0 - ca_value: 'ENGLISH' - - - name: 'eth1' + ca_value: ENGLISH + - name: eth1 enable: false location: coordinate_based: altitude: 2200 - datum: 'WGS84' - longitude: '222.267255W' - latitude: '33.524449N' - + datum: WGS84 + longitude: 222.267255W + latitude: 33.524449N populate_intf: - - name: 'eth2' + - name: eth2 enable: false location: civic_based: - country_code: 'US' + country_code: US ca_info: - ca_type: 0 - ca_value: 'ENGLISH' - + 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'" - + - delete service lldp interface eth2 location + - delete service lldp interface eth2 'disable' + - set service lldp interface eth2 location elin '0000000911' after: - - name: 'eth2' + - name: eth2 location: elin: 0000000911 - deleted: commands: - - "delete service lldp interface eth1" - - "delete service lldp interface eth2" - + - delete service lldp interface eth1 + - delete service lldp interface eth2 after: [] - round_trip: after: - - name: 'eth1' + - name: eth1 location: civic_based: - country_code: 'US' + country_code: US ca_info: - ca_type: 0 - ca_value: 'ENGLISH' - - - name: 'eth2' + ca_value: ENGLISH + - name: eth2 location: coordinate_based: altitude: 2200 - datum: 'WGS84' - longitude: '222.267255W' - latitude: '33.524449N' + datum: WGS84 + longitude: 222.267255W + latitude: 33.524449N diff --git a/tests/integration/targets/vyos_logging/defaults/main.yaml b/tests/integration/targets/vyos_logging/defaults/main.yaml index 9ef5ba5..a845c24 100644 --- a/tests/integration/targets/vyos_logging/defaults/main.yaml +++ b/tests/integration/targets/vyos_logging/defaults/main.yaml @@ -1,3 +1,3 @@ --- -testcase: "*" +testcase: '*' test_items: [] diff --git a/tests/integration/targets/vyos_logging/tasks/cli.yaml b/tests/integration/targets/vyos_logging/tasks/cli.yaml index 890d3ac..90f265f 100644 --- a/tests/integration/targets/vyos_logging/tasks/cli.yaml +++ b/tests/integration/targets/vyos_logging/tasks/cli.yaml @@ -1,22 +1,22 @@ --- - name: collect all cli test cases find: - paths: "{{ role_path }}/tests/cli" - patterns: "{{ testcase }}.yaml" + paths: '{{ role_path }}/tests/cli' + patterns: '{{ testcase }}.yaml' 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 }} ansible_connection=network_cli" - with_items: "{{ test_items }}" +- name: run test case (connection=ansible.netcommon.network_cli) + include: '{{ test_case_to_run }} ansible_connection=ansible.netcommon.network_cli' + with_items: '{{ test_items }}' loop_control: loop_var: test_case_to_run - name: run test case (connection=local) - include: "{{ test_case_to_run }} ansible_connection=local" - with_first_found: "{{ test_items }}" + include: '{{ test_case_to_run }} ansible_connection=local' + with_first_found: '{{ test_items }}' loop_control: loop_var: test_case_to_run diff --git a/tests/integration/targets/vyos_logging/tasks/main.yaml b/tests/integration/targets/vyos_logging/tasks/main.yaml index d4cf26f..a3db933 100644 --- a/tests/integration/targets/vyos_logging/tasks/main.yaml +++ b/tests/integration/targets/vyos_logging/tasks/main.yaml @@ -1,2 +1,4 @@ --- -- {include: cli.yaml, tags: ['cli']} +- include: cli.yaml + tags: + - cli diff --git a/tests/integration/targets/vyos_logging/tests/cli/basic.yaml b/tests/integration/targets/vyos_logging/tests/cli/basic.yaml index d588456..a025047 100644 --- a/tests/integration/targets/vyos_logging/tests/cli/basic.yaml +++ b/tests/integration/targets/vyos_logging/tests/cli/basic.yaml @@ -2,125 +2,154 @@ - debug: msg="START cli/basic.yaml on connection={{ ansible_connection }}" - name: set-up logging + register: result vyos.vyos.vyos_logging: dest: console facility: all level: info state: present - register: result - assert: that: - - 'result.changed == true' + - result.changed == true - '"set system syslog console facility all level info" in result.commands' - name: set-up logging again (idempotent) + register: result vyos.vyos.vyos_logging: dest: console facility: all level: info state: present - register: result - assert: that: - - 'result.changed == false' + - result.changed == false - name: file logging + register: result vyos.vyos.vyos_logging: dest: file name: test facility: all level: notice state: present - register: result - assert: that: - - 'result.changed == true' + - result.changed == true - '"set system syslog file test facility all level notice" in result.commands' - name: file logging again (idempotent) + register: result vyos.vyos.vyos_logging: dest: file name: test facility: all level: notice state: present - register: result - assert: that: - - 'result.changed == false' + - result.changed == false - name: delete logging + register: result vyos.vyos.vyos_logging: dest: file name: test facility: all level: notice state: absent - register: result - assert: that: - - 'result.changed == true' + - result.changed == true - '"delete system syslog file test facility all level notice" in result.commands' - name: delete logging again (idempotent) + register: result vyos.vyos.vyos_logging: dest: file name: test facility: all level: notice state: absent - register: result - assert: that: - - 'result.changed == false' + - result.changed == false - name: Add logging collections + register: result vyos.vyos.vyos_logging: aggregate: - - {dest: file, name: test1, facility: all, level: info} - - {dest: file, name: test2, facility: news, level: debug} + + - dest: file + name: test1 + facility: all + level: info + + - dest: file + name: test2 + facility: news + level: debug state: present - register: result - assert: that: - - 'result.changed == true' + - result.changed == true - '"set system syslog file test1 facility all level info" in result.commands' - '"set system syslog file test2 facility news level debug" in result.commands' - name: Add and remove logging collections with overrides + register: result vyos.vyos.vyos_logging: aggregate: - - {dest: console, facility: all, level: info} - - {dest: file, name: test1, facility: all, level: info, state: absent} - - {dest: console, facility: daemon, level: warning} + + - dest: console + facility: all + level: info + + - dest: file + name: test1 + facility: all + level: info + state: absent + + - dest: console + facility: daemon + level: warning state: present - register: result - assert: that: - - 'result.changed == true' + - result.changed == true - '"delete system syslog file test1 facility all level info" in result.commands' - '"set system syslog console facility daemon level warning" in result.commands' - name: Remove logging collections + register: result vyos.vyos.vyos_logging: aggregate: - - {dest: console, facility: all, level: info} - - {dest: console, facility: daemon, level: warning} - - {dest: file, name: test2, facility: news, level: debug} + + - dest: console + facility: all + level: info + + - dest: console + facility: daemon + level: warning + + - dest: file + name: test2 + facility: news + level: debug state: absent - register: result - assert: that: - - 'result.changed == true' + - result.changed == true - '"delete system syslog console facility all level info" in result.commands' - '"delete system syslog console facility daemon level warning" in result.commands' - '"delete system syslog file test2 facility news level debug" in result.commands' diff --git a/tests/integration/targets/vyos_logging/tests/cli/net_logging.yaml b/tests/integration/targets/vyos_logging/tests/cli/net_logging.yaml index 7c62d72..f8bda74 100644 --- a/tests/integration/targets/vyos_logging/tests/cli/net_logging.yaml +++ b/tests/integration/targets/vyos_logging/tests/cli/net_logging.yaml @@ -1,39 +1,38 @@ --- -- debug: msg="START vyos cli/net_logging.yaml on connection={{ ansible_connection }}" - -# Add minimal testcase to check args are passed correctly to -# implementation module and module run is successful. +- debug: msg="START vyos cli/net_logging.yaml on connection={{ ansible_connection + }}" - name: delete logging - setup - net_logging: + register: result + ansible.netcommon.net_logging: dest: file name: test facility: all level: notice state: absent - register: result - name: file logging using platform agnostic module - net_logging: + register: result + ansible.netcommon.net_logging: dest: file name: test facility: all level: notice state: present - register: result - assert: that: - - 'result.changed == true' + - result.changed == true - '"set system syslog file test facility all level notice" in result.commands' - name: delete logging - teardown - net_logging: + register: result + ansible.netcommon.net_logging: dest: file name: test facility: all level: notice state: absent - register: result -- debug: msg="END vyos cli/net_logging.yaml on connection={{ ansible_connection }}" +- debug: msg="END vyos cli/net_logging.yaml on connection={{ ansible_connection + }}" diff --git a/tests/integration/targets/vyos_smoke/defaults/main.yaml b/tests/integration/targets/vyos_smoke/defaults/main.yaml deleted file mode 100644 index 9ef5ba5..0000000 --- a/tests/integration/targets/vyos_smoke/defaults/main.yaml +++ /dev/null @@ -1,3 +0,0 @@ ---- -testcase: "*" -test_items: [] diff --git a/tests/integration/targets/vyos_smoke/tasks/cli.yaml b/tests/integration/targets/vyos_smoke/tasks/cli.yaml deleted file mode 100644 index 890d3ac..0000000 --- a/tests/integration/targets/vyos_smoke/tasks/cli.yaml +++ /dev/null @@ -1,22 +0,0 @@ ---- -- name: collect all cli test cases - find: - paths: "{{ role_path }}/tests/cli" - patterns: "{{ testcase }}.yaml" - 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 }} ansible_connection=network_cli" - with_items: "{{ test_items }}" - loop_control: - loop_var: test_case_to_run - -- name: run test case (connection=local) - include: "{{ test_case_to_run }} ansible_connection=local" - with_first_found: "{{ test_items }}" - loop_control: - loop_var: test_case_to_run diff --git a/tests/integration/targets/vyos_smoke/tasks/main.yaml b/tests/integration/targets/vyos_smoke/tasks/main.yaml deleted file mode 100644 index d4cf26f..0000000 --- a/tests/integration/targets/vyos_smoke/tasks/main.yaml +++ /dev/null @@ -1,2 +0,0 @@ ---- -- {include: cli.yaml, tags: ['cli']} diff --git a/tests/integration/targets/vyos_smoke/tests/cli/common_config.yaml b/tests/integration/targets/vyos_smoke/tests/cli/common_config.yaml deleted file mode 100644 index cfac254..0000000 --- a/tests/integration/targets/vyos_smoke/tests/cli/common_config.yaml +++ /dev/null @@ -1,11 +0,0 @@ ---- -# vyos.py in plugins and module_utils/network covered by these as well -# hit NetworkConfig -- name: configure simple config command - vyos.vyos.vyos_config: - lines: set system host-name smoke - -- name: return host name to inventory_hostname - vyos.vyos.vyos_config: - lines: set system host-name {{ inventory_hostname_short }} - match: none diff --git a/tests/integration/targets/vyos_smoke/tests/cli/common_utils.yaml b/tests/integration/targets/vyos_smoke/tests/cli/common_utils.yaml deleted file mode 100644 index fb80c93..0000000 --- a/tests/integration/targets/vyos_smoke/tests/cli/common_utils.yaml +++ /dev/null @@ -1,50 +0,0 @@ ---- -# vyos.py in plugins and module_utils/network covered by these as well -# remove_default_spec() hit by multiple plays - -# hit ComplexList -- name: get output for single command - vyos.vyos.vyos_command: - commands: - - show version - register: result - -- assert: - that: - - result.changed == false - - result.stdout is defined - - result.stdout_lines is defined - -# hit conditional() - used for declarative intent -# Note, this can't be run on AWS because fully testing the vyos_interface dependencies -# requires the ability to create and remove interfaces other than eth0 -- name: enable eth1 - vyos.vyos.vyos_interface: - name: eth1 - enabled: true - state: present - register: result - -- name: Check intent arguments - vyos.vyos.vyos_interface: - name: eth1 - state: up - register: result - -- name: Check intent arguments (failed condition) - vyos.vyos.vyos_interface: - name: eth1 - state: down - ignore_errors: true - register: result - -- assert: - that: - - "result.failed == true" - - "'state eq(down)' in result.failed_conditions" - -- name: Config + intent - vyos.vyos.vyos_interface: - name: eth1 - enabled: false - state: down diff --git a/tests/integration/targets/vyos_smoke/tests/cli/misc_tests.yaml b/tests/integration/targets/vyos_smoke/tests/cli/misc_tests.yaml deleted file mode 100644 index 456effc..0000000 --- a/tests/integration/targets/vyos_smoke/tests/cli/misc_tests.yaml +++ /dev/null @@ -1,14 +0,0 @@ ---- -# hit check conditional in module_utils.network.vyos -> load_config() -- name: configure simple config command - vyos.vyos.vyos_config: - lines: set system host-name check-test - check_mode: true - -- name: get host name - vyos.vyos.vyos_command: - commands: show host name - register: result - -- assert: - that: '"check-test" not in result.stdout' diff --git a/tests/integration/targets/vyos_static_route/defaults/main.yaml b/tests/integration/targets/vyos_static_route/defaults/main.yaml index 9ef5ba5..a845c24 100644 --- a/tests/integration/targets/vyos_static_route/defaults/main.yaml +++ b/tests/integration/targets/vyos_static_route/defaults/main.yaml @@ -1,3 +1,3 @@ --- -testcase: "*" +testcase: '*' test_items: [] diff --git a/tests/integration/targets/vyos_static_route/tasks/cli.yaml b/tests/integration/targets/vyos_static_route/tasks/cli.yaml index 890d3ac..90f265f 100644 --- a/tests/integration/targets/vyos_static_route/tasks/cli.yaml +++ b/tests/integration/targets/vyos_static_route/tasks/cli.yaml @@ -1,22 +1,22 @@ --- - name: collect all cli test cases find: - paths: "{{ role_path }}/tests/cli" - patterns: "{{ testcase }}.yaml" + paths: '{{ role_path }}/tests/cli' + patterns: '{{ testcase }}.yaml' 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 }} ansible_connection=network_cli" - with_items: "{{ test_items }}" +- name: run test case (connection=ansible.netcommon.network_cli) + include: '{{ test_case_to_run }} ansible_connection=ansible.netcommon.network_cli' + with_items: '{{ test_items }}' loop_control: loop_var: test_case_to_run - name: run test case (connection=local) - include: "{{ test_case_to_run }} ansible_connection=local" - with_first_found: "{{ test_items }}" + include: '{{ test_case_to_run }} ansible_connection=local' + with_first_found: '{{ test_items }}' loop_control: loop_var: test_case_to_run diff --git a/tests/integration/targets/vyos_static_route/tasks/main.yaml b/tests/integration/targets/vyos_static_route/tasks/main.yaml index d4cf26f..a3db933 100644 --- a/tests/integration/targets/vyos_static_route/tasks/main.yaml +++ b/tests/integration/targets/vyos_static_route/tasks/main.yaml @@ -1,2 +1,4 @@ --- -- {include: cli.yaml, tags: ['cli']} +- include: cli.yaml + tags: + - cli diff --git a/tests/integration/targets/vyos_static_route/tests/cli/basic.yaml b/tests/integration/targets/vyos_static_route/tests/cli/basic.yaml index 4b1ef1c..be93e89 100644 --- a/tests/integration/targets/vyos_static_route/tests/cli/basic.yaml +++ b/tests/integration/targets/vyos_static_route/tests/cli/basic.yaml @@ -2,119 +2,136 @@ - debug: msg="START cli/basic.yaml on connection={{ ansible_connection }}" - name: create static route + register: result vyos.vyos.vyos_static_route: prefix: 172.24.0.0/24 next_hop: 192.168.42.64 state: present - register: result - assert: that: - - 'result.changed == true' + - result.changed == true - '"set protocols static route 172.24.0.0/24 next-hop 192.168.42.64" in result.commands' - name: create static route again (idempotent) + register: result vyos.vyos.vyos_static_route: prefix: 172.24.0.0 mask: 24 next_hop: 192.168.42.64 state: present - register: result - assert: that: - - 'result.changed == false' + - result.changed == false - name: modify admin distance of static route + register: result vyos.vyos.vyos_static_route: prefix: 172.24.0.0/24 next_hop: 192.168.42.64 admin_distance: 1 state: present - register: result - assert: that: - - 'result.changed == true' - - '"set protocols static route 172.24.0.0/24 next-hop 192.168.42.64 distance 1" in result.commands' + - result.changed == true + - '"set protocols static route 172.24.0.0/24 next-hop 192.168.42.64 distance + 1" in result.commands' - name: modify admin distance of static route again (idempotent) + register: result vyos.vyos.vyos_static_route: prefix: 172.24.0.0 mask: 24 next_hop: 192.168.42.64 admin_distance: 1 state: present - register: result - assert: that: - - 'result.changed == false' + - result.changed == false - name: delete static route + register: result vyos.vyos.vyos_static_route: prefix: 172.24.0.0/24 next_hop: 192.168.42.64 admin_distance: 1 state: absent - register: result - assert: that: - - 'result.changed == true' + - result.changed == true - '"delete protocols static route 172.24.0.0/24" in result.commands' - name: delete static route again (idempotent) + register: result vyos.vyos.vyos_static_route: prefix: 172.24.0.0/24 next_hop: 192.168.42.64 admin_distance: 1 state: absent - register: result - assert: that: - - 'result.changed == false' + - result.changed == false - name: Add static route collections + register: result vyos.vyos.vyos_static_route: aggregate: - - {prefix: 172.24.1.0/24, next_hop: 192.168.42.64} - - {prefix: 172.24.2.0, mask: 24, next_hop: 192.168.42.64} + + - prefix: 172.24.1.0/24 + next_hop: 192.168.42.64 + + - prefix: 172.24.2.0 + mask: 24 + next_hop: 192.168.42.64 state: present - register: result - assert: that: - - 'result.changed == true' + - result.changed == true - '"set protocols static route 172.24.1.0/24 next-hop 192.168.42.64" in result.commands' - '"set protocols static route 172.24.2.0/24 next-hop 192.168.42.64" in result.commands' - name: Add and remove static route collections with overrides + register: result vyos.vyos.vyos_static_route: aggregate: - - {prefix: 172.24.1.0/24, next_hop: 192.168.42.64} - - {prefix: 172.24.2.0/24, next_hop: 192.168.42.64, state: absent} - - {prefix: 172.24.3.0/24, next_hop: 192.168.42.64} + + - prefix: 172.24.1.0/24 + next_hop: 192.168.42.64 + + - prefix: 172.24.2.0/24 + next_hop: 192.168.42.64 + state: absent + + - prefix: 172.24.3.0/24 + next_hop: 192.168.42.64 state: present - register: result - assert: that: - - 'result.changed == true' + - result.changed == true - '"delete protocols static route 172.24.2.0/24" in result.commands' - '"set protocols static route 172.24.3.0/24 next-hop 192.168.42.64" in result.commands' - name: Remove static route collections + register: result vyos.vyos.vyos_static_route: aggregate: - - {prefix: 172.24.1.0/24, next_hop: 192.168.42.64} - - {prefix: 172.24.3.0/24, next_hop: 192.168.42.64} + + - prefix: 172.24.1.0/24 + next_hop: 192.168.42.64 + + - prefix: 172.24.3.0/24 + next_hop: 192.168.42.64 state: absent - register: result - assert: that: - - 'result.changed == true' + - result.changed == true - '"delete protocols static route 172.24.1.0/24" in result.commands' - '"delete protocols static route 172.24.3.0/24" in result.commands' diff --git a/tests/integration/targets/vyos_static_route/tests/cli/net_static_route.yaml b/tests/integration/targets/vyos_static_route/tests/cli/net_static_route.yaml index e2529eb..c53c838 100644 --- a/tests/integration/targets/vyos_static_route/tests/cli/net_static_route.yaml +++ b/tests/integration/targets/vyos_static_route/tests/cli/net_static_route.yaml @@ -1,33 +1,32 @@ --- -- debug: msg="START vyos cli/net_static_route.yaml on connection={{ ansible_connection }}" - -# Add minimal testcase to check args are passed correctly to -# implementation module and module run is successful. +- debug: msg="START vyos cli/net_static_route.yaml on connection={{ ansible_connection + }}" - name: delete static route - setup - net_static_route: + register: result + ansible.netcommon.net_static_route: prefix: 172.24.0.0/24 next_hop: 192.168.42.64 state: absent - register: result - name: create static route using platform agnostic module - net_static_route: + register: result + ansible.netcommon.net_static_route: prefix: 172.24.0.0/24 next_hop: 192.168.42.64 state: present - register: result - assert: that: - - 'result.changed == true' + - result.changed == true - '"set protocols static route 172.24.0.0/24 next-hop 192.168.42.64" in result.commands' - name: delete static route - teardown - net_static_route: + register: result + ansible.netcommon.net_static_route: prefix: 172.24.0.0/24 next_hop: 192.168.42.64 state: absent - register: result -- debug: msg="END vyos cli/net_static_route.yaml on connection={{ ansible_connection }}" +- debug: msg="END vyos cli/net_static_route.yaml on connection={{ ansible_connection + }}" diff --git a/tests/integration/targets/vyos_system/defaults/main.yaml b/tests/integration/targets/vyos_system/defaults/main.yaml index 9ef5ba5..a845c24 100644 --- a/tests/integration/targets/vyos_system/defaults/main.yaml +++ b/tests/integration/targets/vyos_system/defaults/main.yaml @@ -1,3 +1,3 @@ --- -testcase: "*" +testcase: '*' test_items: [] diff --git a/tests/integration/targets/vyos_system/tasks/cli.yaml b/tests/integration/targets/vyos_system/tasks/cli.yaml index 890d3ac..90f265f 100644 --- a/tests/integration/targets/vyos_system/tasks/cli.yaml +++ b/tests/integration/targets/vyos_system/tasks/cli.yaml @@ -1,22 +1,22 @@ --- - name: collect all cli test cases find: - paths: "{{ role_path }}/tests/cli" - patterns: "{{ testcase }}.yaml" + paths: '{{ role_path }}/tests/cli' + patterns: '{{ testcase }}.yaml' 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 }} ansible_connection=network_cli" - with_items: "{{ test_items }}" +- name: run test case (connection=ansible.netcommon.network_cli) + include: '{{ test_case_to_run }} ansible_connection=ansible.netcommon.network_cli' + with_items: '{{ test_items }}' loop_control: loop_var: test_case_to_run - name: run test case (connection=local) - include: "{{ test_case_to_run }} ansible_connection=local" - with_first_found: "{{ test_items }}" + include: '{{ test_case_to_run }} ansible_connection=local' + with_first_found: '{{ test_items }}' loop_control: loop_var: test_case_to_run diff --git a/tests/integration/targets/vyos_system/tasks/main.yaml b/tests/integration/targets/vyos_system/tasks/main.yaml index d4cf26f..a3db933 100644 --- a/tests/integration/targets/vyos_system/tasks/main.yaml +++ b/tests/integration/targets/vyos_system/tasks/main.yaml @@ -1,2 +1,4 @@ --- -- {include: cli.yaml, tags: ['cli']} +- include: cli.yaml + tags: + - cli diff --git a/tests/integration/targets/vyos_system/tests/cli/basic.yaml b/tests/integration/targets/vyos_system/tests/cli/basic.yaml index 474042f..9c3c09f 100644 --- a/tests/integration/targets/vyos_system/tests/cli/basic.yaml +++ b/tests/integration/targets/vyos_system/tests/cli/basic.yaml @@ -10,12 +10,12 @@ match: none - name: configure name servers + register: result vyos.vyos.vyos_system: name_servers: - 192.0.2.1 - 192.0.2.2 - 192.0.2.3 - register: result - assert: that: @@ -26,23 +26,23 @@ - result.commands[2] is search("set system name-server '192.0.2.3'") - name: verify name_servers + register: result vyos.vyos.vyos_system: name_servers: - 192.0.2.1 - 192.0.2.2 - 192.0.2.3 - register: result - assert: that: - result.changed == false - name: remove one + register: result vyos.vyos.vyos_system: name_servers: - 192.0.2.3 state: absent - register: result - assert: that: diff --git a/tests/integration/targets/vyos_system/tests/cli/net_system.yaml b/tests/integration/targets/vyos_system/tests/cli/net_system.yaml index 3688866..3e68d20 100644 --- a/tests/integration/targets/vyos_system/tests/cli/net_system.yaml +++ b/tests/integration/targets/vyos_system/tests/cli/net_system.yaml @@ -1,8 +1,6 @@ --- -- debug: msg="START vyos cli/net_system.yaml on connection={{ ansible_connection }}" - -# Add minimal testcase to check args are passed correctly to -# implementation module and module run is successful. +- debug: msg="START vyos cli/net_system.yaml on connection={{ ansible_connection + }}" - name: setup vyos.vyos.vyos_config: @@ -11,10 +9,10 @@ match: none - name: configure name servers using platform agnostic module - net_system: + register: result + ansible.netcommon.net_system: name_servers: - 192.0.2.1 - register: result - assert: that: diff --git a/tests/integration/targets/vyos_user/defaults/main.yaml b/tests/integration/targets/vyos_user/defaults/main.yaml index 9ef5ba5..a845c24 100644 --- a/tests/integration/targets/vyos_user/defaults/main.yaml +++ b/tests/integration/targets/vyos_user/defaults/main.yaml @@ -1,3 +1,3 @@ --- -testcase: "*" +testcase: '*' test_items: [] diff --git a/tests/integration/targets/vyos_user/tasks/cli.yaml b/tests/integration/targets/vyos_user/tasks/cli.yaml index 890d3ac..90f265f 100644 --- a/tests/integration/targets/vyos_user/tasks/cli.yaml +++ b/tests/integration/targets/vyos_user/tasks/cli.yaml @@ -1,22 +1,22 @@ --- - name: collect all cli test cases find: - paths: "{{ role_path }}/tests/cli" - patterns: "{{ testcase }}.yaml" + paths: '{{ role_path }}/tests/cli' + patterns: '{{ testcase }}.yaml' 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 }} ansible_connection=network_cli" - with_items: "{{ test_items }}" +- name: run test case (connection=ansible.netcommon.network_cli) + include: '{{ test_case_to_run }} ansible_connection=ansible.netcommon.network_cli' + with_items: '{{ test_items }}' loop_control: loop_var: test_case_to_run - name: run test case (connection=local) - include: "{{ test_case_to_run }} ansible_connection=local" - with_first_found: "{{ test_items }}" + include: '{{ test_case_to_run }} ansible_connection=local' + with_first_found: '{{ test_items }}' loop_control: loop_var: test_case_to_run diff --git a/tests/integration/targets/vyos_user/tasks/main.yaml b/tests/integration/targets/vyos_user/tasks/main.yaml index d4cf26f..a3db933 100644 --- a/tests/integration/targets/vyos_user/tasks/main.yaml +++ b/tests/integration/targets/vyos_user/tasks/main.yaml @@ -1,2 +1,4 @@ --- -- {include: cli.yaml, tags: ['cli']} +- include: cli.yaml + tags: + - cli diff --git a/tests/integration/targets/vyos_user/tests/cli/auth.yaml b/tests/integration/targets/vyos_user/tests/cli/auth.yaml index bbd67bc..bc4e788 100644 --- a/tests/integration/targets/vyos_user/tests/cli/auth.yaml +++ b/tests/integration/targets/vyos_user/tests/cli/auth.yaml @@ -1,34 +1,39 @@ --- - block: - - name: Create user with password - vyos.vyos.vyos_user: - name: auth_user - role: admin - state: present - configured_password: pass123 - - name: test login via ssh with new user - expect: - command: "ssh auth_user@{{ ansible_ssh_host }} -p {{ ansible_port | default(22) }} -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no '/opt/vyatta/sbin/vyatta-cfg-cmd-wrapper show version'" - responses: - (?i)password: "pass123" + - name: Create user with password + vyos.vyos.vyos_user: + name: auth_user + role: admin + state: present + configured_password: pass123 - - name: test login via ssh with invalid password (should fail) - expect: - command: "ssh auth_user@{{ ansible_ssh_host }} -p {{ ansible_port | default(22) }} -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no '/opt/vyatta/sbin/vyatta-cfg-cmd-wrapper show version'" - responses: - (?i)password: "badpass" - ignore_errors: true - register: results + - name: test login via ssh with new user + expect: + command: ssh auth_user@{{ ansible_ssh_host }} -p {{ ansible_port | default(22) + }} -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no '/opt/vyatta/sbin/vyatta-cfg-cmd-wrapper + show version' + responses: + (?i)password: pass123 - - name: check that attempt failed - assert: - that: - - results.failed + - name: test login via ssh with invalid password (should fail) + expect: + command: ssh auth_user@{{ ansible_ssh_host }} -p {{ ansible_port | default(22) + }} -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no '/opt/vyatta/sbin/vyatta-cfg-cmd-wrapper + show version' + responses: + (?i)password: badpass + ignore_errors: true + register: results + - name: check that attempt failed + assert: + that: + - results.failed always: + - name: delete user + register: result vyos.vyos.vyos_user: name: auth_user state: absent - register: result diff --git a/tests/integration/targets/vyos_user/tests/cli/basic.yaml b/tests/integration/targets/vyos_user/tests/cli/basic.yaml index a71f9c6..00a7a26 100644 --- a/tests/integration/targets/vyos_user/tests/cli/basic.yaml +++ b/tests/integration/targets/vyos_user/tests/cli/basic.yaml @@ -9,69 +9,78 @@ - delete system login user ansibletest3 - name: Create user + register: result vyos.vyos.vyos_user: name: ansibletest1 configured_password: test state: present - register: result - assert: that: - - 'result.changed == true' + - result.changed == true - '"set system login user" in result.commands[0]' - '"authentication plaintext-password" in result.commands[0]' - name: Collection of users (SetUp) + register: result vyos.vyos.vyos_user: aggregate: + - name: ansibletest2 + - name: ansibletest3 level: operator state: present - register: result - assert: that: - - 'result.changed == true' - - 'result.commands == ["set system login user ansibletest2 level operator", "set system login user ansibletest3 level operator"]' + - result.changed == true + - result.commands == ["set system login user ansibletest2 level operator", + "set system login user ansibletest3 level operator"] - name: Add user again (Idempotent) + register: result vyos.vyos.vyos_user: name: ansibletest1 configured_password: test state: present update_password: on_create - register: result - assert: that: - - 'result.changed == false' - - 'result.commands | length == 0' + - result.changed == false + - result.commands | length == 0 - name: Add collection of users (Idempotent) + register: result vyos.vyos.vyos_user: aggregate: + - name: ansibletest2 + - name: ansibletest3 level: operator state: present - register: result - assert: that: - - 'result.changed == false' - - 'result.commands | length == 0' + - result.changed == false + - result.commands | length == 0 - name: tearDown + register: result vyos.vyos.vyos_user: users: + - name: ansibletest1 + - name: ansibletest2 + - name: ansibletest3 state: absent - register: result - assert: that: - - 'result.changed == true' - - 'result.commands == ["delete system login user ansibletest1", "delete system login user ansibletest2", "delete system login user ansibletest3"]' + - result.changed == true + - result.commands == ["delete system login user ansibletest1", "delete system + login user ansibletest2", "delete system login user ansibletest3"] diff --git a/tests/integration/targets/vyos_vlan/defaults/main.yaml b/tests/integration/targets/vyos_vlan/defaults/main.yaml index 9ef5ba5..a845c24 100644 --- a/tests/integration/targets/vyos_vlan/defaults/main.yaml +++ b/tests/integration/targets/vyos_vlan/defaults/main.yaml @@ -1,3 +1,3 @@ --- -testcase: "*" +testcase: '*' test_items: [] diff --git a/tests/integration/targets/vyos_vlan/tasks/cli.yaml b/tests/integration/targets/vyos_vlan/tasks/cli.yaml index 890d3ac..90f265f 100644 --- a/tests/integration/targets/vyos_vlan/tasks/cli.yaml +++ b/tests/integration/targets/vyos_vlan/tasks/cli.yaml @@ -1,22 +1,22 @@ --- - name: collect all cli test cases find: - paths: "{{ role_path }}/tests/cli" - patterns: "{{ testcase }}.yaml" + paths: '{{ role_path }}/tests/cli' + patterns: '{{ testcase }}.yaml' 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 }} ansible_connection=network_cli" - with_items: "{{ test_items }}" +- name: run test case (connection=ansible.netcommon.network_cli) + include: '{{ test_case_to_run }} ansible_connection=ansible.netcommon.network_cli' + with_items: '{{ test_items }}' loop_control: loop_var: test_case_to_run - name: run test case (connection=local) - include: "{{ test_case_to_run }} ansible_connection=local" - with_first_found: "{{ test_items }}" + include: '{{ test_case_to_run }} ansible_connection=local' + with_first_found: '{{ test_items }}' loop_control: loop_var: test_case_to_run diff --git a/tests/integration/targets/vyos_vlan/tasks/main.yaml b/tests/integration/targets/vyos_vlan/tasks/main.yaml index d4cf26f..a3db933 100644 --- a/tests/integration/targets/vyos_vlan/tasks/main.yaml +++ b/tests/integration/targets/vyos_vlan/tasks/main.yaml @@ -1,2 +1,4 @@ --- -- {include: cli.yaml, tags: ['cli']} +- include: cli.yaml + tags: + - cli diff --git a/tests/integration/targets/vyos_vlan/tests/cli/basic.yaml b/tests/integration/targets/vyos_vlan/tests/cli/basic.yaml index cb0f348..eade5a4 100644 --- a/tests/integration/targets/vyos_vlan/tests/cli/basic.yaml +++ b/tests/integration/targets/vyos_vlan/tests/cli/basic.yaml @@ -11,86 +11,92 @@ - delete interfaces ethernet eth1 vif 201 - name: set vlan with name - vyos.vyos.vyos_vlan: &name + register: result + vyos.vyos.vyos_vlan: &id001 vlan_id: 100 name: vlan-100 interfaces: eth1 - register: result - assert: that: - - "result.changed == true" + - result.changed == true - "'set interfaces ethernet eth1 vif 100 description vlan-100' in result.commands" - name: set vlan with name(idempotence) - vyos.vyos.vyos_vlan: *name register: result + vyos.vyos.vyos_vlan: *id001 - assert: that: - - "result.changed == false" + - result.changed == false - name: set vlan with address - vyos.vyos.vyos_vlan: &address + register: result + vyos.vyos.vyos_vlan: &id002 vlan_id: 5 address: 192.168.5.12/24 interfaces: eth0 - register: result - assert: that: - - "result.changed == true" + - result.changed == true - "'set interfaces ethernet eth0 vif 5 address 192.168.5.12/24' in result.commands" - name: set vlan with address(idempotence) - vyos.vyos.vyos_vlan: *address register: result + vyos.vyos.vyos_vlan: *id002 - assert: that: - - "result.changed == false" + - result.changed == false - name: delete - vyos.vyos.vyos_vlan: &delete + register: result + vyos.vyos.vyos_vlan: &id003 vlan_id: 100 interfaces: eth1 state: absent - register: result - assert: that: - - "result.changed == true" + - result.changed == true - "'delete interfaces ethernet eth1 vif 100' in result.commands" - name: delete(idempotence) - vyos.vyos.vyos_vlan: *delete register: result + vyos.vyos.vyos_vlan: *id003 - assert: that: - - "result.changed == false" + - result.changed == false - name: Create VLANs using aggregate - vyos.vyos.vyos_vlan: &agg_vlan + register: result + vyos.vyos.vyos_vlan: &id004 aggregate: - - {vlan_id: 101, name: voice, interfaces: "eth0"} - - {vlan_id: 201, name: mgm, interfaces: "eth1"} + + - vlan_id: 101 + name: voice + interfaces: eth0 + + - vlan_id: 201 + name: mgm + interfaces: eth1 state: present - register: result - assert: that: - - "result.changed == true" + - result.changed == true - "'set interfaces ethernet eth0 vif 101 description voice' in result.commands" - "'set interfaces ethernet eth1 vif 201 description mgm' in result.commands" - name: Create VLANs using aggregate (idempotent) - vyos.vyos.vyos_vlan: *agg_vlan register: result + vyos.vyos.vyos_vlan: *id004 - assert: that: - - "result.changed == false" + - result.changed == false - name: teardown vyos.vyos.vyos_config: diff --git a/tests/integration/targets/vyos_vlan/tests/cli/intent.yaml b/tests/integration/targets/vyos_vlan/tests/cli/intent.yaml index 4a12317..f180d17 100644 --- a/tests/integration/targets/vyos_vlan/tests/cli/intent.yaml +++ b/tests/integration/targets/vyos_vlan/tests/cli/intent.yaml @@ -2,58 +2,58 @@ - debug: msg="START cli/intent.yaml on connection={{ ansible_connection }}" - name: setup - remove vlan used in test - vyos.vyos.vyos_config: &delete + vyos.vyos.vyos_config: lines: - delete interfaces ethernet eth1 vif 100 - delete interfaces ethernet eth0 vif 100 - name: set vlan with name + register: result vyos.vyos.vyos_vlan: vlan_id: 100 name: vlan-100 interfaces: eth1 - register: result - assert: that: - - "result.changed == true" + - result.changed == true - "'set interfaces ethernet eth1 vif 100 description vlan-100' in result.commands" - name: check vlan interface intent + register: result vyos.vyos.vyos_vlan: vlan_id: 100 name: vlan-100 associated_interfaces: eth1 - register: result - assert: that: - - "result.failed == false" + - result.failed == false - name: vlan interface config + intent + register: result vyos.vyos.vyos_vlan: vlan_id: 100 interfaces: eth0 associated_interfaces: - eth0 - eth1 - register: result - assert: that: - - "result.failed == false" + - result.failed == false - name: vlan intent fail + register: result + ignore_errors: true vyos.vyos.vyos_vlan: vlan_id: 100 associated_interfaces: - eth3 - eth4 - register: result - ignore_errors: true - assert: that: - - "result.failed == True" + - result.failed == True - debug: msg="End cli/intent.yaml on connection={{ ansible_connection }}" diff --git a/tests/integration/targets/vyos_vlan/tests/cli/multiple.yaml b/tests/integration/targets/vyos_vlan/tests/cli/multiple.yaml index 53e93fd..2059a43 100644 --- a/tests/integration/targets/vyos_vlan/tests/cli/multiple.yaml +++ b/tests/integration/targets/vyos_vlan/tests/cli/multiple.yaml @@ -9,49 +9,49 @@ - delete interfaces ethernet eth1 vif 100 - name: Add multiple interfaces to vlan - vyos.vyos.vyos_vlan: &multiple + register: result + vyos.vyos.vyos_vlan: &id001 vlan_id: 100 interfaces: - eth0 - eth1 - register: result - assert: that: - - "result.changed == true" + - result.changed == true - "'set interfaces ethernet eth0 vif 100' in result.commands" - "'set interfaces ethernet eth1 vif 100' in result.commands" - name: Add multiple interfaces to vlan(idempotence) - vyos.vyos.vyos_vlan: *multiple register: result + vyos.vyos.vyos_vlan: *id001 - assert: that: - - "result.changed == false" + - result.changed == false - name: delete vlan with multiple interfaces - vyos.vyos.vyos_vlan: &delete_multiple + register: result + vyos.vyos.vyos_vlan: &id002 vlan_id: 100 interfaces: - eth0 - eth1 state: absent - register: result - assert: that: - - "result.changed == true" + - result.changed == true - "'delete interfaces ethernet eth0 vif 100' in result.commands" - "'delete interfaces ethernet eth1 vif 100' in result.commands" - name: delete vlan with multiple interfaces(idempotence) - vyos.vyos.vyos_vlan: *delete_multiple register: result + vyos.vyos.vyos_vlan: *id002 - assert: that: - - "result.changed == false" + - result.changed == false - name: teardown vyos.vyos.vyos_config: diff --git a/tests/sanity/ignore-2.10.txt b/tests/sanity/ignore-2.10.txt new file mode 100644 index 0000000..a90966f --- /dev/null +++ b/tests/sanity/ignore-2.10.txt @@ -0,0 +1,79 @@ +plugins/module_utils/network/vyos/vyos.py future-import-boilerplate +plugins/module_utils/network/vyos/vyos.py metaclass-boilerplate +plugins/modules/vyos_banner.py future-import-boilerplate +plugins/modules/vyos_banner.py metaclass-boilerplate +plugins/modules/vyos_banner.py validate-modules:doc-default-does-not-match-spec +plugins/modules/vyos_banner.py validate-modules:doc-missing-type +plugins/modules/vyos_banner.py validate-modules:doc-required-mismatch +plugins/modules/vyos_command.py future-import-boilerplate +plugins/modules/vyos_command.py metaclass-boilerplate +plugins/modules/vyos_command.py pylint:blacklisted-name +plugins/modules/vyos_command.py validate-modules:doc-default-does-not-match-spec +plugins/modules/vyos_command.py validate-modules:doc-missing-type +plugins/modules/vyos_command.py validate-modules:doc-required-mismatch +plugins/modules/vyos_command.py validate-modules:parameter-type-not-in-doc +plugins/modules/vyos_config.py future-import-boilerplate +plugins/modules/vyos_config.py metaclass-boilerplate +plugins/modules/vyos_config.py validate-modules:doc-default-does-not-match-spec +plugins/modules/vyos_config.py validate-modules:doc-missing-type +plugins/modules/vyos_config.py validate-modules:doc-required-mismatch +plugins/modules/vyos_config.py validate-modules:parameter-type-not-in-doc +plugins/modules/vyos_facts.py future-import-boilerplate +plugins/modules/vyos_facts.py metaclass-boilerplate +plugins/modules/vyos_facts.py validate-modules:doc-default-does-not-match-spec +plugins/modules/vyos_facts.py validate-modules:doc-required-mismatch +plugins/modules/vyos_facts.py validate-modules:parameter-type-not-in-doc +plugins/modules/vyos_lldp_interfaces.py validate-modules:doc-required-mismatch +plugins/modules/vyos_logging.py future-import-boilerplate +plugins/modules/vyos_logging.py metaclass-boilerplate +plugins/modules/vyos_logging.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/vyos_logging.py validate-modules:doc-default-does-not-match-spec +plugins/modules/vyos_logging.py validate-modules:doc-missing-type +plugins/modules/vyos_logging.py validate-modules:doc-required-mismatch +plugins/modules/vyos_logging.py validate-modules:missing-suboption-docs +plugins/modules/vyos_logging.py validate-modules:parameter-type-not-in-doc +plugins/modules/vyos_logging.py validate-modules:undocumented-parameter +plugins/modules/vyos_ping.py validate-modules:doc-default-does-not-match-spec +plugins/modules/vyos_ping.py validate-modules:doc-required-mismatch +plugins/modules/vyos_ping.py validate-modules:parameter-type-not-in-doc +plugins/modules/vyos_static_route.py future-import-boilerplate +plugins/modules/vyos_static_route.py metaclass-boilerplate +plugins/modules/vyos_static_route.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/vyos_static_route.py validate-modules:doc-default-does-not-match-spec +plugins/modules/vyos_static_route.py validate-modules:doc-missing-type +plugins/modules/vyos_static_route.py validate-modules:doc-required-mismatch +plugins/modules/vyos_static_route.py validate-modules:missing-suboption-docs +plugins/modules/vyos_static_route.py validate-modules:parameter-type-not-in-doc +plugins/modules/vyos_static_route.py validate-modules:undocumented-parameter +plugins/modules/vyos_system.py future-import-boilerplate +plugins/modules/vyos_system.py metaclass-boilerplate +plugins/modules/vyos_system.py validate-modules:doc-default-does-not-match-spec +plugins/modules/vyos_system.py validate-modules:doc-required-mismatch +plugins/modules/vyos_system.py validate-modules:parameter-type-not-in-doc +plugins/modules/vyos_user.py future-import-boilerplate +plugins/modules/vyos_user.py metaclass-boilerplate +plugins/modules/vyos_user.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/vyos_user.py validate-modules:doc-default-does-not-match-spec +plugins/modules/vyos_user.py validate-modules:doc-missing-type +plugins/modules/vyos_user.py validate-modules:doc-required-mismatch +plugins/modules/vyos_user.py validate-modules:missing-suboption-docs +plugins/modules/vyos_user.py validate-modules:parameter-type-not-in-doc +plugins/modules/vyos_user.py validate-modules:undocumented-parameter +plugins/modules/vyos_vlan.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/vyos_vlan.py validate-modules:doc-default-does-not-match-spec +plugins/modules/vyos_vlan.py validate-modules:doc-missing-type +plugins/modules/vyos_vlan.py validate-modules:doc-required-mismatch +plugins/modules/vyos_vlan.py validate-modules:missing-suboption-docs +plugins/modules/vyos_vlan.py validate-modules:parameter-type-not-in-doc +plugins/modules/vyos_vlan.py validate-modules:undocumented-parameter +plugins/action/vyos.py action-plugin-docs # base class for deprecated network platform modules using `connection: local` +plugins/doc_fragments/vyos.py future-import-boilerplate +plugins/doc_fragments/vyos.py metaclass-boilerplate +tests/unit/mock/path.py future-import-boilerplate +tests/unit/mock/path.py metaclass-boilerplate +tests/unit/mock/yaml_helper.py future-import-boilerplate +tests/unit/mock/yaml_helper.py metaclass-boilerplate +tests/unit/modules/conftest.py future-import-boilerplate +tests/unit/modules/conftest.py metaclass-boilerplate +tests/unit/modules/utils.py future-import-boilerplate +tests/unit/modules/utils.py metaclass-boilerplate
\ No newline at end of file diff --git a/tests/sanity/ignore-2.9.txt b/tests/sanity/ignore-2.9.txt new file mode 100644 index 0000000..a90966f --- /dev/null +++ b/tests/sanity/ignore-2.9.txt @@ -0,0 +1,79 @@ +plugins/module_utils/network/vyos/vyos.py future-import-boilerplate +plugins/module_utils/network/vyos/vyos.py metaclass-boilerplate +plugins/modules/vyos_banner.py future-import-boilerplate +plugins/modules/vyos_banner.py metaclass-boilerplate +plugins/modules/vyos_banner.py validate-modules:doc-default-does-not-match-spec +plugins/modules/vyos_banner.py validate-modules:doc-missing-type +plugins/modules/vyos_banner.py validate-modules:doc-required-mismatch +plugins/modules/vyos_command.py future-import-boilerplate +plugins/modules/vyos_command.py metaclass-boilerplate +plugins/modules/vyos_command.py pylint:blacklisted-name +plugins/modules/vyos_command.py validate-modules:doc-default-does-not-match-spec +plugins/modules/vyos_command.py validate-modules:doc-missing-type +plugins/modules/vyos_command.py validate-modules:doc-required-mismatch +plugins/modules/vyos_command.py validate-modules:parameter-type-not-in-doc +plugins/modules/vyos_config.py future-import-boilerplate +plugins/modules/vyos_config.py metaclass-boilerplate +plugins/modules/vyos_config.py validate-modules:doc-default-does-not-match-spec +plugins/modules/vyos_config.py validate-modules:doc-missing-type +plugins/modules/vyos_config.py validate-modules:doc-required-mismatch +plugins/modules/vyos_config.py validate-modules:parameter-type-not-in-doc +plugins/modules/vyos_facts.py future-import-boilerplate +plugins/modules/vyos_facts.py metaclass-boilerplate +plugins/modules/vyos_facts.py validate-modules:doc-default-does-not-match-spec +plugins/modules/vyos_facts.py validate-modules:doc-required-mismatch +plugins/modules/vyos_facts.py validate-modules:parameter-type-not-in-doc +plugins/modules/vyos_lldp_interfaces.py validate-modules:doc-required-mismatch +plugins/modules/vyos_logging.py future-import-boilerplate +plugins/modules/vyos_logging.py metaclass-boilerplate +plugins/modules/vyos_logging.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/vyos_logging.py validate-modules:doc-default-does-not-match-spec +plugins/modules/vyos_logging.py validate-modules:doc-missing-type +plugins/modules/vyos_logging.py validate-modules:doc-required-mismatch +plugins/modules/vyos_logging.py validate-modules:missing-suboption-docs +plugins/modules/vyos_logging.py validate-modules:parameter-type-not-in-doc +plugins/modules/vyos_logging.py validate-modules:undocumented-parameter +plugins/modules/vyos_ping.py validate-modules:doc-default-does-not-match-spec +plugins/modules/vyos_ping.py validate-modules:doc-required-mismatch +plugins/modules/vyos_ping.py validate-modules:parameter-type-not-in-doc +plugins/modules/vyos_static_route.py future-import-boilerplate +plugins/modules/vyos_static_route.py metaclass-boilerplate +plugins/modules/vyos_static_route.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/vyos_static_route.py validate-modules:doc-default-does-not-match-spec +plugins/modules/vyos_static_route.py validate-modules:doc-missing-type +plugins/modules/vyos_static_route.py validate-modules:doc-required-mismatch +plugins/modules/vyos_static_route.py validate-modules:missing-suboption-docs +plugins/modules/vyos_static_route.py validate-modules:parameter-type-not-in-doc +plugins/modules/vyos_static_route.py validate-modules:undocumented-parameter +plugins/modules/vyos_system.py future-import-boilerplate +plugins/modules/vyos_system.py metaclass-boilerplate +plugins/modules/vyos_system.py validate-modules:doc-default-does-not-match-spec +plugins/modules/vyos_system.py validate-modules:doc-required-mismatch +plugins/modules/vyos_system.py validate-modules:parameter-type-not-in-doc +plugins/modules/vyos_user.py future-import-boilerplate +plugins/modules/vyos_user.py metaclass-boilerplate +plugins/modules/vyos_user.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/vyos_user.py validate-modules:doc-default-does-not-match-spec +plugins/modules/vyos_user.py validate-modules:doc-missing-type +plugins/modules/vyos_user.py validate-modules:doc-required-mismatch +plugins/modules/vyos_user.py validate-modules:missing-suboption-docs +plugins/modules/vyos_user.py validate-modules:parameter-type-not-in-doc +plugins/modules/vyos_user.py validate-modules:undocumented-parameter +plugins/modules/vyos_vlan.py validate-modules:doc-choices-do-not-match-spec +plugins/modules/vyos_vlan.py validate-modules:doc-default-does-not-match-spec +plugins/modules/vyos_vlan.py validate-modules:doc-missing-type +plugins/modules/vyos_vlan.py validate-modules:doc-required-mismatch +plugins/modules/vyos_vlan.py validate-modules:missing-suboption-docs +plugins/modules/vyos_vlan.py validate-modules:parameter-type-not-in-doc +plugins/modules/vyos_vlan.py validate-modules:undocumented-parameter +plugins/action/vyos.py action-plugin-docs # base class for deprecated network platform modules using `connection: local` +plugins/doc_fragments/vyos.py future-import-boilerplate +plugins/doc_fragments/vyos.py metaclass-boilerplate +tests/unit/mock/path.py future-import-boilerplate +tests/unit/mock/path.py metaclass-boilerplate +tests/unit/mock/yaml_helper.py future-import-boilerplate +tests/unit/mock/yaml_helper.py metaclass-boilerplate +tests/unit/modules/conftest.py future-import-boilerplate +tests/unit/modules/conftest.py metaclass-boilerplate +tests/unit/modules/utils.py future-import-boilerplate +tests/unit/modules/utils.py metaclass-boilerplate
\ No newline at end of file diff --git a/tests/sanity/requirements.txt b/tests/sanity/requirements.txt new file mode 100644 index 0000000..3e3a966 --- /dev/null +++ b/tests/sanity/requirements.txt @@ -0,0 +1,4 @@ +packaging # needed for update-bundled and changelog +sphinx ; python_version >= '3.5' # docs build requires python 3+ +sphinx-notfound-page ; python_version >= '3.5' # docs build requires python 3+ +straight.plugin ; python_version >= '3.5' # needed for hacking/build-ansible.py which will host changelog generation and requires python 3+ diff --git a/tests/unit/__init__.py b/tests/unit/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/tests/unit/__init__.py diff --git a/tests/unit/compat/__init__.py b/tests/unit/compat/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/tests/unit/compat/__init__.py diff --git a/tests/unit/compat/builtins.py b/tests/unit/compat/builtins.py new file mode 100644 index 0000000..bfc8adf --- /dev/null +++ b/tests/unit/compat/builtins.py @@ -0,0 +1,34 @@ +# (c) 2014, Toshio Kuratomi <tkuratomi@ansible.com> +# +# 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 + +# +# Compat for python2.7 +# + +# One unittest needs to import builtins via __import__() so we need to have +# the string that represents it +try: + import __builtin__ +except ImportError: + BUILTINS = "builtins" +else: + BUILTINS = "__builtin__" diff --git a/tests/unit/compat/mock.py b/tests/unit/compat/mock.py new file mode 100644 index 0000000..b45d6b5 --- /dev/null +++ b/tests/unit/compat/mock.py @@ -0,0 +1,127 @@ +# (c) 2014, Toshio Kuratomi <tkuratomi@ansible.com> +# +# 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 + +""" +Compat module for Python3.x's unittest.mock module +""" +import sys + +# Python 2.7 + +# Note: Could use the pypi mock library on python3.x as well as python2.x. It +# is the same as the python3 stdlib mock library + +try: + # Allow wildcard import because we really do want to import all of mock's + # symbols into this compat shim + # pylint: disable=wildcard-import,unused-wildcard-import + from unittest.mock import * +except ImportError: + # Python 2 + # pylint: disable=wildcard-import,unused-wildcard-import + try: + from mock import * + except ImportError: + print("You need the mock library installed on python2.x to run tests") + + +# Prior to 3.4.4, mock_open cannot handle binary read_data +if sys.version_info >= (3,) and sys.version_info < (3, 4, 4): + file_spec = None + + def _iterate_read_data(read_data): + # Helper for mock_open: + # Retrieve lines from read_data via a generator so that separate calls to + # readline, read, and readlines are properly interleaved + sep = b"\n" if isinstance(read_data, bytes) else "\n" + data_as_list = [l + sep for l in read_data.split(sep)] + + if data_as_list[-1] == sep: + # If the last line ended in a newline, the list comprehension will have an + # extra entry that's just a newline. Remove this. + data_as_list = data_as_list[:-1] + else: + # If there wasn't an extra newline by itself, then the file being + # emulated doesn't have a newline to end the last line remove the + # newline that our naive format() added + data_as_list[-1] = data_as_list[-1][:-1] + + for line in data_as_list: + yield line + + def mock_open(mock=None, read_data=""): + """ + A helper function to create a mock to replace the use of `open`. It works + for `open` called directly or used as a context manager. + + The `mock` argument is the mock object to configure. If `None` (the + default) then a `MagicMock` will be created for you, with the API limited + to methods or attributes available on standard file handles. + + `read_data` is a string for the `read` methoddline`, and `readlines` of the + file handle to return. This is an empty string by default. + """ + + def _readlines_side_effect(*args, **kwargs): + if handle.readlines.return_value is not None: + return handle.readlines.return_value + return list(_data) + + def _read_side_effect(*args, **kwargs): + if handle.read.return_value is not None: + return handle.read.return_value + return type(read_data)().join(_data) + + def _readline_side_effect(): + if handle.readline.return_value is not None: + while True: + yield handle.readline.return_value + for line in _data: + yield line + + global file_spec + if file_spec is None: + import _io + + file_spec = list( + set(dir(_io.TextIOWrapper)).union(set(dir(_io.BytesIO))) + ) + + if mock is None: + mock = MagicMock(name="open", spec=open) + + handle = MagicMock(spec=file_spec) + handle.__enter__.return_value = handle + + _data = _iterate_read_data(read_data) + + handle.write.return_value = None + handle.read.return_value = None + handle.readline.return_value = None + handle.readlines.return_value = None + + handle.read.side_effect = _read_side_effect + handle.readline.side_effect = _readline_side_effect() + handle.readlines.side_effect = _readlines_side_effect + + mock.return_value = handle + return mock diff --git a/tests/unit/compat/unittest.py b/tests/unit/compat/unittest.py new file mode 100644 index 0000000..df3379b --- /dev/null +++ b/tests/unit/compat/unittest.py @@ -0,0 +1,39 @@ +# (c) 2014, Toshio Kuratomi <tkuratomi@ansible.com> +# +# 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 + +""" +Compat module for Python2.7's unittest module +""" + +import sys + +# Allow wildcard import because we really do want to import all of +# unittests's symbols into this compat shim +# pylint: disable=wildcard-import,unused-wildcard-import +if sys.version_info < (2, 7): + try: + # Need unittest2 on python2.6 + from unittest2 import * + except ImportError: + print("You need unittest2 installed on python2.6.x to run tests") +else: + from unittest import * diff --git a/tests/unit/mock/__init__.py b/tests/unit/mock/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/tests/unit/mock/__init__.py diff --git a/tests/unit/mock/loader.py b/tests/unit/mock/loader.py new file mode 100644 index 0000000..c21188e --- /dev/null +++ b/tests/unit/mock/loader.py @@ -0,0 +1,116 @@ +# (c) 2012-2014, Michael DeHaan <michael.dehaan@gmail.com> +# +# 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 + +import os + +from ansible.errors import AnsibleParserError +from ansible.parsing.dataloader import DataLoader +from ansible.module_utils._text import to_bytes, to_text + + +class DictDataLoader(DataLoader): + def __init__(self, file_mapping=None): + file_mapping = {} if file_mapping is None else file_mapping + assert type(file_mapping) == dict + + super(DictDataLoader, self).__init__() + + self._file_mapping = file_mapping + self._build_known_directories() + self._vault_secrets = None + + def load_from_file(self, path, cache=True, unsafe=False): + path = to_text(path) + if path in self._file_mapping: + return self.load(self._file_mapping[path], path) + return None + + # TODO: the real _get_file_contents returns a bytestring, so we actually convert the + # unicode/text it's created with to utf-8 + def _get_file_contents(self, path): + path = to_text(path) + if path in self._file_mapping: + return (to_bytes(self._file_mapping[path]), False) + else: + raise AnsibleParserError("file not found: %s" % path) + + def path_exists(self, path): + path = to_text(path) + return path in self._file_mapping or path in self._known_directories + + def is_file(self, path): + path = to_text(path) + return path in self._file_mapping + + def is_directory(self, path): + path = to_text(path) + return path in self._known_directories + + def list_directory(self, path): + ret = [] + path = to_text(path) + for x in list(self._file_mapping.keys()) + self._known_directories: + if x.startswith(path): + if os.path.dirname(x) == path: + ret.append(os.path.basename(x)) + return ret + + def is_executable(self, path): + # FIXME: figure out a way to make paths return true for this + return False + + def _add_known_directory(self, directory): + if directory not in self._known_directories: + self._known_directories.append(directory) + + def _build_known_directories(self): + self._known_directories = [] + for path in self._file_mapping: + dirname = os.path.dirname(path) + while dirname not in ("/", ""): + self._add_known_directory(dirname) + dirname = os.path.dirname(dirname) + + def push(self, path, content): + rebuild_dirs = False + if path not in self._file_mapping: + rebuild_dirs = True + + self._file_mapping[path] = content + + if rebuild_dirs: + self._build_known_directories() + + def pop(self, path): + if path in self._file_mapping: + del self._file_mapping[path] + self._build_known_directories() + + def clear(self): + self._file_mapping = dict() + self._known_directories = [] + + def get_basedir(self): + return os.getcwd() + + def set_vault_secrets(self, vault_secrets): + self._vault_secrets = vault_secrets diff --git a/tests/unit/mock/path.py b/tests/unit/mock/path.py new file mode 100644 index 0000000..aea8ba1 --- /dev/null +++ b/tests/unit/mock/path.py @@ -0,0 +1,7 @@ +from ansible_collections.vyos.vyos.tests.unit.compat.mock import MagicMock +from ansible.utils.path import unfrackpath + + +mock_unfrackpath_noop = MagicMock( + spec_set=unfrackpath, side_effect=lambda x, *args, **kwargs: x +) diff --git a/tests/unit/mock/procenv.py b/tests/unit/mock/procenv.py new file mode 100644 index 0000000..1587949 --- /dev/null +++ b/tests/unit/mock/procenv.py @@ -0,0 +1,94 @@ +# (c) 2016, Matt Davis <mdavis@ansible.com> +# (c) 2016, Toshio Kuratomi <tkuratomi@ansible.com> +# +# 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 + +import sys +import json + +from contextlib import contextmanager +from io import BytesIO, StringIO +from ansible_collections.vyos.vyos.tests.unit.compat import unittest +from ansible.module_utils.six import PY3 +from ansible.module_utils._text import to_bytes + + +@contextmanager +def swap_stdin_and_argv(stdin_data="", argv_data=tuple()): + """ + context manager that temporarily masks the test runner's values for stdin and argv + """ + real_stdin = sys.stdin + real_argv = sys.argv + + if PY3: + fake_stream = StringIO(stdin_data) + fake_stream.buffer = BytesIO(to_bytes(stdin_data)) + else: + fake_stream = BytesIO(to_bytes(stdin_data)) + + try: + sys.stdin = fake_stream + sys.argv = argv_data + + yield + finally: + sys.stdin = real_stdin + sys.argv = real_argv + + +@contextmanager +def swap_stdout(): + """ + context manager that temporarily replaces stdout for tests that need to verify output + """ + old_stdout = sys.stdout + + if PY3: + fake_stream = StringIO() + else: + fake_stream = BytesIO() + + try: + sys.stdout = fake_stream + + yield fake_stream + finally: + sys.stdout = old_stdout + + +class ModuleTestCase(unittest.TestCase): + def setUp(self, module_args=None): + if module_args is None: + module_args = { + "_ansible_remote_tmp": "/tmp", + "_ansible_keep_remote_files": False, + } + + args = json.dumps(dict(ANSIBLE_MODULE_ARGS=module_args)) + + # unittest doesn't have a clean place to use a context manager, so we have to enter/exit manually + self.stdin_swap = swap_stdin_and_argv(stdin_data=args) + self.stdin_swap.__enter__() + + def tearDown(self): + # unittest doesn't have a clean place to use a context manager, so we have to enter/exit manually + self.stdin_swap.__exit__(None, None, None) diff --git a/tests/unit/mock/vault_helper.py b/tests/unit/mock/vault_helper.py new file mode 100644 index 0000000..b34ae13 --- /dev/null +++ b/tests/unit/mock/vault_helper.py @@ -0,0 +1,42 @@ +# 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.module_utils._text import to_bytes + +from ansible.parsing.vault import VaultSecret + + +class TextVaultSecret(VaultSecret): + """A secret piece of text. ie, a password. Tracks text encoding. + + The text encoding of the text may not be the default text encoding so + we keep track of the encoding so we encode it to the same bytes.""" + + def __init__(self, text, encoding=None, errors=None, _bytes=None): + super(TextVaultSecret, self).__init__() + self.text = text + self.encoding = encoding or "utf-8" + self._bytes = _bytes + self.errors = errors or "strict" + + @property + def bytes(self): + """The text encoded with encoding, unless we specifically set _bytes.""" + return self._bytes or to_bytes( + self.text, encoding=self.encoding, errors=self.errors + ) diff --git a/tests/unit/mock/yaml_helper.py b/tests/unit/mock/yaml_helper.py new file mode 100644 index 0000000..1a945f1 --- /dev/null +++ b/tests/unit/mock/yaml_helper.py @@ -0,0 +1,164 @@ +import io +import yaml + +from ansible.module_utils.six import PY3 +from ansible.parsing.yaml.loader import AnsibleLoader +from ansible.parsing.yaml.dumper import AnsibleDumper + + +class YamlTestUtils(object): + """Mixin class to combine with a unittest.TestCase subclass.""" + + def _loader(self, stream): + """Vault related tests will want to override this. + + Vault cases should setup a AnsibleLoader that has the vault password.""" + return AnsibleLoader(stream) + + def _dump_stream(self, obj, stream, dumper=None): + """Dump to a py2-unicode or py3-string stream.""" + if PY3: + return yaml.dump(obj, stream, Dumper=dumper) + else: + return yaml.dump(obj, stream, Dumper=dumper, encoding=None) + + def _dump_string(self, obj, dumper=None): + """Dump to a py2-unicode or py3-string""" + if PY3: + return yaml.dump(obj, Dumper=dumper) + else: + return yaml.dump(obj, Dumper=dumper, encoding=None) + + def _dump_load_cycle(self, obj): + # Each pass though a dump or load revs the 'generation' + # obj to yaml string + string_from_object_dump = self._dump_string(obj, dumper=AnsibleDumper) + + # wrap a stream/file like StringIO around that yaml + stream_from_object_dump = io.StringIO(string_from_object_dump) + loader = self._loader(stream_from_object_dump) + # load the yaml stream to create a new instance of the object (gen 2) + obj_2 = loader.get_data() + + # dump the gen 2 objects directory to strings + string_from_object_dump_2 = self._dump_string( + obj_2, dumper=AnsibleDumper + ) + + # The gen 1 and gen 2 yaml strings + self.assertEqual(string_from_object_dump, string_from_object_dump_2) + # the gen 1 (orig) and gen 2 py object + self.assertEqual(obj, obj_2) + + # again! gen 3... load strings into py objects + stream_3 = io.StringIO(string_from_object_dump_2) + loader_3 = self._loader(stream_3) + obj_3 = loader_3.get_data() + + string_from_object_dump_3 = self._dump_string( + obj_3, dumper=AnsibleDumper + ) + + self.assertEqual(obj, obj_3) + # should be transitive, but... + self.assertEqual(obj_2, obj_3) + self.assertEqual(string_from_object_dump, string_from_object_dump_3) + + def _old_dump_load_cycle(self, obj): + """Dump the passed in object to yaml, load it back up, dump again, compare.""" + stream = io.StringIO() + + yaml_string = self._dump_string(obj, dumper=AnsibleDumper) + self._dump_stream(obj, stream, dumper=AnsibleDumper) + + yaml_string_from_stream = stream.getvalue() + + # reset stream + stream.seek(0) + + loader = self._loader(stream) + # loader = AnsibleLoader(stream, vault_password=self.vault_password) + obj_from_stream = loader.get_data() + + stream_from_string = io.StringIO(yaml_string) + loader2 = self._loader(stream_from_string) + # loader2 = AnsibleLoader(stream_from_string, vault_password=self.vault_password) + obj_from_string = loader2.get_data() + + stream_obj_from_stream = io.StringIO() + stream_obj_from_string = io.StringIO() + + if PY3: + yaml.dump( + obj_from_stream, stream_obj_from_stream, Dumper=AnsibleDumper + ) + yaml.dump( + obj_from_stream, stream_obj_from_string, Dumper=AnsibleDumper + ) + else: + yaml.dump( + obj_from_stream, + stream_obj_from_stream, + Dumper=AnsibleDumper, + encoding=None, + ) + yaml.dump( + obj_from_stream, + stream_obj_from_string, + Dumper=AnsibleDumper, + encoding=None, + ) + + yaml_string_stream_obj_from_stream = stream_obj_from_stream.getvalue() + yaml_string_stream_obj_from_string = stream_obj_from_string.getvalue() + + stream_obj_from_stream.seek(0) + stream_obj_from_string.seek(0) + + if PY3: + yaml_string_obj_from_stream = yaml.dump( + obj_from_stream, Dumper=AnsibleDumper + ) + yaml_string_obj_from_string = yaml.dump( + obj_from_string, Dumper=AnsibleDumper + ) + else: + yaml_string_obj_from_stream = yaml.dump( + obj_from_stream, Dumper=AnsibleDumper, encoding=None + ) + yaml_string_obj_from_string = yaml.dump( + obj_from_string, Dumper=AnsibleDumper, encoding=None + ) + + assert yaml_string == yaml_string_obj_from_stream + assert ( + yaml_string + == yaml_string_obj_from_stream + == yaml_string_obj_from_string + ) + assert ( + yaml_string + == yaml_string_obj_from_stream + == yaml_string_obj_from_string + == yaml_string_stream_obj_from_stream + == yaml_string_stream_obj_from_string + ) + assert obj == obj_from_stream + assert obj == obj_from_string + assert obj == yaml_string_obj_from_stream + assert obj == yaml_string_obj_from_string + assert ( + obj + == obj_from_stream + == obj_from_string + == yaml_string_obj_from_stream + == yaml_string_obj_from_string + ) + return { + "obj": obj, + "yaml_string": yaml_string, + "yaml_string_from_stream": yaml_string_from_stream, + "obj_from_stream": obj_from_stream, + "obj_from_string": obj_from_string, + "yaml_string_obj_from_string": yaml_string_obj_from_string, + } diff --git a/tests/unit/modules/__init__.py b/tests/unit/modules/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/tests/unit/modules/__init__.py diff --git a/tests/unit/modules/conftest.py b/tests/unit/modules/conftest.py new file mode 100644 index 0000000..ac56c9c --- /dev/null +++ b/tests/unit/modules/conftest.py @@ -0,0 +1,37 @@ +# Copyright (c) 2017 Ansible Project +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +import json + +import pytest + +from ansible.module_utils.six import string_types +from ansible.module_utils._text import to_bytes +from ansible.module_utils.common._collections_compat import MutableMapping + + +@pytest.fixture +def patch_ansible_module(request, mocker): + if isinstance(request.param, string_types): + args = request.param + elif isinstance(request.param, MutableMapping): + if "ANSIBLE_MODULE_ARGS" not in request.param: + request.param = {"ANSIBLE_MODULE_ARGS": request.param} + if "_ansible_remote_tmp" not in request.param["ANSIBLE_MODULE_ARGS"]: + request.param["ANSIBLE_MODULE_ARGS"][ + "_ansible_remote_tmp" + ] = "/tmp" + if ( + "_ansible_keep_remote_files" + not in request.param["ANSIBLE_MODULE_ARGS"] + ): + request.param["ANSIBLE_MODULE_ARGS"][ + "_ansible_keep_remote_files" + ] = False + args = json.dumps(request.param) + else: + raise Exception( + "Malformed data to the patch_ansible_module pytest fixture" + ) + + mocker.patch("ansible.module_utils.basic._ANSIBLE_ARGS", to_bytes(args)) diff --git a/tests/unit/modules/network/__init__.py b/tests/unit/modules/network/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/tests/unit/modules/network/__init__.py diff --git a/tests/unit/modules/network/vyos/__init__.py b/tests/unit/modules/network/vyos/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/tests/unit/modules/network/vyos/__init__.py diff --git a/tests/unit/modules/network/vyos/fixtures/__init__.py b/tests/unit/modules/network/vyos/fixtures/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/tests/unit/modules/network/vyos/fixtures/__init__.py diff --git a/tests/unit/modules/network/vyos/fixtures/show_host_name b/tests/unit/modules/network/vyos/fixtures/show_host_name new file mode 100644 index 0000000..e89bc06 --- /dev/null +++ b/tests/unit/modules/network/vyos/fixtures/show_host_name @@ -0,0 +1 @@ +vyos01 diff --git a/tests/unit/modules/network/vyos/fixtures/show_version b/tests/unit/modules/network/vyos/fixtures/show_version new file mode 100644 index 0000000..a015d55 --- /dev/null +++ b/tests/unit/modules/network/vyos/fixtures/show_version @@ -0,0 +1,14 @@ +Version: VyOS 1.1.7 +Description: VyOS 1.1.7 (helium) +Copyright: 2016 VyOS maintainers and contributors +Built by: maintainers@vyos.net +Built on: Wed Feb 17 09:57:31 UTC 2016 +Build ID: 1602170957-4459750 +System type: x86 64-bit +Boot via: image +Hypervisor: VMware +HW model: VMware Virtual Platform +HW S/N: VMware-42 3c 26 25 44 c5 0a 91-cf 2c 97 2b fe 9b 25 be +HW UUID: 423C2625-44C5-0A91-CF2C-972BFE9B25BE +Uptime: 01:08:20 up 52 days, 2:13, 1 user, load average: 0.00, 0.01, 0.05 + diff --git a/tests/unit/modules/network/vyos/fixtures/vyos_config_config.cfg b/tests/unit/modules/network/vyos/fixtures/vyos_config_config.cfg new file mode 100644 index 0000000..fcef8eb --- /dev/null +++ b/tests/unit/modules/network/vyos/fixtures/vyos_config_config.cfg @@ -0,0 +1,10 @@ +set system host-name 'router' +set system domain-name 'example.com' +set system domain-search domain 'example.com' +set system name-server '8.8.8.8' +set system name-server '8.8.4.4' +set interfaces ethernet eth0 address '1.2.3.4/24' +set interfaces ethernet eth0 description 'test string' +set interfaces ethernet eth1 address '6.7.8.9/24' +set interfaces ethernet eth1 description 'test string' +set interfaces ethernet eth1 disable diff --git a/tests/unit/modules/network/vyos/fixtures/vyos_config_src.cfg b/tests/unit/modules/network/vyos/fixtures/vyos_config_src.cfg new file mode 100644 index 0000000..410f611 --- /dev/null +++ b/tests/unit/modules/network/vyos/fixtures/vyos_config_src.cfg @@ -0,0 +1,6 @@ +set system host-name foo + +delete interfaces ethernet eth0 address +set interfaces ethernet eth1 address '6.7.8.9/24' + set interfaces ethernet eth1 description 'test string' +set interfaces ethernet eth1 disable diff --git a/tests/unit/modules/network/vyos/fixtures/vyos_config_src_brackets.cfg b/tests/unit/modules/network/vyos/fixtures/vyos_config_src_brackets.cfg new file mode 100644 index 0000000..468b32c --- /dev/null +++ b/tests/unit/modules/network/vyos/fixtures/vyos_config_src_brackets.cfg @@ -0,0 +1,13 @@ +interfaces { + ethernet eth0 { + address 10.10.10.10/24 + } + ethernet eth1 { + address 6.7.8.9/24 + description test string + disable + } +} +system { + host-name foo +} diff --git a/tests/unit/modules/network/vyos/fixtures/vyos_ping_ping_10.10.10.10_count_2 b/tests/unit/modules/network/vyos/fixtures/vyos_ping_ping_10.10.10.10_count_2 new file mode 100644 index 0000000..c28fba1 --- /dev/null +++ b/tests/unit/modules/network/vyos/fixtures/vyos_ping_ping_10.10.10.10_count_2 @@ -0,0 +1,7 @@ +PING 10.10.10.10 (10.10.10.10) 56(84) bytes of data. +64 bytes from 10.10.10.10: icmp_req=1 ttl=255 time=1.27 ms +64 bytes from 10.10.10.10: icmp_req=2 ttl=255 time=2.28 ms + +--- 10.8.38.66 ping statistics --- +2 packets transmitted, 2 received, 0% packet loss, time 1001ms +rtt min/avg/max/mdev = 12.1222/17.124/22.225/10.143 ms diff --git a/tests/unit/modules/network/vyos/fixtures/vyos_ping_ping_10.10.10.11_count_10_ttl_128_size_512 b/tests/unit/modules/network/vyos/fixtures/vyos_ping_ping_10.10.10.11_count_10_ttl_128_size_512 new file mode 100644 index 0000000..54e026c --- /dev/null +++ b/tests/unit/modules/network/vyos/fixtures/vyos_ping_ping_10.10.10.11_count_10_ttl_128_size_512 @@ -0,0 +1,15 @@ +PING 10.10.10.11 (10.8.38.65) 512(540) bytes of data. +520 bytes from 10.10.10.11: icmp_req=1 ttl=255 time=1.17 ms +520 bytes from 10.10.10.11: icmp_req=2 ttl=255 time=1.32 ms +520 bytes from 10.10.10.11: icmp_req=3 ttl=255 time=1.21 ms +520 bytes from 10.10.10.11: icmp_req=4 ttl=255 time=1.46 ms +520 bytes from 10.10.10.11: icmp_req=5 ttl=255 time=1.32 ms +520 bytes from 10.10.10.11: icmp_req=6 ttl=255 time=1.28 ms +520 bytes from 10.10.10.11: icmp_req=7 ttl=255 time=1.25 ms +520 bytes from 10.10.10.11: icmp_req=8 ttl=255 time=1.23 ms +520 bytes from 10.10.10.11: icmp_req=9 ttl=255 time=1.34 ms +520 bytes from 10.10.10.11: icmp_req=10 ttl=255 time=21.0 ms + +--- 10.10.10.11 ping statistics --- +10 packets transmitted, 10 received, 0% packet loss, time 9012ms +rtt min/avg/max/mdev = 1.170/3.262/21.002/5.913 ms diff --git a/tests/unit/modules/network/vyos/fixtures/vyos_ping_ping_10.10.10.20_count_4 b/tests/unit/modules/network/vyos/fixtures/vyos_ping_ping_10.10.10.20_count_4 new file mode 100644 index 0000000..08e6181 --- /dev/null +++ b/tests/unit/modules/network/vyos/fixtures/vyos_ping_ping_10.10.10.20_count_4 @@ -0,0 +1,9 @@ +PING 10.10.10.20 (10.10.10.20) 56(84) bytes of data. +From 10.10.10.20 icmp_seq=1 Destination Host Unreachable +From 10.10.10.20 icmp_seq=2 Destination Host Unreachable +From 10.10.10.20 icmp_seq=3 Destination Host Unreachable +From 10.10.10.20 icmp_seq=4 Destination Host Unreachable + +--- 10.10.10.20 ping statistics --- +4 packets transmitted, 0 received, +4 errors, 100% packet loss, time 3053ms +pipe 3 diff --git a/tests/unit/modules/network/vyos/fixtures/vyos_user_config.cfg b/tests/unit/modules/network/vyos/fixtures/vyos_user_config.cfg new file mode 100644 index 0000000..81cd1a4 --- /dev/null +++ b/tests/unit/modules/network/vyos/fixtures/vyos_user_config.cfg @@ -0,0 +1,2 @@ +set system login user admin level operator authentication encrypted-password '$6$V5oWW3JM9NFAwOG$P2L4raFvIrZjjs3g0qmH4Ns5ti7flRpSs6aEqy4TrGZYXGeBiYzwi2A6jy' +set system login user ansible level operator authentication encrypted-password '$6$ZfvSv6A50W6yNPYX$4HP5eg2sywcXYxTqhApQ7zvUvx0HsQHrI9xuJoFLy2gM/' diff --git a/tests/unit/modules/network/vyos/test_vyos_banner.py b/tests/unit/modules/network/vyos/test_vyos_banner.py new file mode 100644 index 0000000..c575409 --- /dev/null +++ b/tests/unit/modules/network/vyos/test_vyos_banner.py @@ -0,0 +1,63 @@ +# 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_banner +from ansible_collections.vyos.vyos.tests.unit.modules.utils import ( + set_module_args, +) +from .vyos_module import TestVyosModule + + +class TestVyosBannerModule(TestVyosModule): + + module = vyos_banner + + def setUp(self): + super(TestVyosBannerModule, self).setUp() + + self.mock_get_config = patch( + "ansible_collections.vyos.vyos.plugins.modules.vyos_banner.get_config" + ) + self.get_config = self.mock_get_config.start() + + self.mock_load_config = patch( + "ansible_collections.vyos.vyos.plugins.modules.vyos_banner.load_config" + ) + self.load_config = self.mock_load_config.start() + + def tearDown(self): + super(TestVyosBannerModule, self).tearDown() + self.mock_get_config.stop() + self.mock_load_config.stop() + + def load_fixtures(self, commands=None): + self.load_config.return_value = dict(diff=None, session="session") + + def test_vyos_banner_create(self): + set_module_args(dict(banner="pre-login", text="test\nbanner\nstring")) + commands = [ + "set system login banner pre-login 'test\\nbanner\\nstring'" + ] + self.execute_module(changed=True, commands=commands) + + def test_vyos_banner_remove(self): + set_module_args(dict(banner="pre-login", state="absent")) + self.execute_module(changed=False, commands=[]) diff --git a/tests/unit/modules/network/vyos/test_vyos_command.py b/tests/unit/modules/network/vyos/test_vyos_command.py new file mode 100644 index 0000000..820c6c4 --- /dev/null +++ b/tests/unit/modules/network/vyos/test_vyos_command.py @@ -0,0 +1,122 @@ +# (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_command +from ansible_collections.vyos.vyos.tests.unit.modules.utils import ( + set_module_args, +) +from .vyos_module import TestVyosModule, load_fixture + + +class TestVyosCommandModule(TestVyosModule): + + module = vyos_command + + def setUp(self): + super(TestVyosCommandModule, self).setUp() + self.mock_run_commands = patch( + "ansible_collections.vyos.vyos.plugins.modules.vyos_command.run_commands" + ) + self.run_commands = self.mock_run_commands.start() + + def tearDown(self): + super(TestVyosCommandModule, self).tearDown() + self.mock_run_commands.stop() + + def load_fixtures(self, commands=None): + def load_from_file(*args, **kwargs): + module, commands = args + output = list() + + for item in commands: + try: + command = item["command"] + except ValueError: + command = item + filename = str(command).replace(" ", "_") + output.append(load_fixture(filename)) + return output + + self.run_commands.side_effect = load_from_file + + def test_vyos_command_simple(self): + set_module_args(dict(commands=["show version"])) + result = self.execute_module() + self.assertEqual(len(result["stdout"]), 1) + self.assertTrue(result["stdout"][0].startswith("Version: VyOS")) + + def test_vyos_command_multiple(self): + set_module_args(dict(commands=["show version", "show version"])) + result = self.execute_module() + self.assertEqual(len(result["stdout"]), 2) + self.assertTrue(result["stdout"][0].startswith("Version: VyOS")) + + def test_vyos_command_wait_for(self): + wait_for = 'result[0] contains "VyOS maintainers"' + set_module_args(dict(commands=["show version"], wait_for=wait_for)) + self.execute_module() + + def test_vyos_command_wait_for_fails(self): + wait_for = 'result[0] contains "test string"' + set_module_args(dict(commands=["show version"], wait_for=wait_for)) + self.execute_module(failed=True) + self.assertEqual(self.run_commands.call_count, 10) + + def test_vyos_command_retries(self): + wait_for = 'result[0] contains "test string"' + set_module_args( + dict(commands=["show version"], wait_for=wait_for, retries=2) + ) + self.execute_module(failed=True) + self.assertEqual(self.run_commands.call_count, 2) + + def test_vyos_command_match_any(self): + wait_for = [ + 'result[0] contains "VyOS maintainers"', + 'result[0] contains "test string"', + ] + set_module_args( + dict(commands=["show version"], wait_for=wait_for, match="any") + ) + self.execute_module() + + def test_vyos_command_match_all(self): + wait_for = [ + 'result[0] contains "VyOS maintainers"', + 'result[0] contains "maintainers@vyos.net"', + ] + set_module_args( + dict(commands=["show version"], wait_for=wait_for, match="all") + ) + self.execute_module() + + def test_vyos_command_match_all_failure(self): + wait_for = [ + 'result[0] contains "VyOS maintainers"', + 'result[0] contains "test string"', + ] + commands = ["show version", "show version"] + set_module_args( + dict(commands=commands, wait_for=wait_for, match="all") + ) + self.execute_module(failed=True) diff --git a/tests/unit/modules/network/vyos/test_vyos_config.py b/tests/unit/modules/network/vyos/test_vyos_config.py new file mode 100644 index 0000000..a471edd --- /dev/null +++ b/tests/unit/modules/network/vyos/test_vyos_config.py @@ -0,0 +1,159 @@ +# +# (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, + MagicMock, +) +from ansible_collections.vyos.vyos.plugins.modules import vyos_config +from ansible_collections.vyos.vyos.plugins.cliconf.vyos import Cliconf +from ansible_collections.vyos.vyos.tests.unit.modules.utils import ( + set_module_args, +) +from .vyos_module import TestVyosModule, load_fixture + + +class TestVyosConfigModule(TestVyosModule): + + module = vyos_config + + def setUp(self): + super(TestVyosConfigModule, self).setUp() + + self.mock_get_config = patch( + "ansible_collections.vyos.vyos.plugins.modules.vyos_config.get_config" + ) + self.get_config = self.mock_get_config.start() + + self.mock_load_config = patch( + "ansible_collections.vyos.vyos.plugins.modules.vyos_config.load_config" + ) + self.load_config = self.mock_load_config.start() + + self.mock_run_commands = patch( + "ansible_collections.vyos.vyos.plugins.modules.vyos_config.run_commands" + ) + self.run_commands = self.mock_run_commands.start() + + self.mock_get_connection = patch( + "ansible_collections.vyos.vyos.plugins.modules.vyos_config.get_connection" + ) + self.get_connection = self.mock_get_connection.start() + + self.cliconf_obj = Cliconf(MagicMock()) + self.running_config = load_fixture("vyos_config_config.cfg") + + self.conn = self.get_connection() + self.conn.edit_config = MagicMock() + self.running_config = load_fixture("vyos_config_config.cfg") + + def tearDown(self): + super(TestVyosConfigModule, self).tearDown() + + self.mock_get_config.stop() + self.mock_load_config.stop() + self.mock_run_commands.stop() + self.mock_get_connection.stop() + + def load_fixtures(self, commands=None): + config_file = "vyos_config_config.cfg" + self.get_config.return_value = load_fixture(config_file) + self.load_config.return_value = None + + def test_vyos_config_unchanged(self): + src = load_fixture("vyos_config_config.cfg") + self.conn.get_diff = MagicMock( + return_value=self.cliconf_obj.get_diff(src, src) + ) + set_module_args(dict(src=src)) + self.execute_module() + + def test_vyos_config_src(self): + src = load_fixture("vyos_config_src.cfg") + set_module_args(dict(src=src)) + candidate = "\n".join(self.module.format_commands(src.splitlines())) + commands = [ + "set system host-name foo", + "delete interfaces ethernet eth0 address", + ] + self.conn.get_diff = MagicMock( + return_value=self.cliconf_obj.get_diff( + candidate, self.running_config + ) + ) + self.execute_module(changed=True, commands=commands) + + def test_vyos_config_src_brackets(self): + src = load_fixture("vyos_config_src_brackets.cfg") + set_module_args(dict(src=src)) + candidate = "\n".join(self.module.format_commands(src.splitlines())) + commands = [ + "set interfaces ethernet eth0 address 10.10.10.10/24", + "set system host-name foo", + ] + self.conn.get_diff = MagicMock( + return_value=self.cliconf_obj.get_diff( + candidate, self.running_config + ) + ) + self.execute_module(changed=True, commands=commands) + + def test_vyos_config_backup(self): + set_module_args(dict(backup=True)) + result = self.execute_module() + self.assertIn("__backup__", result) + + def test_vyos_config_lines(self): + commands = ["set system host-name foo"] + set_module_args(dict(lines=commands)) + candidate = "\n".join(commands) + self.conn.get_diff = MagicMock( + return_value=self.cliconf_obj.get_diff( + candidate, self.running_config + ) + ) + self.execute_module(changed=True, commands=commands) + + def test_vyos_config_config(self): + config = "set system host-name localhost" + new_config = ["set system host-name router"] + set_module_args(dict(lines=new_config, config=config)) + candidate = "\n".join(new_config) + self.conn.get_diff = MagicMock( + return_value=self.cliconf_obj.get_diff(candidate, config) + ) + self.execute_module(changed=True, commands=new_config) + + def test_vyos_config_match_none(self): + lines = [ + "set system interfaces ethernet eth0 address 1.2.3.4/24", + "set system interfaces ethernet eth0 description test string", + ] + set_module_args(dict(lines=lines, match="none")) + candidate = "\n".join(lines) + self.conn.get_diff = MagicMock( + return_value=self.cliconf_obj.get_diff( + candidate, None, diff_match="none" + ) + ) + self.execute_module(changed=True, commands=lines, sort=False) diff --git a/tests/unit/modules/network/vyos/test_vyos_facts.py b/tests/unit/modules/network/vyos/test_vyos_facts.py new file mode 100644 index 0000000..b22a523 --- /dev/null +++ b/tests/unit/modules/network/vyos/test_vyos_facts.py @@ -0,0 +1,109 @@ +# (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 +import json +from ansible_collections.vyos.vyos.tests.unit.compat.mock import patch +from ansible_collections.vyos.vyos.plugins.modules import vyos_facts +from ansible_collections.vyos.vyos.tests.unit.modules.utils import ( + set_module_args, +) +from .vyos_module import TestVyosModule, load_fixture + + +class TestVyosFactsModule(TestVyosModule): + module = vyos_facts + + def setUp(self): + super(TestVyosFactsModule, self).setUp() + self.mock_run_commands = patch( + "ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.facts.legacy.base.run_commands" + ) + self.run_commands = self.mock_run_commands.start() + + self.mock_get_resource_connection = patch( + "ansible_collections.ansible.netcommon.plugins.module_utils.network.common.facts.facts.get_resource_connection" + ) + self.get_resource_connection = ( + self.mock_get_resource_connection.start() + ) + + self.mock_get_capabilities = patch( + "ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.facts.legacy.base.get_capabilities" + ) + self.get_capabilities = self.mock_get_capabilities.start() + self.get_capabilities.return_value = { + "device_info": { + "network_os": "vyos", + "network_os_hostname": "vyos01", + "network_os_model": "VMware", + "network_os_version": "VyOS 1.1.7", + }, + "network_api": "cliconf", + } + + def tearDown(self): + super(TestVyosFactsModule, self).tearDown() + self.mock_run_commands.stop() + self.mock_get_capabilities.stop() + self.mock_get_resource_connection.stop() + + def load_fixtures(self, commands=None): + def load_from_file(*args, **kwargs): + module, commands = args + output = list() + for item in commands: + try: + obj = json.loads(item) + command = obj["command"] + except ValueError: + command = item + filename = str(command).replace(" ", "_") + output.append(load_fixture(filename)) + return output + + self.run_commands.side_effect = load_from_file + + def test_vyos_facts_default(self): + set_module_args(dict(gather_subset="default")) + result = self.execute_module() + facts = result.get("ansible_facts") + self.assertEqual(len(facts), 10) + self.assertEqual(facts["ansible_net_hostname"].strip(), "vyos01") + self.assertEqual(facts["ansible_net_version"], "VyOS 1.1.7") + + def test_vyos_facts_not_all(self): + set_module_args(dict(gather_subset="!all")) + result = self.execute_module() + facts = result.get("ansible_facts") + self.assertEqual(len(facts), 10) + self.assertEqual(facts["ansible_net_hostname"].strip(), "vyos01") + self.assertEqual(facts["ansible_net_version"], "VyOS 1.1.7") + + def test_vyos_facts_exclude_most(self): + set_module_args(dict(gather_subset=["!neighbors", "!config"])) + result = self.execute_module() + facts = result.get("ansible_facts") + self.assertEqual(len(facts), 10) + self.assertEqual(facts["ansible_net_hostname"].strip(), "vyos01") + self.assertEqual(facts["ansible_net_version"], "VyOS 1.1.7") + + def test_vyos_facts_invalid_subset(self): + set_module_args(dict(gather_subset="cereal")) + self.execute_module(failed=True) diff --git a/tests/unit/modules/network/vyos/test_vyos_ping.py b/tests/unit/modules/network/vyos/test_vyos_ping.py new file mode 100644 index 0000000..e307610 --- /dev/null +++ b/tests/unit/modules/network/vyos/test_vyos_ping.py @@ -0,0 +1,107 @@ +# (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_ping +from ansible_collections.vyos.vyos.tests.unit.modules.utils import ( + set_module_args, +) +from .vyos_module import TestVyosModule, load_fixture + + +class TestVyosPingModule(TestVyosModule): + + module = vyos_ping + + def setUp(self): + super(TestVyosPingModule, self).setUp() + self.mock_run_commands = patch( + "ansible_collections.vyos.vyos.plugins.modules.vyos_ping.run_commands" + ) + self.run_commands = self.mock_run_commands.start() + + def tearDown(self): + super(TestVyosPingModule, self).tearDown() + self.mock_run_commands.stop() + + def load_fixtures(self, commands=None): + def load_from_file(*args, **kwargs): + commands = kwargs["commands"] + output = list() + + for command in commands: + filename = str(command).split(" | ")[0].replace(" ", "_") + output.append(load_fixture("vyos_ping_%s" % filename)) + return output + + self.run_commands.side_effect = load_from_file + + def test_vyos_ping_expected_success(self): + """ Test for successful pings when destination should be reachable """ + set_module_args(dict(count=2, dest="10.10.10.10")) + self.execute_module() + + def test_vyos_ping_expected_failure(self): + """ Test for unsuccessful pings when destination should not be reachable """ + set_module_args(dict(count=4, dest="10.10.10.20", state="absent")) + self.execute_module() + + def test_vyos_ping_unexpected_success(self): + """ Test for successful pings when destination should not be reachable - FAIL. """ + set_module_args(dict(count=2, dest="10.10.10.10", state="absent")) + self.execute_module(failed=True) + + def test_vyos_ping_unexpected_failure(self): + """ Test for unsuccessful pings when destination should be reachable - FAIL. """ + set_module_args(dict(count=4, dest="10.10.10.20")) + self.execute_module(failed=True) + + def test_vyos_ping_failure_stats(self): + """Test for asserting stats when ping fails""" + set_module_args(dict(count=4, dest="10.10.10.20")) + result = self.execute_module(failed=True) + self.assertEqual(result["packet_loss"], "100%") + self.assertEqual(result["packets_rx"], 0) + self.assertEqual(result["packets_tx"], 4) + + def test_vyos_ping_success_stats(self): + """Test for asserting stats when ping passes""" + set_module_args(dict(count=2, dest="10.10.10.10")) + result = self.execute_module() + self.assertEqual(result["packet_loss"], "0%") + self.assertEqual(result["packets_rx"], 2) + self.assertEqual(result["packets_tx"], 2) + self.assertEqual(result["rtt"]["min"], 12) + self.assertEqual(result["rtt"]["avg"], 17) + self.assertEqual(result["rtt"]["max"], 22) + self.assertEqual(result["rtt"]["mdev"], 10) + + def test_vyos_ping_success_stats_with_options(self): + set_module_args(dict(count=10, ttl=128, size=512, dest="10.10.10.11")) + result = self.execute_module() + self.assertEqual(result["packet_loss"], "0%") + self.assertEqual(result["packets_rx"], 10) + self.assertEqual(result["packets_tx"], 10) + self.assertEqual(result["rtt"]["min"], 1) + self.assertEqual(result["rtt"]["avg"], 3) + self.assertEqual(result["rtt"]["max"], 21) + self.assertEqual(result["rtt"]["mdev"], 5) diff --git a/tests/unit/modules/network/vyos/test_vyos_static_route.py b/tests/unit/modules/network/vyos/test_vyos_static_route.py new file mode 100644 index 0000000..e020ca5 --- /dev/null +++ b/tests/unit/modules/network/vyos/test_vyos_static_route.py @@ -0,0 +1,71 @@ +# (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_static_route +from ansible_collections.vyos.vyos.tests.unit.modules.utils import ( + set_module_args, +) +from .vyos_module import TestVyosModule + + +class TestVyosStaticRouteModule(TestVyosModule): + + module = vyos_static_route + + def setUp(self): + super(TestVyosStaticRouteModule, self).setUp() + + self.mock_get_config = patch( + "ansible_collections.vyos.vyos.plugins.modules.vyos_static_route.get_config" + ) + self.get_config = self.mock_get_config.start() + + self.mock_load_config = patch( + "ansible_collections.vyos.vyos.plugins.modules.vyos_static_route.load_config" + ) + self.load_config = self.mock_load_config.start() + + def tearDown(self): + super(TestVyosStaticRouteModule, self).tearDown() + + self.mock_get_config.stop() + self.mock_load_config.stop() + + def load_fixtures(self, commands=None, transport="cli"): + self.load_config.return_value = dict(diff=None, session="session") + + def test_vyos_static_route_present(self): + set_module_args( + dict( + prefix="172.26.0.0/16", + next_hop="172.26.4.1", + admin_distance="1", + ) + ) + result = self.execute_module(changed=True) + self.assertEqual( + result["commands"], + [ + "set protocols static route 172.26.0.0/16 next-hop 172.26.4.1 distance 1" + ], + ) diff --git a/tests/unit/modules/network/vyos/test_vyos_system.py b/tests/unit/modules/network/vyos/test_vyos_system.py new file mode 100644 index 0000000..c22f7c1 --- /dev/null +++ b/tests/unit/modules/network/vyos/test_vyos_system.py @@ -0,0 +1,116 @@ +# (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_system +from ansible_collections.vyos.vyos.tests.unit.modules.utils import ( + set_module_args, +) +from .vyos_module import TestVyosModule, load_fixture + + +class TestVyosSystemModule(TestVyosModule): + + module = vyos_system + + def setUp(self): + super(TestVyosSystemModule, self).setUp() + + self.mock_get_config = patch( + "ansible_collections.vyos.vyos.plugins.modules.vyos_system.get_config" + ) + self.get_config = self.mock_get_config.start() + + self.mock_load_config = patch( + "ansible_collections.vyos.vyos.plugins.modules.vyos_system.load_config" + ) + self.load_config = self.mock_load_config.start() + + def tearDown(self): + super(TestVyosSystemModule, self).tearDown() + + self.mock_get_config.stop() + self.mock_load_config.stop() + + def load_fixtures(self, commands=None): + self.get_config.return_value = load_fixture("vyos_config_config.cfg") + + def test_vyos_system_hostname(self): + set_module_args(dict(host_name="foo")) + commands = ["set system host-name 'foo'"] + self.execute_module(changed=True, commands=commands) + + def test_vyos_system_clear_hostname(self): + set_module_args(dict(host_name="foo", state="absent")) + commands = ["delete system host-name"] + self.execute_module(changed=True, commands=commands) + + def test_vyos_remove_single_name_server(self): + set_module_args(dict(name_server=["8.8.4.4"], state="absent")) + commands = ["delete system name-server '8.8.4.4'"] + self.execute_module(changed=True, commands=commands) + + def test_vyos_system_domain_name(self): + set_module_args(dict(domain_name="example2.com")) + commands = ["set system domain-name 'example2.com'"] + self.execute_module(changed=True, commands=commands) + + def test_vyos_system_clear_domain_name(self): + set_module_args(dict(domain_name="example.com", state="absent")) + commands = ["delete system domain-name"] + self.execute_module(changed=True, commands=commands) + + def test_vyos_system_domain_search(self): + set_module_args( + dict(domain_search=["foo.example.com", "bar.example.com"]) + ) + commands = [ + "set system domain-search domain 'foo.example.com'", + "set system domain-search domain 'bar.example.com'", + ] + self.execute_module(changed=True, commands=commands) + + def test_vyos_system_clear_domain_search(self): + set_module_args(dict(domain_search=[])) + commands = ["delete system domain-search domain"] + self.execute_module(changed=True, commands=commands) + + def test_vyos_system_no_change(self): + set_module_args( + dict( + host_name="router", + domain_name="example.com", + name_server=["8.8.8.8", "8.8.4.4"], + ) + ) + result = self.execute_module() + self.assertEqual([], result["commands"]) + + def test_vyos_system_clear_all(self): + set_module_args(dict(state="absent")) + commands = [ + "delete system host-name", + "delete system domain-search domain", + "delete system domain-name", + "delete system name-server", + ] + self.execute_module(changed=True, commands=commands) diff --git a/tests/unit/modules/network/vyos/test_vyos_user.py b/tests/unit/modules/network/vyos/test_vyos_user.py new file mode 100644 index 0000000..d4c2dbe --- /dev/null +++ b/tests/unit/modules/network/vyos/test_vyos_user.py @@ -0,0 +1,139 @@ +# (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_user +from ansible_collections.vyos.vyos.tests.unit.modules.utils import ( + set_module_args, +) +from .vyos_module import TestVyosModule, load_fixture + + +class TestVyosUserModule(TestVyosModule): + + module = vyos_user + + def setUp(self): + super(TestVyosUserModule, self).setUp() + + self.mock_get_config = patch( + "ansible_collections.vyos.vyos.plugins.modules.vyos_user.get_config" + ) + self.get_config = self.mock_get_config.start() + + self.mock_load_config = patch( + "ansible_collections.vyos.vyos.plugins.modules.vyos_user.load_config" + ) + self.load_config = self.mock_load_config.start() + + def tearDown(self): + super(TestVyosUserModule, self).tearDown() + self.mock_get_config.stop() + self.mock_load_config.stop() + + def load_fixtures(self, commands=None, transport="cli"): + self.get_config.return_value = load_fixture("vyos_user_config.cfg") + self.load_config.return_value = dict(diff=None, session="session") + + def test_vyos_user_password(self): + set_module_args(dict(name="ansible", configured_password="test")) + result = self.execute_module(changed=True) + self.assertEqual( + result["commands"], + [ + "set system login user ansible authentication plaintext-password test" + ], + ) + + def test_vyos_user_delete(self): + set_module_args(dict(name="ansible", state="absent")) + result = self.execute_module(changed=True) + self.assertEqual( + result["commands"], ["delete system login user ansible"] + ) + + def test_vyos_user_level(self): + set_module_args(dict(name="ansible", level="operator")) + result = self.execute_module(changed=True) + self.assertEqual( + result["commands"], + ["set system login user ansible level operator"], + ) + + def test_vyos_user_level_invalid(self): + set_module_args(dict(name="ansible", level="sysadmin")) + self.execute_module(failed=True) + + def test_vyos_user_purge(self): + set_module_args(dict(purge=True)) + result = self.execute_module(changed=True) + self.assertEqual( + sorted(result["commands"]), + sorted( + [ + "delete system login user ansible", + "delete system login user admin", + ] + ), + ) + + def test_vyos_user_update_password_changed(self): + set_module_args( + dict( + name="test", + configured_password="test", + update_password="on_create", + ) + ) + result = self.execute_module(changed=True) + self.assertEqual( + result["commands"], + [ + "set system login user test authentication plaintext-password test" + ], + ) + + def test_vyos_user_update_password_on_create_ok(self): + set_module_args( + dict( + name="ansible", + configured_password="test", + update_password="on_create", + ) + ) + self.execute_module() + + def test_vyos_user_update_password_always(self): + set_module_args( + dict( + name="ansible", + configured_password="test", + update_password="always", + ) + ) + result = self.execute_module(changed=True) + self.assertEqual( + result["commands"], + [ + "set system login user ansible authentication plaintext-password test" + ], + ) diff --git a/tests/unit/modules/network/vyos/vyos_module.py b/tests/unit/modules/network/vyos/vyos_module.py new file mode 100644 index 0000000..fb15c71 --- /dev/null +++ b/tests/unit/modules/network/vyos/vyos_module.py @@ -0,0 +1,104 @@ +# (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 + +import os +import json + +from ansible_collections.vyos.vyos.tests.unit.modules.utils import ( + AnsibleExitJson, + AnsibleFailJson, + ModuleTestCase, +) + + +fixture_path = os.path.join(os.path.dirname(__file__), "fixtures") +fixture_data = {} + + +def load_fixture(name): + path = os.path.join(fixture_path, name) + + if path in fixture_data: + return fixture_data[path] + + with open(path) as f: + data = f.read() + + try: + data = json.loads(data) + except Exception: + pass + + fixture_data[path] = data + return data + + +class TestVyosModule(ModuleTestCase): + def execute_module( + self, + failed=False, + changed=False, + commands=None, + sort=True, + defaults=False, + ): + self.load_fixtures(commands) + + if failed: + result = self.failed() + self.assertTrue(result["failed"], result) + else: + result = self.changed(changed) + self.assertEqual(result["changed"], changed, result) + + if commands is not None: + if sort: + self.assertEqual( + sorted(commands), + sorted(result["commands"]), + result["commands"], + ) + else: + self.assertEqual( + commands, result["commands"], result["commands"] + ) + + return result + + def failed(self): + with self.assertRaises(AnsibleFailJson) as exc: + self.module.main() + + result = exc.exception.args[0] + self.assertTrue(result["failed"], result) + return result + + def changed(self, changed=False): + with self.assertRaises(AnsibleExitJson) as exc: + self.module.main() + + result = exc.exception.args[0] + self.assertEqual(result["changed"], changed, result) + return result + + def load_fixtures(self, commands=None): + pass diff --git a/tests/unit/modules/utils.py b/tests/unit/modules/utils.py new file mode 100644 index 0000000..2c9c602 --- /dev/null +++ b/tests/unit/modules/utils.py @@ -0,0 +1,48 @@ +import json + +from ansible_collections.vyos.vyos.tests.unit.compat import unittest +from ansible_collections.vyos.vyos.tests.unit.compat.mock import patch +from ansible.module_utils import basic +from ansible.module_utils._text import to_bytes + + +def set_module_args(args): + if "_ansible_remote_tmp" not in args: + args["_ansible_remote_tmp"] = "/tmp" + if "_ansible_keep_remote_files" not in args: + args["_ansible_keep_remote_files"] = False + + args = json.dumps({"ANSIBLE_MODULE_ARGS": args}) + basic._ANSIBLE_ARGS = to_bytes(args) + + +class AnsibleExitJson(Exception): + pass + + +class AnsibleFailJson(Exception): + pass + + +def exit_json(*args, **kwargs): + if "changed" not in kwargs: + kwargs["changed"] = False + raise AnsibleExitJson(kwargs) + + +def fail_json(*args, **kwargs): + kwargs["failed"] = True + raise AnsibleFailJson(kwargs) + + +class ModuleTestCase(unittest.TestCase): + def setUp(self): + self.mock_module = patch.multiple( + basic.AnsibleModule, exit_json=exit_json, fail_json=fail_json + ) + self.mock_module.start() + self.mock_sleep = patch("time.sleep") + self.mock_sleep.start() + set_module_args({}) + self.addCleanup(self.mock_module.stop) + self.addCleanup(self.mock_sleep.stop) diff --git a/tests/unit/requirements.txt b/tests/unit/requirements.txt new file mode 100644 index 0000000..a9772be --- /dev/null +++ b/tests/unit/requirements.txt @@ -0,0 +1,42 @@ +boto3 +placebo +pycrypto +passlib +pypsrp +python-memcached +pytz +pyvmomi +redis +requests +setuptools > 0.6 # pytest-xdist installed via requirements does not work with very old setuptools (sanity_ok) +unittest2 ; python_version < '2.7' +importlib ; python_version < '2.7' +netaddr +ipaddress +netapp-lib +solidfire-sdk-python + +# requirements for F5 specific modules +f5-sdk ; python_version >= '2.7' +f5-icontrol-rest ; python_version >= '2.7' +deepdiff + +# requirement for Fortinet specific modules +pyFMG + +# requirement for aci_rest module +xmljson + +# requirement for winrm connection plugin tests +pexpect + +# requirement for the linode module +linode-python # APIv3 +linode_api4 ; python_version > '2.6' # APIv4 + +# requirement for the gitlab module +python-gitlab +httmock + +# requirment for kubevirt modules +openshift ; python_version >= '2.7' |