Skip to content

Commit 904c42e

Browse files
authored
Merge pull request #1938 from napalm-automation/develop
NAPALM Release 4.1.0
2 parents f5000c7 + 26b7bfb commit 904c42e

File tree

89 files changed

+1997
-728
lines changed

Some content is hidden

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

89 files changed

+1997
-728
lines changed

.github/workflows/commit.yaml

+7-7
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,14 @@ jobs:
1010
strategy:
1111
max-parallel: 4
1212
matrix:
13-
python-version: [3.7, 3.8, 3.9, 3.10.0]
13+
python-version: [3.7, 3.8, 3.9, 3.10.9, 3.11]
1414

1515
steps:
1616
- name: Checkout repository
17-
uses: actions/checkout@v2
17+
uses: actions/checkout@v3
1818

1919
- name: Setup Python ${{ matrix.python-version }}
20-
uses: actions/setup-python@v2
20+
uses: actions/setup-python@v4
2121
with:
2222
python-version: ${{ matrix.python-version }}
2323

@@ -54,20 +54,20 @@ jobs:
5454

5555
steps:
5656
- name: Checkout repository
57-
uses: actions/checkout@v2
57+
uses: actions/checkout@v3
5858

5959
- name: Setup Python ${{ matrix.python-version }}
60-
uses: actions/setup-python@v2
60+
uses: actions/setup-python@v4
6161
with:
6262
python-version: ${{ matrix.python-version }}
6363

6464
- name: Install dependencies
6565
run: |
6666
python -m pip install --upgrade pip
6767
python -m pip install -e .
68-
pip install -r requirements.txt
69-
pip install -r requirements-dev.txt
7068
python -m pip install -r docs/requirements.txt
69+
pip install -r requirements-dev.txt
70+
pip install -r requirements.txt
7171
7272
- name: Doctests
7373
run: |

.github/workflows/pythonpublish.yml

+9-8
Original file line numberDiff line numberDiff line change
@@ -12,19 +12,20 @@ jobs:
1212
deploy:
1313
runs-on: ubuntu-latest
1414
steps:
15-
- uses: actions/checkout@v1
15+
- uses: actions/checkout@v3
1616
- name: Set up Python
17-
uses: actions/setup-python@v1
17+
uses: actions/setup-python@v4
1818
with:
1919
python-version: '3.x'
2020
- name: Install dependencies
2121
run: |
2222
python -m pip install --upgrade pip
23-
pip install setuptools wheel twine
24-
- name: Build and publish
25-
env:
26-
TWINE_USERNAME: ${{ secrets.PYPI_USERNAME }}
27-
TWINE_PASSWORD: ${{ secrets.PYPI_PASSWORD }}
23+
pip install setuptools wheel
24+
- name: Build
2825
run: |
2926
python setup.py sdist bdist_wheel
30-
twine upload dist/*
27+
- name: Publish
28+
uses: pypa/gh-action-pypi-publish@master
29+
with:
30+
user: __token__
31+
password: ${{ secrets.PYPI_TOKEN }}

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ env
6565

6666
test/unit/test_devices.py
6767

68+
.report.json
6869
report.json
6970
tags
7071
.pytest_cache/

.readthedocs.yml

+2-1
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,10 @@ formats: all
1414

1515
# Optionally set the version of Python and requirements required to build your docs
1616
python:
17-
version: 3.7
17+
version: 3.8
1818
install:
1919
- method: pip
2020
path: .
2121
- requirements: docs/requirements.txt
22+
- requirements: requirements-dev.txt
2223
- requirements: requirements.txt

docs/conf.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -371,13 +371,13 @@ def build_getters_support_matrix(app):
371371
if not (m.startswith("_") or m in EXCLUDE_METHODS)
372372
}
373373

374-
regex_name = re.compile(r"(?P<driver>\w+)\/.*::test_(?P<getter>\w+)")
374+
regex_name = re.compile(r"test.*/(?P<driver>\w+)\/.*::test_(?P<getter>\w+)")
375375

