[Python-modules-commits] [napalm-base] 01/03: Import napalm-base_0.18.0.orig.tar.gz

Vincent Bernat bernat at moszumanska.debian.org
Tue Nov 1 20:19:21 UTC 2016


This is an automated email from the git hooks/post-receive script.

bernat pushed a commit to branch master
in repository napalm-base.

commit b98c5980a5dad5d2c23b4c6939fbdcf7c0c92eb4
Author: Vincent Bernat <bernat at debian.org>
Date:   Tue Nov 1 21:16:36 2016 +0100

    Import napalm-base_0.18.0.orig.tar.gz
---
 PKG-INFO                                    |   5 +-
 napalm_base.egg-info/PKG-INFO               |   5 +-
 napalm_base.egg-info/SOURCES.txt            |  12 +-
 napalm_base.egg-info/entry_points.txt       |   1 +
 napalm_base.egg-info/requires.txt           |   3 +-
 napalm_base.egg-info/top_level.txt          |   1 +
 napalm_base/__init__.py                     |  57 ++--
 napalm_base/base.py                         | 348 ++++++++++++++++-------
 napalm_base/clitools/cl_napalm_configure.py | 122 ++------
 napalm_base/clitools/cl_napalm_test.py      |  45 +++
 napalm_base/clitools/helpers.py             | 110 +++++++
 napalm_base/exceptions.py                   |  14 +
 napalm_base/helpers.py                      | 122 ++++++--
 napalm_base/test/base.py                    | 279 +++++++++++++-----
 napalm_base/test/conftest.py                |  49 ++++
 napalm_base/test/double.py                  |  78 +++++
 napalm_base/test/getters.py                 | 427 ++++++++++++++++++++++++++++
 napalm_base/test/helpers.py                 |  23 ++
 napalm_base/test/models.py                  | 296 ++++++++++---------
 napalm_base/utils/jinja_filters.py          |  53 ++++
 napalm_base/utils/py23_compat.py            |  15 +
 napalm_base/utils/string_parsers.py         |  43 +--
 requirements.txt                            |   3 +-
 setup.cfg                                   |  11 +-
 setup.py                                    |   8 +-
 test/__init__.py                            |   0
 26 files changed, 1646 insertions(+), 484 deletions(-)

diff --git a/PKG-INFO b/PKG-INFO
index 05c9677..7e31242 100644
--- a/PKG-INFO
+++ b/PKG-INFO
@@ -1,6 +1,6 @@
 Metadata-Version: 1.1
 Name: napalm-base
-Version: 0.14.1
+Version: 0.18.0
 Summary: Network Automation and Programmability Abstraction Layer with Multivendor support
 Home-page: https://github.com/napalm-automation/napalm-base
 Author: David Barroso
@@ -12,5 +12,8 @@ Classifier: Topic :: Utilities
 Classifier: Programming Language :: Python
 Classifier: Programming Language :: Python :: 2
 Classifier: Programming Language :: Python :: 2.7
+Classifier: Programming Language :: Python :: 3
+Classifier: Programming Language :: Python :: 3.4
+Classifier: Operating System :: POSIX :: Linux
 Classifier: Operating System :: POSIX :: Linux
 Classifier: Operating System :: MacOS
diff --git a/napalm_base.egg-info/PKG-INFO b/napalm_base.egg-info/PKG-INFO
index 05c9677..7e31242 100644
--- a/napalm_base.egg-info/PKG-INFO
+++ b/napalm_base.egg-info/PKG-INFO
@@ -1,6 +1,6 @@
 Metadata-Version: 1.1
 Name: napalm-base
-Version: 0.14.1
+Version: 0.18.0
 Summary: Network Automation and Programmability Abstraction Layer with Multivendor support
 Home-page: https://github.com/napalm-automation/napalm-base
 Author: David Barroso
@@ -12,5 +12,8 @@ Classifier: Topic :: Utilities
 Classifier: Programming Language :: Python
 Classifier: Programming Language :: Python :: 2
 Classifier: Programming Language :: Python :: 2.7
+Classifier: Programming Language :: Python :: 3
+Classifier: Programming Language :: Python :: 3.4
+Classifier: Operating System :: POSIX :: Linux
 Classifier: Operating System :: POSIX :: Linux
 Classifier: Operating System :: MacOS
diff --git a/napalm_base.egg-info/SOURCES.txt b/napalm_base.egg-info/SOURCES.txt
index 8260714..a727a17 100644
--- a/napalm_base.egg-info/SOURCES.txt
+++ b/napalm_base.egg-info/SOURCES.txt
@@ -1,5 +1,6 @@
 MANIFEST.in
 requirements.txt
+setup.cfg
 setup.py
 napalm_base/__init__.py
 napalm_base/base.py
@@ -13,8 +14,17 @@ napalm_base.egg-info/requires.txt
 napalm_base.egg-info/top_level.txt
 napalm_base/clitools/__init__.py
 napalm_base/clitools/cl_napalm_configure.py
+napalm_base/clitools/cl_napalm_test.py
+napalm_base/clitools/helpers.py
 napalm_base/test/__init__.py
 napalm_base/test/base.py
