[Python-modules-commits] [napalm-junos] 01/03: Import napalm-junos_0.5.1.orig.tar.gz

Vincent Bernat bernat at moszumanska.debian.org
Sun Dec 25 10:27:56 UTC 2016


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

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

commit bc980bc027635ac537b51e42a996fa821baecf95
Author: Vincent Bernat <bernat at debian.org>
Date:   Sun Dec 25 11:24:39 2016 +0100

    Import napalm-junos_0.5.1.orig.tar.gz
---
 PKG-INFO                                     |   2 +-
 napalm_junos.egg-info/PKG-INFO               |   2 +-
 napalm_junos.egg-info/SOURCES.txt            |   5 +
 napalm_junos.egg-info/requires.txt           |   2 +-
 napalm_junos/constants.py                    |  16 +++
 napalm_junos/junos.py                        | 174 +++++++++++++++++++--------
 napalm_junos/templates/delete_ntp_servers.j2 |  11 ++
 napalm_junos/templates/delete_snmp_config.j2 |  24 ++++
 napalm_junos/templates/set_ntp_servers.j2    |  11 ++
 napalm_junos/templates/snmp_config.j2        |  23 ++++
 napalm_junos/utils/junos_views.yml           |  39 ++++--
 requirements.txt                             |   2 +-
 setup.cfg                                    |   9 ++
 setup.py                                     |   2 +-
 14 files changed, 261 insertions(+), 61 deletions(-)

diff --git a/PKG-INFO b/PKG-INFO
index 5eb894d..529bb90 100644
--- a/PKG-INFO
+++ b/PKG-INFO
@@ -1,6 +1,6 @@
 Metadata-Version: 1.1
 Name: napalm-junos
-Version: 0.4.3
+Version: 0.5.1
 Summary: Network Automation and Programmability Abstraction Layer with Multivendor support
 Home-page: https://github.com/napalm-automation/napalm-junos
 Author: David Barroso, Mircea Ulinic
diff --git a/napalm_junos.egg-info/PKG-INFO b/napalm_junos.egg-info/PKG-INFO
index 5eb894d..529bb90 100644
--- a/napalm_junos.egg-info/PKG-INFO
+++ b/napalm_junos.egg-info/PKG-INFO
@@ -1,6 +1,6 @@
 Metadata-Version: 1.1
 Name: napalm-junos
-Version: 0.4.3
+Version: 0.5.1
 Summary: Network Automation and Programmability Abstraction Layer with Multivendor support
 Home-page: https://github.com/napalm-automation/napalm-junos
 Author: David Barroso, Mircea Ulinic
diff --git a/napalm_junos.egg-info/SOURCES.txt b/napalm_junos.egg-info/SOURCES.txt
index 08b5e5a..affcf58 100644
--- a/napalm_junos.egg-info/SOURCES.txt
+++ b/napalm_junos.egg-info/SOURCES.txt
@@ -3,6 +3,7 @@ requirements.txt
 setup.cfg
 setup.py
 napalm_junos/__init__.py
+napalm_junos/constants.py
 napalm_junos/junos.py
 napalm_junos.egg-info/PKG-INFO
 napalm_junos.egg-info/SOURCES.txt
@@ -10,11 +11,15 @@ napalm_junos.egg-info/dependency_links.txt
 napalm_junos.egg-info/requires.txt
 napalm_junos.egg-info/top_level.txt
 napalm_junos/templates/delete_ntp_peers.j2
+napalm_junos/templates/delete_ntp_servers.j2
 napalm_junos/templates/delete_probes.j2
+napalm_junos/templates/delete_snmp_config.j2
 napalm_junos/templates/schedule_probes.j2
 napalm_junos/templates/set_hostname.j2
 napalm_junos/templates/set_ntp_peers.j2
+napalm_junos/templates/set_ntp_servers.j2
 napalm_junos/templates/set_probes.j2
+napalm_junos/templates/snmp_config.j2
 napalm_junos/utils/__init__.py
 napalm_junos/utils/junos_views.py
 napalm_junos/utils/junos_views.yml