376376
filename = "./support/tests/report.json"
377377
with open(filename, "r") as f:
378378
data = json.loads(f.read())
379-
for test in data["report"]["tests"]:
380-
match = regex_name.search(test["name"])
379+
for test in data["tests"]:
380+
match = regex_name.search(test["nodeid"])
381381
if match:
382382
driver = match.group("driver")
383383
drivers.add(driver)

docs/development/testing_framework.rst

+44-11
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
Testing Framework
22
-----------------
33

4-
As napalm consists of multiple drivers and all of them have to provide similar functionality, we have developed a testing framework to provide a consistent test suite for all the drivers.
4+
As NAPALM consists of multiple drivers and all of them have to provide similar functionality, we have developed a testing framework to provide a consistent test suite for all the drivers.
55

66
Features
77
________
@@ -42,7 +42,7 @@ By default, the tests are going to be run against mocked data but you can change
4242
* ``NAPALM_USERNAME``
4343
* ``NAPALM_PASSWORD``
4444
* ``NAPALM_OPTIONAL_ARGS``
45-
45+
4646
Mocking the ``open`` method
4747
^^^^^^^^^^^^^^^^^^^^^^^^^^^
4848

@@ -56,29 +56,29 @@ Multiple test cases::
5656
(napalm) ➜ napalm-eos git:(test_framework) ✗ ls test/unit/mocked_data/test_get_bgp_neighbors
5757
lots_of_peers no_peers normal
5858
(napalm) ➜ napalm-eos git:(test_framework) ✗ py.test test/unit/test_getters.py::TestGetter::test_get_bgp_neighbors
59-
...
59+
...
6060
test/unit/test_getters.py::TestGetter::test_get_bgp_neighbors[lots_of_peers] <- ../napalm/napalm.base/test/getters.py PASSED
6161
test/unit/test_getters.py::TestGetter::test_get_bgp_neighbors[no_peers] <- ../napalm/napalm.base/test/getters.py PASSED
6262
test/unit/test_getters.py::TestGetter::test_get_bgp_neighbors[normal] <- ../napalm/napalm.base/test/getters.py PASSED
63-
63+
6464
Missing test cases::
6565

6666
(napalm) ➜ napalm-eos git:(test_framework) ✗ ls test/unit/mocked_data/test_get_bgp_neighbors
6767
ls: test/unit/mocked_data/test_get_bgp_neighbors: No such file or directory
6868
(napalm) ➜ napalm-eos git:(test_framework) ✗ py.test test/unit/test_getters.py::TestGetter::test_get_bgp_neighbors
69-
...
69+
...
7070
test/unit/test_getters.py::TestGetter::test_get_bgp_neighbors[no_test_case_found] <- ../napalm/napalm.base/test/getters.py FAILED
71-
71+
7272
========================================================= FAILURES ==========================================================
7373
___________________________________ TestGetter.test_get_bgp_neighbors[no_test_case_found] ___________________________________
74-
74+
7575
cls = <test_getters.TestGetter instance at 0x10ed5eb90>, test_case = 'no_test_case_found'
76-
76+
7777
@functools.wraps(func)
7878
def wrapper(cls, test_case):
7979
cls.device.device.current_test = func.__name__
8080
cls.device.device.current_test_case = test_case
81-
81+
8282
try:
8383
# This is an ugly, ugly, ugly hack because some python objects don't load
8484
# as expected. For example, dicts where integers are strings
@@ -87,7 +87,7 @@ Missing test cases::
8787
if test_case == "no_test_case_found":
8888
> pytest.fail("No test case for '{}' found".format(func.__name__))
8989
E Failed: No test case for 'test_get_bgp_neighbors' found
90-
90+
9191
../napalm/napalm.base/test/getters.py:64: Failed
9292
================================================= 1 failed in 0.12 seconds ==================================================
9393

