[Python-modules-commits] [napalm-eos] 01/03: Import napalm-eos_0.4.2.orig.tar.gz
Vincent Bernat
bernat at moszumanska.debian.org
Wed Nov 2 18:57:58 UTC 2016
This is an automated email from the git hooks/post-receive script.
bernat pushed a commit to branch master
in repository napalm-eos.
commit c480182d1566220f5ba0706afd5e01eabdbec184
Author: Vincent Bernat <bernat at debian.org>
Date: Wed Nov 2 19:54:31 2016 +0100
Import napalm-eos_0.4.2.orig.tar.gz
---
PKG-INFO | 2 +-
napalm_eos.egg-info/PKG-INFO | 2 +-
napalm_eos.egg-info/SOURCES.txt | 2 +
napalm_eos.egg-info/requires.txt | 2 +-
napalm_eos/__init__.py | 8 +
napalm_eos/eos.py | 768 ++++++++++++++++------
napalm_eos/utils/textfsm_templates/bgp_detail.tpl | 46 ++
requirements.txt | 2 +-
setup.cfg | 16 +
setup.py | 2 +-
10 files changed, 636 insertions(+), 214 deletions(-)
diff --git a/PKG-INFO b/PKG-INFO
index f546c4f..2f87f6c 100644
--- a/PKG-INFO
+++ b/PKG-INFO
@@ -1,6 +1,6 @@
Metadata-Version: 1.1
Name: napalm-eos
-Version: 0.2.1
+Version: 0.4.2
Summary: Network Automation and Programmability Abstraction Layer with Multivendor support
Home-page: https://github.com/napalm-automation/napalm-eos
Author: David Barroso
diff --git a/napalm_eos.egg-info/PKG-INFO b/napalm_eos.egg-info/PKG-INFO
index f546c4f..2f87f6c 100644
--- a/napalm_eos.egg-info/PKG-INFO
+++ b/napalm_eos.egg-info/PKG-INFO
@@ -1,6 +1,6 @@
Metadata-Version: 1.1
Name: napalm-eos
-Version: 0.2.1
+Version: 0.4.2
Summary: Network Automation and Programmability Abstraction Layer with Multivendor support
Home-page: https://github.com/napalm-automation/napalm-eos
Author: David Barroso
diff --git a/napalm_eos.egg-info/SOURCES.txt b/napalm_eos.egg-info/SOURCES.txt
index 59f4055..3385ad8 100644
--- a/napalm_eos.egg-info/SOURCES.txt
+++ b/napalm_eos.egg-info/SOURCES.txt
@@ -1,5 +1,6 @@
MANIFEST.in
requirements.txt
+setup.cfg
setup.py
napalm_eos/__init__.py
napalm_eos/eos.py
@@ -11,5 +12,6 @@ napalm_eos.egg-info/top_level.txt
napalm_eos/templates/delete_ntp_peers.j2
napalm_eos/templates/set_ntp_peers.j2
napalm_eos/utils/__init__.py
+napalm_eos/utils/textfsm_templates/bgp_detail.tpl
napalm_eos/utils/textfsm_templates/ntp_peers.tpl
napalm_eos/utils/textfsm_templates/snmp_config.tpl
\ No newline at end of file
diff --git a/napalm_eos.egg-info/requires.txt b/napalm_eos.egg-info/requires.txt
index 5e773d3..64f2b11 100644
--- a/napalm_eos.egg-info/requires.txt
+++ b/napalm_eos.egg-info/requires.txt
@@ -1,2 +1,2 @@
-napalm-base
+napalm-base>=0.18.0
pyeapi
diff --git a/napalm_eos/__init__.py b/napalm_eos/__init__.py
index 7015fd1..c398f99 100644
--- a/napalm_eos/__init__.py
+++ b/napalm_eos/__init__.py
@@ -14,3 +14,11 @@
"""napalm_eos package."""
from eos import EOSDriver
+import pkg_resources
+
+try:
+ __version__ = pkg_resources.get_distribution('napalm-eos').version
+except pkg_resources.DistributionNotFound:
+ __version__ = "Not installed"
+
+__all__ = ('EOSDriver',)
diff --git a/napalm_eos/eos.py b/napalm_eos/eos.py
index 050e57c..5ffc224 100644
--- a/napalm_eos/eos.py
+++ b/napalm_eos/eos.py
@@ -21,10 +21,12 @@ Read napalm.readthedocs.org for more information.
# std libs
import re
import time
+
from datetime import datetime
+
from netaddr import IPAddress
from netaddr import IPNetwork
-from collections import defaultdict
+
from netaddr.core import AddrFormatError
# third party libs
@@ -35,8 +37,8 @@ from pyeapi.eapilib import ConnectionError
import napalm_base.helpers
from napalm_base.base import NetworkDriver
from napalm_base.utils import string_parsers
-from napalm_base.exceptions import ConnectionException, MergeConfigException, ReplaceConfigException,\
- SessionLockedException, CommandErrorException
+from napalm_base.exceptions import ConnectionException, MergeConfigException, \
+ ReplaceConfigException, SessionLockedException, CommandErrorException
# local modules
# here add local imports
@@ -46,6 +48,8 @@ from napalm_base.exceptions import ConnectionException, MergeConfigException, Re
class EOSDriver(NetworkDriver):
"""Napalm driver for Arista EOS."""
+ SUPPORTED_OC_MODELS = []
+
def __init__(self, hostname, username, password, timeout=60, optional_args=None):
"""Constructor."""
self.device = None
@@ -57,20 +61,35 @@ class EOSDriver(NetworkDriver):
if optional_args is None:
optional_args = {}
- self.port = optional_args.get('port', 443)
+
+ self.transport = optional_args.get('eos_transport', 'https')
+
+ if self.transport == 'https':
+ self.port = optional_args.get('port', 443)
+ elif self.transrpot == 'http':
+ self.port = optional_args.get('port', 80)
+
+ self.enablepwd = optional_args.get('enable_password', '')
def open(self):
- """Implemantation of NAPALM method open."""
+ """Implementation of NAPALM method open."""
try:
- connection = pyeapi.client.connect(
- transport='https',
- host=self.hostname,
- username=self.username,
- password=self.password,
- port=self.port,
- timeout=self.timeout
- )
- self.device = pyeapi.client.Node(connection)
+ if self.transport in ('http', 'https'):
+ connection = pyeapi.client.connect(
+ transport='https',
+ host=self.hostname,
+ username=self.username,
+ password=self.password,
+ port=self.port,
+ timeout=self.timeout
+ )
+ elif self.transport == 'socket':
+ connection = pyeapi.client.connect(transport=self.transport)
+ else:
+ raise ConnectionException("Unknown transport: {}".format(self.transport))
+
+ if self.device is None:
+ self.device = pyeapi.client.Node(connection, enablepwd=self.enablepwd)
# does not raise an Exception if unusable
# let's try to run a very simple command
@@ -82,7 +101,7 @@ class EOSDriver(NetworkDriver):
raise ConnectionException(ce.message)
def close(self):
- """Implemantation of NAPALM method close."""
+ """Implementation of NAPALM method close."""
self.discard_config()
def _load_config(self, filename=None, config=None, replace=True):
@@ -125,15 +144,15 @@ class EOSDriver(NetworkDriver):
raise MergeConfigException(e.message)
def load_replace_candidate(self, filename=None, config=None):
- """Implemantation of NAPALM method load_replace_candidate."""
+ """Implementation of NAPALM method load_replace_candidate."""
self._load_config(filename, config, True)
def load_merge_candidate(self, filename=None, config=None):
- """Implemantation of NAPALM method load_merge_candidate."""
+ """Implementation of NAPALM method load_merge_candidate."""
self._load_config(filename, config, False)
def compare_config(self):
- """Implemantation of NAPALM method compare_config."""
+ """Implementation of NAPALM method compare_config."""
if self.config_session is None:
return ''
else:
@@ -145,7 +164,7 @@ class EOSDriver(NetworkDriver):
return result.strip()
def commit_config(self):
- """Implemantation of NAPALM method commit_config."""
+ """Implementation of NAPALM method commit_config."""
commands = list()
commands.append('copy startup-config flash:rollback-0')
commands.append('configure session {}'.format(self.config_session))
@@ -156,7 +175,7 @@ class EOSDriver(NetworkDriver):
self.config_session = None
def discard_config(self):
- """Implemantation of NAPALM method discard_config."""
+ """Implementation of NAPALM method discard_config."""
if self.config_session is not None:
commands = list()
commands.append('configure session {}'.format(self.config_session))
@@ -165,14 +184,14 @@ class EOSDriver(NetworkDriver):
self.config_session = None
def rollback(self):
- """Implemantation of NAPALM method rollback."""
+ """Implementation of NAPALM method rollback."""
commands = list()
commands.append('configure replace flash:rollback-0')
commands.append('write memory')
self.device.run_commands(commands)
def get_facts(self):
- """Implemantation of NAPALM method get_facts."""
+ """Implementation of NAPALM method get_facts."""
commands = list()
commands.append('show version')
commands.append('show hostname')
@@ -225,7 +244,8 @@ class EOSDriver(NetworkDriver):
interfaces[interface]['last_flapped'] = values.pop('lastStatusChangeTimestamp', None)
interfaces[interface]['speed'] = int(values['bandwidth'] * 1e-6)
- interfaces[interface]['mac_address'] = values.pop('physicalAddress', u'')
+ interfaces[interface]['mac_address'] = napalm_base.helpers.convert(
+ napalm_base.helpers.mac, values.pop('physicalAddress', u''))
return interfaces
@@ -304,12 +324,17 @@ class EOSDriver(NetworkDriver):
return m.group('as')
@staticmethod
+ def _bgp_neighbor_enabled(line):
+ m = re.match('\s+BGP\s+state\s+is\s+.*,\s+Administratively\s+shut\s+down', line)
+ return m is None
+
+ @staticmethod
def _parse_prefix_info(line):
m = re.match('(\s*?)(?P<af>IPv[46]) Unicast:\s*(?P<sent>\d+)\s*(?P<received>\d+)', line)
return m.group('sent'), m.group('received')
def get_bgp_neighbors(self):
- NEIGHBOR_FILTER = 'bgp neighbors vrf all | include remote AS | remote router ID |^\s*IPv[46] Unicast:.*[0-9]+|^Local AS|Desc'
+ NEIGHBOR_FILTER = 'bgp neighbors vrf all | include remote AS | remote router ID |IPv[46] Unicast:.*[0-9]+|^Local AS|Desc|BGP state' # noqa
output_summary_cmds = self.device.run_commands(
['show ipv6 bgp summary vrf all', 'show ip bgp summary vrf all'],
encoding='json')
@@ -317,7 +342,7 @@ class EOSDriver(NetworkDriver):
['show ip ' + NEIGHBOR_FILTER, 'show ipv6 ' + NEIGHBOR_FILTER],
encoding='text')
- bgp_counters = defaultdict(lambda: dict(peers=dict()))
+ bgp_counters = {}
for summary in output_summary_cmds:
"""
Json output looks as follows
@@ -344,14 +369,19 @@ class EOSDriver(NetworkDriver):
}
"""
for vrf, vrf_data in summary['vrfs'].iteritems():
+ if vrf not in bgp_counters.keys():
+ bgp_counters[vrf] = {
+ 'peers': {}
+ }
bgp_counters[vrf]['router_id'] = vrf_data['routerId']
for peer, peer_data in vrf_data['peers'].iteritems():
peer_info = {
'is_up': peer_data['peerState'] == 'Established',
- 'is_enabled': peer_data['peerState'] == 'Established' or peer_data['peerState'] == 'Active',
+ 'is_enabled': peer_data['peerState'] == 'Established' or
+ peer_data['peerState'] == 'Active',
'uptime': int(peer_data['upDownTime'])
}
- bgp_counters[vrf]['peers'][peer] = peer_info
+ bgp_counters[vrf]['peers'][napalm_base.helpers.ip(peer)] = peer_info
lines = []
[lines.extend(x['output'].splitlines()) for x in output_neighbor_cmds]
for line in lines:
@@ -361,6 +391,7 @@ class EOSDriver(NetworkDriver):
BGP neighbor is 1.1.1.1, remote AS 1, external link
Description: Very info such descriptive
BGP version 4, remote router ID 1.1.1.1, VRF my_vrf
+ BGP state is Idle, Administratively shut down
IPv4 Unicast: 683 78
IPv6 Unicast: 0 0
Local AS is 2, local router ID 2.2.2.2
@@ -377,12 +408,13 @@ class EOSDriver(NetworkDriver):
else:
rid, vrf = self._parse_rid_info(lines.pop(0))
+ is_enabled = self._bgp_neighbor_enabled(lines.pop(0))
v4_sent, v4_recv = self._parse_prefix_info(lines.pop(0))
v6_sent, v6_recv = self._parse_prefix_info(lines.pop(0))
local_as = self._parse_local_info(lines.pop(0))
data = {
'remote_as': int(r_as),
- 'remote_id': unicode(rid),
+ 'remote_id': napalm_base.helpers.ip(rid),
'local_as': int(local_as),
'description': unicode(desc),
'address_family': {
@@ -398,30 +430,22 @@ class EOSDriver(NetworkDriver):
}
}
}
- bgp_counters[vrf]['peers'][neighbor].update(data)
+ peer_addr = napalm_base.helpers.ip(neighbor)
+ if peer_addr not in bgp_counters[vrf]['peers'].keys():
+ bgp_counters[vrf]['peers'][peer_addr] = {
+ 'is_up': False, # if not found, means it was not found in the oper stats
+ # i.e. neighbor down,
+ 'uptime': 0,
+ 'is_enabled': is_enabled
+ }
+ bgp_counters[vrf]['peers'][peer_addr].update(data)
if 'default' in bgp_counters.keys():
bgp_counters['global'] = bgp_counters.pop('default')
return bgp_counters
def get_environment(self):
- """
- Returns a dictionary where:
- * fans is a dictionary of dictionaries where the key is the location and the values:
- * status (boolean) - 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 (int) - Temperature in celsius the sensor is reporting.
- * is_alert (boolean) - True if the temperature is above the alert threshold
- * is_critical (boolean) - True if the temperature is above the critical threshold
- * power is a dictionary of dictionaries where the key is the PSU id and the values:
- * status (boolean) - True if it's ok, false if it's broken
- * capacity (int) - Capacity in W that the power supply can support
- * output (int) - Watts drawn by the system
- * cpu is a dictionary of dictionaries where the key is the ID and the values
- * %usage
- * available_ram (int) - Total amount of RAM installed in the device
- * used_ram (int) - RAM that is still free in the device
- """
+ """Impplementation of get_environment"""
command = list()
command.append('show environment cooling')
command.append('show environment temperature')
@@ -439,7 +463,8 @@ class EOSDriver(NetworkDriver):
fans_output = output[0]
temp_output = output[1]
power_output = output[2]
- cpu_output = self.device.run_commands(['show processes top once'], encoding='text')[0]['output']
+ cpu_output = self.device.run_commands(['show processes top once'],
+ encoding='text')[0]['output']
''' Get fans counters '''
for slot in fans_output['fanTraySlots']:
@@ -452,9 +477,9 @@ class EOSDriver(NetworkDriver):
for sensorsgroup in temp_output[slot]:
for sensor in sensorsgroup['tempSensors']:
environment_counters['temperature'][sensor['name']] = {
- 'temperature': sensor['currentTemperature'],
- 'is_alert': sensor['currentTemperature'] > sensor['overheatThreshold'],
- 'is_critical': sensor['currentTemperature'] > sensor['criticalThreshold']
+ 'temperature': sensor['currentTemperature'],
+ 'is_alert': sensor['currentTemperature'] > sensor['overheatThreshold'],
+ 'is_critical': sensor['currentTemperature'] > sensor['criticalThreshold']
}
except:
pass
@@ -482,7 +507,7 @@ class EOSDriver(NetworkDriver):
return environment_counters
- def get_lldp_neighbors_detail(self, interface = ''):
+ def get_lldp_neighbors_detail(self, interface=''):
lldp_neighbors_out = dict()
@@ -493,42 +518,44 @@ class EOSDriver(NetworkDriver):
commands = list()
commands.append(
'show lldp neighbors {filters} detail'.format(
- filters = ' '.join(filters)
+ filters=' '.join(filters)
)
)
lldp_neighbors_in = {}
- try:
- lldp_neighbors_in = self.device.run_commands(commands)[0].get('lldpNeighbors', {})
- except Exception:
- return {}
+ lldp_neighbors_in = self.device.run_commands(commands)[0].get('lldpNeighbors', {})
for interface in lldp_neighbors_in:
interface_neighbors = lldp_neighbors_in.get(interface).get('lldpNeighborInfo', {})
if not interface_neighbors:
# in case of empty infos
continue
- for neighbor in interface_neighbors: # it is provided a list of neighbors per interface
+
+ # it is provided a list of neighbors per interface
+ for neighbor in interface_neighbors:
if interface not in lldp_neighbors_out.keys():
lldp_neighbors_out[interface] = list()
capabilities = neighbor.get('systemCapabilities')
lldp_neighbors_out[interface].append(
{
- 'parent_interface' : interface, # no parent interfaces
- 'remote_port' : neighbor.get('neighborInterfaceInfo', {}).get('interfaceId', u''),
- 'remote_port_description' : u'',
- 'remote_system_name' : neighbor.get('systemName', u''),
- 'remote_system_description' : neighbor.get('systemDescription', u''),
- 'remote_chassis_id' : neighbor.get('chassisId', u''),
- 'remote_system_capab' : unicode(', '.join(capabilities)),
- 'remote_system_enable_capab' : unicode(', '.join([capability for capability in capabilities.keys() if capabilities[capability]]))
+ 'parent_interface': interface, # no parent interfaces
+ 'remote_port':
+ neighbor.get('neighborInterfaceInfo', {}).get('interfaceId', u''),
+ 'remote_port_description': u'',
+ 'remote_system_name': neighbor.get('systemName', u''),
+ 'remote_system_description': neighbor.get('systemDescription', u''),
+ 'remote_chassis_id': napalm_base.helpers.mac(
+ neighbor.get('chassisId', u'')),
+ 'remote_system_capab': unicode(', '.join(capabilities)),
+ 'remote_system_enable_capab': unicode(', '.join(
+ [capability for capability in capabilities.keys()
+ if capabilities[capability]]))
}
)
return lldp_neighbors_out
- def cli(self, commands = None):
-
+ def cli(self, commands=None):
cli_output = dict()
if type(commands) is not list:
@@ -536,7 +563,8 @@ class EOSDriver(NetworkDriver):
for command in commands:
try:
- cli_output[unicode(command)] = self.device.run_commands([command], encoding='text')[0].get('output')
+ cli_output[unicode(command)] = self.device.run_commands(
+ [command], encoding='text')[0].get('output')
# not quite fair to not exploit rum_commands
# but at least can have better control to point to wrong command in case of failure
except pyeapi.eapilib.CommandError:
@@ -556,7 +584,7 @@ class EOSDriver(NetworkDriver):
return cli_output
def get_bgp_config(self, group='', neighbor=''):
- """Implemantation of NAPALM method get_bgp_config."""
+ """Implementation of NAPALM method get_bgp_config."""
_GROUP_FIELD_MAP_ = {
'type': 'type',
'multipath': 'multipath',
@@ -592,40 +620,40 @@ class EOSDriver(NetworkDriver):
_PROPERTY_TYPE_MAP_ = {
# used to determine the default value
# and cast the values
- 'remote-as' : int,
- 'ebgp-multihop' : int,
- 'local-v4-addr' : unicode,
- 'local-v6-addr' : unicode,
- 'local-as' : int,
- 'remove-private-as' : bool,
- 'next-hop-self' : bool,
- 'description' : unicode,
+ 'remote-as': int,
+ 'ebgp-multihop': int,
+ 'local-v4-addr': unicode,
+ 'local-v6-addr': unicode,
+ 'local-as': int,
+ 'remove-private-as': bool,
+ 'next-hop-self': bool,
+ 'description': unicode,
'route-reflector-client': bool,
- 'password' : unicode,
- 'route-map' : unicode,
- 'apply-groups' : list,
- 'type' : unicode,
- 'import-policy' : unicode,
- 'export-policy' : unicode,
- 'multipath' : bool
+ 'password': unicode,
+ 'route-map': unicode,
+ 'apply-groups': list,
+ 'type': unicode,
+ 'import-policy': unicode,
+ 'export-policy': unicode,
+ 'multipath': bool
}
_DATATYPE_DEFAULT_ = {
- unicode : u'',
- int : 0,
- bool : False,
- list : []
+ unicode: u'',
+ int: 0,
+ bool: False,
+ list: []
}
- def parse_options(options, default_value = False):
+ def parse_options(options, default_value=False):
if not options:
return dict()
config_property = options[0]
- field_name = _PROPERTY_FIELD_MAP_.get(config_property)
- field_type = _PROPERTY_TYPE_MAP_.get(config_property)
- field_value = _DATATYPE_DEFAULT_.get(field_type) # to get the default value
+ field_name = _PROPERTY_FIELD_MAP_.get(config_property)
+ field_type = _PROPERTY_TYPE_MAP_.get(config_property)
+ field_value = _DATATYPE_DEFAULT_.get(field_type) # to get the default value
if not field_type:
# no type specified at all => return empty dictionary
@@ -649,7 +677,7 @@ class EOSDriver(NetworkDriver):
direction = None
if len(options) == 3:
direction = options[2]
- field_value = field_type(options[1]) # the name of the policy
+ field_value = field_type(options[1]) # the name of the policy
elif len(options) == 2:
direction = options[1]
if direction == 'in':
@@ -675,13 +703,13 @@ class EOSDriver(NetworkDriver):
last_peer_group = ''
local_as = 0
for bgp_conf_line in bgp_conf_lines:
- raw_line = bgp_conf_line
default_value = False
bgp_conf_line = bgp_conf_line.strip()
if bgp_conf_line.startswith('router bgp'):
local_as = int(bgp_conf_line.replace('router bgp', '').strip())
continue
- if not (bgp_conf_line.startswith('neighbor') or bgp_conf_line.startswith('no neighbor')):
+ if not (bgp_conf_line.startswith('neighbor') or
+ bgp_conf_line.startswith('no neighbor')):
continue
if bgp_conf_line.startswith('no'):
default_value = True
@@ -718,20 +746,22 @@ class EOSDriver(NetworkDriver):
#
# because the lines are parsed sequentially
# can use the last group detected
- # that way we avoid one more loop to match the neighbors with the group they belong to
+ # that way we avoid one more loop to
+ # match the neighbors with the group they belong to
# directly will apend the neighbor in the neighbor list of the group at the end
if last_peer_group not in bgp_neighbors.keys():
bgp_neighbors[last_peer_group] = dict()
if peer_address not in bgp_neighbors[last_peer_group]:
bgp_neighbors[last_peer_group][peer_address] = dict()
bgp_neighbors[last_peer_group][peer_address].update({
- key:_DATATYPE_DEFAULT_.get(_PROPERTY_TYPE_MAP_.get(prop)) for prop, key in _PEER_FIELD_MAP_.iteritems()
- }) # populating with default values
+ key: _DATATYPE_DEFAULT_.get(_PROPERTY_TYPE_MAP_.get(prop))
+ for prop, key in _PEER_FIELD_MAP_.iteritems()
+ }) # populating with default values
bgp_neighbors[last_peer_group][peer_address].update({
'prefix_limit': {},
- 'local_as' : local_as,
+ 'local_as': local_as,
'authentication_key': u''
- }) # few more default values
+ }) # few more default values
bgp_neighbors[last_peer_group][peer_address].update(
parse_options(options, default_value)
)
@@ -744,13 +774,14 @@ class EOSDriver(NetworkDriver):
if group_name not in bgp_config.keys():
bgp_config[group_name] = dict()
bgp_config[group_name].update({
- key:_DATATYPE_DEFAULT_.get(_PROPERTY_TYPE_MAP_.get(prop)) for prop, key in _GROUP_FIELD_MAP_.iteritems()
+ key: _DATATYPE_DEFAULT_.get(_PROPERTY_TYPE_MAP_.get(prop))
+ for prop, key in _GROUP_FIELD_MAP_.iteritems()
})
bgp_config[group_name].update({
- 'prefix_limit' : {},
- 'neighbors' : {},
- 'local_as' : local_as
- }) # few more default values
+ 'prefix_limit': {},
+ 'neighbors': {},
+ 'local_as': local_as
+ }) # few more default values
bgp_config[group_name].update(
parse_options(options, default_value)
)
@@ -778,37 +809,32 @@ class EOSDriver(NetworkDriver):
return []
for neighbor in ipv4_neighbors:
- interface = unicode(neighbor.get('interface'))
- mac_raw = neighbor.get('hwAddress')
- mac_all = mac_raw.replace('.', '').replace(':', '')
- mac_format = unicode(':'.join([mac_all[i:i+2] for i in range(12)[::2]]))
- ip = unicode(neighbor.get('address'))
- age = float(neighbor.get('age'))
+ interface = unicode(neighbor.get('interface'))
+ mac_raw = neighbor.get('hwAddress')
+ ip = unicode(neighbor.get('address'))
+ age = float(neighbor.get('age'))
arp_table.append(
{
- 'interface' : interface,
- 'mac' : mac_format,
- 'ip' : ip,
- 'age' : age
+ 'interface': interface,
+ 'mac': napalm_base.helpers.mac(mac_raw),
+ 'ip': napalm_base.helpers.ip(ip),
+ 'age': age
}
)
return arp_table
-
- def get_ntp_peers(self):
-
+ def get_ntp_servers(self):
commands = ['show running-config | section ntp']
raw_ntp_config = self.device.run_commands(commands, encoding='text')[0].get('output', '')
ntp_config = napalm_base.helpers.textfsm_extractor(self, 'ntp_peers', raw_ntp_config)
- return {unicode(ntp_peer.get('ntppeer')):{} for ntp_peer in ntp_config if ntp_peer.get('ntppeer', '')}
-
+ return {unicode(ntp_peer.get('ntppeer')): {}
+ for ntp_peer in ntp_config if ntp_peer.get('ntppeer', '')}
def get_ntp_stats(self):
-
ntp_stats = list()
REGEX = (
@@ -823,33 +849,34 @@ class EOSDriver(NetworkDriver):
commands.append('show ntp associations')
# output = self.device.run_commands(commands)
- # pyeapi.eapilib.CommandError: CLI command 2 of 2 'show ntp associations' failed: unconverted command
+ # pyeapi.eapilib.CommandError: CLI command 2 of 2 'show ntp associations'
+ # failed: unconverted command
# JSON output not yet implemented...
- ntp_assoc = self.device.run_commands(commands, encoding = 'text')[0].get('output', '\n\n')
+ ntp_assoc = self.device.run_commands(commands, encoding='text')[0].get('output', '\n\n')
ntp_assoc_lines = ntp_assoc.splitlines()[2:]
for ntp_assoc in ntp_assoc_lines:
line_search = re.search(REGEX, ntp_assoc, re.I)
if not line_search:
- continue # pattern not found
+ continue # pattern not found
line_groups = line_search.groups()
try:
ntp_stats.append({
- 'remote' : unicode(line_groups[1]),
- 'synchronized' : (line_groups[0] == '*'),
- 'referenceid' : unicode(line_groups[2]),
- 'stratum' : int(line_groups[3]),
- 'type' : unicode(line_groups[4]),
- 'when' : unicode(line_groups[5]),
- 'hostpoll' : int(line_groups[6]),
- 'reachability' : int(line_groups[7]),
- 'delay' : float(line_groups[8]),
- 'offset' : float(line_groups[9]),
- 'jitter' : float(line_groups[10])
+ 'remote': unicode(line_groups[1]),
+ 'synchronized': (line_groups[0] == '*'),
+ 'referenceid': unicode(line_groups[2]),
+ 'stratum': int(line_groups[3]),
+ 'type': unicode(line_groups[4]),
+ 'when': unicode(line_groups[5]),
+ 'hostpoll': int(line_groups[6]),
+ 'reachability': int(line_groups[7]),
+ 'delay': float(line_groups[8]),
+ 'offset': float(line_groups[9]),
+ 'jitter': float(line_groups[10])
})
except Exception:
- continue # jump to next line
+ continue # jump to next line
return ntp_stats
@@ -870,7 +897,7 @@ class EOSDriver(NetworkDriver):
ipv4_list = list()
if interface_name not in interfaces_ip.keys():
interfaces_ip[interface_name] = dict()
-
+
if u'ipv4' not in interfaces_ip.get(interface_name):
interfaces_ip[interface_name][u'ipv4'] = dict()
if u'ipv6' not in interfaces_ip.get(interface_name):
@@ -880,15 +907,16 @@ class EOSDriver(NetworkDriver):
if iface_details.get('primaryIp', {}).get('address') != '0.0.0.0':
ipv4_list.append(
{
- 'address' : iface_details.get('primaryIp', {}).get('address'),
- 'masklen' : iface_details.get('primaryIp', {}).get('maskLen')
+ 'address': napalm_base.helpers.ip(iface_details.get(
+ 'primaryIp', {}).get('address')),
+ 'masklen': iface_details.get('primaryIp', {}).get('maskLen')
}
)
for secondary_ip in iface_details.get('secondaryIpsOrderedList', []):
ipv4_list.append(
{
- 'address' : secondary_ip.get('address'),
- 'masklen' : secondary_ip.get('maskLen')
+ 'address': napalm_base.helpers.ip(secondary_ip.get('address')),
+ 'masklen': secondary_ip.get('maskLen')
}
)
@@ -912,16 +940,19 @@ class EOSDriver(NetworkDriver):
ipv6_list.append(
{
- 'address' : interface_details.get('linkLocal', {}).get('address'),
- 'masklen' : int(interface_details.get('linkLocal', {}).get('subnet', '::/0').split('/')[-1])
+ 'address': napalm_base.helpers.convert(
+ napalm_base.helpers.ip, interface_details.get('linkLocal', {})
+ .get('address')),
+ 'masklen': int(
+ interface_details.get('linkLocal', {}).get('subnet', '::/0').split('/')[-1])
# when no link-local set, address will be None and maslken 0
}
)
for address in interface_details.get('addresses'):
ipv6_list.append(
{
- 'address' : address.get('address'),
- 'masklen' : int(address.get('subnet').split('/')[-1])
+ 'address': napalm_base.helpers.ip(address.get('address')),
+ 'masklen': int(address.get('subnet').split('/')[-1])
}
)
for ip in ipv6_list:
@@ -942,35 +973,33 @@ class EOSDriver(NetworkDriver):
mac_entries = []
try:
- mac_entries = self.device.run_commands(commands)[0].get('unicastTable', {}).get('tableEntries', [])
+ mac_entries = self.device.run_commands(commands)[0].get(
+ 'unicastTable', {}).get('tableEntries', [])
except Exception:
return {}
for mac_entry in mac_entries:
- vlan = mac_entry.get('vlanId')
- interface = mac_entry.get('interface')
- mac_raw = mac_entry.get('macAddress')
- mac_str = mac_raw.replace('.', '').replace(':', '')
- mac_format = ':'.join([ mac_str[i:i+2] for i in range(12)[::2] ])
- static = (mac_entry.get('entryType') == 'static')
- last_move = mac_entry.get('lastMove', 0.0)
- moves = mac_entry.get('moves', 0)
+ vlan = mac_entry.get('vlanId')
+ interface = mac_entry.get('interface')
+ mac_raw = mac_entry.get('macAddress')
+ static = (mac_entry.get('entryType') == 'static')
+ last_move = mac_entry.get('lastMove', 0.0)
+ moves = mac_entry.get('moves', 0)
mac_table.append(
{
- 'mac' : mac_format,
- 'interface' : interface,
- 'vlan' : vlan,
- 'active' : True,
- 'static' : static,
- 'moves' : moves,
- 'last_move' : last_move
+ 'mac': napalm_base.helpers.mac(mac_raw),
+ 'interface': interface,
+ 'vlan': vlan,
+ 'active': True,
+ 'static': static,
+ 'moves': moves,
+ 'last_move': last_move
}
)
return mac_table
- def get_route_to(self, destination = '', protocol = ''):
-
+ def get_route_to(self, destination='', protocol=''):
routes = dict()
try:
@@ -981,8 +1010,8 @@ class EOSDriver(NetworkDriver):
return 'Please specify a valid destination!'
command = 'show ip{ipv} route {destination} detail'.format(
- ipv = ipv,
- destination = destination
+ ipv=ipv,
+ destination=destination
)
command_output = self.device.run_commands([command])[0]
@@ -995,57 +1024,59 @@ class EOSDriver(NetworkDriver):
for prefix, route_details in routes_out.iteritems():
if prefix not in routes.keys():
routes[prefix] = list()
- route_protocol = route_details.get('routeType').upper()
- preference = route_details.get('preference')
+ route_protocol = route_details.get('routeType').upper()
+ preference = route_details.get('preference')
route = {
- 'current_active' : False,
- 'last_active' : False,
- 'age' : 0,
- 'next_hop' : u'',
- 'protocol' : route_protocol,
+ 'current_active': False,
+ 'last_active': False,
+ 'age': 0,
+ 'next_hop': u'',
+ 'protocol': route_protocol,
'outgoing_interface': u'',
- 'preference' : preference,
- 'inactive_reason' : u'',
- 'routing_table' : u'default',
- 'selected_next_hop' : False,
+ 'preference': preference,
+ 'inactive_reason': u'',
+ 'routing_table': u'default',
+ 'selected_next_hop': False,
'protocol_attributes': {}
}
if protocol == 'bgp':
- metric = route_details.get('metric')
+ metric = route_details.get('metric')
command = 'show ip{ipv} bgp {destination} detail'.format(
- ipv = ipv,
- destination = prefix
+ ipv=ipv,
+ destination=prefix
)
- default_vrf_details = self.device.run_commands([command])[0].get('vrfs', {}).get('default', {})
- local_as = default_vrf_details.get('asn')
- bgp_routes = default_vrf_details.get('bgpRouteEntries', {}).get(prefix, {}).get('bgpRoutePaths', [])
+ default_vrf_details = self.device.run_commands([command])[0].get(
+ 'vrfs', {}).get('default', {})
+ local_as = default_vrf_details.get('asn')
+ bgp_routes = default_vrf_details.get(
+ 'bgpRouteEntries', {}).get(prefix, {}).get('bgpRoutePaths', [])
for bgp_route_details in bgp_routes:
bgp_route = route.copy()
as_path = bgp_route_details.get('asPathEntry', {}).get('asPath', u'')
remote_as = int(as_path.split()[-1])
- remote_address = bgp_route_details.get('routeDetail', {}).get('peerEntry', {}).get('peerAddr', '')
+ remote_address = napalm_base.helpers.ip(bgp_route_details.get(
+ 'routeDetail', {}).get('peerEntry', {}).get('peerAddr', ''))
local_preference = bgp_route_details.get('localPreference')
- next_hop = bgp_route_details.get('nextHop')
+ next_hop = napalm_base.helpers.ip(bgp_route_details.get('nextHop'))
active_route = bgp_route_details.get('routeType', {}).get('active', False)
- last_active = active_route # should find smth better
+ last_active = active_route # should find smth better
communities = bgp_route_details.get('routeDetail', {}).get('communityList', [])
preference2 = bgp_route_details.get('weight')
- selected_next_hop = active_route
bgp_route.update({
- 'current_active' : active_route,
- 'last_active' : last_active,
- 'next_hop' : next_hop,
- 'selected_next_hop' : active_route,
+ 'current_active': active_route,
+ 'last_active': last_active,
+ 'next_hop': next_hop,
+ 'selected_next_hop': active_route,
'protocol_attributes': {
- 'metric' : metric,
- 'as_path' : as_path,
- 'local_preference' : local_preference,
- 'local_as' : local_as,
- 'remote_as' : remote_as,
- 'remote_address' : remote_address,
- 'preference2' : preference2,
- 'communities' : communities
+ 'metric': metric,
+ 'as_path': as_path,
+ 'local_preference': local_preference,
+ 'local_as': local_as,
+ 'remote_as': remote_as,
+ 'remote_address': remote_address,
+ 'preference2': preference2,
+ 'communities': communities
}
})
routes[prefix].append(bgp_route)
@@ -1054,7 +1085,7 @@ class EOSDriver(NetworkDriver):
route_next_hop = route.copy()
route_next_hop.update(
{
- 'next_hop' : next_hop.get('nexthopAddr'),
+ 'next_hop': napalm_base.helpers.ip(next_hop.get('nexthopAddr')),
'outgoing_interface': next_hop.get('interface')
}
)
@@ -1076,10 +1107,10 @@ class EOSDriver(NetworkDriver):
return snmp_information
snmp_information = {
- 'contact' : unicode(snmp_config[0].get('contact', '')),
- 'location' : unicode(snmp_config[0].get('location', '')),
+ 'contact': unicode(snmp_config[0].get('contact', '')),
+ 'location': unicode(snmp_config[0].get('location', '')),
'chassis_id': unicode(snmp_config[0].get('chassis_id', '')),
- 'community' : {}
+ 'community': {}
}
for snmp_entry in snmp_config:
@@ -1097,10 +1128,10 @@ class EOSDriver(NetworkDriver):
def _sshkey_type(sshkey):
if sshkey.startswith('ssh-rsa'):
- return 'ssh_rsa', sshkey
+ return u'ssh_rsa', unicode(sshkey)
elif sshkey.startswith('ssh-dss'):
- return 'ssh_dsa', sshkey
- return 'ssh_rsa', ''
+ return u'ssh_dsa', unicode(sshkey)
+ return u'ssh_rsa', u''
users = dict()
@@ -1113,7 +1144,7 @@ class EOSDriver(NetworkDriver):
sshkey_type, sshkey_value = _sshkey_type(sshkey_value)
user_details.update({
'level': user_details.pop('privLevel', 0),
- 'password': user_details.pop('secret', ''),
+ 'password': unicode(user_details.pop('secret', '')),
'sshkeys': [sshkey_value]
})
users[user] = user_details
@@ -1172,7 +1203,8 @@ class EOSDriver(NetworkDriver):
)
try:
- traceroute_raw_output = self.device.run_commands([command], encoding='text')[0].get('output')
+ traceroute_raw_output = self.device.run_commands(
+ [command], encoding='text')[0].get('output')
except CommandErrorException:
return {'error': 'Cannot execute traceroute on the device: {}'.format(command)}
@@ -1187,10 +1219,13 @@ class EOSDriver(NetworkDriver):
hop_index = int(hop_details[0])
previous_probe_host_name = '*'
previous_probe_ip_address = '*'
- traceroute_result['success'][hop_index] = {'probes':{}}
+ traceroute_result['success'][hop_index] = {'probes': {}}
for probe_index in range(probes):
host_name = hop_details[3+probe_index*5]
- ip_address = hop_details[4+probe_index*5]
+ hop_addr = hop_details[4+probe_index*5]
+ ip_address = napalm_base.helpers.convert(
+ napalm_base.helpers.ip, hop_addr, hop_addr
+ )
rtt = hop_details[5+probe_index*5]
if rtt:
rtt = float(rtt)
@@ -1212,3 +1247,318 @@ class EOSDriver(NetworkDriver):
previous_probe_ip_address = ip_address
return traceroute_result
+
+ def get_bgp_neighbors_detail(self, neighbor_address=''):
+ """Implementation of get_bgp_neighbors_detail"""
+ def _parse_per_peer_bgp_detail(peer_output):
+ """This function parses the raw data per peer and returns a
+ json structure per peer.
+ """
+
+ int_fields = ['local_as', 'remote_as',
... 403 lines suppressed ...
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/python-modules/packages/napalm-eos.git
More information about the Python-modules-commits
mailing list