\ No newline at end of file
diff --git a/napalm_junos.egg-info/requires.txt b/napalm_junos.egg-info/requires.txt
index 1c041d0..724db5e 100644
--- a/napalm_junos.egg-info/requires.txt
+++ b/napalm_junos.egg-info/requires.txt
@@ -1,2 +1,2 @@
-napalm-base>=0.18.0
+napalm-base>=0.20.3
 junos-eznc
diff --git a/napalm_junos/constants.py b/napalm_junos/constants.py
new file mode 100644
index 0000000..9cf47fd
--- /dev/null
+++ b/napalm_junos/constants.py
@@ -0,0 +1,16 @@
+"""Constants for the JunOS driver."""
+
+from __future__ import unicode_literals
+
+from napalm_base.constants import *  # noqa
+
+# OpenConfig mapping
+# ref: https://github.com/openconfig/public/blob/master/release/models/network-instance/openconfig-network-instance-types.yang  # noqa
+OC_NETWORK_INSTANCE_TYPE_MAP = {
+    'default': 'DEFAULT_INSTANCE',
+    'l2vpn': 'L2VPN',
+    'vrf': 'L3VRF',
+    'evpn': 'BGP_EVPN',
+    'vpls': 'BGP_VPLS',
+    'forwarding': 'L2P2P'
+}
diff --git a/napalm_junos/junos.py b/napalm_junos/junos.py
index 0939b00..5c7e15c 100644
--- a/napalm_junos/junos.py
+++ b/napalm_junos/junos.py
@@ -27,6 +27,7 @@ from lxml.builder import E
 
 from jnpr.junos import Device
 from jnpr.junos.utils.config import Config
+from jnpr.junos.exception import RpcError
 from jnpr.junos.exception import ConfigLoadError
 from jnpr.junos.exception import RpcTimeoutError
 from jnpr.junos.exception import ConnectTimeoutError
@@ -36,6 +37,7 @@ import napalm_base.helpers
 from napalm_base.base import NetworkDriver
 from napalm_base.utils import string_parsers
 from napalm_base.utils import py23_compat
+import napalm_junos.constants as C
 from napalm_base.exceptions import ConnectionException
 from napalm_base.exceptions import MergeConfigException
 from napalm_base.exceptions import CommandErrorException
@@ -84,26 +86,33 @@ class JunOSDriver(NetworkDriver):
             del self.device.cu
         self.device.bind(cu=Config)
         if self.config_lock:
-            self.lock()
+            self._lock()
 
     def close(self):
         """Close the connection."""
         if self.config_lock:
-            self.unlock()
+            self._unlock()
         self.device.close()
 
-    def lock(self):
+    def _lock(self):
         """Lock the config DB."""
         if not self.locked:
             self.device.cu.lock()
             self.locked = True
 
-    def unlock(self):
+    def _unlock(self):
         """Unlock the config DB."""
         if self.locked:
             self.device.cu.unlock()
             self.locked = False
 
+    def is_alive(self):
+        # evaluate the state of the underlying SSH connection
+        # and also the NETCONF status from PyEZ
+        return {
+            'is_alive': self.device._conn._session.transport.is_active() and self.device.connected
+        }
+
     def _load_candidate(self, filename, config, overwrite):
         if filename is None:
             configuration = config
@@ -114,7 +123,7 @@ class JunOSDriver(NetworkDriver):
         if not self.config_lock:
             # if not locked during connection time
             # will try to lock it if not already aquired
-            self.lock()
+            self._lock()
             # and the device will be locked till first commit/rollback
 
         try:
@@ -148,13 +157,13 @@ class JunOSDriver(NetworkDriver):
         """Commit configuration."""
         self.device.cu.commit()
         if not self.config_lock:
-            self.unlock()
+            self._unlock()
 
     def discard_config(self):
         """Discard changes (rollback 0)."""
         self.device.cu.rollback(rb_id=0)
         if not self.config_lock:
-            self.unlock()
+            self._unlock()
 
     def rollback(self):
         """Rollback to previous commit."""