+napalm_base/test/conftest.py
+napalm_base/test/double.py
+napalm_base/test/getters.py
+napalm_base/test/helpers.py
 napalm_base/test/models.py
 napalm_base/utils/__init__.py
-napalm_base/utils/string_parsers.py
\ No newline at end of file
+napalm_base/utils/jinja_filters.py
+napalm_base/utils/py23_compat.py
+napalm_base/utils/string_parsers.py
+test/__init__.py
\ No newline at end of file
diff --git a/napalm_base.egg-info/entry_points.txt b/napalm_base.egg-info/entry_points.txt
index 4a94e3e..30cf208 100644
--- a/napalm_base.egg-info/entry_points.txt
+++ b/napalm_base.egg-info/entry_points.txt
@@ -1,3 +1,4 @@
 [console_scripts]
 cl_napalm_configure = napalm_base.clitools.cl_napalm_configure:main
+cl_napalm_test = napalm_base.clitools.cl_napalm_test:main
 
diff --git a/napalm_base.egg-info/requires.txt b/napalm_base.egg-info/requires.txt
index 62b0e5a..d8a6f3e 100644
--- a/napalm_base.egg-info/requires.txt
+++ b/napalm_base.egg-info/requires.txt
@@ -1,2 +1,3 @@
+jtextfsm
 jinja2
-gtextfsm
+netaddr
diff --git a/napalm_base.egg-info/top_level.txt b/napalm_base.egg-info/top_level.txt
index d140051..4c74f08 100644
--- a/napalm_base.egg-info/top_level.txt
+++ b/napalm_base.egg-info/top_level.txt
@@ -1 +1,2 @@
 napalm_base
+test
diff --git a/napalm_base/__init__.py b/napalm_base/__init__.py
index b14c82a..3b09d4d 100644
--- a/napalm_base/__init__.py
+++ b/napalm_base/__init__.py
@@ -14,13 +14,33 @@
 
 """napalm_base package."""
 
+# Python3 support
+from __future__ import print_function
+from __future__ import unicode_literals
+
 # Python std lib
+import sys
 import inspect
 import importlib
+import pkg_resources
+
+# Verify Python Version that is running
+try:
+    if not(sys.version_info.major == 2 and sys.version_info.minor == 7) and \
+            not(sys.version_info.major == 3):
+        raise RuntimeError('NAPALM requires Python 2.7 or Python3')
+except AttributeError:
+    raise RuntimeError('NAPALM requires Python 2.7 or Python3')
 
 # NAPALM base
 from napalm_base.base import NetworkDriver
 from napalm_base.exceptions import ModuleImportError
