Skip to content

Commit a65fc25

Browse files
authored
Preparing release 2.5.0 (#1065)
* namespace fix for napalm cli (#950) * Fix broken get_bgp_neighbors when 6PE configured on eos (#945) * fix _RE_BGP_PREFIX and NEIGHBOR_FILTER for 6PE into eos * add testcase for 6PE version * Renamed testcase mocked file for regexp syntax change * If parent_table None call exception (#939) Hi, i have this situation when ipv6 is turned off: $ napalm --user oxi --password gdfw23 --vendor nxos 10.143.36.8 call get_interfaces_ip 2019-03-07 15:08:10,226 - napalm - ERROR - method - Failed: 'NoneType' object has no attribute 'get' ================= Traceback ================= Traceback (most recent call last): File "/opt/py3.6/bin/napalm", line 10, in <module> sys.exit(main()) File "/opt/py3.6/lib/python3.6/site-packages/napalm/base/clitools/cl_napalm.py", line 309, in main run_tests(args) File "/opt/py3.6/lib/python3.6/site-packages/napalm/base/clitools/cl_napalm.py", line 292, in run_tests call_getter(device, args.method, **method_kwargs) File "/opt/py3.6/lib/python3.6/site-packages/napalm/base/clitools/cl_napalm.py", line 31, in wrapper r = func(*args, **kwargs) File "/opt/py3.6/lib/python3.6/site-packages/napalm/base/clitools/cl_napalm.py", line 256, in call_getter r = func(**kwargs) File "/opt/py3.6/lib/python3.6/site-packages/napalm/nxos/nxos.py", line 1091, in get_interfaces_ip ipv6_command, "TABLE_intf", "ROW_intf" File "/opt/py3.6/lib/python3.6/site-packages/napalm/nxos/nxos.py", line 721, in _get_command_table return self._get_reply_table(json_output, table_name, row_name) File "/opt/py3.6/lib/python3.6/site-packages/napalm/nxos/nxos.py", line 717, in _get_reply_table return self._get_table_rows(result, table_name, row_name) File "/opt/py3.6/lib/python3.6/site-packages/napalm/nxos/nxos.py", line 706, in _get_table_rows _table = parent_table.get(table_name) AttributeError: 'NoneType' object has no attribute 'get' * Remove extensive argument from junos_iface_table (#929) Fixes #928 * Add GitHub issue template, as we used to have before (#961) When we used to maintain separare NAPALM drivers, we had an issue template looking like this: napalm-automation/napalm-junos@110fec4#diff-faa36bc26a21ed93c8de974753b71507. I was looking today through the issues we currently have open, and I found some of them a bit chaotic, and hard to understand the context / environment the user runs. Additionally, some, e.g., #960, is really hard to follow, and I've included a note to invite the user to check the HitGub markdown manual. * NXOS_SSH get_route_to (updated) (#914) * Add MTU support to get_interface (#940) * Feature/ios get bgp config (#897) * support n9k ipv6 ints for interfaces_ip getter (#969) * support catalyst vss for mac_address getter (#968) * support getting auto-negotiated speed on junos (#967) * [IOS] Raise exception if BGP neighbor info requested and BGP not running (#970) * Implement nxos_ssh get_environment (#973) * Switch Docker image to Python 3 and reduce the number of layers and size (#980) * Better handling of connection closing upon exceptions in __enter__ (#994) * Fix incorrect get_interfaces_ip parsing on n9k with IPv6 addresses (#997) * Modernize docs for FreeBSD installation (#993) * Fix nxos and nxos_ssh hostname change handling (#999) * Update link location in the docs (#1002) * Hostname fixes for NXOS and IOS (#1007) * Clean up the documentation contribution section (#1004) * <exception>.message is no longer a thing in Python3 (#1016) * Added option to show run all (#1029) * Update ISSUE_TEMPLATE Removing the space between the brackets, as it seems like it's confusing the users. * junos add optional arg for DB config selection (#1035) * fix junos issue #1028 (#1032) * fix junos issue #1028 * junos add test case for get_network_instances * Incorrectly taken serial number in NXOS. (#1025) * The serial number is taken incorrectly, in particular, the "Processor Board ID" is displayed, and you need a Chassis -> serialnum: * Additional safety net for the lack of a serial number in the output. * black test * mov function _get_table_rows, _get_reply_table and _get_command_table from class NXOSDriver to NXOSDriverBase, because used in NXOSSSHDriver. * Added verification and conversion from string to json * Implemented lock_disable for EOS based on Junos. (#1042) To fix(?) issue #1041 - #1041 On branch eos-lock-disable-flag Changes to be committed: modified: napalm/eos/eos.py * #1025 Work around NXAPI double quoting (#1048) * #1025 Work around NXAPI double quoting The NXAPI on the Nexus 9000 platform seems to be double-quoting the name of inventory items. Amend the check for the inventory item name to take this into account. * the output of the N9000 has extra quotes: show inventory | json {"TABLE_inv": {"ROW_inv": [{"name": "\"Chassis\"", "desc": "\"Nexus9000 C92160YC-X chassis\"",....... * #1046 Use new dictionary key to fetch OS version (#1047) Some Cisco Nexus equipment doesn’t have `sys_ver_str`, but has `rr_sys_ver` instead. Use this as a backup. * Add get_environment support for NXOS driver (#1054) * napalm.nxos.traceroute - VRF traces and handle AS in hops (#989) * Adding traceroute from a specific VRF * Combination of source and vrf command * On some devices running BGP, an AS number will appear after the IP address of the hop * E261 at least two spaces before inline comment [pep8] * Fix extra line in show ip int brief on IOS (#986) * keep nxos consistent with ios for rollback of failed merge (#860) * IOS: add support for VRF for get_arp_table func (#937) Simply takes into account the vrf function arg and exec the expected ios command. * ios get_bgp_neighbors vrf and safi aware (#768) * get_bgp_neighbors vrf support * afi string contains afi modifier * mocked data, minor changes * afi string with afi modifier * supported afis * mocked data * comments * typo * show arp vrf ios test * black reformated * Check if temperature sensor on Cisco device is not supported (#1055) * Check if temperature sensor on Cisco device is not supported Some older Cisco devices like models from the 2960 platform have no temperature sensor built-in. In that case the get_environment function will throw on exception. That case will now be handeled. * Correct if check * Fixes get_environment memory collection on ios-xe devices (#1053) * fixes issue #1052 * add tests for get_environment on ios-xe devices * Pin PyEZ to 2.2.1 (#1061) * get_route_to implementation for IOS (#750) * 1st functional config * bgp protocol attributes added * linting, minor changes * test_get_route_to mocked_data * linting errors fix * comments, minor changes in bgp procesing * bgp processing separated * bgp support 7200 old * new bgp processing * mocked data global routing table * comments, _get_vrfs update * mocked data c7200 * bug in regex * connected, next-hop regex changed,.. * community + ext.community, comments * linting * RE_RDB1 regex fixed * asr_pe test * typo * typo * typo in mocked data - vrf Test -> TEST * longer parameter added (PR735) * rollback to pass test_method_signatures ... * bgp_time_conversion duplicity fixed * community regex fixed * code optimization * module constant, variables renaming * black reformated * sh arp vrf test * When asPathType is Internal (IBGP), as_path is empty and the remote-as is the local_as (#1064) * Pin Netmiko to version 2.4.2 (#1066) * Release 2.5.0 (#1063)
1 parent 2332653 commit a65fc25

File tree

157 files changed

+28366
-2286
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

157 files changed

+28366
-2286
lines changed

Diff for: .github/ISSUE_TEMPLATE

+36
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
### Description of Issue/Question
2+
3+
*Note*: Please check https://guides.github.com/features/mastering-markdown/
4+
to see how to properly format your request.
5+
6+
### Did you follow the steps from https://github.com/napalm-automation/napalm#faq
7+
(Place an ``x`` between the square brackets where applicable)
8+
9+
- [] Yes
10+
- [] No
11+
12+
13+
### Setup
14+
15+
### napalm version
16+
(Paste verbatim output from `pip freeze | grep napalm` between quotes below)
17+
18+
```
19+
20+
```
21+
22+
### Network operating system version
23+
(Paste verbatim output from `show version` - or equivalent - between quotes below)
24+
25+
```
26+
27+
```
28+
29+
### Steps to Reproduce the Issue
30+
31+
### Error Traceback
32+
(Paste the complete traceback of the exception between quotes below)
33+
34+
```
35+
36+
```

Diff for: Dockerfile

+7-12
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,10 @@
1-
FROM debian:stretch
2-
3-
## Install min deps
4-
RUN apt-get update
1+
FROM python:3.6-slim-stretch
52

63
COPY ./ /var/cache/napalm/
74

8-
## Install NAPALM & underlying libraries dependencies
9-
RUN apt-get install -y python-cffi python-dev libxslt1-dev libssl-dev libffi-dev \
10-
&& apt-get install -y python-pip \
11-
&& pip install -U cffi \
12-
&& pip install -U cryptography \
13-
&& pip install /var/cache/napalm/
14-
15-
RUN rm -rf /var/lib/apt/lists/*
5+
RUN apt-get update \
6+
&& apt-get install -y python-dev python-cffi libxslt1-dev libssl-dev libffi-dev \
7+
&& apt-get autoremove \
8+
&& rm -rf /var/lib/apt/lists/* \
9+
&& pip --no-cache-dir install -U cffi cryptography /var/cache/napalm/ \
10+
&& rm -rf /var/cache/napalm/

Diff for: docs/contributing/index.rst

+24-1
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,27 @@ If you found a bug and know how to fix just contribute the bugfix. It might be i
4444
Documentation
4545
-------------
4646

47-
Just do it! :)
47+
The documentation is built using `Sphinx`_ and hosted on Read the Docs. The docs
48+
are kept in the ``docs/`` directory at the top of the source tree.
49+
50+
To make changes, it is preferable to set up a `python virtual environment`_
51+
called ``env`` and activate it.
52+
53+
Next, install the documentation dependencies using ``pip``:
54+
55+
.. code:: console
56+
57+
pip install -r docs/requirements.txt
58+
59+
Make your changes and then check them for correctness by building them locally:
60+
61+
.. code:: console
62+
63+
# in the docs directory
64+
make html
65+
66+
.. tip:: If it is a simple change to a single page, you can use the "Edit on
67+
GitHub" button in the upper right hand corner of the page in question.
4868

4969
Proposing a new driver
5070
----------------------
@@ -58,3 +78,6 @@ Please check :ref:`contributing-drivers` to understand the process.
5878

5979
core
6080
drivers
81+
82+
.. _python virtual environment: https://packaging.python.org/guides/installing-using-pip-and-virtualenv/
83+
.. _Sphinx: http://www.sphinx-doc.org/en/master/

Diff for: docs/installation/index.rst

+19
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,25 @@ You can install napalm with pip:
1414
That will install all the drivers currently available.
1515

1616

17+
OS Package Managers
18+
-------------------
19+
20+
Some execution environments offer napalm through a system-level package manager. Installing with pip outside of a user profile or virtualenv/venv is inadvisable in these cases.
21+
22+
FreeBSD
23+
~~~~~~~
24+
25+
.. code-block:: bash
26+
27+
pkg install net-mgmt/py-napalm
28+
29+
This will install napalm and all drivers and dependencies for the default version(s) of python. To install for a specific version, python X.Y, if supported:
30+
31+
.. code-block:: bash
32+
33+
pkg install pyXY-napalm
34+
35+
1736
Dependencies
1837
------------
1938

Diff for: docs/installation/ios.rst

-8
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,3 @@ RedHat and CentOS
1515
.. code-block:: bash
1616
1717
sudo yum install -y python-pip gcc openssl openssl-devel libffi-devel python-devel
18-
19-
20-
FreeBSD
21-
-------
22-
23-
.. code-block:: bash
24-
25-
sudo pkg_add -r py27-pip

Diff for: docs/installation/iosxr.rst

-8
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,3 @@ RedHat and CentOS
1515
.. code-block:: bash
1616
1717
sudo yum install -y python-pip gcc openssl openssl-devel libffi-devel python-devel
18-
19-
20-
FreeBSD
21-
-------
22-
23-
.. code-block:: bash
24-
25-
sudo pkg_add -r py27-pip

Diff for: docs/installation/junos.rst

-7
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,3 @@ RedHat and CentOS
1515
.. code-block:: bash
1616
1717
sudo yum install -y python-pip python-devel libxml2-devel libxslt-devel gcc openssl openssl-devel libffi-devel
18-
19-
FreeBSD
20-
-------
21-
22-
.. code-block:: bash
23-
24-
sudo pkg_add -r py27-pip libxml2 libxslt

Diff for: docs/validate/index.rst

+1-1
Original file line numberDiff line numberDiff line change
@@ -263,7 +263,7 @@ CLI & Ansible
263263
If you prefer, you can also make use of the validate functionality via the CLI with the command ``cl_napalm_validate`` or with ansible plugin. You can find more information about them here:
264264

265265
* CLI - https://github.com/napalm-automation/napalm/pull/168
266-
* Ansible - https://github.com/napalm-automation/napalm-ansible/blob/master/library/napalm_validate.py
266+
* Ansible - https://github.com/napalm-automation/napalm-ansible/blob/master/napalm_ansible/modules/napalm_validate.py
267267

268268

269269
Why this and what's next

Diff for: napalm/base/base.py

+24-8
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,16 @@
1616
from __future__ import print_function
1717
from __future__ import unicode_literals
1818

19+
import sys
20+
21+
from netmiko import ConnectHandler, NetMikoTimeoutException
22+
1923
# local modules
2024
import napalm.base.exceptions
21-
from napalm.base.exceptions import ConnectionException
2225
import napalm.base.helpers
2326
from napalm.base import constants as c
2427
from napalm.base import validate
25-
26-
from netmiko import ConnectHandler, NetMikoTimeoutException
28+
from napalm.base.exceptions import ConnectionException
2729

2830

2931
class NetworkDriver(object):
@@ -44,8 +46,15 @@ def __init__(self, hostname, username, password, timeout=60, optional_args=None)
4446
raise NotImplementedError
4547

4648
def __enter__(self):
47-
self.open()
48-
return self
49+
try:
50+
self.open()
51+
return self
52+
except: # noqa: E722
53+
# Swallow exception if __exit__ returns a True value
54+
if self.__exit__(*sys.exc_info()):
55+
pass
56+
else:
57+
raise
4958

5059
def __exit__(self, exc_type, exc_value, exc_traceback):
5160
self.close()
@@ -95,8 +104,9 @@ def _netmiko_open(self, device_type, netmiko_optional_args=None):
95104

96105
def _netmiko_close(self):
97106
"""Standardized method of closing a Netmiko connection."""
98-
self.device.disconnect()
99-
self._netmiko_device = None
107+
if getattr(self, "_netmiko_device", None):
108+
self._netmiko_device.disconnect()
109+
self._netmiko_device = None
100110
self.device = None
101111

102112
def open(self):
@@ -268,6 +278,7 @@ def get_interfaces(self):
268278
* description (string)
269279
* last_flapped (float in seconds)
270280
* speed (int in Mbit)
281+
* MTU (in Bytes)
271282
* mac_address (string)
272283
273284
Example::
@@ -280,6 +291,7 @@ def get_interfaces(self):
280291
'description': '',
281292
'last_flapped': -1.0,
282293
'speed': 1000,
294+
'mtu': 1500,
283295
'mac_address': 'FA:16:3E:57:33:61',
284296
},
285297
u'Ethernet1':
@@ -289,6 +301,7 @@ def get_interfaces(self):
289301
'description': 'foo',
290302
'last_flapped': 1429978575.1554043,
291303
'speed': 1000,
304+
'mtu': 1500,
292305
'mac_address': 'FA:16:3E:57:33:62',
293306
},
294307
u'Ethernet2':
@@ -298,6 +311,7 @@ def get_interfaces(self):
298311
'description': 'bla',
299312
'last_flapped': 1429978575.1555667,
300313
'speed': 1000,
314+
'mtu': 1500,
301315
'mac_address': 'FA:16:3E:57:33:63',
302316
},
303317
u'Ethernet3':
@@ -307,6 +321,7 @@ def get_interfaces(self):
307321
'description': 'bar',
308322
'last_flapped': -1.0,
309323
'speed': 1000,
324+
'mtu': 1500,
310325
'mac_address': 'FA:16:3E:57:33:64',
311326
}
312327
}
@@ -1497,13 +1512,14 @@ def get_optics(self):
14971512
"""
14981513
raise NotImplementedError
14991514

1500-
def get_config(self, retrieve="all"):
1515+
def get_config(self, retrieve="all", full=False):
15011516
"""
15021517
Return the configuration of a device.
15031518
15041519
Args:
15051520
retrieve(string): Which configuration type you want to populate, default is all of them.
15061521
The rest will be set to "".
1522+
full(bool): Retrieve all the configuration. For instance, on ios, "sh run all".
15071523
15081524
Returns:
15091525
The object returned is a dictionary with a key for each configuration store:

Diff for: napalm/base/clitools/cl_napalm.py

+3
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,9 @@ def build_help():
146146
)
147147
args = parser.parse_args()
148148

149+
if not hasattr(args, "which"):
150+
args.which = None
151+
149152
if args.password is None:
150153
password = getpass.getpass("Enter password: ")
151154
setattr(args, "password", password)

Diff for: napalm/base/helpers.py

+63
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
# std libs
88
import os
9+
import re
910
import sys
1011
import itertools
1112

@@ -15,6 +16,7 @@
1516
from netaddr import EUI
1617
from netaddr import mac_unix
1718
from netaddr import IPAddress
19+
from ciscoconfparse import CiscoConfParse
1820

1921
# local modules
2022
import napalm.base.exceptions
@@ -108,6 +110,67 @@ def load_template(
108110
return cls.load_merge_candidate(config=configuration)
109111

110112

113+
def cisco_conf_parse_parents(parent, child, config):
114+
"""
115+
Use CiscoConfParse to find parent lines that contain a specific child line.
116+
117+
:param parent: The parent line to search for
118+
:param child: The child line required under the given parent
119+
:param config: The device running/startup config
120+
"""
121+
if type(config) == str:
122+
config = config.splitlines()
123+
parse = CiscoConfParse(config)
124+
cfg_obj = parse.find_parents_w_child(parent, child)
125+
return cfg_obj
126+
127+
128+
def cisco_conf_parse_objects(cfg_section, config):
129+
"""
130+
Use CiscoConfParse to find and return a section of Cisco IOS config.
131+
Similar to "show run | section <cfg_section>"
132+
133+
:param cfg_section: The section of the config to return eg. "router bgp"
134+
:param config: The running/startup config of the device to parse
135+
"""
136+
return_config = []
137+
if type(config) is str:
138+
config = config.splitlines()
139+
parse = CiscoConfParse(config)
140+
cfg_obj = parse.find_objects(cfg_section)
141+
for parent in cfg_obj:
142+
return_config.append(parent.text)
143+
for child in parent.all_children:
144+
return_config.append(child.text)
145+
return return_config
146+
147+
148+
def regex_find_txt(pattern, text, default=""):
149+
"""""
150+
RegEx search for pattern in text. Will try to match the data type of the "default" value
151+
or return the default value if no match is found.
152+
This is to parse IOS config like below:
153+
regex_find_txt(r"remote-as (65000)", "neighbor 10.0.0.1 remote-as 65000", default=0)
154+
RETURNS: 65001
155+
156+
:param pattern: RegEx pattern to match on
157+
:param text: String of text ot search for "pattern" in
158+
:param default="": Default value and type to return on error
159+
"""
160+
text = str(text)
161+
value = re.findall(pattern, text)
162+
try:
163+
if not value:
164+
raise Exception
165+
if not isinstance(value, type(default)):
166+
if isinstance(value, list) and len(value) == 1:
167+
value = value[0]
168+
value = type(default)(value)
169+
except Exception: # in case of any exception, returns default
170+
value = default
171+
return value
172+
173+
111174
def textfsm_extractor(cls, template_name, raw_text):
112175
"""
113176
Applies a TextFSM template over a raw text and return the matching table.

Diff for: napalm/base/test/models.py

+1
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
"is_enabled": bool,
2020
"description": text_type,
2121
"last_flapped": float,
22+
"mtu": int,
2223
"speed": int,
2324
"mac_address": text_type,
2425
}

0 commit comments

Comments
 (0)