Skip to content
This repository has been archived by the owner on Sep 17, 2019. It is now read-only.

Commit

Permalink
Merge pull request #125 from napalm-automation/develop
Browse files Browse the repository at this point in the history
Release 0.5.0
  • Loading branch information
mirceaulinic authored Jun 5, 2017
2 parents 36f3783 + 95967c2 commit 33f697a
Show file tree
Hide file tree
Showing 6 changed files with 74 additions and 15 deletions.
82 changes: 70 additions & 12 deletions napalm_iosxr/iosxr.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
# import stdlib
import re
import copy
import socket
from collections import defaultdict

# import third party lib
Expand All @@ -26,6 +27,8 @@
from netaddr import IPAddress # needed for traceroute, to check IP version
from netaddr.core import AddrFormatError

from netmiko import __version__ as netmiko_version

from pyIOSXR import IOSXR
from pyIOSXR.exceptions import ConnectError
from pyIOSXR.exceptions import TimeoutError
Expand Down Expand Up @@ -57,13 +60,41 @@ def __init__(self, hostname, username, password, timeout=60, optional_args=None)
if optional_args is None:
optional_args = {}
self.port = optional_args.get('port', 22)
self.lock_on_connect = optional_args.get('config_lock', True)
self.lock_on_connect = optional_args.get('config_lock', False)
# Netmiko possible arguments
netmiko_argument_map = {
'keepalive': 30,
'verbose': False,
'global_delay_factor': 1,
'use_keys': False,
'key_file': None,
'ssh_strict': False,
'system_host_keys': False,
'alt_host_keys': False,
'alt_key_file': '',
'ssh_config_file': None
}
fields = netmiko_version.split('.')
fields = [int(x) for x in fields]
maj_ver, min_ver, bug_fix = fields
if maj_ver >= 2:
netmiko_argument_map['allow_agent'] = False
elif maj_ver == 1 and min_ver >= 1:
netmiko_argument_map['allow_agent'] = False
# Build dict of any optional Netmiko args
self.netmiko_optional_args = {}
for k, v in netmiko_argument_map.items():
try:
self.netmiko_optional_args[k] = optional_args[k]
except KeyError:
pass
self.device = IOSXR(hostname,
username,
password,
timeout=timeout,
port=self.port,
lock=self.lock_on_connect)
lock=self.lock_on_connect,
**self.netmiko_optional_args)

def open(self):
try:
Expand All @@ -75,6 +106,18 @@ def close(self):
self.device.close()

def is_alive(self):
null = chr(0)
try:
# Try sending ASCII null byte to maintain
# the connection alive
self.device.device.send_command(null)
except (socket.error, EOFError):
# If unable to send, we can tell for sure
# that the connection is unusable,
# hence return False.
return {
'is_alive': False
}
return {
'is_alive': self.device.device.remote_conn.transport.is_active()
}
Expand Down Expand Up @@ -1012,7 +1055,7 @@ def get_bgp_neighbors_detail(self, neighbor_address=''):
'advertised_prefix_count': advertised_prefix_count,
'flap_count': flap_count
})

bgp_neighbors_detail['global'] = bgp_neighbors_detail.pop('default')
return bgp_neighbors_detail

def get_arp_table(self):
Expand Down Expand Up @@ -1240,15 +1283,30 @@ def get_route_to(self, destination='', protocol=''):
prefix_tag = '<PrefixLength>{prefix_length}</PrefixLength>'.format(
prefix_length=dest_split[1])

route_info_rpc_command = '<Get><Operational><RIB><VRFTable><VRF><Naming><VRFName>default\
</VRFName></Naming><AFTable><AF><Naming><AFName>IPv4</AFName></Naming><SAFTable><SAF>\
<Naming><SAFName>Unicast</SAFName></Naming><IP_RIBRouteTable><IP_RIBRoute><Naming>\
<RouteTableName>default</RouteTableName></Naming><RouteTable><Route><Naming><Address>\
{network}</Address>{prefix}</Naming></Route></RouteTable></IP_RIBRoute></IP_RIBRouteTable>\
</SAF></SAFTable></AF></AFTable></VRF></VRFTable></RIB></Operational></Get>'.format(
network=network,
prefix=prefix_tag
)
ipv = 4
try:
ipv = IPAddress(network).version
except AddrFormatError:
raise TypeError('Wrong destination IP Address!')

if ipv == 6:
route_info_rpc_command = '<Get><Operational><IPV6_RIB><VRFTable><VRF><Naming><VRFName>\
default</VRFName></Naming><AFTable><AF><Naming><AFName>IPv6</AFName></Naming><SAFTable>\
<SAF><Naming><SAFName>Unicast</SAFName></Naming><IP_RIBRouteTable><IP_RIBRoute><Naming>\
<RouteTableName>default</RouteTableName></Naming><RouteTable><Route><Naming><Address>\
{network}</Address>{prefix}</Naming></Route></RouteTable></IP_RIBRoute>\
</IP_RIBRouteTable></SAF></SAFTable></AF></AFTable></VRF></VRFTable></IPV6_RIB>\
</Operational></Get>'.format(network=network, prefix=prefix_tag)
else:
route_info_rpc_command = '<Get><Operational><RIB><VRFTable><VRF><Naming><VRFName>default\
</VRFName></Naming><AFTable><AF><Naming><AFName>IPv4</AFName></Naming><SAFTable><SAF>\
<Naming><SAFName>Unicast</SAFName></Naming><IP_RIBRouteTable><IP_RIBRoute><Naming>\
<RouteTableName>default</RouteTableName></Naming><RouteTable><Route><Naming><Address>\
{network}</Address>{prefix}</Naming></Route></RouteTable></IP_RIBRoute></IP_RIBRouteTable>\
</SAF></SAFTable></AF></AFTable></VRF></VRFTable></RIB></Operational></Get>'.format(
network=network,
prefix=prefix_tag
)

routes_tree = ETREE.fromstring(self.device.make_rpc_call(route_info_rpc_command))

Expand Down
2 changes: 1 addition & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
napalm-base>=0.18.0
pyIOSXR >= 0.20
pyIOSXR>=0.50
netaddr
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

setup(
name="napalm-iosxr",
version="0.4.8",
version="0.5.0",
packages=find_packages(),
author="David Barroso, Mircea Ulinic",
author_email="[email protected], [email protected]",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"default": {
"global": {
"7777": [{
"suppress_4byte_as": false,
"local_as_prepend": true,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<Response MajorVersion="1" MinorVersion="0"><Get><Operational><IPV6_RIB MajorVersion="4" MinorVersion="0"><VRFTable><VRF><Naming><VRFName>default</VRFName></Naming><AFTable><AF><Naming><AFName>IPv6</AFName></Naming><SAFTable><SAF><Naming><SAFName>Unicast</SAFName></Naming><IP_RIBRouteTable><IP_RIBRoute><Naming><RouteTableName>default</RouteTableName></Naming><RouteTable><Route><Naming><Address>dead:beef:210:210::53</Address></Naming></Route></RouteTable></IP_RIBRoute></IP_RIBRouteTable></SAF></SAFTable></AF></AFTable></VRF></VRFTable></IPV6_RIB></Operational></Get><ResultSummary ErrorCount="0"/></Response>

0 comments on commit 33f697a

Please sign in to comment.