diff --git a/.github/workflows/commit.yaml b/.github/workflows/commit.yaml index 0329a5554..f7d265f1f 100644 --- a/.github/workflows/commit.yaml +++ b/.github/workflows/commit.yaml @@ -10,14 +10,14 @@ jobs: strategy: max-parallel: 4 matrix: - python-version: [3.7, 3.8, 3.9, 3.10.9, 3.11] + python-version: [3.7, 3.8, 3.9, 3.10.0] steps: - name: Checkout repository - uses: actions/checkout@v3 + uses: actions/checkout@v2 - name: Setup Python ${{ matrix.python-version }} - uses: actions/setup-python@v4 + uses: actions/setup-python@v2 with: python-version: ${{ matrix.python-version }} @@ -54,10 +54,10 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v3 + uses: actions/checkout@v2 - name: Setup Python ${{ matrix.python-version }} - uses: actions/setup-python@v4 + uses: actions/setup-python@v2 with: python-version: ${{ matrix.python-version }} @@ -65,9 +65,9 @@ jobs: run: | python -m pip install --upgrade pip python -m pip install -e . - python -m pip install -r docs/requirements.txt - pip install -r requirements-dev.txt pip install -r requirements.txt + pip install -r requirements-dev.txt + python -m pip install -r docs/requirements.txt - name: Doctests run: | diff --git a/.github/workflows/pythonpublish.yml b/.github/workflows/pythonpublish.yml index ed1ba114e..1fba0b41b 100644 --- a/.github/workflows/pythonpublish.yml +++ b/.github/workflows/pythonpublish.yml @@ -12,20 +12,19 @@ jobs: deploy: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v1 - name: Set up Python - uses: actions/setup-python@v4 + uses: actions/setup-python@v1 with: python-version: '3.x' - name: Install dependencies run: | python -m pip install --upgrade pip - pip install setuptools wheel - - name: Build + pip install setuptools wheel twine + - name: Build and publish + env: + TWINE_USERNAME: ${{ secrets.PYPI_USERNAME }} + TWINE_PASSWORD: ${{ secrets.PYPI_PASSWORD }} run: | python setup.py sdist bdist_wheel - - name: Publish - uses: pypa/gh-action-pypi-publish@master - with: - user: __token__ - password: ${{ secrets.PYPI_TOKEN }} + twine upload dist/* diff --git a/.gitignore b/.gitignore index 87330b57c..a00f7f807 100644 --- a/.gitignore +++ b/.gitignore @@ -65,7 +65,6 @@ env test/unit/test_devices.py -.report.json report.json tags .pytest_cache/ diff --git a/.readthedocs.yml b/.readthedocs.yml index 320d0121d..65fd950da 100644 --- a/.readthedocs.yml +++ b/.readthedocs.yml @@ -14,10 +14,9 @@ formats: all # Optionally set the version of Python and requirements required to build your docs python: - version: 3.8 + version: 3.7 install: - method: pip path: . - requirements: docs/requirements.txt - - requirements: requirements-dev.txt - requirements: requirements.txt diff --git a/docs/conf.py b/docs/conf.py index d9b5774cd..cf56e0537 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -371,13 +371,13 @@ def build_getters_support_matrix(app): if not (m.startswith("_") or m in EXCLUDE_METHODS) } - regex_name = re.compile(r"test.*/(?P\w+)\/.*::test_(?P\w+)") + regex_name = re.compile(r"(?P\w+)\/.*::test_(?P\w+)") filename = "./support/tests/report.json" with open(filename, "r") as f: data = json.loads(f.read()) - for test in data["tests"]: - match = regex_name.search(test["nodeid"]) + for test in data["report"]["tests"]: + match = regex_name.search(test["name"]) if match: driver = match.group("driver") drivers.add(driver) diff --git a/docs/development/testing_framework.rst b/docs/development/testing_framework.rst index ef5a7ed7f..2b61cc9da 100644 --- a/docs/development/testing_framework.rst +++ b/docs/development/testing_framework.rst @@ -1,7 +1,7 @@ Testing Framework ----------------- -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. +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. Features ________ @@ -42,7 +42,7 @@ By default, the tests are going to be run against mocked data but you can change * ``NAPALM_USERNAME`` * ``NAPALM_PASSWORD`` * ``NAPALM_OPTIONAL_ARGS`` - + Mocking the ``open`` method ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -56,29 +56,29 @@ Multiple test cases:: (napalm) ➜ napalm-eos git:(test_framework) ✗ ls test/unit/mocked_data/test_get_bgp_neighbors lots_of_peers no_peers normal (napalm) ➜ napalm-eos git:(test_framework) ✗ py.test test/unit/test_getters.py::TestGetter::test_get_bgp_neighbors - ... + ... test/unit/test_getters.py::TestGetter::test_get_bgp_neighbors[lots_of_peers] <- ../napalm/napalm.base/test/getters.py PASSED test/unit/test_getters.py::TestGetter::test_get_bgp_neighbors[no_peers] <- ../napalm/napalm.base/test/getters.py PASSED test/unit/test_getters.py::TestGetter::test_get_bgp_neighbors[normal] <- ../napalm/napalm.base/test/getters.py PASSED - + Missing test cases:: (napalm) ➜ napalm-eos git:(test_framework) ✗ ls test/unit/mocked_data/test_get_bgp_neighbors ls: test/unit/mocked_data/test_get_bgp_neighbors: No such file or directory (napalm) ➜ napalm-eos git:(test_framework) ✗ py.test test/unit/test_getters.py::TestGetter::test_get_bgp_neighbors - ... + ... test/unit/test_getters.py::TestGetter::test_get_bgp_neighbors[no_test_case_found] <- ../napalm/napalm.base/test/getters.py FAILED - + ========================================================= FAILURES ========================================================== ___________________________________ TestGetter.test_get_bgp_neighbors[no_test_case_found] ___________________________________ - + cls = , test_case = 'no_test_case_found' - + @functools.wraps(func) def wrapper(cls, test_case): cls.device.device.current_test = func.__name__ cls.device.device.current_test_case = test_case - + try: # This is an ugly, ugly, ugly hack because some python objects don't load # as expected. For example, dicts where integers are strings @@ -87,7 +87,7 @@ Missing test cases:: if test_case == "no_test_case_found": > pytest.fail("No test case for '{}' found".format(func.__name__)) E Failed: No test case for 'test_get_bgp_neighbors' found - + ../napalm/napalm.base/test/getters.py:64: Failed ================================================= 1 failed in 0.12 seconds ================================================== @@ -96,41 +96,8 @@ Method not implemented:: (napalm) ➜ napalm-eos git:(test_framework) ✗ py.test test/unit/test_getters.py::TestGetter::test_get_probes_config ... test/unit/test_getters.py::TestGetter::test_get_probes_config[no_test_case_found] <- ../napalm/napalm.base/test/getters.py SKIPPED - + ================================================= 1 skipped in 0.09 seconds ================================================= -Testing Matrix --------------- - -NAPALM leverages [Github Actions](https://docs.github.com/en/actions) to test and lint code on commits and pull requests. -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 - -.. code-block:: console - - $ act -j std_tests - [build/std_tests-4] 🚀 Start image=catthehacker/ubuntu:act-latest - [build/std_tests-3] 🚀 Start image=catthehacker/ubuntu:act-latest - [build/std_tests-1] 🚀 Start image=catthehacker/ubuntu:act-latest - [build/std_tests-2] 🚀 Start image=catthehacker/ubuntu:act-latest - [build/std_tests-5] 🚀 Start image=catthehacker/ubuntu:act-latest - [build/std_tests-4] 🐳 docker pull image=catthehacker/ubuntu:act-latest platform= username= forcePull=true - [build/std_tests-1] 🐳 docker pull image=catthehacker/ubuntu:act-latest platform= username= forcePull=true - [build/std_tests-3] 🐳 docker pull image=catthehacker/ubuntu:act-latest platform= username= forcePull=true - [build/std_tests-5] 🐳 docker pull image=catthehacker/ubuntu:act-latest platform= username= forcePull=true - [build/std_tests-2] 🐳 docker pull image=catthehacker/ubuntu:act-latest platform= username= forcePull=true - - ... - - | --------------------------------------------------------------------- - | TOTAL 9258 1836 80% - | - | ================= 619 passed, 80 skipped, 3 warnings in 19.97s ================= - [build/std_tests-5] ✅ Success - Main Run Tests - [build/std_tests-5] ⭐ Run Post Setup Python 3.11 - [build/std_tests-5] 🐳 docker exec cmd=[node /var/run/act/actions/actions-setup-python@v2/dist/cache-save/index.js] user= workdir= - [build/std_tests-5] ✅ Success - Post Setup Python 3.11 - [build/std_tests-5] 🏁 Job succeeded - - .. _`test_getters.py`: https://github.com/napalm-automation/napalm-eos/blob/a2fc2cf6a98b0851efe4cba907086191b8f1df02/test/unit/test_getters.py .. _`conftest.py`: https://github.com/napalm-automation/napalm-eos/blob/a2fc2cf6a98b0851efe4cba907086191b8f1df02/test/unit/conftest.py diff --git a/docs/requirements.txt b/docs/requirements.txt index 24e3fa96b..f822bffdb 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -1,9 +1,4 @@ -urllib3==1.26.15 # https://github.com/readthedocs/readthedocs.org/issues/10290 -sphinx==1.8.6 -sphinx-rtd-theme==1.2.0 -sphinxcontrib-napoleon==0.7 -invoke==2.0.0 -jinja2==2.11.3 -MarkupSafe==2.0.1 -pytest==7.2.2 -ansible==4.10.0 +sphinx +sphinx-rtd-theme +sphinxcontrib-napoleon +invoke diff --git a/docs/support/index.rst b/docs/support/index.rst index 78ad1191a..f869f592c 100644 --- a/docs/support/index.rst +++ b/docs/support/index.rst @@ -13,7 +13,7 @@ General support matrix ===================== ========== ============= ==================== ================== ============ ============ ============ **Driver Name** eos junos iosxr_netconf iosxr nxos nxos_ssh ios **Structured data** Yes Yes Yes No Yes No No - **Minimum version** 4.15.0F 12.1 7.0 5.1.0 6.1 [#g1]_ 6.3.2 12.4(20)T + **Minimum version** 4.15.0F 12.1 7.0 5.1.0 6.1 [#g1]_ 12.4(20)T 6.3.2 **Backend library** `pyeapi`_ `junos-eznc`_ `ncclient`_ `pyIOSXR`_ `pynxos`_ `netmiko`_ `netmiko`_ **Caveats** :doc:`eos` :doc:`iosxr_netconf` :doc:`nxos` :doc:`nxos` :doc:`ios` ===================== ========== ============= ==================== ================== ============ ============ ============ @@ -141,7 +141,6 @@ ____________________________________ * :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 that enabling this option will change the configuration you're loading through NAPALM. Default: ``False`` (won't change your configuration commands). .. versionadded:: 3.0.1 -* :code:`force_cfg_session_invalid` (eos) - Force the config_session to be cleared in case of issues, like `discard_config` failure. (default: ``False``) The transport argument ______________________ diff --git a/docs/support/ios.rst b/docs/support/ios.rst index 1bbc5116e..b46a92a54 100644 --- a/docs/support/ios.rst +++ b/docs/support/ios.rst @@ -116,7 +116,7 @@ File Operation Prompts ______________________ 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. -This can be controlled using the `auto_file_prompt` optional argument: +This can be controlled using the `auto_file_prompt` optional arguement: * `auto_file_prompt=True` (default): NAPALM will automatically add `file prompt quiet` to the device configuration before performing file operations, 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 diff --git a/docs/support/nxos.rst b/docs/support/nxos.rst index 9f9e5ee8b..0dfff92be 100644 --- a/docs/support/nxos.rst +++ b/docs/support/nxos.rst @@ -71,7 +71,7 @@ One caveat of using netutils diff of configurations is that the diff is performe Example assuming that the device config contains: -.. code-block:: bash +.. code-block:: interface loopback0 ip address 10.1.4.4/32 diff --git a/docs/test.sh b/docs/test.sh index 3d102c74a..78a572fac 100755 --- a/docs/test.sh +++ b/docs/test.sh @@ -1,12 +1,14 @@ #!/bin/bash CWD=`pwd` TEST_RESULTS_PATH="$CWD/support/tests" -REPOBASE=$CWD/.. -if [ ! -f ".report.json" ]; then +if [ ! -f "report.json" ]; then set -e - pytest --rootdir $REPOBASE -c /dev/null --json-report --cov=./ -vs $REPOBASE/test*/*/test_getters.py + pip install -r ../requirements.txt -r ../requirements-dev.txt + set +e + py.test -c /dev/null --cov=./ -vs --json=report.json ../test*/*/test_getters.py set -e - cp .report.json $TEST_RESULTS_PATH/report.json + + cp report.json $TEST_RESULTS_PATH/report.json fi diff --git a/napalm/base/base.py b/napalm/base/base.py index 7410bf6a8..1259f6966 100644 --- a/napalm/base/base.py +++ b/napalm/base/base.py @@ -19,7 +19,6 @@ from typing_extensions import Literal from netmiko import ConnectHandler, NetMikoTimeoutException -from netutils.interface import canonical_interface_name # local modules import napalm.base.exceptions @@ -648,8 +647,7 @@ def get_bgp_config( :param neighbor: Returns the configuration of a specific BGP neighbor. Main dictionary keys represent the group name and the values represent a dictionary having - the keys below. A default group named "_" will contain information regarding global - settings and any neighbors that are not members of a group. + the keys below. Neighbors which aren't members of a group will be stored in a key named "_": * type (string) * description (string) @@ -1806,6 +1804,8 @@ def compliance_report( def _canonical_int(self, interface: str) -> str: """Expose the helper function within this class.""" if self.use_canonical_interface is True: - return canonical_interface_name(interface, addl_name_map=None) + return napalm.base.helpers.canonical_interface_name( + interface, addl_name_map=None + ) else: return interface diff --git a/napalm/base/canonical_map.py b/napalm/base/canonical_map.py index fb9658213..29b50e714 100644 --- a/napalm/base/canonical_map.py +++ b/napalm/base/canonical_map.py @@ -1,4 +1,153 @@ -# Do not remove the below imports, functions were moved to netutils, but to not -# break backwards compatibility, these should remain -from netutils.constants import BASE_INTERFACES as base_interfaces # noqa -from netutils.constants import REVERSE_MAPPING as reverse_mapping # noqa +base_interfaces = { + "ATM": "ATM", + "AT": "ATM", + "B": "Bdi", + "Bd": "Bdi", + "Bdi": "Bdi", + "EOBC": "EOBC", + "EO": "EOBC", + "Ethernet": "Ethernet", + "Eth": "Ethernet", + "eth": "Ethernet", + "Et": "Ethernet", + "et": "Ethernet", + "FastEthernet": "FastEthernet", + "FastEth": "FastEthernet", + "FastE": "FastEthernet", + "Fast": "FastEthernet", + "Fas": "FastEthernet", + "FE": "FastEthernet", + "Fa": "FastEthernet", + "fa": "FastEthernet", + "Fddi": "Fddi", + "FD": "Fddi", + "FortyGigabitEthernet": "FortyGigabitEthernet", + "FortyGigEthernet": "FortyGigabitEthernet", + "FortyGigEth": "FortyGigabitEthernet", + "FortyGigE": "FortyGigabitEthernet", + "FortyGig": "FortyGigabitEthernet", + "FGE": "FortyGigabitEthernet", + "FO": "FortyGigabitEthernet", + "Fo": "FortyGigabitEthernet", + "FiftyGigabitEthernet": "FiftyGigabitEthernet", + "FiftyGigEthernet": "FiftyGigabitEthernet", + "FiftyGigEth": "FiftyGigabitEthernet", + "FiftyGigE": "FiftyGigabitEthernet", + "FI": "FiftyGigabitEthernet", + "Fi": "FiftyGigabitEthernet", + "fi": "FiftyGigabitEthernet", + "GigabitEthernet": "GigabitEthernet", + "GigEthernet": "GigabitEthernet", + "GigEth": "GigabitEthernet", + "GigE": "GigabitEthernet", + "Gig": "GigabitEthernet", + "GE": "GigabitEthernet", + "Ge": "GigabitEthernet", + "ge": "GigabitEthernet", + "Gi": "GigabitEthernet", + "gi": "GigabitEthernet", + "HundredGigabitEthernet": "HundredGigabitEthernet", + "HundredGigEthernet": "HundredGigabitEthernet", + "HundredGigEth": "HundredGigabitEthernet", + "HundredGigE": "HundredGigabitEthernet", + "HundredGig": "HundredGigabitEthernet", + "Hu": "HundredGigabitEthernet", + "TwentyFiveGigabitEthernet": "TwentyFiveGigabitEthernet", + "TwentyFiveGigEthernet": "TwentyFiveGigabitEthernet", + "TwentyFiveGigEth": "TwentyFiveGigabitEthernet", + "TwentyFiveGigE": "TwentyFiveGigabitEthernet", + "TwentyFiveGig": "TwentyFiveGigabitEthernet", + "TF": "TwentyFiveGigabitEthernet", + "Tf": "TwentyFiveGigabitEthernet", + "tf": "TwentyFiveGigabitEthernet", + "TwoHundredGigabitEthernet": "TwoHundredGigabitEthernet", + "TwoHundredGigEthernet": "TwoHundredGigabitEthernet", + "TwoHundredGigEth": "TwoHundredGigabitEthernet", + "TwoHundredGigE": "TwoHundredGigabitEthernet", + "TwoHundredGig": "TwoHundredGigabitEthernet", + "TH": "TwoHundredGigabitEthernet", + "Th": "TwoHundredGigabitEthernet", + "th": "TwoHundredGigabitEthernet", + "FourHundredGigabitEthernet": "FourHundredGigabitEthernet", + "FourHundredGigEthernet": "FourHundredGigabitEthernet", + "FourHundredGigEth": "FourHundredGigabitEthernet", + "FourHundredGigE": "FourHundredGigabitEthernet", + "FourHundredGig": "FourHundredGigabitEthernet", + "F": "FourHundredGigabitEthernet", + "f": "FourHundredGigabitEthernet", + "Loopback": "Loopback", + "loopback": "Loopback", + "Lo": "Loopback", + "lo": "Loopback", + "Management": "Management", + "Mgmt": "Management", + "mgmt": "Management", + "Ma": "Management", + "Management_short": "Ma", + "MFR": "MFR", + "Multilink": "Multilink", + "Mu": "Multilink", + "n": "nve", + "nv": "nve", + "nve": "nve", + "PortChannel": "Port-channel", + "Port-channel": "Port-channel", + "Port-Channel": "Port-channel", + "port-channel": "Port-channel", + "po": "Port-channel", + "Po": "Port-channel", + "POS": "POS", + "PO": "POS", + "Serial": "Serial", + "Se": "Serial", + "S": "Serial", + "TenGigabitEthernet": "TenGigabitEthernet", + "TenGigEthernet": "TenGigabitEthernet", + "TenGigEth": "TenGigabitEthernet", + "TenGig": "TenGigabitEthernet", + "TeGig": "TenGigabitEthernet", + "Ten": "TenGigabitEthernet", + "T": "TenGigabitEthernet", + "Te": "TenGigabitEthernet", + "te": "TenGigabitEthernet", + "Tunnel": "Tunnel", + "Tun": "Tunnel", + "Tu": "Tunnel", + "Twe": "TwentyFiveGigE", + "Tw": "TwoGigabitEthernet", + "Two": "TwoGigabitEthernet", + "Virtual-Access": "Virtual-Access", + "Vi": "Virtual-Access", + "Virtual-Template": "Virtual-Template", + "Vt": "Virtual-Template", + "VLAN": "VLAN", + "V": "VLAN", + "Vl": "VLAN", + "Wlan-GigabitEthernet": "Wlan-GigabitEthernet", +} + +reverse_mapping = { + "ATM": "At", + "EOBC": "EO", + "Ethernet": "Et", + "FastEthernet": "Fa", + "Fddi": "FD", + "FortyGigabitEthernet": "Fo", + "GigabitEthernet": "Gi", + "HundredGigabitEthernet": "Hu", + "Loopback": "Lo", + "Management": "Ma", + "MFR": "MFR", + "Multilink": "Mu", + "Port-channel": "Po", + "POS": "PO", + "Serial": "Se", + "TenGigabitEthernet": "Te", + "Tunnel": "Tu", + "TwoGigabitEthernet": "Two", + "TwentyFiveGigE": "Twe", + "Virtual-Access": "Vi", + "Virtual-Template": "Vt", + "VLAN": "Vl", + "Wlan-GigabitEthernet": "Wl-Gi", +} diff --git a/napalm/base/helpers.py b/napalm/base/helpers.py index dd58ddc7a..935dfd58d 100644 --- a/napalm/base/helpers.py +++ b/napalm/base/helpers.py @@ -1,5 +1,4 @@ """Helper functions for the NAPALM base.""" -import ipaddress import itertools import logging @@ -15,17 +14,10 @@ import textfsm from lxml import etree from netaddr import EUI +from netaddr import IPAddress from netaddr import mac_unix from netutils.config.parser import IOSConfigParser -# Do not remove the below imports, functions were moved to netutils, but to not -# break backwards compatibility, these should remain -from netutils.interface import abbreviated_interface_name # noqa -from netutils.interface import canonical_interface_name # noqa -from netutils.constants import BASE_INTERFACES as base_interfaces # noqa -from netutils.constants import REVERSE_MAPPING as reverse_mapping # noqa -from netutils.interface import split_interface as _split_interface - try: from ttp import quick_parse as ttp_quick_parse @@ -38,6 +30,7 @@ from napalm.base import constants from napalm.base.models import ConfigDict from napalm.base.utils.jinja_filters import CustomJinjaFilters +from napalm.base.canonical_map import base_interfaces, reverse_mapping T = TypeVar("T") R = TypeVar("R") @@ -544,19 +537,10 @@ def ip(addr: str, version: Optional[int] = None) -> str: >>> ip('2001:0dB8:85a3:0000:0000:8A2e:0370:7334') u'2001:db8:85a3::8a2e:370:7334' """ - scope = "" - if "%" in addr: - addr, scope = addr.split("%", 1) - addr_obj = ipaddress.ip_address(addr) + addr_obj = IPAddress(addr) if version and addr_obj.version != version: raise ValueError("{} is not an ipv{} address".format(addr, version)) - if addr_obj.version == 6 and addr_obj.ipv4_mapped is not None: - return_addr = "%s:%s" % ("::ffff", addr_obj.ipv4_mapped) - else: - return_addr = str(addr_obj) - if scope: - return_addr = "%s%%%s" % (return_addr, scope) - return return_addr + return str(addr_obj) def as_number(as_number_val: str) -> int: @@ -571,7 +555,92 @@ def as_number(as_number_val: str) -> int: def split_interface(intf_name: str) -> Tuple[str, str]: """Split an interface name based on first digit, slash, or space match.""" - return _split_interface(interface=intf_name) + head = intf_name.rstrip(r"/\0123456789. ") + tail = intf_name[len(head) :].lstrip() + return (head, tail) + + +def canonical_interface_name( + interface: str, addl_name_map: Optional[Dict[str, str]] = None +) -> str: + """Function to return an interface's canonical name (fully expanded name). + + Use of explicit matches used to indicate a clear understanding on any potential + match. Regex and other looser matching methods were not implmented to avoid false + positive matches. As an example, it would make sense to do "[P|p][O|o]" which would + incorrectly match PO = POS and Po = Port-channel, leading to a false positive, not + easily troubleshot, found, or known. + + :param interface: The interface you are attempting to expand. + :param addl_name_map: A dict containing key/value pairs that updates + the base mapping. Used if an OS has specific differences. e.g. {"Po": "PortChannel"} vs + {"Po": "Port-Channel"} + :type addl_name_map: optional + """ + + name_map = {} + name_map.update(base_interfaces) + interface_type, interface_number = split_interface(interface) + + if isinstance(addl_name_map, dict): + name_map.update(addl_name_map) + # check in dict for mapping + if name_map.get(interface_type): + long_int = name_map.get(interface_type) + assert isinstance(long_int, str) + return long_int + str(interface_number) + # if nothing matched, return the original name + else: + return interface + + +def abbreviated_interface_name( + interface: str, + addl_name_map: Optional[Dict[str, str]] = None, + addl_reverse_map: Optional[Dict[str, str]] = None, +) -> str: + """Function to return an abbreviated representation of the interface name. + + :param interface: The interface you are attempting to abbreviate. + :param addl_name_map: A dict containing key/value pairs that updates + the base mapping. Used if an OS has specific differences. e.g. {"Po": "PortChannel"} vs + {"Po": "Port-Channel"} + :type addl_name_map: optional + :param addl_reverse_map: A dict containing key/value pairs that updates + the reverse mapping. Used if an OS has specific differences. e.g. {"PortChannel": "Po"} vs + {"PortChannel": "po"} + :type addl_reverse_map: optional + """ + + name_map = {} + name_map.update(base_interfaces) + interface_type, interface_number = split_interface(interface) + + if isinstance(addl_name_map, dict): + name_map.update(addl_name_map) + + rev_name_map = {} + rev_name_map.update(reverse_mapping) + + if isinstance(addl_reverse_map, dict): + rev_name_map.update(addl_reverse_map) + + # Try to ensure canonical type. + if name_map.get(interface_type): + canonical_type = name_map.get(interface_type) + else: + canonical_type = interface_type + + assert isinstance(canonical_type, str) + + try: + abbreviated_name = rev_name_map[canonical_type] + str(interface_number) + return abbreviated_name + except KeyError: + pass + + # If abbreviated name lookup fails, return original name + return interface def transform_lldp_capab(capabilities: Union[str, Any]) -> List[str]: diff --git a/napalm/base/test/getters.py b/napalm/base/test/getters.py index 0a2e47a66..cc64f551e 100644 --- a/napalm/base/test/getters.py +++ b/napalm/base/test/getters.py @@ -244,7 +244,7 @@ def test_get_lldp_neighbors_detail(self, test_case): def test_get_bgp_config(self, test_case): """Test get_bgp_config.""" get_bgp_config = self.device.get_bgp_config() - assert get_bgp_config == {} or len(get_bgp_config) > 0 + assert len(get_bgp_config) > 0 for bgp_group in get_bgp_config.values(): assert helpers.test_model(models.BPGConfigGroupDict, bgp_group) diff --git a/napalm/base/utils/string_parsers.py b/napalm/base/utils/string_parsers.py index f14f10e8b..c7dd8f376 100644 --- a/napalm/base/utils/string_parsers.py +++ b/napalm/base/utils/string_parsers.py @@ -1,7 +1,6 @@ """ Common methods to normalize a string """ import re -import struct -from typing import Union, List, Iterable, Dict, Optional, Tuple +from typing import Union, List, Iterable, Dict, Optional def convert(text: str) -> Union[str, int]: @@ -51,7 +50,7 @@ def colon_separated_string_to_dict( dictionary[line_data[0].strip()] = None else: raise Exception( - f"Something went wrong parsing the colon separated string:\n\n{line}" + "Something went wrong parsing the colo separated string {}".format(line) ) return dictionary @@ -134,14 +133,3 @@ def convert_uptime_string_seconds(uptime: str) -> int: raise Exception("Unrecognized uptime string:{}".format(uptime)) return uptime_seconds - - -def parse_fixed_width(text: str, *fields: int) -> List[Tuple[str, ...]]: - len = sum(fields) - fmtstring = " ".join(f"{fw}s" for fw in fields) - unpack = struct.Struct(fmtstring).unpack_from - - def parse(line: str) -> Tuple[str, ...]: - return tuple([str(s.decode()) for s in unpack(line.ljust(len).encode())]) - - return [parse(s) for s in text.splitlines()] diff --git a/napalm/eos/eos.py b/napalm/eos/eos.py index d5554f434..b38ae4e7d 100644 --- a/napalm/eos/eos.py +++ b/napalm/eos/eos.py @@ -23,12 +23,15 @@ import time import importlib import inspect -import ipaddress import json import socket from datetime import datetime from collections import defaultdict +from netaddr import IPAddress +from netaddr import IPNetwork + +from netaddr.core import AddrFormatError # third party libs import pyeapi @@ -37,7 +40,6 @@ # NAPALM base import napalm.base.helpers -from napalm.base.netmiko_helpers import netmiko_args from napalm.base.base import NetworkDriver from napalm.base.utils import string_parsers from napalm.base.exceptions import ( @@ -96,12 +98,9 @@ def __init__(self, hostname, username, password, timeout=60, optional_args=None) Optional args: * lock_disable (True/False): force configuration lock to be disabled (for external lock management). - * force_cfg_session_invalid (True/False): force invalidation of the config session - in case of failure. * enable_password (True/False): Enable password for privilege elevation * eos_autoComplete (True/False): Allow for shortening of cli commands - * transport (string): transport, eos_transport is a fallback for compatibility. - - ssh (uses Netmiko) + * transport (string): pyeapi transport, defaults to eos_transport if set - socket - http_local - http @@ -127,47 +126,45 @@ def __init__(self, hostname, username, password, timeout=60, optional_args=None) self.platform = "eos" self.profile = [self.platform] - self.optional_args = optional_args or {} - self.enablepwd = self.optional_args.pop("enable_password", "") - self.eos_autoComplete = self.optional_args.pop("eos_autoComplete", None) - self.fn0039_config = self.optional_args.pop("eos_fn0039_config", False) + self._process_optional_args(optional_args or {}) + def _process_optional_args(self, optional_args): # Define locking method - self.lock_disable = self.optional_args.pop("lock_disable", False) - - self.force_cfg_session_invalid = self.optional_args.pop( - "force_cfg_session_invalid", False - ) + self.lock_disable = optional_args.get("lock_disable", False) + self.enablepwd = optional_args.pop("enable_password", "") + self.eos_autoComplete = optional_args.pop("eos_autoComplete", None) # eos_transport is there for backwards compatibility, transport is the preferred method - transport = self.optional_args.get( - "transport", self.optional_args.get("eos_transport", "https") + transport = optional_args.get( + "transport", optional_args.get("eos_transport", "https") ) + self.fn0039_config = optional_args.pop("eos_fn0039_config", False) self.transport = transport + if transport == "ssh": + self.transport_class = "ssh" + init_args = ["port"] + else: + # Parse pyeapi transport class + self.transport_class = self._parse_transport(transport) + # ([1:]) to omit self + init_args = inspect.getfullargspec(self.transport_class.__init__)[0][1:] + + filter_args = ["host", "username", "password", "timeout", "lock_disable"] if transport == "ssh": - self._process_optional_args_ssh(self.optional_args) + self.netmiko_optional_args = { + k: v + for k, v in optional_args.items() + if k in init_args and k not in filter_args + } else: - self._process_optional_args_eapi(self.optional_args) - - def _process_optional_args_ssh(self, optional_args): - self.transport_class = None - self.netmiko_optional_args = netmiko_args(optional_args) - - def _process_optional_args_eapi(self, optional_args): - # Parse pyeapi transport class - self.transport_class = self._parse_transport(self.transport) - - # ([1:]) to omit self - init_args = inspect.getfullargspec(self.transport_class.__init__)[0][1:] - filter_args = ["host", "username", "password", "timeout"] - init_args.append("enforce_verification") # Not an arg for unknown reason - self.eapi_kwargs = { - k: v - for k, v in optional_args.items() - if k in init_args and k not in filter_args - } + init_args.append("enforce_verification") # Not an arg for unknown reason + self.eapi_kwargs = { + k: v + for k, v in optional_args.items() + if k in init_args and k not in filter_args + } def _parse_transport(self, transport): if inspect.isclass(transport) and issubclass(transport, EapiConnection): @@ -198,8 +195,7 @@ def open(self): """Implementation of NAPALM method open.""" if self.transport == "ssh": self.device = self._netmiko_open( - device_type="arista_eos", - netmiko_optional_args=self.netmiko_optional_args, + "arista_eos", netmiko_optional_args=self.netmiko_optional_args ) # let's try to determine if we need to use new EOS cli syntax sh_ver = self._run_commands(["show version"]) @@ -212,7 +208,7 @@ def open(self): username=self.username, password=self.password, timeout=self.timeout, - **self.eapi_kwargs, + **self.eapi_kwargs ) if self.device is None: @@ -235,9 +231,7 @@ def open(self): def close(self): """Implementation of NAPALM method close.""" self.discard_config() - if self.transport == "ssh": - self._netmiko_close() - elif hasattr(self.device.connection, "close") and callable( + if hasattr(self.device.connection, "close") and callable( self.device.connection.close ): self.device.connection.close() @@ -288,27 +282,6 @@ def _run_commands(self, commands, **kwargs): else: return self.device.run_commands(commands, **kwargs) - def _obtain_lock(self, wait_time=None): - """ - EOS internally creates config sessions when using commit-confirm. - - This can cause issues obtaining the configuration lock: - - cfg-2034--574620864-0 completed - cfg-2034--574620864-1 pending - """ - if wait_time: - start_time = time.time() - while time.time() - start_time < wait_time: - try: - self._lock() - return - except SessionLockedException: - time.sleep(1) - - # One last try - return self._lock() - def _lock(self): sess = self._run_commands(["show configuration sessions"])[0]["sessions"] if [ @@ -412,7 +385,7 @@ def _load_config(self, filename=None, config=None, replace=True): self.config_session = "napalm_{}".format(datetime.now().microsecond) if not self.lock_disable: - self._obtain_lock(wait_time=10) + self._lock() commands = [] commands.append("configure session {}".format(self.config_session)) @@ -457,7 +430,7 @@ def _load_config(self, filename=None, config=None, replace=True): return None try: - if not any(cmd == "end" for cmd in commands): + if not any(l == "end" for l in commands): commands.append("end") # exit config mode if self.eos_autoComplete is not None: self._run_commands( @@ -548,15 +521,13 @@ def confirm_commit(self): def discard_config(self): """Implementation of NAPALM method discard_config.""" if self.config_session is not None: - try: - commands = [f"configure session {self.config_session} abort"] - self._run_commands(commands, encoding="text") - except Exception: - # If discard fails, you might want to invalidate the config_session (esp. Salt) - # The config_session in EOS is used as the config lock. - if self.force_cfg_session_invalid: - self.config_session = None - raise + commands = ["configure session {}".format(self.config_session), "abort"] + if self.transport == "ssh": + # For some reason when testing with vEOS 4.26.1F this + # doesn't work with the normal wrapper. + self._run_commands(["", commands[0]]) + else: + self.device.run_commands(commands) self.config_session = None def rollback(self): @@ -685,13 +656,13 @@ def get_interfaces_counters(self): def get_bgp_neighbors(self): def get_re_group(res, key, default=None): - """Small helper to retrieve data from re match groups""" + """Small helper to retrive data from re match groups""" try: return res.group(key) except KeyError: return default - NEIGHBOR_FILTER = "bgp neighbors vrf all | include IPv[46] (Unicast|6PE):.*[0-9]+ | grep -v ' IPv[46] Unicast:/.' | remote AS |^Local AS|Desc|BGP state |remote router ID" # noqa + NEIGHBOR_FILTER = "bgp neighbors vrf all | include remote AS | remote router ID |IPv[46] (Unicast|6PE):.*[0-9]+|^Local AS|Desc|BGP state" # noqa output_summary_cmds = self._run_commands( ["show ipv6 bgp summary vrf all", "show ip bgp summary vrf all"], encoding="json", @@ -1006,7 +977,6 @@ def get_bgp_config(self, group="", neighbor=""): "local-v4-addr": "local_address", "local-v6-addr": "local_address", "local-as": "local_as", - "next-hop-self": "nhs", "description": "description", "import-policy": "import_policy", "export-policy": "export_policy", @@ -1064,7 +1034,7 @@ def default_group_dict(local_as): ) # few more default values return group_dict - def default_neighbor_dict(local_as, group_dict): + def default_neighbor_dict(local_as): neighbor_dict = {} neighbor_dict.update( { @@ -1075,13 +1045,6 @@ def default_neighbor_dict(local_as, group_dict): neighbor_dict.update( {"prefix_limit": {}, "local_as": local_as, "authentication_key": ""} ) # few more default values - neighbor_dict.update( - { - key: group_dict.get(key) - for key in _GROUP_FIELD_MAP_.values() - if key in group_dict and key in _PEER_FIELD_MAP_.values() - } - ) # copy in values from group dict if present return neighbor_dict def parse_options(options, default_value=False): @@ -1169,23 +1132,17 @@ def parse_options(options, default_value=False): # will try to parse the neighbor name # which sometimes is the IP Address of the neigbor # or the name of the BGP group - ipaddress.ip_address(group_or_neighbor) + IPAddress(group_or_neighbor) # if passes the test => it is an IP Address, thus a Neighbor! peer_address = group_or_neighbor - group_name = None + if peer_address not in bgp_neighbors: + bgp_neighbors[peer_address] = default_neighbor_dict(local_as) if options[0] == "peer-group": - group_name = options[1] + bgp_neighbors[peer_address]["__group"] = options[1] # EOS > 4.23.0 only supports the new syntax # https://www.arista.com/en/support/advisories-notices/fieldnotices/7097-field-notice-39 elif options[0] == "peer" and options[1] == "group": - group_name = options[2] - if peer_address not in bgp_neighbors: - bgp_neighbors[peer_address] = default_neighbor_dict( - local_as, bgp_config.get(group_name, {}) - ) - - if group_name: - bgp_neighbors[peer_address]["__group"] = group_name + bgp_neighbors[peer_address]["__group"] = options[2] # in the config, neighbor details are lister after # the group is specified for the neighbor: @@ -1203,7 +1160,7 @@ def parse_options(options, default_value=False): bgp_neighbors[peer_address].update( parse_options(options, default_value) ) - except ValueError: + except AddrFormatError: # exception trying to parse group name # group_or_neighbor represents the name of the group group_name = group_or_neighbor @@ -1213,8 +1170,6 @@ def parse_options(options, default_value=False): bgp_config[group_name] = default_group_dict(local_as) bgp_config[group_name].update(parse_options(options, default_value)) - bgp_config["_"] = default_group_dict(local_as) - for peer, peer_details in bgp_neighbors.items(): peer_group = peer_details.pop("__group", None) if not peer_group: @@ -1223,14 +1178,6 @@ def parse_options(options, default_value=False): bgp_config[peer_group] = default_group_dict(local_as) bgp_config[peer_group]["neighbors"][peer] = peer_details - [ - v.pop("nhs", None) for v in bgp_config.values() - ] # remove NHS from group-level dictionary - - if local_as == 0: - # BGP not running - return {} - return bgp_config def get_arp_table(self, vrf=""): @@ -1476,7 +1423,7 @@ def get_route_to(self, destination="", protocol="", longer=False): protocol = "connected" ipv = "" - if ipaddress.ip_network(destination).version == 6: + if IPNetwork(destination).version == 6: ipv = "v6" commands = [] @@ -1583,7 +1530,7 @@ def get_route_to(self, destination="", protocol="", longer=False): .get("peerEntry", {}) .get("peerAddr", "") ) - except ValueError: + except AddrFormatError: remote_address = napalm.base.helpers.ip( bgp_route_details.get("peerEntry", {}).get( "peerAddr", "" @@ -1962,7 +1909,7 @@ def _append(bgp_dict, peer_info): summary_commands.append("show ipv6 bgp summary vrf all") else: try: - peer_ver = ipaddress.ip_address(neighbor_address).version + peer_ver = IPAddress(neighbor_address).version except Exception as e: raise e @@ -2130,59 +2077,15 @@ def get_config(self, retrieve="all", full=False, sanitized=False): else: raise Exception("Wrong retrieve filter: {}".format(retrieve)) - def _show_vrf_json(self): - commands = ["show vrf"] - - vrfs = self._run_commands(commands)[0]["vrfs"] - return [ - { - "name": k, - "interfaces": [i for i in v["interfaces"]], - "route_distinguisher": v["routeDistinguisher"], - } - for k, v in vrfs.items() - ] - - def _show_vrf_text(self): + def _show_vrf(self): commands = ["show vrf"] - # This command has no JSON in EOS < 4.23 + # This command has no JSON yet raw_output = self._run_commands(commands, encoding="text")[0].get("output", "") - width_line = raw_output.splitlines()[2] # Line with dashes - fields = width_line.split(" ") - widths = [len(f) + 1 for f in fields] - widths[-1] -= 1 - - parsed_lines = string_parsers.parse_fixed_width(raw_output, *widths) - - vrfs = [] - vrf = {} - current_vrf = None - for line in parsed_lines[3:]: - line = [t.strip() for t in line] - if line[0]: - if current_vrf: - vrfs.append(vrf) - current_vrf = line[0] - vrf = { - "name": current_vrf, - "interfaces": list(), - } - if line[1]: - vrf["route_distinguisher"] = line[1] - if line[4]: - vrf["interfaces"].extend([t.strip() for t in line[4].split(",") if t]) - if current_vrf: - vrfs.append(vrf) - - return vrfs + output = napalm.base.helpers.textfsm_extractor(self, "vrf", raw_output) - def _show_vrf(self): - if self.cli_version == 2: - return self._show_vrf_json() - else: - return self._show_vrf_text() + return output def _get_vrfs(self): output = self._show_vrf() @@ -2215,26 +2118,23 @@ def get_network_instances(self, name=""): interfaces[str(line.strip())] = {} all_vrf_interfaces[str(line.strip())] = {} - vrfs[vrf["name"]] = { - "name": vrf["name"], - "type": "DEFAULT_INSTANCE" if vrf["name"] == "default" else "L3VRF", + vrfs[str(vrf["name"])] = { + "name": str(vrf["name"]), + "type": "L3VRF", "state": {"route_distinguisher": vrf["route_distinguisher"]}, "interfaces": {"interface": interfaces}, } - if "default" not in vrfs: - all_interfaces = self.get_interfaces_ip().keys() - vrfs["default"] = { - "name": "default", - "type": "DEFAULT_INSTANCE", - "state": {"route_distinguisher": ""}, - "interfaces": { - "interface": { - k: {} - for k in all_interfaces - if k not in all_vrf_interfaces.keys() - } - }, - } + all_interfaces = self.get_interfaces_ip().keys() + vrfs["default"] = { + "name": "default", + "type": "DEFAULT_INSTANCE", + "state": {"route_distinguisher": ""}, + "interfaces": { + "interface": { + k: {} for k in all_interfaces if k not in all_vrf_interfaces.keys() + } + }, + } if name: if name in vrfs: diff --git a/napalm/ios/ios.py b/napalm/ios/ios.py index 5e31c49f8..59284a362 100644 --- a/napalm/ios/ios.py +++ b/napalm/ios/ios.py @@ -14,7 +14,6 @@ # the License. import copy import functools -import ipaddress import os import re import socket @@ -23,6 +22,8 @@ import uuid from collections import defaultdict +from netaddr import IPNetwork +from netaddr.core import AddrFormatError from netmiko import FileTransfer, InLineTransfer import napalm.base.constants as C @@ -36,17 +37,14 @@ CommitConfirmException, ) from napalm.base.helpers import ( + canonical_interface_name, transform_lldp_capab, textfsm_extractor, + split_interface, + abbreviated_interface_name, generate_regex_or, sanitize_configs, ) -from netaddr.core import AddrFormatError -from netutils.interface import ( - abbreviated_interface_name, - canonical_interface_name, - split_interface, -) from napalm.base.netmiko_helpers import netmiko_args # Easier to store these as constants @@ -483,10 +481,10 @@ def _commit_handler(self, cmd): # Handle special username removal pattern pattern2 = r".*all username.*confirm" patterns = rf"(?:{pattern1}|{pattern2})" - output = self.device.send_command(cmd, expect_string=patterns, read_timeout=90) + output = self.device.send_command(cmd, expect_string=patterns) loop_count = 50 new_output = output - for _ in range(loop_count): + for i in range(loop_count): if re.search(pattern2, new_output): # Send confirmation if username removal new_output = self.device.send_command_timing( @@ -987,26 +985,10 @@ def get_lldp_neighbors(self): hostname = lldp_entry["remote_system_name"] port = lldp_entry["remote_port"] # Match IOS behaviour of taking remote chassis ID - # when lacking a system name (in show lldp neighbors) - - # We can't assume remote_chassis_id or remote_port are MAC Addresses - # See IEEE 802.1AB-2005 and rfc2922, specifically PtopoChassisId + # When lacking a system name (in show lldp neighbors) if not hostname: - try: - hostname = napalm.base.helpers.mac( - lldp_entry["remote_chassis_id"] - ) - except AddrFormatError: - hostname = lldp_entry["remote_chassis_id"] - - # If port is a mac-address, normalize it. - # The MAC helper library will normalize "15" to "00:00:00:00:00:0F" - if port.count(":") == 5 or port.count("-") == 5 or port.count(".") == 2: - try: - port = napalm.base.helpers.mac(port) - except AddrFormatError: - pass - + hostname = napalm.base.helpers.mac(lldp_entry["remote_chassis_id"]) + port = napalm.base.helpers.mac(port) lldp_dict = {"port": port, "hostname": hostname} lldp[intf_name].append(lldp_dict) @@ -1463,11 +1445,6 @@ def build_prefix_limit(af_table, limit, prefix_percent, prefix_timeout): bgp_config_list = napalm.base.helpers.netutils_parse_objects( "router bgp", cfg["running"] ) - - # No BGP configuration - if not bgp_config_list: - return {} - bgp_asn = napalm.base.helpers.regex_find_txt( r"router bgp (\d+)", bgp_config_list, default=0 ) @@ -1538,9 +1515,7 @@ def build_prefix_limit(af_table, limit, prefix_percent, prefix_timeout): r" update-source (\w+)", neighbor_config ) local_as = napalm.base.helpers.regex_find_txt( - r"local-as (\d+)", - neighbor_config, - default=bgp_asn, + r"local-as (\d+)", neighbor_config, default=0 ) password = napalm.base.helpers.regex_find_txt( r"password (?:[0-9] )?([^\']+\')", neighbor_config @@ -1574,32 +1549,29 @@ def build_prefix_limit(af_table, limit, prefix_percent, prefix_timeout): "route_reflector_client": route_reflector_client, } - # Do not include the no-group ("_") if a group argument is passed in - # unless group argument is "_" - if not group or group == "_": - bgp_config["_"] = { - "apply_groups": [], - "description": "", - "local_as": bgp_asn, - "type": "", - "import_policy": "", - "export_policy": "", - "local_address": "", - "multipath": False, - "multihop_ttl": 0, - "remote_as": 0, - "remove_private_as": False, - "prefix_limit": {}, - "neighbors": bgp_group_neighbors.get("_", {}), - } - # Get the peer-group level config for each group for group_name in bgp_group_neighbors.keys(): # If a group is passed in params, only continue on that group if group: if group_name != group: continue + # Default no group if group_name == "_": + bgp_config["_"] = { + "apply_groups": [], + "description": "", + "local_as": 0, + "type": "", + "import_policy": "", + "export_policy": "", + "local_address": "", + "multipath": False, + "multihop_ttl": 0, + "remote_as": 0, + "remove_private_as": False, + "prefix_limit": {}, + "neighbors": bgp_group_neighbors.get("_", {}), + } continue neighbor_config = napalm.base.helpers.netutils_parse_objects( group_name, bgp_config_list @@ -1621,7 +1593,7 @@ def build_prefix_limit(af_table, limit, prefix_percent, prefix_timeout): r" description ([^\']+)\'", neighbor_config ) local_as = napalm.base.helpers.regex_find_txt( - r"local-as (\d+)", neighbor_config, default=bgp_asn + r"local-as (\d+)", neighbor_config, default=0 ) import_policy = napalm.base.helpers.regex_find_txt( r"route-map ([^\s]+) in", neighbor_config @@ -3033,7 +3005,7 @@ def _get_bgp_route_attr(self, destination, vrf, next_hop, ip_version=4): # next-hop is not known in this vrf, route leaked from # other vrf or from vpnv4 table? # get remote AS nr. from as-path if it is ebgp neighbor - # locally sourced prefix is not in routing table as a bgp route (i hope...) + # localy sourced prefix is not in routing table as a bgp route (i hope...) if search_re_dict["bgpie"]["result"] == "external": bgpras = ( search_re_dict["aspath"]["result"] @@ -3102,8 +3074,8 @@ def get_route_to(self, destination="", protocol="", longer=False): vrf = "" ip_version = None try: - ip_version = ipaddress.ip_network(destination).version - except ValueError: + ip_version = IPNetwork(destination).version + except AddrFormatError: return "Please specify a valid destination!" if ip_version == 4: # process IPv4 routing table if vrf == "": @@ -3111,8 +3083,8 @@ def get_route_to(self, destination="", protocol="", longer=False): else: vrfs = [vrf] # VRFs where IPv4 is enabled vrfs.append("default") # global VRF - ipnet_dest = ipaddress.ip_network(destination) - prefix = str(ipnet_dest.network_address) + ipnet_dest = IPNetwork(destination) + prefix = str(ipnet_dest.network) netmask = "" routes = {} if "/" in destination: diff --git a/napalm/iosxr/iosxr.py b/napalm/iosxr/iosxr.py index 383e8ae00..e8e4e5921 100644 --- a/napalm/iosxr/iosxr.py +++ b/napalm/iosxr/iosxr.py @@ -16,13 +16,15 @@ # import stdlib import re import copy -import ipaddress from collections import defaultdict import logging # import third party lib from lxml import etree as ETREE +from netaddr import IPAddress # needed for traceroute, to check IP version +from netaddr.core import AddrFormatError + from napalm.pyIOSXR import IOSXR from napalm.pyIOSXR.exceptions import ConnectError from napalm.pyIOSXR.exceptions import TimeoutError @@ -987,22 +989,6 @@ def build_prefix_limit(af_table, limit, prefix_percent, prefix_timeout): default" result_tree = ETREE.fromstring(self.device.make_rpc_call(rpc_command)) - # Check if BGP is not configured. - get_tag = result_tree.find("./Get") - if get_tag is not None: - bgp_not_found = get_tag.attrib.get("ItemNotFound") - if bgp_not_found: - return {} - - bgp_asn = napalm.base.helpers.convert( - int, - napalm.base.helpers.find_txt( - result_tree, - "Get/Configuration/BGP/Instance[1]/InstanceAS/FourByteAS/Naming/AS", - ), - 0, - ) - if not group: neighbor = "" @@ -1026,9 +1012,7 @@ def build_prefix_limit(af_table, limit, prefix_percent, prefix_timeout): int, napalm.base.helpers.find_txt(bgp_neighbor, "RemoteAS/AS_YY"), 0 ) local_as = napalm.base.helpers.convert( - int, - napalm.base.helpers.find_txt(bgp_neighbor, "LocalAS/AS_YY"), - bgp_asn, + int, napalm.base.helpers.find_txt(bgp_neighbor, "LocalAS/AS_YY"), 0 ) af_table = napalm.base.helpers.find_txt( bgp_neighbor, "NeighborAFTable/NeighborAF/Naming/AFName" @@ -1120,7 +1104,7 @@ def build_prefix_limit(af_table, limit, prefix_percent, prefix_timeout): int, napalm.base.helpers.find_txt(bgp_group, "RemoteAS/AS_YY"), 0 ) local_as = napalm.base.helpers.convert( - int, napalm.base.helpers.find_txt(bgp_group, "LocalAS/AS_YY"), bgp_asn + int, napalm.base.helpers.find_txt(bgp_group, "LocalAS/AS_YY"), 0 ) multihop_ttl = napalm.base.helpers.convert( int, @@ -1182,22 +1166,22 @@ def build_prefix_limit(af_table, limit, prefix_percent, prefix_timeout): } if group and group == group_name: break - - bgp_config["_"] = { - "apply_groups": [], - "description": "", - "local_as": bgp_asn, - "type": "", - "import_policy": "", - "export_policy": "", - "local_address": "", - "multipath": False, - "multihop_ttl": 0, - "remote_as": 0, - "remove_private_as": False, - "prefix_limit": {}, - "neighbors": bgp_group_neighbors.get("", {}), - } + if "" in bgp_group_neighbors.keys(): + bgp_config["_"] = { + "apply_groups": [], + "description": "", + "local_as": 0, + "type": "", + "import_policy": "", + "export_policy": "", + "local_address": "", + "multipath": False, + "multihop_ttl": 0, + "remote_as": 0, + "remove_private_as": False, + "prefix_limit": {}, + "neighbors": bgp_group_neighbors.get("", {}), + } return bgp_config @@ -1749,8 +1733,8 @@ def get_route_to(self, destination="", protocol="", longer=False): ipv = 4 try: - ipv = ipaddress.ip_address(network).version - except ValueError: + ipv = IPAddress(network).version + except AddrFormatError: logger.error("Wrong destination IP Address format supplied to get_route_to") raise TypeError("Wrong destination IP Address!") @@ -2203,8 +2187,8 @@ def traceroute( ipv = 4 try: - ipv = ipaddress.ip_address(destination).version - except ValueError: + ipv = IPAddress(destination).version + except AddrFormatError: logger.error( "Incorrect format of IP Address in traceroute \ with value provided:%s" diff --git a/napalm/iosxr_netconf/iosxr_netconf.py b/napalm/iosxr_netconf/iosxr_netconf.py index ff7a06ef8..656078880 100644 --- a/napalm/iosxr_netconf/iosxr_netconf.py +++ b/napalm/iosxr_netconf/iosxr_netconf.py @@ -22,7 +22,6 @@ import re import copy import difflib -import ipaddress import logging # import third party lib @@ -32,6 +31,8 @@ from ncclient.operations.errors import TimeoutExpiredError from lxml import etree as ETREE from lxml.etree import XMLSyntaxError +from netaddr import IPAddress # needed for traceroute, to check IP version +from netaddr.core import AddrFormatError # import NAPALM base from napalm.iosxr_netconf import constants as C @@ -1366,25 +1367,9 @@ def build_prefix_limit(af_table, limit, prefix_percent, prefix_timeout): # Converts string to etree result_tree = ETREE.fromstring(rpc_reply) - data_ele = result_tree.find("./{*}data") - # If there are no children in "", then there is no BGP configured - bgp_configured = bool(len(data_ele.getchildren())) - if not bgp_configured: - return {} - if not group: neighbor = "" - bgp_asn = napalm.base.helpers.convert( - int, - self._find_txt( - result_tree, - ".//bgpc:bgp/bgpc:instance/bgpc:instance-as/bgpc:four-byte-as/bgpc:as", - default=0, - namespaces=C.NS, - ), - ) - bgp_group_neighbors = {} bgp_neighbor_xpath = ".//bgpc:bgp/bgpc:instance/bgpc:instance-as/\ bgpc:four-byte-as/bgpc:default-vrf/bgpc:bgp-entity/bgpc:neighbors/bgpc:neighbor" @@ -1446,7 +1431,7 @@ def build_prefix_limit(af_table, limit, prefix_percent, prefix_timeout): ), 0, ) - local_as = (local_as_x * 65536 + local_as_y) or bgp_asn + local_as = local_as_x * 65536 + local_as_y af_table = self._find_txt( bgp_neighbor, "./bgpc:neighbor-afs/bgpc:neighbor-af/bgpc:af-name", @@ -1613,7 +1598,7 @@ def build_prefix_limit(af_table, limit, prefix_percent, prefix_timeout): ), 0, ) - local_as = (local_as_x * 65536 + local_as_y) or bgp_asn + local_as = local_as_x * 65536 + local_as_y multihop_ttl = napalm.base.helpers.convert( int, self._find_txt( @@ -1695,22 +1680,22 @@ def build_prefix_limit(af_table, limit, prefix_percent, prefix_timeout): } if group and group == group_name: break - - bgp_config["_"] = { - "apply_groups": [], - "description": "", - "local_as": bgp_asn, - "type": "", - "import_policy": "", - "export_policy": "", - "local_address": "", - "multipath": False, - "multihop_ttl": 0, - "remote_as": 0, - "remove_private_as": False, - "prefix_limit": {}, - "neighbors": bgp_group_neighbors.get("", {}), - } + if "" in bgp_group_neighbors.keys(): + bgp_config["_"] = { + "apply_groups": [], + "description": "", + "local_as": 0, + "type": "", + "import_policy": "", + "export_policy": "", + "local_address": "", + "multipath": False, + "multihop_ttl": 0, + "remote_as": 0, + "remove_private_as": False, + "prefix_limit": {}, + "neighbors": bgp_group_neighbors.get("", {}), + } return bgp_config @@ -2496,8 +2481,8 @@ def get_route_to(self, destination="", protocol="", longer=False): ipv = 4 try: - ipv = ipaddress.ip_address(network).version - except ValueError: + ipv = IPAddress(network).version + except AddrFormatError: logger.error("Wrong destination IP Address format supplied to get_route_to") raise TypeError("Wrong destination IP Address!") @@ -2967,8 +2952,8 @@ def traceroute( ipv = 4 try: - ipv = ipaddress.ip_address(destination).version - except ValueError: + ipv = IPAddress(destination).version + except AddrFormatError: logger.error( "Incorrect format of IP Address in traceroute \ with value provided:%s" @@ -3154,7 +3139,7 @@ def get_config(self, retrieve="all", full=False, sanitized=False): if config[datastore] != "": if encoding == "cli": cli_tree = ETREE.XML(config[datastore], parser=parser)[0] - if len(cli_tree): + if cli_tree: config[datastore] = cli_tree[0].text.strip() else: config[datastore] = "" diff --git a/napalm/junos/junos.py b/napalm/junos/junos.py index 74b6e5efe..d274dac91 100644 --- a/napalm/junos/junos.py +++ b/napalm/junos/junos.py @@ -176,10 +176,10 @@ def _unlock(self): def _rpc(self, get, child=None, **kwargs): """ - This allows you to construct an arbitrary RPC call to retrieve common stuff. For example: + This allows you to construct an arbitrary RPC call to retreive common stuff. For example: Configuration: get: "" Interface information: get: "" - A particular interface information: + A particular interfacece information: get: "" child: "ge-0/0/0" """ @@ -1169,7 +1169,7 @@ def update_dict(d, u): # for deep dictionary update def build_prefix_limit(**args): """ - Transform the elements of a dictionary into nested dictionaries. + Transform the lements of a dictionary into nested dictionaries. Example: { @@ -1250,40 +1250,13 @@ def build_prefix_limit(**args): bgp_config = {} - routing_options = junos_views.junos_routing_config_table(self.device) - routing_options.get(options=self.junos_config_options) - - bgp_asn_obj = routing_options.xml.find( - "./routing-options/autonomous-system/as-number" - ) - system_bgp_asn = int(bgp_asn_obj.text) if bgp_asn_obj is not None else 0 - - # No BGP peer-group i.e. "_" key is a special case. - if group and group != "_": + if group: bgp = junos_views.junos_bgp_config_group_table(self.device) bgp.get(group=group, options=self.junos_config_options) else: bgp = junos_views.junos_bgp_config_table(self.device) bgp.get(options=self.junos_config_options) neighbor = "" # if no group is set, no neighbor should be set either - - # Only set no peer-group if BGP is actually configured. - if bgp.items() or system_bgp_asn: - bgp_config["_"] = { - "apply_groups": [], - "description": "", - "local_as": system_bgp_asn, - "type": "", - "import_policy": "", - "export_policy": "", - "local_address": "", - "multipath": False, - "multihop_ttl": 0, - "remote_as": 0, - "remove_private_as": False, - "prefix_limit": {}, - "neighbors": {}, - } bgp_items = bgp.items() if neighbor: @@ -1310,17 +1283,13 @@ def build_prefix_limit(**args): for field, datatype in _GROUP_FIELDS_DATATYPE_MAP_.items() if "_prefix_limit" not in field } - - # Always overwrite with the system local_as (this will either be - # valid or will be zero i.e. the same as the default value). - bgp_config[bgp_group_name]["local_as"] = system_bgp_asn - - for key, value in bgp_group_details: - if "_prefix_limit" in key or value is None: + for elem in bgp_group_details: + if not ("_prefix_limit" not in elem[0] and elem[1] is not None): continue - datatype = _GROUP_FIELDS_DATATYPE_MAP_.get(key) + datatype = _GROUP_FIELDS_DATATYPE_MAP_.get(elem[0]) default = _DATATYPE_DEFAULT_.get(datatype) - + key = elem[0] + value = elem[1] if key in ["export_policy", "import_policy"]: if isinstance(value, list): value = " ".join(value) @@ -1328,10 +1297,6 @@ def build_prefix_limit(**args): value = napalm.base.helpers.convert( napalm.base.helpers.ip, value, value ) - if key == "apply_groups": - # Ensure apply_groups value is wrapped in a list - if isinstance(value, str): - value = [value] if key == "neighbors": bgp_group_peers = value continue @@ -1339,15 +1304,15 @@ def build_prefix_limit(**args): {key: napalm.base.helpers.convert(datatype, value, default)} ) prefix_limit_fields = {} - for key, value in bgp_group_details: - if "_prefix_limit" in key and value is not None: - datatype = _GROUP_FIELDS_DATATYPE_MAP_.get(key) + for elem in bgp_group_details: + if "_prefix_limit" in elem[0] and elem[1] is not None: + datatype = _GROUP_FIELDS_DATATYPE_MAP_.get(elem[0]) default = _DATATYPE_DEFAULT_.get(datatype) prefix_limit_fields.update( { - key.replace( + elem[0].replace( "_prefix_limit", "" - ): napalm.base.helpers.convert(datatype, value, default) + ): napalm.base.helpers.convert(datatype, elem[1], default) } ) bgp_config[bgp_group_name]["prefix_limit"] = build_prefix_limit( @@ -1361,31 +1326,23 @@ def build_prefix_limit(**args): bgp_config[bgp_group_name]["multihop_ttl"] = 64 bgp_config[bgp_group_name]["neighbors"] = {} - bgp_group_remote_as = bgp_config[bgp_group_name]["remote_as"] for bgp_group_neighbor in bgp_group_peers.items(): bgp_peer_address = napalm.base.helpers.ip(bgp_group_neighbor[0]) if neighbor and bgp_peer_address != neighbor: continue # if filters applied, jump over all other neighbors bgp_group_details = bgp_group_neighbor[1] - - # Set defaults for this BGP peer bgp_peer_details = { field: _DATATYPE_DEFAULT_.get(datatype) for field, datatype in _PEER_FIELDS_DATATYPE_MAP_.items() if "_prefix_limit" not in field } - - # Always overwrite with the system local_as (this will either be - # valid or will be zero i.e. the same as the default value). - bgp_peer_details["local_as"] = system_bgp_asn - # Always set the default remote-as as the Peer-Group remote-as - bgp_peer_details["remote_as"] = bgp_group_remote_as - - for key, value in bgp_group_details: - if "_prefix_limit" in key or value is None: + for elem in bgp_group_details: + if not ("_prefix_limit" not in elem[0] and elem[1] is not None): continue - datatype = _PEER_FIELDS_DATATYPE_MAP_.get(key) + datatype = _PEER_FIELDS_DATATYPE_MAP_.get(elem[0]) default = _DATATYPE_DEFAULT_.get(datatype) + key = elem[0] + value = elem[1] if key in ["export_policy"]: # next-hop self is applied on export IBGP sessions bgp_peer_details["nhs"] = _check_nhs(value, nhs_policies) @@ -1413,15 +1370,17 @@ def build_prefix_limit(**args): if "cluster" in bgp_config[bgp_group_name].keys(): bgp_peer_details["route_reflector_client"] = True prefix_limit_fields = {} - for key, value in bgp_group_details: - if "_prefix_limit" in key and value is not None: - datatype = _PEER_FIELDS_DATATYPE_MAP_.get(key) + for elem in bgp_group_details: + if "_prefix_limit" in elem[0] and elem[1] is not None: + datatype = _PEER_FIELDS_DATATYPE_MAP_.get(elem[0]) default = _DATATYPE_DEFAULT_.get(datatype) prefix_limit_fields.update( { - key.replace( + elem[0].replace( "_prefix_limit", "" - ): napalm.base.helpers.convert(datatype, value, default) + ): napalm.base.helpers.convert( + datatype, elem[1], default + ) } ) bgp_peer_details["prefix_limit"] = build_prefix_limit( @@ -1865,7 +1824,7 @@ def get_route_to(self, destination="", protocol="", longer=False): try: routes_table.get(**rt_kargs) except RpcTimeoutError: - # on devices with millions of routes + # on devices with milions of routes # in case the destination is too generic (e.g.: 10/8) # will take very very long to determine all routes and # moreover will return a huge list diff --git a/napalm/junos/utils/junos_views.yml b/napalm/junos/utils/junos_views.yml index 3fd60b1f4..5d81ae2fc 100644 --- a/napalm/junos/utils/junos_views.yml +++ b/napalm/junos/utils/junos_views.yml @@ -402,15 +402,6 @@ junos_bgp_config_peers_view: inet6_flow_teardown_timeout_prefix_limit: {family/inet6/flow/prefix-limit/teardown/idle-timeout/timeout: int} inet6_flow_novalidate_prefix_limit: {family/inet6/flow/prefix-limit/no-validate: unicode} -junos_routing_config_table: - get: "routing-options/autonomous-system" - view: junos_routing_config_view - -junos_routing_config_view: - fields: - local_system_as: autonomous-system - - #### #### BGP Neighbors and Routing Tables Stats #### diff --git a/napalm/nxos/nxos.py b/napalm/nxos/nxos.py index 9668569ff..d857832e4 100644 --- a/napalm/nxos/nxos.py +++ b/napalm/nxos/nxos.py @@ -13,7 +13,6 @@ # License for the specific language governing permissions and limitations under # the License. -import ipaddress import json import os import re @@ -43,10 +42,11 @@ DefaultDict, ) +from netaddr import IPAddress +from netaddr.core import AddrFormatError from netmiko import file_transfer from requests.exceptions import ConnectionError from netutils.config.compliance import diff_network_config -from netutils.interface import canonical_interface_name import napalm.base.constants as c @@ -233,7 +233,7 @@ def _get_merge_diff(self) -> str: interface loopback0 ip address 10.1.4.5/32 """ - running_config = self.get_config(retrieve="running", full=True)["running"] + running_config = self.get_config(retrieve="running")["running"] return diff_network_config(self.merge_candidate, running_config, "cisco_nxos") def _get_diff(self) -> str: @@ -356,8 +356,8 @@ def ping( version = "" try: - version = "6" if ipaddress.ip_address(destination).version == 6 else "" - except ValueError: + version = "6" if IPAddress(destination).version == 6 else "" + except AddrFormatError: # Allow use of DNS names pass @@ -470,8 +470,8 @@ def traceroute( version = "" try: - version = "6" if ipaddress.ip_address(destination).version == 6 else "" - except ValueError: + version = "6" if IPAddress(destination).version == 6 else "" + except AddrFormatError: # Allow use of DNS names pass @@ -683,7 +683,7 @@ def get_lldp_neighbors_detail( lldp_entry["remote_system_enable_capab"] ) # Turn the interfaces into their long version - local_intf = canonical_interface_name(local_intf) + local_intf = napalm.base.helpers.canonical_interface_name(local_intf) lldp.setdefault(local_intf, []) lldp[local_intf].append(lldp_entry) # type: ignore @@ -739,9 +739,13 @@ def _parse_vlan_ports(self, vlan_s: Union[str, List]) -> List: find = re.findall(find_regexp, vls.strip()) if find: for i in range(int(find[0][1]), int(find[0][2]) + 1): - vlans.append(canonical_interface_name(find[0][0] + str(i))) + vlans.append( + napalm.base.helpers.canonical_interface_name( + find[0][0] + str(i) + ) + ) else: - vlans.append(canonical_interface_name(vls.strip())) + vlans.append(napalm.base.helpers.canonical_interface_name(vls.strip())) return vlans @abstractmethod diff --git a/napalm/nxos_ssh/nxos_ssh.py b/napalm/nxos_ssh/nxos_ssh.py index bdb01f5a9..01147d0e6 100644 --- a/napalm/nxos_ssh/nxos_ssh.py +++ b/napalm/nxos_ssh/nxos_ssh.py @@ -15,13 +15,12 @@ # import stdlib from builtins import super -import ipaddress import re import socket -from collections import defaultdict -# import external lib -from netutils.interface import canonical_interface_name +# import third party lib +from netaddr import IPAddress, IPNetwork +from netaddr.core import AddrFormatError # import NAPALM Base from napalm.base import helpers @@ -119,7 +118,7 @@ def parse_intf_section(interface): else: # More standard is up, next line admin state is lines match = re.search(re_intf_name_state, interface) - intf_name = canonical_interface_name(match.group("intf_name")) + intf_name = helpers.canonical_interface_name(match.group("intf_name")) intf_state = match.group("intf_state").strip() is_up = True if intf_state == "up" else False @@ -457,15 +456,21 @@ def _send_command(self, command, raw_text=False, cmd_verify=True): """ return self.device.send_command(command, cmd_verify=cmd_verify) - def _send_command_list(self, commands, expect_string=None, **kwargs): - """Send a list of commands using Netmiko""" - return self.device.send_multiline( - commands, expect_string=expect_string, **kwargs - ) + def _send_command_list(self, commands, expect_string=None): + """Wrapper for Netmiko's send_command method (for list of commands.""" + output = "" + for command in commands: + output += self.device.send_command( + command, + strip_prompt=False, + strip_command=False, + expect_string=expect_string, + ) + return output def _send_config(self, commands): if isinstance(commands, str): - commands = [command for command in commands.splitlines() if command] + commands = (command for command in commands.splitlines() if command) return self.device.send_config_set(commands) @staticmethod @@ -519,6 +524,7 @@ def is_alive(self): return {"is_alive": self.device.remote_conn.transport.is_active()} def _copy_run_start(self): + output = self.device.save_config() if "complete" in output.lower(): return True @@ -527,6 +533,7 @@ def _copy_run_start(self): raise CommandErrorException(msg) def _load_cfg_from_checkpoint(self): + commands = [ "terminal dont-ask", "rollback running-config file {}".format(self.candidate_cfg), @@ -534,9 +541,7 @@ def _load_cfg_from_checkpoint(self): ] try: - rollback_result = self._send_command_list( - commands, expect_string=r"[#>]", read_timeout=90 - ) + rollback_result = self._send_command_list(commands, expect_string=r"[#>]") finally: self.changed = True msg = rollback_result @@ -550,9 +555,7 @@ def rollback(self): "rollback running-config file {}".format(self.rollback_cfg), "no terminal dont-ask", ] - result = self._send_command_list( - commands, expect_string=r"[#>]", read_timeout=90 - ) + result = self._send_command_list(commands, expect_string=r"[#>]") if "completed" not in result.lower(): raise ReplaceConfigException(result) # If hostname changes ensure Netmiko state is updated properly @@ -656,7 +659,7 @@ def get_facts(self): continue interface = line.split()[0] # Return canonical interface name - interface_list.append(canonical_interface_name(interface)) + interface_list.append(helpers.canonical_interface_name(interface)) return { "uptime": float(uptime), @@ -796,61 +799,6 @@ def cli(self, commands, encoding="text"): cli_output[str(command)] = output return cli_output - def get_network_instances(self, name=""): - """ - get_network_instances implementation for NX-OS - """ - - # command 'show vrf detail | json' returns all VRFs with detailed information in JSON format - # format: list of dictionaries with keys such as 'vrf_name' and 'rd' - vrf_table_raw = self._get_command_table( - "show vrf detail | json", "TABLE_vrf", "ROW_vrf" - ) - - # command 'show vrf interface' returns all interfaces including their assigned VRF - # format: list of dictionaries with keys 'if_name', 'vrf_name', 'vrf_id' and 'soo' - intf_table_raw = self._get_command_table( - "show vrf interface | json", "TABLE_if", "ROW_if" - ) - - # create a dictionary with key = 'vrf_name' and value = list of interfaces - vrf_intfs = defaultdict(list) - for intf in intf_table_raw: - vrf_intfs[intf["vrf_name"]].append(str(intf["if_name"])) - - vrfs = {} - for vrf in vrf_table_raw: - vrf_name = str(vrf.get("vrf_name")) - vrfs[vrf_name] = {} - vrfs[vrf_name]["name"] = vrf_name - - # differentiate between VRF type 'DEFAULT_INSTANCE' and 'L3VRF' - if vrf_name == "default": - vrfs[vrf_name]["type"] = "DEFAULT_INSTANCE" - else: - vrfs[vrf_name]["type"] = "L3VRF" - - vrfs[vrf_name]["state"] = {"route_distinguisher": str(vrf.get("rd"))} - - # convert list of interfaces (vrf_intfs[vrf_name]) to expected format - # format = dict with key = interface name and empty values - vrfs[vrf_name]["interfaces"] = {} - vrfs[vrf_name]["interfaces"]["interface"] = dict.fromkeys( - vrf_intfs[vrf_name], {} - ) - - # if name of a specific VRF was passed as an argument - # only return results for this particular VRF - - if name: - if name in vrfs.keys(): - return {str(name): vrfs[name]} - else: - return {} - # else return results for all VRFs - else: - return vrfs - def get_environment(self): """ Get environment facts. @@ -1005,7 +953,7 @@ def _get_ntp_entity(self, peer_type): # Skip first two lines and last line of command output if line == "" or "-----" in line or "Peer IP Address" in line: continue - elif not ipaddress.ip_address(len(line.split()[0])).is_multicast: + elif IPAddress(len(line.split()[0])).is_unicast: peer_addr = line.split()[0] ntp_entities[peer_addr] = {} else: @@ -1191,7 +1139,7 @@ def process_mac_fields(vlan, mac, mac_type, interface): active = False return { "mac": helpers.mac(mac), - "interface": canonical_interface_name(interface), + "interface": helpers.canonical_interface_name(interface), "vlan": int(vlan), "static": static, "active": active, @@ -1210,6 +1158,7 @@ def process_mac_fields(vlan, mac, mac_type, interface): output = re.sub(r"vPC Peer-Link", "vPC-Peer-Link", output, flags=re.M) for line in output.splitlines(): + # Every 500 Mac's Legend is reprinted, regardless of terminal length if re.search(r"^Legend", line): continue @@ -1391,8 +1340,8 @@ def get_route_to(self, destination="", protocol="", longer=False): ip_version = None try: - ip_version = ipaddress.ip_network(destination).version - except ValueError: + ip_version = IPNetwork(destination).version + except AddrFormatError: return "Please specify a valid destination!" if ip_version == 4: # process IPv4 routing table routes = {} @@ -1460,7 +1409,7 @@ def get_route_to(self, destination="", protocol="", longer=False): # routing protocol process number, for future use # nh_source_proc_nr = viastr.group('procnr) if nh_int: - nh_int_canon = canonical_interface_name(nh_int) + nh_int_canon = helpers.canonical_interface_name(nh_int) else: nh_int_canon = "" route_entry = { diff --git a/napalm/pyIOSXR/iosxr.py b/napalm/pyIOSXR/iosxr.py index a1ddc2215..694a73227 100644 --- a/napalm/pyIOSXR/iosxr.py +++ b/napalm/pyIOSXR/iosxr.py @@ -690,7 +690,7 @@ def commit_replace_config(self, label=None, comment=None, confirmed=None): def discard_config(self): """ - Clear uncommitted changes in the current session. + Clear uncommited changes in the current session. Clear previously loaded configuration on the device without committing it. """ diff --git a/requirements-dev.txt b/requirements-dev.txt index 62923790b..b1197ced2 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -1,17 +1,17 @@ black==22.6.0 coveralls==3.3.1 -ddt==1.6.0 -flake8-import-order==0.18.2 -pytest==7.3.1 -pytest-cov==4.0.0 -pytest-json-report==1.5.0 -pyflakes==3.0.1 -pylama==8.4.1 -mock==5.0.2 -mypy==0.982 -types-PyYAML==6.0.12.10 -types-requests==2.28.11.17 -types-six==1.16.21.8 -types-setuptools==67.8.0.0 -ttp==0.9.4 -ttp_templates==0.3.5 +ddt==1.5.0 +flake8-import-order==0.18.1 +pytest==7.1.2 +pytest-cov==3.0.0 +pytest-json==0.4.0 +pylama==8.2.1 +mock==4.0.3 +tox==3.25.1 +mypy==0.961 +types-requests==2.28.0 +types-six==1.16.17 +types-setuptools==57.4.18 +types-PyYAML==6.0.9 +ttp==0.9.0 +ttp_templates==0.3.0 \ No newline at end of file diff --git a/requirements.txt b/requirements.txt index 57ecd72eb..18530cdd5 100644 --- a/requirements.txt +++ b/requirements.txt @@ -3,12 +3,12 @@ cffi>=1.11.3 paramiko>=2.6.0 requests>=2.7.0 future -textfsm +textfsm<=1.1.2 jinja2 netaddr pyYAML pyeapi>=0.8.2 -netmiko>=4.1.0 +netmiko>=4.0.0 junos-eznc>=2.6.3 scp lxml>=4.3.0 diff --git a/setup.cfg b/setup.cfg index 871c4c939..272f56d7f 100644 --- a/setup.cfg +++ b/setup.cfg @@ -5,11 +5,11 @@ universal = 1 license_file = LICENSE [pylama] -linters = mccabe,pycodestyle,pyflakes +linters = mccabe,pep8,pyflakes ignore = D203,C901,E203 skip = .tox/*,.env/*,.venv/* -[pylama:pycodestyle] +[pylama:pep8] max_line_length = 100 [tool:pytest] diff --git a/setup.py b/setup.py index 0a3bbe374..9eb0865d0 100644 --- a/setup.py +++ b/setup.py @@ -12,7 +12,7 @@ setup( name="napalm", - version="4.1.0", + version="4.0.0", packages=find_packages(exclude=("test*",)), test_suite="test_base", author="David Barroso, Kirk Byers, Mircea Ulinic", diff --git a/test/base/test_helpers.py b/test/base/test_helpers.py index cd2226877..f6ca9717b 100644 --- a/test/base/test_helpers.py +++ b/test/base/test_helpers.py @@ -57,10 +57,7 @@ from napalm.base.netmiko_helpers import netmiko_args import napalm.base.exceptions from napalm.base.base import NetworkDriver -from napalm.base.utils.string_parsers import ( - convert_uptime_string_seconds, - parse_fixed_width, -) +from napalm.base.utils.string_parsers import convert_uptime_string_seconds class TestBaseHelpers(unittest.TestCase): @@ -84,7 +81,7 @@ def test_load_template(self): custom path * check if can load correct template from custom path * check if template passed as string can be loaded - * check that the search path setup by MRO is correct when loading an incorrect template + * check that the search path setup by MRO is correct when loading an incorrecet template """ self.assertTrue(HAS_JINJA) # firstly check if jinja2 is installed @@ -378,8 +375,10 @@ def test_ip(self): * check if IPv6 address returned as expected """ - # test that raises ValueError when wrong format - self.assertRaises(ValueError, napalm.base.helpers.ip, "fake") + self.assertTrue(HAS_NETADDR) + + # test that raises AddrFormatError when wrong format + self.assertRaises(AddrFormatError, napalm.base.helpers.ip, "fake") self.assertRaises( ValueError, napalm.base.helpers.ip, @@ -496,6 +495,87 @@ def test_convert_uptime_string_seconds(self): self.assertEqual(convert_uptime_string_seconds("95w2d10h58m"), 57668280) self.assertEqual(convert_uptime_string_seconds("1h5m"), 3900) + def test_canonical_interface_name(self): + """Test the canonical_interface_name helper function.""" + self.assertEqual( + napalm.base.helpers.canonical_interface_name("Fa0/1"), "FastEthernet0/1" + ) + self.assertEqual( + napalm.base.helpers.canonical_interface_name("FastEthernet0/1"), + "FastEthernet0/1", + ) + self.assertEqual( + napalm.base.helpers.canonical_interface_name("TenGig1/1/1.5"), + "TenGigabitEthernet1/1/1.5", + ) + self.assertEqual( + napalm.base.helpers.canonical_interface_name("Gi1/2"), "GigabitEthernet1/2" + ) + self.assertEqual( + napalm.base.helpers.canonical_interface_name("HundredGigE105/1/1"), + "HundredGigabitEthernet105/1/1", + ) + self.assertEqual( + napalm.base.helpers.canonical_interface_name("Lo0"), "Loopback0" + ) + self.assertEqual( + napalm.base.helpers.canonical_interface_name("lo0"), "Loopback0" + ) + self.assertEqual( + napalm.base.helpers.canonical_interface_name("no_match0/1"), "no_match0/1" + ) + self.assertEqual( + napalm.base.helpers.canonical_interface_name( + "lo10", addl_name_map={"lo": "something_custom"} + ), + "something_custom10", + ) + self.assertEqual( + napalm.base.helpers.canonical_interface_name( + "uniq0/1/1", addl_name_map={"uniq": "something_custom"} + ), + "something_custom0/1/1", + ) + + def test_abbreviated_interface_name(self): + """Test the abbreviated_interface_name helper function.""" + self.assertEqual( + napalm.base.helpers.abbreviated_interface_name("Fa0/1"), "Fa0/1" + ) + self.assertEqual( + napalm.base.helpers.abbreviated_interface_name("FastEthernet0/1"), "Fa0/1" + ) + self.assertEqual( + napalm.base.helpers.abbreviated_interface_name("TenGig1/1/1.5"), "Te1/1/1.5" + ) + self.assertEqual( + napalm.base.helpers.abbreviated_interface_name("Gi1/2"), "Gi1/2" + ) + self.assertEqual( + napalm.base.helpers.abbreviated_interface_name("HundredGigE105/1/1"), + "Hu105/1/1", + ) + self.assertEqual(napalm.base.helpers.abbreviated_interface_name("Lo0"), "Lo0") + self.assertEqual(napalm.base.helpers.abbreviated_interface_name("lo0"), "Lo0") + self.assertEqual( + napalm.base.helpers.abbreviated_interface_name("something_custom0/1"), + "something_custom0/1", + ) + self.assertEqual( + napalm.base.helpers.abbreviated_interface_name( + "loop10", addl_name_map={"loop": "Loopback"} + ), + "Lo10", + ) + self.assertEqual( + napalm.base.helpers.abbreviated_interface_name( + "loop10", + addl_name_map={"loop": "Loopback"}, + addl_reverse_map={"Loopback": "lo"}, + ), + "lo10", + ) + def test_netmiko_arguments(self): """Test the netmiko argument processing.""" self.assertEqual(netmiko_args(optional_args={}), {}) @@ -675,37 +755,6 @@ def test_ttp_parse(self): ) self.assertEqual(result, _EXPECTED_RESULT) - def test_parse_fixed_width(self): - _TEST_STRING = """ VRF RD Protocols State Interfaces ----------------- --------------- --------------- ------------------- --------------------------- -123456789012345671234567890123456123456789012345612345678901234567890123456789012345678901234567 -""" # noqa: E501 - _EXPECTED_RESULT = [ - ( - " VRF ", - " RD ", - " Protocols ", - " State ", - "Interfaces ", - ), - ( - "---------------- ", - "--------------- ", - "--------------- ", - "------------------- ", - "---------------------------", - ), - ( - "12345678901234567", - "1234567890123456", - "1234567890123456", - "12345678901234567890", - "123456789012345678901234567", - ), - ] - result = parse_fixed_width(_TEST_STRING, 17, 16, 16, 20, 27) - self.assertEqual(result, _EXPECTED_RESULT) - class FakeNetworkDriver(NetworkDriver): def __init__(self): diff --git a/test/eos/conftest.py b/test/eos/conftest.py index aff8e78a1..7cf515f31 100644 --- a/test/eos/conftest.py +++ b/test/eos/conftest.py @@ -37,19 +37,6 @@ def __init__(self, hostname, username, password, timeout=60, optional_args=None) self.patched_attrs = ["device"] self.device = FakeEOSDevice() - self._cli_version = 1 - - @property - def cli_version(self): - try: - full_path = self.device.find_file("cli_version.txt") - except IOError: - return self._cli_version - return int(self.device.read_txt_file(full_path)) - - @cli_version.setter - def cli_version(self, value): - self._cli_version = value class FakeEOSDevice(BaseTestDouble): diff --git a/test/eos/mocked_data/test_get_bgp_config/issue1504_alt_peer_group_syntax/expected_result.json b/test/eos/mocked_data/test_get_bgp_config/issue1504_alt_peer_group_syntax/expected_result.json index 1dbf0d43b..8354f24ba 100644 --- a/test/eos/mocked_data/test_get_bgp_config/issue1504_alt_peer_group_syntax/expected_result.json +++ b/test/eos/mocked_data/test_get_bgp_config/issue1504_alt_peer_group_syntax/expected_result.json @@ -1,19 +1,4 @@ { - "_": { - "type": "", - "multipath": false, - "apply_groups": [], - "remove_private_as": false, - "multihop_ttl": 0, - "remote_as": 0, - "local_address": "", - "local_as": 64496, - "description": "", - "import_policy": "", - "export_policy": "", - "prefix_limit": {}, - "neighbors": {} - }, "IPv6-PEERS-GROUP-NAME": { "type": "", "multipath": false, @@ -35,8 +20,8 @@ "local_as": 64496, "nhs": false, "route_reflector_client": false, - "import_policy": "reject-all", - "export_policy": "reject-all", + "import_policy": "", + "export_policy": "", "authentication_key": "", "prefix_limit": {} }, @@ -47,8 +32,8 @@ "local_as": 64496, "nhs": false, "route_reflector_client": false, - "import_policy": "reject-all", - "export_policy": "reject-all", + "import_policy": "", + "export_policy": "", "authentication_key": "", "prefix_limit": {} } diff --git a/test/eos/mocked_data/test_get_bgp_config/issue_1113_dot_asn/expected_result.json b/test/eos/mocked_data/test_get_bgp_config/issue_1113_dot_asn/expected_result.json index 1f885538c..84f8c3bd8 100644 --- a/test/eos/mocked_data/test_get_bgp_config/issue_1113_dot_asn/expected_result.json +++ b/test/eos/mocked_data/test_get_bgp_config/issue_1113_dot_asn/expected_result.json @@ -1,19 +1,4 @@ { - "_": { - "type": "", - "multipath": false, - "apply_groups": [], - "remove_private_as": false, - "multihop_ttl": 0, - "remote_as": 0, - "local_address": "", - "local_as": 4266524237, - "description": "", - "import_policy": "", - "export_policy": "", - "prefix_limit": {}, - "neighbors": {} - }, "IPv4-PEERS-GROUP-NAME": { "type": "", "multipath": false, @@ -35,8 +20,8 @@ "local_as": 4266524237, "nhs": false, "route_reflector_client": false, - "import_policy": "reject-all", - "export_policy": "4-public-peer-anycast-out", + "import_policy": "", + "export_policy": "", "authentication_key": "", "prefix_limit": {} }, @@ -47,8 +32,8 @@ "local_as": 4266524237, "nhs": false, "route_reflector_client": false, - "import_policy": "reject-all", - "export_policy": "4-public-peer-anycast-out", + "import_policy": "", + "export_policy": "", "authentication_key": "", "prefix_limit": {} } @@ -75,8 +60,8 @@ "local_as": 4266524237, "nhs": false, "route_reflector_client": false, - "import_policy": "reject-all", - "export_policy": "reject-all", + "import_policy": "", + "export_policy": "", "authentication_key": "", "prefix_limit": {} }, @@ -87,8 +72,8 @@ "local_as": 4266524237, "nhs": false, "route_reflector_client": false, - "import_policy": "reject-all", - "export_policy": "reject-all", + "import_policy": "", + "export_policy": "", "authentication_key": "", "prefix_limit": {} } diff --git a/test/eos/mocked_data/test_get_bgp_config/issue_905_group_copydown/expected_result.json b/test/eos/mocked_data/test_get_bgp_config/issue_905_group_copydown/expected_result.json deleted file mode 100644 index 4f2f36e4e..000000000 --- a/test/eos/mocked_data/test_get_bgp_config/issue_905_group_copydown/expected_result.json +++ /dev/null @@ -1,57 +0,0 @@ -{ - "_": { - "type": "", - "multipath": false, - "apply_groups": [], - "remove_private_as": false, - "multihop_ttl": 0, - "remote_as": 0, - "local_address": "", - "local_as": 65534, - "description": "", - "import_policy": "", - "export_policy": "", - "prefix_limit": {}, - "neighbors": {} - }, - "FOO-GROUP": { - "local_address": "", - "description": "FOO", - "type": "", - "local_as": 65534, - "apply_groups": [], - "multihop_ttl": 0, - "remove_private_as": false, - "remote_as": 65534, - "import_policy": "", - "export_policy": "", - "neighbors": { - "192.0.2.2": { - "local_address": "", - "authentication_key": "", - "description": "FOO", - "nhs": false, - "local_as": 65534, - "route_reflector_client": false, - "remote_as": 65534, - "import_policy": "", - "export_policy": "", - "prefix_limit": {} - }, - "192.0.2.3": { - "local_address": "", - "authentication_key": "", - "description": "SECOND-PEER", - "nhs": true, - "local_as": 65534, - "route_reflector_client": false, - "remote_as": 65534, - "import_policy": "", - "export_policy": "", - "prefix_limit": {} - } - }, - "prefix_limit": {}, - "multipath": false - } -} diff --git a/test/eos/mocked_data/test_get_bgp_config/issue_905_group_copydown/show_running_config___section_router_bgp.text b/test/eos/mocked_data/test_get_bgp_config/issue_905_group_copydown/show_running_config___section_router_bgp.text deleted file mode 100644 index 0db6d0c27..000000000 --- a/test/eos/mocked_data/test_get_bgp_config/issue_905_group_copydown/show_running_config___section_router_bgp.text +++ /dev/null @@ -1,11 +0,0 @@ -router bgp 65534 - router-id 192.0.2.1 - neighbor FOO-GROUP peer group - neighbor FOO-GROUP next-hop-self - neighbor FOO-GROUP description FOO - neighbor FOO-GROUP remote-as 65534 - neighbor 192.0.2.2 peer group FOO-GROUP - no neighbor 192.0.2.2 next-hop-self - neighbor 192.0.2.3 peer group FOO-GROUP - neighbor 192.0.2.3 description SECOND-PEER -! diff --git a/test/eos/mocked_data/test_get_bgp_config/no_bgp_config/expected_result.json b/test/eos/mocked_data/test_get_bgp_config/no_bgp_config/expected_result.json deleted file mode 100644 index 0967ef424..000000000 --- a/test/eos/mocked_data/test_get_bgp_config/no_bgp_config/expected_result.json +++ /dev/null @@ -1 +0,0 @@ -{} diff --git a/test/eos/mocked_data/test_get_bgp_config/normal/expected_result.json b/test/eos/mocked_data/test_get_bgp_config/normal/expected_result.json index bdf8f2657..de52578fe 100644 --- a/test/eos/mocked_data/test_get_bgp_config/normal/expected_result.json +++ b/test/eos/mocked_data/test_get_bgp_config/normal/expected_result.json @@ -1,97 +1 @@ -{ - "_": { - "type": "", - "multipath": false, - "apply_groups": [], - "remove_private_as": false, - "multihop_ttl": 0, - "remote_as": 0, - "local_address": "", - "local_as": 13335, - "description": "", - "import_policy": "", - "export_policy": "", - "prefix_limit": {}, - "neighbors": {} - }, - "IPv4-PEERS-GROUP-NAME": { - "local_address": "", - "description": "", - "type": "", - "local_as": 13335, - "apply_groups": [], - "multihop_ttl": 0, - "remove_private_as": true, - "remote_as": 0, - "import_policy": "reject-all", - "export_policy": "4-public-peer-anycast-out", - "neighbors": { - "172.17.17.1": { - "local_address": "", - "authentication_key": "", - "description": "", - "nhs": false, - "local_as": 13335, - "route_reflector_client": false, - "remote_as": 13414, - "import_policy": "reject-all", - "export_policy": "4-public-peer-anycast-out", - "prefix_limit": {} - }, - "192.168.0.1": { - "local_address": "", - "authentication_key": "", - "description": "", - "nhs": false, - "local_as": 13335, - "route_reflector_client": false, - "remote_as": 32934, - "import_policy": "reject-all", - "export_policy": "4-public-peer-anycast-out", - "prefix_limit": {} - } - }, - "prefix_limit": {}, - "multipath": false - }, - "IPv6-PEERS-GROUP-NAME": { - "local_address": "", - "description": "", - "type": "", - "local_as": 13335, - "apply_groups": [], - "multihop_ttl": 0, - "remove_private_as": true, - "remote_as": 0, - "import_policy": "reject-all", - "export_policy": "reject-all", - "neighbors": { - "2001:db8::0:2": { - "local_address": "", - "authentication_key": "", - "description": "", - "nhs": false, - "local_as": 13335, - "route_reflector_client": false, - "remote_as": 54113, - "import_policy": "reject-all", - "export_policy": "reject-all", - "prefix_limit": {} - }, - "2001:db8::0:1": { - "local_address": "", - "authentication_key": "", - "description": "", - "nhs": false, - "local_as": 13335, - "route_reflector_client": false, - "remote_as": 8403, - "import_policy": "reject-all", - "export_policy": "reject-all", - "prefix_limit": {} - } - }, - "prefix_limit": {}, - "multipath": false - } -} +{"IPv4-PEERS-GROUP-NAME": {"local_address": "", "description": "", "type": "", "local_as": 13335, "apply_groups": [], "multihop_ttl": 0, "remove_private_as": true, "remote_as": 0, "import_policy": "reject-all", "export_policy": "4-public-peer-anycast-out", "neighbors": {"172.17.17.1": {"local_address": "", "authentication_key": "", "description": "", "nhs": false, "local_as": 13335, "route_reflector_client": false, "remote_as": 13414, "import_policy": "", "export_policy": "", "prefix_limit": {}}, "192.168.0.1": {"local_address": "", "authentication_key": "", "description": "", "nhs": false, "local_as": 13335, "route_reflector_client": false, "remote_as": 32934, "import_policy": "", "export_policy": "", "prefix_limit": {}}}, "prefix_limit": {}, "multipath": false}, "IPv6-PEERS-GROUP-NAME": {"local_address": "", "description": "", "type": "", "local_as": 13335, "apply_groups": [], "multihop_ttl": 0, "remove_private_as": true, "remote_as": 0, "import_policy": "reject-all", "export_policy": "reject-all", "neighbors": {"2001:db8::0:2": {"local_address": "", "authentication_key": "", "description": "", "nhs": false, "local_as": 13335, "route_reflector_client": false, "remote_as": 54113, "import_policy": "", "export_policy": "", "prefix_limit": {}}, "2001:db8::0:1": {"local_address": "", "authentication_key": "", "description": "", "nhs": false, "local_as": 13335, "route_reflector_client": false, "remote_as": 8403, "import_policy": "", "export_policy": "", "prefix_limit": {}}}, "prefix_limit": {}, "multipath": false}} diff --git a/test/eos/mocked_data/test_get_bgp_neighbors/issue1168/show_ip_bgp_neighbors_vrf_all___include_IPv_46___Unicast_6PE_____0_9_____grep__v___IPv_46__Unicast_______remote_AS___Local_AS_Desc_BGP_state__remote_r.text b/test/eos/mocked_data/test_get_bgp_neighbors/issue1168/show_ip_bgp_neighbors_vrf_all___include_remote_AS___remote_router_ID__IPv_46___Unicast_6PE_____0_9____Local_AS_Desc_BGP_state.text similarity index 100% rename from test/eos/mocked_data/test_get_bgp_neighbors/issue1168/show_ip_bgp_neighbors_vrf_all___include_IPv_46___Unicast_6PE_____0_9_____grep__v___IPv_46__Unicast_______remote_AS___Local_AS_Desc_BGP_state__remote_r.text rename to test/eos/mocked_data/test_get_bgp_neighbors/issue1168/show_ip_bgp_neighbors_vrf_all___include_remote_AS___remote_router_ID__IPv_46___Unicast_6PE_____0_9____Local_AS_Desc_BGP_state.text diff --git a/test/eos/mocked_data/test_get_bgp_neighbors/issue1168/show_ipv6_bgp_neighbors_vrf_all___include_IPv_46___Unicast_6PE_____0_9_____grep__v___IPv_46__Unicast_______remote_AS___Local_AS_Desc_BGP_state__remote.text b/test/eos/mocked_data/test_get_bgp_neighbors/issue1168/show_ipv6_bgp_neighbors_vrf_all___include_remote_AS___remote_router_ID__IPv_46___Unicast_6PE_____0_9____Local_AS_Desc_BGP_state.text similarity index 100% rename from test/eos/mocked_data/test_get_bgp_neighbors/issue1168/show_ipv6_bgp_neighbors_vrf_all___include_IPv_46___Unicast_6PE_____0_9_____grep__v___IPv_46__Unicast_______remote_AS___Local_AS_Desc_BGP_state__remote.text rename to test/eos/mocked_data/test_get_bgp_neighbors/issue1168/show_ipv6_bgp_neighbors_vrf_all___include_remote_AS___remote_router_ID__IPv_46___Unicast_6PE_____0_9____Local_AS_Desc_BGP_state.text diff --git a/test/eos/mocked_data/test_get_bgp_neighbors/issue1356/show_ip_bgp_neighbors_vrf_all___include_IPv_46___Unicast_6PE_____0_9_____grep__v___IPv_46__Unicast_______remote_AS___Local_AS_Desc_BGP_state__remote_r.text b/test/eos/mocked_data/test_get_bgp_neighbors/issue1356/show_ip_bgp_neighbors_vrf_all___include_remote_AS___remote_router_ID__IPv_46___Unicast_6PE_____0_9____Local_AS_Desc_BGP_state.text similarity index 100% rename from test/eos/mocked_data/test_get_bgp_neighbors/issue1356/show_ip_bgp_neighbors_vrf_all___include_IPv_46___Unicast_6PE_____0_9_____grep__v___IPv_46__Unicast_______remote_AS___Local_AS_Desc_BGP_state__remote_r.text rename to test/eos/mocked_data/test_get_bgp_neighbors/issue1356/show_ip_bgp_neighbors_vrf_all___include_remote_AS___remote_router_ID__IPv_46___Unicast_6PE_____0_9____Local_AS_Desc_BGP_state.text diff --git a/test/eos/mocked_data/test_get_bgp_neighbors/issue1356/show_ipv6_bgp_neighbors_vrf_all___include_IPv_46___Unicast_6PE_____0_9_____grep__v___IPv_46__Unicast_______remote_AS___Local_AS_Desc_BGP_state__remote.text b/test/eos/mocked_data/test_get_bgp_neighbors/issue1356/show_ipv6_bgp_neighbors_vrf_all___include_IPv_46___Unicast_6PE_____0_9_____grep__v___IPv_46__Unicast_______remote_AS___Local_AS_Desc_BGP_state__remote.text deleted file mode 100644 index e69de29bb..000000000 diff --git a/test/eos/mocked_data/test_get_bgp_config/no_bgp_config/show_running_config___section_router_bgp.text b/test/eos/mocked_data/test_get_bgp_neighbors/issue1356/show_ipv6_bgp_neighbors_vrf_all___include_remote_AS___remote_router_ID__IPv_46___Unicast_6PE_____0_9____Local_AS_Desc_BGP_state.text similarity index 100% rename from test/eos/mocked_data/test_get_bgp_config/no_bgp_config/show_running_config___section_router_bgp.text rename to test/eos/mocked_data/test_get_bgp_neighbors/issue1356/show_ipv6_bgp_neighbors_vrf_all___include_remote_AS___remote_router_ID__IPv_46___Unicast_6PE_____0_9____Local_AS_Desc_BGP_state.text diff --git a/test/eos/mocked_data/test_get_bgp_neighbors/issue1759/expected_result.json b/test/eos/mocked_data/test_get_bgp_neighbors/issue1759/expected_result.json deleted file mode 100644 index ee7922393..000000000 --- a/test/eos/mocked_data/test_get_bgp_neighbors/issue1759/expected_result.json +++ /dev/null @@ -1,112 +0,0 @@ -{ - "global": { - "peers": { - "fe80::a8c1:abff:fe0b:7b5f%Et5": { - "is_up": true, - "is_enabled": true, - "uptime": "...", - "description": "", - "remote_as": 4259840008, - "remote_id": "172.18.0.8", - "local_as": 4259906562, - "address_family": { - "ipv4": { - "sent_prefixes": 9, - "received_prefixes": 2, - "accepted_prefixes": -1 - }, - "ipv6": { - "sent_prefixes": 9, - "received_prefixes": 2, - "accepted_prefixes": -1 - } - } - }, - "fe80::a8c1:abff:fe27:69e9%Et2": { - "is_up": true, - "is_enabled": true, - "uptime": "...", - "description": "", - "remote_as": 4259973121, - "remote_id": "172.18.8.1", - "local_as": 4259906562, - "address_family": { - "ipv4": { - "sent_prefixes": 9, - "received_prefixes": 5, - "accepted_prefixes": -1 - }, - "ipv6": { - "sent_prefixes": 9, - "received_prefixes": 5, - "accepted_prefixes": -1 - } - } - }, - "fe80::a8c1:abff:fe35:51d9%Et1": { - "is_up": true, - "is_enabled": true, - "uptime": "...", - "description": "", - "remote_as": 4259973120, - "remote_id": "172.18.8.0", - "local_as": 4259906562, - "address_family": { - "ipv4": { - "sent_prefixes": 6, - "received_prefixes": 5, - "accepted_prefixes": -1 - }, - "ipv6": { - "sent_prefixes": 6, - "received_prefixes": 5, - "accepted_prefixes": -1 - } - } - }, - "fe80::a8c1:abff:fe5d:9706%Et4": { - "is_up": true, - "is_enabled": true, - "uptime": "...", - "description": "", - "remote_as": 4259840007, - "remote_id": "172.18.0.7", - "local_as": 4259906562, - "address_family": { - "ipv4": { - "sent_prefixes": 9, - "received_prefixes": 2, - "accepted_prefixes": -1 - }, - "ipv6": { - "sent_prefixes": 9, - "received_prefixes": 2, - "accepted_prefixes": -1 - } - } - }, - "fe80::a8c1:abff:fe95:fa49%Et3": { - "is_up": true, - "is_enabled": true, - "uptime": "...", - "description": "", - "remote_as": 4259840005, - "remote_id": "172.18.0.5", - "local_as": 4259906562, - "address_family": { - "ipv4": { - "sent_prefixes": 9, - "received_prefixes": 2, - "accepted_prefixes": -1 - }, - "ipv6": { - "sent_prefixes": 9, - "received_prefixes": 2, - "accepted_prefixes": -1 - } - } - } - }, - "router_id": "172.18.4.2" - } -} diff --git a/test/eos/mocked_data/test_get_bgp_neighbors/issue1759/show_ip_bgp_neighbors_vrf_all___include_IPv_46___Unicast_6PE_____0_9_____grep__v___IPv_46__Unicast_______remote_AS___Local_AS_Desc_BGP_state__remote_r.text b/test/eos/mocked_data/test_get_bgp_neighbors/issue1759/show_ip_bgp_neighbors_vrf_all___include_IPv_46___Unicast_6PE_____0_9_____grep__v___IPv_46__Unicast_______remote_AS___Local_AS_Desc_BGP_state__remote_r.text deleted file mode 100644 index e69de29bb..000000000 diff --git a/test/eos/mocked_data/test_get_bgp_neighbors/issue1759/show_ip_bgp_summary_vrf_all.json b/test/eos/mocked_data/test_get_bgp_neighbors/issue1759/show_ip_bgp_summary_vrf_all.json deleted file mode 100644 index 0155ea42a..000000000 --- a/test/eos/mocked_data/test_get_bgp_neighbors/issue1759/show_ip_bgp_summary_vrf_all.json +++ /dev/null @@ -1,76 +0,0 @@ -{ - "vrfs": { - "default": { - "routerId": "172.18.4.2", - "peers": { - "fe80::a8c1:abff:fe0b:7b5f%Et5": { - "msgSent": 239229, - "inMsgQueue": 0, - "prefixReceived": 2, - "upDownTime": 1664912777.128896, - "version": 4, - "prefixAccepted": 2, - "msgReceived": 203694, - "peerState": "Established", - "outMsgQueue": 0, - "underMaintenance": false, - "asn": "65000.8" - }, - "fe80::a8c1:abff:fe27:69e9%Et2": { - "msgSent": 11997, - "inMsgQueue": 0, - "prefixReceived": 5, - "upDownTime": 1664912780.356704, - "version": 4, - "prefixAccepted": 5, - "msgReceived": 11972, - "peerState": "Established", - "outMsgQueue": 0, - "underMaintenance": false, - "asn": "65002.2049" - }, - "fe80::a8c1:abff:fe35:51d9%Et1": { - "msgSent": 11984, - "inMsgQueue": 0, - "prefixReceived": 5, - "upDownTime": 1664912783.670673, - "version": 4, - "prefixAccepted": 5, - "msgReceived": 11979, - "peerState": "Established", - "outMsgQueue": 0, - "underMaintenance": false, - "asn": "65002.2048" - }, - "fe80::a8c1:abff:fe5d:9706%Et4": { - "msgSent": 239170, - "inMsgQueue": 0, - "prefixReceived": 2, - "upDownTime": 1664912777.50903, - "version": 4, - "prefixAccepted": 2, - "msgReceived": 203718, - "peerState": "Established", - "outMsgQueue": 0, - "underMaintenance": false, - "asn": "65000.7" - }, - "fe80::a8c1:abff:fe95:fa49%Et3": { - "msgSent": 239116, - "inMsgQueue": 0, - "prefixReceived": 2, - "upDownTime": 1664912777.604791, - "version": 4, - "prefixAccepted": 2, - "msgReceived": 203718, - "peerState": "Established", - "outMsgQueue": 0, - "underMaintenance": false, - "asn": "65000.5" - } - }, - "vrf": "default", - "asn": "65001.1026" - } - } -} diff --git a/test/eos/mocked_data/test_get_bgp_neighbors/issue1759/show_ipv6_bgp_neighbors_vrf_all___include_IPv_46___Unicast_6PE_____0_9_____grep__v___IPv_46__Unicast_______remote_AS___Local_AS_Desc_BGP_state__remote.text b/test/eos/mocked_data/test_get_bgp_neighbors/issue1759/show_ipv6_bgp_neighbors_vrf_all___include_IPv_46___Unicast_6PE_____0_9_____grep__v___IPv_46__Unicast_______remote_AS___Local_AS_Desc_BGP_state__remote.text deleted file mode 100644 index f1d5ed371..000000000 --- a/test/eos/mocked_data/test_get_bgp_neighbors/issue1759/show_ipv6_bgp_neighbors_vrf_all___include_IPv_46___Unicast_6PE_____0_9_____grep__v___IPv_46__Unicast_______remote_AS___Local_AS_Desc_BGP_state__remote.text +++ /dev/null @@ -1,30 +0,0 @@ -BGP neighbor is fe80::a8c1:abff:fe0b:7b5f%Et5, remote AS 65000.8, external link - BGP version 4, remote router ID 172.18.0.8, VRF default - BGP state is Established, up for 7d01h - IPv4 Unicast: 9 2 1 0 - IPv6 Unicast: 9 2 1 0 -Local AS is 65001.1026, local router ID 172.18.4.2 -BGP neighbor is fe80::a8c1:abff:fe27:69e9%Et2, remote AS 65002.2049, external link - BGP version 4, remote router ID 172.18.8.1, VRF default - BGP state is Established, up for 7d01h - IPv4 Unicast: 9 5 1 0 - IPv6 Unicast: 9 5 1 0 -Local AS is 65001.1026, local router ID 172.18.4.2 -BGP neighbor is fe80::a8c1:abff:fe35:51d9%Et1, remote AS 65002.2048, external link - BGP version 4, remote router ID 172.18.8.0, VRF default - BGP state is Established, up for 7d01h - IPv4 Unicast: 6 5 4 0 - IPv6 Unicast: 6 5 4 0 -Local AS is 65001.1026, local router ID 172.18.4.2 -BGP neighbor is fe80::a8c1:abff:fe5d:9706%Et4, remote AS 65000.7, external link - BGP version 4, remote router ID 172.18.0.7, VRF default - BGP state is Established, up for 7d01h - IPv4 Unicast: 9 2 1 0 - IPv6 Unicast: 9 2 1 0 -Local AS is 65001.1026, local router ID 172.18.4.2 -BGP neighbor is fe80::a8c1:abff:fe95:fa49%Et3, remote AS 65000.5, external link - BGP version 4, remote router ID 172.18.0.5, VRF default - BGP state is Established, up for 7d01h - IPv4 Unicast: 9 2 1 0 - IPv6 Unicast: 9 2 1 0 -Local AS is 65001.1026, local router ID 172.18.4.2 diff --git a/test/eos/mocked_data/test_get_bgp_neighbors/issue1759/show_ipv6_bgp_summary_vrf_all.json b/test/eos/mocked_data/test_get_bgp_neighbors/issue1759/show_ipv6_bgp_summary_vrf_all.json deleted file mode 100644 index aa96e6d48..000000000 --- a/test/eos/mocked_data/test_get_bgp_neighbors/issue1759/show_ipv6_bgp_summary_vrf_all.json +++ /dev/null @@ -1,76 +0,0 @@ -{ - "vrfs": { - "default": { - "routerId": "172.18.4.2", - "peers": { - "fe80::a8c1:abff:fe0b:7b5f%Et5": { - "msgSent": 239193, - "inMsgQueue": 0, - "prefixReceived": 2, - "upDownTime": 1664912777.128896, - "version": 4, - "prefixAccepted": 2, - "msgReceived": 203664, - "peerState": "Established", - "outMsgQueue": 0, - "underMaintenance": false, - "asn": "65000.8" - }, - "fe80::a8c1:abff:fe27:69e9%Et2": { - "msgSent": 11995, - "inMsgQueue": 0, - "prefixReceived": 5, - "upDownTime": 1664912780.356703, - "version": 4, - "prefixAccepted": 5, - "msgReceived": 11970, - "peerState": "Established", - "outMsgQueue": 0, - "underMaintenance": false, - "asn": "65002.2049" - }, - "fe80::a8c1:abff:fe35:51d9%Et1": { - "msgSent": 11982, - "inMsgQueue": 0, - "prefixReceived": 5, - "upDownTime": 1664912783.670674, - "version": 4, - "prefixAccepted": 5, - "msgReceived": 11977, - "peerState": "Established", - "outMsgQueue": 0, - "underMaintenance": false, - "asn": "65002.2048" - }, - "fe80::a8c1:abff:fe5d:9706%Et4": { - "msgSent": 239135, - "inMsgQueue": 0, - "prefixReceived": 2, - "upDownTime": 1664912777.50903, - "version": 4, - "prefixAccepted": 2, - "msgReceived": 203688, - "peerState": "Established", - "outMsgQueue": 0, - "underMaintenance": false, - "asn": "65000.7" - }, - "fe80::a8c1:abff:fe95:fa49%Et3": { - "msgSent": 239080, - "inMsgQueue": 0, - "prefixReceived": 2, - "upDownTime": 1664912777.604791, - "version": 4, - "prefixAccepted": 2, - "msgReceived": 203688, - "peerState": "Established", - "outMsgQueue": 0, - "underMaintenance": false, - "asn": "65000.5" - } - }, - "vrf": "default", - "asn": "65001.1026" - } - } -} diff --git a/test/eos/mocked_data/test_get_bgp_neighbors/issue58_neighbor_down/show_ip_bgp_neighbors_vrf_all___include_IPv_46___Unicast_6PE_____0_9_____grep__v___IPv_46__Unicast_______remote_AS___Local_AS_Desc_BGP_state__remote_r.text b/test/eos/mocked_data/test_get_bgp_neighbors/issue58_neighbor_down/show_ip_bgp_neighbors_vrf_all___include_remote_AS___remote_router_ID__IPv_46___Unicast_6PE_____0_9____Local_AS_Desc_BGP_state.text similarity index 100% rename from test/eos/mocked_data/test_get_bgp_neighbors/issue58_neighbor_down/show_ip_bgp_neighbors_vrf_all___include_IPv_46___Unicast_6PE_____0_9_____grep__v___IPv_46__Unicast_______remote_AS___Local_AS_Desc_BGP_state__remote_r.text rename to test/eos/mocked_data/test_get_bgp_neighbors/issue58_neighbor_down/show_ip_bgp_neighbors_vrf_all___include_remote_AS___remote_router_ID__IPv_46___Unicast_6PE_____0_9____Local_AS_Desc_BGP_state.text diff --git a/test/eos/mocked_data/test_get_bgp_neighbors/issue58_neighbor_down/show_ipv6_bgp_neighbors_vrf_all___include_IPv_46___Unicast_6PE_____0_9_____grep__v___IPv_46__Unicast_______remote_AS___Local_AS_Desc_BGP_state__remote.text b/test/eos/mocked_data/test_get_bgp_neighbors/issue58_neighbor_down/show_ipv6_bgp_neighbors_vrf_all___include_remote_AS___remote_router_ID__IPv_46___Unicast_6PE_____0_9____Local_AS_Desc_BGP_state.text similarity index 100% rename from test/eos/mocked_data/test_get_bgp_neighbors/issue58_neighbor_down/show_ipv6_bgp_neighbors_vrf_all___include_IPv_46___Unicast_6PE_____0_9_____grep__v___IPv_46__Unicast_______remote_AS___Local_AS_Desc_BGP_state__remote.text rename to test/eos/mocked_data/test_get_bgp_neighbors/issue58_neighbor_down/show_ipv6_bgp_neighbors_vrf_all___include_remote_AS___remote_router_ID__IPv_46___Unicast_6PE_____0_9____Local_AS_Desc_BGP_state.text diff --git a/test/eos/mocked_data/test_get_bgp_neighbors/issue944/show_ip_bgp_neighbors_vrf_all___include_IPv_46___Unicast_6PE_____0_9_____grep__v___IPv_46__Unicast_______remote_AS___Local_AS_Desc_BGP_state__remote_r.text b/test/eos/mocked_data/test_get_bgp_neighbors/issue944/show_ip_bgp_neighbors_vrf_all___include_remote_AS___remote_router_ID__IPv_46___Unicast_6PE_____0_9____Local_AS_Desc_BGP_state.text similarity index 100% rename from test/eos/mocked_data/test_get_bgp_neighbors/issue944/show_ip_bgp_neighbors_vrf_all___include_IPv_46___Unicast_6PE_____0_9_____grep__v___IPv_46__Unicast_______remote_AS___Local_AS_Desc_BGP_state__remote_r.text rename to test/eos/mocked_data/test_get_bgp_neighbors/issue944/show_ip_bgp_neighbors_vrf_all___include_remote_AS___remote_router_ID__IPv_46___Unicast_6PE_____0_9____Local_AS_Desc_BGP_state.text diff --git a/test/eos/mocked_data/test_get_bgp_neighbors/issue944/show_ipv6_bgp_neighbors_vrf_all___include_IPv_46___Unicast_6PE_____0_9_____grep__v___IPv_46__Unicast_______remote_AS___Local_AS_Desc_BGP_state__remote.text b/test/eos/mocked_data/test_get_bgp_neighbors/issue944/show_ipv6_bgp_neighbors_vrf_all___include_remote_AS___remote_router_ID__IPv_46___Unicast_6PE_____0_9____Local_AS_Desc_BGP_state.text similarity index 100% rename from test/eos/mocked_data/test_get_bgp_neighbors/issue944/show_ipv6_bgp_neighbors_vrf_all___include_IPv_46___Unicast_6PE_____0_9_____grep__v___IPv_46__Unicast_______remote_AS___Local_AS_Desc_BGP_state__remote.text rename to test/eos/mocked_data/test_get_bgp_neighbors/issue944/show_ipv6_bgp_neighbors_vrf_all___include_remote_AS___remote_router_ID__IPv_46___Unicast_6PE_____0_9____Local_AS_Desc_BGP_state.text diff --git a/test/eos/mocked_data/test_get_bgp_neighbors/normal/show_ip_bgp_neighbors_vrf_all___include_IPv_46___Unicast_6PE_____0_9_____grep__v___IPv_46__Unicast_______remote_AS___Local_AS_Desc_BGP_state__remote_r.text b/test/eos/mocked_data/test_get_bgp_neighbors/normal/show_ip_bgp_neighbors_vrf_all___include_remote_AS___remote_router_ID__IPv_46___Unicast_6PE_____0_9____Local_AS_Desc_BGP_state.text similarity index 100% rename from test/eos/mocked_data/test_get_bgp_neighbors/normal/show_ip_bgp_neighbors_vrf_all___include_IPv_46___Unicast_6PE_____0_9_____grep__v___IPv_46__Unicast_______remote_AS___Local_AS_Desc_BGP_state__remote_r.text rename to test/eos/mocked_data/test_get_bgp_neighbors/normal/show_ip_bgp_neighbors_vrf_all___include_remote_AS___remote_router_ID__IPv_46___Unicast_6PE_____0_9____Local_AS_Desc_BGP_state.text diff --git a/test/eos/mocked_data/test_get_bgp_neighbors/normal/show_ipv6_bgp_neighbors_vrf_all___include_IPv_46___Unicast_6PE_____0_9_____grep__v___IPv_46__Unicast_______remote_AS___Local_AS_Desc_BGP_state__remote.text b/test/eos/mocked_data/test_get_bgp_neighbors/normal/show_ipv6_bgp_neighbors_vrf_all___include_remote_AS___remote_router_ID__IPv_46___Unicast_6PE_____0_9____Local_AS_Desc_BGP_state.text similarity index 100% rename from test/eos/mocked_data/test_get_bgp_neighbors/normal/show_ipv6_bgp_neighbors_vrf_all___include_IPv_46___Unicast_6PE_____0_9_____grep__v___IPv_46__Unicast_______remote_AS___Local_AS_Desc_BGP_state__remote.text rename to test/eos/mocked_data/test_get_bgp_neighbors/normal/show_ipv6_bgp_neighbors_vrf_all___include_remote_AS___remote_router_ID__IPv_46___Unicast_6PE_____0_9____Local_AS_Desc_BGP_state.text diff --git a/test/eos/mocked_data/test_get_network_instances/issue-1922/expected_result.json b/test/eos/mocked_data/test_get_network_instances/issue-1922/expected_result.json deleted file mode 100644 index 413d219c4..000000000 --- a/test/eos/mocked_data/test_get_network_instances/issue-1922/expected_result.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "management": { - "name": "management", - "type": "L3VRF", - "state": { "route_distinguisher": "" }, - "interfaces": { "interface": { "Management1": {} } } - }, - "default": { - "interfaces": { - "interface": { - "Ethernet1": {}, - "Ethernet2": {}, - "Ethernet3": {}, - "Ethernet4": {}, - "Ethernet49/1": {}, - "Ethernet5": {}, - "Ethernet50/1": {}, - "Ethernet52/1": {}, - "Ethernet53/1": {}, - "Ethernet54/1": {}, - "Ethernet55/1": {}, - "Ethernet56/1": {}, - "Loopback0": {} - } - }, - "state": { "route_distinguisher": "" }, - "type": "DEFAULT_INSTANCE", - "name": "default" - } -} diff --git a/test/eos/mocked_data/test_get_network_instances/issue-1922/show_vrf.text b/test/eos/mocked_data/test_get_network_instances/issue-1922/show_vrf.text deleted file mode 100644 index cd1dbbba4..000000000 --- a/test/eos/mocked_data/test_get_network_instances/issue-1922/show_vrf.text +++ /dev/null @@ -1,12 +0,0 @@ -Maximum number of vrfs allowed: 1023 - VRF RD Protocols State Interfaces ----------------- --------------- --------------- ------------------- --------------------------- - default ipv4,ipv6 v4:routing, Ethernet1, Ethernet2, - v6:no routing Ethernet3, Ethernet4, - Ethernet49/1, Ethernet5, - Ethernet50/1, Ethernet52/1, - Ethernet53/1, Ethernet54/1, - Ethernet55/1, Ethernet56/1, - Loopback0 - management ipv4,ipv6 v4:routing, Management1 - v6:no routing diff --git a/test/eos/mocked_data/test_get_network_instances/issue-509/show_vrf.text b/test/eos/mocked_data/test_get_network_instances/issue-509/show_vrf.text index 65fdb6529..e81cd6e11 100644 --- a/test/eos/mocked_data/test_get_network_instances/issue-509/show_vrf.text +++ b/test/eos/mocked_data/test_get_network_instances/issue-509/show_vrf.text @@ -1,11 +1,11 @@ Maximum number of vrfs allowed: 14 - Vrf RD Protocols State Interfaces -------- --------- ------------ ------------------------ ------------------- - VRFA0 201:201 ipv4 v4:routing; multicast, Vlan2, Vlan102 - v6:no routing + Vrf RD Protocols State Interfaces +------- ------------ ------------ ------------------- ------------------- +VRFA0 201:201 ipv4 v4:routing; multicast, Vlan2, Vlan102 + v6:no routing - VRFA1 203:203 ipv4 v4:routing; multicast, Vlan3, Vlan103 - v6:no routing +VRFA1 203:203 ipv4 v4:routing; multicast, Vlan3, Vlan103 + v6:no routing - VRFA2 205:205 ipv4 v4:routing; multicast, Ethernet1, Vlan100 - v6:no routing +VRFA2 205:205 ipv4 v4:routing; multicast, Ethernet1, Vlan100 + v6:no routing diff --git a/test/eos/mocked_data/test_get_network_instances/vrf/cli_version.txt b/test/eos/mocked_data/test_get_network_instances/vrf/cli_version.txt deleted file mode 100644 index 0cfbf0888..000000000 --- a/test/eos/mocked_data/test_get_network_instances/vrf/cli_version.txt +++ /dev/null @@ -1 +0,0 @@ -2 diff --git a/test/eos/mocked_data/test_get_network_instances/vrf/expected_result.json b/test/eos/mocked_data/test_get_network_instances/vrf/expected_result.json deleted file mode 100644 index dc3f3d294..000000000 --- a/test/eos/mocked_data/test_get_network_instances/vrf/expected_result.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "default": { - "name": "default", - "type": "DEFAULT_INSTANCE", - "state": { "route_distinguisher": "" }, - "interfaces": { - "interface": { - "Ethernet1": {}, - "Ethernet2": {}, - "Loopback0": {}, - "Management0": {} - } - } - }, - "foo": { - "name": "foo", - "type": "L3VRF", - "state": { "route_distinguisher": "0:1" }, - "interfaces": { - "interface": {} - } - }, - "bar": { - "name": "bar", - "type": "L3VRF", - "state": { "route_distinguisher": "" }, - "interfaces": { - "interface": {} - } - } -} diff --git a/test/eos/mocked_data/test_get_network_instances/vrf/show_vrf.json b/test/eos/mocked_data/test_get_network_instances/vrf/show_vrf.json deleted file mode 100644 index bbc04245a..000000000 --- a/test/eos/mocked_data/test_get_network_instances/vrf/show_vrf.json +++ /dev/null @@ -1,61 +0,0 @@ -{ - "vrfs": { - "foo": { - "routeDistinguisher": "0:1", - "protocols": { - "ipv4": { - "supported": true, - "protocolState": "up", - "routingState": "up" - }, - "ipv6": { - "supported": true, - "protocolState": "up", - "routingState": "down" - } - }, - "vrfState": "up", - "interfacesV4": [], - "interfacesV6": [], - "interfaces": [] - }, - "bar": { - "routeDistinguisher": "", - "protocols": { - "ipv4": { - "supported": true, - "protocolState": "up", - "routingState": "down" - }, - "ipv6": { - "supported": true, - "protocolState": "up", - "routingState": "down" - } - }, - "vrfState": "up", - "interfacesV4": [], - "interfacesV6": [], - "interfaces": [] - }, - "default": { - "routeDistinguisher": "", - "protocols": { - "ipv4": { - "supported": true, - "protocolState": "up", - "routingState": "up" - }, - "ipv6": { - "supported": true, - "protocolState": "up", - "routingState": "down" - } - }, - "vrfState": "up", - "interfacesV4": ["Ethernet1", "Ethernet2", "Loopback0", "Management0"], - "interfacesV6": ["Management0"], - "interfaces": ["Ethernet1", "Ethernet2", "Loopback0", "Management0"] - } - } -} diff --git a/test/ios/mocked_data/test_get_bgp_config/mixed_with_without_groups/expected_result.json b/test/ios/mocked_data/test_get_bgp_config/mixed_with_without_groups/expected_result.json index d6a2343ac..f74d5a593 100644 --- a/test/ios/mocked_data/test_get_bgp_config/mixed_with_without_groups/expected_result.json +++ b/test/ios/mocked_data/test_get_bgp_config/mixed_with_without_groups/expected_result.json @@ -5,7 +5,7 @@ "export_policy": "PASS-OUT", "import_policy": "PASS-IN", "local_address": "GigabitEthernet1", - "local_as": 65001, + "local_as": 0, "multihop_ttl": 0, "multipath": false, "neighbors": { @@ -15,7 +15,7 @@ "export_policy": "", "import_policy": "", "local_address": "", - "local_as": 65001, + "local_as": 0, "nhs": false, "prefix_limit": { "inet": { @@ -37,7 +37,7 @@ "export_policy": "", "import_policy": "", "local_address": "", - "local_as": 65001, + "local_as": 0, "nhs": false, "prefix_limit": { "inet": { @@ -75,7 +75,7 @@ "export_policy": "", "import_policy": "", "local_address": "", - "local_as": 65001, + "local_as": 0, "multihop_ttl": 0, "multipath": false, "neighbors": { diff --git a/test/ios/mocked_data/test_get_bgp_config/no_afi/expected_result.json b/test/ios/mocked_data/test_get_bgp_config/no_afi/expected_result.json index b75943177..6c5a9cbaa 100644 --- a/test/ios/mocked_data/test_get_bgp_config/no_afi/expected_result.json +++ b/test/ios/mocked_data/test_get_bgp_config/no_afi/expected_result.json @@ -2,7 +2,7 @@ "_": { "apply_groups": [], "description": "", - "local_as": 42, + "local_as": 0, "type": "", "import_policy": "", "export_policy": "", @@ -20,7 +20,7 @@ "export_policy": "", "import_policy": "", "local_address": "", - "local_as": 42, + "local_as": 0, "authentication_key": "", "nhs": false, "route_reflector_client": false diff --git a/test/ios/mocked_data/test_get_bgp_config/no_bgp/expected_result.json b/test/ios/mocked_data/test_get_bgp_config/no_bgp/expected_result.json deleted file mode 100644 index 0967ef424..000000000 --- a/test/ios/mocked_data/test_get_bgp_config/no_bgp/expected_result.json +++ /dev/null @@ -1 +0,0 @@ -{} diff --git a/test/ios/mocked_data/test_get_bgp_config/no_bgp/show_running_config.txt b/test/ios/mocked_data/test_get_bgp_config/no_bgp/show_running_config.txt deleted file mode 100644 index 50e08a544..000000000 --- a/test/ios/mocked_data/test_get_bgp_config/no_bgp/show_running_config.txt +++ /dev/null @@ -1,150 +0,0 @@ -! -! Last configuration change at 18:41:02 UTC Thu Nov 24 2016 -! -version 15.5 -service timestamps debug datetime msec -service timestamps log datetime msec -no platform punt-keepalive disable-kernel-core -platform console auto -! -hostname CSR1 -! -boot-start-marker -boot-end-marker -! -! -enable password cisco -! -aaa new-model -! -! -aaa authentication login default local -aaa authorization exec default local -! -! -! -! -! -aaa session-id common -! -ip vrf MGMT -! -! -! -! -! -! -! -! -! - - -ip domain name example.local - -! -! -! -! -! -! -! -! -! -! -subscriber templating -! -multilink bundle-name authenticated -! -! -! -! -! -! -! -! -! -! -! -! -! -license udi pid CSR1000V sn 9OSEGKJXRHE -spanning-tree extend system-id -! -username cisco privilege 15 password 0 cisco -! -redundancy -! -! -! -! -! -! -! -! -! -! -! -! -! -! -! -! -! -! -! -! -! -! -! -interface Loopback0 - ip address 1.1.1.1 255.255.255.255 -! -interface GigabitEthernet1 - ip vrf forwarding MGMT - ip address 192.168.35.121 255.255.255.0 - negotiation auto -! -interface GigabitEthernet2 - ip address 10.1.1.1 255.255.255.0 - negotiation auto -! -interface GigabitEthernet3 - no ip address - shutdown - negotiation auto -! -router ospf 1 - redistribute connected subnets - network 10.1.1.0 0.0.0.255 area 0 -! -! -! -! -virtual-service csr_mgmt -! -ip forward-protocol nd -! -no ip http server -no ip http secure-server -! -! -! -! -! -! -control-plane -! - ! - ! - ! - ! -! -! -! -! -! -line con 0 -line vty 0 4 -! -! -end diff --git a/test/ios/mocked_data/test_get_bgp_config/normal/expected_result.json b/test/ios/mocked_data/test_get_bgp_config/normal/expected_result.json index f58f5e0c5..3f4742397 100644 --- a/test/ios/mocked_data/test_get_bgp_config/normal/expected_result.json +++ b/test/ios/mocked_data/test_get_bgp_config/normal/expected_result.json @@ -1,26 +1,11 @@ { - "_": { - "apply_groups": [], - "description": "", - "local_as": 65001, - "type": "", - "import_policy": "", - "export_policy": "", - "local_address": "", - "multipath": false, - "multihop_ttl": 0, - "remote_as": 0, - "remove_private_as": false, - "prefix_limit": {}, - "neighbors": {} - }, "RR-CLIENTS": { "apply_groups": [], "description": "[ibgp - rr clients]", "export_policy": "PASS-OUT", "import_policy": "PASS-IN", "local_address": "GigabitEthernet1", - "local_as": 65001, + "local_as": 0, "multihop_ttl": 0, "multipath": false, "neighbors": { @@ -30,7 +15,7 @@ "export_policy": "", "import_policy": "", "local_address": "", - "local_as": 65001, + "local_as": 0, "nhs": false, "prefix_limit": { "inet": { @@ -52,7 +37,7 @@ "export_policy": "", "import_policy": "", "local_address": "", - "local_as": 65001, + "local_as": 0, "nhs": false, "prefix_limit": { "inet": { diff --git a/test/ios/mocked_data/test_get_bgp_config/peers_without_groups/expected_result.json b/test/ios/mocked_data/test_get_bgp_config/peers_without_groups/expected_result.json index 1f53b03ff..d2dfbaf32 100644 --- a/test/ios/mocked_data/test_get_bgp_config/peers_without_groups/expected_result.json +++ b/test/ios/mocked_data/test_get_bgp_config/peers_without_groups/expected_result.json @@ -5,7 +5,7 @@ "export_policy": "", "import_policy": "", "local_address": "", - "local_as": 65001, + "local_as": 0, "multihop_ttl": 0, "multipath": false, "neighbors": { @@ -15,7 +15,7 @@ "export_policy": "PASS-OUT", "import_policy": "PASS-IN", "local_address": "GigabitEthernet1", - "local_as": 65001, + "local_as": 0, "nhs": false, "prefix_limit": { "inet": { @@ -37,4 +37,4 @@ "remove_private_as": false, "type": "" } -} +} \ No newline at end of file diff --git a/test/ios/mocked_data/test_get_lldp_neighbors/no_mac_support/expected_result.json b/test/ios/mocked_data/test_get_lldp_neighbors/no_mac_support/expected_result.json deleted file mode 100644 index 49bc80227..000000000 --- a/test/ios/mocked_data/test_get_lldp_neighbors/no_mac_support/expected_result.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "GigabitEthernet9/48": [ - { - "port": "Gi0", - "hostname": "COMPUTER.company.example.com" - } - ] - , - "GigabitEthernet9/8": [ - { - "port": "A1:8B:95:B5:E4:6F", - "hostname": "NICEHOSTNAME" - } - ] -} diff --git a/test/ios/mocked_data/test_get_lldp_neighbors/no_mac_support/show_lldp_neighbors.txt b/test/ios/mocked_data/test_get_lldp_neighbors/no_mac_support/show_lldp_neighbors.txt deleted file mode 100644 index f7074e0d7..000000000 --- a/test/ios/mocked_data/test_get_lldp_neighbors/no_mac_support/show_lldp_neighbors.txt +++ /dev/null @@ -1,8 +0,0 @@ - -Capability codes: - (R) Router, (B) Bridge, (T) Telephone, (C) DOCSIS Cable Device - (W) WLAN Access Point, (P) Repeater, (S) Station, (O) Other - -Device ID Local Intf Hold-time Capability Port ID -ACOMPUTER.company.exGi9/48 120 B Gi0 -NICEHOSTNAME Gi9/8 3601 a18b.95b5.e46f diff --git a/test/ios/mocked_data/test_get_lldp_neighbors/no_mac_support/show_lldp_neighbors_detail.txt b/test/ios/mocked_data/test_get_lldp_neighbors/no_mac_support/show_lldp_neighbors_detail.txt deleted file mode 100644 index 5908277d6..000000000 --- a/test/ios/mocked_data/test_get_lldp_neighbors/no_mac_support/show_lldp_neighbors_detail.txt +++ /dev/null @@ -1,68 +0,0 @@ ------------------------------------------------- -Local Intf: Gi9/48 -Chassis id: 4a07.d0f3.fbb6 -Port id: Gi0 -Port Description: GigabitEthernet0 -System Name: COMPUTER.company.example.com - -System Description: -Cisco IOS Software, C3600 Software (AP3G2-K9W8-M), Version 15.3(3)JC15, RELEASE SOFTWARE (fc1) -Technical Support: http://www.cisco.com/techsupport -Copyright (c) 1986-2018 by Cisco Systems, Inc. -Compiled Thu 07-Jun-18 16:43 by prod_rel_team - -Time remaining: 95 seconds -System Capabilities: B -Enabled Capabilities: B -Management Addresses: - IP: 10.31.18.65 -Auto Negotiation - supported, enabled -Physical media capabilities: - 1000baseT(FD) - 1000baseT(HD) - 100base-TX(FD) - 100base-TX(HD) - 10base-T(FD) - 10base-T(HD) -Media Attachment Unit type: 30 -Vlan ID: - not advertised -PoE+ Power-via-MDI TLV: - Power Pair: Signal - Power Class: Class 4 - Power Device Type: Type 1 PD - Power Source: PSE - Power Priority: high - Power Requested: 13000 mW - Power Allocated: 13000 mW - ------------------------------------------------- -Local Intf: Gi9/8 -Chassis id: NICEHOSTNAME -Port id: a18b.95b5.e46f -Port Description - not advertised -System Name - not advertised -System Description - not advertised - -Time remaining: 2690 seconds -System Capabilities - not advertised -Enabled Capabilities - not advertised -Management Addresses - not advertised -Auto Negotiation - supported, enabled -Physical media capabilities: - 1000baseT(FD) -Media Attachment Unit type - not advertised -Vlan ID: - not advertised - -MED Information: - - MED Codes: - (NP) Network Policy, (LI) Location Identification - (PS) Power Source Entity, (PD) Power Device - (IN) Inventory - - Inventory information - not advertised - Capabilities: - Device type: Endpoint Class I - Network Policies - not advertised - Power requirements - not advertised - Location - not advertised diff --git a/test/iosxr/mocked_data/test_get_bgp_config/mixed_with_without_groups/expected_result.json b/test/iosxr/mocked_data/test_get_bgp_config/mixed_with_without_groups/expected_result.json index 60e669b26..e39f06c91 100644 --- a/test/iosxr/mocked_data/test_get_bgp_config/mixed_with_without_groups/expected_result.json +++ b/test/iosxr/mocked_data/test_get_bgp_config/mixed_with_without_groups/expected_result.json @@ -8,7 +8,7 @@ "description": "", "route_reflector_client": false, "nhs": false, - "local_as": 65900, + "local_as": 0, "import_policy": "pass-all", "local_address": "", "prefix_limit": { @@ -30,7 +30,7 @@ "description": "", "route_reflector_client": false, "nhs": false, - "local_as": 65900, + "local_as": 0, "import_policy": "pass-all", "local_address": "", "prefix_limit": { @@ -54,7 +54,7 @@ "remove_private_as": false, "description": "", "export_policy": "", - "local_as": 65900, + "local_as": 0, "apply_groups": [], "multipath": false, "prefix_limit": {} @@ -68,7 +68,7 @@ "description": "", "route_reflector_client": false, "nhs": false, - "local_as": 65900, + "local_as": 0, "import_policy": "RP-SPECIAL-SNOWFLAKE-IN", "local_address": "", "prefix_limit": { @@ -90,7 +90,7 @@ "description": "", "route_reflector_client": false, "nhs": false, - "local_as": 65900, + "local_as": 0, "import_policy": "", "local_address": "", "prefix_limit": {}, @@ -104,7 +104,7 @@ "remove_private_as": true, "description": "", "export_policy": "", - "local_as": 65900, + "local_as": 0, "apply_groups": [], "multipath": false, "prefix_limit": {} diff --git a/test/iosxr/mocked_data/test_get_bgp_config/no_bgp/_Get__Configuration__BGP__Instance__Naming__________InstanceName_default__InstanceName___Naming___Instance___BGP___Configuration___Get_.txt b/test/iosxr/mocked_data/test_get_bgp_config/no_bgp/_Get__Configuration__BGP__Instance__Naming__________InstanceName_default__InstanceName___Naming___Instance___BGP___Configuration___Get_.txt deleted file mode 100644 index 1bcd305b2..000000000 --- a/test/iosxr/mocked_data/test_get_bgp_config/no_bgp/_Get__Configuration__BGP__Instance__Naming__________InstanceName_default__InstanceName___Naming___Instance___BGP___Configuration___Get_.txt +++ /dev/null @@ -1,2 +0,0 @@ - -default diff --git a/test/iosxr/mocked_data/test_get_bgp_config/no_bgp/expected_result.json b/test/iosxr/mocked_data/test_get_bgp_config/no_bgp/expected_result.json deleted file mode 100644 index 0967ef424..000000000 --- a/test/iosxr/mocked_data/test_get_bgp_config/no_bgp/expected_result.json +++ /dev/null @@ -1 +0,0 @@ -{} diff --git a/test/iosxr/mocked_data/test_get_bgp_config/normal/expected_result.json b/test/iosxr/mocked_data/test_get_bgp_config/normal/expected_result.json index c850fe601..20971ddf8 100644 --- a/test/iosxr/mocked_data/test_get_bgp_config/normal/expected_result.json +++ b/test/iosxr/mocked_data/test_get_bgp_config/normal/expected_result.json @@ -1,28 +1,13 @@ { - "_": { - "local_as": 13335, - "remove_private_as": false, - "import_policy": "", - "multihop_ttl": 0, - "neighbors": {}, - "multipath": false, - "export_policy": "", - "type": "", - "apply_groups": [], - "remote_as": 0, - "prefix_limit": {}, - "description": "", - "local_address": "" - }, "4-public-anycast-peers": { - "local_as": 13335, + "local_as": 0, "remove_private_as": true, "import_policy": "4-public-anycast-peers-in", "multihop_ttl": 0, "neighbors": { "192.168.20.3": { "export_policy": "", - "local_as": 13335, + "local_as": 0, "prefix_limit": { "inet": { "unicast": { @@ -44,7 +29,7 @@ }, "172.17.17.50": { "export_policy": "", - "local_as": 13335, + "local_as": 0, "prefix_limit": { "inet": { "unicast": { @@ -66,7 +51,7 @@ }, "192.168.50.5": { "export_policy": "", - "local_as": 13335, + "local_as": 0, "prefix_limit": { "inet": { "unicast": { diff --git a/test/iosxr/mocked_data/test_get_bgp_config/peers_without_groups/expected_result.json b/test/iosxr/mocked_data/test_get_bgp_config/peers_without_groups/expected_result.json index 30a30dd4c..bc0239416 100644 --- a/test/iosxr/mocked_data/test_get_bgp_config/peers_without_groups/expected_result.json +++ b/test/iosxr/mocked_data/test_get_bgp_config/peers_without_groups/expected_result.json @@ -10,7 +10,7 @@ "remove_private_as": false, "remote_as": 0, "multihop_ttl": 0, - "local_as": 65900, + "local_as": 0, "apply_groups": [], "neighbors": { "10.255.255.2": { @@ -26,7 +26,7 @@ } } }, - "local_as": 65900, + "local_as": 0, "description": "", "local_address": "", "import_policy": "pass-all", @@ -48,7 +48,7 @@ } } }, - "local_as": 65900, + "local_as": 0, "description": "", "local_address": "", "import_policy": "pass-all", diff --git a/test/iosxr_netconf/mocked_data/test_get_bgp_config/no_bgp/expected_result.json b/test/iosxr_netconf/mocked_data/test_get_bgp_config/no_bgp/expected_result.json deleted file mode 100644 index 0967ef424..000000000 --- a/test/iosxr_netconf/mocked_data/test_get_bgp_config/no_bgp/expected_result.json +++ /dev/null @@ -1 +0,0 @@ -{} diff --git a/test/iosxr_netconf/mocked_data/test_get_bgp_config/no_bgp/ipv4-bgp-cfg_bgp__running.xml b/test/iosxr_netconf/mocked_data/test_get_bgp_config/no_bgp/ipv4-bgp-cfg_bgp__running.xml deleted file mode 100644 index 7a3a0b218..000000000 --- a/test/iosxr_netconf/mocked_data/test_get_bgp_config/no_bgp/ipv4-bgp-cfg_bgp__running.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - diff --git a/test/iosxr_netconf/mocked_data/test_get_bgp_config/normal/expected_result.json b/test/iosxr_netconf/mocked_data/test_get_bgp_config/normal/expected_result.json index 4ed653140..1d60e8893 100644 --- a/test/iosxr_netconf/mocked_data/test_get_bgp_config/normal/expected_result.json +++ b/test/iosxr_netconf/mocked_data/test_get_bgp_config/normal/expected_result.json @@ -1,26 +1,11 @@ { - "_": { - "apply_groups": [], - "description": "", - "export_policy": "", - "import_policy": "", - "local_address": "", - "local_as": 65172, - "multihop_ttl": 0, - "multipath": false, - "neighbors": {}, - "prefix_limit": {}, - "remote_as": 0, - "remove_private_as": false, - "type": "" - }, "EBGP": { "apply_groups": [], "description": "", "export_policy": "EBGP-OUT-POLICY", "import_policy": "EBGP-IN-POLICY", "local_address": "", - "local_as": 65172, + "local_as": 0, "multihop_ttl": 0, "multipath": false, "neighbors": { @@ -30,7 +15,7 @@ "export_policy": "", "import_policy": "", "local_address": "", - "local_as": 65172, + "local_as": 0, "nhs": false, "prefix_limit": { "inet": { @@ -52,7 +37,7 @@ "export_policy": "", "import_policy": "", "local_address": "", - "local_as": 65172, + "local_as": 0, "nhs": false, "prefix_limit": { "inet": { @@ -80,7 +65,7 @@ "export_policy": "EBGP-VRF-OUT-POLICY", "import_policy": "EBGP-VRF-IN-POLICY", "local_address": "", - "local_as": 65172, + "local_as": 0, "multihop_ttl": 0, "multipath": false, "neighbors": {}, @@ -95,7 +80,7 @@ "export_policy": "IBGPv6-OUT-POLICY", "import_policy": "IBGPv6-IN-POLICY", "local_address": "", - "local_as": 65172, + "local_as": 0, "multihop_ttl": 0, "multipath": false, "neighbors": { @@ -105,7 +90,7 @@ "export_policy": "", "import_policy": "", "local_address": "", - "local_as": 65172, + "local_as": 0, "nhs": false, "prefix_limit": { "inet6": { @@ -127,7 +112,7 @@ "export_policy": "", "import_policy": "", "local_address": "", - "local_as": 65172, + "local_as": 0, "nhs": false, "prefix_limit": { "inet6": { @@ -155,7 +140,7 @@ "export_policy": "EBGPv6-VRF-OUT-POLICY", "import_policy": "EBGPv6-VRF-IN-POLICY", "local_address": "", - "local_as": 65172, + "local_as": 0, "multihop_ttl": 0, "multipath": false, "neighbors": {}, @@ -170,7 +155,7 @@ "export_policy": "IBGP-OUT-POLICY", "import_policy": "", "local_address": "", - "local_as": 65172, + "local_as": 0, "multihop_ttl": 0, "multipath": false, "neighbors": { @@ -180,7 +165,7 @@ "export_policy": "", "import_policy": "", "local_address": "", - "local_as": 65172, + "local_as": 0, "nhs": false, "prefix_limit": { "inet": { @@ -208,7 +193,7 @@ "export_policy": "IBGP-OUT-POLICY", "import_policy": "", "local_address": "", - "local_as": 65172, + "local_as": 0, "multihop_ttl": 0, "multipath": false, "neighbors": { @@ -218,7 +203,7 @@ "export_policy": "", "import_policy": "", "local_address": "", - "local_as": 65172, + "local_as": 0, "nhs": false, "prefix_limit": { "inet6": { diff --git a/test/junos/mocked_data/test_get_bgp_config/nhs/_configuration__routing_options__autonomous_system____routing_options___configuration_.xml b/test/junos/mocked_data/test_get_bgp_config/nhs/_configuration__routing_options__autonomous_system____routing_options___configuration_.xml deleted file mode 100644 index bd581bc2c..000000000 --- a/test/junos/mocked_data/test_get_bgp_config/nhs/_configuration__routing_options__autonomous_system____routing_options___configuration_.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - 65001 - - - diff --git a/test/junos/mocked_data/test_get_bgp_config/nhs/expected_result.json b/test/junos/mocked_data/test_get_bgp_config/nhs/expected_result.json index a375a75a0..93c77a2ec 100644 --- a/test/junos/mocked_data/test_get_bgp_config/nhs/expected_result.json +++ b/test/junos/mocked_data/test_get_bgp_config/nhs/expected_result.json @@ -1,73 +1 @@ -{ - "_": { - "export_policy": "", - "multipath": false, - "prefix_limit": {}, - "description": "", - "local_as": 65001, - "multihop_ttl": 0, - "apply_groups": [], - "remote_as": 0, - "remove_private_as": false, - "local_address": "", - "type": "", - "import_policy": "", - "neighbors": {} - }, - "internal": { - "apply_groups": [], - "description": "", - "export_policy": "", - "import_policy": "", - "local_address": "", - "local_as": 65001, - "multihop_ttl": 0, - "multipath": false, - "neighbors": { - "10.10.10.1": { - "authentication_key": "", - "description": "", - "export_policy": "nhs", - "import_policy": "", - "local_address": "", - "local_as": 65001, - "nhs": true, - "prefix_limit": {}, - "remote_as": 0, - "route_reflector_client": false - } - }, - "prefix_limit": {}, - "remote_as": 0, - "remove_private_as": false, - "type": "internal" - }, - "internal-2": { - "apply_groups": [], - "description": "", - "export_policy": "", - "import_policy": "", - "local_address": "", - "local_as": 65001, - "multihop_ttl": 0, - "multipath": false, - "neighbors": { - "10.10.10.2": { - "authentication_key": "", - "description": "", - "export_policy": "static", - "import_policy": "", - "local_address": "", - "local_as": 65001, - "nhs": false, - "prefix_limit": {}, - "remote_as": 0, - "route_reflector_client": false - } - }, - "prefix_limit": {}, - "remote_as": 0, - "remove_private_as": false, - "type": "internal" - } -} +{"internal":{"apply_groups":[],"description":"","export_policy":"","import_policy":"","local_address":"","local_as":0,"multihop_ttl":0,"multipath":false,"neighbors":{"10.10.10.1":{"authentication_key":"","description":"","export_policy":"nhs","import_policy":"","local_address":"","local_as":0,"nhs":true,"prefix_limit":{},"remote_as":0,"route_reflector_client":false}},"prefix_limit":{},"remote_as":0,"remove_private_as":false,"type":"internal"},"internal-2":{"apply_groups":[],"description":"","export_policy":"","import_policy":"","local_address":"","local_as":0,"multihop_ttl":0,"multipath":false,"neighbors":{"10.10.10.2":{"authentication_key":"","description":"","export_policy":"static","import_policy":"","local_address":"","local_as":0,"nhs":false,"prefix_limit":{},"remote_as":0,"route_reflector_client":false}},"prefix_limit":{},"remote_as":0,"remove_private_as":false,"type":"internal"}} diff --git a/test/junos/mocked_data/test_get_bgp_config/no_bgp/_configuration__policy_options__policy_statement____policy_options___configuration_.xml b/test/junos/mocked_data/test_get_bgp_config/no_bgp/_configuration__policy_options__policy_statement____policy_options___configuration_.xml deleted file mode 100644 index 83138436e..000000000 --- a/test/junos/mocked_data/test_get_bgp_config/no_bgp/_configuration__policy_options__policy_statement____policy_options___configuration_.xml +++ /dev/null @@ -1,2 +0,0 @@ - - diff --git a/test/junos/mocked_data/test_get_bgp_config/no_bgp/_configuration__protocols__bgp__group____bgp___protocols___configuration_.xml b/test/junos/mocked_data/test_get_bgp_config/no_bgp/_configuration__protocols__bgp__group____bgp___protocols___configuration_.xml deleted file mode 100644 index 83138436e..000000000 --- a/test/junos/mocked_data/test_get_bgp_config/no_bgp/_configuration__protocols__bgp__group____bgp___protocols___configuration_.xml +++ /dev/null @@ -1,2 +0,0 @@ - - diff --git a/test/junos/mocked_data/test_get_bgp_config/no_bgp/_configuration__routing_options__autonomous_system____routing_options___configuration_.xml b/test/junos/mocked_data/test_get_bgp_config/no_bgp/_configuration__routing_options__autonomous_system____routing_options___configuration_.xml deleted file mode 100644 index 83138436e..000000000 --- a/test/junos/mocked_data/test_get_bgp_config/no_bgp/_configuration__routing_options__autonomous_system____routing_options___configuration_.xml +++ /dev/null @@ -1,2 +0,0 @@ - - diff --git a/test/junos/mocked_data/test_get_bgp_config/no_bgp/expected_result.json b/test/junos/mocked_data/test_get_bgp_config/no_bgp/expected_result.json deleted file mode 100644 index 0967ef424..000000000 --- a/test/junos/mocked_data/test_get_bgp_config/no_bgp/expected_result.json +++ /dev/null @@ -1 +0,0 @@ -{} diff --git a/test/junos/mocked_data/test_get_bgp_config/normal/_configuration__routing_options__autonomous_system____routing_options___configuration_.xml b/test/junos/mocked_data/test_get_bgp_config/normal/_configuration__routing_options__autonomous_system____routing_options___configuration_.xml deleted file mode 100644 index 6ad44d234..000000000 --- a/test/junos/mocked_data/test_get_bgp_config/normal/_configuration__routing_options__autonomous_system____routing_options___configuration_.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - 13335 - - - diff --git a/test/junos/mocked_data/test_get_bgp_config/normal/expected_result.json b/test/junos/mocked_data/test_get_bgp_config/normal/expected_result.json index 6c44290dd..868ef99cc 100644 --- a/test/junos/mocked_data/test_get_bgp_config/normal/expected_result.json +++ b/test/junos/mocked_data/test_get_bgp_config/normal/expected_result.json @@ -1,69 +1 @@ -{ - "_": { - "export_policy": "", - "multipath": false, - "prefix_limit": {}, - "description": "", - "local_as": 13335, - "multihop_ttl": 0, - "apply_groups": [], - "remote_as": 0, - "remove_private_as": false, - "local_address": "", - "type": "", - "import_policy": "", - "neighbors": {} - }, - "PEERS-GROUP-NAME": { - "neighbors": { - "192.168.0.1": { - "export_policy": "", - "prefix_limit": { - "inet": { - "unicast": { - "limit": 100 - } - } - }, - "route_reflector_client": false, - "description": "Facebook [CDN]", - "local_as": 13335, - "nhs": false, - "local_address": "", - "remote_as": 32934, - "authentication_key": "", - "import_policy": "" - }, - "172.17.17.1": { - "export_policy": "", - "prefix_limit": { - "inet": { - "unicast": { - "limit": 500 - } - } - }, - "route_reflector_client": false, - "description": "Twitter [CDN]", - "local_as": 13335, - "nhs": false, - "local_address": "", - "remote_as": 13414, - "authentication_key": "", - "import_policy": "" - } - }, - "export_policy": "PUBLIC-PEER-OUT", - "multipath": true, - "prefix_limit": {}, - "description": "", - "local_as": 13335, - "multihop_ttl": 0, - "apply_groups": ["BGP-PREFIX-LIMIT"], - "remote_as": 0, - "remove_private_as": true, - "local_address": "", - "type": "external", - "import_policy": "PUBLIC-PEER-IN" - } -} +{"PEERS-GROUP-NAME": {"neighbors": {"192.168.0.1": {"export_policy": "", "prefix_limit": {"inet": {"unicast": {"limit": 100}}}, "route_reflector_client": false, "description": "Facebook [CDN]", "local_as": 0, "nhs": false, "local_address": "", "remote_as": 32934, "authentication_key": "", "import_policy": ""}, "172.17.17.1": {"export_policy": "", "prefix_limit": {"inet": {"unicast": {"limit": 500}}}, "route_reflector_client": false, "description": "Twitter [CDN]", "local_as": 0, "nhs": false, "local_address": "", "remote_as": 13414, "authentication_key": "", "import_policy": ""}}, "export_policy": "PUBLIC-PEER-OUT", "multipath": true, "prefix_limit": {}, "description": "", "local_as": 13335, "multihop_ttl": 0, "apply_groups": ["B", "G", "P", "-", "P", "R", "E", "F", "I", "X", "-", "L", "I", "M", "I", "T"], "remote_as": 0, "remove_private_as": true, "local_address": "", "type": "external", "import_policy": "PUBLIC-PEER-IN"}} diff --git a/test/nxos_ssh/mocked_data/test_get_network_instances/normal/expected_result.json b/test/nxos_ssh/mocked_data/test_get_network_instances/normal/expected_result.json deleted file mode 100644 index ca3d2f110..000000000 --- a/test/nxos_ssh/mocked_data/test_get_network_instances/normal/expected_result.json +++ /dev/null @@ -1,36 +0,0 @@ -{ - "management": { - "name": "management", - "type": "L3VRF", - "state": { - "route_distinguisher": "0:0" - }, - "interfaces": { - "interface": { - "mgmt0": {} - } - } - }, - "default": { - "name": "default", - "type": "DEFAULT_INSTANCE", - "state": { - "route_distinguisher": "0:0" - }, - "interfaces": { - "interface": { - "Vlan1": {}, - "Vlan100": {}, - "Vlan101": {}, - "Vlan102": {}, - "Vlan103": {}, - "Vlan104": {}, - "Vlan105": {}, - "loopback1": {}, - "Null0": {}, - "Ethernet1/5": {}, - "Ethernet1/5.1": {} - } - } - } -} diff --git a/test/nxos_ssh/mocked_data/test_get_network_instances/normal/show_vrf_detail___json.txt b/test/nxos_ssh/mocked_data/test_get_network_instances/normal/show_vrf_detail___json.txt deleted file mode 100644 index 637f62365..000000000 --- a/test/nxos_ssh/mocked_data/test_get_network_instances/normal/show_vrf_detail___json.txt +++ /dev/null @@ -1,58 +0,0 @@ -{ - "TABLE_vrf": { - "ROW_vrf": [ - { - "vrf_name": "default", - "vrf_id": 1, - "vrf_state": "Up", - "vpnid": "unknown", - "rd": "0:0", - "vni": 0, - "max_routes": 0, - "mid_threshold": 0, - "TABLE_tib": { - "ROW_tib": [ - { - "tib_id": 80000001, - "tib_af": "IPv6", - "tib_nonce": 80000001, - "tib_state": "Up" - }, - { - "tib_id": 1, - "tib_af": "IPv4", - "tib_nonce": 1, - "tib_state": "Up" - } - ] - } - }, - { - "vrf_name": "management", - "vrf_id": 2, - "vrf_state": "Up", - "vpnid": "unknown", - "rd": "0:0", - "vni": 0, - "max_routes": 0, - "mid_threshold": 0, - "TABLE_tib": { - "ROW_tib": [ - { - "tib_id": 80000002, - "tib_af": "IPv6", - "tib_nonce": 80000002, - "tib_state": "Up" - }, - { - "tib_id": 2, - "tib_af": "IPv4", - "tib_nonce": 2, - "tib_state": "Up" - } - ] - } - } - ] - } -} diff --git a/test/nxos_ssh/mocked_data/test_get_network_instances/normal/show_vrf_interface___json.txt b/test/nxos_ssh/mocked_data/test_get_network_instances/normal/show_vrf_interface___json.txt deleted file mode 100644 index 72a325a0d..000000000 --- a/test/nxos_ssh/mocked_data/test_get_network_instances/normal/show_vrf_interface___json.txt +++ /dev/null @@ -1,78 +0,0 @@ -{ - "TABLE_if": { - "ROW_if": [ - { - "if_name": "Vlan1", - "vrf_name": "default", - "vrf_id": 1, - "soo": "--" - }, - { - "if_name": "Vlan100", - "vrf_name": "default", - "vrf_id": 1, - "soo": "--" - }, - { - "if_name": "Vlan101", - "vrf_name": "default", - "vrf_id": 1, - "soo": "--" - }, - { - "if_name": "Vlan102", - "vrf_name": "default", - "vrf_id": 1, - "soo": "--" - }, - { - "if_name": "Vlan103", - "vrf_name": "default", - "vrf_id": 1, - "soo": "--" - }, - { - "if_name": "Vlan104", - "vrf_name": "default", - "vrf_id": 1, - "soo": "--" - }, - { - "if_name": "Vlan105", - "vrf_name": "default", - "vrf_id": 1, - "soo": "--" - }, - { - "if_name": "loopback1", - "vrf_name": "default", - "vrf_id": 1, - "soo": "--" - }, - { - "if_name": "Null0", - "vrf_name": "default", - "vrf_id": 1, - "soo": "--" - }, - { - "if_name": "Ethernet1/5", - "vrf_name": "default", - "vrf_id": 1, - "soo": "--" - }, - { - "if_name": "Ethernet1/5.1", - "vrf_name": "default", - "vrf_id": 1, - "soo": "--" - }, - { - "if_name": "mgmt0", - "vrf_name": "management", - "vrf_id": 2, - "soo": "--" - } - ] - } -} diff --git a/test/pyiosxr/test_iosxr.py b/test/pyiosxr/test_iosxr.py index b8485659d..9c8128c45 100755 --- a/test/pyiosxr/test_iosxr.py +++ b/test/pyiosxr/test_iosxr.py @@ -257,7 +257,7 @@ def test__getattr_show_config(self): def test__getattr__no_show(self): - """Test special attribute __getattr__ against a no-show command""" + """Test special attribute __getattr__ agains a no-show command""" raised = False diff --git a/tox.ini b/tox.ini new file mode 100644 index 000000000..a6f11697f --- /dev/null +++ b/tox.ini @@ -0,0 +1,39 @@ +[tox] +envlist = py3{6,7,8},black,pylama +skip_missing_interpreters = true + +[testenv] +deps = + -rrequirements.txt + -rrequirements-dev.txt +passenv = * + +commands = + py.test --cov=napalm --cov-report term-missing -vs --pylama {posargs} + +[testenv:black] +deps = black==20.8b1 + +basepython = python3.6 +commands = + black --check . + +[testenv:pylama] +deps = + -rrequirements-dev.txt + +basepython = python3.6 +commands = + pylama . + +[testenv:sphinx] +deps = + -rdocs/requirements.txt + +basepython = python3.6 + +commands = + make doctest + +whitelist_externals = + make