From 5ca390678dc9119af3ceca9db9290b8507d322d3 Mon Sep 17 00:00:00 2001 From: Jeff Kala <48843785+jeffkala@users.noreply.github.com> Date: Wed, 5 Apr 2023 11:02:06 -0600 Subject: [PATCH] Remove ABC, deprecate and remove show_list and config_list methods, add fact properties (#275) * deprecate list methods * remove ABC and use standard python inheritance * clean up commented out code * bump version to alpha and prep changelog --- docs/admin/release_notes/version_1_0.md | 10 +++ mkdocs.yml | 1 + pyntc/devices/aireos_device.py | 62 +------------------ pyntc/devices/asa_device.py | 22 ------- pyntc/devices/base_device.py | 62 ------------------- pyntc/devices/eos_device.py | 23 +------ pyntc/devices/f5_device.py | 3 +- pyntc/devices/ios_device.py | 42 +------------ pyntc/devices/jnpr_device.py | 33 ++-------- pyntc/devices/nxos_device.py | 62 +++++++------------ pyproject.toml | 2 +- tests/unit/test_devices/test_aireos_device.py | 13 ++-- tests/unit/test_devices/test_asa_device.py | 9 +-- tests/unit/test_devices/test_eos_device.py | 15 ++--- tests/unit/test_devices/test_ios_device.py | 9 +-- tests/unit/test_devices/test_jnpr_device.py | 14 ++--- tests/unit/test_devices/test_nxos_device.py | 14 ++--- 17 files changed, 81 insertions(+), 315 deletions(-) create mode 100644 docs/admin/release_notes/version_1_0.md diff --git a/docs/admin/release_notes/version_1_0.md b/docs/admin/release_notes/version_1_0.md new file mode 100644 index 00000000..8b8fe3d3 --- /dev/null +++ b/docs/admin/release_notes/version_1_0.md @@ -0,0 +1,10 @@ +# v1.0 Release Notes + +## [1.0.0a0] 04-2023 + +### Added + +### Changed + +### Deprecated + diff --git a/mkdocs.yml b/mkdocs.yml index 05ab9ac6..5594aec5 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -112,6 +112,7 @@ nav: - v0.18: "admin/release_notes/version_0_18.md" - v0.19: "admin/release_notes/version_0_19.md" - v0.20: "admin/release_notes/version_0_20.md" + - v1.0: "admin/release_notes/version_1_0.md" - Developer Guide: - Extending the Library: "dev/extending.md" - Contributing to the Library: "dev/contributing.md" diff --git a/pyntc/devices/aireos_device.py b/pyntc/devices/aireos_device.py index 9f3ab35b..002cc268 100644 --- a/pyntc/devices/aireos_device.py +++ b/pyntc/devices/aireos_device.py @@ -7,6 +7,7 @@ import time from netmiko import ConnectHandler + from pyntc import log from pyntc.errors import ( CommandError, @@ -616,35 +617,6 @@ def config(self, command, **netmiko_args): ) return command_responses - def config_list(self, commands, **netmiko_args): # noqa: D401 - """ - DEPRECATED - Use the `config` method. - - Send config commands to device. - - By default, entering and exiting config mode is handled automatically. - To disable entering and exiting config mode, pass `enter_config_mode` and `exit_config_mode` in ``**netmiko_args``. - This supports all arguments supported by Netmiko's `send_config_set` method using ``netmiko_args``. - - Args: - commands (list): The commands to send to the device. - **netmiko_args: Any argument supported by ``netmiko.base_connection.BaseConnection.send_config_set``. - - Returns: - list: Each command's input and ouput from sending the command in ``commands``. - - Raises: - TypeError: When sending an argument in ``**netmiko_args`` that is not supported. - CommandListError: When one of the commands reports an error on the device. - - Example: - >>> device = AIREOSDevice(**connection_args) - >>> device.config_list(["interface hostname virtual wlc1.site.com", "config interface vlan airway 20"]) - >>> - """ - log.warning("config_list() is deprecated; use config.") - return self.config(commands, **netmiko_args) - def confirm_is_active(self): """ Confirm that the device is either standalone or the active device in a high availability cluster. @@ -1425,38 +1397,6 @@ def show(self, command, expect_string=None, **netmiko_args): ) return command_responses - def show_list(self, commands, **netmiko_args): # noqa: D401 - """ - DEPRECATED - Use the `show` method. - - Send operational commands to the device. - - Args: - commands (list): The list of commands to send to the device. - **netmiko_args: Any argument supported by ``netmiko.ConnectHandler.send_command``. - - Returns: - list: The data returned from the device for all commands. - - Raises: - TypeError: When sending an argument in ``**netmiko_args`` that is not supported. - CommandListError: When the returned data indicates one of the commands failed. - - Example: - >>> device = AIREOSDevice(**connection_args) - >>> command_data = device._send_command(["show sysinfo", "show boot"]) - >>> print(command_data[0]) - Product Version.....8.2.170.0 - System Up Time......3 days 2 hrs 20 mins 30 sec - ... - >>> print(command_data[1]) - Primary Boot Image............................... 8.2.170.0 (default) (active) - Backup Boot Image................................ 8.5.110.0 - >>> - """ - log.warning("show_list() is deprecated; use show.") - return self.show(commands, **netmiko_args) - @property def startup_config(self): """ diff --git a/pyntc/devices/asa_device.py b/pyntc/devices/asa_device.py index b27f05a8..4091a2f2 100644 --- a/pyntc/devices/asa_device.py +++ b/pyntc/devices/asa_device.py @@ -419,17 +419,6 @@ def config(self, command): self.native.exit_config_mode() log.info("Host %s: Device configured with command %s.", self.host, command) - def config_list(self, commands): - """Send configuration commands in list format to a device. - - DEPRECATED - Use the `config` method. - - Args: - commands (list): List with multiple commands. - """ - log.warning("config_list() is deprecated; use config().") - self.config(commands) - @property def connected_interface(self) -> str: """ @@ -1124,17 +1113,6 @@ def show(self, command, expect_string=None): return responses return self._send_command(command, expect_string=expect_string) - def show_list(self, commands): - """Send show commands in list format to a device. - - DEPRECATED - Use the `show` method. - - Args: - commands (list): List with multiple commands. - """ - log.warning("show_list() is deprecated; use show().") - return self.show(commands) - @property def startup_config(self): """ diff --git a/pyntc/devices/base_device.py b/pyntc/devices/base_device.py index 2fdc1ba3..f05ef836 100644 --- a/pyntc/devices/base_device.py +++ b/pyntc/devices/base_device.py @@ -1,6 +1,5 @@ """The module contains the base class that all device classes must inherit from.""" -import abc import importlib import warnings @@ -27,8 +26,6 @@ def fix_docs(cls): class BaseDevice: # pylint: disable=too-many-instance-attributes,too-many-public-methods """Base Device ABC.""" - __metaclass__ = abc.ABCMeta - def __init__( self, host, username, password, device_type=None, **kwargs ): # noqa: D403 # pylint: disable=unused-argument @@ -67,10 +64,6 @@ def _image_booted(self, image_name, **vendor_specifics): """ raise NotImplementedError - #################### - # ABSTRACT METHODS # - #################### - @abc.abstractmethod def backup_running_config(self, filename): """Save a local copy of the running config. @@ -80,7 +73,6 @@ def backup_running_config(self, filename): raise NotImplementedError @property - @abc.abstractmethod def boot_options(self): """Get current boot variables. @@ -91,7 +83,6 @@ def boot_options(self): """ raise NotImplementedError - @abc.abstractmethod def checkpoint(self, filename): """Save a checkpoint of the running configuration to the device. @@ -100,12 +91,10 @@ def checkpoint(self, filename): """ raise NotImplementedError - @abc.abstractmethod def close(self): """Close the connection to the device.""" raise NotImplementedError - @abc.abstractmethod def config(self, command): """Send a configuration command. @@ -117,20 +106,7 @@ def config(self, command): """ raise NotImplementedError - @abc.abstractmethod - def config_list(self, commands): - """Send a list of configuration commands. - - Args: - commands (list): A list of commands to send to the device. - - Raises: - CommandListError: If there is a problem with one of the commands in the list. - """ - raise NotImplementedError - @property - @abc.abstractmethod def uptime(self): """Uptime integer property, part of device facts. @@ -140,7 +116,6 @@ def uptime(self): raise NotImplementedError @property - @abc.abstractmethod def os_version(self): """Operating System string property, part of device facts. @@ -150,7 +125,6 @@ def os_version(self): raise NotImplementedError @property - @abc.abstractmethod def interfaces(self): """Interfaces list of strings property, part of device facts. @@ -160,7 +134,6 @@ def interfaces(self): raise NotImplementedError @property - @abc.abstractmethod def hostname(self): """Host name string property, part of device facts. @@ -170,7 +143,6 @@ def hostname(self): raise NotImplementedError @property - @abc.abstractmethod def fqdn(self): """ Get FQDN of the device. @@ -181,7 +153,6 @@ def fqdn(self): raise NotImplementedError @property - @abc.abstractmethod def uptime_string(self): """Uptime string string property, part of device facts. @@ -191,7 +162,6 @@ def uptime_string(self): raise NotImplementedError @property - @abc.abstractmethod def serial_number(self): """ Get serial number of the device. @@ -202,7 +172,6 @@ def serial_number(self): raise NotImplementedError @property - @abc.abstractmethod def model(self): """Model string property, part of device facts. @@ -212,7 +181,6 @@ def model(self): raise NotImplementedError @property - @abc.abstractmethod def vlans(self): """Vlans lost of strings property, part of device facts. @@ -242,7 +210,6 @@ def facts(self): # noqa 401 if self.device_type == "cisco_ios_ssh": facts[self.device_type] = {"config_register": self.config_register} # pylint: disable=no-member - @abc.abstractmethod def file_copy(self, src, dest=None, **kwargs): """Send a local file to the device. @@ -259,7 +226,6 @@ def file_copy(self, src, dest=None, **kwargs): """ raise NotImplementedError - @abc.abstractmethod def file_copy_remote_exists(self, src, dest=None, **kwargs): """Check if a remote file exists. @@ -281,7 +247,6 @@ def file_copy_remote_exists(self, src, dest=None, **kwargs): True if the remote file exists, False if it doesn't. """ - @abc.abstractmethod def install_os(self, image_name, **vendor_specifics): """Install the OS from specified image_name. @@ -314,12 +279,10 @@ def install_os(self, image_name, **vendor_specifics): """ raise NotImplementedError - @abc.abstractmethod def open(self): """Open a connection to the device.""" raise NotImplementedError - @abc.abstractmethod def reboot(self, timer=0): """Reboot the device. @@ -329,7 +292,6 @@ def reboot(self, timer=0): """ raise NotImplementedError - @abc.abstractmethod def rollback(self, checkpoint_file): """Rollback to a checkpoint file. @@ -339,12 +301,10 @@ def rollback(self, checkpoint_file): raise NotImplementedError @property - @abc.abstractmethod def running_config(self): """Return the running configuration of the device.""" raise NotImplementedError - @abc.abstractmethod def save(self, filename=None): """Save a device's running configuration. @@ -355,7 +315,6 @@ def save(self, filename=None): """ raise NotImplementedError - @abc.abstractmethod def set_boot_options(self, image_name, **vendor_specifics): """Set boot variables like system image and kickstart image. @@ -376,7 +335,6 @@ def set_boot_options(self, image_name, **vendor_specifics): """ raise NotImplementedError - @abc.abstractmethod def show(self, command, raw_text=False): """Send a non-configuration command. @@ -391,31 +349,11 @@ def show(self, command, raw_text=False): """ raise NotImplementedError - @abc.abstractmethod - def show_list(self, commands, raw_text=False): - """Send a list of non-configuration commands. - - Args: - commands (list): A list of commands to send to the device. - - Keyword Args: - raw_text (bool): Whether to return raw text or structured data. - - Returns: - A list of outputs for each show command - """ - raise NotImplementedError - @property - @abc.abstractmethod def startup_config(self): """Return the startup configuration of the device.""" raise NotImplementedError - ################################# - # Inherited implemented methods # - ################################# - def feature(self, feature_name): """Return a feature class based on the ``feature_name`` for the appropriate subclassed device type.""" try: diff --git a/pyntc/devices/eos_device.py b/pyntc/devices/eos_device.py index 32189c5d..4efab307 100644 --- a/pyntc/devices/eos_device.py +++ b/pyntc/devices/eos_device.py @@ -8,6 +8,7 @@ from pyeapi import connect as eos_connect from pyeapi.client import Node as EOSNative from pyeapi.eapilib import CommandError as EOSCommandError + from pyntc import log from pyntc.errors import ( CommandError, @@ -217,17 +218,6 @@ def config(self, commands): raise CommandError(commands, e.message) raise CommandListError(commands, e.commands[len(e.commands) - 1], e.message) - def config_list(self, commands): - """Send configuration commands in list format to a device. - - DEPRECATED - Use the `config` method. - - Args: - commands (list): List with multiple commands. - """ - log.warning("config_list() is deprecated; use config().") - self.config(commands) - def enable(self): """Ensure device is in enable mode. @@ -606,17 +596,6 @@ def show(self, commands, raw_text=False): log.error("Host %s: Command list error for commands %s with message %s.", self.host, commands, e.message) raise CommandListError(commands, e.commands[len(e.commands) - 1], e.message) - def show_list(self, commands): - """Send show commands in list format to a device. - - DEPRECATED - Use the `show` method. - - Args: - commands (list): List with multiple commands. - """ - log.warning("show_list() is deprecated; use show().") - self.show(commands) - @property def startup_config(self): """Get startup configuration. diff --git a/pyntc/devices/f5_device.py b/pyntc/devices/f5_device.py index b257cf6f..7fa64a50 100644 --- a/pyntc/devices/f5_device.py +++ b/pyntc/devices/f5_device.py @@ -8,6 +8,7 @@ import requests from f5.bigip import ManagementRoot + from pyntc import log from pyntc.errors import FileTransferError, NotEnoughFreeSpaceError, NTCFileNotFoundError, OSInstallError @@ -708,7 +709,7 @@ def reboot(self, timer=0, volume=None, **kwargs): log.debug("Host %s: Reboot to volume %s succeeded.", self.host, volume) def rollback(self, checkpoint_file): - """Rollback to checkpoint configurtion file. + """Rollback to checkpoint configuration file. Args: checkpoint_file (str): Name of checkpoint file. diff --git a/pyntc/devices/ios_device.py b/pyntc/devices/ios_device.py index a8a9cffe..21b9dfa3 100644 --- a/pyntc/devices/ios_device.py +++ b/pyntc/devices/ios_device.py @@ -6,6 +6,7 @@ import time from netmiko import ConnectHandler, FileTransfer + from pyntc import log from pyntc.errors import ( CommandError, @@ -398,36 +399,6 @@ def config(self, command, **netmiko_args): log.info("Host %s: Device configured with command responses %s.", self.host, command_responses) return command_responses - def config_list(self, commands, **netmiko_args): # noqa: D401 - r""" - DEPRECATED - Use the `config` method. - - Send config commands to device. - - By default, entering and exiting config mode is handled automatically. - To disable entering and exiting config mode, pass `enter_config_mode` and `exit_config_mode` in ``**netmiko_args``. - This supports all arguments supported by Netmiko's `send_config_set` method using ``netmiko_args``. - - Args: - commands (list): The commands to send to the device. - **netmiko_args: Any argument supported by ``netmiko.ConnectHandler.send_config_set``. - - Returns: - list: Each command's input and output from sending the command in ``commands``. - - Raises: - TypeError: When sending an argument in ``**netmiko_args`` that is not supported. - CommandListError: When one of the commands reports an error on the device. - - Example: - >>> device = IOSDevice(**connection_args) - >>> device.config_list(["interface Gig0/1", "description x-connect"]) - ['host(config)#interface Gig0/1\nhost(config-if)#, 'description x-connect\nhost(config-if)#'] - >>> - """ - log.warning("config_list() is deprecated; use config.") - return self.config(commands, **netmiko_args) - def confirm_is_active(self): """ Confirm that the device is either standalone or the active device in a high availability cluster. @@ -1135,17 +1106,6 @@ def show(self, command, expect_string=None, **netmiko_args): return responses return self._send_command(command, expect_string=expect_string, **netmiko_args) - def show_list(self, commands): - """Send show commands in list format to a device. - - DEPRECATED - Use the `show` method. - - Args: - commands (list): List with multiple commands. - """ - log.warning("show_list() is deprecated; use show().") - return self.show(commands) - @property def startup_config(self): """Get startup configuration. diff --git a/pyntc/devices/jnpr_device.py b/pyntc/devices/jnpr_device.py index 17048ee8..65b369f8 100644 --- a/pyntc/devices/jnpr_device.py +++ b/pyntc/devices/jnpr_device.py @@ -13,6 +13,7 @@ from jnpr.junos.utils.fs import FS as JunosNativeFS from jnpr.junos.utils.scp import SCP from jnpr.junos.utils.sw import SW as JunosNativeSW + from pyntc.errors import CommandError, CommandListError, FileTransferError, RebootTimeoutError from .base_device import BaseDevice, fix_docs @@ -144,12 +145,12 @@ def config(self, commands, format="set"): """Send configuration commands to a device. Args: - commands (str, list): String with single command, or list with multiple commands. + commands (str, list): String with single command, or list with multiple commands. Raises: - ConfigLoadError: Issue with loading the command. - CommandError: Issue with the command provided, if its a single command, passed in as a string. - CommandListError: Issue with a command in the list provided. + ConfigLoadError: Issue with loading the command. + CommandError: Issue with the command provided, if its a single command, passed in as a string. + CommandListError: Issue with a command in the list provided. """ if isinstance(commands, str): try: @@ -166,18 +167,6 @@ def config(self, commands, format="set"): except ConfigLoadError as e: raise CommandListError(commands, command, e.message) - def config_list(self, commands, format="set"): - """Send configuration commands in list format to a device. - - DEPRECATED - Use the `config` method. - - Args: - commands (list): List with multiple commands. - format (str): The Junos format the commands are in. - """ - warnings.warn("config_list() is deprecated; use config().", DeprecationWarning) - self.config(commands, format=format) - @property def connected(self): """Get connection status of device. @@ -463,18 +452,6 @@ def show(self, commands): return responses[0] return responses - def show_list(self, commands, raw_text=True): - """Send show commands in list format to a device. - - DEPRECATED - Use the `show` method. - - Args: - commands (list): List with multiple commands. - raw_text (bool): Return raw text or structured text. - """ - warnings.warn("show_list() is deprecated; use show().", DeprecationWarning) - return self.show(commands) - @property def startup_config(self): """Get startup configuration. diff --git a/pyntc/devices/nxos_device.py b/pyntc/devices/nxos_device.py index 0c3fe599..df4d1a72 100644 --- a/pyntc/devices/nxos_device.py +++ b/pyntc/devices/nxos_device.py @@ -3,6 +3,10 @@ import re import time +from pynxos.device import Device as NXOSNative +from pynxos.errors import CLIError +from pynxos.features.file_copy import FileTransferError as NXOSFileTransferError + from pyntc import log from pyntc.errors import ( CommandError, @@ -12,9 +16,6 @@ OSInstallError, RebootTimeoutError, ) -from pynxos.device import Device as NXOSNative -from pynxos.errors import CLIError -from pynxos.features.file_copy import FileTransferError as NXOSFileTransferError from .base_device import BaseDevice, fix_docs, RebootTimerError, RollbackError @@ -102,11 +103,18 @@ def config(self, command): """Send configuration command. Args: - command (str): command to be sent to the device. + command (str, list): command to be sent to the device. Raises: CommandError: Error if command is not succesfully ran on device. """ + if isinstance(command, list): + try: + self.native.config_list(command) + log.info("Host %s: Configured with commands: %s", self.host, command) + except CLIError as e: + log.error("Host %s: Command error with commands: %s and error message %s", self.host, command, str(e)) + raise CommandListError(command, e.command, str(e)) try: self.native.config(command) log.info("Host %s: Device configured with command %s.", self.host, command) @@ -114,22 +122,6 @@ def config(self, command): log.error("Host %s: Command error with commands: %s and error message %s", self.host, command, str(e)) raise CommandError(command, str(e)) - def config_list(self, commands): - """Send a list of configuration commands. - - Args: - commands (list): A list of commands. - - Raises: - CommandListError: Error if any of the commands in the list fail running on the device. - """ - try: - self.native.config_list(commands) - log.info("Host %s: Configured with commands: %s", self.host, commands) - except CLIError as e: - log.error("Host %s: Command error with commands: %s and error message %s", self.host, commands, str(e)) - raise CommandListError(commands, e.command, str(e)) - @property def uptime(self): """Get uptime of the device in seconds. @@ -161,7 +153,7 @@ def interfaces(self): """Get list of interfaces. Returns: - list: List of interfaces. + list: List of interfaces. """ if self._interfaces is None: self._interfaces = self.native.facts.get("interfaces") @@ -440,6 +432,14 @@ def show(self, command, raw_text=False): Returns: str: Results of the command ran. """ + log.debug("Host %s: Successfully executed command 'show' with responses.", self.host) + if isinstance(command, list): + try: + log.debug("Host %s: Successfully executed command 'show' with commands %s.", self.host, command) + return self.native.show_list(command, raw_text=raw_text) + except CLIError as e: + log.error("Host %s: Command error for command %s with message %s.", self.host, e.command, str(e)) + raise CommandListError(command, e.command, str(e)) try: log.debug("Host %s: Successfully executed command 'show'.", self.host) return self.native.show(command, raw_text=raw_text) @@ -447,26 +447,6 @@ def show(self, command, raw_text=False): log.error("Host %s: Command error %s.", self.host, str(e)) raise CommandError(command, str(e)) - def show_list(self, commands, raw_text=False): - """Send a list of non-configuration commands. - - Args: - commands (str): A list of commands to be sent to the device. - raw_text (bool, optional): Whether to return raw text or structured data. Defaults to False. - - Raises: - CommandListError: Error message stating which command failed. - - Returns: - list: Outputs of all the commands ran on the device. - """ - try: - log.debug("Host %s: Successfully executed command 'show' with commands %s.", self.host, commands) - return self.native.show_list(commands, raw_text=raw_text) - except CLIError as e: - log.error("Host %s: Command error for command %s with message %s.", self.host, e.command, str(e)) - raise CommandListError(commands, e.command, str(e)) - @property def startup_config(self): """Get startup configuration. diff --git a/pyproject.toml b/pyproject.toml index fac1ef73..40e54a36 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "pyntc" -version = "0.20.3" +version = "1.0.0a0" description = "SDK to simplify common workflows for Network Devices." authors = ["Network to Code, LLC "] readme = "README.md" diff --git a/tests/unit/test_devices/test_aireos_device.py b/tests/unit/test_devices/test_aireos_device.py index 60ce6324..059db59a 100644 --- a/tests/unit/test_devices/test_aireos_device.py +++ b/tests/unit/test_devices/test_aireos_device.py @@ -2,6 +2,7 @@ from unittest import mock import pytest + from pyntc.devices import aireos_device as aireos_module from pyntc.devices import AIREOSDevice @@ -378,14 +379,14 @@ def test_config_pass_invalid_list_command(mock_enter_config, mock_check_for_erro @mock.patch.object(AIREOSDevice, "config") def test_config_list(mock_config, aireos_device): config_commands = ["a", "b"] - aireos_device.config_list(config_commands) + aireos_device.config(config_commands) mock_config.assert_called_with(config_commands) @mock.patch.object(AIREOSDevice, "config") def test_config_list_pass_netmiko_args(mock_config, aireos_device): config_commands = ["a", "b"] - aireos_device.config_list(config_commands, strip_prompt=True) + aireos_device.config(config_commands, strip_prompt=True) mock_config.assert_called_with(config_commands, strip_prompt=True) @@ -1427,7 +1428,7 @@ def test_show_pass_invalid_list_command(mock_check_for_errors, aireos_send_comma @mock.patch.object(AIREOSDevice, "show") def test_show_list(mock_show, aireos_device): commands = ["a", "b"] - aireos_device.show_list(commands) + aireos_device.show(commands) mock_show.assert_called_with(commands) @@ -1435,14 +1436,14 @@ def test_show_list(mock_show, aireos_device): def test_show_list_pass_netmiko_args(mock_show, aireos_device): commands = ["a", "b"] netmiko_args = {"auto_find_prompt": False} - aireos_device.show_list(commands, **netmiko_args) + aireos_device.show(commands, **netmiko_args) mock_show.assert_called_with(commands, auto_find_prompt=False) @mock.patch.object(AIREOSDevice, "show") def test_show_list_pass_expect_string(mock_show, aireos_device): commands = ["a", "b"] - aireos_device.show_list(commands, expect_string="Continue?") + aireos_device.show(commands, expect_string="Continue?") mock_show.assert_called_with(commands, expect_string="Continue?") @@ -1450,7 +1451,7 @@ def test_show_list_pass_expect_string(mock_show, aireos_device): def test_show_list_pass_netmiko_args_and_expect_string(mock_show, aireos_device): commands = ["a", "b"] netmiko_args = {"auto_find_prompt": False} - aireos_device.show_list(commands, expect_string="Continue?", **netmiko_args) + aireos_device.show(commands, expect_string="Continue?", **netmiko_args) mock_show.assert_called_with(commands, expect_string="Continue?", auto_find_prompt=False) diff --git a/tests/unit/test_devices/test_asa_device.py b/tests/unit/test_devices/test_asa_device.py index c53399d0..2fe40328 100644 --- a/tests/unit/test_devices/test_asa_device.py +++ b/tests/unit/test_devices/test_asa_device.py @@ -3,6 +3,7 @@ from unittest import mock import pytest + from pyntc.devices import asa_device as asa_module from pyntc.devices import ASADevice @@ -180,7 +181,7 @@ def test_bad_config(asa_device): def test_config_list(asa_device): commands = ["crypto key generate rsa modulus 2048", "aaa authentication ssh console LOCAL"] - asa_device.config_list(commands) + asa_device.config(commands) for cmd in commands: asa_device.native.send_command_timing.assert_any_call(cmd) @@ -193,7 +194,7 @@ def test_bad_config_list(asa_device): asa_device.native.send_command_timing.side_effect = results with pytest.raises(asa_module.CommandListError, match=commands[1]): - asa_device.config_list(commands) + asa_device.config(commands) def test_show(asa_device): @@ -219,7 +220,7 @@ def test_show_list(asa_device): results = ["console 0", "security-level meh"] asa_device.native.send_command_timing.side_effect = results - result = asa_device.show_list(commands) + result = asa_device.show(commands) assert isinstance(result, list) assert "console" in result[0] assert "security-level" in result[1] @@ -235,7 +236,7 @@ def test_bad_show_list(asa_device): asa_device.native.send_command_timing.side_effect = results with pytest.raises(asa_module.CommandListError, match="show badcommand"): - asa_device.show_list(commands) + asa_device.show(commands) def test_save(asa_device): diff --git a/tests/unit/test_devices/test_eos_device.py b/tests/unit/test_devices/test_eos_device.py index 443e0fa1..fad0e06c 100644 --- a/tests/unit/test_devices/test_eos_device.py +++ b/tests/unit/test_devices/test_eos_device.py @@ -1,17 +1,18 @@ +import os +import time import unittest + import mock -import os import pytest -import time -from .device_mocks.eos import enable, config -from .device_mocks.eos import send_command, send_command_expect from pyntc.devices import EOSDevice -from pyntc.devices.base_device import RollbackError, RebootTimerError +from pyntc.devices.base_device import RebootTimerError, RollbackError from pyntc.devices.eos_device import FileTransferError from pyntc.devices.system_features.vlans.eos_vlans import EOSVlans from pyntc.errors import CommandError, CommandListError +from .device_mocks.eos import config, enable, send_command, send_command_expect + class TestEOSDevice(unittest.TestCase): @mock.patch("pyeapi.client.Node", autospec=True) @@ -44,7 +45,7 @@ def test_config_pass_list(self): @mock.patch.object(EOSDevice, "config") def test_config_list(self, mock_config): commands = ["interface Eth1", "no shutdown"] - self.device.config_list(commands) + self.device.config(commands) self.device.config.assert_called_with(commands) def test_bad_config_pass_string(self): @@ -149,7 +150,7 @@ def test_show_raw_text(self, mock_parse): @mock.patch.object(EOSDevice, "show") def test_show_list(self, mock_config): commands = ["show hostname", "show clock"] - self.device.show_list(commands) + self.device.show(commands) self.device.show.assert_called_with(commands) def test_save(self): diff --git a/tests/unit/test_devices/test_ios_device.py b/tests/unit/test_devices/test_ios_device.py index db4783e5..2f9ebcd9 100644 --- a/tests/unit/test_devices/test_ios_device.py +++ b/tests/unit/test_devices/test_ios_device.py @@ -4,6 +4,7 @@ import mock import pytest + from pyntc.devices import ios_device as ios_module from pyntc.devices import IOSDevice from pyntc.devices.base_device import RollbackError @@ -90,7 +91,7 @@ def test_bad_show_list(self): self.device.native.send_command.side_effect = results with self.assertRaisesRegex(ios_module.CommandListError, "show badcommand"): - self.device.show_list(commands) + self.device.show(commands) def test_save(self): result = self.device.save() @@ -544,14 +545,14 @@ def test_config_pass_invalid_list_command(mock_enter_config, mock_check_for_erro @mock.patch.object(IOSDevice, "config") def test_config_list(mock_config, ios_device): config_commands = ["a", "b"] - ios_device.config_list(config_commands) + ios_device.config(config_commands) mock_config.assert_called_with(config_commands) @mock.patch.object(IOSDevice, "config") def test_config_list_pass_netmiko_args(mock_config, ios_device): config_commands = ["a", "b"] - ios_device.config_list(config_commands, strip_prompt=True) + ios_device.config(config_commands, strip_prompt=True) mock_config.assert_called_with(config_commands, strip_prompt=True) @@ -1370,7 +1371,7 @@ def test_show_netmiko_args(ios_send_command): def test_show_list(ios_native_send_command): commands = ["show_version", "show_ip_arp"] device = ios_native_send_command([f"{commands[0]}.txt", f"{commands[1]}"]) - device.show_list(commands) + device.show(commands) device.native.send_command.assert_has_calls( [mock.call(command_string="show_version"), mock.call(command_string="show_ip_arp")] ) diff --git a/tests/unit/test_devices/test_jnpr_device.py b/tests/unit/test_devices/test_jnpr_device.py index 256aa115..d55c7147 100644 --- a/tests/unit/test_devices/test_jnpr_device.py +++ b/tests/unit/test_devices/test_jnpr_device.py @@ -1,16 +1,14 @@ +import os import unittest +from tempfile import NamedTemporaryFile + import mock -import os import pytest - -from tempfile import NamedTemporaryFile +from jnpr.junos.exception import ConfigLoadError from pyntc.devices import JunosDevice from pyntc.errors import CommandError, CommandListError -from jnpr.junos.exception import ConfigLoadError - - DEVICE_FACTS = { "domain": "ntc.com", "hostname": "vmx3", @@ -78,7 +76,7 @@ def test_config_pass_list(self): def test_config_list(self, mock_config): commands = ["set interfaces lo0", "set snmp community jason"] - self.device.config_list(commands, format="set") + self.device.config(commands, format="set") self.device.config.assert_called_with(commands, format="set") def test_bad_config_pass_string(self): @@ -164,7 +162,7 @@ def test_bad_show_non_show_pass_list(self): def test_show_list(self, mock_show): commands = ["show vlans", "show snmp v3"] - self.device.show_list(commands) + self.device.show(commands) self.device.show.assert_called_with(commands) @mock.patch("pyntc.devices.jnpr_device.SCP", autospec=True) diff --git a/tests/unit/test_devices/test_nxos_device.py b/tests/unit/test_devices/test_nxos_device.py index 3f494cd1..5e0aad5e 100644 --- a/tests/unit/test_devices/test_nxos_device.py +++ b/tests/unit/test_devices/test_nxos_device.py @@ -1,13 +1,13 @@ import unittest -import mock +import mock from pynxos.errors import CLIError -from .device_mocks.nxos import show, show_list +from pyntc.devices.base_device import RebootTimerError, RollbackError from pyntc.devices.nxos_device import NXOSDevice -from pyntc.devices.base_device import RollbackError, RebootTimerError from pyntc.errors import CommandError, CommandListError, FileTransferError, NTCFileNotFoundError +from .device_mocks.nxos import show, show_list BOOT_IMAGE = "n9000-dk9.9.2.1.bin" KICKSTART_IMAGE = "n9000-kickstart.9.2.1.bin" @@ -53,7 +53,7 @@ def test_bad_config(self): def test_config_list(self): commands = ["interface eth 1/1", "no shutdown"] - result = self.device.config_list(commands) + result = self.device.config(commands) self.assertIsNone(result) self.device.native.config_list.assert_called_with(commands) @@ -63,7 +63,7 @@ def test_bad_config_list(self): self.device.native.config_list.side_effect = CLIError(commands[1], "Invalid command.") with self.assertRaisesRegex(CommandListError, commands[1]): - self.device.config_list(commands) + self.device.config(commands) def test_show(self): command = "show cdp neighbors" @@ -90,7 +90,7 @@ def test_show_raw_text(self): def test_show_list(self): commands = ["show hostname", "show clock"] - result = self.device.show_list(commands) + result = self.device.show(commands) self.assertIsInstance(result, list) self.assertIn("hostname", result[0]) @@ -101,7 +101,7 @@ def test_show_list(self): def test_bad_show_list(self): commands = ["show badcommand", "show clock"] with self.assertRaisesRegex(CommandListError, "show badcommand"): - self.device.show_list(commands) + self.device.show(commands) def test_save(self): result = self.device.save()