@@ -468,7 +477,7 @@ class JunOSDriver(NetworkDriver):
 
         return lldp_neighbors
 
-    def cli(self, commands=None):
+    def cli(self, commands):
         """Execute raw CLI commands and returns their output."""
         cli_output = {}
 
@@ -951,20 +960,18 @@ class JunOSDriver(NetworkDriver):
 
         return mac_address_table
 
-    def get_route_to(self, destination=None, protocol=None):
+    def get_route_to(self, destination='', protocol=''):
         """Return route details to a specific destination, learned from a certain protocol."""
         routes = {}
 
         if not isinstance(destination, py23_compat.string_types):
             raise TypeError('Please specify a valid destination!')
 
-        if not isinstance(protocol, py23_compat.string_types) or \
-           protocol.lower() not in ('static', 'bgp', 'isis'):
-            raise TypeError("Protocol not supported: {protocol}.".format(
-                protocol=protocol
-            ))
+        if protocol and isinstance(destination, py23_compat.string_types):
+            protocol = protocol.lower()
 
-        protocol = protocol.lower()
+        if protocol == 'connected':
+            protocol = 'direct'  # this is how is called on JunOS
 
         _COMMON_PROTOCOL_FIELDS_ = [
             'destination',
@@ -1008,19 +1015,27 @@ class JunOSDriver(NetworkDriver):
 
         routes_table = junos_views.junos_protocol_route_table(self.device)
 
+        rt_kargs = {
+            'destination': destination
+        }
+        if protocol and isinstance(destination, py23_compat.string_types):
+            rt_kargs['protocol'] = protocol
+
         try:
-            routes_table.get(
-                destination=destination,
-                protocol=protocol
-            )
+            routes_table.get(**rt_kargs)
         except RpcTimeoutError:
             # on devices with milions of routes
             # in case the destination is too generic (e.g.: 10/8)
             # will take very very long to determine all routes and
             # moreover will return a huge list
             raise CommandTimeoutException(
-                'Too many routes returned! Please try with a longer prefix!'
+                'Too many routes returned! Please try with a longer prefix or a specific protocol!'
             )
+        except RpcError as rpce:
+            if len(rpce.errs) > 0 and 'bad_element' in rpce.errs[0]:
+                raise CommandErrorException(
+                    'Unknown protocol: {proto}'.format(proto=rpce.errs[0]['bad_element']))
+            raise CommandErrorException(rpce)
         except Exception as err:
             raise CommandErrorException('Cannot retrieve routes! Reason: {err}'.format(err=err))
 
@@ -1028,7 +1043,7 @@ class JunOSDriver(NetworkDriver):
 
         for route in routes_items:
             d = {}
-            next_hop = route[0]
+            # next_hop = route[0]
             d = {elem[0]: elem[1] for elem in route[1]}
             destination = napalm_base.helpers.ip(d.pop('destination', ''))
             prefix_length = d.pop('prefix_length', 32)
@@ -1046,10 +1061,13 @@ class JunOSDriver(NetworkDriver):
                 # to be sure that contains only AS Numbers
             if d.get('inactive_reason') is None:
                 d['inactive_reason'] = u''
+            route_protocol = d.get('protocol').lower()
+            if protocol and protocol != route_protocol:
+                continue
             communities = d.get('communities')
             if communities is not None and type(communities) is not list:
                 d['communities'] = [communities]
-            d['next_hop'] = unicode(next_hop)
+            # d['next_hop'] = unicode(next_hop)
             d_keys = d.keys()
             # fields that are not in _COMMON_PROTOCOL_FIELDS_ are supposed to be protocol specific
             all_protocol_attributes = {
@@ -1059,7 +1077,7 @@ class JunOSDriver(NetworkDriver):
             }
             protocol_attributes = {
                 key: value for key, value in all_protocol_attributes.iteritems()
-                if key in _PROTOCOL_SPECIFIC_FIELDS_.get(protocol)
+                if key in _PROTOCOL_SPECIFIC_FIELDS_.get(route_protocol, [])
             }
             d['protocol_attributes'] = protocol_attributes
             if destination not in routes.keys():
@@ -1072,11 +1090,6 @@ class JunOSDriver(NetworkDriver):
         """Return the SNMP configuration."""
         snmp_information = {}
 
-        _AUTHORIZATION_MODE_MAP_ = {
-            'read-only': u'ro',
-            'read-write': u'rw'
-        }
-
         snmp_config = junos_views.junos_snmp_config_table(self.device)
         snmp_config.get()
         snmp_items = snmp_config.items()
@@ -1084,27 +1097,28 @@ class JunOSDriver(NetworkDriver):
         if not snmp_items:
             return snmp_information
 
-        communities = []
-        for snmp_config_out in snmp_items:
-            community_details = snmp_config_out[1]
-            communities.append({
-                c[0]: c[1] for c in community_details
-            })
-
         snmp_information = {
-            'contact': napalm_base.helpers.convert(unicode, communities[0].get('contact')),
-            'location': napalm_base.helpers.convert(unicode, communities[0].get('location')),
-            'chassis_id': napalm_base.helpers.convert(unicode, communities[0].get('chassis')),
-            'community': {}
+            py23_compat.text_type(ele[0]): ele[1] if ele[1] else ''
+            for ele in snmp_items[0][1]
         }
 
-        for snmp_entry in communities:
-            name = napalm_base.helpers.convert(unicode, snmp_entry.get('name'))
-            authorization = napalm_base.helpers.convert(unicode, snmp_entry.get('authorization'))
-            snmp_information['community'][name] = {
-                'mode': _AUTHORIZATION_MODE_MAP_.get(authorization, u''),
-                'acl': u''
+        snmp_information['community'] = {}
+        communities_table = snmp_information.pop('communities_table')
+        if not communities_table:
+            return snmp_information
+
+        for community in communities_table.items():
+            community_name = py23_compat.text_type(community[0])
+            community_details = {
+                'acl': ''
             }
+            community_details.update({
+                py23_compat.text_type(ele[0]): py23_compat.text_type(
+                    ele[1] if ele[0] != 'mode'
+                    else C.SNMP_AUTHORIZATION_MODE_MAP.get(ele[1]))
+                for ele in community[1]
+            })
+            snmp_information['community'][community_name] = community_details
 
         return snmp_information
 
@@ -1168,7 +1182,11 @@ class JunOSDriver(NetworkDriver):
 
         return probes_results
 
-    def traceroute(self, destination, source='', ttl=0, timeout=0):
+    def traceroute(self,
+                   destination,
+                   source=C.TRACEROUTE_SOURCE,
+                   ttl=C.TRACEROUTE_TTL,
+                   timeout=C.TRACEROUTE_TIMEOUT):
         """Execute traceroute and return results."""
         traceroute_result = {}
 
@@ -1283,9 +1301,10 @@ class JunOSDriver(NetworkDriver):
         # Formatting data into return data structure
         optics_detail = {}
         for intf_optic_item in optics_items:
+            interface_name = py23_compat.text_type(intf_optic_item[0])
             optics = dict(intf_optic_item[1])
-            if intf_optic_item[0] not in optics_detail:
-                optics_detail[intf_optic_item[0]] = {}
+            if interface_name not in optics_detail:
+                optics_detail[interface_name] = {}
 
             # Defaulting avg, min, max values to 0.0 since device does not
             # return these values
@@ -1325,7 +1344,7 @@ class JunOSDriver(NetworkDriver):
                         }]
                     }
                 }
