[Python-modules-commits] [netmiko] 01/06: Imported Upstream version 0.5.1

Vincent Bernat bernat at moszumanska.debian.org
Thu May 26 19:18:39 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 a1d991fff375048dbc1e5f181161181c1ff859c1
Author: Vincent Bernat <bernat at debian.org>
Date:   Thu May 26 21:10:18 2016 +0200

    Imported Upstream version 0.5.1
---
 LICENSE                                 |  22 +
 MANIFEST.in                             |   4 +
 PKG-INFO                                |  19 +
 README.md                               | 122 ++++++
 TESTING.md                              |  46 +++
 VENDOR.md                               |  90 ++++
 netmiko.egg-info/PKG-INFO               |  19 +
 netmiko.egg-info/SOURCES.txt            |  65 +++
 netmiko.egg-info/dependency_links.txt   |   1 +
 netmiko.egg-info/requires.txt           |   6 +
 netmiko.egg-info/top_level.txt          |  19 +
 netmiko/__init__.py                     |  11 +
 netmiko/a10/__init__.py                 |   3 +
 netmiko/a10/a10_ssh.py                  |  11 +
 netmiko/alcatel/__init__.py             |   3 +
 netmiko/alcatel/alcatel_sros_ssh.py     |  25 ++
 netmiko/arista/__init__.py              |   3 +
 netmiko/arista/arista_ssh.py            |   5 +
 netmiko/avaya/__init__.py               |   4 +
 netmiko/avaya/avaya_ers_ssh.py          |  42 ++
 netmiko/avaya/avaya_vsp_ssh.py          |  12 +
 netmiko/base_connection.py              | 710 ++++++++++++++++++++++++++++++++
 netmiko/brocade/__init__.py             |   5 +
 netmiko/brocade/brocade_fastiron_ssh.py |   7 +
 netmiko/brocade/brocade_netiron_ssh.py  |   7 +
 netmiko/brocade/brocade_nos_ssh.py      |  13 +
 netmiko/cisco/__init__.py               |   7 +
 netmiko/cisco/cisco_asa_ssh.py          |  42 ++
 netmiko/cisco/cisco_ios_ssh.py          |   5 +
 netmiko/cisco/cisco_nxos_ssh.py         |  16 +
 netmiko/cisco/cisco_wlc_ssh.py          | 106 +++++
 netmiko/cisco/cisco_xr_ssh.py           | 112 +++++
 netmiko/dell/__init__.py                |   3 +
 netmiko/dell/dell_force10_ssh.py        |  16 +
 netmiko/enterasys/__init__.py           |   3 +
 netmiko/enterasys/enterasys_ssh.py      |  11 +
 netmiko/extreme/__init__.py             |   3 +
 netmiko/extreme/extreme_ssh.py          |  11 +
 netmiko/f5/__init__.py                  |   3 +
 netmiko/f5/f5_ltm_ssh.py                |  32 ++
 netmiko/fortinet/__init__.py            |   3 +
 netmiko/fortinet/fortinet_ssh.py        | 105 +++++
 netmiko/hp/__init__.py                  |   4 +
 netmiko/hp/hp_comware_ssh.py            |  67 +++
 netmiko/hp/hp_procurve_ssh.py           |  35 ++
 netmiko/huawei/__init__.py              |   3 +
 netmiko/huawei/huawei_ssh.py            |  68 +++
 netmiko/juniper/__init__.py             |   3 +
 netmiko/juniper/juniper_ssh.py          | 182 ++++++++
 netmiko/linux/__init__.py               |   3 +
 netmiko/linux/linux_ssh.py              |  70 ++++
 netmiko/netmiko_globals.py              |   3 +
 netmiko/ovs/__init__.py                 |   3 +
 netmiko/ovs/ovs_linux_ssh.py            |   5 +
 netmiko/paloalto/__init__.py            |   3 +
 netmiko/paloalto/paloalto_panos_ssh.py  | 149 +++++++
 netmiko/quanta/__init__.py              |   3 +
 netmiko/quanta/quanta_mesh_ssh.py       |  11 +
 netmiko/scp_handler.py                  | 183 ++++++++
 netmiko/ssh_connection.py               |  68 +++
 netmiko/ssh_dispatcher.py               |  89 ++++
 netmiko/ssh_exception.py                |  19 +
 netmiko/utilities.py                    | 142 +++++++
 requirements.txt                        |   4 +
 setup.cfg                               |   9 +
 setup.py                                |  65 +++
 66 files changed, 2943 insertions(+)

diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..f56095b
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,22 @@
+The MIT License (MIT)
+
+Copyright (c) 2016 Kirk Byers
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+
diff --git a/MANIFEST.in b/MANIFEST.in
new file mode 100644
index 0000000..a2cde7e
--- /dev/null
+++ b/MANIFEST.in
@@ -0,0 +1,4 @@
+include *.md
+include requirements.txt
+include LICENSE
+
diff --git a/PKG-INFO b/PKG-INFO
new file mode 100644
index 0000000..158b8d7
--- /dev/null
+++ b/PKG-INFO
@@ -0,0 +1,19 @@
+Metadata-Version: 1.1
+Name: netmiko
+Version: 0.5.1
+Summary: Multi-vendor library to simplify Paramiko SSH connections to network devices
+Home-page: https://github.com/ktbyers/netmiko
+Author: Kirk Byers
+Author-email: ktbyers at twb-tech.com
+License: MIT
+Description: UNKNOWN
+Platform: UNKNOWN
+Classifier: Development Status :: 4 - Beta
+Classifier: License :: OSI Approved :: MIT License
+Classifier: Programming Language :: Python :: 2
+Classifier: Programming Language :: Python :: 2.6
+Classifier: Programming Language :: Python :: 2.7
+Classifier: Programming Language :: Python :: 3
+Classifier: Programming Language :: Python :: 3.3
+Classifier: Programming Language :: Python :: 3.4
+Classifier: Programming Language :: Python :: 3.5
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..c3d14ef
--- /dev/null
+++ b/README.md
@@ -0,0 +1,122 @@
+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: #####
+Paramiko >= 1.13+  
+scp >= 0.10.0  
+pyyaml  
+pytest (for unit tests)   
+  
+  
+<br>  
+##### Supports: #####
+Cisco IOS  
+Cisco IOS-XE  
+Cisco ASA  
+Cisco NX-OS  
+Cisco IOS-XR  
+Cisco WLC (limited testing)  
+Arista vEOS  
+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)  
+
+   
+<br>      
+##### Netmiko Tutorial: #####
+See https://pynet.twb-tech.com/blog/automation/netmiko.html  
+
+##### Netmiko and SSH Proxy #####
+https://pynet.twb-tech.com/blog/automation/netmiko-proxy.html  
+  
+  
+<br>      
+##### Simple example: #####
+
+```
+>>> from netmiko import ConnectHandler
+
+# 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)
+
+```
+
+```
+# Establish an SSH connection to the device by passing in the device dictionary.
+>>> net_connect = ConnectHandler(**cisco_881)
+
+```
+
+```
+# 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    
+FastEthernet2              unassigned      YES unset  down                  down    
+FastEthernet3              unassigned      YES unset  down                  down    
+FastEthernet4              10.10.10.10     YES manual up                    up      
+Vlan1                      unassigned      YES unset  down                  down    
+```
+
+```
+# Enter enable mode
+>>> net_connect.enable()
+```
+
+```
+# 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
+
+pynet-rtr1#config term
+Enter configuration commands, one per line.  End with CNTL/Z.
+pynet-rtr1(config)#logging buffered 20000
+pynet-rtr1(config)#logging buffered 20010
+pynet-rtr1(config)#no logging console
+pynet-rtr1(config)#end
+pynet-rtr1#
+
+```
+
+  
+<br>      
+---    
+Kirk Byers  
+Python for Network Engineers  
+https://pynet.twb-tech.com
+
+ 
diff --git a/TESTING.md b/TESTING.md
new file mode 100644
index 0000000..931c4bd
--- /dev/null
+++ b/TESTING.md
@@ -0,0 +1,46 @@
+# Testing
+
+This document covers the test suite for Netmiko.
+
+<br />
+## The simple version
+
+cd ./netmiko/tests/etc  
+cp test_devices.yml.example test_devices.yml  
+cp responses.yml.example responses.yml  
+cp commands.yml.example commands.yml  
+
+<br />
+##### edit test_devices.yml  
+
+Pick the device_types you want to test against; update:
+* ip 
+* username
+* password
+* secret (optional)
+
+<br />
+##### edit responses.yml  
+
+For the device_types that you are testing against, update the following to match the test 
+device(s):  
+* the base_prompt
+* router_prompt
+* enable_prompt
+* interface_ip
+
+<br />
+##### Execute the test
+cd ./netmiko/tests
+
+Note, the test_device is the name of the device from test_devices.yml and responses.yml:  
+py.test -v test_netmiko_show.py --test_device cisco881  
+py.test -v test_netmiko_config.py --test_device cisco881
+
+<br />
+There are three tests available:  
+* test_netmiko_show.py  
+* test_netmiko_config.py  
+* test_netmiko_commit.py      # currently only for Juniper  
+
+<br />
diff --git a/VENDOR.md b/VENDOR.md
new file mode 100644
index 0000000..9bf5c4b
--- /dev/null
+++ b/VENDOR.md
@@ -0,0 +1,90 @@
+Steps for adding a new vendor
+=======
+
+Create a new vendor directory underneath netmiko/netmiko:
+
+```
+$ cd netmiko/netmiko
+$ mkdir arista
+```
+ 
+Make the directory a Python package:
+
+```
+$ cd arista
+$ touch __init__.py
+```
+  
+Create a new module for the vendor:
+
+```
+$ vi arista_ssh.py
+from netmiko.ssh_connection import SSHConnection
+
+class AristaSSH(SSHConnection):
+
+    pass
+```
+  
+Inherit from the SSHConnection class. Note, the netmiko package will need to be in 
+your PYTHONPATH
+
+Update \_\_init__.py to export the new class:
+
+```
+$ vi __init__.py
+from netmiko.arista.arista_ssh import AristaSSH
+
+__all__ = ['AristaSSH']
+```
+
+Update the dispatcher adding the new class:  
+
+```
+$ cd netmiko/netmiko
+$ vi ssh_dispatcher.py
+from netmiko.cisco import CiscoIosSSH
+from netmiko.cisco import CiscoAsaSSH
+from netmiko.arista import AristaSSH            # Add here
+
+CLASS_MAPPER = {
+    'cisco_ios'     : CiscoIosSSH,
+    'cisco_asa'     : CiscoAsaSSH,
+    'arista_eos'    : AristaSSH,        # Add Here (device_type to class mapping)
+}
+```
+
+Your class will need to support the following methods:
+
+```
+def __init__(self, ip, username, password, secret='', port=22, device_type='', verbose=True):
+def establish_connection(self, sleep_time=3, verbose=True):
+def disable_paging(self):
+def find_prompt(self):
+def clear_buffer(self):
+def send_command(self, command_string, delay_factor=1, max_loops=30):
+def strip_prompt(self, a_string):
+def strip_command(self, command_string, output):
+def normalize_linefeeds(self, a_string):
+def enable(self):
+def config_mode(self):
+def exit_config_mode(self):
+def send_config_set(self, config_commands=None):
+def cleanup(self):
+def disconnect(self):
+```
+
+As much as possible, you should re-use the inherited methods from SSHConnection 
+and BaseSSHConnection (i.e. only re-write what you have to).
+
+BaseSSHConnection is intended to be generic (i.e. irrespective of the vendor)
+SSHConnection is Cisco-IOS specific (because lots of vendors imitate Cisco IOS).
+
+You should also write unit tests and verify the functionality of your new class.
+See netmiko/tests/test_cisco_ios.py and netmiko/tests/test_cisco_ios_enable.py.
+
+
+  
+
+Note, you will also need to update the 'packages' section of 'setup.py' file if you are adding a 
+completely new package.
diff --git a/netmiko.egg-info/PKG-INFO b/netmiko.egg-info/PKG-INFO
new file mode 100644
index 0000000..158b8d7
--- /dev/null
+++ b/netmiko.egg-info/PKG-INFO
@@ -0,0 +1,19 @@
+Metadata-Version: 1.1
+Name: netmiko
+Version: 0.5.1
+Summary: Multi-vendor library to simplify Paramiko SSH connections to network devices
+Home-page: https://github.com/ktbyers/netmiko
+Author: Kirk Byers
+Author-email: ktbyers at twb-tech.com
+License: MIT
+Description: UNKNOWN
+Platform: UNKNOWN
+Classifier: Development Status :: 4 - Beta
+Classifier: License :: OSI Approved :: MIT License
+Classifier: Programming Language :: Python :: 2
+Classifier: Programming Language :: Python :: 2.6
+Classifier: Programming Language :: Python :: 2.7
+Classifier: Programming Language :: Python :: 3
+Classifier: Programming Language :: Python :: 3.3
+Classifier: Programming Language :: Python :: 3.4
+Classifier: Programming Language :: Python :: 3.5
diff --git a/netmiko.egg-info/SOURCES.txt b/netmiko.egg-info/SOURCES.txt
new file mode 100644
index 0000000..808d513
--- /dev/null
+++ b/netmiko.egg-info/SOURCES.txt
@@ -0,0 +1,65 @@
+LICENSE
+MANIFEST.in
+README.md
+TESTING.md
+VENDOR.md
+requirements.txt
+setup.cfg
+setup.py
+netmiko/__init__.py
+netmiko/base_connection.py
+netmiko/netmiko_globals.py
+netmiko/scp_handler.py
+netmiko/ssh_connection.py
+netmiko/ssh_dispatcher.py
+netmiko/ssh_exception.py
+netmiko/utilities.py
+netmiko.egg-info/PKG-INFO
+netmiko.egg-info/SOURCES.txt
+netmiko.egg-info/dependency_links.txt
+netmiko.egg-info/requires.txt
+netmiko.egg-info/top_level.txt
+netmiko/a10/__init__.py
+netmiko/a10/a10_ssh.py
+netmiko/alcatel/__init__.py
+netmiko/alcatel/alcatel_sros_ssh.py
+netmiko/arista/__init__.py
+netmiko/arista/arista_ssh.py
+netmiko/avaya/__init__.py
+netmiko/avaya/avaya_ers_ssh.py
+netmiko/avaya/avaya_vsp_ssh.py
+netmiko/brocade/__init__.py
+netmiko/brocade/brocade_fastiron_ssh.py
+netmiko/brocade/brocade_netiron_ssh.py
+netmiko/brocade/brocade_nos_ssh.py
+netmiko/cisco/__init__.py
+netmiko/cisco/cisco_asa_ssh.py
+netmiko/cisco/cisco_ios_ssh.py
+netmiko/cisco/cisco_nxos_ssh.py
+netmiko/cisco/cisco_wlc_ssh.py
+netmiko/cisco/cisco_xr_ssh.py
+netmiko/dell/__init__.py
+netmiko/dell/dell_force10_ssh.py
+netmiko/enterasys/__init__.py
+netmiko/enterasys/enterasys_ssh.py
+netmiko/extreme/__init__.py
+netmiko/extreme/extreme_ssh.py
+netmiko/f5/__init__.py
+netmiko/f5/f5_ltm_ssh.py
+netmiko/fortinet/__init__.py
+netmiko/fortinet/fortinet_ssh.py
+netmiko/hp/__init__.py
+netmiko/hp/hp_comware_ssh.py
+netmiko/hp/hp_procurve_ssh.py
+netmiko/huawei/__init__.py
+netmiko/huawei/huawei_ssh.py
+netmiko/juniper/__init__.py
+netmiko/juniper/juniper_ssh.py
+netmiko/linux/__init__.py
+netmiko/linux/linux_ssh.py
+netmiko/ovs/__init__.py
+netmiko/ovs/ovs_linux_ssh.py
+netmiko/paloalto/__init__.py
+netmiko/paloalto/paloalto_panos_ssh.py
+netmiko/quanta/__init__.py
+netmiko/quanta/quanta_mesh_ssh.py
\ No newline at end of file
diff --git a/netmiko.egg-info/dependency_links.txt b/netmiko.egg-info/dependency_links.txt
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/netmiko.egg-info/dependency_links.txt
@@ -0,0 +1 @@
+
diff --git a/netmiko.egg-info/requires.txt b/netmiko.egg-info/requires.txt
new file mode 100644
index 0000000..12ec795
--- /dev/null
+++ b/netmiko.egg-info/requires.txt
@@ -0,0 +1,6 @@
+paramiko>=1.13.0
+scp>=0.10.0
+pyyaml
+
+[test]
+pytest>=2.6.0
diff --git a/netmiko.egg-info/top_level.txt b/netmiko.egg-info/top_level.txt
new file mode 100644
index 0000000..b80e31b
--- /dev/null
+++ b/netmiko.egg-info/top_level.txt
@@ -0,0 +1,19 @@
+netmiko
+netmiko/a10
+netmiko/alcatel
+netmiko/arista
+netmiko/avaya
+netmiko/brocade
+netmiko/cisco
+netmiko/dell
+netmiko/enterasys
+netmiko/extreme
+netmiko/f5
+netmiko/fortinet
+netmiko/hp
+netmiko/huawei
+netmiko/juniper
+netmiko/linux
+netmiko/ovs
+netmiko/paloalto
+netmiko/quanta
diff --git a/netmiko/__init__.py b/netmiko/__init__.py
new file mode 100644
index 0000000..251bd2d
--- /dev/null
+++ b/netmiko/__init__.py
@@ -0,0 +1,11 @@
+from netmiko.ssh_dispatcher import ConnectHandler
+from netmiko.ssh_dispatcher import ssh_dispatcher
+from netmiko.ssh_dispatcher import platforms
+from netmiko.scp_handler import SCPConn
+from netmiko.scp_handler import FileTransfer
+from netmiko.ssh_exception import NetMikoTimeoutException
+from netmiko.ssh_exception import NetMikoAuthenticationException
+
+__version__ = '0.5.1'
+__all__ = ('ConnectHandler', 'ssh_dispatcher', 'platforms', 'SCPConn', 'FileTransfer',
+           'NetMikoTimeoutException', 'NetMikoAuthenticationException',)
diff --git a/netmiko/a10/__init__.py b/netmiko/a10/__init__.py
new file mode 100644
index 0000000..bb82984
--- /dev/null
+++ b/netmiko/a10/__init__.py
@@ -0,0 +1,3 @@
+from netmiko.a10.a10_ssh import A10SSH
+
+__all__ = ['A10SSH']
diff --git a/netmiko/a10/a10_ssh.py b/netmiko/a10/a10_ssh.py
new file mode 100644
index 0000000..11ab9ae
--- /dev/null
+++ b/netmiko/a10/a10_ssh.py
@@ -0,0 +1,11 @@
+"""A10 support."""
+from netmiko.ssh_connection import SSHConnection
+
+
+class A10SSH(SSHConnection):
+    """A10 support."""
+    def session_preparation(self):
+        """A10 requires to be enable mode to disable paging."""
+        self.set_base_prompt()
+        self.enable()
+        self.disable_paging(command="terminal length 0\n")
diff --git a/netmiko/alcatel/__init__.py b/netmiko/alcatel/__init__.py
new file mode 100644
index 0000000..f9c18d3
--- /dev/null
+++ b/netmiko/alcatel/__init__.py
@@ -0,0 +1,3 @@
+from netmiko.alcatel.alcatel_sros_ssh import AlcatelSrosSSH
+
+__all__ = ['AlcatelSrosSSH']
diff --git a/netmiko/alcatel/alcatel_sros_ssh.py b/netmiko/alcatel/alcatel_sros_ssh.py
new file mode 100644
index 0000000..ea436ce
--- /dev/null
+++ b/netmiko/alcatel/alcatel_sros_ssh.py
@@ -0,0 +1,25 @@
+"""Alcatel-Lucent SROS support."""
+import re
+from netmiko.ssh_connection import SSHConnection
+
+
+class AlcatelSrosSSH(SSHConnection):
+    """Alcatel-Lucent SROS support."""
+    def session_preparation(self):
+        self.set_base_prompt()
+        self.disable_paging(command="environment no more\n")
+
+    def set_base_prompt(self, *args, **kwargs):
+        """Remove the > when navigating into the different config level."""
+        cur_base_prompt = super(AlcatelSrosSSH, self).set_base_prompt(*args, **kwargs)
+        match = re.search(r'(.*)(>.*)*#', cur_base_prompt)
+        if match:
+            # strip off >... from base_prompt
+            self.base_prompt = match.group(1)
+            return self.base_prompt
+
+    def enable(self, *args, **kwargs):
+        pass
+
+    def config_mode(self, *args, **kwargs):
+        pass
diff --git a/netmiko/arista/__init__.py b/netmiko/arista/__init__.py
new file mode 100644
index 0000000..04c12b7
--- /dev/null
+++ b/netmiko/arista/__init__.py
@@ -0,0 +1,3 @@
+from netmiko.arista.arista_ssh import AristaSSH
+
+__all__ = ['AristaSSH']
diff --git a/netmiko/arista/arista_ssh.py b/netmiko/arista/arista_ssh.py
new file mode 100644
index 0000000..dc6d148
--- /dev/null
+++ b/netmiko/arista/arista_ssh.py
@@ -0,0 +1,5 @@
+from netmiko.ssh_connection import SSHConnection
+
+
+class AristaSSH(SSHConnection):
+    pass
diff --git a/netmiko/avaya/__init__.py b/netmiko/avaya/__init__.py
new file mode 100644
index 0000000..dea4de5
--- /dev/null
+++ b/netmiko/avaya/__init__.py
@@ -0,0 +1,4 @@
+from netmiko.avaya.avaya_vsp_ssh import AvayaVspSSH
+from netmiko.avaya.avaya_ers_ssh import AvayaErsSSH
+
+__all__ = ['AvayaVspSSH', 'AvayaErsSSH']
diff --git a/netmiko/avaya/avaya_ers_ssh.py b/netmiko/avaya/avaya_ers_ssh.py
new file mode 100644
index 0000000..b3f65dc
--- /dev/null
+++ b/netmiko/avaya/avaya_ers_ssh.py
@@ -0,0 +1,42 @@
+'''
+Netmiko support for Avaya Ethernet Routing Switch
+'''
+from __future__ import print_function
+from __future__ import unicode_literals
+from netmiko.ssh_connection import SSHConnection
+from netmiko.netmiko_globals import MAX_BUFFER
+import time
+
+# Avaya presents Enter Ctrl-Y to begin.
+CTRL_Y = '\x19'
+
+
+class AvayaErsSSH(SSHConnection):
+    '''
+    Netmiko support for Avaya Ethernet Routing Switch
+    '''
+    def special_login_handler(self, delay_factor=.5):
+        '''
+        Avaya ERS presents the following as part of the login process:
+
+        Enter Ctrl-Y to begin.
+        '''
+        delay_factor = self.select_delay_factor(delay_factor)
+
+        # Handle 'Enter Ctrl-Y to begin'
+        i = 0
+        while i <= 12:
+            if self.remote_conn.recv_ready():
+                output = self.remote_conn.recv(MAX_BUFFER).decode('utf-8', 'ignore')
+                if 'Ctrl-Y' in output:
+                    self.remote_conn.sendall(CTRL_Y)
+                if 'sername' in output:
+                    self.remote_conn.sendall(self.username + '\n')
+                elif 'ssword' in output:
+                    self.remote_conn.sendall(self.password + '\n')
+                    break
+                time.sleep(delay_factor)
+            else:
+                self.remote_conn.sendall('\n')
+                time.sleep(2 * delay_factor)
+            i += 1
diff --git a/netmiko/avaya/avaya_vsp_ssh.py b/netmiko/avaya/avaya_vsp_ssh.py
new file mode 100644
index 0000000..777abba
--- /dev/null
+++ b/netmiko/avaya/avaya_vsp_ssh.py
@@ -0,0 +1,12 @@
+"""Avaya Virtual Services Platform Support."""
+from __future__ import print_function
+from __future__ import unicode_literals
+from netmiko.ssh_connection import SSHConnection
+
+
+class AvayaVspSSH(SSHConnection):
+    """Avaya Virtual Services Platform Support."""
+    def session_preparation(self):
+        """Prepare the session after the connection has been established."""
+        self.set_base_prompt()
+        self.disable_paging(command="terminal more disable\n")
diff --git a/netmiko/base_connection.py b/netmiko/base_connection.py
new file mode 100644
index 0000000..be95ced
--- /dev/null
+++ b/netmiko/base_connection.py
@@ -0,0 +1,710 @@
+'''
+Base connection class for netmiko
+
+Handles SSH connection and methods that are generically applicable to different
+platforms (Cisco and non-Cisco).
+
+Also defines methods that should generally be supported by child classes
+'''
+
+from __future__ import print_function
+from __future__ import unicode_literals
+
+import paramiko
+import time
+import socket
+import re
+import io
+from os import path
+
+from netmiko.netmiko_globals import MAX_BUFFER, BACKSPACE_CHAR
+from netmiko.ssh_exception import NetMikoTimeoutException, NetMikoAuthenticationException
+
+
+class BaseSSHConnection(object):
+    """
+    Defines vendor independent methods.
+
+    Otherwise method left as a stub method.
+    """
+    def __init__(self, ip=u'', host=u'', username=u'', password=u'', secret=u'', port=22,
+                 device_type=u'', verbose=False, global_delay_factor=.1, use_keys=False,
+                 key_file=None, ssh_strict=False, system_host_keys=False, alt_host_keys=False,
+                 alt_key_file='', ssh_config_file=None):
+
+        if ip:
+            self.host = ip
+            self.ip = ip
+        elif host:
+            self.host = host
+        if not ip and not host:
+            raise ValueError("Either ip or host must be set")
+        self.port = int(port)
+        self.username = username
+        self.password = password
+        self.secret = secret
+        self.device_type = device_type
+        self.ansi_escape_codes = False
+
+        # Use the greater of global_delay_factor or delay_factor local to method
+        self.global_delay_factor = global_delay_factor
+
+        # set in set_base_prompt method
+        self.base_prompt = ''
+
+        if not ssh_strict:
+            self.key_policy = paramiko.AutoAddPolicy()
+        else:
+            self.key_policy = paramiko.RejectPolicy()
+
+        # Options for SSH host_keys
+        self.system_host_keys = system_host_keys
+        self.alt_host_keys = alt_host_keys
+        self.alt_key_file = alt_key_file
+
+        # For SSH proxy support
+        self.ssh_config_file = ssh_config_file
+
+        self.establish_connection(verbose=verbose, use_keys=use_keys, key_file=key_file)
+        self.session_preparation()
+
+    def session_preparation(self):
+        """
+        Prepare the session after the connection has been established
+
+        This method handles some of vagaries that occur between various devices
+        early on in the session.
+
+        In general, it should include:
+        self.set_base_prompt()
+        self.disable_paging()   # if applicable
+        """
+        self.set_base_prompt()
+        self.disable_paging()
+
+    def _use_ssh_config(self, connect_dict):
+        """
+        Update SSH connection parameters based on contents of SSH 'config' file
+
+        This method modifies the connect_dict dictionary, returns None
+        """
+        # Use SSHConfig to generate source content.
+        full_path = path.abspath(path.expanduser(self.ssh_config_file))
+        if path.exists(full_path):
+            ssh_config_instance = paramiko.SSHConfig()
+            with open(full_path) as f:
+                ssh_config_instance.parse(f)
+                host_specifier = "{0}:{1}".format(self.host, self.port)
+                source = ssh_config_instance.lookup(host_specifier)
+        else:
+            source = {}
+
+        if source.get('proxycommand'):
+            proxy = paramiko.ProxyCommand(source['proxycommand'])
+        elif source.get('ProxyCommand'):
+            proxy = paramiko.ProxyCommand(source['proxycommand'])
+        else:
+            proxy = None
+
+        # Only update 'hostname', 'sock', 'port', and 'username'
+        # For 'port' and 'username' only update if using object defaults
+        if connect_dict['port'] == 22:
+            connect_dict['port'] = int(source.get('port', self.port))
+        if connect_dict['username'] == '':
+            connect_dict['username'] = source.get('username', self.username)
+        if proxy:
+            connect_dict['sock'] = proxy
+        connect_dict['hostname'] = source.get('hostname', self.host)
+
+    def _connect_params_dict(self, use_keys=False, key_file=None, timeout=8):
+        """Convert Paramiko connect params to a dictionary."""
+        return {
+            'hostname': self.host,
+            'port': self.port,
+            'username': self.username,
+            'password': self.password,
+            'look_for_keys': use_keys,
+            'allow_agent': False,
+            'key_filename': key_file,
+            'timeout': timeout,
+        }
+
+    def establish_connection(self, sleep_time=3, verbose=True, timeout=8,
+                             use_keys=False, key_file=None):
+        """
+        Establish SSH connection to the network device
+
+        Timeout will generate a NetMikoTimeoutException
+        Authentication failure will generate a NetMikoAuthenticationException
+
+        use_keys is a boolean that allows ssh-keys to be used for authentication
+        """
+
+        # Convert Paramiko connection parameters to a dictionary
+        ssh_connect_params = self._connect_params_dict(use_keys=use_keys, key_file=key_file,
+                                                       timeout=timeout)
+
+        # Check if using SSH 'config' file mainly for SSH proxy support (updates ssh_connect_params)
+        if self.ssh_config_file:
+            self._use_ssh_config(ssh_connect_params)
+
+        # Create instance of SSHClient object
+        self.remote_conn_pre = paramiko.SSHClient()
+
+        # Load host_keys for better SSH security
+        if self.system_host_keys:
+            self.remote_conn_pre.load_system_host_keys()
+        if self.alt_host_keys and path.isfile(self.alt_key_file):
+            self.remote_conn_pre.load_host_keys(self.alt_key_file)
+
+        # Default is to automatically add untrusted hosts (make sure appropriate for your env)
+        self.remote_conn_pre.set_missing_host_key_policy(self.key_policy)
+
+        # initiate SSH connection
+        try:
+            self.remote_conn_pre.connect(**ssh_connect_params)
+        except socket.error:
+            msg = "Connection to device timed-out: {device_type} {ip}:{port}".format(
+                device_type=self.device_type, ip=self.host, port=self.port)
+            raise NetMikoTimeoutException(msg)
+        except paramiko.ssh_exception.AuthenticationException as auth_err:
+            msg = "Authentication failure: unable to connect {device_type} {ip}:{port}".format(
+                device_type=self.device_type, ip=self.host, port=self.port)
+            msg += '\n' + str(auth_err)
+            raise NetMikoAuthenticationException(msg)
+
+        if verbose:
+            print("SSH connection established to {0}:{1}".format(self.host, self.port))
+
+        # Use invoke_shell to establish an 'interactive session'
+        self.remote_conn = self.remote_conn_pre.invoke_shell()
+        self.remote_conn.settimeout(timeout)
+        self.special_login_handler()
+        if verbose:
+            print("Interactive SSH session established")
+
+        time.sleep(.1)
+        if self.wait_for_recv_ready_newline():
+            return self.remote_conn.recv(MAX_BUFFER).decode('utf-8', 'ignore')
+        return ""
+
+    def select_delay_factor(self, delay_factor):
+        """Choose the greater of delay_factor or self.global_delay_factor."""
+        if delay_factor >= self.global_delay_factor:
+            return delay_factor
+        else:
+            return self.global_delay_factor
+
+    def special_login_handler(self, delay_factor=.1):
+        """Handler for devices like WLC, Avaya ERS that throw up characters prior to login."""
+        pass
+
+    def disable_paging(self, command="terminal length 0", delay_factor=.1):
+        """Disable paging default to a Cisco CLI method."""
+        debug = False
+        time.sleep(1 * delay_factor)
+        self.clear_buffer()
+        command = self.normalize_cmd(command)
+        if debug:
+            print("In disable_paging")
+            print("Command: {}".format(command))
+        self.remote_conn.sendall(self.normalize_cmd(command))
+        output = self.read_until_prompt()
+        if self.ansi_escape_codes:
+            output = self.strip_ansi_escape_codes(output)
+        if debug:
+            print(output)
+            print("Exiting disable_paging")
+        return output
+
+    def wait_for_recv_ready_newline(self, delay_factor=.1, max_loops=20):
+        """Wait for data to be in the buffer so it can be received."""
+        i = 0
+        time.sleep(delay_factor)
+        while i <= max_loops:
+            if self.remote_conn.recv_ready():
+                return True
+            else:
+                self.remote_conn.sendall('\n')
+                delay_factor = delay_factor * 1.1
+                if delay_factor >= 8:
+                    delay_factor = 8
+                time.sleep(delay_factor)
+                i += 1
+        raise NetMikoTimeoutException("Timed out waiting for recv_ready")
+
+    def wait_for_recv_ready(self, delay_factor=.1, max_loops=100, send_newline=False):
+        """Wait for data to be in the buffer so it can be received."""
+        i = 0
+        time.sleep(delay_factor)
+        while i <= max_loops:
+            if self.remote_conn.recv_ready():
+                return True
+            else:
+                time.sleep(delay_factor)
+                i += 1
+        raise NetMikoTimeoutException("Timed out waiting for recv_ready")
+
+    def set_base_prompt(self, pri_prompt_terminator='#',
+                        alt_prompt_terminator='>', delay_factor=.1):
+        """
+        Sets self.base_prompt
+
+        Used as delimiter for stripping of trailing prompt in output.
+
+        Should be set to something that is general and applies in multiple contexts. For Cisco
+        devices this will be set to router hostname (i.e. prompt without '>' or '#').
+
+        This will be set on entering user exec or privileged exec on Cisco, but not when
+        entering/exiting config mode.
+        """
+        prompt = self.find_prompt(delay_factor=delay_factor)
... 2414 lines suppressed ...

-- 
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