@@ -96,8 +96,41 @@ Method not implemented::
9696
(napalm) ➜ napalm-eos git:(test_framework) ✗ py.test test/unit/test_getters.py::TestGetter::test_get_probes_config
9797
...
9898
test/unit/test_getters.py::TestGetter::test_get_probes_config[no_test_case_found] <- ../napalm/napalm.base/test/getters.py SKIPPED
99-
99+
100100
================================================= 1 skipped in 0.09 seconds =================================================
101101

102+
Testing Matrix
103+
--------------
104+
105+
NAPALM leverages [Github Actions](https://docs.github.com/en/actions) to test and lint code on commits and pull requests.
106+
If you want to test prior to opening a pull request, you can use [nektos/act](https://github.com/nektos/act) and Docker to locally run the tests
107+
108+
.. code-block:: console
109+
110+
$ act -j std_tests
111+
[build/std_tests-4] 🚀 Start image=catthehacker/ubuntu:act-latest
112+
[build/std_tests-3] 🚀 Start image=catthehacker/ubuntu:act-latest
113+
[build/std_tests-1] 🚀 Start image=catthehacker/ubuntu:act-latest
114+
[build/std_tests-2] 🚀 Start image=catthehacker/ubuntu:act-latest
115+
[build/std_tests-5] 🚀 Start image=catthehacker/ubuntu:act-latest
116+
[build/std_tests-4] 🐳 docker pull image=catthehacker/ubuntu:act-latest platform= username= forcePull=true
117+
[build/std_tests-1] 🐳 docker pull image=catthehacker/ubuntu:act-latest platform= username= forcePull=true
118+
[build/std_tests-3] 🐳 docker pull image=catthehacker/ubuntu:act-latest platform= username= forcePull=true
119+
[build/std_tests-5] 🐳 docker pull image=catthehacker/ubuntu:act-latest platform= username= forcePull=true
120+
[build/std_tests-2] 🐳 docker pull image=catthehacker/ubuntu:act-latest platform= username= forcePull=true
121+
122+
...
123+
124+
| ---------------------------------------------------------------------
125+
| TOTAL 9258 1836 80%
126+
|
127+
| ================= 619 passed, 80 skipped, 3 warnings in 19.97s =================
128+
[build/std_tests-5] ✅ Success - Main Run Tests
129+
[build/std_tests-5] ⭐ Run Post Setup Python 3.11
130+
[build/std_tests-5] 🐳 docker exec cmd=[node /var/run/act/actions/actions-setup-python@v2/dist/cache-save/index.js] user= workdir=
131+
[build/std_tests-5] ✅ Success - Post Setup Python 3.11
132+
[build/std_tests-5] 🏁 Job succeeded
133+
134+
102135
.. _`test_getters.py`: https://github.com/napalm-automation/napalm-eos/blob/a2fc2cf6a98b0851efe4cba907086191b8f1df02/test/unit/test_getters.py
103136
.. _`conftest.py`: https://github.com/napalm-automation/napalm-eos/blob/a2fc2cf6a98b0851efe4cba907086191b8f1df02/test/unit/conftest.py

docs/requirements.txt

+9-4
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
1-
sphinx
2-
sphinx-rtd-theme
3-
sphinxcontrib-napoleon
4-
invoke
1+
urllib3==1.26.15 # https://github.com/readthedocs/readthedocs.org/issues/10290
2+
sphinx==1.8.6
3+
sphinx-rtd-theme==1.2.0
4+
sphinxcontrib-napoleon==0.7
5+
invoke==2.0.0
6+
jinja2==2.11.3
7+
MarkupSafe==2.0.1
8+
pytest==7.2.2
9+
ansible==4.10.0

docs/support/index.rst

+2-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ General support matrix
1313
===================== ========== ============= ==================== ================== ============ ============ ============
1414
**Driver Name** eos junos iosxr_netconf iosxr nxos nxos_ssh ios
1515
**Structured data** Yes Yes Yes No Yes No No
16-
**Minimum version** 4.15.0F 12.1 7.0 5.1.0 6.1 [#g1]_ 12.4(20)T 6.3.2
16+
**Minimum version** 4.15.0F 12.1 7.0 5.1.0 6.1 [#g1]_ 6.3.2 12.4(20)T
1717
**Backend library** `pyeapi`_ `junos-eznc`_ `ncclient`_ `pyIOSXR`_ `pynxos`_ `netmiko`_ `netmiko`_
1818
**Caveats** :doc:`eos` :doc:`iosxr_netconf` :doc:`nxos` :doc:`nxos` :doc:`ios`
1919
===================== ========== ============= ==================== ================== ============ ============ ============
@@ -141,6 +141,7 @@ ____________________________________
141141
* :code:`eos_fn0039_config` (eos) - Transform old style configuration to the new style, available beginning with EOS release 4.23.0, as per FN 0039. Beware
142142
that enabling this option will change the configuration you're loading through NAPALM. Default: ``False`` (won't change your configuration commands).
143143
.. versionadded:: 3.0.1
144+
* :code:`force_cfg_session_invalid` (eos) - Force the config_session to be cleared in case of issues, like `discard_config` failure. (default: ``False``)
144145

145146
The transport argument
146147
______________________

docs/support/ios.rst

+1-1
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ File Operation Prompts
116116
______________________
117117

118118
By default IOS will prompt for confirmation on file operations. These prompts need to be disabled before the NAPALM-ios driver performs any such operation on the device.
119-
This can be controlled using the `auto_file_prompt` optional arguement:
119+
This can be controlled using the `auto_file_prompt` optional argument:
120120

121121
* `auto_file_prompt=True` (default): NAPALM will automatically add `file prompt quiet` to the device configuration before performing file operations,
122122
and un-configure it again afterwards. If the device already had the command in its configuration then it will be silently removed as a result, and

docs/support/nxos.rst

+1-1
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ One caveat of using netutils diff of configurations is that the diff is performe
7171

7272
Example assuming that the device config contains:
7373

74-
.. code-block::
74+
.. code-block:: bash
7575
7676
interface loopback0
7777
ip address 10.1.4.4/32

docs/test.sh

+4-6
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,12 @@
11
#!/bin/bash
22
CWD=`pwd`
33
TEST_RESULTS_PATH="$CWD/support/tests"
4+
REPOBASE=$CWD/..
45

5-
if [ ! -f "report.json" ]; then
6+
if [ ! -f ".report.json" ]; then
67
set -e
7-
pip install -r ../requirements.txt -r ../requirements-dev.txt
8+
pytest --rootdir $REPOBASE -c /dev/null --json-report --cov=./ -vs $REPOBASE/test*/*/test_getters.py
89

9-
set +e
10-
py.test -c /dev/null --cov=./ -vs --json=report.json ../test*/*/test_getters.py
1110
set -e
12-
13-
cp report.json $TEST_RESULTS_PATH/report.json
11+
cp .report.json $TEST_RESULTS_PATH/report.json
1412
fi

napalm/base/base.py

+4-4
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
from typing_extensions import Literal
2020

2121
from netmiko import ConnectHandler, NetMikoTimeoutException
22+
from netutils.interface import canonical_interface_name
2223

2324
# local modules
2425
import napalm.base.exceptions
@@ -647,7 +648,8 @@ def get_bgp_config(
647648
:param neighbor: Returns the configuration of a specific BGP neighbor.
648649
649650
Main dictionary keys represent the group name and the values represent a dictionary having
650-
the keys below. Neighbors which aren't members of a group will be stored in a key named "_":
651+
the keys below. A default group named "_" will contain information regarding global
652+
settings and any neighbors that are not members of a group.
651653
652654
* type (string)
653655
* description (string)
@@ -1804,8 +1806,6 @@ def compliance_report(
18041806
def _canonical_int(self, interface: str) -> str:
18051807
"""Expose the helper function within this class."""
18061808
if self.use_canonical_interface is True:
1807-
return napalm.base.helpers.canonical_interface_name(
1808-
interface, addl_name_map=None
1809-
)
1809+
return canonical_interface_name(interface, addl_name_map=None)
18101810
else:
18111811
return interface

0 commit comments

Comments
 (0)