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

Commit 8f644bb

Browse files
authored
Merge pull request #251 from napalm-automation/develop
Preparing napalm-base 0.24.0
2 parents 6f37907 + 30f3d66 commit 8f644bb

File tree

18 files changed

+206
-40
lines changed

18 files changed

+206
-40
lines changed

.travis.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,14 @@ language: python
22

33
python:
44
- 2.7
5-
- 3.4
5+
- 3.4
6+
- 3.5
67

78
install:
89
- pip install .
910
- pip install -r requirements-dev.txt
1011
- pip install -r requirements.txt
11-
- if [[ $TRAVIS_PYTHON_VERSION == 2.7 ]]; then pip install -r test/unit/requirements.txt; fi
12-
- if [[ $TRAVIS_PYTHON_VERSION == 3.4 ]]; then pip install -r test/unit/requirements_py3.txt; fi
12+
- pip install -r test/unit/requirements.txt
1313

1414
deploy:
1515
provider: pypi

napalm_base/exceptions.py

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,40 @@ class ModuleImportError(Exception):
2222

2323

2424
class ConnectionException(Exception):
25+
'''
26+
Unable to connect to the network device.
27+
'''
28+
pass
29+
30+
31+
class ConnectAuthError(ConnectionException):
32+
'''
33+
Unable to connect to the network device
34+
due to invalid credentials.
35+
'''
36+
pass
37+
38+
39+
class ConnectTimeoutError(ConnectionException):
40+
'''
41+
Exception raised when the connection to the
42+
network device takes too long.
43+
This may be avoided by adjusting the `timeout`
44+
argument.
45+
'''
46+
pass
47+
48+
49+
class ConnectionClosedException(ConnectionException):
50+
'''
51+
The network device closed the connection.
52+
Raised whenever we try to execute a certain
53+
function, but we detect that the connection
54+
is not usable anymore. This can happen for
55+
various reasons: the network device terminates the
56+
session or it is dropped by a firewall or
57+
the server.
58+
'''
2559
pass
2660

2761

@@ -33,6 +67,28 @@ class MergeConfigException(Exception):
3367
pass
3468

3569

70+
class CommitError(Exception):
71+
'''
72+
Raised when unable to commit the candidate config
73+
into the running config.
74+
'''
75+
pass
76+
77+
78+
class LockError(Exception):
79+
'''
80+
Unable to lock the candidate config.
81+
'''
82+
pass
83+
84+
85+
class UnlockError(Exception):
86+
'''
87+
Unable to unlock the candidate config.
88+
'''
89+
pass
90+
91+
3692
class SessionLockedException(Exception):
3793
pass
3894

napalm_base/helpers.py

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -219,16 +219,19 @@ def mac(raw):
219219
return py23_compat.text_type(EUI(raw, dialect=_MACFormat))
220220

221221

222-
def ip(addr):
222+
def ip(addr, version=None):
223223
"""
224-
Converts a raw string to a valid IP address.
224+
Converts a raw string to a valid IP address. Optional version argument will detect that \
225+
object matches specified version.
225226
226227
Motivation: the groups of the IP addreses may contain leading zeros. IPv6 addresses can \
227228
contain sometimes uppercase characters. E.g.: 2001:0dB8:85a3:0000:0000:8A2e:0370:7334 has \
228229
the same logical value as 2001:db8:85a3::8a2e:370:7334. However, their values as strings are \
229230
not the same.
230231
231232
:param raw: the raw string containing the value of the IP Address
233+
:param version: (optional) insist on a specific IP address version.
234+
:type version: int.
232235
:return: a string containing the IP Address in a standard format (no leading zeros, \
233236
zeros-grouping, lowercase)
234237
@@ -239,4 +242,16 @@ def ip(addr):
239242
>>> ip('2001:0dB8:85a3:0000:0000:8A2e:0370:7334')
240243
u'2001:db8:85a3::8a2e:370:7334'
241244
"""
242-
return py23_compat.text_type(IPAddress(addr))
245+
addr_obj = IPAddress(addr)
246+
if version and addr_obj.version != version:
247+
raise ValueError("{} is not an ipv{} address".format(addr, version))
248+
return py23_compat.text_type(addr_obj)
249+
250+
251+
def as_number(as_number):
252+
"""Convert AS Number to standardized asplain notation as an integer."""
253+
if '.' in as_number:
254+
big, little = as_number.split('.')
255+
return (int(big) << 16) + int(little)
256+
else:
257+
return int(as_number)

