[Python-modules-commits] [netmiko] 01/03: Import netmiko_0.5.6.orig.tar.gz
Vincent Bernat
bernat at moszumanska.debian.org
Sat Sep 3 10:30:47 UTC 2016
This is an automated email from the git hooks/post-receive script.
bernat pushed a commit to branch master
in repository netmiko.
commit ffb85605be2808f3625b66aa6cbba621df0f7e89
Author: Vincent Bernat <bernat at debian.org>
Date: Sat Sep 3 12:29:00 2016 +0200
Import netmiko_0.5.6.orig.tar.gz
---
PKG-INFO | 2 +-
README.md | 153 +++++++++++++++++++-------------
netmiko.egg-info/PKG-INFO | 2 +-
netmiko/__init__.py | 9 +-
netmiko/arista/arista_ssh.py | 8 +-
netmiko/base_connection.py | 50 ++++++-----
netmiko/brocade/brocade_fastiron_ssh.py | 16 +++-
netmiko/brocade/brocade_netiron_ssh.py | 4 +-
netmiko/brocade/brocade_nos_ssh.py | 9 ++
netmiko/fortinet/fortinet_ssh.py | 2 +-
netmiko/hp/hp_comware_ssh.py | 49 +++++-----
netmiko/paloalto/paloalto_panos_ssh.py | 3 +-
netmiko/ssh_exception.py | 11 +--
netmiko/utilities.py | 7 +-
14 files changed, 186 insertions(+), 139 deletions(-)
diff --git a/PKG-INFO b/PKG-INFO
index 158b8d7..afec092 100644
--- a/PKG-INFO
+++ b/PKG-INFO
@@ -1,6 +1,6 @@
Metadata-Version: 1.1
Name: netmiko
-Version: 0.5.1
+Version: 0.5.6
Summary: Multi-vendor library to simplify Paramiko SSH connections to network devices
Home-page: https://github.com/ktbyers/netmiko
Author: Kirk Byers
diff --git a/README.md b/README.md
index c3d14ef..3cd0ff1 100644
--- a/README.md
+++ b/README.md
@@ -1,85 +1,97 @@
-netmiko
+Netmiko
=======
Multi-vendor library to simplify Paramiko SSH connections to network devices
Python 2.6, 2.7, 3.3, 3.4, 3.5
-
<br>
-##### Requires: #####
+#### Requires:
Paramiko >= 1.13+
scp >= 0.10.0
pyyaml
pytest (for unit tests)
-<br>
-##### Supports: #####
+<br>
+#### Supports:
+
+###### Regularly tested
+Arista vEOS
+Cisco ASA
Cisco IOS
Cisco IOS-XE
-Cisco ASA
-Cisco NX-OS
Cisco IOS-XR
-Cisco WLC (limited testing)
-Arista vEOS
+HP Comware7
HP ProCurve
-HP Comware (limited testing)
Juniper Junos
-Brocade VDX (limited testing)
-F5 LTM (experimental)
-Huawei (limited testing)
-A10 (limited testing)
-Avaya ERS (limited testing)
-Avaya VSP (limited testing)
-Dell-Force10 DNOS9 (limited testing)
-OVS (experimental)
-Enterasys (experimental)
-Extreme (experiemental)
-Fortinet (experimental)
-Alcatel-Lucent SR-OS (experimental)
+
+###### Limited testing
+Avaya ERS
+Avaya VSP
+Brocade VDX
+Brocade ICX/FastIron
+Brocade MLX/NetIron
+Cisco NX-OS
+Cisco WLC
+Dell-Force10 DNOS9
+Huawei
+Linux
+Palo Alto PAN-OS
+
+###### Experimental
+A10
+F5 LTM
+Enterasys
+Extreme
+Fortinet
+Alcatel-Lucent SR-OS
-<br>
-##### Netmiko Tutorial: #####
-See https://pynet.twb-tech.com/blog/automation/netmiko.html
+<br>
+## Tutorials:
-##### Netmiko and SSH Proxy #####
-https://pynet.twb-tech.com/blog/automation/netmiko-proxy.html
+##### Standard Tutorial:
+https://pynet.twb-tech.com/blog/automation/netmiko.html
+##### SSH Proxy:
+https://pynet.twb-tech.com/blog/automation/netmiko-proxy.html
-<br>
-##### Simple example: #####
+
+<br>
+## Examples:
-```
->>> from netmiko import ConnectHandler
+#### Create a dictionary representing the device.
-# Create a dictionary representing the device.
->>> cisco_881 = {
-... 'device_type': 'cisco_ios',
-... 'ip': '10.10.10.10',
-... 'username': 'test',
-... 'password': 'password',
-... 'port' : 8022, # optional, defaults to 22
-... 'secret': 'secret', # optional, defaults to ''
-... 'verbose': False, # optional, defaults to True
-... }
-# Supported device_types can be found at:
-# https://github.com/ktbyers/netmiko/blob/master/netmiko/ssh_dispatcher.py
-# (see CLASS_MAPPER keys)
+Supported device_types can be found [here](https://github.com/ktbyers/netmiko/blob/master/netmiko/ssh_dispatcher.py), see CLASS_MAPPER keys.
+```py
+from netmiko import ConnectHandler
-```
+cisco_881 = {
+ 'device_type': 'cisco_ios',
+ 'ip': '10.10.10.10',
+ 'username': 'test',
+ 'password': 'password',
+ 'port' : 8022, # optional, defaults to 22
+ 'secret': 'secret', # optional, defaults to ''
+ 'verbose': False, # optional, defaults to False
+}
```
-# Establish an SSH connection to the device by passing in the device dictionary.
->>> net_connect = ConnectHandler(**cisco_881)
+<br>
+#### Establish an SSH connection to the device by passing in the device dictionary.
+```py
+net_connect = ConnectHandler(**cisco_881)
```
+<br>
+#### Execute show commands.
+```py
+output = net_connect.send_command('show ip int brief')
+print(output)
+```
```
-# Execute show commands on the channel:
->>> output = net_connect.send_command('show ip int brief')
->>> print output
Interface IP-Address OK? Method Status Protocol
FastEthernet0 unassigned YES unset down down
FastEthernet1 unassigned YES unset down down
@@ -89,19 +101,35 @@ FastEthernet4 10.10.10.10 YES manual up up
Vlan1 unassigned YES unset down down
```
+<br>
+#### For long-running commands, use `send_command_expect()`
+
+`send_command_expect` waits for the trailing prompt (or for an optional pattern)
+```py
+net_connect.send_command_expect('write memory')
+```
```
-# Enter enable mode
->>> net_connect.enable()
+Building configuration...
+[OK]
```
+<br>
+#### Enter and exit enable mode.
+```py
+net_connect.enable()
+net_connect.exit_enable_mode()
```
-# Execute configuration change commands (will automatically enter into config mode)
->>> config_commands = [ 'logging buffered 20000',
- 'logging buffered 20010',
- 'no logging console' ]
->>> output = net_connect.send_config_set(config_commands)
->>> print output
+<br>
+#### Execute configuration change commands (will automatically enter into config mode)
+```py
+config_commands = [ 'logging buffered 20000',
+ 'logging buffered 20010',
+ 'no logging console' ]
+output = net_connect.send_config_set(config_commands)
+print(output)
+```
+```
pynet-rtr1#config term
Enter configuration commands, one per line. End with CNTL/Z.
pynet-rtr1(config)#logging buffered 20000
@@ -109,14 +137,11 @@ pynet-rtr1(config)#logging buffered 20010
pynet-rtr1(config)#no logging console
pynet-rtr1(config)#end
pynet-rtr1#
-
```
-
-<br>
+
+<br>
---
Kirk Byers
Python for Network Engineers
-https://pynet.twb-tech.com
-
-
+https://pynet.twb-tech.com
diff --git a/netmiko.egg-info/PKG-INFO b/netmiko.egg-info/PKG-INFO
index 158b8d7..afec092 100644
--- a/netmiko.egg-info/PKG-INFO
+++ b/netmiko.egg-info/PKG-INFO
@@ -1,6 +1,6 @@
Metadata-Version: 1.1
Name: netmiko
-Version: 0.5.1
+Version: 0.5.6
Summary: Multi-vendor library to simplify Paramiko SSH connections to network devices
Home-page: https://github.com/ktbyers/netmiko
Author: Kirk Byers
diff --git a/netmiko/__init__.py b/netmiko/__init__.py
index 251bd2d..069c2fb 100644
--- a/netmiko/__init__.py
+++ b/netmiko/__init__.py
@@ -6,6 +6,11 @@ from netmiko.scp_handler import FileTransfer
from netmiko.ssh_exception import NetMikoTimeoutException
from netmiko.ssh_exception import NetMikoAuthenticationException
-__version__ = '0.5.1'
+# Alternate naming
+NetmikoTimeoutError = NetMikoTimeoutException
+NetmikoAuthError = NetMikoAuthenticationException
+
+__version__ = '0.5.6'
__all__ = ('ConnectHandler', 'ssh_dispatcher', 'platforms', 'SCPConn', 'FileTransfer',
- 'NetMikoTimeoutException', 'NetMikoAuthenticationException',)
+ 'NetMikoTimeoutException', 'NetMikoAuthenticationException',
+ 'NetmikoTimeoutError', 'NetmikoAuthError')
diff --git a/netmiko/arista/arista_ssh.py b/netmiko/arista/arista_ssh.py
index dc6d148..ef47c09 100644
--- a/netmiko/arista/arista_ssh.py
+++ b/netmiko/arista/arista_ssh.py
@@ -1,5 +1,11 @@
+import time
from netmiko.ssh_connection import SSHConnection
class AristaSSH(SSHConnection):
- pass
+ def special_login_handler(self, delay_factor=1):
+ """
+ Arista adds a "Last login: " message that doesn't always have sufficient time to be handled
+ """
+ time.sleep(3 * delay_factor)
+ self.clear_buffer()
diff --git a/netmiko/base_connection.py b/netmiko/base_connection.py
index be95ced..de2f10c 100644
--- a/netmiko/base_connection.py
+++ b/netmiko/base_connection.py
@@ -129,6 +129,18 @@ class BaseSSHConnection(object):
'timeout': timeout,
}
+ def _sanitize_output(self, output, strip_command=False, command_string=None,
+ strip_prompt=False):
+ """Sanitize the output."""
+ if self.ansi_escape_codes:
+ output = self.strip_ansi_escape_codes(output)
+ output = self.normalize_linefeeds(output)
+ if strip_command and command_string:
+ output = self.strip_command(command_string, output)
+ if strip_prompt:
+ output = self.strip_prompt(output)
+ return output
+
def establish_connection(self, sleep_time=3, verbose=True, timeout=8,
use_keys=False, key_file=None):
"""
@@ -274,8 +286,6 @@ class BaseSSHConnection(object):
time.sleep(delay_factor)
prompt = ''
- if debug:
- print("aaa: {}".format(prompt))
# Initial attempt to get prompt
if self.remote_conn.recv_ready():
prompt = self.remote_conn.recv(MAX_BUFFER).decode('utf-8', 'ignore')
@@ -284,22 +294,25 @@ class BaseSSHConnection(object):
prompt = self.strip_ansi_escape_codes(prompt)
if debug:
- print("bbb: {}".format(prompt))
+ print("prompt1: {}".format(prompt))
# Check if the only thing you received was a newline
count = 0
while count <= 10 and not prompt:
- if self.wait_for_recv_ready():
+ if self.wait_for_recv_ready(delay_factor=delay_factor):
prompt = self.remote_conn.recv(MAX_BUFFER).decode('utf-8', 'ignore')
if debug:
- print("ccc1: {}".format(repr(prompt)))
- print("ccc2: {}".format(prompt))
+ print("prompt2a: {}".format(repr(prompt)))
+ print("prompt2b: {}".format(prompt))
if self.ansi_escape_codes:
prompt = self.strip_ansi_escape_codes(prompt)
prompt = prompt.strip()
+ else:
+ self.remote_conn.sendall("\n")
+ time.sleep(delay_factor)
count += 1
if debug:
- print("ddd: {}".format(prompt))
+ print("prompt3: {}".format(prompt))
# If multiple lines in the output take the last line
prompt = self.normalize_linefeeds(prompt)
prompt = prompt.split('\n')[-1]
@@ -346,14 +359,8 @@ class BaseSSHConnection(object):
max_loops=max_loops):
output += tmp_output
- # Some platforms have ansi_escape codes
- if self.ansi_escape_codes:
- output = self.strip_ansi_escape_codes(output)
- output = self.normalize_linefeeds(output)
- if strip_command:
- output = self.strip_command(command_string, output)
- if strip_prompt:
- output = self.strip_prompt(output)
+ output = self._sanitize_output(output, strip_command=strip_command,
+ command_string=command_string, strip_prompt=strip_prompt)
if debug:
print(output)
return output
@@ -482,14 +489,8 @@ class BaseSSHConnection(object):
raise IOError("Search pattern never detected in send_command_expect: {0}".format(
search_pattern))
- # Some platforms have ansi_escape codes
- if self.ansi_escape_codes:
- output = self.strip_ansi_escape_codes(output)
- output = self.normalize_linefeeds(output)
- if strip_command:
- output = self.strip_command(command_string, output)
- if strip_prompt:
- output = self.strip_prompt(output)
+ output = self._sanitize_output(output, strip_command=strip_command,
+ command_string=command_string, strip_prompt=strip_prompt)
return output
@staticmethod
@@ -520,7 +521,7 @@ class BaseSSHConnection(object):
@staticmethod
def normalize_linefeeds(a_string):
"""Convert '\r\r\n','\r\n', '\n\r' to '\n."""
- newline = re.compile(r'(\r\r\n|\r\n|\n\r)')
+ newline = re.compile(r'(\r\r\r\n|\r\r\n|\r\n|\n\r)')
return newline.sub('\n', a_string)
@staticmethod
@@ -639,6 +640,7 @@ class BaseSSHConnection(object):
output += tmp_output
if exit_config_mode:
output += self.exit_config_mode()
+ output = self._sanitize_output(output)
if debug:
print(output)
return output
diff --git a/netmiko/brocade/brocade_fastiron_ssh.py b/netmiko/brocade/brocade_fastiron_ssh.py
index ac7b1f9..3082ea3 100644
--- a/netmiko/brocade/brocade_fastiron_ssh.py
+++ b/netmiko/brocade/brocade_fastiron_ssh.py
@@ -1,7 +1,17 @@
+import re
from netmiko.ssh_connection import SSHConnection
class BrocadeFastironSSH(SSHConnection):
- '''Placeholder for Brocade FastIron'''
- def __init__(self, *args, **kwargs):
- raise NotImplementedError
+ """Brocade FastIron aka ICX support."""
+ def session_preparation(self):
+ """FastIron requires to be enable mode to disable paging."""
+ self.set_base_prompt()
+ self.enable()
+ self.disable_paging(command="skip-page-display")
+
+ @staticmethod
+ def normalize_linefeeds(a_string):
+ """Convert '\r\n\r\n', '\r\r\n','\r\n', '\n\r' to '\n."""
+ newline = re.compile(r'(\r\n\r\n|\r\r\n|\r\n|\n\r|\r)')
+ return newline.sub('\n', a_string)
diff --git a/netmiko/brocade/brocade_netiron_ssh.py b/netmiko/brocade/brocade_netiron_ssh.py
index 4b0a45b..38cac45 100644
--- a/netmiko/brocade/brocade_netiron_ssh.py
+++ b/netmiko/brocade/brocade_netiron_ssh.py
@@ -2,6 +2,4 @@ from netmiko.ssh_connection import SSHConnection
class BrocadeNetironSSH(SSHConnection):
- '''Placeholder for Brocade NetIron'''
- def __init__(self, *args, **kwargs):
- raise NotImplementedError
+ pass
diff --git a/netmiko/brocade/brocade_nos_ssh.py b/netmiko/brocade/brocade_nos_ssh.py
index 5e985f2..0d3a2b4 100644
--- a/netmiko/brocade/brocade_nos_ssh.py
+++ b/netmiko/brocade/brocade_nos_ssh.py
@@ -1,4 +1,5 @@
"""Support for Brocade NOS/VDX."""
+import time
from netmiko.ssh_connection import SSHConnection
@@ -11,3 +12,11 @@ class BrocadeNosSSH(SSHConnection):
def exit_enable_mode(self, *args, **kwargs):
"""No enable mode on Brocade VDX."""
pass
+
+ def special_login_handler(self, delay_factor=.5):
+ '''
+ Adding a delay after login
+ '''
+ delay_factor = self.select_delay_factor(delay_factor)
+ self.remote_conn.sendall('\n')
+ time.sleep(2 * delay_factor)
diff --git a/netmiko/fortinet/fortinet_ssh.py b/netmiko/fortinet/fortinet_ssh.py
index 7c4473d..3e2943c 100644
--- a/netmiko/fortinet/fortinet_ssh.py
+++ b/netmiko/fortinet/fortinet_ssh.py
@@ -11,7 +11,7 @@ class FortinetSSH(SSHConnection):
def session_preparation(self):
"""Prepare the session after the connection has been established."""
- self.set_base_prompt(pri_prompt_terminator='$')
+ self.set_base_prompt(alt_prompt_terminator='$')
self.disable_paging()
def disable_paging(self, delay_factor=.1):
diff --git a/netmiko/hp/hp_comware_ssh.py b/netmiko/hp/hp_comware_ssh.py
index c2a7431..64713cb 100644
--- a/netmiko/hp/hp_comware_ssh.py
+++ b/netmiko/hp/hp_comware_ssh.py
@@ -1,14 +1,18 @@
from __future__ import print_function
from __future__ import unicode_literals
+
import time
+
from netmiko.ssh_connection import SSHConnection
-from netmiko.netmiko_globals import MAX_BUFFER
class HPComwareSSH(SSHConnection):
def session_preparation(self):
"""Prepare the session after the connection has been established."""
+ # Extra time to read HP banners
+ time.sleep(2)
+ self.clear_buffer()
self.set_base_prompt()
self.disable_paging(command="\nscreen-length disable\n")
@@ -36,32 +40,25 @@ class HPComwareSSH(SSHConnection):
This will be set on logging in, but not when entering system-view
"""
- debug = True
- if debug:
- print("In set_base_prompt")
-
- delay_factor = self.select_delay_factor(delay_factor)
- self.clear_buffer()
- self.remote_conn.sendall("\n")
- time.sleep(1 * delay_factor)
-
- prompt = self.remote_conn.recv(MAX_BUFFER).decode('utf-8', 'ignore')
- prompt = self.normalize_linefeeds(prompt)
- if debug:
- print(prompt)
+ prompt = super(HPComwareSSH, self).set_base_prompt(
+ pri_prompt_terminator=pri_prompt_terminator,
+ alt_prompt_terminator=alt_prompt_terminator,
+ delay_factor=delay_factor)
- # If multiple lines in the output take the last line
- prompt = prompt.split('\n')[-1]
- prompt = prompt.strip()
-
- # Check that ends with a valid terminator character
- if not prompt[-1] in (pri_prompt_terminator, alt_prompt_terminator):
- raise ValueError("Router prompt not found: {0}".format(prompt))
-
- # Strip off leading and trailing terminator
- prompt = prompt[1:-1]
+ # Strip off leading character
+ prompt = prompt[1:]
prompt = prompt.strip()
self.base_prompt = prompt
- if debug:
- print("prompt: {}".format(self.base_prompt))
return self.base_prompt
+
+ def enable(self, cmd='system-view'):
+ """enable mode on Comware is system-view."""
+ return self.config_mode(config_command=cmd)
+
+ def exit_enable_mode(self, exit_command='return'):
+ """enable mode on Comware is system-view."""
+ return self.exit_config_mode(exit_config=exit_command)
+
+ def check_enable_mode(self, check_string=']'):
+ """enable mode on Comware is system-view."""
+ return self.check_config_mode(check_string=check_string)
diff --git a/netmiko/paloalto/paloalto_panos_ssh.py b/netmiko/paloalto/paloalto_panos_ssh.py
index 07af198..68b8c23 100644
--- a/netmiko/paloalto/paloalto_panos_ssh.py
+++ b/netmiko/paloalto/paloalto_panos_ssh.py
@@ -94,7 +94,8 @@ class PaloAltoPanosSSH(BaseSSHConnection):
# Enter config mode (if necessary)
output = self.config_mode()
output += self.send_command_expect(command_string, strip_prompt=False,
- strip_command=False, expect_string='100%')
+ strip_command=False, expect_string='100%',
+ delay_factor=delay_factor)
if commit_marker not in output.lower():
raise ValueError("Commit failed with the following errors:\n\n{0}"
diff --git a/netmiko/ssh_exception.py b/netmiko/ssh_exception.py
index 4449851..ad9e728 100644
--- a/netmiko/ssh_exception.py
+++ b/netmiko/ssh_exception.py
@@ -1,19 +1,12 @@
-
from paramiko.ssh_exception import SSHException
from paramiko.ssh_exception import AuthenticationException
class NetMikoTimeoutException(SSHException):
- '''
- SSH session timed trying to connect to the device
-
- Based on Paramiko SSHException
- '''
+ """SSH session timed trying to connect to the device."""
pass
class NetMikoAuthenticationException(AuthenticationException):
- '''
- SSH authentication exception based on Paramiko AuthenticationException
- '''
+ """SSH authentication exception based on Paramiko AuthenticationException."""
pass
diff --git a/netmiko/utilities.py b/netmiko/utilities.py
index 05368ee..6342fda 100644
--- a/netmiko/utilities.py
+++ b/netmiko/utilities.py
@@ -58,16 +58,17 @@ def load_devices():
def find_cfg_file(file_name=None):
"""Look for .netmiko.yml in current dir, then ~/.netmiko.yml."""
+ base_file = '.netmiko.yml'
check_files = [
- '.netmiko.yml',
- os.path.expanduser('~') + '/.netmiko.yml',
+ base_file,
+ os.path.expanduser('~') + '/' + base_file,
]
if file_name:
check_files.insert(0, file_name)
for test_file in check_files:
if os.path.isfile(test_file):
return test_file
- raise IOError("{} file not found in current dir or home dir.".format(file_name))
+ raise IOError("{File not found in current dir or home dir.".format(base_file))
def display_inventory(my_devices):
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/python-modules/packages/netmiko.git
More information about the Python-modules-commits
mailing list