Hello community, here is the log from the commit of package python-netmiko for openSUSE:Factory checked in at 2019-08-06 17:27:14 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-netmiko (Old) and /work/SRC/openSUSE:Factory/.python-netmiko.new.4126 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-netmiko" Tue Aug 6 17:27:14 2019 rev:5 rq:721258 version:2.4.1 Changes: -------- --- /work/SRC/openSUSE:Factory/python-netmiko/python-netmiko.changes 2019-07-17 14:26:47.499432262 +0200 +++ /work/SRC/openSUSE:Factory/.python-netmiko.new.4126/python-netmiko.changes 2019-08-06 17:27:14.872688946 +0200 @@ -1,0 +2,9 @@ +Tue Aug 6 10:30:40 UTC 2019 - Thomas Bechtold <[email protected]> + +- update to 2.4.1: + * Add Genie/pyATS parser support + * Fix Huawei telnet login + * Fix support for TextFSM >= 1.0.0 + * Fixes on Mellanox Driver + +------------------------------------------------------------------- Old: ---- netmiko-2.4.0.tar.gz New: ---- netmiko-2.4.1.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-netmiko.spec ++++++ --- /var/tmp/diff_new_pack.bwNBV4/_old 2019-08-06 17:27:16.968688490 +0200 +++ /var/tmp/diff_new_pack.bwNBV4/_new 2019-08-06 17:27:16.972688490 +0200 @@ -18,7 +18,7 @@ %{?!python_module:%define python_module() python-%{**} python3-%{**}} Name: python-netmiko -Version: 2.4.0 +Version: 2.4.1 Release: 0 Summary: Multi-vendor library to simplify Paramiko SSH connections to network devices License: MIT ++++++ netmiko-2.4.0.tar.gz -> netmiko-2.4.1.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/netmiko-2.4.0/PKG-INFO new/netmiko-2.4.1/PKG-INFO --- old/netmiko-2.4.0/PKG-INFO 2019-07-08 00:47:10.000000000 +0200 +++ new/netmiko-2.4.1/PKG-INFO 2019-07-25 23:15:47.000000000 +0200 @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: netmiko -Version: 2.4.0 +Version: 2.4.1 Summary: Multi-vendor library to simplify Paramiko SSH connections to network devices Home-page: https://github.com/ktbyers/netmiko Author: Kirk Byers @@ -20,14 +20,14 @@ ## Quick Links - - [Supported Platforms](#SupportedPlatforms) - - [Installation](#Installation) - - [Tutorials/Examples/Getting Started](#TutorialsExamplesGetting-Started) - - [Common Issues/FAQ](#Common-IssuesFAQ) - - [API-Documentation](#API-Documentation) - - [TextFSM Integration](#TextFSM-Integration) - - [Contributing](#Contributing) - - [Questions/Discussion](#QuestionsDiscussion) + - [Supported Platforms](https://ktbyers.github.io/netmiko/#supported-platforms) + - [Installation](https://ktbyers.github.io/netmiko/#installation) + - [Tutorials/Examples/Getting Started](https://ktbyers.github.io/netmiko/#tutorialsexamplesgetting-started) + - [Common Issues/FAQ](https://ktbyers.github.io/netmiko/#common-issuesfaq) + - [API-Documentation](https://ktbyers.github.io/netmiko/#api-documentation) + - [TextFSM Integration](https://ktbyers.github.io/netmiko/#textfsm-integration) + - [Contributing](https://ktbyers.github.io/netmiko/#contributing) + - [Questions/Discussion](https://ktbyers.github.io/netmiko/#questionsdiscussion) ## Supported Platforms @@ -57,7 +57,6 @@ Netmiko has the following requirements (which pip will install for you) - Paramiko >= 2.4.3 - scp >= 0.13.2 - - pyyaml - pyserial - textfsm @@ -82,6 +81,7 @@ - [Sending Configuration Commands](https://github.com/ktbyers/netmiko/tree/develop/examples/use_cases/case6_config_change) - [Handling Additional Prompting](https://github.com/ktbyers/netmiko/blob/develop/examples/use_cases/case5_prompting/send_command_prompting.py) - [Connecting with SSH Keys](https://github.com/ktbyers/netmiko/blob/develop/examples/use_cases/case9_ssh_keys/conn_ssh_keys.py) + - [Cisco Genie Integration](https://github.com/ktbyers/netmiko/blob/develop/examples/use_cases/case18_structured_data_genie) ### Getting Started: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/netmiko-2.4.0/PLATFORMS.md new/netmiko-2.4.1/PLATFORMS.md --- old/netmiko-2.4.0/PLATFORMS.md 2019-07-08 00:01:32.000000000 +0200 +++ new/netmiko-2.4.1/PLATFORMS.md 2019-07-12 01:20:14.000000000 +0200 @@ -62,7 +62,6 @@ - F5 TMSH - F5 Linux - Fortinet -- Mikrotik - MRV Communications OptiSwitch - MRV LX - Nokia/Alcatel SR-OS diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/netmiko-2.4.0/README.md new/netmiko-2.4.1/README.md --- old/netmiko-2.4.0/README.md 2019-07-08 00:01:32.000000000 +0200 +++ new/netmiko-2.4.1/README.md 2019-07-25 23:12:55.000000000 +0200 @@ -12,14 +12,14 @@ ## Quick Links -- [Supported Platforms](#SupportedPlatforms) -- [Installation](#Installation) -- [Tutorials/Examples/Getting Started](#TutorialsExamplesGetting-Started) -- [Common Issues/FAQ](#Common-IssuesFAQ) -- [API-Documentation](#API-Documentation) -- [TextFSM Integration](#TextFSM-Integration) -- [Contributing](#Contributing) -- [Questions/Discussion](#QuestionsDiscussion) +- [Supported Platforms](https://ktbyers.github.io/netmiko/#supported-platforms) +- [Installation](https://ktbyers.github.io/netmiko/#installation) +- [Tutorials/Examples/Getting Started](https://ktbyers.github.io/netmiko/#tutorialsexamplesgetting-started) +- [Common Issues/FAQ](https://ktbyers.github.io/netmiko/#common-issuesfaq) +- [API-Documentation](https://ktbyers.github.io/netmiko/#api-documentation) +- [TextFSM Integration](https://ktbyers.github.io/netmiko/#textfsm-integration) +- [Contributing](https://ktbyers.github.io/netmiko/#contributing) +- [Questions/Discussion](https://ktbyers.github.io/netmiko/#questionsdiscussion) ## Supported Platforms @@ -49,7 +49,6 @@ Netmiko has the following requirements (which pip will install for you) - Paramiko >= 2.4.3 - scp >= 0.13.2 -- pyyaml - pyserial - textfsm @@ -74,6 +73,7 @@ - [Sending Configuration Commands](https://github.com/ktbyers/netmiko/tree/develop/examples/use_cases/case6_config_change) - [Handling Additional Prompting](https://github.com/ktbyers/netmiko/blob/develop/examples/use_cases/case5_prompting/send_command_prompting.py) - [Connecting with SSH Keys](https://github.com/ktbyers/netmiko/blob/develop/examples/use_cases/case9_ssh_keys/conn_ssh_keys.py) +- [Cisco Genie Integration](https://github.com/ktbyers/netmiko/blob/develop/examples/use_cases/case18_structured_data_genie) ### Getting Started: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/netmiko-2.4.0/netmiko/__init__.py new/netmiko-2.4.1/netmiko/__init__.py --- old/netmiko-2.4.0/netmiko/__init__.py 2019-07-08 00:01:32.000000000 +0200 +++ new/netmiko-2.4.1/netmiko/__init__.py 2019-07-25 23:12:55.000000000 +0200 @@ -23,7 +23,7 @@ NetmikoAuthError = NetMikoAuthenticationException Netmiko = ConnectHandler -__version__ = "2.4.0" +__version__ = "2.4.1" __all__ = ( "ConnectHandler", "ssh_dispatcher", diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/netmiko-2.4.0/netmiko/_textfsm/_clitable.py new/netmiko-2.4.1/netmiko/_textfsm/_clitable.py --- old/netmiko-2.4.0/netmiko/_textfsm/_clitable.py 2019-03-08 04:18:29.000000000 +0100 +++ new/netmiko-2.4.1/netmiko/_textfsm/_clitable.py 2019-07-25 23:12:55.000000000 +0200 @@ -31,7 +31,13 @@ import os import re import threading -import copyable_regex_object + +try: + # TextFSM >= 1.0 (new package structure) + from textfsm import copyable_regex_object +except ImportError: + # TextFSM <= 0.4.1 + import copyable_regex_object import textfsm from netmiko._textfsm import _texttable as texttable diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/netmiko-2.4.0/netmiko/base_connection.py new/netmiko-2.4.1/netmiko/base_connection.py --- old/netmiko-2.4.0/netmiko/base_connection.py 2019-07-08 00:01:32.000000000 +0200 +++ new/netmiko-2.4.1/netmiko/base_connection.py 2019-07-25 23:12:55.000000000 +0200 @@ -29,7 +29,12 @@ NetMikoTimeoutException, NetMikoAuthenticationException, ) -from netmiko.utilities import write_bytes, check_serial_port, get_structured_data +from netmiko.utilities import ( + write_bytes, + check_serial_port, + get_structured_data, + get_structured_data_genie, +) class BaseConnection(object): @@ -131,10 +136,10 @@ means unknown SSH host keys will be accepted). :type ssh_strict: bool - :param system_host_keys: Load host keys from the user's 'known_hosts' file. + :param system_host_keys: Load host keys from the users known_hosts file. :type system_host_keys: bool :param alt_host_keys: If `True` host keys will be loaded from the file specified in - 'alt_key_file'. + alt_key_file. :type alt_host_keys: bool :param alt_key_file: SSH host key file to use (if alt_host_keys=True). @@ -160,11 +165,11 @@ to keep the connection alive). :type keepalive: int - :param default_enter: Character(s) to send to correspond to enter key (default: '\n'). + :param default_enter: Character(s) to send to correspond to enter key (default: \n). :type default_enter: str :param response_return: Character(s) to use in normalized return data to represent - enter key (default: '\n') + enter key (default: \n) :type response_return: str :param fast_cli: Provide a way to optimize for performance. Converts select_delay_factor @@ -189,7 +194,7 @@ :type allow_auto_change: bool :param encoding: Encoding to be used when writing bytes to the output channel. - (default: 'ascii') + (default: ascii) :type encoding: str """ self.remote_conn = None @@ -721,7 +726,7 @@ """ In case of an exception happening during `session_preparation()` Netmiko should gracefully clean-up after itself. This might be challenging for library users - to do since they don't have a reference to the object. This is possibly related + to do since they do not have a reference to the object. This is possibly related to threads used in Paramiko. """ try: @@ -754,7 +759,7 @@ self.clear_buffer() def _use_ssh_config(self, dict_arg): - """Update SSH connection parameters based on contents of SSH 'config' file. + """Update SSH connection parameters based on contents of SSH config file. :param dict_arg: Dictionary of SSH connection parameters :type dict_arg: dict @@ -1029,7 +1034,7 @@ Used as delimiter for stripping of trailing prompt in output. Should be set to something that is general and applies in multiple contexts. For Cisco - devices this will be set to router hostname (i.e. prompt without '>' or '#'). + devices this will be set to router hostname (i.e. prompt without > or #). This will be set on entering user exec or privileged exec on Cisco, but not when entering/exiting config mode. @@ -1102,6 +1107,7 @@ strip_command=True, normalize=True, use_textfsm=False, + use_genie=False, ): """Execute command_string on the SSH channel using a delay-based mechanism. Generally used for show commands. @@ -1127,6 +1133,9 @@ :param use_textfsm: Process command output through TextFSM template (default: False). :type normalize: bool + + :param use_genie: Process command output through PyATS/Genie parser (default: False). + :type normalize: bool """ output = "" delay_factor = self.select_delay_factor(delay_factor) @@ -1144,10 +1153,18 @@ command_string=command_string, strip_prompt=strip_prompt, ) - if use_textfsm: - output = get_structured_data( - output, platform=self.device_type, command=command_string.strip() - ) + # If both TextFSM and Genie are set, try TextFSM then Genie + for parser_flag, parser_func in ( + (use_textfsm, get_structured_data), + (use_genie, get_structured_data_genie), + ): + if parser_flag: + structured_output = parser_func( + output, platform=self.device_type, command=command_string.strip() + ) + # If we have structured data; return it. + if not isinstance(structured_output, string_types): + return structured_output return output def strip_prompt(self, a_string): @@ -1201,6 +1218,7 @@ strip_command=True, normalize=True, use_textfsm=False, + use_genie=False, ): """Execute command_string on the SSH channel using a pattern-based mechanism. Generally used for show commands. By default this method will keep waiting to receive data until the @@ -1232,6 +1250,9 @@ :param use_textfsm: Process command output through TextFSM template (default: False). :type normalize: bool + + :param use_genie: Process command output through PyATS/Genie parser (default: False). + :type normalize: bool """ # Time to delay in each read loop loop_delay = 0.2 @@ -1308,10 +1329,19 @@ command_string=command_string, strip_prompt=strip_prompt, ) - if use_textfsm: - output = get_structured_data( - output, platform=self.device_type, command=command_string.strip() - ) + + # If both TextFSM and Genie are set, try TextFSM then Genie + for parser_flag, parser_func in ( + (use_textfsm, get_structured_data), + (use_genie, get_structured_data_genie), + ): + if parser_flag: + structured_output = parser_func( + output, platform=self.device_type, command=command_string.strip() + ) + # If we have structured data; return it. + if not isinstance(structured_output, string_types): + return structured_output return output def send_command_expect(self, *args, **kwargs): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/netmiko-2.4.0/netmiko/huawei/huawei.py new/netmiko-2.4.1/netmiko/huawei/huawei.py --- old/netmiko-2.4.0/netmiko/huawei/huawei.py 2019-07-08 00:01:32.000000000 +0200 +++ new/netmiko-2.4.1/netmiko/huawei/huawei.py 2019-07-25 23:12:55.000000000 +0200 @@ -122,28 +122,43 @@ i = 1 while i <= max_loops: try: - # Search for username pattern / send username - output = self.read_until_pattern(pattern=username_pattern) + output = self.read_channel() return_msg += output - self.write_channel(self.username + self.TELNET_RETURN) - - # Search for password pattern, / send password - output = self.read_until_pattern(pattern=pwd_pattern) - return_msg += output - - self.write_channel(self.password + self.TELNET_RETURN) + # Search for username pattern / send username + if re.search(username_pattern, output, flags=re.I): + self.write_channel(self.username + self.TELNET_RETURN) + time.sleep(1 * delay_factor) + output = self.read_channel() + return_msg += output - # Search for router prompt, OR password_change prompt - output = self.read_until_pattern(pattern=combined_pattern) - return_msg += output + # Search for password pattern / send password + if re.search(pwd_pattern, output, flags=re.I): + self.write_channel(self.password + self.TELNET_RETURN) + time.sleep(0.5 * delay_factor) + output = self.read_channel() + return_msg += output + if re.search( + pri_prompt_terminator, output, flags=re.M + ) or re.search(alt_prompt_terminator, output, flags=re.M): + return return_msg + # Search for password change prompt, send "N" if re.search(password_change_prompt, output): self.write_channel("N" + self.TELNET_RETURN) output = self.read_until_pattern(pattern=combined_pattern) return_msg += output - return return_msg + # Check if proper data received + if re.search(pri_prompt_terminator, output, flags=re.M) or re.search( + alt_prompt_terminator, output, flags=re.M + ): + return return_msg + + self.write_channel(self.TELNET_RETURN) + time.sleep(0.5 * delay_factor) + i += 1 + except EOFError: self.remote_conn.close() msg = "Login failed: {}".format(self.host) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/netmiko-2.4.0/netmiko/mellanox/__init__.py new/netmiko-2.4.1/netmiko/mellanox/__init__.py --- old/netmiko-2.4.0/netmiko/mellanox/__init__.py 2019-03-08 04:18:29.000000000 +0100 +++ new/netmiko-2.4.1/netmiko/mellanox/__init__.py 2019-07-25 23:12:55.000000000 +0200 @@ -1,4 +1,4 @@ from __future__ import unicode_literals -from netmiko.mellanox.mellanox_ssh import MellanoxSSH +from netmiko.mellanox.mellanox_mlnxos_ssh import MellanoxMlnxosSSH -__all__ = ["MellanoxSSH"] +__all__ = ["MellanoxMlnxosSSH"] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/netmiko-2.4.0/netmiko/mellanox/mellanox_mlnxos_ssh.py new/netmiko-2.4.1/netmiko/mellanox/mellanox_mlnxos_ssh.py --- old/netmiko-2.4.0/netmiko/mellanox/mellanox_mlnxos_ssh.py 1970-01-01 01:00:00.000000000 +0100 +++ new/netmiko-2.4.1/netmiko/mellanox/mellanox_mlnxos_ssh.py 2019-07-25 23:12:55.000000000 +0200 @@ -0,0 +1,68 @@ +"""Mellanox MLNX-OS Switch support.""" +from __future__ import unicode_literals +import re +from netmiko.cisco_base_connection import CiscoSSHConnection +from netmiko import log + + +class MellanoxMlnxosSSH(CiscoSSHConnection): + """Mellanox MLNX-OS Switch support.""" + + def enable(self, cmd="enable", pattern="#", re_flags=re.IGNORECASE): + """Enter into enable mode.""" + output = "" + if not self.check_enable_mode(): + self.write_channel(self.normalize_cmd(cmd)) + output += self.read_until_prompt_or_pattern( + pattern=pattern, re_flags=re_flags + ) + if not self.check_enable_mode(): + raise ValueError("Failed to enter enable mode.") + return output + + def config_mode(self, config_command="config term", pattern="#"): + return super(MellanoxMlnxosSSH, self).config_mode( + config_command=config_command, pattern=pattern + ) + + def check_config_mode(self, check_string="(config", pattern=r"#"): + return super(MellanoxMlnxosSSH, self).check_config_mode( + check_string=check_string, pattern=pattern + ) + + def disable_paging(self, command="no cli session paging enable", delay_factor=1): + return super(MellanoxMlnxosSSH, self).disable_paging( + command=command, delay_factor=delay_factor + ) + + def exit_config_mode(self, exit_config="exit", pattern="#"): + """Mellanox does not support a single command to completely exit configuration mode. + + Consequently, need to keep checking and sending "exit". + """ + output = "" + check_count = 12 + while check_count >= 0: + if self.check_config_mode(): + self.write_channel(self.normalize_cmd(exit_config)) + output += self.read_until_pattern(pattern=pattern) + else: + break + check_count -= 1 + + # One last check for whether we successfully exited config mode + if self.check_config_mode(): + raise ValueError("Failed to exit configuration mode") + + log.debug("exit_config_mode: {}".format(output)) + return output + + def save_config( + self, cmd="configuration write", confirm=False, confirm_response="" + ): + """Save Config on Mellanox devices Enters and Leaves Config Mode""" + output = self.enable() + output += self.config_mode() + output += self.send_command(cmd) + output += self.exit_config_mode() + return output diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/netmiko-2.4.0/netmiko/mellanox/mellanox_ssh.py new/netmiko-2.4.1/netmiko/mellanox/mellanox_ssh.py --- old/netmiko-2.4.0/netmiko/mellanox/mellanox_ssh.py 2019-03-08 04:18:29.000000000 +0100 +++ new/netmiko-2.4.1/netmiko/mellanox/mellanox_ssh.py 1970-01-01 01:00:00.000000000 +0100 @@ -1,58 +0,0 @@ -from __future__ import unicode_literals -from netmiko.cisco_base_connection import CiscoSSHConnection -from netmiko import log -import time - - -class MellanoxSSH(CiscoSSHConnection): - def config_mode(self, config_command="config term", pattern="#"): - """Enter into config_mode.""" - output = "" - if not self.check_config_mode(): - self.write_channel(self.normalize_cmd(config_command)) - output = self.read_until_pattern(pattern=pattern) - if not self.check_config_mode(): - raise ValueError("Failed to enter configuration mode.") - return output - - def check_config_mode(self, check_string="(config)", pattern=r"[>|#]"): - return super(MellanoxSSH, self).check_config_mode( - check_string=check_string, pattern=pattern - ) - - def disable_paging(self, command="terminal length 999", delay_factor=1): - """Disable paging default to a Cisco CLI method.""" - delay_factor = self.select_delay_factor(delay_factor) - time.sleep(delay_factor * 0.1) - self.clear_buffer() - command = self.normalize_cmd(command) - log.debug("In disable_paging") - log.debug("Command: {0}".format(command)) - self.write_channel(command) - output = self.read_until_prompt() - if self.ansi_escape_codes: - output = self.strip_ansi_escape_codes(output) - log.debug("{0}".format(output)) - log.debug("Exiting disable_paging") - return output - - def exit_config_mode(self, exit_config="exit", pattern="#"): - """Exit from configuration mode.""" - output = "" - if self.check_config_mode(): - self.write_channel(self.normalize_cmd(exit_config)) - output = self.read_until_pattern(pattern=pattern) - if self.check_config_mode(): - raise ValueError("Failed to exit configuration mode") - log.debug("exit_config_mode: {0}".format(output)) - return output - - def save_config( - self, cmd="configuration write", confirm=False, confirm_response="" - ): - """Save Config on Mellanox devices Enters and Leaves Config Mode""" - output = self.enable() - output += self.config_mode() - output += self.send_command(cmd) - output += self.exit_config_mode() - return output diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/netmiko-2.4.0/netmiko/ssh_dispatcher.py new/netmiko-2.4.1/netmiko/ssh_dispatcher.py --- old/netmiko-2.4.0/netmiko/ssh_dispatcher.py 2019-07-08 00:01:32.000000000 +0200 +++ new/netmiko-2.4.1/netmiko/ssh_dispatcher.py 2019-07-25 23:12:55.000000000 +0200 @@ -58,7 +58,7 @@ from netmiko.linux import LinuxSSH, LinuxFileTransfer from netmiko.mikrotik import MikrotikRouterOsSSH from netmiko.mikrotik import MikrotikSwitchOsSSH -from netmiko.mellanox import MellanoxSSH +from netmiko.mellanox import MellanoxMlnxosSSH from netmiko.mrv import MrvLxSSH from netmiko.mrv import MrvOptiswitchSSH from netmiko.netapp import NetAppcDotSSH @@ -142,7 +142,8 @@ "linux": LinuxSSH, "mikrotik_routeros": MikrotikRouterOsSSH, "mikrotik_switchos": MikrotikSwitchOsSSH, - "mellanox": MellanoxSSH, + "mellanox": MellanoxMlnxosSSH, + "mellanox_mlnxos": MellanoxMlnxosSSH, "mrv_lx": MrvLxSSH, "mrv_optiswitch": MrvOptiswitchSSH, "netapp_cdot": NetAppcDotSSH, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/netmiko-2.4.0/netmiko/utilities.py new/netmiko-2.4.1/netmiko/utilities.py --- old/netmiko-2.4.0/netmiko/utilities.py 2019-07-08 00:01:32.000000000 +0200 +++ new/netmiko-2.4.1/netmiko/utilities.py 2019-07-25 23:12:55.000000000 +0200 @@ -7,10 +7,18 @@ import io import os import serial.tools.list_ports +from netmiko.py23_compat import text_type from netmiko._textfsm import _clitable as clitable from netmiko._textfsm._clitable import CliTableError -from netmiko.py23_compat import text_type +try: + from genie.conf.base import Device + from genie.libs.parser.utils import get_parser + from pyats.datastructures import AttrDict + + GENIE_INSTALLED = True +except ImportError: + GENIE_INSTALLED = False # Dictionary mapping 'show run' for vendors with different command SHOW_RUN_MAPPER = { @@ -263,3 +271,51 @@ return output except CliTableError: return raw_output + + +def get_structured_data_genie(raw_output, platform, command): + if not sys.version_info >= (3, 4): + raise ValueError("Genie requires Python >= 3.4") + + if not GENIE_INSTALLED: + msg = ( + "\nGenie and PyATS are not installed. Please PIP install both Genie and PyATS:\n" + "pip install genie\npip install pyats\n" + ) + raise ValueError(msg) + + if "cisco" not in platform: + return raw_output + + genie_device_mapper = { + "cisco_ios": "ios", + "cisco_xe": "iosxe", + "cisco_xr": "iosxr", + "cisco_nxos": "nxos", + "cisco_asa": "asa", + } + + os = None + # platform might be _ssh, _telnet, _serial strip that off + if platform.count("_") > 1: + base_platform = platform.split("_")[:-1] + base_platform = "_".join(base_platform) + else: + base_platform = platform + + os = genie_device_mapper.get(base_platform) + if os is None: + return raw_output + + # Genie specific construct for doing parsing (based on Genie in Ansible) + device = Device("new_device", os=os) + device.custom.setdefault("abstraction", {}) + device.custom["abstraction"]["order"] = ["os"] + device.cli = AttrDict({"execute": None}) + try: + # Test of whether their is a parser for the given command (will return Exception if fails) + get_parser(command, device) + parsed_output = device.parse(command, output=raw_output) + return parsed_output + except Exception: + return raw_output diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/netmiko-2.4.0/netmiko.egg-info/PKG-INFO new/netmiko-2.4.1/netmiko.egg-info/PKG-INFO --- old/netmiko-2.4.0/netmiko.egg-info/PKG-INFO 2019-07-08 00:47:10.000000000 +0200 +++ new/netmiko-2.4.1/netmiko.egg-info/PKG-INFO 2019-07-25 23:15:47.000000000 +0200 @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: netmiko -Version: 2.4.0 +Version: 2.4.1 Summary: Multi-vendor library to simplify Paramiko SSH connections to network devices Home-page: https://github.com/ktbyers/netmiko Author: Kirk Byers @@ -20,14 +20,14 @@ ## Quick Links - - [Supported Platforms](#SupportedPlatforms) - - [Installation](#Installation) - - [Tutorials/Examples/Getting Started](#TutorialsExamplesGetting-Started) - - [Common Issues/FAQ](#Common-IssuesFAQ) - - [API-Documentation](#API-Documentation) - - [TextFSM Integration](#TextFSM-Integration) - - [Contributing](#Contributing) - - [Questions/Discussion](#QuestionsDiscussion) + - [Supported Platforms](https://ktbyers.github.io/netmiko/#supported-platforms) + - [Installation](https://ktbyers.github.io/netmiko/#installation) + - [Tutorials/Examples/Getting Started](https://ktbyers.github.io/netmiko/#tutorialsexamplesgetting-started) + - [Common Issues/FAQ](https://ktbyers.github.io/netmiko/#common-issuesfaq) + - [API-Documentation](https://ktbyers.github.io/netmiko/#api-documentation) + - [TextFSM Integration](https://ktbyers.github.io/netmiko/#textfsm-integration) + - [Contributing](https://ktbyers.github.io/netmiko/#contributing) + - [Questions/Discussion](https://ktbyers.github.io/netmiko/#questionsdiscussion) ## Supported Platforms @@ -57,7 +57,6 @@ Netmiko has the following requirements (which pip will install for you) - Paramiko >= 2.4.3 - scp >= 0.13.2 - - pyyaml - pyserial - textfsm @@ -82,6 +81,7 @@ - [Sending Configuration Commands](https://github.com/ktbyers/netmiko/tree/develop/examples/use_cases/case6_config_change) - [Handling Additional Prompting](https://github.com/ktbyers/netmiko/blob/develop/examples/use_cases/case5_prompting/send_command_prompting.py) - [Connecting with SSH Keys](https://github.com/ktbyers/netmiko/blob/develop/examples/use_cases/case9_ssh_keys/conn_ssh_keys.py) + - [Cisco Genie Integration](https://github.com/ktbyers/netmiko/blob/develop/examples/use_cases/case18_structured_data_genie) ### Getting Started: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/netmiko-2.4.0/netmiko.egg-info/SOURCES.txt new/netmiko-2.4.1/netmiko.egg-info/SOURCES.txt --- old/netmiko-2.4.0/netmiko.egg-info/SOURCES.txt 2019-07-08 00:47:10.000000000 +0200 +++ new/netmiko-2.4.1/netmiko.egg-info/SOURCES.txt 2019-07-25 23:15:47.000000000 +0200 @@ -101,7 +101,7 @@ netmiko/linux/__init__.py netmiko/linux/linux_ssh.py netmiko/mellanox/__init__.py -netmiko/mellanox/mellanox_ssh.py +netmiko/mellanox/mellanox_mlnxos_ssh.py netmiko/mikrotik/__init__.py netmiko/mikrotik/mikrotik_ssh.py netmiko/mrv/__init__.py diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/netmiko-2.4.0/netmiko.egg-info/requires.txt new/netmiko-2.4.1/netmiko.egg-info/requires.txt --- old/netmiko-2.4.0/netmiko.egg-info/requires.txt 2019-07-08 00:47:10.000000000 +0200 +++ new/netmiko-2.4.1/netmiko.egg-info/requires.txt 2019-07-25 23:15:47.000000000 +0200 @@ -1,7 +1,6 @@ setuptools>=38.4.0 paramiko>=2.4.3 scp>=0.13.2 -pyyaml pyserial textfsm @@ -10,4 +9,5 @@ ipaddress [test] +pyyaml==5.1 pytest>=4.6.3 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/netmiko-2.4.0/setup.py new/netmiko-2.4.1/setup.py --- old/netmiko-2.4.0/setup.py 2019-07-08 00:01:32.000000000 +0200 +++ new/netmiko-2.4.1/setup.py 2019-07-25 23:12:55.000000000 +0200 @@ -51,11 +51,10 @@ "setuptools>=38.4.0", "paramiko>=2.4.3", "scp>=0.13.2", - "pyyaml", "pyserial", "textfsm", 'enum34; python_version == "2.7"', 'ipaddress; python_version == "2.7"', ], - extras_require={"test": ["pytest>=4.6.3"]}, + extras_require={"test": ["pyyaml==5.1", "pytest>=4.6.3"]}, )
