diff --git a/PLATFORMS.md b/PLATFORMS.md index fe91f79a5c22ab4071eee5078dea319012efa94a..a0c1c8e9b50678bc3bc8b6291cfa88cbefe7f7da 100644 --- a/PLATFORMS.md +++ b/PLATFORMS.md @@ -16,6 +16,7 @@ ###### Limited testing - 6Wind +- Adtran OS - Alcatel AOS6/AOS8 - Apresia Systems AEOS - Broadcom ICOS @@ -40,6 +41,7 @@ - MikroTik RouterOS - MikroTik SwitchOS - NetApp cDOT +- Netgear ProSafe - Nokia/Alcatel SR OS - OneAccess - Palo Alto PAN-OS diff --git a/README.md b/README.md index 3f8cd6203a1be6212a3d9be890af0507fb260b81..a7f7def87f5afb1a39fc30e8785671b9cfa4915b 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@  [](https://github.com/ambv/black) -<img src="https://github.com/ktbyers/netmiko/blob/improved_examples/images/netmiko_logo_gh.png" width="320"> +<img src="https://ktbyers.github.io/netmiko/images/netmiko_logo_gh.png" width="320"> Netmiko ======= diff --git a/docs/netmiko/a10/a10_ssh.html b/docs/netmiko/a10/a10_ssh.html index ffa59d3fb06f16d9bb2e8d4b823c7ee123a25702..43cde36131d69ea4321aa6261b8f8b9980ed0ff6 100644 --- a/docs/netmiko/a10/a10_ssh.html +++ b/docs/netmiko/a10/a10_ssh.html @@ -36,10 +36,10 @@ class A10SSH(CiscoSSHConnection): self._test_channel_read() self.set_base_prompt() self.enable() - self.disable_paging(command="terminal length 0") # Will not do anything without A10 specific command - self.set_terminal_width() + # self.set_terminal_width() + self.disable_paging(command="terminal length 0") # Clear the read buffer time.sleep(0.3 * self.global_delay_factor) @@ -205,10 +205,10 @@ class A10SSH(CiscoSSHConnection): self._test_channel_read() self.set_base_prompt() self.enable() - self.disable_paging(command="terminal length 0") # Will not do anything without A10 specific command - self.set_terminal_width() + # self.set_terminal_width() + self.disable_paging(command="terminal length 0") # Clear the read buffer time.sleep(0.3 * self.global_delay_factor) @@ -250,10 +250,10 @@ class A10SSH(CiscoSSHConnection): self._test_channel_read() self.set_base_prompt() self.enable() - self.disable_paging(command="terminal length 0") # Will not do anything without A10 specific command - self.set_terminal_width() + # self.set_terminal_width() + self.disable_paging(command="terminal length 0") # Clear the read buffer time.sleep(0.3 * self.global_delay_factor) diff --git a/docs/netmiko/a10/index.html b/docs/netmiko/a10/index.html index 16d62457c332de19b381758d7c6161abe78584cc..7d22e4798eeb11e101e7f8d1981e34eba17dedf4 100644 --- a/docs/netmiko/a10/index.html +++ b/docs/netmiko/a10/index.html @@ -189,10 +189,10 @@ __all__ = ["A10SSH"]</code></pre> self._test_channel_read() self.set_base_prompt() self.enable() - self.disable_paging(command="terminal length 0") # Will not do anything without A10 specific command - self.set_terminal_width() + # self.set_terminal_width() + self.disable_paging(command="terminal length 0") # Clear the read buffer time.sleep(0.3 * self.global_delay_factor) @@ -234,10 +234,10 @@ __all__ = ["A10SSH"]</code></pre> self._test_channel_read() self.set_base_prompt() self.enable() - self.disable_paging(command="terminal length 0") # Will not do anything without A10 specific command - self.set_terminal_width() + # self.set_terminal_width() + self.disable_paging(command="terminal length 0") # Clear the read buffer time.sleep(0.3 * self.global_delay_factor) diff --git a/docs/netmiko/adtran/adtran.html b/docs/netmiko/adtran/adtran.html new file mode 100644 index 0000000000000000000000000000000000000000..ebe0ae08de65644b310568d43bc058fd8d440e6e --- /dev/null +++ b/docs/netmiko/adtran/adtran.html @@ -0,0 +1,576 @@ +<!doctype html> +<html lang="en"> +<head> +<meta charset="utf-8"> +<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1" /> +<meta name="generator" content="pdoc 0.6.3" /> +<title>netmiko.adtran.adtran API documentation</title> +<meta name="description" content="" /> +<link href='https://cdnjs.cloudflare.com/ajax/libs/normalize/8.0.0/normalize.min.css' rel='stylesheet'> +<link href='https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/8.0.0/sanitize.min.css' rel='stylesheet'> +<link href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/github.min.css" rel="stylesheet"> +<style>.flex{display:flex !important}body{line-height:1.5em}#content{padding:20px}#sidebar{padding:30px;overflow:hidden}.http-server-breadcrumbs{font-size:130%;margin:0 0 15px 0}#footer{font-size:.75em;padding:5px 30px;border-top:1px solid #ddd;text-align:right}#footer p{margin:0 0 0 1em;display:inline-block}#footer p:last-child{margin-right:30px}h1,h2,h3,h4,h5{font-weight:300}h1{font-size:2.5em;line-height:1.1em}h2{font-size:1.75em;margin:1em 0 .50em 0}h3{font-size:1.4em;margin:25px 0 10px 0}h4{margin:0;font-size:105%}a{color:#058;text-decoration:none;transition:color .3s ease-in-out}a:hover{color:#e82}.title code{font-weight:bold}h2[id^="header-"]{margin-top:2em}.ident{color:#900}pre code{background:#f8f8f8;font-size:.8em;line-height:1.4em}code{background:#f2f2f1;padding:1px 4px;overflow-wrap:break-word}h1 code{background:transparent}pre{background:#f8f8f8;border:0;border-top:1px solid #ccc;border-bottom:1px solid #ccc;margin:1em 0;padding:1ex}#http-server-module-list{display:flex;flex-flow:column}#http-server-module-list div{display:flex}#http-server-module-list dt{min-width:10%}#http-server-module-list p{margin-top:0}.toc ul,#index{list-style-type:none;margin:0;padding:0}#index code{background:transparent}#index h3{border-bottom:1px solid #ddd}#index ul{padding:0}#index h4{font-weight:bold}#index h4 + ul{margin-bottom:.6em}@media (min-width:200ex){#index .two-column{column-count:2}}@media (min-width:300ex){#index .two-column{column-count:3}}dl{margin-bottom:2em}dl dl:last-child{margin-bottom:4em}dd{margin:0 0 1em 3em}#header-classes + dl > dd{margin-bottom:3em}dd dd{margin-left:2em}dd p{margin:10px 0}.name{background:#eee;font-weight:bold;font-size:.85em;padding:5px 10px;display:inline-block;min-width:40%}.name:hover{background:#e0e0e0}.name > span:first-child{white-space:nowrap}.name.class > span:nth-child(2){margin-left:.4em}.inherited{color:#999;border-left:5px solid #eee;padding-left:1em}.inheritance em{font-style:normal;font-weight:bold}.desc h2{font-weight:400;font-size:1.25em}.desc h3{font-size:1em}.desc dt code{background:inherit}.source summary{color:#666;text-align:right;font-weight:400;font-size:.8em;text-transform:uppercase;cursor:pointer}.source pre{max-height:500px;overflow:auto;margin:0}.source pre code{font-size:12px;overflow:visible}.hlist{list-style:none}.hlist li{display:inline}.hlist li:after{content:',\2002'}.hlist li:last-child:after{content:none}.hlist .hlist{display:inline;padding-left:1em}img{max-width:100%}.admonition{padding:.1em .5em;margin-bottom:1em}.admonition-title{font-weight:bold}.admonition.note,.admonition.info,.admonition.important{background:#aef}.admonition.todo,.admonition.versionadded,.admonition.tip,.admonition.hint{background:#dfd}.admonition.warning,.admonition.versionchanged,.admonition.deprecated{background:#fd4}.admonition.error,.admonition.danger,.admonition.caution{background:lightpink}</style> +<style media="screen and (min-width: 700px)">@media screen and (min-width:700px){#sidebar{width:30%}#content{width:70%;max-width:100ch;padding:3em 4em;border-left:1px solid #ddd}pre code{font-size:1em}.item .name{font-size:1em}main{display:flex;flex-direction:row-reverse;justify-content:flex-end}.toc ul ul,#index ul{padding-left:1.5em}.toc > ul > li{margin-top:.5em}}</style> +<style media="print">@media print{#sidebar h1{page-break-before:always}.source{display:none}}@media print{*{background:transparent !important;color:#000 !important;box-shadow:none !important;text-shadow:none !important}a[href]:after{content:" (" attr(href) ")";font-size:90%}a[href][title]:after{content:none}abbr[title]:after{content:" (" attr(title) ")"}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}@page{margin:0.5cm}p,h2,h3{orphans:3;widows:3}h1,h2,h3,h4,h5,h6{page-break-after:avoid}}</style> +</head> +<body> +<main> +<article id="content"> +<header> +<h1 class="title">Module <code>netmiko.adtran.adtran</code></h1> +</header> +<section id="section-intro"> +<details class="source"> +<summary>Source code</summary> +<pre><code class="python">import time +import re +from netmiko.cisco_base_connection import CiscoBaseConnection + + +class AdtranOSBase(CiscoBaseConnection): + def __init__(self, *args, **kwargs): + if kwargs.get("global_cmd_verify") is None: + kwargs["global_cmd_verify"] = False + return super().__init__(*args, **kwargs) + + def session_preparation(self): + """Prepare the session after the connection has been established.""" + self.ansi_escape_codes = True + self._test_channel_read() + self.set_base_prompt() + self.disable_paging(command="terminal length 0") + # Clear the read buffer + time.sleep(0.3 * self.global_delay_factor) + self.clear_buffer() + + def check_enable_mode(self, check_string="#"): + return super().check_enable_mode(check_string=check_string) + + def enable(self, cmd="enable", pattern="", re_flags=re.IGNORECASE): + return super().enable(cmd=cmd, pattern=pattern, re_flags=re_flags) + + def exit_enable_mode(self, exit_command="disable"): + return super().exit_enable_mode(exit_command=exit_command) + + def check_config_mode(self, check_string=")#"): + return super().check_config_mode(check_string=check_string) + + def config_mode(self, config_command="config term", pattern=""): + return super().config_mode(config_command=config_command, pattern=pattern) + + def exit_config_mode(self, exit_config="end", pattern="#"): + return super().exit_config_mode(exit_config=exit_config, pattern=pattern) + + def set_base_prompt( + self, pri_prompt_terminator=">", alt_prompt_terminator="#", **kwargs + ): + return super().set_base_prompt( + pri_prompt_terminator=pri_prompt_terminator, + alt_prompt_terminator=alt_prompt_terminator, + **kwargs + ) + + +class AdtranOSSSH(AdtranOSBase): + pass</code></pre> +</details> +</section> +<section> +</section> +<section> +</section> +<section> +</section> +<section> +<h2 class="section-title" id="header-classes">Classes</h2> +<dl> +<dt id="netmiko.adtran.adtran.AdtranOSBase"><code class="flex name class"> +<span>class <span class="ident">AdtranOSBase</span></span> +<span>(</span><span>*args, **kwargs)</span> +</code></dt> +<dd> +<section class="desc"><p>Base Class for cisco-like behavior.</p> +<pre><code> Initialize attributes for establishing connection to target device. + + :param ip: IP address of target device. Not required if `host` is + provided. + :type ip: str + + :param host: Hostname of target device. Not required if `ip` is + provided. + :type host: str + + :param username: Username to authenticate against target device if + required. + :type username: str + + :param password: Password to authenticate against target device if + required. + :type password: str + + :param secret: The enable password if target device requires one. + :type secret: str + + :param port: The destination port used to connect to the target + device. + :type port: int or None + + :param device_type: Class selection based on device type. + :type device_type: str + + :param verbose: Enable additional messages to standard output. + :type verbose: bool + + :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1). + :type global_delay_factor: int + + :param use_keys: Connect to target device using SSH keys. + :type use_keys: bool + + :param key_file: Filename path of the SSH key file to use. + :type key_file: str + + :param pkey: SSH key object to use. + :type pkey: paramiko.PKey + + :param passphrase: Passphrase to use for encrypted key; password will be used for key + decryption if not specified. + :type passphrase: str + + :param allow_agent: Enable use of SSH key-agent. + :type allow_agent: bool + + :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which + means unknown SSH host keys will be accepted). + :type ssh_strict: bool + + :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. + :type alt_host_keys: bool + + :param alt_key_file: SSH host key file to use (if alt_host_keys=True). + :type alt_key_file: str + + :param ssh_config_file: File name of OpenSSH configuration file. + :type ssh_config_file: str + + :param timeout: Connection timeout. + :type timeout: float + + :param session_timeout: Set a timeout for parallel requests. + :type session_timeout: float + + :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response. + :type auth_timeout: float + + :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko). + :type banner_timeout: float + + :param keepalive: Send SSH keepalive packets at a specific interval, in seconds. + Currently defaults to 0, for backwards compatibility (it will not attempt + to keep the connection alive). + :type keepalive: int + + :param default_enter: Character(s) to send to correspond to enter key (default: +</code></pre> +<p>). +:type default_enter: str</p> +<pre><code> :param response_return: Character(s) to use in normalized return data to represent + enter key (default: +</code></pre> +<p>) +:type response_return: str</p> +<pre><code> :param fast_cli: Provide a way to optimize for performance. Converts select_delay_factor + to select smallest of global and specific. Sets default global_delay_factor to .1 + (default: False) + :type fast_cli: boolean + + :param session_log: File path or BufferedIOBase subclass object to write the session log to. + :type session_log: str + + :param session_log_record_writes: The session log generally only records channel reads due + to eliminate command duplication due to command echo. You can enable this if you + want to record both channel reads and channel writes in the log (default: False). + :type session_log_record_writes: boolean + + :param session_log_file_mode: "write" or "append" for session_log file mode + (default: "write") + :type session_log_file_mode: str + + :param allow_auto_change: Allow automatic configuration changes for terminal settings. + (default: False) + :type allow_auto_change: bool + + :param encoding: Encoding to be used when writing bytes to the output channel. + (default: ascii) + :type encoding: str + + :param sock: An open socket or socket-like object (such as a `.Channel`) to use for + communication to the target host (default: None). + :type sock: socket + + :param global_cmd_verify: Control whether command echo verification is enabled or disabled + (default: None). Global attribute takes precedence over function `cmd_verify` + argument. Value of `None` indicates to use function `cmd_verify` argument. + :type global_cmd_verify: bool|None + + :param auto_connect: Control whether Netmiko automatically establishes the connection as + part of the object creation (default: True). + :type auto_connect: bool +</code></pre></section> +<details class="source"> +<summary>Source code</summary> +<pre><code class="python">class AdtranOSBase(CiscoBaseConnection): + def __init__(self, *args, **kwargs): + if kwargs.get("global_cmd_verify") is None: + kwargs["global_cmd_verify"] = False + return super().__init__(*args, **kwargs) + + def session_preparation(self): + """Prepare the session after the connection has been established.""" + self.ansi_escape_codes = True + self._test_channel_read() + self.set_base_prompt() + self.disable_paging(command="terminal length 0") + # Clear the read buffer + time.sleep(0.3 * self.global_delay_factor) + self.clear_buffer() + + def check_enable_mode(self, check_string="#"): + return super().check_enable_mode(check_string=check_string) + + def enable(self, cmd="enable", pattern="", re_flags=re.IGNORECASE): + return super().enable(cmd=cmd, pattern=pattern, re_flags=re_flags) + + def exit_enable_mode(self, exit_command="disable"): + return super().exit_enable_mode(exit_command=exit_command) + + def check_config_mode(self, check_string=")#"): + return super().check_config_mode(check_string=check_string) + + def config_mode(self, config_command="config term", pattern=""): + return super().config_mode(config_command=config_command, pattern=pattern) + + def exit_config_mode(self, exit_config="end", pattern="#"): + return super().exit_config_mode(exit_config=exit_config, pattern=pattern) + + def set_base_prompt( + self, pri_prompt_terminator=">", alt_prompt_terminator="#", **kwargs + ): + return super().set_base_prompt( + pri_prompt_terminator=pri_prompt_terminator, + alt_prompt_terminator=alt_prompt_terminator, + **kwargs + )</code></pre> +</details> +<h3>Ancestors</h3> +<ul class="hlist"> +<li><a title="netmiko.cisco_base_connection.CiscoBaseConnection" href="../cisco_base_connection.html#netmiko.cisco_base_connection.CiscoBaseConnection">CiscoBaseConnection</a></li> +<li><a title="netmiko.base_connection.BaseConnection" href="../base_connection.html#netmiko.base_connection.BaseConnection">BaseConnection</a></li> +</ul> +<h3>Subclasses</h3> +<ul class="hlist"> +<li><a title="netmiko.adtran.adtran.AdtranOSSSH" href="#netmiko.adtran.adtran.AdtranOSSSH">AdtranOSSSH</a></li> +</ul> +<h3>Methods</h3> +<dl> +<dt id="netmiko.adtran.adtran.AdtranOSBase.session_preparation"><code class="name flex"> +<span>def <span class="ident">session_preparation</span></span>(<span>self)</span> +</code></dt> +<dd> +<section class="desc"><p>Prepare the session after the connection has been established.</p></section> +<details class="source"> +<summary>Source code</summary> +<pre><code class="python">def session_preparation(self): + """Prepare the session after the connection has been established.""" + self.ansi_escape_codes = True + self._test_channel_read() + self.set_base_prompt() + self.disable_paging(command="terminal length 0") + # Clear the read buffer + time.sleep(0.3 * self.global_delay_factor) + self.clear_buffer()</code></pre> +</details> +</dd> +</dl> +<h3>Inherited members</h3> +<ul class="hlist"> +<li><code><b><a title="netmiko.cisco_base_connection.CiscoBaseConnection" href="../cisco_base_connection.html#netmiko.cisco_base_connection.CiscoBaseConnection">CiscoBaseConnection</a></b></code>: +<ul class="hlist"> +<li><code><a title="netmiko.cisco_base_connection.CiscoBaseConnection.check_config_mode" href="../cisco_base_connection.html#netmiko.cisco_base_connection.CiscoBaseConnection.check_config_mode">check_config_mode</a></code></li> +<li><code><a title="netmiko.cisco_base_connection.CiscoBaseConnection.check_enable_mode" href="../cisco_base_connection.html#netmiko.cisco_base_connection.CiscoBaseConnection.check_enable_mode">check_enable_mode</a></code></li> +<li><code><a title="netmiko.cisco_base_connection.CiscoBaseConnection.cleanup" href="../cisco_base_connection.html#netmiko.cisco_base_connection.CiscoBaseConnection.cleanup">cleanup</a></code></li> +<li><code><a title="netmiko.cisco_base_connection.CiscoBaseConnection.clear_buffer" href="../base_connection.html#netmiko.base_connection.BaseConnection.clear_buffer">clear_buffer</a></code></li> +<li><code><a title="netmiko.cisco_base_connection.CiscoBaseConnection.close_session_log" href="../base_connection.html#netmiko.base_connection.BaseConnection.close_session_log">close_session_log</a></code></li> +<li><code><a title="netmiko.cisco_base_connection.CiscoBaseConnection.commit" href="../base_connection.html#netmiko.base_connection.BaseConnection.commit">commit</a></code></li> +<li><code><a title="netmiko.cisco_base_connection.CiscoBaseConnection.config_mode" href="../cisco_base_connection.html#netmiko.cisco_base_connection.CiscoBaseConnection.config_mode">config_mode</a></code></li> +<li><code><a title="netmiko.cisco_base_connection.CiscoBaseConnection.disable_paging" href="../base_connection.html#netmiko.base_connection.BaseConnection.disable_paging">disable_paging</a></code></li> +<li><code><a title="netmiko.cisco_base_connection.CiscoBaseConnection.disconnect" href="../base_connection.html#netmiko.base_connection.BaseConnection.disconnect">disconnect</a></code></li> +<li><code><a title="netmiko.cisco_base_connection.CiscoBaseConnection.enable" href="../cisco_base_connection.html#netmiko.cisco_base_connection.CiscoBaseConnection.enable">enable</a></code></li> +<li><code><a title="netmiko.cisco_base_connection.CiscoBaseConnection.establish_connection" href="../base_connection.html#netmiko.base_connection.BaseConnection.establish_connection">establish_connection</a></code></li> +<li><code><a title="netmiko.cisco_base_connection.CiscoBaseConnection.exit_config_mode" href="../cisco_base_connection.html#netmiko.cisco_base_connection.CiscoBaseConnection.exit_config_mode">exit_config_mode</a></code></li> +<li><code><a title="netmiko.cisco_base_connection.CiscoBaseConnection.exit_enable_mode" href="../cisco_base_connection.html#netmiko.cisco_base_connection.CiscoBaseConnection.exit_enable_mode">exit_enable_mode</a></code></li> +<li><code><a title="netmiko.cisco_base_connection.CiscoBaseConnection.find_prompt" href="../base_connection.html#netmiko.base_connection.BaseConnection.find_prompt">find_prompt</a></code></li> +<li><code><a title="netmiko.cisco_base_connection.CiscoBaseConnection.is_alive" href="../base_connection.html#netmiko.base_connection.BaseConnection.is_alive">is_alive</a></code></li> +<li><code><a title="netmiko.cisco_base_connection.CiscoBaseConnection.normalize_cmd" href="../base_connection.html#netmiko.base_connection.BaseConnection.normalize_cmd">normalize_cmd</a></code></li> +<li><code><a title="netmiko.cisco_base_connection.CiscoBaseConnection.normalize_linefeeds" href="../base_connection.html#netmiko.base_connection.BaseConnection.normalize_linefeeds">normalize_linefeeds</a></code></li> +<li><code><a title="netmiko.cisco_base_connection.CiscoBaseConnection.open_session_log" href="../base_connection.html#netmiko.base_connection.BaseConnection.open_session_log">open_session_log</a></code></li> +<li><code><a title="netmiko.cisco_base_connection.CiscoBaseConnection.paramiko_cleanup" href="../base_connection.html#netmiko.base_connection.BaseConnection.paramiko_cleanup">paramiko_cleanup</a></code></li> +<li><code><a title="netmiko.cisco_base_connection.CiscoBaseConnection.read_channel" href="../base_connection.html#netmiko.base_connection.BaseConnection.read_channel">read_channel</a></code></li> +<li><code><a title="netmiko.cisco_base_connection.CiscoBaseConnection.read_until_pattern" href="../base_connection.html#netmiko.base_connection.BaseConnection.read_until_pattern">read_until_pattern</a></code></li> +<li><code><a title="netmiko.cisco_base_connection.CiscoBaseConnection.read_until_prompt" href="../base_connection.html#netmiko.base_connection.BaseConnection.read_until_prompt">read_until_prompt</a></code></li> +<li><code><a title="netmiko.cisco_base_connection.CiscoBaseConnection.read_until_prompt_or_pattern" href="../base_connection.html#netmiko.base_connection.BaseConnection.read_until_prompt_or_pattern">read_until_prompt_or_pattern</a></code></li> +<li><code><a title="netmiko.cisco_base_connection.CiscoBaseConnection.save_config" href="../cisco_base_connection.html#netmiko.cisco_base_connection.CiscoBaseConnection.save_config">save_config</a></code></li> +<li><code><a title="netmiko.cisco_base_connection.CiscoBaseConnection.select_delay_factor" href="../base_connection.html#netmiko.base_connection.BaseConnection.select_delay_factor">select_delay_factor</a></code></li> +<li><code><a title="netmiko.cisco_base_connection.CiscoBaseConnection.send_command" href="../base_connection.html#netmiko.base_connection.BaseConnection.send_command">send_command</a></code></li> +<li><code><a title="netmiko.cisco_base_connection.CiscoBaseConnection.send_command_expect" href="../base_connection.html#netmiko.base_connection.BaseConnection.send_command_expect">send_command_expect</a></code></li> +<li><code><a title="netmiko.cisco_base_connection.CiscoBaseConnection.send_command_timing" href="../base_connection.html#netmiko.base_connection.BaseConnection.send_command_timing">send_command_timing</a></code></li> +<li><code><a title="netmiko.cisco_base_connection.CiscoBaseConnection.send_config_from_file" href="../base_connection.html#netmiko.base_connection.BaseConnection.send_config_from_file">send_config_from_file</a></code></li> +<li><code><a title="netmiko.cisco_base_connection.CiscoBaseConnection.send_config_set" href="../base_connection.html#netmiko.base_connection.BaseConnection.send_config_set">send_config_set</a></code></li> +<li><code><a title="netmiko.cisco_base_connection.CiscoBaseConnection.set_base_prompt" href="../base_connection.html#netmiko.base_connection.BaseConnection.set_base_prompt">set_base_prompt</a></code></li> +<li><code><a title="netmiko.cisco_base_connection.CiscoBaseConnection.set_terminal_width" href="../base_connection.html#netmiko.base_connection.BaseConnection.set_terminal_width">set_terminal_width</a></code></li> +<li><code><a title="netmiko.cisco_base_connection.CiscoBaseConnection.special_login_handler" href="../base_connection.html#netmiko.base_connection.BaseConnection.special_login_handler">special_login_handler</a></code></li> +<li><code><a title="netmiko.cisco_base_connection.CiscoBaseConnection.strip_ansi_escape_codes" href="../base_connection.html#netmiko.base_connection.BaseConnection.strip_ansi_escape_codes">strip_ansi_escape_codes</a></code></li> +<li><code><a title="netmiko.cisco_base_connection.CiscoBaseConnection.strip_backspaces" href="../base_connection.html#netmiko.base_connection.BaseConnection.strip_backspaces">strip_backspaces</a></code></li> +<li><code><a title="netmiko.cisco_base_connection.CiscoBaseConnection.strip_command" href="../base_connection.html#netmiko.base_connection.BaseConnection.strip_command">strip_command</a></code></li> +<li><code><a title="netmiko.cisco_base_connection.CiscoBaseConnection.strip_prompt" href="../base_connection.html#netmiko.base_connection.BaseConnection.strip_prompt">strip_prompt</a></code></li> +<li><code><a title="netmiko.cisco_base_connection.CiscoBaseConnection.telnet_login" href="../cisco_base_connection.html#netmiko.cisco_base_connection.CiscoBaseConnection.telnet_login">telnet_login</a></code></li> +<li><code><a title="netmiko.cisco_base_connection.CiscoBaseConnection.write_channel" href="../base_connection.html#netmiko.base_connection.BaseConnection.write_channel">write_channel</a></code></li> +</ul> +</li> +</ul> +</dd> +<dt id="netmiko.adtran.adtran.AdtranOSSSH"><code class="flex name class"> +<span>class <span class="ident">AdtranOSSSH</span></span> +<span>(</span><span>*args, **kwargs)</span> +</code></dt> +<dd> +<section class="desc"><p>Base Class for cisco-like behavior.</p> +<pre><code> Initialize attributes for establishing connection to target device. + + :param ip: IP address of target device. Not required if `host` is + provided. + :type ip: str + + :param host: Hostname of target device. Not required if `ip` is + provided. + :type host: str + + :param username: Username to authenticate against target device if + required. + :type username: str + + :param password: Password to authenticate against target device if + required. + :type password: str + + :param secret: The enable password if target device requires one. + :type secret: str + + :param port: The destination port used to connect to the target + device. + :type port: int or None + + :param device_type: Class selection based on device type. + :type device_type: str + + :param verbose: Enable additional messages to standard output. + :type verbose: bool + + :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1). + :type global_delay_factor: int + + :param use_keys: Connect to target device using SSH keys. + :type use_keys: bool + + :param key_file: Filename path of the SSH key file to use. + :type key_file: str + + :param pkey: SSH key object to use. + :type pkey: paramiko.PKey + + :param passphrase: Passphrase to use for encrypted key; password will be used for key + decryption if not specified. + :type passphrase: str + + :param allow_agent: Enable use of SSH key-agent. + :type allow_agent: bool + + :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which + means unknown SSH host keys will be accepted). + :type ssh_strict: bool + + :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. + :type alt_host_keys: bool + + :param alt_key_file: SSH host key file to use (if alt_host_keys=True). + :type alt_key_file: str + + :param ssh_config_file: File name of OpenSSH configuration file. + :type ssh_config_file: str + + :param timeout: Connection timeout. + :type timeout: float + + :param session_timeout: Set a timeout for parallel requests. + :type session_timeout: float + + :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response. + :type auth_timeout: float + + :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko). + :type banner_timeout: float + + :param keepalive: Send SSH keepalive packets at a specific interval, in seconds. + Currently defaults to 0, for backwards compatibility (it will not attempt + to keep the connection alive). + :type keepalive: int + + :param default_enter: Character(s) to send to correspond to enter key (default: +</code></pre> +<p>). +:type default_enter: str</p> +<pre><code> :param response_return: Character(s) to use in normalized return data to represent + enter key (default: +</code></pre> +<p>) +:type response_return: str</p> +<pre><code> :param fast_cli: Provide a way to optimize for performance. Converts select_delay_factor + to select smallest of global and specific. Sets default global_delay_factor to .1 + (default: False) + :type fast_cli: boolean + + :param session_log: File path or BufferedIOBase subclass object to write the session log to. + :type session_log: str + + :param session_log_record_writes: The session log generally only records channel reads due + to eliminate command duplication due to command echo. You can enable this if you + want to record both channel reads and channel writes in the log (default: False). + :type session_log_record_writes: boolean + + :param session_log_file_mode: "write" or "append" for session_log file mode + (default: "write") + :type session_log_file_mode: str + + :param allow_auto_change: Allow automatic configuration changes for terminal settings. + (default: False) + :type allow_auto_change: bool + + :param encoding: Encoding to be used when writing bytes to the output channel. + (default: ascii) + :type encoding: str + + :param sock: An open socket or socket-like object (such as a `.Channel`) to use for + communication to the target host (default: None). + :type sock: socket + + :param global_cmd_verify: Control whether command echo verification is enabled or disabled + (default: None). Global attribute takes precedence over function `cmd_verify` + argument. Value of `None` indicates to use function `cmd_verify` argument. + :type global_cmd_verify: bool|None + + :param auto_connect: Control whether Netmiko automatically establishes the connection as + part of the object creation (default: True). + :type auto_connect: bool +</code></pre></section> +<details class="source"> +<summary>Source code</summary> +<pre><code class="python">class AdtranOSSSH(AdtranOSBase): + pass</code></pre> +</details> +<h3>Ancestors</h3> +<ul class="hlist"> +<li><a title="netmiko.adtran.adtran.AdtranOSBase" href="#netmiko.adtran.adtran.AdtranOSBase">AdtranOSBase</a></li> +<li><a title="netmiko.cisco_base_connection.CiscoBaseConnection" href="../cisco_base_connection.html#netmiko.cisco_base_connection.CiscoBaseConnection">CiscoBaseConnection</a></li> +<li><a title="netmiko.base_connection.BaseConnection" href="../base_connection.html#netmiko.base_connection.BaseConnection">BaseConnection</a></li> +</ul> +<h3>Inherited members</h3> +<ul class="hlist"> +<li><code><b><a title="netmiko.adtran.adtran.AdtranOSBase" href="#netmiko.adtran.adtran.AdtranOSBase">AdtranOSBase</a></b></code>: +<ul class="hlist"> +<li><code><a title="netmiko.adtran.adtran.AdtranOSBase.check_config_mode" href="../cisco_base_connection.html#netmiko.cisco_base_connection.CiscoBaseConnection.check_config_mode">check_config_mode</a></code></li> +<li><code><a title="netmiko.adtran.adtran.AdtranOSBase.check_enable_mode" href="../cisco_base_connection.html#netmiko.cisco_base_connection.CiscoBaseConnection.check_enable_mode">check_enable_mode</a></code></li> +<li><code><a title="netmiko.adtran.adtran.AdtranOSBase.cleanup" href="../cisco_base_connection.html#netmiko.cisco_base_connection.CiscoBaseConnection.cleanup">cleanup</a></code></li> +<li><code><a title="netmiko.adtran.adtran.AdtranOSBase.clear_buffer" href="../base_connection.html#netmiko.base_connection.BaseConnection.clear_buffer">clear_buffer</a></code></li> +<li><code><a title="netmiko.adtran.adtran.AdtranOSBase.close_session_log" href="../base_connection.html#netmiko.base_connection.BaseConnection.close_session_log">close_session_log</a></code></li> +<li><code><a title="netmiko.adtran.adtran.AdtranOSBase.commit" href="../base_connection.html#netmiko.base_connection.BaseConnection.commit">commit</a></code></li> +<li><code><a title="netmiko.adtran.adtran.AdtranOSBase.config_mode" href="../cisco_base_connection.html#netmiko.cisco_base_connection.CiscoBaseConnection.config_mode">config_mode</a></code></li> +<li><code><a title="netmiko.adtran.adtran.AdtranOSBase.disable_paging" href="../base_connection.html#netmiko.base_connection.BaseConnection.disable_paging">disable_paging</a></code></li> +<li><code><a title="netmiko.adtran.adtran.AdtranOSBase.disconnect" href="../base_connection.html#netmiko.base_connection.BaseConnection.disconnect">disconnect</a></code></li> +<li><code><a title="netmiko.adtran.adtran.AdtranOSBase.enable" href="../cisco_base_connection.html#netmiko.cisco_base_connection.CiscoBaseConnection.enable">enable</a></code></li> +<li><code><a title="netmiko.adtran.adtran.AdtranOSBase.establish_connection" href="../base_connection.html#netmiko.base_connection.BaseConnection.establish_connection">establish_connection</a></code></li> +<li><code><a title="netmiko.adtran.adtran.AdtranOSBase.exit_config_mode" href="../cisco_base_connection.html#netmiko.cisco_base_connection.CiscoBaseConnection.exit_config_mode">exit_config_mode</a></code></li> +<li><code><a title="netmiko.adtran.adtran.AdtranOSBase.exit_enable_mode" href="../cisco_base_connection.html#netmiko.cisco_base_connection.CiscoBaseConnection.exit_enable_mode">exit_enable_mode</a></code></li> +<li><code><a title="netmiko.adtran.adtran.AdtranOSBase.find_prompt" href="../base_connection.html#netmiko.base_connection.BaseConnection.find_prompt">find_prompt</a></code></li> +<li><code><a title="netmiko.adtran.adtran.AdtranOSBase.is_alive" href="../base_connection.html#netmiko.base_connection.BaseConnection.is_alive">is_alive</a></code></li> +<li><code><a title="netmiko.adtran.adtran.AdtranOSBase.normalize_cmd" href="../base_connection.html#netmiko.base_connection.BaseConnection.normalize_cmd">normalize_cmd</a></code></li> +<li><code><a title="netmiko.adtran.adtran.AdtranOSBase.normalize_linefeeds" href="../base_connection.html#netmiko.base_connection.BaseConnection.normalize_linefeeds">normalize_linefeeds</a></code></li> +<li><code><a title="netmiko.adtran.adtran.AdtranOSBase.open_session_log" href="../base_connection.html#netmiko.base_connection.BaseConnection.open_session_log">open_session_log</a></code></li> +<li><code><a title="netmiko.adtran.adtran.AdtranOSBase.paramiko_cleanup" href="../base_connection.html#netmiko.base_connection.BaseConnection.paramiko_cleanup">paramiko_cleanup</a></code></li> +<li><code><a title="netmiko.adtran.adtran.AdtranOSBase.read_channel" href="../base_connection.html#netmiko.base_connection.BaseConnection.read_channel">read_channel</a></code></li> +<li><code><a title="netmiko.adtran.adtran.AdtranOSBase.read_until_pattern" href="../base_connection.html#netmiko.base_connection.BaseConnection.read_until_pattern">read_until_pattern</a></code></li> +<li><code><a title="netmiko.adtran.adtran.AdtranOSBase.read_until_prompt" href="../base_connection.html#netmiko.base_connection.BaseConnection.read_until_prompt">read_until_prompt</a></code></li> +<li><code><a title="netmiko.adtran.adtran.AdtranOSBase.read_until_prompt_or_pattern" href="../base_connection.html#netmiko.base_connection.BaseConnection.read_until_prompt_or_pattern">read_until_prompt_or_pattern</a></code></li> +<li><code><a title="netmiko.adtran.adtran.AdtranOSBase.save_config" href="../cisco_base_connection.html#netmiko.cisco_base_connection.CiscoBaseConnection.save_config">save_config</a></code></li> +<li><code><a title="netmiko.adtran.adtran.AdtranOSBase.select_delay_factor" href="../base_connection.html#netmiko.base_connection.BaseConnection.select_delay_factor">select_delay_factor</a></code></li> +<li><code><a title="netmiko.adtran.adtran.AdtranOSBase.send_command" href="../base_connection.html#netmiko.base_connection.BaseConnection.send_command">send_command</a></code></li> +<li><code><a title="netmiko.adtran.adtran.AdtranOSBase.send_command_expect" href="../base_connection.html#netmiko.base_connection.BaseConnection.send_command_expect">send_command_expect</a></code></li> +<li><code><a title="netmiko.adtran.adtran.AdtranOSBase.send_command_timing" href="../base_connection.html#netmiko.base_connection.BaseConnection.send_command_timing">send_command_timing</a></code></li> +<li><code><a title="netmiko.adtran.adtran.AdtranOSBase.send_config_from_file" href="../base_connection.html#netmiko.base_connection.BaseConnection.send_config_from_file">send_config_from_file</a></code></li> +<li><code><a title="netmiko.adtran.adtran.AdtranOSBase.send_config_set" href="../base_connection.html#netmiko.base_connection.BaseConnection.send_config_set">send_config_set</a></code></li> +<li><code><a title="netmiko.adtran.adtran.AdtranOSBase.session_preparation" href="#netmiko.adtran.adtran.AdtranOSBase.session_preparation">session_preparation</a></code></li> +<li><code><a title="netmiko.adtran.adtran.AdtranOSBase.set_base_prompt" href="../base_connection.html#netmiko.base_connection.BaseConnection.set_base_prompt">set_base_prompt</a></code></li> +<li><code><a title="netmiko.adtran.adtran.AdtranOSBase.set_terminal_width" href="../base_connection.html#netmiko.base_connection.BaseConnection.set_terminal_width">set_terminal_width</a></code></li> +<li><code><a title="netmiko.adtran.adtran.AdtranOSBase.special_login_handler" href="../base_connection.html#netmiko.base_connection.BaseConnection.special_login_handler">special_login_handler</a></code></li> +<li><code><a title="netmiko.adtran.adtran.AdtranOSBase.strip_ansi_escape_codes" href="../base_connection.html#netmiko.base_connection.BaseConnection.strip_ansi_escape_codes">strip_ansi_escape_codes</a></code></li> +<li><code><a title="netmiko.adtran.adtran.AdtranOSBase.strip_backspaces" href="../base_connection.html#netmiko.base_connection.BaseConnection.strip_backspaces">strip_backspaces</a></code></li> +<li><code><a title="netmiko.adtran.adtran.AdtranOSBase.strip_command" href="../base_connection.html#netmiko.base_connection.BaseConnection.strip_command">strip_command</a></code></li> +<li><code><a title="netmiko.adtran.adtran.AdtranOSBase.strip_prompt" href="../base_connection.html#netmiko.base_connection.BaseConnection.strip_prompt">strip_prompt</a></code></li> +<li><code><a title="netmiko.adtran.adtran.AdtranOSBase.telnet_login" href="../cisco_base_connection.html#netmiko.cisco_base_connection.CiscoBaseConnection.telnet_login">telnet_login</a></code></li> +<li><code><a title="netmiko.adtran.adtran.AdtranOSBase.write_channel" href="../base_connection.html#netmiko.base_connection.BaseConnection.write_channel">write_channel</a></code></li> +</ul> +</li> +</ul> +</dd> +</dl> +</section> +</article> +<nav id="sidebar"> +<h1>Index</h1> +<div class="toc"> +<ul></ul> +</div> +<ul id="index"> +<li><h3>Super-module</h3> +<ul> +<li><code><a title="netmiko.adtran" href="index.html">netmiko.adtran</a></code></li> +</ul> +</li> +<li><h3><a href="#header-classes">Classes</a></h3> +<ul> +<li> +<h4><code><a title="netmiko.adtran.adtran.AdtranOSBase" href="#netmiko.adtran.adtran.AdtranOSBase">AdtranOSBase</a></code></h4> +<ul class=""> +<li><code><a title="netmiko.adtran.adtran.AdtranOSBase.session_preparation" href="#netmiko.adtran.adtran.AdtranOSBase.session_preparation">session_preparation</a></code></li> +</ul> +</li> +<li> +<h4><code><a title="netmiko.adtran.adtran.AdtranOSSSH" href="#netmiko.adtran.adtran.AdtranOSSSH">AdtranOSSSH</a></code></h4> +</li> +</ul> +</li> +</ul> +</nav> +</main> +<footer id="footer"> +<p>Generated by <a href="https://pdoc3.github.io/pdoc"><cite>pdoc</cite> 0.6.3</a>.</p> +</footer> +<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/highlight.min.js"></script> +<script>hljs.initHighlightingOnLoad()</script> +</body> +</html> \ No newline at end of file diff --git a/docs/netmiko/adtran/index.html b/docs/netmiko/adtran/index.html new file mode 100644 index 0000000000000000000000000000000000000000..db33db62a8ce04ab3b1cc5b7a007f0f5065b381e --- /dev/null +++ b/docs/netmiko/adtran/index.html @@ -0,0 +1,276 @@ +<!doctype html> +<html lang="en"> +<head> +<meta charset="utf-8"> +<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1" /> +<meta name="generator" content="pdoc 0.6.3" /> +<title>netmiko.adtran API documentation</title> +<meta name="description" content="" /> +<link href='https://cdnjs.cloudflare.com/ajax/libs/normalize/8.0.0/normalize.min.css' rel='stylesheet'> +<link href='https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/8.0.0/sanitize.min.css' rel='stylesheet'> +<link href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/github.min.css" rel="stylesheet"> +<style>.flex{display:flex !important}body{line-height:1.5em}#content{padding:20px}#sidebar{padding:30px;overflow:hidden}.http-server-breadcrumbs{font-size:130%;margin:0 0 15px 0}#footer{font-size:.75em;padding:5px 30px;border-top:1px solid #ddd;text-align:right}#footer p{margin:0 0 0 1em;display:inline-block}#footer p:last-child{margin-right:30px}h1,h2,h3,h4,h5{font-weight:300}h1{font-size:2.5em;line-height:1.1em}h2{font-size:1.75em;margin:1em 0 .50em 0}h3{font-size:1.4em;margin:25px 0 10px 0}h4{margin:0;font-size:105%}a{color:#058;text-decoration:none;transition:color .3s ease-in-out}a:hover{color:#e82}.title code{font-weight:bold}h2[id^="header-"]{margin-top:2em}.ident{color:#900}pre code{background:#f8f8f8;font-size:.8em;line-height:1.4em}code{background:#f2f2f1;padding:1px 4px;overflow-wrap:break-word}h1 code{background:transparent}pre{background:#f8f8f8;border:0;border-top:1px solid #ccc;border-bottom:1px solid #ccc;margin:1em 0;padding:1ex}#http-server-module-list{display:flex;flex-flow:column}#http-server-module-list div{display:flex}#http-server-module-list dt{min-width:10%}#http-server-module-list p{margin-top:0}.toc ul,#index{list-style-type:none;margin:0;padding:0}#index code{background:transparent}#index h3{border-bottom:1px solid #ddd}#index ul{padding:0}#index h4{font-weight:bold}#index h4 + ul{margin-bottom:.6em}@media (min-width:200ex){#index .two-column{column-count:2}}@media (min-width:300ex){#index .two-column{column-count:3}}dl{margin-bottom:2em}dl dl:last-child{margin-bottom:4em}dd{margin:0 0 1em 3em}#header-classes + dl > dd{margin-bottom:3em}dd dd{margin-left:2em}dd p{margin:10px 0}.name{background:#eee;font-weight:bold;font-size:.85em;padding:5px 10px;display:inline-block;min-width:40%}.name:hover{background:#e0e0e0}.name > span:first-child{white-space:nowrap}.name.class > span:nth-child(2){margin-left:.4em}.inherited{color:#999;border-left:5px solid #eee;padding-left:1em}.inheritance em{font-style:normal;font-weight:bold}.desc h2{font-weight:400;font-size:1.25em}.desc h3{font-size:1em}.desc dt code{background:inherit}.source summary{color:#666;text-align:right;font-weight:400;font-size:.8em;text-transform:uppercase;cursor:pointer}.source pre{max-height:500px;overflow:auto;margin:0}.source pre code{font-size:12px;overflow:visible}.hlist{list-style:none}.hlist li{display:inline}.hlist li:after{content:',\2002'}.hlist li:last-child:after{content:none}.hlist .hlist{display:inline;padding-left:1em}img{max-width:100%}.admonition{padding:.1em .5em;margin-bottom:1em}.admonition-title{font-weight:bold}.admonition.note,.admonition.info,.admonition.important{background:#aef}.admonition.todo,.admonition.versionadded,.admonition.tip,.admonition.hint{background:#dfd}.admonition.warning,.admonition.versionchanged,.admonition.deprecated{background:#fd4}.admonition.error,.admonition.danger,.admonition.caution{background:lightpink}</style> +<style media="screen and (min-width: 700px)">@media screen and (min-width:700px){#sidebar{width:30%}#content{width:70%;max-width:100ch;padding:3em 4em;border-left:1px solid #ddd}pre code{font-size:1em}.item .name{font-size:1em}main{display:flex;flex-direction:row-reverse;justify-content:flex-end}.toc ul ul,#index ul{padding-left:1.5em}.toc > ul > li{margin-top:.5em}}</style> +<style media="print">@media print{#sidebar h1{page-break-before:always}.source{display:none}}@media print{*{background:transparent !important;color:#000 !important;box-shadow:none !important;text-shadow:none !important}a[href]:after{content:" (" attr(href) ")";font-size:90%}a[href][title]:after{content:none}abbr[title]:after{content:" (" attr(title) ")"}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}@page{margin:0.5cm}p,h2,h3{orphans:3;widows:3}h1,h2,h3,h4,h5,h6{page-break-after:avoid}}</style> +</head> +<body> +<main> +<article id="content"> +<header> +<h1 class="title">Module <code>netmiko.adtran</code></h1> +</header> +<section id="section-intro"> +<details class="source"> +<summary>Source code</summary> +<pre><code class="python">from netmiko.adtran.adtran import AdtranOSSSH + +__all__ = ["AdtranOSSSH"]</code></pre> +</details> +</section> +<section> +<h2 class="section-title" id="header-submodules">Sub-modules</h2> +<dl> +<dt><code class="name"><a title="netmiko.adtran.adtran" href="adtran.html">netmiko.adtran.adtran</a></code></dt> +<dd> +<section class="desc"></section> +</dd> +</dl> +</section> +<section> +</section> +<section> +</section> +<section> +<h2 class="section-title" id="header-classes">Classes</h2> +<dl> +<dt id="netmiko.adtran.AdtranOSSSH"><code class="flex name class"> +<span>class <span class="ident">AdtranOSSSH</span></span> +<span>(</span><span>*args, **kwargs)</span> +</code></dt> +<dd> +<section class="desc"><p>Base Class for cisco-like behavior.</p> +<pre><code> Initialize attributes for establishing connection to target device. + + :param ip: IP address of target device. Not required if `host` is + provided. + :type ip: str + + :param host: Hostname of target device. Not required if `ip` is + provided. + :type host: str + + :param username: Username to authenticate against target device if + required. + :type username: str + + :param password: Password to authenticate against target device if + required. + :type password: str + + :param secret: The enable password if target device requires one. + :type secret: str + + :param port: The destination port used to connect to the target + device. + :type port: int or None + + :param device_type: Class selection based on device type. + :type device_type: str + + :param verbose: Enable additional messages to standard output. + :type verbose: bool + + :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1). + :type global_delay_factor: int + + :param use_keys: Connect to target device using SSH keys. + :type use_keys: bool + + :param key_file: Filename path of the SSH key file to use. + :type key_file: str + + :param pkey: SSH key object to use. + :type pkey: paramiko.PKey + + :param passphrase: Passphrase to use for encrypted key; password will be used for key + decryption if not specified. + :type passphrase: str + + :param allow_agent: Enable use of SSH key-agent. + :type allow_agent: bool + + :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which + means unknown SSH host keys will be accepted). + :type ssh_strict: bool + + :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. + :type alt_host_keys: bool + + :param alt_key_file: SSH host key file to use (if alt_host_keys=True). + :type alt_key_file: str + + :param ssh_config_file: File name of OpenSSH configuration file. + :type ssh_config_file: str + + :param timeout: Connection timeout. + :type timeout: float + + :param session_timeout: Set a timeout for parallel requests. + :type session_timeout: float + + :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response. + :type auth_timeout: float + + :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko). + :type banner_timeout: float + + :param keepalive: Send SSH keepalive packets at a specific interval, in seconds. + Currently defaults to 0, for backwards compatibility (it will not attempt + to keep the connection alive). + :type keepalive: int + + :param default_enter: Character(s) to send to correspond to enter key (default: +</code></pre> +<p>). +:type default_enter: str</p> +<pre><code> :param response_return: Character(s) to use in normalized return data to represent + enter key (default: +</code></pre> +<p>) +:type response_return: str</p> +<pre><code> :param fast_cli: Provide a way to optimize for performance. Converts select_delay_factor + to select smallest of global and specific. Sets default global_delay_factor to .1 + (default: False) + :type fast_cli: boolean + + :param session_log: File path or BufferedIOBase subclass object to write the session log to. + :type session_log: str + + :param session_log_record_writes: The session log generally only records channel reads due + to eliminate command duplication due to command echo. You can enable this if you + want to record both channel reads and channel writes in the log (default: False). + :type session_log_record_writes: boolean + + :param session_log_file_mode: "write" or "append" for session_log file mode + (default: "write") + :type session_log_file_mode: str + + :param allow_auto_change: Allow automatic configuration changes for terminal settings. + (default: False) + :type allow_auto_change: bool + + :param encoding: Encoding to be used when writing bytes to the output channel. + (default: ascii) + :type encoding: str + + :param sock: An open socket or socket-like object (such as a `.Channel`) to use for + communication to the target host (default: None). + :type sock: socket + + :param global_cmd_verify: Control whether command echo verification is enabled or disabled + (default: None). Global attribute takes precedence over function `cmd_verify` + argument. Value of `None` indicates to use function `cmd_verify` argument. + :type global_cmd_verify: bool|None + + :param auto_connect: Control whether Netmiko automatically establishes the connection as + part of the object creation (default: True). + :type auto_connect: bool +</code></pre></section> +<details class="source"> +<summary>Source code</summary> +<pre><code class="python">class AdtranOSSSH(AdtranOSBase): + pass</code></pre> +</details> +<h3>Ancestors</h3> +<ul class="hlist"> +<li><a title="netmiko.adtran.adtran.AdtranOSBase" href="adtran.html#netmiko.adtran.adtran.AdtranOSBase">AdtranOSBase</a></li> +<li><a title="netmiko.cisco_base_connection.CiscoBaseConnection" href="../cisco_base_connection.html#netmiko.cisco_base_connection.CiscoBaseConnection">CiscoBaseConnection</a></li> +<li><a title="netmiko.base_connection.BaseConnection" href="../base_connection.html#netmiko.base_connection.BaseConnection">BaseConnection</a></li> +</ul> +<h3>Inherited members</h3> +<ul class="hlist"> +<li><code><b><a title="netmiko.adtran.adtran.AdtranOSBase" href="adtran.html#netmiko.adtran.adtran.AdtranOSBase">AdtranOSBase</a></b></code>: +<ul class="hlist"> +<li><code><a title="netmiko.adtran.adtran.AdtranOSBase.check_config_mode" href="../cisco_base_connection.html#netmiko.cisco_base_connection.CiscoBaseConnection.check_config_mode">check_config_mode</a></code></li> +<li><code><a title="netmiko.adtran.adtran.AdtranOSBase.check_enable_mode" href="../cisco_base_connection.html#netmiko.cisco_base_connection.CiscoBaseConnection.check_enable_mode">check_enable_mode</a></code></li> +<li><code><a title="netmiko.adtran.adtran.AdtranOSBase.cleanup" href="../cisco_base_connection.html#netmiko.cisco_base_connection.CiscoBaseConnection.cleanup">cleanup</a></code></li> +<li><code><a title="netmiko.adtran.adtran.AdtranOSBase.clear_buffer" href="../base_connection.html#netmiko.base_connection.BaseConnection.clear_buffer">clear_buffer</a></code></li> +<li><code><a title="netmiko.adtran.adtran.AdtranOSBase.close_session_log" href="../base_connection.html#netmiko.base_connection.BaseConnection.close_session_log">close_session_log</a></code></li> +<li><code><a title="netmiko.adtran.adtran.AdtranOSBase.commit" href="../base_connection.html#netmiko.base_connection.BaseConnection.commit">commit</a></code></li> +<li><code><a title="netmiko.adtran.adtran.AdtranOSBase.config_mode" href="../cisco_base_connection.html#netmiko.cisco_base_connection.CiscoBaseConnection.config_mode">config_mode</a></code></li> +<li><code><a title="netmiko.adtran.adtran.AdtranOSBase.disable_paging" href="../base_connection.html#netmiko.base_connection.BaseConnection.disable_paging">disable_paging</a></code></li> +<li><code><a title="netmiko.adtran.adtran.AdtranOSBase.disconnect" href="../base_connection.html#netmiko.base_connection.BaseConnection.disconnect">disconnect</a></code></li> +<li><code><a title="netmiko.adtran.adtran.AdtranOSBase.enable" href="../cisco_base_connection.html#netmiko.cisco_base_connection.CiscoBaseConnection.enable">enable</a></code></li> +<li><code><a title="netmiko.adtran.adtran.AdtranOSBase.establish_connection" href="../base_connection.html#netmiko.base_connection.BaseConnection.establish_connection">establish_connection</a></code></li> +<li><code><a title="netmiko.adtran.adtran.AdtranOSBase.exit_config_mode" href="../cisco_base_connection.html#netmiko.cisco_base_connection.CiscoBaseConnection.exit_config_mode">exit_config_mode</a></code></li> +<li><code><a title="netmiko.adtran.adtran.AdtranOSBase.exit_enable_mode" href="../cisco_base_connection.html#netmiko.cisco_base_connection.CiscoBaseConnection.exit_enable_mode">exit_enable_mode</a></code></li> +<li><code><a title="netmiko.adtran.adtran.AdtranOSBase.find_prompt" href="../base_connection.html#netmiko.base_connection.BaseConnection.find_prompt">find_prompt</a></code></li> +<li><code><a title="netmiko.adtran.adtran.AdtranOSBase.is_alive" href="../base_connection.html#netmiko.base_connection.BaseConnection.is_alive">is_alive</a></code></li> +<li><code><a title="netmiko.adtran.adtran.AdtranOSBase.normalize_cmd" href="../base_connection.html#netmiko.base_connection.BaseConnection.normalize_cmd">normalize_cmd</a></code></li> +<li><code><a title="netmiko.adtran.adtran.AdtranOSBase.normalize_linefeeds" href="../base_connection.html#netmiko.base_connection.BaseConnection.normalize_linefeeds">normalize_linefeeds</a></code></li> +<li><code><a title="netmiko.adtran.adtran.AdtranOSBase.open_session_log" href="../base_connection.html#netmiko.base_connection.BaseConnection.open_session_log">open_session_log</a></code></li> +<li><code><a title="netmiko.adtran.adtran.AdtranOSBase.paramiko_cleanup" href="../base_connection.html#netmiko.base_connection.BaseConnection.paramiko_cleanup">paramiko_cleanup</a></code></li> +<li><code><a title="netmiko.adtran.adtran.AdtranOSBase.read_channel" href="../base_connection.html#netmiko.base_connection.BaseConnection.read_channel">read_channel</a></code></li> +<li><code><a title="netmiko.adtran.adtran.AdtranOSBase.read_until_pattern" href="../base_connection.html#netmiko.base_connection.BaseConnection.read_until_pattern">read_until_pattern</a></code></li> +<li><code><a title="netmiko.adtran.adtran.AdtranOSBase.read_until_prompt" href="../base_connection.html#netmiko.base_connection.BaseConnection.read_until_prompt">read_until_prompt</a></code></li> +<li><code><a title="netmiko.adtran.adtran.AdtranOSBase.read_until_prompt_or_pattern" href="../base_connection.html#netmiko.base_connection.BaseConnection.read_until_prompt_or_pattern">read_until_prompt_or_pattern</a></code></li> +<li><code><a title="netmiko.adtran.adtran.AdtranOSBase.save_config" href="../cisco_base_connection.html#netmiko.cisco_base_connection.CiscoBaseConnection.save_config">save_config</a></code></li> +<li><code><a title="netmiko.adtran.adtran.AdtranOSBase.select_delay_factor" href="../base_connection.html#netmiko.base_connection.BaseConnection.select_delay_factor">select_delay_factor</a></code></li> +<li><code><a title="netmiko.adtran.adtran.AdtranOSBase.send_command" href="../base_connection.html#netmiko.base_connection.BaseConnection.send_command">send_command</a></code></li> +<li><code><a title="netmiko.adtran.adtran.AdtranOSBase.send_command_expect" href="../base_connection.html#netmiko.base_connection.BaseConnection.send_command_expect">send_command_expect</a></code></li> +<li><code><a title="netmiko.adtran.adtran.AdtranOSBase.send_command_timing" href="../base_connection.html#netmiko.base_connection.BaseConnection.send_command_timing">send_command_timing</a></code></li> +<li><code><a title="netmiko.adtran.adtran.AdtranOSBase.send_config_from_file" href="../base_connection.html#netmiko.base_connection.BaseConnection.send_config_from_file">send_config_from_file</a></code></li> +<li><code><a title="netmiko.adtran.adtran.AdtranOSBase.send_config_set" href="../base_connection.html#netmiko.base_connection.BaseConnection.send_config_set">send_config_set</a></code></li> +<li><code><a title="netmiko.adtran.adtran.AdtranOSBase.session_preparation" href="adtran.html#netmiko.adtran.adtran.AdtranOSBase.session_preparation">session_preparation</a></code></li> +<li><code><a title="netmiko.adtran.adtran.AdtranOSBase.set_base_prompt" href="../base_connection.html#netmiko.base_connection.BaseConnection.set_base_prompt">set_base_prompt</a></code></li> +<li><code><a title="netmiko.adtran.adtran.AdtranOSBase.set_terminal_width" href="../base_connection.html#netmiko.base_connection.BaseConnection.set_terminal_width">set_terminal_width</a></code></li> +<li><code><a title="netmiko.adtran.adtran.AdtranOSBase.special_login_handler" href="../base_connection.html#netmiko.base_connection.BaseConnection.special_login_handler">special_login_handler</a></code></li> +<li><code><a title="netmiko.adtran.adtran.AdtranOSBase.strip_ansi_escape_codes" href="../base_connection.html#netmiko.base_connection.BaseConnection.strip_ansi_escape_codes">strip_ansi_escape_codes</a></code></li> +<li><code><a title="netmiko.adtran.adtran.AdtranOSBase.strip_backspaces" href="../base_connection.html#netmiko.base_connection.BaseConnection.strip_backspaces">strip_backspaces</a></code></li> +<li><code><a title="netmiko.adtran.adtran.AdtranOSBase.strip_command" href="../base_connection.html#netmiko.base_connection.BaseConnection.strip_command">strip_command</a></code></li> +<li><code><a title="netmiko.adtran.adtran.AdtranOSBase.strip_prompt" href="../base_connection.html#netmiko.base_connection.BaseConnection.strip_prompt">strip_prompt</a></code></li> +<li><code><a title="netmiko.adtran.adtran.AdtranOSBase.telnet_login" href="../cisco_base_connection.html#netmiko.cisco_base_connection.CiscoBaseConnection.telnet_login">telnet_login</a></code></li> +<li><code><a title="netmiko.adtran.adtran.AdtranOSBase.write_channel" href="../base_connection.html#netmiko.base_connection.BaseConnection.write_channel">write_channel</a></code></li> +</ul> +</li> +</ul> +</dd> +</dl> +</section> +</article> +<nav id="sidebar"> +<h1>Index</h1> +<div class="toc"> +<ul></ul> +</div> +<ul id="index"> +<li><h3>Super-module</h3> +<ul> +<li><code><a title="netmiko" href="../index.html">netmiko</a></code></li> +</ul> +</li> +<li><h3><a href="#header-submodules">Sub-modules</a></h3> +<ul> +<li><code><a title="netmiko.adtran.adtran" href="adtran.html">netmiko.adtran.adtran</a></code></li> +</ul> +</li> +<li><h3><a href="#header-classes">Classes</a></h3> +<ul> +<li> +<h4><code><a title="netmiko.adtran.AdtranOSSSH" href="#netmiko.adtran.AdtranOSSSH">AdtranOSSSH</a></code></h4> +</li> +</ul> +</li> +</ul> +</nav> +</main> +<footer id="footer"> +<p>Generated by <a href="https://pdoc3.github.io/pdoc"><cite>pdoc</cite> 0.6.3</a>.</p> +</footer> +<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/highlight.min.js"></script> +<script>hljs.initHighlightingOnLoad()</script> +</body> +</html> \ No newline at end of file diff --git a/docs/netmiko/arista/arista.html b/docs/netmiko/arista/arista.html index 6c2ece8c151d17dd4676a817b09398e1fc93bedc..a426d43ad01115f7c4e9e48b0a1b98a52fe93a9b 100644 --- a/docs/netmiko/arista/arista.html +++ b/docs/netmiko/arista/arista.html @@ -32,8 +32,8 @@ class AristaBase(CiscoSSHConnection): """Prepare the session after the connection has been established.""" self._test_channel_read(pattern=r"[>#]") self.set_base_prompt() + self.set_terminal_width(command="terminal width 511", pattern="terminal") self.disable_paging() - self.set_terminal_width(command="terminal width 511") # Clear the read buffer time.sleep(0.3 * self.global_delay_factor) self.clear_buffer() @@ -284,8 +284,8 @@ class AristaFileTransfer(CiscoFileTransfer): """Prepare the session after the connection has been established.""" self._test_channel_read(pattern=r"[>#]") self.set_base_prompt() + self.set_terminal_width(command="terminal width 511", pattern="terminal") self.disable_paging() - self.set_terminal_width(command="terminal width 511") # Clear the read buffer time.sleep(0.3 * self.global_delay_factor) self.clear_buffer() @@ -371,8 +371,8 @@ loc1-core01(s1)#</p> """Prepare the session after the connection has been established.""" self._test_channel_read(pattern=r"[>#]") self.set_base_prompt() + self.set_terminal_width(command="terminal width 511", pattern="terminal") self.disable_paging() - self.set_terminal_width(command="terminal width 511") # Clear the read buffer time.sleep(0.3 * self.global_delay_factor) self.clear_buffer()</code></pre> diff --git a/docs/netmiko/base_connection.html b/docs/netmiko/base_connection.html index 3669a9339b26280407fd5eaac8f7174b31c8021a..8ddfbbba00f5a65de29dffc090284102de7f845a 100644 --- a/docs/netmiko/base_connection.html +++ b/docs/netmiko/base_connection.html @@ -59,6 +59,7 @@ from netmiko.utilities import ( get_structured_data_genie, select_cmd_verify, ) +from netmiko.utilities import m_exec_time # noqa class BaseConnection(object): @@ -106,6 +107,7 @@ class BaseConnection(object): response_return=None, serial_settings=None, fast_cli=False, + _legacy_mode=True, session_log=None, session_log_record_writes=False, session_log_file_mode="write", @@ -325,6 +327,7 @@ class BaseConnection(object): self.serial_settings.update({"port": comm_port}) self.fast_cli = fast_cli + self._legacy_mode = _legacy_mode self.global_delay_factor = global_delay_factor self.global_cmd_verify = global_cmd_verify if self.fast_cli and self.global_delay_factor == 1: @@ -818,8 +821,8 @@ class BaseConnection(object): """ self._test_channel_read() self.set_base_prompt() - self.disable_paging() self.set_terminal_width() + self.disable_paging() # Clear the read buffer time.sleep(0.3 * self.global_delay_factor) @@ -963,11 +966,29 @@ Device settings: {self.device_type} {self.host}:{self.port} msg = msg.lstrip() raise NetmikoTimeoutException(msg) + except paramiko.ssh_exception.SSHException as no_session_err: + self.paramiko_cleanup() + if "No existing session" in str(no_session_err): + msg = ( + "Paramiko: 'No existing session' error: " + "try increasing 'conn_timeout' to 10 seconds or larger." + ) + raise NetmikoTimeoutException(msg) + else: + raise except paramiko.ssh_exception.AuthenticationException as auth_err: self.paramiko_cleanup() - msg = "Authentication failure: unable to connect {device_type} {ip}:{port}".format( - device_type=self.device_type, ip=self.host, port=self.port - ) + msg = f"""Authentication to device failed. + +Common causes of this problem are: +1. Invalid username and password +2. Incorrect SSH-key file +3. Connecting to the wrong device + +Device settings: {self.device_type} {self.host}:{self.port} + +""" + msg += self.RETURN + str(auth_err) raise NetmikoAuthenticationException(msg) @@ -1066,7 +1087,9 @@ Device settings: {self.device_type} {self.host}:{self.port} """Handler for devices like WLC, Extreme ERS that throw up characters prior to login.""" pass - def disable_paging(self, command="terminal length 0", delay_factor=1): + def disable_paging( + self, command="terminal length 0", delay_factor=1, cmd_verify=True, pattern=None + ): """Disable paging default to a Cisco CLI method. :param command: Device command to disable pagination of output @@ -1076,19 +1099,24 @@ Device settings: {self.device_type} {self.host}:{self.port} :type delay_factor: int """ 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(f"Command: {command}") self.write_channel(command) - # Do not use command_verify here as still in session_preparation stage. - output = self.read_until_prompt() + # Make sure you read until you detect the command echo (avoid getting out of sync) + if cmd_verify and self.global_cmd_verify is not False: + output = self.read_until_pattern(pattern=re.escape(command.strip())) + elif pattern: + output = self.read_until_pattern(pattern=pattern) + else: + output = self.read_until_prompt() log.debug(f"{output}") log.debug("Exiting disable_paging") return output - def set_terminal_width(self, command="", delay_factor=1): + def set_terminal_width( + self, command="", delay_factor=1, cmd_verify=False, pattern=None + ): """CLI terminals try to automatically adjust the line based on the width of the terminal. This causes the output to get distorted when accessed programmatically. @@ -1105,8 +1133,13 @@ Device settings: {self.device_type} {self.host}:{self.port} delay_factor = self.select_delay_factor(delay_factor) command = self.normalize_cmd(command) self.write_channel(command) - # Do not use command_verify here as still in session_preparation stage. - output = self.read_until_prompt() + # Avoid cmd_verify here as terminal width must be set before doing cmd_verify + if cmd_verify and self.global_cmd_verify is not False: + output = self.read_until_pattern(pattern=re.escape(command.strip())) + elif pattern: + output = self.read_until_pattern(pattern=pattern) + else: + output = self.read_until_prompt() return output def set_base_prompt( @@ -1151,11 +1184,10 @@ Device settings: {self.device_type} {self.host}:{self.port} time.sleep(sleep_time) # Initial attempt to get prompt - prompt = self.read_channel() + prompt = self.read_channel().strip() # Check if the only thing you received was a newline count = 0 - prompt = prompt.strip() while count <= 12 and not prompt: prompt = self.read_channel().strip() if not prompt: @@ -1787,7 +1819,7 @@ Device settings: {self.device_type} {self.host}:{self.port} cfg_mode_args = (config_mode_command,) if config_mode_command else tuple() output += self.config_mode(*cfg_mode_args) - if self.fast_cli: + if self.fast_cli and self._legacy_mode: for cmd in config_commands: self.write_channel(self.normalize_cmd(cmd)) # Gather output @@ -2169,6 +2201,7 @@ class TelnetConnection(BaseConnection): response_return=None, serial_settings=None, fast_cli=False, + _legacy_mode=True, session_log=None, session_log_record_writes=False, session_log_file_mode="write", @@ -2388,6 +2421,7 @@ class TelnetConnection(BaseConnection): self.serial_settings.update({"port": comm_port}) self.fast_cli = fast_cli + self._legacy_mode = _legacy_mode self.global_delay_factor = global_delay_factor self.global_cmd_verify = global_cmd_verify if self.fast_cli and self.global_delay_factor == 1: @@ -2881,8 +2915,8 @@ class TelnetConnection(BaseConnection): """ self._test_channel_read() self.set_base_prompt() - self.disable_paging() self.set_terminal_width() + self.disable_paging() # Clear the read buffer time.sleep(0.3 * self.global_delay_factor) @@ -3026,11 +3060,29 @@ Device settings: {self.device_type} {self.host}:{self.port} msg = msg.lstrip() raise NetmikoTimeoutException(msg) + except paramiko.ssh_exception.SSHException as no_session_err: + self.paramiko_cleanup() + if "No existing session" in str(no_session_err): + msg = ( + "Paramiko: 'No existing session' error: " + "try increasing 'conn_timeout' to 10 seconds or larger." + ) + raise NetmikoTimeoutException(msg) + else: + raise except paramiko.ssh_exception.AuthenticationException as auth_err: self.paramiko_cleanup() - msg = "Authentication failure: unable to connect {device_type} {ip}:{port}".format( - device_type=self.device_type, ip=self.host, port=self.port - ) + msg = f"""Authentication to device failed. + +Common causes of this problem are: +1. Invalid username and password +2. Incorrect SSH-key file +3. Connecting to the wrong device + +Device settings: {self.device_type} {self.host}:{self.port} + +""" + msg += self.RETURN + str(auth_err) raise NetmikoAuthenticationException(msg) @@ -3129,7 +3181,9 @@ Device settings: {self.device_type} {self.host}:{self.port} """Handler for devices like WLC, Extreme ERS that throw up characters prior to login.""" pass - def disable_paging(self, command="terminal length 0", delay_factor=1): + def disable_paging( + self, command="terminal length 0", delay_factor=1, cmd_verify=True, pattern=None + ): """Disable paging default to a Cisco CLI method. :param command: Device command to disable pagination of output @@ -3139,19 +3193,24 @@ Device settings: {self.device_type} {self.host}:{self.port} :type delay_factor: int """ 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(f"Command: {command}") self.write_channel(command) - # Do not use command_verify here as still in session_preparation stage. - output = self.read_until_prompt() + # Make sure you read until you detect the command echo (avoid getting out of sync) + if cmd_verify and self.global_cmd_verify is not False: + output = self.read_until_pattern(pattern=re.escape(command.strip())) + elif pattern: + output = self.read_until_pattern(pattern=pattern) + else: + output = self.read_until_prompt() log.debug(f"{output}") log.debug("Exiting disable_paging") return output - def set_terminal_width(self, command="", delay_factor=1): + def set_terminal_width( + self, command="", delay_factor=1, cmd_verify=False, pattern=None + ): """CLI terminals try to automatically adjust the line based on the width of the terminal. This causes the output to get distorted when accessed programmatically. @@ -3168,8 +3227,13 @@ Device settings: {self.device_type} {self.host}:{self.port} delay_factor = self.select_delay_factor(delay_factor) command = self.normalize_cmd(command) self.write_channel(command) - # Do not use command_verify here as still in session_preparation stage. - output = self.read_until_prompt() + # Avoid cmd_verify here as terminal width must be set before doing cmd_verify + if cmd_verify and self.global_cmd_verify is not False: + output = self.read_until_pattern(pattern=re.escape(command.strip())) + elif pattern: + output = self.read_until_pattern(pattern=pattern) + else: + output = self.read_until_prompt() return output def set_base_prompt( @@ -3214,11 +3278,10 @@ Device settings: {self.device_type} {self.host}:{self.port} time.sleep(sleep_time) # Initial attempt to get prompt - prompt = self.read_channel() + prompt = self.read_channel().strip() # Check if the only thing you received was a newline count = 0 - prompt = prompt.strip() while count <= 12 and not prompt: prompt = self.read_channel().strip() if not prompt: @@ -3850,7 +3913,7 @@ Device settings: {self.device_type} {self.host}:{self.port} cfg_mode_args = (config_mode_command,) if config_mode_command else tuple() output += self.config_mode(*cfg_mode_args) - if self.fast_cli: + if self.fast_cli and self._legacy_mode: for cmd in config_commands: self.write_channel(self.normalize_cmd(cmd)) # Gather output @@ -4226,7 +4289,7 @@ def strip_backspaces(output): </details> </dd> <dt id="netmiko.base_connection.BaseConnection.disable_paging"><code class="name flex"> -<span>def <span class="ident">disable_paging</span></span>(<span>self, command='terminal length 0', delay_factor=1)</span> +<span>def <span class="ident">disable_paging</span></span>(<span>self, command='terminal length 0', delay_factor=1, cmd_verify=True, pattern=None)</span> </code></dt> <dd> <section class="desc"><p>Disable paging default to a Cisco CLI method.</p> @@ -4236,7 +4299,9 @@ def strip_backspaces(output): :type delay_factor: int</p></section> <details class="source"> <summary>Source code</summary> -<pre><code class="python">def disable_paging(self, command="terminal length 0", delay_factor=1): +<pre><code class="python">def disable_paging( + self, command="terminal length 0", delay_factor=1, cmd_verify=True, pattern=None +): """Disable paging default to a Cisco CLI method. :param command: Device command to disable pagination of output @@ -4246,14 +4311,17 @@ def strip_backspaces(output): :type delay_factor: int """ 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(f"Command: {command}") self.write_channel(command) - # Do not use command_verify here as still in session_preparation stage. - output = self.read_until_prompt() + # Make sure you read until you detect the command echo (avoid getting out of sync) + if cmd_verify and self.global_cmd_verify is not False: + output = self.read_until_pattern(pattern=re.escape(command.strip())) + elif pattern: + output = self.read_until_pattern(pattern=pattern) + else: + output = self.read_until_prompt() log.debug(f"{output}") log.debug("Exiting disable_paging") return output</code></pre> @@ -4392,11 +4460,29 @@ Device settings: {self.device_type} {self.host}:{self.port} msg = msg.lstrip() raise NetmikoTimeoutException(msg) + except paramiko.ssh_exception.SSHException as no_session_err: + self.paramiko_cleanup() + if "No existing session" in str(no_session_err): + msg = ( + "Paramiko: 'No existing session' error: " + "try increasing 'conn_timeout' to 10 seconds or larger." + ) + raise NetmikoTimeoutException(msg) + else: + raise except paramiko.ssh_exception.AuthenticationException as auth_err: self.paramiko_cleanup() - msg = "Authentication failure: unable to connect {device_type} {ip}:{port}".format( - device_type=self.device_type, ip=self.host, port=self.port - ) + msg = f"""Authentication to device failed. + +Common causes of this problem are: +1. Invalid username and password +2. Incorrect SSH-key file +3. Connecting to the wrong device + +Device settings: {self.device_type} {self.host}:{self.port} + +""" + msg += self.RETURN + str(auth_err) raise NetmikoAuthenticationException(msg) @@ -4499,11 +4585,10 @@ Device settings: {self.device_type} {self.host}:{self.port} time.sleep(sleep_time) # Initial attempt to get prompt - prompt = self.read_channel() + prompt = self.read_channel().strip() # Check if the only thing you received was a newline count = 0 - prompt = prompt.strip() while count <= 12 and not prompt: prompt = self.read_channel().strip() if not prompt: @@ -5259,7 +5344,7 @@ The commands will be executed one after the other.</p> cfg_mode_args = (config_mode_command,) if config_mode_command else tuple() output += self.config_mode(*cfg_mode_args) - if self.fast_cli: + if self.fast_cli and self._legacy_mode: for cmd in config_commands: self.write_channel(self.normalize_cmd(cmd)) # Gather output @@ -5355,8 +5440,8 @@ self.clear_buffer()</p></section> """ self._test_channel_read() self.set_base_prompt() - self.disable_paging() self.set_terminal_width() + self.disable_paging() # Clear the read buffer time.sleep(0.3 * self.global_delay_factor) @@ -5412,7 +5497,7 @@ entering/exiting config mode.</p> </details> </dd> <dt id="netmiko.base_connection.BaseConnection.set_terminal_width"><code class="name flex"> -<span>def <span class="ident">set_terminal_width</span></span>(<span>self, command='', delay_factor=1)</span> +<span>def <span class="ident">set_terminal_width</span></span>(<span>self, command='', delay_factor=1, cmd_verify=False, pattern=None)</span> </code></dt> <dd> <section class="desc"><p>CLI terminals try to automatically adjust the line based on the width of the terminal. @@ -5424,7 +5509,9 @@ This causes the output to get distorted when accessed programmatically.</p> :type delay_factor: int</p></section> <details class="source"> <summary>Source code</summary> -<pre><code class="python">def set_terminal_width(self, command="", delay_factor=1): +<pre><code class="python">def set_terminal_width( + self, command="", delay_factor=1, cmd_verify=False, pattern=None +): """CLI terminals try to automatically adjust the line based on the width of the terminal. This causes the output to get distorted when accessed programmatically. @@ -5441,8 +5528,13 @@ This causes the output to get distorted when accessed programmatically.</p> delay_factor = self.select_delay_factor(delay_factor) command = self.normalize_cmd(command) self.write_channel(command) - # Do not use command_verify here as still in session_preparation stage. - output = self.read_until_prompt() + # Avoid cmd_verify here as terminal width must be set before doing cmd_verify + if cmd_verify and self.global_cmd_verify is not False: + output = self.read_until_pattern(pattern=re.escape(command.strip())) + elif pattern: + output = self.read_until_pattern(pattern=pattern) + else: + output = self.read_until_prompt() return output</code></pre> </details> </dd> diff --git a/docs/netmiko/broadcom/broadcom_icos_ssh.html b/docs/netmiko/broadcom/broadcom_icos_ssh.html index 83afc479252a71d87ad08929aa31764c8541ce4d..fb2306629c9f6959147a9ed27d7dc69953975064 100644 --- a/docs/netmiko/broadcom/broadcom_icos_ssh.html +++ b/docs/netmiko/broadcom/broadcom_icos_ssh.html @@ -37,8 +37,8 @@ class BroadcomIcosSSH(CiscoSSHConnection): self.set_base_prompt() self.enable() self.set_base_prompt() - self.disable_paging() self.set_terminal_width() + self.disable_paging() # Clear the read buffer time.sleep(0.3 * self.global_delay_factor) @@ -226,8 +226,8 @@ Syntax its almost identical to Cisco IOS in most cases</p> self.set_base_prompt() self.enable() self.set_base_prompt() - self.disable_paging() self.set_terminal_width() + self.disable_paging() # Clear the read buffer time.sleep(0.3 * self.global_delay_factor) diff --git a/docs/netmiko/broadcom/index.html b/docs/netmiko/broadcom/index.html index 4b7d45b64091be37544e9e17973116468586c2e7..0b92484e451ef6f0523ea84edea5aafe4e9584b6 100644 --- a/docs/netmiko/broadcom/index.html +++ b/docs/netmiko/broadcom/index.html @@ -194,8 +194,8 @@ Syntax its almost identical to Cisco IOS in most cases</p> self.set_base_prompt() self.enable() self.set_base_prompt() - self.disable_paging() self.set_terminal_width() + self.disable_paging() # Clear the read buffer time.sleep(0.3 * self.global_delay_factor) diff --git a/docs/netmiko/calix/calix_b6.html b/docs/netmiko/calix/calix_b6.html index a9d634f9dd94579e844b2c8a54cad66d8d5c3739..b7fd423cb7f8aca2c03ba3f54a3224c88200712f 100644 --- a/docs/netmiko/calix/calix_b6.html +++ b/docs/netmiko/calix/calix_b6.html @@ -53,8 +53,8 @@ class CalixB6Base(CiscoSSHConnection): self.ansi_escape_codes = True self._test_channel_read() self.set_base_prompt() + self.set_terminal_width(command="terminal width 511", pattern="terminal") self.disable_paging() - self.set_terminal_width(command="terminal width 511") # Clear the read buffer time.sleep(0.3 * self.global_delay_factor) self.clear_buffer() @@ -287,8 +287,8 @@ class CalixB6Telnet(CalixB6Base): self.ansi_escape_codes = True self._test_channel_read() self.set_base_prompt() + self.set_terminal_width(command="terminal width 511", pattern="terminal") self.disable_paging() - self.set_terminal_width(command="terminal width 511") # Clear the read buffer time.sleep(0.3 * self.global_delay_factor) self.clear_buffer() @@ -364,8 +364,8 @@ class CalixB6Telnet(CalixB6Base): self.ansi_escape_codes = True self._test_channel_read() self.set_base_prompt() + self.set_terminal_width(command="terminal width 511", pattern="terminal") self.disable_paging() - self.set_terminal_width(command="terminal width 511") # Clear the read buffer time.sleep(0.3 * self.global_delay_factor) self.clear_buffer()</code></pre> diff --git a/docs/netmiko/cisco/cisco_asa_ssh.html b/docs/netmiko/cisco/cisco_asa_ssh.html index 120c0887a422c125854459e7fd1f1e03c3873e60..acf297fa4dab6e95ed6085656038244d4808f431 100644 --- a/docs/netmiko/cisco/cisco_asa_ssh.html +++ b/docs/netmiko/cisco/cisco_asa_ssh.html @@ -37,11 +37,12 @@ class CiscoAsaSSH(CiscoSSHConnection): """Prepare the session after the connection has been established.""" self._test_channel_read() self.set_base_prompt() + if self.secret: self.enable() else: self.asa_login() - self.disable_paging(command="terminal pager 0") + if self.allow_auto_change: try: self.send_config_set("terminal width 511") @@ -52,6 +53,8 @@ class CiscoAsaSSH(CiscoSSHConnection): # Disable cmd_verify if the terminal width can't be set self.global_cmd_verify = False + self.disable_paging(command="terminal pager 0") + # Clear the read buffer time.sleep(0.3 * self.global_delay_factor) self.clear_buffer() @@ -352,11 +355,12 @@ class CiscoAsaFileTransfer(CiscoFileTransfer): """Prepare the session after the connection has been established.""" self._test_channel_read() self.set_base_prompt() + if self.secret: self.enable() else: self.asa_login() - self.disable_paging(command="terminal pager 0") + if self.allow_auto_change: try: self.send_config_set("terminal width 511") @@ -367,6 +371,8 @@ class CiscoAsaFileTransfer(CiscoFileTransfer): # Disable cmd_verify if the terminal width can't be set self.global_cmd_verify = False + self.disable_paging(command="terminal pager 0") + # Clear the read buffer time.sleep(0.3 * self.global_delay_factor) self.clear_buffer() @@ -605,11 +611,12 @@ updated after each context change.</p></section> """Prepare the session after the connection has been established.""" self._test_channel_read() self.set_base_prompt() + if self.secret: self.enable() else: self.asa_login() - self.disable_paging(command="terminal pager 0") + if self.allow_auto_change: try: self.send_config_set("terminal width 511") @@ -620,6 +627,8 @@ updated after each context change.</p></section> # Disable cmd_verify if the terminal width can't be set self.global_cmd_verify = False + self.disable_paging(command="terminal pager 0") + # Clear the read buffer time.sleep(0.3 * self.global_delay_factor) self.clear_buffer()</code></pre> diff --git a/docs/netmiko/cisco/cisco_ios.html b/docs/netmiko/cisco/cisco_ios.html index 0e230cd79e6af417a8169bde271d3fc149bfa9de..c576184546d751d9fe83c675f02190e7e23f708e 100644 --- a/docs/netmiko/cisco/cisco_ios.html +++ b/docs/netmiko/cisco/cisco_ios.html @@ -34,15 +34,18 @@ from netmiko.cisco_base_connection import CiscoBaseConnection, CiscoFileTransfer class CiscoIosBase(CiscoBaseConnection): """Common Methods for IOS (both SSH and telnet).""" + def __init__(self, *args, **kwargs): + # Cisco-IOS defaults to fast_cli=True and legacy_mode=False + kwargs.setdefault("fast_cli", True) + kwargs.setdefault("_legacy_mode", False) + return super().__init__(*args, **kwargs) + def session_preparation(self): """Prepare the session after the connection has been established.""" - self._test_channel_read(pattern=r"[>#]") - self.set_base_prompt() + cmd = "terminal width 511" + self.set_terminal_width(command=cmd, pattern=cmd) self.disable_paging() - self.set_terminal_width(command="terminal width 511") - # Clear the read buffer - time.sleep(0.3 * self.global_delay_factor) - self.clear_buffer() + self.set_base_prompt() def check_config_mode(self, check_string=")#", pattern="#"): """ @@ -278,7 +281,7 @@ class InLineTransfer(CiscoIosFileTransfer): <dl> <dt id="netmiko.cisco.cisco_ios.CiscoIosBase"><code class="flex name class"> <span>class <span class="ident">CiscoIosBase</span></span> -<span>(</span><span>ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=5, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=False, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True)</span> +<span>(</span><span>*args, **kwargs)</span> </code></dt> <dd> <section class="desc"><p>Common Methods for IOS (both SSH and telnet).</p> @@ -417,15 +420,18 @@ class InLineTransfer(CiscoIosFileTransfer): <pre><code class="python">class CiscoIosBase(CiscoBaseConnection): """Common Methods for IOS (both SSH and telnet).""" + def __init__(self, *args, **kwargs): + # Cisco-IOS defaults to fast_cli=True and legacy_mode=False + kwargs.setdefault("fast_cli", True) + kwargs.setdefault("_legacy_mode", False) + return super().__init__(*args, **kwargs) + def session_preparation(self): """Prepare the session after the connection has been established.""" - self._test_channel_read(pattern=r"[>#]") - self.set_base_prompt() + cmd = "terminal width 511" + self.set_terminal_width(command=cmd, pattern=cmd) self.disable_paging() - self.set_terminal_width(command="terminal width 511") - # Clear the read buffer - time.sleep(0.3 * self.global_delay_factor) - self.clear_buffer() + self.set_base_prompt() def check_config_mode(self, check_string=")#", pattern="#"): """ @@ -479,13 +485,10 @@ class InLineTransfer(CiscoIosFileTransfer): <summary>Source code</summary> <pre><code class="python">def session_preparation(self): """Prepare the session after the connection has been established.""" - self._test_channel_read(pattern=r"[>#]") - self.set_base_prompt() + cmd = "terminal width 511" + self.set_terminal_width(command=cmd, pattern=cmd) self.disable_paging() - self.set_terminal_width(command="terminal width 511") - # Clear the read buffer - time.sleep(0.3 * self.global_delay_factor) - self.clear_buffer()</code></pre> + self.set_base_prompt()</code></pre> </details> </dd> </dl> @@ -584,7 +587,7 @@ class InLineTransfer(CiscoIosFileTransfer): </dd> <dt id="netmiko.cisco.cisco_ios.CiscoIosSSH"><code class="flex name class"> <span>class <span class="ident">CiscoIosSSH</span></span> -<span>(</span><span>ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=5, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=False, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True)</span> +<span>(</span><span>*args, **kwargs)</span> </code></dt> <dd> <section class="desc"><p>Cisco IOS SSH driver.</p> @@ -781,7 +784,7 @@ class InLineTransfer(CiscoIosFileTransfer): </dd> <dt id="netmiko.cisco.cisco_ios.CiscoIosSerial"><code class="flex name class"> <span>class <span class="ident">CiscoIosSerial</span></span> -<span>(</span><span>ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=5, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=False, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True)</span> +<span>(</span><span>*args, **kwargs)</span> </code></dt> <dd> <section class="desc"><p>Cisco IOS Serial driver.</p> @@ -978,7 +981,7 @@ class InLineTransfer(CiscoIosFileTransfer): </dd> <dt id="netmiko.cisco.cisco_ios.CiscoIosTelnet"><code class="flex name class"> <span>class <span class="ident">CiscoIosTelnet</span></span> -<span>(</span><span>ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=5, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=False, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True)</span> +<span>(</span><span>*args, **kwargs)</span> </code></dt> <dd> <section class="desc"><p>Cisco IOS Telnet driver.</p> diff --git a/docs/netmiko/cisco/cisco_nxos_ssh.html b/docs/netmiko/cisco/cisco_nxos_ssh.html index 3c56e2cc3daa5efb6a18e378560ed7b3352d2ae3..64c718dbe01d0a487d880259a7485b64229644f6 100644 --- a/docs/netmiko/cisco/cisco_nxos_ssh.html +++ b/docs/netmiko/cisco/cisco_nxos_ssh.html @@ -35,8 +35,8 @@ class CiscoNxosSSH(CiscoSSHConnection): self._test_channel_read(pattern=r"[>#]") self.ansi_escape_codes = True self.set_base_prompt() + self.set_terminal_width(command="terminal width 511", pattern="terminal") self.disable_paging() - self.set_terminal_width(command="terminal width 511") # Clear the read buffer time.sleep(0.3 * self.global_delay_factor) self.clear_buffer() @@ -455,8 +455,8 @@ def process_md5(md5_output, pattern=r"= (.*)"): self._test_channel_read(pattern=r"[>#]") self.ansi_escape_codes = True self.set_base_prompt() + self.set_terminal_width(command="terminal width 511", pattern="terminal") self.disable_paging() - self.set_terminal_width(command="terminal width 511") # Clear the read buffer time.sleep(0.3 * self.global_delay_factor) self.clear_buffer() @@ -521,8 +521,8 @@ def process_md5(md5_output, pattern=r"= (.*)"): self._test_channel_read(pattern=r"[>#]") self.ansi_escape_codes = True self.set_base_prompt() + self.set_terminal_width(command="terminal width 511", pattern="terminal") self.disable_paging() - self.set_terminal_width(command="terminal width 511") # Clear the read buffer time.sleep(0.3 * self.global_delay_factor) self.clear_buffer()</code></pre> diff --git a/docs/netmiko/cisco/cisco_s300.html b/docs/netmiko/cisco/cisco_s300.html index 3be820ce71f77dd7bbae83f93815992a4a57677b..4a23e2092fc9c5888cf2f7732e6c2de351c0a00a 100644 --- a/docs/netmiko/cisco/cisco_s300.html +++ b/docs/netmiko/cisco/cisco_s300.html @@ -41,8 +41,8 @@ class CiscoS300SSH(CiscoSSHConnection): self.ansi_escape_codes = True self._test_channel_read() self.set_base_prompt() + self.set_terminal_width(command="terminal width 511", pattern="terminal") self.disable_paging(command="terminal datadump") - self.set_terminal_width(command="terminal width 511") # Clear the read buffer time.sleep(0.3 * self.global_delay_factor) @@ -217,8 +217,8 @@ ip ssh password-auth</p> self.ansi_escape_codes = True self._test_channel_read() self.set_base_prompt() + self.set_terminal_width(command="terminal width 511", pattern="terminal") self.disable_paging(command="terminal datadump") - self.set_terminal_width(command="terminal width 511") # Clear the read buffer time.sleep(0.3 * self.global_delay_factor) @@ -247,8 +247,8 @@ ip ssh password-auth</p> self.ansi_escape_codes = True self._test_channel_read() self.set_base_prompt() + self.set_terminal_width(command="terminal width 511", pattern="terminal") self.disable_paging(command="terminal datadump") - self.set_terminal_width(command="terminal width 511") # Clear the read buffer time.sleep(0.3 * self.global_delay_factor)</code></pre> </details> diff --git a/docs/netmiko/cisco/cisco_tp_tcce.html b/docs/netmiko/cisco/cisco_tp_tcce.html index fe3c6e5946c8b1eb584ff770dc6e659152e39fcb..f51acba62215c2ada93f74922154786c4c1716d4 100644 --- a/docs/netmiko/cisco/cisco_tp_tcce.html +++ b/docs/netmiko/cisco/cisco_tp_tcce.html @@ -64,8 +64,8 @@ class CiscoTpTcCeSSH(CiscoSSHConnection): """ self._test_channel_read() self.set_base_prompt() - self.disable_paging() self.set_terminal_width() + self.disable_paging() # Clear the read buffer time.sleep(0.3 * self.global_delay_factor) self.clear_buffer() @@ -284,8 +284,8 @@ class CiscoTpTcCeSSH(CiscoSSHConnection): """ self._test_channel_read() self.set_base_prompt() - self.disable_paging() self.set_terminal_width() + self.disable_paging() # Clear the read buffer time.sleep(0.3 * self.global_delay_factor) self.clear_buffer() @@ -432,8 +432,8 @@ self.set_terminal_width()</p></section> """ self._test_channel_read() self.set_base_prompt() - self.disable_paging() self.set_terminal_width() + self.disable_paging() # Clear the read buffer time.sleep(0.3 * self.global_delay_factor) self.clear_buffer()</code></pre> diff --git a/docs/netmiko/cisco/cisco_wlc_ssh.html b/docs/netmiko/cisco/cisco_wlc_ssh.html index e04195533a216871942623123d0f9b5888588bc1..ddc6c5a4ccbb0316222e872b9db3fde4a6a24736 100644 --- a/docs/netmiko/cisco/cisco_wlc_ssh.html +++ b/docs/netmiko/cisco/cisco_wlc_ssh.html @@ -35,6 +35,12 @@ from netmiko.base_connection import BaseConnection class CiscoWlcSSH(BaseConnection): """Netmiko Cisco WLC support.""" + def __init__(self, *args, **kwargs): + # WLC/AireOS has an issue where you can get "No Existing Session" with + # the default conn_timeout (so increase conn_timeout to 10-seconds). + kwargs.setdefault("conn_timeout", 10) + return super().__init__(*args, **kwargs) + def special_login_handler(self, delay_factor=1): """WLC presents with the following on login (in certain OS versions) @@ -230,7 +236,7 @@ class CiscoWlcSSH(BaseConnection): <dl> <dt id="netmiko.cisco.cisco_wlc_ssh.CiscoWlcSSH"><code class="flex name class"> <span>class <span class="ident">CiscoWlcSSH</span></span> -<span>(</span><span>ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=5, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=False, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True)</span> +<span>(</span><span>*args, **kwargs)</span> </code></dt> <dd> <section class="desc"><p>Netmiko Cisco WLC support.</p> @@ -369,6 +375,12 @@ class CiscoWlcSSH(BaseConnection): <pre><code class="python">class CiscoWlcSSH(BaseConnection): """Netmiko Cisco WLC support.""" + def __init__(self, *args, **kwargs): + # WLC/AireOS has an issue where you can get "No Existing Session" with + # the default conn_timeout (so increase conn_timeout to 10-seconds). + kwargs.setdefault("conn_timeout", 10) + return super().__init__(*args, **kwargs) + def special_login_handler(self, delay_factor=1): """WLC presents with the following on login (in certain OS versions) diff --git a/docs/netmiko/cisco/cisco_xr.html b/docs/netmiko/cisco/cisco_xr.html index e01820c261e386c863b03e504c647f1fe57ef164..1c35a8e30439d91a7ca09872e1c553b34e91b9da 100644 --- a/docs/netmiko/cisco/cisco_xr.html +++ b/docs/netmiko/cisco/cisco_xr.html @@ -28,12 +28,16 @@ from netmiko.cisco_base_connection import CiscoBaseConnection, CiscoFileTransfer class CiscoXrBase(CiscoBaseConnection): + def establish_connection(self): + """Establish SSH connection to the network device""" + super().establish_connection(width=511, height=511) + def session_preparation(self): """Prepare the session after the connection has been established.""" self._test_channel_read() self.set_base_prompt() + self.set_terminal_width(command="terminal width 511", pattern="terminal") self.disable_paging() - self.set_terminal_width(command="terminal width 511") # Clear the read buffer time.sleep(0.3 * self.global_delay_factor) self.clear_buffer() @@ -88,12 +92,6 @@ class CiscoXrBase(CiscoBaseConnection): if comment and confirm: raise ValueError("Invalid arguments supplied to XR commit") - # wrap the comment in quotes - if comment: - if '"' in comment: - raise ValueError("Invalid comment contains double quote") - comment = f'"{comment}"' - label = str(label) error_marker = "Failed to" alt_error_marker = "One or more commits have occurred from other" @@ -368,12 +366,16 @@ class CiscoXrFileTransfer(CiscoFileTransfer): <details class="source"> <summary>Source code</summary> <pre><code class="python">class CiscoXrBase(CiscoBaseConnection): + def establish_connection(self): + """Establish SSH connection to the network device""" + super().establish_connection(width=511, height=511) + def session_preparation(self): """Prepare the session after the connection has been established.""" self._test_channel_read() self.set_base_prompt() + self.set_terminal_width(command="terminal width 511", pattern="terminal") self.disable_paging() - self.set_terminal_width(command="terminal width 511") # Clear the read buffer time.sleep(0.3 * self.global_delay_factor) self.clear_buffer() @@ -428,12 +430,6 @@ class CiscoXrFileTransfer(CiscoFileTransfer): if comment and confirm: raise ValueError("Invalid arguments supplied to XR commit") - # wrap the comment in quotes - if comment: - if '"' in comment: - raise ValueError("Invalid comment contains double quote") - comment = f'"{comment}"' - label = str(label) error_marker = "Failed to" alt_error_marker = "One or more commits have occurred from other" @@ -616,12 +612,6 @@ an exception to be generated.</p></section> if comment and confirm: raise ValueError("Invalid arguments supplied to XR commit") - # wrap the comment in quotes - if comment: - if '"' in comment: - raise ValueError("Invalid comment contains double quote") - comment = f'"{comment}"' - label = str(label) error_marker = "Failed to" alt_error_marker = "One or more commits have occurred from other" @@ -663,6 +653,18 @@ an exception to be generated.</p></section> return output</code></pre> </details> </dd> +<dt id="netmiko.cisco.cisco_xr.CiscoXrBase.establish_connection"><code class="name flex"> +<span>def <span class="ident">establish_connection</span></span>(<span>self)</span> +</code></dt> +<dd> +<section class="desc"><p>Establish SSH connection to the network device</p></section> +<details class="source"> +<summary>Source code</summary> +<pre><code class="python">def establish_connection(self): + """Establish SSH connection to the network device""" + super().establish_connection(width=511, height=511)</code></pre> +</details> +</dd> <dt id="netmiko.cisco.cisco_xr.CiscoXrBase.exit_config_mode"><code class="name flex"> <span>def <span class="ident">exit_config_mode</span></span>(<span>self, exit_config='end')</span> </code></dt> @@ -723,8 +725,8 @@ an exception to be generated.</p></section> """Prepare the session after the connection has been established.""" self._test_channel_read() self.set_base_prompt() + self.set_terminal_width(command="terminal width 511", pattern="terminal") self.disable_paging() - self.set_terminal_width(command="terminal width 511") # Clear the read buffer time.sleep(0.3 * self.global_delay_factor) self.clear_buffer()</code></pre> @@ -743,7 +745,6 @@ an exception to be generated.</p></section> <li><code><a title="netmiko.cisco_base_connection.CiscoBaseConnection.disable_paging" href="../base_connection.html#netmiko.base_connection.BaseConnection.disable_paging">disable_paging</a></code></li> <li><code><a title="netmiko.cisco_base_connection.CiscoBaseConnection.disconnect" href="../base_connection.html#netmiko.base_connection.BaseConnection.disconnect">disconnect</a></code></li> <li><code><a title="netmiko.cisco_base_connection.CiscoBaseConnection.enable" href="../cisco_base_connection.html#netmiko.cisco_base_connection.CiscoBaseConnection.enable">enable</a></code></li> -<li><code><a title="netmiko.cisco_base_connection.CiscoBaseConnection.establish_connection" href="../base_connection.html#netmiko.base_connection.BaseConnection.establish_connection">establish_connection</a></code></li> <li><code><a title="netmiko.cisco_base_connection.CiscoBaseConnection.exit_enable_mode" href="../cisco_base_connection.html#netmiko.cisco_base_connection.CiscoBaseConnection.exit_enable_mode">exit_enable_mode</a></code></li> <li><code><a title="netmiko.cisco_base_connection.CiscoBaseConnection.find_prompt" href="../base_connection.html#netmiko.base_connection.BaseConnection.find_prompt">find_prompt</a></code></li> <li><code><a title="netmiko.cisco_base_connection.CiscoBaseConnection.is_alive" href="../base_connection.html#netmiko.base_connection.BaseConnection.is_alive">is_alive</a></code></li> @@ -1067,7 +1068,7 @@ c84843f0030efd44b01343fdb8c2e801</p></section> <li><code><a title="netmiko.cisco.cisco_xr.CiscoXrBase.disable_paging" href="../base_connection.html#netmiko.base_connection.BaseConnection.disable_paging">disable_paging</a></code></li> <li><code><a title="netmiko.cisco.cisco_xr.CiscoXrBase.disconnect" href="../base_connection.html#netmiko.base_connection.BaseConnection.disconnect">disconnect</a></code></li> <li><code><a title="netmiko.cisco.cisco_xr.CiscoXrBase.enable" href="../cisco_base_connection.html#netmiko.cisco_base_connection.CiscoBaseConnection.enable">enable</a></code></li> -<li><code><a title="netmiko.cisco.cisco_xr.CiscoXrBase.establish_connection" href="../base_connection.html#netmiko.base_connection.BaseConnection.establish_connection">establish_connection</a></code></li> +<li><code><a title="netmiko.cisco.cisco_xr.CiscoXrBase.establish_connection" href="#netmiko.cisco.cisco_xr.CiscoXrBase.establish_connection">establish_connection</a></code></li> <li><code><a title="netmiko.cisco.cisco_xr.CiscoXrBase.exit_config_mode" href="#netmiko.cisco.cisco_xr.CiscoXrBase.exit_config_mode">exit_config_mode</a></code></li> <li><code><a title="netmiko.cisco.cisco_xr.CiscoXrBase.exit_enable_mode" href="../cisco_base_connection.html#netmiko.cisco_base_connection.CiscoBaseConnection.exit_enable_mode">exit_enable_mode</a></code></li> <li><code><a title="netmiko.cisco.cisco_xr.CiscoXrBase.find_prompt" href="../base_connection.html#netmiko.base_connection.BaseConnection.find_prompt">find_prompt</a></code></li> @@ -1264,7 +1265,7 @@ c84843f0030efd44b01343fdb8c2e801</p></section> <li><code><a title="netmiko.cisco.cisco_xr.CiscoXrBase.disable_paging" href="../base_connection.html#netmiko.base_connection.BaseConnection.disable_paging">disable_paging</a></code></li> <li><code><a title="netmiko.cisco.cisco_xr.CiscoXrBase.disconnect" href="../base_connection.html#netmiko.base_connection.BaseConnection.disconnect">disconnect</a></code></li> <li><code><a title="netmiko.cisco.cisco_xr.CiscoXrBase.enable" href="../cisco_base_connection.html#netmiko.cisco_base_connection.CiscoBaseConnection.enable">enable</a></code></li> -<li><code><a title="netmiko.cisco.cisco_xr.CiscoXrBase.establish_connection" href="../base_connection.html#netmiko.base_connection.BaseConnection.establish_connection">establish_connection</a></code></li> +<li><code><a title="netmiko.cisco.cisco_xr.CiscoXrBase.establish_connection" href="#netmiko.cisco.cisco_xr.CiscoXrBase.establish_connection">establish_connection</a></code></li> <li><code><a title="netmiko.cisco.cisco_xr.CiscoXrBase.exit_config_mode" href="#netmiko.cisco.cisco_xr.CiscoXrBase.exit_config_mode">exit_config_mode</a></code></li> <li><code><a title="netmiko.cisco.cisco_xr.CiscoXrBase.exit_enable_mode" href="../cisco_base_connection.html#netmiko.cisco_base_connection.CiscoBaseConnection.exit_enable_mode">exit_enable_mode</a></code></li> <li><code><a title="netmiko.cisco.cisco_xr.CiscoXrBase.find_prompt" href="../base_connection.html#netmiko.base_connection.BaseConnection.find_prompt">find_prompt</a></code></li> @@ -1316,9 +1317,10 @@ c84843f0030efd44b01343fdb8c2e801</p></section> <ul> <li> <h4><code><a title="netmiko.cisco.cisco_xr.CiscoXrBase" href="#netmiko.cisco.cisco_xr.CiscoXrBase">CiscoXrBase</a></code></h4> -<ul class="two-column"> +<ul class=""> <li><code><a title="netmiko.cisco.cisco_xr.CiscoXrBase.check_config_mode" href="#netmiko.cisco.cisco_xr.CiscoXrBase.check_config_mode">check_config_mode</a></code></li> <li><code><a title="netmiko.cisco.cisco_xr.CiscoXrBase.commit" href="#netmiko.cisco.cisco_xr.CiscoXrBase.commit">commit</a></code></li> +<li><code><a title="netmiko.cisco.cisco_xr.CiscoXrBase.establish_connection" href="#netmiko.cisco.cisco_xr.CiscoXrBase.establish_connection">establish_connection</a></code></li> <li><code><a title="netmiko.cisco.cisco_xr.CiscoXrBase.exit_config_mode" href="#netmiko.cisco.cisco_xr.CiscoXrBase.exit_config_mode">exit_config_mode</a></code></li> <li><code><a title="netmiko.cisco.cisco_xr.CiscoXrBase.save_config" href="#netmiko.cisco.cisco_xr.CiscoXrBase.save_config">save_config</a></code></li> <li><code><a title="netmiko.cisco.cisco_xr.CiscoXrBase.send_config_set" href="#netmiko.cisco.cisco_xr.CiscoXrBase.send_config_set">send_config_set</a></code></li> diff --git a/docs/netmiko/cisco/index.html b/docs/netmiko/cisco/index.html index 190a86897c806df7ada4cc18c40d8d177b8db96d..8f748537dacf6827c080afff7d41e3d408ec40e0 100644 --- a/docs/netmiko/cisco/index.html +++ b/docs/netmiko/cisco/index.html @@ -287,11 +287,12 @@ Expressway/VCS …</p></section> """Prepare the session after the connection has been established.""" self._test_channel_read() self.set_base_prompt() + if self.secret: self.enable() else: self.asa_login() - self.disable_paging(command="terminal pager 0") + if self.allow_auto_change: try: self.send_config_set("terminal width 511") @@ -302,6 +303,8 @@ Expressway/VCS …</p></section> # Disable cmd_verify if the terminal width can't be set self.global_cmd_verify = False + self.disable_paging(command="terminal pager 0") + # Clear the read buffer time.sleep(0.3 * self.global_delay_factor) self.clear_buffer() @@ -540,11 +543,12 @@ updated after each context change.</p></section> """Prepare the session after the connection has been established.""" self._test_channel_read() self.set_base_prompt() + if self.secret: self.enable() else: self.asa_login() - self.disable_paging(command="terminal pager 0") + if self.allow_auto_change: try: self.send_config_set("terminal width 511") @@ -555,6 +559,8 @@ updated after each context change.</p></section> # Disable cmd_verify if the terminal width can't be set self.global_cmd_verify = False + self.disable_paging(command="terminal pager 0") + # Clear the read buffer time.sleep(0.3 * self.global_delay_factor) self.clear_buffer()</code></pre> @@ -631,7 +637,7 @@ happens the trailing '(config*' needs stripped off.</p></section> </dd> <dt id="netmiko.cisco.CiscoIosBase"><code class="flex name class"> <span>class <span class="ident">CiscoIosBase</span></span> -<span>(</span><span>ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=5, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=False, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True)</span> +<span>(</span><span>*args, **kwargs)</span> </code></dt> <dd> <section class="desc"><p>Common Methods for IOS (both SSH and telnet).</p> @@ -770,15 +776,18 @@ happens the trailing '(config*' needs stripped off.</p></section> <pre><code class="python">class CiscoIosBase(CiscoBaseConnection): """Common Methods for IOS (both SSH and telnet).""" + def __init__(self, *args, **kwargs): + # Cisco-IOS defaults to fast_cli=True and legacy_mode=False + kwargs.setdefault("fast_cli", True) + kwargs.setdefault("_legacy_mode", False) + return super().__init__(*args, **kwargs) + def session_preparation(self): """Prepare the session after the connection has been established.""" - self._test_channel_read(pattern=r"[>#]") - self.set_base_prompt() + cmd = "terminal width 511" + self.set_terminal_width(command=cmd, pattern=cmd) self.disable_paging() - self.set_terminal_width(command="terminal width 511") - # Clear the read buffer - time.sleep(0.3 * self.global_delay_factor) - self.clear_buffer() + self.set_base_prompt() def check_config_mode(self, check_string=")#", pattern="#"): """ @@ -832,13 +841,10 @@ happens the trailing '(config*' needs stripped off.</p></section> <summary>Source code</summary> <pre><code class="python">def session_preparation(self): """Prepare the session after the connection has been established.""" - self._test_channel_read(pattern=r"[>#]") - self.set_base_prompt() + cmd = "terminal width 511" + self.set_terminal_width(command=cmd, pattern=cmd) self.disable_paging() - self.set_terminal_width(command="terminal width 511") - # Clear the read buffer - time.sleep(0.3 * self.global_delay_factor) - self.clear_buffer()</code></pre> + self.set_base_prompt()</code></pre> </details> </dd> </dl> @@ -937,7 +943,7 @@ happens the trailing '(config*' needs stripped off.</p></section> </dd> <dt id="netmiko.cisco.CiscoIosSSH"><code class="flex name class"> <span>class <span class="ident">CiscoIosSSH</span></span> -<span>(</span><span>ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=5, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=False, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True)</span> +<span>(</span><span>*args, **kwargs)</span> </code></dt> <dd> <section class="desc"><p>Cisco IOS SSH driver.</p> @@ -1134,7 +1140,7 @@ happens the trailing '(config*' needs stripped off.</p></section> </dd> <dt id="netmiko.cisco.CiscoIosSerial"><code class="flex name class"> <span>class <span class="ident">CiscoIosSerial</span></span> -<span>(</span><span>ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=5, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=False, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True)</span> +<span>(</span><span>*args, **kwargs)</span> </code></dt> <dd> <section class="desc"><p>Cisco IOS Serial driver.</p> @@ -1331,7 +1337,7 @@ happens the trailing '(config*' needs stripped off.</p></section> </dd> <dt id="netmiko.cisco.CiscoIosTelnet"><code class="flex name class"> <span>class <span class="ident">CiscoIosTelnet</span></span> -<span>(</span><span>ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=5, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=False, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True)</span> +<span>(</span><span>*args, **kwargs)</span> </code></dt> <dd> <section class="desc"><p>Cisco IOS Telnet driver.</p> @@ -1821,8 +1827,8 @@ def process_md5(md5_output, pattern=r"= (.*)"): self._test_channel_read(pattern=r"[>#]") self.ansi_escape_codes = True self.set_base_prompt() + self.set_terminal_width(command="terminal width 511", pattern="terminal") self.disable_paging() - self.set_terminal_width(command="terminal width 511") # Clear the read buffer time.sleep(0.3 * self.global_delay_factor) self.clear_buffer() @@ -1887,8 +1893,8 @@ def process_md5(md5_output, pattern=r"= (.*)"): self._test_channel_read(pattern=r"[>#]") self.ansi_escape_codes = True self.set_base_prompt() + self.set_terminal_width(command="terminal width 511", pattern="terminal") self.disable_paging() - self.set_terminal_width(command="terminal width 511") # Clear the read buffer time.sleep(0.3 * self.global_delay_factor) self.clear_buffer()</code></pre> @@ -2096,8 +2102,8 @@ ip ssh password-auth</p> self.ansi_escape_codes = True self._test_channel_read() self.set_base_prompt() + self.set_terminal_width(command="terminal width 511", pattern="terminal") self.disable_paging(command="terminal datadump") - self.set_terminal_width(command="terminal width 511") # Clear the read buffer time.sleep(0.3 * self.global_delay_factor) @@ -2126,8 +2132,8 @@ ip ssh password-auth</p> self.ansi_escape_codes = True self._test_channel_read() self.set_base_prompt() + self.set_terminal_width(command="terminal width 511", pattern="terminal") self.disable_paging(command="terminal datadump") - self.set_terminal_width(command="terminal width 511") # Clear the read buffer time.sleep(0.3 * self.global_delay_factor)</code></pre> </details> @@ -2342,8 +2348,8 @@ ip ssh password-auth</p> """ self._test_channel_read() self.set_base_prompt() - self.disable_paging() self.set_terminal_width() + self.disable_paging() # Clear the read buffer time.sleep(0.3 * self.global_delay_factor) self.clear_buffer() @@ -2490,8 +2496,8 @@ self.set_terminal_width()</p></section> """ self._test_channel_read() self.set_base_prompt() - self.disable_paging() self.set_terminal_width() + self.disable_paging() # Clear the read buffer time.sleep(0.3 * self.global_delay_factor) self.clear_buffer()</code></pre> @@ -2572,7 +2578,7 @@ self.set_terminal_width()</p></section> </dd> <dt id="netmiko.cisco.CiscoWlcSSH"><code class="flex name class"> <span>class <span class="ident">CiscoWlcSSH</span></span> -<span>(</span><span>ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=5, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=False, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True)</span> +<span>(</span><span>*args, **kwargs)</span> </code></dt> <dd> <section class="desc"><p>Netmiko Cisco WLC support.</p> @@ -2711,6 +2717,12 @@ self.set_terminal_width()</p></section> <pre><code class="python">class CiscoWlcSSH(BaseConnection): """Netmiko Cisco WLC support.""" + def __init__(self, *args, **kwargs): + # WLC/AireOS has an issue where you can get "No Existing Session" with + # the default conn_timeout (so increase conn_timeout to 10-seconds). + kwargs.setdefault("conn_timeout", 10) + return super().__init__(*args, **kwargs) + def special_login_handler(self, delay_factor=1): """WLC presents with the following on login (in certain OS versions) @@ -3478,7 +3490,7 @@ c84843f0030efd44b01343fdb8c2e801</p></section> <li><code><a title="netmiko.cisco.cisco_xr.CiscoXrBase.disable_paging" href="../base_connection.html#netmiko.base_connection.BaseConnection.disable_paging">disable_paging</a></code></li> <li><code><a title="netmiko.cisco.cisco_xr.CiscoXrBase.disconnect" href="../base_connection.html#netmiko.base_connection.BaseConnection.disconnect">disconnect</a></code></li> <li><code><a title="netmiko.cisco.cisco_xr.CiscoXrBase.enable" href="../cisco_base_connection.html#netmiko.cisco_base_connection.CiscoBaseConnection.enable">enable</a></code></li> -<li><code><a title="netmiko.cisco.cisco_xr.CiscoXrBase.establish_connection" href="../base_connection.html#netmiko.base_connection.BaseConnection.establish_connection">establish_connection</a></code></li> +<li><code><a title="netmiko.cisco.cisco_xr.CiscoXrBase.establish_connection" href="cisco_xr.html#netmiko.cisco.cisco_xr.CiscoXrBase.establish_connection">establish_connection</a></code></li> <li><code><a title="netmiko.cisco.cisco_xr.CiscoXrBase.exit_config_mode" href="cisco_xr.html#netmiko.cisco.cisco_xr.CiscoXrBase.exit_config_mode">exit_config_mode</a></code></li> <li><code><a title="netmiko.cisco.cisco_xr.CiscoXrBase.exit_enable_mode" href="../cisco_base_connection.html#netmiko.cisco_base_connection.CiscoBaseConnection.exit_enable_mode">exit_enable_mode</a></code></li> <li><code><a title="netmiko.cisco.cisco_xr.CiscoXrBase.find_prompt" href="../base_connection.html#netmiko.base_connection.BaseConnection.find_prompt">find_prompt</a></code></li> @@ -3675,7 +3687,7 @@ c84843f0030efd44b01343fdb8c2e801</p></section> <li><code><a title="netmiko.cisco.cisco_xr.CiscoXrBase.disable_paging" href="../base_connection.html#netmiko.base_connection.BaseConnection.disable_paging">disable_paging</a></code></li> <li><code><a title="netmiko.cisco.cisco_xr.CiscoXrBase.disconnect" href="../base_connection.html#netmiko.base_connection.BaseConnection.disconnect">disconnect</a></code></li> <li><code><a title="netmiko.cisco.cisco_xr.CiscoXrBase.enable" href="../cisco_base_connection.html#netmiko.cisco_base_connection.CiscoBaseConnection.enable">enable</a></code></li> -<li><code><a title="netmiko.cisco.cisco_xr.CiscoXrBase.establish_connection" href="../base_connection.html#netmiko.base_connection.BaseConnection.establish_connection">establish_connection</a></code></li> +<li><code><a title="netmiko.cisco.cisco_xr.CiscoXrBase.establish_connection" href="cisco_xr.html#netmiko.cisco.cisco_xr.CiscoXrBase.establish_connection">establish_connection</a></code></li> <li><code><a title="netmiko.cisco.cisco_xr.CiscoXrBase.exit_config_mode" href="cisco_xr.html#netmiko.cisco.cisco_xr.CiscoXrBase.exit_config_mode">exit_config_mode</a></code></li> <li><code><a title="netmiko.cisco.cisco_xr.CiscoXrBase.exit_enable_mode" href="../cisco_base_connection.html#netmiko.cisco_base_connection.CiscoBaseConnection.exit_enable_mode">exit_enable_mode</a></code></li> <li><code><a title="netmiko.cisco.cisco_xr.CiscoXrBase.find_prompt" href="../base_connection.html#netmiko.base_connection.BaseConnection.find_prompt">find_prompt</a></code></li> diff --git a/docs/netmiko/cisco_base_connection.html b/docs/netmiko/cisco_base_connection.html index 4ac9ce6cd1645c625a69ee51e6945be7e51ffe1f..610fb453665fac4ede023998863a61c207e4c218 100644 --- a/docs/netmiko/cisco_base_connection.html +++ b/docs/netmiko/cisco_base_connection.html @@ -646,6 +646,7 @@ class CiscoFileTransfer(BaseFileTransfer): <h3>Subclasses</h3> <ul class="hlist"> <li><a title="netmiko.cisco_base_connection.CiscoSSHConnection" href="#netmiko.cisco_base_connection.CiscoSSHConnection">CiscoSSHConnection</a></li> +<li><a title="netmiko.adtran.adtran.AdtranOSBase" href="adtran/adtran.html#netmiko.adtran.adtran.AdtranOSBase">AdtranOSBase</a></li> <li><a title="netmiko.centec.centec_os.CentecOSBase" href="centec/centec_os.html#netmiko.centec.centec_os.CentecOSBase">CentecOSBase</a></li> <li><a title="netmiko.cisco.cisco_ios.CiscoIosBase" href="cisco/cisco_ios.html#netmiko.cisco.cisco_ios.CiscoIosBase">CiscoIosBase</a></li> <li><a title="netmiko.cisco.cisco_xr.CiscoXrBase" href="cisco/cisco_xr.html#netmiko.cisco.cisco_xr.CiscoXrBase">CiscoXrBase</a></li> @@ -1215,6 +1216,7 @@ class CiscoFileTransfer(BaseFileTransfer): <li><a title="netmiko.mellanox.mellanox_mlnxos_ssh.MellanoxMlnxosSSH" href="mellanox/mellanox_mlnxos_ssh.html#netmiko.mellanox.mellanox_mlnxos_ssh.MellanoxMlnxosSSH">MellanoxMlnxosSSH</a></li> <li><a title="netmiko.mrv.mrv_lx.MrvLxSSH" href="mrv/mrv_lx.html#netmiko.mrv.mrv_lx.MrvLxSSH">MrvLxSSH</a></li> <li><a title="netmiko.mrv.mrv_ssh.MrvOptiswitchSSH" href="mrv/mrv_ssh.html#netmiko.mrv.mrv_ssh.MrvOptiswitchSSH">MrvOptiswitchSSH</a></li> +<li><a title="netmiko.netgear.netgear_prosafe_ssh.NetgearProSafeSSH" href="netgear/netgear_prosafe_ssh.html#netmiko.netgear.netgear_prosafe_ssh.NetgearProSafeSSH">NetgearProSafeSSH</a></li> <li><a title="netmiko.quanta.quanta_mesh_ssh.QuantaMeshSSH" href="quanta/quanta_mesh_ssh.html#netmiko.quanta.quanta_mesh_ssh.QuantaMeshSSH">QuantaMeshSSH</a></li> <li><a title="netmiko.ruckus.ruckus_fastiron.RuckusFastironBase" href="ruckus/ruckus_fastiron.html#netmiko.ruckus.ruckus_fastiron.RuckusFastironBase">RuckusFastironBase</a></li> <li><a title="netmiko.sophos.sophos_sfos_ssh.SophosSfosSSH" href="sophos/sophos_sfos_ssh.html#netmiko.sophos.sophos_sfos_ssh.SophosSfosSSH">SophosSfosSSH</a></li> diff --git a/docs/netmiko/dell/dell_dnos6.html b/docs/netmiko/dell/dell_dnos6.html index f97e6ec5cc188d2cd79e4407e1b26ab30d200b5e..467920adadff98a7ad95c083297171b34cc8bffd 100644 --- a/docs/netmiko/dell/dell_dnos6.html +++ b/docs/netmiko/dell/dell_dnos6.html @@ -35,8 +35,8 @@ class DellDNOS6Base(DellPowerConnectBase): self._test_channel_read() self.set_base_prompt() self.enable() - self.disable_paging(command="terminal length 0") self.set_terminal_width() + self.disable_paging(command="terminal length 0") # Clear the read buffer time.sleep(0.3 * self.global_delay_factor) self.clear_buffer() @@ -215,8 +215,8 @@ class DellDNOS6Telnet(DellDNOS6Base): self._test_channel_read() self.set_base_prompt() self.enable() - self.disable_paging(command="terminal length 0") self.set_terminal_width() + self.disable_paging(command="terminal length 0") # Clear the read buffer time.sleep(0.3 * self.global_delay_factor) self.clear_buffer() diff --git a/docs/netmiko/extreme/extreme_wing_ssh.html b/docs/netmiko/extreme/extreme_wing_ssh.html index 6cc7afb308ab76627b5785f4e897887b58bc8c4b..c3c03c82f4f0061aced7feb21af732f0aba9b772 100644 --- a/docs/netmiko/extreme/extreme_wing_ssh.html +++ b/docs/netmiko/extreme/extreme_wing_ssh.html @@ -33,8 +33,8 @@ class ExtremeWingSSH(CiscoSSHConnection): """Disable paging and set Max term width""" self._test_channel_read(pattern=r">|#") self.set_base_prompt() + self.set_terminal_width(command="terminal width 512", pattern="terminal") self.disable_paging(command="no page") - self.set_terminal_width(command="terminal width 512") time.sleep(0.3 * self.global_delay_factor) self.clear_buffer()</code></pre> </details> @@ -193,8 +193,8 @@ class ExtremeWingSSH(CiscoSSHConnection): """Disable paging and set Max term width""" self._test_channel_read(pattern=r">|#") self.set_base_prompt() + self.set_terminal_width(command="terminal width 512", pattern="terminal") self.disable_paging(command="no page") - self.set_terminal_width(command="terminal width 512") time.sleep(0.3 * self.global_delay_factor) self.clear_buffer()</code></pre> </details> @@ -217,8 +217,8 @@ class ExtremeWingSSH(CiscoSSHConnection): """Disable paging and set Max term width""" self._test_channel_read(pattern=r">|#") self.set_base_prompt() + self.set_terminal_width(command="terminal width 512", pattern="terminal") self.disable_paging(command="no page") - self.set_terminal_width(command="terminal width 512") time.sleep(0.3 * self.global_delay_factor) self.clear_buffer()</code></pre> </details> diff --git a/docs/netmiko/extreme/index.html b/docs/netmiko/extreme/index.html index 439bc2b9dfed4f77fb5e334b20bfd4b056f8e66e..de29267304db7720ff262ab8cf47e44b50294f36 100644 --- a/docs/netmiko/extreme/index.html +++ b/docs/netmiko/extreme/index.html @@ -2095,8 +2095,8 @@ __all__ = [ """Disable paging and set Max term width""" self._test_channel_read(pattern=r">|#") self.set_base_prompt() + self.set_terminal_width(command="terminal width 512", pattern="terminal") self.disable_paging(command="no page") - self.set_terminal_width(command="terminal width 512") time.sleep(0.3 * self.global_delay_factor) self.clear_buffer()</code></pre> </details> @@ -2119,8 +2119,8 @@ __all__ = [ """Disable paging and set Max term width""" self._test_channel_read(pattern=r">|#") self.set_base_prompt() + self.set_terminal_width(command="terminal width 512", pattern="terminal") self.disable_paging(command="no page") - self.set_terminal_width(command="terminal width 512") time.sleep(0.3 * self.global_delay_factor) self.clear_buffer()</code></pre> </details> diff --git a/docs/netmiko/f5/f5_tmsh_ssh.html b/docs/netmiko/f5/f5_tmsh_ssh.html index 13b8848b3386a02461396e722e3109f6d86a0678..bfefc1e13c16b94bdad69b1a47a5fb9b81ee72cc 100644 --- a/docs/netmiko/f5/f5_tmsh_ssh.html +++ b/docs/netmiko/f5/f5_tmsh_ssh.html @@ -33,12 +33,12 @@ class F5TmshSSH(BaseConnection): self.set_base_prompt() self.tmsh_mode() self.set_base_prompt() + cmd = 'run /util bash -c "stty cols 255"' + self.set_terminal_width(command=cmd, pattern="run") self.disable_paging( command="modify cli preference pager disabled display-threshold 0" ) self.clear_buffer() - cmd = 'run /util bash -c "stty cols 255"' - self.set_terminal_width(command=cmd) def tmsh_mode(self, delay_factor=1): """tmsh command is equivalent to config command on F5.""" @@ -206,12 +206,12 @@ class F5TmshSSH(BaseConnection): self.set_base_prompt() self.tmsh_mode() self.set_base_prompt() + cmd = 'run /util bash -c "stty cols 255"' + self.set_terminal_width(command=cmd, pattern="run") self.disable_paging( command="modify cli preference pager disabled display-threshold 0" ) self.clear_buffer() - cmd = 'run /util bash -c "stty cols 255"' - self.set_terminal_width(command=cmd) def tmsh_mode(self, delay_factor=1): """tmsh command is equivalent to config command on F5.""" @@ -242,12 +242,12 @@ class F5TmshSSH(BaseConnection): self.set_base_prompt() self.tmsh_mode() self.set_base_prompt() + cmd = 'run /util bash -c "stty cols 255"' + self.set_terminal_width(command=cmd, pattern="run") self.disable_paging( command="modify cli preference pager disabled display-threshold 0" ) - self.clear_buffer() - cmd = 'run /util bash -c "stty cols 255"' - self.set_terminal_width(command=cmd)</code></pre> + self.clear_buffer()</code></pre> </details> </dd> <dt id="netmiko.f5.f5_tmsh_ssh.F5TmshSSH.tmsh_mode"><code class="name flex"> diff --git a/docs/netmiko/f5/index.html b/docs/netmiko/f5/index.html index 61c3d649f916206e53b90c260ab5b5d558498485..45a505471d88dd3a4158458fcbbafef7ca7b4494 100644 --- a/docs/netmiko/f5/index.html +++ b/docs/netmiko/f5/index.html @@ -390,12 +390,12 @@ __all__ = ["F5TmshSSH", "F5LinuxSSH"]</code></pre> self.set_base_prompt() self.tmsh_mode() self.set_base_prompt() + cmd = 'run /util bash -c "stty cols 255"' + self.set_terminal_width(command=cmd, pattern="run") self.disable_paging( command="modify cli preference pager disabled display-threshold 0" ) self.clear_buffer() - cmd = 'run /util bash -c "stty cols 255"' - self.set_terminal_width(command=cmd) def tmsh_mode(self, delay_factor=1): """tmsh command is equivalent to config command on F5.""" @@ -426,12 +426,12 @@ __all__ = ["F5TmshSSH", "F5LinuxSSH"]</code></pre> self.set_base_prompt() self.tmsh_mode() self.set_base_prompt() + cmd = 'run /util bash -c "stty cols 255"' + self.set_terminal_width(command=cmd, pattern="run") self.disable_paging( command="modify cli preference pager disabled display-threshold 0" ) - self.clear_buffer() - cmd = 'run /util bash -c "stty cols 255"' - self.set_terminal_width(command=cmd)</code></pre> + self.clear_buffer()</code></pre> </details> </dd> <dt id="netmiko.f5.F5TmshSSH.tmsh_mode"><code class="name flex"> diff --git a/docs/netmiko/flexvnf/flexvnf_ssh.html b/docs/netmiko/flexvnf/flexvnf_ssh.html index 3623008ef24ac43437cf49746242a4c62eb0a0e4..01c1d98d52e17cdb7b4267ed6f9600300d11e48e 100644 --- a/docs/netmiko/flexvnf/flexvnf_ssh.html +++ b/docs/netmiko/flexvnf/flexvnf_ssh.html @@ -39,8 +39,8 @@ class FlexvnfSSH(BaseConnection): self._test_channel_read() self.enter_cli_mode() self.set_base_prompt() + self.set_terminal_width(command="set screen width 511", pattern="set") self.disable_paging(command="set screen length 0") - self.set_terminal_width(command="set screen width 511") # Clear the read buffer time.sleep(0.3 * self.global_delay_factor) self.clear_buffer() @@ -387,8 +387,8 @@ class FlexvnfSSH(BaseConnection): self._test_channel_read() self.enter_cli_mode() self.set_base_prompt() + self.set_terminal_width(command="set screen width 511", pattern="set") self.disable_paging(command="set screen length 0") - self.set_terminal_width(command="set screen width 511") # Clear the read buffer time.sleep(0.3 * self.global_delay_factor) self.clear_buffer() @@ -824,8 +824,8 @@ Set the base prompt for interaction ('>').</p></section> self._test_channel_read() self.enter_cli_mode() self.set_base_prompt() + self.set_terminal_width(command="set screen width 511", pattern="set") self.disable_paging(command="set screen length 0") - self.set_terminal_width(command="set screen width 511") # Clear the read buffer time.sleep(0.3 * self.global_delay_factor) self.clear_buffer()</code></pre> diff --git a/docs/netmiko/flexvnf/index.html b/docs/netmiko/flexvnf/index.html index ee21aea5f4852dfc5034ff42998da2f8f25566f1..a475841d41c308c46290eef44ad2e57dd4303f42 100644 --- a/docs/netmiko/flexvnf/index.html +++ b/docs/netmiko/flexvnf/index.html @@ -193,8 +193,8 @@ __all__ = ["FlexvnfSSH"]</code></pre> self._test_channel_read() self.enter_cli_mode() self.set_base_prompt() + self.set_terminal_width(command="set screen width 511", pattern="set") self.disable_paging(command="set screen length 0") - self.set_terminal_width(command="set screen width 511") # Clear the read buffer time.sleep(0.3 * self.global_delay_factor) self.clear_buffer() @@ -630,8 +630,8 @@ Set the base prompt for interaction ('>').</p></section> self._test_channel_read() self.enter_cli_mode() self.set_base_prompt() + self.set_terminal_width(command="set screen width 511", pattern="set") self.disable_paging(command="set screen length 0") - self.set_terminal_width(command="set screen width 511") # Clear the read buffer time.sleep(0.3 * self.global_delay_factor) self.clear_buffer()</code></pre> diff --git a/docs/netmiko/hp/hp_procurve.html b/docs/netmiko/hp/hp_procurve.html index 9218645fde8ea4d6f81ea44c8885cba0211b87f3..e2a9237eb6a7a524ec8fac4a24a83fdfd5708355 100644 --- a/docs/netmiko/hp/hp_procurve.html +++ b/docs/netmiko/hp/hp_procurve.html @@ -50,8 +50,8 @@ class HPProcurveBase(CiscoSSHConnection): self._test_channel_read(pattern=r"[>#]") self.set_base_prompt() command = self.RETURN + "no page" + self.set_terminal_width(command="terminal width 511", pattern="terminal") self.disable_paging(command=command) - self.set_terminal_width(command="terminal width 511") # Clear the read buffer time.sleep(0.3 * self.global_delay_factor) self.clear_buffer() @@ -371,8 +371,8 @@ class HPProcurveTelnet(HPProcurveBase): self._test_channel_read(pattern=r"[>#]") self.set_base_prompt() command = self.RETURN + "no page" + self.set_terminal_width(command="terminal width 511", pattern="terminal") self.disable_paging(command=command) - self.set_terminal_width(command="terminal width 511") # Clear the read buffer time.sleep(0.3 * self.global_delay_factor) self.clear_buffer() @@ -564,8 +564,8 @@ class HPProcurveTelnet(HPProcurveBase): self._test_channel_read(pattern=r"[>#]") self.set_base_prompt() command = self.RETURN + "no page" + self.set_terminal_width(command="terminal width 511", pattern="terminal") self.disable_paging(command=command) - self.set_terminal_width(command="terminal width 511") # Clear the read buffer time.sleep(0.3 * self.global_delay_factor) self.clear_buffer()</code></pre> diff --git a/docs/netmiko/index.html b/docs/netmiko/index.html index 3a2fd5e6c6c8e5d9aa09fe84eebb9a46e3311c43..ca51da7948f0c4a83ba878d849b46041e4683d2f 100644 --- a/docs/netmiko/index.html +++ b/docs/netmiko/index.html @@ -47,7 +47,7 @@ from netmiko.scp_functions import file_transfer, progress_bar # Alternate naming Netmiko = ConnectHandler -__version__ = "3.2.0" +__version__ = "3.3.0" __all__ = ( "ConnectHandler", "ssh_dispatcher", @@ -82,6 +82,10 @@ CNTL_SHIFT_6 = chr(30)</code></pre> <dd> <section class="desc"></section> </dd> +<dt><code class="name"><a title="netmiko.adtran" href="adtran/index.html">netmiko.adtran</a></code></dt> +<dd> +<section class="desc"></section> +</dd> <dt><code class="name"><a title="netmiko.alcatel" href="alcatel/index.html">netmiko.alcatel</a></code></dt> <dd> <section class="desc"></section> @@ -218,6 +222,10 @@ CNTL_SHIFT_6 = chr(30)</code></pre> <dd> <section class="desc"></section> </dd> +<dt><code class="name"><a title="netmiko.netgear" href="netgear/index.html">netmiko.netgear</a></code></dt> +<dd> +<section class="desc"></section> +</dd> <dt><code class="name"><a title="netmiko.netmiko_globals" href="netmiko_globals.html">netmiko.netmiko_globals</a></code></dt> <dd> <section class="desc"></section> @@ -763,6 +771,7 @@ with terminal server.</p></section> response_return=None, serial_settings=None, fast_cli=False, + _legacy_mode=True, session_log=None, session_log_record_writes=False, session_log_file_mode="write", @@ -982,6 +991,7 @@ with terminal server.</p></section> self.serial_settings.update({"port": comm_port}) self.fast_cli = fast_cli + self._legacy_mode = _legacy_mode self.global_delay_factor = global_delay_factor self.global_cmd_verify = global_cmd_verify if self.fast_cli and self.global_delay_factor == 1: @@ -1475,8 +1485,8 @@ with terminal server.</p></section> """ self._test_channel_read() self.set_base_prompt() - self.disable_paging() self.set_terminal_width() + self.disable_paging() # Clear the read buffer time.sleep(0.3 * self.global_delay_factor) @@ -1620,11 +1630,29 @@ Device settings: {self.device_type} {self.host}:{self.port} msg = msg.lstrip() raise NetmikoTimeoutException(msg) + except paramiko.ssh_exception.SSHException as no_session_err: + self.paramiko_cleanup() + if "No existing session" in str(no_session_err): + msg = ( + "Paramiko: 'No existing session' error: " + "try increasing 'conn_timeout' to 10 seconds or larger." + ) + raise NetmikoTimeoutException(msg) + else: + raise except paramiko.ssh_exception.AuthenticationException as auth_err: self.paramiko_cleanup() - msg = "Authentication failure: unable to connect {device_type} {ip}:{port}".format( - device_type=self.device_type, ip=self.host, port=self.port - ) + msg = f"""Authentication to device failed. + +Common causes of this problem are: +1. Invalid username and password +2. Incorrect SSH-key file +3. Connecting to the wrong device + +Device settings: {self.device_type} {self.host}:{self.port} + +""" + msg += self.RETURN + str(auth_err) raise NetmikoAuthenticationException(msg) @@ -1723,7 +1751,9 @@ Device settings: {self.device_type} {self.host}:{self.port} """Handler for devices like WLC, Extreme ERS that throw up characters prior to login.""" pass - def disable_paging(self, command="terminal length 0", delay_factor=1): + def disable_paging( + self, command="terminal length 0", delay_factor=1, cmd_verify=True, pattern=None + ): """Disable paging default to a Cisco CLI method. :param command: Device command to disable pagination of output @@ -1733,19 +1763,24 @@ Device settings: {self.device_type} {self.host}:{self.port} :type delay_factor: int """ 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(f"Command: {command}") self.write_channel(command) - # Do not use command_verify here as still in session_preparation stage. - output = self.read_until_prompt() + # Make sure you read until you detect the command echo (avoid getting out of sync) + if cmd_verify and self.global_cmd_verify is not False: + output = self.read_until_pattern(pattern=re.escape(command.strip())) + elif pattern: + output = self.read_until_pattern(pattern=pattern) + else: + output = self.read_until_prompt() log.debug(f"{output}") log.debug("Exiting disable_paging") return output - def set_terminal_width(self, command="", delay_factor=1): + def set_terminal_width( + self, command="", delay_factor=1, cmd_verify=False, pattern=None + ): """CLI terminals try to automatically adjust the line based on the width of the terminal. This causes the output to get distorted when accessed programmatically. @@ -1762,8 +1797,13 @@ Device settings: {self.device_type} {self.host}:{self.port} delay_factor = self.select_delay_factor(delay_factor) command = self.normalize_cmd(command) self.write_channel(command) - # Do not use command_verify here as still in session_preparation stage. - output = self.read_until_prompt() + # Avoid cmd_verify here as terminal width must be set before doing cmd_verify + if cmd_verify and self.global_cmd_verify is not False: + output = self.read_until_pattern(pattern=re.escape(command.strip())) + elif pattern: + output = self.read_until_pattern(pattern=pattern) + else: + output = self.read_until_prompt() return output def set_base_prompt( @@ -1808,11 +1848,10 @@ Device settings: {self.device_type} {self.host}:{self.port} time.sleep(sleep_time) # Initial attempt to get prompt - prompt = self.read_channel() + prompt = self.read_channel().strip() # Check if the only thing you received was a newline count = 0 - prompt = prompt.strip() while count <= 12 and not prompt: prompt = self.read_channel().strip() if not prompt: @@ -2444,7 +2483,7 @@ Device settings: {self.device_type} {self.host}:{self.port} cfg_mode_args = (config_mode_command,) if config_mode_command else tuple() output += self.config_mode(*cfg_mode_args) - if self.fast_cli: + if self.fast_cli and self._legacy_mode: for cmd in config_commands: self.write_channel(self.normalize_cmd(cmd)) # Gather output @@ -2820,7 +2859,7 @@ def strip_backspaces(output): </details> </dd> <dt id="netmiko.BaseConnection.disable_paging"><code class="name flex"> -<span>def <span class="ident">disable_paging</span></span>(<span>self, command='terminal length 0', delay_factor=1)</span> +<span>def <span class="ident">disable_paging</span></span>(<span>self, command='terminal length 0', delay_factor=1, cmd_verify=True, pattern=None)</span> </code></dt> <dd> <section class="desc"><p>Disable paging default to a Cisco CLI method.</p> @@ -2830,7 +2869,9 @@ def strip_backspaces(output): :type delay_factor: int</p></section> <details class="source"> <summary>Source code</summary> -<pre><code class="python">def disable_paging(self, command="terminal length 0", delay_factor=1): +<pre><code class="python">def disable_paging( + self, command="terminal length 0", delay_factor=1, cmd_verify=True, pattern=None +): """Disable paging default to a Cisco CLI method. :param command: Device command to disable pagination of output @@ -2840,14 +2881,17 @@ def strip_backspaces(output): :type delay_factor: int """ 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(f"Command: {command}") self.write_channel(command) - # Do not use command_verify here as still in session_preparation stage. - output = self.read_until_prompt() + # Make sure you read until you detect the command echo (avoid getting out of sync) + if cmd_verify and self.global_cmd_verify is not False: + output = self.read_until_pattern(pattern=re.escape(command.strip())) + elif pattern: + output = self.read_until_pattern(pattern=pattern) + else: + output = self.read_until_prompt() log.debug(f"{output}") log.debug("Exiting disable_paging") return output</code></pre> @@ -2986,11 +3030,29 @@ Device settings: {self.device_type} {self.host}:{self.port} msg = msg.lstrip() raise NetmikoTimeoutException(msg) + except paramiko.ssh_exception.SSHException as no_session_err: + self.paramiko_cleanup() + if "No existing session" in str(no_session_err): + msg = ( + "Paramiko: 'No existing session' error: " + "try increasing 'conn_timeout' to 10 seconds or larger." + ) + raise NetmikoTimeoutException(msg) + else: + raise except paramiko.ssh_exception.AuthenticationException as auth_err: self.paramiko_cleanup() - msg = "Authentication failure: unable to connect {device_type} {ip}:{port}".format( - device_type=self.device_type, ip=self.host, port=self.port - ) + msg = f"""Authentication to device failed. + +Common causes of this problem are: +1. Invalid username and password +2. Incorrect SSH-key file +3. Connecting to the wrong device + +Device settings: {self.device_type} {self.host}:{self.port} + +""" + msg += self.RETURN + str(auth_err) raise NetmikoAuthenticationException(msg) @@ -3093,11 +3155,10 @@ Device settings: {self.device_type} {self.host}:{self.port} time.sleep(sleep_time) # Initial attempt to get prompt - prompt = self.read_channel() + prompt = self.read_channel().strip() # Check if the only thing you received was a newline count = 0 - prompt = prompt.strip() while count <= 12 and not prompt: prompt = self.read_channel().strip() if not prompt: @@ -3853,7 +3914,7 @@ The commands will be executed one after the other.</p> cfg_mode_args = (config_mode_command,) if config_mode_command else tuple() output += self.config_mode(*cfg_mode_args) - if self.fast_cli: + if self.fast_cli and self._legacy_mode: for cmd in config_commands: self.write_channel(self.normalize_cmd(cmd)) # Gather output @@ -3949,8 +4010,8 @@ self.clear_buffer()</p></section> """ self._test_channel_read() self.set_base_prompt() - self.disable_paging() self.set_terminal_width() + self.disable_paging() # Clear the read buffer time.sleep(0.3 * self.global_delay_factor) @@ -4006,7 +4067,7 @@ entering/exiting config mode.</p> </details> </dd> <dt id="netmiko.BaseConnection.set_terminal_width"><code class="name flex"> -<span>def <span class="ident">set_terminal_width</span></span>(<span>self, command='', delay_factor=1)</span> +<span>def <span class="ident">set_terminal_width</span></span>(<span>self, command='', delay_factor=1, cmd_verify=False, pattern=None)</span> </code></dt> <dd> <section class="desc"><p>CLI terminals try to automatically adjust the line based on the width of the terminal. @@ -4018,7 +4079,9 @@ This causes the output to get distorted when accessed programmatically.</p> :type delay_factor: int</p></section> <details class="source"> <summary>Source code</summary> -<pre><code class="python">def set_terminal_width(self, command="", delay_factor=1): +<pre><code class="python">def set_terminal_width( + self, command="", delay_factor=1, cmd_verify=False, pattern=None +): """CLI terminals try to automatically adjust the line based on the width of the terminal. This causes the output to get distorted when accessed programmatically. @@ -4035,8 +4098,13 @@ This causes the output to get distorted when accessed programmatically.</p> delay_factor = self.select_delay_factor(delay_factor) command = self.normalize_cmd(command) self.write_channel(command) - # Do not use command_verify here as still in session_preparation stage. - output = self.read_until_prompt() + # Avoid cmd_verify here as terminal width must be set before doing cmd_verify + if cmd_verify and self.global_cmd_verify is not False: + output = self.read_until_pattern(pattern=re.escape(command.strip())) + elif pattern: + output = self.read_until_pattern(pattern=pattern) + else: + output = self.read_until_prompt() return output</code></pre> </details> </dd> @@ -4760,7 +4828,14 @@ Move cursor position leftward by x characters (1 in this case)</p> def scp_get_file(self, source_file, dest_file): """Get file using SCP.""" - self.scp_client.get(source_file, dest_file) + platform = self.ssh_ctl_chan.device_type + if "cisco_ios" in platform or "cisco_xe" in platform: + try: + self.scp_client.get(source_file, dest_file) + except EOFError: + pass + else: + self.scp_client.get(source_file, dest_file) def scp_put_file(self, source_file, dest_file): """Put file using SCP.""" @@ -4813,7 +4888,14 @@ Move cursor position leftward by x characters (1 in this case)</p> <summary>Source code</summary> <pre><code class="python">def scp_get_file(self, source_file, dest_file): """Get file using SCP.""" - self.scp_client.get(source_file, dest_file)</code></pre> + platform = self.ssh_ctl_chan.device_type + if "cisco_ios" in platform or "cisco_xe" in platform: + try: + self.scp_client.get(source_file, dest_file) + except EOFError: + pass + else: + self.scp_client.get(source_file, dest_file)</code></pre> </details> </dd> <dt id="netmiko.SCPConn.scp_put_file"><code class="name flex"> @@ -5134,6 +5216,7 @@ Try to determine the device type.</p> <ul> <li><code><a title="netmiko.a10" href="a10/index.html">netmiko.a10</a></code></li> <li><code><a title="netmiko.accedian" href="accedian/index.html">netmiko.accedian</a></code></li> +<li><code><a title="netmiko.adtran" href="adtran/index.html">netmiko.adtran</a></code></li> <li><code><a title="netmiko.alcatel" href="alcatel/index.html">netmiko.alcatel</a></code></li> <li><code><a title="netmiko.apresia" href="apresia/index.html">netmiko.apresia</a></code></li> <li><code><a title="netmiko.arista" href="arista/index.html">netmiko.arista</a></code></li> @@ -5168,6 +5251,7 @@ Try to determine the device type.</p> <li><code><a title="netmiko.mikrotik" href="mikrotik/index.html">netmiko.mikrotik</a></code></li> <li><code><a title="netmiko.mrv" href="mrv/index.html">netmiko.mrv</a></code></li> <li><code><a title="netmiko.netapp" href="netapp/index.html">netmiko.netapp</a></code></li> +<li><code><a title="netmiko.netgear" href="netgear/index.html">netmiko.netgear</a></code></li> <li><code><a title="netmiko.netmiko_globals" href="netmiko_globals.html">netmiko.netmiko_globals</a></code></li> <li><code><a title="netmiko.nokia" href="nokia/index.html">netmiko.nokia</a></code></li> <li><code><a title="netmiko.oneaccess" href="oneaccess/index.html">netmiko.oneaccess</a></code></li> diff --git a/docs/netmiko/juniper/juniper.html b/docs/netmiko/juniper/juniper.html index 9ea1fb273acaad3ece427ddf15a45bbaf43bd58d..db24d4cf0785cdf9658a7300a385d6ffd5e96d76 100644 --- a/docs/netmiko/juniper/juniper.html +++ b/docs/netmiko/juniper/juniper.html @@ -48,8 +48,8 @@ class JuniperBase(BaseConnection): self.enter_cli_mode() self.set_base_prompt() self._disable_complete_on_space() + self.set_terminal_width(command="set cli screen-width 511", pattern="set") self.disable_paging(command="set cli screen-length 0") - self.set_terminal_width(command="set cli screen-width 511") # Clear the read buffer time.sleep(0.3 * self.global_delay_factor) self.clear_buffer() @@ -490,8 +490,8 @@ Overrides several methods for Juniper-specific compatibility.</p> self.enter_cli_mode() self.set_base_prompt() self._disable_complete_on_space() + self.set_terminal_width(command="set cli screen-width 511", pattern="set") self.disable_paging(command="set cli screen-length 0") - self.set_terminal_width(command="set cli screen-width 511") # Clear the read buffer time.sleep(0.3 * self.global_delay_factor) self.clear_buffer() @@ -978,8 +978,8 @@ Set the base prompt for interaction ('>').</p></section> self.enter_cli_mode() self.set_base_prompt() self._disable_complete_on_space() + self.set_terminal_width(command="set cli screen-width 511", pattern="set") self.disable_paging(command="set cli screen-length 0") - self.set_terminal_width(command="set cli screen-width 511") # Clear the read buffer time.sleep(0.3 * self.global_delay_factor) self.clear_buffer()</code></pre> diff --git a/docs/netmiko/keymile/index.html b/docs/netmiko/keymile/index.html index bf95c7330762df0600632f4ca838a2f07490994e..17e88f451e61fbc4f314cc761f39115dae03cb04 100644 --- a/docs/netmiko/keymile/index.html +++ b/docs/netmiko/keymile/index.html @@ -50,7 +50,7 @@ __all__ = ["KeymileSSH", "KeymileNOSSSH"]</code></pre> <dl> <dt id="netmiko.keymile.KeymileNOSSSH"><code class="flex name class"> <span>class <span class="ident">KeymileNOSSSH</span></span> -<span>(</span><span>ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=5, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=False, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True)</span> +<span>(</span><span>*args, **kwargs)</span> </code></dt> <dd> <section class="desc"><p>Common Methods for IOS (both SSH and telnet).</p> diff --git a/docs/netmiko/keymile/keymile_nos_ssh.html b/docs/netmiko/keymile/keymile_nos_ssh.html index dc9f571e5edbb7760a6d0aca2c56fd9ea931d203..b91e0b003cc66cd773935c46ac62228d3616e189 100644 --- a/docs/netmiko/keymile/keymile_nos_ssh.html +++ b/docs/netmiko/keymile/keymile_nos_ssh.html @@ -69,7 +69,7 @@ class KeymileNOSSSH(CiscoIosBase): <dl> <dt id="netmiko.keymile.keymile_nos_ssh.KeymileNOSSSH"><code class="flex name class"> <span>class <span class="ident">KeymileNOSSSH</span></span> -<span>(</span><span>ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=5, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=False, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True)</span> +<span>(</span><span>*args, **kwargs)</span> </code></dt> <dd> <section class="desc"><p>Common Methods for IOS (both SSH and telnet).</p> diff --git a/docs/netmiko/netgear/index.html b/docs/netmiko/netgear/index.html new file mode 100644 index 0000000000000000000000000000000000000000..9fdc4c5dd4716c6cda28a2e15f3740e1e6c8ed3f --- /dev/null +++ b/docs/netmiko/netgear/index.html @@ -0,0 +1,337 @@ +<!doctype html> +<html lang="en"> +<head> +<meta charset="utf-8"> +<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1" /> +<meta name="generator" content="pdoc 0.6.3" /> +<title>netmiko.netgear API documentation</title> +<meta name="description" content="" /> +<link href='https://cdnjs.cloudflare.com/ajax/libs/normalize/8.0.0/normalize.min.css' rel='stylesheet'> +<link href='https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/8.0.0/sanitize.min.css' rel='stylesheet'> +<link href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/github.min.css" rel="stylesheet"> +<style>.flex{display:flex !important}body{line-height:1.5em}#content{padding:20px}#sidebar{padding:30px;overflow:hidden}.http-server-breadcrumbs{font-size:130%;margin:0 0 15px 0}#footer{font-size:.75em;padding:5px 30px;border-top:1px solid #ddd;text-align:right}#footer p{margin:0 0 0 1em;display:inline-block}#footer p:last-child{margin-right:30px}h1,h2,h3,h4,h5{font-weight:300}h1{font-size:2.5em;line-height:1.1em}h2{font-size:1.75em;margin:1em 0 .50em 0}h3{font-size:1.4em;margin:25px 0 10px 0}h4{margin:0;font-size:105%}a{color:#058;text-decoration:none;transition:color .3s ease-in-out}a:hover{color:#e82}.title code{font-weight:bold}h2[id^="header-"]{margin-top:2em}.ident{color:#900}pre code{background:#f8f8f8;font-size:.8em;line-height:1.4em}code{background:#f2f2f1;padding:1px 4px;overflow-wrap:break-word}h1 code{background:transparent}pre{background:#f8f8f8;border:0;border-top:1px solid #ccc;border-bottom:1px solid #ccc;margin:1em 0;padding:1ex}#http-server-module-list{display:flex;flex-flow:column}#http-server-module-list div{display:flex}#http-server-module-list dt{min-width:10%}#http-server-module-list p{margin-top:0}.toc ul,#index{list-style-type:none;margin:0;padding:0}#index code{background:transparent}#index h3{border-bottom:1px solid #ddd}#index ul{padding:0}#index h4{font-weight:bold}#index h4 + ul{margin-bottom:.6em}@media (min-width:200ex){#index .two-column{column-count:2}}@media (min-width:300ex){#index .two-column{column-count:3}}dl{margin-bottom:2em}dl dl:last-child{margin-bottom:4em}dd{margin:0 0 1em 3em}#header-classes + dl > dd{margin-bottom:3em}dd dd{margin-left:2em}dd p{margin:10px 0}.name{background:#eee;font-weight:bold;font-size:.85em;padding:5px 10px;display:inline-block;min-width:40%}.name:hover{background:#e0e0e0}.name > span:first-child{white-space:nowrap}.name.class > span:nth-child(2){margin-left:.4em}.inherited{color:#999;border-left:5px solid #eee;padding-left:1em}.inheritance em{font-style:normal;font-weight:bold}.desc h2{font-weight:400;font-size:1.25em}.desc h3{font-size:1em}.desc dt code{background:inherit}.source summary{color:#666;text-align:right;font-weight:400;font-size:.8em;text-transform:uppercase;cursor:pointer}.source pre{max-height:500px;overflow:auto;margin:0}.source pre code{font-size:12px;overflow:visible}.hlist{list-style:none}.hlist li{display:inline}.hlist li:after{content:',\2002'}.hlist li:last-child:after{content:none}.hlist .hlist{display:inline;padding-left:1em}img{max-width:100%}.admonition{padding:.1em .5em;margin-bottom:1em}.admonition-title{font-weight:bold}.admonition.note,.admonition.info,.admonition.important{background:#aef}.admonition.todo,.admonition.versionadded,.admonition.tip,.admonition.hint{background:#dfd}.admonition.warning,.admonition.versionchanged,.admonition.deprecated{background:#fd4}.admonition.error,.admonition.danger,.admonition.caution{background:lightpink}</style> +<style media="screen and (min-width: 700px)">@media screen and (min-width:700px){#sidebar{width:30%}#content{width:70%;max-width:100ch;padding:3em 4em;border-left:1px solid #ddd}pre code{font-size:1em}.item .name{font-size:1em}main{display:flex;flex-direction:row-reverse;justify-content:flex-end}.toc ul ul,#index ul{padding-left:1.5em}.toc > ul > li{margin-top:.5em}}</style> +<style media="print">@media print{#sidebar h1{page-break-before:always}.source{display:none}}@media print{*{background:transparent !important;color:#000 !important;box-shadow:none !important;text-shadow:none !important}a[href]:after{content:" (" attr(href) ")";font-size:90%}a[href][title]:after{content:none}abbr[title]:after{content:" (" attr(title) ")"}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}@page{margin:0.5cm}p,h2,h3{orphans:3;widows:3}h1,h2,h3,h4,h5,h6{page-break-after:avoid}}</style> +</head> +<body> +<main> +<article id="content"> +<header> +<h1 class="title">Module <code>netmiko.netgear</code></h1> +</header> +<section id="section-intro"> +<details class="source"> +<summary>Source code</summary> +<pre><code class="python">from netmiko.netgear.netgear_prosafe_ssh import NetgearProSafeSSH + +__all__ = ["NetgearProSafeSSH"]</code></pre> +</details> +</section> +<section> +<h2 class="section-title" id="header-submodules">Sub-modules</h2> +<dl> +<dt><code class="name"><a title="netmiko.netgear.netgear_prosafe_ssh" href="netgear_prosafe_ssh.html">netmiko.netgear.netgear_prosafe_ssh</a></code></dt> +<dd> +<section class="desc"><p>ProSafe OS support</p></section> +</dd> +</dl> +</section> +<section> +</section> +<section> +</section> +<section> +<h2 class="section-title" id="header-classes">Classes</h2> +<dl> +<dt id="netmiko.netgear.NetgearProSafeSSH"><code class="flex name class"> +<span>class <span class="ident">NetgearProSafeSSH</span></span> +<span>(</span><span>**kwargs)</span> +</code></dt> +<dd> +<section class="desc"><p>ProSafe OS support</p> +<pre><code> Initialize attributes for establishing connection to target device. + + :param ip: IP address of target device. Not required if `host` is + provided. + :type ip: str + + :param host: Hostname of target device. Not required if `ip` is + provided. + :type host: str + + :param username: Username to authenticate against target device if + required. + :type username: str + + :param password: Password to authenticate against target device if + required. + :type password: str + + :param secret: The enable password if target device requires one. + :type secret: str + + :param port: The destination port used to connect to the target + device. + :type port: int or None + + :param device_type: Class selection based on device type. + :type device_type: str + + :param verbose: Enable additional messages to standard output. + :type verbose: bool + + :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1). + :type global_delay_factor: int + + :param use_keys: Connect to target device using SSH keys. + :type use_keys: bool + + :param key_file: Filename path of the SSH key file to use. + :type key_file: str + + :param pkey: SSH key object to use. + :type pkey: paramiko.PKey + + :param passphrase: Passphrase to use for encrypted key; password will be used for key + decryption if not specified. + :type passphrase: str + + :param allow_agent: Enable use of SSH key-agent. + :type allow_agent: bool + + :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which + means unknown SSH host keys will be accepted). + :type ssh_strict: bool + + :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. + :type alt_host_keys: bool + + :param alt_key_file: SSH host key file to use (if alt_host_keys=True). + :type alt_key_file: str + + :param ssh_config_file: File name of OpenSSH configuration file. + :type ssh_config_file: str + + :param timeout: Connection timeout. + :type timeout: float + + :param session_timeout: Set a timeout for parallel requests. + :type session_timeout: float + + :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response. + :type auth_timeout: float + + :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko). + :type banner_timeout: float + + :param keepalive: Send SSH keepalive packets at a specific interval, in seconds. + Currently defaults to 0, for backwards compatibility (it will not attempt + to keep the connection alive). + :type keepalive: int + + :param default_enter: Character(s) to send to correspond to enter key (default: +</code></pre> +<p>). +:type default_enter: str</p> +<pre><code> :param response_return: Character(s) to use in normalized return data to represent + enter key (default: +</code></pre> +<p>) +:type response_return: str</p> +<pre><code> :param fast_cli: Provide a way to optimize for performance. Converts select_delay_factor + to select smallest of global and specific. Sets default global_delay_factor to .1 + (default: False) + :type fast_cli: boolean + + :param session_log: File path or BufferedIOBase subclass object to write the session log to. + :type session_log: str + + :param session_log_record_writes: The session log generally only records channel reads due + to eliminate command duplication due to command echo. You can enable this if you + want to record both channel reads and channel writes in the log (default: False). + :type session_log_record_writes: boolean + + :param session_log_file_mode: "write" or "append" for session_log file mode + (default: "write") + :type session_log_file_mode: str + + :param allow_auto_change: Allow automatic configuration changes for terminal settings. + (default: False) + :type allow_auto_change: bool + + :param encoding: Encoding to be used when writing bytes to the output channel. + (default: ascii) + :type encoding: str + + :param sock: An open socket or socket-like object (such as a `.Channel`) to use for + communication to the target host (default: None). + :type sock: socket + + :param global_cmd_verify: Control whether command echo verification is enabled or disabled + (default: None). Global attribute takes precedence over function `cmd_verify` + argument. Value of `None` indicates to use function `cmd_verify` argument. + :type global_cmd_verify: bool|None + + :param auto_connect: Control whether Netmiko automatically establishes the connection as + part of the object creation (default: True). + :type auto_connect: bool +</code></pre></section> +<details class="source"> +<summary>Source code</summary> +<pre><code class="python">class NetgearProSafeSSH(CiscoSSHConnection): + """ProSafe OS support""" + + def __init__(self, **kwargs): + if kwargs.get("default_enter") is None: + kwargs["default_enter"] = "\r" + return super().__init__(**kwargs) + + def session_preparation(self): + """ProSafe OS requires enabe mode to disable paging.""" + self._test_channel_read() + self.set_base_prompt() + self.enable() + self.disable_paging(command="terminal length 0") + + # Clear the read buffer + time.sleep(0.3 * self.global_delay_factor) + self.clear_buffer() + + def check_config_mode(self, check_string="(Config)#"): + return super().check_config_mode(check_string=check_string) + + def config_mode(self, config_command="configure", pattern=r")#"): + return super().config_mode(config_command=config_command, pattern=pattern) + + def exit_config_mode(self, exit_config="exit", pattern="#"): + return super().exit_config_mode(exit_config=exit_config, pattern=pattern) + + def save_config( + self, save_cmd="write memory confirm", confirm=False, confirm_response="" + ): + self.enable() + """ProSafe doesn't allow saving whilst within configuration mode""" + if self.check_config_mode(): + self.exit_config_mode() + + return super().save_config( + cmd=save_cmd, confirm=confirm, confirm_response=confirm_response + )</code></pre> +</details> +<h3>Ancestors</h3> +<ul class="hlist"> +<li><a title="netmiko.cisco_base_connection.CiscoSSHConnection" href="../cisco_base_connection.html#netmiko.cisco_base_connection.CiscoSSHConnection">CiscoSSHConnection</a></li> +<li><a title="netmiko.cisco_base_connection.CiscoBaseConnection" href="../cisco_base_connection.html#netmiko.cisco_base_connection.CiscoBaseConnection">CiscoBaseConnection</a></li> +<li><a title="netmiko.base_connection.BaseConnection" href="../base_connection.html#netmiko.base_connection.BaseConnection">BaseConnection</a></li> +</ul> +<h3>Methods</h3> +<dl> +<dt id="netmiko.netgear.NetgearProSafeSSH.session_preparation"><code class="name flex"> +<span>def <span class="ident">session_preparation</span></span>(<span>self)</span> +</code></dt> +<dd> +<section class="desc"><p>ProSafe OS requires enabe mode to disable paging.</p></section> +<details class="source"> +<summary>Source code</summary> +<pre><code class="python">def session_preparation(self): + """ProSafe OS requires enabe mode to disable paging.""" + self._test_channel_read() + self.set_base_prompt() + self.enable() + self.disable_paging(command="terminal length 0") + + # Clear the read buffer + time.sleep(0.3 * self.global_delay_factor) + self.clear_buffer()</code></pre> +</details> +</dd> +</dl> +<h3>Inherited members</h3> +<ul class="hlist"> +<li><code><b><a title="netmiko.cisco_base_connection.CiscoSSHConnection" href="../cisco_base_connection.html#netmiko.cisco_base_connection.CiscoSSHConnection">CiscoSSHConnection</a></b></code>: +<ul class="hlist"> +<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.check_config_mode" href="../cisco_base_connection.html#netmiko.cisco_base_connection.CiscoBaseConnection.check_config_mode">check_config_mode</a></code></li> +<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.check_enable_mode" href="../cisco_base_connection.html#netmiko.cisco_base_connection.CiscoBaseConnection.check_enable_mode">check_enable_mode</a></code></li> +<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.cleanup" href="../cisco_base_connection.html#netmiko.cisco_base_connection.CiscoBaseConnection.cleanup">cleanup</a></code></li> +<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.clear_buffer" href="../base_connection.html#netmiko.base_connection.BaseConnection.clear_buffer">clear_buffer</a></code></li> +<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.close_session_log" href="../base_connection.html#netmiko.base_connection.BaseConnection.close_session_log">close_session_log</a></code></li> +<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.commit" href="../base_connection.html#netmiko.base_connection.BaseConnection.commit">commit</a></code></li> +<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.config_mode" href="../cisco_base_connection.html#netmiko.cisco_base_connection.CiscoBaseConnection.config_mode">config_mode</a></code></li> +<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.disable_paging" href="../base_connection.html#netmiko.base_connection.BaseConnection.disable_paging">disable_paging</a></code></li> +<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.disconnect" href="../base_connection.html#netmiko.base_connection.BaseConnection.disconnect">disconnect</a></code></li> +<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.enable" href="../cisco_base_connection.html#netmiko.cisco_base_connection.CiscoBaseConnection.enable">enable</a></code></li> +<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.establish_connection" href="../base_connection.html#netmiko.base_connection.BaseConnection.establish_connection">establish_connection</a></code></li> +<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.exit_config_mode" href="../cisco_base_connection.html#netmiko.cisco_base_connection.CiscoBaseConnection.exit_config_mode">exit_config_mode</a></code></li> +<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.exit_enable_mode" href="../cisco_base_connection.html#netmiko.cisco_base_connection.CiscoBaseConnection.exit_enable_mode">exit_enable_mode</a></code></li> +<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.find_prompt" href="../base_connection.html#netmiko.base_connection.BaseConnection.find_prompt">find_prompt</a></code></li> +<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.is_alive" href="../base_connection.html#netmiko.base_connection.BaseConnection.is_alive">is_alive</a></code></li> +<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.normalize_cmd" href="../base_connection.html#netmiko.base_connection.BaseConnection.normalize_cmd">normalize_cmd</a></code></li> +<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.normalize_linefeeds" href="../base_connection.html#netmiko.base_connection.BaseConnection.normalize_linefeeds">normalize_linefeeds</a></code></li> +<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.open_session_log" href="../base_connection.html#netmiko.base_connection.BaseConnection.open_session_log">open_session_log</a></code></li> +<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.paramiko_cleanup" href="../base_connection.html#netmiko.base_connection.BaseConnection.paramiko_cleanup">paramiko_cleanup</a></code></li> +<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.read_channel" href="../base_connection.html#netmiko.base_connection.BaseConnection.read_channel">read_channel</a></code></li> +<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.read_until_pattern" href="../base_connection.html#netmiko.base_connection.BaseConnection.read_until_pattern">read_until_pattern</a></code></li> +<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.read_until_prompt" href="../base_connection.html#netmiko.base_connection.BaseConnection.read_until_prompt">read_until_prompt</a></code></li> +<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.read_until_prompt_or_pattern" href="../base_connection.html#netmiko.base_connection.BaseConnection.read_until_prompt_or_pattern">read_until_prompt_or_pattern</a></code></li> +<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.save_config" href="../cisco_base_connection.html#netmiko.cisco_base_connection.CiscoBaseConnection.save_config">save_config</a></code></li> +<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.select_delay_factor" href="../base_connection.html#netmiko.base_connection.BaseConnection.select_delay_factor">select_delay_factor</a></code></li> +<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.send_command" href="../base_connection.html#netmiko.base_connection.BaseConnection.send_command">send_command</a></code></li> +<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.send_command_expect" href="../base_connection.html#netmiko.base_connection.BaseConnection.send_command_expect">send_command_expect</a></code></li> +<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.send_command_timing" href="../base_connection.html#netmiko.base_connection.BaseConnection.send_command_timing">send_command_timing</a></code></li> +<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.send_config_from_file" href="../base_connection.html#netmiko.base_connection.BaseConnection.send_config_from_file">send_config_from_file</a></code></li> +<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.send_config_set" href="../base_connection.html#netmiko.base_connection.BaseConnection.send_config_set">send_config_set</a></code></li> +<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.set_base_prompt" href="../base_connection.html#netmiko.base_connection.BaseConnection.set_base_prompt">set_base_prompt</a></code></li> +<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.set_terminal_width" href="../base_connection.html#netmiko.base_connection.BaseConnection.set_terminal_width">set_terminal_width</a></code></li> +<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.special_login_handler" href="../base_connection.html#netmiko.base_connection.BaseConnection.special_login_handler">special_login_handler</a></code></li> +<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.strip_ansi_escape_codes" href="../base_connection.html#netmiko.base_connection.BaseConnection.strip_ansi_escape_codes">strip_ansi_escape_codes</a></code></li> +<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.strip_backspaces" href="../base_connection.html#netmiko.base_connection.BaseConnection.strip_backspaces">strip_backspaces</a></code></li> +<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.strip_command" href="../base_connection.html#netmiko.base_connection.BaseConnection.strip_command">strip_command</a></code></li> +<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.strip_prompt" href="../base_connection.html#netmiko.base_connection.BaseConnection.strip_prompt">strip_prompt</a></code></li> +<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.telnet_login" href="../cisco_base_connection.html#netmiko.cisco_base_connection.CiscoBaseConnection.telnet_login">telnet_login</a></code></li> +<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.write_channel" href="../base_connection.html#netmiko.base_connection.BaseConnection.write_channel">write_channel</a></code></li> +</ul> +</li> +</ul> +</dd> +</dl> +</section> +</article> +<nav id="sidebar"> +<h1>Index</h1> +<div class="toc"> +<ul></ul> +</div> +<ul id="index"> +<li><h3>Super-module</h3> +<ul> +<li><code><a title="netmiko" href="../index.html">netmiko</a></code></li> +</ul> +</li> +<li><h3><a href="#header-submodules">Sub-modules</a></h3> +<ul> +<li><code><a title="netmiko.netgear.netgear_prosafe_ssh" href="netgear_prosafe_ssh.html">netmiko.netgear.netgear_prosafe_ssh</a></code></li> +</ul> +</li> +<li><h3><a href="#header-classes">Classes</a></h3> +<ul> +<li> +<h4><code><a title="netmiko.netgear.NetgearProSafeSSH" href="#netmiko.netgear.NetgearProSafeSSH">NetgearProSafeSSH</a></code></h4> +<ul class=""> +<li><code><a title="netmiko.netgear.NetgearProSafeSSH.session_preparation" href="#netmiko.netgear.NetgearProSafeSSH.session_preparation">session_preparation</a></code></li> +</ul> +</li> +</ul> +</li> +</ul> +</nav> +</main> +<footer id="footer"> +<p>Generated by <a href="https://pdoc3.github.io/pdoc"><cite>pdoc</cite> 0.6.3</a>.</p> +</footer> +<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/highlight.min.js"></script> +<script>hljs.initHighlightingOnLoad()</script> +</body> +</html> \ No newline at end of file diff --git a/docs/netmiko/netgear/netgear_prosafe_ssh.html b/docs/netmiko/netgear/netgear_prosafe_ssh.html new file mode 100644 index 0000000000000000000000000000000000000000..f6851bcd5265ca494d4fe4a2d646c37da9fd04e7 --- /dev/null +++ b/docs/netmiko/netgear/netgear_prosafe_ssh.html @@ -0,0 +1,367 @@ +<!doctype html> +<html lang="en"> +<head> +<meta charset="utf-8"> +<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1" /> +<meta name="generator" content="pdoc 0.6.3" /> +<title>netmiko.netgear.netgear_prosafe_ssh API documentation</title> +<meta name="description" content="ProSafe OS support" /> +<link href='https://cdnjs.cloudflare.com/ajax/libs/normalize/8.0.0/normalize.min.css' rel='stylesheet'> +<link href='https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/8.0.0/sanitize.min.css' rel='stylesheet'> +<link href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/github.min.css" rel="stylesheet"> +<style>.flex{display:flex !important}body{line-height:1.5em}#content{padding:20px}#sidebar{padding:30px;overflow:hidden}.http-server-breadcrumbs{font-size:130%;margin:0 0 15px 0}#footer{font-size:.75em;padding:5px 30px;border-top:1px solid #ddd;text-align:right}#footer p{margin:0 0 0 1em;display:inline-block}#footer p:last-child{margin-right:30px}h1,h2,h3,h4,h5{font-weight:300}h1{font-size:2.5em;line-height:1.1em}h2{font-size:1.75em;margin:1em 0 .50em 0}h3{font-size:1.4em;margin:25px 0 10px 0}h4{margin:0;font-size:105%}a{color:#058;text-decoration:none;transition:color .3s ease-in-out}a:hover{color:#e82}.title code{font-weight:bold}h2[id^="header-"]{margin-top:2em}.ident{color:#900}pre code{background:#f8f8f8;font-size:.8em;line-height:1.4em}code{background:#f2f2f1;padding:1px 4px;overflow-wrap:break-word}h1 code{background:transparent}pre{background:#f8f8f8;border:0;border-top:1px solid #ccc;border-bottom:1px solid #ccc;margin:1em 0;padding:1ex}#http-server-module-list{display:flex;flex-flow:column}#http-server-module-list div{display:flex}#http-server-module-list dt{min-width:10%}#http-server-module-list p{margin-top:0}.toc ul,#index{list-style-type:none;margin:0;padding:0}#index code{background:transparent}#index h3{border-bottom:1px solid #ddd}#index ul{padding:0}#index h4{font-weight:bold}#index h4 + ul{margin-bottom:.6em}@media (min-width:200ex){#index .two-column{column-count:2}}@media (min-width:300ex){#index .two-column{column-count:3}}dl{margin-bottom:2em}dl dl:last-child{margin-bottom:4em}dd{margin:0 0 1em 3em}#header-classes + dl > dd{margin-bottom:3em}dd dd{margin-left:2em}dd p{margin:10px 0}.name{background:#eee;font-weight:bold;font-size:.85em;padding:5px 10px;display:inline-block;min-width:40%}.name:hover{background:#e0e0e0}.name > span:first-child{white-space:nowrap}.name.class > span:nth-child(2){margin-left:.4em}.inherited{color:#999;border-left:5px solid #eee;padding-left:1em}.inheritance em{font-style:normal;font-weight:bold}.desc h2{font-weight:400;font-size:1.25em}.desc h3{font-size:1em}.desc dt code{background:inherit}.source summary{color:#666;text-align:right;font-weight:400;font-size:.8em;text-transform:uppercase;cursor:pointer}.source pre{max-height:500px;overflow:auto;margin:0}.source pre code{font-size:12px;overflow:visible}.hlist{list-style:none}.hlist li{display:inline}.hlist li:after{content:',\2002'}.hlist li:last-child:after{content:none}.hlist .hlist{display:inline;padding-left:1em}img{max-width:100%}.admonition{padding:.1em .5em;margin-bottom:1em}.admonition-title{font-weight:bold}.admonition.note,.admonition.info,.admonition.important{background:#aef}.admonition.todo,.admonition.versionadded,.admonition.tip,.admonition.hint{background:#dfd}.admonition.warning,.admonition.versionchanged,.admonition.deprecated{background:#fd4}.admonition.error,.admonition.danger,.admonition.caution{background:lightpink}</style> +<style media="screen and (min-width: 700px)">@media screen and (min-width:700px){#sidebar{width:30%}#content{width:70%;max-width:100ch;padding:3em 4em;border-left:1px solid #ddd}pre code{font-size:1em}.item .name{font-size:1em}main{display:flex;flex-direction:row-reverse;justify-content:flex-end}.toc ul ul,#index ul{padding-left:1.5em}.toc > ul > li{margin-top:.5em}}</style> +<style media="print">@media print{#sidebar h1{page-break-before:always}.source{display:none}}@media print{*{background:transparent !important;color:#000 !important;box-shadow:none !important;text-shadow:none !important}a[href]:after{content:" (" attr(href) ")";font-size:90%}a[href][title]:after{content:none}abbr[title]:after{content:" (" attr(title) ")"}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}@page{margin:0.5cm}p,h2,h3{orphans:3;widows:3}h1,h2,h3,h4,h5,h6{page-break-after:avoid}}</style> +</head> +<body> +<main> +<article id="content"> +<header> +<h1 class="title">Module <code>netmiko.netgear.netgear_prosafe_ssh</code></h1> +</header> +<section id="section-intro"> +<p>ProSafe OS support</p> +<details class="source"> +<summary>Source code</summary> +<pre><code class="python">"""ProSafe OS support""" +import time +from netmiko.cisco_base_connection import CiscoSSHConnection + + +class NetgearProSafeSSH(CiscoSSHConnection): + """ProSafe OS support""" + + def __init__(self, **kwargs): + if kwargs.get("default_enter") is None: + kwargs["default_enter"] = "\r" + return super().__init__(**kwargs) + + def session_preparation(self): + """ProSafe OS requires enabe mode to disable paging.""" + self._test_channel_read() + self.set_base_prompt() + self.enable() + self.disable_paging(command="terminal length 0") + + # Clear the read buffer + time.sleep(0.3 * self.global_delay_factor) + self.clear_buffer() + + def check_config_mode(self, check_string="(Config)#"): + return super().check_config_mode(check_string=check_string) + + def config_mode(self, config_command="configure", pattern=r")#"): + return super().config_mode(config_command=config_command, pattern=pattern) + + def exit_config_mode(self, exit_config="exit", pattern="#"): + return super().exit_config_mode(exit_config=exit_config, pattern=pattern) + + def save_config( + self, save_cmd="write memory confirm", confirm=False, confirm_response="" + ): + self.enable() + """ProSafe doesn't allow saving whilst within configuration mode""" + if self.check_config_mode(): + self.exit_config_mode() + + return super().save_config( + cmd=save_cmd, confirm=confirm, confirm_response=confirm_response + )</code></pre> +</details> +</section> +<section> +</section> +<section> +</section> +<section> +</section> +<section> +<h2 class="section-title" id="header-classes">Classes</h2> +<dl> +<dt id="netmiko.netgear.netgear_prosafe_ssh.NetgearProSafeSSH"><code class="flex name class"> +<span>class <span class="ident">NetgearProSafeSSH</span></span> +<span>(</span><span>**kwargs)</span> +</code></dt> +<dd> +<section class="desc"><p>ProSafe OS support</p> +<pre><code> Initialize attributes for establishing connection to target device. + + :param ip: IP address of target device. Not required if `host` is + provided. + :type ip: str + + :param host: Hostname of target device. Not required if `ip` is + provided. + :type host: str + + :param username: Username to authenticate against target device if + required. + :type username: str + + :param password: Password to authenticate against target device if + required. + :type password: str + + :param secret: The enable password if target device requires one. + :type secret: str + + :param port: The destination port used to connect to the target + device. + :type port: int or None + + :param device_type: Class selection based on device type. + :type device_type: str + + :param verbose: Enable additional messages to standard output. + :type verbose: bool + + :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1). + :type global_delay_factor: int + + :param use_keys: Connect to target device using SSH keys. + :type use_keys: bool + + :param key_file: Filename path of the SSH key file to use. + :type key_file: str + + :param pkey: SSH key object to use. + :type pkey: paramiko.PKey + + :param passphrase: Passphrase to use for encrypted key; password will be used for key + decryption if not specified. + :type passphrase: str + + :param allow_agent: Enable use of SSH key-agent. + :type allow_agent: bool + + :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which + means unknown SSH host keys will be accepted). + :type ssh_strict: bool + + :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. + :type alt_host_keys: bool + + :param alt_key_file: SSH host key file to use (if alt_host_keys=True). + :type alt_key_file: str + + :param ssh_config_file: File name of OpenSSH configuration file. + :type ssh_config_file: str + + :param timeout: Connection timeout. + :type timeout: float + + :param session_timeout: Set a timeout for parallel requests. + :type session_timeout: float + + :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response. + :type auth_timeout: float + + :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko). + :type banner_timeout: float + + :param keepalive: Send SSH keepalive packets at a specific interval, in seconds. + Currently defaults to 0, for backwards compatibility (it will not attempt + to keep the connection alive). + :type keepalive: int + + :param default_enter: Character(s) to send to correspond to enter key (default: +</code></pre> +<p>). +:type default_enter: str</p> +<pre><code> :param response_return: Character(s) to use in normalized return data to represent + enter key (default: +</code></pre> +<p>) +:type response_return: str</p> +<pre><code> :param fast_cli: Provide a way to optimize for performance. Converts select_delay_factor + to select smallest of global and specific. Sets default global_delay_factor to .1 + (default: False) + :type fast_cli: boolean + + :param session_log: File path or BufferedIOBase subclass object to write the session log to. + :type session_log: str + + :param session_log_record_writes: The session log generally only records channel reads due + to eliminate command duplication due to command echo. You can enable this if you + want to record both channel reads and channel writes in the log (default: False). + :type session_log_record_writes: boolean + + :param session_log_file_mode: "write" or "append" for session_log file mode + (default: "write") + :type session_log_file_mode: str + + :param allow_auto_change: Allow automatic configuration changes for terminal settings. + (default: False) + :type allow_auto_change: bool + + :param encoding: Encoding to be used when writing bytes to the output channel. + (default: ascii) + :type encoding: str + + :param sock: An open socket or socket-like object (such as a `.Channel`) to use for + communication to the target host (default: None). + :type sock: socket + + :param global_cmd_verify: Control whether command echo verification is enabled or disabled + (default: None). Global attribute takes precedence over function `cmd_verify` + argument. Value of `None` indicates to use function `cmd_verify` argument. + :type global_cmd_verify: bool|None + + :param auto_connect: Control whether Netmiko automatically establishes the connection as + part of the object creation (default: True). + :type auto_connect: bool +</code></pre></section> +<details class="source"> +<summary>Source code</summary> +<pre><code class="python">class NetgearProSafeSSH(CiscoSSHConnection): + """ProSafe OS support""" + + def __init__(self, **kwargs): + if kwargs.get("default_enter") is None: + kwargs["default_enter"] = "\r" + return super().__init__(**kwargs) + + def session_preparation(self): + """ProSafe OS requires enabe mode to disable paging.""" + self._test_channel_read() + self.set_base_prompt() + self.enable() + self.disable_paging(command="terminal length 0") + + # Clear the read buffer + time.sleep(0.3 * self.global_delay_factor) + self.clear_buffer() + + def check_config_mode(self, check_string="(Config)#"): + return super().check_config_mode(check_string=check_string) + + def config_mode(self, config_command="configure", pattern=r")#"): + return super().config_mode(config_command=config_command, pattern=pattern) + + def exit_config_mode(self, exit_config="exit", pattern="#"): + return super().exit_config_mode(exit_config=exit_config, pattern=pattern) + + def save_config( + self, save_cmd="write memory confirm", confirm=False, confirm_response="" + ): + self.enable() + """ProSafe doesn't allow saving whilst within configuration mode""" + if self.check_config_mode(): + self.exit_config_mode() + + return super().save_config( + cmd=save_cmd, confirm=confirm, confirm_response=confirm_response + )</code></pre> +</details> +<h3>Ancestors</h3> +<ul class="hlist"> +<li><a title="netmiko.cisco_base_connection.CiscoSSHConnection" href="../cisco_base_connection.html#netmiko.cisco_base_connection.CiscoSSHConnection">CiscoSSHConnection</a></li> +<li><a title="netmiko.cisco_base_connection.CiscoBaseConnection" href="../cisco_base_connection.html#netmiko.cisco_base_connection.CiscoBaseConnection">CiscoBaseConnection</a></li> +<li><a title="netmiko.base_connection.BaseConnection" href="../base_connection.html#netmiko.base_connection.BaseConnection">BaseConnection</a></li> +</ul> +<h3>Methods</h3> +<dl> +<dt id="netmiko.netgear.netgear_prosafe_ssh.NetgearProSafeSSH.session_preparation"><code class="name flex"> +<span>def <span class="ident">session_preparation</span></span>(<span>self)</span> +</code></dt> +<dd> +<section class="desc"><p>ProSafe OS requires enabe mode to disable paging.</p></section> +<details class="source"> +<summary>Source code</summary> +<pre><code class="python">def session_preparation(self): + """ProSafe OS requires enabe mode to disable paging.""" + self._test_channel_read() + self.set_base_prompt() + self.enable() + self.disable_paging(command="terminal length 0") + + # Clear the read buffer + time.sleep(0.3 * self.global_delay_factor) + self.clear_buffer()</code></pre> +</details> +</dd> +</dl> +<h3>Inherited members</h3> +<ul class="hlist"> +<li><code><b><a title="netmiko.cisco_base_connection.CiscoSSHConnection" href="../cisco_base_connection.html#netmiko.cisco_base_connection.CiscoSSHConnection">CiscoSSHConnection</a></b></code>: +<ul class="hlist"> +<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.check_config_mode" href="../cisco_base_connection.html#netmiko.cisco_base_connection.CiscoBaseConnection.check_config_mode">check_config_mode</a></code></li> +<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.check_enable_mode" href="../cisco_base_connection.html#netmiko.cisco_base_connection.CiscoBaseConnection.check_enable_mode">check_enable_mode</a></code></li> +<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.cleanup" href="../cisco_base_connection.html#netmiko.cisco_base_connection.CiscoBaseConnection.cleanup">cleanup</a></code></li> +<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.clear_buffer" href="../base_connection.html#netmiko.base_connection.BaseConnection.clear_buffer">clear_buffer</a></code></li> +<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.close_session_log" href="../base_connection.html#netmiko.base_connection.BaseConnection.close_session_log">close_session_log</a></code></li> +<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.commit" href="../base_connection.html#netmiko.base_connection.BaseConnection.commit">commit</a></code></li> +<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.config_mode" href="../cisco_base_connection.html#netmiko.cisco_base_connection.CiscoBaseConnection.config_mode">config_mode</a></code></li> +<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.disable_paging" href="../base_connection.html#netmiko.base_connection.BaseConnection.disable_paging">disable_paging</a></code></li> +<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.disconnect" href="../base_connection.html#netmiko.base_connection.BaseConnection.disconnect">disconnect</a></code></li> +<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.enable" href="../cisco_base_connection.html#netmiko.cisco_base_connection.CiscoBaseConnection.enable">enable</a></code></li> +<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.establish_connection" href="../base_connection.html#netmiko.base_connection.BaseConnection.establish_connection">establish_connection</a></code></li> +<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.exit_config_mode" href="../cisco_base_connection.html#netmiko.cisco_base_connection.CiscoBaseConnection.exit_config_mode">exit_config_mode</a></code></li> +<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.exit_enable_mode" href="../cisco_base_connection.html#netmiko.cisco_base_connection.CiscoBaseConnection.exit_enable_mode">exit_enable_mode</a></code></li> +<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.find_prompt" href="../base_connection.html#netmiko.base_connection.BaseConnection.find_prompt">find_prompt</a></code></li> +<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.is_alive" href="../base_connection.html#netmiko.base_connection.BaseConnection.is_alive">is_alive</a></code></li> +<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.normalize_cmd" href="../base_connection.html#netmiko.base_connection.BaseConnection.normalize_cmd">normalize_cmd</a></code></li> +<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.normalize_linefeeds" href="../base_connection.html#netmiko.base_connection.BaseConnection.normalize_linefeeds">normalize_linefeeds</a></code></li> +<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.open_session_log" href="../base_connection.html#netmiko.base_connection.BaseConnection.open_session_log">open_session_log</a></code></li> +<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.paramiko_cleanup" href="../base_connection.html#netmiko.base_connection.BaseConnection.paramiko_cleanup">paramiko_cleanup</a></code></li> +<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.read_channel" href="../base_connection.html#netmiko.base_connection.BaseConnection.read_channel">read_channel</a></code></li> +<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.read_until_pattern" href="../base_connection.html#netmiko.base_connection.BaseConnection.read_until_pattern">read_until_pattern</a></code></li> +<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.read_until_prompt" href="../base_connection.html#netmiko.base_connection.BaseConnection.read_until_prompt">read_until_prompt</a></code></li> +<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.read_until_prompt_or_pattern" href="../base_connection.html#netmiko.base_connection.BaseConnection.read_until_prompt_or_pattern">read_until_prompt_or_pattern</a></code></li> +<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.save_config" href="../cisco_base_connection.html#netmiko.cisco_base_connection.CiscoBaseConnection.save_config">save_config</a></code></li> +<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.select_delay_factor" href="../base_connection.html#netmiko.base_connection.BaseConnection.select_delay_factor">select_delay_factor</a></code></li> +<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.send_command" href="../base_connection.html#netmiko.base_connection.BaseConnection.send_command">send_command</a></code></li> +<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.send_command_expect" href="../base_connection.html#netmiko.base_connection.BaseConnection.send_command_expect">send_command_expect</a></code></li> +<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.send_command_timing" href="../base_connection.html#netmiko.base_connection.BaseConnection.send_command_timing">send_command_timing</a></code></li> +<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.send_config_from_file" href="../base_connection.html#netmiko.base_connection.BaseConnection.send_config_from_file">send_config_from_file</a></code></li> +<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.send_config_set" href="../base_connection.html#netmiko.base_connection.BaseConnection.send_config_set">send_config_set</a></code></li> +<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.set_base_prompt" href="../base_connection.html#netmiko.base_connection.BaseConnection.set_base_prompt">set_base_prompt</a></code></li> +<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.set_terminal_width" href="../base_connection.html#netmiko.base_connection.BaseConnection.set_terminal_width">set_terminal_width</a></code></li> +<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.special_login_handler" href="../base_connection.html#netmiko.base_connection.BaseConnection.special_login_handler">special_login_handler</a></code></li> +<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.strip_ansi_escape_codes" href="../base_connection.html#netmiko.base_connection.BaseConnection.strip_ansi_escape_codes">strip_ansi_escape_codes</a></code></li> +<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.strip_backspaces" href="../base_connection.html#netmiko.base_connection.BaseConnection.strip_backspaces">strip_backspaces</a></code></li> +<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.strip_command" href="../base_connection.html#netmiko.base_connection.BaseConnection.strip_command">strip_command</a></code></li> +<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.strip_prompt" href="../base_connection.html#netmiko.base_connection.BaseConnection.strip_prompt">strip_prompt</a></code></li> +<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.telnet_login" href="../cisco_base_connection.html#netmiko.cisco_base_connection.CiscoBaseConnection.telnet_login">telnet_login</a></code></li> +<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.write_channel" href="../base_connection.html#netmiko.base_connection.BaseConnection.write_channel">write_channel</a></code></li> +</ul> +</li> +</ul> +</dd> +</dl> +</section> +</article> +<nav id="sidebar"> +<h1>Index</h1> +<div class="toc"> +<ul></ul> +</div> +<ul id="index"> +<li><h3>Super-module</h3> +<ul> +<li><code><a title="netmiko.netgear" href="index.html">netmiko.netgear</a></code></li> +</ul> +</li> +<li><h3><a href="#header-classes">Classes</a></h3> +<ul> +<li> +<h4><code><a title="netmiko.netgear.netgear_prosafe_ssh.NetgearProSafeSSH" href="#netmiko.netgear.netgear_prosafe_ssh.NetgearProSafeSSH">NetgearProSafeSSH</a></code></h4> +<ul class=""> +<li><code><a title="netmiko.netgear.netgear_prosafe_ssh.NetgearProSafeSSH.session_preparation" href="#netmiko.netgear.netgear_prosafe_ssh.NetgearProSafeSSH.session_preparation">session_preparation</a></code></li> +</ul> +</li> +</ul> +</li> +</ul> +</nav> +</main> +<footer id="footer"> +<p>Generated by <a href="https://pdoc3.github.io/pdoc"><cite>pdoc</cite> 0.6.3</a>.</p> +</footer> +<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/highlight.min.js"></script> +<script>hljs.initHighlightingOnLoad()</script> +</body> +</html> \ No newline at end of file diff --git a/docs/netmiko/nokia/index.html b/docs/netmiko/nokia/index.html index 609448957f2714df2fbc9b75cb8ed64d681b171b..c4cc956af223ea1854b31f5892dd597ecb097a5f 100644 --- a/docs/netmiko/nokia/index.html +++ b/docs/netmiko/nokia/index.html @@ -233,9 +233,7 @@ __all__ = ["NokiaSrosSSH", "NokiaSrosFileTransfer"]</code></pre> <dd> <section class="desc"><p>Implement methods for interacting with Nokia SR OS devices.</p> <p>Not applicable in Nokia SR OS (disabled): -- enable() -- exit_enable_mode() -- check_enable_mode()</p> +- exit_enable_mode()</p> <p>Overriden methods to adapt Nokia SR OS behavior (changed): - session_preparation() - set_base_prompt() @@ -244,7 +242,9 @@ __all__ = ["NokiaSrosSSH", "NokiaSrosFileTransfer"]</code></pre> - check_config_mode() - save_config() - commit() -- strip_prompt()</p> +- strip_prompt() +- enable() +- check_enable_mode()</p> <pre><code> Initialize attributes for establishing connection to target device. :param ip: IP address of target device. Not required if `host` is @@ -382,9 +382,7 @@ __all__ = ["NokiaSrosSSH", "NokiaSrosFileTransfer"]</code></pre> Implement methods for interacting with Nokia SR OS devices. Not applicable in Nokia SR OS (disabled): - - enable() - exit_enable_mode() - - check_enable_mode() Overriden methods to adapt Nokia SR OS behavior (changed): - session_preparation() @@ -395,6 +393,8 @@ __all__ = ["NokiaSrosSSH", "NokiaSrosFileTransfer"]</code></pre> - save_config() - commit() - strip_prompt() + - enable() + - check_enable_mode() """ def session_preparation(self): @@ -402,12 +402,18 @@ __all__ = ["NokiaSrosSSH", "NokiaSrosFileTransfer"]</code></pre> self.set_base_prompt() # "@" indicates model-driven CLI (vs Classical CLI) if "@" in self.base_prompt: + self._disable_complete_on_space() + self.set_terminal_width( + command="environment console width 512", pattern="environment" + ) self.disable_paging(command="environment more false") # To perform file operations we need to disable paging in classical-CLI also self.disable_paging(command="//environment no more") - self.set_terminal_width(command="environment console width 512") else: - self.disable_paging(command="environment no more") + # Classical CLI has no method to set the terminal width nor to disable command + # complete on space; consequently, cmd_verify needs disabled. + self.global_cmd_verify = False + self.disable_paging(command="environment no more", pattern="environment") # Clear the read buffer time.sleep(0.3 * self.global_delay_factor) @@ -422,16 +428,40 @@ __all__ = ["NokiaSrosSSH", "NokiaSrosFileTransfer"]</code></pre> self.base_prompt = match.group(1) return self.base_prompt - def enable(self, *args, **kwargs): - """Nokia SR OS does not support enable-mode""" - return "" + def _disable_complete_on_space(self): + """ + SR-OS tries to auto complete commands when you type a "space" character. - def check_enable_mode(self, *args, **kwargs): - """Nokia SR OS does not support enable-mode""" - return True + This is a bad idea for automation as what your program is sending no longer matches + the command echo from the device, so we disable this behavior. + """ + delay_factor = self.select_delay_factor(delay_factor=0) + time.sleep(delay_factor * 0.1) + command = "environment command-completion space false" + self.write_channel(self.normalize_cmd(command)) + time.sleep(delay_factor * 0.1) + return self.read_channel() + + def enable(self, cmd="enable", pattern="ssword", re_flags=re.IGNORECASE): + """Enable SR OS administrative mode""" + if "@" not in self.base_prompt: + cmd = "enable-admin" + return super().enable(cmd=cmd, pattern=pattern, re_flags=re_flags) + + def check_enable_mode(self, check_string="in admin mode"): + """Check if in enable mode.""" + cmd = "enable" + if "@" not in self.base_prompt: + cmd = "enable-admin" + self.write_channel(self.normalize_cmd(cmd)) + output = self.read_until_prompt_or_pattern(pattern="ssword") + if "ssword" in output: + self.write_channel(self.RETURN) # send ENTER to pass the password prompt + self.read_until_prompt() + return check_string in output def exit_enable_mode(self, *args, **kwargs): - """Nokia SR OS does not support enable-mode""" + """Nokia SR OS does not have a notion of exiting administrative mode""" return "" def config_mode(self, config_command="edit-config exclusive", pattern=r"\(ex\)\["): @@ -572,15 +602,23 @@ __all__ = ["NokiaSrosSSH", "NokiaSrosFileTransfer"]</code></pre> </details> </dd> <dt id="netmiko.nokia.NokiaSrosSSH.check_enable_mode"><code class="name flex"> -<span>def <span class="ident">check_enable_mode</span></span>(<span>self, *args, **kwargs)</span> +<span>def <span class="ident">check_enable_mode</span></span>(<span>self, check_string='in admin mode')</span> </code></dt> <dd> -<section class="desc"><p>Nokia SR OS does not support enable-mode</p></section> +<section class="desc"><p>Check if in enable mode.</p></section> <details class="source"> <summary>Source code</summary> -<pre><code class="python">def check_enable_mode(self, *args, **kwargs): - """Nokia SR OS does not support enable-mode""" - return True</code></pre> +<pre><code class="python">def check_enable_mode(self, check_string="in admin mode"): + """Check if in enable mode.""" + cmd = "enable" + if "@" not in self.base_prompt: + cmd = "enable-admin" + self.write_channel(self.normalize_cmd(cmd)) + output = self.read_until_prompt_or_pattern(pattern="ssword") + if "ssword" in output: + self.write_channel(self.RETURN) # send ENTER to pass the password prompt + self.read_until_prompt() + return check_string in output</code></pre> </details> </dd> <dt id="netmiko.nokia.NokiaSrosSSH.cleanup"><code class="name flex"> @@ -645,15 +683,17 @@ __all__ = ["NokiaSrosSSH", "NokiaSrosFileTransfer"]</code></pre> </details> </dd> <dt id="netmiko.nokia.NokiaSrosSSH.enable"><code class="name flex"> -<span>def <span class="ident">enable</span></span>(<span>self, *args, **kwargs)</span> +<span>def <span class="ident">enable</span></span>(<span>self, cmd='enable', pattern='ssword', re_flags=<RegexFlag.IGNORECASE: 2>)</span> </code></dt> <dd> -<section class="desc"><p>Nokia SR OS does not support enable-mode</p></section> +<section class="desc"><p>Enable SR OS administrative mode</p></section> <details class="source"> <summary>Source code</summary> -<pre><code class="python">def enable(self, *args, **kwargs): - """Nokia SR OS does not support enable-mode""" - return ""</code></pre> +<pre><code class="python">def enable(self, cmd="enable", pattern="ssword", re_flags=re.IGNORECASE): + """Enable SR OS administrative mode""" + if "@" not in self.base_prompt: + cmd = "enable-admin" + return super().enable(cmd=cmd, pattern=pattern, re_flags=re_flags)</code></pre> </details> </dd> <dt id="netmiko.nokia.NokiaSrosSSH.exit_config_mode"><code class="name flex"> @@ -687,11 +727,11 @@ __all__ = ["NokiaSrosSSH", "NokiaSrosFileTransfer"]</code></pre> <span>def <span class="ident">exit_enable_mode</span></span>(<span>self, *args, **kwargs)</span> </code></dt> <dd> -<section class="desc"><p>Nokia SR OS does not support enable-mode</p></section> +<section class="desc"><p>Nokia SR OS does not have a notion of exiting administrative mode</p></section> <details class="source"> <summary>Source code</summary> <pre><code class="python">def exit_enable_mode(self, *args, **kwargs): - """Nokia SR OS does not support enable-mode""" + """Nokia SR OS does not have a notion of exiting administrative mode""" return ""</code></pre> </details> </dd> diff --git a/docs/netmiko/nokia/nokia_sros_ssh.html b/docs/netmiko/nokia/nokia_sros_ssh.html index ac1637511e5b0791b2d860b5fad5418c50c45355..0f59ad2dec186e901c5f2c91256ce6e2abf205b9 100644 --- a/docs/netmiko/nokia/nokia_sros_ssh.html +++ b/docs/netmiko/nokia/nokia_sros_ssh.html @@ -24,9 +24,9 @@ <summary>Source code</summary> <pre><code class="python">#!/usr/bin/python # -*- coding: utf-8 -*- -# Copyright (c) 2014 - 2019 Kirk Byers -# Copyright (c) 2014 - 2019 Twin Bridges Technology -# Copyright (c) 2019 NOKIA Inc. +# Copyright (c) 2014 - 2020 Kirk Byers +# Copyright (c) 2014 - 2020 Twin Bridges Technology +# Copyright (c) 2019 - 2020 NOKIA Inc. # MIT License - See License file at: # https://github.com/ktbyers/netmiko/blob/develop/LICENSE @@ -44,9 +44,7 @@ class NokiaSrosSSH(BaseConnection): Implement methods for interacting with Nokia SR OS devices. Not applicable in Nokia SR OS (disabled): - - enable() - exit_enable_mode() - - check_enable_mode() Overriden methods to adapt Nokia SR OS behavior (changed): - session_preparation() @@ -57,6 +55,8 @@ class NokiaSrosSSH(BaseConnection): - save_config() - commit() - strip_prompt() + - enable() + - check_enable_mode() """ def session_preparation(self): @@ -64,12 +64,18 @@ class NokiaSrosSSH(BaseConnection): self.set_base_prompt() # "@" indicates model-driven CLI (vs Classical CLI) if "@" in self.base_prompt: + self._disable_complete_on_space() + self.set_terminal_width( + command="environment console width 512", pattern="environment" + ) self.disable_paging(command="environment more false") # To perform file operations we need to disable paging in classical-CLI also self.disable_paging(command="//environment no more") - self.set_terminal_width(command="environment console width 512") else: - self.disable_paging(command="environment no more") + # Classical CLI has no method to set the terminal width nor to disable command + # complete on space; consequently, cmd_verify needs disabled. + self.global_cmd_verify = False + self.disable_paging(command="environment no more", pattern="environment") # Clear the read buffer time.sleep(0.3 * self.global_delay_factor) @@ -84,16 +90,40 @@ class NokiaSrosSSH(BaseConnection): self.base_prompt = match.group(1) return self.base_prompt - def enable(self, *args, **kwargs): - """Nokia SR OS does not support enable-mode""" - return "" + def _disable_complete_on_space(self): + """ + SR-OS tries to auto complete commands when you type a "space" character. + + This is a bad idea for automation as what your program is sending no longer matches + the command echo from the device, so we disable this behavior. + """ + delay_factor = self.select_delay_factor(delay_factor=0) + time.sleep(delay_factor * 0.1) + command = "environment command-completion space false" + self.write_channel(self.normalize_cmd(command)) + time.sleep(delay_factor * 0.1) + return self.read_channel() + + def enable(self, cmd="enable", pattern="ssword", re_flags=re.IGNORECASE): + """Enable SR OS administrative mode""" + if "@" not in self.base_prompt: + cmd = "enable-admin" + return super().enable(cmd=cmd, pattern=pattern, re_flags=re_flags) - def check_enable_mode(self, *args, **kwargs): - """Nokia SR OS does not support enable-mode""" - return True + def check_enable_mode(self, check_string="in admin mode"): + """Check if in enable mode.""" + cmd = "enable" + if "@" not in self.base_prompt: + cmd = "enable-admin" + self.write_channel(self.normalize_cmd(cmd)) + output = self.read_until_prompt_or_pattern(pattern="ssword") + if "ssword" in output: + self.write_channel(self.RETURN) # send ENTER to pass the password prompt + self.read_until_prompt() + return check_string in output def exit_enable_mode(self, *args, **kwargs): - """Nokia SR OS does not support enable-mode""" + """Nokia SR OS does not have a notion of exiting administrative mode""" return "" def config_mode(self, config_command="edit-config exclusive", pattern=r"\(ex\)\["): @@ -509,9 +539,7 @@ class NokiaSrosFileTransfer(BaseFileTransfer): <dd> <section class="desc"><p>Implement methods for interacting with Nokia SR OS devices.</p> <p>Not applicable in Nokia SR OS (disabled): -- enable() -- exit_enable_mode() -- check_enable_mode()</p> +- exit_enable_mode()</p> <p>Overriden methods to adapt Nokia SR OS behavior (changed): - session_preparation() - set_base_prompt() @@ -520,7 +548,9 @@ class NokiaSrosFileTransfer(BaseFileTransfer): - check_config_mode() - save_config() - commit() -- strip_prompt()</p> +- strip_prompt() +- enable() +- check_enable_mode()</p> <pre><code> Initialize attributes for establishing connection to target device. :param ip: IP address of target device. Not required if `host` is @@ -658,9 +688,7 @@ class NokiaSrosFileTransfer(BaseFileTransfer): Implement methods for interacting with Nokia SR OS devices. Not applicable in Nokia SR OS (disabled): - - enable() - exit_enable_mode() - - check_enable_mode() Overriden methods to adapt Nokia SR OS behavior (changed): - session_preparation() @@ -671,6 +699,8 @@ class NokiaSrosFileTransfer(BaseFileTransfer): - save_config() - commit() - strip_prompt() + - enable() + - check_enable_mode() """ def session_preparation(self): @@ -678,12 +708,18 @@ class NokiaSrosFileTransfer(BaseFileTransfer): self.set_base_prompt() # "@" indicates model-driven CLI (vs Classical CLI) if "@" in self.base_prompt: + self._disable_complete_on_space() + self.set_terminal_width( + command="environment console width 512", pattern="environment" + ) self.disable_paging(command="environment more false") # To perform file operations we need to disable paging in classical-CLI also self.disable_paging(command="//environment no more") - self.set_terminal_width(command="environment console width 512") else: - self.disable_paging(command="environment no more") + # Classical CLI has no method to set the terminal width nor to disable command + # complete on space; consequently, cmd_verify needs disabled. + self.global_cmd_verify = False + self.disable_paging(command="environment no more", pattern="environment") # Clear the read buffer time.sleep(0.3 * self.global_delay_factor) @@ -698,16 +734,40 @@ class NokiaSrosFileTransfer(BaseFileTransfer): self.base_prompt = match.group(1) return self.base_prompt - def enable(self, *args, **kwargs): - """Nokia SR OS does not support enable-mode""" - return "" + def _disable_complete_on_space(self): + """ + SR-OS tries to auto complete commands when you type a "space" character. - def check_enable_mode(self, *args, **kwargs): - """Nokia SR OS does not support enable-mode""" - return True + This is a bad idea for automation as what your program is sending no longer matches + the command echo from the device, so we disable this behavior. + """ + delay_factor = self.select_delay_factor(delay_factor=0) + time.sleep(delay_factor * 0.1) + command = "environment command-completion space false" + self.write_channel(self.normalize_cmd(command)) + time.sleep(delay_factor * 0.1) + return self.read_channel() + + def enable(self, cmd="enable", pattern="ssword", re_flags=re.IGNORECASE): + """Enable SR OS administrative mode""" + if "@" not in self.base_prompt: + cmd = "enable-admin" + return super().enable(cmd=cmd, pattern=pattern, re_flags=re_flags) + + def check_enable_mode(self, check_string="in admin mode"): + """Check if in enable mode.""" + cmd = "enable" + if "@" not in self.base_prompt: + cmd = "enable-admin" + self.write_channel(self.normalize_cmd(cmd)) + output = self.read_until_prompt_or_pattern(pattern="ssword") + if "ssword" in output: + self.write_channel(self.RETURN) # send ENTER to pass the password prompt + self.read_until_prompt() + return check_string in output def exit_enable_mode(self, *args, **kwargs): - """Nokia SR OS does not support enable-mode""" + """Nokia SR OS does not have a notion of exiting administrative mode""" return "" def config_mode(self, config_command="edit-config exclusive", pattern=r"\(ex\)\["): @@ -848,15 +908,23 @@ class NokiaSrosFileTransfer(BaseFileTransfer): </details> </dd> <dt id="netmiko.nokia.nokia_sros_ssh.NokiaSrosSSH.check_enable_mode"><code class="name flex"> -<span>def <span class="ident">check_enable_mode</span></span>(<span>self, *args, **kwargs)</span> +<span>def <span class="ident">check_enable_mode</span></span>(<span>self, check_string='in admin mode')</span> </code></dt> <dd> -<section class="desc"><p>Nokia SR OS does not support enable-mode</p></section> +<section class="desc"><p>Check if in enable mode.</p></section> <details class="source"> <summary>Source code</summary> -<pre><code class="python">def check_enable_mode(self, *args, **kwargs): - """Nokia SR OS does not support enable-mode""" - return True</code></pre> +<pre><code class="python">def check_enable_mode(self, check_string="in admin mode"): + """Check if in enable mode.""" + cmd = "enable" + if "@" not in self.base_prompt: + cmd = "enable-admin" + self.write_channel(self.normalize_cmd(cmd)) + output = self.read_until_prompt_or_pattern(pattern="ssword") + if "ssword" in output: + self.write_channel(self.RETURN) # send ENTER to pass the password prompt + self.read_until_prompt() + return check_string in output</code></pre> </details> </dd> <dt id="netmiko.nokia.nokia_sros_ssh.NokiaSrosSSH.cleanup"><code class="name flex"> @@ -921,15 +989,17 @@ class NokiaSrosFileTransfer(BaseFileTransfer): </details> </dd> <dt id="netmiko.nokia.nokia_sros_ssh.NokiaSrosSSH.enable"><code class="name flex"> -<span>def <span class="ident">enable</span></span>(<span>self, *args, **kwargs)</span> +<span>def <span class="ident">enable</span></span>(<span>self, cmd='enable', pattern='ssword', re_flags=<RegexFlag.IGNORECASE: 2>)</span> </code></dt> <dd> -<section class="desc"><p>Nokia SR OS does not support enable-mode</p></section> +<section class="desc"><p>Enable SR OS administrative mode</p></section> <details class="source"> <summary>Source code</summary> -<pre><code class="python">def enable(self, *args, **kwargs): - """Nokia SR OS does not support enable-mode""" - return ""</code></pre> +<pre><code class="python">def enable(self, cmd="enable", pattern="ssword", re_flags=re.IGNORECASE): + """Enable SR OS administrative mode""" + if "@" not in self.base_prompt: + cmd = "enable-admin" + return super().enable(cmd=cmd, pattern=pattern, re_flags=re_flags)</code></pre> </details> </dd> <dt id="netmiko.nokia.nokia_sros_ssh.NokiaSrosSSH.exit_config_mode"><code class="name flex"> @@ -963,11 +1033,11 @@ class NokiaSrosFileTransfer(BaseFileTransfer): <span>def <span class="ident">exit_enable_mode</span></span>(<span>self, *args, **kwargs)</span> </code></dt> <dd> -<section class="desc"><p>Nokia SR OS does not support enable-mode</p></section> +<section class="desc"><p>Nokia SR OS does not have a notion of exiting administrative mode</p></section> <details class="source"> <summary>Source code</summary> <pre><code class="python">def exit_enable_mode(self, *args, **kwargs): - """Nokia SR OS does not support enable-mode""" + """Nokia SR OS does not have a notion of exiting administrative mode""" return ""</code></pre> </details> </dd> diff --git a/docs/netmiko/oneaccess/oneaccess_oneos.html b/docs/netmiko/oneaccess/oneaccess_oneos.html index 966e530ea893a5883397fe193cf176530ab0c135..b36328b7783d10f50f95604f33cb6b13c3e8db1d 100644 --- a/docs/netmiko/oneaccess/oneaccess_oneos.html +++ b/docs/netmiko/oneaccess/oneaccess_oneos.html @@ -39,8 +39,8 @@ class OneaccessOneOSBase(CiscoBaseConnection): """Prepare connection - disable paging""" self._test_channel_read() self.set_base_prompt() + self.set_terminal_width(command="stty columns 255", pattern="stty") self.disable_paging(command="term len 0") - self.set_terminal_width(command="stty columns 255") # Clear the read buffer time.sleep(0.3 * self.global_delay_factor) self.clear_buffer() @@ -89,8 +89,8 @@ class OneaccessOneOSTelnet(OneaccessOneOSBase): """Prepare connection - disable paging""" self._test_channel_read() self.set_base_prompt() + self.set_terminal_width(command="stty columns 255", pattern="stty") self.disable_paging(command="term len 0") - self.set_terminal_width(command="stty columns 255") # Clear the read buffer time.sleep(0.3 * self.global_delay_factor) self.clear_buffer() @@ -138,8 +138,8 @@ class OneaccessOneOSTelnet(OneaccessOneOSBase): """Prepare connection - disable paging""" self._test_channel_read() self.set_base_prompt() + self.set_terminal_width(command="stty columns 255", pattern="stty") self.disable_paging(command="term len 0") - self.set_terminal_width(command="stty columns 255") # Clear the read buffer time.sleep(0.3 * self.global_delay_factor) self.clear_buffer()</code></pre> diff --git a/docs/netmiko/ruijie/ruijie_os.html b/docs/netmiko/ruijie/ruijie_os.html index fd77a3832f8df6ff98d2784f8c389b745d2ca857..a6bfa1b94ca777226b492bf36d84565eae8f274d 100644 --- a/docs/netmiko/ruijie/ruijie_os.html +++ b/docs/netmiko/ruijie/ruijie_os.html @@ -35,8 +35,8 @@ class RuijieOSBase(CiscoBaseConnection): self.set_base_prompt() """Ruijie OS requires enable mode to set terminal width""" self.enable() + self.set_terminal_width(command="terminal width 256", pattern="terminal") self.disable_paging(command="terminal length 0") - self.set_terminal_width(command="terminal width 256") # Clear the read buffer time.sleep(0.3 * self.global_delay_factor) self.clear_buffer() @@ -214,8 +214,8 @@ class RuijieOSTelnet(RuijieOSBase): self.set_base_prompt() """Ruijie OS requires enable mode to set terminal width""" self.enable() + self.set_terminal_width(command="terminal width 256", pattern="terminal") self.disable_paging(command="terminal length 0") - self.set_terminal_width(command="terminal width 256") # Clear the read buffer time.sleep(0.3 * self.global_delay_factor) self.clear_buffer() @@ -265,8 +265,8 @@ class RuijieOSTelnet(RuijieOSBase): self.set_base_prompt() """Ruijie OS requires enable mode to set terminal width""" self.enable() + self.set_terminal_width(command="terminal width 256", pattern="terminal") self.disable_paging(command="terminal length 0") - self.set_terminal_width(command="terminal width 256") # Clear the read buffer time.sleep(0.3 * self.global_delay_factor) self.clear_buffer()</code></pre> diff --git a/docs/netmiko/scp_functions.html b/docs/netmiko/scp_functions.html index 87fbf95bafd3b95712e2764dd2429bfc7c560907..1630108d354dae46610a6911bee14c70271f7823 100644 --- a/docs/netmiko/scp_functions.html +++ b/docs/netmiko/scp_functions.html @@ -23,7 +23,6 @@ <p>Netmiko SCP operations.</p> <p>Supports file get and file put operations.</p> <p>SCP requires a separate SSH connection for a control channel.</p> -<p>Currently only supports Cisco IOS and Cisco ASA.</p> <details class="source"> <summary>Source code</summary> <pre><code class="python">""" @@ -32,8 +31,6 @@ Netmiko SCP operations. Supports file get and file put operations. SCP requires a separate SSH connection for a control channel. - -Currently only supports Cisco IOS and Cisco ASA. """ from netmiko import FileTransfer, InLineTransfer diff --git a/docs/netmiko/scp_handler.html b/docs/netmiko/scp_handler.html index 44e75ba8ed7fbeddca0d766420be6991e4da48e2..aa3533ce19423ae09457a65ead4a09472d3f3718 100644 --- a/docs/netmiko/scp_handler.html +++ b/docs/netmiko/scp_handler.html @@ -75,7 +75,14 @@ class SCPConn(object): def scp_get_file(self, source_file, dest_file): """Get file using SCP.""" - self.scp_client.get(source_file, dest_file) + platform = self.ssh_ctl_chan.device_type + if "cisco_ios" in platform or "cisco_xe" in platform: + try: + self.scp_client.get(source_file, dest_file) + except EOFError: + pass + else: + self.scp_client.get(source_file, dest_file) def scp_put_file(self, source_file, dest_file): """Put file using SCP.""" @@ -1187,7 +1194,14 @@ the string</p> def scp_get_file(self, source_file, dest_file): """Get file using SCP.""" - self.scp_client.get(source_file, dest_file) + platform = self.ssh_ctl_chan.device_type + if "cisco_ios" in platform or "cisco_xe" in platform: + try: + self.scp_client.get(source_file, dest_file) + except EOFError: + pass + else: + self.scp_client.get(source_file, dest_file) def scp_put_file(self, source_file, dest_file): """Put file using SCP.""" @@ -1240,7 +1254,14 @@ the string</p> <summary>Source code</summary> <pre><code class="python">def scp_get_file(self, source_file, dest_file): """Get file using SCP.""" - self.scp_client.get(source_file, dest_file)</code></pre> + platform = self.ssh_ctl_chan.device_type + if "cisco_ios" in platform or "cisco_xe" in platform: + try: + self.scp_client.get(source_file, dest_file) + except EOFError: + pass + else: + self.scp_client.get(source_file, dest_file)</code></pre> </details> </dd> <dt id="netmiko.scp_handler.SCPConn.scp_put_file"><code class="name flex"> diff --git a/docs/netmiko/ubiquiti/edge_ssh.html b/docs/netmiko/ubiquiti/edge_ssh.html index 4c5ffed5ead7fdce2783bd86357336b190f6968e..d42dbacd2f5bcd9cf585a2f415019fea553a018b 100644 --- a/docs/netmiko/ubiquiti/edge_ssh.html +++ b/docs/netmiko/ubiquiti/edge_ssh.html @@ -40,8 +40,8 @@ class UbiquitiEdgeSSH(CiscoSSHConnection): self.set_base_prompt() self.enable() self.set_base_prompt() - self.disable_paging() self.set_terminal_width() + self.disable_paging() # Clear the read buffer time.sleep(0.3 * self.global_delay_factor) @@ -233,8 +233,8 @@ class UbiquitiEdgeSSH(CiscoSSHConnection): self.set_base_prompt() self.enable() self.set_base_prompt() - self.disable_paging() self.set_terminal_width() + self.disable_paging() # Clear the read buffer time.sleep(0.3 * self.global_delay_factor) diff --git a/docs/netmiko/ubiquiti/index.html b/docs/netmiko/ubiquiti/index.html index f210c0491b4e35cf86cf493296497185759c9549..57d42e1808c05ac02714e5cf99607beed1367794 100644 --- a/docs/netmiko/ubiquiti/index.html +++ b/docs/netmiko/ubiquiti/index.html @@ -202,8 +202,8 @@ __all__ = ["UbiquitiEdgeSSH", "UnifiSwitchSSH", "UbiquitiUni self.set_base_prompt() self.enable() self.set_base_prompt() - self.disable_paging() self.set_terminal_width() + self.disable_paging() # Clear the read buffer time.sleep(0.3 * self.global_delay_factor) diff --git a/docs/netmiko/utilities.html b/docs/netmiko/utilities.html index c23c341bf8db7c86cb30d7b841edd49cb2271a85..15806fbeab4369e654e900cd78feca54d464b82c 100644 --- a/docs/netmiko/utilities.html +++ b/docs/netmiko/utilities.html @@ -30,7 +30,7 @@ import io import os from pathlib import Path import functools -import serial.tools.list_ports +from datetime import datetime from netmiko._textfsm import _clitable as clitable from netmiko._textfsm._clitable import CliTableError @@ -43,6 +43,14 @@ try: except ImportError: GENIE_INSTALLED = False +try: + import serial.tools.list_ports + + PYSERIAL_INSTALLED = True +except ImportError: + PYSERIAL_INSTALLED = False + + # Dictionary mapping 'show run' for vendors with different command SHOW_RUN_MAPPER = { "juniper": "show configuration", @@ -221,6 +229,14 @@ def write_bytes(out_data, encoding="ascii"): def check_serial_port(name): """returns valid COM Port.""" + + if not PYSERIAL_INSTALLED: + msg = ( + "\npyserial is not installed. Please PIP install pyserial:\n\n" + "pip install pyserial\n\n" + ) + raise ValueError(msg) + try: cdc = next(serial.tools.list_ports.grep(name)) return cdc[0] @@ -371,6 +387,31 @@ def select_cmd_verify(func): kwargs["cmd_verify"] = self.global_cmd_verify return func(self, *args, **kwargs) + return wrapper_decorator + + +def m_exec_time(func): + @functools.wraps(func) + def wrapper_decorator(self, *args, **kwargs): + start_time = datetime.now() + result = func(self, *args, **kwargs) + end_time = datetime.now() + method_name = str(func) + print(f"{method_name}: Elapsed time: {end_time - start_time}") + return result + + return wrapper_decorator + + +def f_exec_time(func): + @functools.wraps(func) + def wrapper_decorator(*args, **kwargs): + start_time = datetime.now() + result = func(*args, **kwargs) + end_time = datetime.now() + print(f"Elapsed time: {end_time - start_time}") + return result + return wrapper_decorator</code></pre> </details> </section> @@ -390,6 +431,14 @@ def select_cmd_verify(func): <summary>Source code</summary> <pre><code class="python">def check_serial_port(name): """returns valid COM Port.""" + + if not PYSERIAL_INSTALLED: + msg = ( + "\npyserial is not installed. Please PIP install pyserial:\n\n" + "pip install pyserial\n\n" + ) + raise ValueError(msg) + try: cdc = next(serial.tools.list_ports.grep(name)) return cdc[0] @@ -470,6 +519,25 @@ def select_cmd_verify(func): raise ValueError(f"{verify_dir} is not a directory")</code></pre> </details> </dd> +<dt id="netmiko.utilities.f_exec_time"><code class="name flex"> +<span>def <span class="ident">f_exec_time</span></span>(<span>func)</span> +</code></dt> +<dd> +<section class="desc"></section> +<details class="source"> +<summary>Source code</summary> +<pre><code class="python">def f_exec_time(func): + @functools.wraps(func) + def wrapper_decorator(*args, **kwargs): + start_time = datetime.now() + result = func(*args, **kwargs) + end_time = datetime.now() + print(f"Elapsed time: {end_time - start_time}") + return result + + return wrapper_decorator</code></pre> +</details> +</dd> <dt id="netmiko.utilities.find_cfg_file"><code class="name flex"> <span>def <span class="ident">find_cfg_file</span></span>(<span>file_name=None)</span> </code></dt> @@ -689,6 +757,26 @@ directory.""" sys.exit(f"Unable to open YAML file: {yaml_file}")</code></pre> </details> </dd> +<dt id="netmiko.utilities.m_exec_time"><code class="name flex"> +<span>def <span class="ident">m_exec_time</span></span>(<span>func)</span> +</code></dt> +<dd> +<section class="desc"></section> +<details class="source"> +<summary>Source code</summary> +<pre><code class="python">def m_exec_time(func): + @functools.wraps(func) + def wrapper_decorator(self, *args, **kwargs): + start_time = datetime.now() + result = func(self, *args, **kwargs) + end_time = datetime.now() + method_name = str(func) + print(f"{method_name}: Elapsed time: {end_time - start_time}") + return result + + return wrapper_decorator</code></pre> +</details> +</dd> <dt id="netmiko.utilities.obtain_all_devices"><code class="name flex"> <span>def <span class="ident">obtain_all_devices</span></span>(<span>my_devices)</span> </code></dt> @@ -797,6 +885,7 @@ directory.""" <li><code><a title="netmiko.utilities.clitable_to_dict" href="#netmiko.utilities.clitable_to_dict">clitable_to_dict</a></code></li> <li><code><a title="netmiko.utilities.display_inventory" href="#netmiko.utilities.display_inventory">display_inventory</a></code></li> <li><code><a title="netmiko.utilities.ensure_dir_exists" href="#netmiko.utilities.ensure_dir_exists">ensure_dir_exists</a></code></li> +<li><code><a title="netmiko.utilities.f_exec_time" href="#netmiko.utilities.f_exec_time">f_exec_time</a></code></li> <li><code><a title="netmiko.utilities.find_cfg_file" href="#netmiko.utilities.find_cfg_file">find_cfg_file</a></code></li> <li><code><a title="netmiko.utilities.find_netmiko_dir" href="#netmiko.utilities.find_netmiko_dir">find_netmiko_dir</a></code></li> <li><code><a title="netmiko.utilities.get_structured_data" href="#netmiko.utilities.get_structured_data">get_structured_data</a></code></li> @@ -804,6 +893,7 @@ directory.""" <li><code><a title="netmiko.utilities.get_template_dir" href="#netmiko.utilities.get_template_dir">get_template_dir</a></code></li> <li><code><a title="netmiko.utilities.load_devices" href="#netmiko.utilities.load_devices">load_devices</a></code></li> <li><code><a title="netmiko.utilities.load_yaml_file" href="#netmiko.utilities.load_yaml_file">load_yaml_file</a></code></li> +<li><code><a title="netmiko.utilities.m_exec_time" href="#netmiko.utilities.m_exec_time">m_exec_time</a></code></li> <li><code><a title="netmiko.utilities.obtain_all_devices" href="#netmiko.utilities.obtain_all_devices">obtain_all_devices</a></code></li> <li><code><a title="netmiko.utilities.obtain_netmiko_filename" href="#netmiko.utilities.obtain_netmiko_filename">obtain_netmiko_filename</a></code></li> <li><code><a title="netmiko.utilities.select_cmd_verify" href="#netmiko.utilities.select_cmd_verify">select_cmd_verify</a></code></li> diff --git a/docs/netmiko/vyos/index.html b/docs/netmiko/vyos/index.html index 63eba10d38389169c7fcf8b2504f3721372b25a3..83dfe0cbc50109afa92167e4eaed9ec5f40ecec1 100644 --- a/docs/netmiko/vyos/index.html +++ b/docs/netmiko/vyos/index.html @@ -188,8 +188,8 @@ __all__ = ["VyOSSSH"]</code></pre> """Prepare the session after the connection has been established.""" self._test_channel_read() self.set_base_prompt() + self.set_terminal_width(command="set terminal width 512", pattern="terminal") self.disable_paging(command="set terminal length 0") - self.set_terminal_width(command="set terminal width 512") # Clear the read buffer time.sleep(0.3 * self.global_delay_factor) self.clear_buffer() @@ -458,8 +458,8 @@ command_string = commit comment <comment></p></section> """Prepare the session after the connection has been established.""" self._test_channel_read() self.set_base_prompt() + self.set_terminal_width(command="set terminal width 512", pattern="terminal") self.disable_paging(command="set terminal length 0") - self.set_terminal_width(command="set terminal width 512") # Clear the read buffer time.sleep(0.3 * self.global_delay_factor) self.clear_buffer()</code></pre> diff --git a/docs/netmiko/vyos/vyos_ssh.html b/docs/netmiko/vyos/vyos_ssh.html index ac665440e13e3fbef264751b9245476bd7011b11..093c9b6a0f3780e8cdafceb3b8faefa6f1bc40b2 100644 --- a/docs/netmiko/vyos/vyos_ssh.html +++ b/docs/netmiko/vyos/vyos_ssh.html @@ -33,8 +33,8 @@ class VyOSSSH(CiscoSSHConnection): """Prepare the session after the connection has been established.""" self._test_channel_read() self.set_base_prompt() + self.set_terminal_width(command="set terminal width 512", pattern="terminal") self.disable_paging(command="set terminal length 0") - self.set_terminal_width(command="set terminal width 512") # Clear the read buffer time.sleep(0.3 * self.global_delay_factor) self.clear_buffer() @@ -284,8 +284,8 @@ class VyOSSSH(CiscoSSHConnection): """Prepare the session after the connection has been established.""" self._test_channel_read() self.set_base_prompt() + self.set_terminal_width(command="set terminal width 512", pattern="terminal") self.disable_paging(command="set terminal length 0") - self.set_terminal_width(command="set terminal width 512") # Clear the read buffer time.sleep(0.3 * self.global_delay_factor) self.clear_buffer() @@ -554,8 +554,8 @@ command_string = commit comment <comment></p></section> """Prepare the session after the connection has been established.""" self._test_channel_read() self.set_base_prompt() + self.set_terminal_width(command="set terminal width 512", pattern="terminal") self.disable_paging(command="set terminal length 0") - self.set_terminal_width(command="set terminal width 512") # Clear the read buffer time.sleep(0.3 * self.global_delay_factor) self.clear_buffer()</code></pre> diff --git a/netmiko/__init__.py b/netmiko/__init__.py index bfa164ce8096cdb6eb9d4382aef6eb80c32ad1f4..b3befa0e20c09ac7a11b141911f34708baafa6e1 100644 --- a/netmiko/__init__.py +++ b/netmiko/__init__.py @@ -23,7 +23,7 @@ from netmiko.scp_functions import file_transfer, progress_bar # Alternate naming Netmiko = ConnectHandler -__version__ = "3.2.0" +__version__ = "3.3.0" __all__ = ( "ConnectHandler", "ssh_dispatcher", diff --git a/netmiko/a10/a10_ssh.py b/netmiko/a10/a10_ssh.py index 2588bfd7a319a2d7af6990769ccee1e83d18f7c1..7f6a03b8e0c39b7562f9b1cd60446c3881ac215e 100644 --- a/netmiko/a10/a10_ssh.py +++ b/netmiko/a10/a10_ssh.py @@ -11,10 +11,10 @@ class A10SSH(CiscoSSHConnection): self._test_channel_read() self.set_base_prompt() self.enable() - self.disable_paging(command="terminal length 0") # Will not do anything without A10 specific command - self.set_terminal_width() + # self.set_terminal_width() + self.disable_paging(command="terminal length 0") # Clear the read buffer time.sleep(0.3 * self.global_delay_factor) diff --git a/netmiko/adtran/__init__.py b/netmiko/adtran/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..a80d312d5d83ce1f971df4003955eb1d187c0d2a --- /dev/null +++ b/netmiko/adtran/__init__.py @@ -0,0 +1,3 @@ +from netmiko.adtran.adtran import AdtranOSSSH + +__all__ = ["AdtranOSSSH"] diff --git a/netmiko/adtran/adtran.py b/netmiko/adtran/adtran.py new file mode 100644 index 0000000000000000000000000000000000000000..f6acd732fd0216342f86255b3937a433cde00e2b --- /dev/null +++ b/netmiko/adtran/adtran.py @@ -0,0 +1,51 @@ +import time +import re +from netmiko.cisco_base_connection import CiscoBaseConnection + + +class AdtranOSBase(CiscoBaseConnection): + def __init__(self, *args, **kwargs): + if kwargs.get("global_cmd_verify") is None: + kwargs["global_cmd_verify"] = False + return super().__init__(*args, **kwargs) + + def session_preparation(self): + """Prepare the session after the connection has been established.""" + self.ansi_escape_codes = True + self._test_channel_read() + self.set_base_prompt() + self.disable_paging(command="terminal length 0") + # Clear the read buffer + time.sleep(0.3 * self.global_delay_factor) + self.clear_buffer() + + def check_enable_mode(self, check_string="#"): + return super().check_enable_mode(check_string=check_string) + + def enable(self, cmd="enable", pattern="", re_flags=re.IGNORECASE): + return super().enable(cmd=cmd, pattern=pattern, re_flags=re_flags) + + def exit_enable_mode(self, exit_command="disable"): + return super().exit_enable_mode(exit_command=exit_command) + + def check_config_mode(self, check_string=")#"): + return super().check_config_mode(check_string=check_string) + + def config_mode(self, config_command="config term", pattern=""): + return super().config_mode(config_command=config_command, pattern=pattern) + + def exit_config_mode(self, exit_config="end", pattern="#"): + return super().exit_config_mode(exit_config=exit_config, pattern=pattern) + + def set_base_prompt( + self, pri_prompt_terminator=">", alt_prompt_terminator="#", **kwargs + ): + return super().set_base_prompt( + pri_prompt_terminator=pri_prompt_terminator, + alt_prompt_terminator=alt_prompt_terminator, + **kwargs + ) + + +class AdtranOSSSH(AdtranOSBase): + pass diff --git a/netmiko/arista/arista.py b/netmiko/arista/arista.py index 695637a2b094e2b4e94633ab3baa391221d991e1..ecba8f5cae6e450ddd247268812215a86962e1a0 100644 --- a/netmiko/arista/arista.py +++ b/netmiko/arista/arista.py @@ -8,8 +8,8 @@ class AristaBase(CiscoSSHConnection): """Prepare the session after the connection has been established.""" self._test_channel_read(pattern=r"[>#]") self.set_base_prompt() + self.set_terminal_width(command="terminal width 511", pattern="terminal") self.disable_paging() - self.set_terminal_width(command="terminal width 511") # Clear the read buffer time.sleep(0.3 * self.global_delay_factor) self.clear_buffer() diff --git a/netmiko/base_connection.py b/netmiko/base_connection.py index 9f46e281b1f90eac2284b5a1f73c7ab8bc08e5eb..c278f6900caae74e8ddba068e626d323bb8eeae8 100644 --- a/netmiko/base_connection.py +++ b/netmiko/base_connection.py @@ -31,6 +31,7 @@ from netmiko.utilities import ( get_structured_data_genie, select_cmd_verify, ) +from netmiko.utilities import m_exec_time # noqa class BaseConnection(object): @@ -78,6 +79,7 @@ class BaseConnection(object): response_return=None, serial_settings=None, fast_cli=False, + _legacy_mode=True, session_log=None, session_log_record_writes=False, session_log_file_mode="write", @@ -297,6 +299,7 @@ class BaseConnection(object): self.serial_settings.update({"port": comm_port}) self.fast_cli = fast_cli + self._legacy_mode = _legacy_mode self.global_delay_factor = global_delay_factor self.global_cmd_verify = global_cmd_verify if self.fast_cli and self.global_delay_factor == 1: @@ -790,8 +793,8 @@ class BaseConnection(object): """ self._test_channel_read() self.set_base_prompt() - self.disable_paging() self.set_terminal_width() + self.disable_paging() # Clear the read buffer time.sleep(0.3 * self.global_delay_factor) @@ -935,11 +938,29 @@ Device settings: {self.device_type} {self.host}:{self.port} msg = msg.lstrip() raise NetmikoTimeoutException(msg) + except paramiko.ssh_exception.SSHException as no_session_err: + self.paramiko_cleanup() + if "No existing session" in str(no_session_err): + msg = ( + "Paramiko: 'No existing session' error: " + "try increasing 'conn_timeout' to 10 seconds or larger." + ) + raise NetmikoTimeoutException(msg) + else: + raise except paramiko.ssh_exception.AuthenticationException as auth_err: self.paramiko_cleanup() - msg = "Authentication failure: unable to connect {device_type} {ip}:{port}".format( - device_type=self.device_type, ip=self.host, port=self.port - ) + msg = f"""Authentication to device failed. + +Common causes of this problem are: +1. Invalid username and password +2. Incorrect SSH-key file +3. Connecting to the wrong device + +Device settings: {self.device_type} {self.host}:{self.port} + +""" + msg += self.RETURN + str(auth_err) raise NetmikoAuthenticationException(msg) @@ -1038,7 +1059,9 @@ Device settings: {self.device_type} {self.host}:{self.port} """Handler for devices like WLC, Extreme ERS that throw up characters prior to login.""" pass - def disable_paging(self, command="terminal length 0", delay_factor=1): + def disable_paging( + self, command="terminal length 0", delay_factor=1, cmd_verify=True, pattern=None + ): """Disable paging default to a Cisco CLI method. :param command: Device command to disable pagination of output @@ -1048,19 +1071,24 @@ Device settings: {self.device_type} {self.host}:{self.port} :type delay_factor: int """ 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(f"Command: {command}") self.write_channel(command) - # Do not use command_verify here as still in session_preparation stage. - output = self.read_until_prompt() + # Make sure you read until you detect the command echo (avoid getting out of sync) + if cmd_verify and self.global_cmd_verify is not False: + output = self.read_until_pattern(pattern=re.escape(command.strip())) + elif pattern: + output = self.read_until_pattern(pattern=pattern) + else: + output = self.read_until_prompt() log.debug(f"{output}") log.debug("Exiting disable_paging") return output - def set_terminal_width(self, command="", delay_factor=1): + def set_terminal_width( + self, command="", delay_factor=1, cmd_verify=False, pattern=None + ): """CLI terminals try to automatically adjust the line based on the width of the terminal. This causes the output to get distorted when accessed programmatically. @@ -1077,8 +1105,13 @@ Device settings: {self.device_type} {self.host}:{self.port} delay_factor = self.select_delay_factor(delay_factor) command = self.normalize_cmd(command) self.write_channel(command) - # Do not use command_verify here as still in session_preparation stage. - output = self.read_until_prompt() + # Avoid cmd_verify here as terminal width must be set before doing cmd_verify + if cmd_verify and self.global_cmd_verify is not False: + output = self.read_until_pattern(pattern=re.escape(command.strip())) + elif pattern: + output = self.read_until_pattern(pattern=pattern) + else: + output = self.read_until_prompt() return output def set_base_prompt( @@ -1123,11 +1156,10 @@ Device settings: {self.device_type} {self.host}:{self.port} time.sleep(sleep_time) # Initial attempt to get prompt - prompt = self.read_channel() + prompt = self.read_channel().strip() # Check if the only thing you received was a newline count = 0 - prompt = prompt.strip() while count <= 12 and not prompt: prompt = self.read_channel().strip() if not prompt: @@ -1759,7 +1791,7 @@ Device settings: {self.device_type} {self.host}:{self.port} cfg_mode_args = (config_mode_command,) if config_mode_command else tuple() output += self.config_mode(*cfg_mode_args) - if self.fast_cli: + if self.fast_cli and self._legacy_mode: for cmd in config_commands: self.write_channel(self.normalize_cmd(cmd)) # Gather output diff --git a/netmiko/broadcom/broadcom_icos_ssh.py b/netmiko/broadcom/broadcom_icos_ssh.py index 10c2b8fea2f81e269b635ef3a279c16e585116db..f8f12d0341fc58ec20d9fd6dc809e0b1ebc24e39 100644 --- a/netmiko/broadcom/broadcom_icos_ssh.py +++ b/netmiko/broadcom/broadcom_icos_ssh.py @@ -13,8 +13,8 @@ class BroadcomIcosSSH(CiscoSSHConnection): self.set_base_prompt() self.enable() self.set_base_prompt() - self.disable_paging() self.set_terminal_width() + self.disable_paging() # Clear the read buffer time.sleep(0.3 * self.global_delay_factor) diff --git a/netmiko/calix/calix_b6.py b/netmiko/calix/calix_b6.py index c49cde0c6863e0676c46b1cdac0630f9a9d8cabc..7392cd9ab55eab7c8768f65ec5a031bcae0a43b1 100644 --- a/netmiko/calix/calix_b6.py +++ b/netmiko/calix/calix_b6.py @@ -28,8 +28,8 @@ class CalixB6Base(CiscoSSHConnection): self.ansi_escape_codes = True self._test_channel_read() self.set_base_prompt() + self.set_terminal_width(command="terminal width 511", pattern="terminal") self.disable_paging() - self.set_terminal_width(command="terminal width 511") # Clear the read buffer time.sleep(0.3 * self.global_delay_factor) self.clear_buffer() diff --git a/netmiko/cisco/cisco_asa_ssh.py b/netmiko/cisco/cisco_asa_ssh.py index cdad7a3d19679e0da07fb604dc47a7603be79460..54c15540b42cfe6cf6a371adca5455a8b5de3b75 100644 --- a/netmiko/cisco/cisco_asa_ssh.py +++ b/netmiko/cisco/cisco_asa_ssh.py @@ -12,11 +12,12 @@ class CiscoAsaSSH(CiscoSSHConnection): """Prepare the session after the connection has been established.""" self._test_channel_read() self.set_base_prompt() + if self.secret: self.enable() else: self.asa_login() - self.disable_paging(command="terminal pager 0") + if self.allow_auto_change: try: self.send_config_set("terminal width 511") @@ -27,6 +28,8 @@ class CiscoAsaSSH(CiscoSSHConnection): # Disable cmd_verify if the terminal width can't be set self.global_cmd_verify = False + self.disable_paging(command="terminal pager 0") + # Clear the read buffer time.sleep(0.3 * self.global_delay_factor) self.clear_buffer() diff --git a/netmiko/cisco/cisco_ios.py b/netmiko/cisco/cisco_ios.py index 0d4e2b9cdef0e819e8e65c820fa85bbe591a7138..baf957d41cb008f72feca1df25b811d2dbf5f8db 100644 --- a/netmiko/cisco/cisco_ios.py +++ b/netmiko/cisco/cisco_ios.py @@ -10,15 +10,18 @@ from netmiko.cisco_base_connection import CiscoBaseConnection, CiscoFileTransfer class CiscoIosBase(CiscoBaseConnection): """Common Methods for IOS (both SSH and telnet).""" + def __init__(self, *args, **kwargs): + # Cisco-IOS defaults to fast_cli=True and legacy_mode=False + kwargs.setdefault("fast_cli", True) + kwargs.setdefault("_legacy_mode", False) + return super().__init__(*args, **kwargs) + def session_preparation(self): """Prepare the session after the connection has been established.""" - self._test_channel_read(pattern=r"[>#]") - self.set_base_prompt() + cmd = "terminal width 511" + self.set_terminal_width(command=cmd, pattern=cmd) self.disable_paging() - self.set_terminal_width(command="terminal width 511") - # Clear the read buffer - time.sleep(0.3 * self.global_delay_factor) - self.clear_buffer() + self.set_base_prompt() def check_config_mode(self, check_string=")#", pattern="#"): """ diff --git a/netmiko/cisco/cisco_nxos_ssh.py b/netmiko/cisco/cisco_nxos_ssh.py index 0f6abab91d9bf9ff9c4ddcf89f49259e3487c4ea..8df4e5a4b644693a658e86690a04da37fce38e8b 100644 --- a/netmiko/cisco/cisco_nxos_ssh.py +++ b/netmiko/cisco/cisco_nxos_ssh.py @@ -11,8 +11,8 @@ class CiscoNxosSSH(CiscoSSHConnection): self._test_channel_read(pattern=r"[>#]") self.ansi_escape_codes = True self.set_base_prompt() + self.set_terminal_width(command="terminal width 511", pattern="terminal") self.disable_paging() - self.set_terminal_width(command="terminal width 511") # Clear the read buffer time.sleep(0.3 * self.global_delay_factor) self.clear_buffer() diff --git a/netmiko/cisco/cisco_s300.py b/netmiko/cisco/cisco_s300.py index 97599f8a7d799e831c9b3d1f9d779ad022c97d30..eb4aa41d4c6ffc2128e6c25b31c3cc60c918113c 100644 --- a/netmiko/cisco/cisco_s300.py +++ b/netmiko/cisco/cisco_s300.py @@ -17,8 +17,8 @@ class CiscoS300SSH(CiscoSSHConnection): self.ansi_escape_codes = True self._test_channel_read() self.set_base_prompt() + self.set_terminal_width(command="terminal width 511", pattern="terminal") self.disable_paging(command="terminal datadump") - self.set_terminal_width(command="terminal width 511") # Clear the read buffer time.sleep(0.3 * self.global_delay_factor) diff --git a/netmiko/cisco/cisco_tp_tcce.py b/netmiko/cisco/cisco_tp_tcce.py index 1043deecbf7980617145c5f90581c49d9f56d20b..4a607c8d4d6862a751c07cbfb70c65bc28387663 100644 --- a/netmiko/cisco/cisco_tp_tcce.py +++ b/netmiko/cisco/cisco_tp_tcce.py @@ -34,8 +34,8 @@ class CiscoTpTcCeSSH(CiscoSSHConnection): """ self._test_channel_read() self.set_base_prompt() - self.disable_paging() self.set_terminal_width() + self.disable_paging() # Clear the read buffer time.sleep(0.3 * self.global_delay_factor) self.clear_buffer() diff --git a/netmiko/cisco/cisco_wlc_ssh.py b/netmiko/cisco/cisco_wlc_ssh.py index b669d43cb0b2563df503aba41adc09ea2c8faacc..77126791ab5c37c8b1190ca07c84bee41cc24bca 100644 --- a/netmiko/cisco/cisco_wlc_ssh.py +++ b/netmiko/cisco/cisco_wlc_ssh.py @@ -10,6 +10,12 @@ from netmiko.base_connection import BaseConnection class CiscoWlcSSH(BaseConnection): """Netmiko Cisco WLC support.""" + def __init__(self, *args, **kwargs): + # WLC/AireOS has an issue where you can get "No Existing Session" with + # the default conn_timeout (so increase conn_timeout to 10-seconds). + kwargs.setdefault("conn_timeout", 10) + return super().__init__(*args, **kwargs) + def special_login_handler(self, delay_factor=1): """WLC presents with the following on login (in certain OS versions) diff --git a/netmiko/cisco/cisco_xr.py b/netmiko/cisco/cisco_xr.py index e6986098c4edfe8463e0689f2562185bfc279769..de2644add22d32a41eae3d40bcca5849bcee330c 100644 --- a/netmiko/cisco/cisco_xr.py +++ b/netmiko/cisco/cisco_xr.py @@ -4,12 +4,16 @@ from netmiko.cisco_base_connection import CiscoBaseConnection, CiscoFileTransfer class CiscoXrBase(CiscoBaseConnection): + def establish_connection(self): + """Establish SSH connection to the network device""" + super().establish_connection(width=511, height=511) + def session_preparation(self): """Prepare the session after the connection has been established.""" self._test_channel_read() self.set_base_prompt() + self.set_terminal_width(command="terminal width 511", pattern="terminal") self.disable_paging() - self.set_terminal_width(command="terminal width 511") # Clear the read buffer time.sleep(0.3 * self.global_delay_factor) self.clear_buffer() @@ -64,12 +68,6 @@ class CiscoXrBase(CiscoBaseConnection): if comment and confirm: raise ValueError("Invalid arguments supplied to XR commit") - # wrap the comment in quotes - if comment: - if '"' in comment: - raise ValueError("Invalid comment contains double quote") - comment = f'"{comment}"' - label = str(label) error_marker = "Failed to" alt_error_marker = "One or more commits have occurred from other" diff --git a/netmiko/dell/dell_dnos6.py b/netmiko/dell/dell_dnos6.py index ff341e2d19bb5df4e0c2ea1ceae5cd9fc303a631..b02b80cf6e713529b70c5f1956faa25b9cc1d616 100644 --- a/netmiko/dell/dell_dnos6.py +++ b/netmiko/dell/dell_dnos6.py @@ -10,8 +10,8 @@ class DellDNOS6Base(DellPowerConnectBase): self._test_channel_read() self.set_base_prompt() self.enable() - self.disable_paging(command="terminal length 0") self.set_terminal_width() + self.disable_paging(command="terminal length 0") # Clear the read buffer time.sleep(0.3 * self.global_delay_factor) self.clear_buffer() diff --git a/netmiko/extreme/extreme_wing_ssh.py b/netmiko/extreme/extreme_wing_ssh.py index e1c5b64a2e69d1c450fa94ab66c4b634de10bb63..e83784e7c7c841d358ae42da200e732ecea2f2e0 100644 --- a/netmiko/extreme/extreme_wing_ssh.py +++ b/netmiko/extreme/extreme_wing_ssh.py @@ -9,7 +9,7 @@ class ExtremeWingSSH(CiscoSSHConnection): """Disable paging and set Max term width""" self._test_channel_read(pattern=r">|#") self.set_base_prompt() + self.set_terminal_width(command="terminal width 512", pattern="terminal") self.disable_paging(command="no page") - self.set_terminal_width(command="terminal width 512") time.sleep(0.3 * self.global_delay_factor) self.clear_buffer() diff --git a/netmiko/f5/f5_tmsh_ssh.py b/netmiko/f5/f5_tmsh_ssh.py index 819bea891926649c38612d38c88f749261980a3e..9885cbec9d0eadf9277fec058bc37a20d6af613b 100644 --- a/netmiko/f5/f5_tmsh_ssh.py +++ b/netmiko/f5/f5_tmsh_ssh.py @@ -9,12 +9,12 @@ class F5TmshSSH(BaseConnection): self.set_base_prompt() self.tmsh_mode() self.set_base_prompt() + cmd = 'run /util bash -c "stty cols 255"' + self.set_terminal_width(command=cmd, pattern="run") self.disable_paging( command="modify cli preference pager disabled display-threshold 0" ) self.clear_buffer() - cmd = 'run /util bash -c "stty cols 255"' - self.set_terminal_width(command=cmd) def tmsh_mode(self, delay_factor=1): """tmsh command is equivalent to config command on F5.""" diff --git a/netmiko/flexvnf/flexvnf_ssh.py b/netmiko/flexvnf/flexvnf_ssh.py index a70e4ad7feadfc088e2d01952cf75d4fda2281ab..177bcaab8cc9ab27ec8b82af15b64622a260bd9d 100644 --- a/netmiko/flexvnf/flexvnf_ssh.py +++ b/netmiko/flexvnf/flexvnf_ssh.py @@ -15,8 +15,8 @@ class FlexvnfSSH(BaseConnection): self._test_channel_read() self.enter_cli_mode() self.set_base_prompt() + self.set_terminal_width(command="set screen width 511", pattern="set") self.disable_paging(command="set screen length 0") - self.set_terminal_width(command="set screen width 511") # Clear the read buffer time.sleep(0.3 * self.global_delay_factor) self.clear_buffer() diff --git a/netmiko/hp/hp_procurve.py b/netmiko/hp/hp_procurve.py index abf01f7dacb6ea01311826d209566c707bd92688..09b79017ed90073bbd0f6044e39382821f9b799d 100644 --- a/netmiko/hp/hp_procurve.py +++ b/netmiko/hp/hp_procurve.py @@ -26,8 +26,8 @@ class HPProcurveBase(CiscoSSHConnection): self._test_channel_read(pattern=r"[>#]") self.set_base_prompt() command = self.RETURN + "no page" + self.set_terminal_width(command="terminal width 511", pattern="terminal") self.disable_paging(command=command) - self.set_terminal_width(command="terminal width 511") # Clear the read buffer time.sleep(0.3 * self.global_delay_factor) self.clear_buffer() diff --git a/netmiko/juniper/juniper.py b/netmiko/juniper/juniper.py index 14d1134201abb6b4d744262129b6217302d0d594..c012ce1fa6dcd31684a4d1f9217c1813c227bfb1 100644 --- a/netmiko/juniper/juniper.py +++ b/netmiko/juniper/juniper.py @@ -24,8 +24,8 @@ class JuniperBase(BaseConnection): self.enter_cli_mode() self.set_base_prompt() self._disable_complete_on_space() + self.set_terminal_width(command="set cli screen-width 511", pattern="set") self.disable_paging(command="set cli screen-length 0") - self.set_terminal_width(command="set cli screen-width 511") # Clear the read buffer time.sleep(0.3 * self.global_delay_factor) self.clear_buffer() diff --git a/netmiko/netgear/__init__.py b/netmiko/netgear/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e1a1cd1f1860964c991589dbd54d516193bfceb4 --- /dev/null +++ b/netmiko/netgear/__init__.py @@ -0,0 +1,3 @@ +from netmiko.netgear.netgear_prosafe_ssh import NetgearProSafeSSH + +__all__ = ["NetgearProSafeSSH"] diff --git a/netmiko/netgear/netgear_prosafe_ssh.py b/netmiko/netgear/netgear_prosafe_ssh.py new file mode 100644 index 0000000000000000000000000000000000000000..b25110a921fbfbda981cc33c759082a17fcfc501 --- /dev/null +++ b/netmiko/netgear/netgear_prosafe_ssh.py @@ -0,0 +1,44 @@ +"""ProSafe OS support""" +import time +from netmiko.cisco_base_connection import CiscoSSHConnection + + +class NetgearProSafeSSH(CiscoSSHConnection): + """ProSafe OS support""" + + def __init__(self, **kwargs): + if kwargs.get("default_enter") is None: + kwargs["default_enter"] = "\r" + return super().__init__(**kwargs) + + def session_preparation(self): + """ProSafe OS requires enabe mode to disable paging.""" + self._test_channel_read() + self.set_base_prompt() + self.enable() + self.disable_paging(command="terminal length 0") + + # Clear the read buffer + time.sleep(0.3 * self.global_delay_factor) + self.clear_buffer() + + def check_config_mode(self, check_string="(Config)#"): + return super().check_config_mode(check_string=check_string) + + def config_mode(self, config_command="configure", pattern=r")#"): + return super().config_mode(config_command=config_command, pattern=pattern) + + def exit_config_mode(self, exit_config="exit", pattern="#"): + return super().exit_config_mode(exit_config=exit_config, pattern=pattern) + + def save_config( + self, save_cmd="write memory confirm", confirm=False, confirm_response="" + ): + self.enable() + """ProSafe doesn't allow saving whilst within configuration mode""" + if self.check_config_mode(): + self.exit_config_mode() + + return super().save_config( + cmd=save_cmd, confirm=confirm, confirm_response=confirm_response + ) diff --git a/netmiko/nokia/nokia_sros_ssh.py b/netmiko/nokia/nokia_sros_ssh.py index 98117867b323f2c673d264bea342a624ca26c41d..3a9b59ca8eb316a4e125fe64a418af5b7ba8d375 100755 --- a/netmiko/nokia/nokia_sros_ssh.py +++ b/netmiko/nokia/nokia_sros_ssh.py @@ -1,8 +1,8 @@ #!/usr/bin/python # -*- coding: utf-8 -*- -# Copyright (c) 2014 - 2019 Kirk Byers -# Copyright (c) 2014 - 2019 Twin Bridges Technology -# Copyright (c) 2019 NOKIA Inc. +# Copyright (c) 2014 - 2020 Kirk Byers +# Copyright (c) 2014 - 2020 Twin Bridges Technology +# Copyright (c) 2019 - 2020 NOKIA Inc. # MIT License - See License file at: # https://github.com/ktbyers/netmiko/blob/develop/LICENSE @@ -20,9 +20,7 @@ class NokiaSrosSSH(BaseConnection): Implement methods for interacting with Nokia SR OS devices. Not applicable in Nokia SR OS (disabled): - - enable() - exit_enable_mode() - - check_enable_mode() Overriden methods to adapt Nokia SR OS behavior (changed): - session_preparation() @@ -33,6 +31,8 @@ class NokiaSrosSSH(BaseConnection): - save_config() - commit() - strip_prompt() + - enable() + - check_enable_mode() """ def session_preparation(self): @@ -40,12 +40,18 @@ class NokiaSrosSSH(BaseConnection): self.set_base_prompt() # "@" indicates model-driven CLI (vs Classical CLI) if "@" in self.base_prompt: + self._disable_complete_on_space() + self.set_terminal_width( + command="environment console width 512", pattern="environment" + ) self.disable_paging(command="environment more false") # To perform file operations we need to disable paging in classical-CLI also self.disable_paging(command="//environment no more") - self.set_terminal_width(command="environment console width 512") else: - self.disable_paging(command="environment no more") + # Classical CLI has no method to set the terminal width nor to disable command + # complete on space; consequently, cmd_verify needs disabled. + self.global_cmd_verify = False + self.disable_paging(command="environment no more", pattern="environment") # Clear the read buffer time.sleep(0.3 * self.global_delay_factor) @@ -60,16 +66,40 @@ class NokiaSrosSSH(BaseConnection): self.base_prompt = match.group(1) return self.base_prompt - def enable(self, *args, **kwargs): - """Nokia SR OS does not support enable-mode""" - return "" + def _disable_complete_on_space(self): + """ + SR-OS tries to auto complete commands when you type a "space" character. - def check_enable_mode(self, *args, **kwargs): - """Nokia SR OS does not support enable-mode""" - return True + This is a bad idea for automation as what your program is sending no longer matches + the command echo from the device, so we disable this behavior. + """ + delay_factor = self.select_delay_factor(delay_factor=0) + time.sleep(delay_factor * 0.1) + command = "environment command-completion space false" + self.write_channel(self.normalize_cmd(command)) + time.sleep(delay_factor * 0.1) + return self.read_channel() + + def enable(self, cmd="enable", pattern="ssword", re_flags=re.IGNORECASE): + """Enable SR OS administrative mode""" + if "@" not in self.base_prompt: + cmd = "enable-admin" + return super().enable(cmd=cmd, pattern=pattern, re_flags=re_flags) + + def check_enable_mode(self, check_string="in admin mode"): + """Check if in enable mode.""" + cmd = "enable" + if "@" not in self.base_prompt: + cmd = "enable-admin" + self.write_channel(self.normalize_cmd(cmd)) + output = self.read_until_prompt_or_pattern(pattern="ssword") + if "ssword" in output: + self.write_channel(self.RETURN) # send ENTER to pass the password prompt + self.read_until_prompt() + return check_string in output def exit_enable_mode(self, *args, **kwargs): - """Nokia SR OS does not support enable-mode""" + """Nokia SR OS does not have a notion of exiting administrative mode""" return "" def config_mode(self, config_command="edit-config exclusive", pattern=r"\(ex\)\["): diff --git a/netmiko/oneaccess/oneaccess_oneos.py b/netmiko/oneaccess/oneaccess_oneos.py index bb3acb438dc217d712ebe217e6d8f696de9cb296..9c9a08e5f78dd7c4bad7a011d0b1dd1f3cc62b30 100644 --- a/netmiko/oneaccess/oneaccess_oneos.py +++ b/netmiko/oneaccess/oneaccess_oneos.py @@ -14,8 +14,8 @@ class OneaccessOneOSBase(CiscoBaseConnection): """Prepare connection - disable paging""" self._test_channel_read() self.set_base_prompt() + self.set_terminal_width(command="stty columns 255", pattern="stty") self.disable_paging(command="term len 0") - self.set_terminal_width(command="stty columns 255") # Clear the read buffer time.sleep(0.3 * self.global_delay_factor) self.clear_buffer() diff --git a/netmiko/ruijie/ruijie_os.py b/netmiko/ruijie/ruijie_os.py index 8d2b51ee00646d572fa5e17f56fd1adb64707f6d..96f2896d21e3d537b3733a2bf96a4b64b43d0b51 100644 --- a/netmiko/ruijie/ruijie_os.py +++ b/netmiko/ruijie/ruijie_os.py @@ -10,8 +10,8 @@ class RuijieOSBase(CiscoBaseConnection): self.set_base_prompt() """Ruijie OS requires enable mode to set terminal width""" self.enable() + self.set_terminal_width(command="terminal width 256", pattern="terminal") self.disable_paging(command="terminal length 0") - self.set_terminal_width(command="terminal width 256") # Clear the read buffer time.sleep(0.3 * self.global_delay_factor) self.clear_buffer() diff --git a/netmiko/scp_functions.py b/netmiko/scp_functions.py index 6b50920b0f693e6d6359910ecbef4ab4dc904477..37f49712bb420955d4b3ff2216b46b44efe35afb 100644 --- a/netmiko/scp_functions.py +++ b/netmiko/scp_functions.py @@ -4,8 +4,6 @@ Netmiko SCP operations. Supports file get and file put operations. SCP requires a separate SSH connection for a control channel. - -Currently only supports Cisco IOS and Cisco ASA. """ from netmiko import FileTransfer, InLineTransfer diff --git a/netmiko/scp_handler.py b/netmiko/scp_handler.py index 11c49fb789c2002aa6d428fa9bc18023ab1ca5e1..70d387333584e8a3290c44e67e05eeaaa392ebc5 100644 --- a/netmiko/scp_handler.py +++ b/netmiko/scp_handler.py @@ -47,7 +47,14 @@ class SCPConn(object): def scp_get_file(self, source_file, dest_file): """Get file using SCP.""" - self.scp_client.get(source_file, dest_file) + platform = self.ssh_ctl_chan.device_type + if "cisco_ios" in platform or "cisco_xe" in platform: + try: + self.scp_client.get(source_file, dest_file) + except EOFError: + pass + else: + self.scp_client.get(source_file, dest_file) def scp_put_file(self, source_file, dest_file): """Put file using SCP.""" diff --git a/netmiko/ssh_dispatcher.py b/netmiko/ssh_dispatcher.py index b1992faf13a6e6967210abd7a36346e2e0c31476..908f06a9c461ece9226845fd44fc8bc76aefc52f 100755 --- a/netmiko/ssh_dispatcher.py +++ b/netmiko/ssh_dispatcher.py @@ -1,6 +1,7 @@ """Controls selection of proper class based on the device type.""" from netmiko.a10 import A10SSH from netmiko.accedian import AccedianSSH +from netmiko.adtran import AdtranOSSSH from netmiko.alcatel import AlcatelAosSSH from netmiko.arista import AristaSSH, AristaTelnet from netmiko.arista import AristaFileTransfer @@ -65,6 +66,7 @@ from netmiko.mrv import MrvLxSSH from netmiko.mrv import MrvOptiswitchSSH from netmiko.netapp import NetAppcDotSSH from netmiko.nokia import NokiaSrosSSH, NokiaSrosFileTransfer +from netmiko.netgear import NetgearProSafeSSH from netmiko.oneaccess import OneaccessOneOSTelnet, OneaccessOneOSSSH from netmiko.ovs import OvsLinuxSSH from netmiko.paloalto import PaloAltoPanosSSH @@ -98,6 +100,7 @@ GenericTelnet = TerminalServerTelnet CLASS_MAPPER_BASE = { "a10": A10SSH, "accedian": AccedianSSH, + "adtran_os": AdtranOSSSH, "alcatel_aos": AlcatelAosSSH, "alcatel_sros": NokiaSrosSSH, "apresia_aeos": ApresiaAeosSSH, @@ -173,6 +176,7 @@ CLASS_MAPPER_BASE = { "mrv_lx": MrvLxSSH, "mrv_optiswitch": MrvOptiswitchSSH, "netapp_cdot": NetAppcDotSSH, + "netgear_prosafe": NetgearProSafeSSH, "netscaler": NetscalerSSH, "nokia_sros": NokiaSrosSSH, "oneaccess_oneos": OneaccessOneOSSSH, diff --git a/netmiko/ubiquiti/edge_ssh.py b/netmiko/ubiquiti/edge_ssh.py index 9650e9e0be2fc7399a926b51d52ead7d0ea76ea8..56bb73c9aec9a57d7782b8506e47a86e55c8db56 100644 --- a/netmiko/ubiquiti/edge_ssh.py +++ b/netmiko/ubiquiti/edge_ssh.py @@ -16,8 +16,8 @@ class UbiquitiEdgeSSH(CiscoSSHConnection): self.set_base_prompt() self.enable() self.set_base_prompt() - self.disable_paging() self.set_terminal_width() + self.disable_paging() # Clear the read buffer time.sleep(0.3 * self.global_delay_factor) diff --git a/netmiko/utilities.py b/netmiko/utilities.py index e32ebde377855f04f641a5beb6450f6dc0e8b553..5a5d4f0f4882647732ca7897a5000a8c88ea11d2 100644 --- a/netmiko/utilities.py +++ b/netmiko/utilities.py @@ -5,7 +5,7 @@ import io import os from pathlib import Path import functools -import serial.tools.list_ports +from datetime import datetime from netmiko._textfsm import _clitable as clitable from netmiko._textfsm._clitable import CliTableError @@ -18,6 +18,14 @@ try: except ImportError: GENIE_INSTALLED = False +try: + import serial.tools.list_ports + + PYSERIAL_INSTALLED = True +except ImportError: + PYSERIAL_INSTALLED = False + + # Dictionary mapping 'show run' for vendors with different command SHOW_RUN_MAPPER = { "juniper": "show configuration", @@ -196,6 +204,14 @@ def write_bytes(out_data, encoding="ascii"): def check_serial_port(name): """returns valid COM Port.""" + + if not PYSERIAL_INSTALLED: + msg = ( + "\npyserial is not installed. Please PIP install pyserial:\n\n" + "pip install pyserial\n\n" + ) + raise ValueError(msg) + try: cdc = next(serial.tools.list_ports.grep(name)) return cdc[0] @@ -347,3 +363,28 @@ def select_cmd_verify(func): return func(self, *args, **kwargs) return wrapper_decorator + + +def m_exec_time(func): + @functools.wraps(func) + def wrapper_decorator(self, *args, **kwargs): + start_time = datetime.now() + result = func(self, *args, **kwargs) + end_time = datetime.now() + method_name = str(func) + print(f"{method_name}: Elapsed time: {end_time - start_time}") + return result + + return wrapper_decorator + + +def f_exec_time(func): + @functools.wraps(func) + def wrapper_decorator(*args, **kwargs): + start_time = datetime.now() + result = func(*args, **kwargs) + end_time = datetime.now() + print(f"Elapsed time: {end_time - start_time}") + return result + + return wrapper_decorator diff --git a/netmiko/vyos/vyos_ssh.py b/netmiko/vyos/vyos_ssh.py index c05a75c51b6c3e9071fd538dcfca6d5c026098f8..08a3254f98f4b1a9b4d805051f058719f7b65fbe 100644 --- a/netmiko/vyos/vyos_ssh.py +++ b/netmiko/vyos/vyos_ssh.py @@ -9,8 +9,8 @@ class VyOSSSH(CiscoSSHConnection): """Prepare the session after the connection has been established.""" self._test_channel_read() self.set_base_prompt() + self.set_terminal_width(command="set terminal width 512", pattern="terminal") self.disable_paging(command="set terminal length 0") - self.set_terminal_width(command="set terminal width 512") # Clear the read buffer time.sleep(0.3 * self.global_delay_factor) self.clear_buffer() diff --git a/tests/SLOG/cisco881_slog.log b/tests/SLOG/cisco881_slog.log index 07f3262558bfc5e7b168b26cfc78eb3e2bfdc73f..2fa45c1d1735db21aa9863889388a22cd21959fe 100644 --- a/tests/SLOG/cisco881_slog.log +++ b/tests/SLOG/cisco881_slog.log @@ -1,6 +1,6 @@ -cisco1# -cisco1#terminal length 0 cisco1#terminal width 511 +cisco1#terminal length 0 +cisco1# cisco1# cisco1#show ip interface brief Interface IP-Address OK? Method Status Protocol diff --git a/tests/SLOG/cisco881_slog_append.log b/tests/SLOG/cisco881_slog_append.log index adda598b3e1707256e58d8abaef84d98e86da8f6..47ce51fe6c15c9393f84e4bf3e137401f0499836 100644 --- a/tests/SLOG/cisco881_slog_append.log +++ b/tests/SLOG/cisco881_slog_append.log @@ -1,8 +1,8 @@ Initial file contents -cisco1# -cisco1#terminal length 0 cisco1#terminal width 511 +cisco1#terminal length 0 +cisco1# cisco1# cisco1#show ip interface brief Interface IP-Address OK? Method Status Protocol diff --git a/tests/SLOG/cisco881_slog_append_compare.log b/tests/SLOG/cisco881_slog_append_compare.log index 07f3262558bfc5e7b168b26cfc78eb3e2bfdc73f..47ce51fe6c15c9393f84e4bf3e137401f0499836 100644 --- a/tests/SLOG/cisco881_slog_append_compare.log +++ b/tests/SLOG/cisco881_slog_append_compare.log @@ -1,6 +1,8 @@ -cisco1# -cisco1#terminal length 0 +Initial file contents + cisco1#terminal width 511 +cisco1#terminal length 0 +cisco1# cisco1# cisco1#show ip interface brief Interface IP-Address OK? Method Status Protocol diff --git a/tests/SLOG/cisco881_slog_compare.log b/tests/SLOG/cisco881_slog_compare.log index 07f3262558bfc5e7b168b26cfc78eb3e2bfdc73f..2fa45c1d1735db21aa9863889388a22cd21959fe 100644 --- a/tests/SLOG/cisco881_slog_compare.log +++ b/tests/SLOG/cisco881_slog_compare.log @@ -1,6 +1,6 @@ -cisco1# -cisco1#terminal length 0 cisco1#terminal width 511 +cisco1#terminal length 0 +cisco1# cisco1# cisco1#show ip interface brief Interface IP-Address OK? Method Status Protocol diff --git a/tests/SLOG/cisco881_slog_wr.log b/tests/SLOG/cisco881_slog_wr.log index e112cffa1b246f412dcc49e040e8e90ed8b0f176..a5f8ad2a023953391f208fcefeb51ee7d1bff8d7 100644 --- a/tests/SLOG/cisco881_slog_wr.log +++ b/tests/SLOG/cisco881_slog_wr.log @@ -1,10 +1,16 @@ +terminal width 511 +cisco1#terminal width 511 +cisco1#terminal length 0 +terminal length 0 +cisco1# cisco1# -cisco1#terminal length 0 -terminal length 0 -cisco1#terminal width 511 -terminal width 511 +cisco1#show foooooooo +show foooooooo + ^ +% Invalid input detected at '^' marker. + cisco1# cisco1#show ip interface brief diff --git a/tests/SLOG/cisco881_slog_wr_compare.log b/tests/SLOG/cisco881_slog_wr_compare.log index e112cffa1b246f412dcc49e040e8e90ed8b0f176..a5f8ad2a023953391f208fcefeb51ee7d1bff8d7 100644 --- a/tests/SLOG/cisco881_slog_wr_compare.log +++ b/tests/SLOG/cisco881_slog_wr_compare.log @@ -1,10 +1,16 @@ +terminal width 511 +cisco1#terminal width 511 +cisco1#terminal length 0 +terminal length 0 +cisco1# cisco1# -cisco1#terminal length 0 -terminal length 0 -cisco1#terminal width 511 -terminal width 511 +cisco1#show foooooooo +show foooooooo + ^ +% Invalid input detected at '^' marker. + cisco1# cisco1#show ip interface brief diff --git a/tests/conftest.py b/tests/conftest.py index 14c010d341710cf9b4d3055b13c0c4e56cb613a2..5c8912f5836083054f035afa0b1819d98a05da79 100755 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -142,6 +142,12 @@ def commands(request): test_platform = device["device_type"] commands_yml = parse_yaml(PWD + "/etc/commands.yml") + + # Nokia SR-OS driver is overloaded with both classical-CLI and MD-CLI + # Swap out the commands to be the MD-CLI commands + if device_under_test == "sros1_md": + test_platform = "nokia_sros_md" + return commands_yml[test_platform] @@ -169,8 +175,42 @@ def delete_file_nxos(ssh_conn, dest_file_system, dest_file): raise ValueError("An error happened deleting file on Cisco NX-OS") +def delete_file_xr(ssh_conn, dest_file_system, dest_file): + """ + Delete a remote file for a Cisco IOS-XR device: + + delete disk0:/test9.txt + Mon Aug 31 17:56:15.008 UTC + Delete disk0:/test9.txt[confirm] + """ + if not dest_file_system: + raise ValueError("Invalid file system specified") + if not dest_file: + raise ValueError("Invalid dest file specified") + + full_file_name = f"{dest_file_system}/{dest_file}" + + cmd = f"delete {full_file_name}" + output = ssh_conn.send_command(cmd, expect_string=r"Delete.*confirm") + if "Delete" in output and dest_file in output: + output += ssh_conn.send_command("\n", expect_string=r"#") + return output + + raise ValueError("An error happened deleting file on Cisco IOS-XR") + + def delete_file_ios(ssh_conn, dest_file_system, dest_file): - """Delete a remote file for a Cisco IOS device.""" + """ + Delete a remote file for a Cisco IOS device: + + cisco1#del flash:/useless_file.cfg + Delete filename [useless_file.cfg]? + Delete flash:/useless_file.cfg? [confirm]y + +delete disk0:/test9.txt +Mon Aug 31 17:56:15.008 UTC +Delete disk0:/test9.txt[confirm] + """ if not dest_file_system: raise ValueError("Invalid file system specified") if not dest_file: @@ -179,14 +219,11 @@ def delete_file_ios(ssh_conn, dest_file_system, dest_file): full_file_name = f"{dest_file_system}/{dest_file}" cmd = f"delete {full_file_name}" - output = ssh_conn.send_command_timing(cmd, delay_factor=2) + output = ssh_conn.send_command(cmd, expect_string=r"Delete filename") if "Delete" in output and dest_file in output: - output += ssh_conn.send_command_timing("\n", delay_factor=2) - if "Delete" in output and full_file_name in output and "confirm" in output: - output += ssh_conn.send_command_timing("y", delay_factor=2) - return output - else: - output += ssh_conn.send_command_timing("n", delay_factor=2) + output += ssh_conn.send_command("\n", expect_string=r"confirm") + output += ssh_conn.send_command("y", expect_string=r"#") + return output raise ValueError("An error happened deleting file on Cisco IOS") @@ -470,8 +507,7 @@ def get_platform_args(): "cisco_xr": { "file_system": "disk0:", "enable_scp": False, - # Delete pattern is the same on IOS-XR - "delete_file": delete_file_ios, + "delete_file": delete_file_xr, }, "linux": { "file_system": "/var/tmp", diff --git a/tests/etc/commands.yml.example b/tests/etc/commands.yml.example index 8d72722dc70835905442b34a214b58a3f20f0f04..56592afd03549a036bc1120aeab35ead6d48f942 100644 --- a/tests/etc/commands.yml.example +++ b/tests/etc/commands.yml.example @@ -430,6 +430,11 @@ sophos_sfos: basic: "system diagnostics utilities route lookup 172.16.16.16" extended_output: "system diagnostics show version-info" +adtran_os + version: "show version" + basic: "show system-management-evc" + extended_output: "show version" + huawei_smartax: version: "display version" basic: "display system sys-info" diff --git a/tests/etc/responses.yml.example b/tests/etc/responses.yml.example index a405d592a22c6e5d4195841f9747176aa6723fcd..47519dcc8e0862f84760b649a8fa572c70abf9c9 100644 --- a/tests/etc/responses.yml.example +++ b/tests/etc/responses.yml.example @@ -276,6 +276,13 @@ sophos_sfos: version_banner: "Serial Number" multiple_line_output: "" +adtran_os: + base_prompt: "adtrantest" + router_prompt: "adtrantest>" + enable_prompt: "adtrantest#" + interface_ip: 192.0.2.1 + version_banner: "Serial number" + huawei_smartax: base_prompt: "ol01.test-lab.xyz" router_prompt: "ol01.test-lab.xyz>" diff --git a/tests/etc/test_devices.yml.example b/tests/etc/test_devices.yml.example index 9fbf5e4f6424d768d1a7cd3fce782eb50ec3a046..97c4722b44415d834770c3f3081c604884cfeefa 100644 --- a/tests/etc/test_devices.yml.example +++ b/tests/etc/test_devices.yml.example @@ -210,6 +210,12 @@ sophos_sfos: username: admin password: admin +adtran_os: + device_type: adtran_os + ip: 192.0.2.1 + username: adtran + password: adtran + huawei_smartax: device_type: huawei_smartax ip: 192.0.2.1 diff --git a/tests/performance/netmiko_performance.csv b/tests/performance/netmiko_performance.csv new file mode 100644 index 0000000000000000000000000000000000000000..9ea8a738c828c82a77dd30d8b9aaf94a25c5a356 --- /dev/null +++ b/tests/performance/netmiko_performance.csv @@ -0,0 +1,19 @@ +date,netmiko_version,device_name,connect,send_command_simple,send_config_simple,send_config_large_acl +2020-8-28 9:35:2,2.4.2,cisco1,0:00:05.028585,0:00:05.437255,0:00:07.698679,0:00:12.757210 +2020-8-28 9:35:32,2.4.2,cisco3,0:00:04.927152,0:00:05.232406,0:00:07.640341,0:00:13.068117 +2020-8-28 9:36:9,2.4.2,cisco5,0:00:05.433502,0:00:05.890628,0:00:08.300116,0:00:16.665863 +2020-8-28 9:42:3,3.0.0,cisco1,0:00:05.651217,0:00:06.045608,0:00:05.959159,0:00:16.530688 +2020-8-28 9:42:37,3.0.0,cisco3,0:00:05.645057,0:00:05.845269,0:00:05.798335,0:00:16.498583 +2020-8-28 9:43:19,3.0.0,cisco5,0:00:05.973869,0:00:06.512771,0:00:06.646396,0:00:23.656478 +2020-8-28 9:47:49,3.1.1,cisco1,0:00:07.806983,0:00:08.139146,0:00:08.046488,0:00:18.478753 +2020-8-28 9:48:32,3.1.1,cisco3,0:00:07.729597,0:00:07.950239,0:00:07.866845,0:00:18.641751 +2020-8-28 9:49:21,3.1.1,cisco5,0:00:08.058890,0:00:08.118542,0:00:08.236710,0:00:24.947753 +2020-8-28 9:54:10,3.2.0,cisco1,0:00:07.727580,0:00:08.128382,0:00:08.053055,0:00:18.472529 +2020-8-28 9:54:52,3.2.0,cisco3,0:00:07.777652,0:00:08.132597,0:00:08.067485,0:00:18.482892 +2020-8-28 9:55:41,3.2.0,cisco5,0:00:08.128708,0:00:08.072531,0:00:08.230244,0:00:24.599200 +2020-8-28 9:57:48,3.2.1_dev,cisco1,0:00:07.722847,0:00:08.129601,0:00:08.048826,0:00:18.485489 +2020-8-28 9:58:30,3.2.1_dev,cisco3,0:00:07.725350,0:00:08.135150,0:00:07.869109,0:00:18.838147 +2020-8-28 9:59:20,3.2.1_dev,cisco5,0:00:07.800455,0:00:08.103660,0:00:08.279644,0:00:25.457361 +2020-8-28 10:5:44,3.3.0_dev,cisco1,0:00:01.028332,0:00:01.059909,0:00:01.094017,0:00:03.527510 +2020-8-28 10:5:55,3.3.0_dev,cisco3,0:00:01.071055,0:00:01.155505,0:00:01.022633,0:00:07.542166 +2020-8-28 10:6:11,3.3.0_dev,cisco5,0:00:01.715099,0:00:01.778859,0:00:01.521635,0:00:11.627172 diff --git a/tests/performance/test_devices.yml b/tests/performance/test_devices.yml new file mode 100644 index 0000000000000000000000000000000000000000..3f0f0d05d76d6722ce251fcbcb70851db4c1bba0 --- /dev/null +++ b/tests/performance/test_devices.yml @@ -0,0 +1,15 @@ +--- +cisco1: + device_type: cisco_ios + host: cisco1.lasthop.io + username: pyclass + +cisco3: + device_type: cisco_xe + host: cisco3.lasthop.io + username: pyclass + +cisco5: + device_type: cisco_xe + host: cisco5.lasthop.io + username: pyclass diff --git a/tests/performance/test_netmiko.py b/tests/performance/test_netmiko.py new file mode 100644 index 0000000000000000000000000000000000000000..ab207e02e0711c3a7f533cb814e4f4cb683d8d1b --- /dev/null +++ b/tests/performance/test_netmiko.py @@ -0,0 +1,139 @@ +from netmiko import ConnectHandler, __version__ +import os +from ipaddress import ip_address +import yaml +import functools +from datetime import datetime +import csv + +# import logging +# logging.basicConfig(filename="test.log", level=logging.DEBUG) +# logger = logging.getLogger("netmiko") + +PRINT_DEBUG = False + + +def generate_csv_timestamp(): + """yyyy-MM-dd HH:mm:ss""" + now = datetime.now() + t_stamp = f"{now.year}-{now.month}-{now.day} {now.hour}:{now.minute}:{now.second}" + return t_stamp + + +def write_csv(device_name, netmiko_results): + results_file = "netmiko_performance.csv" + file_exists = os.path.isfile(results_file) + with open(results_file, "a") as csv_file: + field_names = ["date", "netmiko_version", "device_name"] + list( + netmiko_results.keys() + ) + t_stamp = generate_csv_timestamp() + csv_write = csv.DictWriter(csv_file, fieldnames=field_names) + + # Write the header only once + if not file_exists: + csv_write.writeheader() + + entry = { + "date": t_stamp, + "netmiko_version": __version__, + "device_name": device_name, + } + + for func_name, exec_time in netmiko_results.items(): + entry[func_name] = exec_time + csv_write.writerow(entry) + + +def f_exec_time(func): + @functools.wraps(func) + def wrapper_decorator(*args, **kwargs): + start_time = datetime.now() + result = func(*args, **kwargs) + end_time = datetime.now() + time_delta = end_time - start_time + print(f"{str(func)}: Elapsed time: {time_delta}") + return (time_delta, result) + + return wrapper_decorator + + +def read_devices(): + f_name = "test_devices.yml" + with open(f_name) as f: + return yaml.load(f) + + +@f_exec_time +def connect(device): + with ConnectHandler(**device) as conn: + prompt = conn.find_prompt() + PRINT_DEBUG and print(prompt) + + +@f_exec_time +def send_command_simple(device): + with ConnectHandler(**device) as conn: + output = conn.send_command("show ip int brief") + PRINT_DEBUG and print(output) + + +@f_exec_time +def send_config_simple(device): + with ConnectHandler(**device) as conn: + output = conn.send_config_set("logging buffered 20000") + PRINT_DEBUG and print(output) + + +@f_exec_time +def send_config_large_acl(device): + with ConnectHandler(**device) as conn: + # Results will be marginally distorted by generating the ACL here. + cfg = generate_ios_acl(entries=100) + output = conn.send_config_set(cfg) + PRINT_DEBUG and print(output) + + +def generate_ios_acl(entries=100): + base_cmd = "ip access-list extended netmiko_test_large_acl" + acl = [base_cmd] + for i in range(1, entries + 1): + cmd = f"permit ip host {ip_address('192.168.0.0') + i} any" + acl.append(cmd) + return acl + + +def main(): + PASSWORD = os.environ["NORNIR_PASSWORD"] + + devices = read_devices() + print("\n\n") + for dev_name, dev_dict in devices.items(): + print("-" * 80) + print(f"Device name: {dev_name}") + print("-" * 12) + + dev_dict["password"] = PASSWORD + + # Run tests + operations = [ + "connect", + "send_command_simple", + "send_config_simple", + "send_config_large_acl", + ] + results = {} + for op in operations: + func = globals()[op] + time_delta, result = func(dev_dict) + results[op] = time_delta + print("-" * 80) + print() + + write_csv(dev_name, results) + + print("\n\n") + + +if __name__ == "__main__": + main() diff --git a/tests/test_ios/add_delay_cisco881.sh b/tests/test_ios/add_delay_cisco881.sh new file mode 100755 index 0000000000000000000000000000000000000000..46decf6f950bd46e2e12aa52a99f68082144a9be --- /dev/null +++ b/tests/test_ios/add_delay_cisco881.sh @@ -0,0 +1,9 @@ +#!/bin/bash + +# Add delay for cisco3; must be root or sudo to execute +sudo -s /sbin/tc qdisc del dev eth0 root +sudo -s /sbin/tc qdisc add dev eth0 root handle 1: prio +sudo -s /sbin/tc qdisc add dev eth0 parent 1:3 handle 30: tbf rate 20kbit buffer 1600 limit 3000 +sudo -s /sbin/tc qdisc add dev eth0 parent 30:1 handle 31: netem delay 1000ms 10ms distribution normal loss 10% +sudo -s /sbin/tc filter add dev eth0 protocol ip parent 1:0 prio 3 u32 match ip dst 184.105.247.70/32 flowid 1:3 + diff --git a/tests/test_ios/remove_delay_cisco881.sh b/tests/test_ios/remove_delay_cisco881.sh new file mode 100755 index 0000000000000000000000000000000000000000..41ae9fe9ab861ec0d68dabf4a540bff2ffdc47d8 --- /dev/null +++ b/tests/test_ios/remove_delay_cisco881.sh @@ -0,0 +1,4 @@ +#!/bin/bash + +# Remove delay for all; must be root or sudo to execute +sudo -s /sbin/tc qdisc del dev eth0 root diff --git a/tests/test_ios/test_ios.sh b/tests/test_ios/test_ios.sh new file mode 100755 index 0000000000000000000000000000000000000000..9e3a0360d617c068b01a64b4920d5543758f8b18 --- /dev/null +++ b/tests/test_ios/test_ios.sh @@ -0,0 +1,42 @@ +#!/bin/sh + +RETURN_CODE=0 + +echo "Starting tests...good luck:" \ +&& echo "Cisco IOS" \ +&& cd .. \ +&& py.test -s -x -v test_netmiko_show.py --test_device cisco881 \ +&& py.test -s -x -v test_netmiko_config.py --test_device cisco881 \ +&& py.test -s -x -v test_netmiko_config_acl.py --test_device cisco881 \ +&& py.test -s -x -v test_netmiko_tcl.py --test_device cisco881 \ +&& py.test -s -x -v test_netmiko_scp.py --test_device cisco881 \ +|| RETURN_CODE=1 + +exit $RETURN_CODE + +#&& py.test -v test_netmiko_tcl.py --test_device cisco881_key \ +#&& py.test -v test_netmiko_show.py --test_device cisco881_key \ +#&& py.test -v test_netmiko_config.py --test_device cisco881_key \ +#&& py.test -v test_netmiko_config_acl.py --test_device cisco881_key \ + +#&& py.test -v test_netmiko_session_log.py --test_device cisco881_slog \ + +#&& py.test -v test_netmiko_tcl.py --test_device cisco881_fast \ +#&& py.test -v test_netmiko_show.py --test_device cisco881_fast \ +#&& py.test -v test_netmiko_config.py --test_device cisco881_fast \ + +#&& py.test -v test_netmiko_show.py --test_device cisco881_ssh_config \ +#&& py.test -v test_netmiko_config.py --test_device cisco881_ssh_config \ +#&& py.test -v test_netmiko_config_acl.py --test_device cisco881_ssh_config \ + +#&& py.test -v test_netmiko_show.py --test_device cisco881_ssh_proxyjump \ +#&& py.test -v test_netmiko_config.py --test_device cisco881_ssh_proxyjump \ +#&& py.test -v test_netmiko_config_acl.py --test_device cisco881_ssh_proxyjump \ + +#&& py.test -v test_netmiko_show.py --test_device cisco881_telnet \ +#&& py.test -v test_netmiko_config.py --test_device cisco881_telnet \ +#&& py.test -v test_netmiko_config_acl.py --test_device cisco881_telnet \ +#&& py.test -s -v test_netmiko_autodetect.py --test_device cisco881 \ + +## && py.test -v test_netmiko_scp.py --test_device cisco881_key \ +## && py.test -v test_netmiko_scp.py --test_device cisco881_fast \ diff --git a/tests/test_ios/test_iosxe.sh b/tests/test_ios/test_iosxe.sh new file mode 100755 index 0000000000000000000000000000000000000000..c02647d24e643bbf24c04ef5b6597e6dab06d5a3 --- /dev/null +++ b/tests/test_ios/test_iosxe.sh @@ -0,0 +1,13 @@ +#!/bin/sh + +RETURN_CODE=0 + +echo "Starting tests...good luck:" \ +&& echo "Cisco IOS-XE" \ +&& py.test -v test_netmiko_show.py --test_device cisco3 \ +&& py.test -v test_netmiko_config.py --test_device cisco3 \ +&& py.test -v test_netmiko_config_acl.py --test_device cisco3 \ +&& py.test -v test_netmiko_scp.py --test_device cisco3 \ +|| RETURN_CODE=1 + +exit $RETURN_CODE diff --git a/tests/test_iosxe.sh b/tests/test_iosxe.sh deleted file mode 100755 index 53a44f7f05412b8fe22f725a6742019069de4d86..0000000000000000000000000000000000000000 --- a/tests/test_iosxe.sh +++ /dev/null @@ -1,11 +0,0 @@ -#!/bin/sh - -RETURN_CODE=0 - -echo "Starting tests...good luck:" \ -&& echo "Cisco IOS-XE" \ -&& py.test -v test_netmiko_show.py --test_device ios_xe \ -&& py.test -v test_netmiko_config.py --test_device ios_xe \ -|| RETURN_CODE=1 - -exit $RETURN_CODE diff --git a/tests/test_netmiko_commit.py b/tests/test_netmiko_commit.py index 4442df9ab952e09afa22ea0f214fb1edbaaa0237..4985f79e74755061048eed2f019eacbc2b9b443b 100755 --- a/tests/test_netmiko_commit.py +++ b/tests/test_netmiko_commit.py @@ -17,6 +17,7 @@ import time import re import random import string +import pytest def gen_random(N=6): @@ -120,6 +121,9 @@ def test_commit_confirm(net_connect, commands, expected_responses): net_connect, commands, expected_responses ) + if net_connect.device_type in ["nokia_sros"]: + assert pytest.skip() + # Perform commit-confirm test net_connect.send_config_set(config_commands) if net_connect.device_type == "cisco_xr": @@ -144,6 +148,9 @@ def test_confirm_delay(net_connect, commands, expected_responses): net_connect, commands, expected_responses ) + if net_connect.device_type in ["nokia_sros"]: + assert pytest.skip() + # Perform commit-confirm test net_connect.send_config_set(config_commands) if net_connect.device_type == "cisco_xr": @@ -168,6 +175,9 @@ def test_no_confirm(net_connect, commands, expected_responses): net_connect, commands, expected_responses ) + if net_connect.device_type in ["nokia_sros"]: + assert pytest.skip() + # Perform commit-confirm test net_connect.send_config_set(config_commands) if net_connect.device_type == "cisco_xr": @@ -209,7 +219,7 @@ def test_clear_msg(net_connect, commands, expected_responses): "commit", expect_string=r"Do you wish to" ) output += net_connect.send_command_expect("yes", auto_find_prompt=False) - assert True is True + assert True def test_commit_check(net_connect, commands, expected_responses): @@ -217,8 +227,8 @@ def test_commit_check(net_connect, commands, expected_responses): Test commit check """ # IOS-XR does not support commit check - if net_connect.device_type == "cisco_xr": - assert True is True + if net_connect.device_type in ["cisco_xr", "nokia_sros"]: + assert pytest.skip() else: # Setup the initial config state @@ -248,6 +258,9 @@ def test_commit_comment(net_connect, commands, expected_responses): net_connect, commands, expected_responses ) + if net_connect.device_type in ["nokia_sros"]: + assert pytest.skip() + # Perform commit with comment net_connect.send_config_set(config_commands) net_connect.commit(comment="Unit test on commit with comment") @@ -273,8 +286,8 @@ def test_commit_andquit(net_connect, commands, expected_responses): """ # IOS-XR does not support commit and quit - if net_connect.device_type == "cisco_xr": - assert True is True + if net_connect.device_type in ["cisco_xr", "nokia_sros"]: + assert pytest.skip() else: # Setup the initial config state @@ -324,7 +337,7 @@ def test_commit_label_comment(net_connect, commands, expected_responses): """ # IOS-XR only test if net_connect.device_type != "cisco_xr": - assert True is True + assert pytest.skip() else: # Setup the initial config state config_commands, support_commit, config_verify = setup_initial_state( @@ -357,7 +370,7 @@ def test_commit_label_confirm(net_connect, commands, expected_responses): """ # IOS-XR only test if net_connect.device_type != "cisco_xr": - assert True is True + assert pytest.skip() else: # Setup the initial config state config_commands, support_commit, config_verify = setup_initial_state( diff --git a/tests/test_netmiko_session_log.py b/tests/test_netmiko_session_log.py index 7282bd2e1fce8da2d8fc337c8bd6c02b73e0a66c..26110905d4bf5273018f267e9bb1f208f74bee58 100755 --- a/tests/test_netmiko_session_log.py +++ b/tests/test_netmiko_session_log.py @@ -67,11 +67,33 @@ def test_session_log(net_connect, commands, expected_responses): def test_session_log_write(net_connect_slog_wr, commands, expected_responses): """Verify session_log matches expected content, but when channel writes are also logged.""" command = commands["basic"] - session_action(net_connect_slog_wr, command) + nc = net_connect_slog_wr + + # Send a marker down the channel + nc.send_command("show foooooooo") + time.sleep(1) + nc.clear_buffer() + nc.send_command(command) + nc.disconnect() compare_file = expected_responses["compare_log_wr"] session_file = expected_responses["session_log_wr"] - session_log_md5(session_file, compare_file) + + with open(compare_file, "rb") as f: + compare_contents = f.read() + + # Header information varies too much due to device behavior differences. + # So just discard it. + marker = b"% Invalid input detected at '^' marker." + _, compare_contents = compare_contents.split(marker) + compare_log_md5 = calc_md5(contents=compare_contents.strip()) + + log_content = read_session_log(session_file) + marker = b"% Invalid input detected at '^' marker." + _, log_content = log_content.split(marker) + + session_log_md5 = calc_md5(contents=log_content.strip()) + assert session_log_md5 == compare_log_md5 def test_session_log_append(device_slog, commands, expected_responses): diff --git a/tests/test_netmiko_show.py b/tests/test_netmiko_show.py index e6f521930d6710cfd035677086aa61eb259a2c58..15dc876447da78549392b577698f455dfcee0dc3 100755 --- a/tests/test_netmiko_show.py +++ b/tests/test_netmiko_show.py @@ -59,18 +59,34 @@ def test_send_command_timing(net_connect, commands, expected_responses): """Verify a command can be sent down the channel successfully.""" time.sleep(1) net_connect.clear_buffer() - show_ip = net_connect.send_command_timing(commands["basic"]) - assert expected_responses["interface_ip"] in show_ip # Force verification of command echo show_ip = net_connect.send_command_timing(commands["basic"], cmd_verify=True) assert expected_responses["interface_ip"] in show_ip +def test_send_command_timing_no_cmd_verify(net_connect, commands, expected_responses): + # Skip devices that are performance optimized (i.e. cmd_verify is required there) + if net_connect.fast_cli is True: + assert pytest.skip() + time.sleep(1) + net_connect.clear_buffer() + # cmd_verify=False is the default + show_ip = net_connect.send_command_timing(commands["basic"], cmd_verify=False) + assert expected_responses["interface_ip"] in show_ip + + def test_send_command(net_connect, commands, expected_responses): """Verify a command can be sent down the channel successfully using send_command method.""" net_connect.clear_buffer() show_ip_alt = net_connect.send_command(commands["basic"]) assert expected_responses["interface_ip"] in show_ip_alt + + +def test_send_command_no_cmd_verify(net_connect, commands, expected_responses): + # Skip devices that are performance optimized (i.e. cmd_verify is required there) + if net_connect.fast_cli is True: + assert pytest.skip() + net_connect.clear_buffer() show_ip_alt = net_connect.send_command(commands["basic"], cmd_verify=False) assert expected_responses["interface_ip"] in show_ip_alt @@ -113,6 +129,8 @@ def test_send_command_global_cmd_verify( Disable cmd_verify globally. """ net_connect = net_connect_cmd_verify + if net_connect.fast_cli is True: + assert pytest.skip() net_connect.clear_buffer() # cmd_verify should be disabled globally at this point assert net_connect.global_cmd_verify is False @@ -120,13 +138,21 @@ def test_send_command_global_cmd_verify( assert expected_responses["interface_ip"] in show_ip_alt -def test_send_command_juniper(net_connect, commands, expected_responses): - """Verify Juniper complete on space is disabled.""" +def test_complete_on_space_disabled(net_connect, commands, expected_responses): + """Verify complete on space is disabled.""" # If complete on space is enabled will get re-written to "show configuration groups" - if net_connect.device_type == "juniper_junos": - net_connect.write_channel("show configuration gr \n") + if net_connect.device_type in ["juniper_junos", "nokia_sros"]: + if ( + net_connect.device_type == "nokia_sros" + and "@" not in net_connect.base_prompt + ): + # Only MD-CLI supports disable of command complete on space + assert pytest.skip() + cmd = commands.get("abbreviated_cmd") + cmd_full = commands.get("abbreviated_cmd_full") + net_connect.write_channel(f"{cmd}\n") output = net_connect.read_until_prompt() - assert "show configuration groups" not in output + assert cmd_full not in output else: assert pytest.skip() @@ -244,7 +270,7 @@ def test_enable_mode(net_connect, commands, expected_responses): enable_prompt = net_connect.find_prompt() assert enable_prompt == expected_responses["enable_prompt"] except AttributeError: - assert True is True + assert True def test_disconnect(net_connect, commands, expected_responses): diff --git a/tests/test_sros.sh b/tests/test_sros.sh new file mode 100755 index 0000000000000000000000000000000000000000..3313c40832e6affa258ba2c0d9c3f0bc5def0967 --- /dev/null +++ b/tests/test_sros.sh @@ -0,0 +1,19 @@ +#!/bin/sh + +RETURN_CODE=0 + +# Exit on the first test failure and set RETURN_CODE = 1 +echo "Starting tests...good luck: (SR-OS CLI)" \ +&& echo "SR-OS CLI" \ +&& py.test -x -s -v test_netmiko_show.py --test_device sros2 \ +&& py.test -x -s -v test_netmiko_config.py --test_device sros2 \ +&& py.test -x -s -v test_netmiko_scp.py --test_device sros2 \ +\ +&& echo "SR-OS MD" \ +&& py.test -x -s -v test_netmiko_show.py --test_device sros1_md \ +&& py.test -x -s -v test_netmiko_config.py --test_device sros1_md \ +&& py.test -x -s -v test_netmiko_scp.py --test_device sros1_md \ +&& py.test -x -s -v test_netmiko_commit.py --test_device sros1_md \ +|| RETURN_CODE=1 + +exit $RETURN_CODE diff --git a/tests/test_suite_alt.sh b/tests/test_suite_alt.sh index e4163543060fcff271f30cebfd1859a04253e976..879df98b81b4a16224d7de11624be532d879e1f9 100755 --- a/tests/test_suite_alt.sh +++ b/tests/test_suite_alt.sh @@ -11,9 +11,16 @@ echo "Starting tests...good luck:" \ && py.test -x -s -v test_netmiko_show.py --test_device juniper_vmx \ && py.test -x -s -v test_netmiko_config.py --test_device juniper_vmx \ \ -&& echo "Nokia SR-OS" \ -&& py.test -x -s -v test_netmiko_show.py --test_device sros1 \ -&& py.test -x -s -v test_netmiko_config.py --test_device sros1 \ +&& echo "Nokia SR-OS CLI" \ +&& py.test -x -s -v test_netmiko_show.py --test_device sros2 \ +&& py.test -x -s -v test_netmiko_config.py --test_device sros2 \ +&& py.test -x -s -v test_netmiko_scp.py --test_device sros2 \ +\ +&& echo "SR-OS MD" \ +&& py.test -x -s -v test_netmiko_show.py --test_device sros1_md \ +&& py.test -x -s -v test_netmiko_config.py --test_device sros1_md \ +&& py.test -x -s -v test_netmiko_scp.py --test_device sros1_md \ +&& py.test -x -s -v test_netmiko_commit.py --test_device sros1_md \ \ && echo "Cisco IOS-XE SSH (including SCP)" \ && py.test -v test_netmiko_scp.py --test_device cisco3 \ @@ -32,7 +39,6 @@ echo "Starting tests...good luck:" \ && py.test -v test_netmiko_show.py --test_device cisco881 \ && py.test -v test_netmiko_config.py --test_device cisco881 \ && py.test -v test_netmiko_config_acl.py --test_device cisco881 \ -&& py.test -v test_netmiko_session_log.py --test_device cisco881_slog \ \ && echo "Cisco IOS SSH fast_cli (including SCP)" \ && py.test -v test_netmiko_tcl.py --test_device cisco881_fast \ @@ -65,10 +71,10 @@ echo "Starting tests...good luck:" \ && py.test -v test_netmiko_config_acl.py --test_device arista_sw \ \ && echo "Juniper" \ -&& py.test -v test_netmiko_scp.py --test_device juniper_srx \ -&& py.test -v test_netmiko_show.py --test_device juniper_srx \ -&& py.test -v test_netmiko_config.py --test_device juniper_srx \ -&& py.test -v test_netmiko_commit.py --test_device juniper_srx \ +&& py.test -x -v test_netmiko_scp.py --test_device juniper_srx \ +&& py.test -x -v test_netmiko_show.py --test_device juniper_srx \ +&& py.test -x -v test_netmiko_config.py --test_device juniper_srx \ +&& py.test -x -v test_netmiko_commit.py --test_device juniper_srx \ \ && echo "Cisco ASA" \ && py.test -v test_netmiko_show.py --test_device cisco_asa \ @@ -82,11 +88,6 @@ echo "Starting tests...good luck:" \ && py.test -v test_netmiko_config.py --test_device cisco_xrv \ && py.test -v test_netmiko_commit.py --test_device cisco_xrv \ \ -&& echo "Cisco IOS-XR (Azure)" \ -&& py.test -v test_netmiko_show.py --test_device cisco_xr_azure \ -&& py.test -v test_netmiko_config.py --test_device cisco_xr_azure \ -&& py.test -v test_netmiko_commit.py --test_device cisco_xr_azure \ -\ && echo "Cisco NXOS" \ && py.test -v test_netmiko_scp.py --test_device nxos1 \ && py.test -v test_netmiko_show.py --test_device nxos1 \ @@ -120,3 +121,10 @@ exit $RETURN_CODE # && py.test -v test_netmiko_scp.py --test_device cisco881_key \ # && py.test -v test_netmiko_scp.py --test_device cisco881 \ # && py.test -v test_netmiko_scp.py --test_device cisco881_fast \ +# +# && echo "Cisco IOS-XR (Azure)" \ +# && py.test -v test_netmiko_show.py --test_device cisco_xr_azure \ +# && py.test -v test_netmiko_config.py --test_device cisco_xr_azure \ +# && py.test -v test_netmiko_commit.py --test_device cisco_xr_azure \ +# +# && py.test -v test_netmiko_session_log.py --test_device cisco881_slog \