+from napalm_base.utils import py23_compat
+
+try:
+    __version__ = pkg_resources.get_distribution('napalm-base').version
+except pkg_resources.DistributionNotFound:
+    __version__ = "Not installed"
 
 
 __all__ = [
@@ -30,19 +50,22 @@ __all__ = [
 
 
 def get_network_driver(module_name):
-
     """
     Searches for a class derived form the base NAPALM class NetworkDriver in a specific library.
     The library name must repect the following pattern: napalm_[DEVICE_OS].
-    NAPALM community supports a list of devices and provides the corresponding libraries; for full reference
-    please refer to the `Supported Network Operation Systems`_ paragraph on `Read the Docs`_.
+    NAPALM community supports a list of devices and provides the corresponding libraries; for
+    full reference please refer to the `Supported Network Operation Systems`_ paragraph on
+    `Read the Docs`_.
 
-    .. _`Supported Network Operation Systems`: http://napalm.readthedocs.io/en/latest/#supported-network-operating-systems
-    .. _`Read the Docs`: http://napalm.readthedocs.io/
+    .. _`Supported Network Operation Systems`: \
+    http://napalm.readthedocs.io/en/latest/#supported-network-operating-systems
+    .. _`Read the Docs`: \
+    http://napalm.readthedocs.io/
 
-    :param module_name:         the name of the device operating system, or the name of the library.
+    :param module_name:         the name of the device operating system or the name of the library.
     :return:                    the first class derived from NetworkDriver, found in the library.
-    :raise ModuleImportError:   when the library is not installed, or a derived class from NetworkDriver was not found.
+    :raise ModuleImportError:   when the library is not installed or a derived class from \
+    NetworkDriver was not found.
 
     Example::
 
@@ -55,16 +78,20 @@ def get_network_driver(module_name):
         >>> get_network_driver('napalm_eos')
         <class 'napalm_eos.eos.EOSDriver'>
         >>> get_network_driver('wrong')
-        napalm_base.exceptions.ModuleImportError: Cannot import "napalm_wrong". Is the library installed?
+        napalm_base.exceptions.ModuleImportError: Cannot import "napalm_wrong". Is the library \
+        installed?
     """
 
-    if not (isinstance(module_name, basestring) and len(module_name) > 0):
+    if not (isinstance(module_name, py23_compat.string_types) and len(module_name) > 0):
         raise ModuleImportError('Please provide a valid driver name.')
 
     try:
-        module_name = module_name.lower()  # only lowercase allowed
-        module_install_name = module_name.replace('-', '')  # to not raise error when users requests IOS-XR for e.g.
-        if 'napalm_' not in module_install_name:  # can also request using napalm_[SOMETHING]
+        # Only lowercase allowed
+        module_name = module_name.lower()
+        # Try to not raise error when users requests IOS-XR for e.g.
+        module_install_name = module_name.replace('-', '')
+        # Can also request using napalm_[SOMETHING]
+        if 'napalm_' not in module_install_name:
             module_install_name = 'napalm_{name}'.format(name=module_install_name)
         module = importlib.import_module(module_install_name)
     except ImportError:
@@ -80,7 +107,5 @@ def get_network_driver(module_name):
 
     # looks like you don't have any Driver class in your module...
     raise ModuleImportError(
-            'No class inheriting "napalm_base.base.NetworkDriver" found in "{install_name}".'.format(
-                install_name=module_install_name
-            )
-        )
+        'No class inheriting "napalm_base.base.NetworkDriver" found in "{install_name}".'
+        .format(install_name=module_install_name))
diff --git a/napalm_base/base.py b/napalm_base/base.py
index 19d6c9f..7a94d4c 100644
--- a/napalm_base/base.py
+++ b/napalm_base/base.py
@@ -12,6 +12,10 @@
 # License for the specific language governing permissions and limitations under
 # the License.
 
+# Python3 support
+from __future__ import print_function
+from __future__ import unicode_literals
+
 # std libs
 import sys
 
@@ -24,9 +28,10 @@ class NetworkDriver(object):
 
     def __init__(self, hostname, username, password, timeout, optional_args):
         """
-        This is the base class you have to inherit from when writing your own Network Driver to manage any device. You
-        will, in addition, have to override all the methods specified on this class. Make sure you follow the guidelines
-        for every method and that you return the correct data.
+        This is the base class you have to inherit from when writing your own Network Driver to
+        manage any device. You will, in addition, have to override all the methods specified on
+        this class. Make sure you follow the guidelines for every method and that you return the
+        correct data.
 
         :param hostname: (str) IP or FQDN of the device you want to connect to.
         :param username: (str) Username you want to use
@@ -53,21 +58,24 @@ class NetworkDriver(object):
     @staticmethod
     def __raise_clean_exception(exc_type, exc_value, exc_traceback):
         """
-        This method is going to check if the exception exc_type is part of the builtins exceptions or part of the
-        napalm exceptions. If it is not, it will print a message on the screen giving instructions to fill a bug.
+        This method is going to check if the exception exc_type is part of the builtins exceptions
+        or part of the napalm exceptions. If it is not, it will print a message on the screen
+        giving instructions to fill a bug.
+
         Finally it will raise the original exception.
 
         :param exc_type: Exception class.
         :param exc_value: Exception object.
         :param exc_traceback: Traceback.
         """
-        if exc_type.__name__ not in dir(napalm_base.exceptions) and \
-                        exc_type.__name__ not in __builtins__.keys():
+        if (exc_type.__name__ not in dir(napalm_base.exceptions) and
+                exc_type.__name__ not in __builtins__.keys()):
             epilog = ("NAPALM didn't catch this exception. Please, fill a bugfix on "
                       "https://github.com/napalm-automation/napalm/issues\n"
                       "Don't forget to include this traceback.")
             print(epilog)
-        raise exc_type, exc_value, exc_traceback
+        # Traceback should already be attached to exception; no need to re-attach
+        raise exc_value
 
     def open(self):
         """
@@ -81,21 +89,22 @@ class NetworkDriver(object):
         """
         raise NotImplementedError
 
-    def load_template(self, template_name, template_source=None, template_path=None, **template_vars):
+    def load_template(self, template_name, template_source=None,
+                      template_path=None, **template_vars):
         """
         Will load a templated configuration on the device.
 
         :param cls: Instance of the driver class.
         :param template_name: Identifies the template name.
-        :param template_source (optional): A custom config template to be rendered and loaded on the device
-        :param template_path (optional): Specifies the absolute path to a different directory for the configuration \
-        templates
-        :param template_vars: Dictionary with the arguments  to be used when the template is rendered.
-        :raise DriverTemplateNotImplemented: No template defined for the device type
-        :raise TemplateNotImplemented: The template specified in template_name does not exist in the default path or \
-        in the custom path if any specified using parameter `template_path`
-        :raise TemplateRenderException: The template could not be rendered. Either the template source does not have \
-        the right format, either the arguments in `template_vars` are not properly specified.
+        :param template_source (optional): Custom config template rendered and loaded on device
+        :param template_path (optional): Absolute path to directory for the configuration templates
+        :param template_vars: Dictionary with arguments to be used when the template is rendered.
+        :raise DriverTemplateNotImplemented: No template defined for the device type.
+        :raise TemplateNotImplemented: The template specified in template_name does not exist in \
+        the default path or in the custom path if any specified using parameter `template_path`.
+        :raise TemplateRenderException: The template could not be rendered. Either the template \
+        source does not have the right format, either the arguments in `template_vars` are not \
+        properly specified.
         """
         return napalm_base.helpers.load_template(self,
                                                  template_name,
@@ -105,11 +114,13 @@ class NetworkDriver(object):
 
     def load_replace_candidate(self, filename=None, config=None):
         """
-        Populates the candidate configuration. You can populate it from a file or from a string. If you send both a
-        filename and a string containing the configuration, the file takes precedence.
+        Populates the candidate configuration. You can populate it from a file or from a string.
+        If you send both a filename and a string containing the configuration, the file takes
+        precedence.
 
-        If you use this method the existing configuration will be replaced entirely by the candidate configuration once
-        you commit the changes. This method will not change the configuration by itself.
+        If you use this method the existing configuration will be replaced entirely by the
+        candidate configuration once you commit the changes. This method will not change the
+        configuration by itself.
 
         :param filename: Path to the file containing the desired configuration. By default is None.
         :param config: String containing the desired configuration.
@@ -119,11 +130,13 @@ class NetworkDriver(object):
 
     def load_merge_candidate(self, filename=None, config=None):
         """
-        Populates the candidate configuration. You can populate it from a file or from a string. If you send both a
-        filename and a string containing the configuration, the file takes precedence.
+        Populates the candidate configuration. You can populate it from a file or from a string.
+        If you send both a filename and a string containing the configuration, the file takes
+        precedence.
 
-        If you use this method the existing configuration will be merged with the candidate configuration once
-        you commit the changes. This method will not change the configuration by itself.
+        If you use this method the existing configuration will be merged with the candidate
+        configuration once you commit the changes. This method will not change the configuration
+        by itself.
 
         :param filename: Path to the file containing the desired configuration. By default is None.
         :param config: String containing the desired configuration.
@@ -133,8 +146,9 @@ class NetworkDriver(object):
 
     def compare_config(self):
         """
-        :return: A string showing the difference between the running configuration and the candidate configuration. The\
-        running_config is loaded automatically just before doing the comparison so there is no need for you to do it.
+        :return: A string showing the difference between the running configuration and the \
+        candidate configuration. The running_config is loaded automatically just before doing the \
+        comparison so there is no need for you to do it.
         """
         raise NotImplementedError
 
@@ -186,8 +200,9 @@ class NetworkDriver(object):
 
     def get_interfaces(self):
         """
-        Returns a dictionary of dictionaries. The keys for the first dictionary will be the interfaces in the devices.\
-        The inner dictionary will containing the following data for each interface:
+        Returns a dictionary of dictionaries. The keys for the first dictionary will be the \
+        interfaces in the devices. The inner dictionary will containing the following data for \
+        each interface:
          * is_up (True/False)
          * is_enabled (True/False)
          * description (string)
@@ -240,8 +255,8 @@ class NetworkDriver(object):
 
     def get_lldp_neighbors(self):
         """
-        Returns a dictionary where the keys are local ports and the value is a list of dictionaries with the following \
-        information:
+        Returns a dictionary where the keys are local ports and the value is a list of \
+        dictionaries with the following information:
             * hostname
             * port
 
@@ -286,11 +301,12 @@ class NetworkDriver(object):
 
     def get_bgp_neighbors(self):
         """
-        Returns a dictionary of dictionaries. The keys for the first dictionary will be the vrf (global if no vrf).
-        The inner dictionary will contain the following data for each vrf:
+        Returns a dictionary of dictionaries. The keys for the first dictionary will be the vrf
+        (global if no vrf). The inner dictionary will contain the following data for each vrf:
 
           * router_id
-          * peers - another dictionary of dictionaries. Outer keys are the IPs of the neighbors. The inner keys are:
+          * peers - another dictionary of dictionaries. Outer keys are the IPs of the neighbors. \
+            The inner keys are:
              * local_as (int)
              * remote_as (int)
              * remote_id - peer router id
@@ -298,8 +314,8 @@ class NetworkDriver(object):
              * is_enabled (True/False)
              * description (string)
              * uptime (int in seconds)
-             * address_family (dictionary) - A dictionary of address families available for the neighbor. So far it can\
-               be 'ipv4' or 'ipv6'
+             * address_family (dictionary) - A dictionary of address families available for the \
+               neighbor. So far it can be 'ipv4' or 'ipv6'
                 * received_prefixes (int)
                 * accepted_prefixes (int)
                 * sent_prefixes (int)
@@ -312,10 +328,10 @@ class NetworkDriver(object):
 
             * fans is a dictionary of dictionaries where the key is the location and the values:
                  * status (True/False) - True if it's ok, false if it's broken
-            * temperature is a dictionary of dictionaries where the key is the location and the values:
+            * temperature is a dict of dictionaries where the key is the location and the values:
                  * temperature (float) - Temperature in celsius the sensor is reporting.
                  * is_alert (True/False) - True if the temperature is above the alert threshold
-                 * is_critical (True/False) - True if the temperature is above the critical threshold
+                 * is_critical (True/False) - True if the temp is above the critical threshold
             * power is a dictionary of dictionaries where the key is the PSU id and the values:
                  * status (True/False) - True if it's ok, false if it's broken
                  * capacity (float) - Capacity in W that the power supply can support
@@ -330,8 +346,8 @@ class NetworkDriver(object):
 
     def get_interfaces_counters(self):
         """
-        Returns a dictionary of dictionaries where the first key is an interface name and the inner dictionary contains
-        the following keys:
+        Returns a dictionary of dictionaries where the first key is an interface name and the
+        inner dictionary contains the following keys:
 
             * tx_errors (int)
             * rx_errors (int)
@@ -395,7 +411,7 @@ class NetworkDriver(object):
         """
         raise NotImplementedError
 
-    def get_lldp_neighbors_detail(self, interface = ''):
+    def get_lldp_neighbors_detail(self, interface=''):
         """
         Returns a detailed view of the LLDP neighbors as a dictionary
         containing lists of dictionaries for each interface.
@@ -420,7 +436,8 @@ class NetworkDriver(object):
                         'remote_system_name': u'switch',
                         'remote_port': u'Eth2/2/1',
                         'remote_port_description': u'Ethernet2/2/1',
-                        'remote_system_description': u'''Cisco Nexus Operating System (NX-OS) Software 7.1(0)N1(1a)
+                        'remote_system_description': u'''Cisco Nexus Operating System (NX-OS)
+                              Software 7.1(0)N1(1a)
                               TAC support: http://www.cisco.com/tac
                               Copyright (c) 2002-2015, Cisco Systems, Inc. All rights reserved.''',
                         'remote_system_capab': u'B, R',
@@ -439,7 +456,8 @@ class NetworkDriver(object):
         :param group: Returns the configuration of a specific BGP group.
         :param neighbor: Returns the configuration of a specific BGP neighbor.
 
-        Main dictionary keys represent the group name and the values represent a dictionary having the following keys:
+        Main dictionary keys represent the group name and the values represent a dictionary having
+        the following keys:
             * type (string)
             * description (string)
             * apply_groups (string list)
@@ -541,14 +559,14 @@ class NetworkDriver(object):
                                                         I just saw Episode Two
                                                         You're my only hope
                                             ''',
-                u'show chassis fan'     :   u'''Item                      Status   RPM     Measurement
-                                                Top Rear Fan              OK       3840    Spinning at intermediate-speed
-                                                Bottom Rear Fan           OK       3840    Spinning at intermediate-speed
-                                                Top Middle Fan            OK       3900    Spinning at intermediate-speed
-                                                Bottom Middle Fan         OK       3840    Spinning at intermediate-speed
-                                                Top Front Fan             OK       3810    Spinning at intermediate-speed
-                                                Bottom Front Fan          OK       3840    Spinning at intermediate-speed
-                                            '''
+                u'show chassis fan'     :   u'''
+                    Item               Status  RPM     Measurement
+                    Top Rear Fan       OK      3840    Spinning at intermediate-speed
+                    Bottom Rear Fan    OK      3840    Spinning at intermediate-speed
+                    Top Middle Fan     OK      3900    Spinning at intermediate-speed
+                    Bottom Middle Fan  OK      3840    Spinning at intermediate-speed
+                    Top Front Fan      OK      3810    Spinning at intermediate-speed
+                    Bottom Front Fan   OK      3840    Spinning at intermediate-speed'''
             }
         """
         raise NotImplementedError
@@ -560,11 +578,15 @@ class NetworkDriver(object):
 
         :param neighbor_address: Retuns the statistics for a spcific BGP neighbor.
 
-        The keys of the dictionary represent the AS number of the neighbors.
-        Inner dictionaries contain the following fields:
+        Returns a dictionary of dictionaries. The keys for the first dictionary will be the vrf
+        (global if no vrf).
+        The keys of the inner dictionary represent the AS number of the neighbors.
+        Leaf dictionaries contain the following fields:
+
             * up (True/False)
             * local_as (int)
             * remote_as (int)
+            * router_id (string)
             * local_address (string)
             * routing_table (string)
             * local_address_configured (True/False)
@@ -600,44 +622,46 @@ class NetworkDriver(object):
         Example::
 
             {
-                8121: [
-                    {
-                        'up'                        : True,
-                        'local_as'                  : 13335,
-                        'remote_as'                 : 8121,
-                        'local_address'             : u'172.101.76.1',
-                        'local_address_configured'  : True,
-                        'local_port'                : 179,
-                        'routing_table'             : u'inet.0',
-                        'remote_address'            : u'192.247.78.0',
-                        'remote_port'               : 58380,
-                        'multihop'                  : False,
-                        'multipath'                 : True,
-                        'remove_private_as'         : True,
-                        'import_policy'             : u'4-NTT-TRANSIT-IN',
-                        'export_policy'             : u'4-NTT-TRANSIT-OUT',
-                        'input_messages'            : 123,
-                        'output_messages'           : 13,
-                        'input_updates'             : 123,
-                        'output_updates'            : 5,
-                        'messages_queued_out'       : 23,
-                        'connection_state'          : u'Established',
-                        'previous_connection_state' : u'EstabSync',
-                        'last_event'                : u'RecvKeepAlive',
-                        'suppress_4byte_as'         : False,
-                        'local_as_prepend'          : False,
-                        'holdtime'                  : 90,
-                        'configured_holdtime'       : 90,
-                        'keepalive'                 : 30,
-                        'configured_keepalive'      : 30,
-                        'active_prefix_count'       : 132808,
-                        'received_prefix_count'     : 566739,
-                        'accepted_prefix_count'     : 566479,
-                        'suppressed_prefix_count'   : 0,
-                        'advertise_prefix_count'    : 0,
-                        'flap_count'                : 27
-                    }
-                ]
+                'global': {
+                    8121: [
+                        {
+                            'up'                        : True,
+                            'local_as'                  : 13335,
+                            'remote_as'                 : 8121,
+                            'local_address'             : u'172.101.76.1',
+                            'local_address_configured'  : True,
+                            'local_port'                : 179,
+                            'routing_table'             : u'inet.0',
+                            'remote_address'            : u'192.247.78.0',
+                            'remote_port'               : 58380,
+                            'multihop'                  : False,
+                            'multipath'                 : True,
+                            'remove_private_as'         : True,
+                            'import_policy'             : u'4-NTT-TRANSIT-IN',
+                            'export_policy'             : u'4-NTT-TRANSIT-OUT',
+                            'input_messages'            : 123,
+                            'output_messages'           : 13,
+                            'input_updates'             : 123,
+                            'output_updates'            : 5,
+                            'messages_queued_out'       : 23,
+                            'connection_state'          : u'Established',
+                            'previous_connection_state' : u'EstabSync',
+                            'last_event'                : u'RecvKeepAlive',
+                            'suppress_4byte_as'         : False,
+                            'local_as_prepend'          : False,
+                            'holdtime'                  : 90,
+                            'configured_holdtime'       : 90,
+                            'keepalive'                 : 30,
+                            'configured_keepalive'      : 30,
+                            'active_prefix_count'       : 132808,
+                            'received_prefix_count'     : 566739,
+                            'accepted_prefix_count'     : 566479,
+                            'suppressed_prefix_count'   : 0,
+                            'advertised_prefix_count'   : 0,
+                            'flap_count'                : 27
+                        }
+                    ]
+                }
             }
         """
         raise NotImplementedError
@@ -671,7 +695,6 @@ class NetworkDriver(object):
         """
         raise NotImplementedError
 
-
     def get_ntp_peers(self):
 
         """
@@ -692,6 +715,25 @@ class NetworkDriver(object):
 
         raise NotImplementedError
 
+    def get_ntp_servers(self):
+
+        """
+        Returns the NTP servers configuration as dictionary.
+        The keys of the dictionary represent the IP Addresses of the servers.
+        Inner dictionaries do not have yet any available keys.
+
+        Example::
+
+            {
+                '192.168.0.1': {},
+                '17.72.148.53': {},
+                '37.187.56.220': {},
+                '162.158.20.18': {}
+            }
+
+        """
+
+        raise NotImplementedError
 
     def get_ntp_stats(self):
 
@@ -736,7 +778,8 @@ class NetworkDriver(object):
         Returns all configured IP addresses on all interfaces as a dictionary of dictionaries.
         Keys of the main dictionary represent the name of the interface.
         Values of the main dictionary represent are dictionaries that may consist of two keys
-        'ipv4' and 'ipv6' (one, both or none) which are themselvs dictionaries witht the IP addresses as keys.
+        'ipv4' and 'ipv6' (one, both or none) which are themselvs dictionaries witht the IP
+        addresses as keys.
         Each IP Address dictionary has the following keys:
             * prefix_length (int)
 
@@ -785,8 +828,8 @@ class NetworkDriver(object):
     def get_mac_address_table(self):
 
         """
-        Returns a lists of dictionaries. Each dictionary represents an entry in the MAC Address Table,
-        having the following keys:
+        Returns a lists of dictionaries. Each dictionary represents an entry in the MAC Address
+        Table, having the following keys:
             * mac (string)
             * interface (string)
             * vlan (int)
@@ -835,7 +878,8 @@ class NetworkDriver(object):
     def get_route_to(self, destination='', protocol=''):
 
         """
-        Returns a dictionary of dictionaries containing details of all available routes to a destination.
+        Returns a dictionary of dictionaries containing details of all available routes to a
+        destination.
 
         :param destination: The destination prefix to be used when filtering the routes.
         :param protocol (optional): Retrieve the routes only for a specific protocol.
@@ -950,7 +994,8 @@ class NetworkDriver(object):
     def get_probes_config(self):
         """
         Returns a dictionary with the probes configured on the device.
-        Probes can be either RPM on JunOS devices, either SLA on IOS-XR. Other vendors do not support probes.
+        Probes can be either RPM on JunOS devices, either SLA on IOS-XR. Other vendors do not
+        support probes.
         The keys of the main dictionary represent the name of the probes.
         Each probe consists on multiple tests, each test name being a key in the probe dictionary.
         A test has the following keys:
@@ -1051,7 +1096,6 @@ class NetworkDriver(object):
         """
         raise NotImplementedError
 
-
     def ping(self, destination, source='', ttl=0, timeout=0, size=0, count=0):
         """
         Executes ping on the device and returns a dictionary with the result
@@ -1115,7 +1159,6 @@ class NetworkDriver(object):
         """
         raise NotImplementedError
 
-
     def traceroute(self, destination, source='', ttl=0, timeout=0):
         """
         Executes traceroute on the device and returns a dictionary with the result.
@@ -1130,9 +1173,8 @@ class NetworkDriver(object):
             * success
             * error
 
-        In case of success, the keys of the dictionary represent the hop ID, while values are dictionaries
-        containing the probes results:
-
+        In case of success, the keys of the dictionary represent the hop ID, while values are
+        dictionaries containing the probes results:
             * rtt (float)
             * ip_address (str)
             * host_name (str)
@@ -1223,18 +1265,17 @@ class NetworkDriver(object):
             """
         raise NotImplementedError
 
-
     def get_users(self):
         """
         Returns a dictionary with the configured users.
-        The keys of the main dictionary represents the username. The values represent the details of the user,
-        represented by the following keys:
-
+        The keys of the main dictionary represents the username. The values represent the details
+        of the user, represented by the following keys:
             * level (int)
             * password (str)
             * sshkeys (list)
 
-        The level is an integer between 0 and 15, where 0 is the lowest access and 15 represents full access to the device.
+        The level is an integer between 0 and 15, where 0 is the lowest access and 15 represents
+        full access to the device.
 
         Example::
 
@@ -1243,9 +1284,98 @@ class NetworkDriver(object):
                     'level': 15,
                     'password': '$1$0P70xKPa$z46fewjo/10cBTckk6I/w/',
                     'sshkeys': [
-                        'ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC4pFn+shPwTb2yELO4L7NtQrKOJXNeCl1jel9STXVaGnRAnuc2PXl35vnWmcUq6YbUEcgUTRzzXfmelJKuVJTJIlMXii7h2xkbQp0YZIEs4P8ipwnRBAxFfk/ZcDsN3mjep4/yjN56eorF5xs7zP9HbqbJ1dsqk1p3A/9LIL7l6YewLBCwJj6D+fWSJ0/YW+7oH17Fk2HH+tw0L5PcWLHkwA4t60iXn16qDbIk/ze6jv2hDGdCdz7oYQeCE55CCHOHMJWYfN3jcL4s0qv8/u6Ka1FVkV7iMmro7ChThoV/5snI4Ljf2wKqgHH7TfNaCfpU0WvHAnTs8zhOrGScSrtb mircea at master-roshi'
+                        'ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC4pFn+shPwTb2yELO4L7NtQrKOJXNeCl1je\
+                         l9STXVaGnRAnuc2PXl35vnWmcUq6YbUEcgUTRzzXfmelJKuVJTJIlMXii7h2xkbQp0YZIEs4P\
+                         8ipwnRBAxFfk/ZcDsN3mjep4/yjN56eorF5xs7zP9HbqbJ1dsqk1p3A/9LIL7l6YewLBCwJj6\
+                         D+fWSJ0/YW+7oH17Fk2HH+tw0L5PcWLHkwA4t60iXn16qDbIk/ze6jv2hDGdCdz7oYQeCE55C\
+                         CHOHMJWYfN3jcL4s0qv8/u6Ka1FVkV7iMmro7ChThoV/5snI4Ljf2wKqgHH7TfNaCfpU0WvHA\
+                         nTs8zhOrGScSrtb mircea at master-roshi'
                     ]
                 }
             }
         """
         raise NotImplementedError
+
+    def get_optics(self):
+        """Fetches the power usage on the various transceivers installed
+        on the switch (in dbm), and returns a view that conforms with the
+        openconfig model openconfig-platform-transceiver.yang
+
+        Returns a dictionary where the keys are as listed below:
+
+            * intf_name (unicode)
+                * physical_channels
+                    * channels (list of dicts)
+                        * index (int)
+                        * state
+                            * input_power
+                                * instant (float)
+                                * avg (float)
+                                * min (float)
+                                * max (float)
+                            * output_power
+                                * instant (float)
+                                * avg (float)
+                                * min (float)
+                                * max (float)
+                            * laser_bias_current
+                                * instant (float)
+                                * avg (float)
+                                * min (float)
+                                * max (float)
+
+        Example:
+
+            {
+                    'et1': {
+                        'physical_channels': {
+                            'channel': [
+                                {
+                                    'index': 0,
+                                    'state': {
+                                        'input_power': {
+                                            'instant': 0.0,
+                                            'avg': 0.0,
+                                            'min': 0.0,
+                                            'max': 0.0,
+                                        },
+                                        'output_power': {
+                                            'instant': 0.0,
+                                            'avg': 0.0,
+                                            'min': 0.0,
+                                            'max': 0.0,
+                                        },
+                                        'laser_bias_current': {
+                                            'instant': 0.0,
+                                            'avg': 0.0,
+                                            'min': 0.0,
+                                            'max': 0.0,
+                                        },
+                                    }
+                                }
+                            ]
+                        }
+                    }
+                }
+        """
+        raise NotImplementedError
+
+    def get_config(self, retrieve='all'):
+        """
+        Return the configuration of a device.
+
+        Args:
+            retrieve(string): Which configuration type you want to populate, default is all of them.
+                The rest will be set to "".
+
+        Returns:
+          The object returned is a dictionary with the following keys:
+            - running(string) - Representation of the native running configuration
+            - candidate(string) - Representation of the native candidate configuration. If the
+              device doesnt differentiate between running and startup configuration this will an
+              empty string
+            - startup(string) - Representation of the native startup configuration. If the
+              device doesnt differentiate between running and startup configuration this will an
+              empty string
+        """
+        raise NotImplementedError
diff --git a/napalm_base/clitools/cl_napalm_configure.py b/napalm_base/clitools/cl_napalm_configure.py
index 0f6df15..1251a33 100644
--- a/napalm_base/clitools/cl_napalm_configure.py
+++ b/napalm_base/clitools/cl_napalm_configure.py
@@ -1,113 +1,34 @@
-from __future__ import print_function
+# -*- coding: utf-8 -*-
+'''
+NAPALM CLI Tools: configure
+===========================
 
-import argparse
-import sys
-import getpass
+Deploy device config from the shell.
+'''
 
-from napalm import get_network_driver
+# Python3 support
+from __future__ import print_function
+from __future__ import unicode_literals
 
+# import helpers
+from napalm_base import get_network_driver
+from napalm_base.clitools.helpers import build_help
+from napalm_base.clitools.helpers import configure_logging
+from napalm_base.clitools.helpers import parse_optional_args
+
+import sys
 import logging
 logger = logging.getLogger('cl-napalm-config.py')
 
 
-def build_help():
-    parser = argparse.ArgumentParser(
-        description='Command line tool to handle configuration on devices using NAPALM.'
-                    'The script will print the diff on the screen',
-        epilog='Automate all the things!!!'
-    )
-    parser.add_argument(
-        dest='config_file',
-        action='store',
-        help='File containing the configuration you want to deploy.'
-    )
-    parser.add_argument(
-        dest='hostname',
-        action='store',
-        help='Host where you want to deploy the configuration.'
-    )
-    parser.add_argument(
-        '--user', '-u',
-        dest='user',
-        action='store',
-        default=getpass.getuser(),
-        help='User for authenticating to the host. Default: user running the script.'
-    )
-    parser.add_argument(
-        '--password', '-p',
-        dest='password',
-        action='store',
-        help='Password for authenticating to the host.'
-             'If you do not provide a password in the CLI you will be prompted.',
-    )
-    parser.add_argument(
-        '--vendor', '-v',
-        dest='vendor',
-        action='store',
-        required=True,
-        help='Host Operating System.'
-    )
-    parser.add_argument(
-        '--strategy', '-s',
-        dest='strategy',
-        action='store',
-        choices=['replace', 'merge'],
-        default='replace',
-        help='Strategy to use to deploy configuration. Default: replace.'
-    )
-    parser.add_argument(
-        '--optional_args', '-o',
-        dest='optional_args',
-        action='store',
-        help='String with comma separated key=value pairs that will be passed via optional_args to the driver.',
-    )
-    parser.add_argument(
-        '--dry-run', '-d',
-        dest='dry_run',
-        action='store_true',
-        default=None,
-        help='Only returns diff, it does not deploy the configuration.',
-    )
-    parser.add_argument(
-        '--debug',
-        dest='debug',
-        action='store_true',
-        help='Enables debug mode; more verbosity.'
-    )
-    args = parser.parse_args()
-
-    if args.password is None:
-        password = getpass.getpass('Enter password: ')
-        setattr(args, 'password', password)
-
-    return args
-
-
-def configure_logging(debug):
-    if debug:
-        logger.setLevel(logging.DEBUG)
-    else:
-        logger.setLevel(logging.INFO)
-
-    ch = logging.StreamHandler(sys.stdout)
-    formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
-    ch.setFormatter(formatter)
-    logger.addHandler(ch)
-
-
-class CustomException(Exception):
-    pass
-
-
 def run(vendor, hostname, user, password, strategy, optional_args, config_file, dry_run):
+
     logger.debug('Getting driver for OS "{driver}"'.format(driver=vendor))
     driver = get_network_driver(vendor)
 
-    if optional_args is not None:
-        optional_args = {x.split('=')[0]: x.split('=')[1] for x in optional_args.replace(' ', '').split(',')}
-
-    logger.debug('Connecting to device "{device}" with user "{user}" and optional_args={optional_args}'.format(
-                    device=hostname, user=user, optional_args=optional_args))
+    optional_args = parse_optional_args(optional_args)
+    logger.debug('Connecting to device "{}" with user "{}" and optional_args={}'.format(
+                 hostname, user, optional_args))
     with driver(hostname, user, password, optional_args=optional_args) as device:
         logger.debug('Strategy for loading configuration is "{strategy}"'.format(strategy=strategy))
         if strategy == 'replace':
@@ -127,13 +48,12 @@ def run(vendor, hostname, user, password, strategy, optional_args, config_file,
             logger.debug('Committing configuration')
             device.commit_config()
         logger.debug('Closing session')
-
         return diff
 
 
 def main():
     args = build_help()
-    configure_logging(args.debug)
+    configure_logging(logger, args.debug)
 
     print(run(args.vendor, args.hostname, args.user, args.password, args.strategy,
               args.optional_args, args.config_file, args.dry_run))
diff --git a/napalm_base/clitools/cl_napalm_test.py b/napalm_base/clitools/cl_napalm_test.py
new file mode 100644
index 0000000..86b14bd
--- /dev/null
+++ b/napalm_base/clitools/cl_napalm_test.py
@@ -0,0 +1,45 @@
+# -*- coding: utf-8 -*-
+'''
+NAPALM CLI Tools: test connectivity
+===================================
+
+Module to test connectivity with the network device through NAPALM.
+'''
+from __future__ import absolute_import
+from __future__ import print_function
... 2188 lines suppressed ...

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/python-modules/packages/napalm-base.git



More information about the Python-modules-commits mailing list