napalm_base/validate.py

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -121,8 +121,12 @@ def _compare_getter(src, dst):
121121
return _compare_getter_dict(src, dst, mode)
122122
else:
123123
if isinstance(src, py23_compat.string_types):
124-
m = re.search(src, py23_compat.text_type(dst))
125-
return m is not None
124+
if src.startswith('<') or src.startswith('>'):
125+
cmp_result = compare_numeric(src, dst)
126+
return cmp_result
127+
else:
128+
m = re.search(src, py23_compat.text_type(dst))
129+
return m is not None
126130
elif(type(src) == type(dst) == list):
127131
pairs = zip(src, dst)
128132
diff_lists = [[(k, x[k], y[k])
@@ -133,6 +137,14 @@ def _compare_getter(src, dst):
133137
return src == dst
134138

135139

140+
def compare_numeric(src_num, dst_num):
141+
"""Compare numerical values. You can use '<%d','>%d'."""
142+
complies = eval(str(dst_num)+src_num)
143+
if not isinstance(complies, bool):
144+
return False
145+
return complies
146+
147+
136148
def empty_tree(input_list):
137149
"""Recursively iterate through values in nested lists."""
138150
for item in input_list:

requirements-dev.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,5 @@ pytest-json
44
pytest-pythonpath
55
pylama
66
flake8-import-order
7+
nose
78
-r requirements.txt

setup.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,10 @@
1212

1313
setup(
1414
name="napalm-base",
15-
version='0.23.3',
15+
version='0.24.0',
1616
packages=find_packages(),
17-
author="David Barroso",
18-
author_email="[email protected]",
17+
author="David Barroso, Kirk Byers, Mircea Ulinic",
18+
1919
description="Network Automation and Programmability Abstraction Layer with Multivendor support",
2020
classifiers=[
2121
'Topic :: Utilities',

test/unit/TestGetNetworkDriver.py

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,22 +8,13 @@
88
from napalm_base import get_network_driver
99
from napalm_base.base import NetworkDriver
1010
from napalm_base.exceptions import ModuleImportError
11-
from napalm_base.utils.py23_compat import PY2, PY3
1211

1312

1413
@ddt
1514
class TestGetNetworkDriver(unittest.TestCase):
1615
"""Test the method get_network_driver."""
17-
18-
drivers_common = ('eos', 'ios', 'iosxr', 'IOS-XR', 'junos', 'ros', 'nxos',
19-
'pluribus', 'panos', 'vyos')
20-
drivers_py2_only = ('fortios', )
21-
if PY2:
22-
# All drivers support python2
23-
network_drivers = drivers_common + drivers_py2_only
24-
elif PY3:
25-
# Drivers that support python2 and python3
26-
network_drivers = drivers_common
16+
network_drivers = ('eos', 'fortios', 'ios', 'iosxr', 'IOS-XR', 'junos', 'ros', 'nxos',
17+
'pluribus', 'panos', 'vyos')
2718

2819
@data(*network_drivers)
2920
def test_get_network_driver(self, driver):

test/unit/TestHelpers.py

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -284,24 +284,38 @@ def test_mac(self):
284284
self.assertEqual(napalm_base.helpers.mac('123.4567.89ab'), '01:23:45:67:89:AB')
285285

286286
def test_ip(self):
287-
288287
"""
289288
Tests the helper function ```ip```:
290289
291290
* check if raises AddrFormatError when invalid IP address
291+
* check if calls using incorrect version raises ValueError
292292
* check if IPv6 address returned as expected
293293
"""
294294

295295
self.assertTrue(HAS_NETADDR)
296296

297297
# test that raises AddrFormatError when wrong format
298298
self.assertRaises(AddrFormatError, napalm_base.helpers.ip, 'fake')
299+
self.assertRaises(ValueError, napalm_base.helpers.ip, '2001:db8:85a3::8a2e:370:7334',
300+
version=4)
301+
self.assertRaises(ValueError, napalm_base.helpers.ip, '192.168.17.1',
302+
version=6)
299303
self.assertEqual(
300-
napalm_base.helpers.ip(
301-
'2001:0dB8:85a3:0000:0000:8A2e:0370:7334'
302-
),
304+
napalm_base.helpers.ip('2001:0dB8:85a3:0000:0000:8A2e:0370:7334'),
303305
'2001:db8:85a3::8a2e:370:7334'
304306
)
307+
self.assertEqual(
308+
napalm_base.helpers.ip('2001:0DB8::0003', version=6),
309+
'2001:db8::3'
310+
)
311+
312+
def test_as_number(self):
313+
"""Test the as_number helper function."""
314+
self.assertEqual(napalm_base.helpers.as_number('64001'), 64001)
315+
self.assertEqual(napalm_base.helpers.as_number('1.0'), 65536)
316+
self.assertEqual(napalm_base.helpers.as_number('1.100'), 65636)
317+
self.assertEqual(napalm_base.helpers.as_number('1.65535'), 131071)
318+
self.assertEqual(napalm_base.helpers.as_number('65535.65535'), 4294967295)
305319

306320
def test_convert_uptime_string_seconds(self):
307321
"""

test/unit/requirements.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
ddt
2+
lxml
23
napalm-eos
34
napalm-fortios
45
napalm-ios
56
napalm-iosxr
67
napalm-junos
78
napalm-nxos
8-
napalm-pluribus
99
napalm-panos
10+
napalm-pluribus
1011
napalm-ros
1112
napalm-vyos

test/unit/requirements_py3.txt

Lines changed: 0 additions & 11 deletions
This file was deleted.

0 commit comments

Comments
 (0)