-            optics_detail[intf_optic_item[0]] = intf_optics
+            optics_detail[interface_name] = intf_optics
 
         return optics_detail
 
@@ -1351,3 +1370,60 @@ class JunOSDriver(NetworkDriver):
             rv['running'] = py23_compat.text_type(config.text.encode('ascii', 'replace'))
 
         return rv
+
+    def get_network_instances(self, name=''):
+
+        network_instances = {}
+
+        ri_table = junos_views.junos_nw_instances_table(self.device)
+        ri_table.get()
+        ri_entries = ri_table.items()
+
+        vrf_interfaces = []
+
+        for ri_entry in ri_entries:
+            ri_name = py23_compat.text_type(ri_entry[0])
+            ri_details = {
+                d[0]: d[1] for d in ri_entry[1]
+            }
+            ri_type = ri_details['instance_type']
+            if ri_type is None:
+                ri_type = 'default'
+            ri_rd = ri_details['route_distinguisher']
+            ri_interfaces = ri_details['interfaces']
+            network_instances[ri_name] = {
+                'name': ri_name,
+                'type': C.OC_NETWORK_INSTANCE_TYPE_MAP.get(ri_type, ri_type),  # default: return raw
+                'state': {
+                    'route_distinguisher': ri_rd if ri_rd else ''
+                },
+                'interfaces': {
+                    'interface': {
+                        intrf_name: {} for intrf_name in ri_interfaces if intrf_name
+                    }
+                }
+            }
+            vrf_interfaces.extend(network_instances[ri_name]['interfaces']['interface'].keys())
+
+        all_interfaces = self.get_interfaces().keys()
+        default_interfaces = list(set(all_interfaces) - set(vrf_interfaces))
+        if 'default' not in network_instances:
+            network_instances['default'] = {
+                'name': 'default',
+                'type': C.OC_NETWORK_INSTANCE_TYPE_MAP.get('default'),
+                'state': {
+                    'route_distinguisher': ''
+                },
+                'interfaces': {
+                    'interface': {
+                        py23_compat.text_type(intrf_name): {}
+                        for intrf_name in default_interfaces
+                    }
+                }
+            }
+
+        if not name:
+            return network_instances
+        if name not in network_instances:
+            return {}
+        return {name: network_instances[name]}
diff --git a/napalm_junos/templates/delete_ntp_servers.j2 b/napalm_junos/templates/delete_ntp_servers.j2
new file mode 100644
index 0000000..df53c56
--- /dev/null
+++ b/napalm_junos/templates/delete_ntp_servers.j2
@@ -0,0 +1,11 @@
+{% if (servers is defined) and servers %}
+system {
+  ntp {
+    {% for server in servers %}
+      {% if server %}
+        delete: server {{server}};
+      {% endif %}
+    {% endfor %}
+  }
+}
+{% endif %}
diff --git a/napalm_junos/templates/delete_snmp_config.j2 b/napalm_junos/templates/delete_snmp_config.j2
new file mode 100644
index 0000000..d1accb7
--- /dev/null
+++ b/napalm_junos/templates/delete_snmp_config.j2
@@ -0,0 +1,24 @@
+snmp {
+  {% if (location is defined) and location %}
+  delete: location "{{location}}";
+  {% endif %}
+  {% if (contact is defined) and contact %}
+  delete: contact "{{contact}}";
+  {% endif %}
+  {% if (community is defined) and community %}
+  {% for comm_name, comm_details in community.iteritems() %}
+  delete: community {{comm_name}} {
+    {% if (comm_details is defined) and comm_details %}
+    {% if (comm_details.get('mode') is defined) and comm_details.get('mode') == 'rw' %}
+    authorization read-write;
+    {% else %}
+    authorization read-only;
+    {% endif %}
+    {% else %}
+    authorization read-only;
+    {% endif %}
+  }
+  {% endfor %}
+  {% endif %}
+}
+
diff --git a/napalm_junos/templates/set_ntp_servers.j2 b/napalm_junos/templates/set_ntp_servers.j2
new file mode 100644
index 0000000..10e4f1c
--- /dev/null
+++ b/napalm_junos/templates/set_ntp_servers.j2
@@ -0,0 +1,11 @@
+{% if (servers is defined) and servers %}
+system {
+  ntp {
+    {% for server in servers %}
+      {% if server %}
+        server {{server}};
+      {% endif %}
+    {% endfor %}
+  }
+}
+{% endif %}
diff --git a/napalm_junos/templates/snmp_config.j2 b/napalm_junos/templates/snmp_config.j2
new file mode 100644
index 0000000..39da13d
--- /dev/null
+++ b/napalm_junos/templates/snmp_config.j2
@@ -0,0 +1,23 @@
+snmp {
+  {% if (location is defined) and location %}
+  location "{{location}}";
+  {% endif %}
+  {% if (contact is defined) and contact %}
+  contact "{{contact}}";
+  {% endif %}
+  {% if (community is defined) and community %}
+  {% for comm_name, comm_details in community.iteritems() %}
+  community {{comm_name}} {
+    {% if (comm_details is defined) and comm_details %}
+    {% if (comm_details.get('mode') is defined) and comm_details.get('mode') == 'rw' %}
+    authorization read-write;
+    {% else %}
+    authorization read-only;
+    {% endif %}
+    {% else %}
+    authorization read-only;
+    {% endif %}
+  }
+  {% endfor %}
+  {% endif %}
+}
diff --git a/napalm_junos/utils/junos_views.yml b/napalm_junos/utils/junos_views.yml
index 9c4f7bf..a795a01 100644
--- a/napalm_junos/utils/junos_views.yml
+++ b/napalm_junos/utils/junos_views.yml
@@ -476,7 +476,7 @@ junos_protocol_route_table:
     destination
     protocol
   item: route-table/rt/rt-entry/nh
