diff --git a/docs/netmiko/base_connection.html b/docs/netmiko/base_connection.html index 92c1a1a19755153a39f2a704864e82e7406e64d6..339b63788e14ffce8063780e72db57e4f6b39f66 100644 --- a/docs/netmiko/base_connection.html +++ b/docs/netmiko/base_connection.html @@ -431,6 +431,11 @@ class BaseConnection(object): def _write_session_log(self, data): if self.session_log is not None and len(data) > 0: + # Hide the password and secret in the session_log + if self.password: + data = data.replace(self.password, "********") + if self.secret: + data = data.replace(self.secret, "********") self.session_log.write(write_bytes(data, encoding=self.encoding)) self.session_log.flush() @@ -804,10 +809,20 @@ class BaseConnection(object): else: source = {} + # Keys get normalized to lower-case if "proxycommand" in source: proxy = paramiko.ProxyCommand(source["proxycommand"]) - elif "ProxyCommand" in source: - proxy = paramiko.ProxyCommand(source["ProxyCommand"]) + elif "proxyjump" in source: + hops = list(reversed(source["proxyjump"].split(","))) + if len(hops) > 1: + raise ValueError( + "ProxyJump with more than one proxy server is not supported." + ) + port = source.get("port", self.port) + host = source.get("hostname", self.host) + # -F {full_path} forces the continued use of the same SSH config file + cmd = "ssh -F {} -W {}:{} {}".format(full_path, host, port, hops[0]) + proxy = paramiko.ProxyCommand(cmd) else: proxy = None @@ -967,7 +982,7 @@ class BaseConnection(object): # check if data was ever present if new_data: - return "" + return new_data else: raise NetMikoTimeoutException("Timed out waiting for data") @@ -2282,6 +2297,11 @@ class TelnetConnection(BaseConnection): def _write_session_log(self, data): if self.session_log is not None and len(data) > 0: + # Hide the password and secret in the session_log + if self.password: + data = data.replace(self.password, "********") + if self.secret: + data = data.replace(self.secret, "********") self.session_log.write(write_bytes(data, encoding=self.encoding)) self.session_log.flush() @@ -2655,10 +2675,20 @@ class TelnetConnection(BaseConnection): else: source = {} + # Keys get normalized to lower-case if "proxycommand" in source: proxy = paramiko.ProxyCommand(source["proxycommand"]) - elif "ProxyCommand" in source: - proxy = paramiko.ProxyCommand(source["ProxyCommand"]) + elif "proxyjump" in source: + hops = list(reversed(source["proxyjump"].split(","))) + if len(hops) > 1: + raise ValueError( + "ProxyJump with more than one proxy server is not supported." + ) + port = source.get("port", self.port) + host = source.get("hostname", self.host) + # -F {full_path} forces the continued use of the same SSH config file + cmd = "ssh -F {} -W {}:{} {}".format(full_path, host, port, hops[0]) + proxy = paramiko.ProxyCommand(cmd) else: proxy = None @@ -2818,7 +2848,7 @@ class TelnetConnection(BaseConnection): # check if data was ever present if new_data: - return "" + return new_data else: raise NetMikoTimeoutException("Timed out waiting for data") diff --git a/docs/netmiko/cisco/cisco_ios.html b/docs/netmiko/cisco/cisco_ios.html index 015081b8bfb604c5217eede51a0de4d85ea2273f..5b9340dad627d5a8e7f5d1d725ff172d57ff85c7 100644 --- a/docs/netmiko/cisco/cisco_ios.html +++ b/docs/netmiko/cisco/cisco_ios.html @@ -432,6 +432,8 @@ class InLineTransfer(CiscoIosFileTransfer): <li><a title="netmiko.cisco.cisco_ios.CiscoIosSSH" href="#netmiko.cisco.cisco_ios.CiscoIosSSH">CiscoIosSSH</a></li> <li><a title="netmiko.cisco.cisco_ios.CiscoIosTelnet" href="#netmiko.cisco.cisco_ios.CiscoIosTelnet">CiscoIosTelnet</a></li> <li><a title="netmiko.cisco.cisco_ios.CiscoIosSerial" href="#netmiko.cisco.cisco_ios.CiscoIosSerial">CiscoIosSerial</a></li> +<li><a title="netmiko.keymile.keymile_ssh.KeymileSSH" href="../keymile/keymile_ssh.html#netmiko.keymile.keymile_ssh.KeymileSSH">KeymileSSH</a></li> +<li><a title="netmiko.keymile.keymile_nos_ssh.KeymileNOSSSH" href="../keymile/keymile_nos_ssh.html#netmiko.keymile.keymile_nos_ssh.KeymileNOSSSH">KeymileNOSSSH</a></li> </ul> <h3>Methods</h3> <dl> diff --git a/docs/netmiko/cisco/index.html b/docs/netmiko/cisco/index.html index b9883a6d6ec50864228b4e7aca0f6d9c8aaeb0ed..6a61fb1240d1c01b15083f1407e27db51d63f34e 100644 --- a/docs/netmiko/cisco/index.html +++ b/docs/netmiko/cisco/index.html @@ -764,6 +764,8 @@ happens the trailing '(config*' needs stripped off.</p></section> <li><a title="netmiko.cisco.cisco_ios.CiscoIosSSH" href="cisco_ios.html#netmiko.cisco.cisco_ios.CiscoIosSSH">CiscoIosSSH</a></li> <li><a title="netmiko.cisco.cisco_ios.CiscoIosTelnet" href="cisco_ios.html#netmiko.cisco.cisco_ios.CiscoIosTelnet">CiscoIosTelnet</a></li> <li><a title="netmiko.cisco.cisco_ios.CiscoIosSerial" href="cisco_ios.html#netmiko.cisco.cisco_ios.CiscoIosSerial">CiscoIosSerial</a></li> +<li><a title="netmiko.keymile.keymile_ssh.KeymileSSH" href="../keymile/keymile_ssh.html#netmiko.keymile.keymile_ssh.KeymileSSH">KeymileSSH</a></li> +<li><a title="netmiko.keymile.keymile_nos_ssh.KeymileNOSSSH" href="../keymile/keymile_nos_ssh.html#netmiko.keymile.keymile_nos_ssh.KeymileNOSSSH">KeymileNOSSSH</a></li> </ul> <h3>Methods</h3> <dl> diff --git a/docs/netmiko/hp/hp_procurve.html b/docs/netmiko/hp/hp_procurve.html index 082e0a37a7db6fc874127cb4635e79d3e86d4dd8..946af9f91b9843932e20256ba82d31ff174ed831 100644 --- a/docs/netmiko/hp/hp_procurve.html +++ b/docs/netmiko/hp/hp_procurve.html @@ -27,10 +27,20 @@ from __future__ import unicode_literals import re import time import socket +from os import path +from paramiko import SSHClient from netmiko.cisco_base_connection import CiscoSSHConnection from netmiko import log +class SSHClient_noauth(SSHClient): + """Set noauth when manually handling SSH authentication.""" + + def _auth(self, username, *args): + self._transport.auth_none(username) + return + + class HPProcurveBase(CiscoSSHConnection): def session_preparation(self): """ @@ -123,6 +133,25 @@ class HPProcurveSSH(HPProcurveBase): super(HPProcurveSSH, self).session_preparation() + def _build_ssh_client(self): + """Allow passwordless authentication for HP devices being provisioned.""" + + # Create instance of SSHClient object. If no SSH keys and no password, then use noauth + if not self.use_keys and not self.password: + remote_conn_pre = SSHClient_noauth() + else: + remote_conn_pre = SSHClient() + + # Load host_keys for better SSH security + if self.system_host_keys: + remote_conn_pre.load_system_host_keys() + if self.alt_host_keys and path.isfile(self.alt_key_file): + remote_conn_pre.load_host_keys(self.alt_key_file) + + # Default is to automatically add untrusted hosts (make sure appropriate for your env) + remote_conn_pre.set_missing_host_key_policy(self.key_policy) + return remote_conn_pre + class HPProcurveTelnet(HPProcurveBase): def telnet_login( @@ -621,7 +650,26 @@ class HPProcurveTelnet(HPProcurveBase): # Try one last time to past "Press any key to continue self.write_channel(self.RETURN) - super(HPProcurveSSH, self).session_preparation()</code></pre> + super(HPProcurveSSH, self).session_preparation() + + def _build_ssh_client(self): + """Allow passwordless authentication for HP devices being provisioned.""" + + # Create instance of SSHClient object. If no SSH keys and no password, then use noauth + if not self.use_keys and not self.password: + remote_conn_pre = SSHClient_noauth() + else: + remote_conn_pre = SSHClient() + + # Load host_keys for better SSH security + if self.system_host_keys: + remote_conn_pre.load_system_host_keys() + if self.alt_host_keys and path.isfile(self.alt_key_file): + remote_conn_pre.load_host_keys(self.alt_key_file) + + # Default is to automatically add untrusted hosts (make sure appropriate for your env) + remote_conn_pre.set_missing_host_key_policy(self.key_policy) + return remote_conn_pre</code></pre> </details> <h3>Ancestors</h3> <ul class="hlist"> @@ -907,6 +955,27 @@ class HPProcurveTelnet(HPProcurveBase): </li> </ul> </dd> +<dt id="netmiko.hp.hp_procurve.SSHClient_noauth"><code class="flex name class"> +<span>class <span class="ident">SSHClient_noauth</span></span> +</code></dt> +<dd> +<section class="desc"><p>Set noauth when manually handling SSH authentication.</p> +<p>Create a new SSHClient.</p></section> +<details class="source"> +<summary>Source code</summary> +<pre><code class="python">class SSHClient_noauth(SSHClient): + """Set noauth when manually handling SSH authentication.""" + + def _auth(self, username, *args): + self._transport.auth_none(username) + return</code></pre> +</details> +<h3>Ancestors</h3> +<ul class="hlist"> +<li>paramiko.client.SSHClient</li> +<li>paramiko.util.ClosingContextManager</li> +</ul> +</dd> </dl> </section> </article> @@ -940,6 +1009,9 @@ class HPProcurveTelnet(HPProcurveBase): <li><code><a title="netmiko.hp.hp_procurve.HPProcurveTelnet.telnet_login" href="#netmiko.hp.hp_procurve.HPProcurveTelnet.telnet_login">telnet_login</a></code></li> </ul> </li> +<li> +<h4><code><a title="netmiko.hp.hp_procurve.SSHClient_noauth" href="#netmiko.hp.hp_procurve.SSHClient_noauth">SSHClient_noauth</a></code></h4> +</li> </ul> </li> </ul> diff --git a/docs/netmiko/hp/index.html b/docs/netmiko/hp/index.html index 348b7187abf302de845ac68a0665401ed1fb6869..d0f2c385ae36eefd1170b7967194fdffcd339f37 100644 --- a/docs/netmiko/hp/index.html +++ b/docs/netmiko/hp/index.html @@ -564,7 +564,26 @@ __all__ = ["HPProcurveSSH", "HPProcurveTelnet", "HPComwareSS # Try one last time to past "Press any key to continue self.write_channel(self.RETURN) - super(HPProcurveSSH, self).session_preparation()</code></pre> + super(HPProcurveSSH, self).session_preparation() + + def _build_ssh_client(self): + """Allow passwordless authentication for HP devices being provisioned.""" + + # Create instance of SSHClient object. If no SSH keys and no password, then use noauth + if not self.use_keys and not self.password: + remote_conn_pre = SSHClient_noauth() + else: + remote_conn_pre = SSHClient() + + # Load host_keys for better SSH security + if self.system_host_keys: + remote_conn_pre.load_system_host_keys() + if self.alt_host_keys and path.isfile(self.alt_key_file): + remote_conn_pre.load_host_keys(self.alt_key_file) + + # Default is to automatically add untrusted hosts (make sure appropriate for your env) + remote_conn_pre.set_missing_host_key_policy(self.key_policy) + return remote_conn_pre</code></pre> </details> <h3>Ancestors</h3> <ul class="hlist"> diff --git a/docs/netmiko/index.html b/docs/netmiko/index.html index 11632176a1d560d0bb4dc3a8d9f9d59da752dd5d..58a867099bf2e1cd2a9cfb8cf908a3c08c14cab6 100644 --- a/docs/netmiko/index.html +++ b/docs/netmiko/index.html @@ -47,7 +47,7 @@ NetmikoTimeoutError = NetMikoTimeoutException NetmikoAuthError = NetMikoAuthenticationException Netmiko = ConnectHandler -__version__ = "2.4.1" +__version__ = "2.4.2" __all__ = ( "ConnectHandler", "ssh_dispatcher", @@ -181,6 +181,10 @@ CNTL_SHIFT_6 = chr(30)</code></pre> <dd> <section class="desc"></section> </dd> +<dt><code class="name"><a title="netmiko.keymile" href="keymile/index.html">netmiko.keymile</a></code></dt> +<dd> +<section class="desc"></section> +</dd> <dt><code class="name"><a title="netmiko.linux" href="linux/index.html">netmiko.linux</a></code></dt> <dd> <section class="desc"></section> @@ -975,6 +979,11 @@ with terminal server.</p></section> def _write_session_log(self, data): if self.session_log is not None and len(data) > 0: + # Hide the password and secret in the session_log + if self.password: + data = data.replace(self.password, "********") + if self.secret: + data = data.replace(self.secret, "********") self.session_log.write(write_bytes(data, encoding=self.encoding)) self.session_log.flush() @@ -1348,10 +1357,20 @@ with terminal server.</p></section> else: source = {} + # Keys get normalized to lower-case if "proxycommand" in source: proxy = paramiko.ProxyCommand(source["proxycommand"]) - elif "ProxyCommand" in source: - proxy = paramiko.ProxyCommand(source["ProxyCommand"]) + elif "proxyjump" in source: + hops = list(reversed(source["proxyjump"].split(","))) + if len(hops) > 1: + raise ValueError( + "ProxyJump with more than one proxy server is not supported." + ) + port = source.get("port", self.port) + host = source.get("hostname", self.host) + # -F {full_path} forces the continued use of the same SSH config file + cmd = "ssh -F {} -W {}:{} {}".format(full_path, host, port, hops[0]) + proxy = paramiko.ProxyCommand(cmd) else: proxy = None @@ -1511,7 +1530,7 @@ with terminal server.</p></section> # check if data was ever present if new_data: - return "" + return new_data else: raise NetMikoTimeoutException("Timed out waiting for data") @@ -4603,6 +4622,7 @@ Try to determine the device type.</p> <li><code><a title="netmiko.huawei" href="huawei/index.html">netmiko.huawei</a></code></li> <li><code><a title="netmiko.ipinfusion" href="ipinfusion/index.html">netmiko.ipinfusion</a></code></li> <li><code><a title="netmiko.juniper" href="juniper/index.html">netmiko.juniper</a></code></li> +<li><code><a title="netmiko.keymile" href="keymile/index.html">netmiko.keymile</a></code></li> <li><code><a title="netmiko.linux" href="linux/index.html">netmiko.linux</a></code></li> <li><code><a title="netmiko.mellanox" href="mellanox/index.html">netmiko.mellanox</a></code></li> <li><code><a title="netmiko.mikrotik" href="mikrotik/index.html">netmiko.mikrotik</a></code></li> diff --git a/docs/netmiko/keymile/index.html b/docs/netmiko/keymile/index.html new file mode 100644 index 0000000000000000000000000000000000000000..85b3233c97170776681432858c76c5f7d2488045 --- /dev/null +++ b/docs/netmiko/keymile/index.html @@ -0,0 +1,669 @@ +<!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.2" /> +<title>netmiko.keymile 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}.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.keymile</code></h1> +</header> +<section id="section-intro"> +<details class="source"> +<summary>Source code</summary> +<pre><code class="python">from __future__ import unicode_literals +from netmiko.keymile.keymile_ssh import KeymileSSH +from netmiko.keymile.keymile_nos_ssh import KeymileNOSSSH + +__all__ = ["KeymileSSH", "KeymileNOSSSH"]</code></pre> +</details> +</section> +<section> +<h2 class="section-title" id="header-submodules">Sub-modules</h2> +<dl> +<dt><code class="name"><a title="netmiko.keymile.keymile_nos_ssh" href="keymile_nos_ssh.html">netmiko.keymile.keymile_nos_ssh</a></code></dt> +<dd> +<section class="desc"></section> +</dd> +<dt><code class="name"><a title="netmiko.keymile.keymile_ssh" href="keymile_ssh.html">netmiko.keymile.keymile_ssh</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.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, 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, timeout=100, session_timeout=60, auth_timeout=None, blocking_timeout=8, banner_timeout=5, 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')</span> +</code></dt> +<dd> +<section class="desc"><p>Common Methods for IOS (both SSH and telnet).</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 +</code></pre></section> +<details class="source"> +<summary>Source code</summary> +<pre><code class="python">class KeymileNOSSSH(CiscoIosBase): + def session_preparation(self): + """Prepare the session after the connection has been established.""" + self.set_base_prompt() + self.disable_paging() + time.sleep(0.3 * self.global_delay_factor) + self.clear_buffer() + + def _test_channel_read(self, count=40, pattern=""): + """Since Keymile NOS always returns True on paramiko.connect() we + check the output for substring Login incorrect after connecting.""" + output = super(KeymileNOSSSH, self)._test_channel_read( + count=count, pattern=pattern + ) + pattern = r"Login incorrect" + if re.search(pattern, output): + self.paramiko_cleanup() + msg = "Authentication failure: unable to connect" + msg += "{device_type} {host}:{port}".format( + device_type=self.device_type, host=self.host, port=self.port + ) + msg += self.RESPONSE_RETURN + "Login incorrect" + raise NetMikoAuthenticationException(msg) + else: + return output + + def special_login_handler(self, delay_factor=1): + """Since Keymile NOS always returns True on paramiko.connect() we + check the output for substring Login incorrect after connecting.""" + self._test_channel_read(pattern=r"(>|Login incorrect)")</code></pre> +</details> +<h3>Ancestors</h3> +<ul class="hlist"> +<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_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.keymile.KeymileNOSSSH.special_login_handler"><code class="name flex"> +<span>def <span class="ident">special_login_handler</span></span>(<span>self, delay_factor=1)</span> +</code></dt> +<dd> +<section class="desc"><p>Since Keymile NOS always returns True on paramiko.connect() we +check the output for substring Login incorrect after connecting.</p></section> +<details class="source"> +<summary>Source code</summary> +<pre><code class="python">def special_login_handler(self, delay_factor=1): + """Since Keymile NOS always returns True on paramiko.connect() we + check the output for substring Login incorrect after connecting.""" + self._test_channel_read(pattern=r"(>|Login incorrect)")</code></pre> +</details> +</dd> +</dl> +<h3>Inherited members</h3> +<ul class="hlist"> +<li><code><b><a title="netmiko.cisco.cisco_ios.CiscoIosBase" href="../cisco/cisco_ios.html#netmiko.cisco.cisco_ios.CiscoIosBase">CiscoIosBase</a></b></code>: +<ul class="hlist"> +<li><code><a title="netmiko.cisco.cisco_ios.CiscoIosBase.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.cisco_ios.CiscoIosBase.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.cisco_ios.CiscoIosBase.cleanup" href="../cisco_base_connection.html#netmiko.cisco_base_connection.CiscoBaseConnection.cleanup">cleanup</a></code></li> +<li><code><a title="netmiko.cisco.cisco_ios.CiscoIosBase.clear_buffer" href="../base_connection.html#netmiko.base_connection.BaseConnection.clear_buffer">clear_buffer</a></code></li> +<li><code><a title="netmiko.cisco.cisco_ios.CiscoIosBase.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.cisco_ios.CiscoIosBase.commit" href="../base_connection.html#netmiko.base_connection.BaseConnection.commit">commit</a></code></li> +<li><code><a title="netmiko.cisco.cisco_ios.CiscoIosBase.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.cisco_ios.CiscoIosBase.disable_paging" href="../base_connection.html#netmiko.base_connection.BaseConnection.disable_paging">disable_paging</a></code></li> +<li><code><a title="netmiko.cisco.cisco_ios.CiscoIosBase.disconnect" href="../base_connection.html#netmiko.base_connection.BaseConnection.disconnect">disconnect</a></code></li> +<li><code><a title="netmiko.cisco.cisco_ios.CiscoIosBase.enable" href="../cisco_base_connection.html#netmiko.cisco_base_connection.CiscoBaseConnection.enable">enable</a></code></li> +<li><code><a title="netmiko.cisco.cisco_ios.CiscoIosBase.establish_connection" href="../base_connection.html#netmiko.base_connection.BaseConnection.establish_connection">establish_connection</a></code></li> +<li><code><a title="netmiko.cisco.cisco_ios.CiscoIosBase.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.cisco_ios.CiscoIosBase.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_ios.CiscoIosBase.find_prompt" href="../base_connection.html#netmiko.base_connection.BaseConnection.find_prompt">find_prompt</a></code></li> +<li><code><a title="netmiko.cisco.cisco_ios.CiscoIosBase.is_alive" href="../base_connection.html#netmiko.base_connection.BaseConnection.is_alive">is_alive</a></code></li> +<li><code><a title="netmiko.cisco.cisco_ios.CiscoIosBase.normalize_cmd" href="../base_connection.html#netmiko.base_connection.BaseConnection.normalize_cmd">normalize_cmd</a></code></li> +<li><code><a title="netmiko.cisco.cisco_ios.CiscoIosBase.normalize_linefeeds" href="../base_connection.html#netmiko.base_connection.BaseConnection.normalize_linefeeds">normalize_linefeeds</a></code></li> +<li><code><a title="netmiko.cisco.cisco_ios.CiscoIosBase.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.cisco_ios.CiscoIosBase.paramiko_cleanup" href="../base_connection.html#netmiko.base_connection.BaseConnection.paramiko_cleanup">paramiko_cleanup</a></code></li> +<li><code><a title="netmiko.cisco.cisco_ios.CiscoIosBase.read_channel" href="../base_connection.html#netmiko.base_connection.BaseConnection.read_channel">read_channel</a></code></li> +<li><code><a title="netmiko.cisco.cisco_ios.CiscoIosBase.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.cisco_ios.CiscoIosBase.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.cisco_ios.CiscoIosBase.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.cisco_ios.CiscoIosBase.save_config" href="../cisco/cisco_ios.html#netmiko.cisco.cisco_ios.CiscoIosBase.save_config">save_config</a></code></li> +<li><code><a title="netmiko.cisco.cisco_ios.CiscoIosBase.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.cisco_ios.CiscoIosBase.send_command" href="../base_connection.html#netmiko.base_connection.BaseConnection.send_command">send_command</a></code></li> +<li><code><a title="netmiko.cisco.cisco_ios.CiscoIosBase.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.cisco_ios.CiscoIosBase.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.cisco_ios.CiscoIosBase.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.cisco_ios.CiscoIosBase.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.cisco_ios.CiscoIosBase.session_preparation" href="../cisco/cisco_ios.html#netmiko.cisco.cisco_ios.CiscoIosBase.session_preparation">session_preparation</a></code></li> +<li><code><a title="netmiko.cisco.cisco_ios.CiscoIosBase.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.cisco_ios.CiscoIosBase.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.cisco_ios.CiscoIosBase.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.cisco_ios.CiscoIosBase.strip_backspaces" href="../base_connection.html#netmiko.base_connection.BaseConnection.strip_backspaces">strip_backspaces</a></code></li> +<li><code><a title="netmiko.cisco.cisco_ios.CiscoIosBase.strip_command" href="../base_connection.html#netmiko.base_connection.BaseConnection.strip_command">strip_command</a></code></li> +<li><code><a title="netmiko.cisco.cisco_ios.CiscoIosBase.strip_prompt" href="../base_connection.html#netmiko.base_connection.BaseConnection.strip_prompt">strip_prompt</a></code></li> +<li><code><a title="netmiko.cisco.cisco_ios.CiscoIosBase.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.cisco_ios.CiscoIosBase.write_channel" href="../base_connection.html#netmiko.base_connection.BaseConnection.write_channel">write_channel</a></code></li> +</ul> +</li> +</ul> +</dd> +<dt id="netmiko.keymile.KeymileSSH"><code class="flex name class"> +<span>class <span class="ident">KeymileSSH</span></span> +<span>(</span><span>**kwargs)</span> +</code></dt> +<dd> +<section class="desc"><p>Common Methods for IOS (both SSH and telnet).</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 +</code></pre></section> +<details class="source"> +<summary>Source code</summary> +<pre><code class="python">class KeymileSSH(CiscoIosBase): + def __init__(self, **kwargs): + kwargs.setdefault("default_enter", "\r\n") + return super(KeymileSSH, self).__init__(**kwargs) + + def session_preparation(self): + """Prepare the session after the connection has been established.""" + self._test_channel_read(pattern=r">") + self.set_base_prompt() + time.sleep(0.3 * self.global_delay_factor) + self.clear_buffer() + + def disable_paging(self, *args, **kwargs): + """Keymile does not use paging.""" + return "" + + def check_config_mode(self, *args, **kwargs): + """Keymile does not use config mode.""" + return False + + def config_mode(self, *args, **kwargs): + """Keymile does not use config mode.""" + return "" + + def exit_config_mode(self, *args, **kwargs): + """Keymile does not use config mode.""" + return "" + + def check_enable_mode(self, *args, **kwargs): + """Keymile does not use enable mode.""" + return False + + def enable(self, *args, **kwargs): + """Keymile does not use enable mode.""" + return "" + + def exit_enable_mode(self, *args, **kwargs): + """Keymile does not use enable mode.""" + return "" + + def strip_prompt(self, a_string): + """Remove appending empty line and prompt from output""" + self._write_session_log(a_string) + a_string = a_string[:-1] + return super(KeymileSSH, self).strip_prompt(a_string=a_string) + + def set_base_prompt(self, pri_prompt_terminator=">", **kwargs): + """ set prompt termination to >""" + return super(KeymileSSH, self).set_base_prompt( + pri_prompt_terminator=pri_prompt_terminator + )</code></pre> +</details> +<h3>Ancestors</h3> +<ul class="hlist"> +<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_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.keymile.KeymileSSH.check_config_mode"><code class="name flex"> +<span>def <span class="ident">check_config_mode</span></span>(<span>self, *args, **kwargs)</span> +</code></dt> +<dd> +<section class="desc"><p>Keymile does not use config mode.</p></section> +<details class="source"> +<summary>Source code</summary> +<pre><code class="python">def check_config_mode(self, *args, **kwargs): + """Keymile does not use config mode.""" + return False</code></pre> +</details> +</dd> +<dt id="netmiko.keymile.KeymileSSH.check_enable_mode"><code class="name flex"> +<span>def <span class="ident">check_enable_mode</span></span>(<span>self, *args, **kwargs)</span> +</code></dt> +<dd> +<section class="desc"><p>Keymile does not use enable mode.</p></section> +<details class="source"> +<summary>Source code</summary> +<pre><code class="python">def check_enable_mode(self, *args, **kwargs): + """Keymile does not use enable mode.""" + return False</code></pre> +</details> +</dd> +<dt id="netmiko.keymile.KeymileSSH.config_mode"><code class="name flex"> +<span>def <span class="ident">config_mode</span></span>(<span>self, *args, **kwargs)</span> +</code></dt> +<dd> +<section class="desc"><p>Keymile does not use config mode.</p></section> +<details class="source"> +<summary>Source code</summary> +<pre><code class="python">def config_mode(self, *args, **kwargs): + """Keymile does not use config mode.""" + return ""</code></pre> +</details> +</dd> +<dt id="netmiko.keymile.KeymileSSH.disable_paging"><code class="name flex"> +<span>def <span class="ident">disable_paging</span></span>(<span>self, *args, **kwargs)</span> +</code></dt> +<dd> +<section class="desc"><p>Keymile does not use paging.</p></section> +<details class="source"> +<summary>Source code</summary> +<pre><code class="python">def disable_paging(self, *args, **kwargs): + """Keymile does not use paging.""" + return ""</code></pre> +</details> +</dd> +<dt id="netmiko.keymile.KeymileSSH.enable"><code class="name flex"> +<span>def <span class="ident">enable</span></span>(<span>self, *args, **kwargs)</span> +</code></dt> +<dd> +<section class="desc"><p>Keymile does not use enable mode.</p></section> +<details class="source"> +<summary>Source code</summary> +<pre><code class="python">def enable(self, *args, **kwargs): + """Keymile does not use enable mode.""" + return ""</code></pre> +</details> +</dd> +<dt id="netmiko.keymile.KeymileSSH.exit_config_mode"><code class="name flex"> +<span>def <span class="ident">exit_config_mode</span></span>(<span>self, *args, **kwargs)</span> +</code></dt> +<dd> +<section class="desc"><p>Keymile does not use config mode.</p></section> +<details class="source"> +<summary>Source code</summary> +<pre><code class="python">def exit_config_mode(self, *args, **kwargs): + """Keymile does not use config mode.""" + return ""</code></pre> +</details> +</dd> +<dt id="netmiko.keymile.KeymileSSH.exit_enable_mode"><code class="name flex"> +<span>def <span class="ident">exit_enable_mode</span></span>(<span>self, *args, **kwargs)</span> +</code></dt> +<dd> +<section class="desc"><p>Keymile does not use enable mode.</p></section> +<details class="source"> +<summary>Source code</summary> +<pre><code class="python">def exit_enable_mode(self, *args, **kwargs): + """Keymile does not use enable mode.""" + return ""</code></pre> +</details> +</dd> +<dt id="netmiko.keymile.KeymileSSH.set_base_prompt"><code class="name flex"> +<span>def <span class="ident">set_base_prompt</span></span>(<span>self, pri_prompt_terminator='>', **kwargs)</span> +</code></dt> +<dd> +<section class="desc"><p>set prompt termination +to ></p></section> +<details class="source"> +<summary>Source code</summary> +<pre><code class="python">def set_base_prompt(self, pri_prompt_terminator=">", **kwargs): + """ set prompt termination to >""" + return super(KeymileSSH, self).set_base_prompt( + pri_prompt_terminator=pri_prompt_terminator + )</code></pre> +</details> +</dd> +<dt id="netmiko.keymile.KeymileSSH.strip_prompt"><code class="name flex"> +<span>def <span class="ident">strip_prompt</span></span>(<span>self, a_string)</span> +</code></dt> +<dd> +<section class="desc"><p>Remove appending empty line and prompt from output</p></section> +<details class="source"> +<summary>Source code</summary> +<pre><code class="python">def strip_prompt(self, a_string): + """Remove appending empty line and prompt from output""" + self._write_session_log(a_string) + a_string = a_string[:-1] + return super(KeymileSSH, self).strip_prompt(a_string=a_string)</code></pre> +</details> +</dd> +</dl> +<h3>Inherited members</h3> +<ul class="hlist"> +<li><code><b><a title="netmiko.cisco.cisco_ios.CiscoIosBase" href="../cisco/cisco_ios.html#netmiko.cisco.cisco_ios.CiscoIosBase">CiscoIosBase</a></b></code>: +<ul class="hlist"> +<li><code><a title="netmiko.cisco.cisco_ios.CiscoIosBase.cleanup" href="../cisco_base_connection.html#netmiko.cisco_base_connection.CiscoBaseConnection.cleanup">cleanup</a></code></li> +<li><code><a title="netmiko.cisco.cisco_ios.CiscoIosBase.clear_buffer" href="../base_connection.html#netmiko.base_connection.BaseConnection.clear_buffer">clear_buffer</a></code></li> +<li><code><a title="netmiko.cisco.cisco_ios.CiscoIosBase.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.cisco_ios.CiscoIosBase.commit" href="../base_connection.html#netmiko.base_connection.BaseConnection.commit">commit</a></code></li> +<li><code><a title="netmiko.cisco.cisco_ios.CiscoIosBase.disconnect" href="../base_connection.html#netmiko.base_connection.BaseConnection.disconnect">disconnect</a></code></li> +<li><code><a title="netmiko.cisco.cisco_ios.CiscoIosBase.establish_connection" href="../base_connection.html#netmiko.base_connection.BaseConnection.establish_connection">establish_connection</a></code></li> +<li><code><a title="netmiko.cisco.cisco_ios.CiscoIosBase.find_prompt" href="../base_connection.html#netmiko.base_connection.BaseConnection.find_prompt">find_prompt</a></code></li> +<li><code><a title="netmiko.cisco.cisco_ios.CiscoIosBase.is_alive" href="../base_connection.html#netmiko.base_connection.BaseConnection.is_alive">is_alive</a></code></li> +<li><code><a title="netmiko.cisco.cisco_ios.CiscoIosBase.normalize_cmd" href="../base_connection.html#netmiko.base_connection.BaseConnection.normalize_cmd">normalize_cmd</a></code></li> +<li><code><a title="netmiko.cisco.cisco_ios.CiscoIosBase.normalize_linefeeds" href="../base_connection.html#netmiko.base_connection.BaseConnection.normalize_linefeeds">normalize_linefeeds</a></code></li> +<li><code><a title="netmiko.cisco.cisco_ios.CiscoIosBase.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.cisco_ios.CiscoIosBase.paramiko_cleanup" href="../base_connection.html#netmiko.base_connection.BaseConnection.paramiko_cleanup">paramiko_cleanup</a></code></li> +<li><code><a title="netmiko.cisco.cisco_ios.CiscoIosBase.read_channel" href="../base_connection.html#netmiko.base_connection.BaseConnection.read_channel">read_channel</a></code></li> +<li><code><a title="netmiko.cisco.cisco_ios.CiscoIosBase.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.cisco_ios.CiscoIosBase.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.cisco_ios.CiscoIosBase.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.cisco_ios.CiscoIosBase.save_config" href="../cisco/cisco_ios.html#netmiko.cisco.cisco_ios.CiscoIosBase.save_config">save_config</a></code></li> +<li><code><a title="netmiko.cisco.cisco_ios.CiscoIosBase.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.cisco_ios.CiscoIosBase.send_command" href="../base_connection.html#netmiko.base_connection.BaseConnection.send_command">send_command</a></code></li> +<li><code><a title="netmiko.cisco.cisco_ios.CiscoIosBase.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.cisco_ios.CiscoIosBase.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.cisco_ios.CiscoIosBase.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.cisco_ios.CiscoIosBase.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.cisco_ios.CiscoIosBase.session_preparation" href="../cisco/cisco_ios.html#netmiko.cisco.cisco_ios.CiscoIosBase.session_preparation">session_preparation</a></code></li> +<li><code><a title="netmiko.cisco.cisco_ios.CiscoIosBase.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.cisco_ios.CiscoIosBase.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.cisco_ios.CiscoIosBase.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.cisco_ios.CiscoIosBase.strip_backspaces" href="../base_connection.html#netmiko.base_connection.BaseConnection.strip_backspaces">strip_backspaces</a></code></li> +<li><code><a title="netmiko.cisco.cisco_ios.CiscoIosBase.strip_command" href="../base_connection.html#netmiko.base_connection.BaseConnection.strip_command">strip_command</a></code></li> +<li><code><a title="netmiko.cisco.cisco_ios.CiscoIosBase.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.cisco_ios.CiscoIosBase.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.keymile.keymile_nos_ssh" href="keymile_nos_ssh.html">netmiko.keymile.keymile_nos_ssh</a></code></li> +<li><code><a title="netmiko.keymile.keymile_ssh" href="keymile_ssh.html">netmiko.keymile.keymile_ssh</a></code></li> +</ul> +</li> +<li><h3><a href="#header-classes">Classes</a></h3> +<ul> +<li> +<h4><code><a title="netmiko.keymile.KeymileNOSSSH" href="#netmiko.keymile.KeymileNOSSSH">KeymileNOSSSH</a></code></h4> +<ul class=""> +<li><code><a title="netmiko.keymile.KeymileNOSSSH.special_login_handler" href="#netmiko.keymile.KeymileNOSSSH.special_login_handler">special_login_handler</a></code></li> +</ul> +</li> +<li> +<h4><code><a title="netmiko.keymile.KeymileSSH" href="#netmiko.keymile.KeymileSSH">KeymileSSH</a></code></h4> +<ul class="two-column"> +<li><code><a title="netmiko.keymile.KeymileSSH.check_config_mode" href="#netmiko.keymile.KeymileSSH.check_config_mode">check_config_mode</a></code></li> +<li><code><a title="netmiko.keymile.KeymileSSH.check_enable_mode" href="#netmiko.keymile.KeymileSSH.check_enable_mode">check_enable_mode</a></code></li> +<li><code><a title="netmiko.keymile.KeymileSSH.config_mode" href="#netmiko.keymile.KeymileSSH.config_mode">config_mode</a></code></li> +<li><code><a title="netmiko.keymile.KeymileSSH.disable_paging" href="#netmiko.keymile.KeymileSSH.disable_paging">disable_paging</a></code></li> +<li><code><a title="netmiko.keymile.KeymileSSH.enable" href="#netmiko.keymile.KeymileSSH.enable">enable</a></code></li> +<li><code><a title="netmiko.keymile.KeymileSSH.exit_config_mode" href="#netmiko.keymile.KeymileSSH.exit_config_mode">exit_config_mode</a></code></li> +<li><code><a title="netmiko.keymile.KeymileSSH.exit_enable_mode" href="#netmiko.keymile.KeymileSSH.exit_enable_mode">exit_enable_mode</a></code></li> +<li><code><a title="netmiko.keymile.KeymileSSH.set_base_prompt" href="#netmiko.keymile.KeymileSSH.set_base_prompt">set_base_prompt</a></code></li> +<li><code><a title="netmiko.keymile.KeymileSSH.strip_prompt" href="#netmiko.keymile.KeymileSSH.strip_prompt">strip_prompt</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.2</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/keymile/keymile_nos_ssh.html b/docs/netmiko/keymile/keymile_nos_ssh.html new file mode 100644 index 0000000000000000000000000000000000000000..ff5ab3a839046bd31771164d10c4bfa162013ef9 --- /dev/null +++ b/docs/netmiko/keymile/keymile_nos_ssh.html @@ -0,0 +1,333 @@ +<!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.2" /> +<title>netmiko.keymile.keymile_nos_ssh 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}.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.keymile.keymile_nos_ssh</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.cisco_ios import CiscoIosBase +from netmiko.ssh_exception import NetMikoAuthenticationException + + +class KeymileNOSSSH(CiscoIosBase): + def session_preparation(self): + """Prepare the session after the connection has been established.""" + self.set_base_prompt() + self.disable_paging() + time.sleep(0.3 * self.global_delay_factor) + self.clear_buffer() + + def _test_channel_read(self, count=40, pattern=""): + """Since Keymile NOS always returns True on paramiko.connect() we + check the output for substring Login incorrect after connecting.""" + output = super(KeymileNOSSSH, self)._test_channel_read( + count=count, pattern=pattern + ) + pattern = r"Login incorrect" + if re.search(pattern, output): + self.paramiko_cleanup() + msg = "Authentication failure: unable to connect" + msg += "{device_type} {host}:{port}".format( + device_type=self.device_type, host=self.host, port=self.port + ) + msg += self.RESPONSE_RETURN + "Login incorrect" + raise NetMikoAuthenticationException(msg) + else: + return output + + def special_login_handler(self, delay_factor=1): + """Since Keymile NOS always returns True on paramiko.connect() we + check the output for substring Login incorrect after connecting.""" + self._test_channel_read(pattern=r"(>|Login incorrect)")</code></pre> +</details> +</section> +<section> +</section> +<section> +</section> +<section> +</section> +<section> +<h2 class="section-title" id="header-classes">Classes</h2> +<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, 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, timeout=100, session_timeout=60, auth_timeout=None, blocking_timeout=8, banner_timeout=5, 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')</span> +</code></dt> +<dd> +<section class="desc"><p>Common Methods for IOS (both SSH and telnet).</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 +</code></pre></section> +<details class="source"> +<summary>Source code</summary> +<pre><code class="python">class KeymileNOSSSH(CiscoIosBase): + def session_preparation(self): + """Prepare the session after the connection has been established.""" + self.set_base_prompt() + self.disable_paging() + time.sleep(0.3 * self.global_delay_factor) + self.clear_buffer() + + def _test_channel_read(self, count=40, pattern=""): + """Since Keymile NOS always returns True on paramiko.connect() we + check the output for substring Login incorrect after connecting.""" + output = super(KeymileNOSSSH, self)._test_channel_read( + count=count, pattern=pattern + ) + pattern = r"Login incorrect" + if re.search(pattern, output): + self.paramiko_cleanup() + msg = "Authentication failure: unable to connect" + msg += "{device_type} {host}:{port}".format( + device_type=self.device_type, host=self.host, port=self.port + ) + msg += self.RESPONSE_RETURN + "Login incorrect" + raise NetMikoAuthenticationException(msg) + else: + return output + + def special_login_handler(self, delay_factor=1): + """Since Keymile NOS always returns True on paramiko.connect() we + check the output for substring Login incorrect after connecting.""" + self._test_channel_read(pattern=r"(>|Login incorrect)")</code></pre> +</details> +<h3>Ancestors</h3> +<ul class="hlist"> +<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_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.keymile.keymile_nos_ssh.KeymileNOSSSH.special_login_handler"><code class="name flex"> +<span>def <span class="ident">special_login_handler</span></span>(<span>self, delay_factor=1)</span> +</code></dt> +<dd> +<section class="desc"><p>Since Keymile NOS always returns True on paramiko.connect() we +check the output for substring Login incorrect after connecting.</p></section> +<details class="source"> +<summary>Source code</summary> +<pre><code class="python">def special_login_handler(self, delay_factor=1): + """Since Keymile NOS always returns True on paramiko.connect() we + check the output for substring Login incorrect after connecting.""" + self._test_channel_read(pattern=r"(>|Login incorrect)")</code></pre> +</details> +</dd> +</dl> +<h3>Inherited members</h3> +<ul class="hlist"> +<li><code><b><a title="netmiko.cisco.cisco_ios.CiscoIosBase" href="../cisco/cisco_ios.html#netmiko.cisco.cisco_ios.CiscoIosBase">CiscoIosBase</a></b></code>: +<ul class="hlist"> +<li><code><a title="netmiko.cisco.cisco_ios.CiscoIosBase.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.cisco_ios.CiscoIosBase.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.cisco_ios.CiscoIosBase.cleanup" href="../cisco_base_connection.html#netmiko.cisco_base_connection.CiscoBaseConnection.cleanup">cleanup</a></code></li> +<li><code><a title="netmiko.cisco.cisco_ios.CiscoIosBase.clear_buffer" href="../base_connection.html#netmiko.base_connection.BaseConnection.clear_buffer">clear_buffer</a></code></li> +<li><code><a title="netmiko.cisco.cisco_ios.CiscoIosBase.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.cisco_ios.CiscoIosBase.commit" href="../base_connection.html#netmiko.base_connection.BaseConnection.commit">commit</a></code></li> +<li><code><a title="netmiko.cisco.cisco_ios.CiscoIosBase.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.cisco_ios.CiscoIosBase.disable_paging" href="../base_connection.html#netmiko.base_connection.BaseConnection.disable_paging">disable_paging</a></code></li> +<li><code><a title="netmiko.cisco.cisco_ios.CiscoIosBase.disconnect" href="../base_connection.html#netmiko.base_connection.BaseConnection.disconnect">disconnect</a></code></li> +<li><code><a title="netmiko.cisco.cisco_ios.CiscoIosBase.enable" href="../cisco_base_connection.html#netmiko.cisco_base_connection.CiscoBaseConnection.enable">enable</a></code></li> +<li><code><a title="netmiko.cisco.cisco_ios.CiscoIosBase.establish_connection" href="../base_connection.html#netmiko.base_connection.BaseConnection.establish_connection">establish_connection</a></code></li> +<li><code><a title="netmiko.cisco.cisco_ios.CiscoIosBase.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.cisco_ios.CiscoIosBase.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_ios.CiscoIosBase.find_prompt" href="../base_connection.html#netmiko.base_connection.BaseConnection.find_prompt">find_prompt</a></code></li> +<li><code><a title="netmiko.cisco.cisco_ios.CiscoIosBase.is_alive" href="../base_connection.html#netmiko.base_connection.BaseConnection.is_alive">is_alive</a></code></li> +<li><code><a title="netmiko.cisco.cisco_ios.CiscoIosBase.normalize_cmd" href="../base_connection.html#netmiko.base_connection.BaseConnection.normalize_cmd">normalize_cmd</a></code></li> +<li><code><a title="netmiko.cisco.cisco_ios.CiscoIosBase.normalize_linefeeds" href="../base_connection.html#netmiko.base_connection.BaseConnection.normalize_linefeeds">normalize_linefeeds</a></code></li> +<li><code><a title="netmiko.cisco.cisco_ios.CiscoIosBase.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.cisco_ios.CiscoIosBase.paramiko_cleanup" href="../base_connection.html#netmiko.base_connection.BaseConnection.paramiko_cleanup">paramiko_cleanup</a></code></li> +<li><code><a title="netmiko.cisco.cisco_ios.CiscoIosBase.read_channel" href="../base_connection.html#netmiko.base_connection.BaseConnection.read_channel">read_channel</a></code></li> +<li><code><a title="netmiko.cisco.cisco_ios.CiscoIosBase.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.cisco_ios.CiscoIosBase.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.cisco_ios.CiscoIosBase.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.cisco_ios.CiscoIosBase.save_config" href="../cisco/cisco_ios.html#netmiko.cisco.cisco_ios.CiscoIosBase.save_config">save_config</a></code></li> +<li><code><a title="netmiko.cisco.cisco_ios.CiscoIosBase.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.cisco_ios.CiscoIosBase.send_command" href="../base_connection.html#netmiko.base_connection.BaseConnection.send_command">send_command</a></code></li> +<li><code><a title="netmiko.cisco.cisco_ios.CiscoIosBase.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.cisco_ios.CiscoIosBase.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.cisco_ios.CiscoIosBase.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.cisco_ios.CiscoIosBase.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.cisco_ios.CiscoIosBase.session_preparation" href="../cisco/cisco_ios.html#netmiko.cisco.cisco_ios.CiscoIosBase.session_preparation">session_preparation</a></code></li> +<li><code><a title="netmiko.cisco.cisco_ios.CiscoIosBase.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.cisco_ios.CiscoIosBase.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.cisco_ios.CiscoIosBase.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.cisco_ios.CiscoIosBase.strip_backspaces" href="../base_connection.html#netmiko.base_connection.BaseConnection.strip_backspaces">strip_backspaces</a></code></li> +<li><code><a title="netmiko.cisco.cisco_ios.CiscoIosBase.strip_command" href="../base_connection.html#netmiko.base_connection.BaseConnection.strip_command">strip_command</a></code></li> +<li><code><a title="netmiko.cisco.cisco_ios.CiscoIosBase.strip_prompt" href="../base_connection.html#netmiko.base_connection.BaseConnection.strip_prompt">strip_prompt</a></code></li> +<li><code><a title="netmiko.cisco.cisco_ios.CiscoIosBase.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.cisco_ios.CiscoIosBase.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.keymile" href="index.html">netmiko.keymile</a></code></li> +</ul> +</li> +<li><h3><a href="#header-classes">Classes</a></h3> +<ul> +<li> +<h4><code><a title="netmiko.keymile.keymile_nos_ssh.KeymileNOSSSH" href="#netmiko.keymile.keymile_nos_ssh.KeymileNOSSSH">KeymileNOSSSH</a></code></h4> +<ul class=""> +<li><code><a title="netmiko.keymile.keymile_nos_ssh.KeymileNOSSSH.special_login_handler" href="#netmiko.keymile.keymile_nos_ssh.KeymileNOSSSH.special_login_handler">special_login_handler</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.2</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/keymile/keymile_ssh.html b/docs/netmiko/keymile/keymile_ssh.html new file mode 100644 index 0000000000000000000000000000000000000000..b663494b4fc658123b7768ef11c67384c2498cda --- /dev/null +++ b/docs/netmiko/keymile/keymile_ssh.html @@ -0,0 +1,471 @@ +<!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.2" /> +<title>netmiko.keymile.keymile_ssh 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}.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.keymile.keymile_ssh</code></h1> +</header> +<section id="section-intro"> +<details class="source"> +<summary>Source code</summary> +<pre><code class="python">import time + +from netmiko.cisco.cisco_ios import CiscoIosBase + + +class KeymileSSH(CiscoIosBase): + def __init__(self, **kwargs): + kwargs.setdefault("default_enter", "\r\n") + return super(KeymileSSH, self).__init__(**kwargs) + + def session_preparation(self): + """Prepare the session after the connection has been established.""" + self._test_channel_read(pattern=r">") + self.set_base_prompt() + time.sleep(0.3 * self.global_delay_factor) + self.clear_buffer() + + def disable_paging(self, *args, **kwargs): + """Keymile does not use paging.""" + return "" + + def check_config_mode(self, *args, **kwargs): + """Keymile does not use config mode.""" + return False + + def config_mode(self, *args, **kwargs): + """Keymile does not use config mode.""" + return "" + + def exit_config_mode(self, *args, **kwargs): + """Keymile does not use config mode.""" + return "" + + def check_enable_mode(self, *args, **kwargs): + """Keymile does not use enable mode.""" + return False + + def enable(self, *args, **kwargs): + """Keymile does not use enable mode.""" + return "" + + def exit_enable_mode(self, *args, **kwargs): + """Keymile does not use enable mode.""" + return "" + + def strip_prompt(self, a_string): + """Remove appending empty line and prompt from output""" + self._write_session_log(a_string) + a_string = a_string[:-1] + return super(KeymileSSH, self).strip_prompt(a_string=a_string) + + def set_base_prompt(self, pri_prompt_terminator=">", **kwargs): + """ set prompt termination to >""" + return super(KeymileSSH, self).set_base_prompt( + pri_prompt_terminator=pri_prompt_terminator + )</code></pre> +</details> +</section> +<section> +</section> +<section> +</section> +<section> +</section> +<section> +<h2 class="section-title" id="header-classes">Classes</h2> +<dl> +<dt id="netmiko.keymile.keymile_ssh.KeymileSSH"><code class="flex name class"> +<span>class <span class="ident">KeymileSSH</span></span> +<span>(</span><span>**kwargs)</span> +</code></dt> +<dd> +<section class="desc"><p>Common Methods for IOS (both SSH and telnet).</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 +</code></pre></section> +<details class="source"> +<summary>Source code</summary> +<pre><code class="python">class KeymileSSH(CiscoIosBase): + def __init__(self, **kwargs): + kwargs.setdefault("default_enter", "\r\n") + return super(KeymileSSH, self).__init__(**kwargs) + + def session_preparation(self): + """Prepare the session after the connection has been established.""" + self._test_channel_read(pattern=r">") + self.set_base_prompt() + time.sleep(0.3 * self.global_delay_factor) + self.clear_buffer() + + def disable_paging(self, *args, **kwargs): + """Keymile does not use paging.""" + return "" + + def check_config_mode(self, *args, **kwargs): + """Keymile does not use config mode.""" + return False + + def config_mode(self, *args, **kwargs): + """Keymile does not use config mode.""" + return "" + + def exit_config_mode(self, *args, **kwargs): + """Keymile does not use config mode.""" + return "" + + def check_enable_mode(self, *args, **kwargs): + """Keymile does not use enable mode.""" + return False + + def enable(self, *args, **kwargs): + """Keymile does not use enable mode.""" + return "" + + def exit_enable_mode(self, *args, **kwargs): + """Keymile does not use enable mode.""" + return "" + + def strip_prompt(self, a_string): + """Remove appending empty line and prompt from output""" + self._write_session_log(a_string) + a_string = a_string[:-1] + return super(KeymileSSH, self).strip_prompt(a_string=a_string) + + def set_base_prompt(self, pri_prompt_terminator=">", **kwargs): + """ set prompt termination to >""" + return super(KeymileSSH, self).set_base_prompt( + pri_prompt_terminator=pri_prompt_terminator + )</code></pre> +</details> +<h3>Ancestors</h3> +<ul class="hlist"> +<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_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.keymile.keymile_ssh.KeymileSSH.check_config_mode"><code class="name flex"> +<span>def <span class="ident">check_config_mode</span></span>(<span>self, *args, **kwargs)</span> +</code></dt> +<dd> +<section class="desc"><p>Keymile does not use config mode.</p></section> +<details class="source"> +<summary>Source code</summary> +<pre><code class="python">def check_config_mode(self, *args, **kwargs): + """Keymile does not use config mode.""" + return False</code></pre> +</details> +</dd> +<dt id="netmiko.keymile.keymile_ssh.KeymileSSH.check_enable_mode"><code class="name flex"> +<span>def <span class="ident">check_enable_mode</span></span>(<span>self, *args, **kwargs)</span> +</code></dt> +<dd> +<section class="desc"><p>Keymile does not use enable mode.</p></section> +<details class="source"> +<summary>Source code</summary> +<pre><code class="python">def check_enable_mode(self, *args, **kwargs): + """Keymile does not use enable mode.""" + return False</code></pre> +</details> +</dd> +<dt id="netmiko.keymile.keymile_ssh.KeymileSSH.config_mode"><code class="name flex"> +<span>def <span class="ident">config_mode</span></span>(<span>self, *args, **kwargs)</span> +</code></dt> +<dd> +<section class="desc"><p>Keymile does not use config mode.</p></section> +<details class="source"> +<summary>Source code</summary> +<pre><code class="python">def config_mode(self, *args, **kwargs): + """Keymile does not use config mode.""" + return ""</code></pre> +</details> +</dd> +<dt id="netmiko.keymile.keymile_ssh.KeymileSSH.disable_paging"><code class="name flex"> +<span>def <span class="ident">disable_paging</span></span>(<span>self, *args, **kwargs)</span> +</code></dt> +<dd> +<section class="desc"><p>Keymile does not use paging.</p></section> +<details class="source"> +<summary>Source code</summary> +<pre><code class="python">def disable_paging(self, *args, **kwargs): + """Keymile does not use paging.""" + return ""</code></pre> +</details> +</dd> +<dt id="netmiko.keymile.keymile_ssh.KeymileSSH.enable"><code class="name flex"> +<span>def <span class="ident">enable</span></span>(<span>self, *args, **kwargs)</span> +</code></dt> +<dd> +<section class="desc"><p>Keymile does not use enable mode.</p></section> +<details class="source"> +<summary>Source code</summary> +<pre><code class="python">def enable(self, *args, **kwargs): + """Keymile does not use enable mode.""" + return ""</code></pre> +</details> +</dd> +<dt id="netmiko.keymile.keymile_ssh.KeymileSSH.exit_config_mode"><code class="name flex"> +<span>def <span class="ident">exit_config_mode</span></span>(<span>self, *args, **kwargs)</span> +</code></dt> +<dd> +<section class="desc"><p>Keymile does not use config mode.</p></section> +<details class="source"> +<summary>Source code</summary> +<pre><code class="python">def exit_config_mode(self, *args, **kwargs): + """Keymile does not use config mode.""" + return ""</code></pre> +</details> +</dd> +<dt id="netmiko.keymile.keymile_ssh.KeymileSSH.exit_enable_mode"><code class="name flex"> +<span>def <span class="ident">exit_enable_mode</span></span>(<span>self, *args, **kwargs)</span> +</code></dt> +<dd> +<section class="desc"><p>Keymile does not use enable mode.</p></section> +<details class="source"> +<summary>Source code</summary> +<pre><code class="python">def exit_enable_mode(self, *args, **kwargs): + """Keymile does not use enable mode.""" + return ""</code></pre> +</details> +</dd> +<dt id="netmiko.keymile.keymile_ssh.KeymileSSH.set_base_prompt"><code class="name flex"> +<span>def <span class="ident">set_base_prompt</span></span>(<span>self, pri_prompt_terminator='>', **kwargs)</span> +</code></dt> +<dd> +<section class="desc"><p>set prompt termination +to ></p></section> +<details class="source"> +<summary>Source code</summary> +<pre><code class="python">def set_base_prompt(self, pri_prompt_terminator=">", **kwargs): + """ set prompt termination to >""" + return super(KeymileSSH, self).set_base_prompt( + pri_prompt_terminator=pri_prompt_terminator + )</code></pre> +</details> +</dd> +<dt id="netmiko.keymile.keymile_ssh.KeymileSSH.strip_prompt"><code class="name flex"> +<span>def <span class="ident">strip_prompt</span></span>(<span>self, a_string)</span> +</code></dt> +<dd> +<section class="desc"><p>Remove appending empty line and prompt from output</p></section> +<details class="source"> +<summary>Source code</summary> +<pre><code class="python">def strip_prompt(self, a_string): + """Remove appending empty line and prompt from output""" + self._write_session_log(a_string) + a_string = a_string[:-1] + return super(KeymileSSH, self).strip_prompt(a_string=a_string)</code></pre> +</details> +</dd> +</dl> +<h3>Inherited members</h3> +<ul class="hlist"> +<li><code><b><a title="netmiko.cisco.cisco_ios.CiscoIosBase" href="../cisco/cisco_ios.html#netmiko.cisco.cisco_ios.CiscoIosBase">CiscoIosBase</a></b></code>: +<ul class="hlist"> +<li><code><a title="netmiko.cisco.cisco_ios.CiscoIosBase.cleanup" href="../cisco_base_connection.html#netmiko.cisco_base_connection.CiscoBaseConnection.cleanup">cleanup</a></code></li> +<li><code><a title="netmiko.cisco.cisco_ios.CiscoIosBase.clear_buffer" href="../base_connection.html#netmiko.base_connection.BaseConnection.clear_buffer">clear_buffer</a></code></li> +<li><code><a title="netmiko.cisco.cisco_ios.CiscoIosBase.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.cisco_ios.CiscoIosBase.commit" href="../base_connection.html#netmiko.base_connection.BaseConnection.commit">commit</a></code></li> +<li><code><a title="netmiko.cisco.cisco_ios.CiscoIosBase.disconnect" href="../base_connection.html#netmiko.base_connection.BaseConnection.disconnect">disconnect</a></code></li> +<li><code><a title="netmiko.cisco.cisco_ios.CiscoIosBase.establish_connection" href="../base_connection.html#netmiko.base_connection.BaseConnection.establish_connection">establish_connection</a></code></li> +<li><code><a title="netmiko.cisco.cisco_ios.CiscoIosBase.find_prompt" href="../base_connection.html#netmiko.base_connection.BaseConnection.find_prompt">find_prompt</a></code></li> +<li><code><a title="netmiko.cisco.cisco_ios.CiscoIosBase.is_alive" href="../base_connection.html#netmiko.base_connection.BaseConnection.is_alive">is_alive</a></code></li> +<li><code><a title="netmiko.cisco.cisco_ios.CiscoIosBase.normalize_cmd" href="../base_connection.html#netmiko.base_connection.BaseConnection.normalize_cmd">normalize_cmd</a></code></li> +<li><code><a title="netmiko.cisco.cisco_ios.CiscoIosBase.normalize_linefeeds" href="../base_connection.html#netmiko.base_connection.BaseConnection.normalize_linefeeds">normalize_linefeeds</a></code></li> +<li><code><a title="netmiko.cisco.cisco_ios.CiscoIosBase.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.cisco_ios.CiscoIosBase.paramiko_cleanup" href="../base_connection.html#netmiko.base_connection.BaseConnection.paramiko_cleanup">paramiko_cleanup</a></code></li> +<li><code><a title="netmiko.cisco.cisco_ios.CiscoIosBase.read_channel" href="../base_connection.html#netmiko.base_connection.BaseConnection.read_channel">read_channel</a></code></li> +<li><code><a title="netmiko.cisco.cisco_ios.CiscoIosBase.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.cisco_ios.CiscoIosBase.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.cisco_ios.CiscoIosBase.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.cisco_ios.CiscoIosBase.save_config" href="../cisco/cisco_ios.html#netmiko.cisco.cisco_ios.CiscoIosBase.save_config">save_config</a></code></li> +<li><code><a title="netmiko.cisco.cisco_ios.CiscoIosBase.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.cisco_ios.CiscoIosBase.send_command" href="../base_connection.html#netmiko.base_connection.BaseConnection.send_command">send_command</a></code></li> +<li><code><a title="netmiko.cisco.cisco_ios.CiscoIosBase.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.cisco_ios.CiscoIosBase.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.cisco_ios.CiscoIosBase.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.cisco_ios.CiscoIosBase.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.cisco_ios.CiscoIosBase.session_preparation" href="../cisco/cisco_ios.html#netmiko.cisco.cisco_ios.CiscoIosBase.session_preparation">session_preparation</a></code></li> +<li><code><a title="netmiko.cisco.cisco_ios.CiscoIosBase.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.cisco_ios.CiscoIosBase.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.cisco_ios.CiscoIosBase.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.cisco_ios.CiscoIosBase.strip_backspaces" href="../base_connection.html#netmiko.base_connection.BaseConnection.strip_backspaces">strip_backspaces</a></code></li> +<li><code><a title="netmiko.cisco.cisco_ios.CiscoIosBase.strip_command" href="../base_connection.html#netmiko.base_connection.BaseConnection.strip_command">strip_command</a></code></li> +<li><code><a title="netmiko.cisco.cisco_ios.CiscoIosBase.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.cisco_ios.CiscoIosBase.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.keymile" href="index.html">netmiko.keymile</a></code></li> +</ul> +</li> +<li><h3><a href="#header-classes">Classes</a></h3> +<ul> +<li> +<h4><code><a title="netmiko.keymile.keymile_ssh.KeymileSSH" href="#netmiko.keymile.keymile_ssh.KeymileSSH">KeymileSSH</a></code></h4> +<ul class="two-column"> +<li><code><a title="netmiko.keymile.keymile_ssh.KeymileSSH.check_config_mode" href="#netmiko.keymile.keymile_ssh.KeymileSSH.check_config_mode">check_config_mode</a></code></li> +<li><code><a title="netmiko.keymile.keymile_ssh.KeymileSSH.check_enable_mode" href="#netmiko.keymile.keymile_ssh.KeymileSSH.check_enable_mode">check_enable_mode</a></code></li> +<li><code><a title="netmiko.keymile.keymile_ssh.KeymileSSH.config_mode" href="#netmiko.keymile.keymile_ssh.KeymileSSH.config_mode">config_mode</a></code></li> +<li><code><a title="netmiko.keymile.keymile_ssh.KeymileSSH.disable_paging" href="#netmiko.keymile.keymile_ssh.KeymileSSH.disable_paging">disable_paging</a></code></li> +<li><code><a title="netmiko.keymile.keymile_ssh.KeymileSSH.enable" href="#netmiko.keymile.keymile_ssh.KeymileSSH.enable">enable</a></code></li> +<li><code><a title="netmiko.keymile.keymile_ssh.KeymileSSH.exit_config_mode" href="#netmiko.keymile.keymile_ssh.KeymileSSH.exit_config_mode">exit_config_mode</a></code></li> +<li><code><a title="netmiko.keymile.keymile_ssh.KeymileSSH.exit_enable_mode" href="#netmiko.keymile.keymile_ssh.KeymileSSH.exit_enable_mode">exit_enable_mode</a></code></li> +<li><code><a title="netmiko.keymile.keymile_ssh.KeymileSSH.set_base_prompt" href="#netmiko.keymile.keymile_ssh.KeymileSSH.set_base_prompt">set_base_prompt</a></code></li> +<li><code><a title="netmiko.keymile.keymile_ssh.KeymileSSH.strip_prompt" href="#netmiko.keymile.keymile_ssh.KeymileSSH.strip_prompt">strip_prompt</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.2</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/linux/index.html b/docs/netmiko/linux/index.html index c95d153621582f0a4d3b51f244d9ba6f3991fe85..517b4fc483b28c48fc2922ab6d28687d11afd0d3 100644 --- a/docs/netmiko/linux/index.html +++ b/docs/netmiko/linux/index.html @@ -284,7 +284,10 @@ __all__ = ["LinuxSSH", "LinuxFileTransfer"]</code></pre> return "" def set_base_prompt( - self, pri_prompt_terminator="$", alt_prompt_terminator="#", delay_factor=1 + self, + pri_prompt_terminator=LINUX_PROMPT_PRI, + alt_prompt_terminator=LINUX_PROMPT_ALT, + delay_factor=1, ): """Determine base prompt.""" return super(LinuxSSH, self).set_base_prompt( @@ -301,7 +304,7 @@ __all__ = ["LinuxSSH", "LinuxFileTransfer"]</code></pre> config_commands=config_commands, exit_config_mode=exit_config_mode, **kwargs ) - def check_config_mode(self, check_string="#"): + def check_config_mode(self, check_string=LINUX_PROMPT_ROOT): """Verify root""" return self.check_enable_mode(check_string=check_string) @@ -312,7 +315,7 @@ __all__ = ["LinuxSSH", "LinuxFileTransfer"]</code></pre> def exit_config_mode(self, exit_config="exit"): return self.exit_enable_mode(exit_command=exit_config) - def check_enable_mode(self, check_string="#"): + def check_enable_mode(self, check_string=LINUX_PROMPT_ROOT): """Verify root""" return super(LinuxSSH, self).check_enable_mode(check_string=check_string) @@ -381,7 +384,7 @@ __all__ = ["LinuxSSH", "LinuxFileTransfer"]</code></pre> <section class="desc"><p>Verify root</p></section> <details class="source"> <summary>Source code</summary> -<pre><code class="python">def check_config_mode(self, check_string="#"): +<pre><code class="python">def check_config_mode(self, check_string=LINUX_PROMPT_ROOT): """Verify root""" return self.check_enable_mode(check_string=check_string)</code></pre> </details> @@ -393,7 +396,7 @@ __all__ = ["LinuxSSH", "LinuxFileTransfer"]</code></pre> <section class="desc"><p>Verify root</p></section> <details class="source"> <summary>Source code</summary> -<pre><code class="python">def check_enable_mode(self, check_string="#"): +<pre><code class="python">def check_enable_mode(self, check_string=LINUX_PROMPT_ROOT): """Verify root""" return super(LinuxSSH, self).check_enable_mode(check_string=check_string)</code></pre> </details> @@ -536,7 +539,10 @@ __all__ = ["LinuxSSH", "LinuxFileTransfer"]</code></pre> <details class="source"> <summary>Source code</summary> <pre><code class="python">def set_base_prompt( - self, pri_prompt_terminator="$", alt_prompt_terminator="#", delay_factor=1 + self, + pri_prompt_terminator=LINUX_PROMPT_PRI, + alt_prompt_terminator=LINUX_PROMPT_ALT, + delay_factor=1, ): """Determine base prompt.""" return super(LinuxSSH, self).set_base_prompt( diff --git a/docs/netmiko/linux/linux_ssh.html b/docs/netmiko/linux/linux_ssh.html index 50765121b2fe111aed9c1527baf5e6cd8220519a..76411e2edaa859360ecbeebc75c80d0acf337bda 100644 --- a/docs/netmiko/linux/linux_ssh.html +++ b/docs/netmiko/linux/linux_ssh.html @@ -24,6 +24,7 @@ <summary>Source code</summary> <pre><code class="python">from __future__ import unicode_literals +import os import re import socket import time @@ -32,6 +33,10 @@ from netmiko.cisco_base_connection import CiscoSSHConnection from netmiko.cisco_base_connection import CiscoFileTransfer from netmiko.ssh_exception import NetMikoTimeoutException +LINUX_PROMPT_PRI = os.getenv("NETMIKO_LINUX_PROMPT_PRI", "$") +LINUX_PROMPT_ALT = os.getenv("NETMIKO_LINUX_PROMPT_ALT", "#") +LINUX_PROMPT_ROOT = os.getenv("NETMIKO_LINUX_PROMPT_ROOT", "#") + class LinuxSSH(CiscoSSHConnection): def session_preparation(self): @@ -52,7 +57,10 @@ class LinuxSSH(CiscoSSHConnection): return "" def set_base_prompt( - self, pri_prompt_terminator="$", alt_prompt_terminator="#", delay_factor=1 + self, + pri_prompt_terminator=LINUX_PROMPT_PRI, + alt_prompt_terminator=LINUX_PROMPT_ALT, + delay_factor=1, ): """Determine base prompt.""" return super(LinuxSSH, self).set_base_prompt( @@ -69,7 +77,7 @@ class LinuxSSH(CiscoSSHConnection): config_commands=config_commands, exit_config_mode=exit_config_mode, **kwargs ) - def check_config_mode(self, check_string="#"): + def check_config_mode(self, check_string=LINUX_PROMPT_ROOT): """Verify root""" return self.check_enable_mode(check_string=check_string) @@ -80,7 +88,7 @@ class LinuxSSH(CiscoSSHConnection): def exit_config_mode(self, exit_config="exit"): return self.exit_enable_mode(exit_command=exit_config) - def check_enable_mode(self, check_string="#"): + def check_enable_mode(self, check_string=LINUX_PROMPT_ROOT): """Verify root""" return super(LinuxSSH, self).check_enable_mode(check_string=check_string) @@ -437,7 +445,10 @@ class LinuxFileTransfer(CiscoFileTransfer): return "" def set_base_prompt( - self, pri_prompt_terminator="$", alt_prompt_terminator="#", delay_factor=1 + self, + pri_prompt_terminator=LINUX_PROMPT_PRI, + alt_prompt_terminator=LINUX_PROMPT_ALT, + delay_factor=1, ): """Determine base prompt.""" return super(LinuxSSH, self).set_base_prompt( @@ -454,7 +465,7 @@ class LinuxFileTransfer(CiscoFileTransfer): config_commands=config_commands, exit_config_mode=exit_config_mode, **kwargs ) - def check_config_mode(self, check_string="#"): + def check_config_mode(self, check_string=LINUX_PROMPT_ROOT): """Verify root""" return self.check_enable_mode(check_string=check_string) @@ -465,7 +476,7 @@ class LinuxFileTransfer(CiscoFileTransfer): def exit_config_mode(self, exit_config="exit"): return self.exit_enable_mode(exit_command=exit_config) - def check_enable_mode(self, check_string="#"): + def check_enable_mode(self, check_string=LINUX_PROMPT_ROOT): """Verify root""" return super(LinuxSSH, self).check_enable_mode(check_string=check_string) @@ -534,7 +545,7 @@ class LinuxFileTransfer(CiscoFileTransfer): <section class="desc"><p>Verify root</p></section> <details class="source"> <summary>Source code</summary> -<pre><code class="python">def check_config_mode(self, check_string="#"): +<pre><code class="python">def check_config_mode(self, check_string=LINUX_PROMPT_ROOT): """Verify root""" return self.check_enable_mode(check_string=check_string)</code></pre> </details> @@ -546,7 +557,7 @@ class LinuxFileTransfer(CiscoFileTransfer): <section class="desc"><p>Verify root</p></section> <details class="source"> <summary>Source code</summary> -<pre><code class="python">def check_enable_mode(self, check_string="#"): +<pre><code class="python">def check_enable_mode(self, check_string=LINUX_PROMPT_ROOT): """Verify root""" return super(LinuxSSH, self).check_enable_mode(check_string=check_string)</code></pre> </details> @@ -689,7 +700,10 @@ class LinuxFileTransfer(CiscoFileTransfer): <details class="source"> <summary>Source code</summary> <pre><code class="python">def set_base_prompt( - self, pri_prompt_terminator="$", alt_prompt_terminator="#", delay_factor=1 + self, + pri_prompt_terminator=LINUX_PROMPT_PRI, + alt_prompt_terminator=LINUX_PROMPT_ALT, + delay_factor=1, ): """Determine base prompt.""" return super(LinuxSSH, self).set_base_prompt( diff --git a/netmiko/__init__.py b/netmiko/__init__.py index 1ea80ff25955dd2569ec8215d0fecda0ed68e390..afeb27955cb8981ddb5d4de438f9daacca7152e9 100644 --- a/netmiko/__init__.py +++ b/netmiko/__init__.py @@ -23,7 +23,7 @@ NetmikoTimeoutError = NetMikoTimeoutException NetmikoAuthError = NetMikoAuthenticationException Netmiko = ConnectHandler -__version__ = "2.4.1" +__version__ = "2.4.2" __all__ = ( "ConnectHandler", "ssh_dispatcher", diff --git a/netmiko/base_connection.py b/netmiko/base_connection.py index d2353aecc6ebf53a7a805bf37d52d4af7b7a2057..55aa7492e8ba04049208e43e0c44edd06f8ed296 100644 --- a/netmiko/base_connection.py +++ b/netmiko/base_connection.py @@ -403,6 +403,11 @@ class BaseConnection(object): def _write_session_log(self, data): if self.session_log is not None and len(data) > 0: + # Hide the password and secret in the session_log + if self.password: + data = data.replace(self.password, "********") + if self.secret: + data = data.replace(self.secret, "********") self.session_log.write(write_bytes(data, encoding=self.encoding)) self.session_log.flush() @@ -776,10 +781,20 @@ class BaseConnection(object): else: source = {} + # Keys get normalized to lower-case if "proxycommand" in source: proxy = paramiko.ProxyCommand(source["proxycommand"]) - elif "ProxyCommand" in source: - proxy = paramiko.ProxyCommand(source["ProxyCommand"]) + elif "proxyjump" in source: + hops = list(reversed(source["proxyjump"].split(","))) + if len(hops) > 1: + raise ValueError( + "ProxyJump with more than one proxy server is not supported." + ) + port = source.get("port", self.port) + host = source.get("hostname", self.host) + # -F {full_path} forces the continued use of the same SSH config file + cmd = "ssh -F {} -W {}:{} {}".format(full_path, host, port, hops[0]) + proxy = paramiko.ProxyCommand(cmd) else: proxy = None @@ -939,7 +954,7 @@ class BaseConnection(object): # check if data was ever present if new_data: - return "" + return new_data else: raise NetMikoTimeoutException("Timed out waiting for data") diff --git a/netmiko/hp/hp_procurve.py b/netmiko/hp/hp_procurve.py index 4ff4d621178c7dc1ad3d149e896e6b46c8691195..e09e9f91ca5bf529a09c7a462bf9707683ab9a98 100644 --- a/netmiko/hp/hp_procurve.py +++ b/netmiko/hp/hp_procurve.py @@ -3,10 +3,20 @@ from __future__ import unicode_literals import re import time import socket +from os import path +from paramiko import SSHClient from netmiko.cisco_base_connection import CiscoSSHConnection from netmiko import log +class SSHClient_noauth(SSHClient): + """Set noauth when manually handling SSH authentication.""" + + def _auth(self, username, *args): + self._transport.auth_none(username) + return + + class HPProcurveBase(CiscoSSHConnection): def session_preparation(self): """ @@ -99,6 +109,25 @@ class HPProcurveSSH(HPProcurveBase): super(HPProcurveSSH, self).session_preparation() + def _build_ssh_client(self): + """Allow passwordless authentication for HP devices being provisioned.""" + + # Create instance of SSHClient object. If no SSH keys and no password, then use noauth + if not self.use_keys and not self.password: + remote_conn_pre = SSHClient_noauth() + else: + remote_conn_pre = SSHClient() + + # Load host_keys for better SSH security + if self.system_host_keys: + remote_conn_pre.load_system_host_keys() + if self.alt_host_keys and path.isfile(self.alt_key_file): + remote_conn_pre.load_host_keys(self.alt_key_file) + + # Default is to automatically add untrusted hosts (make sure appropriate for your env) + remote_conn_pre.set_missing_host_key_policy(self.key_policy) + return remote_conn_pre + class HPProcurveTelnet(HPProcurveBase): def telnet_login( diff --git a/netmiko/keymile/__init__.py b/netmiko/keymile/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..af56119122eb1d0edf4e66480845a79d67e8ada7 --- /dev/null +++ b/netmiko/keymile/__init__.py @@ -0,0 +1,5 @@ +from __future__ import unicode_literals +from netmiko.keymile.keymile_ssh import KeymileSSH +from netmiko.keymile.keymile_nos_ssh import KeymileNOSSSH + +__all__ = ["KeymileSSH", "KeymileNOSSSH"] diff --git a/netmiko/keymile/keymile_nos_ssh.py b/netmiko/keymile/keymile_nos_ssh.py new file mode 100644 index 0000000000000000000000000000000000000000..397bc710e0447cbe3c88f69d3f6b4d998d63dad7 --- /dev/null +++ b/netmiko/keymile/keymile_nos_ssh.py @@ -0,0 +1,38 @@ +import time +import re + + +from netmiko.cisco.cisco_ios import CiscoIosBase +from netmiko.ssh_exception import NetMikoAuthenticationException + + +class KeymileNOSSSH(CiscoIosBase): + def session_preparation(self): + """Prepare the session after the connection has been established.""" + self.set_base_prompt() + self.disable_paging() + time.sleep(0.3 * self.global_delay_factor) + self.clear_buffer() + + def _test_channel_read(self, count=40, pattern=""): + """Since Keymile NOS always returns True on paramiko.connect() we + check the output for substring Login incorrect after connecting.""" + output = super(KeymileNOSSSH, self)._test_channel_read( + count=count, pattern=pattern + ) + pattern = r"Login incorrect" + if re.search(pattern, output): + self.paramiko_cleanup() + msg = "Authentication failure: unable to connect" + msg += "{device_type} {host}:{port}".format( + device_type=self.device_type, host=self.host, port=self.port + ) + msg += self.RESPONSE_RETURN + "Login incorrect" + raise NetMikoAuthenticationException(msg) + else: + return output + + def special_login_handler(self, delay_factor=1): + """Since Keymile NOS always returns True on paramiko.connect() we + check the output for substring Login incorrect after connecting.""" + self._test_channel_read(pattern=r"(>|Login incorrect)") diff --git a/netmiko/keymile/keymile_ssh.py b/netmiko/keymile/keymile_ssh.py new file mode 100644 index 0000000000000000000000000000000000000000..89cf190150cda1121dd4999b43ce6646c2cf15d2 --- /dev/null +++ b/netmiko/keymile/keymile_ssh.py @@ -0,0 +1,56 @@ +import time + +from netmiko.cisco.cisco_ios import CiscoIosBase + + +class KeymileSSH(CiscoIosBase): + def __init__(self, **kwargs): + kwargs.setdefault("default_enter", "\r\n") + return super(KeymileSSH, self).__init__(**kwargs) + + def session_preparation(self): + """Prepare the session after the connection has been established.""" + self._test_channel_read(pattern=r">") + self.set_base_prompt() + time.sleep(0.3 * self.global_delay_factor) + self.clear_buffer() + + def disable_paging(self, *args, **kwargs): + """Keymile does not use paging.""" + return "" + + def check_config_mode(self, *args, **kwargs): + """Keymile does not use config mode.""" + return False + + def config_mode(self, *args, **kwargs): + """Keymile does not use config mode.""" + return "" + + def exit_config_mode(self, *args, **kwargs): + """Keymile does not use config mode.""" + return "" + + def check_enable_mode(self, *args, **kwargs): + """Keymile does not use enable mode.""" + return False + + def enable(self, *args, **kwargs): + """Keymile does not use enable mode.""" + return "" + + def exit_enable_mode(self, *args, **kwargs): + """Keymile does not use enable mode.""" + return "" + + def strip_prompt(self, a_string): + """Remove appending empty line and prompt from output""" + self._write_session_log(a_string) + a_string = a_string[:-1] + return super(KeymileSSH, self).strip_prompt(a_string=a_string) + + def set_base_prompt(self, pri_prompt_terminator=">", **kwargs): + """ set prompt termination to >""" + return super(KeymileSSH, self).set_base_prompt( + pri_prompt_terminator=pri_prompt_terminator + ) diff --git a/netmiko/linux/linux_ssh.py b/netmiko/linux/linux_ssh.py index a865a9f55a3870fb8c322354aba3ff752739fba4..41d30499e6d730ada87d7cb7e9e6d6985c1fc7de 100644 --- a/netmiko/linux/linux_ssh.py +++ b/netmiko/linux/linux_ssh.py @@ -1,5 +1,6 @@ from __future__ import unicode_literals +import os import re import socket import time @@ -8,6 +9,10 @@ from netmiko.cisco_base_connection import CiscoSSHConnection from netmiko.cisco_base_connection import CiscoFileTransfer from netmiko.ssh_exception import NetMikoTimeoutException +LINUX_PROMPT_PRI = os.getenv("NETMIKO_LINUX_PROMPT_PRI", "$") +LINUX_PROMPT_ALT = os.getenv("NETMIKO_LINUX_PROMPT_ALT", "#") +LINUX_PROMPT_ROOT = os.getenv("NETMIKO_LINUX_PROMPT_ROOT", "#") + class LinuxSSH(CiscoSSHConnection): def session_preparation(self): @@ -28,7 +33,10 @@ class LinuxSSH(CiscoSSHConnection): return "" def set_base_prompt( - self, pri_prompt_terminator="$", alt_prompt_terminator="#", delay_factor=1 + self, + pri_prompt_terminator=LINUX_PROMPT_PRI, + alt_prompt_terminator=LINUX_PROMPT_ALT, + delay_factor=1, ): """Determine base prompt.""" return super(LinuxSSH, self).set_base_prompt( @@ -45,7 +53,7 @@ class LinuxSSH(CiscoSSHConnection): config_commands=config_commands, exit_config_mode=exit_config_mode, **kwargs ) - def check_config_mode(self, check_string="#"): + def check_config_mode(self, check_string=LINUX_PROMPT_ROOT): """Verify root""" return self.check_enable_mode(check_string=check_string) @@ -56,7 +64,7 @@ class LinuxSSH(CiscoSSHConnection): def exit_config_mode(self, exit_config="exit"): return self.exit_enable_mode(exit_command=exit_config) - def check_enable_mode(self, check_string="#"): + def check_enable_mode(self, check_string=LINUX_PROMPT_ROOT): """Verify root""" return super(LinuxSSH, self).check_enable_mode(check_string=check_string) diff --git a/netmiko/ssh_dispatcher.py b/netmiko/ssh_dispatcher.py index 4e036035dc13373c142afda94c7344733e543c06..7e40c5b15c13d8e69ccf5c4c6928c0869943b3bd 100644 --- a/netmiko/ssh_dispatcher.py +++ b/netmiko/ssh_dispatcher.py @@ -55,6 +55,7 @@ from netmiko.huawei import HuaweiSSH, HuaweiVrpv8SSH, HuaweiTelnet from netmiko.ipinfusion import IpInfusionOcNOSSSH, IpInfusionOcNOSTelnet from netmiko.juniper import JuniperSSH, JuniperTelnet from netmiko.juniper import JuniperFileTransfer +from netmiko.keymile import KeymileSSH, KeymileNOSSSH from netmiko.linux import LinuxSSH, LinuxFileTransfer from netmiko.mikrotik import MikrotikRouterOsSSH from netmiko.mikrotik import MikrotikSwitchOsSSH @@ -139,6 +140,8 @@ CLASS_MAPPER_BASE = { "ipinfusion_ocnos": IpInfusionOcNOSSSH, "juniper": JuniperSSH, "juniper_junos": JuniperSSH, + "keymile": KeymileSSH, + "keymile_nos": KeymileNOSSSH, "linux": LinuxSSH, "mikrotik_routeros": MikrotikRouterOsSSH, "mikrotik_switchos": MikrotikSwitchOsSSH, diff --git a/requirements-genie.txt b/requirements-genie.txt index add4ef2e2af3b6fcbf0168ffa87f999d9b7cb4df..707710677303b2f739e5bb11e33068605897626a 100644 --- a/requirements-genie.txt +++ b/requirements-genie.txt @@ -1,2 +1,2 @@ -pyats; python_version>="3.4" -genie; python_version>="3.4" +pyats>=19.7; python_version>="3.4" +genie>=19.7; python_version>="3.4" diff --git a/tests/etc/commands.yml.example b/tests/etc/commands.yml.example index f810292978b7f3cdd850dbf73dba3c5a80550e4c..7f06e5c35b919998691eb820c3029647925ab142 100644 --- a/tests/etc/commands.yml.example +++ b/tests/etc/commands.yml.example @@ -257,3 +257,20 @@ cloudgenix_ion: config_verification: "dump interface status 2" save_config_confirm: False save_config_response: "#" + +keymile: + version: "show version" + basic: "get /cfgm/IP_Address" + extended_output: "ls" + +keymile_nos: + version: "show version" + basic: "show ip interface brief | include br328" + extended_output: "show interface" + config: + - "log login enable" + config_verification: "show running-config | include log" + save_config_cmd: 'write memory' + save_config_confirm: True + save_config_response: '[OK]' + diff --git a/tests/etc/responses.yml.example b/tests/etc/responses.yml.example index 809f99c43d40a7f28acf663ec8b1ee680ecf3c42..1da7517e88178f09a8b91862dddbba9c31eb5e3f 100644 --- a/tests/etc/responses.yml.example +++ b/tests/etc/responses.yml.example @@ -197,3 +197,19 @@ cloudgenix_ion: interface_ip: "192.168.1.16/24" cmd_response_init: "172.16.16.15/24" cmd_response_final: "172.16.16.16/24" + +keymile: + base_prompt: / + router_prompt: /> + enable_prompt: /> + interface_ip: 1.2.3.4 + version_banner: "---===### CLI Release R2A21, Build 2018-12-21 ###===---" + multiple_line_output: "Equipment State" + +keymile_nos: + base_prompt: KDKB1251 + router_prompt: KDKB1251> + enable_prompt: KDKB1251# + interface_ip: 1.2.3.5 + version_banner: "NOS version 2.09 #0001" + multiple_line_output: "Interface br328" diff --git a/tests/etc/ssh_config_proxyjump b/tests/etc/ssh_config_proxyjump new file mode 100644 index 0000000000000000000000000000000000000000..694a8dd71f493fcbdaa729dbf14025bd971764f4 --- /dev/null +++ b/tests/etc/ssh_config_proxyjump @@ -0,0 +1,10 @@ +host jumphost + IdentitiesOnly yes + IdentityFile ~/.ssh/test_rsa + user myuser + hostname host1.domain.com + +host * !jumphost + User admin + Port 8022 + ProxyJump jumphost diff --git a/tests/etc/test_devices.yml.example b/tests/etc/test_devices.yml.example index f2581a01d03f354098d287bfa8e7ae69d5252248..903c99dd4f08e879c1236dc21bdf8a9c54f7dba0 100644 --- a/tests/etc/test_devices.yml.example +++ b/tests/etc/test_devices.yml.example @@ -159,3 +159,15 @@ cloudgenix_ion: ip: 1.1.1.1 username: TEST password: TEST + +keymile: + device_type: keymile + ip: 1.2.3.4 + username: TEST + password: TEST + +keymile_nos: + device_type: keymile_nos + ip: 1.2.3.5 + username: TEST + password: TEST diff --git a/tests/test_netmiko_sesssion_log.py b/tests/test_netmiko_session_log.py similarity index 83% rename from tests/test_netmiko_sesssion_log.py rename to tests/test_netmiko_session_log.py index 661a71b7072a14012cae758f145feedf5a50e727..381b9c80643699019cfd21774162f544f9231778 100755 --- a/tests/test_netmiko_sesssion_log.py +++ b/tests/test_netmiko_session_log.py @@ -5,6 +5,7 @@ import time import hashlib import io from netmiko import ConnectHandler +from netmiko.py23_compat import bufferedio_types def calc_md5(file_name=None, contents=None): @@ -112,3 +113,21 @@ def test_session_log_bytesio(device_slog, commands, expected_responses): log_content = s_log.getvalue() session_log_md5 = calc_md5(contents=log_content) assert session_log_md5 == compare_log_md5 + + +def test_session_log_secrets(device_slog): + """Verify session_log does not contain password or secret.""" + conn = ConnectHandler(**device_slog) + conn._write_session_log("\nTesting password and secret replacement\n") + conn._write_session_log("This is my password {}\n".format(conn.password)) + conn._write_session_log("This is my secret {}\n".format(conn.secret)) + + if not isinstance(conn.session_log, bufferedio_types): + with open(conn.session_log.name, "r") as f: + session_log = f.read() + if conn.password: + assert conn.password not in session_log + if conn.secret: + assert conn.secret not in session_log + else: + assert True diff --git a/tests/test_suite_alt.sh b/tests/test_suite_alt.sh index ebefb0310c8c1d2e502807472a921cfff0757131..67e345fe92c2fe7e1375d7bbd14b466778849338 100755 --- a/tests/test_suite_alt.sh +++ b/tests/test_suite_alt.sh @@ -18,7 +18,7 @@ echo "Starting tests...good luck:" \ && py.test -v test_netmiko_tcl.py --test_device cisco881 \ && 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_sesssion_log.py --test_device cisco881_slog \ +&& 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 \ @@ -29,6 +29,10 @@ echo "Starting tests...good luck:" \ && py.test -v test_netmiko_show.py --test_device cisco881_ssh_config \ && py.test -v test_netmiko_config.py --test_device cisco881_ssh_config \ \ +&& echo "Cisco IOS using SSH config with SSH Proxy using ProxyJump" \ +&& py.test -v test_netmiko_show.py --test_device cisco881_ssh_proxyjump \ +&& py.test -v test_netmiko_config.py --test_device cisco881_ssh_proxyjump \ +\ && echo "Cisco IOS telnet" \ && py.test -v test_netmiko_show.py --test_device cisco881_telnet \ && py.test -v test_netmiko_config.py --test_device cisco881_telnet \ diff --git a/tests/unit/test_base_connection.py b/tests/unit/test_base_connection.py index b43fceea0985e7fdddcdbb1fea2437fa9794834a..daa9e77657080b23a1468dd102928f6365a01b97 100755 --- a/tests/unit/test_base_connection.py +++ b/tests/unit/test_base_connection.py @@ -86,6 +86,48 @@ def test_use_ssh_file(): assert result == expected +def test_use_ssh_file_proxyjump(): + """Update SSH connection parameters based on the SSH "config" file""" + connection = FakeBaseConnection( + host="10.10.10.70", + port=22, + username="", + password="secret", + use_keys=True, + allow_agent=False, + key_file="/home/user/.ssh/id_rsa", + timeout=60, + pkey=None, + passphrase=None, + auth_timeout=None, + banner_timeout=10, + ssh_config_file=join(RESOURCE_FOLDER, "ssh_config_proxyjump"), + ) + + connect_dict = connection._connect_params_dict() + + expected = { + "hostname": "10.10.10.70", + "port": 8022, + "username": "admin", + "password": "secret", + "look_for_keys": True, + "allow_agent": False, + "key_filename": "/home/user/.ssh/id_rsa", + "timeout": 60, + "pkey": None, + "passphrase": None, + "auth_timeout": None, + "banner_timeout": 10, + } + + result = connection._use_ssh_config(connect_dict) + assert "sock" in result + assert "-W" in result["sock"].cmd + del result["sock"] + assert result == expected + + def test_connect_params_dict(): """Generate dictionary of Paramiko connection parameters""" connection = FakeBaseConnection(