-  key: to
+  key: via
   view: junos_route_table_view
 
 junos_route_table_view:
@@ -518,16 +518,25 @@ junos_route_table_view:
 ###
 
 junos_snmp_config_table:
-  get: snmp/community
+  get: snmp
   view: junos_snmp_config_view
+  key: contact
 
 junos_snmp_config_view:
   fields:
-    name: name
-    authorization: authorization
-    location: ../location
-    contact: ../contact
-    chassis: ../system-name
+    location: {location: unicode}
+    contact: {contact: unicode}
+    chassis_id: {system-name: unicode}
+    communities_table: junos_snmp_communities_table
+
+junos_snmp_communities_table:
+  item: community
+  key: name
+  view: junos_snmp_communities_view
+
+junos_snmp_communities_view:
+  fields:
+    mode: authorization
 
 ###
 ### RPM Probes Config
@@ -608,3 +617,19 @@ junos_intf_optics_view:
     laser_bias_current: laser-bias-current
     output_power: laser-output-power-dbm
     input_power: rx-signal-avg-optical-power-dbm
+
+###
+### Get network instances
+###
+
+junos_nw_instances_table:
+  get: routing-instances/instance
+  view: junos_nw_instances_view
+  args_key:
+    name
+
+junos_nw_instances_view:
+  fields:
+    instance_type: {instance-type: unicode}
+    interfaces: {interface/name: unicode}
+    route_distinguisher: {route-distinguisher/rd-type: unicode}
diff --git a/requirements.txt b/requirements.txt
index 1c041d0..724db5e 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,2 +1,2 @@
-napalm-base>=0.18.0
+napalm-base>=0.20.3
 junos-eznc
diff --git a/setup.cfg b/setup.cfg
index 5f3d64f..68969e0 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -5,6 +5,15 @@ ignore = D203,C901
 [pylama:pep8]
 max_line_length = 100
 
+[pytest]
+addopts = --cov=./ -vs
+json_report = report.json
+jsonapi = true
+
+[coverage:run]
+include = 
+	napalm_junos/*
+
 [egg_info]
 tag_build = 
 tag_date = 0
diff --git a/setup.py b/setup.py
index 97a0abd..2a3702e 100644
--- a/setup.py
+++ b/setup.py
@@ -12,7 +12,7 @@ reqs = [str(ir.req) for ir in install_reqs]
 
 setup(
     name="napalm-junos",
-    version="0.4.3",
+    version="0.5.1",
     packages=find_packages(),
     author="David Barroso, Mircea Ulinic",
     author_email="dbarrosop at dravetech.com, mircea at cloudflare.com",

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



More information about the Python-modules-commits mailing list