summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.devcontainer/devcontainer.json2
-rw-r--r--.github/generate_release.py22
-rw-r--r--.github/workflows/code-testing.yml12
-rw-r--r--.github/workflows/main-doc.yml2
-rw-r--r--.github/workflows/pr-triage.yml2
-rw-r--r--.gitignore1
-rw-r--r--.pre-commit-config.yaml70
-rw-r--r--.vscode/settings.json18
-rw-r--r--Dockerfile28
-rw-r--r--NOTICE28
-rw-r--r--anta/__init__.py5
-rw-r--r--anta/aioeapi.py108
-rw-r--r--anta/catalog.py383
-rw-r--r--anta/cli/__init__.py77
-rw-r--r--anta/cli/_main.py70
-rw-r--r--anta/cli/check/__init__.py7
-rw-r--r--anta/cli/check/commands.py14
-rw-r--r--anta/cli/console.py6
-rw-r--r--anta/cli/debug/__init__.py7
-rw-r--r--anta/cli/debug/commands.py45
-rw-r--r--anta/cli/debug/utils.py48
-rw-r--r--anta/cli/exec/__init__.py17
-rw-r--r--anta/cli/exec/commands.py67
-rw-r--r--anta/cli/exec/utils.py120
-rw-r--r--anta/cli/get/__init__.py7
-rw-r--r--anta/cli/get/commands.py49
-rw-r--r--anta/cli/get/utils.py131
-rw-r--r--anta/cli/nrfu/__init__.py108
-rw-r--r--anta/cli/nrfu/commands.py37
-rw-r--r--anta/cli/nrfu/utils.py95
-rw-r--r--anta/cli/utils.py128
-rw-r--r--anta/custom_types.py103
-rw-r--r--anta/decorators.py54
-rw-r--r--anta/device.py350
-rw-r--r--anta/inventory/__init__.py215
-rw-r--r--anta/inventory/exceptions.py2
-rw-r--r--anta/inventory/models.py82
-rw-r--r--anta/logger.py81
-rw-r--r--anta/models.py431
-rw-r--r--anta/reporter/__init__.py199
-rw-r--r--anta/result_manager/__init__.py225
-rw-r--r--anta/result_manager/models.py49
-rw-r--r--anta/runner.py303
-rw-r--r--anta/tests/__init__.py1
-rw-r--r--anta/tests/aaa.py310
-rw-r--r--anta/tests/avt.py234
-rw-r--r--anta/tests/bfd.py180
-rw-r--r--anta/tests/configuration.py116
-rw-r--r--anta/tests/connectivity.py159
-rw-r--r--anta/tests/field_notices.py104
-rw-r--r--anta/tests/greent.py69
-rw-r--r--anta/tests/hardware.py237
-rw-r--r--anta/tests/interfaces.py676
-rw-r--r--anta/tests/lanz.py37
-rw-r--r--anta/tests/logging.py266
-rw-r--r--anta/tests/mlag.py211
-rw-r--r--anta/tests/multicast.py71
-rw-r--r--anta/tests/path_selection.py165
-rw-r--r--anta/tests/profiles.py72
-rw-r--r--anta/tests/ptp.py232
-rw-r--r--anta/tests/routing/__init__.py1
-rw-r--r--anta/tests/routing/bgp.py857
-rw-r--r--anta/tests/routing/generic.py131
-rw-r--r--anta/tests/routing/isis.py308
-rw-r--r--anta/tests/routing/ospf.py180
-rw-r--r--anta/tests/security.py676
-rw-r--r--anta/tests/services.py165
-rw-r--r--anta/tests/snmp.py190
-rw-r--r--anta/tests/software.py108
-rw-r--r--anta/tests/stp.py191
-rw-r--r--anta/tests/stun.py117
-rw-r--r--anta/tests/system.py234
-rw-r--r--anta/tests/vlan.py46
-rw-r--r--anta/tests/vxlan.py198
-rw-r--r--anta/tools.py348
-rw-r--r--anta/tools/__init__.py3
-rw-r--r--anta/tools/get_dict_superset.py64
-rw-r--r--anta/tools/get_item.py83
-rw-r--r--anta/tools/get_value.py56
-rw-r--r--anta/tools/misc.py26
-rw-r--r--anta/tools/utils.py34
-rw-r--r--asynceapi/__init__.py12
-rw-r--r--asynceapi/aio_portcheck.py58
-rw-r--r--asynceapi/config_session.py289
-rw-r--r--asynceapi/device.py291
-rw-r--r--asynceapi/errors.py42
-rwxr-xr-xdocs/README.md46
-rw-r--r--docs/advanced_usages/as-python-lib.md14
-rw-r--r--docs/advanced_usages/caching.md6
-rw-r--r--docs/advanced_usages/custom-tests.md64
-rw-r--r--docs/api/runner.md (renamed from docs/imgs/animated-svg.md)5
-rw-r--r--docs/api/tests.aaa.md11
-rw-r--r--docs/api/tests.avt.md20
-rw-r--r--docs/api/tests.bfd.md11
-rw-r--r--docs/api/tests.configuration.md11
-rw-r--r--docs/api/tests.connectivity.md11
-rw-r--r--docs/api/tests.field_notices.md11
-rw-r--r--docs/api/tests.greent.md20
-rw-r--r--docs/api/tests.hardware.md11
-rw-r--r--docs/api/tests.interfaces.md11
-rw-r--r--docs/api/tests.lanz.md20
-rw-r--r--docs/api/tests.logging.md11
-rw-r--r--docs/api/tests.md17
-rw-r--r--docs/api/tests.mlag.md11
-rw-r--r--docs/api/tests.multicast.md11
-rw-r--r--docs/api/tests.path_selection.md20
-rw-r--r--docs/api/tests.profiles.md11
-rw-r--r--docs/api/tests.ptp.md20
-rw-r--r--docs/api/tests.routing.bgp.md11
-rw-r--r--docs/api/tests.routing.generic.md11
-rw-r--r--docs/api/tests.routing.isis.md20
-rw-r--r--docs/api/tests.routing.ospf.md11
-rw-r--r--docs/api/tests.security.md11
-rw-r--r--docs/api/tests.services.md11
-rw-r--r--docs/api/tests.snmp.md11
-rw-r--r--docs/api/tests.software.md11
-rw-r--r--docs/api/tests.stp.md11
-rw-r--r--docs/api/tests.stun.md20
-rw-r--r--docs/api/tests.system.md11
-rw-r--r--docs/api/tests.vlan.md11
-rw-r--r--docs/api/tests.vxlan.md11
-rw-r--r--docs/cli/debug.md39
-rw-r--r--docs/cli/exec.md54
-rw-r--r--docs/cli/get-inventory-information.md31
-rw-r--r--docs/cli/inv-from-ansible.md27
-rw-r--r--docs/cli/nrfu.md91
-rw-r--r--docs/cli/overview.md11
-rw-r--r--docs/contribution.md29
-rw-r--r--docs/faq.md122
-rw-r--r--docs/getting-started.md65
-rw-r--r--docs/imgs/anta-nrfu.svg2
-rw-r--r--docs/imgs/anta_nrfu___dry_run.svg127
-rw-r--r--docs/overrides/partials/content.html18
-rw-r--r--docs/overrides/partials/toc-item.html21
-rw-r--r--docs/requirements-and-installation.md46
-rw-r--r--docs/scripts/__init__.py (renamed from tests/units/tools/__init__.py)3
-rw-r--r--docs/scripts/generate_svg.py50
-rw-r--r--docs/snippets/anta_help.txt12
-rw-r--r--docs/snippets/anta_nrfu_help.txt55
-rw-r--r--docs/stylesheets/extra.material.css75
-rw-r--r--docs/templates/python/material/anta_test.html163
-rw-r--r--docs/templates/python/material/attributes_table.html70
-rw-r--r--docs/templates/python/material/class.html35
-rw-r--r--docs/templates/python/material/docstring.html36
-rw-r--r--docs/templates/python/material/docstring/examples.html14
-rw-r--r--docs/troubleshooting.md90
-rw-r--r--docs/usage-inventory-catalog.md37
-rw-r--r--examples/README.md6
-rw-r--r--examples/anta_runner.py67
-rw-r--r--examples/tests.yaml125
-rw-r--r--mkdocs.yml42
-rw-r--r--pylintrc32
-rw-r--r--pyproject.toml265
-rw-r--r--tests/__init__.py1
-rw-r--r--tests/conftest.py21
-rw-r--r--tests/data/__init__.py1
-rw-r--r--tests/data/ansible_inventory_unknown_yaml_tag.yml49
-rw-r--r--tests/data/ansible_inventory_with_vault.yml50
-rw-r--r--tests/data/json_data.py15
-rw-r--r--tests/data/test_catalog_large.yml71690
-rw-r--r--tests/data/test_catalog_medium.yml2078
-rw-r--r--tests/data/test_catalog_with_tags.yml4
-rw-r--r--tests/data/test_empty_dict_catalog.yml1
-rw-r--r--tests/data/test_inventory_large.yml103
-rw-r--r--tests/data/test_inventory_medium.yml14
-rw-r--r--tests/lib/__init__.py1
-rw-r--r--tests/lib/anta.py14
-rw-r--r--tests/lib/fixture.py174
-rw-r--r--tests/lib/utils.py24
-rw-r--r--tests/units/__init__.py1
-rw-r--r--tests/units/anta_tests/__init__.py1
-rw-r--r--tests/units/anta_tests/routing/__init__.py1
-rw-r--r--tests/units/anta_tests/routing/test_bgp.py1910
-rw-r--r--tests/units/anta_tests/routing/test_generic.py47
-rw-r--r--tests/units/anta_tests/routing/test_isis.py570
-rw-r--r--tests/units/anta_tests/routing/test_ospf.py213
-rw-r--r--tests/units/anta_tests/test_aaa.py117
-rw-r--r--tests/units/anta_tests/test_avt.py581
-rw-r--r--tests/units/anta_tests/test_bfd.py7
-rw-r--r--tests/units/anta_tests/test_configuration.py44
-rw-r--r--tests/units/anta_tests/test_connectivity.py193
-rw-r--r--tests/units/anta_tests/test_field_notices.py126
-rw-r--r--tests/units/anta_tests/test_greent.py22
-rw-r--r--tests/units/anta_tests/test_hardware.py103
-rw-r--r--tests/units/anta_tests/test_interfaces.py1219
-rw-r--r--tests/units/anta_tests/test_lanz.py5
-rw-r--r--tests/units/anta_tests/test_logging.py31
-rw-r--r--tests/units/anta_tests/test_mlag.py43
-rw-r--r--tests/units/anta_tests/test_multicast.py19
-rw-r--r--tests/units/anta_tests/test_path_selection.py327
-rw-r--r--tests/units/anta_tests/test_profiles.py9
-rw-r--r--tests/units/anta_tests/test_ptp.py308
-rw-r--r--tests/units/anta_tests/test_security.py334
-rw-r--r--tests/units/anta_tests/test_services.py7
-rw-r--r--tests/units/anta_tests/test_snmp.py5
-rw-r--r--tests/units/anta_tests/test_software.py22
-rw-r--r--tests/units/anta_tests/test_stp.py57
-rw-r--r--tests/units/anta_tests/test_stun.py176
-rw-r--r--tests/units/anta_tests/test_system.py38
-rw-r--r--tests/units/anta_tests/test_vlan.py5
-rw-r--r--tests/units/anta_tests/test_vxlan.py43
-rw-r--r--tests/units/cli/__init__.py1
-rw-r--r--tests/units/cli/check/__init__.py1
-rw-r--r--tests/units/cli/check/test__init__.py18
-rw-r--r--tests/units/cli/check/test_commands.py11
-rw-r--r--tests/units/cli/debug/__init__.py1
-rw-r--r--tests/units/cli/debug/test__init__.py18
-rw-r--r--tests/units/cli/debug/test_commands.py20
-rw-r--r--tests/units/cli/exec/__init__.py1
-rw-r--r--tests/units/cli/exec/test__init__.py18
-rw-r--r--tests/units/cli/exec/test_commands.py32
-rw-r--r--tests/units/cli/exec/test_utils.py122
-rw-r--r--tests/units/cli/get/__init__.py1
-rw-r--r--tests/units/cli/get/test__init__.py20
-rw-r--r--tests/units/cli/get/test_commands.py114
-rw-r--r--tests/units/cli/get/test_utils.py85
-rw-r--r--tests/units/cli/nrfu/__init__.py1
-rw-r--r--tests/units/cli/nrfu/test__init__.py56
-rw-r--r--tests/units/cli/nrfu/test_commands.py73
-rw-r--r--tests/units/cli/test__init__.py79
-rw-r--r--tests/units/cli/test_main.py64
-rw-r--r--tests/units/inventory/__init__.py1
-rw-r--r--tests/units/inventory/test_inventory.py19
-rw-r--r--tests/units/inventory/test_models.py76
-rw-r--r--tests/units/reporter/__init__.py1
-rw-r--r--tests/units/reporter/test__init__.py138
-rw-r--r--tests/units/result_manager/__init__.py1
-rw-r--r--tests/units/result_manager/test__init__.py335
-rw-r--r--tests/units/result_manager/test_models.py7
-rw-r--r--tests/units/test_catalog.py209
-rw-r--r--tests/units/test_custom_types.py264
-rw-r--r--tests/units/test_device.py248
-rw-r--r--tests/units/test_logger.py84
-rw-r--r--tests/units/test_models.py374
-rw-r--r--tests/units/test_runner.py178
-rw-r--r--tests/units/test_tools.py504
-rw-r--r--tests/units/tools/test_get_dict_superset.py149
-rw-r--r--tests/units/tools/test_get_item.py72
-rw-r--r--tests/units/tools/test_get_value.py50
-rw-r--r--tests/units/tools/test_misc.py38
-rw-r--r--tests/units/tools/test_utils.py57
241 files changed, 91628 insertions, 6787 deletions
diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json
index 80633ca..0c13d2c 100644
--- a/.devcontainer/devcontainer.json
+++ b/.devcontainer/devcontainer.json
@@ -15,8 +15,6 @@
"vscode": {
"settings": {},
"extensions": [
- "ms-python.black-formatter",
- "ms-python.isort",
"formulahendry.github-actions",
"matangover.mypy",
"ms-python.mypy-type-checker",
diff --git a/.github/generate_release.py b/.github/generate_release.py
index 56b6500..97f139b 100644
--- a/.github/generate_release.py
+++ b/.github/generate_release.py
@@ -1,6 +1,5 @@
#!/usr/bin/env python
-"""
-generate_release.py
+"""generate_release.py.
This script is used to generate the release.yml file as per
https://docs.github.com/en/repositories/releasing-projects-on-github/automatically-generated-release-notes
@@ -20,18 +19,15 @@ CATEGORIES = {
"fix": "Bug Fixes",
"cut": "Cut",
"doc": "Documentation",
- # "CI": "CI",
"bump": "Bump",
- # "test": "Test",
"revert": "Revert",
"refactor": "Refactoring",
}
class SafeDumper(yaml.SafeDumper):
- """
- Make yamllint happy
- https://github.com/yaml/pyyaml/issues/234#issuecomment-765894586
+ """Make yamllint happy
+ https://github.com/yaml/pyyaml/issues/234#issuecomment-765894586.
"""
# pylint: disable=R0901,W0613,W1113
@@ -60,7 +56,7 @@ if __name__ == "__main__":
{
"title": "Breaking Changes",
"labels": breaking_labels,
- }
+ },
)
# Add new features
@@ -71,7 +67,7 @@ if __name__ == "__main__":
{
"title": "New features and enhancements",
"labels": feat_labels,
- }
+ },
)
# Add fixes
@@ -82,7 +78,7 @@ if __name__ == "__main__":
{
"title": "Fixed issues",
"labels": fixes_labels,
- }
+ },
)
# Add Documentation
@@ -93,7 +89,7 @@ if __name__ == "__main__":
{
"title": "Documentation",
"labels": doc_labels,
- }
+ },
)
# Add the catch all
@@ -101,7 +97,7 @@ if __name__ == "__main__":
{
"title": "Other Changes",
"labels": ["*"],
- }
+ },
)
with open(r"release.yml", "w", encoding="utf-8") as release_file:
yaml.dump(
@@ -109,7 +105,7 @@ if __name__ == "__main__":
"changelog": {
"exclude": {"labels": exclude_list},
"categories": categories_list,
- }
+ },
},
release_file,
Dumper=SafeDumper,
diff --git a/.github/workflows/code-testing.yml b/.github/workflows/code-testing.yml
index 4d4c0a6..5c06d45 100644
--- a/.github/workflows/code-testing.yml
+++ b/.github/workflows/code-testing.yml
@@ -23,6 +23,8 @@ jobs:
- 'anta/**'
- 'tests/*'
- 'tests/**'
+ # detect dependency changes
+ - 'pyproject.toml'
core:
- 'anta/*'
- 'anta/reporter/*'
@@ -44,7 +46,7 @@ jobs:
runs-on: ubuntu-20.04
strategy:
matrix:
- python-version: ["3.8", "3.9", "3.10", "3.11", "3.12"]
+ python-version: ["3.9", "3.10", "3.11", "3.12"]
needs: file-changes
steps:
- uses: actions/checkout@v4
@@ -64,7 +66,7 @@ jobs:
if: needs.file-changes.outputs.cli == 'true' && needs.file-changes.outputs.docs == 'false'
steps:
- name: Documentation is missing
- uses: GrantBirki/comment@v2.0.9
+ uses: GrantBirki/comment@v2.0.10
with:
body: |
Please consider that documentation is missing under `docs/` folder.
@@ -82,7 +84,7 @@ jobs:
config_file: .yamllint.yml
file_or_dir: .
lint-python:
- name: Run isort, black, flake8 and pylint
+ name: Check the code style
runs-on: ubuntu-20.04
needs: file-changes
if: needs.file-changes.outputs.code == 'true'
@@ -97,7 +99,7 @@ jobs:
- name: "Run tox linting environment"
run: tox -e lint
type-python:
- name: Run mypy
+ name: Check typing
runs-on: ubuntu-20.04
needs: file-changes
if: needs.file-changes.outputs.code == 'true'
@@ -117,7 +119,7 @@ jobs:
needs: [lint-python, type-python]
strategy:
matrix:
- python: ["3.8", "3.9", "3.10", "3.11", "3.12"]
+ python: ["3.9", "3.10", "3.11", "3.12"]
steps:
- uses: actions/checkout@v4
- name: Setup Python
diff --git a/.github/workflows/main-doc.yml b/.github/workflows/main-doc.yml
index 0d46fa9..81ac382 100644
--- a/.github/workflows/main-doc.yml
+++ b/.github/workflows/main-doc.yml
@@ -7,9 +7,9 @@ on:
- main
paths:
# Run only if any of the following paths are changed when pushing to main
- # May need to update this
- "docs/**"
- "mkdocs.yml"
+ - "anta/**"
workflow_dispatch:
jobs:
diff --git a/.github/workflows/pr-triage.yml b/.github/workflows/pr-triage.yml
index d60937d..75c2b89 100644
--- a/.github/workflows/pr-triage.yml
+++ b/.github/workflows/pr-triage.yml
@@ -22,7 +22,7 @@ jobs:
steps:
# Please look up the latest version from
# https://github.com/amannn/action-semantic-pull-request/releases
- - uses: amannn/action-semantic-pull-request@v5.4.0
+ - uses: amannn/action-semantic-pull-request@v5.5.2
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
diff --git a/.gitignore b/.gitignore
index d7a0699..a62de02 100644
--- a/.gitignore
+++ b/.gitignore
@@ -30,7 +30,6 @@ share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
-.flake8
# PyInstaller
# Usually these files are written by a python script from a template
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index d2a26a4..bdfb5ab 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -1,15 +1,17 @@
---
# See https://pre-commit.com for more information
# See https://pre-commit.com/hooks.html for more hooks
-files: ^(anta|docs|scripts|tests)/
+files: ^(anta|docs|scripts|tests|asynceapi)/
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.4.0
hooks:
- id: trailing-whitespace
+ exclude: docs/.*.svg
- id: end-of-file-fixer
- id: check-added-large-files
+ exclude: tests/data/.*$
- id: check-merge-conflict
- repo: https://github.com/Lucas-C/pre-commit-hooks
@@ -40,66 +42,48 @@ repos:
- --comment-style
- '<!--| ~| -->'
- - repo: https://github.com/pycqa/isort
- rev: 5.13.2
+ - repo: https://github.com/astral-sh/ruff-pre-commit
+ rev: v0.4.2
hooks:
- - id: isort
- name: Check for changes when running isort on all python files
-
- - repo: https://github.com/psf/black
- rev: 24.1.1
- hooks:
- - id: black
- name: Check for changes when running Black on all python files
-
- - repo: https://github.com/pycqa/flake8
- rev: 7.0.0
- hooks:
- - id: flake8
- name: Check for PEP8 error on Python files
- args:
- - --config=/dev/null
- - --max-line-length=165
+ - id: ruff
+ name: Run Ruff linter
+ args: [ --fix ]
+ - id: ruff-format
+ name: Run Ruff formatter
- repo: local # as per https://pylint.pycqa.org/en/latest/user_guide/installation/pre-commit-integration.html
hooks:
- id: pylint
entry: pylint
language: python
- name: Check for Linting error on Python files
+ name: Check code style with pylint
description: This hook runs pylint.
types: [python]
args:
- - -rn # Only display messages
- - -sn # Don't display the score
- - --rcfile=pylintrc # Link to config file
+ - -rn # Only display messages
+ - -sn # Don't display the score
+ - --rcfile=pyproject.toml # Link to config file
- # Prepare to turn on ruff
- # - repo: https://github.com/astral-sh/ruff-pre-commit
- # # Ruff version.
- # rev: v0.0.280
- # hooks:
- # - id: ruff
+ - repo: https://github.com/codespell-project/codespell
+ rev: v2.2.6
+ hooks:
+ - id: codespell
+ name: Checks for common misspellings in text files.
+ entry: codespell
+ language: python
+ types: [text]
- repo: https://github.com/pre-commit/mirrors-mypy
- rev: v1.7.1
+ rev: v1.10.0
hooks:
- id: mypy
+ name: Check typing with mypy
args:
- --config-file=pyproject.toml
additional_dependencies:
- - "aio-eapi==0.3.0"
- - "click==8.1.3"
- - "click-help-colors==0.9.1"
- - "cvprac~=1.3"
- - "netaddr==0.8.0"
- - "pydantic~=2.0"
- - "PyYAML==6.0"
- - "requests>=2.27"
- - "rich~=13.4"
- - "asyncssh==2.13.1"
- - "Jinja2==3.1.2"
+ - anta[cli]
- types-PyYAML
- - types-paramiko
- types-requests
+ - types-pyOpenSSL
+ - pytest
files: ^(anta|tests)/
diff --git a/.vscode/settings.json b/.vscode/settings.json
index ff14cc1..8428c00 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -1,14 +1,8 @@
{
- "black-formatter.importStrategy": "fromEnvironment",
+ "ruff.enable": true,
+ "python.testing.unittestEnabled": false,
+ "python.testing.pytestEnabled": true,
"pylint.importStrategy": "fromEnvironment",
- "pylint.args": [
- "--rcfile=pylintrc"
- ],
- "flake8.importStrategy": "fromEnvironment",
- "flake8.args": [
- "--config=/dev/null",
- "--max-line-length=165"
- ],
"mypy-type-checker.importStrategy": "fromEnvironment",
"mypy-type-checker.args": [
"--config-file=pyproject.toml"
@@ -17,14 +11,10 @@
"refactor": "Warning"
},
"pylint.args": [
- "--load-plugins pylint_pydantic",
+ "--load-plugins", "pylint_pydantic",
"--rcfile=pylintrc"
],
"python.testing.pytestArgs": [
"tests"
],
- "python.testing.unittestEnabled": false,
- "python.testing.pytestEnabled": true,
- "isort.importStrategy": "fromEnvironment",
- "isort.check": true,
} \ No newline at end of file
diff --git a/Dockerfile b/Dockerfile
index 2a0ef53..873bc1c 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -3,23 +3,30 @@ ARG IMG_OPTION=alpine
### BUILDER
-FROM python:${PYTHON_VER}-${IMG_OPTION} as BUILDER
+FROM python:${PYTHON_VER}-${IMG_OPTION} AS BUILDER
RUN pip install --upgrade pip
WORKDIR /local
COPY . /local
-ENV PYTHONPATH=/local
-ENV PATH=$PATH:/root/.local/bin
+RUN python -m venv /opt/venv
-RUN pip --no-cache-dir install --user .
+
+ENV PATH="/opt/venv/bin:$PATH"
+
+RUN apk add --no-cache build-base # Add build-base package
+RUN pip --no-cache-dir install "." &&\
+ pip --no-cache-dir install ".[cli]"
# ----------------------------------- #
### BASE
-FROM python:${PYTHON_VER}-${IMG_OPTION} as BASE
+FROM python:${PYTHON_VER}-${IMG_OPTION} AS BASE
+
+# Add a system user
+RUN adduser --system anta
# Opencontainer labels
# Labels version and revision will be updating
@@ -40,7 +47,12 @@ LABEL "org.opencontainers.image.title"="anta" \
"org.opencontainers.image.revision"="dev" \
"org.opencontainers.image.version"="dev"
-COPY --from=BUILDER /root/.local/ /root/.local
-ENV PATH=$PATH:/root/.local/bin
+# Copy artifacts from builder
+COPY --from=BUILDER /opt/venv /opt/venv
+
+# Define PATH and default user
+ENV PATH="/opt/venv/bin:$PATH"
+
+USER anta
-ENTRYPOINT [ "/root/.local/bin/anta" ]
+ENTRYPOINT [ "/opt/venv/bin/anta" ]
diff --git a/NOTICE b/NOTICE
new file mode 100644
index 0000000..fbbee8d
--- /dev/null
+++ b/NOTICE
@@ -0,0 +1,28 @@
+ANTA Project
+
+Copyright 2024 Arista Networks
+
+This product includes software developed at Arista Networks.
+
+------------------------------------------------------------------------
+
+This product includes software developed by contributors from the
+following projects, which are also licensed under the Apache License, Version 2.0:
+
+1. aio-eapi
+ - Copyright 2024 Jeremy Schulman
+ - URL: https://github.com/jeremyschulman/aio-eapi
+
+------------------------------------------------------------------------
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
diff --git a/anta/__init__.py b/anta/__init__.py
index 3973288..4dbc107 100644
--- a/anta/__init__.py
+++ b/anta/__init__.py
@@ -2,6 +2,7 @@
# Use of this source code is governed by the Apache License 2.0
# that can be found in the LICENSE file.
"""Arista Network Test Automation (ANTA) Framework."""
+
import importlib.metadata
import os
@@ -16,9 +17,9 @@ __credits__ = [
"Guillaume Mulocher",
"Thomas Grimonet",
]
-__copyright__ = "Copyright 2022, Arista EMEA AS"
+__copyright__ = "Copyright 2022-2024, Arista Networks, Inc."
-# Global ANTA debug mode environment variable
+# ANTA Debug Mode environment variable
__DEBUG__ = bool(os.environ.get("ANTA_DEBUG", "").lower() == "true")
diff --git a/anta/aioeapi.py b/anta/aioeapi.py
deleted file mode 100644
index 3ede8a4..0000000
--- a/anta/aioeapi.py
+++ /dev/null
@@ -1,108 +0,0 @@
-# Copyright (c) 2023-2024 Arista Networks, Inc.
-# Use of this source code is governed by the Apache License 2.0
-# that can be found in the LICENSE file.
-"""Patch for aioeapi waiting for https://github.com/jeremyschulman/aio-eapi/pull/13"""
-from __future__ import annotations
-
-from typing import Any, AnyStr
-
-import aioeapi
-
-Device = aioeapi.Device
-
-
-class EapiCommandError(RuntimeError):
- """
- Exception class for EAPI command errors
-
- Attributes
- ----------
- failed: str - the failed command
- errmsg: str - a description of the failure reason
- errors: list[str] - the command failure details
- passed: list[dict] - a list of command results of the commands that passed
- not_exec: list[str] - a list of commands that were not executed
- """
-
- # pylint: disable=too-many-arguments
- def __init__(self, failed: str, errors: list[str], errmsg: str, passed: list[str | dict[str, Any]], not_exec: list[dict[str, Any]]):
- """Initializer for the EapiCommandError exception"""
- self.failed = failed
- self.errmsg = errmsg
- self.errors = errors
- self.passed = passed
- self.not_exec = not_exec
- super().__init__()
-
- def __str__(self) -> str:
- """returns the error message associated with the exception"""
- return self.errmsg
-
-
-aioeapi.EapiCommandError = EapiCommandError
-
-
-async def jsonrpc_exec(self, jsonrpc: dict) -> list[dict | AnyStr]: # type: ignore
- """
- Execute the JSON-RPC dictionary object.
-
- Parameters
- ----------
- jsonrpc: dict
- The JSON-RPC as created by the `meth`:jsonrpc_command().
-
- Raises
- ------
- EapiCommandError
- In the event that a command resulted in an error response.
-
- Returns
- -------
- The list of command results; either dict or text depending on the
- JSON-RPC format pameter.
- """
- res = await self.post("/command-api", json=jsonrpc)
- res.raise_for_status()
- body = res.json()
-
- commands = jsonrpc["params"]["cmds"]
- ofmt = jsonrpc["params"]["format"]
-
- get_output = (lambda _r: _r["output"]) if ofmt == "text" else (lambda _r: _r)
-
- # if there are no errors then return the list of command results.
- if (err_data := body.get("error")) is None:
- return [get_output(cmd_res) for cmd_res in body["result"]]
-
- # ---------------------------------------------------------------------
- # if we are here, then there were some command errors. Raise a
- # EapiCommandError exception with args (commands that failed, passed,
- # not-executed).
- # ---------------------------------------------------------------------
-
- # -------------------------- eAPI specification ----------------------
- # On an error, no result object is present, only an error object, which
- # is guaranteed to have the following attributes: code, messages, and
- # data. Similar to the result object in the successful response, the
- # data object is a list of objects corresponding to the results of all
- # commands up to, and including, the failed command. If there was a an
- # error before any commands were executed (e.g. bad credentials), data
- # will be empty. The last object in the data array will always
- # correspond to the failed command. The command failure details are
- # always stored in the errors array.
-
- cmd_data = err_data["data"]
- len_data = len(cmd_data)
- err_at = len_data - 1
- err_msg = err_data["message"]
-
- raise EapiCommandError(
- passed=[get_output(cmd_data[cmd_i]) for cmd_i, cmd in enumerate(commands[:err_at])],
- failed=commands[err_at]["cmd"],
- errors=cmd_data[err_at]["errors"],
- errmsg=err_msg,
- not_exec=commands[err_at + 1 :], # noqa: E203
- )
-
-
-aioeapi.Device.jsonrpc_exec = jsonrpc_exec
diff --git a/anta/catalog.py b/anta/catalog.py
index 0c58a56..142640e 100644
--- a/anta/catalog.py
+++ b/anta/catalog.py
@@ -1,37 +1,41 @@
# Copyright (c) 2023-2024 Arista Networks, Inc.
# Use of this source code is governed by the Apache License 2.0
# that can be found in the LICENSE file.
-"""
-Catalog related functions
-"""
+"""Catalog related functions."""
+
from __future__ import annotations
import importlib
import logging
+import math
+from collections import defaultdict
from inspect import isclass
from pathlib import Path
-from types import ModuleType
-from typing import Any, Dict, List, Optional, Tuple, Type, Union
+from typing import TYPE_CHECKING, Any, Optional, Union
-from pydantic import BaseModel, ConfigDict, RootModel, ValidationError, ValidationInfo, field_validator, model_validator
+import yaml
+from pydantic import BaseModel, ConfigDict, RootModel, ValidationError, ValidationInfo, field_validator, model_serializer, model_validator
from pydantic.types import ImportString
+from pydantic_core import PydanticCustomError
from yaml import YAMLError, safe_load
from anta.logger import anta_log_exception
from anta.models import AntaTest
+if TYPE_CHECKING:
+ from types import ModuleType
+
logger = logging.getLogger(__name__)
# { <module_name> : [ { <test_class_name>: <input_as_dict_or_None> }, ... ] }
-RawCatalogInput = Dict[str, List[Dict[str, Optional[Dict[str, Any]]]]]
+RawCatalogInput = dict[str, list[dict[str, Optional[dict[str, Any]]]]]
# [ ( <AntaTest class>, <input_as AntaTest.Input or dict or None > ), ... ]
-ListAntaTestTuples = List[Tuple[Type[AntaTest], Optional[Union[AntaTest.Input, Dict[str, Any]]]]]
+ListAntaTestTuples = list[tuple[type[AntaTest], Optional[Union[AntaTest.Input, dict[str, Any]]]]]
class AntaTestDefinition(BaseModel):
- """
- Define a test with its associated inputs.
+ """Define a test with its associated inputs.
test: An AntaTest concrete subclass
inputs: The associated AntaTest.Input subclass instance
@@ -39,13 +43,29 @@ class AntaTestDefinition(BaseModel):
model_config = ConfigDict(frozen=True)
- test: Type[AntaTest]
+ test: type[AntaTest]
inputs: AntaTest.Input
- def __init__(self, **data: Any) -> None:
+ @model_serializer()
+ def serialize_model(self) -> dict[str, AntaTest.Input]:
+ """Serialize the AntaTestDefinition model.
+
+ The dictionary representing the model will be look like:
+ ```
+ <AntaTest subclass name>:
+ <AntaTest.Input compliant dictionary>
+ ```
+
+ Returns
+ -------
+ A dictionary representing the model.
"""
- Inject test in the context to allow to instantiate Input in the BeforeValidator
- https://docs.pydantic.dev/2.0/usage/validators/#using-validation-context-with-basemodel-initialization
+ return {self.test.__name__: self.inputs}
+
+ def __init__(self, **data: type[AntaTest] | AntaTest.Input | dict[str, Any] | None) -> None:
+ """Inject test in the context to allow to instantiate Input in the BeforeValidator.
+
+ https://docs.pydantic.dev/2.0/usage/validators/#using-validation-context-with-basemodel-initialization.
"""
self.__pydantic_validator__.validate_python(
data,
@@ -56,133 +76,189 @@ class AntaTestDefinition(BaseModel):
@field_validator("inputs", mode="before")
@classmethod
- def instantiate_inputs(cls, data: AntaTest.Input | dict[str, Any] | None, info: ValidationInfo) -> AntaTest.Input:
- """
+ def instantiate_inputs(
+ cls: type[AntaTestDefinition],
+ data: AntaTest.Input | dict[str, Any] | None,
+ info: ValidationInfo,
+ ) -> AntaTest.Input:
+ """Ensure the test inputs can be instantiated and thus are valid.
+
If the test has no inputs, allow the user to omit providing the `inputs` field.
If the test has inputs, allow the user to provide a valid dictionary of the input fields.
This model validator will instantiate an Input class from the `test` class field.
"""
if info.context is None:
- raise ValueError("Could not validate inputs as no test class could be identified")
+ msg = "Could not validate inputs as no test class could be identified"
+ raise ValueError(msg)
# Pydantic guarantees at this stage that test_class is a subclass of AntaTest because of the ordering
# of fields in the class definition - so no need to check for this
test_class = info.context["test"]
if not (isclass(test_class) and issubclass(test_class, AntaTest)):
- raise ValueError(f"Could not validate inputs as no test class {test_class} is not a subclass of AntaTest")
+ msg = f"Could not validate inputs as no test class {test_class} is not a subclass of AntaTest"
+ raise ValueError(msg)
- if data is None:
- return test_class.Input()
if isinstance(data, AntaTest.Input):
return data
- if isinstance(data, dict):
- return test_class.Input(**data)
- raise ValueError(f"Coud not instantiate inputs as type {type(data).__name__} is not valid")
+ try:
+ if data is None:
+ return test_class.Input()
+ if isinstance(data, dict):
+ return test_class.Input(**data)
+ except ValidationError as e:
+ inputs_msg = str(e).replace("\n", "\n\t")
+ err_type = "wrong_test_inputs"
+ raise PydanticCustomError(
+ err_type,
+ f"{test_class.name} test inputs are not valid: {inputs_msg}\n",
+ {"errors": e.errors()},
+ ) from e
+ msg = f"Could not instantiate inputs as type {type(data).__name__} is not valid"
+ raise ValueError(msg)
@model_validator(mode="after")
- def check_inputs(self) -> "AntaTestDefinition":
- """
+ def check_inputs(self) -> AntaTestDefinition:
+ """Check the `inputs` field typing.
+
The `inputs` class attribute needs to be an instance of the AntaTest.Input subclass defined in the class `test`.
"""
if not isinstance(self.inputs, self.test.Input):
- raise ValueError(f"Test input has type {self.inputs.__class__.__qualname__} but expected type {self.test.Input.__qualname__}")
+ msg = f"Test input has type {self.inputs.__class__.__qualname__} but expected type {self.test.Input.__qualname__}"
+ raise ValueError(msg) # noqa: TRY004 pydantic catches ValueError or AssertionError, no TypeError
return self
-class AntaCatalogFile(RootModel[Dict[ImportString[Any], List[AntaTestDefinition]]]): # pylint: disable=too-few-public-methods
- """
- This model represents an ANTA Test Catalog File.
+class AntaCatalogFile(RootModel[dict[ImportString[Any], list[AntaTestDefinition]]]): # pylint: disable=too-few-public-methods
+ """Represents an ANTA Test Catalog File.
- A valid test catalog file must have the following structure:
+ Example:
+ -------
+ A valid test catalog file must have the following structure:
+ ```
<Python module>:
- <AntaTest subclass>:
<AntaTest.Input compliant dictionary>
+ ```
+
"""
- root: Dict[ImportString[Any], List[AntaTestDefinition]]
+ root: dict[ImportString[Any], list[AntaTestDefinition]]
+
+ @staticmethod
+ def flatten_modules(data: dict[str, Any], package: str | None = None) -> dict[ModuleType, list[Any]]:
+ """Allow the user to provide a data structure with nested Python modules.
+
+ Example:
+ -------
+ ```
+ anta.tests.routing:
+ generic:
+ - <AntaTestDefinition>
+ bgp:
+ - <AntaTestDefinition>
+ ```
+ `anta.tests.routing.generic` and `anta.tests.routing.bgp` are importable Python modules.
+
+ """
+ modules: dict[ModuleType, list[Any]] = {}
+ for module_name, tests in data.items():
+ if package and not module_name.startswith("."):
+ # PLW2901 - we redefine the loop variable on purpose here.
+ module_name = f".{module_name}" # noqa: PLW2901
+ try:
+ module: ModuleType = importlib.import_module(name=module_name, package=package)
+ except Exception as e: # pylint: disable=broad-exception-caught
+ # A test module is potentially user-defined code.
+ # We need to catch everything if we want to have meaningful logs
+ module_str = f"{module_name[1:] if module_name.startswith('.') else module_name}{f' from package {package}' if package else ''}"
+ message = f"Module named {module_str} cannot be imported. Verify that the module exists and there is no Python syntax issues."
+ anta_log_exception(e, message, logger)
+ raise ValueError(message) from e
+ if isinstance(tests, dict):
+ # This is an inner Python module
+ modules.update(AntaCatalogFile.flatten_modules(data=tests, package=module.__name__))
+ elif isinstance(tests, list):
+ # This is a list of AntaTestDefinition
+ modules[module] = tests
+ else:
+ msg = f"Syntax error when parsing: {tests}\nIt must be a list of ANTA tests. Check the test catalog."
+ raise ValueError(msg) # noqa: TRY004 pydantic catches ValueError or AssertionError, no TypeError
+ return modules
+ # ANN401 - Any ok for this validator as we are validating the received data
+ # and cannot know in advance what it is.
@model_validator(mode="before")
@classmethod
- def check_tests(cls, data: Any) -> Any:
- """
- Allow the user to provide a Python data structure that only has string values.
+ def check_tests(cls: type[AntaCatalogFile], data: Any) -> Any: # noqa: ANN401
+ """Allow the user to provide a Python data structure that only has string values.
+
This validator will try to flatten and import Python modules, check if the tests classes
are actually defined in their respective Python module and instantiate Input instances
with provided value to validate test inputs.
"""
-
- def flatten_modules(data: dict[str, Any], package: str | None = None) -> dict[ModuleType, list[Any]]:
- """
- Allow the user to provide a data structure with nested Python modules.
-
- Example:
- ```
- anta.tests.routing:
- generic:
- - <AntaTestDefinition>
- bgp:
- - <AntaTestDefinition>
- ```
- `anta.tests.routing.generic` and `anta.tests.routing.bgp` are importable Python modules.
- """
- modules: dict[ModuleType, list[Any]] = {}
- for module_name, tests in data.items():
- if package and not module_name.startswith("."):
- module_name = f".{module_name}"
- try:
- module: ModuleType = importlib.import_module(name=module_name, package=package)
- except Exception as e: # pylint: disable=broad-exception-caught
- # A test module is potentially user-defined code.
- # We need to catch everything if we want to have meaningful logs
- module_str = f"{module_name[1:] if module_name.startswith('.') else module_name}{f' from package {package}' if package else ''}"
- message = f"Module named {module_str} cannot be imported. Verify that the module exists and there is no Python syntax issues."
- anta_log_exception(e, message, logger)
- raise ValueError(message) from e
- if isinstance(tests, dict):
- # This is an inner Python module
- modules.update(flatten_modules(data=tests, package=module.__name__))
- else:
- if not isinstance(tests, list):
- raise ValueError(f"Syntax error when parsing: {tests}\nIt must be a list of ANTA tests. Check the test catalog.")
- # This is a list of AntaTestDefinition
- modules[module] = tests
- return modules
-
if isinstance(data, dict):
- typed_data: dict[ModuleType, list[Any]] = flatten_modules(data)
+ if not data:
+ return data
+ typed_data: dict[ModuleType, list[Any]] = AntaCatalogFile.flatten_modules(data)
for module, tests in typed_data.items():
test_definitions: list[AntaTestDefinition] = []
for test_definition in tests:
+ if isinstance(test_definition, AntaTestDefinition):
+ test_definitions.append(test_definition)
+ continue
if not isinstance(test_definition, dict):
- raise ValueError(f"Syntax error when parsing: {test_definition}\nIt must be a dictionary. Check the test catalog.")
+ msg = f"Syntax error when parsing: {test_definition}\nIt must be a dictionary. Check the test catalog."
+ raise ValueError(msg) # noqa: TRY004 pydantic catches ValueError or AssertionError, no TypeError
if len(test_definition) != 1:
- raise ValueError(
- f"Syntax error when parsing: {test_definition}\nIt must be a dictionary with a single entry. Check the indentation in the test catalog."
+ msg = (
+ f"Syntax error when parsing: {test_definition}\n"
+ "It must be a dictionary with a single entry. Check the indentation in the test catalog."
)
+ raise ValueError(msg)
for test_name, test_inputs in test_definition.copy().items():
test: type[AntaTest] | None = getattr(module, test_name, None)
if test is None:
- raise ValueError(
- f"{test_name} is not defined in Python module {module.__name__}{f' (from {module.__file__})' if module.__file__ is not None else ''}"
+ msg = (
+ f"{test_name} is not defined in Python module {module.__name__}"
+ f"{f' (from {module.__file__})' if module.__file__ is not None else ''}"
)
+ raise ValueError(msg)
test_definitions.append(AntaTestDefinition(test=test, inputs=test_inputs))
typed_data[module] = test_definitions
- return typed_data
+ return typed_data
+ return data
+
+ def yaml(self) -> str:
+ """Return a YAML representation string of this model.
+
+ Returns
+ -------
+ The YAML representation string of this model.
+ """
+ # TODO: Pydantic and YAML serialization/deserialization is not supported natively.
+ # This could be improved.
+ # https://github.com/pydantic/pydantic/issues/1043
+ # Explore if this worth using this: https://github.com/NowanIlfideme/pydantic-yaml
+ return yaml.safe_dump(yaml.safe_load(self.model_dump_json(serialize_as_any=True, exclude_unset=True)), indent=2, width=math.inf)
class AntaCatalog:
- """
- Class representing an ANTA Catalog.
+ """Class representing an ANTA Catalog.
- It can be instantiated using its contructor or one of the static methods: `parse()`, `from_list()` or `from_dict()`
+ It can be instantiated using its constructor or one of the static methods: `parse()`, `from_list()` or `from_dict()`
"""
- def __init__(self, tests: list[AntaTestDefinition] | None = None, filename: str | Path | None = None) -> None:
- """
- Constructor of AntaCatalog.
+ def __init__(
+ self,
+ tests: list[AntaTestDefinition] | None = None,
+ filename: str | Path | None = None,
+ ) -> None:
+ """Instantiate an AntaCatalog instance.
Args:
+ ----
tests: A list of AntaTestDefinition instances.
filename: The path from which the catalog is loaded.
+
"""
self._tests: list[AntaTestDefinition] = []
if tests is not None:
@@ -194,36 +270,46 @@ class AntaCatalog:
else:
self._filename = Path(filename)
+ # Default indexes for faster access
+ self.tag_to_tests: defaultdict[str | None, set[AntaTestDefinition]] = defaultdict(set)
+ self.tests_without_tags: set[AntaTestDefinition] = set()
+ self.indexes_built: bool = False
+ self.final_tests_count: int = 0
+
@property
def filename(self) -> Path | None:
- """Path of the file used to create this AntaCatalog instance"""
+ """Path of the file used to create this AntaCatalog instance."""
return self._filename
@property
def tests(self) -> list[AntaTestDefinition]:
- """List of AntaTestDefinition in this catalog"""
+ """List of AntaTestDefinition in this catalog."""
return self._tests
@tests.setter
def tests(self, value: list[AntaTestDefinition]) -> None:
if not isinstance(value, list):
- raise ValueError("The catalog must contain a list of tests")
+ msg = "The catalog must contain a list of tests"
+ raise TypeError(msg)
for t in value:
if not isinstance(t, AntaTestDefinition):
- raise ValueError("A test in the catalog must be an AntaTestDefinition instance")
+ msg = "A test in the catalog must be an AntaTestDefinition instance"
+ raise TypeError(msg)
self._tests = value
@staticmethod
def parse(filename: str | Path) -> AntaCatalog:
- """
- Create an AntaCatalog instance from a test catalog file.
+ """Create an AntaCatalog instance from a test catalog file.
Args:
+ ----
filename: Path to test catalog YAML file
+
"""
try:
- with open(file=filename, mode="r", encoding="UTF-8") as file:
- data = safe_load(file)
+ file: Path = filename if isinstance(filename, Path) else Path(filename)
+ with file.open(encoding="UTF-8") as f:
+ data = safe_load(f)
except (TypeError, YAMLError, OSError) as e:
message = f"Unable to parse ANTA Test Catalog file '{filename}'"
anta_log_exception(e, message, logger)
@@ -233,15 +319,17 @@ class AntaCatalog:
@staticmethod
def from_dict(data: RawCatalogInput, filename: str | Path | None = None) -> AntaCatalog:
- """
- Create an AntaCatalog instance from a dictionary data structure.
+ """Create an AntaCatalog instance from a dictionary data structure.
+
See RawCatalogInput type alias for details.
It is the data structure returned by `yaml.load()` function of a valid
YAML Test Catalog file.
Args:
+ ----
data: Python dictionary used to instantiate the AntaCatalog instance
filename: value to be set as AntaCatalog instance attribute
+
"""
tests: list[AntaTestDefinition] = []
if data is None:
@@ -249,12 +337,17 @@ class AntaCatalog:
return AntaCatalog(filename=filename)
if not isinstance(data, dict):
- raise ValueError(f"Wrong input type for catalog data{f' (from {filename})' if filename is not None else ''}, must be a dict, got {type(data).__name__}")
+ msg = f"Wrong input type for catalog data{f' (from {filename})' if filename is not None else ''}, must be a dict, got {type(data).__name__}"
+ raise TypeError(msg)
try:
- catalog_data = AntaCatalogFile(**data) # type: ignore[arg-type]
+ catalog_data = AntaCatalogFile(data) # type: ignore[arg-type]
except ValidationError as e:
- anta_log_exception(e, f"Test catalog is invalid!{f' (from {filename})' if filename is not None else ''}", logger)
+ anta_log_exception(
+ e,
+ f"Test catalog is invalid!{f' (from {filename})' if filename is not None else ''}",
+ logger,
+ )
raise
for t in catalog_data.root.values():
tests.extend(t)
@@ -262,12 +355,14 @@ class AntaCatalog:
@staticmethod
def from_list(data: ListAntaTestTuples) -> AntaCatalog:
- """
- Create an AntaCatalog instance from a list data structure.
+ """Create an AntaCatalog instance from a list data structure.
+
See ListAntaTestTuples type alias for details.
Args:
+ ----
data: Python list used to instantiate the AntaCatalog instance
+
"""
tests: list[AntaTestDefinition] = []
try:
@@ -277,15 +372,85 @@ class AntaCatalog:
raise
return AntaCatalog(tests)
- def get_tests_by_tags(self, tags: list[str], strict: bool = False) -> list[AntaTestDefinition]:
+ def merge(self, catalog: AntaCatalog) -> AntaCatalog:
+ """Merge two AntaCatalog instances.
+
+ Args:
+ ----
+ catalog: AntaCatalog instance to merge to this instance.
+
+ Returns
+ -------
+ A new AntaCatalog instance containing the tests of the two instances.
"""
- Return all the tests that have matching tags in their input filters.
- If strict=True, returns only tests that match all the tags provided as input.
- If strict=False, return all the tests that match at least one tag provided as input.
+ return AntaCatalog(tests=self.tests + catalog.tests)
+
+ def dump(self) -> AntaCatalogFile:
+ """Return an AntaCatalogFile instance from this AntaCatalog instance.
+
+ Returns
+ -------
+ An AntaCatalogFile instance containing tests of this AntaCatalog instance.
+ """
+ root: dict[ImportString[Any], list[AntaTestDefinition]] = {}
+ for test in self.tests:
+ # Cannot use AntaTest.module property as the class is not instantiated
+ root.setdefault(test.test.__module__, []).append(test)
+ return AntaCatalogFile(root=root)
+
+ def build_indexes(self, filtered_tests: set[str] | None = None) -> None:
+ """Indexes tests by their tags for quick access during filtering operations.
+
+ If a `filtered_tests` set is provided, only the tests in this set will be indexed.
+
+ This method populates two attributes:
+ - tag_to_tests: A dictionary mapping each tag to a set of tests that contain it.
+ - tests_without_tags: A set of tests that do not have any tags.
+
+ Once the indexes are built, the `indexes_built` attribute is set to True.
"""
- result: list[AntaTestDefinition] = []
for test in self.tests:
- if test.inputs.filters and (f := test.inputs.filters.tags):
- if (strict and all(t in tags for t in f)) or (not strict and any(t in tags for t in f)):
- result.append(test)
- return result
+ # Skip tests that are not in the specified filtered_tests set
+ if filtered_tests and test.test.name not in filtered_tests:
+ continue
+
+ # Indexing by tag
+ if test.inputs.filters and (test_tags := test.inputs.filters.tags):
+ for tag in test_tags:
+ self.tag_to_tests[tag].add(test)
+ else:
+ self.tests_without_tags.add(test)
+
+ self.tag_to_tests[None] = self.tests_without_tags
+ self.indexes_built = True
+
+ def get_tests_by_tags(self, tags: set[str], *, strict: bool = False) -> set[AntaTestDefinition]:
+ """Return all tests that match a given set of tags, according to the specified strictness.
+
+ Args:
+ ----
+ tags: The tags to filter tests by. If empty, return all tests without tags.
+ strict: If True, returns only tests that contain all specified tags (intersection).
+ If False, returns tests that contain any of the specified tags (union).
+
+ Returns
+ -------
+ set[AntaTestDefinition]: A set of tests that match the given tags.
+
+ Raises
+ ------
+ ValueError: If the indexes have not been built prior to method call.
+ """
+ if not self.indexes_built:
+ msg = "Indexes have not been built yet. Call build_indexes() first."
+ raise ValueError(msg)
+ if not tags:
+ return self.tag_to_tests[None]
+
+ filtered_sets = [self.tag_to_tests[tag] for tag in tags if tag in self.tag_to_tests]
+ if not filtered_sets:
+ return set()
+
+ if strict:
+ return set.intersection(*filtered_sets)
+ return set.union(*filtered_sets)
diff --git a/anta/cli/__init__.py b/anta/cli/__init__.py
index 3eecad0..b542a6d 100644
--- a/anta/cli/__init__.py
+++ b/anta/cli/__init__.py
@@ -1,72 +1,41 @@
-#!/usr/bin/env python
# Copyright (c) 2023-2024 Arista Networks, Inc.
# Use of this source code is governed by the Apache License 2.0
# that can be found in the LICENSE file.
-"""
-ANTA CLI
-"""
+"""ANTA CLI."""
+
from __future__ import annotations
-import logging
-import pathlib
import sys
+from typing import Callable
-import click
-
-from anta import GITHUB_SUGGESTION, __version__
-from anta.cli.check import check as check_command
-from anta.cli.debug import debug as debug_command
-from anta.cli.exec import exec as exec_command
-from anta.cli.get import get as get_command
-from anta.cli.nrfu import nrfu as nrfu_command
-from anta.cli.utils import AliasedGroup, ExitCode
-from anta.logger import Log, LogLevel, anta_log_exception, setup_logging
+from anta import __DEBUG__
-logger = logging.getLogger(__name__)
+# Note: need to separate this file from _main to be able to fail on the import.
+try:
+ from ._main import anta, cli
+except ImportError as exc:
-@click.group(cls=AliasedGroup)
-@click.pass_context
-@click.version_option(__version__)
-@click.option(
- "--log-file",
- help="Send the logs to a file. If logging level is DEBUG, only INFO or higher will be sent to stdout.",
- show_envvar=True,
- type=click.Path(file_okay=True, dir_okay=False, writable=True, path_type=pathlib.Path),
-)
-@click.option(
- "--log-level",
- "-l",
- help="ANTA logging level",
- default=logging.getLevelName(logging.INFO),
- show_envvar=True,
- show_default=True,
- type=click.Choice(
- [Log.CRITICAL, Log.ERROR, Log.WARNING, Log.INFO, Log.DEBUG],
- case_sensitive=False,
- ),
-)
-def anta(ctx: click.Context, log_level: LogLevel, log_file: pathlib.Path) -> None:
- """Arista Network Test Automation (ANTA) CLI"""
- ctx.ensure_object(dict)
- setup_logging(log_level, log_file)
+ def build_cli(exception: Exception) -> Callable[[], None]:
+ """Build CLI function using the caught exception."""
+ def wrap() -> None:
+ """Error message if any CLI dependency is missing."""
+ print(
+ "The ANTA command line client could not run because the required "
+ "dependencies were not installed.\nMake sure you've installed "
+ "everything with: pip install 'anta[cli]'"
+ )
+ if __DEBUG__:
+ print(f"The caught exception was: {exception}")
-anta.add_command(nrfu_command)
-anta.add_command(check_command)
-anta.add_command(exec_command)
-anta.add_command(get_command)
-anta.add_command(debug_command)
+ sys.exit(1)
+ return wrap
-def cli() -> None:
- """Entrypoint for pyproject.toml"""
- try:
- anta(obj={}, auto_envvar_prefix="ANTA")
- except Exception as e: # pylint: disable=broad-exception-caught
- anta_log_exception(e, f"Uncaught Exception when running ANTA CLI\n{GITHUB_SUGGESTION}", logger)
- sys.exit(ExitCode.INTERNAL_ERROR)
+ cli = build_cli(exc)
+__all__ = ["cli", "anta"]
if __name__ == "__main__":
cli()
diff --git a/anta/cli/_main.py b/anta/cli/_main.py
new file mode 100644
index 0000000..1211a42
--- /dev/null
+++ b/anta/cli/_main.py
@@ -0,0 +1,70 @@
+# Copyright (c) 2023-2024 Arista Networks, Inc.
+# Use of this source code is governed by the Apache License 2.0
+# that can be found in the LICENSE file.
+"""ANTA CLI."""
+
+from __future__ import annotations
+
+import logging
+import pathlib
+import sys
+
+import click
+
+from anta import GITHUB_SUGGESTION, __version__
+from anta.cli.check import check as check_command
+from anta.cli.debug import debug as debug_command
+from anta.cli.exec import _exec as exec_command
+from anta.cli.get import get as get_command
+from anta.cli.nrfu import nrfu as nrfu_command
+from anta.cli.utils import AliasedGroup, ExitCode
+from anta.logger import Log, LogLevel, anta_log_exception, setup_logging
+
+logger = logging.getLogger(__name__)
+
+
+@click.group(cls=AliasedGroup)
+@click.pass_context
+@click.version_option(__version__)
+@click.option(
+ "--log-file",
+ help="Send the logs to a file. If logging level is DEBUG, only INFO or higher will be sent to stdout.",
+ show_envvar=True,
+ type=click.Path(file_okay=True, dir_okay=False, writable=True, path_type=pathlib.Path),
+)
+@click.option(
+ "--log-level",
+ "-l",
+ help="ANTA logging level",
+ default=logging.getLevelName(logging.INFO),
+ show_envvar=True,
+ show_default=True,
+ type=click.Choice(
+ [Log.CRITICAL, Log.ERROR, Log.WARNING, Log.INFO, Log.DEBUG],
+ case_sensitive=False,
+ ),
+)
+def anta(ctx: click.Context, log_level: LogLevel, log_file: pathlib.Path) -> None:
+ """Arista Network Test Automation (ANTA) CLI."""
+ ctx.ensure_object(dict)
+ setup_logging(log_level, log_file)
+
+
+anta.add_command(nrfu_command)
+anta.add_command(check_command)
+anta.add_command(exec_command)
+anta.add_command(get_command)
+anta.add_command(debug_command)
+
+
+def cli() -> None:
+ """Entrypoint for pyproject.toml."""
+ try:
+ anta(obj={}, auto_envvar_prefix="ANTA")
+ except Exception as exc: # pylint: disable=broad-exception-caught
+ anta_log_exception(
+ exc,
+ f"Uncaught Exception when running ANTA CLI\n{GITHUB_SUGGESTION}",
+ logger,
+ )
+ sys.exit(ExitCode.INTERNAL_ERROR)
diff --git a/anta/cli/check/__init__.py b/anta/cli/check/__init__.py
index aec80aa..bbc5a7e 100644
--- a/anta/cli/check/__init__.py
+++ b/anta/cli/check/__init__.py
@@ -1,9 +1,8 @@
# Copyright (c) 2023-2024 Arista Networks, Inc.
# Use of this source code is governed by the Apache License 2.0
# that can be found in the LICENSE file.
-"""
-Click commands to validate configuration files
-"""
+"""Click commands to validate configuration files."""
+
import click
from anta.cli.check import commands
@@ -11,7 +10,7 @@ from anta.cli.check import commands
@click.group
def check() -> None:
- """Commands to validate configuration files"""
+ """Commands to validate configuration files."""
check.add_command(commands.catalog)
diff --git a/anta/cli/check/commands.py b/anta/cli/check/commands.py
index 8208d64..23895d7 100644
--- a/anta/cli/check/commands.py
+++ b/anta/cli/check/commands.py
@@ -2,28 +2,28 @@
# Use of this source code is governed by the Apache License 2.0
# that can be found in the LICENSE file.
# pylint: disable = redefined-outer-name
-"""
-Click commands to validate configuration files
-"""
+"""Click commands to validate configuration files."""
+
from __future__ import annotations
import logging
+from typing import TYPE_CHECKING
import click
from rich.pretty import pretty_repr
-from anta.catalog import AntaCatalog
from anta.cli.console import console
from anta.cli.utils import catalog_options
+if TYPE_CHECKING:
+ from anta.catalog import AntaCatalog
+
logger = logging.getLogger(__name__)
@click.command
@catalog_options
def catalog(catalog: AntaCatalog) -> None:
- """
- Check that the catalog is valid
- """
+ """Check that the catalog is valid."""
console.print(f"[bold][green]Catalog is valid: {catalog.filename}")
console.print(pretty_repr(catalog.tests))
diff --git a/anta/cli/console.py b/anta/cli/console.py
index cf4e6fb..9c57d6d 100644
--- a/anta/cli/console.py
+++ b/anta/cli/console.py
@@ -1,9 +1,9 @@
# Copyright (c) 2023-2024 Arista Networks, Inc.
# Use of this source code is governed by the Apache License 2.0
# that can be found in the LICENSE file.
-"""
-ANTA Top-level Console
-https://rich.readthedocs.io/en/stable/console.html#console-api
+"""ANTA Top-level Console.
+
+https://rich.readthedocs.io/en/stable/console.html#console-api.
"""
from rich.console import Console
diff --git a/anta/cli/debug/__init__.py b/anta/cli/debug/__init__.py
index 6c4dbfb..18d577f 100644
--- a/anta/cli/debug/__init__.py
+++ b/anta/cli/debug/__init__.py
@@ -1,9 +1,8 @@
# Copyright (c) 2023-2024 Arista Networks, Inc.
# Use of this source code is governed by the Apache License 2.0
# that can be found in the LICENSE file.
-"""
-Click commands to execute EOS commands on remote devices
-"""
+"""Click commands to execute EOS commands on remote devices."""
+
import click
from anta.cli.debug import commands
@@ -11,7 +10,7 @@ from anta.cli.debug import commands
@click.group
def debug() -> None:
- """Commands to execute EOS commands on remote devices"""
+ """Commands to execute EOS commands on remote devices."""
debug.add_command(commands.run_cmd)
diff --git a/anta/cli/debug/commands.py b/anta/cli/debug/commands.py
index 7fffc2e..14f168b 100644
--- a/anta/cli/debug/commands.py
+++ b/anta/cli/debug/commands.py
@@ -2,23 +2,24 @@
# Use of this source code is governed by the Apache License 2.0
# that can be found in the LICENSE file.
# pylint: disable = redefined-outer-name
-"""
-Click commands to execute EOS commands on remote devices
-"""
+"""Click commands to execute EOS commands on remote devices."""
+
from __future__ import annotations
import asyncio
import logging
-from typing import Literal
+from typing import TYPE_CHECKING, Literal
import click
from anta.cli.console import console
from anta.cli.debug.utils import debug_options
from anta.cli.utils import ExitCode
-from anta.device import AntaDevice
from anta.models import AntaCommand, AntaTemplate
+if TYPE_CHECKING:
+ from anta.device import AntaDevice
+
logger = logging.getLogger(__name__)
@@ -26,8 +27,16 @@ logger = logging.getLogger(__name__)
@debug_options
@click.pass_context
@click.option("--command", "-c", type=str, required=True, help="Command to run")
-def run_cmd(ctx: click.Context, device: AntaDevice, command: str, ofmt: Literal["json", "text"], version: Literal["1", "latest"], revision: int) -> None:
- """Run arbitrary command to an ANTA device"""
+def run_cmd(
+ ctx: click.Context,
+ device: AntaDevice,
+ command: str,
+ ofmt: Literal["json", "text"],
+ version: Literal["1", "latest"],
+ revision: int,
+) -> None:
+ # pylint: disable=too-many-arguments
+ """Run arbitrary command to an ANTA device."""
console.print(f"Run command [green]{command}[/green] on [red]{device.name}[/red]")
# I do not assume the following line, but click make me do it
v: Literal[1, "latest"] = version if version == "latest" else 1
@@ -45,18 +54,32 @@ def run_cmd(ctx: click.Context, device: AntaDevice, command: str, ofmt: Literal[
@click.command
@debug_options
@click.pass_context
-@click.option("--template", "-t", type=str, required=True, help="Command template to run. E.g. 'show vlan {vlan_id}'")
+@click.option(
+ "--template",
+ "-t",
+ type=str,
+ required=True,
+ help="Command template to run. E.g. 'show vlan {vlan_id}'",
+)
@click.argument("params", required=True, nargs=-1)
def run_template(
- ctx: click.Context, device: AntaDevice, template: str, params: list[str], ofmt: Literal["json", "text"], version: Literal["1", "latest"], revision: int
+ ctx: click.Context,
+ device: AntaDevice,
+ template: str,
+ params: list[str],
+ ofmt: Literal["json", "text"],
+ version: Literal["1", "latest"],
+ revision: int,
) -> None:
# pylint: disable=too-many-arguments
"""Run arbitrary templated command to an ANTA device.
Takes a list of arguments (keys followed by a value) to build a dictionary used as template parameters.
- Example:
+ Example:
+ -------
anta debug run-template -d leaf1a -t 'show vlan {vlan_id}' vlan_id 1
+
"""
template_params = dict(zip(params[::2], params[1::2]))
@@ -64,7 +87,7 @@ def run_template(
# I do not assume the following line, but click make me do it
v: Literal[1, "latest"] = version if version == "latest" else 1
t = AntaTemplate(template=template, ofmt=ofmt, version=v, revision=revision)
- c = t.render(**template_params) # type: ignore
+ c = t.render(**template_params)
asyncio.run(device.collect(c))
if not c.collected:
console.print(f"[bold red] Command '{c.command}' failed to execute!")
diff --git a/anta/cli/debug/utils.py b/anta/cli/debug/utils.py
index cc2193d..26fef45 100644
--- a/anta/cli/debug/utils.py
+++ b/anta/cli/debug/utils.py
@@ -1,40 +1,58 @@
# Copyright (c) 2023-2024 Arista Networks, Inc.
# Use of this source code is governed by the Apache License 2.0
# that can be found in the LICENSE file.
-"""
-Utils functions to use with anta.cli.debug module.
-"""
+"""Utils functions to use with anta.cli.debug module."""
+
from __future__ import annotations
import functools
import logging
-from typing import Any
+from typing import TYPE_CHECKING, Any, Callable
import click
from anta.cli.utils import ExitCode, inventory_options
-from anta.inventory import AntaInventory
+
+if TYPE_CHECKING:
+ from anta.inventory import AntaInventory
logger = logging.getLogger(__name__)
-def debug_options(f: Any) -> Any:
- """Click common options required to execute a command on a specific device"""
+def debug_options(f: Callable[..., Any]) -> Callable[..., Any]:
+ """Click common options required to execute a command on a specific device."""
@inventory_options
- @click.option("--ofmt", type=click.Choice(["json", "text"]), default="json", help="EOS eAPI format to use. can be text or json")
- @click.option("--version", "-v", type=click.Choice(["1", "latest"]), default="latest", help="EOS eAPI version")
+ @click.option(
+ "--ofmt",
+ type=click.Choice(["json", "text"]),
+ default="json",
+ help="EOS eAPI format to use. can be text or json",
+ )
+ @click.option(
+ "--version",
+ "-v",
+ type=click.Choice(["1", "latest"]),
+ default="latest",
+ help="EOS eAPI version",
+ )
@click.option("--revision", "-r", type=int, help="eAPI command revision", required=False)
@click.option("--device", "-d", type=str, required=True, help="Device from inventory to use")
@click.pass_context
@functools.wraps(f)
- def wrapper(ctx: click.Context, *args: tuple[Any], inventory: AntaInventory, tags: list[str] | None, device: str, **kwargs: dict[str, Any]) -> Any:
+ def wrapper(
+ ctx: click.Context,
+ *args: tuple[Any],
+ inventory: AntaInventory,
+ tags: set[str] | None,
+ device: str,
+ **kwargs: Any,
+ ) -> Any:
+ # TODO: @gmuloc - tags come from context https://github.com/arista-netdevops-community/anta/issues/584
# pylint: disable=unused-argument
- try:
- d = inventory[device]
- except KeyError as e:
- message = f"Device {device} does not exist in Inventory"
- logger.error(e, message)
+ # ruff: noqa: ARG001
+ if (d := inventory.get(device)) is None:
+ logger.error("Device '%s' does not exist in Inventory", device)
ctx.exit(ExitCode.USAGE_ERROR)
return f(*args, device=d, **kwargs)
diff --git a/anta/cli/exec/__init__.py b/anta/cli/exec/__init__.py
index 6be3934..7f9b4c2 100644
--- a/anta/cli/exec/__init__.py
+++ b/anta/cli/exec/__init__.py
@@ -1,19 +1,18 @@
# Copyright (c) 2023-2024 Arista Networks, Inc.
# Use of this source code is governed by the Apache License 2.0
# that can be found in the LICENSE file.
-"""
-Click commands to execute various scripts on EOS devices
-"""
+"""Click commands to execute various scripts on EOS devices."""
+
import click
from anta.cli.exec import commands
-@click.group
-def exec() -> None: # pylint: disable=redefined-builtin
- """Commands to execute various scripts on EOS devices"""
+@click.group("exec")
+def _exec() -> None: # pylint: disable=redefined-builtin
+ """Commands to execute various scripts on EOS devices."""
-exec.add_command(commands.clear_counters)
-exec.add_command(commands.snapshot)
-exec.add_command(commands.collect_tech_support)
+_exec.add_command(commands.clear_counters)
+_exec.add_command(commands.snapshot)
+_exec.add_command(commands.collect_tech_support)
diff --git a/anta/cli/exec/commands.py b/anta/cli/exec/commands.py
index 8b80d19..531614a 100644
--- a/anta/cli/exec/commands.py
+++ b/anta/cli/exec/commands.py
@@ -1,32 +1,35 @@
# Copyright (c) 2023-2024 Arista Networks, Inc.
# Use of this source code is governed by the Apache License 2.0
# that can be found in the LICENSE file.
-"""
-Click commands to execute various scripts on EOS devices
-"""
+"""Click commands to execute various scripts on EOS devices."""
+
from __future__ import annotations
import asyncio
import logging
import sys
-from datetime import datetime
+from datetime import datetime, timezone
from pathlib import Path
+from typing import TYPE_CHECKING
import click
from yaml import safe_load
-from anta.cli.exec.utils import clear_counters_utils, collect_commands, collect_scheduled_show_tech
+from anta.cli.console import console
+from anta.cli.exec import utils
from anta.cli.utils import inventory_options
-from anta.inventory import AntaInventory
+
+if TYPE_CHECKING:
+ from anta.inventory import AntaInventory
logger = logging.getLogger(__name__)
@click.command
@inventory_options
-def clear_counters(inventory: AntaInventory, tags: list[str] | None) -> None:
- """Clear counter statistics on EOS devices"""
- asyncio.run(clear_counters_utils(inventory, tags=tags))
+def clear_counters(inventory: AntaInventory, tags: set[str] | None) -> None:
+ """Clear counter statistics on EOS devices."""
+ asyncio.run(utils.clear_counters(inventory, tags=tags))
@click.command()
@@ -45,27 +48,40 @@ def clear_counters(inventory: AntaInventory, tags: list[str] | None) -> None:
show_envvar=True,
type=click.Path(file_okay=False, dir_okay=True, exists=False, writable=True, path_type=Path),
help="Directory to save commands output.",
- default=f"anta_snapshot_{datetime.now().strftime('%Y-%m-%d_%H_%M_%S')}",
+ default=f"anta_snapshot_{datetime.now(tz=timezone.utc).astimezone().strftime('%Y-%m-%d_%H_%M_%S')}",
show_default=True,
)
-def snapshot(inventory: AntaInventory, tags: list[str] | None, commands_list: Path, output: Path) -> None:
- """Collect commands output from devices in inventory"""
- print(f"Collecting data for {commands_list}")
- print(f"Output directory is {output}")
+def snapshot(inventory: AntaInventory, tags: set[str] | None, commands_list: Path, output: Path) -> None:
+ """Collect commands output from devices in inventory."""
+ console.print(f"Collecting data for {commands_list}")
+ console.print(f"Output directory is {output}")
try:
- with open(commands_list, "r", encoding="UTF-8") as file:
+ with commands_list.open(encoding="UTF-8") as file:
file_content = file.read()
eos_commands = safe_load(file_content)
except FileNotFoundError:
- logger.error(f"Error reading {commands_list}")
+ logger.error("Error reading %s", commands_list)
sys.exit(1)
- asyncio.run(collect_commands(inventory, eos_commands, output, tags=tags))
+ asyncio.run(utils.collect_commands(inventory, eos_commands, output, tags=tags))
@click.command()
@inventory_options
-@click.option("--output", "-o", default="./tech-support", show_default=True, help="Path for test catalog", type=click.Path(path_type=Path), required=False)
-@click.option("--latest", help="Number of scheduled show-tech to retrieve", type=int, required=False)
+@click.option(
+ "--output",
+ "-o",
+ default="./tech-support",
+ show_default=True,
+ help="Path for test catalog",
+ type=click.Path(path_type=Path),
+ required=False,
+)
+@click.option(
+ "--latest",
+ help="Number of scheduled show-tech to retrieve",
+ type=int,
+ required=False,
+)
@click.option(
"--configure",
help="Ensure devices have 'aaa authorization exec default local' configured (required for SCP on EOS). THIS WILL CHANGE THE CONFIGURATION OF YOUR NETWORK.",
@@ -73,6 +89,13 @@ def snapshot(inventory: AntaInventory, tags: list[str] | None, commands_list: Pa
is_flag=True,
show_default=True,
)
-def collect_tech_support(inventory: AntaInventory, tags: list[str] | None, output: Path, latest: int | None, configure: bool) -> None:
- """Collect scheduled tech-support from EOS devices"""
- asyncio.run(collect_scheduled_show_tech(inventory, output, configure, tags=tags, latest=latest))
+def collect_tech_support(
+ inventory: AntaInventory,
+ tags: set[str] | None,
+ output: Path,
+ latest: int | None,
+ *,
+ configure: bool,
+) -> None:
+ """Collect scheduled tech-support from EOS devices."""
+ asyncio.run(utils.collect_show_tech(inventory, output, configure=configure, tags=tags, latest=latest))
diff --git a/anta/cli/exec/utils.py b/anta/cli/exec/utils.py
index 681db17..a5f7da2 100644
--- a/anta/cli/exec/utils.py
+++ b/anta/cli/exec/utils.py
@@ -2,9 +2,8 @@
# Use of this source code is governed by the Apache License 2.0
# that can be found in the LICENSE file.
-"""
-Exec CLI helpers
-"""
+"""Exec CLI helpers."""
+
from __future__ import annotations
import asyncio
@@ -13,24 +12,26 @@ import json
import logging
import re
from pathlib import Path
-from typing import Literal
+from typing import TYPE_CHECKING, Literal
-from aioeapi import EapiCommandError
+from click.exceptions import UsageError
from httpx import ConnectError, HTTPError
+from anta.custom_types import REGEXP_PATH_MARKERS
from anta.device import AntaDevice, AsyncEOSDevice
-from anta.inventory import AntaInventory
from anta.models import AntaCommand
+from asynceapi import EapiCommandError
+
+if TYPE_CHECKING:
+ from anta.inventory import AntaInventory
EOS_SCHEDULED_TECH_SUPPORT = "/mnt/flash/schedule/tech-support"
INVALID_CHAR = "`~!@#$/"
logger = logging.getLogger(__name__)
-async def clear_counters_utils(anta_inventory: AntaInventory, tags: list[str] | None = None) -> None:
- """
- Clear counters
- """
+async def clear_counters(anta_inventory: AntaInventory, tags: set[str] | None = None) -> None:
+ """Clear counters."""
async def clear(dev: AntaDevice) -> None:
commands = [AntaCommand(command="clear counters")]
@@ -39,12 +40,12 @@ async def clear_counters_utils(anta_inventory: AntaInventory, tags: list[str] |
await dev.collect_commands(commands=commands)
for command in commands:
if not command.collected:
- logger.error(f"Could not clear counters on device {dev.name}: {command.errors}")
- logger.info(f"Cleared counters on {dev.name} ({dev.hw_model})")
+ logger.error("Could not clear counters on device %s: %s", dev.name, command.errors)
+ logger.info("Cleared counters on %s (%s)", dev.name, dev.hw_model)
logger.info("Connecting to devices...")
await anta_inventory.connect_inventory()
- devices = anta_inventory.get_inventory(established_only=True, tags=tags).values()
+ devices = anta_inventory.get_inventory(established_only=True, tags=tags).devices
logger.info("Clearing counters on remote devices...")
await asyncio.gather(*(clear(device) for device in devices))
@@ -53,20 +54,18 @@ async def collect_commands(
inv: AntaInventory,
commands: dict[str, str],
root_dir: Path,
- tags: list[str] | None = None,
+ tags: set[str] | None = None,
) -> None:
- """
- Collect EOS commands
- """
+ """Collect EOS commands."""
async def collect(dev: AntaDevice, command: str, outformat: Literal["json", "text"]) -> None:
outdir = Path() / root_dir / dev.name / outformat
outdir.mkdir(parents=True, exist_ok=True)
- safe_command = re.sub(r"(/|\|$)", "_", command)
+ safe_command = re.sub(rf"{REGEXP_PATH_MARKERS}", "_", command)
c = AntaCommand(command=command, ofmt=outformat)
await dev.collect(c)
if not c.collected:
- logger.error(f"Could not collect commands on device {dev.name}: {c.errors}")
+ logger.error("Could not collect commands on device %s: %s", dev.name, c.errors)
return
if c.ofmt == "json":
outfile = outdir / f"{safe_command}.json"
@@ -74,13 +73,16 @@ async def collect_commands(
elif c.ofmt == "text":
outfile = outdir / f"{safe_command}.log"
content = c.text_output
+ else:
+ logger.error("Command outformat is not in ['json', 'text'] for command '%s'", command)
+ return
with outfile.open(mode="w", encoding="UTF-8") as f:
f.write(content)
- logger.info(f"Collected command '{command}' from device {dev.name} ({dev.hw_model})")
+ logger.info("Collected command '%s' from device %s (%s)", command, dev.name, dev.hw_model)
logger.info("Connecting to devices...")
await inv.connect_inventory()
- devices = inv.get_inventory(established_only=True, tags=tags).values()
+ devices = inv.get_inventory(established_only=True, tags=tags).devices
logger.info("Collecting commands from remote devices")
coros = []
if "json_format" in commands:
@@ -90,18 +92,14 @@ async def collect_commands(
res = await asyncio.gather(*coros, return_exceptions=True)
for r in res:
if isinstance(r, Exception):
- logger.error(f"Error when collecting commands: {str(r)}")
+ logger.error("Error when collecting commands: %s", str(r))
-async def collect_scheduled_show_tech(inv: AntaInventory, root_dir: Path, configure: bool, tags: list[str] | None = None, latest: int | None = None) -> None:
- """
- Collect scheduled show-tech on devices
- """
+async def collect_show_tech(inv: AntaInventory, root_dir: Path, *, configure: bool, tags: set[str] | None = None, latest: int | None = None) -> None:
+ """Collect scheduled show-tech on devices."""
async def collect(device: AntaDevice) -> None:
- """
- Collect all the tech-support files stored on Arista switches flash and copy them locally
- """
+ """Collect all the tech-support files stored on Arista switches flash and copy them locally."""
try:
# Get the tech-support filename to retrieve
cmd = f"bash timeout 10 ls -1t {EOS_SCHEDULED_TECH_SUPPORT}"
@@ -109,12 +107,12 @@ async def collect_scheduled_show_tech(inv: AntaInventory, root_dir: Path, config
cmd += f" | head -{latest}"
command = AntaCommand(command=cmd, ofmt="text")
await device.collect(command=command)
- if command.collected and command.text_output:
- filenames = list(map(lambda f: Path(f"{EOS_SCHEDULED_TECH_SUPPORT}/{f}"), command.text_output.splitlines()))
- else:
- logger.error(f"Unable to get tech-support filenames on {device.name}: verify that {EOS_SCHEDULED_TECH_SUPPORT} is not empty")
+ if not (command.collected and command.text_output):
+ logger.error("Unable to get tech-support filenames on %s: verify that %s is not empty", device.name, EOS_SCHEDULED_TECH_SUPPORT)
return
+ filenames = [Path(f"{EOS_SCHEDULED_TECH_SUPPORT}/{f}") for f in command.text_output.splitlines()]
+
# Create directories
outdir = Path() / root_dir / f"{device.name.lower()}"
outdir.mkdir(parents=True, exist_ok=True)
@@ -124,38 +122,42 @@ async def collect_scheduled_show_tech(inv: AntaInventory, root_dir: Path, config
await device.collect(command=command)
if command.collected and not command.text_output:
- logger.debug(f"'aaa authorization exec default local' is not configured on device {device.name}")
- if configure:
- # Otherwise mypy complains about enable
- assert isinstance(device, AsyncEOSDevice)
- # TODO - @mtache - add `config` field to `AntaCommand` object to handle this use case.
- commands = []
- if device.enable and device._enable_password is not None: # pylint: disable=protected-access
- commands.append({"cmd": "enable", "input": device._enable_password}) # pylint: disable=protected-access
- elif device.enable:
- commands.append({"cmd": "enable"})
- commands.extend(
- [
- {"cmd": "configure terminal"},
- {"cmd": "aaa authorization exec default local"},
- ]
- )
- logger.warning(f"Configuring 'aaa authorization exec default local' on device {device.name}")
- command = AntaCommand(command="show running-config | include aaa authorization exec default local", ofmt="text")
- await device._session.cli(commands=commands) # pylint: disable=protected-access
- logger.info(f"Configured 'aaa authorization exec default local' on device {device.name}")
- else:
- logger.error(f"Unable to collect tech-support on {device.name}: configuration 'aaa authorization exec default local' is not present")
+ logger.debug("'aaa authorization exec default local' is not configured on device %s", device.name)
+ if not configure:
+ logger.error("Unable to collect tech-support on %s: configuration 'aaa authorization exec default local' is not present", device.name)
return
- logger.debug(f"'aaa authorization exec default local' is already configured on device {device.name}")
+
+ commands = []
+ # TODO: @mtache - add `config` field to `AntaCommand` object to handle this use case.
+ # Otherwise mypy complains about enable as it is only implemented for AsyncEOSDevice
+ # TODO: Should enable be also included in AntaDevice?
+ if not isinstance(device, AsyncEOSDevice):
+ msg = "anta exec collect-tech-support is only supported with AsyncEOSDevice for now."
+ raise UsageError(msg)
+ if device.enable and device._enable_password is not None: # pylint: disable=protected-access
+ commands.append({"cmd": "enable", "input": device._enable_password}) # pylint: disable=protected-access
+ elif device.enable:
+ commands.append({"cmd": "enable"})
+ commands.extend(
+ [
+ {"cmd": "configure terminal"},
+ {"cmd": "aaa authorization exec default local"},
+ ],
+ )
+ logger.warning("Configuring 'aaa authorization exec default local' on device %s", device.name)
+ command = AntaCommand(command="show running-config | include aaa authorization exec default local", ofmt="text")
+ await device._session.cli(commands=commands) # pylint: disable=protected-access
+ logger.info("Configured 'aaa authorization exec default local' on device %s", device.name)
+
+ logger.debug("'aaa authorization exec default local' is already configured on device %s", device.name)
await device.copy(sources=filenames, destination=outdir, direction="from")
- logger.info(f"Collected {len(filenames)} scheduled tech-support from {device.name}")
+ logger.info("Collected %s scheduled tech-support from %s", len(filenames), device.name)
except (EapiCommandError, HTTPError, ConnectError) as e:
- logger.error(f"Unable to collect tech-support on {device.name}: {str(e)}")
+ logger.error("Unable to collect tech-support on %s: %s", device.name, str(e))
logger.info("Connecting to devices...")
await inv.connect_inventory()
- devices = inv.get_inventory(established_only=True, tags=tags).values()
+ devices = inv.get_inventory(established_only=True, tags=tags).devices
await asyncio.gather(*(collect(device) for device in devices))
diff --git a/anta/cli/get/__init__.py b/anta/cli/get/__init__.py
index d822008..abc7b38 100644
--- a/anta/cli/get/__init__.py
+++ b/anta/cli/get/__init__.py
@@ -1,9 +1,8 @@
# Copyright (c) 2023-2024 Arista Networks, Inc.
# Use of this source code is governed by the Apache License 2.0
# that can be found in the LICENSE file.
-"""
-Click commands to get information from or generate inventories
-"""
+"""Click commands to get information from or generate inventories."""
+
import click
from anta.cli.get import commands
@@ -11,7 +10,7 @@ from anta.cli.get import commands
@click.group
def get() -> None:
- """Commands to get information from or generate inventories"""
+ """Commands to get information from or generate inventories."""
get.add_command(commands.from_cvp)
diff --git a/anta/cli/get/commands.py b/anta/cli/get/commands.py
index b0fe76f..a4125db 100644
--- a/anta/cli/get/commands.py
+++ b/anta/cli/get/commands.py
@@ -2,15 +2,15 @@
# Use of this source code is governed by the Apache License 2.0
# that can be found in the LICENSE file.
# pylint: disable = redefined-outer-name
-"""
-Click commands to get information from or generate inventories
-"""
+"""Click commands to get information from or generate inventories."""
+
from __future__ import annotations
import asyncio
import json
import logging
from pathlib import Path
+from typing import TYPE_CHECKING, Any
import click
from cvprac.cvp_client import CvpClient
@@ -20,10 +20,12 @@ from rich.pretty import pretty_repr
from anta.cli.console import console
from anta.cli.get.utils import inventory_output_options
from anta.cli.utils import ExitCode, inventory_options
-from anta.inventory import AntaInventory
from .utils import create_inventory_from_ansible, create_inventory_from_cvp, get_cv_token
+if TYPE_CHECKING:
+ from anta.inventory import AntaInventory
+
logger = logging.getLogger(__name__)
@@ -35,30 +37,30 @@ logger = logging.getLogger(__name__)
@click.option("--password", "-p", help="CloudVision password", type=str, required=True)
@click.option("--container", "-c", help="CloudVision container where devices are configured", type=str)
def from_cvp(ctx: click.Context, output: Path, host: str, username: str, password: str, container: str | None) -> None:
- """
- Build ANTA inventory from Cloudvision
+ # pylint: disable=too-many-arguments
+ """Build ANTA inventory from Cloudvision.
TODO - handle get_inventory and get_devices_in_container failure
"""
- logger.info(f"Getting authentication token for user '{username}' from CloudVision instance '{host}'")
+ logger.info("Getting authentication token for user '%s' from CloudVision instance '%s'", username, host)
token = get_cv_token(cvp_ip=host, cvp_username=username, cvp_password=password)
clnt = CvpClient()
try:
clnt.connect(nodes=[host], username="", password="", api_token=token)
except CvpApiError as error:
- logger.error(f"Error connecting to CloudVision: {error}")
+ logger.error("Error connecting to CloudVision: %s", error)
ctx.exit(ExitCode.USAGE_ERROR)
- logger.info(f"Connected to CloudVision instance '{host}'")
+ logger.info("Connected to CloudVision instance '%s'", host)
cvp_inventory = None
if container is None:
# Get a list of all devices
- logger.info(f"Getting full inventory from CloudVision instance '{host}'")
+ logger.info("Getting full inventory from CloudVision instance '%s'", host)
cvp_inventory = clnt.api.get_inventory()
else:
# Get devices under a container
- logger.info(f"Getting inventory for container {container} from CloudVision instance '{host}'")
+ logger.info("Getting inventory for container %s from CloudVision instance '%s'", container, host)
cvp_inventory = clnt.api.get_devices_in_container(container)
create_inventory_from_cvp(cvp_inventory, output)
@@ -74,8 +76,12 @@ def from_cvp(ctx: click.Context, output: Path, host: str, username: str, passwor
required=True,
)
def from_ansible(ctx: click.Context, output: Path, ansible_group: str, ansible_inventory: Path) -> None:
- """Build ANTA inventory from an ansible inventory YAML file"""
- logger.info(f"Building inventory from ansible file '{ansible_inventory}'")
+ """Build ANTA inventory from an ansible inventory YAML file.
+
+ NOTE: This command does not support inline vaulted variables. Make sure to comment them out.
+
+ """
+ logger.info("Building inventory from ansible file '%s'", ansible_inventory)
try:
create_inventory_from_ansible(
inventory=ansible_inventory,
@@ -90,10 +96,11 @@ def from_ansible(ctx: click.Context, output: Path, ansible_group: str, ansible_i
@click.command
@inventory_options
@click.option("--connected/--not-connected", help="Display inventory after connection has been created", default=False, required=False)
-def inventory(inventory: AntaInventory, tags: list[str] | None, connected: bool) -> None:
+def inventory(inventory: AntaInventory, tags: set[str] | None, *, connected: bool) -> None:
"""Show inventory loaded in ANTA."""
-
- logger.debug(f"Requesting devices for tags: {tags}")
+ # TODO: @gmuloc - tags come from context - we cannot have everything..
+ # ruff: noqa: ARG001
+ logger.debug("Requesting devices for tags: %s", tags)
console.print("Current inventory content is:", style="white on blue")
if connected:
@@ -105,11 +112,11 @@ def inventory(inventory: AntaInventory, tags: list[str] | None, connected: bool)
@click.command
@inventory_options
-def tags(inventory: AntaInventory, tags: list[str] | None) -> None: # pylint: disable=unused-argument
+def tags(inventory: AntaInventory, **kwargs: Any) -> None:
+ # pylint: disable=unused-argument
"""Get list of configured tags in user inventory."""
- tags_found = []
+ tags: set[str] = set()
for device in inventory.values():
- tags_found += device.tags
- tags_found = sorted(set(tags_found))
+ tags.update(device.tags)
console.print("Tags found:")
- console.print_json(json.dumps(tags_found, indent=2))
+ console.print_json(json.dumps(sorted(tags), indent=2))
diff --git a/anta/cli/get/utils.py b/anta/cli/get/utils.py
index 179da0c..1d56cfa 100644
--- a/anta/cli/get/utils.py
+++ b/anta/cli/get/utils.py
@@ -1,9 +1,8 @@
# Copyright (c) 2023-2024 Arista Networks, Inc.
# Use of this source code is governed by the Apache License 2.0
# that can be found in the LICENSE file.
-"""
-Utils functions to use with anta.cli.get.commands module.
-"""
+"""Utils functions to use with anta.cli.get.commands module."""
+
from __future__ import annotations
import functools
@@ -11,7 +10,7 @@ import json
import logging
from pathlib import Path
from sys import stdin
-from typing import Any
+from typing import Any, Callable
import click
import requests
@@ -27,8 +26,8 @@ urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
logger = logging.getLogger(__name__)
-def inventory_output_options(f: Any) -> Any:
- """Click common options required when an inventory is being generated"""
+def inventory_output_options(f: Callable[..., Any]) -> Callable[..., Any]:
+ """Click common options required when an inventory is being generated."""
@click.option(
"--output",
@@ -50,7 +49,13 @@ def inventory_output_options(f: Any) -> Any:
)
@click.pass_context
@functools.wraps(f)
- def wrapper(ctx: click.Context, *args: tuple[Any], output: Path, overwrite: bool, **kwargs: dict[str, Any]) -> Any:
+ def wrapper(
+ ctx: click.Context,
+ *args: tuple[Any],
+ output: Path,
+ overwrite: bool,
+ **kwargs: dict[str, Any],
+ ) -> Any:
# Boolean to check if the file is empty
output_is_not_empty = output.exists() and output.stat().st_size != 0
# Check overwrite when file is not empty
@@ -58,7 +63,10 @@ def inventory_output_options(f: Any) -> Any:
is_tty = stdin.isatty()
if is_tty:
# File has content and it is in an interactive TTY --> Prompt user
- click.confirm(f"Your destination file '{output}' is not empty, continue?", abort=True)
+ click.confirm(
+ f"Your destination file '{output}' is not empty, continue?",
+ abort=True,
+ )
else:
# File has content and it is not interactive TTY nor overwrite set to True --> execution stop
logger.critical("Conversion aborted since destination file is not empty (not running in interactive TTY)")
@@ -70,84 +78,103 @@ def inventory_output_options(f: Any) -> Any:
def get_cv_token(cvp_ip: str, cvp_username: str, cvp_password: str) -> str:
- """Generate AUTH token from CVP using password"""
- # TODO, need to handle requests eror
+ """Generate AUTH token from CVP using password."""
+ # TODO: need to handle requests error
# use CVP REST API to generate a token
- URL = f"https://{cvp_ip}/cvpservice/login/authenticate.do"
+ url = f"https://{cvp_ip}/cvpservice/login/authenticate.do"
payload = json.dumps({"userId": cvp_username, "password": cvp_password})
headers = {"Content-Type": "application/json", "Accept": "application/json"}
- response = requests.request("POST", URL, headers=headers, data=payload, verify=False, timeout=10)
+ response = requests.request("POST", url, headers=headers, data=payload, verify=False, timeout=10)
return response.json()["sessionId"]
def write_inventory_to_file(hosts: list[AntaInventoryHost], output: Path) -> None:
- """Write a file inventory from pydantic models"""
+ """Write a file inventory from pydantic models."""
i = AntaInventoryInput(hosts=hosts)
- with open(output, "w", encoding="UTF-8") as out_fd:
+ with output.open(mode="w", encoding="UTF-8") as out_fd:
out_fd.write(yaml.dump({AntaInventory.INVENTORY_ROOT_KEY: i.model_dump(exclude_unset=True)}))
- logger.info(f"ANTA inventory file has been created: '{output}'")
+ logger.info("ANTA inventory file has been created: '%s'", output)
def create_inventory_from_cvp(inv: list[dict[str, Any]], output: Path) -> None:
- """
- Create an inventory file from Arista CloudVision inventory
- """
- logger.debug(f"Received {len(inv)} device(s) from CloudVision")
+ """Create an inventory file from Arista CloudVision inventory."""
+ logger.debug("Received %s device(s) from CloudVision", len(inv))
hosts = []
for dev in inv:
- logger.info(f" * adding entry for {dev['hostname']}")
- hosts.append(AntaInventoryHost(name=dev["hostname"], host=dev["ipAddress"], tags=[dev["containerName"].lower()]))
+ logger.info(" * adding entry for %s", dev["hostname"])
+ hosts.append(
+ AntaInventoryHost(
+ name=dev["hostname"],
+ host=dev["ipAddress"],
+ tags={dev["containerName"].lower()},
+ )
+ )
write_inventory_to_file(hosts, output)
+def find_ansible_group(data: dict[str, Any], group: str) -> dict[str, Any] | None:
+ """Retrieve Ansible group from an input data dict."""
+ for k, v in data.items():
+ if isinstance(v, dict):
+ if k == group and ("children" in v or "hosts" in v):
+ return v
+ d = find_ansible_group(v, group)
+ if d is not None:
+ return d
+ return None
+
+
+def deep_yaml_parsing(data: dict[str, Any], hosts: list[AntaInventoryHost] | None = None) -> list[AntaInventoryHost]:
+ """Deep parsing of YAML file to extract hosts and associated IPs."""
+ if hosts is None:
+ hosts = []
+ for key, value in data.items():
+ if isinstance(value, dict) and "ansible_host" in value:
+ logger.info(" * adding entry for %s", key)
+ hosts.append(AntaInventoryHost(name=key, host=value["ansible_host"]))
+ elif isinstance(value, dict):
+ deep_yaml_parsing(value, hosts)
+ else:
+ return hosts
+ return hosts
+
+
def create_inventory_from_ansible(inventory: Path, output: Path, ansible_group: str = "all") -> None:
- """
- Create an ANTA inventory from an Ansible inventory YAML file
+ """Create an ANTA inventory from an Ansible inventory YAML file.
Args:
+ ----
inventory: Ansible Inventory file to read
output: ANTA inventory file to generate.
ansible_group: Ansible group from where to extract data.
- """
-
- def find_ansible_group(data: dict[str, Any], group: str) -> dict[str, Any] | None:
- for k, v in data.items():
- if isinstance(v, dict):
- if k == group and ("children" in v.keys() or "hosts" in v.keys()):
- return v
- d = find_ansible_group(v, group)
- if d is not None:
- return d
- return None
-
- def deep_yaml_parsing(data: dict[str, Any], hosts: list[AntaInventoryHost] | None = None) -> list[AntaInventoryHost]:
- """Deep parsing of YAML file to extract hosts and associated IPs"""
- if hosts is None:
- hosts = []
- for key, value in data.items():
- if isinstance(value, dict) and "ansible_host" in value.keys():
- logger.info(f" * adding entry for {key}")
- hosts.append(AntaInventoryHost(name=key, host=value["ansible_host"]))
- elif isinstance(value, dict):
- deep_yaml_parsing(value, hosts)
- else:
- return hosts
- return hosts
+ """
try:
- with open(inventory, encoding="utf-8") as inv:
+ with inventory.open(encoding="utf-8") as inv:
ansible_inventory = yaml.safe_load(inv)
+ except yaml.constructor.ConstructorError as exc:
+ if exc.problem and "!vault" in exc.problem:
+ logger.error(
+ "`anta get from-ansible` does not support inline vaulted variables, comment them out to generate your inventory. "
+ "If the vaulted variable is necessary to build the inventory (e.g. `ansible_host`), it needs to be unvaulted for "
+ "`from-ansible` command to work."
+ )
+ msg = f"Could not parse {inventory}."
+ raise ValueError(msg) from exc
except OSError as exc:
- raise ValueError(f"Could not parse {inventory}.") from exc
+ msg = f"Could not parse {inventory}."
+ raise ValueError(msg) from exc
if not ansible_inventory:
- raise ValueError(f"Ansible inventory {inventory} is empty")
+ msg = f"Ansible inventory {inventory} is empty"
+ raise ValueError(msg)
ansible_inventory = find_ansible_group(ansible_inventory, ansible_group)
if ansible_inventory is None:
- raise ValueError(f"Group {ansible_group} not found in Ansible inventory")
+ msg = f"Group {ansible_group} not found in Ansible inventory"
+ raise ValueError(msg)
ansible_hosts = deep_yaml_parsing(ansible_inventory)
write_inventory_to_file(ansible_hosts, output)
diff --git a/anta/cli/nrfu/__init__.py b/anta/cli/nrfu/__init__.py
index 2297bc2..6a67e60 100644
--- a/anta/cli/nrfu/__init__.py
+++ b/anta/cli/nrfu/__init__.py
@@ -1,38 +1,40 @@
# Copyright (c) 2023-2024 Arista Networks, Inc.
# Use of this source code is governed by the Apache License 2.0
# that can be found in the LICENSE file.
-"""
-Click commands that run ANTA tests using anta.runner
-"""
+"""Click commands that run ANTA tests using anta.runner."""
+
from __future__ import annotations
import asyncio
+from typing import TYPE_CHECKING, get_args
import click
-from anta.catalog import AntaCatalog
from anta.cli.nrfu import commands
from anta.cli.utils import AliasedGroup, catalog_options, inventory_options
-from anta.inventory import AntaInventory
+from anta.custom_types import TestStatus
from anta.models import AntaTest
from anta.result_manager import ResultManager
from anta.runner import main
from .utils import anta_progress_bar, print_settings
+if TYPE_CHECKING:
+ from anta.catalog import AntaCatalog
+ from anta.inventory import AntaInventory
+
class IgnoreRequiredWithHelp(AliasedGroup):
- """
+ """Custom Click Group.
+
https://stackoverflow.com/questions/55818737/python-click-application-required-parameters-have-precedence-over-sub-command-he
+
Solution to allow help without required options on subcommand
- This is not planned to be fixed in click as per: https://github.com/pallets/click/issues/295#issuecomment-708129734
+ This is not planned to be fixed in click as per: https://github.com/pallets/click/issues/295#issuecomment-708129734.
"""
def parse_args(self, ctx: click.Context, args: list[str]) -> list[str]:
- """
- Ignore MissingParameter exception when parsing arguments if `--help`
- is present for a subcommand
- """
+ """Ignore MissingParameter exception when parsing arguments if `--help` is present for a subcommand."""
# Adding a flag for potential callbacks
ctx.ensure_object(dict)
if "--help" in args:
@@ -51,14 +53,75 @@ class IgnoreRequiredWithHelp(AliasedGroup):
return super().parse_args(ctx, args)
+HIDE_STATUS: list[str] = list(get_args(TestStatus))
+HIDE_STATUS.remove("unset")
+
+
@click.group(invoke_without_command=True, cls=IgnoreRequiredWithHelp)
@click.pass_context
@inventory_options
@catalog_options
-@click.option("--ignore-status", help="Always exit with success", show_envvar=True, is_flag=True, default=False)
-@click.option("--ignore-error", help="Only report failures and not errors", show_envvar=True, is_flag=True, default=False)
-def nrfu(ctx: click.Context, inventory: AntaInventory, tags: list[str] | None, catalog: AntaCatalog, ignore_status: bool, ignore_error: bool) -> None:
- """Run ANTA tests on devices"""
+@click.option(
+ "--device",
+ "-d",
+ help="Run tests on a specific device. Can be provided multiple times.",
+ type=str,
+ multiple=True,
+ required=False,
+)
+@click.option(
+ "--test",
+ "-t",
+ help="Run a specific test. Can be provided multiple times.",
+ type=str,
+ multiple=True,
+ required=False,
+)
+@click.option(
+ "--ignore-status",
+ help="Exit code will always be 0.",
+ show_envvar=True,
+ is_flag=True,
+ default=False,
+)
+@click.option(
+ "--ignore-error",
+ help="Exit code will be 0 if all tests succeeded or 1 if any test failed.",
+ show_envvar=True,
+ is_flag=True,
+ default=False,
+)
+@click.option(
+ "--hide",
+ default=None,
+ type=click.Choice(HIDE_STATUS, case_sensitive=False),
+ multiple=True,
+ help="Group result by test or device.",
+ required=False,
+)
+@click.option(
+ "--dry-run",
+ help="Run anta nrfu command but stop before starting to execute the tests. Considers all devices as connected.",
+ type=str,
+ show_envvar=True,
+ is_flag=True,
+ default=False,
+)
+# pylint: disable=too-many-arguments
+def nrfu(
+ ctx: click.Context,
+ inventory: AntaInventory,
+ tags: set[str] | None,
+ catalog: AntaCatalog,
+ device: tuple[str],
+ test: tuple[str],
+ hide: tuple[str],
+ *,
+ ignore_status: bool,
+ ignore_error: bool,
+ dry_run: bool,
+) -> None:
+ """Run ANTA tests on selected inventory devices."""
# If help is invoke somewhere, skip the command
if ctx.obj.get("_anta_help"):
return
@@ -67,9 +130,22 @@ def nrfu(ctx: click.Context, inventory: AntaInventory, tags: list[str] | None, c
ctx.obj["result_manager"] = ResultManager()
ctx.obj["ignore_status"] = ignore_status
ctx.obj["ignore_error"] = ignore_error
+ ctx.obj["hide"] = set(hide) if hide else None
print_settings(inventory, catalog)
with anta_progress_bar() as AntaTest.progress:
- asyncio.run(main(ctx.obj["result_manager"], inventory, catalog, tags=tags))
+ asyncio.run(
+ main(
+ ctx.obj["result_manager"],
+ inventory,
+ catalog,
+ tags=tags,
+ devices=set(device) if device else None,
+ tests=set(test) if test else None,
+ dry_run=dry_run,
+ )
+ )
+ if dry_run:
+ return
# Invoke `anta nrfu table` if no command is passed
if ctx.invoked_subcommand is None:
ctx.invoke(commands.table)
diff --git a/anta/cli/nrfu/commands.py b/anta/cli/nrfu/commands.py
index a0acfc9..4dd779b 100644
--- a/anta/cli/nrfu/commands.py
+++ b/anta/cli/nrfu/commands.py
@@ -1,13 +1,13 @@
# Copyright (c) 2023-2024 Arista Networks, Inc.
# Use of this source code is governed by the Apache License 2.0
# that can be found in the LICENSE file.
-"""
-Click commands that render ANTA tests results
-"""
+"""Click commands that render ANTA tests results."""
+
from __future__ import annotations
import logging
import pathlib
+from typing import Literal
import click
@@ -20,14 +20,19 @@ logger = logging.getLogger(__name__)
@click.command()
@click.pass_context
-@click.option("--device", "-d", help="Show a summary for this device", type=str, required=False)
-@click.option("--test", "-t", help="Show a summary for this test", type=str, required=False)
@click.option(
- "--group-by", default=None, type=click.Choice(["device", "test"], case_sensitive=False), help="Group result by test or host. default none", required=False
+ "--group-by",
+ default=None,
+ type=click.Choice(["device", "test"], case_sensitive=False),
+ help="Group result by test or device.",
+ required=False,
)
-def table(ctx: click.Context, device: str | None, test: str | None, group_by: str) -> None:
- """ANTA command to check network states with table result"""
- print_table(results=ctx.obj["result_manager"], device=device, group_by=group_by, test=test)
+def table(
+ ctx: click.Context,
+ group_by: Literal["device", "test"] | None,
+) -> None:
+ """ANTA command to check network states with table result."""
+ print_table(ctx, group_by=group_by)
exit_with_code(ctx)
@@ -42,18 +47,16 @@ def table(ctx: click.Context, device: str | None, test: str | None, group_by: st
help="Path to save report as a file",
)
def json(ctx: click.Context, output: pathlib.Path | None) -> None:
- """ANTA command to check network state with JSON result"""
- print_json(results=ctx.obj["result_manager"], output=output)
+ """ANTA command to check network state with JSON result."""
+ print_json(ctx, output=output)
exit_with_code(ctx)
@click.command()
@click.pass_context
-@click.option("--search", "-s", help="Regular expression to search in both name and test", type=str, required=False)
-@click.option("--skip-error", help="Hide tests in errors due to connectivity issue", default=False, is_flag=True, show_default=True, required=False)
-def text(ctx: click.Context, search: str | None, skip_error: bool) -> None:
- """ANTA command to check network states with text result"""
- print_text(results=ctx.obj["result_manager"], search=search, skip_error=skip_error)
+def text(ctx: click.Context) -> None:
+ """ANTA command to check network states with text result."""
+ print_text(ctx)
exit_with_code(ctx)
@@ -76,6 +79,6 @@ def text(ctx: click.Context, search: str | None, skip_error: bool) -> None:
help="Path to save report as a file",
)
def tpl_report(ctx: click.Context, template: pathlib.Path, output: pathlib.Path | None) -> None:
- """ANTA command to check network state with templated report"""
+ """ANTA command to check network state with templated report."""
print_jinja(results=ctx.obj["result_manager"], template=template, output=output)
exit_with_code(ctx)
diff --git a/anta/cli/nrfu/utils.py b/anta/cli/nrfu/utils.py
index 87b89cf..2eeeacb 100644
--- a/anta/cli/nrfu/utils.py
+++ b/anta/cli/nrfu/utils.py
@@ -1,101 +1,96 @@
# Copyright (c) 2023-2024 Arista Networks, Inc.
# Use of this source code is governed by the Apache License 2.0
# that can be found in the LICENSE file.
-"""
-Utils functions to use with anta.cli.nrfu.commands module.
-"""
+"""Utils functions to use with anta.cli.nrfu.commands module."""
+
from __future__ import annotations
import json
import logging
-import pathlib
-import re
+from typing import TYPE_CHECKING, Literal
import rich
from rich.panel import Panel
-from rich.pretty import pprint
from rich.progress import BarColumn, MofNCompleteColumn, Progress, SpinnerColumn, TextColumn, TimeElapsedColumn, TimeRemainingColumn
-from anta.catalog import AntaCatalog
from anta.cli.console import console
-from anta.inventory import AntaInventory
from anta.reporter import ReportJinja, ReportTable
-from anta.result_manager import ResultManager
+
+if TYPE_CHECKING:
+ import pathlib
+
+ import click
+
+ from anta.catalog import AntaCatalog
+ from anta.inventory import AntaInventory
+ from anta.result_manager import ResultManager
logger = logging.getLogger(__name__)
+def _get_result_manager(ctx: click.Context) -> ResultManager:
+ """Get a ResultManager instance based on Click context."""
+ return ctx.obj["result_manager"].filter(ctx.obj.get("hide")) if ctx.obj.get("hide") is not None else ctx.obj["result_manager"]
+
+
def print_settings(
inventory: AntaInventory,
catalog: AntaCatalog,
) -> None:
- """Print ANTA settings before running tests"""
- message = f"Running ANTA tests:\n- {inventory}\n- Tests catalog contains {len(catalog.tests)} tests"
+ """Print ANTA settings before running tests."""
+ message = f"- {inventory}\n- Tests catalog contains {len(catalog.tests)} tests"
console.print(Panel.fit(message, style="cyan", title="[green]Settings"))
console.print()
-def print_table(results: ResultManager, device: str | None = None, test: str | None = None, group_by: str | None = None) -> None:
- """Print result in a table"""
+def print_table(ctx: click.Context, group_by: Literal["device", "test"] | None = None) -> None:
+ """Print result in a table."""
reporter = ReportTable()
console.print()
- if device:
- console.print(reporter.report_all(result_manager=results, host=device))
- elif test:
- console.print(reporter.report_all(result_manager=results, testcase=test))
- elif group_by == "device":
- console.print(reporter.report_summary_hosts(result_manager=results, host=None))
+ results = _get_result_manager(ctx)
+
+ if group_by == "device":
+ console.print(reporter.report_summary_devices(results))
elif group_by == "test":
- console.print(reporter.report_summary_tests(result_manager=results, testcase=None))
+ console.print(reporter.report_summary_tests(results))
else:
- console.print(reporter.report_all(result_manager=results))
-
-
-def print_json(results: ResultManager, output: pathlib.Path | None = None) -> None:
- """Print result in a json format"""
- console.print()
- console.print(Panel("JSON results of all tests", style="cyan"))
- rich.print_json(results.get_json_results())
- if output is not None:
- with open(output, "w", encoding="utf-8") as fout:
- fout.write(results.get_json_results())
+ console.print(reporter.report_all(results))
-def print_list(results: ResultManager, output: pathlib.Path | None = None) -> None:
- """Print result in a list"""
+def print_json(ctx: click.Context, output: pathlib.Path | None = None) -> None:
+ """Print result in a json format."""
+ results = _get_result_manager(ctx)
console.print()
- console.print(Panel.fit("List results of all tests", style="cyan"))
- pprint(results.get_results())
+ console.print(Panel("JSON results", style="cyan"))
+ rich.print_json(results.json)
if output is not None:
- with open(output, "w", encoding="utf-8") as fout:
- fout.write(str(results.get_results()))
+ with output.open(mode="w", encoding="utf-8") as fout:
+ fout.write(results.json)
-def print_text(results: ResultManager, search: str | None = None, skip_error: bool = False) -> None:
- """Print results as simple text"""
+def print_text(ctx: click.Context) -> None:
+ """Print results as simple text."""
console.print()
- regexp = re.compile(search or ".*")
- for line in results.get_results():
- if any(regexp.match(entry) for entry in [line.name, line.test]) and (not skip_error or line.result != "error"):
- message = f" ({str(line.messages[0])})" if len(line.messages) > 0 else ""
- console.print(f"{line.name} :: {line.test} :: [{line.result}]{line.result.upper()}[/{line.result}]{message}", highlight=False)
+ for test in _get_result_manager(ctx).results:
+ message = f" ({test.messages[0]!s})" if len(test.messages) > 0 else ""
+ console.print(f"{test.name} :: {test.test} :: [{test.result}]{test.result.upper()}[/{test.result}]{message}", highlight=False)
def print_jinja(results: ResultManager, template: pathlib.Path, output: pathlib.Path | None = None) -> None:
"""Print result based on template."""
console.print()
reporter = ReportJinja(template_path=template)
- json_data = json.loads(results.get_json_results())
+ json_data = json.loads(results.json)
report = reporter.render(json_data)
console.print(report)
if output is not None:
- with open(output, "w", encoding="utf-8") as file:
+ with output.open(mode="w", encoding="utf-8") as file:
file.write(report)
# Adding our own ANTA spinner - overriding rich SPINNERS for our own
# so ignore warning for redefinition
-rich.spinner.SPINNERS = { # type: ignore[attr-defined] # noqa: F811
+rich.spinner.SPINNERS = { # type: ignore[attr-defined]
"anta": {
"interval": 150,
"frames": [
@@ -112,14 +107,12 @@ rich.spinner.SPINNERS = { # type: ignore[attr-defined] # noqa: F811
"( 🐌 )",
"( 🐌)",
],
- }
+ },
}
def anta_progress_bar() -> Progress:
- """
- Return a customized Progress for progress bar
- """
+ """Return a customized Progress for progress bar."""
return Progress(
SpinnerColumn("anta"),
TextColumn("•"),
diff --git a/anta/cli/utils.py b/anta/cli/utils.py
index 97a0862..71d99b8 100644
--- a/anta/cli/utils.py
+++ b/anta/cli/utils.py
@@ -1,24 +1,22 @@
# Copyright (c) 2023-2024 Arista Networks, Inc.
# Use of this source code is governed by the Apache License 2.0
# that can be found in the LICENSE file.
-"""
-Utils functions to use with anta.cli module.
-"""
+"""Utils functions to use with anta.cli module."""
+
from __future__ import annotations
import enum
import functools
import logging
from pathlib import Path
-from typing import TYPE_CHECKING, Any
+from typing import TYPE_CHECKING, Any, Callable
import click
-from pydantic import ValidationError
from yaml import YAMLError
from anta.catalog import AntaCatalog
from anta.inventory import AntaInventory
-from anta.inventory.exceptions import InventoryIncorrectSchema, InventoryRootKeyError
+from anta.inventory.exceptions import InventoryIncorrectSchemaError, InventoryRootKeyError
if TYPE_CHECKING:
from click import Option
@@ -27,10 +25,7 @@ logger = logging.getLogger(__name__)
class ExitCode(enum.IntEnum):
- """
- Encodes the valid exit codes by anta
- inspired from pytest
- """
+ """Encodes the valid exit codes by anta inspired from pytest."""
# Tests passed.
OK = 0
@@ -44,19 +39,18 @@ class ExitCode(enum.IntEnum):
TESTS_FAILED = 4
-def parse_tags(ctx: click.Context, param: Option, value: str) -> list[str] | None:
+def parse_tags(ctx: click.Context, param: Option, value: str | None) -> set[str] | None:
# pylint: disable=unused-argument
- """
- Click option callback to parse an ANTA inventory tags
- """
+ # ruff: noqa: ARG001
+ """Click option callback to parse an ANTA inventory tags."""
if value is not None:
- return value.split(",") if "," in value else [value]
+ return set(value.split(",")) if "," in value else {value}
return None
def exit_with_code(ctx: click.Context) -> None:
- """
- Exit the Click application with an exit code.
+ """Exit the Click application with an exit code.
+
This function determines the global test status to be either `unset`, `skipped`, `success` or `error`
from the `ResultManger` instance.
If flag `ignore_error` is set, the `error` status will be ignored in all the tests.
@@ -64,10 +58,12 @@ def exit_with_code(ctx: click.Context) -> None:
Exit the application with the following exit code:
* 0 if `ignore_status` is `True` or global test status is `unset`, `skipped` or `success`
* 1 if status is `failure`
- * 2 if status is `error`
+ * 2 if status is `error`.
Args:
+ ----
ctx: Click Context
+
"""
if ctx.obj.get("ignore_status"):
ctx.exit(ExitCode.OK)
@@ -83,18 +79,19 @@ def exit_with_code(ctx: click.Context) -> None:
ctx.exit(ExitCode.TESTS_ERROR)
logger.error("Please gather logs and open an issue on Github.")
- raise ValueError(f"Unknown status returned by the ResultManager: {status}. Please gather logs and open an issue on Github.")
+ msg = f"Unknown status returned by the ResultManager: {status}. Please gather logs and open an issue on Github."
+ raise ValueError(msg)
class AliasedGroup(click.Group):
- """
- Implements a subclass of Group that accepts a prefix for a command.
+ """Implements a subclass of Group that accepts a prefix for a command.
+
If there were a command called push, it would accept pus as an alias (so long as it was unique)
- From Click documentation
+ From Click documentation.
"""
def get_command(self, ctx: click.Context, cmd_name: str) -> Any:
- """Todo: document code"""
+ """Todo: document code."""
rv = click.Group.get_command(self, ctx, cmd_name)
if rv is not None:
return rv
@@ -107,15 +104,16 @@ class AliasedGroup(click.Group):
return None
def resolve_command(self, ctx: click.Context, args: Any) -> Any:
- """Todo: document code"""
+ """Todo: document code."""
# always return the full command name
_, cmd, args = super().resolve_command(ctx, args)
- return cmd.name, cmd, args # type: ignore
+ if not cmd:
+ return None, None, None
+ return cmd.name, cmd, args
-# TODO: check code of click.pass_context that raise mypy errors for types and adapt this decorator
-def inventory_options(f: Any) -> Any:
- """Click common options when requiring an inventory to interact with devices"""
+def inventory_options(f: Callable[..., Any]) -> Callable[..., Any]:
+ """Click common options when requiring an inventory to interact with devices."""
@click.option(
"--username",
@@ -159,26 +157,34 @@ def inventory_options(f: Any) -> Any:
)
@click.option(
"--timeout",
- help="Global connection timeout",
- default=30,
+ help="Global API timeout. This value will be used for all devices.",
+ default=30.0,
show_envvar=True,
envvar="ANTA_TIMEOUT",
show_default=True,
)
@click.option(
"--insecure",
- help="Disable SSH Host Key validation",
+ help="Disable SSH Host Key validation.",
default=False,
show_envvar=True,
envvar="ANTA_INSECURE",
is_flag=True,
show_default=True,
)
- @click.option("--disable-cache", help="Disable cache globally", show_envvar=True, envvar="ANTA_DISABLE_CACHE", show_default=True, is_flag=True, default=False)
+ @click.option(
+ "--disable-cache",
+ help="Disable cache globally.",
+ show_envvar=True,
+ envvar="ANTA_DISABLE_CACHE",
+ show_default=True,
+ is_flag=True,
+ default=False,
+ )
@click.option(
"--inventory",
"-i",
- help="Path to the inventory YAML file",
+ help="Path to the inventory YAML file.",
envvar="ANTA_INVENTORY",
show_envvar=True,
required=True,
@@ -186,8 +192,7 @@ def inventory_options(f: Any) -> Any:
)
@click.option(
"--tags",
- "-t",
- help="List of tags using comma as separator: tag1,tag2,tag3",
+ help="List of tags using comma as separator: tag1,tag2,tag3.",
show_envvar=True,
envvar="ANTA_TAGS",
type=str,
@@ -200,13 +205,13 @@ def inventory_options(f: Any) -> Any:
ctx: click.Context,
*args: tuple[Any],
inventory: Path,
- tags: list[str] | None,
+ tags: set[str] | None,
username: str,
password: str | None,
enable_password: str | None,
enable: bool,
prompt: bool,
- timeout: int,
+ timeout: float,
insecure: bool,
disable_cache: bool,
**kwargs: dict[str, Any],
@@ -218,17 +223,25 @@ def inventory_options(f: Any) -> Any:
if prompt:
# User asked for a password prompt
if password is None:
- password = click.prompt("Please enter a password to connect to EOS", type=str, hide_input=True, confirmation_prompt=True)
- if enable:
- if enable_password is None:
- if click.confirm("Is a password required to enter EOS privileged EXEC mode?"):
- enable_password = click.prompt(
- "Please enter a password to enter EOS privileged EXEC mode", type=str, hide_input=True, confirmation_prompt=True
- )
+ password = click.prompt(
+ "Please enter a password to connect to EOS",
+ type=str,
+ hide_input=True,
+ confirmation_prompt=True,
+ )
+ if enable and enable_password is None and click.confirm("Is a password required to enter EOS privileged EXEC mode?"):
+ enable_password = click.prompt(
+ "Please enter a password to enter EOS privileged EXEC mode",
+ type=str,
+ hide_input=True,
+ confirmation_prompt=True,
+ )
if password is None:
- raise click.BadParameter("EOS password needs to be provided by using either the '--password' option or the '--prompt' option.")
+ msg = "EOS password needs to be provided by using either the '--password' option or the '--prompt' option."
+ raise click.BadParameter(msg)
if not enable and enable_password:
- raise click.BadParameter("Providing a password to access EOS Privileged EXEC mode requires '--enable' option.")
+ msg = "Providing a password to access EOS Privileged EXEC mode requires '--enable' option."
+ raise click.BadParameter(msg)
try:
i = AntaInventory.parse(
filename=inventory,
@@ -240,15 +253,15 @@ def inventory_options(f: Any) -> Any:
insecure=insecure,
disable_cache=disable_cache,
)
- except (ValidationError, TypeError, ValueError, YAMLError, OSError, InventoryIncorrectSchema, InventoryRootKeyError):
+ except (TypeError, ValueError, YAMLError, OSError, InventoryIncorrectSchemaError, InventoryRootKeyError):
ctx.exit(ExitCode.USAGE_ERROR)
return f(*args, inventory=i, tags=tags, **kwargs)
return wrapper
-def catalog_options(f: Any) -> Any:
- """Click common options when requiring a test catalog to execute ANTA tests"""
+def catalog_options(f: Callable[..., Any]) -> Callable[..., Any]:
+ """Click common options when requiring a test catalog to execute ANTA tests."""
@click.option(
"--catalog",
@@ -256,18 +269,29 @@ def catalog_options(f: Any) -> Any:
envvar="ANTA_CATALOG",
show_envvar=True,
help="Path to the test catalog YAML file",
- type=click.Path(file_okay=True, dir_okay=False, exists=True, readable=True, path_type=Path),
+ type=click.Path(
+ file_okay=True,
+ dir_okay=False,
+ exists=True,
+ readable=True,
+ path_type=Path,
+ ),
required=True,
)
@click.pass_context
@functools.wraps(f)
- def wrapper(ctx: click.Context, *args: tuple[Any], catalog: Path, **kwargs: dict[str, Any]) -> Any:
+ def wrapper(
+ ctx: click.Context,
+ *args: tuple[Any],
+ catalog: Path,
+ **kwargs: dict[str, Any],
+ ) -> Any:
# If help is invoke somewhere, do not parse catalog
if ctx.obj.get("_anta_help"):
return f(*args, catalog=None, **kwargs)
try:
c = AntaCatalog.parse(catalog)
- except (ValidationError, TypeError, ValueError, YAMLError, OSError):
+ except (TypeError, ValueError, YAMLError, OSError):
ctx.exit(ExitCode.USAGE_ERROR)
return f(*args, catalog=c, **kwargs)
diff --git a/anta/custom_types.py b/anta/custom_types.py
index d0b9e4b..a0a0631 100644
--- a/anta/custom_types.py
+++ b/anta/custom_types.py
@@ -1,19 +1,42 @@
# Copyright (c) 2023-2024 Arista Networks, Inc.
# Use of this source code is governed by the Apache License 2.0
# that can be found in the LICENSE file.
-"""
-Module that provides predefined types for AntaTest.Input instances
-"""
+"""Module that provides predefined types for AntaTest.Input instances."""
+
import re
-from typing import Literal
+from typing import Annotated, Literal
from pydantic import Field
from pydantic.functional_validators import AfterValidator, BeforeValidator
-from typing_extensions import Annotated
+
+# Regular Expression definition
+# TODO: make this configurable - with an env var maybe?
+REGEXP_EOS_BLACKLIST_CMDS = [r"^reload.*", r"^conf\w*\s*(terminal|session)*", r"^wr\w*\s*\w+"]
+"""List of regular expressions to blacklist from eos commands."""
+REGEXP_PATH_MARKERS = r"[\\\/\s]"
+"""Match directory path from string."""
+REGEXP_INTERFACE_ID = r"\d+(\/\d+)*(\.\d+)?"
+"""Match Interface ID lilke 1/1.1."""
+REGEXP_TYPE_EOS_INTERFACE = r"^(Dps|Ethernet|Fabric|Loopback|Management|Port-Channel|Tunnel|Vlan|Vxlan)[0-9]+(\/[0-9]+)*(\.[0-9]+)?$"
+"""Match EOS interface types like Ethernet1/1, Vlan1, Loopback1, etc."""
+REGEXP_TYPE_VXLAN_SRC_INTERFACE = r"^(Loopback)([0-9]|[1-9][0-9]{1,2}|[1-7][0-9]{3}|8[01][0-9]{2}|819[01])$"
+"""Match Vxlan source interface like Loopback10."""
+REGEXP_TYPE_HOSTNAME = r"^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\-]*[A-Za-z0-9])$"
+"""Match hostname like `my-hostname`, `my-hostname-1`, `my-hostname-1-2`."""
+
+# Regexp BGP AFI/SAFI
+REGEXP_BGP_L2VPN_AFI = r"\b(l2[\s\-]?vpn[\s\-]?evpn)\b"
+"""Match L2VPN EVPN AFI."""
+REGEXP_BGP_IPV4_MPLS_LABELS = r"\b(ipv4[\s\-]?mpls[\s\-]?label(s)?)\b"
+"""Match IPv4 MPLS Labels."""
+REGEX_BGP_IPV4_MPLS_VPN = r"\b(ipv4[\s\-]?mpls[\s\-]?vpn)\b"
+"""Match IPv4 MPLS VPN."""
+REGEX_BGP_IPV4_UNICAST = r"\b(ipv4[\s\-]?uni[\s\-]?cast)\b"
+"""Match IPv4 Unicast."""
def aaa_group_prefix(v: str) -> str:
- """Prefix the AAA method with 'group' if it is known"""
+ """Prefix the AAA method with 'group' if it is known."""
built_in_methods = ["local", "none", "logging"]
return f"group {v}" if v not in built_in_methods and not v.startswith("group ") else v
@@ -24,49 +47,51 @@ def interface_autocomplete(v: str) -> str:
Supported alias:
- `et`, `eth` will be changed to `Ethernet`
- `po` will be changed to `Port-Channel`
- - `lo` will be changed to `Loopback`"""
- intf_id_re = re.compile(r"[0-9]+(\/[0-9]+)*(\.[0-9]+)?")
+ - `lo` will be changed to `Loopback`
+ """
+ intf_id_re = re.compile(REGEXP_INTERFACE_ID)
m = intf_id_re.search(v)
if m is None:
- raise ValueError(f"Could not parse interface ID in interface '{v}'")
+ msg = f"Could not parse interface ID in interface '{v}'"
+ raise ValueError(msg)
intf_id = m[0]
alias_map = {"et": "Ethernet", "eth": "Ethernet", "po": "Port-Channel", "lo": "Loopback"}
- for alias, full_name in alias_map.items():
- if v.lower().startswith(alias):
- return f"{full_name}{intf_id}"
-
- return v
+ return next((f"{full_name}{intf_id}" for alias, full_name in alias_map.items() if v.lower().startswith(alias)), v)
def interface_case_sensitivity(v: str) -> str:
"""Reformat interface name to match expected case sensitivity.
- Examples:
+ Examples
+ --------
- ethernet -> Ethernet
- vlan -> Vlan
- loopback -> Loopback
+
"""
- if isinstance(v, str) and len(v) > 0 and not v[0].isupper():
+ if isinstance(v, str) and v != "" and not v[0].isupper():
return f"{v[0].upper()}{v[1:]}"
return v
def bgp_multiprotocol_capabilities_abbreviations(value: str) -> str:
- """
- Abbreviations for different BGP multiprotocol capabilities.
- Examples:
+ """Abbreviations for different BGP multiprotocol capabilities.
+
+ Examples
+ --------
- IPv4 Unicast
- L2vpnEVPN
- ipv4 MPLS Labels
- ipv4Mplsvpn
+
"""
patterns = {
- r"\b(l2[\s\-]?vpn[\s\-]?evpn)\b": "l2VpnEvpn",
- r"\bipv4[\s_-]?mpls[\s_-]?label(s)?\b": "ipv4MplsLabels",
- r"\bipv4[\s_-]?mpls[\s_-]?vpn\b": "ipv4MplsVpn",
- r"\bipv4[\s_-]?uni[\s_-]?cast\b": "ipv4Unicast",
+ REGEXP_BGP_L2VPN_AFI: "l2VpnEvpn",
+ REGEXP_BGP_IPV4_MPLS_LABELS: "ipv4MplsLabels",
+ REGEX_BGP_IPV4_MPLS_VPN: "ipv4MplsVpn",
+ REGEX_BGP_IPV4_UNICAST: "ipv4Unicast",
}
for pattern, replacement in patterns.items():
@@ -77,6 +102,16 @@ def bgp_multiprotocol_capabilities_abbreviations(value: str) -> str:
return value
+def validate_regex(value: str) -> str:
+ """Validate that the input value is a valid regex format."""
+ try:
+ re.compile(value)
+ except re.error as e:
+ msg = f"Invalid regex: {e}"
+ raise ValueError(msg) from e
+ return value
+
+
# ANTA framework
TestStatus = Literal["unset", "success", "failure", "error", "skipped"]
@@ -87,21 +122,27 @@ MlagPriority = Annotated[int, Field(ge=1, le=32767)]
Vni = Annotated[int, Field(ge=1, le=16777215)]
Interface = Annotated[
str,
- Field(pattern=r"^(Dps|Ethernet|Fabric|Loopback|Management|Port-Channel|Tunnel|Vlan|Vxlan)[0-9]+(\/[0-9]+)*(\.[0-9]+)?$"),
+ Field(pattern=REGEXP_TYPE_EOS_INTERFACE),
+ BeforeValidator(interface_autocomplete),
+ BeforeValidator(interface_case_sensitivity),
+]
+EthernetInterface = Annotated[
+ str,
+ Field(pattern=r"^Ethernet[0-9]+(\/[0-9]+)*$"),
BeforeValidator(interface_autocomplete),
BeforeValidator(interface_case_sensitivity),
]
VxlanSrcIntf = Annotated[
str,
- Field(pattern=r"^(Loopback)([0-9]|[1-9][0-9]{1,2}|[1-7][0-9]{3}|8[01][0-9]{2}|819[01])$"),
+ Field(pattern=REGEXP_TYPE_VXLAN_SRC_INTERFACE),
BeforeValidator(interface_autocomplete),
BeforeValidator(interface_case_sensitivity),
]
-Afi = Literal["ipv4", "ipv6", "vpn-ipv4", "vpn-ipv6", "evpn", "rt-membership"]
-Safi = Literal["unicast", "multicast", "labeled-unicast"]
+Afi = Literal["ipv4", "ipv6", "vpn-ipv4", "vpn-ipv6", "evpn", "rt-membership", "path-selection", "link-state"]
+Safi = Literal["unicast", "multicast", "labeled-unicast", "sr-te"]
EncryptionAlgorithm = Literal["RSA", "ECDSA"]
RsaKeySize = Literal[2048, 3072, 4096]
-EcdsaKeySize = Literal[256, 384, 521]
+EcdsaKeySize = Literal[256, 384, 512]
MultiProtocolCaps = Annotated[str, BeforeValidator(bgp_multiprotocol_capabilities_abbreviations)]
BfdInterval = Annotated[int, Field(ge=50, le=60000)]
BfdMultiplier = Annotated[int, Field(ge=3, le=50)]
@@ -120,3 +161,9 @@ ErrDisableReasons = Literal[
"uplink-failure-detection",
]
ErrDisableInterval = Annotated[int, Field(ge=30, le=86400)]
+Percent = Annotated[float, Field(ge=0.0, le=100.0)]
+PositiveInteger = Annotated[int, Field(ge=0)]
+Revision = Annotated[int, Field(ge=1, le=99)]
+Hostname = Annotated[str, Field(pattern=REGEXP_TYPE_HOSTNAME)]
+Port = Annotated[int, Field(ge=1, le=65535)]
+RegexString = Annotated[str, AfterValidator(validate_regex)]
diff --git a/anta/decorators.py b/anta/decorators.py
index 548f04a..dc57e13 100644
--- a/anta/decorators.py
+++ b/anta/decorators.py
@@ -2,40 +2,45 @@
# Use of this source code is governed by the Apache License 2.0
# that can be found in the LICENSE file.
"""decorators for tests."""
+
from __future__ import annotations
from functools import wraps
-from typing import TYPE_CHECKING, Any, Callable, Optional, TypeVar, cast
+from typing import TYPE_CHECKING, Any, Callable, TypeVar, cast
from anta.models import AntaTest, logger
if TYPE_CHECKING:
from anta.result_manager.models import TestResult
-# TODO - should probably use mypy Awaitable in some places rather than this everywhere - @gmuloc
+# TODO: should probably use mypy Awaitable in some places rather than this everywhere - @gmuloc
F = TypeVar("F", bound=Callable[..., Any])
-def deprecated_test(new_tests: Optional[list[str]] = None) -> Callable[[F], F]:
- """
- Return a decorator to log a message of WARNING severity when a test is deprecated.
+def deprecated_test(new_tests: list[str] | None = None) -> Callable[[F], F]:
+ """Return a decorator to log a message of WARNING severity when a test is deprecated.
Args:
- new_tests (Optional[list[str]]): A list of new test classes that should replace the deprecated test.
+ ----
+ new_tests: A list of new test classes that should replace the deprecated test.
- Returns:
+ Returns
+ -------
Callable[[F], F]: A decorator that can be used to wrap test functions.
+
"""
def decorator(function: F) -> F:
- """
- Actual decorator that logs the message.
+ """Actual decorator that logs the message.
Args:
- function (F): The test function to be decorated.
+ ----
+ function: The test function to be decorated.
- Returns:
+ Returns
+ -------
F: The decorated function.
+
"""
@wraps(function)
@@ -43,9 +48,9 @@ def deprecated_test(new_tests: Optional[list[str]] = None) -> Callable[[F], F]:
anta_test = args[0]
if new_tests:
new_test_names = ", ".join(new_tests)
- logger.warning(f"{anta_test.name} test is deprecated. Consider using the following new tests: {new_test_names}.")
+ logger.warning("%s test is deprecated. Consider using the following new tests: %s.", anta_test.name, new_test_names)
else:
- logger.warning(f"{anta_test.name} test is deprecated.")
+ logger.warning("%s test is deprecated.", anta_test.name)
return await function(*args, **kwargs)
return cast(F, wrapper)
@@ -54,34 +59,37 @@ def deprecated_test(new_tests: Optional[list[str]] = None) -> Callable[[F], F]:
def skip_on_platforms(platforms: list[str]) -> Callable[[F], F]:
- """
- Return a decorator to skip a test based on the device's hardware model.
+ """Return a decorator to skip a test based on the device's hardware model.
This decorator factory generates a decorator that will check the hardware model of the device
the test is run on. If the model is in the list of platforms specified, the test will be skipped.
Args:
- platforms (list[str]): List of hardware models on which the test should be skipped.
+ ----
+ platforms: List of hardware models on which the test should be skipped.
- Returns:
+ Returns
+ -------
Callable[[F], F]: A decorator that can be used to wrap test functions.
+
"""
def decorator(function: F) -> F:
- """
- Actual decorator that either runs the test or skips it based on the device's hardware model.
+ """Actual decorator that either runs the test or skips it based on the device's hardware model.
Args:
- function (F): The test function to be decorated.
+ ----
+ function: The test function to be decorated.
- Returns:
+ Returns
+ -------
F: The decorated function.
+
"""
@wraps(function)
async def wrapper(*args: Any, **kwargs: Any) -> TestResult:
- """
- Check the device's hardware model and conditionally run or skip the test.
+ """Check the device's hardware model and conditionally run or skip the test.
This wrapper inspects the hardware model of the device the test is run on.
If the model is in the list of specified platforms, the test is either skipped.
diff --git a/anta/device.py b/anta/device.py
index d9060c9..f0ec6a0 100644
--- a/anta/device.py
+++ b/anta/device.py
@@ -1,65 +1,76 @@
# Copyright (c) 2023-2024 Arista Networks, Inc.
# Use of this source code is governed by the Apache License 2.0
# that can be found in the LICENSE file.
-"""
-ANTA Device Abstraction Module
-"""
+"""ANTA Device Abstraction Module."""
+
from __future__ import annotations
import asyncio
import logging
from abc import ABC, abstractmethod
from collections import defaultdict
-from pathlib import Path
-from typing import Any, Iterator, Literal, Optional, Union
+from typing import TYPE_CHECKING, Any, Literal
import asyncssh
+import httpcore
from aiocache import Cache
from aiocache.plugins import HitMissRatioPlugin
from asyncssh import SSHClientConnection, SSHClientConnectionOptions
-from httpx import ConnectError, HTTPError
+from httpx import ConnectError, HTTPError, TimeoutException
-from anta import __DEBUG__, aioeapi
+import asynceapi
+from anta import __DEBUG__
+from anta.logger import anta_log_exception, exc_to_str
from anta.models import AntaCommand
-from anta.tools.misc import exc_to_str
+
+if TYPE_CHECKING:
+ from collections.abc import Iterator
+ from pathlib import Path
logger = logging.getLogger(__name__)
+# Do not load the default keypairs multiple times due to a performance issue introduced in cryptography 37.0
+# https://github.com/pyca/cryptography/issues/7236#issuecomment-1131908472
+CLIENT_KEYS = asyncssh.public_key.load_default_keypairs()
+
class AntaDevice(ABC):
- """
- Abstract class representing a device in ANTA.
+ """Abstract class representing a device in ANTA.
+
An implementation of this class must override the abstract coroutines `_collect()` and
`refresh()`.
- Attributes:
+ Attributes
+ ----------
name: Device name
- is_online: True if the device IP is reachable and a port can be open
- established: True if remote command execution succeeds
- hw_model: Hardware model of the device
- tags: List of tags for this device
- cache: In-memory cache from aiocache library for this device (None if cache is disabled)
- cache_locks: Dictionary mapping keys to asyncio locks to guarantee exclusive access to the cache if not disabled
+ is_online: True if the device IP is reachable and a port can be open.
+ established: True if remote command execution succeeds.
+ hw_model: Hardware model of the device.
+ tags: Tags for this device.
+ cache: In-memory cache from aiocache library for this device (None if cache is disabled).
+ cache_locks: Dictionary mapping keys to asyncio locks to guarantee exclusive access to the cache if not disabled.
+
"""
- def __init__(self, name: str, tags: Optional[list[str]] = None, disable_cache: bool = False) -> None:
- """
- Constructor of AntaDevice
+ def __init__(self, name: str, tags: set[str] | None = None, *, disable_cache: bool = False) -> None:
+ """Initialize an AntaDevice.
Args:
- name: Device name
- tags: List of tags for this device
- disable_cache: Disable caching for all commands for this device. Defaults to False.
+ ----
+ name: Device name.
+ tags: Tags for this device.
+ disable_cache: Disable caching for all commands for this device.
+
"""
self.name: str = name
- self.hw_model: Optional[str] = None
- self.tags: list[str] = tags if tags is not None else []
+ self.hw_model: str | None = None
+ self.tags: set[str] = tags if tags is not None else set()
# A device always has its own name as tag
- self.tags.append(self.name)
+ self.tags.add(self.name)
self.is_online: bool = False
self.established: bool = False
- self.cache: Optional[Cache] = None
- self.cache_locks: Optional[defaultdict[str, asyncio.Lock]] = None
+ self.cache: Cache | None = None
+ self.cache_locks: defaultdict[str, asyncio.Lock] | None = None
# Initialize cache if not disabled
if not disable_cache:
@@ -68,34 +79,24 @@ class AntaDevice(ABC):
@property
@abstractmethod
def _keys(self) -> tuple[Any, ...]:
- """
- Read-only property to implement hashing and equality for AntaDevice classes.
- """
+ """Read-only property to implement hashing and equality for AntaDevice classes."""
def __eq__(self, other: object) -> bool:
- """
- Implement equality for AntaDevice objects.
- """
+ """Implement equality for AntaDevice objects."""
return self._keys == other._keys if isinstance(other, self.__class__) else False
def __hash__(self) -> int:
- """
- Implement hashing for AntaDevice objects.
- """
+ """Implement hashing for AntaDevice objects."""
return hash(self._keys)
def _init_cache(self) -> None:
- """
- Initialize cache for the device, can be overriden by subclasses to manipulate how it works
- """
+ """Initialize cache for the device, can be overridden by subclasses to manipulate how it works."""
self.cache = Cache(cache_class=Cache.MEMORY, ttl=60, namespace=self.name, plugins=[HitMissRatioPlugin()])
self.cache_locks = defaultdict(asyncio.Lock)
@property
def cache_statistics(self) -> dict[str, Any] | None:
- """
- Returns the device cache statistics for logging purposes
- """
+ """Returns the device cache statistics for logging purposes."""
# Need to ignore pylint no-member as Cache is a proxy class and pylint is not smart enough
# https://github.com/pylint-dev/pylint/issues/7258
if self.cache is not None:
@@ -104,9 +105,9 @@ class AntaDevice(ABC):
return None
def __rich_repr__(self) -> Iterator[tuple[str, Any]]:
- """
- Implements Rich Repr Protocol
- https://rich.readthedocs.io/en/stable/pretty.html#rich-repr-protocol
+ """Implement Rich Repr Protocol.
+
+ https://rich.readthedocs.io/en/stable/pretty.html#rich-repr-protocol.
"""
yield "name", self.name
yield "tags", self.tags
@@ -116,9 +117,9 @@ class AntaDevice(ABC):
yield "disable_cache", self.cache is None
@abstractmethod
- async def _collect(self, command: AntaCommand) -> None:
- """
- Collect device command output.
+ async def _collect(self, command: AntaCommand, *, collection_id: str | None = None) -> None:
+ """Collect device command output.
+
This abstract coroutine can be used to implement any command collection method
for a device in ANTA.
@@ -130,12 +131,13 @@ class AntaDevice(ABC):
`AntaCommand` object passed as argument would be `None` in this case.
Args:
- command: the command to collect
+ ----
+ command: The command to collect.
+ collection_id: An identifier used to build the eAPI request ID.
"""
- async def collect(self, command: AntaCommand) -> None:
- """
- Collects the output for a specified command.
+ async def collect(self, command: AntaCommand, *, collection_id: str | None = None) -> None:
+ """Collect the output for a specified command.
When caching is activated on both the device and the command,
this method prioritizes retrieving the output from the cache. In cases where the output isn't cached yet,
@@ -146,7 +148,9 @@ class AntaDevice(ABC):
via the private `_collect` method without interacting with the cache.
Args:
- command (AntaCommand): The command to process.
+ ----
+ command: The command to collect.
+ collection_id: An identifier used to build the eAPI request ID.
"""
# Need to ignore pylint no-member as Cache is a proxy class and pylint is not smart enough
# https://github.com/pylint-dev/pylint/issues/7258
@@ -155,35 +159,27 @@ class AntaDevice(ABC):
cached_output = await self.cache.get(command.uid) # pylint: disable=no-member
if cached_output is not None:
- logger.debug(f"Cache hit for {command.command} on {self.name}")
+ logger.debug("Cache hit for %s on %s", command.command, self.name)
command.output = cached_output
else:
- await self._collect(command=command)
+ await self._collect(command=command, collection_id=collection_id)
await self.cache.set(command.uid, command.output) # pylint: disable=no-member
else:
- await self._collect(command=command)
+ await self._collect(command=command, collection_id=collection_id)
- async def collect_commands(self, commands: list[AntaCommand]) -> None:
- """
- Collect multiple commands.
+ async def collect_commands(self, commands: list[AntaCommand], *, collection_id: str | None = None) -> None:
+ """Collect multiple commands.
Args:
- commands: the commands to collect
+ ----
+ commands: The commands to collect.
+ collection_id: An identifier used to build the eAPI request ID.
"""
- await asyncio.gather(*(self.collect(command=command) for command in commands))
-
- def supports(self, command: AntaCommand) -> bool:
- """Returns True if the command is supported on the device hardware platform, False otherwise."""
- unsupported = any("not supported on this hardware platform" in e for e in command.errors)
- logger.debug(command)
- if unsupported:
- logger.debug(f"{command.command} is not supported on {self.hw_model}")
- return not unsupported
+ await asyncio.gather(*(self.collect(command=command, collection_id=collection_id) for command in commands))
@abstractmethod
async def refresh(self) -> None:
- """
- Update attributes of an AntaDevice instance.
+ """Update attributes of an AntaDevice instance.
This coroutine must update the following attributes of AntaDevice:
- `is_online`: When the device IP is reachable and a port can be open
@@ -192,63 +188,71 @@ class AntaDevice(ABC):
"""
async def copy(self, sources: list[Path], destination: Path, direction: Literal["to", "from"] = "from") -> None:
- """
- Copy files to and from the device, usually through SCP.
+ """Copy files to and from the device, usually through SCP.
+
It is not mandatory to implement this for a valid AntaDevice subclass.
Args:
+ ----
sources: List of files to copy to or from the device.
destination: Local or remote destination when copying the files. Can be a folder.
direction: Defines if this coroutine copies files to or from the device.
+
"""
- raise NotImplementedError(f"copy() method has not been implemented in {self.__class__.__name__} definition")
+ _ = (sources, destination, direction)
+ msg = f"copy() method has not been implemented in {self.__class__.__name__} definition"
+ raise NotImplementedError(msg)
class AsyncEOSDevice(AntaDevice):
- """
- Implementation of AntaDevice for EOS using aio-eapi.
+ """Implementation of AntaDevice for EOS using aio-eapi.
- Attributes:
+ Attributes
+ ----------
name: Device name
is_online: True if the device IP is reachable and a port can be open
established: True if remote command execution succeeds
hw_model: Hardware model of the device
- tags: List of tags for this device
+ tags: Tags for this device
+
"""
- def __init__( # pylint: disable=R0913
+ # pylint: disable=R0913
+ def __init__(
self,
host: str,
username: str,
password: str,
- name: Optional[str] = None,
+ name: str | None = None,
+ enable_password: str | None = None,
+ port: int | None = None,
+ ssh_port: int | None = 22,
+ tags: set[str] | None = None,
+ timeout: float | None = None,
+ proto: Literal["http", "https"] = "https",
+ *,
enable: bool = False,
- enable_password: Optional[str] = None,
- port: Optional[int] = None,
- ssh_port: Optional[int] = 22,
- tags: Optional[list[str]] = None,
- timeout: Optional[float] = None,
insecure: bool = False,
- proto: Literal["http", "https"] = "https",
disable_cache: bool = False,
) -> None:
- """
- Constructor of AsyncEOSDevice
+ """Instantiate an AsyncEOSDevice.
Args:
- host: Device FQDN or IP
- username: Username to connect to eAPI and SSH
- password: Password to connect to eAPI and SSH
- name: Device name
- enable: Device needs privileged access
- enable_password: Password used to gain privileged access on EOS
+ ----
+ host: Device FQDN or IP.
+ username: Username to connect to eAPI and SSH.
+ password: Password to connect to eAPI and SSH.
+ name: Device name.
+ enable: Collect commands using privileged mode.
+ enable_password: Password used to gain privileged access on EOS.
port: eAPI port. Defaults to 80 is proto is 'http' or 443 if proto is 'https'.
- ssh_port: SSH port
- tags: List of tags for this device
- timeout: Timeout value in seconds for outgoing connections. Default to 10 secs.
- insecure: Disable SSH Host Key validation
- proto: eAPI protocol. Value can be 'http' or 'https'
- disable_cache: Disable caching for all commands for this device. Defaults to False.
+ ssh_port: SSH port.
+ tags: Tags for this device.
+ timeout: Timeout value in seconds for outgoing API calls.
+ insecure: Disable SSH Host Key validation.
+ proto: eAPI protocol. Value can be 'http' or 'https'.
+ disable_cache: Disable caching for all commands for this device.
+
"""
if host is None:
message = "'host' is required to create an AsyncEOSDevice"
@@ -256,7 +260,7 @@ class AsyncEOSDevice(AntaDevice):
raise ValueError(message)
if name is None:
name = f"{host}{f':{port}' if port else ''}"
- super().__init__(name, tags, disable_cache)
+ super().__init__(name, tags, disable_cache=disable_cache)
if username is None:
message = f"'username' is required to instantiate device '{self.name}'"
logger.error(message)
@@ -267,16 +271,18 @@ class AsyncEOSDevice(AntaDevice):
raise ValueError(message)
self.enable = enable
self._enable_password = enable_password
- self._session: aioeapi.Device = aioeapi.Device(host=host, port=port, username=username, password=password, proto=proto, timeout=timeout)
+ self._session: asynceapi.Device = asynceapi.Device(host=host, port=port, username=username, password=password, proto=proto, timeout=timeout)
ssh_params: dict[str, Any] = {}
if insecure:
ssh_params["known_hosts"] = None
- self._ssh_opts: SSHClientConnectionOptions = SSHClientConnectionOptions(host=host, port=ssh_port, username=username, password=password, **ssh_params)
+ self._ssh_opts: SSHClientConnectionOptions = SSHClientConnectionOptions(
+ host=host, port=ssh_port, username=username, password=password, client_keys=CLIENT_KEYS, **ssh_params
+ )
def __rich_repr__(self) -> Iterator[tuple[str, Any]]:
- """
- Implements Rich Repr Protocol
- https://rich.readthedocs.io/en/stable/pretty.html#rich-repr-protocol
+ """Implement Rich Repr Protocol.
+
+ https://rich.readthedocs.io/en/stable/pretty.html#rich-repr-protocol.
"""
yield from super().__rich_repr__()
yield ("host", self._session.host)
@@ -286,107 +292,125 @@ class AsyncEOSDevice(AntaDevice):
yield ("insecure", self._ssh_opts.known_hosts is None)
if __DEBUG__:
_ssh_opts = vars(self._ssh_opts).copy()
- PASSWORD_VALUE = "<removed>"
- _ssh_opts["password"] = PASSWORD_VALUE
- _ssh_opts["kwargs"]["password"] = PASSWORD_VALUE
+ removed_pw = "<removed>"
+ _ssh_opts["password"] = removed_pw
+ _ssh_opts["kwargs"]["password"] = removed_pw
yield ("_session", vars(self._session))
yield ("_ssh_opts", _ssh_opts)
@property
def _keys(self) -> tuple[Any, ...]:
- """
- Two AsyncEOSDevice objects are equal if the hostname and the port are the same.
+ """Two AsyncEOSDevice objects are equal if the hostname and the port are the same.
+
This covers the use case of port forwarding when the host is localhost and the devices have different ports.
"""
return (self._session.host, self._session.port)
- async def _collect(self, command: AntaCommand) -> None:
- """
- Collect device command output from EOS using aio-eapi.
+ async def _collect(self, command: AntaCommand, *, collection_id: str | None = None) -> None: # noqa: C901 function is too complex - because of many required except blocks #pylint: disable=line-too-long
+ """Collect device command output from EOS using aio-eapi.
Supports outformat `json` and `text` as output structure.
Gain privileged access using the `enable_password` attribute
of the `AntaDevice` instance if populated.
Args:
- command: the command to collect
+ ----
+ command: The command to collect.
+ collection_id: An identifier used to build the eAPI request ID.
"""
- commands = []
+ commands: list[dict[str, str | int]] = []
if self.enable and self._enable_password is not None:
commands.append(
{
"cmd": "enable",
"input": str(self._enable_password),
- }
+ },
)
elif self.enable:
# No password
commands.append({"cmd": "enable"})
- if command.revision:
- commands.append({"cmd": command.command, "revision": command.revision})
- else:
- commands.append({"cmd": command.command})
+ commands += [{"cmd": command.command, "revision": command.revision}] if command.revision else [{"cmd": command.command}]
try:
- response: list[dict[str, Any]] = await self._session.cli(
+ response: list[dict[str, Any] | str] = await self._session.cli(
commands=commands,
ofmt=command.ofmt,
version=command.version,
- )
- except aioeapi.EapiCommandError as e:
- command.errors = e.errors
- if self.supports(command):
- message = f"Command '{command.command}' failed on {self.name}"
- logger.error(message)
- except (HTTPError, ConnectError) as e:
- command.errors = [str(e)]
- message = f"Cannot connect to device {self.name}"
- logger.error(message)
- else:
- # selecting only our command output
+ req_id=f"ANTA-{collection_id}-{id(command)}" if collection_id else f"ANTA-{id(command)}",
+ ) # type: ignore[assignment] # multiple commands returns a list
+ # Do not keep response of 'enable' command
command.output = response[-1]
- logger.debug(f"{self.name}: {command}")
+ except asynceapi.EapiCommandError as e:
+ # This block catches exceptions related to EOS issuing an error.
+ command.errors = e.errors
+ if command.requires_privileges:
+ logger.error(
+ "Command '%s' requires privileged mode on %s. Verify user permissions and if the `enable` option is required.", command.command, self.name
+ )
+ if command.supported:
+ logger.error("Command '%s' failed on %s: %s", command.command, self.name, e.errors[0] if len(e.errors) == 1 else e.errors)
+ else:
+ logger.debug("Command '%s' is not supported on '%s' (%s)", command.command, self.name, self.hw_model)
+ except TimeoutException as e:
+ # This block catches Timeout exceptions.
+ command.errors = [exc_to_str(e)]
+ timeouts = self._session.timeout.as_dict()
+ logger.error(
+ "%s occurred while sending a command to %s. Consider increasing the timeout.\nCurrent timeouts: Connect: %s | Read: %s | Write: %s | Pool: %s",
+ exc_to_str(e),
+ self.name,
+ timeouts["connect"],
+ timeouts["read"],
+ timeouts["write"],
+ timeouts["pool"],
+ )
+ except (ConnectError, OSError) as e:
+ # This block catches OSError and socket issues related exceptions.
+ command.errors = [exc_to_str(e)]
+ if (isinstance(exc := e.__cause__, httpcore.ConnectError) and isinstance(os_error := exc.__context__, OSError)) or isinstance(os_error := e, OSError): # pylint: disable=no-member
+ if isinstance(os_error.__cause__, OSError):
+ os_error = os_error.__cause__
+ logger.error("A local OS error occurred while connecting to %s: %s.", self.name, os_error)
+ else:
+ anta_log_exception(e, f"An error occurred while issuing an eAPI request to {self.name}", logger)
+ except HTTPError as e:
+ # This block catches most of the httpx Exceptions and logs a general message.
+ command.errors = [exc_to_str(e)]
+ anta_log_exception(e, f"An error occurred while issuing an eAPI request to {self.name}", logger)
+ logger.debug("%s: %s", self.name, command)
async def refresh(self) -> None:
- """
- Update attributes of an AsyncEOSDevice instance.
+ """Update attributes of an AsyncEOSDevice instance.
This coroutine must update the following attributes of AsyncEOSDevice:
- is_online: When a device IP is reachable and a port can be open
- established: When a command execution succeeds
- hw_model: The hardware model of the device
"""
- logger.debug(f"Refreshing device {self.name}")
+ logger.debug("Refreshing device %s", self.name)
self.is_online = await self._session.check_connection()
if self.is_online:
- COMMAND: str = "show version"
- HW_MODEL_KEY: str = "modelName"
- try:
- response = await self._session.cli(command=COMMAND)
- except aioeapi.EapiCommandError as e:
- logger.warning(f"Cannot get hardware information from device {self.name}: {e.errmsg}")
-
- except (HTTPError, ConnectError) as e:
- logger.warning(f"Cannot get hardware information from device {self.name}: {exc_to_str(e)}")
-
+ show_version = AntaCommand(command="show version")
+ await self._collect(show_version)
+ if not show_version.collected:
+ logger.warning("Cannot get hardware information from device %s", self.name)
else:
- if HW_MODEL_KEY in response:
- self.hw_model = response[HW_MODEL_KEY]
- else:
- logger.warning(f"Cannot get hardware information from device {self.name}: cannot parse '{COMMAND}'")
-
+ self.hw_model = show_version.json_output.get("modelName", None)
+ if self.hw_model is None:
+ logger.critical("Cannot parse 'show version' returned by device %s", self.name)
else:
- logger.warning(f"Could not connect to device {self.name}: cannot open eAPI port")
+ logger.warning("Could not connect to device %s: cannot open eAPI port", self.name)
self.established = bool(self.is_online and self.hw_model)
async def copy(self, sources: list[Path], destination: Path, direction: Literal["to", "from"] = "from") -> None:
- """
- Copy files to and from the device using asyncssh.scp().
+ """Copy files to and from the device using asyncssh.scp().
Args:
+ ----
sources: List of files to copy to or from the device.
destination: Local or remote destination when copying the files. Can be a folder.
direction: Defines if this coroutine copies files to or from the device.
+
"""
async with asyncssh.connect(
host=self._ssh_opts.host,
@@ -396,22 +420,24 @@ class AsyncEOSDevice(AntaDevice):
local_addr=self._ssh_opts.local_addr,
options=self._ssh_opts,
) as conn:
- src: Union[list[tuple[SSHClientConnection, Path]], list[Path]]
- dst: Union[tuple[SSHClientConnection, Path], Path]
+ src: list[tuple[SSHClientConnection, Path]] | list[Path]
+ dst: tuple[SSHClientConnection, Path] | Path
if direction == "from":
src = [(conn, file) for file in sources]
dst = destination
for file in sources:
- logger.info(f"Copying '{file}' from device {self.name} to '{destination}' locally")
+ message = f"Copying '{file}' from device {self.name} to '{destination}' locally"
+ logger.info(message)
elif direction == "to":
src = sources
dst = conn, destination
for file in src:
- logger.info(f"Copying '{file}' to device {self.name} to '{destination}' remotely")
+ message = f"Copying '{file}' to device {self.name} to '{destination}' remotely"
+ logger.info(message)
else:
- logger.critical(f"'direction' argument to copy() fonction is invalid: {direction}")
+ logger.critical("'direction' argument to copy() function is invalid: %s", direction)
return
await asyncssh.scp(src, dst)
diff --git a/anta/inventory/__init__.py b/anta/inventory/__init__.py
index c5327bd..5e66d84 100644
--- a/anta/inventory/__init__.py
+++ b/anta/inventory/__init__.py
@@ -1,9 +1,7 @@
# Copyright (c) 2023-2024 Arista Networks, Inc.
# Use of this source code is governed by the Apache License 2.0
# that can be found in the LICENSE file.
-"""
-Inventory Module for ANTA.
-"""
+"""Inventory module for ANTA."""
from __future__ import annotations
@@ -11,32 +9,29 @@ import asyncio
import logging
from ipaddress import ip_address, ip_network
from pathlib import Path
-from typing import Any, Optional
+from typing import Any, ClassVar
from pydantic import ValidationError
from yaml import YAMLError, safe_load
from anta.device import AntaDevice, AsyncEOSDevice
-from anta.inventory.exceptions import InventoryIncorrectSchema, InventoryRootKeyError
+from anta.inventory.exceptions import InventoryIncorrectSchemaError, InventoryRootKeyError
from anta.inventory.models import AntaInventoryInput
from anta.logger import anta_log_exception
logger = logging.getLogger(__name__)
-class AntaInventory(dict): # type: ignore
- # dict[str, AntaDevice] - not working in python 3.8 hence the ignore
- """
- Inventory abstraction for ANTA framework.
- """
+class AntaInventory(dict[str, AntaDevice]):
+ """Inventory abstraction for ANTA framework."""
# Root key of inventory part of the inventory file
INVENTORY_ROOT_KEY = "anta_inventory"
# Supported Output format
- INVENTORY_OUTPUT_FORMAT = ["native", "json"]
+ INVENTORY_OUTPUT_FORMAT: ClassVar[list[str]] = ["native", "json"]
def __str__(self) -> str:
- """Human readable string representing the inventory"""
+ """Human readable string representing the inventory."""
devs = {}
for dev in self.values():
if (dev_type := dev.__class__.__name__) not in devs:
@@ -46,80 +41,106 @@ class AntaInventory(dict): # type: ignore
return f"ANTA Inventory contains {' '.join([f'{n} devices ({t})' for t, n in devs.items()])}"
@staticmethod
- def _update_disable_cache(inventory_disable_cache: bool, kwargs: dict[str, Any]) -> dict[str, Any]:
- """
- Return new dictionary, replacing kwargs with added disable_cache value from inventory_value
- if disable_cache has not been set by CLI.
+ def _update_disable_cache(kwargs: dict[str, Any], *, inventory_disable_cache: bool) -> dict[str, Any]:
+ """Return new dictionary, replacing kwargs with added disable_cache value from inventory_value if disable_cache has not been set by CLI.
Args:
- inventory_disable_cache (bool): The value of disable_cache in the inventory
+ ----
+ inventory_disable_cache: The value of disable_cache in the inventory
kwargs: The kwargs to instantiate the device
+
"""
updated_kwargs = kwargs.copy()
updated_kwargs["disable_cache"] = inventory_disable_cache or kwargs.get("disable_cache")
return updated_kwargs
@staticmethod
- def _parse_hosts(inventory_input: AntaInventoryInput, inventory: AntaInventory, **kwargs: Any) -> None:
- """
- Parses the host section of an AntaInventoryInput and add the devices to the inventory
+ def _parse_hosts(
+ inventory_input: AntaInventoryInput,
+ inventory: AntaInventory,
+ **kwargs: dict[str, Any],
+ ) -> None:
+ """Parse the host section of an AntaInventoryInput and add the devices to the inventory.
Args:
- inventory_input (AntaInventoryInput): AntaInventoryInput used to parse the devices
- inventory (AntaInventory): AntaInventory to add the parsed devices to
+ ----
+ inventory_input: AntaInventoryInput used to parse the devices
+ inventory: AntaInventory to add the parsed devices to
+ **kwargs: Additional keyword arguments to pass to the device constructor
+
"""
if inventory_input.hosts is None:
return
for host in inventory_input.hosts:
- updated_kwargs = AntaInventory._update_disable_cache(host.disable_cache, kwargs)
- device = AsyncEOSDevice(name=host.name, host=str(host.host), port=host.port, tags=host.tags, **updated_kwargs)
+ updated_kwargs = AntaInventory._update_disable_cache(kwargs, inventory_disable_cache=host.disable_cache)
+ device = AsyncEOSDevice(
+ name=host.name,
+ host=str(host.host),
+ port=host.port,
+ tags=host.tags,
+ **updated_kwargs,
+ )
inventory.add_device(device)
@staticmethod
- def _parse_networks(inventory_input: AntaInventoryInput, inventory: AntaInventory, **kwargs: Any) -> None:
- """
- Parses the network section of an AntaInventoryInput and add the devices to the inventory.
+ def _parse_networks(
+ inventory_input: AntaInventoryInput,
+ inventory: AntaInventory,
+ **kwargs: dict[str, Any],
+ ) -> None:
+ """Parse the network section of an AntaInventoryInput and add the devices to the inventory.
Args:
- inventory_input (AntaInventoryInput): AntaInventoryInput used to parse the devices
- inventory (AntaInventory): AntaInventory to add the parsed devices to
+ ----
+ inventory_input: AntaInventoryInput used to parse the devices
+ inventory: AntaInventory to add the parsed devices to
+ **kwargs: Additional keyword arguments to pass to the device constructor
+
+ Raises
+ ------
+ InventoryIncorrectSchemaError: Inventory file is not following AntaInventory Schema.
- Raises:
- InventoryIncorrectSchema: Inventory file is not following AntaInventory Schema.
"""
if inventory_input.networks is None:
return
- for network in inventory_input.networks:
- try:
- updated_kwargs = AntaInventory._update_disable_cache(network.disable_cache, kwargs)
+ try:
+ for network in inventory_input.networks:
+ updated_kwargs = AntaInventory._update_disable_cache(kwargs, inventory_disable_cache=network.disable_cache)
for host_ip in ip_network(str(network.network)):
device = AsyncEOSDevice(host=str(host_ip), tags=network.tags, **updated_kwargs)
inventory.add_device(device)
- except ValueError as e:
- message = "Could not parse network {network.network} in the inventory"
- anta_log_exception(e, message, logger)
- raise InventoryIncorrectSchema(message) from e
+ except ValueError as e:
+ message = "Could not parse the network section in the inventory"
+ anta_log_exception(e, message, logger)
+ raise InventoryIncorrectSchemaError(message) from e
@staticmethod
- def _parse_ranges(inventory_input: AntaInventoryInput, inventory: AntaInventory, **kwargs: Any) -> None:
- """
- Parses the range section of an AntaInventoryInput and add the devices to the inventory.
+ def _parse_ranges(
+ inventory_input: AntaInventoryInput,
+ inventory: AntaInventory,
+ **kwargs: dict[str, Any],
+ ) -> None:
+ """Parse the range section of an AntaInventoryInput and add the devices to the inventory.
Args:
- inventory_input (AntaInventoryInput): AntaInventoryInput used to parse the devices
- inventory (AntaInventory): AntaInventory to add the parsed devices to
+ ----
+ inventory_input: AntaInventoryInput used to parse the devices
+ inventory: AntaInventory to add the parsed devices to
+ **kwargs: Additional keyword arguments to pass to the device constructor
+
+ Raises
+ ------
+ InventoryIncorrectSchemaError: Inventory file is not following AntaInventory Schema.
- Raises:
- InventoryIncorrectSchema: Inventory file is not following AntaInventory Schema.
"""
if inventory_input.ranges is None:
return
- for range_def in inventory_input.ranges:
- try:
- updated_kwargs = AntaInventory._update_disable_cache(range_def.disable_cache, kwargs)
+ try:
+ for range_def in inventory_input.ranges:
+ updated_kwargs = AntaInventory._update_disable_cache(kwargs, inventory_disable_cache=range_def.disable_cache)
range_increment = ip_address(str(range_def.start))
range_stop = ip_address(str(range_def.end))
while range_increment <= range_stop: # type: ignore[operator]
@@ -128,46 +149,49 @@ class AntaInventory(dict): # type: ignore
device = AsyncEOSDevice(host=str(range_increment), tags=range_def.tags, **updated_kwargs)
inventory.add_device(device)
range_increment += 1
- except ValueError as e:
- message = f"Could not parse the following range in the inventory: {range_def.start} - {range_def.end}"
- anta_log_exception(e, message, logger)
- raise InventoryIncorrectSchema(message) from e
- except TypeError as e:
- message = f"A range in the inventory has different address families for start and end: {range_def.start} - {range_def.end}"
- anta_log_exception(e, message, logger)
- raise InventoryIncorrectSchema(message) from e
+ except ValueError as e:
+ message = "Could not parse the range section in the inventory"
+ anta_log_exception(e, message, logger)
+ raise InventoryIncorrectSchemaError(message) from e
+ except TypeError as e:
+ message = "A range in the inventory has different address families (IPv4 vs IPv6)"
+ anta_log_exception(e, message, logger)
+ raise InventoryIncorrectSchemaError(message) from e
+ # pylint: disable=too-many-arguments
@staticmethod
def parse(
filename: str | Path,
username: str,
password: str,
+ enable_password: str | None = None,
+ timeout: float | None = None,
+ *,
enable: bool = False,
- enable_password: Optional[str] = None,
- timeout: Optional[float] = None,
insecure: bool = False,
disable_cache: bool = False,
) -> AntaInventory:
- # pylint: disable=too-many-arguments
- """
- Create an AntaInventory instance from an inventory file.
+ """Create an AntaInventory instance from an inventory file.
+
The inventory devices are AsyncEOSDevice instances.
Args:
- filename (str): Path to device inventory YAML file
- username (str): Username to use to connect to devices
- password (str): Password to use to connect to devices
- enable (bool): Whether or not the commands need to be run in enable mode towards the devices
- enable_password (str, optional): Enable password to use if required
- timeout (float, optional): timeout in seconds for every API call.
- insecure (bool): Disable SSH Host Key validation
- disable_cache (bool): Disable cache globally
-
- Raises:
+ ----
+ filename: Path to device inventory YAML file.
+ username: Username to use to connect to devices.
+ password: Password to use to connect to devices.
+ enable_password: Enable password to use if required.
+ timeout: Timeout value in seconds for outgoing API calls.
+ enable: Whether or not the commands need to be run in enable mode towards the devices.
+ insecure: Disable SSH Host Key validation.
+ disable_cache: Disable cache globally.
+
+ Raises
+ ------
InventoryRootKeyError: Root key of inventory is missing.
- InventoryIncorrectSchema: Inventory file is not following AntaInventory Schema.
- """
+ InventoryIncorrectSchemaError: Inventory file is not following AntaInventory Schema.
+ """
inventory = AntaInventory()
kwargs: dict[str, Any] = {
"username": username,
@@ -188,7 +212,8 @@ class AntaInventory(dict): # type: ignore
raise ValueError(message)
try:
- with open(file=filename, mode="r", encoding="UTF-8") as file:
+ filename = Path(filename)
+ with filename.open(encoding="UTF-8") as file:
data = safe_load(file)
except (TypeError, YAMLError, OSError) as e:
message = f"Unable to parse ANTA Device Inventory file '{filename}'"
@@ -213,6 +238,11 @@ class AntaInventory(dict): # type: ignore
return inventory
+ @property
+ def devices(self) -> list[AntaDevice]:
+ """List of AntaDevice in this inventory."""
+ return list(self.values())
+
###########################################################################
# Public methods
###########################################################################
@@ -221,30 +251,31 @@ class AntaInventory(dict): # type: ignore
# GET methods
###########################################################################
- def get_inventory(self, established_only: bool = False, tags: Optional[list[str]] = None) -> AntaInventory:
- """
- Returns a filtered inventory.
+ def get_inventory(self, *, established_only: bool = False, tags: set[str] | None = None, devices: set[str] | None = None) -> AntaInventory:
+ """Return a filtered inventory.
Args:
- established_only: Whether or not to include only established devices. Default False.
- tags: List of tags to filter devices.
-
- Returns:
- AntaInventory: An inventory with filtered AntaDevice objects.
+ ----
+ established_only: Whether or not to include only established devices.
+ tags: Tags to filter devices.
+ devices: Names to filter devices.
+
+ Returns
+ -------
+ An inventory with filtered AntaDevice objects.
"""
def _filter_devices(device: AntaDevice) -> bool:
- """
- Helper function to select the devices based on the input tags
- and the requirement for an established connection.
- """
+ """Select the devices based on the inputs `tags`, `devices` and `established_only`."""
if tags is not None and all(tag not in tags for tag in device.tags):
return False
- return bool(not established_only or device.established)
+ if devices is None or device.name in devices:
+ return bool(not established_only or device.established)
+ return False
- devices: list[AntaDevice] = list(filter(_filter_devices, self.values()))
+ filtered_devices: list[AntaDevice] = list(filter(_filter_devices, self.values()))
result = AntaInventory()
- for device in devices:
+ for device in filtered_devices:
result.add_device(device)
return result
@@ -253,15 +284,19 @@ class AntaInventory(dict): # type: ignore
###########################################################################
def __setitem__(self, key: str, value: AntaDevice) -> None:
+ """Set a device in the inventory."""
if key != value.name:
- raise RuntimeError(f"The key must be the device name for device '{value.name}'. Use AntaInventory.add_device().")
+ msg = f"The key must be the device name for device '{value.name}'. Use AntaInventory.add_device()."
+ raise RuntimeError(msg)
return super().__setitem__(key, value)
def add_device(self, device: AntaDevice) -> None:
"""Add a device to final inventory.
Args:
+ ----
device: Device object to be added
+
"""
self[device.name] = device
diff --git a/anta/inventory/exceptions.py b/anta/inventory/exceptions.py
index dd5f106..90a672f 100644
--- a/anta/inventory/exceptions.py
+++ b/anta/inventory/exceptions.py
@@ -8,5 +8,5 @@ class InventoryRootKeyError(Exception):
"""Error raised when inventory root key is not found."""
-class InventoryIncorrectSchema(Exception):
+class InventoryIncorrectSchemaError(Exception):
"""Error when user data does not follow ANTA schema."""
diff --git a/anta/inventory/models.py b/anta/inventory/models.py
index 94742e4..e26ea00 100644
--- a/anta/inventory/models.py
+++ b/anta/inventory/models.py
@@ -6,87 +6,79 @@
from __future__ import annotations
import logging
-from typing import List, Optional, Union
-# Need to keep List for pydantic in python 3.8
-from pydantic import BaseModel, ConfigDict, IPvAnyAddress, IPvAnyNetwork, conint, constr
+from pydantic import BaseModel, ConfigDict, IPvAnyAddress, IPvAnyNetwork
+
+from anta.custom_types import Hostname, Port
logger = logging.getLogger(__name__)
-# Pydantic models for input validation
-RFC_1123_REGEX = r"^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\-]*[A-Za-z0-9])$"
+class AntaInventoryHost(BaseModel):
+ """Host entry of AntaInventoryInput.
+ Attributes
+ ----------
+ host: IP Address or FQDN of the device.
+ port: Custom eAPI port to use.
+ name: Custom name of the device.
+ tags: Tags of the device.
+ disable_cache: Disable cache for this device.
-class AntaInventoryHost(BaseModel):
- """
- Host definition for user's inventory.
-
- Attributes:
- host (IPvAnyAddress): IPv4 or IPv6 address of the device
- port (int): (Optional) eAPI port to use Default is 443.
- name (str): (Optional) Name to display during tests report. Default is hostname:port
- tags (list[str]): List of attached tags read from inventory file.
- disable_cache (bool): Disable cache per host. Defaults to False.
"""
model_config = ConfigDict(extra="forbid")
- name: Optional[str] = None
- host: Union[constr(pattern=RFC_1123_REGEX), IPvAnyAddress] # type: ignore
- port: Optional[conint(gt=1, lt=65535)] = None # type: ignore
- tags: Optional[List[str]] = None
+ name: str | None = None
+ host: Hostname | IPvAnyAddress
+ port: Port | None = None
+ tags: set[str] | None = None
disable_cache: bool = False
class AntaInventoryNetwork(BaseModel):
- """
- Network definition for user's inventory.
+ """Network entry of AntaInventoryInput.
+
+ Attributes
+ ----------
+ network: Subnet to use for scanning.
+ tags: Tags of the devices in this network.
+ disable_cache: Disable cache for all devices in this network.
- Attributes:
- network (IPvAnyNetwork): Subnet to use for testing.
- tags (list[str]): List of attached tags read from inventory file.
- disable_cache (bool): Disable cache per network. Defaults to False.
"""
model_config = ConfigDict(extra="forbid")
network: IPvAnyNetwork
- tags: Optional[List[str]] = None
+ tags: set[str] | None = None
disable_cache: bool = False
class AntaInventoryRange(BaseModel):
- """
- IP Range definition for user's inventory.
+ """IP Range entry of AntaInventoryInput.
+
+ Attributes
+ ----------
+ start: IPv4 or IPv6 address for the beginning of the range.
+ stop: IPv4 or IPv6 address for the end of the range.
+ tags: Tags of the devices in this IP range.
+ disable_cache: Disable cache for all devices in this IP range.
- Attributes:
- start (IPvAnyAddress): IPv4 or IPv6 address for the begining of the range.
- stop (IPvAnyAddress): IPv4 or IPv6 address for the end of the range.
- tags (list[str]): List of attached tags read from inventory file.
- disable_cache (bool): Disable cache per range of hosts. Defaults to False.
"""
model_config = ConfigDict(extra="forbid")
start: IPvAnyAddress
end: IPvAnyAddress
- tags: Optional[List[str]] = None
+ tags: set[str] | None = None
disable_cache: bool = False
class AntaInventoryInput(BaseModel):
- """
- User's inventory model.
-
- Attributes:
- networks (list[AntaInventoryNetwork],Optional): List of AntaInventoryNetwork objects for networks.
- hosts (list[AntaInventoryHost],Optional): List of AntaInventoryHost objects for hosts.
- range (list[AntaInventoryRange],Optional): List of AntaInventoryRange objects for ranges.
- """
+ """Device inventory input model."""
model_config = ConfigDict(extra="forbid")
- networks: Optional[List[AntaInventoryNetwork]] = None
- hosts: Optional[List[AntaInventoryHost]] = None
- ranges: Optional[List[AntaInventoryRange]] = None
+ networks: list[AntaInventoryNetwork] | None = None
+ hosts: list[AntaInventoryHost] | None = None
+ ranges: list[AntaInventoryRange] | None = None
diff --git a/anta/logger.py b/anta/logger.py
index d5eeeca..e532ace 100644
--- a/anta/logger.py
+++ b/anta/logger.py
@@ -1,26 +1,28 @@
# Copyright (c) 2023-2024 Arista Networks, Inc.
# Use of this source code is governed by the Apache License 2.0
# that can be found in the LICENSE file.
-"""
-Configure logging for ANTA
-"""
+"""Configure logging for ANTA."""
+
from __future__ import annotations
import logging
+import traceback
+from datetime import timedelta
from enum import Enum
-from pathlib import Path
-from typing import Literal, Optional
+from typing import TYPE_CHECKING, Literal
from rich.logging import RichHandler
from anta import __DEBUG__
-from anta.tools.misc import exc_to_str
+
+if TYPE_CHECKING:
+ from pathlib import Path
logger = logging.getLogger(__name__)
class Log(str, Enum):
- """Represent log levels from logging module as immutable strings"""
+ """Represent log levels from logging module as immutable strings."""
CRITICAL = logging.getLevelName(logging.CRITICAL)
ERROR = logging.getLevelName(logging.ERROR)
@@ -33,8 +35,8 @@ LogLevel = Literal[Log.CRITICAL, Log.ERROR, Log.WARNING, Log.INFO, Log.DEBUG]
def setup_logging(level: LogLevel = Log.INFO, file: Path | None = None) -> None:
- """
- Configure logging for ANTA.
+ """Configure logging for ANTA.
+
By default, the logging level is INFO for all loggers except for httpx and asyncssh which are too verbose:
their logging level is WARNING.
@@ -48,12 +50,14 @@ def setup_logging(level: LogLevel = Log.INFO, file: Path | None = None) -> None:
be logged to stdout while all levels will be logged in the file.
Args:
+ ----
level: ANTA logging level
file: Send logs to a file
+
"""
# Init root logger
root = logging.getLogger()
- # In ANTA debug mode, level is overriden to DEBUG
+ # In ANTA debug mode, level is overridden to DEBUG
loglevel = logging.DEBUG if __DEBUG__ else getattr(logging, level.upper())
root.setLevel(loglevel)
# Silence the logging of chatty Python modules when level is INFO
@@ -64,44 +68,57 @@ def setup_logging(level: LogLevel = Log.INFO, file: Path | None = None) -> None:
logging.getLogger("httpx").setLevel(logging.WARNING)
# Add RichHandler for stdout
- richHandler = RichHandler(markup=True, rich_tracebacks=True, tracebacks_show_locals=False)
- # In ANTA debug mode, show Python module in stdout
- if __DEBUG__:
- fmt_string = r"[grey58]\[%(name)s][/grey58] %(message)s"
- else:
- fmt_string = "%(message)s"
+ rich_handler = RichHandler(markup=True, rich_tracebacks=True, tracebacks_show_locals=False)
+ # Show Python module in stdout at DEBUG level
+ fmt_string = "[grey58]\\[%(name)s][/grey58] %(message)s" if loglevel == logging.DEBUG else "%(message)s"
formatter = logging.Formatter(fmt=fmt_string, datefmt="[%X]")
- richHandler.setFormatter(formatter)
- root.addHandler(richHandler)
+ rich_handler.setFormatter(formatter)
+ root.addHandler(rich_handler)
# Add FileHandler if file is provided
if file:
- fileHandler = logging.FileHandler(file)
+ file_handler = logging.FileHandler(file)
formatter = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s")
- fileHandler.setFormatter(formatter)
- root.addHandler(fileHandler)
+ file_handler.setFormatter(formatter)
+ root.addHandler(file_handler)
# If level is DEBUG and file is provided, do not send DEBUG level to stdout
if loglevel == logging.DEBUG:
- richHandler.setLevel(logging.INFO)
+ rich_handler.setLevel(logging.INFO)
if __DEBUG__:
logger.debug("ANTA Debug Mode enabled")
-def anta_log_exception(exception: BaseException, message: Optional[str] = None, calling_logger: Optional[logging.Logger] = None) -> None:
- """
- Helper function to help log exceptions:
- * if anta.__DEBUG__ is True then the logger.exception method is called to get the traceback
- * otherwise logger.error is called
+def format_td(seconds: float, digits: int = 3) -> str:
+ """Return a formatted string from a float number representing seconds and a number of digits."""
+ isec, fsec = divmod(round(seconds * 10**digits), 10**digits)
+ return f"{timedelta(seconds=isec)}.{fsec:0{digits}.0f}"
+
+
+def exc_to_str(exception: BaseException) -> str:
+ """Return a human readable string from an BaseException object."""
+ return f"{type(exception).__name__}{f': {exception}' if str(exception) else ''}"
+
+
+def anta_log_exception(exception: BaseException, message: str | None = None, calling_logger: logging.Logger | None = None) -> None:
+ """Log exception.
+
+ If `anta.__DEBUG__` is True then the `logger.exception` method is called to get the traceback, otherwise `logger.error` is called.
Args:
- exception (BAseException): The Exception being logged
- message (str): An optional message
- calling_logger (logging.Logger): A logger to which the exception should be logged
- if not present, the logger in this file is used.
+ ----
+ exception: The Exception being logged.
+ message: An optional message.
+ calling_logger: A logger to which the exception should be logged. If not present, the logger in this file is used.
"""
if calling_logger is None:
calling_logger = logger
calling_logger.critical(f"{message}\n{exc_to_str(exception)}" if message else exc_to_str(exception))
if __DEBUG__:
- calling_logger.exception(f"[ANTA Debug Mode]{f' {message}' if message else ''}", exc_info=exception)
+ msg = f"[ANTA Debug Mode]{f' {message}' if message else ''}"
+ calling_logger.exception(msg, exc_info=exception)
+
+
+def tb_to_str(exception: BaseException) -> str:
+ """Return a traceback string from an BaseException object."""
+ return "Traceback (most recent call last):\n" + "".join(traceback.format_tb(exception.__traceback__))
diff --git a/anta/models.py b/anta/models.py
index c8acda3..c44f7e8 100644
--- a/anta/models.py
+++ b/anta/models.py
@@ -1,102 +1,128 @@
# Copyright (c) 2023-2024 Arista Networks, Inc.
# Use of this source code is governed by the Apache License 2.0
# that can be found in the LICENSE file.
-"""
-Models to define a TestStructure
-"""
+"""Models to define a TestStructure."""
+
from __future__ import annotations
import hashlib
import logging
import re
-import time
from abc import ABC, abstractmethod
-from copy import deepcopy
-from datetime import timedelta
from functools import wraps
+from string import Formatter
+from typing import TYPE_CHECKING, Any, Callable, ClassVar, Literal, TypeVar
-# Need to keep Dict and List for pydantic in python 3.8
-from typing import TYPE_CHECKING, Any, Callable, ClassVar, Coroutine, Dict, List, Literal, Optional, TypeVar, Union
-
-from pydantic import BaseModel, ConfigDict, ValidationError, conint
-from rich.progress import Progress, TaskID
+from pydantic import BaseModel, ConfigDict, ValidationError, create_model
from anta import GITHUB_SUGGESTION
-from anta.logger import anta_log_exception
+from anta.custom_types import REGEXP_EOS_BLACKLIST_CMDS, Revision
+from anta.logger import anta_log_exception, exc_to_str
from anta.result_manager.models import TestResult
-from anta.tools.misc import exc_to_str
if TYPE_CHECKING:
+ from collections.abc import Coroutine
+
+ from rich.progress import Progress, TaskID
+
from anta.device import AntaDevice
F = TypeVar("F", bound=Callable[..., Any])
# Proper way to type input class - revisit this later if we get any issue @gmuloc
# This would imply overhead to define classes
# https://stackoverflow.com/questions/74103528/type-hinting-an-instance-of-a-nested-class
-# N = TypeVar("N", bound="AntaTest.Input")
-
-
-# TODO - make this configurable - with an env var maybe?
-BLACKLIST_REGEX = [r"^reload.*", r"^conf\w*\s*(terminal|session)*", r"^wr\w*\s*\w+"]
logger = logging.getLogger(__name__)
-class AntaMissingParamException(Exception):
- """
- This Exception should be used when an expected key in an AntaCommand.params dictionary
- was not found.
+class AntaParamsBaseModel(BaseModel):
+ """Extends BaseModel and overwrite __getattr__ to return None on missing attribute."""
- This Exception should in general never be raised in normal usage of ANTA.
- """
+ model_config = ConfigDict(extra="forbid")
- def __init__(self, message: str) -> None:
- self.message = "\n".join([message, GITHUB_SUGGESTION])
- super().__init__(self.message)
-
-class AntaTemplate(BaseModel):
+class AntaTemplate:
"""Class to define a command template as Python f-string.
+
Can render a command from parameters.
- Attributes:
+ Attributes
+ ----------
template: Python f-string. Example: 'show vlan {vlan_id}'
- version: eAPI version - valid values are 1 or "latest" - default is "latest"
+ version: eAPI version - valid values are 1 or "latest".
revision: Revision of the command. Valid values are 1 to 99. Revision has precedence over version.
- ofmt: eAPI output - json or text - default is json
- use_cache: Enable or disable caching for this AntaTemplate if the AntaDevice supports it - default is True
+ ofmt: eAPI output - json or text.
+ use_cache: Enable or disable caching for this AntaTemplate if the AntaDevice supports it.
"""
- template: str
- version: Literal[1, "latest"] = "latest"
- revision: Optional[conint(ge=1, le=99)] = None # type: ignore
- ofmt: Literal["json", "text"] = "json"
- use_cache: bool = True
+ # pylint: disable=too-few-public-methods
+
+ def __init__( # noqa: PLR0913
+ self,
+ template: str,
+ version: Literal[1, "latest"] = "latest",
+ revision: Revision | None = None,
+ ofmt: Literal["json", "text"] = "json",
+ *,
+ use_cache: bool = True,
+ ) -> None:
+ # pylint: disable=too-many-arguments
+ self.template = template
+ self.version = version
+ self.revision = revision
+ self.ofmt = ofmt
+ self.use_cache = use_cache
+
+ # Create a AntaTemplateParams model to elegantly store AntaTemplate variables
+ field_names = [fname for _, fname, _, _ in Formatter().parse(self.template) if fname]
+ # Extracting the type from the params based on the expected field_names from the template
+ fields: dict[str, Any] = {key: (Any, ...) for key in field_names}
+ self.params_schema = create_model(
+ "AntaParams",
+ __base__=AntaParamsBaseModel,
+ **fields,
+ )
+
+ def __repr__(self) -> str:
+ """Return the representation of the class.
+
+ Copying pydantic model style, excluding `params_schema`
+ """
+ return " ".join(f"{a}={v!r}" for a, v in vars(self).items() if a != "params_schema")
- def render(self, **params: dict[str, Any]) -> AntaCommand:
+ def render(self, **params: str | int | bool) -> AntaCommand:
"""Render an AntaCommand from an AntaTemplate instance.
+
Keep the parameters used in the AntaTemplate instance.
Args:
+ ----
params: dictionary of variables with string values to render the Python f-string
- Returns:
- command: The rendered AntaCommand.
- This AntaCommand instance have a template attribute that references this
- AntaTemplate instance.
+ Returns
+ -------
+ The rendered AntaCommand.
+ This AntaCommand instance have a template attribute that references this
+ AntaTemplate instance.
+
+ Raises
+ ------
+ AntaTemplateRenderError
+ If a parameter is missing to render the AntaTemplate instance.
"""
try:
- return AntaCommand(
- command=self.template.format(**params),
- ofmt=self.ofmt,
- version=self.version,
- revision=self.revision,
- template=self,
- params=params,
- use_cache=self.use_cache,
- )
- except KeyError as e:
+ command = self.template.format(**params)
+ except (KeyError, SyntaxError) as e:
raise AntaTemplateRenderError(self, e.args[0]) from e
+ return AntaCommand(
+ command=command,
+ ofmt=self.ofmt,
+ version=self.version,
+ revision=self.revision,
+ template=self,
+ params=self.params_schema(**params),
+ use_cache=self.use_cache,
+ )
class AntaCommand(BaseModel):
@@ -113,70 +139,117 @@ class AntaCommand(BaseModel):
__Revision has precedence over version.__
- Attributes:
+ Attributes
+ ----------
command: Device command
- version: eAPI version - valid values are 1 or "latest" - default is "latest"
+ version: eAPI version - valid values are 1 or "latest".
revision: eAPI revision of the command. Valid values are 1 to 99. Revision has precedence over version.
- ofmt: eAPI output - json or text - default is json
- output: Output of the command populated by the collect() function
- template: AntaTemplate object used to render this command
- params: Dictionary of variables with string values to render the template
- errors: If the command execution fails, eAPI returns a list of strings detailing the error
- use_cache: Enable or disable caching for this AntaCommand if the AntaDevice supports it - default is True
+ ofmt: eAPI output - json or text.
+ output: Output of the command. Only defined if there was no errors.
+ template: AntaTemplate object used to render this command.
+ errors: If the command execution fails, eAPI returns a list of strings detailing the error(s).
+ params: Pydantic Model containing the variables values used to render the template.
+ use_cache: Enable or disable caching for this AntaCommand if the AntaDevice supports it.
+
"""
+ model_config = ConfigDict(arbitrary_types_allowed=True)
+
command: str
version: Literal[1, "latest"] = "latest"
- revision: Optional[conint(ge=1, le=99)] = None # type: ignore
+ revision: Revision | None = None
ofmt: Literal["json", "text"] = "json"
- output: Optional[Union[Dict[str, Any], str]] = None
- template: Optional[AntaTemplate] = None
- errors: List[str] = []
- params: Dict[str, Any] = {}
+ output: dict[str, Any] | str | None = None
+ template: AntaTemplate | None = None
+ errors: list[str] = []
+ params: AntaParamsBaseModel = AntaParamsBaseModel()
use_cache: bool = True
@property
def uid(self) -> str:
- """Generate a unique identifier for this command"""
+ """Generate a unique identifier for this command."""
uid_str = f"{self.command}_{self.version}_{self.revision or 'NA'}_{self.ofmt}"
- return hashlib.sha1(uid_str.encode()).hexdigest()
+ # Ignoring S324 probable use of insecure hash function - sha1 is enough for our needs.
+ return hashlib.sha1(uid_str.encode()).hexdigest() # noqa: S324
@property
def json_output(self) -> dict[str, Any]:
- """Get the command output as JSON"""
+ """Get the command output as JSON."""
if self.output is None:
- raise RuntimeError(f"There is no output for command {self.command}")
+ msg = f"There is no output for command '{self.command}'"
+ raise RuntimeError(msg)
if self.ofmt != "json" or not isinstance(self.output, dict):
- raise RuntimeError(f"Output of command {self.command} is invalid")
+ msg = f"Output of command '{self.command}' is invalid"
+ raise RuntimeError(msg)
return dict(self.output)
@property
def text_output(self) -> str:
- """Get the command output as a string"""
+ """Get the command output as a string."""
if self.output is None:
- raise RuntimeError(f"There is no output for command {self.command}")
+ msg = f"There is no output for command '{self.command}'"
+ raise RuntimeError(msg)
if self.ofmt != "text" or not isinstance(self.output, str):
- raise RuntimeError(f"Output of command {self.command} is invalid")
+ msg = f"Output of command '{self.command}' is invalid"
+ raise RuntimeError(msg)
return str(self.output)
@property
+ def error(self) -> bool:
+ """Return True if the command returned an error, False otherwise."""
+ return len(self.errors) > 0
+
+ @property
def collected(self) -> bool:
- """Return True if the command has been collected"""
- return self.output is not None and not self.errors
+ """Return True if the command has been collected, False otherwise.
+
+ A command that has not been collected could have returned an error.
+ See error property.
+ """
+ return not self.error and self.output is not None
+
+ @property
+ def requires_privileges(self) -> bool:
+ """Return True if the command requires privileged mode, False otherwise.
+
+ Raises
+ ------
+ RuntimeError
+ If the command has not been collected and has not returned an error.
+ AntaDevice.collect() must be called before this property.
+ """
+ if not self.collected and not self.error:
+ msg = f"Command '{self.command}' has not been collected and has not returned an error. Call AntaDevice.collect()."
+ raise RuntimeError(msg)
+ return any("privileged mode required" in e for e in self.errors)
+
+ @property
+ def supported(self) -> bool:
+ """Return True if the command is supported on the device hardware platform, False otherwise.
+
+ Raises
+ ------
+ RuntimeError
+ If the command has not been collected and has not returned an error.
+ AntaDevice.collect() must be called before this property.
+ """
+ if not self.collected and not self.error:
+ msg = f"Command '{self.command}' has not been collected and has not returned an error. Call AntaDevice.collect()."
+ raise RuntimeError(msg)
+ return not any("not supported on this hardware platform" in e for e in self.errors)
class AntaTemplateRenderError(RuntimeError):
- """
- Raised when an AntaTemplate object could not be rendered
- because of missing parameters
- """
+ """Raised when an AntaTemplate object could not be rendered because of missing parameters."""
- def __init__(self, template: AntaTemplate, key: str):
- """Constructor for AntaTemplateRenderError
+ def __init__(self, template: AntaTemplate, key: str) -> None:
+ """Initialize an AntaTemplateRenderError.
Args:
+ ----
template: The AntaTemplate instance that failed to render
key: Key that has not been provided to render the template
+
"""
self.template = template
self.key = key
@@ -184,12 +257,13 @@ class AntaTemplateRenderError(RuntimeError):
class AntaTest(ABC):
- """Abstract class defining a test in ANTA
+ """Abstract class defining a test in ANTA.
The goal of this class is to handle the heavy lifting and make
writing a test as simple as possible.
- Examples:
+ Examples
+ --------
The following is an example of an AntaTest subclass implementation:
```python
class VerifyReachability(AntaTest):
@@ -206,14 +280,13 @@ class AntaTest(ABC):
vrf: str = "default"
def render(self, template: AntaTemplate) -> list[AntaCommand]:
- return [template.render({"dst": host.dst, "src": host.src, "vrf": host.vrf}) for host in self.inputs.hosts]
+ return [template.render(dst=host.dst, src=host.src, vrf=host.vrf) for host in self.inputs.hosts]
@AntaTest.anta_test
def test(self) -> None:
failures = []
for command in self.instance_commands:
- if command.params and ("src" and "dst") in command.params:
- src, dst = command.params["src"], command.params["dst"]
+ src, dst = command.params.src, command.params.dst
if "2 received" not in command.json_output["messages"][0]:
failures.append((str(src), str(dst)))
if not failures:
@@ -221,7 +294,9 @@ class AntaTest(ABC):
else:
self.result.is_failure(f"Connectivity test failed for the following source-destination pairs: {failures}")
```
- Attributes:
+
+ Attributes
+ ----------
device: AntaDevice instance on which this test is run
inputs: AntaTest.Input instance carrying the test inputs
instance_commands: List of AntaCommand instances of this test
@@ -230,19 +305,20 @@ class AntaTest(ABC):
"""
# Mandatory class attributes
- # TODO - find a way to tell mypy these are mandatory for child classes - maybe Protocol
+ # TODO: find a way to tell mypy these are mandatory for child classes - maybe Protocol
name: ClassVar[str]
description: ClassVar[str]
categories: ClassVar[list[str]]
- commands: ClassVar[list[Union[AntaTemplate, AntaCommand]]]
+ commands: ClassVar[list[AntaTemplate | AntaCommand]]
# Class attributes to handle the progress bar of ANTA CLI
- progress: Optional[Progress] = None
- nrfu_task: Optional[TaskID] = None
+ progress: Progress | None = None
+ nrfu_task: TaskID | None = None
class Input(BaseModel):
"""Class defining inputs for a test in ANTA.
- Examples:
+ Examples
+ --------
A valid test catalog will look like the following:
```yaml
<Python module>:
@@ -253,74 +329,86 @@ class AntaTest(ABC):
description: "Test with overwritten description"
custom_field: "Test run by John Doe"
```
- Attributes:
+
+ Attributes
+ ----------
result_overwrite: Define fields to overwrite in the TestResult object
"""
model_config = ConfigDict(extra="forbid")
- result_overwrite: Optional[ResultOverwrite] = None
- filters: Optional[Filters] = None
+ result_overwrite: ResultOverwrite | None = None
+ filters: Filters | None = None
def __hash__(self) -> int:
- """
- Implement generic hashing for AntaTest.Input.
+ """Implement generic hashing for AntaTest.Input.
+
This will work in most cases but this does not consider 2 lists with different ordering as equal.
"""
return hash(self.model_dump_json())
class ResultOverwrite(BaseModel):
- """Test inputs model to overwrite result fields
+ """Test inputs model to overwrite result fields.
- Attributes:
+ Attributes
+ ----------
description: overwrite TestResult.description
categories: overwrite TestResult.categories
custom_field: a free string that will be included in the TestResult object
+
"""
model_config = ConfigDict(extra="forbid")
- description: Optional[str] = None
- categories: Optional[List[str]] = None
- custom_field: Optional[str] = None
+ description: str | None = None
+ categories: list[str] | None = None
+ custom_field: str | None = None
class Filters(BaseModel):
- """Runtime filters to map tests with list of tags or devices
+ """Runtime filters to map tests with list of tags or devices.
- Attributes:
- tags: List of device's tags for the test.
+ Attributes
+ ----------
+ tags: Tag of devices on which to run the test.
"""
model_config = ConfigDict(extra="forbid")
- tags: Optional[List[str]] = None
+ tags: set[str] | None = None
def __init__(
self,
device: AntaDevice,
inputs: dict[str, Any] | AntaTest.Input | None = None,
eos_data: list[dict[Any, Any] | str] | None = None,
- ):
- """AntaTest Constructor
+ ) -> None:
+ """AntaTest Constructor.
Args:
+ ----
device: AntaDevice instance on which the test will be run
inputs: dictionary of attributes used to instantiate the AntaTest.Input instance
eos_data: Populate outputs of the test commands instead of collecting from devices.
This list must have the same length and order than the `instance_commands` instance attribute.
"""
- self.logger: logging.Logger = logging.getLogger(f"{self.__module__}.{self.__class__.__name__}")
+ self.logger: logging.Logger = logging.getLogger(f"{self.module}.{self.__class__.__name__}")
self.device: AntaDevice = device
self.inputs: AntaTest.Input
self.instance_commands: list[AntaCommand] = []
- self.result: TestResult = TestResult(name=device.name, test=self.name, categories=self.categories, description=self.description)
+ self.result: TestResult = TestResult(
+ name=device.name,
+ test=self.name,
+ categories=self.categories,
+ description=self.description,
+ )
self._init_inputs(inputs)
if self.result.result == "unset":
self._init_commands(eos_data)
def _init_inputs(self, inputs: dict[str, Any] | AntaTest.Input | None) -> None:
- """Instantiate the `inputs` instance attribute with an `AntaTest.Input` instance
- to validate test inputs from defined model.
+ """Instantiate the `inputs` instance attribute with an `AntaTest.Input` instance to validate test inputs using the model.
+
Overwrite result fields based on `ResultOverwrite` input definition.
- Any input validation error will set this test result status as 'error'."""
+ Any input validation error will set this test result status as 'error'.
+ """
try:
if inputs is None:
self.inputs = self.Input()
@@ -329,7 +417,7 @@ class AntaTest(ABC):
elif isinstance(inputs, dict):
self.inputs = self.Input(**inputs)
except ValidationError as e:
- message = f"{self.__module__}.{self.__class__.__name__}: Inputs are not valid\n{e}"
+ message = f"{self.module}.{self.name}: Inputs are not valid\n{e}"
self.logger.error(message)
self.result.is_error(message=message)
return
@@ -340,10 +428,11 @@ class AntaTest(ABC):
self.result.description = res_ow.description
self.result.custom_field = res_ow.custom_field
- def _init_commands(self, eos_data: Optional[list[dict[Any, Any] | str]]) -> None:
+ def _init_commands(self, eos_data: list[dict[Any, Any] | str] | None) -> None:
"""Instantiate the `instance_commands` instance attribute from the `commands` class attribute.
+
- Copy of the `AntaCommand` instances
- - Render all `AntaTemplate` instances using the `render()` method
+ - Render all `AntaTemplate` instances using the `render()` method.
Any template rendering error will set this test result status as 'error'.
Any exception in user code in `render()` will set this test result status as 'error'.
@@ -351,7 +440,7 @@ class AntaTest(ABC):
if self.__class__.commands:
for cmd in self.__class__.commands:
if isinstance(cmd, AntaCommand):
- self.instance_commands.append(deepcopy(cmd))
+ self.instance_commands.append(cmd.model_copy())
elif isinstance(cmd, AntaTemplate):
try:
self.instance_commands.extend(self.render(cmd))
@@ -365,17 +454,17 @@ class AntaTest(ABC):
# render() is user-defined code.
# We need to catch everything if we want the AntaTest object
# to live until the reporting
- message = f"Exception in {self.__module__}.{self.__class__.__name__}.render()"
+ message = f"Exception in {self.module}.{self.__class__.__name__}.render()"
anta_log_exception(e, message, self.logger)
self.result.is_error(message=f"{message}: {exc_to_str(e)}")
return
if eos_data is not None:
- self.logger.debug(f"Test {self.name} initialized with input data")
+ self.logger.debug("Test %s initialized with input data", self.name)
self.save_commands_data(eos_data)
def save_commands_data(self, eos_data: list[dict[str, Any] | str]) -> None:
- """Populate output of all AntaCommand instances in `instance_commands`"""
+ """Populate output of all AntaCommand instances in `instance_commands`."""
if len(eos_data) > len(self.instance_commands):
self.result.is_error(message="Test initialization error: Trying to save more data than there are commands for the test")
return
@@ -386,49 +475,59 @@ class AntaTest(ABC):
self.instance_commands[index].output = data
def __init_subclass__(cls) -> None:
- """Verify that the mandatory class attributes are defined"""
+ """Verify that the mandatory class attributes are defined."""
mandatory_attributes = ["name", "description", "categories", "commands"]
for attr in mandatory_attributes:
if not hasattr(cls, attr):
- raise NotImplementedError(f"Class {cls.__module__}.{cls.__name__} is missing required class attribute {attr}")
+ msg = f"Class {cls.__module__}.{cls.__name__} is missing required class attribute {attr}"
+ raise NotImplementedError(msg)
+
+ @property
+ def module(self) -> str:
+ """Return the Python module in which this AntaTest class is defined."""
+ return self.__module__
@property
def collected(self) -> bool:
- """Returns True if all commands for this test have been collected."""
+ """Return True if all commands for this test have been collected."""
return all(command.collected for command in self.instance_commands)
@property
def failed_commands(self) -> list[AntaCommand]:
- """Returns a list of all the commands that have failed."""
- return [command for command in self.instance_commands if command.errors]
+ """Return a list of all the commands that have failed."""
+ return [command for command in self.instance_commands if command.error]
def render(self, template: AntaTemplate) -> list[AntaCommand]:
- """Render an AntaTemplate instance of this AntaTest using the provided
- AntaTest.Input instance at self.inputs.
+ """Render an AntaTemplate instance of this AntaTest using the provided AntaTest.Input instance at self.inputs.
This is not an abstract method because it does not need to be implemented if there is
- no AntaTemplate for this test."""
- raise NotImplementedError(f"AntaTemplate are provided but render() method has not been implemented for {self.__module__}.{self.name}")
+ no AntaTemplate for this test.
+ """
+ _ = template
+ msg = f"AntaTemplate are provided but render() method has not been implemented for {self.module}.{self.__class__.__name__}"
+ raise NotImplementedError(msg)
@property
def blocked(self) -> bool:
"""Check if CLI commands contain a blocked keyword."""
state = False
for command in self.instance_commands:
- for pattern in BLACKLIST_REGEX:
+ for pattern in REGEXP_EOS_BLACKLIST_CMDS:
if re.match(pattern, command.command):
- self.logger.error(f"Command <{command.command}> is blocked for security reason matching {BLACKLIST_REGEX}")
+ self.logger.error(
+ "Command <%s> is blocked for security reason matching %s",
+ command.command,
+ REGEXP_EOS_BLACKLIST_CMDS,
+ )
self.result.is_error(f"<{command.command}> is blocked for security reason")
state = True
return state
async def collect(self) -> None:
- """
- Method used to collect outputs of all commands of this test class from the device of this test instance.
- """
+ """Collect outputs of all commands of this test class from the device of this test instance."""
try:
if self.blocked is False:
- await self.device.collect_commands(self.instance_commands)
+ await self.device.collect_commands(self.instance_commands, collection_id=self.name)
except Exception as e: # pylint: disable=broad-exception-caught
# device._collect() is user-defined code.
# We need to catch everything if we want the AntaTest object
@@ -439,8 +538,7 @@ class AntaTest(ABC):
@staticmethod
def anta_test(function: F) -> Callable[..., Coroutine[Any, Any, TestResult]]:
- """
- Decorator for the `test()` method.
+ """Decorate the `test()` method in child classes.
This decorator implements (in this order):
@@ -454,45 +552,46 @@ class AntaTest(ABC):
async def wrapper(
self: AntaTest,
eos_data: list[dict[Any, Any] | str] | None = None,
- **kwargs: Any,
+ **kwargs: dict[str, Any],
) -> TestResult:
- """
+ """Inner function for the anta_test decorator.
+
Args:
+ ----
+ self: The test instance.
eos_data: Populate outputs of the test commands instead of collecting from devices.
This list must have the same length and order than the `instance_commands` instance attribute.
+ kwargs: Any keyword argument to pass to the test.
- Returns:
+ Returns
+ -------
result: TestResult instance attribute populated with error status if any
- """
- def format_td(seconds: float, digits: int = 3) -> str:
- isec, fsec = divmod(round(seconds * 10**digits), 10**digits)
- return f"{timedelta(seconds=isec)}.{fsec:0{digits}.0f}"
-
- start_time = time.time()
+ """
if self.result.result != "unset":
return self.result
# Data
if eos_data is not None:
self.save_commands_data(eos_data)
- self.logger.debug(f"Test {self.name} initialized with input data {eos_data}")
+ self.logger.debug("Test %s initialized with input data %s", self.name, eos_data)
# If some data is missing, try to collect
if not self.collected:
await self.collect()
if self.result.result != "unset":
+ AntaTest.update_progress()
return self.result
if cmds := self.failed_commands:
- self.logger.debug(self.device.supports)
- unsupported_commands = [f"Skipped because {c.command} is not supported on {self.device.hw_model}" for c in cmds if not self.device.supports(c)]
- self.logger.debug(unsupported_commands)
+ unsupported_commands = [f"'{c.command}' is not supported on {self.device.hw_model}" for c in cmds if not c.supported]
if unsupported_commands:
- self.logger.warning(f"Test {self.name} has been skipped because it is not supported on {self.device.hw_model}: {GITHUB_SUGGESTION}")
+ msg = f"Test {self.name} has been skipped because it is not supported on {self.device.hw_model}: {GITHUB_SUGGESTION}"
+ self.logger.warning(msg)
self.result.is_skipped("\n".join(unsupported_commands))
- return self.result
- self.result.is_error(message="\n".join([f"{c.command} has failed: {', '.join(c.errors)}" for c in cmds]))
+ else:
+ self.result.is_error(message="\n".join([f"{c.command} has failed: {', '.join(c.errors)}" for c in cmds]))
+ AntaTest.update_progress()
return self.result
try:
@@ -505,30 +604,27 @@ class AntaTest(ABC):
anta_log_exception(e, message, self.logger)
self.result.is_error(message=exc_to_str(e))
- test_duration = time.time() - start_time
- self.logger.debug(f"Executing test {self.name} on device {self.device.name} took {format_td(test_duration)}")
-
+ # TODO: find a correct way to time test execution
AntaTest.update_progress()
return self.result
return wrapper
@classmethod
- def update_progress(cls) -> None:
- """
- Update progress bar for all AntaTest objects if it exists
- """
+ def update_progress(cls: type[AntaTest]) -> None:
+ """Update progress bar for all AntaTest objects if it exists."""
if cls.progress and (cls.nrfu_task is not None):
cls.progress.update(cls.nrfu_task, advance=1)
@abstractmethod
def test(self) -> Coroutine[Any, Any, TestResult]:
- """
- This abstract method is the core of the test logic.
- It must set the correct status of the `result` instance attribute
- with the appropriate outcome of the test.
+ """Core of the test logic.
+
+ This is an abstractmethod that must be implemented by child classes.
+ It must set the correct status of the `result` instance attribute with the appropriate outcome of the test.
- Examples:
+ Examples
+ --------
It must be implemented using the `AntaTest.anta_test` decorator:
```python
@AntaTest.anta_test
@@ -536,6 +632,7 @@ class AntaTest(ABC):
self.result.is_success()
for command in self.instance_commands:
if not self._test_command(command): # _test_command() is an arbitrary test logic
- self.result.is_failure("Failure reson")
+ self.result.is_failure("Failure reason")
```
+
"""
diff --git a/anta/reporter/__init__.py b/anta/reporter/__init__.py
index dda9d9c..63a1fe5 100644
--- a/anta/reporter/__init__.py
+++ b/anta/reporter/__init__.py
@@ -1,23 +1,25 @@
# Copyright (c) 2023-2024 Arista Networks, Inc.
# Use of this source code is governed by the Apache License 2.0
# that can be found in the LICENSE file.
-"""
-Report management for ANTA.
-"""
+"""Report management for ANTA."""
+
# pylint: disable = too-few-public-methods
from __future__ import annotations
import logging
-import os.path
-import pathlib
-from typing import Any, Optional
+from typing import TYPE_CHECKING, Any
from jinja2 import Template
from rich.table import Table
from anta import RICH_COLOR_PALETTE, RICH_COLOR_THEME
-from anta.custom_types import TestStatus
-from anta.result_manager import ResultManager
+
+if TYPE_CHECKING:
+ import pathlib
+
+ from anta.custom_types import TestStatus
+ from anta.result_manager import ResultManager
+ from anta.result_manager.models import TestResult
logger = logging.getLogger(__name__)
@@ -25,33 +27,37 @@ logger = logging.getLogger(__name__)
class ReportTable:
"""TableReport Generate a Table based on TestResult."""
- def _split_list_to_txt_list(self, usr_list: list[str], delimiter: Optional[str] = None) -> str:
- """
- Split list to multi-lines string
+ def _split_list_to_txt_list(self, usr_list: list[str], delimiter: str | None = None) -> str:
+ """Split list to multi-lines string.
Args:
+ ----
usr_list (list[str]): List of string to concatenate
delimiter (str, optional): A delimiter to use to start string. Defaults to None.
- Returns:
+ Returns
+ -------
str: Multi-lines string
+
"""
if delimiter is not None:
return "\n".join(f"{delimiter} {line}" for line in usr_list)
return "\n".join(f"{line}" for line in usr_list)
def _build_headers(self, headers: list[str], table: Table) -> Table:
- """
- Create headers for a table.
+ """Create headers for a table.
First key is considered as header and is colored using RICH_COLOR_PALETTE.HEADER
Args:
- headers (list[str]): List of headers
- table (Table): A rich Table instance
+ ----
+ headers: List of headers.
+ table: A rich Table instance.
+
+ Returns
+ -------
+ A rich `Table` instance with headers.
- Returns:
- Table: A rich Table instance with headers
"""
for idx, header in enumerate(headers):
if idx == 0:
@@ -64,72 +70,69 @@ class ReportTable:
return table
def _color_result(self, status: TestStatus) -> str:
- """
- Return a colored string based on the status value.
+ """Return a colored string based on the status value.
Args:
- status (TestStatus): status value to color
+ ----
+ status (TestStatus): status value to color.
- Returns:
+ Returns
+ -------
str: the colored string
+
"""
color = RICH_COLOR_THEME.get(status, "")
return f"[{color}]{status}" if color != "" else str(status)
- def report_all(
- self,
- result_manager: ResultManager,
- host: Optional[str] = None,
- testcase: Optional[str] = None,
- title: str = "All tests results",
- ) -> Table:
- """
- Create a table report with all tests for one or all devices.
+ def report_all(self, manager: ResultManager, title: str = "All tests results") -> Table:
+ """Create a table report with all tests for one or all devices.
Create table with full output: Host / Test / Status / Message
Args:
- result_manager (ResultManager): A manager with a list of tests.
- host (str, optional): IP Address of a host to search for. Defaults to None.
- testcase (str, optional): A test name to search for. Defaults to None.
- title (str, optional): Title for the report. Defaults to 'All tests results'.
+ ----
+ manager: A ResultManager instance.
+ title: Title for the report. Defaults to 'All tests results'.
+
+ Returns
+ -------
+ A fully populated rich `Table`
- Returns:
- Table: A fully populated rich Table
"""
table = Table(title=title, show_lines=True)
headers = ["Device", "Test Name", "Test Status", "Message(s)", "Test description", "Test category"]
table = self._build_headers(headers=headers, table=table)
- for result in result_manager.get_results():
- # pylint: disable=R0916
- if (host is None and testcase is None) or (host is not None and str(result.name) == host) or (testcase is not None and testcase == str(result.test)):
- state = self._color_result(result.result)
- message = self._split_list_to_txt_list(result.messages) if len(result.messages) > 0 else ""
- categories = ", ".join(result.categories)
- table.add_row(str(result.name), result.test, state, message, result.description, categories)
+ def add_line(result: TestResult) -> None:
+ state = self._color_result(result.result)
+ message = self._split_list_to_txt_list(result.messages) if len(result.messages) > 0 else ""
+ categories = ", ".join(result.categories)
+ table.add_row(str(result.name), result.test, state, message, result.description, categories)
+
+ for result in manager.results:
+ add_line(result)
return table
def report_summary_tests(
self,
- result_manager: ResultManager,
- testcase: Optional[str] = None,
- title: str = "Summary per test case",
+ manager: ResultManager,
+ tests: list[str] | None = None,
+ title: str = "Summary per test",
) -> Table:
- """
- Create a table report with result agregated per test.
+ """Create a table report with result aggregated per test.
- Create table with full output: Test / Number of success / Number of failure / Number of error / List of nodes in error or failure
+ Create table with full output: Test | Number of success | Number of failure | Number of error | List of nodes in error or failure
Args:
- result_manager (ResultManager): A manager with a list of tests.
- testcase (str, optional): A test name to search for. Defaults to None.
- title (str, optional): Title for the report. Defaults to 'All tests results'.
-
- Returns:
- Table: A fully populated rich Table
+ ----
+ manager: A ResultManager instance.
+ tests: List of test names to include. None to select all tests.
+ title: Title of the report.
+
+ Returns
+ -------
+ A fully populated rich `Table`.
"""
- # sourcery skip: class-extract-method
table = Table(title=title, show_lines=True)
headers = [
"Test Case",
@@ -140,16 +143,16 @@ class ReportTable:
"List of failed or error nodes",
]
table = self._build_headers(headers=headers, table=table)
- for testcase_read in result_manager.get_testcases():
- if testcase is None or str(testcase_read) == testcase:
- results = result_manager.get_result_by_test(testcase_read)
+ for test in manager.get_tests():
+ if tests is None or test in tests:
+ results = manager.filter_by_tests({test}).results
nb_failure = len([result for result in results if result.result == "failure"])
nb_error = len([result for result in results if result.result == "error"])
- list_failure = [str(result.name) for result in results if result.result in ["failure", "error"]]
+ list_failure = [result.name for result in results if result.result in ["failure", "error"]]
nb_success = len([result for result in results if result.result == "success"])
nb_skipped = len([result for result in results if result.result == "skipped"])
table.add_row(
- testcase_read,
+ test,
str(nb_success),
str(nb_skipped),
str(nb_failure),
@@ -158,24 +161,25 @@ class ReportTable:
)
return table
- def report_summary_hosts(
+ def report_summary_devices(
self,
- result_manager: ResultManager,
- host: Optional[str] = None,
- title: str = "Summary per host",
+ manager: ResultManager,
+ devices: list[str] | None = None,
+ title: str = "Summary per device",
) -> Table:
- """
- Create a table report with result agregated per host.
+ """Create a table report with result aggregated per device.
- Create table with full output: Host / Number of success / Number of failure / Number of error / List of nodes in error or failure
+ Create table with full output: Host | Number of success | Number of failure | Number of error | List of nodes in error or failure
Args:
- result_manager (ResultManager): A manager with a list of tests.
- host (str, optional): IP Address of a host to search for. Defaults to None.
- title (str, optional): Title for the report. Defaults to 'All tests results'.
-
- Returns:
- Table: A fully populated rich Table
+ ----
+ manager: A ResultManager instance.
+ devices: List of device names to include. None to select all devices.
+ title: Title of the report.
+
+ Returns
+ -------
+ A fully populated rich `Table`.
"""
table = Table(title=title, show_lines=True)
headers = [
@@ -187,18 +191,16 @@ class ReportTable:
"List of failed or error test cases",
]
table = self._build_headers(headers=headers, table=table)
- for host_read in result_manager.get_hosts():
- if host is None or str(host_read) == host:
- results = result_manager.get_result_by_host(host_read)
- logger.debug("data to use for computation")
- logger.debug(f"{host}: {results}")
+ for device in manager.get_devices():
+ if devices is None or device in devices:
+ results = manager.filter_by_devices({device}).results
nb_failure = len([result for result in results if result.result == "failure"])
nb_error = len([result for result in results if result.result == "error"])
- list_failure = [str(result.test) for result in results if result.result in ["failure", "error"]]
+ list_failure = [result.test for result in results if result.result in ["failure", "error"]]
nb_success = len([result for result in results if result.result == "success"])
nb_skipped = len([result for result in results if result.result == "skipped"])
table.add_row(
- str(host_read),
+ device,
str(nb_success),
str(nb_skipped),
str(nb_failure),
@@ -212,20 +214,20 @@ class ReportJinja:
"""Report builder based on a Jinja2 template."""
def __init__(self, template_path: pathlib.Path) -> None:
- if os.path.isfile(template_path):
- self.tempalte_path = template_path
- else:
- raise FileNotFoundError(f"template file is not found: {template_path}")
+ """Create a ReportJinja instance."""
+ if not template_path.is_file():
+ msg = f"template file is not found: {template_path}"
+ raise FileNotFoundError(msg)
- def render(self, data: list[dict[str, Any]], trim_blocks: bool = True, lstrip_blocks: bool = True) -> str:
- """
- Build a report based on a Jinja2 template
+ self.template_path = template_path
+
+ def render(self, data: list[dict[str, Any]], *, trim_blocks: bool = True, lstrip_blocks: bool = True) -> str:
+ """Build a report based on a Jinja2 template.
Report is built based on a J2 template provided by user.
Data structure sent to template is:
- >>> data = ResultManager.get_json_results()
- >>> print(data)
+ >>> print(ResultManager.json)
[
{
name: ...,
@@ -238,14 +240,17 @@ class ReportJinja:
]
Args:
- data (list[dict[str, Any]]): List of results from ResultManager.get_results
- trim_blocks (bool, optional): enable trim_blocks for J2 rendering. Defaults to True.
- lstrip_blocks (bool, optional): enable lstrip_blocks for J2 rendering. Defaults to True.
+ ----
+ data: List of results from ResultManager.results
+ trim_blocks: enable trim_blocks for J2 rendering.
+ lstrip_blocks: enable lstrip_blocks for J2 rendering.
+
+ Returns
+ -------
+ Rendered template
- Returns:
- str: rendered template
"""
- with open(self.tempalte_path, encoding="utf-8") as file_:
+ with self.template_path.open(encoding="utf-8") as file_:
template = Template(file_.read(), trim_blocks=trim_blocks, lstrip_blocks=lstrip_blocks)
return template.render({"data": data})
diff --git a/anta/result_manager/__init__.py b/anta/result_manager/__init__.py
index 9ce880e..b367965 100644
--- a/anta/result_manager/__init__.py
+++ b/anta/result_manager/__init__.py
@@ -1,35 +1,32 @@
# Copyright (c) 2023-2024 Arista Networks, Inc.
# Use of this source code is governed by the Apache License 2.0
# that can be found in the LICENSE file.
-"""
-Result Manager Module for ANTA.
-"""
+"""Result Manager module for ANTA."""
+
from __future__ import annotations
import json
-import logging
+from typing import TYPE_CHECKING
from pydantic import TypeAdapter
from anta.custom_types import TestStatus
-from anta.result_manager.models import TestResult
-logger = logging.getLogger(__name__)
+if TYPE_CHECKING:
+ from anta.result_manager.models import TestResult
class ResultManager:
- """
- Helper to manage Test Results and generate reports.
-
- Examples:
+ """Helper to manage Test Results and generate reports.
+ Examples
+ --------
Create Inventory:
inventory_anta = AntaInventory.parse(
filename='examples/inventory.yml',
username='ansible',
password='ansible',
- timeout=0.5
)
Create Result Manager:
@@ -38,36 +35,42 @@ class ResultManager:
Run tests for all connected devices:
- for device in inventory_anta.get_inventory():
- manager.add_test_result(
+ for device in inventory_anta.get_inventory().devices:
+ manager.add(
VerifyNTP(device=device).test()
)
- manager.add_test_result(
+ manager.add(
VerifyEOSVersion(device=device).test(version='4.28.3M')
)
Print result in native format:
- manager.get_results()
+ manager.results
[
TestResult(
- host=IPv4Address('192.168.0.10'),
- test='VerifyNTP',
- result='failure',
- message="device is not running NTP correctly"
+ name="pf1",
+ test="VerifyZeroTouch",
+ categories=["configuration"],
+ description="Verifies ZeroTouch is disabled",
+ result="success",
+ messages=[],
+ custom_field=None,
),
TestResult(
- host=IPv4Address('192.168.0.10'),
- test='VerifyEOSVersion',
- result='success',
- message=None
+ name="pf1",
+ test='VerifyNTP',
+ categories=["software"],
+ categories=['system'],
+ description='Verifies if NTP is synchronised.',
+ result='failure',
+ messages=["The device is not synchronized with the configured NTP server(s): 'NTP is disabled.'"],
+ custom_field=None,
),
]
"""
def __init__(self) -> None:
- """
- Class constructor.
+ """Class constructor.
The status of the class is initialized to "unset"
@@ -88,124 +91,116 @@ class ResultManager:
error_status is set to True.
"""
self._result_entries: list[TestResult] = []
- # Initialize status
self.status: TestStatus = "unset"
self.error_status = False
def __len__(self) -> int:
- """
- Implement __len__ method to count number of results.
- """
+ """Implement __len__ method to count number of results."""
return len(self._result_entries)
- def _update_status(self, test_status: TestStatus) -> None:
- """
- Update ResultManager status based on the table above.
- """
- ResultValidator = TypeAdapter(TestStatus)
- ResultValidator.validate_python(test_status)
- if test_status == "error":
- self.error_status = True
- return
- if self.status == "unset":
- self.status = test_status
- elif self.status == "skipped" and test_status in {"success", "failure"}:
- self.status = test_status
- elif self.status == "success" and test_status == "failure":
- self.status = "failure"
-
- def add_test_result(self, entry: TestResult) -> None:
- """Add a result to the list
+ @property
+ def results(self) -> list[TestResult]:
+ """Get the list of TestResult."""
+ return self._result_entries
- Args:
- entry (TestResult): TestResult data to add to the report
- """
- logger.debug(entry)
- self._result_entries.append(entry)
- self._update_status(entry.result)
+ @results.setter
+ def results(self, value: list[TestResult]) -> None:
+ self._result_entries = []
+ self.status = "unset"
+ self.error_status = False
+ for e in value:
+ self.add(e)
- def add_test_results(self, entries: list[TestResult]) -> None:
- """Add a list of results to the list
+ @property
+ def json(self) -> str:
+ """Get a JSON representation of the results."""
+ return json.dumps([result.model_dump() for result in self._result_entries], indent=4)
- Args:
- entries (list[TestResult]): List of TestResult data to add to the report
- """
- for e in entries:
- self.add_test_result(e)
+ def add(self, result: TestResult) -> None:
+ """Add a result to the ResultManager instance.
- def get_status(self, ignore_error: bool = False) -> str:
- """
- Returns the current status including error_status if ignore_error is False
- """
+ Args:
+ ----
+ result: TestResult to add to the ResultManager instance.
+ """
+
+ def _update_status(test_status: TestStatus) -> None:
+ result_validator = TypeAdapter(TestStatus)
+ result_validator.validate_python(test_status)
+ if test_status == "error":
+ self.error_status = True
+ return
+ if self.status == "unset" or self.status == "skipped" and test_status in {"success", "failure"}:
+ self.status = test_status
+ elif self.status == "success" and test_status == "failure":
+ self.status = "failure"
+
+ self._result_entries.append(result)
+ _update_status(result.result)
+
+ def get_status(self, *, ignore_error: bool = False) -> str:
+ """Return the current status including error_status if ignore_error is False."""
return "error" if self.error_status and not ignore_error else self.status
- def get_results(self) -> list[TestResult]:
- """
- Expose list of all test results in different format
+ def filter(self, hide: set[TestStatus]) -> ResultManager:
+ """Get a filtered ResultManager based on test status.
- Returns:
- any: List of results.
- """
- return self._result_entries
-
- def get_json_results(self) -> str:
- """
- Expose list of all test results in JSON
+ Args:
+ ----
+ hide: set of TestStatus literals to select tests to hide based on their status.
- Returns:
- str: JSON dumps of the list of results
+ Returns
+ -------
+ A filtered `ResultManager`.
"""
- result = [result.model_dump() for result in self._result_entries]
- return json.dumps(result, indent=4)
+ manager = ResultManager()
+ manager.results = [test for test in self._result_entries if test.result not in hide]
+ return manager
- def get_result_by_test(self, test_name: str) -> list[TestResult]:
- """
- Get list of test result for a given test.
+ def filter_by_tests(self, tests: set[str]) -> ResultManager:
+ """Get a filtered ResultManager that only contains specific tests.
Args:
- test_name (str): Test name to use to filter results
- output_format (str, optional): format selector. Can be either native/list. Defaults to 'native'.
+ ----
+ tests: Set of test names to filter the results.
- Returns:
- list[TestResult]: List of results related to the test.
+ Returns
+ -------
+ A filtered `ResultManager`.
"""
- return [result for result in self._result_entries if str(result.test) == test_name]
+ manager = ResultManager()
+ manager.results = [result for result in self._result_entries if result.test in tests]
+ return manager
- def get_result_by_host(self, host_ip: str) -> list[TestResult]:
- """
- Get list of test result for a given host.
+ def filter_by_devices(self, devices: set[str]) -> ResultManager:
+ """Get a filtered ResultManager that only contains specific devices.
Args:
- host_ip (str): IP Address of the host to use to filter results.
- output_format (str, optional): format selector. Can be either native/list. Defaults to 'native'.
+ ----
+ devices: Set of device names to filter the results.
- Returns:
- list[TestResult]: List of results related to the host.
+ Returns
+ -------
+ A filtered `ResultManager`.
"""
- return [result for result in self._result_entries if str(result.name) == host_ip]
+ manager = ResultManager()
+ manager.results = [result for result in self._result_entries if result.name in devices]
+ return manager
- def get_testcases(self) -> list[str]:
- """
- Get list of name of all test cases in current manager.
+ def get_tests(self) -> set[str]:
+ """Get the set of all the test names.
- Returns:
- list[str]: List of names for all tests.
+ Returns
+ -------
+ Set of test names.
"""
- result_list = []
- for testcase in self._result_entries:
- if str(testcase.test) not in result_list:
- result_list.append(str(testcase.test))
- return result_list
+ return {str(result.test) for result in self._result_entries}
- def get_hosts(self) -> list[str]:
- """
- Get list of IP addresses in current manager.
+ def get_devices(self) -> set[str]:
+ """Get the set of all the device names.
- Returns:
- list[str]: List of IP addresses.
+ Returns
+ -------
+ Set of device names.
"""
- result_list = []
- for testcase in self._result_entries:
- if str(testcase.name) not in result_list:
- result_list.append(str(testcase.name))
- return result_list
+ return {str(result.name) for result in self._result_entries}
diff --git a/anta/result_manager/models.py b/anta/result_manager/models.py
index 1531381..c53947e 100644
--- a/anta/result_manager/models.py
+++ b/anta/result_manager/models.py
@@ -2,10 +2,8 @@
# Use of this source code is governed by the Apache License 2.0
# that can be found in the LICENSE file.
"""Models related to anta.result_manager module."""
-from __future__ import annotations
-# Need to keep List for pydantic in 3.8
-from typing import List, Optional
+from __future__ import annotations
from pydantic import BaseModel
@@ -13,10 +11,10 @@ from anta.custom_types import TestStatus
class TestResult(BaseModel):
- """
- Describe the result of a test from a single device.
+ """Describe the result of a test from a single device.
- Attributes:
+ Attributes
+ ----------
name: Device name where the test has run.
test: Test name runs on the device.
categories: List of categories the TestResult belongs to, by default the AntaTest categories.
@@ -24,63 +22,70 @@ class TestResult(BaseModel):
result: Result of the test. Can be one of "unset", "success", "failure", "error" or "skipped".
messages: Message to report after the test if any.
custom_field: Custom field to store a string for flexibility in integrating with ANTA
+
"""
name: str
test: str
- categories: List[str]
+ categories: list[str]
description: str
result: TestStatus = "unset"
- messages: List[str] = []
- custom_field: Optional[str] = None
+ messages: list[str] = []
+ custom_field: str | None = None
def is_success(self, message: str | None = None) -> None:
- """
- Helper to set status to success
+ """Set status to success.
Args:
+ ----
message: Optional message related to the test
+
"""
self._set_status("success", message)
def is_failure(self, message: str | None = None) -> None:
- """
- Helper to set status to failure
+ """Set status to failure.
Args:
+ ----
message: Optional message related to the test
+
"""
self._set_status("failure", message)
def is_skipped(self, message: str | None = None) -> None:
- """
- Helper to set status to skipped
+ """Set status to skipped.
Args:
+ ----
message: Optional message related to the test
+
"""
self._set_status("skipped", message)
def is_error(self, message: str | None = None) -> None:
- """
- Helper to set status to error
+ """Set status to error.
+
+ Args:
+ ----
+ message: Optional message related to the test
+
"""
self._set_status("error", message)
def _set_status(self, status: TestStatus, message: str | None = None) -> None:
- """
- Set status and insert optional message
+ """Set status and insert optional message.
Args:
+ ----
status: status of the test
message: optional message
+
"""
self.result = status
if message is not None:
self.messages.append(message)
def __str__(self) -> str:
- """
- Returns a human readable string of this TestResult
- """
+ """Return a human readable string of this TestResult."""
return f"Test '{self.test}' (on '{self.name}'): Result '{self.result}'\nMessages: {self.messages}"
diff --git a/anta/runner.py b/anta/runner.py
index ab65c80..75391da 100644
--- a/anta/runner.py
+++ b/anta/runner.py
@@ -1,109 +1,270 @@
# Copyright (c) 2023-2024 Arista Networks, Inc.
# Use of this source code is governed by the Apache License 2.0
# that can be found in the LICENSE file.
-# pylint: disable=too-many-branches
-"""
-ANTA runner function
-"""
+"""ANTA runner function."""
+
from __future__ import annotations
import asyncio
import logging
-from typing import Tuple
+import os
+import resource
+from collections import defaultdict
+from typing import TYPE_CHECKING, Any
from anta import GITHUB_SUGGESTION
-from anta.catalog import AntaCatalog, AntaTestDefinition
-from anta.device import AntaDevice
-from anta.inventory import AntaInventory
-from anta.logger import anta_log_exception
+from anta.logger import anta_log_exception, exc_to_str
from anta.models import AntaTest
-from anta.result_manager import ResultManager
+from anta.tools import Catchtime, cprofile
+
+if TYPE_CHECKING:
+ from collections.abc import Coroutine
+
+ from anta.catalog import AntaCatalog, AntaTestDefinition
+ from anta.device import AntaDevice
+ from anta.inventory import AntaInventory
+ from anta.result_manager import ResultManager
+ from anta.result_manager.models import TestResult
logger = logging.getLogger(__name__)
-AntaTestRunner = Tuple[AntaTestDefinition, AntaDevice]
+DEFAULT_NOFILE = 16384
+
+
+def adjust_rlimit_nofile() -> tuple[int, int]:
+ """Adjust the maximum number of open file descriptors for the ANTA process.
+
+ The limit is set to the lower of the current hard limit and the value of the ANTA_NOFILE environment variable.
+ If the `ANTA_NOFILE` environment variable is not set or is invalid, `DEFAULT_NOFILE` is used.
-async def main(manager: ResultManager, inventory: AntaInventory, catalog: AntaCatalog, tags: list[str] | None = None, established_only: bool = True) -> None:
+ Returns
+ -------
+ tuple[int, int]: The new soft and hard limits for open file descriptors.
"""
- Main coroutine to run ANTA.
- Use this as an entrypoint to the test framwork in your script.
+ try:
+ nofile = int(os.environ.get("ANTA_NOFILE", DEFAULT_NOFILE))
+ except ValueError as exception:
+ logger.warning("The ANTA_NOFILE environment variable value is invalid: %s\nDefault to %s.", exc_to_str(exception), DEFAULT_NOFILE)
+ nofile = DEFAULT_NOFILE
+
+ limits = resource.getrlimit(resource.RLIMIT_NOFILE)
+ logger.debug("Initial limit numbers for open file descriptors for the current ANTA process: Soft Limit: %s | Hard Limit: %s", limits[0], limits[1])
+ nofile = nofile if limits[1] > nofile else limits[1]
+ logger.debug("Setting soft limit for open file descriptors for the current ANTA process to %s", nofile)
+ resource.setrlimit(resource.RLIMIT_NOFILE, (nofile, limits[1]))
+ return resource.getrlimit(resource.RLIMIT_NOFILE)
+
+
+def log_cache_statistics(devices: list[AntaDevice]) -> None:
+ """Log cache statistics for each device in the inventory.
Args:
- manager: ResultManager object to populate with the test results.
+ ----
+ devices: List of devices in the inventory.
+ """
+ for device in devices:
+ if device.cache_statistics is not None:
+ msg = (
+ f"Cache statistics for '{device.name}': "
+ f"{device.cache_statistics['cache_hits']} hits / {device.cache_statistics['total_commands_sent']} "
+ f"command(s) ({device.cache_statistics['cache_hit_ratio']})"
+ )
+ logger.info(msg)
+ else:
+ logger.info("Caching is not enabled on %s", device.name)
+
+
+async def setup_inventory(inventory: AntaInventory, tags: set[str] | None, devices: set[str] | None, *, established_only: bool) -> AntaInventory | None:
+ """Set up the inventory for the ANTA run.
+
+ Args:
+ ----
inventory: AntaInventory object that includes the device(s).
- catalog: AntaCatalog object that includes the list of tests.
- tags: List of tags to filter devices from the inventory. Defaults to None.
- established_only: Include only established device(s). Defaults to True.
+ tags: Tags to filter devices from the inventory.
+ devices: Devices on which to run tests. None means all devices.
- Returns:
- any: ResultManager object gets updated with the test results.
+ Returns
+ -------
+ AntaInventory | None: The filtered inventory or None if there are no devices to run tests on.
"""
- if not catalog.tests:
- logger.info("The list of tests is empty, exiting")
- return
if len(inventory) == 0:
logger.info("The inventory is empty, exiting")
- return
- await inventory.connect_inventory()
- devices: list[AntaDevice] = list(inventory.get_inventory(established_only=established_only, tags=tags).values())
+ return None
- if not devices:
- logger.info(
- f"No device in the established state '{established_only}' "
- f"{f'matching the tags {tags} ' if tags else ''}was found. There is no device to run tests against, exiting"
- )
+ # Filter the inventory based on the CLI provided tags and devices if any
+ selected_inventory = inventory.get_inventory(tags=tags, devices=devices) if tags or devices else inventory
+
+ with Catchtime(logger=logger, message="Connecting to devices"):
+ # Connect to the devices
+ await selected_inventory.connect_inventory()
+
+ # Remove devices that are unreachable
+ selected_inventory = selected_inventory.get_inventory(established_only=established_only)
+
+ # If there are no devices in the inventory after filtering, exit
+ if not selected_inventory.devices:
+ msg = f'No reachable device {f"matching the tags {tags} " if tags else ""}was found.{f" Selected devices: {devices} " if devices is not None else ""}'
+ logger.warning(msg)
+ return None
+
+ return selected_inventory
+
+
+def prepare_tests(
+ inventory: AntaInventory, catalog: AntaCatalog, tests: set[str] | None, tags: set[str] | None
+) -> defaultdict[AntaDevice, set[AntaTestDefinition]] | None:
+ """Prepare the tests to run.
+
+ Args:
+ ----
+ inventory: AntaInventory object that includes the device(s).
+ catalog: AntaCatalog object that includes the list of tests.
+ tests: Tests to run against devices. None means all tests.
+ tags: Tags to filter devices from the inventory.
+
+ Returns
+ -------
+ A mapping of devices to the tests to run or None if there are no tests to run.
+ """
+ # Build indexes for the catalog. If `tests` is set, filter the indexes based on these tests
+ catalog.build_indexes(filtered_tests=tests)
- return
- coros = []
# Using a set to avoid inserting duplicate tests
- tests_set: set[AntaTestRunner] = set()
- for device in devices:
+ device_to_tests: defaultdict[AntaDevice, set[AntaTestDefinition]] = defaultdict(set)
+
+ # Create AntaTestRunner tuples from the tags
+ for device in inventory.devices:
if tags:
# If there are CLI tags, only execute tests with matching tags
- tests_set.update((test, device) for test in catalog.get_tests_by_tags(tags))
+ device_to_tests[device].update(catalog.get_tests_by_tags(tags))
else:
- # If there is no CLI tags, execute all tests without filters
- tests_set.update((t, device) for t in catalog.tests if t.inputs.filters is None or t.inputs.filters.tags is None)
+ # If there is no CLI tags, execute all tests that do not have any tags
+ device_to_tests[device].update(catalog.tag_to_tests[None])
# Then add the tests with matching tags from device tags
- tests_set.update((t, device) for t in catalog.get_tests_by_tags(device.tags))
+ device_to_tests[device].update(catalog.get_tests_by_tags(device.tags))
+
+ catalog.final_tests_count += len(device_to_tests[device])
+
+ if catalog.final_tests_count == 0:
+ msg = (
+ f"There are no tests{f' matching the tags {tags} ' if tags else ' '}to run in the current test catalog and device inventory, please verify your inputs."
+ )
+ logger.warning(msg)
+ return None
- tests: list[AntaTestRunner] = list(tests_set)
+ return device_to_tests
- if not tests:
- logger.info(f"There is no tests{f' matching the tags {tags} ' if tags else ' '}to run on current inventory. " "Exiting...")
+
+def get_coroutines(selected_tests: defaultdict[AntaDevice, set[AntaTestDefinition]]) -> list[Coroutine[Any, Any, TestResult]]:
+ """Get the coroutines for the ANTA run.
+
+ Args:
+ ----
+ selected_tests: A mapping of devices to the tests to run. The selected tests are generated by the `prepare_tests` function.
+
+ Returns
+ -------
+ The list of coroutines to run.
+ """
+ coros = []
+ for device, test_definitions in selected_tests.items():
+ for test in test_definitions:
+ try:
+ test_instance = test.test(device=device, inputs=test.inputs)
+ coros.append(test_instance.test())
+ except Exception as e: # noqa: PERF203, pylint: disable=broad-exception-caught
+ # An AntaTest instance is potentially user-defined code.
+ # We need to catch everything and exit gracefully with an error message.
+ message = "\n".join(
+ [
+ f"There is an error when creating test {test.test.module}.{test.test.__name__}.",
+ f"If this is not a custom test implementation: {GITHUB_SUGGESTION}",
+ ],
+ )
+ anta_log_exception(e, message, logger)
+ return coros
+
+
+@cprofile()
+async def main( # noqa: PLR0913
+ manager: ResultManager,
+ inventory: AntaInventory,
+ catalog: AntaCatalog,
+ devices: set[str] | None = None,
+ tests: set[str] | None = None,
+ tags: set[str] | None = None,
+ *,
+ established_only: bool = True,
+ dry_run: bool = False,
+) -> None:
+ # pylint: disable=too-many-arguments
+ """Run ANTA.
+
+ Use this as an entrypoint to the test framework in your script.
+ ResultManager object gets updated with the test results.
+
+ Args:
+ ----
+ manager: ResultManager object to populate with the test results.
+ inventory: AntaInventory object that includes the device(s).
+ catalog: AntaCatalog object that includes the list of tests.
+ devices: Devices on which to run tests. None means all devices. These may come from the `--device / -d` CLI option in NRFU.
+ tests: Tests to run against devices. None means all tests. These may come from the `--test / -t` CLI option in NRFU.
+ tags: Tags to filter devices from the inventory. These may come from the `--tags` CLI option in NRFU.
+ established_only: Include only established device(s).
+ dry_run: Build the list of coroutine to run and stop before test execution.
+ """
+ # Adjust the maximum number of open file descriptors for the ANTA process
+ limits = adjust_rlimit_nofile()
+
+ if not catalog.tests:
+ logger.info("The list of tests is empty, exiting")
return
- for test_definition, device in tests:
- try:
- test_instance = test_definition.test(device=device, inputs=test_definition.inputs)
-
- coros.append(test_instance.test())
- except Exception as e: # pylint: disable=broad-exception-caught
- # An AntaTest instance is potentially user-defined code.
- # We need to catch everything and exit gracefully with an
- # error message
- message = "\n".join(
- [
- f"There is an error when creating test {test_definition.test.__module__}.{test_definition.test.__name__}.",
- f"If this is not a custom test implementation: {GITHUB_SUGGESTION}",
- ]
+ with Catchtime(logger=logger, message="Preparing ANTA NRFU Run"):
+ # Setup the inventory
+ selected_inventory = inventory if dry_run else await setup_inventory(inventory, tags, devices, established_only=established_only)
+ if selected_inventory is None:
+ return
+
+ with Catchtime(logger=logger, message="Preparing the tests"):
+ selected_tests = prepare_tests(selected_inventory, catalog, tests, tags)
+ if selected_tests is None:
+ return
+
+ run_info = (
+ "--- ANTA NRFU Run Information ---\n"
+ f"Number of devices: {len(inventory)} ({len(selected_inventory)} established)\n"
+ f"Total number of selected tests: {catalog.final_tests_count}\n"
+ f"Maximum number of open file descriptors for the current ANTA process: {limits[0]}\n"
+ "---------------------------------"
+ )
+
+ logger.info(run_info)
+
+ if catalog.final_tests_count > limits[0]:
+ logger.warning(
+ "The number of concurrent tests is higher than the open file descriptors limit for this ANTA process.\n"
+ "Errors may occur while running the tests.\n"
+ "Please consult the ANTA FAQ."
)
- anta_log_exception(e, message, logger)
+
+ coroutines = get_coroutines(selected_tests)
+
+ if dry_run:
+ logger.info("Dry-run mode, exiting before running the tests.")
+ for coro in coroutines:
+ coro.close()
+ return
+
if AntaTest.progress is not None:
- AntaTest.nrfu_task = AntaTest.progress.add_task("Running NRFU Tests...", total=len(coros))
+ AntaTest.nrfu_task = AntaTest.progress.add_task("Running NRFU Tests...", total=len(coroutines))
- logger.info("Running ANTA tests...")
- test_results = await asyncio.gather(*coros)
- for r in test_results:
- manager.add_test_result(r)
- for device in devices:
- if device.cache_statistics is not None:
- logger.info(
- f"Cache statistics for '{device.name}': "
- f"{device.cache_statistics['cache_hits']} hits / {device.cache_statistics['total_commands_sent']} "
- f"command(s) ({device.cache_statistics['cache_hit_ratio']})"
- )
- else:
- logger.info(f"Caching is not enabled on {device.name}")
+ with Catchtime(logger=logger, message="Running ANTA tests"):
+ test_results = await asyncio.gather(*coroutines)
+ for r in test_results:
+ manager.add(r)
+
+ log_cache_statistics(selected_inventory.devices)
diff --git a/anta/tests/__init__.py b/anta/tests/__init__.py
index e772bee..ec0b1ec 100644
--- a/anta/tests/__init__.py
+++ b/anta/tests/__init__.py
@@ -1,3 +1,4 @@
# Copyright (c) 2023-2024 Arista Networks, Inc.
# Use of this source code is governed by the Apache License 2.0
# that can be found in the LICENSE file.
+"""Module related to all ANTA tests."""
diff --git a/anta/tests/aaa.py b/anta/tests/aaa.py
index 84298cf..d6d0689 100644
--- a/anta/tests/aaa.py
+++ b/anta/tests/aaa.py
@@ -1,44 +1,56 @@
# Copyright (c) 2023-2024 Arista Networks, Inc.
# Use of this source code is governed by the Apache License 2.0
# that can be found in the LICENSE file.
-"""
-Test functions related to the EOS various AAA settings
-"""
+"""Module related to the EOS various AAA tests."""
+
# Mypy does not understand AntaTest.Input typing
# mypy: disable-error-code=attr-defined
from __future__ import annotations
from ipaddress import IPv4Address
-
-# Need to keep List and Set for pydantic in python 3.8
-from typing import List, Literal, Set
+from typing import TYPE_CHECKING, ClassVar, Literal
from anta.custom_types import AAAAuthMethod
from anta.models import AntaCommand, AntaTest
+if TYPE_CHECKING:
+ from anta.models import AntaTemplate
-class VerifyTacacsSourceIntf(AntaTest):
- """
- Verifies TACACS source-interface for a specified VRF.
- Expected Results:
- * success: The test will pass if the provided TACACS source-interface is configured in the specified VRF.
- * failure: The test will fail if the provided TACACS source-interface is NOT configured in the specified VRF.
+class VerifyTacacsSourceIntf(AntaTest):
+ """Verifies TACACS source-interface for a specified VRF.
+
+ Expected Results
+ ----------------
+ * Success: The test will pass if the provided TACACS source-interface is configured in the specified VRF.
+ * Failure: The test will fail if the provided TACACS source-interface is NOT configured in the specified VRF.
+
+ Examples
+ --------
+ ```yaml
+ anta.tests.aaa:
+ - VerifyTacacsSourceIntf:
+ intf: Management0
+ vrf: MGMT
+ ```
"""
name = "VerifyTacacsSourceIntf"
description = "Verifies TACACS source-interface for a specified VRF."
- categories = ["aaa"]
- commands = [AntaCommand(command="show tacacs")]
+ categories: ClassVar[list[str]] = ["aaa"]
+ commands: ClassVar[list[AntaCommand | AntaTemplate]] = [AntaCommand(command="show tacacs", revision=1)]
+
+ class Input(AntaTest.Input):
+ """Input model for the VerifyTacacsSourceIntf test."""
- class Input(AntaTest.Input): # pylint: disable=missing-class-docstring
intf: str
- """Source-interface to use as source IP of TACACS messages"""
+ """Source-interface to use as source IP of TACACS messages."""
vrf: str = "default"
- """The name of the VRF to transport TACACS messages"""
+ """The name of the VRF to transport TACACS messages. Defaults to `default`."""
@AntaTest.anta_test
def test(self) -> None:
+ """Main test function for VerifyTacacsSourceIntf."""
command_output = self.instance_commands[0].json_output
try:
if command_output["srcIntf"][self.inputs.vrf] == self.inputs.intf:
@@ -50,27 +62,41 @@ class VerifyTacacsSourceIntf(AntaTest):
class VerifyTacacsServers(AntaTest):
- """
- Verifies TACACS servers are configured for a specified VRF.
-
- Expected Results:
- * success: The test will pass if the provided TACACS servers are configured in the specified VRF.
- * failure: The test will fail if the provided TACACS servers are NOT configured in the specified VRF.
+ """Verifies TACACS servers are configured for a specified VRF.
+
+ Expected Results
+ ----------------
+ * Success: The test will pass if the provided TACACS servers are configured in the specified VRF.
+ * Failure: The test will fail if the provided TACACS servers are NOT configured in the specified VRF.
+
+ Examples
+ --------
+ ```yaml
+ anta.tests.aaa:
+ - VerifyTacacsServers:
+ servers:
+ - 10.10.10.21
+ - 10.10.10.22
+ vrf: MGMT
+ ```
"""
name = "VerifyTacacsServers"
description = "Verifies TACACS servers are configured for a specified VRF."
- categories = ["aaa"]
- commands = [AntaCommand(command="show tacacs")]
+ categories: ClassVar[list[str]] = ["aaa"]
+ commands: ClassVar[list[AntaCommand | AntaTemplate]] = [AntaCommand(command="show tacacs", revision=1)]
- class Input(AntaTest.Input): # pylint: disable=missing-class-docstring
- servers: List[IPv4Address]
- """List of TACACS servers"""
+ class Input(AntaTest.Input):
+ """Input model for the VerifyTacacsServers test."""
+
+ servers: list[IPv4Address]
+ """List of TACACS servers."""
vrf: str = "default"
- """The name of the VRF to transport TACACS messages"""
+ """The name of the VRF to transport TACACS messages. Defaults to `default`."""
@AntaTest.anta_test
def test(self) -> None:
+ """Main test function for VerifyTacacsServers."""
command_output = self.instance_commands[0].json_output
tacacs_servers = command_output["tacacsServers"]
if not tacacs_servers:
@@ -90,25 +116,38 @@ class VerifyTacacsServers(AntaTest):
class VerifyTacacsServerGroups(AntaTest):
- """
- Verifies if the provided TACACS server group(s) are configured.
-
- Expected Results:
- * success: The test will pass if the provided TACACS server group(s) are configured.
- * failure: The test will fail if one or all the provided TACACS server group(s) are NOT configured.
+ """Verifies if the provided TACACS server group(s) are configured.
+
+ Expected Results
+ ----------------
+ * Success: The test will pass if the provided TACACS server group(s) are configured.
+ * Failure: The test will fail if one or all the provided TACACS server group(s) are NOT configured.
+
+ Examples
+ --------
+ ```yaml
+ anta.tests.aaa:
+ - VerifyTacacsServerGroups:
+ groups:
+ - TACACS-GROUP1
+ - TACACS-GROUP2
+ ```
"""
name = "VerifyTacacsServerGroups"
description = "Verifies if the provided TACACS server group(s) are configured."
- categories = ["aaa"]
- commands = [AntaCommand(command="show tacacs")]
+ categories: ClassVar[list[str]] = ["aaa"]
+ commands: ClassVar[list[AntaCommand | AntaTemplate]] = [AntaCommand(command="show tacacs", revision=1)]
+
+ class Input(AntaTest.Input):
+ """Input model for the VerifyTacacsServerGroups test."""
- class Input(AntaTest.Input): # pylint: disable=missing-class-docstring
- groups: List[str]
- """List of TACACS server group"""
+ groups: list[str]
+ """List of TACACS server groups."""
@AntaTest.anta_test
def test(self) -> None:
+ """Main test function for VerifyTacacsServerGroups."""
command_output = self.instance_commands[0].json_output
tacacs_groups = command_output["groups"]
if not tacacs_groups:
@@ -122,29 +161,47 @@ class VerifyTacacsServerGroups(AntaTest):
class VerifyAuthenMethods(AntaTest):
- """
- Verifies the AAA authentication method lists for different authentication types (login, enable, dot1x).
-
- Expected Results:
- * success: The test will pass if the provided AAA authentication method list is matching in the configured authentication types.
- * failure: The test will fail if the provided AAA authentication method list is NOT matching in the configured authentication types.
+ """Verifies the AAA authentication method lists for different authentication types (login, enable, dot1x).
+
+ Expected Results
+ ----------------
+ * Success: The test will pass if the provided AAA authentication method list is matching in the configured authentication types.
+ * Failure: The test will fail if the provided AAA authentication method list is NOT matching in the configured authentication types.
+
+ Examples
+ --------
+ ```yaml
+ anta.tests.aaa:
+ - VerifyAuthenMethods:
+ methods:
+ - local
+ - none
+ - logging
+ types:
+ - login
+ - enable
+ - dot1x
+ ```
"""
name = "VerifyAuthenMethods"
description = "Verifies the AAA authentication method lists for different authentication types (login, enable, dot1x)."
- categories = ["aaa"]
- commands = [AntaCommand(command="show aaa methods authentication")]
+ categories: ClassVar[list[str]] = ["aaa"]
+ commands: ClassVar[list[AntaCommand | AntaTemplate]] = [AntaCommand(command="show aaa methods authentication", revision=1)]
+
+ class Input(AntaTest.Input):
+ """Input model for the VerifyAuthenMethods test."""
- class Input(AntaTest.Input): # pylint: disable=missing-class-docstring
- methods: List[AAAAuthMethod]
- """List of AAA authentication methods. Methods should be in the right order"""
- types: Set[Literal["login", "enable", "dot1x"]]
- """List of authentication types to verify"""
+ methods: list[AAAAuthMethod]
+ """List of AAA authentication methods. Methods should be in the right order."""
+ types: set[Literal["login", "enable", "dot1x"]]
+ """List of authentication types to verify."""
@AntaTest.anta_test
def test(self) -> None:
+ """Main test function for VerifyAuthenMethods."""
command_output = self.instance_commands[0].json_output
- not_matching = []
+ not_matching: list[str] = []
for k, v in command_output.items():
auth_type = k.replace("AuthenMethods", "")
if auth_type not in self.inputs.types:
@@ -157,9 +214,8 @@ class VerifyAuthenMethods(AntaTest):
if v["login"]["methods"] != self.inputs.methods:
self.result.is_failure(f"AAA authentication methods {self.inputs.methods} are not matching for login console")
return
- for methods in v.values():
- if methods["methods"] != self.inputs.methods:
- not_matching.append(auth_type)
+ not_matching.extend(auth_type for methods in v.values() if methods["methods"] != self.inputs.methods)
+
if not not_matching:
self.result.is_success()
else:
@@ -167,37 +223,53 @@ class VerifyAuthenMethods(AntaTest):
class VerifyAuthzMethods(AntaTest):
- """
- Verifies the AAA authorization method lists for different authorization types (commands, exec).
-
- Expected Results:
- * success: The test will pass if the provided AAA authorization method list is matching in the configured authorization types.
- * failure: The test will fail if the provided AAA authorization method list is NOT matching in the configured authorization types.
+ """Verifies the AAA authorization method lists for different authorization types (commands, exec).
+
+ Expected Results
+ ----------------
+ * Success: The test will pass if the provided AAA authorization method list is matching in the configured authorization types.
+ * Failure: The test will fail if the provided AAA authorization method list is NOT matching in the configured authorization types.
+
+ Examples
+ --------
+ ```yaml
+ anta.tests.aaa:
+ - VerifyAuthzMethods:
+ methods:
+ - local
+ - none
+ - logging
+ types:
+ - commands
+ - exec
+ ```
"""
name = "VerifyAuthzMethods"
description = "Verifies the AAA authorization method lists for different authorization types (commands, exec)."
- categories = ["aaa"]
- commands = [AntaCommand(command="show aaa methods authorization")]
+ categories: ClassVar[list[str]] = ["aaa"]
+ commands: ClassVar[list[AntaCommand | AntaTemplate]] = [AntaCommand(command="show aaa methods authorization", revision=1)]
+
+ class Input(AntaTest.Input):
+ """Input model for the VerifyAuthzMethods test."""
- class Input(AntaTest.Input): # pylint: disable=missing-class-docstring
- methods: List[AAAAuthMethod]
- """List of AAA authorization methods. Methods should be in the right order"""
- types: Set[Literal["commands", "exec"]]
- """List of authorization types to verify"""
+ methods: list[AAAAuthMethod]
+ """List of AAA authorization methods. Methods should be in the right order."""
+ types: set[Literal["commands", "exec"]]
+ """List of authorization types to verify."""
@AntaTest.anta_test
def test(self) -> None:
+ """Main test function for VerifyAuthzMethods."""
command_output = self.instance_commands[0].json_output
- not_matching = []
+ not_matching: list[str] = []
for k, v in command_output.items():
authz_type = k.replace("AuthzMethods", "")
if authz_type not in self.inputs.types:
# We do not need to verify this accounting type
continue
- for methods in v.values():
- if methods["methods"] != self.inputs.methods:
- not_matching.append(authz_type)
+ not_matching.extend(authz_type for methods in v.values() if methods["methods"] != self.inputs.methods)
+
if not not_matching:
self.result.is_success()
else:
@@ -205,27 +277,46 @@ class VerifyAuthzMethods(AntaTest):
class VerifyAcctDefaultMethods(AntaTest):
- """
- Verifies the AAA accounting default method lists for different accounting types (system, exec, commands, dot1x).
-
- Expected Results:
- * success: The test will pass if the provided AAA accounting default method list is matching in the configured accounting types.
- * failure: The test will fail if the provided AAA accounting default method list is NOT matching in the configured accounting types.
+ """Verifies the AAA accounting default method lists for different accounting types (system, exec, commands, dot1x).
+
+ Expected Results
+ ----------------
+ * Success: The test will pass if the provided AAA accounting default method list is matching in the configured accounting types.
+ * Failure: The test will fail if the provided AAA accounting default method list is NOT matching in the configured accounting types.
+
+ Examples
+ --------
+ ```yaml
+ anta.tests.aaa:
+ - VerifyAcctDefaultMethods:
+ methods:
+ - local
+ - none
+ - logging
+ types:
+ - system
+ - exec
+ - commands
+ - dot1x
+ ```
"""
name = "VerifyAcctDefaultMethods"
description = "Verifies the AAA accounting default method lists for different accounting types (system, exec, commands, dot1x)."
- categories = ["aaa"]
- commands = [AntaCommand(command="show aaa methods accounting")]
+ categories: ClassVar[list[str]] = ["aaa"]
+ commands: ClassVar[list[AntaCommand | AntaTemplate]] = [AntaCommand(command="show aaa methods accounting", revision=1)]
+
+ class Input(AntaTest.Input):
+ """Input model for the VerifyAcctDefaultMethods test."""
- class Input(AntaTest.Input): # pylint: disable=missing-class-docstring
- methods: List[AAAAuthMethod]
- """List of AAA accounting methods. Methods should be in the right order"""
- types: Set[Literal["commands", "exec", "system", "dot1x"]]
- """List of accounting types to verify"""
+ methods: list[AAAAuthMethod]
+ """List of AAA accounting methods. Methods should be in the right order."""
+ types: set[Literal["commands", "exec", "system", "dot1x"]]
+ """List of accounting types to verify."""
@AntaTest.anta_test
def test(self) -> None:
+ """Main test function for VerifyAcctDefaultMethods."""
command_output = self.instance_commands[0].json_output
not_matching = []
not_configured = []
@@ -249,27 +340,46 @@ class VerifyAcctDefaultMethods(AntaTest):
class VerifyAcctConsoleMethods(AntaTest):
- """
- Verifies the AAA accounting console method lists for different accounting types (system, exec, commands, dot1x).
-
- Expected Results:
- * success: The test will pass if the provided AAA accounting console method list is matching in the configured accounting types.
- * failure: The test will fail if the provided AAA accounting console method list is NOT matching in the configured accounting types.
+ """Verifies the AAA accounting console method lists for different accounting types (system, exec, commands, dot1x).
+
+ Expected Results
+ ----------------
+ * Success: The test will pass if the provided AAA accounting console method list is matching in the configured accounting types.
+ * Failure: The test will fail if the provided AAA accounting console method list is NOT matching in the configured accounting types.
+
+ Examples
+ --------
+ ```yaml
+ anta.tests.aaa:
+ - VerifyAcctConsoleMethods:
+ methods:
+ - local
+ - none
+ - logging
+ types:
+ - system
+ - exec
+ - commands
+ - dot1x
+ ```
"""
name = "VerifyAcctConsoleMethods"
description = "Verifies the AAA accounting console method lists for different accounting types (system, exec, commands, dot1x)."
- categories = ["aaa"]
- commands = [AntaCommand(command="show aaa methods accounting")]
+ categories: ClassVar[list[str]] = ["aaa"]
+ commands: ClassVar[list[AntaCommand | AntaTemplate]] = [AntaCommand(command="show aaa methods accounting", revision=1)]
+
+ class Input(AntaTest.Input):
+ """Input model for the VerifyAcctConsoleMethods test."""
- class Input(AntaTest.Input): # pylint: disable=missing-class-docstring
- methods: List[AAAAuthMethod]
- """List of AAA accounting console methods. Methods should be in the right order"""
- types: Set[Literal["commands", "exec", "system", "dot1x"]]
- """List of accounting console types to verify"""
+ methods: list[AAAAuthMethod]
+ """List of AAA accounting console methods. Methods should be in the right order."""
+ types: set[Literal["commands", "exec", "system", "dot1x"]]
+ """List of accounting console types to verify."""
@AntaTest.anta_test
def test(self) -> None:
+ """Main test function for VerifyAcctConsoleMethods."""
command_output = self.instance_commands[0].json_output
not_matching = []
not_configured = []
diff --git a/anta/tests/avt.py b/anta/tests/avt.py
new file mode 100644
index 0000000..d72296a
--- /dev/null
+++ b/anta/tests/avt.py
@@ -0,0 +1,234 @@
+# Copyright (c) 2023-2024 Arista Networks, Inc.
+# Use of this source code is governed by the Apache License 2.0
+# that can be found in the LICENSE file.
+"""Module related to Adaptive virtual topology tests."""
+
+# Mypy does not understand AntaTest.Input typing
+# mypy: disable-error-code=attr-defined
+from __future__ import annotations
+
+from ipaddress import IPv4Address
+from typing import ClassVar
+
+from pydantic import BaseModel
+
+from anta.decorators import skip_on_platforms
+from anta.models import AntaCommand, AntaTemplate, AntaTest
+from anta.tools import get_value
+
+
+class VerifyAVTPathHealth(AntaTest):
+ """
+ Verifies the status of all Adaptive Virtual Topology (AVT) paths for all VRFs.
+
+ Expected Results
+ ----------------
+ * Success: The test will pass if all AVT paths for all VRFs are active and valid.
+ * Failure: The test will fail if the AVT path is not configured or if any AVT path under any VRF is either inactive or invalid.
+
+ Examples
+ --------
+ ```yaml
+ anta.tests.avt:
+ - VerifyAVTPathHealth:
+ ```
+ """
+
+ name = "VerifyAVTPathHealth"
+ description = "Verifies the status of all AVT paths for all VRFs."
+ categories: ClassVar[list[str]] = ["avt"]
+ commands: ClassVar[list[AntaCommand | AntaTemplate]] = [AntaCommand(command="show adaptive-virtual-topology path")]
+
+ @skip_on_platforms(["cEOSLab", "vEOS-lab"])
+ @AntaTest.anta_test
+ def test(self) -> None:
+ """Main test function for VerifyAVTPathHealth."""
+ # Initialize the test result as success
+ self.result.is_success()
+
+ # Get the command output
+ command_output = self.instance_commands[0].json_output.get("vrfs", {})
+
+ # Check if AVT is configured
+ if not command_output:
+ self.result.is_failure("Adaptive virtual topology paths are not configured.")
+ return
+
+ # Iterate over each VRF
+ for vrf, vrf_data in command_output.items():
+ # Iterate over each AVT path
+ for profile, avt_path in vrf_data.get("avts", {}).items():
+ for path, flags in avt_path.get("avtPaths", {}).items():
+ # Get the status of the AVT path
+ valid = flags["flags"]["valid"]
+ active = flags["flags"]["active"]
+
+ # Check the status of the AVT path
+ if not valid and not active:
+ self.result.is_failure(f"AVT path {path} for profile {profile} in VRF {vrf} is invalid and not active.")
+ elif not valid:
+ self.result.is_failure(f"AVT path {path} for profile {profile} in VRF {vrf} is invalid.")
+ elif not active:
+ self.result.is_failure(f"AVT path {path} for profile {profile} in VRF {vrf} is not active.")
+
+
+class VerifyAVTSpecificPath(AntaTest):
+ """
+ Verifies the status and type of an Adaptive Virtual Topology (AVT) path for a specified VRF.
+
+ Expected Results
+ ----------------
+ * Success: The test will pass if all AVT paths for the specified VRF are active, valid, and match the specified type (direct/multihop) if provided.
+ If multiple paths are configured, the test will pass only if all the paths are valid and active.
+ * Failure: The test will fail if no AVT paths are configured for the specified VRF, or if any configured path is not active, valid,
+ or does not match the specified type.
+
+ Examples
+ --------
+ ```yaml
+ anta.tests.avt:
+ - VerifyAVTSpecificPath:
+ avt_paths:
+ - avt_name: CONTROL-PLANE-PROFILE
+ vrf: default
+ destination: 10.101.255.2
+ next_hop: 10.101.255.1
+ path_type: direct
+ ```
+ """
+
+ name = "VerifyAVTSpecificPath"
+ description = "Verifies the status and type of an AVT path for a specified VRF."
+ categories: ClassVar[list[str]] = ["avt"]
+ commands: ClassVar[list[AntaCommand | AntaTemplate]] = [
+ AntaTemplate(template="show adaptive-virtual-topology path vrf {vrf} avt {avt_name} destination {destination}")
+ ]
+
+ class Input(AntaTest.Input):
+ """Input model for the VerifyAVTSpecificPath test."""
+
+ avt_paths: list[AVTPaths]
+ """List of AVT paths to verify."""
+
+ class AVTPaths(BaseModel):
+ """Model for the details of AVT paths."""
+
+ vrf: str = "default"
+ """The VRF for the AVT path. Defaults to 'default' if not provided."""
+ avt_name: str
+ """Name of the adaptive virtual topology."""
+ destination: IPv4Address
+ """The IPv4 address of the AVT peer."""
+ next_hop: IPv4Address
+ """The IPv4 address of the next hop for the AVT peer."""
+ path_type: str | None = None
+ """The type of the AVT path. If not provided, both 'direct' and 'multihop' paths are considered."""
+
+ def render(self, template: AntaTemplate) -> list[AntaCommand]:
+ """Render the template for each input AVT path/peer."""
+ return [template.render(vrf=path.vrf, avt_name=path.avt_name, destination=path.destination) for path in self.inputs.avt_paths]
+
+ @skip_on_platforms(["cEOSLab", "vEOS-lab"])
+ @AntaTest.anta_test
+ def test(self) -> None:
+ """Main test function for VerifyAVTSpecificPath."""
+ # Assume the test is successful until a failure is detected
+ self.result.is_success()
+
+ # Process each command in the instance
+ for command, input_avt in zip(self.instance_commands, self.inputs.avt_paths):
+ # Extract the command output and parameters
+ vrf = command.params.vrf
+ avt_name = command.params.avt_name
+ peer = str(command.params.destination)
+
+ command_output = command.json_output.get("vrfs", {})
+
+ # If no AVT is configured, mark the test as failed and skip to the next command
+ if not command_output:
+ self.result.is_failure(f"AVT configuration for peer '{peer}' under topology '{avt_name}' in VRF '{vrf}' is not found.")
+ continue
+
+ # Extract the AVT paths
+ avt_paths = get_value(command_output, f"{vrf}.avts.{avt_name}.avtPaths")
+ next_hop, input_path_type = str(input_avt.next_hop), input_avt.path_type
+
+ nexthop_path_found = path_type_found = False
+
+ # Check each AVT path
+ for path, path_data in avt_paths.items():
+ # If the path does not match the expected next hop, skip to the next path
+ if path_data.get("nexthopAddr") != next_hop:
+ continue
+
+ nexthop_path_found = True
+ path_type = "direct" if get_value(path_data, "flags.directPath") else "multihop"
+
+ # If the path type does not match the expected path type, skip to the next path
+ if input_path_type and path_type != input_path_type:
+ continue
+
+ path_type_found = True
+ valid = get_value(path_data, "flags.valid")
+ active = get_value(path_data, "flags.active")
+
+ # Check the path status and type against the expected values
+ if not all([valid, active]):
+ failure_reasons = []
+ if not get_value(path_data, "flags.active"):
+ failure_reasons.append("inactive")
+ if not get_value(path_data, "flags.valid"):
+ failure_reasons.append("invalid")
+ # Construct the failure message prefix
+ failed_log = f"AVT path '{path}' for topology '{avt_name}' in VRF '{vrf}'"
+ self.result.is_failure(f"{failed_log} is {', '.join(failure_reasons)}.")
+
+ # If no matching next hop or path type was found, mark the test as failed
+ if not nexthop_path_found or not path_type_found:
+ self.result.is_failure(
+ f"No '{input_path_type}' path found with next-hop address '{next_hop}' for AVT peer '{peer}' under topology '{avt_name}' in VRF '{vrf}'."
+ )
+
+
+class VerifyAVTRole(AntaTest):
+ """
+ Verifies the Adaptive Virtual Topology (AVT) role of a device.
+
+ Expected Results
+ ----------------
+ * Success: The test will pass if the AVT role of the device matches the expected role.
+ * Failure: The test will fail if the AVT is not configured or if the AVT role does not match the expected role.
+
+ Examples
+ --------
+ ```yaml
+ anta.tests.avt:
+ - VerifyAVTRole:
+ role: edge
+ ```
+ """
+
+ name = "VerifyAVTRole"
+ description = "Verifies the AVT role of a device."
+ categories: ClassVar[list[str]] = ["avt"]
+ commands: ClassVar[list[AntaCommand | AntaTemplate]] = [AntaCommand(command="show adaptive-virtual-topology path")]
+
+ class Input(AntaTest.Input):
+ """Input model for the VerifyAVTRole test."""
+
+ role: str
+ """Expected AVT role of the device."""
+
+ @skip_on_platforms(["cEOSLab", "vEOS-lab"])
+ @AntaTest.anta_test
+ def test(self) -> None:
+ """Main test function for VerifyAVTRole."""
+ # Initialize the test result as success
+ self.result.is_success()
+
+ # Get the command output
+ command_output = self.instance_commands[0].json_output
+
+ # Check if the AVT role matches the expected role
+ if self.inputs.role != command_output.get("role"):
+ self.result.is_failure(f"Expected AVT role as `{self.inputs.role}`, but found `{command_output.get('role')}` instead.")
diff --git a/anta/tests/bfd.py b/anta/tests/bfd.py
index aea8d07..f19e9cc 100644
--- a/anta/tests/bfd.py
+++ b/anta/tests/bfd.py
@@ -1,65 +1,80 @@
# Copyright (c) 2023-2024 Arista Networks, Inc.
# Use of this source code is governed by the Apache License 2.0
# that can be found in the LICENSE file.
-"""
-BFD test functions
-"""
+"""Module related to BFD tests."""
+
# Mypy does not understand AntaTest.Input typing
# mypy: disable-error-code=attr-defined
from __future__ import annotations
-from datetime import datetime
+from datetime import datetime, timezone
from ipaddress import IPv4Address
-from typing import Any, List, Optional
+from typing import TYPE_CHECKING, Any, ClassVar
from pydantic import BaseModel, Field
from anta.custom_types import BfdInterval, BfdMultiplier
from anta.models import AntaCommand, AntaTest
-from anta.tools.get_value import get_value
+from anta.tools import get_value
+if TYPE_CHECKING:
+ from anta.models import AntaTemplate
-class VerifyBFDSpecificPeers(AntaTest):
- """
- This class verifies if the IPv4 BFD peer's sessions are UP and remote disc is non-zero in the specified VRF.
- Expected results:
- * success: The test will pass if IPv4 BFD peers are up and remote disc is non-zero in the specified VRF.
- * failure: The test will fail if IPv4 BFD peers are not found, the status is not UP or remote disc is zero in the specified VRF.
+class VerifyBFDSpecificPeers(AntaTest):
+ """Verifies if the IPv4 BFD peer's sessions are UP and remote disc is non-zero in the specified VRF.
+
+ Expected Results
+ ----------------
+ * Success: The test will pass if IPv4 BFD peers are up and remote disc is non-zero in the specified VRF.
+ * Failure: The test will fail if IPv4 BFD peers are not found, the status is not UP or remote disc is zero in the specified VRF.
+
+ Examples
+ --------
+ ```yaml
+ anta.tests.bfd:
+ - VerifyBFDSpecificPeers:
+ bfd_peers:
+ - peer_address: 192.0.255.8
+ vrf: default
+ - peer_address: 192.0.255.7
+ vrf: default
+ ```
"""
name = "VerifyBFDSpecificPeers"
description = "Verifies the IPv4 BFD peer's sessions and remote disc in the specified VRF."
- categories = ["bfd"]
- commands = [AntaCommand(command="show bfd peers")]
+ categories: ClassVar[list[str]] = ["bfd"]
+ commands: ClassVar[list[AntaCommand | AntaTemplate]] = [AntaCommand(command="show bfd peers", revision=4)]
class Input(AntaTest.Input):
- """
- This class defines the input parameters of the test case.
- """
+ """Input model for the VerifyBFDSpecificPeers test."""
- bfd_peers: List[BFDPeers]
- """List of IPv4 BFD peers"""
+ bfd_peers: list[BFDPeer]
+ """List of IPv4 BFD peers."""
- class BFDPeers(BaseModel):
- """
- This class defines the details of an IPv4 BFD peer.
- """
+ class BFDPeer(BaseModel):
+ """Model for an IPv4 BFD peer."""
peer_address: IPv4Address
- """IPv4 address of a BFD peer"""
+ """IPv4 address of a BFD peer."""
vrf: str = "default"
- """Optional VRF for BGP peer. If not provided, it defaults to `default`."""
+ """Optional VRF for BFD peer. If not provided, it defaults to `default`."""
@AntaTest.anta_test
def test(self) -> None:
+ """Main test function for VerifyBFDSpecificPeers."""
failures: dict[Any, Any] = {}
# Iterating over BFD peers
for bfd_peer in self.inputs.bfd_peers:
peer = str(bfd_peer.peer_address)
vrf = bfd_peer.vrf
- bfd_output = get_value(self.instance_commands[0].json_output, f"vrfs..{vrf}..ipv4Neighbors..{peer}..peerStats..", separator="..")
+ bfd_output = get_value(
+ self.instance_commands[0].json_output,
+ f"vrfs..{vrf}..ipv4Neighbors..{peer}..peerStats..",
+ separator="..",
+ )
# Check if BFD peer configured
if not bfd_output:
@@ -68,7 +83,12 @@ class VerifyBFDSpecificPeers(AntaTest):
# Check BFD peer status and remote disc
if not (bfd_output.get("status") == "up" and bfd_output.get("remoteDisc") != 0):
- failures[peer] = {vrf: {"status": bfd_output.get("status"), "remote_disc": bfd_output.get("remoteDisc")}}
+ failures[peer] = {
+ vrf: {
+ "status": bfd_output.get("status"),
+ "remote_disc": bfd_output.get("remoteDisc"),
+ }
+ }
if not failures:
self.result.is_success()
@@ -77,45 +97,60 @@ class VerifyBFDSpecificPeers(AntaTest):
class VerifyBFDPeersIntervals(AntaTest):
- """
- This class verifies the timers of the IPv4 BFD peers in the specified VRF.
-
- Expected results:
- * success: The test will pass if the timers of the IPv4 BFD peers are correct in the specified VRF.
- * failure: The test will fail if the IPv4 BFD peers are not found or their timers are incorrect in the specified VRF.
+ """Verifies the timers of the IPv4 BFD peers in the specified VRF.
+
+ Expected Results
+ ----------------
+ * Success: The test will pass if the timers of the IPv4 BFD peers are correct in the specified VRF.
+ * Failure: The test will fail if the IPv4 BFD peers are not found or their timers are incorrect in the specified VRF.
+
+ Examples
+ --------
+ ```yaml
+ anta.tests.bfd:
+ - VerifyBFDPeersIntervals:
+ bfd_peers:
+ - peer_address: 192.0.255.8
+ vrf: default
+ tx_interval: 1200
+ rx_interval: 1200
+ multiplier: 3
+ - peer_address: 192.0.255.7
+ vrf: default
+ tx_interval: 1200
+ rx_interval: 1200
+ multiplier: 3
+ ```
"""
name = "VerifyBFDPeersIntervals"
description = "Verifies the timers of the IPv4 BFD peers in the specified VRF."
- categories = ["bfd"]
- commands = [AntaCommand(command="show bfd peers detail")]
+ categories: ClassVar[list[str]] = ["bfd"]
+ commands: ClassVar[list[AntaCommand | AntaTemplate]] = [AntaCommand(command="show bfd peers detail", revision=4)]
class Input(AntaTest.Input):
- """
- This class defines the input parameters of the test case.
- """
+ """Input model for the VerifyBFDPeersIntervals test."""
- bfd_peers: List[BFDPeers]
- """List of BFD peers"""
+ bfd_peers: list[BFDPeer]
+ """List of BFD peers."""
- class BFDPeers(BaseModel):
- """
- This class defines the details of an IPv4 BFD peer.
- """
+ class BFDPeer(BaseModel):
+ """Model for an IPv4 BFD peer."""
peer_address: IPv4Address
- """IPv4 address of a BFD peer"""
+ """IPv4 address of a BFD peer."""
vrf: str = "default"
- """Optional VRF for BGP peer. If not provided, it defaults to `default`."""
+ """Optional VRF for BFD peer. If not provided, it defaults to `default`."""
tx_interval: BfdInterval
- """Tx interval of BFD peer in milliseconds"""
+ """Tx interval of BFD peer in milliseconds."""
rx_interval: BfdInterval
- """Rx interval of BFD peer in milliseconds"""
+ """Rx interval of BFD peer in milliseconds."""
multiplier: BfdMultiplier
- """Multiplier of BFD peer"""
+ """Multiplier of BFD peer."""
@AntaTest.anta_test
def test(self) -> None:
+ """Main test function for VerifyBFDPeersIntervals."""
failures: dict[Any, Any] = {}
# Iterating over BFD peers
@@ -127,7 +162,11 @@ class VerifyBFDPeersIntervals(AntaTest):
tx_interval = bfd_peers.tx_interval * 1000
rx_interval = bfd_peers.rx_interval * 1000
multiplier = bfd_peers.multiplier
- bfd_output = get_value(self.instance_commands[0].json_output, f"vrfs..{vrf}..ipv4Neighbors..{peer}..peerStats..", separator="..")
+ bfd_output = get_value(
+ self.instance_commands[0].json_output,
+ f"vrfs..{vrf}..ipv4Neighbors..{peer}..peerStats..",
+ separator="..",
+ )
# Check if BFD peer configured
if not bfd_output:
@@ -157,35 +196,46 @@ class VerifyBFDPeersIntervals(AntaTest):
class VerifyBFDPeersHealth(AntaTest):
- """
- This class verifies the health of IPv4 BFD peers across all VRFs.
+ """Verifies the health of IPv4 BFD peers across all VRFs.
It checks that no BFD peer is in the down state and that the discriminator value of the remote system is not zero.
+
Optionally, it can also verify that BFD peers have not been down before a specified threshold of hours.
- Expected results:
- * Success: The test will pass if all IPv4 BFD peers are up, the discriminator value of each remote system is non-zero,
- and the last downtime of each peer is above the defined threshold.
- * Failure: The test will fail if any IPv4 BFD peer is down, the discriminator value of any remote system is zero,
- or the last downtime of any peer is below the defined threshold.
+ Expected Results
+ ----------------
+ * Success: The test will pass if all IPv4 BFD peers are up, the discriminator value of each remote system is non-zero,
+ and the last downtime of each peer is above the defined threshold.
+ * Failure: The test will fail if any IPv4 BFD peer is down, the discriminator value of any remote system is zero,
+ or the last downtime of any peer is below the defined threshold.
+
+ Examples
+ --------
+ ```yaml
+ anta.tests.bfd:
+ - VerifyBFDPeersHealth:
+ down_threshold: 2
+ ```
"""
name = "VerifyBFDPeersHealth"
description = "Verifies the health of all IPv4 BFD peers."
- categories = ["bfd"]
+ categories: ClassVar[list[str]] = ["bfd"]
# revision 1 as later revision introduces additional nesting for type
- commands = [AntaCommand(command="show bfd peers", revision=1), AntaCommand(command="show clock")]
+ commands: ClassVar[list[AntaCommand | AntaTemplate]] = [
+ AntaCommand(command="show bfd peers", revision=1),
+ AntaCommand(command="show clock", revision=1),
+ ]
class Input(AntaTest.Input):
- """
- This class defines the input parameters of the test case.
- """
+ """Input model for the VerifyBFDPeersHealth test."""
- down_threshold: Optional[int] = Field(default=None, gt=0)
+ down_threshold: int | None = Field(default=None, gt=0)
"""Optional down threshold in hours to check if a BFD peer was down before those hours or not."""
@AntaTest.anta_test
def test(self) -> None:
+ """Main test function for VerifyBFDPeersHealth."""
# Initialize failure strings
down_failures = []
up_failures = []
@@ -212,7 +262,9 @@ class VerifyBFDPeersHealth(AntaTest):
remote_disc = peer_data["remoteDisc"]
remote_disc_info = f" with remote disc {remote_disc}" if remote_disc == 0 else ""
last_down = peer_data["lastDown"]
- hours_difference = (datetime.fromtimestamp(current_timestamp) - datetime.fromtimestamp(last_down)).total_seconds() / 3600
+ hours_difference = (
+ datetime.fromtimestamp(current_timestamp, tz=timezone.utc) - datetime.fromtimestamp(last_down, tz=timezone.utc)
+ ).total_seconds() / 3600
# Check if peer status is not up
if peer_status != "up":
diff --git a/anta/tests/configuration.py b/anta/tests/configuration.py
index 060782a..4a1bd31 100644
--- a/anta/tests/configuration.py
+++ b/anta/tests/configuration.py
@@ -1,30 +1,47 @@
# Copyright (c) 2023-2024 Arista Networks, Inc.
# Use of this source code is governed by the Apache License 2.0
# that can be found in the LICENSE file.
-"""
-Test functions related to the device configuration
-"""
+"""Module related to the device configuration tests."""
+
# Mypy does not understand AntaTest.Input typing
# mypy: disable-error-code=attr-defined
from __future__ import annotations
+import re
+from typing import TYPE_CHECKING, ClassVar
+
+from anta.custom_types import RegexString
from anta.models import AntaCommand, AntaTest
+if TYPE_CHECKING:
+ from anta.models import AntaTemplate
+
class VerifyZeroTouch(AntaTest):
- """
- Verifies ZeroTouch is disabled
+ """Verifies ZeroTouch is disabled.
+
+ Expected Results
+ ----------------
+ * Success: The test will pass if ZeroTouch is disabled.
+ * Failure: The test will fail if ZeroTouch is enabled.
+
+ Examples
+ --------
+ ```yaml
+ anta.tests.configuration:
+ - VerifyZeroTouch:
+ ```
"""
name = "VerifyZeroTouch"
description = "Verifies ZeroTouch is disabled"
- categories = ["configuration"]
- commands = [AntaCommand(command="show zerotouch")]
+ categories: ClassVar[list[str]] = ["configuration"]
+ commands: ClassVar[list[AntaCommand | AntaTemplate]] = [AntaCommand(command="show zerotouch", revision=1)]
@AntaTest.anta_test
def test(self) -> None:
- command_output = self.instance_commands[0].output
- assert isinstance(command_output, dict)
+ """Main test function for VerifyZeroTouch."""
+ command_output = self.instance_commands[0].json_output
if command_output["mode"] == "disabled":
self.result.is_success()
else:
@@ -32,20 +49,85 @@ class VerifyZeroTouch(AntaTest):
class VerifyRunningConfigDiffs(AntaTest):
- """
- Verifies there is no difference between the running-config and the startup-config
+ """Verifies there is no difference between the running-config and the startup-config.
+
+ Expected Results
+ ----------------
+ * Success: The test will pass if there is no difference between the running-config and the startup-config.
+ * Failure: The test will fail if there is a difference between the running-config and the startup-config.
+
+ Examples
+ --------
+ ```yaml
+ anta.tests.configuration:
+ - VerifyRunningConfigDiffs:
+ ```
"""
name = "VerifyRunningConfigDiffs"
description = "Verifies there is no difference between the running-config and the startup-config"
- categories = ["configuration"]
- commands = [AntaCommand(command="show running-config diffs", ofmt="text")]
+ categories: ClassVar[list[str]] = ["configuration"]
+ commands: ClassVar[list[AntaCommand | AntaTemplate]] = [AntaCommand(command="show running-config diffs", ofmt="text")]
@AntaTest.anta_test
def test(self) -> None:
- command_output = self.instance_commands[0].output
- if command_output is None or command_output == "":
+ """Main test function for VerifyRunningConfigDiffs."""
+ command_output = self.instance_commands[0].text_output
+ if command_output == "":
+ self.result.is_success()
+ else:
+ self.result.is_failure(command_output)
+
+
+class VerifyRunningConfigLines(AntaTest):
+ """Verifies the given regular expression patterns are present in the running-config.
+
+ !!! warning
+ Since this uses regular expression searches on the whole running-config, it can
+ drastically impact performance and should only be used if no other test is available.
+
+ If possible, try using another ANTA test that is more specific.
+
+ Expected Results
+ ----------------
+ * Success: The test will pass if all the patterns are found in the running-config.
+ * Failure: The test will fail if any of the patterns are NOT found in the running-config.
+
+ Examples
+ --------
+ ```yaml
+ anta.tests.configuration:
+ - VerifyRunningConfigLines:
+ regex_patterns:
+ - "^enable password.*$"
+ - "bla bla"
+ ```
+ """
+
+ name = "VerifyRunningConfigLines"
+ description = "Search the Running-Config for the given RegEx patterns."
+ categories: ClassVar[list[str]] = ["configuration"]
+ commands: ClassVar[list[AntaCommand | AntaTemplate]] = [AntaCommand(command="show running-config", ofmt="text")]
+
+ class Input(AntaTest.Input):
+ """Input model for the VerifyRunningConfigLines test."""
+
+ regex_patterns: list[RegexString]
+ """List of regular expressions."""
+
+ @AntaTest.anta_test
+ def test(self) -> None:
+ """Main test function for VerifyRunningConfigLines."""
+ failure_msgs = []
+ command_output = self.instance_commands[0].text_output
+
+ for pattern in self.inputs.regex_patterns:
+ re_search = re.compile(pattern, flags=re.MULTILINE)
+
+ if not re_search.search(command_output):
+ failure_msgs.append(f"'{pattern}'")
+
+ if not failure_msgs:
self.result.is_success()
else:
- self.result.is_failure()
- self.result.is_failure(str(command_output))
+ self.result.is_failure("Following patterns were not found: " + ",".join(failure_msgs))
diff --git a/anta/tests/connectivity.py b/anta/tests/connectivity.py
index 7222f56..06cf8ea 100644
--- a/anta/tests/connectivity.py
+++ b/anta/tests/connectivity.py
@@ -1,67 +1,79 @@
# Copyright (c) 2023-2024 Arista Networks, Inc.
# Use of this source code is governed by the Apache License 2.0
# that can be found in the LICENSE file.
-"""
-Test functions related to various connectivity checks
-"""
+"""Module related to various connectivity tests."""
+
# Mypy does not understand AntaTest.Input typing
# mypy: disable-error-code=attr-defined
from __future__ import annotations
from ipaddress import IPv4Address
-
-# Need to keep List for pydantic in python 3.8
-from typing import List, Union
+from typing import ClassVar
from pydantic import BaseModel
from anta.custom_types import Interface
-from anta.models import AntaCommand, AntaMissingParamException, AntaTemplate, AntaTest
+from anta.models import AntaCommand, AntaTemplate, AntaTest
class VerifyReachability(AntaTest):
- """
- Test network reachability to one or many destination IP(s).
-
- Expected Results:
- * success: The test will pass if all destination IP(s) are reachable.
- * failure: The test will fail if one or many destination IP(s) are unreachable.
+ """Test network reachability to one or many destination IP(s).
+
+ Expected Results
+ ----------------
+ * Success: The test will pass if all destination IP(s) are reachable.
+ * Failure: The test will fail if one or many destination IP(s) are unreachable.
+
+ Examples
+ --------
+ ```yaml
+ anta.tests.connectivity:
+ - VerifyReachability:
+ hosts:
+ - source: Management0
+ destination: 1.1.1.1
+ vrf: MGMT
+ - source: Management0
+ destination: 8.8.8.8
+ vrf: MGMT
+ ```
"""
name = "VerifyReachability"
description = "Test the network reachability to one or many destination IP(s)."
- categories = ["connectivity"]
- commands = [AntaTemplate(template="ping vrf {vrf} {destination} source {source} repeat {repeat}")]
+ categories: ClassVar[list[str]] = ["connectivity"]
+ commands: ClassVar[list[AntaCommand | AntaTemplate]] = [AntaTemplate(template="ping vrf {vrf} {destination} source {source} repeat {repeat}", revision=1)]
- class Input(AntaTest.Input): # pylint: disable=missing-class-docstring
- hosts: List[Host]
- """List of hosts to ping"""
+ class Input(AntaTest.Input):
+ """Input model for the VerifyReachability test."""
+
+ hosts: list[Host]
+ """List of host to ping."""
class Host(BaseModel):
- """Remote host to ping"""
+ """Model for a remote host to ping."""
destination: IPv4Address
- """IPv4 address to ping"""
- source: Union[IPv4Address, Interface]
- """IPv4 address source IP or Egress interface to use"""
+ """IPv4 address to ping."""
+ source: IPv4Address | Interface
+ """IPv4 address source IP or egress interface to use."""
vrf: str = "default"
- """VRF context"""
+ """VRF context. Defaults to `default`."""
repeat: int = 2
- """Number of ping repetition (default=2)"""
+ """Number of ping repetition. Defaults to 2."""
def render(self, template: AntaTemplate) -> list[AntaCommand]:
+ """Render the template for each host in the input list."""
return [template.render(destination=host.destination, source=host.source, vrf=host.vrf, repeat=host.repeat) for host in self.inputs.hosts]
@AntaTest.anta_test
def test(self) -> None:
+ """Main test function for VerifyReachability."""
failures = []
for command in self.instance_commands:
- src = command.params.get("source")
- dst = command.params.get("destination")
- repeat = command.params.get("repeat")
-
- if any(elem is None for elem in (src, dst, repeat)):
- raise AntaMissingParamException(f"A parameter is missing to execute the test for command {command}")
+ src = command.params.source
+ dst = command.params.destination
+ repeat = command.params.repeat
if f"{repeat} received" not in command.json_output["messages"][0]:
failures.append((str(src), str(dst)))
@@ -73,53 +85,84 @@ class VerifyReachability(AntaTest):
class VerifyLLDPNeighbors(AntaTest):
- """
- This test verifies that the provided LLDP neighbors are present and connected with the correct configuration.
-
- Expected Results:
- * success: The test will pass if each of the provided LLDP neighbors is present and connected to the specified port and device.
- * failure: The test will fail if any of the following conditions are met:
- - The provided LLDP neighbor is not found.
- - The system name or port of the LLDP neighbor does not match the provided information.
+ """Verifies that the provided LLDP neighbors are present and connected with the correct configuration.
+
+ Expected Results
+ ----------------
+ * Success: The test will pass if each of the provided LLDP neighbors is present and connected to the specified port and device.
+ * Failure: The test will fail if any of the following conditions are met:
+ - The provided LLDP neighbor is not found.
+ - The system name or port of the LLDP neighbor does not match the provided information.
+
+ Examples
+ --------
+ ```yaml
+ anta.tests.connectivity:
+ - VerifyLLDPNeighbors:
+ neighbors:
+ - port: Ethernet1
+ neighbor_device: DC1-SPINE1
+ neighbor_port: Ethernet1
+ - port: Ethernet2
+ neighbor_device: DC1-SPINE2
+ neighbor_port: Ethernet1
+ ```
"""
name = "VerifyLLDPNeighbors"
description = "Verifies that the provided LLDP neighbors are connected properly."
- categories = ["connectivity"]
- commands = [AntaCommand(command="show lldp neighbors detail")]
+ categories: ClassVar[list[str]] = ["connectivity"]
+ commands: ClassVar[list[AntaCommand | AntaTemplate]] = [AntaCommand(command="show lldp neighbors detail", revision=1)]
+
+ class Input(AntaTest.Input):
+ """Input model for the VerifyLLDPNeighbors test."""
- class Input(AntaTest.Input): # pylint: disable=missing-class-docstring
- neighbors: List[Neighbor]
- """List of LLDP neighbors"""
+ neighbors: list[Neighbor]
+ """List of LLDP neighbors."""
class Neighbor(BaseModel):
- """LLDP neighbor"""
+ """Model for an LLDP neighbor."""
port: Interface
- """LLDP port"""
+ """LLDP port."""
neighbor_device: str
- """LLDP neighbor device"""
+ """LLDP neighbor device."""
neighbor_port: Interface
- """LLDP neighbor port"""
+ """LLDP neighbor port."""
@AntaTest.anta_test
def test(self) -> None:
- command_output = self.instance_commands[0].json_output
-
+ """Main test function for VerifyLLDPNeighbors."""
failures: dict[str, list[str]] = {}
+ output = self.instance_commands[0].json_output["lldpNeighbors"]
+
for neighbor in self.inputs.neighbors:
- if neighbor.port not in command_output["lldpNeighbors"]:
- failures.setdefault("port_not_configured", []).append(neighbor.port)
- elif len(lldp_neighbor_info := command_output["lldpNeighbors"][neighbor.port]["lldpNeighborInfo"]) == 0:
- failures.setdefault("no_lldp_neighbor", []).append(neighbor.port)
- elif (
- lldp_neighbor_info[0]["systemName"] != neighbor.neighbor_device
- or lldp_neighbor_info[0]["neighborInterfaceInfo"]["interfaceId_v2"] != neighbor.neighbor_port
+ if neighbor.port not in output:
+ failures.setdefault("Port(s) not configured", []).append(neighbor.port)
+ continue
+
+ if len(lldp_neighbor_info := output[neighbor.port]["lldpNeighborInfo"]) == 0:
+ failures.setdefault("No LLDP neighbor(s) on port(s)", []).append(neighbor.port)
+ continue
+
+ if not any(
+ info["systemName"] == neighbor.neighbor_device and info["neighborInterfaceInfo"]["interfaceId_v2"] == neighbor.neighbor_port
+ for info in lldp_neighbor_info
):
- failures.setdefault("wrong_lldp_neighbor", []).append(neighbor.port)
+ neighbors = "\n ".join(
+ [
+ f"{neighbor[0]}_{neighbor[1]}"
+ for neighbor in [(info["systemName"], info["neighborInterfaceInfo"]["interfaceId_v2"]) for info in lldp_neighbor_info]
+ ]
+ )
+ failures.setdefault("Wrong LLDP neighbor(s) on port(s)", []).append(f"{neighbor.port}\n {neighbors}")
if not failures:
self.result.is_success()
else:
- self.result.is_failure(f"The following port(s) have issues: {failures}")
+ failure_messages = []
+ for failure_type, ports in failures.items():
+ ports_str = "\n ".join(ports)
+ failure_messages.append(f"{failure_type}:\n {ports_str}")
+ self.result.is_failure("\n".join(failure_messages))
diff --git a/anta/tests/field_notices.py b/anta/tests/field_notices.py
index 04fdc4d..71a1174 100644
--- a/anta/tests/field_notices.py
+++ b/anta/tests/field_notices.py
@@ -1,33 +1,48 @@
# Copyright (c) 2023-2024 Arista Networks, Inc.
# Use of this source code is governed by the Apache License 2.0
# that can be found in the LICENSE file.
-"""
-Test functions to flag field notices
-"""
+"""Module related to field notices tests."""
+
+from __future__ import annotations
+
+from typing import TYPE_CHECKING, ClassVar
from anta.decorators import skip_on_platforms
from anta.models import AntaCommand, AntaTest
+if TYPE_CHECKING:
+ from anta.models import AntaTemplate
+
class VerifyFieldNotice44Resolution(AntaTest):
- """
- Verifies the device is using an Aboot version that fix the bug discussed
- in the field notice 44 (Aboot manages system settings prior to EOS initialization).
+ """Verifies if the device is using an Aboot version that fixes the bug discussed in the Field Notice 44.
- https://www.arista.com/en/support/advisories-notices/field-notice/8756-field-notice-44
+ Aboot manages system settings prior to EOS initialization.
+
+ Reference: https://www.arista.com/en/support/advisories-notices/field-notice/8756-field-notice-44
+
+ Expected Results
+ ----------------
+ * Success: The test will pass if the device is using an Aboot version that fixes the bug discussed in the Field Notice 44.
+ * Failure: The test will fail if the device is not using an Aboot version that fixes the bug discussed in the Field Notice 44.
+
+ Examples
+ --------
+ ```yaml
+ anta.tests.field_notices:
+ - VerifyFieldNotice44Resolution:
+ ```
"""
name = "VerifyFieldNotice44Resolution"
- description = (
- "Verifies the device is using an Aboot version that fix the bug discussed in the field notice 44 (Aboot manages system settings prior to EOS initialization)"
- )
- categories = ["field notices", "software"]
- commands = [AntaCommand(command="show version detail")]
-
- # TODO maybe implement ONLY ON PLATFORMS instead
- @skip_on_platforms(["cEOSLab", "vEOS-lab"])
+ description = "Verifies that the device is using the correct Aboot version per FN0044."
+ categories: ClassVar[list[str]] = ["field notices"]
+ commands: ClassVar[list[AntaCommand | AntaTemplate]] = [AntaCommand(command="show version detail", revision=1)]
+
+ @skip_on_platforms(["cEOSLab", "vEOS-lab", "cEOSCloudLab"])
@AntaTest.anta_test
def test(self) -> None:
+ """Main test function for VerifyFieldNotice44Resolution."""
command_output = self.instance_commands[0].json_output
devices = [
@@ -79,7 +94,6 @@ class VerifyFieldNotice44Resolution(AntaTest):
variants = ["-SSD-F", "-SSD-R", "-M-F", "-M-R", "-F", "-R"]
model = command_output["modelName"]
- # TODO this list could be a regex
for variant in variants:
model = model.replace(variant, "")
if model not in devices:
@@ -89,33 +103,55 @@ class VerifyFieldNotice44Resolution(AntaTest):
for component in command_output["details"]["components"]:
if component["name"] == "Aboot":
aboot_version = component["version"].split("-")[2]
+ break
+ else:
+ self.result.is_failure("Aboot component not found")
+ return
+
self.result.is_success()
- if aboot_version.startswith("4.0.") and int(aboot_version.split(".")[2]) < 7:
- self.result.is_failure(f"device is running incorrect version of aboot ({aboot_version})")
- elif aboot_version.startswith("4.1.") and int(aboot_version.split(".")[2]) < 1:
- self.result.is_failure(f"device is running incorrect version of aboot ({aboot_version})")
- elif aboot_version.startswith("6.0.") and int(aboot_version.split(".")[2]) < 9:
- self.result.is_failure(f"device is running incorrect version of aboot ({aboot_version})")
- elif aboot_version.startswith("6.1.") and int(aboot_version.split(".")[2]) < 7:
+ incorrect_aboot_version = (
+ aboot_version.startswith("4.0.")
+ and int(aboot_version.split(".")[2]) < 7
+ or aboot_version.startswith("4.1.")
+ and int(aboot_version.split(".")[2]) < 1
+ or (
+ aboot_version.startswith("6.0.")
+ and int(aboot_version.split(".")[2]) < 9
+ or aboot_version.startswith("6.1.")
+ and int(aboot_version.split(".")[2]) < 7
+ )
+ )
+ if incorrect_aboot_version:
self.result.is_failure(f"device is running incorrect version of aboot ({aboot_version})")
class VerifyFieldNotice72Resolution(AntaTest):
- """
- Checks if the device is potentially exposed to Field Notice 72, and if the issue has been mitigated.
+ """Verifies if the device is potentially exposed to Field Notice 72, and if the issue has been mitigated.
+
+ Reference: https://www.arista.com/en/support/advisories-notices/field-notice/17410-field-notice-0072
+
+ Expected Results
+ ----------------
+ * Success: The test will pass if the device is not exposed to FN72 and the issue has been mitigated.
+ * Failure: The test will fail if the device is exposed to FN72 and the issue has not been mitigated.
- https://www.arista.com/en/support/advisories-notices/field-notice/17410-field-notice-0072
+ Examples
+ --------
+ ```yaml
+ anta.tests.field_notices:
+ - VerifyFieldNotice72Resolution:
+ ```
"""
name = "VerifyFieldNotice72Resolution"
- description = "Verifies if the device has exposeure to FN72, and if the issue has been mitigated"
- categories = ["field notices", "software"]
- commands = [AntaCommand(command="show version detail")]
+ description = "Verifies if the device is exposed to FN0072, and if the issue has been mitigated."
+ categories: ClassVar[list[str]] = ["field notices"]
+ commands: ClassVar[list[AntaCommand | AntaTemplate]] = [AntaCommand(command="show version detail", revision=1)]
- # TODO maybe implement ONLY ON PLATFORMS instead
- @skip_on_platforms(["cEOSLab", "vEOS-lab"])
+ @skip_on_platforms(["cEOSLab", "vEOS-lab", "cEOSCloudLab"])
@AntaTest.anta_test
def test(self) -> None:
+ """Main test function for VerifyFieldNotice72Resolution."""
command_output = self.instance_commands[0].json_output
devices = ["DCS-7280SR3-48YC8", "DCS-7280SR3K-48YC8"]
@@ -151,8 +187,7 @@ class VerifyFieldNotice72Resolution(AntaTest):
self.result.is_skipped("Device not exposed")
return
- # Because each of the if checks above will return if taken, we only run the long
- # check if we get this far
+ # Because each of the if checks above will return if taken, we only run the long check if we get this far
for entry in command_output["details"]["components"]:
if entry["name"] == "FixedSystemvrm1":
if int(entry["version"]) < 7:
@@ -161,5 +196,4 @@ class VerifyFieldNotice72Resolution(AntaTest):
self.result.is_success("FN72 is mitigated")
return
# We should never hit this point
- self.result.is_error(message="Error in running test - FixedSystemvrm1 not found")
- return
+ self.result.is_error("Error in running test - FixedSystemvrm1 not found")
diff --git a/anta/tests/greent.py b/anta/tests/greent.py
index 26271cd..b763242 100644
--- a/anta/tests/greent.py
+++ b/anta/tests/greent.py
@@ -1,60 +1,79 @@
# Copyright (c) 2023-2024 Arista Networks, Inc.
# Use of this source code is governed by the Apache License 2.0
# that can be found in the LICENSE file.
-"""
-Test functions related to GreenT (Postcard Telemetry) in EOS
-"""
+"""Module related to GreenT (Postcard Telemetry) tests."""
+
from __future__ import annotations
+from typing import TYPE_CHECKING, ClassVar
+
from anta.models import AntaCommand, AntaTest
+if TYPE_CHECKING:
+ from anta.models import AntaTemplate
+
class VerifyGreenTCounters(AntaTest):
- """
- Verifies whether GRE packets are sent.
+ """Verifies if the GreenT (GRE Encapsulated Telemetry) counters are incremented.
- Expected Results:
- * success: if >0 gre packets are sent
- * failure: if no gre packets are sent
+ Expected Results
+ ----------------
+ * Success: The test will pass if the GreenT counters are incremented.
+ * Failure: The test will fail if the GreenT counters are not incremented.
+
+ Examples
+ --------
+ ```yaml
+ anta.tests.greent:
+ - VerifyGreenT:
+ ```
"""
name = "VerifyGreenTCounters"
- description = "Verifies if the greent counters are incremented."
- categories = ["greent"]
- commands = [AntaCommand(command="show monitor telemetry postcard counters")]
+ description = "Verifies if the GreenT counters are incremented."
+ categories: ClassVar[list[str]] = ["greent"]
+ commands: ClassVar[list[AntaCommand | AntaTemplate]] = [AntaCommand(command="show monitor telemetry postcard counters", revision=1)]
@AntaTest.anta_test
def test(self) -> None:
+ """Main test function for VerifyGreenTCounters."""
command_output = self.instance_commands[0].json_output
if command_output["grePktSent"] > 0:
self.result.is_success()
else:
- self.result.is_failure("GRE packets are not sent")
+ self.result.is_failure("GreenT counters are not incremented")
class VerifyGreenT(AntaTest):
- """
- Verifies whether GreenT policy is created.
+ """Verifies if a GreenT (GRE Encapsulated Telemetry) policy other than the default is created.
- Expected Results:
- * success: if there exists any policy other than "default" policy.
- * failure: if no policy is created.
+ Expected Results
+ ----------------
+ * Success: The test will pass if a GreenT policy is created other than the default one.
+ * Failure: The test will fail if no other GreenT policy is created.
+
+ Examples
+ --------
+ ```yaml
+ anta.tests.greent:
+ - VerifyGreenTCounters:
+ ```
"""
name = "VerifyGreenT"
- description = "Verifies whether greent policy is created."
- categories = ["greent"]
- commands = [AntaCommand(command="show monitor telemetry postcard policy profile")]
+ description = "Verifies if a GreenT policy is created."
+ categories: ClassVar[list[str]] = ["greent"]
+ commands: ClassVar[list[AntaCommand | AntaTemplate]] = [AntaCommand(command="show monitor telemetry postcard policy profile", revision=1)]
@AntaTest.anta_test
def test(self) -> None:
+ """Main test function for VerifyGreenT."""
command_output = self.instance_commands[0].json_output
- out = [f"{i} policy is created" for i in command_output["profiles"].keys() if "default" not in i]
+ profiles = [profile for profile in command_output["profiles"] if profile != "default"]
- if len(out) > 0:
- for i in out:
- self.result.is_success(f"{i} policy is created")
+ if profiles:
+ self.result.is_success()
else:
- self.result.is_failure("policy is not created")
+ self.result.is_failure("No GreenT policy is created")
diff --git a/anta/tests/hardware.py b/anta/tests/hardware.py
index 0a149f2..569c180 100644
--- a/anta/tests/hardware.py
+++ b/anta/tests/hardware.py
@@ -1,41 +1,56 @@
# Copyright (c) 2023-2024 Arista Networks, Inc.
# Use of this source code is governed by the Apache License 2.0
# that can be found in the LICENSE file.
-"""
-Test functions related to the hardware or environment
-"""
+"""Module related to the hardware or environment tests."""
+
# Mypy does not understand AntaTest.Input typing
# mypy: disable-error-code=attr-defined
from __future__ import annotations
-# Need to keep List for pydantic in python 3.8
-from typing import List
+from typing import TYPE_CHECKING, ClassVar
from anta.decorators import skip_on_platforms
from anta.models import AntaCommand, AntaTest
+if TYPE_CHECKING:
+ from anta.models import AntaTemplate
-class VerifyTransceiversManufacturers(AntaTest):
- """
- This test verifies if all the transceivers come from approved manufacturers.
- Expected Results:
- * success: The test will pass if all transceivers are from approved manufacturers.
- * failure: The test will fail if some transceivers are from unapproved manufacturers.
+class VerifyTransceiversManufacturers(AntaTest):
+ """Verifies if all the transceivers come from approved manufacturers.
+
+ Expected Results
+ ----------------
+ * Success: The test will pass if all transceivers are from approved manufacturers.
+ * Failure: The test will fail if some transceivers are from unapproved manufacturers.
+
+ Examples
+ --------
+ ```yaml
+ anta.tests.hardware:
+ - VerifyTransceiversManufacturers:
+ manufacturers:
+ - Not Present
+ - Arista Networks
+ - Arastra, Inc.
+ ```
"""
name = "VerifyTransceiversManufacturers"
description = "Verifies if all transceivers come from approved manufacturers."
- categories = ["hardware"]
- commands = [AntaCommand(command="show inventory", ofmt="json")]
+ categories: ClassVar[list[str]] = ["hardware"]
+ commands: ClassVar[list[AntaCommand | AntaTemplate]] = [AntaCommand(command="show inventory", revision=2)]
+
+ class Input(AntaTest.Input):
+ """Input model for the VerifyTransceiversManufacturers test."""
- class Input(AntaTest.Input): # pylint: disable=missing-class-docstring
- manufacturers: List[str]
- """List of approved transceivers manufacturers"""
+ manufacturers: list[str]
+ """List of approved transceivers manufacturers."""
- @skip_on_platforms(["cEOSLab", "vEOS-lab"])
+ @skip_on_platforms(["cEOSLab", "vEOS-lab", "cEOSCloudLab"])
@AntaTest.anta_test
def test(self) -> None:
+ """Main test function for VerifyTransceiversManufacturers."""
command_output = self.instance_commands[0].json_output
wrong_manufacturers = {
interface: value["mfgName"] for interface, value in command_output["xcvrSlots"].items() if value["mfgName"] not in self.inputs.manufacturers
@@ -47,24 +62,32 @@ class VerifyTransceiversManufacturers(AntaTest):
class VerifyTemperature(AntaTest):
- """
- This test verifies if the device temperature is within acceptable limits.
-
- Expected Results:
- * success: The test will pass if the device temperature is currently OK: 'temperatureOk'.
- * failure: The test will fail if the device temperature is NOT OK.
+ """Verifies if the device temperature is within acceptable limits.
+
+ Expected Results
+ ----------------
+ * Success: The test will pass if the device temperature is currently OK: 'temperatureOk'.
+ * Failure: The test will fail if the device temperature is NOT OK.
+
+ Examples
+ --------
+ ```yaml
+ anta.tests.hardware:
+ - VerifyTemperature:
+ ```
"""
name = "VerifyTemperature"
description = "Verifies the device temperature."
- categories = ["hardware"]
- commands = [AntaCommand(command="show system environment temperature", ofmt="json")]
+ categories: ClassVar[list[str]] = ["hardware"]
+ commands: ClassVar[list[AntaCommand | AntaTemplate]] = [AntaCommand(command="show system environment temperature", revision=1)]
- @skip_on_platforms(["cEOSLab", "vEOS-lab"])
+ @skip_on_platforms(["cEOSLab", "vEOS-lab", "cEOSCloudLab"])
@AntaTest.anta_test
def test(self) -> None:
+ """Main test function for VerifyTemperature."""
command_output = self.instance_commands[0].json_output
- temperature_status = command_output["systemStatus"] if "systemStatus" in command_output.keys() else ""
+ temperature_status = command_output.get("systemStatus", "")
if temperature_status == "temperatureOk":
self.result.is_success()
else:
@@ -72,24 +95,32 @@ class VerifyTemperature(AntaTest):
class VerifyTransceiversTemperature(AntaTest):
- """
- This test verifies if all the transceivers are operating at an acceptable temperature.
-
- Expected Results:
- * success: The test will pass if all transceivers status are OK: 'ok'.
- * failure: The test will fail if some transceivers are NOT OK.
+ """Verifies if all the transceivers are operating at an acceptable temperature.
+
+ Expected Results
+ ----------------
+ * Success: The test will pass if all transceivers status are OK: 'ok'.
+ * Failure: The test will fail if some transceivers are NOT OK.
+
+ Examples
+ --------
+ ```yaml
+ anta.tests.hardware:
+ - VerifyTransceiversTemperature:
+ ```
"""
name = "VerifyTransceiversTemperature"
description = "Verifies the transceivers temperature."
- categories = ["hardware"]
- commands = [AntaCommand(command="show system environment temperature transceiver", ofmt="json")]
+ categories: ClassVar[list[str]] = ["hardware"]
+ commands: ClassVar[list[AntaCommand | AntaTemplate]] = [AntaCommand(command="show system environment temperature transceiver", revision=1)]
- @skip_on_platforms(["cEOSLab", "vEOS-lab"])
+ @skip_on_platforms(["cEOSLab", "vEOS-lab", "cEOSCloudLab"])
@AntaTest.anta_test
def test(self) -> None:
+ """Main test function for VerifyTransceiversTemperature."""
command_output = self.instance_commands[0].json_output
- sensors = command_output["tempSensors"] if "tempSensors" in command_output.keys() else ""
+ sensors = command_output.get("tempSensors", "")
wrong_sensors = {
sensor["name"]: {
"hwStatus": sensor["hwStatus"],
@@ -105,50 +136,70 @@ class VerifyTransceiversTemperature(AntaTest):
class VerifyEnvironmentSystemCooling(AntaTest):
- """
- This test verifies the device's system cooling.
-
- Expected Results:
- * success: The test will pass if the system cooling status is OK: 'coolingOk'.
- * failure: The test will fail if the system cooling status is NOT OK.
+ """Verifies the device's system cooling status.
+
+ Expected Results
+ ----------------
+ * Success: The test will pass if the system cooling status is OK: 'coolingOk'.
+ * Failure: The test will fail if the system cooling status is NOT OK.
+
+ Examples
+ --------
+ ```yaml
+ anta.tests.hardware:
+ - VerifyEnvironmentSystemCooling:
+ ```
"""
name = "VerifyEnvironmentSystemCooling"
description = "Verifies the system cooling status."
- categories = ["hardware"]
- commands = [AntaCommand(command="show system environment cooling", ofmt="json")]
+ categories: ClassVar[list[str]] = ["hardware"]
+ commands: ClassVar[list[AntaCommand | AntaTemplate]] = [AntaCommand(command="show system environment cooling", revision=1)]
- @skip_on_platforms(["cEOSLab", "vEOS-lab"])
+ @skip_on_platforms(["cEOSLab", "vEOS-lab", "cEOSCloudLab"])
@AntaTest.anta_test
def test(self) -> None:
+ """Main test function for VerifyEnvironmentSystemCooling."""
command_output = self.instance_commands[0].json_output
- sys_status = command_output["systemStatus"] if "systemStatus" in command_output.keys() else ""
+ sys_status = command_output.get("systemStatus", "")
self.result.is_success()
if sys_status != "coolingOk":
self.result.is_failure(f"Device system cooling is not OK: '{sys_status}'")
class VerifyEnvironmentCooling(AntaTest):
- """
- This test verifies the fans status.
-
- Expected Results:
- * success: The test will pass if the fans status are within the accepted states list.
- * failure: The test will fail if some fans status is not within the accepted states list.
+ """Verifies the status of power supply fans and all fan trays.
+
+ Expected Results
+ ----------------
+ * Success: The test will pass if the fans status are within the accepted states list.
+ * Failure: The test will fail if some fans status is not within the accepted states list.
+
+ Examples
+ --------
+ ```yaml
+ anta.tests.hardware:
+ - VerifyEnvironmentCooling:
+ states:
+ - ok
+ ```
"""
name = "VerifyEnvironmentCooling"
description = "Verifies the status of power supply fans and all fan trays."
- categories = ["hardware"]
- commands = [AntaCommand(command="show system environment cooling", ofmt="json")]
+ categories: ClassVar[list[str]] = ["hardware"]
+ commands: ClassVar[list[AntaCommand | AntaTemplate]] = [AntaCommand(command="show system environment cooling", revision=1)]
- class Input(AntaTest.Input): # pylint: disable=missing-class-docstring
- states: List[str]
- """Accepted states list for fan status"""
+ class Input(AntaTest.Input):
+ """Input model for the VerifyEnvironmentCooling test."""
- @skip_on_platforms(["cEOSLab", "vEOS-lab"])
+ states: list[str]
+ """List of accepted states of fan status."""
+
+ @skip_on_platforms(["cEOSLab", "vEOS-lab", "cEOSCloudLab"])
@AntaTest.anta_test
def test(self) -> None:
+ """Main test function for VerifyEnvironmentCooling."""
command_output = self.instance_commands[0].json_output
self.result.is_success()
# First go through power supplies fans
@@ -164,28 +215,40 @@ class VerifyEnvironmentCooling(AntaTest):
class VerifyEnvironmentPower(AntaTest):
- """
- This test verifies the power supplies status.
-
- Expected Results:
- * success: The test will pass if the power supplies status are within the accepted states list.
- * failure: The test will fail if some power supplies status is not within the accepted states list.
+ """Verifies the power supplies status.
+
+ Expected Results
+ ----------------
+ * Success: The test will pass if the power supplies status are within the accepted states list.
+ * Failure: The test will fail if some power supplies status is not within the accepted states list.
+
+ Examples
+ --------
+ ```yaml
+ anta.tests.hardware:
+ - VerifyEnvironmentPower:
+ states:
+ - ok
+ ```
"""
name = "VerifyEnvironmentPower"
description = "Verifies the power supplies status."
- categories = ["hardware"]
- commands = [AntaCommand(command="show system environment power", ofmt="json")]
+ categories: ClassVar[list[str]] = ["hardware"]
+ commands: ClassVar[list[AntaCommand | AntaTemplate]] = [AntaCommand(command="show system environment power", revision=1)]
+
+ class Input(AntaTest.Input):
+ """Input model for the VerifyEnvironmentPower test."""
- class Input(AntaTest.Input): # pylint: disable=missing-class-docstring
- states: List[str]
- """Accepted states list for power supplies status"""
+ states: list[str]
+ """List of accepted states list of power supplies status."""
- @skip_on_platforms(["cEOSLab", "vEOS-lab"])
+ @skip_on_platforms(["cEOSLab", "vEOS-lab", "cEOSCloudLab"])
@AntaTest.anta_test
def test(self) -> None:
+ """Main test function for VerifyEnvironmentPower."""
command_output = self.instance_commands[0].json_output
- power_supplies = command_output["powerSupplies"] if "powerSupplies" in command_output.keys() else "{}"
+ power_supplies = command_output.get("powerSupplies", "{}")
wrong_power_supplies = {
powersupply: {"state": value["state"]} for powersupply, value in dict(power_supplies).items() if value["state"] not in self.inputs.states
}
@@ -196,24 +259,32 @@ class VerifyEnvironmentPower(AntaTest):
class VerifyAdverseDrops(AntaTest):
- """
- This test verifies if there are no adverse drops on DCS7280E and DCS7500E.
-
- Expected Results:
- * success: The test will pass if there are no adverse drops.
- * failure: The test will fail if there are adverse drops.
+ """Verifies there are no adverse drops on DCS-7280 and DCS-7500 family switches (Arad/Jericho chips).
+
+ Expected Results
+ ----------------
+ * Success: The test will pass if there are no adverse drops.
+ * Failure: The test will fail if there are adverse drops.
+
+ Examples
+ --------
+ ```yaml
+ anta.tests.hardware:
+ - VerifyAdverseDrops:
+ ```
"""
name = "VerifyAdverseDrops"
- description = "Verifies there are no adverse drops on DCS7280E and DCS7500E"
- categories = ["hardware"]
- commands = [AntaCommand(command="show hardware counter drop", ofmt="json")]
+ description = "Verifies there are no adverse drops on DCS-7280 and DCS-7500 family switches."
+ categories: ClassVar[list[str]] = ["hardware"]
+ commands: ClassVar[list[AntaCommand | AntaTemplate]] = [AntaCommand(command="show hardware counter drop", revision=1)]
- @skip_on_platforms(["cEOSLab", "vEOS-lab"])
+ @skip_on_platforms(["cEOSLab", "vEOS-lab", "cEOSCloudLab"])
@AntaTest.anta_test
def test(self) -> None:
+ """Main test function for VerifyAdverseDrops."""
command_output = self.instance_commands[0].json_output
- total_adverse_drop = command_output["totalAdverseDrops"] if "totalAdverseDrops" in command_output.keys() else ""
+ total_adverse_drop = command_output.get("totalAdverseDrops", "")
if total_adverse_drop == 0:
self.result.is_success()
else:
diff --git a/anta/tests/interfaces.py b/anta/tests/interfaces.py
index 4c21a29..dfbf15a 100644
--- a/anta/tests/interfaces.py
+++ b/anta/tests/interfaces.py
@@ -1,78 +1,118 @@
# Copyright (c) 2023-2024 Arista Networks, Inc.
# Use of this source code is governed by the Apache License 2.0
# that can be found in the LICENSE file.
-"""
-Test functions related to the device interfaces
-"""
+"""Module related to the device interfaces tests."""
+
# Mypy does not understand AntaTest.Input typing
# mypy: disable-error-code=attr-defined
from __future__ import annotations
import re
from ipaddress import IPv4Network
+from typing import Any, ClassVar, Literal
-# Need to keep Dict and List for pydantic in python 3.8
-from typing import Any, Dict, List, Literal, Optional
-
-from pydantic import BaseModel, conint
+from pydantic import BaseModel, Field
from pydantic_extra_types.mac_address import MacAddress
-from anta.custom_types import Interface
+from anta import GITHUB_SUGGESTION
+from anta.custom_types import EthernetInterface, Interface, Percent, PositiveInteger
from anta.decorators import skip_on_platforms
from anta.models import AntaCommand, AntaTemplate, AntaTest
-from anta.tools.get_item import get_item
-from anta.tools.get_value import get_value
+from anta.tools import custom_division, get_failed_logs, get_item, get_value
+BPS_GBPS_CONVERSIONS = 1000000000
-class VerifyInterfaceUtilization(AntaTest):
- """
- Verifies interfaces utilization is below 75%.
- Expected Results:
- * success: The test will pass if all interfaces have a usage below 75%.
- * failure: The test will fail if one or more interfaces have a usage above 75%.
+class VerifyInterfaceUtilization(AntaTest):
+ """Verifies that the utilization of interfaces is below a certain threshold.
+
+ Load interval (default to 5 minutes) is defined in device configuration.
+ This test has been implemented for full-duplex interfaces only.
+
+ Expected Results
+ ----------------
+ * Success: The test will pass if all interfaces have a usage below the threshold.
+ * Failure: The test will fail if one or more interfaces have a usage above the threshold.
+ * Error: The test will error out if the device has at least one non full-duplex interface.
+
+ Examples
+ --------
+ ```yaml
+ anta.tests.interfaces:
+ - VerifyInterfaceUtilization:
+ threshold: 70.0
+ ```
"""
name = "VerifyInterfaceUtilization"
- description = "Verifies that all interfaces have a usage below 75%."
- categories = ["interfaces"]
- # TODO - move from text to json if possible
- commands = [AntaCommand(command="show interfaces counters rates", ofmt="text")]
+ description = "Verifies that the utilization of interfaces is below a certain threshold."
+ categories: ClassVar[list[str]] = ["interfaces"]
+ commands: ClassVar[list[AntaCommand | AntaTemplate]] = [
+ AntaCommand(command="show interfaces counters rates", revision=1),
+ AntaCommand(command="show interfaces", revision=1),
+ ]
+
+ class Input(AntaTest.Input):
+ """Input model for the VerifyInterfaceUtilization test."""
+
+ threshold: Percent = 75.0
+ """Interface utilization threshold above which the test will fail. Defaults to 75%."""
@AntaTest.anta_test
def test(self) -> None:
- command_output = self.instance_commands[0].text_output
- wrong_interfaces = {}
- for line in command_output.split("\n")[1:]:
- if len(line) > 0:
- if line.split()[-5] == "-" or line.split()[-2] == "-":
- pass
- elif float(line.split()[-5].replace("%", "")) > 75.0:
- wrong_interfaces[line.split()[0]] = line.split()[-5]
- elif float(line.split()[-2].replace("%", "")) > 75.0:
- wrong_interfaces[line.split()[0]] = line.split()[-2]
- if not wrong_interfaces:
+ """Main test function for VerifyInterfaceUtilization."""
+ duplex_full = "duplexFull"
+ failed_interfaces: dict[str, dict[str, float]] = {}
+ rates = self.instance_commands[0].json_output
+ interfaces = self.instance_commands[1].json_output
+
+ for intf, rate in rates["interfaces"].items():
+ # The utilization logic has been implemented for full-duplex interfaces only
+ if ((duplex := (interface := interfaces["interfaces"][intf]).get("duplex", None)) is not None and duplex != duplex_full) or (
+ (members := interface.get("memberInterfaces", None)) is not None and any(stats["duplex"] != duplex_full for stats in members.values())
+ ):
+ self.result.is_error(f"Interface {intf} or one of its member interfaces is not Full-Duplex. VerifyInterfaceUtilization has not been implemented.")
+ return
+
+ if (bandwidth := interfaces["interfaces"][intf]["bandwidth"]) == 0:
+ self.logger.debug("Interface %s has been ignored due to null bandwidth value", intf)
+ continue
+
+ for bps_rate in ("inBpsRate", "outBpsRate"):
+ usage = rate[bps_rate] / bandwidth * 100
+ if usage > self.inputs.threshold:
+ failed_interfaces.setdefault(intf, {})[bps_rate] = usage
+
+ if not failed_interfaces:
self.result.is_success()
else:
- self.result.is_failure(f"The following interfaces have a usage > 75%: {wrong_interfaces}")
+ self.result.is_failure(f"The following interfaces have a usage > {self.inputs.threshold}%: {failed_interfaces}")
class VerifyInterfaceErrors(AntaTest):
- """
- This test verifies that interfaces error counters are equal to zero.
-
- Expected Results:
- * success: The test will pass if all interfaces have error counters equal to zero.
- * failure: The test will fail if one or more interfaces have non-zero error counters.
+ """Verifies that the interfaces error counters are equal to zero.
+
+ Expected Results
+ ----------------
+ * Success: The test will pass if all interfaces have error counters equal to zero.
+ * Failure: The test will fail if one or more interfaces have non-zero error counters.
+
+ Examples
+ --------
+ ```yaml
+ anta.tests.interfaces:
+ - VerifyInterfaceErrors:
+ ```
"""
name = "VerifyInterfaceErrors"
description = "Verifies there are no interface error counters."
- categories = ["interfaces"]
- commands = [AntaCommand(command="show interfaces counters errors")]
+ categories: ClassVar[list[str]] = ["interfaces"]
+ commands: ClassVar[list[AntaCommand | AntaTemplate]] = [AntaCommand(command="show interfaces counters errors", revision=1)]
@AntaTest.anta_test
def test(self) -> None:
+ """Main test function for VerifyInterfaceErrors."""
command_output = self.instance_commands[0].json_output
wrong_interfaces: list[dict[str, dict[str, int]]] = []
for interface, counters in command_output["interfaceErrorCounters"].items():
@@ -85,25 +125,33 @@ class VerifyInterfaceErrors(AntaTest):
class VerifyInterfaceDiscards(AntaTest):
- """
- Verifies interfaces packet discard counters are equal to zero.
-
- Expected Results:
- * success: The test will pass if all interfaces have discard counters equal to zero.
- * failure: The test will fail if one or more interfaces have non-zero discard counters.
+ """Verifies that the interfaces packet discard counters are equal to zero.
+
+ Expected Results
+ ----------------
+ * Success: The test will pass if all interfaces have discard counters equal to zero.
+ * Failure: The test will fail if one or more interfaces have non-zero discard counters.
+
+ Examples
+ --------
+ ```yaml
+ anta.tests.interfaces:
+ - VerifyInterfaceDiscards:
+ ```
"""
name = "VerifyInterfaceDiscards"
description = "Verifies there are no interface discard counters."
- categories = ["interfaces"]
- commands = [AntaCommand(command="show interfaces counters discards")]
+ categories: ClassVar[list[str]] = ["interfaces"]
+ commands: ClassVar[list[AntaCommand | AntaTemplate]] = [AntaCommand(command="show interfaces counters discards", revision=1)]
@AntaTest.anta_test
def test(self) -> None:
+ """Main test function for VerifyInterfaceDiscards."""
command_output = self.instance_commands[0].json_output
wrong_interfaces: list[dict[str, dict[str, int]]] = []
for interface, outer_v in command_output["interfaces"].items():
- wrong_interfaces.extend({interface: outer_v} for counter, value in outer_v.items() if value > 0)
+ wrong_interfaces.extend({interface: outer_v} for value in outer_v.values() if value > 0)
if not wrong_interfaces:
self.result.is_success()
else:
@@ -111,21 +159,29 @@ class VerifyInterfaceDiscards(AntaTest):
class VerifyInterfaceErrDisabled(AntaTest):
- """
- Verifies there are no interfaces in errdisabled state.
-
- Expected Results:
- * success: The test will pass if there are no interfaces in errdisabled state.
- * failure: The test will fail if there is at least one interface in errdisabled state.
+ """Verifies there are no interfaces in the errdisabled state.
+
+ Expected Results
+ ----------------
+ * Success: The test will pass if there are no interfaces in the errdisabled state.
+ * Failure: The test will fail if there is at least one interface in the errdisabled state.
+
+ Examples
+ --------
+ ```yaml
+ anta.tests.interfaces:
+ - VerifyInterfaceErrDisabled:
+ ```
"""
name = "VerifyInterfaceErrDisabled"
description = "Verifies there are no interfaces in the errdisabled state."
- categories = ["interfaces"]
- commands = [AntaCommand(command="show interfaces status")]
+ categories: ClassVar[list[str]] = ["interfaces"]
+ commands: ClassVar[list[AntaCommand | AntaTemplate]] = [AntaCommand(command="show interfaces status", revision=1)]
@AntaTest.anta_test
def test(self) -> None:
+ """Main test function for VerifyInterfaceErrDisabled."""
command_output = self.instance_commands[0].json_output
errdisabled_interfaces = [interface for interface, value in command_output["interfaceStatuses"].items() if value["linkStatus"] == "errdisabled"]
if errdisabled_interfaces:
@@ -135,41 +191,58 @@ class VerifyInterfaceErrDisabled(AntaTest):
class VerifyInterfacesStatus(AntaTest):
- """
- This test verifies if the provided list of interfaces are all in the expected state.
+ """Verifies if the provided list of interfaces are all in the expected state.
- If line protocol status is provided, prioritize checking against both status and line protocol status
- If line protocol status is not provided and interface status is "up", expect both status and line protocol to be "up"
- If interface status is not "up", check only the interface status without considering line protocol status
- Expected Results:
- * success: The test will pass if the provided interfaces are all in the expected state.
- * failure: The test will fail if any interface is not in the expected state.
+ Expected Results
+ ----------------
+ * Success: The test will pass if the provided interfaces are all in the expected state.
+ * Failure: The test will fail if any interface is not in the expected state.
+
+ Examples
+ --------
+ ```yaml
+ anta.tests.interfaces:
+ - VerifyInterfacesStatus:
+ interfaces:
+ - name: Ethernet1
+ status: up
+ - name: Port-Channel100
+ status: down
+ line_protocol_status: lowerLayerDown
+ - name: Ethernet49/1
+ status: adminDown
+ line_protocol_status: notPresent
+ ```
"""
name = "VerifyInterfacesStatus"
description = "Verifies the status of the provided interfaces."
- categories = ["interfaces"]
- commands = [AntaCommand(command="show interfaces description")]
+ categories: ClassVar[list[str]] = ["interfaces"]
+ commands: ClassVar[list[AntaCommand | AntaTemplate]] = [AntaCommand(command="show interfaces description", revision=1)]
class Input(AntaTest.Input):
- """Input for the VerifyInterfacesStatus test."""
+ """Input model for the VerifyInterfacesStatus test."""
- interfaces: List[InterfaceState]
- """List of interfaces to validate with the expected state."""
+ interfaces: list[InterfaceState]
+ """List of interfaces with their expected state."""
class InterfaceState(BaseModel):
- """Model for the interface state input."""
+ """Model for an interface state."""
name: Interface
"""Interface to validate."""
status: Literal["up", "down", "adminDown"]
"""Expected status of the interface."""
- line_protocol_status: Optional[Literal["up", "down", "testing", "unknown", "dormant", "notPresent", "lowerLayerDown"]] = None
+ line_protocol_status: Literal["up", "down", "testing", "unknown", "dormant", "notPresent", "lowerLayerDown"] | None = None
"""Expected line protocol status of the interface."""
@AntaTest.anta_test
def test(self) -> None:
+ """Main test function for VerifyInterfacesStatus."""
command_output = self.instance_commands[0].json_output
self.result.is_success()
@@ -203,22 +276,30 @@ class VerifyInterfacesStatus(AntaTest):
class VerifyStormControlDrops(AntaTest):
- """
- Verifies the device did not drop packets due its to storm-control configuration.
-
- Expected Results:
- * success: The test will pass if there are no storm-control drop counters.
- * failure: The test will fail if there is at least one storm-control drop counter.
+ """Verifies there are no interface storm-control drop counters.
+
+ Expected Results
+ ----------------
+ * Success: The test will pass if there are no storm-control drop counters.
+ * Failure: The test will fail if there is at least one storm-control drop counter.
+
+ Examples
+ --------
+ ```yaml
+ anta.tests.interfaces:
+ - VerifyStormControlDrops:
+ ```
"""
name = "VerifyStormControlDrops"
description = "Verifies there are no interface storm-control drop counters."
- categories = ["interfaces"]
- commands = [AntaCommand(command="show storm-control")]
+ categories: ClassVar[list[str]] = ["interfaces"]
+ commands: ClassVar[list[AntaCommand | AntaTemplate]] = [AntaCommand(command="show storm-control", revision=1)]
- @skip_on_platforms(["cEOSLab", "vEOS-lab"])
+ @skip_on_platforms(["cEOSLab", "vEOS-lab", "cEOSCloudLab"])
@AntaTest.anta_test
def test(self) -> None:
+ """Main test function for VerifyStormControlDrops."""
command_output = self.instance_commands[0].json_output
storm_controlled_interfaces: dict[str, dict[str, Any]] = {}
for interface, interface_dict in command_output["interfaces"].items():
@@ -233,49 +314,64 @@ class VerifyStormControlDrops(AntaTest):
class VerifyPortChannels(AntaTest):
- """
- Verifies there are no inactive ports in all port channels.
-
- Expected Results:
- * success: The test will pass if there are no inactive ports in all port channels.
- * failure: The test will fail if there is at least one inactive port in a port channel.
+ """Verifies there are no inactive ports in all port channels.
+
+ Expected Results
+ ----------------
+ * Success: The test will pass if there are no inactive ports in all port channels.
+ * Failure: The test will fail if there is at least one inactive port in a port channel.
+
+ Examples
+ --------
+ ```yaml
+ anta.tests.interfaces:
+ - VerifyPortChannels:
+ ```
"""
name = "VerifyPortChannels"
description = "Verifies there are no inactive ports in all port channels."
- categories = ["interfaces"]
- commands = [AntaCommand(command="show port-channel")]
+ categories: ClassVar[list[str]] = ["interfaces"]
+ commands: ClassVar[list[AntaCommand | AntaTemplate]] = [AntaCommand(command="show port-channel", revision=1)]
- @skip_on_platforms(["cEOSLab", "vEOS-lab"])
@AntaTest.anta_test
def test(self) -> None:
+ """Main test function for VerifyPortChannels."""
command_output = self.instance_commands[0].json_output
- po_with_invactive_ports: list[dict[str, str]] = []
+ po_with_inactive_ports: list[dict[str, str]] = []
for portchannel, portchannel_dict in command_output["portChannels"].items():
if len(portchannel_dict["inactivePorts"]) != 0:
- po_with_invactive_ports.extend({portchannel: portchannel_dict["inactivePorts"]})
- if not po_with_invactive_ports:
+ po_with_inactive_ports.extend({portchannel: portchannel_dict["inactivePorts"]})
+ if not po_with_inactive_ports:
self.result.is_success()
else:
- self.result.is_failure(f"The following port-channels have inactive port(s): {po_with_invactive_ports}")
+ self.result.is_failure(f"The following port-channels have inactive port(s): {po_with_inactive_ports}")
class VerifyIllegalLACP(AntaTest):
- """
- Verifies there are no illegal LACP packets received.
-
- Expected Results:
- * success: The test will pass if there are no illegal LACP packets received.
- * failure: The test will fail if there is at least one illegal LACP packet received.
+ """Verifies there are no illegal LACP packets in all port channels.
+
+ Expected Results
+ ----------------
+ * Success: The test will pass if there are no illegal LACP packets received.
+ * Failure: The test will fail if there is at least one illegal LACP packet received.
+
+ Examples
+ --------
+ ```yaml
+ anta.tests.interfaces:
+ - VerifyIllegalLACP:
+ ```
"""
name = "VerifyIllegalLACP"
description = "Verifies there are no illegal LACP packets in all port channels."
- categories = ["interfaces"]
- commands = [AntaCommand(command="show lacp counters all-ports")]
+ categories: ClassVar[list[str]] = ["interfaces"]
+ commands: ClassVar[list[AntaCommand | AntaTemplate]] = [AntaCommand(command="show lacp counters all-ports", revision=1)]
@AntaTest.anta_test
def test(self) -> None:
+ """Main test function for VerifyIllegalLACP."""
command_output = self.instance_commands[0].json_output
po_with_illegal_lacp: list[dict[str, dict[str, int]]] = []
for portchannel, portchannel_dict in command_output["portChannels"].items():
@@ -285,29 +381,40 @@ class VerifyIllegalLACP(AntaTest):
if not po_with_illegal_lacp:
self.result.is_success()
else:
- self.result.is_failure("The following port-channels have recieved illegal lacp packets on the " f"following ports: {po_with_illegal_lacp}")
+ self.result.is_failure(f"The following port-channels have received illegal LACP packets on the following ports: {po_with_illegal_lacp}")
class VerifyLoopbackCount(AntaTest):
- """
- Verifies that the device has the expected number of loopback interfaces and all are operational.
-
- Expected Results:
- * success: The test will pass if the device has the correct number of loopback interfaces and none are down.
- * failure: The test will fail if the loopback interface count is incorrect or any are non-operational.
+ """Verifies that the device has the expected number of loopback interfaces and all are operational.
+
+ Expected Results
+ ----------------
+ * Success: The test will pass if the device has the correct number of loopback interfaces and none are down.
+ * Failure: The test will fail if the loopback interface count is incorrect or any are non-operational.
+
+ Examples
+ --------
+ ```yaml
+ anta.tests.interfaces:
+ - VerifyLoopbackCount:
+ number: 3
+ ```
"""
name = "VerifyLoopbackCount"
description = "Verifies the number of loopback interfaces and their status."
- categories = ["interfaces"]
- commands = [AntaCommand(command="show ip interface brief")]
+ categories: ClassVar[list[str]] = ["interfaces"]
+ commands: ClassVar[list[AntaCommand | AntaTemplate]] = [AntaCommand(command="show ip interface brief", revision=1)]
- class Input(AntaTest.Input): # pylint: disable=missing-class-docstring
- number: conint(ge=0) # type: ignore
- """Number of loopback interfaces expected to be present"""
+ class Input(AntaTest.Input):
+ """Input model for the VerifyLoopbackCount test."""
+
+ number: PositiveInteger
+ """Number of loopback interfaces expected to be present."""
@AntaTest.anta_test
def test(self) -> None:
+ """Main test function for VerifyLoopbackCount."""
command_output = self.instance_commands[0].json_output
loopback_count = 0
down_loopback_interfaces = []
@@ -323,33 +430,40 @@ class VerifyLoopbackCount(AntaTest):
self.result.is_failure()
if loopback_count != self.inputs.number:
self.result.is_failure(f"Found {loopback_count} Loopbacks when expecting {self.inputs.number}")
- elif len(down_loopback_interfaces) != 0:
+ elif len(down_loopback_interfaces) != 0: # pragma: no branch
self.result.is_failure(f"The following Loopbacks are not up: {down_loopback_interfaces}")
class VerifySVI(AntaTest):
- """
- Verifies the status of all SVIs.
-
- Expected Results:
- * success: The test will pass if all SVIs are up.
- * failure: The test will fail if one or many SVIs are not up.
+ """Verifies the status of all SVIs.
+
+ Expected Results
+ ----------------
+ * Success: The test will pass if all SVIs are up.
+ * Failure: The test will fail if one or many SVIs are not up.
+
+ Examples
+ --------
+ ```yaml
+ anta.tests.interfaces:
+ - VerifySVI:
+ ```
"""
name = "VerifySVI"
description = "Verifies the status of all SVIs."
- categories = ["interfaces"]
- commands = [AntaCommand(command="show ip interface brief")]
+ categories: ClassVar[list[str]] = ["interfaces"]
+ commands: ClassVar[list[AntaCommand | AntaTemplate]] = [AntaCommand(command="show ip interface brief", revision=1)]
@AntaTest.anta_test
def test(self) -> None:
+ """Main test function for VerifySVI."""
command_output = self.instance_commands[0].json_output
down_svis = []
for interface in command_output["interfaces"]:
interface_dict = command_output["interfaces"][interface]
- if "Vlan" in interface:
- if not (interface_dict["lineProtocolStatus"] == "up" and interface_dict["interfaceStatus"] == "connected"):
- down_svis.append(interface)
+ if "Vlan" in interface and not (interface_dict["lineProtocolStatus"] == "up" and interface_dict["interfaceStatus"] == "connected"):
+ down_svis.append(interface)
if len(down_svis) == 0:
self.result.is_success()
else:
@@ -357,32 +471,48 @@ class VerifySVI(AntaTest):
class VerifyL3MTU(AntaTest):
- """
- Verifies the global layer 3 Maximum Transfer Unit (MTU) for all L3 interfaces.
+ """Verifies the global layer 3 Maximum Transfer Unit (MTU) for all L3 interfaces.
Test that L3 interfaces are configured with the correct MTU. It supports Ethernet, Port Channel and VLAN interfaces.
- You can define a global MTU to check and also an MTU per interface and also ignored some interfaces.
- Expected Results:
- * success: The test will pass if all layer 3 interfaces have the proper MTU configured.
- * failure: The test will fail if one or many layer 3 interfaces have the wrong MTU configured.
+ You can define a global MTU to check, or an MTU per interface and you can also ignored some interfaces.
+
+ Expected Results
+ ----------------
+ * Success: The test will pass if all layer 3 interfaces have the proper MTU configured.
+ * Failure: The test will fail if one or many layer 3 interfaces have the wrong MTU configured.
+
+ Examples
+ --------
+ ```yaml
+ anta.tests.interfaces:
+ - VerifyL3MTU:
+ mtu: 1500
+ ignored_interfaces:
+ - Vxlan1
+ specific_mtu:
+ - Ethernet1: 2500
+ ```
"""
name = "VerifyL3MTU"
description = "Verifies the global L3 MTU of all L3 interfaces."
- categories = ["interfaces"]
- commands = [AntaCommand(command="show interfaces")]
+ categories: ClassVar[list[str]] = ["interfaces"]
+ commands: ClassVar[list[AntaCommand | AntaTemplate]] = [AntaCommand(command="show interfaces", revision=1)]
+
+ class Input(AntaTest.Input):
+ """Input model for the VerifyL3MTU test."""
- class Input(AntaTest.Input): # pylint: disable=missing-class-docstring
mtu: int = 1500
- """Default MTU we should have configured on all non-excluded interfaces"""
- ignored_interfaces: List[str] = ["Management", "Loopback", "Vxlan", "Tunnel"]
+ """Default MTU we should have configured on all non-excluded interfaces. Defaults to 1500."""
+ ignored_interfaces: list[str] = Field(default=["Management", "Loopback", "Vxlan", "Tunnel"])
"""A list of L3 interfaces to ignore"""
- specific_mtu: List[Dict[str, int]] = []
+ specific_mtu: list[dict[str, int]] = Field(default=[])
"""A list of dictionary of L3 interfaces with their specific MTU configured"""
@AntaTest.anta_test
def test(self) -> None:
+ """Main test function for VerifyL3MTU."""
# Parameter to save incorrect interface settings
wrong_l3mtu_intf: list[dict[str, int]] = []
command_output = self.instance_commands[0].json_output
@@ -405,32 +535,45 @@ class VerifyL3MTU(AntaTest):
class VerifyIPProxyARP(AntaTest):
- """
- Verifies if Proxy-ARP is enabled for the provided list of interface(s).
-
- Expected Results:
- * success: The test will pass if Proxy-ARP is enabled on the specified interface(s).
- * failure: The test will fail if Proxy-ARP is disabled on the specified interface(s).
+ """Verifies if Proxy-ARP is enabled for the provided list of interface(s).
+
+ Expected Results
+ ----------------
+ * Success: The test will pass if Proxy-ARP is enabled on the specified interface(s).
+ * Failure: The test will fail if Proxy-ARP is disabled on the specified interface(s).
+
+ Examples
+ --------
+ ```yaml
+ anta.tests.interfaces:
+ - VerifyIPProxyARP:
+ interfaces:
+ - Ethernet1
+ - Ethernet2
+ ```
"""
name = "VerifyIPProxyARP"
description = "Verifies if Proxy ARP is enabled."
- categories = ["interfaces"]
- commands = [AntaTemplate(template="show ip interface {intf}")]
+ categories: ClassVar[list[str]] = ["interfaces"]
+ commands: ClassVar[list[AntaCommand | AntaTemplate]] = [AntaTemplate(template="show ip interface {intf}", revision=2)]
+
+ class Input(AntaTest.Input):
+ """Input model for the VerifyIPProxyARP test."""
- class Input(AntaTest.Input): # pylint: disable=missing-class-docstring
- interfaces: List[str]
- """list of interfaces to be tested"""
+ interfaces: list[str]
+ """List of interfaces to be tested."""
def render(self, template: AntaTemplate) -> list[AntaCommand]:
+ """Render the template for each interface in the input list."""
return [template.render(intf=intf) for intf in self.inputs.interfaces]
@AntaTest.anta_test
def test(self) -> None:
+ """Main test function for VerifyIPProxyARP."""
disabled_intf = []
for command in self.instance_commands:
- if "intf" in command.params:
- intf = command.params["intf"]
+ intf = command.params.intf
if not command.json_output["interfaces"][intf]["proxyArp"]:
disabled_intf.append(intf)
if disabled_intf:
@@ -440,32 +583,48 @@ class VerifyIPProxyARP(AntaTest):
class VerifyL2MTU(AntaTest):
- """
- Verifies the global layer 2 Maximum Transfer Unit (MTU) for all L2 interfaces.
+ """Verifies the global layer 2 Maximum Transfer Unit (MTU) for all L2 interfaces.
Test that L2 interfaces are configured with the correct MTU. It supports Ethernet, Port Channel and VLAN interfaces.
You can define a global MTU to check and also an MTU per interface and also ignored some interfaces.
- Expected Results:
- * success: The test will pass if all layer 2 interfaces have the proper MTU configured.
- * failure: The test will fail if one or many layer 2 interfaces have the wrong MTU configured.
+ Expected Results
+ ----------------
+ * Success: The test will pass if all layer 2 interfaces have the proper MTU configured.
+ * Failure: The test will fail if one or many layer 2 interfaces have the wrong MTU configured.
+
+ Examples
+ --------
+ ```yaml
+ anta.tests.interfaces:
+ - VerifyL2MTU:
+ mtu: 1500
+ ignored_interfaces:
+ - Management1
+ - Vxlan1
+ specific_mtu:
+ - Ethernet1/1: 1500
+ ```
"""
name = "VerifyL2MTU"
description = "Verifies the global L2 MTU of all L2 interfaces."
- categories = ["interfaces"]
- commands = [AntaCommand(command="show interfaces")]
+ categories: ClassVar[list[str]] = ["interfaces"]
+ commands: ClassVar[list[AntaCommand | AntaTemplate]] = [AntaCommand(command="show interfaces", revision=1)]
+
+ class Input(AntaTest.Input):
+ """Input model for the VerifyL2MTU test."""
- class Input(AntaTest.Input): # pylint: disable=missing-class-docstring
mtu: int = 9214
- """Default MTU we should have configured on all non-excluded interfaces"""
- ignored_interfaces: List[str] = ["Management", "Loopback", "Vxlan", "Tunnel"]
- """A list of L2 interfaces to ignore"""
- specific_mtu: List[Dict[str, int]] = []
+ """Default MTU we should have configured on all non-excluded interfaces. Defaults to 9214."""
+ ignored_interfaces: list[str] = Field(default=["Management", "Loopback", "Vxlan", "Tunnel"])
+ """A list of L2 interfaces to ignore. Defaults to ["Management", "Loopback", "Vxlan", "Tunnel"]"""
+ specific_mtu: list[dict[str, int]] = Field(default=[])
"""A list of dictionary of L2 interfaces with their specific MTU configured"""
@AntaTest.anta_test
def test(self) -> None:
+ """Main test function for VerifyL2MTU."""
# Parameter to save incorrect interface settings
wrong_l2mtu_intf: list[dict[str, int]] = []
command_output = self.instance_commands[0].json_output
@@ -475,7 +634,8 @@ class VerifyL2MTU(AntaTest):
for d in self.inputs.specific_mtu:
specific_interfaces.extend(d)
for interface, values in command_output["interfaces"].items():
- if re.findall(r"[a-z]+", interface, re.IGNORECASE)[0] not in self.inputs.ignored_interfaces and values["forwardingModel"] == "bridged":
+ catch_interface = re.findall(r"^[e,p][a-zA-Z]+[-,a-zA-Z]*\d+\/*\d*", interface, re.IGNORECASE)
+ if len(catch_interface) and catch_interface[0] not in self.inputs.ignored_interfaces and values["forwardingModel"] == "bridged":
if interface in specific_interfaces:
wrong_l2mtu_intf.extend({interface: values["mtu"]} for custom_data in self.inputs.specific_mtu if values["mtu"] != custom_data[interface])
# Comparison with generic setting
@@ -488,47 +648,67 @@ class VerifyL2MTU(AntaTest):
class VerifyInterfaceIPv4(AntaTest):
- """
- Verifies if an interface is configured with a correct primary and list of optional secondary IPv4 addresses.
-
- Expected Results:
- * success: The test will pass if an interface is configured with a correct primary and secondary IPv4 address.
- * failure: The test will fail if an interface is not found or the primary and secondary IPv4 addresses do not match with the input.
+ """Verifies if an interface is configured with a correct primary and list of optional secondary IPv4 addresses.
+
+ Expected Results
+ ----------------
+ * Success: The test will pass if an interface is configured with a correct primary and secondary IPv4 address.
+ * Failure: The test will fail if an interface is not found or the primary and secondary IPv4 addresses do not match with the input.
+
+ Examples
+ --------
+ ```yaml
+ anta.tests.interfaces:
+ - VerifyInterfaceIPv4:
+ interfaces:
+ - name: Ethernet2
+ primary_ip: 172.30.11.0/31
+ secondary_ips:
+ - 10.10.10.0/31
+ - 10.10.10.10/31
+ ```
"""
name = "VerifyInterfaceIPv4"
description = "Verifies the interface IPv4 addresses."
- categories = ["interfaces"]
- commands = [AntaTemplate(template="show ip interface {interface}")]
+ categories: ClassVar[list[str]] = ["interfaces"]
+ commands: ClassVar[list[AntaCommand | AntaTemplate]] = [AntaTemplate(template="show ip interface {interface}", revision=2)]
class Input(AntaTest.Input):
- """Inputs for the VerifyInterfaceIPv4 test."""
+ """Input model for the VerifyInterfaceIPv4 test."""
- interfaces: List[InterfaceDetail]
- """list of interfaces to be tested"""
+ interfaces: list[InterfaceDetail]
+ """List of interfaces with their details."""
class InterfaceDetail(BaseModel):
- """Detail of an interface"""
+ """Model for an interface detail."""
name: Interface
- """Name of the interface"""
+ """Name of the interface."""
primary_ip: IPv4Network
- """Primary IPv4 address with subnet on interface"""
- secondary_ips: Optional[List[IPv4Network]] = None
- """Optional list of secondary IPv4 addresses with subnet on interface"""
+ """Primary IPv4 address in CIDR notation."""
+ secondary_ips: list[IPv4Network] | None = None
+ """Optional list of secondary IPv4 addresses in CIDR notation."""
def render(self, template: AntaTemplate) -> list[AntaCommand]:
- # Render the template for each interface
- return [
- template.render(interface=interface.name, primary_ip=interface.primary_ip, secondary_ips=interface.secondary_ips) for interface in self.inputs.interfaces
- ]
+ """Render the template for each interface in the input list."""
+ return [template.render(interface=interface.name) for interface in self.inputs.interfaces]
@AntaTest.anta_test
def test(self) -> None:
+ """Main test function for VerifyInterfaceIPv4."""
self.result.is_success()
for command in self.instance_commands:
- intf = command.params["interface"]
- input_primary_ip = str(command.params["primary_ip"])
+ intf = command.params.interface
+ for interface in self.inputs.interfaces:
+ if interface.name == intf:
+ input_interface_detail = interface
+ break
+ else:
+ self.result.is_error(f"Could not find `{intf}` in the input interfaces. {GITHUB_SUGGESTION}")
+ continue
+
+ input_primary_ip = str(input_interface_detail.primary_ip)
failed_messages = []
# Check if the interface has an IP address configured
@@ -545,8 +725,8 @@ class VerifyInterfaceIPv4(AntaTest):
if actual_primary_ip != input_primary_ip:
failed_messages.append(f"The expected primary IP address is `{input_primary_ip}`, but the actual primary IP address is `{actual_primary_ip}`.")
- if command.params["secondary_ips"] is not None:
- input_secondary_ips = sorted([str(network) for network in command.params["secondary_ips"]])
+ if (param_secondary_ips := input_interface_detail.secondary_ips) is not None:
+ input_secondary_ips = sorted([str(network) for network in param_secondary_ips])
secondary_ips = get_value(interface_output, "secondaryIpsOrderedList")
# Combine IP address and subnet for secondary IPs
@@ -569,27 +749,36 @@ class VerifyInterfaceIPv4(AntaTest):
class VerifyIpVirtualRouterMac(AntaTest):
- """
- Verifies the IP virtual router MAC address.
-
- Expected Results:
- * success: The test will pass if the IP virtual router MAC address matches the input.
- * failure: The test will fail if the IP virtual router MAC address does not match the input.
+ """Verifies the IP virtual router MAC address.
+
+ Expected Results
+ ----------------
+ * Success: The test will pass if the IP virtual router MAC address matches the input.
+ * Failure: The test will fail if the IP virtual router MAC address does not match the input.
+
+ Examples
+ --------
+ ```yaml
+ anta.tests.interfaces:
+ - VerifyIpVirtualRouterMac:
+ mac_address: 00:1c:73:00:dc:01
+ ```
"""
name = "VerifyIpVirtualRouterMac"
description = "Verifies the IP virtual router MAC address."
- categories = ["interfaces"]
- commands = [AntaCommand(command="show ip virtual-router")]
+ categories: ClassVar[list[str]] = ["interfaces"]
+ commands: ClassVar[list[AntaCommand | AntaTemplate]] = [AntaCommand(command="show ip virtual-router", revision=2)]
class Input(AntaTest.Input):
- """Inputs for the VerifyIpVirtualRouterMac test."""
+ """Input model for the VerifyIpVirtualRouterMac test."""
mac_address: MacAddress
- """IP virtual router MAC address"""
+ """IP virtual router MAC address."""
@AntaTest.anta_test
def test(self) -> None:
+ """Main test function for VerifyIpVirtualRouterMac."""
command_output = self.instance_commands[0].json_output["virtualMacs"]
mac_address_found = get_item(command_output, "macAddress", self.inputs.mac_address)
@@ -597,3 +786,100 @@ class VerifyIpVirtualRouterMac(AntaTest):
self.result.is_failure(f"IP virtual router MAC address `{self.inputs.mac_address}` is not configured.")
else:
self.result.is_success()
+
+
+class VerifyInterfacesSpeed(AntaTest):
+ """Verifies the speed, lanes, auto-negotiation status, and mode as full duplex for interfaces.
+
+ - If the auto-negotiation status is set to True, verifies that auto-negotiation is successful, the mode is full duplex and the speed/lanes match the input.
+ - If the auto-negotiation status is set to False, verifies that the mode is full duplex and the speed/lanes match the input.
+
+ Expected Results
+ ----------------
+ * Success: The test will pass if an interface is configured correctly with the specified speed, lanes, auto-negotiation status, and mode as full duplex.
+ * Failure: The test will fail if an interface is not found, if the speed, lanes, and auto-negotiation status do not match the input, or mode is not full duplex.
+
+ Examples
+ --------
+ ```yaml
+ anta.tests.interfaces:
+ - VerifyInterfacesSpeed:
+ interfaces:
+ - name: Ethernet2
+ auto: False
+ speed: 10
+ - name: Eth3
+ auto: True
+ speed: 100
+ lanes: 1
+ - name: Eth2
+ auto: False
+ speed: 2.5
+ ```
+ """
+
+ name = "VerifyInterfacesSpeed"
+ description = "Verifies the speed, lanes, auto-negotiation status, and mode as full duplex for interfaces."
+ categories: ClassVar[list[str]] = ["interfaces"]
+ commands: ClassVar[list[AntaCommand | AntaTemplate]] = [AntaCommand(command="show interfaces")]
+
+ class Input(AntaTest.Input):
+ """Inputs for the VerifyInterfacesSpeed test."""
+
+ interfaces: list[InterfaceDetail]
+ """List of interfaces to be tested"""
+
+ class InterfaceDetail(BaseModel):
+ """Detail of an interface."""
+
+ name: EthernetInterface
+ """The name of the interface."""
+ auto: bool
+ """The auto-negotiation status of the interface."""
+ speed: float = Field(ge=1, le=1000)
+ """The speed of the interface in Gigabits per second. Valid range is 1 to 1000."""
+ lanes: None | int = Field(None, ge=1, le=8)
+ """The number of lanes in the interface. Valid range is 1 to 8. This field is optional."""
+
+ @AntaTest.anta_test
+ def test(self) -> None:
+ """Main test function for VerifyInterfacesSpeed."""
+ self.result.is_success()
+ command_output = self.instance_commands[0].json_output
+
+ # Iterate over all the interfaces
+ for interface in self.inputs.interfaces:
+ intf = interface.name
+
+ # Check if interface exists
+ if not (interface_output := get_value(command_output, f"interfaces.{intf}")):
+ self.result.is_failure(f"Interface `{intf}` is not found.")
+ continue
+
+ auto_negotiation = interface_output.get("autoNegotiate")
+ actual_lanes = interface_output.get("lanes")
+
+ # Collecting actual interface details
+ actual_interface_output = {
+ "auto negotiation": auto_negotiation if interface.auto is True else None,
+ "duplex mode": interface_output.get("duplex"),
+ "speed": interface_output.get("bandwidth"),
+ "lanes": actual_lanes if interface.lanes is not None else None,
+ }
+
+ # Forming expected interface details
+ expected_interface_output = {
+ "auto negotiation": "success" if interface.auto is True else None,
+ "duplex mode": "duplexFull",
+ "speed": interface.speed * BPS_GBPS_CONVERSIONS,
+ "lanes": interface.lanes,
+ }
+
+ # Forming failure message
+ if actual_interface_output != expected_interface_output:
+ for output in [actual_interface_output, expected_interface_output]:
+ # Convert speed to Gbps for readability
+ if output["speed"] is not None:
+ output["speed"] = f"{custom_division(output['speed'], BPS_GBPS_CONVERSIONS)}Gbps"
+ failed_log = get_failed_logs(expected_interface_output, actual_interface_output)
+ self.result.is_failure(f"For interface {intf}:{failed_log}\n")
diff --git a/anta/tests/lanz.py b/anta/tests/lanz.py
index dcbd373..dcdab69 100644
--- a/anta/tests/lanz.py
+++ b/anta/tests/lanz.py
@@ -1,34 +1,47 @@
# Copyright (c) 2023-2024 Arista Networks, Inc.
# Use of this source code is governed by the Apache License 2.0
# that can be found in the LICENSE file.
-"""
-Test functions related to LANZ
-"""
+"""Module related to LANZ tests."""
from __future__ import annotations
+from typing import TYPE_CHECKING, ClassVar
+
+from anta.decorators import skip_on_platforms
from anta.models import AntaCommand, AntaTest
+if TYPE_CHECKING:
+ from anta.models import AntaTemplate
-class VerifyLANZ(AntaTest):
- """
- Verifies if LANZ is enabled
- Expected results:
- * success: the test will pass if lanz is enabled
- * failure: the test will fail if lanz is disabled
+class VerifyLANZ(AntaTest):
+ """Verifies if LANZ (Latency Analyzer) is enabled.
+
+ Expected Results
+ ----------------
+ * Success: The test will pass if LANZ is enabled.
+ * Failure: The test will fail if LANZ is disabled.
+
+ Examples
+ --------
+ ```yaml
+ anta.tests.lanz:
+ - VerifyLANZ:
+ ```
"""
name = "VerifyLANZ"
description = "Verifies if LANZ is enabled."
- categories = ["lanz"]
- commands = [AntaCommand(command="show queue-monitor length status")]
+ categories: ClassVar[list[str]] = ["lanz"]
+ commands: ClassVar[list[AntaCommand | AntaTemplate]] = [AntaCommand(command="show queue-monitor length status", revision=1)]
+ @skip_on_platforms(["cEOSLab", "vEOS-lab", "cEOSCloudLab"])
@AntaTest.anta_test
def test(self) -> None:
+ """Main test function for VerifyLANZ."""
command_output = self.instance_commands[0].json_output
if command_output["lanzEnabled"] is not True:
self.result.is_failure("LANZ is not enabled")
else:
- self.result.is_success("LANZ is enabled")
+ self.result.is_success()
diff --git a/anta/tests/logging.py b/anta/tests/logging.py
index ef56786..b05b0a0 100644
--- a/anta/tests/logging.py
+++ b/anta/tests/logging.py
@@ -1,57 +1,72 @@
# Copyright (c) 2023-2024 Arista Networks, Inc.
# Use of this source code is governed by the Apache License 2.0
# that can be found in the LICENSE file.
-"""
-Test functions related to the EOS various logging settings
+"""Module related to the EOS various logging tests.
-NOTE: 'show logging' does not support json output yet
+NOTE: The EOS command `show logging` does not support JSON output format.
"""
+
# Mypy does not understand AntaTest.Input typing
# mypy: disable-error-code=attr-defined
from __future__ import annotations
-import logging
import re
from ipaddress import IPv4Address
-
-# Need to keep List for pydantic in python 3.8
-from typing import List
+from typing import TYPE_CHECKING, ClassVar
from anta.models import AntaCommand, AntaTest
+if TYPE_CHECKING:
+ import logging
+
+ from anta.models import AntaTemplate
+
def _get_logging_states(logger: logging.Logger, command_output: str) -> str:
- """
- Parse "show logging" output and gets operational logging states used
- in the tests in this module.
+ """Parse `show logging` output and gets operational logging states used in the tests in this module.
Args:
- command_output: The 'show logging' output
+ ----
+ logger: The logger object.
+ command_output: The `show logging` output.
+
+ Returns
+ -------
+ str: The operational logging states.
+
"""
log_states = command_output.partition("\n\nExternal configuration:")[0]
- logger.debug(f"Device logging states:\n{log_states}")
+ logger.debug("Device logging states:\n%s", log_states)
return log_states
class VerifyLoggingPersistent(AntaTest):
- """
- Verifies if logging persistent is enabled and logs are saved in flash.
-
- Expected Results:
- * success: The test will pass if logging persistent is enabled and logs are in flash.
- * failure: The test will fail if logging persistent is disabled or no logs are saved in flash.
+ """Verifies if logging persistent is enabled and logs are saved in flash.
+
+ Expected Results
+ ----------------
+ * Success: The test will pass if logging persistent is enabled and logs are in flash.
+ * Failure: The test will fail if logging persistent is disabled or no logs are saved in flash.
+
+ Examples
+ --------
+ ```yaml
+ anta.tests.logging:
+ - VerifyLoggingPersistent:
+ ```
"""
name = "VerifyLoggingPersistent"
description = "Verifies if logging persistent is enabled and logs are saved in flash."
- categories = ["logging"]
- commands = [
+ categories: ClassVar[list[str]] = ["logging"]
+ commands: ClassVar[list[AntaCommand | AntaTemplate]] = [
AntaCommand(command="show logging", ofmt="text"),
AntaCommand(command="dir flash:/persist/messages", ofmt="text"),
]
@AntaTest.anta_test
def test(self) -> None:
+ """Main test function for VerifyLoggingPersistent."""
self.result.is_success()
log_output = self.instance_commands[0].text_output
dir_flash_output = self.instance_commands[1].text_output
@@ -65,27 +80,39 @@ class VerifyLoggingPersistent(AntaTest):
class VerifyLoggingSourceIntf(AntaTest):
- """
- Verifies logging source-interface for a specified VRF.
-
- Expected Results:
- * success: The test will pass if the provided logging source-interface is configured in the specified VRF.
- * failure: The test will fail if the provided logging source-interface is NOT configured in the specified VRF.
+ """Verifies logging source-interface for a specified VRF.
+
+ Expected Results
+ ----------------
+ * Success: The test will pass if the provided logging source-interface is configured in the specified VRF.
+ * Failure: The test will fail if the provided logging source-interface is NOT configured in the specified VRF.
+
+ Examples
+ --------
+ ```yaml
+ anta.tests.logging:
+ - VerifyLoggingSourceIntf:
+ interface: Management0
+ vrf: default
+ ```
"""
name = "VerifyLoggingSourceInt"
description = "Verifies logging source-interface for a specified VRF."
- categories = ["logging"]
- commands = [AntaCommand(command="show logging", ofmt="text")]
+ categories: ClassVar[list[str]] = ["logging"]
+ commands: ClassVar[list[AntaCommand | AntaTemplate]] = [AntaCommand(command="show logging", ofmt="text")]
+
+ class Input(AntaTest.Input):
+ """Input model for the VerifyLoggingSourceInt test."""
- class Input(AntaTest.Input): # pylint: disable=missing-class-docstring
interface: str
- """Source-interface to use as source IP of log messages"""
+ """Source-interface to use as source IP of log messages."""
vrf: str = "default"
- """The name of the VRF to transport log messages"""
+ """The name of the VRF to transport log messages. Defaults to `default`."""
@AntaTest.anta_test
def test(self) -> None:
+ """Main test function for VerifyLoggingSourceInt."""
output = self.instance_commands[0].text_output
pattern = rf"Logging source-interface '{self.inputs.interface}'.*VRF {self.inputs.vrf}"
if re.search(pattern, _get_logging_states(self.logger, output)):
@@ -95,31 +122,45 @@ class VerifyLoggingSourceIntf(AntaTest):
class VerifyLoggingHosts(AntaTest):
- """
- Verifies logging hosts (syslog servers) for a specified VRF.
-
- Expected Results:
- * success: The test will pass if the provided syslog servers are configured in the specified VRF.
- * failure: The test will fail if the provided syslog servers are NOT configured in the specified VRF.
+ """Verifies logging hosts (syslog servers) for a specified VRF.
+
+ Expected Results
+ ----------------
+ * Success: The test will pass if the provided syslog servers are configured in the specified VRF.
+ * Failure: The test will fail if the provided syslog servers are NOT configured in the specified VRF.
+
+ Examples
+ --------
+ ```yaml
+ anta.tests.logging:
+ - VerifyLoggingHosts:
+ hosts:
+ - 1.1.1.1
+ - 2.2.2.2
+ vrf: default
+ ```
"""
name = "VerifyLoggingHosts"
description = "Verifies logging hosts (syslog servers) for a specified VRF."
- categories = ["logging"]
- commands = [AntaCommand(command="show logging", ofmt="text")]
+ categories: ClassVar[list[str]] = ["logging"]
+ commands: ClassVar[list[AntaCommand | AntaTemplate]] = [AntaCommand(command="show logging", ofmt="text")]
- class Input(AntaTest.Input): # pylint: disable=missing-class-docstring
- hosts: List[IPv4Address]
- """List of hosts (syslog servers) IP addresses"""
+ class Input(AntaTest.Input):
+ """Input model for the VerifyLoggingHosts test."""
+
+ hosts: list[IPv4Address]
+ """List of hosts (syslog servers) IP addresses."""
vrf: str = "default"
- """The name of the VRF to transport log messages"""
+ """The name of the VRF to transport log messages. Defaults to `default`."""
@AntaTest.anta_test
def test(self) -> None:
+ """Main test function for VerifyLoggingHosts."""
output = self.instance_commands[0].text_output
not_configured = []
for host in self.inputs.hosts:
- pattern = rf"Logging to '{str(host)}'.*VRF {self.inputs.vrf}"
+ pattern = rf"Logging to '{host!s}'.*VRF {self.inputs.vrf}"
if not re.search(pattern, _get_logging_states(self.logger, output)):
not_configured.append(str(host))
@@ -130,24 +171,32 @@ class VerifyLoggingHosts(AntaTest):
class VerifyLoggingLogsGeneration(AntaTest):
- """
- Verifies if logs are generated.
-
- Expected Results:
- * success: The test will pass if logs are generated.
- * failure: The test will fail if logs are NOT generated.
+ """Verifies if logs are generated.
+
+ Expected Results
+ ----------------
+ * Success: The test will pass if logs are generated.
+ * Failure: The test will fail if logs are NOT generated.
+
+ Examples
+ --------
+ ```yaml
+ anta.tests.logging:
+ - VerifyLoggingLogsGeneration:
+ ```
"""
name = "VerifyLoggingLogsGeneration"
description = "Verifies if logs are generated."
- categories = ["logging"]
- commands = [
- AntaCommand(command="send log level informational message ANTA VerifyLoggingLogsGeneration validation"),
+ categories: ClassVar[list[str]] = ["logging"]
+ commands: ClassVar[list[AntaCommand | AntaTemplate]] = [
+ AntaCommand(command="send log level informational message ANTA VerifyLoggingLogsGeneration validation", ofmt="text"),
AntaCommand(command="show logging informational last 30 seconds | grep ANTA", ofmt="text", use_cache=False),
]
@AntaTest.anta_test
def test(self) -> None:
+ """Main test function for VerifyLoggingLogsGeneration."""
log_pattern = r"ANTA VerifyLoggingLogsGeneration validation"
output = self.instance_commands[1].text_output
lines = output.strip().split("\n")[::-1]
@@ -159,25 +208,33 @@ class VerifyLoggingLogsGeneration(AntaTest):
class VerifyLoggingHostname(AntaTest):
- """
- Verifies if logs are generated with the device FQDN.
-
- Expected Results:
- * success: The test will pass if logs are generated with the device FQDN.
- * failure: The test will fail if logs are NOT generated with the device FQDN.
+ """Verifies if logs are generated with the device FQDN.
+
+ Expected Results
+ ----------------
+ * Success: The test will pass if logs are generated with the device FQDN.
+ * Failure: The test will fail if logs are NOT generated with the device FQDN.
+
+ Examples
+ --------
+ ```yaml
+ anta.tests.logging:
+ - VerifyLoggingHostname:
+ ```
"""
name = "VerifyLoggingHostname"
description = "Verifies if logs are generated with the device FQDN."
- categories = ["logging"]
- commands = [
- AntaCommand(command="show hostname"),
- AntaCommand(command="send log level informational message ANTA VerifyLoggingHostname validation"),
+ categories: ClassVar[list[str]] = ["logging"]
+ commands: ClassVar[list[AntaCommand | AntaTemplate]] = [
+ AntaCommand(command="show hostname", revision=1),
+ AntaCommand(command="send log level informational message ANTA VerifyLoggingHostname validation", ofmt="text"),
AntaCommand(command="show logging informational last 30 seconds | grep ANTA", ofmt="text", use_cache=False),
]
@AntaTest.anta_test
def test(self) -> None:
+ """Main test function for VerifyLoggingHostname."""
output_hostname = self.instance_commands[0].json_output
output_logging = self.instance_commands[2].text_output
fqdn = output_hostname["fqdn"]
@@ -195,24 +252,32 @@ class VerifyLoggingHostname(AntaTest):
class VerifyLoggingTimestamp(AntaTest):
- """
- Verifies if logs are generated with the approprate timestamp.
-
- Expected Results:
- * success: The test will pass if logs are generated with the appropriated timestamp.
- * failure: The test will fail if logs are NOT generated with the appropriated timestamp.
+ """Verifies if logs are generated with the appropriate timestamp.
+
+ Expected Results
+ ----------------
+ * Success: The test will pass if logs are generated with the appropriate timestamp.
+ * Failure: The test will fail if logs are NOT generated with the appropriate timestamp.
+
+ Examples
+ --------
+ ```yaml
+ anta.tests.logging:
+ - VerifyLoggingTimestamp:
+ ```
"""
name = "VerifyLoggingTimestamp"
- description = "Verifies if logs are generated with the appropriate timestamp."
- categories = ["logging"]
- commands = [
- AntaCommand(command="send log level informational message ANTA VerifyLoggingTimestamp validation"),
+ description = "Verifies if logs are generated with the riate timestamp."
+ categories: ClassVar[list[str]] = ["logging"]
+ commands: ClassVar[list[AntaCommand | AntaTemplate]] = [
+ AntaCommand(command="send log level informational message ANTA VerifyLoggingTimestamp validation", ofmt="text"),
AntaCommand(command="show logging informational last 30 seconds | grep ANTA", ofmt="text", use_cache=False),
]
@AntaTest.anta_test
def test(self) -> None:
+ """Main test function for VerifyLoggingTimestamp."""
log_pattern = r"ANTA VerifyLoggingTimestamp validation"
timestamp_pattern = r"\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{6}-\d{2}:\d{2}"
output = self.instance_commands[1].text_output
@@ -229,21 +294,29 @@ class VerifyLoggingTimestamp(AntaTest):
class VerifyLoggingAccounting(AntaTest):
- """
- Verifies if AAA accounting logs are generated.
-
- Expected Results:
- * success: The test will pass if AAA accounting logs are generated.
- * failure: The test will fail if AAA accounting logs are NOT generated.
+ """Verifies if AAA accounting logs are generated.
+
+ Expected Results
+ ----------------
+ * Success: The test will pass if AAA accounting logs are generated.
+ * Failure: The test will fail if AAA accounting logs are NOT generated.
+
+ Examples
+ --------
+ ```yaml
+ anta.tests.logging:
+ - VerifyLoggingAccounting:
+ ```
"""
name = "VerifyLoggingAccounting"
description = "Verifies if AAA accounting logs are generated."
- categories = ["logging"]
- commands = [AntaCommand(command="show aaa accounting logs | tail", ofmt="text")]
+ categories: ClassVar[list[str]] = ["logging"]
+ commands: ClassVar[list[AntaCommand | AntaTemplate]] = [AntaCommand(command="show aaa accounting logs | tail", ofmt="text")]
@AntaTest.anta_test
def test(self) -> None:
+ """Main test function for VerifyLoggingAccounting."""
pattern = r"cmd=show aaa accounting logs"
output = self.instance_commands[0].text_output
if re.search(pattern, output):
@@ -253,24 +326,29 @@ class VerifyLoggingAccounting(AntaTest):
class VerifyLoggingErrors(AntaTest):
- """
- This test verifies there are no syslog messages with a severity of ERRORS or higher.
-
- Expected Results:
- * success: The test will pass if there are NO syslog messages with a severity of ERRORS or higher.
- * failure: The test will fail if ERRORS or higher syslog messages are present.
+ """Verifies there are no syslog messages with a severity of ERRORS or higher.
+
+ Expected Results
+ ----------------
+ * Success: The test will pass if there are NO syslog messages with a severity of ERRORS or higher.
+ * Failure: The test will fail if ERRORS or higher syslog messages are present.
+
+ Examples
+ --------
+ ```yaml
+ anta.tests.logging:
+ - VerifyLoggingErrors:
+ ```
"""
- name = "VerifyLoggingWarning"
- description = "This test verifies there are no syslog messages with a severity of ERRORS or higher."
- categories = ["logging"]
- commands = [AntaCommand(command="show logging threshold errors", ofmt="text")]
+ name = "VerifyLoggingErrors"
+ description = "Verifies there are no syslog messages with a severity of ERRORS or higher."
+ categories: ClassVar[list[str]] = ["logging"]
+ commands: ClassVar[list[AntaCommand | AntaTemplate]] = [AntaCommand(command="show logging threshold errors", ofmt="text")]
@AntaTest.anta_test
def test(self) -> None:
- """
- Run VerifyLoggingWarning validation
- """
+ """Main test function for VerifyLoggingErrors."""
command_output = self.instance_commands[0].text_output
if len(command_output) == 0:
diff --git a/anta/tests/mlag.py b/anta/tests/mlag.py
index 2c2be01..1d17ab6 100644
--- a/anta/tests/mlag.py
+++ b/anta/tests/mlag.py
@@ -1,39 +1,49 @@
# Copyright (c) 2023-2024 Arista Networks, Inc.
# Use of this source code is governed by the Apache License 2.0
# that can be found in the LICENSE file.
-"""
-Test functions related to Multi-chassis Link Aggregation (MLAG)
-"""
+"""Module related to Multi-chassis Link Aggregation (MLAG) tests."""
+
# Mypy does not understand AntaTest.Input typing
# mypy: disable-error-code=attr-defined
from __future__ import annotations
-from pydantic import conint
+from typing import TYPE_CHECKING, ClassVar
-from anta.custom_types import MlagPriority
+from anta.custom_types import MlagPriority, PositiveInteger
from anta.models import AntaCommand, AntaTest
-from anta.tools.get_value import get_value
+from anta.tools import get_value
+
+if TYPE_CHECKING:
+ from anta.models import AntaTemplate
class VerifyMlagStatus(AntaTest):
- """
- This test verifies the health status of the MLAG configuration.
+ """Verifies the health status of the MLAG configuration.
- Expected Results:
- * success: The test will pass if the MLAG state is 'active', negotiation status is 'connected',
+ Expected Results
+ ----------------
+ * Success: The test will pass if the MLAG state is 'active', negotiation status is 'connected',
peer-link status and local interface status are 'up'.
- * failure: The test will fail if the MLAG state is not 'active', negotiation status is not 'connected',
+ * Failure: The test will fail if the MLAG state is not 'active', negotiation status is not 'connected',
peer-link status or local interface status are not 'up'.
- * skipped: The test will be skipped if MLAG is 'disabled'.
+ * Skipped: The test will be skipped if MLAG is 'disabled'.
+
+ Examples
+ --------
+ ```yaml
+ anta.tests.mlag:
+ - VerifyMlagStatus:
+ ```
"""
name = "VerifyMlagStatus"
description = "Verifies the health status of the MLAG configuration."
- categories = ["mlag"]
- commands = [AntaCommand(command="show mlag", ofmt="json")]
+ categories: ClassVar[list[str]] = ["mlag"]
+ commands: ClassVar[list[AntaCommand | AntaTemplate]] = [AntaCommand(command="show mlag", revision=2)]
@AntaTest.anta_test
def test(self) -> None:
+ """Main test function for VerifyMlagStatus."""
command_output = self.instance_commands[0].json_output
if command_output["state"] == "disabled":
self.result.is_skipped("MLAG is disabled")
@@ -52,22 +62,30 @@ class VerifyMlagStatus(AntaTest):
class VerifyMlagInterfaces(AntaTest):
- """
- This test verifies there are no inactive or active-partial MLAG ports.
-
- Expected Results:
- * success: The test will pass if there are NO inactive or active-partial MLAG ports.
- * failure: The test will fail if there are inactive or active-partial MLAG ports.
- * skipped: The test will be skipped if MLAG is 'disabled'.
+ """Verifies there are no inactive or active-partial MLAG ports.
+
+ Expected Results
+ ----------------
+ * Success: The test will pass if there are NO inactive or active-partial MLAG ports.
+ * Failure: The test will fail if there are inactive or active-partial MLAG ports.
+ * Skipped: The test will be skipped if MLAG is 'disabled'.
+
+ Examples
+ --------
+ ```yaml
+ anta.tests.mlag:
+ - VerifyMlagInterfaces:
+ ```
"""
name = "VerifyMlagInterfaces"
description = "Verifies there are no inactive or active-partial MLAG ports."
- categories = ["mlag"]
- commands = [AntaCommand(command="show mlag", ofmt="json")]
+ categories: ClassVar[list[str]] = ["mlag"]
+ commands: ClassVar[list[AntaCommand | AntaTemplate]] = [AntaCommand(command="show mlag", revision=2)]
@AntaTest.anta_test
def test(self) -> None:
+ """Main test function for VerifyMlagInterfaces."""
command_output = self.instance_commands[0].json_output
if command_output["state"] == "disabled":
self.result.is_skipped("MLAG is disabled")
@@ -79,23 +97,31 @@ class VerifyMlagInterfaces(AntaTest):
class VerifyMlagConfigSanity(AntaTest):
- """
- This test verifies there are no MLAG config-sanity inconsistencies.
-
- Expected Results:
- * success: The test will pass if there are NO MLAG config-sanity inconsistencies.
- * failure: The test will fail if there are MLAG config-sanity inconsistencies.
- * skipped: The test will be skipped if MLAG is 'disabled'.
- * error: The test will give an error if 'mlagActive' is not found in the JSON response.
+ """Verifies there are no MLAG config-sanity inconsistencies.
+
+ Expected Results
+ ----------------
+ * Success: The test will pass if there are NO MLAG config-sanity inconsistencies.
+ * Failure: The test will fail if there are MLAG config-sanity inconsistencies.
+ * Skipped: The test will be skipped if MLAG is 'disabled'.
+ * Error: The test will give an error if 'mlagActive' is not found in the JSON response.
+
+ Examples
+ --------
+ ```yaml
+ anta.tests.mlag:
+ - VerifyMlagConfigSanity:
+ ```
"""
name = "VerifyMlagConfigSanity"
description = "Verifies there are no MLAG config-sanity inconsistencies."
- categories = ["mlag"]
- commands = [AntaCommand(command="show mlag config-sanity", ofmt="json")]
+ categories: ClassVar[list[str]] = ["mlag"]
+ commands: ClassVar[list[AntaCommand | AntaTemplate]] = [AntaCommand(command="show mlag config-sanity", revision=1)]
@AntaTest.anta_test
def test(self) -> None:
+ """Main test function for VerifyMlagConfigSanity."""
command_output = self.instance_commands[0].json_output
if (mlag_status := get_value(command_output, "mlagActive")) is None:
self.result.is_error(message="Incorrect JSON response - 'mlagActive' state was not found")
@@ -112,28 +138,40 @@ class VerifyMlagConfigSanity(AntaTest):
class VerifyMlagReloadDelay(AntaTest):
- """
- This test verifies the reload-delay parameters of the MLAG configuration.
-
- Expected Results:
- * success: The test will pass if the reload-delay parameters are configured properly.
- * failure: The test will fail if the reload-delay parameters are NOT configured properly.
- * skipped: The test will be skipped if MLAG is 'disabled'.
+ """Verifies the reload-delay parameters of the MLAG configuration.
+
+ Expected Results
+ ----------------
+ * Success: The test will pass if the reload-delay parameters are configured properly.
+ * Failure: The test will fail if the reload-delay parameters are NOT configured properly.
+ * Skipped: The test will be skipped if MLAG is 'disabled'.
+
+ Examples
+ --------
+ ```yaml
+ anta.tests.mlag:
+ - VerifyMlagReloadDelay:
+ reload_delay: 300
+ reload_delay_non_mlag: 330
+ ```
"""
name = "VerifyMlagReloadDelay"
description = "Verifies the MLAG reload-delay parameters."
- categories = ["mlag"]
- commands = [AntaCommand(command="show mlag", ofmt="json")]
+ categories: ClassVar[list[str]] = ["mlag"]
+ commands: ClassVar[list[AntaCommand | AntaTemplate]] = [AntaCommand(command="show mlag", revision=2)]
- class Input(AntaTest.Input): # pylint: disable=missing-class-docstring
- reload_delay: conint(ge=0) # type: ignore
- """Delay (seconds) after reboot until non peer-link ports that are part of an MLAG are enabled"""
- reload_delay_non_mlag: conint(ge=0) # type: ignore
- """Delay (seconds) after reboot until ports that are not part of an MLAG are enabled"""
+ class Input(AntaTest.Input):
+ """Input model for the VerifyMlagReloadDelay test."""
+
+ reload_delay: PositiveInteger
+ """Delay (seconds) after reboot until non peer-link ports that are part of an MLAG are enabled."""
+ reload_delay_non_mlag: PositiveInteger
+ """Delay (seconds) after reboot until ports that are not part of an MLAG are enabled."""
@AntaTest.anta_test
def test(self) -> None:
+ """Main test function for VerifyMlagReloadDelay."""
command_output = self.instance_commands[0].json_output
if command_output["state"] == "disabled":
self.result.is_skipped("MLAG is disabled")
@@ -148,32 +186,46 @@ class VerifyMlagReloadDelay(AntaTest):
class VerifyMlagDualPrimary(AntaTest):
- """
- This test verifies the dual-primary detection and its parameters of the MLAG configuration.
-
- Expected Results:
- * success: The test will pass if the dual-primary detection is enabled and its parameters are configured properly.
- * failure: The test will fail if the dual-primary detection is NOT enabled or its parameters are NOT configured properly.
- * skipped: The test will be skipped if MLAG is 'disabled'.
+ """Verifies the dual-primary detection and its parameters of the MLAG configuration.
+
+ Expected Results
+ ----------------
+ * Success: The test will pass if the dual-primary detection is enabled and its parameters are configured properly.
+ * Failure: The test will fail if the dual-primary detection is NOT enabled or its parameters are NOT configured properly.
+ * Skipped: The test will be skipped if MLAG is 'disabled'.
+
+ Examples
+ --------
+ ```yaml
+ anta.tests.mlag:
+ - VerifyMlagDualPrimary:
+ detection_delay: 200
+ errdisabled: True
+ recovery_delay: 60
+ recovery_delay_non_mlag: 0
+ ```
"""
name = "VerifyMlagDualPrimary"
description = "Verifies the MLAG dual-primary detection parameters."
- categories = ["mlag"]
- commands = [AntaCommand(command="show mlag detail", ofmt="json")]
+ categories: ClassVar[list[str]] = ["mlag"]
+ commands: ClassVar[list[AntaCommand | AntaTemplate]] = [AntaCommand(command="show mlag detail", revision=2)]
- class Input(AntaTest.Input): # pylint: disable=missing-class-docstring
- detection_delay: conint(ge=0) # type: ignore
- """Delay detection (seconds)"""
+ class Input(AntaTest.Input):
+ """Input model for the VerifyMlagDualPrimary test."""
+
+ detection_delay: PositiveInteger
+ """Delay detection (seconds)."""
errdisabled: bool = False
- """Errdisabled all interfaces when dual-primary is detected"""
- recovery_delay: conint(ge=0) # type: ignore
- """Delay (seconds) after dual-primary detection resolves until non peer-link ports that are part of an MLAG are enabled"""
- recovery_delay_non_mlag: conint(ge=0) # type: ignore
- """Delay (seconds) after dual-primary detection resolves until ports that are not part of an MLAG are enabled"""
+ """Errdisabled all interfaces when dual-primary is detected."""
+ recovery_delay: PositiveInteger
+ """Delay (seconds) after dual-primary detection resolves until non peer-link ports that are part of an MLAG are enabled."""
+ recovery_delay_non_mlag: PositiveInteger
+ """Delay (seconds) after dual-primary detection resolves until ports that are not part of an MLAG are enabled."""
@AntaTest.anta_test
def test(self) -> None:
+ """Main test function for VerifyMlagDualPrimary."""
errdisabled_action = "errdisableAllInterfaces" if self.inputs.errdisabled else "none"
command_output = self.instance_commands[0].json_output
if command_output["state"] == "disabled":
@@ -196,28 +248,37 @@ class VerifyMlagDualPrimary(AntaTest):
class VerifyMlagPrimaryPriority(AntaTest):
- """
- Test class to verify the MLAG (Multi-Chassis Link Aggregation) primary priority.
-
- Expected Results:
- * Success: The test will pass if the MLAG state is set as 'primary' and the priority matches the input.
- * Failure: The test will fail if the MLAG state is not 'primary' or the priority doesn't match the input.
- * Skipped: The test will be skipped if MLAG is 'disabled'.
+ """Verify the MLAG (Multi-Chassis Link Aggregation) primary priority.
+
+ Expected Results
+ ----------------
+ * Success: The test will pass if the MLAG state is set as 'primary' and the priority matches the input.
+ * Failure: The test will fail if the MLAG state is not 'primary' or the priority doesn't match the input.
+ * Skipped: The test will be skipped if MLAG is 'disabled'.
+
+ Examples
+ --------
+ ```yaml
+ anta.tests.mlag:
+ - VerifyMlagPrimaryPriority:
+ primary_priority: 3276
+ ```
"""
name = "VerifyMlagPrimaryPriority"
description = "Verifies the configuration of the MLAG primary priority."
- categories = ["mlag"]
- commands = [AntaCommand(command="show mlag detail")]
+ categories: ClassVar[list[str]] = ["mlag"]
+ commands: ClassVar[list[AntaCommand | AntaTemplate]] = [AntaCommand(command="show mlag detail", revision=2)]
class Input(AntaTest.Input):
- """Inputs for the VerifyMlagPrimaryPriority test."""
+ """Input model for the VerifyMlagPrimaryPriority test."""
primary_priority: MlagPriority
"""The expected MLAG primary priority."""
@AntaTest.anta_test
def test(self) -> None:
+ """Main test function for VerifyMlagPrimaryPriority."""
command_output = self.instance_commands[0].json_output
self.result.is_success()
# Skip the test if MLAG is disabled
@@ -235,5 +296,5 @@ class VerifyMlagPrimaryPriority(AntaTest):
# Check primary priority
if primary_priority != self.inputs.primary_priority:
self.result.is_failure(
- f"The primary priority does not match expected. Expected `{self.inputs.primary_priority}`, but found `{primary_priority}` instead."
+ f"The primary priority does not match expected. Expected `{self.inputs.primary_priority}`, but found `{primary_priority}` instead.",
)
diff --git a/anta/tests/multicast.py b/anta/tests/multicast.py
index ecd6ec2..554bd57 100644
--- a/anta/tests/multicast.py
+++ b/anta/tests/multicast.py
@@ -1,36 +1,54 @@
# Copyright (c) 2023-2024 Arista Networks, Inc.
# Use of this source code is governed by the Apache License 2.0
# that can be found in the LICENSE file.
-"""
-Test functions related to multicast
-"""
+"""Module related to multicast and IGMP tests."""
+
# Mypy does not understand AntaTest.Input typing
# mypy: disable-error-code=attr-defined
from __future__ import annotations
-# Need to keep Dict for pydantic in python 3.8
-from typing import Dict
+from typing import TYPE_CHECKING, ClassVar
from anta.custom_types import Vlan
from anta.models import AntaCommand, AntaTest
+if TYPE_CHECKING:
+ from anta.models import AntaTemplate
+
class VerifyIGMPSnoopingVlans(AntaTest):
- """
- Verifies the IGMP snooping configuration for some VLANs.
+ """Verifies the IGMP snooping status for the provided VLANs.
+
+ Expected Results
+ ----------------
+ * Success: The test will pass if the IGMP snooping status matches the expected status for the provided VLANs.
+ * Failure: The test will fail if the IGMP snooping status does not match the expected status for the provided VLANs.
+
+ Examples
+ --------
+ ```yaml
+ anta.tests.multicast:
+ - VerifyIGMPSnoopingVlans:
+ vlans:
+ 10: False
+ 12: False
+ ```
"""
name = "VerifyIGMPSnoopingVlans"
- description = "Verifies the IGMP snooping configuration for some VLANs."
- categories = ["multicast", "igmp"]
- commands = [AntaCommand(command="show ip igmp snooping")]
+ description = "Verifies the IGMP snooping status for the provided VLANs."
+ categories: ClassVar[list[str]] = ["multicast"]
+ commands: ClassVar[list[AntaCommand | AntaTemplate]] = [AntaCommand(command="show ip igmp snooping", revision=1)]
- class Input(AntaTest.Input): # pylint: disable=missing-class-docstring
- vlans: Dict[Vlan, bool]
- """Dictionary of VLANs with associated IGMP configuration status (True=enabled, False=disabled)"""
+ class Input(AntaTest.Input):
+ """Input model for the VerifyIGMPSnoopingVlans test."""
+
+ vlans: dict[Vlan, bool]
+ """Dictionary with VLAN ID and whether IGMP snooping must be enabled (True) or disabled (False)."""
@AntaTest.anta_test
def test(self) -> None:
+ """Main test function for VerifyIGMPSnoopingVlans."""
command_output = self.instance_commands[0].json_output
self.result.is_success()
for vlan, enabled in self.inputs.vlans.items():
@@ -44,21 +62,36 @@ class VerifyIGMPSnoopingVlans(AntaTest):
class VerifyIGMPSnoopingGlobal(AntaTest):
- """
- Verifies the IGMP snooping global configuration.
+ """Verifies the IGMP snooping global status.
+
+ Expected Results
+ ----------------
+ * Success: The test will pass if the IGMP snooping global status matches the expected status.
+ * Failure: The test will fail if the IGMP snooping global status does not match the expected status.
+
+ Examples
+ --------
+ ```yaml
+ anta.tests.multicast:
+ - VerifyIGMPSnoopingGlobal:
+ enabled: True
+ ```
"""
name = "VerifyIGMPSnoopingGlobal"
description = "Verifies the IGMP snooping global configuration."
- categories = ["multicast", "igmp"]
- commands = [AntaCommand(command="show ip igmp snooping")]
+ categories: ClassVar[list[str]] = ["multicast"]
+ commands: ClassVar[list[AntaCommand | AntaTemplate]] = [AntaCommand(command="show ip igmp snooping", revision=1)]
+
+ class Input(AntaTest.Input):
+ """Input model for the VerifyIGMPSnoopingGlobal test."""
- class Input(AntaTest.Input): # pylint: disable=missing-class-docstring
enabled: bool
- """Expected global IGMP snooping configuration (True=enabled, False=disabled)"""
+ """Whether global IGMP snopping must be enabled (True) or disabled (False)."""
@AntaTest.anta_test
def test(self) -> None:
+ """Main test function for VerifyIGMPSnoopingGlobal."""
command_output = self.instance_commands[0].json_output
self.result.is_success()
igmp_state = command_output["igmpSnoopingState"]
diff --git a/anta/tests/path_selection.py b/anta/tests/path_selection.py
new file mode 100644
index 0000000..416cb8c
--- /dev/null
+++ b/anta/tests/path_selection.py
@@ -0,0 +1,165 @@
+# Copyright (c) 2023-2024 Arista Networks, Inc.
+# Use of this source code is governed by the Apache License 2.0
+# that can be found in the LICENSE file.
+"""Test functions related to various router path-selection settings."""
+
+# Mypy does not understand AntaTest.Input typing
+# mypy: disable-error-code=attr-defined
+from __future__ import annotations
+
+from ipaddress import IPv4Address
+from typing import ClassVar
+
+from pydantic import BaseModel
+
+from anta.decorators import skip_on_platforms
+from anta.models import AntaCommand, AntaTemplate, AntaTest
+from anta.tools import get_value
+
+
+class VerifyPathsHealth(AntaTest):
+ """
+ Verifies the path and telemetry state of all paths under router path-selection.
+
+ The expected states are 'IPsec established', 'Resolved' for path and 'active' for telemetry.
+
+ Expected Results
+ ----------------
+ * Success: The test will pass if all path states under router path-selection are either 'IPsec established' or 'Resolved'
+ and their telemetry state as 'active'.
+ * Failure: The test will fail if router path-selection is not configured or if any path state is not 'IPsec established' or 'Resolved',
+ or the telemetry state is 'inactive'.
+
+ Examples
+ --------
+ ```yaml
+ anta.tests.path_selection:
+ - VerifyPathsHealth:
+ ```
+ """
+
+ name = "VerifyPathsHealth"
+ description = "Verifies the path and telemetry state of all paths under router path-selection."
+ categories: ClassVar[list[str]] = ["path-selection"]
+ commands: ClassVar[list[AntaCommand | AntaTemplate]] = [AntaCommand(command="show path-selection paths", revision=1)]
+
+ @skip_on_platforms(["cEOSLab", "vEOS-lab"])
+ @AntaTest.anta_test
+ def test(self) -> None:
+ """Main test function for VerifyPathsHealth."""
+ self.result.is_success()
+
+ command_output = self.instance_commands[0].json_output["dpsPeers"]
+
+ # If no paths are configured for router path-selection, the test fails
+ if not command_output:
+ self.result.is_failure("No path configured for router path-selection.")
+ return
+
+ # Check the state of each path
+ for peer, peer_data in command_output.items():
+ for group, group_data in peer_data["dpsGroups"].items():
+ for path_data in group_data["dpsPaths"].values():
+ path_state = path_data["state"]
+ session = path_data["dpsSessions"]["0"]["active"]
+
+ # If the path state of any path is not 'ipsecEstablished' or 'routeResolved', the test fails
+ if path_state not in ["ipsecEstablished", "routeResolved"]:
+ self.result.is_failure(f"Path state for peer {peer} in path-group {group} is `{path_state}`.")
+
+ # If the telemetry state of any path is inactive, the test fails
+ elif not session:
+ self.result.is_failure(f"Telemetry state for peer {peer} in path-group {group} is `inactive`.")
+
+
+class VerifySpecificPath(AntaTest):
+ """
+ Verifies the path and telemetry state of a specific path for an IPv4 peer under router path-selection.
+
+ The expected states are 'IPsec established', 'Resolved' for path and 'active' for telemetry.
+
+ Expected Results
+ ----------------
+ * Success: The test will pass if the path state under router path-selection is either 'IPsec established' or 'Resolved'
+ and telemetry state as 'active'.
+ * Failure: The test will fail if router path-selection is not configured or if the path state is not 'IPsec established' or 'Resolved',
+ or if the telemetry state is 'inactive'.
+
+ Examples
+ --------
+ ```yaml
+ anta.tests.path_selection:
+ - VerifySpecificPath:
+ paths:
+ - peer: 10.255.0.1
+ path_group: internet
+ source_address: 100.64.3.2
+ destination_address: 100.64.1.2
+ ```
+ """
+
+ name = "VerifySpecificPath"
+ description = "Verifies the path and telemetry state of a specific path under router path-selection."
+ categories: ClassVar[list[str]] = ["path-selection"]
+ commands: ClassVar[list[AntaCommand | AntaTemplate]] = [
+ AntaTemplate(template="show path-selection paths peer {peer} path-group {group} source {source} destination {destination}", revision=1)
+ ]
+
+ class Input(AntaTest.Input):
+ """Input model for the VerifySpecificPath test."""
+
+ paths: list[RouterPath]
+ """List of router paths to verify."""
+
+ class RouterPath(BaseModel):
+ """Detail of a router path."""
+
+ peer: IPv4Address
+ """Static peer IPv4 address."""
+
+ path_group: str
+ """Router path group name."""
+
+ source_address: IPv4Address
+ """Source IPv4 address of path."""
+
+ destination_address: IPv4Address
+ """Destination IPv4 address of path."""
+
+ def render(self, template: AntaTemplate) -> list[AntaCommand]:
+ """Render the template for each router path."""
+ return [
+ template.render(peer=path.peer, group=path.path_group, source=path.source_address, destination=path.destination_address) for path in self.inputs.paths
+ ]
+
+ @skip_on_platforms(["cEOSLab", "vEOS-lab"])
+ @AntaTest.anta_test
+ def test(self) -> None:
+ """Main test function for VerifySpecificPath."""
+ self.result.is_success()
+
+ # Check the state of each path
+ for command in self.instance_commands:
+ peer = command.params.peer
+ path_group = command.params.group
+ source = command.params.source
+ destination = command.params.destination
+ command_output = command.json_output.get("dpsPeers", [])
+
+ # If the peer is not configured for the path group, the test fails
+ if not command_output:
+ self.result.is_failure(f"Path `peer: {peer} source: {source} destination: {destination}` is not configured for path-group `{path_group}`.")
+ continue
+
+ # Extract the state of the path
+ path_output = get_value(command_output, f"{peer}..dpsGroups..{path_group}..dpsPaths", separator="..")
+ path_state = next(iter(path_output.values())).get("state")
+ session = get_value(next(iter(path_output.values())), "dpsSessions.0.active")
+
+ # If the state of the path is not 'ipsecEstablished' or 'routeResolved', or the telemetry state is 'inactive', the test fails
+ if path_state not in ["ipsecEstablished", "routeResolved"]:
+ self.result.is_failure(f"Path state for `peer: {peer} source: {source} destination: {destination}` in path-group {path_group} is `{path_state}`.")
+ elif not session:
+ self.result.is_failure(
+ f"Telemetry state for path `peer: {peer} source: {source} destination: {destination}` in path-group {path_group} is `inactive`."
+ )
diff --git a/anta/tests/profiles.py b/anta/tests/profiles.py
index a0ed6d7..859c886 100644
--- a/anta/tests/profiles.py
+++ b/anta/tests/profiles.py
@@ -1,36 +1,53 @@
# Copyright (c) 2023-2024 Arista Networks, Inc.
# Use of this source code is governed by the Apache License 2.0
# that can be found in the LICENSE file.
-"""
-Test functions related to ASIC profiles
-"""
+"""Module related to ASIC profile tests."""
+
# Mypy does not understand AntaTest.Input typing
# mypy: disable-error-code=attr-defined
from __future__ import annotations
-from typing import Literal
+from typing import TYPE_CHECKING, ClassVar, Literal
from anta.decorators import skip_on_platforms
from anta.models import AntaCommand, AntaTest
+if TYPE_CHECKING:
+ from anta.models import AntaTemplate
+
class VerifyUnifiedForwardingTableMode(AntaTest):
- """
- Verifies the device is using the expected Unified Forwarding Table mode.
+ """Verifies the device is using the expected UFT (Unified Forwarding Table) mode.
+
+ Expected Results
+ ----------------
+ * Success: The test will pass if the device is using the expected UFT mode.
+ * Failure: The test will fail if the device is not using the expected UFT mode.
+
+ Examples
+ --------
+ ```yaml
+ anta.tests.profiles:
+ - VerifyUnifiedForwardingTableMode:
+ mode: 3
+ ```
"""
name = "VerifyUnifiedForwardingTableMode"
- description = ""
- categories = ["profiles"]
- commands = [AntaCommand(command="show platform trident forwarding-table partition", ofmt="json")]
+ description = "Verifies the device is using the expected UFT mode."
+ categories: ClassVar[list[str]] = ["profiles"]
+ commands: ClassVar[list[AntaCommand | AntaTemplate]] = [AntaCommand(command="show platform trident forwarding-table partition", revision=1)]
+
+ class Input(AntaTest.Input):
+ """Input model for the VerifyUnifiedForwardingTableMode test."""
- class Input(AntaTest.Input): # pylint: disable=missing-class-docstring
mode: Literal[0, 1, 2, 3, 4, "flexible"]
- """Expected UFT mode"""
+ """Expected UFT mode. Valid values are 0, 1, 2, 3, 4, or "flexible"."""
- @skip_on_platforms(["cEOSLab", "vEOS-lab"])
+ @skip_on_platforms(["cEOSLab", "vEOS-lab", "cEOSCloudLab"])
@AntaTest.anta_test
def test(self) -> None:
+ """Main test function for VerifyUnifiedForwardingTableMode."""
command_output = self.instance_commands[0].json_output
if command_output["uftMode"] == str(self.inputs.mode):
self.result.is_success()
@@ -39,22 +56,37 @@ class VerifyUnifiedForwardingTableMode(AntaTest):
class VerifyTcamProfile(AntaTest):
- """
- Verifies the device is using the configured TCAM profile.
+ """Verifies that the device is using the provided Ternary Content-Addressable Memory (TCAM) profile.
+
+ Expected Results
+ ----------------
+ * Success: The test will pass if the provided TCAM profile is actually running on the device.
+ * Failure: The test will fail if the provided TCAM profile is not running on the device.
+
+ Examples
+ --------
+ ```yaml
+ anta.tests.profiles:
+ - VerifyTcamProfile:
+ profile: vxlan-routing
+ ```
"""
name = "VerifyTcamProfile"
- description = "Verify that the assigned TCAM profile is actually running on the device"
- categories = ["profiles"]
- commands = [AntaCommand(command="show hardware tcam profile", ofmt="json")]
+ description = "Verifies the device TCAM profile."
+ categories: ClassVar[list[str]] = ["profiles"]
+ commands: ClassVar[list[AntaCommand | AntaTemplate]] = [AntaCommand(command="show hardware tcam profile", revision=1)]
+
+ class Input(AntaTest.Input):
+ """Input model for the VerifyTcamProfile test."""
- class Input(AntaTest.Input): # pylint: disable=missing-class-docstring
profile: str
- """Expected TCAM profile"""
+ """Expected TCAM profile."""
- @skip_on_platforms(["cEOSLab", "vEOS-lab"])
+ @skip_on_platforms(["cEOSLab", "vEOS-lab", "cEOSCloudLab"])
@AntaTest.anta_test
def test(self) -> None:
+ """Main test function for VerifyTcamProfile."""
command_output = self.instance_commands[0].json_output
if command_output["pmfProfiles"]["FixedSystem"]["status"] == command_output["pmfProfiles"]["FixedSystem"]["config"] == self.inputs.profile:
self.result.is_success()
diff --git a/anta/tests/ptp.py b/anta/tests/ptp.py
index 9db810d..cbb8ee3 100644
--- a/anta/tests/ptp.py
+++ b/anta/tests/ptp.py
@@ -1,33 +1,235 @@
-# Copyright (c) 2023-2024 Arista Networks, Inc.
+# Copyright (c) 2024 Arista Networks, Inc.
# Use of this source code is governed by the Apache License 2.0
# that can be found in the LICENSE file.
-"""
-Test functions related to PTP (Precision Time Protocol) in EOS
-"""
+"""Module related to PTP tests."""
+
+# Mypy does not understand AntaTest.Input typing
+# mypy: disable-error-code=attr-defined
from __future__ import annotations
+from typing import TYPE_CHECKING, ClassVar
+
+from anta.decorators import skip_on_platforms
from anta.models import AntaCommand, AntaTest
+if TYPE_CHECKING:
+ from anta.models import AntaTemplate
+
+
+class VerifyPtpModeStatus(AntaTest):
+ """Verifies that the device is configured as a Precision Time Protocol (PTP) Boundary Clock (BC).
+
+ Expected Results
+ ----------------
+ * Success: The test will pass if the device is a BC.
+ * Failure: The test will fail if the device is not a BC.
+ * Skipped: The test will be skipped if PTP is not configured on the device.
+
+ Examples
+ --------
+ ```yaml
+ anta.tests.ptp:
+ - VerifyPtpModeStatus:
+ ```
+ """
+
+ name = "VerifyPtpModeStatus"
+ description = "Verifies that the device is configured as a PTP Boundary Clock."
+ categories: ClassVar[list[str]] = ["ptp"]
+ commands: ClassVar[list[AntaCommand | AntaTemplate]] = [AntaCommand(command="show ptp", revision=2)]
+
+ @skip_on_platforms(["cEOSLab", "vEOS-lab", "cEOSCloudLab"])
+ @AntaTest.anta_test
+ def test(self) -> None:
+ """Main test function for VerifyPtpModeStatus."""
+ command_output = self.instance_commands[0].json_output
+
+ if (ptp_mode := command_output.get("ptpMode")) is None:
+ self.result.is_skipped("PTP is not configured")
+ return
+
+ if ptp_mode != "ptpBoundaryClock":
+ self.result.is_failure(f"The device is not configured as a PTP Boundary Clock: '{ptp_mode}'")
+ else:
+ self.result.is_success()
+
-class VerifyPtpStatus(AntaTest):
+class VerifyPtpGMStatus(AntaTest):
+ """Verifies that the device is locked to a valid Precision Time Protocol (PTP) Grandmaster (GM).
+
+ To test PTP failover, re-run the test with a secondary GMID configured.
+
+ Expected Results
+ ----------------
+ * Success: The test will pass if the device is locked to the provided Grandmaster.
+ * Failure: The test will fail if the device is not locked to the provided Grandmaster.
+ * Skipped: The test will be skipped if PTP is not configured on the device.
+
+ Examples
+ --------
+ ```yaml
+ anta.tests.ptp:
+ - VerifyPtpGMStatus:
+ gmid: 0xec:46:70:ff:fe:00:ff:a9
+ ```
"""
- Verifies whether the PTP agent is enabled globally.
- Expected Results:
- * success: The test will pass if the PTP agent is enabled globally.
- * failure: The test will fail if the PTP agent is enabled globally.
+ class Input(AntaTest.Input):
+ """Input model for the VerifyPtpGMStatus test."""
+
+ gmid: str
+ """Identifier of the Grandmaster to which the device should be locked."""
+
+ name = "VerifyPtpGMStatus"
+ description = "Verifies that the device is locked to a valid PTP Grandmaster."
+ categories: ClassVar[list[str]] = ["ptp"]
+ commands: ClassVar[list[AntaCommand | AntaTemplate]] = [AntaCommand(command="show ptp", revision=2)]
+
+ @skip_on_platforms(["cEOSLab", "vEOS-lab", "cEOSCloudLab"])
+ @AntaTest.anta_test
+ def test(self) -> None:
+ """Main test function for VerifyPtpGMStatus."""
+ command_output = self.instance_commands[0].json_output
+
+ if (ptp_clock_summary := command_output.get("ptpClockSummary")) is None:
+ self.result.is_skipped("PTP is not configured")
+ return
+
+ if ptp_clock_summary["gmClockIdentity"] != self.inputs.gmid:
+ self.result.is_failure(
+ f"The device is locked to the following Grandmaster: '{ptp_clock_summary['gmClockIdentity']}', which differ from the expected one.",
+ )
+ else:
+ self.result.is_success()
+
+
+class VerifyPtpLockStatus(AntaTest):
+ """Verifies that the device was locked to the upstream Precision Time Protocol (PTP) Grandmaster (GM) in the last minute.
+
+ Expected Results
+ ----------------
+ * Success: The test will pass if the device was locked to the upstream GM in the last minute.
+ * Failure: The test will fail if the device was not locked to the upstream GM in the last minute.
+ * Skipped: The test will be skipped if PTP is not configured on the device.
+
+ Examples
+ --------
+ ```yaml
+ anta.tests.ptp:
+ - VerifyPtpLockStatus:
+ ```
"""
- name = "VerifyPtpStatus"
- description = "Verifies if the PTP agent is enabled."
- categories = ["ptp"]
- commands = [AntaCommand(command="show ptp")]
+ name = "VerifyPtpLockStatus"
+ description = "Verifies that the device was locked to the upstream PTP GM in the last minute."
+ categories: ClassVar[list[str]] = ["ptp"]
+ commands: ClassVar[list[AntaCommand | AntaTemplate]] = [AntaCommand(command="show ptp", revision=2)]
+ @skip_on_platforms(["cEOSLab", "vEOS-lab", "cEOSCloudLab"])
@AntaTest.anta_test
def test(self) -> None:
+ """Main test function for VerifyPtpLockStatus."""
+ threshold = 60
command_output = self.instance_commands[0].json_output
- if "ptpMode" in command_output.keys():
+ if (ptp_clock_summary := command_output.get("ptpClockSummary")) is None:
+ self.result.is_skipped("PTP is not configured")
+ return
+
+ time_difference = ptp_clock_summary["currentPtpSystemTime"] - ptp_clock_summary["lastSyncTime"]
+
+ if time_difference >= threshold:
+ self.result.is_failure(f"The device lock is more than {threshold}s old: {time_difference}s")
+ else:
+ self.result.is_success()
+
+
+class VerifyPtpOffset(AntaTest):
+ """Verifies that the Precision Time Protocol (PTP) timing offset is within +/- 1000ns from the master clock.
+
+ Expected Results
+ ----------------
+ * Success: The test will pass if the PTP timing offset is within +/- 1000ns from the master clock.
+ * Failure: The test will fail if the PTP timing offset is greater than +/- 1000ns from the master clock.
+ * Skipped: The test will be skipped if PTP is not configured on the device.
+
+ Examples
+ --------
+ ```yaml
+ anta.tests.ptp:
+ - VerifyPtpOffset:
+ ```
+ """
+
+ name = "VerifyPtpOffset"
+ description = "Verifies that the PTP timing offset is within +/- 1000ns from the master clock."
+ categories: ClassVar[list[str]] = ["ptp"]
+ commands: ClassVar[list[AntaCommand | AntaTemplate]] = [AntaCommand(command="show ptp monitor", revision=1)]
+
+ @skip_on_platforms(["cEOSLab", "vEOS-lab", "cEOSCloudLab"])
+ @AntaTest.anta_test
+ def test(self) -> None:
+ """Main test function for VerifyPtpOffset."""
+ threshold = 1000
+ offset_interfaces: dict[str, list[int]] = {}
+ command_output = self.instance_commands[0].json_output
+
+ if not command_output["ptpMonitorData"]:
+ self.result.is_skipped("PTP is not configured")
+ return
+
+ for interface in command_output["ptpMonitorData"]:
+ if abs(interface["offsetFromMaster"]) > threshold:
+ offset_interfaces.setdefault(interface["intf"], []).append(interface["offsetFromMaster"])
+
+ if offset_interfaces:
+ self.result.is_failure(f"The device timing offset from master is greater than +/- {threshold}ns: {offset_interfaces}")
+ else:
+ self.result.is_success()
+
+
+class VerifyPtpPortModeStatus(AntaTest):
+ """Verifies that all interfaces are in a valid Precision Time Protocol (PTP) state.
+
+ The interfaces can be in one of the following state: Master, Slave, Passive, or Disabled.
+
+ Expected Results
+ ----------------
+ * Success: The test will pass if all PTP enabled interfaces are in a valid state.
+ * Failure: The test will fail if there are no PTP enabled interfaces or if some interfaces are not in a valid state.
+
+ Examples
+ --------
+ ```yaml
+ anta.tests.ptp:
+ - VerifyPtpPortModeStatus:
+ ```
+ """
+
+ name = "VerifyPtpPortModeStatus"
+ description = "Verifies the PTP interfaces state."
+ categories: ClassVar[list[str]] = ["ptp"]
+ commands: ClassVar[list[AntaCommand | AntaTemplate]] = [AntaCommand(command="show ptp", revision=2)]
+
+ @skip_on_platforms(["cEOSLab", "vEOS-lab", "cEOSCloudLab"])
+ @AntaTest.anta_test
+ def test(self) -> None:
+ """Main test function for VerifyPtpPortModeStatus."""
+ valid_state = ("psMaster", "psSlave", "psPassive", "psDisabled")
+ command_output = self.instance_commands[0].json_output
+
+ if not command_output["ptpIntfSummaries"]:
+ self.result.is_failure("No interfaces are PTP enabled")
+ return
+
+ invalid_interfaces = [
+ interface
+ for interface in command_output["ptpIntfSummaries"]
+ for vlan in command_output["ptpIntfSummaries"][interface]["ptpIntfVlanSummaries"]
+ if vlan["portState"] not in valid_state
+ ]
+
+ if not invalid_interfaces:
self.result.is_success()
else:
- self.result.is_failure("PTP agent disabled")
+ self.result.is_failure(f"The following interface(s) are not in a valid PTP state: '{invalid_interfaces}'")
diff --git a/anta/tests/routing/__init__.py b/anta/tests/routing/__init__.py
index e772bee..d4b3786 100644
--- a/anta/tests/routing/__init__.py
+++ b/anta/tests/routing/__init__.py
@@ -1,3 +1,4 @@
# Copyright (c) 2023-2024 Arista Networks, Inc.
# Use of this source code is governed by the Apache License 2.0
# that can be found in the LICENSE file.
+"""Package related to routing tests."""
diff --git a/anta/tests/routing/bgp.py b/anta/tests/routing/bgp.py
index 334ac3b..41c2495 100644
--- a/anta/tests/routing/bgp.py
+++ b/anta/tests/routing/bgp.py
@@ -1,41 +1,40 @@
# Copyright (c) 2023-2024 Arista Networks, Inc.
# Use of this source code is governed by the Apache License 2.0
# that can be found in the LICENSE file.
-"""
-BGP test functions
-"""
+"""Module related to BGP tests."""
+
# Mypy does not understand AntaTest.Input typing
# mypy: disable-error-code=attr-defined
from __future__ import annotations
from ipaddress import IPv4Address, IPv4Network, IPv6Address
-from typing import Any, List, Optional, Union, cast
+from typing import Any, ClassVar
-from pydantic import BaseModel, Field, PositiveInt, model_validator, utils
+from pydantic import BaseModel, Field, PositiveInt, model_validator
+from pydantic.v1.utils import deep_update
from pydantic_extra_types.mac_address import MacAddress
from anta.custom_types import Afi, MultiProtocolCaps, Safi, Vni
from anta.models import AntaCommand, AntaTemplate, AntaTest
-from anta.tools.get_item import get_item
-from anta.tools.get_value import get_value
-
-# Need to keep List for pydantic in python 3.8
+from anta.tools import get_item, get_value
-def _add_bgp_failures(failures: dict[tuple[str, Union[str, None]], dict[str, Any]], afi: Afi, safi: Optional[Safi], vrf: str, issue: Any) -> None:
- """
- Add a BGP failure entry to the given `failures` dictionary.
+def _add_bgp_failures(failures: dict[tuple[str, str | None], dict[str, Any]], afi: Afi, safi: Safi | None, vrf: str, issue: str | dict[str, Any]) -> None:
+ """Add a BGP failure entry to the given `failures` dictionary.
Note: This function modifies `failures` in-place.
- Parameters:
- failures (dict): The dictionary to which the failure will be added.
- afi (Afi): The address family identifier.
- vrf (str): The VRF name.
- safi (Safi, optional): The subsequent address family identifier.
- issue (Any): A description of the issue. Can be of any type.
+ Args:
+ ----
+ failures: The dictionary to which the failure will be added.
+ afi: The address family identifier.
+ vrf: The VRF name.
+ safi: The subsequent address family identifier.
+ issue: A description of the issue. Can be of any type.
- The `failures` dictionnary will have the following structure:
+ Example:
+ -------
+ The `failures` dictionary will have the following structure:
{
('afi1', 'safi1'): {
'afi': 'afi1',
@@ -52,40 +51,43 @@ def _add_bgp_failures(failures: dict[tuple[str, Union[str, None]], dict[str, Any
}
}
}
+
"""
key = (afi, safi)
- if safi:
- failure_entry = failures.setdefault(key, {"afi": afi, "safi": safi, "vrfs": {}})
- else:
- failure_entry = failures.setdefault(key, {"afi": afi, "vrfs": {}})
+ failure_entry = failures.setdefault(key, {"afi": afi, "safi": safi, "vrfs": {}}) if safi else failures.setdefault(key, {"afi": afi, "vrfs": {}})
failure_entry["vrfs"][vrf] = issue
-def _check_peer_issues(peer_data: Optional[dict[str, Any]]) -> dict[str, Any]:
- """
- Check for issues in BGP peer data.
+def _check_peer_issues(peer_data: dict[str, Any] | None) -> dict[str, Any]:
+ """Check for issues in BGP peer data.
- Parameters:
- peer_data (dict, optional): The BGP peer data dictionary nested in the `show bgp <afi> <safi> summary` command.
+ Args:
+ ----
+ peer_data: The BGP peer data dictionary nested in the `show bgp <afi> <safi> summary` command.
- Returns:
+ Returns
+ -------
dict: Dictionary with keys indicating issues or an empty dictionary if no issues.
+ Raises
+ ------
+ ValueError: If any of the required keys ("peerState", "inMsgQueue", "outMsgQueue") are missing in `peer_data`, i.e. invalid BGP peer data.
+
Example:
+ -------
{"peerNotFound": True}
{"peerState": "Idle", "inMsgQueue": 2, "outMsgQueue": 0}
{}
- Raises:
- ValueError: If any of the required keys ("peerState", "inMsgQueue", "outMsgQueue") are missing in `peer_data`, i.e. invalid BGP peer data.
"""
if peer_data is None:
return {"peerNotFound": True}
if any(key not in peer_data for key in ["peerState", "inMsgQueue", "outMsgQueue"]):
- raise ValueError("Provided BGP peer data is invalid.")
+ msg = "Provided BGP peer data is invalid."
+ raise ValueError(msg)
if peer_data["peerState"] != "Established" or peer_data["inMsgQueue"] != 0 or peer_data["outMsgQueue"] != 0:
return {"peerState": peer_data["peerState"], "inMsgQueue": peer_data["inMsgQueue"], "outMsgQueue": peer_data["outMsgQueue"]}
@@ -96,80 +98,110 @@ def _check_peer_issues(peer_data: Optional[dict[str, Any]]) -> dict[str, Any]:
def _add_bgp_routes_failure(
bgp_routes: list[str], bgp_output: dict[str, Any], peer: str, vrf: str, route_type: str = "advertised_routes"
) -> dict[str, dict[str, dict[str, dict[str, list[str]]]]]:
- """
- Identifies missing BGP routes and invalid or inactive route entries.
+ """Identify missing BGP routes and invalid or inactive route entries.
This function checks the BGP output from the device against the expected routes.
+
It identifies any missing routes as well as any routes that are invalid or inactive. The results are returned in a dictionary.
- Parameters:
- bgp_routes (list[str]): The list of expected routes.
- bgp_output (dict[str, Any]): The BGP output from the device.
- peer (str): The IP address of the BGP peer.
- vrf (str): The name of the VRF for which the routes need to be verified.
- route_type (str, optional): The type of BGP routes. Defaults to 'advertised_routes'.
+ Args:
+ ----
+ bgp_routes: The list of expected routes.
+ bgp_output: The BGP output from the device.
+ peer: The IP address of the BGP peer.
+ vrf: The name of the VRF for which the routes need to be verified.
+ route_type: The type of BGP routes. Defaults to 'advertised_routes'.
- Returns:
+ Returns
+ -------
dict[str, dict[str, dict[str, dict[str, list[str]]]]]: A dictionary containing the missing routes and invalid or inactive routes.
- """
+ """
# Prepare the failure routes dictionary
failure_routes: dict[str, dict[str, Any]] = {}
# Iterate over the expected BGP routes
for route in bgp_routes:
- route = str(route)
- failure = {"bgp_peers": {peer: {vrf: {route_type: {route: Any}}}}}
+ str_route = str(route)
+ failure = {"bgp_peers": {peer: {vrf: {route_type: {str_route: Any}}}}}
# Check if the route is missing in the BGP output
- if route not in bgp_output:
+ if str_route not in bgp_output:
# If missing, add it to the failure routes dictionary
- failure["bgp_peers"][peer][vrf][route_type][route] = "Not found"
- failure_routes = utils.deep_update(failure_routes, failure)
+ failure["bgp_peers"][peer][vrf][route_type][str_route] = "Not found"
+ failure_routes = deep_update(failure_routes, failure)
continue
# Check if the route is active and valid
- is_active = bgp_output[route]["bgpRoutePaths"][0]["routeType"]["valid"]
- is_valid = bgp_output[route]["bgpRoutePaths"][0]["routeType"]["active"]
+ is_active = bgp_output[str_route]["bgpRoutePaths"][0]["routeType"]["valid"]
+ is_valid = bgp_output[str_route]["bgpRoutePaths"][0]["routeType"]["active"]
# If the route is either inactive or invalid, add it to the failure routes dictionary
if not is_active or not is_valid:
- failure["bgp_peers"][peer][vrf][route_type][route] = {"valid": is_valid, "active": is_active}
- failure_routes = utils.deep_update(failure_routes, failure)
+ failure["bgp_peers"][peer][vrf][route_type][str_route] = {"valid": is_valid, "active": is_active}
+ failure_routes = deep_update(failure_routes, failure)
return failure_routes
class VerifyBGPPeerCount(AntaTest):
- """
- This test verifies the count of BGP peers for a given address family.
+ """Verifies the count of BGP peers for a given address family.
+
+ It supports multiple types of Address Families Identifiers (AFI) and Subsequent Address Family Identifiers (SAFI).
+
+ For SR-TE SAFI, the EOS command supports sr-te first then ipv4/ipv6 (AFI) which is handled automatically in this test.
- It supports multiple types of address families (AFI) and subsequent service families (SAFI).
Please refer to the Input class attributes below for details.
- Expected Results:
- * success: If the count of BGP peers matches the expected count for each address family and VRF.
- * failure: If the count of BGP peers does not match the expected count, or if BGP is not configured for an expected VRF or address family.
+ Expected Results
+ ----------------
+ * Success: If the count of BGP peers matches the expected count for each address family and VRF.
+ * Failure: If the count of BGP peers does not match the expected count, or if BGP is not configured for an expected VRF or address family.
+
+ Examples
+ --------
+ ```yaml
+ anta.tests.routing:
+ bgp:
+ - VerifyBGPPeerCount:
+ address_families:
+ - afi: "evpn"
+ num_peers: 2
+ - afi: "ipv4"
+ safi: "unicast"
+ vrf: "PROD"
+ num_peers: 2
+ - afi: "ipv4"
+ safi: "unicast"
+ vrf: "default"
+ num_peers: 3
+ - afi: "ipv4"
+ safi: "multicast"
+ vrf: "DEV"
+ num_peers: 3
+ ```
"""
name = "VerifyBGPPeerCount"
description = "Verifies the count of BGP peers."
- categories = ["bgp"]
- commands = [
- AntaTemplate(template="show bgp {afi} {safi} summary vrf {vrf}"),
- AntaTemplate(template="show bgp {afi} summary"),
+ categories: ClassVar[list[str]] = ["bgp"]
+ commands: ClassVar[list[AntaCommand | AntaTemplate]] = [
+ AntaTemplate(template="show bgp {afi} {safi} summary vrf {vrf}", revision=3),
+ AntaTemplate(template="show bgp {afi} summary", revision=3),
]
- class Input(AntaTest.Input): # pylint: disable=missing-class-docstring
- address_families: List[BgpAfi]
- """
- List of BGP address families (BgpAfi)
- """
+ class Input(AntaTest.Input):
+ """Input model for the VerifyBGPPeerCount test."""
+
+ address_families: list[BgpAfi]
+ """List of BGP address families (BgpAfi)."""
+
+ class BgpAfi(BaseModel):
+ """Model for a BGP address family (AFI) and subsequent address family (SAFI)."""
- class BgpAfi(BaseModel): # pylint: disable=missing-class-docstring
afi: Afi
- """BGP address family (AFI)"""
- safi: Optional[Safi] = None
+ """BGP address family (AFI)."""
+ safi: Safi | None = None
"""Optional BGP subsequent service family (SAFI).
If the input `afi` is `ipv4` or `ipv6`, a valid `safi` must be provided.
@@ -181,12 +213,11 @@ class VerifyBGPPeerCount(AntaTest):
If the input `afi` is not `ipv4` or `ipv6`, e.g. `evpn`, `vrf` must be `default`.
"""
num_peers: PositiveInt
- """Number of expected BGP peer(s)"""
+ """Number of expected BGP peer(s)."""
@model_validator(mode="after")
def validate_inputs(self: BaseModel) -> BaseModel:
- """
- Validate the inputs provided to the BgpAfi class.
+ """Validate the inputs provided to the BgpAfi class.
If afi is either ipv4 or ipv6, safi must be provided.
@@ -194,36 +225,54 @@ class VerifyBGPPeerCount(AntaTest):
"""
if self.afi in ["ipv4", "ipv6"]:
if self.safi is None:
- raise ValueError("'safi' must be provided when afi is ipv4 or ipv6")
+ msg = "'safi' must be provided when afi is ipv4 or ipv6"
+ raise ValueError(msg)
elif self.safi is not None:
- raise ValueError("'safi' must not be provided when afi is not ipv4 or ipv6")
+ msg = "'safi' must not be provided when afi is not ipv4 or ipv6"
+ raise ValueError(msg)
elif self.vrf != "default":
- raise ValueError("'vrf' must be default when afi is not ipv4 or ipv6")
+ msg = "'vrf' must be default when afi is not ipv4 or ipv6"
+ raise ValueError(msg)
return self
def render(self, template: AntaTemplate) -> list[AntaCommand]:
+ """Render the template for each BGP address family in the input list."""
commands = []
for afi in self.inputs.address_families:
- if template == VerifyBGPPeerCount.commands[0] and afi.afi in ["ipv4", "ipv6"]:
- commands.append(template.render(afi=afi.afi, safi=afi.safi, vrf=afi.vrf, num_peers=afi.num_peers))
+ if template == VerifyBGPPeerCount.commands[0] and afi.afi in ["ipv4", "ipv6"] and afi.safi != "sr-te":
+ commands.append(template.render(afi=afi.afi, safi=afi.safi, vrf=afi.vrf))
+
+ # For SR-TE SAFI, the EOS command supports sr-te first then ipv4/ipv6
+ elif template == VerifyBGPPeerCount.commands[0] and afi.afi in ["ipv4", "ipv6"] and afi.safi == "sr-te":
+ commands.append(template.render(afi=afi.safi, safi=afi.afi, vrf=afi.vrf))
elif template == VerifyBGPPeerCount.commands[1] and afi.afi not in ["ipv4", "ipv6"]:
- commands.append(template.render(afi=afi.afi, vrf=afi.vrf, num_peers=afi.num_peers))
+ commands.append(template.render(afi=afi.afi))
return commands
@AntaTest.anta_test
def test(self) -> None:
+ """Main test function for VerifyBGPPeerCount."""
self.result.is_success()
failures: dict[tuple[str, Any], dict[str, Any]] = {}
for command in self.instance_commands:
+ num_peers = None
peer_count = 0
command_output = command.json_output
- afi = cast(Afi, command.params.get("afi"))
- safi = cast(Optional[Safi], command.params.get("safi"))
- afi_vrf = cast(str, command.params.get("vrf"))
- num_peers = cast(PositiveInt, command.params.get("num_peers"))
+ afi = command.params.afi
+ safi = command.params.safi if hasattr(command.params, "safi") else None
+ afi_vrf = command.params.vrf if hasattr(command.params, "vrf") else "default"
+
+ # Swapping AFI and SAFI in case of SR-TE
+ if afi == "sr-te":
+ afi, safi = safi, afi
+
+ for input_entry in self.inputs.address_families:
+ if input_entry.afi == afi and input_entry.safi == safi and input_entry.vrf == afi_vrf:
+ num_peers = input_entry.num_peers
+ break
if not (vrfs := command_output.get("vrfs")):
_add_bgp_failures(failures=failures, afi=afi, safi=safi, vrf=afi_vrf, issue="Not Configured")
@@ -243,37 +292,58 @@ class VerifyBGPPeerCount(AntaTest):
class VerifyBGPPeersHealth(AntaTest):
- """
- This test verifies the health of BGP peers.
+ """Verifies the health of BGP peers.
It will validate that all BGP sessions are established and all message queues for these BGP sessions are empty for a given address family.
- It supports multiple types of address families (AFI) and subsequent service families (SAFI).
+ It supports multiple types of Address Families Identifiers (AFI) and Subsequent Address Family Identifiers (SAFI).
+
+ For SR-TE SAFI, the EOS command supports sr-te first then ipv4/ipv6 (AFI) which is handled automatically in this test.
+
Please refer to the Input class attributes below for details.
- Expected Results:
- * success: If all BGP sessions are established and all messages queues are empty for each address family and VRF.
- * failure: If there are issues with any of the BGP sessions, or if BGP is not configured for an expected VRF or address family.
+ Expected Results
+ ----------------
+ * Success: If all BGP sessions are established and all messages queues are empty for each address family and VRF.
+ * Failure: If there are issues with any of the BGP sessions, or if BGP is not configured for an expected VRF or address family.
+
+ Examples
+ --------
+ ```yaml
+ anta.tests.routing:
+ bgp:
+ - VerifyBGPPeersHealth:
+ address_families:
+ - afi: "evpn"
+ - afi: "ipv4"
+ safi: "unicast"
+ vrf: "default"
+ - afi: "ipv6"
+ safi: "unicast"
+ vrf: "DEV"
+ ```
"""
name = "VerifyBGPPeersHealth"
description = "Verifies the health of BGP peers"
- categories = ["bgp"]
- commands = [
- AntaTemplate(template="show bgp {afi} {safi} summary vrf {vrf}"),
- AntaTemplate(template="show bgp {afi} summary"),
+ categories: ClassVar[list[str]] = ["bgp"]
+ commands: ClassVar[list[AntaCommand | AntaTemplate]] = [
+ AntaTemplate(template="show bgp {afi} {safi} summary vrf {vrf}", revision=3),
+ AntaTemplate(template="show bgp {afi} summary", revision=3),
]
- class Input(AntaTest.Input): # pylint: disable=missing-class-docstring
- address_families: List[BgpAfi]
- """
- List of BGP address families (BgpAfi)
- """
+ class Input(AntaTest.Input):
+ """Input model for the VerifyBGPPeersHealth test."""
+
+ address_families: list[BgpAfi]
+ """List of BGP address families (BgpAfi)."""
+
+ class BgpAfi(BaseModel):
+ """Model for a BGP address family (AFI) and subsequent address family (SAFI)."""
- class BgpAfi(BaseModel): # pylint: disable=missing-class-docstring
afi: Afi
- """BGP address family (AFI)"""
- safi: Optional[Safi] = None
+ """BGP address family (AFI)."""
+ safi: Safi | None = None
"""Optional BGP subsequent service family (SAFI).
If the input `afi` is `ipv4` or `ipv6`, a valid `safi` must be provided.
@@ -287,8 +357,7 @@ class VerifyBGPPeersHealth(AntaTest):
@model_validator(mode="after")
def validate_inputs(self: BaseModel) -> BaseModel:
- """
- Validate the inputs provided to the BgpAfi class.
+ """Validate the inputs provided to the BgpAfi class.
If afi is either ipv4 or ipv6, safi must be provided.
@@ -296,24 +365,33 @@ class VerifyBGPPeersHealth(AntaTest):
"""
if self.afi in ["ipv4", "ipv6"]:
if self.safi is None:
- raise ValueError("'safi' must be provided when afi is ipv4 or ipv6")
+ msg = "'safi' must be provided when afi is ipv4 or ipv6"
+ raise ValueError(msg)
elif self.safi is not None:
- raise ValueError("'safi' must not be provided when afi is not ipv4 or ipv6")
+ msg = "'safi' must not be provided when afi is not ipv4 or ipv6"
+ raise ValueError(msg)
elif self.vrf != "default":
- raise ValueError("'vrf' must be default when afi is not ipv4 or ipv6")
+ msg = "'vrf' must be default when afi is not ipv4 or ipv6"
+ raise ValueError(msg)
return self
def render(self, template: AntaTemplate) -> list[AntaCommand]:
+ """Render the template for each BGP address family in the input list."""
commands = []
for afi in self.inputs.address_families:
- if template == VerifyBGPPeersHealth.commands[0] and afi.afi in ["ipv4", "ipv6"]:
+ if template == VerifyBGPPeersHealth.commands[0] and afi.afi in ["ipv4", "ipv6"] and afi.safi != "sr-te":
commands.append(template.render(afi=afi.afi, safi=afi.safi, vrf=afi.vrf))
+
+ # For SR-TE SAFI, the EOS command supports sr-te first then ipv4/ipv6
+ elif template == VerifyBGPPeersHealth.commands[0] and afi.afi in ["ipv4", "ipv6"] and afi.safi == "sr-te":
+ commands.append(template.render(afi=afi.safi, safi=afi.afi, vrf=afi.vrf))
elif template == VerifyBGPPeersHealth.commands[1] and afi.afi not in ["ipv4", "ipv6"]:
- commands.append(template.render(afi=afi.afi, vrf=afi.vrf))
+ commands.append(template.render(afi=afi.afi))
return commands
@AntaTest.anta_test
def test(self) -> None:
+ """Main test function for VerifyBGPPeersHealth."""
self.result.is_success()
failures: dict[tuple[str, Any], dict[str, Any]] = {}
@@ -321,9 +399,13 @@ class VerifyBGPPeersHealth(AntaTest):
for command in self.instance_commands:
command_output = command.json_output
- afi = cast(Afi, command.params.get("afi"))
- safi = cast(Optional[Safi], command.params.get("safi"))
- afi_vrf = cast(str, command.params.get("vrf"))
+ afi = command.params.afi
+ safi = command.params.safi if hasattr(command.params, "safi") else None
+ afi_vrf = command.params.vrf if hasattr(command.params, "vrf") else "default"
+
+ # Swapping AFI and SAFI in case of SR-TE
+ if afi == "sr-te":
+ afi, safi = safi, afi
if not (vrfs := command_output.get("vrfs")):
_add_bgp_failures(failures=failures, afi=afi, safi=safi, vrf=afi_vrf, issue="Not Configured")
@@ -349,37 +431,62 @@ class VerifyBGPPeersHealth(AntaTest):
class VerifyBGPSpecificPeers(AntaTest):
- """
- This test verifies the health of specific BGP peer(s).
+ """Verifies the health of specific BGP peer(s).
It will validate that the BGP session is established and all message queues for this BGP session are empty for the given peer(s).
- It supports multiple types of address families (AFI) and subsequent service families (SAFI).
+ It supports multiple types of Address Families Identifiers (AFI) and Subsequent Address Family Identifiers (SAFI).
+
+ For SR-TE SAFI, the EOS command supports sr-te first then ipv4/ipv6 (AFI) which is handled automatically in this test.
+
Please refer to the Input class attributes below for details.
- Expected Results:
- * success: If the BGP session is established and all messages queues are empty for each given peer.
- * failure: If the BGP session has issues or is not configured, or if BGP is not configured for an expected VRF or address family.
+ Expected Results
+ ----------------
+ * Success: If the BGP session is established and all messages queues are empty for each given peer.
+ * Failure: If the BGP session has issues or is not configured, or if BGP is not configured for an expected VRF or address family.
+
+ Examples
+ --------
+ ```yaml
+ anta.tests.routing:
+ bgp:
+ - VerifyBGPSpecificPeers:
+ address_families:
+ - afi: "evpn"
+ peers:
+ - 10.1.0.1
+ - 10.1.0.2
+ - afi: "ipv4"
+ safi: "unicast"
+ peers:
+ - 10.1.254.1
+ - 10.1.255.0
+ - 10.1.255.2
+ - 10.1.255.4
+ ```
"""
name = "VerifyBGPSpecificPeers"
description = "Verifies the health of specific BGP peer(s)."
- categories = ["bgp"]
- commands = [
- AntaTemplate(template="show bgp {afi} {safi} summary vrf {vrf}"),
- AntaTemplate(template="show bgp {afi} summary"),
+ categories: ClassVar[list[str]] = ["bgp"]
+ commands: ClassVar[list[AntaCommand | AntaTemplate]] = [
+ AntaTemplate(template="show bgp {afi} {safi} summary vrf {vrf}", revision=3),
+ AntaTemplate(template="show bgp {afi} summary", revision=3),
]
- class Input(AntaTest.Input): # pylint: disable=missing-class-docstring
- address_families: List[BgpAfi]
- """
- List of BGP address families (BgpAfi)
- """
+ class Input(AntaTest.Input):
+ """Input model for the VerifyBGPSpecificPeers test."""
+
+ address_families: list[BgpAfi]
+ """List of BGP address families (BgpAfi)."""
+
+ class BgpAfi(BaseModel):
+ """Model for a BGP address family (AFI) and subsequent address family (SAFI)."""
- class BgpAfi(BaseModel): # pylint: disable=missing-class-docstring
afi: Afi
- """BGP address family (AFI)"""
- safi: Optional[Safi] = None
+ """BGP address family (AFI)."""
+ safi: Safi | None = None
"""Optional BGP subsequent service family (SAFI).
If the input `afi` is `ipv4` or `ipv6`, a valid `safi` must be provided.
@@ -392,13 +499,12 @@ class VerifyBGPSpecificPeers(AntaTest):
If the input `afi` is not `ipv4` or `ipv6`, e.g. `evpn`, `vrf` must be `default`.
"""
- peers: List[Union[IPv4Address, IPv6Address]]
- """List of BGP IPv4 or IPv6 peer"""
+ peers: list[IPv4Address | IPv6Address]
+ """List of BGP IPv4 or IPv6 peer."""
@model_validator(mode="after")
def validate_inputs(self: BaseModel) -> BaseModel:
- """
- Validate the inputs provided to the BgpAfi class.
+ """Validate the inputs provided to the BgpAfi class.
If afi is either ipv4 or ipv6, safi must be provided and vrf must NOT be all.
@@ -406,26 +512,37 @@ class VerifyBGPSpecificPeers(AntaTest):
"""
if self.afi in ["ipv4", "ipv6"]:
if self.safi is None:
- raise ValueError("'safi' must be provided when afi is ipv4 or ipv6")
+ msg = "'safi' must be provided when afi is ipv4 or ipv6"
+ raise ValueError(msg)
if self.vrf == "all":
- raise ValueError("'all' is not supported in this test. Use VerifyBGPPeersHealth test instead.")
+ msg = "'all' is not supported in this test. Use VerifyBGPPeersHealth test instead."
+ raise ValueError(msg)
elif self.safi is not None:
- raise ValueError("'safi' must not be provided when afi is not ipv4 or ipv6")
+ msg = "'safi' must not be provided when afi is not ipv4 or ipv6"
+ raise ValueError(msg)
elif self.vrf != "default":
- raise ValueError("'vrf' must be default when afi is not ipv4 or ipv6")
+ msg = "'vrf' must be default when afi is not ipv4 or ipv6"
+ raise ValueError(msg)
return self
def render(self, template: AntaTemplate) -> list[AntaCommand]:
+ """Render the template for each BGP address family in the input list."""
commands = []
+
for afi in self.inputs.address_families:
- if template == VerifyBGPSpecificPeers.commands[0] and afi.afi in ["ipv4", "ipv6"]:
- commands.append(template.render(afi=afi.afi, safi=afi.safi, vrf=afi.vrf, peers=afi.peers))
+ if template == VerifyBGPSpecificPeers.commands[0] and afi.afi in ["ipv4", "ipv6"] and afi.safi != "sr-te":
+ commands.append(template.render(afi=afi.afi, safi=afi.safi, vrf=afi.vrf))
+
+ # For SR-TE SAFI, the EOS command supports sr-te first then ipv4/ipv6
+ elif template == VerifyBGPSpecificPeers.commands[0] and afi.afi in ["ipv4", "ipv6"] and afi.safi == "sr-te":
+ commands.append(template.render(afi=afi.safi, safi=afi.afi, vrf=afi.vrf))
elif template == VerifyBGPSpecificPeers.commands[1] and afi.afi not in ["ipv4", "ipv6"]:
- commands.append(template.render(afi=afi.afi, vrf=afi.vrf, peers=afi.peers))
+ commands.append(template.render(afi=afi.afi))
return commands
@AntaTest.anta_test
def test(self) -> None:
+ """Main test function for VerifyBGPSpecificPeers."""
self.result.is_success()
failures: dict[tuple[str, Any], dict[str, Any]] = {}
@@ -433,10 +550,18 @@ class VerifyBGPSpecificPeers(AntaTest):
for command in self.instance_commands:
command_output = command.json_output
- afi = cast(Afi, command.params.get("afi"))
- safi = cast(Optional[Safi], command.params.get("safi"))
- afi_vrf = cast(str, command.params.get("vrf"))
- afi_peers = cast(List[Union[IPv4Address, IPv6Address]], command.params.get("peers", []))
+ afi = command.params.afi
+ safi = command.params.safi if hasattr(command.params, "safi") else None
+ afi_vrf = command.params.vrf if hasattr(command.params, "vrf") else "default"
+
+ # Swapping AFI and SAFI in case of SR-TE
+ if afi == "sr-te":
+ afi, safi = safi, afi
+
+ for input_entry in self.inputs.address_families:
+ if input_entry.afi == afi and input_entry.safi == safi and input_entry.vrf == afi_vrf:
+ afi_peers = input_entry.peers
+ break
if not (vrfs := command_output.get("vrfs")):
_add_bgp_failures(failures=failures, afi=afi, safi=safi, vrf=afi_vrf, issue="Not Configured")
@@ -458,63 +583,82 @@ class VerifyBGPSpecificPeers(AntaTest):
class VerifyBGPExchangedRoutes(AntaTest):
- """
- Verifies if the BGP peers have correctly advertised and received routes.
+ """Verifies if the BGP peers have correctly advertised and received routes.
+
The route type should be 'valid' and 'active' for a specified VRF.
- Expected results:
- * success: If the BGP peers have correctly advertised and received routes of type 'valid' and 'active' for a specified VRF.
- * failure: If a BGP peer is not found, the expected advertised/received routes are not found, or the routes are not 'valid' or 'active'.
+ Expected Results
+ ----------------
+ * Success: If the BGP peers have correctly advertised and received routes of type 'valid' and 'active' for a specified VRF.
+ * Failure: If a BGP peer is not found, the expected advertised/received routes are not found, or the routes are not 'valid' or 'active'.
+
+ Examples
+ --------
+ ```yaml
+ anta.tests.routing:
+ bgp:
+ - VerifyBGPExchangedRoutes:
+ bgp_peers:
+ - peer_address: 172.30.255.5
+ vrf: default
+ advertised_routes:
+ - 192.0.254.5/32
+ received_routes:
+ - 192.0.255.4/32
+ - peer_address: 172.30.255.1
+ vrf: default
+ advertised_routes:
+ - 192.0.255.1/32
+ - 192.0.254.5/32
+ received_routes:
+ - 192.0.254.3/32
+ ```
"""
name = "VerifyBGPExchangedRoutes"
- description = "Verifies if BGP peers have correctly advertised/received routes with type as valid and active for a specified VRF."
- categories = ["bgp"]
- commands = [
- AntaTemplate(template="show bgp neighbors {peer} advertised-routes vrf {vrf}"),
- AntaTemplate(template="show bgp neighbors {peer} routes vrf {vrf}"),
+ description = "Verifies the advertised and received routes of BGP peers."
+ categories: ClassVar[list[str]] = ["bgp"]
+ commands: ClassVar[list[AntaCommand | AntaTemplate]] = [
+ AntaTemplate(template="show bgp neighbors {peer} advertised-routes vrf {vrf}", revision=3),
+ AntaTemplate(template="show bgp neighbors {peer} routes vrf {vrf}", revision=3),
]
class Input(AntaTest.Input):
- """
- Input parameters of the testcase.
- """
+ """Input model for the VerifyBGPExchangedRoutes test."""
- bgp_peers: List[BgpNeighbors]
- """List of BGP peers"""
+ bgp_peers: list[BgpNeighbor]
+ """List of BGP neighbors."""
- class BgpNeighbors(BaseModel):
- """
- This class defines the details of a BGP peer.
- """
+ class BgpNeighbor(BaseModel):
+ """Model for a BGP neighbor."""
peer_address: IPv4Address
- """IPv4 address of a BGP peer"""
+ """IPv4 address of a BGP peer."""
vrf: str = "default"
"""Optional VRF for BGP peer. If not provided, it defaults to `default`."""
- advertised_routes: List[IPv4Network]
- """List of advertised routes of a BGP peer."""
- received_routes: List[IPv4Network]
- """List of received routes of a BGP peer."""
+ advertised_routes: list[IPv4Network]
+ """List of advertised routes in CIDR format."""
+ received_routes: list[IPv4Network]
+ """List of received routes in CIDR format."""
def render(self, template: AntaTemplate) -> list[AntaCommand]:
- """Renders the template with the provided inputs. Returns a list of commands to be executed."""
-
- return [
- template.render(peer=bgp_peer.peer_address, vrf=bgp_peer.vrf, advertised_routes=bgp_peer.advertised_routes, received_routes=bgp_peer.received_routes)
- for bgp_peer in self.inputs.bgp_peers
- ]
+ """Render the template for each BGP neighbor in the input list."""
+ return [template.render(peer=str(bgp_peer.peer_address), vrf=bgp_peer.vrf) for bgp_peer in self.inputs.bgp_peers]
@AntaTest.anta_test
def test(self) -> None:
+ """Main test function for VerifyBGPExchangedRoutes."""
failures: dict[str, dict[str, Any]] = {"bgp_peers": {}}
# Iterating over command output for different peers
for command in self.instance_commands:
- peer = str(command.params["peer"])
- vrf = command.params["vrf"]
- advertised_routes = command.params["advertised_routes"]
- received_routes = command.params["received_routes"]
+ peer = command.params.peer
+ vrf = command.params.vrf
+ for input_entry in self.inputs.bgp_peers:
+ if str(input_entry.peer_address) == peer and input_entry.vrf == vrf:
+ advertised_routes = input_entry.advertised_routes
+ received_routes = input_entry.received_routes
+ break
failure = {vrf: ""}
# Verify if a BGP peer is configured with the provided vrf
@@ -530,7 +674,7 @@ class VerifyBGPExchangedRoutes(AntaTest):
# Validate received routes
else:
failure_routes = _add_bgp_routes_failure(received_routes, bgp_routes, peer, vrf, route_type="received_routes")
- failures = utils.deep_update(failures, failure_routes)
+ failures = deep_update(failures, failure_routes)
if not failures["bgp_peers"]:
self.result.is_success()
@@ -539,40 +683,51 @@ class VerifyBGPExchangedRoutes(AntaTest):
class VerifyBGPPeerMPCaps(AntaTest):
- """
- Verifies the multiprotocol capabilities of a BGP peer in a specified VRF.
- Expected results:
- * success: The test will pass if the BGP peer's multiprotocol capabilities are advertised, received, and enabled in the specified VRF.
- * failure: The test will fail if BGP peers are not found or multiprotocol capabilities are not advertised, received, and enabled in the specified VRF.
+ """Verifies the multiprotocol capabilities of a BGP peer in a specified VRF.
+
+ Expected Results
+ ----------------
+ * Success: The test will pass if the BGP peer's multiprotocol capabilities are advertised, received, and enabled in the specified VRF.
+ * Failure: The test will fail if BGP peers are not found or multiprotocol capabilities are not advertised, received, and enabled in the specified VRF.
+
+ Examples
+ --------
+ ```yaml
+ anta.tests.routing:
+ bgp:
+ - VerifyBGPPeerMPCaps:
+ bgp_peers:
+ - peer_address: 172.30.11.1
+ vrf: default
+ capabilities:
+ - ipv4Unicast
+ ```
"""
name = "VerifyBGPPeerMPCaps"
- description = "Verifies the multiprotocol capabilities of a BGP peer in a specified VRF"
- categories = ["bgp"]
- commands = [AntaCommand(command="show bgp neighbors vrf all")]
+ description = "Verifies the multiprotocol capabilities of a BGP peer."
+ categories: ClassVar[list[str]] = ["bgp"]
+ commands: ClassVar[list[AntaCommand | AntaTemplate]] = [AntaCommand(command="show bgp neighbors vrf all", revision=3)]
class Input(AntaTest.Input):
- """
- Input parameters of the testcase.
- """
+ """Input model for the VerifyBGPPeerMPCaps test."""
- bgp_peers: List[BgpPeers]
+ bgp_peers: list[BgpPeer]
"""List of BGP peers"""
- class BgpPeers(BaseModel):
- """
- This class defines the details of a BGP peer.
- """
+ class BgpPeer(BaseModel):
+ """Model for a BGP peer."""
peer_address: IPv4Address
- """IPv4 address of a BGP peer"""
+ """IPv4 address of a BGP peer."""
vrf: str = "default"
"""Optional VRF for BGP peer. If not provided, it defaults to `default`."""
- capabilities: List[MultiProtocolCaps]
- """Multiprotocol capabilities"""
+ capabilities: list[MultiProtocolCaps]
+ """List of multiprotocol capabilities to be verified."""
@AntaTest.anta_test
def test(self) -> None:
+ """Main test function for VerifyBGPPeerMPCaps."""
failures: dict[str, Any] = {"bgp_peers": {}}
# Iterate over each bgp peer
@@ -588,7 +743,7 @@ class VerifyBGPPeerMPCaps(AntaTest):
or (bgp_output := get_item(bgp_output, "peerAddress", peer)) is None
):
failure["bgp_peers"][peer][vrf] = {"status": "Not configured"}
- failures = utils.deep_update(failures, failure)
+ failures = deep_update(failures, failure)
continue
# Check each capability
@@ -599,12 +754,12 @@ class VerifyBGPPeerMPCaps(AntaTest):
# Check if capabilities are missing
if not capability_output:
failure["bgp_peers"][peer][vrf][capability] = "not found"
- failures = utils.deep_update(failures, failure)
+ failures = deep_update(failures, failure)
# Check if capabilities are not advertised, received, or enabled
elif not all(capability_output.get(prop, False) for prop in ["advertised", "received", "enabled"]):
failure["bgp_peers"][peer][vrf][capability] = capability_output
- failures = utils.deep_update(failures, failure)
+ failures = deep_update(failures, failure)
# Check if there are any failures
if not failures["bgp_peers"]:
@@ -614,38 +769,47 @@ class VerifyBGPPeerMPCaps(AntaTest):
class VerifyBGPPeerASNCap(AntaTest):
- """
- Verifies the four octet asn capabilities of a BGP peer in a specified VRF.
- Expected results:
- * success: The test will pass if BGP peer's four octet asn capabilities are advertised, received, and enabled in the specified VRF.
- * failure: The test will fail if BGP peers are not found or four octet asn capabilities are not advertised, received, and enabled in the specified VRF.
+ """Verifies the four octet asn capabilities of a BGP peer in a specified VRF.
+
+ Expected Results
+ ----------------
+ * Success: The test will pass if BGP peer's four octet asn capabilities are advertised, received, and enabled in the specified VRF.
+ * Failure: The test will fail if BGP peers are not found or four octet asn capabilities are not advertised, received, and enabled in the specified VRF.
+
+ Examples
+ --------
+ ```yaml
+ anta.tests.routing:
+ bgp:
+ - VerifyBGPPeerASNCap:
+ bgp_peers:
+ - peer_address: 172.30.11.1
+ vrf: default
+ ```
"""
name = "VerifyBGPPeerASNCap"
- description = "Verifies the four octet asn capabilities of a BGP peer in a specified VRF."
- categories = ["bgp"]
- commands = [AntaCommand(command="show bgp neighbors vrf all")]
+ description = "Verifies the four octet asn capabilities of a BGP peer."
+ categories: ClassVar[list[str]] = ["bgp"]
+ commands: ClassVar[list[AntaCommand | AntaTemplate]] = [AntaCommand(command="show bgp neighbors vrf all", revision=3)]
class Input(AntaTest.Input):
- """
- Input parameters of the testcase.
- """
+ """Input model for the VerifyBGPPeerASNCap test."""
- bgp_peers: List[BgpPeers]
- """List of BGP peers"""
+ bgp_peers: list[BgpPeer]
+ """List of BGP peers."""
- class BgpPeers(BaseModel):
- """
- This class defines the details of a BGP peer.
- """
+ class BgpPeer(BaseModel):
+ """Model for a BGP peer."""
peer_address: IPv4Address
- """IPv4 address of a BGP peer"""
+ """IPv4 address of a BGP peer."""
vrf: str = "default"
"""Optional VRF for BGP peer. If not provided, it defaults to `default`."""
@AntaTest.anta_test
def test(self) -> None:
+ """Main test function for VerifyBGPPeerASNCap."""
failures: dict[str, Any] = {"bgp_peers": {}}
# Iterate over each bgp peer
@@ -660,7 +824,7 @@ class VerifyBGPPeerASNCap(AntaTest):
or (bgp_output := get_item(bgp_output, "peerAddress", peer)) is None
):
failure["bgp_peers"][peer][vrf] = {"status": "Not configured"}
- failures = utils.deep_update(failures, failure)
+ failures = deep_update(failures, failure)
continue
bgp_output = get_value(bgp_output, "neighborCapabilities.fourOctetAsnCap")
@@ -668,12 +832,12 @@ class VerifyBGPPeerASNCap(AntaTest):
# Check if four octet asn capabilities are found
if not bgp_output:
failure["bgp_peers"][peer][vrf] = {"fourOctetAsnCap": "not found"}
- failures = utils.deep_update(failures, failure)
+ failures = deep_update(failures, failure)
# Check if capabilities are not advertised, received, or enabled
elif not all(bgp_output.get(prop, False) for prop in ["advertised", "received", "enabled"]):
failure["bgp_peers"][peer][vrf] = {"fourOctetAsnCap": bgp_output}
- failures = utils.deep_update(failures, failure)
+ failures = deep_update(failures, failure)
# Check if there are any failures
if not failures["bgp_peers"]:
@@ -683,38 +847,47 @@ class VerifyBGPPeerASNCap(AntaTest):
class VerifyBGPPeerRouteRefreshCap(AntaTest):
- """
- Verifies the route refresh capabilities of a BGP peer in a specified VRF.
- Expected results:
- * success: The test will pass if the BGP peer's route refresh capabilities are advertised, received, and enabled in the specified VRF.
- * failure: The test will fail if BGP peers are not found or route refresh capabilities are not advertised, received, and enabled in the specified VRF.
+ """Verifies the route refresh capabilities of a BGP peer in a specified VRF.
+
+ Expected Results
+ ----------------
+ * Success: The test will pass if the BGP peer's route refresh capabilities are advertised, received, and enabled in the specified VRF.
+ * Failure: The test will fail if BGP peers are not found or route refresh capabilities are not advertised, received, and enabled in the specified VRF.
+
+ Examples
+ --------
+ ```yaml
+ anta.tests.routing:
+ bgp:
+ - VerifyBGPPeerRouteRefreshCap:
+ bgp_peers:
+ - peer_address: 172.30.11.1
+ vrf: default
+ ```
"""
name = "VerifyBGPPeerRouteRefreshCap"
- description = "Verifies the route refresh capabilities of a BGP peer in a specified VRF."
- categories = ["bgp"]
- commands = [AntaCommand(command="show bgp neighbors vrf all")]
+ description = "Verifies the route refresh capabilities of a BGP peer."
+ categories: ClassVar[list[str]] = ["bgp"]
+ commands: ClassVar[list[AntaCommand | AntaTemplate]] = [AntaCommand(command="show bgp neighbors vrf all", revision=3)]
class Input(AntaTest.Input):
- """
- Input parameters of the testcase.
- """
+ """Input model for the VerifyBGPPeerRouteRefreshCap test."""
- bgp_peers: List[BgpPeers]
+ bgp_peers: list[BgpPeer]
"""List of BGP peers"""
- class BgpPeers(BaseModel):
- """
- This class defines the details of a BGP peer.
- """
+ class BgpPeer(BaseModel):
+ """Model for a BGP peer."""
peer_address: IPv4Address
- """IPv4 address of a BGP peer"""
+ """IPv4 address of a BGP peer."""
vrf: str = "default"
"""Optional VRF for BGP peer. If not provided, it defaults to `default`."""
@AntaTest.anta_test
def test(self) -> None:
+ """Main test function for VerifyBGPPeerRouteRefreshCap."""
failures: dict[str, Any] = {"bgp_peers": {}}
# Iterate over each bgp peer
@@ -729,7 +902,7 @@ class VerifyBGPPeerRouteRefreshCap(AntaTest):
or (bgp_output := get_item(bgp_output, "peerAddress", peer)) is None
):
failure["bgp_peers"][peer][vrf] = {"status": "Not configured"}
- failures = utils.deep_update(failures, failure)
+ failures = deep_update(failures, failure)
continue
bgp_output = get_value(bgp_output, "neighborCapabilities.routeRefreshCap")
@@ -737,12 +910,12 @@ class VerifyBGPPeerRouteRefreshCap(AntaTest):
# Check if route refresh capabilities are found
if not bgp_output:
failure["bgp_peers"][peer][vrf] = {"routeRefreshCap": "not found"}
- failures = utils.deep_update(failures, failure)
+ failures = deep_update(failures, failure)
# Check if capabilities are not advertised, received, or enabled
elif not all(bgp_output.get(prop, False) for prop in ["advertised", "received", "enabled"]):
failure["bgp_peers"][peer][vrf] = {"routeRefreshCap": bgp_output}
- failures = utils.deep_update(failures, failure)
+ failures = deep_update(failures, failure)
# Check if there are any failures
if not failures["bgp_peers"]:
@@ -752,30 +925,40 @@ class VerifyBGPPeerRouteRefreshCap(AntaTest):
class VerifyBGPPeerMD5Auth(AntaTest):
- """
- Verifies the MD5 authentication and state of IPv4 BGP peers in a specified VRF.
- Expected results:
- * success: The test will pass if IPv4 BGP peers are configured with MD5 authentication and state as established in the specified VRF.
- * failure: The test will fail if IPv4 BGP peers are not found, state is not as established or MD5 authentication is not enabled in the specified VRF.
+ """Verifies the MD5 authentication and state of IPv4 BGP peers in a specified VRF.
+
+ Expected Results
+ ----------------
+ * Success: The test will pass if IPv4 BGP peers are configured with MD5 authentication and state as established in the specified VRF.
+ * Failure: The test will fail if IPv4 BGP peers are not found, state is not as established or MD5 authentication is not enabled in the specified VRF.
+
+ Examples
+ --------
+ ```yaml
+ anta.tests.routing:
+ bgp:
+ - VerifyBGPPeerMD5Auth:
+ bgp_peers:
+ - peer_address: 172.30.11.1
+ vrf: default
+ - peer_address: 172.30.11.5
+ vrf: default
+ ```
"""
name = "VerifyBGPPeerMD5Auth"
- description = "Verifies the MD5 authentication and state of IPv4 BGP peers in a specified VRF"
- categories = ["routing", "bgp"]
- commands = [AntaCommand(command="show bgp neighbors vrf all")]
+ description = "Verifies the MD5 authentication and state of a BGP peer."
+ categories: ClassVar[list[str]] = ["bgp"]
+ commands: ClassVar[list[AntaCommand | AntaTemplate]] = [AntaCommand(command="show bgp neighbors vrf all", revision=3)]
class Input(AntaTest.Input):
- """
- Input parameters of the test case.
- """
+ """Input model for the VerifyBGPPeerMD5Auth test."""
- bgp_peers: List[BgpPeers]
- """List of IPv4 BGP peers"""
+ bgp_peers: list[BgpPeer]
+ """List of IPv4 BGP peers."""
- class BgpPeers(BaseModel):
- """
- This class defines the details of an IPv4 BGP peer.
- """
+ class BgpPeer(BaseModel):
+ """Model for a BGP peer."""
peer_address: IPv4Address
"""IPv4 address of BGP peer."""
@@ -784,6 +967,7 @@ class VerifyBGPPeerMD5Auth(AntaTest):
@AntaTest.anta_test
def test(self) -> None:
+ """Main test function for VerifyBGPPeerMD5Auth."""
failures: dict[str, Any] = {"bgp_peers": {}}
# Iterate over each command
@@ -798,7 +982,7 @@ class VerifyBGPPeerMD5Auth(AntaTest):
or (bgp_output := get_item(bgp_output, "peerAddress", peer)) is None
):
failure["bgp_peers"][peer][vrf] = {"status": "Not configured"}
- failures = utils.deep_update(failures, failure)
+ failures = deep_update(failures, failure)
continue
# Check if BGP peer state and authentication
@@ -806,7 +990,7 @@ class VerifyBGPPeerMD5Auth(AntaTest):
md5_auth_enabled = bgp_output.get("md5AuthEnabled")
if state != "Established" or not md5_auth_enabled:
failure["bgp_peers"][peer][vrf] = {"state": state, "md5_auth_enabled": md5_auth_enabled}
- failures = utils.deep_update(failures, failure)
+ failures = deep_update(failures, failure)
# Check if there are any failures
if not failures["bgp_peers"]:
@@ -816,45 +1000,60 @@ class VerifyBGPPeerMD5Auth(AntaTest):
class VerifyEVPNType2Route(AntaTest):
- """
- This test verifies the EVPN Type-2 routes for a given IPv4 or MAC address and VNI.
-
- Expected Results:
- * success: If all provided VXLAN endpoints have at least one valid and active path to their EVPN Type-2 routes.
- * failure: If any of the provided VXLAN endpoints do not have at least one valid and active path to their EVPN Type-2 routes.
+ """Verifies the EVPN Type-2 routes for a given IPv4 or MAC address and VNI.
+
+ Expected Results
+ ----------------
+ * Success: If all provided VXLAN endpoints have at least one valid and active path to their EVPN Type-2 routes.
+ * Failure: If any of the provided VXLAN endpoints do not have at least one valid and active path to their EVPN Type-2 routes.
+
+ Examples
+ --------
+ ```yaml
+ anta.tests.routing:
+ bgp:
+ - VerifyEVPNType2Route:
+ vxlan_endpoints:
+ - address: 192.168.20.102
+ vni: 10020
+ - address: aac1.ab5d.b41e
+ vni: 10010
+ ```
"""
name = "VerifyEVPNType2Route"
description = "Verifies the EVPN Type-2 routes for a given IPv4 or MAC address and VNI."
- categories = ["routing", "bgp"]
- commands = [AntaTemplate(template="show bgp evpn route-type mac-ip {address} vni {vni}")]
+ categories: ClassVar[list[str]] = ["bgp"]
+ commands: ClassVar[list[AntaCommand | AntaTemplate]] = [AntaTemplate(template="show bgp evpn route-type mac-ip {address} vni {vni}", revision=2)]
class Input(AntaTest.Input):
- """Inputs for the VerifyEVPNType2Route test."""
+ """Input model for the VerifyEVPNType2Route test."""
- vxlan_endpoints: List[VxlanEndpoint]
- """List of VXLAN endpoints to verify"""
+ vxlan_endpoints: list[VxlanEndpoint]
+ """List of VXLAN endpoints to verify."""
class VxlanEndpoint(BaseModel):
- """VXLAN endpoint input model."""
+ """Model for a VXLAN endpoint."""
- address: Union[IPv4Address, MacAddress]
- """IPv4 or MAC address of the VXLAN endpoint"""
+ address: IPv4Address | MacAddress
+ """IPv4 or MAC address of the VXLAN endpoint."""
vni: Vni
- """VNI of the VXLAN endpoint"""
+ """VNI of the VXLAN endpoint."""
def render(self, template: AntaTemplate) -> list[AntaCommand]:
- return [template.render(address=endpoint.address, vni=endpoint.vni) for endpoint in self.inputs.vxlan_endpoints]
+ """Render the template for each VXLAN endpoint in the input list."""
+ return [template.render(address=str(endpoint.address), vni=endpoint.vni) for endpoint in self.inputs.vxlan_endpoints]
@AntaTest.anta_test
def test(self) -> None:
+ """Main test function for VerifyEVPNType2Route."""
self.result.is_success()
no_evpn_routes = []
bad_evpn_routes = []
for command in self.instance_commands:
- address = str(command.params["address"])
- vni = command.params["vni"]
+ address = command.params.address
+ vni = command.params.vni
# Verify that the VXLAN endpoint is in the BGP EVPN table
evpn_routes = command.json_output["evpnRoutes"]
if not evpn_routes:
@@ -878,30 +1077,40 @@ class VerifyEVPNType2Route(AntaTest):
class VerifyBGPAdvCommunities(AntaTest):
- """
- Verifies if the advertised communities of BGP peers are standard, extended, and large in the specified VRF.
- Expected results:
- * success: The test will pass if the advertised communities of BGP peers are standard, extended, and large in the specified VRF.
- * failure: The test will fail if the advertised communities of BGP peers are not standard, extended, and large in the specified VRF.
+ """Verifies if the advertised communities of BGP peers are standard, extended, and large in the specified VRF.
+
+ Expected Results
+ ----------------
+ * Success: The test will pass if the advertised communities of BGP peers are standard, extended, and large in the specified VRF.
+ * Failure: The test will fail if the advertised communities of BGP peers are not standard, extended, and large in the specified VRF.
+
+ Examples
+ --------
+ ```yaml
+ anta.tests.routing:
+ bgp:
+ - VerifyBGPAdvCommunities:
+ bgp_peers:
+ - peer_address: 172.30.11.17
+ vrf: default
+ - peer_address: 172.30.11.21
+ vrf: default
+ ```
"""
name = "VerifyBGPAdvCommunities"
- description = "Verifies if the advertised communities of BGP peers are standard, extended, and large in the specified VRF."
- categories = ["routing", "bgp"]
- commands = [AntaCommand(command="show bgp neighbors vrf all")]
+ description = "Verifies the advertised communities of a BGP peer."
+ categories: ClassVar[list[str]] = ["bgp"]
+ commands: ClassVar[list[AntaCommand | AntaTemplate]] = [AntaCommand(command="show bgp neighbors vrf all", revision=3)]
class Input(AntaTest.Input):
- """
- Input parameters for the test.
- """
+ """Input model for the VerifyBGPAdvCommunities test."""
- bgp_peers: List[BgpPeers]
- """List of BGP peers"""
+ bgp_peers: list[BgpPeer]
+ """List of BGP peers."""
- class BgpPeers(BaseModel):
- """
- This class defines the details of a BGP peer.
- """
+ class BgpPeer(BaseModel):
+ """Model for a BGP peer."""
peer_address: IPv4Address
"""IPv4 address of a BGP peer."""
@@ -910,6 +1119,7 @@ class VerifyBGPAdvCommunities(AntaTest):
@AntaTest.anta_test
def test(self) -> None:
+ """Main test function for VerifyBGPAdvCommunities."""
failures: dict[str, Any] = {"bgp_peers": {}}
# Iterate over each bgp peer
@@ -924,14 +1134,14 @@ class VerifyBGPAdvCommunities(AntaTest):
or (bgp_output := get_item(bgp_output, "peerAddress", peer)) is None
):
failure["bgp_peers"][peer][vrf] = {"status": "Not configured"}
- failures = utils.deep_update(failures, failure)
+ failures = deep_update(failures, failure)
continue
# Verify BGP peer's advertised communities
bgp_output = bgp_output.get("advertisedCommunities")
if not bgp_output["standard"] or not bgp_output["extended"] or not bgp_output["large"]:
failure["bgp_peers"][peer][vrf] = {"advertised_communities": bgp_output}
- failures = utils.deep_update(failures, failure)
+ failures = deep_update(failures, failure)
if not failures["bgp_peers"]:
self.result.is_success()
@@ -940,42 +1150,57 @@ class VerifyBGPAdvCommunities(AntaTest):
class VerifyBGPTimers(AntaTest):
- """
- Verifies if the BGP peers are configured with the correct hold and keep-alive timers in the specified VRF.
- Expected results:
- * success: The test will pass if the hold and keep-alive timers are correct for BGP peers in the specified VRF.
- * failure: The test will fail if BGP peers are not found or hold and keep-alive timers are not correct in the specified VRF.
+ """Verifies if the BGP peers are configured with the correct hold and keep-alive timers in the specified VRF.
+
+ Expected Results
+ ----------------
+ * Success: The test will pass if the hold and keep-alive timers are correct for BGP peers in the specified VRF.
+ * Failure: The test will fail if BGP peers are not found or hold and keep-alive timers are not correct in the specified VRF.
+
+ Examples
+ --------
+ ```yaml
+ anta.tests.routing:
+ bgp:
+ - VerifyBGPTimers:
+ bgp_peers:
+ - peer_address: 172.30.11.1
+ vrf: default
+ hold_time: 180
+ keep_alive_time: 60
+ - peer_address: 172.30.11.5
+ vrf: default
+ hold_time: 180
+ keep_alive_time: 60
+ ```
"""
name = "VerifyBGPTimers"
- description = "Verifies if the BGP peers are configured with the correct hold and keep alive timers in the specified VRF."
- categories = ["routing", "bgp"]
- commands = [AntaCommand(command="show bgp neighbors vrf all")]
+ description = "Verifies the timers of a BGP peer."
+ categories: ClassVar[list[str]] = ["bgp"]
+ commands: ClassVar[list[AntaCommand | AntaTemplate]] = [AntaCommand(command="show bgp neighbors vrf all", revision=3)]
class Input(AntaTest.Input):
- """
- Input parameters for the test.
- """
+ """Input model for the VerifyBGPTimers test."""
- bgp_peers: List[BgpPeers]
+ bgp_peers: list[BgpPeer]
"""List of BGP peers"""
- class BgpPeers(BaseModel):
- """
- This class defines the details of a BGP peer.
- """
+ class BgpPeer(BaseModel):
+ """Model for a BGP peer."""
peer_address: IPv4Address
- """IPv4 address of a BGP peer"""
+ """IPv4 address of a BGP peer."""
vrf: str = "default"
"""Optional VRF for BGP peer. If not provided, it defaults to `default`."""
hold_time: int = Field(ge=3, le=7200)
- """BGP hold time in seconds"""
+ """BGP hold time in seconds."""
keep_alive_time: int = Field(ge=0, le=3600)
- """BGP keep-alive time in seconds"""
+ """BGP keep-alive time in seconds."""
@AntaTest.anta_test
def test(self) -> None:
+ """Main test function for VerifyBGPTimers."""
failures: dict[str, Any] = {}
# Iterate over each bgp peer
diff --git a/anta/tests/routing/generic.py b/anta/tests/routing/generic.py
index 532b4bb..89d4bc5 100644
--- a/anta/tests/routing/generic.py
+++ b/anta/tests/routing/generic.py
@@ -1,41 +1,52 @@
# Copyright (c) 2023-2024 Arista Networks, Inc.
# Use of this source code is governed by the Apache License 2.0
# that can be found in the LICENSE file.
-"""
-Generic routing test functions
-"""
+"""Module related to generic routing tests."""
+
+# Mypy does not understand AntaTest.Input typing
+# mypy: disable-error-code=attr-defined
from __future__ import annotations
from ipaddress import IPv4Address, ip_interface
-
-# Need to keep List for pydantic in python 3.8
-from typing import List, Literal
+from typing import ClassVar, Literal
from pydantic import model_validator
from anta.models import AntaCommand, AntaTemplate, AntaTest
-# Mypy does not understand AntaTest.Input typing
-# mypy: disable-error-code=attr-defined
-
class VerifyRoutingProtocolModel(AntaTest):
- """
- Verifies the configured routing protocol model is the one we expect.
- And if there is no mismatch between the configured and operating routing protocol model.
+ """Verifies the configured routing protocol model is the one we expect.
+
+ Expected Results
+ ----------------
+ * Success: The test will pass if the configured routing protocol model is the one we expect.
+ * Failure: The test will fail if the configured routing protocol model is not the one we expect.
+
+ Examples
+ --------
+ ```yaml
+ anta.tests.routing:
+ generic:
+ - VerifyRoutingProtocolModel:
+ model: multi-agent
+ ```
"""
name = "VerifyRoutingProtocolModel"
description = "Verifies the configured routing protocol model."
- categories = ["routing"]
- commands = [AntaCommand(command="show ip route summary", revision=3)]
+ categories: ClassVar[list[str]] = ["routing"]
+ commands: ClassVar[list[AntaCommand | AntaTemplate]] = [AntaCommand(command="show ip route summary", revision=3)]
+
+ class Input(AntaTest.Input):
+ """Input model for the VerifyRoutingProtocolModel test."""
- class Input(AntaTest.Input): # pylint: disable=missing-class-docstring
model: Literal["multi-agent", "ribd"] = "multi-agent"
- """Expected routing protocol model"""
+ """Expected routing protocol model. Defaults to `multi-agent`."""
@AntaTest.anta_test
def test(self) -> None:
+ """Main test function for VerifyRoutingProtocolModel."""
command_output = self.instance_commands[0].json_output
configured_model = command_output["protoModelStatus"]["configuredProtoModel"]
operating_model = command_output["protoModelStatus"]["operatingProtoModel"]
@@ -46,31 +57,48 @@ class VerifyRoutingProtocolModel(AntaTest):
class VerifyRoutingTableSize(AntaTest):
- """
- Verifies the size of the IP routing table (default VRF).
- Should be between the two provided thresholds.
+ """Verifies the size of the IP routing table of the default VRF.
+
+ Expected Results
+ ----------------
+ * Success: The test will pass if the routing table size is between the provided minimum and maximum values.
+ * Failure: The test will fail if the routing table size is not between the provided minimum and maximum values.
+
+ Examples
+ --------
+ ```yaml
+ anta.tests.routing:
+ generic:
+ - VerifyRoutingTableSize:
+ minimum: 2
+ maximum: 20
+ ```
"""
name = "VerifyRoutingTableSize"
- description = "Verifies the size of the IP routing table (default VRF). Should be between the two provided thresholds."
- categories = ["routing"]
- commands = [AntaCommand(command="show ip route summary", revision=3)]
+ description = "Verifies the size of the IP routing table of the default VRF."
+ categories: ClassVar[list[str]] = ["routing"]
+ commands: ClassVar[list[AntaCommand | AntaTemplate]] = [AntaCommand(command="show ip route summary", revision=3)]
+
+ class Input(AntaTest.Input):
+ """Input model for the VerifyRoutingTableSize test."""
- class Input(AntaTest.Input): # pylint: disable=missing-class-docstring
minimum: int
- """Expected minimum routing table (default VRF) size"""
+ """Expected minimum routing table size."""
maximum: int
- """Expected maximum routing table (default VRF) size"""
+ """Expected maximum routing table size."""
- @model_validator(mode="after") # type: ignore
+ @model_validator(mode="after") # type: ignore[misc]
def check_min_max(self) -> AntaTest.Input:
- """Validate that maximum is greater than minimum"""
+ """Validate that maximum is greater than minimum."""
if self.minimum > self.maximum:
- raise ValueError(f"Minimum {self.minimum} is greater than maximum {self.maximum}")
+ msg = f"Minimum {self.minimum} is greater than maximum {self.maximum}"
+ raise ValueError(msg)
return self
@AntaTest.anta_test
def test(self) -> None:
+ """Main test function for VerifyRoutingTableSize."""
command_output = self.instance_commands[0].json_output
total_routes = int(command_output["vrfs"]["default"]["totalRoutes"])
if self.inputs.minimum <= total_routes <= self.inputs.maximum:
@@ -80,37 +108,52 @@ class VerifyRoutingTableSize(AntaTest):
class VerifyRoutingTableEntry(AntaTest):
- """
- This test verifies that the provided routes are present in the routing table of a specified VRF.
-
- Expected Results:
- * success: The test will pass if the provided routes are present in the routing table.
- * failure: The test will fail if one or many provided routes are missing from the routing table.
+ """Verifies that the provided routes are present in the routing table of a specified VRF.
+
+ Expected Results
+ ----------------
+ * Success: The test will pass if the provided routes are present in the routing table.
+ * Failure: The test will fail if one or many provided routes are missing from the routing table.
+
+ Examples
+ --------
+ ```yaml
+ anta.tests.routing:
+ generic:
+ - VerifyRoutingTableEntry:
+ vrf: default
+ routes:
+ - 10.1.0.1
+ - 10.1.0.2
+ ```
"""
name = "VerifyRoutingTableEntry"
description = "Verifies that the provided routes are present in the routing table of a specified VRF."
- categories = ["routing"]
- commands = [AntaTemplate(template="show ip route vrf {vrf} {route}")]
+ categories: ClassVar[list[str]] = ["routing"]
+ commands: ClassVar[list[AntaCommand | AntaTemplate]] = [AntaTemplate(template="show ip route vrf {vrf} {route}", revision=4)]
+
+ class Input(AntaTest.Input):
+ """Input model for the VerifyRoutingTableEntry test."""
- class Input(AntaTest.Input): # pylint: disable=missing-class-docstring
vrf: str = "default"
- """VRF context"""
- routes: List[IPv4Address]
- """Routes to verify"""
+ """VRF context. Defaults to `default` VRF."""
+ routes: list[IPv4Address]
+ """List of routes to verify."""
def render(self, template: AntaTemplate) -> list[AntaCommand]:
+ """Render the template for each route in the input list."""
return [template.render(vrf=self.inputs.vrf, route=route) for route in self.inputs.routes]
@AntaTest.anta_test
def test(self) -> None:
+ """Main test function for VerifyRoutingTableEntry."""
missing_routes = []
for command in self.instance_commands:
- if "vrf" in command.params and "route" in command.params:
- vrf, route = command.params["vrf"], command.params["route"]
- if len(routes := command.json_output["vrfs"][vrf]["routes"]) == 0 or route != ip_interface(list(routes)[0]).ip:
- missing_routes.append(str(route))
+ vrf, route = command.params.vrf, command.params.route
+ if len(routes := command.json_output["vrfs"][vrf]["routes"]) == 0 or route != ip_interface(next(iter(routes))).ip:
+ missing_routes.append(str(route))
if not missing_routes:
self.result.is_success()
diff --git a/anta/tests/routing/isis.py b/anta/tests/routing/isis.py
new file mode 100644
index 0000000..addc083
--- /dev/null
+++ b/anta/tests/routing/isis.py
@@ -0,0 +1,308 @@
+# Copyright (c) 2023-2024 Arista Networks, Inc.
+# Use of this source code is governed by the Apache License 2.0
+# that can be found in the LICENSE file.
+"""Module related to IS-IS tests."""
+
+# Mypy does not understand AntaTest.Input typing
+# mypy: disable-error-code=attr-defined
+from __future__ import annotations
+
+from typing import Any, ClassVar, Literal
+
+from pydantic import BaseModel
+
+from anta.custom_types import Interface
+from anta.models import AntaCommand, AntaTemplate, AntaTest
+from anta.tools import get_value
+
+
+def _count_isis_neighbor(isis_neighbor_json: dict[str, Any]) -> int:
+ """Count the number of isis neighbors.
+
+ Args
+ ----
+ isis_neighbor_json: The JSON output of the `show isis neighbors` command.
+
+ Returns
+ -------
+ int: The number of isis neighbors.
+
+ """
+ count = 0
+ for vrf_data in isis_neighbor_json["vrfs"].values():
+ for instance_data in vrf_data["isisInstances"].values():
+ count += len(instance_data.get("neighbors", {}))
+ return count
+
+
+def _get_not_full_isis_neighbors(isis_neighbor_json: dict[str, Any]) -> list[dict[str, Any]]:
+ """Return the isis neighbors whose adjacency state is not `up`.
+
+ Args
+ ----
+ isis_neighbor_json: The JSON output of the `show isis neighbors` command.
+
+ Returns
+ -------
+ list[dict[str, Any]]: A list of isis neighbors whose adjacency state is not `UP`.
+
+ """
+ return [
+ {
+ "vrf": vrf,
+ "instance": instance,
+ "neighbor": adjacency["hostname"],
+ "state": state,
+ }
+ for vrf, vrf_data in isis_neighbor_json["vrfs"].items()
+ for instance, instance_data in vrf_data.get("isisInstances").items()
+ for neighbor, neighbor_data in instance_data.get("neighbors").items()
+ for adjacency in neighbor_data.get("adjacencies")
+ if (state := adjacency["state"]) != "up"
+ ]
+
+
+def _get_full_isis_neighbors(isis_neighbor_json: dict[str, Any], neighbor_state: Literal["up", "down"] = "up") -> list[dict[str, Any]]:
+ """Return the isis neighbors whose adjacency state is `up`.
+
+ Args
+ ----
+ isis_neighbor_json: The JSON output of the `show isis neighbors` command.
+ neighbor_state: Value of the neihbor state we are looking for. Default up
+
+ Returns
+ -------
+ list[dict[str, Any]]: A list of isis neighbors whose adjacency state is not `UP`.
+
+ """
+ return [
+ {
+ "vrf": vrf,
+ "instance": instance,
+ "neighbor": adjacency["hostname"],
+ "neighbor_address": adjacency["routerIdV4"],
+ "interface": adjacency["interfaceName"],
+ "state": state,
+ }
+ for vrf, vrf_data in isis_neighbor_json["vrfs"].items()
+ for instance, instance_data in vrf_data.get("isisInstances").items()
+ for neighbor, neighbor_data in instance_data.get("neighbors").items()
+ for adjacency in neighbor_data.get("adjacencies")
+ if (state := adjacency["state"]) == neighbor_state
+ ]
+
+
+def _get_isis_neighbors_count(isis_neighbor_json: dict[str, Any]) -> list[dict[str, Any]]:
+ """Count number of IS-IS neighbor of the device."""
+ return [
+ {"vrf": vrf, "interface": interface, "mode": mode, "count": int(level_data["numAdjacencies"]), "level": int(level)}
+ for vrf, vrf_data in isis_neighbor_json["vrfs"].items()
+ for instance, instance_data in vrf_data.get("isisInstances").items()
+ for interface, interface_data in instance_data.get("interfaces").items()
+ for level, level_data in interface_data.get("intfLevels").items()
+ if (mode := level_data["passive"]) is not True
+ ]
+
+
+def _get_interface_data(interface: str, vrf: str, command_output: dict[str, Any]) -> dict[str, Any] | None:
+ """Extract data related to an IS-IS interface for testing."""
+ if (vrf_data := get_value(command_output, f"vrfs.{vrf}")) is None:
+ return None
+
+ for instance_data in vrf_data.get("isisInstances").values():
+ if (intf_dict := get_value(dictionary=instance_data, key="interfaces")) is not None:
+ try:
+ return next(ifl_data for ifl, ifl_data in intf_dict.items() if ifl == interface)
+ except StopIteration:
+ return None
+ return None
+
+
+class VerifyISISNeighborState(AntaTest):
+ """Verifies all IS-IS neighbors are in UP state.
+
+ Expected Results
+ ----------------
+ * Success: The test will pass if all IS-IS neighbors are in UP state.
+ * Failure: The test will fail if some IS-IS neighbors are not in UP state.
+ * Skipped: The test will be skipped if no IS-IS neighbor is found.
+
+ Examples
+ --------
+ ```yaml
+ anta.tests.routing:
+ isis:
+ - VerifyISISNeighborState:
+ ```
+ """
+
+ name = "VerifyISISNeighborState"
+ description = "Verifies all IS-IS neighbors are in UP state."
+ categories: ClassVar[list[str]] = ["isis"]
+ commands: ClassVar[list[AntaCommand | AntaTemplate]] = [AntaCommand(command="show isis neighbors", revision=1)]
+
+ @AntaTest.anta_test
+ def test(self) -> None:
+ """Main test function for VerifyISISNeighborState."""
+ command_output = self.instance_commands[0].json_output
+ if _count_isis_neighbor(command_output) == 0:
+ self.result.is_skipped("No IS-IS neighbor detected")
+ return
+ self.result.is_success()
+ not_full_neighbors = _get_not_full_isis_neighbors(command_output)
+ if not_full_neighbors:
+ self.result.is_failure(f"Some neighbors are not in the correct state (UP): {not_full_neighbors}.")
+
+
+class VerifyISISNeighborCount(AntaTest):
+ """Verifies number of IS-IS neighbors per level and per interface.
+
+ Expected Results
+ ----------------
+ * Success: The test will pass if the number of neighbors is correct.
+ * Failure: The test will fail if the number of neighbors is incorrect.
+ * Skipped: The test will be skipped if no IS-IS neighbor is found.
+
+ Examples
+ --------
+ ```yaml
+ anta.tests.routing:
+ isis:
+ - VerifyISISNeighborCount:
+ interfaces:
+ - name: Ethernet1
+ level: 1
+ count: 2
+ - name: Ethernet2
+ level: 2
+ count: 1
+ - name: Ethernet3
+ count: 2
+ # level is set to 2 by default
+ ```
+ """
+
+ name = "VerifyISISNeighborCount"
+ description = "Verifies count of IS-IS interface per level"
+ categories: ClassVar[list[str]] = ["isis"]
+ commands: ClassVar[list[AntaCommand | AntaTemplate]] = [AntaCommand(command="show isis interface brief", revision=1)]
+
+ class Input(AntaTest.Input):
+ """Input model for the VerifyISISNeighborCount test."""
+
+ interfaces: list[InterfaceCount]
+ """list of interfaces with their information."""
+
+ class InterfaceCount(BaseModel):
+ """Input model for the VerifyISISNeighborCount test."""
+
+ name: Interface
+ """Interface name to check."""
+ level: int = 2
+ """IS-IS level to check."""
+ count: int
+ """Number of IS-IS neighbors."""
+
+ @AntaTest.anta_test
+ def test(self) -> None:
+ """Main test function for VerifyISISNeighborCount."""
+ command_output = self.instance_commands[0].json_output
+ self.result.is_success()
+ isis_neighbor_count = _get_isis_neighbors_count(command_output)
+ if len(isis_neighbor_count) == 0:
+ self.result.is_skipped("No IS-IS neighbor detected")
+ for interface in self.inputs.interfaces:
+ eos_data = [ifl_data for ifl_data in isis_neighbor_count if ifl_data["interface"] == interface.name and ifl_data["level"] == interface.level]
+ if not eos_data:
+ self.result.is_failure(f"No neighbor detected for interface {interface.name}")
+ return
+ if eos_data[0]["count"] != interface.count:
+ self.result.is_failure(
+ f"Interface {interface.name}:"
+ f"expected Level {interface.level}: count {interface.count}, "
+ f"got Level {eos_data[0]['level']}: count {eos_data[0]['count']}"
+ )
+
+
+class VerifyISISInterfaceMode(AntaTest):
+ """Verifies ISIS Interfaces are running in correct mode.
+
+ Expected Results
+ ----------------
+ * Success: The test will pass if all listed interfaces are running in correct mode.
+ * Failure: The test will fail if any of the listed interfaces is not running in correct mode.
+ * Skipped: The test will be skipped if no ISIS neighbor is found.
+
+ Examples
+ --------
+ ```yaml
+ anta.tests.routing:
+ isis:
+ - VerifyISISInterfaceMode:
+ interfaces:
+ - name: Loopback0
+ mode: passive
+ # vrf is set to default by default
+ - name: Ethernet2
+ mode: passive
+ level: 2
+ # vrf is set to default by default
+ - name: Ethernet1
+ mode: point-to-point
+ vrf: default
+ # level is set to 2 by default
+ ```
+ """
+
+ name = "VerifyISISInterfaceMode"
+ description = "Verifies interface mode for IS-IS"
+ categories: ClassVar[list[str]] = ["isis"]
+ commands: ClassVar[list[AntaCommand | AntaTemplate]] = [AntaCommand(command="show isis interface brief", revision=1)]
+
+ class Input(AntaTest.Input):
+ """Input model for the VerifyISISNeighborCount test."""
+
+ interfaces: list[InterfaceState]
+ """list of interfaces with their information."""
+
+ class InterfaceState(BaseModel):
+ """Input model for the VerifyISISNeighborCount test."""
+
+ name: Interface
+ """Interface name to check."""
+ level: Literal[1, 2] = 2
+ """ISIS level configured for interface. Default is 2."""
+ mode: Literal["point-to-point", "broadcast", "passive"]
+ """Number of IS-IS neighbors."""
+ vrf: str = "default"
+ """VRF where the interface should be configured"""
+
+ @AntaTest.anta_test
+ def test(self) -> None:
+ """Main test function for VerifyISISInterfaceMode."""
+ command_output = self.instance_commands[0].json_output
+ self.result.is_success()
+
+ if len(command_output["vrfs"]) == 0:
+ self.result.is_failure("IS-IS is not configured on device")
+
+ # Check for p2p interfaces
+ for interface in self.inputs.interfaces:
+ interface_data = _get_interface_data(
+ interface=interface.name,
+ vrf=interface.vrf,
+ command_output=command_output,
+ )
+ # Check for correct VRF
+ if interface_data is not None:
+ interface_type = get_value(dictionary=interface_data, key="interfaceType", default="unset")
+ # Check for interfaceType
+ if interface.mode == "point-to-point" and interface.mode != interface_type:
+ self.result.is_failure(f"Interface {interface.name} in VRF {interface.vrf} is not running in {interface.mode} reporting {interface_type}")
+ # Check for passive
+ elif interface.mode == "passive":
+ json_path = f"intfLevels.{interface.level}.passive"
+ if interface_data is None or get_value(dictionary=interface_data, key=json_path, default=False) is False:
+ self.result.is_failure(f"Interface {interface.name} in VRF {interface.vrf} is not running in passive mode")
+ else:
+ self.result.is_failure(f"Interface {interface.name} not found in VRF {interface.vrf}")
diff --git a/anta/tests/routing/ospf.py b/anta/tests/routing/ospf.py
index 844fcf1..5910bf0 100644
--- a/anta/tests/routing/ospf.py
+++ b/anta/tests/routing/ospf.py
@@ -1,61 +1,116 @@
# Copyright (c) 2023-2024 Arista Networks, Inc.
# Use of this source code is governed by the Apache License 2.0
# that can be found in the LICENSE file.
-"""
-OSPF test functions
-"""
+"""Module related to OSPF tests."""
+
# Mypy does not understand AntaTest.Input typing
# mypy: disable-error-code=attr-defined
from __future__ import annotations
-from typing import Any
+from typing import TYPE_CHECKING, Any, ClassVar
from anta.models import AntaCommand, AntaTest
+if TYPE_CHECKING:
+ from anta.models import AntaTemplate
+
def _count_ospf_neighbor(ospf_neighbor_json: dict[str, Any]) -> int:
- """
- Count the number of OSPF neighbors
+ """Count the number of OSPF neighbors.
+
+ Args:
+ ----
+ ospf_neighbor_json: The JSON output of the `show ip ospf neighbor` command.
+
+ Returns
+ -------
+ int: The number of OSPF neighbors.
+
"""
count = 0
- for _, vrf_data in ospf_neighbor_json["vrfs"].items():
- for _, instance_data in vrf_data["instList"].items():
+ for vrf_data in ospf_neighbor_json["vrfs"].values():
+ for instance_data in vrf_data["instList"].values():
count += len(instance_data.get("ospfNeighborEntries", []))
return count
def _get_not_full_ospf_neighbors(ospf_neighbor_json: dict[str, Any]) -> list[dict[str, Any]]:
+ """Return the OSPF neighbors whose adjacency state is not `full`.
+
+ Args:
+ ----
+ ospf_neighbor_json: The JSON output of the `show ip ospf neighbor` command.
+
+ Returns
+ -------
+ list[dict[str, Any]]: A list of OSPF neighbors whose adjacency state is not `full`.
+
"""
- Return the OSPF neighbors whose adjacency state is not "full"
+ return [
+ {
+ "vrf": vrf,
+ "instance": instance,
+ "neighbor": neighbor_data["routerId"],
+ "state": state,
+ }
+ for vrf, vrf_data in ospf_neighbor_json["vrfs"].items()
+ for instance, instance_data in vrf_data["instList"].items()
+ for neighbor_data in instance_data.get("ospfNeighborEntries", [])
+ if (state := neighbor_data["adjacencyState"]) != "full"
+ ]
+
+
+def _get_ospf_max_lsa_info(ospf_process_json: dict[str, Any]) -> list[dict[str, Any]]:
+ """Return information about OSPF instances and their LSAs.
+
+ Args:
+ ----
+ ospf_process_json: OSPF process information in JSON format.
+
+ Returns
+ -------
+ list[dict[str, Any]]: A list of dictionaries containing OSPF LSAs information.
+
"""
- not_full_neighbors = []
- for vrf, vrf_data in ospf_neighbor_json["vrfs"].items():
- for instance, instance_data in vrf_data["instList"].items():
- for neighbor_data in instance_data.get("ospfNeighborEntries", []):
- if (state := neighbor_data["adjacencyState"]) != "full":
- not_full_neighbors.append(
- {
- "vrf": vrf,
- "instance": instance,
- "neighbor": neighbor_data["routerId"],
- "state": state,
- }
- )
- return not_full_neighbors
+ return [
+ {
+ "vrf": vrf,
+ "instance": instance,
+ "maxLsa": instance_data.get("maxLsaInformation", {}).get("maxLsa"),
+ "maxLsaThreshold": instance_data.get("maxLsaInformation", {}).get("maxLsaThreshold"),
+ "numLsa": instance_data.get("lsaInformation", {}).get("numLsa"),
+ }
+ for vrf, vrf_data in ospf_process_json.get("vrfs", {}).items()
+ for instance, instance_data in vrf_data.get("instList", {}).items()
+ ]
class VerifyOSPFNeighborState(AntaTest):
- """
- Verifies all OSPF neighbors are in FULL state.
+ """Verifies all OSPF neighbors are in FULL state.
+
+ Expected Results
+ ----------------
+ * Success: The test will pass if all OSPF neighbors are in FULL state.
+ * Failure: The test will fail if some OSPF neighbors are not in FULL state.
+ * Skipped: The test will be skipped if no OSPF neighbor is found.
+
+ Examples
+ --------
+ ```yaml
+ anta.tests.routing:
+ ospf:
+ - VerifyOSPFNeighborState:
+ ```
"""
name = "VerifyOSPFNeighborState"
description = "Verifies all OSPF neighbors are in FULL state."
- categories = ["ospf"]
- commands = [AntaCommand(command="show ip ospf neighbor")]
+ categories: ClassVar[list[str]] = ["ospf"]
+ commands: ClassVar[list[AntaCommand | AntaTemplate]] = [AntaCommand(command="show ip ospf neighbor", revision=1)]
@AntaTest.anta_test
def test(self) -> None:
+ """Main test function for VerifyOSPFNeighborState."""
command_output = self.instance_commands[0].json_output
if _count_ospf_neighbor(command_output) == 0:
self.result.is_skipped("no OSPF neighbor found")
@@ -67,21 +122,38 @@ class VerifyOSPFNeighborState(AntaTest):
class VerifyOSPFNeighborCount(AntaTest):
- """
- Verifies the number of OSPF neighbors in FULL state is the one we expect.
+ """Verifies the number of OSPF neighbors in FULL state is the one we expect.
+
+ Expected Results
+ ----------------
+ * Success: The test will pass if the number of OSPF neighbors in FULL state is the one we expect.
+ * Failure: The test will fail if the number of OSPF neighbors in FULL state is not the one we expect.
+ * Skipped: The test will be skipped if no OSPF neighbor is found.
+
+ Examples
+ --------
+ ```yaml
+ anta.tests.routing:
+ ospf:
+ - VerifyOSPFNeighborCount:
+ number: 3
+ ```
"""
name = "VerifyOSPFNeighborCount"
description = "Verifies the number of OSPF neighbors in FULL state is the one we expect."
- categories = ["ospf"]
- commands = [AntaCommand(command="show ip ospf neighbor")]
+ categories: ClassVar[list[str]] = ["ospf"]
+ commands: ClassVar[list[AntaCommand | AntaTemplate]] = [AntaCommand(command="show ip ospf neighbor", revision=1)]
+
+ class Input(AntaTest.Input):
+ """Input model for the VerifyOSPFNeighborCount test."""
- class Input(AntaTest.Input): # pylint: disable=missing-class-docstring
number: int
- """The expected number of OSPF neighbors in FULL state"""
+ """The expected number of OSPF neighbors in FULL state."""
@AntaTest.anta_test
def test(self) -> None:
+ """Main test function for VerifyOSPFNeighborCount."""
command_output = self.instance_commands[0].json_output
if (neighbor_count := _count_ospf_neighbor(command_output)) == 0:
self.result.is_skipped("no OSPF neighbor found")
@@ -90,6 +162,46 @@ class VerifyOSPFNeighborCount(AntaTest):
if neighbor_count != self.inputs.number:
self.result.is_failure(f"device has {neighbor_count} neighbors (expected {self.inputs.number})")
not_full_neighbors = _get_not_full_ospf_neighbors(command_output)
- print(not_full_neighbors)
if not_full_neighbors:
self.result.is_failure(f"Some neighbors are not correctly configured: {not_full_neighbors}.")
+
+
+class VerifyOSPFMaxLSA(AntaTest):
+ """Verifies LSAs present in the OSPF link state database did not cross the maximum LSA Threshold.
+
+ Expected Results
+ ----------------
+ * Success: The test will pass if all OSPF instances did not cross the maximum LSA Threshold.
+ * Failure: The test will fail if some OSPF instances crossed the maximum LSA Threshold.
+ * Skipped: The test will be skipped if no OSPF instance is found.
+
+ Examples
+ --------
+ ```yaml
+ anta.tests.routing:
+ ospf:
+ - VerifyOSPFMaxLSA:
+ ```
+ """
+
+ name = "VerifyOSPFMaxLSA"
+ description = "Verifies all OSPF instances did not cross the maximum LSA threshold."
+ categories: ClassVar[list[str]] = ["ospf"]
+ commands: ClassVar[list[AntaCommand | AntaTemplate]] = [AntaCommand(command="show ip ospf", revision=1)]
+
+ @AntaTest.anta_test
+ def test(self) -> None:
+ """Main test function for VerifyOSPFMaxLSA."""
+ command_output = self.instance_commands[0].json_output
+ ospf_instance_info = _get_ospf_max_lsa_info(command_output)
+ if not ospf_instance_info:
+ self.result.is_skipped("No OSPF instance found.")
+ return
+ all_instances_within_threshold = all(instance["numLsa"] <= instance["maxLsa"] * (instance["maxLsaThreshold"] / 100) for instance in ospf_instance_info)
+ if all_instances_within_threshold:
+ self.result.is_success()
+ else:
+ exceeded_instances = [
+ instance["instance"] for instance in ospf_instance_info if instance["numLsa"] > instance["maxLsa"] * (instance["maxLsaThreshold"] / 100)
+ ]
+ self.result.is_failure(f"OSPF Instances {exceeded_instances} crossed the maximum LSA threshold.")
diff --git a/anta/tests/security.py b/anta/tests/security.py
index ba7f4e5..4eb4d64 100644
--- a/anta/tests/security.py
+++ b/anta/tests/security.py
@@ -1,44 +1,54 @@
# Copyright (c) 2023-2024 Arista Networks, Inc.
# Use of this source code is governed by the Apache License 2.0
# that can be found in the LICENSE file.
-"""
-Test functions related to the EOS various security settings
-"""
+"""Module related to the EOS various security tests."""
+
from __future__ import annotations
# Mypy does not understand AntaTest.Input typing
# mypy: disable-error-code=attr-defined
-from datetime import datetime
-from typing import List, Union
+from datetime import datetime, timezone
+from ipaddress import IPv4Address
+from typing import ClassVar
-from pydantic import BaseModel, Field, conint, model_validator
+from pydantic import BaseModel, Field, model_validator
-from anta.custom_types import EcdsaKeySize, EncryptionAlgorithm, RsaKeySize
+from anta.custom_types import EcdsaKeySize, EncryptionAlgorithm, PositiveInteger, RsaKeySize
from anta.models import AntaCommand, AntaTemplate, AntaTest
-from anta.tools.get_item import get_item
-from anta.tools.get_value import get_value
-from anta.tools.utils import get_failed_logs
+from anta.tools import get_failed_logs, get_item, get_value
class VerifySSHStatus(AntaTest):
- """
- Verifies if the SSHD agent is disabled in the default VRF.
-
- Expected Results:
- * success: The test will pass if the SSHD agent is disabled in the default VRF.
- * failure: The test will fail if the SSHD agent is NOT disabled in the default VRF.
+ """Verifies if the SSHD agent is disabled in the default VRF.
+
+ Expected Results
+ ----------------
+ * Success: The test will pass if the SSHD agent is disabled in the default VRF.
+ * Failure: The test will fail if the SSHD agent is NOT disabled in the default VRF.
+
+ Examples
+ --------
+ ```yaml
+ anta.tests.security:
+ - VerifySSHStatus:
+ ```
"""
name = "VerifySSHStatus"
description = "Verifies if the SSHD agent is disabled in the default VRF."
- categories = ["security"]
- commands = [AntaCommand(command="show management ssh", ofmt="text")]
+ categories: ClassVar[list[str]] = ["security"]
+ commands: ClassVar[list[AntaCommand | AntaTemplate]] = [AntaCommand(command="show management ssh", ofmt="text")]
@AntaTest.anta_test
def test(self) -> None:
+ """Main test function for VerifySSHStatus."""
command_output = self.instance_commands[0].text_output
- line = [line for line in command_output.split("\n") if line.startswith("SSHD status")][0]
+ try:
+ line = next(line for line in command_output.split("\n") if line.startswith("SSHD status"))
+ except StopIteration:
+ self.result.is_error("Could not find SSH status in returned output.")
+ return
status = line.split("is ")[1]
if status == "disabled":
@@ -48,97 +58,127 @@ class VerifySSHStatus(AntaTest):
class VerifySSHIPv4Acl(AntaTest):
- """
- Verifies if the SSHD agent has the right number IPv4 ACL(s) configured for a specified VRF.
-
- Expected results:
- * success: The test will pass if the SSHD agent has the provided number of IPv4 ACL(s) in the specified VRF.
- * failure: The test will fail if the SSHD agent has not the right number of IPv4 ACL(s) in the specified VRF.
+ """Verifies if the SSHD agent has the right number IPv4 ACL(s) configured for a specified VRF.
+
+ Expected Results
+ ----------------
+ * Success: The test will pass if the SSHD agent has the provided number of IPv4 ACL(s) in the specified VRF.
+ * Failure: The test will fail if the SSHD agent has not the right number of IPv4 ACL(s) in the specified VRF.
+
+ Examples
+ --------
+ ```yaml
+ anta.tests.security:
+ - VerifySSHIPv4Acl:
+ number: 3
+ vrf: default
+ ```
"""
name = "VerifySSHIPv4Acl"
description = "Verifies if the SSHD agent has IPv4 ACL(s) configured."
- categories = ["security"]
- commands = [AntaCommand(command="show management ssh ip access-list summary")]
+ categories: ClassVar[list[str]] = ["security"]
+ commands: ClassVar[list[AntaCommand | AntaTemplate]] = [AntaCommand(command="show management ssh ip access-list summary", revision=1)]
+
+ class Input(AntaTest.Input):
+ """Input model for the VerifySSHIPv4Acl test."""
- class Input(AntaTest.Input): # pylint: disable=missing-class-docstring
- number: conint(ge=0) # type:ignore
- """The number of expected IPv4 ACL(s)"""
+ number: PositiveInteger
+ """The number of expected IPv4 ACL(s)."""
vrf: str = "default"
- """The name of the VRF in which to check for the SSHD agent"""
+ """The name of the VRF in which to check for the SSHD agent. Defaults to `default` VRF."""
@AntaTest.anta_test
def test(self) -> None:
+ """Main test function for VerifySSHIPv4Acl."""
command_output = self.instance_commands[0].json_output
ipv4_acl_list = command_output["ipAclList"]["aclList"]
ipv4_acl_number = len(ipv4_acl_list)
- not_configured_acl_list = []
if ipv4_acl_number != self.inputs.number:
self.result.is_failure(f"Expected {self.inputs.number} SSH IPv4 ACL(s) in vrf {self.inputs.vrf} but got {ipv4_acl_number}")
return
- for ipv4_acl in ipv4_acl_list:
- if self.inputs.vrf not in ipv4_acl["configuredVrfs"] or self.inputs.vrf not in ipv4_acl["activeVrfs"]:
- not_configured_acl_list.append(ipv4_acl["name"])
- if not_configured_acl_list:
- self.result.is_failure(f"SSH IPv4 ACL(s) not configured or active in vrf {self.inputs.vrf}: {not_configured_acl_list}")
+
+ not_configured_acl = [acl["name"] for acl in ipv4_acl_list if self.inputs.vrf not in acl["configuredVrfs"] or self.inputs.vrf not in acl["activeVrfs"]]
+
+ if not_configured_acl:
+ self.result.is_failure(f"SSH IPv4 ACL(s) not configured or active in vrf {self.inputs.vrf}: {not_configured_acl}")
else:
self.result.is_success()
class VerifySSHIPv6Acl(AntaTest):
- """
- Verifies if the SSHD agent has the right number IPv6 ACL(s) configured for a specified VRF.
-
- Expected results:
- * success: The test will pass if the SSHD agent has the provided number of IPv6 ACL(s) in the specified VRF.
- * failure: The test will fail if the SSHD agent has not the right number of IPv6 ACL(s) in the specified VRF.
+ """Verifies if the SSHD agent has the right number IPv6 ACL(s) configured for a specified VRF.
+
+ Expected Results
+ ----------------
+ * Success: The test will pass if the SSHD agent has the provided number of IPv6 ACL(s) in the specified VRF.
+ * Failure: The test will fail if the SSHD agent has not the right number of IPv6 ACL(s) in the specified VRF.
+
+ Examples
+ --------
+ ```yaml
+ anta.tests.security:
+ - VerifySSHIPv6Acl:
+ number: 3
+ vrf: default
+ ```
"""
name = "VerifySSHIPv6Acl"
description = "Verifies if the SSHD agent has IPv6 ACL(s) configured."
- categories = ["security"]
- commands = [AntaCommand(command="show management ssh ipv6 access-list summary")]
+ categories: ClassVar[list[str]] = ["security"]
+ commands: ClassVar[list[AntaCommand | AntaTemplate]] = [AntaCommand(command="show management ssh ipv6 access-list summary", revision=1)]
+
+ class Input(AntaTest.Input):
+ """Input model for the VerifySSHIPv6Acl test."""
- class Input(AntaTest.Input): # pylint: disable=missing-class-docstring
- number: conint(ge=0) # type:ignore
- """The number of expected IPv6 ACL(s)"""
+ number: PositiveInteger
+ """The number of expected IPv6 ACL(s)."""
vrf: str = "default"
- """The name of the VRF in which to check for the SSHD agent"""
+ """The name of the VRF in which to check for the SSHD agent. Defaults to `default` VRF."""
@AntaTest.anta_test
def test(self) -> None:
+ """Main test function for VerifySSHIPv6Acl."""
command_output = self.instance_commands[0].json_output
ipv6_acl_list = command_output["ipv6AclList"]["aclList"]
ipv6_acl_number = len(ipv6_acl_list)
- not_configured_acl_list = []
if ipv6_acl_number != self.inputs.number:
self.result.is_failure(f"Expected {self.inputs.number} SSH IPv6 ACL(s) in vrf {self.inputs.vrf} but got {ipv6_acl_number}")
return
- for ipv6_acl in ipv6_acl_list:
- if self.inputs.vrf not in ipv6_acl["configuredVrfs"] or self.inputs.vrf not in ipv6_acl["activeVrfs"]:
- not_configured_acl_list.append(ipv6_acl["name"])
- if not_configured_acl_list:
- self.result.is_failure(f"SSH IPv6 ACL(s) not configured or active in vrf {self.inputs.vrf}: {not_configured_acl_list}")
+
+ not_configured_acl = [acl["name"] for acl in ipv6_acl_list if self.inputs.vrf not in acl["configuredVrfs"] or self.inputs.vrf not in acl["activeVrfs"]]
+
+ if not_configured_acl:
+ self.result.is_failure(f"SSH IPv6 ACL(s) not configured or active in vrf {self.inputs.vrf}: {not_configured_acl}")
else:
self.result.is_success()
class VerifyTelnetStatus(AntaTest):
- """
- Verifies if Telnet is disabled in the default VRF.
-
- Expected Results:
- * success: The test will pass if Telnet is disabled in the default VRF.
- * failure: The test will fail if Telnet is NOT disabled in the default VRF.
+ """Verifies if Telnet is disabled in the default VRF.
+
+ Expected Results
+ ----------------
+ * Success: The test will pass if Telnet is disabled in the default VRF.
+ * Failure: The test will fail if Telnet is NOT disabled in the default VRF.
+
+ Examples
+ --------
+ ```yaml
+ anta.tests.security:
+ - VerifyTelnetStatus:
+ ```
"""
name = "VerifyTelnetStatus"
description = "Verifies if Telnet is disabled in the default VRF."
- categories = ["security"]
- commands = [AntaCommand(command="show management telnet")]
+ categories: ClassVar[list[str]] = ["security"]
+ commands: ClassVar[list[AntaCommand | AntaTemplate]] = [AntaCommand(command="show management telnet", revision=1)]
@AntaTest.anta_test
def test(self) -> None:
+ """Main test function for VerifyTelnetStatus."""
command_output = self.instance_commands[0].json_output
if command_output["serverState"] == "disabled":
self.result.is_success()
@@ -147,21 +187,29 @@ class VerifyTelnetStatus(AntaTest):
class VerifyAPIHttpStatus(AntaTest):
- """
- Verifies if eAPI HTTP server is disabled globally.
-
- Expected Results:
- * success: The test will pass if eAPI HTTP server is disabled globally.
- * failure: The test will fail if eAPI HTTP server is NOT disabled globally.
+ """Verifies if eAPI HTTP server is disabled globally.
+
+ Expected Results
+ ----------------
+ * Success: The test will pass if eAPI HTTP server is disabled globally.
+ * Failure: The test will fail if eAPI HTTP server is NOT disabled globally.
+
+ Examples
+ --------
+ ```yaml
+ anta.tests.security:
+ - VerifyAPIHttpStatus:
+ ```
"""
name = "VerifyAPIHttpStatus"
description = "Verifies if eAPI HTTP server is disabled globally."
- categories = ["security"]
- commands = [AntaCommand(command="show management api http-commands")]
+ categories: ClassVar[list[str]] = ["security"]
+ commands: ClassVar[list[AntaCommand | AntaTemplate]] = [AntaCommand(command="show management api http-commands", revision=1)]
@AntaTest.anta_test
def test(self) -> None:
+ """Main test function for VerifyAPIHttpStatus."""
command_output = self.instance_commands[0].json_output
if command_output["enabled"] and not command_output["httpServer"]["running"]:
self.result.is_success()
@@ -170,25 +218,36 @@ class VerifyAPIHttpStatus(AntaTest):
class VerifyAPIHttpsSSL(AntaTest):
- """
- Verifies if eAPI HTTPS server SSL profile is configured and valid.
-
- Expected results:
- * success: The test will pass if the eAPI HTTPS server SSL profile is configured and valid.
- * failure: The test will fail if the eAPI HTTPS server SSL profile is NOT configured, misconfigured or invalid.
+ """Verifies if eAPI HTTPS server SSL profile is configured and valid.
+
+ Expected Results
+ ----------------
+ * Success: The test will pass if the eAPI HTTPS server SSL profile is configured and valid.
+ * Failure: The test will fail if the eAPI HTTPS server SSL profile is NOT configured, misconfigured or invalid.
+
+ Examples
+ --------
+ ```yaml
+ anta.tests.security:
+ - VerifyAPIHttpsSSL:
+ profile: default
+ ```
"""
name = "VerifyAPIHttpsSSL"
description = "Verifies if the eAPI has a valid SSL profile."
- categories = ["security"]
- commands = [AntaCommand(command="show management api http-commands")]
+ categories: ClassVar[list[str]] = ["security"]
+ commands: ClassVar[list[AntaCommand | AntaTemplate]] = [AntaCommand(command="show management api http-commands", revision=1)]
+
+ class Input(AntaTest.Input):
+ """Input model for the VerifyAPIHttpsSSL test."""
- class Input(AntaTest.Input): # pylint: disable=missing-class-docstring
profile: str
- """SSL profile to verify"""
+ """SSL profile to verify."""
@AntaTest.anta_test
def test(self) -> None:
+ """Main test function for VerifyAPIHttpsSSL."""
command_output = self.instance_commands[0].json_output
try:
if command_output["sslProfile"]["name"] == self.inputs.profile and command_output["sslProfile"]["state"] == "valid":
@@ -201,110 +260,149 @@ class VerifyAPIHttpsSSL(AntaTest):
class VerifyAPIIPv4Acl(AntaTest):
- """
- Verifies if eAPI has the right number IPv4 ACL(s) configured for a specified VRF.
-
- Expected results:
- * success: The test will pass if eAPI has the provided number of IPv4 ACL(s) in the specified VRF.
- * failure: The test will fail if eAPI has not the right number of IPv4 ACL(s) in the specified VRF.
+ """Verifies if eAPI has the right number IPv4 ACL(s) configured for a specified VRF.
+
+ Expected Results
+ ----------------
+ * Success: The test will pass if eAPI has the provided number of IPv4 ACL(s) in the specified VRF.
+ * Failure: The test will fail if eAPI has not the right number of IPv4 ACL(s) in the specified VRF.
+
+ Examples
+ --------
+ ```yaml
+ anta.tests.security:
+ - VerifyAPIIPv4Acl:
+ number: 3
+ vrf: default
+ ```
"""
name = "VerifyAPIIPv4Acl"
description = "Verifies if eAPI has the right number IPv4 ACL(s) configured for a specified VRF."
- categories = ["security"]
- commands = [AntaCommand(command="show management api http-commands ip access-list summary")]
+ categories: ClassVar[list[str]] = ["security"]
+ commands: ClassVar[list[AntaCommand | AntaTemplate]] = [AntaCommand(command="show management api http-commands ip access-list summary", revision=1)]
- class Input(AntaTest.Input): # pylint: disable=missing-class-docstring
- number: conint(ge=0) # type:ignore
- """The number of expected IPv4 ACL(s)"""
+ class Input(AntaTest.Input):
+ """Input parameters for the VerifyAPIIPv4Acl test."""
+
+ number: PositiveInteger
+ """The number of expected IPv4 ACL(s)."""
vrf: str = "default"
- """The name of the VRF in which to check for eAPI"""
+ """The name of the VRF in which to check for eAPI. Defaults to `default` VRF."""
@AntaTest.anta_test
def test(self) -> None:
+ """Main test function for VerifyAPIIPv4Acl."""
command_output = self.instance_commands[0].json_output
ipv4_acl_list = command_output["ipAclList"]["aclList"]
ipv4_acl_number = len(ipv4_acl_list)
- not_configured_acl_list = []
if ipv4_acl_number != self.inputs.number:
self.result.is_failure(f"Expected {self.inputs.number} eAPI IPv4 ACL(s) in vrf {self.inputs.vrf} but got {ipv4_acl_number}")
return
- for ipv4_acl in ipv4_acl_list:
- if self.inputs.vrf not in ipv4_acl["configuredVrfs"] or self.inputs.vrf not in ipv4_acl["activeVrfs"]:
- not_configured_acl_list.append(ipv4_acl["name"])
- if not_configured_acl_list:
- self.result.is_failure(f"eAPI IPv4 ACL(s) not configured or active in vrf {self.inputs.vrf}: {not_configured_acl_list}")
+
+ not_configured_acl = [acl["name"] for acl in ipv4_acl_list if self.inputs.vrf not in acl["configuredVrfs"] or self.inputs.vrf not in acl["activeVrfs"]]
+
+ if not_configured_acl:
+ self.result.is_failure(f"eAPI IPv4 ACL(s) not configured or active in vrf {self.inputs.vrf}: {not_configured_acl}")
else:
self.result.is_success()
class VerifyAPIIPv6Acl(AntaTest):
- """
- Verifies if eAPI has the right number IPv6 ACL(s) configured for a specified VRF.
-
- Expected results:
- * success: The test will pass if eAPI has the provided number of IPv6 ACL(s) in the specified VRF.
- * failure: The test will fail if eAPI has not the right number of IPv6 ACL(s) in the specified VRF.
- * skipped: The test will be skipped if the number of IPv6 ACL(s) or VRF parameter is not provided.
+ """Verifies if eAPI has the right number IPv6 ACL(s) configured for a specified VRF.
+
+ Expected Results
+ ----------------
+ * Success: The test will pass if eAPI has the provided number of IPv6 ACL(s) in the specified VRF.
+ * Failure: The test will fail if eAPI has not the right number of IPv6 ACL(s) in the specified VRF.
+ * Skipped: The test will be skipped if the number of IPv6 ACL(s) or VRF parameter is not provided.
+
+ Examples
+ --------
+ ```yaml
+ anta.tests.security:
+ - VerifyAPIIPv6Acl:
+ number: 3
+ vrf: default
+ ```
"""
name = "VerifyAPIIPv6Acl"
description = "Verifies if eAPI has the right number IPv6 ACL(s) configured for a specified VRF."
- categories = ["security"]
- commands = [AntaCommand(command="show management api http-commands ipv6 access-list summary")]
+ categories: ClassVar[list[str]] = ["security"]
+ commands: ClassVar[list[AntaCommand | AntaTemplate]] = [AntaCommand(command="show management api http-commands ipv6 access-list summary", revision=1)]
- class Input(AntaTest.Input): # pylint: disable=missing-class-docstring
- number: conint(ge=0) # type:ignore
- """The number of expected IPv6 ACL(s)"""
+ class Input(AntaTest.Input):
+ """Input parameters for the VerifyAPIIPv6Acl test."""
+
+ number: PositiveInteger
+ """The number of expected IPv6 ACL(s)."""
vrf: str = "default"
- """The name of the VRF in which to check for eAPI"""
+ """The name of the VRF in which to check for eAPI. Defaults to `default` VRF."""
@AntaTest.anta_test
def test(self) -> None:
+ """Main test function for VerifyAPIIPv6Acl."""
command_output = self.instance_commands[0].json_output
ipv6_acl_list = command_output["ipv6AclList"]["aclList"]
ipv6_acl_number = len(ipv6_acl_list)
- not_configured_acl_list = []
if ipv6_acl_number != self.inputs.number:
self.result.is_failure(f"Expected {self.inputs.number} eAPI IPv6 ACL(s) in vrf {self.inputs.vrf} but got {ipv6_acl_number}")
return
- for ipv6_acl in ipv6_acl_list:
- if self.inputs.vrf not in ipv6_acl["configuredVrfs"] or self.inputs.vrf not in ipv6_acl["activeVrfs"]:
- not_configured_acl_list.append(ipv6_acl["name"])
- if not_configured_acl_list:
- self.result.is_failure(f"eAPI IPv6 ACL(s) not configured or active in vrf {self.inputs.vrf}: {not_configured_acl_list}")
+
+ not_configured_acl = [acl["name"] for acl in ipv6_acl_list if self.inputs.vrf not in acl["configuredVrfs"] or self.inputs.vrf not in acl["activeVrfs"]]
+
+ if not_configured_acl:
+ self.result.is_failure(f"eAPI IPv6 ACL(s) not configured or active in vrf {self.inputs.vrf}: {not_configured_acl}")
else:
self.result.is_success()
class VerifyAPISSLCertificate(AntaTest):
- """
- Verifies the eAPI SSL certificate expiry, common subject name, encryption algorithm and key size.
+ """Verifies the eAPI SSL certificate expiry, common subject name, encryption algorithm and key size.
- Expected Results:
- * success: The test will pass if the certificate's expiry date is greater than the threshold,
+ Expected Results
+ ----------------
+ * Success: The test will pass if the certificate's expiry date is greater than the threshold,
and the certificate has the correct name, encryption algorithm, and key size.
- * failure: The test will fail if the certificate is expired or is going to expire,
+ * Failure: The test will fail if the certificate is expired or is going to expire,
or if the certificate has an incorrect name, encryption algorithm, or key size.
+
+ Examples
+ --------
+ ```yaml
+ anta.tests.security:
+ - VerifyAPISSLCertificate:
+ certificates:
+ - certificate_name: ARISTA_SIGNING_CA.crt
+ expiry_threshold: 30
+ common_name: AristaIT-ICA ECDSA Issuing Cert Authority
+ encryption_algorithm: ECDSA
+ key_size: 256
+ - certificate_name: ARISTA_ROOT_CA.crt
+ expiry_threshold: 30
+ common_name: Arista Networks Internal IT Root Cert Authority
+ encryption_algorithm: RSA
+ key_size: 4096
+ ```
"""
name = "VerifyAPISSLCertificate"
description = "Verifies the eAPI SSL certificate expiry, common subject name, encryption algorithm and key size."
- categories = ["security"]
- commands = [AntaCommand(command="show management security ssl certificate"), AntaCommand(command="show clock")]
+ categories: ClassVar[list[str]] = ["security"]
+ commands: ClassVar[list[AntaCommand | AntaTemplate]] = [
+ AntaCommand(command="show management security ssl certificate", revision=1),
+ AntaCommand(command="show clock", revision=1),
+ ]
class Input(AntaTest.Input):
- """
- Input parameters for the VerifyAPISSLCertificate test.
- """
+ """Input parameters for the VerifyAPISSLCertificate test."""
- certificates: List[APISSLCertificates]
- """List of API SSL certificates"""
+ certificates: list[APISSLCertificate]
+ """List of API SSL certificates."""
- class APISSLCertificates(BaseModel):
- """
- This class defines the details of an API SSL certificate.
- """
+ class APISSLCertificate(BaseModel):
+ """Model for an API SSL certificate."""
certificate_name: str
"""The name of the certificate to be verified."""
@@ -314,31 +412,30 @@ class VerifyAPISSLCertificate(AntaTest):
"""The common subject name of the certificate."""
encryption_algorithm: EncryptionAlgorithm
"""The encryption algorithm of the certificate."""
- key_size: Union[RsaKeySize, EcdsaKeySize]
+ key_size: RsaKeySize | EcdsaKeySize
"""The encryption algorithm key size of the certificate."""
@model_validator(mode="after")
def validate_inputs(self: BaseModel) -> BaseModel:
- """
- Validate the key size provided to the APISSLCertificates class.
+ """Validate the key size provided to the APISSLCertificates class.
If encryption_algorithm is RSA then key_size should be in {2048, 3072, 4096}.
If encryption_algorithm is ECDSA then key_size should be in {256, 384, 521}.
"""
-
if self.encryption_algorithm == "RSA" and self.key_size not in RsaKeySize.__args__:
- raise ValueError(f"`{self.certificate_name}` key size {self.key_size} is invalid for RSA encryption. Allowed sizes are {RsaKeySize.__args__}.")
+ msg = f"`{self.certificate_name}` key size {self.key_size} is invalid for RSA encryption. Allowed sizes are {RsaKeySize.__args__}."
+ raise ValueError(msg)
if self.encryption_algorithm == "ECDSA" and self.key_size not in EcdsaKeySize.__args__:
- raise ValueError(
- f"`{self.certificate_name}` key size {self.key_size} is invalid for ECDSA encryption. Allowed sizes are {EcdsaKeySize.__args__}."
- )
+ msg = f"`{self.certificate_name}` key size {self.key_size} is invalid for ECDSA encryption. Allowed sizes are {EcdsaKeySize.__args__}."
+ raise ValueError(msg)
return self
@AntaTest.anta_test
def test(self) -> None:
+ """Main test function for VerifyAPISSLCertificate."""
# Mark the result as success by default
self.result.is_success()
@@ -356,7 +453,7 @@ class VerifyAPISSLCertificate(AntaTest):
continue
expiry_time = certificate_data["notAfter"]
- day_difference = (datetime.fromtimestamp(expiry_time) - datetime.fromtimestamp(current_timestamp)).days
+ day_difference = (datetime.fromtimestamp(expiry_time, tz=timezone.utc) - datetime.fromtimestamp(current_timestamp, tz=timezone.utc)).days
# Verify certificate expiry
if 0 < day_difference < certificate.expiry_threshold:
@@ -381,27 +478,39 @@ class VerifyAPISSLCertificate(AntaTest):
class VerifyBannerLogin(AntaTest):
- """
- Verifies the login banner of a device.
-
- Expected results:
- * success: The test will pass if the login banner matches the provided input.
- * failure: The test will fail if the login banner does not match the provided input.
+ """Verifies the login banner of a device.
+
+ Expected Results
+ ----------------
+ * Success: The test will pass if the login banner matches the provided input.
+ * Failure: The test will fail if the login banner does not match the provided input.
+
+ Examples
+ --------
+ ```yaml
+ anta.tests.security:
+ - VerifyBannerLogin:
+ login_banner: |
+ # Copyright (c) 2023-2024 Arista Networks, Inc.
+ # Use of this source code is governed by the Apache License 2.0
+ # that can be found in the LICENSE file.
+ ```
"""
name = "VerifyBannerLogin"
description = "Verifies the login banner of a device."
- categories = ["security"]
- commands = [AntaCommand(command="show banner login")]
+ categories: ClassVar[list[str]] = ["security"]
+ commands: ClassVar[list[AntaCommand | AntaTemplate]] = [AntaCommand(command="show banner login", revision=1)]
class Input(AntaTest.Input):
- """Defines the input parameters for this test case."""
+ """Input model for the VerifyBannerLogin test."""
login_banner: str
"""Expected login banner of the device."""
@AntaTest.anta_test
def test(self) -> None:
+ """Main test function for VerifyBannerLogin."""
login_banner = self.instance_commands[0].json_output["loginBanner"]
# Remove leading and trailing whitespaces from each line
@@ -413,27 +522,39 @@ class VerifyBannerLogin(AntaTest):
class VerifyBannerMotd(AntaTest):
- """
- Verifies the motd banner of a device.
-
- Expected results:
- * success: The test will pass if the motd banner matches the provided input.
- * failure: The test will fail if the motd banner does not match the provided input.
+ """Verifies the motd banner of a device.
+
+ Expected Results
+ ----------------
+ * Success: The test will pass if the motd banner matches the provided input.
+ * Failure: The test will fail if the motd banner does not match the provided input.
+
+ Examples
+ --------
+ ```yaml
+ anta.tests.security:
+ - VerifyBannerMotd:
+ motd_banner: |
+ # Copyright (c) 2023-2024 Arista Networks, Inc.
+ # Use of this source code is governed by the Apache License 2.0
+ # that can be found in the LICENSE file.
+ ```
"""
name = "VerifyBannerMotd"
description = "Verifies the motd banner of a device."
- categories = ["security"]
- commands = [AntaCommand(command="show banner motd")]
+ categories: ClassVar[list[str]] = ["security"]
+ commands: ClassVar[list[AntaCommand | AntaTemplate]] = [AntaCommand(command="show banner motd", revision=1)]
class Input(AntaTest.Input):
- """Defines the input parameters for this test case."""
+ """Input model for the VerifyBannerMotd test."""
motd_banner: str
"""Expected motd banner of the device."""
@AntaTest.anta_test
def test(self) -> None:
+ """Main test function for VerifyBannerMotd."""
motd_banner = self.instance_commands[0].json_output["motd"]
# Remove leading and trailing whitespaces from each line
@@ -445,52 +566,77 @@ class VerifyBannerMotd(AntaTest):
class VerifyIPv4ACL(AntaTest):
- """
- Verifies the configuration of IPv4 ACLs.
-
- Expected results:
- * success: The test will pass if an IPv4 ACL is configured with the correct sequence entries.
- * failure: The test will fail if an IPv4 ACL is not configured or entries are not in sequence.
+ """Verifies the configuration of IPv4 ACLs.
+
+ Expected Results
+ ----------------
+ * Success: The test will pass if an IPv4 ACL is configured with the correct sequence entries.
+ * Failure: The test will fail if an IPv4 ACL is not configured or entries are not in sequence.
+
+ Examples
+ --------
+ ```yaml
+ anta.tests.security:
+ - VerifyIPv4ACL:
+ ipv4_access_lists:
+ - name: default-control-plane-acl
+ entries:
+ - sequence: 10
+ action: permit icmp any any
+ - sequence: 20
+ action: permit ip any any tracked
+ - sequence: 30
+ action: permit udp any any eq bfd ttl eq 255
+ - name: LabTest
+ entries:
+ - sequence: 10
+ action: permit icmp any any
+ - sequence: 20
+ action: permit tcp any any range 5900 5910
+ ```
"""
name = "VerifyIPv4ACL"
description = "Verifies the configuration of IPv4 ACLs."
- categories = ["security"]
- commands = [AntaTemplate(template="show ip access-lists {acl}")]
+ categories: ClassVar[list[str]] = ["security"]
+ commands: ClassVar[list[AntaCommand | AntaTemplate]] = [AntaTemplate(template="show ip access-lists {acl}", revision=1)]
class Input(AntaTest.Input):
- """Inputs for the VerifyIPv4ACL test."""
+ """Input model for the VerifyIPv4ACL test."""
- ipv4_access_lists: List[IPv4ACL]
- """List of IPv4 ACLs to verify"""
+ ipv4_access_lists: list[IPv4ACL]
+ """List of IPv4 ACLs to verify."""
class IPv4ACL(BaseModel):
- """Detail of IPv4 ACL"""
+ """Model for an IPv4 ACL."""
name: str
- """Name of IPv4 ACL"""
+ """Name of IPv4 ACL."""
- entries: List[IPv4ACLEntries]
- """List of IPv4 ACL entries"""
+ entries: list[IPv4ACLEntry]
+ """List of IPv4 ACL entries."""
- class IPv4ACLEntries(BaseModel):
- """IPv4 ACL entries details"""
+ class IPv4ACLEntry(BaseModel):
+ """Model for an IPv4 ACL entry."""
sequence: int = Field(ge=1, le=4294967295)
- """Sequence number of an ACL entry"""
+ """Sequence number of an ACL entry."""
action: str
- """Action of an ACL entry"""
+ """Action of an ACL entry."""
def render(self, template: AntaTemplate) -> list[AntaCommand]:
- return [template.render(acl=acl.name, entries=acl.entries) for acl in self.inputs.ipv4_access_lists]
+ """Render the template for each input ACL."""
+ return [template.render(acl=acl.name) for acl in self.inputs.ipv4_access_lists]
@AntaTest.anta_test
def test(self) -> None:
+ """Main test function for VerifyIPv4ACL."""
self.result.is_success()
- for command_output in self.instance_commands:
+ for command_output, acl in zip(self.instance_commands, self.inputs.ipv4_access_lists):
# Collecting input ACL details
- acl_name = command_output.params["acl"]
- acl_entries = command_output.params["entries"]
+ acl_name = command_output.params.acl
+ # Retrieve the expected entries from the inputs
+ acl_entries = acl.entries
# Check if ACL is configured
ipv4_acl_list = command_output.json_output["aclList"]
@@ -512,3 +658,165 @@ class VerifyIPv4ACL(AntaTest):
if failed_log != f"{acl_name}:\n":
self.result.is_failure(f"{failed_log}")
+
+
+class VerifyIPSecConnHealth(AntaTest):
+ """
+ Verifies all IPv4 security connections.
+
+ Expected Results
+ ----------------
+ * Success: The test will pass if all the IPv4 security connections are established in all vrf.
+ * Failure: The test will fail if IPv4 security is not configured or any of IPv4 security connections are not established in any vrf.
+
+ Examples
+ --------
+ ```yaml
+ anta.tests.security:
+ - VerifyIPSecConnHealth:
+ ```
+ """
+
+ name = "VerifyIPSecConnHealth"
+ description = "Verifies all IPv4 security connections."
+ categories: ClassVar[list[str]] = ["security"]
+ commands: ClassVar[list[AntaCommand | AntaTemplate]] = [AntaCommand(command="show ip security connection vrf all")]
+
+ @AntaTest.anta_test
+ def test(self) -> None:
+ """Main test function for VerifyIPSecConnHealth."""
+ self.result.is_success()
+ failure_conn = []
+ command_output = self.instance_commands[0].json_output["connections"]
+
+ # Check if IP security connection is configured
+ if not command_output:
+ self.result.is_failure("No IPv4 security connection configured.")
+ return
+
+ # Iterate over all ipsec connections
+ for conn_data in command_output.values():
+ state = next(iter(conn_data["pathDict"].values()))
+ if state != "Established":
+ source = conn_data.get("saddr")
+ destination = conn_data.get("daddr")
+ vrf = conn_data.get("tunnelNs")
+ failure_conn.append(f"source:{source} destination:{destination} vrf:{vrf}")
+ if failure_conn:
+ failure_msg = "\n".join(failure_conn)
+ self.result.is_failure(f"The following IPv4 security connections are not established:\n{failure_msg}.")
+
+
+class VerifySpecificIPSecConn(AntaTest):
+ """
+ Verifies the state of IPv4 security connections for a specified peer.
+
+ It optionally allows for the verification of a specific path for a peer by providing source and destination addresses.
+ If these addresses are not provided, it will verify all paths for the specified peer.
+
+ Expected Results
+ ----------------
+ * Success: The test passes if the IPv4 security connection for a peer is established in the specified VRF.
+ * Failure: The test fails if IPv4 security is not configured, a connection is not found for a peer, or the connection is not established in the specified VRF.
+
+ Examples
+ --------
+ ```yaml
+ anta.tests.security:
+ - VerifySpecificIPSecConn:
+ ip_security_connections:
+ - peer: 10.255.0.1
+ - peer: 10.255.0.2
+ vrf: default
+ connections:
+ - source_address: 100.64.3.2
+ destination_address: 100.64.2.2
+ - source_address: 172.18.3.2
+ destination_address: 172.18.2.2
+ ```
+ """
+
+ name = "VerifySpecificIPSecConn"
+ description = "Verifies IPv4 security connections for a peer."
+ categories: ClassVar[list[str]] = ["security"]
+ commands: ClassVar[list[AntaCommand | AntaTemplate]] = [AntaTemplate(template="show ip security connection vrf {vrf} path peer {peer}")]
+
+ class Input(AntaTest.Input):
+ """Input model for the VerifySpecificIPSecConn test."""
+
+ ip_security_connections: list[IPSecPeers]
+ """List of IP4v security peers."""
+
+ class IPSecPeers(BaseModel):
+ """Details of IPv4 security peers."""
+
+ peer: IPv4Address
+ """IPv4 address of the peer."""
+
+ vrf: str = "default"
+ """Optional VRF for the IP security peer."""
+
+ connections: list[IPSecConn] | None = None
+ """Optional list of IPv4 security connections of a peer."""
+
+ class IPSecConn(BaseModel):
+ """Details of IPv4 security connections for a peer."""
+
+ source_address: IPv4Address
+ """Source IPv4 address of the connection."""
+ destination_address: IPv4Address
+ """Destination IPv4 address of the connection."""
+
+ def render(self, template: AntaTemplate) -> list[AntaCommand]:
+ """Render the template for each input IP Sec connection."""
+ return [template.render(peer=conn.peer, vrf=conn.vrf) for conn in self.inputs.ip_security_connections]
+
+ @AntaTest.anta_test
+ def test(self) -> None:
+ """Main test function for VerifySpecificIPSecConn."""
+ self.result.is_success()
+ for command_output, input_peer in zip(self.instance_commands, self.inputs.ip_security_connections):
+ conn_output = command_output.json_output["connections"]
+ peer = command_output.params.peer
+ vrf = command_output.params.vrf
+ conn_input = input_peer.connections
+
+ # Check if IPv4 security connection is configured
+ if not conn_output:
+ self.result.is_failure(f"No IPv4 security connection configured for peer `{peer}`.")
+ continue
+
+ # If connection details are not provided then check all connections of a peer
+ if conn_input is None:
+ for conn_data in conn_output.values():
+ state = next(iter(conn_data["pathDict"].values()))
+ if state != "Established":
+ source = conn_data.get("saddr")
+ destination = conn_data.get("daddr")
+ vrf = conn_data.get("tunnelNs")
+ self.result.is_failure(
+ f"Expected state of IPv4 security connection `source:{source} destination:{destination} vrf:{vrf}` for peer `{peer}` is `Established` "
+ f"but found `{state}` instead."
+ )
+ continue
+
+ # Create a dictionary of existing connections for faster lookup
+ existing_connections = {
+ (conn_data.get("saddr"), conn_data.get("daddr"), conn_data.get("tunnelNs")): next(iter(conn_data["pathDict"].values()))
+ for conn_data in conn_output.values()
+ }
+ for connection in conn_input:
+ source_input = str(connection.source_address)
+ destination_input = str(connection.destination_address)
+
+ if (source_input, destination_input, vrf) in existing_connections:
+ existing_state = existing_connections[(source_input, destination_input, vrf)]
+ if existing_state != "Established":
+ self.result.is_failure(
+ f"Expected state of IPv4 security connection `source:{source_input} destination:{destination_input} vrf:{vrf}` "
+ f"for peer `{peer}` is `Established` but found `{existing_state}` instead."
+ )
+ else:
+ self.result.is_failure(
+ f"IPv4 security connection `source:{source_input} destination:{destination_input} vrf:{vrf}` for peer `{peer}` is not found."
+ )
diff --git a/anta/tests/services.py b/anta/tests/services.py
index a2c2136..6184263 100644
--- a/anta/tests/services.py
+++ b/anta/tests/services.py
@@ -1,48 +1,53 @@
# Copyright (c) 2023-2024 Arista Networks, Inc.
# Use of this source code is governed by the Apache License 2.0
# that can be found in the LICENSE file.
-"""
-Test functions related to the EOS various services settings
-"""
+"""Module related to the EOS various services tests."""
+
from __future__ import annotations
+# Mypy does not understand AntaTest.Input typing
+# mypy: disable-error-code=attr-defined
from ipaddress import IPv4Address, IPv6Address
-from typing import List, Union
+from typing import ClassVar
from pydantic import BaseModel, Field
from anta.custom_types import ErrDisableInterval, ErrDisableReasons
from anta.models import AntaCommand, AntaTemplate, AntaTest
-from anta.tools.get_dict_superset import get_dict_superset
-from anta.tools.get_item import get_item
-from anta.tools.utils import get_failed_logs
-
-# Mypy does not understand AntaTest.Input typing
-# mypy: disable-error-code=attr-defined
+from anta.tools import get_dict_superset, get_failed_logs, get_item
class VerifyHostname(AntaTest):
- """
- Verifies the hostname of a device.
-
- Expected results:
- * success: The test will pass if the hostname matches the provided input.
- * failure: The test will fail if the hostname does not match the provided input.
+ """Verifies the hostname of a device.
+
+ Expected Results
+ ----------------
+ * Success: The test will pass if the hostname matches the provided input.
+ * Failure: The test will fail if the hostname does not match the provided input.
+
+ Examples
+ --------
+ ```yaml
+ anta.tests.services:
+ - VerifyHostname:
+ hostname: s1-spine1
+ ```
"""
name = "VerifyHostname"
description = "Verifies the hostname of a device."
- categories = ["services"]
- commands = [AntaCommand(command="show hostname")]
+ categories: ClassVar[list[str]] = ["services"]
+ commands: ClassVar[list[AntaCommand | AntaTemplate]] = [AntaCommand(command="show hostname", revision=1)]
class Input(AntaTest.Input):
- """Defines the input parameters for this test case."""
+ """Input model for the VerifyHostname test."""
hostname: str
"""Expected hostname of the device."""
@AntaTest.anta_test
def test(self) -> None:
+ """Main test function for VerifyHostname."""
hostname = self.instance_commands[0].json_output["hostname"]
if hostname != self.inputs.hostname:
@@ -52,35 +57,48 @@ class VerifyHostname(AntaTest):
class VerifyDNSLookup(AntaTest):
- """
- This class verifies the DNS (Domain name service) name to IP address resolution.
-
- Expected Results:
- * success: The test will pass if a domain name is resolved to an IP address.
- * failure: The test will fail if a domain name does not resolve to an IP address.
- * error: This test will error out if a domain name is invalid.
+ """Verifies the DNS (Domain Name Service) name to IP address resolution.
+
+ Expected Results
+ ----------------
+ * Success: The test will pass if a domain name is resolved to an IP address.
+ * Failure: The test will fail if a domain name does not resolve to an IP address.
+ * Error: This test will error out if a domain name is invalid.
+
+ Examples
+ --------
+ ```yaml
+ anta.tests.services:
+ - VerifyDNSLookup:
+ domain_names:
+ - arista.com
+ - www.google.com
+ - arista.ca
+ ```
"""
name = "VerifyDNSLookup"
description = "Verifies the DNS name to IP address resolution."
- categories = ["services"]
- commands = [AntaTemplate(template="bash timeout 10 nslookup {domain}")]
+ categories: ClassVar[list[str]] = ["services"]
+ commands: ClassVar[list[AntaCommand | AntaTemplate]] = [AntaTemplate(template="bash timeout 10 nslookup {domain}", revision=1)]
class Input(AntaTest.Input):
- """Inputs for the VerifyDNSLookup test."""
+ """Input model for the VerifyDNSLookup test."""
- domain_names: List[str]
- """List of domain names"""
+ domain_names: list[str]
+ """List of domain names."""
def render(self, template: AntaTemplate) -> list[AntaCommand]:
+ """Render the template for each domain name in the input list."""
return [template.render(domain=domain_name) for domain_name in self.inputs.domain_names]
@AntaTest.anta_test
def test(self) -> None:
+ """Main test function for VerifyDNSLookup."""
self.result.is_success()
failed_domains = []
for command in self.instance_commands:
- domain = command.params["domain"]
+ domain = command.params.domain
output = command.json_output["messages"][0]
if f"Can't find {domain}: No answer" in output:
failed_domains.append(domain)
@@ -89,29 +107,43 @@ class VerifyDNSLookup(AntaTest):
class VerifyDNSServers(AntaTest):
- """
- Verifies if the DNS (Domain Name Service) servers are correctly configured.
-
- Expected Results:
- * success: The test will pass if the DNS server specified in the input is configured with the correct VRF and priority.
- * failure: The test will fail if the DNS server is not configured or if the VRF and priority of the DNS server do not match the input.
+ """Verifies if the DNS (Domain Name Service) servers are correctly configured.
+
+ Expected Results
+ ----------------
+ * Success: The test will pass if the DNS server specified in the input is configured with the correct VRF and priority.
+ * Failure: The test will fail if the DNS server is not configured or if the VRF and priority of the DNS server do not match the input.
+
+ Examples
+ --------
+ ```yaml
+ anta.tests.services:
+ - VerifyDNSServers:
+ dns_servers:
+ - server_address: 10.14.0.1
+ vrf: default
+ priority: 1
+ - server_address: 10.14.0.11
+ vrf: MGMT
+ priority: 0
+ ```
"""
name = "VerifyDNSServers"
description = "Verifies if the DNS servers are correctly configured."
- categories = ["services"]
- commands = [AntaCommand(command="show ip name-server")]
+ categories: ClassVar[list[str]] = ["services"]
+ commands: ClassVar[list[AntaCommand | AntaTemplate]] = [AntaCommand(command="show ip name-server", revision=1)]
class Input(AntaTest.Input):
- """Inputs for the VerifyDNSServers test."""
+ """Input model for the VerifyDNSServers test."""
- dns_servers: List[DnsServers]
+ dns_servers: list[DnsServer]
"""List of DNS servers to verify."""
- class DnsServers(BaseModel):
- """DNS server details"""
+ class DnsServer(BaseModel):
+ """Model for a DNS server."""
- server_address: Union[IPv4Address, IPv6Address]
+ server_address: IPv4Address | IPv6Address
"""The IPv4/IPv6 address of the DNS server."""
vrf: str = "default"
"""The VRF for the DNS server. Defaults to 'default' if not provided."""
@@ -120,6 +152,7 @@ class VerifyDNSServers(AntaTest):
@AntaTest.anta_test
def test(self) -> None:
+ """Main test function for VerifyDNSServers."""
command_output = self.instance_commands[0].json_output["nameServerConfigs"]
self.result.is_success()
for server in self.inputs.dns_servers:
@@ -141,35 +174,49 @@ class VerifyDNSServers(AntaTest):
class VerifyErrdisableRecovery(AntaTest):
- """
- Verifies the errdisable recovery reason, status, and interval.
-
- Expected Results:
- * Success: The test will pass if the errdisable recovery reason status is enabled and the interval matches the input.
- * Failure: The test will fail if the errdisable recovery reason is not found, the status is not enabled, or the interval does not match the input.
+ """Verifies the errdisable recovery reason, status, and interval.
+
+ Expected Results
+ ----------------
+ * Success: The test will pass if the errdisable recovery reason status is enabled and the interval matches the input.
+ * Failure: The test will fail if the errdisable recovery reason is not found, the status is not enabled, or the interval does not match the input.
+
+ Examples
+ --------
+ ```yaml
+ anta.tests.services:
+ - VerifyErrdisableRecovery:
+ reasons:
+ - reason: acl
+ interval: 30
+ - reason: bpduguard
+ interval: 30
+ ```
"""
name = "VerifyErrdisableRecovery"
description = "Verifies the errdisable recovery reason, status, and interval."
- categories = ["services"]
- commands = [AntaCommand(command="show errdisable recovery", ofmt="text")] # Command does not support JSON output hence using text output
+ categories: ClassVar[list[str]] = ["services"]
+ # NOTE: Only `text` output format is supported for this command
+ commands: ClassVar[list[AntaCommand | AntaTemplate]] = [AntaCommand(command="show errdisable recovery", ofmt="text")]
class Input(AntaTest.Input):
- """Inputs for the VerifyErrdisableRecovery test."""
+ """Input model for the VerifyErrdisableRecovery test."""
- reasons: List[ErrDisableReason]
- """List of errdisable reasons"""
+ reasons: list[ErrDisableReason]
+ """List of errdisable reasons."""
class ErrDisableReason(BaseModel):
- """Details of an errdisable reason"""
+ """Model for an errdisable reason."""
reason: ErrDisableReasons
- """Type or name of the errdisable reason"""
+ """Type or name of the errdisable reason."""
interval: ErrDisableInterval
- """Interval of the reason in seconds"""
+ """Interval of the reason in seconds."""
@AntaTest.anta_test
def test(self) -> None:
+ """Main test function for VerifyErrdisableRecovery."""
command_output = self.instance_commands[0].text_output
self.result.is_success()
for error_reason in self.inputs.reasons:
diff --git a/anta/tests/snmp.py b/anta/tests/snmp.py
index 39d9424..ac98bfd 100644
--- a/anta/tests/snmp.py
+++ b/anta/tests/snmp.py
@@ -1,38 +1,52 @@
# Copyright (c) 2023-2024 Arista Networks, Inc.
# Use of this source code is governed by the Apache License 2.0
# that can be found in the LICENSE file.
-"""
-Test functions related to the EOS various SNMP settings
-"""
+"""Module related to the EOS various SNMP tests."""
+
# Mypy does not understand AntaTest.Input typing
# mypy: disable-error-code=attr-defined
from __future__ import annotations
-from pydantic import conint
+from typing import TYPE_CHECKING, ClassVar
+from anta.custom_types import PositiveInteger
from anta.models import AntaCommand, AntaTest
+if TYPE_CHECKING:
+ from anta.models import AntaTemplate
-class VerifySnmpStatus(AntaTest):
- """
- Verifies whether the SNMP agent is enabled in a specified VRF.
- Expected Results:
- * success: The test will pass if the SNMP agent is enabled in the specified VRF.
- * failure: The test will fail if the SNMP agent is disabled in the specified VRF.
+class VerifySnmpStatus(AntaTest):
+ """Verifies whether the SNMP agent is enabled in a specified VRF.
+
+ Expected Results
+ ----------------
+ * Success: The test will pass if the SNMP agent is enabled in the specified VRF.
+ * Failure: The test will fail if the SNMP agent is disabled in the specified VRF.
+
+ Examples
+ --------
+ ```yaml
+ anta.tests.snmp:
+ - VerifySnmpStatus:
+ vrf: default
+ ```
"""
name = "VerifySnmpStatus"
description = "Verifies if the SNMP agent is enabled."
- categories = ["snmp"]
- commands = [AntaCommand(command="show snmp")]
+ categories: ClassVar[list[str]] = ["snmp"]
+ commands: ClassVar[list[AntaCommand | AntaTemplate]] = [AntaCommand(command="show snmp", revision=1)]
+
+ class Input(AntaTest.Input):
+ """Input model for the VerifySnmpStatus test."""
- class Input(AntaTest.Input): # pylint: disable=missing-class-docstring
vrf: str = "default"
- """The name of the VRF in which to check for the SNMP agent"""
+ """The name of the VRF in which to check for the SNMP agent. Defaults to `default` VRF."""
@AntaTest.anta_test
def test(self) -> None:
+ """Main test function for VerifySnmpStatus."""
command_output = self.instance_commands[0].json_output
if command_output["enabled"] and self.inputs.vrf in command_output["vrfs"]["snmpVrfs"]:
self.result.is_success()
@@ -41,103 +55,134 @@ class VerifySnmpStatus(AntaTest):
class VerifySnmpIPv4Acl(AntaTest):
- """
- Verifies if the SNMP agent has the right number IPv4 ACL(s) configured for a specified VRF.
-
- Expected results:
- * success: The test will pass if the SNMP agent has the provided number of IPv4 ACL(s) in the specified VRF.
- * failure: The test will fail if the SNMP agent has not the right number of IPv4 ACL(s) in the specified VRF.
+ """Verifies if the SNMP agent has the right number IPv4 ACL(s) configured for a specified VRF.
+
+ Expected Results
+ ----------------
+ * Success: The test will pass if the SNMP agent has the provided number of IPv4 ACL(s) in the specified VRF.
+ * Failure: The test will fail if the SNMP agent has not the right number of IPv4 ACL(s) in the specified VRF.
+
+ Examples
+ --------
+ ```yaml
+ anta.tests.snmp:
+ - VerifySnmpIPv4Acl:
+ number: 3
+ vrf: default
+ ```
"""
name = "VerifySnmpIPv4Acl"
description = "Verifies if the SNMP agent has IPv4 ACL(s) configured."
- categories = ["snmp"]
- commands = [AntaCommand(command="show snmp ipv4 access-list summary")]
+ categories: ClassVar[list[str]] = ["snmp"]
+ commands: ClassVar[list[AntaCommand | AntaTemplate]] = [AntaCommand(command="show snmp ipv4 access-list summary", revision=1)]
- class Input(AntaTest.Input): # pylint: disable=missing-class-docstring
- number: conint(ge=0) # type:ignore
- """The number of expected IPv4 ACL(s)"""
+ class Input(AntaTest.Input):
+ """Input model for the VerifySnmpIPv4Acl test."""
+
+ number: PositiveInteger
+ """The number of expected IPv4 ACL(s)."""
vrf: str = "default"
- """The name of the VRF in which to check for the SNMP agent"""
+ """The name of the VRF in which to check for the SNMP agent. Defaults to `default` VRF."""
@AntaTest.anta_test
def test(self) -> None:
+ """Main test function for VerifySnmpIPv4Acl."""
command_output = self.instance_commands[0].json_output
ipv4_acl_list = command_output["ipAclList"]["aclList"]
ipv4_acl_number = len(ipv4_acl_list)
- not_configured_acl_list = []
if ipv4_acl_number != self.inputs.number:
self.result.is_failure(f"Expected {self.inputs.number} SNMP IPv4 ACL(s) in vrf {self.inputs.vrf} but got {ipv4_acl_number}")
return
- for ipv4_acl in ipv4_acl_list:
- if self.inputs.vrf not in ipv4_acl["configuredVrfs"] or self.inputs.vrf not in ipv4_acl["activeVrfs"]:
- not_configured_acl_list.append(ipv4_acl["name"])
- if not_configured_acl_list:
- self.result.is_failure(f"SNMP IPv4 ACL(s) not configured or active in vrf {self.inputs.vrf}: {not_configured_acl_list}")
+
+ not_configured_acl = [acl["name"] for acl in ipv4_acl_list if self.inputs.vrf not in acl["configuredVrfs"] or self.inputs.vrf not in acl["activeVrfs"]]
+
+ if not_configured_acl:
+ self.result.is_failure(f"SNMP IPv4 ACL(s) not configured or active in vrf {self.inputs.vrf}: {not_configured_acl}")
else:
self.result.is_success()
class VerifySnmpIPv6Acl(AntaTest):
- """
- Verifies if the SNMP agent has the right number IPv6 ACL(s) configured for a specified VRF.
-
- Expected results:
- * success: The test will pass if the SNMP agent has the provided number of IPv6 ACL(s) in the specified VRF.
- * failure: The test will fail if the SNMP agent has not the right number of IPv6 ACL(s) in the specified VRF.
+ """Verifies if the SNMP agent has the right number IPv6 ACL(s) configured for a specified VRF.
+
+ Expected Results
+ ----------------
+ * Success: The test will pass if the SNMP agent has the provided number of IPv6 ACL(s) in the specified VRF.
+ * Failure: The test will fail if the SNMP agent has not the right number of IPv6 ACL(s) in the specified VRF.
+
+ Examples
+ --------
+ ```yaml
+ anta.tests.snmp:
+ - VerifySnmpIPv6Acl:
+ number: 3
+ vrf: default
+ ```
"""
name = "VerifySnmpIPv6Acl"
description = "Verifies if the SNMP agent has IPv6 ACL(s) configured."
- categories = ["snmp"]
- commands = [AntaCommand(command="show snmp ipv6 access-list summary")]
+ categories: ClassVar[list[str]] = ["snmp"]
+ commands: ClassVar[list[AntaCommand | AntaTemplate]] = [AntaCommand(command="show snmp ipv6 access-list summary", revision=1)]
- class Input(AntaTest.Input): # pylint: disable=missing-class-docstring
- number: conint(ge=0) # type:ignore
- """The number of expected IPv6 ACL(s)"""
+ class Input(AntaTest.Input):
+ """Input model for the VerifySnmpIPv6Acl test."""
+
+ number: PositiveInteger
+ """The number of expected IPv6 ACL(s)."""
vrf: str = "default"
- """The name of the VRF in which to check for the SNMP agent"""
+ """The name of the VRF in which to check for the SNMP agent. Defaults to `default` VRF."""
@AntaTest.anta_test
def test(self) -> None:
+ """Main test function for VerifySnmpIPv6Acl."""
command_output = self.instance_commands[0].json_output
ipv6_acl_list = command_output["ipv6AclList"]["aclList"]
ipv6_acl_number = len(ipv6_acl_list)
- not_configured_acl_list = []
if ipv6_acl_number != self.inputs.number:
self.result.is_failure(f"Expected {self.inputs.number} SNMP IPv6 ACL(s) in vrf {self.inputs.vrf} but got {ipv6_acl_number}")
return
- for ipv6_acl in ipv6_acl_list:
- if self.inputs.vrf not in ipv6_acl["configuredVrfs"] or self.inputs.vrf not in ipv6_acl["activeVrfs"]:
- not_configured_acl_list.append(ipv6_acl["name"])
- if not_configured_acl_list:
- self.result.is_failure(f"SNMP IPv6 ACL(s) not configured or active in vrf {self.inputs.vrf}: {not_configured_acl_list}")
+
+ acl_not_configured = [acl["name"] for acl in ipv6_acl_list if self.inputs.vrf not in acl["configuredVrfs"] or self.inputs.vrf not in acl["activeVrfs"]]
+
+ if acl_not_configured:
+ self.result.is_failure(f"SNMP IPv6 ACL(s) not configured or active in vrf {self.inputs.vrf}: {acl_not_configured}")
else:
self.result.is_success()
class VerifySnmpLocation(AntaTest):
- """
- This class verifies the SNMP location of a device.
-
- Expected results:
- * success: The test will pass if the SNMP location matches the provided input.
- * failure: The test will fail if the SNMP location does not match the provided input.
+ """Verifies the SNMP location of a device.
+
+ Expected Results
+ ----------------
+ * Success: The test will pass if the SNMP location matches the provided input.
+ * Failure: The test will fail if the SNMP location does not match the provided input.
+
+ Examples
+ --------
+ ```yaml
+ anta.tests.snmp:
+ - VerifySnmpLocation:
+ location: New York
+ ```
"""
name = "VerifySnmpLocation"
description = "Verifies the SNMP location of a device."
- categories = ["snmp"]
- commands = [AntaCommand(command="show snmp")]
+ categories: ClassVar[list[str]] = ["snmp"]
+ commands: ClassVar[list[AntaCommand | AntaTemplate]] = [AntaCommand(command="show snmp", revision=1)]
class Input(AntaTest.Input):
- """Defines the input parameters for this test case."""
+ """Input model for the VerifySnmpLocation test."""
location: str
"""Expected SNMP location of the device."""
@AntaTest.anta_test
def test(self) -> None:
+ """Main test function for VerifySnmpLocation."""
location = self.instance_commands[0].json_output["location"]["location"]
if location != self.inputs.location:
@@ -147,27 +192,36 @@ class VerifySnmpLocation(AntaTest):
class VerifySnmpContact(AntaTest):
- """
- This class verifies the SNMP contact of a device.
-
- Expected results:
- * success: The test will pass if the SNMP contact matches the provided input.
- * failure: The test will fail if the SNMP contact does not match the provided input.
+ """Verifies the SNMP contact of a device.
+
+ Expected Results
+ ----------------
+ * Success: The test will pass if the SNMP contact matches the provided input.
+ * Failure: The test will fail if the SNMP contact does not match the provided input.
+
+ Examples
+ --------
+ ```yaml
+ anta.tests.snmp:
+ - VerifySnmpContact:
+ contact: Jon@example.com
+ ```
"""
name = "VerifySnmpContact"
description = "Verifies the SNMP contact of a device."
- categories = ["snmp"]
- commands = [AntaCommand(command="show snmp")]
+ categories: ClassVar[list[str]] = ["snmp"]
+ commands: ClassVar[list[AntaCommand | AntaTemplate]] = [AntaCommand(command="show snmp", revision=1)]
class Input(AntaTest.Input):
- """Defines the input parameters for this test case."""
+ """Input model for the VerifySnmpContact test."""
contact: str
"""Expected SNMP contact details of the device."""
@AntaTest.anta_test
def test(self) -> None:
+ """Main test function for VerifySnmpContact."""
contact = self.instance_commands[0].json_output["contact"]["contact"]
if contact != self.inputs.contact:
diff --git a/anta/tests/software.py b/anta/tests/software.py
index a75efc5..4028dd9 100644
--- a/anta/tests/software.py
+++ b/anta/tests/software.py
@@ -1,35 +1,53 @@
# Copyright (c) 2023-2024 Arista Networks, Inc.
# Use of this source code is governed by the Apache License 2.0
# that can be found in the LICENSE file.
-"""
-Test functions related to the EOS software
-"""
+"""Module related to the EOS software tests."""
+
# Mypy does not understand AntaTest.Input typing
# mypy: disable-error-code=attr-defined
from __future__ import annotations
-# Need to keep List for pydantic in python 3.8
-from typing import List
+from typing import TYPE_CHECKING, ClassVar
from anta.models import AntaCommand, AntaTest
+if TYPE_CHECKING:
+ from anta.models import AntaTemplate
+
class VerifyEOSVersion(AntaTest):
- """
- Verifies the device is running one of the allowed EOS version.
+ """Verifies that the device is running one of the allowed EOS version.
+
+ Expected Results
+ ----------------
+ * Success: The test will pass if the device is running one of the allowed EOS version.
+ * Failure: The test will fail if the device is not running one of the allowed EOS version.
+
+ Examples
+ --------
+ ```yaml
+ anta.tests.software:
+ - VerifyEOSVersion:
+ versions:
+ - 4.25.4M
+ - 4.26.1F
+ ```
"""
name = "VerifyEOSVersion"
- description = "Verifies the device is running one of the allowed EOS version."
- categories = ["software"]
- commands = [AntaCommand(command="show version")]
+ description = "Verifies the EOS version of the device."
+ categories: ClassVar[list[str]] = ["software"]
+ commands: ClassVar[list[AntaCommand | AntaTemplate]] = [AntaCommand(command="show version", revision=1)]
+
+ class Input(AntaTest.Input):
+ """Input model for the VerifyEOSVersion test."""
- class Input(AntaTest.Input): # pylint: disable=missing-class-docstring
- versions: List[str]
- """List of allowed EOS versions"""
+ versions: list[str]
+ """List of allowed EOS versions."""
@AntaTest.anta_test
def test(self) -> None:
+ """Main test function for VerifyEOSVersion."""
command_output = self.instance_commands[0].json_output
if command_output["version"] in self.inputs.versions:
self.result.is_success()
@@ -38,21 +56,38 @@ class VerifyEOSVersion(AntaTest):
class VerifyTerminAttrVersion(AntaTest):
- """
- Verifies the device is running one of the allowed TerminAttr version.
+ """Verifies that he device is running one of the allowed TerminAttr version.
+
+ Expected Results
+ ----------------
+ * Success: The test will pass if the device is running one of the allowed TerminAttr version.
+ * Failure: The test will fail if the device is not running one of the allowed TerminAttr version.
+
+ Examples
+ --------
+ ```yaml
+ anta.tests.software:
+ - VerifyTerminAttrVersion:
+ versions:
+ - v1.13.6
+ - v1.8.0
+ ```
"""
name = "VerifyTerminAttrVersion"
- description = "Verifies the device is running one of the allowed TerminAttr version."
- categories = ["software"]
- commands = [AntaCommand(command="show version detail")]
+ description = "Verifies the TerminAttr version of the device."
+ categories: ClassVar[list[str]] = ["software"]
+ commands: ClassVar[list[AntaCommand | AntaTemplate]] = [AntaCommand(command="show version detail", revision=1)]
+
+ class Input(AntaTest.Input):
+ """Input model for the VerifyTerminAttrVersion test."""
- class Input(AntaTest.Input): # pylint: disable=missing-class-docstring
- versions: List[str]
- """List of allowed TerminAttr versions"""
+ versions: list[str]
+ """List of allowed TerminAttr versions."""
@AntaTest.anta_test
def test(self) -> None:
+ """Main test function for VerifyTerminAttrVersion."""
command_output = self.instance_commands[0].json_output
command_output_data = command_output["details"]["packages"]["TerminAttr-core"]["version"]
if command_output_data in self.inputs.versions:
@@ -62,17 +97,32 @@ class VerifyTerminAttrVersion(AntaTest):
class VerifyEOSExtensions(AntaTest):
- """
- Verifies all EOS extensions installed on the device are enabled for boot persistence.
+ """Verifies that all EOS extensions installed on the device are enabled for boot persistence.
+
+ Expected Results
+ ----------------
+ * Success: The test will pass if all EOS extensions installed on the device are enabled for boot persistence.
+ * Failure: The test will fail if some EOS extensions installed on the device are not enabled for boot persistence.
+
+ Examples
+ --------
+ ```yaml
+ anta.tests.software:
+ - VerifyEOSExtensions:
+ ```
"""
name = "VerifyEOSExtensions"
- description = "Verifies all EOS extensions installed on the device are enabled for boot persistence."
- categories = ["software"]
- commands = [AntaCommand(command="show extensions"), AntaCommand(command="show boot-extensions")]
+ description = "Verifies that all EOS extensions installed on the device are enabled for boot persistence."
+ categories: ClassVar[list[str]] = ["software"]
+ commands: ClassVar[list[AntaCommand | AntaTemplate]] = [
+ AntaCommand(command="show extensions", revision=2),
+ AntaCommand(command="show boot-extensions", revision=1),
+ ]
@AntaTest.anta_test
def test(self) -> None:
+ """Main test function for VerifyEOSExtensions."""
boot_extensions = []
show_extensions_command_output = self.instance_commands[0].json_output
show_boot_extensions_command_output = self.instance_commands[1].json_output
@@ -80,9 +130,9 @@ class VerifyEOSExtensions(AntaTest):
extension for extension, extension_data in show_extensions_command_output["extensions"].items() if extension_data["status"] == "installed"
]
for extension in show_boot_extensions_command_output["extensions"]:
- extension = extension.strip("\n")
- if extension != "":
- boot_extensions.append(extension)
+ formatted_extension = extension.strip("\n")
+ if formatted_extension != "":
+ boot_extensions.append(formatted_extension)
installed_extensions.sort()
boot_extensions.sort()
if installed_extensions == boot_extensions:
diff --git a/anta/tests/stp.py b/anta/tests/stp.py
index 66f303b..7cbfc9c 100644
--- a/anta/tests/stp.py
+++ b/anta/tests/stp.py
@@ -1,52 +1,71 @@
# Copyright (c) 2023-2024 Arista Networks, Inc.
# Use of this source code is governed by the Apache License 2.0
# that can be found in the LICENSE file.
-"""
-Test functions related to various Spanning Tree Protocol (STP) settings
-"""
+"""Module related to various Spanning Tree Protocol (STP) tests."""
+
# Mypy does not understand AntaTest.Input typing
# mypy: disable-error-code=attr-defined
from __future__ import annotations
-# Need to keep List for pydantic in python 3.8
-from typing import List, Literal
+from typing import ClassVar, Literal
+
+from pydantic import Field
from anta.custom_types import Vlan
from anta.models import AntaCommand, AntaTemplate, AntaTest
-from anta.tools.get_value import get_value
+from anta.tools import get_value
class VerifySTPMode(AntaTest):
- """
- Verifies the configured STP mode for a provided list of VLAN(s).
-
- Expected Results:
- * success: The test will pass if the STP mode is configured properly in the specified VLAN(s).
- * failure: The test will fail if the STP mode is NOT configured properly for one or more specified VLAN(s).
+ """Verifies the configured STP mode for a provided list of VLAN(s).
+
+ Expected Results
+ ----------------
+ * Success: The test will pass if the STP mode is configured properly in the specified VLAN(s).
+ * Failure: The test will fail if the STP mode is NOT configured properly for one or more specified VLAN(s).
+
+ Examples
+ --------
+ ```yaml
+ anta.tests.stp:
+ - VerifySTPMode:
+ mode: rapidPvst
+ vlans:
+ - 10
+ - 20
+ ```
"""
name = "VerifySTPMode"
description = "Verifies the configured STP mode for a provided list of VLAN(s)."
- categories = ["stp"]
- commands = [AntaTemplate(template="show spanning-tree vlan {vlan}")]
+ categories: ClassVar[list[str]] = ["stp"]
+ commands: ClassVar[list[AntaCommand | AntaTemplate]] = [AntaTemplate(template="show spanning-tree vlan {vlan}", revision=1)]
+
+ class Input(AntaTest.Input):
+ """Input model for the VerifySTPMode test."""
- class Input(AntaTest.Input): # pylint: disable=missing-class-docstring
mode: Literal["mstp", "rstp", "rapidPvst"] = "mstp"
- """STP mode to verify"""
- vlans: List[Vlan]
- """List of VLAN on which to verify STP mode"""
+ """STP mode to verify. Supported values: mstp, rstp, rapidPvst. Defaults to mstp."""
+ vlans: list[Vlan]
+ """List of VLAN on which to verify STP mode."""
def render(self, template: AntaTemplate) -> list[AntaCommand]:
+ """Render the template for each VLAN in the input list."""
return [template.render(vlan=vlan) for vlan in self.inputs.vlans]
@AntaTest.anta_test
def test(self) -> None:
+ """Main test function for VerifySTPMode."""
not_configured = []
wrong_stp_mode = []
for command in self.instance_commands:
- if "vlan" in command.params:
- vlan_id = command.params["vlan"]
- if not (stp_mode := get_value(command.json_output, f"spanningTreeVlanInstances.{vlan_id}.spanningTreeVlanInstance.protocol")):
+ vlan_id = command.params.vlan
+ if not (
+ stp_mode := get_value(
+ command.json_output,
+ f"spanningTreeVlanInstances.{vlan_id}.spanningTreeVlanInstance.protocol",
+ )
+ ):
not_configured.append(vlan_id)
elif stp_mode != self.inputs.mode:
wrong_stp_mode.append(vlan_id)
@@ -59,21 +78,29 @@ class VerifySTPMode(AntaTest):
class VerifySTPBlockedPorts(AntaTest):
- """
- Verifies there is no STP blocked ports.
-
- Expected Results:
- * success: The test will pass if there are NO ports blocked by STP.
- * failure: The test will fail if there are ports blocked by STP.
+ """Verifies there is no STP blocked ports.
+
+ Expected Results
+ ----------------
+ * Success: The test will pass if there are NO ports blocked by STP.
+ * Failure: The test will fail if there are ports blocked by STP.
+
+ Examples
+ --------
+ ```yaml
+ anta.tests.stp:
+ - VerifySTPBlockedPorts:
+ ```
"""
name = "VerifySTPBlockedPorts"
description = "Verifies there is no STP blocked ports."
- categories = ["stp"]
- commands = [AntaCommand(command="show spanning-tree blockedports")]
+ categories: ClassVar[list[str]] = ["stp"]
+ commands: ClassVar[list[AntaCommand | AntaTemplate]] = [AntaCommand(command="show spanning-tree blockedports", revision=1)]
@AntaTest.anta_test
def test(self) -> None:
+ """Main test function for VerifySTPBlockedPorts."""
command_output = self.instance_commands[0].json_output
if not (stp_instances := command_output["spanningTreeInstances"]):
self.result.is_success()
@@ -84,21 +111,29 @@ class VerifySTPBlockedPorts(AntaTest):
class VerifySTPCounters(AntaTest):
- """
- Verifies there is no errors in STP BPDU packets.
-
- Expected Results:
- * success: The test will pass if there are NO STP BPDU packet errors under all interfaces participating in STP.
- * failure: The test will fail if there are STP BPDU packet errors on one or many interface(s).
+ """Verifies there is no errors in STP BPDU packets.
+
+ Expected Results
+ ----------------
+ * Success: The test will pass if there are NO STP BPDU packet errors under all interfaces participating in STP.
+ * Failure: The test will fail if there are STP BPDU packet errors on one or many interface(s).
+
+ Examples
+ --------
+ ```yaml
+ anta.tests.stp:
+ - VerifySTPCounters:
+ ```
"""
name = "VerifySTPCounters"
description = "Verifies there is no errors in STP BPDU packets."
- categories = ["stp"]
- commands = [AntaCommand(command="show spanning-tree counters")]
+ categories: ClassVar[list[str]] = ["stp"]
+ commands: ClassVar[list[AntaCommand | AntaTemplate]] = [AntaCommand(command="show spanning-tree counters", revision=1)]
@AntaTest.anta_test
def test(self) -> None:
+ """Main test function for VerifySTPCounters."""
command_output = self.instance_commands[0].json_output
interfaces_with_errors = [
interface for interface, counters in command_output["interfaces"].items() if counters["bpduTaggedError"] or counters["bpduOtherError"] != 0
@@ -110,77 +145,105 @@ class VerifySTPCounters(AntaTest):
class VerifySTPForwardingPorts(AntaTest):
- """
- Verifies that all interfaces are in a forwarding state for a provided list of VLAN(s).
-
- Expected Results:
- * success: The test will pass if all interfaces are in a forwarding state for the specified VLAN(s).
- * failure: The test will fail if one or many interfaces are NOT in a forwarding state in the specified VLAN(s).
+ """Verifies that all interfaces are in a forwarding state for a provided list of VLAN(s).
+
+ Expected Results
+ ----------------
+ * Success: The test will pass if all interfaces are in a forwarding state for the specified VLAN(s).
+ * Failure: The test will fail if one or many interfaces are NOT in a forwarding state in the specified VLAN(s).
+
+ Examples
+ --------
+ ```yaml
+ anta.tests.stp:
+ - VerifySTPForwardingPorts:
+ vlans:
+ - 10
+ - 20
+ ```
"""
name = "VerifySTPForwardingPorts"
description = "Verifies that all interfaces are forwarding for a provided list of VLAN(s)."
- categories = ["stp"]
- commands = [AntaTemplate(template="show spanning-tree topology vlan {vlan} status")]
+ categories: ClassVar[list[str]] = ["stp"]
+ commands: ClassVar[list[AntaCommand | AntaTemplate]] = [AntaTemplate(template="show spanning-tree topology vlan {vlan} status", revision=1)]
+
+ class Input(AntaTest.Input):
+ """Input model for the VerifySTPForwardingPorts test."""
- class Input(AntaTest.Input): # pylint: disable=missing-class-docstring
- vlans: List[Vlan]
- """List of VLAN on which to verify forwarding states"""
+ vlans: list[Vlan]
+ """List of VLAN on which to verify forwarding states."""
def render(self, template: AntaTemplate) -> list[AntaCommand]:
+ """Render the template for each VLAN in the input list."""
return [template.render(vlan=vlan) for vlan in self.inputs.vlans]
@AntaTest.anta_test
def test(self) -> None:
+ """Main test function for VerifySTPForwardingPorts."""
not_configured = []
not_forwarding = []
for command in self.instance_commands:
- if "vlan" in command.params:
- vlan_id = command.params["vlan"]
+ vlan_id = command.params.vlan
if not (topologies := get_value(command.json_output, "topologies")):
not_configured.append(vlan_id)
else:
+ interfaces_not_forwarding = []
for value in topologies.values():
- if int(vlan_id) in value["vlans"]:
+ if vlan_id and int(vlan_id) in value["vlans"]:
interfaces_not_forwarding = [interface for interface, state in value["interfaces"].items() if state["state"] != "forwarding"]
if interfaces_not_forwarding:
not_forwarding.append({f"VLAN {vlan_id}": interfaces_not_forwarding})
if not_configured:
self.result.is_failure(f"STP instance is not configured for the following VLAN(s): {not_configured}")
if not_forwarding:
- self.result.is_failure(f"The following VLAN(s) have interface(s) that are not in a fowarding state: {not_forwarding}")
+ self.result.is_failure(f"The following VLAN(s) have interface(s) that are not in a forwarding state: {not_forwarding}")
if not not_configured and not interfaces_not_forwarding:
self.result.is_success()
class VerifySTPRootPriority(AntaTest):
- """
- Verifies the STP root priority for a provided list of VLAN or MST instance ID(s).
-
- Expected Results:
- * success: The test will pass if the STP root priority is configured properly for the specified VLAN or MST instance ID(s).
- * failure: The test will fail if the STP root priority is NOT configured properly for the specified VLAN or MST instance ID(s).
+ """Verifies the STP root priority for a provided list of VLAN or MST instance ID(s).
+
+ Expected Results
+ ----------------
+ * Success: The test will pass if the STP root priority is configured properly for the specified VLAN or MST instance ID(s).
+ * Failure: The test will fail if the STP root priority is NOT configured properly for the specified VLAN or MST instance ID(s).
+
+ Examples
+ --------
+ ```yaml
+ anta.tests.stp:
+ - VerifySTPRootPriority:
+ priority: 32768
+ instances:
+ - 10
+ - 20
+ ```
"""
name = "VerifySTPRootPriority"
description = "Verifies the STP root priority for a provided list of VLAN or MST instance ID(s)."
- categories = ["stp"]
- commands = [AntaCommand(command="show spanning-tree root detail")]
+ categories: ClassVar[list[str]] = ["stp"]
+ commands: ClassVar[list[AntaCommand | AntaTemplate]] = [AntaCommand(command="show spanning-tree root detail", revision=1)]
+
+ class Input(AntaTest.Input):
+ """Input model for the VerifySTPRootPriority test."""
- class Input(AntaTest.Input): # pylint: disable=missing-class-docstring
priority: int
- """STP root priority to verify"""
- instances: List[Vlan] = []
+ """STP root priority to verify."""
+ instances: list[Vlan] = Field(default=[])
"""List of VLAN or MST instance ID(s). If empty, ALL VLAN or MST instance ID(s) will be verified."""
@AntaTest.anta_test
def test(self) -> None:
+ """Main test function for VerifySTPRootPriority."""
command_output = self.instance_commands[0].json_output
if not (stp_instances := command_output["instances"]):
self.result.is_failure("No STP instances configured")
return
# Checking the type of instances based on first instance
- first_name = list(stp_instances)[0]
+ first_name = next(iter(stp_instances))
if first_name.startswith("MST"):
prefix = "MST"
elif first_name.startswith("VL"):
diff --git a/anta/tests/stun.py b/anta/tests/stun.py
new file mode 100644
index 0000000..a8e8d9e
--- /dev/null
+++ b/anta/tests/stun.py
@@ -0,0 +1,117 @@
+# Copyright (c) 2023-2024 Arista Networks, Inc.
+# Use of this source code is governed by the Apache License 2.0
+# that can be found in the LICENSE file.
+"""Test functions related to various STUN settings."""
+
+# Mypy does not understand AntaTest.Input typing
+# mypy: disable-error-code=attr-defined
+from __future__ import annotations
+
+from ipaddress import IPv4Address
+from typing import ClassVar
+
+from pydantic import BaseModel
+
+from anta.custom_types import Port
+from anta.models import AntaCommand, AntaTemplate, AntaTest
+from anta.tools import get_failed_logs, get_value
+
+
+class VerifyStunClient(AntaTest):
+ """
+ Verifies the configuration of the STUN client, specifically the IPv4 source address and port.
+
+ Optionally, it can also verify the public address and port.
+
+ Expected Results
+ ----------------
+ * Success: The test will pass if the STUN client is correctly configured with the specified IPv4 source address/port and public address/port.
+ * Failure: The test will fail if the STUN client is not configured or if the IPv4 source address, public address, or port details are incorrect.
+
+ Examples
+ --------
+ ```yaml
+ anta.tests.stun:
+ - VerifyStunClient:
+ stun_clients:
+ - source_address: 172.18.3.2
+ public_address: 172.18.3.21
+ source_port: 4500
+ public_port: 6006
+ - source_address: 100.64.3.2
+ public_address: 100.64.3.21
+ source_port: 4500
+ public_port: 6006
+ ```
+ """
+
+ name = "VerifyStunClient"
+ description = "Verifies the STUN client is configured with the specified IPv4 source address and port. Validate the public IP and port if provided."
+ categories: ClassVar[list[str]] = ["stun"]
+ commands: ClassVar[list[AntaCommand | AntaTemplate]] = [AntaTemplate(template="show stun client translations {source_address} {source_port}")]
+
+ class Input(AntaTest.Input):
+ """Input model for the VerifyStunClient test."""
+
+ stun_clients: list[ClientAddress]
+
+ class ClientAddress(BaseModel):
+ """Source and public address/port details of STUN client."""
+
+ source_address: IPv4Address
+ """IPv4 source address of STUN client."""
+ source_port: Port = 4500
+ """Source port number for STUN client."""
+ public_address: IPv4Address | None = None
+ """Optional IPv4 public address of STUN client."""
+ public_port: Port | None = None
+ """Optional public port number for STUN client."""
+
+ def render(self, template: AntaTemplate) -> list[AntaCommand]:
+ """Render the template for each STUN translation."""
+ return [template.render(source_address=client.source_address, source_port=client.source_port) for client in self.inputs.stun_clients]
+
+ @AntaTest.anta_test
+ def test(self) -> None:
+ """Main test function for VerifyStunClient."""
+ self.result.is_success()
+
+ # Iterate over each command output and corresponding client input
+ for command, client_input in zip(self.instance_commands, self.inputs.stun_clients):
+ bindings = command.json_output["bindings"]
+ source_address = str(command.params.source_address)
+ source_port = command.params.source_port
+
+ # If no bindings are found for the STUN client, mark the test as a failure and continue with the next client
+ if not bindings:
+ self.result.is_failure(f"STUN client transaction for source `{source_address}:{source_port}` is not found.")
+ continue
+
+ # Extract the public address and port from the client input
+ public_address = client_input.public_address
+ public_port = client_input.public_port
+
+ # Extract the transaction ID from the bindings
+ transaction_id = next(iter(bindings.keys()))
+
+ # Prepare the actual and expected STUN data for comparison
+ actual_stun_data = {
+ "source ip": get_value(bindings, f"{transaction_id}.sourceAddress.ip"),
+ "source port": get_value(bindings, f"{transaction_id}.sourceAddress.port"),
+ }
+ expected_stun_data = {"source ip": source_address, "source port": source_port}
+
+ # If public address is provided, add it to the actual and expected STUN data
+ if public_address is not None:
+ actual_stun_data["public ip"] = get_value(bindings, f"{transaction_id}.publicAddress.ip")
+ expected_stun_data["public ip"] = str(public_address)
+
+ # If public port is provided, add it to the actual and expected STUN data
+ if public_port is not None:
+ actual_stun_data["public port"] = get_value(bindings, f"{transaction_id}.publicAddress.port")
+ expected_stun_data["public port"] = public_port
+
+ # If the actual STUN data does not match the expected STUN data, mark the test as failure
+ if actual_stun_data != expected_stun_data:
+ failed_log = get_failed_logs(expected_stun_data, actual_stun_data)
+ self.result.is_failure(f"For STUN source `{source_address}:{source_port}`:{failed_log}")
diff --git a/anta/tests/system.py b/anta/tests/system.py
index 02ba09e..49d2dd2 100644
--- a/anta/tests/system.py
+++ b/anta/tests/system.py
@@ -1,40 +1,57 @@
# Copyright (c) 2023-2024 Arista Networks, Inc.
# Use of this source code is governed by the Apache License 2.0
# that can be found in the LICENSE file.
-"""
-Test functions related to system-level features and protocols
-"""
+"""Module related to system-level features and protocols tests."""
+
# Mypy does not understand AntaTest.Input typing
# mypy: disable-error-code=attr-defined
from __future__ import annotations
import re
+from typing import TYPE_CHECKING, ClassVar
-from pydantic import conint
-
+from anta.custom_types import PositiveInteger
from anta.models import AntaCommand, AntaTest
+if TYPE_CHECKING:
+ from anta.models import AntaTemplate
+
+CPU_IDLE_THRESHOLD = 25
+MEMORY_THRESHOLD = 0.25
+DISK_SPACE_THRESHOLD = 75
-class VerifyUptime(AntaTest):
- """
- This test verifies if the device uptime is higher than the provided minimum uptime value.
- Expected Results:
- * success: The test will pass if the device uptime is higher than the provided value.
- * failure: The test will fail if the device uptime is lower than the provided value.
+class VerifyUptime(AntaTest):
+ """Verifies if the device uptime is higher than the provided minimum uptime value.
+
+ Expected Results
+ ----------------
+ * Success: The test will pass if the device uptime is higher than the provided value.
+ * Failure: The test will fail if the device uptime is lower than the provided value.
+
+ Examples
+ --------
+ ```yaml
+ anta.tests.system:
+ - VerifyUptime:
+ minimum: 86400
+ ```
"""
name = "VerifyUptime"
description = "Verifies the device uptime."
- categories = ["system"]
- commands = [AntaCommand(command="show uptime")]
+ categories: ClassVar[list[str]] = ["system"]
+ commands: ClassVar[list[AntaCommand | AntaTemplate]] = [AntaCommand(command="show uptime", revision=1)]
- class Input(AntaTest.Input): # pylint: disable=missing-class-docstring
- minimum: conint(ge=0) # type: ignore
- """Minimum uptime in seconds"""
+ class Input(AntaTest.Input):
+ """Input model for the VerifyUptime test."""
+
+ minimum: PositiveInteger
+ """Minimum uptime in seconds."""
@AntaTest.anta_test
def test(self) -> None:
+ """Main test function for VerifyUptime."""
command_output = self.instance_commands[0].json_output
if command_output["upTime"] > self.inputs.minimum:
self.result.is_success()
@@ -43,24 +60,32 @@ class VerifyUptime(AntaTest):
class VerifyReloadCause(AntaTest):
- """
- This test verifies the last reload cause of the device.
-
- Expected results:
- * success: The test will pass if there are NO reload causes or if the last reload was caused by the user or after an FPGA upgrade.
- * failure: The test will fail if the last reload was NOT caused by the user or after an FPGA upgrade.
- * error: The test will report an error if the reload cause is NOT available.
+ """Verifies the last reload cause of the device.
+
+ Expected Results
+ ----------------
+ * Success: The test will pass if there are NO reload causes or if the last reload was caused by the user or after an FPGA upgrade.
+ * Failure: The test will fail if the last reload was NOT caused by the user or after an FPGA upgrade.
+ * Error: The test will report an error if the reload cause is NOT available.
+
+ Examples
+ --------
+ ```yaml
+ anta.tests.system:
+ - VerifyReloadCause:
+ ```
"""
name = "VerifyReloadCause"
description = "Verifies the last reload cause of the device."
- categories = ["system"]
- commands = [AntaCommand(command="show reload cause")]
+ categories: ClassVar[list[str]] = ["system"]
+ commands: ClassVar[list[AntaCommand | AntaTemplate]] = [AntaCommand(command="show reload cause", revision=1)]
@AntaTest.anta_test
def test(self) -> None:
+ """Main test function for VerifyReloadCause."""
command_output = self.instance_commands[0].json_output
- if "resetCauses" not in command_output.keys():
+ if "resetCauses" not in command_output:
self.result.is_error(message="No reload causes available")
return
if len(command_output["resetCauses"]) == 0:
@@ -79,24 +104,33 @@ class VerifyReloadCause(AntaTest):
class VerifyCoredump(AntaTest):
- """
- This test verifies if there are core dump files in the /var/core directory.
-
- Expected Results:
- * success: The test will pass if there are NO core dump(s) in /var/core.
- * failure: The test will fail if there are core dump(s) in /var/core.
-
- Note:
- * This test will NOT check for minidump(s) generated by certain agents in /var/core/minidump.
+ """Verifies if there are core dump files in the /var/core directory.
+
+ Expected Results
+ ----------------
+ * Success: The test will pass if there are NO core dump(s) in /var/core.
+ * Failure: The test will fail if there are core dump(s) in /var/core.
+
+ Info
+ ----
+ * This test will NOT check for minidump(s) generated by certain agents in /var/core/minidump.
+
+ Examples
+ --------
+ ```yaml
+ anta.tests.system:
+ - VerifyCoreDump:
+ ```
"""
name = "VerifyCoredump"
description = "Verifies there are no core dump files."
- categories = ["system"]
- commands = [AntaCommand(command="show system coredump", ofmt="json")]
+ categories: ClassVar[list[str]] = ["system"]
+ commands: ClassVar[list[AntaCommand | AntaTemplate]] = [AntaCommand(command="show system coredump", revision=1)]
@AntaTest.anta_test
def test(self) -> None:
+ """Main test function for VerifyCoredump."""
command_output = self.instance_commands[0].json_output
core_files = command_output["coreFiles"]
if "minidump" in core_files:
@@ -108,21 +142,29 @@ class VerifyCoredump(AntaTest):
class VerifyAgentLogs(AntaTest):
- """
- This test verifies that no agent crash reports are present on the device.
-
- Expected Results:
- * success: The test will pass if there is NO agent crash reported.
- * failure: The test will fail if any agent crashes are reported.
+ """Verifies that no agent crash reports are present on the device.
+
+ Expected Results
+ ----------------
+ * Success: The test will pass if there is NO agent crash reported.
+ * Failure: The test will fail if any agent crashes are reported.
+
+ Examples
+ --------
+ ```yaml
+ anta.tests.system:
+ - VerifyAgentLogs:
+ ```
"""
name = "VerifyAgentLogs"
description = "Verifies there are no agent crash reports."
- categories = ["system"]
- commands = [AntaCommand(command="show agent logs crash", ofmt="text")]
+ categories: ClassVar[list[str]] = ["system"]
+ commands: ClassVar[list[AntaCommand | AntaTemplate]] = [AntaCommand(command="show agent logs crash", ofmt="text")]
@AntaTest.anta_test
def test(self) -> None:
+ """Main test function for VerifyAgentLogs."""
command_output = self.instance_commands[0].text_output
if len(command_output) == 0:
self.result.is_success()
@@ -133,92 +175,124 @@ class VerifyAgentLogs(AntaTest):
class VerifyCPUUtilization(AntaTest):
- """
- This test verifies whether the CPU utilization is below 75%.
-
- Expected Results:
- * success: The test will pass if the CPU utilization is below 75%.
- * failure: The test will fail if the CPU utilization is over 75%.
+ """Verifies whether the CPU utilization is below 75%.
+
+ Expected Results
+ ----------------
+ * Success: The test will pass if the CPU utilization is below 75%.
+ * Failure: The test will fail if the CPU utilization is over 75%.
+
+ Examples
+ --------
+ ```yaml
+ anta.tests.system:
+ - VerifyCPUUtilization:
+ ```
"""
name = "VerifyCPUUtilization"
description = "Verifies whether the CPU utilization is below 75%."
- categories = ["system"]
- commands = [AntaCommand(command="show processes top once")]
+ categories: ClassVar[list[str]] = ["system"]
+ commands: ClassVar[list[AntaCommand | AntaTemplate]] = [AntaCommand(command="show processes top once", revision=1)]
@AntaTest.anta_test
def test(self) -> None:
+ """Main test function for VerifyCPUUtilization."""
command_output = self.instance_commands[0].json_output
command_output_data = command_output["cpuInfo"]["%Cpu(s)"]["idle"]
- if command_output_data > 25:
+ if command_output_data > CPU_IDLE_THRESHOLD:
self.result.is_success()
else:
self.result.is_failure(f"Device has reported a high CPU utilization: {100 - command_output_data}%")
class VerifyMemoryUtilization(AntaTest):
- """
- This test verifies whether the memory utilization is below 75%.
-
- Expected Results:
- * success: The test will pass if the memory utilization is below 75%.
- * failure: The test will fail if the memory utilization is over 75%.
+ """Verifies whether the memory utilization is below 75%.
+
+ Expected Results
+ ----------------
+ * Success: The test will pass if the memory utilization is below 75%.
+ * Failure: The test will fail if the memory utilization is over 75%.
+
+ Examples
+ --------
+ ```yaml
+ anta.tests.system:
+ - VerifyMemoryUtilization:
+ ```
"""
name = "VerifyMemoryUtilization"
description = "Verifies whether the memory utilization is below 75%."
- categories = ["system"]
- commands = [AntaCommand(command="show version")]
+ categories: ClassVar[list[str]] = ["system"]
+ commands: ClassVar[list[AntaCommand | AntaTemplate]] = [AntaCommand(command="show version", revision=1)]
@AntaTest.anta_test
def test(self) -> None:
+ """Main test function for VerifyMemoryUtilization."""
command_output = self.instance_commands[0].json_output
memory_usage = command_output["memFree"] / command_output["memTotal"]
- if memory_usage > 0.25:
+ if memory_usage > MEMORY_THRESHOLD:
self.result.is_success()
else:
self.result.is_failure(f"Device has reported a high memory usage: {(1 - memory_usage)*100:.2f}%")
class VerifyFileSystemUtilization(AntaTest):
- """
- This test verifies that no partition is utilizing more than 75% of its disk space.
-
- Expected Results:
- * success: The test will pass if all partitions are using less than 75% of its disk space.
- * failure: The test will fail if any partitions are using more than 75% of its disk space.
+ """Verifies that no partition is utilizing more than 75% of its disk space.
+
+ Expected Results
+ ----------------
+ * Success: The test will pass if all partitions are using less than 75% of its disk space.
+ * Failure: The test will fail if any partitions are using more than 75% of its disk space.
+
+ Examples
+ --------
+ ```yaml
+ anta.tests.system:
+ - VerifyFileSystemUtilization:
+ ```
"""
name = "VerifyFileSystemUtilization"
description = "Verifies that no partition is utilizing more than 75% of its disk space."
- categories = ["system"]
- commands = [AntaCommand(command="bash timeout 10 df -h", ofmt="text")]
+ categories: ClassVar[list[str]] = ["system"]
+ commands: ClassVar[list[AntaCommand | AntaTemplate]] = [AntaCommand(command="bash timeout 10 df -h", ofmt="text")]
@AntaTest.anta_test
def test(self) -> None:
+ """Main test function for VerifyFileSystemUtilization."""
command_output = self.instance_commands[0].text_output
self.result.is_success()
for line in command_output.split("\n")[1:]:
- if "loop" not in line and len(line) > 0 and (percentage := int(line.split()[4].replace("%", ""))) > 75:
+ if "loop" not in line and len(line) > 0 and (percentage := int(line.split()[4].replace("%", ""))) > DISK_SPACE_THRESHOLD:
self.result.is_failure(f"Mount point {line} is higher than 75%: reported {percentage}%")
class VerifyNTP(AntaTest):
- """
- This test verifies that the Network Time Protocol (NTP) is synchronized.
-
- Expected Results:
- * success: The test will pass if the NTP is synchronised.
- * failure: The test will fail if the NTP is NOT synchronised.
+ """Verifies that the Network Time Protocol (NTP) is synchronized.
+
+ Expected Results
+ ----------------
+ * Success: The test will pass if the NTP is synchronised.
+ * Failure: The test will fail if the NTP is NOT synchronised.
+
+ Examples
+ --------
+ ```yaml
+ anta.tests.system:
+ - VerifyNTP:
+ ```
"""
name = "VerifyNTP"
description = "Verifies if NTP is synchronised."
- categories = ["system"]
- commands = [AntaCommand(command="show ntp status", ofmt="text")]
+ categories: ClassVar[list[str]] = ["system"]
+ commands: ClassVar[list[AntaCommand | AntaTemplate]] = [AntaCommand(command="show ntp status", ofmt="text")]
@AntaTest.anta_test
def test(self) -> None:
+ """Main test function for VerifyNTP."""
command_output = self.instance_commands[0].text_output
if command_output.split("\n")[0].split(" ")[0] == "synchronised":
self.result.is_success()
diff --git a/anta/tests/vlan.py b/anta/tests/vlan.py
index 58c28b6..fdf91d8 100644
--- a/anta/tests/vlan.py
+++ b/anta/tests/vlan.py
@@ -1,42 +1,53 @@
# Copyright (c) 2023-2024 Arista Networks, Inc.
# Use of this source code is governed by the Apache License 2.0
# that can be found in the LICENSE file.
-"""
-Test functions related to VLAN
-"""
+"""Module related to VLAN tests."""
+
# Mypy does not understand AntaTest.Input typing
# mypy: disable-error-code=attr-defined
+from __future__ import annotations
-from typing import Literal
+from typing import TYPE_CHECKING, ClassVar, Literal
from anta.custom_types import Vlan
from anta.models import AntaCommand, AntaTest
-from anta.tools.get_value import get_value
-from anta.tools.utils import get_failed_logs
+from anta.tools import get_failed_logs, get_value
+
+if TYPE_CHECKING:
+ from anta.models import AntaTemplate
class VerifyVlanInternalPolicy(AntaTest):
- """
- This class checks if the VLAN internal allocation policy is ascending or descending and
- if the VLANs are within the specified range.
+ """Verifies if the VLAN internal allocation policy is ascending or descending and if the VLANs are within the specified range.
- Expected Results:
- * Success: The test will pass if the VLAN internal allocation policy is either ascending or descending
+ Expected Results
+ ----------------
+ * Success: The test will pass if the VLAN internal allocation policy is either ascending or descending
and the VLANs are within the specified range.
- * Failure: The test will fail if the VLAN internal allocation policy is neither ascending nor descending
+ * Failure: The test will fail if the VLAN internal allocation policy is neither ascending nor descending
or the VLANs are outside the specified range.
+
+ Examples
+ --------
+ ```yaml
+ anta.tests.vlan:
+ - VerifyVlanInternalPolicy:
+ policy: ascending
+ start_vlan_id: 1006
+ end_vlan_id: 4094
+ ```
"""
name = "VerifyVlanInternalPolicy"
- description = "This test checks the VLAN internal allocation policy and the range of VLANs."
- categories = ["vlan"]
- commands = [AntaCommand(command="show vlan internal allocation policy")]
+ description = "Verifies the VLAN internal allocation policy and the range of VLANs."
+ categories: ClassVar[list[str]] = ["vlan"]
+ commands: ClassVar[list[AntaCommand | AntaTemplate]] = [AntaCommand(command="show vlan internal allocation policy", revision=1)]
class Input(AntaTest.Input):
- """Inputs for the VerifyVlanInternalPolicy test."""
+ """Input model for the VerifyVlanInternalPolicy test."""
policy: Literal["ascending", "descending"]
- """The VLAN internal allocation policy."""
+ """The VLAN internal allocation policy. Supported values: ascending, descending."""
start_vlan_id: Vlan
"""The starting VLAN ID in the range."""
end_vlan_id: Vlan
@@ -44,6 +55,7 @@ class VerifyVlanInternalPolicy(AntaTest):
@AntaTest.anta_test
def test(self) -> None:
+ """Main test function for VerifyVlanInternalPolicy."""
command_output = self.instance_commands[0].json_output
keys_to_verify = ["policy", "startVlanId", "endVlanId"]
diff --git a/anta/tests/vxlan.py b/anta/tests/vxlan.py
index e763b8f..fe53816 100644
--- a/anta/tests/vxlan.py
+++ b/anta/tests/vxlan.py
@@ -1,44 +1,54 @@
# Copyright (c) 2023-2024 Arista Networks, Inc.
# Use of this source code is governed by the Apache License 2.0
# that can be found in the LICENSE file.
-"""
-Test functions related to VXLAN
-"""
+"""Module related to VXLAN tests."""
+
# Mypy does not understand AntaTest.Input typing
# mypy: disable-error-code=attr-defined
+from __future__ import annotations
from ipaddress import IPv4Address
-
-# Need to keep List and Dict for pydantic in python 3.8
-from typing import Dict, List
+from typing import TYPE_CHECKING, ClassVar
from pydantic import Field
from anta.custom_types import Vlan, Vni, VxlanSrcIntf
from anta.models import AntaCommand, AntaTest
-from anta.tools.get_value import get_value
-
+from anta.tools import get_value
-class VerifyVxlan1Interface(AntaTest):
- """
- This test verifies if the Vxlan1 interface is configured and 'up/up'.
+if TYPE_CHECKING:
+ from anta.models import AntaTemplate
- !!! warning
- The name of this test has been updated from 'VerifyVxlan' for better representation.
- Expected Results:
- * success: The test will pass if the Vxlan1 interface is configured with line protocol status and interface status 'up'.
- * failure: The test will fail if the Vxlan1 interface line protocol status or interface status are not 'up'.
- * skipped: The test will be skipped if the Vxlan1 interface is not configured.
+class VerifyVxlan1Interface(AntaTest):
+ """Verifies if the Vxlan1 interface is configured and 'up/up'.
+
+ Warning
+ -------
+ The name of this test has been updated from 'VerifyVxlan' for better representation.
+
+ Expected Results
+ ----------------
+ * Success: The test will pass if the Vxlan1 interface is configured with line protocol status and interface status 'up'.
+ * Failure: The test will fail if the Vxlan1 interface line protocol status or interface status are not 'up'.
+ * Skipped: The test will be skipped if the Vxlan1 interface is not configured.
+
+ Examples
+ --------
+ ```yaml
+ anta.tests.vxlan:
+ - VerifyVxlan1Interface:
+ ```
"""
name = "VerifyVxlan1Interface"
description = "Verifies the Vxlan1 interface status."
- categories = ["vxlan"]
- commands = [AntaCommand(command="show interfaces description", ofmt="json")]
+ categories: ClassVar[list[str]] = ["vxlan"]
+ commands: ClassVar[list[AntaCommand | AntaTemplate]] = [AntaCommand(command="show interfaces description", revision=1)]
@AntaTest.anta_test
def test(self) -> None:
+ """Main test function for VerifyVxlan1Interface."""
command_output = self.instance_commands[0].json_output
if "Vxlan1" not in command_output["interfaceDescriptions"]:
self.result.is_skipped("Vxlan1 interface is not configured")
@@ -50,27 +60,35 @@ class VerifyVxlan1Interface(AntaTest):
else:
self.result.is_failure(
f"Vxlan1 interface is {command_output['interfaceDescriptions']['Vxlan1']['lineProtocolStatus']}"
- f"/{command_output['interfaceDescriptions']['Vxlan1']['interfaceStatus']}"
+ f"/{command_output['interfaceDescriptions']['Vxlan1']['interfaceStatus']}",
)
class VerifyVxlanConfigSanity(AntaTest):
- """
- This test verifies that no issues are detected with the VXLAN configuration.
-
- Expected Results:
- * success: The test will pass if no issues are detected with the VXLAN configuration.
- * failure: The test will fail if issues are detected with the VXLAN configuration.
- * skipped: The test will be skipped if VXLAN is not configured on the device.
+ """Verifies that no issues are detected with the VXLAN configuration.
+
+ Expected Results
+ ----------------
+ * Success: The test will pass if no issues are detected with the VXLAN configuration.
+ * Failure: The test will fail if issues are detected with the VXLAN configuration.
+ * Skipped: The test will be skipped if VXLAN is not configured on the device.
+
+ Examples
+ --------
+ ```yaml
+ anta.tests.vxlan:
+ - VerifyVxlanConfigSanity:
+ ```
"""
name = "VerifyVxlanConfigSanity"
description = "Verifies there are no VXLAN config-sanity inconsistencies."
- categories = ["vxlan"]
- commands = [AntaCommand(command="show vxlan config-sanity", ofmt="json")]
+ categories: ClassVar[list[str]] = ["vxlan"]
+ commands: ClassVar[list[AntaCommand | AntaTemplate]] = [AntaCommand(command="show vxlan config-sanity", revision=1)]
@AntaTest.anta_test
def test(self) -> None:
+ """Main test function for VerifyVxlanConfigSanity."""
command_output = self.instance_commands[0].json_output
if "categories" not in command_output or len(command_output["categories"]) == 0:
self.result.is_skipped("VXLAN is not configured")
@@ -87,26 +105,39 @@ class VerifyVxlanConfigSanity(AntaTest):
class VerifyVxlanVniBinding(AntaTest):
- """
- This test verifies the VNI-VLAN bindings of the Vxlan1 interface.
-
- Expected Results:
- * success: The test will pass if the VNI-VLAN bindings provided are properly configured.
- * failure: The test will fail if any VNI lacks bindings or if any bindings are incorrect.
- * skipped: The test will be skipped if the Vxlan1 interface is not configured.
+ """Verifies the VNI-VLAN bindings of the Vxlan1 interface.
+
+ Expected Results
+ ----------------
+ * Success: The test will pass if the VNI-VLAN bindings provided are properly configured.
+ * Failure: The test will fail if any VNI lacks bindings or if any bindings are incorrect.
+ * Skipped: The test will be skipped if the Vxlan1 interface is not configured.
+
+ Examples
+ --------
+ ```yaml
+ anta.tests.vxlan:
+ - VerifyVxlanVniBinding:
+ bindings:
+ 10010: 10
+ 10020: 20
+ ```
"""
name = "VerifyVxlanVniBinding"
description = "Verifies the VNI-VLAN bindings of the Vxlan1 interface."
- categories = ["vxlan"]
- commands = [AntaCommand(command="show vxlan vni", ofmt="json")]
+ categories: ClassVar[list[str]] = ["vxlan"]
+ commands: ClassVar[list[AntaCommand | AntaTemplate]] = [AntaCommand(command="show vxlan vni", revision=1)]
+
+ class Input(AntaTest.Input):
+ """Input model for the VerifyVxlanVniBinding test."""
- class Input(AntaTest.Input): # pylint: disable=missing-class-docstring
- bindings: Dict[Vni, Vlan]
- """VNI to VLAN bindings to verify"""
+ bindings: dict[Vni, Vlan]
+ """VNI to VLAN bindings to verify."""
@AntaTest.anta_test
def test(self) -> None:
+ """Main test function for VerifyVxlanVniBinding."""
self.result.is_success()
no_binding = []
@@ -117,17 +148,17 @@ class VerifyVxlanVniBinding(AntaTest):
return
for vni, vlan in self.inputs.bindings.items():
- vni = str(vni)
- if vni in vxlan1["vniBindings"]:
- retrieved_vlan = vxlan1["vniBindings"][vni]["vlan"]
- elif vni in vxlan1["vniBindingsToVrf"]:
- retrieved_vlan = vxlan1["vniBindingsToVrf"][vni]["vlan"]
+ str_vni = str(vni)
+ if str_vni in vxlan1["vniBindings"]:
+ retrieved_vlan = vxlan1["vniBindings"][str_vni]["vlan"]
+ elif str_vni in vxlan1["vniBindingsToVrf"]:
+ retrieved_vlan = vxlan1["vniBindingsToVrf"][str_vni]["vlan"]
else:
- no_binding.append(vni)
+ no_binding.append(str_vni)
retrieved_vlan = None
if retrieved_vlan and vlan != retrieved_vlan:
- wrong_binding.append({vni: retrieved_vlan})
+ wrong_binding.append({str_vni: retrieved_vlan})
if no_binding:
self.result.is_failure(f"The following VNI(s) have no binding: {no_binding}")
@@ -137,26 +168,39 @@ class VerifyVxlanVniBinding(AntaTest):
class VerifyVxlanVtep(AntaTest):
- """
- This test verifies the VTEP peers of the Vxlan1 interface.
-
- Expected Results:
- * success: The test will pass if all provided VTEP peers are identified and matching.
- * failure: The test will fail if any VTEP peer is missing or there are unexpected VTEP peers.
- * skipped: The test will be skipped if the Vxlan1 interface is not configured.
+ """Verifies the VTEP peers of the Vxlan1 interface.
+
+ Expected Results
+ ----------------
+ * Success: The test will pass if all provided VTEP peers are identified and matching.
+ * Failure: The test will fail if any VTEP peer is missing or there are unexpected VTEP peers.
+ * Skipped: The test will be skipped if the Vxlan1 interface is not configured.
+
+ Examples
+ --------
+ ```yaml
+ anta.tests.vxlan:
+ - VerifyVxlanVtep:
+ vteps:
+ - 10.1.1.5
+ - 10.1.1.6
+ ```
"""
name = "VerifyVxlanVtep"
description = "Verifies the VTEP peers of the Vxlan1 interface"
- categories = ["vxlan"]
- commands = [AntaCommand(command="show vxlan vtep", ofmt="json")]
+ categories: ClassVar[list[str]] = ["vxlan"]
+ commands: ClassVar[list[AntaCommand | AntaTemplate]] = [AntaCommand(command="show vxlan vtep", revision=1)]
- class Input(AntaTest.Input): # pylint: disable=missing-class-docstring
- vteps: List[IPv4Address]
- """List of VTEP peers to verify"""
+ class Input(AntaTest.Input):
+ """Input model for the VerifyVxlanVtep test."""
+
+ vteps: list[IPv4Address]
+ """List of VTEP peers to verify."""
@AntaTest.anta_test
def test(self) -> None:
+ """Main test function for VerifyVxlanVtep."""
self.result.is_success()
inputs_vteps = [str(input_vtep) for input_vtep in self.inputs.vteps]
@@ -176,30 +220,40 @@ class VerifyVxlanVtep(AntaTest):
class VerifyVxlan1ConnSettings(AntaTest):
- """
- Verifies the interface vxlan1 source interface and UDP port.
-
- Expected Results:
- * success: Passes if the interface vxlan1 source interface and UDP port are correct.
- * failure: Fails if the interface vxlan1 source interface or UDP port are incorrect.
- * skipped: Skips if the Vxlan1 interface is not configured.
+ """Verifies the interface vxlan1 source interface and UDP port.
+
+ Expected Results
+ ----------------
+ * Success: Passes if the interface vxlan1 source interface and UDP port are correct.
+ * Failure: Fails if the interface vxlan1 source interface or UDP port are incorrect.
+ * Skipped: Skips if the Vxlan1 interface is not configured.
+
+ Examples
+ --------
+ ```yaml
+ anta.tests.vxlan:
+ - VerifyVxlan1ConnSettings:
+ source_interface: Loopback1
+ udp_port: 4789
+ ```
"""
name = "VerifyVxlan1ConnSettings"
description = "Verifies the interface vxlan1 source interface and UDP port."
- categories = ["vxlan"]
- commands = [AntaCommand(command="show interfaces")]
+ categories: ClassVar[list[str]] = ["vxlan"]
+ commands: ClassVar[list[AntaCommand | AntaTemplate]] = [AntaCommand(command="show interfaces", revision=1)]
class Input(AntaTest.Input):
- """Inputs for the VerifyVxlan1ConnSettings test."""
+ """Input model for the VerifyVxlan1ConnSettings test."""
source_interface: VxlanSrcIntf
- """Source loopback interface of vxlan1 interface"""
+ """Source loopback interface of vxlan1 interface."""
udp_port: int = Field(ge=1024, le=65335)
- """UDP port used for vxlan1 interface"""
+ """UDP port used for vxlan1 interface."""
@AntaTest.anta_test
def test(self) -> None:
+ """Main test function for VerifyVxlan1ConnSettings."""
self.result.is_success()
command_output = self.instance_commands[0].json_output
diff --git a/anta/tools.py b/anta/tools.py
new file mode 100644
index 0000000..b3760da
--- /dev/null
+++ b/anta/tools.py
@@ -0,0 +1,348 @@
+# Copyright (c) 2023-2024 Arista Networks, Inc.
+# Use of this source code is governed by the Apache License 2.0
+# that can be found in the LICENSE file.
+"""Common functions used in ANTA tests."""
+
+from __future__ import annotations
+
+import cProfile
+import os
+import pstats
+from functools import wraps
+from time import perf_counter
+from typing import TYPE_CHECKING, Any, Callable, TypeVar, cast
+
+from anta.logger import format_td
+
+if TYPE_CHECKING:
+ import sys
+ from logging import Logger
+ from types import TracebackType
+
+ if sys.version_info >= (3, 11):
+ from typing import Self
+ else:
+ from typing_extensions import Self
+
+F = TypeVar("F", bound=Callable[..., Any])
+
+
+def get_failed_logs(expected_output: dict[Any, Any], actual_output: dict[Any, Any]) -> str:
+ """Get the failed log for a test.
+
+ Returns the failed log or an empty string if there is no difference between the expected and actual output.
+
+ Args:
+ ----
+ expected_output (dict): Expected output of a test.
+ actual_output (dict): Actual output of a test
+
+ Returns
+ -------
+ str: Failed log of a test.
+
+ """
+ failed_logs = []
+
+ for element, expected_data in expected_output.items():
+ actual_data = actual_output.get(element)
+
+ if actual_data == expected_data:
+ continue
+ if actual_data is None:
+ failed_logs.append(f"\nExpected `{expected_data}` as the {element}, but it was not found in the actual output.")
+ continue
+ # actual_data != expected_data: and actual_data is not None
+ failed_logs.append(f"\nExpected `{expected_data}` as the {element}, but found `{actual_data}` instead.")
+
+ return "".join(failed_logs)
+
+
+def custom_division(numerator: float, denominator: float) -> int | float:
+ """Get the custom division of numbers.
+
+ Custom division that returns an integer if the result is an integer, otherwise a float.
+
+ Parameters
+ ----------
+ numerator: The numerator.
+ denominator: The denominator.
+
+ Returns
+ -------
+ Union[int, float]: The result of the division.
+ """
+ result = numerator / denominator
+ return int(result) if result.is_integer() else result
+
+
+# pylint: disable=too-many-arguments
+def get_dict_superset(
+ list_of_dicts: list[dict[Any, Any]],
+ input_dict: dict[Any, Any],
+ default: Any | None = None,
+ var_name: str | None = None,
+ custom_error_msg: str | None = None,
+ *,
+ required: bool = False,
+) -> Any:
+ """
+ Get the first dictionary from a list of dictionaries that is a superset of the input dict.
+
+ Returns the supplied default value or None if there is no match and "required" is False.
+
+ Will return the first matching item if there are multiple matching items.
+
+ Parameters
+ ----------
+ list_of_dicts: list(dict)
+ List of Dictionaries to get list items from
+ input_dict : dict
+ Dictionary to check subset with a list of dict
+ default: any
+ Default value returned if the key and value are not found
+ required: bool
+ Fail if there is no match
+ var_name : str
+ String used for raising an exception with the full variable name
+ custom_error_msg : str
+ Custom error message to raise when required is True and the value is not found
+
+ Returns
+ -------
+ any
+ Dict or default value
+
+ Raises
+ ------
+ ValueError
+ If the keys and values are not found and "required" == True
+
+ """
+ if not isinstance(list_of_dicts, list) or not list_of_dicts or not isinstance(input_dict, dict) or not input_dict:
+ if required:
+ error_msg = custom_error_msg or f"{var_name} not found in the provided list."
+ raise ValueError(error_msg)
+ return default
+
+ for list_item in list_of_dicts:
+ if isinstance(list_item, dict) and input_dict.items() <= list_item.items():
+ return list_item
+
+ if required:
+ error_msg = custom_error_msg or f"{var_name} not found in the provided list."
+ raise ValueError(error_msg)
+
+ return default
+
+
+# pylint: disable=too-many-arguments
+def get_value(
+ dictionary: dict[Any, Any],
+ key: str,
+ default: Any | None = None,
+ org_key: str | None = None,
+ separator: str = ".",
+ *,
+ required: bool = False,
+) -> Any:
+ """Get a value from a dictionary or nested dictionaries.
+
+ Key supports dot-notation like "foo.bar" to do deeper lookups.
+
+ Returns the supplied default value or None if the key is not found and required is False.
+
+ Parameters
+ ----------
+ dictionary : dict
+ Dictionary to get key from
+ key : str
+ Dictionary Key - supporting dot-notation for nested dictionaries
+ default : any
+ Default value returned if the key is not found
+ required : bool
+ Fail if the key is not found
+ org_key : str
+ Internal variable used for raising exception with the full key name even when called recursively
+ separator: str
+ String to use as the separator parameter in the split function. Useful in cases when the key
+ can contain variables with "." inside (e.g. hostnames)
+
+ Returns
+ -------
+ any
+ Value or default value
+
+ Raises
+ ------
+ ValueError
+ If the key is not found and required == True.
+
+ """
+ if org_key is None:
+ org_key = key
+ keys = key.split(separator)
+ value = dictionary.get(keys[0])
+ if value is None:
+ if required:
+ raise ValueError(org_key)
+ return default
+
+ if len(keys) > 1:
+ return get_value(value, separator.join(keys[1:]), default=default, required=required, org_key=org_key, separator=separator)
+ return value
+
+
+# pylint: disable=too-many-arguments
+def get_item(
+ list_of_dicts: list[dict[Any, Any]],
+ key: Any,
+ value: Any,
+ default: Any | None = None,
+ var_name: str | None = None,
+ custom_error_msg: str | None = None,
+ *,
+ required: bool = False,
+ case_sensitive: bool = False,
+) -> Any:
+ """Get one dictionary from a list of dictionaries by matching the given key and value.
+
+ Returns the supplied default value or None if there is no match and "required" is False.
+
+ Will return the first matching item if there are multiple matching items.
+
+ Parameters
+ ----------
+ list_of_dicts : list(dict)
+ List of Dictionaries to get list item from
+ key : any
+ Dictionary Key to match on
+ value : any
+ Value that must match
+ default : any
+ Default value returned if the key and value is not found
+ required : bool
+ Fail if there is no match
+ case_sensitive : bool
+ If the search value is a string, the comparison will ignore case by default
+ var_name : str
+ String used for raising exception with the full variable name
+ custom_error_msg : str
+ Custom error message to raise when required is True and the value is not found
+
+ Returns
+ -------
+ any
+ Dict or default value
+
+ Raises
+ ------
+ ValueError
+ If the key and value is not found and "required" == True
+
+ """
+ if var_name is None:
+ var_name = key
+
+ if (not isinstance(list_of_dicts, list)) or list_of_dicts == [] or value is None or key is None:
+ if required is True:
+ raise ValueError(custom_error_msg or var_name)
+ return default
+
+ for list_item in list_of_dicts:
+ if not isinstance(list_item, dict):
+ # List item is not a dict as required. Skip this item
+ continue
+
+ item_value = list_item.get(key)
+
+ # Perform case-insensitive comparison if value and item_value are strings and case_sensitive is False
+ if not case_sensitive and isinstance(value, str) and isinstance(item_value, str):
+ if item_value.casefold() == value.casefold():
+ return list_item
+ elif item_value == value:
+ # Match. Return this item
+ return list_item
+
+ # No Match
+ if required is True:
+ raise ValueError(custom_error_msg or var_name)
+ return default
+
+
+class Catchtime:
+ """A class working as a context to capture time differences."""
+
+ start: float
+ raw_time: float
+ time: str
+
+ def __init__(self, logger: Logger | None = None, message: str | None = None) -> None:
+ self.logger = logger
+ self.message = message
+
+ def __enter__(self) -> Self:
+ """__enter__ method."""
+ self.start = perf_counter()
+ if self.logger and self.message:
+ self.logger.info("%s ...", self.message)
+ return self
+
+ def __exit__(self, exc_type: type[BaseException] | None, exc_val: BaseException | None, exc_tb: TracebackType | None) -> None:
+ """__exit__ method."""
+ self.raw_time = perf_counter() - self.start
+ self.time = format_td(self.raw_time, 3)
+ if self.logger and self.message:
+ self.logger.info("%s completed in: %s.", self.message, self.time)
+
+
+def cprofile(sort_by: str = "cumtime") -> Callable[[F], F]:
+ """Profile a function with cProfile.
+
+ profile is conditionally enabled based on the presence of ANTA_CPROFILE environment variable.
+ Expect to decorate an async function.
+
+ Args:
+ ----
+ sort_by (str): The criterion to sort the profiling results. Default is 'cumtime'.
+
+ Returns
+ -------
+ Callable: The decorated function with conditional profiling.
+ """
+
+ def decorator(func: F) -> F:
+ @wraps(func)
+ async def wrapper(*args: Any, **kwargs: Any) -> Any:
+ """Enable cProfile or not.
+
+ If `ANTA_CPROFILE` is set, cProfile is enabled and dumps the stats to the file.
+
+ Args:
+ ----
+ *args: Arbitrary positional arguments.
+ **kwargs: Arbitrary keyword arguments.
+
+ Returns
+ -------
+ The result of the function call.
+ """
+ cprofile_file = os.environ.get("ANTA_CPROFILE")
+
+ if cprofile_file is not None:
+ profiler = cProfile.Profile()
+ profiler.enable()
+
+ try:
+ result = await func(*args, **kwargs)
+ finally:
+ if cprofile_file is not None:
+ profiler.disable()
+ stats = pstats.Stats(profiler).sort_stats(sort_by)
+ stats.dump_stats(cprofile_file)
+
+ return result
+
+ return cast(F, wrapper)
+
+ return decorator
diff --git a/anta/tools/__init__.py b/anta/tools/__init__.py
deleted file mode 100644
index e772bee..0000000
--- a/anta/tools/__init__.py
+++ /dev/null
@@ -1,3 +0,0 @@
-# Copyright (c) 2023-2024 Arista Networks, Inc.
-# Use of this source code is governed by the Apache License 2.0
-# that can be found in the LICENSE file.
diff --git a/anta/tools/get_dict_superset.py b/anta/tools/get_dict_superset.py
deleted file mode 100644
index b3bbde0..0000000
--- a/anta/tools/get_dict_superset.py
+++ /dev/null
@@ -1,64 +0,0 @@
-# Copyright (c) 2023-2024 Arista Networks, Inc.
-# Use of this source code is governed by the Apache License 2.0
-# that can be found in the LICENSE file.
-
-"""Get one dictionary from a list of dictionaries by matching the given key and values."""
-from __future__ import annotations
-
-from typing import Any, Optional
-
-
-def get_dict_superset(
- list_of_dicts: list[dict[Any, Any]],
- input_dict: dict[Any, Any],
- default: Optional[Any] = None,
- required: bool = False,
- var_name: Optional[str] = None,
- custom_error_msg: Optional[str] = None,
-) -> Any:
- """Get the first dictionary from a list of dictionaries that is a superset of the input dict.
-
- Returns the supplied default value or None if there is no match and "required" is False.
-
- Will return the first matching item if there are multiple matching items.
-
- Parameters
- ----------
- list_of_dicts: list(dict)
- List of Dictionaries to get list items from
- input_dict : dict
- Dictionary to check subset with a list of dict
- default: any
- Default value returned if the key and value are not found
- required: bool
- Fail if there is no match
- var_name : str
- String used for raising an exception with the full variable name
- custom_error_msg : str
- Custom error message to raise when required is True and the value is not found
-
- Returns
- -------
- any
- Dict or default value
-
- Raises
- ------
- ValueError
- If the keys and values are not found and "required" == True
- """
- if not isinstance(list_of_dicts, list) or not list_of_dicts or not isinstance(input_dict, dict) or not input_dict:
- if required:
- error_msg = custom_error_msg or f"{var_name} not found in the provided list."
- raise ValueError(error_msg)
- return default
-
- for list_item in list_of_dicts:
- if isinstance(list_item, dict) and input_dict.items() <= list_item.items():
- return list_item
-
- if required:
- error_msg = custom_error_msg or f"{var_name} not found in the provided list."
- raise ValueError(error_msg)
-
- return default
diff --git a/anta/tools/get_item.py b/anta/tools/get_item.py
deleted file mode 100644
index db5695b..0000000
--- a/anta/tools/get_item.py
+++ /dev/null
@@ -1,83 +0,0 @@
-# Copyright (c) 2023-2024 Arista Networks, Inc.
-# Use of this source code is governed by the Apache License 2.0
-# that can be found in the LICENSE file.
-
-"""Get one dictionary from a list of dictionaries by matching the given key and value."""
-from __future__ import annotations
-
-from typing import Any, Optional
-
-
-# pylint: disable=too-many-arguments
-def get_item(
- list_of_dicts: list[dict[Any, Any]],
- key: Any,
- value: Any,
- default: Optional[Any] = None,
- required: bool = False,
- case_sensitive: bool = False,
- var_name: Optional[str] = None,
- custom_error_msg: Optional[str] = None,
-) -> Any:
- """Get one dictionary from a list of dictionaries by matching the given key and value.
-
- Returns the supplied default value or None if there is no match and "required" is False.
-
- Will return the first matching item if there are multiple matching items.
-
- Parameters
- ----------
- list_of_dicts : list(dict)
- List of Dictionaries to get list item from
- key : any
- Dictionary Key to match on
- value : any
- Value that must match
- default : any
- Default value returned if the key and value is not found
- required : bool
- Fail if there is no match
- case_sensitive : bool
- If the search value is a string, the comparison will ignore case by default
- var_name : str
- String used for raising exception with the full variable name
- custom_error_msg : str
- Custom error message to raise when required is True and the value is not found
-
- Returns
- -------
- any
- Dict or default value
-
- Raises
- ------
- ValueError
- If the key and value is not found and "required" == True
- """
- if var_name is None:
- var_name = key
-
- if (not isinstance(list_of_dicts, list)) or list_of_dicts == [] or value is None or key is None:
- if required is True:
- raise ValueError(custom_error_msg or var_name)
- return default
-
- for list_item in list_of_dicts:
- if not isinstance(list_item, dict):
- # List item is not a dict as required. Skip this item
- continue
-
- item_value = list_item.get(key)
-
- # Perform case-insensitive comparison if value and item_value are strings and case_sensitive is False
- if not case_sensitive and isinstance(value, str) and isinstance(item_value, str):
- if item_value.casefold() == value.casefold():
- return list_item
- elif item_value == value:
- # Match. Return this item
- return list_item
-
- # No Match
- if required is True:
- raise ValueError(custom_error_msg or var_name)
- return default
diff --git a/anta/tools/get_value.py b/anta/tools/get_value.py
deleted file mode 100644
index 5e4b84d..0000000
--- a/anta/tools/get_value.py
+++ /dev/null
@@ -1,56 +0,0 @@
-# Copyright (c) 2023-2024 Arista Networks, Inc.
-# Use of this source code is governed by the Apache License 2.0
-# that can be found in the LICENSE file.
-"""
-Get a value from a dictionary or nested dictionaries.
-"""
-from __future__ import annotations
-
-from typing import Any, Optional
-
-
-# pylint: disable=too-many-arguments
-def get_value(
- dictionary: dict[Any, Any], key: str, default: Optional[Any] = None, required: bool = False, org_key: Optional[str] = None, separator: str = "."
-) -> Any:
- """
- Get a value from a dictionary or nested dictionaries.
- Key supports dot-notation like "foo.bar" to do deeper lookups.
- Returns the supplied default value or None if the key is not found and required is False.
- Parameters
- ----------
- dictionary : dict
- Dictionary to get key from
- key : str
- Dictionary Key - supporting dot-notation for nested dictionaries
- default : any
- Default value returned if the key is not found
- required : bool
- Fail if the key is not found
- org_key : str
- Internal variable used for raising exception with the full key name even when called recursively
- separator: str
- String to use as the separator parameter in the split function. Useful in cases when the key
- can contain variables with "." inside (e.g. hostnames)
- Returns
- -------
- any
- Value or default value
- Raises
- ------
- ValueError
- If the key is not found and required == True
- """
-
- if org_key is None:
- org_key = key
- keys = key.split(separator)
- value = dictionary.get(keys[0])
- if value is None:
- if required:
- raise ValueError(org_key)
- return default
-
- if len(keys) > 1:
- return get_value(value, separator.join(keys[1:]), default=default, required=required, org_key=org_key, separator=separator)
- return value
diff --git a/anta/tools/misc.py b/anta/tools/misc.py
deleted file mode 100644
index c01f7f4..0000000
--- a/anta/tools/misc.py
+++ /dev/null
@@ -1,26 +0,0 @@
-# Copyright (c) 2023-2024 Arista Networks, Inc.
-# Use of this source code is governed by the Apache License 2.0
-# that can be found in the LICENSE file.
-"""
-Toolkit for ANTA.
-"""
-from __future__ import annotations
-
-import logging
-import traceback
-
-logger = logging.getLogger(__name__)
-
-
-def exc_to_str(exception: BaseException) -> str:
- """
- Helper function that returns a human readable string from an BaseException object
- """
- return f"{type(exception).__name__}{f' ({exception})' if str(exception) else ''}"
-
-
-def tb_to_str(exception: BaseException) -> str:
- """
- Helper function that returns a traceback string from an BaseException object
- """
- return "Traceback (most recent call last):\n" + "".join(traceback.format_tb(exception.__traceback__))
diff --git a/anta/tools/utils.py b/anta/tools/utils.py
deleted file mode 100644
index e361d1e..0000000
--- a/anta/tools/utils.py
+++ /dev/null
@@ -1,34 +0,0 @@
-# Copyright (c) 2023-2024 Arista Networks, Inc.
-# Use of this source code is governed by the Apache License 2.0
-# that can be found in the LICENSE file.
-"""
-Toolkit for ANTA.
-"""
-from __future__ import annotations
-
-from typing import Any
-
-
-def get_failed_logs(expected_output: dict[Any, Any], actual_output: dict[Any, Any]) -> str:
- """
- Get the failed log for a test.
- Returns the failed log or an empty string if there is no difference between the expected and actual output.
-
- Parameters:
- expected_output (dict): Expected output of a test.
- actual_output (dict): Actual output of a test
-
- Returns:
- str: Failed log of a test.
- """
- failed_logs = []
-
- for element, expected_data in expected_output.items():
- actual_data = actual_output.get(element)
-
- if actual_data is None:
- failed_logs.append(f"\nExpected `{expected_data}` as the {element}, but it was not found in the actual output.")
- elif actual_data != expected_data:
- failed_logs.append(f"\nExpected `{expected_data}` as the {element}, but found `{actual_data}` instead.")
-
- return "".join(failed_logs)
diff --git a/asynceapi/__init__.py b/asynceapi/__init__.py
new file mode 100644
index 0000000..d6586cf
--- /dev/null
+++ b/asynceapi/__init__.py
@@ -0,0 +1,12 @@
+# Copyright (c) 2024 Arista Networks, Inc.
+# Use of this source code is governed by the Apache License 2.0
+# that can be found in the LICENSE file.
+# Initially written by Jeremy Schulman at https://github.com/jeremyschulman/aio-eapi
+
+"""Arista EOS eAPI asyncio client."""
+
+from .config_session import SessionConfig
+from .device import Device
+from .errors import EapiCommandError
+
+__all__ = ["Device", "SessionConfig", "EapiCommandError"]
diff --git a/asynceapi/aio_portcheck.py b/asynceapi/aio_portcheck.py
new file mode 100644
index 0000000..79f4562
--- /dev/null
+++ b/asynceapi/aio_portcheck.py
@@ -0,0 +1,58 @@
+# Copyright (c) 2024 Arista Networks, Inc.
+# Use of this source code is governed by the Apache License 2.0
+# that can be found in the LICENSE file.
+# Initially written by Jeremy Schulman at https://github.com/jeremyschulman/aio-eapi
+"""Utility function to check if a port is open."""
+# -----------------------------------------------------------------------------
+# System Imports
+# -----------------------------------------------------------------------------
+
+from __future__ import annotations
+
+import asyncio
+import socket
+from typing import TYPE_CHECKING
+
+# -----------------------------------------------------------------------------
+# Public Imports
+# -----------------------------------------------------------------------------
+
+if TYPE_CHECKING:
+ from httpx import URL
+
+# -----------------------------------------------------------------------------
+# Exports
+# -----------------------------------------------------------------------------
+
+__all__ = ["port_check_url"]
+
+# -----------------------------------------------------------------------------
+#
+# CODE BEGINS
+#
+# -----------------------------------------------------------------------------
+
+
+async def port_check_url(url: URL, timeout: int = 5) -> bool:
+ """
+ Open the port designated by the URL given the timeout in seconds.
+
+ If the port is available then return True; False otherwise.
+
+ Parameters
+ ----------
+ url: The URL that provides the target system
+ timeout: Time to await for the port to open in seconds
+ """
+ port = url.port or socket.getservbyname(url.scheme)
+
+ try:
+ wr: asyncio.StreamWriter
+ _, wr = await asyncio.wait_for(asyncio.open_connection(host=url.host, port=port), timeout=timeout)
+
+ # MUST close if opened!
+ wr.close()
+
+ except TimeoutError:
+ return False
+ return True
diff --git a/asynceapi/config_session.py b/asynceapi/config_session.py
new file mode 100644
index 0000000..4054f14
--- /dev/null
+++ b/asynceapi/config_session.py
@@ -0,0 +1,289 @@
+# Copyright (c) 2024 Arista Networks, Inc.
+# Use of this source code is governed by the Apache License 2.0
+# that can be found in the LICENSE file.
+# Initially written by Jeremy Schulman at https://github.com/jeremyschulman/aio-eapi
+"""asynceapi.SessionConfig definition."""
+
+# -----------------------------------------------------------------------------
+# System Imports
+# -----------------------------------------------------------------------------
+from __future__ import annotations
+
+import re
+from typing import TYPE_CHECKING, Any
+
+if TYPE_CHECKING:
+ from .device import Device
+
+# -----------------------------------------------------------------------------
+# Exports
+# -----------------------------------------------------------------------------
+
+__all__ = ["SessionConfig"]
+
+# -----------------------------------------------------------------------------
+#
+# CODE BEGINS
+#
+# -----------------------------------------------------------------------------
+
+
+class SessionConfig:
+ """
+ Send configuration to a device using the EOS session mechanism.
+
+ This is the preferred way of managing configuration changes.
+
+ Notes
+ -----
+ This class definition is used by the parent Device class definition as
+ defined by `config_session`. A Caller can use the SessionConfig directly
+ as well, but it is not required.
+ """
+
+ CLI_CFG_FACTORY_RESET = "rollback clean-config"
+
+ def __init__(self, device: Device, name: str) -> None:
+ """
+ Create a new instance of SessionConfig.
+
+ The session config instance bound
+ to the given device instance, and using the session `name`.
+
+ Parameters
+ ----------
+ device: The associated device instance
+ name: The name of the config session
+ """
+ self._device = device
+ self._cli = device.cli
+ self._name = name
+ self._cli_config_session = f"configure session {self.name}"
+
+ # -------------------------------------------------------------------------
+ # properties for read-only attributes
+ # -------------------------------------------------------------------------
+
+ @property
+ def name(self) -> str:
+ """Return read-only session name attribute."""
+ return self._name
+
+ @property
+ def device(self) -> Device:
+ """Return read-only device instance attribute."""
+ return self._device
+
+ # -------------------------------------------------------------------------
+ # Public Methods
+ # -------------------------------------------------------------------------
+
+ async def status_all(self) -> dict[str, Any]:
+ """
+ Get the status of all the session config on the device.
+
+ Run the following command on the device:
+ # show configuration sessions detail
+
+ Returns
+ -------
+ Dict object of native EOS eAPI response; see `status` method for
+ details.
+
+ Examples
+ --------
+ {
+ "maxSavedSessions": 1,
+ "maxOpenSessions": 5,
+ "sessions": {
+ "jeremy1": {
+ "instances": {},
+ "state": "pending",
+ "commitUser": "",
+ "description": ""
+ },
+ "ansible_167510439362": {
+ "instances": {},
+ "state": "completed",
+ "commitUser": "joe.bob",
+ "description": "",
+ "completedTime": 1675104396.4500246
+ }
+ }
+ }
+ """
+ return await self._cli("show configuration sessions detail") # type: ignore[return-value] # json outformat returns dict[str, Any]
+
+ async def status(self) -> dict[str, Any] | None:
+ """
+ Get the status of a session config on the device.
+
+ Run the following command on the device:
+ # show configuration sessions detail
+
+ And return only the status dictionary for this session. If you want
+ all sessions, then use the `status_all` method.
+
+ Returns
+ -------
+ Dict instance of the session status. If the session does not exist,
+ then this method will return None.
+
+ The native eAPI results from JSON output, see example:
+
+ Examples
+ --------
+ all results:
+ {
+ "maxSavedSessions": 1,
+ "maxOpenSessions": 5,
+ "sessions": {
+ "jeremy1": {
+ "instances": {},
+ "state": "pending",
+ "commitUser": "",
+ "description": ""
+ },
+ "ansible_167510439362": {
+ "instances": {},
+ "state": "completed",
+ "commitUser": "joe.bob",
+ "description": "",
+ "completedTime": 1675104396.4500246
+ }
+ }
+ }
+
+ if the session name was 'jeremy1', then this method would return
+ {
+ "instances": {},
+ "state": "pending",
+ "commitUser": "",
+ "description": ""
+ }
+ """
+ res = await self.status_all()
+ return res["sessions"].get(self.name)
+
+ async def push(self, content: list[str] | str, *, replace: bool = False) -> None:
+ """
+ Send the configuration content to the device.
+
+ If `replace` is true, then the command "rollback clean-config" is issued
+ before sending the configuration content.
+
+ Parameters
+ ----------
+ content:
+ The text configuration CLI commands, as a list of strings, that
+ will be sent to the device. If the parameter is a string, and not
+ a list, then split the string across linebreaks. In either case
+ any empty lines will be discarded before they are send to the
+ device.
+ replace:
+ When True, the content will replace the existing configuration
+ on the device.
+ """
+ # if given s string, we need to break it up into individual command
+ # lines.
+
+ if isinstance(content, str):
+ content = content.splitlines()
+
+ # prepare the initial set of command to enter the config session and
+ # rollback clean if the `replace` argument is True.
+
+ commands: list[str | dict[str, Any]] = [self._cli_config_session]
+ if replace:
+ commands.append(self.CLI_CFG_FACTORY_RESET)
+
+ # add the Caller's commands, filtering out any blank lines. any command
+ # lines (!) are still included.
+
+ commands.extend(filter(None, content))
+
+ await self._cli(commands=commands)
+
+ async def commit(self, timer: str | None = None) -> None:
+ """
+ Commit the session config.
+
+ Run the following command on the device:
+ # configure session <name>
+ # commit
+
+ If the timer is specified, format is "hh:mm:ss", then a commit timer is
+ started. A second commit action must be made to confirm the config
+ session before the timer expires; otherwise the config-session is
+ automatically aborted.
+ """
+ command = f"{self._cli_config_session} commit"
+
+ if timer:
+ command += f" timer {timer}"
+
+ await self._cli(command)
+
+ async def abort(self) -> None:
+ """
+ Abort the configuration session.
+
+ Run the following command on the device:
+ # configure session <name> abort
+ """
+ await self._cli(f"{self._cli_config_session} abort")
+
+ async def diff(self) -> str:
+ """
+ Return the "diff" of the session config relative to the running config.
+
+ Run the following command on the device:
+ # show session-config named <name> diffs
+
+ Returns
+ -------
+ Return a string in diff-patch format.
+
+ References
+ ----------
+ * https://www.gnu.org/software/diffutils/manual/diffutils.txt
+ """
+ return await self._cli(f"show session-config named {self.name} diffs", ofmt="text") # type: ignore[return-value] # text outformat returns str
+
+ async def load_file(self, filename: str, *, replace: bool = False) -> None:
+ """
+ Load the configuration from <filename> into the session configuration.
+
+ If the replace parameter is True then the file contents will replace the existing session config (load-replace).
+
+ Parameters
+ ----------
+ filename:
+ The name of the configuration file. The caller is required to
+ specify the filesystem, for example, the
+ filename="flash:thisfile.cfg"
+
+ replace:
+ When True, the contents of the file will completely replace the
+ session config for a load-replace behavior.
+
+ Raises
+ ------
+ If there are any issues with loading the configuration file then a
+ RuntimeError is raised with the error messages content.
+ """
+ commands: list[str | dict[str, Any]] = [self._cli_config_session]
+ if replace:
+ commands.append(self.CLI_CFG_FACTORY_RESET)
+
+ commands.append(f"copy {filename} session-config")
+ res: list[dict[str, Any]] = await self._cli(commands=commands) # type: ignore[assignment] # JSON outformat of multiple commands returns list[dict[str, Any]]
+ checks_re = re.compile(r"error|abort|invalid", flags=re.I)
+ messages = res[-1]["messages"]
+
+ if any(map(checks_re.search, messages)):
+ raise RuntimeError("".join(messages))
+
+ async def write(self) -> None:
+ """Save the running config to the startup config by issuing the command "write" to the device."""
+ await self._cli("write")
diff --git a/asynceapi/device.py b/asynceapi/device.py
new file mode 100644
index 0000000..04ec3ab
--- /dev/null
+++ b/asynceapi/device.py
@@ -0,0 +1,291 @@
+# Copyright (c) 2024 Arista Networks, Inc.
+# Use of this source code is governed by the Apache License 2.0
+# that can be found in the LICENSE file.
+# Initially written by Jeremy Schulman at https://github.com/jeremyschulman/aio-eapi
+"""asynceapi.Device definition."""
+# -----------------------------------------------------------------------------
+# System Imports
+# -----------------------------------------------------------------------------
+
+from __future__ import annotations
+
+from socket import getservbyname
+from typing import TYPE_CHECKING, Any
+
+# -----------------------------------------------------------------------------
+# Public Imports
+# -----------------------------------------------------------------------------
+import httpx
+
+# -----------------------------------------------------------------------------
+# Private Imports
+# -----------------------------------------------------------------------------
+from .aio_portcheck import port_check_url
+from .config_session import SessionConfig
+from .errors import EapiCommandError
+
+if TYPE_CHECKING:
+ from collections.abc import Sequence
+
+# -----------------------------------------------------------------------------
+# Exports
+# -----------------------------------------------------------------------------
+
+
+__all__ = ["Device"]
+
+
+# -----------------------------------------------------------------------------
+#
+# CODE BEGINS
+#
+# -----------------------------------------------------------------------------
+
+
+class Device(httpx.AsyncClient):
+ """
+ Represent the async JSON-RPC client that communicates with an Arista EOS device.
+
+ This class inherits directly from the
+ httpx.AsyncClient, so any initialization options can be passed directly.
+ """
+
+ auth = None
+ EAPI_OFMT_OPTIONS = ("json", "text")
+ EAPI_DEFAULT_OFMT = "json"
+
+ def __init__( # noqa: PLR0913 # pylint: disable=too-many-arguments
+ self,
+ host: str | None = None,
+ username: str | None = None,
+ password: str | None = None,
+ proto: str = "https",
+ port: str | int | None = None,
+ **kwargs: Any, # noqa: ANN401
+ ) -> None:
+ """
+ Initialize the Device class.
+
+ As a subclass to httpx.AsyncClient, the caller can provide any of those initializers.
+ Specific parameters for Device class are all optional and described below.
+
+ Parameters
+ ----------
+ host: The EOS target device, either hostname (DNS) or ipaddress.
+ username: The login user-name; requires the password parameter.
+ password: The login password; requires the username parameter.
+ proto: The protocol, http or https, to communicate eAPI with the device.
+ port: If not provided, the proto value is used to look up the associated
+ port (http=80, https=443). If provided, overrides the port used to
+ communite with the device.
+
+ Other Parameters
+ ----------------
+ base_url: str
+ If provided, the complete URL to the device eAPI endpoint.
+
+ auth:
+ If provided, used as the httpx authorization initializer value. If
+ not provided, then username+password is assumed by the Caller and
+ used to create a BasicAuth instance.
+ """
+ self.port = port or getservbyname(proto)
+ self.host = host
+ kwargs.setdefault("base_url", httpx.URL(f"{proto}://{self.host}:{self.port}"))
+ kwargs.setdefault("verify", False)
+
+ if username and password:
+ self.auth = httpx.BasicAuth(username, password)
+
+ kwargs.setdefault("auth", self.auth)
+
+ super().__init__(**kwargs)
+ self.headers["Content-Type"] = "application/json-rpc"
+
+ async def check_connection(self) -> bool:
+ """
+ Check the target device to ensure that the eAPI port is open and accepting connections.
+
+ It is recommended that a Caller checks the connection before involving cli commands,
+ but this step is not required.
+
+ Returns
+ -------
+ True when the device eAPI is accessible, False otherwise.
+ """
+ return await port_check_url(self.base_url)
+
+ async def cli( # noqa: PLR0913 # pylint: disable=too-many-arguments
+ self,
+ command: str | dict[str, Any] | None = None,
+ commands: Sequence[str | dict[str, Any]] | None = None,
+ ofmt: str | None = None,
+ version: int | str | None = "latest",
+ *,
+ suppress_error: bool = False,
+ auto_complete: bool = False,
+ expand_aliases: bool = False,
+ req_id: int | str | None = None,
+ ) -> list[dict[str, Any] | str] | dict[str, Any] | str | None:
+ """
+ Execute one or more CLI commands.
+
+ Parameters
+ ----------
+ command:
+ A single command to execute; results in a single output response
+ commands:
+ A list of commands to execute; results in a list of output responses
+ ofmt:
+ Either 'json' or 'text'; indicates the output format for the CLI commands.
+ version:
+ By default the eAPI will use "version 1" for all API object models.
+ This driver will, by default, always set version to "latest" so
+ that the behavior matches the CLI of the device. The caller can
+ override the "latest" behavior by explicitly setting the version.
+ suppress_error:
+ When not False, then if the execution of the command would-have
+ raised an EapiCommandError, rather than raising this exception this
+ routine will return the value None.
+
+ For example, if the following command had raised
+ EapiCommandError, now response would be set to None instead.
+
+ response = dev.cli(..., suppress_error=True)
+ auto_complete:
+ Enabled/disables the command auto-compelete feature of the EAPI. Per the
+ documentation:
+ Allows users to use shorthand commands in eAPI calls. With this
+ parameter included a user can send 'sh ver' via eAPI to get the
+ output of 'show version'.
+ expand_aliases:
+ Enables/disables the command use of User defined alias. Per the
+ documentation:
+ Allowed users to provide the expandAliases parameter to eAPI
+ calls. This allows users to use aliased commands via the API.
+ For example if an alias is configured as 'sv' for 'show version'
+ then an API call with sv and the expandAliases parameter will
+ return the output of show version.
+ req_id:
+ A unique identifier that will be echoed back by the switch. May be a string or number.
+
+ Returns
+ -------
+ One or List of output responses, per the description above.
+ """
+ if not any((command, commands)):
+ msg = "Required 'command' or 'commands'"
+ raise RuntimeError(msg)
+
+ jsonrpc = self._jsonrpc_command(
+ commands=[command] if command else commands, ofmt=ofmt, version=version, auto_complete=auto_complete, expand_aliases=expand_aliases, req_id=req_id
+ )
+
+ try:
+ res = await self.jsonrpc_exec(jsonrpc)
+ return res[0] if command else res
+ except EapiCommandError:
+ if suppress_error:
+ return None
+ raise
+
+ def _jsonrpc_command( # noqa: PLR0913 # pylint: disable=too-many-arguments
+ self,
+ commands: Sequence[str | dict[str, Any]] | None = None,
+ ofmt: str | None = None,
+ version: int | str | None = "latest",
+ *,
+ auto_complete: bool = False,
+ expand_aliases: bool = False,
+ req_id: int | str | None = None,
+ ) -> dict[str, Any]:
+ """Create the JSON-RPC command dictionary object."""
+ cmd: dict[str, Any] = {
+ "jsonrpc": "2.0",
+ "method": "runCmds",
+ "params": {
+ "version": version,
+ "cmds": commands,
+ "format": ofmt or self.EAPI_DEFAULT_OFMT,
+ },
+ "id": req_id or id(self),
+ }
+ if auto_complete is not None:
+ cmd["params"].update({"autoComplete": auto_complete})
+
+ if expand_aliases is not None:
+ cmd["params"].update({"expandAliases": expand_aliases})
+
+ return cmd
+
+ async def jsonrpc_exec(self, jsonrpc: dict[str, Any]) -> list[dict[str, Any] | str]:
+ """
+ Execute the JSON-RPC dictionary object.
+
+ Parameters
+ ----------
+ jsonrpc:
+ The JSON-RPC as created by the `meth`:_jsonrpc_command().
+
+ Raises
+ ------
+ EapiCommandError
+ In the event that a command resulted in an error response.
+
+ Returns
+ -------
+ The list of command results; either dict or text depending on the
+ JSON-RPC format parameter.
+ """
+ res = await self.post("/command-api", json=jsonrpc)
+ res.raise_for_status()
+ body = res.json()
+
+ commands = jsonrpc["params"]["cmds"]
+ ofmt = jsonrpc["params"]["format"]
+
+ get_output = (lambda _r: _r["output"]) if ofmt == "text" else (lambda _r: _r)
+
+ # if there are no errors then return the list of command results.
+ if (err_data := body.get("error")) is None:
+ return [get_output(cmd_res) for cmd_res in body["result"]]
+
+ # ---------------------------------------------------------------------
+ # if we are here, then there were some command errors. Raise a
+ # EapiCommandError exception with args (commands that failed, passed,
+ # not-executed).
+ # ---------------------------------------------------------------------
+
+ # -------------------------- eAPI specification ----------------------
+ # On an error, no result object is present, only an error object, which
+ # is guaranteed to have the following attributes: code, messages, and
+ # data. Similar to the result object in the successful response, the
+ # data object is a list of objects corresponding to the results of all
+ # commands up to, and including, the failed command. If there was a an
+ # error before any commands were executed (e.g. bad credentials), data
+ # will be empty. The last object in the data array will always
+ # correspond to the failed command. The command failure details are
+ # always stored in the errors array.
+
+ cmd_data = err_data["data"]
+ len_data = len(cmd_data)
+ err_at = len_data - 1
+ err_msg = err_data["message"]
+
+ raise EapiCommandError(
+ passed=[get_output(cmd_data[cmd_i]) for cmd_i, cmd in enumerate(commands[:err_at])],
+ failed=commands[err_at]["cmd"],
+ errors=cmd_data[err_at]["errors"],
+ errmsg=err_msg,
+ not_exec=commands[err_at + 1 :],
+ )
+
+ def config_session(self, name: str) -> SessionConfig:
+ """
+ return a SessionConfig instance bound to this device with the given session name.
+
+ Parameters
+ ----------
+ name: The config-session name
+ """
+ return SessionConfig(self, name)
diff --git a/asynceapi/errors.py b/asynceapi/errors.py
new file mode 100644
index 0000000..614427a
--- /dev/null
+++ b/asynceapi/errors.py
@@ -0,0 +1,42 @@
+# Copyright (c) 2024 Arista Networks, Inc.
+# Use of this source code is governed by the Apache License 2.0
+# that can be found in the LICENSE file.
+# Initially written by Jeremy Schulman at https://github.com/jeremyschulman/aio-eapi
+"""asynceapi module exceptions."""
+
+from __future__ import annotations
+
+from typing import Any
+
+import httpx
+
+
+class EapiCommandError(RuntimeError):
+ """
+ Exception class for EAPI command errors.
+
+ Attributes
+ ----------
+ failed: the failed command
+ errmsg: a description of the failure reason
+ errors: the command failure details
+ passed: a list of command results of the commands that passed
+ not_exec: a list of commands that were not executed
+ """
+
+ def __init__(self, failed: str, errors: list[str], errmsg: str, passed: list[str | dict[str, Any]], not_exec: list[dict[str, Any]]) -> None: # noqa: PLR0913 # pylint: disable=too-many-arguments
+ """Initialize for the EapiCommandError exception."""
+ self.failed = failed
+ self.errmsg = errmsg
+ self.errors = errors
+ self.passed = passed
+ self.not_exec = not_exec
+ super().__init__()
+
+ def __str__(self) -> str:
+ """Return the error message associated with the exception."""
+ return self.errmsg
+
+
+# alias for exception during sending-receiving
+EapiTransportError = httpx.HTTPStatusError
diff --git a/docs/README.md b/docs/README.md
index d47d3fe..378867f 100755
--- a/docs/README.md
+++ b/docs/README.md
@@ -4,16 +4,14 @@
~ that can be found in the LICENSE file.
-->
-[![License](https://img.shields.io/badge/license-Apache%202.0-brightgreen.svg)](https://github.com/arista-netdevops-community/anta/blob/main/LICENSE)
-[![Linting and Testing Anta](https://github.com/arista-netdevops-community/anta/actions/workflows/code-testing.yml/badge.svg)](https://github.com/arista-netdevops-community/anta/actions/workflows/code-testing.yml)
-[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)
-![GitHub commit activity (branch)](https://img.shields.io/github/commit-activity/m/arista-netdevops-community/anta)
-[![github release](https://img.shields.io/github/release/arista-netdevops-community/anta.svg)](https://github.com/arista-netdevops-community/anta/releases/)
-![PyPI - Downloads](https://img.shields.io/pypi/dm/anta)
-![coverage](https://raw.githubusercontent.com/arista-netdevops-community/anta/coverage-badge/latest-release-coverage.svg)
-
# Arista Network Test Automation (ANTA) Framework
+| **Code** | [![Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json)](https://github.com/astral-sh/ruff) [![Numpy](https://img.shields.io/badge/Docstring_format-numpy-blue)](https://numpydoc.readthedocs.io/en/latest/format.html) |
+| :------------: | :-------|
+| **License** | [![License](https://img.shields.io/badge/license-Apache%202.0-brightgreen.svg)](https://github.com/arista-netdevops-community/anta/blob/main/LICENSE) |
+| **GitHub** | [![CI](https://github.com/arista-netdevops-community/anta/actions/workflows/code-testing.yml/badge.svg)](https://github.com/arista-netdevops-community/anta/actions/workflows/code-testing.yml) ![Coverage](https://raw.githubusercontent.com/arista-netdevops-community/anta/coverage-badge/latest-release-coverage.svg) ![Commit](https://img.shields.io/github/last-commit/arista-netdevops-community/anta) ![GitHub commit activity (branch)](https://img.shields.io/github/commit-activity/m/arista-netdevops-community/anta) [![Github release](https://img.shields.io/github/release/arista-netdevops-community/anta.svg)](https://github.com/arista-netdevops-community/anta/releases/) [![Contributors](https://img.shields.io/github/contributors/arista-netdevops-community/anta)](https://github.com/arista-netdevops-community/anta/graphs/contributors) |
+| **PyPi** | ![PyPi Version](https://img.shields.io/pypi/v/anta) ![Python Versions](https://img.shields.io/pypi/pyversions/anta) ![Python format](https://img.shields.io/pypi/format/anta) ![PyPI - Downloads](https://img.shields.io/pypi/dm/anta) |
+
ANTA is Python framework that automates tests for Arista devices.
- ANTA provides a [set of tests](api/tests.md) to validate the state of your network
@@ -21,14 +19,31 @@ ANTA is Python framework that automates tests for Arista devices.
- Automate NRFU (Network Ready For Use) test on a preproduction network
- Automate tests on a live network (periodically or on demand)
- ANTA can be used with:
- - The [ANTA CLI](cli/overview.md)
- As a [Python library](advanced_usages/as-python-lib.md) in your own application
+ - The [ANTA CLI](cli/overview.md)
![anta nrfu](https://raw.githubusercontent.com/arista-netdevops-community/anta/main/docs/imgs/anta-nrfu.svg)
+## Install ANTA library
+
+The library will **NOT** install the necessary dependencies for the CLI.
+
+```bash
+# Install ANTA as a library
+pip install anta
+```
+
+## Install ANTA CLI
+
+If you plan to use ANTA only as a CLI tool you can use `pipx` to install it.
+[`pipx`](https://pipx.pypa.io/stable/) is a tool to install and run python applications in isolated environments. Refer to `pipx` instructions to install on your system.
+`pipx` installs ANTA in an isolated python environment and makes it available globally.
+
+**This is not recommended if you plan to contribute to ANTA**
+
```bash
-# Install ANTA CLI
-$ pip install anta
+# Install ANTA CLI with pipx
+$ pipx install anta[cli]
# Run ANTA CLI
$ anta --help
@@ -54,8 +69,11 @@ Commands:
nrfu Run ANTA tests on devices
```
-> [!WARNING]
-> The ANTA CLI options have changed after version 0.11 and have moved away from the top level `anta` and are now required at their respective commands (e.g. `anta nrfu`). This breaking change occurs after users feedback on making the CLI more intuitive. This change should not affect user experience when using environment variables.
+You can also still choose to install it with directly with `pip`:
+
+```bash
+$ pip install anta[cli]
+```
## Documentation
@@ -67,4 +85,6 @@ Contributions are welcome. Please refer to the [contribution guide](contribution
## Credits
+Thank you to [Jeremy Schulman](https://github.com/jeremyschulman) for [aio-eapi](https://github.com/jeremyschulman/aio-eapi/tree/main/aioeapi).
+
Thank you to [Angélique Phillipps](https://github.com/aphillipps), [Colin MacGiollaEáin](https://github.com/colinmacgiolla), [Khelil Sator](https://github.com/ksator), [Matthieu Tache](https://github.com/mtache), [Onur Gashi](https://github.com/onurgashi), [Paul Lavelle](https://github.com/paullavelle), [Guillaume Mulocher](https://github.com/gmuloc) and [Thomas Grimonet](https://github.com/titom73) for their contributions and guidances.
diff --git a/docs/advanced_usages/as-python-lib.md b/docs/advanced_usages/as-python-lib.md
index b4ce654..f8d6734 100644
--- a/docs/advanced_usages/as-python-lib.md
+++ b/docs/advanced_usages/as-python-lib.md
@@ -72,7 +72,6 @@ if __name__ == "__main__":
filename="inv.yml",
username="arista",
password="@rista123",
- timeout=15,
)
# Run the main coroutine
@@ -129,7 +128,6 @@ if __name__ == "__main__":
filename="inv.yml",
username="arista",
password="@rista123",
- timeout=15,
)
# Create a list of commands with json output
@@ -228,7 +226,7 @@ class VerifyTransceiversManufacturers(AntaTest):
pass
```
-The test itself does not return any value, but the result is directly availble from your AntaTest object and exposes a `anta.result_manager.models.TestResult` object with result, name of the test and optional messages:
+The test itself does not return any value, but the result is directly available from your AntaTest object and exposes a `anta.result_manager.models.TestResult` object with result, name of the test and optional messages:
- `name` (str): Device name where the test has run.
@@ -256,7 +254,7 @@ To make it easier to get data, ANTA defines 2 different classes to manage comman
Represent a command with following information:
- Command to run
-- Ouput format expected
+- Output format expected
- eAPI version
- Output of the command
@@ -272,13 +270,13 @@ cmd2 = AntaCommand(command="show running-config diffs", ofmt="text")
!!! tip "Command revision and version"
* Most of EOS commands return a JSON structure according to a model (some commands may not be modeled hence the necessity to use `text` outformat sometimes.
* The model can change across time (adding feature, ... ) and when the model is changed in a non backward-compatible way, the __revision__ number is bumped. The initial model starts with __revision__ 1.
- * A __revision__ applies to a particular CLI command whereas a __version__ is global to an eAPI call. The __version__ is internally translated to a specific __revision__ for each CLI command in the RPC call. The currently supported __version__ vaues are `1` and `latest`.
+ * A __revision__ applies to a particular CLI command whereas a __version__ is global to an eAPI call. The __version__ is internally translated to a specific __revision__ for each CLI command in the RPC call. The currently supported __version__ values are `1` and `latest`.
* A __revision takes precedence over a version__ (e.g. if a command is run with version="latest" and revision=1, the first revision of the model is returned)
- * By default eAPI returns the first revision of each model to ensure that when upgrading, intergation with existing tools is not broken. This is done by using by default `version=1` in eAPI calls.
+ * By default, eAPI returns the first revision of each model to ensure that when upgrading, integrations with existing tools are not broken. This is done by using by default `version=1` in eAPI calls.
- ANTA uses by default `version="latest"` in AntaCommand. For some commands, you may want to run them with a different revision or version.
+ By default, ANTA uses `version="latest"` in AntaCommand, but when developing tests, the revision MUST be provided when the outformat of the command is `json`. As explained earlier, this is to ensure that the eAPI always returns the same output model and that the test remains always valid from the day it was created. For some commands, you may also want to run them with a different revision or version.
- For instance the `VerifyRoutingTableSize` test leverages the first revision of `show bfd peers`:
+ For instance, the `VerifyBFDPeersHealth` test leverages the first revision of `show bfd peers`:
```
# revision 1 as later revision introduce additional nesting for type
diff --git a/docs/advanced_usages/caching.md b/docs/advanced_usages/caching.md
index cec2467..ce4a787 100644
--- a/docs/advanced_usages/caching.md
+++ b/docs/advanced_usages/caching.md
@@ -47,7 +47,7 @@ There might be scenarios where caching is not wanted. You can disable caching in
```bash
anta --disable-cache --username arista --password arista nrfu table
```
-2. Caching can be disabled per device, network or range by setting the `disable_cache` key to `True` when definining the ANTA [Inventory](../usage-inventory-catalog.md#create-an-inventory-file) file:
+2. Caching can be disabled per device, network or range by setting the `disable_cache` key to `True` when defining the ANTA [Inventory](../usage-inventory-catalog.md#create-an-inventory-file) file:
```yaml
anta_inventory:
hosts:
@@ -71,7 +71,7 @@ There might be scenarios where caching is not wanted. You can disable caching in
```
This approach effectively disables caching for **ALL** commands sent to devices targeted by the `disable_cache` key.
-3. For tests developpers, caching can be disabled for a specific [`AntaCommand`](../advanced_usages/as-python-lib.md#antacommand-class) or [`AntaTemplate`](../advanced_usages/as-python-lib.md#antatemplate-class) by setting the `use_cache` attribute to `False`. That means the command output will always be collected on the device and therefore, never use caching.
+3. For tests developers, caching can be disabled for a specific [`AntaCommand`](../advanced_usages/as-python-lib.md#antacommand-class) or [`AntaTemplate`](../advanced_usages/as-python-lib.md#antatemplate-class) by setting the `use_cache` attribute to `False`. That means the command output will always be collected on the device and therefore, never use caching.
### Disable caching in a child class of `AntaDevice`
@@ -82,6 +82,6 @@ class AnsibleEOSDevice(AntaDevice):
"""
Implementation of an AntaDevice using Ansible HttpApi plugin for EOS.
"""
- def __init__(self, name: str, connection: ConnectionBase, tags: list = None) -> None:
+ def __init__(self, name: str, connection: ConnectionBase, tags: set = None) -> None:
super().__init__(name, tags, disable_cache=True)
```
diff --git a/docs/advanced_usages/custom-tests.md b/docs/advanced_usages/custom-tests.md
index 87402c1..ba62636 100644
--- a/docs/advanced_usages/custom-tests.md
+++ b/docs/advanced_usages/custom-tests.md
@@ -21,24 +21,32 @@ from anta.decorators import skip_on_platforms
class VerifyTemperature(AntaTest):
- """
- This test verifies if the device temperature is within acceptable limits.
-
- Expected Results:
- * success: The test will pass if the device temperature is currently OK: 'temperatureOk'.
- * failure: The test will fail if the device temperature is NOT OK.
+ """Verifies if the device temperature is within acceptable limits.
+
+ Expected Results
+ ----------------
+ * Success: The test will pass if the device temperature is currently OK: 'temperatureOk'.
+ * Failure: The test will fail if the device temperature is NOT OK.
+
+ Examples
+ --------
+ ```yaml
+ anta.tests.hardware:
+ - VerifyTemperature:
+ ```
"""
name = "VerifyTemperature"
- description = "Verifies if the device temperature is within the acceptable range."
- categories = ["hardware"]
- commands = [AntaCommand(command="show system environment temperature", ofmt="json")]
+ description = "Verifies the device temperature."
+ categories: ClassVar[list[str]] = ["hardware"]
+ commands: ClassVar[list[AntaCommand | AntaTemplate]] = [AntaCommand(command="show system environment temperature", revision=1)]
- @skip_on_platforms(["cEOSLab", "vEOS-lab"])
+ @skip_on_platforms(["cEOSLab", "vEOS-lab", "cEOSCloudLab"])
@AntaTest.anta_test
def test(self) -> None:
+ """Main test function for VerifyTemperature."""
command_output = self.instance_commands[0].json_output
- temperature_status = command_output["systemStatus"] if "systemStatus" in command_output.keys() else ""
+ temperature_status = command_output.get("systemStatus", "")
if temperature_status == "temperatureOk":
self.result.is_success()
else:
@@ -47,14 +55,16 @@ class VerifyTemperature(AntaTest):
[AntaTest](../api/models.md#anta.models.AntaTest) also provide more advanced capabilities like [AntaCommand](../api/models.md#anta.models.AntaCommand) templating using the [AntaTemplate](../api/models.md#anta.models.AntaTemplate) class or test inputs definition and validation using [AntaTest.Input](../api/models.md#anta.models.AntaTest.Input) [pydantic](https://docs.pydantic.dev/latest/) model. This will be discussed in the sections below.
-## [AntaTest](../api/models.md#anta.models.AntaTest) structure
+## AntaTest structure
+
+Full AntaTest API documentation is available in the [API documentation section](../api/models.md#anta.models.AntaTest)
### Class Attributes
- `name` (`str`): Name of the test. Used during reporting.
- `description` (`str`): A human readable description of your test.
- `categories` (`list[str]`): A list of categories in which the test belongs.
-- `commands` (`list[Union[AntaTemplate, AntaCommand]]`): A list of command to collect from devices. This list __must__ be a list of [AntaCommand](../api/models.md#anta.models.AntaCommand) or [AntaTemplate](../api/models.md#anta.models.AntaTemplate) instances. Rendering [AntaTemplate](../api/models.md#anta.models.AntaTemplate) instances will be discussed later.
+- `commands` (`[list[AntaCommand | AntaTemplate]]`): A list of command to collect from devices. This list __must__ be a list of [AntaCommand](../api/models.md#anta.models.AntaCommand) or [AntaTemplate](../api/models.md#anta.models.AntaTemplate) instances. Rendering [AntaTemplate](../api/models.md#anta.models.AntaTemplate) instances will be discussed later.
!!! info
All these class attributes are mandatory. If any attribute is missing, a `NotImplementedError` exception will be raised during class instantiation.
@@ -90,7 +100,9 @@ class VerifyTemperature(AntaTest):
The base definition of [AntaTest.Input](../api/models.md#anta.models.AntaTest.Input) provides common test inputs for all [AntaTest](../api/models.md#anta.models.AntaTest) instances:
-#### [Input](../api/models.md#anta.models.AntaTest.Input) model
+#### Input model
+
+Full `Input` model documentation is available in [API documentation section](../api/models.md#anta.models.AntaTest.Input)
::: anta.models.AntaTest.Input
options:
@@ -106,7 +118,9 @@ The base definition of [AntaTest.Input](../api/models.md#anta.models.AntaTest.In
show_root_toc_entry: false
heading_level: 10
-#### [ResultOverwrite](../api/models.md#anta.models.AntaTest.Input.ResultOverwrite) model
+#### ResultOverwrite model
+
+Full `ResultOverwrite` model documentation is available in [API documentation section](../api/models.md#anta.models.AntaTest.Input.ResultOverwrite)
::: anta.models.AntaTest.Input.ResultOverwrite
options:
@@ -127,7 +141,7 @@ The base definition of [AntaTest.Input](../api/models.md#anta.models.AntaTest.In
### Methods
- [test(self) -> None](../api/models.md#anta.models.AntaTest.test): This is an abstract method that __must__ be implemented. It contains the test logic that can access the collected command outputs using the `instance_commands` instance attribute, access the test inputs using the `inputs` instance attribute and __must__ set the `result` instance attribute accordingly. It must be implemented using the `AntaTest.anta_test` decorator that provides logging and will collect commands before executing the `test()` method.
-- [render(self, template: AntaTemplate) -> list[AntaCommand]](../api/models.md#anta.models.AntaTest.render): This method only needs to be implemented if [AntaTemplate](../api/models.md#anta.models.AntaTemplate) instances are present in the `commands` class attribute. It will be called for every [AntaTemplate](../api/models.md#anta.models.AntaTemplate) occurence and __must__ return a list of [AntaCommand](../api/models.md#anta.models.AntaCommand) using the [AntaTemplate.render()](../api/models.md#anta.models.AntaTemplate.render) method. It can access test inputs using the `inputs` instance attribute.
+- [render(self, template: AntaTemplate) -> list[AntaCommand]](../api/models.md#anta.models.AntaTest.render): This method only needs to be implemented if [AntaTemplate](../api/models.md#anta.models.AntaTemplate) instances are present in the `commands` class attribute. It will be called for every [AntaTemplate](../api/models.md#anta.models.AntaTemplate) occurrence and __must__ return a list of [AntaCommand](../api/models.md#anta.models.AntaCommand) using the [AntaTemplate.render()](../api/models.md#anta.models.AntaTemplate.render) method. It can access test inputs using the `inputs` instance attribute.
## Test execution
@@ -191,8 +205,24 @@ If the user needs to provide inputs for your test, you need to define a [pydanti
```python
class <YourTestName>(AntaTest):
+ """Verifies ...
+
+ Expected Results
+ ----------------
+ * Success: The test will pass if ...
+ * Failure: The test will fail if ...
+
+ Examples
+ --------
+ ```yaml
+ your.module.path:
+ - YourTestName:
+ field_name: example_field_value
+ ```
+ """
...
- class Input(AntaTest.Input): # pylint: disable=missing-class-docstring
+ class Input(AntaTest.Input):
+ """Inputs for my awesome test."""
<input field name>: <input field type>
"""<input field docstring>"""
```
diff --git a/docs/imgs/animated-svg.md b/docs/api/runner.md
index 6a27a50..27fbaa2 100644
--- a/docs/imgs/animated-svg.md
+++ b/docs/api/runner.md
@@ -4,5 +4,6 @@
~ that can be found in the LICENSE file.
-->
-Repository: https://github.com/marionebl/svg-term-cli
-Command: `cat anta-nrfu.cast | svg-term --height 10 --window --out anta.svg`
+### ::: anta.runner
+ options:
+ filters: ["!^_[^_]", "!__str__"]
diff --git a/docs/api/tests.aaa.md b/docs/api/tests.aaa.md
index bdbe7ec..e5c4b91 100644
--- a/docs/api/tests.aaa.md
+++ b/docs/api/tests.aaa.md
@@ -1,13 +1,20 @@
+---
+anta_title: ANTA catalog for AAA tests
+---
<!--
~ Copyright (c) 2023-2024 Arista Networks, Inc.
~ Use of this source code is governed by the Apache License 2.0
~ that can be found in the LICENSE file.
-->
-# ANTA catalog for interfaces tests
-
::: anta.tests.aaa
options:
show_root_heading: false
show_root_toc_entry: false
+ show_bases: false
merge_init_into_class: false
+ anta_hide_test_module_description: true
+ show_labels: true
+ filters:
+ - "!test"
+ - "!render"
diff --git a/docs/api/tests.avt.md b/docs/api/tests.avt.md
new file mode 100644
index 0000000..f9e1acf
--- /dev/null
+++ b/docs/api/tests.avt.md
@@ -0,0 +1,20 @@
+---
+anta_title: ANTA catalog for Adaptive Virtual Topology (AVT) tests
+---
+<!--
+ ~ Copyright (c) 2023-2024 Arista Networks, Inc.
+ ~ Use of this source code is governed by the Apache License 2.0
+ ~ that can be found in the LICENSE file.
+ -->
+
+::: anta.tests.avt
+ options:
+ show_root_heading: false
+ show_root_toc_entry: false
+ show_bases: false
+ merge_init_into_class: false
+ anta_hide_test_module_description: true
+ show_labels: true
+ filters:
+ - "!test"
+ - "!render"
diff --git a/docs/api/tests.bfd.md b/docs/api/tests.bfd.md
index d28521f..719466e 100644
--- a/docs/api/tests.bfd.md
+++ b/docs/api/tests.bfd.md
@@ -1,13 +1,20 @@
+---
+anta_title: ANTA catalog for BFD tests
+---
<!--
~ Copyright (c) 2023-2024 Arista Networks, Inc.
~ Use of this source code is governed by the Apache License 2.0
~ that can be found in the LICENSE file.
-->
-# ANTA catalog for bfd tests
-
::: anta.tests.bfd
options:
show_root_heading: false
show_root_toc_entry: false
+ show_bases: false
merge_init_into_class: false
+ show_labels: true
+ anta_hide_test_module_description: true
+ filters:
+ - "!test"
+ - "!render"
diff --git a/docs/api/tests.configuration.md b/docs/api/tests.configuration.md
index aaee1f4..9b24ea7 100644
--- a/docs/api/tests.configuration.md
+++ b/docs/api/tests.configuration.md
@@ -1,13 +1,20 @@
+---
+anta_title: ANTA catalog for device configuration tests
+---
<!--
~ Copyright (c) 2023-2024 Arista Networks, Inc.
~ Use of this source code is governed by the Apache License 2.0
~ that can be found in the LICENSE file.
-->
-# ANTA catalog for configuration tests
-
::: anta.tests.configuration
options:
show_root_heading: false
show_root_toc_entry: false
+ show_bases: false
merge_init_into_class: false
+ anta_hide_test_module_description: true
+ show_labels: true
+ filters:
+ - "!test"
+ - "!render"
diff --git a/docs/api/tests.connectivity.md b/docs/api/tests.connectivity.md
index 8a1b8a2..0dd5d44 100644
--- a/docs/api/tests.connectivity.md
+++ b/docs/api/tests.connectivity.md
@@ -1,13 +1,20 @@
+---
+anta_title: ANTA catalog for connectivity tests
+---
<!--
~ Copyright (c) 2023-2024 Arista Networks, Inc.
~ Use of this source code is governed by the Apache License 2.0
~ that can be found in the LICENSE file.
-->
-# ANTA catalog for connectivity tests
-
::: anta.tests.connectivity
options:
show_root_heading: false
show_root_toc_entry: false
+ show_bases: false
merge_init_into_class: false
+ anta_hide_test_module_description: true
+ show_labels: true
+ filters:
+ - "!test"
+ - "!render"
diff --git a/docs/api/tests.field_notices.md b/docs/api/tests.field_notices.md
index ed0e837..fe95bf5 100644
--- a/docs/api/tests.field_notices.md
+++ b/docs/api/tests.field_notices.md
@@ -1,13 +1,20 @@
+---
+anta_title: ANTA catalog for Field Notices tests
+---
<!--
~ Copyright (c) 2023-2024 Arista Networks, Inc.
~ Use of this source code is governed by the Apache License 2.0
~ that can be found in the LICENSE file.
-->
-# ANTA catalog for Field Notices tests
-
::: anta.tests.field_notices
options:
show_root_heading: false
show_root_toc_entry: false
+ show_bases: false
merge_init_into_class: false
+ anta_hide_test_module_description: true
+ show_labels: true
+ filters:
+ - "!test"
+ - "!render"
diff --git a/docs/api/tests.greent.md b/docs/api/tests.greent.md
new file mode 100644
index 0000000..01900a9
--- /dev/null
+++ b/docs/api/tests.greent.md
@@ -0,0 +1,20 @@
+---
+anta_title: ANTA catalog for GreenT tests
+---
+<!--
+ ~ Copyright (c) 2023-2024 Arista Networks, Inc.
+ ~ Use of this source code is governed by the Apache License 2.0
+ ~ that can be found in the LICENSE file.
+ -->
+
+::: anta.tests.greent
+ options:
+ show_root_heading: false
+ show_root_toc_entry: false
+ show_bases: false
+ merge_init_into_class: false
+ anta_hide_test_module_description: true
+ show_labels: true
+ filters:
+ - "!test"
+ - "!render"
diff --git a/docs/api/tests.hardware.md b/docs/api/tests.hardware.md
index 6e84196..ad06a50 100644
--- a/docs/api/tests.hardware.md
+++ b/docs/api/tests.hardware.md
@@ -1,13 +1,20 @@
+---
+anta_title: ANTA catalog for hardware tests
+---
<!--
~ Copyright (c) 2023-2024 Arista Networks, Inc.
~ Use of this source code is governed by the Apache License 2.0
~ that can be found in the LICENSE file.
-->
-# ANTA catalog for hardware tests
-
::: anta.tests.hardware
options:
show_root_heading: false
show_root_toc_entry: false
+ show_bases: false
merge_init_into_class: false
+ anta_hide_test_module_description: true
+ show_labels: true
+ filters:
+ - "!test"
+ - "!render"
diff --git a/docs/api/tests.interfaces.md b/docs/api/tests.interfaces.md
index b21da40..95630f5 100644
--- a/docs/api/tests.interfaces.md
+++ b/docs/api/tests.interfaces.md
@@ -1,13 +1,20 @@
+---
+anta_title: ANTA catalog for interfaces tests
+---
<!--
~ Copyright (c) 2023-2024 Arista Networks, Inc.
~ Use of this source code is governed by the Apache License 2.0
~ that can be found in the LICENSE file.
-->
-# ANTA catalog for interfaces tests
-
::: anta.tests.interfaces
options:
show_root_heading: false
show_root_toc_entry: false
+ show_bases: false
merge_init_into_class: false
+ anta_hide_test_module_description: true
+ show_labels: true
+ filters:
+ - "!test"
+ - "!render"
diff --git a/docs/api/tests.lanz.md b/docs/api/tests.lanz.md
new file mode 100644
index 0000000..0685717
--- /dev/null
+++ b/docs/api/tests.lanz.md
@@ -0,0 +1,20 @@
+---
+anta_title: ANTA catalog for LANZ tests
+---
+<!--
+ ~ Copyright (c) 2023-2024 Arista Networks, Inc.
+ ~ Use of this source code is governed by the Apache License 2.0
+ ~ that can be found in the LICENSE file.
+ -->
+
+::: anta.tests.lanz
+ options:
+ show_root_heading: false
+ show_root_toc_entry: false
+ show_bases: false
+ merge_init_into_class: false
+ anta_hide_test_module_description: true
+ show_labels: true
+ filters:
+ - "!test"
+ - "!render"
diff --git a/docs/api/tests.logging.md b/docs/api/tests.logging.md
index e9acc20..2c4dec0 100644
--- a/docs/api/tests.logging.md
+++ b/docs/api/tests.logging.md
@@ -1,13 +1,20 @@
+---
+anta_title: ANTA catalog for logging tests
+---
<!--
~ Copyright (c) 2023-2024 Arista Networks, Inc.
~ Use of this source code is governed by the Apache License 2.0
~ that can be found in the LICENSE file.
-->
-# ANTA catalog for logging tests
-
::: anta.tests.logging
options:
show_root_heading: false
show_root_toc_entry: false
+ show_bases: false
merge_init_into_class: false
+ anta_hide_test_module_description: true
+ show_labels: true
+ filters:
+ - "!test"
+ - "!render"
diff --git a/docs/api/tests.md b/docs/api/tests.md
index 40c7d8a..b11f0ba 100644
--- a/docs/api/tests.md
+++ b/docs/api/tests.md
@@ -4,22 +4,30 @@
~ that can be found in the LICENSE file.
-->
-# ANTA Tests landing page
+# ANTA Tests Landing Page
-This section describes all the available tests provided by ANTA package.
+This section describes all the available tests provided by the ANTA package.
+## Available Tests
+
+Here are the tests that we currently provide:
- [AAA](tests.aaa.md)
+- [Adaptive Virtual Topology](tests.avt.md)
- [BFD](tests.bfd.md)
- [Configuration](tests.configuration.md)
- [Connectivity](tests.connectivity.md)
- [Field Notice](tests.field_notices.md)
+- [GreenT](tests.greent.md)
- [Hardware](tests.hardware.md)
- [Interfaces](tests.interfaces.md)
+- [LANZ](tests.lanz.md)
- [Logging](tests.logging.md)
- [MLAG](tests.mlag.md)
- [Multicast](tests.multicast.md)
- [Profiles](tests.profiles.md)
+- [PTP](tests.ptp.md)
+- [Router Path Selection](tests.path_selection.md)
- [Routing Generic](tests.routing.generic.md)
- [Routing BGP](tests.routing.bgp.md)
- [Routing OSPF](tests.routing.ospf.md)
@@ -28,10 +36,11 @@ This section describes all the available tests provided by ANTA package.
- [SNMP](tests.snmp.md)
- [Software](tests.software.md)
- [STP](tests.stp.md)
+- [STUN](tests.stun.md)
- [System](tests.system.md)
- [VLAN](tests.vlan.md)
- [VXLAN](tests.vxlan.md)
+## Using the Tests
-
-All these tests can be imported in a [catalog](../usage-inventory-catalog.md) to be used by [the anta cli](../cli/nrfu.md) or in your [own framework](../advanced_usages/as-python-lib.md)
+All these tests can be imported in a [catalog](../usage-inventory-catalog.md) to be used by [the ANTA CLI](../cli/nrfu.md) or in your [own framework](../advanced_usages/as-python-lib.md).
diff --git a/docs/api/tests.mlag.md b/docs/api/tests.mlag.md
index 6ce419b..5470bcd 100644
--- a/docs/api/tests.mlag.md
+++ b/docs/api/tests.mlag.md
@@ -1,13 +1,20 @@
+---
+anta_title: ANTA catalog for MLAG tests
+---
<!--
~ Copyright (c) 2023-2024 Arista Networks, Inc.
~ Use of this source code is governed by the Apache License 2.0
~ that can be found in the LICENSE file.
-->
-# ANTA catalog for mlag tests
-
::: anta.tests.mlag
options:
show_root_heading: false
show_root_toc_entry: false
+ show_bases: false
merge_init_into_class: false
+ anta_hide_test_module_description: true
+ show_labels: true
+ filters:
+ - "!test"
+ - "!render"
diff --git a/docs/api/tests.multicast.md b/docs/api/tests.multicast.md
index 2b03420..7072796 100644
--- a/docs/api/tests.multicast.md
+++ b/docs/api/tests.multicast.md
@@ -1,13 +1,20 @@
+---
+anta_title: ANTA catalog for multicast and IGMP tests
+---
<!--
~ Copyright (c) 2023-2024 Arista Networks, Inc.
~ Use of this source code is governed by the Apache License 2.0
~ that can be found in the LICENSE file.
-->
-# ANTA catalog for multicast tests
-
::: anta.tests.multicast
options:
show_root_heading: false
show_root_toc_entry: false
+ show_bases: false
merge_init_into_class: false
+ anta_hide_test_module_description: true
+ show_labels: true
+ filters:
+ - "!test"
+ - "!render"
diff --git a/docs/api/tests.path_selection.md b/docs/api/tests.path_selection.md
new file mode 100644
index 0000000..b7f6b46
--- /dev/null
+++ b/docs/api/tests.path_selection.md
@@ -0,0 +1,20 @@
+---
+anta_title: ANTA catalog for Router path-selection tests
+---
+<!--
+ ~ Copyright (c) 2023-2024 Arista Networks, Inc.
+ ~ Use of this source code is governed by the Apache License 2.0
+ ~ that can be found in the LICENSE file.
+ -->
+
+::: anta.tests.path_selection
+ options:
+ show_root_heading: false
+ show_root_toc_entry: false
+ show_bases: false
+ merge_init_into_class: false
+ anta_hide_test_module_description: true
+ show_labels: true
+ filters:
+ - "!test"
+ - "!render"
diff --git a/docs/api/tests.profiles.md b/docs/api/tests.profiles.md
index c6d06e7..a022c6a 100644
--- a/docs/api/tests.profiles.md
+++ b/docs/api/tests.profiles.md
@@ -1,13 +1,20 @@
+---
+anta_title: ANTA catalog for profiles tests
+---
<!--
~ Copyright (c) 2023-2024 Arista Networks, Inc.
~ Use of this source code is governed by the Apache License 2.0
~ that can be found in the LICENSE file.
-->
-# ANTA catalog for profiles tests
-
::: anta.tests.profiles
options:
show_root_heading: false
show_root_toc_entry: false
+ show_bases: false
merge_init_into_class: false
+ anta_hide_test_module_description: true
+ show_labels: true
+ filters:
+ - "!test"
+ - "!render"
diff --git a/docs/api/tests.ptp.md b/docs/api/tests.ptp.md
new file mode 100644
index 0000000..3b03ac0
--- /dev/null
+++ b/docs/api/tests.ptp.md
@@ -0,0 +1,20 @@
+---
+anta_title: ANTA catalog for PTP tests
+---
+<!--
+ ~ Copyright (c) 2023-2024 Arista Networks, Inc.
+ ~ Use of this source code is governed by the Apache License 2.0
+ ~ that can be found in the LICENSE file.
+ -->
+
+::: anta.tests.ptp
+ options:
+ show_root_heading: false
+ show_root_toc_entry: false
+ show_bases: false
+ merge_init_into_class: false
+ anta_hide_test_module_description: true
+ show_labels: true
+ filters:
+ - "!test"
+ - "!render"
diff --git a/docs/api/tests.routing.bgp.md b/docs/api/tests.routing.bgp.md
index 2346866..5c54678 100644
--- a/docs/api/tests.routing.bgp.md
+++ b/docs/api/tests.routing.bgp.md
@@ -1,13 +1,20 @@
+---
+anta_title: ANTA catalog for BGP tests
+---
<!--
~ Copyright (c) 2023-2024 Arista Networks, Inc.
~ Use of this source code is governed by the Apache License 2.0
~ that can be found in the LICENSE file.
-->
-# ANTA catalog for BGP tests
-
::: anta.tests.routing.bgp
options:
show_root_heading: false
show_root_toc_entry: false
+ show_bases: false
merge_init_into_class: false
+ anta_hide_test_module_description: true
+ show_labels: true
+ filters:
+ - "!test"
+ - "!render"
diff --git a/docs/api/tests.routing.generic.md b/docs/api/tests.routing.generic.md
index 3853fb0..1c4c39d 100644
--- a/docs/api/tests.routing.generic.md
+++ b/docs/api/tests.routing.generic.md
@@ -1,13 +1,20 @@
+---
+anta_title: ANTA catalog for generic routing tests
+---
<!--
~ Copyright (c) 2023-2024 Arista Networks, Inc.
~ Use of this source code is governed by the Apache License 2.0
~ that can be found in the LICENSE file.
-->
-# ANTA catalog for routing-generic tests
-
::: anta.tests.routing.generic
options:
show_root_heading: false
show_root_toc_entry: false
+ show_bases: false
merge_init_into_class: false
+ anta_hide_test_module_description: true
+ show_labels: true
+ filters:
+ - "!test"
+ - "!render"
diff --git a/docs/api/tests.routing.isis.md b/docs/api/tests.routing.isis.md
new file mode 100644
index 0000000..b545f33
--- /dev/null
+++ b/docs/api/tests.routing.isis.md
@@ -0,0 +1,20 @@
+---
+anta_title: ANTA catalog for IS-IS tests
+---
+<!--
+ ~ Copyright (c) 2023-2024 Arista Networks, Inc.
+ ~ Use of this source code is governed by the Apache License 2.0
+ ~ that can be found in the LICENSE file.
+ -->
+
+::: anta.tests.routing.isis
+ options:
+ show_root_heading: false
+ show_root_toc_entry: false
+ show_bases: false
+ merge_init_into_class: false
+ anta_hide_test_module_description: true
+ show_labels: true
+ filters:
+ - "!test"
+ - "!render"
diff --git a/docs/api/tests.routing.ospf.md b/docs/api/tests.routing.ospf.md
index c4e6fed..a01eb50 100644
--- a/docs/api/tests.routing.ospf.md
+++ b/docs/api/tests.routing.ospf.md
@@ -1,13 +1,20 @@
+---
+anta_title: ANTA catalog for OSPF tests
+---
<!--
~ Copyright (c) 2023-2024 Arista Networks, Inc.
~ Use of this source code is governed by the Apache License 2.0
~ that can be found in the LICENSE file.
-->
-# ANTA catalog for routing-ospf tests
-
::: anta.tests.routing.ospf
options:
show_root_heading: false
show_root_toc_entry: false
+ show_bases: false
merge_init_into_class: false
+ anta_hide_test_module_description: true
+ show_labels: true
+ filters:
+ - "!test"
+ - "!render"
diff --git a/docs/api/tests.security.md b/docs/api/tests.security.md
index 1186b31..fe008ba 100644
--- a/docs/api/tests.security.md
+++ b/docs/api/tests.security.md
@@ -1,13 +1,20 @@
+---
+anta_title: ANTA catalog for security tests
+---
<!--
~ Copyright (c) 2023-2024 Arista Networks, Inc.
~ Use of this source code is governed by the Apache License 2.0
~ that can be found in the LICENSE file.
-->
-# ANTA catalog for security tests
-
::: anta.tests.security
options:
show_root_heading: false
show_root_toc_entry: false
+ show_bases: false
merge_init_into_class: false
+ anta_hide_test_module_description: true
+ show_labels: true
+ filters:
+ - "!test"
+ - "!render"
diff --git a/docs/api/tests.services.md b/docs/api/tests.services.md
index 82a7b38..63d9234 100644
--- a/docs/api/tests.services.md
+++ b/docs/api/tests.services.md
@@ -1,13 +1,20 @@
+---
+anta_title: ANTA catalog for services tests
+---
<!--
~ Copyright (c) 2023-2024 Arista Networks, Inc.
~ Use of this source code is governed by the Apache License 2.0
~ that can be found in the LICENSE file.
-->
-# ANTA catalog for services tests
-
::: anta.tests.services
options:
show_root_heading: false
show_root_toc_entry: false
+ show_bases: false
merge_init_into_class: false
+ anta_hide_test_module_description: true
+ show_labels: true
+ filters:
+ - "!test"
+ - "!render"
diff --git a/docs/api/tests.snmp.md b/docs/api/tests.snmp.md
index a015d04..be2da48 100644
--- a/docs/api/tests.snmp.md
+++ b/docs/api/tests.snmp.md
@@ -1,13 +1,20 @@
+---
+anta_title: ANTA catalog for SNMP tests
+---
<!--
~ Copyright (c) 2023-2024 Arista Networks, Inc.
~ Use of this source code is governed by the Apache License 2.0
~ that can be found in the LICENSE file.
-->
-# ANTA catalog for SNMP tests
-
::: anta.tests.snmp
options:
show_root_heading: false
show_root_toc_entry: false
+ show_bases: false
merge_init_into_class: false
+ anta_hide_test_module_description: true
+ show_labels: true
+ filters:
+ - "!test"
+ - "!render"
diff --git a/docs/api/tests.software.md b/docs/api/tests.software.md
index 7a2f0ec..7600476 100644
--- a/docs/api/tests.software.md
+++ b/docs/api/tests.software.md
@@ -1,13 +1,20 @@
+---
+anta_title: ANTA catalog for Software tests
+---
<!--
~ Copyright (c) 2023-2024 Arista Networks, Inc.
~ Use of this source code is governed by the Apache License 2.0
~ that can be found in the LICENSE file.
-->
-# ANTA catalog for software tests
-
::: anta.tests.software
options:
show_root_heading: false
show_root_toc_entry: false
+ show_bases: false
merge_init_into_class: false
+ anta_hide_test_module_description: true
+ show_labels: true
+ filters:
+ - "!test"
+ - "!render"
diff --git a/docs/api/tests.stp.md b/docs/api/tests.stp.md
index f86dac4..50a004b 100644
--- a/docs/api/tests.stp.md
+++ b/docs/api/tests.stp.md
@@ -1,13 +1,20 @@
+---
+anta_title: ANTA catalog for STP tests
+---
<!--
~ Copyright (c) 2023-2024 Arista Networks, Inc.
~ Use of this source code is governed by the Apache License 2.0
~ that can be found in the LICENSE file.
-->
-# ANTA catalog for STP tests
-
::: anta.tests.stp
options:
show_root_heading: false
show_root_toc_entry: false
+ show_bases: false
merge_init_into_class: false
+ anta_hide_test_module_description: true
+ show_labels: true
+ filters:
+ - "!test"
+ - "!render"
diff --git a/docs/api/tests.stun.md b/docs/api/tests.stun.md
new file mode 100644
index 0000000..b4274e9
--- /dev/null
+++ b/docs/api/tests.stun.md
@@ -0,0 +1,20 @@
+---
+anta_title: ANTA catalog for STUN tests
+---
+<!--
+ ~ Copyright (c) 2023-2024 Arista Networks, Inc.
+ ~ Use of this source code is governed by the Apache License 2.0
+ ~ that can be found in the LICENSE file.
+ -->
+
+::: anta.tests.stun
+ options:
+ show_root_heading: false
+ show_root_toc_entry: false
+ show_bases: false
+ merge_init_into_class: false
+ anta_hide_test_module_description: true
+ show_labels: true
+ filters:
+ - "!test"
+ - "!render"
diff --git a/docs/api/tests.system.md b/docs/api/tests.system.md
index 621c17b..5dcfbc0 100644
--- a/docs/api/tests.system.md
+++ b/docs/api/tests.system.md
@@ -1,13 +1,20 @@
+---
+anta_title: ANTA catalog for System tests
+---
<!--
~ Copyright (c) 2023-2024 Arista Networks, Inc.
~ Use of this source code is governed by the Apache License 2.0
~ that can be found in the LICENSE file.
-->
-# ANTA catalog for system tests
-
::: anta.tests.system
options:
show_root_heading: false
show_root_toc_entry: false
+ show_bases: false
merge_init_into_class: false
+ show_labels: true
+ anta_hide_test_module_description: true
+ filters:
+ - "!test"
+ - "!render"
diff --git a/docs/api/tests.vlan.md b/docs/api/tests.vlan.md
index 0e1aa15..74cb003 100644
--- a/docs/api/tests.vlan.md
+++ b/docs/api/tests.vlan.md
@@ -1,13 +1,20 @@
+---
+anta_title: ANTA catalog for VLAN tests
+---
<!--
~ Copyright (c) 2023-2024 Arista Networks, Inc.
~ Use of this source code is governed by the Apache License 2.0
~ that can be found in the LICENSE file.
-->
-# ANTA catalog for vlan tests
-
::: anta.tests.vlan
options:
show_root_heading: false
show_root_toc_entry: false
+ show_bases: false
merge_init_into_class: false
+ show_labels: true
+ anta_hide_test_module_description: true
+ filters:
+ - "!test"
+ - "!render"
diff --git a/docs/api/tests.vxlan.md b/docs/api/tests.vxlan.md
index a4dcff3..4c3859a 100644
--- a/docs/api/tests.vxlan.md
+++ b/docs/api/tests.vxlan.md
@@ -1,13 +1,20 @@
+---
+anta_title: ANTA catalog for VXLAN tests
+---
<!--
~ Copyright (c) 2023-2024 Arista Networks, Inc.
~ Use of this source code is governed by the Apache License 2.0
~ that can be found in the LICENSE file.
-->
-# ANTA catalog for VXLAN tests
-
::: anta.tests.vxlan
options:
show_root_heading: false
show_root_toc_entry: false
+ show_bases: false
merge_init_into_class: false
+ show_labels: true
+ anta_hide_test_module_description: true
+ filters:
+ - "!test"
+ - "!render"
diff --git a/docs/cli/debug.md b/docs/cli/debug.md
index 1743c7a..db5f496 100644
--- a/docs/cli/debug.md
+++ b/docs/cli/debug.md
@@ -23,10 +23,9 @@ You can use the `run-cmd` entrypoint to run a command, which includes the follow
### Command overview
```bash
-$ anta debug run-cmd --help
Usage: anta debug run-cmd [OPTIONS]
- Run arbitrary command to an ANTA device
+ Run arbitrary command to an ANTA device.
Options:
-u, --username TEXT Username to connect to EOS [env var:
@@ -44,16 +43,17 @@ Options:
ANTA_ENABLE]
-P, --prompt Prompt for passwords if they are not provided.
[env var: ANTA_PROMPT]
- --timeout INTEGER Global connection timeout [env var: ANTA_TIMEOUT;
- default: 30]
- --insecure Disable SSH Host Key validation [env var:
+ --timeout FLOAT Global API timeout. This value will be used for
+ all devices. [env var: ANTA_TIMEOUT; default:
+ 30.0]
+ --insecure Disable SSH Host Key validation. [env var:
ANTA_INSECURE]
- --disable-cache Disable cache globally [env var:
+ --disable-cache Disable cache globally. [env var:
ANTA_DISABLE_CACHE]
- -i, --inventory FILE Path to the inventory YAML file [env var:
+ -i, --inventory FILE Path to the inventory YAML file. [env var:
ANTA_INVENTORY; required]
- -t, --tags TEXT List of tags using comma as separator:
- tag1,tag2,tag3 [env var: ANTA_TAGS]
+ --tags TEXT List of tags using comma as separator:
+ tag1,tag2,tag3. [env var: ANTA_TAGS]
--ofmt [json|text] EOS eAPI format to use. can be text or json
-v, --version [1|latest] EOS eAPI version
-r, --revision INTEGER eAPI command revision
@@ -90,15 +90,15 @@ The `run-template` entrypoint allows the user to provide an [`f-string`](https:/
### Command overview
```bash
-$ anta debug run-template --help
Usage: anta debug run-template [OPTIONS] PARAMS...
Run arbitrary templated command to an ANTA device.
Takes a list of arguments (keys followed by a value) to build a dictionary
- used as template parameters. Example:
+ used as template parameters.
- anta debug run-template -d leaf1a -t 'show vlan {vlan_id}' vlan_id 1
+ Example: ------- anta debug run-template -d leaf1a -t 'show vlan {vlan_id}'
+ vlan_id 1
Options:
-u, --username TEXT Username to connect to EOS [env var:
@@ -116,16 +116,17 @@ Options:
ANTA_ENABLE]
-P, --prompt Prompt for passwords if they are not provided.
[env var: ANTA_PROMPT]
- --timeout INTEGER Global connection timeout [env var: ANTA_TIMEOUT;
- default: 30]
- --insecure Disable SSH Host Key validation [env var:
+ --timeout FLOAT Global API timeout. This value will be used for
+ all devices. [env var: ANTA_TIMEOUT; default:
+ 30.0]
+ --insecure Disable SSH Host Key validation. [env var:
ANTA_INSECURE]
- --disable-cache Disable cache globally [env var:
+ --disable-cache Disable cache globally. [env var:
ANTA_DISABLE_CACHE]
- -i, --inventory FILE Path to the inventory YAML file [env var:
+ -i, --inventory FILE Path to the inventory YAML file. [env var:
ANTA_INVENTORY; required]
- -t, --tags TEXT List of tags using comma as separator:
- tag1,tag2,tag3 [env var: ANTA_TAGS]
+ --tags TEXT List of tags using comma as separator:
+ tag1,tag2,tag3. [env var: ANTA_TAGS]
--ofmt [json|text] EOS eAPI format to use. can be text or json
-v, --version [1|latest] EOS eAPI version
-r, --revision INTEGER eAPI command revision
diff --git a/docs/cli/exec.md b/docs/cli/exec.md
index fe39c12..061a19e 100644
--- a/docs/cli/exec.md
+++ b/docs/cli/exec.md
@@ -31,10 +31,9 @@ This command clears interface counters on EOS devices specified in your inventor
### Command overview
```bash
-anta exec clear-counters --help
Usage: anta exec clear-counters [OPTIONS]
- Clear counter statistics on EOS devices
+ Clear counter statistics on EOS devices.
Options:
-u, --username TEXT Username to connect to EOS [env var: ANTA_USERNAME;
@@ -50,16 +49,16 @@ Options:
a command to the device. [env var: ANTA_ENABLE]
-P, --prompt Prompt for passwords if they are not provided. [env
var: ANTA_PROMPT]
- --timeout INTEGER Global connection timeout [env var: ANTA_TIMEOUT;
- default: 30]
- --insecure Disable SSH Host Key validation [env var:
+ --timeout FLOAT Global API timeout. This value will be used for all
+ devices. [env var: ANTA_TIMEOUT; default: 30.0]
+ --insecure Disable SSH Host Key validation. [env var:
ANTA_INSECURE]
- --disable-cache Disable cache globally [env var:
+ --disable-cache Disable cache globally. [env var:
ANTA_DISABLE_CACHE]
- -i, --inventory FILE Path to the inventory YAML file [env var:
+ -i, --inventory FILE Path to the inventory YAML file. [env var:
ANTA_INVENTORY; required]
- -t, --tags TEXT List of tags using comma as separator:
- tag1,tag2,tag3 [env var: ANTA_TAGS]
+ --tags TEXT List of tags using comma as separator:
+ tag1,tag2,tag3. [env var: ANTA_TAGS]
--help Show this message and exit.
```
@@ -84,10 +83,9 @@ This command collects all the commands specified in a commands-list file, which
### Command overview
```bash
-anta exec snapshot --help
Usage: anta exec snapshot [OPTIONS]
- Collect commands output from devices in inventory
+ Collect commands output from devices in inventory.
Options:
-u, --username TEXT Username to connect to EOS [env var:
@@ -105,21 +103,22 @@ Options:
ANTA_ENABLE]
-P, --prompt Prompt for passwords if they are not provided.
[env var: ANTA_PROMPT]
- --timeout INTEGER Global connection timeout [env var: ANTA_TIMEOUT;
- default: 30]
- --insecure Disable SSH Host Key validation [env var:
+ --timeout FLOAT Global API timeout. This value will be used for
+ all devices. [env var: ANTA_TIMEOUT; default:
+ 30.0]
+ --insecure Disable SSH Host Key validation. [env var:
ANTA_INSECURE]
- --disable-cache Disable cache globally [env var:
+ --disable-cache Disable cache globally. [env var:
ANTA_DISABLE_CACHE]
- -i, --inventory FILE Path to the inventory YAML file [env var:
+ -i, --inventory FILE Path to the inventory YAML file. [env var:
ANTA_INVENTORY; required]
- -t, --tags TEXT List of tags using comma as separator:
- tag1,tag2,tag3 [env var: ANTA_TAGS]
+ --tags TEXT List of tags using comma as separator:
+ tag1,tag2,tag3. [env var: ANTA_TAGS]
-c, --commands-list FILE File with list of commands to collect [env var:
ANTA_EXEC_SNAPSHOT_COMMANDS_LIST; required]
-o, --output DIRECTORY Directory to save commands output. [env var:
ANTA_EXEC_SNAPSHOT_OUTPUT; default:
- anta_snapshot_2023-12-06_09_22_11]
+ anta_snapshot_2024-04-09_15_56_19]
--help Show this message and exit.
```
@@ -203,10 +202,9 @@ For Network Readiness for Use (NRFU) tests and to keep a comprehensive report of
### Command overview
```bash
-anta exec collect-tech-support --help
Usage: anta exec collect-tech-support [OPTIONS]
- Collect scheduled tech-support from EOS devices
+ Collect scheduled tech-support from EOS devices.
Options:
-u, --username TEXT Username to connect to EOS [env var: ANTA_USERNAME;
@@ -222,16 +220,16 @@ Options:
a command to the device. [env var: ANTA_ENABLE]
-P, --prompt Prompt for passwords if they are not provided. [env
var: ANTA_PROMPT]
- --timeout INTEGER Global connection timeout [env var: ANTA_TIMEOUT;
- default: 30]
- --insecure Disable SSH Host Key validation [env var:
+ --timeout FLOAT Global API timeout. This value will be used for all
+ devices. [env var: ANTA_TIMEOUT; default: 30.0]
+ --insecure Disable SSH Host Key validation. [env var:
ANTA_INSECURE]
- --disable-cache Disable cache globally [env var:
+ --disable-cache Disable cache globally. [env var:
ANTA_DISABLE_CACHE]
- -i, --inventory FILE Path to the inventory YAML file [env var:
+ -i, --inventory FILE Path to the inventory YAML file. [env var:
ANTA_INVENTORY; required]
- -t, --tags TEXT List of tags using comma as separator:
- tag1,tag2,tag3 [env var: ANTA_TAGS]
+ --tags TEXT List of tags using comma as separator:
+ tag1,tag2,tag3. [env var: ANTA_TAGS]
-o, --output PATH Path for test catalog [default: ./tech-support]
--latest INTEGER Number of scheduled show-tech to retrieve
--configure Ensure devices have 'aaa authorization exec default
diff --git a/docs/cli/get-inventory-information.md b/docs/cli/get-inventory-information.md
index 70100fe..1831484 100644
--- a/docs/cli/get-inventory-information.md
+++ b/docs/cli/get-inventory-information.md
@@ -72,7 +72,6 @@ As most of ANTA's commands accommodate tag filtering, this particular command is
### Command overview
```bash
-anta get tags --help
Usage: anta get tags [OPTIONS]
Get list of configured tags in user inventory.
@@ -91,16 +90,16 @@ Options:
a command to the device. [env var: ANTA_ENABLE]
-P, --prompt Prompt for passwords if they are not provided. [env
var: ANTA_PROMPT]
- --timeout INTEGER Global connection timeout [env var: ANTA_TIMEOUT;
- default: 30]
- --insecure Disable SSH Host Key validation [env var:
+ --timeout FLOAT Global API timeout. This value will be used for all
+ devices. [env var: ANTA_TIMEOUT; default: 30.0]
+ --insecure Disable SSH Host Key validation. [env var:
ANTA_INSECURE]
- --disable-cache Disable cache globally [env var:
+ --disable-cache Disable cache globally. [env var:
ANTA_DISABLE_CACHE]
- -i, --inventory FILE Path to the inventory YAML file [env var:
+ -i, --inventory FILE Path to the inventory YAML file. [env var:
ANTA_INVENTORY; required]
- -t, --tags TEXT List of tags using comma as separator:
- tag1,tag2,tag3 [env var: ANTA_TAGS]
+ --tags TEXT List of tags using comma as separator:
+ tag1,tag2,tag3. [env var: ANTA_TAGS]
--help Show this message and exit.
```
@@ -132,7 +131,6 @@ This command will list all devices available in the inventory. Using the `--tags
### Command overview
```bash
-anta get inventory --help
Usage: anta get inventory [OPTIONS]
Show inventory loaded in ANTA.
@@ -153,16 +151,17 @@ Options:
var: ANTA_ENABLE]
-P, --prompt Prompt for passwords if they are not
provided. [env var: ANTA_PROMPT]
- --timeout INTEGER Global connection timeout [env var:
- ANTA_TIMEOUT; default: 30]
- --insecure Disable SSH Host Key validation [env var:
+ --timeout FLOAT Global API timeout. This value will be used
+ for all devices. [env var: ANTA_TIMEOUT;
+ default: 30.0]
+ --insecure Disable SSH Host Key validation. [env var:
ANTA_INSECURE]
- --disable-cache Disable cache globally [env var:
+ --disable-cache Disable cache globally. [env var:
ANTA_DISABLE_CACHE]
- -i, --inventory FILE Path to the inventory YAML file [env var:
+ -i, --inventory FILE Path to the inventory YAML file. [env var:
ANTA_INVENTORY; required]
- -t, --tags TEXT List of tags using comma as separator:
- tag1,tag2,tag3 [env var: ANTA_TAGS]
+ --tags TEXT List of tags using comma as separator:
+ tag1,tag2,tag3. [env var: ANTA_TAGS]
--connected / --not-connected Display inventory after connection has been
created
--help Show this message and exit.
diff --git a/docs/cli/inv-from-ansible.md b/docs/cli/inv-from-ansible.md
index bb944d4..b2672e2 100644
--- a/docs/cli/inv-from-ansible.md
+++ b/docs/cli/inv-from-ansible.md
@@ -14,17 +14,28 @@ In large setups, it might be beneficial to construct your inventory based on you
$ anta get from-ansible --help
Usage: anta get from-ansible [OPTIONS]
- Build ANTA inventory from an ansible inventory YAML file
+ Build ANTA inventory from an ansible inventory YAML file.
+
+ NOTE: This command does not support inline vaulted variables. Make sure to
+ comment them out.
Options:
- -g, --ansible-group TEXT Ansible group to filter
- --ansible-inventory FILENAME
- Path to your ansible inventory file to read
- -o, --output FILENAME Path to save inventory file
- -d, --inventory-directory PATH Directory to save inventory file
- --help Show this message and exit.
+ -o, --output FILE Path to save inventory file [env var:
+ ANTA_INVENTORY; required]
+ --overwrite Do not prompt when overriding current inventory
+ [env var: ANTA_GET_FROM_ANSIBLE_OVERWRITE]
+ -g, --ansible-group TEXT Ansible group to filter
+ --ansible-inventory FILE Path to your ansible inventory file to read
+ [required]
+ --help Show this message and exit.
```
+!!! warning
+
+ `anta get from-ansible` does not support inline vaulted variables, comment them out to generate your inventory.
+ If the vaulted variable is necessary to build the inventory (e.g. `ansible_host`), it needs to be unvaulted for `from-ansible` command to work."
+
+
The output is an inventory where the name of the container is added as a tag for each host:
```yaml
@@ -39,7 +50,7 @@ anta_inventory:
```
!!! warning
- The current implementation only considers devices directly attached to a specific Ansible group and does not support inheritence when using the `--ansible-group` option.
+ The current implementation only considers devices directly attached to a specific Ansible group and does not support inheritance when using the `--ansible-group` option.
By default, if user does not provide `--output` file, anta will save output to configured anta inventory (`anta --inventory`). If the output file has content, anta will ask user to overwrite when running in interactive console. This mechanism can be controlled by triggers in case of CI usage: `--overwrite` to force anta to overwrite file. If not set, anta will exit
diff --git a/docs/cli/nrfu.md b/docs/cli/nrfu.md
index 6dcc393..76605cb 100644
--- a/docs/cli/nrfu.md
+++ b/docs/cli/nrfu.md
@@ -13,51 +13,10 @@ ANTA provides a set of commands for performing NRFU tests on devices. These comm
- [JSON view](#performing-nrfu-with-json-rendering)
- [Custom template view](#performing-nrfu-with-custom-reports)
-### NRFU Command overview
+## NRFU Command overview
```bash
-anta nrfu --help
-Usage: anta nrfu [OPTIONS] COMMAND [ARGS]...
-
- Run NRFU against inventory devices
-
-Options:
- -u, --username TEXT Username to connect to EOS [env var: ANTA_USERNAME;
- required]
- -p, --password TEXT Password to connect to EOS that must be provided. It
- can be prompted using '--prompt' option. [env var:
- ANTA_PASSWORD]
- --enable-password TEXT Password to access EOS Privileged EXEC mode. It can
- be prompted using '--prompt' option. Requires '--
- enable' option. [env var: ANTA_ENABLE_PASSWORD]
- --enable Some commands may require EOS Privileged EXEC mode.
- This option tries to access this mode before sending
- a command to the device. [env var: ANTA_ENABLE]
- -P, --prompt Prompt for passwords if they are not provided. [env
- var: ANTA_PROMPT]
- --timeout INTEGER Global connection timeout [env var: ANTA_TIMEOUT;
- default: 30]
- --insecure Disable SSH Host Key validation [env var:
- ANTA_INSECURE]
- --disable-cache Disable cache globally [env var:
- ANTA_DISABLE_CACHE]
- -i, --inventory FILE Path to the inventory YAML file [env var:
- ANTA_INVENTORY; required]
- -t, --tags TEXT List of tags using comma as separator:
- tag1,tag2,tag3 [env var: ANTA_TAGS]
- -c, --catalog FILE Path to the test catalog YAML file [env var:
- ANTA_CATALOG; required]
- --ignore-status Always exit with success [env var:
- ANTA_NRFU_IGNORE_STATUS]
- --ignore-error Only report failures and not errors [env var:
- ANTA_NRFU_IGNORE_ERROR]
- --help Show this message and exit.
-
-Commands:
- json ANTA command to check network state with JSON result
- table ANTA command to check network states with table result
- text ANTA command to check network states with text result
- tpl-report ANTA command to check network state with templated report
+--8<-- "anta_nrfu_help.txt"
```
> `username`, `password`, `enable-password`, `enable`, `timeout` and `insecure` values are the same for all devices
@@ -67,7 +26,7 @@ All commands under the `anta nrfu` namespace require a catalog yaml file specifi
!!! info
Issuing the command `anta nrfu` will run `anta nrfu table` without any option.
-## Tag management
+### Tag management
The `--tags` option can be used to target specific devices in your inventory and run only tests configured with this specific tags from your catalog. The default tag is set to `all` and is implicit. Expected behaviour is provided below:
@@ -80,6 +39,14 @@ The `--tags` option can be used to target specific devices in your inventory and
!!! info
[More examples](tag-management.md) available on this dedicated page.
+### Device and test filtering
+
+Options `--device` and `--test` can be used to target one or multiple devices and/or tests to run in your environment. The options can be repeated. Example: `anta nrfu --device leaf1a --device leaf1b --test VerifyUptime --test VerifyReloadCause`.
+
+### Hide results
+
+Option `--hide` can be used to hide test results in the output based on their status. The option can be repeated. Example: `anta nrfu --hide error --hide skipped`.
+
## Performing NRFU with text rendering
The `text` subcommand provides a straightforward text report for each test executed on all devices in your inventory.
@@ -87,25 +54,18 @@ The `text` subcommand provides a straightforward text report for each test execu
### Command overview
```bash
-anta nrfu text --help
Usage: anta nrfu text [OPTIONS]
- ANTA command to check network states with text result
+ ANTA command to check network states with text result.
Options:
- -s, --search TEXT Regular expression to search in both name and test
- --skip-error Hide tests in errors due to connectivity issue
- --help Show this message and exit.
+ --help Show this message and exit.
```
-The `--search` option permits filtering based on a regular expression pattern in both the hostname and the test name.
-
-The `--skip-error` option can be used to exclude tests that failed due to connectivity issues or unsupported commands.
-
### Example
```bash
-anta nrfu text --tags LEAF --search DC1-LEAF1A
+anta nrfu --device DC1-LEAF1A text
```
[![anta nrfu text results](../imgs/anta-nrfu-text-output.png){ loading=lazy width="1600" }](../imgs/anta-nrfu-text-output.png)
@@ -116,20 +76,15 @@ The `table` command under the `anta nrfu` namespace offers a clear and organized
### Command overview
```bash
-anta nrfu table --help
Usage: anta nrfu table [OPTIONS]
- ANTA command to check network states with table result
+ ANTA command to check network states with table result.
Options:
- -d, --device TEXT Show a summary for this device
- -t, --test TEXT Show a summary for this test
- --group-by [device|test] Group result by test or host. default none
+ --group-by [device|test] Group result by test or device.
--help Show this message and exit.
```
-The `--device` and `--test` options show a summarized view of the test results for a specific host or test case, respectively.
-
The `--group-by` option show a summarized view of the test results per host or per test.
### Examples
@@ -154,12 +109,12 @@ anta nrfu table --group-by test
To get more specific information, it is possible to filter on a single device or a single test:
```bash
-anta nrfu table --device spine1
+anta nrfu --device spine1 table
```
[![anta nrfu table filter_host_output](../imgs/anta-nrfu-table-filter-host-output.png){ loading=lazy width="1600" }](../imgs/anta-nrfu-table-filter-host-output.png)
```bash
-anta nrfu table --test VerifyZeroTouch
+anta nrfu --test VerifyZeroTouch table
```
[![anta nrfu table filter_test_output](../imgs/anta-nrfu-table-filter-test-output.png){ loading=lazy width="1600" }](../imgs/anta-nrfu-table-filter-test-output.png)
@@ -173,7 +128,7 @@ The JSON rendering command in NRFU testing is useful in generating a JSON output
anta nrfu json --help
Usage: anta nrfu json [OPTIONS]
- ANTA command to check network state with JSON result
+ ANTA command to check network state with JSON result.
Options:
-o, --output FILE Path to save report as a file [env var:
@@ -218,7 +173,7 @@ The `--output` option allows you to choose the path where the final report will
```bash
anta nrfu --tags LEAF tpl-report --template ./custom_template.j2
```
-[![anta nrfu json results](../imgs/anta-nrfu-tpl-report-output.png){ loading=lazy width="1600" }](../imgs/anta-nrfu-tpl-report-output.png)
+[![anta nrfu tpl_resultss](../imgs/anta-nrfu-tpl-report-output.png){ loading=lazy width="1600" }](../imgs/anta-nrfu-tpl-report-output.png)
The template `./custom_template.j2` is a simple Jinja2 template:
@@ -245,3 +200,9 @@ cat nrfu-tpl-report.txt
* VerifyMlagConfigSanity is [green]SUCCESS[/green] for DC1-LEAF1A
* VerifyMlagReloadDelay is [green]SUCCESS[/green] for DC1-LEAF1A
```
+
+## Dry-run mode
+
+It is possible to run `anta nrfu --dry-run` to execute ANTA up to the point where it should communicate with the network to execute the tests. When using `--dry-run`, all inventory devices are assumed to be online. This can be useful to check how many tests would be run using the catalog and inventory.
+
+[![anta nrfu dry_run](../imgs/anta_nrfu___dry_run.svg){ loading=lazy width="1600" }](../imgs/anta_nrfu___dry_run.svg)
diff --git a/docs/cli/overview.md b/docs/cli/overview.md
index 90e70a5..107976a 100644
--- a/docs/cli/overview.md
+++ b/docs/cli/overview.md
@@ -12,9 +12,6 @@ ANTA can also be used as a Python library, allowing you to build your own tools
To start using the ANTA CLI, open your terminal and type `anta`.
-!!! warning
- The ANTA CLI options have changed after version 0.11 and have moved away from the top level `anta` and are now required at their respective commands (e.g. `anta nrfu`). This breaking change occurs after users feedback on making the CLI more intuitive. This change should not affect user experience when using environment variables.
-
## Invoking ANTA CLI
```bash
@@ -22,7 +19,7 @@ $ anta --help
--8<-- "anta_help.txt"
```
-## ANTA environement variables
+## ANTA environment variables
Certain parameters are required and can be either passed to the ANTA CLI or set as an environment variable (ENV VAR).
@@ -48,10 +45,10 @@ anta nrfu
```
!!! note
- All environement variables may not be needed for every commands.
- Refer to `<command> --help` for the comprehensive environment varibles names.
+ All environment variables may not be needed for every commands.
+ Refer to `<command> --help` for the comprehensive environment variables names.
-Below are the environement variables usable with the `anta nrfu` command:
+Below are the environment variables usable with the `anta nrfu` command:
| Variable Name | Purpose | Required |
| ------------- | ------- |----------|
diff --git a/docs/contribution.md b/docs/contribution.md
index 49df256..cc3a1c0 100644
--- a/docs/contribution.md
+++ b/docs/contribution.md
@@ -10,9 +10,9 @@ Contribution model is based on a fork-model. Don't push to arista-netdevops-comm
To help development, open your PR as soon as possible even in draft mode. It helps other to know on what you are working on and avoid duplicate PRs.
-## Create a development environement
+## Create a development environment
-Run the following commands to create an ANTA development environement:
+Run the following commands to create an ANTA development environment:
```bash
# Clone repository
@@ -21,15 +21,17 @@ $ cd anta
# Install ANTA in editable mode and its development tools
$ pip install -e .[dev]
+# To also install the CLI
+$ pip install -e .[dev,cli]
# Verify installation
$ pip list -e
Package Version Editable project location
------- ------- -------------------------
-anta 0.13.0 /mnt/lab/projects/anta
+anta 0.15.0 /mnt/lab/projects/anta
```
-Then, [`tox`](https://tox.wiki/) is configued with few environments to run CI locally:
+Then, [`tox`](https://tox.wiki/) is configured with few environments to run CI locally:
```bash
$ tox list -d
@@ -91,17 +93,20 @@ All submodule should have its own pytest section under `tests/units/anta_tests/<
The Python modules in the `tests/units/anta_tests` folder define test parameters for AntaTest subclasses unit tests.
A generic test function is written for all unit tests in `tests.lib.anta` module.
+
The `pytest_generate_tests` function definition in `conftest.py` is called during test collection.
+
The `pytest_generate_tests` function will parametrize the generic test function based on the `DATA` data structure defined in `tests.units.anta_tests` modules.
+
See https://docs.pytest.org/en/7.3.x/how-to/parametrize.html#basic-pytest-generate-tests-example
-The `DATA` structure is a list of dictionaries used to parametrize the test.
-The list elements have the following keys:
-- `name` (str): Test name as displayed by Pytest.
-- `test` (AntaTest): An AntaTest subclass imported in the test module - e.g. VerifyUptime.
-- `eos_data` (list[dict]): List of data mocking EOS returned data to be passed to the test.
-- `inputs` (dict): Dictionary to instantiate the `test` inputs as defined in the class from `test`.
-- `expected` (dict): Expected test result structure, a dictionary containing a key
+The `DATA` structure is a list of dictionaries used to parametrize the test. The list elements have the following keys:
+
+ - `name` (str): Test name as displayed by Pytest.
+ - `test` (AntaTest): An AntaTest subclass imported in the test module - e.g. VerifyUptime.
+ - `eos_data` (list[dict]): List of data mocking EOS returned data to be passed to the test.
+ - `inputs` (dict): Dictionary to instantiate the `test` inputs as defined in the class from `test`.
+ - `expected` (dict): Expected test result structure, a dictionary containing a key
`result` containing one of the allowed status (`Literal['success', 'failure', 'unset', 'skipped', 'error']`) and optionally a key `messages` which is a list(str) and each message is expected to be a substring of one of the actual messages in the TestResult object.
@@ -219,7 +224,7 @@ Image will be generated under `docs/imgs/uml/` and can be inserted in your docum
Writing documentation is crucial but managing links can be cumbersome. To be sure there is no dead links, you can use [`muffet`](https://github.com/raviqqe/muffet) with the following command:
```bash
-muffet -c 2 --color=always http://127.0.0.1:8000 -e fonts.gstatic.com
+muffet -c 2 --color=always http://127.0.0.1:8000 -e fonts.gstatic.com -b 8192
```
## Continuous Integration
diff --git a/docs/faq.md b/docs/faq.md
index 7c995ac..c71d1c6 100644
--- a/docs/faq.md
+++ b/docs/faq.md
@@ -1,67 +1,129 @@
+---
+toc_depth: 2
+---
<!--
~ Copyright (c) 2023-2024 Arista Networks, Inc.
~ Use of this source code is governed by the Apache License 2.0
~ that can be found in the LICENSE file.
-->
+<style>
+ .md-typeset h2 {
+ visibility: hidden;
+ font-size: 0em;
+ height: 0em;
+ line-height: 0;
+ padding: 0;
+ margin: 0;
+ }
+ .md-typeset details {
+ margin-top: 0em;
+ margin-bottom: 0.8em;
+ }
+</style>
# Frequently Asked Questions (FAQ)
-## Why am I seeing an `ImportError` related to `urllib3` when running ANTA?
+## A local OS error occurred while connecting to a device
+???+ faq "A local OS error occurred while connecting to a device"
-When running the `anta --help` command, some users might encounter the following error:
+ When running ANTA, you can receive `A local OS error occurred while connecting to <device>` errors. The underlying [`OSError`](https://docs.python.org/3/library/exceptions.html#OSError) exception can have various reasons: `[Errno 24] Too many open files` or `[Errno 16] Device or resource busy`.
-```bash
-ImportError: urllib3 v2.0 only supports OpenSSL 1.1.1+, currently the 'ssl' module is compiled with 'OpenSSL 1.0.2k-fips 26 Jan 2017'. See: https://github.com/urllib3/urllib3/issues/2168
-```
+ This usually means that the operating system refused to open a new file descriptor (or socket) for the ANTA process. This might be due to the hard limit for open file descriptors currently set for the ANTA process.
-This error arises due to a compatibility issue between `urllib3` v2.0 and older versions of OpenSSL.
+ At startup, ANTA sets the soft limit of its process to the hard limit up to 16384. This is because the soft limit is usually 1024 and the hard limit is usually higher (depends on the system). If the hard limit of the ANTA process is still lower than the number of selected tests in ANTA, the ANTA process may request to the operating system too many file descriptors and get an error, a WARNING is displayed at startup if this is the case.
-#### How can I resolve this error?
+ ### Solution
-1. _Workaround_: Downgrade `urllib3`
+ One solution could be to raise the hard limit for the user starting the ANTA process.
+ You can get the current hard limit for a user using the command `ulimit -n -H` while logged in.
+ Create the file `/etc/security/limits.d/10-anta.conf` with the following content:
+ ```
+ <user> hard nofile <value>
+ ```
+ The `user` is the one with which the ANTA process is started.
+ The `value` is the new hard limit. The maximum value depends on the system. A hard limit of 16384 should be sufficient for ANTA to run in most high scale scenarios. After creating this file, log out the current session and log in again.
+
+
+## `Timeout` error in the logs
+???+ faq "`Timeout` error in the logs"
+
+ When running ANTA, you can receive `<Foo>Timeout` errors in the logs (could be ReadTimeout, WriteTimeout, ConnectTimeout or PoolTimeout). More details on the timeouts of the underlying library are available here: https://www.python-httpx.org/advanced/timeouts.
+
+ This might be due to the time the host on which ANTA is run takes to reach the target devices (for instance if going through firewalls, NATs, ...) or when a lot of tests are being run at the same time on a device (eAPI has a queue mechanism to avoid exhausting EOS resources because of a high number of simultaneous eAPI requests).
- If you need a quick fix, you can temporarily downgrade the `urllib3` package:
+ ### Solution
+
+ Use the `timeout` option. As an example for the `nrfu` command:
```bash
- pip3 uninstall urllib3
+ anta nrfu --enable --username username --password arista --inventory inventory.yml -c nrfu.yml --timeout 50 text
+ ```
+
+ The previous command set a couple of options for ANTA NRFU, one them being the `timeout` command, by default, when running ANTA from CLI, it is set to 30s.
+ The timeout is increased to 50s to allow ANTA to wait for API calls a little longer.
+
+## `ImportError` related to `urllib3`
+???+ faq "`ImportError` related to `urllib3` when running ANTA"
+
+
+ When running the `anta --help` command, some users might encounter the following error:
- pip3 install urllib3==1.26.15
+ ```bash
+ ImportError: urllib3 v2.0 only supports OpenSSL 1.1.1+, currently the 'ssl' module is compiled with 'OpenSSL 1.0.2k-fips 26 Jan 2017'. See: https://github.com/urllib3/urllib3/issues/2168
```
-2. _Recommended_: Upgrade System or Libraries:
+ This error arises due to a compatibility issue between `urllib3` v2.0 and older versions of OpenSSL.
+
+ ### Solution
+
+ 1. _Workaround_: Downgrade `urllib3`
- As per the [urllib3 v2 migration guide](https://urllib3.readthedocs.io/en/latest/v2-migration-guide.html), the root cause of this error is an incompatibility with older OpenSSL versions. For example, users on RHEL7 might consider upgrading to RHEL8, which supports the required OpenSSL version.
+ If you need a quick fix, you can temporarily downgrade the `urllib3` package:
-## Why am I seeing `AttributeError: module 'lib' has no attribute 'OpenSSL_add_all_algorithms'` when running ANTA
+ ```bash
+ pip3 uninstall urllib3
-When running the `anta` commands after installation, some users might encounter the following error:
+ pip3 install urllib3==1.26.15
+ ```
-```bash
-AttributeError: module 'lib' has no attribute 'OpenSSL_add_all_algorithms'
-```
+ 2. _Recommended_: Upgrade System or Libraries:
-The error is a result of incompatibility between `cryptography` and `pyopenssl` when installing `asyncssh` which is a requirement of ANTA.
+ As per the [urllib3 v2 migration guide](https://urllib3.readthedocs.io/en/latest/v2-migration-guide.html), the root cause of this error is an incompatibility with older OpenSSL versions. For example, users on RHEL7 might consider upgrading to RHEL8, which supports the required OpenSSL version.
-#### How can I resolve this error?
+##`AttributeError: module 'lib' has no attribute 'OpenSSL_add_all_algorithms'`
+???+ faq "`AttributeError: module 'lib' has no attribute 'OpenSSL_add_all_algorithms'` when running ANTA"
-1. Upgrade `pyopenssl`
+
+ When running the `anta` commands after installation, some users might encounter the following error:
```bash
- pip install -U pyopenssl>22.0
+ AttributeError: module 'lib' has no attribute 'OpenSSL_add_all_algorithms'
```
+ The error is a result of incompatibility between `cryptography` and `pyopenssl` when installing `asyncssh` which is a requirement of ANTA.
+
+ ### Solution
+
+ 1. Upgrade `pyopenssl`
+
+ ```bash
+ pip install -U pyopenssl>22.0
+ ```
+
## `__NSCFConstantString initialize` error on OSX
+???+ faq "`__NSCFConstantString initialize` error on OSX"
-This error occurs because of added security to restrict multithreading in macOS High Sierra and later versions of macOS. https://www.wefearchange.org/2018/11/forkmacos.rst.html
-#### How can I resolve this error?
+ This error occurs because of added security to restrict multithreading in macOS High Sierra and later versions of macOS. https://www.wefearchange.org/2018/11/forkmacos.rst.html
-1. Set the following environment variable
+ ### Solution
- ```bash
- export OBJC_DISABLE_INITIALIZE_FORK_SAFETY=YES
- ```
+ 1. Set the following environment variable
+
+ ```bash
+ export OBJC_DISABLE_INITIALIZE_FORK_SAFETY=YES
+ ```
-## Still facing issues?
+# Still facing issues?
-If you've tried the above solutions and continue to experience problems, please report the issue in our [GitHub repository](https://github.com/arista-netdevops-community/anta).
+If you've tried the above solutions and continue to experience problems, please follow the [troubleshooting](troubleshooting.md) instructions and report the issue in our [GitHub repository](https://github.com/arista-netdevops-community/anta).
diff --git a/docs/getting-started.md b/docs/getting-started.md
index fd147e7..bab1cea 100644
--- a/docs/getting-started.md
+++ b/docs/getting-started.md
@@ -10,13 +10,13 @@ This section shows how to use ANTA with basic configuration. All examples are ba
## Installation
-The easiest way to intall ANTA package is to run Python (`>=3.8`) and its pip package to install:
+The easiest way to install ANTA package is to run Python (`>=3.9`) and its pip package to install:
```bash
-pip install anta
+pip install anta[cli]
```
-For more details about how to install package, please see the [requirements and intallation](./requirements-and-installation.md) section.
+For more details about how to install package, please see the [requirements and installation](./requirements-and-installation.md) section.
## Configure Arista EOS devices
@@ -121,64 +121,29 @@ anta.tests.configuration:
## Test your network
+### Basic usage in a python script
+
+```python
+--8<-- "anta_runner.py"
+```
+
+### CLI
+
ANTA comes with a generic CLI entrypoint to run tests in your network. It requires an inventory file as well as a test catalog.
This entrypoint has multiple options to manage test coverage and reporting.
```bash
-# Generic ANTA options
-$ anta
--8<-- "anta_help.txt"
```
```bash
-# NRFU part of ANTA
-Usage: anta nrfu [OPTIONS] COMMAND [ARGS]...
-
- Run ANTA tests on devices
-
-Options:
- -u, --username TEXT Username to connect to EOS [env var: ANTA_USERNAME;
- required]
- -p, --password TEXT Password to connect to EOS that must be provided. It
- can be prompted using '--prompt' option. [env var:
- ANTA_PASSWORD]
- --enable-password TEXT Password to access EOS Privileged EXEC mode. It can
- be prompted using '--prompt' option. Requires '--
- enable' option. [env var: ANTA_ENABLE_PASSWORD]
- --enable Some commands may require EOS Privileged EXEC mode.
- This option tries to access this mode before sending
- a command to the device. [env var: ANTA_ENABLE]
- -P, --prompt Prompt for passwords if they are not provided. [env
- var: ANTA_PROMPT]
- --timeout INTEGER Global connection timeout [env var: ANTA_TIMEOUT;
- default: 30]
- --insecure Disable SSH Host Key validation [env var:
- ANTA_INSECURE]
- --disable-cache Disable cache globally [env var:
- ANTA_DISABLE_CACHE]
- -i, --inventory FILE Path to the inventory YAML file [env var:
- ANTA_INVENTORY; required]
- -t, --tags TEXT List of tags using comma as separator:
- tag1,tag2,tag3 [env var: ANTA_TAGS]
- -c, --catalog FILE Path to the test catalog YAML file [env var:
- ANTA_CATALOG; required]
- --ignore-status Always exit with success [env var:
- ANTA_NRFU_IGNORE_STATUS]
- --ignore-error Only report failures and not errors [env var:
- ANTA_NRFU_IGNORE_ERROR]
- --help Show this message and exit.
-
-Commands:
- json ANTA command to check network state with JSON result
- table ANTA command to check network states with table result
- text ANTA command to check network states with text result
- tpl-report ANTA command to check network state with templated report
+--8<-- "anta_nrfu_help.txt"
```
To run the NRFU, you need to select an output format amongst ["json", "table", "text", "tpl-report"]. For a first usage, `table` is recommended. By default all test results for all devices are rendered but it can be changed to a report per test case or per host
-### Default report using table
+#### Default report using table
```bash
anta nrfu \
@@ -219,7 +184,7 @@ anta nrfu \
└───────────┴──────────────────────────┴─────────────┴──────────────────┴──────────────────────────────────────────────────────────────────────┴───────────────┘
```
-### Report in text mode
+#### Report in text mode
```bash
$ anta nrfu \
@@ -249,7 +214,7 @@ leaf01 :: VerifyMlagConfigSanity :: SKIPPED (MLAG is disabled)
[...]
```
-### Report in JSON format
+#### Report in JSON format
```bash
$ anta nrfu \
diff --git a/docs/imgs/anta-nrfu.svg b/docs/imgs/anta-nrfu.svg
index c01eabb..c9ed61b 100644
--- a/docs/imgs/anta-nrfu.svg
+++ b/docs/imgs/anta-nrfu.svg
@@ -1 +1 @@
-<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="1250" height="277.1"><rect width="1250" height="277.1" rx="5" ry="5" class="a"/><svg y="0%" x="0%"><circle cx="20" cy="20" r="6" fill="#ff5f58"/><circle cx="40" cy="20" r="6" fill="#ffbd2e"/><circle cx="60" cy="20" r="6" fill="#18c132"/></svg><svg height="217.1" viewBox="0 0 121 21.71" width="1210" x="15" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" y="50"><style>@keyframes q{0%{transform:translateX(0)}2.2%{transform:translateX(-121px)}11.3%{transform:translateX(-242px)}13.7%{transform:translateX(-363px)}15.8%{transform:translateX(-484px)}17.9%{transform:translateX(-605px)}19.9%{transform:translateX(-726px)}22.2%{transform:translateX(-847px)}23.9%{transform:translateX(-968px)}26.1%{transform:translateX(-1089px)}28.3%{transform:translateX(-1210px)}29.4%{transform:translateX(-1331px)}32.1%{transform:translateX(-1452px)}34%{transform:translateX(-1573px)}36.6%{transform:translateX(-1694px)}38.3%{transform:translateX(-1815px)}40%{transform:translateX(-1936px)}45%{transform:translateX(-2057px)}48.5%{transform:translateX(-2299px)}49.1%{transform:translateX(-2541px)}49.9%{transform:translateX(-2662px)}51.1%{transform:translateX(-2783px)}52.4%{transform:translateX(-2904px)}53.6%{transform:translateX(-3025px)}54.9%{transform:translateX(-3146px)}56.1%{transform:translateX(-3267px)}57.4%{transform:translateX(-3388px)}59%{transform:translateX(-3509px)}60.3%{transform:translateX(-3630px)}61.5%{transform:translateX(-3751px)}62.8%{transform:translateX(-3872px)}64%{transform:translateX(-3993px)}65.2%{transform:translateX(-4114px)}66.5%{transform:translateX(-4235px)}67.7%{transform:translateX(-4356px)}68.9%{transform:translateX(-4477px)}70.2%{transform:translateX(-4598px)}71.4%{transform:translateX(-4719px)}72.6%{transform:translateX(-4840px)}73.9%{transform:translateX(-4961px)}75.1%{transform:translateX(-5082px)}76.3%{transform:translateX(-5203px)}77.6%{transform:translateX(-5324px)}78.8%{transform:translateX(-5445px)}80%{transform:translateX(-5566px)}81.3%{transform:translateX(-5687px)}82.5%{transform:translateX(-5808px)}83.7%{transform:translateX(-5929px)}85%{transform:translateX(-6050px)}86.2%{transform:translateX(-6171px)}87.4%{transform:translateX(-6292px)}88.7%{transform:translateX(-6413px)}89.9%{transform:translateX(-6534px)}91.1%{transform:translateX(-6655px)}92.3%{transform:translateX(-6776px)}93.6%{transform:translateX(-6897px)}94.8%{transform:translateX(-7018px)}96%{transform:translateX(-7139px)}97.3%{transform:translateX(-7260px)}98.5%{transform:translateX(-7381px)}99.1%{transform:translateX(-7502px)}to{transform:translateX(-7623px)}}.a{fill:#282d35}.f{fill:#b9c0cb;white-space:pre}.g,.h,.i,.j,.k,.m{fill:#66c2cd;white-space:pre}.h,.i,.j,.k,.m{fill:#a8cc8c}.i,.j,.k,.m{fill:#d290e4}.j,.k,.m{fill:#3a3a3a}.k,.m{fill:#dbab79}.m{fill:#ff005f}</style><g font-family="Monaco,Consolas,Menlo,'Bitstream Vera Sans Mono','Powerline Symbols',monospace" font-size="1.67"><defs><symbol id="1"><text y="1.67" class="f">❯</text></symbol><symbol id="2"><text y="1.67" class="f">❯</text><text x="2.004" y="1.67" class="f">anta</text></symbol><symbol id="3"><text y="1.67" class="f">❯</text><text x="2.004" y="1.67" class="f">anta</text><text x="7.014" y="1.67" class="f">nrfu</text></symbol><symbol id="4"><text y="1.67" class="f">❯</text><text x="2.004" y="1.67" class="f">anta</text><text x="7.014" y="1.67" class="f">nrfu</text><text x="12.024" y="1.67" class="f">table</text></symbol><symbol id="5"><text y="1.67" class="g">╭──────────────────────</text><text x="24.048" y="1.67" class="h">Settings</text><text x="33.066" y="1.67" class="g">──────────────────────╮</text></symbol><symbol id="6"><text y="1.67" class="g">│</text><text x="2.004" y="1.67" class="g">Running</text><text x="10.02" y="1.67" class="g">ANTA</text><text x="15.03" y="1.67" class="g">tests:</text><text x="55.11" y="1.67" class="g">│</text></symbol><symbol id="7"><text y="1.67" class="g">│</text><text x="2.004" y="1.67" class="g">-</text><text x="4.008" y="1.67" class="g">ANTA</text><text x="9.018" y="1.67" class="g">Inventory</text><text x="19.038" y="1.67" class="g">contains</text><text x="28.056" y="1.67" class="g">6</text><text x="30.06" y="1.67" class="g">devices</text><text x="38.076" y="1.67" class="g">(AsyncEOSDevice)</text><text x="55.11" y="1.67" class="g">│</text></symbol><symbol id="8"><text y="1.67" class="g">│</text><text x="2.004" y="1.67" class="g">-</text><text x="4.008" y="1.67" class="g">Tests</text><text x="10.02" y="1.67" class="g">catalog</text><text x="18.036" y="1.67" class="g">contains</text><text x="27.054" y="1.67" class="g">89</text><text x="30.06" y="1.67" class="g">tests</text><text x="55.11" y="1.67" class="g">│</text></symbol><symbol id="9"><text y="1.67" class="g">╰──────────────────────────────────────────────────────╯</text></symbol><symbol id="10"><text y="1.67" class="h">(</text><text x="6.012" y="1.67" class="h">🐜)</text><text x="10.02" y="1.67" class="f">•</text><text x="12.024" y="1.67" class="f">Running</text><text x="20.04" y="1.67" class="f">NRFU</text><text x="25.05" y="1.67" class="f">Tests...</text><text x="35.07" y="1.67" class="i">0%</text><text x="38.076" y="1.67" class="j">━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━</text><text x="96.192" y="1.67" class="h">0/534</text><text x="102.204" y="1.67" class="f">•</text><text x="104.208" y="1.67" class="k">0:00:00</text><text x="112.224" y="1.67" class="f">•</text><text x="114.228" y="1.67" class="g">-:--:--</text></symbol><symbol id="11"><text y="1.67" class="g">[11:29:47]</text><text x="11.022" y="1.67" style="white-space:pre" fill="#71bef2">INFO</text><text x="20.04" y="1.67" class="f">Running</text><text x="28.056" y="1.67" class="f">ANTA</text><text x="33.066" y="1.67" class="f">tests</text><text x="38.076" y="1.67" class="k">...</text><text x="109.218" y="1.67" class="f">runner.py:71</text></symbol><symbol id="12"><text y="1.67" class="h">(</text><text x="5.01" y="1.67" class="h">🐜</text><text x="8.016" y="1.67" class="h">)</text><text x="10.02" y="1.67" class="f">•</text><text x="12.024" y="1.67" class="f">Running</text><text x="20.04" y="1.67" class="f">NRFU</text><text x="25.05" y="1.67" class="f">Tests...</text><text x="34.068" y="1.67" class="i">15%</text><text x="38.076" y="1.67" class="m">━━━━━━━━</text><text x="46.092" y="1.67" class="j">╺━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━</text><text x="95.19" y="1.67" class="h">78/534</text><text x="102.204" y="1.67" class="f">•</text><text x="104.208" y="1.67" class="k">0:00:00</text><text x="112.224" y="1.67" class="f">•</text><text x="114.228" y="1.67" class="g">0:00:01</text></symbol><symbol id="13"><text y="1.67" class="h">(</text><text x="3.006" y="1.67" class="h">🐜</text><text x="8.016" y="1.67" class="h">)</text><text x="10.02" y="1.67" class="f">•</text><text x="12.024" y="1.67" class="f">Running</text><text x="20.04" y="1.67" class="f">NRFU</text><text x="25.05" y="1.67" class="f">Tests...</text><text x="34.068" y="1.67" class="i">15%</text><text x="38.076" y="1.67" class="m">━━━━━━━━</text><text x="46.092" y="1.67" class="j">╺━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━</text><text x="95.19" y="1.67" class="h">78/534</text><text x="102.204" y="1.67" class="f">•</text><text x="104.208" y="1.67" class="k">0:00:00</text><text x="112.224" y="1.67" class="f">•</text><text x="114.228" y="1.67" class="g">0:00:01</text></symbol><symbol id="14"><text y="1.67" class="h">(</text><text x="2.004" y="1.67" class="h">🐌</text><text x="8.016" y="1.67" class="h">)</text><text x="10.02" y="1.67" class="f">•</text><text x="12.024" y="1.67" class="f">Running</text><text x="20.04" y="1.67" class="f">NRFU</text><text x="25.05" y="1.67" class="f">Tests...</text><text x="34.068" y="1.67" class="i">99%</text><text x="38.076" y="1.67" class="m">━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╸</text><text x="94.188" y="1.67" class="h">531/534</text><text x="102.204" y="1.67" class="f">•</text><text x="104.208" y="1.67" class="k">0:00:02</text><text x="112.224" y="1.67" class="f">•</text><text x="114.228" y="1.67" class="g">0:00:01</text></symbol><symbol id="15"><text y="1.67" class="h">(</text><text x="4.008" y="1.67" class="h">🐌</text><text x="8.016" y="1.67" class="h">)</text><text x="10.02" y="1.67" class="f">•</text><text x="12.024" y="1.67" class="f">Running</text><text x="20.04" y="1.67" class="f">NRFU</text><text x="25.05" y="1.67" class="f">Tests...</text><text x="34.068" y="1.67" class="i">99%</text><text x="38.076" y="1.67" class="m">━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╸</text><text x="94.188" y="1.67" class="h">531/534</text><text x="102.204" y="1.67" class="f">•</text><text x="104.208" y="1.67" class="k">0:00:03</text><text x="112.224" y="1.67" class="f">•</text><text x="114.228" y="1.67" class="g">0:00:01</text></symbol><symbol id="16"><text y="1.67" class="h">(</text><text x="6.012" y="1.67" class="h">🐌)</text><text x="10.02" y="1.67" class="f">•</text><text x="12.024" y="1.67" class="f">Running</text><text x="20.04" y="1.67" class="f">NRFU</text><text x="25.05" y="1.67" class="f">Tests...</text><text x="34.068" y="1.67" class="i">99%</text><text x="38.076" y="1.67" class="m">━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╸</text><text x="94.188" y="1.67" class="h">531/534</text><text x="102.204" y="1.67" class="f">•</text><text x="104.208" y="1.67" class="k">0:00:03</text><text x="112.224" y="1.67" class="f">•</text><text x="114.228" y="1.67" class="g">0:00:01</text></symbol><symbol id="17"><text y="1.67" class="h">(</text><text x="5.01" y="1.67" class="h">🐜</text><text x="8.016" y="1.67" class="h">)</text><text x="10.02" y="1.67" class="f">•</text><text x="12.024" y="1.67" class="f">Running</text><text x="20.04" y="1.67" class="f">NRFU</text><text x="25.05" y="1.67" class="f">Tests...</text><text x="34.068" y="1.67" class="i">99%</text><text x="38.076" y="1.67" class="m">━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╸</text><text x="94.188" y="1.67" class="h">531/534</text><text x="102.204" y="1.67" class="f">•</text><text x="104.208" y="1.67" class="k">0:00:03</text><text x="112.224" y="1.67" class="f">•</text><text x="114.228" y="1.67" class="g">0:00:01</text></symbol><symbol id="18"><text x="2.004" y="1.67" class="f">•</text><text x="4.008" y="1.67" class="f">Running</text><text x="12.024" y="1.67" class="f">NRFU</text><text x="17.034" y="1.67" class="f">Tests...</text><text x="25.05" y="1.67" class="i">100%</text><text x="30.06" y="1.67" style="white-space:pre" fill="#5faf00">━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━</text><text x="94.188" y="1.67" class="h">534/534</text><text x="102.204" y="1.67" class="f">•</text><text x="104.208" y="1.67" class="k">0:00:04</text><text x="112.224" y="1.67" class="f">•</text><text x="114.228" y="1.67" class="g">0:00:00</text></symbol><symbol id="a"><path fill="transparent" d="M0 0h121v11H0z"/></symbol><symbol id="b"><path fill="#6f7683" d="M0 0h1.102v2.171H0z"/></symbol></defs><path class="a" d="M0 0h121v21.71H0z"/><g style="animation-duration:8.22014s;animation-iteration-count:infinite;animation-name:q;animation-timing-function:steps(1,end)"><svg width="7744"><svg><use xlink:href="#a"/><use xlink:href="#b" x="-.004"/></svg><svg x="121"><use xlink:href="#a"/><use xlink:href="#b" x="1.996"/><use xlink:href="#1"/></svg><svg x="242"><use xlink:href="#a"/><use xlink:href="#b" x="2.996"/><text y="1.67" class="f">❯</text><text x="2.004" y="1.67" class="f">a</text></svg><svg x="363"><use xlink:href="#a"/><use xlink:href="#b" x="3.996"/><text y="1.67" class="f">❯</text><text x="2.004" y="1.67" class="f">an</text></svg><svg x="484"><use xlink:href="#a"/><use xlink:href="#b" x="4.996"/><text y="1.67" class="f">❯</text><text x="2.004" y="1.67" class="f">ant</text></svg><svg x="605"><use xlink:href="#a"/><use xlink:href="#b" x="5.996"/><use xlink:href="#2"/></svg><svg x="726"><use xlink:href="#a"/><use xlink:href="#b" x="6.996"/><use xlink:href="#2"/></svg><svg x="847"><use xlink:href="#a"/><use xlink:href="#b" x="7.996"/><text y="1.67" class="f">❯</text><text x="2.004" y="1.67" class="f">anta</text><text x="7.014" y="1.67" class="f">n</text></svg><svg x="968"><use xlink:href="#a"/><use xlink:href="#b" x="8.996"/><text y="1.67" class="f">❯</text><text x="2.004" y="1.67" class="f">anta</text><text x="7.014" y="1.67" class="f">nr</text></svg><svg x="1089"><use xlink:href="#a"/><use xlink:href="#b" x="9.996"/><text y="1.67" class="f">❯</text><text x="2.004" y="1.67" class="f">anta</text><text x="7.014" y="1.67" class="f">nrf</text></svg><svg x="1210"><use xlink:href="#a"/><use xlink:href="#b" x="10.996"/><use xlink:href="#3"/></svg><svg x="1331"><use xlink:href="#a"/><use xlink:href="#b" x="11.996"/><use xlink:href="#3"/></svg><svg x="1452"><use xlink:href="#a"/><use xlink:href="#b" x="12.996"/><text y="1.67" class="f">❯</text><text x="2.004" y="1.67" class="f">anta</text><text x="7.014" y="1.67" class="f">nrfu</text><text x="12.024" y="1.67" class="f">t</text></svg><svg x="1573"><use xlink:href="#a"/><use xlink:href="#b" x="13.996"/><text y="1.67" class="f">❯</text><text x="2.004" y="1.67" class="f">anta</text><text x="7.014" y="1.67" class="f">nrfu</text><text x="12.024" y="1.67" class="f">ta</text></svg><svg x="1694"><use xlink:href="#a"/><use xlink:href="#b" x="14.996"/><text y="1.67" class="f">❯</text><text x="2.004" y="1.67" class="f">anta</text><text x="7.014" y="1.67" class="f">nrfu</text><text x="12.024" y="1.67" class="f">tab</text></svg><svg x="1815"><use xlink:href="#a"/><use xlink:href="#b" x="15.996"/><text y="1.67" class="f">❯</text><text x="2.004" y="1.67" class="f">anta</text><text x="7.014" y="1.67" class="f">nrfu</text><text x="12.024" y="1.67" class="f">tabl</text></svg><svg x="1936"><use xlink:href="#a"/><use xlink:href="#b" x="16.996"/><use xlink:href="#4"/></svg><svg x="2057"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="2.146"/><use xlink:href="#4"/></svg><svg x="2178"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="13.001"/><use xlink:href="#4"/><use xlink:href="#5" y="2.171"/><use xlink:href="#6" y="4.342"/><use xlink:href="#7" y="6.513"/><use xlink:href="#8" y="8.684"/><use xlink:href="#9" y="10.855"/></svg><svg x="2299"><use xlink:href="#a"/><use xlink:href="#4"/><use xlink:href="#5" y="2.171"/><use xlink:href="#6" y="4.342"/><use xlink:href="#7" y="6.513"/><use xlink:href="#8" y="8.684"/><use xlink:href="#9" y="10.855"/></svg><svg x="2420"><use xlink:href="#a"/><use xlink:href="#4"/><use xlink:href="#5" y="2.171"/><use xlink:href="#6" y="4.342"/><use xlink:href="#7" y="6.513"/><use xlink:href="#8" y="8.684"/><use xlink:href="#9" y="10.855"/><use xlink:href="#10" y="13.026"/></svg><svg x="2541"><use xlink:href="#a"/><use xlink:href="#4"/><use xlink:href="#5" y="2.171"/><use xlink:href="#6" y="4.342"/><use xlink:href="#7" y="6.513"/><use xlink:href="#8" y="8.684"/><use xlink:href="#9" y="10.855"/><use xlink:href="#11" y="13.026"/><use xlink:href="#10" y="15.197"/></svg><svg x="2662"><use xlink:href="#a"/><use xlink:href="#4"/><use xlink:href="#5" y="2.171"/><use xlink:href="#6" y="4.342"/><use xlink:href="#7" y="6.513"/><use xlink:href="#8" y="8.684"/><use xlink:href="#9" y="10.855"/><use xlink:href="#11" y="13.026"/><text y="16.867" class="h">(</text><text x="6.012" y="16.867" class="h">🐜)</text><text x="10.02" y="16.867" class="f">•</text><text x="12.024" y="16.867" class="f">Running</text><text x="20.04" y="16.867" class="f">NRFU</text><text x="25.05" y="16.867" class="f">Tests...</text><text x="34.068" y="16.867" class="i">15%</text><text x="38.076" y="16.867" class="m">━━━━━━━━</text><text x="46.092" y="16.867" class="j">╺━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━</text><text x="95.19" y="16.867" class="h">78/534</text><text x="102.204" y="16.867" class="f">•</text><text x="104.208" y="16.867" class="k">0:00:00</text><text x="112.224" y="16.867" class="f">•</text><text x="114.228" y="16.867" class="g">0:00:01</text></svg><svg x="2783"><use xlink:href="#a"/><use xlink:href="#4"/><use xlink:href="#5" y="2.171"/><use xlink:href="#6" y="4.342"/><use xlink:href="#7" y="6.513"/><use xlink:href="#8" y="8.684"/><use xlink:href="#9" y="10.855"/><use xlink:href="#11" y="13.026"/><use xlink:href="#12" y="15.197"/></svg><svg x="2904"><use xlink:href="#a"/><use xlink:href="#4"/><use xlink:href="#5" y="2.171"/><use xlink:href="#6" y="4.342"/><use xlink:href="#7" y="6.513"/><use xlink:href="#8" y="8.684"/><use xlink:href="#9" y="10.855"/><use xlink:href="#11" y="13.026"/><use xlink:href="#12" y="15.197"/></svg><svg x="3025"><use xlink:href="#a"/><use xlink:href="#4"/><use xlink:href="#5" y="2.171"/><use xlink:href="#6" y="4.342"/><use xlink:href="#7" y="6.513"/><use xlink:href="#8" y="8.684"/><use xlink:href="#9" y="10.855"/><use xlink:href="#11" y="13.026"/><text y="16.867" class="h">(</text><text x="4.008" y="16.867" class="h">🐜</text><text x="8.016" y="16.867" class="h">)</text><text x="10.02" y="16.867" class="f">•</text><text x="12.024" y="16.867" class="f">Running</text><text x="20.04" y="16.867" class="f">NRFU</text><text x="25.05" y="16.867" class="f">Tests...</text><text x="34.068" y="16.867" class="i">15%</text><text x="38.076" y="16.867" class="m">━━━━━━━━</text><text x="46.092" y="16.867" class="j">╺━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━</text><text x="95.19" y="16.867" class="h">78/534</text><text x="102.204" y="16.867" class="f">•</text><text x="104.208" y="16.867" class="k">0:00:00</text><text x="112.224" y="16.867" class="f">•</text><text x="114.228" y="16.867" class="g">0:00:01</text></svg><svg x="3146"><use xlink:href="#a"/><use xlink:href="#4"/><use xlink:href="#5" y="2.171"/><use xlink:href="#6" y="4.342"/><use xlink:href="#7" y="6.513"/><use xlink:href="#8" y="8.684"/><use xlink:href="#9" y="10.855"/><use xlink:href="#11" y="13.026"/><use xlink:href="#13" y="15.197"/></svg><svg x="3267"><use xlink:href="#a"/><use xlink:href="#4"/><use xlink:href="#5" y="2.171"/><use xlink:href="#6" y="4.342"/><use xlink:href="#7" y="6.513"/><use xlink:href="#8" y="8.684"/><use xlink:href="#9" y="10.855"/><use xlink:href="#11" y="13.026"/><use xlink:href="#13" y="15.197"/></svg><svg x="3388"><use xlink:href="#a"/><use xlink:href="#4"/><use xlink:href="#5" y="2.171"/><use xlink:href="#6" y="4.342"/><use xlink:href="#7" y="6.513"/><use xlink:href="#8" y="8.684"/><use xlink:href="#9" y="10.855"/><use xlink:href="#11" y="13.026"/><text y="16.867" class="h">(</text><text x="2.004" y="16.867" class="h">🐜</text><text x="8.016" y="16.867" class="h">)</text><text x="10.02" y="16.867" class="f">•</text><text x="12.024" y="16.867" class="f">Running</text><text x="20.04" y="16.867" class="f">NRFU</text><text x="25.05" y="16.867" class="f">Tests...</text><text x="34.068" y="16.867" class="i">15%</text><text x="38.076" y="16.867" class="m">━━━━━━━━</text><text x="46.092" y="16.867" class="j">╺━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━</text><text x="95.19" y="16.867" class="h">78/534</text><text x="102.204" y="16.867" class="f">•</text><text x="104.208" y="16.867" class="k">0:00:00</text><text x="112.224" y="16.867" class="f">•</text><text x="114.228" y="16.867" class="g">0:00:01</text></svg><svg x="3509"><use xlink:href="#a"/><use xlink:href="#4"/><use xlink:href="#5" y="2.171"/><use xlink:href="#6" y="4.342"/><use xlink:href="#7" y="6.513"/><use xlink:href="#8" y="8.684"/><use xlink:href="#9" y="10.855"/><use xlink:href="#11" y="13.026"/><text y="16.867" class="h">(🐜</text><text x="8.016" y="16.867" class="h">)</text><text x="10.02" y="16.867" class="f">•</text><text x="12.024" y="16.867" class="f">Running</text><text x="20.04" y="16.867" class="f">NRFU</text><text x="25.05" y="16.867" class="f">Tests...</text><text x="34.068" y="16.867" class="i">15%</text><text x="38.076" y="16.867" class="m">━━━━━━━━</text><text x="46.092" y="16.867" class="j">╺━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━</text><text x="95.19" y="16.867" class="h">78/534</text><text x="102.204" y="16.867" class="f">•</text><text x="104.208" y="16.867" class="k">0:00:00</text><text x="112.224" y="16.867" class="f">•</text><text x="114.228" y="16.867" class="g">0:00:01</text></svg><svg x="3630"><use xlink:href="#a"/><use xlink:href="#4"/><use xlink:href="#5" y="2.171"/><use xlink:href="#6" y="4.342"/><use xlink:href="#7" y="6.513"/><use xlink:href="#8" y="8.684"/><use xlink:href="#9" y="10.855"/><use xlink:href="#11" y="13.026"/><text y="16.867" class="h">(🐌</text><text x="8.016" y="16.867" class="h">)</text><text x="10.02" y="16.867" class="f">•</text><text x="12.024" y="16.867" class="f">Running</text><text x="20.04" y="16.867" class="f">NRFU</text><text x="25.05" y="16.867" class="f">Tests...</text><text x="34.068" y="16.867" class="i">18%</text><text x="38.076" y="16.867" class="m">━━━━━━━━━━</text><text x="48.096" y="16.867" class="j">╺━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━</text><text x="95.19" y="16.867" class="h">98/534</text><text x="102.204" y="16.867" class="f">•</text><text x="104.208" y="16.867" class="k">0:00:00</text><text x="112.224" y="16.867" class="f">•</text><text x="114.228" y="16.867" class="g">0:00:05</text></svg><svg x="3751"><use xlink:href="#a"/><use xlink:href="#4"/><use xlink:href="#5" y="2.171"/><use xlink:href="#6" y="4.342"/><use xlink:href="#7" y="6.513"/><use xlink:href="#8" y="8.684"/><use xlink:href="#9" y="10.855"/><use xlink:href="#11" y="13.026"/><text y="16.867" class="h">(🐌</text><text x="8.016" y="16.867" class="h">)</text><text x="10.02" y="16.867" class="f">•</text><text x="12.024" y="16.867" class="f">Running</text><text x="20.04" y="16.867" class="f">NRFU</text><text x="25.05" y="16.867" class="f">Tests...</text><text x="34.068" y="16.867" class="i">35%</text><text x="38.076" y="16.867" class="m">━━━━━━━━━━━━━━━━━━━</text><text x="57.114" y="16.867" class="j">╺━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━</text><text x="94.188" y="16.867" class="h">189/534</text><text x="102.204" y="16.867" class="f">•</text><text x="104.208" y="16.867" class="k">0:00:01</text><text x="112.224" y="16.867" class="f">•</text><text x="114.228" y="16.867" class="g">0:00:02</text></svg><svg x="3872"><use xlink:href="#a"/><use xlink:href="#4"/><use xlink:href="#5" y="2.171"/><use xlink:href="#6" y="4.342"/><use xlink:href="#7" y="6.513"/><use xlink:href="#8" y="8.684"/><use xlink:href="#9" y="10.855"/><use xlink:href="#11" y="13.026"/><text y="16.867" class="h">(</text><text x="2.004" y="16.867" class="h">🐌</text><text x="8.016" y="16.867" class="h">)</text><text x="10.02" y="16.867" class="f">•</text><text x="12.024" y="16.867" class="f">Running</text><text x="20.04" y="16.867" class="f">NRFU</text><text x="25.05" y="16.867" class="f">Tests...</text><text x="34.068" y="16.867" class="i">55%</text><text x="38.076" y="16.867" class="m">━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━</text><text x="68.136" y="16.867" class="j">╺━━━━━━━━━━━━━━━━━━━━━━━━</text><text x="94.188" y="16.867" class="h">293/534</text><text x="102.204" y="16.867" class="f">•</text><text x="104.208" y="16.867" class="k">0:00:01</text><text x="112.224" y="16.867" class="f">•</text><text x="114.228" y="16.867" class="g">0:00:01</text></svg><svg x="3993"><use xlink:href="#a"/><use xlink:href="#4"/><use xlink:href="#5" y="2.171"/><use xlink:href="#6" y="4.342"/><use xlink:href="#7" y="6.513"/><use xlink:href="#8" y="8.684"/><use xlink:href="#9" y="10.855"/><use xlink:href="#11" y="13.026"/><text y="16.867" class="h">(</text><text x="3.006" y="16.867" class="h">🐌</text><text x="8.016" y="16.867" class="h">)</text><text x="10.02" y="16.867" class="f">•</text><text x="12.024" y="16.867" class="f">Running</text><text x="20.04" y="16.867" class="f">NRFU</text><text x="25.05" y="16.867" class="f">Tests...</text><text x="34.068" y="16.867" class="i">58%</text><text x="38.076" y="16.867" class="m">━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━</text><text x="70.14" y="16.867" class="j">╺━━━━━━━━━━━━━━━━━━━━━━</text><text x="94.188" y="16.867" class="h">311/534</text><text x="102.204" y="16.867" class="f">•</text><text x="104.208" y="16.867" class="k">0:00:01</text><text x="112.224" y="16.867" class="f">•</text><text x="114.228" y="16.867" class="g">0:00:01</text></svg><svg x="4114"><use xlink:href="#a"/><use xlink:href="#4"/><use xlink:href="#5" y="2.171"/><use xlink:href="#6" y="4.342"/><use xlink:href="#7" y="6.513"/><use xlink:href="#8" y="8.684"/><use xlink:href="#9" y="10.855"/><use xlink:href="#11" y="13.026"/><text y="16.867" class="h">(</text><text x="3.006" y="16.867" class="h">🐌</text><text x="8.016" y="16.867" class="h">)</text><text x="10.02" y="16.867" class="f">•</text><text x="12.024" y="16.867" class="f">Running</text><text x="20.04" y="16.867" class="f">NRFU</text><text x="25.05" y="16.867" class="f">Tests...</text><text x="34.068" y="16.867" class="i">63%</text><text x="38.076" y="16.867" class="m">━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╸</text><text x="73.146" y="16.867" class="j">━━━━━━━━━━━━━━━━━━━━</text><text x="94.188" y="16.867" class="h">335/534</text><text x="102.204" y="16.867" class="f">•</text><text x="104.208" y="16.867" class="k">0:00:01</text><text x="112.224" y="16.867" class="f">•</text><text x="114.228" y="16.867" class="g">0:00:01</text></svg><svg x="4235"><use xlink:href="#a"/><use xlink:href="#4"/><use xlink:href="#5" y="2.171"/><use xlink:href="#6" y="4.342"/><use xlink:href="#7" y="6.513"/><use xlink:href="#8" y="8.684"/><use xlink:href="#9" y="10.855"/><use xlink:href="#11" y="13.026"/><text y="16.867" class="h">(</text><text x="4.008" y="16.867" class="h">🐌</text><text x="8.016" y="16.867" class="h">)</text><text x="10.02" y="16.867" class="f">•</text><text x="12.024" y="16.867" class="f">Running</text><text x="20.04" y="16.867" class="f">NRFU</text><text x="25.05" y="16.867" class="f">Tests...</text><text x="34.068" y="16.867" class="i">67%</text><text x="38.076" y="16.867" class="m">━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━</text><text x="75.15" y="16.867" class="j">╺━━━━━━━━━━━━━━━━━</text><text x="94.188" y="16.867" class="h">360/534</text><text x="102.204" y="16.867" class="f">•</text><text x="104.208" y="16.867" class="k">0:00:01</text><text x="112.224" y="16.867" class="f">•</text><text x="114.228" y="16.867" class="g">0:00:01</text></svg><svg x="4356"><use xlink:href="#a"/><use xlink:href="#4"/><use xlink:href="#5" y="2.171"/><use xlink:href="#6" y="4.342"/><use xlink:href="#7" y="6.513"/><use xlink:href="#8" y="8.684"/><use xlink:href="#9" y="10.855"/><use xlink:href="#11" y="13.026"/><text y="16.867" class="h">(</text><text x="5.01" y="16.867" class="h">🐌</text><text x="8.016" y="16.867" class="h">)</text><text x="10.02" y="16.867" class="f">•</text><text x="12.024" y="16.867" class="f">Running</text><text x="20.04" y="16.867" class="f">NRFU</text><text x="25.05" y="16.867" class="f">Tests...</text><text x="34.068" y="16.867" class="i">71%</text><text x="38.076" y="16.867" class="m">━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╸</text><text x="77.154" y="16.867" class="j">━━━━━━━━━━━━━━━━</text><text x="94.188" y="16.867" class="h">378/534</text><text x="102.204" y="16.867" class="f">•</text><text x="104.208" y="16.867" class="k">0:00:01</text><text x="112.224" y="16.867" class="f">•</text><text x="114.228" y="16.867" class="g">0:00:01</text></svg><svg x="4477"><use xlink:href="#a"/><use xlink:href="#4"/><use xlink:href="#5" y="2.171"/><use xlink:href="#6" y="4.342"/><use xlink:href="#7" y="6.513"/><use xlink:href="#8" y="8.684"/><use xlink:href="#9" y="10.855"/><use xlink:href="#11" y="13.026"/><text y="16.867" class="h">(</text><text x="5.01" y="16.867" class="h">🐌</text><text x="8.016" y="16.867" class="h">)</text><text x="10.02" y="16.867" class="f">•</text><text x="12.024" y="16.867" class="f">Running</text><text x="20.04" y="16.867" class="f">NRFU</text><text x="25.05" y="16.867" class="f">Tests...</text><text x="34.068" y="16.867" class="i">72%</text><text x="38.076" y="16.867" class="m">━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━</text><text x="77.154" y="16.867" class="j">╺━━━━━━━━━━━━━━━</text><text x="94.188" y="16.867" class="h">383/534</text><text x="102.204" y="16.867" class="f">•</text><text x="104.208" y="16.867" class="k">0:00:01</text><text x="112.224" y="16.867" class="f">•</text><text x="114.228" y="16.867" class="g">0:00:01</text></svg><svg x="4598"><use xlink:href="#a"/><use xlink:href="#4"/><use xlink:href="#5" y="2.171"/><use xlink:href="#6" y="4.342"/><use xlink:href="#7" y="6.513"/><use xlink:href="#8" y="8.684"/><use xlink:href="#9" y="10.855"/><use xlink:href="#11" y="13.026"/><text y="16.867" class="h">(</text><text x="6.012" y="16.867" class="h">🐌)</text><text x="10.02" y="16.867" class="f">•</text><text x="12.024" y="16.867" class="f">Running</text><text x="20.04" y="16.867" class="f">NRFU</text><text x="25.05" y="16.867" class="f">Tests...</text><text x="34.068" y="16.867" class="i">72%</text><text x="38.076" y="16.867" class="m">━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╸</text><text x="78.156" y="16.867" class="j">━━━━━━━━━━━━━━━</text><text x="94.188" y="16.867" class="h">385/534</text><text x="102.204" y="16.867" class="f">•</text><text x="104.208" y="16.867" class="k">0:00:01</text><text x="112.224" y="16.867" class="f">•</text><text x="114.228" y="16.867" class="g">0:00:01</text></svg><svg x="4719"><use xlink:href="#a"/><use xlink:href="#4"/><use xlink:href="#5" y="2.171"/><use xlink:href="#6" y="4.342"/><use xlink:href="#7" y="6.513"/><use xlink:href="#8" y="8.684"/><use xlink:href="#9" y="10.855"/><use xlink:href="#11" y="13.026"/><text y="16.867" class="h">(</text><text x="6.012" y="16.867" class="h">🐜)</text><text x="10.02" y="16.867" class="f">•</text><text x="12.024" y="16.867" class="f">Running</text><text x="20.04" y="16.867" class="f">NRFU</text><text x="25.05" y="16.867" class="f">Tests...</text><text x="34.068" y="16.867" class="i">76%</text><text x="38.076" y="16.867" class="m">━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╸</text><text x="80.16" y="16.867" class="j">━━━━━━━━━━━━━</text><text x="94.188" y="16.867" class="h">407/534</text><text x="102.204" y="16.867" class="f">•</text><text x="104.208" y="16.867" class="k">0:00:01</text><text x="112.224" y="16.867" class="f">•</text><text x="114.228" y="16.867" class="g">0:00:01</text></svg><svg x="4840"><use xlink:href="#a"/><use xlink:href="#4"/><use xlink:href="#5" y="2.171"/><use xlink:href="#6" y="4.342"/><use xlink:href="#7" y="6.513"/><use xlink:href="#8" y="8.684"/><use xlink:href="#9" y="10.855"/><use xlink:href="#11" y="13.026"/><text y="16.867" class="h">(</text><text x="6.012" y="16.867" class="h">🐜)</text><text x="10.02" y="16.867" class="f">•</text><text x="12.024" y="16.867" class="f">Running</text><text x="20.04" y="16.867" class="f">NRFU</text><text x="25.05" y="16.867" class="f">Tests...</text><text x="34.068" y="16.867" class="i">81%</text><text x="38.076" y="16.867" class="m">━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╸</text><text x="83.166" y="16.867" class="j">━━━━━━━━━━</text><text x="94.188" y="16.867" class="h">433/534</text><text x="102.204" y="16.867" class="f">•</text><text x="104.208" y="16.867" class="k">0:00:01</text><text x="112.224" y="16.867" class="f">•</text><text x="114.228" y="16.867" class="g">0:00:01</text></svg><svg x="4961"><use xlink:href="#a"/><use xlink:href="#4"/><use xlink:href="#5" y="2.171"/><use xlink:href="#6" y="4.342"/><use xlink:href="#7" y="6.513"/><use xlink:href="#8" y="8.684"/><use xlink:href="#9" y="10.855"/><use xlink:href="#11" y="13.026"/><text y="16.867" class="h">(</text><text x="5.01" y="16.867" class="h">🐜</text><text x="8.016" y="16.867" class="h">)</text><text x="10.02" y="16.867" class="f">•</text><text x="12.024" y="16.867" class="f">Running</text><text x="20.04" y="16.867" class="f">NRFU</text><text x="25.05" y="16.867" class="f">Tests...</text><text x="34.068" y="16.867" class="i">84%</text><text x="38.076" y="16.867" class="m">━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━</text><text x="84.168" y="16.867" class="j">╺━━━━━━━━</text><text x="94.188" y="16.867" class="h">447/534</text><text x="102.204" y="16.867" class="f">•</text><text x="104.208" y="16.867" class="k">0:00:02</text><text x="112.224" y="16.867" class="f">•</text><text x="114.228" y="16.867" class="g">0:00:01</text></svg><svg x="5082"><use xlink:href="#a"/><use xlink:href="#4"/><use xlink:href="#5" y="2.171"/><use xlink:href="#6" y="4.342"/><use xlink:href="#7" y="6.513"/><use xlink:href="#8" y="8.684"/><use xlink:href="#9" y="10.855"/><use xlink:href="#11" y="13.026"/><text y="16.867" class="h">(</text><text x="4.008" y="16.867" class="h">🐜</text><text x="8.016" y="16.867" class="h">)</text><text x="10.02" y="16.867" class="f">•</text><text x="12.024" y="16.867" class="f">Running</text><text x="20.04" y="16.867" class="f">NRFU</text><text x="25.05" y="16.867" class="f">Tests...</text><text x="34.068" y="16.867" class="i">85%</text><text x="38.076" y="16.867" class="m">━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╸</text><text x="85.17" y="16.867" class="j">━━━━━━━━</text><text x="94.188" y="16.867" class="h">456/534</text><text x="102.204" y="16.867" class="f">•</text><text x="104.208" y="16.867" class="k">0:00:02</text><text x="112.224" y="16.867" class="f">•</text><text x="114.228" y="16.867" class="g">0:00:01</text></svg><svg x="5203"><use xlink:href="#a"/><use xlink:href="#4"/><use xlink:href="#5" y="2.171"/><use xlink:href="#6" y="4.342"/><use xlink:href="#7" y="6.513"/><use xlink:href="#8" y="8.684"/><use xlink:href="#9" y="10.855"/><use xlink:href="#11" y="13.026"/><text y="16.867" class="h">(</text><text x="4.008" y="16.867" class="h">🐜</text><text x="8.016" y="16.867" class="h">)</text><text x="10.02" y="16.867" class="f">•</text><text x="12.024" y="16.867" class="f">Running</text><text x="20.04" y="16.867" class="f">NRFU</text><text x="25.05" y="16.867" class="f">Tests...</text><text x="34.068" y="16.867" class="i">87%</text><text x="38.076" y="16.867" class="m">━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━</text><text x="86.172" y="16.867" class="j">╺━━━━━━</text><text x="94.188" y="16.867" class="h">467/534</text><text x="102.204" y="16.867" class="f">•</text><text x="104.208" y="16.867" class="k">0:00:02</text><text x="112.224" y="16.867" class="f">•</text><text x="114.228" y="16.867" class="g">0:00:01</text></svg><svg x="5324"><use xlink:href="#a"/><use xlink:href="#4"/><use xlink:href="#5" y="2.171"/><use xlink:href="#6" y="4.342"/><use xlink:href="#7" y="6.513"/><use xlink:href="#8" y="8.684"/><use xlink:href="#9" y="10.855"/><use xlink:href="#11" y="13.026"/><text y="16.867" class="h">(</text><text x="3.006" y="16.867" class="h">🐜</text><text x="8.016" y="16.867" class="h">)</text><text x="10.02" y="16.867" class="f">•</text><text x="12.024" y="16.867" class="f">Running</text><text x="20.04" y="16.867" class="f">NRFU</text><text x="25.05" y="16.867" class="f">Tests...</text><text x="34.068" y="16.867" class="i">89%</text><text x="38.076" y="16.867" class="m">━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━</text><text x="87.174" y="16.867" class="j">╺━━━━━</text><text x="94.188" y="16.867" class="h">476/534</text><text x="102.204" y="16.867" class="f">•</text><text x="104.208" y="16.867" class="k">0:00:02</text><text x="112.224" y="16.867" class="f">•</text><text x="114.228" y="16.867" class="g">0:00:01</text></svg><svg x="5445"><use xlink:href="#a"/><use xlink:href="#4"/><use xlink:href="#5" y="2.171"/><use xlink:href="#6" y="4.342"/><use xlink:href="#7" y="6.513"/><use xlink:href="#8" y="8.684"/><use xlink:href="#9" y="10.855"/><use xlink:href="#11" y="13.026"/><text y="16.867" class="h">(</text><text x="2.004" y="16.867" class="h">🐜</text><text x="8.016" y="16.867" class="h">)</text><text x="10.02" y="16.867" class="f">•</text><text x="12.024" y="16.867" class="f">Running</text><text x="20.04" y="16.867" class="f">NRFU</text><text x="25.05" y="16.867" class="f">Tests...</text><text x="34.068" y="16.867" class="i">91%</text><text x="38.076" y="16.867" class="m">━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━</text><text x="88.176" y="16.867" class="j">╺━━━━</text><text x="94.188" y="16.867" class="h">486/534</text><text x="102.204" y="16.867" class="f">•</text><text x="104.208" y="16.867" class="k">0:00:02</text><text x="112.224" y="16.867" class="f">•</text><text x="114.228" y="16.867" class="g">0:00:01</text></svg><svg x="5566"><use xlink:href="#a"/><use xlink:href="#4"/><use xlink:href="#5" y="2.171"/><use xlink:href="#6" y="4.342"/><use xlink:href="#7" y="6.513"/><use xlink:href="#8" y="8.684"/><use xlink:href="#9" y="10.855"/><use xlink:href="#11" y="13.026"/><text y="16.867" class="h">(</text><text x="2.004" y="16.867" class="h">🐜</text><text x="8.016" y="16.867" class="h">)</text><text x="10.02" y="16.867" class="f">•</text><text x="12.024" y="16.867" class="f">Running</text><text x="20.04" y="16.867" class="f">NRFU</text><text x="25.05" y="16.867" class="f">Tests...</text><text x="34.068" y="16.867" class="i">95%</text><text x="38.076" y="16.867" class="m">━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━</text><text x="90.18" y="16.867" class="j">╺━━</text><text x="94.188" y="16.867" class="h">505/534</text><text x="102.204" y="16.867" class="f">•</text><text x="104.208" y="16.867" class="k">0:00:02</text><text x="112.224" y="16.867" class="f">•</text><text x="114.228" y="16.867" class="g">0:00:01</text></svg><svg x="5687"><use xlink:href="#a"/><use xlink:href="#4"/><use xlink:href="#5" y="2.171"/><use xlink:href="#6" y="4.342"/><use xlink:href="#7" y="6.513"/><use xlink:href="#8" y="8.684"/><use xlink:href="#9" y="10.855"/><use xlink:href="#11" y="13.026"/><text y="16.867" class="h">(🐜</text><text x="8.016" y="16.867" class="h">)</text><text x="10.02" y="16.867" class="f">•</text><text x="12.024" y="16.867" class="f">Running</text><text x="20.04" y="16.867" class="f">NRFU</text><text x="25.05" y="16.867" class="f">Tests...</text><text x="34.068" y="16.867" class="i">98%</text><text x="38.076" y="16.867" class="m">━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╸</text><text x="92.184" y="16.867" class="j">━</text><text x="94.188" y="16.867" class="h">521/534</text><text x="102.204" y="16.867" class="f">•</text><text x="104.208" y="16.867" class="k">0:00:02</text><text x="112.224" y="16.867" class="f">•</text><text x="114.228" y="16.867" class="g">0:00:01</text></svg><svg x="5808"><use xlink:href="#a"/><use xlink:href="#4"/><use xlink:href="#5" y="2.171"/><use xlink:href="#6" y="4.342"/><use xlink:href="#7" y="6.513"/><use xlink:href="#8" y="8.684"/><use xlink:href="#9" y="10.855"/><use xlink:href="#11" y="13.026"/><text y="16.867" class="h">(🐌</text><text x="8.016" y="16.867" class="h">)</text><text x="10.02" y="16.867" class="f">•</text><text x="12.024" y="16.867" class="f">Running</text><text x="20.04" y="16.867" class="f">NRFU</text><text x="25.05" y="16.867" class="f">Tests...</text><text x="34.068" y="16.867" class="i">99%</text><text x="38.076" y="16.867" class="m">━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━</text><text x="92.184" y="16.867" class="j">╺</text><text x="94.188" y="16.867" class="h">528/534</text><text x="102.204" y="16.867" class="f">•</text><text x="104.208" y="16.867" class="k">0:00:02</text><text x="112.224" y="16.867" class="f">•</text><text x="114.228" y="16.867" class="g">0:00:01</text></svg><svg x="5929"><use xlink:href="#a"/><use xlink:href="#4"/><use xlink:href="#5" y="2.171"/><use xlink:href="#6" y="4.342"/><use xlink:href="#7" y="6.513"/><use xlink:href="#8" y="8.684"/><use xlink:href="#9" y="10.855"/><use xlink:href="#11" y="13.026"/><use xlink:href="#14" y="15.197"/></svg><svg x="6050"><use xlink:href="#a"/><use xlink:href="#4"/><use xlink:href="#5" y="2.171"/><use xlink:href="#6" y="4.342"/><use xlink:href="#7" y="6.513"/><use xlink:href="#8" y="8.684"/><use xlink:href="#9" y="10.855"/><use xlink:href="#11" y="13.026"/><use xlink:href="#14" y="15.197"/></svg><svg x="6171"><use xlink:href="#a"/><use xlink:href="#4"/><use xlink:href="#5" y="2.171"/><use xlink:href="#6" y="4.342"/><use xlink:href="#7" y="6.513"/><use xlink:href="#8" y="8.684"/><use xlink:href="#9" y="10.855"/><use xlink:href="#11" y="13.026"/><text y="16.867" class="h">(</text><text x="3.006" y="16.867" class="h">🐌</text><text x="8.016" y="16.867" class="h">)</text><text x="10.02" y="16.867" class="f">•</text><text x="12.024" y="16.867" class="f">Running</text><text x="20.04" y="16.867" class="f">NRFU</text><text x="25.05" y="16.867" class="f">Tests...</text><text x="34.068" y="16.867" class="i">99%</text><text x="38.076" y="16.867" class="m">━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╸</text><text x="94.188" y="16.867" class="h">531/534</text><text x="102.204" y="16.867" class="f">•</text><text x="104.208" y="16.867" class="k">0:00:03</text><text x="112.224" y="16.867" class="f">•</text><text x="114.228" y="16.867" class="g">0:00:01</text></svg><svg x="6292"><use xlink:href="#a"/><use xlink:href="#4"/><use xlink:href="#5" y="2.171"/><use xlink:href="#6" y="4.342"/><use xlink:href="#7" y="6.513"/><use xlink:href="#8" y="8.684"/><use xlink:href="#9" y="10.855"/><use xlink:href="#11" y="13.026"/><use xlink:href="#15" y="15.197"/></svg><svg x="6413"><use xlink:href="#a"/><use xlink:href="#4"/><use xlink:href="#5" y="2.171"/><use xlink:href="#6" y="4.342"/><use xlink:href="#7" y="6.513"/><use xlink:href="#8" y="8.684"/><use xlink:href="#9" y="10.855"/><use xlink:href="#11" y="13.026"/><use xlink:href="#15" y="15.197"/></svg><svg x="6534"><use xlink:href="#a"/><use xlink:href="#4"/><use xlink:href="#5" y="2.171"/><use xlink:href="#6" y="4.342"/><use xlink:href="#7" y="6.513"/><use xlink:href="#8" y="8.684"/><use xlink:href="#9" y="10.855"/><use xlink:href="#11" y="13.026"/><text y="16.867" class="h">(</text><text x="5.01" y="16.867" class="h">🐌</text><text x="8.016" y="16.867" class="h">)</text><text x="10.02" y="16.867" class="f">•</text><text x="12.024" y="16.867" class="f">Running</text><text x="20.04" y="16.867" class="f">NRFU</text><text x="25.05" y="16.867" class="f">Tests...</text><text x="34.068" y="16.867" class="i">99%</text><text x="38.076" y="16.867" class="m">━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╸</text><text x="94.188" y="16.867" class="h">531/534</text><text x="102.204" y="16.867" class="f">•</text><text x="104.208" y="16.867" class="k">0:00:03</text><text x="112.224" y="16.867" class="f">•</text><text x="114.228" y="16.867" class="g">0:00:01</text></svg><svg x="6655"><use xlink:href="#a"/><use xlink:href="#4"/><use xlink:href="#5" y="2.171"/><use xlink:href="#6" y="4.342"/><use xlink:href="#7" y="6.513"/><use xlink:href="#8" y="8.684"/><use xlink:href="#9" y="10.855"/><use xlink:href="#11" y="13.026"/><use xlink:href="#16" y="15.197"/></svg><svg x="6776"><use xlink:href="#a"/><use xlink:href="#4"/><use xlink:href="#5" y="2.171"/><use xlink:href="#6" y="4.342"/><use xlink:href="#7" y="6.513"/><use xlink:href="#8" y="8.684"/><use xlink:href="#9" y="10.855"/><use xlink:href="#11" y="13.026"/><use xlink:href="#16" y="15.197"/></svg><svg x="6897"><use xlink:href="#a"/><use xlink:href="#4"/><use xlink:href="#5" y="2.171"/><use xlink:href="#6" y="4.342"/><use xlink:href="#7" y="6.513"/><use xlink:href="#8" y="8.684"/><use xlink:href="#9" y="10.855"/><use xlink:href="#11" y="13.026"/><text y="16.867" class="h">(</text><text x="6.012" y="16.867" class="h">🐜)</text><text x="10.02" y="16.867" class="f">•</text><text x="12.024" y="16.867" class="f">Running</text><text x="20.04" y="16.867" class="f">NRFU</text><text x="25.05" y="16.867" class="f">Tests...</text><text x="34.068" y="16.867" class="i">99%</text><text x="38.076" y="16.867" class="m">━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╸</text><text x="94.188" y="16.867" class="h">531/534</text><text x="102.204" y="16.867" class="f">•</text><text x="104.208" y="16.867" class="k">0:00:03</text><text x="112.224" y="16.867" class="f">•</text><text x="114.228" y="16.867" class="g">0:00:01</text></svg><svg x="7018"><use xlink:href="#a"/><use xlink:href="#4"/><use xlink:href="#5" y="2.171"/><use xlink:href="#6" y="4.342"/><use xlink:href="#7" y="6.513"/><use xlink:href="#8" y="8.684"/><use xlink:href="#9" y="10.855"/><use xlink:href="#11" y="13.026"/><use xlink:href="#17" y="15.197"/></svg><svg x="7139"><use xlink:href="#a"/><use xlink:href="#4"/><use xlink:href="#5" y="2.171"/><use xlink:href="#6" y="4.342"/><use xlink:href="#7" y="6.513"/><use xlink:href="#8" y="8.684"/><use xlink:href="#9" y="10.855"/><use xlink:href="#11" y="13.026"/><use xlink:href="#17" y="15.197"/></svg><svg x="7260"><use xlink:href="#a"/><use xlink:href="#4"/><use xlink:href="#5" y="2.171"/><use xlink:href="#6" y="4.342"/><use xlink:href="#7" y="6.513"/><use xlink:href="#8" y="8.684"/><use xlink:href="#9" y="10.855"/><use xlink:href="#11" y="13.026"/><text y="16.867" class="h">(</text><text x="4.008" y="16.867" class="h">🐜</text><text x="8.016" y="16.867" class="h">)</text><text x="10.02" y="16.867" class="f">•</text><text x="12.024" y="16.867" class="f">Running</text><text x="20.04" y="16.867" class="f">NRFU</text><text x="25.05" y="16.867" class="f">Tests...</text><text x="34.068" y="16.867" class="i">99%</text><text x="38.076" y="16.867" class="m">━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╸</text><text x="94.188" y="16.867" class="h">531/534</text><text x="102.204" y="16.867" class="f">•</text><text x="104.208" y="16.867" class="k">0:00:03</text><text x="112.224" y="16.867" class="f">•</text><text x="114.228" y="16.867" class="g">0:00:01</text></svg><svg x="7381"><use xlink:href="#a"/><use xlink:href="#4"/><use xlink:href="#5" y="2.171"/><use xlink:href="#6" y="4.342"/><use xlink:href="#7" y="6.513"/><use xlink:href="#8" y="8.684"/><use xlink:href="#9" y="10.855"/><use xlink:href="#11" y="13.026"/><text y="16.867" class="h">(</text><text x="3.006" y="16.867" class="h">🐜</text><text x="8.016" y="16.867" class="h">)</text><text x="10.02" y="16.867" class="f">•</text><text x="12.024" y="16.867" class="f">Running</text><text x="20.04" y="16.867" class="f">NRFU</text><text x="25.05" y="16.867" class="f">Tests...</text><text x="33.066" y="16.867" class="i">100%</text><text x="38.076" y="16.867" class="m">━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╸</text><text x="94.188" y="16.867" class="h">533/534</text><text x="102.204" y="16.867" class="f">•</text><text x="104.208" y="16.867" class="k">0:00:04</text><text x="112.224" y="16.867" class="f">•</text><text x="114.228" y="16.867" class="g">0:00:01</text></svg><svg x="7502"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="17.343"/><use xlink:href="#4"/><use xlink:href="#5" y="2.171"/><use xlink:href="#6" y="4.342"/><use xlink:href="#7" y="6.513"/><use xlink:href="#8" y="8.684"/><use xlink:href="#9" y="10.855"/><use xlink:href="#11" y="13.026"/><use xlink:href="#18" y="15.197"/></svg><svg x="7623"><use xlink:href="#a"/><use xlink:href="#b" x="1.996" y="17.343"/><use xlink:href="#4"/><use xlink:href="#5" y="2.171"/><use xlink:href="#6" y="4.342"/><use xlink:href="#7" y="6.513"/><use xlink:href="#8" y="8.684"/><use xlink:href="#9" y="10.855"/><use xlink:href="#11" y="13.026"/><use xlink:href="#18" y="15.197"/><use xlink:href="#1" y="17.368"/></svg></svg></g></g></svg></svg>
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="1250" height="277.1"><rect width="1250" height="277.1" rx="5" ry="5" class="a"/><svg y="0%" x="0%"><circle cx="20" cy="20" r="6" fill="#ff5f58"/><circle cx="40" cy="20" r="6" fill="#ffbd2e"/><circle cx="60" cy="20" r="6" fill="#18c132"/></svg><svg height="217.1" viewBox="0 0 121 21.71" width="1210" x="15" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" y="50"><style>@keyframes q{0%{transform:translateX(0)}2.2%{transform:translateX(-121px)}11.3%{transform:translateX(-242px)}13.7%{transform:translateX(-363px)}15.8%{transform:translateX(-484px)}17.9%{transform:translateX(-605px)}19.9%{transform:translateX(-726px)}22.2%{transform:translateX(-847px)}23.9%{transform:translateX(-968px)}26.1%{transform:translateX(-1089px)}28.3%{transform:translateX(-1210px)}29.4%{transform:translateX(-1331px)}32.1%{transform:translateX(-1452px)}34%{transform:translateX(-1573px)}36.6%{transform:translateX(-1694px)}38.3%{transform:translateX(-1815px)}40%{transform:translateX(-1936px)}45%{transform:translateX(-2057px)}48.5%{transform:translateX(-2299px)}49.1%{transform:translateX(-2541px)}49.9%{transform:translateX(-2662px)}51.1%{transform:translateX(-2783px)}52.4%{transform:translateX(-2904px)}53.6%{transform:translateX(-3025px)}54.9%{transform:translateX(-3146px)}56.1%{transform:translateX(-3267px)}57.4%{transform:translateX(-3388px)}59%{transform:translateX(-3509px)}60.3%{transform:translateX(-3630px)}61.5%{transform:translateX(-3751px)}62.8%{transform:translateX(-3872px)}64%{transform:translateX(-3993px)}65.2%{transform:translateX(-4114px)}66.5%{transform:translateX(-4235px)}67.7%{transform:translateX(-4356px)}68.9%{transform:translateX(-4477px)}70.2%{transform:translateX(-4598px)}71.4%{transform:translateX(-4719px)}72.6%{transform:translateX(-4840px)}73.9%{transform:translateX(-4961px)}75.1%{transform:translateX(-5082px)}76.3%{transform:translateX(-5203px)}77.6%{transform:translateX(-5324px)}78.8%{transform:translateX(-5445px)}80%{transform:translateX(-5566px)}81.3%{transform:translateX(-5687px)}82.5%{transform:translateX(-5808px)}83.7%{transform:translateX(-5929px)}85%{transform:translateX(-6050px)}86.2%{transform:translateX(-6171px)}87.4%{transform:translateX(-6292px)}88.7%{transform:translateX(-6413px)}89.9%{transform:translateX(-6534px)}91.1%{transform:translateX(-6655px)}92.3%{transform:translateX(-6776px)}93.6%{transform:translateX(-6897px)}94.8%{transform:translateX(-7018px)}96%{transform:translateX(-7139px)}97.3%{transform:translateX(-7260px)}98.5%{transform:translateX(-7381px)}99.1%{transform:translateX(-7502px)}to{transform:translateX(-7623px)}}.a{fill:#282d35}.f{fill:#b9c0cb;white-space:pre}.g,.h,.i,.j,.k,.m{fill:#66c2cd;white-space:pre}.h,.i,.j,.k,.m{fill:#a8cc8c}.i,.j,.k,.m{fill:#d290e4}.j,.k,.m{fill:#3a3a3a}.k,.m{fill:#dbab79}.m{fill:#ff005f}</style><g font-family="Monaco,Consolas,Menlo,'Bitstream Vera Sans Mono','Powerline Symbols',monospace" font-size="1.67"><defs><symbol id="1"><text y="1.67" class="f">❯</text></symbol><symbol id="2"><text y="1.67" class="f">❯</text><text x="2.004" y="1.67" class="f">anta</text></symbol><symbol id="3"><text y="1.67" class="f">❯</text><text x="2.004" y="1.67" class="f">anta</text><text x="7.014" y="1.67" class="f">nrfu</text></symbol><symbol id="4"><text y="1.67" class="f">❯</text><text x="2.004" y="1.67" class="f">anta</text><text x="7.014" y="1.67" class="f">nrfu</text><text x="12.024" y="1.67" class="f">table</text></symbol><symbol id="5"><text y="1.67" class="g">╭──────────────────────</text><text x="24.048" y="1.67" class="h">Settings</text><text x="33.066" y="1.67" class="g">──────────────────────╮</text></symbol><symbol id="6"><text y="1.67" class="g">│</text><text x="2.004" y="1.67" class="g">Running</text><text x="10.02" y="1.67" class="g">ANTA</text><text x="15.03" y="1.67" class="g">tests:</text><text x="55.11" y="1.67" class="g">│</text></symbol><symbol id="7"><text y="1.67" class="g">│</text><text x="2.004" y="1.67" class="g">-</text><text x="4.008" y="1.67" class="g">ANTA</text><text x="9.018" y="1.67" class="g">Inventory</text><text x="19.038" y="1.67" class="g">contains</text><text x="28.056" y="1.67" class="g">6</text><text x="30.06" y="1.67" class="g">devices</text><text x="38.076" y="1.67" class="g">(AsyncEOSDevice)</text><text x="55.11" y="1.67" class="g">│</text></symbol><symbol id="8"><text y="1.67" class="g">│</text><text x="2.004" y="1.67" class="g">-</text><text x="4.008" y="1.67" class="g">Tests</text><text x="10.02" y="1.67" class="g">catalog</text><text x="18.036" y="1.67" class="g">contains</text><text x="27.054" y="1.67" class="g">89</text><text x="30.06" y="1.67" class="g">tests</text><text x="55.11" y="1.67" class="g">│</text></symbol><symbol id="9"><text y="1.67" class="g">╰──────────────────────────────────────────────────────╯</text></symbol><symbol id="10"><text y="1.67" class="h">(</text><text x="6.012" y="1.67" class="h">🐜)</text><text x="10.02" y="1.67" class="f">•</text><text x="12.024" y="1.67" class="f">Running</text><text x="20.04" y="1.67" class="f">NRFU</text><text x="25.05" y="1.67" class="f">Tests...</text><text x="35.07" y="1.67" class="i">0%</text><text x="38.076" y="1.67" class="j">━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━</text><text x="96.192" y="1.67" class="h">0/534</text><text x="102.204" y="1.67" class="f">•</text><text x="104.208" y="1.67" class="k">0:00:00</text><text x="112.224" y="1.67" class="f">•</text><text x="114.228" y="1.67" class="g">-:--:--</text></symbol><symbol id="11"><text y="1.67" class="g">[11:29:47]</text><text x="11.022" y="1.67" style="white-space:pre" fill="#71bef2">INFO</text><text x="20.04" y="1.67" class="f">Running</text><text x="28.056" y="1.67" class="f">ANTA</text><text x="33.066" y="1.67" class="f">tests</text><text x="38.076" y="1.67" class="k">...</text><text x="109.218" y="1.67" class="f">runner.py:71</text></symbol><symbol id="12"><text y="1.67" class="h">(</text><text x="5.01" y="1.67" class="h">🐜</text><text x="8.016" y="1.67" class="h">)</text><text x="10.02" y="1.67" class="f">•</text><text x="12.024" y="1.67" class="f">Running</text><text x="20.04" y="1.67" class="f">NRFU</text><text x="25.05" y="1.67" class="f">Tests...</text><text x="34.068" y="1.67" class="i">15%</text><text x="38.076" y="1.67" class="m">━━━━━━━━</text><text x="46.092" y="1.67" class="j">╺━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━</text><text x="95.19" y="1.67" class="h">78/534</text><text x="102.204" y="1.67" class="f">•</text><text x="104.208" y="1.67" class="k">0:00:00</text><text x="112.224" y="1.67" class="f">•</text><text x="114.228" y="1.67" class="g">0:00:01</text></symbol><symbol id="13"><text y="1.67" class="h">(</text><text x="3.006" y="1.67" class="h">🐜</text><text x="8.016" y="1.67" class="h">)</text><text x="10.02" y="1.67" class="f">•</text><text x="12.024" y="1.67" class="f">Running</text><text x="20.04" y="1.67" class="f">NRFU</text><text x="25.05" y="1.67" class="f">Tests...</text><text x="34.068" y="1.67" class="i">15%</text><text x="38.076" y="1.67" class="m">━━━━━━━━</text><text x="46.092" y="1.67" class="j">╺━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━</text><text x="95.19" y="1.67" class="h">78/534</text><text x="102.204" y="1.67" class="f">•</text><text x="104.208" y="1.67" class="k">0:00:00</text><text x="112.224" y="1.67" class="f">•</text><text x="114.228" y="1.67" class="g">0:00:01</text></symbol><symbol id="14"><text y="1.67" class="h">(</text><text x="2.004" y="1.67" class="h">🐌</text><text x="8.016" y="1.67" class="h">)</text><text x="10.02" y="1.67" class="f">•</text><text x="12.024" y="1.67" class="f">Running</text><text x="20.04" y="1.67" class="f">NRFU</text><text x="25.05" y="1.67" class="f">Tests...</text><text x="34.068" y="1.67" class="i">99%</text><text x="38.076" y="1.67" class="m">━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╸</text><text x="94.188" y="1.67" class="h">531/534</text><text x="102.204" y="1.67" class="f">•</text><text x="104.208" y="1.67" class="k">0:00:02</text><text x="112.224" y="1.67" class="f">•</text><text x="114.228" y="1.67" class="g">0:00:01</text></symbol><symbol id="15"><text y="1.67" class="h">(</text><text x="4.008" y="1.67" class="h">🐌</text><text x="8.016" y="1.67" class="h">)</text><text x="10.02" y="1.67" class="f">•</text><text x="12.024" y="1.67" class="f">Running</text><text x="20.04" y="1.67" class="f">NRFU</text><text x="25.05" y="1.67" class="f">Tests...</text><text x="34.068" y="1.67" class="i">99%</text><text x="38.076" y="1.67" class="m">━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╸</text><text x="94.188" y="1.67" class="h">531/534</text><text x="102.204" y="1.67" class="f">•</text><text x="104.208" y="1.67" class="k">0:00:03</text><text x="112.224" y="1.67" class="f">•</text><text x="114.228" y="1.67" class="g">0:00:01</text></symbol><symbol id="16"><text y="1.67" class="h">(</text><text x="6.012" y="1.67" class="h">🐌)</text><text x="10.02" y="1.67" class="f">•</text><text x="12.024" y="1.67" class="f">Running</text><text x="20.04" y="1.67" class="f">NRFU</text><text x="25.05" y="1.67" class="f">Tests...</text><text x="34.068" y="1.67" class="i">99%</text><text x="38.076" y="1.67" class="m">━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╸</text><text x="94.188" y="1.67" class="h">531/534</text><text x="102.204" y="1.67" class="f">•</text><text x="104.208" y="1.67" class="k">0:00:03</text><text x="112.224" y="1.67" class="f">•</text><text x="114.228" y="1.67" class="g">0:00:01</text></symbol><symbol id="17"><text y="1.67" class="h">(</text><text x="5.01" y="1.67" class="h">🐜</text><text x="8.016" y="1.67" class="h">)</text><text x="10.02" y="1.67" class="f">•</text><text x="12.024" y="1.67" class="f">Running</text><text x="20.04" y="1.67" class="f">NRFU</text><text x="25.05" y="1.67" class="f">Tests...</text><text x="34.068" y="1.67" class="i">99%</text><text x="38.076" y="1.67" class="m">━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╸</text><text x="94.188" y="1.67" class="h">531/534</text><text x="102.204" y="1.67" class="f">•</text><text x="104.208" y="1.67" class="k">0:00:03</text><text x="112.224" y="1.67" class="f">•</text><text x="114.228" y="1.67" class="g">0:00:01</text></symbol><symbol id="18"><text x="2.004" y="1.67" class="f">•</text><text x="4.008" y="1.67" class="f">Running</text><text x="12.024" y="1.67" class="f">NRFU</text><text x="17.034" y="1.67" class="f">Tests...</text><text x="25.05" y="1.67" class="i">100%</text><text x="30.06" y="1.67" style="white-space:pre" fill="#5faf00">━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━</text><text x="94.188" y="1.67" class="h">534/534</text><text x="102.204" y="1.67" class="f">•</text><text x="104.208" y="1.67" class="k">0:00:04</text><text x="112.224" y="1.67" class="f">•</text><text x="114.228" y="1.67" class="g">0:00:00</text></symbol><symbol id="a"><path fill="transparent" d="M0 0h121v11H0z"/></symbol><symbol id="b"><path fill="#6f7683" d="M0 0h1.102v2.171H0z"/></symbol></defs><path class="a" d="M0 0h121v21.71H0z"/><g style="animation-duration:8.22014s;animation-iteration-count:infinite;animation-name:q;animation-timing-function:steps(1,end)"><svg width="7744"><svg><use xlink:href="#a"/><use xlink:href="#b" x="-.004"/></svg><svg x="121"><use xlink:href="#a"/><use xlink:href="#b" x="1.996"/><use xlink:href="#1"/></svg><svg x="242"><use xlink:href="#a"/><use xlink:href="#b" x="2.996"/><text y="1.67" class="f">❯</text><text x="2.004" y="1.67" class="f">a</text></svg><svg x="363"><use xlink:href="#a"/><use xlink:href="#b" x="3.996"/><text y="1.67" class="f">❯</text><text x="2.004" y="1.67" class="f">an</text></svg><svg x="484"><use xlink:href="#a"/><use xlink:href="#b" x="4.996"/><text y="1.67" class="f">❯</text><text x="2.004" y="1.67" class="f">ant</text></svg><svg x="605"><use xlink:href="#a"/><use xlink:href="#b" x="5.996"/><use xlink:href="#2"/></svg><svg x="726"><use xlink:href="#a"/><use xlink:href="#b" x="6.996"/><use xlink:href="#2"/></svg><svg x="847"><use xlink:href="#a"/><use xlink:href="#b" x="7.996"/><text y="1.67" class="f">❯</text><text x="2.004" y="1.67" class="f">anta</text><text x="7.014" y="1.67" class="f">n</text></svg><svg x="968"><use xlink:href="#a"/><use xlink:href="#b" x="8.996"/><text y="1.67" class="f">❯</text><text x="2.004" y="1.67" class="f">anta</text><text x="7.014" y="1.67" class="f">nr</text></svg><svg x="1089"><use xlink:href="#a"/><use xlink:href="#b" x="9.996"/><text y="1.67" class="f">❯</text><text x="2.004" y="1.67" class="f">anta</text><text x="7.014" y="1.67" class="f">nrf</text></svg><svg x="1210"><use xlink:href="#a"/><use xlink:href="#b" x="10.996"/><use xlink:href="#3"/></svg><svg x="1331"><use xlink:href="#a"/><use xlink:href="#b" x="11.996"/><use xlink:href="#3"/></svg><svg x="1452"><use xlink:href="#a"/><use xlink:href="#b" x="12.996"/><text y="1.67" class="f">❯</text><text x="2.004" y="1.67" class="f">anta</text><text x="7.014" y="1.67" class="f">nrfu</text><text x="12.024" y="1.67" class="f">t</text></svg><svg x="1573"><use xlink:href="#a"/><use xlink:href="#b" x="13.996"/><text y="1.67" class="f">❯</text><text x="2.004" y="1.67" class="f">anta</text><text x="7.014" y="1.67" class="f">nrfu</text><text x="12.024" y="1.67" class="f">ta</text></svg><svg x="1694"><use xlink:href="#a"/><use xlink:href="#b" x="14.996"/><text y="1.67" class="f">❯</text><text x="2.004" y="1.67" class="f">anta</text><text x="7.014" y="1.67" class="f">nrfu</text><text x="12.024" y="1.67" class="f">tab</text></svg><svg x="1815"><use xlink:href="#a"/><use xlink:href="#b" x="15.996"/><text y="1.67" class="f">❯</text><text x="2.004" y="1.67" class="f">anta</text><text x="7.014" y="1.67" class="f">nrfu</text><text x="12.024" y="1.67" class="f">table</text></svg><svg x="1936"><use xlink:href="#a"/><use xlink:href="#b" x="16.996"/><use xlink:href="#4"/></svg><svg x="2057"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="2.146"/><use xlink:href="#4"/></svg><svg x="2178"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="13.001"/><use xlink:href="#4"/><use xlink:href="#5" y="2.171"/><use xlink:href="#6" y="4.342"/><use xlink:href="#7" y="6.513"/><use xlink:href="#8" y="8.684"/><use xlink:href="#9" y="10.855"/></svg><svg x="2299"><use xlink:href="#a"/><use xlink:href="#4"/><use xlink:href="#5" y="2.171"/><use xlink:href="#6" y="4.342"/><use xlink:href="#7" y="6.513"/><use xlink:href="#8" y="8.684"/><use xlink:href="#9" y="10.855"/></svg><svg x="2420"><use xlink:href="#a"/><use xlink:href="#4"/><use xlink:href="#5" y="2.171"/><use xlink:href="#6" y="4.342"/><use xlink:href="#7" y="6.513"/><use xlink:href="#8" y="8.684"/><use xlink:href="#9" y="10.855"/><use xlink:href="#10" y="13.026"/></svg><svg x="2541"><use xlink:href="#a"/><use xlink:href="#4"/><use xlink:href="#5" y="2.171"/><use xlink:href="#6" y="4.342"/><use xlink:href="#7" y="6.513"/><use xlink:href="#8" y="8.684"/><use xlink:href="#9" y="10.855"/><use xlink:href="#11" y="13.026"/><use xlink:href="#10" y="15.197"/></svg><svg x="2662"><use xlink:href="#a"/><use xlink:href="#4"/><use xlink:href="#5" y="2.171"/><use xlink:href="#6" y="4.342"/><use xlink:href="#7" y="6.513"/><use xlink:href="#8" y="8.684"/><use xlink:href="#9" y="10.855"/><use xlink:href="#11" y="13.026"/><text y="16.867" class="h">(</text><text x="6.012" y="16.867" class="h">🐜)</text><text x="10.02" y="16.867" class="f">•</text><text x="12.024" y="16.867" class="f">Running</text><text x="20.04" y="16.867" class="f">NRFU</text><text x="25.05" y="16.867" class="f">Tests...</text><text x="34.068" y="16.867" class="i">15%</text><text x="38.076" y="16.867" class="m">━━━━━━━━</text><text x="46.092" y="16.867" class="j">╺━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━</text><text x="95.19" y="16.867" class="h">78/534</text><text x="102.204" y="16.867" class="f">•</text><text x="104.208" y="16.867" class="k">0:00:00</text><text x="112.224" y="16.867" class="f">•</text><text x="114.228" y="16.867" class="g">0:00:01</text></svg><svg x="2783"><use xlink:href="#a"/><use xlink:href="#4"/><use xlink:href="#5" y="2.171"/><use xlink:href="#6" y="4.342"/><use xlink:href="#7" y="6.513"/><use xlink:href="#8" y="8.684"/><use xlink:href="#9" y="10.855"/><use xlink:href="#11" y="13.026"/><use xlink:href="#12" y="15.197"/></svg><svg x="2904"><use xlink:href="#a"/><use xlink:href="#4"/><use xlink:href="#5" y="2.171"/><use xlink:href="#6" y="4.342"/><use xlink:href="#7" y="6.513"/><use xlink:href="#8" y="8.684"/><use xlink:href="#9" y="10.855"/><use xlink:href="#11" y="13.026"/><use xlink:href="#12" y="15.197"/></svg><svg x="3025"><use xlink:href="#a"/><use xlink:href="#4"/><use xlink:href="#5" y="2.171"/><use xlink:href="#6" y="4.342"/><use xlink:href="#7" y="6.513"/><use xlink:href="#8" y="8.684"/><use xlink:href="#9" y="10.855"/><use xlink:href="#11" y="13.026"/><text y="16.867" class="h">(</text><text x="4.008" y="16.867" class="h">🐜</text><text x="8.016" y="16.867" class="h">)</text><text x="10.02" y="16.867" class="f">•</text><text x="12.024" y="16.867" class="f">Running</text><text x="20.04" y="16.867" class="f">NRFU</text><text x="25.05" y="16.867" class="f">Tests...</text><text x="34.068" y="16.867" class="i">15%</text><text x="38.076" y="16.867" class="m">━━━━━━━━</text><text x="46.092" y="16.867" class="j">╺━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━</text><text x="95.19" y="16.867" class="h">78/534</text><text x="102.204" y="16.867" class="f">•</text><text x="104.208" y="16.867" class="k">0:00:00</text><text x="112.224" y="16.867" class="f">•</text><text x="114.228" y="16.867" class="g">0:00:01</text></svg><svg x="3146"><use xlink:href="#a"/><use xlink:href="#4"/><use xlink:href="#5" y="2.171"/><use xlink:href="#6" y="4.342"/><use xlink:href="#7" y="6.513"/><use xlink:href="#8" y="8.684"/><use xlink:href="#9" y="10.855"/><use xlink:href="#11" y="13.026"/><use xlink:href="#13" y="15.197"/></svg><svg x="3267"><use xlink:href="#a"/><use xlink:href="#4"/><use xlink:href="#5" y="2.171"/><use xlink:href="#6" y="4.342"/><use xlink:href="#7" y="6.513"/><use xlink:href="#8" y="8.684"/><use xlink:href="#9" y="10.855"/><use xlink:href="#11" y="13.026"/><use xlink:href="#13" y="15.197"/></svg><svg x="3388"><use xlink:href="#a"/><use xlink:href="#4"/><use xlink:href="#5" y="2.171"/><use xlink:href="#6" y="4.342"/><use xlink:href="#7" y="6.513"/><use xlink:href="#8" y="8.684"/><use xlink:href="#9" y="10.855"/><use xlink:href="#11" y="13.026"/><text y="16.867" class="h">(</text><text x="2.004" y="16.867" class="h">🐜</text><text x="8.016" y="16.867" class="h">)</text><text x="10.02" y="16.867" class="f">•</text><text x="12.024" y="16.867" class="f">Running</text><text x="20.04" y="16.867" class="f">NRFU</text><text x="25.05" y="16.867" class="f">Tests...</text><text x="34.068" y="16.867" class="i">15%</text><text x="38.076" y="16.867" class="m">━━━━━━━━</text><text x="46.092" y="16.867" class="j">╺━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━</text><text x="95.19" y="16.867" class="h">78/534</text><text x="102.204" y="16.867" class="f">•</text><text x="104.208" y="16.867" class="k">0:00:00</text><text x="112.224" y="16.867" class="f">•</text><text x="114.228" y="16.867" class="g">0:00:01</text></svg><svg x="3509"><use xlink:href="#a"/><use xlink:href="#4"/><use xlink:href="#5" y="2.171"/><use xlink:href="#6" y="4.342"/><use xlink:href="#7" y="6.513"/><use xlink:href="#8" y="8.684"/><use xlink:href="#9" y="10.855"/><use xlink:href="#11" y="13.026"/><text y="16.867" class="h">(🐜</text><text x="8.016" y="16.867" class="h">)</text><text x="10.02" y="16.867" class="f">•</text><text x="12.024" y="16.867" class="f">Running</text><text x="20.04" y="16.867" class="f">NRFU</text><text x="25.05" y="16.867" class="f">Tests...</text><text x="34.068" y="16.867" class="i">15%</text><text x="38.076" y="16.867" class="m">━━━━━━━━</text><text x="46.092" y="16.867" class="j">╺━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━</text><text x="95.19" y="16.867" class="h">78/534</text><text x="102.204" y="16.867" class="f">•</text><text x="104.208" y="16.867" class="k">0:00:00</text><text x="112.224" y="16.867" class="f">•</text><text x="114.228" y="16.867" class="g">0:00:01</text></svg><svg x="3630"><use xlink:href="#a"/><use xlink:href="#4"/><use xlink:href="#5" y="2.171"/><use xlink:href="#6" y="4.342"/><use xlink:href="#7" y="6.513"/><use xlink:href="#8" y="8.684"/><use xlink:href="#9" y="10.855"/><use xlink:href="#11" y="13.026"/><text y="16.867" class="h">(🐌</text><text x="8.016" y="16.867" class="h">)</text><text x="10.02" y="16.867" class="f">•</text><text x="12.024" y="16.867" class="f">Running</text><text x="20.04" y="16.867" class="f">NRFU</text><text x="25.05" y="16.867" class="f">Tests...</text><text x="34.068" y="16.867" class="i">18%</text><text x="38.076" y="16.867" class="m">━━━━━━━━━━</text><text x="48.096" y="16.867" class="j">╺━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━</text><text x="95.19" y="16.867" class="h">98/534</text><text x="102.204" y="16.867" class="f">•</text><text x="104.208" y="16.867" class="k">0:00:00</text><text x="112.224" y="16.867" class="f">•</text><text x="114.228" y="16.867" class="g">0:00:05</text></svg><svg x="3751"><use xlink:href="#a"/><use xlink:href="#4"/><use xlink:href="#5" y="2.171"/><use xlink:href="#6" y="4.342"/><use xlink:href="#7" y="6.513"/><use xlink:href="#8" y="8.684"/><use xlink:href="#9" y="10.855"/><use xlink:href="#11" y="13.026"/><text y="16.867" class="h">(🐌</text><text x="8.016" y="16.867" class="h">)</text><text x="10.02" y="16.867" class="f">•</text><text x="12.024" y="16.867" class="f">Running</text><text x="20.04" y="16.867" class="f">NRFU</text><text x="25.05" y="16.867" class="f">Tests...</text><text x="34.068" y="16.867" class="i">35%</text><text x="38.076" y="16.867" class="m">━━━━━━━━━━━━━━━━━━━</text><text x="57.114" y="16.867" class="j">╺━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━</text><text x="94.188" y="16.867" class="h">189/534</text><text x="102.204" y="16.867" class="f">•</text><text x="104.208" y="16.867" class="k">0:00:01</text><text x="112.224" y="16.867" class="f">•</text><text x="114.228" y="16.867" class="g">0:00:02</text></svg><svg x="3872"><use xlink:href="#a"/><use xlink:href="#4"/><use xlink:href="#5" y="2.171"/><use xlink:href="#6" y="4.342"/><use xlink:href="#7" y="6.513"/><use xlink:href="#8" y="8.684"/><use xlink:href="#9" y="10.855"/><use xlink:href="#11" y="13.026"/><text y="16.867" class="h">(</text><text x="2.004" y="16.867" class="h">🐌</text><text x="8.016" y="16.867" class="h">)</text><text x="10.02" y="16.867" class="f">•</text><text x="12.024" y="16.867" class="f">Running</text><text x="20.04" y="16.867" class="f">NRFU</text><text x="25.05" y="16.867" class="f">Tests...</text><text x="34.068" y="16.867" class="i">55%</text><text x="38.076" y="16.867" class="m">━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━</text><text x="68.136" y="16.867" class="j">╺━━━━━━━━━━━━━━━━━━━━━━━━</text><text x="94.188" y="16.867" class="h">293/534</text><text x="102.204" y="16.867" class="f">•</text><text x="104.208" y="16.867" class="k">0:00:01</text><text x="112.224" y="16.867" class="f">•</text><text x="114.228" y="16.867" class="g">0:00:01</text></svg><svg x="3993"><use xlink:href="#a"/><use xlink:href="#4"/><use xlink:href="#5" y="2.171"/><use xlink:href="#6" y="4.342"/><use xlink:href="#7" y="6.513"/><use xlink:href="#8" y="8.684"/><use xlink:href="#9" y="10.855"/><use xlink:href="#11" y="13.026"/><text y="16.867" class="h">(</text><text x="3.006" y="16.867" class="h">🐌</text><text x="8.016" y="16.867" class="h">)</text><text x="10.02" y="16.867" class="f">•</text><text x="12.024" y="16.867" class="f">Running</text><text x="20.04" y="16.867" class="f">NRFU</text><text x="25.05" y="16.867" class="f">Tests...</text><text x="34.068" y="16.867" class="i">58%</text><text x="38.076" y="16.867" class="m">━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━</text><text x="70.14" y="16.867" class="j">╺━━━━━━━━━━━━━━━━━━━━━━</text><text x="94.188" y="16.867" class="h">311/534</text><text x="102.204" y="16.867" class="f">•</text><text x="104.208" y="16.867" class="k">0:00:01</text><text x="112.224" y="16.867" class="f">•</text><text x="114.228" y="16.867" class="g">0:00:01</text></svg><svg x="4114"><use xlink:href="#a"/><use xlink:href="#4"/><use xlink:href="#5" y="2.171"/><use xlink:href="#6" y="4.342"/><use xlink:href="#7" y="6.513"/><use xlink:href="#8" y="8.684"/><use xlink:href="#9" y="10.855"/><use xlink:href="#11" y="13.026"/><text y="16.867" class="h">(</text><text x="3.006" y="16.867" class="h">🐌</text><text x="8.016" y="16.867" class="h">)</text><text x="10.02" y="16.867" class="f">•</text><text x="12.024" y="16.867" class="f">Running</text><text x="20.04" y="16.867" class="f">NRFU</text><text x="25.05" y="16.867" class="f">Tests...</text><text x="34.068" y="16.867" class="i">63%</text><text x="38.076" y="16.867" class="m">━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╸</text><text x="73.146" y="16.867" class="j">━━━━━━━━━━━━━━━━━━━━</text><text x="94.188" y="16.867" class="h">335/534</text><text x="102.204" y="16.867" class="f">•</text><text x="104.208" y="16.867" class="k">0:00:01</text><text x="112.224" y="16.867" class="f">•</text><text x="114.228" y="16.867" class="g">0:00:01</text></svg><svg x="4235"><use xlink:href="#a"/><use xlink:href="#4"/><use xlink:href="#5" y="2.171"/><use xlink:href="#6" y="4.342"/><use xlink:href="#7" y="6.513"/><use xlink:href="#8" y="8.684"/><use xlink:href="#9" y="10.855"/><use xlink:href="#11" y="13.026"/><text y="16.867" class="h">(</text><text x="4.008" y="16.867" class="h">🐌</text><text x="8.016" y="16.867" class="h">)</text><text x="10.02" y="16.867" class="f">•</text><text x="12.024" y="16.867" class="f">Running</text><text x="20.04" y="16.867" class="f">NRFU</text><text x="25.05" y="16.867" class="f">Tests...</text><text x="34.068" y="16.867" class="i">67%</text><text x="38.076" y="16.867" class="m">━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━</text><text x="75.15" y="16.867" class="j">╺━━━━━━━━━━━━━━━━━</text><text x="94.188" y="16.867" class="h">360/534</text><text x="102.204" y="16.867" class="f">•</text><text x="104.208" y="16.867" class="k">0:00:01</text><text x="112.224" y="16.867" class="f">•</text><text x="114.228" y="16.867" class="g">0:00:01</text></svg><svg x="4356"><use xlink:href="#a"/><use xlink:href="#4"/><use xlink:href="#5" y="2.171"/><use xlink:href="#6" y="4.342"/><use xlink:href="#7" y="6.513"/><use xlink:href="#8" y="8.684"/><use xlink:href="#9" y="10.855"/><use xlink:href="#11" y="13.026"/><text y="16.867" class="h">(</text><text x="5.01" y="16.867" class="h">🐌</text><text x="8.016" y="16.867" class="h">)</text><text x="10.02" y="16.867" class="f">•</text><text x="12.024" y="16.867" class="f">Running</text><text x="20.04" y="16.867" class="f">NRFU</text><text x="25.05" y="16.867" class="f">Tests...</text><text x="34.068" y="16.867" class="i">71%</text><text x="38.076" y="16.867" class="m">━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╸</text><text x="77.154" y="16.867" class="j">━━━━━━━━━━━━━━━━</text><text x="94.188" y="16.867" class="h">378/534</text><text x="102.204" y="16.867" class="f">•</text><text x="104.208" y="16.867" class="k">0:00:01</text><text x="112.224" y="16.867" class="f">•</text><text x="114.228" y="16.867" class="g">0:00:01</text></svg><svg x="4477"><use xlink:href="#a"/><use xlink:href="#4"/><use xlink:href="#5" y="2.171"/><use xlink:href="#6" y="4.342"/><use xlink:href="#7" y="6.513"/><use xlink:href="#8" y="8.684"/><use xlink:href="#9" y="10.855"/><use xlink:href="#11" y="13.026"/><text y="16.867" class="h">(</text><text x="5.01" y="16.867" class="h">🐌</text><text x="8.016" y="16.867" class="h">)</text><text x="10.02" y="16.867" class="f">•</text><text x="12.024" y="16.867" class="f">Running</text><text x="20.04" y="16.867" class="f">NRFU</text><text x="25.05" y="16.867" class="f">Tests...</text><text x="34.068" y="16.867" class="i">72%</text><text x="38.076" y="16.867" class="m">━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━</text><text x="77.154" y="16.867" class="j">╺━━━━━━━━━━━━━━━</text><text x="94.188" y="16.867" class="h">383/534</text><text x="102.204" y="16.867" class="f">•</text><text x="104.208" y="16.867" class="k">0:00:01</text><text x="112.224" y="16.867" class="f">•</text><text x="114.228" y="16.867" class="g">0:00:01</text></svg><svg x="4598"><use xlink:href="#a"/><use xlink:href="#4"/><use xlink:href="#5" y="2.171"/><use xlink:href="#6" y="4.342"/><use xlink:href="#7" y="6.513"/><use xlink:href="#8" y="8.684"/><use xlink:href="#9" y="10.855"/><use xlink:href="#11" y="13.026"/><text y="16.867" class="h">(</text><text x="6.012" y="16.867" class="h">🐌)</text><text x="10.02" y="16.867" class="f">•</text><text x="12.024" y="16.867" class="f">Running</text><text x="20.04" y="16.867" class="f">NRFU</text><text x="25.05" y="16.867" class="f">Tests...</text><text x="34.068" y="16.867" class="i">72%</text><text x="38.076" y="16.867" class="m">━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╸</text><text x="78.156" y="16.867" class="j">━━━━━━━━━━━━━━━</text><text x="94.188" y="16.867" class="h">385/534</text><text x="102.204" y="16.867" class="f">•</text><text x="104.208" y="16.867" class="k">0:00:01</text><text x="112.224" y="16.867" class="f">•</text><text x="114.228" y="16.867" class="g">0:00:01</text></svg><svg x="4719"><use xlink:href="#a"/><use xlink:href="#4"/><use xlink:href="#5" y="2.171"/><use xlink:href="#6" y="4.342"/><use xlink:href="#7" y="6.513"/><use xlink:href="#8" y="8.684"/><use xlink:href="#9" y="10.855"/><use xlink:href="#11" y="13.026"/><text y="16.867" class="h">(</text><text x="6.012" y="16.867" class="h">🐜)</text><text x="10.02" y="16.867" class="f">•</text><text x="12.024" y="16.867" class="f">Running</text><text x="20.04" y="16.867" class="f">NRFU</text><text x="25.05" y="16.867" class="f">Tests...</text><text x="34.068" y="16.867" class="i">76%</text><text x="38.076" y="16.867" class="m">━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╸</text><text x="80.16" y="16.867" class="j">━━━━━━━━━━━━━</text><text x="94.188" y="16.867" class="h">407/534</text><text x="102.204" y="16.867" class="f">•</text><text x="104.208" y="16.867" class="k">0:00:01</text><text x="112.224" y="16.867" class="f">•</text><text x="114.228" y="16.867" class="g">0:00:01</text></svg><svg x="4840"><use xlink:href="#a"/><use xlink:href="#4"/><use xlink:href="#5" y="2.171"/><use xlink:href="#6" y="4.342"/><use xlink:href="#7" y="6.513"/><use xlink:href="#8" y="8.684"/><use xlink:href="#9" y="10.855"/><use xlink:href="#11" y="13.026"/><text y="16.867" class="h">(</text><text x="6.012" y="16.867" class="h">🐜)</text><text x="10.02" y="16.867" class="f">•</text><text x="12.024" y="16.867" class="f">Running</text><text x="20.04" y="16.867" class="f">NRFU</text><text x="25.05" y="16.867" class="f">Tests...</text><text x="34.068" y="16.867" class="i">81%</text><text x="38.076" y="16.867" class="m">━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╸</text><text x="83.166" y="16.867" class="j">━━━━━━━━━━</text><text x="94.188" y="16.867" class="h">433/534</text><text x="102.204" y="16.867" class="f">•</text><text x="104.208" y="16.867" class="k">0:00:01</text><text x="112.224" y="16.867" class="f">•</text><text x="114.228" y="16.867" class="g">0:00:01</text></svg><svg x="4961"><use xlink:href="#a"/><use xlink:href="#4"/><use xlink:href="#5" y="2.171"/><use xlink:href="#6" y="4.342"/><use xlink:href="#7" y="6.513"/><use xlink:href="#8" y="8.684"/><use xlink:href="#9" y="10.855"/><use xlink:href="#11" y="13.026"/><text y="16.867" class="h">(</text><text x="5.01" y="16.867" class="h">🐜</text><text x="8.016" y="16.867" class="h">)</text><text x="10.02" y="16.867" class="f">•</text><text x="12.024" y="16.867" class="f">Running</text><text x="20.04" y="16.867" class="f">NRFU</text><text x="25.05" y="16.867" class="f">Tests...</text><text x="34.068" y="16.867" class="i">84%</text><text x="38.076" y="16.867" class="m">━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━</text><text x="84.168" y="16.867" class="j">╺━━━━━━━━</text><text x="94.188" y="16.867" class="h">447/534</text><text x="102.204" y="16.867" class="f">•</text><text x="104.208" y="16.867" class="k">0:00:02</text><text x="112.224" y="16.867" class="f">•</text><text x="114.228" y="16.867" class="g">0:00:01</text></svg><svg x="5082"><use xlink:href="#a"/><use xlink:href="#4"/><use xlink:href="#5" y="2.171"/><use xlink:href="#6" y="4.342"/><use xlink:href="#7" y="6.513"/><use xlink:href="#8" y="8.684"/><use xlink:href="#9" y="10.855"/><use xlink:href="#11" y="13.026"/><text y="16.867" class="h">(</text><text x="4.008" y="16.867" class="h">🐜</text><text x="8.016" y="16.867" class="h">)</text><text x="10.02" y="16.867" class="f">•</text><text x="12.024" y="16.867" class="f">Running</text><text x="20.04" y="16.867" class="f">NRFU</text><text x="25.05" y="16.867" class="f">Tests...</text><text x="34.068" y="16.867" class="i">85%</text><text x="38.076" y="16.867" class="m">━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╸</text><text x="85.17" y="16.867" class="j">━━━━━━━━</text><text x="94.188" y="16.867" class="h">456/534</text><text x="102.204" y="16.867" class="f">•</text><text x="104.208" y="16.867" class="k">0:00:02</text><text x="112.224" y="16.867" class="f">•</text><text x="114.228" y="16.867" class="g">0:00:01</text></svg><svg x="5203"><use xlink:href="#a"/><use xlink:href="#4"/><use xlink:href="#5" y="2.171"/><use xlink:href="#6" y="4.342"/><use xlink:href="#7" y="6.513"/><use xlink:href="#8" y="8.684"/><use xlink:href="#9" y="10.855"/><use xlink:href="#11" y="13.026"/><text y="16.867" class="h">(</text><text x="4.008" y="16.867" class="h">🐜</text><text x="8.016" y="16.867" class="h">)</text><text x="10.02" y="16.867" class="f">•</text><text x="12.024" y="16.867" class="f">Running</text><text x="20.04" y="16.867" class="f">NRFU</text><text x="25.05" y="16.867" class="f">Tests...</text><text x="34.068" y="16.867" class="i">87%</text><text x="38.076" y="16.867" class="m">━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━</text><text x="86.172" y="16.867" class="j">╺━━━━━━</text><text x="94.188" y="16.867" class="h">467/534</text><text x="102.204" y="16.867" class="f">•</text><text x="104.208" y="16.867" class="k">0:00:02</text><text x="112.224" y="16.867" class="f">•</text><text x="114.228" y="16.867" class="g">0:00:01</text></svg><svg x="5324"><use xlink:href="#a"/><use xlink:href="#4"/><use xlink:href="#5" y="2.171"/><use xlink:href="#6" y="4.342"/><use xlink:href="#7" y="6.513"/><use xlink:href="#8" y="8.684"/><use xlink:href="#9" y="10.855"/><use xlink:href="#11" y="13.026"/><text y="16.867" class="h">(</text><text x="3.006" y="16.867" class="h">🐜</text><text x="8.016" y="16.867" class="h">)</text><text x="10.02" y="16.867" class="f">•</text><text x="12.024" y="16.867" class="f">Running</text><text x="20.04" y="16.867" class="f">NRFU</text><text x="25.05" y="16.867" class="f">Tests...</text><text x="34.068" y="16.867" class="i">89%</text><text x="38.076" y="16.867" class="m">━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━</text><text x="87.174" y="16.867" class="j">╺━━━━━</text><text x="94.188" y="16.867" class="h">476/534</text><text x="102.204" y="16.867" class="f">•</text><text x="104.208" y="16.867" class="k">0:00:02</text><text x="112.224" y="16.867" class="f">•</text><text x="114.228" y="16.867" class="g">0:00:01</text></svg><svg x="5445"><use xlink:href="#a"/><use xlink:href="#4"/><use xlink:href="#5" y="2.171"/><use xlink:href="#6" y="4.342"/><use xlink:href="#7" y="6.513"/><use xlink:href="#8" y="8.684"/><use xlink:href="#9" y="10.855"/><use xlink:href="#11" y="13.026"/><text y="16.867" class="h">(</text><text x="2.004" y="16.867" class="h">🐜</text><text x="8.016" y="16.867" class="h">)</text><text x="10.02" y="16.867" class="f">•</text><text x="12.024" y="16.867" class="f">Running</text><text x="20.04" y="16.867" class="f">NRFU</text><text x="25.05" y="16.867" class="f">Tests...</text><text x="34.068" y="16.867" class="i">91%</text><text x="38.076" y="16.867" class="m">━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━</text><text x="88.176" y="16.867" class="j">╺━━━━</text><text x="94.188" y="16.867" class="h">486/534</text><text x="102.204" y="16.867" class="f">•</text><text x="104.208" y="16.867" class="k">0:00:02</text><text x="112.224" y="16.867" class="f">•</text><text x="114.228" y="16.867" class="g">0:00:01</text></svg><svg x="5566"><use xlink:href="#a"/><use xlink:href="#4"/><use xlink:href="#5" y="2.171"/><use xlink:href="#6" y="4.342"/><use xlink:href="#7" y="6.513"/><use xlink:href="#8" y="8.684"/><use xlink:href="#9" y="10.855"/><use xlink:href="#11" y="13.026"/><text y="16.867" class="h">(</text><text x="2.004" y="16.867" class="h">🐜</text><text x="8.016" y="16.867" class="h">)</text><text x="10.02" y="16.867" class="f">•</text><text x="12.024" y="16.867" class="f">Running</text><text x="20.04" y="16.867" class="f">NRFU</text><text x="25.05" y="16.867" class="f">Tests...</text><text x="34.068" y="16.867" class="i">95%</text><text x="38.076" y="16.867" class="m">━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━</text><text x="90.18" y="16.867" class="j">╺━━</text><text x="94.188" y="16.867" class="h">505/534</text><text x="102.204" y="16.867" class="f">•</text><text x="104.208" y="16.867" class="k">0:00:02</text><text x="112.224" y="16.867" class="f">•</text><text x="114.228" y="16.867" class="g">0:00:01</text></svg><svg x="5687"><use xlink:href="#a"/><use xlink:href="#4"/><use xlink:href="#5" y="2.171"/><use xlink:href="#6" y="4.342"/><use xlink:href="#7" y="6.513"/><use xlink:href="#8" y="8.684"/><use xlink:href="#9" y="10.855"/><use xlink:href="#11" y="13.026"/><text y="16.867" class="h">(🐜</text><text x="8.016" y="16.867" class="h">)</text><text x="10.02" y="16.867" class="f">•</text><text x="12.024" y="16.867" class="f">Running</text><text x="20.04" y="16.867" class="f">NRFU</text><text x="25.05" y="16.867" class="f">Tests...</text><text x="34.068" y="16.867" class="i">98%</text><text x="38.076" y="16.867" class="m">━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╸</text><text x="92.184" y="16.867" class="j">━</text><text x="94.188" y="16.867" class="h">521/534</text><text x="102.204" y="16.867" class="f">•</text><text x="104.208" y="16.867" class="k">0:00:02</text><text x="112.224" y="16.867" class="f">•</text><text x="114.228" y="16.867" class="g">0:00:01</text></svg><svg x="5808"><use xlink:href="#a"/><use xlink:href="#4"/><use xlink:href="#5" y="2.171"/><use xlink:href="#6" y="4.342"/><use xlink:href="#7" y="6.513"/><use xlink:href="#8" y="8.684"/><use xlink:href="#9" y="10.855"/><use xlink:href="#11" y="13.026"/><text y="16.867" class="h">(🐌</text><text x="8.016" y="16.867" class="h">)</text><text x="10.02" y="16.867" class="f">•</text><text x="12.024" y="16.867" class="f">Running</text><text x="20.04" y="16.867" class="f">NRFU</text><text x="25.05" y="16.867" class="f">Tests...</text><text x="34.068" y="16.867" class="i">99%</text><text x="38.076" y="16.867" class="m">━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━</text><text x="92.184" y="16.867" class="j">╺</text><text x="94.188" y="16.867" class="h">528/534</text><text x="102.204" y="16.867" class="f">•</text><text x="104.208" y="16.867" class="k">0:00:02</text><text x="112.224" y="16.867" class="f">•</text><text x="114.228" y="16.867" class="g">0:00:01</text></svg><svg x="5929"><use xlink:href="#a"/><use xlink:href="#4"/><use xlink:href="#5" y="2.171"/><use xlink:href="#6" y="4.342"/><use xlink:href="#7" y="6.513"/><use xlink:href="#8" y="8.684"/><use xlink:href="#9" y="10.855"/><use xlink:href="#11" y="13.026"/><use xlink:href="#14" y="15.197"/></svg><svg x="6050"><use xlink:href="#a"/><use xlink:href="#4"/><use xlink:href="#5" y="2.171"/><use xlink:href="#6" y="4.342"/><use xlink:href="#7" y="6.513"/><use xlink:href="#8" y="8.684"/><use xlink:href="#9" y="10.855"/><use xlink:href="#11" y="13.026"/><use xlink:href="#14" y="15.197"/></svg><svg x="6171"><use xlink:href="#a"/><use xlink:href="#4"/><use xlink:href="#5" y="2.171"/><use xlink:href="#6" y="4.342"/><use xlink:href="#7" y="6.513"/><use xlink:href="#8" y="8.684"/><use xlink:href="#9" y="10.855"/><use xlink:href="#11" y="13.026"/><text y="16.867" class="h">(</text><text x="3.006" y="16.867" class="h">🐌</text><text x="8.016" y="16.867" class="h">)</text><text x="10.02" y="16.867" class="f">•</text><text x="12.024" y="16.867" class="f">Running</text><text x="20.04" y="16.867" class="f">NRFU</text><text x="25.05" y="16.867" class="f">Tests...</text><text x="34.068" y="16.867" class="i">99%</text><text x="38.076" y="16.867" class="m">━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╸</text><text x="94.188" y="16.867" class="h">531/534</text><text x="102.204" y="16.867" class="f">•</text><text x="104.208" y="16.867" class="k">0:00:03</text><text x="112.224" y="16.867" class="f">•</text><text x="114.228" y="16.867" class="g">0:00:01</text></svg><svg x="6292"><use xlink:href="#a"/><use xlink:href="#4"/><use xlink:href="#5" y="2.171"/><use xlink:href="#6" y="4.342"/><use xlink:href="#7" y="6.513"/><use xlink:href="#8" y="8.684"/><use xlink:href="#9" y="10.855"/><use xlink:href="#11" y="13.026"/><use xlink:href="#15" y="15.197"/></svg><svg x="6413"><use xlink:href="#a"/><use xlink:href="#4"/><use xlink:href="#5" y="2.171"/><use xlink:href="#6" y="4.342"/><use xlink:href="#7" y="6.513"/><use xlink:href="#8" y="8.684"/><use xlink:href="#9" y="10.855"/><use xlink:href="#11" y="13.026"/><use xlink:href="#15" y="15.197"/></svg><svg x="6534"><use xlink:href="#a"/><use xlink:href="#4"/><use xlink:href="#5" y="2.171"/><use xlink:href="#6" y="4.342"/><use xlink:href="#7" y="6.513"/><use xlink:href="#8" y="8.684"/><use xlink:href="#9" y="10.855"/><use xlink:href="#11" y="13.026"/><text y="16.867" class="h">(</text><text x="5.01" y="16.867" class="h">🐌</text><text x="8.016" y="16.867" class="h">)</text><text x="10.02" y="16.867" class="f">•</text><text x="12.024" y="16.867" class="f">Running</text><text x="20.04" y="16.867" class="f">NRFU</text><text x="25.05" y="16.867" class="f">Tests...</text><text x="34.068" y="16.867" class="i">99%</text><text x="38.076" y="16.867" class="m">━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╸</text><text x="94.188" y="16.867" class="h">531/534</text><text x="102.204" y="16.867" class="f">•</text><text x="104.208" y="16.867" class="k">0:00:03</text><text x="112.224" y="16.867" class="f">•</text><text x="114.228" y="16.867" class="g">0:00:01</text></svg><svg x="6655"><use xlink:href="#a"/><use xlink:href="#4"/><use xlink:href="#5" y="2.171"/><use xlink:href="#6" y="4.342"/><use xlink:href="#7" y="6.513"/><use xlink:href="#8" y="8.684"/><use xlink:href="#9" y="10.855"/><use xlink:href="#11" y="13.026"/><use xlink:href="#16" y="15.197"/></svg><svg x="6776"><use xlink:href="#a"/><use xlink:href="#4"/><use xlink:href="#5" y="2.171"/><use xlink:href="#6" y="4.342"/><use xlink:href="#7" y="6.513"/><use xlink:href="#8" y="8.684"/><use xlink:href="#9" y="10.855"/><use xlink:href="#11" y="13.026"/><use xlink:href="#16" y="15.197"/></svg><svg x="6897"><use xlink:href="#a"/><use xlink:href="#4"/><use xlink:href="#5" y="2.171"/><use xlink:href="#6" y="4.342"/><use xlink:href="#7" y="6.513"/><use xlink:href="#8" y="8.684"/><use xlink:href="#9" y="10.855"/><use xlink:href="#11" y="13.026"/><text y="16.867" class="h">(</text><text x="6.012" y="16.867" class="h">🐜)</text><text x="10.02" y="16.867" class="f">•</text><text x="12.024" y="16.867" class="f">Running</text><text x="20.04" y="16.867" class="f">NRFU</text><text x="25.05" y="16.867" class="f">Tests...</text><text x="34.068" y="16.867" class="i">99%</text><text x="38.076" y="16.867" class="m">━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╸</text><text x="94.188" y="16.867" class="h">531/534</text><text x="102.204" y="16.867" class="f">•</text><text x="104.208" y="16.867" class="k">0:00:03</text><text x="112.224" y="16.867" class="f">•</text><text x="114.228" y="16.867" class="g">0:00:01</text></svg><svg x="7018"><use xlink:href="#a"/><use xlink:href="#4"/><use xlink:href="#5" y="2.171"/><use xlink:href="#6" y="4.342"/><use xlink:href="#7" y="6.513"/><use xlink:href="#8" y="8.684"/><use xlink:href="#9" y="10.855"/><use xlink:href="#11" y="13.026"/><use xlink:href="#17" y="15.197"/></svg><svg x="7139"><use xlink:href="#a"/><use xlink:href="#4"/><use xlink:href="#5" y="2.171"/><use xlink:href="#6" y="4.342"/><use xlink:href="#7" y="6.513"/><use xlink:href="#8" y="8.684"/><use xlink:href="#9" y="10.855"/><use xlink:href="#11" y="13.026"/><use xlink:href="#17" y="15.197"/></svg><svg x="7260"><use xlink:href="#a"/><use xlink:href="#4"/><use xlink:href="#5" y="2.171"/><use xlink:href="#6" y="4.342"/><use xlink:href="#7" y="6.513"/><use xlink:href="#8" y="8.684"/><use xlink:href="#9" y="10.855"/><use xlink:href="#11" y="13.026"/><text y="16.867" class="h">(</text><text x="4.008" y="16.867" class="h">🐜</text><text x="8.016" y="16.867" class="h">)</text><text x="10.02" y="16.867" class="f">•</text><text x="12.024" y="16.867" class="f">Running</text><text x="20.04" y="16.867" class="f">NRFU</text><text x="25.05" y="16.867" class="f">Tests...</text><text x="34.068" y="16.867" class="i">99%</text><text x="38.076" y="16.867" class="m">━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╸</text><text x="94.188" y="16.867" class="h">531/534</text><text x="102.204" y="16.867" class="f">•</text><text x="104.208" y="16.867" class="k">0:00:03</text><text x="112.224" y="16.867" class="f">•</text><text x="114.228" y="16.867" class="g">0:00:01</text></svg><svg x="7381"><use xlink:href="#a"/><use xlink:href="#4"/><use xlink:href="#5" y="2.171"/><use xlink:href="#6" y="4.342"/><use xlink:href="#7" y="6.513"/><use xlink:href="#8" y="8.684"/><use xlink:href="#9" y="10.855"/><use xlink:href="#11" y="13.026"/><text y="16.867" class="h">(</text><text x="3.006" y="16.867" class="h">🐜</text><text x="8.016" y="16.867" class="h">)</text><text x="10.02" y="16.867" class="f">•</text><text x="12.024" y="16.867" class="f">Running</text><text x="20.04" y="16.867" class="f">NRFU</text><text x="25.05" y="16.867" class="f">Tests...</text><text x="33.066" y="16.867" class="i">100%</text><text x="38.076" y="16.867" class="m">━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╸</text><text x="94.188" y="16.867" class="h">533/534</text><text x="102.204" y="16.867" class="f">•</text><text x="104.208" y="16.867" class="k">0:00:04</text><text x="112.224" y="16.867" class="f">•</text><text x="114.228" y="16.867" class="g">0:00:01</text></svg><svg x="7502"><use xlink:href="#a"/><use xlink:href="#b" x="-.004" y="17.343"/><use xlink:href="#4"/><use xlink:href="#5" y="2.171"/><use xlink:href="#6" y="4.342"/><use xlink:href="#7" y="6.513"/><use xlink:href="#8" y="8.684"/><use xlink:href="#9" y="10.855"/><use xlink:href="#11" y="13.026"/><use xlink:href="#18" y="15.197"/></svg><svg x="7623"><use xlink:href="#a"/><use xlink:href="#b" x="1.996" y="17.343"/><use xlink:href="#4"/><use xlink:href="#5" y="2.171"/><use xlink:href="#6" y="4.342"/><use xlink:href="#7" y="6.513"/><use xlink:href="#8" y="8.684"/><use xlink:href="#9" y="10.855"/><use xlink:href="#11" y="13.026"/><use xlink:href="#18" y="15.197"/><use xlink:href="#1" y="17.368"/></svg></svg></g></g></svg></svg>
diff --git a/docs/imgs/anta_nrfu___dry_run.svg b/docs/imgs/anta_nrfu___dry_run.svg
new file mode 100644
index 0000000..9b5876e
--- /dev/null
+++ b/docs/imgs/anta_nrfu___dry_run.svg
@@ -0,0 +1,127 @@
+<svg class="rich-terminal" viewBox="0 0 1482 440.4" xmlns="http://www.w3.org/2000/svg">
+ <!-- Generated with Rich https://www.textualize.io -->
+ <style>
+
+ @font-face {
+ font-family: "Fira Code";
+ src: local("FiraCode-Regular"),
+ url("https://cdnjs.cloudflare.com/ajax/libs/firacode/6.2.0/woff2/FiraCode-Regular.woff2") format("woff2"),
+ url("https://cdnjs.cloudflare.com/ajax/libs/firacode/6.2.0/woff/FiraCode-Regular.woff") format("woff");
+ font-style: normal;
+ font-weight: 400;
+ }
+ @font-face {
+ font-family: "Fira Code";
+ src: local("FiraCode-Bold"),
+ url("https://cdnjs.cloudflare.com/ajax/libs/firacode/6.2.0/woff2/FiraCode-Bold.woff2") format("woff2"),
+ url("https://cdnjs.cloudflare.com/ajax/libs/firacode/6.2.0/woff/FiraCode-Bold.woff") format("woff");
+ font-style: bold;
+ font-weight: 700;
+ }
+
+ .terminal-2602327173-matrix {
+ font-family: Fira Code, monospace;
+ font-size: 20px;
+ line-height: 24.4px;
+ font-variant-east-asian: full-width;
+ }
+
+ .terminal-2602327173-title {
+ font-size: 18px;
+ font-weight: bold;
+ font-family: arial;
+ }
+
+ .terminal-2602327173-r1 { fill: #c5c8c6 }
+.terminal-2602327173-r2 { fill: #68a0b3 }
+.terminal-2602327173-r3 { fill: #98a84b }
+.terminal-2602327173-r4 { fill: #4e707b }
+.terminal-2602327173-r5 { fill: #608ab1 }
+.terminal-2602327173-r6 { fill: #d0b344 }
+.terminal-2602327173-r7 { fill: #868887 }
+.terminal-2602327173-r8 { fill: #00823d;font-weight: bold }
+.terminal-2602327173-r9 { fill: #68a0b3;font-weight: bold }
+.terminal-2602327173-r10 { fill: #c5c8c6;font-weight: bold }
+ </style>
+
+ <defs>
+ <clipPath id="terminal-2602327173-clip-terminal">
+ <rect x="0" y="0" width="1463.0" height="389.4" />
+ </clipPath>
+ <clipPath id="terminal-2602327173-line-0">
+ <rect x="0" y="1.5" width="1464" height="24.65"/>
+ </clipPath>
+<clipPath id="terminal-2602327173-line-1">
+ <rect x="0" y="25.9" width="1464" height="24.65"/>
+ </clipPath>
+<clipPath id="terminal-2602327173-line-2">
+ <rect x="0" y="50.3" width="1464" height="24.65"/>
+ </clipPath>
+<clipPath id="terminal-2602327173-line-3">
+ <rect x="0" y="74.7" width="1464" height="24.65"/>
+ </clipPath>
+<clipPath id="terminal-2602327173-line-4">
+ <rect x="0" y="99.1" width="1464" height="24.65"/>
+ </clipPath>
+<clipPath id="terminal-2602327173-line-5">
+ <rect x="0" y="123.5" width="1464" height="24.65"/>
+ </clipPath>
+<clipPath id="terminal-2602327173-line-6">
+ <rect x="0" y="147.9" width="1464" height="24.65"/>
+ </clipPath>
+<clipPath id="terminal-2602327173-line-7">
+ <rect x="0" y="172.3" width="1464" height="24.65"/>
+ </clipPath>
+<clipPath id="terminal-2602327173-line-8">
+ <rect x="0" y="196.7" width="1464" height="24.65"/>
+ </clipPath>
+<clipPath id="terminal-2602327173-line-9">
+ <rect x="0" y="221.1" width="1464" height="24.65"/>
+ </clipPath>
+<clipPath id="terminal-2602327173-line-10">
+ <rect x="0" y="245.5" width="1464" height="24.65"/>
+ </clipPath>
+<clipPath id="terminal-2602327173-line-11">
+ <rect x="0" y="269.9" width="1464" height="24.65"/>
+ </clipPath>
+<clipPath id="terminal-2602327173-line-12">
+ <rect x="0" y="294.3" width="1464" height="24.65"/>
+ </clipPath>
+<clipPath id="terminal-2602327173-line-13">
+ <rect x="0" y="318.7" width="1464" height="24.65"/>
+ </clipPath>
+<clipPath id="terminal-2602327173-line-14">
+ <rect x="0" y="343.1" width="1464" height="24.65"/>
+ </clipPath>
+ </defs>
+
+ <rect fill="#292929" stroke="rgba(255,255,255,0.35)" stroke-width="1" x="1" y="1" width="1480" height="438.4" rx="8"/><text class="terminal-2602327173-title" fill="#c5c8c6" text-anchor="middle" x="740" y="27">anta&#160;nrfu&#160;--dry-run</text>
+ <g transform="translate(26,22)">
+ <circle cx="0" cy="0" r="7" fill="#ff5f57"/>
+ <circle cx="22" cy="0" r="7" fill="#febc2e"/>
+ <circle cx="44" cy="0" r="7" fill="#28c840"/>
+ </g>
+
+ <g transform="translate(9, 41)" clip-path="url(#terminal-2602327173-clip-terminal)">
+
+ <g class="terminal-2602327173-matrix">
+ <text class="terminal-2602327173-r1" x="0" y="20" textLength="390.4" clip-path="url(#terminal-2602327173-line-0)">ant@anthill$&#160;anta&#160;nrfu&#160;--dry-run</text><text class="terminal-2602327173-r1" x="1464" y="20" textLength="12.2" clip-path="url(#terminal-2602327173-line-0)">
+</text><text class="terminal-2602327173-r2" x="0" y="44.4" textLength="24.4" clip-path="url(#terminal-2602327173-line-1)">╭─</text><text class="terminal-2602327173-r2" x="24.4" y="44.4" textLength="256.2" clip-path="url(#terminal-2602327173-line-1)">─────────────────────</text><text class="terminal-2602327173-r3" x="292.8" y="44.4" textLength="97.6" clip-path="url(#terminal-2602327173-line-1)">Settings</text><text class="terminal-2602327173-r2" x="402.6" y="44.4" textLength="256.2" clip-path="url(#terminal-2602327173-line-1)">─────────────────────</text><text class="terminal-2602327173-r2" x="658.8" y="44.4" textLength="24.4" clip-path="url(#terminal-2602327173-line-1)">─╮</text><text class="terminal-2602327173-r1" x="1464" y="44.4" textLength="12.2" clip-path="url(#terminal-2602327173-line-1)">
+</text><text class="terminal-2602327173-r2" x="0" y="68.8" textLength="12.2" clip-path="url(#terminal-2602327173-line-2)">│</text><text class="terminal-2602327173-r2" x="24.4" y="68.8" textLength="634.4" clip-path="url(#terminal-2602327173-line-2)">-&#160;ANTA&#160;Inventory&#160;contains&#160;3&#160;devices&#160;(AsyncEOSDevice)</text><text class="terminal-2602327173-r2" x="671" y="68.8" textLength="12.2" clip-path="url(#terminal-2602327173-line-2)">│</text><text class="terminal-2602327173-r1" x="1464" y="68.8" textLength="12.2" clip-path="url(#terminal-2602327173-line-2)">
+</text><text class="terminal-2602327173-r2" x="0" y="93.2" textLength="12.2" clip-path="url(#terminal-2602327173-line-3)">│</text><text class="terminal-2602327173-r2" x="24.4" y="93.2" textLength="390.4" clip-path="url(#terminal-2602327173-line-3)">-&#160;Tests&#160;catalog&#160;contains&#160;9&#160;tests</text><text class="terminal-2602327173-r2" x="671" y="93.2" textLength="12.2" clip-path="url(#terminal-2602327173-line-3)">│</text><text class="terminal-2602327173-r1" x="1464" y="93.2" textLength="12.2" clip-path="url(#terminal-2602327173-line-3)">
+</text><text class="terminal-2602327173-r2" x="0" y="117.6" textLength="683.2" clip-path="url(#terminal-2602327173-line-4)">╰──────────────────────────────────────────────────────╯</text><text class="terminal-2602327173-r1" x="1464" y="117.6" textLength="12.2" clip-path="url(#terminal-2602327173-line-4)">
+</text><text class="terminal-2602327173-r1" x="1464" y="142" textLength="12.2" clip-path="url(#terminal-2602327173-line-5)">
+</text><text class="terminal-2602327173-r4" x="0" y="166.4" textLength="231.8" clip-path="url(#terminal-2602327173-line-6)">[04/29/24&#160;12:12:25]</text><text class="terminal-2602327173-r5" x="244" y="166.4" textLength="97.6" clip-path="url(#terminal-2602327173-line-6)">INFO&#160;&#160;&#160;&#160;</text><text class="terminal-2602327173-r1" x="353.8" y="166.4" textLength="292.8" clip-path="url(#terminal-2602327173-line-6)">Preparing&#160;ANTA&#160;NRFU&#160;Run&#160;</text><text class="terminal-2602327173-r6" x="646.6" y="166.4" textLength="36.6" clip-path="url(#terminal-2602327173-line-6)">...</text><text class="terminal-2602327173-r7" x="1317.6" y="166.4" textLength="97.6" clip-path="url(#terminal-2602327173-line-6)">tools.py</text><text class="terminal-2602327173-r7" x="1415.2" y="166.4" textLength="12.2" clip-path="url(#terminal-2602327173-line-6)">:</text><text class="terminal-2602327173-r7" x="1427.4" y="166.4" textLength="36.6" clip-path="url(#terminal-2602327173-line-6)">288</text><text class="terminal-2602327173-r1" x="1464" y="166.4" textLength="12.2" clip-path="url(#terminal-2602327173-line-6)">
+</text><text class="terminal-2602327173-r5" x="244" y="190.8" textLength="97.6" clip-path="url(#terminal-2602327173-line-7)">INFO&#160;&#160;&#160;&#160;</text><text class="terminal-2602327173-r1" x="353.8" y="190.8" textLength="244" clip-path="url(#terminal-2602327173-line-7)">Preparing&#160;the&#160;tests&#160;</text><text class="terminal-2602327173-r6" x="597.8" y="190.8" textLength="36.6" clip-path="url(#terminal-2602327173-line-7)">...</text><text class="terminal-2602327173-r7" x="1317.6" y="190.8" textLength="97.6" clip-path="url(#terminal-2602327173-line-7)">tools.py</text><text class="terminal-2602327173-r7" x="1415.2" y="190.8" textLength="12.2" clip-path="url(#terminal-2602327173-line-7)">:</text><text class="terminal-2602327173-r7" x="1427.4" y="190.8" textLength="36.6" clip-path="url(#terminal-2602327173-line-7)">288</text><text class="terminal-2602327173-r1" x="1464" y="190.8" textLength="12.2" clip-path="url(#terminal-2602327173-line-7)">
+</text><text class="terminal-2602327173-r5" x="244" y="215.2" textLength="97.6" clip-path="url(#terminal-2602327173-line-8)">INFO&#160;&#160;&#160;&#160;</text><text class="terminal-2602327173-r1" x="353.8" y="215.2" textLength="414.8" clip-path="url(#terminal-2602327173-line-8)">Preparing&#160;the&#160;tests&#160;completed&#160;in:&#160;</text><text class="terminal-2602327173-r8" x="768.6" y="215.2" textLength="85.4" clip-path="url(#terminal-2602327173-line-8)">0:00:00</text><text class="terminal-2602327173-r1" x="854" y="215.2" textLength="12.2" clip-path="url(#terminal-2602327173-line-8)">.</text><text class="terminal-2602327173-r9" x="866.2" y="215.2" textLength="36.6" clip-path="url(#terminal-2602327173-line-8)">001</text><text class="terminal-2602327173-r1" x="902.8" y="215.2" textLength="402.6" clip-path="url(#terminal-2602327173-line-8)">.&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2602327173-r7" x="1317.6" y="215.2" textLength="97.6" clip-path="url(#terminal-2602327173-line-8)">tools.py</text><text class="terminal-2602327173-r7" x="1415.2" y="215.2" textLength="12.2" clip-path="url(#terminal-2602327173-line-8)">:</text><text class="terminal-2602327173-r7" x="1427.4" y="215.2" textLength="36.6" clip-path="url(#terminal-2602327173-line-8)">296</text><text class="terminal-2602327173-r1" x="1464" y="215.2" textLength="12.2" clip-path="url(#terminal-2602327173-line-8)">
+</text><text class="terminal-2602327173-r5" x="244" y="239.6" textLength="97.6" clip-path="url(#terminal-2602327173-line-9)">INFO&#160;&#160;&#160;&#160;</text><text class="terminal-2602327173-r1" x="353.8" y="239.6" textLength="939.4" clip-path="url(#terminal-2602327173-line-9)">---&#160;ANTA&#160;NRFU&#160;Run&#160;Information&#160;---&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2602327173-r7" x="1305.4" y="239.6" textLength="109.8" clip-path="url(#terminal-2602327173-line-9)">runner.py</text><text class="terminal-2602327173-r7" x="1415.2" y="239.6" textLength="12.2" clip-path="url(#terminal-2602327173-line-9)">:</text><text class="terminal-2602327173-r7" x="1427.4" y="239.6" textLength="36.6" clip-path="url(#terminal-2602327173-line-9)">245</text><text class="terminal-2602327173-r1" x="1464" y="239.6" textLength="12.2" clip-path="url(#terminal-2602327173-line-9)">
+</text><text class="terminal-2602327173-r1" x="353.8" y="264" textLength="231.8" clip-path="url(#terminal-2602327173-line-10)">Number&#160;of&#160;devices:&#160;</text><text class="terminal-2602327173-r9" x="585.6" y="264" textLength="12.2" clip-path="url(#terminal-2602327173-line-10)">3</text><text class="terminal-2602327173-r10" x="610" y="264" textLength="12.2" clip-path="url(#terminal-2602327173-line-10)">(</text><text class="terminal-2602327173-r9" x="622.2" y="264" textLength="12.2" clip-path="url(#terminal-2602327173-line-10)">3</text><text class="terminal-2602327173-r1" x="634.4" y="264" textLength="146.4" clip-path="url(#terminal-2602327173-line-10)">&#160;established</text><text class="terminal-2602327173-r10" x="780.8" y="264" textLength="12.2" clip-path="url(#terminal-2602327173-line-10)">)</text><text class="terminal-2602327173-r1" x="1464" y="264" textLength="12.2" clip-path="url(#terminal-2602327173-line-10)">
+</text><text class="terminal-2602327173-r1" x="353.8" y="288.4" textLength="390.4" clip-path="url(#terminal-2602327173-line-11)">Total&#160;number&#160;of&#160;selected&#160;tests:&#160;</text><text class="terminal-2602327173-r9" x="744.2" y="288.4" textLength="24.4" clip-path="url(#terminal-2602327173-line-11)">27</text><text class="terminal-2602327173-r1" x="1464" y="288.4" textLength="12.2" clip-path="url(#terminal-2602327173-line-11)">
+</text><text class="terminal-2602327173-r1" x="353.8" y="312.8" textLength="854" clip-path="url(#terminal-2602327173-line-12)">Maximum&#160;number&#160;of&#160;open&#160;file&#160;descriptors&#160;for&#160;the&#160;current&#160;ANTA&#160;process:&#160;</text><text class="terminal-2602327173-r9" x="1207.8" y="312.8" textLength="61" clip-path="url(#terminal-2602327173-line-12)">16384</text><text class="terminal-2602327173-r1" x="1464" y="312.8" textLength="12.2" clip-path="url(#terminal-2602327173-line-12)">
+</text><text class="terminal-2602327173-r1" x="353.8" y="337.2" textLength="939.4" clip-path="url(#terminal-2602327173-line-13)">---------------------------------&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2602327173-r1" x="1464" y="337.2" textLength="12.2" clip-path="url(#terminal-2602327173-line-13)">
+</text><text class="terminal-2602327173-r5" x="244" y="361.6" textLength="97.6" clip-path="url(#terminal-2602327173-line-14)">INFO&#160;&#160;&#160;&#160;</text><text class="terminal-2602327173-r1" x="353.8" y="361.6" textLength="463.6" clip-path="url(#terminal-2602327173-line-14)">Preparing&#160;ANTA&#160;NRFU&#160;Run&#160;completed&#160;in:&#160;</text><text class="terminal-2602327173-r8" x="817.4" y="361.6" textLength="85.4" clip-path="url(#terminal-2602327173-line-14)">0:00:00</text><text class="terminal-2602327173-r1" x="902.8" y="361.6" textLength="12.2" clip-path="url(#terminal-2602327173-line-14)">.</text><text class="terminal-2602327173-r9" x="915" y="361.6" textLength="36.6" clip-path="url(#terminal-2602327173-line-14)">006</text><text class="terminal-2602327173-r1" x="951.6" y="361.6" textLength="353.8" clip-path="url(#terminal-2602327173-line-14)">.&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2602327173-r7" x="1317.6" y="361.6" textLength="97.6" clip-path="url(#terminal-2602327173-line-14)">tools.py</text><text class="terminal-2602327173-r7" x="1415.2" y="361.6" textLength="12.2" clip-path="url(#terminal-2602327173-line-14)">:</text><text class="terminal-2602327173-r7" x="1427.4" y="361.6" textLength="36.6" clip-path="url(#terminal-2602327173-line-14)">296</text><text class="terminal-2602327173-r1" x="1464" y="361.6" textLength="12.2" clip-path="url(#terminal-2602327173-line-14)">
+</text><text class="terminal-2602327173-r5" x="244" y="386" textLength="97.6" clip-path="url(#terminal-2602327173-line-15)">INFO&#160;&#160;&#160;&#160;</text><text class="terminal-2602327173-r1" x="353.8" y="386" textLength="939.4" clip-path="url(#terminal-2602327173-line-15)">Dry-run&#160;mode,&#160;exiting&#160;before&#160;running&#160;the&#160;tests.&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</text><text class="terminal-2602327173-r7" x="1305.4" y="386" textLength="109.8" clip-path="url(#terminal-2602327173-line-15)">runner.py</text><text class="terminal-2602327173-r7" x="1415.2" y="386" textLength="12.2" clip-path="url(#terminal-2602327173-line-15)">:</text><text class="terminal-2602327173-r7" x="1427.4" y="386" textLength="36.6" clip-path="url(#terminal-2602327173-line-15)">257</text><text class="terminal-2602327173-r1" x="1464" y="386" textLength="12.2" clip-path="url(#terminal-2602327173-line-15)">
+</text>
+ </g>
+ </g>
+</svg>
diff --git a/docs/overrides/partials/content.html b/docs/overrides/partials/content.html
new file mode 100644
index 0000000..1bda13b
--- /dev/null
+++ b/docs/overrides/partials/content.html
@@ -0,0 +1,18 @@
+{#-
+ This file was automatically generated - do not edit
+-#}
+{% if "material/tags" in config.plugins and tags %}
+ {% include "partials/tags.html" %}
+{% endif %}
+{% include "partials/actions.html" %}
+{% if "\x3ch1" not in page.content %}
+ {% if page.meta and page.meta.anta_title %}
+ <h1>{{ page.meta.anta_title | d(config.site_name, true)}}</h1>
+ {% else %}
+ <h1>{{ page.title | d(config.site_name, true)}}</h1>
+ {% endif %}
+{% endif %}
+{{ page.content }}
+{% include "partials/source-file.html" %}
+{% include "partials/feedback.html" %}
+{% include "partials/comments.html" %}
diff --git a/docs/overrides/partials/toc-item.html b/docs/overrides/partials/toc-item.html
new file mode 100644
index 0000000..b5cd840
--- /dev/null
+++ b/docs/overrides/partials/toc-item.html
@@ -0,0 +1,21 @@
+<!-- Courtesy of https://github.com/squidfunk/mkdocs-material/issues/4827#issuecomment-1869812019 -->
+<li class="md-nav__item">
+ <a href="{{ toc_item.url }}" class="md-nav__link">
+ <span class="md-ellipsis">
+ {{ toc_item.title }}
+ </span>
+ </a>
+
+ <!-- Table of contents list -->
+ {% if toc_item.children %}
+ <nav class="md-nav" aria-label="{{ toc_item.title | striptags }}">
+ <ul class="md-nav__list">
+ {% for toc_item in toc_item.children %}
+ {% if not page.meta.toc_depth or toc_item.level <= page.meta.toc_depth %}
+ {% include "partials/toc-item.html" %}
+ {% endif %}
+ {% endfor %}
+ </ul>
+ </nav>
+ {% endif %}
+ </li>
diff --git a/docs/requirements-and-installation.md b/docs/requirements-and-installation.md
index 9885cbe..75560d3 100644
--- a/docs/requirements-and-installation.md
+++ b/docs/requirements-and-installation.md
@@ -8,11 +8,11 @@
## Python version
-Python 3 (`>=3.8`) is required:
+Python 3 (`>=3.9`) is required:
```bash
python --version
-Python 3.9.9
+Python 3.11.8
```
## Install ANTA package
@@ -22,25 +22,57 @@ This installation will deploy tests collection, scripts and all their Python req
The ANTA package and the cli require some packages that are not part of the Python standard library. They are indicated in the [pyproject.toml](https://github.com/arista-netdevops-community/anta/blob/main/pyproject.toml) file, under dependencies.
-### Install from Pypi server
+### Install library from Pypi server
```bash
pip install anta
```
+!!! Warning
+
+ * This command alone **will not** install the ANTA CLI requirements.
+ * When using ANTA mode in [AVD](https://avd.arista.com) `eos_validate` role, (currently in preview), ensure you install the documented supported ANTA version for your AVD version.</br>
+ The latest documented version can be found at: https://avd.arista.com/stable/roles/eos_validate_state/ANTA-Preview.html
+
+### Install ANTA CLI as an application with `pipx`
+
+[`pipx`](https://pipx.pypa.io/stable/) is a tool to install and run python applications in isolated environments. If you plan to use ANTA only as a CLI tool you can use `pipx` to install it. `pipx` installs ANTA in an isolated python environment and makes it available globally.
+
+```
+pipx install anta[cli]
+```
+
+!!! Info
+
+ Please take the time to read through the installation instructions of `pipx` before getting started.
+
+
+### Install CLI from Pypi server
+
+Alternatively, pip install with `cli` extra is enough to install the ANTA CLI.
+
+```bash
+pip install anta[cli]
+```
+
### Install ANTA from github
```bash
pip install git+https://github.com/arista-netdevops-community/anta.git
+pip install git+https://github.com/arista-netdevops-community/anta.git#egg=anta[cli]
# You can even specify the branch, tag or commit:
pip install git+https://github.com/arista-netdevops-community/anta.git@<cool-feature-branch>
+pip install git+https://github.com/arista-netdevops-community/anta.git@<cool-feature-branch>#egg=anta[cli]
+
pip install git+https://github.com/arista-netdevops-community/anta.git@<cool-tag>
+pip install git+https://github.com/arista-netdevops-community/anta.git@<cool-tag>#egg=anta[cli]
+
pip install git+https://github.com/arista-netdevops-community/anta.git@<more-or-less-cool-hash>
+pip install git+https://github.com/arista-netdevops-community/anta.git@<more-or-less-cool-hash>#egg=anta[cli]
```
-
### Check installation
After installing ANTA, verify the installation with the following commands:
@@ -61,12 +93,12 @@ which anta
```bash
# Check ANTA version
anta --version
-anta, version v0.13.0
+anta, version v0.15.0
```
## EOS Requirements
-To get ANTA working, the targetted Arista EOS devices must have the following configuration (assuming you connect to the device using Management interface in MGMT VRF):
+To get ANTA working, the targeted Arista EOS devices must have eAPI enabled. They need to use the following configuration (assuming you connect to the device using Management interface in MGMT VRF):
```eos
configure
@@ -95,7 +127,7 @@ management api http-commands
end
```
-Now the swicth accepts on port 443 in the MGMT VRF HTTPS requests containing a list of CLI commands.
+Now the switch accepts on port 443 in the MGMT VRF HTTPS requests containing a list of CLI commands.
Run these EOS commands to verify:
diff --git a/tests/units/tools/__init__.py b/docs/scripts/__init__.py
index e772bee..c6adabb 100644
--- a/tests/units/tools/__init__.py
+++ b/docs/scripts/__init__.py
@@ -1,3 +1,4 @@
-# Copyright (c) 2023-2024 Arista Networks, Inc.
+# Copyright (c) 2024 Arista Networks, Inc.
# Use of this source code is governed by the Apache License 2.0
# that can be found in the LICENSE file.
+"""Scripts for ANTA documentation."""
diff --git a/docs/scripts/generate_svg.py b/docs/scripts/generate_svg.py
index 19177db..0048160 100644
--- a/docs/scripts/generate_svg.py
+++ b/docs/scripts/generate_svg.py
@@ -1,15 +1,19 @@
# Copyright (c) 2023-2024 Arista Networks, Inc.
# Use of this source code is governed by the Apache License 2.0
# that can be found in the LICENSE file.
-"""
-A script to generate svg files from anta command
+"""A script to generate svg files from anta command.
usage:
python generate_svg.py anta ...
"""
+# This script is not a package
+# ruff: noqa: INP001
+# This script contains print statements
+# ruff: noqa: T201
import io
+import logging
import os
import pathlib
import sys
@@ -19,16 +23,22 @@ from importlib.metadata import entry_points
from unittest.mock import patch
from rich.console import Console
+from rich.logging import RichHandler
from anta.cli.console import console
from anta.cli.nrfu.utils import anta_progress_bar
+root = logging.getLogger()
+
+r = RichHandler(console=console)
+root.addHandler(r)
+
+
OUTPUT_DIR = pathlib.Path(__file__).parent.parent / "imgs"
def custom_progress_bar() -> None:
- """
- Set the console of progress_bar to main anta console
+ """Set the console of progress_bar to main anta console.
Caveat: this capture all steps of the progress bar..
Disabling refresh to only capture beginning and end
@@ -41,7 +51,7 @@ def custom_progress_bar() -> None:
if __name__ == "__main__":
# Sane rich size
- os.environ["COLUMNS"] = "165"
+ os.environ["COLUMNS"] = "120"
# stolen from https://github.com/ewels/rich-click/blob/main/src/rich_click/cli.py
args = sys.argv[1:]
@@ -62,6 +72,8 @@ if __name__ == "__main__":
print("Usage: python generate_svg.py anta <options>")
sys.exit(1)
+ # possibly-used-before-assignment - prog / function_name -> not understanding sys.exit here...
+ # pylint: disable=E0606
sys.argv = [prog, *args[1:]]
module = import_module(module_path)
function = getattr(module, function_name)
@@ -69,24 +81,24 @@ if __name__ == "__main__":
# Console to captur everything
new_console = Console(record=True)
- # tweaks to record and redirect to a dummy file
pipe = io.StringIO()
console.record = True
console.file = pipe
-
- # Redirect stdout of the program towards another StringIO to capture help
- # that is not part or anta rich console
with redirect_stdout(io.StringIO()) as f:
+ # tweaks to record and redirect to a dummy file
+
+ console.print(f"ant@anthill$ {' '.join(sys.argv)}")
+
+ # Redirect stdout of the program towards another StringIO to capture help
+ # that is not part or anta rich console
# redirect potential progress bar output to console by patching
- with patch("anta.cli.nrfu.commands.anta_progress_bar", custom_progress_bar):
- with suppress(SystemExit):
- function()
- # print to our new console the output of anta console
- new_console.print(console.export_text())
- # print the content of the stdout to our new_console
- new_console.print(f.getvalue())
-
- filename = f"{'_'.join(map(lambda x: x.replace('/', '_').replace('-', '_').replace('.', '_'), args))}.svg"
+ with patch("anta.cli.nrfu.anta_progress_bar", custom_progress_bar), suppress(SystemExit):
+ function()
+
+ if "--help" in args:
+ console.print(f.getvalue())
+
+ filename = f"{'_'.join(x.replace('/', '_').replace('-', '_').replace('.', '_') for x in args)}.svg"
filename = f"{OUTPUT_DIR}/{filename}"
print(f"File saved at {filename}")
- new_console.save_svg(filename, title=" ".join(args))
+ console.save_svg(filename, title=" ".join(args))
diff --git a/docs/snippets/anta_help.txt b/docs/snippets/anta_help.txt
index 0c3302a..7bc37ad 100644
--- a/docs/snippets/anta_help.txt
+++ b/docs/snippets/anta_help.txt
@@ -1,6 +1,6 @@
Usage: anta [OPTIONS] COMMAND [ARGS]...
- Arista Network Test Automation (ANTA) CLI
+ Arista Network Test Automation (ANTA) CLI.
Options:
--version Show the version and exit.
@@ -13,8 +13,8 @@ Options:
--help Show this message and exit.
Commands:
- check Commands to validate configuration files
- debug Commands to execute EOS commands on remote devices
- exec Commands to execute various scripts on EOS devices
- get Commands to get information from or generate inventories
- nrfu Run ANTA tests on devices
+ check Commands to validate configuration files.
+ debug Commands to execute EOS commands on remote devices.
+ exec Commands to execute various scripts on EOS devices.
+ get Commands to get information from or generate inventories.
+ nrfu Run ANTA tests on selected inventory devices.
diff --git a/docs/snippets/anta_nrfu_help.txt b/docs/snippets/anta_nrfu_help.txt
new file mode 100644
index 0000000..68cb4b8
--- /dev/null
+++ b/docs/snippets/anta_nrfu_help.txt
@@ -0,0 +1,55 @@
+Usage: anta nrfu [OPTIONS] COMMAND [ARGS]...
+
+ Run ANTA tests on selected inventory devices.
+
+Options:
+ -u, --username TEXT Username to connect to EOS [env var:
+ ANTA_USERNAME; required]
+ -p, --password TEXT Password to connect to EOS that must be
+ provided. It can be prompted using '--
+ prompt' option. [env var: ANTA_PASSWORD]
+ --enable-password TEXT Password to access EOS Privileged EXEC mode.
+ It can be prompted using '--prompt' option.
+ Requires '--enable' option. [env var:
+ ANTA_ENABLE_PASSWORD]
+ --enable Some commands may require EOS Privileged
+ EXEC mode. This option tries to access this
+ mode before sending a command to the device.
+ [env var: ANTA_ENABLE]
+ -P, --prompt Prompt for passwords if they are not
+ provided. [env var: ANTA_PROMPT]
+ --timeout FLOAT Global API timeout. This value will be used
+ for all devices. [env var: ANTA_TIMEOUT;
+ default: 30.0]
+ --insecure Disable SSH Host Key validation. [env var:
+ ANTA_INSECURE]
+ --disable-cache Disable cache globally. [env var:
+ ANTA_DISABLE_CACHE]
+ -i, --inventory FILE Path to the inventory YAML file. [env var:
+ ANTA_INVENTORY; required]
+ --tags TEXT List of tags using comma as separator:
+ tag1,tag2,tag3. [env var: ANTA_TAGS]
+ -c, --catalog FILE Path to the test catalog YAML file [env
+ var: ANTA_CATALOG; required]
+ -d, --device TEXT Run tests on a specific device. Can be
+ provided multiple times.
+ -t, --test TEXT Run a specific test. Can be provided
+ multiple times.
+ --ignore-status Exit code will always be 0. [env var:
+ ANTA_NRFU_IGNORE_STATUS]
+ --ignore-error Exit code will be 0 if all tests succeeded
+ or 1 if any test failed. [env var:
+ ANTA_NRFU_IGNORE_ERROR]
+ --hide [success|failure|error|skipped]
+ Group result by test or device.
+ --dry-run Run anta nrfu command but stop before
+ starting to execute the tests. Considers all
+ devices as connected. [env var:
+ ANTA_NRFU_DRY_RUN]
+ --help Show this message and exit.
+
+Commands:
+ json ANTA command to check network state with JSON result.
+ table ANTA command to check network states with table result.
+ text ANTA command to check network states with text result.
+ tpl-report ANTA command to check network state with templated report.
diff --git a/docs/stylesheets/extra.material.css b/docs/stylesheets/extra.material.css
index b401c9a..09d7c8d 100644
--- a/docs/stylesheets/extra.material.css
+++ b/docs/stylesheets/extra.material.css
@@ -2,11 +2,15 @@
--md-hue: 210;
}
+#page {
+ counter-reset: heading;
+}
+
:root {
/* Color schema based on Arista Color Schema */
/* Default color shades */
--md-default-fg-color: #000000;
- --md-default-fg-color--light: #a1a0a0;
+ --md-default-fg-color--light: #444343;
--md-default-fg-color--lighter: #FFFFFF;
--md-default-fg-color--lightest: #FFFFFF;
--md-default-bg-color: #FFFFFF;
@@ -35,12 +39,8 @@
--md-code-bg-color: #E6E6E6;
--md-code-border-color: #0000004f;
--block-code-bg-color: #e4e4e4;
- /* --md-code-fg-color: ...; */
font-size: 1.1rem;
- /* min-height: 100%;
- position: relative;
- width: 100%; */
font-feature-settings: "kern","liga";
font-family: var(--md-text-font-family,_),-apple-system,BlinkMacSystemFont,Helvetica,Arial,sans-serif;
-webkit-font-smoothing: antialiased;
@@ -49,15 +49,16 @@
[data-md-color-scheme="slate"] {
+ /* Default color shades */
+ --md-default-fg-color--light: #949393;
+
/* Link color */
--md-typeset-a-color: #75aaf8;
--md-typeset-a-color-fg: #FFFFFF;
--md-typeset-a-color-bg: #27569B;
/* Code block color shades */
- /* --md-code-bg-color: #E6E6E6; */
--md-code-border-color: #aec6db4f;
- /* --block-code-bg-color: #e4e4e4; */
}
@media only screen and (min-width: 76.25em) {
@@ -76,6 +77,7 @@
}
@media only screen {
+
.md-typeset a:hover {
background-color: var(--md-typeset-a-color-bg);
color: var(--md-typeset-a-color-fg);
@@ -102,12 +104,56 @@
color: var(--md-default-fg-color--light);
}
- .md-typeset h4 h5 h6 {
- font-size: 1.5rem;
- margin: 1em 0;
- /* font-weight: 700; */
- letter-spacing: -.01em;
- line-height: 3em;
+ .md-typeset h2 {
+ line-height: 2em;
+ font-size: 1.5rem;
+ margin: 1em 0;
+ /* font-weight: 700; */
+ letter-spacing: -.01em;
+ color: var(--md-default-fg-color--light);
+ text-transform: capitalize;
+ font-style: normal;
+ font-weight: bolder;
+ }
+
+ .md-typeset h3 {
+ line-height: 1em;
+ font-size: 1.3rem;
+ margin: 1em 0;
+ /* font-weight: 700; */
+ letter-spacing: -.01em;
+ color: var(--md-default-fg-color--light);
+ text-transform: capitalize;
+ font-style: normal;
+ font-weight: bold;
+ }
+
+ .md-typeset h4::before {
+ content: ">> ";
+ }
+
+ .md-typeset h4 {
+ font-size: 1.1rem;
+ margin: 1em 0;
+ font-weight: 700;
+ letter-spacing: -.01em;
+ line-height: 1em;
+ color: var(--md-default-fg-color--light);
+ font-style: italic;
+ text-transform: capitalize;
+ }
+
+ .md-typeset h5,
+ .md-typeset h6 {
+ font-size: 0.9rem;
+ margin: 1em 0;
+ /* font-weight: 700; */
+ letter-spacing: -.01em;
+ /* line-height: 2em; */
+ color: var(--md-default-fg-color--light);
+ font-style: italic;
+ text-transform: capitalize;
+ text-decoration: underline;
}
.md-typeset table:not([class]) th {
@@ -178,8 +224,6 @@
.md-typeset table:not([class]) th {
min-width: 5rem;
padding: .6rem .8rem;
- /* color: var(--md-primary-fg-color--light); */
- bg: var(--md-footer-fg-color--lighter);
}
.md-footer-copyright {
@@ -195,7 +239,6 @@
margin-left: auto;
margin-right: auto;
border-radius: 1%;
- /* width: 50%; */
}
}
diff --git a/docs/templates/python/material/anta_test.html b/docs/templates/python/material/anta_test.html
new file mode 100644
index 0000000..ade0ba6
--- /dev/null
+++ b/docs/templates/python/material/anta_test.html
@@ -0,0 +1,163 @@
+{% if obj.members %}
+ {{ log.debug("Rendering children of " + obj.path) }}
+
+ <div class="doc doc-children">
+
+ {% if root_members %}
+ {% set members_list = config.members %}
+ {% else %}
+ {% set members_list = none %}
+ {% endif %}
+
+ {% if config.group_by_category %}
+
+ {% with %}
+
+ {% if config.show_category_heading %}
+ {% set extra_level = 1 %}
+ {% else %}
+ {% set extra_level = 0 %}
+ {% endif %}
+
+ {% with attributes = obj.attributes|filter_objects(
+ filters=config.filters,
+ members_list=members_list,
+ inherited_members=config.inherited_members,
+ keep_no_docstrings=config.show_if_no_docstring,
+ ) %}
+ {% if attributes %}
+ {% if config.show_category_heading %}
+ {% filter heading(heading_level, id=html_id ~ "-attributes") %}Attributes{% endfilter %}
+ {% endif %}
+ {% with heading_level = heading_level + extra_level %}
+ {% for attribute in attributes|order_members(config.members_order, members_list) %}
+ {% if members_list is not none or attribute.is_public(check_name=False) %}
+ {% include attribute|get_template with context %}
+ {% endif %}
+ {% endfor %}
+ {% endwith %}
+ {% endif %}
+ {% endwith %}
+
+ {% with classes = obj.classes|filter_objects(
+ filters=config.filters,
+ members_list=members_list,
+ inherited_members=config.inherited_members,
+ keep_no_docstrings=config.show_if_no_docstring,
+ ) %}
+ {% if classes %}
+ {% if config.show_category_heading %}
+ {% filter heading(heading_level, id=html_id ~ "-classes") %}Classes{% endfilter %}
+ {% endif %}
+ {% with heading_level = heading_level + extra_level %}
+ {% for class in classes|order_members(config.members_order, members_list) %}
+ {% if class.name == "Input" %}
+ {% filter heading(heading_level, id=html_id ~ "-attributes") %}Inputs{% endfilter %}
+ {% set root = False %}
+ {% set heading_level = heading_level + 1 %}
+ {% set old_obj = obj %}
+ {% set obj = class %}
+ {% include "attributes_table.html" with context %}
+ {% set obj = old_obj %}
+ {% else %}
+ {% if members_list is not none or class.is_public(check_name=False) %}
+ {% include class|get_template with context %}
+ {% endif %}
+ {% endif %}
+ {% endfor %}
+ {% endwith %}
+ {% endif %}
+ {% endwith %}
+
+ {% with functions = obj.functions|filter_objects(
+ filters=config.filters,
+ members_list=members_list,
+ inherited_members=config.inherited_members,
+ keep_no_docstrings=config.show_if_no_docstring,
+ ) %}
+ {% if functions %}
+ {% if config.show_category_heading %}
+ {% filter heading(heading_level, id=html_id ~ "-functions") %}Functions{% endfilter %}
+ {% endif %}
+ {% with heading_level = heading_level + extra_level %}
+ {% for function in functions|order_members(config.members_order, members_list) %}
+ {% if not (obj.kind.value == "class" and function.name == "__init__" and config.merge_init_into_class) %}
+ {% if members_list is not none or function.is_public(check_name=False) %}
+ {% include function|get_template with context %}
+ {% endif %}
+ {% endif %}
+ {% endfor %}
+ {% endwith %}
+ {% endif %}
+ {% endwith %}
+
+ {% if config.show_submodules %}
+ {% with modules = obj.modules|filter_objects(
+ filters=config.filters,
+ members_list=members_list,
+ inherited_members=config.inherited_members,
+ keep_no_docstrings=config.show_if_no_docstring,
+ ) %}
+ {% if modules %}
+ {% if config.show_category_heading %}
+ {% filter heading(heading_level, id=html_id ~ "-modules") %}Modules{% endfilter %}
+ {% endif %}
+ {% with heading_level = heading_level + extra_level %}
+ {% for module in modules|order_members(config.members_order.alphabetical, members_list) %}
+ {% if members_list is not none or module.is_public(check_name=False) %}
+ {% include module|get_template with context %}
+ {% endif %}
+ {% endfor %}
+ {% endwith %}
+ {% endif %}
+ {% endwith %}
+ {% endif %}
+
+ {% endwith %}
+
+ {% else %}
+
+ {% for child in obj.all_members
+ |filter_objects(
+ filters=config.filters,
+ members_list=members_list,
+ inherited_members=config.inherited_members,
+ keep_no_docstrings=config.show_if_no_docstring,
+ )
+ |order_members(config.members_order, members_list)
+ %}
+
+ {% if not (obj.is_class and child.name == "__init__" and config.merge_init_into_class) %}
+
+ {% if members_list is not none or child.is_public(check_name=False) %}
+ {% if child.is_attribute %}
+ {% with attribute = child %}
+ {% include attribute|get_template with context %}
+ {% endwith %}
+
+ {% elif child.is_class %}
+ {% with class = child %}
+ {% include class|get_template with context %}
+ {% endwith %}
+
+ {% elif child.is_function %}
+ {% with function = child %}
+ {% include function|get_template with context %}
+ {% endwith %}
+
+ {% elif child.is_module and config.show_submodules %}
+ {% with module = child %}
+ {% include module|get_template with context %}
+ {% endwith %}
+
+ {% endif %}
+ {% endif %}
+
+ {% endif %}
+
+ {% endfor %}
+
+ {% endif %}
+
+ </div>
+{% endif %}
diff --git a/docs/templates/python/material/attributes_table.html b/docs/templates/python/material/attributes_table.html
new file mode 100644
index 0000000..4997145
--- /dev/null
+++ b/docs/templates/python/material/attributes_table.html
@@ -0,0 +1,70 @@
+{% if obj.members %}
+ {{ log.debug("Rendering children of " + obj.path) }}
+
+ <div class="doc doc-children">
+ {# Notice inherited members false #}
+ {% with attributes = obj.attributes|filter_objects(
+ filters=config.filters,
+ members_list=members_list,
+ inherited_members=false,
+ keep_no_docstrings=config.show_if_no_docstring,
+ ) %}
+ <table>
+ <thead>
+ <tr>
+ <th>Name</th>
+ <th>Type</th>
+ <th>Description</th>
+ <th>Default</th>
+ </tr>
+ </thead>
+ <tbody>
+ {% for attribute in attributes %}
+ <tr>
+ <td><code>{{ attribute.name }}</code></td>
+ <td>
+ {% if attribute.annotation %}
+ {% with expression = attribute.annotation %}
+ <code>{% include "expression.html" with context %}</code>
+ {% endwith %}
+ {% endif %}
+ </td>
+ <td>
+ <div class="doc-md-description">
+ {{ attribute.docstring.value }}
+ </div>
+ </td>
+ <td>
+ {% if attribute.value %}
+ {% with expression = attribute.value %}
+ <code>{% include "expression.html" with context %}</code>
+ {% endwith %}
+ {% else %}
+ <em>-</em>
+ {% endif %}
+ </td>
+ </tr>
+ {% endfor %}
+ </tbody>
+ </table>
+ {%endwith %}
+ {% with classes = obj.classes|filter_objects(
+ filters=config.filters,
+ members_list=members_list,
+ inherited_members=false,
+ keep_no_docstrings=config.show_if_no_docstring,
+ ) %}
+ {% for class in classes %}
+ {% filter heading(heading_level, id=html_id ~ "-attributes") %}{{class.name}}{% endfilter %}
+ <div class="doc doc-children doc-contents">
+ {% set root = False %}
+ {% set heading_level = heading_level + 1 %}
+ {% set old_obj = obj %}
+ {% set obj = class %}
+ {% include "attributes_table.html" with context %}
+ {% set obj = old_obj %}
+ </div>
+ {% endfor %}
+ {%endwith %}
+ </div>
+{% endif %}
diff --git a/docs/templates/python/material/class.html b/docs/templates/python/material/class.html
new file mode 100644
index 0000000..940103b
--- /dev/null
+++ b/docs/templates/python/material/class.html
@@ -0,0 +1,35 @@
+{% extends "_base/class.html" %}
+{% set anta_test = namespace(found=false) %}
+{% for base in class.bases %}
+{% set basestr = base | string %}
+{% if "AntaTest" == basestr %}
+{% set anta_test.found = True %}
+{% endif %}
+{% endfor %}
+{% block children %}
+{% if anta_test.found %}
+ {% set root = False %}
+ {% set heading_level = heading_level + 1 %}
+ {% include "anta_test.html" with context %}
+ {# render source after children - TODO make add flag to respect disabling it.. though do we want to disable?#}
+ <details class="quote">
+ <summary>Source code in <code>
+ {%- if class.relative_filepath.is_absolute() -%}
+ {{ class.relative_package_filepath }}
+ {%- else -%}
+ {{ class.relative_filepath }}
+ {%- endif -%}
+ </code></summary>
+ {{ class.source|highlight(language="python", linestart=class.lineno, linenums=True) }}
+ </details>
+{% else %}
+ {{ super() }}
+{% endif %}
+{% endblock children %}
+
+{# Do not render source before children for AntaTest #}
+{% block source %}
+{% if not anta_test.found %}
+ {{ super() }}
+{% endif %}
+{% endblock source %}
diff --git a/docs/templates/python/material/docstring.html b/docs/templates/python/material/docstring.html
new file mode 100644
index 0000000..b12ae7e
--- /dev/null
+++ b/docs/templates/python/material/docstring.html
@@ -0,0 +1,36 @@
+{% if docstring_sections %}
+ {{ log.debug("Rendering docstring") }}
+ {% for section in docstring_sections %}
+ {% if config.show_docstring_description and section.kind.value == "text" %}
+ {% if not (config.anta_hide_test_module_description and module == obj) %}
+ {{ section.value|convert_markdown(heading_level, html_id) }}
+ {% endif %}
+ {% elif config.show_docstring_attributes and section.kind.value == "attributes" %}
+ {% include "docstring/attributes.html" with context %}
+ {% elif config.show_docstring_functions and section.kind.value == "functions" %}
+ {% include "docstring/functions.html" with context %}
+ {% elif config.show_docstring_classes and section.kind.value == "classes" %}
+ {% include "docstring/classes.html" with context %}
+ {% elif config.show_docstring_modules and section.kind.value == "modules" %}
+ {% include "docstring/modules.html" with context %}
+ {% elif config.show_docstring_parameters and section.kind.value == "parameters" %}
+ {% include "docstring/parameters.html" with context %}
+ {% elif config.show_docstring_other_parameters and section.kind.value == "other parameters" %}
+ {% include "docstring/other_parameters.html" with context %}
+ {% elif config.show_docstring_raises and section.kind.value == "raises" %}
+ {% include "docstring/raises.html" with context %}
+ {% elif config.show_docstring_warns and section.kind.value == "warns" %}
+ {% include "docstring/warns.html" with context %}
+ {% elif config.show_docstring_yields and section.kind.value == "yields" %}
+ {% include "docstring/yields.html" with context %}
+ {% elif config.show_docstring_receives and section.kind.value == "receives" %}
+ {% include "docstring/receives.html" with context %}
+ {% elif config.show_docstring_returns and section.kind.value == "returns" %}
+ {% include "docstring/returns.html" with context %}
+ {% elif config.show_docstring_examples and section.kind.value == "examples" %}
+ {% include "docstring/examples.html" with context %}
+ {% elif config.show_docstring_description and section.kind.value == "admonition" %}
+ {% include "docstring/admonition.html" with context %}
+ {% endif %}
+ {% endfor %}
+{% endif %}
diff --git a/docs/templates/python/material/docstring/examples.html b/docs/templates/python/material/docstring/examples.html
new file mode 100644
index 0000000..d8709c9
--- /dev/null
+++ b/docs/templates/python/material/docstring/examples.html
@@ -0,0 +1,14 @@
+{{ log.debug("Rendering examples section") }}
+
+{% import "language.html" as lang with context %}
+
+<details class="example" open>
+ <summary>{{ "Examples" | convert_markdown(heading_level +1, html_id, strip_paragraph=True) }}</summary>
+ {% for section_type, sub_section in section.value %}
+ {% if section_type.value == "text" %}
+ {{ sub_section|convert_markdown(heading_level, html_id) }}
+ {% elif section_type.value == "examples" %}
+ {{ sub_section|highlight(language="pycon", linenums=False) }}
+ {% endif %}
+ {% endfor %}
+</details>
diff --git a/docs/troubleshooting.md b/docs/troubleshooting.md
new file mode 100644
index 0000000..f27de7a
--- /dev/null
+++ b/docs/troubleshooting.md
@@ -0,0 +1,90 @@
+<!--
+ ~ Copyright (c) 2024 Arista Networks, Inc.
+ ~ Use of this source code is governed by the Apache License 2.0
+ ~ that can be found in the LICENSE file.
+ -->
+
+# Troubleshooting ANTA
+
+A couple of things to check when hitting an issue with ANTA:
+
+```mermaid
+flowchart LR
+ A>Hitting an issue with ANTA] --> B{Is my issue <br >listed in the FAQ?}
+ B -- Yes --> C{Does the FAQ solution<<br />works for me?}
+ C -- Yes --> V(((Victory)))
+ B -->|No| E{Is my problem<br />mentioned in one<<br />of the open issues?}
+ C -->|No| E
+ E -- Yes --> F{Has the issue been<br />fixed in a newer<br />release or in main?}
+ F -- Yes --> U[Upgrade]
+ E -- No ---> H((Follow the steps below<br />and open a Github issue))
+ U --> I{Did it fix<br /> your problem}
+ I -- Yes --> V
+ I -- No --> H
+ F -- No ----> G((Add a comment on the <br />issue indicating you<br >are hitting this and<br />describing your setup<br /> and adding your logs.))
+
+ click B "../faq" "FAQ"
+ click E "https://github.com/arista-netdevops-community/anta/issues"
+ click H "https://github.com/arista-netdevops-community/anta/issues"
+ style A stroke:#f00,stroke-width:2px
+```
+
+## Capturing logs
+
+To help document the issue in Github, it is important to capture some logs so the developers can understand what is affecting your system. No logs mean that the first question asked on the issue will probably be _"Can you share some logs please?"_.
+
+ANTA provides very verbose logs when using the `DEBUG` level. When using DEBUG log level with a log file, the DEBUG logging level is not sent to stdout, but only to the file.
+
+!!! danger
+
+ On real deployments, do not use DEBUG logging level without setting a log file at the same time.
+
+To save the logs to a file called `anta.log`, use the following flags:
+
+```bash
+# Where ANTA_COMMAND is one of nrfu, debug, get, exec, check
+anta -l DEBUG –log-file anta.log <ANTA_COMMAND>
+```
+
+See `anta --help` for more information. These have to precede the `nrfu` cmd.
+
+!!! tip
+
+ Remember that in ANTA, each level of command has its own options and they can only be set at this level.
+ so the `-l` and `--log-file` MUST be between `anta` and the `ANTA_COMMAND`.
+ similarly, all the `nrfu` options MUST be set between the `nrfu` and the `ANTA_NRFU_SUBCOMMAND` (`json`, `text`, `table` or `tpl-report`).
+
+
+As an example, for the `nrfu` command, it would look like:
+
+```bash
+anta -l DEBUG --log-file anta.log nrfu --enable --username username --password arista --inventory inventory.yml -c nrfu.yml text
+```
+
+
+### `ANTA_DEBUG` environment variable
+
+??? warning
+
+ Do not use this if you do not know why. This produces a lot of logs and can create confusion if you do not know what to look for.
+
+The environment variable `ANTA_DEBUG=true` enable ANTA Debug Mode.
+
+This flag is used by various functions in ANTA: when set to true, the function will display or log more information. In particular, when an Exception occurs in the code and this variable is set, the logging function used by ANTA is different to also produce the Python traceback for debugging. This typically needs to be done when opening a GitHub issue and an Exception is seen at runtime.
+
+Example:
+
+```bash
+ANTA_DEBUG=true anta -l DEBUG --log-file anta.log nrfu --enable --username username --password arista --inventory inventory.yml -c nrfu.yml text
+```
+
+### Troubleshooting on EOS
+
+ANTA is using a specific ID in eAPI requests towards EOS. This allows for easier eAPI requests debugging on the device using EOS configuration `trace CapiApp setting UwsgiRequestContext/4,CapiUwsgiServer/4` to set up CapiApp agent logs.
+
+Then, you can view agent logs using:
+```bash
+bash tail -f /var/log/agents/CapiApp-*
+
+2024-05-15 15:32:54.056166 1429 UwsgiRequestContext 4 request content b'{"jsonrpc": "2.0", "method": "runCmds", "params": {"version": "latest", "cmds": [{"cmd": "show ip route vrf default 10.255.0.3", "revision": 4}], "format": "json", "autoComplete": false, "expandAliases": false}, "id": "ANTA-VerifyRoutingTableEntry-132366530677328"}'
+```
diff --git a/docs/usage-inventory-catalog.md b/docs/usage-inventory-catalog.md
index 39734f3..e698dca 100644
--- a/docs/usage-inventory-catalog.md
+++ b/docs/usage-inventory-catalog.md
@@ -12,7 +12,7 @@ Both inputs can be defined in a file or programmatically.
## Device Inventory
-A device inventory is an instance of the [AntaInventory](../api/inventory.md#anta.inventory.AntaInventory) class.
+A device inventory is an instance of the [AntaInventory](./api/inventory.md#anta.inventory.AntaInventory) class.
### Device Inventory File
@@ -41,8 +41,8 @@ anta_inventory:
The inventory file must start with the `anta_inventory` key then define one or multiple methods:
- `hosts`: define each device individually
-- `networks`: scan a network for devices accesible via eAPI
-- `ranges`: scan a range for devices accesible via eAPI
+- `networks`: scan a network for devices accessible via eAPI
+- `ranges`: scan a range for devices accessible via eAPI
A full description of the inventory model is available in [API documentation](api/inventory.models.input.md)
@@ -72,7 +72,7 @@ anta_inventory:
## Test Catalog
-A test catalog is an instance of the [AntaCatalog](../api/catalog.md#anta.catalog.AntaCatalog) class.
+A test catalog is an instance of the [AntaCatalog](./api/catalog.md#anta.catalog.AntaCatalog) class.
### Test Catalog File
@@ -244,3 +244,32 @@ Once you run `anta nrfu table`, you will see following output:
│ spine01 │ VerifyInterfaceUtilization │ success │ │ Verifies interfaces utilization is below 75%. │ interfaces │
└───────────┴────────────────────────────┴─────────────┴────────────┴───────────────────────────────────────────────┴───────────────┘
```
+
+### Example script to merge catalogs
+
+The following script reads all the files in `intended/test_catalogs/` with names `<device_name>-catalog.yml` and merge them together inside one big catalog `anta-catalog.yml`.
+
+```python
+#!/usr/bin/env python
+from anta.catalog import AntaCatalog
+
+from pathlib import Path
+from anta.models import AntaTest
+
+
+CATALOG_SUFFIX = '-catalog.yml'
+CATALOG_DIR = 'intended/test_catalogs/'
+
+if __name__ == "__main__":
+ catalog = AntaCatalog()
+ for file in Path(CATALOG_DIR).glob('*'+CATALOG_SUFFIX):
+ c = AntaCatalog.parse(file)
+ device = str(file).removesuffix(CATALOG_SUFFIX).removeprefix(CATALOG_DIR)
+ print(f"Merging test catalog for device {device}")
+ # Apply filters to all tests for this device
+ for test in c.tests:
+ test.inputs.filters = AntaTest.Input.Filters(tags=[device])
+ catalog.merge(c)
+ with open(Path('anta-catalog.yml'), "w") as f:
+ f.write(catalog.dump().yaml())
+```
diff --git a/examples/README.md b/examples/README.md
index 5c24087..3a166e2 100644
--- a/examples/README.md
+++ b/examples/README.md
@@ -1,12 +1,12 @@
## Device Inventory
-The file [inventory.yaml](inventory.yaml) is an example of [device inventory](https://www.anta.ninja/usage-inventory-catalog/#create-an-inventory-file).
+The file [inventory.yaml](inventory.yaml) is an example of [device inventory](https://www.anta.ninja/stable/usage-inventory-catalog/#create-an-inventory-file).
## Test Catalog
-The file [tests.yaml](tests.yaml) is an example of a [test catalog](https://www.anta.ninja/usage-inventory-catalog/#test-catalog).
+The file [tests.yaml](tests.yaml) is an example of a [test catalog](https://www.anta.ninja/stable/usage-inventory-catalog/#test-catalog).
This file should contain all the tests implemented in [anta.tests](../anta/tests) with arbitrary parameters.
## eos-commands.yaml file
-The file [eos-commands.yaml](eos-commands.yaml) is an example of input given with the `--commands-list` option to the [anta exec snapshot](https://www.anta.ninja/cli/exec/#collect-a-set-of-commands) command.
+The file [eos-commands.yaml](eos-commands.yaml) is an example of input given with the `--commands-list` option to the [anta exec snapshot](https://www.anta.ninja/stable/cli/exec/#collect-a-set-of-commands) command.
diff --git a/examples/anta_runner.py b/examples/anta_runner.py
new file mode 100644
index 0000000..722cb87
--- /dev/null
+++ b/examples/anta_runner.py
@@ -0,0 +1,67 @@
+# Copyright (c) 2023-2024 Arista Networks, Inc.
+# Use of this source code is governed by the Apache License 2.0
+# that can be found in the LICENSE file.
+"""Example script for ANTA.
+
+usage:
+
+python anta_runner.py
+"""
+
+from __future__ import annotations
+
+import asyncio
+import logging
+import sys
+from pathlib import Path
+
+from anta.catalog import AntaCatalog
+from anta.cli.nrfu.utils import anta_progress_bar
+from anta.inventory import AntaInventory
+from anta.logger import Log, setup_logging
+from anta.models import AntaTest
+from anta.result_manager import ResultManager
+from anta.runner import main as anta_runner
+
+# setup logging
+setup_logging(Log.INFO, Path("/tmp/anta.log"))
+LOGGER = logging.getLogger()
+SCRIPT_LOG_PREFIX = "[bold magenta][ANTA RUNNER SCRIPT][/] " # For convenience purpose - there are nicer way to do this.
+
+
+# NOTE: The inventory and catalog files are not delivered with this script
+USERNAME = "admin"
+PASSWORD = "admin"
+CATALOG_PATH = Path("/tmp/anta_catalog.yml")
+INVENTORY_PATH = Path("/tmp/anta_inventory.yml")
+
+# Load catalog file
+try:
+ catalog = AntaCatalog.parse(CATALOG_PATH)
+except Exception:
+ LOGGER.exception("%s Catalog failed to load!", SCRIPT_LOG_PREFIX)
+ sys.exit(1)
+LOGGER.info("%s Catalog loaded!", SCRIPT_LOG_PREFIX)
+
+# Load inventory
+try:
+ inventory = AntaInventory.parse(INVENTORY_PATH, username=USERNAME, password=PASSWORD)
+except Exception:
+ LOGGER.exception("%s Inventory failed to load!", SCRIPT_LOG_PREFIX)
+ sys.exit(1)
+LOGGER.info("%s Inventory loaded!", SCRIPT_LOG_PREFIX)
+
+# Create result manager object
+manager = ResultManager()
+
+# Launch ANTA
+LOGGER.info("%s Starting ANTA runner...", SCRIPT_LOG_PREFIX)
+with anta_progress_bar() as AntaTest.progress:
+ # Set dry_run to True to avoid connecting to the devices
+ asyncio.run(anta_runner(manager, inventory, catalog, dry_run=False))
+
+LOGGER.info("%s ANTA run completed!", SCRIPT_LOG_PREFIX)
+
+# Manipulate the test result object
+for test_result in manager.results:
+ LOGGER.info("%s %s:%s:%s", SCRIPT_LOG_PREFIX, test_result.name, test_result.test, test_result.result)
diff --git a/examples/tests.yaml b/examples/tests.yaml
index 6b5875f..cb3d19b 100644
--- a/examples/tests.yaml
+++ b/examples/tests.yaml
@@ -1,7 +1,7 @@
---
anta.tests.aaa:
- VerifyTacacsSourceIntf:
- intf: Management0
+ intf: Management1
vrf: default
- VerifyTacacsServers:
servers:
@@ -50,6 +50,18 @@ anta.tests.aaa:
- commands
- dot1x
+anta.tests.avt:
+ - VerifyAVTPathHealth:
+ - VerifyAVTSpecificPath:
+ avt_paths:
+ - avt_name: CONTROL-PLANE-PROFILE
+ vrf: default
+ destination: 10.101.255.2
+ next_hop: 10.101.255.1
+ path_type: direct
+ - VerifyAVTRole:
+ role: edge
+
anta.tests.bfd:
- VerifyBFDSpecificPeers:
bfd_peers:
@@ -79,10 +91,10 @@ anta.tests.configuration:
anta.tests.connectivity:
- VerifyReachability:
hosts:
- - source: Management0
+ - source: Management1
destination: 1.1.1.1
vrf: MGMT
- - source: Management0
+ - source: Management1
destination: 8.8.8.8
vrf: MGMT
- VerifyLLDPNeighbors:
@@ -98,6 +110,10 @@ anta.tests.field_notices:
- VerifyFieldNotice44Resolution:
- VerifyFieldNotice72Resolution:
+anta.tests.greent:
+ - VerifyGreenT:
+ - VerifyGreenTCounters:
+
anta.tests.hardware:
- VerifyTransceiversManufacturers:
manufacturers:
@@ -117,18 +133,19 @@ anta.tests.hardware:
anta.tests.interfaces:
- VerifyInterfaceUtilization:
+ threshold: 70.0
- VerifyInterfaceErrors:
- VerifyInterfaceDiscards:
- VerifyInterfaceErrDisabled:
- VerifyInterfacesStatus:
interfaces:
- - interface: Ethernet1
- state: up
- - interface: Port-Channel100
- state: down
+ - name: Ethernet1
+ status: up
+ - name: Port-Channel100
+ status: down
line_protocol_status: lowerLayerDown
- - interface: Ethernet49/1
- state: adminDown
+ - name: Ethernet49/1
+ status: adminDown
line_protocol_status: notPresent
- VerifyStormControlDrops:
- VerifyPortChannels:
@@ -144,8 +161,8 @@ anta.tests.interfaces:
- Ethernet1: 2500
- VerifyIPProxyARP:
interfaces:
- - Ethernet1
- - Ethernet2
+ - Ethernet1/1
+ - Ethernet2/1
- VerifyL2MTU:
mtu: 1500
ignored_interfaces:
@@ -155,18 +172,33 @@ anta.tests.interfaces:
- Ethernet1/1: 1500
- VerifyInterfaceIPv4:
interfaces:
- - name: Ethernet2
+ - name: Ethernet2/1
primary_ip: 172.30.11.0/31
secondary_ips:
- 10.10.10.0/31
- 10.10.10.10/31
- VerifyIpVirtualRouterMac:
mac_address: 00:1c:73:00:dc:01
+ - VerifyInterfacesSpeed:
+ interfaces:
+ - name: Ethernet2
+ auto: False
+ speed: 10
+ - name: Eth3
+ auto: True
+ speed: 100
+ lanes: 1
+ - name: Eth2
+ auto: False
+ speed: 2.5
+
+anta.tests.lanz:
+ - VerifyLANZ:
anta.tests.logging:
- VerifyLoggingPersistent:
- VerifyLoggingSourceIntf:
- interface: Management0
+ interface: Management1
vrf: default
- VerifyLoggingHosts:
hosts:
@@ -202,12 +234,29 @@ anta.tests.multicast:
- VerifyIGMPSnoopingGlobal:
enabled: True
+anta.tests.path_selection:
+ - VerifyPathsHealth:
+ - VerifySpecificPath:
+ paths:
+ - peer: 10.255.0.1
+ path_group: internet
+ source_address: 100.64.3.2
+ destination_address: 100.64.1.2
+
anta.tests.profiles:
- VerifyUnifiedForwardingTableMode:
mode: 3
- VerifyTcamProfile:
profile: vxlan-routing
+anta.tests.ptp:
+ - VerifyPtpModeStatus:
+ - VerifyPtpGMStatus:
+ gmid: 0xec:46:70:ff:fe:00:ff:a9
+ - VerifyPtpLockStatus:
+ - VerifyPtpOffset:
+ - VerifyPtpPortModeStatus:
+
anta.tests.security:
- VerifySSHStatus:
- VerifySSHIPv4Acl:
@@ -264,6 +313,17 @@ anta.tests.security:
action: permit icmp any any
- sequence: 20
action: permit tcp any any range 5900 5910
+ - VerifyIPSecConnHealth:
+ - VerifySpecificIPSecConn:
+ ip_security_connections:
+ - peer: 10.255.0.1
+ - peer: 10.255.0.2
+ vrf: default
+ connections:
+ - source_address: 100.64.3.2
+ destination_address: 100.64.2.2
+ - source_address: 172.18.3.2
+ destination_address: 172.18.2.2
anta.tests.services:
- VerifyHostname:
@@ -331,6 +391,18 @@ anta.tests.stp:
- 10
- 20
+anta.tests.stun:
+ - VerifyStunClient:
+ stun_clients:
+ - source_address: 172.18.3.2
+ public_address: 172.18.3.21
+ source_port: 4500
+ public_port: 6006
+ - source_address: 100.64.3.2
+ public_address: 100.64.3.21
+ source_port: 4500
+ public_port: 6006
+
anta.tests.system:
- VerifyUptime:
minimum: 86400
@@ -475,3 +547,30 @@ anta.tests.routing:
- VerifyOSPFNeighborState:
- VerifyOSPFNeighborCount:
number: 3
+ - VerifyOSPFMaxLSA:
+ isis:
+ - VerifyISISNeighborState:
+ - VerifyISISNeighborCount:
+ interfaces:
+ - name: Ethernet1
+ level: 1
+ count: 2
+ - name: Ethernet2
+ level: 2
+ count: 1
+ - name: Ethernet3
+ count: 2
+ # level is set to 2 by default
+ - VerifyISISInterfaceMode:
+ interfaces:
+ - name: Loopback0
+ mode: passive
+ # vrf is set to default by default
+ - name: Ethernet2
+ mode: passive
+ level: 2
+ # vrf is set to default by default
+ - name: Ethernet1
+ mode: point-to-point
+ vrf: default
+ # level is set to 2 by default \ No newline at end of file
diff --git a/mkdocs.yml b/mkdocs.yml
index 9dbc60f..834c8ab 100644
--- a/mkdocs.yml
+++ b/mkdocs.yml
@@ -2,7 +2,7 @@
site_name: Arista Network Test Automation - ANTA
site_author: Khelil Sator
site_description: Arista Network Test Automation
-copyright: Copyright &copy; 2019 - 2023 Arista Networks
+copyright: Copyright &copy; 2019 - 2024 Arista Networks
# Repository
repo_name: ANTA on Github
@@ -76,20 +76,20 @@ extra_javascript:
watch:
- docs
- # Watch src/ directory to reload on changes to docstrings for mkdocstrings plugin.
- anta
plugins:
- mkdocstrings:
default_handler: python
+ custom_templates: docs/templates
handlers:
python:
- paths: [anta]
import:
- https://docs.python.org/3/objects.inv
- https://mkdocstrings.github.io/objects.inv
- https://mkdocstrings.github.io/griffe/objects.inv
options:
+ docstring_style: numpy
docstring_options:
ignore_init_summary: true
docstring_section_style: table
@@ -106,6 +106,7 @@ plugins:
# show_symbol_type_toc: true
# default filters here
filters: ["!^_[^_]"]
+
- search:
lang: en
- git-revision-date-localized:
@@ -115,8 +116,8 @@ plugins:
markdown_extensions:
- attr_list
- pymdownx.emoji:
- emoji_index: !!python/name:materialx.emoji.twemoji
- emoji_generator: !!python/name:materialx.emoji.to_svg
+ emoji_index: !!python/name:material.extensions.emoji.twemoji
+ emoji_generator: !!python/name:material.extensions.emoji.to_svg
- smarty
- pymdownx.arithmatex
- pymdownx.betterem:
@@ -128,7 +129,11 @@ markdown_extensions:
- pymdownx.magiclink
- pymdownx.mark
- pymdownx.smartsymbols
- - pymdownx.superfences
+ - pymdownx.superfences:
+ custom_fences:
+ - name: mermaid
+ class: mermaid
+ format: !!python/name:pymdownx.superfences.fence_code_format
- pymdownx.tasklist:
custom_checkbox: true
- pymdownx.tilde
@@ -140,10 +145,12 @@ markdown_extensions:
separator: "-"
# permalink: "#"
permalink: true
- baselevel: 3
+ # baselevel: 3
- pymdownx.highlight
- pymdownx.snippets:
- base_path: docs/snippets
+ base_path:
+ - docs/snippets
+ - examples
- pymdownx.superfences
- pymdownx.superfences
- pymdownx.tabbed:
@@ -156,7 +163,7 @@ nav:
- Getting Started: getting-started.md
- Installation: requirements-and-installation.md
- Inventory & Tests catalog: usage-inventory-catalog.md
- - Anta CLI:
+ - ANTA CLI:
- Overview: cli/overview.md
- NRFU: cli/nrfu.md
- Execute commands: cli/exec.md
@@ -170,45 +177,52 @@ nav:
- Caching in ANTA: advanced_usages/caching.md
- Developing ANTA tests: advanced_usages/custom-tests.md
- ANTA as a Python Library: advanced_usages/as-python-lib.md
- - Test Catalog Documentation:
+ - Tests Documentation:
- Overview: api/tests.md
- AAA: api/tests.aaa.md
+ - Adaptive Virtual Topology: api/tests.avt.md
- BFD: api/tests.bfd.md
- Configuration: api/tests.configuration.md
- Connectivity: api/tests.connectivity.md
- Field Notices: api/tests.field_notices.md
+ - GreenT: api/tests.greent.md
- Hardware: api/tests.hardware.md
- Interfaces: api/tests.interfaces.md
+ - LANZ: api/tests.lanz.md
- Logging: api/tests.logging.md
- MLAG: api/tests.mlag.md
- Multicast: api/tests.multicast.md
- Profiles: api/tests.profiles.md
+ - PTP: api/tests.ptp.md
+ - Router Path Selection: api/tests.path_selection.md
- Routing:
- Generic: api/tests.routing.generic.md
- BGP: api/tests.routing.bgp.md
- OSPF: api/tests.routing.ospf.md
+ - ISIS: api/tests.routing.isis.md
- Security: api/tests.security.md
- Services: api/tests.services.md
- SNMP: api/tests.snmp.md
- STP: api/tests.stp.md
+ - STUN: api/tests.stun.md
- Software: api/tests.software.md
- System: api/tests.system.md
- VXLAN: api/tests.vxlan.md
- VLAN: api/tests.vlan.md
- API Documentation:
+ - Device: api/device.md
- Inventory:
- Inventory module: api/inventory.md
- Inventory models: api/inventory.models.input.md
- Test Catalog: api/catalog.md
- - Device: api/device.md
- Test:
- Test models: api/models.md
- Input Types: api/types.md
- Result Manager:
- Result Manager module: api/result_manager.md
- Result Manager models: api/result_manager_models.md
- - Report Manager:
- - Report Manager module: api/report_manager.md
- - Report Manager models: api/report_manager_models.md
+ - Report Manager: api/report_manager.md
+ - Runner: api/runner.md
+ - Troubleshooting: troubleshooting.md
- Contributions: contribution.md
- FAQ: faq.md
diff --git a/pylintrc b/pylintrc
deleted file mode 100644
index 76cda50..0000000
--- a/pylintrc
+++ /dev/null
@@ -1,32 +0,0 @@
-[MESSAGES CONTROL]
-disable=
- invalid-name,
- logging-fstring-interpolation,
- fixme
-
-[BASIC]
-good-names=runCmds, i, y, t, c, x, e, fd, ip, v
-
-[DESIGN]
-max-statements=61
-max-returns=8
-max-locals=23
-max-args=6
-
-[FORMAT]
-max-line-length=165
-max-module-lines=1700
-
-[SIMILARITIES]
-# making similarity lines limit a bit higher than default 4
-min-similarity-lines=10
-
-[TYPECHECK]
-# https://stackoverflow.com/questions/49680191/click-and-pylint
-signature-mutators=click.decorators.option
-
-[MAIN]
-load-plugins=pylint_pydantic
-extension-pkg-whitelist=pydantic
-ignore-paths = ^tests/units/anta_tests/.*/data.py$,
- ^tests/units/anta_tests/routing/.*/data.py$,
diff --git a/pyproject.toml b/pyproject.toml
index 9a23db3..0c7a915 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -5,7 +5,7 @@ build-backend = "setuptools.build_meta"
[project]
name = "anta"
-version = "v0.13.0"
+version = "v0.15.0"
readme = "docs/README.md"
authors = [{ name = "Khelil Sator", email = "ksator@arista.com" }]
maintainers = [
@@ -17,19 +17,17 @@ maintainers = [
description = "Arista Network Test Automation (ANTA) Framework"
license = { file = "LICENSE" }
dependencies = [
- "aiocache~=0.12.2",
- "aio-eapi==0.6.3",
- "click~=8.1.6",
- "click-help-colors~=0.9",
- "cvprac~=1.3.1",
- "pydantic>=2.1.1,<2.7.0",
- "pydantic-extra-types>=2.1.0",
- "PyYAML~=6.0",
- "requests~=2.31.0",
- "rich>=13.5.2,<13.8.0",
- "rich>=13.5.2,<13.8.0",
- "asyncssh>=2.13.2,<2.15.0",
- "Jinja2~=3.1.2",
+ "aiocache>=0.12.2",
+ "asyncssh>=2.13.2",
+ "cvprac>=1.3.1",
+ "eval-type-backport>=0.1.3", # Support newer typing features in older Python versions (required until Python 3.9 support is removed)
+ "Jinja2>=3.1.2",
+ "pydantic>=2.7",
+ "pydantic-extra-types>=2.3.0",
+ "PyYAML>=6.0",
+ "requests>=2.31.0",
+ "rich>=13.5.2,<14",
+ "httpx>=0.27.0"
]
keywords = ["test", "anta", "Arista", "network", "automation", "networking", "devops", "netdevops"]
classifiers = [
@@ -41,7 +39,6 @@ classifiers = [
"Intended Audience :: Information Technology",
"Programming Language :: Python",
"Programming Language :: Python :: 3",
- "Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
@@ -51,45 +48,47 @@ classifiers = [
"Topic :: Software Development :: Testing",
"Topic :: System :: Networking",
]
-requires-python = ">=3.8"
+requires-python = ">=3.9"
[project.optional-dependencies]
+cli = [
+ "click~=8.1.6",
+ "click-help-colors>=0.9",
+]
dev = [
- "bumpver==2023.1129",
- "black==24.2.0",
- "flake8==7.0.0",
- "isort==5.13.2",
- "mypy~=1.7",
+ "bumpver>=2023.1129",
+ "codespell~=2.2.6",
"mypy-extensions~=1.0",
+ "mypy~=1.10",
"pre-commit>=3.3.3",
+ "pylint-pydantic>=0.2.4",
"pylint>=2.17.5",
- "ruff>=0.0.280",
- "pytest>=7.4.0",
"pytest-asyncio>=0.21.1",
"pytest-cov>=4.1.0",
"pytest-dependency",
"pytest-html>=3.2.0",
"pytest-metadata>=3.0.0",
- "pylint-pydantic>=0.2.4",
+ "pytest>=7.4.0",
+ "ruff>=0.3.7,<0.5.0",
"tox>=4.10.0,<5.0.0",
"types-PyYAML",
- "types-paramiko",
+ "types-pyOpenSSL",
"types-requests",
"typing-extensions",
"yamllint>=1.32.0",
]
doc = [
- "mkdocs>=1.3.1",
+ "fontawesome_markdown",
+ "griffe",
+ "mike==2.1.1",
"mkdocs-autorefs>=0.4.1",
"mkdocs-bootswatch>=1.1",
"mkdocs-git-revision-date-localized-plugin>=1.1.0",
"mkdocs-git-revision-date-plugin>=0.3.2",
- "mkdocs-material>=8.3.9",
"mkdocs-material-extensions>=1.0.3",
+ "mkdocs-material>=8.3.9",
+ "mkdocs>=1.3.1",
"mkdocstrings[python]>=0.20.0",
- "fontawesome_markdown",
- "mike==2.0.0",
- "griffe==0.41.1"
]
[project.urls]
@@ -100,19 +99,18 @@ Contributing = "https://www.anta.ninja/main/contribution/"
[project.scripts]
anta = "anta.cli:cli"
-
################################
# Tools
################################
[tool.setuptools.packages.find]
-include = ["anta*"]
+include = ["anta*", "asynceapi*"]
namespaces = false
################################
# Version
################################
[tool.bumpver]
-current_version = "0.13.0"
+current_version = "0.15.0"
version_pattern = "MAJOR.MINOR.PATCH"
commit_message = "bump: Version {old_version} -> {new_version}"
commit = true
@@ -126,21 +124,6 @@ push = false
"docs/requirements-and-installation.md " = ["anta, version v{version}"]
################################
-# Linting
-################################
-[tool.isort]
-profile = "black"
-line_length = 165
-
-[tool.black]
-line-length = 165
-force-exclude = """
-(
-.*data.py|
-)
-"""
-
-################################
# Typing
# mypy as per https://pydantic-docs.helpmanual.io/mypy_plugin/#enabling-the-plugin
################################
@@ -150,6 +133,8 @@ plugins = [
]
# Comment below for better type checking
#follow_imports = "skip"
+# Make it false if we implement stubs using stubgen from mypy for aio-eapi, aiocache and cvprac
+# and configure mypy_path to generated stubs e.g.: mypy_path = "./out"
ignore_missing_imports = true
warn_redundant_casts = true
# Note: tox find some unused type ignore which are required for pre-commit
@@ -173,25 +158,25 @@ warn_untyped_fields = true
# Testing
################################
[tool.pytest.ini_options]
-# TODO - may need cov-append for Tox
# When run from anta directory this will read cov-config from pyproject.toml
-addopts = "-ra -q -s -vv --capture=tee-sys --cov --cov-report term:skip-covered --color yes"
+addopts = "-ra -q -vv --cov --cov-report term:skip-covered --color yes"
log_level = "WARNING"
-log_cli = true
render_collapsed = true
+testpaths = ["tests"]
filterwarnings = [
- "ignore::urllib3.exceptions.InsecureRequestWarning"
+ "error",
+ # cvprac is raising the next warning
+ "default:pkg_resources is deprecated:DeprecationWarning",
+ # Need to investigate the following - only occuring when running the full pytest suite
+ "ignore:Exception ignored in.*:pytest.PytestUnraisableExceptionWarning",
+
]
-testpaths = ["tests"]
+
[tool.coverage.run]
branch = true
source = ["anta"]
parallel = true
-omit = [
- # omit aioeapi patch
- "anta/aioeapi.py",
- ]
[tool.coverage.report]
# Regexes for lines to exclude from consideration
@@ -237,12 +222,11 @@ envlist =
clean,
lint,
type,
- py{38,39,310,311,312},
+ py{39,310,311,312},
report
[gh-actions]
python =
- 3.8: py38
3.9: py39
3.10: py310
3.11: erase, py311, report
@@ -250,7 +234,9 @@ python =
[testenv]
description = Run pytest with {basepython}
-extras = dev
+extras =
+ dev
+ cli
# posargs allows to run only a specific test using
# tox -e <env> -- path/to/my/test::test
commands =
@@ -259,9 +245,8 @@ commands =
[testenv:lint]
description = Check the code style
commands =
- black --check --diff --color .
- isort --check --diff --color .
- flake8 --max-line-length=165 --config=/dev/null anta tests
+ ruff check .
+ ruff format . --check
pylint anta
pylint tests
@@ -289,17 +274,10 @@ commands =
depends = py311
"""
-# TRYING RUFF - NOT ENABLED IN CI NOR PRE-COMMIT
+################################
+# Ruff
+################################
[tool.ruff]
-# Enable pycodestyle (`E`) and Pyflakes (`F`) codes by default.
-# select = ["E", "F"]
-# select all cause we like being suffering
-select = ["A", "B", "C", "D", "E", "F", "G", "I", "N", "Q", "S", "T", "W", "ANN", "ARG", "BLE", "COM", "DJ", "DTZ", "EM", "ERA", "EXE", "FBT", "ICN", "INP", "ISC", "NPY", "PD", "PGH", "PIE", "PL", "PT", "PTH", "PYI", "RET", "RSE", "RUF", "SIM", "SLF", "TCH", "TID", "TRY", "UP", "YTT"]
-ignore = []
-
-# Allow autofix for all enabled rules (when `--fix`) is provided.
-fixable = ["A", "B", "C", "D", "E", "F", "G", "I", "N", "Q", "S", "T", "W", "ANN", "ARG", "BLE", "COM", "DJ", "DTZ", "EM", "ERA", "EXE", "FBT", "ICN", "INP", "ISC", "NPY", "PD", "PGH", "PIE", "PL", "PT", "PTH", "PYI", "RET", "RSE", "RUF", "SIM", "SLF", "TCH", "TID", "TRY", "UP", "YTT"]
-unfixable = []
# Exclude a variety of commonly ignored directories.
exclude = [
@@ -309,32 +287,165 @@ exclude = [
".git",
".git-rewrite",
".hg",
+ ".ipynb_checkpoints",
".mypy_cache",
".nox",
".pants.d",
+ ".pyenv",
+ ".pytest_cache",
".pytype",
".ruff_cache",
".svn",
".tox",
".venv",
+ ".vscode",
"__pypackages__",
"_build",
"buck-out",
"build",
"dist",
"node_modules",
+ "site-packages",
"venv",
+ ".github",
]
-# Same as Black.
line-length = 165
+# Assume Python 3.9 as this is the lowest supported version for ANTA
+target-version = "py39"
+
+[tool.ruff.lint]
+# select all cause we like being suffering
+select = ["ALL"]
+ignore = [
+ "ANN101", # Missing type annotation for `self` in method - we know what self is..
+ "D203", # Ignoring conflicting D* warnings - one-blank-line-before-class
+ "D213", # Ignoring conflicting D* warnings - multi-line-summary-second-line
+ "COM812", # Ignoring conflicting rules that may cause conflicts when used with the formatter
+ "ISC001", # Ignoring conflicting rules that may cause conflicts when used with the formatter
+ "TD002", # We don't have require authors in TODO
+ "TD003", # We don't have an issue link for all TODOs today
+ "FIX002", # Line contains TODO - ignoring for ruff for now
+ "F821", # Disable undefined-name until resolution of #10451
+]
+
+# Allow autofix for all enabled rules (when `--fix`) is provided.
+fixable = ["ALL"]
+unfixable = []
+
# Allow unused variables when underscore-prefixed.
dummy-variable-rgx = "^(_+|(_+[a-zA-Z0-9_]*[a-zA-Z0-9]+?))$"
-# Assume Python 3.8 as this is the lowest supported version for ANTA
-target-version = "py38"
+[tool.ruff.lint.pydocstyle]
+convention = "numpy"
-[tool.ruff.mccabe]
+[tool.ruff.lint.pylint]
+# These settings are used to configure pylint rules run in ruff. In order to keep sane and while
+# we have not removed pylint completely, these settings should be kept in sync with our pylintrc file.
+# https://github.com/astral-sh/ruff/issues/970
+max-branches = 13
+
+[tool.ruff.lint.mccabe]
# Unlike Flake8, default to a complexity level of 10.
max-complexity = 10
+
+[tool.ruff.lint.pep8-naming]
+"ignore-names" = [
+ "RICH_COLOR_PALETTE"
+]
+
+[tool.ruff.lint.flake8-type-checking]
+# These classes require that type annotations be available at runtime
+runtime-evaluated-base-classes = ["pydantic.BaseModel", "anta.models.AntaTest.Input"]
+
+
+[tool.ruff.lint.per-file-ignores]
+"tests/*" = [
+ "S101", # Complains about asserts in units and libs.
+ "SLF001", # Lots of private member accessed for test purposes
+]
+"tests/units/*" = [
+ "BLE001", # Do not catch blind exception: `Exception` - already disabling this in pylint
+ "FBT001", # Boolean-typed positional argument in function definition
+ "PLR0913", # Too many arguments to function call (8 > 5)
+ "PLR2004", # Magic value used in comparison, consider replacing {value} with a constant variable
+ "S105", # Passwords are indeed hardcoded in tests
+ "S106", # Passwords are indeed hardcoded in tests
+ "S108", # Probable insecure usage of temporary file or directory
+]
+"tests/units/anta_tests/test_interfaces.py" = [
+ "S104", # False positive for 0.0.0.0 bindings in test inputs
+]
+"anta/*" = [
+ "BLE001", # Do not catch blind exception: `Exception` - caught by other linter
+ "TRY400", # Use `logging.exception` instead of `logging.error` - we know what we are doing
+]
+"anta/cli/exec/utils.py" = [
+ "SLF001", # TODO: some private members, lets try to fix
+]
+"anta/cli/__init__.py" = [
+ "T201", # Allow print statements
+]
+"anta/cli/*" = [
+ "PLR0913", # Allow more than 5 input arguments in CLI functions
+ "ANN401", # TODO: Check if we can update the Any type hints in the CLI
+]
+"anta/tests/field_notices.py" = [
+ "PLR2004", # Magic value used in comparison, consider replacing 2131 with a constant variable - Field notice IDs are magic values
+ "C901", # TODO: test function is too complex, needs a refactor
+ "PLR0911", # TODO: Too many return statements, same as above needs a refactor
+]
+"anta/decorators.py" = [
+ "ANN401", # Ok to use Any type hint in our decorators
+]
+"anta/tools.py" = [
+ "ANN401", # Ok to use Any type hint in our custom get functions
+ "PLR0913", # Ok to have more than 5 arguments in our custom get functions
+]
+"anta/device.py" = [
+ "PLR0913", # Ok to have more than 5 arguments in the AntaDevice classes
+]
+"anta/inventory/__init__.py" = [
+ "PLR0913", # Ok to have more than 5 arguments in the AntaInventory class
+]
+"examples/anta_runner.py" = [ # This is an example script and linked in snippets
+ "S108", # Probable insecure usage of temporary file or directory
+ "S105", # Possible hardcoded password
+ "INP001", # Implicit packages
+]
+
+################################
+# Pylint
+################################
+[tool.pylint.'MESSAGES CONTROL']
+disable = [
+ "invalid-name",
+ "fixme"
+]
+
+[tool.pylint.DESIGN]
+max-statements=61
+max-returns=8
+max-locals=23
+
+[tool.pylint.FORMAT]
+max-line-length=165
+max-module-lines=1700
+
+[tool.pylint.SIMILARITIES]
+# making similarity lines limit a bit higher than default 4
+min-similarity-lines=10
+
+[tool.pylint.TYPECHECK]
+# https://stackoverflow.com/questions/49680191/click-and-pylint
+signature-mutators="click.decorators.option"
+
+[tool.pylint.MAIN]
+load-plugins="pylint_pydantic"
+extension-pkg-whitelist="pydantic"
+ignore-paths = [
+ "^tests/units/anta_tests/.*/data.py$",
+ "^tests/units/anta_tests/routing/.*/data.py$",
+ "^docs/scripts/anta_runner.py",
+]
diff --git a/tests/__init__.py b/tests/__init__.py
index e772bee..0a2486a 100644
--- a/tests/__init__.py
+++ b/tests/__init__.py
@@ -1,3 +1,4 @@
# Copyright (c) 2023-2024 Arista Networks, Inc.
# Use of this source code is governed by the Apache License 2.0
# that can be found in the LICENSE file.
+"""Tests for ANTA."""
diff --git a/tests/conftest.py b/tests/conftest.py
index 5a40c24..d6b1b8c 100644
--- a/tests/conftest.py
+++ b/tests/conftest.py
@@ -1,19 +1,15 @@
# Copyright (c) 2023-2024 Arista Networks, Inc.
# Use of this source code is governed by the Apache License 2.0
# that can be found in the LICENSE file.
-"""
-conftest.py - used to store anta specific fixtures used for tests
-"""
+"""conftest.py - used to store anta specific fixtures used for tests."""
+
from __future__ import annotations
import logging
-from typing import TYPE_CHECKING, Any
+from typing import Any
import pytest
-if TYPE_CHECKING:
- from pytest import Metafunc
-
# Load fixtures from dedicated file tests/lib/fixture.py
# As well as pytest_asyncio plugin to test co-routines
pytest_plugins = [
@@ -31,8 +27,7 @@ for _ in ("asyncio", "httpx"):
def build_test_id(val: dict[str, Any]) -> str:
- """
- build id for a unit test of an AntaTest subclass
+ """Build id for a unit test of an AntaTest subclass.
{
"name": "meaniful test name",
@@ -40,12 +35,12 @@ def build_test_id(val: dict[str, Any]) -> str:
...
}
"""
- return f"{val['test'].__module__}.{val['test'].__name__}-{val['name']}"
+ return f"{val['test'].module}.{val['test'].__name__}-{val['name']}"
-def pytest_generate_tests(metafunc: Metafunc) -> None:
- """
- This function is called during test collection.
+def pytest_generate_tests(metafunc: pytest.Metafunc) -> None:
+ """Generate ANTA testts unit tests dynamically during test collection.
+
It will parametrize test cases based on the `DATA` data structure defined in `tests.units.anta_tests` modules.
See `tests/units/anta_tests/README.md` for more information on how to use it.
Test IDs are generated using the `build_test_id` function above.
diff --git a/tests/data/__init__.py b/tests/data/__init__.py
index e772bee..864da68 100644
--- a/tests/data/__init__.py
+++ b/tests/data/__init__.py
@@ -1,3 +1,4 @@
# Copyright (c) 2023-2024 Arista Networks, Inc.
# Use of this source code is governed by the Apache License 2.0
# that can be found in the LICENSE file.
+"""Data for unit tests."""
diff --git a/tests/data/ansible_inventory_unknown_yaml_tag.yml b/tests/data/ansible_inventory_unknown_yaml_tag.yml
new file mode 100644
index 0000000..5739241
--- /dev/null
+++ b/tests/data/ansible_inventory_unknown_yaml_tag.yml
@@ -0,0 +1,49 @@
+
+---
+all:
+ children:
+ cv_servers:
+ hosts:
+ cv_atd1:
+ ansible_host: 10.73.1.238
+ ansible_user: tom
+ ansible_password: !unknown |
+ OOOOOOOK!GNUTERRYPRATCHETT!OOOOOOK!EEEEEEEK!
+ cv_collection: v3
+ ATD_LAB:
+ vars:
+ ansible_user: arista
+ ansible_ssh_pass: arista
+ children:
+ ATD_FABRIC:
+ children:
+ ATD_SPINES:
+ vars:
+ type: spine
+ hosts:
+ spine1:
+ ansible_host: 192.168.0.10
+ spine2:
+ ansible_host: 192.168.0.11
+ ATD_LEAFS:
+ vars:
+ type: l3leaf
+ children:
+ pod1:
+ hosts:
+ leaf1:
+ ansible_host: 192.168.0.12
+ leaf2:
+ ansible_host: 192.168.0.13
+ pod2:
+ hosts:
+ leaf3:
+ ansible_host: 192.168.0.14
+ leaf4:
+ ansible_host: 192.168.0.15
+ ATD_TENANTS_NETWORKS:
+ children:
+ ATD_LEAFS:
+ ATD_SERVERS:
+ children:
+ ATD_LEAFS:
diff --git a/tests/data/ansible_inventory_with_vault.yml b/tests/data/ansible_inventory_with_vault.yml
new file mode 100644
index 0000000..bf66ce0
--- /dev/null
+++ b/tests/data/ansible_inventory_with_vault.yml
@@ -0,0 +1,50 @@
+
+---
+all:
+ children:
+ cv_servers:
+ hosts:
+ cv_atd1:
+ ansible_host: 10.73.1.238
+ ansible_user: tom
+ ansible_password: !vault |
+ $ANSIBLE_VAULT;1.1;AES256
+ OOOOOOOK!YOURAWESOMEVAULTEDPASSWOR!OOOOOOK!EEEEEEEK!
+ cv_collection: v3
+ ATD_LAB:
+ vars:
+ ansible_user: arista
+ ansible_ssh_pass: arista
+ children:
+ ATD_FABRIC:
+ children:
+ ATD_SPINES:
+ vars:
+ type: spine
+ hosts:
+ spine1:
+ ansible_host: 192.168.0.10
+ spine2:
+ ansible_host: 192.168.0.11
+ ATD_LEAFS:
+ vars:
+ type: l3leaf
+ children:
+ pod1:
+ hosts:
+ leaf1:
+ ansible_host: 192.168.0.12
+ leaf2:
+ ansible_host: 192.168.0.13
+ pod2:
+ hosts:
+ leaf3:
+ ansible_host: 192.168.0.14
+ leaf4:
+ ansible_host: 192.168.0.15
+ ATD_TENANTS_NETWORKS:
+ children:
+ ATD_LEAFS:
+ ATD_SERVERS:
+ children:
+ ATD_LEAFS:
diff --git a/tests/data/json_data.py b/tests/data/json_data.py
index ad2c9ed..5630840 100644
--- a/tests/data/json_data.py
+++ b/tests/data/json_data.py
@@ -2,6 +2,7 @@
# Use of this source code is governed by the Apache License 2.0
# that can be found in the LICENSE file.
# pylint: skip-file
+"""JSON Data for unit tests."""
INVENTORY_MODEL_HOST_VALID = [
{"name": "validIPv4", "input": "1.1.1.1", "expected_result": "valid"},
@@ -92,7 +93,7 @@ INVENTORY_MODEL_VALID = [
"ranges": [
{"start": "10.1.0.1", "end": "10.1.0.10"},
{"start": "10.2.0.1", "end": "10.2.1.10"},
- ]
+ ],
},
"expected_result": "valid",
},
@@ -150,8 +151,8 @@ ANTA_INVENTORY_TESTS_VALID = [
"ranges": [
{"start": "10.0.0.1", "end": "10.0.0.11"},
{"start": "10.0.0.101", "end": "10.0.0.111"},
- ]
- }
+ ],
+ },
},
"expected_result": "valid",
"parameters": {
@@ -197,8 +198,8 @@ ANTA_INVENTORY_TESTS_VALID = [
"ranges": [
{"start": "10.0.0.1", "end": "10.0.0.11", "tags": ["leaf"]},
{"start": "10.0.0.101", "end": "10.0.0.111", "tags": ["spine"]},
- ]
- }
+ ],
+ },
},
"expected_result": "valid",
"parameters": {
@@ -242,8 +243,8 @@ ANTA_INVENTORY_TESTS_INVALID = [
"ranges": [
{"start": "10.0.0.1", "end": "10.0.0.11"},
{"start": "10.0.0.100", "end": "10.0.0.111"},
- ]
- }
+ ],
+ },
},
"expected_result": "invalid",
},
diff --git a/tests/data/test_catalog_large.yml b/tests/data/test_catalog_large.yml
new file mode 100644
index 0000000..4858f6c
--- /dev/null
+++ b/tests/data/test_catalog_large.yml
@@ -0,0 +1,71690 @@
+anta.tests.connectivity:
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-leaf4b
+ neighbors:
+ - neighbor_device: pod1-leaf4a
+ neighbor_port: Ethernet53/1
+ port: Ethernet53/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet53/1 - Remote: pod1-leaf4a Ethernet53/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-leaf4b
+ neighbors:
+ - neighbor_device: pod1-leaf4a
+ neighbor_port: Ethernet54/1
+ port: Ethernet54/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet54/1 - Remote: pod1-leaf4a Ethernet54/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-leaf4b
+ neighbors:
+ - neighbor_device: pod1-spine1
+ neighbor_port: Ethernet8/1
+ port: Ethernet1/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet1/1 - Remote: pod1-spine1 Ethernet8/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-leaf4b
+ neighbors:
+ - neighbor_device: pod1-spine2
+ neighbor_port: Ethernet8/1
+ port: Ethernet2/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet2/1 - Remote: pod1-spine2 Ethernet8/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-leaf4b
+ neighbors:
+ - neighbor_device: pod1-spine3
+ neighbor_port: Ethernet8/1
+ port: Ethernet3/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet3/1 - Remote: pod1-spine3 Ethernet8/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-leaf4b
+ neighbors:
+ - neighbor_device: pod1-spine4
+ neighbor_port: Ethernet8/1
+ port: Ethernet4/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet4/1 - Remote: pod1-spine4 Ethernet8/1'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf4b
+ hosts:
+ - destination: 10.255.255.56
+ repeat: 1
+ source: 10.255.255.57
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet1/1 (IP: 10.255.255.57) - Destination: pod1-spine1 Ethernet8/1 (IP: 10.255.255.56)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf4b
+ hosts:
+ - destination: 10.255.255.58
+ repeat: 1
+ source: 10.255.255.59
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet2/1 (IP: 10.255.255.59) - Destination: pod1-spine2 Ethernet8/1 (IP: 10.255.255.58)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf4b
+ hosts:
+ - destination: 10.255.255.60
+ repeat: 1
+ source: 10.255.255.61
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet3/1 (IP: 10.255.255.61) - Destination: pod1-spine3 Ethernet8/1 (IP: 10.255.255.60)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf4b
+ hosts:
+ - destination: 10.255.255.62
+ repeat: 1
+ source: 10.255.255.63
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet4/1 (IP: 10.255.255.63) - Destination: pod1-spine4 Ethernet8/1 (IP: 10.255.255.62)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf4b
+ hosts:
+ - destination: 10.255.0.1
+ repeat: 1
+ source: 10.255.1.12
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.12) - Destination: super-spine1 Loopback0 (IP: 10.255.0.1)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf4b
+ hosts:
+ - destination: 10.255.0.2
+ repeat: 1
+ source: 10.255.1.12
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.12) - Destination: super-spine2 Loopback0 (IP: 10.255.0.2)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf4b
+ hosts:
+ - destination: 10.255.1.1
+ repeat: 1
+ source: 10.255.1.12
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.12) - Destination: pod1-spine1 Loopback0 (IP: 10.255.1.1)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf4b
+ hosts:
+ - destination: 10.255.1.2
+ repeat: 1
+ source: 10.255.1.12
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.12) - Destination: pod1-spine2 Loopback0 (IP: 10.255.1.2)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf4b
+ hosts:
+ - destination: 10.255.1.3
+ repeat: 1
+ source: 10.255.1.12
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.12) - Destination: pod1-spine3 Loopback0 (IP: 10.255.1.3)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf4b
+ hosts:
+ - destination: 10.255.1.4
+ repeat: 1
+ source: 10.255.1.12
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.12) - Destination: pod1-spine4 Loopback0 (IP: 10.255.1.4)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf4b
+ hosts:
+ - destination: 10.255.1.5
+ repeat: 1
+ source: 10.255.1.12
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.12) - Destination: pod1-leaf1a Loopback0 (IP: 10.255.1.5)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf4b
+ hosts:
+ - destination: 10.255.1.6
+ repeat: 1
+ source: 10.255.1.12
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.12) - Destination: pod1-leaf1b Loopback0 (IP: 10.255.1.6)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf4b
+ hosts:
+ - destination: 10.255.1.7
+ repeat: 1
+ source: 10.255.1.12
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.12) - Destination: pod1-leaf2a Loopback0 (IP: 10.255.1.7)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf4b
+ hosts:
+ - destination: 10.255.1.8
+ repeat: 1
+ source: 10.255.1.12
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.12) - Destination: pod1-leaf2b Loopback0 (IP: 10.255.1.8)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf4b
+ hosts:
+ - destination: 10.255.1.9
+ repeat: 1
+ source: 10.255.1.12
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.12) - Destination: pod1-leaf3a Loopback0 (IP: 10.255.1.9)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf4b
+ hosts:
+ - destination: 10.255.1.10
+ repeat: 1
+ source: 10.255.1.12
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.12) - Destination: pod1-leaf3b Loopback0 (IP: 10.255.1.10)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf4b
+ hosts:
+ - destination: 10.255.1.11
+ repeat: 1
+ source: 10.255.1.12
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.12) - Destination: pod1-leaf4a Loopback0 (IP: 10.255.1.11)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf4b
+ hosts:
+ - destination: 10.255.1.12
+ repeat: 1
+ source: 10.255.1.12
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.12) - Destination: pod1-leaf4b Loopback0 (IP: 10.255.1.12)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf4b
+ hosts:
+ - destination: 10.255.1.13
+ repeat: 1
+ source: 10.255.1.12
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.12) - Destination: pod1-leaf5a Loopback0 (IP: 10.255.1.13)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf4b
+ hosts:
+ - destination: 10.255.1.14
+ repeat: 1
+ source: 10.255.1.12
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.12) - Destination: pod1-leaf5b Loopback0 (IP: 10.255.1.14)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf4b
+ hosts:
+ - destination: 10.255.1.15
+ repeat: 1
+ source: 10.255.1.12
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.12) - Destination: pod1-leaf6a Loopback0 (IP: 10.255.1.15)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf4b
+ hosts:
+ - destination: 10.255.1.16
+ repeat: 1
+ source: 10.255.1.12
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.12) - Destination: pod1-leaf6b Loopback0 (IP: 10.255.1.16)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf4b
+ hosts:
+ - destination: 10.255.1.17
+ repeat: 1
+ source: 10.255.1.12
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.12) - Destination: pod1-leaf7a Loopback0 (IP: 10.255.1.17)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf4b
+ hosts:
+ - destination: 10.255.1.18
+ repeat: 1
+ source: 10.255.1.12
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.12) - Destination: pod1-leaf7b Loopback0 (IP: 10.255.1.18)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf4b
+ hosts:
+ - destination: 10.255.1.19
+ repeat: 1
+ source: 10.255.1.12
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.12) - Destination: pod1-leaf8a Loopback0 (IP: 10.255.1.19)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf4b
+ hosts:
+ - destination: 10.255.1.20
+ repeat: 1
+ source: 10.255.1.12
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.12) - Destination: pod1-leaf8b Loopback0 (IP: 10.255.1.20)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf4b
+ hosts:
+ - destination: 10.255.1.21
+ repeat: 1
+ source: 10.255.1.12
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.12) - Destination: pod1-leaf9a Loopback0 (IP: 10.255.1.21)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf4b
+ hosts:
+ - destination: 10.255.1.22
+ repeat: 1
+ source: 10.255.1.12
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.12) - Destination: pod1-leaf9b Loopback0 (IP: 10.255.1.22)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf4b
+ hosts:
+ - destination: 10.255.1.23
+ repeat: 1
+ source: 10.255.1.12
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.12) - Destination: pod1-leaf10a Loopback0 (IP: 10.255.1.23)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf4b
+ hosts:
+ - destination: 10.255.1.24
+ repeat: 1
+ source: 10.255.1.12
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.12) - Destination: pod1-leaf10b Loopback0 (IP: 10.255.1.24)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf4b
+ hosts:
+ - destination: 10.255.2.1
+ repeat: 1
+ source: 10.255.1.12
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.12) - Destination: pod2-spine1 Loopback0 (IP: 10.255.2.1)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf4b
+ hosts:
+ - destination: 10.255.2.2
+ repeat: 1
+ source: 10.255.1.12
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.12) - Destination: pod2-spine2 Loopback0 (IP: 10.255.2.2)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf4b
+ hosts:
+ - destination: 10.255.2.3
+ repeat: 1
+ source: 10.255.1.12
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.12) - Destination: pod2-spine3 Loopback0 (IP: 10.255.2.3)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf4b
+ hosts:
+ - destination: 10.255.2.4
+ repeat: 1
+ source: 10.255.1.12
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.12) - Destination: pod2-spine4 Loopback0 (IP: 10.255.2.4)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf4b
+ hosts:
+ - destination: 10.255.2.5
+ repeat: 1
+ source: 10.255.1.12
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.12) - Destination: pod2-leaf1a Loopback0 (IP: 10.255.2.5)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf4b
+ hosts:
+ - destination: 10.255.2.6
+ repeat: 1
+ source: 10.255.1.12
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.12) - Destination: pod2-leaf1b Loopback0 (IP: 10.255.2.6)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf4b
+ hosts:
+ - destination: 10.255.2.7
+ repeat: 1
+ source: 10.255.1.12
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.12) - Destination: pod2-leaf2a Loopback0 (IP: 10.255.2.7)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf4b
+ hosts:
+ - destination: 10.255.2.8
+ repeat: 1
+ source: 10.255.1.12
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.12) - Destination: pod2-leaf2b Loopback0 (IP: 10.255.2.8)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf4b
+ hosts:
+ - destination: 10.255.2.9
+ repeat: 1
+ source: 10.255.1.12
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.12) - Destination: pod2-leaf3a Loopback0 (IP: 10.255.2.9)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf4b
+ hosts:
+ - destination: 10.255.2.10
+ repeat: 1
+ source: 10.255.1.12
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.12) - Destination: pod2-leaf3b Loopback0 (IP: 10.255.2.10)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf4b
+ hosts:
+ - destination: 10.255.2.11
+ repeat: 1
+ source: 10.255.1.12
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.12) - Destination: pod2-leaf4a Loopback0 (IP: 10.255.2.11)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf4b
+ hosts:
+ - destination: 10.255.2.12
+ repeat: 1
+ source: 10.255.1.12
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.12) - Destination: pod2-leaf4b Loopback0 (IP: 10.255.2.12)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf4b
+ hosts:
+ - destination: 10.255.2.13
+ repeat: 1
+ source: 10.255.1.12
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.12) - Destination: pod2-leaf5a Loopback0 (IP: 10.255.2.13)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf4b
+ hosts:
+ - destination: 10.255.2.14
+ repeat: 1
+ source: 10.255.1.12
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.12) - Destination: pod2-leaf5b Loopback0 (IP: 10.255.2.14)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf4b
+ hosts:
+ - destination: 10.255.2.15
+ repeat: 1
+ source: 10.255.1.12
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.12) - Destination: pod2-leaf6a Loopback0 (IP: 10.255.2.15)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf4b
+ hosts:
+ - destination: 10.255.2.16
+ repeat: 1
+ source: 10.255.1.12
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.12) - Destination: pod2-leaf6b Loopback0 (IP: 10.255.2.16)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf4b
+ hosts:
+ - destination: 10.255.2.17
+ repeat: 1
+ source: 10.255.1.12
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.12) - Destination: pod2-leaf7a Loopback0 (IP: 10.255.2.17)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf4b
+ hosts:
+ - destination: 10.255.2.18
+ repeat: 1
+ source: 10.255.1.12
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.12) - Destination: pod2-leaf7b Loopback0 (IP: 10.255.2.18)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf4b
+ hosts:
+ - destination: 10.255.2.19
+ repeat: 1
+ source: 10.255.1.12
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.12) - Destination: pod2-leaf8a Loopback0 (IP: 10.255.2.19)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf4b
+ hosts:
+ - destination: 10.255.2.20
+ repeat: 1
+ source: 10.255.1.12
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.12) - Destination: pod2-leaf8b Loopback0 (IP: 10.255.2.20)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf4b
+ hosts:
+ - destination: 10.255.2.21
+ repeat: 1
+ source: 10.255.1.12
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.12) - Destination: pod2-leaf9a Loopback0 (IP: 10.255.2.21)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf4b
+ hosts:
+ - destination: 10.255.2.22
+ repeat: 1
+ source: 10.255.1.12
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.12) - Destination: pod2-leaf9b Loopback0 (IP: 10.255.2.22)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf4b
+ hosts:
+ - destination: 10.255.2.23
+ repeat: 1
+ source: 10.255.1.12
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.12) - Destination: pod2-leaf10a Loopback0 (IP: 10.255.2.23)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf4b
+ hosts:
+ - destination: 10.255.2.24
+ repeat: 1
+ source: 10.255.1.12
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.12) - Destination: pod2-leaf10b Loopback0 (IP: 10.255.2.24)'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-spine1
+ neighbors:
+ - neighbor_device: pod2-leaf1a
+ neighbor_port: Ethernet1/1
+ port: Ethernet1/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet1/1 - Remote: pod2-leaf1a Ethernet1/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-spine1
+ neighbors:
+ - neighbor_device: pod2-leaf1b
+ neighbor_port: Ethernet1/1
+ port: Ethernet2/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet2/1 - Remote: pod2-leaf1b Ethernet1/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-spine1
+ neighbors:
+ - neighbor_device: pod2-leaf2a
+ neighbor_port: Ethernet1/1
+ port: Ethernet3/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet3/1 - Remote: pod2-leaf2a Ethernet1/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-spine1
+ neighbors:
+ - neighbor_device: pod2-leaf2b
+ neighbor_port: Ethernet1/1
+ port: Ethernet4/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet4/1 - Remote: pod2-leaf2b Ethernet1/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-spine1
+ neighbors:
+ - neighbor_device: pod2-leaf3a
+ neighbor_port: Ethernet1/1
+ port: Ethernet5/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet5/1 - Remote: pod2-leaf3a Ethernet1/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-spine1
+ neighbors:
+ - neighbor_device: pod2-leaf3b
+ neighbor_port: Ethernet1/1
+ port: Ethernet6/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet6/1 - Remote: pod2-leaf3b Ethernet1/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-spine1
+ neighbors:
+ - neighbor_device: pod2-leaf4a
+ neighbor_port: Ethernet1/1
+ port: Ethernet7/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet7/1 - Remote: pod2-leaf4a Ethernet1/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-spine1
+ neighbors:
+ - neighbor_device: pod2-leaf4b
+ neighbor_port: Ethernet1/1
+ port: Ethernet8/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet8/1 - Remote: pod2-leaf4b Ethernet1/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-spine1
+ neighbors:
+ - neighbor_device: pod2-leaf5a
+ neighbor_port: Ethernet1/1
+ port: Ethernet9/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet9/1 - Remote: pod2-leaf5a Ethernet1/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-spine1
+ neighbors:
+ - neighbor_device: pod2-leaf5b
+ neighbor_port: Ethernet1/1
+ port: Ethernet10/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet10/1 - Remote: pod2-leaf5b Ethernet1/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-spine1
+ neighbors:
+ - neighbor_device: pod2-leaf6a
+ neighbor_port: Ethernet1/1
+ port: Ethernet11/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet11/1 - Remote: pod2-leaf6a Ethernet1/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-spine1
+ neighbors:
+ - neighbor_device: pod2-leaf6b
+ neighbor_port: Ethernet1/1
+ port: Ethernet12/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet12/1 - Remote: pod2-leaf6b Ethernet1/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-spine1
+ neighbors:
+ - neighbor_device: pod2-leaf7a
+ neighbor_port: Ethernet1/1
+ port: Ethernet13/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet13/1 - Remote: pod2-leaf7a Ethernet1/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-spine1
+ neighbors:
+ - neighbor_device: pod2-leaf7b
+ neighbor_port: Ethernet1/1
+ port: Ethernet14/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet14/1 - Remote: pod2-leaf7b Ethernet1/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-spine1
+ neighbors:
+ - neighbor_device: pod2-leaf8a
+ neighbor_port: Ethernet1/1
+ port: Ethernet15/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet15/1 - Remote: pod2-leaf8a Ethernet1/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-spine1
+ neighbors:
+ - neighbor_device: pod2-leaf8b
+ neighbor_port: Ethernet1/1
+ port: Ethernet16/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet16/1 - Remote: pod2-leaf8b Ethernet1/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-spine1
+ neighbors:
+ - neighbor_device: pod2-leaf9a
+ neighbor_port: Ethernet1/1
+ port: Ethernet17/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet17/1 - Remote: pod2-leaf9a Ethernet1/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-spine1
+ neighbors:
+ - neighbor_device: pod2-leaf9b
+ neighbor_port: Ethernet1/1
+ port: Ethernet18/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet18/1 - Remote: pod2-leaf9b Ethernet1/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-spine1
+ neighbors:
+ - neighbor_device: pod2-leaf10a
+ neighbor_port: Ethernet1/1
+ port: Ethernet19/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet19/1 - Remote: pod2-leaf10a Ethernet1/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-spine1
+ neighbors:
+ - neighbor_device: pod2-leaf10b
+ neighbor_port: Ethernet1/1
+ port: Ethernet20/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet20/1 - Remote: pod2-leaf10b Ethernet1/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-spine1
+ neighbors:
+ - neighbor_device: super-spine1
+ neighbor_port: Ethernet5/1
+ port: Ethernet31/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet31/1 - Remote: super-spine1 Ethernet5/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-spine1
+ neighbors:
+ - neighbor_device: super-spine2
+ neighbor_port: Ethernet5/1
+ port: Ethernet32/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet32/1 - Remote: super-spine2 Ethernet5/1'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-spine1
+ hosts:
+ - destination: 10.255.255.1
+ repeat: 1
+ source: 10.255.255.0
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet1/1 (IP: 10.255.255.0) - Destination: pod2-leaf1a Ethernet1/1 (IP: 10.255.255.1)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-spine1
+ hosts:
+ - destination: 10.255.255.9
+ repeat: 1
+ source: 10.255.255.8
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet2/1 (IP: 10.255.255.8) - Destination: pod2-leaf1b Ethernet1/1 (IP: 10.255.255.9)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-spine1
+ hosts:
+ - destination: 10.255.255.17
+ repeat: 1
+ source: 10.255.255.16
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet3/1 (IP: 10.255.255.16) - Destination: pod2-leaf2a Ethernet1/1 (IP: 10.255.255.17)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-spine1
+ hosts:
+ - destination: 10.255.255.25
+ repeat: 1
+ source: 10.255.255.24
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet4/1 (IP: 10.255.255.24) - Destination: pod2-leaf2b Ethernet1/1 (IP: 10.255.255.25)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-spine1
+ hosts:
+ - destination: 10.255.255.33
+ repeat: 1
+ source: 10.255.255.32
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet5/1 (IP: 10.255.255.32) - Destination: pod2-leaf3a Ethernet1/1 (IP: 10.255.255.33)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-spine1
+ hosts:
+ - destination: 10.255.255.41
+ repeat: 1
+ source: 10.255.255.40
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet6/1 (IP: 10.255.255.40) - Destination: pod2-leaf3b Ethernet1/1 (IP: 10.255.255.41)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-spine1
+ hosts:
+ - destination: 10.255.255.49
+ repeat: 1
+ source: 10.255.255.48
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet7/1 (IP: 10.255.255.48) - Destination: pod2-leaf4a Ethernet1/1 (IP: 10.255.255.49)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-spine1
+ hosts:
+ - destination: 10.255.255.57
+ repeat: 1
+ source: 10.255.255.56
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet8/1 (IP: 10.255.255.56) - Destination: pod2-leaf4b Ethernet1/1 (IP: 10.255.255.57)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-spine1
+ hosts:
+ - destination: 10.255.255.65
+ repeat: 1
+ source: 10.255.255.64
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet9/1 (IP: 10.255.255.64) - Destination: pod2-leaf5a Ethernet1/1 (IP: 10.255.255.65)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-spine1
+ hosts:
+ - destination: 10.255.255.73
+ repeat: 1
+ source: 10.255.255.72
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet10/1 (IP: 10.255.255.72) - Destination: pod2-leaf5b Ethernet1/1 (IP: 10.255.255.73)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-spine1
+ hosts:
+ - destination: 10.255.255.81
+ repeat: 1
+ source: 10.255.255.80
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet11/1 (IP: 10.255.255.80) - Destination: pod2-leaf6a Ethernet1/1 (IP: 10.255.255.81)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-spine1
+ hosts:
+ - destination: 10.255.255.89
+ repeat: 1
+ source: 10.255.255.88
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet12/1 (IP: 10.255.255.88) - Destination: pod2-leaf6b Ethernet1/1 (IP: 10.255.255.89)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-spine1
+ hosts:
+ - destination: 10.255.255.97
+ repeat: 1
+ source: 10.255.255.96
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet13/1 (IP: 10.255.255.96) - Destination: pod2-leaf7a Ethernet1/1 (IP: 10.255.255.97)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-spine1
+ hosts:
+ - destination: 10.255.255.105
+ repeat: 1
+ source: 10.255.255.104
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet14/1 (IP: 10.255.255.104) - Destination: pod2-leaf7b Ethernet1/1 (IP: 10.255.255.105)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-spine1
+ hosts:
+ - destination: 10.255.255.113
+ repeat: 1
+ source: 10.255.255.112
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet15/1 (IP: 10.255.255.112) - Destination: pod2-leaf8a Ethernet1/1 (IP: 10.255.255.113)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-spine1
+ hosts:
+ - destination: 10.255.255.121
+ repeat: 1
+ source: 10.255.255.120
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet16/1 (IP: 10.255.255.120) - Destination: pod2-leaf8b Ethernet1/1 (IP: 10.255.255.121)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-spine1
+ hosts:
+ - destination: 10.255.255.129
+ repeat: 1
+ source: 10.255.255.128
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet17/1 (IP: 10.255.255.128) - Destination: pod2-leaf9a Ethernet1/1 (IP: 10.255.255.129)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-spine1
+ hosts:
+ - destination: 10.255.255.137
+ repeat: 1
+ source: 10.255.255.136
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet18/1 (IP: 10.255.255.136) - Destination: pod2-leaf9b Ethernet1/1 (IP: 10.255.255.137)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-spine1
+ hosts:
+ - destination: 10.255.255.145
+ repeat: 1
+ source: 10.255.255.144
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet19/1 (IP: 10.255.255.144) - Destination: pod2-leaf10a Ethernet1/1 (IP: 10.255.255.145)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-spine1
+ hosts:
+ - destination: 10.255.255.153
+ repeat: 1
+ source: 10.255.255.152
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet20/1 (IP: 10.255.255.152) - Destination: pod2-leaf10b Ethernet1/1 (IP: 10.255.255.153)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-spine1
+ hosts:
+ - destination: 10.255.255.128
+ repeat: 1
+ source: 10.255.255.129
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet31/1 (IP: 10.255.255.129) - Destination: super-spine1 Ethernet5/1 (IP: 10.255.255.128)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-spine1
+ hosts:
+ - destination: 10.255.255.130
+ repeat: 1
+ source: 10.255.255.131
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet32/1 (IP: 10.255.255.131) - Destination: super-spine2 Ethernet5/1 (IP: 10.255.255.130)'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-leaf3b
+ neighbors:
+ - neighbor_device: pod1-leaf3a
+ neighbor_port: Ethernet53/1
+ port: Ethernet53/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet53/1 - Remote: pod1-leaf3a Ethernet53/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-leaf3b
+ neighbors:
+ - neighbor_device: pod1-leaf3a
+ neighbor_port: Ethernet54/1
+ port: Ethernet54/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet54/1 - Remote: pod1-leaf3a Ethernet54/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-leaf3b
+ neighbors:
+ - neighbor_device: pod1-spine1
+ neighbor_port: Ethernet6/1
+ port: Ethernet1/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet1/1 - Remote: pod1-spine1 Ethernet6/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-leaf3b
+ neighbors:
+ - neighbor_device: pod1-spine2
+ neighbor_port: Ethernet6/1
+ port: Ethernet2/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet2/1 - Remote: pod1-spine2 Ethernet6/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-leaf3b
+ neighbors:
+ - neighbor_device: pod1-spine3
+ neighbor_port: Ethernet6/1
+ port: Ethernet3/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet3/1 - Remote: pod1-spine3 Ethernet6/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-leaf3b
+ neighbors:
+ - neighbor_device: pod1-spine4
+ neighbor_port: Ethernet6/1
+ port: Ethernet4/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet4/1 - Remote: pod1-spine4 Ethernet6/1'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf3b
+ hosts:
+ - destination: 10.255.255.40
+ repeat: 1
+ source: 10.255.255.41
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet1/1 (IP: 10.255.255.41) - Destination: pod1-spine1 Ethernet6/1 (IP: 10.255.255.40)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf3b
+ hosts:
+ - destination: 10.255.255.42
+ repeat: 1
+ source: 10.255.255.43
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet2/1 (IP: 10.255.255.43) - Destination: pod1-spine2 Ethernet6/1 (IP: 10.255.255.42)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf3b
+ hosts:
+ - destination: 10.255.255.44
+ repeat: 1
+ source: 10.255.255.45
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet3/1 (IP: 10.255.255.45) - Destination: pod1-spine3 Ethernet6/1 (IP: 10.255.255.44)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf3b
+ hosts:
+ - destination: 10.255.255.46
+ repeat: 1
+ source: 10.255.255.47
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet4/1 (IP: 10.255.255.47) - Destination: pod1-spine4 Ethernet6/1 (IP: 10.255.255.46)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf3b
+ hosts:
+ - destination: 10.255.0.1
+ repeat: 1
+ source: 10.255.1.10
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.10) - Destination: super-spine1 Loopback0 (IP: 10.255.0.1)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf3b
+ hosts:
+ - destination: 10.255.0.2
+ repeat: 1
+ source: 10.255.1.10
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.10) - Destination: super-spine2 Loopback0 (IP: 10.255.0.2)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf3b
+ hosts:
+ - destination: 10.255.1.1
+ repeat: 1
+ source: 10.255.1.10
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.10) - Destination: pod1-spine1 Loopback0 (IP: 10.255.1.1)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf3b
+ hosts:
+ - destination: 10.255.1.2
+ repeat: 1
+ source: 10.255.1.10
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.10) - Destination: pod1-spine2 Loopback0 (IP: 10.255.1.2)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf3b
+ hosts:
+ - destination: 10.255.1.3
+ repeat: 1
+ source: 10.255.1.10
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.10) - Destination: pod1-spine3 Loopback0 (IP: 10.255.1.3)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf3b
+ hosts:
+ - destination: 10.255.1.4
+ repeat: 1
+ source: 10.255.1.10
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.10) - Destination: pod1-spine4 Loopback0 (IP: 10.255.1.4)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf3b
+ hosts:
+ - destination: 10.255.1.5
+ repeat: 1
+ source: 10.255.1.10
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.10) - Destination: pod1-leaf1a Loopback0 (IP: 10.255.1.5)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf3b
+ hosts:
+ - destination: 10.255.1.6
+ repeat: 1
+ source: 10.255.1.10
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.10) - Destination: pod1-leaf1b Loopback0 (IP: 10.255.1.6)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf3b
+ hosts:
+ - destination: 10.255.1.7
+ repeat: 1
+ source: 10.255.1.10
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.10) - Destination: pod1-leaf2a Loopback0 (IP: 10.255.1.7)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf3b
+ hosts:
+ - destination: 10.255.1.8
+ repeat: 1
+ source: 10.255.1.10
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.10) - Destination: pod1-leaf2b Loopback0 (IP: 10.255.1.8)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf3b
+ hosts:
+ - destination: 10.255.1.9
+ repeat: 1
+ source: 10.255.1.10
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.10) - Destination: pod1-leaf3a Loopback0 (IP: 10.255.1.9)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf3b
+ hosts:
+ - destination: 10.255.1.10
+ repeat: 1
+ source: 10.255.1.10
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.10) - Destination: pod1-leaf3b Loopback0 (IP: 10.255.1.10)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf3b
+ hosts:
+ - destination: 10.255.1.11
+ repeat: 1
+ source: 10.255.1.10
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.10) - Destination: pod1-leaf4a Loopback0 (IP: 10.255.1.11)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf3b
+ hosts:
+ - destination: 10.255.1.12
+ repeat: 1
+ source: 10.255.1.10
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.10) - Destination: pod1-leaf4b Loopback0 (IP: 10.255.1.12)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf3b
+ hosts:
+ - destination: 10.255.1.13
+ repeat: 1
+ source: 10.255.1.10
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.10) - Destination: pod1-leaf5a Loopback0 (IP: 10.255.1.13)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf3b
+ hosts:
+ - destination: 10.255.1.14
+ repeat: 1
+ source: 10.255.1.10
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.10) - Destination: pod1-leaf5b Loopback0 (IP: 10.255.1.14)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf3b
+ hosts:
+ - destination: 10.255.1.15
+ repeat: 1
+ source: 10.255.1.10
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.10) - Destination: pod1-leaf6a Loopback0 (IP: 10.255.1.15)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf3b
+ hosts:
+ - destination: 10.255.1.16
+ repeat: 1
+ source: 10.255.1.10
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.10) - Destination: pod1-leaf6b Loopback0 (IP: 10.255.1.16)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf3b
+ hosts:
+ - destination: 10.255.1.17
+ repeat: 1
+ source: 10.255.1.10
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.10) - Destination: pod1-leaf7a Loopback0 (IP: 10.255.1.17)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf3b
+ hosts:
+ - destination: 10.255.1.18
+ repeat: 1
+ source: 10.255.1.10
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.10) - Destination: pod1-leaf7b Loopback0 (IP: 10.255.1.18)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf3b
+ hosts:
+ - destination: 10.255.1.19
+ repeat: 1
+ source: 10.255.1.10
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.10) - Destination: pod1-leaf8a Loopback0 (IP: 10.255.1.19)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf3b
+ hosts:
+ - destination: 10.255.1.20
+ repeat: 1
+ source: 10.255.1.10
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.10) - Destination: pod1-leaf8b Loopback0 (IP: 10.255.1.20)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf3b
+ hosts:
+ - destination: 10.255.1.21
+ repeat: 1
+ source: 10.255.1.10
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.10) - Destination: pod1-leaf9a Loopback0 (IP: 10.255.1.21)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf3b
+ hosts:
+ - destination: 10.255.1.22
+ repeat: 1
+ source: 10.255.1.10
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.10) - Destination: pod1-leaf9b Loopback0 (IP: 10.255.1.22)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf3b
+ hosts:
+ - destination: 10.255.1.23
+ repeat: 1
+ source: 10.255.1.10
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.10) - Destination: pod1-leaf10a Loopback0 (IP: 10.255.1.23)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf3b
+ hosts:
+ - destination: 10.255.1.24
+ repeat: 1
+ source: 10.255.1.10
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.10) - Destination: pod1-leaf10b Loopback0 (IP: 10.255.1.24)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf3b
+ hosts:
+ - destination: 10.255.2.1
+ repeat: 1
+ source: 10.255.1.10
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.10) - Destination: pod2-spine1 Loopback0 (IP: 10.255.2.1)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf3b
+ hosts:
+ - destination: 10.255.2.2
+ repeat: 1
+ source: 10.255.1.10
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.10) - Destination: pod2-spine2 Loopback0 (IP: 10.255.2.2)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf3b
+ hosts:
+ - destination: 10.255.2.3
+ repeat: 1
+ source: 10.255.1.10
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.10) - Destination: pod2-spine3 Loopback0 (IP: 10.255.2.3)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf3b
+ hosts:
+ - destination: 10.255.2.4
+ repeat: 1
+ source: 10.255.1.10
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.10) - Destination: pod2-spine4 Loopback0 (IP: 10.255.2.4)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf3b
+ hosts:
+ - destination: 10.255.2.5
+ repeat: 1
+ source: 10.255.1.10
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.10) - Destination: pod2-leaf1a Loopback0 (IP: 10.255.2.5)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf3b
+ hosts:
+ - destination: 10.255.2.6
+ repeat: 1
+ source: 10.255.1.10
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.10) - Destination: pod2-leaf1b Loopback0 (IP: 10.255.2.6)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf3b
+ hosts:
+ - destination: 10.255.2.7
+ repeat: 1
+ source: 10.255.1.10
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.10) - Destination: pod2-leaf2a Loopback0 (IP: 10.255.2.7)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf3b
+ hosts:
+ - destination: 10.255.2.8
+ repeat: 1
+ source: 10.255.1.10
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.10) - Destination: pod2-leaf2b Loopback0 (IP: 10.255.2.8)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf3b
+ hosts:
+ - destination: 10.255.2.9
+ repeat: 1
+ source: 10.255.1.10
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.10) - Destination: pod2-leaf3a Loopback0 (IP: 10.255.2.9)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf3b
+ hosts:
+ - destination: 10.255.2.10
+ repeat: 1
+ source: 10.255.1.10
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.10) - Destination: pod2-leaf3b Loopback0 (IP: 10.255.2.10)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf3b
+ hosts:
+ - destination: 10.255.2.11
+ repeat: 1
+ source: 10.255.1.10
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.10) - Destination: pod2-leaf4a Loopback0 (IP: 10.255.2.11)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf3b
+ hosts:
+ - destination: 10.255.2.12
+ repeat: 1
+ source: 10.255.1.10
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.10) - Destination: pod2-leaf4b Loopback0 (IP: 10.255.2.12)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf3b
+ hosts:
+ - destination: 10.255.2.13
+ repeat: 1
+ source: 10.255.1.10
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.10) - Destination: pod2-leaf5a Loopback0 (IP: 10.255.2.13)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf3b
+ hosts:
+ - destination: 10.255.2.14
+ repeat: 1
+ source: 10.255.1.10
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.10) - Destination: pod2-leaf5b Loopback0 (IP: 10.255.2.14)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf3b
+ hosts:
+ - destination: 10.255.2.15
+ repeat: 1
+ source: 10.255.1.10
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.10) - Destination: pod2-leaf6a Loopback0 (IP: 10.255.2.15)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf3b
+ hosts:
+ - destination: 10.255.2.16
+ repeat: 1
+ source: 10.255.1.10
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.10) - Destination: pod2-leaf6b Loopback0 (IP: 10.255.2.16)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf3b
+ hosts:
+ - destination: 10.255.2.17
+ repeat: 1
+ source: 10.255.1.10
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.10) - Destination: pod2-leaf7a Loopback0 (IP: 10.255.2.17)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf3b
+ hosts:
+ - destination: 10.255.2.18
+ repeat: 1
+ source: 10.255.1.10
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.10) - Destination: pod2-leaf7b Loopback0 (IP: 10.255.2.18)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf3b
+ hosts:
+ - destination: 10.255.2.19
+ repeat: 1
+ source: 10.255.1.10
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.10) - Destination: pod2-leaf8a Loopback0 (IP: 10.255.2.19)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf3b
+ hosts:
+ - destination: 10.255.2.20
+ repeat: 1
+ source: 10.255.1.10
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.10) - Destination: pod2-leaf8b Loopback0 (IP: 10.255.2.20)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf3b
+ hosts:
+ - destination: 10.255.2.21
+ repeat: 1
+ source: 10.255.1.10
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.10) - Destination: pod2-leaf9a Loopback0 (IP: 10.255.2.21)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf3b
+ hosts:
+ - destination: 10.255.2.22
+ repeat: 1
+ source: 10.255.1.10
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.10) - Destination: pod2-leaf9b Loopback0 (IP: 10.255.2.22)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf3b
+ hosts:
+ - destination: 10.255.2.23
+ repeat: 1
+ source: 10.255.1.10
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.10) - Destination: pod2-leaf10a Loopback0 (IP: 10.255.2.23)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf3b
+ hosts:
+ - destination: 10.255.2.24
+ repeat: 1
+ source: 10.255.1.10
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.10) - Destination: pod2-leaf10b Loopback0 (IP: 10.255.2.24)'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-leaf9a
+ neighbors:
+ - neighbor_device: pod1-leaf9b
+ neighbor_port: Ethernet53/1
+ port: Ethernet53/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet53/1 - Remote: pod1-leaf9b Ethernet53/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-leaf9a
+ neighbors:
+ - neighbor_device: pod1-leaf9b
+ neighbor_port: Ethernet54/1
+ port: Ethernet54/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet54/1 - Remote: pod1-leaf9b Ethernet54/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-leaf9a
+ neighbors:
+ - neighbor_device: pod1-spine1
+ neighbor_port: Ethernet17/1
+ port: Ethernet1/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet1/1 - Remote: pod1-spine1 Ethernet17/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-leaf9a
+ neighbors:
+ - neighbor_device: pod1-spine2
+ neighbor_port: Ethernet17/1
+ port: Ethernet2/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet2/1 - Remote: pod1-spine2 Ethernet17/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-leaf9a
+ neighbors:
+ - neighbor_device: pod1-spine3
+ neighbor_port: Ethernet17/1
+ port: Ethernet3/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet3/1 - Remote: pod1-spine3 Ethernet17/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-leaf9a
+ neighbors:
+ - neighbor_device: pod1-spine4
+ neighbor_port: Ethernet17/1
+ port: Ethernet4/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet4/1 - Remote: pod1-spine4 Ethernet17/1'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf9a
+ hosts:
+ - destination: 10.255.255.128
+ repeat: 1
+ source: 10.255.255.129
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet1/1 (IP: 10.255.255.129) - Destination: pod1-spine1 Ethernet17/1 (IP: 10.255.255.128)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf9a
+ hosts:
+ - destination: 10.255.255.130
+ repeat: 1
+ source: 10.255.255.131
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet2/1 (IP: 10.255.255.131) - Destination: pod1-spine2 Ethernet17/1 (IP: 10.255.255.130)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf9a
+ hosts:
+ - destination: 10.255.255.132
+ repeat: 1
+ source: 10.255.255.133
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet3/1 (IP: 10.255.255.133) - Destination: pod1-spine3 Ethernet17/1 (IP: 10.255.255.132)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf9a
+ hosts:
+ - destination: 10.255.255.134
+ repeat: 1
+ source: 10.255.255.135
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet4/1 (IP: 10.255.255.135) - Destination: pod1-spine4 Ethernet17/1 (IP: 10.255.255.134)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf9a
+ hosts:
+ - destination: 10.255.0.1
+ repeat: 1
+ source: 10.255.1.21
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.21) - Destination: super-spine1 Loopback0 (IP: 10.255.0.1)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf9a
+ hosts:
+ - destination: 10.255.0.2
+ repeat: 1
+ source: 10.255.1.21
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.21) - Destination: super-spine2 Loopback0 (IP: 10.255.0.2)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf9a
+ hosts:
+ - destination: 10.255.1.1
+ repeat: 1
+ source: 10.255.1.21
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.21) - Destination: pod1-spine1 Loopback0 (IP: 10.255.1.1)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf9a
+ hosts:
+ - destination: 10.255.1.2
+ repeat: 1
+ source: 10.255.1.21
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.21) - Destination: pod1-spine2 Loopback0 (IP: 10.255.1.2)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf9a
+ hosts:
+ - destination: 10.255.1.3
+ repeat: 1
+ source: 10.255.1.21
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.21) - Destination: pod1-spine3 Loopback0 (IP: 10.255.1.3)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf9a
+ hosts:
+ - destination: 10.255.1.4
+ repeat: 1
+ source: 10.255.1.21
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.21) - Destination: pod1-spine4 Loopback0 (IP: 10.255.1.4)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf9a
+ hosts:
+ - destination: 10.255.1.5
+ repeat: 1
+ source: 10.255.1.21
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.21) - Destination: pod1-leaf1a Loopback0 (IP: 10.255.1.5)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf9a
+ hosts:
+ - destination: 10.255.1.6
+ repeat: 1
+ source: 10.255.1.21
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.21) - Destination: pod1-leaf1b Loopback0 (IP: 10.255.1.6)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf9a
+ hosts:
+ - destination: 10.255.1.7
+ repeat: 1
+ source: 10.255.1.21
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.21) - Destination: pod1-leaf2a Loopback0 (IP: 10.255.1.7)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf9a
+ hosts:
+ - destination: 10.255.1.8
+ repeat: 1
+ source: 10.255.1.21
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.21) - Destination: pod1-leaf2b Loopback0 (IP: 10.255.1.8)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf9a
+ hosts:
+ - destination: 10.255.1.9
+ repeat: 1
+ source: 10.255.1.21
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.21) - Destination: pod1-leaf3a Loopback0 (IP: 10.255.1.9)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf9a
+ hosts:
+ - destination: 10.255.1.10
+ repeat: 1
+ source: 10.255.1.21
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.21) - Destination: pod1-leaf3b Loopback0 (IP: 10.255.1.10)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf9a
+ hosts:
+ - destination: 10.255.1.11
+ repeat: 1
+ source: 10.255.1.21
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.21) - Destination: pod1-leaf4a Loopback0 (IP: 10.255.1.11)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf9a
+ hosts:
+ - destination: 10.255.1.12
+ repeat: 1
+ source: 10.255.1.21
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.21) - Destination: pod1-leaf4b Loopback0 (IP: 10.255.1.12)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf9a
+ hosts:
+ - destination: 10.255.1.13
+ repeat: 1
+ source: 10.255.1.21
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.21) - Destination: pod1-leaf5a Loopback0 (IP: 10.255.1.13)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf9a
+ hosts:
+ - destination: 10.255.1.14
+ repeat: 1
+ source: 10.255.1.21
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.21) - Destination: pod1-leaf5b Loopback0 (IP: 10.255.1.14)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf9a
+ hosts:
+ - destination: 10.255.1.15
+ repeat: 1
+ source: 10.255.1.21
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.21) - Destination: pod1-leaf6a Loopback0 (IP: 10.255.1.15)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf9a
+ hosts:
+ - destination: 10.255.1.16
+ repeat: 1
+ source: 10.255.1.21
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.21) - Destination: pod1-leaf6b Loopback0 (IP: 10.255.1.16)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf9a
+ hosts:
+ - destination: 10.255.1.17
+ repeat: 1
+ source: 10.255.1.21
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.21) - Destination: pod1-leaf7a Loopback0 (IP: 10.255.1.17)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf9a
+ hosts:
+ - destination: 10.255.1.18
+ repeat: 1
+ source: 10.255.1.21
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.21) - Destination: pod1-leaf7b Loopback0 (IP: 10.255.1.18)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf9a
+ hosts:
+ - destination: 10.255.1.19
+ repeat: 1
+ source: 10.255.1.21
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.21) - Destination: pod1-leaf8a Loopback0 (IP: 10.255.1.19)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf9a
+ hosts:
+ - destination: 10.255.1.20
+ repeat: 1
+ source: 10.255.1.21
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.21) - Destination: pod1-leaf8b Loopback0 (IP: 10.255.1.20)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf9a
+ hosts:
+ - destination: 10.255.1.21
+ repeat: 1
+ source: 10.255.1.21
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.21) - Destination: pod1-leaf9a Loopback0 (IP: 10.255.1.21)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf9a
+ hosts:
+ - destination: 10.255.1.22
+ repeat: 1
+ source: 10.255.1.21
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.21) - Destination: pod1-leaf9b Loopback0 (IP: 10.255.1.22)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf9a
+ hosts:
+ - destination: 10.255.1.23
+ repeat: 1
+ source: 10.255.1.21
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.21) - Destination: pod1-leaf10a Loopback0 (IP: 10.255.1.23)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf9a
+ hosts:
+ - destination: 10.255.1.24
+ repeat: 1
+ source: 10.255.1.21
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.21) - Destination: pod1-leaf10b Loopback0 (IP: 10.255.1.24)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf9a
+ hosts:
+ - destination: 10.255.2.1
+ repeat: 1
+ source: 10.255.1.21
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.21) - Destination: pod2-spine1 Loopback0 (IP: 10.255.2.1)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf9a
+ hosts:
+ - destination: 10.255.2.2
+ repeat: 1
+ source: 10.255.1.21
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.21) - Destination: pod2-spine2 Loopback0 (IP: 10.255.2.2)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf9a
+ hosts:
+ - destination: 10.255.2.3
+ repeat: 1
+ source: 10.255.1.21
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.21) - Destination: pod2-spine3 Loopback0 (IP: 10.255.2.3)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf9a
+ hosts:
+ - destination: 10.255.2.4
+ repeat: 1
+ source: 10.255.1.21
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.21) - Destination: pod2-spine4 Loopback0 (IP: 10.255.2.4)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf9a
+ hosts:
+ - destination: 10.255.2.5
+ repeat: 1
+ source: 10.255.1.21
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.21) - Destination: pod2-leaf1a Loopback0 (IP: 10.255.2.5)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf9a
+ hosts:
+ - destination: 10.255.2.6
+ repeat: 1
+ source: 10.255.1.21
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.21) - Destination: pod2-leaf1b Loopback0 (IP: 10.255.2.6)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf9a
+ hosts:
+ - destination: 10.255.2.7
+ repeat: 1
+ source: 10.255.1.21
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.21) - Destination: pod2-leaf2a Loopback0 (IP: 10.255.2.7)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf9a
+ hosts:
+ - destination: 10.255.2.8
+ repeat: 1
+ source: 10.255.1.21
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.21) - Destination: pod2-leaf2b Loopback0 (IP: 10.255.2.8)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf9a
+ hosts:
+ - destination: 10.255.2.9
+ repeat: 1
+ source: 10.255.1.21
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.21) - Destination: pod2-leaf3a Loopback0 (IP: 10.255.2.9)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf9a
+ hosts:
+ - destination: 10.255.2.10
+ repeat: 1
+ source: 10.255.1.21
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.21) - Destination: pod2-leaf3b Loopback0 (IP: 10.255.2.10)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf9a
+ hosts:
+ - destination: 10.255.2.11
+ repeat: 1
+ source: 10.255.1.21
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.21) - Destination: pod2-leaf4a Loopback0 (IP: 10.255.2.11)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf9a
+ hosts:
+ - destination: 10.255.2.12
+ repeat: 1
+ source: 10.255.1.21
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.21) - Destination: pod2-leaf4b Loopback0 (IP: 10.255.2.12)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf9a
+ hosts:
+ - destination: 10.255.2.13
+ repeat: 1
+ source: 10.255.1.21
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.21) - Destination: pod2-leaf5a Loopback0 (IP: 10.255.2.13)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf9a
+ hosts:
+ - destination: 10.255.2.14
+ repeat: 1
+ source: 10.255.1.21
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.21) - Destination: pod2-leaf5b Loopback0 (IP: 10.255.2.14)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf9a
+ hosts:
+ - destination: 10.255.2.15
+ repeat: 1
+ source: 10.255.1.21
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.21) - Destination: pod2-leaf6a Loopback0 (IP: 10.255.2.15)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf9a
+ hosts:
+ - destination: 10.255.2.16
+ repeat: 1
+ source: 10.255.1.21
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.21) - Destination: pod2-leaf6b Loopback0 (IP: 10.255.2.16)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf9a
+ hosts:
+ - destination: 10.255.2.17
+ repeat: 1
+ source: 10.255.1.21
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.21) - Destination: pod2-leaf7a Loopback0 (IP: 10.255.2.17)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf9a
+ hosts:
+ - destination: 10.255.2.18
+ repeat: 1
+ source: 10.255.1.21
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.21) - Destination: pod2-leaf7b Loopback0 (IP: 10.255.2.18)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf9a
+ hosts:
+ - destination: 10.255.2.19
+ repeat: 1
+ source: 10.255.1.21
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.21) - Destination: pod2-leaf8a Loopback0 (IP: 10.255.2.19)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf9a
+ hosts:
+ - destination: 10.255.2.20
+ repeat: 1
+ source: 10.255.1.21
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.21) - Destination: pod2-leaf8b Loopback0 (IP: 10.255.2.20)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf9a
+ hosts:
+ - destination: 10.255.2.21
+ repeat: 1
+ source: 10.255.1.21
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.21) - Destination: pod2-leaf9a Loopback0 (IP: 10.255.2.21)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf9a
+ hosts:
+ - destination: 10.255.2.22
+ repeat: 1
+ source: 10.255.1.21
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.21) - Destination: pod2-leaf9b Loopback0 (IP: 10.255.2.22)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf9a
+ hosts:
+ - destination: 10.255.2.23
+ repeat: 1
+ source: 10.255.1.21
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.21) - Destination: pod2-leaf10a Loopback0 (IP: 10.255.2.23)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf9a
+ hosts:
+ - destination: 10.255.2.24
+ repeat: 1
+ source: 10.255.1.21
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.21) - Destination: pod2-leaf10b Loopback0 (IP: 10.255.2.24)'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-spine4
+ neighbors:
+ - neighbor_device: pod1-leaf1a
+ neighbor_port: Ethernet4/1
+ port: Ethernet1/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet1/1 - Remote: pod1-leaf1a Ethernet4/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-spine4
+ neighbors:
+ - neighbor_device: pod1-leaf1b
+ neighbor_port: Ethernet4/1
+ port: Ethernet2/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet2/1 - Remote: pod1-leaf1b Ethernet4/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-spine4
+ neighbors:
+ - neighbor_device: pod1-leaf2a
+ neighbor_port: Ethernet4/1
+ port: Ethernet3/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet3/1 - Remote: pod1-leaf2a Ethernet4/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-spine4
+ neighbors:
+ - neighbor_device: pod1-leaf2b
+ neighbor_port: Ethernet4/1
+ port: Ethernet4/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet4/1 - Remote: pod1-leaf2b Ethernet4/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-spine4
+ neighbors:
+ - neighbor_device: pod1-leaf3a
+ neighbor_port: Ethernet4/1
+ port: Ethernet5/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet5/1 - Remote: pod1-leaf3a Ethernet4/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-spine4
+ neighbors:
+ - neighbor_device: pod1-leaf3b
+ neighbor_port: Ethernet4/1
+ port: Ethernet6/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet6/1 - Remote: pod1-leaf3b Ethernet4/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-spine4
+ neighbors:
+ - neighbor_device: pod1-leaf4a
+ neighbor_port: Ethernet4/1
+ port: Ethernet7/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet7/1 - Remote: pod1-leaf4a Ethernet4/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-spine4
+ neighbors:
+ - neighbor_device: pod1-leaf4b
+ neighbor_port: Ethernet4/1
+ port: Ethernet8/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet8/1 - Remote: pod1-leaf4b Ethernet4/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-spine4
+ neighbors:
+ - neighbor_device: pod1-leaf5a
+ neighbor_port: Ethernet4/1
+ port: Ethernet9/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet9/1 - Remote: pod1-leaf5a Ethernet4/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-spine4
+ neighbors:
+ - neighbor_device: pod1-leaf5b
+ neighbor_port: Ethernet4/1
+ port: Ethernet10/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet10/1 - Remote: pod1-leaf5b Ethernet4/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-spine4
+ neighbors:
+ - neighbor_device: pod1-leaf6a
+ neighbor_port: Ethernet4/1
+ port: Ethernet11/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet11/1 - Remote: pod1-leaf6a Ethernet4/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-spine4
+ neighbors:
+ - neighbor_device: pod1-leaf6b
+ neighbor_port: Ethernet4/1
+ port: Ethernet12/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet12/1 - Remote: pod1-leaf6b Ethernet4/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-spine4
+ neighbors:
+ - neighbor_device: pod1-leaf7a
+ neighbor_port: Ethernet4/1
+ port: Ethernet13/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet13/1 - Remote: pod1-leaf7a Ethernet4/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-spine4
+ neighbors:
+ - neighbor_device: pod1-leaf7b
+ neighbor_port: Ethernet4/1
+ port: Ethernet14/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet14/1 - Remote: pod1-leaf7b Ethernet4/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-spine4
+ neighbors:
+ - neighbor_device: pod1-leaf8a
+ neighbor_port: Ethernet4/1
+ port: Ethernet15/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet15/1 - Remote: pod1-leaf8a Ethernet4/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-spine4
+ neighbors:
+ - neighbor_device: pod1-leaf8b
+ neighbor_port: Ethernet4/1
+ port: Ethernet16/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet16/1 - Remote: pod1-leaf8b Ethernet4/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-spine4
+ neighbors:
+ - neighbor_device: pod1-leaf9a
+ neighbor_port: Ethernet4/1
+ port: Ethernet17/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet17/1 - Remote: pod1-leaf9a Ethernet4/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-spine4
+ neighbors:
+ - neighbor_device: pod1-leaf9b
+ neighbor_port: Ethernet4/1
+ port: Ethernet18/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet18/1 - Remote: pod1-leaf9b Ethernet4/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-spine4
+ neighbors:
+ - neighbor_device: pod1-leaf10a
+ neighbor_port: Ethernet4/1
+ port: Ethernet19/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet19/1 - Remote: pod1-leaf10a Ethernet4/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-spine4
+ neighbors:
+ - neighbor_device: pod1-leaf10b
+ neighbor_port: Ethernet4/1
+ port: Ethernet20/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet20/1 - Remote: pod1-leaf10b Ethernet4/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-spine4
+ neighbors:
+ - neighbor_device: super-spine1
+ neighbor_port: Ethernet4/1
+ port: Ethernet31/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet31/1 - Remote: super-spine1 Ethernet4/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-spine4
+ neighbors:
+ - neighbor_device: super-spine2
+ neighbor_port: Ethernet4/1
+ port: Ethernet32/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet32/1 - Remote: super-spine2 Ethernet4/1'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-spine4
+ hosts:
+ - destination: 10.255.255.7
+ repeat: 1
+ source: 10.255.255.6
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet1/1 (IP: 10.255.255.6) - Destination: pod1-leaf1a Ethernet4/1 (IP: 10.255.255.7)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-spine4
+ hosts:
+ - destination: 10.255.255.15
+ repeat: 1
+ source: 10.255.255.14
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet2/1 (IP: 10.255.255.14) - Destination: pod1-leaf1b Ethernet4/1 (IP: 10.255.255.15)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-spine4
+ hosts:
+ - destination: 10.255.255.23
+ repeat: 1
+ source: 10.255.255.22
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet3/1 (IP: 10.255.255.22) - Destination: pod1-leaf2a Ethernet4/1 (IP: 10.255.255.23)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-spine4
+ hosts:
+ - destination: 10.255.255.31
+ repeat: 1
+ source: 10.255.255.30
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet4/1 (IP: 10.255.255.30) - Destination: pod1-leaf2b Ethernet4/1 (IP: 10.255.255.31)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-spine4
+ hosts:
+ - destination: 10.255.255.39
+ repeat: 1
+ source: 10.255.255.38
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet5/1 (IP: 10.255.255.38) - Destination: pod1-leaf3a Ethernet4/1 (IP: 10.255.255.39)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-spine4
+ hosts:
+ - destination: 10.255.255.47
+ repeat: 1
+ source: 10.255.255.46
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet6/1 (IP: 10.255.255.46) - Destination: pod1-leaf3b Ethernet4/1 (IP: 10.255.255.47)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-spine4
+ hosts:
+ - destination: 10.255.255.55
+ repeat: 1
+ source: 10.255.255.54
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet7/1 (IP: 10.255.255.54) - Destination: pod1-leaf4a Ethernet4/1 (IP: 10.255.255.55)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-spine4
+ hosts:
+ - destination: 10.255.255.63
+ repeat: 1
+ source: 10.255.255.62
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet8/1 (IP: 10.255.255.62) - Destination: pod1-leaf4b Ethernet4/1 (IP: 10.255.255.63)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-spine4
+ hosts:
+ - destination: 10.255.255.71
+ repeat: 1
+ source: 10.255.255.70
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet9/1 (IP: 10.255.255.70) - Destination: pod1-leaf5a Ethernet4/1 (IP: 10.255.255.71)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-spine4
+ hosts:
+ - destination: 10.255.255.79
+ repeat: 1
+ source: 10.255.255.78
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet10/1 (IP: 10.255.255.78) - Destination: pod1-leaf5b Ethernet4/1 (IP: 10.255.255.79)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-spine4
+ hosts:
+ - destination: 10.255.255.87
+ repeat: 1
+ source: 10.255.255.86
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet11/1 (IP: 10.255.255.86) - Destination: pod1-leaf6a Ethernet4/1 (IP: 10.255.255.87)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-spine4
+ hosts:
+ - destination: 10.255.255.95
+ repeat: 1
+ source: 10.255.255.94
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet12/1 (IP: 10.255.255.94) - Destination: pod1-leaf6b Ethernet4/1 (IP: 10.255.255.95)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-spine4
+ hosts:
+ - destination: 10.255.255.103
+ repeat: 1
+ source: 10.255.255.102
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet13/1 (IP: 10.255.255.102) - Destination: pod1-leaf7a Ethernet4/1 (IP: 10.255.255.103)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-spine4
+ hosts:
+ - destination: 10.255.255.111
+ repeat: 1
+ source: 10.255.255.110
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet14/1 (IP: 10.255.255.110) - Destination: pod1-leaf7b Ethernet4/1 (IP: 10.255.255.111)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-spine4
+ hosts:
+ - destination: 10.255.255.119
+ repeat: 1
+ source: 10.255.255.118
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet15/1 (IP: 10.255.255.118) - Destination: pod1-leaf8a Ethernet4/1 (IP: 10.255.255.119)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-spine4
+ hosts:
+ - destination: 10.255.255.127
+ repeat: 1
+ source: 10.255.255.126
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet16/1 (IP: 10.255.255.126) - Destination: pod1-leaf8b Ethernet4/1 (IP: 10.255.255.127)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-spine4
+ hosts:
+ - destination: 10.255.255.135
+ repeat: 1
+ source: 10.255.255.134
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet17/1 (IP: 10.255.255.134) - Destination: pod1-leaf9a Ethernet4/1 (IP: 10.255.255.135)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-spine4
+ hosts:
+ - destination: 10.255.255.143
+ repeat: 1
+ source: 10.255.255.142
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet18/1 (IP: 10.255.255.142) - Destination: pod1-leaf9b Ethernet4/1 (IP: 10.255.255.143)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-spine4
+ hosts:
+ - destination: 10.255.255.151
+ repeat: 1
+ source: 10.255.255.150
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet19/1 (IP: 10.255.255.150) - Destination: pod1-leaf10a Ethernet4/1 (IP: 10.255.255.151)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-spine4
+ hosts:
+ - destination: 10.255.255.159
+ repeat: 1
+ source: 10.255.255.158
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet20/1 (IP: 10.255.255.158) - Destination: pod1-leaf10b Ethernet4/1 (IP: 10.255.255.159)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-spine4
+ hosts:
+ - destination: 10.255.255.12
+ repeat: 1
+ source: 10.255.255.13
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet31/1 (IP: 10.255.255.13) - Destination: super-spine1 Ethernet4/1 (IP: 10.255.255.12)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-spine4
+ hosts:
+ - destination: 10.255.255.14
+ repeat: 1
+ source: 10.255.255.15
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet32/1 (IP: 10.255.255.15) - Destination: super-spine2 Ethernet4/1 (IP: 10.255.255.14)'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-leaf5b
+ neighbors:
+ - neighbor_device: pod2-leaf5a
+ neighbor_port: Ethernet53/1
+ port: Ethernet53/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet53/1 - Remote: pod2-leaf5a Ethernet53/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-leaf5b
+ neighbors:
+ - neighbor_device: pod2-leaf5a
+ neighbor_port: Ethernet54/1
+ port: Ethernet54/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet54/1 - Remote: pod2-leaf5a Ethernet54/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-leaf5b
+ neighbors:
+ - neighbor_device: pod2-spine1
+ neighbor_port: Ethernet10/1
+ port: Ethernet1/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet1/1 - Remote: pod2-spine1 Ethernet10/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-leaf5b
+ neighbors:
+ - neighbor_device: pod2-spine2
+ neighbor_port: Ethernet10/1
+ port: Ethernet2/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet2/1 - Remote: pod2-spine2 Ethernet10/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-leaf5b
+ neighbors:
+ - neighbor_device: pod2-spine3
+ neighbor_port: Ethernet10/1
+ port: Ethernet3/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet3/1 - Remote: pod2-spine3 Ethernet10/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-leaf5b
+ neighbors:
+ - neighbor_device: pod2-spine4
+ neighbor_port: Ethernet10/1
+ port: Ethernet4/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet4/1 - Remote: pod2-spine4 Ethernet10/1'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf5b
+ hosts:
+ - destination: 10.255.255.72
+ repeat: 1
+ source: 10.255.255.73
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet1/1 (IP: 10.255.255.73) - Destination: pod2-spine1 Ethernet10/1 (IP: 10.255.255.72)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf5b
+ hosts:
+ - destination: 10.255.255.74
+ repeat: 1
+ source: 10.255.255.75
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet2/1 (IP: 10.255.255.75) - Destination: pod2-spine2 Ethernet10/1 (IP: 10.255.255.74)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf5b
+ hosts:
+ - destination: 10.255.255.76
+ repeat: 1
+ source: 10.255.255.77
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet3/1 (IP: 10.255.255.77) - Destination: pod2-spine3 Ethernet10/1 (IP: 10.255.255.76)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf5b
+ hosts:
+ - destination: 10.255.255.78
+ repeat: 1
+ source: 10.255.255.79
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet4/1 (IP: 10.255.255.79) - Destination: pod2-spine4 Ethernet10/1 (IP: 10.255.255.78)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf5b
+ hosts:
+ - destination: 10.255.0.1
+ repeat: 1
+ source: 10.255.2.14
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.14) - Destination: super-spine1 Loopback0 (IP: 10.255.0.1)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf5b
+ hosts:
+ - destination: 10.255.0.2
+ repeat: 1
+ source: 10.255.2.14
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.14) - Destination: super-spine2 Loopback0 (IP: 10.255.0.2)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf5b
+ hosts:
+ - destination: 10.255.1.1
+ repeat: 1
+ source: 10.255.2.14
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.14) - Destination: pod1-spine1 Loopback0 (IP: 10.255.1.1)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf5b
+ hosts:
+ - destination: 10.255.1.2
+ repeat: 1
+ source: 10.255.2.14
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.14) - Destination: pod1-spine2 Loopback0 (IP: 10.255.1.2)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf5b
+ hosts:
+ - destination: 10.255.1.3
+ repeat: 1
+ source: 10.255.2.14
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.14) - Destination: pod1-spine3 Loopback0 (IP: 10.255.1.3)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf5b
+ hosts:
+ - destination: 10.255.1.4
+ repeat: 1
+ source: 10.255.2.14
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.14) - Destination: pod1-spine4 Loopback0 (IP: 10.255.1.4)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf5b
+ hosts:
+ - destination: 10.255.1.5
+ repeat: 1
+ source: 10.255.2.14
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.14) - Destination: pod1-leaf1a Loopback0 (IP: 10.255.1.5)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf5b
+ hosts:
+ - destination: 10.255.1.6
+ repeat: 1
+ source: 10.255.2.14
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.14) - Destination: pod1-leaf1b Loopback0 (IP: 10.255.1.6)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf5b
+ hosts:
+ - destination: 10.255.1.7
+ repeat: 1
+ source: 10.255.2.14
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.14) - Destination: pod1-leaf2a Loopback0 (IP: 10.255.1.7)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf5b
+ hosts:
+ - destination: 10.255.1.8
+ repeat: 1
+ source: 10.255.2.14
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.14) - Destination: pod1-leaf2b Loopback0 (IP: 10.255.1.8)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf5b
+ hosts:
+ - destination: 10.255.1.9
+ repeat: 1
+ source: 10.255.2.14
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.14) - Destination: pod1-leaf3a Loopback0 (IP: 10.255.1.9)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf5b
+ hosts:
+ - destination: 10.255.1.10
+ repeat: 1
+ source: 10.255.2.14
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.14) - Destination: pod1-leaf3b Loopback0 (IP: 10.255.1.10)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf5b
+ hosts:
+ - destination: 10.255.1.11
+ repeat: 1
+ source: 10.255.2.14
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.14) - Destination: pod1-leaf4a Loopback0 (IP: 10.255.1.11)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf5b
+ hosts:
+ - destination: 10.255.1.12
+ repeat: 1
+ source: 10.255.2.14
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.14) - Destination: pod1-leaf4b Loopback0 (IP: 10.255.1.12)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf5b
+ hosts:
+ - destination: 10.255.1.13
+ repeat: 1
+ source: 10.255.2.14
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.14) - Destination: pod1-leaf5a Loopback0 (IP: 10.255.1.13)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf5b
+ hosts:
+ - destination: 10.255.1.14
+ repeat: 1
+ source: 10.255.2.14
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.14) - Destination: pod1-leaf5b Loopback0 (IP: 10.255.1.14)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf5b
+ hosts:
+ - destination: 10.255.1.15
+ repeat: 1
+ source: 10.255.2.14
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.14) - Destination: pod1-leaf6a Loopback0 (IP: 10.255.1.15)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf5b
+ hosts:
+ - destination: 10.255.1.16
+ repeat: 1
+ source: 10.255.2.14
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.14) - Destination: pod1-leaf6b Loopback0 (IP: 10.255.1.16)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf5b
+ hosts:
+ - destination: 10.255.1.17
+ repeat: 1
+ source: 10.255.2.14
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.14) - Destination: pod1-leaf7a Loopback0 (IP: 10.255.1.17)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf5b
+ hosts:
+ - destination: 10.255.1.18
+ repeat: 1
+ source: 10.255.2.14
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.14) - Destination: pod1-leaf7b Loopback0 (IP: 10.255.1.18)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf5b
+ hosts:
+ - destination: 10.255.1.19
+ repeat: 1
+ source: 10.255.2.14
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.14) - Destination: pod1-leaf8a Loopback0 (IP: 10.255.1.19)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf5b
+ hosts:
+ - destination: 10.255.1.20
+ repeat: 1
+ source: 10.255.2.14
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.14) - Destination: pod1-leaf8b Loopback0 (IP: 10.255.1.20)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf5b
+ hosts:
+ - destination: 10.255.1.21
+ repeat: 1
+ source: 10.255.2.14
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.14) - Destination: pod1-leaf9a Loopback0 (IP: 10.255.1.21)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf5b
+ hosts:
+ - destination: 10.255.1.22
+ repeat: 1
+ source: 10.255.2.14
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.14) - Destination: pod1-leaf9b Loopback0 (IP: 10.255.1.22)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf5b
+ hosts:
+ - destination: 10.255.1.23
+ repeat: 1
+ source: 10.255.2.14
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.14) - Destination: pod1-leaf10a Loopback0 (IP: 10.255.1.23)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf5b
+ hosts:
+ - destination: 10.255.1.24
+ repeat: 1
+ source: 10.255.2.14
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.14) - Destination: pod1-leaf10b Loopback0 (IP: 10.255.1.24)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf5b
+ hosts:
+ - destination: 10.255.2.1
+ repeat: 1
+ source: 10.255.2.14
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.14) - Destination: pod2-spine1 Loopback0 (IP: 10.255.2.1)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf5b
+ hosts:
+ - destination: 10.255.2.2
+ repeat: 1
+ source: 10.255.2.14
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.14) - Destination: pod2-spine2 Loopback0 (IP: 10.255.2.2)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf5b
+ hosts:
+ - destination: 10.255.2.3
+ repeat: 1
+ source: 10.255.2.14
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.14) - Destination: pod2-spine3 Loopback0 (IP: 10.255.2.3)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf5b
+ hosts:
+ - destination: 10.255.2.4
+ repeat: 1
+ source: 10.255.2.14
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.14) - Destination: pod2-spine4 Loopback0 (IP: 10.255.2.4)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf5b
+ hosts:
+ - destination: 10.255.2.5
+ repeat: 1
+ source: 10.255.2.14
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.14) - Destination: pod2-leaf1a Loopback0 (IP: 10.255.2.5)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf5b
+ hosts:
+ - destination: 10.255.2.6
+ repeat: 1
+ source: 10.255.2.14
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.14) - Destination: pod2-leaf1b Loopback0 (IP: 10.255.2.6)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf5b
+ hosts:
+ - destination: 10.255.2.7
+ repeat: 1
+ source: 10.255.2.14
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.14) - Destination: pod2-leaf2a Loopback0 (IP: 10.255.2.7)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf5b
+ hosts:
+ - destination: 10.255.2.8
+ repeat: 1
+ source: 10.255.2.14
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.14) - Destination: pod2-leaf2b Loopback0 (IP: 10.255.2.8)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf5b
+ hosts:
+ - destination: 10.255.2.9
+ repeat: 1
+ source: 10.255.2.14
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.14) - Destination: pod2-leaf3a Loopback0 (IP: 10.255.2.9)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf5b
+ hosts:
+ - destination: 10.255.2.10
+ repeat: 1
+ source: 10.255.2.14
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.14) - Destination: pod2-leaf3b Loopback0 (IP: 10.255.2.10)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf5b
+ hosts:
+ - destination: 10.255.2.11
+ repeat: 1
+ source: 10.255.2.14
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.14) - Destination: pod2-leaf4a Loopback0 (IP: 10.255.2.11)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf5b
+ hosts:
+ - destination: 10.255.2.12
+ repeat: 1
+ source: 10.255.2.14
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.14) - Destination: pod2-leaf4b Loopback0 (IP: 10.255.2.12)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf5b
+ hosts:
+ - destination: 10.255.2.13
+ repeat: 1
+ source: 10.255.2.14
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.14) - Destination: pod2-leaf5a Loopback0 (IP: 10.255.2.13)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf5b
+ hosts:
+ - destination: 10.255.2.14
+ repeat: 1
+ source: 10.255.2.14
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.14) - Destination: pod2-leaf5b Loopback0 (IP: 10.255.2.14)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf5b
+ hosts:
+ - destination: 10.255.2.15
+ repeat: 1
+ source: 10.255.2.14
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.14) - Destination: pod2-leaf6a Loopback0 (IP: 10.255.2.15)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf5b
+ hosts:
+ - destination: 10.255.2.16
+ repeat: 1
+ source: 10.255.2.14
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.14) - Destination: pod2-leaf6b Loopback0 (IP: 10.255.2.16)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf5b
+ hosts:
+ - destination: 10.255.2.17
+ repeat: 1
+ source: 10.255.2.14
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.14) - Destination: pod2-leaf7a Loopback0 (IP: 10.255.2.17)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf5b
+ hosts:
+ - destination: 10.255.2.18
+ repeat: 1
+ source: 10.255.2.14
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.14) - Destination: pod2-leaf7b Loopback0 (IP: 10.255.2.18)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf5b
+ hosts:
+ - destination: 10.255.2.19
+ repeat: 1
+ source: 10.255.2.14
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.14) - Destination: pod2-leaf8a Loopback0 (IP: 10.255.2.19)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf5b
+ hosts:
+ - destination: 10.255.2.20
+ repeat: 1
+ source: 10.255.2.14
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.14) - Destination: pod2-leaf8b Loopback0 (IP: 10.255.2.20)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf5b
+ hosts:
+ - destination: 10.255.2.21
+ repeat: 1
+ source: 10.255.2.14
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.14) - Destination: pod2-leaf9a Loopback0 (IP: 10.255.2.21)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf5b
+ hosts:
+ - destination: 10.255.2.22
+ repeat: 1
+ source: 10.255.2.14
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.14) - Destination: pod2-leaf9b Loopback0 (IP: 10.255.2.22)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf5b
+ hosts:
+ - destination: 10.255.2.23
+ repeat: 1
+ source: 10.255.2.14
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.14) - Destination: pod2-leaf10a Loopback0 (IP: 10.255.2.23)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf5b
+ hosts:
+ - destination: 10.255.2.24
+ repeat: 1
+ source: 10.255.2.14
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.14) - Destination: pod2-leaf10b Loopback0 (IP: 10.255.2.24)'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-leaf2b
+ neighbors:
+ - neighbor_device: pod2-leaf2a
+ neighbor_port: Ethernet53/1
+ port: Ethernet53/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet53/1 - Remote: pod2-leaf2a Ethernet53/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-leaf2b
+ neighbors:
+ - neighbor_device: pod2-leaf2a
+ neighbor_port: Ethernet54/1
+ port: Ethernet54/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet54/1 - Remote: pod2-leaf2a Ethernet54/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-leaf2b
+ neighbors:
+ - neighbor_device: pod2-spine1
+ neighbor_port: Ethernet4/1
+ port: Ethernet1/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet1/1 - Remote: pod2-spine1 Ethernet4/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-leaf2b
+ neighbors:
+ - neighbor_device: pod2-spine2
+ neighbor_port: Ethernet4/1
+ port: Ethernet2/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet2/1 - Remote: pod2-spine2 Ethernet4/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-leaf2b
+ neighbors:
+ - neighbor_device: pod2-spine3
+ neighbor_port: Ethernet4/1
+ port: Ethernet3/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet3/1 - Remote: pod2-spine3 Ethernet4/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-leaf2b
+ neighbors:
+ - neighbor_device: pod2-spine4
+ neighbor_port: Ethernet4/1
+ port: Ethernet4/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet4/1 - Remote: pod2-spine4 Ethernet4/1'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf2b
+ hosts:
+ - destination: 10.255.255.24
+ repeat: 1
+ source: 10.255.255.25
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet1/1 (IP: 10.255.255.25) - Destination: pod2-spine1 Ethernet4/1 (IP: 10.255.255.24)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf2b
+ hosts:
+ - destination: 10.255.255.26
+ repeat: 1
+ source: 10.255.255.27
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet2/1 (IP: 10.255.255.27) - Destination: pod2-spine2 Ethernet4/1 (IP: 10.255.255.26)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf2b
+ hosts:
+ - destination: 10.255.255.28
+ repeat: 1
+ source: 10.255.255.29
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet3/1 (IP: 10.255.255.29) - Destination: pod2-spine3 Ethernet4/1 (IP: 10.255.255.28)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf2b
+ hosts:
+ - destination: 10.255.255.30
+ repeat: 1
+ source: 10.255.255.31
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet4/1 (IP: 10.255.255.31) - Destination: pod2-spine4 Ethernet4/1 (IP: 10.255.255.30)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf2b
+ hosts:
+ - destination: 10.255.0.1
+ repeat: 1
+ source: 10.255.2.8
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.8) - Destination: super-spine1 Loopback0 (IP: 10.255.0.1)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf2b
+ hosts:
+ - destination: 10.255.0.2
+ repeat: 1
+ source: 10.255.2.8
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.8) - Destination: super-spine2 Loopback0 (IP: 10.255.0.2)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf2b
+ hosts:
+ - destination: 10.255.1.1
+ repeat: 1
+ source: 10.255.2.8
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.8) - Destination: pod1-spine1 Loopback0 (IP: 10.255.1.1)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf2b
+ hosts:
+ - destination: 10.255.1.2
+ repeat: 1
+ source: 10.255.2.8
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.8) - Destination: pod1-spine2 Loopback0 (IP: 10.255.1.2)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf2b
+ hosts:
+ - destination: 10.255.1.3
+ repeat: 1
+ source: 10.255.2.8
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.8) - Destination: pod1-spine3 Loopback0 (IP: 10.255.1.3)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf2b
+ hosts:
+ - destination: 10.255.1.4
+ repeat: 1
+ source: 10.255.2.8
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.8) - Destination: pod1-spine4 Loopback0 (IP: 10.255.1.4)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf2b
+ hosts:
+ - destination: 10.255.1.5
+ repeat: 1
+ source: 10.255.2.8
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.8) - Destination: pod1-leaf1a Loopback0 (IP: 10.255.1.5)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf2b
+ hosts:
+ - destination: 10.255.1.6
+ repeat: 1
+ source: 10.255.2.8
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.8) - Destination: pod1-leaf1b Loopback0 (IP: 10.255.1.6)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf2b
+ hosts:
+ - destination: 10.255.1.7
+ repeat: 1
+ source: 10.255.2.8
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.8) - Destination: pod1-leaf2a Loopback0 (IP: 10.255.1.7)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf2b
+ hosts:
+ - destination: 10.255.1.8
+ repeat: 1
+ source: 10.255.2.8
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.8) - Destination: pod1-leaf2b Loopback0 (IP: 10.255.1.8)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf2b
+ hosts:
+ - destination: 10.255.1.9
+ repeat: 1
+ source: 10.255.2.8
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.8) - Destination: pod1-leaf3a Loopback0 (IP: 10.255.1.9)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf2b
+ hosts:
+ - destination: 10.255.1.10
+ repeat: 1
+ source: 10.255.2.8
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.8) - Destination: pod1-leaf3b Loopback0 (IP: 10.255.1.10)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf2b
+ hosts:
+ - destination: 10.255.1.11
+ repeat: 1
+ source: 10.255.2.8
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.8) - Destination: pod1-leaf4a Loopback0 (IP: 10.255.1.11)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf2b
+ hosts:
+ - destination: 10.255.1.12
+ repeat: 1
+ source: 10.255.2.8
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.8) - Destination: pod1-leaf4b Loopback0 (IP: 10.255.1.12)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf2b
+ hosts:
+ - destination: 10.255.1.13
+ repeat: 1
+ source: 10.255.2.8
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.8) - Destination: pod1-leaf5a Loopback0 (IP: 10.255.1.13)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf2b
+ hosts:
+ - destination: 10.255.1.14
+ repeat: 1
+ source: 10.255.2.8
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.8) - Destination: pod1-leaf5b Loopback0 (IP: 10.255.1.14)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf2b
+ hosts:
+ - destination: 10.255.1.15
+ repeat: 1
+ source: 10.255.2.8
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.8) - Destination: pod1-leaf6a Loopback0 (IP: 10.255.1.15)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf2b
+ hosts:
+ - destination: 10.255.1.16
+ repeat: 1
+ source: 10.255.2.8
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.8) - Destination: pod1-leaf6b Loopback0 (IP: 10.255.1.16)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf2b
+ hosts:
+ - destination: 10.255.1.17
+ repeat: 1
+ source: 10.255.2.8
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.8) - Destination: pod1-leaf7a Loopback0 (IP: 10.255.1.17)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf2b
+ hosts:
+ - destination: 10.255.1.18
+ repeat: 1
+ source: 10.255.2.8
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.8) - Destination: pod1-leaf7b Loopback0 (IP: 10.255.1.18)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf2b
+ hosts:
+ - destination: 10.255.1.19
+ repeat: 1
+ source: 10.255.2.8
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.8) - Destination: pod1-leaf8a Loopback0 (IP: 10.255.1.19)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf2b
+ hosts:
+ - destination: 10.255.1.20
+ repeat: 1
+ source: 10.255.2.8
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.8) - Destination: pod1-leaf8b Loopback0 (IP: 10.255.1.20)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf2b
+ hosts:
+ - destination: 10.255.1.21
+ repeat: 1
+ source: 10.255.2.8
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.8) - Destination: pod1-leaf9a Loopback0 (IP: 10.255.1.21)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf2b
+ hosts:
+ - destination: 10.255.1.22
+ repeat: 1
+ source: 10.255.2.8
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.8) - Destination: pod1-leaf9b Loopback0 (IP: 10.255.1.22)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf2b
+ hosts:
+ - destination: 10.255.1.23
+ repeat: 1
+ source: 10.255.2.8
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.8) - Destination: pod1-leaf10a Loopback0 (IP: 10.255.1.23)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf2b
+ hosts:
+ - destination: 10.255.1.24
+ repeat: 1
+ source: 10.255.2.8
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.8) - Destination: pod1-leaf10b Loopback0 (IP: 10.255.1.24)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf2b
+ hosts:
+ - destination: 10.255.2.1
+ repeat: 1
+ source: 10.255.2.8
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.8) - Destination: pod2-spine1 Loopback0 (IP: 10.255.2.1)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf2b
+ hosts:
+ - destination: 10.255.2.2
+ repeat: 1
+ source: 10.255.2.8
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.8) - Destination: pod2-spine2 Loopback0 (IP: 10.255.2.2)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf2b
+ hosts:
+ - destination: 10.255.2.3
+ repeat: 1
+ source: 10.255.2.8
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.8) - Destination: pod2-spine3 Loopback0 (IP: 10.255.2.3)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf2b
+ hosts:
+ - destination: 10.255.2.4
+ repeat: 1
+ source: 10.255.2.8
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.8) - Destination: pod2-spine4 Loopback0 (IP: 10.255.2.4)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf2b
+ hosts:
+ - destination: 10.255.2.5
+ repeat: 1
+ source: 10.255.2.8
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.8) - Destination: pod2-leaf1a Loopback0 (IP: 10.255.2.5)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf2b
+ hosts:
+ - destination: 10.255.2.6
+ repeat: 1
+ source: 10.255.2.8
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.8) - Destination: pod2-leaf1b Loopback0 (IP: 10.255.2.6)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf2b
+ hosts:
+ - destination: 10.255.2.7
+ repeat: 1
+ source: 10.255.2.8
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.8) - Destination: pod2-leaf2a Loopback0 (IP: 10.255.2.7)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf2b
+ hosts:
+ - destination: 10.255.2.8
+ repeat: 1
+ source: 10.255.2.8
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.8) - Destination: pod2-leaf2b Loopback0 (IP: 10.255.2.8)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf2b
+ hosts:
+ - destination: 10.255.2.9
+ repeat: 1
+ source: 10.255.2.8
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.8) - Destination: pod2-leaf3a Loopback0 (IP: 10.255.2.9)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf2b
+ hosts:
+ - destination: 10.255.2.10
+ repeat: 1
+ source: 10.255.2.8
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.8) - Destination: pod2-leaf3b Loopback0 (IP: 10.255.2.10)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf2b
+ hosts:
+ - destination: 10.255.2.11
+ repeat: 1
+ source: 10.255.2.8
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.8) - Destination: pod2-leaf4a Loopback0 (IP: 10.255.2.11)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf2b
+ hosts:
+ - destination: 10.255.2.12
+ repeat: 1
+ source: 10.255.2.8
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.8) - Destination: pod2-leaf4b Loopback0 (IP: 10.255.2.12)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf2b
+ hosts:
+ - destination: 10.255.2.13
+ repeat: 1
+ source: 10.255.2.8
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.8) - Destination: pod2-leaf5a Loopback0 (IP: 10.255.2.13)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf2b
+ hosts:
+ - destination: 10.255.2.14
+ repeat: 1
+ source: 10.255.2.8
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.8) - Destination: pod2-leaf5b Loopback0 (IP: 10.255.2.14)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf2b
+ hosts:
+ - destination: 10.255.2.15
+ repeat: 1
+ source: 10.255.2.8
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.8) - Destination: pod2-leaf6a Loopback0 (IP: 10.255.2.15)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf2b
+ hosts:
+ - destination: 10.255.2.16
+ repeat: 1
+ source: 10.255.2.8
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.8) - Destination: pod2-leaf6b Loopback0 (IP: 10.255.2.16)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf2b
+ hosts:
+ - destination: 10.255.2.17
+ repeat: 1
+ source: 10.255.2.8
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.8) - Destination: pod2-leaf7a Loopback0 (IP: 10.255.2.17)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf2b
+ hosts:
+ - destination: 10.255.2.18
+ repeat: 1
+ source: 10.255.2.8
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.8) - Destination: pod2-leaf7b Loopback0 (IP: 10.255.2.18)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf2b
+ hosts:
+ - destination: 10.255.2.19
+ repeat: 1
+ source: 10.255.2.8
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.8) - Destination: pod2-leaf8a Loopback0 (IP: 10.255.2.19)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf2b
+ hosts:
+ - destination: 10.255.2.20
+ repeat: 1
+ source: 10.255.2.8
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.8) - Destination: pod2-leaf8b Loopback0 (IP: 10.255.2.20)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf2b
+ hosts:
+ - destination: 10.255.2.21
+ repeat: 1
+ source: 10.255.2.8
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.8) - Destination: pod2-leaf9a Loopback0 (IP: 10.255.2.21)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf2b
+ hosts:
+ - destination: 10.255.2.22
+ repeat: 1
+ source: 10.255.2.8
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.8) - Destination: pod2-leaf9b Loopback0 (IP: 10.255.2.22)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf2b
+ hosts:
+ - destination: 10.255.2.23
+ repeat: 1
+ source: 10.255.2.8
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.8) - Destination: pod2-leaf10a Loopback0 (IP: 10.255.2.23)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf2b
+ hosts:
+ - destination: 10.255.2.24
+ repeat: 1
+ source: 10.255.2.8
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.8) - Destination: pod2-leaf10b Loopback0 (IP: 10.255.2.24)'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-leaf8a
+ neighbors:
+ - neighbor_device: pod2-leaf8b
+ neighbor_port: Ethernet53/1
+ port: Ethernet53/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet53/1 - Remote: pod2-leaf8b Ethernet53/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-leaf8a
+ neighbors:
+ - neighbor_device: pod2-leaf8b
+ neighbor_port: Ethernet54/1
+ port: Ethernet54/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet54/1 - Remote: pod2-leaf8b Ethernet54/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-leaf8a
+ neighbors:
+ - neighbor_device: pod2-spine1
+ neighbor_port: Ethernet15/1
+ port: Ethernet1/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet1/1 - Remote: pod2-spine1 Ethernet15/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-leaf8a
+ neighbors:
+ - neighbor_device: pod2-spine2
+ neighbor_port: Ethernet15/1
+ port: Ethernet2/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet2/1 - Remote: pod2-spine2 Ethernet15/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-leaf8a
+ neighbors:
+ - neighbor_device: pod2-spine3
+ neighbor_port: Ethernet15/1
+ port: Ethernet3/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet3/1 - Remote: pod2-spine3 Ethernet15/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-leaf8a
+ neighbors:
+ - neighbor_device: pod2-spine4
+ neighbor_port: Ethernet15/1
+ port: Ethernet4/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet4/1 - Remote: pod2-spine4 Ethernet15/1'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf8a
+ hosts:
+ - destination: 10.255.255.112
+ repeat: 1
+ source: 10.255.255.113
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet1/1 (IP: 10.255.255.113) - Destination: pod2-spine1 Ethernet15/1 (IP: 10.255.255.112)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf8a
+ hosts:
+ - destination: 10.255.255.114
+ repeat: 1
+ source: 10.255.255.115
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet2/1 (IP: 10.255.255.115) - Destination: pod2-spine2 Ethernet15/1 (IP: 10.255.255.114)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf8a
+ hosts:
+ - destination: 10.255.255.116
+ repeat: 1
+ source: 10.255.255.117
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet3/1 (IP: 10.255.255.117) - Destination: pod2-spine3 Ethernet15/1 (IP: 10.255.255.116)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf8a
+ hosts:
+ - destination: 10.255.255.118
+ repeat: 1
+ source: 10.255.255.119
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet4/1 (IP: 10.255.255.119) - Destination: pod2-spine4 Ethernet15/1 (IP: 10.255.255.118)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf8a
+ hosts:
+ - destination: 10.255.0.1
+ repeat: 1
+ source: 10.255.2.19
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.19) - Destination: super-spine1 Loopback0 (IP: 10.255.0.1)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf8a
+ hosts:
+ - destination: 10.255.0.2
+ repeat: 1
+ source: 10.255.2.19
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.19) - Destination: super-spine2 Loopback0 (IP: 10.255.0.2)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf8a
+ hosts:
+ - destination: 10.255.1.1
+ repeat: 1
+ source: 10.255.2.19
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.19) - Destination: pod1-spine1 Loopback0 (IP: 10.255.1.1)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf8a
+ hosts:
+ - destination: 10.255.1.2
+ repeat: 1
+ source: 10.255.2.19
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.19) - Destination: pod1-spine2 Loopback0 (IP: 10.255.1.2)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf8a
+ hosts:
+ - destination: 10.255.1.3
+ repeat: 1
+ source: 10.255.2.19
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.19) - Destination: pod1-spine3 Loopback0 (IP: 10.255.1.3)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf8a
+ hosts:
+ - destination: 10.255.1.4
+ repeat: 1
+ source: 10.255.2.19
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.19) - Destination: pod1-spine4 Loopback0 (IP: 10.255.1.4)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf8a
+ hosts:
+ - destination: 10.255.1.5
+ repeat: 1
+ source: 10.255.2.19
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.19) - Destination: pod1-leaf1a Loopback0 (IP: 10.255.1.5)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf8a
+ hosts:
+ - destination: 10.255.1.6
+ repeat: 1
+ source: 10.255.2.19
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.19) - Destination: pod1-leaf1b Loopback0 (IP: 10.255.1.6)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf8a
+ hosts:
+ - destination: 10.255.1.7
+ repeat: 1
+ source: 10.255.2.19
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.19) - Destination: pod1-leaf2a Loopback0 (IP: 10.255.1.7)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf8a
+ hosts:
+ - destination: 10.255.1.8
+ repeat: 1
+ source: 10.255.2.19
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.19) - Destination: pod1-leaf2b Loopback0 (IP: 10.255.1.8)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf8a
+ hosts:
+ - destination: 10.255.1.9
+ repeat: 1
+ source: 10.255.2.19
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.19) - Destination: pod1-leaf3a Loopback0 (IP: 10.255.1.9)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf8a
+ hosts:
+ - destination: 10.255.1.10
+ repeat: 1
+ source: 10.255.2.19
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.19) - Destination: pod1-leaf3b Loopback0 (IP: 10.255.1.10)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf8a
+ hosts:
+ - destination: 10.255.1.11
+ repeat: 1
+ source: 10.255.2.19
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.19) - Destination: pod1-leaf4a Loopback0 (IP: 10.255.1.11)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf8a
+ hosts:
+ - destination: 10.255.1.12
+ repeat: 1
+ source: 10.255.2.19
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.19) - Destination: pod1-leaf4b Loopback0 (IP: 10.255.1.12)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf8a
+ hosts:
+ - destination: 10.255.1.13
+ repeat: 1
+ source: 10.255.2.19
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.19) - Destination: pod1-leaf5a Loopback0 (IP: 10.255.1.13)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf8a
+ hosts:
+ - destination: 10.255.1.14
+ repeat: 1
+ source: 10.255.2.19
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.19) - Destination: pod1-leaf5b Loopback0 (IP: 10.255.1.14)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf8a
+ hosts:
+ - destination: 10.255.1.15
+ repeat: 1
+ source: 10.255.2.19
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.19) - Destination: pod1-leaf6a Loopback0 (IP: 10.255.1.15)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf8a
+ hosts:
+ - destination: 10.255.1.16
+ repeat: 1
+ source: 10.255.2.19
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.19) - Destination: pod1-leaf6b Loopback0 (IP: 10.255.1.16)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf8a
+ hosts:
+ - destination: 10.255.1.17
+ repeat: 1
+ source: 10.255.2.19
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.19) - Destination: pod1-leaf7a Loopback0 (IP: 10.255.1.17)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf8a
+ hosts:
+ - destination: 10.255.1.18
+ repeat: 1
+ source: 10.255.2.19
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.19) - Destination: pod1-leaf7b Loopback0 (IP: 10.255.1.18)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf8a
+ hosts:
+ - destination: 10.255.1.19
+ repeat: 1
+ source: 10.255.2.19
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.19) - Destination: pod1-leaf8a Loopback0 (IP: 10.255.1.19)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf8a
+ hosts:
+ - destination: 10.255.1.20
+ repeat: 1
+ source: 10.255.2.19
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.19) - Destination: pod1-leaf8b Loopback0 (IP: 10.255.1.20)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf8a
+ hosts:
+ - destination: 10.255.1.21
+ repeat: 1
+ source: 10.255.2.19
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.19) - Destination: pod1-leaf9a Loopback0 (IP: 10.255.1.21)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf8a
+ hosts:
+ - destination: 10.255.1.22
+ repeat: 1
+ source: 10.255.2.19
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.19) - Destination: pod1-leaf9b Loopback0 (IP: 10.255.1.22)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf8a
+ hosts:
+ - destination: 10.255.1.23
+ repeat: 1
+ source: 10.255.2.19
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.19) - Destination: pod1-leaf10a Loopback0 (IP: 10.255.1.23)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf8a
+ hosts:
+ - destination: 10.255.1.24
+ repeat: 1
+ source: 10.255.2.19
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.19) - Destination: pod1-leaf10b Loopback0 (IP: 10.255.1.24)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf8a
+ hosts:
+ - destination: 10.255.2.1
+ repeat: 1
+ source: 10.255.2.19
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.19) - Destination: pod2-spine1 Loopback0 (IP: 10.255.2.1)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf8a
+ hosts:
+ - destination: 10.255.2.2
+ repeat: 1
+ source: 10.255.2.19
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.19) - Destination: pod2-spine2 Loopback0 (IP: 10.255.2.2)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf8a
+ hosts:
+ - destination: 10.255.2.3
+ repeat: 1
+ source: 10.255.2.19
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.19) - Destination: pod2-spine3 Loopback0 (IP: 10.255.2.3)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf8a
+ hosts:
+ - destination: 10.255.2.4
+ repeat: 1
+ source: 10.255.2.19
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.19) - Destination: pod2-spine4 Loopback0 (IP: 10.255.2.4)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf8a
+ hosts:
+ - destination: 10.255.2.5
+ repeat: 1
+ source: 10.255.2.19
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.19) - Destination: pod2-leaf1a Loopback0 (IP: 10.255.2.5)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf8a
+ hosts:
+ - destination: 10.255.2.6
+ repeat: 1
+ source: 10.255.2.19
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.19) - Destination: pod2-leaf1b Loopback0 (IP: 10.255.2.6)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf8a
+ hosts:
+ - destination: 10.255.2.7
+ repeat: 1
+ source: 10.255.2.19
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.19) - Destination: pod2-leaf2a Loopback0 (IP: 10.255.2.7)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf8a
+ hosts:
+ - destination: 10.255.2.8
+ repeat: 1
+ source: 10.255.2.19
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.19) - Destination: pod2-leaf2b Loopback0 (IP: 10.255.2.8)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf8a
+ hosts:
+ - destination: 10.255.2.9
+ repeat: 1
+ source: 10.255.2.19
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.19) - Destination: pod2-leaf3a Loopback0 (IP: 10.255.2.9)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf8a
+ hosts:
+ - destination: 10.255.2.10
+ repeat: 1
+ source: 10.255.2.19
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.19) - Destination: pod2-leaf3b Loopback0 (IP: 10.255.2.10)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf8a
+ hosts:
+ - destination: 10.255.2.11
+ repeat: 1
+ source: 10.255.2.19
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.19) - Destination: pod2-leaf4a Loopback0 (IP: 10.255.2.11)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf8a
+ hosts:
+ - destination: 10.255.2.12
+ repeat: 1
+ source: 10.255.2.19
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.19) - Destination: pod2-leaf4b Loopback0 (IP: 10.255.2.12)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf8a
+ hosts:
+ - destination: 10.255.2.13
+ repeat: 1
+ source: 10.255.2.19
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.19) - Destination: pod2-leaf5a Loopback0 (IP: 10.255.2.13)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf8a
+ hosts:
+ - destination: 10.255.2.14
+ repeat: 1
+ source: 10.255.2.19
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.19) - Destination: pod2-leaf5b Loopback0 (IP: 10.255.2.14)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf8a
+ hosts:
+ - destination: 10.255.2.15
+ repeat: 1
+ source: 10.255.2.19
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.19) - Destination: pod2-leaf6a Loopback0 (IP: 10.255.2.15)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf8a
+ hosts:
+ - destination: 10.255.2.16
+ repeat: 1
+ source: 10.255.2.19
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.19) - Destination: pod2-leaf6b Loopback0 (IP: 10.255.2.16)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf8a
+ hosts:
+ - destination: 10.255.2.17
+ repeat: 1
+ source: 10.255.2.19
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.19) - Destination: pod2-leaf7a Loopback0 (IP: 10.255.2.17)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf8a
+ hosts:
+ - destination: 10.255.2.18
+ repeat: 1
+ source: 10.255.2.19
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.19) - Destination: pod2-leaf7b Loopback0 (IP: 10.255.2.18)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf8a
+ hosts:
+ - destination: 10.255.2.19
+ repeat: 1
+ source: 10.255.2.19
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.19) - Destination: pod2-leaf8a Loopback0 (IP: 10.255.2.19)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf8a
+ hosts:
+ - destination: 10.255.2.20
+ repeat: 1
+ source: 10.255.2.19
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.19) - Destination: pod2-leaf8b Loopback0 (IP: 10.255.2.20)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf8a
+ hosts:
+ - destination: 10.255.2.21
+ repeat: 1
+ source: 10.255.2.19
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.19) - Destination: pod2-leaf9a Loopback0 (IP: 10.255.2.21)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf8a
+ hosts:
+ - destination: 10.255.2.22
+ repeat: 1
+ source: 10.255.2.19
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.19) - Destination: pod2-leaf9b Loopback0 (IP: 10.255.2.22)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf8a
+ hosts:
+ - destination: 10.255.2.23
+ repeat: 1
+ source: 10.255.2.19
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.19) - Destination: pod2-leaf10a Loopback0 (IP: 10.255.2.23)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf8a
+ hosts:
+ - destination: 10.255.2.24
+ repeat: 1
+ source: 10.255.2.19
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.19) - Destination: pod2-leaf10b Loopback0 (IP: 10.255.2.24)'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-leaf2b
+ neighbors:
+ - neighbor_device: pod1-leaf2a
+ neighbor_port: Ethernet53/1
+ port: Ethernet53/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet53/1 - Remote: pod1-leaf2a Ethernet53/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-leaf2b
+ neighbors:
+ - neighbor_device: pod1-leaf2a
+ neighbor_port: Ethernet54/1
+ port: Ethernet54/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet54/1 - Remote: pod1-leaf2a Ethernet54/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-leaf2b
+ neighbors:
+ - neighbor_device: pod1-spine1
+ neighbor_port: Ethernet4/1
+ port: Ethernet1/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet1/1 - Remote: pod1-spine1 Ethernet4/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-leaf2b
+ neighbors:
+ - neighbor_device: pod1-spine2
+ neighbor_port: Ethernet4/1
+ port: Ethernet2/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet2/1 - Remote: pod1-spine2 Ethernet4/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-leaf2b
+ neighbors:
+ - neighbor_device: pod1-spine3
+ neighbor_port: Ethernet4/1
+ port: Ethernet3/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet3/1 - Remote: pod1-spine3 Ethernet4/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-leaf2b
+ neighbors:
+ - neighbor_device: pod1-spine4
+ neighbor_port: Ethernet4/1
+ port: Ethernet4/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet4/1 - Remote: pod1-spine4 Ethernet4/1'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf2b
+ hosts:
+ - destination: 10.255.255.24
+ repeat: 1
+ source: 10.255.255.25
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet1/1 (IP: 10.255.255.25) - Destination: pod1-spine1 Ethernet4/1 (IP: 10.255.255.24)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf2b
+ hosts:
+ - destination: 10.255.255.26
+ repeat: 1
+ source: 10.255.255.27
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet2/1 (IP: 10.255.255.27) - Destination: pod1-spine2 Ethernet4/1 (IP: 10.255.255.26)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf2b
+ hosts:
+ - destination: 10.255.255.28
+ repeat: 1
+ source: 10.255.255.29
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet3/1 (IP: 10.255.255.29) - Destination: pod1-spine3 Ethernet4/1 (IP: 10.255.255.28)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf2b
+ hosts:
+ - destination: 10.255.255.30
+ repeat: 1
+ source: 10.255.255.31
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet4/1 (IP: 10.255.255.31) - Destination: pod1-spine4 Ethernet4/1 (IP: 10.255.255.30)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf2b
+ hosts:
+ - destination: 10.255.0.1
+ repeat: 1
+ source: 10.255.1.8
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.8) - Destination: super-spine1 Loopback0 (IP: 10.255.0.1)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf2b
+ hosts:
+ - destination: 10.255.0.2
+ repeat: 1
+ source: 10.255.1.8
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.8) - Destination: super-spine2 Loopback0 (IP: 10.255.0.2)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf2b
+ hosts:
+ - destination: 10.255.1.1
+ repeat: 1
+ source: 10.255.1.8
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.8) - Destination: pod1-spine1 Loopback0 (IP: 10.255.1.1)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf2b
+ hosts:
+ - destination: 10.255.1.2
+ repeat: 1
+ source: 10.255.1.8
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.8) - Destination: pod1-spine2 Loopback0 (IP: 10.255.1.2)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf2b
+ hosts:
+ - destination: 10.255.1.3
+ repeat: 1
+ source: 10.255.1.8
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.8) - Destination: pod1-spine3 Loopback0 (IP: 10.255.1.3)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf2b
+ hosts:
+ - destination: 10.255.1.4
+ repeat: 1
+ source: 10.255.1.8
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.8) - Destination: pod1-spine4 Loopback0 (IP: 10.255.1.4)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf2b
+ hosts:
+ - destination: 10.255.1.5
+ repeat: 1
+ source: 10.255.1.8
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.8) - Destination: pod1-leaf1a Loopback0 (IP: 10.255.1.5)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf2b
+ hosts:
+ - destination: 10.255.1.6
+ repeat: 1
+ source: 10.255.1.8
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.8) - Destination: pod1-leaf1b Loopback0 (IP: 10.255.1.6)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf2b
+ hosts:
+ - destination: 10.255.1.7
+ repeat: 1
+ source: 10.255.1.8
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.8) - Destination: pod1-leaf2a Loopback0 (IP: 10.255.1.7)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf2b
+ hosts:
+ - destination: 10.255.1.8
+ repeat: 1
+ source: 10.255.1.8
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.8) - Destination: pod1-leaf2b Loopback0 (IP: 10.255.1.8)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf2b
+ hosts:
+ - destination: 10.255.1.9
+ repeat: 1
+ source: 10.255.1.8
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.8) - Destination: pod1-leaf3a Loopback0 (IP: 10.255.1.9)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf2b
+ hosts:
+ - destination: 10.255.1.10
+ repeat: 1
+ source: 10.255.1.8
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.8) - Destination: pod1-leaf3b Loopback0 (IP: 10.255.1.10)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf2b
+ hosts:
+ - destination: 10.255.1.11
+ repeat: 1
+ source: 10.255.1.8
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.8) - Destination: pod1-leaf4a Loopback0 (IP: 10.255.1.11)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf2b
+ hosts:
+ - destination: 10.255.1.12
+ repeat: 1
+ source: 10.255.1.8
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.8) - Destination: pod1-leaf4b Loopback0 (IP: 10.255.1.12)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf2b
+ hosts:
+ - destination: 10.255.1.13
+ repeat: 1
+ source: 10.255.1.8
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.8) - Destination: pod1-leaf5a Loopback0 (IP: 10.255.1.13)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf2b
+ hosts:
+ - destination: 10.255.1.14
+ repeat: 1
+ source: 10.255.1.8
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.8) - Destination: pod1-leaf5b Loopback0 (IP: 10.255.1.14)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf2b
+ hosts:
+ - destination: 10.255.1.15
+ repeat: 1
+ source: 10.255.1.8
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.8) - Destination: pod1-leaf6a Loopback0 (IP: 10.255.1.15)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf2b
+ hosts:
+ - destination: 10.255.1.16
+ repeat: 1
+ source: 10.255.1.8
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.8) - Destination: pod1-leaf6b Loopback0 (IP: 10.255.1.16)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf2b
+ hosts:
+ - destination: 10.255.1.17
+ repeat: 1
+ source: 10.255.1.8
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.8) - Destination: pod1-leaf7a Loopback0 (IP: 10.255.1.17)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf2b
+ hosts:
+ - destination: 10.255.1.18
+ repeat: 1
+ source: 10.255.1.8
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.8) - Destination: pod1-leaf7b Loopback0 (IP: 10.255.1.18)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf2b
+ hosts:
+ - destination: 10.255.1.19
+ repeat: 1
+ source: 10.255.1.8
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.8) - Destination: pod1-leaf8a Loopback0 (IP: 10.255.1.19)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf2b
+ hosts:
+ - destination: 10.255.1.20
+ repeat: 1
+ source: 10.255.1.8
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.8) - Destination: pod1-leaf8b Loopback0 (IP: 10.255.1.20)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf2b
+ hosts:
+ - destination: 10.255.1.21
+ repeat: 1
+ source: 10.255.1.8
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.8) - Destination: pod1-leaf9a Loopback0 (IP: 10.255.1.21)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf2b
+ hosts:
+ - destination: 10.255.1.22
+ repeat: 1
+ source: 10.255.1.8
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.8) - Destination: pod1-leaf9b Loopback0 (IP: 10.255.1.22)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf2b
+ hosts:
+ - destination: 10.255.1.23
+ repeat: 1
+ source: 10.255.1.8
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.8) - Destination: pod1-leaf10a Loopback0 (IP: 10.255.1.23)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf2b
+ hosts:
+ - destination: 10.255.1.24
+ repeat: 1
+ source: 10.255.1.8
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.8) - Destination: pod1-leaf10b Loopback0 (IP: 10.255.1.24)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf2b
+ hosts:
+ - destination: 10.255.2.1
+ repeat: 1
+ source: 10.255.1.8
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.8) - Destination: pod2-spine1 Loopback0 (IP: 10.255.2.1)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf2b
+ hosts:
+ - destination: 10.255.2.2
+ repeat: 1
+ source: 10.255.1.8
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.8) - Destination: pod2-spine2 Loopback0 (IP: 10.255.2.2)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf2b
+ hosts:
+ - destination: 10.255.2.3
+ repeat: 1
+ source: 10.255.1.8
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.8) - Destination: pod2-spine3 Loopback0 (IP: 10.255.2.3)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf2b
+ hosts:
+ - destination: 10.255.2.4
+ repeat: 1
+ source: 10.255.1.8
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.8) - Destination: pod2-spine4 Loopback0 (IP: 10.255.2.4)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf2b
+ hosts:
+ - destination: 10.255.2.5
+ repeat: 1
+ source: 10.255.1.8
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.8) - Destination: pod2-leaf1a Loopback0 (IP: 10.255.2.5)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf2b
+ hosts:
+ - destination: 10.255.2.6
+ repeat: 1
+ source: 10.255.1.8
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.8) - Destination: pod2-leaf1b Loopback0 (IP: 10.255.2.6)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf2b
+ hosts:
+ - destination: 10.255.2.7
+ repeat: 1
+ source: 10.255.1.8
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.8) - Destination: pod2-leaf2a Loopback0 (IP: 10.255.2.7)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf2b
+ hosts:
+ - destination: 10.255.2.8
+ repeat: 1
+ source: 10.255.1.8
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.8) - Destination: pod2-leaf2b Loopback0 (IP: 10.255.2.8)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf2b
+ hosts:
+ - destination: 10.255.2.9
+ repeat: 1
+ source: 10.255.1.8
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.8) - Destination: pod2-leaf3a Loopback0 (IP: 10.255.2.9)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf2b
+ hosts:
+ - destination: 10.255.2.10
+ repeat: 1
+ source: 10.255.1.8
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.8) - Destination: pod2-leaf3b Loopback0 (IP: 10.255.2.10)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf2b
+ hosts:
+ - destination: 10.255.2.11
+ repeat: 1
+ source: 10.255.1.8
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.8) - Destination: pod2-leaf4a Loopback0 (IP: 10.255.2.11)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf2b
+ hosts:
+ - destination: 10.255.2.12
+ repeat: 1
+ source: 10.255.1.8
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.8) - Destination: pod2-leaf4b Loopback0 (IP: 10.255.2.12)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf2b
+ hosts:
+ - destination: 10.255.2.13
+ repeat: 1
+ source: 10.255.1.8
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.8) - Destination: pod2-leaf5a Loopback0 (IP: 10.255.2.13)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf2b
+ hosts:
+ - destination: 10.255.2.14
+ repeat: 1
+ source: 10.255.1.8
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.8) - Destination: pod2-leaf5b Loopback0 (IP: 10.255.2.14)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf2b
+ hosts:
+ - destination: 10.255.2.15
+ repeat: 1
+ source: 10.255.1.8
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.8) - Destination: pod2-leaf6a Loopback0 (IP: 10.255.2.15)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf2b
+ hosts:
+ - destination: 10.255.2.16
+ repeat: 1
+ source: 10.255.1.8
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.8) - Destination: pod2-leaf6b Loopback0 (IP: 10.255.2.16)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf2b
+ hosts:
+ - destination: 10.255.2.17
+ repeat: 1
+ source: 10.255.1.8
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.8) - Destination: pod2-leaf7a Loopback0 (IP: 10.255.2.17)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf2b
+ hosts:
+ - destination: 10.255.2.18
+ repeat: 1
+ source: 10.255.1.8
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.8) - Destination: pod2-leaf7b Loopback0 (IP: 10.255.2.18)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf2b
+ hosts:
+ - destination: 10.255.2.19
+ repeat: 1
+ source: 10.255.1.8
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.8) - Destination: pod2-leaf8a Loopback0 (IP: 10.255.2.19)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf2b
+ hosts:
+ - destination: 10.255.2.20
+ repeat: 1
+ source: 10.255.1.8
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.8) - Destination: pod2-leaf8b Loopback0 (IP: 10.255.2.20)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf2b
+ hosts:
+ - destination: 10.255.2.21
+ repeat: 1
+ source: 10.255.1.8
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.8) - Destination: pod2-leaf9a Loopback0 (IP: 10.255.2.21)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf2b
+ hosts:
+ - destination: 10.255.2.22
+ repeat: 1
+ source: 10.255.1.8
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.8) - Destination: pod2-leaf9b Loopback0 (IP: 10.255.2.22)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf2b
+ hosts:
+ - destination: 10.255.2.23
+ repeat: 1
+ source: 10.255.1.8
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.8) - Destination: pod2-leaf10a Loopback0 (IP: 10.255.2.23)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf2b
+ hosts:
+ - destination: 10.255.2.24
+ repeat: 1
+ source: 10.255.1.8
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.8) - Destination: pod2-leaf10b Loopback0 (IP: 10.255.2.24)'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-leaf5b
+ neighbors:
+ - neighbor_device: pod1-leaf5a
+ neighbor_port: Ethernet53/1
+ port: Ethernet53/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet53/1 - Remote: pod1-leaf5a Ethernet53/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-leaf5b
+ neighbors:
+ - neighbor_device: pod1-leaf5a
+ neighbor_port: Ethernet54/1
+ port: Ethernet54/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet54/1 - Remote: pod1-leaf5a Ethernet54/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-leaf5b
+ neighbors:
+ - neighbor_device: pod1-spine1
+ neighbor_port: Ethernet10/1
+ port: Ethernet1/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet1/1 - Remote: pod1-spine1 Ethernet10/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-leaf5b
+ neighbors:
+ - neighbor_device: pod1-spine2
+ neighbor_port: Ethernet10/1
+ port: Ethernet2/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet2/1 - Remote: pod1-spine2 Ethernet10/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-leaf5b
+ neighbors:
+ - neighbor_device: pod1-spine3
+ neighbor_port: Ethernet10/1
+ port: Ethernet3/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet3/1 - Remote: pod1-spine3 Ethernet10/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-leaf5b
+ neighbors:
+ - neighbor_device: pod1-spine4
+ neighbor_port: Ethernet10/1
+ port: Ethernet4/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet4/1 - Remote: pod1-spine4 Ethernet10/1'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf5b
+ hosts:
+ - destination: 10.255.255.72
+ repeat: 1
+ source: 10.255.255.73
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet1/1 (IP: 10.255.255.73) - Destination: pod1-spine1 Ethernet10/1 (IP: 10.255.255.72)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf5b
+ hosts:
+ - destination: 10.255.255.74
+ repeat: 1
+ source: 10.255.255.75
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet2/1 (IP: 10.255.255.75) - Destination: pod1-spine2 Ethernet10/1 (IP: 10.255.255.74)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf5b
+ hosts:
+ - destination: 10.255.255.76
+ repeat: 1
+ source: 10.255.255.77
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet3/1 (IP: 10.255.255.77) - Destination: pod1-spine3 Ethernet10/1 (IP: 10.255.255.76)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf5b
+ hosts:
+ - destination: 10.255.255.78
+ repeat: 1
+ source: 10.255.255.79
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet4/1 (IP: 10.255.255.79) - Destination: pod1-spine4 Ethernet10/1 (IP: 10.255.255.78)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf5b
+ hosts:
+ - destination: 10.255.0.1
+ repeat: 1
+ source: 10.255.1.14
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.14) - Destination: super-spine1 Loopback0 (IP: 10.255.0.1)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf5b
+ hosts:
+ - destination: 10.255.0.2
+ repeat: 1
+ source: 10.255.1.14
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.14) - Destination: super-spine2 Loopback0 (IP: 10.255.0.2)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf5b
+ hosts:
+ - destination: 10.255.1.1
+ repeat: 1
+ source: 10.255.1.14
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.14) - Destination: pod1-spine1 Loopback0 (IP: 10.255.1.1)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf5b
+ hosts:
+ - destination: 10.255.1.2
+ repeat: 1
+ source: 10.255.1.14
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.14) - Destination: pod1-spine2 Loopback0 (IP: 10.255.1.2)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf5b
+ hosts:
+ - destination: 10.255.1.3
+ repeat: 1
+ source: 10.255.1.14
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.14) - Destination: pod1-spine3 Loopback0 (IP: 10.255.1.3)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf5b
+ hosts:
+ - destination: 10.255.1.4
+ repeat: 1
+ source: 10.255.1.14
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.14) - Destination: pod1-spine4 Loopback0 (IP: 10.255.1.4)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf5b
+ hosts:
+ - destination: 10.255.1.5
+ repeat: 1
+ source: 10.255.1.14
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.14) - Destination: pod1-leaf1a Loopback0 (IP: 10.255.1.5)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf5b
+ hosts:
+ - destination: 10.255.1.6
+ repeat: 1
+ source: 10.255.1.14
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.14) - Destination: pod1-leaf1b Loopback0 (IP: 10.255.1.6)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf5b
+ hosts:
+ - destination: 10.255.1.7
+ repeat: 1
+ source: 10.255.1.14
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.14) - Destination: pod1-leaf2a Loopback0 (IP: 10.255.1.7)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf5b
+ hosts:
+ - destination: 10.255.1.8
+ repeat: 1
+ source: 10.255.1.14
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.14) - Destination: pod1-leaf2b Loopback0 (IP: 10.255.1.8)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf5b
+ hosts:
+ - destination: 10.255.1.9
+ repeat: 1
+ source: 10.255.1.14
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.14) - Destination: pod1-leaf3a Loopback0 (IP: 10.255.1.9)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf5b
+ hosts:
+ - destination: 10.255.1.10
+ repeat: 1
+ source: 10.255.1.14
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.14) - Destination: pod1-leaf3b Loopback0 (IP: 10.255.1.10)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf5b
+ hosts:
+ - destination: 10.255.1.11
+ repeat: 1
+ source: 10.255.1.14
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.14) - Destination: pod1-leaf4a Loopback0 (IP: 10.255.1.11)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf5b
+ hosts:
+ - destination: 10.255.1.12
+ repeat: 1
+ source: 10.255.1.14
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.14) - Destination: pod1-leaf4b Loopback0 (IP: 10.255.1.12)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf5b
+ hosts:
+ - destination: 10.255.1.13
+ repeat: 1
+ source: 10.255.1.14
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.14) - Destination: pod1-leaf5a Loopback0 (IP: 10.255.1.13)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf5b
+ hosts:
+ - destination: 10.255.1.14
+ repeat: 1
+ source: 10.255.1.14
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.14) - Destination: pod1-leaf5b Loopback0 (IP: 10.255.1.14)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf5b
+ hosts:
+ - destination: 10.255.1.15
+ repeat: 1
+ source: 10.255.1.14
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.14) - Destination: pod1-leaf6a Loopback0 (IP: 10.255.1.15)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf5b
+ hosts:
+ - destination: 10.255.1.16
+ repeat: 1
+ source: 10.255.1.14
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.14) - Destination: pod1-leaf6b Loopback0 (IP: 10.255.1.16)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf5b
+ hosts:
+ - destination: 10.255.1.17
+ repeat: 1
+ source: 10.255.1.14
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.14) - Destination: pod1-leaf7a Loopback0 (IP: 10.255.1.17)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf5b
+ hosts:
+ - destination: 10.255.1.18
+ repeat: 1
+ source: 10.255.1.14
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.14) - Destination: pod1-leaf7b Loopback0 (IP: 10.255.1.18)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf5b
+ hosts:
+ - destination: 10.255.1.19
+ repeat: 1
+ source: 10.255.1.14
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.14) - Destination: pod1-leaf8a Loopback0 (IP: 10.255.1.19)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf5b
+ hosts:
+ - destination: 10.255.1.20
+ repeat: 1
+ source: 10.255.1.14
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.14) - Destination: pod1-leaf8b Loopback0 (IP: 10.255.1.20)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf5b
+ hosts:
+ - destination: 10.255.1.21
+ repeat: 1
+ source: 10.255.1.14
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.14) - Destination: pod1-leaf9a Loopback0 (IP: 10.255.1.21)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf5b
+ hosts:
+ - destination: 10.255.1.22
+ repeat: 1
+ source: 10.255.1.14
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.14) - Destination: pod1-leaf9b Loopback0 (IP: 10.255.1.22)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf5b
+ hosts:
+ - destination: 10.255.1.23
+ repeat: 1
+ source: 10.255.1.14
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.14) - Destination: pod1-leaf10a Loopback0 (IP: 10.255.1.23)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf5b
+ hosts:
+ - destination: 10.255.1.24
+ repeat: 1
+ source: 10.255.1.14
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.14) - Destination: pod1-leaf10b Loopback0 (IP: 10.255.1.24)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf5b
+ hosts:
+ - destination: 10.255.2.1
+ repeat: 1
+ source: 10.255.1.14
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.14) - Destination: pod2-spine1 Loopback0 (IP: 10.255.2.1)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf5b
+ hosts:
+ - destination: 10.255.2.2
+ repeat: 1
+ source: 10.255.1.14
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.14) - Destination: pod2-spine2 Loopback0 (IP: 10.255.2.2)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf5b
+ hosts:
+ - destination: 10.255.2.3
+ repeat: 1
+ source: 10.255.1.14
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.14) - Destination: pod2-spine3 Loopback0 (IP: 10.255.2.3)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf5b
+ hosts:
+ - destination: 10.255.2.4
+ repeat: 1
+ source: 10.255.1.14
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.14) - Destination: pod2-spine4 Loopback0 (IP: 10.255.2.4)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf5b
+ hosts:
+ - destination: 10.255.2.5
+ repeat: 1
+ source: 10.255.1.14
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.14) - Destination: pod2-leaf1a Loopback0 (IP: 10.255.2.5)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf5b
+ hosts:
+ - destination: 10.255.2.6
+ repeat: 1
+ source: 10.255.1.14
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.14) - Destination: pod2-leaf1b Loopback0 (IP: 10.255.2.6)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf5b
+ hosts:
+ - destination: 10.255.2.7
+ repeat: 1
+ source: 10.255.1.14
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.14) - Destination: pod2-leaf2a Loopback0 (IP: 10.255.2.7)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf5b
+ hosts:
+ - destination: 10.255.2.8
+ repeat: 1
+ source: 10.255.1.14
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.14) - Destination: pod2-leaf2b Loopback0 (IP: 10.255.2.8)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf5b
+ hosts:
+ - destination: 10.255.2.9
+ repeat: 1
+ source: 10.255.1.14
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.14) - Destination: pod2-leaf3a Loopback0 (IP: 10.255.2.9)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf5b
+ hosts:
+ - destination: 10.255.2.10
+ repeat: 1
+ source: 10.255.1.14
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.14) - Destination: pod2-leaf3b Loopback0 (IP: 10.255.2.10)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf5b
+ hosts:
+ - destination: 10.255.2.11
+ repeat: 1
+ source: 10.255.1.14
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.14) - Destination: pod2-leaf4a Loopback0 (IP: 10.255.2.11)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf5b
+ hosts:
+ - destination: 10.255.2.12
+ repeat: 1
+ source: 10.255.1.14
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.14) - Destination: pod2-leaf4b Loopback0 (IP: 10.255.2.12)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf5b
+ hosts:
+ - destination: 10.255.2.13
+ repeat: 1
+ source: 10.255.1.14
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.14) - Destination: pod2-leaf5a Loopback0 (IP: 10.255.2.13)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf5b
+ hosts:
+ - destination: 10.255.2.14
+ repeat: 1
+ source: 10.255.1.14
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.14) - Destination: pod2-leaf5b Loopback0 (IP: 10.255.2.14)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf5b
+ hosts:
+ - destination: 10.255.2.15
+ repeat: 1
+ source: 10.255.1.14
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.14) - Destination: pod2-leaf6a Loopback0 (IP: 10.255.2.15)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf5b
+ hosts:
+ - destination: 10.255.2.16
+ repeat: 1
+ source: 10.255.1.14
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.14) - Destination: pod2-leaf6b Loopback0 (IP: 10.255.2.16)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf5b
+ hosts:
+ - destination: 10.255.2.17
+ repeat: 1
+ source: 10.255.1.14
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.14) - Destination: pod2-leaf7a Loopback0 (IP: 10.255.2.17)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf5b
+ hosts:
+ - destination: 10.255.2.18
+ repeat: 1
+ source: 10.255.1.14
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.14) - Destination: pod2-leaf7b Loopback0 (IP: 10.255.2.18)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf5b
+ hosts:
+ - destination: 10.255.2.19
+ repeat: 1
+ source: 10.255.1.14
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.14) - Destination: pod2-leaf8a Loopback0 (IP: 10.255.2.19)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf5b
+ hosts:
+ - destination: 10.255.2.20
+ repeat: 1
+ source: 10.255.1.14
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.14) - Destination: pod2-leaf8b Loopback0 (IP: 10.255.2.20)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf5b
+ hosts:
+ - destination: 10.255.2.21
+ repeat: 1
+ source: 10.255.1.14
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.14) - Destination: pod2-leaf9a Loopback0 (IP: 10.255.2.21)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf5b
+ hosts:
+ - destination: 10.255.2.22
+ repeat: 1
+ source: 10.255.1.14
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.14) - Destination: pod2-leaf9b Loopback0 (IP: 10.255.2.22)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf5b
+ hosts:
+ - destination: 10.255.2.23
+ repeat: 1
+ source: 10.255.1.14
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.14) - Destination: pod2-leaf10a Loopback0 (IP: 10.255.2.23)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf5b
+ hosts:
+ - destination: 10.255.2.24
+ repeat: 1
+ source: 10.255.1.14
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.14) - Destination: pod2-leaf10b Loopback0 (IP: 10.255.2.24)'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-leaf8a
+ neighbors:
+ - neighbor_device: pod1-leaf8b
+ neighbor_port: Ethernet53/1
+ port: Ethernet53/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet53/1 - Remote: pod1-leaf8b Ethernet53/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-leaf8a
+ neighbors:
+ - neighbor_device: pod1-leaf8b
+ neighbor_port: Ethernet54/1
+ port: Ethernet54/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet54/1 - Remote: pod1-leaf8b Ethernet54/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-leaf8a
+ neighbors:
+ - neighbor_device: pod1-spine1
+ neighbor_port: Ethernet15/1
+ port: Ethernet1/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet1/1 - Remote: pod1-spine1 Ethernet15/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-leaf8a
+ neighbors:
+ - neighbor_device: pod1-spine2
+ neighbor_port: Ethernet15/1
+ port: Ethernet2/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet2/1 - Remote: pod1-spine2 Ethernet15/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-leaf8a
+ neighbors:
+ - neighbor_device: pod1-spine3
+ neighbor_port: Ethernet15/1
+ port: Ethernet3/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet3/1 - Remote: pod1-spine3 Ethernet15/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-leaf8a
+ neighbors:
+ - neighbor_device: pod1-spine4
+ neighbor_port: Ethernet15/1
+ port: Ethernet4/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet4/1 - Remote: pod1-spine4 Ethernet15/1'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf8a
+ hosts:
+ - destination: 10.255.255.112
+ repeat: 1
+ source: 10.255.255.113
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet1/1 (IP: 10.255.255.113) - Destination: pod1-spine1 Ethernet15/1 (IP: 10.255.255.112)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf8a
+ hosts:
+ - destination: 10.255.255.114
+ repeat: 1
+ source: 10.255.255.115
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet2/1 (IP: 10.255.255.115) - Destination: pod1-spine2 Ethernet15/1 (IP: 10.255.255.114)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf8a
+ hosts:
+ - destination: 10.255.255.116
+ repeat: 1
+ source: 10.255.255.117
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet3/1 (IP: 10.255.255.117) - Destination: pod1-spine3 Ethernet15/1 (IP: 10.255.255.116)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf8a
+ hosts:
+ - destination: 10.255.255.118
+ repeat: 1
+ source: 10.255.255.119
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet4/1 (IP: 10.255.255.119) - Destination: pod1-spine4 Ethernet15/1 (IP: 10.255.255.118)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf8a
+ hosts:
+ - destination: 10.255.0.1
+ repeat: 1
+ source: 10.255.1.19
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.19) - Destination: super-spine1 Loopback0 (IP: 10.255.0.1)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf8a
+ hosts:
+ - destination: 10.255.0.2
+ repeat: 1
+ source: 10.255.1.19
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.19) - Destination: super-spine2 Loopback0 (IP: 10.255.0.2)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf8a
+ hosts:
+ - destination: 10.255.1.1
+ repeat: 1
+ source: 10.255.1.19
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.19) - Destination: pod1-spine1 Loopback0 (IP: 10.255.1.1)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf8a
+ hosts:
+ - destination: 10.255.1.2
+ repeat: 1
+ source: 10.255.1.19
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.19) - Destination: pod1-spine2 Loopback0 (IP: 10.255.1.2)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf8a
+ hosts:
+ - destination: 10.255.1.3
+ repeat: 1
+ source: 10.255.1.19
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.19) - Destination: pod1-spine3 Loopback0 (IP: 10.255.1.3)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf8a
+ hosts:
+ - destination: 10.255.1.4
+ repeat: 1
+ source: 10.255.1.19
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.19) - Destination: pod1-spine4 Loopback0 (IP: 10.255.1.4)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf8a
+ hosts:
+ - destination: 10.255.1.5
+ repeat: 1
+ source: 10.255.1.19
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.19) - Destination: pod1-leaf1a Loopback0 (IP: 10.255.1.5)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf8a
+ hosts:
+ - destination: 10.255.1.6
+ repeat: 1
+ source: 10.255.1.19
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.19) - Destination: pod1-leaf1b Loopback0 (IP: 10.255.1.6)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf8a
+ hosts:
+ - destination: 10.255.1.7
+ repeat: 1
+ source: 10.255.1.19
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.19) - Destination: pod1-leaf2a Loopback0 (IP: 10.255.1.7)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf8a
+ hosts:
+ - destination: 10.255.1.8
+ repeat: 1
+ source: 10.255.1.19
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.19) - Destination: pod1-leaf2b Loopback0 (IP: 10.255.1.8)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf8a
+ hosts:
+ - destination: 10.255.1.9
+ repeat: 1
+ source: 10.255.1.19
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.19) - Destination: pod1-leaf3a Loopback0 (IP: 10.255.1.9)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf8a
+ hosts:
+ - destination: 10.255.1.10
+ repeat: 1
+ source: 10.255.1.19
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.19) - Destination: pod1-leaf3b Loopback0 (IP: 10.255.1.10)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf8a
+ hosts:
+ - destination: 10.255.1.11
+ repeat: 1
+ source: 10.255.1.19
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.19) - Destination: pod1-leaf4a Loopback0 (IP: 10.255.1.11)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf8a
+ hosts:
+ - destination: 10.255.1.12
+ repeat: 1
+ source: 10.255.1.19
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.19) - Destination: pod1-leaf4b Loopback0 (IP: 10.255.1.12)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf8a
+ hosts:
+ - destination: 10.255.1.13
+ repeat: 1
+ source: 10.255.1.19
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.19) - Destination: pod1-leaf5a Loopback0 (IP: 10.255.1.13)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf8a
+ hosts:
+ - destination: 10.255.1.14
+ repeat: 1
+ source: 10.255.1.19
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.19) - Destination: pod1-leaf5b Loopback0 (IP: 10.255.1.14)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf8a
+ hosts:
+ - destination: 10.255.1.15
+ repeat: 1
+ source: 10.255.1.19
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.19) - Destination: pod1-leaf6a Loopback0 (IP: 10.255.1.15)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf8a
+ hosts:
+ - destination: 10.255.1.16
+ repeat: 1
+ source: 10.255.1.19
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.19) - Destination: pod1-leaf6b Loopback0 (IP: 10.255.1.16)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf8a
+ hosts:
+ - destination: 10.255.1.17
+ repeat: 1
+ source: 10.255.1.19
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.19) - Destination: pod1-leaf7a Loopback0 (IP: 10.255.1.17)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf8a
+ hosts:
+ - destination: 10.255.1.18
+ repeat: 1
+ source: 10.255.1.19
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.19) - Destination: pod1-leaf7b Loopback0 (IP: 10.255.1.18)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf8a
+ hosts:
+ - destination: 10.255.1.19
+ repeat: 1
+ source: 10.255.1.19
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.19) - Destination: pod1-leaf8a Loopback0 (IP: 10.255.1.19)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf8a
+ hosts:
+ - destination: 10.255.1.20
+ repeat: 1
+ source: 10.255.1.19
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.19) - Destination: pod1-leaf8b Loopback0 (IP: 10.255.1.20)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf8a
+ hosts:
+ - destination: 10.255.1.21
+ repeat: 1
+ source: 10.255.1.19
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.19) - Destination: pod1-leaf9a Loopback0 (IP: 10.255.1.21)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf8a
+ hosts:
+ - destination: 10.255.1.22
+ repeat: 1
+ source: 10.255.1.19
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.19) - Destination: pod1-leaf9b Loopback0 (IP: 10.255.1.22)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf8a
+ hosts:
+ - destination: 10.255.1.23
+ repeat: 1
+ source: 10.255.1.19
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.19) - Destination: pod1-leaf10a Loopback0 (IP: 10.255.1.23)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf8a
+ hosts:
+ - destination: 10.255.1.24
+ repeat: 1
+ source: 10.255.1.19
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.19) - Destination: pod1-leaf10b Loopback0 (IP: 10.255.1.24)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf8a
+ hosts:
+ - destination: 10.255.2.1
+ repeat: 1
+ source: 10.255.1.19
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.19) - Destination: pod2-spine1 Loopback0 (IP: 10.255.2.1)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf8a
+ hosts:
+ - destination: 10.255.2.2
+ repeat: 1
+ source: 10.255.1.19
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.19) - Destination: pod2-spine2 Loopback0 (IP: 10.255.2.2)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf8a
+ hosts:
+ - destination: 10.255.2.3
+ repeat: 1
+ source: 10.255.1.19
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.19) - Destination: pod2-spine3 Loopback0 (IP: 10.255.2.3)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf8a
+ hosts:
+ - destination: 10.255.2.4
+ repeat: 1
+ source: 10.255.1.19
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.19) - Destination: pod2-spine4 Loopback0 (IP: 10.255.2.4)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf8a
+ hosts:
+ - destination: 10.255.2.5
+ repeat: 1
+ source: 10.255.1.19
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.19) - Destination: pod2-leaf1a Loopback0 (IP: 10.255.2.5)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf8a
+ hosts:
+ - destination: 10.255.2.6
+ repeat: 1
+ source: 10.255.1.19
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.19) - Destination: pod2-leaf1b Loopback0 (IP: 10.255.2.6)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf8a
+ hosts:
+ - destination: 10.255.2.7
+ repeat: 1
+ source: 10.255.1.19
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.19) - Destination: pod2-leaf2a Loopback0 (IP: 10.255.2.7)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf8a
+ hosts:
+ - destination: 10.255.2.8
+ repeat: 1
+ source: 10.255.1.19
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.19) - Destination: pod2-leaf2b Loopback0 (IP: 10.255.2.8)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf8a
+ hosts:
+ - destination: 10.255.2.9
+ repeat: 1
+ source: 10.255.1.19
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.19) - Destination: pod2-leaf3a Loopback0 (IP: 10.255.2.9)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf8a
+ hosts:
+ - destination: 10.255.2.10
+ repeat: 1
+ source: 10.255.1.19
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.19) - Destination: pod2-leaf3b Loopback0 (IP: 10.255.2.10)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf8a
+ hosts:
+ - destination: 10.255.2.11
+ repeat: 1
+ source: 10.255.1.19
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.19) - Destination: pod2-leaf4a Loopback0 (IP: 10.255.2.11)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf8a
+ hosts:
+ - destination: 10.255.2.12
+ repeat: 1
+ source: 10.255.1.19
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.19) - Destination: pod2-leaf4b Loopback0 (IP: 10.255.2.12)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf8a
+ hosts:
+ - destination: 10.255.2.13
+ repeat: 1
+ source: 10.255.1.19
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.19) - Destination: pod2-leaf5a Loopback0 (IP: 10.255.2.13)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf8a
+ hosts:
+ - destination: 10.255.2.14
+ repeat: 1
+ source: 10.255.1.19
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.19) - Destination: pod2-leaf5b Loopback0 (IP: 10.255.2.14)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf8a
+ hosts:
+ - destination: 10.255.2.15
+ repeat: 1
+ source: 10.255.1.19
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.19) - Destination: pod2-leaf6a Loopback0 (IP: 10.255.2.15)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf8a
+ hosts:
+ - destination: 10.255.2.16
+ repeat: 1
+ source: 10.255.1.19
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.19) - Destination: pod2-leaf6b Loopback0 (IP: 10.255.2.16)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf8a
+ hosts:
+ - destination: 10.255.2.17
+ repeat: 1
+ source: 10.255.1.19
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.19) - Destination: pod2-leaf7a Loopback0 (IP: 10.255.2.17)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf8a
+ hosts:
+ - destination: 10.255.2.18
+ repeat: 1
+ source: 10.255.1.19
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.19) - Destination: pod2-leaf7b Loopback0 (IP: 10.255.2.18)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf8a
+ hosts:
+ - destination: 10.255.2.19
+ repeat: 1
+ source: 10.255.1.19
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.19) - Destination: pod2-leaf8a Loopback0 (IP: 10.255.2.19)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf8a
+ hosts:
+ - destination: 10.255.2.20
+ repeat: 1
+ source: 10.255.1.19
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.19) - Destination: pod2-leaf8b Loopback0 (IP: 10.255.2.20)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf8a
+ hosts:
+ - destination: 10.255.2.21
+ repeat: 1
+ source: 10.255.1.19
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.19) - Destination: pod2-leaf9a Loopback0 (IP: 10.255.2.21)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf8a
+ hosts:
+ - destination: 10.255.2.22
+ repeat: 1
+ source: 10.255.1.19
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.19) - Destination: pod2-leaf9b Loopback0 (IP: 10.255.2.22)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf8a
+ hosts:
+ - destination: 10.255.2.23
+ repeat: 1
+ source: 10.255.1.19
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.19) - Destination: pod2-leaf10a Loopback0 (IP: 10.255.2.23)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf8a
+ hosts:
+ - destination: 10.255.2.24
+ repeat: 1
+ source: 10.255.1.19
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.19) - Destination: pod2-leaf10b Loopback0 (IP: 10.255.2.24)'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-spine4
+ neighbors:
+ - neighbor_device: pod2-leaf1a
+ neighbor_port: Ethernet4/1
+ port: Ethernet1/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet1/1 - Remote: pod2-leaf1a Ethernet4/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-spine4
+ neighbors:
+ - neighbor_device: pod2-leaf1b
+ neighbor_port: Ethernet4/1
+ port: Ethernet2/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet2/1 - Remote: pod2-leaf1b Ethernet4/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-spine4
+ neighbors:
+ - neighbor_device: pod2-leaf2a
+ neighbor_port: Ethernet4/1
+ port: Ethernet3/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet3/1 - Remote: pod2-leaf2a Ethernet4/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-spine4
+ neighbors:
+ - neighbor_device: pod2-leaf2b
+ neighbor_port: Ethernet4/1
+ port: Ethernet4/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet4/1 - Remote: pod2-leaf2b Ethernet4/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-spine4
+ neighbors:
+ - neighbor_device: pod2-leaf3a
+ neighbor_port: Ethernet4/1
+ port: Ethernet5/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet5/1 - Remote: pod2-leaf3a Ethernet4/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-spine4
+ neighbors:
+ - neighbor_device: pod2-leaf3b
+ neighbor_port: Ethernet4/1
+ port: Ethernet6/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet6/1 - Remote: pod2-leaf3b Ethernet4/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-spine4
+ neighbors:
+ - neighbor_device: pod2-leaf4a
+ neighbor_port: Ethernet4/1
+ port: Ethernet7/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet7/1 - Remote: pod2-leaf4a Ethernet4/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-spine4
+ neighbors:
+ - neighbor_device: pod2-leaf4b
+ neighbor_port: Ethernet4/1
+ port: Ethernet8/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet8/1 - Remote: pod2-leaf4b Ethernet4/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-spine4
+ neighbors:
+ - neighbor_device: pod2-leaf5a
+ neighbor_port: Ethernet4/1
+ port: Ethernet9/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet9/1 - Remote: pod2-leaf5a Ethernet4/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-spine4
+ neighbors:
+ - neighbor_device: pod2-leaf5b
+ neighbor_port: Ethernet4/1
+ port: Ethernet10/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet10/1 - Remote: pod2-leaf5b Ethernet4/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-spine4
+ neighbors:
+ - neighbor_device: pod2-leaf6a
+ neighbor_port: Ethernet4/1
+ port: Ethernet11/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet11/1 - Remote: pod2-leaf6a Ethernet4/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-spine4
+ neighbors:
+ - neighbor_device: pod2-leaf6b
+ neighbor_port: Ethernet4/1
+ port: Ethernet12/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet12/1 - Remote: pod2-leaf6b Ethernet4/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-spine4
+ neighbors:
+ - neighbor_device: pod2-leaf7a
+ neighbor_port: Ethernet4/1
+ port: Ethernet13/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet13/1 - Remote: pod2-leaf7a Ethernet4/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-spine4
+ neighbors:
+ - neighbor_device: pod2-leaf7b
+ neighbor_port: Ethernet4/1
+ port: Ethernet14/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet14/1 - Remote: pod2-leaf7b Ethernet4/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-spine4
+ neighbors:
+ - neighbor_device: pod2-leaf8a
+ neighbor_port: Ethernet4/1
+ port: Ethernet15/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet15/1 - Remote: pod2-leaf8a Ethernet4/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-spine4
+ neighbors:
+ - neighbor_device: pod2-leaf8b
+ neighbor_port: Ethernet4/1
+ port: Ethernet16/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet16/1 - Remote: pod2-leaf8b Ethernet4/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-spine4
+ neighbors:
+ - neighbor_device: pod2-leaf9a
+ neighbor_port: Ethernet4/1
+ port: Ethernet17/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet17/1 - Remote: pod2-leaf9a Ethernet4/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-spine4
+ neighbors:
+ - neighbor_device: pod2-leaf9b
+ neighbor_port: Ethernet4/1
+ port: Ethernet18/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet18/1 - Remote: pod2-leaf9b Ethernet4/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-spine4
+ neighbors:
+ - neighbor_device: pod2-leaf10a
+ neighbor_port: Ethernet4/1
+ port: Ethernet19/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet19/1 - Remote: pod2-leaf10a Ethernet4/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-spine4
+ neighbors:
+ - neighbor_device: pod2-leaf10b
+ neighbor_port: Ethernet4/1
+ port: Ethernet20/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet20/1 - Remote: pod2-leaf10b Ethernet4/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-spine4
+ neighbors:
+ - neighbor_device: super-spine1
+ neighbor_port: Ethernet8/1
+ port: Ethernet31/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet31/1 - Remote: super-spine1 Ethernet8/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-spine4
+ neighbors:
+ - neighbor_device: super-spine2
+ neighbor_port: Ethernet8/1
+ port: Ethernet32/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet32/1 - Remote: super-spine2 Ethernet8/1'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-spine4
+ hosts:
+ - destination: 10.255.255.7
+ repeat: 1
+ source: 10.255.255.6
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet1/1 (IP: 10.255.255.6) - Destination: pod2-leaf1a Ethernet4/1 (IP: 10.255.255.7)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-spine4
+ hosts:
+ - destination: 10.255.255.15
+ repeat: 1
+ source: 10.255.255.14
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet2/1 (IP: 10.255.255.14) - Destination: pod2-leaf1b Ethernet4/1 (IP: 10.255.255.15)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-spine4
+ hosts:
+ - destination: 10.255.255.23
+ repeat: 1
+ source: 10.255.255.22
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet3/1 (IP: 10.255.255.22) - Destination: pod2-leaf2a Ethernet4/1 (IP: 10.255.255.23)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-spine4
+ hosts:
+ - destination: 10.255.255.31
+ repeat: 1
+ source: 10.255.255.30
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet4/1 (IP: 10.255.255.30) - Destination: pod2-leaf2b Ethernet4/1 (IP: 10.255.255.31)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-spine4
+ hosts:
+ - destination: 10.255.255.39
+ repeat: 1
+ source: 10.255.255.38
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet5/1 (IP: 10.255.255.38) - Destination: pod2-leaf3a Ethernet4/1 (IP: 10.255.255.39)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-spine4
+ hosts:
+ - destination: 10.255.255.47
+ repeat: 1
+ source: 10.255.255.46
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet6/1 (IP: 10.255.255.46) - Destination: pod2-leaf3b Ethernet4/1 (IP: 10.255.255.47)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-spine4
+ hosts:
+ - destination: 10.255.255.55
+ repeat: 1
+ source: 10.255.255.54
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet7/1 (IP: 10.255.255.54) - Destination: pod2-leaf4a Ethernet4/1 (IP: 10.255.255.55)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-spine4
+ hosts:
+ - destination: 10.255.255.63
+ repeat: 1
+ source: 10.255.255.62
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet8/1 (IP: 10.255.255.62) - Destination: pod2-leaf4b Ethernet4/1 (IP: 10.255.255.63)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-spine4
+ hosts:
+ - destination: 10.255.255.71
+ repeat: 1
+ source: 10.255.255.70
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet9/1 (IP: 10.255.255.70) - Destination: pod2-leaf5a Ethernet4/1 (IP: 10.255.255.71)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-spine4
+ hosts:
+ - destination: 10.255.255.79
+ repeat: 1
+ source: 10.255.255.78
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet10/1 (IP: 10.255.255.78) - Destination: pod2-leaf5b Ethernet4/1 (IP: 10.255.255.79)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-spine4
+ hosts:
+ - destination: 10.255.255.87
+ repeat: 1
+ source: 10.255.255.86
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet11/1 (IP: 10.255.255.86) - Destination: pod2-leaf6a Ethernet4/1 (IP: 10.255.255.87)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-spine4
+ hosts:
+ - destination: 10.255.255.95
+ repeat: 1
+ source: 10.255.255.94
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet12/1 (IP: 10.255.255.94) - Destination: pod2-leaf6b Ethernet4/1 (IP: 10.255.255.95)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-spine4
+ hosts:
+ - destination: 10.255.255.103
+ repeat: 1
+ source: 10.255.255.102
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet13/1 (IP: 10.255.255.102) - Destination: pod2-leaf7a Ethernet4/1 (IP: 10.255.255.103)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-spine4
+ hosts:
+ - destination: 10.255.255.111
+ repeat: 1
+ source: 10.255.255.110
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet14/1 (IP: 10.255.255.110) - Destination: pod2-leaf7b Ethernet4/1 (IP: 10.255.255.111)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-spine4
+ hosts:
+ - destination: 10.255.255.119
+ repeat: 1
+ source: 10.255.255.118
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet15/1 (IP: 10.255.255.118) - Destination: pod2-leaf8a Ethernet4/1 (IP: 10.255.255.119)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-spine4
+ hosts:
+ - destination: 10.255.255.127
+ repeat: 1
+ source: 10.255.255.126
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet16/1 (IP: 10.255.255.126) - Destination: pod2-leaf8b Ethernet4/1 (IP: 10.255.255.127)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-spine4
+ hosts:
+ - destination: 10.255.255.135
+ repeat: 1
+ source: 10.255.255.134
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet17/1 (IP: 10.255.255.134) - Destination: pod2-leaf9a Ethernet4/1 (IP: 10.255.255.135)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-spine4
+ hosts:
+ - destination: 10.255.255.143
+ repeat: 1
+ source: 10.255.255.142
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet18/1 (IP: 10.255.255.142) - Destination: pod2-leaf9b Ethernet4/1 (IP: 10.255.255.143)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-spine4
+ hosts:
+ - destination: 10.255.255.151
+ repeat: 1
+ source: 10.255.255.150
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet19/1 (IP: 10.255.255.150) - Destination: pod2-leaf10a Ethernet4/1 (IP: 10.255.255.151)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-spine4
+ hosts:
+ - destination: 10.255.255.159
+ repeat: 1
+ source: 10.255.255.158
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet20/1 (IP: 10.255.255.158) - Destination: pod2-leaf10b Ethernet4/1 (IP: 10.255.255.159)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-spine4
+ hosts:
+ - destination: 10.255.255.140
+ repeat: 1
+ source: 10.255.255.141
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet31/1 (IP: 10.255.255.141) - Destination: super-spine1 Ethernet8/1 (IP: 10.255.255.140)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-spine4
+ hosts:
+ - destination: 10.255.255.142
+ repeat: 1
+ source: 10.255.255.143
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet32/1 (IP: 10.255.255.143) - Destination: super-spine2 Ethernet8/1 (IP: 10.255.255.142)'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-leaf3b
+ neighbors:
+ - neighbor_device: pod2-leaf3a
+ neighbor_port: Ethernet53/1
+ port: Ethernet53/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet53/1 - Remote: pod2-leaf3a Ethernet53/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-leaf3b
+ neighbors:
+ - neighbor_device: pod2-leaf3a
+ neighbor_port: Ethernet54/1
+ port: Ethernet54/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet54/1 - Remote: pod2-leaf3a Ethernet54/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-leaf3b
+ neighbors:
+ - neighbor_device: pod2-spine1
+ neighbor_port: Ethernet6/1
+ port: Ethernet1/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet1/1 - Remote: pod2-spine1 Ethernet6/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-leaf3b
+ neighbors:
+ - neighbor_device: pod2-spine2
+ neighbor_port: Ethernet6/1
+ port: Ethernet2/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet2/1 - Remote: pod2-spine2 Ethernet6/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-leaf3b
+ neighbors:
+ - neighbor_device: pod2-spine3
+ neighbor_port: Ethernet6/1
+ port: Ethernet3/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet3/1 - Remote: pod2-spine3 Ethernet6/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-leaf3b
+ neighbors:
+ - neighbor_device: pod2-spine4
+ neighbor_port: Ethernet6/1
+ port: Ethernet4/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet4/1 - Remote: pod2-spine4 Ethernet6/1'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf3b
+ hosts:
+ - destination: 10.255.255.40
+ repeat: 1
+ source: 10.255.255.41
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet1/1 (IP: 10.255.255.41) - Destination: pod2-spine1 Ethernet6/1 (IP: 10.255.255.40)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf3b
+ hosts:
+ - destination: 10.255.255.42
+ repeat: 1
+ source: 10.255.255.43
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet2/1 (IP: 10.255.255.43) - Destination: pod2-spine2 Ethernet6/1 (IP: 10.255.255.42)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf3b
+ hosts:
+ - destination: 10.255.255.44
+ repeat: 1
+ source: 10.255.255.45
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet3/1 (IP: 10.255.255.45) - Destination: pod2-spine3 Ethernet6/1 (IP: 10.255.255.44)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf3b
+ hosts:
+ - destination: 10.255.255.46
+ repeat: 1
+ source: 10.255.255.47
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet4/1 (IP: 10.255.255.47) - Destination: pod2-spine4 Ethernet6/1 (IP: 10.255.255.46)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf3b
+ hosts:
+ - destination: 10.255.0.1
+ repeat: 1
+ source: 10.255.2.10
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.10) - Destination: super-spine1 Loopback0 (IP: 10.255.0.1)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf3b
+ hosts:
+ - destination: 10.255.0.2
+ repeat: 1
+ source: 10.255.2.10
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.10) - Destination: super-spine2 Loopback0 (IP: 10.255.0.2)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf3b
+ hosts:
+ - destination: 10.255.1.1
+ repeat: 1
+ source: 10.255.2.10
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.10) - Destination: pod1-spine1 Loopback0 (IP: 10.255.1.1)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf3b
+ hosts:
+ - destination: 10.255.1.2
+ repeat: 1
+ source: 10.255.2.10
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.10) - Destination: pod1-spine2 Loopback0 (IP: 10.255.1.2)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf3b
+ hosts:
+ - destination: 10.255.1.3
+ repeat: 1
+ source: 10.255.2.10
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.10) - Destination: pod1-spine3 Loopback0 (IP: 10.255.1.3)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf3b
+ hosts:
+ - destination: 10.255.1.4
+ repeat: 1
+ source: 10.255.2.10
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.10) - Destination: pod1-spine4 Loopback0 (IP: 10.255.1.4)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf3b
+ hosts:
+ - destination: 10.255.1.5
+ repeat: 1
+ source: 10.255.2.10
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.10) - Destination: pod1-leaf1a Loopback0 (IP: 10.255.1.5)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf3b
+ hosts:
+ - destination: 10.255.1.6
+ repeat: 1
+ source: 10.255.2.10
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.10) - Destination: pod1-leaf1b Loopback0 (IP: 10.255.1.6)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf3b
+ hosts:
+ - destination: 10.255.1.7
+ repeat: 1
+ source: 10.255.2.10
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.10) - Destination: pod1-leaf2a Loopback0 (IP: 10.255.1.7)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf3b
+ hosts:
+ - destination: 10.255.1.8
+ repeat: 1
+ source: 10.255.2.10
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.10) - Destination: pod1-leaf2b Loopback0 (IP: 10.255.1.8)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf3b
+ hosts:
+ - destination: 10.255.1.9
+ repeat: 1
+ source: 10.255.2.10
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.10) - Destination: pod1-leaf3a Loopback0 (IP: 10.255.1.9)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf3b
+ hosts:
+ - destination: 10.255.1.10
+ repeat: 1
+ source: 10.255.2.10
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.10) - Destination: pod1-leaf3b Loopback0 (IP: 10.255.1.10)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf3b
+ hosts:
+ - destination: 10.255.1.11
+ repeat: 1
+ source: 10.255.2.10
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.10) - Destination: pod1-leaf4a Loopback0 (IP: 10.255.1.11)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf3b
+ hosts:
+ - destination: 10.255.1.12
+ repeat: 1
+ source: 10.255.2.10
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.10) - Destination: pod1-leaf4b Loopback0 (IP: 10.255.1.12)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf3b
+ hosts:
+ - destination: 10.255.1.13
+ repeat: 1
+ source: 10.255.2.10
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.10) - Destination: pod1-leaf5a Loopback0 (IP: 10.255.1.13)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf3b
+ hosts:
+ - destination: 10.255.1.14
+ repeat: 1
+ source: 10.255.2.10
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.10) - Destination: pod1-leaf5b Loopback0 (IP: 10.255.1.14)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf3b
+ hosts:
+ - destination: 10.255.1.15
+ repeat: 1
+ source: 10.255.2.10
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.10) - Destination: pod1-leaf6a Loopback0 (IP: 10.255.1.15)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf3b
+ hosts:
+ - destination: 10.255.1.16
+ repeat: 1
+ source: 10.255.2.10
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.10) - Destination: pod1-leaf6b Loopback0 (IP: 10.255.1.16)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf3b
+ hosts:
+ - destination: 10.255.1.17
+ repeat: 1
+ source: 10.255.2.10
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.10) - Destination: pod1-leaf7a Loopback0 (IP: 10.255.1.17)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf3b
+ hosts:
+ - destination: 10.255.1.18
+ repeat: 1
+ source: 10.255.2.10
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.10) - Destination: pod1-leaf7b Loopback0 (IP: 10.255.1.18)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf3b
+ hosts:
+ - destination: 10.255.1.19
+ repeat: 1
+ source: 10.255.2.10
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.10) - Destination: pod1-leaf8a Loopback0 (IP: 10.255.1.19)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf3b
+ hosts:
+ - destination: 10.255.1.20
+ repeat: 1
+ source: 10.255.2.10
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.10) - Destination: pod1-leaf8b Loopback0 (IP: 10.255.1.20)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf3b
+ hosts:
+ - destination: 10.255.1.21
+ repeat: 1
+ source: 10.255.2.10
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.10) - Destination: pod1-leaf9a Loopback0 (IP: 10.255.1.21)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf3b
+ hosts:
+ - destination: 10.255.1.22
+ repeat: 1
+ source: 10.255.2.10
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.10) - Destination: pod1-leaf9b Loopback0 (IP: 10.255.1.22)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf3b
+ hosts:
+ - destination: 10.255.1.23
+ repeat: 1
+ source: 10.255.2.10
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.10) - Destination: pod1-leaf10a Loopback0 (IP: 10.255.1.23)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf3b
+ hosts:
+ - destination: 10.255.1.24
+ repeat: 1
+ source: 10.255.2.10
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.10) - Destination: pod1-leaf10b Loopback0 (IP: 10.255.1.24)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf3b
+ hosts:
+ - destination: 10.255.2.1
+ repeat: 1
+ source: 10.255.2.10
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.10) - Destination: pod2-spine1 Loopback0 (IP: 10.255.2.1)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf3b
+ hosts:
+ - destination: 10.255.2.2
+ repeat: 1
+ source: 10.255.2.10
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.10) - Destination: pod2-spine2 Loopback0 (IP: 10.255.2.2)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf3b
+ hosts:
+ - destination: 10.255.2.3
+ repeat: 1
+ source: 10.255.2.10
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.10) - Destination: pod2-spine3 Loopback0 (IP: 10.255.2.3)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf3b
+ hosts:
+ - destination: 10.255.2.4
+ repeat: 1
+ source: 10.255.2.10
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.10) - Destination: pod2-spine4 Loopback0 (IP: 10.255.2.4)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf3b
+ hosts:
+ - destination: 10.255.2.5
+ repeat: 1
+ source: 10.255.2.10
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.10) - Destination: pod2-leaf1a Loopback0 (IP: 10.255.2.5)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf3b
+ hosts:
+ - destination: 10.255.2.6
+ repeat: 1
+ source: 10.255.2.10
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.10) - Destination: pod2-leaf1b Loopback0 (IP: 10.255.2.6)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf3b
+ hosts:
+ - destination: 10.255.2.7
+ repeat: 1
+ source: 10.255.2.10
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.10) - Destination: pod2-leaf2a Loopback0 (IP: 10.255.2.7)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf3b
+ hosts:
+ - destination: 10.255.2.8
+ repeat: 1
+ source: 10.255.2.10
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.10) - Destination: pod2-leaf2b Loopback0 (IP: 10.255.2.8)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf3b
+ hosts:
+ - destination: 10.255.2.9
+ repeat: 1
+ source: 10.255.2.10
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.10) - Destination: pod2-leaf3a Loopback0 (IP: 10.255.2.9)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf3b
+ hosts:
+ - destination: 10.255.2.10
+ repeat: 1
+ source: 10.255.2.10
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.10) - Destination: pod2-leaf3b Loopback0 (IP: 10.255.2.10)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf3b
+ hosts:
+ - destination: 10.255.2.11
+ repeat: 1
+ source: 10.255.2.10
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.10) - Destination: pod2-leaf4a Loopback0 (IP: 10.255.2.11)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf3b
+ hosts:
+ - destination: 10.255.2.12
+ repeat: 1
+ source: 10.255.2.10
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.10) - Destination: pod2-leaf4b Loopback0 (IP: 10.255.2.12)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf3b
+ hosts:
+ - destination: 10.255.2.13
+ repeat: 1
+ source: 10.255.2.10
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.10) - Destination: pod2-leaf5a Loopback0 (IP: 10.255.2.13)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf3b
+ hosts:
+ - destination: 10.255.2.14
+ repeat: 1
+ source: 10.255.2.10
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.10) - Destination: pod2-leaf5b Loopback0 (IP: 10.255.2.14)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf3b
+ hosts:
+ - destination: 10.255.2.15
+ repeat: 1
+ source: 10.255.2.10
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.10) - Destination: pod2-leaf6a Loopback0 (IP: 10.255.2.15)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf3b
+ hosts:
+ - destination: 10.255.2.16
+ repeat: 1
+ source: 10.255.2.10
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.10) - Destination: pod2-leaf6b Loopback0 (IP: 10.255.2.16)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf3b
+ hosts:
+ - destination: 10.255.2.17
+ repeat: 1
+ source: 10.255.2.10
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.10) - Destination: pod2-leaf7a Loopback0 (IP: 10.255.2.17)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf3b
+ hosts:
+ - destination: 10.255.2.18
+ repeat: 1
+ source: 10.255.2.10
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.10) - Destination: pod2-leaf7b Loopback0 (IP: 10.255.2.18)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf3b
+ hosts:
+ - destination: 10.255.2.19
+ repeat: 1
+ source: 10.255.2.10
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.10) - Destination: pod2-leaf8a Loopback0 (IP: 10.255.2.19)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf3b
+ hosts:
+ - destination: 10.255.2.20
+ repeat: 1
+ source: 10.255.2.10
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.10) - Destination: pod2-leaf8b Loopback0 (IP: 10.255.2.20)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf3b
+ hosts:
+ - destination: 10.255.2.21
+ repeat: 1
+ source: 10.255.2.10
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.10) - Destination: pod2-leaf9a Loopback0 (IP: 10.255.2.21)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf3b
+ hosts:
+ - destination: 10.255.2.22
+ repeat: 1
+ source: 10.255.2.10
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.10) - Destination: pod2-leaf9b Loopback0 (IP: 10.255.2.22)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf3b
+ hosts:
+ - destination: 10.255.2.23
+ repeat: 1
+ source: 10.255.2.10
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.10) - Destination: pod2-leaf10a Loopback0 (IP: 10.255.2.23)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf3b
+ hosts:
+ - destination: 10.255.2.24
+ repeat: 1
+ source: 10.255.2.10
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.10) - Destination: pod2-leaf10b Loopback0 (IP: 10.255.2.24)'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-leaf4b
+ neighbors:
+ - neighbor_device: pod2-leaf4a
+ neighbor_port: Ethernet53/1
+ port: Ethernet53/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet53/1 - Remote: pod2-leaf4a Ethernet53/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-leaf4b
+ neighbors:
+ - neighbor_device: pod2-leaf4a
+ neighbor_port: Ethernet54/1
+ port: Ethernet54/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet54/1 - Remote: pod2-leaf4a Ethernet54/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-leaf4b
+ neighbors:
+ - neighbor_device: pod2-spine1
+ neighbor_port: Ethernet8/1
+ port: Ethernet1/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet1/1 - Remote: pod2-spine1 Ethernet8/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-leaf4b
+ neighbors:
+ - neighbor_device: pod2-spine2
+ neighbor_port: Ethernet8/1
+ port: Ethernet2/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet2/1 - Remote: pod2-spine2 Ethernet8/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-leaf4b
+ neighbors:
+ - neighbor_device: pod2-spine3
+ neighbor_port: Ethernet8/1
+ port: Ethernet3/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet3/1 - Remote: pod2-spine3 Ethernet8/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-leaf4b
+ neighbors:
+ - neighbor_device: pod2-spine4
+ neighbor_port: Ethernet8/1
+ port: Ethernet4/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet4/1 - Remote: pod2-spine4 Ethernet8/1'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf4b
+ hosts:
+ - destination: 10.255.255.56
+ repeat: 1
+ source: 10.255.255.57
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet1/1 (IP: 10.255.255.57) - Destination: pod2-spine1 Ethernet8/1 (IP: 10.255.255.56)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf4b
+ hosts:
+ - destination: 10.255.255.58
+ repeat: 1
+ source: 10.255.255.59
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet2/1 (IP: 10.255.255.59) - Destination: pod2-spine2 Ethernet8/1 (IP: 10.255.255.58)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf4b
+ hosts:
+ - destination: 10.255.255.60
+ repeat: 1
+ source: 10.255.255.61
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet3/1 (IP: 10.255.255.61) - Destination: pod2-spine3 Ethernet8/1 (IP: 10.255.255.60)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf4b
+ hosts:
+ - destination: 10.255.255.62
+ repeat: 1
+ source: 10.255.255.63
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet4/1 (IP: 10.255.255.63) - Destination: pod2-spine4 Ethernet8/1 (IP: 10.255.255.62)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf4b
+ hosts:
+ - destination: 10.255.0.1
+ repeat: 1
+ source: 10.255.2.12
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.12) - Destination: super-spine1 Loopback0 (IP: 10.255.0.1)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf4b
+ hosts:
+ - destination: 10.255.0.2
+ repeat: 1
+ source: 10.255.2.12
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.12) - Destination: super-spine2 Loopback0 (IP: 10.255.0.2)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf4b
+ hosts:
+ - destination: 10.255.1.1
+ repeat: 1
+ source: 10.255.2.12
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.12) - Destination: pod1-spine1 Loopback0 (IP: 10.255.1.1)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf4b
+ hosts:
+ - destination: 10.255.1.2
+ repeat: 1
+ source: 10.255.2.12
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.12) - Destination: pod1-spine2 Loopback0 (IP: 10.255.1.2)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf4b
+ hosts:
+ - destination: 10.255.1.3
+ repeat: 1
+ source: 10.255.2.12
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.12) - Destination: pod1-spine3 Loopback0 (IP: 10.255.1.3)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf4b
+ hosts:
+ - destination: 10.255.1.4
+ repeat: 1
+ source: 10.255.2.12
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.12) - Destination: pod1-spine4 Loopback0 (IP: 10.255.1.4)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf4b
+ hosts:
+ - destination: 10.255.1.5
+ repeat: 1
+ source: 10.255.2.12
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.12) - Destination: pod1-leaf1a Loopback0 (IP: 10.255.1.5)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf4b
+ hosts:
+ - destination: 10.255.1.6
+ repeat: 1
+ source: 10.255.2.12
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.12) - Destination: pod1-leaf1b Loopback0 (IP: 10.255.1.6)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf4b
+ hosts:
+ - destination: 10.255.1.7
+ repeat: 1
+ source: 10.255.2.12
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.12) - Destination: pod1-leaf2a Loopback0 (IP: 10.255.1.7)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf4b
+ hosts:
+ - destination: 10.255.1.8
+ repeat: 1
+ source: 10.255.2.12
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.12) - Destination: pod1-leaf2b Loopback0 (IP: 10.255.1.8)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf4b
+ hosts:
+ - destination: 10.255.1.9
+ repeat: 1
+ source: 10.255.2.12
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.12) - Destination: pod1-leaf3a Loopback0 (IP: 10.255.1.9)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf4b
+ hosts:
+ - destination: 10.255.1.10
+ repeat: 1
+ source: 10.255.2.12
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.12) - Destination: pod1-leaf3b Loopback0 (IP: 10.255.1.10)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf4b
+ hosts:
+ - destination: 10.255.1.11
+ repeat: 1
+ source: 10.255.2.12
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.12) - Destination: pod1-leaf4a Loopback0 (IP: 10.255.1.11)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf4b
+ hosts:
+ - destination: 10.255.1.12
+ repeat: 1
+ source: 10.255.2.12
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.12) - Destination: pod1-leaf4b Loopback0 (IP: 10.255.1.12)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf4b
+ hosts:
+ - destination: 10.255.1.13
+ repeat: 1
+ source: 10.255.2.12
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.12) - Destination: pod1-leaf5a Loopback0 (IP: 10.255.1.13)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf4b
+ hosts:
+ - destination: 10.255.1.14
+ repeat: 1
+ source: 10.255.2.12
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.12) - Destination: pod1-leaf5b Loopback0 (IP: 10.255.1.14)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf4b
+ hosts:
+ - destination: 10.255.1.15
+ repeat: 1
+ source: 10.255.2.12
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.12) - Destination: pod1-leaf6a Loopback0 (IP: 10.255.1.15)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf4b
+ hosts:
+ - destination: 10.255.1.16
+ repeat: 1
+ source: 10.255.2.12
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.12) - Destination: pod1-leaf6b Loopback0 (IP: 10.255.1.16)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf4b
+ hosts:
+ - destination: 10.255.1.17
+ repeat: 1
+ source: 10.255.2.12
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.12) - Destination: pod1-leaf7a Loopback0 (IP: 10.255.1.17)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf4b
+ hosts:
+ - destination: 10.255.1.18
+ repeat: 1
+ source: 10.255.2.12
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.12) - Destination: pod1-leaf7b Loopback0 (IP: 10.255.1.18)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf4b
+ hosts:
+ - destination: 10.255.1.19
+ repeat: 1
+ source: 10.255.2.12
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.12) - Destination: pod1-leaf8a Loopback0 (IP: 10.255.1.19)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf4b
+ hosts:
+ - destination: 10.255.1.20
+ repeat: 1
+ source: 10.255.2.12
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.12) - Destination: pod1-leaf8b Loopback0 (IP: 10.255.1.20)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf4b
+ hosts:
+ - destination: 10.255.1.21
+ repeat: 1
+ source: 10.255.2.12
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.12) - Destination: pod1-leaf9a Loopback0 (IP: 10.255.1.21)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf4b
+ hosts:
+ - destination: 10.255.1.22
+ repeat: 1
+ source: 10.255.2.12
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.12) - Destination: pod1-leaf9b Loopback0 (IP: 10.255.1.22)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf4b
+ hosts:
+ - destination: 10.255.1.23
+ repeat: 1
+ source: 10.255.2.12
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.12) - Destination: pod1-leaf10a Loopback0 (IP: 10.255.1.23)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf4b
+ hosts:
+ - destination: 10.255.1.24
+ repeat: 1
+ source: 10.255.2.12
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.12) - Destination: pod1-leaf10b Loopback0 (IP: 10.255.1.24)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf4b
+ hosts:
+ - destination: 10.255.2.1
+ repeat: 1
+ source: 10.255.2.12
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.12) - Destination: pod2-spine1 Loopback0 (IP: 10.255.2.1)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf4b
+ hosts:
+ - destination: 10.255.2.2
+ repeat: 1
+ source: 10.255.2.12
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.12) - Destination: pod2-spine2 Loopback0 (IP: 10.255.2.2)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf4b
+ hosts:
+ - destination: 10.255.2.3
+ repeat: 1
+ source: 10.255.2.12
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.12) - Destination: pod2-spine3 Loopback0 (IP: 10.255.2.3)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf4b
+ hosts:
+ - destination: 10.255.2.4
+ repeat: 1
+ source: 10.255.2.12
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.12) - Destination: pod2-spine4 Loopback0 (IP: 10.255.2.4)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf4b
+ hosts:
+ - destination: 10.255.2.5
+ repeat: 1
+ source: 10.255.2.12
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.12) - Destination: pod2-leaf1a Loopback0 (IP: 10.255.2.5)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf4b
+ hosts:
+ - destination: 10.255.2.6
+ repeat: 1
+ source: 10.255.2.12
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.12) - Destination: pod2-leaf1b Loopback0 (IP: 10.255.2.6)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf4b
+ hosts:
+ - destination: 10.255.2.7
+ repeat: 1
+ source: 10.255.2.12
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.12) - Destination: pod2-leaf2a Loopback0 (IP: 10.255.2.7)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf4b
+ hosts:
+ - destination: 10.255.2.8
+ repeat: 1
+ source: 10.255.2.12
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.12) - Destination: pod2-leaf2b Loopback0 (IP: 10.255.2.8)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf4b
+ hosts:
+ - destination: 10.255.2.9
+ repeat: 1
+ source: 10.255.2.12
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.12) - Destination: pod2-leaf3a Loopback0 (IP: 10.255.2.9)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf4b
+ hosts:
+ - destination: 10.255.2.10
+ repeat: 1
+ source: 10.255.2.12
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.12) - Destination: pod2-leaf3b Loopback0 (IP: 10.255.2.10)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf4b
+ hosts:
+ - destination: 10.255.2.11
+ repeat: 1
+ source: 10.255.2.12
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.12) - Destination: pod2-leaf4a Loopback0 (IP: 10.255.2.11)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf4b
+ hosts:
+ - destination: 10.255.2.12
+ repeat: 1
+ source: 10.255.2.12
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.12) - Destination: pod2-leaf4b Loopback0 (IP: 10.255.2.12)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf4b
+ hosts:
+ - destination: 10.255.2.13
+ repeat: 1
+ source: 10.255.2.12
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.12) - Destination: pod2-leaf5a Loopback0 (IP: 10.255.2.13)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf4b
+ hosts:
+ - destination: 10.255.2.14
+ repeat: 1
+ source: 10.255.2.12
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.12) - Destination: pod2-leaf5b Loopback0 (IP: 10.255.2.14)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf4b
+ hosts:
+ - destination: 10.255.2.15
+ repeat: 1
+ source: 10.255.2.12
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.12) - Destination: pod2-leaf6a Loopback0 (IP: 10.255.2.15)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf4b
+ hosts:
+ - destination: 10.255.2.16
+ repeat: 1
+ source: 10.255.2.12
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.12) - Destination: pod2-leaf6b Loopback0 (IP: 10.255.2.16)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf4b
+ hosts:
+ - destination: 10.255.2.17
+ repeat: 1
+ source: 10.255.2.12
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.12) - Destination: pod2-leaf7a Loopback0 (IP: 10.255.2.17)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf4b
+ hosts:
+ - destination: 10.255.2.18
+ repeat: 1
+ source: 10.255.2.12
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.12) - Destination: pod2-leaf7b Loopback0 (IP: 10.255.2.18)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf4b
+ hosts:
+ - destination: 10.255.2.19
+ repeat: 1
+ source: 10.255.2.12
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.12) - Destination: pod2-leaf8a Loopback0 (IP: 10.255.2.19)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf4b
+ hosts:
+ - destination: 10.255.2.20
+ repeat: 1
+ source: 10.255.2.12
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.12) - Destination: pod2-leaf8b Loopback0 (IP: 10.255.2.20)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf4b
+ hosts:
+ - destination: 10.255.2.21
+ repeat: 1
+ source: 10.255.2.12
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.12) - Destination: pod2-leaf9a Loopback0 (IP: 10.255.2.21)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf4b
+ hosts:
+ - destination: 10.255.2.22
+ repeat: 1
+ source: 10.255.2.12
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.12) - Destination: pod2-leaf9b Loopback0 (IP: 10.255.2.22)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf4b
+ hosts:
+ - destination: 10.255.2.23
+ repeat: 1
+ source: 10.255.2.12
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.12) - Destination: pod2-leaf10a Loopback0 (IP: 10.255.2.23)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf4b
+ hosts:
+ - destination: 10.255.2.24
+ repeat: 1
+ source: 10.255.2.12
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.12) - Destination: pod2-leaf10b Loopback0 (IP: 10.255.2.24)'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-spine1
+ neighbors:
+ - neighbor_device: pod1-leaf1a
+ neighbor_port: Ethernet1/1
+ port: Ethernet1/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet1/1 - Remote: pod1-leaf1a Ethernet1/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-spine1
+ neighbors:
+ - neighbor_device: pod1-leaf1b
+ neighbor_port: Ethernet1/1
+ port: Ethernet2/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet2/1 - Remote: pod1-leaf1b Ethernet1/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-spine1
+ neighbors:
+ - neighbor_device: pod1-leaf2a
+ neighbor_port: Ethernet1/1
+ port: Ethernet3/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet3/1 - Remote: pod1-leaf2a Ethernet1/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-spine1
+ neighbors:
+ - neighbor_device: pod1-leaf2b
+ neighbor_port: Ethernet1/1
+ port: Ethernet4/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet4/1 - Remote: pod1-leaf2b Ethernet1/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-spine1
+ neighbors:
+ - neighbor_device: pod1-leaf3a
+ neighbor_port: Ethernet1/1
+ port: Ethernet5/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet5/1 - Remote: pod1-leaf3a Ethernet1/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-spine1
+ neighbors:
+ - neighbor_device: pod1-leaf3b
+ neighbor_port: Ethernet1/1
+ port: Ethernet6/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet6/1 - Remote: pod1-leaf3b Ethernet1/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-spine1
+ neighbors:
+ - neighbor_device: pod1-leaf4a
+ neighbor_port: Ethernet1/1
+ port: Ethernet7/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet7/1 - Remote: pod1-leaf4a Ethernet1/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-spine1
+ neighbors:
+ - neighbor_device: pod1-leaf4b
+ neighbor_port: Ethernet1/1
+ port: Ethernet8/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet8/1 - Remote: pod1-leaf4b Ethernet1/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-spine1
+ neighbors:
+ - neighbor_device: pod1-leaf5a
+ neighbor_port: Ethernet1/1
+ port: Ethernet9/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet9/1 - Remote: pod1-leaf5a Ethernet1/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-spine1
+ neighbors:
+ - neighbor_device: pod1-leaf5b
+ neighbor_port: Ethernet1/1
+ port: Ethernet10/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet10/1 - Remote: pod1-leaf5b Ethernet1/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-spine1
+ neighbors:
+ - neighbor_device: pod1-leaf6a
+ neighbor_port: Ethernet1/1
+ port: Ethernet11/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet11/1 - Remote: pod1-leaf6a Ethernet1/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-spine1
+ neighbors:
+ - neighbor_device: pod1-leaf6b
+ neighbor_port: Ethernet1/1
+ port: Ethernet12/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet12/1 - Remote: pod1-leaf6b Ethernet1/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-spine1
+ neighbors:
+ - neighbor_device: pod1-leaf7a
+ neighbor_port: Ethernet1/1
+ port: Ethernet13/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet13/1 - Remote: pod1-leaf7a Ethernet1/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-spine1
+ neighbors:
+ - neighbor_device: pod1-leaf7b
+ neighbor_port: Ethernet1/1
+ port: Ethernet14/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet14/1 - Remote: pod1-leaf7b Ethernet1/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-spine1
+ neighbors:
+ - neighbor_device: pod1-leaf8a
+ neighbor_port: Ethernet1/1
+ port: Ethernet15/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet15/1 - Remote: pod1-leaf8a Ethernet1/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-spine1
+ neighbors:
+ - neighbor_device: pod1-leaf8b
+ neighbor_port: Ethernet1/1
+ port: Ethernet16/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet16/1 - Remote: pod1-leaf8b Ethernet1/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-spine1
+ neighbors:
+ - neighbor_device: pod1-leaf9a
+ neighbor_port: Ethernet1/1
+ port: Ethernet17/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet17/1 - Remote: pod1-leaf9a Ethernet1/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-spine1
+ neighbors:
+ - neighbor_device: pod1-leaf9b
+ neighbor_port: Ethernet1/1
+ port: Ethernet18/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet18/1 - Remote: pod1-leaf9b Ethernet1/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-spine1
+ neighbors:
+ - neighbor_device: pod1-leaf10a
+ neighbor_port: Ethernet1/1
+ port: Ethernet19/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet19/1 - Remote: pod1-leaf10a Ethernet1/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-spine1
+ neighbors:
+ - neighbor_device: pod1-leaf10b
+ neighbor_port: Ethernet1/1
+ port: Ethernet20/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet20/1 - Remote: pod1-leaf10b Ethernet1/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-spine1
+ neighbors:
+ - neighbor_device: super-spine1
+ neighbor_port: Ethernet1/1
+ port: Ethernet31/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet31/1 - Remote: super-spine1 Ethernet1/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-spine1
+ neighbors:
+ - neighbor_device: super-spine2
+ neighbor_port: Ethernet1/1
+ port: Ethernet32/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet32/1 - Remote: super-spine2 Ethernet1/1'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-spine1
+ hosts:
+ - destination: 10.255.255.1
+ repeat: 1
+ source: 10.255.255.0
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet1/1 (IP: 10.255.255.0) - Destination: pod1-leaf1a Ethernet1/1 (IP: 10.255.255.1)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-spine1
+ hosts:
+ - destination: 10.255.255.9
+ repeat: 1
+ source: 10.255.255.8
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet2/1 (IP: 10.255.255.8) - Destination: pod1-leaf1b Ethernet1/1 (IP: 10.255.255.9)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-spine1
+ hosts:
+ - destination: 10.255.255.17
+ repeat: 1
+ source: 10.255.255.16
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet3/1 (IP: 10.255.255.16) - Destination: pod1-leaf2a Ethernet1/1 (IP: 10.255.255.17)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-spine1
+ hosts:
+ - destination: 10.255.255.25
+ repeat: 1
+ source: 10.255.255.24
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet4/1 (IP: 10.255.255.24) - Destination: pod1-leaf2b Ethernet1/1 (IP: 10.255.255.25)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-spine1
+ hosts:
+ - destination: 10.255.255.33
+ repeat: 1
+ source: 10.255.255.32
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet5/1 (IP: 10.255.255.32) - Destination: pod1-leaf3a Ethernet1/1 (IP: 10.255.255.33)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-spine1
+ hosts:
+ - destination: 10.255.255.41
+ repeat: 1
+ source: 10.255.255.40
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet6/1 (IP: 10.255.255.40) - Destination: pod1-leaf3b Ethernet1/1 (IP: 10.255.255.41)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-spine1
+ hosts:
+ - destination: 10.255.255.49
+ repeat: 1
+ source: 10.255.255.48
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet7/1 (IP: 10.255.255.48) - Destination: pod1-leaf4a Ethernet1/1 (IP: 10.255.255.49)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-spine1
+ hosts:
+ - destination: 10.255.255.57
+ repeat: 1
+ source: 10.255.255.56
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet8/1 (IP: 10.255.255.56) - Destination: pod1-leaf4b Ethernet1/1 (IP: 10.255.255.57)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-spine1
+ hosts:
+ - destination: 10.255.255.65
+ repeat: 1
+ source: 10.255.255.64
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet9/1 (IP: 10.255.255.64) - Destination: pod1-leaf5a Ethernet1/1 (IP: 10.255.255.65)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-spine1
+ hosts:
+ - destination: 10.255.255.73
+ repeat: 1
+ source: 10.255.255.72
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet10/1 (IP: 10.255.255.72) - Destination: pod1-leaf5b Ethernet1/1 (IP: 10.255.255.73)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-spine1
+ hosts:
+ - destination: 10.255.255.81
+ repeat: 1
+ source: 10.255.255.80
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet11/1 (IP: 10.255.255.80) - Destination: pod1-leaf6a Ethernet1/1 (IP: 10.255.255.81)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-spine1
+ hosts:
+ - destination: 10.255.255.89
+ repeat: 1
+ source: 10.255.255.88
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet12/1 (IP: 10.255.255.88) - Destination: pod1-leaf6b Ethernet1/1 (IP: 10.255.255.89)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-spine1
+ hosts:
+ - destination: 10.255.255.97
+ repeat: 1
+ source: 10.255.255.96
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet13/1 (IP: 10.255.255.96) - Destination: pod1-leaf7a Ethernet1/1 (IP: 10.255.255.97)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-spine1
+ hosts:
+ - destination: 10.255.255.105
+ repeat: 1
+ source: 10.255.255.104
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet14/1 (IP: 10.255.255.104) - Destination: pod1-leaf7b Ethernet1/1 (IP: 10.255.255.105)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-spine1
+ hosts:
+ - destination: 10.255.255.113
+ repeat: 1
+ source: 10.255.255.112
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet15/1 (IP: 10.255.255.112) - Destination: pod1-leaf8a Ethernet1/1 (IP: 10.255.255.113)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-spine1
+ hosts:
+ - destination: 10.255.255.121
+ repeat: 1
+ source: 10.255.255.120
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet16/1 (IP: 10.255.255.120) - Destination: pod1-leaf8b Ethernet1/1 (IP: 10.255.255.121)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-spine1
+ hosts:
+ - destination: 10.255.255.129
+ repeat: 1
+ source: 10.255.255.128
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet17/1 (IP: 10.255.255.128) - Destination: pod1-leaf9a Ethernet1/1 (IP: 10.255.255.129)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-spine1
+ hosts:
+ - destination: 10.255.255.137
+ repeat: 1
+ source: 10.255.255.136
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet18/1 (IP: 10.255.255.136) - Destination: pod1-leaf9b Ethernet1/1 (IP: 10.255.255.137)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-spine1
+ hosts:
+ - destination: 10.255.255.145
+ repeat: 1
+ source: 10.255.255.144
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet19/1 (IP: 10.255.255.144) - Destination: pod1-leaf10a Ethernet1/1 (IP: 10.255.255.145)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-spine1
+ hosts:
+ - destination: 10.255.255.153
+ repeat: 1
+ source: 10.255.255.152
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet20/1 (IP: 10.255.255.152) - Destination: pod1-leaf10b Ethernet1/1 (IP: 10.255.255.153)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-spine1
+ hosts:
+ - destination: 10.255.255.0
+ repeat: 1
+ source: 10.255.255.1
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet31/1 (IP: 10.255.255.1) - Destination: super-spine1 Ethernet1/1 (IP: 10.255.255.0)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-spine1
+ hosts:
+ - destination: 10.255.255.2
+ repeat: 1
+ source: 10.255.255.3
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet32/1 (IP: 10.255.255.3) - Destination: super-spine2 Ethernet1/1 (IP: 10.255.255.2)'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-leaf9a
+ neighbors:
+ - neighbor_device: pod2-leaf9b
+ neighbor_port: Ethernet53/1
+ port: Ethernet53/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet53/1 - Remote: pod2-leaf9b Ethernet53/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-leaf9a
+ neighbors:
+ - neighbor_device: pod2-leaf9b
+ neighbor_port: Ethernet54/1
+ port: Ethernet54/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet54/1 - Remote: pod2-leaf9b Ethernet54/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-leaf9a
+ neighbors:
+ - neighbor_device: pod2-spine1
+ neighbor_port: Ethernet17/1
+ port: Ethernet1/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet1/1 - Remote: pod2-spine1 Ethernet17/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-leaf9a
+ neighbors:
+ - neighbor_device: pod2-spine2
+ neighbor_port: Ethernet17/1
+ port: Ethernet2/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet2/1 - Remote: pod2-spine2 Ethernet17/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-leaf9a
+ neighbors:
+ - neighbor_device: pod2-spine3
+ neighbor_port: Ethernet17/1
+ port: Ethernet3/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet3/1 - Remote: pod2-spine3 Ethernet17/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-leaf9a
+ neighbors:
+ - neighbor_device: pod2-spine4
+ neighbor_port: Ethernet17/1
+ port: Ethernet4/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet4/1 - Remote: pod2-spine4 Ethernet17/1'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf9a
+ hosts:
+ - destination: 10.255.255.128
+ repeat: 1
+ source: 10.255.255.129
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet1/1 (IP: 10.255.255.129) - Destination: pod2-spine1 Ethernet17/1 (IP: 10.255.255.128)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf9a
+ hosts:
+ - destination: 10.255.255.130
+ repeat: 1
+ source: 10.255.255.131
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet2/1 (IP: 10.255.255.131) - Destination: pod2-spine2 Ethernet17/1 (IP: 10.255.255.130)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf9a
+ hosts:
+ - destination: 10.255.255.132
+ repeat: 1
+ source: 10.255.255.133
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet3/1 (IP: 10.255.255.133) - Destination: pod2-spine3 Ethernet17/1 (IP: 10.255.255.132)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf9a
+ hosts:
+ - destination: 10.255.255.134
+ repeat: 1
+ source: 10.255.255.135
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet4/1 (IP: 10.255.255.135) - Destination: pod2-spine4 Ethernet17/1 (IP: 10.255.255.134)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf9a
+ hosts:
+ - destination: 10.255.0.1
+ repeat: 1
+ source: 10.255.2.21
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.21) - Destination: super-spine1 Loopback0 (IP: 10.255.0.1)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf9a
+ hosts:
+ - destination: 10.255.0.2
+ repeat: 1
+ source: 10.255.2.21
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.21) - Destination: super-spine2 Loopback0 (IP: 10.255.0.2)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf9a
+ hosts:
+ - destination: 10.255.1.1
+ repeat: 1
+ source: 10.255.2.21
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.21) - Destination: pod1-spine1 Loopback0 (IP: 10.255.1.1)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf9a
+ hosts:
+ - destination: 10.255.1.2
+ repeat: 1
+ source: 10.255.2.21
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.21) - Destination: pod1-spine2 Loopback0 (IP: 10.255.1.2)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf9a
+ hosts:
+ - destination: 10.255.1.3
+ repeat: 1
+ source: 10.255.2.21
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.21) - Destination: pod1-spine3 Loopback0 (IP: 10.255.1.3)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf9a
+ hosts:
+ - destination: 10.255.1.4
+ repeat: 1
+ source: 10.255.2.21
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.21) - Destination: pod1-spine4 Loopback0 (IP: 10.255.1.4)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf9a
+ hosts:
+ - destination: 10.255.1.5
+ repeat: 1
+ source: 10.255.2.21
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.21) - Destination: pod1-leaf1a Loopback0 (IP: 10.255.1.5)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf9a
+ hosts:
+ - destination: 10.255.1.6
+ repeat: 1
+ source: 10.255.2.21
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.21) - Destination: pod1-leaf1b Loopback0 (IP: 10.255.1.6)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf9a
+ hosts:
+ - destination: 10.255.1.7
+ repeat: 1
+ source: 10.255.2.21
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.21) - Destination: pod1-leaf2a Loopback0 (IP: 10.255.1.7)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf9a
+ hosts:
+ - destination: 10.255.1.8
+ repeat: 1
+ source: 10.255.2.21
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.21) - Destination: pod1-leaf2b Loopback0 (IP: 10.255.1.8)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf9a
+ hosts:
+ - destination: 10.255.1.9
+ repeat: 1
+ source: 10.255.2.21
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.21) - Destination: pod1-leaf3a Loopback0 (IP: 10.255.1.9)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf9a
+ hosts:
+ - destination: 10.255.1.10
+ repeat: 1
+ source: 10.255.2.21
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.21) - Destination: pod1-leaf3b Loopback0 (IP: 10.255.1.10)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf9a
+ hosts:
+ - destination: 10.255.1.11
+ repeat: 1
+ source: 10.255.2.21
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.21) - Destination: pod1-leaf4a Loopback0 (IP: 10.255.1.11)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf9a
+ hosts:
+ - destination: 10.255.1.12
+ repeat: 1
+ source: 10.255.2.21
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.21) - Destination: pod1-leaf4b Loopback0 (IP: 10.255.1.12)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf9a
+ hosts:
+ - destination: 10.255.1.13
+ repeat: 1
+ source: 10.255.2.21
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.21) - Destination: pod1-leaf5a Loopback0 (IP: 10.255.1.13)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf9a
+ hosts:
+ - destination: 10.255.1.14
+ repeat: 1
+ source: 10.255.2.21
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.21) - Destination: pod1-leaf5b Loopback0 (IP: 10.255.1.14)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf9a
+ hosts:
+ - destination: 10.255.1.15
+ repeat: 1
+ source: 10.255.2.21
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.21) - Destination: pod1-leaf6a Loopback0 (IP: 10.255.1.15)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf9a
+ hosts:
+ - destination: 10.255.1.16
+ repeat: 1
+ source: 10.255.2.21
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.21) - Destination: pod1-leaf6b Loopback0 (IP: 10.255.1.16)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf9a
+ hosts:
+ - destination: 10.255.1.17
+ repeat: 1
+ source: 10.255.2.21
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.21) - Destination: pod1-leaf7a Loopback0 (IP: 10.255.1.17)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf9a
+ hosts:
+ - destination: 10.255.1.18
+ repeat: 1
+ source: 10.255.2.21
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.21) - Destination: pod1-leaf7b Loopback0 (IP: 10.255.1.18)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf9a
+ hosts:
+ - destination: 10.255.1.19
+ repeat: 1
+ source: 10.255.2.21
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.21) - Destination: pod1-leaf8a Loopback0 (IP: 10.255.1.19)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf9a
+ hosts:
+ - destination: 10.255.1.20
+ repeat: 1
+ source: 10.255.2.21
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.21) - Destination: pod1-leaf8b Loopback0 (IP: 10.255.1.20)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf9a
+ hosts:
+ - destination: 10.255.1.21
+ repeat: 1
+ source: 10.255.2.21
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.21) - Destination: pod1-leaf9a Loopback0 (IP: 10.255.1.21)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf9a
+ hosts:
+ - destination: 10.255.1.22
+ repeat: 1
+ source: 10.255.2.21
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.21) - Destination: pod1-leaf9b Loopback0 (IP: 10.255.1.22)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf9a
+ hosts:
+ - destination: 10.255.1.23
+ repeat: 1
+ source: 10.255.2.21
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.21) - Destination: pod1-leaf10a Loopback0 (IP: 10.255.1.23)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf9a
+ hosts:
+ - destination: 10.255.1.24
+ repeat: 1
+ source: 10.255.2.21
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.21) - Destination: pod1-leaf10b Loopback0 (IP: 10.255.1.24)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf9a
+ hosts:
+ - destination: 10.255.2.1
+ repeat: 1
+ source: 10.255.2.21
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.21) - Destination: pod2-spine1 Loopback0 (IP: 10.255.2.1)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf9a
+ hosts:
+ - destination: 10.255.2.2
+ repeat: 1
+ source: 10.255.2.21
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.21) - Destination: pod2-spine2 Loopback0 (IP: 10.255.2.2)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf9a
+ hosts:
+ - destination: 10.255.2.3
+ repeat: 1
+ source: 10.255.2.21
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.21) - Destination: pod2-spine3 Loopback0 (IP: 10.255.2.3)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf9a
+ hosts:
+ - destination: 10.255.2.4
+ repeat: 1
+ source: 10.255.2.21
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.21) - Destination: pod2-spine4 Loopback0 (IP: 10.255.2.4)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf9a
+ hosts:
+ - destination: 10.255.2.5
+ repeat: 1
+ source: 10.255.2.21
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.21) - Destination: pod2-leaf1a Loopback0 (IP: 10.255.2.5)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf9a
+ hosts:
+ - destination: 10.255.2.6
+ repeat: 1
+ source: 10.255.2.21
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.21) - Destination: pod2-leaf1b Loopback0 (IP: 10.255.2.6)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf9a
+ hosts:
+ - destination: 10.255.2.7
+ repeat: 1
+ source: 10.255.2.21
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.21) - Destination: pod2-leaf2a Loopback0 (IP: 10.255.2.7)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf9a
+ hosts:
+ - destination: 10.255.2.8
+ repeat: 1
+ source: 10.255.2.21
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.21) - Destination: pod2-leaf2b Loopback0 (IP: 10.255.2.8)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf9a
+ hosts:
+ - destination: 10.255.2.9
+ repeat: 1
+ source: 10.255.2.21
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.21) - Destination: pod2-leaf3a Loopback0 (IP: 10.255.2.9)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf9a
+ hosts:
+ - destination: 10.255.2.10
+ repeat: 1
+ source: 10.255.2.21
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.21) - Destination: pod2-leaf3b Loopback0 (IP: 10.255.2.10)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf9a
+ hosts:
+ - destination: 10.255.2.11
+ repeat: 1
+ source: 10.255.2.21
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.21) - Destination: pod2-leaf4a Loopback0 (IP: 10.255.2.11)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf9a
+ hosts:
+ - destination: 10.255.2.12
+ repeat: 1
+ source: 10.255.2.21
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.21) - Destination: pod2-leaf4b Loopback0 (IP: 10.255.2.12)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf9a
+ hosts:
+ - destination: 10.255.2.13
+ repeat: 1
+ source: 10.255.2.21
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.21) - Destination: pod2-leaf5a Loopback0 (IP: 10.255.2.13)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf9a
+ hosts:
+ - destination: 10.255.2.14
+ repeat: 1
+ source: 10.255.2.21
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.21) - Destination: pod2-leaf5b Loopback0 (IP: 10.255.2.14)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf9a
+ hosts:
+ - destination: 10.255.2.15
+ repeat: 1
+ source: 10.255.2.21
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.21) - Destination: pod2-leaf6a Loopback0 (IP: 10.255.2.15)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf9a
+ hosts:
+ - destination: 10.255.2.16
+ repeat: 1
+ source: 10.255.2.21
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.21) - Destination: pod2-leaf6b Loopback0 (IP: 10.255.2.16)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf9a
+ hosts:
+ - destination: 10.255.2.17
+ repeat: 1
+ source: 10.255.2.21
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.21) - Destination: pod2-leaf7a Loopback0 (IP: 10.255.2.17)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf9a
+ hosts:
+ - destination: 10.255.2.18
+ repeat: 1
+ source: 10.255.2.21
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.21) - Destination: pod2-leaf7b Loopback0 (IP: 10.255.2.18)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf9a
+ hosts:
+ - destination: 10.255.2.19
+ repeat: 1
+ source: 10.255.2.21
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.21) - Destination: pod2-leaf8a Loopback0 (IP: 10.255.2.19)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf9a
+ hosts:
+ - destination: 10.255.2.20
+ repeat: 1
+ source: 10.255.2.21
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.21) - Destination: pod2-leaf8b Loopback0 (IP: 10.255.2.20)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf9a
+ hosts:
+ - destination: 10.255.2.21
+ repeat: 1
+ source: 10.255.2.21
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.21) - Destination: pod2-leaf9a Loopback0 (IP: 10.255.2.21)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf9a
+ hosts:
+ - destination: 10.255.2.22
+ repeat: 1
+ source: 10.255.2.21
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.21) - Destination: pod2-leaf9b Loopback0 (IP: 10.255.2.22)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf9a
+ hosts:
+ - destination: 10.255.2.23
+ repeat: 1
+ source: 10.255.2.21
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.21) - Destination: pod2-leaf10a Loopback0 (IP: 10.255.2.23)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf9a
+ hosts:
+ - destination: 10.255.2.24
+ repeat: 1
+ source: 10.255.2.21
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.21) - Destination: pod2-leaf10b Loopback0 (IP: 10.255.2.24)'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-leaf9b
+ neighbors:
+ - neighbor_device: pod2-leaf9a
+ neighbor_port: Ethernet53/1
+ port: Ethernet53/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet53/1 - Remote: pod2-leaf9a Ethernet53/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-leaf9b
+ neighbors:
+ - neighbor_device: pod2-leaf9a
+ neighbor_port: Ethernet54/1
+ port: Ethernet54/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet54/1 - Remote: pod2-leaf9a Ethernet54/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-leaf9b
+ neighbors:
+ - neighbor_device: pod2-spine1
+ neighbor_port: Ethernet18/1
+ port: Ethernet1/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet1/1 - Remote: pod2-spine1 Ethernet18/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-leaf9b
+ neighbors:
+ - neighbor_device: pod2-spine2
+ neighbor_port: Ethernet18/1
+ port: Ethernet2/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet2/1 - Remote: pod2-spine2 Ethernet18/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-leaf9b
+ neighbors:
+ - neighbor_device: pod2-spine3
+ neighbor_port: Ethernet18/1
+ port: Ethernet3/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet3/1 - Remote: pod2-spine3 Ethernet18/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-leaf9b
+ neighbors:
+ - neighbor_device: pod2-spine4
+ neighbor_port: Ethernet18/1
+ port: Ethernet4/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet4/1 - Remote: pod2-spine4 Ethernet18/1'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf9b
+ hosts:
+ - destination: 10.255.255.136
+ repeat: 1
+ source: 10.255.255.137
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet1/1 (IP: 10.255.255.137) - Destination: pod2-spine1 Ethernet18/1 (IP: 10.255.255.136)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf9b
+ hosts:
+ - destination: 10.255.255.138
+ repeat: 1
+ source: 10.255.255.139
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet2/1 (IP: 10.255.255.139) - Destination: pod2-spine2 Ethernet18/1 (IP: 10.255.255.138)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf9b
+ hosts:
+ - destination: 10.255.255.140
+ repeat: 1
+ source: 10.255.255.141
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet3/1 (IP: 10.255.255.141) - Destination: pod2-spine3 Ethernet18/1 (IP: 10.255.255.140)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf9b
+ hosts:
+ - destination: 10.255.255.142
+ repeat: 1
+ source: 10.255.255.143
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet4/1 (IP: 10.255.255.143) - Destination: pod2-spine4 Ethernet18/1 (IP: 10.255.255.142)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf9b
+ hosts:
+ - destination: 10.255.0.1
+ repeat: 1
+ source: 10.255.2.22
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.22) - Destination: super-spine1 Loopback0 (IP: 10.255.0.1)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf9b
+ hosts:
+ - destination: 10.255.0.2
+ repeat: 1
+ source: 10.255.2.22
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.22) - Destination: super-spine2 Loopback0 (IP: 10.255.0.2)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf9b
+ hosts:
+ - destination: 10.255.1.1
+ repeat: 1
+ source: 10.255.2.22
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.22) - Destination: pod1-spine1 Loopback0 (IP: 10.255.1.1)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf9b
+ hosts:
+ - destination: 10.255.1.2
+ repeat: 1
+ source: 10.255.2.22
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.22) - Destination: pod1-spine2 Loopback0 (IP: 10.255.1.2)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf9b
+ hosts:
+ - destination: 10.255.1.3
+ repeat: 1
+ source: 10.255.2.22
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.22) - Destination: pod1-spine3 Loopback0 (IP: 10.255.1.3)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf9b
+ hosts:
+ - destination: 10.255.1.4
+ repeat: 1
+ source: 10.255.2.22
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.22) - Destination: pod1-spine4 Loopback0 (IP: 10.255.1.4)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf9b
+ hosts:
+ - destination: 10.255.1.5
+ repeat: 1
+ source: 10.255.2.22
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.22) - Destination: pod1-leaf1a Loopback0 (IP: 10.255.1.5)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf9b
+ hosts:
+ - destination: 10.255.1.6
+ repeat: 1
+ source: 10.255.2.22
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.22) - Destination: pod1-leaf1b Loopback0 (IP: 10.255.1.6)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf9b
+ hosts:
+ - destination: 10.255.1.7
+ repeat: 1
+ source: 10.255.2.22
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.22) - Destination: pod1-leaf2a Loopback0 (IP: 10.255.1.7)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf9b
+ hosts:
+ - destination: 10.255.1.8
+ repeat: 1
+ source: 10.255.2.22
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.22) - Destination: pod1-leaf2b Loopback0 (IP: 10.255.1.8)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf9b
+ hosts:
+ - destination: 10.255.1.9
+ repeat: 1
+ source: 10.255.2.22
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.22) - Destination: pod1-leaf3a Loopback0 (IP: 10.255.1.9)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf9b
+ hosts:
+ - destination: 10.255.1.10
+ repeat: 1
+ source: 10.255.2.22
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.22) - Destination: pod1-leaf3b Loopback0 (IP: 10.255.1.10)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf9b
+ hosts:
+ - destination: 10.255.1.11
+ repeat: 1
+ source: 10.255.2.22
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.22) - Destination: pod1-leaf4a Loopback0 (IP: 10.255.1.11)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf9b
+ hosts:
+ - destination: 10.255.1.12
+ repeat: 1
+ source: 10.255.2.22
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.22) - Destination: pod1-leaf4b Loopback0 (IP: 10.255.1.12)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf9b
+ hosts:
+ - destination: 10.255.1.13
+ repeat: 1
+ source: 10.255.2.22
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.22) - Destination: pod1-leaf5a Loopback0 (IP: 10.255.1.13)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf9b
+ hosts:
+ - destination: 10.255.1.14
+ repeat: 1
+ source: 10.255.2.22
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.22) - Destination: pod1-leaf5b Loopback0 (IP: 10.255.1.14)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf9b
+ hosts:
+ - destination: 10.255.1.15
+ repeat: 1
+ source: 10.255.2.22
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.22) - Destination: pod1-leaf6a Loopback0 (IP: 10.255.1.15)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf9b
+ hosts:
+ - destination: 10.255.1.16
+ repeat: 1
+ source: 10.255.2.22
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.22) - Destination: pod1-leaf6b Loopback0 (IP: 10.255.1.16)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf9b
+ hosts:
+ - destination: 10.255.1.17
+ repeat: 1
+ source: 10.255.2.22
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.22) - Destination: pod1-leaf7a Loopback0 (IP: 10.255.1.17)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf9b
+ hosts:
+ - destination: 10.255.1.18
+ repeat: 1
+ source: 10.255.2.22
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.22) - Destination: pod1-leaf7b Loopback0 (IP: 10.255.1.18)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf9b
+ hosts:
+ - destination: 10.255.1.19
+ repeat: 1
+ source: 10.255.2.22
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.22) - Destination: pod1-leaf8a Loopback0 (IP: 10.255.1.19)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf9b
+ hosts:
+ - destination: 10.255.1.20
+ repeat: 1
+ source: 10.255.2.22
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.22) - Destination: pod1-leaf8b Loopback0 (IP: 10.255.1.20)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf9b
+ hosts:
+ - destination: 10.255.1.21
+ repeat: 1
+ source: 10.255.2.22
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.22) - Destination: pod1-leaf9a Loopback0 (IP: 10.255.1.21)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf9b
+ hosts:
+ - destination: 10.255.1.22
+ repeat: 1
+ source: 10.255.2.22
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.22) - Destination: pod1-leaf9b Loopback0 (IP: 10.255.1.22)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf9b
+ hosts:
+ - destination: 10.255.1.23
+ repeat: 1
+ source: 10.255.2.22
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.22) - Destination: pod1-leaf10a Loopback0 (IP: 10.255.1.23)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf9b
+ hosts:
+ - destination: 10.255.1.24
+ repeat: 1
+ source: 10.255.2.22
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.22) - Destination: pod1-leaf10b Loopback0 (IP: 10.255.1.24)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf9b
+ hosts:
+ - destination: 10.255.2.1
+ repeat: 1
+ source: 10.255.2.22
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.22) - Destination: pod2-spine1 Loopback0 (IP: 10.255.2.1)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf9b
+ hosts:
+ - destination: 10.255.2.2
+ repeat: 1
+ source: 10.255.2.22
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.22) - Destination: pod2-spine2 Loopback0 (IP: 10.255.2.2)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf9b
+ hosts:
+ - destination: 10.255.2.3
+ repeat: 1
+ source: 10.255.2.22
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.22) - Destination: pod2-spine3 Loopback0 (IP: 10.255.2.3)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf9b
+ hosts:
+ - destination: 10.255.2.4
+ repeat: 1
+ source: 10.255.2.22
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.22) - Destination: pod2-spine4 Loopback0 (IP: 10.255.2.4)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf9b
+ hosts:
+ - destination: 10.255.2.5
+ repeat: 1
+ source: 10.255.2.22
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.22) - Destination: pod2-leaf1a Loopback0 (IP: 10.255.2.5)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf9b
+ hosts:
+ - destination: 10.255.2.6
+ repeat: 1
+ source: 10.255.2.22
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.22) - Destination: pod2-leaf1b Loopback0 (IP: 10.255.2.6)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf9b
+ hosts:
+ - destination: 10.255.2.7
+ repeat: 1
+ source: 10.255.2.22
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.22) - Destination: pod2-leaf2a Loopback0 (IP: 10.255.2.7)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf9b
+ hosts:
+ - destination: 10.255.2.8
+ repeat: 1
+ source: 10.255.2.22
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.22) - Destination: pod2-leaf2b Loopback0 (IP: 10.255.2.8)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf9b
+ hosts:
+ - destination: 10.255.2.9
+ repeat: 1
+ source: 10.255.2.22
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.22) - Destination: pod2-leaf3a Loopback0 (IP: 10.255.2.9)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf9b
+ hosts:
+ - destination: 10.255.2.10
+ repeat: 1
+ source: 10.255.2.22
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.22) - Destination: pod2-leaf3b Loopback0 (IP: 10.255.2.10)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf9b
+ hosts:
+ - destination: 10.255.2.11
+ repeat: 1
+ source: 10.255.2.22
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.22) - Destination: pod2-leaf4a Loopback0 (IP: 10.255.2.11)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf9b
+ hosts:
+ - destination: 10.255.2.12
+ repeat: 1
+ source: 10.255.2.22
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.22) - Destination: pod2-leaf4b Loopback0 (IP: 10.255.2.12)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf9b
+ hosts:
+ - destination: 10.255.2.13
+ repeat: 1
+ source: 10.255.2.22
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.22) - Destination: pod2-leaf5a Loopback0 (IP: 10.255.2.13)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf9b
+ hosts:
+ - destination: 10.255.2.14
+ repeat: 1
+ source: 10.255.2.22
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.22) - Destination: pod2-leaf5b Loopback0 (IP: 10.255.2.14)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf9b
+ hosts:
+ - destination: 10.255.2.15
+ repeat: 1
+ source: 10.255.2.22
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.22) - Destination: pod2-leaf6a Loopback0 (IP: 10.255.2.15)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf9b
+ hosts:
+ - destination: 10.255.2.16
+ repeat: 1
+ source: 10.255.2.22
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.22) - Destination: pod2-leaf6b Loopback0 (IP: 10.255.2.16)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf9b
+ hosts:
+ - destination: 10.255.2.17
+ repeat: 1
+ source: 10.255.2.22
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.22) - Destination: pod2-leaf7a Loopback0 (IP: 10.255.2.17)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf9b
+ hosts:
+ - destination: 10.255.2.18
+ repeat: 1
+ source: 10.255.2.22
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.22) - Destination: pod2-leaf7b Loopback0 (IP: 10.255.2.18)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf9b
+ hosts:
+ - destination: 10.255.2.19
+ repeat: 1
+ source: 10.255.2.22
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.22) - Destination: pod2-leaf8a Loopback0 (IP: 10.255.2.19)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf9b
+ hosts:
+ - destination: 10.255.2.20
+ repeat: 1
+ source: 10.255.2.22
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.22) - Destination: pod2-leaf8b Loopback0 (IP: 10.255.2.20)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf9b
+ hosts:
+ - destination: 10.255.2.21
+ repeat: 1
+ source: 10.255.2.22
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.22) - Destination: pod2-leaf9a Loopback0 (IP: 10.255.2.21)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf9b
+ hosts:
+ - destination: 10.255.2.22
+ repeat: 1
+ source: 10.255.2.22
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.22) - Destination: pod2-leaf9b Loopback0 (IP: 10.255.2.22)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf9b
+ hosts:
+ - destination: 10.255.2.23
+ repeat: 1
+ source: 10.255.2.22
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.22) - Destination: pod2-leaf10a Loopback0 (IP: 10.255.2.23)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf9b
+ hosts:
+ - destination: 10.255.2.24
+ repeat: 1
+ source: 10.255.2.22
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.22) - Destination: pod2-leaf10b Loopback0 (IP: 10.255.2.24)'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-leaf3a
+ neighbors:
+ - neighbor_device: pod2-leaf3b
+ neighbor_port: Ethernet53/1
+ port: Ethernet53/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet53/1 - Remote: pod2-leaf3b Ethernet53/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-leaf3a
+ neighbors:
+ - neighbor_device: pod2-leaf3b
+ neighbor_port: Ethernet54/1
+ port: Ethernet54/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet54/1 - Remote: pod2-leaf3b Ethernet54/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-leaf3a
+ neighbors:
+ - neighbor_device: pod2-spine1
+ neighbor_port: Ethernet5/1
+ port: Ethernet1/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet1/1 - Remote: pod2-spine1 Ethernet5/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-leaf3a
+ neighbors:
+ - neighbor_device: pod2-spine2
+ neighbor_port: Ethernet5/1
+ port: Ethernet2/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet2/1 - Remote: pod2-spine2 Ethernet5/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-leaf3a
+ neighbors:
+ - neighbor_device: pod2-spine3
+ neighbor_port: Ethernet5/1
+ port: Ethernet3/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet3/1 - Remote: pod2-spine3 Ethernet5/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-leaf3a
+ neighbors:
+ - neighbor_device: pod2-spine4
+ neighbor_port: Ethernet5/1
+ port: Ethernet4/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet4/1 - Remote: pod2-spine4 Ethernet5/1'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf3a
+ hosts:
+ - destination: 10.255.255.32
+ repeat: 1
+ source: 10.255.255.33
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet1/1 (IP: 10.255.255.33) - Destination: pod2-spine1 Ethernet5/1 (IP: 10.255.255.32)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf3a
+ hosts:
+ - destination: 10.255.255.34
+ repeat: 1
+ source: 10.255.255.35
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet2/1 (IP: 10.255.255.35) - Destination: pod2-spine2 Ethernet5/1 (IP: 10.255.255.34)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf3a
+ hosts:
+ - destination: 10.255.255.36
+ repeat: 1
+ source: 10.255.255.37
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet3/1 (IP: 10.255.255.37) - Destination: pod2-spine3 Ethernet5/1 (IP: 10.255.255.36)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf3a
+ hosts:
+ - destination: 10.255.255.38
+ repeat: 1
+ source: 10.255.255.39
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet4/1 (IP: 10.255.255.39) - Destination: pod2-spine4 Ethernet5/1 (IP: 10.255.255.38)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf3a
+ hosts:
+ - destination: 10.255.0.1
+ repeat: 1
+ source: 10.255.2.9
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.9) - Destination: super-spine1 Loopback0 (IP: 10.255.0.1)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf3a
+ hosts:
+ - destination: 10.255.0.2
+ repeat: 1
+ source: 10.255.2.9
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.9) - Destination: super-spine2 Loopback0 (IP: 10.255.0.2)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf3a
+ hosts:
+ - destination: 10.255.1.1
+ repeat: 1
+ source: 10.255.2.9
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.9) - Destination: pod1-spine1 Loopback0 (IP: 10.255.1.1)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf3a
+ hosts:
+ - destination: 10.255.1.2
+ repeat: 1
+ source: 10.255.2.9
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.9) - Destination: pod1-spine2 Loopback0 (IP: 10.255.1.2)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf3a
+ hosts:
+ - destination: 10.255.1.3
+ repeat: 1
+ source: 10.255.2.9
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.9) - Destination: pod1-spine3 Loopback0 (IP: 10.255.1.3)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf3a
+ hosts:
+ - destination: 10.255.1.4
+ repeat: 1
+ source: 10.255.2.9
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.9) - Destination: pod1-spine4 Loopback0 (IP: 10.255.1.4)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf3a
+ hosts:
+ - destination: 10.255.1.5
+ repeat: 1
+ source: 10.255.2.9
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.9) - Destination: pod1-leaf1a Loopback0 (IP: 10.255.1.5)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf3a
+ hosts:
+ - destination: 10.255.1.6
+ repeat: 1
+ source: 10.255.2.9
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.9) - Destination: pod1-leaf1b Loopback0 (IP: 10.255.1.6)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf3a
+ hosts:
+ - destination: 10.255.1.7
+ repeat: 1
+ source: 10.255.2.9
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.9) - Destination: pod1-leaf2a Loopback0 (IP: 10.255.1.7)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf3a
+ hosts:
+ - destination: 10.255.1.8
+ repeat: 1
+ source: 10.255.2.9
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.9) - Destination: pod1-leaf2b Loopback0 (IP: 10.255.1.8)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf3a
+ hosts:
+ - destination: 10.255.1.9
+ repeat: 1
+ source: 10.255.2.9
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.9) - Destination: pod1-leaf3a Loopback0 (IP: 10.255.1.9)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf3a
+ hosts:
+ - destination: 10.255.1.10
+ repeat: 1
+ source: 10.255.2.9
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.9) - Destination: pod1-leaf3b Loopback0 (IP: 10.255.1.10)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf3a
+ hosts:
+ - destination: 10.255.1.11
+ repeat: 1
+ source: 10.255.2.9
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.9) - Destination: pod1-leaf4a Loopback0 (IP: 10.255.1.11)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf3a
+ hosts:
+ - destination: 10.255.1.12
+ repeat: 1
+ source: 10.255.2.9
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.9) - Destination: pod1-leaf4b Loopback0 (IP: 10.255.1.12)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf3a
+ hosts:
+ - destination: 10.255.1.13
+ repeat: 1
+ source: 10.255.2.9
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.9) - Destination: pod1-leaf5a Loopback0 (IP: 10.255.1.13)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf3a
+ hosts:
+ - destination: 10.255.1.14
+ repeat: 1
+ source: 10.255.2.9
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.9) - Destination: pod1-leaf5b Loopback0 (IP: 10.255.1.14)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf3a
+ hosts:
+ - destination: 10.255.1.15
+ repeat: 1
+ source: 10.255.2.9
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.9) - Destination: pod1-leaf6a Loopback0 (IP: 10.255.1.15)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf3a
+ hosts:
+ - destination: 10.255.1.16
+ repeat: 1
+ source: 10.255.2.9
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.9) - Destination: pod1-leaf6b Loopback0 (IP: 10.255.1.16)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf3a
+ hosts:
+ - destination: 10.255.1.17
+ repeat: 1
+ source: 10.255.2.9
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.9) - Destination: pod1-leaf7a Loopback0 (IP: 10.255.1.17)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf3a
+ hosts:
+ - destination: 10.255.1.18
+ repeat: 1
+ source: 10.255.2.9
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.9) - Destination: pod1-leaf7b Loopback0 (IP: 10.255.1.18)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf3a
+ hosts:
+ - destination: 10.255.1.19
+ repeat: 1
+ source: 10.255.2.9
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.9) - Destination: pod1-leaf8a Loopback0 (IP: 10.255.1.19)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf3a
+ hosts:
+ - destination: 10.255.1.20
+ repeat: 1
+ source: 10.255.2.9
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.9) - Destination: pod1-leaf8b Loopback0 (IP: 10.255.1.20)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf3a
+ hosts:
+ - destination: 10.255.1.21
+ repeat: 1
+ source: 10.255.2.9
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.9) - Destination: pod1-leaf9a Loopback0 (IP: 10.255.1.21)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf3a
+ hosts:
+ - destination: 10.255.1.22
+ repeat: 1
+ source: 10.255.2.9
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.9) - Destination: pod1-leaf9b Loopback0 (IP: 10.255.1.22)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf3a
+ hosts:
+ - destination: 10.255.1.23
+ repeat: 1
+ source: 10.255.2.9
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.9) - Destination: pod1-leaf10a Loopback0 (IP: 10.255.1.23)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf3a
+ hosts:
+ - destination: 10.255.1.24
+ repeat: 1
+ source: 10.255.2.9
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.9) - Destination: pod1-leaf10b Loopback0 (IP: 10.255.1.24)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf3a
+ hosts:
+ - destination: 10.255.2.1
+ repeat: 1
+ source: 10.255.2.9
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.9) - Destination: pod2-spine1 Loopback0 (IP: 10.255.2.1)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf3a
+ hosts:
+ - destination: 10.255.2.2
+ repeat: 1
+ source: 10.255.2.9
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.9) - Destination: pod2-spine2 Loopback0 (IP: 10.255.2.2)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf3a
+ hosts:
+ - destination: 10.255.2.3
+ repeat: 1
+ source: 10.255.2.9
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.9) - Destination: pod2-spine3 Loopback0 (IP: 10.255.2.3)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf3a
+ hosts:
+ - destination: 10.255.2.4
+ repeat: 1
+ source: 10.255.2.9
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.9) - Destination: pod2-spine4 Loopback0 (IP: 10.255.2.4)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf3a
+ hosts:
+ - destination: 10.255.2.5
+ repeat: 1
+ source: 10.255.2.9
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.9) - Destination: pod2-leaf1a Loopback0 (IP: 10.255.2.5)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf3a
+ hosts:
+ - destination: 10.255.2.6
+ repeat: 1
+ source: 10.255.2.9
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.9) - Destination: pod2-leaf1b Loopback0 (IP: 10.255.2.6)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf3a
+ hosts:
+ - destination: 10.255.2.7
+ repeat: 1
+ source: 10.255.2.9
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.9) - Destination: pod2-leaf2a Loopback0 (IP: 10.255.2.7)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf3a
+ hosts:
+ - destination: 10.255.2.8
+ repeat: 1
+ source: 10.255.2.9
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.9) - Destination: pod2-leaf2b Loopback0 (IP: 10.255.2.8)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf3a
+ hosts:
+ - destination: 10.255.2.9
+ repeat: 1
+ source: 10.255.2.9
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.9) - Destination: pod2-leaf3a Loopback0 (IP: 10.255.2.9)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf3a
+ hosts:
+ - destination: 10.255.2.10
+ repeat: 1
+ source: 10.255.2.9
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.9) - Destination: pod2-leaf3b Loopback0 (IP: 10.255.2.10)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf3a
+ hosts:
+ - destination: 10.255.2.11
+ repeat: 1
+ source: 10.255.2.9
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.9) - Destination: pod2-leaf4a Loopback0 (IP: 10.255.2.11)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf3a
+ hosts:
+ - destination: 10.255.2.12
+ repeat: 1
+ source: 10.255.2.9
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.9) - Destination: pod2-leaf4b Loopback0 (IP: 10.255.2.12)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf3a
+ hosts:
+ - destination: 10.255.2.13
+ repeat: 1
+ source: 10.255.2.9
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.9) - Destination: pod2-leaf5a Loopback0 (IP: 10.255.2.13)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf3a
+ hosts:
+ - destination: 10.255.2.14
+ repeat: 1
+ source: 10.255.2.9
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.9) - Destination: pod2-leaf5b Loopback0 (IP: 10.255.2.14)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf3a
+ hosts:
+ - destination: 10.255.2.15
+ repeat: 1
+ source: 10.255.2.9
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.9) - Destination: pod2-leaf6a Loopback0 (IP: 10.255.2.15)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf3a
+ hosts:
+ - destination: 10.255.2.16
+ repeat: 1
+ source: 10.255.2.9
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.9) - Destination: pod2-leaf6b Loopback0 (IP: 10.255.2.16)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf3a
+ hosts:
+ - destination: 10.255.2.17
+ repeat: 1
+ source: 10.255.2.9
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.9) - Destination: pod2-leaf7a Loopback0 (IP: 10.255.2.17)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf3a
+ hosts:
+ - destination: 10.255.2.18
+ repeat: 1
+ source: 10.255.2.9
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.9) - Destination: pod2-leaf7b Loopback0 (IP: 10.255.2.18)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf3a
+ hosts:
+ - destination: 10.255.2.19
+ repeat: 1
+ source: 10.255.2.9
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.9) - Destination: pod2-leaf8a Loopback0 (IP: 10.255.2.19)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf3a
+ hosts:
+ - destination: 10.255.2.20
+ repeat: 1
+ source: 10.255.2.9
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.9) - Destination: pod2-leaf8b Loopback0 (IP: 10.255.2.20)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf3a
+ hosts:
+ - destination: 10.255.2.21
+ repeat: 1
+ source: 10.255.2.9
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.9) - Destination: pod2-leaf9a Loopback0 (IP: 10.255.2.21)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf3a
+ hosts:
+ - destination: 10.255.2.22
+ repeat: 1
+ source: 10.255.2.9
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.9) - Destination: pod2-leaf9b Loopback0 (IP: 10.255.2.22)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf3a
+ hosts:
+ - destination: 10.255.2.23
+ repeat: 1
+ source: 10.255.2.9
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.9) - Destination: pod2-leaf10a Loopback0 (IP: 10.255.2.23)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf3a
+ hosts:
+ - destination: 10.255.2.24
+ repeat: 1
+ source: 10.255.2.9
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.9) - Destination: pod2-leaf10b Loopback0 (IP: 10.255.2.24)'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-spine2
+ neighbors:
+ - neighbor_device: pod1-leaf1a
+ neighbor_port: Ethernet2/1
+ port: Ethernet1/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet1/1 - Remote: pod1-leaf1a Ethernet2/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-spine2
+ neighbors:
+ - neighbor_device: pod1-leaf1b
+ neighbor_port: Ethernet2/1
+ port: Ethernet2/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet2/1 - Remote: pod1-leaf1b Ethernet2/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-spine2
+ neighbors:
+ - neighbor_device: pod1-leaf2a
+ neighbor_port: Ethernet2/1
+ port: Ethernet3/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet3/1 - Remote: pod1-leaf2a Ethernet2/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-spine2
+ neighbors:
+ - neighbor_device: pod1-leaf2b
+ neighbor_port: Ethernet2/1
+ port: Ethernet4/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet4/1 - Remote: pod1-leaf2b Ethernet2/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-spine2
+ neighbors:
+ - neighbor_device: pod1-leaf3a
+ neighbor_port: Ethernet2/1
+ port: Ethernet5/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet5/1 - Remote: pod1-leaf3a Ethernet2/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-spine2
+ neighbors:
+ - neighbor_device: pod1-leaf3b
+ neighbor_port: Ethernet2/1
+ port: Ethernet6/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet6/1 - Remote: pod1-leaf3b Ethernet2/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-spine2
+ neighbors:
+ - neighbor_device: pod1-leaf4a
+ neighbor_port: Ethernet2/1
+ port: Ethernet7/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet7/1 - Remote: pod1-leaf4a Ethernet2/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-spine2
+ neighbors:
+ - neighbor_device: pod1-leaf4b
+ neighbor_port: Ethernet2/1
+ port: Ethernet8/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet8/1 - Remote: pod1-leaf4b Ethernet2/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-spine2
+ neighbors:
+ - neighbor_device: pod1-leaf5a
+ neighbor_port: Ethernet2/1
+ port: Ethernet9/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet9/1 - Remote: pod1-leaf5a Ethernet2/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-spine2
+ neighbors:
+ - neighbor_device: pod1-leaf5b
+ neighbor_port: Ethernet2/1
+ port: Ethernet10/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet10/1 - Remote: pod1-leaf5b Ethernet2/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-spine2
+ neighbors:
+ - neighbor_device: pod1-leaf6a
+ neighbor_port: Ethernet2/1
+ port: Ethernet11/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet11/1 - Remote: pod1-leaf6a Ethernet2/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-spine2
+ neighbors:
+ - neighbor_device: pod1-leaf6b
+ neighbor_port: Ethernet2/1
+ port: Ethernet12/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet12/1 - Remote: pod1-leaf6b Ethernet2/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-spine2
+ neighbors:
+ - neighbor_device: pod1-leaf7a
+ neighbor_port: Ethernet2/1
+ port: Ethernet13/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet13/1 - Remote: pod1-leaf7a Ethernet2/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-spine2
+ neighbors:
+ - neighbor_device: pod1-leaf7b
+ neighbor_port: Ethernet2/1
+ port: Ethernet14/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet14/1 - Remote: pod1-leaf7b Ethernet2/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-spine2
+ neighbors:
+ - neighbor_device: pod1-leaf8a
+ neighbor_port: Ethernet2/1
+ port: Ethernet15/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet15/1 - Remote: pod1-leaf8a Ethernet2/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-spine2
+ neighbors:
+ - neighbor_device: pod1-leaf8b
+ neighbor_port: Ethernet2/1
+ port: Ethernet16/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet16/1 - Remote: pod1-leaf8b Ethernet2/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-spine2
+ neighbors:
+ - neighbor_device: pod1-leaf9a
+ neighbor_port: Ethernet2/1
+ port: Ethernet17/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet17/1 - Remote: pod1-leaf9a Ethernet2/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-spine2
+ neighbors:
+ - neighbor_device: pod1-leaf9b
+ neighbor_port: Ethernet2/1
+ port: Ethernet18/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet18/1 - Remote: pod1-leaf9b Ethernet2/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-spine2
+ neighbors:
+ - neighbor_device: pod1-leaf10a
+ neighbor_port: Ethernet2/1
+ port: Ethernet19/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet19/1 - Remote: pod1-leaf10a Ethernet2/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-spine2
+ neighbors:
+ - neighbor_device: pod1-leaf10b
+ neighbor_port: Ethernet2/1
+ port: Ethernet20/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet20/1 - Remote: pod1-leaf10b Ethernet2/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-spine2
+ neighbors:
+ - neighbor_device: super-spine1
+ neighbor_port: Ethernet2/1
+ port: Ethernet31/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet31/1 - Remote: super-spine1 Ethernet2/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-spine2
+ neighbors:
+ - neighbor_device: super-spine2
+ neighbor_port: Ethernet2/1
+ port: Ethernet32/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet32/1 - Remote: super-spine2 Ethernet2/1'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-spine2
+ hosts:
+ - destination: 10.255.255.3
+ repeat: 1
+ source: 10.255.255.2
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet1/1 (IP: 10.255.255.2) - Destination: pod1-leaf1a Ethernet2/1 (IP: 10.255.255.3)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-spine2
+ hosts:
+ - destination: 10.255.255.11
+ repeat: 1
+ source: 10.255.255.10
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet2/1 (IP: 10.255.255.10) - Destination: pod1-leaf1b Ethernet2/1 (IP: 10.255.255.11)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-spine2
+ hosts:
+ - destination: 10.255.255.19
+ repeat: 1
+ source: 10.255.255.18
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet3/1 (IP: 10.255.255.18) - Destination: pod1-leaf2a Ethernet2/1 (IP: 10.255.255.19)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-spine2
+ hosts:
+ - destination: 10.255.255.27
+ repeat: 1
+ source: 10.255.255.26
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet4/1 (IP: 10.255.255.26) - Destination: pod1-leaf2b Ethernet2/1 (IP: 10.255.255.27)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-spine2
+ hosts:
+ - destination: 10.255.255.35
+ repeat: 1
+ source: 10.255.255.34
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet5/1 (IP: 10.255.255.34) - Destination: pod1-leaf3a Ethernet2/1 (IP: 10.255.255.35)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-spine2
+ hosts:
+ - destination: 10.255.255.43
+ repeat: 1
+ source: 10.255.255.42
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet6/1 (IP: 10.255.255.42) - Destination: pod1-leaf3b Ethernet2/1 (IP: 10.255.255.43)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-spine2
+ hosts:
+ - destination: 10.255.255.51
+ repeat: 1
+ source: 10.255.255.50
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet7/1 (IP: 10.255.255.50) - Destination: pod1-leaf4a Ethernet2/1 (IP: 10.255.255.51)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-spine2
+ hosts:
+ - destination: 10.255.255.59
+ repeat: 1
+ source: 10.255.255.58
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet8/1 (IP: 10.255.255.58) - Destination: pod1-leaf4b Ethernet2/1 (IP: 10.255.255.59)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-spine2
+ hosts:
+ - destination: 10.255.255.67
+ repeat: 1
+ source: 10.255.255.66
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet9/1 (IP: 10.255.255.66) - Destination: pod1-leaf5a Ethernet2/1 (IP: 10.255.255.67)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-spine2
+ hosts:
+ - destination: 10.255.255.75
+ repeat: 1
+ source: 10.255.255.74
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet10/1 (IP: 10.255.255.74) - Destination: pod1-leaf5b Ethernet2/1 (IP: 10.255.255.75)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-spine2
+ hosts:
+ - destination: 10.255.255.83
+ repeat: 1
+ source: 10.255.255.82
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet11/1 (IP: 10.255.255.82) - Destination: pod1-leaf6a Ethernet2/1 (IP: 10.255.255.83)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-spine2
+ hosts:
+ - destination: 10.255.255.91
+ repeat: 1
+ source: 10.255.255.90
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet12/1 (IP: 10.255.255.90) - Destination: pod1-leaf6b Ethernet2/1 (IP: 10.255.255.91)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-spine2
+ hosts:
+ - destination: 10.255.255.99
+ repeat: 1
+ source: 10.255.255.98
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet13/1 (IP: 10.255.255.98) - Destination: pod1-leaf7a Ethernet2/1 (IP: 10.255.255.99)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-spine2
+ hosts:
+ - destination: 10.255.255.107
+ repeat: 1
+ source: 10.255.255.106
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet14/1 (IP: 10.255.255.106) - Destination: pod1-leaf7b Ethernet2/1 (IP: 10.255.255.107)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-spine2
+ hosts:
+ - destination: 10.255.255.115
+ repeat: 1
+ source: 10.255.255.114
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet15/1 (IP: 10.255.255.114) - Destination: pod1-leaf8a Ethernet2/1 (IP: 10.255.255.115)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-spine2
+ hosts:
+ - destination: 10.255.255.123
+ repeat: 1
+ source: 10.255.255.122
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet16/1 (IP: 10.255.255.122) - Destination: pod1-leaf8b Ethernet2/1 (IP: 10.255.255.123)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-spine2
+ hosts:
+ - destination: 10.255.255.131
+ repeat: 1
+ source: 10.255.255.130
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet17/1 (IP: 10.255.255.130) - Destination: pod1-leaf9a Ethernet2/1 (IP: 10.255.255.131)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-spine2
+ hosts:
+ - destination: 10.255.255.139
+ repeat: 1
+ source: 10.255.255.138
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet18/1 (IP: 10.255.255.138) - Destination: pod1-leaf9b Ethernet2/1 (IP: 10.255.255.139)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-spine2
+ hosts:
+ - destination: 10.255.255.147
+ repeat: 1
+ source: 10.255.255.146
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet19/1 (IP: 10.255.255.146) - Destination: pod1-leaf10a Ethernet2/1 (IP: 10.255.255.147)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-spine2
+ hosts:
+ - destination: 10.255.255.155
+ repeat: 1
+ source: 10.255.255.154
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet20/1 (IP: 10.255.255.154) - Destination: pod1-leaf10b Ethernet2/1 (IP: 10.255.255.155)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-spine2
+ hosts:
+ - destination: 10.255.255.4
+ repeat: 1
+ source: 10.255.255.5
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet31/1 (IP: 10.255.255.5) - Destination: super-spine1 Ethernet2/1 (IP: 10.255.255.4)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-spine2
+ hosts:
+ - destination: 10.255.255.6
+ repeat: 1
+ source: 10.255.255.7
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet32/1 (IP: 10.255.255.7) - Destination: super-spine2 Ethernet2/1 (IP: 10.255.255.6)'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-leaf4a
+ neighbors:
+ - neighbor_device: pod2-leaf4b
+ neighbor_port: Ethernet53/1
+ port: Ethernet53/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet53/1 - Remote: pod2-leaf4b Ethernet53/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-leaf4a
+ neighbors:
+ - neighbor_device: pod2-leaf4b
+ neighbor_port: Ethernet54/1
+ port: Ethernet54/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet54/1 - Remote: pod2-leaf4b Ethernet54/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-leaf4a
+ neighbors:
+ - neighbor_device: pod2-spine1
+ neighbor_port: Ethernet7/1
+ port: Ethernet1/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet1/1 - Remote: pod2-spine1 Ethernet7/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-leaf4a
+ neighbors:
+ - neighbor_device: pod2-spine2
+ neighbor_port: Ethernet7/1
+ port: Ethernet2/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet2/1 - Remote: pod2-spine2 Ethernet7/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-leaf4a
+ neighbors:
+ - neighbor_device: pod2-spine3
+ neighbor_port: Ethernet7/1
+ port: Ethernet3/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet3/1 - Remote: pod2-spine3 Ethernet7/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-leaf4a
+ neighbors:
+ - neighbor_device: pod2-spine4
+ neighbor_port: Ethernet7/1
+ port: Ethernet4/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet4/1 - Remote: pod2-spine4 Ethernet7/1'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf4a
+ hosts:
+ - destination: 10.255.255.48
+ repeat: 1
+ source: 10.255.255.49
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet1/1 (IP: 10.255.255.49) - Destination: pod2-spine1 Ethernet7/1 (IP: 10.255.255.48)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf4a
+ hosts:
+ - destination: 10.255.255.50
+ repeat: 1
+ source: 10.255.255.51
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet2/1 (IP: 10.255.255.51) - Destination: pod2-spine2 Ethernet7/1 (IP: 10.255.255.50)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf4a
+ hosts:
+ - destination: 10.255.255.52
+ repeat: 1
+ source: 10.255.255.53
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet3/1 (IP: 10.255.255.53) - Destination: pod2-spine3 Ethernet7/1 (IP: 10.255.255.52)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf4a
+ hosts:
+ - destination: 10.255.255.54
+ repeat: 1
+ source: 10.255.255.55
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet4/1 (IP: 10.255.255.55) - Destination: pod2-spine4 Ethernet7/1 (IP: 10.255.255.54)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf4a
+ hosts:
+ - destination: 10.255.0.1
+ repeat: 1
+ source: 10.255.2.11
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.11) - Destination: super-spine1 Loopback0 (IP: 10.255.0.1)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf4a
+ hosts:
+ - destination: 10.255.0.2
+ repeat: 1
+ source: 10.255.2.11
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.11) - Destination: super-spine2 Loopback0 (IP: 10.255.0.2)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf4a
+ hosts:
+ - destination: 10.255.1.1
+ repeat: 1
+ source: 10.255.2.11
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.11) - Destination: pod1-spine1 Loopback0 (IP: 10.255.1.1)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf4a
+ hosts:
+ - destination: 10.255.1.2
+ repeat: 1
+ source: 10.255.2.11
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.11) - Destination: pod1-spine2 Loopback0 (IP: 10.255.1.2)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf4a
+ hosts:
+ - destination: 10.255.1.3
+ repeat: 1
+ source: 10.255.2.11
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.11) - Destination: pod1-spine3 Loopback0 (IP: 10.255.1.3)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf4a
+ hosts:
+ - destination: 10.255.1.4
+ repeat: 1
+ source: 10.255.2.11
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.11) - Destination: pod1-spine4 Loopback0 (IP: 10.255.1.4)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf4a
+ hosts:
+ - destination: 10.255.1.5
+ repeat: 1
+ source: 10.255.2.11
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.11) - Destination: pod1-leaf1a Loopback0 (IP: 10.255.1.5)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf4a
+ hosts:
+ - destination: 10.255.1.6
+ repeat: 1
+ source: 10.255.2.11
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.11) - Destination: pod1-leaf1b Loopback0 (IP: 10.255.1.6)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf4a
+ hosts:
+ - destination: 10.255.1.7
+ repeat: 1
+ source: 10.255.2.11
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.11) - Destination: pod1-leaf2a Loopback0 (IP: 10.255.1.7)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf4a
+ hosts:
+ - destination: 10.255.1.8
+ repeat: 1
+ source: 10.255.2.11
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.11) - Destination: pod1-leaf2b Loopback0 (IP: 10.255.1.8)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf4a
+ hosts:
+ - destination: 10.255.1.9
+ repeat: 1
+ source: 10.255.2.11
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.11) - Destination: pod1-leaf3a Loopback0 (IP: 10.255.1.9)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf4a
+ hosts:
+ - destination: 10.255.1.10
+ repeat: 1
+ source: 10.255.2.11
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.11) - Destination: pod1-leaf3b Loopback0 (IP: 10.255.1.10)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf4a
+ hosts:
+ - destination: 10.255.1.11
+ repeat: 1
+ source: 10.255.2.11
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.11) - Destination: pod1-leaf4a Loopback0 (IP: 10.255.1.11)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf4a
+ hosts:
+ - destination: 10.255.1.12
+ repeat: 1
+ source: 10.255.2.11
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.11) - Destination: pod1-leaf4b Loopback0 (IP: 10.255.1.12)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf4a
+ hosts:
+ - destination: 10.255.1.13
+ repeat: 1
+ source: 10.255.2.11
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.11) - Destination: pod1-leaf5a Loopback0 (IP: 10.255.1.13)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf4a
+ hosts:
+ - destination: 10.255.1.14
+ repeat: 1
+ source: 10.255.2.11
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.11) - Destination: pod1-leaf5b Loopback0 (IP: 10.255.1.14)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf4a
+ hosts:
+ - destination: 10.255.1.15
+ repeat: 1
+ source: 10.255.2.11
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.11) - Destination: pod1-leaf6a Loopback0 (IP: 10.255.1.15)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf4a
+ hosts:
+ - destination: 10.255.1.16
+ repeat: 1
+ source: 10.255.2.11
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.11) - Destination: pod1-leaf6b Loopback0 (IP: 10.255.1.16)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf4a
+ hosts:
+ - destination: 10.255.1.17
+ repeat: 1
+ source: 10.255.2.11
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.11) - Destination: pod1-leaf7a Loopback0 (IP: 10.255.1.17)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf4a
+ hosts:
+ - destination: 10.255.1.18
+ repeat: 1
+ source: 10.255.2.11
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.11) - Destination: pod1-leaf7b Loopback0 (IP: 10.255.1.18)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf4a
+ hosts:
+ - destination: 10.255.1.19
+ repeat: 1
+ source: 10.255.2.11
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.11) - Destination: pod1-leaf8a Loopback0 (IP: 10.255.1.19)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf4a
+ hosts:
+ - destination: 10.255.1.20
+ repeat: 1
+ source: 10.255.2.11
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.11) - Destination: pod1-leaf8b Loopback0 (IP: 10.255.1.20)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf4a
+ hosts:
+ - destination: 10.255.1.21
+ repeat: 1
+ source: 10.255.2.11
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.11) - Destination: pod1-leaf9a Loopback0 (IP: 10.255.1.21)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf4a
+ hosts:
+ - destination: 10.255.1.22
+ repeat: 1
+ source: 10.255.2.11
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.11) - Destination: pod1-leaf9b Loopback0 (IP: 10.255.1.22)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf4a
+ hosts:
+ - destination: 10.255.1.23
+ repeat: 1
+ source: 10.255.2.11
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.11) - Destination: pod1-leaf10a Loopback0 (IP: 10.255.1.23)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf4a
+ hosts:
+ - destination: 10.255.1.24
+ repeat: 1
+ source: 10.255.2.11
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.11) - Destination: pod1-leaf10b Loopback0 (IP: 10.255.1.24)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf4a
+ hosts:
+ - destination: 10.255.2.1
+ repeat: 1
+ source: 10.255.2.11
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.11) - Destination: pod2-spine1 Loopback0 (IP: 10.255.2.1)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf4a
+ hosts:
+ - destination: 10.255.2.2
+ repeat: 1
+ source: 10.255.2.11
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.11) - Destination: pod2-spine2 Loopback0 (IP: 10.255.2.2)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf4a
+ hosts:
+ - destination: 10.255.2.3
+ repeat: 1
+ source: 10.255.2.11
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.11) - Destination: pod2-spine3 Loopback0 (IP: 10.255.2.3)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf4a
+ hosts:
+ - destination: 10.255.2.4
+ repeat: 1
+ source: 10.255.2.11
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.11) - Destination: pod2-spine4 Loopback0 (IP: 10.255.2.4)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf4a
+ hosts:
+ - destination: 10.255.2.5
+ repeat: 1
+ source: 10.255.2.11
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.11) - Destination: pod2-leaf1a Loopback0 (IP: 10.255.2.5)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf4a
+ hosts:
+ - destination: 10.255.2.6
+ repeat: 1
+ source: 10.255.2.11
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.11) - Destination: pod2-leaf1b Loopback0 (IP: 10.255.2.6)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf4a
+ hosts:
+ - destination: 10.255.2.7
+ repeat: 1
+ source: 10.255.2.11
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.11) - Destination: pod2-leaf2a Loopback0 (IP: 10.255.2.7)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf4a
+ hosts:
+ - destination: 10.255.2.8
+ repeat: 1
+ source: 10.255.2.11
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.11) - Destination: pod2-leaf2b Loopback0 (IP: 10.255.2.8)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf4a
+ hosts:
+ - destination: 10.255.2.9
+ repeat: 1
+ source: 10.255.2.11
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.11) - Destination: pod2-leaf3a Loopback0 (IP: 10.255.2.9)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf4a
+ hosts:
+ - destination: 10.255.2.10
+ repeat: 1
+ source: 10.255.2.11
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.11) - Destination: pod2-leaf3b Loopback0 (IP: 10.255.2.10)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf4a
+ hosts:
+ - destination: 10.255.2.11
+ repeat: 1
+ source: 10.255.2.11
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.11) - Destination: pod2-leaf4a Loopback0 (IP: 10.255.2.11)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf4a
+ hosts:
+ - destination: 10.255.2.12
+ repeat: 1
+ source: 10.255.2.11
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.11) - Destination: pod2-leaf4b Loopback0 (IP: 10.255.2.12)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf4a
+ hosts:
+ - destination: 10.255.2.13
+ repeat: 1
+ source: 10.255.2.11
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.11) - Destination: pod2-leaf5a Loopback0 (IP: 10.255.2.13)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf4a
+ hosts:
+ - destination: 10.255.2.14
+ repeat: 1
+ source: 10.255.2.11
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.11) - Destination: pod2-leaf5b Loopback0 (IP: 10.255.2.14)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf4a
+ hosts:
+ - destination: 10.255.2.15
+ repeat: 1
+ source: 10.255.2.11
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.11) - Destination: pod2-leaf6a Loopback0 (IP: 10.255.2.15)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf4a
+ hosts:
+ - destination: 10.255.2.16
+ repeat: 1
+ source: 10.255.2.11
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.11) - Destination: pod2-leaf6b Loopback0 (IP: 10.255.2.16)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf4a
+ hosts:
+ - destination: 10.255.2.17
+ repeat: 1
+ source: 10.255.2.11
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.11) - Destination: pod2-leaf7a Loopback0 (IP: 10.255.2.17)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf4a
+ hosts:
+ - destination: 10.255.2.18
+ repeat: 1
+ source: 10.255.2.11
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.11) - Destination: pod2-leaf7b Loopback0 (IP: 10.255.2.18)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf4a
+ hosts:
+ - destination: 10.255.2.19
+ repeat: 1
+ source: 10.255.2.11
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.11) - Destination: pod2-leaf8a Loopback0 (IP: 10.255.2.19)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf4a
+ hosts:
+ - destination: 10.255.2.20
+ repeat: 1
+ source: 10.255.2.11
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.11) - Destination: pod2-leaf8b Loopback0 (IP: 10.255.2.20)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf4a
+ hosts:
+ - destination: 10.255.2.21
+ repeat: 1
+ source: 10.255.2.11
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.11) - Destination: pod2-leaf9a Loopback0 (IP: 10.255.2.21)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf4a
+ hosts:
+ - destination: 10.255.2.22
+ repeat: 1
+ source: 10.255.2.11
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.11) - Destination: pod2-leaf9b Loopback0 (IP: 10.255.2.22)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf4a
+ hosts:
+ - destination: 10.255.2.23
+ repeat: 1
+ source: 10.255.2.11
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.11) - Destination: pod2-leaf10a Loopback0 (IP: 10.255.2.23)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf4a
+ hosts:
+ - destination: 10.255.2.24
+ repeat: 1
+ source: 10.255.2.11
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.11) - Destination: pod2-leaf10b Loopback0 (IP: 10.255.2.24)'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-leaf8b
+ neighbors:
+ - neighbor_device: pod1-leaf8a
+ neighbor_port: Ethernet53/1
+ port: Ethernet53/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet53/1 - Remote: pod1-leaf8a Ethernet53/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-leaf8b
+ neighbors:
+ - neighbor_device: pod1-leaf8a
+ neighbor_port: Ethernet54/1
+ port: Ethernet54/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet54/1 - Remote: pod1-leaf8a Ethernet54/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-leaf8b
+ neighbors:
+ - neighbor_device: pod1-spine1
+ neighbor_port: Ethernet16/1
+ port: Ethernet1/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet1/1 - Remote: pod1-spine1 Ethernet16/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-leaf8b
+ neighbors:
+ - neighbor_device: pod1-spine2
+ neighbor_port: Ethernet16/1
+ port: Ethernet2/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet2/1 - Remote: pod1-spine2 Ethernet16/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-leaf8b
+ neighbors:
+ - neighbor_device: pod1-spine3
+ neighbor_port: Ethernet16/1
+ port: Ethernet3/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet3/1 - Remote: pod1-spine3 Ethernet16/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-leaf8b
+ neighbors:
+ - neighbor_device: pod1-spine4
+ neighbor_port: Ethernet16/1
+ port: Ethernet4/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet4/1 - Remote: pod1-spine4 Ethernet16/1'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf8b
+ hosts:
+ - destination: 10.255.255.120
+ repeat: 1
+ source: 10.255.255.121
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet1/1 (IP: 10.255.255.121) - Destination: pod1-spine1 Ethernet16/1 (IP: 10.255.255.120)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf8b
+ hosts:
+ - destination: 10.255.255.122
+ repeat: 1
+ source: 10.255.255.123
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet2/1 (IP: 10.255.255.123) - Destination: pod1-spine2 Ethernet16/1 (IP: 10.255.255.122)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf8b
+ hosts:
+ - destination: 10.255.255.124
+ repeat: 1
+ source: 10.255.255.125
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet3/1 (IP: 10.255.255.125) - Destination: pod1-spine3 Ethernet16/1 (IP: 10.255.255.124)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf8b
+ hosts:
+ - destination: 10.255.255.126
+ repeat: 1
+ source: 10.255.255.127
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet4/1 (IP: 10.255.255.127) - Destination: pod1-spine4 Ethernet16/1 (IP: 10.255.255.126)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf8b
+ hosts:
+ - destination: 10.255.0.1
+ repeat: 1
+ source: 10.255.1.20
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.20) - Destination: super-spine1 Loopback0 (IP: 10.255.0.1)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf8b
+ hosts:
+ - destination: 10.255.0.2
+ repeat: 1
+ source: 10.255.1.20
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.20) - Destination: super-spine2 Loopback0 (IP: 10.255.0.2)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf8b
+ hosts:
+ - destination: 10.255.1.1
+ repeat: 1
+ source: 10.255.1.20
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.20) - Destination: pod1-spine1 Loopback0 (IP: 10.255.1.1)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf8b
+ hosts:
+ - destination: 10.255.1.2
+ repeat: 1
+ source: 10.255.1.20
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.20) - Destination: pod1-spine2 Loopback0 (IP: 10.255.1.2)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf8b
+ hosts:
+ - destination: 10.255.1.3
+ repeat: 1
+ source: 10.255.1.20
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.20) - Destination: pod1-spine3 Loopback0 (IP: 10.255.1.3)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf8b
+ hosts:
+ - destination: 10.255.1.4
+ repeat: 1
+ source: 10.255.1.20
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.20) - Destination: pod1-spine4 Loopback0 (IP: 10.255.1.4)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf8b
+ hosts:
+ - destination: 10.255.1.5
+ repeat: 1
+ source: 10.255.1.20
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.20) - Destination: pod1-leaf1a Loopback0 (IP: 10.255.1.5)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf8b
+ hosts:
+ - destination: 10.255.1.6
+ repeat: 1
+ source: 10.255.1.20
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.20) - Destination: pod1-leaf1b Loopback0 (IP: 10.255.1.6)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf8b
+ hosts:
+ - destination: 10.255.1.7
+ repeat: 1
+ source: 10.255.1.20
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.20) - Destination: pod1-leaf2a Loopback0 (IP: 10.255.1.7)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf8b
+ hosts:
+ - destination: 10.255.1.8
+ repeat: 1
+ source: 10.255.1.20
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.20) - Destination: pod1-leaf2b Loopback0 (IP: 10.255.1.8)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf8b
+ hosts:
+ - destination: 10.255.1.9
+ repeat: 1
+ source: 10.255.1.20
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.20) - Destination: pod1-leaf3a Loopback0 (IP: 10.255.1.9)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf8b
+ hosts:
+ - destination: 10.255.1.10
+ repeat: 1
+ source: 10.255.1.20
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.20) - Destination: pod1-leaf3b Loopback0 (IP: 10.255.1.10)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf8b
+ hosts:
+ - destination: 10.255.1.11
+ repeat: 1
+ source: 10.255.1.20
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.20) - Destination: pod1-leaf4a Loopback0 (IP: 10.255.1.11)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf8b
+ hosts:
+ - destination: 10.255.1.12
+ repeat: 1
+ source: 10.255.1.20
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.20) - Destination: pod1-leaf4b Loopback0 (IP: 10.255.1.12)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf8b
+ hosts:
+ - destination: 10.255.1.13
+ repeat: 1
+ source: 10.255.1.20
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.20) - Destination: pod1-leaf5a Loopback0 (IP: 10.255.1.13)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf8b
+ hosts:
+ - destination: 10.255.1.14
+ repeat: 1
+ source: 10.255.1.20
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.20) - Destination: pod1-leaf5b Loopback0 (IP: 10.255.1.14)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf8b
+ hosts:
+ - destination: 10.255.1.15
+ repeat: 1
+ source: 10.255.1.20
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.20) - Destination: pod1-leaf6a Loopback0 (IP: 10.255.1.15)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf8b
+ hosts:
+ - destination: 10.255.1.16
+ repeat: 1
+ source: 10.255.1.20
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.20) - Destination: pod1-leaf6b Loopback0 (IP: 10.255.1.16)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf8b
+ hosts:
+ - destination: 10.255.1.17
+ repeat: 1
+ source: 10.255.1.20
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.20) - Destination: pod1-leaf7a Loopback0 (IP: 10.255.1.17)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf8b
+ hosts:
+ - destination: 10.255.1.18
+ repeat: 1
+ source: 10.255.1.20
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.20) - Destination: pod1-leaf7b Loopback0 (IP: 10.255.1.18)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf8b
+ hosts:
+ - destination: 10.255.1.19
+ repeat: 1
+ source: 10.255.1.20
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.20) - Destination: pod1-leaf8a Loopback0 (IP: 10.255.1.19)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf8b
+ hosts:
+ - destination: 10.255.1.20
+ repeat: 1
+ source: 10.255.1.20
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.20) - Destination: pod1-leaf8b Loopback0 (IP: 10.255.1.20)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf8b
+ hosts:
+ - destination: 10.255.1.21
+ repeat: 1
+ source: 10.255.1.20
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.20) - Destination: pod1-leaf9a Loopback0 (IP: 10.255.1.21)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf8b
+ hosts:
+ - destination: 10.255.1.22
+ repeat: 1
+ source: 10.255.1.20
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.20) - Destination: pod1-leaf9b Loopback0 (IP: 10.255.1.22)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf8b
+ hosts:
+ - destination: 10.255.1.23
+ repeat: 1
+ source: 10.255.1.20
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.20) - Destination: pod1-leaf10a Loopback0 (IP: 10.255.1.23)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf8b
+ hosts:
+ - destination: 10.255.1.24
+ repeat: 1
+ source: 10.255.1.20
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.20) - Destination: pod1-leaf10b Loopback0 (IP: 10.255.1.24)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf8b
+ hosts:
+ - destination: 10.255.2.1
+ repeat: 1
+ source: 10.255.1.20
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.20) - Destination: pod2-spine1 Loopback0 (IP: 10.255.2.1)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf8b
+ hosts:
+ - destination: 10.255.2.2
+ repeat: 1
+ source: 10.255.1.20
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.20) - Destination: pod2-spine2 Loopback0 (IP: 10.255.2.2)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf8b
+ hosts:
+ - destination: 10.255.2.3
+ repeat: 1
+ source: 10.255.1.20
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.20) - Destination: pod2-spine3 Loopback0 (IP: 10.255.2.3)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf8b
+ hosts:
+ - destination: 10.255.2.4
+ repeat: 1
+ source: 10.255.1.20
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.20) - Destination: pod2-spine4 Loopback0 (IP: 10.255.2.4)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf8b
+ hosts:
+ - destination: 10.255.2.5
+ repeat: 1
+ source: 10.255.1.20
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.20) - Destination: pod2-leaf1a Loopback0 (IP: 10.255.2.5)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf8b
+ hosts:
+ - destination: 10.255.2.6
+ repeat: 1
+ source: 10.255.1.20
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.20) - Destination: pod2-leaf1b Loopback0 (IP: 10.255.2.6)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf8b
+ hosts:
+ - destination: 10.255.2.7
+ repeat: 1
+ source: 10.255.1.20
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.20) - Destination: pod2-leaf2a Loopback0 (IP: 10.255.2.7)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf8b
+ hosts:
+ - destination: 10.255.2.8
+ repeat: 1
+ source: 10.255.1.20
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.20) - Destination: pod2-leaf2b Loopback0 (IP: 10.255.2.8)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf8b
+ hosts:
+ - destination: 10.255.2.9
+ repeat: 1
+ source: 10.255.1.20
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.20) - Destination: pod2-leaf3a Loopback0 (IP: 10.255.2.9)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf8b
+ hosts:
+ - destination: 10.255.2.10
+ repeat: 1
+ source: 10.255.1.20
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.20) - Destination: pod2-leaf3b Loopback0 (IP: 10.255.2.10)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf8b
+ hosts:
+ - destination: 10.255.2.11
+ repeat: 1
+ source: 10.255.1.20
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.20) - Destination: pod2-leaf4a Loopback0 (IP: 10.255.2.11)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf8b
+ hosts:
+ - destination: 10.255.2.12
+ repeat: 1
+ source: 10.255.1.20
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.20) - Destination: pod2-leaf4b Loopback0 (IP: 10.255.2.12)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf8b
+ hosts:
+ - destination: 10.255.2.13
+ repeat: 1
+ source: 10.255.1.20
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.20) - Destination: pod2-leaf5a Loopback0 (IP: 10.255.2.13)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf8b
+ hosts:
+ - destination: 10.255.2.14
+ repeat: 1
+ source: 10.255.1.20
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.20) - Destination: pod2-leaf5b Loopback0 (IP: 10.255.2.14)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf8b
+ hosts:
+ - destination: 10.255.2.15
+ repeat: 1
+ source: 10.255.1.20
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.20) - Destination: pod2-leaf6a Loopback0 (IP: 10.255.2.15)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf8b
+ hosts:
+ - destination: 10.255.2.16
+ repeat: 1
+ source: 10.255.1.20
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.20) - Destination: pod2-leaf6b Loopback0 (IP: 10.255.2.16)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf8b
+ hosts:
+ - destination: 10.255.2.17
+ repeat: 1
+ source: 10.255.1.20
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.20) - Destination: pod2-leaf7a Loopback0 (IP: 10.255.2.17)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf8b
+ hosts:
+ - destination: 10.255.2.18
+ repeat: 1
+ source: 10.255.1.20
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.20) - Destination: pod2-leaf7b Loopback0 (IP: 10.255.2.18)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf8b
+ hosts:
+ - destination: 10.255.2.19
+ repeat: 1
+ source: 10.255.1.20
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.20) - Destination: pod2-leaf8a Loopback0 (IP: 10.255.2.19)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf8b
+ hosts:
+ - destination: 10.255.2.20
+ repeat: 1
+ source: 10.255.1.20
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.20) - Destination: pod2-leaf8b Loopback0 (IP: 10.255.2.20)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf8b
+ hosts:
+ - destination: 10.255.2.21
+ repeat: 1
+ source: 10.255.1.20
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.20) - Destination: pod2-leaf9a Loopback0 (IP: 10.255.2.21)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf8b
+ hosts:
+ - destination: 10.255.2.22
+ repeat: 1
+ source: 10.255.1.20
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.20) - Destination: pod2-leaf9b Loopback0 (IP: 10.255.2.22)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf8b
+ hosts:
+ - destination: 10.255.2.23
+ repeat: 1
+ source: 10.255.1.20
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.20) - Destination: pod2-leaf10a Loopback0 (IP: 10.255.2.23)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf8b
+ hosts:
+ - destination: 10.255.2.24
+ repeat: 1
+ source: 10.255.1.20
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.20) - Destination: pod2-leaf10b Loopback0 (IP: 10.255.2.24)'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-leaf2a
+ neighbors:
+ - neighbor_device: pod1-leaf2b
+ neighbor_port: Ethernet53/1
+ port: Ethernet53/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet53/1 - Remote: pod1-leaf2b Ethernet53/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-leaf2a
+ neighbors:
+ - neighbor_device: pod1-leaf2b
+ neighbor_port: Ethernet54/1
+ port: Ethernet54/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet54/1 - Remote: pod1-leaf2b Ethernet54/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-leaf2a
+ neighbors:
+ - neighbor_device: pod1-spine1
+ neighbor_port: Ethernet3/1
+ port: Ethernet1/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet1/1 - Remote: pod1-spine1 Ethernet3/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-leaf2a
+ neighbors:
+ - neighbor_device: pod1-spine2
+ neighbor_port: Ethernet3/1
+ port: Ethernet2/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet2/1 - Remote: pod1-spine2 Ethernet3/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-leaf2a
+ neighbors:
+ - neighbor_device: pod1-spine3
+ neighbor_port: Ethernet3/1
+ port: Ethernet3/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet3/1 - Remote: pod1-spine3 Ethernet3/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-leaf2a
+ neighbors:
+ - neighbor_device: pod1-spine4
+ neighbor_port: Ethernet3/1
+ port: Ethernet4/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet4/1 - Remote: pod1-spine4 Ethernet3/1'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf2a
+ hosts:
+ - destination: 10.255.255.16
+ repeat: 1
+ source: 10.255.255.17
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet1/1 (IP: 10.255.255.17) - Destination: pod1-spine1 Ethernet3/1 (IP: 10.255.255.16)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf2a
+ hosts:
+ - destination: 10.255.255.18
+ repeat: 1
+ source: 10.255.255.19
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet2/1 (IP: 10.255.255.19) - Destination: pod1-spine2 Ethernet3/1 (IP: 10.255.255.18)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf2a
+ hosts:
+ - destination: 10.255.255.20
+ repeat: 1
+ source: 10.255.255.21
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet3/1 (IP: 10.255.255.21) - Destination: pod1-spine3 Ethernet3/1 (IP: 10.255.255.20)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf2a
+ hosts:
+ - destination: 10.255.255.22
+ repeat: 1
+ source: 10.255.255.23
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet4/1 (IP: 10.255.255.23) - Destination: pod1-spine4 Ethernet3/1 (IP: 10.255.255.22)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf2a
+ hosts:
+ - destination: 10.255.0.1
+ repeat: 1
+ source: 10.255.1.7
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.7) - Destination: super-spine1 Loopback0 (IP: 10.255.0.1)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf2a
+ hosts:
+ - destination: 10.255.0.2
+ repeat: 1
+ source: 10.255.1.7
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.7) - Destination: super-spine2 Loopback0 (IP: 10.255.0.2)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf2a
+ hosts:
+ - destination: 10.255.1.1
+ repeat: 1
+ source: 10.255.1.7
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.7) - Destination: pod1-spine1 Loopback0 (IP: 10.255.1.1)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf2a
+ hosts:
+ - destination: 10.255.1.2
+ repeat: 1
+ source: 10.255.1.7
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.7) - Destination: pod1-spine2 Loopback0 (IP: 10.255.1.2)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf2a
+ hosts:
+ - destination: 10.255.1.3
+ repeat: 1
+ source: 10.255.1.7
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.7) - Destination: pod1-spine3 Loopback0 (IP: 10.255.1.3)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf2a
+ hosts:
+ - destination: 10.255.1.4
+ repeat: 1
+ source: 10.255.1.7
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.7) - Destination: pod1-spine4 Loopback0 (IP: 10.255.1.4)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf2a
+ hosts:
+ - destination: 10.255.1.5
+ repeat: 1
+ source: 10.255.1.7
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.7) - Destination: pod1-leaf1a Loopback0 (IP: 10.255.1.5)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf2a
+ hosts:
+ - destination: 10.255.1.6
+ repeat: 1
+ source: 10.255.1.7
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.7) - Destination: pod1-leaf1b Loopback0 (IP: 10.255.1.6)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf2a
+ hosts:
+ - destination: 10.255.1.7
+ repeat: 1
+ source: 10.255.1.7
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.7) - Destination: pod1-leaf2a Loopback0 (IP: 10.255.1.7)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf2a
+ hosts:
+ - destination: 10.255.1.8
+ repeat: 1
+ source: 10.255.1.7
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.7) - Destination: pod1-leaf2b Loopback0 (IP: 10.255.1.8)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf2a
+ hosts:
+ - destination: 10.255.1.9
+ repeat: 1
+ source: 10.255.1.7
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.7) - Destination: pod1-leaf3a Loopback0 (IP: 10.255.1.9)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf2a
+ hosts:
+ - destination: 10.255.1.10
+ repeat: 1
+ source: 10.255.1.7
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.7) - Destination: pod1-leaf3b Loopback0 (IP: 10.255.1.10)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf2a
+ hosts:
+ - destination: 10.255.1.11
+ repeat: 1
+ source: 10.255.1.7
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.7) - Destination: pod1-leaf4a Loopback0 (IP: 10.255.1.11)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf2a
+ hosts:
+ - destination: 10.255.1.12
+ repeat: 1
+ source: 10.255.1.7
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.7) - Destination: pod1-leaf4b Loopback0 (IP: 10.255.1.12)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf2a
+ hosts:
+ - destination: 10.255.1.13
+ repeat: 1
+ source: 10.255.1.7
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.7) - Destination: pod1-leaf5a Loopback0 (IP: 10.255.1.13)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf2a
+ hosts:
+ - destination: 10.255.1.14
+ repeat: 1
+ source: 10.255.1.7
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.7) - Destination: pod1-leaf5b Loopback0 (IP: 10.255.1.14)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf2a
+ hosts:
+ - destination: 10.255.1.15
+ repeat: 1
+ source: 10.255.1.7
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.7) - Destination: pod1-leaf6a Loopback0 (IP: 10.255.1.15)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf2a
+ hosts:
+ - destination: 10.255.1.16
+ repeat: 1
+ source: 10.255.1.7
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.7) - Destination: pod1-leaf6b Loopback0 (IP: 10.255.1.16)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf2a
+ hosts:
+ - destination: 10.255.1.17
+ repeat: 1
+ source: 10.255.1.7
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.7) - Destination: pod1-leaf7a Loopback0 (IP: 10.255.1.17)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf2a
+ hosts:
+ - destination: 10.255.1.18
+ repeat: 1
+ source: 10.255.1.7
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.7) - Destination: pod1-leaf7b Loopback0 (IP: 10.255.1.18)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf2a
+ hosts:
+ - destination: 10.255.1.19
+ repeat: 1
+ source: 10.255.1.7
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.7) - Destination: pod1-leaf8a Loopback0 (IP: 10.255.1.19)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf2a
+ hosts:
+ - destination: 10.255.1.20
+ repeat: 1
+ source: 10.255.1.7
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.7) - Destination: pod1-leaf8b Loopback0 (IP: 10.255.1.20)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf2a
+ hosts:
+ - destination: 10.255.1.21
+ repeat: 1
+ source: 10.255.1.7
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.7) - Destination: pod1-leaf9a Loopback0 (IP: 10.255.1.21)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf2a
+ hosts:
+ - destination: 10.255.1.22
+ repeat: 1
+ source: 10.255.1.7
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.7) - Destination: pod1-leaf9b Loopback0 (IP: 10.255.1.22)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf2a
+ hosts:
+ - destination: 10.255.1.23
+ repeat: 1
+ source: 10.255.1.7
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.7) - Destination: pod1-leaf10a Loopback0 (IP: 10.255.1.23)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf2a
+ hosts:
+ - destination: 10.255.1.24
+ repeat: 1
+ source: 10.255.1.7
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.7) - Destination: pod1-leaf10b Loopback0 (IP: 10.255.1.24)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf2a
+ hosts:
+ - destination: 10.255.2.1
+ repeat: 1
+ source: 10.255.1.7
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.7) - Destination: pod2-spine1 Loopback0 (IP: 10.255.2.1)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf2a
+ hosts:
+ - destination: 10.255.2.2
+ repeat: 1
+ source: 10.255.1.7
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.7) - Destination: pod2-spine2 Loopback0 (IP: 10.255.2.2)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf2a
+ hosts:
+ - destination: 10.255.2.3
+ repeat: 1
+ source: 10.255.1.7
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.7) - Destination: pod2-spine3 Loopback0 (IP: 10.255.2.3)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf2a
+ hosts:
+ - destination: 10.255.2.4
+ repeat: 1
+ source: 10.255.1.7
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.7) - Destination: pod2-spine4 Loopback0 (IP: 10.255.2.4)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf2a
+ hosts:
+ - destination: 10.255.2.5
+ repeat: 1
+ source: 10.255.1.7
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.7) - Destination: pod2-leaf1a Loopback0 (IP: 10.255.2.5)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf2a
+ hosts:
+ - destination: 10.255.2.6
+ repeat: 1
+ source: 10.255.1.7
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.7) - Destination: pod2-leaf1b Loopback0 (IP: 10.255.2.6)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf2a
+ hosts:
+ - destination: 10.255.2.7
+ repeat: 1
+ source: 10.255.1.7
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.7) - Destination: pod2-leaf2a Loopback0 (IP: 10.255.2.7)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf2a
+ hosts:
+ - destination: 10.255.2.8
+ repeat: 1
+ source: 10.255.1.7
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.7) - Destination: pod2-leaf2b Loopback0 (IP: 10.255.2.8)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf2a
+ hosts:
+ - destination: 10.255.2.9
+ repeat: 1
+ source: 10.255.1.7
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.7) - Destination: pod2-leaf3a Loopback0 (IP: 10.255.2.9)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf2a
+ hosts:
+ - destination: 10.255.2.10
+ repeat: 1
+ source: 10.255.1.7
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.7) - Destination: pod2-leaf3b Loopback0 (IP: 10.255.2.10)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf2a
+ hosts:
+ - destination: 10.255.2.11
+ repeat: 1
+ source: 10.255.1.7
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.7) - Destination: pod2-leaf4a Loopback0 (IP: 10.255.2.11)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf2a
+ hosts:
+ - destination: 10.255.2.12
+ repeat: 1
+ source: 10.255.1.7
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.7) - Destination: pod2-leaf4b Loopback0 (IP: 10.255.2.12)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf2a
+ hosts:
+ - destination: 10.255.2.13
+ repeat: 1
+ source: 10.255.1.7
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.7) - Destination: pod2-leaf5a Loopback0 (IP: 10.255.2.13)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf2a
+ hosts:
+ - destination: 10.255.2.14
+ repeat: 1
+ source: 10.255.1.7
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.7) - Destination: pod2-leaf5b Loopback0 (IP: 10.255.2.14)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf2a
+ hosts:
+ - destination: 10.255.2.15
+ repeat: 1
+ source: 10.255.1.7
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.7) - Destination: pod2-leaf6a Loopback0 (IP: 10.255.2.15)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf2a
+ hosts:
+ - destination: 10.255.2.16
+ repeat: 1
+ source: 10.255.1.7
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.7) - Destination: pod2-leaf6b Loopback0 (IP: 10.255.2.16)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf2a
+ hosts:
+ - destination: 10.255.2.17
+ repeat: 1
+ source: 10.255.1.7
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.7) - Destination: pod2-leaf7a Loopback0 (IP: 10.255.2.17)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf2a
+ hosts:
+ - destination: 10.255.2.18
+ repeat: 1
+ source: 10.255.1.7
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.7) - Destination: pod2-leaf7b Loopback0 (IP: 10.255.2.18)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf2a
+ hosts:
+ - destination: 10.255.2.19
+ repeat: 1
+ source: 10.255.1.7
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.7) - Destination: pod2-leaf8a Loopback0 (IP: 10.255.2.19)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf2a
+ hosts:
+ - destination: 10.255.2.20
+ repeat: 1
+ source: 10.255.1.7
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.7) - Destination: pod2-leaf8b Loopback0 (IP: 10.255.2.20)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf2a
+ hosts:
+ - destination: 10.255.2.21
+ repeat: 1
+ source: 10.255.1.7
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.7) - Destination: pod2-leaf9a Loopback0 (IP: 10.255.2.21)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf2a
+ hosts:
+ - destination: 10.255.2.22
+ repeat: 1
+ source: 10.255.1.7
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.7) - Destination: pod2-leaf9b Loopback0 (IP: 10.255.2.22)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf2a
+ hosts:
+ - destination: 10.255.2.23
+ repeat: 1
+ source: 10.255.1.7
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.7) - Destination: pod2-leaf10a Loopback0 (IP: 10.255.2.23)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf2a
+ hosts:
+ - destination: 10.255.2.24
+ repeat: 1
+ source: 10.255.1.7
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.7) - Destination: pod2-leaf10b Loopback0 (IP: 10.255.2.24)'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-leaf5a
+ neighbors:
+ - neighbor_device: pod1-leaf5b
+ neighbor_port: Ethernet53/1
+ port: Ethernet53/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet53/1 - Remote: pod1-leaf5b Ethernet53/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-leaf5a
+ neighbors:
+ - neighbor_device: pod1-leaf5b
+ neighbor_port: Ethernet54/1
+ port: Ethernet54/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet54/1 - Remote: pod1-leaf5b Ethernet54/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-leaf5a
+ neighbors:
+ - neighbor_device: pod1-spine1
+ neighbor_port: Ethernet9/1
+ port: Ethernet1/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet1/1 - Remote: pod1-spine1 Ethernet9/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-leaf5a
+ neighbors:
+ - neighbor_device: pod1-spine2
+ neighbor_port: Ethernet9/1
+ port: Ethernet2/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet2/1 - Remote: pod1-spine2 Ethernet9/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-leaf5a
+ neighbors:
+ - neighbor_device: pod1-spine3
+ neighbor_port: Ethernet9/1
+ port: Ethernet3/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet3/1 - Remote: pod1-spine3 Ethernet9/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-leaf5a
+ neighbors:
+ - neighbor_device: pod1-spine4
+ neighbor_port: Ethernet9/1
+ port: Ethernet4/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet4/1 - Remote: pod1-spine4 Ethernet9/1'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf5a
+ hosts:
+ - destination: 10.255.255.64
+ repeat: 1
+ source: 10.255.255.65
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet1/1 (IP: 10.255.255.65) - Destination: pod1-spine1 Ethernet9/1 (IP: 10.255.255.64)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf5a
+ hosts:
+ - destination: 10.255.255.66
+ repeat: 1
+ source: 10.255.255.67
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet2/1 (IP: 10.255.255.67) - Destination: pod1-spine2 Ethernet9/1 (IP: 10.255.255.66)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf5a
+ hosts:
+ - destination: 10.255.255.68
+ repeat: 1
+ source: 10.255.255.69
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet3/1 (IP: 10.255.255.69) - Destination: pod1-spine3 Ethernet9/1 (IP: 10.255.255.68)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf5a
+ hosts:
+ - destination: 10.255.255.70
+ repeat: 1
+ source: 10.255.255.71
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet4/1 (IP: 10.255.255.71) - Destination: pod1-spine4 Ethernet9/1 (IP: 10.255.255.70)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf5a
+ hosts:
+ - destination: 10.255.0.1
+ repeat: 1
+ source: 10.255.1.13
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.13) - Destination: super-spine1 Loopback0 (IP: 10.255.0.1)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf5a
+ hosts:
+ - destination: 10.255.0.2
+ repeat: 1
+ source: 10.255.1.13
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.13) - Destination: super-spine2 Loopback0 (IP: 10.255.0.2)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf5a
+ hosts:
+ - destination: 10.255.1.1
+ repeat: 1
+ source: 10.255.1.13
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.13) - Destination: pod1-spine1 Loopback0 (IP: 10.255.1.1)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf5a
+ hosts:
+ - destination: 10.255.1.2
+ repeat: 1
+ source: 10.255.1.13
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.13) - Destination: pod1-spine2 Loopback0 (IP: 10.255.1.2)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf5a
+ hosts:
+ - destination: 10.255.1.3
+ repeat: 1
+ source: 10.255.1.13
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.13) - Destination: pod1-spine3 Loopback0 (IP: 10.255.1.3)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf5a
+ hosts:
+ - destination: 10.255.1.4
+ repeat: 1
+ source: 10.255.1.13
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.13) - Destination: pod1-spine4 Loopback0 (IP: 10.255.1.4)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf5a
+ hosts:
+ - destination: 10.255.1.5
+ repeat: 1
+ source: 10.255.1.13
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.13) - Destination: pod1-leaf1a Loopback0 (IP: 10.255.1.5)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf5a
+ hosts:
+ - destination: 10.255.1.6
+ repeat: 1
+ source: 10.255.1.13
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.13) - Destination: pod1-leaf1b Loopback0 (IP: 10.255.1.6)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf5a
+ hosts:
+ - destination: 10.255.1.7
+ repeat: 1
+ source: 10.255.1.13
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.13) - Destination: pod1-leaf2a Loopback0 (IP: 10.255.1.7)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf5a
+ hosts:
+ - destination: 10.255.1.8
+ repeat: 1
+ source: 10.255.1.13
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.13) - Destination: pod1-leaf2b Loopback0 (IP: 10.255.1.8)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf5a
+ hosts:
+ - destination: 10.255.1.9
+ repeat: 1
+ source: 10.255.1.13
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.13) - Destination: pod1-leaf3a Loopback0 (IP: 10.255.1.9)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf5a
+ hosts:
+ - destination: 10.255.1.10
+ repeat: 1
+ source: 10.255.1.13
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.13) - Destination: pod1-leaf3b Loopback0 (IP: 10.255.1.10)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf5a
+ hosts:
+ - destination: 10.255.1.11
+ repeat: 1
+ source: 10.255.1.13
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.13) - Destination: pod1-leaf4a Loopback0 (IP: 10.255.1.11)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf5a
+ hosts:
+ - destination: 10.255.1.12
+ repeat: 1
+ source: 10.255.1.13
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.13) - Destination: pod1-leaf4b Loopback0 (IP: 10.255.1.12)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf5a
+ hosts:
+ - destination: 10.255.1.13
+ repeat: 1
+ source: 10.255.1.13
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.13) - Destination: pod1-leaf5a Loopback0 (IP: 10.255.1.13)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf5a
+ hosts:
+ - destination: 10.255.1.14
+ repeat: 1
+ source: 10.255.1.13
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.13) - Destination: pod1-leaf5b Loopback0 (IP: 10.255.1.14)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf5a
+ hosts:
+ - destination: 10.255.1.15
+ repeat: 1
+ source: 10.255.1.13
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.13) - Destination: pod1-leaf6a Loopback0 (IP: 10.255.1.15)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf5a
+ hosts:
+ - destination: 10.255.1.16
+ repeat: 1
+ source: 10.255.1.13
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.13) - Destination: pod1-leaf6b Loopback0 (IP: 10.255.1.16)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf5a
+ hosts:
+ - destination: 10.255.1.17
+ repeat: 1
+ source: 10.255.1.13
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.13) - Destination: pod1-leaf7a Loopback0 (IP: 10.255.1.17)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf5a
+ hosts:
+ - destination: 10.255.1.18
+ repeat: 1
+ source: 10.255.1.13
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.13) - Destination: pod1-leaf7b Loopback0 (IP: 10.255.1.18)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf5a
+ hosts:
+ - destination: 10.255.1.19
+ repeat: 1
+ source: 10.255.1.13
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.13) - Destination: pod1-leaf8a Loopback0 (IP: 10.255.1.19)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf5a
+ hosts:
+ - destination: 10.255.1.20
+ repeat: 1
+ source: 10.255.1.13
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.13) - Destination: pod1-leaf8b Loopback0 (IP: 10.255.1.20)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf5a
+ hosts:
+ - destination: 10.255.1.21
+ repeat: 1
+ source: 10.255.1.13
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.13) - Destination: pod1-leaf9a Loopback0 (IP: 10.255.1.21)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf5a
+ hosts:
+ - destination: 10.255.1.22
+ repeat: 1
+ source: 10.255.1.13
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.13) - Destination: pod1-leaf9b Loopback0 (IP: 10.255.1.22)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf5a
+ hosts:
+ - destination: 10.255.1.23
+ repeat: 1
+ source: 10.255.1.13
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.13) - Destination: pod1-leaf10a Loopback0 (IP: 10.255.1.23)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf5a
+ hosts:
+ - destination: 10.255.1.24
+ repeat: 1
+ source: 10.255.1.13
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.13) - Destination: pod1-leaf10b Loopback0 (IP: 10.255.1.24)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf5a
+ hosts:
+ - destination: 10.255.2.1
+ repeat: 1
+ source: 10.255.1.13
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.13) - Destination: pod2-spine1 Loopback0 (IP: 10.255.2.1)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf5a
+ hosts:
+ - destination: 10.255.2.2
+ repeat: 1
+ source: 10.255.1.13
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.13) - Destination: pod2-spine2 Loopback0 (IP: 10.255.2.2)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf5a
+ hosts:
+ - destination: 10.255.2.3
+ repeat: 1
+ source: 10.255.1.13
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.13) - Destination: pod2-spine3 Loopback0 (IP: 10.255.2.3)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf5a
+ hosts:
+ - destination: 10.255.2.4
+ repeat: 1
+ source: 10.255.1.13
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.13) - Destination: pod2-spine4 Loopback0 (IP: 10.255.2.4)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf5a
+ hosts:
+ - destination: 10.255.2.5
+ repeat: 1
+ source: 10.255.1.13
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.13) - Destination: pod2-leaf1a Loopback0 (IP: 10.255.2.5)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf5a
+ hosts:
+ - destination: 10.255.2.6
+ repeat: 1
+ source: 10.255.1.13
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.13) - Destination: pod2-leaf1b Loopback0 (IP: 10.255.2.6)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf5a
+ hosts:
+ - destination: 10.255.2.7
+ repeat: 1
+ source: 10.255.1.13
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.13) - Destination: pod2-leaf2a Loopback0 (IP: 10.255.2.7)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf5a
+ hosts:
+ - destination: 10.255.2.8
+ repeat: 1
+ source: 10.255.1.13
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.13) - Destination: pod2-leaf2b Loopback0 (IP: 10.255.2.8)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf5a
+ hosts:
+ - destination: 10.255.2.9
+ repeat: 1
+ source: 10.255.1.13
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.13) - Destination: pod2-leaf3a Loopback0 (IP: 10.255.2.9)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf5a
+ hosts:
+ - destination: 10.255.2.10
+ repeat: 1
+ source: 10.255.1.13
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.13) - Destination: pod2-leaf3b Loopback0 (IP: 10.255.2.10)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf5a
+ hosts:
+ - destination: 10.255.2.11
+ repeat: 1
+ source: 10.255.1.13
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.13) - Destination: pod2-leaf4a Loopback0 (IP: 10.255.2.11)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf5a
+ hosts:
+ - destination: 10.255.2.12
+ repeat: 1
+ source: 10.255.1.13
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.13) - Destination: pod2-leaf4b Loopback0 (IP: 10.255.2.12)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf5a
+ hosts:
+ - destination: 10.255.2.13
+ repeat: 1
+ source: 10.255.1.13
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.13) - Destination: pod2-leaf5a Loopback0 (IP: 10.255.2.13)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf5a
+ hosts:
+ - destination: 10.255.2.14
+ repeat: 1
+ source: 10.255.1.13
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.13) - Destination: pod2-leaf5b Loopback0 (IP: 10.255.2.14)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf5a
+ hosts:
+ - destination: 10.255.2.15
+ repeat: 1
+ source: 10.255.1.13
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.13) - Destination: pod2-leaf6a Loopback0 (IP: 10.255.2.15)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf5a
+ hosts:
+ - destination: 10.255.2.16
+ repeat: 1
+ source: 10.255.1.13
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.13) - Destination: pod2-leaf6b Loopback0 (IP: 10.255.2.16)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf5a
+ hosts:
+ - destination: 10.255.2.17
+ repeat: 1
+ source: 10.255.1.13
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.13) - Destination: pod2-leaf7a Loopback0 (IP: 10.255.2.17)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf5a
+ hosts:
+ - destination: 10.255.2.18
+ repeat: 1
+ source: 10.255.1.13
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.13) - Destination: pod2-leaf7b Loopback0 (IP: 10.255.2.18)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf5a
+ hosts:
+ - destination: 10.255.2.19
+ repeat: 1
+ source: 10.255.1.13
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.13) - Destination: pod2-leaf8a Loopback0 (IP: 10.255.2.19)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf5a
+ hosts:
+ - destination: 10.255.2.20
+ repeat: 1
+ source: 10.255.1.13
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.13) - Destination: pod2-leaf8b Loopback0 (IP: 10.255.2.20)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf5a
+ hosts:
+ - destination: 10.255.2.21
+ repeat: 1
+ source: 10.255.1.13
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.13) - Destination: pod2-leaf9a Loopback0 (IP: 10.255.2.21)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf5a
+ hosts:
+ - destination: 10.255.2.22
+ repeat: 1
+ source: 10.255.1.13
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.13) - Destination: pod2-leaf9b Loopback0 (IP: 10.255.2.22)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf5a
+ hosts:
+ - destination: 10.255.2.23
+ repeat: 1
+ source: 10.255.1.13
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.13) - Destination: pod2-leaf10a Loopback0 (IP: 10.255.2.23)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf5a
+ hosts:
+ - destination: 10.255.2.24
+ repeat: 1
+ source: 10.255.1.13
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.13) - Destination: pod2-leaf10b Loopback0 (IP: 10.255.2.24)'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-leaf8b
+ neighbors:
+ - neighbor_device: pod2-leaf8a
+ neighbor_port: Ethernet53/1
+ port: Ethernet53/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet53/1 - Remote: pod2-leaf8a Ethernet53/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-leaf8b
+ neighbors:
+ - neighbor_device: pod2-leaf8a
+ neighbor_port: Ethernet54/1
+ port: Ethernet54/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet54/1 - Remote: pod2-leaf8a Ethernet54/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-leaf8b
+ neighbors:
+ - neighbor_device: pod2-spine1
+ neighbor_port: Ethernet16/1
+ port: Ethernet1/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet1/1 - Remote: pod2-spine1 Ethernet16/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-leaf8b
+ neighbors:
+ - neighbor_device: pod2-spine2
+ neighbor_port: Ethernet16/1
+ port: Ethernet2/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet2/1 - Remote: pod2-spine2 Ethernet16/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-leaf8b
+ neighbors:
+ - neighbor_device: pod2-spine3
+ neighbor_port: Ethernet16/1
+ port: Ethernet3/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet3/1 - Remote: pod2-spine3 Ethernet16/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-leaf8b
+ neighbors:
+ - neighbor_device: pod2-spine4
+ neighbor_port: Ethernet16/1
+ port: Ethernet4/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet4/1 - Remote: pod2-spine4 Ethernet16/1'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf8b
+ hosts:
+ - destination: 10.255.255.120
+ repeat: 1
+ source: 10.255.255.121
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet1/1 (IP: 10.255.255.121) - Destination: pod2-spine1 Ethernet16/1 (IP: 10.255.255.120)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf8b
+ hosts:
+ - destination: 10.255.255.122
+ repeat: 1
+ source: 10.255.255.123
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet2/1 (IP: 10.255.255.123) - Destination: pod2-spine2 Ethernet16/1 (IP: 10.255.255.122)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf8b
+ hosts:
+ - destination: 10.255.255.124
+ repeat: 1
+ source: 10.255.255.125
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet3/1 (IP: 10.255.255.125) - Destination: pod2-spine3 Ethernet16/1 (IP: 10.255.255.124)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf8b
+ hosts:
+ - destination: 10.255.255.126
+ repeat: 1
+ source: 10.255.255.127
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet4/1 (IP: 10.255.255.127) - Destination: pod2-spine4 Ethernet16/1 (IP: 10.255.255.126)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf8b
+ hosts:
+ - destination: 10.255.0.1
+ repeat: 1
+ source: 10.255.2.20
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.20) - Destination: super-spine1 Loopback0 (IP: 10.255.0.1)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf8b
+ hosts:
+ - destination: 10.255.0.2
+ repeat: 1
+ source: 10.255.2.20
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.20) - Destination: super-spine2 Loopback0 (IP: 10.255.0.2)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf8b
+ hosts:
+ - destination: 10.255.1.1
+ repeat: 1
+ source: 10.255.2.20
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.20) - Destination: pod1-spine1 Loopback0 (IP: 10.255.1.1)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf8b
+ hosts:
+ - destination: 10.255.1.2
+ repeat: 1
+ source: 10.255.2.20
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.20) - Destination: pod1-spine2 Loopback0 (IP: 10.255.1.2)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf8b
+ hosts:
+ - destination: 10.255.1.3
+ repeat: 1
+ source: 10.255.2.20
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.20) - Destination: pod1-spine3 Loopback0 (IP: 10.255.1.3)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf8b
+ hosts:
+ - destination: 10.255.1.4
+ repeat: 1
+ source: 10.255.2.20
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.20) - Destination: pod1-spine4 Loopback0 (IP: 10.255.1.4)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf8b
+ hosts:
+ - destination: 10.255.1.5
+ repeat: 1
+ source: 10.255.2.20
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.20) - Destination: pod1-leaf1a Loopback0 (IP: 10.255.1.5)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf8b
+ hosts:
+ - destination: 10.255.1.6
+ repeat: 1
+ source: 10.255.2.20
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.20) - Destination: pod1-leaf1b Loopback0 (IP: 10.255.1.6)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf8b
+ hosts:
+ - destination: 10.255.1.7
+ repeat: 1
+ source: 10.255.2.20
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.20) - Destination: pod1-leaf2a Loopback0 (IP: 10.255.1.7)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf8b
+ hosts:
+ - destination: 10.255.1.8
+ repeat: 1
+ source: 10.255.2.20
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.20) - Destination: pod1-leaf2b Loopback0 (IP: 10.255.1.8)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf8b
+ hosts:
+ - destination: 10.255.1.9
+ repeat: 1
+ source: 10.255.2.20
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.20) - Destination: pod1-leaf3a Loopback0 (IP: 10.255.1.9)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf8b
+ hosts:
+ - destination: 10.255.1.10
+ repeat: 1
+ source: 10.255.2.20
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.20) - Destination: pod1-leaf3b Loopback0 (IP: 10.255.1.10)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf8b
+ hosts:
+ - destination: 10.255.1.11
+ repeat: 1
+ source: 10.255.2.20
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.20) - Destination: pod1-leaf4a Loopback0 (IP: 10.255.1.11)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf8b
+ hosts:
+ - destination: 10.255.1.12
+ repeat: 1
+ source: 10.255.2.20
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.20) - Destination: pod1-leaf4b Loopback0 (IP: 10.255.1.12)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf8b
+ hosts:
+ - destination: 10.255.1.13
+ repeat: 1
+ source: 10.255.2.20
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.20) - Destination: pod1-leaf5a Loopback0 (IP: 10.255.1.13)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf8b
+ hosts:
+ - destination: 10.255.1.14
+ repeat: 1
+ source: 10.255.2.20
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.20) - Destination: pod1-leaf5b Loopback0 (IP: 10.255.1.14)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf8b
+ hosts:
+ - destination: 10.255.1.15
+ repeat: 1
+ source: 10.255.2.20
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.20) - Destination: pod1-leaf6a Loopback0 (IP: 10.255.1.15)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf8b
+ hosts:
+ - destination: 10.255.1.16
+ repeat: 1
+ source: 10.255.2.20
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.20) - Destination: pod1-leaf6b Loopback0 (IP: 10.255.1.16)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf8b
+ hosts:
+ - destination: 10.255.1.17
+ repeat: 1
+ source: 10.255.2.20
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.20) - Destination: pod1-leaf7a Loopback0 (IP: 10.255.1.17)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf8b
+ hosts:
+ - destination: 10.255.1.18
+ repeat: 1
+ source: 10.255.2.20
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.20) - Destination: pod1-leaf7b Loopback0 (IP: 10.255.1.18)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf8b
+ hosts:
+ - destination: 10.255.1.19
+ repeat: 1
+ source: 10.255.2.20
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.20) - Destination: pod1-leaf8a Loopback0 (IP: 10.255.1.19)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf8b
+ hosts:
+ - destination: 10.255.1.20
+ repeat: 1
+ source: 10.255.2.20
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.20) - Destination: pod1-leaf8b Loopback0 (IP: 10.255.1.20)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf8b
+ hosts:
+ - destination: 10.255.1.21
+ repeat: 1
+ source: 10.255.2.20
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.20) - Destination: pod1-leaf9a Loopback0 (IP: 10.255.1.21)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf8b
+ hosts:
+ - destination: 10.255.1.22
+ repeat: 1
+ source: 10.255.2.20
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.20) - Destination: pod1-leaf9b Loopback0 (IP: 10.255.1.22)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf8b
+ hosts:
+ - destination: 10.255.1.23
+ repeat: 1
+ source: 10.255.2.20
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.20) - Destination: pod1-leaf10a Loopback0 (IP: 10.255.1.23)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf8b
+ hosts:
+ - destination: 10.255.1.24
+ repeat: 1
+ source: 10.255.2.20
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.20) - Destination: pod1-leaf10b Loopback0 (IP: 10.255.1.24)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf8b
+ hosts:
+ - destination: 10.255.2.1
+ repeat: 1
+ source: 10.255.2.20
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.20) - Destination: pod2-spine1 Loopback0 (IP: 10.255.2.1)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf8b
+ hosts:
+ - destination: 10.255.2.2
+ repeat: 1
+ source: 10.255.2.20
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.20) - Destination: pod2-spine2 Loopback0 (IP: 10.255.2.2)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf8b
+ hosts:
+ - destination: 10.255.2.3
+ repeat: 1
+ source: 10.255.2.20
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.20) - Destination: pod2-spine3 Loopback0 (IP: 10.255.2.3)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf8b
+ hosts:
+ - destination: 10.255.2.4
+ repeat: 1
+ source: 10.255.2.20
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.20) - Destination: pod2-spine4 Loopback0 (IP: 10.255.2.4)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf8b
+ hosts:
+ - destination: 10.255.2.5
+ repeat: 1
+ source: 10.255.2.20
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.20) - Destination: pod2-leaf1a Loopback0 (IP: 10.255.2.5)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf8b
+ hosts:
+ - destination: 10.255.2.6
+ repeat: 1
+ source: 10.255.2.20
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.20) - Destination: pod2-leaf1b Loopback0 (IP: 10.255.2.6)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf8b
+ hosts:
+ - destination: 10.255.2.7
+ repeat: 1
+ source: 10.255.2.20
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.20) - Destination: pod2-leaf2a Loopback0 (IP: 10.255.2.7)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf8b
+ hosts:
+ - destination: 10.255.2.8
+ repeat: 1
+ source: 10.255.2.20
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.20) - Destination: pod2-leaf2b Loopback0 (IP: 10.255.2.8)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf8b
+ hosts:
+ - destination: 10.255.2.9
+ repeat: 1
+ source: 10.255.2.20
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.20) - Destination: pod2-leaf3a Loopback0 (IP: 10.255.2.9)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf8b
+ hosts:
+ - destination: 10.255.2.10
+ repeat: 1
+ source: 10.255.2.20
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.20) - Destination: pod2-leaf3b Loopback0 (IP: 10.255.2.10)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf8b
+ hosts:
+ - destination: 10.255.2.11
+ repeat: 1
+ source: 10.255.2.20
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.20) - Destination: pod2-leaf4a Loopback0 (IP: 10.255.2.11)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf8b
+ hosts:
+ - destination: 10.255.2.12
+ repeat: 1
+ source: 10.255.2.20
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.20) - Destination: pod2-leaf4b Loopback0 (IP: 10.255.2.12)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf8b
+ hosts:
+ - destination: 10.255.2.13
+ repeat: 1
+ source: 10.255.2.20
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.20) - Destination: pod2-leaf5a Loopback0 (IP: 10.255.2.13)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf8b
+ hosts:
+ - destination: 10.255.2.14
+ repeat: 1
+ source: 10.255.2.20
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.20) - Destination: pod2-leaf5b Loopback0 (IP: 10.255.2.14)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf8b
+ hosts:
+ - destination: 10.255.2.15
+ repeat: 1
+ source: 10.255.2.20
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.20) - Destination: pod2-leaf6a Loopback0 (IP: 10.255.2.15)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf8b
+ hosts:
+ - destination: 10.255.2.16
+ repeat: 1
+ source: 10.255.2.20
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.20) - Destination: pod2-leaf6b Loopback0 (IP: 10.255.2.16)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf8b
+ hosts:
+ - destination: 10.255.2.17
+ repeat: 1
+ source: 10.255.2.20
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.20) - Destination: pod2-leaf7a Loopback0 (IP: 10.255.2.17)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf8b
+ hosts:
+ - destination: 10.255.2.18
+ repeat: 1
+ source: 10.255.2.20
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.20) - Destination: pod2-leaf7b Loopback0 (IP: 10.255.2.18)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf8b
+ hosts:
+ - destination: 10.255.2.19
+ repeat: 1
+ source: 10.255.2.20
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.20) - Destination: pod2-leaf8a Loopback0 (IP: 10.255.2.19)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf8b
+ hosts:
+ - destination: 10.255.2.20
+ repeat: 1
+ source: 10.255.2.20
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.20) - Destination: pod2-leaf8b Loopback0 (IP: 10.255.2.20)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf8b
+ hosts:
+ - destination: 10.255.2.21
+ repeat: 1
+ source: 10.255.2.20
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.20) - Destination: pod2-leaf9a Loopback0 (IP: 10.255.2.21)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf8b
+ hosts:
+ - destination: 10.255.2.22
+ repeat: 1
+ source: 10.255.2.20
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.20) - Destination: pod2-leaf9b Loopback0 (IP: 10.255.2.22)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf8b
+ hosts:
+ - destination: 10.255.2.23
+ repeat: 1
+ source: 10.255.2.20
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.20) - Destination: pod2-leaf10a Loopback0 (IP: 10.255.2.23)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf8b
+ hosts:
+ - destination: 10.255.2.24
+ repeat: 1
+ source: 10.255.2.20
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.20) - Destination: pod2-leaf10b Loopback0 (IP: 10.255.2.24)'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-leaf5a
+ neighbors:
+ - neighbor_device: pod2-leaf5b
+ neighbor_port: Ethernet53/1
+ port: Ethernet53/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet53/1 - Remote: pod2-leaf5b Ethernet53/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-leaf5a
+ neighbors:
+ - neighbor_device: pod2-leaf5b
+ neighbor_port: Ethernet54/1
+ port: Ethernet54/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet54/1 - Remote: pod2-leaf5b Ethernet54/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-leaf5a
+ neighbors:
+ - neighbor_device: pod2-spine1
+ neighbor_port: Ethernet9/1
+ port: Ethernet1/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet1/1 - Remote: pod2-spine1 Ethernet9/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-leaf5a
+ neighbors:
+ - neighbor_device: pod2-spine2
+ neighbor_port: Ethernet9/1
+ port: Ethernet2/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet2/1 - Remote: pod2-spine2 Ethernet9/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-leaf5a
+ neighbors:
+ - neighbor_device: pod2-spine3
+ neighbor_port: Ethernet9/1
+ port: Ethernet3/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet3/1 - Remote: pod2-spine3 Ethernet9/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-leaf5a
+ neighbors:
+ - neighbor_device: pod2-spine4
+ neighbor_port: Ethernet9/1
+ port: Ethernet4/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet4/1 - Remote: pod2-spine4 Ethernet9/1'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf5a
+ hosts:
+ - destination: 10.255.255.64
+ repeat: 1
+ source: 10.255.255.65
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet1/1 (IP: 10.255.255.65) - Destination: pod2-spine1 Ethernet9/1 (IP: 10.255.255.64)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf5a
+ hosts:
+ - destination: 10.255.255.66
+ repeat: 1
+ source: 10.255.255.67
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet2/1 (IP: 10.255.255.67) - Destination: pod2-spine2 Ethernet9/1 (IP: 10.255.255.66)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf5a
+ hosts:
+ - destination: 10.255.255.68
+ repeat: 1
+ source: 10.255.255.69
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet3/1 (IP: 10.255.255.69) - Destination: pod2-spine3 Ethernet9/1 (IP: 10.255.255.68)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf5a
+ hosts:
+ - destination: 10.255.255.70
+ repeat: 1
+ source: 10.255.255.71
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet4/1 (IP: 10.255.255.71) - Destination: pod2-spine4 Ethernet9/1 (IP: 10.255.255.70)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf5a
+ hosts:
+ - destination: 10.255.0.1
+ repeat: 1
+ source: 10.255.2.13
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.13) - Destination: super-spine1 Loopback0 (IP: 10.255.0.1)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf5a
+ hosts:
+ - destination: 10.255.0.2
+ repeat: 1
+ source: 10.255.2.13
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.13) - Destination: super-spine2 Loopback0 (IP: 10.255.0.2)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf5a
+ hosts:
+ - destination: 10.255.1.1
+ repeat: 1
+ source: 10.255.2.13
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.13) - Destination: pod1-spine1 Loopback0 (IP: 10.255.1.1)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf5a
+ hosts:
+ - destination: 10.255.1.2
+ repeat: 1
+ source: 10.255.2.13
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.13) - Destination: pod1-spine2 Loopback0 (IP: 10.255.1.2)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf5a
+ hosts:
+ - destination: 10.255.1.3
+ repeat: 1
+ source: 10.255.2.13
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.13) - Destination: pod1-spine3 Loopback0 (IP: 10.255.1.3)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf5a
+ hosts:
+ - destination: 10.255.1.4
+ repeat: 1
+ source: 10.255.2.13
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.13) - Destination: pod1-spine4 Loopback0 (IP: 10.255.1.4)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf5a
+ hosts:
+ - destination: 10.255.1.5
+ repeat: 1
+ source: 10.255.2.13
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.13) - Destination: pod1-leaf1a Loopback0 (IP: 10.255.1.5)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf5a
+ hosts:
+ - destination: 10.255.1.6
+ repeat: 1
+ source: 10.255.2.13
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.13) - Destination: pod1-leaf1b Loopback0 (IP: 10.255.1.6)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf5a
+ hosts:
+ - destination: 10.255.1.7
+ repeat: 1
+ source: 10.255.2.13
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.13) - Destination: pod1-leaf2a Loopback0 (IP: 10.255.1.7)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf5a
+ hosts:
+ - destination: 10.255.1.8
+ repeat: 1
+ source: 10.255.2.13
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.13) - Destination: pod1-leaf2b Loopback0 (IP: 10.255.1.8)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf5a
+ hosts:
+ - destination: 10.255.1.9
+ repeat: 1
+ source: 10.255.2.13
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.13) - Destination: pod1-leaf3a Loopback0 (IP: 10.255.1.9)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf5a
+ hosts:
+ - destination: 10.255.1.10
+ repeat: 1
+ source: 10.255.2.13
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.13) - Destination: pod1-leaf3b Loopback0 (IP: 10.255.1.10)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf5a
+ hosts:
+ - destination: 10.255.1.11
+ repeat: 1
+ source: 10.255.2.13
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.13) - Destination: pod1-leaf4a Loopback0 (IP: 10.255.1.11)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf5a
+ hosts:
+ - destination: 10.255.1.12
+ repeat: 1
+ source: 10.255.2.13
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.13) - Destination: pod1-leaf4b Loopback0 (IP: 10.255.1.12)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf5a
+ hosts:
+ - destination: 10.255.1.13
+ repeat: 1
+ source: 10.255.2.13
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.13) - Destination: pod1-leaf5a Loopback0 (IP: 10.255.1.13)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf5a
+ hosts:
+ - destination: 10.255.1.14
+ repeat: 1
+ source: 10.255.2.13
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.13) - Destination: pod1-leaf5b Loopback0 (IP: 10.255.1.14)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf5a
+ hosts:
+ - destination: 10.255.1.15
+ repeat: 1
+ source: 10.255.2.13
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.13) - Destination: pod1-leaf6a Loopback0 (IP: 10.255.1.15)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf5a
+ hosts:
+ - destination: 10.255.1.16
+ repeat: 1
+ source: 10.255.2.13
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.13) - Destination: pod1-leaf6b Loopback0 (IP: 10.255.1.16)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf5a
+ hosts:
+ - destination: 10.255.1.17
+ repeat: 1
+ source: 10.255.2.13
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.13) - Destination: pod1-leaf7a Loopback0 (IP: 10.255.1.17)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf5a
+ hosts:
+ - destination: 10.255.1.18
+ repeat: 1
+ source: 10.255.2.13
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.13) - Destination: pod1-leaf7b Loopback0 (IP: 10.255.1.18)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf5a
+ hosts:
+ - destination: 10.255.1.19
+ repeat: 1
+ source: 10.255.2.13
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.13) - Destination: pod1-leaf8a Loopback0 (IP: 10.255.1.19)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf5a
+ hosts:
+ - destination: 10.255.1.20
+ repeat: 1
+ source: 10.255.2.13
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.13) - Destination: pod1-leaf8b Loopback0 (IP: 10.255.1.20)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf5a
+ hosts:
+ - destination: 10.255.1.21
+ repeat: 1
+ source: 10.255.2.13
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.13) - Destination: pod1-leaf9a Loopback0 (IP: 10.255.1.21)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf5a
+ hosts:
+ - destination: 10.255.1.22
+ repeat: 1
+ source: 10.255.2.13
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.13) - Destination: pod1-leaf9b Loopback0 (IP: 10.255.1.22)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf5a
+ hosts:
+ - destination: 10.255.1.23
+ repeat: 1
+ source: 10.255.2.13
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.13) - Destination: pod1-leaf10a Loopback0 (IP: 10.255.1.23)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf5a
+ hosts:
+ - destination: 10.255.1.24
+ repeat: 1
+ source: 10.255.2.13
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.13) - Destination: pod1-leaf10b Loopback0 (IP: 10.255.1.24)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf5a
+ hosts:
+ - destination: 10.255.2.1
+ repeat: 1
+ source: 10.255.2.13
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.13) - Destination: pod2-spine1 Loopback0 (IP: 10.255.2.1)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf5a
+ hosts:
+ - destination: 10.255.2.2
+ repeat: 1
+ source: 10.255.2.13
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.13) - Destination: pod2-spine2 Loopback0 (IP: 10.255.2.2)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf5a
+ hosts:
+ - destination: 10.255.2.3
+ repeat: 1
+ source: 10.255.2.13
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.13) - Destination: pod2-spine3 Loopback0 (IP: 10.255.2.3)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf5a
+ hosts:
+ - destination: 10.255.2.4
+ repeat: 1
+ source: 10.255.2.13
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.13) - Destination: pod2-spine4 Loopback0 (IP: 10.255.2.4)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf5a
+ hosts:
+ - destination: 10.255.2.5
+ repeat: 1
+ source: 10.255.2.13
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.13) - Destination: pod2-leaf1a Loopback0 (IP: 10.255.2.5)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf5a
+ hosts:
+ - destination: 10.255.2.6
+ repeat: 1
+ source: 10.255.2.13
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.13) - Destination: pod2-leaf1b Loopback0 (IP: 10.255.2.6)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf5a
+ hosts:
+ - destination: 10.255.2.7
+ repeat: 1
+ source: 10.255.2.13
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.13) - Destination: pod2-leaf2a Loopback0 (IP: 10.255.2.7)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf5a
+ hosts:
+ - destination: 10.255.2.8
+ repeat: 1
+ source: 10.255.2.13
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.13) - Destination: pod2-leaf2b Loopback0 (IP: 10.255.2.8)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf5a
+ hosts:
+ - destination: 10.255.2.9
+ repeat: 1
+ source: 10.255.2.13
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.13) - Destination: pod2-leaf3a Loopback0 (IP: 10.255.2.9)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf5a
+ hosts:
+ - destination: 10.255.2.10
+ repeat: 1
+ source: 10.255.2.13
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.13) - Destination: pod2-leaf3b Loopback0 (IP: 10.255.2.10)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf5a
+ hosts:
+ - destination: 10.255.2.11
+ repeat: 1
+ source: 10.255.2.13
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.13) - Destination: pod2-leaf4a Loopback0 (IP: 10.255.2.11)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf5a
+ hosts:
+ - destination: 10.255.2.12
+ repeat: 1
+ source: 10.255.2.13
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.13) - Destination: pod2-leaf4b Loopback0 (IP: 10.255.2.12)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf5a
+ hosts:
+ - destination: 10.255.2.13
+ repeat: 1
+ source: 10.255.2.13
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.13) - Destination: pod2-leaf5a Loopback0 (IP: 10.255.2.13)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf5a
+ hosts:
+ - destination: 10.255.2.14
+ repeat: 1
+ source: 10.255.2.13
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.13) - Destination: pod2-leaf5b Loopback0 (IP: 10.255.2.14)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf5a
+ hosts:
+ - destination: 10.255.2.15
+ repeat: 1
+ source: 10.255.2.13
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.13) - Destination: pod2-leaf6a Loopback0 (IP: 10.255.2.15)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf5a
+ hosts:
+ - destination: 10.255.2.16
+ repeat: 1
+ source: 10.255.2.13
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.13) - Destination: pod2-leaf6b Loopback0 (IP: 10.255.2.16)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf5a
+ hosts:
+ - destination: 10.255.2.17
+ repeat: 1
+ source: 10.255.2.13
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.13) - Destination: pod2-leaf7a Loopback0 (IP: 10.255.2.17)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf5a
+ hosts:
+ - destination: 10.255.2.18
+ repeat: 1
+ source: 10.255.2.13
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.13) - Destination: pod2-leaf7b Loopback0 (IP: 10.255.2.18)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf5a
+ hosts:
+ - destination: 10.255.2.19
+ repeat: 1
+ source: 10.255.2.13
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.13) - Destination: pod2-leaf8a Loopback0 (IP: 10.255.2.19)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf5a
+ hosts:
+ - destination: 10.255.2.20
+ repeat: 1
+ source: 10.255.2.13
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.13) - Destination: pod2-leaf8b Loopback0 (IP: 10.255.2.20)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf5a
+ hosts:
+ - destination: 10.255.2.21
+ repeat: 1
+ source: 10.255.2.13
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.13) - Destination: pod2-leaf9a Loopback0 (IP: 10.255.2.21)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf5a
+ hosts:
+ - destination: 10.255.2.22
+ repeat: 1
+ source: 10.255.2.13
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.13) - Destination: pod2-leaf9b Loopback0 (IP: 10.255.2.22)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf5a
+ hosts:
+ - destination: 10.255.2.23
+ repeat: 1
+ source: 10.255.2.13
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.13) - Destination: pod2-leaf10a Loopback0 (IP: 10.255.2.23)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf5a
+ hosts:
+ - destination: 10.255.2.24
+ repeat: 1
+ source: 10.255.2.13
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.13) - Destination: pod2-leaf10b Loopback0 (IP: 10.255.2.24)'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-leaf2a
+ neighbors:
+ - neighbor_device: pod2-leaf2b
+ neighbor_port: Ethernet53/1
+ port: Ethernet53/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet53/1 - Remote: pod2-leaf2b Ethernet53/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-leaf2a
+ neighbors:
+ - neighbor_device: pod2-leaf2b
+ neighbor_port: Ethernet54/1
+ port: Ethernet54/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet54/1 - Remote: pod2-leaf2b Ethernet54/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-leaf2a
+ neighbors:
+ - neighbor_device: pod2-spine1
+ neighbor_port: Ethernet3/1
+ port: Ethernet1/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet1/1 - Remote: pod2-spine1 Ethernet3/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-leaf2a
+ neighbors:
+ - neighbor_device: pod2-spine2
+ neighbor_port: Ethernet3/1
+ port: Ethernet2/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet2/1 - Remote: pod2-spine2 Ethernet3/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-leaf2a
+ neighbors:
+ - neighbor_device: pod2-spine3
+ neighbor_port: Ethernet3/1
+ port: Ethernet3/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet3/1 - Remote: pod2-spine3 Ethernet3/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-leaf2a
+ neighbors:
+ - neighbor_device: pod2-spine4
+ neighbor_port: Ethernet3/1
+ port: Ethernet4/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet4/1 - Remote: pod2-spine4 Ethernet3/1'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf2a
+ hosts:
+ - destination: 10.255.255.16
+ repeat: 1
+ source: 10.255.255.17
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet1/1 (IP: 10.255.255.17) - Destination: pod2-spine1 Ethernet3/1 (IP: 10.255.255.16)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf2a
+ hosts:
+ - destination: 10.255.255.18
+ repeat: 1
+ source: 10.255.255.19
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet2/1 (IP: 10.255.255.19) - Destination: pod2-spine2 Ethernet3/1 (IP: 10.255.255.18)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf2a
+ hosts:
+ - destination: 10.255.255.20
+ repeat: 1
+ source: 10.255.255.21
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet3/1 (IP: 10.255.255.21) - Destination: pod2-spine3 Ethernet3/1 (IP: 10.255.255.20)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf2a
+ hosts:
+ - destination: 10.255.255.22
+ repeat: 1
+ source: 10.255.255.23
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet4/1 (IP: 10.255.255.23) - Destination: pod2-spine4 Ethernet3/1 (IP: 10.255.255.22)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf2a
+ hosts:
+ - destination: 10.255.0.1
+ repeat: 1
+ source: 10.255.2.7
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.7) - Destination: super-spine1 Loopback0 (IP: 10.255.0.1)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf2a
+ hosts:
+ - destination: 10.255.0.2
+ repeat: 1
+ source: 10.255.2.7
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.7) - Destination: super-spine2 Loopback0 (IP: 10.255.0.2)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf2a
+ hosts:
+ - destination: 10.255.1.1
+ repeat: 1
+ source: 10.255.2.7
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.7) - Destination: pod1-spine1 Loopback0 (IP: 10.255.1.1)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf2a
+ hosts:
+ - destination: 10.255.1.2
+ repeat: 1
+ source: 10.255.2.7
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.7) - Destination: pod1-spine2 Loopback0 (IP: 10.255.1.2)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf2a
+ hosts:
+ - destination: 10.255.1.3
+ repeat: 1
+ source: 10.255.2.7
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.7) - Destination: pod1-spine3 Loopback0 (IP: 10.255.1.3)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf2a
+ hosts:
+ - destination: 10.255.1.4
+ repeat: 1
+ source: 10.255.2.7
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.7) - Destination: pod1-spine4 Loopback0 (IP: 10.255.1.4)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf2a
+ hosts:
+ - destination: 10.255.1.5
+ repeat: 1
+ source: 10.255.2.7
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.7) - Destination: pod1-leaf1a Loopback0 (IP: 10.255.1.5)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf2a
+ hosts:
+ - destination: 10.255.1.6
+ repeat: 1
+ source: 10.255.2.7
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.7) - Destination: pod1-leaf1b Loopback0 (IP: 10.255.1.6)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf2a
+ hosts:
+ - destination: 10.255.1.7
+ repeat: 1
+ source: 10.255.2.7
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.7) - Destination: pod1-leaf2a Loopback0 (IP: 10.255.1.7)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf2a
+ hosts:
+ - destination: 10.255.1.8
+ repeat: 1
+ source: 10.255.2.7
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.7) - Destination: pod1-leaf2b Loopback0 (IP: 10.255.1.8)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf2a
+ hosts:
+ - destination: 10.255.1.9
+ repeat: 1
+ source: 10.255.2.7
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.7) - Destination: pod1-leaf3a Loopback0 (IP: 10.255.1.9)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf2a
+ hosts:
+ - destination: 10.255.1.10
+ repeat: 1
+ source: 10.255.2.7
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.7) - Destination: pod1-leaf3b Loopback0 (IP: 10.255.1.10)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf2a
+ hosts:
+ - destination: 10.255.1.11
+ repeat: 1
+ source: 10.255.2.7
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.7) - Destination: pod1-leaf4a Loopback0 (IP: 10.255.1.11)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf2a
+ hosts:
+ - destination: 10.255.1.12
+ repeat: 1
+ source: 10.255.2.7
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.7) - Destination: pod1-leaf4b Loopback0 (IP: 10.255.1.12)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf2a
+ hosts:
+ - destination: 10.255.1.13
+ repeat: 1
+ source: 10.255.2.7
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.7) - Destination: pod1-leaf5a Loopback0 (IP: 10.255.1.13)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf2a
+ hosts:
+ - destination: 10.255.1.14
+ repeat: 1
+ source: 10.255.2.7
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.7) - Destination: pod1-leaf5b Loopback0 (IP: 10.255.1.14)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf2a
+ hosts:
+ - destination: 10.255.1.15
+ repeat: 1
+ source: 10.255.2.7
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.7) - Destination: pod1-leaf6a Loopback0 (IP: 10.255.1.15)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf2a
+ hosts:
+ - destination: 10.255.1.16
+ repeat: 1
+ source: 10.255.2.7
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.7) - Destination: pod1-leaf6b Loopback0 (IP: 10.255.1.16)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf2a
+ hosts:
+ - destination: 10.255.1.17
+ repeat: 1
+ source: 10.255.2.7
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.7) - Destination: pod1-leaf7a Loopback0 (IP: 10.255.1.17)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf2a
+ hosts:
+ - destination: 10.255.1.18
+ repeat: 1
+ source: 10.255.2.7
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.7) - Destination: pod1-leaf7b Loopback0 (IP: 10.255.1.18)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf2a
+ hosts:
+ - destination: 10.255.1.19
+ repeat: 1
+ source: 10.255.2.7
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.7) - Destination: pod1-leaf8a Loopback0 (IP: 10.255.1.19)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf2a
+ hosts:
+ - destination: 10.255.1.20
+ repeat: 1
+ source: 10.255.2.7
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.7) - Destination: pod1-leaf8b Loopback0 (IP: 10.255.1.20)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf2a
+ hosts:
+ - destination: 10.255.1.21
+ repeat: 1
+ source: 10.255.2.7
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.7) - Destination: pod1-leaf9a Loopback0 (IP: 10.255.1.21)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf2a
+ hosts:
+ - destination: 10.255.1.22
+ repeat: 1
+ source: 10.255.2.7
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.7) - Destination: pod1-leaf9b Loopback0 (IP: 10.255.1.22)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf2a
+ hosts:
+ - destination: 10.255.1.23
+ repeat: 1
+ source: 10.255.2.7
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.7) - Destination: pod1-leaf10a Loopback0 (IP: 10.255.1.23)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf2a
+ hosts:
+ - destination: 10.255.1.24
+ repeat: 1
+ source: 10.255.2.7
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.7) - Destination: pod1-leaf10b Loopback0 (IP: 10.255.1.24)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf2a
+ hosts:
+ - destination: 10.255.2.1
+ repeat: 1
+ source: 10.255.2.7
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.7) - Destination: pod2-spine1 Loopback0 (IP: 10.255.2.1)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf2a
+ hosts:
+ - destination: 10.255.2.2
+ repeat: 1
+ source: 10.255.2.7
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.7) - Destination: pod2-spine2 Loopback0 (IP: 10.255.2.2)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf2a
+ hosts:
+ - destination: 10.255.2.3
+ repeat: 1
+ source: 10.255.2.7
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.7) - Destination: pod2-spine3 Loopback0 (IP: 10.255.2.3)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf2a
+ hosts:
+ - destination: 10.255.2.4
+ repeat: 1
+ source: 10.255.2.7
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.7) - Destination: pod2-spine4 Loopback0 (IP: 10.255.2.4)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf2a
+ hosts:
+ - destination: 10.255.2.5
+ repeat: 1
+ source: 10.255.2.7
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.7) - Destination: pod2-leaf1a Loopback0 (IP: 10.255.2.5)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf2a
+ hosts:
+ - destination: 10.255.2.6
+ repeat: 1
+ source: 10.255.2.7
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.7) - Destination: pod2-leaf1b Loopback0 (IP: 10.255.2.6)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf2a
+ hosts:
+ - destination: 10.255.2.7
+ repeat: 1
+ source: 10.255.2.7
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.7) - Destination: pod2-leaf2a Loopback0 (IP: 10.255.2.7)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf2a
+ hosts:
+ - destination: 10.255.2.8
+ repeat: 1
+ source: 10.255.2.7
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.7) - Destination: pod2-leaf2b Loopback0 (IP: 10.255.2.8)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf2a
+ hosts:
+ - destination: 10.255.2.9
+ repeat: 1
+ source: 10.255.2.7
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.7) - Destination: pod2-leaf3a Loopback0 (IP: 10.255.2.9)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf2a
+ hosts:
+ - destination: 10.255.2.10
+ repeat: 1
+ source: 10.255.2.7
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.7) - Destination: pod2-leaf3b Loopback0 (IP: 10.255.2.10)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf2a
+ hosts:
+ - destination: 10.255.2.11
+ repeat: 1
+ source: 10.255.2.7
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.7) - Destination: pod2-leaf4a Loopback0 (IP: 10.255.2.11)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf2a
+ hosts:
+ - destination: 10.255.2.12
+ repeat: 1
+ source: 10.255.2.7
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.7) - Destination: pod2-leaf4b Loopback0 (IP: 10.255.2.12)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf2a
+ hosts:
+ - destination: 10.255.2.13
+ repeat: 1
+ source: 10.255.2.7
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.7) - Destination: pod2-leaf5a Loopback0 (IP: 10.255.2.13)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf2a
+ hosts:
+ - destination: 10.255.2.14
+ repeat: 1
+ source: 10.255.2.7
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.7) - Destination: pod2-leaf5b Loopback0 (IP: 10.255.2.14)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf2a
+ hosts:
+ - destination: 10.255.2.15
+ repeat: 1
+ source: 10.255.2.7
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.7) - Destination: pod2-leaf6a Loopback0 (IP: 10.255.2.15)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf2a
+ hosts:
+ - destination: 10.255.2.16
+ repeat: 1
+ source: 10.255.2.7
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.7) - Destination: pod2-leaf6b Loopback0 (IP: 10.255.2.16)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf2a
+ hosts:
+ - destination: 10.255.2.17
+ repeat: 1
+ source: 10.255.2.7
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.7) - Destination: pod2-leaf7a Loopback0 (IP: 10.255.2.17)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf2a
+ hosts:
+ - destination: 10.255.2.18
+ repeat: 1
+ source: 10.255.2.7
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.7) - Destination: pod2-leaf7b Loopback0 (IP: 10.255.2.18)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf2a
+ hosts:
+ - destination: 10.255.2.19
+ repeat: 1
+ source: 10.255.2.7
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.7) - Destination: pod2-leaf8a Loopback0 (IP: 10.255.2.19)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf2a
+ hosts:
+ - destination: 10.255.2.20
+ repeat: 1
+ source: 10.255.2.7
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.7) - Destination: pod2-leaf8b Loopback0 (IP: 10.255.2.20)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf2a
+ hosts:
+ - destination: 10.255.2.21
+ repeat: 1
+ source: 10.255.2.7
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.7) - Destination: pod2-leaf9a Loopback0 (IP: 10.255.2.21)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf2a
+ hosts:
+ - destination: 10.255.2.22
+ repeat: 1
+ source: 10.255.2.7
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.7) - Destination: pod2-leaf9b Loopback0 (IP: 10.255.2.22)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf2a
+ hosts:
+ - destination: 10.255.2.23
+ repeat: 1
+ source: 10.255.2.7
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.7) - Destination: pod2-leaf10a Loopback0 (IP: 10.255.2.23)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf2a
+ hosts:
+ - destination: 10.255.2.24
+ repeat: 1
+ source: 10.255.2.7
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.7) - Destination: pod2-leaf10b Loopback0 (IP: 10.255.2.24)'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-leaf9b
+ neighbors:
+ - neighbor_device: pod1-leaf9a
+ neighbor_port: Ethernet53/1
+ port: Ethernet53/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet53/1 - Remote: pod1-leaf9a Ethernet53/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-leaf9b
+ neighbors:
+ - neighbor_device: pod1-leaf9a
+ neighbor_port: Ethernet54/1
+ port: Ethernet54/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet54/1 - Remote: pod1-leaf9a Ethernet54/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-leaf9b
+ neighbors:
+ - neighbor_device: pod1-spine1
+ neighbor_port: Ethernet18/1
+ port: Ethernet1/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet1/1 - Remote: pod1-spine1 Ethernet18/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-leaf9b
+ neighbors:
+ - neighbor_device: pod1-spine2
+ neighbor_port: Ethernet18/1
+ port: Ethernet2/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet2/1 - Remote: pod1-spine2 Ethernet18/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-leaf9b
+ neighbors:
+ - neighbor_device: pod1-spine3
+ neighbor_port: Ethernet18/1
+ port: Ethernet3/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet3/1 - Remote: pod1-spine3 Ethernet18/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-leaf9b
+ neighbors:
+ - neighbor_device: pod1-spine4
+ neighbor_port: Ethernet18/1
+ port: Ethernet4/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet4/1 - Remote: pod1-spine4 Ethernet18/1'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf9b
+ hosts:
+ - destination: 10.255.255.136
+ repeat: 1
+ source: 10.255.255.137
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet1/1 (IP: 10.255.255.137) - Destination: pod1-spine1 Ethernet18/1 (IP: 10.255.255.136)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf9b
+ hosts:
+ - destination: 10.255.255.138
+ repeat: 1
+ source: 10.255.255.139
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet2/1 (IP: 10.255.255.139) - Destination: pod1-spine2 Ethernet18/1 (IP: 10.255.255.138)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf9b
+ hosts:
+ - destination: 10.255.255.140
+ repeat: 1
+ source: 10.255.255.141
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet3/1 (IP: 10.255.255.141) - Destination: pod1-spine3 Ethernet18/1 (IP: 10.255.255.140)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf9b
+ hosts:
+ - destination: 10.255.255.142
+ repeat: 1
+ source: 10.255.255.143
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet4/1 (IP: 10.255.255.143) - Destination: pod1-spine4 Ethernet18/1 (IP: 10.255.255.142)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf9b
+ hosts:
+ - destination: 10.255.0.1
+ repeat: 1
+ source: 10.255.1.22
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.22) - Destination: super-spine1 Loopback0 (IP: 10.255.0.1)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf9b
+ hosts:
+ - destination: 10.255.0.2
+ repeat: 1
+ source: 10.255.1.22
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.22) - Destination: super-spine2 Loopback0 (IP: 10.255.0.2)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf9b
+ hosts:
+ - destination: 10.255.1.1
+ repeat: 1
+ source: 10.255.1.22
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.22) - Destination: pod1-spine1 Loopback0 (IP: 10.255.1.1)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf9b
+ hosts:
+ - destination: 10.255.1.2
+ repeat: 1
+ source: 10.255.1.22
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.22) - Destination: pod1-spine2 Loopback0 (IP: 10.255.1.2)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf9b
+ hosts:
+ - destination: 10.255.1.3
+ repeat: 1
+ source: 10.255.1.22
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.22) - Destination: pod1-spine3 Loopback0 (IP: 10.255.1.3)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf9b
+ hosts:
+ - destination: 10.255.1.4
+ repeat: 1
+ source: 10.255.1.22
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.22) - Destination: pod1-spine4 Loopback0 (IP: 10.255.1.4)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf9b
+ hosts:
+ - destination: 10.255.1.5
+ repeat: 1
+ source: 10.255.1.22
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.22) - Destination: pod1-leaf1a Loopback0 (IP: 10.255.1.5)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf9b
+ hosts:
+ - destination: 10.255.1.6
+ repeat: 1
+ source: 10.255.1.22
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.22) - Destination: pod1-leaf1b Loopback0 (IP: 10.255.1.6)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf9b
+ hosts:
+ - destination: 10.255.1.7
+ repeat: 1
+ source: 10.255.1.22
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.22) - Destination: pod1-leaf2a Loopback0 (IP: 10.255.1.7)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf9b
+ hosts:
+ - destination: 10.255.1.8
+ repeat: 1
+ source: 10.255.1.22
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.22) - Destination: pod1-leaf2b Loopback0 (IP: 10.255.1.8)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf9b
+ hosts:
+ - destination: 10.255.1.9
+ repeat: 1
+ source: 10.255.1.22
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.22) - Destination: pod1-leaf3a Loopback0 (IP: 10.255.1.9)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf9b
+ hosts:
+ - destination: 10.255.1.10
+ repeat: 1
+ source: 10.255.1.22
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.22) - Destination: pod1-leaf3b Loopback0 (IP: 10.255.1.10)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf9b
+ hosts:
+ - destination: 10.255.1.11
+ repeat: 1
+ source: 10.255.1.22
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.22) - Destination: pod1-leaf4a Loopback0 (IP: 10.255.1.11)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf9b
+ hosts:
+ - destination: 10.255.1.12
+ repeat: 1
+ source: 10.255.1.22
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.22) - Destination: pod1-leaf4b Loopback0 (IP: 10.255.1.12)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf9b
+ hosts:
+ - destination: 10.255.1.13
+ repeat: 1
+ source: 10.255.1.22
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.22) - Destination: pod1-leaf5a Loopback0 (IP: 10.255.1.13)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf9b
+ hosts:
+ - destination: 10.255.1.14
+ repeat: 1
+ source: 10.255.1.22
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.22) - Destination: pod1-leaf5b Loopback0 (IP: 10.255.1.14)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf9b
+ hosts:
+ - destination: 10.255.1.15
+ repeat: 1
+ source: 10.255.1.22
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.22) - Destination: pod1-leaf6a Loopback0 (IP: 10.255.1.15)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf9b
+ hosts:
+ - destination: 10.255.1.16
+ repeat: 1
+ source: 10.255.1.22
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.22) - Destination: pod1-leaf6b Loopback0 (IP: 10.255.1.16)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf9b
+ hosts:
+ - destination: 10.255.1.17
+ repeat: 1
+ source: 10.255.1.22
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.22) - Destination: pod1-leaf7a Loopback0 (IP: 10.255.1.17)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf9b
+ hosts:
+ - destination: 10.255.1.18
+ repeat: 1
+ source: 10.255.1.22
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.22) - Destination: pod1-leaf7b Loopback0 (IP: 10.255.1.18)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf9b
+ hosts:
+ - destination: 10.255.1.19
+ repeat: 1
+ source: 10.255.1.22
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.22) - Destination: pod1-leaf8a Loopback0 (IP: 10.255.1.19)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf9b
+ hosts:
+ - destination: 10.255.1.20
+ repeat: 1
+ source: 10.255.1.22
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.22) - Destination: pod1-leaf8b Loopback0 (IP: 10.255.1.20)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf9b
+ hosts:
+ - destination: 10.255.1.21
+ repeat: 1
+ source: 10.255.1.22
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.22) - Destination: pod1-leaf9a Loopback0 (IP: 10.255.1.21)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf9b
+ hosts:
+ - destination: 10.255.1.22
+ repeat: 1
+ source: 10.255.1.22
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.22) - Destination: pod1-leaf9b Loopback0 (IP: 10.255.1.22)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf9b
+ hosts:
+ - destination: 10.255.1.23
+ repeat: 1
+ source: 10.255.1.22
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.22) - Destination: pod1-leaf10a Loopback0 (IP: 10.255.1.23)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf9b
+ hosts:
+ - destination: 10.255.1.24
+ repeat: 1
+ source: 10.255.1.22
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.22) - Destination: pod1-leaf10b Loopback0 (IP: 10.255.1.24)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf9b
+ hosts:
+ - destination: 10.255.2.1
+ repeat: 1
+ source: 10.255.1.22
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.22) - Destination: pod2-spine1 Loopback0 (IP: 10.255.2.1)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf9b
+ hosts:
+ - destination: 10.255.2.2
+ repeat: 1
+ source: 10.255.1.22
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.22) - Destination: pod2-spine2 Loopback0 (IP: 10.255.2.2)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf9b
+ hosts:
+ - destination: 10.255.2.3
+ repeat: 1
+ source: 10.255.1.22
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.22) - Destination: pod2-spine3 Loopback0 (IP: 10.255.2.3)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf9b
+ hosts:
+ - destination: 10.255.2.4
+ repeat: 1
+ source: 10.255.1.22
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.22) - Destination: pod2-spine4 Loopback0 (IP: 10.255.2.4)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf9b
+ hosts:
+ - destination: 10.255.2.5
+ repeat: 1
+ source: 10.255.1.22
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.22) - Destination: pod2-leaf1a Loopback0 (IP: 10.255.2.5)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf9b
+ hosts:
+ - destination: 10.255.2.6
+ repeat: 1
+ source: 10.255.1.22
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.22) - Destination: pod2-leaf1b Loopback0 (IP: 10.255.2.6)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf9b
+ hosts:
+ - destination: 10.255.2.7
+ repeat: 1
+ source: 10.255.1.22
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.22) - Destination: pod2-leaf2a Loopback0 (IP: 10.255.2.7)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf9b
+ hosts:
+ - destination: 10.255.2.8
+ repeat: 1
+ source: 10.255.1.22
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.22) - Destination: pod2-leaf2b Loopback0 (IP: 10.255.2.8)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf9b
+ hosts:
+ - destination: 10.255.2.9
+ repeat: 1
+ source: 10.255.1.22
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.22) - Destination: pod2-leaf3a Loopback0 (IP: 10.255.2.9)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf9b
+ hosts:
+ - destination: 10.255.2.10
+ repeat: 1
+ source: 10.255.1.22
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.22) - Destination: pod2-leaf3b Loopback0 (IP: 10.255.2.10)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf9b
+ hosts:
+ - destination: 10.255.2.11
+ repeat: 1
+ source: 10.255.1.22
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.22) - Destination: pod2-leaf4a Loopback0 (IP: 10.255.2.11)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf9b
+ hosts:
+ - destination: 10.255.2.12
+ repeat: 1
+ source: 10.255.1.22
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.22) - Destination: pod2-leaf4b Loopback0 (IP: 10.255.2.12)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf9b
+ hosts:
+ - destination: 10.255.2.13
+ repeat: 1
+ source: 10.255.1.22
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.22) - Destination: pod2-leaf5a Loopback0 (IP: 10.255.2.13)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf9b
+ hosts:
+ - destination: 10.255.2.14
+ repeat: 1
+ source: 10.255.1.22
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.22) - Destination: pod2-leaf5b Loopback0 (IP: 10.255.2.14)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf9b
+ hosts:
+ - destination: 10.255.2.15
+ repeat: 1
+ source: 10.255.1.22
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.22) - Destination: pod2-leaf6a Loopback0 (IP: 10.255.2.15)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf9b
+ hosts:
+ - destination: 10.255.2.16
+ repeat: 1
+ source: 10.255.1.22
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.22) - Destination: pod2-leaf6b Loopback0 (IP: 10.255.2.16)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf9b
+ hosts:
+ - destination: 10.255.2.17
+ repeat: 1
+ source: 10.255.1.22
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.22) - Destination: pod2-leaf7a Loopback0 (IP: 10.255.2.17)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf9b
+ hosts:
+ - destination: 10.255.2.18
+ repeat: 1
+ source: 10.255.1.22
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.22) - Destination: pod2-leaf7b Loopback0 (IP: 10.255.2.18)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf9b
+ hosts:
+ - destination: 10.255.2.19
+ repeat: 1
+ source: 10.255.1.22
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.22) - Destination: pod2-leaf8a Loopback0 (IP: 10.255.2.19)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf9b
+ hosts:
+ - destination: 10.255.2.20
+ repeat: 1
+ source: 10.255.1.22
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.22) - Destination: pod2-leaf8b Loopback0 (IP: 10.255.2.20)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf9b
+ hosts:
+ - destination: 10.255.2.21
+ repeat: 1
+ source: 10.255.1.22
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.22) - Destination: pod2-leaf9a Loopback0 (IP: 10.255.2.21)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf9b
+ hosts:
+ - destination: 10.255.2.22
+ repeat: 1
+ source: 10.255.1.22
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.22) - Destination: pod2-leaf9b Loopback0 (IP: 10.255.2.22)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf9b
+ hosts:
+ - destination: 10.255.2.23
+ repeat: 1
+ source: 10.255.1.22
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.22) - Destination: pod2-leaf10a Loopback0 (IP: 10.255.2.23)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf9b
+ hosts:
+ - destination: 10.255.2.24
+ repeat: 1
+ source: 10.255.1.22
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.22) - Destination: pod2-leaf10b Loopback0 (IP: 10.255.2.24)'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-spine2
+ neighbors:
+ - neighbor_device: pod2-leaf1a
+ neighbor_port: Ethernet2/1
+ port: Ethernet1/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet1/1 - Remote: pod2-leaf1a Ethernet2/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-spine2
+ neighbors:
+ - neighbor_device: pod2-leaf1b
+ neighbor_port: Ethernet2/1
+ port: Ethernet2/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet2/1 - Remote: pod2-leaf1b Ethernet2/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-spine2
+ neighbors:
+ - neighbor_device: pod2-leaf2a
+ neighbor_port: Ethernet2/1
+ port: Ethernet3/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet3/1 - Remote: pod2-leaf2a Ethernet2/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-spine2
+ neighbors:
+ - neighbor_device: pod2-leaf2b
+ neighbor_port: Ethernet2/1
+ port: Ethernet4/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet4/1 - Remote: pod2-leaf2b Ethernet2/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-spine2
+ neighbors:
+ - neighbor_device: pod2-leaf3a
+ neighbor_port: Ethernet2/1
+ port: Ethernet5/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet5/1 - Remote: pod2-leaf3a Ethernet2/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-spine2
+ neighbors:
+ - neighbor_device: pod2-leaf3b
+ neighbor_port: Ethernet2/1
+ port: Ethernet6/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet6/1 - Remote: pod2-leaf3b Ethernet2/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-spine2
+ neighbors:
+ - neighbor_device: pod2-leaf4a
+ neighbor_port: Ethernet2/1
+ port: Ethernet7/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet7/1 - Remote: pod2-leaf4a Ethernet2/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-spine2
+ neighbors:
+ - neighbor_device: pod2-leaf4b
+ neighbor_port: Ethernet2/1
+ port: Ethernet8/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet8/1 - Remote: pod2-leaf4b Ethernet2/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-spine2
+ neighbors:
+ - neighbor_device: pod2-leaf5a
+ neighbor_port: Ethernet2/1
+ port: Ethernet9/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet9/1 - Remote: pod2-leaf5a Ethernet2/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-spine2
+ neighbors:
+ - neighbor_device: pod2-leaf5b
+ neighbor_port: Ethernet2/1
+ port: Ethernet10/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet10/1 - Remote: pod2-leaf5b Ethernet2/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-spine2
+ neighbors:
+ - neighbor_device: pod2-leaf6a
+ neighbor_port: Ethernet2/1
+ port: Ethernet11/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet11/1 - Remote: pod2-leaf6a Ethernet2/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-spine2
+ neighbors:
+ - neighbor_device: pod2-leaf6b
+ neighbor_port: Ethernet2/1
+ port: Ethernet12/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet12/1 - Remote: pod2-leaf6b Ethernet2/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-spine2
+ neighbors:
+ - neighbor_device: pod2-leaf7a
+ neighbor_port: Ethernet2/1
+ port: Ethernet13/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet13/1 - Remote: pod2-leaf7a Ethernet2/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-spine2
+ neighbors:
+ - neighbor_device: pod2-leaf7b
+ neighbor_port: Ethernet2/1
+ port: Ethernet14/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet14/1 - Remote: pod2-leaf7b Ethernet2/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-spine2
+ neighbors:
+ - neighbor_device: pod2-leaf8a
+ neighbor_port: Ethernet2/1
+ port: Ethernet15/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet15/1 - Remote: pod2-leaf8a Ethernet2/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-spine2
+ neighbors:
+ - neighbor_device: pod2-leaf8b
+ neighbor_port: Ethernet2/1
+ port: Ethernet16/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet16/1 - Remote: pod2-leaf8b Ethernet2/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-spine2
+ neighbors:
+ - neighbor_device: pod2-leaf9a
+ neighbor_port: Ethernet2/1
+ port: Ethernet17/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet17/1 - Remote: pod2-leaf9a Ethernet2/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-spine2
+ neighbors:
+ - neighbor_device: pod2-leaf9b
+ neighbor_port: Ethernet2/1
+ port: Ethernet18/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet18/1 - Remote: pod2-leaf9b Ethernet2/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-spine2
+ neighbors:
+ - neighbor_device: pod2-leaf10a
+ neighbor_port: Ethernet2/1
+ port: Ethernet19/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet19/1 - Remote: pod2-leaf10a Ethernet2/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-spine2
+ neighbors:
+ - neighbor_device: pod2-leaf10b
+ neighbor_port: Ethernet2/1
+ port: Ethernet20/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet20/1 - Remote: pod2-leaf10b Ethernet2/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-spine2
+ neighbors:
+ - neighbor_device: super-spine1
+ neighbor_port: Ethernet6/1
+ port: Ethernet31/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet31/1 - Remote: super-spine1 Ethernet6/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-spine2
+ neighbors:
+ - neighbor_device: super-spine2
+ neighbor_port: Ethernet6/1
+ port: Ethernet32/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet32/1 - Remote: super-spine2 Ethernet6/1'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-spine2
+ hosts:
+ - destination: 10.255.255.3
+ repeat: 1
+ source: 10.255.255.2
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet1/1 (IP: 10.255.255.2) - Destination: pod2-leaf1a Ethernet2/1 (IP: 10.255.255.3)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-spine2
+ hosts:
+ - destination: 10.255.255.11
+ repeat: 1
+ source: 10.255.255.10
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet2/1 (IP: 10.255.255.10) - Destination: pod2-leaf1b Ethernet2/1 (IP: 10.255.255.11)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-spine2
+ hosts:
+ - destination: 10.255.255.19
+ repeat: 1
+ source: 10.255.255.18
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet3/1 (IP: 10.255.255.18) - Destination: pod2-leaf2a Ethernet2/1 (IP: 10.255.255.19)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-spine2
+ hosts:
+ - destination: 10.255.255.27
+ repeat: 1
+ source: 10.255.255.26
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet4/1 (IP: 10.255.255.26) - Destination: pod2-leaf2b Ethernet2/1 (IP: 10.255.255.27)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-spine2
+ hosts:
+ - destination: 10.255.255.35
+ repeat: 1
+ source: 10.255.255.34
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet5/1 (IP: 10.255.255.34) - Destination: pod2-leaf3a Ethernet2/1 (IP: 10.255.255.35)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-spine2
+ hosts:
+ - destination: 10.255.255.43
+ repeat: 1
+ source: 10.255.255.42
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet6/1 (IP: 10.255.255.42) - Destination: pod2-leaf3b Ethernet2/1 (IP: 10.255.255.43)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-spine2
+ hosts:
+ - destination: 10.255.255.51
+ repeat: 1
+ source: 10.255.255.50
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet7/1 (IP: 10.255.255.50) - Destination: pod2-leaf4a Ethernet2/1 (IP: 10.255.255.51)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-spine2
+ hosts:
+ - destination: 10.255.255.59
+ repeat: 1
+ source: 10.255.255.58
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet8/1 (IP: 10.255.255.58) - Destination: pod2-leaf4b Ethernet2/1 (IP: 10.255.255.59)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-spine2
+ hosts:
+ - destination: 10.255.255.67
+ repeat: 1
+ source: 10.255.255.66
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet9/1 (IP: 10.255.255.66) - Destination: pod2-leaf5a Ethernet2/1 (IP: 10.255.255.67)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-spine2
+ hosts:
+ - destination: 10.255.255.75
+ repeat: 1
+ source: 10.255.255.74
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet10/1 (IP: 10.255.255.74) - Destination: pod2-leaf5b Ethernet2/1 (IP: 10.255.255.75)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-spine2
+ hosts:
+ - destination: 10.255.255.83
+ repeat: 1
+ source: 10.255.255.82
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet11/1 (IP: 10.255.255.82) - Destination: pod2-leaf6a Ethernet2/1 (IP: 10.255.255.83)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-spine2
+ hosts:
+ - destination: 10.255.255.91
+ repeat: 1
+ source: 10.255.255.90
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet12/1 (IP: 10.255.255.90) - Destination: pod2-leaf6b Ethernet2/1 (IP: 10.255.255.91)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-spine2
+ hosts:
+ - destination: 10.255.255.99
+ repeat: 1
+ source: 10.255.255.98
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet13/1 (IP: 10.255.255.98) - Destination: pod2-leaf7a Ethernet2/1 (IP: 10.255.255.99)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-spine2
+ hosts:
+ - destination: 10.255.255.107
+ repeat: 1
+ source: 10.255.255.106
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet14/1 (IP: 10.255.255.106) - Destination: pod2-leaf7b Ethernet2/1 (IP: 10.255.255.107)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-spine2
+ hosts:
+ - destination: 10.255.255.115
+ repeat: 1
+ source: 10.255.255.114
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet15/1 (IP: 10.255.255.114) - Destination: pod2-leaf8a Ethernet2/1 (IP: 10.255.255.115)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-spine2
+ hosts:
+ - destination: 10.255.255.123
+ repeat: 1
+ source: 10.255.255.122
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet16/1 (IP: 10.255.255.122) - Destination: pod2-leaf8b Ethernet2/1 (IP: 10.255.255.123)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-spine2
+ hosts:
+ - destination: 10.255.255.131
+ repeat: 1
+ source: 10.255.255.130
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet17/1 (IP: 10.255.255.130) - Destination: pod2-leaf9a Ethernet2/1 (IP: 10.255.255.131)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-spine2
+ hosts:
+ - destination: 10.255.255.139
+ repeat: 1
+ source: 10.255.255.138
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet18/1 (IP: 10.255.255.138) - Destination: pod2-leaf9b Ethernet2/1 (IP: 10.255.255.139)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-spine2
+ hosts:
+ - destination: 10.255.255.147
+ repeat: 1
+ source: 10.255.255.146
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet19/1 (IP: 10.255.255.146) - Destination: pod2-leaf10a Ethernet2/1 (IP: 10.255.255.147)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-spine2
+ hosts:
+ - destination: 10.255.255.155
+ repeat: 1
+ source: 10.255.255.154
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet20/1 (IP: 10.255.255.154) - Destination: pod2-leaf10b Ethernet2/1 (IP: 10.255.255.155)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-spine2
+ hosts:
+ - destination: 10.255.255.132
+ repeat: 1
+ source: 10.255.255.133
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet31/1 (IP: 10.255.255.133) - Destination: super-spine1 Ethernet6/1 (IP: 10.255.255.132)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-spine2
+ hosts:
+ - destination: 10.255.255.134
+ repeat: 1
+ source: 10.255.255.135
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet32/1 (IP: 10.255.255.135) - Destination: super-spine2 Ethernet6/1 (IP: 10.255.255.134)'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-leaf4a
+ neighbors:
+ - neighbor_device: pod1-leaf4b
+ neighbor_port: Ethernet53/1
+ port: Ethernet53/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet53/1 - Remote: pod1-leaf4b Ethernet53/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-leaf4a
+ neighbors:
+ - neighbor_device: pod1-leaf4b
+ neighbor_port: Ethernet54/1
+ port: Ethernet54/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet54/1 - Remote: pod1-leaf4b Ethernet54/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-leaf4a
+ neighbors:
+ - neighbor_device: pod1-spine1
+ neighbor_port: Ethernet7/1
+ port: Ethernet1/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet1/1 - Remote: pod1-spine1 Ethernet7/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-leaf4a
+ neighbors:
+ - neighbor_device: pod1-spine2
+ neighbor_port: Ethernet7/1
+ port: Ethernet2/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet2/1 - Remote: pod1-spine2 Ethernet7/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-leaf4a
+ neighbors:
+ - neighbor_device: pod1-spine3
+ neighbor_port: Ethernet7/1
+ port: Ethernet3/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet3/1 - Remote: pod1-spine3 Ethernet7/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-leaf4a
+ neighbors:
+ - neighbor_device: pod1-spine4
+ neighbor_port: Ethernet7/1
+ port: Ethernet4/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet4/1 - Remote: pod1-spine4 Ethernet7/1'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf4a
+ hosts:
+ - destination: 10.255.255.48
+ repeat: 1
+ source: 10.255.255.49
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet1/1 (IP: 10.255.255.49) - Destination: pod1-spine1 Ethernet7/1 (IP: 10.255.255.48)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf4a
+ hosts:
+ - destination: 10.255.255.50
+ repeat: 1
+ source: 10.255.255.51
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet2/1 (IP: 10.255.255.51) - Destination: pod1-spine2 Ethernet7/1 (IP: 10.255.255.50)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf4a
+ hosts:
+ - destination: 10.255.255.52
+ repeat: 1
+ source: 10.255.255.53
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet3/1 (IP: 10.255.255.53) - Destination: pod1-spine3 Ethernet7/1 (IP: 10.255.255.52)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf4a
+ hosts:
+ - destination: 10.255.255.54
+ repeat: 1
+ source: 10.255.255.55
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet4/1 (IP: 10.255.255.55) - Destination: pod1-spine4 Ethernet7/1 (IP: 10.255.255.54)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf4a
+ hosts:
+ - destination: 10.255.0.1
+ repeat: 1
+ source: 10.255.1.11
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.11) - Destination: super-spine1 Loopback0 (IP: 10.255.0.1)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf4a
+ hosts:
+ - destination: 10.255.0.2
+ repeat: 1
+ source: 10.255.1.11
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.11) - Destination: super-spine2 Loopback0 (IP: 10.255.0.2)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf4a
+ hosts:
+ - destination: 10.255.1.1
+ repeat: 1
+ source: 10.255.1.11
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.11) - Destination: pod1-spine1 Loopback0 (IP: 10.255.1.1)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf4a
+ hosts:
+ - destination: 10.255.1.2
+ repeat: 1
+ source: 10.255.1.11
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.11) - Destination: pod1-spine2 Loopback0 (IP: 10.255.1.2)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf4a
+ hosts:
+ - destination: 10.255.1.3
+ repeat: 1
+ source: 10.255.1.11
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.11) - Destination: pod1-spine3 Loopback0 (IP: 10.255.1.3)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf4a
+ hosts:
+ - destination: 10.255.1.4
+ repeat: 1
+ source: 10.255.1.11
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.11) - Destination: pod1-spine4 Loopback0 (IP: 10.255.1.4)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf4a
+ hosts:
+ - destination: 10.255.1.5
+ repeat: 1
+ source: 10.255.1.11
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.11) - Destination: pod1-leaf1a Loopback0 (IP: 10.255.1.5)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf4a
+ hosts:
+ - destination: 10.255.1.6
+ repeat: 1
+ source: 10.255.1.11
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.11) - Destination: pod1-leaf1b Loopback0 (IP: 10.255.1.6)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf4a
+ hosts:
+ - destination: 10.255.1.7
+ repeat: 1
+ source: 10.255.1.11
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.11) - Destination: pod1-leaf2a Loopback0 (IP: 10.255.1.7)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf4a
+ hosts:
+ - destination: 10.255.1.8
+ repeat: 1
+ source: 10.255.1.11
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.11) - Destination: pod1-leaf2b Loopback0 (IP: 10.255.1.8)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf4a
+ hosts:
+ - destination: 10.255.1.9
+ repeat: 1
+ source: 10.255.1.11
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.11) - Destination: pod1-leaf3a Loopback0 (IP: 10.255.1.9)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf4a
+ hosts:
+ - destination: 10.255.1.10
+ repeat: 1
+ source: 10.255.1.11
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.11) - Destination: pod1-leaf3b Loopback0 (IP: 10.255.1.10)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf4a
+ hosts:
+ - destination: 10.255.1.11
+ repeat: 1
+ source: 10.255.1.11
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.11) - Destination: pod1-leaf4a Loopback0 (IP: 10.255.1.11)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf4a
+ hosts:
+ - destination: 10.255.1.12
+ repeat: 1
+ source: 10.255.1.11
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.11) - Destination: pod1-leaf4b Loopback0 (IP: 10.255.1.12)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf4a
+ hosts:
+ - destination: 10.255.1.13
+ repeat: 1
+ source: 10.255.1.11
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.11) - Destination: pod1-leaf5a Loopback0 (IP: 10.255.1.13)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf4a
+ hosts:
+ - destination: 10.255.1.14
+ repeat: 1
+ source: 10.255.1.11
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.11) - Destination: pod1-leaf5b Loopback0 (IP: 10.255.1.14)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf4a
+ hosts:
+ - destination: 10.255.1.15
+ repeat: 1
+ source: 10.255.1.11
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.11) - Destination: pod1-leaf6a Loopback0 (IP: 10.255.1.15)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf4a
+ hosts:
+ - destination: 10.255.1.16
+ repeat: 1
+ source: 10.255.1.11
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.11) - Destination: pod1-leaf6b Loopback0 (IP: 10.255.1.16)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf4a
+ hosts:
+ - destination: 10.255.1.17
+ repeat: 1
+ source: 10.255.1.11
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.11) - Destination: pod1-leaf7a Loopback0 (IP: 10.255.1.17)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf4a
+ hosts:
+ - destination: 10.255.1.18
+ repeat: 1
+ source: 10.255.1.11
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.11) - Destination: pod1-leaf7b Loopback0 (IP: 10.255.1.18)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf4a
+ hosts:
+ - destination: 10.255.1.19
+ repeat: 1
+ source: 10.255.1.11
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.11) - Destination: pod1-leaf8a Loopback0 (IP: 10.255.1.19)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf4a
+ hosts:
+ - destination: 10.255.1.20
+ repeat: 1
+ source: 10.255.1.11
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.11) - Destination: pod1-leaf8b Loopback0 (IP: 10.255.1.20)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf4a
+ hosts:
+ - destination: 10.255.1.21
+ repeat: 1
+ source: 10.255.1.11
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.11) - Destination: pod1-leaf9a Loopback0 (IP: 10.255.1.21)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf4a
+ hosts:
+ - destination: 10.255.1.22
+ repeat: 1
+ source: 10.255.1.11
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.11) - Destination: pod1-leaf9b Loopback0 (IP: 10.255.1.22)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf4a
+ hosts:
+ - destination: 10.255.1.23
+ repeat: 1
+ source: 10.255.1.11
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.11) - Destination: pod1-leaf10a Loopback0 (IP: 10.255.1.23)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf4a
+ hosts:
+ - destination: 10.255.1.24
+ repeat: 1
+ source: 10.255.1.11
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.11) - Destination: pod1-leaf10b Loopback0 (IP: 10.255.1.24)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf4a
+ hosts:
+ - destination: 10.255.2.1
+ repeat: 1
+ source: 10.255.1.11
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.11) - Destination: pod2-spine1 Loopback0 (IP: 10.255.2.1)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf4a
+ hosts:
+ - destination: 10.255.2.2
+ repeat: 1
+ source: 10.255.1.11
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.11) - Destination: pod2-spine2 Loopback0 (IP: 10.255.2.2)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf4a
+ hosts:
+ - destination: 10.255.2.3
+ repeat: 1
+ source: 10.255.1.11
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.11) - Destination: pod2-spine3 Loopback0 (IP: 10.255.2.3)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf4a
+ hosts:
+ - destination: 10.255.2.4
+ repeat: 1
+ source: 10.255.1.11
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.11) - Destination: pod2-spine4 Loopback0 (IP: 10.255.2.4)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf4a
+ hosts:
+ - destination: 10.255.2.5
+ repeat: 1
+ source: 10.255.1.11
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.11) - Destination: pod2-leaf1a Loopback0 (IP: 10.255.2.5)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf4a
+ hosts:
+ - destination: 10.255.2.6
+ repeat: 1
+ source: 10.255.1.11
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.11) - Destination: pod2-leaf1b Loopback0 (IP: 10.255.2.6)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf4a
+ hosts:
+ - destination: 10.255.2.7
+ repeat: 1
+ source: 10.255.1.11
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.11) - Destination: pod2-leaf2a Loopback0 (IP: 10.255.2.7)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf4a
+ hosts:
+ - destination: 10.255.2.8
+ repeat: 1
+ source: 10.255.1.11
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.11) - Destination: pod2-leaf2b Loopback0 (IP: 10.255.2.8)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf4a
+ hosts:
+ - destination: 10.255.2.9
+ repeat: 1
+ source: 10.255.1.11
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.11) - Destination: pod2-leaf3a Loopback0 (IP: 10.255.2.9)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf4a
+ hosts:
+ - destination: 10.255.2.10
+ repeat: 1
+ source: 10.255.1.11
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.11) - Destination: pod2-leaf3b Loopback0 (IP: 10.255.2.10)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf4a
+ hosts:
+ - destination: 10.255.2.11
+ repeat: 1
+ source: 10.255.1.11
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.11) - Destination: pod2-leaf4a Loopback0 (IP: 10.255.2.11)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf4a
+ hosts:
+ - destination: 10.255.2.12
+ repeat: 1
+ source: 10.255.1.11
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.11) - Destination: pod2-leaf4b Loopback0 (IP: 10.255.2.12)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf4a
+ hosts:
+ - destination: 10.255.2.13
+ repeat: 1
+ source: 10.255.1.11
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.11) - Destination: pod2-leaf5a Loopback0 (IP: 10.255.2.13)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf4a
+ hosts:
+ - destination: 10.255.2.14
+ repeat: 1
+ source: 10.255.1.11
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.11) - Destination: pod2-leaf5b Loopback0 (IP: 10.255.2.14)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf4a
+ hosts:
+ - destination: 10.255.2.15
+ repeat: 1
+ source: 10.255.1.11
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.11) - Destination: pod2-leaf6a Loopback0 (IP: 10.255.2.15)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf4a
+ hosts:
+ - destination: 10.255.2.16
+ repeat: 1
+ source: 10.255.1.11
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.11) - Destination: pod2-leaf6b Loopback0 (IP: 10.255.2.16)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf4a
+ hosts:
+ - destination: 10.255.2.17
+ repeat: 1
+ source: 10.255.1.11
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.11) - Destination: pod2-leaf7a Loopback0 (IP: 10.255.2.17)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf4a
+ hosts:
+ - destination: 10.255.2.18
+ repeat: 1
+ source: 10.255.1.11
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.11) - Destination: pod2-leaf7b Loopback0 (IP: 10.255.2.18)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf4a
+ hosts:
+ - destination: 10.255.2.19
+ repeat: 1
+ source: 10.255.1.11
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.11) - Destination: pod2-leaf8a Loopback0 (IP: 10.255.2.19)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf4a
+ hosts:
+ - destination: 10.255.2.20
+ repeat: 1
+ source: 10.255.1.11
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.11) - Destination: pod2-leaf8b Loopback0 (IP: 10.255.2.20)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf4a
+ hosts:
+ - destination: 10.255.2.21
+ repeat: 1
+ source: 10.255.1.11
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.11) - Destination: pod2-leaf9a Loopback0 (IP: 10.255.2.21)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf4a
+ hosts:
+ - destination: 10.255.2.22
+ repeat: 1
+ source: 10.255.1.11
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.11) - Destination: pod2-leaf9b Loopback0 (IP: 10.255.2.22)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf4a
+ hosts:
+ - destination: 10.255.2.23
+ repeat: 1
+ source: 10.255.1.11
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.11) - Destination: pod2-leaf10a Loopback0 (IP: 10.255.2.23)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf4a
+ hosts:
+ - destination: 10.255.2.24
+ repeat: 1
+ source: 10.255.1.11
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.11) - Destination: pod2-leaf10b Loopback0 (IP: 10.255.2.24)'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-leaf3a
+ neighbors:
+ - neighbor_device: pod1-leaf3b
+ neighbor_port: Ethernet53/1
+ port: Ethernet53/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet53/1 - Remote: pod1-leaf3b Ethernet53/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-leaf3a
+ neighbors:
+ - neighbor_device: pod1-leaf3b
+ neighbor_port: Ethernet54/1
+ port: Ethernet54/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet54/1 - Remote: pod1-leaf3b Ethernet54/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-leaf3a
+ neighbors:
+ - neighbor_device: pod1-spine1
+ neighbor_port: Ethernet5/1
+ port: Ethernet1/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet1/1 - Remote: pod1-spine1 Ethernet5/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-leaf3a
+ neighbors:
+ - neighbor_device: pod1-spine2
+ neighbor_port: Ethernet5/1
+ port: Ethernet2/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet2/1 - Remote: pod1-spine2 Ethernet5/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-leaf3a
+ neighbors:
+ - neighbor_device: pod1-spine3
+ neighbor_port: Ethernet5/1
+ port: Ethernet3/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet3/1 - Remote: pod1-spine3 Ethernet5/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-leaf3a
+ neighbors:
+ - neighbor_device: pod1-spine4
+ neighbor_port: Ethernet5/1
+ port: Ethernet4/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet4/1 - Remote: pod1-spine4 Ethernet5/1'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf3a
+ hosts:
+ - destination: 10.255.255.32
+ repeat: 1
+ source: 10.255.255.33
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet1/1 (IP: 10.255.255.33) - Destination: pod1-spine1 Ethernet5/1 (IP: 10.255.255.32)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf3a
+ hosts:
+ - destination: 10.255.255.34
+ repeat: 1
+ source: 10.255.255.35
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet2/1 (IP: 10.255.255.35) - Destination: pod1-spine2 Ethernet5/1 (IP: 10.255.255.34)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf3a
+ hosts:
+ - destination: 10.255.255.36
+ repeat: 1
+ source: 10.255.255.37
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet3/1 (IP: 10.255.255.37) - Destination: pod1-spine3 Ethernet5/1 (IP: 10.255.255.36)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf3a
+ hosts:
+ - destination: 10.255.255.38
+ repeat: 1
+ source: 10.255.255.39
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet4/1 (IP: 10.255.255.39) - Destination: pod1-spine4 Ethernet5/1 (IP: 10.255.255.38)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf3a
+ hosts:
+ - destination: 10.255.0.1
+ repeat: 1
+ source: 10.255.1.9
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.9) - Destination: super-spine1 Loopback0 (IP: 10.255.0.1)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf3a
+ hosts:
+ - destination: 10.255.0.2
+ repeat: 1
+ source: 10.255.1.9
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.9) - Destination: super-spine2 Loopback0 (IP: 10.255.0.2)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf3a
+ hosts:
+ - destination: 10.255.1.1
+ repeat: 1
+ source: 10.255.1.9
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.9) - Destination: pod1-spine1 Loopback0 (IP: 10.255.1.1)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf3a
+ hosts:
+ - destination: 10.255.1.2
+ repeat: 1
+ source: 10.255.1.9
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.9) - Destination: pod1-spine2 Loopback0 (IP: 10.255.1.2)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf3a
+ hosts:
+ - destination: 10.255.1.3
+ repeat: 1
+ source: 10.255.1.9
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.9) - Destination: pod1-spine3 Loopback0 (IP: 10.255.1.3)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf3a
+ hosts:
+ - destination: 10.255.1.4
+ repeat: 1
+ source: 10.255.1.9
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.9) - Destination: pod1-spine4 Loopback0 (IP: 10.255.1.4)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf3a
+ hosts:
+ - destination: 10.255.1.5
+ repeat: 1
+ source: 10.255.1.9
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.9) - Destination: pod1-leaf1a Loopback0 (IP: 10.255.1.5)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf3a
+ hosts:
+ - destination: 10.255.1.6
+ repeat: 1
+ source: 10.255.1.9
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.9) - Destination: pod1-leaf1b Loopback0 (IP: 10.255.1.6)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf3a
+ hosts:
+ - destination: 10.255.1.7
+ repeat: 1
+ source: 10.255.1.9
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.9) - Destination: pod1-leaf2a Loopback0 (IP: 10.255.1.7)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf3a
+ hosts:
+ - destination: 10.255.1.8
+ repeat: 1
+ source: 10.255.1.9
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.9) - Destination: pod1-leaf2b Loopback0 (IP: 10.255.1.8)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf3a
+ hosts:
+ - destination: 10.255.1.9
+ repeat: 1
+ source: 10.255.1.9
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.9) - Destination: pod1-leaf3a Loopback0 (IP: 10.255.1.9)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf3a
+ hosts:
+ - destination: 10.255.1.10
+ repeat: 1
+ source: 10.255.1.9
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.9) - Destination: pod1-leaf3b Loopback0 (IP: 10.255.1.10)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf3a
+ hosts:
+ - destination: 10.255.1.11
+ repeat: 1
+ source: 10.255.1.9
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.9) - Destination: pod1-leaf4a Loopback0 (IP: 10.255.1.11)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf3a
+ hosts:
+ - destination: 10.255.1.12
+ repeat: 1
+ source: 10.255.1.9
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.9) - Destination: pod1-leaf4b Loopback0 (IP: 10.255.1.12)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf3a
+ hosts:
+ - destination: 10.255.1.13
+ repeat: 1
+ source: 10.255.1.9
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.9) - Destination: pod1-leaf5a Loopback0 (IP: 10.255.1.13)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf3a
+ hosts:
+ - destination: 10.255.1.14
+ repeat: 1
+ source: 10.255.1.9
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.9) - Destination: pod1-leaf5b Loopback0 (IP: 10.255.1.14)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf3a
+ hosts:
+ - destination: 10.255.1.15
+ repeat: 1
+ source: 10.255.1.9
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.9) - Destination: pod1-leaf6a Loopback0 (IP: 10.255.1.15)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf3a
+ hosts:
+ - destination: 10.255.1.16
+ repeat: 1
+ source: 10.255.1.9
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.9) - Destination: pod1-leaf6b Loopback0 (IP: 10.255.1.16)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf3a
+ hosts:
+ - destination: 10.255.1.17
+ repeat: 1
+ source: 10.255.1.9
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.9) - Destination: pod1-leaf7a Loopback0 (IP: 10.255.1.17)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf3a
+ hosts:
+ - destination: 10.255.1.18
+ repeat: 1
+ source: 10.255.1.9
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.9) - Destination: pod1-leaf7b Loopback0 (IP: 10.255.1.18)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf3a
+ hosts:
+ - destination: 10.255.1.19
+ repeat: 1
+ source: 10.255.1.9
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.9) - Destination: pod1-leaf8a Loopback0 (IP: 10.255.1.19)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf3a
+ hosts:
+ - destination: 10.255.1.20
+ repeat: 1
+ source: 10.255.1.9
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.9) - Destination: pod1-leaf8b Loopback0 (IP: 10.255.1.20)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf3a
+ hosts:
+ - destination: 10.255.1.21
+ repeat: 1
+ source: 10.255.1.9
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.9) - Destination: pod1-leaf9a Loopback0 (IP: 10.255.1.21)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf3a
+ hosts:
+ - destination: 10.255.1.22
+ repeat: 1
+ source: 10.255.1.9
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.9) - Destination: pod1-leaf9b Loopback0 (IP: 10.255.1.22)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf3a
+ hosts:
+ - destination: 10.255.1.23
+ repeat: 1
+ source: 10.255.1.9
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.9) - Destination: pod1-leaf10a Loopback0 (IP: 10.255.1.23)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf3a
+ hosts:
+ - destination: 10.255.1.24
+ repeat: 1
+ source: 10.255.1.9
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.9) - Destination: pod1-leaf10b Loopback0 (IP: 10.255.1.24)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf3a
+ hosts:
+ - destination: 10.255.2.1
+ repeat: 1
+ source: 10.255.1.9
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.9) - Destination: pod2-spine1 Loopback0 (IP: 10.255.2.1)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf3a
+ hosts:
+ - destination: 10.255.2.2
+ repeat: 1
+ source: 10.255.1.9
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.9) - Destination: pod2-spine2 Loopback0 (IP: 10.255.2.2)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf3a
+ hosts:
+ - destination: 10.255.2.3
+ repeat: 1
+ source: 10.255.1.9
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.9) - Destination: pod2-spine3 Loopback0 (IP: 10.255.2.3)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf3a
+ hosts:
+ - destination: 10.255.2.4
+ repeat: 1
+ source: 10.255.1.9
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.9) - Destination: pod2-spine4 Loopback0 (IP: 10.255.2.4)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf3a
+ hosts:
+ - destination: 10.255.2.5
+ repeat: 1
+ source: 10.255.1.9
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.9) - Destination: pod2-leaf1a Loopback0 (IP: 10.255.2.5)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf3a
+ hosts:
+ - destination: 10.255.2.6
+ repeat: 1
+ source: 10.255.1.9
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.9) - Destination: pod2-leaf1b Loopback0 (IP: 10.255.2.6)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf3a
+ hosts:
+ - destination: 10.255.2.7
+ repeat: 1
+ source: 10.255.1.9
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.9) - Destination: pod2-leaf2a Loopback0 (IP: 10.255.2.7)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf3a
+ hosts:
+ - destination: 10.255.2.8
+ repeat: 1
+ source: 10.255.1.9
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.9) - Destination: pod2-leaf2b Loopback0 (IP: 10.255.2.8)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf3a
+ hosts:
+ - destination: 10.255.2.9
+ repeat: 1
+ source: 10.255.1.9
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.9) - Destination: pod2-leaf3a Loopback0 (IP: 10.255.2.9)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf3a
+ hosts:
+ - destination: 10.255.2.10
+ repeat: 1
+ source: 10.255.1.9
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.9) - Destination: pod2-leaf3b Loopback0 (IP: 10.255.2.10)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf3a
+ hosts:
+ - destination: 10.255.2.11
+ repeat: 1
+ source: 10.255.1.9
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.9) - Destination: pod2-leaf4a Loopback0 (IP: 10.255.2.11)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf3a
+ hosts:
+ - destination: 10.255.2.12
+ repeat: 1
+ source: 10.255.1.9
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.9) - Destination: pod2-leaf4b Loopback0 (IP: 10.255.2.12)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf3a
+ hosts:
+ - destination: 10.255.2.13
+ repeat: 1
+ source: 10.255.1.9
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.9) - Destination: pod2-leaf5a Loopback0 (IP: 10.255.2.13)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf3a
+ hosts:
+ - destination: 10.255.2.14
+ repeat: 1
+ source: 10.255.1.9
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.9) - Destination: pod2-leaf5b Loopback0 (IP: 10.255.2.14)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf3a
+ hosts:
+ - destination: 10.255.2.15
+ repeat: 1
+ source: 10.255.1.9
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.9) - Destination: pod2-leaf6a Loopback0 (IP: 10.255.2.15)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf3a
+ hosts:
+ - destination: 10.255.2.16
+ repeat: 1
+ source: 10.255.1.9
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.9) - Destination: pod2-leaf6b Loopback0 (IP: 10.255.2.16)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf3a
+ hosts:
+ - destination: 10.255.2.17
+ repeat: 1
+ source: 10.255.1.9
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.9) - Destination: pod2-leaf7a Loopback0 (IP: 10.255.2.17)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf3a
+ hosts:
+ - destination: 10.255.2.18
+ repeat: 1
+ source: 10.255.1.9
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.9) - Destination: pod2-leaf7b Loopback0 (IP: 10.255.2.18)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf3a
+ hosts:
+ - destination: 10.255.2.19
+ repeat: 1
+ source: 10.255.1.9
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.9) - Destination: pod2-leaf8a Loopback0 (IP: 10.255.2.19)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf3a
+ hosts:
+ - destination: 10.255.2.20
+ repeat: 1
+ source: 10.255.1.9
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.9) - Destination: pod2-leaf8b Loopback0 (IP: 10.255.2.20)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf3a
+ hosts:
+ - destination: 10.255.2.21
+ repeat: 1
+ source: 10.255.1.9
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.9) - Destination: pod2-leaf9a Loopback0 (IP: 10.255.2.21)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf3a
+ hosts:
+ - destination: 10.255.2.22
+ repeat: 1
+ source: 10.255.1.9
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.9) - Destination: pod2-leaf9b Loopback0 (IP: 10.255.2.22)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf3a
+ hosts:
+ - destination: 10.255.2.23
+ repeat: 1
+ source: 10.255.1.9
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.9) - Destination: pod2-leaf10a Loopback0 (IP: 10.255.2.23)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf3a
+ hosts:
+ - destination: 10.255.2.24
+ repeat: 1
+ source: 10.255.1.9
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.9) - Destination: pod2-leaf10b Loopback0 (IP: 10.255.2.24)'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-leaf7a
+ neighbors:
+ - neighbor_device: pod2-leaf7b
+ neighbor_port: Ethernet53/1
+ port: Ethernet53/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet53/1 - Remote: pod2-leaf7b Ethernet53/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-leaf7a
+ neighbors:
+ - neighbor_device: pod2-leaf7b
+ neighbor_port: Ethernet54/1
+ port: Ethernet54/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet54/1 - Remote: pod2-leaf7b Ethernet54/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-leaf7a
+ neighbors:
+ - neighbor_device: pod2-spine1
+ neighbor_port: Ethernet13/1
+ port: Ethernet1/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet1/1 - Remote: pod2-spine1 Ethernet13/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-leaf7a
+ neighbors:
+ - neighbor_device: pod2-spine2
+ neighbor_port: Ethernet13/1
+ port: Ethernet2/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet2/1 - Remote: pod2-spine2 Ethernet13/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-leaf7a
+ neighbors:
+ - neighbor_device: pod2-spine3
+ neighbor_port: Ethernet13/1
+ port: Ethernet3/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet3/1 - Remote: pod2-spine3 Ethernet13/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-leaf7a
+ neighbors:
+ - neighbor_device: pod2-spine4
+ neighbor_port: Ethernet13/1
+ port: Ethernet4/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet4/1 - Remote: pod2-spine4 Ethernet13/1'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf7a
+ hosts:
+ - destination: 10.255.255.96
+ repeat: 1
+ source: 10.255.255.97
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet1/1 (IP: 10.255.255.97) - Destination: pod2-spine1 Ethernet13/1 (IP: 10.255.255.96)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf7a
+ hosts:
+ - destination: 10.255.255.98
+ repeat: 1
+ source: 10.255.255.99
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet2/1 (IP: 10.255.255.99) - Destination: pod2-spine2 Ethernet13/1 (IP: 10.255.255.98)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf7a
+ hosts:
+ - destination: 10.255.255.100
+ repeat: 1
+ source: 10.255.255.101
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet3/1 (IP: 10.255.255.101) - Destination: pod2-spine3 Ethernet13/1 (IP: 10.255.255.100)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf7a
+ hosts:
+ - destination: 10.255.255.102
+ repeat: 1
+ source: 10.255.255.103
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet4/1 (IP: 10.255.255.103) - Destination: pod2-spine4 Ethernet13/1 (IP: 10.255.255.102)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf7a
+ hosts:
+ - destination: 10.255.0.1
+ repeat: 1
+ source: 10.255.2.17
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.17) - Destination: super-spine1 Loopback0 (IP: 10.255.0.1)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf7a
+ hosts:
+ - destination: 10.255.0.2
+ repeat: 1
+ source: 10.255.2.17
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.17) - Destination: super-spine2 Loopback0 (IP: 10.255.0.2)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf7a
+ hosts:
+ - destination: 10.255.1.1
+ repeat: 1
+ source: 10.255.2.17
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.17) - Destination: pod1-spine1 Loopback0 (IP: 10.255.1.1)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf7a
+ hosts:
+ - destination: 10.255.1.2
+ repeat: 1
+ source: 10.255.2.17
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.17) - Destination: pod1-spine2 Loopback0 (IP: 10.255.1.2)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf7a
+ hosts:
+ - destination: 10.255.1.3
+ repeat: 1
+ source: 10.255.2.17
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.17) - Destination: pod1-spine3 Loopback0 (IP: 10.255.1.3)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf7a
+ hosts:
+ - destination: 10.255.1.4
+ repeat: 1
+ source: 10.255.2.17
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.17) - Destination: pod1-spine4 Loopback0 (IP: 10.255.1.4)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf7a
+ hosts:
+ - destination: 10.255.1.5
+ repeat: 1
+ source: 10.255.2.17
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.17) - Destination: pod1-leaf1a Loopback0 (IP: 10.255.1.5)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf7a
+ hosts:
+ - destination: 10.255.1.6
+ repeat: 1
+ source: 10.255.2.17
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.17) - Destination: pod1-leaf1b Loopback0 (IP: 10.255.1.6)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf7a
+ hosts:
+ - destination: 10.255.1.7
+ repeat: 1
+ source: 10.255.2.17
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.17) - Destination: pod1-leaf2a Loopback0 (IP: 10.255.1.7)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf7a
+ hosts:
+ - destination: 10.255.1.8
+ repeat: 1
+ source: 10.255.2.17
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.17) - Destination: pod1-leaf2b Loopback0 (IP: 10.255.1.8)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf7a
+ hosts:
+ - destination: 10.255.1.9
+ repeat: 1
+ source: 10.255.2.17
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.17) - Destination: pod1-leaf3a Loopback0 (IP: 10.255.1.9)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf7a
+ hosts:
+ - destination: 10.255.1.10
+ repeat: 1
+ source: 10.255.2.17
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.17) - Destination: pod1-leaf3b Loopback0 (IP: 10.255.1.10)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf7a
+ hosts:
+ - destination: 10.255.1.11
+ repeat: 1
+ source: 10.255.2.17
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.17) - Destination: pod1-leaf4a Loopback0 (IP: 10.255.1.11)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf7a
+ hosts:
+ - destination: 10.255.1.12
+ repeat: 1
+ source: 10.255.2.17
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.17) - Destination: pod1-leaf4b Loopback0 (IP: 10.255.1.12)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf7a
+ hosts:
+ - destination: 10.255.1.13
+ repeat: 1
+ source: 10.255.2.17
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.17) - Destination: pod1-leaf5a Loopback0 (IP: 10.255.1.13)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf7a
+ hosts:
+ - destination: 10.255.1.14
+ repeat: 1
+ source: 10.255.2.17
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.17) - Destination: pod1-leaf5b Loopback0 (IP: 10.255.1.14)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf7a
+ hosts:
+ - destination: 10.255.1.15
+ repeat: 1
+ source: 10.255.2.17
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.17) - Destination: pod1-leaf6a Loopback0 (IP: 10.255.1.15)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf7a
+ hosts:
+ - destination: 10.255.1.16
+ repeat: 1
+ source: 10.255.2.17
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.17) - Destination: pod1-leaf6b Loopback0 (IP: 10.255.1.16)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf7a
+ hosts:
+ - destination: 10.255.1.17
+ repeat: 1
+ source: 10.255.2.17
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.17) - Destination: pod1-leaf7a Loopback0 (IP: 10.255.1.17)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf7a
+ hosts:
+ - destination: 10.255.1.18
+ repeat: 1
+ source: 10.255.2.17
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.17) - Destination: pod1-leaf7b Loopback0 (IP: 10.255.1.18)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf7a
+ hosts:
+ - destination: 10.255.1.19
+ repeat: 1
+ source: 10.255.2.17
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.17) - Destination: pod1-leaf8a Loopback0 (IP: 10.255.1.19)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf7a
+ hosts:
+ - destination: 10.255.1.20
+ repeat: 1
+ source: 10.255.2.17
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.17) - Destination: pod1-leaf8b Loopback0 (IP: 10.255.1.20)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf7a
+ hosts:
+ - destination: 10.255.1.21
+ repeat: 1
+ source: 10.255.2.17
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.17) - Destination: pod1-leaf9a Loopback0 (IP: 10.255.1.21)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf7a
+ hosts:
+ - destination: 10.255.1.22
+ repeat: 1
+ source: 10.255.2.17
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.17) - Destination: pod1-leaf9b Loopback0 (IP: 10.255.1.22)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf7a
+ hosts:
+ - destination: 10.255.1.23
+ repeat: 1
+ source: 10.255.2.17
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.17) - Destination: pod1-leaf10a Loopback0 (IP: 10.255.1.23)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf7a
+ hosts:
+ - destination: 10.255.1.24
+ repeat: 1
+ source: 10.255.2.17
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.17) - Destination: pod1-leaf10b Loopback0 (IP: 10.255.1.24)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf7a
+ hosts:
+ - destination: 10.255.2.1
+ repeat: 1
+ source: 10.255.2.17
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.17) - Destination: pod2-spine1 Loopback0 (IP: 10.255.2.1)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf7a
+ hosts:
+ - destination: 10.255.2.2
+ repeat: 1
+ source: 10.255.2.17
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.17) - Destination: pod2-spine2 Loopback0 (IP: 10.255.2.2)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf7a
+ hosts:
+ - destination: 10.255.2.3
+ repeat: 1
+ source: 10.255.2.17
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.17) - Destination: pod2-spine3 Loopback0 (IP: 10.255.2.3)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf7a
+ hosts:
+ - destination: 10.255.2.4
+ repeat: 1
+ source: 10.255.2.17
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.17) - Destination: pod2-spine4 Loopback0 (IP: 10.255.2.4)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf7a
+ hosts:
+ - destination: 10.255.2.5
+ repeat: 1
+ source: 10.255.2.17
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.17) - Destination: pod2-leaf1a Loopback0 (IP: 10.255.2.5)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf7a
+ hosts:
+ - destination: 10.255.2.6
+ repeat: 1
+ source: 10.255.2.17
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.17) - Destination: pod2-leaf1b Loopback0 (IP: 10.255.2.6)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf7a
+ hosts:
+ - destination: 10.255.2.7
+ repeat: 1
+ source: 10.255.2.17
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.17) - Destination: pod2-leaf2a Loopback0 (IP: 10.255.2.7)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf7a
+ hosts:
+ - destination: 10.255.2.8
+ repeat: 1
+ source: 10.255.2.17
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.17) - Destination: pod2-leaf2b Loopback0 (IP: 10.255.2.8)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf7a
+ hosts:
+ - destination: 10.255.2.9
+ repeat: 1
+ source: 10.255.2.17
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.17) - Destination: pod2-leaf3a Loopback0 (IP: 10.255.2.9)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf7a
+ hosts:
+ - destination: 10.255.2.10
+ repeat: 1
+ source: 10.255.2.17
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.17) - Destination: pod2-leaf3b Loopback0 (IP: 10.255.2.10)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf7a
+ hosts:
+ - destination: 10.255.2.11
+ repeat: 1
+ source: 10.255.2.17
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.17) - Destination: pod2-leaf4a Loopback0 (IP: 10.255.2.11)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf7a
+ hosts:
+ - destination: 10.255.2.12
+ repeat: 1
+ source: 10.255.2.17
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.17) - Destination: pod2-leaf4b Loopback0 (IP: 10.255.2.12)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf7a
+ hosts:
+ - destination: 10.255.2.13
+ repeat: 1
+ source: 10.255.2.17
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.17) - Destination: pod2-leaf5a Loopback0 (IP: 10.255.2.13)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf7a
+ hosts:
+ - destination: 10.255.2.14
+ repeat: 1
+ source: 10.255.2.17
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.17) - Destination: pod2-leaf5b Loopback0 (IP: 10.255.2.14)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf7a
+ hosts:
+ - destination: 10.255.2.15
+ repeat: 1
+ source: 10.255.2.17
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.17) - Destination: pod2-leaf6a Loopback0 (IP: 10.255.2.15)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf7a
+ hosts:
+ - destination: 10.255.2.16
+ repeat: 1
+ source: 10.255.2.17
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.17) - Destination: pod2-leaf6b Loopback0 (IP: 10.255.2.16)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf7a
+ hosts:
+ - destination: 10.255.2.17
+ repeat: 1
+ source: 10.255.2.17
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.17) - Destination: pod2-leaf7a Loopback0 (IP: 10.255.2.17)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf7a
+ hosts:
+ - destination: 10.255.2.18
+ repeat: 1
+ source: 10.255.2.17
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.17) - Destination: pod2-leaf7b Loopback0 (IP: 10.255.2.18)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf7a
+ hosts:
+ - destination: 10.255.2.19
+ repeat: 1
+ source: 10.255.2.17
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.17) - Destination: pod2-leaf8a Loopback0 (IP: 10.255.2.19)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf7a
+ hosts:
+ - destination: 10.255.2.20
+ repeat: 1
+ source: 10.255.2.17
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.17) - Destination: pod2-leaf8b Loopback0 (IP: 10.255.2.20)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf7a
+ hosts:
+ - destination: 10.255.2.21
+ repeat: 1
+ source: 10.255.2.17
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.17) - Destination: pod2-leaf9a Loopback0 (IP: 10.255.2.21)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf7a
+ hosts:
+ - destination: 10.255.2.22
+ repeat: 1
+ source: 10.255.2.17
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.17) - Destination: pod2-leaf9b Loopback0 (IP: 10.255.2.22)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf7a
+ hosts:
+ - destination: 10.255.2.23
+ repeat: 1
+ source: 10.255.2.17
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.17) - Destination: pod2-leaf10a Loopback0 (IP: 10.255.2.23)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf7a
+ hosts:
+ - destination: 10.255.2.24
+ repeat: 1
+ source: 10.255.2.17
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.17) - Destination: pod2-leaf10b Loopback0 (IP: 10.255.2.24)'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-leaf1a
+ neighbors:
+ - neighbor_device: pod1-leaf1b
+ neighbor_port: Ethernet53/1
+ port: Ethernet53/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet53/1 - Remote: pod1-leaf1b Ethernet53/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-leaf1a
+ neighbors:
+ - neighbor_device: pod1-leaf1b
+ neighbor_port: Ethernet54/1
+ port: Ethernet54/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet54/1 - Remote: pod1-leaf1b Ethernet54/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-leaf1a
+ neighbors:
+ - neighbor_device: pod1-spine1
+ neighbor_port: Ethernet1/1
+ port: Ethernet1/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet1/1 - Remote: pod1-spine1 Ethernet1/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-leaf1a
+ neighbors:
+ - neighbor_device: pod1-spine2
+ neighbor_port: Ethernet1/1
+ port: Ethernet2/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet2/1 - Remote: pod1-spine2 Ethernet1/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-leaf1a
+ neighbors:
+ - neighbor_device: pod1-spine3
+ neighbor_port: Ethernet1/1
+ port: Ethernet3/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet3/1 - Remote: pod1-spine3 Ethernet1/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-leaf1a
+ neighbors:
+ - neighbor_device: pod1-spine4
+ neighbor_port: Ethernet1/1
+ port: Ethernet4/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet4/1 - Remote: pod1-spine4 Ethernet1/1'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf1a
+ hosts:
+ - destination: 10.255.255.0
+ repeat: 1
+ source: 10.255.255.1
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet1/1 (IP: 10.255.255.1) - Destination: pod1-spine1 Ethernet1/1 (IP: 10.255.255.0)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf1a
+ hosts:
+ - destination: 10.255.255.2
+ repeat: 1
+ source: 10.255.255.3
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet2/1 (IP: 10.255.255.3) - Destination: pod1-spine2 Ethernet1/1 (IP: 10.255.255.2)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf1a
+ hosts:
+ - destination: 10.255.255.4
+ repeat: 1
+ source: 10.255.255.5
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet3/1 (IP: 10.255.255.5) - Destination: pod1-spine3 Ethernet1/1 (IP: 10.255.255.4)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf1a
+ hosts:
+ - destination: 10.255.255.6
+ repeat: 1
+ source: 10.255.255.7
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet4/1 (IP: 10.255.255.7) - Destination: pod1-spine4 Ethernet1/1 (IP: 10.255.255.6)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf1a
+ hosts:
+ - destination: 10.255.0.1
+ repeat: 1
+ source: 10.255.1.5
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.5) - Destination: super-spine1 Loopback0 (IP: 10.255.0.1)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf1a
+ hosts:
+ - destination: 10.255.0.2
+ repeat: 1
+ source: 10.255.1.5
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.5) - Destination: super-spine2 Loopback0 (IP: 10.255.0.2)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf1a
+ hosts:
+ - destination: 10.255.1.1
+ repeat: 1
+ source: 10.255.1.5
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.5) - Destination: pod1-spine1 Loopback0 (IP: 10.255.1.1)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf1a
+ hosts:
+ - destination: 10.255.1.2
+ repeat: 1
+ source: 10.255.1.5
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.5) - Destination: pod1-spine2 Loopback0 (IP: 10.255.1.2)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf1a
+ hosts:
+ - destination: 10.255.1.3
+ repeat: 1
+ source: 10.255.1.5
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.5) - Destination: pod1-spine3 Loopback0 (IP: 10.255.1.3)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf1a
+ hosts:
+ - destination: 10.255.1.4
+ repeat: 1
+ source: 10.255.1.5
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.5) - Destination: pod1-spine4 Loopback0 (IP: 10.255.1.4)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf1a
+ hosts:
+ - destination: 10.255.1.5
+ repeat: 1
+ source: 10.255.1.5
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.5) - Destination: pod1-leaf1a Loopback0 (IP: 10.255.1.5)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf1a
+ hosts:
+ - destination: 10.255.1.6
+ repeat: 1
+ source: 10.255.1.5
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.5) - Destination: pod1-leaf1b Loopback0 (IP: 10.255.1.6)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf1a
+ hosts:
+ - destination: 10.255.1.7
+ repeat: 1
+ source: 10.255.1.5
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.5) - Destination: pod1-leaf2a Loopback0 (IP: 10.255.1.7)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf1a
+ hosts:
+ - destination: 10.255.1.8
+ repeat: 1
+ source: 10.255.1.5
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.5) - Destination: pod1-leaf2b Loopback0 (IP: 10.255.1.8)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf1a
+ hosts:
+ - destination: 10.255.1.9
+ repeat: 1
+ source: 10.255.1.5
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.5) - Destination: pod1-leaf3a Loopback0 (IP: 10.255.1.9)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf1a
+ hosts:
+ - destination: 10.255.1.10
+ repeat: 1
+ source: 10.255.1.5
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.5) - Destination: pod1-leaf3b Loopback0 (IP: 10.255.1.10)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf1a
+ hosts:
+ - destination: 10.255.1.11
+ repeat: 1
+ source: 10.255.1.5
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.5) - Destination: pod1-leaf4a Loopback0 (IP: 10.255.1.11)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf1a
+ hosts:
+ - destination: 10.255.1.12
+ repeat: 1
+ source: 10.255.1.5
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.5) - Destination: pod1-leaf4b Loopback0 (IP: 10.255.1.12)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf1a
+ hosts:
+ - destination: 10.255.1.13
+ repeat: 1
+ source: 10.255.1.5
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.5) - Destination: pod1-leaf5a Loopback0 (IP: 10.255.1.13)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf1a
+ hosts:
+ - destination: 10.255.1.14
+ repeat: 1
+ source: 10.255.1.5
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.5) - Destination: pod1-leaf5b Loopback0 (IP: 10.255.1.14)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf1a
+ hosts:
+ - destination: 10.255.1.15
+ repeat: 1
+ source: 10.255.1.5
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.5) - Destination: pod1-leaf6a Loopback0 (IP: 10.255.1.15)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf1a
+ hosts:
+ - destination: 10.255.1.16
+ repeat: 1
+ source: 10.255.1.5
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.5) - Destination: pod1-leaf6b Loopback0 (IP: 10.255.1.16)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf1a
+ hosts:
+ - destination: 10.255.1.17
+ repeat: 1
+ source: 10.255.1.5
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.5) - Destination: pod1-leaf7a Loopback0 (IP: 10.255.1.17)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf1a
+ hosts:
+ - destination: 10.255.1.18
+ repeat: 1
+ source: 10.255.1.5
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.5) - Destination: pod1-leaf7b Loopback0 (IP: 10.255.1.18)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf1a
+ hosts:
+ - destination: 10.255.1.19
+ repeat: 1
+ source: 10.255.1.5
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.5) - Destination: pod1-leaf8a Loopback0 (IP: 10.255.1.19)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf1a
+ hosts:
+ - destination: 10.255.1.20
+ repeat: 1
+ source: 10.255.1.5
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.5) - Destination: pod1-leaf8b Loopback0 (IP: 10.255.1.20)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf1a
+ hosts:
+ - destination: 10.255.1.21
+ repeat: 1
+ source: 10.255.1.5
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.5) - Destination: pod1-leaf9a Loopback0 (IP: 10.255.1.21)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf1a
+ hosts:
+ - destination: 10.255.1.22
+ repeat: 1
+ source: 10.255.1.5
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.5) - Destination: pod1-leaf9b Loopback0 (IP: 10.255.1.22)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf1a
+ hosts:
+ - destination: 10.255.1.23
+ repeat: 1
+ source: 10.255.1.5
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.5) - Destination: pod1-leaf10a Loopback0 (IP: 10.255.1.23)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf1a
+ hosts:
+ - destination: 10.255.1.24
+ repeat: 1
+ source: 10.255.1.5
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.5) - Destination: pod1-leaf10b Loopback0 (IP: 10.255.1.24)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf1a
+ hosts:
+ - destination: 10.255.2.1
+ repeat: 1
+ source: 10.255.1.5
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.5) - Destination: pod2-spine1 Loopback0 (IP: 10.255.2.1)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf1a
+ hosts:
+ - destination: 10.255.2.2
+ repeat: 1
+ source: 10.255.1.5
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.5) - Destination: pod2-spine2 Loopback0 (IP: 10.255.2.2)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf1a
+ hosts:
+ - destination: 10.255.2.3
+ repeat: 1
+ source: 10.255.1.5
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.5) - Destination: pod2-spine3 Loopback0 (IP: 10.255.2.3)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf1a
+ hosts:
+ - destination: 10.255.2.4
+ repeat: 1
+ source: 10.255.1.5
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.5) - Destination: pod2-spine4 Loopback0 (IP: 10.255.2.4)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf1a
+ hosts:
+ - destination: 10.255.2.5
+ repeat: 1
+ source: 10.255.1.5
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.5) - Destination: pod2-leaf1a Loopback0 (IP: 10.255.2.5)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf1a
+ hosts:
+ - destination: 10.255.2.6
+ repeat: 1
+ source: 10.255.1.5
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.5) - Destination: pod2-leaf1b Loopback0 (IP: 10.255.2.6)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf1a
+ hosts:
+ - destination: 10.255.2.7
+ repeat: 1
+ source: 10.255.1.5
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.5) - Destination: pod2-leaf2a Loopback0 (IP: 10.255.2.7)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf1a
+ hosts:
+ - destination: 10.255.2.8
+ repeat: 1
+ source: 10.255.1.5
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.5) - Destination: pod2-leaf2b Loopback0 (IP: 10.255.2.8)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf1a
+ hosts:
+ - destination: 10.255.2.9
+ repeat: 1
+ source: 10.255.1.5
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.5) - Destination: pod2-leaf3a Loopback0 (IP: 10.255.2.9)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf1a
+ hosts:
+ - destination: 10.255.2.10
+ repeat: 1
+ source: 10.255.1.5
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.5) - Destination: pod2-leaf3b Loopback0 (IP: 10.255.2.10)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf1a
+ hosts:
+ - destination: 10.255.2.11
+ repeat: 1
+ source: 10.255.1.5
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.5) - Destination: pod2-leaf4a Loopback0 (IP: 10.255.2.11)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf1a
+ hosts:
+ - destination: 10.255.2.12
+ repeat: 1
+ source: 10.255.1.5
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.5) - Destination: pod2-leaf4b Loopback0 (IP: 10.255.2.12)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf1a
+ hosts:
+ - destination: 10.255.2.13
+ repeat: 1
+ source: 10.255.1.5
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.5) - Destination: pod2-leaf5a Loopback0 (IP: 10.255.2.13)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf1a
+ hosts:
+ - destination: 10.255.2.14
+ repeat: 1
+ source: 10.255.1.5
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.5) - Destination: pod2-leaf5b Loopback0 (IP: 10.255.2.14)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf1a
+ hosts:
+ - destination: 10.255.2.15
+ repeat: 1
+ source: 10.255.1.5
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.5) - Destination: pod2-leaf6a Loopback0 (IP: 10.255.2.15)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf1a
+ hosts:
+ - destination: 10.255.2.16
+ repeat: 1
+ source: 10.255.1.5
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.5) - Destination: pod2-leaf6b Loopback0 (IP: 10.255.2.16)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf1a
+ hosts:
+ - destination: 10.255.2.17
+ repeat: 1
+ source: 10.255.1.5
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.5) - Destination: pod2-leaf7a Loopback0 (IP: 10.255.2.17)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf1a
+ hosts:
+ - destination: 10.255.2.18
+ repeat: 1
+ source: 10.255.1.5
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.5) - Destination: pod2-leaf7b Loopback0 (IP: 10.255.2.18)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf1a
+ hosts:
+ - destination: 10.255.2.19
+ repeat: 1
+ source: 10.255.1.5
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.5) - Destination: pod2-leaf8a Loopback0 (IP: 10.255.2.19)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf1a
+ hosts:
+ - destination: 10.255.2.20
+ repeat: 1
+ source: 10.255.1.5
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.5) - Destination: pod2-leaf8b Loopback0 (IP: 10.255.2.20)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf1a
+ hosts:
+ - destination: 10.255.2.21
+ repeat: 1
+ source: 10.255.1.5
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.5) - Destination: pod2-leaf9a Loopback0 (IP: 10.255.2.21)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf1a
+ hosts:
+ - destination: 10.255.2.22
+ repeat: 1
+ source: 10.255.1.5
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.5) - Destination: pod2-leaf9b Loopback0 (IP: 10.255.2.22)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf1a
+ hosts:
+ - destination: 10.255.2.23
+ repeat: 1
+ source: 10.255.1.5
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.5) - Destination: pod2-leaf10a Loopback0 (IP: 10.255.2.23)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf1a
+ hosts:
+ - destination: 10.255.2.24
+ repeat: 1
+ source: 10.255.1.5
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.5) - Destination: pod2-leaf10b Loopback0 (IP: 10.255.2.24)'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - super-spine1
+ neighbors:
+ - neighbor_device: pod1-spine1
+ neighbor_port: Ethernet31/1
+ port: Ethernet1/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet1/1 - Remote: pod1-spine1 Ethernet31/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - super-spine1
+ neighbors:
+ - neighbor_device: pod1-spine2
+ neighbor_port: Ethernet31/1
+ port: Ethernet2/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet2/1 - Remote: pod1-spine2 Ethernet31/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - super-spine1
+ neighbors:
+ - neighbor_device: pod1-spine3
+ neighbor_port: Ethernet31/1
+ port: Ethernet3/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet3/1 - Remote: pod1-spine3 Ethernet31/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - super-spine1
+ neighbors:
+ - neighbor_device: pod1-spine4
+ neighbor_port: Ethernet31/1
+ port: Ethernet4/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet4/1 - Remote: pod1-spine4 Ethernet31/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - super-spine1
+ neighbors:
+ - neighbor_device: pod2-spine1
+ neighbor_port: Ethernet31/1
+ port: Ethernet5/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet5/1 - Remote: pod2-spine1 Ethernet31/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - super-spine1
+ neighbors:
+ - neighbor_device: pod2-spine2
+ neighbor_port: Ethernet31/1
+ port: Ethernet6/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet6/1 - Remote: pod2-spine2 Ethernet31/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - super-spine1
+ neighbors:
+ - neighbor_device: pod2-spine3
+ neighbor_port: Ethernet31/1
+ port: Ethernet7/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet7/1 - Remote: pod2-spine3 Ethernet31/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - super-spine1
+ neighbors:
+ - neighbor_device: pod2-spine4
+ neighbor_port: Ethernet31/1
+ port: Ethernet8/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet8/1 - Remote: pod2-spine4 Ethernet31/1'
+- VerifyReachability:
+ filters:
+ tags:
+ - super-spine1
+ hosts:
+ - destination: 10.255.255.1
+ repeat: 1
+ source: 10.255.255.0
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet1/1 (IP: 10.255.255.0) - Destination: pod1-spine1 Ethernet31/1 (IP: 10.255.255.1)'
+- VerifyReachability:
+ filters:
+ tags:
+ - super-spine1
+ hosts:
+ - destination: 10.255.255.5
+ repeat: 1
+ source: 10.255.255.4
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet2/1 (IP: 10.255.255.4) - Destination: pod1-spine2 Ethernet31/1 (IP: 10.255.255.5)'
+- VerifyReachability:
+ filters:
+ tags:
+ - super-spine1
+ hosts:
+ - destination: 10.255.255.9
+ repeat: 1
+ source: 10.255.255.8
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet3/1 (IP: 10.255.255.8) - Destination: pod1-spine3 Ethernet31/1 (IP: 10.255.255.9)'
+- VerifyReachability:
+ filters:
+ tags:
+ - super-spine1
+ hosts:
+ - destination: 10.255.255.13
+ repeat: 1
+ source: 10.255.255.12
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet4/1 (IP: 10.255.255.12) - Destination: pod1-spine4 Ethernet31/1 (IP: 10.255.255.13)'
+- VerifyReachability:
+ filters:
+ tags:
+ - super-spine1
+ hosts:
+ - destination: 10.255.255.129
+ repeat: 1
+ source: 10.255.255.128
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet5/1 (IP: 10.255.255.128) - Destination: pod2-spine1 Ethernet31/1 (IP: 10.255.255.129)'
+- VerifyReachability:
+ filters:
+ tags:
+ - super-spine1
+ hosts:
+ - destination: 10.255.255.133
+ repeat: 1
+ source: 10.255.255.132
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet6/1 (IP: 10.255.255.132) - Destination: pod2-spine2 Ethernet31/1 (IP: 10.255.255.133)'
+- VerifyReachability:
+ filters:
+ tags:
+ - super-spine1
+ hosts:
+ - destination: 10.255.255.137
+ repeat: 1
+ source: 10.255.255.136
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet7/1 (IP: 10.255.255.136) - Destination: pod2-spine3 Ethernet31/1 (IP: 10.255.255.137)'
+- VerifyReachability:
+ filters:
+ tags:
+ - super-spine1
+ hosts:
+ - destination: 10.255.255.141
+ repeat: 1
+ source: 10.255.255.140
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet8/1 (IP: 10.255.255.140) - Destination: pod2-spine4 Ethernet31/1 (IP: 10.255.255.141)'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-leaf6a
+ neighbors:
+ - neighbor_device: pod1-leaf6b
+ neighbor_port: Ethernet53/1
+ port: Ethernet53/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet53/1 - Remote: pod1-leaf6b Ethernet53/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-leaf6a
+ neighbors:
+ - neighbor_device: pod1-leaf6b
+ neighbor_port: Ethernet54/1
+ port: Ethernet54/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet54/1 - Remote: pod1-leaf6b Ethernet54/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-leaf6a
+ neighbors:
+ - neighbor_device: pod1-spine1
+ neighbor_port: Ethernet11/1
+ port: Ethernet1/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet1/1 - Remote: pod1-spine1 Ethernet11/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-leaf6a
+ neighbors:
+ - neighbor_device: pod1-spine2
+ neighbor_port: Ethernet11/1
+ port: Ethernet2/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet2/1 - Remote: pod1-spine2 Ethernet11/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-leaf6a
+ neighbors:
+ - neighbor_device: pod1-spine3
+ neighbor_port: Ethernet11/1
+ port: Ethernet3/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet3/1 - Remote: pod1-spine3 Ethernet11/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-leaf6a
+ neighbors:
+ - neighbor_device: pod1-spine4
+ neighbor_port: Ethernet11/1
+ port: Ethernet4/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet4/1 - Remote: pod1-spine4 Ethernet11/1'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf6a
+ hosts:
+ - destination: 10.255.255.80
+ repeat: 1
+ source: 10.255.255.81
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet1/1 (IP: 10.255.255.81) - Destination: pod1-spine1 Ethernet11/1 (IP: 10.255.255.80)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf6a
+ hosts:
+ - destination: 10.255.255.82
+ repeat: 1
+ source: 10.255.255.83
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet2/1 (IP: 10.255.255.83) - Destination: pod1-spine2 Ethernet11/1 (IP: 10.255.255.82)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf6a
+ hosts:
+ - destination: 10.255.255.84
+ repeat: 1
+ source: 10.255.255.85
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet3/1 (IP: 10.255.255.85) - Destination: pod1-spine3 Ethernet11/1 (IP: 10.255.255.84)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf6a
+ hosts:
+ - destination: 10.255.255.86
+ repeat: 1
+ source: 10.255.255.87
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet4/1 (IP: 10.255.255.87) - Destination: pod1-spine4 Ethernet11/1 (IP: 10.255.255.86)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf6a
+ hosts:
+ - destination: 10.255.0.1
+ repeat: 1
+ source: 10.255.1.15
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.15) - Destination: super-spine1 Loopback0 (IP: 10.255.0.1)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf6a
+ hosts:
+ - destination: 10.255.0.2
+ repeat: 1
+ source: 10.255.1.15
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.15) - Destination: super-spine2 Loopback0 (IP: 10.255.0.2)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf6a
+ hosts:
+ - destination: 10.255.1.1
+ repeat: 1
+ source: 10.255.1.15
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.15) - Destination: pod1-spine1 Loopback0 (IP: 10.255.1.1)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf6a
+ hosts:
+ - destination: 10.255.1.2
+ repeat: 1
+ source: 10.255.1.15
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.15) - Destination: pod1-spine2 Loopback0 (IP: 10.255.1.2)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf6a
+ hosts:
+ - destination: 10.255.1.3
+ repeat: 1
+ source: 10.255.1.15
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.15) - Destination: pod1-spine3 Loopback0 (IP: 10.255.1.3)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf6a
+ hosts:
+ - destination: 10.255.1.4
+ repeat: 1
+ source: 10.255.1.15
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.15) - Destination: pod1-spine4 Loopback0 (IP: 10.255.1.4)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf6a
+ hosts:
+ - destination: 10.255.1.5
+ repeat: 1
+ source: 10.255.1.15
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.15) - Destination: pod1-leaf1a Loopback0 (IP: 10.255.1.5)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf6a
+ hosts:
+ - destination: 10.255.1.6
+ repeat: 1
+ source: 10.255.1.15
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.15) - Destination: pod1-leaf1b Loopback0 (IP: 10.255.1.6)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf6a
+ hosts:
+ - destination: 10.255.1.7
+ repeat: 1
+ source: 10.255.1.15
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.15) - Destination: pod1-leaf2a Loopback0 (IP: 10.255.1.7)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf6a
+ hosts:
+ - destination: 10.255.1.8
+ repeat: 1
+ source: 10.255.1.15
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.15) - Destination: pod1-leaf2b Loopback0 (IP: 10.255.1.8)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf6a
+ hosts:
+ - destination: 10.255.1.9
+ repeat: 1
+ source: 10.255.1.15
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.15) - Destination: pod1-leaf3a Loopback0 (IP: 10.255.1.9)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf6a
+ hosts:
+ - destination: 10.255.1.10
+ repeat: 1
+ source: 10.255.1.15
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.15) - Destination: pod1-leaf3b Loopback0 (IP: 10.255.1.10)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf6a
+ hosts:
+ - destination: 10.255.1.11
+ repeat: 1
+ source: 10.255.1.15
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.15) - Destination: pod1-leaf4a Loopback0 (IP: 10.255.1.11)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf6a
+ hosts:
+ - destination: 10.255.1.12
+ repeat: 1
+ source: 10.255.1.15
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.15) - Destination: pod1-leaf4b Loopback0 (IP: 10.255.1.12)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf6a
+ hosts:
+ - destination: 10.255.1.13
+ repeat: 1
+ source: 10.255.1.15
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.15) - Destination: pod1-leaf5a Loopback0 (IP: 10.255.1.13)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf6a
+ hosts:
+ - destination: 10.255.1.14
+ repeat: 1
+ source: 10.255.1.15
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.15) - Destination: pod1-leaf5b Loopback0 (IP: 10.255.1.14)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf6a
+ hosts:
+ - destination: 10.255.1.15
+ repeat: 1
+ source: 10.255.1.15
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.15) - Destination: pod1-leaf6a Loopback0 (IP: 10.255.1.15)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf6a
+ hosts:
+ - destination: 10.255.1.16
+ repeat: 1
+ source: 10.255.1.15
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.15) - Destination: pod1-leaf6b Loopback0 (IP: 10.255.1.16)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf6a
+ hosts:
+ - destination: 10.255.1.17
+ repeat: 1
+ source: 10.255.1.15
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.15) - Destination: pod1-leaf7a Loopback0 (IP: 10.255.1.17)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf6a
+ hosts:
+ - destination: 10.255.1.18
+ repeat: 1
+ source: 10.255.1.15
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.15) - Destination: pod1-leaf7b Loopback0 (IP: 10.255.1.18)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf6a
+ hosts:
+ - destination: 10.255.1.19
+ repeat: 1
+ source: 10.255.1.15
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.15) - Destination: pod1-leaf8a Loopback0 (IP: 10.255.1.19)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf6a
+ hosts:
+ - destination: 10.255.1.20
+ repeat: 1
+ source: 10.255.1.15
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.15) - Destination: pod1-leaf8b Loopback0 (IP: 10.255.1.20)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf6a
+ hosts:
+ - destination: 10.255.1.21
+ repeat: 1
+ source: 10.255.1.15
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.15) - Destination: pod1-leaf9a Loopback0 (IP: 10.255.1.21)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf6a
+ hosts:
+ - destination: 10.255.1.22
+ repeat: 1
+ source: 10.255.1.15
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.15) - Destination: pod1-leaf9b Loopback0 (IP: 10.255.1.22)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf6a
+ hosts:
+ - destination: 10.255.1.23
+ repeat: 1
+ source: 10.255.1.15
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.15) - Destination: pod1-leaf10a Loopback0 (IP: 10.255.1.23)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf6a
+ hosts:
+ - destination: 10.255.1.24
+ repeat: 1
+ source: 10.255.1.15
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.15) - Destination: pod1-leaf10b Loopback0 (IP: 10.255.1.24)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf6a
+ hosts:
+ - destination: 10.255.2.1
+ repeat: 1
+ source: 10.255.1.15
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.15) - Destination: pod2-spine1 Loopback0 (IP: 10.255.2.1)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf6a
+ hosts:
+ - destination: 10.255.2.2
+ repeat: 1
+ source: 10.255.1.15
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.15) - Destination: pod2-spine2 Loopback0 (IP: 10.255.2.2)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf6a
+ hosts:
+ - destination: 10.255.2.3
+ repeat: 1
+ source: 10.255.1.15
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.15) - Destination: pod2-spine3 Loopback0 (IP: 10.255.2.3)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf6a
+ hosts:
+ - destination: 10.255.2.4
+ repeat: 1
+ source: 10.255.1.15
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.15) - Destination: pod2-spine4 Loopback0 (IP: 10.255.2.4)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf6a
+ hosts:
+ - destination: 10.255.2.5
+ repeat: 1
+ source: 10.255.1.15
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.15) - Destination: pod2-leaf1a Loopback0 (IP: 10.255.2.5)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf6a
+ hosts:
+ - destination: 10.255.2.6
+ repeat: 1
+ source: 10.255.1.15
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.15) - Destination: pod2-leaf1b Loopback0 (IP: 10.255.2.6)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf6a
+ hosts:
+ - destination: 10.255.2.7
+ repeat: 1
+ source: 10.255.1.15
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.15) - Destination: pod2-leaf2a Loopback0 (IP: 10.255.2.7)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf6a
+ hosts:
+ - destination: 10.255.2.8
+ repeat: 1
+ source: 10.255.1.15
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.15) - Destination: pod2-leaf2b Loopback0 (IP: 10.255.2.8)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf6a
+ hosts:
+ - destination: 10.255.2.9
+ repeat: 1
+ source: 10.255.1.15
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.15) - Destination: pod2-leaf3a Loopback0 (IP: 10.255.2.9)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf6a
+ hosts:
+ - destination: 10.255.2.10
+ repeat: 1
+ source: 10.255.1.15
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.15) - Destination: pod2-leaf3b Loopback0 (IP: 10.255.2.10)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf6a
+ hosts:
+ - destination: 10.255.2.11
+ repeat: 1
+ source: 10.255.1.15
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.15) - Destination: pod2-leaf4a Loopback0 (IP: 10.255.2.11)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf6a
+ hosts:
+ - destination: 10.255.2.12
+ repeat: 1
+ source: 10.255.1.15
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.15) - Destination: pod2-leaf4b Loopback0 (IP: 10.255.2.12)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf6a
+ hosts:
+ - destination: 10.255.2.13
+ repeat: 1
+ source: 10.255.1.15
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.15) - Destination: pod2-leaf5a Loopback0 (IP: 10.255.2.13)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf6a
+ hosts:
+ - destination: 10.255.2.14
+ repeat: 1
+ source: 10.255.1.15
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.15) - Destination: pod2-leaf5b Loopback0 (IP: 10.255.2.14)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf6a
+ hosts:
+ - destination: 10.255.2.15
+ repeat: 1
+ source: 10.255.1.15
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.15) - Destination: pod2-leaf6a Loopback0 (IP: 10.255.2.15)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf6a
+ hosts:
+ - destination: 10.255.2.16
+ repeat: 1
+ source: 10.255.1.15
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.15) - Destination: pod2-leaf6b Loopback0 (IP: 10.255.2.16)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf6a
+ hosts:
+ - destination: 10.255.2.17
+ repeat: 1
+ source: 10.255.1.15
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.15) - Destination: pod2-leaf7a Loopback0 (IP: 10.255.2.17)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf6a
+ hosts:
+ - destination: 10.255.2.18
+ repeat: 1
+ source: 10.255.1.15
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.15) - Destination: pod2-leaf7b Loopback0 (IP: 10.255.2.18)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf6a
+ hosts:
+ - destination: 10.255.2.19
+ repeat: 1
+ source: 10.255.1.15
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.15) - Destination: pod2-leaf8a Loopback0 (IP: 10.255.2.19)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf6a
+ hosts:
+ - destination: 10.255.2.20
+ repeat: 1
+ source: 10.255.1.15
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.15) - Destination: pod2-leaf8b Loopback0 (IP: 10.255.2.20)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf6a
+ hosts:
+ - destination: 10.255.2.21
+ repeat: 1
+ source: 10.255.1.15
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.15) - Destination: pod2-leaf9a Loopback0 (IP: 10.255.2.21)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf6a
+ hosts:
+ - destination: 10.255.2.22
+ repeat: 1
+ source: 10.255.1.15
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.15) - Destination: pod2-leaf9b Loopback0 (IP: 10.255.2.22)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf6a
+ hosts:
+ - destination: 10.255.2.23
+ repeat: 1
+ source: 10.255.1.15
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.15) - Destination: pod2-leaf10a Loopback0 (IP: 10.255.2.23)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf6a
+ hosts:
+ - destination: 10.255.2.24
+ repeat: 1
+ source: 10.255.1.15
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.15) - Destination: pod2-leaf10b Loopback0 (IP: 10.255.2.24)'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-leaf6a
+ neighbors:
+ - neighbor_device: pod2-leaf6b
+ neighbor_port: Ethernet53/1
+ port: Ethernet53/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet53/1 - Remote: pod2-leaf6b Ethernet53/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-leaf6a
+ neighbors:
+ - neighbor_device: pod2-leaf6b
+ neighbor_port: Ethernet54/1
+ port: Ethernet54/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet54/1 - Remote: pod2-leaf6b Ethernet54/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-leaf6a
+ neighbors:
+ - neighbor_device: pod2-spine1
+ neighbor_port: Ethernet11/1
+ port: Ethernet1/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet1/1 - Remote: pod2-spine1 Ethernet11/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-leaf6a
+ neighbors:
+ - neighbor_device: pod2-spine2
+ neighbor_port: Ethernet11/1
+ port: Ethernet2/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet2/1 - Remote: pod2-spine2 Ethernet11/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-leaf6a
+ neighbors:
+ - neighbor_device: pod2-spine3
+ neighbor_port: Ethernet11/1
+ port: Ethernet3/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet3/1 - Remote: pod2-spine3 Ethernet11/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-leaf6a
+ neighbors:
+ - neighbor_device: pod2-spine4
+ neighbor_port: Ethernet11/1
+ port: Ethernet4/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet4/1 - Remote: pod2-spine4 Ethernet11/1'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf6a
+ hosts:
+ - destination: 10.255.255.80
+ repeat: 1
+ source: 10.255.255.81
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet1/1 (IP: 10.255.255.81) - Destination: pod2-spine1 Ethernet11/1 (IP: 10.255.255.80)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf6a
+ hosts:
+ - destination: 10.255.255.82
+ repeat: 1
+ source: 10.255.255.83
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet2/1 (IP: 10.255.255.83) - Destination: pod2-spine2 Ethernet11/1 (IP: 10.255.255.82)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf6a
+ hosts:
+ - destination: 10.255.255.84
+ repeat: 1
+ source: 10.255.255.85
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet3/1 (IP: 10.255.255.85) - Destination: pod2-spine3 Ethernet11/1 (IP: 10.255.255.84)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf6a
+ hosts:
+ - destination: 10.255.255.86
+ repeat: 1
+ source: 10.255.255.87
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet4/1 (IP: 10.255.255.87) - Destination: pod2-spine4 Ethernet11/1 (IP: 10.255.255.86)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf6a
+ hosts:
+ - destination: 10.255.0.1
+ repeat: 1
+ source: 10.255.2.15
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.15) - Destination: super-spine1 Loopback0 (IP: 10.255.0.1)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf6a
+ hosts:
+ - destination: 10.255.0.2
+ repeat: 1
+ source: 10.255.2.15
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.15) - Destination: super-spine2 Loopback0 (IP: 10.255.0.2)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf6a
+ hosts:
+ - destination: 10.255.1.1
+ repeat: 1
+ source: 10.255.2.15
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.15) - Destination: pod1-spine1 Loopback0 (IP: 10.255.1.1)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf6a
+ hosts:
+ - destination: 10.255.1.2
+ repeat: 1
+ source: 10.255.2.15
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.15) - Destination: pod1-spine2 Loopback0 (IP: 10.255.1.2)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf6a
+ hosts:
+ - destination: 10.255.1.3
+ repeat: 1
+ source: 10.255.2.15
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.15) - Destination: pod1-spine3 Loopback0 (IP: 10.255.1.3)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf6a
+ hosts:
+ - destination: 10.255.1.4
+ repeat: 1
+ source: 10.255.2.15
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.15) - Destination: pod1-spine4 Loopback0 (IP: 10.255.1.4)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf6a
+ hosts:
+ - destination: 10.255.1.5
+ repeat: 1
+ source: 10.255.2.15
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.15) - Destination: pod1-leaf1a Loopback0 (IP: 10.255.1.5)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf6a
+ hosts:
+ - destination: 10.255.1.6
+ repeat: 1
+ source: 10.255.2.15
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.15) - Destination: pod1-leaf1b Loopback0 (IP: 10.255.1.6)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf6a
+ hosts:
+ - destination: 10.255.1.7
+ repeat: 1
+ source: 10.255.2.15
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.15) - Destination: pod1-leaf2a Loopback0 (IP: 10.255.1.7)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf6a
+ hosts:
+ - destination: 10.255.1.8
+ repeat: 1
+ source: 10.255.2.15
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.15) - Destination: pod1-leaf2b Loopback0 (IP: 10.255.1.8)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf6a
+ hosts:
+ - destination: 10.255.1.9
+ repeat: 1
+ source: 10.255.2.15
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.15) - Destination: pod1-leaf3a Loopback0 (IP: 10.255.1.9)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf6a
+ hosts:
+ - destination: 10.255.1.10
+ repeat: 1
+ source: 10.255.2.15
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.15) - Destination: pod1-leaf3b Loopback0 (IP: 10.255.1.10)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf6a
+ hosts:
+ - destination: 10.255.1.11
+ repeat: 1
+ source: 10.255.2.15
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.15) - Destination: pod1-leaf4a Loopback0 (IP: 10.255.1.11)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf6a
+ hosts:
+ - destination: 10.255.1.12
+ repeat: 1
+ source: 10.255.2.15
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.15) - Destination: pod1-leaf4b Loopback0 (IP: 10.255.1.12)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf6a
+ hosts:
+ - destination: 10.255.1.13
+ repeat: 1
+ source: 10.255.2.15
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.15) - Destination: pod1-leaf5a Loopback0 (IP: 10.255.1.13)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf6a
+ hosts:
+ - destination: 10.255.1.14
+ repeat: 1
+ source: 10.255.2.15
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.15) - Destination: pod1-leaf5b Loopback0 (IP: 10.255.1.14)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf6a
+ hosts:
+ - destination: 10.255.1.15
+ repeat: 1
+ source: 10.255.2.15
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.15) - Destination: pod1-leaf6a Loopback0 (IP: 10.255.1.15)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf6a
+ hosts:
+ - destination: 10.255.1.16
+ repeat: 1
+ source: 10.255.2.15
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.15) - Destination: pod1-leaf6b Loopback0 (IP: 10.255.1.16)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf6a
+ hosts:
+ - destination: 10.255.1.17
+ repeat: 1
+ source: 10.255.2.15
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.15) - Destination: pod1-leaf7a Loopback0 (IP: 10.255.1.17)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf6a
+ hosts:
+ - destination: 10.255.1.18
+ repeat: 1
+ source: 10.255.2.15
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.15) - Destination: pod1-leaf7b Loopback0 (IP: 10.255.1.18)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf6a
+ hosts:
+ - destination: 10.255.1.19
+ repeat: 1
+ source: 10.255.2.15
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.15) - Destination: pod1-leaf8a Loopback0 (IP: 10.255.1.19)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf6a
+ hosts:
+ - destination: 10.255.1.20
+ repeat: 1
+ source: 10.255.2.15
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.15) - Destination: pod1-leaf8b Loopback0 (IP: 10.255.1.20)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf6a
+ hosts:
+ - destination: 10.255.1.21
+ repeat: 1
+ source: 10.255.2.15
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.15) - Destination: pod1-leaf9a Loopback0 (IP: 10.255.1.21)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf6a
+ hosts:
+ - destination: 10.255.1.22
+ repeat: 1
+ source: 10.255.2.15
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.15) - Destination: pod1-leaf9b Loopback0 (IP: 10.255.1.22)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf6a
+ hosts:
+ - destination: 10.255.1.23
+ repeat: 1
+ source: 10.255.2.15
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.15) - Destination: pod1-leaf10a Loopback0 (IP: 10.255.1.23)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf6a
+ hosts:
+ - destination: 10.255.1.24
+ repeat: 1
+ source: 10.255.2.15
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.15) - Destination: pod1-leaf10b Loopback0 (IP: 10.255.1.24)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf6a
+ hosts:
+ - destination: 10.255.2.1
+ repeat: 1
+ source: 10.255.2.15
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.15) - Destination: pod2-spine1 Loopback0 (IP: 10.255.2.1)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf6a
+ hosts:
+ - destination: 10.255.2.2
+ repeat: 1
+ source: 10.255.2.15
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.15) - Destination: pod2-spine2 Loopback0 (IP: 10.255.2.2)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf6a
+ hosts:
+ - destination: 10.255.2.3
+ repeat: 1
+ source: 10.255.2.15
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.15) - Destination: pod2-spine3 Loopback0 (IP: 10.255.2.3)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf6a
+ hosts:
+ - destination: 10.255.2.4
+ repeat: 1
+ source: 10.255.2.15
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.15) - Destination: pod2-spine4 Loopback0 (IP: 10.255.2.4)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf6a
+ hosts:
+ - destination: 10.255.2.5
+ repeat: 1
+ source: 10.255.2.15
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.15) - Destination: pod2-leaf1a Loopback0 (IP: 10.255.2.5)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf6a
+ hosts:
+ - destination: 10.255.2.6
+ repeat: 1
+ source: 10.255.2.15
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.15) - Destination: pod2-leaf1b Loopback0 (IP: 10.255.2.6)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf6a
+ hosts:
+ - destination: 10.255.2.7
+ repeat: 1
+ source: 10.255.2.15
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.15) - Destination: pod2-leaf2a Loopback0 (IP: 10.255.2.7)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf6a
+ hosts:
+ - destination: 10.255.2.8
+ repeat: 1
+ source: 10.255.2.15
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.15) - Destination: pod2-leaf2b Loopback0 (IP: 10.255.2.8)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf6a
+ hosts:
+ - destination: 10.255.2.9
+ repeat: 1
+ source: 10.255.2.15
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.15) - Destination: pod2-leaf3a Loopback0 (IP: 10.255.2.9)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf6a
+ hosts:
+ - destination: 10.255.2.10
+ repeat: 1
+ source: 10.255.2.15
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.15) - Destination: pod2-leaf3b Loopback0 (IP: 10.255.2.10)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf6a
+ hosts:
+ - destination: 10.255.2.11
+ repeat: 1
+ source: 10.255.2.15
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.15) - Destination: pod2-leaf4a Loopback0 (IP: 10.255.2.11)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf6a
+ hosts:
+ - destination: 10.255.2.12
+ repeat: 1
+ source: 10.255.2.15
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.15) - Destination: pod2-leaf4b Loopback0 (IP: 10.255.2.12)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf6a
+ hosts:
+ - destination: 10.255.2.13
+ repeat: 1
+ source: 10.255.2.15
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.15) - Destination: pod2-leaf5a Loopback0 (IP: 10.255.2.13)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf6a
+ hosts:
+ - destination: 10.255.2.14
+ repeat: 1
+ source: 10.255.2.15
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.15) - Destination: pod2-leaf5b Loopback0 (IP: 10.255.2.14)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf6a
+ hosts:
+ - destination: 10.255.2.15
+ repeat: 1
+ source: 10.255.2.15
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.15) - Destination: pod2-leaf6a Loopback0 (IP: 10.255.2.15)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf6a
+ hosts:
+ - destination: 10.255.2.16
+ repeat: 1
+ source: 10.255.2.15
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.15) - Destination: pod2-leaf6b Loopback0 (IP: 10.255.2.16)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf6a
+ hosts:
+ - destination: 10.255.2.17
+ repeat: 1
+ source: 10.255.2.15
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.15) - Destination: pod2-leaf7a Loopback0 (IP: 10.255.2.17)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf6a
+ hosts:
+ - destination: 10.255.2.18
+ repeat: 1
+ source: 10.255.2.15
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.15) - Destination: pod2-leaf7b Loopback0 (IP: 10.255.2.18)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf6a
+ hosts:
+ - destination: 10.255.2.19
+ repeat: 1
+ source: 10.255.2.15
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.15) - Destination: pod2-leaf8a Loopback0 (IP: 10.255.2.19)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf6a
+ hosts:
+ - destination: 10.255.2.20
+ repeat: 1
+ source: 10.255.2.15
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.15) - Destination: pod2-leaf8b Loopback0 (IP: 10.255.2.20)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf6a
+ hosts:
+ - destination: 10.255.2.21
+ repeat: 1
+ source: 10.255.2.15
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.15) - Destination: pod2-leaf9a Loopback0 (IP: 10.255.2.21)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf6a
+ hosts:
+ - destination: 10.255.2.22
+ repeat: 1
+ source: 10.255.2.15
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.15) - Destination: pod2-leaf9b Loopback0 (IP: 10.255.2.22)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf6a
+ hosts:
+ - destination: 10.255.2.23
+ repeat: 1
+ source: 10.255.2.15
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.15) - Destination: pod2-leaf10a Loopback0 (IP: 10.255.2.23)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf6a
+ hosts:
+ - destination: 10.255.2.24
+ repeat: 1
+ source: 10.255.2.15
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.15) - Destination: pod2-leaf10b Loopback0 (IP: 10.255.2.24)'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-leaf1a
+ neighbors:
+ - neighbor_device: pod2-leaf1b
+ neighbor_port: Ethernet53/1
+ port: Ethernet53/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet53/1 - Remote: pod2-leaf1b Ethernet53/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-leaf1a
+ neighbors:
+ - neighbor_device: pod2-leaf1b
+ neighbor_port: Ethernet54/1
+ port: Ethernet54/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet54/1 - Remote: pod2-leaf1b Ethernet54/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-leaf1a
+ neighbors:
+ - neighbor_device: pod2-spine1
+ neighbor_port: Ethernet1/1
+ port: Ethernet1/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet1/1 - Remote: pod2-spine1 Ethernet1/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-leaf1a
+ neighbors:
+ - neighbor_device: pod2-spine2
+ neighbor_port: Ethernet1/1
+ port: Ethernet2/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet2/1 - Remote: pod2-spine2 Ethernet1/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-leaf1a
+ neighbors:
+ - neighbor_device: pod2-spine3
+ neighbor_port: Ethernet1/1
+ port: Ethernet3/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet3/1 - Remote: pod2-spine3 Ethernet1/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-leaf1a
+ neighbors:
+ - neighbor_device: pod2-spine4
+ neighbor_port: Ethernet1/1
+ port: Ethernet4/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet4/1 - Remote: pod2-spine4 Ethernet1/1'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf1a
+ hosts:
+ - destination: 10.255.255.0
+ repeat: 1
+ source: 10.255.255.1
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet1/1 (IP: 10.255.255.1) - Destination: pod2-spine1 Ethernet1/1 (IP: 10.255.255.0)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf1a
+ hosts:
+ - destination: 10.255.255.2
+ repeat: 1
+ source: 10.255.255.3
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet2/1 (IP: 10.255.255.3) - Destination: pod2-spine2 Ethernet1/1 (IP: 10.255.255.2)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf1a
+ hosts:
+ - destination: 10.255.255.4
+ repeat: 1
+ source: 10.255.255.5
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet3/1 (IP: 10.255.255.5) - Destination: pod2-spine3 Ethernet1/1 (IP: 10.255.255.4)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf1a
+ hosts:
+ - destination: 10.255.255.6
+ repeat: 1
+ source: 10.255.255.7
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet4/1 (IP: 10.255.255.7) - Destination: pod2-spine4 Ethernet1/1 (IP: 10.255.255.6)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf1a
+ hosts:
+ - destination: 10.255.0.1
+ repeat: 1
+ source: 10.255.2.5
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.5) - Destination: super-spine1 Loopback0 (IP: 10.255.0.1)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf1a
+ hosts:
+ - destination: 10.255.0.2
+ repeat: 1
+ source: 10.255.2.5
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.5) - Destination: super-spine2 Loopback0 (IP: 10.255.0.2)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf1a
+ hosts:
+ - destination: 10.255.1.1
+ repeat: 1
+ source: 10.255.2.5
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.5) - Destination: pod1-spine1 Loopback0 (IP: 10.255.1.1)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf1a
+ hosts:
+ - destination: 10.255.1.2
+ repeat: 1
+ source: 10.255.2.5
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.5) - Destination: pod1-spine2 Loopback0 (IP: 10.255.1.2)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf1a
+ hosts:
+ - destination: 10.255.1.3
+ repeat: 1
+ source: 10.255.2.5
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.5) - Destination: pod1-spine3 Loopback0 (IP: 10.255.1.3)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf1a
+ hosts:
+ - destination: 10.255.1.4
+ repeat: 1
+ source: 10.255.2.5
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.5) - Destination: pod1-spine4 Loopback0 (IP: 10.255.1.4)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf1a
+ hosts:
+ - destination: 10.255.1.5
+ repeat: 1
+ source: 10.255.2.5
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.5) - Destination: pod1-leaf1a Loopback0 (IP: 10.255.1.5)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf1a
+ hosts:
+ - destination: 10.255.1.6
+ repeat: 1
+ source: 10.255.2.5
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.5) - Destination: pod1-leaf1b Loopback0 (IP: 10.255.1.6)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf1a
+ hosts:
+ - destination: 10.255.1.7
+ repeat: 1
+ source: 10.255.2.5
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.5) - Destination: pod1-leaf2a Loopback0 (IP: 10.255.1.7)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf1a
+ hosts:
+ - destination: 10.255.1.8
+ repeat: 1
+ source: 10.255.2.5
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.5) - Destination: pod1-leaf2b Loopback0 (IP: 10.255.1.8)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf1a
+ hosts:
+ - destination: 10.255.1.9
+ repeat: 1
+ source: 10.255.2.5
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.5) - Destination: pod1-leaf3a Loopback0 (IP: 10.255.1.9)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf1a
+ hosts:
+ - destination: 10.255.1.10
+ repeat: 1
+ source: 10.255.2.5
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.5) - Destination: pod1-leaf3b Loopback0 (IP: 10.255.1.10)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf1a
+ hosts:
+ - destination: 10.255.1.11
+ repeat: 1
+ source: 10.255.2.5
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.5) - Destination: pod1-leaf4a Loopback0 (IP: 10.255.1.11)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf1a
+ hosts:
+ - destination: 10.255.1.12
+ repeat: 1
+ source: 10.255.2.5
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.5) - Destination: pod1-leaf4b Loopback0 (IP: 10.255.1.12)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf1a
+ hosts:
+ - destination: 10.255.1.13
+ repeat: 1
+ source: 10.255.2.5
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.5) - Destination: pod1-leaf5a Loopback0 (IP: 10.255.1.13)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf1a
+ hosts:
+ - destination: 10.255.1.14
+ repeat: 1
+ source: 10.255.2.5
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.5) - Destination: pod1-leaf5b Loopback0 (IP: 10.255.1.14)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf1a
+ hosts:
+ - destination: 10.255.1.15
+ repeat: 1
+ source: 10.255.2.5
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.5) - Destination: pod1-leaf6a Loopback0 (IP: 10.255.1.15)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf1a
+ hosts:
+ - destination: 10.255.1.16
+ repeat: 1
+ source: 10.255.2.5
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.5) - Destination: pod1-leaf6b Loopback0 (IP: 10.255.1.16)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf1a
+ hosts:
+ - destination: 10.255.1.17
+ repeat: 1
+ source: 10.255.2.5
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.5) - Destination: pod1-leaf7a Loopback0 (IP: 10.255.1.17)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf1a
+ hosts:
+ - destination: 10.255.1.18
+ repeat: 1
+ source: 10.255.2.5
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.5) - Destination: pod1-leaf7b Loopback0 (IP: 10.255.1.18)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf1a
+ hosts:
+ - destination: 10.255.1.19
+ repeat: 1
+ source: 10.255.2.5
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.5) - Destination: pod1-leaf8a Loopback0 (IP: 10.255.1.19)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf1a
+ hosts:
+ - destination: 10.255.1.20
+ repeat: 1
+ source: 10.255.2.5
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.5) - Destination: pod1-leaf8b Loopback0 (IP: 10.255.1.20)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf1a
+ hosts:
+ - destination: 10.255.1.21
+ repeat: 1
+ source: 10.255.2.5
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.5) - Destination: pod1-leaf9a Loopback0 (IP: 10.255.1.21)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf1a
+ hosts:
+ - destination: 10.255.1.22
+ repeat: 1
+ source: 10.255.2.5
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.5) - Destination: pod1-leaf9b Loopback0 (IP: 10.255.1.22)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf1a
+ hosts:
+ - destination: 10.255.1.23
+ repeat: 1
+ source: 10.255.2.5
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.5) - Destination: pod1-leaf10a Loopback0 (IP: 10.255.1.23)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf1a
+ hosts:
+ - destination: 10.255.1.24
+ repeat: 1
+ source: 10.255.2.5
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.5) - Destination: pod1-leaf10b Loopback0 (IP: 10.255.1.24)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf1a
+ hosts:
+ - destination: 10.255.2.1
+ repeat: 1
+ source: 10.255.2.5
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.5) - Destination: pod2-spine1 Loopback0 (IP: 10.255.2.1)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf1a
+ hosts:
+ - destination: 10.255.2.2
+ repeat: 1
+ source: 10.255.2.5
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.5) - Destination: pod2-spine2 Loopback0 (IP: 10.255.2.2)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf1a
+ hosts:
+ - destination: 10.255.2.3
+ repeat: 1
+ source: 10.255.2.5
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.5) - Destination: pod2-spine3 Loopback0 (IP: 10.255.2.3)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf1a
+ hosts:
+ - destination: 10.255.2.4
+ repeat: 1
+ source: 10.255.2.5
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.5) - Destination: pod2-spine4 Loopback0 (IP: 10.255.2.4)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf1a
+ hosts:
+ - destination: 10.255.2.5
+ repeat: 1
+ source: 10.255.2.5
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.5) - Destination: pod2-leaf1a Loopback0 (IP: 10.255.2.5)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf1a
+ hosts:
+ - destination: 10.255.2.6
+ repeat: 1
+ source: 10.255.2.5
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.5) - Destination: pod2-leaf1b Loopback0 (IP: 10.255.2.6)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf1a
+ hosts:
+ - destination: 10.255.2.7
+ repeat: 1
+ source: 10.255.2.5
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.5) - Destination: pod2-leaf2a Loopback0 (IP: 10.255.2.7)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf1a
+ hosts:
+ - destination: 10.255.2.8
+ repeat: 1
+ source: 10.255.2.5
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.5) - Destination: pod2-leaf2b Loopback0 (IP: 10.255.2.8)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf1a
+ hosts:
+ - destination: 10.255.2.9
+ repeat: 1
+ source: 10.255.2.5
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.5) - Destination: pod2-leaf3a Loopback0 (IP: 10.255.2.9)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf1a
+ hosts:
+ - destination: 10.255.2.10
+ repeat: 1
+ source: 10.255.2.5
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.5) - Destination: pod2-leaf3b Loopback0 (IP: 10.255.2.10)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf1a
+ hosts:
+ - destination: 10.255.2.11
+ repeat: 1
+ source: 10.255.2.5
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.5) - Destination: pod2-leaf4a Loopback0 (IP: 10.255.2.11)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf1a
+ hosts:
+ - destination: 10.255.2.12
+ repeat: 1
+ source: 10.255.2.5
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.5) - Destination: pod2-leaf4b Loopback0 (IP: 10.255.2.12)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf1a
+ hosts:
+ - destination: 10.255.2.13
+ repeat: 1
+ source: 10.255.2.5
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.5) - Destination: pod2-leaf5a Loopback0 (IP: 10.255.2.13)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf1a
+ hosts:
+ - destination: 10.255.2.14
+ repeat: 1
+ source: 10.255.2.5
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.5) - Destination: pod2-leaf5b Loopback0 (IP: 10.255.2.14)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf1a
+ hosts:
+ - destination: 10.255.2.15
+ repeat: 1
+ source: 10.255.2.5
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.5) - Destination: pod2-leaf6a Loopback0 (IP: 10.255.2.15)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf1a
+ hosts:
+ - destination: 10.255.2.16
+ repeat: 1
+ source: 10.255.2.5
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.5) - Destination: pod2-leaf6b Loopback0 (IP: 10.255.2.16)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf1a
+ hosts:
+ - destination: 10.255.2.17
+ repeat: 1
+ source: 10.255.2.5
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.5) - Destination: pod2-leaf7a Loopback0 (IP: 10.255.2.17)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf1a
+ hosts:
+ - destination: 10.255.2.18
+ repeat: 1
+ source: 10.255.2.5
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.5) - Destination: pod2-leaf7b Loopback0 (IP: 10.255.2.18)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf1a
+ hosts:
+ - destination: 10.255.2.19
+ repeat: 1
+ source: 10.255.2.5
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.5) - Destination: pod2-leaf8a Loopback0 (IP: 10.255.2.19)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf1a
+ hosts:
+ - destination: 10.255.2.20
+ repeat: 1
+ source: 10.255.2.5
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.5) - Destination: pod2-leaf8b Loopback0 (IP: 10.255.2.20)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf1a
+ hosts:
+ - destination: 10.255.2.21
+ repeat: 1
+ source: 10.255.2.5
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.5) - Destination: pod2-leaf9a Loopback0 (IP: 10.255.2.21)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf1a
+ hosts:
+ - destination: 10.255.2.22
+ repeat: 1
+ source: 10.255.2.5
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.5) - Destination: pod2-leaf9b Loopback0 (IP: 10.255.2.22)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf1a
+ hosts:
+ - destination: 10.255.2.23
+ repeat: 1
+ source: 10.255.2.5
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.5) - Destination: pod2-leaf10a Loopback0 (IP: 10.255.2.23)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf1a
+ hosts:
+ - destination: 10.255.2.24
+ repeat: 1
+ source: 10.255.2.5
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.5) - Destination: pod2-leaf10b Loopback0 (IP: 10.255.2.24)'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-leaf10b
+ neighbors:
+ - neighbor_device: pod1-leaf10a
+ neighbor_port: Ethernet53/1
+ port: Ethernet53/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet53/1 - Remote: pod1-leaf10a Ethernet53/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-leaf10b
+ neighbors:
+ - neighbor_device: pod1-leaf10a
+ neighbor_port: Ethernet54/1
+ port: Ethernet54/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet54/1 - Remote: pod1-leaf10a Ethernet54/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-leaf10b
+ neighbors:
+ - neighbor_device: pod1-spine1
+ neighbor_port: Ethernet20/1
+ port: Ethernet1/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet1/1 - Remote: pod1-spine1 Ethernet20/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-leaf10b
+ neighbors:
+ - neighbor_device: pod1-spine2
+ neighbor_port: Ethernet20/1
+ port: Ethernet2/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet2/1 - Remote: pod1-spine2 Ethernet20/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-leaf10b
+ neighbors:
+ - neighbor_device: pod1-spine3
+ neighbor_port: Ethernet20/1
+ port: Ethernet3/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet3/1 - Remote: pod1-spine3 Ethernet20/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-leaf10b
+ neighbors:
+ - neighbor_device: pod1-spine4
+ neighbor_port: Ethernet20/1
+ port: Ethernet4/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet4/1 - Remote: pod1-spine4 Ethernet20/1'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf10b
+ hosts:
+ - destination: 10.255.255.152
+ repeat: 1
+ source: 10.255.255.153
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet1/1 (IP: 10.255.255.153) - Destination: pod1-spine1 Ethernet20/1 (IP: 10.255.255.152)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf10b
+ hosts:
+ - destination: 10.255.255.154
+ repeat: 1
+ source: 10.255.255.155
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet2/1 (IP: 10.255.255.155) - Destination: pod1-spine2 Ethernet20/1 (IP: 10.255.255.154)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf10b
+ hosts:
+ - destination: 10.255.255.156
+ repeat: 1
+ source: 10.255.255.157
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet3/1 (IP: 10.255.255.157) - Destination: pod1-spine3 Ethernet20/1 (IP: 10.255.255.156)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf10b
+ hosts:
+ - destination: 10.255.255.158
+ repeat: 1
+ source: 10.255.255.159
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet4/1 (IP: 10.255.255.159) - Destination: pod1-spine4 Ethernet20/1 (IP: 10.255.255.158)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf10b
+ hosts:
+ - destination: 10.255.0.1
+ repeat: 1
+ source: 10.255.1.24
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.24) - Destination: super-spine1 Loopback0 (IP: 10.255.0.1)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf10b
+ hosts:
+ - destination: 10.255.0.2
+ repeat: 1
+ source: 10.255.1.24
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.24) - Destination: super-spine2 Loopback0 (IP: 10.255.0.2)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf10b
+ hosts:
+ - destination: 10.255.1.1
+ repeat: 1
+ source: 10.255.1.24
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.24) - Destination: pod1-spine1 Loopback0 (IP: 10.255.1.1)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf10b
+ hosts:
+ - destination: 10.255.1.2
+ repeat: 1
+ source: 10.255.1.24
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.24) - Destination: pod1-spine2 Loopback0 (IP: 10.255.1.2)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf10b
+ hosts:
+ - destination: 10.255.1.3
+ repeat: 1
+ source: 10.255.1.24
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.24) - Destination: pod1-spine3 Loopback0 (IP: 10.255.1.3)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf10b
+ hosts:
+ - destination: 10.255.1.4
+ repeat: 1
+ source: 10.255.1.24
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.24) - Destination: pod1-spine4 Loopback0 (IP: 10.255.1.4)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf10b
+ hosts:
+ - destination: 10.255.1.5
+ repeat: 1
+ source: 10.255.1.24
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.24) - Destination: pod1-leaf1a Loopback0 (IP: 10.255.1.5)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf10b
+ hosts:
+ - destination: 10.255.1.6
+ repeat: 1
+ source: 10.255.1.24
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.24) - Destination: pod1-leaf1b Loopback0 (IP: 10.255.1.6)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf10b
+ hosts:
+ - destination: 10.255.1.7
+ repeat: 1
+ source: 10.255.1.24
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.24) - Destination: pod1-leaf2a Loopback0 (IP: 10.255.1.7)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf10b
+ hosts:
+ - destination: 10.255.1.8
+ repeat: 1
+ source: 10.255.1.24
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.24) - Destination: pod1-leaf2b Loopback0 (IP: 10.255.1.8)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf10b
+ hosts:
+ - destination: 10.255.1.9
+ repeat: 1
+ source: 10.255.1.24
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.24) - Destination: pod1-leaf3a Loopback0 (IP: 10.255.1.9)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf10b
+ hosts:
+ - destination: 10.255.1.10
+ repeat: 1
+ source: 10.255.1.24
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.24) - Destination: pod1-leaf3b Loopback0 (IP: 10.255.1.10)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf10b
+ hosts:
+ - destination: 10.255.1.11
+ repeat: 1
+ source: 10.255.1.24
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.24) - Destination: pod1-leaf4a Loopback0 (IP: 10.255.1.11)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf10b
+ hosts:
+ - destination: 10.255.1.12
+ repeat: 1
+ source: 10.255.1.24
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.24) - Destination: pod1-leaf4b Loopback0 (IP: 10.255.1.12)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf10b
+ hosts:
+ - destination: 10.255.1.13
+ repeat: 1
+ source: 10.255.1.24
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.24) - Destination: pod1-leaf5a Loopback0 (IP: 10.255.1.13)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf10b
+ hosts:
+ - destination: 10.255.1.14
+ repeat: 1
+ source: 10.255.1.24
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.24) - Destination: pod1-leaf5b Loopback0 (IP: 10.255.1.14)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf10b
+ hosts:
+ - destination: 10.255.1.15
+ repeat: 1
+ source: 10.255.1.24
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.24) - Destination: pod1-leaf6a Loopback0 (IP: 10.255.1.15)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf10b
+ hosts:
+ - destination: 10.255.1.16
+ repeat: 1
+ source: 10.255.1.24
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.24) - Destination: pod1-leaf6b Loopback0 (IP: 10.255.1.16)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf10b
+ hosts:
+ - destination: 10.255.1.17
+ repeat: 1
+ source: 10.255.1.24
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.24) - Destination: pod1-leaf7a Loopback0 (IP: 10.255.1.17)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf10b
+ hosts:
+ - destination: 10.255.1.18
+ repeat: 1
+ source: 10.255.1.24
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.24) - Destination: pod1-leaf7b Loopback0 (IP: 10.255.1.18)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf10b
+ hosts:
+ - destination: 10.255.1.19
+ repeat: 1
+ source: 10.255.1.24
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.24) - Destination: pod1-leaf8a Loopback0 (IP: 10.255.1.19)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf10b
+ hosts:
+ - destination: 10.255.1.20
+ repeat: 1
+ source: 10.255.1.24
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.24) - Destination: pod1-leaf8b Loopback0 (IP: 10.255.1.20)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf10b
+ hosts:
+ - destination: 10.255.1.21
+ repeat: 1
+ source: 10.255.1.24
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.24) - Destination: pod1-leaf9a Loopback0 (IP: 10.255.1.21)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf10b
+ hosts:
+ - destination: 10.255.1.22
+ repeat: 1
+ source: 10.255.1.24
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.24) - Destination: pod1-leaf9b Loopback0 (IP: 10.255.1.22)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf10b
+ hosts:
+ - destination: 10.255.1.23
+ repeat: 1
+ source: 10.255.1.24
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.24) - Destination: pod1-leaf10a Loopback0 (IP: 10.255.1.23)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf10b
+ hosts:
+ - destination: 10.255.1.24
+ repeat: 1
+ source: 10.255.1.24
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.24) - Destination: pod1-leaf10b Loopback0 (IP: 10.255.1.24)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf10b
+ hosts:
+ - destination: 10.255.2.1
+ repeat: 1
+ source: 10.255.1.24
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.24) - Destination: pod2-spine1 Loopback0 (IP: 10.255.2.1)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf10b
+ hosts:
+ - destination: 10.255.2.2
+ repeat: 1
+ source: 10.255.1.24
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.24) - Destination: pod2-spine2 Loopback0 (IP: 10.255.2.2)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf10b
+ hosts:
+ - destination: 10.255.2.3
+ repeat: 1
+ source: 10.255.1.24
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.24) - Destination: pod2-spine3 Loopback0 (IP: 10.255.2.3)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf10b
+ hosts:
+ - destination: 10.255.2.4
+ repeat: 1
+ source: 10.255.1.24
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.24) - Destination: pod2-spine4 Loopback0 (IP: 10.255.2.4)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf10b
+ hosts:
+ - destination: 10.255.2.5
+ repeat: 1
+ source: 10.255.1.24
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.24) - Destination: pod2-leaf1a Loopback0 (IP: 10.255.2.5)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf10b
+ hosts:
+ - destination: 10.255.2.6
+ repeat: 1
+ source: 10.255.1.24
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.24) - Destination: pod2-leaf1b Loopback0 (IP: 10.255.2.6)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf10b
+ hosts:
+ - destination: 10.255.2.7
+ repeat: 1
+ source: 10.255.1.24
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.24) - Destination: pod2-leaf2a Loopback0 (IP: 10.255.2.7)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf10b
+ hosts:
+ - destination: 10.255.2.8
+ repeat: 1
+ source: 10.255.1.24
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.24) - Destination: pod2-leaf2b Loopback0 (IP: 10.255.2.8)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf10b
+ hosts:
+ - destination: 10.255.2.9
+ repeat: 1
+ source: 10.255.1.24
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.24) - Destination: pod2-leaf3a Loopback0 (IP: 10.255.2.9)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf10b
+ hosts:
+ - destination: 10.255.2.10
+ repeat: 1
+ source: 10.255.1.24
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.24) - Destination: pod2-leaf3b Loopback0 (IP: 10.255.2.10)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf10b
+ hosts:
+ - destination: 10.255.2.11
+ repeat: 1
+ source: 10.255.1.24
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.24) - Destination: pod2-leaf4a Loopback0 (IP: 10.255.2.11)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf10b
+ hosts:
+ - destination: 10.255.2.12
+ repeat: 1
+ source: 10.255.1.24
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.24) - Destination: pod2-leaf4b Loopback0 (IP: 10.255.2.12)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf10b
+ hosts:
+ - destination: 10.255.2.13
+ repeat: 1
+ source: 10.255.1.24
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.24) - Destination: pod2-leaf5a Loopback0 (IP: 10.255.2.13)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf10b
+ hosts:
+ - destination: 10.255.2.14
+ repeat: 1
+ source: 10.255.1.24
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.24) - Destination: pod2-leaf5b Loopback0 (IP: 10.255.2.14)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf10b
+ hosts:
+ - destination: 10.255.2.15
+ repeat: 1
+ source: 10.255.1.24
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.24) - Destination: pod2-leaf6a Loopback0 (IP: 10.255.2.15)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf10b
+ hosts:
+ - destination: 10.255.2.16
+ repeat: 1
+ source: 10.255.1.24
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.24) - Destination: pod2-leaf6b Loopback0 (IP: 10.255.2.16)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf10b
+ hosts:
+ - destination: 10.255.2.17
+ repeat: 1
+ source: 10.255.1.24
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.24) - Destination: pod2-leaf7a Loopback0 (IP: 10.255.2.17)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf10b
+ hosts:
+ - destination: 10.255.2.18
+ repeat: 1
+ source: 10.255.1.24
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.24) - Destination: pod2-leaf7b Loopback0 (IP: 10.255.2.18)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf10b
+ hosts:
+ - destination: 10.255.2.19
+ repeat: 1
+ source: 10.255.1.24
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.24) - Destination: pod2-leaf8a Loopback0 (IP: 10.255.2.19)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf10b
+ hosts:
+ - destination: 10.255.2.20
+ repeat: 1
+ source: 10.255.1.24
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.24) - Destination: pod2-leaf8b Loopback0 (IP: 10.255.2.20)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf10b
+ hosts:
+ - destination: 10.255.2.21
+ repeat: 1
+ source: 10.255.1.24
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.24) - Destination: pod2-leaf9a Loopback0 (IP: 10.255.2.21)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf10b
+ hosts:
+ - destination: 10.255.2.22
+ repeat: 1
+ source: 10.255.1.24
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.24) - Destination: pod2-leaf9b Loopback0 (IP: 10.255.2.22)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf10b
+ hosts:
+ - destination: 10.255.2.23
+ repeat: 1
+ source: 10.255.1.24
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.24) - Destination: pod2-leaf10a Loopback0 (IP: 10.255.2.23)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf10b
+ hosts:
+ - destination: 10.255.2.24
+ repeat: 1
+ source: 10.255.1.24
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.24) - Destination: pod2-leaf10b Loopback0 (IP: 10.255.2.24)'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-leaf7a
+ neighbors:
+ - neighbor_device: pod1-leaf7b
+ neighbor_port: Ethernet53/1
+ port: Ethernet53/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet53/1 - Remote: pod1-leaf7b Ethernet53/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-leaf7a
+ neighbors:
+ - neighbor_device: pod1-leaf7b
+ neighbor_port: Ethernet54/1
+ port: Ethernet54/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet54/1 - Remote: pod1-leaf7b Ethernet54/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-leaf7a
+ neighbors:
+ - neighbor_device: pod1-spine1
+ neighbor_port: Ethernet13/1
+ port: Ethernet1/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet1/1 - Remote: pod1-spine1 Ethernet13/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-leaf7a
+ neighbors:
+ - neighbor_device: pod1-spine2
+ neighbor_port: Ethernet13/1
+ port: Ethernet2/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet2/1 - Remote: pod1-spine2 Ethernet13/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-leaf7a
+ neighbors:
+ - neighbor_device: pod1-spine3
+ neighbor_port: Ethernet13/1
+ port: Ethernet3/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet3/1 - Remote: pod1-spine3 Ethernet13/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-leaf7a
+ neighbors:
+ - neighbor_device: pod1-spine4
+ neighbor_port: Ethernet13/1
+ port: Ethernet4/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet4/1 - Remote: pod1-spine4 Ethernet13/1'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf7a
+ hosts:
+ - destination: 10.255.255.96
+ repeat: 1
+ source: 10.255.255.97
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet1/1 (IP: 10.255.255.97) - Destination: pod1-spine1 Ethernet13/1 (IP: 10.255.255.96)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf7a
+ hosts:
+ - destination: 10.255.255.98
+ repeat: 1
+ source: 10.255.255.99
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet2/1 (IP: 10.255.255.99) - Destination: pod1-spine2 Ethernet13/1 (IP: 10.255.255.98)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf7a
+ hosts:
+ - destination: 10.255.255.100
+ repeat: 1
+ source: 10.255.255.101
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet3/1 (IP: 10.255.255.101) - Destination: pod1-spine3 Ethernet13/1 (IP: 10.255.255.100)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf7a
+ hosts:
+ - destination: 10.255.255.102
+ repeat: 1
+ source: 10.255.255.103
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet4/1 (IP: 10.255.255.103) - Destination: pod1-spine4 Ethernet13/1 (IP: 10.255.255.102)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf7a
+ hosts:
+ - destination: 10.255.0.1
+ repeat: 1
+ source: 10.255.1.17
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.17) - Destination: super-spine1 Loopback0 (IP: 10.255.0.1)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf7a
+ hosts:
+ - destination: 10.255.0.2
+ repeat: 1
+ source: 10.255.1.17
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.17) - Destination: super-spine2 Loopback0 (IP: 10.255.0.2)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf7a
+ hosts:
+ - destination: 10.255.1.1
+ repeat: 1
+ source: 10.255.1.17
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.17) - Destination: pod1-spine1 Loopback0 (IP: 10.255.1.1)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf7a
+ hosts:
+ - destination: 10.255.1.2
+ repeat: 1
+ source: 10.255.1.17
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.17) - Destination: pod1-spine2 Loopback0 (IP: 10.255.1.2)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf7a
+ hosts:
+ - destination: 10.255.1.3
+ repeat: 1
+ source: 10.255.1.17
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.17) - Destination: pod1-spine3 Loopback0 (IP: 10.255.1.3)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf7a
+ hosts:
+ - destination: 10.255.1.4
+ repeat: 1
+ source: 10.255.1.17
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.17) - Destination: pod1-spine4 Loopback0 (IP: 10.255.1.4)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf7a
+ hosts:
+ - destination: 10.255.1.5
+ repeat: 1
+ source: 10.255.1.17
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.17) - Destination: pod1-leaf1a Loopback0 (IP: 10.255.1.5)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf7a
+ hosts:
+ - destination: 10.255.1.6
+ repeat: 1
+ source: 10.255.1.17
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.17) - Destination: pod1-leaf1b Loopback0 (IP: 10.255.1.6)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf7a
+ hosts:
+ - destination: 10.255.1.7
+ repeat: 1
+ source: 10.255.1.17
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.17) - Destination: pod1-leaf2a Loopback0 (IP: 10.255.1.7)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf7a
+ hosts:
+ - destination: 10.255.1.8
+ repeat: 1
+ source: 10.255.1.17
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.17) - Destination: pod1-leaf2b Loopback0 (IP: 10.255.1.8)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf7a
+ hosts:
+ - destination: 10.255.1.9
+ repeat: 1
+ source: 10.255.1.17
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.17) - Destination: pod1-leaf3a Loopback0 (IP: 10.255.1.9)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf7a
+ hosts:
+ - destination: 10.255.1.10
+ repeat: 1
+ source: 10.255.1.17
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.17) - Destination: pod1-leaf3b Loopback0 (IP: 10.255.1.10)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf7a
+ hosts:
+ - destination: 10.255.1.11
+ repeat: 1
+ source: 10.255.1.17
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.17) - Destination: pod1-leaf4a Loopback0 (IP: 10.255.1.11)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf7a
+ hosts:
+ - destination: 10.255.1.12
+ repeat: 1
+ source: 10.255.1.17
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.17) - Destination: pod1-leaf4b Loopback0 (IP: 10.255.1.12)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf7a
+ hosts:
+ - destination: 10.255.1.13
+ repeat: 1
+ source: 10.255.1.17
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.17) - Destination: pod1-leaf5a Loopback0 (IP: 10.255.1.13)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf7a
+ hosts:
+ - destination: 10.255.1.14
+ repeat: 1
+ source: 10.255.1.17
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.17) - Destination: pod1-leaf5b Loopback0 (IP: 10.255.1.14)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf7a
+ hosts:
+ - destination: 10.255.1.15
+ repeat: 1
+ source: 10.255.1.17
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.17) - Destination: pod1-leaf6a Loopback0 (IP: 10.255.1.15)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf7a
+ hosts:
+ - destination: 10.255.1.16
+ repeat: 1
+ source: 10.255.1.17
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.17) - Destination: pod1-leaf6b Loopback0 (IP: 10.255.1.16)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf7a
+ hosts:
+ - destination: 10.255.1.17
+ repeat: 1
+ source: 10.255.1.17
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.17) - Destination: pod1-leaf7a Loopback0 (IP: 10.255.1.17)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf7a
+ hosts:
+ - destination: 10.255.1.18
+ repeat: 1
+ source: 10.255.1.17
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.17) - Destination: pod1-leaf7b Loopback0 (IP: 10.255.1.18)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf7a
+ hosts:
+ - destination: 10.255.1.19
+ repeat: 1
+ source: 10.255.1.17
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.17) - Destination: pod1-leaf8a Loopback0 (IP: 10.255.1.19)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf7a
+ hosts:
+ - destination: 10.255.1.20
+ repeat: 1
+ source: 10.255.1.17
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.17) - Destination: pod1-leaf8b Loopback0 (IP: 10.255.1.20)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf7a
+ hosts:
+ - destination: 10.255.1.21
+ repeat: 1
+ source: 10.255.1.17
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.17) - Destination: pod1-leaf9a Loopback0 (IP: 10.255.1.21)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf7a
+ hosts:
+ - destination: 10.255.1.22
+ repeat: 1
+ source: 10.255.1.17
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.17) - Destination: pod1-leaf9b Loopback0 (IP: 10.255.1.22)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf7a
+ hosts:
+ - destination: 10.255.1.23
+ repeat: 1
+ source: 10.255.1.17
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.17) - Destination: pod1-leaf10a Loopback0 (IP: 10.255.1.23)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf7a
+ hosts:
+ - destination: 10.255.1.24
+ repeat: 1
+ source: 10.255.1.17
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.17) - Destination: pod1-leaf10b Loopback0 (IP: 10.255.1.24)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf7a
+ hosts:
+ - destination: 10.255.2.1
+ repeat: 1
+ source: 10.255.1.17
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.17) - Destination: pod2-spine1 Loopback0 (IP: 10.255.2.1)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf7a
+ hosts:
+ - destination: 10.255.2.2
+ repeat: 1
+ source: 10.255.1.17
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.17) - Destination: pod2-spine2 Loopback0 (IP: 10.255.2.2)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf7a
+ hosts:
+ - destination: 10.255.2.3
+ repeat: 1
+ source: 10.255.1.17
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.17) - Destination: pod2-spine3 Loopback0 (IP: 10.255.2.3)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf7a
+ hosts:
+ - destination: 10.255.2.4
+ repeat: 1
+ source: 10.255.1.17
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.17) - Destination: pod2-spine4 Loopback0 (IP: 10.255.2.4)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf7a
+ hosts:
+ - destination: 10.255.2.5
+ repeat: 1
+ source: 10.255.1.17
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.17) - Destination: pod2-leaf1a Loopback0 (IP: 10.255.2.5)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf7a
+ hosts:
+ - destination: 10.255.2.6
+ repeat: 1
+ source: 10.255.1.17
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.17) - Destination: pod2-leaf1b Loopback0 (IP: 10.255.2.6)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf7a
+ hosts:
+ - destination: 10.255.2.7
+ repeat: 1
+ source: 10.255.1.17
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.17) - Destination: pod2-leaf2a Loopback0 (IP: 10.255.2.7)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf7a
+ hosts:
+ - destination: 10.255.2.8
+ repeat: 1
+ source: 10.255.1.17
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.17) - Destination: pod2-leaf2b Loopback0 (IP: 10.255.2.8)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf7a
+ hosts:
+ - destination: 10.255.2.9
+ repeat: 1
+ source: 10.255.1.17
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.17) - Destination: pod2-leaf3a Loopback0 (IP: 10.255.2.9)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf7a
+ hosts:
+ - destination: 10.255.2.10
+ repeat: 1
+ source: 10.255.1.17
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.17) - Destination: pod2-leaf3b Loopback0 (IP: 10.255.2.10)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf7a
+ hosts:
+ - destination: 10.255.2.11
+ repeat: 1
+ source: 10.255.1.17
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.17) - Destination: pod2-leaf4a Loopback0 (IP: 10.255.2.11)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf7a
+ hosts:
+ - destination: 10.255.2.12
+ repeat: 1
+ source: 10.255.1.17
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.17) - Destination: pod2-leaf4b Loopback0 (IP: 10.255.2.12)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf7a
+ hosts:
+ - destination: 10.255.2.13
+ repeat: 1
+ source: 10.255.1.17
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.17) - Destination: pod2-leaf5a Loopback0 (IP: 10.255.2.13)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf7a
+ hosts:
+ - destination: 10.255.2.14
+ repeat: 1
+ source: 10.255.1.17
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.17) - Destination: pod2-leaf5b Loopback0 (IP: 10.255.2.14)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf7a
+ hosts:
+ - destination: 10.255.2.15
+ repeat: 1
+ source: 10.255.1.17
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.17) - Destination: pod2-leaf6a Loopback0 (IP: 10.255.2.15)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf7a
+ hosts:
+ - destination: 10.255.2.16
+ repeat: 1
+ source: 10.255.1.17
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.17) - Destination: pod2-leaf6b Loopback0 (IP: 10.255.2.16)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf7a
+ hosts:
+ - destination: 10.255.2.17
+ repeat: 1
+ source: 10.255.1.17
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.17) - Destination: pod2-leaf7a Loopback0 (IP: 10.255.2.17)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf7a
+ hosts:
+ - destination: 10.255.2.18
+ repeat: 1
+ source: 10.255.1.17
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.17) - Destination: pod2-leaf7b Loopback0 (IP: 10.255.2.18)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf7a
+ hosts:
+ - destination: 10.255.2.19
+ repeat: 1
+ source: 10.255.1.17
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.17) - Destination: pod2-leaf8a Loopback0 (IP: 10.255.2.19)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf7a
+ hosts:
+ - destination: 10.255.2.20
+ repeat: 1
+ source: 10.255.1.17
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.17) - Destination: pod2-leaf8b Loopback0 (IP: 10.255.2.20)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf7a
+ hosts:
+ - destination: 10.255.2.21
+ repeat: 1
+ source: 10.255.1.17
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.17) - Destination: pod2-leaf9a Loopback0 (IP: 10.255.2.21)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf7a
+ hosts:
+ - destination: 10.255.2.22
+ repeat: 1
+ source: 10.255.1.17
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.17) - Destination: pod2-leaf9b Loopback0 (IP: 10.255.2.22)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf7a
+ hosts:
+ - destination: 10.255.2.23
+ repeat: 1
+ source: 10.255.1.17
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.17) - Destination: pod2-leaf10a Loopback0 (IP: 10.255.2.23)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf7a
+ hosts:
+ - destination: 10.255.2.24
+ repeat: 1
+ source: 10.255.1.17
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.17) - Destination: pod2-leaf10b Loopback0 (IP: 10.255.2.24)'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-leaf10b
+ neighbors:
+ - neighbor_device: pod2-leaf10a
+ neighbor_port: Ethernet53/1
+ port: Ethernet53/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet53/1 - Remote: pod2-leaf10a Ethernet53/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-leaf10b
+ neighbors:
+ - neighbor_device: pod2-leaf10a
+ neighbor_port: Ethernet54/1
+ port: Ethernet54/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet54/1 - Remote: pod2-leaf10a Ethernet54/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-leaf10b
+ neighbors:
+ - neighbor_device: pod2-spine1
+ neighbor_port: Ethernet20/1
+ port: Ethernet1/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet1/1 - Remote: pod2-spine1 Ethernet20/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-leaf10b
+ neighbors:
+ - neighbor_device: pod2-spine2
+ neighbor_port: Ethernet20/1
+ port: Ethernet2/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet2/1 - Remote: pod2-spine2 Ethernet20/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-leaf10b
+ neighbors:
+ - neighbor_device: pod2-spine3
+ neighbor_port: Ethernet20/1
+ port: Ethernet3/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet3/1 - Remote: pod2-spine3 Ethernet20/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-leaf10b
+ neighbors:
+ - neighbor_device: pod2-spine4
+ neighbor_port: Ethernet20/1
+ port: Ethernet4/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet4/1 - Remote: pod2-spine4 Ethernet20/1'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf10b
+ hosts:
+ - destination: 10.255.255.152
+ repeat: 1
+ source: 10.255.255.153
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet1/1 (IP: 10.255.255.153) - Destination: pod2-spine1 Ethernet20/1 (IP: 10.255.255.152)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf10b
+ hosts:
+ - destination: 10.255.255.154
+ repeat: 1
+ source: 10.255.255.155
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet2/1 (IP: 10.255.255.155) - Destination: pod2-spine2 Ethernet20/1 (IP: 10.255.255.154)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf10b
+ hosts:
+ - destination: 10.255.255.156
+ repeat: 1
+ source: 10.255.255.157
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet3/1 (IP: 10.255.255.157) - Destination: pod2-spine3 Ethernet20/1 (IP: 10.255.255.156)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf10b
+ hosts:
+ - destination: 10.255.255.158
+ repeat: 1
+ source: 10.255.255.159
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet4/1 (IP: 10.255.255.159) - Destination: pod2-spine4 Ethernet20/1 (IP: 10.255.255.158)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf10b
+ hosts:
+ - destination: 10.255.0.1
+ repeat: 1
+ source: 10.255.2.24
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.24) - Destination: super-spine1 Loopback0 (IP: 10.255.0.1)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf10b
+ hosts:
+ - destination: 10.255.0.2
+ repeat: 1
+ source: 10.255.2.24
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.24) - Destination: super-spine2 Loopback0 (IP: 10.255.0.2)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf10b
+ hosts:
+ - destination: 10.255.1.1
+ repeat: 1
+ source: 10.255.2.24
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.24) - Destination: pod1-spine1 Loopback0 (IP: 10.255.1.1)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf10b
+ hosts:
+ - destination: 10.255.1.2
+ repeat: 1
+ source: 10.255.2.24
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.24) - Destination: pod1-spine2 Loopback0 (IP: 10.255.1.2)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf10b
+ hosts:
+ - destination: 10.255.1.3
+ repeat: 1
+ source: 10.255.2.24
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.24) - Destination: pod1-spine3 Loopback0 (IP: 10.255.1.3)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf10b
+ hosts:
+ - destination: 10.255.1.4
+ repeat: 1
+ source: 10.255.2.24
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.24) - Destination: pod1-spine4 Loopback0 (IP: 10.255.1.4)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf10b
+ hosts:
+ - destination: 10.255.1.5
+ repeat: 1
+ source: 10.255.2.24
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.24) - Destination: pod1-leaf1a Loopback0 (IP: 10.255.1.5)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf10b
+ hosts:
+ - destination: 10.255.1.6
+ repeat: 1
+ source: 10.255.2.24
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.24) - Destination: pod1-leaf1b Loopback0 (IP: 10.255.1.6)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf10b
+ hosts:
+ - destination: 10.255.1.7
+ repeat: 1
+ source: 10.255.2.24
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.24) - Destination: pod1-leaf2a Loopback0 (IP: 10.255.1.7)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf10b
+ hosts:
+ - destination: 10.255.1.8
+ repeat: 1
+ source: 10.255.2.24
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.24) - Destination: pod1-leaf2b Loopback0 (IP: 10.255.1.8)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf10b
+ hosts:
+ - destination: 10.255.1.9
+ repeat: 1
+ source: 10.255.2.24
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.24) - Destination: pod1-leaf3a Loopback0 (IP: 10.255.1.9)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf10b
+ hosts:
+ - destination: 10.255.1.10
+ repeat: 1
+ source: 10.255.2.24
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.24) - Destination: pod1-leaf3b Loopback0 (IP: 10.255.1.10)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf10b
+ hosts:
+ - destination: 10.255.1.11
+ repeat: 1
+ source: 10.255.2.24
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.24) - Destination: pod1-leaf4a Loopback0 (IP: 10.255.1.11)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf10b
+ hosts:
+ - destination: 10.255.1.12
+ repeat: 1
+ source: 10.255.2.24
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.24) - Destination: pod1-leaf4b Loopback0 (IP: 10.255.1.12)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf10b
+ hosts:
+ - destination: 10.255.1.13
+ repeat: 1
+ source: 10.255.2.24
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.24) - Destination: pod1-leaf5a Loopback0 (IP: 10.255.1.13)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf10b
+ hosts:
+ - destination: 10.255.1.14
+ repeat: 1
+ source: 10.255.2.24
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.24) - Destination: pod1-leaf5b Loopback0 (IP: 10.255.1.14)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf10b
+ hosts:
+ - destination: 10.255.1.15
+ repeat: 1
+ source: 10.255.2.24
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.24) - Destination: pod1-leaf6a Loopback0 (IP: 10.255.1.15)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf10b
+ hosts:
+ - destination: 10.255.1.16
+ repeat: 1
+ source: 10.255.2.24
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.24) - Destination: pod1-leaf6b Loopback0 (IP: 10.255.1.16)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf10b
+ hosts:
+ - destination: 10.255.1.17
+ repeat: 1
+ source: 10.255.2.24
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.24) - Destination: pod1-leaf7a Loopback0 (IP: 10.255.1.17)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf10b
+ hosts:
+ - destination: 10.255.1.18
+ repeat: 1
+ source: 10.255.2.24
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.24) - Destination: pod1-leaf7b Loopback0 (IP: 10.255.1.18)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf10b
+ hosts:
+ - destination: 10.255.1.19
+ repeat: 1
+ source: 10.255.2.24
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.24) - Destination: pod1-leaf8a Loopback0 (IP: 10.255.1.19)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf10b
+ hosts:
+ - destination: 10.255.1.20
+ repeat: 1
+ source: 10.255.2.24
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.24) - Destination: pod1-leaf8b Loopback0 (IP: 10.255.1.20)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf10b
+ hosts:
+ - destination: 10.255.1.21
+ repeat: 1
+ source: 10.255.2.24
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.24) - Destination: pod1-leaf9a Loopback0 (IP: 10.255.1.21)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf10b
+ hosts:
+ - destination: 10.255.1.22
+ repeat: 1
+ source: 10.255.2.24
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.24) - Destination: pod1-leaf9b Loopback0 (IP: 10.255.1.22)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf10b
+ hosts:
+ - destination: 10.255.1.23
+ repeat: 1
+ source: 10.255.2.24
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.24) - Destination: pod1-leaf10a Loopback0 (IP: 10.255.1.23)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf10b
+ hosts:
+ - destination: 10.255.1.24
+ repeat: 1
+ source: 10.255.2.24
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.24) - Destination: pod1-leaf10b Loopback0 (IP: 10.255.1.24)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf10b
+ hosts:
+ - destination: 10.255.2.1
+ repeat: 1
+ source: 10.255.2.24
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.24) - Destination: pod2-spine1 Loopback0 (IP: 10.255.2.1)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf10b
+ hosts:
+ - destination: 10.255.2.2
+ repeat: 1
+ source: 10.255.2.24
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.24) - Destination: pod2-spine2 Loopback0 (IP: 10.255.2.2)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf10b
+ hosts:
+ - destination: 10.255.2.3
+ repeat: 1
+ source: 10.255.2.24
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.24) - Destination: pod2-spine3 Loopback0 (IP: 10.255.2.3)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf10b
+ hosts:
+ - destination: 10.255.2.4
+ repeat: 1
+ source: 10.255.2.24
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.24) - Destination: pod2-spine4 Loopback0 (IP: 10.255.2.4)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf10b
+ hosts:
+ - destination: 10.255.2.5
+ repeat: 1
+ source: 10.255.2.24
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.24) - Destination: pod2-leaf1a Loopback0 (IP: 10.255.2.5)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf10b
+ hosts:
+ - destination: 10.255.2.6
+ repeat: 1
+ source: 10.255.2.24
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.24) - Destination: pod2-leaf1b Loopback0 (IP: 10.255.2.6)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf10b
+ hosts:
+ - destination: 10.255.2.7
+ repeat: 1
+ source: 10.255.2.24
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.24) - Destination: pod2-leaf2a Loopback0 (IP: 10.255.2.7)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf10b
+ hosts:
+ - destination: 10.255.2.8
+ repeat: 1
+ source: 10.255.2.24
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.24) - Destination: pod2-leaf2b Loopback0 (IP: 10.255.2.8)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf10b
+ hosts:
+ - destination: 10.255.2.9
+ repeat: 1
+ source: 10.255.2.24
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.24) - Destination: pod2-leaf3a Loopback0 (IP: 10.255.2.9)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf10b
+ hosts:
+ - destination: 10.255.2.10
+ repeat: 1
+ source: 10.255.2.24
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.24) - Destination: pod2-leaf3b Loopback0 (IP: 10.255.2.10)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf10b
+ hosts:
+ - destination: 10.255.2.11
+ repeat: 1
+ source: 10.255.2.24
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.24) - Destination: pod2-leaf4a Loopback0 (IP: 10.255.2.11)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf10b
+ hosts:
+ - destination: 10.255.2.12
+ repeat: 1
+ source: 10.255.2.24
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.24) - Destination: pod2-leaf4b Loopback0 (IP: 10.255.2.12)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf10b
+ hosts:
+ - destination: 10.255.2.13
+ repeat: 1
+ source: 10.255.2.24
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.24) - Destination: pod2-leaf5a Loopback0 (IP: 10.255.2.13)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf10b
+ hosts:
+ - destination: 10.255.2.14
+ repeat: 1
+ source: 10.255.2.24
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.24) - Destination: pod2-leaf5b Loopback0 (IP: 10.255.2.14)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf10b
+ hosts:
+ - destination: 10.255.2.15
+ repeat: 1
+ source: 10.255.2.24
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.24) - Destination: pod2-leaf6a Loopback0 (IP: 10.255.2.15)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf10b
+ hosts:
+ - destination: 10.255.2.16
+ repeat: 1
+ source: 10.255.2.24
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.24) - Destination: pod2-leaf6b Loopback0 (IP: 10.255.2.16)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf10b
+ hosts:
+ - destination: 10.255.2.17
+ repeat: 1
+ source: 10.255.2.24
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.24) - Destination: pod2-leaf7a Loopback0 (IP: 10.255.2.17)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf10b
+ hosts:
+ - destination: 10.255.2.18
+ repeat: 1
+ source: 10.255.2.24
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.24) - Destination: pod2-leaf7b Loopback0 (IP: 10.255.2.18)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf10b
+ hosts:
+ - destination: 10.255.2.19
+ repeat: 1
+ source: 10.255.2.24
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.24) - Destination: pod2-leaf8a Loopback0 (IP: 10.255.2.19)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf10b
+ hosts:
+ - destination: 10.255.2.20
+ repeat: 1
+ source: 10.255.2.24
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.24) - Destination: pod2-leaf8b Loopback0 (IP: 10.255.2.20)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf10b
+ hosts:
+ - destination: 10.255.2.21
+ repeat: 1
+ source: 10.255.2.24
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.24) - Destination: pod2-leaf9a Loopback0 (IP: 10.255.2.21)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf10b
+ hosts:
+ - destination: 10.255.2.22
+ repeat: 1
+ source: 10.255.2.24
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.24) - Destination: pod2-leaf9b Loopback0 (IP: 10.255.2.22)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf10b
+ hosts:
+ - destination: 10.255.2.23
+ repeat: 1
+ source: 10.255.2.24
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.24) - Destination: pod2-leaf10a Loopback0 (IP: 10.255.2.23)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf10b
+ hosts:
+ - destination: 10.255.2.24
+ repeat: 1
+ source: 10.255.2.24
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.24) - Destination: pod2-leaf10b Loopback0 (IP: 10.255.2.24)'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-leaf10a
+ neighbors:
+ - neighbor_device: pod2-leaf10b
+ neighbor_port: Ethernet53/1
+ port: Ethernet53/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet53/1 - Remote: pod2-leaf10b Ethernet53/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-leaf10a
+ neighbors:
+ - neighbor_device: pod2-leaf10b
+ neighbor_port: Ethernet54/1
+ port: Ethernet54/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet54/1 - Remote: pod2-leaf10b Ethernet54/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-leaf10a
+ neighbors:
+ - neighbor_device: pod2-spine1
+ neighbor_port: Ethernet19/1
+ port: Ethernet1/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet1/1 - Remote: pod2-spine1 Ethernet19/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-leaf10a
+ neighbors:
+ - neighbor_device: pod2-spine2
+ neighbor_port: Ethernet19/1
+ port: Ethernet2/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet2/1 - Remote: pod2-spine2 Ethernet19/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-leaf10a
+ neighbors:
+ - neighbor_device: pod2-spine3
+ neighbor_port: Ethernet19/1
+ port: Ethernet3/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet3/1 - Remote: pod2-spine3 Ethernet19/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-leaf10a
+ neighbors:
+ - neighbor_device: pod2-spine4
+ neighbor_port: Ethernet19/1
+ port: Ethernet4/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet4/1 - Remote: pod2-spine4 Ethernet19/1'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf10a
+ hosts:
+ - destination: 10.255.255.144
+ repeat: 1
+ source: 10.255.255.145
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet1/1 (IP: 10.255.255.145) - Destination: pod2-spine1 Ethernet19/1 (IP: 10.255.255.144)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf10a
+ hosts:
+ - destination: 10.255.255.146
+ repeat: 1
+ source: 10.255.255.147
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet2/1 (IP: 10.255.255.147) - Destination: pod2-spine2 Ethernet19/1 (IP: 10.255.255.146)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf10a
+ hosts:
+ - destination: 10.255.255.148
+ repeat: 1
+ source: 10.255.255.149
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet3/1 (IP: 10.255.255.149) - Destination: pod2-spine3 Ethernet19/1 (IP: 10.255.255.148)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf10a
+ hosts:
+ - destination: 10.255.255.150
+ repeat: 1
+ source: 10.255.255.151
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet4/1 (IP: 10.255.255.151) - Destination: pod2-spine4 Ethernet19/1 (IP: 10.255.255.150)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf10a
+ hosts:
+ - destination: 10.255.0.1
+ repeat: 1
+ source: 10.255.2.23
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.23) - Destination: super-spine1 Loopback0 (IP: 10.255.0.1)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf10a
+ hosts:
+ - destination: 10.255.0.2
+ repeat: 1
+ source: 10.255.2.23
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.23) - Destination: super-spine2 Loopback0 (IP: 10.255.0.2)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf10a
+ hosts:
+ - destination: 10.255.1.1
+ repeat: 1
+ source: 10.255.2.23
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.23) - Destination: pod1-spine1 Loopback0 (IP: 10.255.1.1)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf10a
+ hosts:
+ - destination: 10.255.1.2
+ repeat: 1
+ source: 10.255.2.23
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.23) - Destination: pod1-spine2 Loopback0 (IP: 10.255.1.2)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf10a
+ hosts:
+ - destination: 10.255.1.3
+ repeat: 1
+ source: 10.255.2.23
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.23) - Destination: pod1-spine3 Loopback0 (IP: 10.255.1.3)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf10a
+ hosts:
+ - destination: 10.255.1.4
+ repeat: 1
+ source: 10.255.2.23
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.23) - Destination: pod1-spine4 Loopback0 (IP: 10.255.1.4)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf10a
+ hosts:
+ - destination: 10.255.1.5
+ repeat: 1
+ source: 10.255.2.23
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.23) - Destination: pod1-leaf1a Loopback0 (IP: 10.255.1.5)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf10a
+ hosts:
+ - destination: 10.255.1.6
+ repeat: 1
+ source: 10.255.2.23
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.23) - Destination: pod1-leaf1b Loopback0 (IP: 10.255.1.6)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf10a
+ hosts:
+ - destination: 10.255.1.7
+ repeat: 1
+ source: 10.255.2.23
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.23) - Destination: pod1-leaf2a Loopback0 (IP: 10.255.1.7)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf10a
+ hosts:
+ - destination: 10.255.1.8
+ repeat: 1
+ source: 10.255.2.23
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.23) - Destination: pod1-leaf2b Loopback0 (IP: 10.255.1.8)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf10a
+ hosts:
+ - destination: 10.255.1.9
+ repeat: 1
+ source: 10.255.2.23
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.23) - Destination: pod1-leaf3a Loopback0 (IP: 10.255.1.9)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf10a
+ hosts:
+ - destination: 10.255.1.10
+ repeat: 1
+ source: 10.255.2.23
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.23) - Destination: pod1-leaf3b Loopback0 (IP: 10.255.1.10)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf10a
+ hosts:
+ - destination: 10.255.1.11
+ repeat: 1
+ source: 10.255.2.23
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.23) - Destination: pod1-leaf4a Loopback0 (IP: 10.255.1.11)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf10a
+ hosts:
+ - destination: 10.255.1.12
+ repeat: 1
+ source: 10.255.2.23
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.23) - Destination: pod1-leaf4b Loopback0 (IP: 10.255.1.12)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf10a
+ hosts:
+ - destination: 10.255.1.13
+ repeat: 1
+ source: 10.255.2.23
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.23) - Destination: pod1-leaf5a Loopback0 (IP: 10.255.1.13)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf10a
+ hosts:
+ - destination: 10.255.1.14
+ repeat: 1
+ source: 10.255.2.23
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.23) - Destination: pod1-leaf5b Loopback0 (IP: 10.255.1.14)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf10a
+ hosts:
+ - destination: 10.255.1.15
+ repeat: 1
+ source: 10.255.2.23
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.23) - Destination: pod1-leaf6a Loopback0 (IP: 10.255.1.15)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf10a
+ hosts:
+ - destination: 10.255.1.16
+ repeat: 1
+ source: 10.255.2.23
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.23) - Destination: pod1-leaf6b Loopback0 (IP: 10.255.1.16)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf10a
+ hosts:
+ - destination: 10.255.1.17
+ repeat: 1
+ source: 10.255.2.23
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.23) - Destination: pod1-leaf7a Loopback0 (IP: 10.255.1.17)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf10a
+ hosts:
+ - destination: 10.255.1.18
+ repeat: 1
+ source: 10.255.2.23
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.23) - Destination: pod1-leaf7b Loopback0 (IP: 10.255.1.18)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf10a
+ hosts:
+ - destination: 10.255.1.19
+ repeat: 1
+ source: 10.255.2.23
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.23) - Destination: pod1-leaf8a Loopback0 (IP: 10.255.1.19)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf10a
+ hosts:
+ - destination: 10.255.1.20
+ repeat: 1
+ source: 10.255.2.23
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.23) - Destination: pod1-leaf8b Loopback0 (IP: 10.255.1.20)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf10a
+ hosts:
+ - destination: 10.255.1.21
+ repeat: 1
+ source: 10.255.2.23
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.23) - Destination: pod1-leaf9a Loopback0 (IP: 10.255.1.21)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf10a
+ hosts:
+ - destination: 10.255.1.22
+ repeat: 1
+ source: 10.255.2.23
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.23) - Destination: pod1-leaf9b Loopback0 (IP: 10.255.1.22)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf10a
+ hosts:
+ - destination: 10.255.1.23
+ repeat: 1
+ source: 10.255.2.23
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.23) - Destination: pod1-leaf10a Loopback0 (IP: 10.255.1.23)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf10a
+ hosts:
+ - destination: 10.255.1.24
+ repeat: 1
+ source: 10.255.2.23
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.23) - Destination: pod1-leaf10b Loopback0 (IP: 10.255.1.24)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf10a
+ hosts:
+ - destination: 10.255.2.1
+ repeat: 1
+ source: 10.255.2.23
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.23) - Destination: pod2-spine1 Loopback0 (IP: 10.255.2.1)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf10a
+ hosts:
+ - destination: 10.255.2.2
+ repeat: 1
+ source: 10.255.2.23
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.23) - Destination: pod2-spine2 Loopback0 (IP: 10.255.2.2)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf10a
+ hosts:
+ - destination: 10.255.2.3
+ repeat: 1
+ source: 10.255.2.23
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.23) - Destination: pod2-spine3 Loopback0 (IP: 10.255.2.3)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf10a
+ hosts:
+ - destination: 10.255.2.4
+ repeat: 1
+ source: 10.255.2.23
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.23) - Destination: pod2-spine4 Loopback0 (IP: 10.255.2.4)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf10a
+ hosts:
+ - destination: 10.255.2.5
+ repeat: 1
+ source: 10.255.2.23
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.23) - Destination: pod2-leaf1a Loopback0 (IP: 10.255.2.5)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf10a
+ hosts:
+ - destination: 10.255.2.6
+ repeat: 1
+ source: 10.255.2.23
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.23) - Destination: pod2-leaf1b Loopback0 (IP: 10.255.2.6)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf10a
+ hosts:
+ - destination: 10.255.2.7
+ repeat: 1
+ source: 10.255.2.23
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.23) - Destination: pod2-leaf2a Loopback0 (IP: 10.255.2.7)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf10a
+ hosts:
+ - destination: 10.255.2.8
+ repeat: 1
+ source: 10.255.2.23
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.23) - Destination: pod2-leaf2b Loopback0 (IP: 10.255.2.8)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf10a
+ hosts:
+ - destination: 10.255.2.9
+ repeat: 1
+ source: 10.255.2.23
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.23) - Destination: pod2-leaf3a Loopback0 (IP: 10.255.2.9)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf10a
+ hosts:
+ - destination: 10.255.2.10
+ repeat: 1
+ source: 10.255.2.23
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.23) - Destination: pod2-leaf3b Loopback0 (IP: 10.255.2.10)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf10a
+ hosts:
+ - destination: 10.255.2.11
+ repeat: 1
+ source: 10.255.2.23
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.23) - Destination: pod2-leaf4a Loopback0 (IP: 10.255.2.11)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf10a
+ hosts:
+ - destination: 10.255.2.12
+ repeat: 1
+ source: 10.255.2.23
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.23) - Destination: pod2-leaf4b Loopback0 (IP: 10.255.2.12)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf10a
+ hosts:
+ - destination: 10.255.2.13
+ repeat: 1
+ source: 10.255.2.23
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.23) - Destination: pod2-leaf5a Loopback0 (IP: 10.255.2.13)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf10a
+ hosts:
+ - destination: 10.255.2.14
+ repeat: 1
+ source: 10.255.2.23
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.23) - Destination: pod2-leaf5b Loopback0 (IP: 10.255.2.14)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf10a
+ hosts:
+ - destination: 10.255.2.15
+ repeat: 1
+ source: 10.255.2.23
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.23) - Destination: pod2-leaf6a Loopback0 (IP: 10.255.2.15)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf10a
+ hosts:
+ - destination: 10.255.2.16
+ repeat: 1
+ source: 10.255.2.23
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.23) - Destination: pod2-leaf6b Loopback0 (IP: 10.255.2.16)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf10a
+ hosts:
+ - destination: 10.255.2.17
+ repeat: 1
+ source: 10.255.2.23
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.23) - Destination: pod2-leaf7a Loopback0 (IP: 10.255.2.17)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf10a
+ hosts:
+ - destination: 10.255.2.18
+ repeat: 1
+ source: 10.255.2.23
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.23) - Destination: pod2-leaf7b Loopback0 (IP: 10.255.2.18)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf10a
+ hosts:
+ - destination: 10.255.2.19
+ repeat: 1
+ source: 10.255.2.23
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.23) - Destination: pod2-leaf8a Loopback0 (IP: 10.255.2.19)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf10a
+ hosts:
+ - destination: 10.255.2.20
+ repeat: 1
+ source: 10.255.2.23
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.23) - Destination: pod2-leaf8b Loopback0 (IP: 10.255.2.20)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf10a
+ hosts:
+ - destination: 10.255.2.21
+ repeat: 1
+ source: 10.255.2.23
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.23) - Destination: pod2-leaf9a Loopback0 (IP: 10.255.2.21)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf10a
+ hosts:
+ - destination: 10.255.2.22
+ repeat: 1
+ source: 10.255.2.23
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.23) - Destination: pod2-leaf9b Loopback0 (IP: 10.255.2.22)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf10a
+ hosts:
+ - destination: 10.255.2.23
+ repeat: 1
+ source: 10.255.2.23
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.23) - Destination: pod2-leaf10a Loopback0 (IP: 10.255.2.23)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf10a
+ hosts:
+ - destination: 10.255.2.24
+ repeat: 1
+ source: 10.255.2.23
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.23) - Destination: pod2-leaf10b Loopback0 (IP: 10.255.2.24)'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-spine3
+ neighbors:
+ - neighbor_device: pod2-leaf1a
+ neighbor_port: Ethernet3/1
+ port: Ethernet1/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet1/1 - Remote: pod2-leaf1a Ethernet3/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-spine3
+ neighbors:
+ - neighbor_device: pod2-leaf1b
+ neighbor_port: Ethernet3/1
+ port: Ethernet2/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet2/1 - Remote: pod2-leaf1b Ethernet3/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-spine3
+ neighbors:
+ - neighbor_device: pod2-leaf2a
+ neighbor_port: Ethernet3/1
+ port: Ethernet3/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet3/1 - Remote: pod2-leaf2a Ethernet3/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-spine3
+ neighbors:
+ - neighbor_device: pod2-leaf2b
+ neighbor_port: Ethernet3/1
+ port: Ethernet4/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet4/1 - Remote: pod2-leaf2b Ethernet3/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-spine3
+ neighbors:
+ - neighbor_device: pod2-leaf3a
+ neighbor_port: Ethernet3/1
+ port: Ethernet5/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet5/1 - Remote: pod2-leaf3a Ethernet3/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-spine3
+ neighbors:
+ - neighbor_device: pod2-leaf3b
+ neighbor_port: Ethernet3/1
+ port: Ethernet6/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet6/1 - Remote: pod2-leaf3b Ethernet3/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-spine3
+ neighbors:
+ - neighbor_device: pod2-leaf4a
+ neighbor_port: Ethernet3/1
+ port: Ethernet7/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet7/1 - Remote: pod2-leaf4a Ethernet3/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-spine3
+ neighbors:
+ - neighbor_device: pod2-leaf4b
+ neighbor_port: Ethernet3/1
+ port: Ethernet8/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet8/1 - Remote: pod2-leaf4b Ethernet3/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-spine3
+ neighbors:
+ - neighbor_device: pod2-leaf5a
+ neighbor_port: Ethernet3/1
+ port: Ethernet9/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet9/1 - Remote: pod2-leaf5a Ethernet3/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-spine3
+ neighbors:
+ - neighbor_device: pod2-leaf5b
+ neighbor_port: Ethernet3/1
+ port: Ethernet10/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet10/1 - Remote: pod2-leaf5b Ethernet3/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-spine3
+ neighbors:
+ - neighbor_device: pod2-leaf6a
+ neighbor_port: Ethernet3/1
+ port: Ethernet11/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet11/1 - Remote: pod2-leaf6a Ethernet3/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-spine3
+ neighbors:
+ - neighbor_device: pod2-leaf6b
+ neighbor_port: Ethernet3/1
+ port: Ethernet12/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet12/1 - Remote: pod2-leaf6b Ethernet3/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-spine3
+ neighbors:
+ - neighbor_device: pod2-leaf7a
+ neighbor_port: Ethernet3/1
+ port: Ethernet13/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet13/1 - Remote: pod2-leaf7a Ethernet3/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-spine3
+ neighbors:
+ - neighbor_device: pod2-leaf7b
+ neighbor_port: Ethernet3/1
+ port: Ethernet14/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet14/1 - Remote: pod2-leaf7b Ethernet3/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-spine3
+ neighbors:
+ - neighbor_device: pod2-leaf8a
+ neighbor_port: Ethernet3/1
+ port: Ethernet15/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet15/1 - Remote: pod2-leaf8a Ethernet3/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-spine3
+ neighbors:
+ - neighbor_device: pod2-leaf8b
+ neighbor_port: Ethernet3/1
+ port: Ethernet16/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet16/1 - Remote: pod2-leaf8b Ethernet3/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-spine3
+ neighbors:
+ - neighbor_device: pod2-leaf9a
+ neighbor_port: Ethernet3/1
+ port: Ethernet17/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet17/1 - Remote: pod2-leaf9a Ethernet3/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-spine3
+ neighbors:
+ - neighbor_device: pod2-leaf9b
+ neighbor_port: Ethernet3/1
+ port: Ethernet18/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet18/1 - Remote: pod2-leaf9b Ethernet3/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-spine3
+ neighbors:
+ - neighbor_device: pod2-leaf10a
+ neighbor_port: Ethernet3/1
+ port: Ethernet19/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet19/1 - Remote: pod2-leaf10a Ethernet3/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-spine3
+ neighbors:
+ - neighbor_device: pod2-leaf10b
+ neighbor_port: Ethernet3/1
+ port: Ethernet20/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet20/1 - Remote: pod2-leaf10b Ethernet3/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-spine3
+ neighbors:
+ - neighbor_device: super-spine1
+ neighbor_port: Ethernet7/1
+ port: Ethernet31/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet31/1 - Remote: super-spine1 Ethernet7/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-spine3
+ neighbors:
+ - neighbor_device: super-spine2
+ neighbor_port: Ethernet7/1
+ port: Ethernet32/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet32/1 - Remote: super-spine2 Ethernet7/1'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-spine3
+ hosts:
+ - destination: 10.255.255.5
+ repeat: 1
+ source: 10.255.255.4
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet1/1 (IP: 10.255.255.4) - Destination: pod2-leaf1a Ethernet3/1 (IP: 10.255.255.5)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-spine3
+ hosts:
+ - destination: 10.255.255.13
+ repeat: 1
+ source: 10.255.255.12
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet2/1 (IP: 10.255.255.12) - Destination: pod2-leaf1b Ethernet3/1 (IP: 10.255.255.13)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-spine3
+ hosts:
+ - destination: 10.255.255.21
+ repeat: 1
+ source: 10.255.255.20
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet3/1 (IP: 10.255.255.20) - Destination: pod2-leaf2a Ethernet3/1 (IP: 10.255.255.21)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-spine3
+ hosts:
+ - destination: 10.255.255.29
+ repeat: 1
+ source: 10.255.255.28
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet4/1 (IP: 10.255.255.28) - Destination: pod2-leaf2b Ethernet3/1 (IP: 10.255.255.29)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-spine3
+ hosts:
+ - destination: 10.255.255.37
+ repeat: 1
+ source: 10.255.255.36
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet5/1 (IP: 10.255.255.36) - Destination: pod2-leaf3a Ethernet3/1 (IP: 10.255.255.37)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-spine3
+ hosts:
+ - destination: 10.255.255.45
+ repeat: 1
+ source: 10.255.255.44
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet6/1 (IP: 10.255.255.44) - Destination: pod2-leaf3b Ethernet3/1 (IP: 10.255.255.45)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-spine3
+ hosts:
+ - destination: 10.255.255.53
+ repeat: 1
+ source: 10.255.255.52
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet7/1 (IP: 10.255.255.52) - Destination: pod2-leaf4a Ethernet3/1 (IP: 10.255.255.53)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-spine3
+ hosts:
+ - destination: 10.255.255.61
+ repeat: 1
+ source: 10.255.255.60
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet8/1 (IP: 10.255.255.60) - Destination: pod2-leaf4b Ethernet3/1 (IP: 10.255.255.61)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-spine3
+ hosts:
+ - destination: 10.255.255.69
+ repeat: 1
+ source: 10.255.255.68
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet9/1 (IP: 10.255.255.68) - Destination: pod2-leaf5a Ethernet3/1 (IP: 10.255.255.69)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-spine3
+ hosts:
+ - destination: 10.255.255.77
+ repeat: 1
+ source: 10.255.255.76
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet10/1 (IP: 10.255.255.76) - Destination: pod2-leaf5b Ethernet3/1 (IP: 10.255.255.77)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-spine3
+ hosts:
+ - destination: 10.255.255.85
+ repeat: 1
+ source: 10.255.255.84
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet11/1 (IP: 10.255.255.84) - Destination: pod2-leaf6a Ethernet3/1 (IP: 10.255.255.85)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-spine3
+ hosts:
+ - destination: 10.255.255.93
+ repeat: 1
+ source: 10.255.255.92
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet12/1 (IP: 10.255.255.92) - Destination: pod2-leaf6b Ethernet3/1 (IP: 10.255.255.93)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-spine3
+ hosts:
+ - destination: 10.255.255.101
+ repeat: 1
+ source: 10.255.255.100
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet13/1 (IP: 10.255.255.100) - Destination: pod2-leaf7a Ethernet3/1 (IP: 10.255.255.101)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-spine3
+ hosts:
+ - destination: 10.255.255.109
+ repeat: 1
+ source: 10.255.255.108
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet14/1 (IP: 10.255.255.108) - Destination: pod2-leaf7b Ethernet3/1 (IP: 10.255.255.109)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-spine3
+ hosts:
+ - destination: 10.255.255.117
+ repeat: 1
+ source: 10.255.255.116
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet15/1 (IP: 10.255.255.116) - Destination: pod2-leaf8a Ethernet3/1 (IP: 10.255.255.117)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-spine3
+ hosts:
+ - destination: 10.255.255.125
+ repeat: 1
+ source: 10.255.255.124
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet16/1 (IP: 10.255.255.124) - Destination: pod2-leaf8b Ethernet3/1 (IP: 10.255.255.125)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-spine3
+ hosts:
+ - destination: 10.255.255.133
+ repeat: 1
+ source: 10.255.255.132
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet17/1 (IP: 10.255.255.132) - Destination: pod2-leaf9a Ethernet3/1 (IP: 10.255.255.133)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-spine3
+ hosts:
+ - destination: 10.255.255.141
+ repeat: 1
+ source: 10.255.255.140
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet18/1 (IP: 10.255.255.140) - Destination: pod2-leaf9b Ethernet3/1 (IP: 10.255.255.141)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-spine3
+ hosts:
+ - destination: 10.255.255.149
+ repeat: 1
+ source: 10.255.255.148
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet19/1 (IP: 10.255.255.148) - Destination: pod2-leaf10a Ethernet3/1 (IP: 10.255.255.149)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-spine3
+ hosts:
+ - destination: 10.255.255.157
+ repeat: 1
+ source: 10.255.255.156
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet20/1 (IP: 10.255.255.156) - Destination: pod2-leaf10b Ethernet3/1 (IP: 10.255.255.157)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-spine3
+ hosts:
+ - destination: 10.255.255.136
+ repeat: 1
+ source: 10.255.255.137
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet31/1 (IP: 10.255.255.137) - Destination: super-spine1 Ethernet7/1 (IP: 10.255.255.136)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-spine3
+ hosts:
+ - destination: 10.255.255.138
+ repeat: 1
+ source: 10.255.255.139
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet32/1 (IP: 10.255.255.139) - Destination: super-spine2 Ethernet7/1 (IP: 10.255.255.138)'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-leaf7b
+ neighbors:
+ - neighbor_device: pod1-leaf7a
+ neighbor_port: Ethernet53/1
+ port: Ethernet53/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet53/1 - Remote: pod1-leaf7a Ethernet53/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-leaf7b
+ neighbors:
+ - neighbor_device: pod1-leaf7a
+ neighbor_port: Ethernet54/1
+ port: Ethernet54/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet54/1 - Remote: pod1-leaf7a Ethernet54/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-leaf7b
+ neighbors:
+ - neighbor_device: pod1-spine1
+ neighbor_port: Ethernet14/1
+ port: Ethernet1/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet1/1 - Remote: pod1-spine1 Ethernet14/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-leaf7b
+ neighbors:
+ - neighbor_device: pod1-spine2
+ neighbor_port: Ethernet14/1
+ port: Ethernet2/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet2/1 - Remote: pod1-spine2 Ethernet14/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-leaf7b
+ neighbors:
+ - neighbor_device: pod1-spine3
+ neighbor_port: Ethernet14/1
+ port: Ethernet3/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet3/1 - Remote: pod1-spine3 Ethernet14/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-leaf7b
+ neighbors:
+ - neighbor_device: pod1-spine4
+ neighbor_port: Ethernet14/1
+ port: Ethernet4/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet4/1 - Remote: pod1-spine4 Ethernet14/1'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf7b
+ hosts:
+ - destination: 10.255.255.104
+ repeat: 1
+ source: 10.255.255.105
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet1/1 (IP: 10.255.255.105) - Destination: pod1-spine1 Ethernet14/1 (IP: 10.255.255.104)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf7b
+ hosts:
+ - destination: 10.255.255.106
+ repeat: 1
+ source: 10.255.255.107
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet2/1 (IP: 10.255.255.107) - Destination: pod1-spine2 Ethernet14/1 (IP: 10.255.255.106)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf7b
+ hosts:
+ - destination: 10.255.255.108
+ repeat: 1
+ source: 10.255.255.109
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet3/1 (IP: 10.255.255.109) - Destination: pod1-spine3 Ethernet14/1 (IP: 10.255.255.108)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf7b
+ hosts:
+ - destination: 10.255.255.110
+ repeat: 1
+ source: 10.255.255.111
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet4/1 (IP: 10.255.255.111) - Destination: pod1-spine4 Ethernet14/1 (IP: 10.255.255.110)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf7b
+ hosts:
+ - destination: 10.255.0.1
+ repeat: 1
+ source: 10.255.1.18
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.18) - Destination: super-spine1 Loopback0 (IP: 10.255.0.1)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf7b
+ hosts:
+ - destination: 10.255.0.2
+ repeat: 1
+ source: 10.255.1.18
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.18) - Destination: super-spine2 Loopback0 (IP: 10.255.0.2)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf7b
+ hosts:
+ - destination: 10.255.1.1
+ repeat: 1
+ source: 10.255.1.18
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.18) - Destination: pod1-spine1 Loopback0 (IP: 10.255.1.1)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf7b
+ hosts:
+ - destination: 10.255.1.2
+ repeat: 1
+ source: 10.255.1.18
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.18) - Destination: pod1-spine2 Loopback0 (IP: 10.255.1.2)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf7b
+ hosts:
+ - destination: 10.255.1.3
+ repeat: 1
+ source: 10.255.1.18
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.18) - Destination: pod1-spine3 Loopback0 (IP: 10.255.1.3)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf7b
+ hosts:
+ - destination: 10.255.1.4
+ repeat: 1
+ source: 10.255.1.18
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.18) - Destination: pod1-spine4 Loopback0 (IP: 10.255.1.4)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf7b
+ hosts:
+ - destination: 10.255.1.5
+ repeat: 1
+ source: 10.255.1.18
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.18) - Destination: pod1-leaf1a Loopback0 (IP: 10.255.1.5)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf7b
+ hosts:
+ - destination: 10.255.1.6
+ repeat: 1
+ source: 10.255.1.18
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.18) - Destination: pod1-leaf1b Loopback0 (IP: 10.255.1.6)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf7b
+ hosts:
+ - destination: 10.255.1.7
+ repeat: 1
+ source: 10.255.1.18
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.18) - Destination: pod1-leaf2a Loopback0 (IP: 10.255.1.7)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf7b
+ hosts:
+ - destination: 10.255.1.8
+ repeat: 1
+ source: 10.255.1.18
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.18) - Destination: pod1-leaf2b Loopback0 (IP: 10.255.1.8)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf7b
+ hosts:
+ - destination: 10.255.1.9
+ repeat: 1
+ source: 10.255.1.18
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.18) - Destination: pod1-leaf3a Loopback0 (IP: 10.255.1.9)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf7b
+ hosts:
+ - destination: 10.255.1.10
+ repeat: 1
+ source: 10.255.1.18
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.18) - Destination: pod1-leaf3b Loopback0 (IP: 10.255.1.10)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf7b
+ hosts:
+ - destination: 10.255.1.11
+ repeat: 1
+ source: 10.255.1.18
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.18) - Destination: pod1-leaf4a Loopback0 (IP: 10.255.1.11)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf7b
+ hosts:
+ - destination: 10.255.1.12
+ repeat: 1
+ source: 10.255.1.18
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.18) - Destination: pod1-leaf4b Loopback0 (IP: 10.255.1.12)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf7b
+ hosts:
+ - destination: 10.255.1.13
+ repeat: 1
+ source: 10.255.1.18
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.18) - Destination: pod1-leaf5a Loopback0 (IP: 10.255.1.13)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf7b
+ hosts:
+ - destination: 10.255.1.14
+ repeat: 1
+ source: 10.255.1.18
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.18) - Destination: pod1-leaf5b Loopback0 (IP: 10.255.1.14)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf7b
+ hosts:
+ - destination: 10.255.1.15
+ repeat: 1
+ source: 10.255.1.18
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.18) - Destination: pod1-leaf6a Loopback0 (IP: 10.255.1.15)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf7b
+ hosts:
+ - destination: 10.255.1.16
+ repeat: 1
+ source: 10.255.1.18
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.18) - Destination: pod1-leaf6b Loopback0 (IP: 10.255.1.16)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf7b
+ hosts:
+ - destination: 10.255.1.17
+ repeat: 1
+ source: 10.255.1.18
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.18) - Destination: pod1-leaf7a Loopback0 (IP: 10.255.1.17)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf7b
+ hosts:
+ - destination: 10.255.1.18
+ repeat: 1
+ source: 10.255.1.18
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.18) - Destination: pod1-leaf7b Loopback0 (IP: 10.255.1.18)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf7b
+ hosts:
+ - destination: 10.255.1.19
+ repeat: 1
+ source: 10.255.1.18
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.18) - Destination: pod1-leaf8a Loopback0 (IP: 10.255.1.19)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf7b
+ hosts:
+ - destination: 10.255.1.20
+ repeat: 1
+ source: 10.255.1.18
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.18) - Destination: pod1-leaf8b Loopback0 (IP: 10.255.1.20)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf7b
+ hosts:
+ - destination: 10.255.1.21
+ repeat: 1
+ source: 10.255.1.18
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.18) - Destination: pod1-leaf9a Loopback0 (IP: 10.255.1.21)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf7b
+ hosts:
+ - destination: 10.255.1.22
+ repeat: 1
+ source: 10.255.1.18
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.18) - Destination: pod1-leaf9b Loopback0 (IP: 10.255.1.22)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf7b
+ hosts:
+ - destination: 10.255.1.23
+ repeat: 1
+ source: 10.255.1.18
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.18) - Destination: pod1-leaf10a Loopback0 (IP: 10.255.1.23)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf7b
+ hosts:
+ - destination: 10.255.1.24
+ repeat: 1
+ source: 10.255.1.18
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.18) - Destination: pod1-leaf10b Loopback0 (IP: 10.255.1.24)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf7b
+ hosts:
+ - destination: 10.255.2.1
+ repeat: 1
+ source: 10.255.1.18
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.18) - Destination: pod2-spine1 Loopback0 (IP: 10.255.2.1)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf7b
+ hosts:
+ - destination: 10.255.2.2
+ repeat: 1
+ source: 10.255.1.18
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.18) - Destination: pod2-spine2 Loopback0 (IP: 10.255.2.2)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf7b
+ hosts:
+ - destination: 10.255.2.3
+ repeat: 1
+ source: 10.255.1.18
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.18) - Destination: pod2-spine3 Loopback0 (IP: 10.255.2.3)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf7b
+ hosts:
+ - destination: 10.255.2.4
+ repeat: 1
+ source: 10.255.1.18
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.18) - Destination: pod2-spine4 Loopback0 (IP: 10.255.2.4)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf7b
+ hosts:
+ - destination: 10.255.2.5
+ repeat: 1
+ source: 10.255.1.18
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.18) - Destination: pod2-leaf1a Loopback0 (IP: 10.255.2.5)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf7b
+ hosts:
+ - destination: 10.255.2.6
+ repeat: 1
+ source: 10.255.1.18
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.18) - Destination: pod2-leaf1b Loopback0 (IP: 10.255.2.6)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf7b
+ hosts:
+ - destination: 10.255.2.7
+ repeat: 1
+ source: 10.255.1.18
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.18) - Destination: pod2-leaf2a Loopback0 (IP: 10.255.2.7)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf7b
+ hosts:
+ - destination: 10.255.2.8
+ repeat: 1
+ source: 10.255.1.18
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.18) - Destination: pod2-leaf2b Loopback0 (IP: 10.255.2.8)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf7b
+ hosts:
+ - destination: 10.255.2.9
+ repeat: 1
+ source: 10.255.1.18
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.18) - Destination: pod2-leaf3a Loopback0 (IP: 10.255.2.9)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf7b
+ hosts:
+ - destination: 10.255.2.10
+ repeat: 1
+ source: 10.255.1.18
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.18) - Destination: pod2-leaf3b Loopback0 (IP: 10.255.2.10)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf7b
+ hosts:
+ - destination: 10.255.2.11
+ repeat: 1
+ source: 10.255.1.18
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.18) - Destination: pod2-leaf4a Loopback0 (IP: 10.255.2.11)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf7b
+ hosts:
+ - destination: 10.255.2.12
+ repeat: 1
+ source: 10.255.1.18
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.18) - Destination: pod2-leaf4b Loopback0 (IP: 10.255.2.12)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf7b
+ hosts:
+ - destination: 10.255.2.13
+ repeat: 1
+ source: 10.255.1.18
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.18) - Destination: pod2-leaf5a Loopback0 (IP: 10.255.2.13)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf7b
+ hosts:
+ - destination: 10.255.2.14
+ repeat: 1
+ source: 10.255.1.18
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.18) - Destination: pod2-leaf5b Loopback0 (IP: 10.255.2.14)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf7b
+ hosts:
+ - destination: 10.255.2.15
+ repeat: 1
+ source: 10.255.1.18
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.18) - Destination: pod2-leaf6a Loopback0 (IP: 10.255.2.15)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf7b
+ hosts:
+ - destination: 10.255.2.16
+ repeat: 1
+ source: 10.255.1.18
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.18) - Destination: pod2-leaf6b Loopback0 (IP: 10.255.2.16)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf7b
+ hosts:
+ - destination: 10.255.2.17
+ repeat: 1
+ source: 10.255.1.18
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.18) - Destination: pod2-leaf7a Loopback0 (IP: 10.255.2.17)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf7b
+ hosts:
+ - destination: 10.255.2.18
+ repeat: 1
+ source: 10.255.1.18
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.18) - Destination: pod2-leaf7b Loopback0 (IP: 10.255.2.18)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf7b
+ hosts:
+ - destination: 10.255.2.19
+ repeat: 1
+ source: 10.255.1.18
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.18) - Destination: pod2-leaf8a Loopback0 (IP: 10.255.2.19)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf7b
+ hosts:
+ - destination: 10.255.2.20
+ repeat: 1
+ source: 10.255.1.18
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.18) - Destination: pod2-leaf8b Loopback0 (IP: 10.255.2.20)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf7b
+ hosts:
+ - destination: 10.255.2.21
+ repeat: 1
+ source: 10.255.1.18
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.18) - Destination: pod2-leaf9a Loopback0 (IP: 10.255.2.21)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf7b
+ hosts:
+ - destination: 10.255.2.22
+ repeat: 1
+ source: 10.255.1.18
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.18) - Destination: pod2-leaf9b Loopback0 (IP: 10.255.2.22)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf7b
+ hosts:
+ - destination: 10.255.2.23
+ repeat: 1
+ source: 10.255.1.18
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.18) - Destination: pod2-leaf10a Loopback0 (IP: 10.255.2.23)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf7b
+ hosts:
+ - destination: 10.255.2.24
+ repeat: 1
+ source: 10.255.1.18
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.18) - Destination: pod2-leaf10b Loopback0 (IP: 10.255.2.24)'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-leaf10a
+ neighbors:
+ - neighbor_device: pod1-leaf10b
+ neighbor_port: Ethernet53/1
+ port: Ethernet53/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet53/1 - Remote: pod1-leaf10b Ethernet53/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-leaf10a
+ neighbors:
+ - neighbor_device: pod1-leaf10b
+ neighbor_port: Ethernet54/1
+ port: Ethernet54/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet54/1 - Remote: pod1-leaf10b Ethernet54/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-leaf10a
+ neighbors:
+ - neighbor_device: pod1-spine1
+ neighbor_port: Ethernet19/1
+ port: Ethernet1/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet1/1 - Remote: pod1-spine1 Ethernet19/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-leaf10a
+ neighbors:
+ - neighbor_device: pod1-spine2
+ neighbor_port: Ethernet19/1
+ port: Ethernet2/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet2/1 - Remote: pod1-spine2 Ethernet19/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-leaf10a
+ neighbors:
+ - neighbor_device: pod1-spine3
+ neighbor_port: Ethernet19/1
+ port: Ethernet3/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet3/1 - Remote: pod1-spine3 Ethernet19/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-leaf10a
+ neighbors:
+ - neighbor_device: pod1-spine4
+ neighbor_port: Ethernet19/1
+ port: Ethernet4/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet4/1 - Remote: pod1-spine4 Ethernet19/1'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf10a
+ hosts:
+ - destination: 10.255.255.144
+ repeat: 1
+ source: 10.255.255.145
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet1/1 (IP: 10.255.255.145) - Destination: pod1-spine1 Ethernet19/1 (IP: 10.255.255.144)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf10a
+ hosts:
+ - destination: 10.255.255.146
+ repeat: 1
+ source: 10.255.255.147
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet2/1 (IP: 10.255.255.147) - Destination: pod1-spine2 Ethernet19/1 (IP: 10.255.255.146)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf10a
+ hosts:
+ - destination: 10.255.255.148
+ repeat: 1
+ source: 10.255.255.149
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet3/1 (IP: 10.255.255.149) - Destination: pod1-spine3 Ethernet19/1 (IP: 10.255.255.148)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf10a
+ hosts:
+ - destination: 10.255.255.150
+ repeat: 1
+ source: 10.255.255.151
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet4/1 (IP: 10.255.255.151) - Destination: pod1-spine4 Ethernet19/1 (IP: 10.255.255.150)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf10a
+ hosts:
+ - destination: 10.255.0.1
+ repeat: 1
+ source: 10.255.1.23
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.23) - Destination: super-spine1 Loopback0 (IP: 10.255.0.1)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf10a
+ hosts:
+ - destination: 10.255.0.2
+ repeat: 1
+ source: 10.255.1.23
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.23) - Destination: super-spine2 Loopback0 (IP: 10.255.0.2)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf10a
+ hosts:
+ - destination: 10.255.1.1
+ repeat: 1
+ source: 10.255.1.23
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.23) - Destination: pod1-spine1 Loopback0 (IP: 10.255.1.1)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf10a
+ hosts:
+ - destination: 10.255.1.2
+ repeat: 1
+ source: 10.255.1.23
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.23) - Destination: pod1-spine2 Loopback0 (IP: 10.255.1.2)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf10a
+ hosts:
+ - destination: 10.255.1.3
+ repeat: 1
+ source: 10.255.1.23
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.23) - Destination: pod1-spine3 Loopback0 (IP: 10.255.1.3)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf10a
+ hosts:
+ - destination: 10.255.1.4
+ repeat: 1
+ source: 10.255.1.23
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.23) - Destination: pod1-spine4 Loopback0 (IP: 10.255.1.4)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf10a
+ hosts:
+ - destination: 10.255.1.5
+ repeat: 1
+ source: 10.255.1.23
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.23) - Destination: pod1-leaf1a Loopback0 (IP: 10.255.1.5)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf10a
+ hosts:
+ - destination: 10.255.1.6
+ repeat: 1
+ source: 10.255.1.23
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.23) - Destination: pod1-leaf1b Loopback0 (IP: 10.255.1.6)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf10a
+ hosts:
+ - destination: 10.255.1.7
+ repeat: 1
+ source: 10.255.1.23
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.23) - Destination: pod1-leaf2a Loopback0 (IP: 10.255.1.7)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf10a
+ hosts:
+ - destination: 10.255.1.8
+ repeat: 1
+ source: 10.255.1.23
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.23) - Destination: pod1-leaf2b Loopback0 (IP: 10.255.1.8)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf10a
+ hosts:
+ - destination: 10.255.1.9
+ repeat: 1
+ source: 10.255.1.23
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.23) - Destination: pod1-leaf3a Loopback0 (IP: 10.255.1.9)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf10a
+ hosts:
+ - destination: 10.255.1.10
+ repeat: 1
+ source: 10.255.1.23
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.23) - Destination: pod1-leaf3b Loopback0 (IP: 10.255.1.10)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf10a
+ hosts:
+ - destination: 10.255.1.11
+ repeat: 1
+ source: 10.255.1.23
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.23) - Destination: pod1-leaf4a Loopback0 (IP: 10.255.1.11)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf10a
+ hosts:
+ - destination: 10.255.1.12
+ repeat: 1
+ source: 10.255.1.23
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.23) - Destination: pod1-leaf4b Loopback0 (IP: 10.255.1.12)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf10a
+ hosts:
+ - destination: 10.255.1.13
+ repeat: 1
+ source: 10.255.1.23
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.23) - Destination: pod1-leaf5a Loopback0 (IP: 10.255.1.13)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf10a
+ hosts:
+ - destination: 10.255.1.14
+ repeat: 1
+ source: 10.255.1.23
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.23) - Destination: pod1-leaf5b Loopback0 (IP: 10.255.1.14)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf10a
+ hosts:
+ - destination: 10.255.1.15
+ repeat: 1
+ source: 10.255.1.23
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.23) - Destination: pod1-leaf6a Loopback0 (IP: 10.255.1.15)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf10a
+ hosts:
+ - destination: 10.255.1.16
+ repeat: 1
+ source: 10.255.1.23
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.23) - Destination: pod1-leaf6b Loopback0 (IP: 10.255.1.16)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf10a
+ hosts:
+ - destination: 10.255.1.17
+ repeat: 1
+ source: 10.255.1.23
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.23) - Destination: pod1-leaf7a Loopback0 (IP: 10.255.1.17)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf10a
+ hosts:
+ - destination: 10.255.1.18
+ repeat: 1
+ source: 10.255.1.23
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.23) - Destination: pod1-leaf7b Loopback0 (IP: 10.255.1.18)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf10a
+ hosts:
+ - destination: 10.255.1.19
+ repeat: 1
+ source: 10.255.1.23
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.23) - Destination: pod1-leaf8a Loopback0 (IP: 10.255.1.19)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf10a
+ hosts:
+ - destination: 10.255.1.20
+ repeat: 1
+ source: 10.255.1.23
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.23) - Destination: pod1-leaf8b Loopback0 (IP: 10.255.1.20)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf10a
+ hosts:
+ - destination: 10.255.1.21
+ repeat: 1
+ source: 10.255.1.23
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.23) - Destination: pod1-leaf9a Loopback0 (IP: 10.255.1.21)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf10a
+ hosts:
+ - destination: 10.255.1.22
+ repeat: 1
+ source: 10.255.1.23
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.23) - Destination: pod1-leaf9b Loopback0 (IP: 10.255.1.22)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf10a
+ hosts:
+ - destination: 10.255.1.23
+ repeat: 1
+ source: 10.255.1.23
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.23) - Destination: pod1-leaf10a Loopback0 (IP: 10.255.1.23)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf10a
+ hosts:
+ - destination: 10.255.1.24
+ repeat: 1
+ source: 10.255.1.23
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.23) - Destination: pod1-leaf10b Loopback0 (IP: 10.255.1.24)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf10a
+ hosts:
+ - destination: 10.255.2.1
+ repeat: 1
+ source: 10.255.1.23
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.23) - Destination: pod2-spine1 Loopback0 (IP: 10.255.2.1)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf10a
+ hosts:
+ - destination: 10.255.2.2
+ repeat: 1
+ source: 10.255.1.23
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.23) - Destination: pod2-spine2 Loopback0 (IP: 10.255.2.2)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf10a
+ hosts:
+ - destination: 10.255.2.3
+ repeat: 1
+ source: 10.255.1.23
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.23) - Destination: pod2-spine3 Loopback0 (IP: 10.255.2.3)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf10a
+ hosts:
+ - destination: 10.255.2.4
+ repeat: 1
+ source: 10.255.1.23
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.23) - Destination: pod2-spine4 Loopback0 (IP: 10.255.2.4)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf10a
+ hosts:
+ - destination: 10.255.2.5
+ repeat: 1
+ source: 10.255.1.23
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.23) - Destination: pod2-leaf1a Loopback0 (IP: 10.255.2.5)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf10a
+ hosts:
+ - destination: 10.255.2.6
+ repeat: 1
+ source: 10.255.1.23
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.23) - Destination: pod2-leaf1b Loopback0 (IP: 10.255.2.6)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf10a
+ hosts:
+ - destination: 10.255.2.7
+ repeat: 1
+ source: 10.255.1.23
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.23) - Destination: pod2-leaf2a Loopback0 (IP: 10.255.2.7)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf10a
+ hosts:
+ - destination: 10.255.2.8
+ repeat: 1
+ source: 10.255.1.23
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.23) - Destination: pod2-leaf2b Loopback0 (IP: 10.255.2.8)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf10a
+ hosts:
+ - destination: 10.255.2.9
+ repeat: 1
+ source: 10.255.1.23
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.23) - Destination: pod2-leaf3a Loopback0 (IP: 10.255.2.9)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf10a
+ hosts:
+ - destination: 10.255.2.10
+ repeat: 1
+ source: 10.255.1.23
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.23) - Destination: pod2-leaf3b Loopback0 (IP: 10.255.2.10)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf10a
+ hosts:
+ - destination: 10.255.2.11
+ repeat: 1
+ source: 10.255.1.23
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.23) - Destination: pod2-leaf4a Loopback0 (IP: 10.255.2.11)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf10a
+ hosts:
+ - destination: 10.255.2.12
+ repeat: 1
+ source: 10.255.1.23
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.23) - Destination: pod2-leaf4b Loopback0 (IP: 10.255.2.12)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf10a
+ hosts:
+ - destination: 10.255.2.13
+ repeat: 1
+ source: 10.255.1.23
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.23) - Destination: pod2-leaf5a Loopback0 (IP: 10.255.2.13)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf10a
+ hosts:
+ - destination: 10.255.2.14
+ repeat: 1
+ source: 10.255.1.23
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.23) - Destination: pod2-leaf5b Loopback0 (IP: 10.255.2.14)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf10a
+ hosts:
+ - destination: 10.255.2.15
+ repeat: 1
+ source: 10.255.1.23
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.23) - Destination: pod2-leaf6a Loopback0 (IP: 10.255.2.15)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf10a
+ hosts:
+ - destination: 10.255.2.16
+ repeat: 1
+ source: 10.255.1.23
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.23) - Destination: pod2-leaf6b Loopback0 (IP: 10.255.2.16)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf10a
+ hosts:
+ - destination: 10.255.2.17
+ repeat: 1
+ source: 10.255.1.23
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.23) - Destination: pod2-leaf7a Loopback0 (IP: 10.255.2.17)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf10a
+ hosts:
+ - destination: 10.255.2.18
+ repeat: 1
+ source: 10.255.1.23
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.23) - Destination: pod2-leaf7b Loopback0 (IP: 10.255.2.18)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf10a
+ hosts:
+ - destination: 10.255.2.19
+ repeat: 1
+ source: 10.255.1.23
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.23) - Destination: pod2-leaf8a Loopback0 (IP: 10.255.2.19)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf10a
+ hosts:
+ - destination: 10.255.2.20
+ repeat: 1
+ source: 10.255.1.23
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.23) - Destination: pod2-leaf8b Loopback0 (IP: 10.255.2.20)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf10a
+ hosts:
+ - destination: 10.255.2.21
+ repeat: 1
+ source: 10.255.1.23
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.23) - Destination: pod2-leaf9a Loopback0 (IP: 10.255.2.21)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf10a
+ hosts:
+ - destination: 10.255.2.22
+ repeat: 1
+ source: 10.255.1.23
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.23) - Destination: pod2-leaf9b Loopback0 (IP: 10.255.2.22)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf10a
+ hosts:
+ - destination: 10.255.2.23
+ repeat: 1
+ source: 10.255.1.23
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.23) - Destination: pod2-leaf10a Loopback0 (IP: 10.255.2.23)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf10a
+ hosts:
+ - destination: 10.255.2.24
+ repeat: 1
+ source: 10.255.1.23
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.23) - Destination: pod2-leaf10b Loopback0 (IP: 10.255.2.24)'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-leaf6b
+ neighbors:
+ - neighbor_device: pod2-leaf6a
+ neighbor_port: Ethernet53/1
+ port: Ethernet53/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet53/1 - Remote: pod2-leaf6a Ethernet53/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-leaf6b
+ neighbors:
+ - neighbor_device: pod2-leaf6a
+ neighbor_port: Ethernet54/1
+ port: Ethernet54/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet54/1 - Remote: pod2-leaf6a Ethernet54/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-leaf6b
+ neighbors:
+ - neighbor_device: pod2-spine1
+ neighbor_port: Ethernet12/1
+ port: Ethernet1/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet1/1 - Remote: pod2-spine1 Ethernet12/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-leaf6b
+ neighbors:
+ - neighbor_device: pod2-spine2
+ neighbor_port: Ethernet12/1
+ port: Ethernet2/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet2/1 - Remote: pod2-spine2 Ethernet12/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-leaf6b
+ neighbors:
+ - neighbor_device: pod2-spine3
+ neighbor_port: Ethernet12/1
+ port: Ethernet3/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet3/1 - Remote: pod2-spine3 Ethernet12/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-leaf6b
+ neighbors:
+ - neighbor_device: pod2-spine4
+ neighbor_port: Ethernet12/1
+ port: Ethernet4/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet4/1 - Remote: pod2-spine4 Ethernet12/1'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf6b
+ hosts:
+ - destination: 10.255.255.88
+ repeat: 1
+ source: 10.255.255.89
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet1/1 (IP: 10.255.255.89) - Destination: pod2-spine1 Ethernet12/1 (IP: 10.255.255.88)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf6b
+ hosts:
+ - destination: 10.255.255.90
+ repeat: 1
+ source: 10.255.255.91
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet2/1 (IP: 10.255.255.91) - Destination: pod2-spine2 Ethernet12/1 (IP: 10.255.255.90)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf6b
+ hosts:
+ - destination: 10.255.255.92
+ repeat: 1
+ source: 10.255.255.93
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet3/1 (IP: 10.255.255.93) - Destination: pod2-spine3 Ethernet12/1 (IP: 10.255.255.92)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf6b
+ hosts:
+ - destination: 10.255.255.94
+ repeat: 1
+ source: 10.255.255.95
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet4/1 (IP: 10.255.255.95) - Destination: pod2-spine4 Ethernet12/1 (IP: 10.255.255.94)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf6b
+ hosts:
+ - destination: 10.255.0.1
+ repeat: 1
+ source: 10.255.2.16
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.16) - Destination: super-spine1 Loopback0 (IP: 10.255.0.1)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf6b
+ hosts:
+ - destination: 10.255.0.2
+ repeat: 1
+ source: 10.255.2.16
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.16) - Destination: super-spine2 Loopback0 (IP: 10.255.0.2)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf6b
+ hosts:
+ - destination: 10.255.1.1
+ repeat: 1
+ source: 10.255.2.16
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.16) - Destination: pod1-spine1 Loopback0 (IP: 10.255.1.1)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf6b
+ hosts:
+ - destination: 10.255.1.2
+ repeat: 1
+ source: 10.255.2.16
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.16) - Destination: pod1-spine2 Loopback0 (IP: 10.255.1.2)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf6b
+ hosts:
+ - destination: 10.255.1.3
+ repeat: 1
+ source: 10.255.2.16
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.16) - Destination: pod1-spine3 Loopback0 (IP: 10.255.1.3)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf6b
+ hosts:
+ - destination: 10.255.1.4
+ repeat: 1
+ source: 10.255.2.16
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.16) - Destination: pod1-spine4 Loopback0 (IP: 10.255.1.4)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf6b
+ hosts:
+ - destination: 10.255.1.5
+ repeat: 1
+ source: 10.255.2.16
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.16) - Destination: pod1-leaf1a Loopback0 (IP: 10.255.1.5)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf6b
+ hosts:
+ - destination: 10.255.1.6
+ repeat: 1
+ source: 10.255.2.16
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.16) - Destination: pod1-leaf1b Loopback0 (IP: 10.255.1.6)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf6b
+ hosts:
+ - destination: 10.255.1.7
+ repeat: 1
+ source: 10.255.2.16
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.16) - Destination: pod1-leaf2a Loopback0 (IP: 10.255.1.7)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf6b
+ hosts:
+ - destination: 10.255.1.8
+ repeat: 1
+ source: 10.255.2.16
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.16) - Destination: pod1-leaf2b Loopback0 (IP: 10.255.1.8)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf6b
+ hosts:
+ - destination: 10.255.1.9
+ repeat: 1
+ source: 10.255.2.16
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.16) - Destination: pod1-leaf3a Loopback0 (IP: 10.255.1.9)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf6b
+ hosts:
+ - destination: 10.255.1.10
+ repeat: 1
+ source: 10.255.2.16
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.16) - Destination: pod1-leaf3b Loopback0 (IP: 10.255.1.10)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf6b
+ hosts:
+ - destination: 10.255.1.11
+ repeat: 1
+ source: 10.255.2.16
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.16) - Destination: pod1-leaf4a Loopback0 (IP: 10.255.1.11)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf6b
+ hosts:
+ - destination: 10.255.1.12
+ repeat: 1
+ source: 10.255.2.16
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.16) - Destination: pod1-leaf4b Loopback0 (IP: 10.255.1.12)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf6b
+ hosts:
+ - destination: 10.255.1.13
+ repeat: 1
+ source: 10.255.2.16
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.16) - Destination: pod1-leaf5a Loopback0 (IP: 10.255.1.13)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf6b
+ hosts:
+ - destination: 10.255.1.14
+ repeat: 1
+ source: 10.255.2.16
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.16) - Destination: pod1-leaf5b Loopback0 (IP: 10.255.1.14)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf6b
+ hosts:
+ - destination: 10.255.1.15
+ repeat: 1
+ source: 10.255.2.16
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.16) - Destination: pod1-leaf6a Loopback0 (IP: 10.255.1.15)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf6b
+ hosts:
+ - destination: 10.255.1.16
+ repeat: 1
+ source: 10.255.2.16
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.16) - Destination: pod1-leaf6b Loopback0 (IP: 10.255.1.16)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf6b
+ hosts:
+ - destination: 10.255.1.17
+ repeat: 1
+ source: 10.255.2.16
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.16) - Destination: pod1-leaf7a Loopback0 (IP: 10.255.1.17)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf6b
+ hosts:
+ - destination: 10.255.1.18
+ repeat: 1
+ source: 10.255.2.16
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.16) - Destination: pod1-leaf7b Loopback0 (IP: 10.255.1.18)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf6b
+ hosts:
+ - destination: 10.255.1.19
+ repeat: 1
+ source: 10.255.2.16
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.16) - Destination: pod1-leaf8a Loopback0 (IP: 10.255.1.19)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf6b
+ hosts:
+ - destination: 10.255.1.20
+ repeat: 1
+ source: 10.255.2.16
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.16) - Destination: pod1-leaf8b Loopback0 (IP: 10.255.1.20)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf6b
+ hosts:
+ - destination: 10.255.1.21
+ repeat: 1
+ source: 10.255.2.16
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.16) - Destination: pod1-leaf9a Loopback0 (IP: 10.255.1.21)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf6b
+ hosts:
+ - destination: 10.255.1.22
+ repeat: 1
+ source: 10.255.2.16
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.16) - Destination: pod1-leaf9b Loopback0 (IP: 10.255.1.22)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf6b
+ hosts:
+ - destination: 10.255.1.23
+ repeat: 1
+ source: 10.255.2.16
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.16) - Destination: pod1-leaf10a Loopback0 (IP: 10.255.1.23)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf6b
+ hosts:
+ - destination: 10.255.1.24
+ repeat: 1
+ source: 10.255.2.16
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.16) - Destination: pod1-leaf10b Loopback0 (IP: 10.255.1.24)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf6b
+ hosts:
+ - destination: 10.255.2.1
+ repeat: 1
+ source: 10.255.2.16
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.16) - Destination: pod2-spine1 Loopback0 (IP: 10.255.2.1)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf6b
+ hosts:
+ - destination: 10.255.2.2
+ repeat: 1
+ source: 10.255.2.16
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.16) - Destination: pod2-spine2 Loopback0 (IP: 10.255.2.2)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf6b
+ hosts:
+ - destination: 10.255.2.3
+ repeat: 1
+ source: 10.255.2.16
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.16) - Destination: pod2-spine3 Loopback0 (IP: 10.255.2.3)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf6b
+ hosts:
+ - destination: 10.255.2.4
+ repeat: 1
+ source: 10.255.2.16
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.16) - Destination: pod2-spine4 Loopback0 (IP: 10.255.2.4)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf6b
+ hosts:
+ - destination: 10.255.2.5
+ repeat: 1
+ source: 10.255.2.16
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.16) - Destination: pod2-leaf1a Loopback0 (IP: 10.255.2.5)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf6b
+ hosts:
+ - destination: 10.255.2.6
+ repeat: 1
+ source: 10.255.2.16
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.16) - Destination: pod2-leaf1b Loopback0 (IP: 10.255.2.6)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf6b
+ hosts:
+ - destination: 10.255.2.7
+ repeat: 1
+ source: 10.255.2.16
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.16) - Destination: pod2-leaf2a Loopback0 (IP: 10.255.2.7)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf6b
+ hosts:
+ - destination: 10.255.2.8
+ repeat: 1
+ source: 10.255.2.16
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.16) - Destination: pod2-leaf2b Loopback0 (IP: 10.255.2.8)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf6b
+ hosts:
+ - destination: 10.255.2.9
+ repeat: 1
+ source: 10.255.2.16
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.16) - Destination: pod2-leaf3a Loopback0 (IP: 10.255.2.9)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf6b
+ hosts:
+ - destination: 10.255.2.10
+ repeat: 1
+ source: 10.255.2.16
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.16) - Destination: pod2-leaf3b Loopback0 (IP: 10.255.2.10)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf6b
+ hosts:
+ - destination: 10.255.2.11
+ repeat: 1
+ source: 10.255.2.16
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.16) - Destination: pod2-leaf4a Loopback0 (IP: 10.255.2.11)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf6b
+ hosts:
+ - destination: 10.255.2.12
+ repeat: 1
+ source: 10.255.2.16
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.16) - Destination: pod2-leaf4b Loopback0 (IP: 10.255.2.12)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf6b
+ hosts:
+ - destination: 10.255.2.13
+ repeat: 1
+ source: 10.255.2.16
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.16) - Destination: pod2-leaf5a Loopback0 (IP: 10.255.2.13)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf6b
+ hosts:
+ - destination: 10.255.2.14
+ repeat: 1
+ source: 10.255.2.16
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.16) - Destination: pod2-leaf5b Loopback0 (IP: 10.255.2.14)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf6b
+ hosts:
+ - destination: 10.255.2.15
+ repeat: 1
+ source: 10.255.2.16
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.16) - Destination: pod2-leaf6a Loopback0 (IP: 10.255.2.15)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf6b
+ hosts:
+ - destination: 10.255.2.16
+ repeat: 1
+ source: 10.255.2.16
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.16) - Destination: pod2-leaf6b Loopback0 (IP: 10.255.2.16)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf6b
+ hosts:
+ - destination: 10.255.2.17
+ repeat: 1
+ source: 10.255.2.16
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.16) - Destination: pod2-leaf7a Loopback0 (IP: 10.255.2.17)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf6b
+ hosts:
+ - destination: 10.255.2.18
+ repeat: 1
+ source: 10.255.2.16
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.16) - Destination: pod2-leaf7b Loopback0 (IP: 10.255.2.18)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf6b
+ hosts:
+ - destination: 10.255.2.19
+ repeat: 1
+ source: 10.255.2.16
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.16) - Destination: pod2-leaf8a Loopback0 (IP: 10.255.2.19)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf6b
+ hosts:
+ - destination: 10.255.2.20
+ repeat: 1
+ source: 10.255.2.16
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.16) - Destination: pod2-leaf8b Loopback0 (IP: 10.255.2.20)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf6b
+ hosts:
+ - destination: 10.255.2.21
+ repeat: 1
+ source: 10.255.2.16
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.16) - Destination: pod2-leaf9a Loopback0 (IP: 10.255.2.21)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf6b
+ hosts:
+ - destination: 10.255.2.22
+ repeat: 1
+ source: 10.255.2.16
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.16) - Destination: pod2-leaf9b Loopback0 (IP: 10.255.2.22)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf6b
+ hosts:
+ - destination: 10.255.2.23
+ repeat: 1
+ source: 10.255.2.16
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.16) - Destination: pod2-leaf10a Loopback0 (IP: 10.255.2.23)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf6b
+ hosts:
+ - destination: 10.255.2.24
+ repeat: 1
+ source: 10.255.2.16
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.16) - Destination: pod2-leaf10b Loopback0 (IP: 10.255.2.24)'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-leaf1b
+ neighbors:
+ - neighbor_device: pod2-leaf1a
+ neighbor_port: Ethernet53/1
+ port: Ethernet53/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet53/1 - Remote: pod2-leaf1a Ethernet53/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-leaf1b
+ neighbors:
+ - neighbor_device: pod2-leaf1a
+ neighbor_port: Ethernet54/1
+ port: Ethernet54/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet54/1 - Remote: pod2-leaf1a Ethernet54/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-leaf1b
+ neighbors:
+ - neighbor_device: pod2-spine1
+ neighbor_port: Ethernet2/1
+ port: Ethernet1/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet1/1 - Remote: pod2-spine1 Ethernet2/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-leaf1b
+ neighbors:
+ - neighbor_device: pod2-spine2
+ neighbor_port: Ethernet2/1
+ port: Ethernet2/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet2/1 - Remote: pod2-spine2 Ethernet2/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-leaf1b
+ neighbors:
+ - neighbor_device: pod2-spine3
+ neighbor_port: Ethernet2/1
+ port: Ethernet3/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet3/1 - Remote: pod2-spine3 Ethernet2/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-leaf1b
+ neighbors:
+ - neighbor_device: pod2-spine4
+ neighbor_port: Ethernet2/1
+ port: Ethernet4/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet4/1 - Remote: pod2-spine4 Ethernet2/1'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf1b
+ hosts:
+ - destination: 10.255.255.8
+ repeat: 1
+ source: 10.255.255.9
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet1/1 (IP: 10.255.255.9) - Destination: pod2-spine1 Ethernet2/1 (IP: 10.255.255.8)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf1b
+ hosts:
+ - destination: 10.255.255.10
+ repeat: 1
+ source: 10.255.255.11
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet2/1 (IP: 10.255.255.11) - Destination: pod2-spine2 Ethernet2/1 (IP: 10.255.255.10)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf1b
+ hosts:
+ - destination: 10.255.255.12
+ repeat: 1
+ source: 10.255.255.13
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet3/1 (IP: 10.255.255.13) - Destination: pod2-spine3 Ethernet2/1 (IP: 10.255.255.12)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf1b
+ hosts:
+ - destination: 10.255.255.14
+ repeat: 1
+ source: 10.255.255.15
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet4/1 (IP: 10.255.255.15) - Destination: pod2-spine4 Ethernet2/1 (IP: 10.255.255.14)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf1b
+ hosts:
+ - destination: 10.255.0.1
+ repeat: 1
+ source: 10.255.2.6
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.6) - Destination: super-spine1 Loopback0 (IP: 10.255.0.1)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf1b
+ hosts:
+ - destination: 10.255.0.2
+ repeat: 1
+ source: 10.255.2.6
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.6) - Destination: super-spine2 Loopback0 (IP: 10.255.0.2)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf1b
+ hosts:
+ - destination: 10.255.1.1
+ repeat: 1
+ source: 10.255.2.6
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.6) - Destination: pod1-spine1 Loopback0 (IP: 10.255.1.1)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf1b
+ hosts:
+ - destination: 10.255.1.2
+ repeat: 1
+ source: 10.255.2.6
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.6) - Destination: pod1-spine2 Loopback0 (IP: 10.255.1.2)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf1b
+ hosts:
+ - destination: 10.255.1.3
+ repeat: 1
+ source: 10.255.2.6
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.6) - Destination: pod1-spine3 Loopback0 (IP: 10.255.1.3)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf1b
+ hosts:
+ - destination: 10.255.1.4
+ repeat: 1
+ source: 10.255.2.6
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.6) - Destination: pod1-spine4 Loopback0 (IP: 10.255.1.4)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf1b
+ hosts:
+ - destination: 10.255.1.5
+ repeat: 1
+ source: 10.255.2.6
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.6) - Destination: pod1-leaf1a Loopback0 (IP: 10.255.1.5)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf1b
+ hosts:
+ - destination: 10.255.1.6
+ repeat: 1
+ source: 10.255.2.6
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.6) - Destination: pod1-leaf1b Loopback0 (IP: 10.255.1.6)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf1b
+ hosts:
+ - destination: 10.255.1.7
+ repeat: 1
+ source: 10.255.2.6
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.6) - Destination: pod1-leaf2a Loopback0 (IP: 10.255.1.7)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf1b
+ hosts:
+ - destination: 10.255.1.8
+ repeat: 1
+ source: 10.255.2.6
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.6) - Destination: pod1-leaf2b Loopback0 (IP: 10.255.1.8)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf1b
+ hosts:
+ - destination: 10.255.1.9
+ repeat: 1
+ source: 10.255.2.6
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.6) - Destination: pod1-leaf3a Loopback0 (IP: 10.255.1.9)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf1b
+ hosts:
+ - destination: 10.255.1.10
+ repeat: 1
+ source: 10.255.2.6
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.6) - Destination: pod1-leaf3b Loopback0 (IP: 10.255.1.10)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf1b
+ hosts:
+ - destination: 10.255.1.11
+ repeat: 1
+ source: 10.255.2.6
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.6) - Destination: pod1-leaf4a Loopback0 (IP: 10.255.1.11)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf1b
+ hosts:
+ - destination: 10.255.1.12
+ repeat: 1
+ source: 10.255.2.6
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.6) - Destination: pod1-leaf4b Loopback0 (IP: 10.255.1.12)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf1b
+ hosts:
+ - destination: 10.255.1.13
+ repeat: 1
+ source: 10.255.2.6
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.6) - Destination: pod1-leaf5a Loopback0 (IP: 10.255.1.13)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf1b
+ hosts:
+ - destination: 10.255.1.14
+ repeat: 1
+ source: 10.255.2.6
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.6) - Destination: pod1-leaf5b Loopback0 (IP: 10.255.1.14)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf1b
+ hosts:
+ - destination: 10.255.1.15
+ repeat: 1
+ source: 10.255.2.6
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.6) - Destination: pod1-leaf6a Loopback0 (IP: 10.255.1.15)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf1b
+ hosts:
+ - destination: 10.255.1.16
+ repeat: 1
+ source: 10.255.2.6
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.6) - Destination: pod1-leaf6b Loopback0 (IP: 10.255.1.16)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf1b
+ hosts:
+ - destination: 10.255.1.17
+ repeat: 1
+ source: 10.255.2.6
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.6) - Destination: pod1-leaf7a Loopback0 (IP: 10.255.1.17)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf1b
+ hosts:
+ - destination: 10.255.1.18
+ repeat: 1
+ source: 10.255.2.6
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.6) - Destination: pod1-leaf7b Loopback0 (IP: 10.255.1.18)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf1b
+ hosts:
+ - destination: 10.255.1.19
+ repeat: 1
+ source: 10.255.2.6
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.6) - Destination: pod1-leaf8a Loopback0 (IP: 10.255.1.19)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf1b
+ hosts:
+ - destination: 10.255.1.20
+ repeat: 1
+ source: 10.255.2.6
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.6) - Destination: pod1-leaf8b Loopback0 (IP: 10.255.1.20)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf1b
+ hosts:
+ - destination: 10.255.1.21
+ repeat: 1
+ source: 10.255.2.6
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.6) - Destination: pod1-leaf9a Loopback0 (IP: 10.255.1.21)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf1b
+ hosts:
+ - destination: 10.255.1.22
+ repeat: 1
+ source: 10.255.2.6
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.6) - Destination: pod1-leaf9b Loopback0 (IP: 10.255.1.22)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf1b
+ hosts:
+ - destination: 10.255.1.23
+ repeat: 1
+ source: 10.255.2.6
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.6) - Destination: pod1-leaf10a Loopback0 (IP: 10.255.1.23)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf1b
+ hosts:
+ - destination: 10.255.1.24
+ repeat: 1
+ source: 10.255.2.6
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.6) - Destination: pod1-leaf10b Loopback0 (IP: 10.255.1.24)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf1b
+ hosts:
+ - destination: 10.255.2.1
+ repeat: 1
+ source: 10.255.2.6
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.6) - Destination: pod2-spine1 Loopback0 (IP: 10.255.2.1)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf1b
+ hosts:
+ - destination: 10.255.2.2
+ repeat: 1
+ source: 10.255.2.6
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.6) - Destination: pod2-spine2 Loopback0 (IP: 10.255.2.2)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf1b
+ hosts:
+ - destination: 10.255.2.3
+ repeat: 1
+ source: 10.255.2.6
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.6) - Destination: pod2-spine3 Loopback0 (IP: 10.255.2.3)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf1b
+ hosts:
+ - destination: 10.255.2.4
+ repeat: 1
+ source: 10.255.2.6
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.6) - Destination: pod2-spine4 Loopback0 (IP: 10.255.2.4)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf1b
+ hosts:
+ - destination: 10.255.2.5
+ repeat: 1
+ source: 10.255.2.6
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.6) - Destination: pod2-leaf1a Loopback0 (IP: 10.255.2.5)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf1b
+ hosts:
+ - destination: 10.255.2.6
+ repeat: 1
+ source: 10.255.2.6
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.6) - Destination: pod2-leaf1b Loopback0 (IP: 10.255.2.6)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf1b
+ hosts:
+ - destination: 10.255.2.7
+ repeat: 1
+ source: 10.255.2.6
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.6) - Destination: pod2-leaf2a Loopback0 (IP: 10.255.2.7)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf1b
+ hosts:
+ - destination: 10.255.2.8
+ repeat: 1
+ source: 10.255.2.6
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.6) - Destination: pod2-leaf2b Loopback0 (IP: 10.255.2.8)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf1b
+ hosts:
+ - destination: 10.255.2.9
+ repeat: 1
+ source: 10.255.2.6
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.6) - Destination: pod2-leaf3a Loopback0 (IP: 10.255.2.9)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf1b
+ hosts:
+ - destination: 10.255.2.10
+ repeat: 1
+ source: 10.255.2.6
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.6) - Destination: pod2-leaf3b Loopback0 (IP: 10.255.2.10)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf1b
+ hosts:
+ - destination: 10.255.2.11
+ repeat: 1
+ source: 10.255.2.6
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.6) - Destination: pod2-leaf4a Loopback0 (IP: 10.255.2.11)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf1b
+ hosts:
+ - destination: 10.255.2.12
+ repeat: 1
+ source: 10.255.2.6
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.6) - Destination: pod2-leaf4b Loopback0 (IP: 10.255.2.12)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf1b
+ hosts:
+ - destination: 10.255.2.13
+ repeat: 1
+ source: 10.255.2.6
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.6) - Destination: pod2-leaf5a Loopback0 (IP: 10.255.2.13)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf1b
+ hosts:
+ - destination: 10.255.2.14
+ repeat: 1
+ source: 10.255.2.6
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.6) - Destination: pod2-leaf5b Loopback0 (IP: 10.255.2.14)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf1b
+ hosts:
+ - destination: 10.255.2.15
+ repeat: 1
+ source: 10.255.2.6
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.6) - Destination: pod2-leaf6a Loopback0 (IP: 10.255.2.15)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf1b
+ hosts:
+ - destination: 10.255.2.16
+ repeat: 1
+ source: 10.255.2.6
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.6) - Destination: pod2-leaf6b Loopback0 (IP: 10.255.2.16)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf1b
+ hosts:
+ - destination: 10.255.2.17
+ repeat: 1
+ source: 10.255.2.6
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.6) - Destination: pod2-leaf7a Loopback0 (IP: 10.255.2.17)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf1b
+ hosts:
+ - destination: 10.255.2.18
+ repeat: 1
+ source: 10.255.2.6
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.6) - Destination: pod2-leaf7b Loopback0 (IP: 10.255.2.18)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf1b
+ hosts:
+ - destination: 10.255.2.19
+ repeat: 1
+ source: 10.255.2.6
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.6) - Destination: pod2-leaf8a Loopback0 (IP: 10.255.2.19)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf1b
+ hosts:
+ - destination: 10.255.2.20
+ repeat: 1
+ source: 10.255.2.6
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.6) - Destination: pod2-leaf8b Loopback0 (IP: 10.255.2.20)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf1b
+ hosts:
+ - destination: 10.255.2.21
+ repeat: 1
+ source: 10.255.2.6
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.6) - Destination: pod2-leaf9a Loopback0 (IP: 10.255.2.21)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf1b
+ hosts:
+ - destination: 10.255.2.22
+ repeat: 1
+ source: 10.255.2.6
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.6) - Destination: pod2-leaf9b Loopback0 (IP: 10.255.2.22)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf1b
+ hosts:
+ - destination: 10.255.2.23
+ repeat: 1
+ source: 10.255.2.6
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.6) - Destination: pod2-leaf10a Loopback0 (IP: 10.255.2.23)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf1b
+ hosts:
+ - destination: 10.255.2.24
+ repeat: 1
+ source: 10.255.2.6
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.6) - Destination: pod2-leaf10b Loopback0 (IP: 10.255.2.24)'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - super-spine2
+ neighbors:
+ - neighbor_device: pod1-spine1
+ neighbor_port: Ethernet32/1
+ port: Ethernet1/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet1/1 - Remote: pod1-spine1 Ethernet32/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - super-spine2
+ neighbors:
+ - neighbor_device: pod1-spine2
+ neighbor_port: Ethernet32/1
+ port: Ethernet2/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet2/1 - Remote: pod1-spine2 Ethernet32/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - super-spine2
+ neighbors:
+ - neighbor_device: pod1-spine3
+ neighbor_port: Ethernet32/1
+ port: Ethernet3/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet3/1 - Remote: pod1-spine3 Ethernet32/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - super-spine2
+ neighbors:
+ - neighbor_device: pod1-spine4
+ neighbor_port: Ethernet32/1
+ port: Ethernet4/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet4/1 - Remote: pod1-spine4 Ethernet32/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - super-spine2
+ neighbors:
+ - neighbor_device: pod2-spine1
+ neighbor_port: Ethernet32/1
+ port: Ethernet5/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet5/1 - Remote: pod2-spine1 Ethernet32/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - super-spine2
+ neighbors:
+ - neighbor_device: pod2-spine2
+ neighbor_port: Ethernet32/1
+ port: Ethernet6/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet6/1 - Remote: pod2-spine2 Ethernet32/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - super-spine2
+ neighbors:
+ - neighbor_device: pod2-spine3
+ neighbor_port: Ethernet32/1
+ port: Ethernet7/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet7/1 - Remote: pod2-spine3 Ethernet32/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - super-spine2
+ neighbors:
+ - neighbor_device: pod2-spine4
+ neighbor_port: Ethernet32/1
+ port: Ethernet8/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet8/1 - Remote: pod2-spine4 Ethernet32/1'
+- VerifyReachability:
+ filters:
+ tags:
+ - super-spine2
+ hosts:
+ - destination: 10.255.255.3
+ repeat: 1
+ source: 10.255.255.2
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet1/1 (IP: 10.255.255.2) - Destination: pod1-spine1 Ethernet32/1 (IP: 10.255.255.3)'
+- VerifyReachability:
+ filters:
+ tags:
+ - super-spine2
+ hosts:
+ - destination: 10.255.255.7
+ repeat: 1
+ source: 10.255.255.6
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet2/1 (IP: 10.255.255.6) - Destination: pod1-spine2 Ethernet32/1 (IP: 10.255.255.7)'
+- VerifyReachability:
+ filters:
+ tags:
+ - super-spine2
+ hosts:
+ - destination: 10.255.255.11
+ repeat: 1
+ source: 10.255.255.10
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet3/1 (IP: 10.255.255.10) - Destination: pod1-spine3 Ethernet32/1 (IP: 10.255.255.11)'
+- VerifyReachability:
+ filters:
+ tags:
+ - super-spine2
+ hosts:
+ - destination: 10.255.255.15
+ repeat: 1
+ source: 10.255.255.14
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet4/1 (IP: 10.255.255.14) - Destination: pod1-spine4 Ethernet32/1 (IP: 10.255.255.15)'
+- VerifyReachability:
+ filters:
+ tags:
+ - super-spine2
+ hosts:
+ - destination: 10.255.255.131
+ repeat: 1
+ source: 10.255.255.130
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet5/1 (IP: 10.255.255.130) - Destination: pod2-spine1 Ethernet32/1 (IP: 10.255.255.131)'
+- VerifyReachability:
+ filters:
+ tags:
+ - super-spine2
+ hosts:
+ - destination: 10.255.255.135
+ repeat: 1
+ source: 10.255.255.134
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet6/1 (IP: 10.255.255.134) - Destination: pod2-spine2 Ethernet32/1 (IP: 10.255.255.135)'
+- VerifyReachability:
+ filters:
+ tags:
+ - super-spine2
+ hosts:
+ - destination: 10.255.255.139
+ repeat: 1
+ source: 10.255.255.138
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet7/1 (IP: 10.255.255.138) - Destination: pod2-spine3 Ethernet32/1 (IP: 10.255.255.139)'
+- VerifyReachability:
+ filters:
+ tags:
+ - super-spine2
+ hosts:
+ - destination: 10.255.255.143
+ repeat: 1
+ source: 10.255.255.142
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet8/1 (IP: 10.255.255.142) - Destination: pod2-spine4 Ethernet32/1 (IP: 10.255.255.143)'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-leaf1b
+ neighbors:
+ - neighbor_device: pod1-leaf1a
+ neighbor_port: Ethernet53/1
+ port: Ethernet53/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet53/1 - Remote: pod1-leaf1a Ethernet53/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-leaf1b
+ neighbors:
+ - neighbor_device: pod1-leaf1a
+ neighbor_port: Ethernet54/1
+ port: Ethernet54/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet54/1 - Remote: pod1-leaf1a Ethernet54/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-leaf1b
+ neighbors:
+ - neighbor_device: pod1-spine1
+ neighbor_port: Ethernet2/1
+ port: Ethernet1/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet1/1 - Remote: pod1-spine1 Ethernet2/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-leaf1b
+ neighbors:
+ - neighbor_device: pod1-spine2
+ neighbor_port: Ethernet2/1
+ port: Ethernet2/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet2/1 - Remote: pod1-spine2 Ethernet2/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-leaf1b
+ neighbors:
+ - neighbor_device: pod1-spine3
+ neighbor_port: Ethernet2/1
+ port: Ethernet3/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet3/1 - Remote: pod1-spine3 Ethernet2/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-leaf1b
+ neighbors:
+ - neighbor_device: pod1-spine4
+ neighbor_port: Ethernet2/1
+ port: Ethernet4/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet4/1 - Remote: pod1-spine4 Ethernet2/1'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf1b
+ hosts:
+ - destination: 10.255.255.8
+ repeat: 1
+ source: 10.255.255.9
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet1/1 (IP: 10.255.255.9) - Destination: pod1-spine1 Ethernet2/1 (IP: 10.255.255.8)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf1b
+ hosts:
+ - destination: 10.255.255.10
+ repeat: 1
+ source: 10.255.255.11
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet2/1 (IP: 10.255.255.11) - Destination: pod1-spine2 Ethernet2/1 (IP: 10.255.255.10)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf1b
+ hosts:
+ - destination: 10.255.255.12
+ repeat: 1
+ source: 10.255.255.13
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet3/1 (IP: 10.255.255.13) - Destination: pod1-spine3 Ethernet2/1 (IP: 10.255.255.12)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf1b
+ hosts:
+ - destination: 10.255.255.14
+ repeat: 1
+ source: 10.255.255.15
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet4/1 (IP: 10.255.255.15) - Destination: pod1-spine4 Ethernet2/1 (IP: 10.255.255.14)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf1b
+ hosts:
+ - destination: 10.255.0.1
+ repeat: 1
+ source: 10.255.1.6
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.6) - Destination: super-spine1 Loopback0 (IP: 10.255.0.1)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf1b
+ hosts:
+ - destination: 10.255.0.2
+ repeat: 1
+ source: 10.255.1.6
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.6) - Destination: super-spine2 Loopback0 (IP: 10.255.0.2)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf1b
+ hosts:
+ - destination: 10.255.1.1
+ repeat: 1
+ source: 10.255.1.6
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.6) - Destination: pod1-spine1 Loopback0 (IP: 10.255.1.1)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf1b
+ hosts:
+ - destination: 10.255.1.2
+ repeat: 1
+ source: 10.255.1.6
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.6) - Destination: pod1-spine2 Loopback0 (IP: 10.255.1.2)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf1b
+ hosts:
+ - destination: 10.255.1.3
+ repeat: 1
+ source: 10.255.1.6
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.6) - Destination: pod1-spine3 Loopback0 (IP: 10.255.1.3)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf1b
+ hosts:
+ - destination: 10.255.1.4
+ repeat: 1
+ source: 10.255.1.6
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.6) - Destination: pod1-spine4 Loopback0 (IP: 10.255.1.4)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf1b
+ hosts:
+ - destination: 10.255.1.5
+ repeat: 1
+ source: 10.255.1.6
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.6) - Destination: pod1-leaf1a Loopback0 (IP: 10.255.1.5)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf1b
+ hosts:
+ - destination: 10.255.1.6
+ repeat: 1
+ source: 10.255.1.6
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.6) - Destination: pod1-leaf1b Loopback0 (IP: 10.255.1.6)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf1b
+ hosts:
+ - destination: 10.255.1.7
+ repeat: 1
+ source: 10.255.1.6
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.6) - Destination: pod1-leaf2a Loopback0 (IP: 10.255.1.7)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf1b
+ hosts:
+ - destination: 10.255.1.8
+ repeat: 1
+ source: 10.255.1.6
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.6) - Destination: pod1-leaf2b Loopback0 (IP: 10.255.1.8)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf1b
+ hosts:
+ - destination: 10.255.1.9
+ repeat: 1
+ source: 10.255.1.6
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.6) - Destination: pod1-leaf3a Loopback0 (IP: 10.255.1.9)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf1b
+ hosts:
+ - destination: 10.255.1.10
+ repeat: 1
+ source: 10.255.1.6
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.6) - Destination: pod1-leaf3b Loopback0 (IP: 10.255.1.10)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf1b
+ hosts:
+ - destination: 10.255.1.11
+ repeat: 1
+ source: 10.255.1.6
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.6) - Destination: pod1-leaf4a Loopback0 (IP: 10.255.1.11)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf1b
+ hosts:
+ - destination: 10.255.1.12
+ repeat: 1
+ source: 10.255.1.6
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.6) - Destination: pod1-leaf4b Loopback0 (IP: 10.255.1.12)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf1b
+ hosts:
+ - destination: 10.255.1.13
+ repeat: 1
+ source: 10.255.1.6
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.6) - Destination: pod1-leaf5a Loopback0 (IP: 10.255.1.13)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf1b
+ hosts:
+ - destination: 10.255.1.14
+ repeat: 1
+ source: 10.255.1.6
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.6) - Destination: pod1-leaf5b Loopback0 (IP: 10.255.1.14)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf1b
+ hosts:
+ - destination: 10.255.1.15
+ repeat: 1
+ source: 10.255.1.6
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.6) - Destination: pod1-leaf6a Loopback0 (IP: 10.255.1.15)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf1b
+ hosts:
+ - destination: 10.255.1.16
+ repeat: 1
+ source: 10.255.1.6
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.6) - Destination: pod1-leaf6b Loopback0 (IP: 10.255.1.16)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf1b
+ hosts:
+ - destination: 10.255.1.17
+ repeat: 1
+ source: 10.255.1.6
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.6) - Destination: pod1-leaf7a Loopback0 (IP: 10.255.1.17)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf1b
+ hosts:
+ - destination: 10.255.1.18
+ repeat: 1
+ source: 10.255.1.6
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.6) - Destination: pod1-leaf7b Loopback0 (IP: 10.255.1.18)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf1b
+ hosts:
+ - destination: 10.255.1.19
+ repeat: 1
+ source: 10.255.1.6
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.6) - Destination: pod1-leaf8a Loopback0 (IP: 10.255.1.19)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf1b
+ hosts:
+ - destination: 10.255.1.20
+ repeat: 1
+ source: 10.255.1.6
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.6) - Destination: pod1-leaf8b Loopback0 (IP: 10.255.1.20)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf1b
+ hosts:
+ - destination: 10.255.1.21
+ repeat: 1
+ source: 10.255.1.6
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.6) - Destination: pod1-leaf9a Loopback0 (IP: 10.255.1.21)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf1b
+ hosts:
+ - destination: 10.255.1.22
+ repeat: 1
+ source: 10.255.1.6
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.6) - Destination: pod1-leaf9b Loopback0 (IP: 10.255.1.22)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf1b
+ hosts:
+ - destination: 10.255.1.23
+ repeat: 1
+ source: 10.255.1.6
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.6) - Destination: pod1-leaf10a Loopback0 (IP: 10.255.1.23)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf1b
+ hosts:
+ - destination: 10.255.1.24
+ repeat: 1
+ source: 10.255.1.6
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.6) - Destination: pod1-leaf10b Loopback0 (IP: 10.255.1.24)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf1b
+ hosts:
+ - destination: 10.255.2.1
+ repeat: 1
+ source: 10.255.1.6
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.6) - Destination: pod2-spine1 Loopback0 (IP: 10.255.2.1)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf1b
+ hosts:
+ - destination: 10.255.2.2
+ repeat: 1
+ source: 10.255.1.6
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.6) - Destination: pod2-spine2 Loopback0 (IP: 10.255.2.2)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf1b
+ hosts:
+ - destination: 10.255.2.3
+ repeat: 1
+ source: 10.255.1.6
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.6) - Destination: pod2-spine3 Loopback0 (IP: 10.255.2.3)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf1b
+ hosts:
+ - destination: 10.255.2.4
+ repeat: 1
+ source: 10.255.1.6
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.6) - Destination: pod2-spine4 Loopback0 (IP: 10.255.2.4)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf1b
+ hosts:
+ - destination: 10.255.2.5
+ repeat: 1
+ source: 10.255.1.6
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.6) - Destination: pod2-leaf1a Loopback0 (IP: 10.255.2.5)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf1b
+ hosts:
+ - destination: 10.255.2.6
+ repeat: 1
+ source: 10.255.1.6
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.6) - Destination: pod2-leaf1b Loopback0 (IP: 10.255.2.6)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf1b
+ hosts:
+ - destination: 10.255.2.7
+ repeat: 1
+ source: 10.255.1.6
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.6) - Destination: pod2-leaf2a Loopback0 (IP: 10.255.2.7)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf1b
+ hosts:
+ - destination: 10.255.2.8
+ repeat: 1
+ source: 10.255.1.6
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.6) - Destination: pod2-leaf2b Loopback0 (IP: 10.255.2.8)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf1b
+ hosts:
+ - destination: 10.255.2.9
+ repeat: 1
+ source: 10.255.1.6
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.6) - Destination: pod2-leaf3a Loopback0 (IP: 10.255.2.9)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf1b
+ hosts:
+ - destination: 10.255.2.10
+ repeat: 1
+ source: 10.255.1.6
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.6) - Destination: pod2-leaf3b Loopback0 (IP: 10.255.2.10)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf1b
+ hosts:
+ - destination: 10.255.2.11
+ repeat: 1
+ source: 10.255.1.6
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.6) - Destination: pod2-leaf4a Loopback0 (IP: 10.255.2.11)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf1b
+ hosts:
+ - destination: 10.255.2.12
+ repeat: 1
+ source: 10.255.1.6
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.6) - Destination: pod2-leaf4b Loopback0 (IP: 10.255.2.12)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf1b
+ hosts:
+ - destination: 10.255.2.13
+ repeat: 1
+ source: 10.255.1.6
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.6) - Destination: pod2-leaf5a Loopback0 (IP: 10.255.2.13)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf1b
+ hosts:
+ - destination: 10.255.2.14
+ repeat: 1
+ source: 10.255.1.6
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.6) - Destination: pod2-leaf5b Loopback0 (IP: 10.255.2.14)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf1b
+ hosts:
+ - destination: 10.255.2.15
+ repeat: 1
+ source: 10.255.1.6
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.6) - Destination: pod2-leaf6a Loopback0 (IP: 10.255.2.15)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf1b
+ hosts:
+ - destination: 10.255.2.16
+ repeat: 1
+ source: 10.255.1.6
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.6) - Destination: pod2-leaf6b Loopback0 (IP: 10.255.2.16)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf1b
+ hosts:
+ - destination: 10.255.2.17
+ repeat: 1
+ source: 10.255.1.6
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.6) - Destination: pod2-leaf7a Loopback0 (IP: 10.255.2.17)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf1b
+ hosts:
+ - destination: 10.255.2.18
+ repeat: 1
+ source: 10.255.1.6
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.6) - Destination: pod2-leaf7b Loopback0 (IP: 10.255.2.18)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf1b
+ hosts:
+ - destination: 10.255.2.19
+ repeat: 1
+ source: 10.255.1.6
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.6) - Destination: pod2-leaf8a Loopback0 (IP: 10.255.2.19)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf1b
+ hosts:
+ - destination: 10.255.2.20
+ repeat: 1
+ source: 10.255.1.6
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.6) - Destination: pod2-leaf8b Loopback0 (IP: 10.255.2.20)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf1b
+ hosts:
+ - destination: 10.255.2.21
+ repeat: 1
+ source: 10.255.1.6
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.6) - Destination: pod2-leaf9a Loopback0 (IP: 10.255.2.21)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf1b
+ hosts:
+ - destination: 10.255.2.22
+ repeat: 1
+ source: 10.255.1.6
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.6) - Destination: pod2-leaf9b Loopback0 (IP: 10.255.2.22)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf1b
+ hosts:
+ - destination: 10.255.2.23
+ repeat: 1
+ source: 10.255.1.6
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.6) - Destination: pod2-leaf10a Loopback0 (IP: 10.255.2.23)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf1b
+ hosts:
+ - destination: 10.255.2.24
+ repeat: 1
+ source: 10.255.1.6
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.6) - Destination: pod2-leaf10b Loopback0 (IP: 10.255.2.24)'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-leaf6b
+ neighbors:
+ - neighbor_device: pod1-leaf6a
+ neighbor_port: Ethernet53/1
+ port: Ethernet53/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet53/1 - Remote: pod1-leaf6a Ethernet53/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-leaf6b
+ neighbors:
+ - neighbor_device: pod1-leaf6a
+ neighbor_port: Ethernet54/1
+ port: Ethernet54/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet54/1 - Remote: pod1-leaf6a Ethernet54/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-leaf6b
+ neighbors:
+ - neighbor_device: pod1-spine1
+ neighbor_port: Ethernet12/1
+ port: Ethernet1/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet1/1 - Remote: pod1-spine1 Ethernet12/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-leaf6b
+ neighbors:
+ - neighbor_device: pod1-spine2
+ neighbor_port: Ethernet12/1
+ port: Ethernet2/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet2/1 - Remote: pod1-spine2 Ethernet12/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-leaf6b
+ neighbors:
+ - neighbor_device: pod1-spine3
+ neighbor_port: Ethernet12/1
+ port: Ethernet3/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet3/1 - Remote: pod1-spine3 Ethernet12/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-leaf6b
+ neighbors:
+ - neighbor_device: pod1-spine4
+ neighbor_port: Ethernet12/1
+ port: Ethernet4/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet4/1 - Remote: pod1-spine4 Ethernet12/1'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf6b
+ hosts:
+ - destination: 10.255.255.88
+ repeat: 1
+ source: 10.255.255.89
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet1/1 (IP: 10.255.255.89) - Destination: pod1-spine1 Ethernet12/1 (IP: 10.255.255.88)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf6b
+ hosts:
+ - destination: 10.255.255.90
+ repeat: 1
+ source: 10.255.255.91
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet2/1 (IP: 10.255.255.91) - Destination: pod1-spine2 Ethernet12/1 (IP: 10.255.255.90)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf6b
+ hosts:
+ - destination: 10.255.255.92
+ repeat: 1
+ source: 10.255.255.93
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet3/1 (IP: 10.255.255.93) - Destination: pod1-spine3 Ethernet12/1 (IP: 10.255.255.92)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf6b
+ hosts:
+ - destination: 10.255.255.94
+ repeat: 1
+ source: 10.255.255.95
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet4/1 (IP: 10.255.255.95) - Destination: pod1-spine4 Ethernet12/1 (IP: 10.255.255.94)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf6b
+ hosts:
+ - destination: 10.255.0.1
+ repeat: 1
+ source: 10.255.1.16
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.16) - Destination: super-spine1 Loopback0 (IP: 10.255.0.1)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf6b
+ hosts:
+ - destination: 10.255.0.2
+ repeat: 1
+ source: 10.255.1.16
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.16) - Destination: super-spine2 Loopback0 (IP: 10.255.0.2)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf6b
+ hosts:
+ - destination: 10.255.1.1
+ repeat: 1
+ source: 10.255.1.16
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.16) - Destination: pod1-spine1 Loopback0 (IP: 10.255.1.1)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf6b
+ hosts:
+ - destination: 10.255.1.2
+ repeat: 1
+ source: 10.255.1.16
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.16) - Destination: pod1-spine2 Loopback0 (IP: 10.255.1.2)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf6b
+ hosts:
+ - destination: 10.255.1.3
+ repeat: 1
+ source: 10.255.1.16
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.16) - Destination: pod1-spine3 Loopback0 (IP: 10.255.1.3)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf6b
+ hosts:
+ - destination: 10.255.1.4
+ repeat: 1
+ source: 10.255.1.16
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.16) - Destination: pod1-spine4 Loopback0 (IP: 10.255.1.4)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf6b
+ hosts:
+ - destination: 10.255.1.5
+ repeat: 1
+ source: 10.255.1.16
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.16) - Destination: pod1-leaf1a Loopback0 (IP: 10.255.1.5)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf6b
+ hosts:
+ - destination: 10.255.1.6
+ repeat: 1
+ source: 10.255.1.16
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.16) - Destination: pod1-leaf1b Loopback0 (IP: 10.255.1.6)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf6b
+ hosts:
+ - destination: 10.255.1.7
+ repeat: 1
+ source: 10.255.1.16
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.16) - Destination: pod1-leaf2a Loopback0 (IP: 10.255.1.7)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf6b
+ hosts:
+ - destination: 10.255.1.8
+ repeat: 1
+ source: 10.255.1.16
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.16) - Destination: pod1-leaf2b Loopback0 (IP: 10.255.1.8)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf6b
+ hosts:
+ - destination: 10.255.1.9
+ repeat: 1
+ source: 10.255.1.16
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.16) - Destination: pod1-leaf3a Loopback0 (IP: 10.255.1.9)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf6b
+ hosts:
+ - destination: 10.255.1.10
+ repeat: 1
+ source: 10.255.1.16
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.16) - Destination: pod1-leaf3b Loopback0 (IP: 10.255.1.10)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf6b
+ hosts:
+ - destination: 10.255.1.11
+ repeat: 1
+ source: 10.255.1.16
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.16) - Destination: pod1-leaf4a Loopback0 (IP: 10.255.1.11)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf6b
+ hosts:
+ - destination: 10.255.1.12
+ repeat: 1
+ source: 10.255.1.16
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.16) - Destination: pod1-leaf4b Loopback0 (IP: 10.255.1.12)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf6b
+ hosts:
+ - destination: 10.255.1.13
+ repeat: 1
+ source: 10.255.1.16
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.16) - Destination: pod1-leaf5a Loopback0 (IP: 10.255.1.13)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf6b
+ hosts:
+ - destination: 10.255.1.14
+ repeat: 1
+ source: 10.255.1.16
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.16) - Destination: pod1-leaf5b Loopback0 (IP: 10.255.1.14)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf6b
+ hosts:
+ - destination: 10.255.1.15
+ repeat: 1
+ source: 10.255.1.16
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.16) - Destination: pod1-leaf6a Loopback0 (IP: 10.255.1.15)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf6b
+ hosts:
+ - destination: 10.255.1.16
+ repeat: 1
+ source: 10.255.1.16
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.16) - Destination: pod1-leaf6b Loopback0 (IP: 10.255.1.16)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf6b
+ hosts:
+ - destination: 10.255.1.17
+ repeat: 1
+ source: 10.255.1.16
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.16) - Destination: pod1-leaf7a Loopback0 (IP: 10.255.1.17)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf6b
+ hosts:
+ - destination: 10.255.1.18
+ repeat: 1
+ source: 10.255.1.16
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.16) - Destination: pod1-leaf7b Loopback0 (IP: 10.255.1.18)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf6b
+ hosts:
+ - destination: 10.255.1.19
+ repeat: 1
+ source: 10.255.1.16
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.16) - Destination: pod1-leaf8a Loopback0 (IP: 10.255.1.19)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf6b
+ hosts:
+ - destination: 10.255.1.20
+ repeat: 1
+ source: 10.255.1.16
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.16) - Destination: pod1-leaf8b Loopback0 (IP: 10.255.1.20)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf6b
+ hosts:
+ - destination: 10.255.1.21
+ repeat: 1
+ source: 10.255.1.16
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.16) - Destination: pod1-leaf9a Loopback0 (IP: 10.255.1.21)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf6b
+ hosts:
+ - destination: 10.255.1.22
+ repeat: 1
+ source: 10.255.1.16
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.16) - Destination: pod1-leaf9b Loopback0 (IP: 10.255.1.22)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf6b
+ hosts:
+ - destination: 10.255.1.23
+ repeat: 1
+ source: 10.255.1.16
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.16) - Destination: pod1-leaf10a Loopback0 (IP: 10.255.1.23)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf6b
+ hosts:
+ - destination: 10.255.1.24
+ repeat: 1
+ source: 10.255.1.16
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.16) - Destination: pod1-leaf10b Loopback0 (IP: 10.255.1.24)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf6b
+ hosts:
+ - destination: 10.255.2.1
+ repeat: 1
+ source: 10.255.1.16
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.16) - Destination: pod2-spine1 Loopback0 (IP: 10.255.2.1)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf6b
+ hosts:
+ - destination: 10.255.2.2
+ repeat: 1
+ source: 10.255.1.16
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.16) - Destination: pod2-spine2 Loopback0 (IP: 10.255.2.2)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf6b
+ hosts:
+ - destination: 10.255.2.3
+ repeat: 1
+ source: 10.255.1.16
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.16) - Destination: pod2-spine3 Loopback0 (IP: 10.255.2.3)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf6b
+ hosts:
+ - destination: 10.255.2.4
+ repeat: 1
+ source: 10.255.1.16
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.16) - Destination: pod2-spine4 Loopback0 (IP: 10.255.2.4)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf6b
+ hosts:
+ - destination: 10.255.2.5
+ repeat: 1
+ source: 10.255.1.16
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.16) - Destination: pod2-leaf1a Loopback0 (IP: 10.255.2.5)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf6b
+ hosts:
+ - destination: 10.255.2.6
+ repeat: 1
+ source: 10.255.1.16
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.16) - Destination: pod2-leaf1b Loopback0 (IP: 10.255.2.6)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf6b
+ hosts:
+ - destination: 10.255.2.7
+ repeat: 1
+ source: 10.255.1.16
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.16) - Destination: pod2-leaf2a Loopback0 (IP: 10.255.2.7)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf6b
+ hosts:
+ - destination: 10.255.2.8
+ repeat: 1
+ source: 10.255.1.16
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.16) - Destination: pod2-leaf2b Loopback0 (IP: 10.255.2.8)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf6b
+ hosts:
+ - destination: 10.255.2.9
+ repeat: 1
+ source: 10.255.1.16
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.16) - Destination: pod2-leaf3a Loopback0 (IP: 10.255.2.9)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf6b
+ hosts:
+ - destination: 10.255.2.10
+ repeat: 1
+ source: 10.255.1.16
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.16) - Destination: pod2-leaf3b Loopback0 (IP: 10.255.2.10)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf6b
+ hosts:
+ - destination: 10.255.2.11
+ repeat: 1
+ source: 10.255.1.16
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.16) - Destination: pod2-leaf4a Loopback0 (IP: 10.255.2.11)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf6b
+ hosts:
+ - destination: 10.255.2.12
+ repeat: 1
+ source: 10.255.1.16
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.16) - Destination: pod2-leaf4b Loopback0 (IP: 10.255.2.12)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf6b
+ hosts:
+ - destination: 10.255.2.13
+ repeat: 1
+ source: 10.255.1.16
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.16) - Destination: pod2-leaf5a Loopback0 (IP: 10.255.2.13)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf6b
+ hosts:
+ - destination: 10.255.2.14
+ repeat: 1
+ source: 10.255.1.16
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.16) - Destination: pod2-leaf5b Loopback0 (IP: 10.255.2.14)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf6b
+ hosts:
+ - destination: 10.255.2.15
+ repeat: 1
+ source: 10.255.1.16
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.16) - Destination: pod2-leaf6a Loopback0 (IP: 10.255.2.15)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf6b
+ hosts:
+ - destination: 10.255.2.16
+ repeat: 1
+ source: 10.255.1.16
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.16) - Destination: pod2-leaf6b Loopback0 (IP: 10.255.2.16)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf6b
+ hosts:
+ - destination: 10.255.2.17
+ repeat: 1
+ source: 10.255.1.16
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.16) - Destination: pod2-leaf7a Loopback0 (IP: 10.255.2.17)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf6b
+ hosts:
+ - destination: 10.255.2.18
+ repeat: 1
+ source: 10.255.1.16
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.16) - Destination: pod2-leaf7b Loopback0 (IP: 10.255.2.18)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf6b
+ hosts:
+ - destination: 10.255.2.19
+ repeat: 1
+ source: 10.255.1.16
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.16) - Destination: pod2-leaf8a Loopback0 (IP: 10.255.2.19)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf6b
+ hosts:
+ - destination: 10.255.2.20
+ repeat: 1
+ source: 10.255.1.16
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.16) - Destination: pod2-leaf8b Loopback0 (IP: 10.255.2.20)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf6b
+ hosts:
+ - destination: 10.255.2.21
+ repeat: 1
+ source: 10.255.1.16
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.16) - Destination: pod2-leaf9a Loopback0 (IP: 10.255.2.21)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf6b
+ hosts:
+ - destination: 10.255.2.22
+ repeat: 1
+ source: 10.255.1.16
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.16) - Destination: pod2-leaf9b Loopback0 (IP: 10.255.2.22)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf6b
+ hosts:
+ - destination: 10.255.2.23
+ repeat: 1
+ source: 10.255.1.16
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.16) - Destination: pod2-leaf10a Loopback0 (IP: 10.255.2.23)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-leaf6b
+ hosts:
+ - destination: 10.255.2.24
+ repeat: 1
+ source: 10.255.1.16
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.1.16) - Destination: pod2-leaf10b Loopback0 (IP: 10.255.2.24)'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-leaf7b
+ neighbors:
+ - neighbor_device: pod2-leaf7a
+ neighbor_port: Ethernet53/1
+ port: Ethernet53/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet53/1 - Remote: pod2-leaf7a Ethernet53/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-leaf7b
+ neighbors:
+ - neighbor_device: pod2-leaf7a
+ neighbor_port: Ethernet54/1
+ port: Ethernet54/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet54/1 - Remote: pod2-leaf7a Ethernet54/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-leaf7b
+ neighbors:
+ - neighbor_device: pod2-spine1
+ neighbor_port: Ethernet14/1
+ port: Ethernet1/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet1/1 - Remote: pod2-spine1 Ethernet14/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-leaf7b
+ neighbors:
+ - neighbor_device: pod2-spine2
+ neighbor_port: Ethernet14/1
+ port: Ethernet2/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet2/1 - Remote: pod2-spine2 Ethernet14/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-leaf7b
+ neighbors:
+ - neighbor_device: pod2-spine3
+ neighbor_port: Ethernet14/1
+ port: Ethernet3/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet3/1 - Remote: pod2-spine3 Ethernet14/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod2-leaf7b
+ neighbors:
+ - neighbor_device: pod2-spine4
+ neighbor_port: Ethernet14/1
+ port: Ethernet4/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet4/1 - Remote: pod2-spine4 Ethernet14/1'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf7b
+ hosts:
+ - destination: 10.255.255.104
+ repeat: 1
+ source: 10.255.255.105
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet1/1 (IP: 10.255.255.105) - Destination: pod2-spine1 Ethernet14/1 (IP: 10.255.255.104)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf7b
+ hosts:
+ - destination: 10.255.255.106
+ repeat: 1
+ source: 10.255.255.107
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet2/1 (IP: 10.255.255.107) - Destination: pod2-spine2 Ethernet14/1 (IP: 10.255.255.106)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf7b
+ hosts:
+ - destination: 10.255.255.108
+ repeat: 1
+ source: 10.255.255.109
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet3/1 (IP: 10.255.255.109) - Destination: pod2-spine3 Ethernet14/1 (IP: 10.255.255.108)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf7b
+ hosts:
+ - destination: 10.255.255.110
+ repeat: 1
+ source: 10.255.255.111
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet4/1 (IP: 10.255.255.111) - Destination: pod2-spine4 Ethernet14/1 (IP: 10.255.255.110)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf7b
+ hosts:
+ - destination: 10.255.0.1
+ repeat: 1
+ source: 10.255.2.18
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.18) - Destination: super-spine1 Loopback0 (IP: 10.255.0.1)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf7b
+ hosts:
+ - destination: 10.255.0.2
+ repeat: 1
+ source: 10.255.2.18
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.18) - Destination: super-spine2 Loopback0 (IP: 10.255.0.2)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf7b
+ hosts:
+ - destination: 10.255.1.1
+ repeat: 1
+ source: 10.255.2.18
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.18) - Destination: pod1-spine1 Loopback0 (IP: 10.255.1.1)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf7b
+ hosts:
+ - destination: 10.255.1.2
+ repeat: 1
+ source: 10.255.2.18
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.18) - Destination: pod1-spine2 Loopback0 (IP: 10.255.1.2)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf7b
+ hosts:
+ - destination: 10.255.1.3
+ repeat: 1
+ source: 10.255.2.18
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.18) - Destination: pod1-spine3 Loopback0 (IP: 10.255.1.3)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf7b
+ hosts:
+ - destination: 10.255.1.4
+ repeat: 1
+ source: 10.255.2.18
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.18) - Destination: pod1-spine4 Loopback0 (IP: 10.255.1.4)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf7b
+ hosts:
+ - destination: 10.255.1.5
+ repeat: 1
+ source: 10.255.2.18
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.18) - Destination: pod1-leaf1a Loopback0 (IP: 10.255.1.5)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf7b
+ hosts:
+ - destination: 10.255.1.6
+ repeat: 1
+ source: 10.255.2.18
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.18) - Destination: pod1-leaf1b Loopback0 (IP: 10.255.1.6)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf7b
+ hosts:
+ - destination: 10.255.1.7
+ repeat: 1
+ source: 10.255.2.18
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.18) - Destination: pod1-leaf2a Loopback0 (IP: 10.255.1.7)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf7b
+ hosts:
+ - destination: 10.255.1.8
+ repeat: 1
+ source: 10.255.2.18
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.18) - Destination: pod1-leaf2b Loopback0 (IP: 10.255.1.8)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf7b
+ hosts:
+ - destination: 10.255.1.9
+ repeat: 1
+ source: 10.255.2.18
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.18) - Destination: pod1-leaf3a Loopback0 (IP: 10.255.1.9)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf7b
+ hosts:
+ - destination: 10.255.1.10
+ repeat: 1
+ source: 10.255.2.18
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.18) - Destination: pod1-leaf3b Loopback0 (IP: 10.255.1.10)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf7b
+ hosts:
+ - destination: 10.255.1.11
+ repeat: 1
+ source: 10.255.2.18
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.18) - Destination: pod1-leaf4a Loopback0 (IP: 10.255.1.11)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf7b
+ hosts:
+ - destination: 10.255.1.12
+ repeat: 1
+ source: 10.255.2.18
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.18) - Destination: pod1-leaf4b Loopback0 (IP: 10.255.1.12)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf7b
+ hosts:
+ - destination: 10.255.1.13
+ repeat: 1
+ source: 10.255.2.18
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.18) - Destination: pod1-leaf5a Loopback0 (IP: 10.255.1.13)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf7b
+ hosts:
+ - destination: 10.255.1.14
+ repeat: 1
+ source: 10.255.2.18
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.18) - Destination: pod1-leaf5b Loopback0 (IP: 10.255.1.14)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf7b
+ hosts:
+ - destination: 10.255.1.15
+ repeat: 1
+ source: 10.255.2.18
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.18) - Destination: pod1-leaf6a Loopback0 (IP: 10.255.1.15)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf7b
+ hosts:
+ - destination: 10.255.1.16
+ repeat: 1
+ source: 10.255.2.18
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.18) - Destination: pod1-leaf6b Loopback0 (IP: 10.255.1.16)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf7b
+ hosts:
+ - destination: 10.255.1.17
+ repeat: 1
+ source: 10.255.2.18
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.18) - Destination: pod1-leaf7a Loopback0 (IP: 10.255.1.17)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf7b
+ hosts:
+ - destination: 10.255.1.18
+ repeat: 1
+ source: 10.255.2.18
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.18) - Destination: pod1-leaf7b Loopback0 (IP: 10.255.1.18)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf7b
+ hosts:
+ - destination: 10.255.1.19
+ repeat: 1
+ source: 10.255.2.18
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.18) - Destination: pod1-leaf8a Loopback0 (IP: 10.255.1.19)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf7b
+ hosts:
+ - destination: 10.255.1.20
+ repeat: 1
+ source: 10.255.2.18
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.18) - Destination: pod1-leaf8b Loopback0 (IP: 10.255.1.20)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf7b
+ hosts:
+ - destination: 10.255.1.21
+ repeat: 1
+ source: 10.255.2.18
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.18) - Destination: pod1-leaf9a Loopback0 (IP: 10.255.1.21)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf7b
+ hosts:
+ - destination: 10.255.1.22
+ repeat: 1
+ source: 10.255.2.18
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.18) - Destination: pod1-leaf9b Loopback0 (IP: 10.255.1.22)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf7b
+ hosts:
+ - destination: 10.255.1.23
+ repeat: 1
+ source: 10.255.2.18
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.18) - Destination: pod1-leaf10a Loopback0 (IP: 10.255.1.23)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf7b
+ hosts:
+ - destination: 10.255.1.24
+ repeat: 1
+ source: 10.255.2.18
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.18) - Destination: pod1-leaf10b Loopback0 (IP: 10.255.1.24)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf7b
+ hosts:
+ - destination: 10.255.2.1
+ repeat: 1
+ source: 10.255.2.18
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.18) - Destination: pod2-spine1 Loopback0 (IP: 10.255.2.1)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf7b
+ hosts:
+ - destination: 10.255.2.2
+ repeat: 1
+ source: 10.255.2.18
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.18) - Destination: pod2-spine2 Loopback0 (IP: 10.255.2.2)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf7b
+ hosts:
+ - destination: 10.255.2.3
+ repeat: 1
+ source: 10.255.2.18
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.18) - Destination: pod2-spine3 Loopback0 (IP: 10.255.2.3)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf7b
+ hosts:
+ - destination: 10.255.2.4
+ repeat: 1
+ source: 10.255.2.18
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.18) - Destination: pod2-spine4 Loopback0 (IP: 10.255.2.4)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf7b
+ hosts:
+ - destination: 10.255.2.5
+ repeat: 1
+ source: 10.255.2.18
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.18) - Destination: pod2-leaf1a Loopback0 (IP: 10.255.2.5)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf7b
+ hosts:
+ - destination: 10.255.2.6
+ repeat: 1
+ source: 10.255.2.18
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.18) - Destination: pod2-leaf1b Loopback0 (IP: 10.255.2.6)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf7b
+ hosts:
+ - destination: 10.255.2.7
+ repeat: 1
+ source: 10.255.2.18
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.18) - Destination: pod2-leaf2a Loopback0 (IP: 10.255.2.7)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf7b
+ hosts:
+ - destination: 10.255.2.8
+ repeat: 1
+ source: 10.255.2.18
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.18) - Destination: pod2-leaf2b Loopback0 (IP: 10.255.2.8)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf7b
+ hosts:
+ - destination: 10.255.2.9
+ repeat: 1
+ source: 10.255.2.18
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.18) - Destination: pod2-leaf3a Loopback0 (IP: 10.255.2.9)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf7b
+ hosts:
+ - destination: 10.255.2.10
+ repeat: 1
+ source: 10.255.2.18
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.18) - Destination: pod2-leaf3b Loopback0 (IP: 10.255.2.10)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf7b
+ hosts:
+ - destination: 10.255.2.11
+ repeat: 1
+ source: 10.255.2.18
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.18) - Destination: pod2-leaf4a Loopback0 (IP: 10.255.2.11)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf7b
+ hosts:
+ - destination: 10.255.2.12
+ repeat: 1
+ source: 10.255.2.18
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.18) - Destination: pod2-leaf4b Loopback0 (IP: 10.255.2.12)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf7b
+ hosts:
+ - destination: 10.255.2.13
+ repeat: 1
+ source: 10.255.2.18
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.18) - Destination: pod2-leaf5a Loopback0 (IP: 10.255.2.13)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf7b
+ hosts:
+ - destination: 10.255.2.14
+ repeat: 1
+ source: 10.255.2.18
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.18) - Destination: pod2-leaf5b Loopback0 (IP: 10.255.2.14)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf7b
+ hosts:
+ - destination: 10.255.2.15
+ repeat: 1
+ source: 10.255.2.18
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.18) - Destination: pod2-leaf6a Loopback0 (IP: 10.255.2.15)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf7b
+ hosts:
+ - destination: 10.255.2.16
+ repeat: 1
+ source: 10.255.2.18
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.18) - Destination: pod2-leaf6b Loopback0 (IP: 10.255.2.16)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf7b
+ hosts:
+ - destination: 10.255.2.17
+ repeat: 1
+ source: 10.255.2.18
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.18) - Destination: pod2-leaf7a Loopback0 (IP: 10.255.2.17)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf7b
+ hosts:
+ - destination: 10.255.2.18
+ repeat: 1
+ source: 10.255.2.18
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.18) - Destination: pod2-leaf7b Loopback0 (IP: 10.255.2.18)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf7b
+ hosts:
+ - destination: 10.255.2.19
+ repeat: 1
+ source: 10.255.2.18
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.18) - Destination: pod2-leaf8a Loopback0 (IP: 10.255.2.19)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf7b
+ hosts:
+ - destination: 10.255.2.20
+ repeat: 1
+ source: 10.255.2.18
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.18) - Destination: pod2-leaf8b Loopback0 (IP: 10.255.2.20)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf7b
+ hosts:
+ - destination: 10.255.2.21
+ repeat: 1
+ source: 10.255.2.18
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.18) - Destination: pod2-leaf9a Loopback0 (IP: 10.255.2.21)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf7b
+ hosts:
+ - destination: 10.255.2.22
+ repeat: 1
+ source: 10.255.2.18
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.18) - Destination: pod2-leaf9b Loopback0 (IP: 10.255.2.22)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf7b
+ hosts:
+ - destination: 10.255.2.23
+ repeat: 1
+ source: 10.255.2.18
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.18) - Destination: pod2-leaf10a Loopback0 (IP: 10.255.2.23)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod2-leaf7b
+ hosts:
+ - destination: 10.255.2.24
+ repeat: 1
+ source: 10.255.2.18
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.2.18) - Destination: pod2-leaf10b Loopback0 (IP: 10.255.2.24)'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-spine3
+ neighbors:
+ - neighbor_device: pod1-leaf1a
+ neighbor_port: Ethernet3/1
+ port: Ethernet1/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet1/1 - Remote: pod1-leaf1a Ethernet3/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-spine3
+ neighbors:
+ - neighbor_device: pod1-leaf1b
+ neighbor_port: Ethernet3/1
+ port: Ethernet2/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet2/1 - Remote: pod1-leaf1b Ethernet3/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-spine3
+ neighbors:
+ - neighbor_device: pod1-leaf2a
+ neighbor_port: Ethernet3/1
+ port: Ethernet3/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet3/1 - Remote: pod1-leaf2a Ethernet3/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-spine3
+ neighbors:
+ - neighbor_device: pod1-leaf2b
+ neighbor_port: Ethernet3/1
+ port: Ethernet4/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet4/1 - Remote: pod1-leaf2b Ethernet3/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-spine3
+ neighbors:
+ - neighbor_device: pod1-leaf3a
+ neighbor_port: Ethernet3/1
+ port: Ethernet5/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet5/1 - Remote: pod1-leaf3a Ethernet3/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-spine3
+ neighbors:
+ - neighbor_device: pod1-leaf3b
+ neighbor_port: Ethernet3/1
+ port: Ethernet6/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet6/1 - Remote: pod1-leaf3b Ethernet3/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-spine3
+ neighbors:
+ - neighbor_device: pod1-leaf4a
+ neighbor_port: Ethernet3/1
+ port: Ethernet7/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet7/1 - Remote: pod1-leaf4a Ethernet3/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-spine3
+ neighbors:
+ - neighbor_device: pod1-leaf4b
+ neighbor_port: Ethernet3/1
+ port: Ethernet8/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet8/1 - Remote: pod1-leaf4b Ethernet3/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-spine3
+ neighbors:
+ - neighbor_device: pod1-leaf5a
+ neighbor_port: Ethernet3/1
+ port: Ethernet9/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet9/1 - Remote: pod1-leaf5a Ethernet3/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-spine3
+ neighbors:
+ - neighbor_device: pod1-leaf5b
+ neighbor_port: Ethernet3/1
+ port: Ethernet10/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet10/1 - Remote: pod1-leaf5b Ethernet3/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-spine3
+ neighbors:
+ - neighbor_device: pod1-leaf6a
+ neighbor_port: Ethernet3/1
+ port: Ethernet11/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet11/1 - Remote: pod1-leaf6a Ethernet3/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-spine3
+ neighbors:
+ - neighbor_device: pod1-leaf6b
+ neighbor_port: Ethernet3/1
+ port: Ethernet12/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet12/1 - Remote: pod1-leaf6b Ethernet3/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-spine3
+ neighbors:
+ - neighbor_device: pod1-leaf7a
+ neighbor_port: Ethernet3/1
+ port: Ethernet13/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet13/1 - Remote: pod1-leaf7a Ethernet3/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-spine3
+ neighbors:
+ - neighbor_device: pod1-leaf7b
+ neighbor_port: Ethernet3/1
+ port: Ethernet14/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet14/1 - Remote: pod1-leaf7b Ethernet3/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-spine3
+ neighbors:
+ - neighbor_device: pod1-leaf8a
+ neighbor_port: Ethernet3/1
+ port: Ethernet15/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet15/1 - Remote: pod1-leaf8a Ethernet3/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-spine3
+ neighbors:
+ - neighbor_device: pod1-leaf8b
+ neighbor_port: Ethernet3/1
+ port: Ethernet16/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet16/1 - Remote: pod1-leaf8b Ethernet3/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-spine3
+ neighbors:
+ - neighbor_device: pod1-leaf9a
+ neighbor_port: Ethernet3/1
+ port: Ethernet17/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet17/1 - Remote: pod1-leaf9a Ethernet3/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-spine3
+ neighbors:
+ - neighbor_device: pod1-leaf9b
+ neighbor_port: Ethernet3/1
+ port: Ethernet18/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet18/1 - Remote: pod1-leaf9b Ethernet3/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-spine3
+ neighbors:
+ - neighbor_device: pod1-leaf10a
+ neighbor_port: Ethernet3/1
+ port: Ethernet19/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet19/1 - Remote: pod1-leaf10a Ethernet3/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-spine3
+ neighbors:
+ - neighbor_device: pod1-leaf10b
+ neighbor_port: Ethernet3/1
+ port: Ethernet20/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet20/1 - Remote: pod1-leaf10b Ethernet3/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-spine3
+ neighbors:
+ - neighbor_device: super-spine1
+ neighbor_port: Ethernet3/1
+ port: Ethernet31/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet31/1 - Remote: super-spine1 Ethernet3/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - pod1-spine3
+ neighbors:
+ - neighbor_device: super-spine2
+ neighbor_port: Ethernet3/1
+ port: Ethernet32/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet32/1 - Remote: super-spine2 Ethernet3/1'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-spine3
+ hosts:
+ - destination: 10.255.255.5
+ repeat: 1
+ source: 10.255.255.4
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet1/1 (IP: 10.255.255.4) - Destination: pod1-leaf1a Ethernet3/1 (IP: 10.255.255.5)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-spine3
+ hosts:
+ - destination: 10.255.255.13
+ repeat: 1
+ source: 10.255.255.12
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet2/1 (IP: 10.255.255.12) - Destination: pod1-leaf1b Ethernet3/1 (IP: 10.255.255.13)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-spine3
+ hosts:
+ - destination: 10.255.255.21
+ repeat: 1
+ source: 10.255.255.20
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet3/1 (IP: 10.255.255.20) - Destination: pod1-leaf2a Ethernet3/1 (IP: 10.255.255.21)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-spine3
+ hosts:
+ - destination: 10.255.255.29
+ repeat: 1
+ source: 10.255.255.28
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet4/1 (IP: 10.255.255.28) - Destination: pod1-leaf2b Ethernet3/1 (IP: 10.255.255.29)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-spine3
+ hosts:
+ - destination: 10.255.255.37
+ repeat: 1
+ source: 10.255.255.36
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet5/1 (IP: 10.255.255.36) - Destination: pod1-leaf3a Ethernet3/1 (IP: 10.255.255.37)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-spine3
+ hosts:
+ - destination: 10.255.255.45
+ repeat: 1
+ source: 10.255.255.44
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet6/1 (IP: 10.255.255.44) - Destination: pod1-leaf3b Ethernet3/1 (IP: 10.255.255.45)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-spine3
+ hosts:
+ - destination: 10.255.255.53
+ repeat: 1
+ source: 10.255.255.52
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet7/1 (IP: 10.255.255.52) - Destination: pod1-leaf4a Ethernet3/1 (IP: 10.255.255.53)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-spine3
+ hosts:
+ - destination: 10.255.255.61
+ repeat: 1
+ source: 10.255.255.60
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet8/1 (IP: 10.255.255.60) - Destination: pod1-leaf4b Ethernet3/1 (IP: 10.255.255.61)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-spine3
+ hosts:
+ - destination: 10.255.255.69
+ repeat: 1
+ source: 10.255.255.68
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet9/1 (IP: 10.255.255.68) - Destination: pod1-leaf5a Ethernet3/1 (IP: 10.255.255.69)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-spine3
+ hosts:
+ - destination: 10.255.255.77
+ repeat: 1
+ source: 10.255.255.76
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet10/1 (IP: 10.255.255.76) - Destination: pod1-leaf5b Ethernet3/1 (IP: 10.255.255.77)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-spine3
+ hosts:
+ - destination: 10.255.255.85
+ repeat: 1
+ source: 10.255.255.84
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet11/1 (IP: 10.255.255.84) - Destination: pod1-leaf6a Ethernet3/1 (IP: 10.255.255.85)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-spine3
+ hosts:
+ - destination: 10.255.255.93
+ repeat: 1
+ source: 10.255.255.92
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet12/1 (IP: 10.255.255.92) - Destination: pod1-leaf6b Ethernet3/1 (IP: 10.255.255.93)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-spine3
+ hosts:
+ - destination: 10.255.255.101
+ repeat: 1
+ source: 10.255.255.100
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet13/1 (IP: 10.255.255.100) - Destination: pod1-leaf7a Ethernet3/1 (IP: 10.255.255.101)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-spine3
+ hosts:
+ - destination: 10.255.255.109
+ repeat: 1
+ source: 10.255.255.108
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet14/1 (IP: 10.255.255.108) - Destination: pod1-leaf7b Ethernet3/1 (IP: 10.255.255.109)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-spine3
+ hosts:
+ - destination: 10.255.255.117
+ repeat: 1
+ source: 10.255.255.116
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet15/1 (IP: 10.255.255.116) - Destination: pod1-leaf8a Ethernet3/1 (IP: 10.255.255.117)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-spine3
+ hosts:
+ - destination: 10.255.255.125
+ repeat: 1
+ source: 10.255.255.124
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet16/1 (IP: 10.255.255.124) - Destination: pod1-leaf8b Ethernet3/1 (IP: 10.255.255.125)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-spine3
+ hosts:
+ - destination: 10.255.255.133
+ repeat: 1
+ source: 10.255.255.132
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet17/1 (IP: 10.255.255.132) - Destination: pod1-leaf9a Ethernet3/1 (IP: 10.255.255.133)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-spine3
+ hosts:
+ - destination: 10.255.255.141
+ repeat: 1
+ source: 10.255.255.140
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet18/1 (IP: 10.255.255.140) - Destination: pod1-leaf9b Ethernet3/1 (IP: 10.255.255.141)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-spine3
+ hosts:
+ - destination: 10.255.255.149
+ repeat: 1
+ source: 10.255.255.148
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet19/1 (IP: 10.255.255.148) - Destination: pod1-leaf10a Ethernet3/1 (IP: 10.255.255.149)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-spine3
+ hosts:
+ - destination: 10.255.255.157
+ repeat: 1
+ source: 10.255.255.156
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet20/1 (IP: 10.255.255.156) - Destination: pod1-leaf10b Ethernet3/1 (IP: 10.255.255.157)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-spine3
+ hosts:
+ - destination: 10.255.255.8
+ repeat: 1
+ source: 10.255.255.9
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet31/1 (IP: 10.255.255.9) - Destination: super-spine1 Ethernet3/1 (IP: 10.255.255.8)'
+- VerifyReachability:
+ filters:
+ tags:
+ - pod1-spine3
+ hosts:
+ - destination: 10.255.255.10
+ repeat: 1
+ source: 10.255.255.11
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet32/1 (IP: 10.255.255.11) - Destination: super-spine2 Ethernet3/1 (IP: 10.255.255.10)'
+anta.tests.hardware:
+- VerifyEnvironmentPower:
+ filters:
+ tags:
+ - pod1-leaf4b
+ result_overwrite:
+ custom_field: 'Accepted States: ''ok'''
+ states:
+ - ok
+- VerifyEnvironmentCooling:
+ filters:
+ tags:
+ - pod1-leaf4b
+ result_overwrite:
+ custom_field: 'Accepted States: ''ok'''
+ states:
+ - ok
+- VerifyTemperature:
+ filters:
+ tags:
+ - pod1-leaf4b
+- VerifyTransceiversManufacturers:
+ filters:
+ tags:
+ - pod1-leaf4b
+ manufacturers:
+ - Arista Networks
+ - Arastra, Inc.
+ - Not Present
+ result_overwrite:
+ custom_field: 'Accepted Manufacturers: ''Arista Networks'', ''Arastra, Inc.'', ''Not Present'''
+- VerifyEnvironmentPower:
+ filters:
+ tags:
+ - pod2-spine1
+ result_overwrite:
+ custom_field: 'Accepted States: ''ok'''
+ states:
+ - ok
+- VerifyEnvironmentCooling:
+ filters:
+ tags:
+ - pod2-spine1
+ result_overwrite:
+ custom_field: 'Accepted States: ''ok'''
+ states:
+ - ok
+- VerifyTemperature:
+ filters:
+ tags:
+ - pod2-spine1
+- VerifyTransceiversManufacturers:
+ filters:
+ tags:
+ - pod2-spine1
+ manufacturers:
+ - Arista Networks
+ - Arastra, Inc.
+ - Not Present
+ result_overwrite:
+ custom_field: 'Accepted Manufacturers: ''Arista Networks'', ''Arastra, Inc.'', ''Not Present'''
+- VerifyEnvironmentPower:
+ filters:
+ tags:
+ - pod1-leaf3b
+ result_overwrite:
+ custom_field: 'Accepted States: ''ok'''
+ states:
+ - ok
+- VerifyEnvironmentCooling:
+ filters:
+ tags:
+ - pod1-leaf3b
+ result_overwrite:
+ custom_field: 'Accepted States: ''ok'''
+ states:
+ - ok
+- VerifyTemperature:
+ filters:
+ tags:
+ - pod1-leaf3b
+- VerifyTransceiversManufacturers:
+ filters:
+ tags:
+ - pod1-leaf3b
+ manufacturers:
+ - Arista Networks
+ - Arastra, Inc.
+ - Not Present
+ result_overwrite:
+ custom_field: 'Accepted Manufacturers: ''Arista Networks'', ''Arastra, Inc.'', ''Not Present'''
+- VerifyEnvironmentPower:
+ filters:
+ tags:
+ - pod1-leaf9a
+ result_overwrite:
+ custom_field: 'Accepted States: ''ok'''
+ states:
+ - ok
+- VerifyEnvironmentCooling:
+ filters:
+ tags:
+ - pod1-leaf9a
+ result_overwrite:
+ custom_field: 'Accepted States: ''ok'''
+ states:
+ - ok
+- VerifyTemperature:
+ filters:
+ tags:
+ - pod1-leaf9a
+- VerifyTransceiversManufacturers:
+ filters:
+ tags:
+ - pod1-leaf9a
+ manufacturers:
+ - Arista Networks
+ - Arastra, Inc.
+ - Not Present
+ result_overwrite:
+ custom_field: 'Accepted Manufacturers: ''Arista Networks'', ''Arastra, Inc.'', ''Not Present'''
+- VerifyEnvironmentPower:
+ filters:
+ tags:
+ - pod1-spine4
+ result_overwrite:
+ custom_field: 'Accepted States: ''ok'''
+ states:
+ - ok
+- VerifyEnvironmentCooling:
+ filters:
+ tags:
+ - pod1-spine4
+ result_overwrite:
+ custom_field: 'Accepted States: ''ok'''
+ states:
+ - ok
+- VerifyTemperature:
+ filters:
+ tags:
+ - pod1-spine4
+- VerifyTransceiversManufacturers:
+ filters:
+ tags:
+ - pod1-spine4
+ manufacturers:
+ - Arista Networks
+ - Arastra, Inc.
+ - Not Present
+ result_overwrite:
+ custom_field: 'Accepted Manufacturers: ''Arista Networks'', ''Arastra, Inc.'', ''Not Present'''
+- VerifyEnvironmentPower:
+ filters:
+ tags:
+ - pod2-leaf5b
+ result_overwrite:
+ custom_field: 'Accepted States: ''ok'''
+ states:
+ - ok
+- VerifyEnvironmentCooling:
+ filters:
+ tags:
+ - pod2-leaf5b
+ result_overwrite:
+ custom_field: 'Accepted States: ''ok'''
+ states:
+ - ok
+- VerifyTemperature:
+ filters:
+ tags:
+ - pod2-leaf5b
+- VerifyTransceiversManufacturers:
+ filters:
+ tags:
+ - pod2-leaf5b
+ manufacturers:
+ - Arista Networks
+ - Arastra, Inc.
+ - Not Present
+ result_overwrite:
+ custom_field: 'Accepted Manufacturers: ''Arista Networks'', ''Arastra, Inc.'', ''Not Present'''
+- VerifyEnvironmentPower:
+ filters:
+ tags:
+ - pod2-leaf2b
+ result_overwrite:
+ custom_field: 'Accepted States: ''ok'''
+ states:
+ - ok
+- VerifyEnvironmentCooling:
+ filters:
+ tags:
+ - pod2-leaf2b
+ result_overwrite:
+ custom_field: 'Accepted States: ''ok'''
+ states:
+ - ok
+- VerifyTemperature:
+ filters:
+ tags:
+ - pod2-leaf2b
+- VerifyTransceiversManufacturers:
+ filters:
+ tags:
+ - pod2-leaf2b
+ manufacturers:
+ - Arista Networks
+ - Arastra, Inc.
+ - Not Present
+ result_overwrite:
+ custom_field: 'Accepted Manufacturers: ''Arista Networks'', ''Arastra, Inc.'', ''Not Present'''
+- VerifyEnvironmentPower:
+ filters:
+ tags:
+ - pod2-leaf8a
+ result_overwrite:
+ custom_field: 'Accepted States: ''ok'''
+ states:
+ - ok
+- VerifyEnvironmentCooling:
+ filters:
+ tags:
+ - pod2-leaf8a
+ result_overwrite:
+ custom_field: 'Accepted States: ''ok'''
+ states:
+ - ok
+- VerifyTemperature:
+ filters:
+ tags:
+ - pod2-leaf8a
+- VerifyTransceiversManufacturers:
+ filters:
+ tags:
+ - pod2-leaf8a
+ manufacturers:
+ - Arista Networks
+ - Arastra, Inc.
+ - Not Present
+ result_overwrite:
+ custom_field: 'Accepted Manufacturers: ''Arista Networks'', ''Arastra, Inc.'', ''Not Present'''
+- VerifyEnvironmentPower:
+ filters:
+ tags:
+ - pod1-leaf2b
+ result_overwrite:
+ custom_field: 'Accepted States: ''ok'''
+ states:
+ - ok
+- VerifyEnvironmentCooling:
+ filters:
+ tags:
+ - pod1-leaf2b
+ result_overwrite:
+ custom_field: 'Accepted States: ''ok'''
+ states:
+ - ok
+- VerifyTemperature:
+ filters:
+ tags:
+ - pod1-leaf2b
+- VerifyTransceiversManufacturers:
+ filters:
+ tags:
+ - pod1-leaf2b
+ manufacturers:
+ - Arista Networks
+ - Arastra, Inc.
+ - Not Present
+ result_overwrite:
+ custom_field: 'Accepted Manufacturers: ''Arista Networks'', ''Arastra, Inc.'', ''Not Present'''
+- VerifyEnvironmentPower:
+ filters:
+ tags:
+ - pod1-leaf5b
+ result_overwrite:
+ custom_field: 'Accepted States: ''ok'''
+ states:
+ - ok
+- VerifyEnvironmentCooling:
+ filters:
+ tags:
+ - pod1-leaf5b
+ result_overwrite:
+ custom_field: 'Accepted States: ''ok'''
+ states:
+ - ok
+- VerifyTemperature:
+ filters:
+ tags:
+ - pod1-leaf5b
+- VerifyTransceiversManufacturers:
+ filters:
+ tags:
+ - pod1-leaf5b
+ manufacturers:
+ - Arista Networks
+ - Arastra, Inc.
+ - Not Present
+ result_overwrite:
+ custom_field: 'Accepted Manufacturers: ''Arista Networks'', ''Arastra, Inc.'', ''Not Present'''
+- VerifyEnvironmentPower:
+ filters:
+ tags:
+ - pod1-leaf8a
+ result_overwrite:
+ custom_field: 'Accepted States: ''ok'''
+ states:
+ - ok
+- VerifyEnvironmentCooling:
+ filters:
+ tags:
+ - pod1-leaf8a
+ result_overwrite:
+ custom_field: 'Accepted States: ''ok'''
+ states:
+ - ok
+- VerifyTemperature:
+ filters:
+ tags:
+ - pod1-leaf8a
+- VerifyTransceiversManufacturers:
+ filters:
+ tags:
+ - pod1-leaf8a
+ manufacturers:
+ - Arista Networks
+ - Arastra, Inc.
+ - Not Present
+ result_overwrite:
+ custom_field: 'Accepted Manufacturers: ''Arista Networks'', ''Arastra, Inc.'', ''Not Present'''
+- VerifyEnvironmentPower:
+ filters:
+ tags:
+ - pod2-spine4
+ result_overwrite:
+ custom_field: 'Accepted States: ''ok'''
+ states:
+ - ok
+- VerifyEnvironmentCooling:
+ filters:
+ tags:
+ - pod2-spine4
+ result_overwrite:
+ custom_field: 'Accepted States: ''ok'''
+ states:
+ - ok
+- VerifyTemperature:
+ filters:
+ tags:
+ - pod2-spine4
+- VerifyTransceiversManufacturers:
+ filters:
+ tags:
+ - pod2-spine4
+ manufacturers:
+ - Arista Networks
+ - Arastra, Inc.
+ - Not Present
+ result_overwrite:
+ custom_field: 'Accepted Manufacturers: ''Arista Networks'', ''Arastra, Inc.'', ''Not Present'''
+- VerifyEnvironmentPower:
+ filters:
+ tags:
+ - pod2-leaf3b
+ result_overwrite:
+ custom_field: 'Accepted States: ''ok'''
+ states:
+ - ok
+- VerifyEnvironmentCooling:
+ filters:
+ tags:
+ - pod2-leaf3b
+ result_overwrite:
+ custom_field: 'Accepted States: ''ok'''
+ states:
+ - ok
+- VerifyTemperature:
+ filters:
+ tags:
+ - pod2-leaf3b
+- VerifyTransceiversManufacturers:
+ filters:
+ tags:
+ - pod2-leaf3b
+ manufacturers:
+ - Arista Networks
+ - Arastra, Inc.
+ - Not Present
+ result_overwrite:
+ custom_field: 'Accepted Manufacturers: ''Arista Networks'', ''Arastra, Inc.'', ''Not Present'''
+- VerifyEnvironmentPower:
+ filters:
+ tags:
+ - pod2-leaf4b
+ result_overwrite:
+ custom_field: 'Accepted States: ''ok'''
+ states:
+ - ok
+- VerifyEnvironmentCooling:
+ filters:
+ tags:
+ - pod2-leaf4b
+ result_overwrite:
+ custom_field: 'Accepted States: ''ok'''
+ states:
+ - ok
+- VerifyTemperature:
+ filters:
+ tags:
+ - pod2-leaf4b
+- VerifyTransceiversManufacturers:
+ filters:
+ tags:
+ - pod2-leaf4b
+ manufacturers:
+ - Arista Networks
+ - Arastra, Inc.
+ - Not Present
+ result_overwrite:
+ custom_field: 'Accepted Manufacturers: ''Arista Networks'', ''Arastra, Inc.'', ''Not Present'''
+- VerifyEnvironmentPower:
+ filters:
+ tags:
+ - pod1-spine1
+ result_overwrite:
+ custom_field: 'Accepted States: ''ok'''
+ states:
+ - ok
+- VerifyEnvironmentCooling:
+ filters:
+ tags:
+ - pod1-spine1
+ result_overwrite:
+ custom_field: 'Accepted States: ''ok'''
+ states:
+ - ok
+- VerifyTemperature:
+ filters:
+ tags:
+ - pod1-spine1
+- VerifyTransceiversManufacturers:
+ filters:
+ tags:
+ - pod1-spine1
+ manufacturers:
+ - Arista Networks
+ - Arastra, Inc.
+ - Not Present
+ result_overwrite:
+ custom_field: 'Accepted Manufacturers: ''Arista Networks'', ''Arastra, Inc.'', ''Not Present'''
+- VerifyEnvironmentPower:
+ filters:
+ tags:
+ - pod2-leaf9a
+ result_overwrite:
+ custom_field: 'Accepted States: ''ok'''
+ states:
+ - ok
+- VerifyEnvironmentCooling:
+ filters:
+ tags:
+ - pod2-leaf9a
+ result_overwrite:
+ custom_field: 'Accepted States: ''ok'''
+ states:
+ - ok
+- VerifyTemperature:
+ filters:
+ tags:
+ - pod2-leaf9a
+- VerifyTransceiversManufacturers:
+ filters:
+ tags:
+ - pod2-leaf9a
+ manufacturers:
+ - Arista Networks
+ - Arastra, Inc.
+ - Not Present
+ result_overwrite:
+ custom_field: 'Accepted Manufacturers: ''Arista Networks'', ''Arastra, Inc.'', ''Not Present'''
+- VerifyEnvironmentPower:
+ filters:
+ tags:
+ - pod2-leaf9b
+ result_overwrite:
+ custom_field: 'Accepted States: ''ok'''
+ states:
+ - ok
+- VerifyEnvironmentCooling:
+ filters:
+ tags:
+ - pod2-leaf9b
+ result_overwrite:
+ custom_field: 'Accepted States: ''ok'''
+ states:
+ - ok
+- VerifyTemperature:
+ filters:
+ tags:
+ - pod2-leaf9b
+- VerifyTransceiversManufacturers:
+ filters:
+ tags:
+ - pod2-leaf9b
+ manufacturers:
+ - Arista Networks
+ - Arastra, Inc.
+ - Not Present
+ result_overwrite:
+ custom_field: 'Accepted Manufacturers: ''Arista Networks'', ''Arastra, Inc.'', ''Not Present'''
+- VerifyEnvironmentPower:
+ filters:
+ tags:
+ - pod2-leaf3a
+ result_overwrite:
+ custom_field: 'Accepted States: ''ok'''
+ states:
+ - ok
+- VerifyEnvironmentCooling:
+ filters:
+ tags:
+ - pod2-leaf3a
+ result_overwrite:
+ custom_field: 'Accepted States: ''ok'''
+ states:
+ - ok
+- VerifyTemperature:
+ filters:
+ tags:
+ - pod2-leaf3a
+- VerifyTransceiversManufacturers:
+ filters:
+ tags:
+ - pod2-leaf3a
+ manufacturers:
+ - Arista Networks
+ - Arastra, Inc.
+ - Not Present
+ result_overwrite:
+ custom_field: 'Accepted Manufacturers: ''Arista Networks'', ''Arastra, Inc.'', ''Not Present'''
+- VerifyEnvironmentPower:
+ filters:
+ tags:
+ - pod1-spine2
+ result_overwrite:
+ custom_field: 'Accepted States: ''ok'''
+ states:
+ - ok
+- VerifyEnvironmentCooling:
+ filters:
+ tags:
+ - pod1-spine2
+ result_overwrite:
+ custom_field: 'Accepted States: ''ok'''
+ states:
+ - ok
+- VerifyTemperature:
+ filters:
+ tags:
+ - pod1-spine2
+- VerifyTransceiversManufacturers:
+ filters:
+ tags:
+ - pod1-spine2
+ manufacturers:
+ - Arista Networks
+ - Arastra, Inc.
+ - Not Present
+ result_overwrite:
+ custom_field: 'Accepted Manufacturers: ''Arista Networks'', ''Arastra, Inc.'', ''Not Present'''
+- VerifyEnvironmentPower:
+ filters:
+ tags:
+ - pod2-leaf4a
+ result_overwrite:
+ custom_field: 'Accepted States: ''ok'''
+ states:
+ - ok
+- VerifyEnvironmentCooling:
+ filters:
+ tags:
+ - pod2-leaf4a
+ result_overwrite:
+ custom_field: 'Accepted States: ''ok'''
+ states:
+ - ok
+- VerifyTemperature:
+ filters:
+ tags:
+ - pod2-leaf4a
+- VerifyTransceiversManufacturers:
+ filters:
+ tags:
+ - pod2-leaf4a
+ manufacturers:
+ - Arista Networks
+ - Arastra, Inc.
+ - Not Present
+ result_overwrite:
+ custom_field: 'Accepted Manufacturers: ''Arista Networks'', ''Arastra, Inc.'', ''Not Present'''
+- VerifyEnvironmentPower:
+ filters:
+ tags:
+ - pod1-leaf8b
+ result_overwrite:
+ custom_field: 'Accepted States: ''ok'''
+ states:
+ - ok
+- VerifyEnvironmentCooling:
+ filters:
+ tags:
+ - pod1-leaf8b
+ result_overwrite:
+ custom_field: 'Accepted States: ''ok'''
+ states:
+ - ok
+- VerifyTemperature:
+ filters:
+ tags:
+ - pod1-leaf8b
+- VerifyTransceiversManufacturers:
+ filters:
+ tags:
+ - pod1-leaf8b
+ manufacturers:
+ - Arista Networks
+ - Arastra, Inc.
+ - Not Present
+ result_overwrite:
+ custom_field: 'Accepted Manufacturers: ''Arista Networks'', ''Arastra, Inc.'', ''Not Present'''
+- VerifyEnvironmentPower:
+ filters:
+ tags:
+ - pod1-leaf2a
+ result_overwrite:
+ custom_field: 'Accepted States: ''ok'''
+ states:
+ - ok
+- VerifyEnvironmentCooling:
+ filters:
+ tags:
+ - pod1-leaf2a
+ result_overwrite:
+ custom_field: 'Accepted States: ''ok'''
+ states:
+ - ok
+- VerifyTemperature:
+ filters:
+ tags:
+ - pod1-leaf2a
+- VerifyTransceiversManufacturers:
+ filters:
+ tags:
+ - pod1-leaf2a
+ manufacturers:
+ - Arista Networks
+ - Arastra, Inc.
+ - Not Present
+ result_overwrite:
+ custom_field: 'Accepted Manufacturers: ''Arista Networks'', ''Arastra, Inc.'', ''Not Present'''
+- VerifyEnvironmentPower:
+ filters:
+ tags:
+ - pod1-leaf5a
+ result_overwrite:
+ custom_field: 'Accepted States: ''ok'''
+ states:
+ - ok
+- VerifyEnvironmentCooling:
+ filters:
+ tags:
+ - pod1-leaf5a
+ result_overwrite:
+ custom_field: 'Accepted States: ''ok'''
+ states:
+ - ok
+- VerifyTemperature:
+ filters:
+ tags:
+ - pod1-leaf5a
+- VerifyTransceiversManufacturers:
+ filters:
+ tags:
+ - pod1-leaf5a
+ manufacturers:
+ - Arista Networks
+ - Arastra, Inc.
+ - Not Present
+ result_overwrite:
+ custom_field: 'Accepted Manufacturers: ''Arista Networks'', ''Arastra, Inc.'', ''Not Present'''
+- VerifyEnvironmentPower:
+ filters:
+ tags:
+ - pod2-leaf8b
+ result_overwrite:
+ custom_field: 'Accepted States: ''ok'''
+ states:
+ - ok
+- VerifyEnvironmentCooling:
+ filters:
+ tags:
+ - pod2-leaf8b
+ result_overwrite:
+ custom_field: 'Accepted States: ''ok'''
+ states:
+ - ok
+- VerifyTemperature:
+ filters:
+ tags:
+ - pod2-leaf8b
+- VerifyTransceiversManufacturers:
+ filters:
+ tags:
+ - pod2-leaf8b
+ manufacturers:
+ - Arista Networks
+ - Arastra, Inc.
+ - Not Present
+ result_overwrite:
+ custom_field: 'Accepted Manufacturers: ''Arista Networks'', ''Arastra, Inc.'', ''Not Present'''
+- VerifyEnvironmentPower:
+ filters:
+ tags:
+ - pod2-leaf5a
+ result_overwrite:
+ custom_field: 'Accepted States: ''ok'''
+ states:
+ - ok
+- VerifyEnvironmentCooling:
+ filters:
+ tags:
+ - pod2-leaf5a
+ result_overwrite:
+ custom_field: 'Accepted States: ''ok'''
+ states:
+ - ok
+- VerifyTemperature:
+ filters:
+ tags:
+ - pod2-leaf5a
+- VerifyTransceiversManufacturers:
+ filters:
+ tags:
+ - pod2-leaf5a
+ manufacturers:
+ - Arista Networks
+ - Arastra, Inc.
+ - Not Present
+ result_overwrite:
+ custom_field: 'Accepted Manufacturers: ''Arista Networks'', ''Arastra, Inc.'', ''Not Present'''
+- VerifyEnvironmentPower:
+ filters:
+ tags:
+ - pod2-leaf2a
+ result_overwrite:
+ custom_field: 'Accepted States: ''ok'''
+ states:
+ - ok
+- VerifyEnvironmentCooling:
+ filters:
+ tags:
+ - pod2-leaf2a
+ result_overwrite:
+ custom_field: 'Accepted States: ''ok'''
+ states:
+ - ok
+- VerifyTemperature:
+ filters:
+ tags:
+ - pod2-leaf2a
+- VerifyTransceiversManufacturers:
+ filters:
+ tags:
+ - pod2-leaf2a
+ manufacturers:
+ - Arista Networks
+ - Arastra, Inc.
+ - Not Present
+ result_overwrite:
+ custom_field: 'Accepted Manufacturers: ''Arista Networks'', ''Arastra, Inc.'', ''Not Present'''
+- VerifyEnvironmentPower:
+ filters:
+ tags:
+ - pod1-leaf9b
+ result_overwrite:
+ custom_field: 'Accepted States: ''ok'''
+ states:
+ - ok
+- VerifyEnvironmentCooling:
+ filters:
+ tags:
+ - pod1-leaf9b
+ result_overwrite:
+ custom_field: 'Accepted States: ''ok'''
+ states:
+ - ok
+- VerifyTemperature:
+ filters:
+ tags:
+ - pod1-leaf9b
+- VerifyTransceiversManufacturers:
+ filters:
+ tags:
+ - pod1-leaf9b
+ manufacturers:
+ - Arista Networks
+ - Arastra, Inc.
+ - Not Present
+ result_overwrite:
+ custom_field: 'Accepted Manufacturers: ''Arista Networks'', ''Arastra, Inc.'', ''Not Present'''
+- VerifyEnvironmentPower:
+ filters:
+ tags:
+ - pod2-spine2
+ result_overwrite:
+ custom_field: 'Accepted States: ''ok'''
+ states:
+ - ok
+- VerifyEnvironmentCooling:
+ filters:
+ tags:
+ - pod2-spine2
+ result_overwrite:
+ custom_field: 'Accepted States: ''ok'''
+ states:
+ - ok
+- VerifyTemperature:
+ filters:
+ tags:
+ - pod2-spine2
+- VerifyTransceiversManufacturers:
+ filters:
+ tags:
+ - pod2-spine2
+ manufacturers:
+ - Arista Networks
+ - Arastra, Inc.
+ - Not Present
+ result_overwrite:
+ custom_field: 'Accepted Manufacturers: ''Arista Networks'', ''Arastra, Inc.'', ''Not Present'''
+- VerifyEnvironmentPower:
+ filters:
+ tags:
+ - pod1-leaf4a
+ result_overwrite:
+ custom_field: 'Accepted States: ''ok'''
+ states:
+ - ok
+- VerifyEnvironmentCooling:
+ filters:
+ tags:
+ - pod1-leaf4a
+ result_overwrite:
+ custom_field: 'Accepted States: ''ok'''
+ states:
+ - ok
+- VerifyTemperature:
+ filters:
+ tags:
+ - pod1-leaf4a
+- VerifyTransceiversManufacturers:
+ filters:
+ tags:
+ - pod1-leaf4a
+ manufacturers:
+ - Arista Networks
+ - Arastra, Inc.
+ - Not Present
+ result_overwrite:
+ custom_field: 'Accepted Manufacturers: ''Arista Networks'', ''Arastra, Inc.'', ''Not Present'''
+- VerifyEnvironmentPower:
+ filters:
+ tags:
+ - pod1-leaf3a
+ result_overwrite:
+ custom_field: 'Accepted States: ''ok'''
+ states:
+ - ok
+- VerifyEnvironmentCooling:
+ filters:
+ tags:
+ - pod1-leaf3a
+ result_overwrite:
+ custom_field: 'Accepted States: ''ok'''
+ states:
+ - ok
+- VerifyTemperature:
+ filters:
+ tags:
+ - pod1-leaf3a
+- VerifyTransceiversManufacturers:
+ filters:
+ tags:
+ - pod1-leaf3a
+ manufacturers:
+ - Arista Networks
+ - Arastra, Inc.
+ - Not Present
+ result_overwrite:
+ custom_field: 'Accepted Manufacturers: ''Arista Networks'', ''Arastra, Inc.'', ''Not Present'''
+- VerifyEnvironmentPower:
+ filters:
+ tags:
+ - pod2-leaf7a
+ result_overwrite:
+ custom_field: 'Accepted States: ''ok'''
+ states:
+ - ok
+- VerifyEnvironmentCooling:
+ filters:
+ tags:
+ - pod2-leaf7a
+ result_overwrite:
+ custom_field: 'Accepted States: ''ok'''
+ states:
+ - ok
+- VerifyTemperature:
+ filters:
+ tags:
+ - pod2-leaf7a
+- VerifyTransceiversManufacturers:
+ filters:
+ tags:
+ - pod2-leaf7a
+ manufacturers:
+ - Arista Networks
+ - Arastra, Inc.
+ - Not Present
+ result_overwrite:
+ custom_field: 'Accepted Manufacturers: ''Arista Networks'', ''Arastra, Inc.'', ''Not Present'''
+- VerifyEnvironmentPower:
+ filters:
+ tags:
+ - pod1-leaf1a
+ result_overwrite:
+ custom_field: 'Accepted States: ''ok'''
+ states:
+ - ok
+- VerifyEnvironmentCooling:
+ filters:
+ tags:
+ - pod1-leaf1a
+ result_overwrite:
+ custom_field: 'Accepted States: ''ok'''
+ states:
+ - ok
+- VerifyTemperature:
+ filters:
+ tags:
+ - pod1-leaf1a
+- VerifyTransceiversManufacturers:
+ filters:
+ tags:
+ - pod1-leaf1a
+ manufacturers:
+ - Arista Networks
+ - Arastra, Inc.
+ - Not Present
+ result_overwrite:
+ custom_field: 'Accepted Manufacturers: ''Arista Networks'', ''Arastra, Inc.'', ''Not Present'''
+- VerifyEnvironmentPower:
+ filters:
+ tags:
+ - super-spine1
+ result_overwrite:
+ custom_field: 'Accepted States: ''ok'''
+ states:
+ - ok
+- VerifyEnvironmentCooling:
+ filters:
+ tags:
+ - super-spine1
+ result_overwrite:
+ custom_field: 'Accepted States: ''ok'''
+ states:
+ - ok
+- VerifyTemperature:
+ filters:
+ tags:
+ - super-spine1
+- VerifyTransceiversManufacturers:
+ filters:
+ tags:
+ - super-spine1
+ manufacturers:
+ - Arista Networks
+ - Arastra, Inc.
+ - Not Present
+ result_overwrite:
+ custom_field: 'Accepted Manufacturers: ''Arista Networks'', ''Arastra, Inc.'', ''Not Present'''
+- VerifyEnvironmentPower:
+ filters:
+ tags:
+ - pod1-leaf6a
+ result_overwrite:
+ custom_field: 'Accepted States: ''ok'''
+ states:
+ - ok
+- VerifyEnvironmentCooling:
+ filters:
+ tags:
+ - pod1-leaf6a
+ result_overwrite:
+ custom_field: 'Accepted States: ''ok'''
+ states:
+ - ok
+- VerifyTemperature:
+ filters:
+ tags:
+ - pod1-leaf6a
+- VerifyTransceiversManufacturers:
+ filters:
+ tags:
+ - pod1-leaf6a
+ manufacturers:
+ - Arista Networks
+ - Arastra, Inc.
+ - Not Present
+ result_overwrite:
+ custom_field: 'Accepted Manufacturers: ''Arista Networks'', ''Arastra, Inc.'', ''Not Present'''
+- VerifyEnvironmentPower:
+ filters:
+ tags:
+ - pod2-leaf6a
+ result_overwrite:
+ custom_field: 'Accepted States: ''ok'''
+ states:
+ - ok
+- VerifyEnvironmentCooling:
+ filters:
+ tags:
+ - pod2-leaf6a
+ result_overwrite:
+ custom_field: 'Accepted States: ''ok'''
+ states:
+ - ok
+- VerifyTemperature:
+ filters:
+ tags:
+ - pod2-leaf6a
+- VerifyTransceiversManufacturers:
+ filters:
+ tags:
+ - pod2-leaf6a
+ manufacturers:
+ - Arista Networks
+ - Arastra, Inc.
+ - Not Present
+ result_overwrite:
+ custom_field: 'Accepted Manufacturers: ''Arista Networks'', ''Arastra, Inc.'', ''Not Present'''
+- VerifyEnvironmentPower:
+ filters:
+ tags:
+ - pod2-leaf1a
+ result_overwrite:
+ custom_field: 'Accepted States: ''ok'''
+ states:
+ - ok
+- VerifyEnvironmentCooling:
+ filters:
+ tags:
+ - pod2-leaf1a
+ result_overwrite:
+ custom_field: 'Accepted States: ''ok'''
+ states:
+ - ok
+- VerifyTemperature:
+ filters:
+ tags:
+ - pod2-leaf1a
+- VerifyTransceiversManufacturers:
+ filters:
+ tags:
+ - pod2-leaf1a
+ manufacturers:
+ - Arista Networks
+ - Arastra, Inc.
+ - Not Present
+ result_overwrite:
+ custom_field: 'Accepted Manufacturers: ''Arista Networks'', ''Arastra, Inc.'', ''Not Present'''
+- VerifyEnvironmentPower:
+ filters:
+ tags:
+ - pod1-leaf10b
+ result_overwrite:
+ custom_field: 'Accepted States: ''ok'''
+ states:
+ - ok
+- VerifyEnvironmentCooling:
+ filters:
+ tags:
+ - pod1-leaf10b
+ result_overwrite:
+ custom_field: 'Accepted States: ''ok'''
+ states:
+ - ok
+- VerifyTemperature:
+ filters:
+ tags:
+ - pod1-leaf10b
+- VerifyTransceiversManufacturers:
+ filters:
+ tags:
+ - pod1-leaf10b
+ manufacturers:
+ - Arista Networks
+ - Arastra, Inc.
+ - Not Present
+ result_overwrite:
+ custom_field: 'Accepted Manufacturers: ''Arista Networks'', ''Arastra, Inc.'', ''Not Present'''
+- VerifyEnvironmentPower:
+ filters:
+ tags:
+ - pod1-leaf7a
+ result_overwrite:
+ custom_field: 'Accepted States: ''ok'''
+ states:
+ - ok
+- VerifyEnvironmentCooling:
+ filters:
+ tags:
+ - pod1-leaf7a
+ result_overwrite:
+ custom_field: 'Accepted States: ''ok'''
+ states:
+ - ok
+- VerifyTemperature:
+ filters:
+ tags:
+ - pod1-leaf7a
+- VerifyTransceiversManufacturers:
+ filters:
+ tags:
+ - pod1-leaf7a
+ manufacturers:
+ - Arista Networks
+ - Arastra, Inc.
+ - Not Present
+ result_overwrite:
+ custom_field: 'Accepted Manufacturers: ''Arista Networks'', ''Arastra, Inc.'', ''Not Present'''
+- VerifyEnvironmentPower:
+ filters:
+ tags:
+ - pod2-leaf10b
+ result_overwrite:
+ custom_field: 'Accepted States: ''ok'''
+ states:
+ - ok
+- VerifyEnvironmentCooling:
+ filters:
+ tags:
+ - pod2-leaf10b
+ result_overwrite:
+ custom_field: 'Accepted States: ''ok'''
+ states:
+ - ok
+- VerifyTemperature:
+ filters:
+ tags:
+ - pod2-leaf10b
+- VerifyTransceiversManufacturers:
+ filters:
+ tags:
+ - pod2-leaf10b
+ manufacturers:
+ - Arista Networks
+ - Arastra, Inc.
+ - Not Present
+ result_overwrite:
+ custom_field: 'Accepted Manufacturers: ''Arista Networks'', ''Arastra, Inc.'', ''Not Present'''
+- VerifyEnvironmentPower:
+ filters:
+ tags:
+ - pod2-leaf10a
+ result_overwrite:
+ custom_field: 'Accepted States: ''ok'''
+ states:
+ - ok
+- VerifyEnvironmentCooling:
+ filters:
+ tags:
+ - pod2-leaf10a
+ result_overwrite:
+ custom_field: 'Accepted States: ''ok'''
+ states:
+ - ok
+- VerifyTemperature:
+ filters:
+ tags:
+ - pod2-leaf10a
+- VerifyTransceiversManufacturers:
+ filters:
+ tags:
+ - pod2-leaf10a
+ manufacturers:
+ - Arista Networks
+ - Arastra, Inc.
+ - Not Present
+ result_overwrite:
+ custom_field: 'Accepted Manufacturers: ''Arista Networks'', ''Arastra, Inc.'', ''Not Present'''
+- VerifyEnvironmentPower:
+ filters:
+ tags:
+ - pod2-spine3
+ result_overwrite:
+ custom_field: 'Accepted States: ''ok'''
+ states:
+ - ok
+- VerifyEnvironmentCooling:
+ filters:
+ tags:
+ - pod2-spine3
+ result_overwrite:
+ custom_field: 'Accepted States: ''ok'''
+ states:
+ - ok
+- VerifyTemperature:
+ filters:
+ tags:
+ - pod2-spine3
+- VerifyTransceiversManufacturers:
+ filters:
+ tags:
+ - pod2-spine3
+ manufacturers:
+ - Arista Networks
+ - Arastra, Inc.
+ - Not Present
+ result_overwrite:
+ custom_field: 'Accepted Manufacturers: ''Arista Networks'', ''Arastra, Inc.'', ''Not Present'''
+- VerifyEnvironmentPower:
+ filters:
+ tags:
+ - pod1-leaf7b
+ result_overwrite:
+ custom_field: 'Accepted States: ''ok'''
+ states:
+ - ok
+- VerifyEnvironmentCooling:
+ filters:
+ tags:
+ - pod1-leaf7b
+ result_overwrite:
+ custom_field: 'Accepted States: ''ok'''
+ states:
+ - ok
+- VerifyTemperature:
+ filters:
+ tags:
+ - pod1-leaf7b
+- VerifyTransceiversManufacturers:
+ filters:
+ tags:
+ - pod1-leaf7b
+ manufacturers:
+ - Arista Networks
+ - Arastra, Inc.
+ - Not Present
+ result_overwrite:
+ custom_field: 'Accepted Manufacturers: ''Arista Networks'', ''Arastra, Inc.'', ''Not Present'''
+- VerifyEnvironmentPower:
+ filters:
+ tags:
+ - pod1-leaf10a
+ result_overwrite:
+ custom_field: 'Accepted States: ''ok'''
+ states:
+ - ok
+- VerifyEnvironmentCooling:
+ filters:
+ tags:
+ - pod1-leaf10a
+ result_overwrite:
+ custom_field: 'Accepted States: ''ok'''
+ states:
+ - ok
+- VerifyTemperature:
+ filters:
+ tags:
+ - pod1-leaf10a
+- VerifyTransceiversManufacturers:
+ filters:
+ tags:
+ - pod1-leaf10a
+ manufacturers:
+ - Arista Networks
+ - Arastra, Inc.
+ - Not Present
+ result_overwrite:
+ custom_field: 'Accepted Manufacturers: ''Arista Networks'', ''Arastra, Inc.'', ''Not Present'''
+- VerifyEnvironmentPower:
+ filters:
+ tags:
+ - pod2-leaf6b
+ result_overwrite:
+ custom_field: 'Accepted States: ''ok'''
+ states:
+ - ok
+- VerifyEnvironmentCooling:
+ filters:
+ tags:
+ - pod2-leaf6b
+ result_overwrite:
+ custom_field: 'Accepted States: ''ok'''
+ states:
+ - ok
+- VerifyTemperature:
+ filters:
+ tags:
+ - pod2-leaf6b
+- VerifyTransceiversManufacturers:
+ filters:
+ tags:
+ - pod2-leaf6b
+ manufacturers:
+ - Arista Networks
+ - Arastra, Inc.
+ - Not Present
+ result_overwrite:
+ custom_field: 'Accepted Manufacturers: ''Arista Networks'', ''Arastra, Inc.'', ''Not Present'''
+- VerifyEnvironmentPower:
+ filters:
+ tags:
+ - pod2-leaf1b
+ result_overwrite:
+ custom_field: 'Accepted States: ''ok'''
+ states:
+ - ok
+- VerifyEnvironmentCooling:
+ filters:
+ tags:
+ - pod2-leaf1b
+ result_overwrite:
+ custom_field: 'Accepted States: ''ok'''
+ states:
+ - ok
+- VerifyTemperature:
+ filters:
+ tags:
+ - pod2-leaf1b
+- VerifyTransceiversManufacturers:
+ filters:
+ tags:
+ - pod2-leaf1b
+ manufacturers:
+ - Arista Networks
+ - Arastra, Inc.
+ - Not Present
+ result_overwrite:
+ custom_field: 'Accepted Manufacturers: ''Arista Networks'', ''Arastra, Inc.'', ''Not Present'''
+- VerifyEnvironmentPower:
+ filters:
+ tags:
+ - super-spine2
+ result_overwrite:
+ custom_field: 'Accepted States: ''ok'''
+ states:
+ - ok
+- VerifyEnvironmentCooling:
+ filters:
+ tags:
+ - super-spine2
+ result_overwrite:
+ custom_field: 'Accepted States: ''ok'''
+ states:
+ - ok
+- VerifyTemperature:
+ filters:
+ tags:
+ - super-spine2
+- VerifyTransceiversManufacturers:
+ filters:
+ tags:
+ - super-spine2
+ manufacturers:
+ - Arista Networks
+ - Arastra, Inc.
+ - Not Present
+ result_overwrite:
+ custom_field: 'Accepted Manufacturers: ''Arista Networks'', ''Arastra, Inc.'', ''Not Present'''
+- VerifyEnvironmentPower:
+ filters:
+ tags:
+ - pod1-leaf1b
+ result_overwrite:
+ custom_field: 'Accepted States: ''ok'''
+ states:
+ - ok
+- VerifyEnvironmentCooling:
+ filters:
+ tags:
+ - pod1-leaf1b
+ result_overwrite:
+ custom_field: 'Accepted States: ''ok'''
+ states:
+ - ok
+- VerifyTemperature:
+ filters:
+ tags:
+ - pod1-leaf1b
+- VerifyTransceiversManufacturers:
+ filters:
+ tags:
+ - pod1-leaf1b
+ manufacturers:
+ - Arista Networks
+ - Arastra, Inc.
+ - Not Present
+ result_overwrite:
+ custom_field: 'Accepted Manufacturers: ''Arista Networks'', ''Arastra, Inc.'', ''Not Present'''
+- VerifyEnvironmentPower:
+ filters:
+ tags:
+ - pod1-leaf6b
+ result_overwrite:
+ custom_field: 'Accepted States: ''ok'''
+ states:
+ - ok
+- VerifyEnvironmentCooling:
+ filters:
+ tags:
+ - pod1-leaf6b
+ result_overwrite:
+ custom_field: 'Accepted States: ''ok'''
+ states:
+ - ok
+- VerifyTemperature:
+ filters:
+ tags:
+ - pod1-leaf6b
+- VerifyTransceiversManufacturers:
+ filters:
+ tags:
+ - pod1-leaf6b
+ manufacturers:
+ - Arista Networks
+ - Arastra, Inc.
+ - Not Present
+ result_overwrite:
+ custom_field: 'Accepted Manufacturers: ''Arista Networks'', ''Arastra, Inc.'', ''Not Present'''
+- VerifyEnvironmentPower:
+ filters:
+ tags:
+ - pod2-leaf7b
+ result_overwrite:
+ custom_field: 'Accepted States: ''ok'''
+ states:
+ - ok
+- VerifyEnvironmentCooling:
+ filters:
+ tags:
+ - pod2-leaf7b
+ result_overwrite:
+ custom_field: 'Accepted States: ''ok'''
+ states:
+ - ok
+- VerifyTemperature:
+ filters:
+ tags:
+ - pod2-leaf7b
+- VerifyTransceiversManufacturers:
+ filters:
+ tags:
+ - pod2-leaf7b
+ manufacturers:
+ - Arista Networks
+ - Arastra, Inc.
+ - Not Present
+ result_overwrite:
+ custom_field: 'Accepted Manufacturers: ''Arista Networks'', ''Arastra, Inc.'', ''Not Present'''
+- VerifyEnvironmentPower:
+ filters:
+ tags:
+ - pod1-spine3
+ result_overwrite:
+ custom_field: 'Accepted States: ''ok'''
+ states:
+ - ok
+- VerifyEnvironmentCooling:
+ filters:
+ tags:
+ - pod1-spine3
+ result_overwrite:
+ custom_field: 'Accepted States: ''ok'''
+ states:
+ - ok
+- VerifyTemperature:
+ filters:
+ tags:
+ - pod1-spine3
+- VerifyTransceiversManufacturers:
+ filters:
+ tags:
+ - pod1-spine3
+ manufacturers:
+ - Arista Networks
+ - Arastra, Inc.
+ - Not Present
+ result_overwrite:
+ custom_field: 'Accepted Manufacturers: ''Arista Networks'', ''Arastra, Inc.'', ''Not Present'''
+anta.tests.interfaces:
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf4b
+ interfaces:
+ - name: Ethernet53/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet53/1 - MLAG_PEER_pod1-leaf4a_Ethernet53/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf4b
+ interfaces:
+ - name: Ethernet54/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet54/1 - MLAG_PEER_pod1-leaf4a_Ethernet54/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf4b
+ interfaces:
+ - name: Ethernet1/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet1/1 - P2P_LINK_TO_POD1-SPINE1_Ethernet8/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf4b
+ interfaces:
+ - name: Ethernet2/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet2/1 - P2P_LINK_TO_POD1-SPINE2_Ethernet8/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf4b
+ interfaces:
+ - name: Ethernet3/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet3/1 - P2P_LINK_TO_POD1-SPINE3_Ethernet8/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf4b
+ interfaces:
+ - name: Ethernet4/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet4/1 - P2P_LINK_TO_POD1-SPINE4_Ethernet8/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf4b
+ interfaces:
+ - name: Port-Channel531
+ status: up
+ result_overwrite:
+ custom_field: Interface Port-Channel531 - MLAG_PEER_pod1-leaf4a_Po531 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf4b
+ interfaces:
+ - name: Vlan4093
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan4093 - MLAG_PEER_L3_PEERING = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf4b
+ interfaces:
+ - name: Vlan4094
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan4094 - MLAG_PEER = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf4b
+ interfaces:
+ - name: Vlan11
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan11 - VRF10_VLAN11 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf4b
+ interfaces:
+ - name: Vlan12
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan12 - VRF10_VLAN12 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf4b
+ interfaces:
+ - name: Vlan3009
+ status: up
+ result_overwrite:
+ custom_field: 'Interface Vlan3009 - MLAG_PEER_L3_iBGP: vrf VRF10 = ''up'''
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf4b
+ interfaces:
+ - name: Vlan21
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan21 - VRF20_VLAN21 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf4b
+ interfaces:
+ - name: Vlan22
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan22 - VRF20_VLAN22 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf4b
+ interfaces:
+ - name: Vlan3019
+ status: up
+ result_overwrite:
+ custom_field: 'Interface Vlan3019 - MLAG_PEER_L3_iBGP: vrf VRF20 = ''up'''
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf4b
+ interfaces:
+ - name: Loopback0
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback0 - EVPN_Overlay_Peering = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf4b
+ interfaces:
+ - name: Loopback1
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback1 - VTEP_VXLAN_Tunnel_Source = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf4b
+ interfaces:
+ - name: Loopback10
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback10 - VRF10_VTEP_DIAGNOSTICS = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf4b
+ interfaces:
+ - name: Loopback20
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback20 - VRF20_VTEP_DIAGNOSTICS = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf4b
+ interfaces:
+ - name: Vxlan1
+ status: up
+ result_overwrite:
+ custom_field: Interface Vxlan1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-spine1
+ interfaces:
+ - name: Ethernet1/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet1/1 - P2P_LINK_TO_POD2-LEAF1A_Ethernet1/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-spine1
+ interfaces:
+ - name: Ethernet2/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet2/1 - P2P_LINK_TO_POD2-LEAF1B_Ethernet1/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-spine1
+ interfaces:
+ - name: Ethernet3/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet3/1 - P2P_LINK_TO_POD2-LEAF2A_Ethernet1/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-spine1
+ interfaces:
+ - name: Ethernet4/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet4/1 - P2P_LINK_TO_POD2-LEAF2B_Ethernet1/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-spine1
+ interfaces:
+ - name: Ethernet5/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet5/1 - P2P_LINK_TO_POD2-LEAF3A_Ethernet1/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-spine1
+ interfaces:
+ - name: Ethernet6/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet6/1 - P2P_LINK_TO_POD2-LEAF3B_Ethernet1/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-spine1
+ interfaces:
+ - name: Ethernet7/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet7/1 - P2P_LINK_TO_POD2-LEAF4A_Ethernet1/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-spine1
+ interfaces:
+ - name: Ethernet8/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet8/1 - P2P_LINK_TO_POD2-LEAF4B_Ethernet1/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-spine1
+ interfaces:
+ - name: Ethernet9/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet9/1 - P2P_LINK_TO_POD2-LEAF5A_Ethernet1/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-spine1
+ interfaces:
+ - name: Ethernet10/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet10/1 - P2P_LINK_TO_POD2-LEAF5B_Ethernet1/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-spine1
+ interfaces:
+ - name: Ethernet11/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet11/1 - P2P_LINK_TO_POD2-LEAF6A_Ethernet1/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-spine1
+ interfaces:
+ - name: Ethernet12/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet12/1 - P2P_LINK_TO_POD2-LEAF6B_Ethernet1/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-spine1
+ interfaces:
+ - name: Ethernet13/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet13/1 - P2P_LINK_TO_POD2-LEAF7A_Ethernet1/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-spine1
+ interfaces:
+ - name: Ethernet14/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet14/1 - P2P_LINK_TO_POD2-LEAF7B_Ethernet1/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-spine1
+ interfaces:
+ - name: Ethernet15/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet15/1 - P2P_LINK_TO_POD2-LEAF8A_Ethernet1/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-spine1
+ interfaces:
+ - name: Ethernet16/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet16/1 - P2P_LINK_TO_POD2-LEAF8B_Ethernet1/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-spine1
+ interfaces:
+ - name: Ethernet17/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet17/1 - P2P_LINK_TO_POD2-LEAF9A_Ethernet1/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-spine1
+ interfaces:
+ - name: Ethernet18/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet18/1 - P2P_LINK_TO_POD2-LEAF9B_Ethernet1/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-spine1
+ interfaces:
+ - name: Ethernet19/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet19/1 - P2P_LINK_TO_POD2-LEAF10A_Ethernet1/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-spine1
+ interfaces:
+ - name: Ethernet20/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet20/1 - P2P_LINK_TO_POD2-LEAF10B_Ethernet1/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-spine1
+ interfaces:
+ - name: Ethernet31/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet31/1 - P2P_LINK_TO_SUPER-SPINE1_Ethernet5/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-spine1
+ interfaces:
+ - name: Ethernet32/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet32/1 - P2P_LINK_TO_SUPER-SPINE2_Ethernet5/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-spine1
+ interfaces:
+ - name: Loopback0
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback0 - EVPN_Overlay_Peering = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf3b
+ interfaces:
+ - name: Ethernet53/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet53/1 - MLAG_PEER_pod1-leaf3a_Ethernet53/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf3b
+ interfaces:
+ - name: Ethernet54/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet54/1 - MLAG_PEER_pod1-leaf3a_Ethernet54/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf3b
+ interfaces:
+ - name: Ethernet1/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet1/1 - P2P_LINK_TO_POD1-SPINE1_Ethernet6/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf3b
+ interfaces:
+ - name: Ethernet2/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet2/1 - P2P_LINK_TO_POD1-SPINE2_Ethernet6/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf3b
+ interfaces:
+ - name: Ethernet3/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet3/1 - P2P_LINK_TO_POD1-SPINE3_Ethernet6/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf3b
+ interfaces:
+ - name: Ethernet4/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet4/1 - P2P_LINK_TO_POD1-SPINE4_Ethernet6/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf3b
+ interfaces:
+ - name: Port-Channel531
+ status: up
+ result_overwrite:
+ custom_field: Interface Port-Channel531 - MLAG_PEER_pod1-leaf3a_Po531 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf3b
+ interfaces:
+ - name: Vlan4093
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan4093 - MLAG_PEER_L3_PEERING = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf3b
+ interfaces:
+ - name: Vlan4094
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan4094 - MLAG_PEER = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf3b
+ interfaces:
+ - name: Vlan11
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan11 - VRF10_VLAN11 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf3b
+ interfaces:
+ - name: Vlan12
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan12 - VRF10_VLAN12 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf3b
+ interfaces:
+ - name: Vlan3009
+ status: up
+ result_overwrite:
+ custom_field: 'Interface Vlan3009 - MLAG_PEER_L3_iBGP: vrf VRF10 = ''up'''
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf3b
+ interfaces:
+ - name: Vlan21
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan21 - VRF20_VLAN21 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf3b
+ interfaces:
+ - name: Vlan22
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan22 - VRF20_VLAN22 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf3b
+ interfaces:
+ - name: Vlan3019
+ status: up
+ result_overwrite:
+ custom_field: 'Interface Vlan3019 - MLAG_PEER_L3_iBGP: vrf VRF20 = ''up'''
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf3b
+ interfaces:
+ - name: Loopback0
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback0 - EVPN_Overlay_Peering = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf3b
+ interfaces:
+ - name: Loopback1
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback1 - VTEP_VXLAN_Tunnel_Source = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf3b
+ interfaces:
+ - name: Loopback10
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback10 - VRF10_VTEP_DIAGNOSTICS = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf3b
+ interfaces:
+ - name: Loopback20
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback20 - VRF20_VTEP_DIAGNOSTICS = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf3b
+ interfaces:
+ - name: Vxlan1
+ status: up
+ result_overwrite:
+ custom_field: Interface Vxlan1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf9a
+ interfaces:
+ - name: Ethernet53/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet53/1 - MLAG_PEER_pod1-leaf9b_Ethernet53/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf9a
+ interfaces:
+ - name: Ethernet54/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet54/1 - MLAG_PEER_pod1-leaf9b_Ethernet54/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf9a
+ interfaces:
+ - name: Ethernet1/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet1/1 - P2P_LINK_TO_POD1-SPINE1_Ethernet17/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf9a
+ interfaces:
+ - name: Ethernet2/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet2/1 - P2P_LINK_TO_POD1-SPINE2_Ethernet17/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf9a
+ interfaces:
+ - name: Ethernet3/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet3/1 - P2P_LINK_TO_POD1-SPINE3_Ethernet17/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf9a
+ interfaces:
+ - name: Ethernet4/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet4/1 - P2P_LINK_TO_POD1-SPINE4_Ethernet17/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf9a
+ interfaces:
+ - name: Port-Channel531
+ status: up
+ result_overwrite:
+ custom_field: Interface Port-Channel531 - MLAG_PEER_pod1-leaf9b_Po531 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf9a
+ interfaces:
+ - name: Vlan4093
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan4093 - MLAG_PEER_L3_PEERING = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf9a
+ interfaces:
+ - name: Vlan4094
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan4094 - MLAG_PEER = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf9a
+ interfaces:
+ - name: Vlan11
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan11 - VRF10_VLAN11 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf9a
+ interfaces:
+ - name: Vlan12
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan12 - VRF10_VLAN12 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf9a
+ interfaces:
+ - name: Vlan3009
+ status: up
+ result_overwrite:
+ custom_field: 'Interface Vlan3009 - MLAG_PEER_L3_iBGP: vrf VRF10 = ''up'''
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf9a
+ interfaces:
+ - name: Vlan21
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan21 - VRF20_VLAN21 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf9a
+ interfaces:
+ - name: Vlan22
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan22 - VRF20_VLAN22 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf9a
+ interfaces:
+ - name: Vlan3019
+ status: up
+ result_overwrite:
+ custom_field: 'Interface Vlan3019 - MLAG_PEER_L3_iBGP: vrf VRF20 = ''up'''
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf9a
+ interfaces:
+ - name: Loopback0
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback0 - EVPN_Overlay_Peering = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf9a
+ interfaces:
+ - name: Loopback1
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback1 - VTEP_VXLAN_Tunnel_Source = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf9a
+ interfaces:
+ - name: Loopback10
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback10 - VRF10_VTEP_DIAGNOSTICS = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf9a
+ interfaces:
+ - name: Loopback20
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback20 - VRF20_VTEP_DIAGNOSTICS = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf9a
+ interfaces:
+ - name: Vxlan1
+ status: up
+ result_overwrite:
+ custom_field: Interface Vxlan1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-spine4
+ interfaces:
+ - name: Ethernet1/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet1/1 - P2P_LINK_TO_POD1-LEAF1A_Ethernet4/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-spine4
+ interfaces:
+ - name: Ethernet2/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet2/1 - P2P_LINK_TO_POD1-LEAF1B_Ethernet4/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-spine4
+ interfaces:
+ - name: Ethernet3/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet3/1 - P2P_LINK_TO_POD1-LEAF2A_Ethernet4/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-spine4
+ interfaces:
+ - name: Ethernet4/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet4/1 - P2P_LINK_TO_POD1-LEAF2B_Ethernet4/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-spine4
+ interfaces:
+ - name: Ethernet5/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet5/1 - P2P_LINK_TO_POD1-LEAF3A_Ethernet4/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-spine4
+ interfaces:
+ - name: Ethernet6/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet6/1 - P2P_LINK_TO_POD1-LEAF3B_Ethernet4/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-spine4
+ interfaces:
+ - name: Ethernet7/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet7/1 - P2P_LINK_TO_POD1-LEAF4A_Ethernet4/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-spine4
+ interfaces:
+ - name: Ethernet8/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet8/1 - P2P_LINK_TO_POD1-LEAF4B_Ethernet4/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-spine4
+ interfaces:
+ - name: Ethernet9/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet9/1 - P2P_LINK_TO_POD1-LEAF5A_Ethernet4/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-spine4
+ interfaces:
+ - name: Ethernet10/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet10/1 - P2P_LINK_TO_POD1-LEAF5B_Ethernet4/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-spine4
+ interfaces:
+ - name: Ethernet11/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet11/1 - P2P_LINK_TO_POD1-LEAF6A_Ethernet4/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-spine4
+ interfaces:
+ - name: Ethernet12/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet12/1 - P2P_LINK_TO_POD1-LEAF6B_Ethernet4/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-spine4
+ interfaces:
+ - name: Ethernet13/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet13/1 - P2P_LINK_TO_POD1-LEAF7A_Ethernet4/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-spine4
+ interfaces:
+ - name: Ethernet14/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet14/1 - P2P_LINK_TO_POD1-LEAF7B_Ethernet4/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-spine4
+ interfaces:
+ - name: Ethernet15/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet15/1 - P2P_LINK_TO_POD1-LEAF8A_Ethernet4/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-spine4
+ interfaces:
+ - name: Ethernet16/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet16/1 - P2P_LINK_TO_POD1-LEAF8B_Ethernet4/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-spine4
+ interfaces:
+ - name: Ethernet17/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet17/1 - P2P_LINK_TO_POD1-LEAF9A_Ethernet4/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-spine4
+ interfaces:
+ - name: Ethernet18/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet18/1 - P2P_LINK_TO_POD1-LEAF9B_Ethernet4/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-spine4
+ interfaces:
+ - name: Ethernet19/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet19/1 - P2P_LINK_TO_POD1-LEAF10A_Ethernet4/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-spine4
+ interfaces:
+ - name: Ethernet20/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet20/1 - P2P_LINK_TO_POD1-LEAF10B_Ethernet4/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-spine4
+ interfaces:
+ - name: Ethernet31/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet31/1 - P2P_LINK_TO_SUPER-SPINE1_Ethernet4/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-spine4
+ interfaces:
+ - name: Ethernet32/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet32/1 - P2P_LINK_TO_SUPER-SPINE2_Ethernet4/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-spine4
+ interfaces:
+ - name: Loopback0
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback0 - EVPN_Overlay_Peering = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf5b
+ interfaces:
+ - name: Ethernet53/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet53/1 - MLAG_PEER_pod2-leaf5a_Ethernet53/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf5b
+ interfaces:
+ - name: Ethernet54/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet54/1 - MLAG_PEER_pod2-leaf5a_Ethernet54/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf5b
+ interfaces:
+ - name: Ethernet1/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet1/1 - P2P_LINK_TO_POD2-SPINE1_Ethernet10/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf5b
+ interfaces:
+ - name: Ethernet2/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet2/1 - P2P_LINK_TO_POD2-SPINE2_Ethernet10/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf5b
+ interfaces:
+ - name: Ethernet3/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet3/1 - P2P_LINK_TO_POD2-SPINE3_Ethernet10/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf5b
+ interfaces:
+ - name: Ethernet4/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet4/1 - P2P_LINK_TO_POD2-SPINE4_Ethernet10/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf5b
+ interfaces:
+ - name: Port-Channel531
+ status: up
+ result_overwrite:
+ custom_field: Interface Port-Channel531 - MLAG_PEER_pod2-leaf5a_Po531 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf5b
+ interfaces:
+ - name: Vlan4093
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan4093 - MLAG_PEER_L3_PEERING = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf5b
+ interfaces:
+ - name: Vlan4094
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan4094 - MLAG_PEER = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf5b
+ interfaces:
+ - name: Vlan11
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan11 - VRF10_VLAN11 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf5b
+ interfaces:
+ - name: Vlan12
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan12 - VRF10_VLAN12 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf5b
+ interfaces:
+ - name: Vlan3009
+ status: up
+ result_overwrite:
+ custom_field: 'Interface Vlan3009 - MLAG_PEER_L3_iBGP: vrf VRF10 = ''up'''
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf5b
+ interfaces:
+ - name: Vlan21
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan21 - VRF20_VLAN21 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf5b
+ interfaces:
+ - name: Vlan22
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan22 - VRF20_VLAN22 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf5b
+ interfaces:
+ - name: Vlan3019
+ status: up
+ result_overwrite:
+ custom_field: 'Interface Vlan3019 - MLAG_PEER_L3_iBGP: vrf VRF20 = ''up'''
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf5b
+ interfaces:
+ - name: Loopback0
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback0 - EVPN_Overlay_Peering = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf5b
+ interfaces:
+ - name: Loopback1
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback1 - VTEP_VXLAN_Tunnel_Source = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf5b
+ interfaces:
+ - name: Loopback10
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback10 - VRF10_VTEP_DIAGNOSTICS = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf5b
+ interfaces:
+ - name: Loopback20
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback20 - VRF20_VTEP_DIAGNOSTICS = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf5b
+ interfaces:
+ - name: Vxlan1
+ status: up
+ result_overwrite:
+ custom_field: Interface Vxlan1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf2b
+ interfaces:
+ - name: Ethernet53/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet53/1 - MLAG_PEER_pod2-leaf2a_Ethernet53/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf2b
+ interfaces:
+ - name: Ethernet54/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet54/1 - MLAG_PEER_pod2-leaf2a_Ethernet54/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf2b
+ interfaces:
+ - name: Ethernet1/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet1/1 - P2P_LINK_TO_POD2-SPINE1_Ethernet4/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf2b
+ interfaces:
+ - name: Ethernet2/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet2/1 - P2P_LINK_TO_POD2-SPINE2_Ethernet4/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf2b
+ interfaces:
+ - name: Ethernet3/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet3/1 - P2P_LINK_TO_POD2-SPINE3_Ethernet4/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf2b
+ interfaces:
+ - name: Ethernet4/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet4/1 - P2P_LINK_TO_POD2-SPINE4_Ethernet4/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf2b
+ interfaces:
+ - name: Port-Channel531
+ status: up
+ result_overwrite:
+ custom_field: Interface Port-Channel531 - MLAG_PEER_pod2-leaf2a_Po531 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf2b
+ interfaces:
+ - name: Vlan4093
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan4093 - MLAG_PEER_L3_PEERING = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf2b
+ interfaces:
+ - name: Vlan4094
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan4094 - MLAG_PEER = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf2b
+ interfaces:
+ - name: Vlan11
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan11 - VRF10_VLAN11 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf2b
+ interfaces:
+ - name: Vlan12
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan12 - VRF10_VLAN12 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf2b
+ interfaces:
+ - name: Vlan3009
+ status: up
+ result_overwrite:
+ custom_field: 'Interface Vlan3009 - MLAG_PEER_L3_iBGP: vrf VRF10 = ''up'''
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf2b
+ interfaces:
+ - name: Vlan21
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan21 - VRF20_VLAN21 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf2b
+ interfaces:
+ - name: Vlan22
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan22 - VRF20_VLAN22 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf2b
+ interfaces:
+ - name: Vlan3019
+ status: up
+ result_overwrite:
+ custom_field: 'Interface Vlan3019 - MLAG_PEER_L3_iBGP: vrf VRF20 = ''up'''
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf2b
+ interfaces:
+ - name: Loopback0
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback0 - EVPN_Overlay_Peering = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf2b
+ interfaces:
+ - name: Loopback1
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback1 - VTEP_VXLAN_Tunnel_Source = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf2b
+ interfaces:
+ - name: Loopback10
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback10 - VRF10_VTEP_DIAGNOSTICS = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf2b
+ interfaces:
+ - name: Loopback20
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback20 - VRF20_VTEP_DIAGNOSTICS = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf2b
+ interfaces:
+ - name: Vxlan1
+ status: up
+ result_overwrite:
+ custom_field: Interface Vxlan1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf8a
+ interfaces:
+ - name: Ethernet53/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet53/1 - MLAG_PEER_pod2-leaf8b_Ethernet53/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf8a
+ interfaces:
+ - name: Ethernet54/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet54/1 - MLAG_PEER_pod2-leaf8b_Ethernet54/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf8a
+ interfaces:
+ - name: Ethernet1/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet1/1 - P2P_LINK_TO_POD2-SPINE1_Ethernet15/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf8a
+ interfaces:
+ - name: Ethernet2/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet2/1 - P2P_LINK_TO_POD2-SPINE2_Ethernet15/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf8a
+ interfaces:
+ - name: Ethernet3/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet3/1 - P2P_LINK_TO_POD2-SPINE3_Ethernet15/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf8a
+ interfaces:
+ - name: Ethernet4/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet4/1 - P2P_LINK_TO_POD2-SPINE4_Ethernet15/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf8a
+ interfaces:
+ - name: Port-Channel531
+ status: up
+ result_overwrite:
+ custom_field: Interface Port-Channel531 - MLAG_PEER_pod2-leaf8b_Po531 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf8a
+ interfaces:
+ - name: Vlan4093
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan4093 - MLAG_PEER_L3_PEERING = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf8a
+ interfaces:
+ - name: Vlan4094
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan4094 - MLAG_PEER = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf8a
+ interfaces:
+ - name: Vlan11
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan11 - VRF10_VLAN11 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf8a
+ interfaces:
+ - name: Vlan12
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan12 - VRF10_VLAN12 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf8a
+ interfaces:
+ - name: Vlan3009
+ status: up
+ result_overwrite:
+ custom_field: 'Interface Vlan3009 - MLAG_PEER_L3_iBGP: vrf VRF10 = ''up'''
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf8a
+ interfaces:
+ - name: Vlan21
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan21 - VRF20_VLAN21 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf8a
+ interfaces:
+ - name: Vlan22
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan22 - VRF20_VLAN22 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf8a
+ interfaces:
+ - name: Vlan3019
+ status: up
+ result_overwrite:
+ custom_field: 'Interface Vlan3019 - MLAG_PEER_L3_iBGP: vrf VRF20 = ''up'''
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf8a
+ interfaces:
+ - name: Loopback0
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback0 - EVPN_Overlay_Peering = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf8a
+ interfaces:
+ - name: Loopback1
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback1 - VTEP_VXLAN_Tunnel_Source = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf8a
+ interfaces:
+ - name: Loopback10
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback10 - VRF10_VTEP_DIAGNOSTICS = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf8a
+ interfaces:
+ - name: Loopback20
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback20 - VRF20_VTEP_DIAGNOSTICS = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf8a
+ interfaces:
+ - name: Vxlan1
+ status: up
+ result_overwrite:
+ custom_field: Interface Vxlan1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf2b
+ interfaces:
+ - name: Ethernet53/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet53/1 - MLAG_PEER_pod1-leaf2a_Ethernet53/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf2b
+ interfaces:
+ - name: Ethernet54/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet54/1 - MLAG_PEER_pod1-leaf2a_Ethernet54/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf2b
+ interfaces:
+ - name: Ethernet1/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet1/1 - P2P_LINK_TO_POD1-SPINE1_Ethernet4/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf2b
+ interfaces:
+ - name: Ethernet2/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet2/1 - P2P_LINK_TO_POD1-SPINE2_Ethernet4/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf2b
+ interfaces:
+ - name: Ethernet3/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet3/1 - P2P_LINK_TO_POD1-SPINE3_Ethernet4/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf2b
+ interfaces:
+ - name: Ethernet4/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet4/1 - P2P_LINK_TO_POD1-SPINE4_Ethernet4/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf2b
+ interfaces:
+ - name: Port-Channel531
+ status: up
+ result_overwrite:
+ custom_field: Interface Port-Channel531 - MLAG_PEER_pod1-leaf2a_Po531 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf2b
+ interfaces:
+ - name: Vlan4093
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan4093 - MLAG_PEER_L3_PEERING = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf2b
+ interfaces:
+ - name: Vlan4094
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan4094 - MLAG_PEER = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf2b
+ interfaces:
+ - name: Vlan11
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan11 - VRF10_VLAN11 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf2b
+ interfaces:
+ - name: Vlan12
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan12 - VRF10_VLAN12 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf2b
+ interfaces:
+ - name: Vlan3009
+ status: up
+ result_overwrite:
+ custom_field: 'Interface Vlan3009 - MLAG_PEER_L3_iBGP: vrf VRF10 = ''up'''
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf2b
+ interfaces:
+ - name: Vlan21
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan21 - VRF20_VLAN21 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf2b
+ interfaces:
+ - name: Vlan22
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan22 - VRF20_VLAN22 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf2b
+ interfaces:
+ - name: Vlan3019
+ status: up
+ result_overwrite:
+ custom_field: 'Interface Vlan3019 - MLAG_PEER_L3_iBGP: vrf VRF20 = ''up'''
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf2b
+ interfaces:
+ - name: Loopback0
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback0 - EVPN_Overlay_Peering = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf2b
+ interfaces:
+ - name: Loopback1
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback1 - VTEP_VXLAN_Tunnel_Source = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf2b
+ interfaces:
+ - name: Loopback10
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback10 - VRF10_VTEP_DIAGNOSTICS = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf2b
+ interfaces:
+ - name: Loopback20
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback20 - VRF20_VTEP_DIAGNOSTICS = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf2b
+ interfaces:
+ - name: Vxlan1
+ status: up
+ result_overwrite:
+ custom_field: Interface Vxlan1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf5b
+ interfaces:
+ - name: Ethernet53/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet53/1 - MLAG_PEER_pod1-leaf5a_Ethernet53/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf5b
+ interfaces:
+ - name: Ethernet54/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet54/1 - MLAG_PEER_pod1-leaf5a_Ethernet54/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf5b
+ interfaces:
+ - name: Ethernet1/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet1/1 - P2P_LINK_TO_POD1-SPINE1_Ethernet10/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf5b
+ interfaces:
+ - name: Ethernet2/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet2/1 - P2P_LINK_TO_POD1-SPINE2_Ethernet10/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf5b
+ interfaces:
+ - name: Ethernet3/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet3/1 - P2P_LINK_TO_POD1-SPINE3_Ethernet10/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf5b
+ interfaces:
+ - name: Ethernet4/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet4/1 - P2P_LINK_TO_POD1-SPINE4_Ethernet10/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf5b
+ interfaces:
+ - name: Port-Channel531
+ status: up
+ result_overwrite:
+ custom_field: Interface Port-Channel531 - MLAG_PEER_pod1-leaf5a_Po531 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf5b
+ interfaces:
+ - name: Vlan4093
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan4093 - MLAG_PEER_L3_PEERING = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf5b
+ interfaces:
+ - name: Vlan4094
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan4094 - MLAG_PEER = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf5b
+ interfaces:
+ - name: Vlan11
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan11 - VRF10_VLAN11 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf5b
+ interfaces:
+ - name: Vlan12
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan12 - VRF10_VLAN12 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf5b
+ interfaces:
+ - name: Vlan3009
+ status: up
+ result_overwrite:
+ custom_field: 'Interface Vlan3009 - MLAG_PEER_L3_iBGP: vrf VRF10 = ''up'''
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf5b
+ interfaces:
+ - name: Vlan21
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan21 - VRF20_VLAN21 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf5b
+ interfaces:
+ - name: Vlan22
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan22 - VRF20_VLAN22 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf5b
+ interfaces:
+ - name: Vlan3019
+ status: up
+ result_overwrite:
+ custom_field: 'Interface Vlan3019 - MLAG_PEER_L3_iBGP: vrf VRF20 = ''up'''
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf5b
+ interfaces:
+ - name: Loopback0
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback0 - EVPN_Overlay_Peering = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf5b
+ interfaces:
+ - name: Loopback1
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback1 - VTEP_VXLAN_Tunnel_Source = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf5b
+ interfaces:
+ - name: Loopback10
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback10 - VRF10_VTEP_DIAGNOSTICS = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf5b
+ interfaces:
+ - name: Loopback20
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback20 - VRF20_VTEP_DIAGNOSTICS = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf5b
+ interfaces:
+ - name: Vxlan1
+ status: up
+ result_overwrite:
+ custom_field: Interface Vxlan1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf8a
+ interfaces:
+ - name: Ethernet53/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet53/1 - MLAG_PEER_pod1-leaf8b_Ethernet53/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf8a
+ interfaces:
+ - name: Ethernet54/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet54/1 - MLAG_PEER_pod1-leaf8b_Ethernet54/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf8a
+ interfaces:
+ - name: Ethernet1/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet1/1 - P2P_LINK_TO_POD1-SPINE1_Ethernet15/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf8a
+ interfaces:
+ - name: Ethernet2/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet2/1 - P2P_LINK_TO_POD1-SPINE2_Ethernet15/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf8a
+ interfaces:
+ - name: Ethernet3/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet3/1 - P2P_LINK_TO_POD1-SPINE3_Ethernet15/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf8a
+ interfaces:
+ - name: Ethernet4/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet4/1 - P2P_LINK_TO_POD1-SPINE4_Ethernet15/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf8a
+ interfaces:
+ - name: Port-Channel531
+ status: up
+ result_overwrite:
+ custom_field: Interface Port-Channel531 - MLAG_PEER_pod1-leaf8b_Po531 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf8a
+ interfaces:
+ - name: Vlan4093
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan4093 - MLAG_PEER_L3_PEERING = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf8a
+ interfaces:
+ - name: Vlan4094
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan4094 - MLAG_PEER = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf8a
+ interfaces:
+ - name: Vlan11
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan11 - VRF10_VLAN11 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf8a
+ interfaces:
+ - name: Vlan12
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan12 - VRF10_VLAN12 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf8a
+ interfaces:
+ - name: Vlan3009
+ status: up
+ result_overwrite:
+ custom_field: 'Interface Vlan3009 - MLAG_PEER_L3_iBGP: vrf VRF10 = ''up'''
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf8a
+ interfaces:
+ - name: Vlan21
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan21 - VRF20_VLAN21 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf8a
+ interfaces:
+ - name: Vlan22
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan22 - VRF20_VLAN22 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf8a
+ interfaces:
+ - name: Vlan3019
+ status: up
+ result_overwrite:
+ custom_field: 'Interface Vlan3019 - MLAG_PEER_L3_iBGP: vrf VRF20 = ''up'''
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf8a
+ interfaces:
+ - name: Loopback0
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback0 - EVPN_Overlay_Peering = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf8a
+ interfaces:
+ - name: Loopback1
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback1 - VTEP_VXLAN_Tunnel_Source = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf8a
+ interfaces:
+ - name: Loopback10
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback10 - VRF10_VTEP_DIAGNOSTICS = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf8a
+ interfaces:
+ - name: Loopback20
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback20 - VRF20_VTEP_DIAGNOSTICS = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf8a
+ interfaces:
+ - name: Vxlan1
+ status: up
+ result_overwrite:
+ custom_field: Interface Vxlan1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-spine4
+ interfaces:
+ - name: Ethernet1/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet1/1 - P2P_LINK_TO_POD2-LEAF1A_Ethernet4/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-spine4
+ interfaces:
+ - name: Ethernet2/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet2/1 - P2P_LINK_TO_POD2-LEAF1B_Ethernet4/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-spine4
+ interfaces:
+ - name: Ethernet3/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet3/1 - P2P_LINK_TO_POD2-LEAF2A_Ethernet4/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-spine4
+ interfaces:
+ - name: Ethernet4/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet4/1 - P2P_LINK_TO_POD2-LEAF2B_Ethernet4/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-spine4
+ interfaces:
+ - name: Ethernet5/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet5/1 - P2P_LINK_TO_POD2-LEAF3A_Ethernet4/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-spine4
+ interfaces:
+ - name: Ethernet6/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet6/1 - P2P_LINK_TO_POD2-LEAF3B_Ethernet4/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-spine4
+ interfaces:
+ - name: Ethernet7/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet7/1 - P2P_LINK_TO_POD2-LEAF4A_Ethernet4/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-spine4
+ interfaces:
+ - name: Ethernet8/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet8/1 - P2P_LINK_TO_POD2-LEAF4B_Ethernet4/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-spine4
+ interfaces:
+ - name: Ethernet9/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet9/1 - P2P_LINK_TO_POD2-LEAF5A_Ethernet4/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-spine4
+ interfaces:
+ - name: Ethernet10/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet10/1 - P2P_LINK_TO_POD2-LEAF5B_Ethernet4/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-spine4
+ interfaces:
+ - name: Ethernet11/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet11/1 - P2P_LINK_TO_POD2-LEAF6A_Ethernet4/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-spine4
+ interfaces:
+ - name: Ethernet12/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet12/1 - P2P_LINK_TO_POD2-LEAF6B_Ethernet4/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-spine4
+ interfaces:
+ - name: Ethernet13/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet13/1 - P2P_LINK_TO_POD2-LEAF7A_Ethernet4/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-spine4
+ interfaces:
+ - name: Ethernet14/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet14/1 - P2P_LINK_TO_POD2-LEAF7B_Ethernet4/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-spine4
+ interfaces:
+ - name: Ethernet15/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet15/1 - P2P_LINK_TO_POD2-LEAF8A_Ethernet4/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-spine4
+ interfaces:
+ - name: Ethernet16/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet16/1 - P2P_LINK_TO_POD2-LEAF8B_Ethernet4/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-spine4
+ interfaces:
+ - name: Ethernet17/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet17/1 - P2P_LINK_TO_POD2-LEAF9A_Ethernet4/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-spine4
+ interfaces:
+ - name: Ethernet18/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet18/1 - P2P_LINK_TO_POD2-LEAF9B_Ethernet4/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-spine4
+ interfaces:
+ - name: Ethernet19/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet19/1 - P2P_LINK_TO_POD2-LEAF10A_Ethernet4/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-spine4
+ interfaces:
+ - name: Ethernet20/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet20/1 - P2P_LINK_TO_POD2-LEAF10B_Ethernet4/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-spine4
+ interfaces:
+ - name: Ethernet31/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet31/1 - P2P_LINK_TO_SUPER-SPINE1_Ethernet8/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-spine4
+ interfaces:
+ - name: Ethernet32/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet32/1 - P2P_LINK_TO_SUPER-SPINE2_Ethernet8/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-spine4
+ interfaces:
+ - name: Loopback0
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback0 - EVPN_Overlay_Peering = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf3b
+ interfaces:
+ - name: Ethernet53/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet53/1 - MLAG_PEER_pod2-leaf3a_Ethernet53/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf3b
+ interfaces:
+ - name: Ethernet54/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet54/1 - MLAG_PEER_pod2-leaf3a_Ethernet54/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf3b
+ interfaces:
+ - name: Ethernet1/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet1/1 - P2P_LINK_TO_POD2-SPINE1_Ethernet6/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf3b
+ interfaces:
+ - name: Ethernet2/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet2/1 - P2P_LINK_TO_POD2-SPINE2_Ethernet6/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf3b
+ interfaces:
+ - name: Ethernet3/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet3/1 - P2P_LINK_TO_POD2-SPINE3_Ethernet6/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf3b
+ interfaces:
+ - name: Ethernet4/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet4/1 - P2P_LINK_TO_POD2-SPINE4_Ethernet6/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf3b
+ interfaces:
+ - name: Port-Channel531
+ status: up
+ result_overwrite:
+ custom_field: Interface Port-Channel531 - MLAG_PEER_pod2-leaf3a_Po531 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf3b
+ interfaces:
+ - name: Vlan4093
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan4093 - MLAG_PEER_L3_PEERING = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf3b
+ interfaces:
+ - name: Vlan4094
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan4094 - MLAG_PEER = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf3b
+ interfaces:
+ - name: Vlan11
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan11 - VRF10_VLAN11 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf3b
+ interfaces:
+ - name: Vlan12
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan12 - VRF10_VLAN12 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf3b
+ interfaces:
+ - name: Vlan3009
+ status: up
+ result_overwrite:
+ custom_field: 'Interface Vlan3009 - MLAG_PEER_L3_iBGP: vrf VRF10 = ''up'''
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf3b
+ interfaces:
+ - name: Vlan21
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan21 - VRF20_VLAN21 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf3b
+ interfaces:
+ - name: Vlan22
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan22 - VRF20_VLAN22 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf3b
+ interfaces:
+ - name: Vlan3019
+ status: up
+ result_overwrite:
+ custom_field: 'Interface Vlan3019 - MLAG_PEER_L3_iBGP: vrf VRF20 = ''up'''
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf3b
+ interfaces:
+ - name: Loopback0
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback0 - EVPN_Overlay_Peering = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf3b
+ interfaces:
+ - name: Loopback1
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback1 - VTEP_VXLAN_Tunnel_Source = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf3b
+ interfaces:
+ - name: Loopback10
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback10 - VRF10_VTEP_DIAGNOSTICS = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf3b
+ interfaces:
+ - name: Loopback20
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback20 - VRF20_VTEP_DIAGNOSTICS = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf3b
+ interfaces:
+ - name: Vxlan1
+ status: up
+ result_overwrite:
+ custom_field: Interface Vxlan1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf4b
+ interfaces:
+ - name: Ethernet53/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet53/1 - MLAG_PEER_pod2-leaf4a_Ethernet53/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf4b
+ interfaces:
+ - name: Ethernet54/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet54/1 - MLAG_PEER_pod2-leaf4a_Ethernet54/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf4b
+ interfaces:
+ - name: Ethernet1/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet1/1 - P2P_LINK_TO_POD2-SPINE1_Ethernet8/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf4b
+ interfaces:
+ - name: Ethernet2/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet2/1 - P2P_LINK_TO_POD2-SPINE2_Ethernet8/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf4b
+ interfaces:
+ - name: Ethernet3/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet3/1 - P2P_LINK_TO_POD2-SPINE3_Ethernet8/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf4b
+ interfaces:
+ - name: Ethernet4/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet4/1 - P2P_LINK_TO_POD2-SPINE4_Ethernet8/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf4b
+ interfaces:
+ - name: Port-Channel531
+ status: up
+ result_overwrite:
+ custom_field: Interface Port-Channel531 - MLAG_PEER_pod2-leaf4a_Po531 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf4b
+ interfaces:
+ - name: Vlan4093
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan4093 - MLAG_PEER_L3_PEERING = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf4b
+ interfaces:
+ - name: Vlan4094
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan4094 - MLAG_PEER = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf4b
+ interfaces:
+ - name: Vlan11
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan11 - VRF10_VLAN11 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf4b
+ interfaces:
+ - name: Vlan12
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan12 - VRF10_VLAN12 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf4b
+ interfaces:
+ - name: Vlan3009
+ status: up
+ result_overwrite:
+ custom_field: 'Interface Vlan3009 - MLAG_PEER_L3_iBGP: vrf VRF10 = ''up'''
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf4b
+ interfaces:
+ - name: Vlan21
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan21 - VRF20_VLAN21 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf4b
+ interfaces:
+ - name: Vlan22
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan22 - VRF20_VLAN22 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf4b
+ interfaces:
+ - name: Vlan3019
+ status: up
+ result_overwrite:
+ custom_field: 'Interface Vlan3019 - MLAG_PEER_L3_iBGP: vrf VRF20 = ''up'''
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf4b
+ interfaces:
+ - name: Loopback0
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback0 - EVPN_Overlay_Peering = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf4b
+ interfaces:
+ - name: Loopback1
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback1 - VTEP_VXLAN_Tunnel_Source = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf4b
+ interfaces:
+ - name: Loopback10
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback10 - VRF10_VTEP_DIAGNOSTICS = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf4b
+ interfaces:
+ - name: Loopback20
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback20 - VRF20_VTEP_DIAGNOSTICS = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf4b
+ interfaces:
+ - name: Vxlan1
+ status: up
+ result_overwrite:
+ custom_field: Interface Vxlan1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-spine1
+ interfaces:
+ - name: Ethernet1/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet1/1 - P2P_LINK_TO_POD1-LEAF1A_Ethernet1/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-spine1
+ interfaces:
+ - name: Ethernet2/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet2/1 - P2P_LINK_TO_POD1-LEAF1B_Ethernet1/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-spine1
+ interfaces:
+ - name: Ethernet3/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet3/1 - P2P_LINK_TO_POD1-LEAF2A_Ethernet1/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-spine1
+ interfaces:
+ - name: Ethernet4/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet4/1 - P2P_LINK_TO_POD1-LEAF2B_Ethernet1/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-spine1
+ interfaces:
+ - name: Ethernet5/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet5/1 - P2P_LINK_TO_POD1-LEAF3A_Ethernet1/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-spine1
+ interfaces:
+ - name: Ethernet6/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet6/1 - P2P_LINK_TO_POD1-LEAF3B_Ethernet1/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-spine1
+ interfaces:
+ - name: Ethernet7/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet7/1 - P2P_LINK_TO_POD1-LEAF4A_Ethernet1/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-spine1
+ interfaces:
+ - name: Ethernet8/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet8/1 - P2P_LINK_TO_POD1-LEAF4B_Ethernet1/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-spine1
+ interfaces:
+ - name: Ethernet9/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet9/1 - P2P_LINK_TO_POD1-LEAF5A_Ethernet1/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-spine1
+ interfaces:
+ - name: Ethernet10/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet10/1 - P2P_LINK_TO_POD1-LEAF5B_Ethernet1/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-spine1
+ interfaces:
+ - name: Ethernet11/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet11/1 - P2P_LINK_TO_POD1-LEAF6A_Ethernet1/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-spine1
+ interfaces:
+ - name: Ethernet12/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet12/1 - P2P_LINK_TO_POD1-LEAF6B_Ethernet1/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-spine1
+ interfaces:
+ - name: Ethernet13/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet13/1 - P2P_LINK_TO_POD1-LEAF7A_Ethernet1/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-spine1
+ interfaces:
+ - name: Ethernet14/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet14/1 - P2P_LINK_TO_POD1-LEAF7B_Ethernet1/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-spine1
+ interfaces:
+ - name: Ethernet15/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet15/1 - P2P_LINK_TO_POD1-LEAF8A_Ethernet1/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-spine1
+ interfaces:
+ - name: Ethernet16/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet16/1 - P2P_LINK_TO_POD1-LEAF8B_Ethernet1/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-spine1
+ interfaces:
+ - name: Ethernet17/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet17/1 - P2P_LINK_TO_POD1-LEAF9A_Ethernet1/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-spine1
+ interfaces:
+ - name: Ethernet18/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet18/1 - P2P_LINK_TO_POD1-LEAF9B_Ethernet1/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-spine1
+ interfaces:
+ - name: Ethernet19/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet19/1 - P2P_LINK_TO_POD1-LEAF10A_Ethernet1/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-spine1
+ interfaces:
+ - name: Ethernet20/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet20/1 - P2P_LINK_TO_POD1-LEAF10B_Ethernet1/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-spine1
+ interfaces:
+ - name: Ethernet31/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet31/1 - P2P_LINK_TO_SUPER-SPINE1_Ethernet1/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-spine1
+ interfaces:
+ - name: Ethernet32/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet32/1 - P2P_LINK_TO_SUPER-SPINE2_Ethernet1/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-spine1
+ interfaces:
+ - name: Loopback0
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback0 - EVPN_Overlay_Peering = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf9a
+ interfaces:
+ - name: Ethernet53/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet53/1 - MLAG_PEER_pod2-leaf9b_Ethernet53/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf9a
+ interfaces:
+ - name: Ethernet54/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet54/1 - MLAG_PEER_pod2-leaf9b_Ethernet54/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf9a
+ interfaces:
+ - name: Ethernet1/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet1/1 - P2P_LINK_TO_POD2-SPINE1_Ethernet17/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf9a
+ interfaces:
+ - name: Ethernet2/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet2/1 - P2P_LINK_TO_POD2-SPINE2_Ethernet17/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf9a
+ interfaces:
+ - name: Ethernet3/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet3/1 - P2P_LINK_TO_POD2-SPINE3_Ethernet17/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf9a
+ interfaces:
+ - name: Ethernet4/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet4/1 - P2P_LINK_TO_POD2-SPINE4_Ethernet17/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf9a
+ interfaces:
+ - name: Port-Channel531
+ status: up
+ result_overwrite:
+ custom_field: Interface Port-Channel531 - MLAG_PEER_pod2-leaf9b_Po531 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf9a
+ interfaces:
+ - name: Vlan4093
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan4093 - MLAG_PEER_L3_PEERING = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf9a
+ interfaces:
+ - name: Vlan4094
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan4094 - MLAG_PEER = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf9a
+ interfaces:
+ - name: Vlan11
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan11 - VRF10_VLAN11 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf9a
+ interfaces:
+ - name: Vlan12
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan12 - VRF10_VLAN12 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf9a
+ interfaces:
+ - name: Vlan3009
+ status: up
+ result_overwrite:
+ custom_field: 'Interface Vlan3009 - MLAG_PEER_L3_iBGP: vrf VRF10 = ''up'''
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf9a
+ interfaces:
+ - name: Vlan21
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan21 - VRF20_VLAN21 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf9a
+ interfaces:
+ - name: Vlan22
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan22 - VRF20_VLAN22 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf9a
+ interfaces:
+ - name: Vlan3019
+ status: up
+ result_overwrite:
+ custom_field: 'Interface Vlan3019 - MLAG_PEER_L3_iBGP: vrf VRF20 = ''up'''
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf9a
+ interfaces:
+ - name: Loopback0
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback0 - EVPN_Overlay_Peering = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf9a
+ interfaces:
+ - name: Loopback1
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback1 - VTEP_VXLAN_Tunnel_Source = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf9a
+ interfaces:
+ - name: Loopback10
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback10 - VRF10_VTEP_DIAGNOSTICS = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf9a
+ interfaces:
+ - name: Loopback20
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback20 - VRF20_VTEP_DIAGNOSTICS = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf9a
+ interfaces:
+ - name: Vxlan1
+ status: up
+ result_overwrite:
+ custom_field: Interface Vxlan1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf9b
+ interfaces:
+ - name: Ethernet53/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet53/1 - MLAG_PEER_pod2-leaf9a_Ethernet53/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf9b
+ interfaces:
+ - name: Ethernet54/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet54/1 - MLAG_PEER_pod2-leaf9a_Ethernet54/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf9b
+ interfaces:
+ - name: Ethernet1/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet1/1 - P2P_LINK_TO_POD2-SPINE1_Ethernet18/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf9b
+ interfaces:
+ - name: Ethernet2/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet2/1 - P2P_LINK_TO_POD2-SPINE2_Ethernet18/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf9b
+ interfaces:
+ - name: Ethernet3/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet3/1 - P2P_LINK_TO_POD2-SPINE3_Ethernet18/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf9b
+ interfaces:
+ - name: Ethernet4/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet4/1 - P2P_LINK_TO_POD2-SPINE4_Ethernet18/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf9b
+ interfaces:
+ - name: Port-Channel531
+ status: up
+ result_overwrite:
+ custom_field: Interface Port-Channel531 - MLAG_PEER_pod2-leaf9a_Po531 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf9b
+ interfaces:
+ - name: Vlan4093
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan4093 - MLAG_PEER_L3_PEERING = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf9b
+ interfaces:
+ - name: Vlan4094
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan4094 - MLAG_PEER = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf9b
+ interfaces:
+ - name: Vlan11
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan11 - VRF10_VLAN11 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf9b
+ interfaces:
+ - name: Vlan12
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan12 - VRF10_VLAN12 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf9b
+ interfaces:
+ - name: Vlan3009
+ status: up
+ result_overwrite:
+ custom_field: 'Interface Vlan3009 - MLAG_PEER_L3_iBGP: vrf VRF10 = ''up'''
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf9b
+ interfaces:
+ - name: Vlan21
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan21 - VRF20_VLAN21 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf9b
+ interfaces:
+ - name: Vlan22
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan22 - VRF20_VLAN22 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf9b
+ interfaces:
+ - name: Vlan3019
+ status: up
+ result_overwrite:
+ custom_field: 'Interface Vlan3019 - MLAG_PEER_L3_iBGP: vrf VRF20 = ''up'''
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf9b
+ interfaces:
+ - name: Loopback0
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback0 - EVPN_Overlay_Peering = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf9b
+ interfaces:
+ - name: Loopback1
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback1 - VTEP_VXLAN_Tunnel_Source = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf9b
+ interfaces:
+ - name: Loopback10
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback10 - VRF10_VTEP_DIAGNOSTICS = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf9b
+ interfaces:
+ - name: Loopback20
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback20 - VRF20_VTEP_DIAGNOSTICS = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf9b
+ interfaces:
+ - name: Vxlan1
+ status: up
+ result_overwrite:
+ custom_field: Interface Vxlan1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf3a
+ interfaces:
+ - name: Ethernet53/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet53/1 - MLAG_PEER_pod2-leaf3b_Ethernet53/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf3a
+ interfaces:
+ - name: Ethernet54/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet54/1 - MLAG_PEER_pod2-leaf3b_Ethernet54/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf3a
+ interfaces:
+ - name: Ethernet1/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet1/1 - P2P_LINK_TO_POD2-SPINE1_Ethernet5/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf3a
+ interfaces:
+ - name: Ethernet2/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet2/1 - P2P_LINK_TO_POD2-SPINE2_Ethernet5/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf3a
+ interfaces:
+ - name: Ethernet3/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet3/1 - P2P_LINK_TO_POD2-SPINE3_Ethernet5/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf3a
+ interfaces:
+ - name: Ethernet4/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet4/1 - P2P_LINK_TO_POD2-SPINE4_Ethernet5/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf3a
+ interfaces:
+ - name: Port-Channel531
+ status: up
+ result_overwrite:
+ custom_field: Interface Port-Channel531 - MLAG_PEER_pod2-leaf3b_Po531 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf3a
+ interfaces:
+ - name: Vlan4093
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan4093 - MLAG_PEER_L3_PEERING = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf3a
+ interfaces:
+ - name: Vlan4094
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan4094 - MLAG_PEER = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf3a
+ interfaces:
+ - name: Vlan11
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan11 - VRF10_VLAN11 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf3a
+ interfaces:
+ - name: Vlan12
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan12 - VRF10_VLAN12 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf3a
+ interfaces:
+ - name: Vlan3009
+ status: up
+ result_overwrite:
+ custom_field: 'Interface Vlan3009 - MLAG_PEER_L3_iBGP: vrf VRF10 = ''up'''
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf3a
+ interfaces:
+ - name: Vlan21
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan21 - VRF20_VLAN21 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf3a
+ interfaces:
+ - name: Vlan22
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan22 - VRF20_VLAN22 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf3a
+ interfaces:
+ - name: Vlan3019
+ status: up
+ result_overwrite:
+ custom_field: 'Interface Vlan3019 - MLAG_PEER_L3_iBGP: vrf VRF20 = ''up'''
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf3a
+ interfaces:
+ - name: Loopback0
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback0 - EVPN_Overlay_Peering = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf3a
+ interfaces:
+ - name: Loopback1
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback1 - VTEP_VXLAN_Tunnel_Source = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf3a
+ interfaces:
+ - name: Loopback10
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback10 - VRF10_VTEP_DIAGNOSTICS = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf3a
+ interfaces:
+ - name: Loopback20
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback20 - VRF20_VTEP_DIAGNOSTICS = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf3a
+ interfaces:
+ - name: Vxlan1
+ status: up
+ result_overwrite:
+ custom_field: Interface Vxlan1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-spine2
+ interfaces:
+ - name: Ethernet1/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet1/1 - P2P_LINK_TO_POD1-LEAF1A_Ethernet2/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-spine2
+ interfaces:
+ - name: Ethernet2/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet2/1 - P2P_LINK_TO_POD1-LEAF1B_Ethernet2/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-spine2
+ interfaces:
+ - name: Ethernet3/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet3/1 - P2P_LINK_TO_POD1-LEAF2A_Ethernet2/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-spine2
+ interfaces:
+ - name: Ethernet4/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet4/1 - P2P_LINK_TO_POD1-LEAF2B_Ethernet2/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-spine2
+ interfaces:
+ - name: Ethernet5/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet5/1 - P2P_LINK_TO_POD1-LEAF3A_Ethernet2/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-spine2
+ interfaces:
+ - name: Ethernet6/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet6/1 - P2P_LINK_TO_POD1-LEAF3B_Ethernet2/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-spine2
+ interfaces:
+ - name: Ethernet7/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet7/1 - P2P_LINK_TO_POD1-LEAF4A_Ethernet2/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-spine2
+ interfaces:
+ - name: Ethernet8/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet8/1 - P2P_LINK_TO_POD1-LEAF4B_Ethernet2/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-spine2
+ interfaces:
+ - name: Ethernet9/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet9/1 - P2P_LINK_TO_POD1-LEAF5A_Ethernet2/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-spine2
+ interfaces:
+ - name: Ethernet10/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet10/1 - P2P_LINK_TO_POD1-LEAF5B_Ethernet2/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-spine2
+ interfaces:
+ - name: Ethernet11/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet11/1 - P2P_LINK_TO_POD1-LEAF6A_Ethernet2/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-spine2
+ interfaces:
+ - name: Ethernet12/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet12/1 - P2P_LINK_TO_POD1-LEAF6B_Ethernet2/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-spine2
+ interfaces:
+ - name: Ethernet13/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet13/1 - P2P_LINK_TO_POD1-LEAF7A_Ethernet2/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-spine2
+ interfaces:
+ - name: Ethernet14/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet14/1 - P2P_LINK_TO_POD1-LEAF7B_Ethernet2/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-spine2
+ interfaces:
+ - name: Ethernet15/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet15/1 - P2P_LINK_TO_POD1-LEAF8A_Ethernet2/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-spine2
+ interfaces:
+ - name: Ethernet16/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet16/1 - P2P_LINK_TO_POD1-LEAF8B_Ethernet2/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-spine2
+ interfaces:
+ - name: Ethernet17/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet17/1 - P2P_LINK_TO_POD1-LEAF9A_Ethernet2/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-spine2
+ interfaces:
+ - name: Ethernet18/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet18/1 - P2P_LINK_TO_POD1-LEAF9B_Ethernet2/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-spine2
+ interfaces:
+ - name: Ethernet19/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet19/1 - P2P_LINK_TO_POD1-LEAF10A_Ethernet2/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-spine2
+ interfaces:
+ - name: Ethernet20/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet20/1 - P2P_LINK_TO_POD1-LEAF10B_Ethernet2/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-spine2
+ interfaces:
+ - name: Ethernet31/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet31/1 - P2P_LINK_TO_SUPER-SPINE1_Ethernet2/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-spine2
+ interfaces:
+ - name: Ethernet32/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet32/1 - P2P_LINK_TO_SUPER-SPINE2_Ethernet2/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-spine2
+ interfaces:
+ - name: Loopback0
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback0 - EVPN_Overlay_Peering = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf4a
+ interfaces:
+ - name: Ethernet53/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet53/1 - MLAG_PEER_pod2-leaf4b_Ethernet53/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf4a
+ interfaces:
+ - name: Ethernet54/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet54/1 - MLAG_PEER_pod2-leaf4b_Ethernet54/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf4a
+ interfaces:
+ - name: Ethernet1/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet1/1 - P2P_LINK_TO_POD2-SPINE1_Ethernet7/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf4a
+ interfaces:
+ - name: Ethernet2/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet2/1 - P2P_LINK_TO_POD2-SPINE2_Ethernet7/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf4a
+ interfaces:
+ - name: Ethernet3/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet3/1 - P2P_LINK_TO_POD2-SPINE3_Ethernet7/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf4a
+ interfaces:
+ - name: Ethernet4/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet4/1 - P2P_LINK_TO_POD2-SPINE4_Ethernet7/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf4a
+ interfaces:
+ - name: Port-Channel531
+ status: up
+ result_overwrite:
+ custom_field: Interface Port-Channel531 - MLAG_PEER_pod2-leaf4b_Po531 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf4a
+ interfaces:
+ - name: Vlan4093
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan4093 - MLAG_PEER_L3_PEERING = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf4a
+ interfaces:
+ - name: Vlan4094
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan4094 - MLAG_PEER = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf4a
+ interfaces:
+ - name: Vlan11
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan11 - VRF10_VLAN11 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf4a
+ interfaces:
+ - name: Vlan12
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan12 - VRF10_VLAN12 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf4a
+ interfaces:
+ - name: Vlan3009
+ status: up
+ result_overwrite:
+ custom_field: 'Interface Vlan3009 - MLAG_PEER_L3_iBGP: vrf VRF10 = ''up'''
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf4a
+ interfaces:
+ - name: Vlan21
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan21 - VRF20_VLAN21 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf4a
+ interfaces:
+ - name: Vlan22
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan22 - VRF20_VLAN22 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf4a
+ interfaces:
+ - name: Vlan3019
+ status: up
+ result_overwrite:
+ custom_field: 'Interface Vlan3019 - MLAG_PEER_L3_iBGP: vrf VRF20 = ''up'''
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf4a
+ interfaces:
+ - name: Loopback0
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback0 - EVPN_Overlay_Peering = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf4a
+ interfaces:
+ - name: Loopback1
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback1 - VTEP_VXLAN_Tunnel_Source = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf4a
+ interfaces:
+ - name: Loopback10
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback10 - VRF10_VTEP_DIAGNOSTICS = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf4a
+ interfaces:
+ - name: Loopback20
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback20 - VRF20_VTEP_DIAGNOSTICS = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf4a
+ interfaces:
+ - name: Vxlan1
+ status: up
+ result_overwrite:
+ custom_field: Interface Vxlan1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf8b
+ interfaces:
+ - name: Ethernet53/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet53/1 - MLAG_PEER_pod1-leaf8a_Ethernet53/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf8b
+ interfaces:
+ - name: Ethernet54/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet54/1 - MLAG_PEER_pod1-leaf8a_Ethernet54/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf8b
+ interfaces:
+ - name: Ethernet1/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet1/1 - P2P_LINK_TO_POD1-SPINE1_Ethernet16/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf8b
+ interfaces:
+ - name: Ethernet2/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet2/1 - P2P_LINK_TO_POD1-SPINE2_Ethernet16/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf8b
+ interfaces:
+ - name: Ethernet3/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet3/1 - P2P_LINK_TO_POD1-SPINE3_Ethernet16/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf8b
+ interfaces:
+ - name: Ethernet4/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet4/1 - P2P_LINK_TO_POD1-SPINE4_Ethernet16/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf8b
+ interfaces:
+ - name: Port-Channel531
+ status: up
+ result_overwrite:
+ custom_field: Interface Port-Channel531 - MLAG_PEER_pod1-leaf8a_Po531 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf8b
+ interfaces:
+ - name: Vlan4093
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan4093 - MLAG_PEER_L3_PEERING = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf8b
+ interfaces:
+ - name: Vlan4094
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan4094 - MLAG_PEER = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf8b
+ interfaces:
+ - name: Vlan11
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan11 - VRF10_VLAN11 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf8b
+ interfaces:
+ - name: Vlan12
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan12 - VRF10_VLAN12 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf8b
+ interfaces:
+ - name: Vlan3009
+ status: up
+ result_overwrite:
+ custom_field: 'Interface Vlan3009 - MLAG_PEER_L3_iBGP: vrf VRF10 = ''up'''
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf8b
+ interfaces:
+ - name: Vlan21
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan21 - VRF20_VLAN21 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf8b
+ interfaces:
+ - name: Vlan22
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan22 - VRF20_VLAN22 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf8b
+ interfaces:
+ - name: Vlan3019
+ status: up
+ result_overwrite:
+ custom_field: 'Interface Vlan3019 - MLAG_PEER_L3_iBGP: vrf VRF20 = ''up'''
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf8b
+ interfaces:
+ - name: Loopback0
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback0 - EVPN_Overlay_Peering = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf8b
+ interfaces:
+ - name: Loopback1
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback1 - VTEP_VXLAN_Tunnel_Source = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf8b
+ interfaces:
+ - name: Loopback10
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback10 - VRF10_VTEP_DIAGNOSTICS = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf8b
+ interfaces:
+ - name: Loopback20
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback20 - VRF20_VTEP_DIAGNOSTICS = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf8b
+ interfaces:
+ - name: Vxlan1
+ status: up
+ result_overwrite:
+ custom_field: Interface Vxlan1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf2a
+ interfaces:
+ - name: Ethernet53/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet53/1 - MLAG_PEER_pod1-leaf2b_Ethernet53/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf2a
+ interfaces:
+ - name: Ethernet54/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet54/1 - MLAG_PEER_pod1-leaf2b_Ethernet54/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf2a
+ interfaces:
+ - name: Ethernet1/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet1/1 - P2P_LINK_TO_POD1-SPINE1_Ethernet3/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf2a
+ interfaces:
+ - name: Ethernet2/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet2/1 - P2P_LINK_TO_POD1-SPINE2_Ethernet3/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf2a
+ interfaces:
+ - name: Ethernet3/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet3/1 - P2P_LINK_TO_POD1-SPINE3_Ethernet3/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf2a
+ interfaces:
+ - name: Ethernet4/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet4/1 - P2P_LINK_TO_POD1-SPINE4_Ethernet3/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf2a
+ interfaces:
+ - name: Port-Channel531
+ status: up
+ result_overwrite:
+ custom_field: Interface Port-Channel531 - MLAG_PEER_pod1-leaf2b_Po531 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf2a
+ interfaces:
+ - name: Vlan4093
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan4093 - MLAG_PEER_L3_PEERING = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf2a
+ interfaces:
+ - name: Vlan4094
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan4094 - MLAG_PEER = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf2a
+ interfaces:
+ - name: Vlan11
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan11 - VRF10_VLAN11 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf2a
+ interfaces:
+ - name: Vlan12
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan12 - VRF10_VLAN12 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf2a
+ interfaces:
+ - name: Vlan3009
+ status: up
+ result_overwrite:
+ custom_field: 'Interface Vlan3009 - MLAG_PEER_L3_iBGP: vrf VRF10 = ''up'''
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf2a
+ interfaces:
+ - name: Vlan21
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan21 - VRF20_VLAN21 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf2a
+ interfaces:
+ - name: Vlan22
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan22 - VRF20_VLAN22 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf2a
+ interfaces:
+ - name: Vlan3019
+ status: up
+ result_overwrite:
+ custom_field: 'Interface Vlan3019 - MLAG_PEER_L3_iBGP: vrf VRF20 = ''up'''
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf2a
+ interfaces:
+ - name: Loopback0
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback0 - EVPN_Overlay_Peering = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf2a
+ interfaces:
+ - name: Loopback1
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback1 - VTEP_VXLAN_Tunnel_Source = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf2a
+ interfaces:
+ - name: Loopback10
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback10 - VRF10_VTEP_DIAGNOSTICS = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf2a
+ interfaces:
+ - name: Loopback20
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback20 - VRF20_VTEP_DIAGNOSTICS = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf2a
+ interfaces:
+ - name: Vxlan1
+ status: up
+ result_overwrite:
+ custom_field: Interface Vxlan1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf5a
+ interfaces:
+ - name: Ethernet53/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet53/1 - MLAG_PEER_pod1-leaf5b_Ethernet53/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf5a
+ interfaces:
+ - name: Ethernet54/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet54/1 - MLAG_PEER_pod1-leaf5b_Ethernet54/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf5a
+ interfaces:
+ - name: Ethernet1/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet1/1 - P2P_LINK_TO_POD1-SPINE1_Ethernet9/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf5a
+ interfaces:
+ - name: Ethernet2/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet2/1 - P2P_LINK_TO_POD1-SPINE2_Ethernet9/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf5a
+ interfaces:
+ - name: Ethernet3/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet3/1 - P2P_LINK_TO_POD1-SPINE3_Ethernet9/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf5a
+ interfaces:
+ - name: Ethernet4/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet4/1 - P2P_LINK_TO_POD1-SPINE4_Ethernet9/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf5a
+ interfaces:
+ - name: Port-Channel531
+ status: up
+ result_overwrite:
+ custom_field: Interface Port-Channel531 - MLAG_PEER_pod1-leaf5b_Po531 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf5a
+ interfaces:
+ - name: Vlan4093
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan4093 - MLAG_PEER_L3_PEERING = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf5a
+ interfaces:
+ - name: Vlan4094
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan4094 - MLAG_PEER = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf5a
+ interfaces:
+ - name: Vlan11
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan11 - VRF10_VLAN11 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf5a
+ interfaces:
+ - name: Vlan12
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan12 - VRF10_VLAN12 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf5a
+ interfaces:
+ - name: Vlan3009
+ status: up
+ result_overwrite:
+ custom_field: 'Interface Vlan3009 - MLAG_PEER_L3_iBGP: vrf VRF10 = ''up'''
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf5a
+ interfaces:
+ - name: Vlan21
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan21 - VRF20_VLAN21 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf5a
+ interfaces:
+ - name: Vlan22
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan22 - VRF20_VLAN22 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf5a
+ interfaces:
+ - name: Vlan3019
+ status: up
+ result_overwrite:
+ custom_field: 'Interface Vlan3019 - MLAG_PEER_L3_iBGP: vrf VRF20 = ''up'''
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf5a
+ interfaces:
+ - name: Loopback0
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback0 - EVPN_Overlay_Peering = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf5a
+ interfaces:
+ - name: Loopback1
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback1 - VTEP_VXLAN_Tunnel_Source = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf5a
+ interfaces:
+ - name: Loopback10
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback10 - VRF10_VTEP_DIAGNOSTICS = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf5a
+ interfaces:
+ - name: Loopback20
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback20 - VRF20_VTEP_DIAGNOSTICS = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf5a
+ interfaces:
+ - name: Vxlan1
+ status: up
+ result_overwrite:
+ custom_field: Interface Vxlan1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf8b
+ interfaces:
+ - name: Ethernet53/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet53/1 - MLAG_PEER_pod2-leaf8a_Ethernet53/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf8b
+ interfaces:
+ - name: Ethernet54/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet54/1 - MLAG_PEER_pod2-leaf8a_Ethernet54/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf8b
+ interfaces:
+ - name: Ethernet1/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet1/1 - P2P_LINK_TO_POD2-SPINE1_Ethernet16/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf8b
+ interfaces:
+ - name: Ethernet2/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet2/1 - P2P_LINK_TO_POD2-SPINE2_Ethernet16/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf8b
+ interfaces:
+ - name: Ethernet3/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet3/1 - P2P_LINK_TO_POD2-SPINE3_Ethernet16/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf8b
+ interfaces:
+ - name: Ethernet4/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet4/1 - P2P_LINK_TO_POD2-SPINE4_Ethernet16/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf8b
+ interfaces:
+ - name: Port-Channel531
+ status: up
+ result_overwrite:
+ custom_field: Interface Port-Channel531 - MLAG_PEER_pod2-leaf8a_Po531 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf8b
+ interfaces:
+ - name: Vlan4093
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan4093 - MLAG_PEER_L3_PEERING = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf8b
+ interfaces:
+ - name: Vlan4094
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan4094 - MLAG_PEER = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf8b
+ interfaces:
+ - name: Vlan11
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan11 - VRF10_VLAN11 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf8b
+ interfaces:
+ - name: Vlan12
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan12 - VRF10_VLAN12 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf8b
+ interfaces:
+ - name: Vlan3009
+ status: up
+ result_overwrite:
+ custom_field: 'Interface Vlan3009 - MLAG_PEER_L3_iBGP: vrf VRF10 = ''up'''
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf8b
+ interfaces:
+ - name: Vlan21
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan21 - VRF20_VLAN21 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf8b
+ interfaces:
+ - name: Vlan22
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan22 - VRF20_VLAN22 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf8b
+ interfaces:
+ - name: Vlan3019
+ status: up
+ result_overwrite:
+ custom_field: 'Interface Vlan3019 - MLAG_PEER_L3_iBGP: vrf VRF20 = ''up'''
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf8b
+ interfaces:
+ - name: Loopback0
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback0 - EVPN_Overlay_Peering = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf8b
+ interfaces:
+ - name: Loopback1
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback1 - VTEP_VXLAN_Tunnel_Source = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf8b
+ interfaces:
+ - name: Loopback10
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback10 - VRF10_VTEP_DIAGNOSTICS = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf8b
+ interfaces:
+ - name: Loopback20
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback20 - VRF20_VTEP_DIAGNOSTICS = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf8b
+ interfaces:
+ - name: Vxlan1
+ status: up
+ result_overwrite:
+ custom_field: Interface Vxlan1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf5a
+ interfaces:
+ - name: Ethernet53/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet53/1 - MLAG_PEER_pod2-leaf5b_Ethernet53/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf5a
+ interfaces:
+ - name: Ethernet54/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet54/1 - MLAG_PEER_pod2-leaf5b_Ethernet54/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf5a
+ interfaces:
+ - name: Ethernet1/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet1/1 - P2P_LINK_TO_POD2-SPINE1_Ethernet9/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf5a
+ interfaces:
+ - name: Ethernet2/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet2/1 - P2P_LINK_TO_POD2-SPINE2_Ethernet9/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf5a
+ interfaces:
+ - name: Ethernet3/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet3/1 - P2P_LINK_TO_POD2-SPINE3_Ethernet9/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf5a
+ interfaces:
+ - name: Ethernet4/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet4/1 - P2P_LINK_TO_POD2-SPINE4_Ethernet9/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf5a
+ interfaces:
+ - name: Port-Channel531
+ status: up
+ result_overwrite:
+ custom_field: Interface Port-Channel531 - MLAG_PEER_pod2-leaf5b_Po531 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf5a
+ interfaces:
+ - name: Vlan4093
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan4093 - MLAG_PEER_L3_PEERING = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf5a
+ interfaces:
+ - name: Vlan4094
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan4094 - MLAG_PEER = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf5a
+ interfaces:
+ - name: Vlan11
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan11 - VRF10_VLAN11 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf5a
+ interfaces:
+ - name: Vlan12
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan12 - VRF10_VLAN12 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf5a
+ interfaces:
+ - name: Vlan3009
+ status: up
+ result_overwrite:
+ custom_field: 'Interface Vlan3009 - MLAG_PEER_L3_iBGP: vrf VRF10 = ''up'''
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf5a
+ interfaces:
+ - name: Vlan21
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan21 - VRF20_VLAN21 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf5a
+ interfaces:
+ - name: Vlan22
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan22 - VRF20_VLAN22 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf5a
+ interfaces:
+ - name: Vlan3019
+ status: up
+ result_overwrite:
+ custom_field: 'Interface Vlan3019 - MLAG_PEER_L3_iBGP: vrf VRF20 = ''up'''
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf5a
+ interfaces:
+ - name: Loopback0
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback0 - EVPN_Overlay_Peering = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf5a
+ interfaces:
+ - name: Loopback1
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback1 - VTEP_VXLAN_Tunnel_Source = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf5a
+ interfaces:
+ - name: Loopback10
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback10 - VRF10_VTEP_DIAGNOSTICS = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf5a
+ interfaces:
+ - name: Loopback20
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback20 - VRF20_VTEP_DIAGNOSTICS = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf5a
+ interfaces:
+ - name: Vxlan1
+ status: up
+ result_overwrite:
+ custom_field: Interface Vxlan1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf2a
+ interfaces:
+ - name: Ethernet53/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet53/1 - MLAG_PEER_pod2-leaf2b_Ethernet53/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf2a
+ interfaces:
+ - name: Ethernet54/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet54/1 - MLAG_PEER_pod2-leaf2b_Ethernet54/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf2a
+ interfaces:
+ - name: Ethernet1/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet1/1 - P2P_LINK_TO_POD2-SPINE1_Ethernet3/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf2a
+ interfaces:
+ - name: Ethernet2/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet2/1 - P2P_LINK_TO_POD2-SPINE2_Ethernet3/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf2a
+ interfaces:
+ - name: Ethernet3/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet3/1 - P2P_LINK_TO_POD2-SPINE3_Ethernet3/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf2a
+ interfaces:
+ - name: Ethernet4/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet4/1 - P2P_LINK_TO_POD2-SPINE4_Ethernet3/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf2a
+ interfaces:
+ - name: Port-Channel531
+ status: up
+ result_overwrite:
+ custom_field: Interface Port-Channel531 - MLAG_PEER_pod2-leaf2b_Po531 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf2a
+ interfaces:
+ - name: Vlan4093
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan4093 - MLAG_PEER_L3_PEERING = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf2a
+ interfaces:
+ - name: Vlan4094
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan4094 - MLAG_PEER = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf2a
+ interfaces:
+ - name: Vlan11
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan11 - VRF10_VLAN11 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf2a
+ interfaces:
+ - name: Vlan12
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan12 - VRF10_VLAN12 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf2a
+ interfaces:
+ - name: Vlan3009
+ status: up
+ result_overwrite:
+ custom_field: 'Interface Vlan3009 - MLAG_PEER_L3_iBGP: vrf VRF10 = ''up'''
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf2a
+ interfaces:
+ - name: Vlan21
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan21 - VRF20_VLAN21 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf2a
+ interfaces:
+ - name: Vlan22
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan22 - VRF20_VLAN22 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf2a
+ interfaces:
+ - name: Vlan3019
+ status: up
+ result_overwrite:
+ custom_field: 'Interface Vlan3019 - MLAG_PEER_L3_iBGP: vrf VRF20 = ''up'''
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf2a
+ interfaces:
+ - name: Loopback0
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback0 - EVPN_Overlay_Peering = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf2a
+ interfaces:
+ - name: Loopback1
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback1 - VTEP_VXLAN_Tunnel_Source = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf2a
+ interfaces:
+ - name: Loopback10
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback10 - VRF10_VTEP_DIAGNOSTICS = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf2a
+ interfaces:
+ - name: Loopback20
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback20 - VRF20_VTEP_DIAGNOSTICS = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf2a
+ interfaces:
+ - name: Vxlan1
+ status: up
+ result_overwrite:
+ custom_field: Interface Vxlan1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf9b
+ interfaces:
+ - name: Ethernet53/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet53/1 - MLAG_PEER_pod1-leaf9a_Ethernet53/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf9b
+ interfaces:
+ - name: Ethernet54/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet54/1 - MLAG_PEER_pod1-leaf9a_Ethernet54/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf9b
+ interfaces:
+ - name: Ethernet1/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet1/1 - P2P_LINK_TO_POD1-SPINE1_Ethernet18/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf9b
+ interfaces:
+ - name: Ethernet2/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet2/1 - P2P_LINK_TO_POD1-SPINE2_Ethernet18/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf9b
+ interfaces:
+ - name: Ethernet3/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet3/1 - P2P_LINK_TO_POD1-SPINE3_Ethernet18/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf9b
+ interfaces:
+ - name: Ethernet4/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet4/1 - P2P_LINK_TO_POD1-SPINE4_Ethernet18/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf9b
+ interfaces:
+ - name: Port-Channel531
+ status: up
+ result_overwrite:
+ custom_field: Interface Port-Channel531 - MLAG_PEER_pod1-leaf9a_Po531 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf9b
+ interfaces:
+ - name: Vlan4093
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan4093 - MLAG_PEER_L3_PEERING = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf9b
+ interfaces:
+ - name: Vlan4094
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan4094 - MLAG_PEER = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf9b
+ interfaces:
+ - name: Vlan11
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan11 - VRF10_VLAN11 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf9b
+ interfaces:
+ - name: Vlan12
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan12 - VRF10_VLAN12 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf9b
+ interfaces:
+ - name: Vlan3009
+ status: up
+ result_overwrite:
+ custom_field: 'Interface Vlan3009 - MLAG_PEER_L3_iBGP: vrf VRF10 = ''up'''
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf9b
+ interfaces:
+ - name: Vlan21
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan21 - VRF20_VLAN21 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf9b
+ interfaces:
+ - name: Vlan22
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan22 - VRF20_VLAN22 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf9b
+ interfaces:
+ - name: Vlan3019
+ status: up
+ result_overwrite:
+ custom_field: 'Interface Vlan3019 - MLAG_PEER_L3_iBGP: vrf VRF20 = ''up'''
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf9b
+ interfaces:
+ - name: Loopback0
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback0 - EVPN_Overlay_Peering = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf9b
+ interfaces:
+ - name: Loopback1
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback1 - VTEP_VXLAN_Tunnel_Source = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf9b
+ interfaces:
+ - name: Loopback10
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback10 - VRF10_VTEP_DIAGNOSTICS = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf9b
+ interfaces:
+ - name: Loopback20
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback20 - VRF20_VTEP_DIAGNOSTICS = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf9b
+ interfaces:
+ - name: Vxlan1
+ status: up
+ result_overwrite:
+ custom_field: Interface Vxlan1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-spine2
+ interfaces:
+ - name: Ethernet1/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet1/1 - P2P_LINK_TO_POD2-LEAF1A_Ethernet2/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-spine2
+ interfaces:
+ - name: Ethernet2/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet2/1 - P2P_LINK_TO_POD2-LEAF1B_Ethernet2/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-spine2
+ interfaces:
+ - name: Ethernet3/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet3/1 - P2P_LINK_TO_POD2-LEAF2A_Ethernet2/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-spine2
+ interfaces:
+ - name: Ethernet4/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet4/1 - P2P_LINK_TO_POD2-LEAF2B_Ethernet2/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-spine2
+ interfaces:
+ - name: Ethernet5/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet5/1 - P2P_LINK_TO_POD2-LEAF3A_Ethernet2/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-spine2
+ interfaces:
+ - name: Ethernet6/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet6/1 - P2P_LINK_TO_POD2-LEAF3B_Ethernet2/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-spine2
+ interfaces:
+ - name: Ethernet7/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet7/1 - P2P_LINK_TO_POD2-LEAF4A_Ethernet2/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-spine2
+ interfaces:
+ - name: Ethernet8/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet8/1 - P2P_LINK_TO_POD2-LEAF4B_Ethernet2/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-spine2
+ interfaces:
+ - name: Ethernet9/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet9/1 - P2P_LINK_TO_POD2-LEAF5A_Ethernet2/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-spine2
+ interfaces:
+ - name: Ethernet10/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet10/1 - P2P_LINK_TO_POD2-LEAF5B_Ethernet2/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-spine2
+ interfaces:
+ - name: Ethernet11/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet11/1 - P2P_LINK_TO_POD2-LEAF6A_Ethernet2/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-spine2
+ interfaces:
+ - name: Ethernet12/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet12/1 - P2P_LINK_TO_POD2-LEAF6B_Ethernet2/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-spine2
+ interfaces:
+ - name: Ethernet13/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet13/1 - P2P_LINK_TO_POD2-LEAF7A_Ethernet2/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-spine2
+ interfaces:
+ - name: Ethernet14/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet14/1 - P2P_LINK_TO_POD2-LEAF7B_Ethernet2/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-spine2
+ interfaces:
+ - name: Ethernet15/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet15/1 - P2P_LINK_TO_POD2-LEAF8A_Ethernet2/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-spine2
+ interfaces:
+ - name: Ethernet16/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet16/1 - P2P_LINK_TO_POD2-LEAF8B_Ethernet2/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-spine2
+ interfaces:
+ - name: Ethernet17/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet17/1 - P2P_LINK_TO_POD2-LEAF9A_Ethernet2/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-spine2
+ interfaces:
+ - name: Ethernet18/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet18/1 - P2P_LINK_TO_POD2-LEAF9B_Ethernet2/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-spine2
+ interfaces:
+ - name: Ethernet19/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet19/1 - P2P_LINK_TO_POD2-LEAF10A_Ethernet2/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-spine2
+ interfaces:
+ - name: Ethernet20/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet20/1 - P2P_LINK_TO_POD2-LEAF10B_Ethernet2/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-spine2
+ interfaces:
+ - name: Ethernet31/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet31/1 - P2P_LINK_TO_SUPER-SPINE1_Ethernet6/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-spine2
+ interfaces:
+ - name: Ethernet32/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet32/1 - P2P_LINK_TO_SUPER-SPINE2_Ethernet6/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-spine2
+ interfaces:
+ - name: Loopback0
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback0 - EVPN_Overlay_Peering = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf4a
+ interfaces:
+ - name: Ethernet53/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet53/1 - MLAG_PEER_pod1-leaf4b_Ethernet53/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf4a
+ interfaces:
+ - name: Ethernet54/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet54/1 - MLAG_PEER_pod1-leaf4b_Ethernet54/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf4a
+ interfaces:
+ - name: Ethernet1/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet1/1 - P2P_LINK_TO_POD1-SPINE1_Ethernet7/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf4a
+ interfaces:
+ - name: Ethernet2/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet2/1 - P2P_LINK_TO_POD1-SPINE2_Ethernet7/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf4a
+ interfaces:
+ - name: Ethernet3/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet3/1 - P2P_LINK_TO_POD1-SPINE3_Ethernet7/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf4a
+ interfaces:
+ - name: Ethernet4/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet4/1 - P2P_LINK_TO_POD1-SPINE4_Ethernet7/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf4a
+ interfaces:
+ - name: Port-Channel531
+ status: up
+ result_overwrite:
+ custom_field: Interface Port-Channel531 - MLAG_PEER_pod1-leaf4b_Po531 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf4a
+ interfaces:
+ - name: Vlan4093
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan4093 - MLAG_PEER_L3_PEERING = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf4a
+ interfaces:
+ - name: Vlan4094
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan4094 - MLAG_PEER = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf4a
+ interfaces:
+ - name: Vlan11
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan11 - VRF10_VLAN11 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf4a
+ interfaces:
+ - name: Vlan12
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan12 - VRF10_VLAN12 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf4a
+ interfaces:
+ - name: Vlan3009
+ status: up
+ result_overwrite:
+ custom_field: 'Interface Vlan3009 - MLAG_PEER_L3_iBGP: vrf VRF10 = ''up'''
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf4a
+ interfaces:
+ - name: Vlan21
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan21 - VRF20_VLAN21 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf4a
+ interfaces:
+ - name: Vlan22
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan22 - VRF20_VLAN22 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf4a
+ interfaces:
+ - name: Vlan3019
+ status: up
+ result_overwrite:
+ custom_field: 'Interface Vlan3019 - MLAG_PEER_L3_iBGP: vrf VRF20 = ''up'''
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf4a
+ interfaces:
+ - name: Loopback0
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback0 - EVPN_Overlay_Peering = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf4a
+ interfaces:
+ - name: Loopback1
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback1 - VTEP_VXLAN_Tunnel_Source = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf4a
+ interfaces:
+ - name: Loopback10
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback10 - VRF10_VTEP_DIAGNOSTICS = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf4a
+ interfaces:
+ - name: Loopback20
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback20 - VRF20_VTEP_DIAGNOSTICS = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf4a
+ interfaces:
+ - name: Vxlan1
+ status: up
+ result_overwrite:
+ custom_field: Interface Vxlan1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf3a
+ interfaces:
+ - name: Ethernet53/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet53/1 - MLAG_PEER_pod1-leaf3b_Ethernet53/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf3a
+ interfaces:
+ - name: Ethernet54/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet54/1 - MLAG_PEER_pod1-leaf3b_Ethernet54/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf3a
+ interfaces:
+ - name: Ethernet1/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet1/1 - P2P_LINK_TO_POD1-SPINE1_Ethernet5/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf3a
+ interfaces:
+ - name: Ethernet2/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet2/1 - P2P_LINK_TO_POD1-SPINE2_Ethernet5/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf3a
+ interfaces:
+ - name: Ethernet3/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet3/1 - P2P_LINK_TO_POD1-SPINE3_Ethernet5/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf3a
+ interfaces:
+ - name: Ethernet4/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet4/1 - P2P_LINK_TO_POD1-SPINE4_Ethernet5/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf3a
+ interfaces:
+ - name: Port-Channel531
+ status: up
+ result_overwrite:
+ custom_field: Interface Port-Channel531 - MLAG_PEER_pod1-leaf3b_Po531 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf3a
+ interfaces:
+ - name: Vlan4093
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan4093 - MLAG_PEER_L3_PEERING = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf3a
+ interfaces:
+ - name: Vlan4094
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan4094 - MLAG_PEER = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf3a
+ interfaces:
+ - name: Vlan11
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan11 - VRF10_VLAN11 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf3a
+ interfaces:
+ - name: Vlan12
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan12 - VRF10_VLAN12 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf3a
+ interfaces:
+ - name: Vlan3009
+ status: up
+ result_overwrite:
+ custom_field: 'Interface Vlan3009 - MLAG_PEER_L3_iBGP: vrf VRF10 = ''up'''
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf3a
+ interfaces:
+ - name: Vlan21
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan21 - VRF20_VLAN21 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf3a
+ interfaces:
+ - name: Vlan22
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan22 - VRF20_VLAN22 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf3a
+ interfaces:
+ - name: Vlan3019
+ status: up
+ result_overwrite:
+ custom_field: 'Interface Vlan3019 - MLAG_PEER_L3_iBGP: vrf VRF20 = ''up'''
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf3a
+ interfaces:
+ - name: Loopback0
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback0 - EVPN_Overlay_Peering = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf3a
+ interfaces:
+ - name: Loopback1
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback1 - VTEP_VXLAN_Tunnel_Source = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf3a
+ interfaces:
+ - name: Loopback10
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback10 - VRF10_VTEP_DIAGNOSTICS = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf3a
+ interfaces:
+ - name: Loopback20
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback20 - VRF20_VTEP_DIAGNOSTICS = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf3a
+ interfaces:
+ - name: Vxlan1
+ status: up
+ result_overwrite:
+ custom_field: Interface Vxlan1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf7a
+ interfaces:
+ - name: Ethernet53/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet53/1 - MLAG_PEER_pod2-leaf7b_Ethernet53/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf7a
+ interfaces:
+ - name: Ethernet54/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet54/1 - MLAG_PEER_pod2-leaf7b_Ethernet54/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf7a
+ interfaces:
+ - name: Ethernet1/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet1/1 - P2P_LINK_TO_POD2-SPINE1_Ethernet13/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf7a
+ interfaces:
+ - name: Ethernet2/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet2/1 - P2P_LINK_TO_POD2-SPINE2_Ethernet13/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf7a
+ interfaces:
+ - name: Ethernet3/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet3/1 - P2P_LINK_TO_POD2-SPINE3_Ethernet13/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf7a
+ interfaces:
+ - name: Ethernet4/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet4/1 - P2P_LINK_TO_POD2-SPINE4_Ethernet13/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf7a
+ interfaces:
+ - name: Port-Channel531
+ status: up
+ result_overwrite:
+ custom_field: Interface Port-Channel531 - MLAG_PEER_pod2-leaf7b_Po531 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf7a
+ interfaces:
+ - name: Vlan4093
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan4093 - MLAG_PEER_L3_PEERING = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf7a
+ interfaces:
+ - name: Vlan4094
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan4094 - MLAG_PEER = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf7a
+ interfaces:
+ - name: Vlan11
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan11 - VRF10_VLAN11 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf7a
+ interfaces:
+ - name: Vlan12
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan12 - VRF10_VLAN12 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf7a
+ interfaces:
+ - name: Vlan3009
+ status: up
+ result_overwrite:
+ custom_field: 'Interface Vlan3009 - MLAG_PEER_L3_iBGP: vrf VRF10 = ''up'''
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf7a
+ interfaces:
+ - name: Vlan21
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan21 - VRF20_VLAN21 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf7a
+ interfaces:
+ - name: Vlan22
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan22 - VRF20_VLAN22 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf7a
+ interfaces:
+ - name: Vlan3019
+ status: up
+ result_overwrite:
+ custom_field: 'Interface Vlan3019 - MLAG_PEER_L3_iBGP: vrf VRF20 = ''up'''
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf7a
+ interfaces:
+ - name: Loopback0
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback0 - EVPN_Overlay_Peering = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf7a
+ interfaces:
+ - name: Loopback1
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback1 - VTEP_VXLAN_Tunnel_Source = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf7a
+ interfaces:
+ - name: Loopback10
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback10 - VRF10_VTEP_DIAGNOSTICS = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf7a
+ interfaces:
+ - name: Loopback20
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback20 - VRF20_VTEP_DIAGNOSTICS = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf7a
+ interfaces:
+ - name: Vxlan1
+ status: up
+ result_overwrite:
+ custom_field: Interface Vxlan1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf1a
+ interfaces:
+ - name: Ethernet53/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet53/1 - MLAG_PEER_pod1-leaf1b_Ethernet53/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf1a
+ interfaces:
+ - name: Ethernet54/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet54/1 - MLAG_PEER_pod1-leaf1b_Ethernet54/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf1a
+ interfaces:
+ - name: Ethernet1/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet1/1 - P2P_LINK_TO_POD1-SPINE1_Ethernet1/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf1a
+ interfaces:
+ - name: Ethernet2/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet2/1 - P2P_LINK_TO_POD1-SPINE2_Ethernet1/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf1a
+ interfaces:
+ - name: Ethernet3/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet3/1 - P2P_LINK_TO_POD1-SPINE3_Ethernet1/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf1a
+ interfaces:
+ - name: Ethernet4/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet4/1 - P2P_LINK_TO_POD1-SPINE4_Ethernet1/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf1a
+ interfaces:
+ - name: Port-Channel531
+ status: up
+ result_overwrite:
+ custom_field: Interface Port-Channel531 - MLAG_PEER_pod1-leaf1b_Po531 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf1a
+ interfaces:
+ - name: Vlan4093
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan4093 - MLAG_PEER_L3_PEERING = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf1a
+ interfaces:
+ - name: Vlan4094
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan4094 - MLAG_PEER = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf1a
+ interfaces:
+ - name: Vlan11
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan11 - VRF10_VLAN11 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf1a
+ interfaces:
+ - name: Vlan12
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan12 - VRF10_VLAN12 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf1a
+ interfaces:
+ - name: Vlan3009
+ status: up
+ result_overwrite:
+ custom_field: 'Interface Vlan3009 - MLAG_PEER_L3_iBGP: vrf VRF10 = ''up'''
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf1a
+ interfaces:
+ - name: Vlan21
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan21 - VRF20_VLAN21 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf1a
+ interfaces:
+ - name: Vlan22
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan22 - VRF20_VLAN22 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf1a
+ interfaces:
+ - name: Vlan3019
+ status: up
+ result_overwrite:
+ custom_field: 'Interface Vlan3019 - MLAG_PEER_L3_iBGP: vrf VRF20 = ''up'''
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf1a
+ interfaces:
+ - name: Loopback0
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback0 - EVPN_Overlay_Peering = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf1a
+ interfaces:
+ - name: Loopback1
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback1 - VTEP_VXLAN_Tunnel_Source = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf1a
+ interfaces:
+ - name: Loopback10
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback10 - VRF10_VTEP_DIAGNOSTICS = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf1a
+ interfaces:
+ - name: Loopback20
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback20 - VRF20_VTEP_DIAGNOSTICS = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf1a
+ interfaces:
+ - name: Vxlan1
+ status: up
+ result_overwrite:
+ custom_field: Interface Vxlan1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - super-spine1
+ interfaces:
+ - name: Ethernet1/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet1/1 - P2P_LINK_TO_POD1-SPINE1_Ethernet31/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - super-spine1
+ interfaces:
+ - name: Ethernet2/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet2/1 - P2P_LINK_TO_POD1-SPINE2_Ethernet31/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - super-spine1
+ interfaces:
+ - name: Ethernet3/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet3/1 - P2P_LINK_TO_POD1-SPINE3_Ethernet31/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - super-spine1
+ interfaces:
+ - name: Ethernet4/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet4/1 - P2P_LINK_TO_POD1-SPINE4_Ethernet31/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - super-spine1
+ interfaces:
+ - name: Ethernet5/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet5/1 - P2P_LINK_TO_POD2-SPINE1_Ethernet31/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - super-spine1
+ interfaces:
+ - name: Ethernet6/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet6/1 - P2P_LINK_TO_POD2-SPINE2_Ethernet31/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - super-spine1
+ interfaces:
+ - name: Ethernet7/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet7/1 - P2P_LINK_TO_POD2-SPINE3_Ethernet31/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - super-spine1
+ interfaces:
+ - name: Ethernet8/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet8/1 - P2P_LINK_TO_POD2-SPINE4_Ethernet31/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - super-spine1
+ interfaces:
+ - name: Loopback0
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback0 - EVPN_Overlay_Peering = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf6a
+ interfaces:
+ - name: Ethernet53/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet53/1 - MLAG_PEER_pod1-leaf6b_Ethernet53/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf6a
+ interfaces:
+ - name: Ethernet54/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet54/1 - MLAG_PEER_pod1-leaf6b_Ethernet54/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf6a
+ interfaces:
+ - name: Ethernet1/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet1/1 - P2P_LINK_TO_POD1-SPINE1_Ethernet11/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf6a
+ interfaces:
+ - name: Ethernet2/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet2/1 - P2P_LINK_TO_POD1-SPINE2_Ethernet11/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf6a
+ interfaces:
+ - name: Ethernet3/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet3/1 - P2P_LINK_TO_POD1-SPINE3_Ethernet11/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf6a
+ interfaces:
+ - name: Ethernet4/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet4/1 - P2P_LINK_TO_POD1-SPINE4_Ethernet11/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf6a
+ interfaces:
+ - name: Port-Channel531
+ status: up
+ result_overwrite:
+ custom_field: Interface Port-Channel531 - MLAG_PEER_pod1-leaf6b_Po531 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf6a
+ interfaces:
+ - name: Vlan4093
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan4093 - MLAG_PEER_L3_PEERING = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf6a
+ interfaces:
+ - name: Vlan4094
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan4094 - MLAG_PEER = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf6a
+ interfaces:
+ - name: Vlan11
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan11 - VRF10_VLAN11 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf6a
+ interfaces:
+ - name: Vlan12
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan12 - VRF10_VLAN12 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf6a
+ interfaces:
+ - name: Vlan3009
+ status: up
+ result_overwrite:
+ custom_field: 'Interface Vlan3009 - MLAG_PEER_L3_iBGP: vrf VRF10 = ''up'''
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf6a
+ interfaces:
+ - name: Vlan21
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan21 - VRF20_VLAN21 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf6a
+ interfaces:
+ - name: Vlan22
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan22 - VRF20_VLAN22 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf6a
+ interfaces:
+ - name: Vlan3019
+ status: up
+ result_overwrite:
+ custom_field: 'Interface Vlan3019 - MLAG_PEER_L3_iBGP: vrf VRF20 = ''up'''
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf6a
+ interfaces:
+ - name: Loopback0
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback0 - EVPN_Overlay_Peering = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf6a
+ interfaces:
+ - name: Loopback1
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback1 - VTEP_VXLAN_Tunnel_Source = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf6a
+ interfaces:
+ - name: Loopback10
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback10 - VRF10_VTEP_DIAGNOSTICS = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf6a
+ interfaces:
+ - name: Loopback20
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback20 - VRF20_VTEP_DIAGNOSTICS = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf6a
+ interfaces:
+ - name: Vxlan1
+ status: up
+ result_overwrite:
+ custom_field: Interface Vxlan1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf6a
+ interfaces:
+ - name: Ethernet53/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet53/1 - MLAG_PEER_pod2-leaf6b_Ethernet53/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf6a
+ interfaces:
+ - name: Ethernet54/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet54/1 - MLAG_PEER_pod2-leaf6b_Ethernet54/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf6a
+ interfaces:
+ - name: Ethernet1/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet1/1 - P2P_LINK_TO_POD2-SPINE1_Ethernet11/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf6a
+ interfaces:
+ - name: Ethernet2/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet2/1 - P2P_LINK_TO_POD2-SPINE2_Ethernet11/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf6a
+ interfaces:
+ - name: Ethernet3/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet3/1 - P2P_LINK_TO_POD2-SPINE3_Ethernet11/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf6a
+ interfaces:
+ - name: Ethernet4/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet4/1 - P2P_LINK_TO_POD2-SPINE4_Ethernet11/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf6a
+ interfaces:
+ - name: Port-Channel531
+ status: up
+ result_overwrite:
+ custom_field: Interface Port-Channel531 - MLAG_PEER_pod2-leaf6b_Po531 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf6a
+ interfaces:
+ - name: Vlan4093
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan4093 - MLAG_PEER_L3_PEERING = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf6a
+ interfaces:
+ - name: Vlan4094
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan4094 - MLAG_PEER = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf6a
+ interfaces:
+ - name: Vlan11
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan11 - VRF10_VLAN11 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf6a
+ interfaces:
+ - name: Vlan12
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan12 - VRF10_VLAN12 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf6a
+ interfaces:
+ - name: Vlan3009
+ status: up
+ result_overwrite:
+ custom_field: 'Interface Vlan3009 - MLAG_PEER_L3_iBGP: vrf VRF10 = ''up'''
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf6a
+ interfaces:
+ - name: Vlan21
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan21 - VRF20_VLAN21 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf6a
+ interfaces:
+ - name: Vlan22
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan22 - VRF20_VLAN22 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf6a
+ interfaces:
+ - name: Vlan3019
+ status: up
+ result_overwrite:
+ custom_field: 'Interface Vlan3019 - MLAG_PEER_L3_iBGP: vrf VRF20 = ''up'''
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf6a
+ interfaces:
+ - name: Loopback0
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback0 - EVPN_Overlay_Peering = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf6a
+ interfaces:
+ - name: Loopback1
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback1 - VTEP_VXLAN_Tunnel_Source = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf6a
+ interfaces:
+ - name: Loopback10
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback10 - VRF10_VTEP_DIAGNOSTICS = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf6a
+ interfaces:
+ - name: Loopback20
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback20 - VRF20_VTEP_DIAGNOSTICS = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf6a
+ interfaces:
+ - name: Vxlan1
+ status: up
+ result_overwrite:
+ custom_field: Interface Vxlan1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf1a
+ interfaces:
+ - name: Ethernet53/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet53/1 - MLAG_PEER_pod2-leaf1b_Ethernet53/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf1a
+ interfaces:
+ - name: Ethernet54/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet54/1 - MLAG_PEER_pod2-leaf1b_Ethernet54/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf1a
+ interfaces:
+ - name: Ethernet1/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet1/1 - P2P_LINK_TO_POD2-SPINE1_Ethernet1/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf1a
+ interfaces:
+ - name: Ethernet2/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet2/1 - P2P_LINK_TO_POD2-SPINE2_Ethernet1/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf1a
+ interfaces:
+ - name: Ethernet3/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet3/1 - P2P_LINK_TO_POD2-SPINE3_Ethernet1/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf1a
+ interfaces:
+ - name: Ethernet4/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet4/1 - P2P_LINK_TO_POD2-SPINE4_Ethernet1/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf1a
+ interfaces:
+ - name: Port-Channel531
+ status: up
+ result_overwrite:
+ custom_field: Interface Port-Channel531 - MLAG_PEER_pod2-leaf1b_Po531 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf1a
+ interfaces:
+ - name: Vlan4093
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan4093 - MLAG_PEER_L3_PEERING = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf1a
+ interfaces:
+ - name: Vlan4094
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan4094 - MLAG_PEER = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf1a
+ interfaces:
+ - name: Vlan11
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan11 - VRF10_VLAN11 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf1a
+ interfaces:
+ - name: Vlan12
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan12 - VRF10_VLAN12 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf1a
+ interfaces:
+ - name: Vlan3009
+ status: up
+ result_overwrite:
+ custom_field: 'Interface Vlan3009 - MLAG_PEER_L3_iBGP: vrf VRF10 = ''up'''
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf1a
+ interfaces:
+ - name: Vlan21
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan21 - VRF20_VLAN21 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf1a
+ interfaces:
+ - name: Vlan22
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan22 - VRF20_VLAN22 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf1a
+ interfaces:
+ - name: Vlan3019
+ status: up
+ result_overwrite:
+ custom_field: 'Interface Vlan3019 - MLAG_PEER_L3_iBGP: vrf VRF20 = ''up'''
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf1a
+ interfaces:
+ - name: Loopback0
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback0 - EVPN_Overlay_Peering = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf1a
+ interfaces:
+ - name: Loopback1
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback1 - VTEP_VXLAN_Tunnel_Source = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf1a
+ interfaces:
+ - name: Loopback10
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback10 - VRF10_VTEP_DIAGNOSTICS = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf1a
+ interfaces:
+ - name: Loopback20
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback20 - VRF20_VTEP_DIAGNOSTICS = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf1a
+ interfaces:
+ - name: Vxlan1
+ status: up
+ result_overwrite:
+ custom_field: Interface Vxlan1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf10b
+ interfaces:
+ - name: Ethernet53/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet53/1 - MLAG_PEER_pod1-leaf10a_Ethernet53/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf10b
+ interfaces:
+ - name: Ethernet54/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet54/1 - MLAG_PEER_pod1-leaf10a_Ethernet54/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf10b
+ interfaces:
+ - name: Ethernet1/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet1/1 - P2P_LINK_TO_POD1-SPINE1_Ethernet20/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf10b
+ interfaces:
+ - name: Ethernet2/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet2/1 - P2P_LINK_TO_POD1-SPINE2_Ethernet20/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf10b
+ interfaces:
+ - name: Ethernet3/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet3/1 - P2P_LINK_TO_POD1-SPINE3_Ethernet20/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf10b
+ interfaces:
+ - name: Ethernet4/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet4/1 - P2P_LINK_TO_POD1-SPINE4_Ethernet20/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf10b
+ interfaces:
+ - name: Port-Channel531
+ status: up
+ result_overwrite:
+ custom_field: Interface Port-Channel531 - MLAG_PEER_pod1-leaf10a_Po531 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf10b
+ interfaces:
+ - name: Vlan4093
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan4093 - MLAG_PEER_L3_PEERING = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf10b
+ interfaces:
+ - name: Vlan4094
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan4094 - MLAG_PEER = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf10b
+ interfaces:
+ - name: Vlan11
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan11 - VRF10_VLAN11 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf10b
+ interfaces:
+ - name: Vlan12
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan12 - VRF10_VLAN12 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf10b
+ interfaces:
+ - name: Vlan3009
+ status: up
+ result_overwrite:
+ custom_field: 'Interface Vlan3009 - MLAG_PEER_L3_iBGP: vrf VRF10 = ''up'''
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf10b
+ interfaces:
+ - name: Vlan21
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan21 - VRF20_VLAN21 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf10b
+ interfaces:
+ - name: Vlan22
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan22 - VRF20_VLAN22 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf10b
+ interfaces:
+ - name: Vlan3019
+ status: up
+ result_overwrite:
+ custom_field: 'Interface Vlan3019 - MLAG_PEER_L3_iBGP: vrf VRF20 = ''up'''
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf10b
+ interfaces:
+ - name: Loopback0
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback0 - EVPN_Overlay_Peering = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf10b
+ interfaces:
+ - name: Loopback1
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback1 - VTEP_VXLAN_Tunnel_Source = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf10b
+ interfaces:
+ - name: Loopback10
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback10 - VRF10_VTEP_DIAGNOSTICS = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf10b
+ interfaces:
+ - name: Loopback20
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback20 - VRF20_VTEP_DIAGNOSTICS = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf10b
+ interfaces:
+ - name: Vxlan1
+ status: up
+ result_overwrite:
+ custom_field: Interface Vxlan1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf7a
+ interfaces:
+ - name: Ethernet53/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet53/1 - MLAG_PEER_pod1-leaf7b_Ethernet53/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf7a
+ interfaces:
+ - name: Ethernet54/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet54/1 - MLAG_PEER_pod1-leaf7b_Ethernet54/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf7a
+ interfaces:
+ - name: Ethernet1/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet1/1 - P2P_LINK_TO_POD1-SPINE1_Ethernet13/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf7a
+ interfaces:
+ - name: Ethernet2/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet2/1 - P2P_LINK_TO_POD1-SPINE2_Ethernet13/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf7a
+ interfaces:
+ - name: Ethernet3/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet3/1 - P2P_LINK_TO_POD1-SPINE3_Ethernet13/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf7a
+ interfaces:
+ - name: Ethernet4/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet4/1 - P2P_LINK_TO_POD1-SPINE4_Ethernet13/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf7a
+ interfaces:
+ - name: Port-Channel531
+ status: up
+ result_overwrite:
+ custom_field: Interface Port-Channel531 - MLAG_PEER_pod1-leaf7b_Po531 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf7a
+ interfaces:
+ - name: Vlan4093
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan4093 - MLAG_PEER_L3_PEERING = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf7a
+ interfaces:
+ - name: Vlan4094
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan4094 - MLAG_PEER = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf7a
+ interfaces:
+ - name: Vlan11
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan11 - VRF10_VLAN11 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf7a
+ interfaces:
+ - name: Vlan12
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan12 - VRF10_VLAN12 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf7a
+ interfaces:
+ - name: Vlan3009
+ status: up
+ result_overwrite:
+ custom_field: 'Interface Vlan3009 - MLAG_PEER_L3_iBGP: vrf VRF10 = ''up'''
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf7a
+ interfaces:
+ - name: Vlan21
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan21 - VRF20_VLAN21 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf7a
+ interfaces:
+ - name: Vlan22
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan22 - VRF20_VLAN22 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf7a
+ interfaces:
+ - name: Vlan3019
+ status: up
+ result_overwrite:
+ custom_field: 'Interface Vlan3019 - MLAG_PEER_L3_iBGP: vrf VRF20 = ''up'''
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf7a
+ interfaces:
+ - name: Loopback0
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback0 - EVPN_Overlay_Peering = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf7a
+ interfaces:
+ - name: Loopback1
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback1 - VTEP_VXLAN_Tunnel_Source = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf7a
+ interfaces:
+ - name: Loopback10
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback10 - VRF10_VTEP_DIAGNOSTICS = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf7a
+ interfaces:
+ - name: Loopback20
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback20 - VRF20_VTEP_DIAGNOSTICS = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf7a
+ interfaces:
+ - name: Vxlan1
+ status: up
+ result_overwrite:
+ custom_field: Interface Vxlan1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf10b
+ interfaces:
+ - name: Ethernet53/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet53/1 - MLAG_PEER_pod2-leaf10a_Ethernet53/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf10b
+ interfaces:
+ - name: Ethernet54/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet54/1 - MLAG_PEER_pod2-leaf10a_Ethernet54/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf10b
+ interfaces:
+ - name: Ethernet1/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet1/1 - P2P_LINK_TO_POD2-SPINE1_Ethernet20/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf10b
+ interfaces:
+ - name: Ethernet2/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet2/1 - P2P_LINK_TO_POD2-SPINE2_Ethernet20/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf10b
+ interfaces:
+ - name: Ethernet3/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet3/1 - P2P_LINK_TO_POD2-SPINE3_Ethernet20/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf10b
+ interfaces:
+ - name: Ethernet4/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet4/1 - P2P_LINK_TO_POD2-SPINE4_Ethernet20/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf10b
+ interfaces:
+ - name: Port-Channel531
+ status: up
+ result_overwrite:
+ custom_field: Interface Port-Channel531 - MLAG_PEER_pod2-leaf10a_Po531 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf10b
+ interfaces:
+ - name: Vlan4093
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan4093 - MLAG_PEER_L3_PEERING = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf10b
+ interfaces:
+ - name: Vlan4094
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan4094 - MLAG_PEER = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf10b
+ interfaces:
+ - name: Vlan11
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan11 - VRF10_VLAN11 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf10b
+ interfaces:
+ - name: Vlan12
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan12 - VRF10_VLAN12 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf10b
+ interfaces:
+ - name: Vlan3009
+ status: up
+ result_overwrite:
+ custom_field: 'Interface Vlan3009 - MLAG_PEER_L3_iBGP: vrf VRF10 = ''up'''
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf10b
+ interfaces:
+ - name: Vlan21
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan21 - VRF20_VLAN21 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf10b
+ interfaces:
+ - name: Vlan22
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan22 - VRF20_VLAN22 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf10b
+ interfaces:
+ - name: Vlan3019
+ status: up
+ result_overwrite:
+ custom_field: 'Interface Vlan3019 - MLAG_PEER_L3_iBGP: vrf VRF20 = ''up'''
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf10b
+ interfaces:
+ - name: Loopback0
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback0 - EVPN_Overlay_Peering = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf10b
+ interfaces:
+ - name: Loopback1
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback1 - VTEP_VXLAN_Tunnel_Source = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf10b
+ interfaces:
+ - name: Loopback10
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback10 - VRF10_VTEP_DIAGNOSTICS = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf10b
+ interfaces:
+ - name: Loopback20
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback20 - VRF20_VTEP_DIAGNOSTICS = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf10b
+ interfaces:
+ - name: Vxlan1
+ status: up
+ result_overwrite:
+ custom_field: Interface Vxlan1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf10a
+ interfaces:
+ - name: Ethernet53/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet53/1 - MLAG_PEER_pod2-leaf10b_Ethernet53/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf10a
+ interfaces:
+ - name: Ethernet54/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet54/1 - MLAG_PEER_pod2-leaf10b_Ethernet54/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf10a
+ interfaces:
+ - name: Ethernet1/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet1/1 - P2P_LINK_TO_POD2-SPINE1_Ethernet19/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf10a
+ interfaces:
+ - name: Ethernet2/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet2/1 - P2P_LINK_TO_POD2-SPINE2_Ethernet19/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf10a
+ interfaces:
+ - name: Ethernet3/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet3/1 - P2P_LINK_TO_POD2-SPINE3_Ethernet19/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf10a
+ interfaces:
+ - name: Ethernet4/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet4/1 - P2P_LINK_TO_POD2-SPINE4_Ethernet19/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf10a
+ interfaces:
+ - name: Port-Channel531
+ status: up
+ result_overwrite:
+ custom_field: Interface Port-Channel531 - MLAG_PEER_pod2-leaf10b_Po531 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf10a
+ interfaces:
+ - name: Vlan4093
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan4093 - MLAG_PEER_L3_PEERING = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf10a
+ interfaces:
+ - name: Vlan4094
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan4094 - MLAG_PEER = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf10a
+ interfaces:
+ - name: Vlan11
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan11 - VRF10_VLAN11 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf10a
+ interfaces:
+ - name: Vlan12
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan12 - VRF10_VLAN12 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf10a
+ interfaces:
+ - name: Vlan3009
+ status: up
+ result_overwrite:
+ custom_field: 'Interface Vlan3009 - MLAG_PEER_L3_iBGP: vrf VRF10 = ''up'''
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf10a
+ interfaces:
+ - name: Vlan21
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan21 - VRF20_VLAN21 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf10a
+ interfaces:
+ - name: Vlan22
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan22 - VRF20_VLAN22 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf10a
+ interfaces:
+ - name: Vlan3019
+ status: up
+ result_overwrite:
+ custom_field: 'Interface Vlan3019 - MLAG_PEER_L3_iBGP: vrf VRF20 = ''up'''
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf10a
+ interfaces:
+ - name: Loopback0
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback0 - EVPN_Overlay_Peering = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf10a
+ interfaces:
+ - name: Loopback1
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback1 - VTEP_VXLAN_Tunnel_Source = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf10a
+ interfaces:
+ - name: Loopback10
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback10 - VRF10_VTEP_DIAGNOSTICS = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf10a
+ interfaces:
+ - name: Loopback20
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback20 - VRF20_VTEP_DIAGNOSTICS = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf10a
+ interfaces:
+ - name: Vxlan1
+ status: up
+ result_overwrite:
+ custom_field: Interface Vxlan1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-spine3
+ interfaces:
+ - name: Ethernet1/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet1/1 - P2P_LINK_TO_POD2-LEAF1A_Ethernet3/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-spine3
+ interfaces:
+ - name: Ethernet2/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet2/1 - P2P_LINK_TO_POD2-LEAF1B_Ethernet3/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-spine3
+ interfaces:
+ - name: Ethernet3/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet3/1 - P2P_LINK_TO_POD2-LEAF2A_Ethernet3/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-spine3
+ interfaces:
+ - name: Ethernet4/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet4/1 - P2P_LINK_TO_POD2-LEAF2B_Ethernet3/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-spine3
+ interfaces:
+ - name: Ethernet5/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet5/1 - P2P_LINK_TO_POD2-LEAF3A_Ethernet3/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-spine3
+ interfaces:
+ - name: Ethernet6/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet6/1 - P2P_LINK_TO_POD2-LEAF3B_Ethernet3/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-spine3
+ interfaces:
+ - name: Ethernet7/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet7/1 - P2P_LINK_TO_POD2-LEAF4A_Ethernet3/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-spine3
+ interfaces:
+ - name: Ethernet8/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet8/1 - P2P_LINK_TO_POD2-LEAF4B_Ethernet3/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-spine3
+ interfaces:
+ - name: Ethernet9/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet9/1 - P2P_LINK_TO_POD2-LEAF5A_Ethernet3/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-spine3
+ interfaces:
+ - name: Ethernet10/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet10/1 - P2P_LINK_TO_POD2-LEAF5B_Ethernet3/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-spine3
+ interfaces:
+ - name: Ethernet11/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet11/1 - P2P_LINK_TO_POD2-LEAF6A_Ethernet3/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-spine3
+ interfaces:
+ - name: Ethernet12/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet12/1 - P2P_LINK_TO_POD2-LEAF6B_Ethernet3/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-spine3
+ interfaces:
+ - name: Ethernet13/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet13/1 - P2P_LINK_TO_POD2-LEAF7A_Ethernet3/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-spine3
+ interfaces:
+ - name: Ethernet14/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet14/1 - P2P_LINK_TO_POD2-LEAF7B_Ethernet3/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-spine3
+ interfaces:
+ - name: Ethernet15/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet15/1 - P2P_LINK_TO_POD2-LEAF8A_Ethernet3/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-spine3
+ interfaces:
+ - name: Ethernet16/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet16/1 - P2P_LINK_TO_POD2-LEAF8B_Ethernet3/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-spine3
+ interfaces:
+ - name: Ethernet17/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet17/1 - P2P_LINK_TO_POD2-LEAF9A_Ethernet3/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-spine3
+ interfaces:
+ - name: Ethernet18/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet18/1 - P2P_LINK_TO_POD2-LEAF9B_Ethernet3/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-spine3
+ interfaces:
+ - name: Ethernet19/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet19/1 - P2P_LINK_TO_POD2-LEAF10A_Ethernet3/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-spine3
+ interfaces:
+ - name: Ethernet20/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet20/1 - P2P_LINK_TO_POD2-LEAF10B_Ethernet3/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-spine3
+ interfaces:
+ - name: Ethernet31/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet31/1 - P2P_LINK_TO_SUPER-SPINE1_Ethernet7/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-spine3
+ interfaces:
+ - name: Ethernet32/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet32/1 - P2P_LINK_TO_SUPER-SPINE2_Ethernet7/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-spine3
+ interfaces:
+ - name: Loopback0
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback0 - EVPN_Overlay_Peering = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf7b
+ interfaces:
+ - name: Ethernet53/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet53/1 - MLAG_PEER_pod1-leaf7a_Ethernet53/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf7b
+ interfaces:
+ - name: Ethernet54/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet54/1 - MLAG_PEER_pod1-leaf7a_Ethernet54/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf7b
+ interfaces:
+ - name: Ethernet1/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet1/1 - P2P_LINK_TO_POD1-SPINE1_Ethernet14/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf7b
+ interfaces:
+ - name: Ethernet2/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet2/1 - P2P_LINK_TO_POD1-SPINE2_Ethernet14/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf7b
+ interfaces:
+ - name: Ethernet3/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet3/1 - P2P_LINK_TO_POD1-SPINE3_Ethernet14/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf7b
+ interfaces:
+ - name: Ethernet4/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet4/1 - P2P_LINK_TO_POD1-SPINE4_Ethernet14/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf7b
+ interfaces:
+ - name: Port-Channel531
+ status: up
+ result_overwrite:
+ custom_field: Interface Port-Channel531 - MLAG_PEER_pod1-leaf7a_Po531 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf7b
+ interfaces:
+ - name: Vlan4093
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan4093 - MLAG_PEER_L3_PEERING = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf7b
+ interfaces:
+ - name: Vlan4094
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan4094 - MLAG_PEER = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf7b
+ interfaces:
+ - name: Vlan11
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan11 - VRF10_VLAN11 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf7b
+ interfaces:
+ - name: Vlan12
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan12 - VRF10_VLAN12 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf7b
+ interfaces:
+ - name: Vlan3009
+ status: up
+ result_overwrite:
+ custom_field: 'Interface Vlan3009 - MLAG_PEER_L3_iBGP: vrf VRF10 = ''up'''
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf7b
+ interfaces:
+ - name: Vlan21
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan21 - VRF20_VLAN21 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf7b
+ interfaces:
+ - name: Vlan22
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan22 - VRF20_VLAN22 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf7b
+ interfaces:
+ - name: Vlan3019
+ status: up
+ result_overwrite:
+ custom_field: 'Interface Vlan3019 - MLAG_PEER_L3_iBGP: vrf VRF20 = ''up'''
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf7b
+ interfaces:
+ - name: Loopback0
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback0 - EVPN_Overlay_Peering = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf7b
+ interfaces:
+ - name: Loopback1
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback1 - VTEP_VXLAN_Tunnel_Source = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf7b
+ interfaces:
+ - name: Loopback10
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback10 - VRF10_VTEP_DIAGNOSTICS = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf7b
+ interfaces:
+ - name: Loopback20
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback20 - VRF20_VTEP_DIAGNOSTICS = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf7b
+ interfaces:
+ - name: Vxlan1
+ status: up
+ result_overwrite:
+ custom_field: Interface Vxlan1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf10a
+ interfaces:
+ - name: Ethernet53/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet53/1 - MLAG_PEER_pod1-leaf10b_Ethernet53/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf10a
+ interfaces:
+ - name: Ethernet54/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet54/1 - MLAG_PEER_pod1-leaf10b_Ethernet54/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf10a
+ interfaces:
+ - name: Ethernet1/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet1/1 - P2P_LINK_TO_POD1-SPINE1_Ethernet19/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf10a
+ interfaces:
+ - name: Ethernet2/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet2/1 - P2P_LINK_TO_POD1-SPINE2_Ethernet19/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf10a
+ interfaces:
+ - name: Ethernet3/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet3/1 - P2P_LINK_TO_POD1-SPINE3_Ethernet19/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf10a
+ interfaces:
+ - name: Ethernet4/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet4/1 - P2P_LINK_TO_POD1-SPINE4_Ethernet19/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf10a
+ interfaces:
+ - name: Port-Channel531
+ status: up
+ result_overwrite:
+ custom_field: Interface Port-Channel531 - MLAG_PEER_pod1-leaf10b_Po531 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf10a
+ interfaces:
+ - name: Vlan4093
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan4093 - MLAG_PEER_L3_PEERING = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf10a
+ interfaces:
+ - name: Vlan4094
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan4094 - MLAG_PEER = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf10a
+ interfaces:
+ - name: Vlan11
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan11 - VRF10_VLAN11 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf10a
+ interfaces:
+ - name: Vlan12
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan12 - VRF10_VLAN12 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf10a
+ interfaces:
+ - name: Vlan3009
+ status: up
+ result_overwrite:
+ custom_field: 'Interface Vlan3009 - MLAG_PEER_L3_iBGP: vrf VRF10 = ''up'''
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf10a
+ interfaces:
+ - name: Vlan21
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan21 - VRF20_VLAN21 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf10a
+ interfaces:
+ - name: Vlan22
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan22 - VRF20_VLAN22 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf10a
+ interfaces:
+ - name: Vlan3019
+ status: up
+ result_overwrite:
+ custom_field: 'Interface Vlan3019 - MLAG_PEER_L3_iBGP: vrf VRF20 = ''up'''
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf10a
+ interfaces:
+ - name: Loopback0
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback0 - EVPN_Overlay_Peering = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf10a
+ interfaces:
+ - name: Loopback1
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback1 - VTEP_VXLAN_Tunnel_Source = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf10a
+ interfaces:
+ - name: Loopback10
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback10 - VRF10_VTEP_DIAGNOSTICS = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf10a
+ interfaces:
+ - name: Loopback20
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback20 - VRF20_VTEP_DIAGNOSTICS = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf10a
+ interfaces:
+ - name: Vxlan1
+ status: up
+ result_overwrite:
+ custom_field: Interface Vxlan1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf6b
+ interfaces:
+ - name: Ethernet53/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet53/1 - MLAG_PEER_pod2-leaf6a_Ethernet53/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf6b
+ interfaces:
+ - name: Ethernet54/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet54/1 - MLAG_PEER_pod2-leaf6a_Ethernet54/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf6b
+ interfaces:
+ - name: Ethernet1/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet1/1 - P2P_LINK_TO_POD2-SPINE1_Ethernet12/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf6b
+ interfaces:
+ - name: Ethernet2/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet2/1 - P2P_LINK_TO_POD2-SPINE2_Ethernet12/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf6b
+ interfaces:
+ - name: Ethernet3/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet3/1 - P2P_LINK_TO_POD2-SPINE3_Ethernet12/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf6b
+ interfaces:
+ - name: Ethernet4/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet4/1 - P2P_LINK_TO_POD2-SPINE4_Ethernet12/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf6b
+ interfaces:
+ - name: Port-Channel531
+ status: up
+ result_overwrite:
+ custom_field: Interface Port-Channel531 - MLAG_PEER_pod2-leaf6a_Po531 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf6b
+ interfaces:
+ - name: Vlan4093
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan4093 - MLAG_PEER_L3_PEERING = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf6b
+ interfaces:
+ - name: Vlan4094
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan4094 - MLAG_PEER = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf6b
+ interfaces:
+ - name: Vlan11
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan11 - VRF10_VLAN11 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf6b
+ interfaces:
+ - name: Vlan12
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan12 - VRF10_VLAN12 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf6b
+ interfaces:
+ - name: Vlan3009
+ status: up
+ result_overwrite:
+ custom_field: 'Interface Vlan3009 - MLAG_PEER_L3_iBGP: vrf VRF10 = ''up'''
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf6b
+ interfaces:
+ - name: Vlan21
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan21 - VRF20_VLAN21 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf6b
+ interfaces:
+ - name: Vlan22
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan22 - VRF20_VLAN22 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf6b
+ interfaces:
+ - name: Vlan3019
+ status: up
+ result_overwrite:
+ custom_field: 'Interface Vlan3019 - MLAG_PEER_L3_iBGP: vrf VRF20 = ''up'''
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf6b
+ interfaces:
+ - name: Loopback0
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback0 - EVPN_Overlay_Peering = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf6b
+ interfaces:
+ - name: Loopback1
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback1 - VTEP_VXLAN_Tunnel_Source = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf6b
+ interfaces:
+ - name: Loopback10
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback10 - VRF10_VTEP_DIAGNOSTICS = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf6b
+ interfaces:
+ - name: Loopback20
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback20 - VRF20_VTEP_DIAGNOSTICS = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf6b
+ interfaces:
+ - name: Vxlan1
+ status: up
+ result_overwrite:
+ custom_field: Interface Vxlan1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf1b
+ interfaces:
+ - name: Ethernet53/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet53/1 - MLAG_PEER_pod2-leaf1a_Ethernet53/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf1b
+ interfaces:
+ - name: Ethernet54/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet54/1 - MLAG_PEER_pod2-leaf1a_Ethernet54/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf1b
+ interfaces:
+ - name: Ethernet1/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet1/1 - P2P_LINK_TO_POD2-SPINE1_Ethernet2/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf1b
+ interfaces:
+ - name: Ethernet2/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet2/1 - P2P_LINK_TO_POD2-SPINE2_Ethernet2/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf1b
+ interfaces:
+ - name: Ethernet3/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet3/1 - P2P_LINK_TO_POD2-SPINE3_Ethernet2/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf1b
+ interfaces:
+ - name: Ethernet4/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet4/1 - P2P_LINK_TO_POD2-SPINE4_Ethernet2/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf1b
+ interfaces:
+ - name: Port-Channel531
+ status: up
+ result_overwrite:
+ custom_field: Interface Port-Channel531 - MLAG_PEER_pod2-leaf1a_Po531 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf1b
+ interfaces:
+ - name: Vlan4093
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan4093 - MLAG_PEER_L3_PEERING = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf1b
+ interfaces:
+ - name: Vlan4094
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan4094 - MLAG_PEER = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf1b
+ interfaces:
+ - name: Vlan11
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan11 - VRF10_VLAN11 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf1b
+ interfaces:
+ - name: Vlan12
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan12 - VRF10_VLAN12 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf1b
+ interfaces:
+ - name: Vlan3009
+ status: up
+ result_overwrite:
+ custom_field: 'Interface Vlan3009 - MLAG_PEER_L3_iBGP: vrf VRF10 = ''up'''
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf1b
+ interfaces:
+ - name: Vlan21
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan21 - VRF20_VLAN21 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf1b
+ interfaces:
+ - name: Vlan22
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan22 - VRF20_VLAN22 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf1b
+ interfaces:
+ - name: Vlan3019
+ status: up
+ result_overwrite:
+ custom_field: 'Interface Vlan3019 - MLAG_PEER_L3_iBGP: vrf VRF20 = ''up'''
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf1b
+ interfaces:
+ - name: Loopback0
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback0 - EVPN_Overlay_Peering = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf1b
+ interfaces:
+ - name: Loopback1
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback1 - VTEP_VXLAN_Tunnel_Source = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf1b
+ interfaces:
+ - name: Loopback10
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback10 - VRF10_VTEP_DIAGNOSTICS = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf1b
+ interfaces:
+ - name: Loopback20
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback20 - VRF20_VTEP_DIAGNOSTICS = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf1b
+ interfaces:
+ - name: Vxlan1
+ status: up
+ result_overwrite:
+ custom_field: Interface Vxlan1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - super-spine2
+ interfaces:
+ - name: Ethernet1/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet1/1 - P2P_LINK_TO_POD1-SPINE1_Ethernet32/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - super-spine2
+ interfaces:
+ - name: Ethernet2/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet2/1 - P2P_LINK_TO_POD1-SPINE2_Ethernet32/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - super-spine2
+ interfaces:
+ - name: Ethernet3/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet3/1 - P2P_LINK_TO_POD1-SPINE3_Ethernet32/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - super-spine2
+ interfaces:
+ - name: Ethernet4/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet4/1 - P2P_LINK_TO_POD1-SPINE4_Ethernet32/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - super-spine2
+ interfaces:
+ - name: Ethernet5/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet5/1 - P2P_LINK_TO_POD2-SPINE1_Ethernet32/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - super-spine2
+ interfaces:
+ - name: Ethernet6/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet6/1 - P2P_LINK_TO_POD2-SPINE2_Ethernet32/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - super-spine2
+ interfaces:
+ - name: Ethernet7/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet7/1 - P2P_LINK_TO_POD2-SPINE3_Ethernet32/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - super-spine2
+ interfaces:
+ - name: Ethernet8/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet8/1 - P2P_LINK_TO_POD2-SPINE4_Ethernet32/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - super-spine2
+ interfaces:
+ - name: Loopback0
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback0 - EVPN_Overlay_Peering = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf1b
+ interfaces:
+ - name: Ethernet53/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet53/1 - MLAG_PEER_pod1-leaf1a_Ethernet53/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf1b
+ interfaces:
+ - name: Ethernet54/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet54/1 - MLAG_PEER_pod1-leaf1a_Ethernet54/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf1b
+ interfaces:
+ - name: Ethernet1/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet1/1 - P2P_LINK_TO_POD1-SPINE1_Ethernet2/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf1b
+ interfaces:
+ - name: Ethernet2/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet2/1 - P2P_LINK_TO_POD1-SPINE2_Ethernet2/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf1b
+ interfaces:
+ - name: Ethernet3/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet3/1 - P2P_LINK_TO_POD1-SPINE3_Ethernet2/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf1b
+ interfaces:
+ - name: Ethernet4/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet4/1 - P2P_LINK_TO_POD1-SPINE4_Ethernet2/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf1b
+ interfaces:
+ - name: Port-Channel531
+ status: up
+ result_overwrite:
+ custom_field: Interface Port-Channel531 - MLAG_PEER_pod1-leaf1a_Po531 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf1b
+ interfaces:
+ - name: Vlan4093
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan4093 - MLAG_PEER_L3_PEERING = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf1b
+ interfaces:
+ - name: Vlan4094
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan4094 - MLAG_PEER = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf1b
+ interfaces:
+ - name: Vlan11
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan11 - VRF10_VLAN11 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf1b
+ interfaces:
+ - name: Vlan12
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan12 - VRF10_VLAN12 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf1b
+ interfaces:
+ - name: Vlan3009
+ status: up
+ result_overwrite:
+ custom_field: 'Interface Vlan3009 - MLAG_PEER_L3_iBGP: vrf VRF10 = ''up'''
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf1b
+ interfaces:
+ - name: Vlan21
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan21 - VRF20_VLAN21 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf1b
+ interfaces:
+ - name: Vlan22
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan22 - VRF20_VLAN22 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf1b
+ interfaces:
+ - name: Vlan3019
+ status: up
+ result_overwrite:
+ custom_field: 'Interface Vlan3019 - MLAG_PEER_L3_iBGP: vrf VRF20 = ''up'''
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf1b
+ interfaces:
+ - name: Loopback0
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback0 - EVPN_Overlay_Peering = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf1b
+ interfaces:
+ - name: Loopback1
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback1 - VTEP_VXLAN_Tunnel_Source = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf1b
+ interfaces:
+ - name: Loopback10
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback10 - VRF10_VTEP_DIAGNOSTICS = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf1b
+ interfaces:
+ - name: Loopback20
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback20 - VRF20_VTEP_DIAGNOSTICS = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf1b
+ interfaces:
+ - name: Vxlan1
+ status: up
+ result_overwrite:
+ custom_field: Interface Vxlan1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf6b
+ interfaces:
+ - name: Ethernet53/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet53/1 - MLAG_PEER_pod1-leaf6a_Ethernet53/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf6b
+ interfaces:
+ - name: Ethernet54/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet54/1 - MLAG_PEER_pod1-leaf6a_Ethernet54/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf6b
+ interfaces:
+ - name: Ethernet1/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet1/1 - P2P_LINK_TO_POD1-SPINE1_Ethernet12/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf6b
+ interfaces:
+ - name: Ethernet2/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet2/1 - P2P_LINK_TO_POD1-SPINE2_Ethernet12/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf6b
+ interfaces:
+ - name: Ethernet3/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet3/1 - P2P_LINK_TO_POD1-SPINE3_Ethernet12/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf6b
+ interfaces:
+ - name: Ethernet4/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet4/1 - P2P_LINK_TO_POD1-SPINE4_Ethernet12/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf6b
+ interfaces:
+ - name: Port-Channel531
+ status: up
+ result_overwrite:
+ custom_field: Interface Port-Channel531 - MLAG_PEER_pod1-leaf6a_Po531 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf6b
+ interfaces:
+ - name: Vlan4093
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan4093 - MLAG_PEER_L3_PEERING = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf6b
+ interfaces:
+ - name: Vlan4094
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan4094 - MLAG_PEER = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf6b
+ interfaces:
+ - name: Vlan11
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan11 - VRF10_VLAN11 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf6b
+ interfaces:
+ - name: Vlan12
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan12 - VRF10_VLAN12 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf6b
+ interfaces:
+ - name: Vlan3009
+ status: up
+ result_overwrite:
+ custom_field: 'Interface Vlan3009 - MLAG_PEER_L3_iBGP: vrf VRF10 = ''up'''
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf6b
+ interfaces:
+ - name: Vlan21
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan21 - VRF20_VLAN21 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf6b
+ interfaces:
+ - name: Vlan22
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan22 - VRF20_VLAN22 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf6b
+ interfaces:
+ - name: Vlan3019
+ status: up
+ result_overwrite:
+ custom_field: 'Interface Vlan3019 - MLAG_PEER_L3_iBGP: vrf VRF20 = ''up'''
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf6b
+ interfaces:
+ - name: Loopback0
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback0 - EVPN_Overlay_Peering = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf6b
+ interfaces:
+ - name: Loopback1
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback1 - VTEP_VXLAN_Tunnel_Source = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf6b
+ interfaces:
+ - name: Loopback10
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback10 - VRF10_VTEP_DIAGNOSTICS = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf6b
+ interfaces:
+ - name: Loopback20
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback20 - VRF20_VTEP_DIAGNOSTICS = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-leaf6b
+ interfaces:
+ - name: Vxlan1
+ status: up
+ result_overwrite:
+ custom_field: Interface Vxlan1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf7b
+ interfaces:
+ - name: Ethernet53/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet53/1 - MLAG_PEER_pod2-leaf7a_Ethernet53/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf7b
+ interfaces:
+ - name: Ethernet54/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet54/1 - MLAG_PEER_pod2-leaf7a_Ethernet54/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf7b
+ interfaces:
+ - name: Ethernet1/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet1/1 - P2P_LINK_TO_POD2-SPINE1_Ethernet14/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf7b
+ interfaces:
+ - name: Ethernet2/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet2/1 - P2P_LINK_TO_POD2-SPINE2_Ethernet14/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf7b
+ interfaces:
+ - name: Ethernet3/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet3/1 - P2P_LINK_TO_POD2-SPINE3_Ethernet14/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf7b
+ interfaces:
+ - name: Ethernet4/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet4/1 - P2P_LINK_TO_POD2-SPINE4_Ethernet14/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf7b
+ interfaces:
+ - name: Port-Channel531
+ status: up
+ result_overwrite:
+ custom_field: Interface Port-Channel531 - MLAG_PEER_pod2-leaf7a_Po531 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf7b
+ interfaces:
+ - name: Vlan4093
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan4093 - MLAG_PEER_L3_PEERING = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf7b
+ interfaces:
+ - name: Vlan4094
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan4094 - MLAG_PEER = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf7b
+ interfaces:
+ - name: Vlan11
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan11 - VRF10_VLAN11 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf7b
+ interfaces:
+ - name: Vlan12
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan12 - VRF10_VLAN12 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf7b
+ interfaces:
+ - name: Vlan3009
+ status: up
+ result_overwrite:
+ custom_field: 'Interface Vlan3009 - MLAG_PEER_L3_iBGP: vrf VRF10 = ''up'''
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf7b
+ interfaces:
+ - name: Vlan21
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan21 - VRF20_VLAN21 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf7b
+ interfaces:
+ - name: Vlan22
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan22 - VRF20_VLAN22 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf7b
+ interfaces:
+ - name: Vlan3019
+ status: up
+ result_overwrite:
+ custom_field: 'Interface Vlan3019 - MLAG_PEER_L3_iBGP: vrf VRF20 = ''up'''
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf7b
+ interfaces:
+ - name: Loopback0
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback0 - EVPN_Overlay_Peering = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf7b
+ interfaces:
+ - name: Loopback1
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback1 - VTEP_VXLAN_Tunnel_Source = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf7b
+ interfaces:
+ - name: Loopback10
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback10 - VRF10_VTEP_DIAGNOSTICS = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf7b
+ interfaces:
+ - name: Loopback20
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback20 - VRF20_VTEP_DIAGNOSTICS = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod2-leaf7b
+ interfaces:
+ - name: Vxlan1
+ status: up
+ result_overwrite:
+ custom_field: Interface Vxlan1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-spine3
+ interfaces:
+ - name: Ethernet1/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet1/1 - P2P_LINK_TO_POD1-LEAF1A_Ethernet3/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-spine3
+ interfaces:
+ - name: Ethernet2/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet2/1 - P2P_LINK_TO_POD1-LEAF1B_Ethernet3/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-spine3
+ interfaces:
+ - name: Ethernet3/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet3/1 - P2P_LINK_TO_POD1-LEAF2A_Ethernet3/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-spine3
+ interfaces:
+ - name: Ethernet4/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet4/1 - P2P_LINK_TO_POD1-LEAF2B_Ethernet3/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-spine3
+ interfaces:
+ - name: Ethernet5/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet5/1 - P2P_LINK_TO_POD1-LEAF3A_Ethernet3/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-spine3
+ interfaces:
+ - name: Ethernet6/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet6/1 - P2P_LINK_TO_POD1-LEAF3B_Ethernet3/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-spine3
+ interfaces:
+ - name: Ethernet7/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet7/1 - P2P_LINK_TO_POD1-LEAF4A_Ethernet3/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-spine3
+ interfaces:
+ - name: Ethernet8/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet8/1 - P2P_LINK_TO_POD1-LEAF4B_Ethernet3/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-spine3
+ interfaces:
+ - name: Ethernet9/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet9/1 - P2P_LINK_TO_POD1-LEAF5A_Ethernet3/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-spine3
+ interfaces:
+ - name: Ethernet10/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet10/1 - P2P_LINK_TO_POD1-LEAF5B_Ethernet3/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-spine3
+ interfaces:
+ - name: Ethernet11/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet11/1 - P2P_LINK_TO_POD1-LEAF6A_Ethernet3/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-spine3
+ interfaces:
+ - name: Ethernet12/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet12/1 - P2P_LINK_TO_POD1-LEAF6B_Ethernet3/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-spine3
+ interfaces:
+ - name: Ethernet13/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet13/1 - P2P_LINK_TO_POD1-LEAF7A_Ethernet3/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-spine3
+ interfaces:
+ - name: Ethernet14/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet14/1 - P2P_LINK_TO_POD1-LEAF7B_Ethernet3/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-spine3
+ interfaces:
+ - name: Ethernet15/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet15/1 - P2P_LINK_TO_POD1-LEAF8A_Ethernet3/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-spine3
+ interfaces:
+ - name: Ethernet16/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet16/1 - P2P_LINK_TO_POD1-LEAF8B_Ethernet3/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-spine3
+ interfaces:
+ - name: Ethernet17/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet17/1 - P2P_LINK_TO_POD1-LEAF9A_Ethernet3/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-spine3
+ interfaces:
+ - name: Ethernet18/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet18/1 - P2P_LINK_TO_POD1-LEAF9B_Ethernet3/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-spine3
+ interfaces:
+ - name: Ethernet19/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet19/1 - P2P_LINK_TO_POD1-LEAF10A_Ethernet3/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-spine3
+ interfaces:
+ - name: Ethernet20/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet20/1 - P2P_LINK_TO_POD1-LEAF10B_Ethernet3/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-spine3
+ interfaces:
+ - name: Ethernet31/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet31/1 - P2P_LINK_TO_SUPER-SPINE1_Ethernet3/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-spine3
+ interfaces:
+ - name: Ethernet32/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet32/1 - P2P_LINK_TO_SUPER-SPINE2_Ethernet3/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - pod1-spine3
+ interfaces:
+ - name: Loopback0
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback0 - EVPN_Overlay_Peering = 'up'
+anta.tests.mlag:
+- VerifyMlagStatus:
+ filters:
+ tags:
+ - pod1-leaf4b
+- VerifyMlagStatus:
+ filters:
+ tags:
+ - pod1-leaf3b
+- VerifyMlagStatus:
+ filters:
+ tags:
+ - pod1-leaf9a
+- VerifyMlagStatus:
+ filters:
+ tags:
+ - pod2-leaf5b
+- VerifyMlagStatus:
+ filters:
+ tags:
+ - pod2-leaf2b
+- VerifyMlagStatus:
+ filters:
+ tags:
+ - pod2-leaf8a
+- VerifyMlagStatus:
+ filters:
+ tags:
+ - pod1-leaf2b
+- VerifyMlagStatus:
+ filters:
+ tags:
+ - pod1-leaf5b
+- VerifyMlagStatus:
+ filters:
+ tags:
+ - pod1-leaf8a
+- VerifyMlagStatus:
+ filters:
+ tags:
+ - pod2-leaf3b
+- VerifyMlagStatus:
+ filters:
+ tags:
+ - pod2-leaf4b
+- VerifyMlagStatus:
+ filters:
+ tags:
+ - pod2-leaf9a
+- VerifyMlagStatus:
+ filters:
+ tags:
+ - pod2-leaf9b
+- VerifyMlagStatus:
+ filters:
+ tags:
+ - pod2-leaf3a
+- VerifyMlagStatus:
+ filters:
+ tags:
+ - pod2-leaf4a
+- VerifyMlagStatus:
+ filters:
+ tags:
+ - pod1-leaf8b
+- VerifyMlagStatus:
+ filters:
+ tags:
+ - pod1-leaf2a
+- VerifyMlagStatus:
+ filters:
+ tags:
+ - pod1-leaf5a
+- VerifyMlagStatus:
+ filters:
+ tags:
+ - pod2-leaf8b
+- VerifyMlagStatus:
+ filters:
+ tags:
+ - pod2-leaf5a
+- VerifyMlagStatus:
+ filters:
+ tags:
+ - pod2-leaf2a
+- VerifyMlagStatus:
+ filters:
+ tags:
+ - pod1-leaf9b
+- VerifyMlagStatus:
+ filters:
+ tags:
+ - pod1-leaf4a
+- VerifyMlagStatus:
+ filters:
+ tags:
+ - pod1-leaf3a
+- VerifyMlagStatus:
+ filters:
+ tags:
+ - pod2-leaf7a
+- VerifyMlagStatus:
+ filters:
+ tags:
+ - pod1-leaf1a
+- VerifyMlagStatus:
+ filters:
+ tags:
+ - pod1-leaf6a
+- VerifyMlagStatus:
+ filters:
+ tags:
+ - pod2-leaf6a
+- VerifyMlagStatus:
+ filters:
+ tags:
+ - pod2-leaf1a
+- VerifyMlagStatus:
+ filters:
+ tags:
+ - pod1-leaf10b
+- VerifyMlagStatus:
+ filters:
+ tags:
+ - pod1-leaf7a
+- VerifyMlagStatus:
+ filters:
+ tags:
+ - pod2-leaf10b
+- VerifyMlagStatus:
+ filters:
+ tags:
+ - pod2-leaf10a
+- VerifyMlagStatus:
+ filters:
+ tags:
+ - pod1-leaf7b
+- VerifyMlagStatus:
+ filters:
+ tags:
+ - pod1-leaf10a
+- VerifyMlagStatus:
+ filters:
+ tags:
+ - pod2-leaf6b
+- VerifyMlagStatus:
+ filters:
+ tags:
+ - pod2-leaf1b
+- VerifyMlagStatus:
+ filters:
+ tags:
+ - pod1-leaf1b
+- VerifyMlagStatus:
+ filters:
+ tags:
+ - pod1-leaf6b
+- VerifyMlagStatus:
+ filters:
+ tags:
+ - pod2-leaf7b
+anta.tests.routing.bgp:
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.1.1
+ filters:
+ tags:
+ - pod1-leaf4b
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod1-spine1 (IP: 10.255.1.1)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.1.2
+ filters:
+ tags:
+ - pod1-leaf4b
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod1-spine2 (IP: 10.255.1.2)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.1.3
+ filters:
+ tags:
+ - pod1-leaf4b
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod1-spine3 (IP: 10.255.1.3)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.1.4
+ filters:
+ tags:
+ - pod1-leaf4b
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod1-spine4 (IP: 10.255.1.4)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.253.12
+ safi: unicast
+ filters:
+ tags:
+ - pod1-leaf4b
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-leaf4a (IP: 10.255.253.12)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.56
+ safi: unicast
+ filters:
+ tags:
+ - pod1-leaf4b
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-spine1 (IP: 10.255.255.56)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.58
+ safi: unicast
+ filters:
+ tags:
+ - pod1-leaf4b
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-spine2 (IP: 10.255.255.58)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.60
+ safi: unicast
+ filters:
+ tags:
+ - pod1-leaf4b
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-spine3 (IP: 10.255.255.60)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.62
+ safi: unicast
+ filters:
+ tags:
+ - pod1-leaf4b
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-spine4 (IP: 10.255.255.62)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.2.5
+ filters:
+ tags:
+ - pod2-spine1
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod2-leaf1a (IP: 10.255.2.5)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.2.6
+ filters:
+ tags:
+ - pod2-spine1
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod2-leaf1b (IP: 10.255.2.6)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.2.7
+ filters:
+ tags:
+ - pod2-spine1
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod2-leaf2a (IP: 10.255.2.7)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.2.8
+ filters:
+ tags:
+ - pod2-spine1
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod2-leaf2b (IP: 10.255.2.8)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.2.9
+ filters:
+ tags:
+ - pod2-spine1
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod2-leaf3a (IP: 10.255.2.9)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.2.10
+ filters:
+ tags:
+ - pod2-spine1
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod2-leaf3b (IP: 10.255.2.10)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.2.11
+ filters:
+ tags:
+ - pod2-spine1
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod2-leaf4a (IP: 10.255.2.11)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.2.12
+ filters:
+ tags:
+ - pod2-spine1
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod2-leaf4b (IP: 10.255.2.12)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.2.13
+ filters:
+ tags:
+ - pod2-spine1
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod2-leaf5a (IP: 10.255.2.13)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.2.14
+ filters:
+ tags:
+ - pod2-spine1
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod2-leaf5b (IP: 10.255.2.14)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.2.15
+ filters:
+ tags:
+ - pod2-spine1
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod2-leaf6a (IP: 10.255.2.15)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.2.16
+ filters:
+ tags:
+ - pod2-spine1
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod2-leaf6b (IP: 10.255.2.16)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.2.17
+ filters:
+ tags:
+ - pod2-spine1
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod2-leaf7a (IP: 10.255.2.17)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.2.18
+ filters:
+ tags:
+ - pod2-spine1
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod2-leaf7b (IP: 10.255.2.18)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.2.19
+ filters:
+ tags:
+ - pod2-spine1
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod2-leaf8a (IP: 10.255.2.19)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.2.20
+ filters:
+ tags:
+ - pod2-spine1
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod2-leaf8b (IP: 10.255.2.20)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.2.21
+ filters:
+ tags:
+ - pod2-spine1
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod2-leaf9a (IP: 10.255.2.21)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.2.22
+ filters:
+ tags:
+ - pod2-spine1
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod2-leaf9b (IP: 10.255.2.22)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.2.23
+ filters:
+ tags:
+ - pod2-spine1
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod2-leaf10a (IP: 10.255.2.23)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.2.24
+ filters:
+ tags:
+ - pod2-spine1
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod2-leaf10b (IP: 10.255.2.24)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.1
+ safi: unicast
+ filters:
+ tags:
+ - pod2-spine1
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-leaf1a (IP: 10.255.255.1)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.9
+ safi: unicast
+ filters:
+ tags:
+ - pod2-spine1
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-leaf1b (IP: 10.255.255.9)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.17
+ safi: unicast
+ filters:
+ tags:
+ - pod2-spine1
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-leaf2a (IP: 10.255.255.17)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.25
+ safi: unicast
+ filters:
+ tags:
+ - pod2-spine1
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-leaf2b (IP: 10.255.255.25)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.33
+ safi: unicast
+ filters:
+ tags:
+ - pod2-spine1
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-leaf3a (IP: 10.255.255.33)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.41
+ safi: unicast
+ filters:
+ tags:
+ - pod2-spine1
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-leaf3b (IP: 10.255.255.41)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.49
+ safi: unicast
+ filters:
+ tags:
+ - pod2-spine1
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-leaf4a (IP: 10.255.255.49)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.57
+ safi: unicast
+ filters:
+ tags:
+ - pod2-spine1
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-leaf4b (IP: 10.255.255.57)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.65
+ safi: unicast
+ filters:
+ tags:
+ - pod2-spine1
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-leaf5a (IP: 10.255.255.65)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.73
+ safi: unicast
+ filters:
+ tags:
+ - pod2-spine1
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-leaf5b (IP: 10.255.255.73)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.81
+ safi: unicast
+ filters:
+ tags:
+ - pod2-spine1
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-leaf6a (IP: 10.255.255.81)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.89
+ safi: unicast
+ filters:
+ tags:
+ - pod2-spine1
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-leaf6b (IP: 10.255.255.89)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.97
+ safi: unicast
+ filters:
+ tags:
+ - pod2-spine1
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-leaf7a (IP: 10.255.255.97)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.105
+ safi: unicast
+ filters:
+ tags:
+ - pod2-spine1
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-leaf7b (IP: 10.255.255.105)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.113
+ safi: unicast
+ filters:
+ tags:
+ - pod2-spine1
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-leaf8a (IP: 10.255.255.113)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.121
+ safi: unicast
+ filters:
+ tags:
+ - pod2-spine1
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-leaf8b (IP: 10.255.255.121)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.129
+ safi: unicast
+ filters:
+ tags:
+ - pod2-spine1
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-leaf9a (IP: 10.255.255.129)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.137
+ safi: unicast
+ filters:
+ tags:
+ - pod2-spine1
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-leaf9b (IP: 10.255.255.137)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.145
+ safi: unicast
+ filters:
+ tags:
+ - pod2-spine1
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-leaf10a (IP: 10.255.255.145)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.153
+ safi: unicast
+ filters:
+ tags:
+ - pod2-spine1
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-leaf10b (IP: 10.255.255.153)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.128
+ safi: unicast
+ filters:
+ tags:
+ - pod2-spine1
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: super-spine1 (IP: 10.255.255.128)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.130
+ safi: unicast
+ filters:
+ tags:
+ - pod2-spine1
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: super-spine2 (IP: 10.255.255.130)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.1.1
+ filters:
+ tags:
+ - pod1-leaf3b
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod1-spine1 (IP: 10.255.1.1)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.1.2
+ filters:
+ tags:
+ - pod1-leaf3b
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod1-spine2 (IP: 10.255.1.2)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.1.3
+ filters:
+ tags:
+ - pod1-leaf3b
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod1-spine3 (IP: 10.255.1.3)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.1.4
+ filters:
+ tags:
+ - pod1-leaf3b
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod1-spine4 (IP: 10.255.1.4)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.253.8
+ safi: unicast
+ filters:
+ tags:
+ - pod1-leaf3b
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-leaf3a (IP: 10.255.253.8)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.40
+ safi: unicast
+ filters:
+ tags:
+ - pod1-leaf3b
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-spine1 (IP: 10.255.255.40)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.42
+ safi: unicast
+ filters:
+ tags:
+ - pod1-leaf3b
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-spine2 (IP: 10.255.255.42)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.44
+ safi: unicast
+ filters:
+ tags:
+ - pod1-leaf3b
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-spine3 (IP: 10.255.255.44)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.46
+ safi: unicast
+ filters:
+ tags:
+ - pod1-leaf3b
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-spine4 (IP: 10.255.255.46)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.1.1
+ filters:
+ tags:
+ - pod1-leaf9a
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod1-spine1 (IP: 10.255.1.1)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.1.2
+ filters:
+ tags:
+ - pod1-leaf9a
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod1-spine2 (IP: 10.255.1.2)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.1.3
+ filters:
+ tags:
+ - pod1-leaf9a
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod1-spine3 (IP: 10.255.1.3)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.1.4
+ filters:
+ tags:
+ - pod1-leaf9a
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod1-spine4 (IP: 10.255.1.4)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.253.33
+ safi: unicast
+ filters:
+ tags:
+ - pod1-leaf9a
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-leaf9b (IP: 10.255.253.33)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.128
+ safi: unicast
+ filters:
+ tags:
+ - pod1-leaf9a
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-spine1 (IP: 10.255.255.128)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.130
+ safi: unicast
+ filters:
+ tags:
+ - pod1-leaf9a
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-spine2 (IP: 10.255.255.130)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.132
+ safi: unicast
+ filters:
+ tags:
+ - pod1-leaf9a
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-spine3 (IP: 10.255.255.132)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.134
+ safi: unicast
+ filters:
+ tags:
+ - pod1-leaf9a
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-spine4 (IP: 10.255.255.134)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.1.5
+ filters:
+ tags:
+ - pod1-spine4
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod1-leaf1a (IP: 10.255.1.5)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.1.6
+ filters:
+ tags:
+ - pod1-spine4
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod1-leaf1b (IP: 10.255.1.6)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.1.7
+ filters:
+ tags:
+ - pod1-spine4
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod1-leaf2a (IP: 10.255.1.7)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.1.8
+ filters:
+ tags:
+ - pod1-spine4
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod1-leaf2b (IP: 10.255.1.8)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.1.9
+ filters:
+ tags:
+ - pod1-spine4
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod1-leaf3a (IP: 10.255.1.9)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.1.10
+ filters:
+ tags:
+ - pod1-spine4
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod1-leaf3b (IP: 10.255.1.10)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.1.11
+ filters:
+ tags:
+ - pod1-spine4
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod1-leaf4a (IP: 10.255.1.11)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.1.12
+ filters:
+ tags:
+ - pod1-spine4
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod1-leaf4b (IP: 10.255.1.12)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.1.13
+ filters:
+ tags:
+ - pod1-spine4
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod1-leaf5a (IP: 10.255.1.13)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.1.14
+ filters:
+ tags:
+ - pod1-spine4
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod1-leaf5b (IP: 10.255.1.14)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.1.15
+ filters:
+ tags:
+ - pod1-spine4
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod1-leaf6a (IP: 10.255.1.15)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.1.16
+ filters:
+ tags:
+ - pod1-spine4
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod1-leaf6b (IP: 10.255.1.16)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.1.17
+ filters:
+ tags:
+ - pod1-spine4
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod1-leaf7a (IP: 10.255.1.17)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.1.18
+ filters:
+ tags:
+ - pod1-spine4
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod1-leaf7b (IP: 10.255.1.18)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.1.19
+ filters:
+ tags:
+ - pod1-spine4
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod1-leaf8a (IP: 10.255.1.19)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.1.20
+ filters:
+ tags:
+ - pod1-spine4
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod1-leaf8b (IP: 10.255.1.20)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.1.21
+ filters:
+ tags:
+ - pod1-spine4
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod1-leaf9a (IP: 10.255.1.21)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.1.22
+ filters:
+ tags:
+ - pod1-spine4
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod1-leaf9b (IP: 10.255.1.22)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.1.23
+ filters:
+ tags:
+ - pod1-spine4
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod1-leaf10a (IP: 10.255.1.23)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.1.24
+ filters:
+ tags:
+ - pod1-spine4
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod1-leaf10b (IP: 10.255.1.24)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.7
+ safi: unicast
+ filters:
+ tags:
+ - pod1-spine4
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-leaf1a (IP: 10.255.255.7)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.15
+ safi: unicast
+ filters:
+ tags:
+ - pod1-spine4
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-leaf1b (IP: 10.255.255.15)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.23
+ safi: unicast
+ filters:
+ tags:
+ - pod1-spine4
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-leaf2a (IP: 10.255.255.23)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.31
+ safi: unicast
+ filters:
+ tags:
+ - pod1-spine4
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-leaf2b (IP: 10.255.255.31)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.39
+ safi: unicast
+ filters:
+ tags:
+ - pod1-spine4
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-leaf3a (IP: 10.255.255.39)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.47
+ safi: unicast
+ filters:
+ tags:
+ - pod1-spine4
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-leaf3b (IP: 10.255.255.47)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.55
+ safi: unicast
+ filters:
+ tags:
+ - pod1-spine4
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-leaf4a (IP: 10.255.255.55)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.63
+ safi: unicast
+ filters:
+ tags:
+ - pod1-spine4
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-leaf4b (IP: 10.255.255.63)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.71
+ safi: unicast
+ filters:
+ tags:
+ - pod1-spine4
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-leaf5a (IP: 10.255.255.71)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.79
+ safi: unicast
+ filters:
+ tags:
+ - pod1-spine4
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-leaf5b (IP: 10.255.255.79)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.87
+ safi: unicast
+ filters:
+ tags:
+ - pod1-spine4
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-leaf6a (IP: 10.255.255.87)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.95
+ safi: unicast
+ filters:
+ tags:
+ - pod1-spine4
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-leaf6b (IP: 10.255.255.95)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.103
+ safi: unicast
+ filters:
+ tags:
+ - pod1-spine4
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-leaf7a (IP: 10.255.255.103)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.111
+ safi: unicast
+ filters:
+ tags:
+ - pod1-spine4
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-leaf7b (IP: 10.255.255.111)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.119
+ safi: unicast
+ filters:
+ tags:
+ - pod1-spine4
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-leaf8a (IP: 10.255.255.119)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.127
+ safi: unicast
+ filters:
+ tags:
+ - pod1-spine4
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-leaf8b (IP: 10.255.255.127)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.135
+ safi: unicast
+ filters:
+ tags:
+ - pod1-spine4
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-leaf9a (IP: 10.255.255.135)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.143
+ safi: unicast
+ filters:
+ tags:
+ - pod1-spine4
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-leaf9b (IP: 10.255.255.143)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.151
+ safi: unicast
+ filters:
+ tags:
+ - pod1-spine4
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-leaf10a (IP: 10.255.255.151)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.159
+ safi: unicast
+ filters:
+ tags:
+ - pod1-spine4
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-leaf10b (IP: 10.255.255.159)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.12
+ safi: unicast
+ filters:
+ tags:
+ - pod1-spine4
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: super-spine1 (IP: 10.255.255.12)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.14
+ safi: unicast
+ filters:
+ tags:
+ - pod1-spine4
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: super-spine2 (IP: 10.255.255.14)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.2.1
+ filters:
+ tags:
+ - pod2-leaf5b
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod2-spine1 (IP: 10.255.2.1)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.2.2
+ filters:
+ tags:
+ - pod2-leaf5b
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod2-spine2 (IP: 10.255.2.2)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.2.3
+ filters:
+ tags:
+ - pod2-leaf5b
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod2-spine3 (IP: 10.255.2.3)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.2.4
+ filters:
+ tags:
+ - pod2-leaf5b
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod2-spine4 (IP: 10.255.2.4)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.253.16
+ safi: unicast
+ filters:
+ tags:
+ - pod2-leaf5b
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-leaf5a (IP: 10.255.253.16)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.72
+ safi: unicast
+ filters:
+ tags:
+ - pod2-leaf5b
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-spine1 (IP: 10.255.255.72)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.74
+ safi: unicast
+ filters:
+ tags:
+ - pod2-leaf5b
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-spine2 (IP: 10.255.255.74)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.76
+ safi: unicast
+ filters:
+ tags:
+ - pod2-leaf5b
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-spine3 (IP: 10.255.255.76)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.78
+ safi: unicast
+ filters:
+ tags:
+ - pod2-leaf5b
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-spine4 (IP: 10.255.255.78)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.2.1
+ filters:
+ tags:
+ - pod2-leaf2b
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod2-spine1 (IP: 10.255.2.1)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.2.2
+ filters:
+ tags:
+ - pod2-leaf2b
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod2-spine2 (IP: 10.255.2.2)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.2.3
+ filters:
+ tags:
+ - pod2-leaf2b
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod2-spine3 (IP: 10.255.2.3)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.2.4
+ filters:
+ tags:
+ - pod2-leaf2b
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod2-spine4 (IP: 10.255.2.4)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.253.4
+ safi: unicast
+ filters:
+ tags:
+ - pod2-leaf2b
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-leaf2a (IP: 10.255.253.4)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.24
+ safi: unicast
+ filters:
+ tags:
+ - pod2-leaf2b
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-spine1 (IP: 10.255.255.24)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.26
+ safi: unicast
+ filters:
+ tags:
+ - pod2-leaf2b
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-spine2 (IP: 10.255.255.26)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.28
+ safi: unicast
+ filters:
+ tags:
+ - pod2-leaf2b
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-spine3 (IP: 10.255.255.28)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.30
+ safi: unicast
+ filters:
+ tags:
+ - pod2-leaf2b
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-spine4 (IP: 10.255.255.30)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.2.1
+ filters:
+ tags:
+ - pod2-leaf8a
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod2-spine1 (IP: 10.255.2.1)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.2.2
+ filters:
+ tags:
+ - pod2-leaf8a
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod2-spine2 (IP: 10.255.2.2)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.2.3
+ filters:
+ tags:
+ - pod2-leaf8a
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod2-spine3 (IP: 10.255.2.3)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.2.4
+ filters:
+ tags:
+ - pod2-leaf8a
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod2-spine4 (IP: 10.255.2.4)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.253.29
+ safi: unicast
+ filters:
+ tags:
+ - pod2-leaf8a
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-leaf8b (IP: 10.255.253.29)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.112
+ safi: unicast
+ filters:
+ tags:
+ - pod2-leaf8a
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-spine1 (IP: 10.255.255.112)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.114
+ safi: unicast
+ filters:
+ tags:
+ - pod2-leaf8a
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-spine2 (IP: 10.255.255.114)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.116
+ safi: unicast
+ filters:
+ tags:
+ - pod2-leaf8a
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-spine3 (IP: 10.255.255.116)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.118
+ safi: unicast
+ filters:
+ tags:
+ - pod2-leaf8a
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-spine4 (IP: 10.255.255.118)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.1.1
+ filters:
+ tags:
+ - pod1-leaf2b
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod1-spine1 (IP: 10.255.1.1)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.1.2
+ filters:
+ tags:
+ - pod1-leaf2b
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod1-spine2 (IP: 10.255.1.2)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.1.3
+ filters:
+ tags:
+ - pod1-leaf2b
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod1-spine3 (IP: 10.255.1.3)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.1.4
+ filters:
+ tags:
+ - pod1-leaf2b
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod1-spine4 (IP: 10.255.1.4)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.253.4
+ safi: unicast
+ filters:
+ tags:
+ - pod1-leaf2b
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-leaf2a (IP: 10.255.253.4)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.24
+ safi: unicast
+ filters:
+ tags:
+ - pod1-leaf2b
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-spine1 (IP: 10.255.255.24)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.26
+ safi: unicast
+ filters:
+ tags:
+ - pod1-leaf2b
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-spine2 (IP: 10.255.255.26)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.28
+ safi: unicast
+ filters:
+ tags:
+ - pod1-leaf2b
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-spine3 (IP: 10.255.255.28)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.30
+ safi: unicast
+ filters:
+ tags:
+ - pod1-leaf2b
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-spine4 (IP: 10.255.255.30)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.1.1
+ filters:
+ tags:
+ - pod1-leaf5b
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod1-spine1 (IP: 10.255.1.1)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.1.2
+ filters:
+ tags:
+ - pod1-leaf5b
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod1-spine2 (IP: 10.255.1.2)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.1.3
+ filters:
+ tags:
+ - pod1-leaf5b
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod1-spine3 (IP: 10.255.1.3)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.1.4
+ filters:
+ tags:
+ - pod1-leaf5b
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod1-spine4 (IP: 10.255.1.4)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.253.16
+ safi: unicast
+ filters:
+ tags:
+ - pod1-leaf5b
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-leaf5a (IP: 10.255.253.16)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.72
+ safi: unicast
+ filters:
+ tags:
+ - pod1-leaf5b
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-spine1 (IP: 10.255.255.72)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.74
+ safi: unicast
+ filters:
+ tags:
+ - pod1-leaf5b
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-spine2 (IP: 10.255.255.74)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.76
+ safi: unicast
+ filters:
+ tags:
+ - pod1-leaf5b
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-spine3 (IP: 10.255.255.76)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.78
+ safi: unicast
+ filters:
+ tags:
+ - pod1-leaf5b
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-spine4 (IP: 10.255.255.78)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.1.1
+ filters:
+ tags:
+ - pod1-leaf8a
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod1-spine1 (IP: 10.255.1.1)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.1.2
+ filters:
+ tags:
+ - pod1-leaf8a
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod1-spine2 (IP: 10.255.1.2)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.1.3
+ filters:
+ tags:
+ - pod1-leaf8a
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod1-spine3 (IP: 10.255.1.3)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.1.4
+ filters:
+ tags:
+ - pod1-leaf8a
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod1-spine4 (IP: 10.255.1.4)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.253.29
+ safi: unicast
+ filters:
+ tags:
+ - pod1-leaf8a
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-leaf8b (IP: 10.255.253.29)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.112
+ safi: unicast
+ filters:
+ tags:
+ - pod1-leaf8a
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-spine1 (IP: 10.255.255.112)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.114
+ safi: unicast
+ filters:
+ tags:
+ - pod1-leaf8a
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-spine2 (IP: 10.255.255.114)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.116
+ safi: unicast
+ filters:
+ tags:
+ - pod1-leaf8a
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-spine3 (IP: 10.255.255.116)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.118
+ safi: unicast
+ filters:
+ tags:
+ - pod1-leaf8a
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-spine4 (IP: 10.255.255.118)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.2.5
+ filters:
+ tags:
+ - pod2-spine4
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod2-leaf1a (IP: 10.255.2.5)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.2.6
+ filters:
+ tags:
+ - pod2-spine4
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod2-leaf1b (IP: 10.255.2.6)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.2.7
+ filters:
+ tags:
+ - pod2-spine4
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod2-leaf2a (IP: 10.255.2.7)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.2.8
+ filters:
+ tags:
+ - pod2-spine4
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod2-leaf2b (IP: 10.255.2.8)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.2.9
+ filters:
+ tags:
+ - pod2-spine4
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod2-leaf3a (IP: 10.255.2.9)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.2.10
+ filters:
+ tags:
+ - pod2-spine4
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod2-leaf3b (IP: 10.255.2.10)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.2.11
+ filters:
+ tags:
+ - pod2-spine4
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod2-leaf4a (IP: 10.255.2.11)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.2.12
+ filters:
+ tags:
+ - pod2-spine4
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod2-leaf4b (IP: 10.255.2.12)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.2.13
+ filters:
+ tags:
+ - pod2-spine4
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod2-leaf5a (IP: 10.255.2.13)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.2.14
+ filters:
+ tags:
+ - pod2-spine4
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod2-leaf5b (IP: 10.255.2.14)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.2.15
+ filters:
+ tags:
+ - pod2-spine4
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod2-leaf6a (IP: 10.255.2.15)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.2.16
+ filters:
+ tags:
+ - pod2-spine4
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod2-leaf6b (IP: 10.255.2.16)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.2.17
+ filters:
+ tags:
+ - pod2-spine4
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod2-leaf7a (IP: 10.255.2.17)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.2.18
+ filters:
+ tags:
+ - pod2-spine4
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod2-leaf7b (IP: 10.255.2.18)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.2.19
+ filters:
+ tags:
+ - pod2-spine4
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod2-leaf8a (IP: 10.255.2.19)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.2.20
+ filters:
+ tags:
+ - pod2-spine4
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod2-leaf8b (IP: 10.255.2.20)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.2.21
+ filters:
+ tags:
+ - pod2-spine4
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod2-leaf9a (IP: 10.255.2.21)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.2.22
+ filters:
+ tags:
+ - pod2-spine4
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod2-leaf9b (IP: 10.255.2.22)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.2.23
+ filters:
+ tags:
+ - pod2-spine4
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod2-leaf10a (IP: 10.255.2.23)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.2.24
+ filters:
+ tags:
+ - pod2-spine4
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod2-leaf10b (IP: 10.255.2.24)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.7
+ safi: unicast
+ filters:
+ tags:
+ - pod2-spine4
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-leaf1a (IP: 10.255.255.7)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.15
+ safi: unicast
+ filters:
+ tags:
+ - pod2-spine4
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-leaf1b (IP: 10.255.255.15)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.23
+ safi: unicast
+ filters:
+ tags:
+ - pod2-spine4
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-leaf2a (IP: 10.255.255.23)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.31
+ safi: unicast
+ filters:
+ tags:
+ - pod2-spine4
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-leaf2b (IP: 10.255.255.31)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.39
+ safi: unicast
+ filters:
+ tags:
+ - pod2-spine4
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-leaf3a (IP: 10.255.255.39)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.47
+ safi: unicast
+ filters:
+ tags:
+ - pod2-spine4
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-leaf3b (IP: 10.255.255.47)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.55
+ safi: unicast
+ filters:
+ tags:
+ - pod2-spine4
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-leaf4a (IP: 10.255.255.55)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.63
+ safi: unicast
+ filters:
+ tags:
+ - pod2-spine4
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-leaf4b (IP: 10.255.255.63)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.71
+ safi: unicast
+ filters:
+ tags:
+ - pod2-spine4
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-leaf5a (IP: 10.255.255.71)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.79
+ safi: unicast
+ filters:
+ tags:
+ - pod2-spine4
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-leaf5b (IP: 10.255.255.79)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.87
+ safi: unicast
+ filters:
+ tags:
+ - pod2-spine4
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-leaf6a (IP: 10.255.255.87)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.95
+ safi: unicast
+ filters:
+ tags:
+ - pod2-spine4
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-leaf6b (IP: 10.255.255.95)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.103
+ safi: unicast
+ filters:
+ tags:
+ - pod2-spine4
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-leaf7a (IP: 10.255.255.103)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.111
+ safi: unicast
+ filters:
+ tags:
+ - pod2-spine4
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-leaf7b (IP: 10.255.255.111)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.119
+ safi: unicast
+ filters:
+ tags:
+ - pod2-spine4
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-leaf8a (IP: 10.255.255.119)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.127
+ safi: unicast
+ filters:
+ tags:
+ - pod2-spine4
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-leaf8b (IP: 10.255.255.127)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.135
+ safi: unicast
+ filters:
+ tags:
+ - pod2-spine4
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-leaf9a (IP: 10.255.255.135)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.143
+ safi: unicast
+ filters:
+ tags:
+ - pod2-spine4
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-leaf9b (IP: 10.255.255.143)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.151
+ safi: unicast
+ filters:
+ tags:
+ - pod2-spine4
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-leaf10a (IP: 10.255.255.151)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.159
+ safi: unicast
+ filters:
+ tags:
+ - pod2-spine4
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-leaf10b (IP: 10.255.255.159)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.140
+ safi: unicast
+ filters:
+ tags:
+ - pod2-spine4
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: super-spine1 (IP: 10.255.255.140)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.142
+ safi: unicast
+ filters:
+ tags:
+ - pod2-spine4
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: super-spine2 (IP: 10.255.255.142)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.2.1
+ filters:
+ tags:
+ - pod2-leaf3b
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod2-spine1 (IP: 10.255.2.1)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.2.2
+ filters:
+ tags:
+ - pod2-leaf3b
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod2-spine2 (IP: 10.255.2.2)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.2.3
+ filters:
+ tags:
+ - pod2-leaf3b
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod2-spine3 (IP: 10.255.2.3)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.2.4
+ filters:
+ tags:
+ - pod2-leaf3b
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod2-spine4 (IP: 10.255.2.4)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.253.8
+ safi: unicast
+ filters:
+ tags:
+ - pod2-leaf3b
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-leaf3a (IP: 10.255.253.8)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.40
+ safi: unicast
+ filters:
+ tags:
+ - pod2-leaf3b
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-spine1 (IP: 10.255.255.40)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.42
+ safi: unicast
+ filters:
+ tags:
+ - pod2-leaf3b
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-spine2 (IP: 10.255.255.42)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.44
+ safi: unicast
+ filters:
+ tags:
+ - pod2-leaf3b
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-spine3 (IP: 10.255.255.44)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.46
+ safi: unicast
+ filters:
+ tags:
+ - pod2-leaf3b
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-spine4 (IP: 10.255.255.46)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.2.1
+ filters:
+ tags:
+ - pod2-leaf4b
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod2-spine1 (IP: 10.255.2.1)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.2.2
+ filters:
+ tags:
+ - pod2-leaf4b
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod2-spine2 (IP: 10.255.2.2)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.2.3
+ filters:
+ tags:
+ - pod2-leaf4b
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod2-spine3 (IP: 10.255.2.3)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.2.4
+ filters:
+ tags:
+ - pod2-leaf4b
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod2-spine4 (IP: 10.255.2.4)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.253.12
+ safi: unicast
+ filters:
+ tags:
+ - pod2-leaf4b
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-leaf4a (IP: 10.255.253.12)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.56
+ safi: unicast
+ filters:
+ tags:
+ - pod2-leaf4b
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-spine1 (IP: 10.255.255.56)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.58
+ safi: unicast
+ filters:
+ tags:
+ - pod2-leaf4b
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-spine2 (IP: 10.255.255.58)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.60
+ safi: unicast
+ filters:
+ tags:
+ - pod2-leaf4b
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-spine3 (IP: 10.255.255.60)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.62
+ safi: unicast
+ filters:
+ tags:
+ - pod2-leaf4b
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-spine4 (IP: 10.255.255.62)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.1.5
+ filters:
+ tags:
+ - pod1-spine1
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod1-leaf1a (IP: 10.255.1.5)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.1.6
+ filters:
+ tags:
+ - pod1-spine1
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod1-leaf1b (IP: 10.255.1.6)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.1.7
+ filters:
+ tags:
+ - pod1-spine1
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod1-leaf2a (IP: 10.255.1.7)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.1.8
+ filters:
+ tags:
+ - pod1-spine1
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod1-leaf2b (IP: 10.255.1.8)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.1.9
+ filters:
+ tags:
+ - pod1-spine1
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod1-leaf3a (IP: 10.255.1.9)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.1.10
+ filters:
+ tags:
+ - pod1-spine1
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod1-leaf3b (IP: 10.255.1.10)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.1.11
+ filters:
+ tags:
+ - pod1-spine1
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod1-leaf4a (IP: 10.255.1.11)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.1.12
+ filters:
+ tags:
+ - pod1-spine1
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod1-leaf4b (IP: 10.255.1.12)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.1.13
+ filters:
+ tags:
+ - pod1-spine1
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod1-leaf5a (IP: 10.255.1.13)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.1.14
+ filters:
+ tags:
+ - pod1-spine1
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod1-leaf5b (IP: 10.255.1.14)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.1.15
+ filters:
+ tags:
+ - pod1-spine1
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod1-leaf6a (IP: 10.255.1.15)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.1.16
+ filters:
+ tags:
+ - pod1-spine1
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod1-leaf6b (IP: 10.255.1.16)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.1.17
+ filters:
+ tags:
+ - pod1-spine1
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod1-leaf7a (IP: 10.255.1.17)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.1.18
+ filters:
+ tags:
+ - pod1-spine1
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod1-leaf7b (IP: 10.255.1.18)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.1.19
+ filters:
+ tags:
+ - pod1-spine1
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod1-leaf8a (IP: 10.255.1.19)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.1.20
+ filters:
+ tags:
+ - pod1-spine1
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod1-leaf8b (IP: 10.255.1.20)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.1.21
+ filters:
+ tags:
+ - pod1-spine1
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod1-leaf9a (IP: 10.255.1.21)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.1.22
+ filters:
+ tags:
+ - pod1-spine1
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod1-leaf9b (IP: 10.255.1.22)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.1.23
+ filters:
+ tags:
+ - pod1-spine1
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod1-leaf10a (IP: 10.255.1.23)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.1.24
+ filters:
+ tags:
+ - pod1-spine1
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod1-leaf10b (IP: 10.255.1.24)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.1
+ safi: unicast
+ filters:
+ tags:
+ - pod1-spine1
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-leaf1a (IP: 10.255.255.1)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.9
+ safi: unicast
+ filters:
+ tags:
+ - pod1-spine1
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-leaf1b (IP: 10.255.255.9)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.17
+ safi: unicast
+ filters:
+ tags:
+ - pod1-spine1
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-leaf2a (IP: 10.255.255.17)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.25
+ safi: unicast
+ filters:
+ tags:
+ - pod1-spine1
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-leaf2b (IP: 10.255.255.25)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.33
+ safi: unicast
+ filters:
+ tags:
+ - pod1-spine1
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-leaf3a (IP: 10.255.255.33)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.41
+ safi: unicast
+ filters:
+ tags:
+ - pod1-spine1
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-leaf3b (IP: 10.255.255.41)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.49
+ safi: unicast
+ filters:
+ tags:
+ - pod1-spine1
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-leaf4a (IP: 10.255.255.49)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.57
+ safi: unicast
+ filters:
+ tags:
+ - pod1-spine1
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-leaf4b (IP: 10.255.255.57)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.65
+ safi: unicast
+ filters:
+ tags:
+ - pod1-spine1
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-leaf5a (IP: 10.255.255.65)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.73
+ safi: unicast
+ filters:
+ tags:
+ - pod1-spine1
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-leaf5b (IP: 10.255.255.73)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.81
+ safi: unicast
+ filters:
+ tags:
+ - pod1-spine1
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-leaf6a (IP: 10.255.255.81)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.89
+ safi: unicast
+ filters:
+ tags:
+ - pod1-spine1
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-leaf6b (IP: 10.255.255.89)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.97
+ safi: unicast
+ filters:
+ tags:
+ - pod1-spine1
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-leaf7a (IP: 10.255.255.97)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.105
+ safi: unicast
+ filters:
+ tags:
+ - pod1-spine1
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-leaf7b (IP: 10.255.255.105)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.113
+ safi: unicast
+ filters:
+ tags:
+ - pod1-spine1
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-leaf8a (IP: 10.255.255.113)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.121
+ safi: unicast
+ filters:
+ tags:
+ - pod1-spine1
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-leaf8b (IP: 10.255.255.121)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.129
+ safi: unicast
+ filters:
+ tags:
+ - pod1-spine1
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-leaf9a (IP: 10.255.255.129)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.137
+ safi: unicast
+ filters:
+ tags:
+ - pod1-spine1
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-leaf9b (IP: 10.255.255.137)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.145
+ safi: unicast
+ filters:
+ tags:
+ - pod1-spine1
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-leaf10a (IP: 10.255.255.145)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.153
+ safi: unicast
+ filters:
+ tags:
+ - pod1-spine1
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-leaf10b (IP: 10.255.255.153)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.0
+ safi: unicast
+ filters:
+ tags:
+ - pod1-spine1
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: super-spine1 (IP: 10.255.255.0)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.2
+ safi: unicast
+ filters:
+ tags:
+ - pod1-spine1
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: super-spine2 (IP: 10.255.255.2)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.2.1
+ filters:
+ tags:
+ - pod2-leaf9a
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod2-spine1 (IP: 10.255.2.1)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.2.2
+ filters:
+ tags:
+ - pod2-leaf9a
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod2-spine2 (IP: 10.255.2.2)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.2.3
+ filters:
+ tags:
+ - pod2-leaf9a
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod2-spine3 (IP: 10.255.2.3)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.2.4
+ filters:
+ tags:
+ - pod2-leaf9a
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod2-spine4 (IP: 10.255.2.4)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.253.33
+ safi: unicast
+ filters:
+ tags:
+ - pod2-leaf9a
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-leaf9b (IP: 10.255.253.33)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.128
+ safi: unicast
+ filters:
+ tags:
+ - pod2-leaf9a
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-spine1 (IP: 10.255.255.128)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.130
+ safi: unicast
+ filters:
+ tags:
+ - pod2-leaf9a
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-spine2 (IP: 10.255.255.130)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.132
+ safi: unicast
+ filters:
+ tags:
+ - pod2-leaf9a
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-spine3 (IP: 10.255.255.132)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.134
+ safi: unicast
+ filters:
+ tags:
+ - pod2-leaf9a
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-spine4 (IP: 10.255.255.134)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.2.1
+ filters:
+ tags:
+ - pod2-leaf9b
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod2-spine1 (IP: 10.255.2.1)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.2.2
+ filters:
+ tags:
+ - pod2-leaf9b
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod2-spine2 (IP: 10.255.2.2)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.2.3
+ filters:
+ tags:
+ - pod2-leaf9b
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod2-spine3 (IP: 10.255.2.3)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.2.4
+ filters:
+ tags:
+ - pod2-leaf9b
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod2-spine4 (IP: 10.255.2.4)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.253.32
+ safi: unicast
+ filters:
+ tags:
+ - pod2-leaf9b
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-leaf9a (IP: 10.255.253.32)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.136
+ safi: unicast
+ filters:
+ tags:
+ - pod2-leaf9b
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-spine1 (IP: 10.255.255.136)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.138
+ safi: unicast
+ filters:
+ tags:
+ - pod2-leaf9b
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-spine2 (IP: 10.255.255.138)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.140
+ safi: unicast
+ filters:
+ tags:
+ - pod2-leaf9b
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-spine3 (IP: 10.255.255.140)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.142
+ safi: unicast
+ filters:
+ tags:
+ - pod2-leaf9b
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-spine4 (IP: 10.255.255.142)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.2.1
+ filters:
+ tags:
+ - pod2-leaf3a
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod2-spine1 (IP: 10.255.2.1)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.2.2
+ filters:
+ tags:
+ - pod2-leaf3a
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod2-spine2 (IP: 10.255.2.2)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.2.3
+ filters:
+ tags:
+ - pod2-leaf3a
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod2-spine3 (IP: 10.255.2.3)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.2.4
+ filters:
+ tags:
+ - pod2-leaf3a
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod2-spine4 (IP: 10.255.2.4)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.253.9
+ safi: unicast
+ filters:
+ tags:
+ - pod2-leaf3a
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-leaf3b (IP: 10.255.253.9)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.32
+ safi: unicast
+ filters:
+ tags:
+ - pod2-leaf3a
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-spine1 (IP: 10.255.255.32)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.34
+ safi: unicast
+ filters:
+ tags:
+ - pod2-leaf3a
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-spine2 (IP: 10.255.255.34)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.36
+ safi: unicast
+ filters:
+ tags:
+ - pod2-leaf3a
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-spine3 (IP: 10.255.255.36)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.38
+ safi: unicast
+ filters:
+ tags:
+ - pod2-leaf3a
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-spine4 (IP: 10.255.255.38)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.1.5
+ filters:
+ tags:
+ - pod1-spine2
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod1-leaf1a (IP: 10.255.1.5)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.1.6
+ filters:
+ tags:
+ - pod1-spine2
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod1-leaf1b (IP: 10.255.1.6)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.1.7
+ filters:
+ tags:
+ - pod1-spine2
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod1-leaf2a (IP: 10.255.1.7)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.1.8
+ filters:
+ tags:
+ - pod1-spine2
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod1-leaf2b (IP: 10.255.1.8)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.1.9
+ filters:
+ tags:
+ - pod1-spine2
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod1-leaf3a (IP: 10.255.1.9)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.1.10
+ filters:
+ tags:
+ - pod1-spine2
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod1-leaf3b (IP: 10.255.1.10)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.1.11
+ filters:
+ tags:
+ - pod1-spine2
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod1-leaf4a (IP: 10.255.1.11)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.1.12
+ filters:
+ tags:
+ - pod1-spine2
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod1-leaf4b (IP: 10.255.1.12)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.1.13
+ filters:
+ tags:
+ - pod1-spine2
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod1-leaf5a (IP: 10.255.1.13)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.1.14
+ filters:
+ tags:
+ - pod1-spine2
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod1-leaf5b (IP: 10.255.1.14)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.1.15
+ filters:
+ tags:
+ - pod1-spine2
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod1-leaf6a (IP: 10.255.1.15)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.1.16
+ filters:
+ tags:
+ - pod1-spine2
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod1-leaf6b (IP: 10.255.1.16)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.1.17
+ filters:
+ tags:
+ - pod1-spine2
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod1-leaf7a (IP: 10.255.1.17)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.1.18
+ filters:
+ tags:
+ - pod1-spine2
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod1-leaf7b (IP: 10.255.1.18)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.1.19
+ filters:
+ tags:
+ - pod1-spine2
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod1-leaf8a (IP: 10.255.1.19)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.1.20
+ filters:
+ tags:
+ - pod1-spine2
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod1-leaf8b (IP: 10.255.1.20)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.1.21
+ filters:
+ tags:
+ - pod1-spine2
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod1-leaf9a (IP: 10.255.1.21)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.1.22
+ filters:
+ tags:
+ - pod1-spine2
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod1-leaf9b (IP: 10.255.1.22)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.1.23
+ filters:
+ tags:
+ - pod1-spine2
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod1-leaf10a (IP: 10.255.1.23)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.1.24
+ filters:
+ tags:
+ - pod1-spine2
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod1-leaf10b (IP: 10.255.1.24)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.3
+ safi: unicast
+ filters:
+ tags:
+ - pod1-spine2
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-leaf1a (IP: 10.255.255.3)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.11
+ safi: unicast
+ filters:
+ tags:
+ - pod1-spine2
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-leaf1b (IP: 10.255.255.11)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.19
+ safi: unicast
+ filters:
+ tags:
+ - pod1-spine2
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-leaf2a (IP: 10.255.255.19)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.27
+ safi: unicast
+ filters:
+ tags:
+ - pod1-spine2
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-leaf2b (IP: 10.255.255.27)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.35
+ safi: unicast
+ filters:
+ tags:
+ - pod1-spine2
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-leaf3a (IP: 10.255.255.35)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.43
+ safi: unicast
+ filters:
+ tags:
+ - pod1-spine2
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-leaf3b (IP: 10.255.255.43)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.51
+ safi: unicast
+ filters:
+ tags:
+ - pod1-spine2
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-leaf4a (IP: 10.255.255.51)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.59
+ safi: unicast
+ filters:
+ tags:
+ - pod1-spine2
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-leaf4b (IP: 10.255.255.59)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.67
+ safi: unicast
+ filters:
+ tags:
+ - pod1-spine2
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-leaf5a (IP: 10.255.255.67)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.75
+ safi: unicast
+ filters:
+ tags:
+ - pod1-spine2
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-leaf5b (IP: 10.255.255.75)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.83
+ safi: unicast
+ filters:
+ tags:
+ - pod1-spine2
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-leaf6a (IP: 10.255.255.83)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.91
+ safi: unicast
+ filters:
+ tags:
+ - pod1-spine2
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-leaf6b (IP: 10.255.255.91)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.99
+ safi: unicast
+ filters:
+ tags:
+ - pod1-spine2
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-leaf7a (IP: 10.255.255.99)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.107
+ safi: unicast
+ filters:
+ tags:
+ - pod1-spine2
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-leaf7b (IP: 10.255.255.107)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.115
+ safi: unicast
+ filters:
+ tags:
+ - pod1-spine2
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-leaf8a (IP: 10.255.255.115)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.123
+ safi: unicast
+ filters:
+ tags:
+ - pod1-spine2
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-leaf8b (IP: 10.255.255.123)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.131
+ safi: unicast
+ filters:
+ tags:
+ - pod1-spine2
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-leaf9a (IP: 10.255.255.131)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.139
+ safi: unicast
+ filters:
+ tags:
+ - pod1-spine2
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-leaf9b (IP: 10.255.255.139)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.147
+ safi: unicast
+ filters:
+ tags:
+ - pod1-spine2
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-leaf10a (IP: 10.255.255.147)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.155
+ safi: unicast
+ filters:
+ tags:
+ - pod1-spine2
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-leaf10b (IP: 10.255.255.155)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.4
+ safi: unicast
+ filters:
+ tags:
+ - pod1-spine2
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: super-spine1 (IP: 10.255.255.4)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.6
+ safi: unicast
+ filters:
+ tags:
+ - pod1-spine2
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: super-spine2 (IP: 10.255.255.6)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.2.1
+ filters:
+ tags:
+ - pod2-leaf4a
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod2-spine1 (IP: 10.255.2.1)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.2.2
+ filters:
+ tags:
+ - pod2-leaf4a
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod2-spine2 (IP: 10.255.2.2)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.2.3
+ filters:
+ tags:
+ - pod2-leaf4a
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod2-spine3 (IP: 10.255.2.3)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.2.4
+ filters:
+ tags:
+ - pod2-leaf4a
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod2-spine4 (IP: 10.255.2.4)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.253.13
+ safi: unicast
+ filters:
+ tags:
+ - pod2-leaf4a
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-leaf4b (IP: 10.255.253.13)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.48
+ safi: unicast
+ filters:
+ tags:
+ - pod2-leaf4a
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-spine1 (IP: 10.255.255.48)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.50
+ safi: unicast
+ filters:
+ tags:
+ - pod2-leaf4a
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-spine2 (IP: 10.255.255.50)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.52
+ safi: unicast
+ filters:
+ tags:
+ - pod2-leaf4a
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-spine3 (IP: 10.255.255.52)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.54
+ safi: unicast
+ filters:
+ tags:
+ - pod2-leaf4a
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-spine4 (IP: 10.255.255.54)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.1.1
+ filters:
+ tags:
+ - pod1-leaf8b
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod1-spine1 (IP: 10.255.1.1)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.1.2
+ filters:
+ tags:
+ - pod1-leaf8b
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod1-spine2 (IP: 10.255.1.2)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.1.3
+ filters:
+ tags:
+ - pod1-leaf8b
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod1-spine3 (IP: 10.255.1.3)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.1.4
+ filters:
+ tags:
+ - pod1-leaf8b
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod1-spine4 (IP: 10.255.1.4)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.253.28
+ safi: unicast
+ filters:
+ tags:
+ - pod1-leaf8b
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-leaf8a (IP: 10.255.253.28)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.120
+ safi: unicast
+ filters:
+ tags:
+ - pod1-leaf8b
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-spine1 (IP: 10.255.255.120)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.122
+ safi: unicast
+ filters:
+ tags:
+ - pod1-leaf8b
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-spine2 (IP: 10.255.255.122)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.124
+ safi: unicast
+ filters:
+ tags:
+ - pod1-leaf8b
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-spine3 (IP: 10.255.255.124)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.126
+ safi: unicast
+ filters:
+ tags:
+ - pod1-leaf8b
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-spine4 (IP: 10.255.255.126)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.1.1
+ filters:
+ tags:
+ - pod1-leaf2a
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod1-spine1 (IP: 10.255.1.1)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.1.2
+ filters:
+ tags:
+ - pod1-leaf2a
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod1-spine2 (IP: 10.255.1.2)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.1.3
+ filters:
+ tags:
+ - pod1-leaf2a
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod1-spine3 (IP: 10.255.1.3)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.1.4
+ filters:
+ tags:
+ - pod1-leaf2a
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod1-spine4 (IP: 10.255.1.4)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.253.5
+ safi: unicast
+ filters:
+ tags:
+ - pod1-leaf2a
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-leaf2b (IP: 10.255.253.5)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.16
+ safi: unicast
+ filters:
+ tags:
+ - pod1-leaf2a
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-spine1 (IP: 10.255.255.16)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.18
+ safi: unicast
+ filters:
+ tags:
+ - pod1-leaf2a
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-spine2 (IP: 10.255.255.18)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.20
+ safi: unicast
+ filters:
+ tags:
+ - pod1-leaf2a
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-spine3 (IP: 10.255.255.20)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.22
+ safi: unicast
+ filters:
+ tags:
+ - pod1-leaf2a
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-spine4 (IP: 10.255.255.22)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.1.1
+ filters:
+ tags:
+ - pod1-leaf5a
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod1-spine1 (IP: 10.255.1.1)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.1.2
+ filters:
+ tags:
+ - pod1-leaf5a
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod1-spine2 (IP: 10.255.1.2)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.1.3
+ filters:
+ tags:
+ - pod1-leaf5a
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod1-spine3 (IP: 10.255.1.3)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.1.4
+ filters:
+ tags:
+ - pod1-leaf5a
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod1-spine4 (IP: 10.255.1.4)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.253.17
+ safi: unicast
+ filters:
+ tags:
+ - pod1-leaf5a
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-leaf5b (IP: 10.255.253.17)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.64
+ safi: unicast
+ filters:
+ tags:
+ - pod1-leaf5a
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-spine1 (IP: 10.255.255.64)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.66
+ safi: unicast
+ filters:
+ tags:
+ - pod1-leaf5a
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-spine2 (IP: 10.255.255.66)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.68
+ safi: unicast
+ filters:
+ tags:
+ - pod1-leaf5a
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-spine3 (IP: 10.255.255.68)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.70
+ safi: unicast
+ filters:
+ tags:
+ - pod1-leaf5a
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-spine4 (IP: 10.255.255.70)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.2.1
+ filters:
+ tags:
+ - pod2-leaf8b
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod2-spine1 (IP: 10.255.2.1)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.2.2
+ filters:
+ tags:
+ - pod2-leaf8b
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod2-spine2 (IP: 10.255.2.2)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.2.3
+ filters:
+ tags:
+ - pod2-leaf8b
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod2-spine3 (IP: 10.255.2.3)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.2.4
+ filters:
+ tags:
+ - pod2-leaf8b
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod2-spine4 (IP: 10.255.2.4)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.253.28
+ safi: unicast
+ filters:
+ tags:
+ - pod2-leaf8b
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-leaf8a (IP: 10.255.253.28)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.120
+ safi: unicast
+ filters:
+ tags:
+ - pod2-leaf8b
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-spine1 (IP: 10.255.255.120)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.122
+ safi: unicast
+ filters:
+ tags:
+ - pod2-leaf8b
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-spine2 (IP: 10.255.255.122)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.124
+ safi: unicast
+ filters:
+ tags:
+ - pod2-leaf8b
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-spine3 (IP: 10.255.255.124)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.126
+ safi: unicast
+ filters:
+ tags:
+ - pod2-leaf8b
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-spine4 (IP: 10.255.255.126)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.2.1
+ filters:
+ tags:
+ - pod2-leaf5a
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod2-spine1 (IP: 10.255.2.1)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.2.2
+ filters:
+ tags:
+ - pod2-leaf5a
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod2-spine2 (IP: 10.255.2.2)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.2.3
+ filters:
+ tags:
+ - pod2-leaf5a
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod2-spine3 (IP: 10.255.2.3)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.2.4
+ filters:
+ tags:
+ - pod2-leaf5a
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod2-spine4 (IP: 10.255.2.4)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.253.17
+ safi: unicast
+ filters:
+ tags:
+ - pod2-leaf5a
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-leaf5b (IP: 10.255.253.17)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.64
+ safi: unicast
+ filters:
+ tags:
+ - pod2-leaf5a
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-spine1 (IP: 10.255.255.64)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.66
+ safi: unicast
+ filters:
+ tags:
+ - pod2-leaf5a
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-spine2 (IP: 10.255.255.66)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.68
+ safi: unicast
+ filters:
+ tags:
+ - pod2-leaf5a
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-spine3 (IP: 10.255.255.68)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.70
+ safi: unicast
+ filters:
+ tags:
+ - pod2-leaf5a
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-spine4 (IP: 10.255.255.70)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.2.1
+ filters:
+ tags:
+ - pod2-leaf2a
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod2-spine1 (IP: 10.255.2.1)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.2.2
+ filters:
+ tags:
+ - pod2-leaf2a
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod2-spine2 (IP: 10.255.2.2)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.2.3
+ filters:
+ tags:
+ - pod2-leaf2a
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod2-spine3 (IP: 10.255.2.3)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.2.4
+ filters:
+ tags:
+ - pod2-leaf2a
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod2-spine4 (IP: 10.255.2.4)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.253.5
+ safi: unicast
+ filters:
+ tags:
+ - pod2-leaf2a
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-leaf2b (IP: 10.255.253.5)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.16
+ safi: unicast
+ filters:
+ tags:
+ - pod2-leaf2a
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-spine1 (IP: 10.255.255.16)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.18
+ safi: unicast
+ filters:
+ tags:
+ - pod2-leaf2a
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-spine2 (IP: 10.255.255.18)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.20
+ safi: unicast
+ filters:
+ tags:
+ - pod2-leaf2a
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-spine3 (IP: 10.255.255.20)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.22
+ safi: unicast
+ filters:
+ tags:
+ - pod2-leaf2a
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-spine4 (IP: 10.255.255.22)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.1.1
+ filters:
+ tags:
+ - pod1-leaf9b
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod1-spine1 (IP: 10.255.1.1)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.1.2
+ filters:
+ tags:
+ - pod1-leaf9b
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod1-spine2 (IP: 10.255.1.2)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.1.3
+ filters:
+ tags:
+ - pod1-leaf9b
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod1-spine3 (IP: 10.255.1.3)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.1.4
+ filters:
+ tags:
+ - pod1-leaf9b
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod1-spine4 (IP: 10.255.1.4)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.253.32
+ safi: unicast
+ filters:
+ tags:
+ - pod1-leaf9b
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-leaf9a (IP: 10.255.253.32)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.136
+ safi: unicast
+ filters:
+ tags:
+ - pod1-leaf9b
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-spine1 (IP: 10.255.255.136)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.138
+ safi: unicast
+ filters:
+ tags:
+ - pod1-leaf9b
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-spine2 (IP: 10.255.255.138)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.140
+ safi: unicast
+ filters:
+ tags:
+ - pod1-leaf9b
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-spine3 (IP: 10.255.255.140)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.142
+ safi: unicast
+ filters:
+ tags:
+ - pod1-leaf9b
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-spine4 (IP: 10.255.255.142)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.2.5
+ filters:
+ tags:
+ - pod2-spine2
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod2-leaf1a (IP: 10.255.2.5)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.2.6
+ filters:
+ tags:
+ - pod2-spine2
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod2-leaf1b (IP: 10.255.2.6)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.2.7
+ filters:
+ tags:
+ - pod2-spine2
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod2-leaf2a (IP: 10.255.2.7)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.2.8
+ filters:
+ tags:
+ - pod2-spine2
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod2-leaf2b (IP: 10.255.2.8)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.2.9
+ filters:
+ tags:
+ - pod2-spine2
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod2-leaf3a (IP: 10.255.2.9)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.2.10
+ filters:
+ tags:
+ - pod2-spine2
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod2-leaf3b (IP: 10.255.2.10)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.2.11
+ filters:
+ tags:
+ - pod2-spine2
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod2-leaf4a (IP: 10.255.2.11)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.2.12
+ filters:
+ tags:
+ - pod2-spine2
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod2-leaf4b (IP: 10.255.2.12)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.2.13
+ filters:
+ tags:
+ - pod2-spine2
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod2-leaf5a (IP: 10.255.2.13)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.2.14
+ filters:
+ tags:
+ - pod2-spine2
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod2-leaf5b (IP: 10.255.2.14)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.2.15
+ filters:
+ tags:
+ - pod2-spine2
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod2-leaf6a (IP: 10.255.2.15)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.2.16
+ filters:
+ tags:
+ - pod2-spine2
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod2-leaf6b (IP: 10.255.2.16)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.2.17
+ filters:
+ tags:
+ - pod2-spine2
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod2-leaf7a (IP: 10.255.2.17)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.2.18
+ filters:
+ tags:
+ - pod2-spine2
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod2-leaf7b (IP: 10.255.2.18)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.2.19
+ filters:
+ tags:
+ - pod2-spine2
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod2-leaf8a (IP: 10.255.2.19)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.2.20
+ filters:
+ tags:
+ - pod2-spine2
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod2-leaf8b (IP: 10.255.2.20)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.2.21
+ filters:
+ tags:
+ - pod2-spine2
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod2-leaf9a (IP: 10.255.2.21)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.2.22
+ filters:
+ tags:
+ - pod2-spine2
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod2-leaf9b (IP: 10.255.2.22)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.2.23
+ filters:
+ tags:
+ - pod2-spine2
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod2-leaf10a (IP: 10.255.2.23)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.2.24
+ filters:
+ tags:
+ - pod2-spine2
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod2-leaf10b (IP: 10.255.2.24)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.3
+ safi: unicast
+ filters:
+ tags:
+ - pod2-spine2
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-leaf1a (IP: 10.255.255.3)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.11
+ safi: unicast
+ filters:
+ tags:
+ - pod2-spine2
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-leaf1b (IP: 10.255.255.11)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.19
+ safi: unicast
+ filters:
+ tags:
+ - pod2-spine2
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-leaf2a (IP: 10.255.255.19)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.27
+ safi: unicast
+ filters:
+ tags:
+ - pod2-spine2
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-leaf2b (IP: 10.255.255.27)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.35
+ safi: unicast
+ filters:
+ tags:
+ - pod2-spine2
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-leaf3a (IP: 10.255.255.35)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.43
+ safi: unicast
+ filters:
+ tags:
+ - pod2-spine2
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-leaf3b (IP: 10.255.255.43)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.51
+ safi: unicast
+ filters:
+ tags:
+ - pod2-spine2
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-leaf4a (IP: 10.255.255.51)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.59
+ safi: unicast
+ filters:
+ tags:
+ - pod2-spine2
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-leaf4b (IP: 10.255.255.59)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.67
+ safi: unicast
+ filters:
+ tags:
+ - pod2-spine2
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-leaf5a (IP: 10.255.255.67)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.75
+ safi: unicast
+ filters:
+ tags:
+ - pod2-spine2
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-leaf5b (IP: 10.255.255.75)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.83
+ safi: unicast
+ filters:
+ tags:
+ - pod2-spine2
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-leaf6a (IP: 10.255.255.83)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.91
+ safi: unicast
+ filters:
+ tags:
+ - pod2-spine2
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-leaf6b (IP: 10.255.255.91)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.99
+ safi: unicast
+ filters:
+ tags:
+ - pod2-spine2
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-leaf7a (IP: 10.255.255.99)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.107
+ safi: unicast
+ filters:
+ tags:
+ - pod2-spine2
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-leaf7b (IP: 10.255.255.107)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.115
+ safi: unicast
+ filters:
+ tags:
+ - pod2-spine2
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-leaf8a (IP: 10.255.255.115)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.123
+ safi: unicast
+ filters:
+ tags:
+ - pod2-spine2
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-leaf8b (IP: 10.255.255.123)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.131
+ safi: unicast
+ filters:
+ tags:
+ - pod2-spine2
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-leaf9a (IP: 10.255.255.131)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.139
+ safi: unicast
+ filters:
+ tags:
+ - pod2-spine2
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-leaf9b (IP: 10.255.255.139)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.147
+ safi: unicast
+ filters:
+ tags:
+ - pod2-spine2
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-leaf10a (IP: 10.255.255.147)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.155
+ safi: unicast
+ filters:
+ tags:
+ - pod2-spine2
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-leaf10b (IP: 10.255.255.155)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.132
+ safi: unicast
+ filters:
+ tags:
+ - pod2-spine2
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: super-spine1 (IP: 10.255.255.132)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.134
+ safi: unicast
+ filters:
+ tags:
+ - pod2-spine2
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: super-spine2 (IP: 10.255.255.134)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.1.1
+ filters:
+ tags:
+ - pod1-leaf4a
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod1-spine1 (IP: 10.255.1.1)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.1.2
+ filters:
+ tags:
+ - pod1-leaf4a
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod1-spine2 (IP: 10.255.1.2)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.1.3
+ filters:
+ tags:
+ - pod1-leaf4a
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod1-spine3 (IP: 10.255.1.3)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.1.4
+ filters:
+ tags:
+ - pod1-leaf4a
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod1-spine4 (IP: 10.255.1.4)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.253.13
+ safi: unicast
+ filters:
+ tags:
+ - pod1-leaf4a
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-leaf4b (IP: 10.255.253.13)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.48
+ safi: unicast
+ filters:
+ tags:
+ - pod1-leaf4a
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-spine1 (IP: 10.255.255.48)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.50
+ safi: unicast
+ filters:
+ tags:
+ - pod1-leaf4a
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-spine2 (IP: 10.255.255.50)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.52
+ safi: unicast
+ filters:
+ tags:
+ - pod1-leaf4a
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-spine3 (IP: 10.255.255.52)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.54
+ safi: unicast
+ filters:
+ tags:
+ - pod1-leaf4a
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-spine4 (IP: 10.255.255.54)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.1.1
+ filters:
+ tags:
+ - pod1-leaf3a
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod1-spine1 (IP: 10.255.1.1)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.1.2
+ filters:
+ tags:
+ - pod1-leaf3a
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod1-spine2 (IP: 10.255.1.2)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.1.3
+ filters:
+ tags:
+ - pod1-leaf3a
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod1-spine3 (IP: 10.255.1.3)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.1.4
+ filters:
+ tags:
+ - pod1-leaf3a
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod1-spine4 (IP: 10.255.1.4)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.253.9
+ safi: unicast
+ filters:
+ tags:
+ - pod1-leaf3a
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-leaf3b (IP: 10.255.253.9)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.32
+ safi: unicast
+ filters:
+ tags:
+ - pod1-leaf3a
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-spine1 (IP: 10.255.255.32)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.34
+ safi: unicast
+ filters:
+ tags:
+ - pod1-leaf3a
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-spine2 (IP: 10.255.255.34)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.36
+ safi: unicast
+ filters:
+ tags:
+ - pod1-leaf3a
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-spine3 (IP: 10.255.255.36)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.38
+ safi: unicast
+ filters:
+ tags:
+ - pod1-leaf3a
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-spine4 (IP: 10.255.255.38)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.2.1
+ filters:
+ tags:
+ - pod2-leaf7a
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod2-spine1 (IP: 10.255.2.1)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.2.2
+ filters:
+ tags:
+ - pod2-leaf7a
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod2-spine2 (IP: 10.255.2.2)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.2.3
+ filters:
+ tags:
+ - pod2-leaf7a
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod2-spine3 (IP: 10.255.2.3)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.2.4
+ filters:
+ tags:
+ - pod2-leaf7a
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod2-spine4 (IP: 10.255.2.4)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.253.25
+ safi: unicast
+ filters:
+ tags:
+ - pod2-leaf7a
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-leaf7b (IP: 10.255.253.25)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.96
+ safi: unicast
+ filters:
+ tags:
+ - pod2-leaf7a
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-spine1 (IP: 10.255.255.96)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.98
+ safi: unicast
+ filters:
+ tags:
+ - pod2-leaf7a
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-spine2 (IP: 10.255.255.98)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.100
+ safi: unicast
+ filters:
+ tags:
+ - pod2-leaf7a
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-spine3 (IP: 10.255.255.100)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.102
+ safi: unicast
+ filters:
+ tags:
+ - pod2-leaf7a
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-spine4 (IP: 10.255.255.102)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.1.1
+ filters:
+ tags:
+ - pod1-leaf1a
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod1-spine1 (IP: 10.255.1.1)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.1.2
+ filters:
+ tags:
+ - pod1-leaf1a
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod1-spine2 (IP: 10.255.1.2)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.1.3
+ filters:
+ tags:
+ - pod1-leaf1a
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod1-spine3 (IP: 10.255.1.3)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.1.4
+ filters:
+ tags:
+ - pod1-leaf1a
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod1-spine4 (IP: 10.255.1.4)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.253.1
+ safi: unicast
+ filters:
+ tags:
+ - pod1-leaf1a
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-leaf1b (IP: 10.255.253.1)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.0
+ safi: unicast
+ filters:
+ tags:
+ - pod1-leaf1a
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-spine1 (IP: 10.255.255.0)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.2
+ safi: unicast
+ filters:
+ tags:
+ - pod1-leaf1a
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-spine2 (IP: 10.255.255.2)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.4
+ safi: unicast
+ filters:
+ tags:
+ - pod1-leaf1a
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-spine3 (IP: 10.255.255.4)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.6
+ safi: unicast
+ filters:
+ tags:
+ - pod1-leaf1a
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-spine4 (IP: 10.255.255.6)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.1
+ safi: unicast
+ filters:
+ tags:
+ - super-spine1
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-spine1 (IP: 10.255.255.1)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.5
+ safi: unicast
+ filters:
+ tags:
+ - super-spine1
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-spine2 (IP: 10.255.255.5)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.9
+ safi: unicast
+ filters:
+ tags:
+ - super-spine1
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-spine3 (IP: 10.255.255.9)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.13
+ safi: unicast
+ filters:
+ tags:
+ - super-spine1
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-spine4 (IP: 10.255.255.13)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.129
+ safi: unicast
+ filters:
+ tags:
+ - super-spine1
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-spine1 (IP: 10.255.255.129)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.133
+ safi: unicast
+ filters:
+ tags:
+ - super-spine1
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-spine2 (IP: 10.255.255.133)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.137
+ safi: unicast
+ filters:
+ tags:
+ - super-spine1
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-spine3 (IP: 10.255.255.137)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.141
+ safi: unicast
+ filters:
+ tags:
+ - super-spine1
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-spine4 (IP: 10.255.255.141)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.1.1
+ filters:
+ tags:
+ - pod1-leaf6a
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod1-spine1 (IP: 10.255.1.1)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.1.2
+ filters:
+ tags:
+ - pod1-leaf6a
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod1-spine2 (IP: 10.255.1.2)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.1.3
+ filters:
+ tags:
+ - pod1-leaf6a
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod1-spine3 (IP: 10.255.1.3)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.1.4
+ filters:
+ tags:
+ - pod1-leaf6a
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod1-spine4 (IP: 10.255.1.4)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.253.21
+ safi: unicast
+ filters:
+ tags:
+ - pod1-leaf6a
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-leaf6b (IP: 10.255.253.21)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.80
+ safi: unicast
+ filters:
+ tags:
+ - pod1-leaf6a
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-spine1 (IP: 10.255.255.80)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.82
+ safi: unicast
+ filters:
+ tags:
+ - pod1-leaf6a
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-spine2 (IP: 10.255.255.82)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.84
+ safi: unicast
+ filters:
+ tags:
+ - pod1-leaf6a
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-spine3 (IP: 10.255.255.84)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.86
+ safi: unicast
+ filters:
+ tags:
+ - pod1-leaf6a
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-spine4 (IP: 10.255.255.86)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.2.1
+ filters:
+ tags:
+ - pod2-leaf6a
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod2-spine1 (IP: 10.255.2.1)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.2.2
+ filters:
+ tags:
+ - pod2-leaf6a
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod2-spine2 (IP: 10.255.2.2)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.2.3
+ filters:
+ tags:
+ - pod2-leaf6a
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod2-spine3 (IP: 10.255.2.3)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.2.4
+ filters:
+ tags:
+ - pod2-leaf6a
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod2-spine4 (IP: 10.255.2.4)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.253.21
+ safi: unicast
+ filters:
+ tags:
+ - pod2-leaf6a
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-leaf6b (IP: 10.255.253.21)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.80
+ safi: unicast
+ filters:
+ tags:
+ - pod2-leaf6a
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-spine1 (IP: 10.255.255.80)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.82
+ safi: unicast
+ filters:
+ tags:
+ - pod2-leaf6a
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-spine2 (IP: 10.255.255.82)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.84
+ safi: unicast
+ filters:
+ tags:
+ - pod2-leaf6a
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-spine3 (IP: 10.255.255.84)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.86
+ safi: unicast
+ filters:
+ tags:
+ - pod2-leaf6a
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-spine4 (IP: 10.255.255.86)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.2.1
+ filters:
+ tags:
+ - pod2-leaf1a
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod2-spine1 (IP: 10.255.2.1)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.2.2
+ filters:
+ tags:
+ - pod2-leaf1a
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod2-spine2 (IP: 10.255.2.2)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.2.3
+ filters:
+ tags:
+ - pod2-leaf1a
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod2-spine3 (IP: 10.255.2.3)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.2.4
+ filters:
+ tags:
+ - pod2-leaf1a
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod2-spine4 (IP: 10.255.2.4)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.253.1
+ safi: unicast
+ filters:
+ tags:
+ - pod2-leaf1a
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-leaf1b (IP: 10.255.253.1)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.0
+ safi: unicast
+ filters:
+ tags:
+ - pod2-leaf1a
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-spine1 (IP: 10.255.255.0)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.2
+ safi: unicast
+ filters:
+ tags:
+ - pod2-leaf1a
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-spine2 (IP: 10.255.255.2)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.4
+ safi: unicast
+ filters:
+ tags:
+ - pod2-leaf1a
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-spine3 (IP: 10.255.255.4)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.6
+ safi: unicast
+ filters:
+ tags:
+ - pod2-leaf1a
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-spine4 (IP: 10.255.255.6)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.1.1
+ filters:
+ tags:
+ - pod1-leaf10b
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod1-spine1 (IP: 10.255.1.1)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.1.2
+ filters:
+ tags:
+ - pod1-leaf10b
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod1-spine2 (IP: 10.255.1.2)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.1.3
+ filters:
+ tags:
+ - pod1-leaf10b
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod1-spine3 (IP: 10.255.1.3)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.1.4
+ filters:
+ tags:
+ - pod1-leaf10b
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod1-spine4 (IP: 10.255.1.4)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.253.36
+ safi: unicast
+ filters:
+ tags:
+ - pod1-leaf10b
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-leaf10a (IP: 10.255.253.36)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.152
+ safi: unicast
+ filters:
+ tags:
+ - pod1-leaf10b
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-spine1 (IP: 10.255.255.152)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.154
+ safi: unicast
+ filters:
+ tags:
+ - pod1-leaf10b
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-spine2 (IP: 10.255.255.154)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.156
+ safi: unicast
+ filters:
+ tags:
+ - pod1-leaf10b
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-spine3 (IP: 10.255.255.156)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.158
+ safi: unicast
+ filters:
+ tags:
+ - pod1-leaf10b
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-spine4 (IP: 10.255.255.158)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.1.1
+ filters:
+ tags:
+ - pod1-leaf7a
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod1-spine1 (IP: 10.255.1.1)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.1.2
+ filters:
+ tags:
+ - pod1-leaf7a
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod1-spine2 (IP: 10.255.1.2)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.1.3
+ filters:
+ tags:
+ - pod1-leaf7a
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod1-spine3 (IP: 10.255.1.3)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.1.4
+ filters:
+ tags:
+ - pod1-leaf7a
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod1-spine4 (IP: 10.255.1.4)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.253.25
+ safi: unicast
+ filters:
+ tags:
+ - pod1-leaf7a
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-leaf7b (IP: 10.255.253.25)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.96
+ safi: unicast
+ filters:
+ tags:
+ - pod1-leaf7a
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-spine1 (IP: 10.255.255.96)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.98
+ safi: unicast
+ filters:
+ tags:
+ - pod1-leaf7a
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-spine2 (IP: 10.255.255.98)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.100
+ safi: unicast
+ filters:
+ tags:
+ - pod1-leaf7a
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-spine3 (IP: 10.255.255.100)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.102
+ safi: unicast
+ filters:
+ tags:
+ - pod1-leaf7a
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-spine4 (IP: 10.255.255.102)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.2.1
+ filters:
+ tags:
+ - pod2-leaf10b
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod2-spine1 (IP: 10.255.2.1)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.2.2
+ filters:
+ tags:
+ - pod2-leaf10b
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod2-spine2 (IP: 10.255.2.2)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.2.3
+ filters:
+ tags:
+ - pod2-leaf10b
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod2-spine3 (IP: 10.255.2.3)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.2.4
+ filters:
+ tags:
+ - pod2-leaf10b
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod2-spine4 (IP: 10.255.2.4)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.253.36
+ safi: unicast
+ filters:
+ tags:
+ - pod2-leaf10b
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-leaf10a (IP: 10.255.253.36)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.152
+ safi: unicast
+ filters:
+ tags:
+ - pod2-leaf10b
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-spine1 (IP: 10.255.255.152)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.154
+ safi: unicast
+ filters:
+ tags:
+ - pod2-leaf10b
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-spine2 (IP: 10.255.255.154)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.156
+ safi: unicast
+ filters:
+ tags:
+ - pod2-leaf10b
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-spine3 (IP: 10.255.255.156)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.158
+ safi: unicast
+ filters:
+ tags:
+ - pod2-leaf10b
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-spine4 (IP: 10.255.255.158)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.2.1
+ filters:
+ tags:
+ - pod2-leaf10a
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod2-spine1 (IP: 10.255.2.1)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.2.2
+ filters:
+ tags:
+ - pod2-leaf10a
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod2-spine2 (IP: 10.255.2.2)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.2.3
+ filters:
+ tags:
+ - pod2-leaf10a
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod2-spine3 (IP: 10.255.2.3)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.2.4
+ filters:
+ tags:
+ - pod2-leaf10a
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod2-spine4 (IP: 10.255.2.4)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.253.37
+ safi: unicast
+ filters:
+ tags:
+ - pod2-leaf10a
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-leaf10b (IP: 10.255.253.37)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.144
+ safi: unicast
+ filters:
+ tags:
+ - pod2-leaf10a
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-spine1 (IP: 10.255.255.144)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.146
+ safi: unicast
+ filters:
+ tags:
+ - pod2-leaf10a
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-spine2 (IP: 10.255.255.146)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.148
+ safi: unicast
+ filters:
+ tags:
+ - pod2-leaf10a
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-spine3 (IP: 10.255.255.148)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.150
+ safi: unicast
+ filters:
+ tags:
+ - pod2-leaf10a
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-spine4 (IP: 10.255.255.150)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.2.5
+ filters:
+ tags:
+ - pod2-spine3
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod2-leaf1a (IP: 10.255.2.5)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.2.6
+ filters:
+ tags:
+ - pod2-spine3
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod2-leaf1b (IP: 10.255.2.6)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.2.7
+ filters:
+ tags:
+ - pod2-spine3
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod2-leaf2a (IP: 10.255.2.7)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.2.8
+ filters:
+ tags:
+ - pod2-spine3
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod2-leaf2b (IP: 10.255.2.8)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.2.9
+ filters:
+ tags:
+ - pod2-spine3
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod2-leaf3a (IP: 10.255.2.9)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.2.10
+ filters:
+ tags:
+ - pod2-spine3
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod2-leaf3b (IP: 10.255.2.10)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.2.11
+ filters:
+ tags:
+ - pod2-spine3
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod2-leaf4a (IP: 10.255.2.11)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.2.12
+ filters:
+ tags:
+ - pod2-spine3
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod2-leaf4b (IP: 10.255.2.12)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.2.13
+ filters:
+ tags:
+ - pod2-spine3
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod2-leaf5a (IP: 10.255.2.13)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.2.14
+ filters:
+ tags:
+ - pod2-spine3
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod2-leaf5b (IP: 10.255.2.14)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.2.15
+ filters:
+ tags:
+ - pod2-spine3
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod2-leaf6a (IP: 10.255.2.15)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.2.16
+ filters:
+ tags:
+ - pod2-spine3
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod2-leaf6b (IP: 10.255.2.16)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.2.17
+ filters:
+ tags:
+ - pod2-spine3
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod2-leaf7a (IP: 10.255.2.17)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.2.18
+ filters:
+ tags:
+ - pod2-spine3
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod2-leaf7b (IP: 10.255.2.18)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.2.19
+ filters:
+ tags:
+ - pod2-spine3
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod2-leaf8a (IP: 10.255.2.19)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.2.20
+ filters:
+ tags:
+ - pod2-spine3
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod2-leaf8b (IP: 10.255.2.20)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.2.21
+ filters:
+ tags:
+ - pod2-spine3
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod2-leaf9a (IP: 10.255.2.21)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.2.22
+ filters:
+ tags:
+ - pod2-spine3
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod2-leaf9b (IP: 10.255.2.22)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.2.23
+ filters:
+ tags:
+ - pod2-spine3
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod2-leaf10a (IP: 10.255.2.23)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.2.24
+ filters:
+ tags:
+ - pod2-spine3
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod2-leaf10b (IP: 10.255.2.24)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.5
+ safi: unicast
+ filters:
+ tags:
+ - pod2-spine3
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-leaf1a (IP: 10.255.255.5)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.13
+ safi: unicast
+ filters:
+ tags:
+ - pod2-spine3
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-leaf1b (IP: 10.255.255.13)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.21
+ safi: unicast
+ filters:
+ tags:
+ - pod2-spine3
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-leaf2a (IP: 10.255.255.21)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.29
+ safi: unicast
+ filters:
+ tags:
+ - pod2-spine3
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-leaf2b (IP: 10.255.255.29)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.37
+ safi: unicast
+ filters:
+ tags:
+ - pod2-spine3
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-leaf3a (IP: 10.255.255.37)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.45
+ safi: unicast
+ filters:
+ tags:
+ - pod2-spine3
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-leaf3b (IP: 10.255.255.45)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.53
+ safi: unicast
+ filters:
+ tags:
+ - pod2-spine3
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-leaf4a (IP: 10.255.255.53)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.61
+ safi: unicast
+ filters:
+ tags:
+ - pod2-spine3
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-leaf4b (IP: 10.255.255.61)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.69
+ safi: unicast
+ filters:
+ tags:
+ - pod2-spine3
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-leaf5a (IP: 10.255.255.69)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.77
+ safi: unicast
+ filters:
+ tags:
+ - pod2-spine3
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-leaf5b (IP: 10.255.255.77)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.85
+ safi: unicast
+ filters:
+ tags:
+ - pod2-spine3
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-leaf6a (IP: 10.255.255.85)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.93
+ safi: unicast
+ filters:
+ tags:
+ - pod2-spine3
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-leaf6b (IP: 10.255.255.93)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.101
+ safi: unicast
+ filters:
+ tags:
+ - pod2-spine3
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-leaf7a (IP: 10.255.255.101)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.109
+ safi: unicast
+ filters:
+ tags:
+ - pod2-spine3
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-leaf7b (IP: 10.255.255.109)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.117
+ safi: unicast
+ filters:
+ tags:
+ - pod2-spine3
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-leaf8a (IP: 10.255.255.117)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.125
+ safi: unicast
+ filters:
+ tags:
+ - pod2-spine3
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-leaf8b (IP: 10.255.255.125)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.133
+ safi: unicast
+ filters:
+ tags:
+ - pod2-spine3
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-leaf9a (IP: 10.255.255.133)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.141
+ safi: unicast
+ filters:
+ tags:
+ - pod2-spine3
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-leaf9b (IP: 10.255.255.141)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.149
+ safi: unicast
+ filters:
+ tags:
+ - pod2-spine3
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-leaf10a (IP: 10.255.255.149)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.157
+ safi: unicast
+ filters:
+ tags:
+ - pod2-spine3
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-leaf10b (IP: 10.255.255.157)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.136
+ safi: unicast
+ filters:
+ tags:
+ - pod2-spine3
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: super-spine1 (IP: 10.255.255.136)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.138
+ safi: unicast
+ filters:
+ tags:
+ - pod2-spine3
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: super-spine2 (IP: 10.255.255.138)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.1.1
+ filters:
+ tags:
+ - pod1-leaf7b
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod1-spine1 (IP: 10.255.1.1)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.1.2
+ filters:
+ tags:
+ - pod1-leaf7b
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod1-spine2 (IP: 10.255.1.2)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.1.3
+ filters:
+ tags:
+ - pod1-leaf7b
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod1-spine3 (IP: 10.255.1.3)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.1.4
+ filters:
+ tags:
+ - pod1-leaf7b
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod1-spine4 (IP: 10.255.1.4)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.253.24
+ safi: unicast
+ filters:
+ tags:
+ - pod1-leaf7b
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-leaf7a (IP: 10.255.253.24)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.104
+ safi: unicast
+ filters:
+ tags:
+ - pod1-leaf7b
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-spine1 (IP: 10.255.255.104)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.106
+ safi: unicast
+ filters:
+ tags:
+ - pod1-leaf7b
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-spine2 (IP: 10.255.255.106)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.108
+ safi: unicast
+ filters:
+ tags:
+ - pod1-leaf7b
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-spine3 (IP: 10.255.255.108)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.110
+ safi: unicast
+ filters:
+ tags:
+ - pod1-leaf7b
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-spine4 (IP: 10.255.255.110)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.1.1
+ filters:
+ tags:
+ - pod1-leaf10a
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod1-spine1 (IP: 10.255.1.1)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.1.2
+ filters:
+ tags:
+ - pod1-leaf10a
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod1-spine2 (IP: 10.255.1.2)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.1.3
+ filters:
+ tags:
+ - pod1-leaf10a
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod1-spine3 (IP: 10.255.1.3)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.1.4
+ filters:
+ tags:
+ - pod1-leaf10a
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod1-spine4 (IP: 10.255.1.4)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.253.37
+ safi: unicast
+ filters:
+ tags:
+ - pod1-leaf10a
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-leaf10b (IP: 10.255.253.37)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.144
+ safi: unicast
+ filters:
+ tags:
+ - pod1-leaf10a
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-spine1 (IP: 10.255.255.144)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.146
+ safi: unicast
+ filters:
+ tags:
+ - pod1-leaf10a
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-spine2 (IP: 10.255.255.146)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.148
+ safi: unicast
+ filters:
+ tags:
+ - pod1-leaf10a
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-spine3 (IP: 10.255.255.148)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.150
+ safi: unicast
+ filters:
+ tags:
+ - pod1-leaf10a
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-spine4 (IP: 10.255.255.150)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.2.1
+ filters:
+ tags:
+ - pod2-leaf6b
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod2-spine1 (IP: 10.255.2.1)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.2.2
+ filters:
+ tags:
+ - pod2-leaf6b
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod2-spine2 (IP: 10.255.2.2)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.2.3
+ filters:
+ tags:
+ - pod2-leaf6b
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod2-spine3 (IP: 10.255.2.3)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.2.4
+ filters:
+ tags:
+ - pod2-leaf6b
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod2-spine4 (IP: 10.255.2.4)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.253.20
+ safi: unicast
+ filters:
+ tags:
+ - pod2-leaf6b
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-leaf6a (IP: 10.255.253.20)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.88
+ safi: unicast
+ filters:
+ tags:
+ - pod2-leaf6b
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-spine1 (IP: 10.255.255.88)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.90
+ safi: unicast
+ filters:
+ tags:
+ - pod2-leaf6b
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-spine2 (IP: 10.255.255.90)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.92
+ safi: unicast
+ filters:
+ tags:
+ - pod2-leaf6b
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-spine3 (IP: 10.255.255.92)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.94
+ safi: unicast
+ filters:
+ tags:
+ - pod2-leaf6b
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-spine4 (IP: 10.255.255.94)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.2.1
+ filters:
+ tags:
+ - pod2-leaf1b
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod2-spine1 (IP: 10.255.2.1)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.2.2
+ filters:
+ tags:
+ - pod2-leaf1b
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod2-spine2 (IP: 10.255.2.2)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.2.3
+ filters:
+ tags:
+ - pod2-leaf1b
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod2-spine3 (IP: 10.255.2.3)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.2.4
+ filters:
+ tags:
+ - pod2-leaf1b
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod2-spine4 (IP: 10.255.2.4)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.253.0
+ safi: unicast
+ filters:
+ tags:
+ - pod2-leaf1b
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-leaf1a (IP: 10.255.253.0)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.8
+ safi: unicast
+ filters:
+ tags:
+ - pod2-leaf1b
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-spine1 (IP: 10.255.255.8)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.10
+ safi: unicast
+ filters:
+ tags:
+ - pod2-leaf1b
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-spine2 (IP: 10.255.255.10)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.12
+ safi: unicast
+ filters:
+ tags:
+ - pod2-leaf1b
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-spine3 (IP: 10.255.255.12)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.14
+ safi: unicast
+ filters:
+ tags:
+ - pod2-leaf1b
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-spine4 (IP: 10.255.255.14)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.3
+ safi: unicast
+ filters:
+ tags:
+ - super-spine2
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-spine1 (IP: 10.255.255.3)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.7
+ safi: unicast
+ filters:
+ tags:
+ - super-spine2
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-spine2 (IP: 10.255.255.7)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.11
+ safi: unicast
+ filters:
+ tags:
+ - super-spine2
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-spine3 (IP: 10.255.255.11)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.15
+ safi: unicast
+ filters:
+ tags:
+ - super-spine2
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-spine4 (IP: 10.255.255.15)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.131
+ safi: unicast
+ filters:
+ tags:
+ - super-spine2
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-spine1 (IP: 10.255.255.131)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.135
+ safi: unicast
+ filters:
+ tags:
+ - super-spine2
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-spine2 (IP: 10.255.255.135)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.139
+ safi: unicast
+ filters:
+ tags:
+ - super-spine2
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-spine3 (IP: 10.255.255.139)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.143
+ safi: unicast
+ filters:
+ tags:
+ - super-spine2
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-spine4 (IP: 10.255.255.143)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.1.1
+ filters:
+ tags:
+ - pod1-leaf1b
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod1-spine1 (IP: 10.255.1.1)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.1.2
+ filters:
+ tags:
+ - pod1-leaf1b
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod1-spine2 (IP: 10.255.1.2)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.1.3
+ filters:
+ tags:
+ - pod1-leaf1b
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod1-spine3 (IP: 10.255.1.3)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.1.4
+ filters:
+ tags:
+ - pod1-leaf1b
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod1-spine4 (IP: 10.255.1.4)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.253.0
+ safi: unicast
+ filters:
+ tags:
+ - pod1-leaf1b
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-leaf1a (IP: 10.255.253.0)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.8
+ safi: unicast
+ filters:
+ tags:
+ - pod1-leaf1b
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-spine1 (IP: 10.255.255.8)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.10
+ safi: unicast
+ filters:
+ tags:
+ - pod1-leaf1b
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-spine2 (IP: 10.255.255.10)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.12
+ safi: unicast
+ filters:
+ tags:
+ - pod1-leaf1b
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-spine3 (IP: 10.255.255.12)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.14
+ safi: unicast
+ filters:
+ tags:
+ - pod1-leaf1b
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-spine4 (IP: 10.255.255.14)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.1.1
+ filters:
+ tags:
+ - pod1-leaf6b
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod1-spine1 (IP: 10.255.1.1)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.1.2
+ filters:
+ tags:
+ - pod1-leaf6b
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod1-spine2 (IP: 10.255.1.2)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.1.3
+ filters:
+ tags:
+ - pod1-leaf6b
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod1-spine3 (IP: 10.255.1.3)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.1.4
+ filters:
+ tags:
+ - pod1-leaf6b
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod1-spine4 (IP: 10.255.1.4)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.253.20
+ safi: unicast
+ filters:
+ tags:
+ - pod1-leaf6b
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-leaf6a (IP: 10.255.253.20)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.88
+ safi: unicast
+ filters:
+ tags:
+ - pod1-leaf6b
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-spine1 (IP: 10.255.255.88)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.90
+ safi: unicast
+ filters:
+ tags:
+ - pod1-leaf6b
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-spine2 (IP: 10.255.255.90)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.92
+ safi: unicast
+ filters:
+ tags:
+ - pod1-leaf6b
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-spine3 (IP: 10.255.255.92)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.94
+ safi: unicast
+ filters:
+ tags:
+ - pod1-leaf6b
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-spine4 (IP: 10.255.255.94)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.2.1
+ filters:
+ tags:
+ - pod2-leaf7b
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod2-spine1 (IP: 10.255.2.1)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.2.2
+ filters:
+ tags:
+ - pod2-leaf7b
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod2-spine2 (IP: 10.255.2.2)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.2.3
+ filters:
+ tags:
+ - pod2-leaf7b
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod2-spine3 (IP: 10.255.2.3)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.2.4
+ filters:
+ tags:
+ - pod2-leaf7b
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod2-spine4 (IP: 10.255.2.4)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.253.24
+ safi: unicast
+ filters:
+ tags:
+ - pod2-leaf7b
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-leaf7a (IP: 10.255.253.24)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.104
+ safi: unicast
+ filters:
+ tags:
+ - pod2-leaf7b
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-spine1 (IP: 10.255.255.104)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.106
+ safi: unicast
+ filters:
+ tags:
+ - pod2-leaf7b
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-spine2 (IP: 10.255.255.106)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.108
+ safi: unicast
+ filters:
+ tags:
+ - pod2-leaf7b
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-spine3 (IP: 10.255.255.108)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.110
+ safi: unicast
+ filters:
+ tags:
+ - pod2-leaf7b
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod2-spine4 (IP: 10.255.255.110)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.1.5
+ filters:
+ tags:
+ - pod1-spine3
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod1-leaf1a (IP: 10.255.1.5)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.1.6
+ filters:
+ tags:
+ - pod1-spine3
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod1-leaf1b (IP: 10.255.1.6)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.1.7
+ filters:
+ tags:
+ - pod1-spine3
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod1-leaf2a (IP: 10.255.1.7)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.1.8
+ filters:
+ tags:
+ - pod1-spine3
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod1-leaf2b (IP: 10.255.1.8)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.1.9
+ filters:
+ tags:
+ - pod1-spine3
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod1-leaf3a (IP: 10.255.1.9)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.1.10
+ filters:
+ tags:
+ - pod1-spine3
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod1-leaf3b (IP: 10.255.1.10)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.1.11
+ filters:
+ tags:
+ - pod1-spine3
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod1-leaf4a (IP: 10.255.1.11)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.1.12
+ filters:
+ tags:
+ - pod1-spine3
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod1-leaf4b (IP: 10.255.1.12)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.1.13
+ filters:
+ tags:
+ - pod1-spine3
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod1-leaf5a (IP: 10.255.1.13)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.1.14
+ filters:
+ tags:
+ - pod1-spine3
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod1-leaf5b (IP: 10.255.1.14)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.1.15
+ filters:
+ tags:
+ - pod1-spine3
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod1-leaf6a (IP: 10.255.1.15)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.1.16
+ filters:
+ tags:
+ - pod1-spine3
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod1-leaf6b (IP: 10.255.1.16)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.1.17
+ filters:
+ tags:
+ - pod1-spine3
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod1-leaf7a (IP: 10.255.1.17)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.1.18
+ filters:
+ tags:
+ - pod1-spine3
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod1-leaf7b (IP: 10.255.1.18)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.1.19
+ filters:
+ tags:
+ - pod1-spine3
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod1-leaf8a (IP: 10.255.1.19)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.1.20
+ filters:
+ tags:
+ - pod1-spine3
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod1-leaf8b (IP: 10.255.1.20)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.1.21
+ filters:
+ tags:
+ - pod1-spine3
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod1-leaf9a (IP: 10.255.1.21)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.1.22
+ filters:
+ tags:
+ - pod1-spine3
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod1-leaf9b (IP: 10.255.1.22)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.1.23
+ filters:
+ tags:
+ - pod1-spine3
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod1-leaf10a (IP: 10.255.1.23)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.1.24
+ filters:
+ tags:
+ - pod1-spine3
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: pod1-leaf10b (IP: 10.255.1.24)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.5
+ safi: unicast
+ filters:
+ tags:
+ - pod1-spine3
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-leaf1a (IP: 10.255.255.5)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.13
+ safi: unicast
+ filters:
+ tags:
+ - pod1-spine3
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-leaf1b (IP: 10.255.255.13)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.21
+ safi: unicast
+ filters:
+ tags:
+ - pod1-spine3
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-leaf2a (IP: 10.255.255.21)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.29
+ safi: unicast
+ filters:
+ tags:
+ - pod1-spine3
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-leaf2b (IP: 10.255.255.29)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.37
+ safi: unicast
+ filters:
+ tags:
+ - pod1-spine3
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-leaf3a (IP: 10.255.255.37)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.45
+ safi: unicast
+ filters:
+ tags:
+ - pod1-spine3
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-leaf3b (IP: 10.255.255.45)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.53
+ safi: unicast
+ filters:
+ tags:
+ - pod1-spine3
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-leaf4a (IP: 10.255.255.53)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.61
+ safi: unicast
+ filters:
+ tags:
+ - pod1-spine3
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-leaf4b (IP: 10.255.255.61)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.69
+ safi: unicast
+ filters:
+ tags:
+ - pod1-spine3
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-leaf5a (IP: 10.255.255.69)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.77
+ safi: unicast
+ filters:
+ tags:
+ - pod1-spine3
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-leaf5b (IP: 10.255.255.77)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.85
+ safi: unicast
+ filters:
+ tags:
+ - pod1-spine3
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-leaf6a (IP: 10.255.255.85)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.93
+ safi: unicast
+ filters:
+ tags:
+ - pod1-spine3
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-leaf6b (IP: 10.255.255.93)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.101
+ safi: unicast
+ filters:
+ tags:
+ - pod1-spine3
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-leaf7a (IP: 10.255.255.101)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.109
+ safi: unicast
+ filters:
+ tags:
+ - pod1-spine3
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-leaf7b (IP: 10.255.255.109)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.117
+ safi: unicast
+ filters:
+ tags:
+ - pod1-spine3
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-leaf8a (IP: 10.255.255.117)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.125
+ safi: unicast
+ filters:
+ tags:
+ - pod1-spine3
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-leaf8b (IP: 10.255.255.125)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.133
+ safi: unicast
+ filters:
+ tags:
+ - pod1-spine3
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-leaf9a (IP: 10.255.255.133)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.141
+ safi: unicast
+ filters:
+ tags:
+ - pod1-spine3
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-leaf9b (IP: 10.255.255.141)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.149
+ safi: unicast
+ filters:
+ tags:
+ - pod1-spine3
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-leaf10a (IP: 10.255.255.149)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.157
+ safi: unicast
+ filters:
+ tags:
+ - pod1-spine3
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: pod1-leaf10b (IP: 10.255.255.157)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.8
+ safi: unicast
+ filters:
+ tags:
+ - pod1-spine3
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: super-spine1 (IP: 10.255.255.8)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.10
+ safi: unicast
+ filters:
+ tags:
+ - pod1-spine3
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: super-spine2 (IP: 10.255.255.10)'
+anta.tests.routing.generic:
+- VerifyRoutingProtocolModel:
+ filters:
+ tags:
+ - pod1-leaf4b
+ model: multi-agent
+ result_overwrite:
+ custom_field: 'Routing protocol model: multi-agent'
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf4b
+ result_overwrite:
+ custom_field: 'Route: 10.255.0.1 - Peer: super-spine1'
+ routes:
+ - 10.255.0.1
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf4b
+ result_overwrite:
+ custom_field: 'Route: 10.255.0.2 - Peer: super-spine2'
+ routes:
+ - 10.255.0.2
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf4b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.1 - Peer: pod1-spine1'
+ routes:
+ - 10.255.1.1
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf4b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.2 - Peer: pod1-spine2'
+ routes:
+ - 10.255.1.2
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf4b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.3 - Peer: pod1-spine3'
+ routes:
+ - 10.255.1.3
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf4b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.4 - Peer: pod1-spine4'
+ routes:
+ - 10.255.1.4
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf4b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.5 - Peer: pod1-leaf1a'
+ routes:
+ - 10.255.1.5
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf4b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.6 - Peer: pod1-leaf1b'
+ routes:
+ - 10.255.1.6
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf4b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.7 - Peer: pod1-leaf2a'
+ routes:
+ - 10.255.1.7
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf4b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.8 - Peer: pod1-leaf2b'
+ routes:
+ - 10.255.1.8
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf4b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.9 - Peer: pod1-leaf3a'
+ routes:
+ - 10.255.1.9
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf4b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.10 - Peer: pod1-leaf3b'
+ routes:
+ - 10.255.1.10
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf4b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.11 - Peer: pod1-leaf4a'
+ routes:
+ - 10.255.1.11
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf4b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.12 - Peer: pod1-leaf4b'
+ routes:
+ - 10.255.1.12
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf4b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.13 - Peer: pod1-leaf5a'
+ routes:
+ - 10.255.1.13
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf4b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.14 - Peer: pod1-leaf5b'
+ routes:
+ - 10.255.1.14
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf4b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.15 - Peer: pod1-leaf6a'
+ routes:
+ - 10.255.1.15
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf4b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.16 - Peer: pod1-leaf6b'
+ routes:
+ - 10.255.1.16
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf4b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.17 - Peer: pod1-leaf7a'
+ routes:
+ - 10.255.1.17
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf4b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.18 - Peer: pod1-leaf7b'
+ routes:
+ - 10.255.1.18
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf4b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.19 - Peer: pod1-leaf8a'
+ routes:
+ - 10.255.1.19
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf4b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.20 - Peer: pod1-leaf8b'
+ routes:
+ - 10.255.1.20
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf4b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.21 - Peer: pod1-leaf9a'
+ routes:
+ - 10.255.1.21
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf4b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.22 - Peer: pod1-leaf9b'
+ routes:
+ - 10.255.1.22
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf4b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.23 - Peer: pod1-leaf10a'
+ routes:
+ - 10.255.1.23
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf4b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.24 - Peer: pod1-leaf10b'
+ routes:
+ - 10.255.1.24
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf4b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.1 - Peer: pod2-spine1'
+ routes:
+ - 10.255.2.1
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf4b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.2 - Peer: pod2-spine2'
+ routes:
+ - 10.255.2.2
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf4b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.3 - Peer: pod2-spine3'
+ routes:
+ - 10.255.2.3
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf4b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.4 - Peer: pod2-spine4'
+ routes:
+ - 10.255.2.4
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf4b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.5 - Peer: pod2-leaf1a'
+ routes:
+ - 10.255.2.5
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf4b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.6 - Peer: pod2-leaf1b'
+ routes:
+ - 10.255.2.6
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf4b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.7 - Peer: pod2-leaf2a'
+ routes:
+ - 10.255.2.7
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf4b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.8 - Peer: pod2-leaf2b'
+ routes:
+ - 10.255.2.8
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf4b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.9 - Peer: pod2-leaf3a'
+ routes:
+ - 10.255.2.9
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf4b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.10 - Peer: pod2-leaf3b'
+ routes:
+ - 10.255.2.10
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf4b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.11 - Peer: pod2-leaf4a'
+ routes:
+ - 10.255.2.11
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf4b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.12 - Peer: pod2-leaf4b'
+ routes:
+ - 10.255.2.12
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf4b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.13 - Peer: pod2-leaf5a'
+ routes:
+ - 10.255.2.13
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf4b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.14 - Peer: pod2-leaf5b'
+ routes:
+ - 10.255.2.14
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf4b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.15 - Peer: pod2-leaf6a'
+ routes:
+ - 10.255.2.15
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf4b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.16 - Peer: pod2-leaf6b'
+ routes:
+ - 10.255.2.16
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf4b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.17 - Peer: pod2-leaf7a'
+ routes:
+ - 10.255.2.17
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf4b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.18 - Peer: pod2-leaf7b'
+ routes:
+ - 10.255.2.18
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf4b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.19 - Peer: pod2-leaf8a'
+ routes:
+ - 10.255.2.19
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf4b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.20 - Peer: pod2-leaf8b'
+ routes:
+ - 10.255.2.20
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf4b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.21 - Peer: pod2-leaf9a'
+ routes:
+ - 10.255.2.21
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf4b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.22 - Peer: pod2-leaf9b'
+ routes:
+ - 10.255.2.22
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf4b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.23 - Peer: pod2-leaf10a'
+ routes:
+ - 10.255.2.23
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf4b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.24 - Peer: pod2-leaf10b'
+ routes:
+ - 10.255.2.24
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf4b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.5 - Peer: pod1-leaf1a'
+ routes:
+ - 10.255.100.5
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf4b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.7 - Peer: pod1-leaf2a'
+ routes:
+ - 10.255.100.7
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf4b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.9 - Peer: pod1-leaf3a'
+ routes:
+ - 10.255.100.9
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf4b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.11 - Peer: pod1-leaf4a'
+ routes:
+ - 10.255.100.11
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf4b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.13 - Peer: pod1-leaf5a'
+ routes:
+ - 10.255.100.13
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf4b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.15 - Peer: pod1-leaf6a'
+ routes:
+ - 10.255.100.15
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf4b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.17 - Peer: pod1-leaf7a'
+ routes:
+ - 10.255.100.17
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf4b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.19 - Peer: pod1-leaf8a'
+ routes:
+ - 10.255.100.19
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf4b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.21 - Peer: pod1-leaf9a'
+ routes:
+ - 10.255.100.21
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf4b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.23 - Peer: pod1-leaf10a'
+ routes:
+ - 10.255.100.23
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf4b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.5 - Peer: pod2-leaf1a'
+ routes:
+ - 10.255.200.5
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf4b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.7 - Peer: pod2-leaf2a'
+ routes:
+ - 10.255.200.7
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf4b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.9 - Peer: pod2-leaf3a'
+ routes:
+ - 10.255.200.9
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf4b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.11 - Peer: pod2-leaf4a'
+ routes:
+ - 10.255.200.11
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf4b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.13 - Peer: pod2-leaf5a'
+ routes:
+ - 10.255.200.13
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf4b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.15 - Peer: pod2-leaf6a'
+ routes:
+ - 10.255.200.15
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf4b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.17 - Peer: pod2-leaf7a'
+ routes:
+ - 10.255.200.17
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf4b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.19 - Peer: pod2-leaf8a'
+ routes:
+ - 10.255.200.19
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf4b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.21 - Peer: pod2-leaf9a'
+ routes:
+ - 10.255.200.21
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf4b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.23 - Peer: pod2-leaf10a'
+ routes:
+ - 10.255.200.23
+- VerifyRoutingProtocolModel:
+ filters:
+ tags:
+ - pod2-spine1
+ model: multi-agent
+ result_overwrite:
+ custom_field: 'Routing protocol model: multi-agent'
+- VerifyRoutingProtocolModel:
+ filters:
+ tags:
+ - pod1-leaf3b
+ model: multi-agent
+ result_overwrite:
+ custom_field: 'Routing protocol model: multi-agent'
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf3b
+ result_overwrite:
+ custom_field: 'Route: 10.255.0.1 - Peer: super-spine1'
+ routes:
+ - 10.255.0.1
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf3b
+ result_overwrite:
+ custom_field: 'Route: 10.255.0.2 - Peer: super-spine2'
+ routes:
+ - 10.255.0.2
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf3b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.1 - Peer: pod1-spine1'
+ routes:
+ - 10.255.1.1
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf3b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.2 - Peer: pod1-spine2'
+ routes:
+ - 10.255.1.2
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf3b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.3 - Peer: pod1-spine3'
+ routes:
+ - 10.255.1.3
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf3b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.4 - Peer: pod1-spine4'
+ routes:
+ - 10.255.1.4
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf3b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.5 - Peer: pod1-leaf1a'
+ routes:
+ - 10.255.1.5
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf3b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.6 - Peer: pod1-leaf1b'
+ routes:
+ - 10.255.1.6
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf3b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.7 - Peer: pod1-leaf2a'
+ routes:
+ - 10.255.1.7
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf3b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.8 - Peer: pod1-leaf2b'
+ routes:
+ - 10.255.1.8
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf3b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.9 - Peer: pod1-leaf3a'
+ routes:
+ - 10.255.1.9
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf3b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.10 - Peer: pod1-leaf3b'
+ routes:
+ - 10.255.1.10
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf3b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.11 - Peer: pod1-leaf4a'
+ routes:
+ - 10.255.1.11
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf3b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.12 - Peer: pod1-leaf4b'
+ routes:
+ - 10.255.1.12
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf3b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.13 - Peer: pod1-leaf5a'
+ routes:
+ - 10.255.1.13
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf3b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.14 - Peer: pod1-leaf5b'
+ routes:
+ - 10.255.1.14
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf3b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.15 - Peer: pod1-leaf6a'
+ routes:
+ - 10.255.1.15
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf3b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.16 - Peer: pod1-leaf6b'
+ routes:
+ - 10.255.1.16
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf3b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.17 - Peer: pod1-leaf7a'
+ routes:
+ - 10.255.1.17
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf3b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.18 - Peer: pod1-leaf7b'
+ routes:
+ - 10.255.1.18
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf3b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.19 - Peer: pod1-leaf8a'
+ routes:
+ - 10.255.1.19
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf3b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.20 - Peer: pod1-leaf8b'
+ routes:
+ - 10.255.1.20
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf3b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.21 - Peer: pod1-leaf9a'
+ routes:
+ - 10.255.1.21
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf3b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.22 - Peer: pod1-leaf9b'
+ routes:
+ - 10.255.1.22
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf3b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.23 - Peer: pod1-leaf10a'
+ routes:
+ - 10.255.1.23
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf3b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.24 - Peer: pod1-leaf10b'
+ routes:
+ - 10.255.1.24
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf3b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.1 - Peer: pod2-spine1'
+ routes:
+ - 10.255.2.1
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf3b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.2 - Peer: pod2-spine2'
+ routes:
+ - 10.255.2.2
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf3b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.3 - Peer: pod2-spine3'
+ routes:
+ - 10.255.2.3
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf3b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.4 - Peer: pod2-spine4'
+ routes:
+ - 10.255.2.4
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf3b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.5 - Peer: pod2-leaf1a'
+ routes:
+ - 10.255.2.5
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf3b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.6 - Peer: pod2-leaf1b'
+ routes:
+ - 10.255.2.6
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf3b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.7 - Peer: pod2-leaf2a'
+ routes:
+ - 10.255.2.7
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf3b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.8 - Peer: pod2-leaf2b'
+ routes:
+ - 10.255.2.8
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf3b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.9 - Peer: pod2-leaf3a'
+ routes:
+ - 10.255.2.9
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf3b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.10 - Peer: pod2-leaf3b'
+ routes:
+ - 10.255.2.10
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf3b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.11 - Peer: pod2-leaf4a'
+ routes:
+ - 10.255.2.11
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf3b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.12 - Peer: pod2-leaf4b'
+ routes:
+ - 10.255.2.12
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf3b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.13 - Peer: pod2-leaf5a'
+ routes:
+ - 10.255.2.13
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf3b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.14 - Peer: pod2-leaf5b'
+ routes:
+ - 10.255.2.14
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf3b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.15 - Peer: pod2-leaf6a'
+ routes:
+ - 10.255.2.15
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf3b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.16 - Peer: pod2-leaf6b'
+ routes:
+ - 10.255.2.16
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf3b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.17 - Peer: pod2-leaf7a'
+ routes:
+ - 10.255.2.17
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf3b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.18 - Peer: pod2-leaf7b'
+ routes:
+ - 10.255.2.18
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf3b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.19 - Peer: pod2-leaf8a'
+ routes:
+ - 10.255.2.19
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf3b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.20 - Peer: pod2-leaf8b'
+ routes:
+ - 10.255.2.20
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf3b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.21 - Peer: pod2-leaf9a'
+ routes:
+ - 10.255.2.21
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf3b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.22 - Peer: pod2-leaf9b'
+ routes:
+ - 10.255.2.22
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf3b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.23 - Peer: pod2-leaf10a'
+ routes:
+ - 10.255.2.23
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf3b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.24 - Peer: pod2-leaf10b'
+ routes:
+ - 10.255.2.24
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf3b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.5 - Peer: pod1-leaf1a'
+ routes:
+ - 10.255.100.5
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf3b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.7 - Peer: pod1-leaf2a'
+ routes:
+ - 10.255.100.7
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf3b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.9 - Peer: pod1-leaf3a'
+ routes:
+ - 10.255.100.9
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf3b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.11 - Peer: pod1-leaf4a'
+ routes:
+ - 10.255.100.11
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf3b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.13 - Peer: pod1-leaf5a'
+ routes:
+ - 10.255.100.13
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf3b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.15 - Peer: pod1-leaf6a'
+ routes:
+ - 10.255.100.15
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf3b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.17 - Peer: pod1-leaf7a'
+ routes:
+ - 10.255.100.17
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf3b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.19 - Peer: pod1-leaf8a'
+ routes:
+ - 10.255.100.19
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf3b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.21 - Peer: pod1-leaf9a'
+ routes:
+ - 10.255.100.21
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf3b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.23 - Peer: pod1-leaf10a'
+ routes:
+ - 10.255.100.23
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf3b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.5 - Peer: pod2-leaf1a'
+ routes:
+ - 10.255.200.5
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf3b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.7 - Peer: pod2-leaf2a'
+ routes:
+ - 10.255.200.7
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf3b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.9 - Peer: pod2-leaf3a'
+ routes:
+ - 10.255.200.9
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf3b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.11 - Peer: pod2-leaf4a'
+ routes:
+ - 10.255.200.11
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf3b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.13 - Peer: pod2-leaf5a'
+ routes:
+ - 10.255.200.13
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf3b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.15 - Peer: pod2-leaf6a'
+ routes:
+ - 10.255.200.15
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf3b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.17 - Peer: pod2-leaf7a'
+ routes:
+ - 10.255.200.17
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf3b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.19 - Peer: pod2-leaf8a'
+ routes:
+ - 10.255.200.19
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf3b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.21 - Peer: pod2-leaf9a'
+ routes:
+ - 10.255.200.21
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf3b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.23 - Peer: pod2-leaf10a'
+ routes:
+ - 10.255.200.23
+- VerifyRoutingProtocolModel:
+ filters:
+ tags:
+ - pod1-leaf9a
+ model: multi-agent
+ result_overwrite:
+ custom_field: 'Routing protocol model: multi-agent'
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf9a
+ result_overwrite:
+ custom_field: 'Route: 10.255.0.1 - Peer: super-spine1'
+ routes:
+ - 10.255.0.1
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf9a
+ result_overwrite:
+ custom_field: 'Route: 10.255.0.2 - Peer: super-spine2'
+ routes:
+ - 10.255.0.2
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf9a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.1 - Peer: pod1-spine1'
+ routes:
+ - 10.255.1.1
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf9a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.2 - Peer: pod1-spine2'
+ routes:
+ - 10.255.1.2
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf9a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.3 - Peer: pod1-spine3'
+ routes:
+ - 10.255.1.3
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf9a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.4 - Peer: pod1-spine4'
+ routes:
+ - 10.255.1.4
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf9a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.5 - Peer: pod1-leaf1a'
+ routes:
+ - 10.255.1.5
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf9a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.6 - Peer: pod1-leaf1b'
+ routes:
+ - 10.255.1.6
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf9a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.7 - Peer: pod1-leaf2a'
+ routes:
+ - 10.255.1.7
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf9a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.8 - Peer: pod1-leaf2b'
+ routes:
+ - 10.255.1.8
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf9a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.9 - Peer: pod1-leaf3a'
+ routes:
+ - 10.255.1.9
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf9a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.10 - Peer: pod1-leaf3b'
+ routes:
+ - 10.255.1.10
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf9a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.11 - Peer: pod1-leaf4a'
+ routes:
+ - 10.255.1.11
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf9a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.12 - Peer: pod1-leaf4b'
+ routes:
+ - 10.255.1.12
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf9a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.13 - Peer: pod1-leaf5a'
+ routes:
+ - 10.255.1.13
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf9a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.14 - Peer: pod1-leaf5b'
+ routes:
+ - 10.255.1.14
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf9a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.15 - Peer: pod1-leaf6a'
+ routes:
+ - 10.255.1.15
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf9a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.16 - Peer: pod1-leaf6b'
+ routes:
+ - 10.255.1.16
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf9a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.17 - Peer: pod1-leaf7a'
+ routes:
+ - 10.255.1.17
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf9a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.18 - Peer: pod1-leaf7b'
+ routes:
+ - 10.255.1.18
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf9a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.19 - Peer: pod1-leaf8a'
+ routes:
+ - 10.255.1.19
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf9a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.20 - Peer: pod1-leaf8b'
+ routes:
+ - 10.255.1.20
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf9a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.21 - Peer: pod1-leaf9a'
+ routes:
+ - 10.255.1.21
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf9a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.22 - Peer: pod1-leaf9b'
+ routes:
+ - 10.255.1.22
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf9a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.23 - Peer: pod1-leaf10a'
+ routes:
+ - 10.255.1.23
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf9a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.24 - Peer: pod1-leaf10b'
+ routes:
+ - 10.255.1.24
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf9a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.1 - Peer: pod2-spine1'
+ routes:
+ - 10.255.2.1
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf9a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.2 - Peer: pod2-spine2'
+ routes:
+ - 10.255.2.2
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf9a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.3 - Peer: pod2-spine3'
+ routes:
+ - 10.255.2.3
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf9a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.4 - Peer: pod2-spine4'
+ routes:
+ - 10.255.2.4
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf9a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.5 - Peer: pod2-leaf1a'
+ routes:
+ - 10.255.2.5
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf9a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.6 - Peer: pod2-leaf1b'
+ routes:
+ - 10.255.2.6
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf9a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.7 - Peer: pod2-leaf2a'
+ routes:
+ - 10.255.2.7
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf9a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.8 - Peer: pod2-leaf2b'
+ routes:
+ - 10.255.2.8
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf9a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.9 - Peer: pod2-leaf3a'
+ routes:
+ - 10.255.2.9
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf9a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.10 - Peer: pod2-leaf3b'
+ routes:
+ - 10.255.2.10
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf9a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.11 - Peer: pod2-leaf4a'
+ routes:
+ - 10.255.2.11
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf9a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.12 - Peer: pod2-leaf4b'
+ routes:
+ - 10.255.2.12
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf9a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.13 - Peer: pod2-leaf5a'
+ routes:
+ - 10.255.2.13
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf9a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.14 - Peer: pod2-leaf5b'
+ routes:
+ - 10.255.2.14
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf9a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.15 - Peer: pod2-leaf6a'
+ routes:
+ - 10.255.2.15
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf9a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.16 - Peer: pod2-leaf6b'
+ routes:
+ - 10.255.2.16
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf9a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.17 - Peer: pod2-leaf7a'
+ routes:
+ - 10.255.2.17
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf9a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.18 - Peer: pod2-leaf7b'
+ routes:
+ - 10.255.2.18
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf9a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.19 - Peer: pod2-leaf8a'
+ routes:
+ - 10.255.2.19
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf9a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.20 - Peer: pod2-leaf8b'
+ routes:
+ - 10.255.2.20
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf9a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.21 - Peer: pod2-leaf9a'
+ routes:
+ - 10.255.2.21
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf9a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.22 - Peer: pod2-leaf9b'
+ routes:
+ - 10.255.2.22
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf9a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.23 - Peer: pod2-leaf10a'
+ routes:
+ - 10.255.2.23
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf9a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.24 - Peer: pod2-leaf10b'
+ routes:
+ - 10.255.2.24
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf9a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.5 - Peer: pod1-leaf1a'
+ routes:
+ - 10.255.100.5
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf9a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.7 - Peer: pod1-leaf2a'
+ routes:
+ - 10.255.100.7
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf9a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.9 - Peer: pod1-leaf3a'
+ routes:
+ - 10.255.100.9
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf9a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.11 - Peer: pod1-leaf4a'
+ routes:
+ - 10.255.100.11
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf9a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.13 - Peer: pod1-leaf5a'
+ routes:
+ - 10.255.100.13
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf9a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.15 - Peer: pod1-leaf6a'
+ routes:
+ - 10.255.100.15
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf9a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.17 - Peer: pod1-leaf7a'
+ routes:
+ - 10.255.100.17
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf9a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.19 - Peer: pod1-leaf8a'
+ routes:
+ - 10.255.100.19
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf9a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.21 - Peer: pod1-leaf9a'
+ routes:
+ - 10.255.100.21
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf9a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.23 - Peer: pod1-leaf10a'
+ routes:
+ - 10.255.100.23
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf9a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.5 - Peer: pod2-leaf1a'
+ routes:
+ - 10.255.200.5
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf9a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.7 - Peer: pod2-leaf2a'
+ routes:
+ - 10.255.200.7
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf9a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.9 - Peer: pod2-leaf3a'
+ routes:
+ - 10.255.200.9
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf9a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.11 - Peer: pod2-leaf4a'
+ routes:
+ - 10.255.200.11
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf9a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.13 - Peer: pod2-leaf5a'
+ routes:
+ - 10.255.200.13
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf9a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.15 - Peer: pod2-leaf6a'
+ routes:
+ - 10.255.200.15
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf9a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.17 - Peer: pod2-leaf7a'
+ routes:
+ - 10.255.200.17
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf9a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.19 - Peer: pod2-leaf8a'
+ routes:
+ - 10.255.200.19
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf9a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.21 - Peer: pod2-leaf9a'
+ routes:
+ - 10.255.200.21
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf9a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.23 - Peer: pod2-leaf10a'
+ routes:
+ - 10.255.200.23
+- VerifyRoutingProtocolModel:
+ filters:
+ tags:
+ - pod1-spine4
+ model: multi-agent
+ result_overwrite:
+ custom_field: 'Routing protocol model: multi-agent'
+- VerifyRoutingProtocolModel:
+ filters:
+ tags:
+ - pod2-leaf5b
+ model: multi-agent
+ result_overwrite:
+ custom_field: 'Routing protocol model: multi-agent'
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf5b
+ result_overwrite:
+ custom_field: 'Route: 10.255.0.1 - Peer: super-spine1'
+ routes:
+ - 10.255.0.1
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf5b
+ result_overwrite:
+ custom_field: 'Route: 10.255.0.2 - Peer: super-spine2'
+ routes:
+ - 10.255.0.2
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf5b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.1 - Peer: pod1-spine1'
+ routes:
+ - 10.255.1.1
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf5b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.2 - Peer: pod1-spine2'
+ routes:
+ - 10.255.1.2
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf5b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.3 - Peer: pod1-spine3'
+ routes:
+ - 10.255.1.3
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf5b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.4 - Peer: pod1-spine4'
+ routes:
+ - 10.255.1.4
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf5b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.5 - Peer: pod1-leaf1a'
+ routes:
+ - 10.255.1.5
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf5b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.6 - Peer: pod1-leaf1b'
+ routes:
+ - 10.255.1.6
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf5b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.7 - Peer: pod1-leaf2a'
+ routes:
+ - 10.255.1.7
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf5b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.8 - Peer: pod1-leaf2b'
+ routes:
+ - 10.255.1.8
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf5b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.9 - Peer: pod1-leaf3a'
+ routes:
+ - 10.255.1.9
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf5b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.10 - Peer: pod1-leaf3b'
+ routes:
+ - 10.255.1.10
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf5b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.11 - Peer: pod1-leaf4a'
+ routes:
+ - 10.255.1.11
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf5b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.12 - Peer: pod1-leaf4b'
+ routes:
+ - 10.255.1.12
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf5b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.13 - Peer: pod1-leaf5a'
+ routes:
+ - 10.255.1.13
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf5b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.14 - Peer: pod1-leaf5b'
+ routes:
+ - 10.255.1.14
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf5b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.15 - Peer: pod1-leaf6a'
+ routes:
+ - 10.255.1.15
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf5b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.16 - Peer: pod1-leaf6b'
+ routes:
+ - 10.255.1.16
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf5b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.17 - Peer: pod1-leaf7a'
+ routes:
+ - 10.255.1.17
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf5b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.18 - Peer: pod1-leaf7b'
+ routes:
+ - 10.255.1.18
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf5b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.19 - Peer: pod1-leaf8a'
+ routes:
+ - 10.255.1.19
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf5b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.20 - Peer: pod1-leaf8b'
+ routes:
+ - 10.255.1.20
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf5b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.21 - Peer: pod1-leaf9a'
+ routes:
+ - 10.255.1.21
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf5b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.22 - Peer: pod1-leaf9b'
+ routes:
+ - 10.255.1.22
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf5b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.23 - Peer: pod1-leaf10a'
+ routes:
+ - 10.255.1.23
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf5b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.24 - Peer: pod1-leaf10b'
+ routes:
+ - 10.255.1.24
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf5b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.1 - Peer: pod2-spine1'
+ routes:
+ - 10.255.2.1
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf5b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.2 - Peer: pod2-spine2'
+ routes:
+ - 10.255.2.2
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf5b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.3 - Peer: pod2-spine3'
+ routes:
+ - 10.255.2.3
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf5b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.4 - Peer: pod2-spine4'
+ routes:
+ - 10.255.2.4
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf5b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.5 - Peer: pod2-leaf1a'
+ routes:
+ - 10.255.2.5
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf5b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.6 - Peer: pod2-leaf1b'
+ routes:
+ - 10.255.2.6
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf5b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.7 - Peer: pod2-leaf2a'
+ routes:
+ - 10.255.2.7
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf5b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.8 - Peer: pod2-leaf2b'
+ routes:
+ - 10.255.2.8
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf5b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.9 - Peer: pod2-leaf3a'
+ routes:
+ - 10.255.2.9
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf5b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.10 - Peer: pod2-leaf3b'
+ routes:
+ - 10.255.2.10
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf5b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.11 - Peer: pod2-leaf4a'
+ routes:
+ - 10.255.2.11
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf5b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.12 - Peer: pod2-leaf4b'
+ routes:
+ - 10.255.2.12
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf5b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.13 - Peer: pod2-leaf5a'
+ routes:
+ - 10.255.2.13
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf5b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.14 - Peer: pod2-leaf5b'
+ routes:
+ - 10.255.2.14
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf5b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.15 - Peer: pod2-leaf6a'
+ routes:
+ - 10.255.2.15
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf5b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.16 - Peer: pod2-leaf6b'
+ routes:
+ - 10.255.2.16
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf5b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.17 - Peer: pod2-leaf7a'
+ routes:
+ - 10.255.2.17
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf5b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.18 - Peer: pod2-leaf7b'
+ routes:
+ - 10.255.2.18
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf5b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.19 - Peer: pod2-leaf8a'
+ routes:
+ - 10.255.2.19
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf5b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.20 - Peer: pod2-leaf8b'
+ routes:
+ - 10.255.2.20
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf5b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.21 - Peer: pod2-leaf9a'
+ routes:
+ - 10.255.2.21
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf5b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.22 - Peer: pod2-leaf9b'
+ routes:
+ - 10.255.2.22
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf5b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.23 - Peer: pod2-leaf10a'
+ routes:
+ - 10.255.2.23
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf5b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.24 - Peer: pod2-leaf10b'
+ routes:
+ - 10.255.2.24
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf5b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.5 - Peer: pod1-leaf1a'
+ routes:
+ - 10.255.100.5
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf5b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.7 - Peer: pod1-leaf2a'
+ routes:
+ - 10.255.100.7
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf5b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.9 - Peer: pod1-leaf3a'
+ routes:
+ - 10.255.100.9
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf5b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.11 - Peer: pod1-leaf4a'
+ routes:
+ - 10.255.100.11
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf5b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.13 - Peer: pod1-leaf5a'
+ routes:
+ - 10.255.100.13
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf5b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.15 - Peer: pod1-leaf6a'
+ routes:
+ - 10.255.100.15
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf5b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.17 - Peer: pod1-leaf7a'
+ routes:
+ - 10.255.100.17
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf5b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.19 - Peer: pod1-leaf8a'
+ routes:
+ - 10.255.100.19
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf5b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.21 - Peer: pod1-leaf9a'
+ routes:
+ - 10.255.100.21
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf5b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.23 - Peer: pod1-leaf10a'
+ routes:
+ - 10.255.100.23
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf5b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.5 - Peer: pod2-leaf1a'
+ routes:
+ - 10.255.200.5
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf5b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.7 - Peer: pod2-leaf2a'
+ routes:
+ - 10.255.200.7
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf5b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.9 - Peer: pod2-leaf3a'
+ routes:
+ - 10.255.200.9
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf5b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.11 - Peer: pod2-leaf4a'
+ routes:
+ - 10.255.200.11
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf5b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.13 - Peer: pod2-leaf5a'
+ routes:
+ - 10.255.200.13
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf5b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.15 - Peer: pod2-leaf6a'
+ routes:
+ - 10.255.200.15
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf5b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.17 - Peer: pod2-leaf7a'
+ routes:
+ - 10.255.200.17
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf5b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.19 - Peer: pod2-leaf8a'
+ routes:
+ - 10.255.200.19
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf5b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.21 - Peer: pod2-leaf9a'
+ routes:
+ - 10.255.200.21
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf5b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.23 - Peer: pod2-leaf10a'
+ routes:
+ - 10.255.200.23
+- VerifyRoutingProtocolModel:
+ filters:
+ tags:
+ - pod2-leaf2b
+ model: multi-agent
+ result_overwrite:
+ custom_field: 'Routing protocol model: multi-agent'
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf2b
+ result_overwrite:
+ custom_field: 'Route: 10.255.0.1 - Peer: super-spine1'
+ routes:
+ - 10.255.0.1
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf2b
+ result_overwrite:
+ custom_field: 'Route: 10.255.0.2 - Peer: super-spine2'
+ routes:
+ - 10.255.0.2
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf2b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.1 - Peer: pod1-spine1'
+ routes:
+ - 10.255.1.1
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf2b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.2 - Peer: pod1-spine2'
+ routes:
+ - 10.255.1.2
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf2b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.3 - Peer: pod1-spine3'
+ routes:
+ - 10.255.1.3
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf2b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.4 - Peer: pod1-spine4'
+ routes:
+ - 10.255.1.4
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf2b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.5 - Peer: pod1-leaf1a'
+ routes:
+ - 10.255.1.5
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf2b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.6 - Peer: pod1-leaf1b'
+ routes:
+ - 10.255.1.6
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf2b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.7 - Peer: pod1-leaf2a'
+ routes:
+ - 10.255.1.7
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf2b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.8 - Peer: pod1-leaf2b'
+ routes:
+ - 10.255.1.8
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf2b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.9 - Peer: pod1-leaf3a'
+ routes:
+ - 10.255.1.9
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf2b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.10 - Peer: pod1-leaf3b'
+ routes:
+ - 10.255.1.10
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf2b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.11 - Peer: pod1-leaf4a'
+ routes:
+ - 10.255.1.11
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf2b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.12 - Peer: pod1-leaf4b'
+ routes:
+ - 10.255.1.12
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf2b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.13 - Peer: pod1-leaf5a'
+ routes:
+ - 10.255.1.13
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf2b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.14 - Peer: pod1-leaf5b'
+ routes:
+ - 10.255.1.14
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf2b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.15 - Peer: pod1-leaf6a'
+ routes:
+ - 10.255.1.15
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf2b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.16 - Peer: pod1-leaf6b'
+ routes:
+ - 10.255.1.16
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf2b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.17 - Peer: pod1-leaf7a'
+ routes:
+ - 10.255.1.17
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf2b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.18 - Peer: pod1-leaf7b'
+ routes:
+ - 10.255.1.18
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf2b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.19 - Peer: pod1-leaf8a'
+ routes:
+ - 10.255.1.19
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf2b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.20 - Peer: pod1-leaf8b'
+ routes:
+ - 10.255.1.20
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf2b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.21 - Peer: pod1-leaf9a'
+ routes:
+ - 10.255.1.21
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf2b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.22 - Peer: pod1-leaf9b'
+ routes:
+ - 10.255.1.22
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf2b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.23 - Peer: pod1-leaf10a'
+ routes:
+ - 10.255.1.23
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf2b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.24 - Peer: pod1-leaf10b'
+ routes:
+ - 10.255.1.24
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf2b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.1 - Peer: pod2-spine1'
+ routes:
+ - 10.255.2.1
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf2b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.2 - Peer: pod2-spine2'
+ routes:
+ - 10.255.2.2
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf2b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.3 - Peer: pod2-spine3'
+ routes:
+ - 10.255.2.3
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf2b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.4 - Peer: pod2-spine4'
+ routes:
+ - 10.255.2.4
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf2b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.5 - Peer: pod2-leaf1a'
+ routes:
+ - 10.255.2.5
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf2b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.6 - Peer: pod2-leaf1b'
+ routes:
+ - 10.255.2.6
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf2b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.7 - Peer: pod2-leaf2a'
+ routes:
+ - 10.255.2.7
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf2b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.8 - Peer: pod2-leaf2b'
+ routes:
+ - 10.255.2.8
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf2b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.9 - Peer: pod2-leaf3a'
+ routes:
+ - 10.255.2.9
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf2b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.10 - Peer: pod2-leaf3b'
+ routes:
+ - 10.255.2.10
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf2b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.11 - Peer: pod2-leaf4a'
+ routes:
+ - 10.255.2.11
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf2b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.12 - Peer: pod2-leaf4b'
+ routes:
+ - 10.255.2.12
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf2b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.13 - Peer: pod2-leaf5a'
+ routes:
+ - 10.255.2.13
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf2b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.14 - Peer: pod2-leaf5b'
+ routes:
+ - 10.255.2.14
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf2b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.15 - Peer: pod2-leaf6a'
+ routes:
+ - 10.255.2.15
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf2b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.16 - Peer: pod2-leaf6b'
+ routes:
+ - 10.255.2.16
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf2b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.17 - Peer: pod2-leaf7a'
+ routes:
+ - 10.255.2.17
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf2b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.18 - Peer: pod2-leaf7b'
+ routes:
+ - 10.255.2.18
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf2b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.19 - Peer: pod2-leaf8a'
+ routes:
+ - 10.255.2.19
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf2b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.20 - Peer: pod2-leaf8b'
+ routes:
+ - 10.255.2.20
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf2b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.21 - Peer: pod2-leaf9a'
+ routes:
+ - 10.255.2.21
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf2b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.22 - Peer: pod2-leaf9b'
+ routes:
+ - 10.255.2.22
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf2b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.23 - Peer: pod2-leaf10a'
+ routes:
+ - 10.255.2.23
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf2b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.24 - Peer: pod2-leaf10b'
+ routes:
+ - 10.255.2.24
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf2b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.5 - Peer: pod1-leaf1a'
+ routes:
+ - 10.255.100.5
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf2b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.7 - Peer: pod1-leaf2a'
+ routes:
+ - 10.255.100.7
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf2b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.9 - Peer: pod1-leaf3a'
+ routes:
+ - 10.255.100.9
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf2b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.11 - Peer: pod1-leaf4a'
+ routes:
+ - 10.255.100.11
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf2b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.13 - Peer: pod1-leaf5a'
+ routes:
+ - 10.255.100.13
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf2b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.15 - Peer: pod1-leaf6a'
+ routes:
+ - 10.255.100.15
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf2b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.17 - Peer: pod1-leaf7a'
+ routes:
+ - 10.255.100.17
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf2b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.19 - Peer: pod1-leaf8a'
+ routes:
+ - 10.255.100.19
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf2b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.21 - Peer: pod1-leaf9a'
+ routes:
+ - 10.255.100.21
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf2b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.23 - Peer: pod1-leaf10a'
+ routes:
+ - 10.255.100.23
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf2b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.5 - Peer: pod2-leaf1a'
+ routes:
+ - 10.255.200.5
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf2b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.7 - Peer: pod2-leaf2a'
+ routes:
+ - 10.255.200.7
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf2b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.9 - Peer: pod2-leaf3a'
+ routes:
+ - 10.255.200.9
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf2b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.11 - Peer: pod2-leaf4a'
+ routes:
+ - 10.255.200.11
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf2b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.13 - Peer: pod2-leaf5a'
+ routes:
+ - 10.255.200.13
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf2b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.15 - Peer: pod2-leaf6a'
+ routes:
+ - 10.255.200.15
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf2b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.17 - Peer: pod2-leaf7a'
+ routes:
+ - 10.255.200.17
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf2b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.19 - Peer: pod2-leaf8a'
+ routes:
+ - 10.255.200.19
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf2b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.21 - Peer: pod2-leaf9a'
+ routes:
+ - 10.255.200.21
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf2b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.23 - Peer: pod2-leaf10a'
+ routes:
+ - 10.255.200.23
+- VerifyRoutingProtocolModel:
+ filters:
+ tags:
+ - pod2-leaf8a
+ model: multi-agent
+ result_overwrite:
+ custom_field: 'Routing protocol model: multi-agent'
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf8a
+ result_overwrite:
+ custom_field: 'Route: 10.255.0.1 - Peer: super-spine1'
+ routes:
+ - 10.255.0.1
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf8a
+ result_overwrite:
+ custom_field: 'Route: 10.255.0.2 - Peer: super-spine2'
+ routes:
+ - 10.255.0.2
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf8a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.1 - Peer: pod1-spine1'
+ routes:
+ - 10.255.1.1
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf8a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.2 - Peer: pod1-spine2'
+ routes:
+ - 10.255.1.2
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf8a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.3 - Peer: pod1-spine3'
+ routes:
+ - 10.255.1.3
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf8a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.4 - Peer: pod1-spine4'
+ routes:
+ - 10.255.1.4
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf8a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.5 - Peer: pod1-leaf1a'
+ routes:
+ - 10.255.1.5
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf8a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.6 - Peer: pod1-leaf1b'
+ routes:
+ - 10.255.1.6
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf8a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.7 - Peer: pod1-leaf2a'
+ routes:
+ - 10.255.1.7
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf8a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.8 - Peer: pod1-leaf2b'
+ routes:
+ - 10.255.1.8
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf8a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.9 - Peer: pod1-leaf3a'
+ routes:
+ - 10.255.1.9
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf8a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.10 - Peer: pod1-leaf3b'
+ routes:
+ - 10.255.1.10
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf8a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.11 - Peer: pod1-leaf4a'
+ routes:
+ - 10.255.1.11
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf8a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.12 - Peer: pod1-leaf4b'
+ routes:
+ - 10.255.1.12
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf8a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.13 - Peer: pod1-leaf5a'
+ routes:
+ - 10.255.1.13
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf8a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.14 - Peer: pod1-leaf5b'
+ routes:
+ - 10.255.1.14
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf8a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.15 - Peer: pod1-leaf6a'
+ routes:
+ - 10.255.1.15
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf8a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.16 - Peer: pod1-leaf6b'
+ routes:
+ - 10.255.1.16
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf8a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.17 - Peer: pod1-leaf7a'
+ routes:
+ - 10.255.1.17
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf8a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.18 - Peer: pod1-leaf7b'
+ routes:
+ - 10.255.1.18
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf8a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.19 - Peer: pod1-leaf8a'
+ routes:
+ - 10.255.1.19
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf8a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.20 - Peer: pod1-leaf8b'
+ routes:
+ - 10.255.1.20
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf8a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.21 - Peer: pod1-leaf9a'
+ routes:
+ - 10.255.1.21
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf8a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.22 - Peer: pod1-leaf9b'
+ routes:
+ - 10.255.1.22
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf8a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.23 - Peer: pod1-leaf10a'
+ routes:
+ - 10.255.1.23
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf8a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.24 - Peer: pod1-leaf10b'
+ routes:
+ - 10.255.1.24
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf8a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.1 - Peer: pod2-spine1'
+ routes:
+ - 10.255.2.1
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf8a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.2 - Peer: pod2-spine2'
+ routes:
+ - 10.255.2.2
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf8a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.3 - Peer: pod2-spine3'
+ routes:
+ - 10.255.2.3
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf8a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.4 - Peer: pod2-spine4'
+ routes:
+ - 10.255.2.4
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf8a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.5 - Peer: pod2-leaf1a'
+ routes:
+ - 10.255.2.5
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf8a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.6 - Peer: pod2-leaf1b'
+ routes:
+ - 10.255.2.6
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf8a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.7 - Peer: pod2-leaf2a'
+ routes:
+ - 10.255.2.7
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf8a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.8 - Peer: pod2-leaf2b'
+ routes:
+ - 10.255.2.8
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf8a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.9 - Peer: pod2-leaf3a'
+ routes:
+ - 10.255.2.9
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf8a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.10 - Peer: pod2-leaf3b'
+ routes:
+ - 10.255.2.10
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf8a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.11 - Peer: pod2-leaf4a'
+ routes:
+ - 10.255.2.11
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf8a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.12 - Peer: pod2-leaf4b'
+ routes:
+ - 10.255.2.12
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf8a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.13 - Peer: pod2-leaf5a'
+ routes:
+ - 10.255.2.13
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf8a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.14 - Peer: pod2-leaf5b'
+ routes:
+ - 10.255.2.14
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf8a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.15 - Peer: pod2-leaf6a'
+ routes:
+ - 10.255.2.15
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf8a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.16 - Peer: pod2-leaf6b'
+ routes:
+ - 10.255.2.16
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf8a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.17 - Peer: pod2-leaf7a'
+ routes:
+ - 10.255.2.17
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf8a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.18 - Peer: pod2-leaf7b'
+ routes:
+ - 10.255.2.18
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf8a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.19 - Peer: pod2-leaf8a'
+ routes:
+ - 10.255.2.19
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf8a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.20 - Peer: pod2-leaf8b'
+ routes:
+ - 10.255.2.20
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf8a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.21 - Peer: pod2-leaf9a'
+ routes:
+ - 10.255.2.21
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf8a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.22 - Peer: pod2-leaf9b'
+ routes:
+ - 10.255.2.22
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf8a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.23 - Peer: pod2-leaf10a'
+ routes:
+ - 10.255.2.23
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf8a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.24 - Peer: pod2-leaf10b'
+ routes:
+ - 10.255.2.24
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf8a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.5 - Peer: pod1-leaf1a'
+ routes:
+ - 10.255.100.5
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf8a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.7 - Peer: pod1-leaf2a'
+ routes:
+ - 10.255.100.7
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf8a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.9 - Peer: pod1-leaf3a'
+ routes:
+ - 10.255.100.9
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf8a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.11 - Peer: pod1-leaf4a'
+ routes:
+ - 10.255.100.11
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf8a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.13 - Peer: pod1-leaf5a'
+ routes:
+ - 10.255.100.13
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf8a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.15 - Peer: pod1-leaf6a'
+ routes:
+ - 10.255.100.15
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf8a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.17 - Peer: pod1-leaf7a'
+ routes:
+ - 10.255.100.17
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf8a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.19 - Peer: pod1-leaf8a'
+ routes:
+ - 10.255.100.19
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf8a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.21 - Peer: pod1-leaf9a'
+ routes:
+ - 10.255.100.21
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf8a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.23 - Peer: pod1-leaf10a'
+ routes:
+ - 10.255.100.23
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf8a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.5 - Peer: pod2-leaf1a'
+ routes:
+ - 10.255.200.5
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf8a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.7 - Peer: pod2-leaf2a'
+ routes:
+ - 10.255.200.7
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf8a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.9 - Peer: pod2-leaf3a'
+ routes:
+ - 10.255.200.9
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf8a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.11 - Peer: pod2-leaf4a'
+ routes:
+ - 10.255.200.11
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf8a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.13 - Peer: pod2-leaf5a'
+ routes:
+ - 10.255.200.13
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf8a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.15 - Peer: pod2-leaf6a'
+ routes:
+ - 10.255.200.15
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf8a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.17 - Peer: pod2-leaf7a'
+ routes:
+ - 10.255.200.17
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf8a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.19 - Peer: pod2-leaf8a'
+ routes:
+ - 10.255.200.19
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf8a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.21 - Peer: pod2-leaf9a'
+ routes:
+ - 10.255.200.21
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf8a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.23 - Peer: pod2-leaf10a'
+ routes:
+ - 10.255.200.23
+- VerifyRoutingProtocolModel:
+ filters:
+ tags:
+ - pod1-leaf2b
+ model: multi-agent
+ result_overwrite:
+ custom_field: 'Routing protocol model: multi-agent'
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf2b
+ result_overwrite:
+ custom_field: 'Route: 10.255.0.1 - Peer: super-spine1'
+ routes:
+ - 10.255.0.1
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf2b
+ result_overwrite:
+ custom_field: 'Route: 10.255.0.2 - Peer: super-spine2'
+ routes:
+ - 10.255.0.2
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf2b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.1 - Peer: pod1-spine1'
+ routes:
+ - 10.255.1.1
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf2b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.2 - Peer: pod1-spine2'
+ routes:
+ - 10.255.1.2
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf2b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.3 - Peer: pod1-spine3'
+ routes:
+ - 10.255.1.3
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf2b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.4 - Peer: pod1-spine4'
+ routes:
+ - 10.255.1.4
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf2b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.5 - Peer: pod1-leaf1a'
+ routes:
+ - 10.255.1.5
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf2b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.6 - Peer: pod1-leaf1b'
+ routes:
+ - 10.255.1.6
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf2b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.7 - Peer: pod1-leaf2a'
+ routes:
+ - 10.255.1.7
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf2b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.8 - Peer: pod1-leaf2b'
+ routes:
+ - 10.255.1.8
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf2b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.9 - Peer: pod1-leaf3a'
+ routes:
+ - 10.255.1.9
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf2b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.10 - Peer: pod1-leaf3b'
+ routes:
+ - 10.255.1.10
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf2b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.11 - Peer: pod1-leaf4a'
+ routes:
+ - 10.255.1.11
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf2b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.12 - Peer: pod1-leaf4b'
+ routes:
+ - 10.255.1.12
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf2b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.13 - Peer: pod1-leaf5a'
+ routes:
+ - 10.255.1.13
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf2b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.14 - Peer: pod1-leaf5b'
+ routes:
+ - 10.255.1.14
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf2b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.15 - Peer: pod1-leaf6a'
+ routes:
+ - 10.255.1.15
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf2b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.16 - Peer: pod1-leaf6b'
+ routes:
+ - 10.255.1.16
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf2b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.17 - Peer: pod1-leaf7a'
+ routes:
+ - 10.255.1.17
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf2b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.18 - Peer: pod1-leaf7b'
+ routes:
+ - 10.255.1.18
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf2b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.19 - Peer: pod1-leaf8a'
+ routes:
+ - 10.255.1.19
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf2b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.20 - Peer: pod1-leaf8b'
+ routes:
+ - 10.255.1.20
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf2b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.21 - Peer: pod1-leaf9a'
+ routes:
+ - 10.255.1.21
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf2b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.22 - Peer: pod1-leaf9b'
+ routes:
+ - 10.255.1.22
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf2b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.23 - Peer: pod1-leaf10a'
+ routes:
+ - 10.255.1.23
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf2b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.24 - Peer: pod1-leaf10b'
+ routes:
+ - 10.255.1.24
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf2b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.1 - Peer: pod2-spine1'
+ routes:
+ - 10.255.2.1
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf2b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.2 - Peer: pod2-spine2'
+ routes:
+ - 10.255.2.2
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf2b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.3 - Peer: pod2-spine3'
+ routes:
+ - 10.255.2.3
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf2b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.4 - Peer: pod2-spine4'
+ routes:
+ - 10.255.2.4
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf2b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.5 - Peer: pod2-leaf1a'
+ routes:
+ - 10.255.2.5
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf2b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.6 - Peer: pod2-leaf1b'
+ routes:
+ - 10.255.2.6
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf2b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.7 - Peer: pod2-leaf2a'
+ routes:
+ - 10.255.2.7
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf2b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.8 - Peer: pod2-leaf2b'
+ routes:
+ - 10.255.2.8
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf2b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.9 - Peer: pod2-leaf3a'
+ routes:
+ - 10.255.2.9
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf2b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.10 - Peer: pod2-leaf3b'
+ routes:
+ - 10.255.2.10
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf2b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.11 - Peer: pod2-leaf4a'
+ routes:
+ - 10.255.2.11
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf2b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.12 - Peer: pod2-leaf4b'
+ routes:
+ - 10.255.2.12
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf2b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.13 - Peer: pod2-leaf5a'
+ routes:
+ - 10.255.2.13
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf2b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.14 - Peer: pod2-leaf5b'
+ routes:
+ - 10.255.2.14
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf2b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.15 - Peer: pod2-leaf6a'
+ routes:
+ - 10.255.2.15
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf2b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.16 - Peer: pod2-leaf6b'
+ routes:
+ - 10.255.2.16
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf2b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.17 - Peer: pod2-leaf7a'
+ routes:
+ - 10.255.2.17
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf2b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.18 - Peer: pod2-leaf7b'
+ routes:
+ - 10.255.2.18
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf2b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.19 - Peer: pod2-leaf8a'
+ routes:
+ - 10.255.2.19
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf2b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.20 - Peer: pod2-leaf8b'
+ routes:
+ - 10.255.2.20
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf2b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.21 - Peer: pod2-leaf9a'
+ routes:
+ - 10.255.2.21
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf2b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.22 - Peer: pod2-leaf9b'
+ routes:
+ - 10.255.2.22
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf2b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.23 - Peer: pod2-leaf10a'
+ routes:
+ - 10.255.2.23
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf2b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.24 - Peer: pod2-leaf10b'
+ routes:
+ - 10.255.2.24
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf2b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.5 - Peer: pod1-leaf1a'
+ routes:
+ - 10.255.100.5
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf2b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.7 - Peer: pod1-leaf2a'
+ routes:
+ - 10.255.100.7
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf2b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.9 - Peer: pod1-leaf3a'
+ routes:
+ - 10.255.100.9
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf2b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.11 - Peer: pod1-leaf4a'
+ routes:
+ - 10.255.100.11
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf2b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.13 - Peer: pod1-leaf5a'
+ routes:
+ - 10.255.100.13
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf2b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.15 - Peer: pod1-leaf6a'
+ routes:
+ - 10.255.100.15
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf2b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.17 - Peer: pod1-leaf7a'
+ routes:
+ - 10.255.100.17
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf2b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.19 - Peer: pod1-leaf8a'
+ routes:
+ - 10.255.100.19
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf2b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.21 - Peer: pod1-leaf9a'
+ routes:
+ - 10.255.100.21
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf2b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.23 - Peer: pod1-leaf10a'
+ routes:
+ - 10.255.100.23
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf2b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.5 - Peer: pod2-leaf1a'
+ routes:
+ - 10.255.200.5
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf2b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.7 - Peer: pod2-leaf2a'
+ routes:
+ - 10.255.200.7
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf2b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.9 - Peer: pod2-leaf3a'
+ routes:
+ - 10.255.200.9
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf2b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.11 - Peer: pod2-leaf4a'
+ routes:
+ - 10.255.200.11
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf2b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.13 - Peer: pod2-leaf5a'
+ routes:
+ - 10.255.200.13
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf2b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.15 - Peer: pod2-leaf6a'
+ routes:
+ - 10.255.200.15
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf2b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.17 - Peer: pod2-leaf7a'
+ routes:
+ - 10.255.200.17
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf2b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.19 - Peer: pod2-leaf8a'
+ routes:
+ - 10.255.200.19
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf2b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.21 - Peer: pod2-leaf9a'
+ routes:
+ - 10.255.200.21
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf2b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.23 - Peer: pod2-leaf10a'
+ routes:
+ - 10.255.200.23
+- VerifyRoutingProtocolModel:
+ filters:
+ tags:
+ - pod1-leaf5b
+ model: multi-agent
+ result_overwrite:
+ custom_field: 'Routing protocol model: multi-agent'
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf5b
+ result_overwrite:
+ custom_field: 'Route: 10.255.0.1 - Peer: super-spine1'
+ routes:
+ - 10.255.0.1
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf5b
+ result_overwrite:
+ custom_field: 'Route: 10.255.0.2 - Peer: super-spine2'
+ routes:
+ - 10.255.0.2
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf5b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.1 - Peer: pod1-spine1'
+ routes:
+ - 10.255.1.1
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf5b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.2 - Peer: pod1-spine2'
+ routes:
+ - 10.255.1.2
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf5b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.3 - Peer: pod1-spine3'
+ routes:
+ - 10.255.1.3
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf5b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.4 - Peer: pod1-spine4'
+ routes:
+ - 10.255.1.4
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf5b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.5 - Peer: pod1-leaf1a'
+ routes:
+ - 10.255.1.5
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf5b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.6 - Peer: pod1-leaf1b'
+ routes:
+ - 10.255.1.6
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf5b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.7 - Peer: pod1-leaf2a'
+ routes:
+ - 10.255.1.7
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf5b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.8 - Peer: pod1-leaf2b'
+ routes:
+ - 10.255.1.8
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf5b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.9 - Peer: pod1-leaf3a'
+ routes:
+ - 10.255.1.9
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf5b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.10 - Peer: pod1-leaf3b'
+ routes:
+ - 10.255.1.10
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf5b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.11 - Peer: pod1-leaf4a'
+ routes:
+ - 10.255.1.11
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf5b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.12 - Peer: pod1-leaf4b'
+ routes:
+ - 10.255.1.12
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf5b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.13 - Peer: pod1-leaf5a'
+ routes:
+ - 10.255.1.13
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf5b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.14 - Peer: pod1-leaf5b'
+ routes:
+ - 10.255.1.14
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf5b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.15 - Peer: pod1-leaf6a'
+ routes:
+ - 10.255.1.15
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf5b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.16 - Peer: pod1-leaf6b'
+ routes:
+ - 10.255.1.16
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf5b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.17 - Peer: pod1-leaf7a'
+ routes:
+ - 10.255.1.17
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf5b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.18 - Peer: pod1-leaf7b'
+ routes:
+ - 10.255.1.18
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf5b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.19 - Peer: pod1-leaf8a'
+ routes:
+ - 10.255.1.19
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf5b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.20 - Peer: pod1-leaf8b'
+ routes:
+ - 10.255.1.20
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf5b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.21 - Peer: pod1-leaf9a'
+ routes:
+ - 10.255.1.21
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf5b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.22 - Peer: pod1-leaf9b'
+ routes:
+ - 10.255.1.22
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf5b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.23 - Peer: pod1-leaf10a'
+ routes:
+ - 10.255.1.23
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf5b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.24 - Peer: pod1-leaf10b'
+ routes:
+ - 10.255.1.24
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf5b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.1 - Peer: pod2-spine1'
+ routes:
+ - 10.255.2.1
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf5b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.2 - Peer: pod2-spine2'
+ routes:
+ - 10.255.2.2
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf5b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.3 - Peer: pod2-spine3'
+ routes:
+ - 10.255.2.3
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf5b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.4 - Peer: pod2-spine4'
+ routes:
+ - 10.255.2.4
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf5b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.5 - Peer: pod2-leaf1a'
+ routes:
+ - 10.255.2.5
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf5b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.6 - Peer: pod2-leaf1b'
+ routes:
+ - 10.255.2.6
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf5b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.7 - Peer: pod2-leaf2a'
+ routes:
+ - 10.255.2.7
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf5b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.8 - Peer: pod2-leaf2b'
+ routes:
+ - 10.255.2.8
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf5b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.9 - Peer: pod2-leaf3a'
+ routes:
+ - 10.255.2.9
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf5b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.10 - Peer: pod2-leaf3b'
+ routes:
+ - 10.255.2.10
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf5b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.11 - Peer: pod2-leaf4a'
+ routes:
+ - 10.255.2.11
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf5b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.12 - Peer: pod2-leaf4b'
+ routes:
+ - 10.255.2.12
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf5b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.13 - Peer: pod2-leaf5a'
+ routes:
+ - 10.255.2.13
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf5b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.14 - Peer: pod2-leaf5b'
+ routes:
+ - 10.255.2.14
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf5b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.15 - Peer: pod2-leaf6a'
+ routes:
+ - 10.255.2.15
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf5b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.16 - Peer: pod2-leaf6b'
+ routes:
+ - 10.255.2.16
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf5b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.17 - Peer: pod2-leaf7a'
+ routes:
+ - 10.255.2.17
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf5b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.18 - Peer: pod2-leaf7b'
+ routes:
+ - 10.255.2.18
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf5b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.19 - Peer: pod2-leaf8a'
+ routes:
+ - 10.255.2.19
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf5b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.20 - Peer: pod2-leaf8b'
+ routes:
+ - 10.255.2.20
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf5b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.21 - Peer: pod2-leaf9a'
+ routes:
+ - 10.255.2.21
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf5b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.22 - Peer: pod2-leaf9b'
+ routes:
+ - 10.255.2.22
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf5b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.23 - Peer: pod2-leaf10a'
+ routes:
+ - 10.255.2.23
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf5b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.24 - Peer: pod2-leaf10b'
+ routes:
+ - 10.255.2.24
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf5b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.5 - Peer: pod1-leaf1a'
+ routes:
+ - 10.255.100.5
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf5b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.7 - Peer: pod1-leaf2a'
+ routes:
+ - 10.255.100.7
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf5b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.9 - Peer: pod1-leaf3a'
+ routes:
+ - 10.255.100.9
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf5b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.11 - Peer: pod1-leaf4a'
+ routes:
+ - 10.255.100.11
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf5b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.13 - Peer: pod1-leaf5a'
+ routes:
+ - 10.255.100.13
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf5b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.15 - Peer: pod1-leaf6a'
+ routes:
+ - 10.255.100.15
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf5b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.17 - Peer: pod1-leaf7a'
+ routes:
+ - 10.255.100.17
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf5b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.19 - Peer: pod1-leaf8a'
+ routes:
+ - 10.255.100.19
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf5b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.21 - Peer: pod1-leaf9a'
+ routes:
+ - 10.255.100.21
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf5b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.23 - Peer: pod1-leaf10a'
+ routes:
+ - 10.255.100.23
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf5b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.5 - Peer: pod2-leaf1a'
+ routes:
+ - 10.255.200.5
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf5b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.7 - Peer: pod2-leaf2a'
+ routes:
+ - 10.255.200.7
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf5b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.9 - Peer: pod2-leaf3a'
+ routes:
+ - 10.255.200.9
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf5b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.11 - Peer: pod2-leaf4a'
+ routes:
+ - 10.255.200.11
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf5b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.13 - Peer: pod2-leaf5a'
+ routes:
+ - 10.255.200.13
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf5b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.15 - Peer: pod2-leaf6a'
+ routes:
+ - 10.255.200.15
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf5b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.17 - Peer: pod2-leaf7a'
+ routes:
+ - 10.255.200.17
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf5b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.19 - Peer: pod2-leaf8a'
+ routes:
+ - 10.255.200.19
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf5b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.21 - Peer: pod2-leaf9a'
+ routes:
+ - 10.255.200.21
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf5b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.23 - Peer: pod2-leaf10a'
+ routes:
+ - 10.255.200.23
+- VerifyRoutingProtocolModel:
+ filters:
+ tags:
+ - pod1-leaf8a
+ model: multi-agent
+ result_overwrite:
+ custom_field: 'Routing protocol model: multi-agent'
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf8a
+ result_overwrite:
+ custom_field: 'Route: 10.255.0.1 - Peer: super-spine1'
+ routes:
+ - 10.255.0.1
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf8a
+ result_overwrite:
+ custom_field: 'Route: 10.255.0.2 - Peer: super-spine2'
+ routes:
+ - 10.255.0.2
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf8a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.1 - Peer: pod1-spine1'
+ routes:
+ - 10.255.1.1
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf8a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.2 - Peer: pod1-spine2'
+ routes:
+ - 10.255.1.2
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf8a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.3 - Peer: pod1-spine3'
+ routes:
+ - 10.255.1.3
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf8a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.4 - Peer: pod1-spine4'
+ routes:
+ - 10.255.1.4
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf8a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.5 - Peer: pod1-leaf1a'
+ routes:
+ - 10.255.1.5
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf8a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.6 - Peer: pod1-leaf1b'
+ routes:
+ - 10.255.1.6
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf8a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.7 - Peer: pod1-leaf2a'
+ routes:
+ - 10.255.1.7
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf8a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.8 - Peer: pod1-leaf2b'
+ routes:
+ - 10.255.1.8
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf8a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.9 - Peer: pod1-leaf3a'
+ routes:
+ - 10.255.1.9
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf8a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.10 - Peer: pod1-leaf3b'
+ routes:
+ - 10.255.1.10
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf8a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.11 - Peer: pod1-leaf4a'
+ routes:
+ - 10.255.1.11
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf8a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.12 - Peer: pod1-leaf4b'
+ routes:
+ - 10.255.1.12
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf8a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.13 - Peer: pod1-leaf5a'
+ routes:
+ - 10.255.1.13
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf8a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.14 - Peer: pod1-leaf5b'
+ routes:
+ - 10.255.1.14
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf8a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.15 - Peer: pod1-leaf6a'
+ routes:
+ - 10.255.1.15
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf8a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.16 - Peer: pod1-leaf6b'
+ routes:
+ - 10.255.1.16
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf8a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.17 - Peer: pod1-leaf7a'
+ routes:
+ - 10.255.1.17
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf8a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.18 - Peer: pod1-leaf7b'
+ routes:
+ - 10.255.1.18
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf8a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.19 - Peer: pod1-leaf8a'
+ routes:
+ - 10.255.1.19
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf8a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.20 - Peer: pod1-leaf8b'
+ routes:
+ - 10.255.1.20
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf8a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.21 - Peer: pod1-leaf9a'
+ routes:
+ - 10.255.1.21
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf8a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.22 - Peer: pod1-leaf9b'
+ routes:
+ - 10.255.1.22
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf8a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.23 - Peer: pod1-leaf10a'
+ routes:
+ - 10.255.1.23
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf8a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.24 - Peer: pod1-leaf10b'
+ routes:
+ - 10.255.1.24
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf8a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.1 - Peer: pod2-spine1'
+ routes:
+ - 10.255.2.1
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf8a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.2 - Peer: pod2-spine2'
+ routes:
+ - 10.255.2.2
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf8a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.3 - Peer: pod2-spine3'
+ routes:
+ - 10.255.2.3
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf8a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.4 - Peer: pod2-spine4'
+ routes:
+ - 10.255.2.4
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf8a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.5 - Peer: pod2-leaf1a'
+ routes:
+ - 10.255.2.5
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf8a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.6 - Peer: pod2-leaf1b'
+ routes:
+ - 10.255.2.6
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf8a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.7 - Peer: pod2-leaf2a'
+ routes:
+ - 10.255.2.7
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf8a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.8 - Peer: pod2-leaf2b'
+ routes:
+ - 10.255.2.8
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf8a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.9 - Peer: pod2-leaf3a'
+ routes:
+ - 10.255.2.9
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf8a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.10 - Peer: pod2-leaf3b'
+ routes:
+ - 10.255.2.10
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf8a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.11 - Peer: pod2-leaf4a'
+ routes:
+ - 10.255.2.11
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf8a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.12 - Peer: pod2-leaf4b'
+ routes:
+ - 10.255.2.12
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf8a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.13 - Peer: pod2-leaf5a'
+ routes:
+ - 10.255.2.13
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf8a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.14 - Peer: pod2-leaf5b'
+ routes:
+ - 10.255.2.14
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf8a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.15 - Peer: pod2-leaf6a'
+ routes:
+ - 10.255.2.15
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf8a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.16 - Peer: pod2-leaf6b'
+ routes:
+ - 10.255.2.16
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf8a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.17 - Peer: pod2-leaf7a'
+ routes:
+ - 10.255.2.17
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf8a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.18 - Peer: pod2-leaf7b'
+ routes:
+ - 10.255.2.18
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf8a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.19 - Peer: pod2-leaf8a'
+ routes:
+ - 10.255.2.19
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf8a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.20 - Peer: pod2-leaf8b'
+ routes:
+ - 10.255.2.20
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf8a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.21 - Peer: pod2-leaf9a'
+ routes:
+ - 10.255.2.21
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf8a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.22 - Peer: pod2-leaf9b'
+ routes:
+ - 10.255.2.22
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf8a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.23 - Peer: pod2-leaf10a'
+ routes:
+ - 10.255.2.23
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf8a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.24 - Peer: pod2-leaf10b'
+ routes:
+ - 10.255.2.24
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf8a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.5 - Peer: pod1-leaf1a'
+ routes:
+ - 10.255.100.5
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf8a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.7 - Peer: pod1-leaf2a'
+ routes:
+ - 10.255.100.7
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf8a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.9 - Peer: pod1-leaf3a'
+ routes:
+ - 10.255.100.9
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf8a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.11 - Peer: pod1-leaf4a'
+ routes:
+ - 10.255.100.11
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf8a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.13 - Peer: pod1-leaf5a'
+ routes:
+ - 10.255.100.13
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf8a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.15 - Peer: pod1-leaf6a'
+ routes:
+ - 10.255.100.15
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf8a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.17 - Peer: pod1-leaf7a'
+ routes:
+ - 10.255.100.17
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf8a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.19 - Peer: pod1-leaf8a'
+ routes:
+ - 10.255.100.19
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf8a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.21 - Peer: pod1-leaf9a'
+ routes:
+ - 10.255.100.21
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf8a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.23 - Peer: pod1-leaf10a'
+ routes:
+ - 10.255.100.23
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf8a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.5 - Peer: pod2-leaf1a'
+ routes:
+ - 10.255.200.5
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf8a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.7 - Peer: pod2-leaf2a'
+ routes:
+ - 10.255.200.7
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf8a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.9 - Peer: pod2-leaf3a'
+ routes:
+ - 10.255.200.9
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf8a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.11 - Peer: pod2-leaf4a'
+ routes:
+ - 10.255.200.11
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf8a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.13 - Peer: pod2-leaf5a'
+ routes:
+ - 10.255.200.13
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf8a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.15 - Peer: pod2-leaf6a'
+ routes:
+ - 10.255.200.15
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf8a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.17 - Peer: pod2-leaf7a'
+ routes:
+ - 10.255.200.17
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf8a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.19 - Peer: pod2-leaf8a'
+ routes:
+ - 10.255.200.19
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf8a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.21 - Peer: pod2-leaf9a'
+ routes:
+ - 10.255.200.21
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf8a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.23 - Peer: pod2-leaf10a'
+ routes:
+ - 10.255.200.23
+- VerifyRoutingProtocolModel:
+ filters:
+ tags:
+ - pod2-spine4
+ model: multi-agent
+ result_overwrite:
+ custom_field: 'Routing protocol model: multi-agent'
+- VerifyRoutingProtocolModel:
+ filters:
+ tags:
+ - pod2-leaf3b
+ model: multi-agent
+ result_overwrite:
+ custom_field: 'Routing protocol model: multi-agent'
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf3b
+ result_overwrite:
+ custom_field: 'Route: 10.255.0.1 - Peer: super-spine1'
+ routes:
+ - 10.255.0.1
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf3b
+ result_overwrite:
+ custom_field: 'Route: 10.255.0.2 - Peer: super-spine2'
+ routes:
+ - 10.255.0.2
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf3b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.1 - Peer: pod1-spine1'
+ routes:
+ - 10.255.1.1
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf3b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.2 - Peer: pod1-spine2'
+ routes:
+ - 10.255.1.2
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf3b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.3 - Peer: pod1-spine3'
+ routes:
+ - 10.255.1.3
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf3b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.4 - Peer: pod1-spine4'
+ routes:
+ - 10.255.1.4
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf3b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.5 - Peer: pod1-leaf1a'
+ routes:
+ - 10.255.1.5
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf3b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.6 - Peer: pod1-leaf1b'
+ routes:
+ - 10.255.1.6
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf3b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.7 - Peer: pod1-leaf2a'
+ routes:
+ - 10.255.1.7
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf3b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.8 - Peer: pod1-leaf2b'
+ routes:
+ - 10.255.1.8
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf3b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.9 - Peer: pod1-leaf3a'
+ routes:
+ - 10.255.1.9
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf3b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.10 - Peer: pod1-leaf3b'
+ routes:
+ - 10.255.1.10
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf3b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.11 - Peer: pod1-leaf4a'
+ routes:
+ - 10.255.1.11
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf3b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.12 - Peer: pod1-leaf4b'
+ routes:
+ - 10.255.1.12
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf3b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.13 - Peer: pod1-leaf5a'
+ routes:
+ - 10.255.1.13
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf3b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.14 - Peer: pod1-leaf5b'
+ routes:
+ - 10.255.1.14
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf3b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.15 - Peer: pod1-leaf6a'
+ routes:
+ - 10.255.1.15
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf3b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.16 - Peer: pod1-leaf6b'
+ routes:
+ - 10.255.1.16
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf3b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.17 - Peer: pod1-leaf7a'
+ routes:
+ - 10.255.1.17
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf3b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.18 - Peer: pod1-leaf7b'
+ routes:
+ - 10.255.1.18
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf3b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.19 - Peer: pod1-leaf8a'
+ routes:
+ - 10.255.1.19
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf3b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.20 - Peer: pod1-leaf8b'
+ routes:
+ - 10.255.1.20
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf3b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.21 - Peer: pod1-leaf9a'
+ routes:
+ - 10.255.1.21
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf3b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.22 - Peer: pod1-leaf9b'
+ routes:
+ - 10.255.1.22
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf3b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.23 - Peer: pod1-leaf10a'
+ routes:
+ - 10.255.1.23
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf3b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.24 - Peer: pod1-leaf10b'
+ routes:
+ - 10.255.1.24
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf3b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.1 - Peer: pod2-spine1'
+ routes:
+ - 10.255.2.1
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf3b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.2 - Peer: pod2-spine2'
+ routes:
+ - 10.255.2.2
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf3b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.3 - Peer: pod2-spine3'
+ routes:
+ - 10.255.2.3
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf3b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.4 - Peer: pod2-spine4'
+ routes:
+ - 10.255.2.4
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf3b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.5 - Peer: pod2-leaf1a'
+ routes:
+ - 10.255.2.5
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf3b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.6 - Peer: pod2-leaf1b'
+ routes:
+ - 10.255.2.6
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf3b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.7 - Peer: pod2-leaf2a'
+ routes:
+ - 10.255.2.7
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf3b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.8 - Peer: pod2-leaf2b'
+ routes:
+ - 10.255.2.8
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf3b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.9 - Peer: pod2-leaf3a'
+ routes:
+ - 10.255.2.9
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf3b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.10 - Peer: pod2-leaf3b'
+ routes:
+ - 10.255.2.10
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf3b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.11 - Peer: pod2-leaf4a'
+ routes:
+ - 10.255.2.11
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf3b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.12 - Peer: pod2-leaf4b'
+ routes:
+ - 10.255.2.12
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf3b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.13 - Peer: pod2-leaf5a'
+ routes:
+ - 10.255.2.13
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf3b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.14 - Peer: pod2-leaf5b'
+ routes:
+ - 10.255.2.14
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf3b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.15 - Peer: pod2-leaf6a'
+ routes:
+ - 10.255.2.15
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf3b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.16 - Peer: pod2-leaf6b'
+ routes:
+ - 10.255.2.16
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf3b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.17 - Peer: pod2-leaf7a'
+ routes:
+ - 10.255.2.17
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf3b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.18 - Peer: pod2-leaf7b'
+ routes:
+ - 10.255.2.18
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf3b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.19 - Peer: pod2-leaf8a'
+ routes:
+ - 10.255.2.19
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf3b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.20 - Peer: pod2-leaf8b'
+ routes:
+ - 10.255.2.20
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf3b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.21 - Peer: pod2-leaf9a'
+ routes:
+ - 10.255.2.21
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf3b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.22 - Peer: pod2-leaf9b'
+ routes:
+ - 10.255.2.22
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf3b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.23 - Peer: pod2-leaf10a'
+ routes:
+ - 10.255.2.23
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf3b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.24 - Peer: pod2-leaf10b'
+ routes:
+ - 10.255.2.24
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf3b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.5 - Peer: pod1-leaf1a'
+ routes:
+ - 10.255.100.5
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf3b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.7 - Peer: pod1-leaf2a'
+ routes:
+ - 10.255.100.7
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf3b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.9 - Peer: pod1-leaf3a'
+ routes:
+ - 10.255.100.9
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf3b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.11 - Peer: pod1-leaf4a'
+ routes:
+ - 10.255.100.11
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf3b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.13 - Peer: pod1-leaf5a'
+ routes:
+ - 10.255.100.13
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf3b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.15 - Peer: pod1-leaf6a'
+ routes:
+ - 10.255.100.15
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf3b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.17 - Peer: pod1-leaf7a'
+ routes:
+ - 10.255.100.17
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf3b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.19 - Peer: pod1-leaf8a'
+ routes:
+ - 10.255.100.19
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf3b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.21 - Peer: pod1-leaf9a'
+ routes:
+ - 10.255.100.21
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf3b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.23 - Peer: pod1-leaf10a'
+ routes:
+ - 10.255.100.23
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf3b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.5 - Peer: pod2-leaf1a'
+ routes:
+ - 10.255.200.5
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf3b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.7 - Peer: pod2-leaf2a'
+ routes:
+ - 10.255.200.7
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf3b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.9 - Peer: pod2-leaf3a'
+ routes:
+ - 10.255.200.9
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf3b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.11 - Peer: pod2-leaf4a'
+ routes:
+ - 10.255.200.11
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf3b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.13 - Peer: pod2-leaf5a'
+ routes:
+ - 10.255.200.13
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf3b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.15 - Peer: pod2-leaf6a'
+ routes:
+ - 10.255.200.15
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf3b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.17 - Peer: pod2-leaf7a'
+ routes:
+ - 10.255.200.17
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf3b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.19 - Peer: pod2-leaf8a'
+ routes:
+ - 10.255.200.19
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf3b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.21 - Peer: pod2-leaf9a'
+ routes:
+ - 10.255.200.21
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf3b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.23 - Peer: pod2-leaf10a'
+ routes:
+ - 10.255.200.23
+- VerifyRoutingProtocolModel:
+ filters:
+ tags:
+ - pod2-leaf4b
+ model: multi-agent
+ result_overwrite:
+ custom_field: 'Routing protocol model: multi-agent'
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf4b
+ result_overwrite:
+ custom_field: 'Route: 10.255.0.1 - Peer: super-spine1'
+ routes:
+ - 10.255.0.1
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf4b
+ result_overwrite:
+ custom_field: 'Route: 10.255.0.2 - Peer: super-spine2'
+ routes:
+ - 10.255.0.2
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf4b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.1 - Peer: pod1-spine1'
+ routes:
+ - 10.255.1.1
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf4b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.2 - Peer: pod1-spine2'
+ routes:
+ - 10.255.1.2
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf4b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.3 - Peer: pod1-spine3'
+ routes:
+ - 10.255.1.3
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf4b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.4 - Peer: pod1-spine4'
+ routes:
+ - 10.255.1.4
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf4b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.5 - Peer: pod1-leaf1a'
+ routes:
+ - 10.255.1.5
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf4b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.6 - Peer: pod1-leaf1b'
+ routes:
+ - 10.255.1.6
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf4b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.7 - Peer: pod1-leaf2a'
+ routes:
+ - 10.255.1.7
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf4b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.8 - Peer: pod1-leaf2b'
+ routes:
+ - 10.255.1.8
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf4b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.9 - Peer: pod1-leaf3a'
+ routes:
+ - 10.255.1.9
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf4b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.10 - Peer: pod1-leaf3b'
+ routes:
+ - 10.255.1.10
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf4b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.11 - Peer: pod1-leaf4a'
+ routes:
+ - 10.255.1.11
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf4b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.12 - Peer: pod1-leaf4b'
+ routes:
+ - 10.255.1.12
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf4b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.13 - Peer: pod1-leaf5a'
+ routes:
+ - 10.255.1.13
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf4b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.14 - Peer: pod1-leaf5b'
+ routes:
+ - 10.255.1.14
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf4b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.15 - Peer: pod1-leaf6a'
+ routes:
+ - 10.255.1.15
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf4b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.16 - Peer: pod1-leaf6b'
+ routes:
+ - 10.255.1.16
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf4b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.17 - Peer: pod1-leaf7a'
+ routes:
+ - 10.255.1.17
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf4b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.18 - Peer: pod1-leaf7b'
+ routes:
+ - 10.255.1.18
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf4b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.19 - Peer: pod1-leaf8a'
+ routes:
+ - 10.255.1.19
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf4b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.20 - Peer: pod1-leaf8b'
+ routes:
+ - 10.255.1.20
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf4b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.21 - Peer: pod1-leaf9a'
+ routes:
+ - 10.255.1.21
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf4b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.22 - Peer: pod1-leaf9b'
+ routes:
+ - 10.255.1.22
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf4b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.23 - Peer: pod1-leaf10a'
+ routes:
+ - 10.255.1.23
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf4b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.24 - Peer: pod1-leaf10b'
+ routes:
+ - 10.255.1.24
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf4b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.1 - Peer: pod2-spine1'
+ routes:
+ - 10.255.2.1
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf4b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.2 - Peer: pod2-spine2'
+ routes:
+ - 10.255.2.2
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf4b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.3 - Peer: pod2-spine3'
+ routes:
+ - 10.255.2.3
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf4b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.4 - Peer: pod2-spine4'
+ routes:
+ - 10.255.2.4
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf4b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.5 - Peer: pod2-leaf1a'
+ routes:
+ - 10.255.2.5
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf4b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.6 - Peer: pod2-leaf1b'
+ routes:
+ - 10.255.2.6
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf4b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.7 - Peer: pod2-leaf2a'
+ routes:
+ - 10.255.2.7
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf4b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.8 - Peer: pod2-leaf2b'
+ routes:
+ - 10.255.2.8
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf4b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.9 - Peer: pod2-leaf3a'
+ routes:
+ - 10.255.2.9
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf4b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.10 - Peer: pod2-leaf3b'
+ routes:
+ - 10.255.2.10
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf4b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.11 - Peer: pod2-leaf4a'
+ routes:
+ - 10.255.2.11
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf4b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.12 - Peer: pod2-leaf4b'
+ routes:
+ - 10.255.2.12
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf4b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.13 - Peer: pod2-leaf5a'
+ routes:
+ - 10.255.2.13
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf4b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.14 - Peer: pod2-leaf5b'
+ routes:
+ - 10.255.2.14
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf4b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.15 - Peer: pod2-leaf6a'
+ routes:
+ - 10.255.2.15
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf4b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.16 - Peer: pod2-leaf6b'
+ routes:
+ - 10.255.2.16
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf4b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.17 - Peer: pod2-leaf7a'
+ routes:
+ - 10.255.2.17
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf4b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.18 - Peer: pod2-leaf7b'
+ routes:
+ - 10.255.2.18
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf4b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.19 - Peer: pod2-leaf8a'
+ routes:
+ - 10.255.2.19
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf4b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.20 - Peer: pod2-leaf8b'
+ routes:
+ - 10.255.2.20
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf4b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.21 - Peer: pod2-leaf9a'
+ routes:
+ - 10.255.2.21
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf4b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.22 - Peer: pod2-leaf9b'
+ routes:
+ - 10.255.2.22
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf4b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.23 - Peer: pod2-leaf10a'
+ routes:
+ - 10.255.2.23
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf4b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.24 - Peer: pod2-leaf10b'
+ routes:
+ - 10.255.2.24
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf4b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.5 - Peer: pod1-leaf1a'
+ routes:
+ - 10.255.100.5
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf4b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.7 - Peer: pod1-leaf2a'
+ routes:
+ - 10.255.100.7
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf4b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.9 - Peer: pod1-leaf3a'
+ routes:
+ - 10.255.100.9
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf4b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.11 - Peer: pod1-leaf4a'
+ routes:
+ - 10.255.100.11
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf4b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.13 - Peer: pod1-leaf5a'
+ routes:
+ - 10.255.100.13
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf4b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.15 - Peer: pod1-leaf6a'
+ routes:
+ - 10.255.100.15
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf4b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.17 - Peer: pod1-leaf7a'
+ routes:
+ - 10.255.100.17
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf4b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.19 - Peer: pod1-leaf8a'
+ routes:
+ - 10.255.100.19
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf4b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.21 - Peer: pod1-leaf9a'
+ routes:
+ - 10.255.100.21
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf4b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.23 - Peer: pod1-leaf10a'
+ routes:
+ - 10.255.100.23
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf4b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.5 - Peer: pod2-leaf1a'
+ routes:
+ - 10.255.200.5
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf4b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.7 - Peer: pod2-leaf2a'
+ routes:
+ - 10.255.200.7
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf4b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.9 - Peer: pod2-leaf3a'
+ routes:
+ - 10.255.200.9
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf4b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.11 - Peer: pod2-leaf4a'
+ routes:
+ - 10.255.200.11
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf4b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.13 - Peer: pod2-leaf5a'
+ routes:
+ - 10.255.200.13
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf4b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.15 - Peer: pod2-leaf6a'
+ routes:
+ - 10.255.200.15
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf4b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.17 - Peer: pod2-leaf7a'
+ routes:
+ - 10.255.200.17
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf4b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.19 - Peer: pod2-leaf8a'
+ routes:
+ - 10.255.200.19
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf4b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.21 - Peer: pod2-leaf9a'
+ routes:
+ - 10.255.200.21
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf4b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.23 - Peer: pod2-leaf10a'
+ routes:
+ - 10.255.200.23
+- VerifyRoutingProtocolModel:
+ filters:
+ tags:
+ - pod1-spine1
+ model: multi-agent
+ result_overwrite:
+ custom_field: 'Routing protocol model: multi-agent'
+- VerifyRoutingProtocolModel:
+ filters:
+ tags:
+ - pod2-leaf9a
+ model: multi-agent
+ result_overwrite:
+ custom_field: 'Routing protocol model: multi-agent'
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf9a
+ result_overwrite:
+ custom_field: 'Route: 10.255.0.1 - Peer: super-spine1'
+ routes:
+ - 10.255.0.1
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf9a
+ result_overwrite:
+ custom_field: 'Route: 10.255.0.2 - Peer: super-spine2'
+ routes:
+ - 10.255.0.2
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf9a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.1 - Peer: pod1-spine1'
+ routes:
+ - 10.255.1.1
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf9a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.2 - Peer: pod1-spine2'
+ routes:
+ - 10.255.1.2
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf9a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.3 - Peer: pod1-spine3'
+ routes:
+ - 10.255.1.3
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf9a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.4 - Peer: pod1-spine4'
+ routes:
+ - 10.255.1.4
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf9a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.5 - Peer: pod1-leaf1a'
+ routes:
+ - 10.255.1.5
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf9a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.6 - Peer: pod1-leaf1b'
+ routes:
+ - 10.255.1.6
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf9a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.7 - Peer: pod1-leaf2a'
+ routes:
+ - 10.255.1.7
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf9a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.8 - Peer: pod1-leaf2b'
+ routes:
+ - 10.255.1.8
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf9a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.9 - Peer: pod1-leaf3a'
+ routes:
+ - 10.255.1.9
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf9a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.10 - Peer: pod1-leaf3b'
+ routes:
+ - 10.255.1.10
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf9a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.11 - Peer: pod1-leaf4a'
+ routes:
+ - 10.255.1.11
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf9a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.12 - Peer: pod1-leaf4b'
+ routes:
+ - 10.255.1.12
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf9a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.13 - Peer: pod1-leaf5a'
+ routes:
+ - 10.255.1.13
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf9a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.14 - Peer: pod1-leaf5b'
+ routes:
+ - 10.255.1.14
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf9a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.15 - Peer: pod1-leaf6a'
+ routes:
+ - 10.255.1.15
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf9a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.16 - Peer: pod1-leaf6b'
+ routes:
+ - 10.255.1.16
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf9a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.17 - Peer: pod1-leaf7a'
+ routes:
+ - 10.255.1.17
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf9a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.18 - Peer: pod1-leaf7b'
+ routes:
+ - 10.255.1.18
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf9a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.19 - Peer: pod1-leaf8a'
+ routes:
+ - 10.255.1.19
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf9a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.20 - Peer: pod1-leaf8b'
+ routes:
+ - 10.255.1.20
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf9a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.21 - Peer: pod1-leaf9a'
+ routes:
+ - 10.255.1.21
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf9a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.22 - Peer: pod1-leaf9b'
+ routes:
+ - 10.255.1.22
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf9a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.23 - Peer: pod1-leaf10a'
+ routes:
+ - 10.255.1.23
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf9a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.24 - Peer: pod1-leaf10b'
+ routes:
+ - 10.255.1.24
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf9a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.1 - Peer: pod2-spine1'
+ routes:
+ - 10.255.2.1
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf9a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.2 - Peer: pod2-spine2'
+ routes:
+ - 10.255.2.2
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf9a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.3 - Peer: pod2-spine3'
+ routes:
+ - 10.255.2.3
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf9a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.4 - Peer: pod2-spine4'
+ routes:
+ - 10.255.2.4
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf9a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.5 - Peer: pod2-leaf1a'
+ routes:
+ - 10.255.2.5
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf9a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.6 - Peer: pod2-leaf1b'
+ routes:
+ - 10.255.2.6
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf9a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.7 - Peer: pod2-leaf2a'
+ routes:
+ - 10.255.2.7
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf9a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.8 - Peer: pod2-leaf2b'
+ routes:
+ - 10.255.2.8
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf9a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.9 - Peer: pod2-leaf3a'
+ routes:
+ - 10.255.2.9
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf9a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.10 - Peer: pod2-leaf3b'
+ routes:
+ - 10.255.2.10
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf9a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.11 - Peer: pod2-leaf4a'
+ routes:
+ - 10.255.2.11
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf9a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.12 - Peer: pod2-leaf4b'
+ routes:
+ - 10.255.2.12
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf9a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.13 - Peer: pod2-leaf5a'
+ routes:
+ - 10.255.2.13
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf9a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.14 - Peer: pod2-leaf5b'
+ routes:
+ - 10.255.2.14
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf9a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.15 - Peer: pod2-leaf6a'
+ routes:
+ - 10.255.2.15
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf9a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.16 - Peer: pod2-leaf6b'
+ routes:
+ - 10.255.2.16
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf9a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.17 - Peer: pod2-leaf7a'
+ routes:
+ - 10.255.2.17
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf9a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.18 - Peer: pod2-leaf7b'
+ routes:
+ - 10.255.2.18
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf9a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.19 - Peer: pod2-leaf8a'
+ routes:
+ - 10.255.2.19
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf9a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.20 - Peer: pod2-leaf8b'
+ routes:
+ - 10.255.2.20
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf9a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.21 - Peer: pod2-leaf9a'
+ routes:
+ - 10.255.2.21
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf9a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.22 - Peer: pod2-leaf9b'
+ routes:
+ - 10.255.2.22
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf9a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.23 - Peer: pod2-leaf10a'
+ routes:
+ - 10.255.2.23
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf9a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.24 - Peer: pod2-leaf10b'
+ routes:
+ - 10.255.2.24
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf9a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.5 - Peer: pod1-leaf1a'
+ routes:
+ - 10.255.100.5
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf9a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.7 - Peer: pod1-leaf2a'
+ routes:
+ - 10.255.100.7
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf9a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.9 - Peer: pod1-leaf3a'
+ routes:
+ - 10.255.100.9
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf9a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.11 - Peer: pod1-leaf4a'
+ routes:
+ - 10.255.100.11
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf9a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.13 - Peer: pod1-leaf5a'
+ routes:
+ - 10.255.100.13
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf9a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.15 - Peer: pod1-leaf6a'
+ routes:
+ - 10.255.100.15
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf9a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.17 - Peer: pod1-leaf7a'
+ routes:
+ - 10.255.100.17
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf9a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.19 - Peer: pod1-leaf8a'
+ routes:
+ - 10.255.100.19
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf9a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.21 - Peer: pod1-leaf9a'
+ routes:
+ - 10.255.100.21
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf9a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.23 - Peer: pod1-leaf10a'
+ routes:
+ - 10.255.100.23
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf9a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.5 - Peer: pod2-leaf1a'
+ routes:
+ - 10.255.200.5
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf9a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.7 - Peer: pod2-leaf2a'
+ routes:
+ - 10.255.200.7
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf9a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.9 - Peer: pod2-leaf3a'
+ routes:
+ - 10.255.200.9
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf9a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.11 - Peer: pod2-leaf4a'
+ routes:
+ - 10.255.200.11
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf9a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.13 - Peer: pod2-leaf5a'
+ routes:
+ - 10.255.200.13
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf9a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.15 - Peer: pod2-leaf6a'
+ routes:
+ - 10.255.200.15
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf9a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.17 - Peer: pod2-leaf7a'
+ routes:
+ - 10.255.200.17
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf9a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.19 - Peer: pod2-leaf8a'
+ routes:
+ - 10.255.200.19
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf9a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.21 - Peer: pod2-leaf9a'
+ routes:
+ - 10.255.200.21
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf9a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.23 - Peer: pod2-leaf10a'
+ routes:
+ - 10.255.200.23
+- VerifyRoutingProtocolModel:
+ filters:
+ tags:
+ - pod2-leaf9b
+ model: multi-agent
+ result_overwrite:
+ custom_field: 'Routing protocol model: multi-agent'
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf9b
+ result_overwrite:
+ custom_field: 'Route: 10.255.0.1 - Peer: super-spine1'
+ routes:
+ - 10.255.0.1
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf9b
+ result_overwrite:
+ custom_field: 'Route: 10.255.0.2 - Peer: super-spine2'
+ routes:
+ - 10.255.0.2
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf9b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.1 - Peer: pod1-spine1'
+ routes:
+ - 10.255.1.1
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf9b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.2 - Peer: pod1-spine2'
+ routes:
+ - 10.255.1.2
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf9b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.3 - Peer: pod1-spine3'
+ routes:
+ - 10.255.1.3
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf9b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.4 - Peer: pod1-spine4'
+ routes:
+ - 10.255.1.4
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf9b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.5 - Peer: pod1-leaf1a'
+ routes:
+ - 10.255.1.5
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf9b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.6 - Peer: pod1-leaf1b'
+ routes:
+ - 10.255.1.6
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf9b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.7 - Peer: pod1-leaf2a'
+ routes:
+ - 10.255.1.7
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf9b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.8 - Peer: pod1-leaf2b'
+ routes:
+ - 10.255.1.8
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf9b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.9 - Peer: pod1-leaf3a'
+ routes:
+ - 10.255.1.9
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf9b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.10 - Peer: pod1-leaf3b'
+ routes:
+ - 10.255.1.10
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf9b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.11 - Peer: pod1-leaf4a'
+ routes:
+ - 10.255.1.11
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf9b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.12 - Peer: pod1-leaf4b'
+ routes:
+ - 10.255.1.12
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf9b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.13 - Peer: pod1-leaf5a'
+ routes:
+ - 10.255.1.13
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf9b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.14 - Peer: pod1-leaf5b'
+ routes:
+ - 10.255.1.14
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf9b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.15 - Peer: pod1-leaf6a'
+ routes:
+ - 10.255.1.15
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf9b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.16 - Peer: pod1-leaf6b'
+ routes:
+ - 10.255.1.16
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf9b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.17 - Peer: pod1-leaf7a'
+ routes:
+ - 10.255.1.17
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf9b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.18 - Peer: pod1-leaf7b'
+ routes:
+ - 10.255.1.18
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf9b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.19 - Peer: pod1-leaf8a'
+ routes:
+ - 10.255.1.19
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf9b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.20 - Peer: pod1-leaf8b'
+ routes:
+ - 10.255.1.20
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf9b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.21 - Peer: pod1-leaf9a'
+ routes:
+ - 10.255.1.21
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf9b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.22 - Peer: pod1-leaf9b'
+ routes:
+ - 10.255.1.22
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf9b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.23 - Peer: pod1-leaf10a'
+ routes:
+ - 10.255.1.23
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf9b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.24 - Peer: pod1-leaf10b'
+ routes:
+ - 10.255.1.24
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf9b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.1 - Peer: pod2-spine1'
+ routes:
+ - 10.255.2.1
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf9b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.2 - Peer: pod2-spine2'
+ routes:
+ - 10.255.2.2
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf9b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.3 - Peer: pod2-spine3'
+ routes:
+ - 10.255.2.3
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf9b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.4 - Peer: pod2-spine4'
+ routes:
+ - 10.255.2.4
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf9b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.5 - Peer: pod2-leaf1a'
+ routes:
+ - 10.255.2.5
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf9b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.6 - Peer: pod2-leaf1b'
+ routes:
+ - 10.255.2.6
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf9b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.7 - Peer: pod2-leaf2a'
+ routes:
+ - 10.255.2.7
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf9b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.8 - Peer: pod2-leaf2b'
+ routes:
+ - 10.255.2.8
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf9b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.9 - Peer: pod2-leaf3a'
+ routes:
+ - 10.255.2.9
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf9b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.10 - Peer: pod2-leaf3b'
+ routes:
+ - 10.255.2.10
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf9b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.11 - Peer: pod2-leaf4a'
+ routes:
+ - 10.255.2.11
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf9b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.12 - Peer: pod2-leaf4b'
+ routes:
+ - 10.255.2.12
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf9b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.13 - Peer: pod2-leaf5a'
+ routes:
+ - 10.255.2.13
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf9b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.14 - Peer: pod2-leaf5b'
+ routes:
+ - 10.255.2.14
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf9b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.15 - Peer: pod2-leaf6a'
+ routes:
+ - 10.255.2.15
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf9b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.16 - Peer: pod2-leaf6b'
+ routes:
+ - 10.255.2.16
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf9b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.17 - Peer: pod2-leaf7a'
+ routes:
+ - 10.255.2.17
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf9b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.18 - Peer: pod2-leaf7b'
+ routes:
+ - 10.255.2.18
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf9b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.19 - Peer: pod2-leaf8a'
+ routes:
+ - 10.255.2.19
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf9b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.20 - Peer: pod2-leaf8b'
+ routes:
+ - 10.255.2.20
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf9b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.21 - Peer: pod2-leaf9a'
+ routes:
+ - 10.255.2.21
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf9b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.22 - Peer: pod2-leaf9b'
+ routes:
+ - 10.255.2.22
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf9b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.23 - Peer: pod2-leaf10a'
+ routes:
+ - 10.255.2.23
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf9b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.24 - Peer: pod2-leaf10b'
+ routes:
+ - 10.255.2.24
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf9b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.5 - Peer: pod1-leaf1a'
+ routes:
+ - 10.255.100.5
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf9b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.7 - Peer: pod1-leaf2a'
+ routes:
+ - 10.255.100.7
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf9b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.9 - Peer: pod1-leaf3a'
+ routes:
+ - 10.255.100.9
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf9b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.11 - Peer: pod1-leaf4a'
+ routes:
+ - 10.255.100.11
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf9b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.13 - Peer: pod1-leaf5a'
+ routes:
+ - 10.255.100.13
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf9b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.15 - Peer: pod1-leaf6a'
+ routes:
+ - 10.255.100.15
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf9b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.17 - Peer: pod1-leaf7a'
+ routes:
+ - 10.255.100.17
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf9b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.19 - Peer: pod1-leaf8a'
+ routes:
+ - 10.255.100.19
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf9b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.21 - Peer: pod1-leaf9a'
+ routes:
+ - 10.255.100.21
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf9b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.23 - Peer: pod1-leaf10a'
+ routes:
+ - 10.255.100.23
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf9b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.5 - Peer: pod2-leaf1a'
+ routes:
+ - 10.255.200.5
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf9b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.7 - Peer: pod2-leaf2a'
+ routes:
+ - 10.255.200.7
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf9b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.9 - Peer: pod2-leaf3a'
+ routes:
+ - 10.255.200.9
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf9b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.11 - Peer: pod2-leaf4a'
+ routes:
+ - 10.255.200.11
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf9b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.13 - Peer: pod2-leaf5a'
+ routes:
+ - 10.255.200.13
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf9b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.15 - Peer: pod2-leaf6a'
+ routes:
+ - 10.255.200.15
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf9b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.17 - Peer: pod2-leaf7a'
+ routes:
+ - 10.255.200.17
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf9b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.19 - Peer: pod2-leaf8a'
+ routes:
+ - 10.255.200.19
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf9b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.21 - Peer: pod2-leaf9a'
+ routes:
+ - 10.255.200.21
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf9b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.23 - Peer: pod2-leaf10a'
+ routes:
+ - 10.255.200.23
+- VerifyRoutingProtocolModel:
+ filters:
+ tags:
+ - pod2-leaf3a
+ model: multi-agent
+ result_overwrite:
+ custom_field: 'Routing protocol model: multi-agent'
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf3a
+ result_overwrite:
+ custom_field: 'Route: 10.255.0.1 - Peer: super-spine1'
+ routes:
+ - 10.255.0.1
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf3a
+ result_overwrite:
+ custom_field: 'Route: 10.255.0.2 - Peer: super-spine2'
+ routes:
+ - 10.255.0.2
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf3a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.1 - Peer: pod1-spine1'
+ routes:
+ - 10.255.1.1
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf3a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.2 - Peer: pod1-spine2'
+ routes:
+ - 10.255.1.2
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf3a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.3 - Peer: pod1-spine3'
+ routes:
+ - 10.255.1.3
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf3a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.4 - Peer: pod1-spine4'
+ routes:
+ - 10.255.1.4
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf3a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.5 - Peer: pod1-leaf1a'
+ routes:
+ - 10.255.1.5
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf3a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.6 - Peer: pod1-leaf1b'
+ routes:
+ - 10.255.1.6
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf3a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.7 - Peer: pod1-leaf2a'
+ routes:
+ - 10.255.1.7
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf3a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.8 - Peer: pod1-leaf2b'
+ routes:
+ - 10.255.1.8
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf3a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.9 - Peer: pod1-leaf3a'
+ routes:
+ - 10.255.1.9
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf3a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.10 - Peer: pod1-leaf3b'
+ routes:
+ - 10.255.1.10
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf3a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.11 - Peer: pod1-leaf4a'
+ routes:
+ - 10.255.1.11
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf3a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.12 - Peer: pod1-leaf4b'
+ routes:
+ - 10.255.1.12
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf3a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.13 - Peer: pod1-leaf5a'
+ routes:
+ - 10.255.1.13
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf3a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.14 - Peer: pod1-leaf5b'
+ routes:
+ - 10.255.1.14
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf3a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.15 - Peer: pod1-leaf6a'
+ routes:
+ - 10.255.1.15
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf3a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.16 - Peer: pod1-leaf6b'
+ routes:
+ - 10.255.1.16
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf3a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.17 - Peer: pod1-leaf7a'
+ routes:
+ - 10.255.1.17
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf3a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.18 - Peer: pod1-leaf7b'
+ routes:
+ - 10.255.1.18
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf3a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.19 - Peer: pod1-leaf8a'
+ routes:
+ - 10.255.1.19
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf3a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.20 - Peer: pod1-leaf8b'
+ routes:
+ - 10.255.1.20
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf3a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.21 - Peer: pod1-leaf9a'
+ routes:
+ - 10.255.1.21
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf3a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.22 - Peer: pod1-leaf9b'
+ routes:
+ - 10.255.1.22
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf3a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.23 - Peer: pod1-leaf10a'
+ routes:
+ - 10.255.1.23
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf3a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.24 - Peer: pod1-leaf10b'
+ routes:
+ - 10.255.1.24
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf3a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.1 - Peer: pod2-spine1'
+ routes:
+ - 10.255.2.1
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf3a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.2 - Peer: pod2-spine2'
+ routes:
+ - 10.255.2.2
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf3a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.3 - Peer: pod2-spine3'
+ routes:
+ - 10.255.2.3
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf3a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.4 - Peer: pod2-spine4'
+ routes:
+ - 10.255.2.4
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf3a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.5 - Peer: pod2-leaf1a'
+ routes:
+ - 10.255.2.5
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf3a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.6 - Peer: pod2-leaf1b'
+ routes:
+ - 10.255.2.6
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf3a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.7 - Peer: pod2-leaf2a'
+ routes:
+ - 10.255.2.7
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf3a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.8 - Peer: pod2-leaf2b'
+ routes:
+ - 10.255.2.8
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf3a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.9 - Peer: pod2-leaf3a'
+ routes:
+ - 10.255.2.9
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf3a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.10 - Peer: pod2-leaf3b'
+ routes:
+ - 10.255.2.10
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf3a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.11 - Peer: pod2-leaf4a'
+ routes:
+ - 10.255.2.11
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf3a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.12 - Peer: pod2-leaf4b'
+ routes:
+ - 10.255.2.12
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf3a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.13 - Peer: pod2-leaf5a'
+ routes:
+ - 10.255.2.13
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf3a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.14 - Peer: pod2-leaf5b'
+ routes:
+ - 10.255.2.14
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf3a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.15 - Peer: pod2-leaf6a'
+ routes:
+ - 10.255.2.15
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf3a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.16 - Peer: pod2-leaf6b'
+ routes:
+ - 10.255.2.16
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf3a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.17 - Peer: pod2-leaf7a'
+ routes:
+ - 10.255.2.17
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf3a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.18 - Peer: pod2-leaf7b'
+ routes:
+ - 10.255.2.18
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf3a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.19 - Peer: pod2-leaf8a'
+ routes:
+ - 10.255.2.19
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf3a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.20 - Peer: pod2-leaf8b'
+ routes:
+ - 10.255.2.20
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf3a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.21 - Peer: pod2-leaf9a'
+ routes:
+ - 10.255.2.21
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf3a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.22 - Peer: pod2-leaf9b'
+ routes:
+ - 10.255.2.22
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf3a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.23 - Peer: pod2-leaf10a'
+ routes:
+ - 10.255.2.23
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf3a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.24 - Peer: pod2-leaf10b'
+ routes:
+ - 10.255.2.24
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf3a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.5 - Peer: pod1-leaf1a'
+ routes:
+ - 10.255.100.5
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf3a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.7 - Peer: pod1-leaf2a'
+ routes:
+ - 10.255.100.7
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf3a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.9 - Peer: pod1-leaf3a'
+ routes:
+ - 10.255.100.9
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf3a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.11 - Peer: pod1-leaf4a'
+ routes:
+ - 10.255.100.11
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf3a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.13 - Peer: pod1-leaf5a'
+ routes:
+ - 10.255.100.13
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf3a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.15 - Peer: pod1-leaf6a'
+ routes:
+ - 10.255.100.15
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf3a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.17 - Peer: pod1-leaf7a'
+ routes:
+ - 10.255.100.17
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf3a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.19 - Peer: pod1-leaf8a'
+ routes:
+ - 10.255.100.19
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf3a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.21 - Peer: pod1-leaf9a'
+ routes:
+ - 10.255.100.21
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf3a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.23 - Peer: pod1-leaf10a'
+ routes:
+ - 10.255.100.23
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf3a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.5 - Peer: pod2-leaf1a'
+ routes:
+ - 10.255.200.5
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf3a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.7 - Peer: pod2-leaf2a'
+ routes:
+ - 10.255.200.7
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf3a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.9 - Peer: pod2-leaf3a'
+ routes:
+ - 10.255.200.9
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf3a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.11 - Peer: pod2-leaf4a'
+ routes:
+ - 10.255.200.11
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf3a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.13 - Peer: pod2-leaf5a'
+ routes:
+ - 10.255.200.13
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf3a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.15 - Peer: pod2-leaf6a'
+ routes:
+ - 10.255.200.15
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf3a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.17 - Peer: pod2-leaf7a'
+ routes:
+ - 10.255.200.17
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf3a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.19 - Peer: pod2-leaf8a'
+ routes:
+ - 10.255.200.19
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf3a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.21 - Peer: pod2-leaf9a'
+ routes:
+ - 10.255.200.21
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf3a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.23 - Peer: pod2-leaf10a'
+ routes:
+ - 10.255.200.23
+- VerifyRoutingProtocolModel:
+ filters:
+ tags:
+ - pod1-spine2
+ model: multi-agent
+ result_overwrite:
+ custom_field: 'Routing protocol model: multi-agent'
+- VerifyRoutingProtocolModel:
+ filters:
+ tags:
+ - pod2-leaf4a
+ model: multi-agent
+ result_overwrite:
+ custom_field: 'Routing protocol model: multi-agent'
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf4a
+ result_overwrite:
+ custom_field: 'Route: 10.255.0.1 - Peer: super-spine1'
+ routes:
+ - 10.255.0.1
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf4a
+ result_overwrite:
+ custom_field: 'Route: 10.255.0.2 - Peer: super-spine2'
+ routes:
+ - 10.255.0.2
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf4a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.1 - Peer: pod1-spine1'
+ routes:
+ - 10.255.1.1
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf4a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.2 - Peer: pod1-spine2'
+ routes:
+ - 10.255.1.2
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf4a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.3 - Peer: pod1-spine3'
+ routes:
+ - 10.255.1.3
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf4a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.4 - Peer: pod1-spine4'
+ routes:
+ - 10.255.1.4
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf4a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.5 - Peer: pod1-leaf1a'
+ routes:
+ - 10.255.1.5
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf4a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.6 - Peer: pod1-leaf1b'
+ routes:
+ - 10.255.1.6
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf4a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.7 - Peer: pod1-leaf2a'
+ routes:
+ - 10.255.1.7
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf4a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.8 - Peer: pod1-leaf2b'
+ routes:
+ - 10.255.1.8
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf4a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.9 - Peer: pod1-leaf3a'
+ routes:
+ - 10.255.1.9
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf4a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.10 - Peer: pod1-leaf3b'
+ routes:
+ - 10.255.1.10
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf4a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.11 - Peer: pod1-leaf4a'
+ routes:
+ - 10.255.1.11
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf4a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.12 - Peer: pod1-leaf4b'
+ routes:
+ - 10.255.1.12
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf4a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.13 - Peer: pod1-leaf5a'
+ routes:
+ - 10.255.1.13
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf4a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.14 - Peer: pod1-leaf5b'
+ routes:
+ - 10.255.1.14
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf4a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.15 - Peer: pod1-leaf6a'
+ routes:
+ - 10.255.1.15
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf4a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.16 - Peer: pod1-leaf6b'
+ routes:
+ - 10.255.1.16
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf4a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.17 - Peer: pod1-leaf7a'
+ routes:
+ - 10.255.1.17
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf4a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.18 - Peer: pod1-leaf7b'
+ routes:
+ - 10.255.1.18
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf4a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.19 - Peer: pod1-leaf8a'
+ routes:
+ - 10.255.1.19
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf4a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.20 - Peer: pod1-leaf8b'
+ routes:
+ - 10.255.1.20
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf4a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.21 - Peer: pod1-leaf9a'
+ routes:
+ - 10.255.1.21
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf4a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.22 - Peer: pod1-leaf9b'
+ routes:
+ - 10.255.1.22
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf4a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.23 - Peer: pod1-leaf10a'
+ routes:
+ - 10.255.1.23
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf4a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.24 - Peer: pod1-leaf10b'
+ routes:
+ - 10.255.1.24
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf4a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.1 - Peer: pod2-spine1'
+ routes:
+ - 10.255.2.1
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf4a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.2 - Peer: pod2-spine2'
+ routes:
+ - 10.255.2.2
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf4a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.3 - Peer: pod2-spine3'
+ routes:
+ - 10.255.2.3
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf4a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.4 - Peer: pod2-spine4'
+ routes:
+ - 10.255.2.4
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf4a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.5 - Peer: pod2-leaf1a'
+ routes:
+ - 10.255.2.5
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf4a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.6 - Peer: pod2-leaf1b'
+ routes:
+ - 10.255.2.6
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf4a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.7 - Peer: pod2-leaf2a'
+ routes:
+ - 10.255.2.7
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf4a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.8 - Peer: pod2-leaf2b'
+ routes:
+ - 10.255.2.8
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf4a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.9 - Peer: pod2-leaf3a'
+ routes:
+ - 10.255.2.9
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf4a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.10 - Peer: pod2-leaf3b'
+ routes:
+ - 10.255.2.10
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf4a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.11 - Peer: pod2-leaf4a'
+ routes:
+ - 10.255.2.11
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf4a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.12 - Peer: pod2-leaf4b'
+ routes:
+ - 10.255.2.12
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf4a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.13 - Peer: pod2-leaf5a'
+ routes:
+ - 10.255.2.13
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf4a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.14 - Peer: pod2-leaf5b'
+ routes:
+ - 10.255.2.14
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf4a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.15 - Peer: pod2-leaf6a'
+ routes:
+ - 10.255.2.15
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf4a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.16 - Peer: pod2-leaf6b'
+ routes:
+ - 10.255.2.16
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf4a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.17 - Peer: pod2-leaf7a'
+ routes:
+ - 10.255.2.17
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf4a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.18 - Peer: pod2-leaf7b'
+ routes:
+ - 10.255.2.18
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf4a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.19 - Peer: pod2-leaf8a'
+ routes:
+ - 10.255.2.19
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf4a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.20 - Peer: pod2-leaf8b'
+ routes:
+ - 10.255.2.20
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf4a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.21 - Peer: pod2-leaf9a'
+ routes:
+ - 10.255.2.21
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf4a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.22 - Peer: pod2-leaf9b'
+ routes:
+ - 10.255.2.22
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf4a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.23 - Peer: pod2-leaf10a'
+ routes:
+ - 10.255.2.23
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf4a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.24 - Peer: pod2-leaf10b'
+ routes:
+ - 10.255.2.24
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf4a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.5 - Peer: pod1-leaf1a'
+ routes:
+ - 10.255.100.5
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf4a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.7 - Peer: pod1-leaf2a'
+ routes:
+ - 10.255.100.7
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf4a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.9 - Peer: pod1-leaf3a'
+ routes:
+ - 10.255.100.9
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf4a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.11 - Peer: pod1-leaf4a'
+ routes:
+ - 10.255.100.11
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf4a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.13 - Peer: pod1-leaf5a'
+ routes:
+ - 10.255.100.13
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf4a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.15 - Peer: pod1-leaf6a'
+ routes:
+ - 10.255.100.15
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf4a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.17 - Peer: pod1-leaf7a'
+ routes:
+ - 10.255.100.17
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf4a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.19 - Peer: pod1-leaf8a'
+ routes:
+ - 10.255.100.19
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf4a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.21 - Peer: pod1-leaf9a'
+ routes:
+ - 10.255.100.21
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf4a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.23 - Peer: pod1-leaf10a'
+ routes:
+ - 10.255.100.23
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf4a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.5 - Peer: pod2-leaf1a'
+ routes:
+ - 10.255.200.5
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf4a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.7 - Peer: pod2-leaf2a'
+ routes:
+ - 10.255.200.7
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf4a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.9 - Peer: pod2-leaf3a'
+ routes:
+ - 10.255.200.9
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf4a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.11 - Peer: pod2-leaf4a'
+ routes:
+ - 10.255.200.11
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf4a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.13 - Peer: pod2-leaf5a'
+ routes:
+ - 10.255.200.13
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf4a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.15 - Peer: pod2-leaf6a'
+ routes:
+ - 10.255.200.15
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf4a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.17 - Peer: pod2-leaf7a'
+ routes:
+ - 10.255.200.17
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf4a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.19 - Peer: pod2-leaf8a'
+ routes:
+ - 10.255.200.19
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf4a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.21 - Peer: pod2-leaf9a'
+ routes:
+ - 10.255.200.21
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf4a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.23 - Peer: pod2-leaf10a'
+ routes:
+ - 10.255.200.23
+- VerifyRoutingProtocolModel:
+ filters:
+ tags:
+ - pod1-leaf8b
+ model: multi-agent
+ result_overwrite:
+ custom_field: 'Routing protocol model: multi-agent'
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf8b
+ result_overwrite:
+ custom_field: 'Route: 10.255.0.1 - Peer: super-spine1'
+ routes:
+ - 10.255.0.1
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf8b
+ result_overwrite:
+ custom_field: 'Route: 10.255.0.2 - Peer: super-spine2'
+ routes:
+ - 10.255.0.2
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf8b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.1 - Peer: pod1-spine1'
+ routes:
+ - 10.255.1.1
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf8b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.2 - Peer: pod1-spine2'
+ routes:
+ - 10.255.1.2
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf8b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.3 - Peer: pod1-spine3'
+ routes:
+ - 10.255.1.3
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf8b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.4 - Peer: pod1-spine4'
+ routes:
+ - 10.255.1.4
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf8b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.5 - Peer: pod1-leaf1a'
+ routes:
+ - 10.255.1.5
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf8b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.6 - Peer: pod1-leaf1b'
+ routes:
+ - 10.255.1.6
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf8b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.7 - Peer: pod1-leaf2a'
+ routes:
+ - 10.255.1.7
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf8b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.8 - Peer: pod1-leaf2b'
+ routes:
+ - 10.255.1.8
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf8b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.9 - Peer: pod1-leaf3a'
+ routes:
+ - 10.255.1.9
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf8b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.10 - Peer: pod1-leaf3b'
+ routes:
+ - 10.255.1.10
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf8b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.11 - Peer: pod1-leaf4a'
+ routes:
+ - 10.255.1.11
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf8b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.12 - Peer: pod1-leaf4b'
+ routes:
+ - 10.255.1.12
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf8b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.13 - Peer: pod1-leaf5a'
+ routes:
+ - 10.255.1.13
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf8b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.14 - Peer: pod1-leaf5b'
+ routes:
+ - 10.255.1.14
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf8b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.15 - Peer: pod1-leaf6a'
+ routes:
+ - 10.255.1.15
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf8b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.16 - Peer: pod1-leaf6b'
+ routes:
+ - 10.255.1.16
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf8b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.17 - Peer: pod1-leaf7a'
+ routes:
+ - 10.255.1.17
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf8b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.18 - Peer: pod1-leaf7b'
+ routes:
+ - 10.255.1.18
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf8b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.19 - Peer: pod1-leaf8a'
+ routes:
+ - 10.255.1.19
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf8b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.20 - Peer: pod1-leaf8b'
+ routes:
+ - 10.255.1.20
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf8b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.21 - Peer: pod1-leaf9a'
+ routes:
+ - 10.255.1.21
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf8b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.22 - Peer: pod1-leaf9b'
+ routes:
+ - 10.255.1.22
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf8b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.23 - Peer: pod1-leaf10a'
+ routes:
+ - 10.255.1.23
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf8b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.24 - Peer: pod1-leaf10b'
+ routes:
+ - 10.255.1.24
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf8b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.1 - Peer: pod2-spine1'
+ routes:
+ - 10.255.2.1
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf8b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.2 - Peer: pod2-spine2'
+ routes:
+ - 10.255.2.2
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf8b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.3 - Peer: pod2-spine3'
+ routes:
+ - 10.255.2.3
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf8b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.4 - Peer: pod2-spine4'
+ routes:
+ - 10.255.2.4
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf8b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.5 - Peer: pod2-leaf1a'
+ routes:
+ - 10.255.2.5
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf8b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.6 - Peer: pod2-leaf1b'
+ routes:
+ - 10.255.2.6
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf8b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.7 - Peer: pod2-leaf2a'
+ routes:
+ - 10.255.2.7
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf8b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.8 - Peer: pod2-leaf2b'
+ routes:
+ - 10.255.2.8
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf8b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.9 - Peer: pod2-leaf3a'
+ routes:
+ - 10.255.2.9
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf8b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.10 - Peer: pod2-leaf3b'
+ routes:
+ - 10.255.2.10
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf8b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.11 - Peer: pod2-leaf4a'
+ routes:
+ - 10.255.2.11
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf8b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.12 - Peer: pod2-leaf4b'
+ routes:
+ - 10.255.2.12
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf8b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.13 - Peer: pod2-leaf5a'
+ routes:
+ - 10.255.2.13
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf8b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.14 - Peer: pod2-leaf5b'
+ routes:
+ - 10.255.2.14
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf8b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.15 - Peer: pod2-leaf6a'
+ routes:
+ - 10.255.2.15
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf8b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.16 - Peer: pod2-leaf6b'
+ routes:
+ - 10.255.2.16
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf8b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.17 - Peer: pod2-leaf7a'
+ routes:
+ - 10.255.2.17
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf8b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.18 - Peer: pod2-leaf7b'
+ routes:
+ - 10.255.2.18
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf8b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.19 - Peer: pod2-leaf8a'
+ routes:
+ - 10.255.2.19
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf8b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.20 - Peer: pod2-leaf8b'
+ routes:
+ - 10.255.2.20
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf8b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.21 - Peer: pod2-leaf9a'
+ routes:
+ - 10.255.2.21
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf8b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.22 - Peer: pod2-leaf9b'
+ routes:
+ - 10.255.2.22
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf8b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.23 - Peer: pod2-leaf10a'
+ routes:
+ - 10.255.2.23
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf8b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.24 - Peer: pod2-leaf10b'
+ routes:
+ - 10.255.2.24
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf8b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.5 - Peer: pod1-leaf1a'
+ routes:
+ - 10.255.100.5
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf8b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.7 - Peer: pod1-leaf2a'
+ routes:
+ - 10.255.100.7
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf8b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.9 - Peer: pod1-leaf3a'
+ routes:
+ - 10.255.100.9
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf8b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.11 - Peer: pod1-leaf4a'
+ routes:
+ - 10.255.100.11
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf8b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.13 - Peer: pod1-leaf5a'
+ routes:
+ - 10.255.100.13
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf8b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.15 - Peer: pod1-leaf6a'
+ routes:
+ - 10.255.100.15
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf8b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.17 - Peer: pod1-leaf7a'
+ routes:
+ - 10.255.100.17
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf8b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.19 - Peer: pod1-leaf8a'
+ routes:
+ - 10.255.100.19
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf8b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.21 - Peer: pod1-leaf9a'
+ routes:
+ - 10.255.100.21
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf8b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.23 - Peer: pod1-leaf10a'
+ routes:
+ - 10.255.100.23
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf8b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.5 - Peer: pod2-leaf1a'
+ routes:
+ - 10.255.200.5
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf8b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.7 - Peer: pod2-leaf2a'
+ routes:
+ - 10.255.200.7
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf8b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.9 - Peer: pod2-leaf3a'
+ routes:
+ - 10.255.200.9
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf8b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.11 - Peer: pod2-leaf4a'
+ routes:
+ - 10.255.200.11
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf8b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.13 - Peer: pod2-leaf5a'
+ routes:
+ - 10.255.200.13
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf8b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.15 - Peer: pod2-leaf6a'
+ routes:
+ - 10.255.200.15
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf8b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.17 - Peer: pod2-leaf7a'
+ routes:
+ - 10.255.200.17
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf8b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.19 - Peer: pod2-leaf8a'
+ routes:
+ - 10.255.200.19
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf8b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.21 - Peer: pod2-leaf9a'
+ routes:
+ - 10.255.200.21
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf8b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.23 - Peer: pod2-leaf10a'
+ routes:
+ - 10.255.200.23
+- VerifyRoutingProtocolModel:
+ filters:
+ tags:
+ - pod1-leaf2a
+ model: multi-agent
+ result_overwrite:
+ custom_field: 'Routing protocol model: multi-agent'
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf2a
+ result_overwrite:
+ custom_field: 'Route: 10.255.0.1 - Peer: super-spine1'
+ routes:
+ - 10.255.0.1
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf2a
+ result_overwrite:
+ custom_field: 'Route: 10.255.0.2 - Peer: super-spine2'
+ routes:
+ - 10.255.0.2
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf2a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.1 - Peer: pod1-spine1'
+ routes:
+ - 10.255.1.1
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf2a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.2 - Peer: pod1-spine2'
+ routes:
+ - 10.255.1.2
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf2a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.3 - Peer: pod1-spine3'
+ routes:
+ - 10.255.1.3
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf2a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.4 - Peer: pod1-spine4'
+ routes:
+ - 10.255.1.4
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf2a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.5 - Peer: pod1-leaf1a'
+ routes:
+ - 10.255.1.5
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf2a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.6 - Peer: pod1-leaf1b'
+ routes:
+ - 10.255.1.6
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf2a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.7 - Peer: pod1-leaf2a'
+ routes:
+ - 10.255.1.7
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf2a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.8 - Peer: pod1-leaf2b'
+ routes:
+ - 10.255.1.8
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf2a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.9 - Peer: pod1-leaf3a'
+ routes:
+ - 10.255.1.9
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf2a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.10 - Peer: pod1-leaf3b'
+ routes:
+ - 10.255.1.10
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf2a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.11 - Peer: pod1-leaf4a'
+ routes:
+ - 10.255.1.11
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf2a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.12 - Peer: pod1-leaf4b'
+ routes:
+ - 10.255.1.12
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf2a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.13 - Peer: pod1-leaf5a'
+ routes:
+ - 10.255.1.13
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf2a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.14 - Peer: pod1-leaf5b'
+ routes:
+ - 10.255.1.14
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf2a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.15 - Peer: pod1-leaf6a'
+ routes:
+ - 10.255.1.15
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf2a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.16 - Peer: pod1-leaf6b'
+ routes:
+ - 10.255.1.16
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf2a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.17 - Peer: pod1-leaf7a'
+ routes:
+ - 10.255.1.17
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf2a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.18 - Peer: pod1-leaf7b'
+ routes:
+ - 10.255.1.18
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf2a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.19 - Peer: pod1-leaf8a'
+ routes:
+ - 10.255.1.19
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf2a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.20 - Peer: pod1-leaf8b'
+ routes:
+ - 10.255.1.20
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf2a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.21 - Peer: pod1-leaf9a'
+ routes:
+ - 10.255.1.21
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf2a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.22 - Peer: pod1-leaf9b'
+ routes:
+ - 10.255.1.22
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf2a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.23 - Peer: pod1-leaf10a'
+ routes:
+ - 10.255.1.23
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf2a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.24 - Peer: pod1-leaf10b'
+ routes:
+ - 10.255.1.24
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf2a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.1 - Peer: pod2-spine1'
+ routes:
+ - 10.255.2.1
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf2a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.2 - Peer: pod2-spine2'
+ routes:
+ - 10.255.2.2
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf2a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.3 - Peer: pod2-spine3'
+ routes:
+ - 10.255.2.3
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf2a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.4 - Peer: pod2-spine4'
+ routes:
+ - 10.255.2.4
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf2a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.5 - Peer: pod2-leaf1a'
+ routes:
+ - 10.255.2.5
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf2a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.6 - Peer: pod2-leaf1b'
+ routes:
+ - 10.255.2.6
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf2a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.7 - Peer: pod2-leaf2a'
+ routes:
+ - 10.255.2.7
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf2a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.8 - Peer: pod2-leaf2b'
+ routes:
+ - 10.255.2.8
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf2a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.9 - Peer: pod2-leaf3a'
+ routes:
+ - 10.255.2.9
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf2a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.10 - Peer: pod2-leaf3b'
+ routes:
+ - 10.255.2.10
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf2a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.11 - Peer: pod2-leaf4a'
+ routes:
+ - 10.255.2.11
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf2a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.12 - Peer: pod2-leaf4b'
+ routes:
+ - 10.255.2.12
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf2a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.13 - Peer: pod2-leaf5a'
+ routes:
+ - 10.255.2.13
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf2a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.14 - Peer: pod2-leaf5b'
+ routes:
+ - 10.255.2.14
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf2a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.15 - Peer: pod2-leaf6a'
+ routes:
+ - 10.255.2.15
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf2a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.16 - Peer: pod2-leaf6b'
+ routes:
+ - 10.255.2.16
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf2a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.17 - Peer: pod2-leaf7a'
+ routes:
+ - 10.255.2.17
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf2a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.18 - Peer: pod2-leaf7b'
+ routes:
+ - 10.255.2.18
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf2a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.19 - Peer: pod2-leaf8a'
+ routes:
+ - 10.255.2.19
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf2a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.20 - Peer: pod2-leaf8b'
+ routes:
+ - 10.255.2.20
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf2a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.21 - Peer: pod2-leaf9a'
+ routes:
+ - 10.255.2.21
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf2a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.22 - Peer: pod2-leaf9b'
+ routes:
+ - 10.255.2.22
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf2a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.23 - Peer: pod2-leaf10a'
+ routes:
+ - 10.255.2.23
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf2a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.24 - Peer: pod2-leaf10b'
+ routes:
+ - 10.255.2.24
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf2a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.5 - Peer: pod1-leaf1a'
+ routes:
+ - 10.255.100.5
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf2a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.7 - Peer: pod1-leaf2a'
+ routes:
+ - 10.255.100.7
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf2a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.9 - Peer: pod1-leaf3a'
+ routes:
+ - 10.255.100.9
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf2a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.11 - Peer: pod1-leaf4a'
+ routes:
+ - 10.255.100.11
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf2a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.13 - Peer: pod1-leaf5a'
+ routes:
+ - 10.255.100.13
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf2a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.15 - Peer: pod1-leaf6a'
+ routes:
+ - 10.255.100.15
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf2a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.17 - Peer: pod1-leaf7a'
+ routes:
+ - 10.255.100.17
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf2a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.19 - Peer: pod1-leaf8a'
+ routes:
+ - 10.255.100.19
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf2a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.21 - Peer: pod1-leaf9a'
+ routes:
+ - 10.255.100.21
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf2a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.23 - Peer: pod1-leaf10a'
+ routes:
+ - 10.255.100.23
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf2a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.5 - Peer: pod2-leaf1a'
+ routes:
+ - 10.255.200.5
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf2a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.7 - Peer: pod2-leaf2a'
+ routes:
+ - 10.255.200.7
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf2a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.9 - Peer: pod2-leaf3a'
+ routes:
+ - 10.255.200.9
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf2a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.11 - Peer: pod2-leaf4a'
+ routes:
+ - 10.255.200.11
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf2a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.13 - Peer: pod2-leaf5a'
+ routes:
+ - 10.255.200.13
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf2a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.15 - Peer: pod2-leaf6a'
+ routes:
+ - 10.255.200.15
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf2a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.17 - Peer: pod2-leaf7a'
+ routes:
+ - 10.255.200.17
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf2a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.19 - Peer: pod2-leaf8a'
+ routes:
+ - 10.255.200.19
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf2a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.21 - Peer: pod2-leaf9a'
+ routes:
+ - 10.255.200.21
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf2a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.23 - Peer: pod2-leaf10a'
+ routes:
+ - 10.255.200.23
+- VerifyRoutingProtocolModel:
+ filters:
+ tags:
+ - pod1-leaf5a
+ model: multi-agent
+ result_overwrite:
+ custom_field: 'Routing protocol model: multi-agent'
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf5a
+ result_overwrite:
+ custom_field: 'Route: 10.255.0.1 - Peer: super-spine1'
+ routes:
+ - 10.255.0.1
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf5a
+ result_overwrite:
+ custom_field: 'Route: 10.255.0.2 - Peer: super-spine2'
+ routes:
+ - 10.255.0.2
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf5a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.1 - Peer: pod1-spine1'
+ routes:
+ - 10.255.1.1
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf5a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.2 - Peer: pod1-spine2'
+ routes:
+ - 10.255.1.2
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf5a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.3 - Peer: pod1-spine3'
+ routes:
+ - 10.255.1.3
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf5a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.4 - Peer: pod1-spine4'
+ routes:
+ - 10.255.1.4
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf5a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.5 - Peer: pod1-leaf1a'
+ routes:
+ - 10.255.1.5
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf5a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.6 - Peer: pod1-leaf1b'
+ routes:
+ - 10.255.1.6
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf5a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.7 - Peer: pod1-leaf2a'
+ routes:
+ - 10.255.1.7
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf5a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.8 - Peer: pod1-leaf2b'
+ routes:
+ - 10.255.1.8
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf5a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.9 - Peer: pod1-leaf3a'
+ routes:
+ - 10.255.1.9
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf5a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.10 - Peer: pod1-leaf3b'
+ routes:
+ - 10.255.1.10
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf5a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.11 - Peer: pod1-leaf4a'
+ routes:
+ - 10.255.1.11
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf5a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.12 - Peer: pod1-leaf4b'
+ routes:
+ - 10.255.1.12
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf5a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.13 - Peer: pod1-leaf5a'
+ routes:
+ - 10.255.1.13
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf5a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.14 - Peer: pod1-leaf5b'
+ routes:
+ - 10.255.1.14
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf5a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.15 - Peer: pod1-leaf6a'
+ routes:
+ - 10.255.1.15
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf5a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.16 - Peer: pod1-leaf6b'
+ routes:
+ - 10.255.1.16
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf5a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.17 - Peer: pod1-leaf7a'
+ routes:
+ - 10.255.1.17
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf5a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.18 - Peer: pod1-leaf7b'
+ routes:
+ - 10.255.1.18
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf5a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.19 - Peer: pod1-leaf8a'
+ routes:
+ - 10.255.1.19
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf5a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.20 - Peer: pod1-leaf8b'
+ routes:
+ - 10.255.1.20
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf5a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.21 - Peer: pod1-leaf9a'
+ routes:
+ - 10.255.1.21
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf5a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.22 - Peer: pod1-leaf9b'
+ routes:
+ - 10.255.1.22
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf5a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.23 - Peer: pod1-leaf10a'
+ routes:
+ - 10.255.1.23
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf5a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.24 - Peer: pod1-leaf10b'
+ routes:
+ - 10.255.1.24
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf5a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.1 - Peer: pod2-spine1'
+ routes:
+ - 10.255.2.1
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf5a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.2 - Peer: pod2-spine2'
+ routes:
+ - 10.255.2.2
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf5a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.3 - Peer: pod2-spine3'
+ routes:
+ - 10.255.2.3
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf5a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.4 - Peer: pod2-spine4'
+ routes:
+ - 10.255.2.4
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf5a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.5 - Peer: pod2-leaf1a'
+ routes:
+ - 10.255.2.5
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf5a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.6 - Peer: pod2-leaf1b'
+ routes:
+ - 10.255.2.6
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf5a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.7 - Peer: pod2-leaf2a'
+ routes:
+ - 10.255.2.7
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf5a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.8 - Peer: pod2-leaf2b'
+ routes:
+ - 10.255.2.8
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf5a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.9 - Peer: pod2-leaf3a'
+ routes:
+ - 10.255.2.9
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf5a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.10 - Peer: pod2-leaf3b'
+ routes:
+ - 10.255.2.10
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf5a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.11 - Peer: pod2-leaf4a'
+ routes:
+ - 10.255.2.11
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf5a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.12 - Peer: pod2-leaf4b'
+ routes:
+ - 10.255.2.12
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf5a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.13 - Peer: pod2-leaf5a'
+ routes:
+ - 10.255.2.13
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf5a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.14 - Peer: pod2-leaf5b'
+ routes:
+ - 10.255.2.14
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf5a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.15 - Peer: pod2-leaf6a'
+ routes:
+ - 10.255.2.15
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf5a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.16 - Peer: pod2-leaf6b'
+ routes:
+ - 10.255.2.16
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf5a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.17 - Peer: pod2-leaf7a'
+ routes:
+ - 10.255.2.17
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf5a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.18 - Peer: pod2-leaf7b'
+ routes:
+ - 10.255.2.18
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf5a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.19 - Peer: pod2-leaf8a'
+ routes:
+ - 10.255.2.19
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf5a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.20 - Peer: pod2-leaf8b'
+ routes:
+ - 10.255.2.20
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf5a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.21 - Peer: pod2-leaf9a'
+ routes:
+ - 10.255.2.21
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf5a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.22 - Peer: pod2-leaf9b'
+ routes:
+ - 10.255.2.22
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf5a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.23 - Peer: pod2-leaf10a'
+ routes:
+ - 10.255.2.23
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf5a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.24 - Peer: pod2-leaf10b'
+ routes:
+ - 10.255.2.24
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf5a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.5 - Peer: pod1-leaf1a'
+ routes:
+ - 10.255.100.5
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf5a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.7 - Peer: pod1-leaf2a'
+ routes:
+ - 10.255.100.7
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf5a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.9 - Peer: pod1-leaf3a'
+ routes:
+ - 10.255.100.9
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf5a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.11 - Peer: pod1-leaf4a'
+ routes:
+ - 10.255.100.11
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf5a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.13 - Peer: pod1-leaf5a'
+ routes:
+ - 10.255.100.13
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf5a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.15 - Peer: pod1-leaf6a'
+ routes:
+ - 10.255.100.15
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf5a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.17 - Peer: pod1-leaf7a'
+ routes:
+ - 10.255.100.17
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf5a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.19 - Peer: pod1-leaf8a'
+ routes:
+ - 10.255.100.19
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf5a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.21 - Peer: pod1-leaf9a'
+ routes:
+ - 10.255.100.21
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf5a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.23 - Peer: pod1-leaf10a'
+ routes:
+ - 10.255.100.23
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf5a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.5 - Peer: pod2-leaf1a'
+ routes:
+ - 10.255.200.5
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf5a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.7 - Peer: pod2-leaf2a'
+ routes:
+ - 10.255.200.7
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf5a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.9 - Peer: pod2-leaf3a'
+ routes:
+ - 10.255.200.9
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf5a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.11 - Peer: pod2-leaf4a'
+ routes:
+ - 10.255.200.11
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf5a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.13 - Peer: pod2-leaf5a'
+ routes:
+ - 10.255.200.13
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf5a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.15 - Peer: pod2-leaf6a'
+ routes:
+ - 10.255.200.15
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf5a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.17 - Peer: pod2-leaf7a'
+ routes:
+ - 10.255.200.17
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf5a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.19 - Peer: pod2-leaf8a'
+ routes:
+ - 10.255.200.19
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf5a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.21 - Peer: pod2-leaf9a'
+ routes:
+ - 10.255.200.21
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf5a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.23 - Peer: pod2-leaf10a'
+ routes:
+ - 10.255.200.23
+- VerifyRoutingProtocolModel:
+ filters:
+ tags:
+ - pod2-leaf8b
+ model: multi-agent
+ result_overwrite:
+ custom_field: 'Routing protocol model: multi-agent'
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf8b
+ result_overwrite:
+ custom_field: 'Route: 10.255.0.1 - Peer: super-spine1'
+ routes:
+ - 10.255.0.1
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf8b
+ result_overwrite:
+ custom_field: 'Route: 10.255.0.2 - Peer: super-spine2'
+ routes:
+ - 10.255.0.2
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf8b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.1 - Peer: pod1-spine1'
+ routes:
+ - 10.255.1.1
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf8b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.2 - Peer: pod1-spine2'
+ routes:
+ - 10.255.1.2
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf8b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.3 - Peer: pod1-spine3'
+ routes:
+ - 10.255.1.3
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf8b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.4 - Peer: pod1-spine4'
+ routes:
+ - 10.255.1.4
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf8b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.5 - Peer: pod1-leaf1a'
+ routes:
+ - 10.255.1.5
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf8b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.6 - Peer: pod1-leaf1b'
+ routes:
+ - 10.255.1.6
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf8b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.7 - Peer: pod1-leaf2a'
+ routes:
+ - 10.255.1.7
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf8b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.8 - Peer: pod1-leaf2b'
+ routes:
+ - 10.255.1.8
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf8b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.9 - Peer: pod1-leaf3a'
+ routes:
+ - 10.255.1.9
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf8b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.10 - Peer: pod1-leaf3b'
+ routes:
+ - 10.255.1.10
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf8b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.11 - Peer: pod1-leaf4a'
+ routes:
+ - 10.255.1.11
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf8b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.12 - Peer: pod1-leaf4b'
+ routes:
+ - 10.255.1.12
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf8b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.13 - Peer: pod1-leaf5a'
+ routes:
+ - 10.255.1.13
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf8b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.14 - Peer: pod1-leaf5b'
+ routes:
+ - 10.255.1.14
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf8b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.15 - Peer: pod1-leaf6a'
+ routes:
+ - 10.255.1.15
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf8b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.16 - Peer: pod1-leaf6b'
+ routes:
+ - 10.255.1.16
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf8b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.17 - Peer: pod1-leaf7a'
+ routes:
+ - 10.255.1.17
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf8b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.18 - Peer: pod1-leaf7b'
+ routes:
+ - 10.255.1.18
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf8b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.19 - Peer: pod1-leaf8a'
+ routes:
+ - 10.255.1.19
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf8b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.20 - Peer: pod1-leaf8b'
+ routes:
+ - 10.255.1.20
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf8b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.21 - Peer: pod1-leaf9a'
+ routes:
+ - 10.255.1.21
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf8b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.22 - Peer: pod1-leaf9b'
+ routes:
+ - 10.255.1.22
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf8b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.23 - Peer: pod1-leaf10a'
+ routes:
+ - 10.255.1.23
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf8b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.24 - Peer: pod1-leaf10b'
+ routes:
+ - 10.255.1.24
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf8b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.1 - Peer: pod2-spine1'
+ routes:
+ - 10.255.2.1
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf8b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.2 - Peer: pod2-spine2'
+ routes:
+ - 10.255.2.2
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf8b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.3 - Peer: pod2-spine3'
+ routes:
+ - 10.255.2.3
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf8b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.4 - Peer: pod2-spine4'
+ routes:
+ - 10.255.2.4
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf8b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.5 - Peer: pod2-leaf1a'
+ routes:
+ - 10.255.2.5
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf8b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.6 - Peer: pod2-leaf1b'
+ routes:
+ - 10.255.2.6
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf8b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.7 - Peer: pod2-leaf2a'
+ routes:
+ - 10.255.2.7
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf8b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.8 - Peer: pod2-leaf2b'
+ routes:
+ - 10.255.2.8
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf8b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.9 - Peer: pod2-leaf3a'
+ routes:
+ - 10.255.2.9
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf8b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.10 - Peer: pod2-leaf3b'
+ routes:
+ - 10.255.2.10
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf8b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.11 - Peer: pod2-leaf4a'
+ routes:
+ - 10.255.2.11
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf8b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.12 - Peer: pod2-leaf4b'
+ routes:
+ - 10.255.2.12
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf8b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.13 - Peer: pod2-leaf5a'
+ routes:
+ - 10.255.2.13
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf8b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.14 - Peer: pod2-leaf5b'
+ routes:
+ - 10.255.2.14
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf8b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.15 - Peer: pod2-leaf6a'
+ routes:
+ - 10.255.2.15
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf8b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.16 - Peer: pod2-leaf6b'
+ routes:
+ - 10.255.2.16
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf8b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.17 - Peer: pod2-leaf7a'
+ routes:
+ - 10.255.2.17
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf8b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.18 - Peer: pod2-leaf7b'
+ routes:
+ - 10.255.2.18
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf8b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.19 - Peer: pod2-leaf8a'
+ routes:
+ - 10.255.2.19
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf8b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.20 - Peer: pod2-leaf8b'
+ routes:
+ - 10.255.2.20
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf8b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.21 - Peer: pod2-leaf9a'
+ routes:
+ - 10.255.2.21
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf8b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.22 - Peer: pod2-leaf9b'
+ routes:
+ - 10.255.2.22
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf8b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.23 - Peer: pod2-leaf10a'
+ routes:
+ - 10.255.2.23
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf8b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.24 - Peer: pod2-leaf10b'
+ routes:
+ - 10.255.2.24
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf8b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.5 - Peer: pod1-leaf1a'
+ routes:
+ - 10.255.100.5
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf8b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.7 - Peer: pod1-leaf2a'
+ routes:
+ - 10.255.100.7
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf8b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.9 - Peer: pod1-leaf3a'
+ routes:
+ - 10.255.100.9
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf8b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.11 - Peer: pod1-leaf4a'
+ routes:
+ - 10.255.100.11
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf8b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.13 - Peer: pod1-leaf5a'
+ routes:
+ - 10.255.100.13
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf8b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.15 - Peer: pod1-leaf6a'
+ routes:
+ - 10.255.100.15
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf8b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.17 - Peer: pod1-leaf7a'
+ routes:
+ - 10.255.100.17
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf8b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.19 - Peer: pod1-leaf8a'
+ routes:
+ - 10.255.100.19
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf8b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.21 - Peer: pod1-leaf9a'
+ routes:
+ - 10.255.100.21
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf8b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.23 - Peer: pod1-leaf10a'
+ routes:
+ - 10.255.100.23
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf8b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.5 - Peer: pod2-leaf1a'
+ routes:
+ - 10.255.200.5
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf8b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.7 - Peer: pod2-leaf2a'
+ routes:
+ - 10.255.200.7
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf8b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.9 - Peer: pod2-leaf3a'
+ routes:
+ - 10.255.200.9
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf8b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.11 - Peer: pod2-leaf4a'
+ routes:
+ - 10.255.200.11
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf8b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.13 - Peer: pod2-leaf5a'
+ routes:
+ - 10.255.200.13
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf8b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.15 - Peer: pod2-leaf6a'
+ routes:
+ - 10.255.200.15
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf8b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.17 - Peer: pod2-leaf7a'
+ routes:
+ - 10.255.200.17
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf8b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.19 - Peer: pod2-leaf8a'
+ routes:
+ - 10.255.200.19
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf8b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.21 - Peer: pod2-leaf9a'
+ routes:
+ - 10.255.200.21
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf8b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.23 - Peer: pod2-leaf10a'
+ routes:
+ - 10.255.200.23
+- VerifyRoutingProtocolModel:
+ filters:
+ tags:
+ - pod2-leaf5a
+ model: multi-agent
+ result_overwrite:
+ custom_field: 'Routing protocol model: multi-agent'
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf5a
+ result_overwrite:
+ custom_field: 'Route: 10.255.0.1 - Peer: super-spine1'
+ routes:
+ - 10.255.0.1
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf5a
+ result_overwrite:
+ custom_field: 'Route: 10.255.0.2 - Peer: super-spine2'
+ routes:
+ - 10.255.0.2
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf5a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.1 - Peer: pod1-spine1'
+ routes:
+ - 10.255.1.1
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf5a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.2 - Peer: pod1-spine2'
+ routes:
+ - 10.255.1.2
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf5a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.3 - Peer: pod1-spine3'
+ routes:
+ - 10.255.1.3
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf5a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.4 - Peer: pod1-spine4'
+ routes:
+ - 10.255.1.4
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf5a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.5 - Peer: pod1-leaf1a'
+ routes:
+ - 10.255.1.5
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf5a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.6 - Peer: pod1-leaf1b'
+ routes:
+ - 10.255.1.6
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf5a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.7 - Peer: pod1-leaf2a'
+ routes:
+ - 10.255.1.7
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf5a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.8 - Peer: pod1-leaf2b'
+ routes:
+ - 10.255.1.8
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf5a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.9 - Peer: pod1-leaf3a'
+ routes:
+ - 10.255.1.9
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf5a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.10 - Peer: pod1-leaf3b'
+ routes:
+ - 10.255.1.10
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf5a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.11 - Peer: pod1-leaf4a'
+ routes:
+ - 10.255.1.11
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf5a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.12 - Peer: pod1-leaf4b'
+ routes:
+ - 10.255.1.12
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf5a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.13 - Peer: pod1-leaf5a'
+ routes:
+ - 10.255.1.13
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf5a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.14 - Peer: pod1-leaf5b'
+ routes:
+ - 10.255.1.14
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf5a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.15 - Peer: pod1-leaf6a'
+ routes:
+ - 10.255.1.15
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf5a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.16 - Peer: pod1-leaf6b'
+ routes:
+ - 10.255.1.16
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf5a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.17 - Peer: pod1-leaf7a'
+ routes:
+ - 10.255.1.17
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf5a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.18 - Peer: pod1-leaf7b'
+ routes:
+ - 10.255.1.18
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf5a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.19 - Peer: pod1-leaf8a'
+ routes:
+ - 10.255.1.19
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf5a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.20 - Peer: pod1-leaf8b'
+ routes:
+ - 10.255.1.20
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf5a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.21 - Peer: pod1-leaf9a'
+ routes:
+ - 10.255.1.21
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf5a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.22 - Peer: pod1-leaf9b'
+ routes:
+ - 10.255.1.22
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf5a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.23 - Peer: pod1-leaf10a'
+ routes:
+ - 10.255.1.23
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf5a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.24 - Peer: pod1-leaf10b'
+ routes:
+ - 10.255.1.24
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf5a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.1 - Peer: pod2-spine1'
+ routes:
+ - 10.255.2.1
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf5a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.2 - Peer: pod2-spine2'
+ routes:
+ - 10.255.2.2
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf5a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.3 - Peer: pod2-spine3'
+ routes:
+ - 10.255.2.3
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf5a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.4 - Peer: pod2-spine4'
+ routes:
+ - 10.255.2.4
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf5a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.5 - Peer: pod2-leaf1a'
+ routes:
+ - 10.255.2.5
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf5a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.6 - Peer: pod2-leaf1b'
+ routes:
+ - 10.255.2.6
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf5a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.7 - Peer: pod2-leaf2a'
+ routes:
+ - 10.255.2.7
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf5a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.8 - Peer: pod2-leaf2b'
+ routes:
+ - 10.255.2.8
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf5a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.9 - Peer: pod2-leaf3a'
+ routes:
+ - 10.255.2.9
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf5a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.10 - Peer: pod2-leaf3b'
+ routes:
+ - 10.255.2.10
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf5a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.11 - Peer: pod2-leaf4a'
+ routes:
+ - 10.255.2.11
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf5a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.12 - Peer: pod2-leaf4b'
+ routes:
+ - 10.255.2.12
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf5a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.13 - Peer: pod2-leaf5a'
+ routes:
+ - 10.255.2.13
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf5a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.14 - Peer: pod2-leaf5b'
+ routes:
+ - 10.255.2.14
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf5a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.15 - Peer: pod2-leaf6a'
+ routes:
+ - 10.255.2.15
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf5a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.16 - Peer: pod2-leaf6b'
+ routes:
+ - 10.255.2.16
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf5a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.17 - Peer: pod2-leaf7a'
+ routes:
+ - 10.255.2.17
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf5a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.18 - Peer: pod2-leaf7b'
+ routes:
+ - 10.255.2.18
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf5a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.19 - Peer: pod2-leaf8a'
+ routes:
+ - 10.255.2.19
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf5a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.20 - Peer: pod2-leaf8b'
+ routes:
+ - 10.255.2.20
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf5a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.21 - Peer: pod2-leaf9a'
+ routes:
+ - 10.255.2.21
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf5a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.22 - Peer: pod2-leaf9b'
+ routes:
+ - 10.255.2.22
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf5a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.23 - Peer: pod2-leaf10a'
+ routes:
+ - 10.255.2.23
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf5a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.24 - Peer: pod2-leaf10b'
+ routes:
+ - 10.255.2.24
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf5a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.5 - Peer: pod1-leaf1a'
+ routes:
+ - 10.255.100.5
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf5a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.7 - Peer: pod1-leaf2a'
+ routes:
+ - 10.255.100.7
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf5a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.9 - Peer: pod1-leaf3a'
+ routes:
+ - 10.255.100.9
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf5a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.11 - Peer: pod1-leaf4a'
+ routes:
+ - 10.255.100.11
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf5a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.13 - Peer: pod1-leaf5a'
+ routes:
+ - 10.255.100.13
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf5a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.15 - Peer: pod1-leaf6a'
+ routes:
+ - 10.255.100.15
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf5a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.17 - Peer: pod1-leaf7a'
+ routes:
+ - 10.255.100.17
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf5a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.19 - Peer: pod1-leaf8a'
+ routes:
+ - 10.255.100.19
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf5a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.21 - Peer: pod1-leaf9a'
+ routes:
+ - 10.255.100.21
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf5a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.23 - Peer: pod1-leaf10a'
+ routes:
+ - 10.255.100.23
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf5a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.5 - Peer: pod2-leaf1a'
+ routes:
+ - 10.255.200.5
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf5a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.7 - Peer: pod2-leaf2a'
+ routes:
+ - 10.255.200.7
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf5a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.9 - Peer: pod2-leaf3a'
+ routes:
+ - 10.255.200.9
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf5a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.11 - Peer: pod2-leaf4a'
+ routes:
+ - 10.255.200.11
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf5a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.13 - Peer: pod2-leaf5a'
+ routes:
+ - 10.255.200.13
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf5a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.15 - Peer: pod2-leaf6a'
+ routes:
+ - 10.255.200.15
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf5a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.17 - Peer: pod2-leaf7a'
+ routes:
+ - 10.255.200.17
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf5a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.19 - Peer: pod2-leaf8a'
+ routes:
+ - 10.255.200.19
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf5a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.21 - Peer: pod2-leaf9a'
+ routes:
+ - 10.255.200.21
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf5a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.23 - Peer: pod2-leaf10a'
+ routes:
+ - 10.255.200.23
+- VerifyRoutingProtocolModel:
+ filters:
+ tags:
+ - pod2-leaf2a
+ model: multi-agent
+ result_overwrite:
+ custom_field: 'Routing protocol model: multi-agent'
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf2a
+ result_overwrite:
+ custom_field: 'Route: 10.255.0.1 - Peer: super-spine1'
+ routes:
+ - 10.255.0.1
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf2a
+ result_overwrite:
+ custom_field: 'Route: 10.255.0.2 - Peer: super-spine2'
+ routes:
+ - 10.255.0.2
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf2a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.1 - Peer: pod1-spine1'
+ routes:
+ - 10.255.1.1
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf2a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.2 - Peer: pod1-spine2'
+ routes:
+ - 10.255.1.2
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf2a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.3 - Peer: pod1-spine3'
+ routes:
+ - 10.255.1.3
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf2a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.4 - Peer: pod1-spine4'
+ routes:
+ - 10.255.1.4
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf2a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.5 - Peer: pod1-leaf1a'
+ routes:
+ - 10.255.1.5
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf2a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.6 - Peer: pod1-leaf1b'
+ routes:
+ - 10.255.1.6
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf2a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.7 - Peer: pod1-leaf2a'
+ routes:
+ - 10.255.1.7
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf2a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.8 - Peer: pod1-leaf2b'
+ routes:
+ - 10.255.1.8
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf2a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.9 - Peer: pod1-leaf3a'
+ routes:
+ - 10.255.1.9
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf2a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.10 - Peer: pod1-leaf3b'
+ routes:
+ - 10.255.1.10
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf2a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.11 - Peer: pod1-leaf4a'
+ routes:
+ - 10.255.1.11
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf2a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.12 - Peer: pod1-leaf4b'
+ routes:
+ - 10.255.1.12
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf2a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.13 - Peer: pod1-leaf5a'
+ routes:
+ - 10.255.1.13
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf2a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.14 - Peer: pod1-leaf5b'
+ routes:
+ - 10.255.1.14
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf2a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.15 - Peer: pod1-leaf6a'
+ routes:
+ - 10.255.1.15
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf2a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.16 - Peer: pod1-leaf6b'
+ routes:
+ - 10.255.1.16
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf2a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.17 - Peer: pod1-leaf7a'
+ routes:
+ - 10.255.1.17
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf2a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.18 - Peer: pod1-leaf7b'
+ routes:
+ - 10.255.1.18
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf2a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.19 - Peer: pod1-leaf8a'
+ routes:
+ - 10.255.1.19
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf2a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.20 - Peer: pod1-leaf8b'
+ routes:
+ - 10.255.1.20
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf2a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.21 - Peer: pod1-leaf9a'
+ routes:
+ - 10.255.1.21
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf2a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.22 - Peer: pod1-leaf9b'
+ routes:
+ - 10.255.1.22
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf2a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.23 - Peer: pod1-leaf10a'
+ routes:
+ - 10.255.1.23
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf2a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.24 - Peer: pod1-leaf10b'
+ routes:
+ - 10.255.1.24
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf2a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.1 - Peer: pod2-spine1'
+ routes:
+ - 10.255.2.1
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf2a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.2 - Peer: pod2-spine2'
+ routes:
+ - 10.255.2.2
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf2a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.3 - Peer: pod2-spine3'
+ routes:
+ - 10.255.2.3
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf2a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.4 - Peer: pod2-spine4'
+ routes:
+ - 10.255.2.4
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf2a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.5 - Peer: pod2-leaf1a'
+ routes:
+ - 10.255.2.5
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf2a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.6 - Peer: pod2-leaf1b'
+ routes:
+ - 10.255.2.6
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf2a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.7 - Peer: pod2-leaf2a'
+ routes:
+ - 10.255.2.7
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf2a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.8 - Peer: pod2-leaf2b'
+ routes:
+ - 10.255.2.8
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf2a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.9 - Peer: pod2-leaf3a'
+ routes:
+ - 10.255.2.9
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf2a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.10 - Peer: pod2-leaf3b'
+ routes:
+ - 10.255.2.10
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf2a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.11 - Peer: pod2-leaf4a'
+ routes:
+ - 10.255.2.11
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf2a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.12 - Peer: pod2-leaf4b'
+ routes:
+ - 10.255.2.12
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf2a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.13 - Peer: pod2-leaf5a'
+ routes:
+ - 10.255.2.13
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf2a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.14 - Peer: pod2-leaf5b'
+ routes:
+ - 10.255.2.14
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf2a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.15 - Peer: pod2-leaf6a'
+ routes:
+ - 10.255.2.15
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf2a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.16 - Peer: pod2-leaf6b'
+ routes:
+ - 10.255.2.16
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf2a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.17 - Peer: pod2-leaf7a'
+ routes:
+ - 10.255.2.17
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf2a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.18 - Peer: pod2-leaf7b'
+ routes:
+ - 10.255.2.18
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf2a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.19 - Peer: pod2-leaf8a'
+ routes:
+ - 10.255.2.19
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf2a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.20 - Peer: pod2-leaf8b'
+ routes:
+ - 10.255.2.20
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf2a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.21 - Peer: pod2-leaf9a'
+ routes:
+ - 10.255.2.21
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf2a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.22 - Peer: pod2-leaf9b'
+ routes:
+ - 10.255.2.22
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf2a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.23 - Peer: pod2-leaf10a'
+ routes:
+ - 10.255.2.23
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf2a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.24 - Peer: pod2-leaf10b'
+ routes:
+ - 10.255.2.24
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf2a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.5 - Peer: pod1-leaf1a'
+ routes:
+ - 10.255.100.5
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf2a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.7 - Peer: pod1-leaf2a'
+ routes:
+ - 10.255.100.7
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf2a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.9 - Peer: pod1-leaf3a'
+ routes:
+ - 10.255.100.9
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf2a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.11 - Peer: pod1-leaf4a'
+ routes:
+ - 10.255.100.11
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf2a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.13 - Peer: pod1-leaf5a'
+ routes:
+ - 10.255.100.13
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf2a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.15 - Peer: pod1-leaf6a'
+ routes:
+ - 10.255.100.15
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf2a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.17 - Peer: pod1-leaf7a'
+ routes:
+ - 10.255.100.17
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf2a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.19 - Peer: pod1-leaf8a'
+ routes:
+ - 10.255.100.19
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf2a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.21 - Peer: pod1-leaf9a'
+ routes:
+ - 10.255.100.21
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf2a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.23 - Peer: pod1-leaf10a'
+ routes:
+ - 10.255.100.23
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf2a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.5 - Peer: pod2-leaf1a'
+ routes:
+ - 10.255.200.5
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf2a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.7 - Peer: pod2-leaf2a'
+ routes:
+ - 10.255.200.7
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf2a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.9 - Peer: pod2-leaf3a'
+ routes:
+ - 10.255.200.9
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf2a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.11 - Peer: pod2-leaf4a'
+ routes:
+ - 10.255.200.11
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf2a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.13 - Peer: pod2-leaf5a'
+ routes:
+ - 10.255.200.13
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf2a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.15 - Peer: pod2-leaf6a'
+ routes:
+ - 10.255.200.15
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf2a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.17 - Peer: pod2-leaf7a'
+ routes:
+ - 10.255.200.17
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf2a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.19 - Peer: pod2-leaf8a'
+ routes:
+ - 10.255.200.19
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf2a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.21 - Peer: pod2-leaf9a'
+ routes:
+ - 10.255.200.21
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf2a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.23 - Peer: pod2-leaf10a'
+ routes:
+ - 10.255.200.23
+- VerifyRoutingProtocolModel:
+ filters:
+ tags:
+ - pod1-leaf9b
+ model: multi-agent
+ result_overwrite:
+ custom_field: 'Routing protocol model: multi-agent'
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf9b
+ result_overwrite:
+ custom_field: 'Route: 10.255.0.1 - Peer: super-spine1'
+ routes:
+ - 10.255.0.1
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf9b
+ result_overwrite:
+ custom_field: 'Route: 10.255.0.2 - Peer: super-spine2'
+ routes:
+ - 10.255.0.2
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf9b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.1 - Peer: pod1-spine1'
+ routes:
+ - 10.255.1.1
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf9b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.2 - Peer: pod1-spine2'
+ routes:
+ - 10.255.1.2
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf9b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.3 - Peer: pod1-spine3'
+ routes:
+ - 10.255.1.3
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf9b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.4 - Peer: pod1-spine4'
+ routes:
+ - 10.255.1.4
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf9b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.5 - Peer: pod1-leaf1a'
+ routes:
+ - 10.255.1.5
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf9b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.6 - Peer: pod1-leaf1b'
+ routes:
+ - 10.255.1.6
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf9b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.7 - Peer: pod1-leaf2a'
+ routes:
+ - 10.255.1.7
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf9b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.8 - Peer: pod1-leaf2b'
+ routes:
+ - 10.255.1.8
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf9b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.9 - Peer: pod1-leaf3a'
+ routes:
+ - 10.255.1.9
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf9b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.10 - Peer: pod1-leaf3b'
+ routes:
+ - 10.255.1.10
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf9b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.11 - Peer: pod1-leaf4a'
+ routes:
+ - 10.255.1.11
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf9b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.12 - Peer: pod1-leaf4b'
+ routes:
+ - 10.255.1.12
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf9b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.13 - Peer: pod1-leaf5a'
+ routes:
+ - 10.255.1.13
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf9b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.14 - Peer: pod1-leaf5b'
+ routes:
+ - 10.255.1.14
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf9b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.15 - Peer: pod1-leaf6a'
+ routes:
+ - 10.255.1.15
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf9b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.16 - Peer: pod1-leaf6b'
+ routes:
+ - 10.255.1.16
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf9b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.17 - Peer: pod1-leaf7a'
+ routes:
+ - 10.255.1.17
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf9b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.18 - Peer: pod1-leaf7b'
+ routes:
+ - 10.255.1.18
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf9b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.19 - Peer: pod1-leaf8a'
+ routes:
+ - 10.255.1.19
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf9b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.20 - Peer: pod1-leaf8b'
+ routes:
+ - 10.255.1.20
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf9b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.21 - Peer: pod1-leaf9a'
+ routes:
+ - 10.255.1.21
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf9b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.22 - Peer: pod1-leaf9b'
+ routes:
+ - 10.255.1.22
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf9b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.23 - Peer: pod1-leaf10a'
+ routes:
+ - 10.255.1.23
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf9b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.24 - Peer: pod1-leaf10b'
+ routes:
+ - 10.255.1.24
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf9b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.1 - Peer: pod2-spine1'
+ routes:
+ - 10.255.2.1
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf9b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.2 - Peer: pod2-spine2'
+ routes:
+ - 10.255.2.2
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf9b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.3 - Peer: pod2-spine3'
+ routes:
+ - 10.255.2.3
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf9b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.4 - Peer: pod2-spine4'
+ routes:
+ - 10.255.2.4
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf9b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.5 - Peer: pod2-leaf1a'
+ routes:
+ - 10.255.2.5
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf9b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.6 - Peer: pod2-leaf1b'
+ routes:
+ - 10.255.2.6
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf9b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.7 - Peer: pod2-leaf2a'
+ routes:
+ - 10.255.2.7
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf9b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.8 - Peer: pod2-leaf2b'
+ routes:
+ - 10.255.2.8
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf9b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.9 - Peer: pod2-leaf3a'
+ routes:
+ - 10.255.2.9
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf9b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.10 - Peer: pod2-leaf3b'
+ routes:
+ - 10.255.2.10
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf9b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.11 - Peer: pod2-leaf4a'
+ routes:
+ - 10.255.2.11
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf9b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.12 - Peer: pod2-leaf4b'
+ routes:
+ - 10.255.2.12
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf9b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.13 - Peer: pod2-leaf5a'
+ routes:
+ - 10.255.2.13
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf9b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.14 - Peer: pod2-leaf5b'
+ routes:
+ - 10.255.2.14
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf9b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.15 - Peer: pod2-leaf6a'
+ routes:
+ - 10.255.2.15
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf9b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.16 - Peer: pod2-leaf6b'
+ routes:
+ - 10.255.2.16
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf9b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.17 - Peer: pod2-leaf7a'
+ routes:
+ - 10.255.2.17
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf9b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.18 - Peer: pod2-leaf7b'
+ routes:
+ - 10.255.2.18
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf9b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.19 - Peer: pod2-leaf8a'
+ routes:
+ - 10.255.2.19
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf9b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.20 - Peer: pod2-leaf8b'
+ routes:
+ - 10.255.2.20
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf9b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.21 - Peer: pod2-leaf9a'
+ routes:
+ - 10.255.2.21
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf9b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.22 - Peer: pod2-leaf9b'
+ routes:
+ - 10.255.2.22
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf9b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.23 - Peer: pod2-leaf10a'
+ routes:
+ - 10.255.2.23
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf9b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.24 - Peer: pod2-leaf10b'
+ routes:
+ - 10.255.2.24
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf9b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.5 - Peer: pod1-leaf1a'
+ routes:
+ - 10.255.100.5
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf9b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.7 - Peer: pod1-leaf2a'
+ routes:
+ - 10.255.100.7
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf9b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.9 - Peer: pod1-leaf3a'
+ routes:
+ - 10.255.100.9
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf9b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.11 - Peer: pod1-leaf4a'
+ routes:
+ - 10.255.100.11
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf9b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.13 - Peer: pod1-leaf5a'
+ routes:
+ - 10.255.100.13
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf9b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.15 - Peer: pod1-leaf6a'
+ routes:
+ - 10.255.100.15
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf9b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.17 - Peer: pod1-leaf7a'
+ routes:
+ - 10.255.100.17
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf9b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.19 - Peer: pod1-leaf8a'
+ routes:
+ - 10.255.100.19
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf9b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.21 - Peer: pod1-leaf9a'
+ routes:
+ - 10.255.100.21
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf9b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.23 - Peer: pod1-leaf10a'
+ routes:
+ - 10.255.100.23
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf9b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.5 - Peer: pod2-leaf1a'
+ routes:
+ - 10.255.200.5
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf9b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.7 - Peer: pod2-leaf2a'
+ routes:
+ - 10.255.200.7
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf9b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.9 - Peer: pod2-leaf3a'
+ routes:
+ - 10.255.200.9
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf9b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.11 - Peer: pod2-leaf4a'
+ routes:
+ - 10.255.200.11
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf9b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.13 - Peer: pod2-leaf5a'
+ routes:
+ - 10.255.200.13
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf9b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.15 - Peer: pod2-leaf6a'
+ routes:
+ - 10.255.200.15
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf9b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.17 - Peer: pod2-leaf7a'
+ routes:
+ - 10.255.200.17
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf9b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.19 - Peer: pod2-leaf8a'
+ routes:
+ - 10.255.200.19
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf9b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.21 - Peer: pod2-leaf9a'
+ routes:
+ - 10.255.200.21
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf9b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.23 - Peer: pod2-leaf10a'
+ routes:
+ - 10.255.200.23
+- VerifyRoutingProtocolModel:
+ filters:
+ tags:
+ - pod2-spine2
+ model: multi-agent
+ result_overwrite:
+ custom_field: 'Routing protocol model: multi-agent'
+- VerifyRoutingProtocolModel:
+ filters:
+ tags:
+ - pod1-leaf4a
+ model: multi-agent
+ result_overwrite:
+ custom_field: 'Routing protocol model: multi-agent'
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf4a
+ result_overwrite:
+ custom_field: 'Route: 10.255.0.1 - Peer: super-spine1'
+ routes:
+ - 10.255.0.1
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf4a
+ result_overwrite:
+ custom_field: 'Route: 10.255.0.2 - Peer: super-spine2'
+ routes:
+ - 10.255.0.2
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf4a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.1 - Peer: pod1-spine1'
+ routes:
+ - 10.255.1.1
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf4a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.2 - Peer: pod1-spine2'
+ routes:
+ - 10.255.1.2
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf4a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.3 - Peer: pod1-spine3'
+ routes:
+ - 10.255.1.3
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf4a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.4 - Peer: pod1-spine4'
+ routes:
+ - 10.255.1.4
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf4a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.5 - Peer: pod1-leaf1a'
+ routes:
+ - 10.255.1.5
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf4a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.6 - Peer: pod1-leaf1b'
+ routes:
+ - 10.255.1.6
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf4a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.7 - Peer: pod1-leaf2a'
+ routes:
+ - 10.255.1.7
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf4a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.8 - Peer: pod1-leaf2b'
+ routes:
+ - 10.255.1.8
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf4a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.9 - Peer: pod1-leaf3a'
+ routes:
+ - 10.255.1.9
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf4a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.10 - Peer: pod1-leaf3b'
+ routes:
+ - 10.255.1.10
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf4a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.11 - Peer: pod1-leaf4a'
+ routes:
+ - 10.255.1.11
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf4a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.12 - Peer: pod1-leaf4b'
+ routes:
+ - 10.255.1.12
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf4a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.13 - Peer: pod1-leaf5a'
+ routes:
+ - 10.255.1.13
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf4a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.14 - Peer: pod1-leaf5b'
+ routes:
+ - 10.255.1.14
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf4a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.15 - Peer: pod1-leaf6a'
+ routes:
+ - 10.255.1.15
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf4a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.16 - Peer: pod1-leaf6b'
+ routes:
+ - 10.255.1.16
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf4a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.17 - Peer: pod1-leaf7a'
+ routes:
+ - 10.255.1.17
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf4a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.18 - Peer: pod1-leaf7b'
+ routes:
+ - 10.255.1.18
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf4a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.19 - Peer: pod1-leaf8a'
+ routes:
+ - 10.255.1.19
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf4a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.20 - Peer: pod1-leaf8b'
+ routes:
+ - 10.255.1.20
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf4a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.21 - Peer: pod1-leaf9a'
+ routes:
+ - 10.255.1.21
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf4a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.22 - Peer: pod1-leaf9b'
+ routes:
+ - 10.255.1.22
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf4a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.23 - Peer: pod1-leaf10a'
+ routes:
+ - 10.255.1.23
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf4a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.24 - Peer: pod1-leaf10b'
+ routes:
+ - 10.255.1.24
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf4a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.1 - Peer: pod2-spine1'
+ routes:
+ - 10.255.2.1
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf4a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.2 - Peer: pod2-spine2'
+ routes:
+ - 10.255.2.2
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf4a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.3 - Peer: pod2-spine3'
+ routes:
+ - 10.255.2.3
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf4a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.4 - Peer: pod2-spine4'
+ routes:
+ - 10.255.2.4
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf4a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.5 - Peer: pod2-leaf1a'
+ routes:
+ - 10.255.2.5
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf4a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.6 - Peer: pod2-leaf1b'
+ routes:
+ - 10.255.2.6
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf4a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.7 - Peer: pod2-leaf2a'
+ routes:
+ - 10.255.2.7
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf4a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.8 - Peer: pod2-leaf2b'
+ routes:
+ - 10.255.2.8
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf4a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.9 - Peer: pod2-leaf3a'
+ routes:
+ - 10.255.2.9
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf4a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.10 - Peer: pod2-leaf3b'
+ routes:
+ - 10.255.2.10
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf4a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.11 - Peer: pod2-leaf4a'
+ routes:
+ - 10.255.2.11
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf4a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.12 - Peer: pod2-leaf4b'
+ routes:
+ - 10.255.2.12
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf4a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.13 - Peer: pod2-leaf5a'
+ routes:
+ - 10.255.2.13
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf4a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.14 - Peer: pod2-leaf5b'
+ routes:
+ - 10.255.2.14
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf4a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.15 - Peer: pod2-leaf6a'
+ routes:
+ - 10.255.2.15
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf4a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.16 - Peer: pod2-leaf6b'
+ routes:
+ - 10.255.2.16
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf4a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.17 - Peer: pod2-leaf7a'
+ routes:
+ - 10.255.2.17
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf4a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.18 - Peer: pod2-leaf7b'
+ routes:
+ - 10.255.2.18
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf4a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.19 - Peer: pod2-leaf8a'
+ routes:
+ - 10.255.2.19
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf4a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.20 - Peer: pod2-leaf8b'
+ routes:
+ - 10.255.2.20
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf4a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.21 - Peer: pod2-leaf9a'
+ routes:
+ - 10.255.2.21
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf4a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.22 - Peer: pod2-leaf9b'
+ routes:
+ - 10.255.2.22
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf4a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.23 - Peer: pod2-leaf10a'
+ routes:
+ - 10.255.2.23
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf4a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.24 - Peer: pod2-leaf10b'
+ routes:
+ - 10.255.2.24
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf4a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.5 - Peer: pod1-leaf1a'
+ routes:
+ - 10.255.100.5
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf4a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.7 - Peer: pod1-leaf2a'
+ routes:
+ - 10.255.100.7
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf4a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.9 - Peer: pod1-leaf3a'
+ routes:
+ - 10.255.100.9
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf4a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.11 - Peer: pod1-leaf4a'
+ routes:
+ - 10.255.100.11
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf4a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.13 - Peer: pod1-leaf5a'
+ routes:
+ - 10.255.100.13
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf4a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.15 - Peer: pod1-leaf6a'
+ routes:
+ - 10.255.100.15
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf4a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.17 - Peer: pod1-leaf7a'
+ routes:
+ - 10.255.100.17
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf4a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.19 - Peer: pod1-leaf8a'
+ routes:
+ - 10.255.100.19
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf4a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.21 - Peer: pod1-leaf9a'
+ routes:
+ - 10.255.100.21
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf4a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.23 - Peer: pod1-leaf10a'
+ routes:
+ - 10.255.100.23
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf4a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.5 - Peer: pod2-leaf1a'
+ routes:
+ - 10.255.200.5
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf4a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.7 - Peer: pod2-leaf2a'
+ routes:
+ - 10.255.200.7
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf4a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.9 - Peer: pod2-leaf3a'
+ routes:
+ - 10.255.200.9
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf4a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.11 - Peer: pod2-leaf4a'
+ routes:
+ - 10.255.200.11
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf4a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.13 - Peer: pod2-leaf5a'
+ routes:
+ - 10.255.200.13
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf4a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.15 - Peer: pod2-leaf6a'
+ routes:
+ - 10.255.200.15
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf4a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.17 - Peer: pod2-leaf7a'
+ routes:
+ - 10.255.200.17
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf4a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.19 - Peer: pod2-leaf8a'
+ routes:
+ - 10.255.200.19
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf4a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.21 - Peer: pod2-leaf9a'
+ routes:
+ - 10.255.200.21
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf4a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.23 - Peer: pod2-leaf10a'
+ routes:
+ - 10.255.200.23
+- VerifyRoutingProtocolModel:
+ filters:
+ tags:
+ - pod1-leaf3a
+ model: multi-agent
+ result_overwrite:
+ custom_field: 'Routing protocol model: multi-agent'
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf3a
+ result_overwrite:
+ custom_field: 'Route: 10.255.0.1 - Peer: super-spine1'
+ routes:
+ - 10.255.0.1
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf3a
+ result_overwrite:
+ custom_field: 'Route: 10.255.0.2 - Peer: super-spine2'
+ routes:
+ - 10.255.0.2
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf3a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.1 - Peer: pod1-spine1'
+ routes:
+ - 10.255.1.1
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf3a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.2 - Peer: pod1-spine2'
+ routes:
+ - 10.255.1.2
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf3a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.3 - Peer: pod1-spine3'
+ routes:
+ - 10.255.1.3
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf3a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.4 - Peer: pod1-spine4'
+ routes:
+ - 10.255.1.4
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf3a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.5 - Peer: pod1-leaf1a'
+ routes:
+ - 10.255.1.5
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf3a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.6 - Peer: pod1-leaf1b'
+ routes:
+ - 10.255.1.6
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf3a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.7 - Peer: pod1-leaf2a'
+ routes:
+ - 10.255.1.7
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf3a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.8 - Peer: pod1-leaf2b'
+ routes:
+ - 10.255.1.8
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf3a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.9 - Peer: pod1-leaf3a'
+ routes:
+ - 10.255.1.9
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf3a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.10 - Peer: pod1-leaf3b'
+ routes:
+ - 10.255.1.10
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf3a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.11 - Peer: pod1-leaf4a'
+ routes:
+ - 10.255.1.11
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf3a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.12 - Peer: pod1-leaf4b'
+ routes:
+ - 10.255.1.12
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf3a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.13 - Peer: pod1-leaf5a'
+ routes:
+ - 10.255.1.13
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf3a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.14 - Peer: pod1-leaf5b'
+ routes:
+ - 10.255.1.14
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf3a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.15 - Peer: pod1-leaf6a'
+ routes:
+ - 10.255.1.15
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf3a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.16 - Peer: pod1-leaf6b'
+ routes:
+ - 10.255.1.16
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf3a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.17 - Peer: pod1-leaf7a'
+ routes:
+ - 10.255.1.17
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf3a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.18 - Peer: pod1-leaf7b'
+ routes:
+ - 10.255.1.18
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf3a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.19 - Peer: pod1-leaf8a'
+ routes:
+ - 10.255.1.19
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf3a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.20 - Peer: pod1-leaf8b'
+ routes:
+ - 10.255.1.20
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf3a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.21 - Peer: pod1-leaf9a'
+ routes:
+ - 10.255.1.21
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf3a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.22 - Peer: pod1-leaf9b'
+ routes:
+ - 10.255.1.22
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf3a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.23 - Peer: pod1-leaf10a'
+ routes:
+ - 10.255.1.23
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf3a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.24 - Peer: pod1-leaf10b'
+ routes:
+ - 10.255.1.24
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf3a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.1 - Peer: pod2-spine1'
+ routes:
+ - 10.255.2.1
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf3a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.2 - Peer: pod2-spine2'
+ routes:
+ - 10.255.2.2
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf3a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.3 - Peer: pod2-spine3'
+ routes:
+ - 10.255.2.3
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf3a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.4 - Peer: pod2-spine4'
+ routes:
+ - 10.255.2.4
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf3a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.5 - Peer: pod2-leaf1a'
+ routes:
+ - 10.255.2.5
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf3a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.6 - Peer: pod2-leaf1b'
+ routes:
+ - 10.255.2.6
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf3a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.7 - Peer: pod2-leaf2a'
+ routes:
+ - 10.255.2.7
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf3a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.8 - Peer: pod2-leaf2b'
+ routes:
+ - 10.255.2.8
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf3a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.9 - Peer: pod2-leaf3a'
+ routes:
+ - 10.255.2.9
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf3a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.10 - Peer: pod2-leaf3b'
+ routes:
+ - 10.255.2.10
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf3a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.11 - Peer: pod2-leaf4a'
+ routes:
+ - 10.255.2.11
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf3a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.12 - Peer: pod2-leaf4b'
+ routes:
+ - 10.255.2.12
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf3a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.13 - Peer: pod2-leaf5a'
+ routes:
+ - 10.255.2.13
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf3a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.14 - Peer: pod2-leaf5b'
+ routes:
+ - 10.255.2.14
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf3a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.15 - Peer: pod2-leaf6a'
+ routes:
+ - 10.255.2.15
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf3a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.16 - Peer: pod2-leaf6b'
+ routes:
+ - 10.255.2.16
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf3a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.17 - Peer: pod2-leaf7a'
+ routes:
+ - 10.255.2.17
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf3a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.18 - Peer: pod2-leaf7b'
+ routes:
+ - 10.255.2.18
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf3a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.19 - Peer: pod2-leaf8a'
+ routes:
+ - 10.255.2.19
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf3a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.20 - Peer: pod2-leaf8b'
+ routes:
+ - 10.255.2.20
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf3a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.21 - Peer: pod2-leaf9a'
+ routes:
+ - 10.255.2.21
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf3a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.22 - Peer: pod2-leaf9b'
+ routes:
+ - 10.255.2.22
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf3a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.23 - Peer: pod2-leaf10a'
+ routes:
+ - 10.255.2.23
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf3a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.24 - Peer: pod2-leaf10b'
+ routes:
+ - 10.255.2.24
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf3a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.5 - Peer: pod1-leaf1a'
+ routes:
+ - 10.255.100.5
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf3a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.7 - Peer: pod1-leaf2a'
+ routes:
+ - 10.255.100.7
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf3a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.9 - Peer: pod1-leaf3a'
+ routes:
+ - 10.255.100.9
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf3a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.11 - Peer: pod1-leaf4a'
+ routes:
+ - 10.255.100.11
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf3a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.13 - Peer: pod1-leaf5a'
+ routes:
+ - 10.255.100.13
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf3a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.15 - Peer: pod1-leaf6a'
+ routes:
+ - 10.255.100.15
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf3a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.17 - Peer: pod1-leaf7a'
+ routes:
+ - 10.255.100.17
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf3a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.19 - Peer: pod1-leaf8a'
+ routes:
+ - 10.255.100.19
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf3a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.21 - Peer: pod1-leaf9a'
+ routes:
+ - 10.255.100.21
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf3a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.23 - Peer: pod1-leaf10a'
+ routes:
+ - 10.255.100.23
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf3a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.5 - Peer: pod2-leaf1a'
+ routes:
+ - 10.255.200.5
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf3a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.7 - Peer: pod2-leaf2a'
+ routes:
+ - 10.255.200.7
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf3a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.9 - Peer: pod2-leaf3a'
+ routes:
+ - 10.255.200.9
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf3a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.11 - Peer: pod2-leaf4a'
+ routes:
+ - 10.255.200.11
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf3a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.13 - Peer: pod2-leaf5a'
+ routes:
+ - 10.255.200.13
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf3a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.15 - Peer: pod2-leaf6a'
+ routes:
+ - 10.255.200.15
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf3a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.17 - Peer: pod2-leaf7a'
+ routes:
+ - 10.255.200.17
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf3a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.19 - Peer: pod2-leaf8a'
+ routes:
+ - 10.255.200.19
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf3a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.21 - Peer: pod2-leaf9a'
+ routes:
+ - 10.255.200.21
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf3a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.23 - Peer: pod2-leaf10a'
+ routes:
+ - 10.255.200.23
+- VerifyRoutingProtocolModel:
+ filters:
+ tags:
+ - pod2-leaf7a
+ model: multi-agent
+ result_overwrite:
+ custom_field: 'Routing protocol model: multi-agent'
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf7a
+ result_overwrite:
+ custom_field: 'Route: 10.255.0.1 - Peer: super-spine1'
+ routes:
+ - 10.255.0.1
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf7a
+ result_overwrite:
+ custom_field: 'Route: 10.255.0.2 - Peer: super-spine2'
+ routes:
+ - 10.255.0.2
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf7a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.1 - Peer: pod1-spine1'
+ routes:
+ - 10.255.1.1
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf7a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.2 - Peer: pod1-spine2'
+ routes:
+ - 10.255.1.2
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf7a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.3 - Peer: pod1-spine3'
+ routes:
+ - 10.255.1.3
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf7a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.4 - Peer: pod1-spine4'
+ routes:
+ - 10.255.1.4
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf7a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.5 - Peer: pod1-leaf1a'
+ routes:
+ - 10.255.1.5
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf7a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.6 - Peer: pod1-leaf1b'
+ routes:
+ - 10.255.1.6
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf7a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.7 - Peer: pod1-leaf2a'
+ routes:
+ - 10.255.1.7
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf7a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.8 - Peer: pod1-leaf2b'
+ routes:
+ - 10.255.1.8
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf7a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.9 - Peer: pod1-leaf3a'
+ routes:
+ - 10.255.1.9
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf7a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.10 - Peer: pod1-leaf3b'
+ routes:
+ - 10.255.1.10
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf7a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.11 - Peer: pod1-leaf4a'
+ routes:
+ - 10.255.1.11
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf7a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.12 - Peer: pod1-leaf4b'
+ routes:
+ - 10.255.1.12
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf7a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.13 - Peer: pod1-leaf5a'
+ routes:
+ - 10.255.1.13
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf7a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.14 - Peer: pod1-leaf5b'
+ routes:
+ - 10.255.1.14
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf7a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.15 - Peer: pod1-leaf6a'
+ routes:
+ - 10.255.1.15
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf7a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.16 - Peer: pod1-leaf6b'
+ routes:
+ - 10.255.1.16
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf7a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.17 - Peer: pod1-leaf7a'
+ routes:
+ - 10.255.1.17
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf7a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.18 - Peer: pod1-leaf7b'
+ routes:
+ - 10.255.1.18
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf7a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.19 - Peer: pod1-leaf8a'
+ routes:
+ - 10.255.1.19
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf7a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.20 - Peer: pod1-leaf8b'
+ routes:
+ - 10.255.1.20
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf7a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.21 - Peer: pod1-leaf9a'
+ routes:
+ - 10.255.1.21
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf7a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.22 - Peer: pod1-leaf9b'
+ routes:
+ - 10.255.1.22
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf7a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.23 - Peer: pod1-leaf10a'
+ routes:
+ - 10.255.1.23
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf7a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.24 - Peer: pod1-leaf10b'
+ routes:
+ - 10.255.1.24
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf7a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.1 - Peer: pod2-spine1'
+ routes:
+ - 10.255.2.1
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf7a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.2 - Peer: pod2-spine2'
+ routes:
+ - 10.255.2.2
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf7a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.3 - Peer: pod2-spine3'
+ routes:
+ - 10.255.2.3
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf7a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.4 - Peer: pod2-spine4'
+ routes:
+ - 10.255.2.4
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf7a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.5 - Peer: pod2-leaf1a'
+ routes:
+ - 10.255.2.5
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf7a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.6 - Peer: pod2-leaf1b'
+ routes:
+ - 10.255.2.6
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf7a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.7 - Peer: pod2-leaf2a'
+ routes:
+ - 10.255.2.7
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf7a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.8 - Peer: pod2-leaf2b'
+ routes:
+ - 10.255.2.8
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf7a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.9 - Peer: pod2-leaf3a'
+ routes:
+ - 10.255.2.9
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf7a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.10 - Peer: pod2-leaf3b'
+ routes:
+ - 10.255.2.10
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf7a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.11 - Peer: pod2-leaf4a'
+ routes:
+ - 10.255.2.11
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf7a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.12 - Peer: pod2-leaf4b'
+ routes:
+ - 10.255.2.12
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf7a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.13 - Peer: pod2-leaf5a'
+ routes:
+ - 10.255.2.13
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf7a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.14 - Peer: pod2-leaf5b'
+ routes:
+ - 10.255.2.14
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf7a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.15 - Peer: pod2-leaf6a'
+ routes:
+ - 10.255.2.15
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf7a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.16 - Peer: pod2-leaf6b'
+ routes:
+ - 10.255.2.16
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf7a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.17 - Peer: pod2-leaf7a'
+ routes:
+ - 10.255.2.17
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf7a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.18 - Peer: pod2-leaf7b'
+ routes:
+ - 10.255.2.18
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf7a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.19 - Peer: pod2-leaf8a'
+ routes:
+ - 10.255.2.19
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf7a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.20 - Peer: pod2-leaf8b'
+ routes:
+ - 10.255.2.20
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf7a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.21 - Peer: pod2-leaf9a'
+ routes:
+ - 10.255.2.21
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf7a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.22 - Peer: pod2-leaf9b'
+ routes:
+ - 10.255.2.22
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf7a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.23 - Peer: pod2-leaf10a'
+ routes:
+ - 10.255.2.23
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf7a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.24 - Peer: pod2-leaf10b'
+ routes:
+ - 10.255.2.24
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf7a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.5 - Peer: pod1-leaf1a'
+ routes:
+ - 10.255.100.5
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf7a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.7 - Peer: pod1-leaf2a'
+ routes:
+ - 10.255.100.7
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf7a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.9 - Peer: pod1-leaf3a'
+ routes:
+ - 10.255.100.9
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf7a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.11 - Peer: pod1-leaf4a'
+ routes:
+ - 10.255.100.11
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf7a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.13 - Peer: pod1-leaf5a'
+ routes:
+ - 10.255.100.13
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf7a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.15 - Peer: pod1-leaf6a'
+ routes:
+ - 10.255.100.15
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf7a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.17 - Peer: pod1-leaf7a'
+ routes:
+ - 10.255.100.17
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf7a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.19 - Peer: pod1-leaf8a'
+ routes:
+ - 10.255.100.19
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf7a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.21 - Peer: pod1-leaf9a'
+ routes:
+ - 10.255.100.21
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf7a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.23 - Peer: pod1-leaf10a'
+ routes:
+ - 10.255.100.23
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf7a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.5 - Peer: pod2-leaf1a'
+ routes:
+ - 10.255.200.5
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf7a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.7 - Peer: pod2-leaf2a'
+ routes:
+ - 10.255.200.7
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf7a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.9 - Peer: pod2-leaf3a'
+ routes:
+ - 10.255.200.9
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf7a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.11 - Peer: pod2-leaf4a'
+ routes:
+ - 10.255.200.11
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf7a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.13 - Peer: pod2-leaf5a'
+ routes:
+ - 10.255.200.13
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf7a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.15 - Peer: pod2-leaf6a'
+ routes:
+ - 10.255.200.15
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf7a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.17 - Peer: pod2-leaf7a'
+ routes:
+ - 10.255.200.17
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf7a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.19 - Peer: pod2-leaf8a'
+ routes:
+ - 10.255.200.19
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf7a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.21 - Peer: pod2-leaf9a'
+ routes:
+ - 10.255.200.21
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf7a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.23 - Peer: pod2-leaf10a'
+ routes:
+ - 10.255.200.23
+- VerifyRoutingProtocolModel:
+ filters:
+ tags:
+ - pod1-leaf1a
+ model: multi-agent
+ result_overwrite:
+ custom_field: 'Routing protocol model: multi-agent'
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf1a
+ result_overwrite:
+ custom_field: 'Route: 10.255.0.1 - Peer: super-spine1'
+ routes:
+ - 10.255.0.1
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf1a
+ result_overwrite:
+ custom_field: 'Route: 10.255.0.2 - Peer: super-spine2'
+ routes:
+ - 10.255.0.2
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf1a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.1 - Peer: pod1-spine1'
+ routes:
+ - 10.255.1.1
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf1a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.2 - Peer: pod1-spine2'
+ routes:
+ - 10.255.1.2
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf1a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.3 - Peer: pod1-spine3'
+ routes:
+ - 10.255.1.3
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf1a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.4 - Peer: pod1-spine4'
+ routes:
+ - 10.255.1.4
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf1a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.5 - Peer: pod1-leaf1a'
+ routes:
+ - 10.255.1.5
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf1a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.6 - Peer: pod1-leaf1b'
+ routes:
+ - 10.255.1.6
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf1a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.7 - Peer: pod1-leaf2a'
+ routes:
+ - 10.255.1.7
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf1a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.8 - Peer: pod1-leaf2b'
+ routes:
+ - 10.255.1.8
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf1a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.9 - Peer: pod1-leaf3a'
+ routes:
+ - 10.255.1.9
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf1a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.10 - Peer: pod1-leaf3b'
+ routes:
+ - 10.255.1.10
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf1a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.11 - Peer: pod1-leaf4a'
+ routes:
+ - 10.255.1.11
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf1a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.12 - Peer: pod1-leaf4b'
+ routes:
+ - 10.255.1.12
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf1a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.13 - Peer: pod1-leaf5a'
+ routes:
+ - 10.255.1.13
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf1a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.14 - Peer: pod1-leaf5b'
+ routes:
+ - 10.255.1.14
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf1a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.15 - Peer: pod1-leaf6a'
+ routes:
+ - 10.255.1.15
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf1a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.16 - Peer: pod1-leaf6b'
+ routes:
+ - 10.255.1.16
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf1a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.17 - Peer: pod1-leaf7a'
+ routes:
+ - 10.255.1.17
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf1a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.18 - Peer: pod1-leaf7b'
+ routes:
+ - 10.255.1.18
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf1a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.19 - Peer: pod1-leaf8a'
+ routes:
+ - 10.255.1.19
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf1a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.20 - Peer: pod1-leaf8b'
+ routes:
+ - 10.255.1.20
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf1a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.21 - Peer: pod1-leaf9a'
+ routes:
+ - 10.255.1.21
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf1a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.22 - Peer: pod1-leaf9b'
+ routes:
+ - 10.255.1.22
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf1a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.23 - Peer: pod1-leaf10a'
+ routes:
+ - 10.255.1.23
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf1a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.24 - Peer: pod1-leaf10b'
+ routes:
+ - 10.255.1.24
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf1a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.1 - Peer: pod2-spine1'
+ routes:
+ - 10.255.2.1
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf1a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.2 - Peer: pod2-spine2'
+ routes:
+ - 10.255.2.2
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf1a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.3 - Peer: pod2-spine3'
+ routes:
+ - 10.255.2.3
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf1a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.4 - Peer: pod2-spine4'
+ routes:
+ - 10.255.2.4
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf1a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.5 - Peer: pod2-leaf1a'
+ routes:
+ - 10.255.2.5
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf1a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.6 - Peer: pod2-leaf1b'
+ routes:
+ - 10.255.2.6
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf1a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.7 - Peer: pod2-leaf2a'
+ routes:
+ - 10.255.2.7
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf1a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.8 - Peer: pod2-leaf2b'
+ routes:
+ - 10.255.2.8
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf1a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.9 - Peer: pod2-leaf3a'
+ routes:
+ - 10.255.2.9
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf1a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.10 - Peer: pod2-leaf3b'
+ routes:
+ - 10.255.2.10
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf1a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.11 - Peer: pod2-leaf4a'
+ routes:
+ - 10.255.2.11
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf1a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.12 - Peer: pod2-leaf4b'
+ routes:
+ - 10.255.2.12
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf1a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.13 - Peer: pod2-leaf5a'
+ routes:
+ - 10.255.2.13
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf1a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.14 - Peer: pod2-leaf5b'
+ routes:
+ - 10.255.2.14
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf1a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.15 - Peer: pod2-leaf6a'
+ routes:
+ - 10.255.2.15
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf1a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.16 - Peer: pod2-leaf6b'
+ routes:
+ - 10.255.2.16
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf1a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.17 - Peer: pod2-leaf7a'
+ routes:
+ - 10.255.2.17
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf1a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.18 - Peer: pod2-leaf7b'
+ routes:
+ - 10.255.2.18
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf1a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.19 - Peer: pod2-leaf8a'
+ routes:
+ - 10.255.2.19
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf1a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.20 - Peer: pod2-leaf8b'
+ routes:
+ - 10.255.2.20
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf1a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.21 - Peer: pod2-leaf9a'
+ routes:
+ - 10.255.2.21
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf1a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.22 - Peer: pod2-leaf9b'
+ routes:
+ - 10.255.2.22
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf1a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.23 - Peer: pod2-leaf10a'
+ routes:
+ - 10.255.2.23
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf1a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.24 - Peer: pod2-leaf10b'
+ routes:
+ - 10.255.2.24
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf1a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.5 - Peer: pod1-leaf1a'
+ routes:
+ - 10.255.100.5
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf1a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.7 - Peer: pod1-leaf2a'
+ routes:
+ - 10.255.100.7
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf1a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.9 - Peer: pod1-leaf3a'
+ routes:
+ - 10.255.100.9
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf1a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.11 - Peer: pod1-leaf4a'
+ routes:
+ - 10.255.100.11
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf1a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.13 - Peer: pod1-leaf5a'
+ routes:
+ - 10.255.100.13
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf1a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.15 - Peer: pod1-leaf6a'
+ routes:
+ - 10.255.100.15
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf1a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.17 - Peer: pod1-leaf7a'
+ routes:
+ - 10.255.100.17
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf1a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.19 - Peer: pod1-leaf8a'
+ routes:
+ - 10.255.100.19
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf1a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.21 - Peer: pod1-leaf9a'
+ routes:
+ - 10.255.100.21
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf1a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.23 - Peer: pod1-leaf10a'
+ routes:
+ - 10.255.100.23
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf1a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.5 - Peer: pod2-leaf1a'
+ routes:
+ - 10.255.200.5
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf1a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.7 - Peer: pod2-leaf2a'
+ routes:
+ - 10.255.200.7
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf1a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.9 - Peer: pod2-leaf3a'
+ routes:
+ - 10.255.200.9
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf1a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.11 - Peer: pod2-leaf4a'
+ routes:
+ - 10.255.200.11
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf1a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.13 - Peer: pod2-leaf5a'
+ routes:
+ - 10.255.200.13
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf1a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.15 - Peer: pod2-leaf6a'
+ routes:
+ - 10.255.200.15
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf1a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.17 - Peer: pod2-leaf7a'
+ routes:
+ - 10.255.200.17
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf1a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.19 - Peer: pod2-leaf8a'
+ routes:
+ - 10.255.200.19
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf1a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.21 - Peer: pod2-leaf9a'
+ routes:
+ - 10.255.200.21
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf1a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.23 - Peer: pod2-leaf10a'
+ routes:
+ - 10.255.200.23
+- VerifyRoutingProtocolModel:
+ filters:
+ tags:
+ - super-spine1
+ model: multi-agent
+ result_overwrite:
+ custom_field: 'Routing protocol model: multi-agent'
+- VerifyRoutingProtocolModel:
+ filters:
+ tags:
+ - pod1-leaf6a
+ model: multi-agent
+ result_overwrite:
+ custom_field: 'Routing protocol model: multi-agent'
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf6a
+ result_overwrite:
+ custom_field: 'Route: 10.255.0.1 - Peer: super-spine1'
+ routes:
+ - 10.255.0.1
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf6a
+ result_overwrite:
+ custom_field: 'Route: 10.255.0.2 - Peer: super-spine2'
+ routes:
+ - 10.255.0.2
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf6a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.1 - Peer: pod1-spine1'
+ routes:
+ - 10.255.1.1
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf6a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.2 - Peer: pod1-spine2'
+ routes:
+ - 10.255.1.2
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf6a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.3 - Peer: pod1-spine3'
+ routes:
+ - 10.255.1.3
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf6a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.4 - Peer: pod1-spine4'
+ routes:
+ - 10.255.1.4
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf6a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.5 - Peer: pod1-leaf1a'
+ routes:
+ - 10.255.1.5
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf6a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.6 - Peer: pod1-leaf1b'
+ routes:
+ - 10.255.1.6
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf6a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.7 - Peer: pod1-leaf2a'
+ routes:
+ - 10.255.1.7
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf6a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.8 - Peer: pod1-leaf2b'
+ routes:
+ - 10.255.1.8
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf6a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.9 - Peer: pod1-leaf3a'
+ routes:
+ - 10.255.1.9
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf6a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.10 - Peer: pod1-leaf3b'
+ routes:
+ - 10.255.1.10
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf6a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.11 - Peer: pod1-leaf4a'
+ routes:
+ - 10.255.1.11
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf6a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.12 - Peer: pod1-leaf4b'
+ routes:
+ - 10.255.1.12
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf6a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.13 - Peer: pod1-leaf5a'
+ routes:
+ - 10.255.1.13
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf6a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.14 - Peer: pod1-leaf5b'
+ routes:
+ - 10.255.1.14
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf6a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.15 - Peer: pod1-leaf6a'
+ routes:
+ - 10.255.1.15
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf6a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.16 - Peer: pod1-leaf6b'
+ routes:
+ - 10.255.1.16
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf6a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.17 - Peer: pod1-leaf7a'
+ routes:
+ - 10.255.1.17
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf6a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.18 - Peer: pod1-leaf7b'
+ routes:
+ - 10.255.1.18
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf6a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.19 - Peer: pod1-leaf8a'
+ routes:
+ - 10.255.1.19
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf6a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.20 - Peer: pod1-leaf8b'
+ routes:
+ - 10.255.1.20
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf6a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.21 - Peer: pod1-leaf9a'
+ routes:
+ - 10.255.1.21
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf6a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.22 - Peer: pod1-leaf9b'
+ routes:
+ - 10.255.1.22
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf6a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.23 - Peer: pod1-leaf10a'
+ routes:
+ - 10.255.1.23
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf6a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.24 - Peer: pod1-leaf10b'
+ routes:
+ - 10.255.1.24
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf6a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.1 - Peer: pod2-spine1'
+ routes:
+ - 10.255.2.1
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf6a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.2 - Peer: pod2-spine2'
+ routes:
+ - 10.255.2.2
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf6a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.3 - Peer: pod2-spine3'
+ routes:
+ - 10.255.2.3
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf6a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.4 - Peer: pod2-spine4'
+ routes:
+ - 10.255.2.4
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf6a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.5 - Peer: pod2-leaf1a'
+ routes:
+ - 10.255.2.5
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf6a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.6 - Peer: pod2-leaf1b'
+ routes:
+ - 10.255.2.6
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf6a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.7 - Peer: pod2-leaf2a'
+ routes:
+ - 10.255.2.7
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf6a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.8 - Peer: pod2-leaf2b'
+ routes:
+ - 10.255.2.8
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf6a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.9 - Peer: pod2-leaf3a'
+ routes:
+ - 10.255.2.9
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf6a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.10 - Peer: pod2-leaf3b'
+ routes:
+ - 10.255.2.10
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf6a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.11 - Peer: pod2-leaf4a'
+ routes:
+ - 10.255.2.11
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf6a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.12 - Peer: pod2-leaf4b'
+ routes:
+ - 10.255.2.12
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf6a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.13 - Peer: pod2-leaf5a'
+ routes:
+ - 10.255.2.13
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf6a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.14 - Peer: pod2-leaf5b'
+ routes:
+ - 10.255.2.14
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf6a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.15 - Peer: pod2-leaf6a'
+ routes:
+ - 10.255.2.15
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf6a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.16 - Peer: pod2-leaf6b'
+ routes:
+ - 10.255.2.16
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf6a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.17 - Peer: pod2-leaf7a'
+ routes:
+ - 10.255.2.17
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf6a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.18 - Peer: pod2-leaf7b'
+ routes:
+ - 10.255.2.18
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf6a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.19 - Peer: pod2-leaf8a'
+ routes:
+ - 10.255.2.19
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf6a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.20 - Peer: pod2-leaf8b'
+ routes:
+ - 10.255.2.20
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf6a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.21 - Peer: pod2-leaf9a'
+ routes:
+ - 10.255.2.21
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf6a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.22 - Peer: pod2-leaf9b'
+ routes:
+ - 10.255.2.22
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf6a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.23 - Peer: pod2-leaf10a'
+ routes:
+ - 10.255.2.23
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf6a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.24 - Peer: pod2-leaf10b'
+ routes:
+ - 10.255.2.24
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf6a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.5 - Peer: pod1-leaf1a'
+ routes:
+ - 10.255.100.5
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf6a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.7 - Peer: pod1-leaf2a'
+ routes:
+ - 10.255.100.7
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf6a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.9 - Peer: pod1-leaf3a'
+ routes:
+ - 10.255.100.9
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf6a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.11 - Peer: pod1-leaf4a'
+ routes:
+ - 10.255.100.11
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf6a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.13 - Peer: pod1-leaf5a'
+ routes:
+ - 10.255.100.13
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf6a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.15 - Peer: pod1-leaf6a'
+ routes:
+ - 10.255.100.15
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf6a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.17 - Peer: pod1-leaf7a'
+ routes:
+ - 10.255.100.17
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf6a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.19 - Peer: pod1-leaf8a'
+ routes:
+ - 10.255.100.19
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf6a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.21 - Peer: pod1-leaf9a'
+ routes:
+ - 10.255.100.21
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf6a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.23 - Peer: pod1-leaf10a'
+ routes:
+ - 10.255.100.23
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf6a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.5 - Peer: pod2-leaf1a'
+ routes:
+ - 10.255.200.5
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf6a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.7 - Peer: pod2-leaf2a'
+ routes:
+ - 10.255.200.7
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf6a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.9 - Peer: pod2-leaf3a'
+ routes:
+ - 10.255.200.9
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf6a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.11 - Peer: pod2-leaf4a'
+ routes:
+ - 10.255.200.11
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf6a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.13 - Peer: pod2-leaf5a'
+ routes:
+ - 10.255.200.13
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf6a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.15 - Peer: pod2-leaf6a'
+ routes:
+ - 10.255.200.15
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf6a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.17 - Peer: pod2-leaf7a'
+ routes:
+ - 10.255.200.17
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf6a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.19 - Peer: pod2-leaf8a'
+ routes:
+ - 10.255.200.19
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf6a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.21 - Peer: pod2-leaf9a'
+ routes:
+ - 10.255.200.21
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf6a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.23 - Peer: pod2-leaf10a'
+ routes:
+ - 10.255.200.23
+- VerifyRoutingProtocolModel:
+ filters:
+ tags:
+ - pod2-leaf6a
+ model: multi-agent
+ result_overwrite:
+ custom_field: 'Routing protocol model: multi-agent'
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf6a
+ result_overwrite:
+ custom_field: 'Route: 10.255.0.1 - Peer: super-spine1'
+ routes:
+ - 10.255.0.1
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf6a
+ result_overwrite:
+ custom_field: 'Route: 10.255.0.2 - Peer: super-spine2'
+ routes:
+ - 10.255.0.2
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf6a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.1 - Peer: pod1-spine1'
+ routes:
+ - 10.255.1.1
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf6a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.2 - Peer: pod1-spine2'
+ routes:
+ - 10.255.1.2
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf6a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.3 - Peer: pod1-spine3'
+ routes:
+ - 10.255.1.3
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf6a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.4 - Peer: pod1-spine4'
+ routes:
+ - 10.255.1.4
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf6a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.5 - Peer: pod1-leaf1a'
+ routes:
+ - 10.255.1.5
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf6a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.6 - Peer: pod1-leaf1b'
+ routes:
+ - 10.255.1.6
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf6a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.7 - Peer: pod1-leaf2a'
+ routes:
+ - 10.255.1.7
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf6a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.8 - Peer: pod1-leaf2b'
+ routes:
+ - 10.255.1.8
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf6a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.9 - Peer: pod1-leaf3a'
+ routes:
+ - 10.255.1.9
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf6a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.10 - Peer: pod1-leaf3b'
+ routes:
+ - 10.255.1.10
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf6a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.11 - Peer: pod1-leaf4a'
+ routes:
+ - 10.255.1.11
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf6a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.12 - Peer: pod1-leaf4b'
+ routes:
+ - 10.255.1.12
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf6a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.13 - Peer: pod1-leaf5a'
+ routes:
+ - 10.255.1.13
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf6a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.14 - Peer: pod1-leaf5b'
+ routes:
+ - 10.255.1.14
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf6a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.15 - Peer: pod1-leaf6a'
+ routes:
+ - 10.255.1.15
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf6a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.16 - Peer: pod1-leaf6b'
+ routes:
+ - 10.255.1.16
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf6a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.17 - Peer: pod1-leaf7a'
+ routes:
+ - 10.255.1.17
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf6a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.18 - Peer: pod1-leaf7b'
+ routes:
+ - 10.255.1.18
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf6a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.19 - Peer: pod1-leaf8a'
+ routes:
+ - 10.255.1.19
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf6a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.20 - Peer: pod1-leaf8b'
+ routes:
+ - 10.255.1.20
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf6a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.21 - Peer: pod1-leaf9a'
+ routes:
+ - 10.255.1.21
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf6a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.22 - Peer: pod1-leaf9b'
+ routes:
+ - 10.255.1.22
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf6a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.23 - Peer: pod1-leaf10a'
+ routes:
+ - 10.255.1.23
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf6a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.24 - Peer: pod1-leaf10b'
+ routes:
+ - 10.255.1.24
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf6a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.1 - Peer: pod2-spine1'
+ routes:
+ - 10.255.2.1
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf6a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.2 - Peer: pod2-spine2'
+ routes:
+ - 10.255.2.2
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf6a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.3 - Peer: pod2-spine3'
+ routes:
+ - 10.255.2.3
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf6a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.4 - Peer: pod2-spine4'
+ routes:
+ - 10.255.2.4
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf6a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.5 - Peer: pod2-leaf1a'
+ routes:
+ - 10.255.2.5
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf6a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.6 - Peer: pod2-leaf1b'
+ routes:
+ - 10.255.2.6
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf6a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.7 - Peer: pod2-leaf2a'
+ routes:
+ - 10.255.2.7
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf6a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.8 - Peer: pod2-leaf2b'
+ routes:
+ - 10.255.2.8
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf6a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.9 - Peer: pod2-leaf3a'
+ routes:
+ - 10.255.2.9
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf6a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.10 - Peer: pod2-leaf3b'
+ routes:
+ - 10.255.2.10
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf6a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.11 - Peer: pod2-leaf4a'
+ routes:
+ - 10.255.2.11
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf6a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.12 - Peer: pod2-leaf4b'
+ routes:
+ - 10.255.2.12
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf6a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.13 - Peer: pod2-leaf5a'
+ routes:
+ - 10.255.2.13
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf6a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.14 - Peer: pod2-leaf5b'
+ routes:
+ - 10.255.2.14
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf6a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.15 - Peer: pod2-leaf6a'
+ routes:
+ - 10.255.2.15
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf6a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.16 - Peer: pod2-leaf6b'
+ routes:
+ - 10.255.2.16
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf6a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.17 - Peer: pod2-leaf7a'
+ routes:
+ - 10.255.2.17
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf6a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.18 - Peer: pod2-leaf7b'
+ routes:
+ - 10.255.2.18
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf6a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.19 - Peer: pod2-leaf8a'
+ routes:
+ - 10.255.2.19
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf6a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.20 - Peer: pod2-leaf8b'
+ routes:
+ - 10.255.2.20
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf6a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.21 - Peer: pod2-leaf9a'
+ routes:
+ - 10.255.2.21
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf6a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.22 - Peer: pod2-leaf9b'
+ routes:
+ - 10.255.2.22
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf6a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.23 - Peer: pod2-leaf10a'
+ routes:
+ - 10.255.2.23
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf6a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.24 - Peer: pod2-leaf10b'
+ routes:
+ - 10.255.2.24
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf6a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.5 - Peer: pod1-leaf1a'
+ routes:
+ - 10.255.100.5
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf6a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.7 - Peer: pod1-leaf2a'
+ routes:
+ - 10.255.100.7
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf6a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.9 - Peer: pod1-leaf3a'
+ routes:
+ - 10.255.100.9
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf6a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.11 - Peer: pod1-leaf4a'
+ routes:
+ - 10.255.100.11
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf6a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.13 - Peer: pod1-leaf5a'
+ routes:
+ - 10.255.100.13
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf6a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.15 - Peer: pod1-leaf6a'
+ routes:
+ - 10.255.100.15
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf6a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.17 - Peer: pod1-leaf7a'
+ routes:
+ - 10.255.100.17
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf6a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.19 - Peer: pod1-leaf8a'
+ routes:
+ - 10.255.100.19
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf6a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.21 - Peer: pod1-leaf9a'
+ routes:
+ - 10.255.100.21
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf6a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.23 - Peer: pod1-leaf10a'
+ routes:
+ - 10.255.100.23
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf6a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.5 - Peer: pod2-leaf1a'
+ routes:
+ - 10.255.200.5
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf6a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.7 - Peer: pod2-leaf2a'
+ routes:
+ - 10.255.200.7
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf6a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.9 - Peer: pod2-leaf3a'
+ routes:
+ - 10.255.200.9
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf6a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.11 - Peer: pod2-leaf4a'
+ routes:
+ - 10.255.200.11
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf6a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.13 - Peer: pod2-leaf5a'
+ routes:
+ - 10.255.200.13
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf6a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.15 - Peer: pod2-leaf6a'
+ routes:
+ - 10.255.200.15
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf6a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.17 - Peer: pod2-leaf7a'
+ routes:
+ - 10.255.200.17
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf6a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.19 - Peer: pod2-leaf8a'
+ routes:
+ - 10.255.200.19
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf6a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.21 - Peer: pod2-leaf9a'
+ routes:
+ - 10.255.200.21
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf6a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.23 - Peer: pod2-leaf10a'
+ routes:
+ - 10.255.200.23
+- VerifyRoutingProtocolModel:
+ filters:
+ tags:
+ - pod2-leaf1a
+ model: multi-agent
+ result_overwrite:
+ custom_field: 'Routing protocol model: multi-agent'
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf1a
+ result_overwrite:
+ custom_field: 'Route: 10.255.0.1 - Peer: super-spine1'
+ routes:
+ - 10.255.0.1
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf1a
+ result_overwrite:
+ custom_field: 'Route: 10.255.0.2 - Peer: super-spine2'
+ routes:
+ - 10.255.0.2
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf1a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.1 - Peer: pod1-spine1'
+ routes:
+ - 10.255.1.1
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf1a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.2 - Peer: pod1-spine2'
+ routes:
+ - 10.255.1.2
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf1a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.3 - Peer: pod1-spine3'
+ routes:
+ - 10.255.1.3
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf1a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.4 - Peer: pod1-spine4'
+ routes:
+ - 10.255.1.4
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf1a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.5 - Peer: pod1-leaf1a'
+ routes:
+ - 10.255.1.5
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf1a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.6 - Peer: pod1-leaf1b'
+ routes:
+ - 10.255.1.6
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf1a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.7 - Peer: pod1-leaf2a'
+ routes:
+ - 10.255.1.7
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf1a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.8 - Peer: pod1-leaf2b'
+ routes:
+ - 10.255.1.8
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf1a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.9 - Peer: pod1-leaf3a'
+ routes:
+ - 10.255.1.9
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf1a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.10 - Peer: pod1-leaf3b'
+ routes:
+ - 10.255.1.10
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf1a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.11 - Peer: pod1-leaf4a'
+ routes:
+ - 10.255.1.11
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf1a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.12 - Peer: pod1-leaf4b'
+ routes:
+ - 10.255.1.12
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf1a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.13 - Peer: pod1-leaf5a'
+ routes:
+ - 10.255.1.13
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf1a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.14 - Peer: pod1-leaf5b'
+ routes:
+ - 10.255.1.14
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf1a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.15 - Peer: pod1-leaf6a'
+ routes:
+ - 10.255.1.15
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf1a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.16 - Peer: pod1-leaf6b'
+ routes:
+ - 10.255.1.16
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf1a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.17 - Peer: pod1-leaf7a'
+ routes:
+ - 10.255.1.17
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf1a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.18 - Peer: pod1-leaf7b'
+ routes:
+ - 10.255.1.18
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf1a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.19 - Peer: pod1-leaf8a'
+ routes:
+ - 10.255.1.19
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf1a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.20 - Peer: pod1-leaf8b'
+ routes:
+ - 10.255.1.20
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf1a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.21 - Peer: pod1-leaf9a'
+ routes:
+ - 10.255.1.21
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf1a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.22 - Peer: pod1-leaf9b'
+ routes:
+ - 10.255.1.22
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf1a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.23 - Peer: pod1-leaf10a'
+ routes:
+ - 10.255.1.23
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf1a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.24 - Peer: pod1-leaf10b'
+ routes:
+ - 10.255.1.24
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf1a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.1 - Peer: pod2-spine1'
+ routes:
+ - 10.255.2.1
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf1a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.2 - Peer: pod2-spine2'
+ routes:
+ - 10.255.2.2
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf1a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.3 - Peer: pod2-spine3'
+ routes:
+ - 10.255.2.3
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf1a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.4 - Peer: pod2-spine4'
+ routes:
+ - 10.255.2.4
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf1a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.5 - Peer: pod2-leaf1a'
+ routes:
+ - 10.255.2.5
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf1a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.6 - Peer: pod2-leaf1b'
+ routes:
+ - 10.255.2.6
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf1a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.7 - Peer: pod2-leaf2a'
+ routes:
+ - 10.255.2.7
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf1a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.8 - Peer: pod2-leaf2b'
+ routes:
+ - 10.255.2.8
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf1a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.9 - Peer: pod2-leaf3a'
+ routes:
+ - 10.255.2.9
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf1a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.10 - Peer: pod2-leaf3b'
+ routes:
+ - 10.255.2.10
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf1a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.11 - Peer: pod2-leaf4a'
+ routes:
+ - 10.255.2.11
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf1a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.12 - Peer: pod2-leaf4b'
+ routes:
+ - 10.255.2.12
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf1a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.13 - Peer: pod2-leaf5a'
+ routes:
+ - 10.255.2.13
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf1a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.14 - Peer: pod2-leaf5b'
+ routes:
+ - 10.255.2.14
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf1a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.15 - Peer: pod2-leaf6a'
+ routes:
+ - 10.255.2.15
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf1a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.16 - Peer: pod2-leaf6b'
+ routes:
+ - 10.255.2.16
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf1a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.17 - Peer: pod2-leaf7a'
+ routes:
+ - 10.255.2.17
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf1a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.18 - Peer: pod2-leaf7b'
+ routes:
+ - 10.255.2.18
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf1a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.19 - Peer: pod2-leaf8a'
+ routes:
+ - 10.255.2.19
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf1a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.20 - Peer: pod2-leaf8b'
+ routes:
+ - 10.255.2.20
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf1a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.21 - Peer: pod2-leaf9a'
+ routes:
+ - 10.255.2.21
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf1a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.22 - Peer: pod2-leaf9b'
+ routes:
+ - 10.255.2.22
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf1a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.23 - Peer: pod2-leaf10a'
+ routes:
+ - 10.255.2.23
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf1a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.24 - Peer: pod2-leaf10b'
+ routes:
+ - 10.255.2.24
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf1a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.5 - Peer: pod1-leaf1a'
+ routes:
+ - 10.255.100.5
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf1a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.7 - Peer: pod1-leaf2a'
+ routes:
+ - 10.255.100.7
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf1a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.9 - Peer: pod1-leaf3a'
+ routes:
+ - 10.255.100.9
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf1a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.11 - Peer: pod1-leaf4a'
+ routes:
+ - 10.255.100.11
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf1a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.13 - Peer: pod1-leaf5a'
+ routes:
+ - 10.255.100.13
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf1a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.15 - Peer: pod1-leaf6a'
+ routes:
+ - 10.255.100.15
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf1a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.17 - Peer: pod1-leaf7a'
+ routes:
+ - 10.255.100.17
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf1a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.19 - Peer: pod1-leaf8a'
+ routes:
+ - 10.255.100.19
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf1a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.21 - Peer: pod1-leaf9a'
+ routes:
+ - 10.255.100.21
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf1a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.23 - Peer: pod1-leaf10a'
+ routes:
+ - 10.255.100.23
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf1a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.5 - Peer: pod2-leaf1a'
+ routes:
+ - 10.255.200.5
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf1a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.7 - Peer: pod2-leaf2a'
+ routes:
+ - 10.255.200.7
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf1a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.9 - Peer: pod2-leaf3a'
+ routes:
+ - 10.255.200.9
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf1a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.11 - Peer: pod2-leaf4a'
+ routes:
+ - 10.255.200.11
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf1a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.13 - Peer: pod2-leaf5a'
+ routes:
+ - 10.255.200.13
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf1a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.15 - Peer: pod2-leaf6a'
+ routes:
+ - 10.255.200.15
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf1a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.17 - Peer: pod2-leaf7a'
+ routes:
+ - 10.255.200.17
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf1a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.19 - Peer: pod2-leaf8a'
+ routes:
+ - 10.255.200.19
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf1a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.21 - Peer: pod2-leaf9a'
+ routes:
+ - 10.255.200.21
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf1a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.23 - Peer: pod2-leaf10a'
+ routes:
+ - 10.255.200.23
+- VerifyRoutingProtocolModel:
+ filters:
+ tags:
+ - pod1-leaf10b
+ model: multi-agent
+ result_overwrite:
+ custom_field: 'Routing protocol model: multi-agent'
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf10b
+ result_overwrite:
+ custom_field: 'Route: 10.255.0.1 - Peer: super-spine1'
+ routes:
+ - 10.255.0.1
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf10b
+ result_overwrite:
+ custom_field: 'Route: 10.255.0.2 - Peer: super-spine2'
+ routes:
+ - 10.255.0.2
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf10b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.1 - Peer: pod1-spine1'
+ routes:
+ - 10.255.1.1
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf10b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.2 - Peer: pod1-spine2'
+ routes:
+ - 10.255.1.2
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf10b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.3 - Peer: pod1-spine3'
+ routes:
+ - 10.255.1.3
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf10b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.4 - Peer: pod1-spine4'
+ routes:
+ - 10.255.1.4
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf10b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.5 - Peer: pod1-leaf1a'
+ routes:
+ - 10.255.1.5
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf10b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.6 - Peer: pod1-leaf1b'
+ routes:
+ - 10.255.1.6
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf10b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.7 - Peer: pod1-leaf2a'
+ routes:
+ - 10.255.1.7
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf10b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.8 - Peer: pod1-leaf2b'
+ routes:
+ - 10.255.1.8
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf10b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.9 - Peer: pod1-leaf3a'
+ routes:
+ - 10.255.1.9
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf10b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.10 - Peer: pod1-leaf3b'
+ routes:
+ - 10.255.1.10
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf10b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.11 - Peer: pod1-leaf4a'
+ routes:
+ - 10.255.1.11
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf10b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.12 - Peer: pod1-leaf4b'
+ routes:
+ - 10.255.1.12
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf10b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.13 - Peer: pod1-leaf5a'
+ routes:
+ - 10.255.1.13
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf10b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.14 - Peer: pod1-leaf5b'
+ routes:
+ - 10.255.1.14
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf10b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.15 - Peer: pod1-leaf6a'
+ routes:
+ - 10.255.1.15
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf10b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.16 - Peer: pod1-leaf6b'
+ routes:
+ - 10.255.1.16
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf10b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.17 - Peer: pod1-leaf7a'
+ routes:
+ - 10.255.1.17
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf10b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.18 - Peer: pod1-leaf7b'
+ routes:
+ - 10.255.1.18
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf10b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.19 - Peer: pod1-leaf8a'
+ routes:
+ - 10.255.1.19
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf10b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.20 - Peer: pod1-leaf8b'
+ routes:
+ - 10.255.1.20
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf10b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.21 - Peer: pod1-leaf9a'
+ routes:
+ - 10.255.1.21
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf10b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.22 - Peer: pod1-leaf9b'
+ routes:
+ - 10.255.1.22
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf10b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.23 - Peer: pod1-leaf10a'
+ routes:
+ - 10.255.1.23
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf10b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.24 - Peer: pod1-leaf10b'
+ routes:
+ - 10.255.1.24
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf10b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.1 - Peer: pod2-spine1'
+ routes:
+ - 10.255.2.1
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf10b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.2 - Peer: pod2-spine2'
+ routes:
+ - 10.255.2.2
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf10b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.3 - Peer: pod2-spine3'
+ routes:
+ - 10.255.2.3
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf10b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.4 - Peer: pod2-spine4'
+ routes:
+ - 10.255.2.4
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf10b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.5 - Peer: pod2-leaf1a'
+ routes:
+ - 10.255.2.5
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf10b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.6 - Peer: pod2-leaf1b'
+ routes:
+ - 10.255.2.6
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf10b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.7 - Peer: pod2-leaf2a'
+ routes:
+ - 10.255.2.7
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf10b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.8 - Peer: pod2-leaf2b'
+ routes:
+ - 10.255.2.8
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf10b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.9 - Peer: pod2-leaf3a'
+ routes:
+ - 10.255.2.9
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf10b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.10 - Peer: pod2-leaf3b'
+ routes:
+ - 10.255.2.10
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf10b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.11 - Peer: pod2-leaf4a'
+ routes:
+ - 10.255.2.11
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf10b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.12 - Peer: pod2-leaf4b'
+ routes:
+ - 10.255.2.12
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf10b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.13 - Peer: pod2-leaf5a'
+ routes:
+ - 10.255.2.13
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf10b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.14 - Peer: pod2-leaf5b'
+ routes:
+ - 10.255.2.14
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf10b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.15 - Peer: pod2-leaf6a'
+ routes:
+ - 10.255.2.15
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf10b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.16 - Peer: pod2-leaf6b'
+ routes:
+ - 10.255.2.16
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf10b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.17 - Peer: pod2-leaf7a'
+ routes:
+ - 10.255.2.17
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf10b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.18 - Peer: pod2-leaf7b'
+ routes:
+ - 10.255.2.18
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf10b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.19 - Peer: pod2-leaf8a'
+ routes:
+ - 10.255.2.19
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf10b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.20 - Peer: pod2-leaf8b'
+ routes:
+ - 10.255.2.20
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf10b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.21 - Peer: pod2-leaf9a'
+ routes:
+ - 10.255.2.21
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf10b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.22 - Peer: pod2-leaf9b'
+ routes:
+ - 10.255.2.22
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf10b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.23 - Peer: pod2-leaf10a'
+ routes:
+ - 10.255.2.23
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf10b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.24 - Peer: pod2-leaf10b'
+ routes:
+ - 10.255.2.24
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf10b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.5 - Peer: pod1-leaf1a'
+ routes:
+ - 10.255.100.5
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf10b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.7 - Peer: pod1-leaf2a'
+ routes:
+ - 10.255.100.7
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf10b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.9 - Peer: pod1-leaf3a'
+ routes:
+ - 10.255.100.9
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf10b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.11 - Peer: pod1-leaf4a'
+ routes:
+ - 10.255.100.11
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf10b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.13 - Peer: pod1-leaf5a'
+ routes:
+ - 10.255.100.13
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf10b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.15 - Peer: pod1-leaf6a'
+ routes:
+ - 10.255.100.15
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf10b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.17 - Peer: pod1-leaf7a'
+ routes:
+ - 10.255.100.17
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf10b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.19 - Peer: pod1-leaf8a'
+ routes:
+ - 10.255.100.19
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf10b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.21 - Peer: pod1-leaf9a'
+ routes:
+ - 10.255.100.21
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf10b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.23 - Peer: pod1-leaf10a'
+ routes:
+ - 10.255.100.23
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf10b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.5 - Peer: pod2-leaf1a'
+ routes:
+ - 10.255.200.5
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf10b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.7 - Peer: pod2-leaf2a'
+ routes:
+ - 10.255.200.7
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf10b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.9 - Peer: pod2-leaf3a'
+ routes:
+ - 10.255.200.9
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf10b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.11 - Peer: pod2-leaf4a'
+ routes:
+ - 10.255.200.11
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf10b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.13 - Peer: pod2-leaf5a'
+ routes:
+ - 10.255.200.13
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf10b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.15 - Peer: pod2-leaf6a'
+ routes:
+ - 10.255.200.15
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf10b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.17 - Peer: pod2-leaf7a'
+ routes:
+ - 10.255.200.17
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf10b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.19 - Peer: pod2-leaf8a'
+ routes:
+ - 10.255.200.19
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf10b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.21 - Peer: pod2-leaf9a'
+ routes:
+ - 10.255.200.21
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf10b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.23 - Peer: pod2-leaf10a'
+ routes:
+ - 10.255.200.23
+- VerifyRoutingProtocolModel:
+ filters:
+ tags:
+ - pod1-leaf7a
+ model: multi-agent
+ result_overwrite:
+ custom_field: 'Routing protocol model: multi-agent'
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf7a
+ result_overwrite:
+ custom_field: 'Route: 10.255.0.1 - Peer: super-spine1'
+ routes:
+ - 10.255.0.1
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf7a
+ result_overwrite:
+ custom_field: 'Route: 10.255.0.2 - Peer: super-spine2'
+ routes:
+ - 10.255.0.2
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf7a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.1 - Peer: pod1-spine1'
+ routes:
+ - 10.255.1.1
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf7a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.2 - Peer: pod1-spine2'
+ routes:
+ - 10.255.1.2
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf7a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.3 - Peer: pod1-spine3'
+ routes:
+ - 10.255.1.3
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf7a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.4 - Peer: pod1-spine4'
+ routes:
+ - 10.255.1.4
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf7a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.5 - Peer: pod1-leaf1a'
+ routes:
+ - 10.255.1.5
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf7a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.6 - Peer: pod1-leaf1b'
+ routes:
+ - 10.255.1.6
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf7a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.7 - Peer: pod1-leaf2a'
+ routes:
+ - 10.255.1.7
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf7a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.8 - Peer: pod1-leaf2b'
+ routes:
+ - 10.255.1.8
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf7a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.9 - Peer: pod1-leaf3a'
+ routes:
+ - 10.255.1.9
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf7a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.10 - Peer: pod1-leaf3b'
+ routes:
+ - 10.255.1.10
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf7a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.11 - Peer: pod1-leaf4a'
+ routes:
+ - 10.255.1.11
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf7a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.12 - Peer: pod1-leaf4b'
+ routes:
+ - 10.255.1.12
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf7a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.13 - Peer: pod1-leaf5a'
+ routes:
+ - 10.255.1.13
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf7a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.14 - Peer: pod1-leaf5b'
+ routes:
+ - 10.255.1.14
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf7a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.15 - Peer: pod1-leaf6a'
+ routes:
+ - 10.255.1.15
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf7a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.16 - Peer: pod1-leaf6b'
+ routes:
+ - 10.255.1.16
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf7a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.17 - Peer: pod1-leaf7a'
+ routes:
+ - 10.255.1.17
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf7a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.18 - Peer: pod1-leaf7b'
+ routes:
+ - 10.255.1.18
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf7a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.19 - Peer: pod1-leaf8a'
+ routes:
+ - 10.255.1.19
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf7a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.20 - Peer: pod1-leaf8b'
+ routes:
+ - 10.255.1.20
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf7a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.21 - Peer: pod1-leaf9a'
+ routes:
+ - 10.255.1.21
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf7a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.22 - Peer: pod1-leaf9b'
+ routes:
+ - 10.255.1.22
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf7a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.23 - Peer: pod1-leaf10a'
+ routes:
+ - 10.255.1.23
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf7a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.24 - Peer: pod1-leaf10b'
+ routes:
+ - 10.255.1.24
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf7a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.1 - Peer: pod2-spine1'
+ routes:
+ - 10.255.2.1
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf7a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.2 - Peer: pod2-spine2'
+ routes:
+ - 10.255.2.2
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf7a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.3 - Peer: pod2-spine3'
+ routes:
+ - 10.255.2.3
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf7a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.4 - Peer: pod2-spine4'
+ routes:
+ - 10.255.2.4
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf7a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.5 - Peer: pod2-leaf1a'
+ routes:
+ - 10.255.2.5
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf7a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.6 - Peer: pod2-leaf1b'
+ routes:
+ - 10.255.2.6
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf7a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.7 - Peer: pod2-leaf2a'
+ routes:
+ - 10.255.2.7
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf7a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.8 - Peer: pod2-leaf2b'
+ routes:
+ - 10.255.2.8
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf7a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.9 - Peer: pod2-leaf3a'
+ routes:
+ - 10.255.2.9
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf7a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.10 - Peer: pod2-leaf3b'
+ routes:
+ - 10.255.2.10
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf7a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.11 - Peer: pod2-leaf4a'
+ routes:
+ - 10.255.2.11
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf7a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.12 - Peer: pod2-leaf4b'
+ routes:
+ - 10.255.2.12
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf7a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.13 - Peer: pod2-leaf5a'
+ routes:
+ - 10.255.2.13
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf7a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.14 - Peer: pod2-leaf5b'
+ routes:
+ - 10.255.2.14
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf7a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.15 - Peer: pod2-leaf6a'
+ routes:
+ - 10.255.2.15
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf7a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.16 - Peer: pod2-leaf6b'
+ routes:
+ - 10.255.2.16
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf7a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.17 - Peer: pod2-leaf7a'
+ routes:
+ - 10.255.2.17
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf7a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.18 - Peer: pod2-leaf7b'
+ routes:
+ - 10.255.2.18
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf7a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.19 - Peer: pod2-leaf8a'
+ routes:
+ - 10.255.2.19
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf7a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.20 - Peer: pod2-leaf8b'
+ routes:
+ - 10.255.2.20
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf7a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.21 - Peer: pod2-leaf9a'
+ routes:
+ - 10.255.2.21
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf7a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.22 - Peer: pod2-leaf9b'
+ routes:
+ - 10.255.2.22
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf7a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.23 - Peer: pod2-leaf10a'
+ routes:
+ - 10.255.2.23
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf7a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.24 - Peer: pod2-leaf10b'
+ routes:
+ - 10.255.2.24
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf7a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.5 - Peer: pod1-leaf1a'
+ routes:
+ - 10.255.100.5
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf7a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.7 - Peer: pod1-leaf2a'
+ routes:
+ - 10.255.100.7
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf7a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.9 - Peer: pod1-leaf3a'
+ routes:
+ - 10.255.100.9
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf7a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.11 - Peer: pod1-leaf4a'
+ routes:
+ - 10.255.100.11
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf7a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.13 - Peer: pod1-leaf5a'
+ routes:
+ - 10.255.100.13
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf7a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.15 - Peer: pod1-leaf6a'
+ routes:
+ - 10.255.100.15
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf7a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.17 - Peer: pod1-leaf7a'
+ routes:
+ - 10.255.100.17
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf7a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.19 - Peer: pod1-leaf8a'
+ routes:
+ - 10.255.100.19
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf7a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.21 - Peer: pod1-leaf9a'
+ routes:
+ - 10.255.100.21
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf7a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.23 - Peer: pod1-leaf10a'
+ routes:
+ - 10.255.100.23
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf7a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.5 - Peer: pod2-leaf1a'
+ routes:
+ - 10.255.200.5
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf7a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.7 - Peer: pod2-leaf2a'
+ routes:
+ - 10.255.200.7
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf7a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.9 - Peer: pod2-leaf3a'
+ routes:
+ - 10.255.200.9
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf7a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.11 - Peer: pod2-leaf4a'
+ routes:
+ - 10.255.200.11
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf7a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.13 - Peer: pod2-leaf5a'
+ routes:
+ - 10.255.200.13
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf7a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.15 - Peer: pod2-leaf6a'
+ routes:
+ - 10.255.200.15
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf7a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.17 - Peer: pod2-leaf7a'
+ routes:
+ - 10.255.200.17
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf7a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.19 - Peer: pod2-leaf8a'
+ routes:
+ - 10.255.200.19
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf7a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.21 - Peer: pod2-leaf9a'
+ routes:
+ - 10.255.200.21
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf7a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.23 - Peer: pod2-leaf10a'
+ routes:
+ - 10.255.200.23
+- VerifyRoutingProtocolModel:
+ filters:
+ tags:
+ - pod2-leaf10b
+ model: multi-agent
+ result_overwrite:
+ custom_field: 'Routing protocol model: multi-agent'
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf10b
+ result_overwrite:
+ custom_field: 'Route: 10.255.0.1 - Peer: super-spine1'
+ routes:
+ - 10.255.0.1
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf10b
+ result_overwrite:
+ custom_field: 'Route: 10.255.0.2 - Peer: super-spine2'
+ routes:
+ - 10.255.0.2
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf10b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.1 - Peer: pod1-spine1'
+ routes:
+ - 10.255.1.1
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf10b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.2 - Peer: pod1-spine2'
+ routes:
+ - 10.255.1.2
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf10b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.3 - Peer: pod1-spine3'
+ routes:
+ - 10.255.1.3
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf10b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.4 - Peer: pod1-spine4'
+ routes:
+ - 10.255.1.4
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf10b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.5 - Peer: pod1-leaf1a'
+ routes:
+ - 10.255.1.5
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf10b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.6 - Peer: pod1-leaf1b'
+ routes:
+ - 10.255.1.6
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf10b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.7 - Peer: pod1-leaf2a'
+ routes:
+ - 10.255.1.7
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf10b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.8 - Peer: pod1-leaf2b'
+ routes:
+ - 10.255.1.8
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf10b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.9 - Peer: pod1-leaf3a'
+ routes:
+ - 10.255.1.9
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf10b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.10 - Peer: pod1-leaf3b'
+ routes:
+ - 10.255.1.10
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf10b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.11 - Peer: pod1-leaf4a'
+ routes:
+ - 10.255.1.11
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf10b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.12 - Peer: pod1-leaf4b'
+ routes:
+ - 10.255.1.12
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf10b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.13 - Peer: pod1-leaf5a'
+ routes:
+ - 10.255.1.13
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf10b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.14 - Peer: pod1-leaf5b'
+ routes:
+ - 10.255.1.14
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf10b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.15 - Peer: pod1-leaf6a'
+ routes:
+ - 10.255.1.15
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf10b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.16 - Peer: pod1-leaf6b'
+ routes:
+ - 10.255.1.16
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf10b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.17 - Peer: pod1-leaf7a'
+ routes:
+ - 10.255.1.17
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf10b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.18 - Peer: pod1-leaf7b'
+ routes:
+ - 10.255.1.18
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf10b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.19 - Peer: pod1-leaf8a'
+ routes:
+ - 10.255.1.19
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf10b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.20 - Peer: pod1-leaf8b'
+ routes:
+ - 10.255.1.20
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf10b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.21 - Peer: pod1-leaf9a'
+ routes:
+ - 10.255.1.21
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf10b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.22 - Peer: pod1-leaf9b'
+ routes:
+ - 10.255.1.22
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf10b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.23 - Peer: pod1-leaf10a'
+ routes:
+ - 10.255.1.23
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf10b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.24 - Peer: pod1-leaf10b'
+ routes:
+ - 10.255.1.24
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf10b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.1 - Peer: pod2-spine1'
+ routes:
+ - 10.255.2.1
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf10b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.2 - Peer: pod2-spine2'
+ routes:
+ - 10.255.2.2
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf10b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.3 - Peer: pod2-spine3'
+ routes:
+ - 10.255.2.3
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf10b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.4 - Peer: pod2-spine4'
+ routes:
+ - 10.255.2.4
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf10b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.5 - Peer: pod2-leaf1a'
+ routes:
+ - 10.255.2.5
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf10b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.6 - Peer: pod2-leaf1b'
+ routes:
+ - 10.255.2.6
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf10b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.7 - Peer: pod2-leaf2a'
+ routes:
+ - 10.255.2.7
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf10b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.8 - Peer: pod2-leaf2b'
+ routes:
+ - 10.255.2.8
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf10b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.9 - Peer: pod2-leaf3a'
+ routes:
+ - 10.255.2.9
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf10b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.10 - Peer: pod2-leaf3b'
+ routes:
+ - 10.255.2.10
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf10b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.11 - Peer: pod2-leaf4a'
+ routes:
+ - 10.255.2.11
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf10b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.12 - Peer: pod2-leaf4b'
+ routes:
+ - 10.255.2.12
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf10b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.13 - Peer: pod2-leaf5a'
+ routes:
+ - 10.255.2.13
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf10b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.14 - Peer: pod2-leaf5b'
+ routes:
+ - 10.255.2.14
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf10b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.15 - Peer: pod2-leaf6a'
+ routes:
+ - 10.255.2.15
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf10b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.16 - Peer: pod2-leaf6b'
+ routes:
+ - 10.255.2.16
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf10b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.17 - Peer: pod2-leaf7a'
+ routes:
+ - 10.255.2.17
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf10b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.18 - Peer: pod2-leaf7b'
+ routes:
+ - 10.255.2.18
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf10b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.19 - Peer: pod2-leaf8a'
+ routes:
+ - 10.255.2.19
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf10b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.20 - Peer: pod2-leaf8b'
+ routes:
+ - 10.255.2.20
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf10b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.21 - Peer: pod2-leaf9a'
+ routes:
+ - 10.255.2.21
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf10b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.22 - Peer: pod2-leaf9b'
+ routes:
+ - 10.255.2.22
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf10b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.23 - Peer: pod2-leaf10a'
+ routes:
+ - 10.255.2.23
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf10b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.24 - Peer: pod2-leaf10b'
+ routes:
+ - 10.255.2.24
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf10b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.5 - Peer: pod1-leaf1a'
+ routes:
+ - 10.255.100.5
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf10b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.7 - Peer: pod1-leaf2a'
+ routes:
+ - 10.255.100.7
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf10b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.9 - Peer: pod1-leaf3a'
+ routes:
+ - 10.255.100.9
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf10b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.11 - Peer: pod1-leaf4a'
+ routes:
+ - 10.255.100.11
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf10b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.13 - Peer: pod1-leaf5a'
+ routes:
+ - 10.255.100.13
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf10b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.15 - Peer: pod1-leaf6a'
+ routes:
+ - 10.255.100.15
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf10b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.17 - Peer: pod1-leaf7a'
+ routes:
+ - 10.255.100.17
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf10b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.19 - Peer: pod1-leaf8a'
+ routes:
+ - 10.255.100.19
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf10b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.21 - Peer: pod1-leaf9a'
+ routes:
+ - 10.255.100.21
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf10b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.23 - Peer: pod1-leaf10a'
+ routes:
+ - 10.255.100.23
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf10b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.5 - Peer: pod2-leaf1a'
+ routes:
+ - 10.255.200.5
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf10b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.7 - Peer: pod2-leaf2a'
+ routes:
+ - 10.255.200.7
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf10b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.9 - Peer: pod2-leaf3a'
+ routes:
+ - 10.255.200.9
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf10b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.11 - Peer: pod2-leaf4a'
+ routes:
+ - 10.255.200.11
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf10b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.13 - Peer: pod2-leaf5a'
+ routes:
+ - 10.255.200.13
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf10b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.15 - Peer: pod2-leaf6a'
+ routes:
+ - 10.255.200.15
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf10b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.17 - Peer: pod2-leaf7a'
+ routes:
+ - 10.255.200.17
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf10b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.19 - Peer: pod2-leaf8a'
+ routes:
+ - 10.255.200.19
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf10b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.21 - Peer: pod2-leaf9a'
+ routes:
+ - 10.255.200.21
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf10b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.23 - Peer: pod2-leaf10a'
+ routes:
+ - 10.255.200.23
+- VerifyRoutingProtocolModel:
+ filters:
+ tags:
+ - pod2-leaf10a
+ model: multi-agent
+ result_overwrite:
+ custom_field: 'Routing protocol model: multi-agent'
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf10a
+ result_overwrite:
+ custom_field: 'Route: 10.255.0.1 - Peer: super-spine1'
+ routes:
+ - 10.255.0.1
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf10a
+ result_overwrite:
+ custom_field: 'Route: 10.255.0.2 - Peer: super-spine2'
+ routes:
+ - 10.255.0.2
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf10a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.1 - Peer: pod1-spine1'
+ routes:
+ - 10.255.1.1
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf10a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.2 - Peer: pod1-spine2'
+ routes:
+ - 10.255.1.2
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf10a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.3 - Peer: pod1-spine3'
+ routes:
+ - 10.255.1.3
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf10a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.4 - Peer: pod1-spine4'
+ routes:
+ - 10.255.1.4
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf10a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.5 - Peer: pod1-leaf1a'
+ routes:
+ - 10.255.1.5
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf10a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.6 - Peer: pod1-leaf1b'
+ routes:
+ - 10.255.1.6
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf10a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.7 - Peer: pod1-leaf2a'
+ routes:
+ - 10.255.1.7
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf10a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.8 - Peer: pod1-leaf2b'
+ routes:
+ - 10.255.1.8
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf10a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.9 - Peer: pod1-leaf3a'
+ routes:
+ - 10.255.1.9
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf10a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.10 - Peer: pod1-leaf3b'
+ routes:
+ - 10.255.1.10
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf10a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.11 - Peer: pod1-leaf4a'
+ routes:
+ - 10.255.1.11
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf10a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.12 - Peer: pod1-leaf4b'
+ routes:
+ - 10.255.1.12
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf10a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.13 - Peer: pod1-leaf5a'
+ routes:
+ - 10.255.1.13
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf10a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.14 - Peer: pod1-leaf5b'
+ routes:
+ - 10.255.1.14
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf10a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.15 - Peer: pod1-leaf6a'
+ routes:
+ - 10.255.1.15
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf10a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.16 - Peer: pod1-leaf6b'
+ routes:
+ - 10.255.1.16
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf10a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.17 - Peer: pod1-leaf7a'
+ routes:
+ - 10.255.1.17
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf10a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.18 - Peer: pod1-leaf7b'
+ routes:
+ - 10.255.1.18
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf10a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.19 - Peer: pod1-leaf8a'
+ routes:
+ - 10.255.1.19
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf10a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.20 - Peer: pod1-leaf8b'
+ routes:
+ - 10.255.1.20
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf10a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.21 - Peer: pod1-leaf9a'
+ routes:
+ - 10.255.1.21
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf10a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.22 - Peer: pod1-leaf9b'
+ routes:
+ - 10.255.1.22
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf10a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.23 - Peer: pod1-leaf10a'
+ routes:
+ - 10.255.1.23
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf10a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.24 - Peer: pod1-leaf10b'
+ routes:
+ - 10.255.1.24
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf10a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.1 - Peer: pod2-spine1'
+ routes:
+ - 10.255.2.1
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf10a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.2 - Peer: pod2-spine2'
+ routes:
+ - 10.255.2.2
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf10a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.3 - Peer: pod2-spine3'
+ routes:
+ - 10.255.2.3
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf10a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.4 - Peer: pod2-spine4'
+ routes:
+ - 10.255.2.4
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf10a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.5 - Peer: pod2-leaf1a'
+ routes:
+ - 10.255.2.5
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf10a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.6 - Peer: pod2-leaf1b'
+ routes:
+ - 10.255.2.6
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf10a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.7 - Peer: pod2-leaf2a'
+ routes:
+ - 10.255.2.7
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf10a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.8 - Peer: pod2-leaf2b'
+ routes:
+ - 10.255.2.8
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf10a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.9 - Peer: pod2-leaf3a'
+ routes:
+ - 10.255.2.9
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf10a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.10 - Peer: pod2-leaf3b'
+ routes:
+ - 10.255.2.10
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf10a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.11 - Peer: pod2-leaf4a'
+ routes:
+ - 10.255.2.11
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf10a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.12 - Peer: pod2-leaf4b'
+ routes:
+ - 10.255.2.12
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf10a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.13 - Peer: pod2-leaf5a'
+ routes:
+ - 10.255.2.13
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf10a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.14 - Peer: pod2-leaf5b'
+ routes:
+ - 10.255.2.14
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf10a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.15 - Peer: pod2-leaf6a'
+ routes:
+ - 10.255.2.15
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf10a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.16 - Peer: pod2-leaf6b'
+ routes:
+ - 10.255.2.16
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf10a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.17 - Peer: pod2-leaf7a'
+ routes:
+ - 10.255.2.17
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf10a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.18 - Peer: pod2-leaf7b'
+ routes:
+ - 10.255.2.18
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf10a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.19 - Peer: pod2-leaf8a'
+ routes:
+ - 10.255.2.19
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf10a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.20 - Peer: pod2-leaf8b'
+ routes:
+ - 10.255.2.20
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf10a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.21 - Peer: pod2-leaf9a'
+ routes:
+ - 10.255.2.21
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf10a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.22 - Peer: pod2-leaf9b'
+ routes:
+ - 10.255.2.22
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf10a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.23 - Peer: pod2-leaf10a'
+ routes:
+ - 10.255.2.23
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf10a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.24 - Peer: pod2-leaf10b'
+ routes:
+ - 10.255.2.24
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf10a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.5 - Peer: pod1-leaf1a'
+ routes:
+ - 10.255.100.5
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf10a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.7 - Peer: pod1-leaf2a'
+ routes:
+ - 10.255.100.7
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf10a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.9 - Peer: pod1-leaf3a'
+ routes:
+ - 10.255.100.9
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf10a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.11 - Peer: pod1-leaf4a'
+ routes:
+ - 10.255.100.11
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf10a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.13 - Peer: pod1-leaf5a'
+ routes:
+ - 10.255.100.13
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf10a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.15 - Peer: pod1-leaf6a'
+ routes:
+ - 10.255.100.15
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf10a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.17 - Peer: pod1-leaf7a'
+ routes:
+ - 10.255.100.17
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf10a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.19 - Peer: pod1-leaf8a'
+ routes:
+ - 10.255.100.19
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf10a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.21 - Peer: pod1-leaf9a'
+ routes:
+ - 10.255.100.21
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf10a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.23 - Peer: pod1-leaf10a'
+ routes:
+ - 10.255.100.23
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf10a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.5 - Peer: pod2-leaf1a'
+ routes:
+ - 10.255.200.5
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf10a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.7 - Peer: pod2-leaf2a'
+ routes:
+ - 10.255.200.7
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf10a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.9 - Peer: pod2-leaf3a'
+ routes:
+ - 10.255.200.9
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf10a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.11 - Peer: pod2-leaf4a'
+ routes:
+ - 10.255.200.11
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf10a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.13 - Peer: pod2-leaf5a'
+ routes:
+ - 10.255.200.13
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf10a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.15 - Peer: pod2-leaf6a'
+ routes:
+ - 10.255.200.15
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf10a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.17 - Peer: pod2-leaf7a'
+ routes:
+ - 10.255.200.17
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf10a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.19 - Peer: pod2-leaf8a'
+ routes:
+ - 10.255.200.19
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf10a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.21 - Peer: pod2-leaf9a'
+ routes:
+ - 10.255.200.21
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf10a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.23 - Peer: pod2-leaf10a'
+ routes:
+ - 10.255.200.23
+- VerifyRoutingProtocolModel:
+ filters:
+ tags:
+ - pod2-spine3
+ model: multi-agent
+ result_overwrite:
+ custom_field: 'Routing protocol model: multi-agent'
+- VerifyRoutingProtocolModel:
+ filters:
+ tags:
+ - pod1-leaf7b
+ model: multi-agent
+ result_overwrite:
+ custom_field: 'Routing protocol model: multi-agent'
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf7b
+ result_overwrite:
+ custom_field: 'Route: 10.255.0.1 - Peer: super-spine1'
+ routes:
+ - 10.255.0.1
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf7b
+ result_overwrite:
+ custom_field: 'Route: 10.255.0.2 - Peer: super-spine2'
+ routes:
+ - 10.255.0.2
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf7b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.1 - Peer: pod1-spine1'
+ routes:
+ - 10.255.1.1
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf7b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.2 - Peer: pod1-spine2'
+ routes:
+ - 10.255.1.2
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf7b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.3 - Peer: pod1-spine3'
+ routes:
+ - 10.255.1.3
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf7b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.4 - Peer: pod1-spine4'
+ routes:
+ - 10.255.1.4
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf7b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.5 - Peer: pod1-leaf1a'
+ routes:
+ - 10.255.1.5
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf7b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.6 - Peer: pod1-leaf1b'
+ routes:
+ - 10.255.1.6
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf7b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.7 - Peer: pod1-leaf2a'
+ routes:
+ - 10.255.1.7
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf7b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.8 - Peer: pod1-leaf2b'
+ routes:
+ - 10.255.1.8
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf7b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.9 - Peer: pod1-leaf3a'
+ routes:
+ - 10.255.1.9
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf7b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.10 - Peer: pod1-leaf3b'
+ routes:
+ - 10.255.1.10
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf7b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.11 - Peer: pod1-leaf4a'
+ routes:
+ - 10.255.1.11
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf7b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.12 - Peer: pod1-leaf4b'
+ routes:
+ - 10.255.1.12
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf7b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.13 - Peer: pod1-leaf5a'
+ routes:
+ - 10.255.1.13
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf7b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.14 - Peer: pod1-leaf5b'
+ routes:
+ - 10.255.1.14
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf7b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.15 - Peer: pod1-leaf6a'
+ routes:
+ - 10.255.1.15
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf7b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.16 - Peer: pod1-leaf6b'
+ routes:
+ - 10.255.1.16
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf7b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.17 - Peer: pod1-leaf7a'
+ routes:
+ - 10.255.1.17
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf7b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.18 - Peer: pod1-leaf7b'
+ routes:
+ - 10.255.1.18
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf7b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.19 - Peer: pod1-leaf8a'
+ routes:
+ - 10.255.1.19
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf7b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.20 - Peer: pod1-leaf8b'
+ routes:
+ - 10.255.1.20
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf7b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.21 - Peer: pod1-leaf9a'
+ routes:
+ - 10.255.1.21
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf7b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.22 - Peer: pod1-leaf9b'
+ routes:
+ - 10.255.1.22
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf7b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.23 - Peer: pod1-leaf10a'
+ routes:
+ - 10.255.1.23
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf7b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.24 - Peer: pod1-leaf10b'
+ routes:
+ - 10.255.1.24
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf7b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.1 - Peer: pod2-spine1'
+ routes:
+ - 10.255.2.1
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf7b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.2 - Peer: pod2-spine2'
+ routes:
+ - 10.255.2.2
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf7b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.3 - Peer: pod2-spine3'
+ routes:
+ - 10.255.2.3
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf7b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.4 - Peer: pod2-spine4'
+ routes:
+ - 10.255.2.4
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf7b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.5 - Peer: pod2-leaf1a'
+ routes:
+ - 10.255.2.5
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf7b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.6 - Peer: pod2-leaf1b'
+ routes:
+ - 10.255.2.6
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf7b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.7 - Peer: pod2-leaf2a'
+ routes:
+ - 10.255.2.7
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf7b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.8 - Peer: pod2-leaf2b'
+ routes:
+ - 10.255.2.8
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf7b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.9 - Peer: pod2-leaf3a'
+ routes:
+ - 10.255.2.9
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf7b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.10 - Peer: pod2-leaf3b'
+ routes:
+ - 10.255.2.10
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf7b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.11 - Peer: pod2-leaf4a'
+ routes:
+ - 10.255.2.11
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf7b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.12 - Peer: pod2-leaf4b'
+ routes:
+ - 10.255.2.12
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf7b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.13 - Peer: pod2-leaf5a'
+ routes:
+ - 10.255.2.13
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf7b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.14 - Peer: pod2-leaf5b'
+ routes:
+ - 10.255.2.14
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf7b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.15 - Peer: pod2-leaf6a'
+ routes:
+ - 10.255.2.15
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf7b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.16 - Peer: pod2-leaf6b'
+ routes:
+ - 10.255.2.16
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf7b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.17 - Peer: pod2-leaf7a'
+ routes:
+ - 10.255.2.17
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf7b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.18 - Peer: pod2-leaf7b'
+ routes:
+ - 10.255.2.18
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf7b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.19 - Peer: pod2-leaf8a'
+ routes:
+ - 10.255.2.19
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf7b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.20 - Peer: pod2-leaf8b'
+ routes:
+ - 10.255.2.20
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf7b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.21 - Peer: pod2-leaf9a'
+ routes:
+ - 10.255.2.21
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf7b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.22 - Peer: pod2-leaf9b'
+ routes:
+ - 10.255.2.22
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf7b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.23 - Peer: pod2-leaf10a'
+ routes:
+ - 10.255.2.23
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf7b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.24 - Peer: pod2-leaf10b'
+ routes:
+ - 10.255.2.24
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf7b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.5 - Peer: pod1-leaf1a'
+ routes:
+ - 10.255.100.5
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf7b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.7 - Peer: pod1-leaf2a'
+ routes:
+ - 10.255.100.7
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf7b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.9 - Peer: pod1-leaf3a'
+ routes:
+ - 10.255.100.9
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf7b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.11 - Peer: pod1-leaf4a'
+ routes:
+ - 10.255.100.11
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf7b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.13 - Peer: pod1-leaf5a'
+ routes:
+ - 10.255.100.13
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf7b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.15 - Peer: pod1-leaf6a'
+ routes:
+ - 10.255.100.15
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf7b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.17 - Peer: pod1-leaf7a'
+ routes:
+ - 10.255.100.17
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf7b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.19 - Peer: pod1-leaf8a'
+ routes:
+ - 10.255.100.19
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf7b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.21 - Peer: pod1-leaf9a'
+ routes:
+ - 10.255.100.21
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf7b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.23 - Peer: pod1-leaf10a'
+ routes:
+ - 10.255.100.23
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf7b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.5 - Peer: pod2-leaf1a'
+ routes:
+ - 10.255.200.5
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf7b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.7 - Peer: pod2-leaf2a'
+ routes:
+ - 10.255.200.7
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf7b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.9 - Peer: pod2-leaf3a'
+ routes:
+ - 10.255.200.9
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf7b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.11 - Peer: pod2-leaf4a'
+ routes:
+ - 10.255.200.11
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf7b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.13 - Peer: pod2-leaf5a'
+ routes:
+ - 10.255.200.13
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf7b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.15 - Peer: pod2-leaf6a'
+ routes:
+ - 10.255.200.15
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf7b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.17 - Peer: pod2-leaf7a'
+ routes:
+ - 10.255.200.17
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf7b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.19 - Peer: pod2-leaf8a'
+ routes:
+ - 10.255.200.19
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf7b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.21 - Peer: pod2-leaf9a'
+ routes:
+ - 10.255.200.21
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf7b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.23 - Peer: pod2-leaf10a'
+ routes:
+ - 10.255.200.23
+- VerifyRoutingProtocolModel:
+ filters:
+ tags:
+ - pod1-leaf10a
+ model: multi-agent
+ result_overwrite:
+ custom_field: 'Routing protocol model: multi-agent'
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf10a
+ result_overwrite:
+ custom_field: 'Route: 10.255.0.1 - Peer: super-spine1'
+ routes:
+ - 10.255.0.1
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf10a
+ result_overwrite:
+ custom_field: 'Route: 10.255.0.2 - Peer: super-spine2'
+ routes:
+ - 10.255.0.2
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf10a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.1 - Peer: pod1-spine1'
+ routes:
+ - 10.255.1.1
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf10a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.2 - Peer: pod1-spine2'
+ routes:
+ - 10.255.1.2
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf10a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.3 - Peer: pod1-spine3'
+ routes:
+ - 10.255.1.3
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf10a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.4 - Peer: pod1-spine4'
+ routes:
+ - 10.255.1.4
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf10a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.5 - Peer: pod1-leaf1a'
+ routes:
+ - 10.255.1.5
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf10a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.6 - Peer: pod1-leaf1b'
+ routes:
+ - 10.255.1.6
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf10a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.7 - Peer: pod1-leaf2a'
+ routes:
+ - 10.255.1.7
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf10a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.8 - Peer: pod1-leaf2b'
+ routes:
+ - 10.255.1.8
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf10a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.9 - Peer: pod1-leaf3a'
+ routes:
+ - 10.255.1.9
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf10a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.10 - Peer: pod1-leaf3b'
+ routes:
+ - 10.255.1.10
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf10a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.11 - Peer: pod1-leaf4a'
+ routes:
+ - 10.255.1.11
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf10a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.12 - Peer: pod1-leaf4b'
+ routes:
+ - 10.255.1.12
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf10a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.13 - Peer: pod1-leaf5a'
+ routes:
+ - 10.255.1.13
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf10a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.14 - Peer: pod1-leaf5b'
+ routes:
+ - 10.255.1.14
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf10a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.15 - Peer: pod1-leaf6a'
+ routes:
+ - 10.255.1.15
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf10a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.16 - Peer: pod1-leaf6b'
+ routes:
+ - 10.255.1.16
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf10a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.17 - Peer: pod1-leaf7a'
+ routes:
+ - 10.255.1.17
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf10a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.18 - Peer: pod1-leaf7b'
+ routes:
+ - 10.255.1.18
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf10a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.19 - Peer: pod1-leaf8a'
+ routes:
+ - 10.255.1.19
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf10a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.20 - Peer: pod1-leaf8b'
+ routes:
+ - 10.255.1.20
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf10a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.21 - Peer: pod1-leaf9a'
+ routes:
+ - 10.255.1.21
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf10a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.22 - Peer: pod1-leaf9b'
+ routes:
+ - 10.255.1.22
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf10a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.23 - Peer: pod1-leaf10a'
+ routes:
+ - 10.255.1.23
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf10a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.24 - Peer: pod1-leaf10b'
+ routes:
+ - 10.255.1.24
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf10a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.1 - Peer: pod2-spine1'
+ routes:
+ - 10.255.2.1
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf10a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.2 - Peer: pod2-spine2'
+ routes:
+ - 10.255.2.2
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf10a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.3 - Peer: pod2-spine3'
+ routes:
+ - 10.255.2.3
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf10a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.4 - Peer: pod2-spine4'
+ routes:
+ - 10.255.2.4
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf10a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.5 - Peer: pod2-leaf1a'
+ routes:
+ - 10.255.2.5
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf10a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.6 - Peer: pod2-leaf1b'
+ routes:
+ - 10.255.2.6
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf10a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.7 - Peer: pod2-leaf2a'
+ routes:
+ - 10.255.2.7
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf10a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.8 - Peer: pod2-leaf2b'
+ routes:
+ - 10.255.2.8
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf10a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.9 - Peer: pod2-leaf3a'
+ routes:
+ - 10.255.2.9
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf10a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.10 - Peer: pod2-leaf3b'
+ routes:
+ - 10.255.2.10
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf10a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.11 - Peer: pod2-leaf4a'
+ routes:
+ - 10.255.2.11
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf10a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.12 - Peer: pod2-leaf4b'
+ routes:
+ - 10.255.2.12
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf10a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.13 - Peer: pod2-leaf5a'
+ routes:
+ - 10.255.2.13
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf10a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.14 - Peer: pod2-leaf5b'
+ routes:
+ - 10.255.2.14
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf10a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.15 - Peer: pod2-leaf6a'
+ routes:
+ - 10.255.2.15
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf10a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.16 - Peer: pod2-leaf6b'
+ routes:
+ - 10.255.2.16
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf10a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.17 - Peer: pod2-leaf7a'
+ routes:
+ - 10.255.2.17
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf10a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.18 - Peer: pod2-leaf7b'
+ routes:
+ - 10.255.2.18
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf10a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.19 - Peer: pod2-leaf8a'
+ routes:
+ - 10.255.2.19
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf10a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.20 - Peer: pod2-leaf8b'
+ routes:
+ - 10.255.2.20
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf10a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.21 - Peer: pod2-leaf9a'
+ routes:
+ - 10.255.2.21
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf10a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.22 - Peer: pod2-leaf9b'
+ routes:
+ - 10.255.2.22
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf10a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.23 - Peer: pod2-leaf10a'
+ routes:
+ - 10.255.2.23
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf10a
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.24 - Peer: pod2-leaf10b'
+ routes:
+ - 10.255.2.24
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf10a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.5 - Peer: pod1-leaf1a'
+ routes:
+ - 10.255.100.5
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf10a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.7 - Peer: pod1-leaf2a'
+ routes:
+ - 10.255.100.7
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf10a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.9 - Peer: pod1-leaf3a'
+ routes:
+ - 10.255.100.9
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf10a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.11 - Peer: pod1-leaf4a'
+ routes:
+ - 10.255.100.11
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf10a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.13 - Peer: pod1-leaf5a'
+ routes:
+ - 10.255.100.13
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf10a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.15 - Peer: pod1-leaf6a'
+ routes:
+ - 10.255.100.15
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf10a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.17 - Peer: pod1-leaf7a'
+ routes:
+ - 10.255.100.17
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf10a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.19 - Peer: pod1-leaf8a'
+ routes:
+ - 10.255.100.19
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf10a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.21 - Peer: pod1-leaf9a'
+ routes:
+ - 10.255.100.21
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf10a
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.23 - Peer: pod1-leaf10a'
+ routes:
+ - 10.255.100.23
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf10a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.5 - Peer: pod2-leaf1a'
+ routes:
+ - 10.255.200.5
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf10a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.7 - Peer: pod2-leaf2a'
+ routes:
+ - 10.255.200.7
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf10a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.9 - Peer: pod2-leaf3a'
+ routes:
+ - 10.255.200.9
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf10a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.11 - Peer: pod2-leaf4a'
+ routes:
+ - 10.255.200.11
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf10a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.13 - Peer: pod2-leaf5a'
+ routes:
+ - 10.255.200.13
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf10a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.15 - Peer: pod2-leaf6a'
+ routes:
+ - 10.255.200.15
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf10a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.17 - Peer: pod2-leaf7a'
+ routes:
+ - 10.255.200.17
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf10a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.19 - Peer: pod2-leaf8a'
+ routes:
+ - 10.255.200.19
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf10a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.21 - Peer: pod2-leaf9a'
+ routes:
+ - 10.255.200.21
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf10a
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.23 - Peer: pod2-leaf10a'
+ routes:
+ - 10.255.200.23
+- VerifyRoutingProtocolModel:
+ filters:
+ tags:
+ - pod2-leaf6b
+ model: multi-agent
+ result_overwrite:
+ custom_field: 'Routing protocol model: multi-agent'
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf6b
+ result_overwrite:
+ custom_field: 'Route: 10.255.0.1 - Peer: super-spine1'
+ routes:
+ - 10.255.0.1
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf6b
+ result_overwrite:
+ custom_field: 'Route: 10.255.0.2 - Peer: super-spine2'
+ routes:
+ - 10.255.0.2
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf6b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.1 - Peer: pod1-spine1'
+ routes:
+ - 10.255.1.1
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf6b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.2 - Peer: pod1-spine2'
+ routes:
+ - 10.255.1.2
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf6b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.3 - Peer: pod1-spine3'
+ routes:
+ - 10.255.1.3
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf6b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.4 - Peer: pod1-spine4'
+ routes:
+ - 10.255.1.4
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf6b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.5 - Peer: pod1-leaf1a'
+ routes:
+ - 10.255.1.5
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf6b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.6 - Peer: pod1-leaf1b'
+ routes:
+ - 10.255.1.6
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf6b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.7 - Peer: pod1-leaf2a'
+ routes:
+ - 10.255.1.7
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf6b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.8 - Peer: pod1-leaf2b'
+ routes:
+ - 10.255.1.8
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf6b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.9 - Peer: pod1-leaf3a'
+ routes:
+ - 10.255.1.9
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf6b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.10 - Peer: pod1-leaf3b'
+ routes:
+ - 10.255.1.10
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf6b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.11 - Peer: pod1-leaf4a'
+ routes:
+ - 10.255.1.11
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf6b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.12 - Peer: pod1-leaf4b'
+ routes:
+ - 10.255.1.12
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf6b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.13 - Peer: pod1-leaf5a'
+ routes:
+ - 10.255.1.13
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf6b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.14 - Peer: pod1-leaf5b'
+ routes:
+ - 10.255.1.14
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf6b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.15 - Peer: pod1-leaf6a'
+ routes:
+ - 10.255.1.15
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf6b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.16 - Peer: pod1-leaf6b'
+ routes:
+ - 10.255.1.16
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf6b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.17 - Peer: pod1-leaf7a'
+ routes:
+ - 10.255.1.17
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf6b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.18 - Peer: pod1-leaf7b'
+ routes:
+ - 10.255.1.18
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf6b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.19 - Peer: pod1-leaf8a'
+ routes:
+ - 10.255.1.19
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf6b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.20 - Peer: pod1-leaf8b'
+ routes:
+ - 10.255.1.20
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf6b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.21 - Peer: pod1-leaf9a'
+ routes:
+ - 10.255.1.21
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf6b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.22 - Peer: pod1-leaf9b'
+ routes:
+ - 10.255.1.22
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf6b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.23 - Peer: pod1-leaf10a'
+ routes:
+ - 10.255.1.23
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf6b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.24 - Peer: pod1-leaf10b'
+ routes:
+ - 10.255.1.24
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf6b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.1 - Peer: pod2-spine1'
+ routes:
+ - 10.255.2.1
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf6b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.2 - Peer: pod2-spine2'
+ routes:
+ - 10.255.2.2
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf6b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.3 - Peer: pod2-spine3'
+ routes:
+ - 10.255.2.3
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf6b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.4 - Peer: pod2-spine4'
+ routes:
+ - 10.255.2.4
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf6b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.5 - Peer: pod2-leaf1a'
+ routes:
+ - 10.255.2.5
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf6b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.6 - Peer: pod2-leaf1b'
+ routes:
+ - 10.255.2.6
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf6b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.7 - Peer: pod2-leaf2a'
+ routes:
+ - 10.255.2.7
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf6b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.8 - Peer: pod2-leaf2b'
+ routes:
+ - 10.255.2.8
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf6b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.9 - Peer: pod2-leaf3a'
+ routes:
+ - 10.255.2.9
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf6b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.10 - Peer: pod2-leaf3b'
+ routes:
+ - 10.255.2.10
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf6b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.11 - Peer: pod2-leaf4a'
+ routes:
+ - 10.255.2.11
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf6b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.12 - Peer: pod2-leaf4b'
+ routes:
+ - 10.255.2.12
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf6b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.13 - Peer: pod2-leaf5a'
+ routes:
+ - 10.255.2.13
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf6b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.14 - Peer: pod2-leaf5b'
+ routes:
+ - 10.255.2.14
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf6b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.15 - Peer: pod2-leaf6a'
+ routes:
+ - 10.255.2.15
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf6b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.16 - Peer: pod2-leaf6b'
+ routes:
+ - 10.255.2.16
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf6b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.17 - Peer: pod2-leaf7a'
+ routes:
+ - 10.255.2.17
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf6b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.18 - Peer: pod2-leaf7b'
+ routes:
+ - 10.255.2.18
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf6b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.19 - Peer: pod2-leaf8a'
+ routes:
+ - 10.255.2.19
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf6b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.20 - Peer: pod2-leaf8b'
+ routes:
+ - 10.255.2.20
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf6b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.21 - Peer: pod2-leaf9a'
+ routes:
+ - 10.255.2.21
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf6b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.22 - Peer: pod2-leaf9b'
+ routes:
+ - 10.255.2.22
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf6b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.23 - Peer: pod2-leaf10a'
+ routes:
+ - 10.255.2.23
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf6b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.24 - Peer: pod2-leaf10b'
+ routes:
+ - 10.255.2.24
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf6b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.5 - Peer: pod1-leaf1a'
+ routes:
+ - 10.255.100.5
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf6b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.7 - Peer: pod1-leaf2a'
+ routes:
+ - 10.255.100.7
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf6b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.9 - Peer: pod1-leaf3a'
+ routes:
+ - 10.255.100.9
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf6b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.11 - Peer: pod1-leaf4a'
+ routes:
+ - 10.255.100.11
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf6b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.13 - Peer: pod1-leaf5a'
+ routes:
+ - 10.255.100.13
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf6b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.15 - Peer: pod1-leaf6a'
+ routes:
+ - 10.255.100.15
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf6b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.17 - Peer: pod1-leaf7a'
+ routes:
+ - 10.255.100.17
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf6b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.19 - Peer: pod1-leaf8a'
+ routes:
+ - 10.255.100.19
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf6b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.21 - Peer: pod1-leaf9a'
+ routes:
+ - 10.255.100.21
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf6b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.23 - Peer: pod1-leaf10a'
+ routes:
+ - 10.255.100.23
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf6b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.5 - Peer: pod2-leaf1a'
+ routes:
+ - 10.255.200.5
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf6b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.7 - Peer: pod2-leaf2a'
+ routes:
+ - 10.255.200.7
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf6b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.9 - Peer: pod2-leaf3a'
+ routes:
+ - 10.255.200.9
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf6b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.11 - Peer: pod2-leaf4a'
+ routes:
+ - 10.255.200.11
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf6b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.13 - Peer: pod2-leaf5a'
+ routes:
+ - 10.255.200.13
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf6b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.15 - Peer: pod2-leaf6a'
+ routes:
+ - 10.255.200.15
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf6b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.17 - Peer: pod2-leaf7a'
+ routes:
+ - 10.255.200.17
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf6b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.19 - Peer: pod2-leaf8a'
+ routes:
+ - 10.255.200.19
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf6b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.21 - Peer: pod2-leaf9a'
+ routes:
+ - 10.255.200.21
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf6b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.23 - Peer: pod2-leaf10a'
+ routes:
+ - 10.255.200.23
+- VerifyRoutingProtocolModel:
+ filters:
+ tags:
+ - pod2-leaf1b
+ model: multi-agent
+ result_overwrite:
+ custom_field: 'Routing protocol model: multi-agent'
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf1b
+ result_overwrite:
+ custom_field: 'Route: 10.255.0.1 - Peer: super-spine1'
+ routes:
+ - 10.255.0.1
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf1b
+ result_overwrite:
+ custom_field: 'Route: 10.255.0.2 - Peer: super-spine2'
+ routes:
+ - 10.255.0.2
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf1b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.1 - Peer: pod1-spine1'
+ routes:
+ - 10.255.1.1
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf1b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.2 - Peer: pod1-spine2'
+ routes:
+ - 10.255.1.2
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf1b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.3 - Peer: pod1-spine3'
+ routes:
+ - 10.255.1.3
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf1b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.4 - Peer: pod1-spine4'
+ routes:
+ - 10.255.1.4
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf1b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.5 - Peer: pod1-leaf1a'
+ routes:
+ - 10.255.1.5
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf1b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.6 - Peer: pod1-leaf1b'
+ routes:
+ - 10.255.1.6
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf1b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.7 - Peer: pod1-leaf2a'
+ routes:
+ - 10.255.1.7
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf1b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.8 - Peer: pod1-leaf2b'
+ routes:
+ - 10.255.1.8
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf1b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.9 - Peer: pod1-leaf3a'
+ routes:
+ - 10.255.1.9
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf1b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.10 - Peer: pod1-leaf3b'
+ routes:
+ - 10.255.1.10
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf1b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.11 - Peer: pod1-leaf4a'
+ routes:
+ - 10.255.1.11
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf1b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.12 - Peer: pod1-leaf4b'
+ routes:
+ - 10.255.1.12
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf1b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.13 - Peer: pod1-leaf5a'
+ routes:
+ - 10.255.1.13
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf1b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.14 - Peer: pod1-leaf5b'
+ routes:
+ - 10.255.1.14
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf1b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.15 - Peer: pod1-leaf6a'
+ routes:
+ - 10.255.1.15
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf1b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.16 - Peer: pod1-leaf6b'
+ routes:
+ - 10.255.1.16
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf1b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.17 - Peer: pod1-leaf7a'
+ routes:
+ - 10.255.1.17
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf1b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.18 - Peer: pod1-leaf7b'
+ routes:
+ - 10.255.1.18
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf1b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.19 - Peer: pod1-leaf8a'
+ routes:
+ - 10.255.1.19
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf1b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.20 - Peer: pod1-leaf8b'
+ routes:
+ - 10.255.1.20
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf1b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.21 - Peer: pod1-leaf9a'
+ routes:
+ - 10.255.1.21
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf1b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.22 - Peer: pod1-leaf9b'
+ routes:
+ - 10.255.1.22
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf1b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.23 - Peer: pod1-leaf10a'
+ routes:
+ - 10.255.1.23
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf1b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.24 - Peer: pod1-leaf10b'
+ routes:
+ - 10.255.1.24
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf1b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.1 - Peer: pod2-spine1'
+ routes:
+ - 10.255.2.1
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf1b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.2 - Peer: pod2-spine2'
+ routes:
+ - 10.255.2.2
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf1b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.3 - Peer: pod2-spine3'
+ routes:
+ - 10.255.2.3
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf1b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.4 - Peer: pod2-spine4'
+ routes:
+ - 10.255.2.4
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf1b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.5 - Peer: pod2-leaf1a'
+ routes:
+ - 10.255.2.5
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf1b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.6 - Peer: pod2-leaf1b'
+ routes:
+ - 10.255.2.6
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf1b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.7 - Peer: pod2-leaf2a'
+ routes:
+ - 10.255.2.7
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf1b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.8 - Peer: pod2-leaf2b'
+ routes:
+ - 10.255.2.8
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf1b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.9 - Peer: pod2-leaf3a'
+ routes:
+ - 10.255.2.9
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf1b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.10 - Peer: pod2-leaf3b'
+ routes:
+ - 10.255.2.10
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf1b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.11 - Peer: pod2-leaf4a'
+ routes:
+ - 10.255.2.11
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf1b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.12 - Peer: pod2-leaf4b'
+ routes:
+ - 10.255.2.12
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf1b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.13 - Peer: pod2-leaf5a'
+ routes:
+ - 10.255.2.13
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf1b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.14 - Peer: pod2-leaf5b'
+ routes:
+ - 10.255.2.14
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf1b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.15 - Peer: pod2-leaf6a'
+ routes:
+ - 10.255.2.15
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf1b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.16 - Peer: pod2-leaf6b'
+ routes:
+ - 10.255.2.16
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf1b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.17 - Peer: pod2-leaf7a'
+ routes:
+ - 10.255.2.17
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf1b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.18 - Peer: pod2-leaf7b'
+ routes:
+ - 10.255.2.18
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf1b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.19 - Peer: pod2-leaf8a'
+ routes:
+ - 10.255.2.19
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf1b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.20 - Peer: pod2-leaf8b'
+ routes:
+ - 10.255.2.20
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf1b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.21 - Peer: pod2-leaf9a'
+ routes:
+ - 10.255.2.21
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf1b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.22 - Peer: pod2-leaf9b'
+ routes:
+ - 10.255.2.22
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf1b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.23 - Peer: pod2-leaf10a'
+ routes:
+ - 10.255.2.23
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf1b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.24 - Peer: pod2-leaf10b'
+ routes:
+ - 10.255.2.24
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf1b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.5 - Peer: pod1-leaf1a'
+ routes:
+ - 10.255.100.5
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf1b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.7 - Peer: pod1-leaf2a'
+ routes:
+ - 10.255.100.7
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf1b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.9 - Peer: pod1-leaf3a'
+ routes:
+ - 10.255.100.9
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf1b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.11 - Peer: pod1-leaf4a'
+ routes:
+ - 10.255.100.11
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf1b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.13 - Peer: pod1-leaf5a'
+ routes:
+ - 10.255.100.13
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf1b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.15 - Peer: pod1-leaf6a'
+ routes:
+ - 10.255.100.15
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf1b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.17 - Peer: pod1-leaf7a'
+ routes:
+ - 10.255.100.17
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf1b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.19 - Peer: pod1-leaf8a'
+ routes:
+ - 10.255.100.19
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf1b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.21 - Peer: pod1-leaf9a'
+ routes:
+ - 10.255.100.21
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf1b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.23 - Peer: pod1-leaf10a'
+ routes:
+ - 10.255.100.23
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf1b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.5 - Peer: pod2-leaf1a'
+ routes:
+ - 10.255.200.5
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf1b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.7 - Peer: pod2-leaf2a'
+ routes:
+ - 10.255.200.7
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf1b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.9 - Peer: pod2-leaf3a'
+ routes:
+ - 10.255.200.9
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf1b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.11 - Peer: pod2-leaf4a'
+ routes:
+ - 10.255.200.11
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf1b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.13 - Peer: pod2-leaf5a'
+ routes:
+ - 10.255.200.13
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf1b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.15 - Peer: pod2-leaf6a'
+ routes:
+ - 10.255.200.15
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf1b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.17 - Peer: pod2-leaf7a'
+ routes:
+ - 10.255.200.17
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf1b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.19 - Peer: pod2-leaf8a'
+ routes:
+ - 10.255.200.19
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf1b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.21 - Peer: pod2-leaf9a'
+ routes:
+ - 10.255.200.21
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf1b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.23 - Peer: pod2-leaf10a'
+ routes:
+ - 10.255.200.23
+- VerifyRoutingProtocolModel:
+ filters:
+ tags:
+ - super-spine2
+ model: multi-agent
+ result_overwrite:
+ custom_field: 'Routing protocol model: multi-agent'
+- VerifyRoutingProtocolModel:
+ filters:
+ tags:
+ - pod1-leaf1b
+ model: multi-agent
+ result_overwrite:
+ custom_field: 'Routing protocol model: multi-agent'
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf1b
+ result_overwrite:
+ custom_field: 'Route: 10.255.0.1 - Peer: super-spine1'
+ routes:
+ - 10.255.0.1
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf1b
+ result_overwrite:
+ custom_field: 'Route: 10.255.0.2 - Peer: super-spine2'
+ routes:
+ - 10.255.0.2
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf1b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.1 - Peer: pod1-spine1'
+ routes:
+ - 10.255.1.1
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf1b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.2 - Peer: pod1-spine2'
+ routes:
+ - 10.255.1.2
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf1b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.3 - Peer: pod1-spine3'
+ routes:
+ - 10.255.1.3
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf1b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.4 - Peer: pod1-spine4'
+ routes:
+ - 10.255.1.4
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf1b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.5 - Peer: pod1-leaf1a'
+ routes:
+ - 10.255.1.5
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf1b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.6 - Peer: pod1-leaf1b'
+ routes:
+ - 10.255.1.6
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf1b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.7 - Peer: pod1-leaf2a'
+ routes:
+ - 10.255.1.7
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf1b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.8 - Peer: pod1-leaf2b'
+ routes:
+ - 10.255.1.8
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf1b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.9 - Peer: pod1-leaf3a'
+ routes:
+ - 10.255.1.9
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf1b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.10 - Peer: pod1-leaf3b'
+ routes:
+ - 10.255.1.10
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf1b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.11 - Peer: pod1-leaf4a'
+ routes:
+ - 10.255.1.11
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf1b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.12 - Peer: pod1-leaf4b'
+ routes:
+ - 10.255.1.12
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf1b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.13 - Peer: pod1-leaf5a'
+ routes:
+ - 10.255.1.13
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf1b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.14 - Peer: pod1-leaf5b'
+ routes:
+ - 10.255.1.14
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf1b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.15 - Peer: pod1-leaf6a'
+ routes:
+ - 10.255.1.15
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf1b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.16 - Peer: pod1-leaf6b'
+ routes:
+ - 10.255.1.16
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf1b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.17 - Peer: pod1-leaf7a'
+ routes:
+ - 10.255.1.17
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf1b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.18 - Peer: pod1-leaf7b'
+ routes:
+ - 10.255.1.18
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf1b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.19 - Peer: pod1-leaf8a'
+ routes:
+ - 10.255.1.19
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf1b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.20 - Peer: pod1-leaf8b'
+ routes:
+ - 10.255.1.20
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf1b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.21 - Peer: pod1-leaf9a'
+ routes:
+ - 10.255.1.21
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf1b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.22 - Peer: pod1-leaf9b'
+ routes:
+ - 10.255.1.22
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf1b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.23 - Peer: pod1-leaf10a'
+ routes:
+ - 10.255.1.23
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf1b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.24 - Peer: pod1-leaf10b'
+ routes:
+ - 10.255.1.24
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf1b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.1 - Peer: pod2-spine1'
+ routes:
+ - 10.255.2.1
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf1b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.2 - Peer: pod2-spine2'
+ routes:
+ - 10.255.2.2
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf1b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.3 - Peer: pod2-spine3'
+ routes:
+ - 10.255.2.3
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf1b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.4 - Peer: pod2-spine4'
+ routes:
+ - 10.255.2.4
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf1b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.5 - Peer: pod2-leaf1a'
+ routes:
+ - 10.255.2.5
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf1b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.6 - Peer: pod2-leaf1b'
+ routes:
+ - 10.255.2.6
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf1b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.7 - Peer: pod2-leaf2a'
+ routes:
+ - 10.255.2.7
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf1b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.8 - Peer: pod2-leaf2b'
+ routes:
+ - 10.255.2.8
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf1b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.9 - Peer: pod2-leaf3a'
+ routes:
+ - 10.255.2.9
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf1b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.10 - Peer: pod2-leaf3b'
+ routes:
+ - 10.255.2.10
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf1b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.11 - Peer: pod2-leaf4a'
+ routes:
+ - 10.255.2.11
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf1b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.12 - Peer: pod2-leaf4b'
+ routes:
+ - 10.255.2.12
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf1b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.13 - Peer: pod2-leaf5a'
+ routes:
+ - 10.255.2.13
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf1b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.14 - Peer: pod2-leaf5b'
+ routes:
+ - 10.255.2.14
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf1b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.15 - Peer: pod2-leaf6a'
+ routes:
+ - 10.255.2.15
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf1b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.16 - Peer: pod2-leaf6b'
+ routes:
+ - 10.255.2.16
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf1b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.17 - Peer: pod2-leaf7a'
+ routes:
+ - 10.255.2.17
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf1b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.18 - Peer: pod2-leaf7b'
+ routes:
+ - 10.255.2.18
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf1b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.19 - Peer: pod2-leaf8a'
+ routes:
+ - 10.255.2.19
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf1b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.20 - Peer: pod2-leaf8b'
+ routes:
+ - 10.255.2.20
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf1b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.21 - Peer: pod2-leaf9a'
+ routes:
+ - 10.255.2.21
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf1b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.22 - Peer: pod2-leaf9b'
+ routes:
+ - 10.255.2.22
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf1b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.23 - Peer: pod2-leaf10a'
+ routes:
+ - 10.255.2.23
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf1b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.24 - Peer: pod2-leaf10b'
+ routes:
+ - 10.255.2.24
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf1b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.5 - Peer: pod1-leaf1a'
+ routes:
+ - 10.255.100.5
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf1b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.7 - Peer: pod1-leaf2a'
+ routes:
+ - 10.255.100.7
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf1b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.9 - Peer: pod1-leaf3a'
+ routes:
+ - 10.255.100.9
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf1b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.11 - Peer: pod1-leaf4a'
+ routes:
+ - 10.255.100.11
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf1b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.13 - Peer: pod1-leaf5a'
+ routes:
+ - 10.255.100.13
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf1b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.15 - Peer: pod1-leaf6a'
+ routes:
+ - 10.255.100.15
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf1b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.17 - Peer: pod1-leaf7a'
+ routes:
+ - 10.255.100.17
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf1b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.19 - Peer: pod1-leaf8a'
+ routes:
+ - 10.255.100.19
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf1b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.21 - Peer: pod1-leaf9a'
+ routes:
+ - 10.255.100.21
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf1b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.23 - Peer: pod1-leaf10a'
+ routes:
+ - 10.255.100.23
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf1b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.5 - Peer: pod2-leaf1a'
+ routes:
+ - 10.255.200.5
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf1b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.7 - Peer: pod2-leaf2a'
+ routes:
+ - 10.255.200.7
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf1b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.9 - Peer: pod2-leaf3a'
+ routes:
+ - 10.255.200.9
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf1b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.11 - Peer: pod2-leaf4a'
+ routes:
+ - 10.255.200.11
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf1b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.13 - Peer: pod2-leaf5a'
+ routes:
+ - 10.255.200.13
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf1b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.15 - Peer: pod2-leaf6a'
+ routes:
+ - 10.255.200.15
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf1b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.17 - Peer: pod2-leaf7a'
+ routes:
+ - 10.255.200.17
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf1b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.19 - Peer: pod2-leaf8a'
+ routes:
+ - 10.255.200.19
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf1b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.21 - Peer: pod2-leaf9a'
+ routes:
+ - 10.255.200.21
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf1b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.23 - Peer: pod2-leaf10a'
+ routes:
+ - 10.255.200.23
+- VerifyRoutingProtocolModel:
+ filters:
+ tags:
+ - pod1-leaf6b
+ model: multi-agent
+ result_overwrite:
+ custom_field: 'Routing protocol model: multi-agent'
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf6b
+ result_overwrite:
+ custom_field: 'Route: 10.255.0.1 - Peer: super-spine1'
+ routes:
+ - 10.255.0.1
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf6b
+ result_overwrite:
+ custom_field: 'Route: 10.255.0.2 - Peer: super-spine2'
+ routes:
+ - 10.255.0.2
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf6b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.1 - Peer: pod1-spine1'
+ routes:
+ - 10.255.1.1
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf6b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.2 - Peer: pod1-spine2'
+ routes:
+ - 10.255.1.2
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf6b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.3 - Peer: pod1-spine3'
+ routes:
+ - 10.255.1.3
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf6b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.4 - Peer: pod1-spine4'
+ routes:
+ - 10.255.1.4
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf6b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.5 - Peer: pod1-leaf1a'
+ routes:
+ - 10.255.1.5
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf6b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.6 - Peer: pod1-leaf1b'
+ routes:
+ - 10.255.1.6
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf6b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.7 - Peer: pod1-leaf2a'
+ routes:
+ - 10.255.1.7
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf6b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.8 - Peer: pod1-leaf2b'
+ routes:
+ - 10.255.1.8
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf6b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.9 - Peer: pod1-leaf3a'
+ routes:
+ - 10.255.1.9
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf6b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.10 - Peer: pod1-leaf3b'
+ routes:
+ - 10.255.1.10
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf6b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.11 - Peer: pod1-leaf4a'
+ routes:
+ - 10.255.1.11
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf6b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.12 - Peer: pod1-leaf4b'
+ routes:
+ - 10.255.1.12
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf6b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.13 - Peer: pod1-leaf5a'
+ routes:
+ - 10.255.1.13
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf6b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.14 - Peer: pod1-leaf5b'
+ routes:
+ - 10.255.1.14
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf6b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.15 - Peer: pod1-leaf6a'
+ routes:
+ - 10.255.1.15
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf6b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.16 - Peer: pod1-leaf6b'
+ routes:
+ - 10.255.1.16
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf6b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.17 - Peer: pod1-leaf7a'
+ routes:
+ - 10.255.1.17
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf6b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.18 - Peer: pod1-leaf7b'
+ routes:
+ - 10.255.1.18
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf6b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.19 - Peer: pod1-leaf8a'
+ routes:
+ - 10.255.1.19
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf6b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.20 - Peer: pod1-leaf8b'
+ routes:
+ - 10.255.1.20
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf6b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.21 - Peer: pod1-leaf9a'
+ routes:
+ - 10.255.1.21
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf6b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.22 - Peer: pod1-leaf9b'
+ routes:
+ - 10.255.1.22
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf6b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.23 - Peer: pod1-leaf10a'
+ routes:
+ - 10.255.1.23
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf6b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.24 - Peer: pod1-leaf10b'
+ routes:
+ - 10.255.1.24
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf6b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.1 - Peer: pod2-spine1'
+ routes:
+ - 10.255.2.1
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf6b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.2 - Peer: pod2-spine2'
+ routes:
+ - 10.255.2.2
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf6b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.3 - Peer: pod2-spine3'
+ routes:
+ - 10.255.2.3
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf6b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.4 - Peer: pod2-spine4'
+ routes:
+ - 10.255.2.4
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf6b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.5 - Peer: pod2-leaf1a'
+ routes:
+ - 10.255.2.5
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf6b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.6 - Peer: pod2-leaf1b'
+ routes:
+ - 10.255.2.6
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf6b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.7 - Peer: pod2-leaf2a'
+ routes:
+ - 10.255.2.7
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf6b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.8 - Peer: pod2-leaf2b'
+ routes:
+ - 10.255.2.8
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf6b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.9 - Peer: pod2-leaf3a'
+ routes:
+ - 10.255.2.9
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf6b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.10 - Peer: pod2-leaf3b'
+ routes:
+ - 10.255.2.10
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf6b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.11 - Peer: pod2-leaf4a'
+ routes:
+ - 10.255.2.11
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf6b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.12 - Peer: pod2-leaf4b'
+ routes:
+ - 10.255.2.12
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf6b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.13 - Peer: pod2-leaf5a'
+ routes:
+ - 10.255.2.13
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf6b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.14 - Peer: pod2-leaf5b'
+ routes:
+ - 10.255.2.14
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf6b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.15 - Peer: pod2-leaf6a'
+ routes:
+ - 10.255.2.15
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf6b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.16 - Peer: pod2-leaf6b'
+ routes:
+ - 10.255.2.16
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf6b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.17 - Peer: pod2-leaf7a'
+ routes:
+ - 10.255.2.17
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf6b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.18 - Peer: pod2-leaf7b'
+ routes:
+ - 10.255.2.18
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf6b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.19 - Peer: pod2-leaf8a'
+ routes:
+ - 10.255.2.19
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf6b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.20 - Peer: pod2-leaf8b'
+ routes:
+ - 10.255.2.20
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf6b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.21 - Peer: pod2-leaf9a'
+ routes:
+ - 10.255.2.21
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf6b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.22 - Peer: pod2-leaf9b'
+ routes:
+ - 10.255.2.22
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf6b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.23 - Peer: pod2-leaf10a'
+ routes:
+ - 10.255.2.23
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf6b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.24 - Peer: pod2-leaf10b'
+ routes:
+ - 10.255.2.24
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf6b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.5 - Peer: pod1-leaf1a'
+ routes:
+ - 10.255.100.5
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf6b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.7 - Peer: pod1-leaf2a'
+ routes:
+ - 10.255.100.7
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf6b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.9 - Peer: pod1-leaf3a'
+ routes:
+ - 10.255.100.9
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf6b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.11 - Peer: pod1-leaf4a'
+ routes:
+ - 10.255.100.11
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf6b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.13 - Peer: pod1-leaf5a'
+ routes:
+ - 10.255.100.13
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf6b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.15 - Peer: pod1-leaf6a'
+ routes:
+ - 10.255.100.15
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf6b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.17 - Peer: pod1-leaf7a'
+ routes:
+ - 10.255.100.17
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf6b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.19 - Peer: pod1-leaf8a'
+ routes:
+ - 10.255.100.19
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf6b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.21 - Peer: pod1-leaf9a'
+ routes:
+ - 10.255.100.21
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf6b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.23 - Peer: pod1-leaf10a'
+ routes:
+ - 10.255.100.23
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf6b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.5 - Peer: pod2-leaf1a'
+ routes:
+ - 10.255.200.5
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf6b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.7 - Peer: pod2-leaf2a'
+ routes:
+ - 10.255.200.7
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf6b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.9 - Peer: pod2-leaf3a'
+ routes:
+ - 10.255.200.9
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf6b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.11 - Peer: pod2-leaf4a'
+ routes:
+ - 10.255.200.11
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf6b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.13 - Peer: pod2-leaf5a'
+ routes:
+ - 10.255.200.13
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf6b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.15 - Peer: pod2-leaf6a'
+ routes:
+ - 10.255.200.15
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf6b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.17 - Peer: pod2-leaf7a'
+ routes:
+ - 10.255.200.17
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf6b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.19 - Peer: pod2-leaf8a'
+ routes:
+ - 10.255.200.19
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf6b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.21 - Peer: pod2-leaf9a'
+ routes:
+ - 10.255.200.21
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod1-leaf6b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.23 - Peer: pod2-leaf10a'
+ routes:
+ - 10.255.200.23
+- VerifyRoutingProtocolModel:
+ filters:
+ tags:
+ - pod2-leaf7b
+ model: multi-agent
+ result_overwrite:
+ custom_field: 'Routing protocol model: multi-agent'
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf7b
+ result_overwrite:
+ custom_field: 'Route: 10.255.0.1 - Peer: super-spine1'
+ routes:
+ - 10.255.0.1
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf7b
+ result_overwrite:
+ custom_field: 'Route: 10.255.0.2 - Peer: super-spine2'
+ routes:
+ - 10.255.0.2
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf7b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.1 - Peer: pod1-spine1'
+ routes:
+ - 10.255.1.1
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf7b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.2 - Peer: pod1-spine2'
+ routes:
+ - 10.255.1.2
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf7b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.3 - Peer: pod1-spine3'
+ routes:
+ - 10.255.1.3
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf7b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.4 - Peer: pod1-spine4'
+ routes:
+ - 10.255.1.4
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf7b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.5 - Peer: pod1-leaf1a'
+ routes:
+ - 10.255.1.5
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf7b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.6 - Peer: pod1-leaf1b'
+ routes:
+ - 10.255.1.6
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf7b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.7 - Peer: pod1-leaf2a'
+ routes:
+ - 10.255.1.7
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf7b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.8 - Peer: pod1-leaf2b'
+ routes:
+ - 10.255.1.8
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf7b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.9 - Peer: pod1-leaf3a'
+ routes:
+ - 10.255.1.9
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf7b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.10 - Peer: pod1-leaf3b'
+ routes:
+ - 10.255.1.10
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf7b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.11 - Peer: pod1-leaf4a'
+ routes:
+ - 10.255.1.11
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf7b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.12 - Peer: pod1-leaf4b'
+ routes:
+ - 10.255.1.12
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf7b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.13 - Peer: pod1-leaf5a'
+ routes:
+ - 10.255.1.13
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf7b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.14 - Peer: pod1-leaf5b'
+ routes:
+ - 10.255.1.14
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf7b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.15 - Peer: pod1-leaf6a'
+ routes:
+ - 10.255.1.15
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf7b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.16 - Peer: pod1-leaf6b'
+ routes:
+ - 10.255.1.16
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf7b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.17 - Peer: pod1-leaf7a'
+ routes:
+ - 10.255.1.17
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf7b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.18 - Peer: pod1-leaf7b'
+ routes:
+ - 10.255.1.18
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf7b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.19 - Peer: pod1-leaf8a'
+ routes:
+ - 10.255.1.19
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf7b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.20 - Peer: pod1-leaf8b'
+ routes:
+ - 10.255.1.20
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf7b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.21 - Peer: pod1-leaf9a'
+ routes:
+ - 10.255.1.21
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf7b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.22 - Peer: pod1-leaf9b'
+ routes:
+ - 10.255.1.22
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf7b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.23 - Peer: pod1-leaf10a'
+ routes:
+ - 10.255.1.23
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf7b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.24 - Peer: pod1-leaf10b'
+ routes:
+ - 10.255.1.24
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf7b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.1 - Peer: pod2-spine1'
+ routes:
+ - 10.255.2.1
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf7b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.2 - Peer: pod2-spine2'
+ routes:
+ - 10.255.2.2
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf7b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.3 - Peer: pod2-spine3'
+ routes:
+ - 10.255.2.3
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf7b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.4 - Peer: pod2-spine4'
+ routes:
+ - 10.255.2.4
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf7b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.5 - Peer: pod2-leaf1a'
+ routes:
+ - 10.255.2.5
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf7b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.6 - Peer: pod2-leaf1b'
+ routes:
+ - 10.255.2.6
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf7b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.7 - Peer: pod2-leaf2a'
+ routes:
+ - 10.255.2.7
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf7b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.8 - Peer: pod2-leaf2b'
+ routes:
+ - 10.255.2.8
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf7b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.9 - Peer: pod2-leaf3a'
+ routes:
+ - 10.255.2.9
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf7b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.10 - Peer: pod2-leaf3b'
+ routes:
+ - 10.255.2.10
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf7b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.11 - Peer: pod2-leaf4a'
+ routes:
+ - 10.255.2.11
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf7b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.12 - Peer: pod2-leaf4b'
+ routes:
+ - 10.255.2.12
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf7b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.13 - Peer: pod2-leaf5a'
+ routes:
+ - 10.255.2.13
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf7b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.14 - Peer: pod2-leaf5b'
+ routes:
+ - 10.255.2.14
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf7b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.15 - Peer: pod2-leaf6a'
+ routes:
+ - 10.255.2.15
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf7b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.16 - Peer: pod2-leaf6b'
+ routes:
+ - 10.255.2.16
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf7b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.17 - Peer: pod2-leaf7a'
+ routes:
+ - 10.255.2.17
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf7b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.18 - Peer: pod2-leaf7b'
+ routes:
+ - 10.255.2.18
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf7b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.19 - Peer: pod2-leaf8a'
+ routes:
+ - 10.255.2.19
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf7b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.20 - Peer: pod2-leaf8b'
+ routes:
+ - 10.255.2.20
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf7b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.21 - Peer: pod2-leaf9a'
+ routes:
+ - 10.255.2.21
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf7b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.22 - Peer: pod2-leaf9b'
+ routes:
+ - 10.255.2.22
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf7b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.23 - Peer: pod2-leaf10a'
+ routes:
+ - 10.255.2.23
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf7b
+ result_overwrite:
+ custom_field: 'Route: 10.255.2.24 - Peer: pod2-leaf10b'
+ routes:
+ - 10.255.2.24
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf7b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.5 - Peer: pod1-leaf1a'
+ routes:
+ - 10.255.100.5
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf7b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.7 - Peer: pod1-leaf2a'
+ routes:
+ - 10.255.100.7
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf7b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.9 - Peer: pod1-leaf3a'
+ routes:
+ - 10.255.100.9
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf7b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.11 - Peer: pod1-leaf4a'
+ routes:
+ - 10.255.100.11
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf7b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.13 - Peer: pod1-leaf5a'
+ routes:
+ - 10.255.100.13
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf7b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.15 - Peer: pod1-leaf6a'
+ routes:
+ - 10.255.100.15
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf7b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.17 - Peer: pod1-leaf7a'
+ routes:
+ - 10.255.100.17
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf7b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.19 - Peer: pod1-leaf8a'
+ routes:
+ - 10.255.100.19
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf7b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.21 - Peer: pod1-leaf9a'
+ routes:
+ - 10.255.100.21
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf7b
+ result_overwrite:
+ custom_field: 'Route: 10.255.100.23 - Peer: pod1-leaf10a'
+ routes:
+ - 10.255.100.23
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf7b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.5 - Peer: pod2-leaf1a'
+ routes:
+ - 10.255.200.5
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf7b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.7 - Peer: pod2-leaf2a'
+ routes:
+ - 10.255.200.7
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf7b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.9 - Peer: pod2-leaf3a'
+ routes:
+ - 10.255.200.9
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf7b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.11 - Peer: pod2-leaf4a'
+ routes:
+ - 10.255.200.11
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf7b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.13 - Peer: pod2-leaf5a'
+ routes:
+ - 10.255.200.13
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf7b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.15 - Peer: pod2-leaf6a'
+ routes:
+ - 10.255.200.15
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf7b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.17 - Peer: pod2-leaf7a'
+ routes:
+ - 10.255.200.17
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf7b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.19 - Peer: pod2-leaf8a'
+ routes:
+ - 10.255.200.19
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf7b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.21 - Peer: pod2-leaf9a'
+ routes:
+ - 10.255.200.21
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - pod2-leaf7b
+ result_overwrite:
+ custom_field: 'Route: 10.255.200.23 - Peer: pod2-leaf10a'
+ routes:
+ - 10.255.200.23
+- VerifyRoutingProtocolModel:
+ filters:
+ tags:
+ - pod1-spine3
+ model: multi-agent
+ result_overwrite:
+ custom_field: 'Routing protocol model: multi-agent'
+anta.tests.security:
+- VerifyAPIHttpsSSL:
+ filters:
+ tags:
+ - pod1-leaf4b
+ profile: EAPI
+ result_overwrite:
+ custom_field: 'eAPI HTTPS SSL Profile: EAPI'
+- VerifyAPIHttpsSSL:
+ filters:
+ tags:
+ - pod2-spine1
+ profile: EAPI
+ result_overwrite:
+ custom_field: 'eAPI HTTPS SSL Profile: EAPI'
+- VerifyAPIHttpsSSL:
+ filters:
+ tags:
+ - pod1-leaf3b
+ profile: EAPI
+ result_overwrite:
+ custom_field: 'eAPI HTTPS SSL Profile: EAPI'
+- VerifyAPIHttpsSSL:
+ filters:
+ tags:
+ - pod1-leaf9a
+ profile: EAPI
+ result_overwrite:
+ custom_field: 'eAPI HTTPS SSL Profile: EAPI'
+- VerifyAPIHttpsSSL:
+ filters:
+ tags:
+ - pod1-spine4
+ profile: EAPI
+ result_overwrite:
+ custom_field: 'eAPI HTTPS SSL Profile: EAPI'
+- VerifyAPIHttpsSSL:
+ filters:
+ tags:
+ - pod2-leaf5b
+ profile: EAPI
+ result_overwrite:
+ custom_field: 'eAPI HTTPS SSL Profile: EAPI'
+- VerifyAPIHttpsSSL:
+ filters:
+ tags:
+ - pod2-leaf2b
+ profile: EAPI
+ result_overwrite:
+ custom_field: 'eAPI HTTPS SSL Profile: EAPI'
+- VerifyAPIHttpsSSL:
+ filters:
+ tags:
+ - pod2-leaf8a
+ profile: EAPI
+ result_overwrite:
+ custom_field: 'eAPI HTTPS SSL Profile: EAPI'
+- VerifyAPIHttpsSSL:
+ filters:
+ tags:
+ - pod1-leaf2b
+ profile: EAPI
+ result_overwrite:
+ custom_field: 'eAPI HTTPS SSL Profile: EAPI'
+- VerifyAPIHttpsSSL:
+ filters:
+ tags:
+ - pod1-leaf5b
+ profile: EAPI
+ result_overwrite:
+ custom_field: 'eAPI HTTPS SSL Profile: EAPI'
+- VerifyAPIHttpsSSL:
+ filters:
+ tags:
+ - pod1-leaf8a
+ profile: EAPI
+ result_overwrite:
+ custom_field: 'eAPI HTTPS SSL Profile: EAPI'
+- VerifyAPIHttpsSSL:
+ filters:
+ tags:
+ - pod2-spine4
+ profile: EAPI
+ result_overwrite:
+ custom_field: 'eAPI HTTPS SSL Profile: EAPI'
+- VerifyAPIHttpsSSL:
+ filters:
+ tags:
+ - pod2-leaf3b
+ profile: EAPI
+ result_overwrite:
+ custom_field: 'eAPI HTTPS SSL Profile: EAPI'
+- VerifyAPIHttpsSSL:
+ filters:
+ tags:
+ - pod2-leaf4b
+ profile: EAPI
+ result_overwrite:
+ custom_field: 'eAPI HTTPS SSL Profile: EAPI'
+- VerifyAPIHttpsSSL:
+ filters:
+ tags:
+ - pod1-spine1
+ profile: EAPI
+ result_overwrite:
+ custom_field: 'eAPI HTTPS SSL Profile: EAPI'
+- VerifyAPIHttpsSSL:
+ filters:
+ tags:
+ - pod2-leaf9a
+ profile: EAPI
+ result_overwrite:
+ custom_field: 'eAPI HTTPS SSL Profile: EAPI'
+- VerifyAPIHttpsSSL:
+ filters:
+ tags:
+ - pod2-leaf9b
+ profile: EAPI
+ result_overwrite:
+ custom_field: 'eAPI HTTPS SSL Profile: EAPI'
+- VerifyAPIHttpsSSL:
+ filters:
+ tags:
+ - pod2-leaf3a
+ profile: EAPI
+ result_overwrite:
+ custom_field: 'eAPI HTTPS SSL Profile: EAPI'
+- VerifyAPIHttpsSSL:
+ filters:
+ tags:
+ - pod1-spine2
+ profile: EAPI
+ result_overwrite:
+ custom_field: 'eAPI HTTPS SSL Profile: EAPI'
+- VerifyAPIHttpsSSL:
+ filters:
+ tags:
+ - pod2-leaf4a
+ profile: EAPI
+ result_overwrite:
+ custom_field: 'eAPI HTTPS SSL Profile: EAPI'
+- VerifyAPIHttpsSSL:
+ filters:
+ tags:
+ - pod1-leaf8b
+ profile: EAPI
+ result_overwrite:
+ custom_field: 'eAPI HTTPS SSL Profile: EAPI'
+- VerifyAPIHttpsSSL:
+ filters:
+ tags:
+ - pod1-leaf2a
+ profile: EAPI
+ result_overwrite:
+ custom_field: 'eAPI HTTPS SSL Profile: EAPI'
+- VerifyAPIHttpsSSL:
+ filters:
+ tags:
+ - pod1-leaf5a
+ profile: EAPI
+ result_overwrite:
+ custom_field: 'eAPI HTTPS SSL Profile: EAPI'
+- VerifyAPIHttpsSSL:
+ filters:
+ tags:
+ - pod2-leaf8b
+ profile: EAPI
+ result_overwrite:
+ custom_field: 'eAPI HTTPS SSL Profile: EAPI'
+- VerifyAPIHttpsSSL:
+ filters:
+ tags:
+ - pod2-leaf5a
+ profile: EAPI
+ result_overwrite:
+ custom_field: 'eAPI HTTPS SSL Profile: EAPI'
+- VerifyAPIHttpsSSL:
+ filters:
+ tags:
+ - pod2-leaf2a
+ profile: EAPI
+ result_overwrite:
+ custom_field: 'eAPI HTTPS SSL Profile: EAPI'
+- VerifyAPIHttpsSSL:
+ filters:
+ tags:
+ - pod1-leaf9b
+ profile: EAPI
+ result_overwrite:
+ custom_field: 'eAPI HTTPS SSL Profile: EAPI'
+- VerifyAPIHttpsSSL:
+ filters:
+ tags:
+ - pod2-spine2
+ profile: EAPI
+ result_overwrite:
+ custom_field: 'eAPI HTTPS SSL Profile: EAPI'
+- VerifyAPIHttpsSSL:
+ filters:
+ tags:
+ - pod1-leaf4a
+ profile: EAPI
+ result_overwrite:
+ custom_field: 'eAPI HTTPS SSL Profile: EAPI'
+- VerifyAPIHttpsSSL:
+ filters:
+ tags:
+ - pod1-leaf3a
+ profile: EAPI
+ result_overwrite:
+ custom_field: 'eAPI HTTPS SSL Profile: EAPI'
+- VerifyAPIHttpsSSL:
+ filters:
+ tags:
+ - pod2-leaf7a
+ profile: EAPI
+ result_overwrite:
+ custom_field: 'eAPI HTTPS SSL Profile: EAPI'
+- VerifyAPIHttpsSSL:
+ filters:
+ tags:
+ - pod1-leaf1a
+ profile: EAPI
+ result_overwrite:
+ custom_field: 'eAPI HTTPS SSL Profile: EAPI'
+- VerifyAPIHttpsSSL:
+ filters:
+ tags:
+ - super-spine1
+ profile: EAPI
+ result_overwrite:
+ custom_field: 'eAPI HTTPS SSL Profile: EAPI'
+- VerifyAPIHttpsSSL:
+ filters:
+ tags:
+ - pod1-leaf6a
+ profile: EAPI
+ result_overwrite:
+ custom_field: 'eAPI HTTPS SSL Profile: EAPI'
+- VerifyAPIHttpsSSL:
+ filters:
+ tags:
+ - pod2-leaf6a
+ profile: EAPI
+ result_overwrite:
+ custom_field: 'eAPI HTTPS SSL Profile: EAPI'
+- VerifyAPIHttpsSSL:
+ filters:
+ tags:
+ - pod2-leaf1a
+ profile: EAPI
+ result_overwrite:
+ custom_field: 'eAPI HTTPS SSL Profile: EAPI'
+- VerifyAPIHttpsSSL:
+ filters:
+ tags:
+ - pod1-leaf10b
+ profile: EAPI
+ result_overwrite:
+ custom_field: 'eAPI HTTPS SSL Profile: EAPI'
+- VerifyAPIHttpsSSL:
+ filters:
+ tags:
+ - pod1-leaf7a
+ profile: EAPI
+ result_overwrite:
+ custom_field: 'eAPI HTTPS SSL Profile: EAPI'
+- VerifyAPIHttpsSSL:
+ filters:
+ tags:
+ - pod2-leaf10b
+ profile: EAPI
+ result_overwrite:
+ custom_field: 'eAPI HTTPS SSL Profile: EAPI'
+- VerifyAPIHttpsSSL:
+ filters:
+ tags:
+ - pod2-leaf10a
+ profile: EAPI
+ result_overwrite:
+ custom_field: 'eAPI HTTPS SSL Profile: EAPI'
+- VerifyAPIHttpsSSL:
+ filters:
+ tags:
+ - pod2-spine3
+ profile: EAPI
+ result_overwrite:
+ custom_field: 'eAPI HTTPS SSL Profile: EAPI'
+- VerifyAPIHttpsSSL:
+ filters:
+ tags:
+ - pod1-leaf7b
+ profile: EAPI
+ result_overwrite:
+ custom_field: 'eAPI HTTPS SSL Profile: EAPI'
+- VerifyAPIHttpsSSL:
+ filters:
+ tags:
+ - pod1-leaf10a
+ profile: EAPI
+ result_overwrite:
+ custom_field: 'eAPI HTTPS SSL Profile: EAPI'
+- VerifyAPIHttpsSSL:
+ filters:
+ tags:
+ - pod2-leaf6b
+ profile: EAPI
+ result_overwrite:
+ custom_field: 'eAPI HTTPS SSL Profile: EAPI'
+- VerifyAPIHttpsSSL:
+ filters:
+ tags:
+ - pod2-leaf1b
+ profile: EAPI
+ result_overwrite:
+ custom_field: 'eAPI HTTPS SSL Profile: EAPI'
+- VerifyAPIHttpsSSL:
+ filters:
+ tags:
+ - super-spine2
+ profile: EAPI
+ result_overwrite:
+ custom_field: 'eAPI HTTPS SSL Profile: EAPI'
+- VerifyAPIHttpsSSL:
+ filters:
+ tags:
+ - pod1-leaf1b
+ profile: EAPI
+ result_overwrite:
+ custom_field: 'eAPI HTTPS SSL Profile: EAPI'
+- VerifyAPIHttpsSSL:
+ filters:
+ tags:
+ - pod1-leaf6b
+ profile: EAPI
+ result_overwrite:
+ custom_field: 'eAPI HTTPS SSL Profile: EAPI'
+- VerifyAPIHttpsSSL:
+ filters:
+ tags:
+ - pod2-leaf7b
+ profile: EAPI
+ result_overwrite:
+ custom_field: 'eAPI HTTPS SSL Profile: EAPI'
+- VerifyAPIHttpsSSL:
+ filters:
+ tags:
+ - pod1-spine3
+ profile: EAPI
+ result_overwrite:
+ custom_field: 'eAPI HTTPS SSL Profile: EAPI'
+anta.tests.system:
+- VerifyNTP:
+ filters:
+ tags:
+ - pod1-leaf4b
+- VerifyNTP:
+ filters:
+ tags:
+ - pod2-spine1
+- VerifyNTP:
+ filters:
+ tags:
+ - pod1-leaf3b
+- VerifyNTP:
+ filters:
+ tags:
+ - pod1-leaf9a
+- VerifyNTP:
+ filters:
+ tags:
+ - pod1-spine4
+- VerifyNTP:
+ filters:
+ tags:
+ - pod2-leaf5b
+- VerifyNTP:
+ filters:
+ tags:
+ - pod2-leaf2b
+- VerifyNTP:
+ filters:
+ tags:
+ - pod2-leaf8a
+- VerifyNTP:
+ filters:
+ tags:
+ - pod1-leaf2b
+- VerifyNTP:
+ filters:
+ tags:
+ - pod1-leaf5b
+- VerifyNTP:
+ filters:
+ tags:
+ - pod1-leaf8a
+- VerifyNTP:
+ filters:
+ tags:
+ - pod2-spine4
+- VerifyNTP:
+ filters:
+ tags:
+ - pod2-leaf3b
+- VerifyNTP:
+ filters:
+ tags:
+ - pod2-leaf4b
+- VerifyNTP:
+ filters:
+ tags:
+ - pod1-spine1
+- VerifyNTP:
+ filters:
+ tags:
+ - pod2-leaf9a
+- VerifyNTP:
+ filters:
+ tags:
+ - pod2-leaf9b
+- VerifyNTP:
+ filters:
+ tags:
+ - pod2-leaf3a
+- VerifyNTP:
+ filters:
+ tags:
+ - pod1-spine2
+- VerifyNTP:
+ filters:
+ tags:
+ - pod2-leaf4a
+- VerifyNTP:
+ filters:
+ tags:
+ - pod1-leaf8b
+- VerifyNTP:
+ filters:
+ tags:
+ - pod1-leaf2a
+- VerifyNTP:
+ filters:
+ tags:
+ - pod1-leaf5a
+- VerifyNTP:
+ filters:
+ tags:
+ - pod2-leaf8b
+- VerifyNTP:
+ filters:
+ tags:
+ - pod2-leaf5a
+- VerifyNTP:
+ filters:
+ tags:
+ - pod2-leaf2a
+- VerifyNTP:
+ filters:
+ tags:
+ - pod1-leaf9b
+- VerifyNTP:
+ filters:
+ tags:
+ - pod2-spine2
+- VerifyNTP:
+ filters:
+ tags:
+ - pod1-leaf4a
+- VerifyNTP:
+ filters:
+ tags:
+ - pod1-leaf3a
+- VerifyNTP:
+ filters:
+ tags:
+ - pod2-leaf7a
+- VerifyNTP:
+ filters:
+ tags:
+ - pod1-leaf1a
+- VerifyNTP:
+ filters:
+ tags:
+ - super-spine1
+- VerifyNTP:
+ filters:
+ tags:
+ - pod1-leaf6a
+- VerifyNTP:
+ filters:
+ tags:
+ - pod2-leaf6a
+- VerifyNTP:
+ filters:
+ tags:
+ - pod2-leaf1a
+- VerifyNTP:
+ filters:
+ tags:
+ - pod1-leaf10b
+- VerifyNTP:
+ filters:
+ tags:
+ - pod1-leaf7a
+- VerifyNTP:
+ filters:
+ tags:
+ - pod2-leaf10b
+- VerifyNTP:
+ filters:
+ tags:
+ - pod2-leaf10a
+- VerifyNTP:
+ filters:
+ tags:
+ - pod2-spine3
+- VerifyNTP:
+ filters:
+ tags:
+ - pod1-leaf7b
+- VerifyNTP:
+ filters:
+ tags:
+ - pod1-leaf10a
+- VerifyNTP:
+ filters:
+ tags:
+ - pod2-leaf6b
+- VerifyNTP:
+ filters:
+ tags:
+ - pod2-leaf1b
+- VerifyNTP:
+ filters:
+ tags:
+ - super-spine2
+- VerifyNTP:
+ filters:
+ tags:
+ - pod1-leaf1b
+- VerifyNTP:
+ filters:
+ tags:
+ - pod1-leaf6b
+- VerifyNTP:
+ filters:
+ tags:
+ - pod2-leaf7b
+- VerifyNTP:
+ filters:
+ tags:
+ - pod1-spine3
diff --git a/tests/data/test_catalog_medium.yml b/tests/data/test_catalog_medium.yml
new file mode 100644
index 0000000..21e3784
--- /dev/null
+++ b/tests/data/test_catalog_medium.yml
@@ -0,0 +1,2078 @@
+anta.tests.connectivity:
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - leaf1a
+ neighbors:
+ - neighbor_device: leaf1b
+ neighbor_port: Ethernet3/1
+ port: Ethernet3/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet3/1 - Remote: leaf1b Ethernet3/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - leaf1a
+ neighbors:
+ - neighbor_device: leaf1b
+ neighbor_port: Ethernet4/1
+ port: Ethernet4/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet4/1 - Remote: leaf1b Ethernet4/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - leaf1a
+ neighbors:
+ - neighbor_device: spine1
+ neighbor_port: Ethernet1/1
+ port: Ethernet1/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet1/1 - Remote: spine1 Ethernet1/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - leaf1a
+ neighbors:
+ - neighbor_device: spine2
+ neighbor_port: Ethernet1/1
+ port: Ethernet2/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet2/1 - Remote: spine2 Ethernet1/1'
+- VerifyReachability:
+ filters:
+ tags:
+ - leaf1a
+ hosts:
+ - destination: 10.255.255.0
+ repeat: 1
+ source: 10.255.255.1
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet1/1 (IP: 10.255.255.1) - Destination: spine1 Ethernet1/1 (IP: 10.255.255.0)'
+- VerifyReachability:
+ filters:
+ tags:
+ - leaf1a
+ hosts:
+ - destination: 10.255.255.2
+ repeat: 1
+ source: 10.255.255.3
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet2/1 (IP: 10.255.255.3) - Destination: spine2 Ethernet1/1 (IP: 10.255.255.2)'
+- VerifyReachability:
+ filters:
+ tags:
+ - leaf1a
+ hosts:
+ - destination: 10.255.0.1
+ repeat: 1
+ source: 10.255.0.3
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.0.3) - Destination: spine1 Loopback0 (IP: 10.255.0.1)'
+- VerifyReachability:
+ filters:
+ tags:
+ - leaf1a
+ hosts:
+ - destination: 10.255.0.2
+ repeat: 1
+ source: 10.255.0.3
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.0.3) - Destination: spine2 Loopback0 (IP: 10.255.0.2)'
+- VerifyReachability:
+ filters:
+ tags:
+ - leaf1a
+ hosts:
+ - destination: 10.255.0.3
+ repeat: 1
+ source: 10.255.0.3
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.0.3) - Destination: leaf1a Loopback0 (IP: 10.255.0.3)'
+- VerifyReachability:
+ filters:
+ tags:
+ - leaf1a
+ hosts:
+ - destination: 10.255.0.4
+ repeat: 1
+ source: 10.255.0.3
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.0.3) - Destination: leaf1b Loopback0 (IP: 10.255.0.4)'
+- VerifyReachability:
+ filters:
+ tags:
+ - leaf1a
+ hosts:
+ - destination: 10.255.0.5
+ repeat: 1
+ source: 10.255.0.3
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.0.3) - Destination: leaf2a Loopback0 (IP: 10.255.0.5)'
+- VerifyReachability:
+ filters:
+ tags:
+ - leaf1a
+ hosts:
+ - destination: 10.255.0.6
+ repeat: 1
+ source: 10.255.0.3
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.0.3) - Destination: leaf2b Loopback0 (IP: 10.255.0.6)'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - leaf1b
+ neighbors:
+ - neighbor_device: leaf1a
+ neighbor_port: Ethernet3/1
+ port: Ethernet3/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet3/1 - Remote: leaf1a Ethernet3/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - leaf1b
+ neighbors:
+ - neighbor_device: leaf1a
+ neighbor_port: Ethernet4/1
+ port: Ethernet4/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet4/1 - Remote: leaf1a Ethernet4/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - leaf1b
+ neighbors:
+ - neighbor_device: spine1
+ neighbor_port: Ethernet2/1
+ port: Ethernet1/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet1/1 - Remote: spine1 Ethernet2/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - leaf1b
+ neighbors:
+ - neighbor_device: spine2
+ neighbor_port: Ethernet2/1
+ port: Ethernet2/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet2/1 - Remote: spine2 Ethernet2/1'
+- VerifyReachability:
+ filters:
+ tags:
+ - leaf1b
+ hosts:
+ - destination: 10.255.255.4
+ repeat: 1
+ source: 10.255.255.5
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet1/1 (IP: 10.255.255.5) - Destination: spine1 Ethernet2/1 (IP: 10.255.255.4)'
+- VerifyReachability:
+ filters:
+ tags:
+ - leaf1b
+ hosts:
+ - destination: 10.255.255.6
+ repeat: 1
+ source: 10.255.255.7
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet2/1 (IP: 10.255.255.7) - Destination: spine2 Ethernet2/1 (IP: 10.255.255.6)'
+- VerifyReachability:
+ filters:
+ tags:
+ - leaf1b
+ hosts:
+ - destination: 10.255.0.1
+ repeat: 1
+ source: 10.255.0.4
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.0.4) - Destination: spine1 Loopback0 (IP: 10.255.0.1)'
+- VerifyReachability:
+ filters:
+ tags:
+ - leaf1b
+ hosts:
+ - destination: 10.255.0.2
+ repeat: 1
+ source: 10.255.0.4
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.0.4) - Destination: spine2 Loopback0 (IP: 10.255.0.2)'
+- VerifyReachability:
+ filters:
+ tags:
+ - leaf1b
+ hosts:
+ - destination: 10.255.0.3
+ repeat: 1
+ source: 10.255.0.4
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.0.4) - Destination: leaf1a Loopback0 (IP: 10.255.0.3)'
+- VerifyReachability:
+ filters:
+ tags:
+ - leaf1b
+ hosts:
+ - destination: 10.255.0.4
+ repeat: 1
+ source: 10.255.0.4
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.0.4) - Destination: leaf1b Loopback0 (IP: 10.255.0.4)'
+- VerifyReachability:
+ filters:
+ tags:
+ - leaf1b
+ hosts:
+ - destination: 10.255.0.5
+ repeat: 1
+ source: 10.255.0.4
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.0.4) - Destination: leaf2a Loopback0 (IP: 10.255.0.5)'
+- VerifyReachability:
+ filters:
+ tags:
+ - leaf1b
+ hosts:
+ - destination: 10.255.0.6
+ repeat: 1
+ source: 10.255.0.4
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.0.4) - Destination: leaf2b Loopback0 (IP: 10.255.0.6)'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - spine1
+ neighbors:
+ - neighbor_device: leaf1a
+ neighbor_port: Ethernet1/1
+ port: Ethernet1/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet1/1 - Remote: leaf1a Ethernet1/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - spine1
+ neighbors:
+ - neighbor_device: leaf1b
+ neighbor_port: Ethernet1/1
+ port: Ethernet2/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet2/1 - Remote: leaf1b Ethernet1/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - spine1
+ neighbors:
+ - neighbor_device: leaf2a
+ neighbor_port: Ethernet1/1
+ port: Ethernet3/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet3/1 - Remote: leaf2a Ethernet1/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - spine1
+ neighbors:
+ - neighbor_device: leaf2b
+ neighbor_port: Ethernet1/1
+ port: Ethernet4/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet4/1 - Remote: leaf2b Ethernet1/1'
+- VerifyReachability:
+ filters:
+ tags:
+ - spine1
+ hosts:
+ - destination: 10.255.255.1
+ repeat: 1
+ source: 10.255.255.0
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet1/1 (IP: 10.255.255.0) - Destination: leaf1a Ethernet1/1 (IP: 10.255.255.1)'
+- VerifyReachability:
+ filters:
+ tags:
+ - spine1
+ hosts:
+ - destination: 10.255.255.5
+ repeat: 1
+ source: 10.255.255.4
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet2/1 (IP: 10.255.255.4) - Destination: leaf1b Ethernet1/1 (IP: 10.255.255.5)'
+- VerifyReachability:
+ filters:
+ tags:
+ - spine1
+ hosts:
+ - destination: 10.255.255.9
+ repeat: 1
+ source: 10.255.255.8
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet3/1 (IP: 10.255.255.8) - Destination: leaf2a Ethernet1/1 (IP: 10.255.255.9)'
+- VerifyReachability:
+ filters:
+ tags:
+ - spine1
+ hosts:
+ - destination: 10.255.255.13
+ repeat: 1
+ source: 10.255.255.12
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet4/1 (IP: 10.255.255.12) - Destination: leaf2b Ethernet1/1 (IP: 10.255.255.13)'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - leaf2b
+ neighbors:
+ - neighbor_device: leaf2a
+ neighbor_port: Ethernet3/1
+ port: Ethernet3/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet3/1 - Remote: leaf2a Ethernet3/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - leaf2b
+ neighbors:
+ - neighbor_device: leaf2a
+ neighbor_port: Ethernet4/1
+ port: Ethernet4/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet4/1 - Remote: leaf2a Ethernet4/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - leaf2b
+ neighbors:
+ - neighbor_device: spine1
+ neighbor_port: Ethernet4/1
+ port: Ethernet1/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet1/1 - Remote: spine1 Ethernet4/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - leaf2b
+ neighbors:
+ - neighbor_device: spine2
+ neighbor_port: Ethernet4/1
+ port: Ethernet2/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet2/1 - Remote: spine2 Ethernet4/1'
+- VerifyReachability:
+ filters:
+ tags:
+ - leaf2b
+ hosts:
+ - destination: 10.255.255.12
+ repeat: 1
+ source: 10.255.255.13
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet1/1 (IP: 10.255.255.13) - Destination: spine1 Ethernet4/1 (IP: 10.255.255.12)'
+- VerifyReachability:
+ filters:
+ tags:
+ - leaf2b
+ hosts:
+ - destination: 10.255.255.14
+ repeat: 1
+ source: 10.255.255.15
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet2/1 (IP: 10.255.255.15) - Destination: spine2 Ethernet4/1 (IP: 10.255.255.14)'
+- VerifyReachability:
+ filters:
+ tags:
+ - leaf2b
+ hosts:
+ - destination: 10.255.0.1
+ repeat: 1
+ source: 10.255.0.6
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.0.6) - Destination: spine1 Loopback0 (IP: 10.255.0.1)'
+- VerifyReachability:
+ filters:
+ tags:
+ - leaf2b
+ hosts:
+ - destination: 10.255.0.2
+ repeat: 1
+ source: 10.255.0.6
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.0.6) - Destination: spine2 Loopback0 (IP: 10.255.0.2)'
+- VerifyReachability:
+ filters:
+ tags:
+ - leaf2b
+ hosts:
+ - destination: 10.255.0.3
+ repeat: 1
+ source: 10.255.0.6
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.0.6) - Destination: leaf1a Loopback0 (IP: 10.255.0.3)'
+- VerifyReachability:
+ filters:
+ tags:
+ - leaf2b
+ hosts:
+ - destination: 10.255.0.4
+ repeat: 1
+ source: 10.255.0.6
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.0.6) - Destination: leaf1b Loopback0 (IP: 10.255.0.4)'
+- VerifyReachability:
+ filters:
+ tags:
+ - leaf2b
+ hosts:
+ - destination: 10.255.0.5
+ repeat: 1
+ source: 10.255.0.6
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.0.6) - Destination: leaf2a Loopback0 (IP: 10.255.0.5)'
+- VerifyReachability:
+ filters:
+ tags:
+ - leaf2b
+ hosts:
+ - destination: 10.255.0.6
+ repeat: 1
+ source: 10.255.0.6
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.0.6) - Destination: leaf2b Loopback0 (IP: 10.255.0.6)'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - leaf2a
+ neighbors:
+ - neighbor_device: leaf2b
+ neighbor_port: Ethernet3/1
+ port: Ethernet3/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet3/1 - Remote: leaf2b Ethernet3/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - leaf2a
+ neighbors:
+ - neighbor_device: leaf2b
+ neighbor_port: Ethernet4/1
+ port: Ethernet4/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet4/1 - Remote: leaf2b Ethernet4/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - leaf2a
+ neighbors:
+ - neighbor_device: spine1
+ neighbor_port: Ethernet3/1
+ port: Ethernet1/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet1/1 - Remote: spine1 Ethernet3/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - leaf2a
+ neighbors:
+ - neighbor_device: spine2
+ neighbor_port: Ethernet3/1
+ port: Ethernet2/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet2/1 - Remote: spine2 Ethernet3/1'
+- VerifyReachability:
+ filters:
+ tags:
+ - leaf2a
+ hosts:
+ - destination: 10.255.255.8
+ repeat: 1
+ source: 10.255.255.9
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet1/1 (IP: 10.255.255.9) - Destination: spine1 Ethernet3/1 (IP: 10.255.255.8)'
+- VerifyReachability:
+ filters:
+ tags:
+ - leaf2a
+ hosts:
+ - destination: 10.255.255.10
+ repeat: 1
+ source: 10.255.255.11
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet2/1 (IP: 10.255.255.11) - Destination: spine2 Ethernet3/1 (IP: 10.255.255.10)'
+- VerifyReachability:
+ filters:
+ tags:
+ - leaf2a
+ hosts:
+ - destination: 10.255.0.1
+ repeat: 1
+ source: 10.255.0.5
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.0.5) - Destination: spine1 Loopback0 (IP: 10.255.0.1)'
+- VerifyReachability:
+ filters:
+ tags:
+ - leaf2a
+ hosts:
+ - destination: 10.255.0.2
+ repeat: 1
+ source: 10.255.0.5
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.0.5) - Destination: spine2 Loopback0 (IP: 10.255.0.2)'
+- VerifyReachability:
+ filters:
+ tags:
+ - leaf2a
+ hosts:
+ - destination: 10.255.0.3
+ repeat: 1
+ source: 10.255.0.5
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.0.5) - Destination: leaf1a Loopback0 (IP: 10.255.0.3)'
+- VerifyReachability:
+ filters:
+ tags:
+ - leaf2a
+ hosts:
+ - destination: 10.255.0.4
+ repeat: 1
+ source: 10.255.0.5
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.0.5) - Destination: leaf1b Loopback0 (IP: 10.255.0.4)'
+- VerifyReachability:
+ filters:
+ tags:
+ - leaf2a
+ hosts:
+ - destination: 10.255.0.5
+ repeat: 1
+ source: 10.255.0.5
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.0.5) - Destination: leaf2a Loopback0 (IP: 10.255.0.5)'
+- VerifyReachability:
+ filters:
+ tags:
+ - leaf2a
+ hosts:
+ - destination: 10.255.0.6
+ repeat: 1
+ source: 10.255.0.5
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: Loopback0 (IP: 10.255.0.5) - Destination: leaf2b Loopback0 (IP: 10.255.0.6)'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - spine2
+ neighbors:
+ - neighbor_device: leaf1a
+ neighbor_port: Ethernet2/1
+ port: Ethernet1/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet1/1 - Remote: leaf1a Ethernet2/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - spine2
+ neighbors:
+ - neighbor_device: leaf1b
+ neighbor_port: Ethernet2/1
+ port: Ethernet2/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet2/1 - Remote: leaf1b Ethernet2/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - spine2
+ neighbors:
+ - neighbor_device: leaf2a
+ neighbor_port: Ethernet2/1
+ port: Ethernet3/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet3/1 - Remote: leaf2a Ethernet2/1'
+- VerifyLLDPNeighbors:
+ filters:
+ tags:
+ - spine2
+ neighbors:
+ - neighbor_device: leaf2b
+ neighbor_port: Ethernet2/1
+ port: Ethernet4/1
+ result_overwrite:
+ custom_field: 'Local: Ethernet4/1 - Remote: leaf2b Ethernet2/1'
+- VerifyReachability:
+ filters:
+ tags:
+ - spine2
+ hosts:
+ - destination: 10.255.255.3
+ repeat: 1
+ source: 10.255.255.2
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet1/1 (IP: 10.255.255.2) - Destination: leaf1a Ethernet2/1 (IP: 10.255.255.3)'
+- VerifyReachability:
+ filters:
+ tags:
+ - spine2
+ hosts:
+ - destination: 10.255.255.7
+ repeat: 1
+ source: 10.255.255.6
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet2/1 (IP: 10.255.255.6) - Destination: leaf1b Ethernet2/1 (IP: 10.255.255.7)'
+- VerifyReachability:
+ filters:
+ tags:
+ - spine2
+ hosts:
+ - destination: 10.255.255.11
+ repeat: 1
+ source: 10.255.255.10
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet3/1 (IP: 10.255.255.10) - Destination: leaf2a Ethernet2/1 (IP: 10.255.255.11)'
+- VerifyReachability:
+ filters:
+ tags:
+ - spine2
+ hosts:
+ - destination: 10.255.255.15
+ repeat: 1
+ source: 10.255.255.14
+ vrf: default
+ result_overwrite:
+ custom_field: 'Source: P2P Interface Ethernet4/1 (IP: 10.255.255.14) - Destination: leaf2b Ethernet2/1 (IP: 10.255.255.15)'
+anta.tests.hardware:
+- VerifyEnvironmentPower:
+ filters:
+ tags:
+ - leaf1a
+ result_overwrite:
+ custom_field: 'Accepted States: ''ok'''
+ states:
+ - ok
+- VerifyEnvironmentCooling:
+ filters:
+ tags:
+ - leaf1a
+ result_overwrite:
+ custom_field: 'Accepted States: ''ok'''
+ states:
+ - ok
+- VerifyTemperature:
+ filters:
+ tags:
+ - leaf1a
+- VerifyTransceiversManufacturers:
+ filters:
+ tags:
+ - leaf1a
+ manufacturers:
+ - Arista Networks
+ - Arastra, Inc.
+ - Not Present
+ result_overwrite:
+ custom_field: 'Accepted Manufacturers: ''Arista Networks'', ''Arastra, Inc.'', ''Not Present'''
+- VerifyEnvironmentPower:
+ filters:
+ tags:
+ - leaf1b
+ result_overwrite:
+ custom_field: 'Accepted States: ''ok'''
+ states:
+ - ok
+- VerifyEnvironmentCooling:
+ filters:
+ tags:
+ - leaf1b
+ result_overwrite:
+ custom_field: 'Accepted States: ''ok'''
+ states:
+ - ok
+- VerifyTemperature:
+ filters:
+ tags:
+ - leaf1b
+- VerifyTransceiversManufacturers:
+ filters:
+ tags:
+ - leaf1b
+ manufacturers:
+ - Arista Networks
+ - Arastra, Inc.
+ - Not Present
+ result_overwrite:
+ custom_field: 'Accepted Manufacturers: ''Arista Networks'', ''Arastra, Inc.'', ''Not Present'''
+- VerifyEnvironmentPower:
+ filters:
+ tags:
+ - spine1
+ result_overwrite:
+ custom_field: 'Accepted States: ''ok'''
+ states:
+ - ok
+- VerifyEnvironmentCooling:
+ filters:
+ tags:
+ - spine1
+ result_overwrite:
+ custom_field: 'Accepted States: ''ok'''
+ states:
+ - ok
+- VerifyTemperature:
+ filters:
+ tags:
+ - spine1
+- VerifyTransceiversManufacturers:
+ filters:
+ tags:
+ - spine1
+ manufacturers:
+ - Arista Networks
+ - Arastra, Inc.
+ - Not Present
+ result_overwrite:
+ custom_field: 'Accepted Manufacturers: ''Arista Networks'', ''Arastra, Inc.'', ''Not Present'''
+- VerifyEnvironmentPower:
+ filters:
+ tags:
+ - leaf2b
+ result_overwrite:
+ custom_field: 'Accepted States: ''ok'''
+ states:
+ - ok
+- VerifyEnvironmentCooling:
+ filters:
+ tags:
+ - leaf2b
+ result_overwrite:
+ custom_field: 'Accepted States: ''ok'''
+ states:
+ - ok
+- VerifyTemperature:
+ filters:
+ tags:
+ - leaf2b
+- VerifyTransceiversManufacturers:
+ filters:
+ tags:
+ - leaf2b
+ manufacturers:
+ - Arista Networks
+ - Arastra, Inc.
+ - Not Present
+ result_overwrite:
+ custom_field: 'Accepted Manufacturers: ''Arista Networks'', ''Arastra, Inc.'', ''Not Present'''
+- VerifyEnvironmentPower:
+ filters:
+ tags:
+ - leaf2a
+ result_overwrite:
+ custom_field: 'Accepted States: ''ok'''
+ states:
+ - ok
+- VerifyEnvironmentCooling:
+ filters:
+ tags:
+ - leaf2a
+ result_overwrite:
+ custom_field: 'Accepted States: ''ok'''
+ states:
+ - ok
+- VerifyTemperature:
+ filters:
+ tags:
+ - leaf2a
+- VerifyTransceiversManufacturers:
+ filters:
+ tags:
+ - leaf2a
+ manufacturers:
+ - Arista Networks
+ - Arastra, Inc.
+ - Not Present
+ result_overwrite:
+ custom_field: 'Accepted Manufacturers: ''Arista Networks'', ''Arastra, Inc.'', ''Not Present'''
+- VerifyEnvironmentPower:
+ filters:
+ tags:
+ - spine2
+ result_overwrite:
+ custom_field: 'Accepted States: ''ok'''
+ states:
+ - ok
+- VerifyEnvironmentCooling:
+ filters:
+ tags:
+ - spine2
+ result_overwrite:
+ custom_field: 'Accepted States: ''ok'''
+ states:
+ - ok
+- VerifyTemperature:
+ filters:
+ tags:
+ - spine2
+- VerifyTransceiversManufacturers:
+ filters:
+ tags:
+ - spine2
+ manufacturers:
+ - Arista Networks
+ - Arastra, Inc.
+ - Not Present
+ result_overwrite:
+ custom_field: 'Accepted Manufacturers: ''Arista Networks'', ''Arastra, Inc.'', ''Not Present'''
+anta.tests.interfaces:
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - leaf1a
+ interfaces:
+ - name: Ethernet3/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet3/1 - MLAG_PEER_leaf1b_Ethernet3/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - leaf1a
+ interfaces:
+ - name: Ethernet4/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet4/1 - MLAG_PEER_leaf1b_Ethernet4/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - leaf1a
+ interfaces:
+ - name: Ethernet1/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet1/1 - P2P_LINK_TO_SPINE1_Ethernet1/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - leaf1a
+ interfaces:
+ - name: Ethernet2/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet2/1 - P2P_LINK_TO_SPINE2_Ethernet1/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - leaf1a
+ interfaces:
+ - name: Port-Channel31
+ status: up
+ result_overwrite:
+ custom_field: Interface Port-Channel31 - MLAG_PEER_leaf1b_Po31 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - leaf1a
+ interfaces:
+ - name: Vlan4093
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan4093 - MLAG_PEER_L3_PEERING = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - leaf1a
+ interfaces:
+ - name: Vlan4094
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan4094 - MLAG_PEER = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - leaf1a
+ interfaces:
+ - name: Loopback0
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback0 - EVPN_Overlay_Peering = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - leaf1a
+ interfaces:
+ - name: Loopback1
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback1 - VTEP_VXLAN_Tunnel_Source = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - leaf1a
+ interfaces:
+ - name: Vxlan1
+ status: up
+ result_overwrite:
+ custom_field: Interface Vxlan1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - leaf1b
+ interfaces:
+ - name: Ethernet3/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet3/1 - MLAG_PEER_leaf1a_Ethernet3/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - leaf1b
+ interfaces:
+ - name: Ethernet4/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet4/1 - MLAG_PEER_leaf1a_Ethernet4/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - leaf1b
+ interfaces:
+ - name: Ethernet1/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet1/1 - P2P_LINK_TO_SPINE1_Ethernet2/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - leaf1b
+ interfaces:
+ - name: Ethernet2/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet2/1 - P2P_LINK_TO_SPINE2_Ethernet2/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - leaf1b
+ interfaces:
+ - name: Port-Channel31
+ status: up
+ result_overwrite:
+ custom_field: Interface Port-Channel31 - MLAG_PEER_leaf1a_Po31 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - leaf1b
+ interfaces:
+ - name: Vlan4093
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan4093 - MLAG_PEER_L3_PEERING = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - leaf1b
+ interfaces:
+ - name: Vlan4094
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan4094 - MLAG_PEER = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - leaf1b
+ interfaces:
+ - name: Loopback0
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback0 - EVPN_Overlay_Peering = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - leaf1b
+ interfaces:
+ - name: Loopback1
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback1 - VTEP_VXLAN_Tunnel_Source = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - leaf1b
+ interfaces:
+ - name: Vxlan1
+ status: up
+ result_overwrite:
+ custom_field: Interface Vxlan1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - spine1
+ interfaces:
+ - name: Ethernet1/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet1/1 - P2P_LINK_TO_LEAF1A_Ethernet1/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - spine1
+ interfaces:
+ - name: Ethernet2/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet2/1 - P2P_LINK_TO_LEAF1B_Ethernet1/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - spine1
+ interfaces:
+ - name: Ethernet3/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet3/1 - P2P_LINK_TO_LEAF2A_Ethernet1/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - spine1
+ interfaces:
+ - name: Ethernet4/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet4/1 - P2P_LINK_TO_LEAF2B_Ethernet1/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - spine1
+ interfaces:
+ - name: Loopback0
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback0 - EVPN_Overlay_Peering = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - leaf2b
+ interfaces:
+ - name: Ethernet3/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet3/1 - MLAG_PEER_leaf2a_Ethernet3/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - leaf2b
+ interfaces:
+ - name: Ethernet4/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet4/1 - MLAG_PEER_leaf2a_Ethernet4/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - leaf2b
+ interfaces:
+ - name: Ethernet1/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet1/1 - P2P_LINK_TO_SPINE1_Ethernet4/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - leaf2b
+ interfaces:
+ - name: Ethernet2/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet2/1 - P2P_LINK_TO_SPINE2_Ethernet4/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - leaf2b
+ interfaces:
+ - name: Port-Channel31
+ status: up
+ result_overwrite:
+ custom_field: Interface Port-Channel31 - MLAG_PEER_leaf2a_Po31 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - leaf2b
+ interfaces:
+ - name: Vlan4093
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan4093 - MLAG_PEER_L3_PEERING = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - leaf2b
+ interfaces:
+ - name: Vlan4094
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan4094 - MLAG_PEER = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - leaf2b
+ interfaces:
+ - name: Loopback0
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback0 - EVPN_Overlay_Peering = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - leaf2b
+ interfaces:
+ - name: Loopback1
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback1 - VTEP_VXLAN_Tunnel_Source = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - leaf2b
+ interfaces:
+ - name: Vxlan1
+ status: up
+ result_overwrite:
+ custom_field: Interface Vxlan1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - leaf2a
+ interfaces:
+ - name: Ethernet3/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet3/1 - MLAG_PEER_leaf2b_Ethernet3/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - leaf2a
+ interfaces:
+ - name: Ethernet4/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet4/1 - MLAG_PEER_leaf2b_Ethernet4/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - leaf2a
+ interfaces:
+ - name: Ethernet1/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet1/1 - P2P_LINK_TO_SPINE1_Ethernet3/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - leaf2a
+ interfaces:
+ - name: Ethernet2/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet2/1 - P2P_LINK_TO_SPINE2_Ethernet3/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - leaf2a
+ interfaces:
+ - name: Port-Channel31
+ status: up
+ result_overwrite:
+ custom_field: Interface Port-Channel31 - MLAG_PEER_leaf2b_Po31 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - leaf2a
+ interfaces:
+ - name: Vlan4093
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan4093 - MLAG_PEER_L3_PEERING = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - leaf2a
+ interfaces:
+ - name: Vlan4094
+ status: up
+ result_overwrite:
+ custom_field: Interface Vlan4094 - MLAG_PEER = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - leaf2a
+ interfaces:
+ - name: Loopback0
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback0 - EVPN_Overlay_Peering = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - leaf2a
+ interfaces:
+ - name: Loopback1
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback1 - VTEP_VXLAN_Tunnel_Source = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - leaf2a
+ interfaces:
+ - name: Vxlan1
+ status: up
+ result_overwrite:
+ custom_field: Interface Vxlan1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - spine2
+ interfaces:
+ - name: Ethernet1/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet1/1 - P2P_LINK_TO_LEAF1A_Ethernet2/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - spine2
+ interfaces:
+ - name: Ethernet2/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet2/1 - P2P_LINK_TO_LEAF1B_Ethernet2/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - spine2
+ interfaces:
+ - name: Ethernet3/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet3/1 - P2P_LINK_TO_LEAF2A_Ethernet2/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - spine2
+ interfaces:
+ - name: Ethernet4/1
+ status: up
+ result_overwrite:
+ custom_field: Interface Ethernet4/1 - P2P_LINK_TO_LEAF2B_Ethernet2/1 = 'up'
+- VerifyInterfacesStatus:
+ filters:
+ tags:
+ - spine2
+ interfaces:
+ - name: Loopback0
+ status: up
+ result_overwrite:
+ custom_field: Interface Loopback0 - EVPN_Overlay_Peering = 'up'
+anta.tests.mlag:
+- VerifyMlagStatus:
+ filters:
+ tags:
+ - leaf1a
+- VerifyMlagStatus:
+ filters:
+ tags:
+ - leaf1b
+- VerifyMlagStatus:
+ filters:
+ tags:
+ - leaf2b
+- VerifyMlagStatus:
+ filters:
+ tags:
+ - leaf2a
+anta.tests.routing.bgp:
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.0.1
+ filters:
+ tags:
+ - leaf1a
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: spine1 (IP: 10.255.0.1)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.0.2
+ filters:
+ tags:
+ - leaf1a
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: spine2 (IP: 10.255.0.2)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.1.97
+ safi: unicast
+ filters:
+ tags:
+ - leaf1a
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: leaf1b (IP: 10.255.1.97)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.0
+ safi: unicast
+ filters:
+ tags:
+ - leaf1a
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: spine1 (IP: 10.255.255.0)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.2
+ safi: unicast
+ filters:
+ tags:
+ - leaf1a
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: spine2 (IP: 10.255.255.2)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.0.1
+ filters:
+ tags:
+ - leaf1b
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: spine1 (IP: 10.255.0.1)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.0.2
+ filters:
+ tags:
+ - leaf1b
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: spine2 (IP: 10.255.0.2)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.1.96
+ safi: unicast
+ filters:
+ tags:
+ - leaf1b
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: leaf1a (IP: 10.255.1.96)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.4
+ safi: unicast
+ filters:
+ tags:
+ - leaf1b
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: spine1 (IP: 10.255.255.4)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.6
+ safi: unicast
+ filters:
+ tags:
+ - leaf1b
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: spine2 (IP: 10.255.255.6)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.0.3
+ filters:
+ tags:
+ - spine1
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: leaf1a (IP: 10.255.0.3)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.0.4
+ filters:
+ tags:
+ - spine1
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: leaf1b (IP: 10.255.0.4)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.0.5
+ filters:
+ tags:
+ - spine1
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: leaf2a (IP: 10.255.0.5)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.0.6
+ filters:
+ tags:
+ - spine1
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: leaf2b (IP: 10.255.0.6)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.1
+ safi: unicast
+ filters:
+ tags:
+ - spine1
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: leaf1a (IP: 10.255.255.1)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.5
+ safi: unicast
+ filters:
+ tags:
+ - spine1
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: leaf1b (IP: 10.255.255.5)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.9
+ safi: unicast
+ filters:
+ tags:
+ - spine1
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: leaf2a (IP: 10.255.255.9)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.13
+ safi: unicast
+ filters:
+ tags:
+ - spine1
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: leaf2b (IP: 10.255.255.13)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.0.1
+ filters:
+ tags:
+ - leaf2b
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: spine1 (IP: 10.255.0.1)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.0.2
+ filters:
+ tags:
+ - leaf2b
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: spine2 (IP: 10.255.0.2)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.1.100
+ safi: unicast
+ filters:
+ tags:
+ - leaf2b
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: leaf2a (IP: 10.255.1.100)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.12
+ safi: unicast
+ filters:
+ tags:
+ - leaf2b
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: spine1 (IP: 10.255.255.12)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.14
+ safi: unicast
+ filters:
+ tags:
+ - leaf2b
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: spine2 (IP: 10.255.255.14)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.0.1
+ filters:
+ tags:
+ - leaf2a
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: spine1 (IP: 10.255.0.1)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.0.2
+ filters:
+ tags:
+ - leaf2a
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: spine2 (IP: 10.255.0.2)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.1.101
+ safi: unicast
+ filters:
+ tags:
+ - leaf2a
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: leaf2b (IP: 10.255.1.101)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.8
+ safi: unicast
+ filters:
+ tags:
+ - leaf2a
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: spine1 (IP: 10.255.255.8)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.10
+ safi: unicast
+ filters:
+ tags:
+ - leaf2a
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: spine2 (IP: 10.255.255.10)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.0.3
+ filters:
+ tags:
+ - spine2
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: leaf1a (IP: 10.255.0.3)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.0.4
+ filters:
+ tags:
+ - spine2
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: leaf1b (IP: 10.255.0.4)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.0.5
+ filters:
+ tags:
+ - spine2
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: leaf2a (IP: 10.255.0.5)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: evpn
+ peers:
+ - 10.255.0.6
+ filters:
+ tags:
+ - spine2
+ result_overwrite:
+ custom_field: 'BGP EVPN Peer: leaf2b (IP: 10.255.0.6)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.3
+ safi: unicast
+ filters:
+ tags:
+ - spine2
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: leaf1a (IP: 10.255.255.3)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.7
+ safi: unicast
+ filters:
+ tags:
+ - spine2
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: leaf1b (IP: 10.255.255.7)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.11
+ safi: unicast
+ filters:
+ tags:
+ - spine2
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: leaf2a (IP: 10.255.255.11)'
+- VerifyBGPSpecificPeers:
+ address_families:
+ - afi: ipv4
+ peers:
+ - 10.255.255.15
+ safi: unicast
+ filters:
+ tags:
+ - spine2
+ result_overwrite:
+ custom_field: 'BGP IPv4 Unicast Peer: leaf2b (IP: 10.255.255.15)'
+anta.tests.routing.generic:
+- VerifyRoutingProtocolModel:
+ filters:
+ tags:
+ - leaf1a
+ model: multi-agent
+ result_overwrite:
+ custom_field: 'Routing protocol model: multi-agent'
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - leaf1a
+ result_overwrite:
+ custom_field: 'Route: 10.255.0.1 - Peer: spine1'
+ routes:
+ - 10.255.0.1
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - leaf1a
+ result_overwrite:
+ custom_field: 'Route: 10.255.0.2 - Peer: spine2'
+ routes:
+ - 10.255.0.2
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - leaf1a
+ result_overwrite:
+ custom_field: 'Route: 10.255.0.3 - Peer: leaf1a'
+ routes:
+ - 10.255.0.3
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - leaf1a
+ result_overwrite:
+ custom_field: 'Route: 10.255.0.4 - Peer: leaf1b'
+ routes:
+ - 10.255.0.4
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - leaf1a
+ result_overwrite:
+ custom_field: 'Route: 10.255.0.5 - Peer: leaf2a'
+ routes:
+ - 10.255.0.5
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - leaf1a
+ result_overwrite:
+ custom_field: 'Route: 10.255.0.6 - Peer: leaf2b'
+ routes:
+ - 10.255.0.6
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - leaf1a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.3 - Peer: leaf1a'
+ routes:
+ - 10.255.1.3
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - leaf1a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.5 - Peer: leaf2a'
+ routes:
+ - 10.255.1.5
+- VerifyRoutingProtocolModel:
+ filters:
+ tags:
+ - leaf1b
+ model: multi-agent
+ result_overwrite:
+ custom_field: 'Routing protocol model: multi-agent'
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - leaf1b
+ result_overwrite:
+ custom_field: 'Route: 10.255.0.1 - Peer: spine1'
+ routes:
+ - 10.255.0.1
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - leaf1b
+ result_overwrite:
+ custom_field: 'Route: 10.255.0.2 - Peer: spine2'
+ routes:
+ - 10.255.0.2
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - leaf1b
+ result_overwrite:
+ custom_field: 'Route: 10.255.0.3 - Peer: leaf1a'
+ routes:
+ - 10.255.0.3
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - leaf1b
+ result_overwrite:
+ custom_field: 'Route: 10.255.0.4 - Peer: leaf1b'
+ routes:
+ - 10.255.0.4
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - leaf1b
+ result_overwrite:
+ custom_field: 'Route: 10.255.0.5 - Peer: leaf2a'
+ routes:
+ - 10.255.0.5
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - leaf1b
+ result_overwrite:
+ custom_field: 'Route: 10.255.0.6 - Peer: leaf2b'
+ routes:
+ - 10.255.0.6
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - leaf1b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.3 - Peer: leaf1a'
+ routes:
+ - 10.255.1.3
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - leaf1b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.5 - Peer: leaf2a'
+ routes:
+ - 10.255.1.5
+- VerifyRoutingProtocolModel:
+ filters:
+ tags:
+ - spine1
+ model: multi-agent
+ result_overwrite:
+ custom_field: 'Routing protocol model: multi-agent'
+- VerifyRoutingProtocolModel:
+ filters:
+ tags:
+ - leaf2b
+ model: multi-agent
+ result_overwrite:
+ custom_field: 'Routing protocol model: multi-agent'
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - leaf2b
+ result_overwrite:
+ custom_field: 'Route: 10.255.0.1 - Peer: spine1'
+ routes:
+ - 10.255.0.1
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - leaf2b
+ result_overwrite:
+ custom_field: 'Route: 10.255.0.2 - Peer: spine2'
+ routes:
+ - 10.255.0.2
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - leaf2b
+ result_overwrite:
+ custom_field: 'Route: 10.255.0.3 - Peer: leaf1a'
+ routes:
+ - 10.255.0.3
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - leaf2b
+ result_overwrite:
+ custom_field: 'Route: 10.255.0.4 - Peer: leaf1b'
+ routes:
+ - 10.255.0.4
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - leaf2b
+ result_overwrite:
+ custom_field: 'Route: 10.255.0.5 - Peer: leaf2a'
+ routes:
+ - 10.255.0.5
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - leaf2b
+ result_overwrite:
+ custom_field: 'Route: 10.255.0.6 - Peer: leaf2b'
+ routes:
+ - 10.255.0.6
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - leaf2b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.3 - Peer: leaf1a'
+ routes:
+ - 10.255.1.3
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - leaf2b
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.5 - Peer: leaf2a'
+ routes:
+ - 10.255.1.5
+- VerifyRoutingProtocolModel:
+ filters:
+ tags:
+ - leaf2a
+ model: multi-agent
+ result_overwrite:
+ custom_field: 'Routing protocol model: multi-agent'
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - leaf2a
+ result_overwrite:
+ custom_field: 'Route: 10.255.0.1 - Peer: spine1'
+ routes:
+ - 10.255.0.1
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - leaf2a
+ result_overwrite:
+ custom_field: 'Route: 10.255.0.2 - Peer: spine2'
+ routes:
+ - 10.255.0.2
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - leaf2a
+ result_overwrite:
+ custom_field: 'Route: 10.255.0.3 - Peer: leaf1a'
+ routes:
+ - 10.255.0.3
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - leaf2a
+ result_overwrite:
+ custom_field: 'Route: 10.255.0.4 - Peer: leaf1b'
+ routes:
+ - 10.255.0.4
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - leaf2a
+ result_overwrite:
+ custom_field: 'Route: 10.255.0.5 - Peer: leaf2a'
+ routes:
+ - 10.255.0.5
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - leaf2a
+ result_overwrite:
+ custom_field: 'Route: 10.255.0.6 - Peer: leaf2b'
+ routes:
+ - 10.255.0.6
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - leaf2a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.3 - Peer: leaf1a'
+ routes:
+ - 10.255.1.3
+- VerifyRoutingTableEntry:
+ filters:
+ tags:
+ - leaf2a
+ result_overwrite:
+ custom_field: 'Route: 10.255.1.5 - Peer: leaf2a'
+ routes:
+ - 10.255.1.5
+- VerifyRoutingProtocolModel:
+ filters:
+ tags:
+ - spine2
+ model: multi-agent
+ result_overwrite:
+ custom_field: 'Routing protocol model: multi-agent'
+anta.tests.security:
+- VerifyAPIHttpsSSL:
+ filters:
+ tags:
+ - leaf1a
+ profile: EAPI
+ result_overwrite:
+ custom_field: 'eAPI HTTPS SSL Profile: EAPI'
+- VerifyAPIHttpsSSL:
+ filters:
+ tags:
+ - leaf1b
+ profile: EAPI
+ result_overwrite:
+ custom_field: 'eAPI HTTPS SSL Profile: EAPI'
+- VerifyAPIHttpsSSL:
+ filters:
+ tags:
+ - spine1
+ profile: EAPI
+ result_overwrite:
+ custom_field: 'eAPI HTTPS SSL Profile: EAPI'
+- VerifyAPIHttpsSSL:
+ filters:
+ tags:
+ - leaf2b
+ profile: EAPI
+ result_overwrite:
+ custom_field: 'eAPI HTTPS SSL Profile: EAPI'
+- VerifyAPIHttpsSSL:
+ filters:
+ tags:
+ - leaf2a
+ profile: EAPI
+ result_overwrite:
+ custom_field: 'eAPI HTTPS SSL Profile: EAPI'
+- VerifyAPIHttpsSSL:
+ filters:
+ tags:
+ - spine2
+ profile: EAPI
+ result_overwrite:
+ custom_field: 'eAPI HTTPS SSL Profile: EAPI'
+anta.tests.system:
+- VerifyNTP:
+ filters:
+ tags:
+ - leaf1a
+- VerifyNTP:
+ filters:
+ tags:
+ - leaf1b
+- VerifyNTP:
+ filters:
+ tags:
+ - spine1
+- VerifyNTP:
+ filters:
+ tags:
+ - leaf2b
+- VerifyNTP:
+ filters:
+ tags:
+ - leaf2a
+- VerifyNTP:
+ filters:
+ tags:
+ - spine2
diff --git a/tests/data/test_catalog_with_tags.yml b/tests/data/test_catalog_with_tags.yml
index 0c8f5f6..109781e 100644
--- a/tests/data/test_catalog_with_tags.yml
+++ b/tests/data/test_catalog_with_tags.yml
@@ -4,6 +4,10 @@ anta.tests.system:
minimum: 10
filters:
tags: ['fabric']
+ - VerifyUptime:
+ minimum: 9
+ filters:
+ tags: ['leaf']
- VerifyReloadCause:
filters:
tags: ['leaf', 'spine']
diff --git a/tests/data/test_empty_dict_catalog.yml b/tests/data/test_empty_dict_catalog.yml
new file mode 100644
index 0000000..0967ef4
--- /dev/null
+++ b/tests/data/test_empty_dict_catalog.yml
@@ -0,0 +1 @@
+{}
diff --git a/tests/data/test_inventory_large.yml b/tests/data/test_inventory_large.yml
new file mode 100644
index 0000000..e19461c
--- /dev/null
+++ b/tests/data/test_inventory_large.yml
@@ -0,0 +1,103 @@
+---
+anta_inventory:
+ hosts:
+ - host: localhost
+ name: super-spine1
+ - host: localhost
+ name: super-spine2
+ - host: localhost
+ name: pod1-spine1
+ - host: localhost
+ name: pod1-spine2
+ - host: localhost
+ name: pod1-spine3
+ - host: localhost
+ name: pod1-spine4
+ - host: localhost
+ name: pod1-leaf1a
+ - host: localhost
+ name: pod1-leaf1b
+ - host: localhost
+ name: pod1-leaf2a
+ - host: localhost
+ name: pod1-leaf2b
+ - host: localhost
+ name: pod1-leaf3a
+ - host: localhost
+ name: pod1-leaf3b
+ - host: localhost
+ name: pod1-leaf4a
+ - host: localhost
+ name: pod1-leaf4b
+ - host: localhost
+ name: pod1-leaf5a
+ - host: localhost
+ name: pod1-leaf5b
+ - host: localhost
+ name: pod1-leaf6a
+ - host: localhost
+ name: pod1-leaf6b
+ - host: localhost
+ name: pod1-leaf7a
+ - host: localhost
+ name: pod1-leaf7b
+ - host: localhost
+ name: pod1-leaf8a
+ - host: localhost
+ name: pod1-leaf8b
+ - host: localhost
+ name: pod1-leaf9a
+ - host: localhost
+ name: pod1-leaf9b
+ - host: localhost
+ name: pod1-leaf10a
+ - host: localhost
+ name: pod1-leaf10b
+ - host: localhost
+ name: pod2-spine1
+ - host: localhost
+ name: pod2-spine2
+ - host: localhost
+ name: pod2-spine3
+ - host: localhost
+ name: pod2-spine4
+ - host: localhost
+ name: pod2-leaf1a
+ - host: localhost
+ name: pod2-leaf1b
+ - host: localhost
+ name: pod2-leaf2a
+ - host: localhost
+ name: pod2-leaf2b
+ - host: localhost
+ name: pod2-leaf3a
+ - host: localhost
+ name: pod2-leaf3b
+ - host: localhost
+ name: pod2-leaf4a
+ - host: localhost
+ name: pod2-leaf4b
+ - host: localhost
+ name: pod2-leaf5a
+ - host: localhost
+ name: pod2-leaf5b
+ - host: localhost
+ name: pod2-leaf6a
+ - host: localhost
+ name: pod2-leaf6b
+ - host: localhost
+ name: pod2-leaf7a
+ - host: localhost
+ name: pod2-leaf7b
+ - host: localhost
+ name: pod2-leaf8a
+ - host: localhost
+ name: pod2-leaf8b
+ - host: localhost
+ name: pod2-leaf9a
+ - host: localhost
+ name: pod2-leaf9b
+ - host: localhost
+ name: pod2-leaf10a
+ - host: localhost
+ name: pod2-leaf10b
diff --git a/tests/data/test_inventory_medium.yml b/tests/data/test_inventory_medium.yml
new file mode 100644
index 0000000..6b6e4b7
--- /dev/null
+++ b/tests/data/test_inventory_medium.yml
@@ -0,0 +1,14 @@
+anta_inventory:
+ hosts:
+ - host: localhost
+ name: spine1
+ - host: localhost
+ name: spine2
+ - host: localhost
+ name: leaf1a
+ - host: localhost
+ name: leaf1b
+ - host: localhost
+ name: leaf2a
+ - host: localhost
+ name: leaf2b
diff --git a/tests/lib/__init__.py b/tests/lib/__init__.py
index e772bee..cd54f3a 100644
--- a/tests/lib/__init__.py
+++ b/tests/lib/__init__.py
@@ -1,3 +1,4 @@
# Copyright (c) 2023-2024 Arista Networks, Inc.
# Use of this source code is governed by the Apache License 2.0
# that can be found in the LICENSE file.
+"""Library for ANTA unit tests."""
diff --git a/tests/lib/anta.py b/tests/lib/anta.py
index b97d91d..cabb27b 100644
--- a/tests/lib/anta.py
+++ b/tests/lib/anta.py
@@ -1,20 +1,20 @@
# Copyright (c) 2023-2024 Arista Networks, Inc.
# Use of this source code is governed by the Apache License 2.0
# that can be found in the LICENSE file.
-"""
-generic test funciton used to generate unit tests for each AntaTest
-"""
+"""generic test function used to generate unit tests for each AntaTest."""
+
from __future__ import annotations
import asyncio
-from typing import Any
+from typing import TYPE_CHECKING, Any
-from anta.device import AntaDevice
+if TYPE_CHECKING:
+ from anta.device import AntaDevice
def test(device: AntaDevice, data: dict[str, Any]) -> None:
- """
- Generic test function for AntaTest subclass.
+ """Generic test function for AntaTest subclass.
+
See `tests/units/anta_tests/README.md` for more information on how to use it.
"""
# Instantiate the AntaTest subclass
diff --git a/tests/lib/fixture.py b/tests/lib/fixture.py
index 68e9e57..17943ed 100644
--- a/tests/lib/fixture.py
+++ b/tests/lib/fixture.py
@@ -1,35 +1,39 @@
# Copyright (c) 2023-2024 Arista Networks, Inc.
# Use of this source code is governed by the Apache License 2.0
# that can be found in the LICENSE file.
-"""Fixture for Anta Testing"""
+"""Fixture for Anta Testing."""
+
from __future__ import annotations
import logging
import shutil
-from pathlib import Path
-from typing import Any, Callable, Iterator
+from typing import TYPE_CHECKING, Any, Callable
from unittest.mock import patch
import pytest
from click.testing import CliRunner, Result
-from pytest import CaptureFixture
-from anta import aioeapi
+import asynceapi
from anta.cli.console import console
from anta.device import AntaDevice, AsyncEOSDevice
from anta.inventory import AntaInventory
-from anta.models import AntaCommand
from anta.result_manager import ResultManager
from anta.result_manager.models import TestResult
from tests.lib.utils import default_anta_env
+if TYPE_CHECKING:
+ from collections.abc import Iterator
+ from pathlib import Path
+
+ from anta.models import AntaCommand
+
logger = logging.getLogger(__name__)
DEVICE_HW_MODEL = "pytest"
DEVICE_NAME = "pytest"
COMMAND_OUTPUT = "retrieved"
-MOCK_CLI_JSON: dict[str, aioeapi.EapiCommandError | dict[str, Any]] = {
+MOCK_CLI_JSON: dict[str, asynceapi.EapiCommandError | dict[str, Any]] = {
"show version": {
"modelName": "DCS-7280CR3-32P4-F",
"version": "4.31.1F",
@@ -37,12 +41,16 @@ MOCK_CLI_JSON: dict[str, aioeapi.EapiCommandError | dict[str, Any]] = {
"enable": {},
"clear counters": {},
"clear hardware counter drop": {},
- "undefined": aioeapi.EapiCommandError(
- passed=[], failed="show version", errors=["Authorization denied for command 'show version'"], errmsg="Invalid command", not_exec=[]
+ "undefined": asynceapi.EapiCommandError(
+ passed=[],
+ failed="show version",
+ errors=["Authorization denied for command 'show version'"],
+ errmsg="Invalid command",
+ not_exec=[],
),
}
-MOCK_CLI_TEXT: dict[str, aioeapi.EapiCommandError | str] = {
+MOCK_CLI_TEXT: dict[str, asynceapi.EapiCommandError | str] = {
"show version": "Arista cEOSLab",
"bash timeout 10 ls -1t /mnt/flash/schedule/tech-support": "dummy_tech-support_2023-12-01.1115.log.gz\ndummy_tech-support_2023-12-01.1015.log.gz",
"bash timeout 10 ls -1t /mnt/flash/schedule/tech-support | head -1": "dummy_tech-support_2023-12-01.1115.log.gz",
@@ -50,13 +58,11 @@ MOCK_CLI_TEXT: dict[str, aioeapi.EapiCommandError | str] = {
}
-@pytest.fixture
+@pytest.fixture()
def device(request: pytest.FixtureRequest) -> Iterator[AntaDevice]:
- """
- Returns an AntaDevice instance with mocked abstract method
- """
+ """Return an AntaDevice instance with mocked abstract method."""
- def _collect(command: AntaCommand) -> None:
+ def _collect(command: AntaCommand, *args: Any, **kwargs: Any) -> None: # noqa: ARG001, ANN401 #pylint: disable=unused-argument
command.output = COMMAND_OUTPUT
kwargs = {"name": DEVICE_NAME, "hw_model": DEVICE_HW_MODEL}
@@ -64,22 +70,21 @@ def device(request: pytest.FixtureRequest) -> Iterator[AntaDevice]:
if hasattr(request, "param"):
# Fixture is parametrized indirectly
kwargs.update(request.param)
- with patch.object(AntaDevice, "__abstractmethods__", set()):
- with patch("anta.device.AntaDevice._collect", side_effect=_collect):
- # AntaDevice constructor does not have hw_model argument
- hw_model = kwargs.pop("hw_model")
- dev = AntaDevice(**kwargs) # type: ignore[abstract, arg-type] # pylint: disable=abstract-class-instantiated, unexpected-keyword-arg
- dev.hw_model = hw_model
- yield dev
+ with patch.object(AntaDevice, "__abstractmethods__", set()), patch("anta.device.AntaDevice._collect", side_effect=_collect):
+ # AntaDevice constructor does not have hw_model argument
+ hw_model = kwargs.pop("hw_model")
+ dev = AntaDevice(**kwargs) # type: ignore[abstract, arg-type] # pylint: disable=abstract-class-instantiated, unexpected-keyword-arg
+ dev.hw_model = hw_model
+ yield dev
-@pytest.fixture
+@pytest.fixture()
def test_inventory() -> AntaInventory:
- """
- Return the test_inventory
- """
+ """Return the test_inventory."""
env = default_anta_env()
- assert env["ANTA_INVENTORY"] and env["ANTA_USERNAME"] and env["ANTA_PASSWORD"] is not None
+ assert env["ANTA_INVENTORY"]
+ assert env["ANTA_USERNAME"]
+ assert env["ANTA_PASSWORD"] is not None
return AntaInventory.parse(
filename=env["ANTA_INVENTORY"],
username=env["ANTA_USERNAME"],
@@ -88,34 +93,30 @@ def test_inventory() -> AntaInventory:
# tests.unit.test_device.py fixture
-@pytest.fixture
+@pytest.fixture()
def async_device(request: pytest.FixtureRequest) -> AsyncEOSDevice:
- """
- Returns an AsyncEOSDevice instance
- """
-
- kwargs = {"name": DEVICE_NAME, "host": "42.42.42.42", "username": "anta", "password": "anta"}
+ """Return an AsyncEOSDevice instance."""
+ kwargs = {
+ "name": DEVICE_NAME,
+ "host": "42.42.42.42",
+ "username": "anta",
+ "password": "anta",
+ }
if hasattr(request, "param"):
# Fixture is parametrized indirectly
kwargs.update(request.param)
- dev = AsyncEOSDevice(**kwargs) # type: ignore[arg-type]
- return dev
+ return AsyncEOSDevice(**kwargs) # type: ignore[arg-type]
# tests.units.result_manager fixtures
-@pytest.fixture
+@pytest.fixture()
def test_result_factory(device: AntaDevice) -> Callable[[int], TestResult]:
- """
- Return a anta.result_manager.models.TestResult object
- """
-
+ """Return a anta.result_manager.models.TestResult object."""
# pylint: disable=redefined-outer-name
def _create(index: int = 0) -> TestResult:
- """
- Actual Factory
- """
+ """Actual Factory."""
return TestResult(
name=device.name,
test=f"VerifyTest{index}",
@@ -127,50 +128,39 @@ def test_result_factory(device: AntaDevice) -> Callable[[int], TestResult]:
return _create
-@pytest.fixture
+@pytest.fixture()
def list_result_factory(test_result_factory: Callable[[int], TestResult]) -> Callable[[int], list[TestResult]]:
- """
- Return a list[TestResult] with 'size' TestResult instanciated using the test_result_factory fixture
- """
-
+ """Return a list[TestResult] with 'size' TestResult instantiated using the test_result_factory fixture."""
# pylint: disable=redefined-outer-name
def _factory(size: int = 0) -> list[TestResult]:
- """
- Factory for list[TestResult] entry of size entries
- """
- result: list[TestResult] = []
- for i in range(size):
- result.append(test_result_factory(i))
- return result
+ """Create a factory for list[TestResult] entry of size entries."""
+ return [test_result_factory(i) for i in range(size)]
return _factory
-@pytest.fixture
+@pytest.fixture()
def result_manager_factory(list_result_factory: Callable[[int], list[TestResult]]) -> Callable[[int], ResultManager]:
- """
- Return a ResultManager factory that takes as input a number of tests
- """
-
+ """Return a ResultManager factory that takes as input a number of tests."""
# pylint: disable=redefined-outer-name
def _factory(number: int = 0) -> ResultManager:
- """
- Factory for list[TestResult] entry of size entries
- """
+ """Create a factory for list[TestResult] entry of size entries."""
result_manager = ResultManager()
- result_manager.add_test_results(list_result_factory(number))
+ result_manager.results = list_result_factory(number)
return result_manager
return _factory
# tests.units.cli fixtures
-@pytest.fixture
+@pytest.fixture()
def temp_env(tmp_path: Path) -> dict[str, str | None]:
- """Fixture that create a temporary ANTA inventory that can be overriden
- and returns the corresponding environment variables"""
+ """Fixture that create a temporary ANTA inventory.
+
+ The inventory can be overridden and returns the corresponding environment variables.
+ """
env = default_anta_env()
anta_inventory = str(env["ANTA_INVENTORY"])
temp_inventory = tmp_path / "test_inventory.yml"
@@ -179,16 +169,19 @@ def temp_env(tmp_path: Path) -> dict[str, str | None]:
return env
-@pytest.fixture
-def click_runner(capsys: CaptureFixture[str]) -> Iterator[CliRunner]:
- """
- Convenience fixture to return a click.CliRunner for cli testing
- """
+@pytest.fixture()
+# Disabling C901 - too complex as we like our runner like this
+def click_runner(capsys: pytest.CaptureFixture[str]) -> Iterator[CliRunner]: # noqa: C901
+ """Return a click.CliRunner for cli testing."""
class AntaCliRunner(CliRunner):
- """Override CliRunner to inject specific variables for ANTA"""
+ """Override CliRunner to inject specific variables for ANTA."""
- def invoke(self, *args, **kwargs) -> Result: # type: ignore[no-untyped-def]
+ def invoke(
+ self,
+ *args: Any, # noqa: ANN401
+ **kwargs: Any, # noqa: ANN401
+ ) -> Result:
# Inject default env if not provided
kwargs["env"] = kwargs["env"] if "env" in kwargs else default_anta_env()
# Deterministic terminal width
@@ -198,14 +191,18 @@ def click_runner(capsys: CaptureFixture[str]) -> Iterator[CliRunner]:
# Way to fix https://github.com/pallets/click/issues/824
with capsys.disabled():
result = super().invoke(*args, **kwargs)
- print("--- CLI Output ---")
- print(result.output)
+ # disabling T201 as we want to print here
+ print("--- CLI Output ---") # noqa: T201
+ print(result.output) # noqa: T201
return result
def cli(
- command: str | None = None, commands: list[dict[str, Any]] | None = None, ofmt: str = "json", version: int | str | None = "latest", **kwargs: Any
+ command: str | None = None,
+ commands: list[dict[str, Any]] | None = None,
+ ofmt: str = "json",
+ _version: int | str | None = "latest",
+ **_kwargs: Any, # noqa: ANN401
) -> dict[str, Any] | list[dict[str, Any]]:
- # pylint: disable=unused-argument
def get_output(command: str | dict[str, Any]) -> dict[str, Any]:
if isinstance(command, dict):
command = command["cmd"]
@@ -216,8 +213,8 @@ def click_runner(capsys: CaptureFixture[str]) -> Iterator[CliRunner]:
mock_cli = MOCK_CLI_TEXT
for mock_cmd, output in mock_cli.items():
if command == mock_cmd:
- logger.info(f"Mocking command {mock_cmd}")
- if isinstance(output, aioeapi.EapiCommandError):
+ logger.info("Mocking command %s", mock_cmd)
+ if isinstance(output, asynceapi.EapiCommandError):
raise output
return output
message = f"Command '{command}' is not mocked"
@@ -226,17 +223,22 @@ def click_runner(capsys: CaptureFixture[str]) -> Iterator[CliRunner]:
res: dict[str, Any] | list[dict[str, Any]]
if command is not None:
- logger.debug(f"Mock input {command}")
+ logger.debug("Mock input %s", command)
res = get_output(command)
if commands is not None:
- logger.debug(f"Mock input {commands}")
+ logger.debug("Mock input %s", commands)
res = list(map(get_output, commands))
- logger.debug(f"Mock output {res}")
+ logger.debug("Mock output %s", res)
return res
- # Patch aioeapi methods used by AsyncEOSDevice. See tests/units/test_device.py
- with patch("aioeapi.device.Device.check_connection", return_value=True), patch("aioeapi.device.Device.cli", side_effect=cli), patch("asyncssh.connect"), patch(
- "asyncssh.scp"
+ # Patch asynceapi methods used by AsyncEOSDevice. See tests/units/test_device.py
+ with (
+ patch("asynceapi.device.Device.check_connection", return_value=True),
+ patch("asynceapi.device.Device.cli", side_effect=cli),
+ patch("asyncssh.connect"),
+ patch(
+ "asyncssh.scp",
+ ),
):
console._color_system = None # pylint: disable=protected-access
yield AntaCliRunner()
diff --git a/tests/lib/utils.py b/tests/lib/utils.py
index 460e014..ba669c2 100644
--- a/tests/lib/utils.py
+++ b/tests/lib/utils.py
@@ -1,9 +1,8 @@
# Copyright (c) 2023-2024 Arista Networks, Inc.
# Use of this source code is governed by the Apache License 2.0
# that can be found in the LICENSE file.
-"""
-tests.lib.utils
-"""
+"""tests.lib.utils."""
+
from __future__ import annotations
from pathlib import Path
@@ -11,22 +10,17 @@ from typing import Any
def generate_test_ids_dict(val: dict[str, Any], key: str = "name") -> str:
- """
- generate_test_ids Helper to generate test ID for parametrize
- """
+ """generate_test_ids Helper to generate test ID for parametrize."""
return val.get(key, "unamed_test")
def generate_test_ids_list(val: list[dict[str, Any]], key: str = "name") -> list[str]:
- """
- generate_test_ids Helper to generate test ID for parametrize
- """
- return [entry[key] if key in entry.keys() else "unamed_test" for entry in val]
+ """generate_test_ids Helper to generate test ID for parametrize."""
+ return [entry.get(key, "unamed_test") for entry in val]
def generate_test_ids(data: list[dict[str, Any]]) -> list[str]:
- """
- build id for a unit test of an AntaTest subclass
+ """Build id for a unit test of an AntaTest subclass.
{
"name": "meaniful test name",
@@ -34,13 +28,11 @@ def generate_test_ids(data: list[dict[str, Any]]) -> list[str]:
...
}
"""
- return [f"{val['test'].__module__}.{val['test'].__name__}-{val['name']}" for val in data]
+ return [f"{val['test'].module}.{val['test'].__name__}-{val['name']}" for val in data]
def default_anta_env() -> dict[str, str | None]:
- """
- Return a default_anta_environement which can be passed to a cliRunner.invoke method
- """
+ """Return a default_anta_environement which can be passed to a cliRunner.invoke method."""
return {
"ANTA_USERNAME": "anta",
"ANTA_PASSWORD": "formica",
diff --git a/tests/units/__init__.py b/tests/units/__init__.py
index e772bee..6f96a0d 100644
--- a/tests/units/__init__.py
+++ b/tests/units/__init__.py
@@ -1,3 +1,4 @@
# Copyright (c) 2023-2024 Arista Networks, Inc.
# Use of this source code is governed by the Apache License 2.0
# that can be found in the LICENSE file.
+"""Unit tests for anta."""
diff --git a/tests/units/anta_tests/__init__.py b/tests/units/anta_tests/__init__.py
index e772bee..8ca0e8c 100644
--- a/tests/units/anta_tests/__init__.py
+++ b/tests/units/anta_tests/__init__.py
@@ -1,3 +1,4 @@
# Copyright (c) 2023-2024 Arista Networks, Inc.
# Use of this source code is governed by the Apache License 2.0
# that can be found in the LICENSE file.
+"""Test for anta.tests submodule."""
diff --git a/tests/units/anta_tests/routing/__init__.py b/tests/units/anta_tests/routing/__init__.py
index e772bee..aef1274 100644
--- a/tests/units/anta_tests/routing/__init__.py
+++ b/tests/units/anta_tests/routing/__init__.py
@@ -1,3 +1,4 @@
# Copyright (c) 2023-2024 Arista Networks, Inc.
# Use of this source code is governed by the Apache License 2.0
# that can be found in the LICENSE file.
+"""Test for anta.tests.routing submodule."""
diff --git a/tests/units/anta_tests/routing/test_bgp.py b/tests/units/anta_tests/routing/test_bgp.py
index 799f058..e712e12 100644
--- a/tests/units/anta_tests/routing/test_bgp.py
+++ b/tests/units/anta_tests/routing/test_bgp.py
@@ -1,9 +1,8 @@
# Copyright (c) 2023-2024 Arista Networks, Inc.
# Use of this source code is governed by the Apache License 2.0
# that can be found in the LICENSE file.
-"""
-Tests for anta.tests.routing.bgp.py
-"""
+"""Tests for anta.tests.routing.bgp.py."""
+
# pylint: disable=C0302
from __future__ import annotations
@@ -11,7 +10,7 @@ from typing import Any
# pylint: disable=C0413
# because of the patch above
-from anta.tests.routing.bgp import ( # noqa: E402
+from anta.tests.routing.bgp import (
VerifyBGPAdvCommunities,
VerifyBGPExchangedRoutes,
VerifyBGPPeerASNCap,
@@ -31,47 +30,105 @@ DATA: list[dict[str, Any]] = [
"name": "success",
"test": VerifyBGPPeerCount,
"eos_data": [
+ # Need to order the output as the commands would be sorted after template rendering.
{
"vrfs": {
"default": {
- "vrf": "default",
- "routerId": "10.1.0.3",
- "asn": "65120",
"peers": {
"10.1.255.0": {
- "description": "DC1-SPINE1_Ethernet1",
- "version": 4,
- "msgReceived": 0,
- "msgSent": 0,
"inMsgQueue": 0,
"outMsgQueue": 0,
- "asn": "65100",
- "prefixAccepted": 0,
- "prefixReceived": 0,
- "upDownTime": 1694266295.098931,
- "underMaintenance": False,
"peerState": "Established",
},
"10.1.255.2": {
+ "inMsgQueue": 0,
+ "outMsgQueue": 0,
+ "peerState": "Established",
+ },
+ },
+ },
+ },
+ },
+ {
+ "vrfs": {
+ "MGMT": {
+ "peers": {
+ "10.255.0.21": {
+ "inMsgQueue": 0,
+ "outMsgQueue": 0,
+ "peerState": "Established",
+ },
+ },
+ },
+ },
+ },
+ {
+ "vrfs": {
+ "default": {
+ "peers": {
+ "10.255.0.1": {
+ "inMsgQueue": 0,
+ "outMsgQueue": 0,
+ "peerState": "Established",
+ },
+ "10.255.0.2": {
"description": "DC1-SPINE2_Ethernet1",
- "version": 4,
- "msgReceived": 3759,
- "msgSent": 3757,
"inMsgQueue": 0,
"outMsgQueue": 0,
- "asn": "65100",
- "prefixAccepted": 14,
- "prefixReceived": 14,
- "upDownTime": 1694266296.367261,
- "underMaintenance": False,
"peerState": "Established",
},
},
- }
- }
- }
+ },
+ },
+ },
+ {
+ "vrfs": {
+ "default": {
+ "peers": {
+ "10.255.0.11": {
+ "inMsgQueue": 0,
+ "outMsgQueue": 0,
+ "peerState": "Established",
+ },
+ "10.255.0.12": {
+ "description": "DC1-SPINE2_Ethernet1",
+ "inMsgQueue": 0,
+ "outMsgQueue": 0,
+ "peerState": "Established",
+ },
+ },
+ },
+ },
+ },
+ {
+ "vrfs": {
+ "default": {
+ "peers": {
+ "10.255.0.21": {
+ "inMsgQueue": 0,
+ "outMsgQueue": 0,
+ "peerState": "Established",
+ },
+ "10.255.0.22": {
+ "inMsgQueue": 0,
+ "outMsgQueue": 0,
+ "peerState": "Established",
+ },
+ },
+ },
+ },
+ },
],
- "inputs": {"address_families": [{"afi": "ipv4", "safi": "unicast", "vrf": "default", "num_peers": 2}]},
+ "inputs": {
+ "address_families": [
+ # evpn first to make sure that the correct mapping output to input is kept.
+ {"afi": "evpn", "num_peers": 2},
+ {"afi": "ipv4", "safi": "unicast", "vrf": "default", "num_peers": 2},
+ {"afi": "ipv4", "safi": "sr-te", "vrf": "MGMT", "num_peers": 1},
+ {"afi": "link-state", "num_peers": 2},
+ {"afi": "path-selection", "num_peers": 2},
+ ]
+ },
"expected": {"result": "success"},
},
{
@@ -81,59 +138,189 @@ DATA: list[dict[str, Any]] = [
{
"vrfs": {
"default": {
- "vrf": "default",
- "routerId": "10.1.0.3",
- "asn": "65120",
"peers": {
"10.1.255.0": {
- "description": "DC1-SPINE1_Ethernet1",
- "version": 4,
- "msgReceived": 0,
- "msgSent": 0,
"inMsgQueue": 0,
"outMsgQueue": 0,
- "asn": "65100",
- "prefixAccepted": 0,
- "prefixReceived": 0,
- "upDownTime": 1694266295.098931,
- "underMaintenance": False,
"peerState": "Established",
},
"10.1.255.2": {
+ "inMsgQueue": 0,
+ "outMsgQueue": 0,
+ "peerState": "Established",
+ },
+ },
+ },
+ },
+ },
+ {
+ "vrfs": {
+ "MGMT": {
+ "peers": {
+ "10.255.0.21": {
+ "inMsgQueue": 0,
+ "outMsgQueue": 0,
+ "peerState": "Established",
+ },
+ },
+ },
+ },
+ },
+ {
+ "vrfs": {
+ "default": {
+ "peers": {
+ "10.255.0.1": {
+ "inMsgQueue": 0,
+ "outMsgQueue": 0,
+ "peerState": "Established",
+ },
+ "10.255.0.2": {
"description": "DC1-SPINE2_Ethernet1",
- "version": 4,
- "msgReceived": 3759,
- "msgSent": 3757,
"inMsgQueue": 0,
"outMsgQueue": 0,
- "asn": "65100",
- "prefixAccepted": 14,
- "prefixReceived": 14,
- "upDownTime": 1694266296.367261,
- "underMaintenance": False,
"peerState": "Established",
},
},
- }
- }
- }
+ },
+ },
+ },
+ {
+ "vrfs": {
+ "default": {
+ "peers": {
+ "10.255.0.11": {
+ "inMsgQueue": 0,
+ "outMsgQueue": 0,
+ "peerState": "Established",
+ },
+ "10.255.0.12": {
+ "description": "DC1-SPINE2_Ethernet1",
+ "inMsgQueue": 0,
+ "outMsgQueue": 0,
+ "peerState": "Established",
+ },
+ },
+ },
+ },
+ },
+ {
+ "vrfs": {
+ "default": {
+ "peers": {
+ "10.255.0.21": {
+ "inMsgQueue": 0,
+ "outMsgQueue": 0,
+ "peerState": "Established",
+ },
+ },
+ },
+ },
+ },
],
- "inputs": {"address_families": [{"afi": "ipv4", "safi": "unicast", "vrf": "default", "num_peers": 3}]},
- "expected": {"result": "failure", "messages": ["Failures: [{'afi': 'ipv4', 'safi': 'unicast', 'vrfs': {'default': 'Expected: 3, Actual: 2'}}]"]},
+ "inputs": {
+ "address_families": [
+ {"afi": "ipv4", "safi": "unicast", "vrf": "default", "num_peers": 3},
+ {"afi": "ipv4", "safi": "sr-te", "vrf": "MGMT", "num_peers": 2},
+ {"afi": "evpn", "num_peers": 1},
+ {"afi": "link-state", "num_peers": 3},
+ {"afi": "path-selection", "num_peers": 3},
+ ]
+ },
+ "expected": {
+ "result": "failure",
+ "messages": [
+ "Failures: [{'afi': 'ipv4', 'safi': 'unicast', 'vrfs': {'default': 'Expected: 3, Actual: 2'}}, "
+ "{'afi': 'ipv4', 'safi': 'sr-te', 'vrfs': {'MGMT': 'Expected: 2, Actual: 1'}}, "
+ "{'afi': 'evpn', 'vrfs': {'default': 'Expected: 1, Actual: 2'}}, "
+ "{'afi': 'link-state', 'vrfs': {'default': 'Expected: 3, Actual: 2'}}, "
+ "{'afi': 'path-selection', 'vrfs': {'default': 'Expected: 3, Actual: 1'}}]"
+ ],
+ },
},
{
"name": "failure-no-peers",
"test": VerifyBGPPeerCount,
- "eos_data": [{"vrfs": {"default": {"vrf": "default", "routerId": "10.1.0.3", "asn": "65120", "peers": {}}}}],
- "inputs": {"address_families": [{"afi": "ipv6", "safi": "unicast", "vrf": "default", "num_peers": 3}]},
- "expected": {"result": "failure", "messages": ["Failures: [{'afi': 'ipv6', 'safi': 'unicast', 'vrfs': {'default': 'Expected: 3, Actual: 0'}}]"]},
+ "eos_data": [
+ {
+ "vrfs": {
+ "default": {
+ "peers": {},
+ }
+ }
+ },
+ {
+ "vrfs": {
+ "MGMT": {
+ "peers": {},
+ }
+ }
+ },
+ {
+ "vrfs": {
+ "default": {
+ "peers": {},
+ }
+ }
+ },
+ {
+ "vrfs": {
+ "default": {
+ "peers": {},
+ }
+ }
+ },
+ {
+ "vrfs": {
+ "default": {
+ "peers": {},
+ }
+ }
+ },
+ ],
+ "inputs": {
+ "address_families": [
+ {"afi": "ipv4", "safi": "unicast", "vrf": "default", "num_peers": 2},
+ {"afi": "ipv4", "safi": "sr-te", "vrf": "MGMT", "num_peers": 1},
+ {"afi": "evpn", "num_peers": 2},
+ {"afi": "link-state", "num_peers": 2},
+ {"afi": "path-selection", "num_peers": 2},
+ ]
+ },
+ "expected": {
+ "result": "failure",
+ "messages": [
+ "Failures: [{'afi': 'ipv4', 'safi': 'unicast', 'vrfs': {'default': 'Expected: 2, Actual: 0'}}, "
+ "{'afi': 'ipv4', 'safi': 'sr-te', 'vrfs': {'MGMT': 'Expected: 1, Actual: 0'}}, "
+ "{'afi': 'evpn', 'vrfs': {'default': 'Expected: 2, Actual: 0'}}, "
+ "{'afi': 'link-state', 'vrfs': {'default': 'Expected: 2, Actual: 0'}}, "
+ "{'afi': 'path-selection', 'vrfs': {'default': 'Expected: 2, Actual: 0'}}]"
+ ],
+ },
},
{
"name": "failure-not-configured",
"test": VerifyBGPPeerCount,
- "eos_data": [{"vrfs": {}}],
- "inputs": {"address_families": [{"afi": "ipv6", "safi": "multicast", "vrf": "DEV", "num_peers": 3}]},
- "expected": {"result": "failure", "messages": ["Failures: [{'afi': 'ipv6', 'safi': 'multicast', 'vrfs': {'DEV': 'Not Configured'}}]"]},
+ "eos_data": [{"vrfs": {}}, {"vrfs": {}}, {"vrfs": {}}, {"vrfs": {}}, {"vrfs": {}}],
+ "inputs": {
+ "address_families": [
+ {"afi": "ipv6", "safi": "multicast", "vrf": "DEV", "num_peers": 3},
+ {"afi": "ipv4", "safi": "sr-te", "vrf": "MGMT", "num_peers": 1},
+ {"afi": "evpn", "num_peers": 2},
+ {"afi": "link-state", "num_peers": 2},
+ {"afi": "path-selection", "num_peers": 2},
+ ]
+ },
+ "expected": {
+ "result": "failure",
+ "messages": [
+ "Failures: [{'afi': 'ipv6', 'safi': 'multicast', 'vrfs': {'DEV': 'Not Configured'}}, "
+ "{'afi': 'ipv4', 'safi': 'sr-te', 'vrfs': {'MGMT': 'Not Configured'}}, "
+ "{'afi': 'evpn', 'vrfs': {'default': 'Not Configured'}}, "
+ "{'afi': 'link-state', 'vrfs': {'default': 'Not Configured'}}, "
+ "{'afi': 'path-selection', 'vrfs': {'default': 'Not Configured'}}]"
+ ],
+ },
},
{
"name": "success-vrf-all",
@@ -142,226 +329,132 @@ DATA: list[dict[str, Any]] = [
{
"vrfs": {
"default": {
- "vrf": "default",
- "routerId": "10.1.0.3",
- "asn": "65120",
"peers": {
"10.1.255.0": {
- "description": "DC1-SPINE1_Ethernet1",
- "version": 4,
- "msgReceived": 0,
- "msgSent": 0,
"inMsgQueue": 0,
"outMsgQueue": 0,
- "asn": "65100",
- "prefixAccepted": 0,
- "prefixReceived": 0,
- "upDownTime": 1694266295.098931,
- "underMaintenance": False,
"peerState": "Established",
},
},
},
"PROD": {
- "vrf": "PROD",
- "routerId": "10.1.0.3",
- "asn": "65120",
"peers": {
"10.1.254.1": {
- "description": "DC1-LEAF1B",
- "version": 4,
- "msgReceived": 3777,
- "msgSent": 3764,
"inMsgQueue": 0,
"outMsgQueue": 0,
- "asn": "65120",
- "prefixAccepted": 2,
- "prefixReceived": 2,
- "upDownTime": 1694266296.659891,
- "underMaintenance": False,
"peerState": "Established",
},
"192.168.1.11": {
- "description": "K8S-CLUSTER1",
- "version": 4,
- "msgReceived": 6417,
- "msgSent": 7546,
"inMsgQueue": 0,
"outMsgQueue": 0,
- "asn": "65000",
- "prefixAccepted": 1,
- "prefixReceived": 1,
- "upDownTime": 1694266329.978035,
- "underMaintenance": False,
"peerState": "Established",
},
},
},
- }
- }
- ],
- "inputs": {"address_families": [{"afi": "ipv4", "safi": "unicast", "vrf": "all", "num_peers": 3}]},
- "expected": {"result": "success"},
- },
- {
- "name": "failure-vrf-all",
- "test": VerifyBGPPeerCount,
- "eos_data": [
+ },
+ },
{
"vrfs": {
"default": {
- "vrf": "default",
- "routerId": "10.1.0.3",
- "asn": "65120",
"peers": {
- "10.1.255.0": {
- "description": "DC1-SPINE1_Ethernet1",
- "version": 4,
- "msgReceived": 0,
- "msgSent": 0,
+ "10.1.255.10": {
"inMsgQueue": 0,
"outMsgQueue": 0,
- "asn": "65100",
- "prefixAccepted": 0,
- "prefixReceived": 0,
- "upDownTime": 1694266295.098931,
- "underMaintenance": False,
"peerState": "Established",
},
},
},
"PROD": {
- "vrf": "PROD",
- "routerId": "10.1.0.3",
- "asn": "65120",
"peers": {
- "10.1.254.1": {
- "description": "DC1-LEAF1B",
- "version": 4,
- "msgReceived": 3777,
- "msgSent": 3764,
- "inMsgQueue": 0,
- "outMsgQueue": 0,
- "asn": "65120",
- "prefixAccepted": 2,
- "prefixReceived": 2,
- "upDownTime": 1694266296.659891,
- "underMaintenance": False,
- "peerState": "Established",
- },
- "192.168.1.11": {
- "description": "K8S-CLUSTER1",
- "version": 4,
- "msgReceived": 6417,
- "msgSent": 7546,
+ "10.1.254.11": {
"inMsgQueue": 0,
"outMsgQueue": 0,
- "asn": "65000",
- "prefixAccepted": 1,
- "prefixReceived": 1,
- "upDownTime": 1694266329.978035,
- "underMaintenance": False,
"peerState": "Established",
},
},
},
- }
- }
+ },
+ },
],
- "inputs": {"address_families": [{"afi": "ipv4", "safi": "unicast", "vrf": "all", "num_peers": 5}]},
- "expected": {"result": "failure", "messages": ["Failures: [{'afi': 'ipv4', 'safi': 'unicast', 'vrfs': {'all': 'Expected: 5, Actual: 3'}}]"]},
+ "inputs": {
+ "address_families": [
+ {"afi": "ipv4", "safi": "unicast", "vrf": "all", "num_peers": 3},
+ {"afi": "ipv4", "safi": "sr-te", "vrf": "all", "num_peers": 2},
+ ]
+ },
+ "expected": {"result": "success"},
},
{
- "name": "success-multiple-afi",
+ "name": "failure-vrf-all",
"test": VerifyBGPPeerCount,
"eos_data": [
{
"vrfs": {
+ "default": {
+ "peers": {
+ "10.1.255.0": {
+ "inMsgQueue": 0,
+ "outMsgQueue": 0,
+ "peerState": "Established",
+ },
+ },
+ },
"PROD": {
- "vrf": "PROD",
- "routerId": "10.1.0.3",
- "asn": "65120",
"peers": {
"10.1.254.1": {
- "description": "DC1-LEAF1B",
- "version": 4,
- "msgReceived": 3777,
- "msgSent": 3764,
"inMsgQueue": 0,
"outMsgQueue": 0,
- "asn": "65120",
- "prefixAccepted": 2,
- "prefixReceived": 2,
- "upDownTime": 1694266296.659891,
- "underMaintenance": False,
"peerState": "Established",
},
"192.168.1.11": {
- "description": "K8S-CLUSTER1",
- "version": 4,
- "msgReceived": 6417,
- "msgSent": 7546,
"inMsgQueue": 0,
"outMsgQueue": 0,
- "asn": "65000",
- "prefixAccepted": 1,
- "prefixReceived": 1,
- "upDownTime": 1694266329.978035,
- "underMaintenance": False,
"peerState": "Established",
},
},
- }
- }
+ },
+ },
},
{
"vrfs": {
"default": {
- "vrf": "default",
- "routerId": "10.1.0.3",
- "asn": "65120",
"peers": {
- "10.1.0.1": {
- "description": "DC1-SPINE1",
- "version": 4,
- "msgReceived": 3894,
- "msgSent": 3897,
+ "10.1.255.10": {
"inMsgQueue": 0,
"outMsgQueue": 0,
- "asn": "65100",
- "prefixAccepted": 0,
- "prefixReceived": 0,
- "upDownTime": 1694266296.584472,
- "underMaintenance": False,
"peerState": "Established",
},
- "10.1.0.2": {
- "description": "DC1-SPINE2",
- "version": 4,
- "msgReceived": 3893,
- "msgSent": 3902,
+ },
+ },
+ "PROD": {
+ "peers": {
+ "10.1.254.1": {
+ "inMsgQueue": 0,
+ "outMsgQueue": 0,
+ "peerState": "Established",
+ },
+ "192.168.1.12": {
"inMsgQueue": 0,
"outMsgQueue": 0,
- "asn": "65100",
- "prefixAccepted": 0,
- "prefixReceived": 0,
- "upDownTime": 1694266297.433896,
- "underMaintenance": False,
"peerState": "Established",
},
},
- }
- }
+ },
+ },
},
],
"inputs": {
"address_families": [
- {"afi": "ipv4", "safi": "unicast", "vrf": "PROD", "num_peers": 2},
- {"afi": "evpn", "num_peers": 2},
+ {"afi": "ipv4", "safi": "unicast", "vrf": "all", "num_peers": 5},
+ {"afi": "ipv4", "safi": "sr-te", "vrf": "all", "num_peers": 2},
]
},
"expected": {
- "result": "success",
+ "result": "failure",
+ "messages": [
+ "Failures: [{'afi': 'ipv4', 'safi': 'unicast', 'vrfs': {'all': 'Expected: 5, Actual: 3'}}, "
+ "{'afi': 'ipv4', 'safi': 'sr-te', 'vrfs': {'all': 'Expected: 2, Actual: 3'}}]"
+ ],
},
},
{
@@ -371,96 +464,114 @@ DATA: list[dict[str, Any]] = [
{
"vrfs": {
"PROD": {
- "vrf": "PROD",
- "routerId": "10.1.0.3",
- "asn": "65120",
"peers": {
"10.1.254.1": {
- "description": "DC1-LEAF1B",
- "version": 4,
- "msgReceived": 3777,
- "msgSent": 3764,
"inMsgQueue": 0,
"outMsgQueue": 0,
- "asn": "65120",
- "prefixAccepted": 2,
- "prefixReceived": 2,
- "upDownTime": 1694266296.659891,
- "underMaintenance": False,
"peerState": "Established",
},
"192.168.1.11": {
- "description": "K8S-CLUSTER1",
- "version": 4,
- "msgReceived": 6417,
- "msgSent": 7546,
"inMsgQueue": 0,
"outMsgQueue": 0,
- "asn": "65000",
- "prefixAccepted": 1,
- "prefixReceived": 1,
- "upDownTime": 1694266329.978035,
- "underMaintenance": False,
"peerState": "Established",
},
},
- }
- }
+ },
+ },
},
{"vrfs": {}},
{
"vrfs": {
+ "MGMT": {
+ "peers": {
+ "10.1.254.11": {
+ "inMsgQueue": 0,
+ "outMsgQueue": 0,
+ "peerState": "Established",
+ },
+ "192.168.1.21": {
+ "inMsgQueue": 0,
+ "outMsgQueue": 0,
+ "peerState": "Established",
+ },
+ },
+ },
+ },
+ },
+ {
+ "vrfs": {
"default": {
- "vrf": "default",
- "routerId": "10.1.0.3",
- "asn": "65120",
"peers": {
"10.1.0.1": {
- "description": "DC1-SPINE1",
- "version": 4,
- "msgReceived": 3894,
- "msgSent": 3897,
"inMsgQueue": 0,
"outMsgQueue": 0,
- "asn": "65100",
- "prefixAccepted": 0,
- "prefixReceived": 0,
- "upDownTime": 1694266296.584472,
- "underMaintenance": False,
"peerState": "Established",
},
"10.1.0.2": {
- "description": "DC1-SPINE2",
- "version": 4,
- "msgReceived": 3893,
- "msgSent": 3902,
"inMsgQueue": 0,
"outMsgQueue": 0,
- "asn": "65100",
- "prefixAccepted": 0,
- "prefixReceived": 0,
- "upDownTime": 1694266297.433896,
- "underMaintenance": False,
"peerState": "Established",
},
},
- }
- }
+ },
+ },
+ },
+ {
+ "vrfs": {
+ "default": {
+ "peers": {
+ "10.1.0.11": {
+ "inMsgQueue": 0,
+ "outMsgQueue": 0,
+ "peerState": "Established",
+ },
+ "10.1.0.21": {
+ "inMsgQueue": 0,
+ "outMsgQueue": 0,
+ "peerState": "Established",
+ },
+ },
+ },
+ },
+ },
+ {
+ "vrfs": {
+ "default": {
+ "peers": {
+ "10.1.0.2": {
+ "inMsgQueue": 0,
+ "outMsgQueue": 0,
+ "peerState": "Established",
+ },
+ "10.1.0.22": {
+ "inMsgQueue": 0,
+ "outMsgQueue": 0,
+ "peerState": "Established",
+ },
+ },
+ },
+ },
},
],
"inputs": {
"address_families": [
{"afi": "ipv4", "safi": "unicast", "vrf": "PROD", "num_peers": 3},
- {"afi": "evpn", "num_peers": 3},
{"afi": "ipv6", "safi": "unicast", "vrf": "default", "num_peers": 3},
- ]
+ {"afi": "ipv4", "safi": "sr-te", "vrf": "MGMT", "num_peers": 3},
+ {"afi": "evpn", "num_peers": 3},
+ {"afi": "link-state", "num_peers": 4},
+ {"afi": "path-selection", "num_peers": 1},
+ ],
},
"expected": {
"result": "failure",
"messages": [
"Failures: [{'afi': 'ipv4', 'safi': 'unicast', 'vrfs': {'PROD': 'Expected: 3, Actual: 2'}}, "
"{'afi': 'ipv6', 'safi': 'unicast', 'vrfs': {'default': 'Not Configured'}}, "
- "{'afi': 'evpn', 'vrfs': {'default': 'Expected: 3, Actual: 2'}}"
+ "{'afi': 'ipv4', 'safi': 'sr-te', 'vrfs': {'MGMT': 'Expected: 3, Actual: 2'}}, "
+ "{'afi': 'evpn', 'vrfs': {'default': 'Expected: 3, Actual: 2'}}, "
+ "{'afi': 'link-state', 'vrfs': {'default': 'Expected: 4, Actual: 2'}}, "
+ "{'afi': 'path-selection', 'vrfs': {'default': 'Expected: 1, Actual: 2'}}]",
],
},
},
@@ -471,44 +582,85 @@ DATA: list[dict[str, Any]] = [
{
"vrfs": {
"default": {
- "vrf": "default",
- "routerId": "10.1.0.3",
- "asn": "65120",
"peers": {
"10.1.255.0": {
- "description": "DC1-SPINE1_Ethernet1",
- "version": 4,
- "msgReceived": 0,
- "msgSent": 0,
"inMsgQueue": 0,
"outMsgQueue": 0,
- "asn": "65100",
- "prefixAccepted": 0,
- "prefixReceived": 0,
- "upDownTime": 1694266295.098931,
- "underMaintenance": False,
"peerState": "Established",
},
"10.1.255.2": {
- "description": "DC1-SPINE2_Ethernet1",
- "version": 4,
- "msgReceived": 3759,
- "msgSent": 3757,
"inMsgQueue": 0,
"outMsgQueue": 0,
- "asn": "65100",
- "prefixAccepted": 14,
- "prefixReceived": 14,
- "upDownTime": 1694266296.367261,
- "underMaintenance": False,
"peerState": "Established",
},
},
}
}
- }
+ },
+ {
+ "vrfs": {
+ "MGMT": {
+ "peers": {
+ "10.1.255.10": {
+ "inMsgQueue": 0,
+ "outMsgQueue": 0,
+ "peerState": "Established",
+ },
+ "10.1.255.12": {
+ "inMsgQueue": 0,
+ "outMsgQueue": 0,
+ "peerState": "Established",
+ },
+ },
+ }
+ }
+ },
+ {
+ "vrfs": {
+ "default": {
+ "peers": {
+ "10.1.255.20": {
+ "inMsgQueue": 0,
+ "outMsgQueue": 0,
+ "peerState": "Established",
+ },
+ "10.1.255.22": {
+ "inMsgQueue": 0,
+ "outMsgQueue": 0,
+ "peerState": "Established",
+ },
+ },
+ }
+ }
+ },
+ {
+ "vrfs": {
+ "default": {
+ "peers": {
+ "10.1.255.30": {
+ "inMsgQueue": 0,
+ "outMsgQueue": 0,
+ "peerState": "Established",
+ },
+ "10.1.255.32": {
+ "inMsgQueue": 0,
+ "outMsgQueue": 0,
+ "peerState": "Established",
+ },
+ },
+ }
+ }
+ },
],
- "inputs": {"address_families": [{"afi": "ipv4", "safi": "unicast", "vrf": "default"}]},
+ "inputs": {
+ "address_families": [
+ # Path selection first to make sure input to output mapping is correct.
+ {"afi": "path-selection"},
+ {"afi": "ipv4", "safi": "unicast", "vrf": "default"},
+ {"afi": "ipv4", "safi": "sr-te", "vrf": "MGMT"},
+ {"afi": "link-state"},
+ ]
+ },
"expected": {"result": "success"},
},
{
@@ -518,48 +670,91 @@ DATA: list[dict[str, Any]] = [
{
"vrfs": {
"default": {
- "vrf": "default",
- "routerId": "10.1.0.3",
- "asn": "65120",
"peers": {
"10.1.255.0": {
- "description": "DC1-SPINE1_Ethernet1",
- "version": 4,
- "msgReceived": 0,
- "msgSent": 0,
"inMsgQueue": 0,
"outMsgQueue": 0,
- "asn": "65100",
- "prefixAccepted": 0,
- "prefixReceived": 0,
- "upDownTime": 1694266295.098931,
- "underMaintenance": False,
"peerState": "Idle",
},
"10.1.255.2": {
- "description": "DC1-SPINE2_Ethernet1",
- "version": 4,
- "msgReceived": 3759,
- "msgSent": 3757,
"inMsgQueue": 0,
"outMsgQueue": 0,
- "asn": "65100",
- "prefixAccepted": 14,
- "prefixReceived": 14,
- "upDownTime": 1694266296.367261,
- "underMaintenance": False,
"peerState": "Established",
},
},
}
}
- }
+ },
+ {
+ "vrfs": {
+ "MGMT": {
+ "peers": {
+ "10.1.255.10": {
+ "inMsgQueue": 0,
+ "outMsgQueue": 0,
+ "peerState": "Established",
+ },
+ "10.1.255.12": {
+ "inMsgQueue": 0,
+ "outMsgQueue": 0,
+ "peerState": "Idle",
+ },
+ },
+ }
+ }
+ },
+ {
+ "vrfs": {
+ "default": {
+ "peers": {
+ "10.1.255.20": {
+ "inMsgQueue": 0,
+ "outMsgQueue": 0,
+ "peerState": "Idle",
+ },
+ "10.1.255.22": {
+ "inMsgQueue": 0,
+ "outMsgQueue": 0,
+ "peerState": "Established",
+ },
+ },
+ }
+ }
+ },
+ {
+ "vrfs": {
+ "default": {
+ "peers": {
+ "10.1.255.30": {
+ "inMsgQueue": 0,
+ "outMsgQueue": 0,
+ "peerState": "Established",
+ },
+ "10.1.255.32": {
+ "inMsgQueue": 0,
+ "outMsgQueue": 0,
+ "peerState": "Idle",
+ },
+ },
+ }
+ }
+ },
],
- "inputs": {"address_families": [{"afi": "ipv4", "safi": "unicast", "vrf": "default"}]},
+ "inputs": {
+ "address_families": [
+ {"afi": "ipv4", "safi": "unicast", "vrf": "default"},
+ {"afi": "ipv4", "safi": "sr-te", "vrf": "MGMT"},
+ {"afi": "path-selection"},
+ {"afi": "link-state"},
+ ]
+ },
"expected": {
"result": "failure",
"messages": [
- "Failures: [{'afi': 'ipv4', 'safi': 'unicast', 'vrfs': {'default': {'10.1.255.0': {'peerState': 'Idle', 'inMsgQueue': 0, 'outMsgQueue': 0}}}}]"
+ "Failures: [{'afi': 'ipv4', 'safi': 'unicast', 'vrfs': {'default': {'10.1.255.0': {'peerState': 'Idle', 'inMsgQueue': 0, 'outMsgQueue': 0}}}}, "
+ "{'afi': 'ipv4', 'safi': 'sr-te', 'vrfs': {'MGMT': {'10.1.255.12': {'peerState': 'Idle', 'inMsgQueue': 0, 'outMsgQueue': 0}}}}, "
+ "{'afi': 'path-selection', 'vrfs': {'default': {'10.1.255.20': {'peerState': 'Idle', 'inMsgQueue': 0, 'outMsgQueue': 0}}}}, "
+ "{'afi': 'link-state', 'vrfs': {'default': {'10.1.255.32': {'peerState': 'Idle', 'inMsgQueue': 0, 'outMsgQueue': 0}}}}]"
],
},
},
@@ -570,79 +765,74 @@ DATA: list[dict[str, Any]] = [
{
"vrfs": {
"default": {
- "vrf": "default",
- "routerId": "10.1.0.3",
- "asn": "65120",
"peers": {
"10.1.255.0": {
- "description": "DC1-SPINE1_Ethernet1",
- "version": 4,
- "msgReceived": 0,
- "msgSent": 0,
"inMsgQueue": 0,
"outMsgQueue": 0,
- "asn": "65100",
- "prefixAccepted": 0,
- "prefixReceived": 0,
- "upDownTime": 1694266295.098931,
- "underMaintenance": False,
"peerState": "Established",
},
"10.1.255.2": {
- "description": "DC1-SPINE2_Ethernet1",
- "version": 4,
- "msgReceived": 3759,
- "msgSent": 3757,
"inMsgQueue": 0,
"outMsgQueue": 0,
- "asn": "65100",
- "prefixAccepted": 14,
- "prefixReceived": 14,
- "upDownTime": 1694266296.367261,
- "underMaintenance": False,
"peerState": "Established",
},
},
},
"PROD": {
- "vrf": "PROD",
- "routerId": "10.1.0.3",
- "asn": "65120",
"peers": {
"10.1.254.1": {
- "description": "DC1-LEAF1B",
- "version": 4,
- "msgReceived": 3777,
- "msgSent": 3764,
"inMsgQueue": 0,
"outMsgQueue": 0,
- "asn": "65120",
- "prefixAccepted": 2,
- "prefixReceived": 2,
- "upDownTime": 1694266296.659891,
- "underMaintenance": False,
"peerState": "Established",
},
"192.168.1.11": {
- "description": "K8S-CLUSTER1",
- "version": 4,
- "msgReceived": 6417,
- "msgSent": 7546,
"inMsgQueue": 0,
"outMsgQueue": 0,
- "asn": "65000",
- "prefixAccepted": 1,
- "prefixReceived": 1,
- "upDownTime": 1694266329.978035,
- "underMaintenance": False,
"peerState": "Established",
},
},
},
}
- }
+ },
+ {
+ "vrfs": {
+ "default": {
+ "peers": {
+ "10.1.255.10": {
+ "inMsgQueue": 0,
+ "outMsgQueue": 0,
+ "peerState": "Established",
+ },
+ "10.1.255.12": {
+ "inMsgQueue": 0,
+ "outMsgQueue": 0,
+ "peerState": "Established",
+ },
+ },
+ },
+ "PROD": {
+ "peers": {
+ "10.1.254.11": {
+ "inMsgQueue": 0,
+ "outMsgQueue": 0,
+ "peerState": "Established",
+ },
+ "192.168.1.111": {
+ "inMsgQueue": 0,
+ "outMsgQueue": 0,
+ "peerState": "Established",
+ },
+ },
+ },
+ }
+ },
],
- "inputs": {"address_families": [{"afi": "ipv4", "safi": "unicast", "vrf": "all"}]},
+ "inputs": {
+ "address_families": [
+ {"afi": "ipv4", "safi": "unicast", "vrf": "all"},
+ {"afi": "ipv4", "safi": "sr-te", "vrf": "all"},
+ ]
+ },
"expected": {
"result": "success",
},
@@ -654,138 +844,183 @@ DATA: list[dict[str, Any]] = [
{
"vrfs": {
"default": {
- "vrf": "default",
- "routerId": "10.1.0.3",
- "asn": "65120",
"peers": {
"10.1.255.0": {
- "description": "DC1-SPINE1_Ethernet1",
- "version": 4,
- "msgReceived": 0,
- "msgSent": 0,
"inMsgQueue": 0,
"outMsgQueue": 0,
- "asn": "65100",
- "prefixAccepted": 0,
- "prefixReceived": 0,
- "upDownTime": 1694266295.098931,
- "underMaintenance": False,
"peerState": "Idle",
},
"10.1.255.2": {
- "description": "DC1-SPINE2_Ethernet1",
- "version": 4,
- "msgReceived": 3759,
- "msgSent": 3757,
"inMsgQueue": 0,
"outMsgQueue": 0,
- "asn": "65100",
- "prefixAccepted": 14,
- "prefixReceived": 14,
- "upDownTime": 1694266296.367261,
- "underMaintenance": False,
"peerState": "Established",
},
},
},
"PROD": {
- "vrf": "PROD",
- "routerId": "10.1.0.3",
- "asn": "65120",
"peers": {
"10.1.254.1": {
- "description": "DC1-LEAF1B",
- "version": 4,
- "msgReceived": 3777,
- "msgSent": 3764,
"inMsgQueue": 0,
"outMsgQueue": 0,
- "asn": "65120",
- "prefixAccepted": 2,
- "prefixReceived": 2,
- "upDownTime": 1694266296.659891,
- "underMaintenance": False,
"peerState": "Established",
},
"192.168.1.11": {
- "description": "K8S-CLUSTER1",
- "version": 4,
- "msgReceived": 6417,
- "msgSent": 7546,
"inMsgQueue": 100,
"outMsgQueue": 200,
- "asn": "65000",
- "prefixAccepted": 1,
- "prefixReceived": 1,
- "upDownTime": 1694266329.978035,
- "underMaintenance": False,
"peerState": "Established",
},
},
},
}
- }
+ },
+ {
+ "vrfs": {
+ "default": {
+ "peers": {
+ "10.1.255.10": {
+ "inMsgQueue": 0,
+ "outMsgQueue": 0,
+ "peerState": "Idle",
+ },
+ "10.1.255.12": {
+ "inMsgQueue": 0,
+ "outMsgQueue": 0,
+ "peerState": "Established",
+ },
+ },
+ },
+ "PROD": {
+ "peers": {
+ "10.1.254.11": {
+ "inMsgQueue": 0,
+ "outMsgQueue": 0,
+ "peerState": "Established",
+ },
+ "192.168.1.111": {
+ "inMsgQueue": 100,
+ "outMsgQueue": 200,
+ "peerState": "Established",
+ },
+ },
+ },
+ }
+ },
],
- "inputs": {"address_families": [{"afi": "ipv4", "safi": "unicast", "vrf": "all"}]},
+ "inputs": {
+ "address_families": [
+ {"afi": "ipv4", "safi": "unicast", "vrf": "all"},
+ {"afi": "ipv4", "safi": "sr-te", "vrf": "all"},
+ ]
+ },
"expected": {
"result": "failure",
"messages": [
"Failures: [{'afi': 'ipv4', 'safi': 'unicast', 'vrfs': {'default': {'10.1.255.0': {'peerState': 'Idle', 'inMsgQueue': 0, 'outMsgQueue': 0}}, "
- "'PROD': {'192.168.1.11': {'peerState': 'Established', 'inMsgQueue': 100, 'outMsgQueue': 200}}}}]"
+ "'PROD': {'192.168.1.11': {'peerState': 'Established', 'inMsgQueue': 100, 'outMsgQueue': 200}}}}, "
+ "{'afi': 'ipv4', 'safi': 'sr-te', 'vrfs': {'default': {'10.1.255.10': {'peerState': 'Idle', 'inMsgQueue': 0, 'outMsgQueue': 0}}, "
+ "'PROD': {'192.168.1.111': {'peerState': 'Established', 'inMsgQueue': 100, 'outMsgQueue': 200}}}}]"
],
},
},
{
"name": "failure-not-configured",
"test": VerifyBGPPeersHealth,
- "eos_data": [{"vrfs": {}}],
- "inputs": {"address_families": [{"afi": "ipv4", "safi": "unicast", "vrf": "DEV"}]},
- "expected": {"result": "failure", "messages": ["Failures: [{'afi': 'ipv4', 'safi': 'unicast', 'vrfs': {'DEV': 'Not Configured'}}]"]},
+ "eos_data": [{"vrfs": {}}, {"vrfs": {}}, {"vrfs": {}}, {"vrfs": {}}],
+ "inputs": {
+ "address_families": [
+ {"afi": "ipv4", "safi": "unicast", "vrf": "DEV"},
+ {"afi": "ipv4", "safi": "sr-te", "vrf": "MGMT"},
+ {"afi": "link-state"},
+ {"afi": "path-selection"},
+ ]
+ },
+ "expected": {
+ "result": "failure",
+ "messages": [
+ "Failures: [{'afi': 'ipv4', 'safi': 'unicast', 'vrfs': {'DEV': 'Not Configured'}}, "
+ "{'afi': 'ipv4', 'safi': 'sr-te', 'vrfs': {'MGMT': 'Not Configured'}}, "
+ "{'afi': 'link-state', 'vrfs': {'default': 'Not Configured'}}, "
+ "{'afi': 'path-selection', 'vrfs': {'default': 'Not Configured'}}]"
+ ],
+ },
},
{
"name": "failure-no-peers",
"test": VerifyBGPPeersHealth,
- "eos_data": [{"vrfs": {"default": {"vrf": "default", "routerId": "10.1.0.3", "asn": "65120", "peers": {}}}}],
- "inputs": {"address_families": [{"afi": "ipv4", "safi": "multicast"}]},
- "expected": {"result": "failure", "messages": ["Failures: [{'afi': 'ipv4', 'safi': 'multicast', 'vrfs': {'default': 'No Peers'}}]"]},
- },
- {
- "name": "success-multiple-afi",
- "test": VerifyBGPPeersHealth,
"eos_data": [
{
"vrfs": {
- "PROD": {
- "vrf": "PROD",
+ "default": {
+ "vrf": "default",
"routerId": "10.1.0.3",
"asn": "65120",
+ "peers": {},
+ }
+ }
+ },
+ {
+ "vrfs": {
+ "MGMT": {
+ "vrf": "MGMT",
+ "routerId": "10.1.0.3",
+ "asn": "65120",
+ "peers": {},
+ }
+ }
+ },
+ {
+ "vrfs": {
+ "default": {
+ "vrf": "default",
+ "routerId": "10.1.0.3",
+ "asn": "65120",
+ "peers": {},
+ }
+ }
+ },
+ {
+ "vrfs": {
+ "default": {
+ "vrf": "default",
+ "routerId": "10.1.0.3",
+ "asn": "65120",
+ "peers": {},
+ }
+ }
+ },
+ ],
+ "inputs": {
+ "address_families": [
+ {"afi": "ipv4", "safi": "multicast"},
+ {"afi": "ipv4", "safi": "sr-te", "vrf": "MGMT"},
+ {"afi": "link-state"},
+ {"afi": "path-selection"},
+ ]
+ },
+ "expected": {
+ "result": "failure",
+ "messages": [
+ "Failures: [{'afi': 'ipv4', 'safi': 'multicast', 'vrfs': {'default': 'No Peers'}}, {'afi': 'ipv4', 'safi': 'sr-te', 'vrfs': {'MGMT': 'No Peers'}}, "
+ "{'afi': 'link-state', 'vrfs': {'default': 'No Peers'}}, {'afi': 'path-selection', 'vrfs': {'default': 'No Peers'}}]"
+ ],
+ },
+ },
+ {
+ "name": "success",
+ "test": VerifyBGPSpecificPeers,
+ "eos_data": [
+ {
+ "vrfs": {
+ "default": {
"peers": {
- "10.1.254.1": {
- "description": "DC1-LEAF1B",
- "version": 4,
- "msgReceived": 3777,
- "msgSent": 3764,
+ "10.1.255.0": {
"inMsgQueue": 0,
"outMsgQueue": 0,
- "asn": "65120",
- "prefixAccepted": 2,
- "prefixReceived": 2,
- "upDownTime": 1694266296.659891,
- "underMaintenance": False,
"peerState": "Established",
},
- "192.168.1.11": {
- "description": "K8S-CLUSTER1",
- "version": 4,
- "msgReceived": 6417,
- "msgSent": 7546,
+ "10.1.255.2": {
"inMsgQueue": 0,
"outMsgQueue": 0,
- "asn": "65000",
- "prefixAccepted": 1,
- "prefixReceived": 1,
- "upDownTime": 1694266329.978035,
- "underMaintenance": False,
"peerState": "Established",
},
},
@@ -794,132 +1029,53 @@ DATA: list[dict[str, Any]] = [
},
{
"vrfs": {
- "default": {
- "vrf": "default",
- "routerId": "10.1.0.3",
- "asn": "65120",
+ "MGMT": {
"peers": {
- "10.1.0.1": {
- "description": "DC1-SPINE1",
- "version": 4,
- "msgReceived": 3894,
- "msgSent": 3897,
+ "10.1.255.10": {
"inMsgQueue": 0,
"outMsgQueue": 0,
- "asn": "65100",
- "prefixAccepted": 0,
- "prefixReceived": 0,
- "upDownTime": 1694266296.584472,
- "underMaintenance": False,
"peerState": "Established",
},
- "10.1.0.2": {
- "description": "DC1-SPINE2",
- "version": 4,
- "msgReceived": 3893,
- "msgSent": 3902,
+ "10.1.255.12": {
"inMsgQueue": 0,
"outMsgQueue": 0,
- "asn": "65100",
- "prefixAccepted": 0,
- "prefixReceived": 0,
- "upDownTime": 1694266297.433896,
- "underMaintenance": False,
"peerState": "Established",
},
},
}
}
},
- ],
- "inputs": {
- "address_families": [
- {"afi": "ipv4", "safi": "unicast", "vrf": "PROD"},
- {"afi": "evpn"},
- ]
- },
- "expected": {
- "result": "success",
- },
- },
- {
- "name": "failure-multiple-afi",
- "test": VerifyBGPPeersHealth,
- "eos_data": [
{
"vrfs": {
- "PROD": {
- "vrf": "PROD",
- "routerId": "10.1.0.3",
- "asn": "65120",
+ "default": {
"peers": {
- "10.1.254.1": {
- "description": "DC1-LEAF1B",
- "version": 4,
- "msgReceived": 3777,
- "msgSent": 3764,
+ "10.1.255.20": {
"inMsgQueue": 0,
"outMsgQueue": 0,
- "asn": "65120",
- "prefixAccepted": 2,
- "prefixReceived": 2,
- "upDownTime": 1694266296.659891,
- "underMaintenance": False,
"peerState": "Established",
},
- "192.168.1.11": {
- "description": "K8S-CLUSTER1",
- "version": 4,
- "msgReceived": 6417,
- "msgSent": 7546,
- "inMsgQueue": 10,
+ "10.1.255.22": {
+ "inMsgQueue": 0,
"outMsgQueue": 0,
- "asn": "65000",
- "prefixAccepted": 1,
- "prefixReceived": 1,
- "upDownTime": 1694266329.978035,
- "underMaintenance": False,
"peerState": "Established",
},
},
}
}
},
- {"vrfs": {}},
{
"vrfs": {
"default": {
- "vrf": "default",
- "routerId": "10.1.0.3",
- "asn": "65120",
"peers": {
- "10.1.0.1": {
- "description": "DC1-SPINE1",
- "version": 4,
- "msgReceived": 3894,
- "msgSent": 3897,
+ "10.1.255.30": {
"inMsgQueue": 0,
"outMsgQueue": 0,
- "asn": "65100",
- "prefixAccepted": 0,
- "prefixReceived": 0,
- "upDownTime": 1694266296.584472,
- "underMaintenance": False,
"peerState": "Established",
},
- "10.1.0.2": {
- "description": "DC1-SPINE2",
- "version": 4,
- "msgReceived": 3893,
- "msgSent": 3902,
+ "10.1.255.32": {
"inMsgQueue": 0,
"outMsgQueue": 0,
- "asn": "65100",
- "prefixAccepted": 0,
- "prefixReceived": 0,
- "upDownTime": 1694266297.433896,
- "underMaintenance": False,
- "peerState": "Idle",
+ "peerState": "Established",
},
},
}
@@ -928,174 +1084,77 @@ DATA: list[dict[str, Any]] = [
],
"inputs": {
"address_families": [
- {"afi": "ipv4", "safi": "unicast", "vrf": "PROD"},
- {"afi": "evpn"},
- {"afi": "ipv6", "safi": "unicast", "vrf": "default"},
+ # Path selection first to make sure input to output mapping is correct.
+ {"afi": "path-selection", "peers": ["10.1.255.20", "10.1.255.22"]},
+ {
+ "afi": "ipv4",
+ "safi": "unicast",
+ "vrf": "default",
+ "peers": ["10.1.255.0", "10.1.255.2"],
+ },
+ {
+ "afi": "ipv4",
+ "safi": "sr-te",
+ "vrf": "MGMT",
+ "peers": ["10.1.255.10", "10.1.255.12"],
+ },
+ {"afi": "link-state", "peers": ["10.1.255.30", "10.1.255.32"]},
]
},
- "expected": {
- "result": "failure",
- "messages": [
- "Failures: [{'afi': 'ipv4', 'safi': 'unicast', 'vrfs': "
- "{'PROD': {'192.168.1.11': {'peerState': 'Established', 'inMsgQueue': 10, 'outMsgQueue': 0}}}}, "
- "{'afi': 'ipv6', 'safi': 'unicast', 'vrfs': {'default': 'Not Configured'}}, "
- "{'afi': 'evpn', 'vrfs': {'default': {'10.1.0.2': {'peerState': 'Idle', 'inMsgQueue': 0, 'outMsgQueue': 0}}}"
- ],
- },
+ "expected": {"result": "success"},
},
{
- "name": "success",
+ "name": "failure-issues",
"test": VerifyBGPSpecificPeers,
"eos_data": [
{
"vrfs": {
"default": {
- "vrf": "default",
- "routerId": "10.1.0.3",
- "asn": "65120",
"peers": {
"10.1.255.0": {
- "description": "DC1-SPINE1_Ethernet1",
- "version": 4,
- "msgReceived": 0,
- "msgSent": 0,
"inMsgQueue": 0,
"outMsgQueue": 0,
- "asn": "65100",
- "prefixAccepted": 0,
- "prefixReceived": 0,
- "upDownTime": 1694266295.098931,
- "underMaintenance": False,
- "peerState": "Established",
+ "peerState": "Idle",
},
"10.1.255.2": {
- "description": "DC1-SPINE2_Ethernet1",
- "version": 4,
- "msgReceived": 3759,
- "msgSent": 3757,
"inMsgQueue": 0,
"outMsgQueue": 0,
- "asn": "65100",
- "prefixAccepted": 14,
- "prefixReceived": 14,
- "upDownTime": 1694266296.367261,
- "underMaintenance": False,
"peerState": "Established",
},
},
}
}
- }
- ],
- "inputs": {"address_families": [{"afi": "ipv4", "safi": "unicast", "vrf": "default", "peers": ["10.1.255.0", "10.1.255.2"]}]},
- "expected": {"result": "success"},
- },
- {
- "name": "failure-issues",
- "test": VerifyBGPSpecificPeers,
- "eos_data": [
+ },
{
"vrfs": {
- "default": {
- "vrf": "default",
- "routerId": "10.1.0.3",
- "asn": "65120",
+ "MGMT": {
"peers": {
- "10.1.255.0": {
- "description": "DC1-SPINE1_Ethernet1",
- "version": 4,
- "msgReceived": 0,
- "msgSent": 0,
+ "10.1.255.10": {
"inMsgQueue": 0,
"outMsgQueue": 0,
- "asn": "65100",
- "prefixAccepted": 0,
- "prefixReceived": 0,
- "upDownTime": 1694266295.098931,
- "underMaintenance": False,
- "peerState": "Idle",
+ "peerState": "Established",
},
- "10.1.255.2": {
- "description": "DC1-SPINE2_Ethernet1",
- "version": 4,
- "msgReceived": 3759,
- "msgSent": 3757,
+ "10.1.255.12": {
"inMsgQueue": 0,
"outMsgQueue": 0,
- "asn": "65100",
- "prefixAccepted": 14,
- "prefixReceived": 14,
- "upDownTime": 1694266296.367261,
- "underMaintenance": False,
- "peerState": "Established",
+ "peerState": "Idle",
},
},
}
}
- }
- ],
- "inputs": {"address_families": [{"afi": "ipv4", "safi": "unicast", "vrf": "default", "peers": ["10.1.255.0", "10.1.255.2"]}]},
- "expected": {
- "result": "failure",
- "messages": [
- "Failures: [{'afi': 'ipv4', 'safi': 'unicast', 'vrfs': {'default': {'10.1.255.0': {'peerState': 'Idle', 'inMsgQueue': 0, 'outMsgQueue': 0}}}}]"
- ],
- },
- },
- {
- "name": "failure-not-configured",
- "test": VerifyBGPSpecificPeers,
- "eos_data": [{"vrfs": {}}],
- "inputs": {"address_families": [{"afi": "ipv4", "safi": "unicast", "vrf": "DEV", "peers": ["10.1.255.0"]}]},
- "expected": {"result": "failure", "messages": ["Failures: [{'afi': 'ipv4', 'safi': 'unicast', 'vrfs': {'DEV': 'Not Configured'}}]"]},
- },
- {
- "name": "failure-no-peers",
- "test": VerifyBGPSpecificPeers,
- "eos_data": [{"vrfs": {"default": {"vrf": "default", "routerId": "10.1.0.3", "asn": "65120", "peers": {}}}}],
- "inputs": {"address_families": [{"afi": "ipv4", "safi": "multicast", "peers": ["10.1.255.0"]}]},
- "expected": {
- "result": "failure",
- "messages": ["Failures: [{'afi': 'ipv4', 'safi': 'multicast', 'vrfs': {'default': {'10.1.255.0': {'peerNotFound': True}}}}]"],
- },
- },
- {
- "name": "success-multiple-afi",
- "test": VerifyBGPSpecificPeers,
- "eos_data": [
+ },
{
"vrfs": {
- "PROD": {
- "vrf": "PROD",
- "routerId": "10.1.0.3",
- "asn": "65120",
+ "default": {
"peers": {
- "10.1.254.1": {
- "description": "DC1-LEAF1B",
- "version": 4,
- "msgReceived": 3777,
- "msgSent": 3764,
+ "10.1.255.20": {
"inMsgQueue": 0,
"outMsgQueue": 0,
- "asn": "65120",
- "prefixAccepted": 2,
- "prefixReceived": 2,
- "upDownTime": 1694266296.659891,
- "underMaintenance": False,
- "peerState": "Established",
+ "peerState": "Idle",
},
- "192.168.1.11": {
- "description": "K8S-CLUSTER1",
- "version": 4,
- "msgReceived": 6417,
- "msgSent": 7546,
+ "10.1.255.22": {
"inMsgQueue": 0,
"outMsgQueue": 0,
- "asn": "65000",
- "prefixAccepted": 1,
- "prefixReceived": 1,
- "upDownTime": 1694266329.978035,
- "underMaintenance": False,
"peerState": "Established",
},
},
@@ -1105,37 +1164,16 @@ DATA: list[dict[str, Any]] = [
{
"vrfs": {
"default": {
- "vrf": "default",
- "routerId": "10.1.0.3",
- "asn": "65120",
"peers": {
- "10.1.0.1": {
- "description": "DC1-SPINE1",
- "version": 4,
- "msgReceived": 3894,
- "msgSent": 3897,
+ "10.1.255.30": {
"inMsgQueue": 0,
"outMsgQueue": 0,
- "asn": "65100",
- "prefixAccepted": 0,
- "prefixReceived": 0,
- "upDownTime": 1694266296.584472,
- "underMaintenance": False,
"peerState": "Established",
},
- "10.1.0.2": {
- "description": "DC1-SPINE2",
- "version": 4,
- "msgReceived": 3893,
- "msgSent": 3902,
+ "10.1.255.32": {
"inMsgQueue": 0,
"outMsgQueue": 0,
- "asn": "65100",
- "prefixAccepted": 0,
- "prefixReceived": 0,
- "upDownTime": 1694266297.433896,
- "underMaintenance": False,
- "peerState": "Established",
+ "peerState": "Idle",
},
},
}
@@ -1144,110 +1182,128 @@ DATA: list[dict[str, Any]] = [
],
"inputs": {
"address_families": [
- {"afi": "ipv4", "safi": "unicast", "vrf": "PROD", "peers": ["10.1.254.1", "192.168.1.11"]},
- {"afi": "evpn", "peers": ["10.1.0.1", "10.1.0.2"]},
+ {
+ "afi": "ipv4",
+ "safi": "unicast",
+ "vrf": "default",
+ "peers": ["10.1.255.0", "10.1.255.2"],
+ },
+ {
+ "afi": "ipv4",
+ "safi": "sr-te",
+ "vrf": "MGMT",
+ "peers": ["10.1.255.10", "10.1.255.12"],
+ },
+ {"afi": "path-selection", "peers": ["10.1.255.20", "10.1.255.22"]},
+ {"afi": "link-state", "peers": ["10.1.255.30", "10.1.255.32"]},
]
},
- "expected": {"result": "success"},
+ "expected": {
+ "result": "failure",
+ "messages": [
+ "Failures: [{'afi': 'ipv4', 'safi': 'unicast', 'vrfs': {'default': {'10.1.255.0': {'peerState': 'Idle', 'inMsgQueue': 0, 'outMsgQueue': 0}}}}, "
+ "{'afi': 'ipv4', 'safi': 'sr-te', 'vrfs': {'MGMT': {'10.1.255.12': {'peerState': 'Idle', 'inMsgQueue': 0, 'outMsgQueue': 0}}}}, "
+ "{'afi': 'path-selection', 'vrfs': {'default': {'10.1.255.20': {'peerState': 'Idle', 'inMsgQueue': 0, 'outMsgQueue': 0}}}}, "
+ "{'afi': 'link-state', 'vrfs': {'default': {'10.1.255.32': {'peerState': 'Idle', 'inMsgQueue': 0, 'outMsgQueue': 0}}}}]"
+ ],
+ },
},
{
- "name": "failure-multiple-afi",
+ "name": "failure-not-configured",
+ "test": VerifyBGPSpecificPeers,
+ "eos_data": [{"vrfs": {}}, {"vrfs": {}}, {"vrfs": {}}, {"vrfs": {}}],
+ "inputs": {
+ "address_families": [
+ {
+ "afi": "ipv4",
+ "safi": "unicast",
+ "vrf": "DEV",
+ "peers": ["10.1.255.0"],
+ },
+ {
+ "afi": "ipv4",
+ "safi": "sr-te",
+ "vrf": "MGMT",
+ "peers": ["10.1.255.10"],
+ },
+ {"afi": "link-state", "peers": ["10.1.255.20"]},
+ {"afi": "path-selection", "peers": ["10.1.255.30"]},
+ ]
+ },
+ "expected": {
+ "result": "failure",
+ "messages": [
+ "Failures: [{'afi': 'ipv4', 'safi': 'unicast', 'vrfs': {'DEV': 'Not Configured'}}, "
+ "{'afi': 'ipv4', 'safi': 'sr-te', 'vrfs': {'MGMT': 'Not Configured'}}, {'afi': 'link-state', 'vrfs': {'default': 'Not Configured'}}, "
+ "{'afi': 'path-selection', 'vrfs': {'default': 'Not Configured'}}]"
+ ],
+ },
+ },
+ {
+ "name": "failure-no-peers",
"test": VerifyBGPSpecificPeers,
"eos_data": [
{
"vrfs": {
- "PROD": {
- "vrf": "PROD",
+ "default": {
+ "vrf": "default",
"routerId": "10.1.0.3",
"asn": "65120",
- "peers": {
- "10.1.254.1": {
- "description": "DC1-LEAF1B",
- "version": 4,
- "msgReceived": 3777,
- "msgSent": 3764,
- "inMsgQueue": 0,
- "outMsgQueue": 0,
- "asn": "65120",
- "prefixAccepted": 2,
- "prefixReceived": 2,
- "upDownTime": 1694266296.659891,
- "underMaintenance": False,
- "peerState": "Established",
- },
- "192.168.1.11": {
- "description": "K8S-CLUSTER1",
- "version": 4,
- "msgReceived": 6417,
- "msgSent": 7546,
- "inMsgQueue": 10,
- "outMsgQueue": 0,
- "asn": "65000",
- "prefixAccepted": 1,
- "prefixReceived": 1,
- "upDownTime": 1694266329.978035,
- "underMaintenance": False,
- "peerState": "Established",
- },
- },
+ "peers": {},
+ }
+ }
+ },
+ {
+ "vrfs": {
+ "MGMT": {
+ "vrf": "MGMT",
+ "routerId": "10.1.0.3",
+ "asn": "65120",
+ "peers": {},
}
}
},
- {"vrfs": {}},
{
"vrfs": {
"default": {
"vrf": "default",
"routerId": "10.1.0.3",
"asn": "65120",
- "peers": {
- "10.1.0.1": {
- "description": "DC1-SPINE1",
- "version": 4,
- "msgReceived": 3894,
- "msgSent": 3897,
- "inMsgQueue": 0,
- "outMsgQueue": 0,
- "asn": "65100",
- "prefixAccepted": 0,
- "prefixReceived": 0,
- "upDownTime": 1694266296.584472,
- "underMaintenance": False,
- "peerState": "Established",
- },
- "10.1.0.2": {
- "description": "DC1-SPINE2",
- "version": 4,
- "msgReceived": 3893,
- "msgSent": 3902,
- "inMsgQueue": 0,
- "outMsgQueue": 0,
- "asn": "65100",
- "prefixAccepted": 0,
- "prefixReceived": 0,
- "upDownTime": 1694266297.433896,
- "underMaintenance": False,
- "peerState": "Idle",
- },
- },
+ "peers": {},
+ }
+ }
+ },
+ {
+ "vrfs": {
+ "default": {
+ "vrf": "default",
+ "routerId": "10.1.0.3",
+ "asn": "65120",
+ "peers": {},
}
}
},
],
"inputs": {
"address_families": [
- {"afi": "ipv4", "safi": "unicast", "vrf": "PROD", "peers": ["10.1.254.1", "192.168.1.11"]},
- {"afi": "evpn", "peers": ["10.1.0.1", "10.1.0.2"]},
- {"afi": "ipv6", "safi": "unicast", "vrf": "default", "peers": ["10.1.0.1", "10.1.0.2"]},
+ {"afi": "ipv4", "safi": "multicast", "peers": ["10.1.255.0"]},
+ {
+ "afi": "ipv4",
+ "safi": "sr-te",
+ "vrf": "MGMT",
+ "peers": ["10.1.255.10"],
+ },
+ {"afi": "link-state", "peers": ["10.1.255.20"]},
+ {"afi": "path-selection", "peers": ["10.1.255.30"]},
]
},
"expected": {
"result": "failure",
"messages": [
- "Failures: [{'afi': 'ipv4', 'safi': 'unicast', 'vrfs': "
- "{'PROD': {'192.168.1.11': {'peerState': 'Established', 'inMsgQueue': 10, 'outMsgQueue': 0}}}}, "
- "{'afi': 'ipv6', 'safi': 'unicast', 'vrfs': {'default': 'Not Configured'}}, "
- "{'afi': 'evpn', 'vrfs': {'default': {'10.1.0.2': {'peerState': 'Idle', 'inMsgQueue': 0, 'outMsgQueue': 0}}}"
+ "Failures: [{'afi': 'ipv4', 'safi': 'multicast', 'vrfs': {'default': {'10.1.255.0': {'peerNotFound': True}}}}, "
+ "{'afi': 'ipv4', 'safi': 'sr-te', 'vrfs': {'MGMT': {'10.1.255.10': {'peerNotFound': True}}}}, "
+ "{'afi': 'link-state', 'vrfs': {'default': {'10.1.255.20': {'peerNotFound': True}}}}, "
+ "{'afi': 'path-selection', 'vrfs': {'default': {'10.1.255.30': {'peerNotFound': True}}}}]"
],
},
},
@@ -1390,10 +1446,46 @@ DATA: list[dict[str, Any]] = [
"name": "failure-no-routes",
"test": VerifyBGPExchangedRoutes,
"eos_data": [
- {"vrfs": {"default": {"vrf": "default", "routerId": "192.0.255.1", "asn": "65001", "bgpRouteEntries": {}}}},
- {"vrfs": {"default": {"vrf": "default", "routerId": "192.0.255.1", "asn": "65001", "bgpRouteEntries": {}}}},
- {"vrfs": {"default": {"vrf": "default", "routerId": "192.0.255.1", "asn": "65001", "bgpRouteEntries": {}}}},
- {"vrfs": {"default": {"vrf": "default", "routerId": "192.0.255.1", "asn": "65001", "bgpRouteEntries": {}}}},
+ {
+ "vrfs": {
+ "default": {
+ "vrf": "default",
+ "routerId": "192.0.255.1",
+ "asn": "65001",
+ "bgpRouteEntries": {},
+ }
+ }
+ },
+ {
+ "vrfs": {
+ "default": {
+ "vrf": "default",
+ "routerId": "192.0.255.1",
+ "asn": "65001",
+ "bgpRouteEntries": {},
+ }
+ }
+ },
+ {
+ "vrfs": {
+ "default": {
+ "vrf": "default",
+ "routerId": "192.0.255.1",
+ "asn": "65001",
+ "bgpRouteEntries": {},
+ }
+ }
+ },
+ {
+ "vrfs": {
+ "default": {
+ "vrf": "default",
+ "routerId": "192.0.255.1",
+ "asn": "65001",
+ "bgpRouteEntries": {},
+ }
+ }
+ },
],
"inputs": {
"bgp_peers": [
@@ -1801,8 +1893,16 @@ DATA: list[dict[str, Any]] = [
"peerAddress": "172.30.11.1",
"neighborCapabilities": {
"multiprotocolCaps": {
- "ipv4Unicast": {"advertised": True, "received": True, "enabled": True},
- "ipv4MplsLabels": {"advertised": True, "received": True, "enabled": True},
+ "ipv4Unicast": {
+ "advertised": True,
+ "received": True,
+ "enabled": True,
+ },
+ "ipv4MplsLabels": {
+ "advertised": True,
+ "received": True,
+ "enabled": True,
+ },
}
},
}
@@ -1814,8 +1914,16 @@ DATA: list[dict[str, Any]] = [
"peerAddress": "172.30.11.10",
"neighborCapabilities": {
"multiprotocolCaps": {
- "ipv4Unicast": {"advertised": True, "received": True, "enabled": True},
- "ipv4MplsVpn": {"advertised": True, "received": True, "enabled": True},
+ "ipv4Unicast": {
+ "advertised": True,
+ "received": True,
+ "enabled": True,
+ },
+ "ipv4MplsVpn": {
+ "advertised": True,
+ "received": True,
+ "enabled": True,
+ },
}
},
}
@@ -1852,8 +1960,16 @@ DATA: list[dict[str, Any]] = [
"peerAddress": "172.30.11.1",
"neighborCapabilities": {
"multiprotocolCaps": {
- "ipv4Unicast": {"advertised": True, "received": True, "enabled": True},
- "ipv4MplsVpn": {"advertised": True, "received": True, "enabled": True},
+ "ipv4Unicast": {
+ "advertised": True,
+ "received": True,
+ "enabled": True,
+ },
+ "ipv4MplsVpn": {
+ "advertised": True,
+ "received": True,
+ "enabled": True,
+ },
}
},
}
@@ -1889,7 +2005,13 @@ DATA: list[dict[str, Any]] = [
{
"peerAddress": "172.30.11.1",
"neighborCapabilities": {
- "multiprotocolCaps": {"ipv4Unicast": {"advertised": True, "received": True, "enabled": True}},
+ "multiprotocolCaps": {
+ "ipv4Unicast": {
+ "advertised": True,
+ "received": True,
+ "enabled": True,
+ }
+ },
},
}
]
@@ -1899,7 +2021,13 @@ DATA: list[dict[str, Any]] = [
{
"peerAddress": "172.30.11.10",
"neighborCapabilities": {
- "multiprotocolCaps": {"ipv4Unicast": {"advertised": True, "received": True, "enabled": True}},
+ "multiprotocolCaps": {
+ "ipv4Unicast": {
+ "advertised": True,
+ "received": True,
+ "enabled": True,
+ }
+ },
},
}
]
@@ -1940,7 +2068,13 @@ DATA: list[dict[str, Any]] = [
{
"peerAddress": "172.30.11.1",
"neighborCapabilities": {
- "multiprotocolCaps": {"ipv4Unicast": {"advertised": True, "received": True, "enabled": True}},
+ "multiprotocolCaps": {
+ "ipv4Unicast": {
+ "advertised": True,
+ "received": True,
+ "enabled": True,
+ }
+ },
},
}
]
@@ -1948,7 +2082,15 @@ DATA: list[dict[str, Any]] = [
}
}
],
- "inputs": {"bgp_peers": [{"peer_address": "172.30.11.1", "vrf": "default", "capabilities": ["ipv4 Unicast", "L2VpnEVPN"]}]},
+ "inputs": {
+ "bgp_peers": [
+ {
+ "peer_address": "172.30.11.1",
+ "vrf": "default",
+ "capabilities": ["ipv4 Unicast", "L2VpnEVPN"],
+ }
+ ]
+ },
"expected": {
"result": "failure",
"messages": [
@@ -1968,8 +2110,16 @@ DATA: list[dict[str, Any]] = [
"peerAddress": "172.30.11.1",
"neighborCapabilities": {
"multiprotocolCaps": {
- "ipv4Unicast": {"advertised": False, "received": False, "enabled": False},
- "ipv4MplsVpn": {"advertised": False, "received": True, "enabled": False},
+ "ipv4Unicast": {
+ "advertised": False,
+ "received": False,
+ "enabled": False,
+ },
+ "ipv4MplsVpn": {
+ "advertised": False,
+ "received": True,
+ "enabled": False,
+ },
},
},
}
@@ -1981,8 +2131,16 @@ DATA: list[dict[str, Any]] = [
"peerAddress": "172.30.11.10",
"neighborCapabilities": {
"multiprotocolCaps": {
- "l2VpnEvpn": {"advertised": True, "received": False, "enabled": False},
- "ipv4MplsVpn": {"advertised": False, "received": False, "enabled": True},
+ "l2VpnEvpn": {
+ "advertised": True,
+ "received": False,
+ "enabled": False,
+ },
+ "ipv4MplsVpn": {
+ "advertised": False,
+ "received": False,
+ "enabled": True,
+ },
},
},
},
@@ -1990,8 +2148,16 @@ DATA: list[dict[str, Any]] = [
"peerAddress": "172.30.11.11",
"neighborCapabilities": {
"multiprotocolCaps": {
- "ipv4Unicast": {"advertised": False, "received": False, "enabled": False},
- "ipv4MplsVpn": {"advertised": False, "received": False, "enabled": False},
+ "ipv4Unicast": {
+ "advertised": False,
+ "received": False,
+ "enabled": False,
+ },
+ "ipv4MplsVpn": {
+ "advertised": False,
+ "received": False,
+ "enabled": False,
+ },
},
},
},
@@ -2002,9 +2168,21 @@ DATA: list[dict[str, Any]] = [
],
"inputs": {
"bgp_peers": [
- {"peer_address": "172.30.11.1", "vrf": "default", "capabilities": ["ipv4 unicast", "ipv4 mpls vpn", "L2 vpn EVPN"]},
- {"peer_address": "172.30.11.10", "vrf": "MGMT", "capabilities": ["ipv4unicast", "ipv4 mplsvpn", "L2vpnEVPN"]},
- {"peer_address": "172.30.11.11", "vrf": "MGMT", "capabilities": ["Ipv4 Unicast", "ipv4 MPLSVPN", "L2 vpnEVPN"]},
+ {
+ "peer_address": "172.30.11.1",
+ "vrf": "default",
+ "capabilities": ["ipv4 unicast", "ipv4 mpls vpn", "L2 vpn EVPN"],
+ },
+ {
+ "peer_address": "172.30.11.10",
+ "vrf": "MGMT",
+ "capabilities": ["ipv4unicast", "ipv4 mplsvpn", "L2vpnEVPN"],
+ },
+ {
+ "peer_address": "172.30.11.11",
+ "vrf": "MGMT",
+ "capabilities": ["Ipv4 Unicast", "ipv4 MPLSVPN", "L2 vpnEVPN"],
+ },
]
},
"expected": {
@@ -2031,7 +2209,11 @@ DATA: list[dict[str, Any]] = [
{
"peerAddress": "172.30.11.1",
"neighborCapabilities": {
- "fourOctetAsnCap": {"advertised": True, "received": True, "enabled": True},
+ "fourOctetAsnCap": {
+ "advertised": True,
+ "received": True,
+ "enabled": True,
+ },
},
}
]
@@ -2041,7 +2223,11 @@ DATA: list[dict[str, Any]] = [
{
"peerAddress": "172.30.11.10",
"neighborCapabilities": {
- "fourOctetAsnCap": {"advertised": True, "received": True, "enabled": True},
+ "fourOctetAsnCap": {
+ "advertised": True,
+ "received": True,
+ "enabled": True,
+ },
},
}
]
@@ -2074,7 +2260,11 @@ DATA: list[dict[str, Any]] = [
{
"peerAddress": "172.30.11.1",
"neighborCapabilities": {
- "fourOctetAsnCap": {"advertised": True, "received": True, "enabled": True},
+ "fourOctetAsnCap": {
+ "advertised": True,
+ "received": True,
+ "enabled": True,
+ },
},
}
]
@@ -2085,7 +2275,11 @@ DATA: list[dict[str, Any]] = [
{
"peerAddress": "172.30.11.10",
"neighborCapabilities": {
- "fourOctetAsnCap": {"advertised": True, "received": True, "enabled": True},
+ "fourOctetAsnCap": {
+ "advertised": True,
+ "received": True,
+ "enabled": True,
+ },
},
}
]
@@ -2123,7 +2317,13 @@ DATA: list[dict[str, Any]] = [
{
"peerAddress": "172.30.11.1",
"neighborCapabilities": {
- "multiprotocolCaps": {"ipv4Unicast": {"advertised": True, "received": True, "enabled": True}},
+ "multiprotocolCaps": {
+ "ipv4Unicast": {
+ "advertised": True,
+ "received": True,
+ "enabled": True,
+ }
+ },
},
},
]
@@ -2157,7 +2357,13 @@ DATA: list[dict[str, Any]] = [
{
"peerAddress": "172.30.11.1",
"neighborCapabilities": {
- "multiprotocolCaps": {"ipv4Unicast": {"advertised": True, "received": True, "enabled": True}},
+ "multiprotocolCaps": {
+ "ipv4Unicast": {
+ "advertised": True,
+ "received": True,
+ "enabled": True,
+ }
+ },
},
}
]
@@ -2167,7 +2373,13 @@ DATA: list[dict[str, Any]] = [
{
"peerAddress": "172.30.11.10",
"neighborCapabilities": {
- "multiprotocolCaps": {"ipv4MplsLabels": {"advertised": True, "received": True, "enabled": True}},
+ "multiprotocolCaps": {
+ "ipv4MplsLabels": {
+ "advertised": True,
+ "received": True,
+ "enabled": True,
+ }
+ },
},
}
]
@@ -2175,7 +2387,12 @@ DATA: list[dict[str, Any]] = [
}
}
],
- "inputs": {"bgp_peers": [{"peer_address": "172.30.11.1", "vrf": "default"}, {"peer_address": "172.30.11.10", "vrf": "MGMT"}]},
+ "inputs": {
+ "bgp_peers": [
+ {"peer_address": "172.30.11.1", "vrf": "default"},
+ {"peer_address": "172.30.11.10", "vrf": "MGMT"},
+ ]
+ },
"expected": {
"result": "failure",
"messages": [
@@ -2195,7 +2412,11 @@ DATA: list[dict[str, Any]] = [
{
"peerAddress": "172.30.11.1",
"neighborCapabilities": {
- "fourOctetAsnCap": {"advertised": False, "received": False, "enabled": False},
+ "fourOctetAsnCap": {
+ "advertised": False,
+ "received": False,
+ "enabled": False,
+ },
},
}
]
@@ -2205,7 +2426,11 @@ DATA: list[dict[str, Any]] = [
{
"peerAddress": "172.30.11.10",
"neighborCapabilities": {
- "fourOctetAsnCap": {"advertised": True, "received": False, "enabled": True},
+ "fourOctetAsnCap": {
+ "advertised": True,
+ "received": False,
+ "enabled": True,
+ },
},
}
]
@@ -2213,7 +2438,12 @@ DATA: list[dict[str, Any]] = [
}
}
],
- "inputs": {"bgp_peers": [{"peer_address": "172.30.11.1", "vrf": "default"}, {"peer_address": "172.30.11.10", "vrf": "MGMT"}]},
+ "inputs": {
+ "bgp_peers": [
+ {"peer_address": "172.30.11.1", "vrf": "default"},
+ {"peer_address": "172.30.11.10", "vrf": "MGMT"},
+ ]
+ },
"expected": {
"result": "failure",
"messages": [
@@ -2234,7 +2464,11 @@ DATA: list[dict[str, Any]] = [
{
"peerAddress": "172.30.11.1",
"neighborCapabilities": {
- "routeRefreshCap": {"advertised": True, "received": True, "enabled": True},
+ "routeRefreshCap": {
+ "advertised": True,
+ "received": True,
+ "enabled": True,
+ },
},
}
]
@@ -2244,7 +2478,11 @@ DATA: list[dict[str, Any]] = [
{
"peerAddress": "172.30.11.11",
"neighborCapabilities": {
- "routeRefreshCap": {"advertised": True, "received": True, "enabled": True},
+ "routeRefreshCap": {
+ "advertised": True,
+ "received": True,
+ "enabled": True,
+ },
},
}
]
@@ -2296,7 +2534,13 @@ DATA: list[dict[str, Any]] = [
{
"peerAddress": "172.30.11.1",
"neighborCapabilities": {
- "multiprotocolCaps": {"ip4Unicast": {"advertised": True, "received": True, "enabled": True}},
+ "multiprotocolCaps": {
+ "ip4Unicast": {
+ "advertised": True,
+ "received": True,
+ "enabled": True,
+ }
+ },
},
}
]
@@ -2306,7 +2550,13 @@ DATA: list[dict[str, Any]] = [
{
"peerAddress": "172.30.11.12",
"neighborCapabilities": {
- "multiprotocolCaps": {"ip4Unicast": {"advertised": True, "received": True, "enabled": True}},
+ "multiprotocolCaps": {
+ "ip4Unicast": {
+ "advertised": True,
+ "received": True,
+ "enabled": True,
+ }
+ },
},
}
]
@@ -2345,7 +2595,13 @@ DATA: list[dict[str, Any]] = [
{
"peerAddress": "172.30.11.1",
"neighborCapabilities": {
- "multiprotocolCaps": {"ipv4Unicast": {"advertised": True, "received": True, "enabled": True}},
+ "multiprotocolCaps": {
+ "ipv4Unicast": {
+ "advertised": True,
+ "received": True,
+ "enabled": True,
+ }
+ },
},
}
]
@@ -2355,7 +2611,13 @@ DATA: list[dict[str, Any]] = [
{
"peerAddress": "172.30.11.11",
"neighborCapabilities": {
- "multiprotocolCaps": {"ipv4Unicast": {"advertised": True, "received": True, "enabled": True}},
+ "multiprotocolCaps": {
+ "ipv4Unicast": {
+ "advertised": True,
+ "received": True,
+ "enabled": True,
+ }
+ },
},
}
]
@@ -2363,7 +2625,12 @@ DATA: list[dict[str, Any]] = [
}
}
],
- "inputs": {"bgp_peers": [{"peer_address": "172.30.11.1", "vrf": "default"}, {"peer_address": "172.30.11.11", "vrf": "CS"}]},
+ "inputs": {
+ "bgp_peers": [
+ {"peer_address": "172.30.11.1", "vrf": "default"},
+ {"peer_address": "172.30.11.11", "vrf": "CS"},
+ ]
+ },
"expected": {
"result": "failure",
"messages": [
@@ -2383,7 +2650,11 @@ DATA: list[dict[str, Any]] = [
{
"peerAddress": "172.30.11.1",
"neighborCapabilities": {
- "routeRefreshCap": {"advertised": False, "received": False, "enabled": False},
+ "routeRefreshCap": {
+ "advertised": False,
+ "received": False,
+ "enabled": False,
+ },
},
}
]
@@ -2393,7 +2664,11 @@ DATA: list[dict[str, Any]] = [
{
"peerAddress": "172.30.11.11",
"neighborCapabilities": {
- "routeRefreshCap": {"advertised": True, "received": True, "enabled": True},
+ "routeRefreshCap": {
+ "advertised": True,
+ "received": True,
+ "enabled": True,
+ },
},
}
]
@@ -2401,7 +2676,12 @@ DATA: list[dict[str, Any]] = [
}
}
],
- "inputs": {"bgp_peers": [{"peer_address": "172.30.11.1", "vrf": "default"}, {"peer_address": "172.30.11.11", "vrf": "CS"}]},
+ "inputs": {
+ "bgp_peers": [
+ {"peer_address": "172.30.11.1", "vrf": "default"},
+ {"peer_address": "172.30.11.11", "vrf": "CS"},
+ ]
+ },
"expected": {
"result": "failure",
"messages": [
@@ -2592,10 +2872,22 @@ DATA: list[dict[str, Any]] = [
"peerAddress": "172.30.11.1",
"state": "Established",
},
- {"peerAddress": "172.30.11.10", "state": "Established", "md5AuthEnabled": False},
+ {
+ "peerAddress": "172.30.11.10",
+ "state": "Established",
+ "md5AuthEnabled": False,
+ },
+ ]
+ },
+ "MGMT": {
+ "peerList": [
+ {
+ "peerAddress": "172.30.11.11",
+ "state": "Established",
+ "md5AuthEnabled": False,
+ }
]
},
- "MGMT": {"peerList": [{"peerAddress": "172.30.11.11", "state": "Established", "md5AuthEnabled": False}]},
}
}
],
@@ -2684,7 +2976,12 @@ DATA: list[dict[str, Any]] = [
},
},
],
- "inputs": {"vxlan_endpoints": [{"address": "192.168.20.102", "vni": 10020}, {"address": "aac1.ab5d.b41e", "vni": 10010}]},
+ "inputs": {
+ "vxlan_endpoints": [
+ {"address": "192.168.20.102", "vni": 10020},
+ {"address": "aac1.ab5d.b41e", "vni": 10010},
+ ]
+ },
"expected": {"result": "success"},
},
{
@@ -3024,7 +3321,12 @@ DATA: list[dict[str, Any]] = [
},
},
],
- "inputs": {"vxlan_endpoints": [{"address": "192.168.20.102", "vni": 10020}, {"address": "aac1.ab5d.b41e", "vni": 10010}]},
+ "inputs": {
+ "vxlan_endpoints": [
+ {"address": "192.168.20.102", "vni": 10020},
+ {"address": "aac1.ab5d.b41e", "vni": 10010},
+ ]
+ },
"expected": {
"result": "failure",
"messages": [
@@ -3057,7 +3359,12 @@ DATA: list[dict[str, Any]] = [
},
},
],
- "inputs": {"vxlan_endpoints": [{"address": "aac1.ab4e.bec2", "vni": 10020}, {"address": "192.168.10.101", "vni": 10010}]},
+ "inputs": {
+ "vxlan_endpoints": [
+ {"address": "aac1.ab4e.bec2", "vni": 10020},
+ {"address": "192.168.10.101", "vni": 10010},
+ ]
+ },
"expected": {
"result": "failure",
"messages": [
@@ -3074,7 +3381,12 @@ DATA: list[dict[str, Any]] = [
{"vrf": "default", "routerId": "10.1.0.3", "asn": 65120, "evpnRoutes": {}},
{"vrf": "default", "routerId": "10.1.0.3", "asn": 65120, "evpnRoutes": {}},
],
- "inputs": {"vxlan_endpoints": [{"address": "aac1.ab4e.bec2", "vni": 10020}, {"address": "192.168.10.101", "vni": 10010}]},
+ "inputs": {
+ "vxlan_endpoints": [
+ {"address": "aac1.ab4e.bec2", "vni": 10020},
+ {"address": "192.168.10.101", "vni": 10010},
+ ]
+ },
"expected": {
"result": "failure",
"messages": ["The following VXLAN endpoint do not have any EVPN Type-2 route: [('aa:c1:ab:4e:be:c2', 10020), ('192.168.10.101', 10010)]"],
@@ -3090,7 +3402,11 @@ DATA: list[dict[str, Any]] = [
"peerList": [
{
"peerAddress": "172.30.11.1",
- "advertisedCommunities": {"standard": True, "extended": True, "large": True},
+ "advertisedCommunities": {
+ "standard": True,
+ "extended": True,
+ "large": True,
+ },
}
]
},
@@ -3098,7 +3414,11 @@ DATA: list[dict[str, Any]] = [
"peerList": [
{
"peerAddress": "172.30.11.10",
- "advertisedCommunities": {"standard": True, "extended": True, "large": True},
+ "advertisedCommunities": {
+ "standard": True,
+ "extended": True,
+ "large": True,
+ },
}
]
},
@@ -3128,7 +3448,11 @@ DATA: list[dict[str, Any]] = [
"peerList": [
{
"peerAddress": "172.30.11.1",
- "advertisedCommunities": {"standard": True, "extended": True, "large": True},
+ "advertisedCommunities": {
+ "standard": True,
+ "extended": True,
+ "large": True,
+ },
}
]
},
@@ -3161,7 +3485,11 @@ DATA: list[dict[str, Any]] = [
"peerList": [
{
"peerAddress": "172.30.11.1",
- "advertisedCommunities": {"standard": True, "extended": True, "large": True},
+ "advertisedCommunities": {
+ "standard": True,
+ "extended": True,
+ "large": True,
+ },
}
]
},
@@ -3169,7 +3497,11 @@ DATA: list[dict[str, Any]] = [
"peerList": [
{
"peerAddress": "172.30.11.1",
- "advertisedCommunities": {"standard": True, "extended": True, "large": True},
+ "advertisedCommunities": {
+ "standard": True,
+ "extended": True,
+ "large": True,
+ },
}
]
},
@@ -3206,7 +3538,11 @@ DATA: list[dict[str, Any]] = [
"peerList": [
{
"peerAddress": "172.30.11.1",
- "advertisedCommunities": {"standard": False, "extended": False, "large": False},
+ "advertisedCommunities": {
+ "standard": False,
+ "extended": False,
+ "large": False,
+ },
}
]
},
@@ -3214,7 +3550,11 @@ DATA: list[dict[str, Any]] = [
"peerList": [
{
"peerAddress": "172.30.11.10",
- "advertisedCommunities": {"standard": True, "extended": True, "large": False},
+ "advertisedCommunities": {
+ "standard": True,
+ "extended": True,
+ "large": False,
+ },
}
]
},
diff --git a/tests/units/anta_tests/routing/test_generic.py b/tests/units/anta_tests/routing/test_generic.py
index 90e70f8..36658f5 100644
--- a/tests/units/anta_tests/routing/test_generic.py
+++ b/tests/units/anta_tests/routing/test_generic.py
@@ -1,9 +1,8 @@
# Copyright (c) 2023-2024 Arista Networks, Inc.
# Use of this source code is governed by the Apache License 2.0
# that can be found in the LICENSE file.
-"""
-Tests for anta.tests.routing.generic.py
-"""
+"""Tests for anta.tests.routing.generic.py."""
+
from __future__ import annotations
from typing import Any
@@ -43,9 +42,9 @@ DATA: list[dict[str, Any]] = [
# Output truncated
"maskLen": {"8": 2},
"totalRoutes": 123,
- }
+ },
},
- }
+ },
],
"inputs": {"minimum": 42, "maximum": 666},
"expected": {"result": "success"},
@@ -60,9 +59,9 @@ DATA: list[dict[str, Any]] = [
# Output truncated
"maskLen": {"8": 2},
"totalRoutes": 1000,
- }
+ },
},
- }
+ },
],
"inputs": {"minimum": 42, "maximum": 666},
"expected": {"result": "failure", "messages": ["routing-table has 1000 routes and not between min (42) and maximum (666)"]},
@@ -99,10 +98,10 @@ DATA: list[dict[str, Any]] = [
"preference": 20,
"metric": 0,
"vias": [{"nexthopAddr": "10.1.255.4", "interface": "Ethernet1"}],
- }
+ },
},
- }
- }
+ },
+ },
},
{
"vrfs": {
@@ -122,10 +121,10 @@ DATA: list[dict[str, Any]] = [
"preference": 20,
"metric": 0,
"vias": [{"nexthopAddr": "10.1.255.6", "interface": "Ethernet2"}],
- }
+ },
},
- }
- }
+ },
+ },
},
],
"inputs": {"vrf": "default", "routes": ["10.1.0.1", "10.1.0.2"]},
@@ -143,8 +142,8 @@ DATA: list[dict[str, Any]] = [
"allRoutesProgrammedKernel": True,
"defaultRouteState": "notSet",
"routes": {},
- }
- }
+ },
+ },
},
{
"vrfs": {
@@ -164,10 +163,10 @@ DATA: list[dict[str, Any]] = [
"preference": 20,
"metric": 0,
"vias": [{"nexthopAddr": "10.1.255.6", "interface": "Ethernet2"}],
- }
+ },
},
- }
- }
+ },
+ },
},
],
"inputs": {"vrf": "default", "routes": ["10.1.0.1", "10.1.0.2"]},
@@ -195,10 +194,10 @@ DATA: list[dict[str, Any]] = [
"preference": 20,
"metric": 0,
"vias": [{"nexthopAddr": "10.1.255.4", "interface": "Ethernet1"}],
- }
+ },
},
- }
- }
+ },
+ },
},
{
"vrfs": {
@@ -218,10 +217,10 @@ DATA: list[dict[str, Any]] = [
"preference": 20,
"metric": 0,
"vias": [{"nexthopAddr": "10.1.255.6", "interface": "Ethernet2"}],
- }
+ },
},
- }
- }
+ },
+ },
},
],
"inputs": {"vrf": "default", "routes": ["10.1.0.1", "10.1.0.2"]},
diff --git a/tests/units/anta_tests/routing/test_isis.py b/tests/units/anta_tests/routing/test_isis.py
new file mode 100644
index 0000000..ec41105
--- /dev/null
+++ b/tests/units/anta_tests/routing/test_isis.py
@@ -0,0 +1,570 @@
+# Copyright (c) 2023-2024 Arista Networks, Inc.
+# Use of this source code is governed by the Apache License 2.0
+# that can be found in the LICENSE file.
+"""Tests for anta.tests.routing.ospf.py."""
+
+from __future__ import annotations
+
+from typing import Any
+
+from anta.tests.routing.isis import VerifyISISInterfaceMode, VerifyISISNeighborCount, VerifyISISNeighborState
+from tests.lib.anta import test # noqa: F401; pylint: disable=W0611
+
+DATA: list[dict[str, Any]] = [
+ {
+ "name": "success only default vrf",
+ "test": VerifyISISNeighborState,
+ "eos_data": [
+ {
+ "vrfs": {
+ "default": {
+ "isisInstances": {
+ "CORE-ISIS": {
+ "neighbors": {
+ "0168.0000.0111": {
+ "adjacencies": [
+ {
+ "hostname": "s1-p01",
+ "circuitId": "83",
+ "interfaceName": "Ethernet1",
+ "state": "up",
+ "lastHelloTime": 1713688408,
+ "routerIdV4": "1.0.0.111",
+ }
+ ]
+ },
+ "0168.0000.0112": {
+ "adjacencies": [
+ {
+ "hostname": "s1-p02",
+ "circuitId": "87",
+ "interfaceName": "Ethernet2",
+ "state": "up",
+ "lastHelloTime": 1713688405,
+ "routerIdV4": "1.0.0.112",
+ }
+ ]
+ },
+ }
+ }
+ }
+ }
+ }
+ },
+ ],
+ "inputs": None,
+ "expected": {"result": "success"},
+ },
+ {
+ "name": "success different vrfs",
+ "test": VerifyISISNeighborState,
+ "eos_data": [
+ {
+ "vrfs": {
+ "default": {
+ "isisInstances": {
+ "CORE-ISIS": {
+ "neighbors": {
+ "0168.0000.0111": {
+ "adjacencies": [
+ {
+ "hostname": "s1-p01",
+ "circuitId": "83",
+ "interfaceName": "Ethernet1",
+ "state": "up",
+ "lastHelloTime": 1713688408,
+ "routerIdV4": "1.0.0.111",
+ }
+ ]
+ },
+ },
+ },
+ },
+ "customer": {
+ "isisInstances": {
+ "CORE-ISIS": {
+ "neighbors": {
+ "0168.0000.0112": {
+ "adjacencies": [
+ {
+ "hostname": "s1-p02",
+ "circuitId": "87",
+ "interfaceName": "Ethernet2",
+ "state": "up",
+ "lastHelloTime": 1713688405,
+ "routerIdV4": "1.0.0.112",
+ }
+ ]
+ }
+ }
+ }
+ }
+ },
+ }
+ }
+ },
+ ],
+ "inputs": None,
+ "expected": {"result": "success"},
+ },
+ {
+ "name": "failure",
+ "test": VerifyISISNeighborState,
+ "eos_data": [
+ {
+ "vrfs": {
+ "default": {
+ "isisInstances": {
+ "CORE-ISIS": {
+ "neighbors": {
+ "0168.0000.0111": {
+ "adjacencies": [
+ {
+ "hostname": "s1-p01",
+ "circuitId": "83",
+ "interfaceName": "Ethernet1",
+ "state": "down",
+ "lastHelloTime": 1713688408,
+ "routerIdV4": "1.0.0.111",
+ }
+ ]
+ },
+ "0168.0000.0112": {
+ "adjacencies": [
+ {
+ "hostname": "s1-p02",
+ "circuitId": "87",
+ "interfaceName": "Ethernet2",
+ "state": "up",
+ "lastHelloTime": 1713688405,
+ "routerIdV4": "1.0.0.112",
+ }
+ ]
+ },
+ }
+ }
+ }
+ }
+ }
+ },
+ ],
+ "inputs": None,
+ "expected": {
+ "result": "failure",
+ "messages": ["Some neighbors are not in the correct state (UP): [{'vrf': 'default', 'instance': 'CORE-ISIS', 'neighbor': 's1-p01', 'state': 'down'}]."],
+ },
+ },
+ {
+ "name": "success only default vrf",
+ "test": VerifyISISNeighborCount,
+ "eos_data": [
+ {
+ "vrfs": {
+ "default": {
+ "isisInstances": {
+ "CORE-ISIS": {
+ "interfaces": {
+ "Loopback0": {
+ "enabled": True,
+ "intfLevels": {
+ "2": {
+ "ipv4Metric": 10,
+ "sharedSecretProfile": "",
+ "isisAdjacencies": [],
+ "passive": True,
+ "v4Protection": "disabled",
+ "v6Protection": "disabled",
+ }
+ },
+ "areaProxyBoundary": False,
+ },
+ "Ethernet1": {
+ "intfLevels": {
+ "2": {
+ "ipv4Metric": 10,
+ "numAdjacencies": 1,
+ "linkId": "84",
+ "sharedSecretProfile": "",
+ "isisAdjacencies": [],
+ "passive": False,
+ "v4Protection": "link",
+ "v6Protection": "disabled",
+ }
+ },
+ "interfaceSpeed": 1000,
+ "areaProxyBoundary": False,
+ },
+ "Ethernet2": {
+ "enabled": True,
+ "intfLevels": {
+ "2": {
+ "ipv4Metric": 10,
+ "numAdjacencies": 1,
+ "linkId": "88",
+ "sharedSecretProfile": "",
+ "isisAdjacencies": [],
+ "passive": False,
+ "v4Protection": "link",
+ "v6Protection": "disabled",
+ }
+ },
+ "interfaceSpeed": 1000,
+ "areaProxyBoundary": False,
+ },
+ }
+ }
+ }
+ }
+ }
+ },
+ ],
+ "inputs": {
+ "interfaces": [
+ {"name": "Ethernet1", "level": 2, "count": 1},
+ {"name": "Ethernet2", "level": 2, "count": 1},
+ ]
+ },
+ "expected": {"result": "success"},
+ },
+ {
+ "name": "success VerifyISISInterfaceMode only default vrf",
+ "test": VerifyISISInterfaceMode,
+ "eos_data": [
+ {
+ "vrfs": {
+ "default": {
+ "isisInstances": {
+ "CORE-ISIS": {
+ "interfaces": {
+ "Loopback0": {
+ "enabled": True,
+ "index": 2,
+ "snpa": "0:0:0:0:0:0",
+ "mtu": 65532,
+ "interfaceAddressFamily": "ipv4",
+ "interfaceType": "loopback",
+ "intfLevels": {
+ "2": {
+ "ipv4Metric": 10,
+ "sharedSecretProfile": "",
+ "isisAdjacencies": [],
+ "passive": True,
+ "v4Protection": "disabled",
+ "v6Protection": "disabled",
+ }
+ },
+ "areaProxyBoundary": False,
+ },
+ "Ethernet1": {
+ "enabled": True,
+ "index": 132,
+ "snpa": "P2P",
+ "interfaceType": "point-to-point",
+ "intfLevels": {
+ "2": {
+ "ipv4Metric": 10,
+ "numAdjacencies": 1,
+ "linkId": "84",
+ "sharedSecretProfile": "",
+ "isisAdjacencies": [],
+ "passive": False,
+ "v4Protection": "link",
+ "v6Protection": "disabled",
+ }
+ },
+ "interfaceSpeed": 1000,
+ "areaProxyBoundary": False,
+ },
+ "Ethernet2": {
+ "enabled": True,
+ "interfaceType": "broadcast",
+ "intfLevels": {
+ "2": {
+ "ipv4Metric": 10,
+ "numAdjacencies": 0,
+ "sharedSecretProfile": "",
+ "isisAdjacencies": [],
+ "passive": True,
+ "v4Protection": "disabled",
+ "v6Protection": "disabled",
+ }
+ },
+ "interfaceSpeed": 1000,
+ "areaProxyBoundary": False,
+ },
+ }
+ }
+ }
+ }
+ }
+ }
+ ],
+ "inputs": {
+ "interfaces": [
+ {"name": "Loopback0", "mode": "passive"},
+ {"name": "Ethernet2", "mode": "passive"},
+ {"name": "Ethernet1", "mode": "point-to-point", "vrf": "default"},
+ ]
+ },
+ "expected": {"result": "success"},
+ },
+ {
+ "name": "failure VerifyISISInterfaceMode default vrf with interface not running passive mode",
+ "test": VerifyISISInterfaceMode,
+ "eos_data": [
+ {
+ "vrfs": {
+ "default": {
+ "isisInstances": {
+ "CORE-ISIS": {
+ "interfaces": {
+ "Loopback0": {
+ "enabled": True,
+ "index": 2,
+ "snpa": "0:0:0:0:0:0",
+ "mtu": 65532,
+ "interfaceAddressFamily": "ipv4",
+ "interfaceType": "loopback",
+ "intfLevels": {
+ "2": {
+ "ipv4Metric": 10,
+ "sharedSecretProfile": "",
+ "isisAdjacencies": [],
+ "passive": True,
+ "v4Protection": "disabled",
+ "v6Protection": "disabled",
+ }
+ },
+ "areaProxyBoundary": False,
+ },
+ "Ethernet1": {
+ "enabled": True,
+ "index": 132,
+ "snpa": "P2P",
+ "interfaceType": "point-to-point",
+ "intfLevels": {
+ "2": {
+ "ipv4Metric": 10,
+ "numAdjacencies": 1,
+ "linkId": "84",
+ "sharedSecretProfile": "",
+ "isisAdjacencies": [],
+ "passive": False,
+ "v4Protection": "link",
+ "v6Protection": "disabled",
+ }
+ },
+ "interfaceSpeed": 1000,
+ "areaProxyBoundary": False,
+ },
+ "Ethernet2": {
+ "enabled": True,
+ "interfaceType": "point-to-point",
+ "intfLevels": {
+ "2": {
+ "ipv4Metric": 10,
+ "numAdjacencies": 0,
+ "sharedSecretProfile": "",
+ "isisAdjacencies": [],
+ "passive": False,
+ "v4Protection": "disabled",
+ "v6Protection": "disabled",
+ }
+ },
+ "interfaceSpeed": 1000,
+ "areaProxyBoundary": False,
+ },
+ }
+ }
+ }
+ }
+ }
+ }
+ ],
+ "inputs": {
+ "interfaces": [
+ {"name": "Loopback0", "mode": "passive"},
+ {"name": "Ethernet2", "mode": "passive"},
+ {"name": "Ethernet1", "mode": "point-to-point", "vrf": "default"},
+ ]
+ },
+ "expected": {
+ "result": "failure",
+ "messages": ["Interface Ethernet2 in VRF default is not running in passive mode"],
+ },
+ },
+ {
+ "name": "failure VerifyISISInterfaceMode default vrf with interface not running point-point mode",
+ "test": VerifyISISInterfaceMode,
+ "eos_data": [
+ {
+ "vrfs": {
+ "default": {
+ "isisInstances": {
+ "CORE-ISIS": {
+ "interfaces": {
+ "Loopback0": {
+ "enabled": True,
+ "index": 2,
+ "snpa": "0:0:0:0:0:0",
+ "mtu": 65532,
+ "interfaceAddressFamily": "ipv4",
+ "interfaceType": "loopback",
+ "intfLevels": {
+ "2": {
+ "ipv4Metric": 10,
+ "sharedSecretProfile": "",
+ "isisAdjacencies": [],
+ "passive": True,
+ "v4Protection": "disabled",
+ "v6Protection": "disabled",
+ }
+ },
+ "areaProxyBoundary": False,
+ },
+ "Ethernet1": {
+ "enabled": True,
+ "index": 132,
+ "snpa": "P2P",
+ "interfaceType": "broadcast",
+ "intfLevels": {
+ "2": {
+ "ipv4Metric": 10,
+ "numAdjacencies": 1,
+ "linkId": "84",
+ "sharedSecretProfile": "",
+ "isisAdjacencies": [],
+ "passive": False,
+ "v4Protection": "link",
+ "v6Protection": "disabled",
+ }
+ },
+ "interfaceSpeed": 1000,
+ "areaProxyBoundary": False,
+ },
+ "Ethernet2": {
+ "enabled": True,
+ "interfaceType": "broadcast",
+ "intfLevels": {
+ "2": {
+ "ipv4Metric": 10,
+ "numAdjacencies": 0,
+ "sharedSecretProfile": "",
+ "isisAdjacencies": [],
+ "passive": True,
+ "v4Protection": "disabled",
+ "v6Protection": "disabled",
+ }
+ },
+ "interfaceSpeed": 1000,
+ "areaProxyBoundary": False,
+ },
+ }
+ }
+ }
+ }
+ }
+ }
+ ],
+ "inputs": {
+ "interfaces": [
+ {"name": "Loopback0", "mode": "passive"},
+ {"name": "Ethernet2", "mode": "passive"},
+ {"name": "Ethernet1", "mode": "point-to-point", "vrf": "default"},
+ ]
+ },
+ "expected": {
+ "result": "failure",
+ "messages": ["Interface Ethernet1 in VRF default is not running in point-to-point reporting broadcast"],
+ },
+ },
+ {
+ "name": "failure VerifyISISInterfaceMode default vrf with interface not running correct VRF mode",
+ "test": VerifyISISInterfaceMode,
+ "eos_data": [
+ {
+ "vrfs": {
+ "fake_vrf": {
+ "isisInstances": {
+ "CORE-ISIS": {
+ "interfaces": {
+ "Loopback0": {
+ "enabled": True,
+ "index": 2,
+ "snpa": "0:0:0:0:0:0",
+ "mtu": 65532,
+ "interfaceAddressFamily": "ipv4",
+ "interfaceType": "loopback",
+ "intfLevels": {
+ "2": {
+ "ipv4Metric": 10,
+ "sharedSecretProfile": "",
+ "isisAdjacencies": [],
+ "passive": True,
+ "v4Protection": "disabled",
+ "v6Protection": "disabled",
+ }
+ },
+ "areaProxyBoundary": False,
+ },
+ "Ethernet1": {
+ "enabled": True,
+ "index": 132,
+ "snpa": "P2P",
+ "interfaceType": "point-to-point",
+ "intfLevels": {
+ "2": {
+ "ipv4Metric": 10,
+ "numAdjacencies": 1,
+ "linkId": "84",
+ "sharedSecretProfile": "",
+ "isisAdjacencies": [],
+ "passive": False,
+ "v4Protection": "link",
+ "v6Protection": "disabled",
+ }
+ },
+ "interfaceSpeed": 1000,
+ "areaProxyBoundary": False,
+ },
+ "Ethernet2": {
+ "enabled": True,
+ "interfaceType": "broadcast",
+ "intfLevels": {
+ "2": {
+ "ipv4Metric": 10,
+ "numAdjacencies": 0,
+ "sharedSecretProfile": "",
+ "isisAdjacencies": [],
+ "passive": True,
+ "v4Protection": "disabled",
+ "v6Protection": "disabled",
+ }
+ },
+ "interfaceSpeed": 1000,
+ "areaProxyBoundary": False,
+ },
+ }
+ }
+ }
+ }
+ }
+ }
+ ],
+ "inputs": {
+ "interfaces": [
+ {"name": "Loopback0", "mode": "passive"},
+ {"name": "Ethernet2", "mode": "passive"},
+ {"name": "Ethernet1", "mode": "point-to-point", "vrf": "default"},
+ ]
+ },
+ "expected": {
+ "result": "failure",
+ "messages": [
+ "Interface Loopback0 not found in VRF default",
+ "Interface Ethernet2 not found in VRF default",
+ "Interface Ethernet1 not found in VRF default",
+ ],
+ },
+ },
+]
diff --git a/tests/units/anta_tests/routing/test_ospf.py b/tests/units/anta_tests/routing/test_ospf.py
index fbabee9..81d8010 100644
--- a/tests/units/anta_tests/routing/test_ospf.py
+++ b/tests/units/anta_tests/routing/test_ospf.py
@@ -1,14 +1,13 @@
# Copyright (c) 2023-2024 Arista Networks, Inc.
# Use of this source code is governed by the Apache License 2.0
# that can be found in the LICENSE file.
-"""
-Tests for anta.tests.routing.ospf.py
-"""
+"""Tests for anta.tests.routing.ospf.py."""
+
from __future__ import annotations
from typing import Any
-from anta.tests.routing.ospf import VerifyOSPFNeighborCount, VerifyOSPFNeighborState
+from anta.tests.routing.ospf import VerifyOSPFMaxLSA, VerifyOSPFNeighborCount, VerifyOSPFNeighborState
from tests.lib.anta import test # noqa: F401; pylint: disable=W0611
DATA: list[dict[str, Any]] = [
@@ -40,9 +39,9 @@ DATA: list[dict[str, Any]] = [
"inactivity": 1683298014.844345,
"interfaceAddress": "10.3.0.1",
},
- ]
- }
- }
+ ],
+ },
+ },
},
"BLAH": {
"instList": {
@@ -56,13 +55,13 @@ DATA: list[dict[str, Any]] = [
"adjacencyState": "full",
"inactivity": 1683298014.844345,
"interfaceAddress": "10.3.0.1",
- }
- ]
- }
- }
+ },
+ ],
+ },
+ },
},
- }
- }
+ },
+ },
],
"inputs": None,
"expected": {"result": "success"},
@@ -95,9 +94,9 @@ DATA: list[dict[str, Any]] = [
"inactivity": 1683298014.844345,
"interfaceAddress": "10.3.0.1",
},
- ]
- }
- }
+ ],
+ },
+ },
},
"BLAH": {
"instList": {
@@ -111,20 +110,20 @@ DATA: list[dict[str, Any]] = [
"adjacencyState": "down",
"inactivity": 1683298014.844345,
"interfaceAddress": "10.3.0.1",
- }
- ]
- }
- }
+ },
+ ],
+ },
+ },
},
- }
- }
+ },
+ },
],
"inputs": None,
"expected": {
"result": "failure",
"messages": [
"Some neighbors are not correctly configured: [{'vrf': 'default', 'instance': '666', 'neighbor': '7.7.7.7', 'state': '2-way'},"
- " {'vrf': 'BLAH', 'instance': '777', 'neighbor': '8.8.8.8', 'state': 'down'}]."
+ " {'vrf': 'BLAH', 'instance': '777', 'neighbor': '8.8.8.8', 'state': 'down'}].",
],
},
},
@@ -134,7 +133,7 @@ DATA: list[dict[str, Any]] = [
"eos_data": [
{
"vrfs": {},
- }
+ },
],
"inputs": None,
"expected": {"result": "skipped", "messages": ["no OSPF neighbor found"]},
@@ -167,9 +166,9 @@ DATA: list[dict[str, Any]] = [
"inactivity": 1683298014.844345,
"interfaceAddress": "10.3.0.1",
},
- ]
- }
- }
+ ],
+ },
+ },
},
"BLAH": {
"instList": {
@@ -183,13 +182,13 @@ DATA: list[dict[str, Any]] = [
"adjacencyState": "full",
"inactivity": 1683298014.844345,
"interfaceAddress": "10.3.0.1",
- }
- ]
- }
- }
+ },
+ ],
+ },
+ },
},
- }
- }
+ },
+ },
],
"inputs": {"number": 3},
"expected": {"result": "success"},
@@ -213,12 +212,12 @@ DATA: list[dict[str, Any]] = [
"inactivity": 1683298014.844345,
"interfaceAddress": "10.3.0.1",
},
- ]
- }
- }
- }
- }
- }
+ ],
+ },
+ },
+ },
+ },
+ },
],
"inputs": {"number": 3},
"expected": {"result": "failure", "messages": ["device has 1 neighbors (expected 3)"]},
@@ -251,9 +250,9 @@ DATA: list[dict[str, Any]] = [
"inactivity": 1683298014.844345,
"interfaceAddress": "10.3.0.1",
},
- ]
- }
- }
+ ],
+ },
+ },
},
"BLAH": {
"instList": {
@@ -267,20 +266,20 @@ DATA: list[dict[str, Any]] = [
"adjacencyState": "down",
"inactivity": 1683298014.844345,
"interfaceAddress": "10.3.0.1",
- }
- ]
- }
- }
+ },
+ ],
+ },
+ },
},
- }
- }
+ },
+ },
],
"inputs": {"number": 3},
"expected": {
"result": "failure",
"messages": [
"Some neighbors are not correctly configured: [{'vrf': 'default', 'instance': '666', 'neighbor': '7.7.7.7', 'state': '2-way'},"
- " {'vrf': 'BLAH', 'instance': '777', 'neighbor': '8.8.8.8', 'state': 'down'}]."
+ " {'vrf': 'BLAH', 'instance': '777', 'neighbor': '8.8.8.8', 'state': 'down'}].",
],
},
},
@@ -290,9 +289,123 @@ DATA: list[dict[str, Any]] = [
"eos_data": [
{
"vrfs": {},
- }
+ },
],
"inputs": {"number": 3},
"expected": {"result": "skipped", "messages": ["no OSPF neighbor found"]},
},
+ {
+ "name": "success",
+ "test": VerifyOSPFMaxLSA,
+ "eos_data": [
+ {
+ "vrfs": {
+ "default": {
+ "instList": {
+ "1": {
+ "instanceId": 1,
+ "maxLsaInformation": {
+ "maxLsa": 12000,
+ "maxLsaThreshold": 75,
+ },
+ "routerId": "1.1.1.1",
+ "lsaInformation": {
+ "lsaArrivalInterval": 1000,
+ "lsaStartInterval": 1000,
+ "lsaHoldInterval": 5000,
+ "lsaMaxWaitInterval": 5000,
+ "numLsa": 9,
+ },
+ },
+ },
+ },
+ "TEST": {
+ "instList": {
+ "10": {
+ "instanceId": 10,
+ "maxLsaInformation": {
+ "maxLsa": 1000,
+ "maxLsaThreshold": 75,
+ },
+ "routerId": "20.20.20.20",
+ "lsaInformation": {
+ "lsaArrivalInterval": 1000,
+ "lsaStartInterval": 1000,
+ "lsaHoldInterval": 5000,
+ "lsaMaxWaitInterval": 5000,
+ "numLsa": 5,
+ },
+ },
+ },
+ },
+ },
+ },
+ ],
+ "inputs": None,
+ "expected": {"result": "success"},
+ },
+ {
+ "name": "failure",
+ "test": VerifyOSPFMaxLSA,
+ "eos_data": [
+ {
+ "vrfs": {
+ "default": {
+ "instList": {
+ "1": {
+ "instanceId": 1,
+ "maxLsaInformation": {
+ "maxLsa": 12000,
+ "maxLsaThreshold": 75,
+ },
+ "routerId": "1.1.1.1",
+ "lsaInformation": {
+ "lsaArrivalInterval": 1000,
+ "lsaStartInterval": 1000,
+ "lsaHoldInterval": 5000,
+ "lsaMaxWaitInterval": 5000,
+ "numLsa": 11500,
+ },
+ },
+ },
+ },
+ "TEST": {
+ "instList": {
+ "10": {
+ "instanceId": 10,
+ "maxLsaInformation": {
+ "maxLsa": 1000,
+ "maxLsaThreshold": 75,
+ },
+ "routerId": "20.20.20.20",
+ "lsaInformation": {
+ "lsaArrivalInterval": 1000,
+ "lsaStartInterval": 1000,
+ "lsaHoldInterval": 5000,
+ "lsaMaxWaitInterval": 5000,
+ "numLsa": 1500,
+ },
+ },
+ },
+ },
+ },
+ },
+ ],
+ "inputs": None,
+ "expected": {
+ "result": "failure",
+ "messages": ["OSPF Instances ['1', '10'] crossed the maximum LSA threshold."],
+ },
+ },
+ {
+ "name": "skipped",
+ "test": VerifyOSPFMaxLSA,
+ "eos_data": [
+ {
+ "vrfs": {},
+ },
+ ],
+ "inputs": None,
+ "expected": {"result": "skipped", "messages": ["No OSPF instance found."]},
+ },
]
diff --git a/tests/units/anta_tests/test_aaa.py b/tests/units/anta_tests/test_aaa.py
index 2992290..40bf82e 100644
--- a/tests/units/anta_tests/test_aaa.py
+++ b/tests/units/anta_tests/test_aaa.py
@@ -1,9 +1,8 @@
# Copyright (c) 2023-2024 Arista Networks, Inc.
# Use of this source code is governed by the Apache License 2.0
# that can be found in the LICENSE file.
-"""
-Tests for anta.tests.aaa.py
-"""
+"""Tests for anta.tests.aaa.py."""
+
from __future__ import annotations
from typing import Any
@@ -28,11 +27,11 @@ DATA: list[dict[str, Any]] = [
"tacacsServers": [
{
"serverInfo": {"hostname": "10.22.10.91", "authport": 49, "vrf": "MGMT"},
- }
+ },
],
"groups": {"GROUP1": {"serverGroup": "TACACS+", "members": [{"hostname": "SERVER1", "authport": 49, "vrf": "MGMT"}]}},
"srcIntf": {"MGMT": "Management0"},
- }
+ },
],
"inputs": {"intf": "Management0", "vrf": "MGMT"},
"expected": {"result": "success"},
@@ -45,7 +44,7 @@ DATA: list[dict[str, Any]] = [
"tacacsServers": [],
"groups": {},
"srcIntf": {},
- }
+ },
],
"inputs": {"intf": "Management0", "vrf": "MGMT"},
"expected": {"result": "failure", "messages": ["Source-interface Management0 is not configured in VRF MGMT"]},
@@ -58,11 +57,11 @@ DATA: list[dict[str, Any]] = [
"tacacsServers": [
{
"serverInfo": {"hostname": "10.22.10.91", "authport": 49, "vrf": "MGMT"},
- }
+ },
],
"groups": {"GROUP1": {"serverGroup": "TACACS+", "members": [{"hostname": "SERVER1", "authport": 49, "vrf": "MGMT"}]}},
"srcIntf": {"MGMT": "Management1"},
- }
+ },
],
"inputs": {"intf": "Management0", "vrf": "MGMT"},
"expected": {"result": "failure", "messages": ["Wrong source-interface configured in VRF MGMT"]},
@@ -75,11 +74,11 @@ DATA: list[dict[str, Any]] = [
"tacacsServers": [
{
"serverInfo": {"hostname": "10.22.10.91", "authport": 49, "vrf": "MGMT"},
- }
+ },
],
"groups": {"GROUP1": {"serverGroup": "TACACS+", "members": [{"hostname": "SERVER1", "authport": 49, "vrf": "MGMT"}]}},
"srcIntf": {"PROD": "Management0"},
- }
+ },
],
"inputs": {"intf": "Management0", "vrf": "MGMT"},
"expected": {"result": "failure", "messages": ["Source-interface Management0 is not configured in VRF MGMT"]},
@@ -92,11 +91,11 @@ DATA: list[dict[str, Any]] = [
"tacacsServers": [
{
"serverInfo": {"hostname": "10.22.10.91", "authport": 49, "vrf": "MGMT"},
- }
+ },
],
"groups": {"GROUP1": {"serverGroup": "TACACS+", "members": [{"hostname": "SERVER1", "authport": 49, "vrf": "MGMT"}]}},
"srcIntf": {"MGMT": "Management0"},
- }
+ },
],
"inputs": {"servers": ["10.22.10.91"], "vrf": "MGMT"},
"expected": {"result": "success"},
@@ -109,7 +108,7 @@ DATA: list[dict[str, Any]] = [
"tacacsServers": [],
"groups": {},
"srcIntf": {},
- }
+ },
],
"inputs": {"servers": ["10.22.10.91"], "vrf": "MGMT"},
"expected": {"result": "failure", "messages": ["No TACACS servers are configured"]},
@@ -122,11 +121,11 @@ DATA: list[dict[str, Any]] = [
"tacacsServers": [
{
"serverInfo": {"hostname": "10.22.10.91", "authport": 49, "vrf": "MGMT"},
- }
+ },
],
"groups": {"GROUP1": {"serverGroup": "TACACS+", "members": [{"hostname": "SERVER1", "authport": 49, "vrf": "MGMT"}]}},
"srcIntf": {"MGMT": "Management0"},
- }
+ },
],
"inputs": {"servers": ["10.22.10.91", "10.22.10.92"], "vrf": "MGMT"},
"expected": {"result": "failure", "messages": ["TACACS servers ['10.22.10.92'] are not configured in VRF MGMT"]},
@@ -139,11 +138,11 @@ DATA: list[dict[str, Any]] = [
"tacacsServers": [
{
"serverInfo": {"hostname": "10.22.10.91", "authport": 49, "vrf": "PROD"},
- }
+ },
],
"groups": {"GROUP1": {"serverGroup": "TACACS+", "members": [{"hostname": "SERVER1", "authport": 49, "vrf": "MGMT"}]}},
"srcIntf": {"MGMT": "Management0"},
- }
+ },
],
"inputs": {"servers": ["10.22.10.91"], "vrf": "MGMT"},
"expected": {"result": "failure", "messages": ["TACACS servers ['10.22.10.91'] are not configured in VRF MGMT"]},
@@ -156,11 +155,11 @@ DATA: list[dict[str, Any]] = [
"tacacsServers": [
{
"serverInfo": {"hostname": "10.22.10.91", "authport": 49, "vrf": "MGMT"},
- }
+ },
],
"groups": {"GROUP1": {"serverGroup": "TACACS+", "members": [{"hostname": "SERVER1", "authport": 49, "vrf": "MGMT"}]}},
"srcIntf": {"MGMT": "Management0"},
- }
+ },
],
"inputs": {"groups": ["GROUP1"]},
"expected": {"result": "success"},
@@ -173,7 +172,7 @@ DATA: list[dict[str, Any]] = [
"tacacsServers": [],
"groups": {},
"srcIntf": {},
- }
+ },
],
"inputs": {"groups": ["GROUP1"]},
"expected": {"result": "failure", "messages": ["No TACACS server group(s) are configured"]},
@@ -186,11 +185,11 @@ DATA: list[dict[str, Any]] = [
"tacacsServers": [
{
"serverInfo": {"hostname": "10.22.10.91", "authport": 49, "vrf": "MGMT"},
- }
+ },
],
"groups": {"GROUP2": {"serverGroup": "TACACS+", "members": [{"hostname": "SERVER1", "authport": 49, "vrf": "MGMT"}]}},
"srcIntf": {"MGMT": "Management0"},
- }
+ },
],
"inputs": {"groups": ["GROUP1"]},
"expected": {"result": "failure", "messages": ["TACACS server group(s) ['GROUP1'] are not configured"]},
@@ -203,7 +202,7 @@ DATA: list[dict[str, Any]] = [
"loginAuthenMethods": {"default": {"methods": ["group tacacs+", "local"]}, "login": {"methods": ["group tacacs+", "local"]}},
"enableAuthenMethods": {"default": {"methods": ["group tacacs+", "local"]}},
"dot1xAuthenMethods": {"default": {"methods": ["group radius"]}},
- }
+ },
],
"inputs": {"methods": ["tacacs+", "local"], "types": ["login", "enable"]},
"expected": {"result": "success"},
@@ -216,7 +215,7 @@ DATA: list[dict[str, Any]] = [
"loginAuthenMethods": {"default": {"methods": ["group tacacs+", "local"]}, "login": {"methods": ["group tacacs+", "local"]}},
"enableAuthenMethods": {"default": {"methods": ["group tacacs+", "local"]}},
"dot1xAuthenMethods": {"default": {"methods": ["group radius"]}},
- }
+ },
],
"inputs": {"methods": ["radius"], "types": ["dot1x"]},
"expected": {"result": "success"},
@@ -229,7 +228,7 @@ DATA: list[dict[str, Any]] = [
"loginAuthenMethods": {"default": {"methods": ["group tacacs+", "local"]}},
"enableAuthenMethods": {"default": {"methods": ["group tacacs+", "local"]}},
"dot1xAuthenMethods": {"default": {"methods": ["group radius"]}},
- }
+ },
],
"inputs": {"methods": ["tacacs+", "local"], "types": ["login", "enable"]},
"expected": {"result": "failure", "messages": ["AAA authentication methods are not configured for login console"]},
@@ -242,7 +241,7 @@ DATA: list[dict[str, Any]] = [
"loginAuthenMethods": {"default": {"methods": ["group tacacs+", "local"]}, "login": {"methods": ["group radius", "local"]}},
"enableAuthenMethods": {"default": {"methods": ["group tacacs+", "local"]}},
"dot1xAuthenMethods": {"default": {"methods": ["group radius"]}},
- }
+ },
],
"inputs": {"methods": ["tacacs+", "local"], "types": ["login", "enable"]},
"expected": {"result": "failure", "messages": ["AAA authentication methods ['group tacacs+', 'local'] are not matching for login console"]},
@@ -255,7 +254,7 @@ DATA: list[dict[str, Any]] = [
"loginAuthenMethods": {"default": {"methods": ["group radius", "local"]}, "login": {"methods": ["group tacacs+", "local"]}},
"enableAuthenMethods": {"default": {"methods": ["group tacacs+", "local"]}},
"dot1xAuthenMethods": {"default": {"methods": ["group radius"]}},
- }
+ },
],
"inputs": {"methods": ["tacacs+", "local"], "types": ["login", "enable"]},
"expected": {"result": "failure", "messages": ["AAA authentication methods ['group tacacs+', 'local'] are not matching for ['login']"]},
@@ -267,19 +266,31 @@ DATA: list[dict[str, Any]] = [
{
"commandsAuthzMethods": {"privilege0-15": {"methods": ["group tacacs+", "local"]}},
"execAuthzMethods": {"exec": {"methods": ["group tacacs+", "local"]}},
- }
+ },
],
"inputs": {"methods": ["tacacs+", "local"], "types": ["commands", "exec"]},
"expected": {"result": "success"},
},
{
+ "name": "success-skipping-exec",
+ "test": VerifyAuthzMethods,
+ "eos_data": [
+ {
+ "commandsAuthzMethods": {"privilege0-15": {"methods": ["group tacacs+", "local"]}},
+ "execAuthzMethods": {"exec": {"methods": ["group tacacs+", "local"]}},
+ },
+ ],
+ "inputs": {"methods": ["tacacs+", "local"], "types": ["commands"]},
+ "expected": {"result": "success"},
+ },
+ {
"name": "failure-commands",
"test": VerifyAuthzMethods,
"eos_data": [
{
"commandsAuthzMethods": {"privilege0-15": {"methods": ["group radius", "local"]}},
"execAuthzMethods": {"exec": {"methods": ["group tacacs+", "local"]}},
- }
+ },
],
"inputs": {"methods": ["tacacs+", "local"], "types": ["commands", "exec"]},
"expected": {"result": "failure", "messages": ["AAA authorization methods ['group tacacs+', 'local'] are not matching for ['commands']"]},
@@ -291,7 +302,7 @@ DATA: list[dict[str, Any]] = [
{
"commandsAuthzMethods": {"privilege0-15": {"methods": ["group tacacs+", "local"]}},
"execAuthzMethods": {"exec": {"methods": ["group radius", "local"]}},
- }
+ },
],
"inputs": {"methods": ["tacacs+", "local"], "types": ["commands", "exec"]},
"expected": {"result": "failure", "messages": ["AAA authorization methods ['group tacacs+', 'local'] are not matching for ['exec']"]},
@@ -305,7 +316,7 @@ DATA: list[dict[str, Any]] = [
"execAcctMethods": {"exec": {"defaultAction": "startStop", "defaultMethods": ["group tacacs+", "logging"], "consoleMethods": []}},
"systemAcctMethods": {"system": {"defaultAction": "startStop", "defaultMethods": ["group tacacs+", "logging"], "consoleMethods": []}},
"dot1xAcctMethods": {"dot1x": {"defaultMethods": [], "consoleMethods": []}},
- }
+ },
],
"inputs": {"methods": ["tacacs+", "logging"], "types": ["commands", "exec", "system"]},
"expected": {"result": "success"},
@@ -319,7 +330,7 @@ DATA: list[dict[str, Any]] = [
"execAcctMethods": {"exec": {"defaultAction": "startStop", "defaultMethods": ["group tacacs+", "logging"], "consoleMethods": []}},
"systemAcctMethods": {"system": {"defaultAction": "startStop", "defaultMethods": ["group tacacs+", "logging"], "consoleMethods": []}},
"dot1xAcctMethods": {"dot1x": {"defaultAction": "startStop", "defaultMethods": ["group radius", "logging"], "consoleMethods": []}},
- }
+ },
],
"inputs": {"methods": ["radius", "logging"], "types": ["dot1x"]},
"expected": {"result": "success"},
@@ -333,7 +344,7 @@ DATA: list[dict[str, Any]] = [
"execAcctMethods": {"exec": {"defaultAction": "startStop", "defaultMethods": ["group tacacs+", "logging"], "consoleMethods": []}},
"systemAcctMethods": {"system": {"defaultAction": "startStop", "defaultMethods": ["group tacacs+", "logging"], "consoleMethods": []}},
"dot1xAcctMethods": {"dot1x": {"defaultMethods": [], "consoleMethods": []}},
- }
+ },
],
"inputs": {"methods": ["tacacs+", "logging"], "types": ["commands", "exec", "system"]},
"expected": {"result": "failure", "messages": ["AAA default accounting is not configured for ['commands']"]},
@@ -347,7 +358,7 @@ DATA: list[dict[str, Any]] = [
"execAcctMethods": {"exec": {"defaultMethods": [], "consoleMethods": []}},
"commandsAcctMethods": {"privilege0-15": {"defaultMethods": [], "consoleMethods": []}},
"dot1xAcctMethods": {"dot1x": {"defaultMethods": [], "consoleMethods": []}},
- }
+ },
],
"inputs": {"methods": ["tacacs+", "logging"], "types": ["commands", "exec", "system"]},
"expected": {"result": "failure", "messages": ["AAA default accounting is not configured for ['system', 'exec', 'commands']"]},
@@ -361,7 +372,7 @@ DATA: list[dict[str, Any]] = [
"execAcctMethods": {"exec": {"defaultAction": "startStop", "defaultMethods": ["group tacacs+", "logging"], "consoleMethods": []}},
"systemAcctMethods": {"system": {"defaultAction": "startStop", "defaultMethods": ["group tacacs+", "logging"], "consoleMethods": []}},
"dot1xAcctMethods": {"dot1x": {"defaultMethods": [], "consoleMethods": []}},
- }
+ },
],
"inputs": {"methods": ["tacacs+", "logging"], "types": ["commands", "exec", "system"]},
"expected": {"result": "failure", "messages": ["AAA accounting default methods ['group tacacs+', 'logging'] are not matching for ['commands']"]},
@@ -376,24 +387,24 @@ DATA: list[dict[str, Any]] = [
"defaultMethods": [],
"consoleAction": "startStop",
"consoleMethods": ["group tacacs+", "logging"],
- }
+ },
},
"execAcctMethods": {
"exec": {
"defaultMethods": [],
"consoleAction": "startStop",
"consoleMethods": ["group tacacs+", "logging"],
- }
+ },
},
"systemAcctMethods": {
"system": {
"defaultMethods": [],
"consoleAction": "startStop",
"consoleMethods": ["group tacacs+", "logging"],
- }
+ },
},
"dot1xAcctMethods": {"dot1x": {"defaultMethods": [], "consoleMethods": []}},
- }
+ },
],
"inputs": {"methods": ["tacacs+", "logging"], "types": ["commands", "exec", "system"]},
"expected": {"result": "success"},
@@ -408,30 +419,30 @@ DATA: list[dict[str, Any]] = [
"defaultMethods": [],
"consoleAction": "startStop",
"consoleMethods": ["group tacacs+", "logging"],
- }
+ },
},
"execAcctMethods": {
"exec": {
"defaultMethods": [],
"consoleAction": "startStop",
"consoleMethods": ["group tacacs+", "logging"],
- }
+ },
},
"systemAcctMethods": {
"system": {
"defaultMethods": [],
"consoleAction": "startStop",
"consoleMethods": ["group tacacs+", "logging"],
- }
+ },
},
"dot1xAcctMethods": {
"dot1x": {
"defaultMethods": [],
"consoleAction": "startStop",
"consoleMethods": ["group tacacs+", "logging"],
- }
+ },
},
- }
+ },
],
"inputs": {"methods": ["tacacs+", "logging"], "types": ["dot1x"]},
"expected": {"result": "success"},
@@ -445,24 +456,24 @@ DATA: list[dict[str, Any]] = [
"privilege0-15": {
"defaultMethods": [],
"consoleMethods": [],
- }
+ },
},
"execAcctMethods": {
"exec": {
"defaultMethods": [],
"consoleAction": "startStop",
"consoleMethods": ["group tacacs+", "logging"],
- }
+ },
},
"systemAcctMethods": {
"system": {
"defaultMethods": [],
"consoleAction": "startStop",
"consoleMethods": ["group tacacs+", "logging"],
- }
+ },
},
"dot1xAcctMethods": {"dot1x": {"defaultMethods": [], "consoleMethods": []}},
- }
+ },
],
"inputs": {"methods": ["tacacs+", "logging"], "types": ["commands", "exec", "system"]},
"expected": {"result": "failure", "messages": ["AAA console accounting is not configured for ['commands']"]},
@@ -476,7 +487,7 @@ DATA: list[dict[str, Any]] = [
"execAcctMethods": {"exec": {"defaultMethods": [], "consoleMethods": []}},
"commandsAcctMethods": {"privilege0-15": {"defaultMethods": [], "consoleMethods": []}},
"dot1xAcctMethods": {"dot1x": {"defaultMethods": [], "consoleMethods": []}},
- }
+ },
],
"inputs": {"methods": ["tacacs+", "logging"], "types": ["commands", "exec", "system"]},
"expected": {"result": "failure", "messages": ["AAA console accounting is not configured for ['system', 'exec', 'commands']"]},
@@ -491,24 +502,24 @@ DATA: list[dict[str, Any]] = [
"defaultMethods": [],
"consoleAction": "startStop",
"consoleMethods": ["group radius", "logging"],
- }
+ },
},
"execAcctMethods": {
"exec": {
"defaultMethods": [],
"consoleAction": "startStop",
"consoleMethods": ["group tacacs+", "logging"],
- }
+ },
},
"systemAcctMethods": {
"system": {
"defaultMethods": [],
"consoleAction": "startStop",
"consoleMethods": ["group tacacs+", "logging"],
- }
+ },
},
"dot1xAcctMethods": {"dot1x": {"defaultMethods": [], "consoleMethods": []}},
- }
+ },
],
"inputs": {"methods": ["tacacs+", "logging"], "types": ["commands", "exec", "system"]},
"expected": {"result": "failure", "messages": ["AAA accounting console methods ['group tacacs+', 'logging'] are not matching for ['commands']"]},
diff --git a/tests/units/anta_tests/test_avt.py b/tests/units/anta_tests/test_avt.py
new file mode 100644
index 0000000..7ef6be3
--- /dev/null
+++ b/tests/units/anta_tests/test_avt.py
@@ -0,0 +1,581 @@
+# Copyright (c) 2023-2024 Arista Networks, Inc.
+# Use of this source code is governed by the Apache License 2.0
+# that can be found in the LICENSE file.
+"""Tests for anta.tests.avt.py."""
+
+from __future__ import annotations
+
+from typing import Any
+
+from anta.tests.avt import VerifyAVTPathHealth, VerifyAVTRole, VerifyAVTSpecificPath
+from tests.lib.anta import test # noqa: F401; pylint: disable=unused-import
+
+DATA: list[dict[str, Any]] = [
+ {
+ "name": "success",
+ "test": VerifyAVTPathHealth,
+ "eos_data": [
+ {
+ "vrfs": {
+ "data": {
+ "avts": {
+ "DATA-AVT-POLICY-DEFAULT": {
+ "avtPaths": {
+ "direct:9": {
+ "flags": {"directPath": True, "valid": True, "active": True},
+ },
+ "direct:10": {
+ "flags": {"directPath": True, "valid": True, "active": True},
+ },
+ "direct:1": {
+ "flags": {"directPath": True, "valid": True, "active": True},
+ },
+ "direct:8": {
+ "flags": {"directPath": True, "valid": True, "active": True},
+ },
+ }
+ }
+ }
+ },
+ "guest": {
+ "avts": {
+ "GUEST-AVT-POLICY-DEFAULT": {
+ "avtPaths": {
+ "direct:10": {
+ "flags": {"directPath": True, "valid": True, "active": True},
+ },
+ "direct:8": {
+ "flags": {"directPath": True, "valid": True, "active": True},
+ },
+ }
+ }
+ }
+ },
+ "default": {
+ "avts": {
+ "CONTROL-PLANE-PROFILE": {
+ "avtPaths": {
+ "direct:9": {
+ "flags": {"directPath": True, "valid": True, "active": True},
+ },
+ "direct:10": {
+ "flags": {"directPath": True, "valid": True, "active": True},
+ },
+ "direct:1": {
+ "flags": {"directPath": True, "valid": True, "active": True},
+ },
+ "direct:8": {
+ "flags": {"directPath": True, "valid": True, "active": True},
+ },
+ }
+ },
+ "DEFAULT-AVT-POLICY-DEFAULT": {
+ "avtPaths": {
+ "direct:10": {
+ "flags": {"directPath": True, "valid": True, "active": True},
+ },
+ "direct:8": {
+ "flags": {"directPath": True, "valid": True, "active": True},
+ },
+ }
+ },
+ }
+ },
+ }
+ }
+ ],
+ "inputs": {},
+ "expected": {"result": "success"},
+ },
+ {
+ "name": "failure-avt-not-configured",
+ "test": VerifyAVTPathHealth,
+ "eos_data": [{"vrfs": {}}],
+ "inputs": {},
+ "expected": {
+ "result": "failure",
+ "messages": ["Adaptive virtual topology paths are not configured."],
+ },
+ },
+ {
+ "name": "failure-not-active-path",
+ "test": VerifyAVTPathHealth,
+ "eos_data": [
+ {
+ "vrfs": {
+ "data": {
+ "avts": {
+ "DATA-AVT-POLICY-DEFAULT": {
+ "avtPaths": {
+ "direct:9": {
+ "flags": {"directPath": True, "valid": True, "active": True},
+ },
+ "direct:10": {
+ "flags": {"directPath": True, "valid": True, "active": True},
+ },
+ "direct:1": {
+ "flags": {"directPath": True, "valid": True, "active": True},
+ },
+ "direct:8": {
+ "flags": {"directPath": True, "valid": True, "active": True},
+ },
+ }
+ }
+ }
+ },
+ "guest": {
+ "avts": {
+ "GUEST-AVT-POLICY-DEFAULT": {
+ "avtPaths": {
+ "direct:10": {
+ "flags": {"directPath": True, "valid": True, "active": False},
+ },
+ "direct:8": {
+ "flags": {"directPath": True, "valid": True, "active": True},
+ },
+ }
+ }
+ }
+ },
+ "default": {
+ "avts": {
+ "CONTROL-PLANE-PROFILE": {
+ "avtPaths": {
+ "direct:9": {
+ "flags": {"directPath": True, "valid": True, "active": True},
+ },
+ "direct:10": {
+ "flags": {"directPath": True, "valid": True, "active": True},
+ },
+ "direct:1": {
+ "flags": {"directPath": True, "valid": True, "active": False},
+ },
+ "direct:8": {
+ "flags": {"directPath": True, "valid": True, "active": True},
+ },
+ }
+ },
+ "DEFAULT-AVT-POLICY-DEFAULT": {
+ "avtPaths": {
+ "direct:10": {
+ "flags": {"directPath": True, "valid": True, "active": False},
+ },
+ "direct:8": {
+ "flags": {"directPath": True, "valid": True, "active": True},
+ },
+ }
+ },
+ }
+ },
+ }
+ }
+ ],
+ "inputs": {},
+ "expected": {
+ "result": "failure",
+ "messages": [
+ "AVT path direct:10 for profile GUEST-AVT-POLICY-DEFAULT in VRF guest is not active.",
+ "AVT path direct:1 for profile CONTROL-PLANE-PROFILE in VRF default is not active.",
+ "AVT path direct:10 for profile DEFAULT-AVT-POLICY-DEFAULT in VRF default is not active.",
+ ],
+ },
+ },
+ {
+ "name": "failure-invalid-path",
+ "test": VerifyAVTPathHealth,
+ "eos_data": [
+ {
+ "vrfs": {
+ "data": {
+ "avts": {
+ "DATA-AVT-POLICY-DEFAULT": {
+ "avtPaths": {
+ "direct:9": {
+ "flags": {"directPath": True, "valid": True, "active": True},
+ },
+ "direct:10": {
+ "flags": {"directPath": True, "valid": False, "active": True},
+ },
+ "direct:1": {
+ "flags": {"directPath": True, "valid": True, "active": True},
+ },
+ "direct:8": {
+ "flags": {"directPath": True, "valid": True, "active": True},
+ },
+ }
+ }
+ }
+ },
+ "guest": {
+ "avts": {
+ "GUEST-AVT-POLICY-DEFAULT": {
+ "avtPaths": {
+ "direct:10": {
+ "flags": {"directPath": True, "valid": True, "active": True},
+ },
+ "direct:8": {
+ "flags": {"directPath": True, "valid": False, "active": True},
+ },
+ }
+ }
+ }
+ },
+ "default": {
+ "avts": {
+ "CONTROL-PLANE-PROFILE": {
+ "avtPaths": {
+ "direct:9": {
+ "flags": {"directPath": True, "valid": True, "active": True},
+ },
+ "direct:10": {
+ "flags": {"directPath": True, "valid": False, "active": True},
+ },
+ "direct:1": {
+ "flags": {"directPath": True, "valid": True, "active": True},
+ },
+ "direct:8": {
+ "flags": {"directPath": True, "valid": True, "active": True},
+ },
+ }
+ },
+ "DEFAULT-AVT-POLICY-DEFAULT": {
+ "avtPaths": {
+ "direct:10": {
+ "flags": {"directPath": True, "valid": True, "active": True},
+ },
+ "direct:8": {
+ "flags": {"directPath": True, "valid": False, "active": True},
+ },
+ }
+ },
+ }
+ },
+ }
+ }
+ ],
+ "inputs": {},
+ "expected": {
+ "result": "failure",
+ "messages": [
+ "AVT path direct:10 for profile DATA-AVT-POLICY-DEFAULT in VRF data is invalid.",
+ "AVT path direct:8 for profile GUEST-AVT-POLICY-DEFAULT in VRF guest is invalid.",
+ "AVT path direct:10 for profile CONTROL-PLANE-PROFILE in VRF default is invalid.",
+ "AVT path direct:8 for profile DEFAULT-AVT-POLICY-DEFAULT in VRF default is invalid.",
+ ],
+ },
+ },
+ {
+ "name": "failure-not-active-and-invalid",
+ "test": VerifyAVTPathHealth,
+ "eos_data": [
+ {
+ "vrfs": {
+ "data": {
+ "avts": {
+ "DATA-AVT-POLICY-DEFAULT": {
+ "avtPaths": {
+ "direct:9": {
+ "flags": {"directPath": True, "valid": True, "active": True},
+ },
+ "direct:10": {
+ "flags": {"directPath": True, "valid": False, "active": False},
+ },
+ "direct:1": {
+ "flags": {"directPath": True, "valid": True, "active": False},
+ },
+ "direct:8": {
+ "flags": {"directPath": True, "valid": True, "active": True},
+ },
+ }
+ }
+ }
+ },
+ "guest": {
+ "avts": {
+ "GUEST-AVT-POLICY-DEFAULT": {
+ "avtPaths": {
+ "direct:10": {
+ "flags": {"directPath": True, "valid": False, "active": True},
+ },
+ "direct:8": {
+ "flags": {"directPath": True, "valid": False, "active": False},
+ },
+ }
+ }
+ }
+ },
+ "default": {
+ "avts": {
+ "CONTROL-PLANE-PROFILE": {
+ "avtPaths": {
+ "direct:9": {
+ "flags": {"directPath": True, "valid": True, "active": True},
+ },
+ "direct:10": {
+ "flags": {"directPath": True, "valid": False, "active": False},
+ },
+ "direct:1": {
+ "flags": {"directPath": True, "valid": True, "active": True},
+ },
+ "direct:8": {
+ "flags": {"directPath": True, "valid": True, "active": True},
+ },
+ }
+ },
+ "DEFAULT-AVT-POLICY-DEFAULT": {
+ "avtPaths": {
+ "direct:10": {
+ "flags": {"directPath": True, "valid": True, "active": False},
+ },
+ "direct:8": {
+ "flags": {"directPath": True, "valid": False, "active": False},
+ },
+ }
+ },
+ }
+ },
+ }
+ }
+ ],
+ "inputs": {},
+ "expected": {
+ "result": "failure",
+ "messages": [
+ "AVT path direct:10 for profile DATA-AVT-POLICY-DEFAULT in VRF data is invalid and not active.",
+ "AVT path direct:1 for profile DATA-AVT-POLICY-DEFAULT in VRF data is not active.",
+ "AVT path direct:10 for profile GUEST-AVT-POLICY-DEFAULT in VRF guest is invalid.",
+ "AVT path direct:8 for profile GUEST-AVT-POLICY-DEFAULT in VRF guest is invalid and not active.",
+ "AVT path direct:10 for profile CONTROL-PLANE-PROFILE in VRF default is invalid and not active.",
+ "AVT path direct:10 for profile DEFAULT-AVT-POLICY-DEFAULT in VRF default is not active.",
+ "AVT path direct:8 for profile DEFAULT-AVT-POLICY-DEFAULT in VRF default is invalid and not active.",
+ ],
+ },
+ },
+ {
+ "name": "success",
+ "test": VerifyAVTSpecificPath,
+ "eos_data": [
+ {
+ "vrfs": {
+ "default": {
+ "avts": {
+ "DEFAULT-AVT-POLICY-CONTROL-PLANE": {
+ "avtPaths": {
+ "direct:10": {"flags": {"directPath": True, "valid": True, "active": True}, "nexthopAddr": "10.101.255.1"},
+ "direct:9": {"flags": {"directPath": True, "valid": True, "active": True}, "nexthopAddr": "10.101.255.1"},
+ "multihop:1": {"flags": {"directPath": False, "valid": True, "active": True}, "nexthopAddr": "10.101.255.1"},
+ "multihop:3": {"flags": {"directPath": False, "valid": True, "active": True}, "nexthopAddr": "10.101.255.1"},
+ }
+ }
+ }
+ }
+ }
+ },
+ {
+ "vrfs": {
+ "data": {
+ "avts": {
+ "DATA-AVT-POLICY-CONTROL-PLANE": {
+ "avtPaths": {
+ "direct:10": {"flags": {"directPath": True, "valid": True, "active": True}, "nexthopAddr": "10.101.255.1"},
+ "direct:9": {"flags": {"directPath": True, "valid": True, "active": True}, "nexthopAddr": "10.101.255.1"},
+ "direct:8": {"flags": {"directPath": True, "valid": True, "active": True}, "nexthopAddr": "10.101.255.2"},
+ "multihop:1": {"flags": {"directPath": False, "valid": True, "active": True}, "nexthopAddr": "10.101.255.2"},
+ "multihop:3": {"flags": {"directPath": False, "valid": True, "active": True}, "nexthopAddr": "10.101.255.2"},
+ }
+ }
+ }
+ }
+ }
+ },
+ {
+ "vrfs": {
+ "data": {
+ "avts": {
+ "DATA-AVT-POLICY-CONTROL-PLANE": {
+ "avtPaths": {
+ "direct:10": {"flags": {"directPath": True, "valid": True, "active": True}, "nexthopAddr": "10.101.255.1"},
+ "direct:9": {"flags": {"directPath": True, "valid": True, "active": True}, "nexthopAddr": "10.101.255.1"},
+ "direct:8": {"flags": {"directPath": True, "valid": True, "active": True}, "nexthopAddr": "10.101.255.2"},
+ "multihop:1": {"flags": {"directPath": False, "valid": True, "active": True}, "nexthopAddr": "10.101.255.2"},
+ "multihop:3": {"flags": {"directPath": False, "valid": True, "active": True}, "nexthopAddr": "10.101.255.2"},
+ }
+ }
+ }
+ }
+ }
+ },
+ ],
+ "inputs": {
+ "avt_paths": [
+ {"avt_name": "DEFAULT-AVT-POLICY-CONTROL-PLANE", "destination": "10.101.255.2", "next_hop": "10.101.255.1", "path_type": "multihop"},
+ {"avt_name": "DATA-AVT-POLICY-CONTROL-PLANE", "vrf": "data", "destination": "10.101.255.1", "next_hop": "10.101.255.2", "path_type": "direct"},
+ {"avt_name": "DATA-AVT-POLICY-CONTROL-PLANE", "vrf": "data", "destination": "10.101.255.1", "next_hop": "10.101.255.2"},
+ ]
+ },
+ "expected": {"result": "success"},
+ },
+ {
+ "name": "failure-no-peer",
+ "test": VerifyAVTSpecificPath,
+ "eos_data": [
+ {"vrfs": {}},
+ {
+ "vrfs": {
+ "data": {
+ "avts": {
+ "DATA-AVT-POLICY-CONTROL-PLANE": {
+ "avtPaths": {
+ "direct:10": {"flags": {"directPath": True, "valid": True, "active": True}, "nexthopAddr": "10.101.255.1"},
+ "direct:9": {"flags": {"directPath": True, "valid": True, "active": True}, "nexthopAddr": "10.101.255.1"},
+ "multihop:1": {"flags": {"directPath": False, "valid": True, "active": True}, "nexthopAddr": "10.101.255.2"},
+ "multihop:3": {"flags": {"directPath": False, "valid": True, "active": True}, "nexthopAddr": "10.101.255.2"},
+ }
+ }
+ }
+ }
+ }
+ },
+ ],
+ "inputs": {
+ "avt_paths": [
+ {"avt_name": "MGMT-AVT-POLICY-DEFAULT", "vrf": "default", "destination": "10.101.255.2", "next_hop": "10.101.255.1", "path_type": "multihop"},
+ {"avt_name": "DATA-AVT-POLICY-CONTROL-PLANE", "vrf": "data", "destination": "10.101.255.1", "next_hop": "10.101.255.2", "path_type": "multihop"},
+ ]
+ },
+ "expected": {
+ "result": "failure",
+ "messages": ["AVT configuration for peer '10.101.255.2' under topology 'MGMT-AVT-POLICY-DEFAULT' in VRF 'default' is not found."],
+ },
+ },
+ {
+ "name": "failure-no-path-with-correct-next-hop",
+ "test": VerifyAVTSpecificPath,
+ "eos_data": [
+ {
+ "vrfs": {
+ "default": {
+ "avts": {
+ "DEFAULT-AVT-POLICY-CONTROL-PLANE": {
+ "avtPaths": {
+ "direct:10": {"flags": {"directPath": True, "valid": True, "active": True}, "nexthopAddr": "10.101.255.2"},
+ "direct:9": {"flags": {"directPath": True, "valid": True, "active": True}, "nexthopAddr": "10.101.255.2"},
+ "multihop:1": {"flags": {"directPath": False, "valid": True, "active": True}, "nexthopAddr": "10.101.255.1"},
+ "multihop:3": {"flags": {"directPath": False, "valid": True, "active": True}, "nexthopAddr": "10.101.255.1"},
+ }
+ }
+ }
+ }
+ }
+ },
+ {
+ "vrfs": {
+ "data": {
+ "avts": {
+ "DATA-AVT-POLICY-CONTROL-PLANE": {
+ "avtPaths": {
+ "direct:10": {"flags": {"directPath": True, "valid": True, "active": True}, "nexthopAddr": "10.101.255.1"},
+ "direct:9": {"flags": {"directPath": True, "valid": True, "active": True}, "nexthopAddr": "10.101.255.1"},
+ "multihop:1": {"flags": {"directPath": False, "valid": True, "active": True}, "nexthopAddr": "10.101.255.2"},
+ "multihop:3": {"flags": {"directPath": False, "valid": True, "active": True}, "nexthopAddr": "10.101.255.2"},
+ }
+ }
+ }
+ }
+ }
+ },
+ ],
+ "inputs": {
+ "avt_paths": [
+ {
+ "avt_name": "DEFAULT-AVT-POLICY-CONTROL-PLANE",
+ "vrf": "default",
+ "destination": "10.101.255.2",
+ "next_hop": "10.101.255.11",
+ "path_type": "multihop",
+ },
+ {"avt_name": "DATA-AVT-POLICY-CONTROL-PLANE", "vrf": "data", "destination": "10.101.255.1", "next_hop": "10.101.255.21", "path_type": "direct"},
+ ]
+ },
+ "expected": {
+ "result": "failure",
+ "messages": [
+ "No 'multihop' path found with next-hop address '10.101.255.11' for AVT peer '10.101.255.2' under "
+ "topology 'DEFAULT-AVT-POLICY-CONTROL-PLANE' in VRF 'default'.",
+ "No 'direct' path found with next-hop address '10.101.255.21' for AVT peer '10.101.255.1' under "
+ "topology 'DATA-AVT-POLICY-CONTROL-PLANE' in VRF 'data'.",
+ ],
+ },
+ },
+ {
+ "name": "failure-incorrect-path",
+ "test": VerifyAVTSpecificPath,
+ "eos_data": [
+ {
+ "vrfs": {
+ "default": {
+ "avts": {
+ "DEFAULT-AVT-POLICY-CONTROL-PLANE": {
+ "avtPaths": {
+ "direct:10": {"flags": {"directPath": True, "valid": True, "active": True}, "nexthopAddr": "10.101.255.2"},
+ "direct:9": {"flags": {"directPath": True, "valid": True, "active": True}, "nexthopAddr": "10.101.255.2"},
+ "multihop:1": {"flags": {"directPath": True, "valid": False, "active": False}, "nexthopAddr": "10.101.255.1"},
+ "multihop:3": {"flags": {"directPath": False, "valid": True, "active": False}, "nexthopAddr": "10.101.255.1"},
+ }
+ }
+ }
+ }
+ }
+ },
+ {
+ "vrfs": {
+ "data": {
+ "avts": {
+ "DATA-AVT-POLICY-CONTROL-PLANE": {
+ "avtPaths": {
+ "direct:10": {"flags": {"directPath": True, "valid": True, "active": True}, "nexthopAddr": "10.101.255.1"},
+ "direct:9": {"flags": {"directPath": True, "valid": False, "active": True}, "nexthopAddr": "10.101.255.1"},
+ "multihop:1": {"flags": {"directPath": False, "valid": True, "active": True}, "nexthopAddr": "10.101.255.2"},
+ "multihop:3": {"flags": {"directPath": False, "valid": True, "active": True}, "nexthopAddr": "10.101.255.2"},
+ }
+ }
+ }
+ }
+ }
+ },
+ ],
+ "inputs": {
+ "avt_paths": [
+ {
+ "avt_name": "DEFAULT-AVT-POLICY-CONTROL-PLANE",
+ "vrf": "default",
+ "destination": "10.101.255.2",
+ "next_hop": "10.101.255.1",
+ "path_type": "multihop",
+ },
+ {"avt_name": "DATA-AVT-POLICY-CONTROL-PLANE", "vrf": "data", "destination": "10.101.255.1", "next_hop": "10.101.255.1", "path_type": "direct"},
+ ]
+ },
+ "expected": {
+ "result": "failure",
+ "messages": [
+ "AVT path 'multihop:3' for topology 'DEFAULT-AVT-POLICY-CONTROL-PLANE' in VRF 'default' is inactive.",
+ "AVT path 'direct:9' for topology 'DATA-AVT-POLICY-CONTROL-PLANE' in VRF 'data' is invalid.",
+ ],
+ },
+ },
+ {
+ "name": "success",
+ "test": VerifyAVTRole,
+ "eos_data": [{"role": "edge"}],
+ "inputs": {"role": "edge"},
+ "expected": {"result": "success"},
+ },
+ {
+ "name": "failure-incorrect-role",
+ "test": VerifyAVTRole,
+ "eos_data": [{"role": "transit"}],
+ "inputs": {"role": "edge"},
+ "expected": {"result": "failure", "messages": ["Expected AVT role as `edge`, but found `transit` instead."]},
+ },
+]
diff --git a/tests/units/anta_tests/test_bfd.py b/tests/units/anta_tests/test_bfd.py
index 67bb0b4..54dc7a0 100644
--- a/tests/units/anta_tests/test_bfd.py
+++ b/tests/units/anta_tests/test_bfd.py
@@ -1,9 +1,8 @@
# Copyright (c) 2023-2024 Arista Networks, Inc.
# Use of this source code is governed by the Apache License 2.0
# that can be found in the LICENSE file.
-"""
-Tests for anta.tests.bfd.py
-"""
+"""Tests for anta.tests.bfd.py."""
+
# pylint: disable=C0302
from __future__ import annotations
@@ -11,7 +10,7 @@ from typing import Any
# pylint: disable=C0413
# because of the patch above
-from anta.tests.bfd import VerifyBFDPeersHealth, VerifyBFDPeersIntervals, VerifyBFDSpecificPeers # noqa: E402
+from anta.tests.bfd import VerifyBFDPeersHealth, VerifyBFDPeersIntervals, VerifyBFDSpecificPeers
from tests.lib.anta import test # noqa: F401; pylint: disable=W0611
DATA: list[dict[str, Any]] = [
diff --git a/tests/units/anta_tests/test_configuration.py b/tests/units/anta_tests/test_configuration.py
index a2ab673..7f198a3 100644
--- a/tests/units/anta_tests/test_configuration.py
+++ b/tests/units/anta_tests/test_configuration.py
@@ -1,12 +1,13 @@
# Copyright (c) 2023-2024 Arista Networks, Inc.
# Use of this source code is governed by the Apache License 2.0
# that can be found in the LICENSE file.
-"""Data for testing anta.tests.configuration"""
+"""Data for testing anta.tests.configuration."""
+
from __future__ import annotations
from typing import Any
-from anta.tests.configuration import VerifyRunningConfigDiffs, VerifyZeroTouch
+from anta.tests.configuration import VerifyRunningConfigDiffs, VerifyRunningConfigLines, VerifyZeroTouch
from tests.lib.anta import test # noqa: F401; pylint: disable=W0611
DATA: list[dict[str, Any]] = [
@@ -31,5 +32,42 @@ DATA: list[dict[str, Any]] = [
"inputs": None,
"expected": {"result": "success"},
},
- {"name": "failure", "test": VerifyRunningConfigDiffs, "eos_data": ["blah blah"], "inputs": None, "expected": {"result": "failure", "messages": ["blah blah"]}},
+ {
+ "name": "failure",
+ "test": VerifyRunningConfigDiffs,
+ "eos_data": ["blah blah"],
+ "inputs": None,
+ "expected": {"result": "failure", "messages": ["blah blah"]},
+ },
+ {
+ "name": "success",
+ "test": VerifyRunningConfigLines,
+ "eos_data": ["blah blah"],
+ "inputs": {"regex_patterns": ["blah"]},
+ "expected": {"result": "success"},
+ },
+ {
+ "name": "success",
+ "test": VerifyRunningConfigLines,
+ "eos_data": ["enable password something\nsome other line"],
+ "inputs": {"regex_patterns": ["^enable password .*$", "^.*other line$"]},
+ "expected": {"result": "success"},
+ },
+ {
+ "name": "failure",
+ "test": VerifyRunningConfigLines,
+ "eos_data": ["enable password something\nsome other line"],
+ "inputs": {"regex_patterns": ["bla", "bleh"]},
+ "expected": {"result": "failure", "messages": ["Following patterns were not found: 'bla','bleh'"]},
+ },
+ {
+ "name": "failure-invalid-regex",
+ "test": VerifyRunningConfigLines,
+ "eos_data": ["enable password something\nsome other line"],
+ "inputs": {"regex_patterns": ["["]},
+ "expected": {
+ "result": "error",
+ "messages": ["1 validation error for Input\nregex_patterns.0\n Value error, Invalid regex: unterminated character set at position 0"],
+ },
+ },
]
diff --git a/tests/units/anta_tests/test_connectivity.py b/tests/units/anta_tests/test_connectivity.py
index f79ce24..bd30811 100644
--- a/tests/units/anta_tests/test_connectivity.py
+++ b/tests/units/anta_tests/test_connectivity.py
@@ -1,9 +1,8 @@
# Copyright (c) 2023-2024 Arista Networks, Inc.
# Use of this source code is governed by the Apache License 2.0
# that can be found in the LICENSE file.
-"""
-Tests for anta.tests.connectivity.py
-"""
+"""Tests for anta.tests.connectivity.py."""
+
from __future__ import annotations
from typing import Any
@@ -27,8 +26,8 @@ DATA: list[dict[str, Any]] = [
2 packets transmitted, 2 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.072/0.159/0.247/0.088 ms, ipg/ewma 0.370/0.225 ms
- """
- ]
+ """,
+ ],
},
{
"messages": [
@@ -40,8 +39,8 @@ DATA: list[dict[str, Any]] = [
2 packets transmitted, 2 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.072/0.159/0.247/0.088 ms, ipg/ewma 0.370/0.225 ms
- """
- ]
+ """,
+ ],
},
],
"expected": {"result": "success"},
@@ -61,8 +60,8 @@ DATA: list[dict[str, Any]] = [
2 packets transmitted, 2 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.072/0.159/0.247/0.088 ms, ipg/ewma 0.370/0.225 ms
- """
- ]
+ """,
+ ],
},
{
"messages": [
@@ -74,8 +73,8 @@ DATA: list[dict[str, Any]] = [
2 packets transmitted, 2 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.072/0.159/0.247/0.088 ms, ipg/ewma 0.370/0.225 ms
- """
- ]
+ """,
+ ],
},
],
"expected": {"result": "success"},
@@ -94,8 +93,8 @@ DATA: list[dict[str, Any]] = [
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.072/0.159/0.247/0.088 ms, ipg/ewma 0.370/0.225 ms
- """
- ]
+ """,
+ ],
},
],
"expected": {"result": "success"},
@@ -115,8 +114,8 @@ DATA: list[dict[str, Any]] = [
2 packets transmitted, 0 received, 100% packet loss, time 10ms
- """
- ]
+ """,
+ ],
},
{
"messages": [
@@ -128,8 +127,8 @@ DATA: list[dict[str, Any]] = [
2 packets transmitted, 2 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.072/0.159/0.247/0.088 ms, ipg/ewma 0.370/0.225 ms
- """
- ]
+ """,
+ ],
},
],
"expected": {"result": "failure", "messages": ["Connectivity test failed for the following source-destination pairs: [('10.0.0.5', '10.0.0.11')]"]},
@@ -149,8 +148,8 @@ DATA: list[dict[str, Any]] = [
2 packets transmitted, 0 received, 100% packet loss, time 10ms
- """
- ]
+ """,
+ ],
},
{
"messages": [
@@ -162,8 +161,8 @@ DATA: list[dict[str, Any]] = [
2 packets transmitted, 2 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.072/0.159/0.247/0.088 ms, ipg/ewma 0.370/0.225 ms
- """
- ]
+ """,
+ ],
},
],
"expected": {"result": "failure", "messages": ["Connectivity test failed for the following source-destination pairs: [('Management0', '10.0.0.11')]"]},
@@ -175,7 +174,7 @@ DATA: list[dict[str, Any]] = [
"neighbors": [
{"port": "Ethernet1", "neighbor_device": "DC1-SPINE1", "neighbor_port": "Ethernet1"},
{"port": "Ethernet2", "neighbor_device": "DC1-SPINE2", "neighbor_port": "Ethernet1"},
- ]
+ ],
},
"eos_data": [
{
@@ -192,8 +191,8 @@ DATA: list[dict[str, Any]] = [
"interfaceId_v2": "Ethernet1",
"interfaceDescription": "P2P_LINK_TO_DC1-LEAF1A_Ethernet1",
},
- }
- ]
+ },
+ ],
},
"Ethernet2": {
"lldpNeighborInfo": [
@@ -207,11 +206,53 @@ DATA: list[dict[str, Any]] = [
"interfaceId_v2": "Ethernet1",
"interfaceDescription": "P2P_LINK_TO_DC1-LEAF1A_Ethernet2",
},
- }
- ]
+ },
+ ],
},
- }
- }
+ },
+ },
+ ],
+ "expected": {"result": "success"},
+ },
+ {
+ "name": "success-multiple-neighbors",
+ "test": VerifyLLDPNeighbors,
+ "inputs": {
+ "neighbors": [
+ {"port": "Ethernet1", "neighbor_device": "DC1-SPINE2", "neighbor_port": "Ethernet1"},
+ ],
+ },
+ "eos_data": [
+ {
+ "lldpNeighbors": {
+ "Ethernet1": {
+ "lldpNeighborInfo": [
+ {
+ "chassisIdType": "macAddress",
+ "chassisId": "001c.73a0.fc18",
+ "systemName": "DC1-SPINE1",
+ "neighborInterfaceInfo": {
+ "interfaceIdType": "interfaceName",
+ "interfaceId": '"Ethernet1"',
+ "interfaceId_v2": "Ethernet1",
+ "interfaceDescription": "P2P_LINK_TO_DC1-LEAF1A_Ethernet1",
+ },
+ },
+ {
+ "chassisIdType": "macAddress",
+ "chassisId": "001c.73f7.d138",
+ "systemName": "DC1-SPINE2",
+ "neighborInterfaceInfo": {
+ "interfaceIdType": "interfaceName",
+ "interfaceId": '"Ethernet1"',
+ "interfaceId_v2": "Ethernet1",
+ "interfaceDescription": "P2P_LINK_TO_DC1-LEAF1A_Ethernet2",
+ },
+ },
+ ],
+ },
+ },
+ },
],
"expected": {"result": "success"},
},
@@ -222,7 +263,7 @@ DATA: list[dict[str, Any]] = [
"neighbors": [
{"port": "Ethernet1", "neighbor_device": "DC1-SPINE1", "neighbor_port": "Ethernet1"},
{"port": "Ethernet2", "neighbor_device": "DC1-SPINE2", "neighbor_port": "Ethernet1"},
- ]
+ ],
},
"eos_data": [
{
@@ -239,13 +280,13 @@ DATA: list[dict[str, Any]] = [
"interfaceId_v2": "Ethernet1",
"interfaceDescription": "P2P_LINK_TO_DC1-LEAF1A_Ethernet1",
},
- }
- ]
+ },
+ ],
},
- }
- }
+ },
+ },
],
- "expected": {"result": "failure", "messages": ["The following port(s) have issues: {'port_not_configured': ['Ethernet2']}"]},
+ "expected": {"result": "failure", "messages": ["Port(s) not configured:\n Ethernet2"]},
},
{
"name": "failure-no-neighbor",
@@ -254,7 +295,7 @@ DATA: list[dict[str, Any]] = [
"neighbors": [
{"port": "Ethernet1", "neighbor_device": "DC1-SPINE1", "neighbor_port": "Ethernet1"},
{"port": "Ethernet2", "neighbor_device": "DC1-SPINE2", "neighbor_port": "Ethernet1"},
- ]
+ ],
},
"eos_data": [
{
@@ -271,14 +312,14 @@ DATA: list[dict[str, Any]] = [
"interfaceId_v2": "Ethernet1",
"interfaceDescription": "P2P_LINK_TO_DC1-LEAF1A_Ethernet1",
},
- }
- ]
+ },
+ ],
},
"Ethernet2": {"lldpNeighborInfo": []},
- }
- }
+ },
+ },
],
- "expected": {"result": "failure", "messages": ["The following port(s) have issues: {'no_lldp_neighbor': ['Ethernet2']}"]},
+ "expected": {"result": "failure", "messages": ["No LLDP neighbor(s) on port(s):\n Ethernet2"]},
},
{
"name": "failure-wrong-neighbor",
@@ -287,7 +328,7 @@ DATA: list[dict[str, Any]] = [
"neighbors": [
{"port": "Ethernet1", "neighbor_device": "DC1-SPINE1", "neighbor_port": "Ethernet1"},
{"port": "Ethernet2", "neighbor_device": "DC1-SPINE2", "neighbor_port": "Ethernet1"},
- ]
+ ],
},
"eos_data": [
{
@@ -304,8 +345,8 @@ DATA: list[dict[str, Any]] = [
"interfaceId_v2": "Ethernet1",
"interfaceDescription": "P2P_LINK_TO_DC1-LEAF1A_Ethernet1",
},
- }
- ]
+ },
+ ],
},
"Ethernet2": {
"lldpNeighborInfo": [
@@ -319,13 +360,13 @@ DATA: list[dict[str, Any]] = [
"interfaceId_v2": "Ethernet2",
"interfaceDescription": "P2P_LINK_TO_DC1-LEAF1A_Ethernet2",
},
- }
- ]
+ },
+ ],
},
- }
- }
+ },
+ },
],
- "expected": {"result": "failure", "messages": ["The following port(s) have issues: {'wrong_lldp_neighbor': ['Ethernet2']}"]},
+ "expected": {"result": "failure", "messages": ["Wrong LLDP neighbor(s) on port(s):\n Ethernet2\n DC1-SPINE2_Ethernet2"]},
},
{
"name": "failure-multiple",
@@ -335,7 +376,7 @@ DATA: list[dict[str, Any]] = [
{"port": "Ethernet1", "neighbor_device": "DC1-SPINE1", "neighbor_port": "Ethernet1"},
{"port": "Ethernet2", "neighbor_device": "DC1-SPINE2", "neighbor_port": "Ethernet1"},
{"port": "Ethernet3", "neighbor_device": "DC1-SPINE3", "neighbor_port": "Ethernet1"},
- ]
+ ],
},
"eos_data": [
{
@@ -352,18 +393,62 @@ DATA: list[dict[str, Any]] = [
"interfaceId_v2": "Ethernet2",
"interfaceDescription": "P2P_LINK_TO_DC1-LEAF1A_Ethernet1",
},
- }
- ]
+ },
+ ],
},
"Ethernet2": {"lldpNeighborInfo": []},
- }
- }
+ },
+ },
],
"expected": {
"result": "failure",
"messages": [
- "The following port(s) have issues: {'wrong_lldp_neighbor': ['Ethernet1'], 'no_lldp_neighbor': ['Ethernet2'], 'port_not_configured': ['Ethernet3']}"
+ "Wrong LLDP neighbor(s) on port(s):\n Ethernet1\n DC1-SPINE1_Ethernet2\n"
+ "No LLDP neighbor(s) on port(s):\n Ethernet2\n"
+ "Port(s) not configured:\n Ethernet3"
],
},
},
+ {
+ "name": "failure-multiple-neighbors",
+ "test": VerifyLLDPNeighbors,
+ "inputs": {
+ "neighbors": [
+ {"port": "Ethernet1", "neighbor_device": "DC1-SPINE3", "neighbor_port": "Ethernet1"},
+ ],
+ },
+ "eos_data": [
+ {
+ "lldpNeighbors": {
+ "Ethernet1": {
+ "lldpNeighborInfo": [
+ {
+ "chassisIdType": "macAddress",
+ "chassisId": "001c.73a0.fc18",
+ "systemName": "DC1-SPINE1",
+ "neighborInterfaceInfo": {
+ "interfaceIdType": "interfaceName",
+ "interfaceId": '"Ethernet1"',
+ "interfaceId_v2": "Ethernet1",
+ "interfaceDescription": "P2P_LINK_TO_DC1-LEAF1A_Ethernet1",
+ },
+ },
+ {
+ "chassisIdType": "macAddress",
+ "chassisId": "001c.73f7.d138",
+ "systemName": "DC1-SPINE2",
+ "neighborInterfaceInfo": {
+ "interfaceIdType": "interfaceName",
+ "interfaceId": '"Ethernet1"',
+ "interfaceId_v2": "Ethernet1",
+ "interfaceDescription": "P2P_LINK_TO_DC1-LEAF1A_Ethernet2",
+ },
+ },
+ ],
+ },
+ },
+ },
+ ],
+ "expected": {"result": "failure", "messages": ["Wrong LLDP neighbor(s) on port(s):\n Ethernet1\n DC1-SPINE1_Ethernet1\n DC1-SPINE2_Ethernet1"]},
+ },
]
diff --git a/tests/units/anta_tests/test_field_notices.py b/tests/units/anta_tests/test_field_notices.py
index 7c17f22..3cb7286 100644
--- a/tests/units/anta_tests/test_field_notices.py
+++ b/tests/units/anta_tests/test_field_notices.py
@@ -1,7 +1,8 @@
# Copyright (c) 2023-2024 Arista Networks, Inc.
# Use of this source code is governed by the Apache License 2.0
# that can be found in the LICENSE file.
-"""Test inputs for anta.tests.field_notices"""
+"""Test inputs for anta.tests.field_notices."""
+
from __future__ import annotations
from typing import Any
@@ -20,9 +21,9 @@ DATA: list[dict[str, Any]] = [
"modelName": "DCS-7280QRA-C36S",
"details": {
"deviations": [],
- "components": [{"name": "Aboot", "version": "Aboot-veos-8.0.0-3255441"}],
+ "components": [{"name": "Aboot", "version": "Aboot-veos-8.0.0-3255441"}, {"name": "NotAboot", "version": "Aboot-veos-8.0.0-3255441"}],
},
- }
+ },
],
"inputs": None,
"expected": {"result": "success"},
@@ -39,10 +40,13 @@ DATA: list[dict[str, Any]] = [
"deviations": [],
"components": [{"name": "Aboot", "version": "Aboot-veos-4.0.1-3255441"}],
},
- }
+ },
],
"inputs": None,
- "expected": {"result": "failure", "messages": ["device is running incorrect version of aboot (4.0.1)"]},
+ "expected": {
+ "result": "failure",
+ "messages": ["device is running incorrect version of aboot (4.0.1)"],
+ },
},
{
"name": "failure-4.1",
@@ -56,10 +60,13 @@ DATA: list[dict[str, Any]] = [
"deviations": [],
"components": [{"name": "Aboot", "version": "Aboot-veos-4.1.0-3255441"}],
},
- }
+ },
],
"inputs": None,
- "expected": {"result": "failure", "messages": ["device is running incorrect version of aboot (4.1.0)"]},
+ "expected": {
+ "result": "failure",
+ "messages": ["device is running incorrect version of aboot (4.1.0)"],
+ },
},
{
"name": "failure-6.0",
@@ -73,10 +80,13 @@ DATA: list[dict[str, Any]] = [
"deviations": [],
"components": [{"name": "Aboot", "version": "Aboot-veos-6.0.1-3255441"}],
},
- }
+ },
],
"inputs": None,
- "expected": {"result": "failure", "messages": ["device is running incorrect version of aboot (6.0.1)"]},
+ "expected": {
+ "result": "failure",
+ "messages": ["device is running incorrect version of aboot (6.0.1)"],
+ },
},
{
"name": "failure-6.1",
@@ -90,10 +100,13 @@ DATA: list[dict[str, Any]] = [
"deviations": [],
"components": [{"name": "Aboot", "version": "Aboot-veos-6.1.1-3255441"}],
},
- }
+ },
],
"inputs": None,
- "expected": {"result": "failure", "messages": ["device is running incorrect version of aboot (6.1.1)"]},
+ "expected": {
+ "result": "failure",
+ "messages": ["device is running incorrect version of aboot (6.1.1)"],
+ },
},
{
"name": "skipped-model",
@@ -107,10 +120,33 @@ DATA: list[dict[str, Any]] = [
"deviations": [],
"components": [{"name": "Aboot", "version": "Aboot-veos-8.0.0-3255441"}],
},
- }
+ },
],
"inputs": None,
- "expected": {"result": "skipped", "messages": ["device is not impacted by FN044"]},
+ "expected": {
+ "result": "skipped",
+ "messages": ["device is not impacted by FN044"],
+ },
+ },
+ {
+ "name": "failure-no-aboot-component",
+ "test": VerifyFieldNotice44Resolution,
+ "eos_data": [
+ {
+ "imageFormatVersion": "1.0",
+ "uptime": 1109144.35,
+ "modelName": "DCS-7280QRA-C36S",
+ "details": {
+ "deviations": [],
+ "components": [{"name": "NotAboot", "version": "Aboot-veos-4.0.1-3255441"}],
+ },
+ },
+ ],
+ "inputs": None,
+ "expected": {
+ "result": "failure",
+ "messages": ["Aboot component not found"],
+ },
},
{
"name": "success-JPE",
@@ -123,7 +159,7 @@ DATA: list[dict[str, Any]] = [
"deviations": [],
"components": [{"name": "FixedSystemvrm1", "version": "7"}],
},
- }
+ },
],
"inputs": None,
"expected": {"result": "success", "messages": ["FN72 is mitigated"]},
@@ -139,7 +175,7 @@ DATA: list[dict[str, Any]] = [
"deviations": [],
"components": [{"name": "FixedSystemvrm1", "version": "7"}],
},
- }
+ },
],
"inputs": None,
"expected": {"result": "success", "messages": ["FN72 is mitigated"]},
@@ -155,7 +191,7 @@ DATA: list[dict[str, Any]] = [
"deviations": [],
"components": [{"name": "FixedSystemvrm1", "version": "7"}],
},
- }
+ },
],
"inputs": None,
"expected": {"result": "success", "messages": ["FN72 is mitigated"]},
@@ -171,7 +207,7 @@ DATA: list[dict[str, Any]] = [
"deviations": [],
"components": [{"name": "FixedSystemvrm1", "version": "7"}],
},
- }
+ },
],
"inputs": None,
"expected": {"result": "success", "messages": ["FN72 is mitigated"]},
@@ -187,7 +223,7 @@ DATA: list[dict[str, Any]] = [
"deviations": [],
"components": [{"name": "FixedSystemvrm1", "version": "7"}],
},
- }
+ },
],
"inputs": None,
"expected": {"result": "skipped", "messages": ["Device not exposed"]},
@@ -203,10 +239,13 @@ DATA: list[dict[str, Any]] = [
"deviations": [],
"components": [{"name": "FixedSystemvrm1", "version": "5"}],
},
- }
+ },
],
"inputs": None,
- "expected": {"result": "skipped", "messages": ["Platform is not impacted by FN072"]},
+ "expected": {
+ "result": "skipped",
+ "messages": ["Platform is not impacted by FN072"],
+ },
},
{
"name": "skipped-range-JPE",
@@ -219,7 +258,39 @@ DATA: list[dict[str, Any]] = [
"deviations": [],
"components": [{"name": "FixedSystemvrm1", "version": "5"}],
},
- }
+ },
+ ],
+ "inputs": None,
+ "expected": {"result": "skipped", "messages": ["Device not exposed"]},
+ },
+ {
+ "name": "skipped-range-K-JPE",
+ "test": VerifyFieldNotice72Resolution,
+ "eos_data": [
+ {
+ "modelName": "DCS-7280SR3K-48YC8",
+ "serialNumber": "JPE2134000",
+ "details": {
+ "deviations": [],
+ "components": [{"name": "FixedSystemvrm1", "version": "5"}],
+ },
+ },
+ ],
+ "inputs": None,
+ "expected": {"result": "skipped", "messages": ["Device not exposed"]},
+ },
+ {
+ "name": "skipped-range-JAS",
+ "test": VerifyFieldNotice72Resolution,
+ "eos_data": [
+ {
+ "modelName": "DCS-7280SR3-48YC8",
+ "serialNumber": "JAS2041000",
+ "details": {
+ "deviations": [],
+ "components": [{"name": "FixedSystemvrm1", "version": "5"}],
+ },
+ },
],
"inputs": None,
"expected": {"result": "skipped", "messages": ["Device not exposed"]},
@@ -235,7 +306,7 @@ DATA: list[dict[str, Any]] = [
"deviations": [],
"components": [{"name": "FixedSystemvrm1", "version": "5"}],
},
- }
+ },
],
"inputs": None,
"expected": {"result": "skipped", "messages": ["Device not exposed"]},
@@ -251,7 +322,7 @@ DATA: list[dict[str, Any]] = [
"deviations": [],
"components": [{"name": "FixedSystemvrm1", "version": "5"}],
},
- }
+ },
],
"inputs": None,
"expected": {"result": "failure", "messages": ["Device is exposed to FN72"]},
@@ -267,7 +338,7 @@ DATA: list[dict[str, Any]] = [
"deviations": [],
"components": [{"name": "FixedSystemvrm1", "version": "5"}],
},
- }
+ },
],
"inputs": None,
"expected": {"result": "failure", "messages": ["Device is exposed to FN72"]},
@@ -283,9 +354,12 @@ DATA: list[dict[str, Any]] = [
"deviations": [],
"components": [{"name": "FixedSystemvrm2", "version": "5"}],
},
- }
+ },
],
"inputs": None,
- "expected": {"result": "error", "messages": ["Error in running test - FixedSystemvrm1 not found"]},
+ "expected": {
+ "result": "error",
+ "messages": ["Error in running test - FixedSystemvrm1 not found"],
+ },
},
]
diff --git a/tests/units/anta_tests/test_greent.py b/tests/units/anta_tests/test_greent.py
index 65789a2..2c48301 100644
--- a/tests/units/anta_tests/test_greent.py
+++ b/tests/units/anta_tests/test_greent.py
@@ -1,12 +1,14 @@
# Copyright (c) 2023-2024 Arista Networks, Inc.
# Use of this source code is governed by the Apache License 2.0
# that can be found in the LICENSE file.
-"""Data for testing anta.tests.configuration"""
+"""Data for testing anta.tests.configuration."""
+
from __future__ import annotations
from typing import Any
from anta.tests.greent import VerifyGreenT, VerifyGreenTCounters
+from tests.lib.anta import test # noqa: F401; pylint: disable=W0611
DATA: list[dict[str, Any]] = [
{
@@ -21,12 +23,19 @@ DATA: list[dict[str, Any]] = [
"test": VerifyGreenTCounters,
"eos_data": [{"sampleRcvd": 0, "sampleDiscarded": 0, "multiDstSampleRcvd": 0, "grePktSent": 0, "sampleSent": 0}],
"inputs": None,
- "expected": {"result": "failure"},
+ "expected": {"result": "failure", "messages": ["GreenT counters are not incremented"]},
},
{
"name": "success",
"test": VerifyGreenT,
- "eos_data": [{"sampleRcvd": 0, "sampleDiscarded": 0, "multiDstSampleRcvd": 0, "grePktSent": 1, "sampleSent": 0}],
+ "eos_data": [
+ {
+ "profiles": {
+ "default": {"interfaces": [], "appliedInterfaces": [], "samplePolicy": "default", "failures": {}, "appliedInterfaces6": [], "failures6": {}},
+ "testProfile": {"interfaces": [], "appliedInterfaces": [], "samplePolicy": "default", "failures": {}, "appliedInterfaces6": [], "failures6": {}},
+ },
+ },
+ ],
"inputs": None,
"expected": {"result": "success"},
},
@@ -37,11 +46,10 @@ DATA: list[dict[str, Any]] = [
{
"profiles": {
"default": {"interfaces": [], "appliedInterfaces": [], "samplePolicy": "default", "failures": {}, "appliedInterfaces6": [], "failures6": {}},
- "testProfile": {"interfaces": [], "appliedInterfaces": [], "samplePolicy": "default", "failures": {}, "appliedInterfaces6": [], "failures6": {}},
- }
- }
+ },
+ },
],
"inputs": None,
- "expected": {"result": "failure"},
+ "expected": {"result": "failure", "messages": ["No GreenT policy is created"]},
},
]
diff --git a/tests/units/anta_tests/test_hardware.py b/tests/units/anta_tests/test_hardware.py
index 5279d89..e601c68 100644
--- a/tests/units/anta_tests/test_hardware.py
+++ b/tests/units/anta_tests/test_hardware.py
@@ -1,7 +1,8 @@
# Copyright (c) 2023-2024 Arista Networks, Inc.
# Use of this source code is governed by the Apache License 2.0
# that can be found in the LICENSE file.
-"""Test inputs for anta.tests.hardware"""
+"""Test inputs for anta.tests.hardware."""
+
from __future__ import annotations
from typing import Any
@@ -26,8 +27,8 @@ DATA: list[dict[str, Any]] = [
"xcvrSlots": {
"1": {"mfgName": "Arista Networks", "modelName": "QSFP-100G-DR", "serialNum": "XKT203501340", "hardwareRev": "21"},
"2": {"mfgName": "Arista Networks", "modelName": "QSFP-100G-DR", "serialNum": "XKT203501337", "hardwareRev": "21"},
- }
- }
+ },
+ },
],
"inputs": {"manufacturers": ["Arista Networks"]},
"expected": {"result": "success"},
@@ -40,8 +41,8 @@ DATA: list[dict[str, Any]] = [
"xcvrSlots": {
"1": {"mfgName": "Arista Networks", "modelName": "QSFP-100G-DR", "serialNum": "XKT203501340", "hardwareRev": "21"},
"2": {"mfgName": "Arista Networks", "modelName": "QSFP-100G-DR", "serialNum": "XKT203501337", "hardwareRev": "21"},
- }
- }
+ },
+ },
],
"inputs": {"manufacturers": ["Arista"]},
"expected": {"result": "failure", "messages": ["Some transceivers are from unapproved manufacturers: {'1': 'Arista Networks', '2': 'Arista Networks'}"]},
@@ -57,7 +58,7 @@ DATA: list[dict[str, Any]] = [
"shutdownOnOverheat": "True",
"systemStatus": "temperatureOk",
"recoveryModeOnOverheat": "recoveryModeNA",
- }
+ },
],
"inputs": None,
"expected": {"result": "success"},
@@ -73,7 +74,7 @@ DATA: list[dict[str, Any]] = [
"shutdownOnOverheat": "True",
"systemStatus": "temperatureKO",
"recoveryModeOnOverheat": "recoveryModeNA",
- }
+ },
],
"inputs": None,
"expected": {"result": "failure", "messages": ["Device temperature exceeds acceptable limits. Current system status: 'temperatureKO'"]},
@@ -100,10 +101,10 @@ DATA: list[dict[str, Any]] = [
"pidDriverCount": 0,
"isPidDriver": False,
"name": "DomTemperatureSensor54",
- }
+ },
],
"cardSlots": [],
- }
+ },
],
"inputs": None,
"expected": {"result": "success"},
@@ -130,10 +131,10 @@ DATA: list[dict[str, Any]] = [
"pidDriverCount": 0,
"isPidDriver": False,
"name": "DomTemperatureSensor54",
- }
+ },
],
"cardSlots": [],
- }
+ },
],
"inputs": None,
"expected": {
@@ -141,7 +142,7 @@ DATA: list[dict[str, Any]] = [
"messages": [
"The following sensors are operating outside the acceptable temperature range or have raised alerts: "
"{'DomTemperatureSensor54': "
- "{'hwStatus': 'ko', 'alertCount': 0}}"
+ "{'hwStatus': 'ko', 'alertCount': 0}}",
],
},
},
@@ -167,10 +168,10 @@ DATA: list[dict[str, Any]] = [
"pidDriverCount": 0,
"isPidDriver": False,
"name": "DomTemperatureSensor54",
- }
+ },
],
"cardSlots": [],
- }
+ },
],
"inputs": None,
"expected": {
@@ -178,7 +179,7 @@ DATA: list[dict[str, Any]] = [
"messages": [
"The following sensors are operating outside the acceptable temperature range or have raised alerts: "
"{'DomTemperatureSensor54': "
- "{'hwStatus': 'ok', 'alertCount': 1}}"
+ "{'hwStatus': 'ok', 'alertCount': 1}}",
],
},
},
@@ -200,7 +201,7 @@ DATA: list[dict[str, Any]] = [
"currentZones": 1,
"configuredZones": 0,
"systemStatus": "coolingOk",
- }
+ },
],
"inputs": None,
"expected": {"result": "success"},
@@ -223,7 +224,7 @@ DATA: list[dict[str, Any]] = [
"currentZones": 1,
"configuredZones": 0,
"systemStatus": "coolingKo",
- }
+ },
],
"inputs": None,
"expected": {"result": "failure", "messages": ["Device system cooling is not OK: 'coolingKo'"]},
@@ -254,7 +255,7 @@ DATA: list[dict[str, Any]] = [
"speedHwOverride": True,
"speedStable": True,
"label": "PowerSupply1/1",
- }
+ },
],
"speed": 30,
"label": "PowerSupply1",
@@ -272,7 +273,7 @@ DATA: list[dict[str, Any]] = [
"speedHwOverride": True,
"speedStable": True,
"label": "PowerSupply2/1",
- }
+ },
],
"speed": 30,
"label": "PowerSupply2",
@@ -292,7 +293,7 @@ DATA: list[dict[str, Any]] = [
"speedHwOverride": False,
"speedStable": True,
"label": "1/1",
- }
+ },
],
"speed": 30,
"label": "1",
@@ -310,7 +311,7 @@ DATA: list[dict[str, Any]] = [
"speedHwOverride": False,
"speedStable": True,
"label": "2/1",
- }
+ },
],
"speed": 30,
"label": "2",
@@ -328,7 +329,7 @@ DATA: list[dict[str, Any]] = [
"speedHwOverride": False,
"speedStable": True,
"label": "3/1",
- }
+ },
],
"speed": 30,
"label": "3",
@@ -346,7 +347,7 @@ DATA: list[dict[str, Any]] = [
"speedHwOverride": False,
"speedStable": True,
"label": "4/1",
- }
+ },
],
"speed": 30,
"label": "4",
@@ -356,7 +357,7 @@ DATA: list[dict[str, Any]] = [
"currentZones": 1,
"configuredZones": 0,
"systemStatus": "coolingOk",
- }
+ },
],
"inputs": {"states": ["ok"]},
"expected": {"result": "success"},
@@ -387,7 +388,7 @@ DATA: list[dict[str, Any]] = [
"speedHwOverride": True,
"speedStable": True,
"label": "PowerSupply1/1",
- }
+ },
],
"speed": 30,
"label": "PowerSupply1",
@@ -405,7 +406,7 @@ DATA: list[dict[str, Any]] = [
"speedHwOverride": True,
"speedStable": True,
"label": "PowerSupply2/1",
- }
+ },
],
"speed": 30,
"label": "PowerSupply2",
@@ -425,7 +426,7 @@ DATA: list[dict[str, Any]] = [
"speedHwOverride": False,
"speedStable": True,
"label": "1/1",
- }
+ },
],
"speed": 30,
"label": "1",
@@ -443,7 +444,7 @@ DATA: list[dict[str, Any]] = [
"speedHwOverride": False,
"speedStable": True,
"label": "2/1",
- }
+ },
],
"speed": 30,
"label": "2",
@@ -461,7 +462,7 @@ DATA: list[dict[str, Any]] = [
"speedHwOverride": False,
"speedStable": True,
"label": "3/1",
- }
+ },
],
"speed": 30,
"label": "3",
@@ -479,7 +480,7 @@ DATA: list[dict[str, Any]] = [
"speedHwOverride": False,
"speedStable": True,
"label": "4/1",
- }
+ },
],
"speed": 30,
"label": "4",
@@ -489,7 +490,7 @@ DATA: list[dict[str, Any]] = [
"currentZones": 1,
"configuredZones": 0,
"systemStatus": "coolingOk",
- }
+ },
],
"inputs": {"states": ["ok", "Not Inserted"]},
"expected": {"result": "success"},
@@ -520,7 +521,7 @@ DATA: list[dict[str, Any]] = [
"speedHwOverride": True,
"speedStable": True,
"label": "PowerSupply1/1",
- }
+ },
],
"speed": 30,
"label": "PowerSupply1",
@@ -538,7 +539,7 @@ DATA: list[dict[str, Any]] = [
"speedHwOverride": True,
"speedStable": True,
"label": "PowerSupply2/1",
- }
+ },
],
"speed": 30,
"label": "PowerSupply2",
@@ -558,7 +559,7 @@ DATA: list[dict[str, Any]] = [
"speedHwOverride": False,
"speedStable": True,
"label": "1/1",
- }
+ },
],
"speed": 30,
"label": "1",
@@ -576,7 +577,7 @@ DATA: list[dict[str, Any]] = [
"speedHwOverride": False,
"speedStable": True,
"label": "2/1",
- }
+ },
],
"speed": 30,
"label": "2",
@@ -594,7 +595,7 @@ DATA: list[dict[str, Any]] = [
"speedHwOverride": False,
"speedStable": True,
"label": "3/1",
- }
+ },
],
"speed": 30,
"label": "3",
@@ -612,7 +613,7 @@ DATA: list[dict[str, Any]] = [
"speedHwOverride": False,
"speedStable": True,
"label": "4/1",
- }
+ },
],
"speed": 30,
"label": "4",
@@ -622,7 +623,7 @@ DATA: list[dict[str, Any]] = [
"currentZones": 1,
"configuredZones": 0,
"systemStatus": "CoolingKo",
- }
+ },
],
"inputs": {"states": ["ok", "Not Inserted"]},
"expected": {"result": "failure", "messages": ["Fan 1/1 on Fan Tray 1 is: 'down'"]},
@@ -653,7 +654,7 @@ DATA: list[dict[str, Any]] = [
"speedHwOverride": True,
"speedStable": True,
"label": "PowerSupply1/1",
- }
+ },
],
"speed": 30,
"label": "PowerSupply1",
@@ -671,7 +672,7 @@ DATA: list[dict[str, Any]] = [
"speedHwOverride": True,
"speedStable": True,
"label": "PowerSupply2/1",
- }
+ },
],
"speed": 30,
"label": "PowerSupply2",
@@ -691,7 +692,7 @@ DATA: list[dict[str, Any]] = [
"speedHwOverride": False,
"speedStable": True,
"label": "1/1",
- }
+ },
],
"speed": 30,
"label": "1",
@@ -709,7 +710,7 @@ DATA: list[dict[str, Any]] = [
"speedHwOverride": False,
"speedStable": True,
"label": "2/1",
- }
+ },
],
"speed": 30,
"label": "2",
@@ -727,7 +728,7 @@ DATA: list[dict[str, Any]] = [
"speedHwOverride": False,
"speedStable": True,
"label": "3/1",
- }
+ },
],
"speed": 30,
"label": "3",
@@ -745,7 +746,7 @@ DATA: list[dict[str, Any]] = [
"speedHwOverride": False,
"speedStable": True,
"label": "4/1",
- }
+ },
],
"speed": 30,
"label": "4",
@@ -755,7 +756,7 @@ DATA: list[dict[str, Any]] = [
"currentZones": 1,
"configuredZones": 0,
"systemStatus": "CoolingKo",
- }
+ },
],
"inputs": {"states": ["ok", "Not Inserted"]},
"expected": {"result": "failure", "messages": ["Fan PowerSupply1/1 on PowerSupply PowerSupply1 is: 'down'"]},
@@ -801,8 +802,8 @@ DATA: list[dict[str, Any]] = [
"outputCurrent": 9.828125,
"managed": True,
},
- }
- }
+ },
+ },
],
"inputs": {"states": ["ok"]},
"expected": {"result": "success"},
@@ -848,8 +849,8 @@ DATA: list[dict[str, Any]] = [
"outputCurrent": 9.828125,
"managed": True,
},
- }
- }
+ },
+ },
],
"inputs": {"states": ["ok", "Not Inserted"]},
"expected": {"result": "success"},
@@ -895,8 +896,8 @@ DATA: list[dict[str, Any]] = [
"outputCurrent": 9.828125,
"managed": True,
},
- }
- }
+ },
+ },
],
"inputs": {"states": ["ok"]},
"expected": {"result": "failure", "messages": ["The following power supplies status are not in the accepted states list: {'1': {'state': 'powerLoss'}}"]},
diff --git a/tests/units/anta_tests/test_interfaces.py b/tests/units/anta_tests/test_interfaces.py
index 5b0d845..b8cf493 100644
--- a/tests/units/anta_tests/test_interfaces.py
+++ b/tests/units/anta_tests/test_interfaces.py
@@ -1,7 +1,9 @@
# Copyright (c) 2023-2024 Arista Networks, Inc.
# Use of this source code is governed by the Apache License 2.0
# that can be found in the LICENSE file.
-"""Test inputs for anta.tests.hardware"""
+"""Test inputs for anta.tests.interfaces."""
+
+# pylint: disable=C0302
from __future__ import annotations
from typing import Any
@@ -12,6 +14,7 @@ from anta.tests.interfaces import (
VerifyInterfaceErrDisabled,
VerifyInterfaceErrors,
VerifyInterfaceIPv4,
+ VerifyInterfacesSpeed,
VerifyInterfacesStatus,
VerifyInterfaceUtilization,
VerifyIPProxyARP,
@@ -30,25 +33,772 @@ DATA: list[dict[str, Any]] = [
"name": "success",
"test": VerifyInterfaceUtilization,
"eos_data": [
- """Port Name Intvl In Mbps % In Kpps Out Mbps % Out Kpps
-Et1 5:00 0.0 0.0% 0 0.0 0.0% 0
-Et4 5:00 0.0 0.0% 0 0.0 0.0% 0
-"""
+ {
+ "interfaces": {
+ "Ethernet1/1": {
+ "description": "P2P_LINK_TO_DC1-SPINE1_Ethernet1/1",
+ "interval": 300,
+ "inBpsRate": 2242.2497205060313,
+ "inPktsRate": 0.00028663359326985426,
+ "inPpsRate": 3.9005388262031966,
+ "outBpsRate": 0.0,
+ "outPktsRate": 0.0,
+ "outPpsRate": 0.0,
+ "lastUpdateTimestamp": 1710253727.138605,
+ },
+ "Port-Channel31": {
+ "description": "MLAG_PEER_dc1-leaf1b_Po31",
+ "interval": 300,
+ "inBpsRate": 1862.4876594267096,
+ "inPktsRate": 0.00011473185873493155,
+ "inPpsRate": 2.7009344704495084,
+ "outBpsRate": 1758.0044570479704,
+ "outPktsRate": 0.00010844978034772172,
+ "outPpsRate": 2.5686946869154013,
+ "lastUpdateTimestamp": 1710253726.4029949,
+ },
+ }
+ },
+ {
+ "interfaces": {
+ "Ethernet1/1": {
+ "name": "Ethernet1/1",
+ "forwardingModel": "routed",
+ "lineProtocolStatus": "up",
+ "interfaceStatus": "connected",
+ "hardware": "ethernet",
+ "interfaceAddress": [
+ {
+ "primaryIp": {"address": "10.255.255.1", "maskLen": 31},
+ "secondaryIps": {},
+ "secondaryIpsOrderedList": [],
+ "virtualIp": {"address": "0.0.0.0", "maskLen": 0},
+ "virtualSecondaryIps": {},
+ "virtualSecondaryIpsOrderedList": [],
+ "broadcastAddress": "255.255.255.255",
+ "dhcp": False,
+ }
+ ],
+ "physicalAddress": "aa:c1:ab:7e:76:36",
+ "burnedInAddress": "aa:c1:ab:7e:76:36",
+ "description": "P2P_LINK_TO_DC1-SPINE1_Ethernet1/1",
+ "bandwidth": 1000000000,
+ "mtu": 1500,
+ "l3MtuConfigured": True,
+ "l2Mru": 0,
+ "lastStatusChangeTimestamp": 1710234511.3085763,
+ "interfaceStatistics": {
+ "updateInterval": 300.0,
+ "inBitsRate": 2240.0023281094,
+ "inPktsRate": 3.8978070399448654,
+ "outBitsRate": 0.0,
+ "outPktsRate": 0.0,
+ },
+ "interfaceCounters": {
+ "inOctets": 5413008,
+ "inUcastPkts": 74693,
+ "inMulticastPkts": 643,
+ "inBroadcastPkts": 1,
+ "inDiscards": 0,
+ "inTotalPkts": 75337,
+ "outOctets": 0,
+ "outUcastPkts": 0,
+ "outMulticastPkts": 0,
+ "outBroadcastPkts": 0,
+ "outDiscards": 0,
+ "outTotalPkts": 0,
+ "linkStatusChanges": 2,
+ "totalInErrors": 0,
+ "inputErrorsDetail": {"runtFrames": 0, "giantFrames": 0, "fcsErrors": 0, "alignmentErrors": 0, "symbolErrors": 0, "rxPause": 0},
+ "totalOutErrors": 0,
+ "outputErrorsDetail": {"collisions": 0, "lateCollisions": 0, "deferredTransmissions": 0, "txPause": 0},
+ "counterRefreshTime": 1710253760.6489396,
+ },
+ "duplex": "duplexFull",
+ "autoNegotiate": "unknown",
+ "loopbackMode": "loopbackNone",
+ "lanes": 0,
+ },
+ "Port-Channel31": {
+ "name": "Port-Channel31",
+ "forwardingModel": "bridged",
+ "lineProtocolStatus": "up",
+ "interfaceStatus": "connected",
+ "hardware": "portChannel",
+ "interfaceAddress": [],
+ "physicalAddress": "aa:c1:ab:72:58:40",
+ "description": "MLAG_PEER_dc1-leaf1b_Po31",
+ "bandwidth": 2000000000,
+ "mtu": 9214,
+ "l3MtuConfigured": False,
+ "l2Mru": 0,
+ "lastStatusChangeTimestamp": 1710234510.1133935,
+ "interfaceStatistics": {
+ "updateInterval": 300.0,
+ "inBitsRate": 1854.287898883752,
+ "inPktsRate": 2.6902775246495665,
+ "outBitsRate": 1749.1141130864632,
+ "outPktsRate": 2.5565618978302362,
+ },
+ "interfaceCounters": {
+ "inOctets": 4475556,
+ "inUcastPkts": 48949,
+ "inMulticastPkts": 2579,
+ "inBroadcastPkts": 2,
+ "inDiscards": 0,
+ "inTotalPkts": 51530,
+ "outOctets": 4230011,
+ "outUcastPkts": 48982,
+ "outMulticastPkts": 6,
+ "outBroadcastPkts": 2,
+ "outDiscards": 0,
+ "outTotalPkts": 48990,
+ "linkStatusChanges": 2,
+ "totalInErrors": 0,
+ "totalOutErrors": 0,
+ "counterRefreshTime": 1710253760.6500373,
+ },
+ "memberInterfaces": {
+ "Ethernet3/1": {"bandwidth": 1000000000, "duplex": "duplexFull"},
+ "Ethernet4/1": {"bandwidth": 1000000000, "duplex": "duplexFull"},
+ },
+ "fallbackEnabled": False,
+ "fallbackEnabledType": "fallbackNone",
+ },
+ }
+ },
],
- "inputs": None,
+ "inputs": {"threshold": 70.0},
+ "expected": {"result": "success"},
+ },
+ {
+ "name": "success-ignored-interface",
+ "test": VerifyInterfaceUtilization,
+ "eos_data": [
+ {
+ "interfaces": {
+ "Ethernet1/1": {
+ "description": "P2P_LINK_TO_DC1-SPINE1_Ethernet1/1",
+ "interval": 300,
+ "inBpsRate": 2242.2497205060313,
+ "inPktsRate": 0.00028663359326985426,
+ "inPpsRate": 3.9005388262031966,
+ "outBpsRate": 0.0,
+ "outPktsRate": 0.0,
+ "outPpsRate": 0.0,
+ "lastUpdateTimestamp": 1710253727.138605,
+ },
+ "Port-Channel31": {
+ "description": "MLAG_PEER_dc1-leaf1b_Po31",
+ "interval": 300,
+ "inBpsRate": 1862.4876594267096,
+ "inPktsRate": 0.00011473185873493155,
+ "inPpsRate": 2.7009344704495084,
+ "outBpsRate": 1758.0044570479704,
+ "outPktsRate": 0.00010844978034772172,
+ "outPpsRate": 2.5686946869154013,
+ "lastUpdateTimestamp": 1710253726.4029949,
+ },
+ "Port-Channel51": {
+ "description": "dc1-leaf1-server1",
+ "interval": 300,
+ "inBpsRate": 0.0023680437493116147,
+ "inPpsRate": 2.3125427239371238e-06,
+ "outBpsRate": 0.0,
+ "outPpsRate": 0.0,
+ "lastUpdateTimestamp": 1712928643.7805147,
+ },
+ },
+ },
+ {
+ "interfaces": {
+ "Ethernet1/1": {
+ "name": "Ethernet1/1",
+ "forwardingModel": "routed",
+ "lineProtocolStatus": "up",
+ "interfaceStatus": "connected",
+ "hardware": "ethernet",
+ "interfaceAddress": [
+ {
+ "primaryIp": {"address": "10.255.255.1", "maskLen": 31},
+ "secondaryIps": {},
+ "secondaryIpsOrderedList": [],
+ "virtualIp": {"address": "0.0.0.0", "maskLen": 0},
+ "virtualSecondaryIps": {},
+ "virtualSecondaryIpsOrderedList": [],
+ "broadcastAddress": "255.255.255.255",
+ "dhcp": False,
+ }
+ ],
+ "physicalAddress": "aa:c1:ab:7e:76:36",
+ "burnedInAddress": "aa:c1:ab:7e:76:36",
+ "description": "P2P_LINK_TO_DC1-SPINE1_Ethernet1/1",
+ "bandwidth": 1000000000,
+ "mtu": 1500,
+ "l3MtuConfigured": True,
+ "l2Mru": 0,
+ "lastStatusChangeTimestamp": 1710234511.3085763,
+ "interfaceStatistics": {
+ "updateInterval": 300.0,
+ "inBitsRate": 2240.0023281094,
+ "inPktsRate": 3.8978070399448654,
+ "outBitsRate": 0.0,
+ "outPktsRate": 0.0,
+ },
+ "interfaceCounters": {
+ "inOctets": 5413008,
+ "inUcastPkts": 74693,
+ "inMulticastPkts": 643,
+ "inBroadcastPkts": 1,
+ "inDiscards": 0,
+ "inTotalPkts": 75337,
+ "outOctets": 0,
+ "outUcastPkts": 0,
+ "outMulticastPkts": 0,
+ "outBroadcastPkts": 0,
+ "outDiscards": 0,
+ "outTotalPkts": 0,
+ "linkStatusChanges": 2,
+ "totalInErrors": 0,
+ "inputErrorsDetail": {"runtFrames": 0, "giantFrames": 0, "fcsErrors": 0, "alignmentErrors": 0, "symbolErrors": 0, "rxPause": 0},
+ "totalOutErrors": 0,
+ "outputErrorsDetail": {"collisions": 0, "lateCollisions": 0, "deferredTransmissions": 0, "txPause": 0},
+ "counterRefreshTime": 1710253760.6489396,
+ },
+ "duplex": "duplexFull",
+ "autoNegotiate": "unknown",
+ "loopbackMode": "loopbackNone",
+ "lanes": 0,
+ },
+ "Port-Channel31": {
+ "name": "Port-Channel31",
+ "forwardingModel": "bridged",
+ "lineProtocolStatus": "up",
+ "interfaceStatus": "connected",
+ "hardware": "portChannel",
+ "interfaceAddress": [],
+ "physicalAddress": "aa:c1:ab:72:58:40",
+ "description": "MLAG_PEER_dc1-leaf1b_Po31",
+ "bandwidth": 2000000000,
+ "mtu": 9214,
+ "l3MtuConfigured": False,
+ "l2Mru": 0,
+ "lastStatusChangeTimestamp": 1710234510.1133935,
+ "interfaceStatistics": {
+ "updateInterval": 300.0,
+ "inBitsRate": 1854.287898883752,
+ "inPktsRate": 2.6902775246495665,
+ "outBitsRate": 1749.1141130864632,
+ "outPktsRate": 2.5565618978302362,
+ },
+ "interfaceCounters": {
+ "inOctets": 4475556,
+ "inUcastPkts": 48949,
+ "inMulticastPkts": 2579,
+ "inBroadcastPkts": 2,
+ "inDiscards": 0,
+ "inTotalPkts": 51530,
+ "outOctets": 4230011,
+ "outUcastPkts": 48982,
+ "outMulticastPkts": 6,
+ "outBroadcastPkts": 2,
+ "outDiscards": 0,
+ "outTotalPkts": 48990,
+ "linkStatusChanges": 2,
+ "totalInErrors": 0,
+ "totalOutErrors": 0,
+ "counterRefreshTime": 1710253760.6500373,
+ },
+ "memberInterfaces": {
+ "Ethernet3/1": {"bandwidth": 1000000000, "duplex": "duplexFull"},
+ "Ethernet4/1": {"bandwidth": 1000000000, "duplex": "duplexFull"},
+ },
+ "fallbackEnabled": False,
+ "fallbackEnabledType": "fallbackNone",
+ },
+ "Port-Channel51": {
+ "name": "Port-Channel51",
+ "forwardingModel": "bridged",
+ "lineProtocolStatus": "lowerLayerDown",
+ "interfaceStatus": "notconnect",
+ "hardware": "portChannel",
+ "interfaceAddress": [],
+ "physicalAddress": "00:00:00:00:00:00",
+ "description": "dc1-leaf1-server1",
+ "bandwidth": 0,
+ "mtu": 9214,
+ "l3MtuConfigured": False,
+ "l2Mru": 0,
+ "lastStatusChangeTimestamp": 1712925798.5035574,
+ "interfaceStatistics": {
+ "updateInterval": 300.0,
+ "inBitsRate": 0.00839301770723288,
+ "inPktsRate": 8.19630635471961e-06,
+ "outBitsRate": 0.0,
+ "outPktsRate": 0.0,
+ },
+ "interfaceCounters": {
+ "inOctets": 329344,
+ "inUcastPkts": 0,
+ "inMulticastPkts": 2573,
+ "inBroadcastPkts": 0,
+ "inDiscards": 0,
+ "inTotalPkts": 2573,
+ "outOctets": 0,
+ "outUcastPkts": 0,
+ "outMulticastPkts": 0,
+ "outBroadcastPkts": 0,
+ "outDiscards": 0,
+ "outTotalPkts": 0,
+ "linkStatusChanges": 3,
+ "totalInErrors": 0,
+ "totalOutErrors": 0,
+ "counterRefreshTime": 1712928265.9816775,
+ },
+ "memberInterfaces": {},
+ "fallbackEnabled": False,
+ "fallbackEnabledType": "fallbackNone",
+ },
+ }
+ },
+ ],
+ "inputs": {"threshold": 70.0},
"expected": {"result": "success"},
},
{
"name": "failure",
"test": VerifyInterfaceUtilization,
"eos_data": [
- """Port Name Intvl In Mbps % In Kpps Out Mbps % Out Kpps
-Et1 5:00 0.0 0.0% 0 0.0 80.0% 0
-Et4 5:00 0.0 99.9% 0 0.0 0.0% 0
-"""
+ {
+ "interfaces": {
+ "Ethernet1/1": {
+ "description": "P2P_LINK_TO_DC1-SPINE1_Ethernet1/1",
+ "interval": 300,
+ "inBpsRate": 100000000.0,
+ "inPktsRate": 0.00028663359326985426,
+ "inPpsRate": 3.9005388262031966,
+ "outBpsRate": 0.0,
+ "outPktsRate": 0.0,
+ "outPpsRate": 0.0,
+ "lastUpdateTimestamp": 1710253727.138605,
+ },
+ "Port-Channel31": {
+ "description": "MLAG_PEER_dc1-leaf1b_Po31",
+ "interval": 300,
+ "inBpsRate": 1862.4876594267096,
+ "inPktsRate": 0.00011473185873493155,
+ "inPpsRate": 2.7009344704495084,
+ "outBpsRate": 100000000.0,
+ "outPktsRate": 0.00010844978034772172,
+ "outPpsRate": 2.5686946869154013,
+ "lastUpdateTimestamp": 1710253726.4029949,
+ },
+ }
+ },
+ {
+ "interfaces": {
+ "Ethernet1/1": {
+ "name": "Ethernet1/1",
+ "forwardingModel": "routed",
+ "lineProtocolStatus": "up",
+ "interfaceStatus": "connected",
+ "hardware": "ethernet",
+ "interfaceAddress": [
+ {
+ "primaryIp": {"address": "10.255.255.1", "maskLen": 31},
+ "secondaryIps": {},
+ "secondaryIpsOrderedList": [],
+ "virtualIp": {"address": "0.0.0.0", "maskLen": 0},
+ "virtualSecondaryIps": {},
+ "virtualSecondaryIpsOrderedList": [],
+ "broadcastAddress": "255.255.255.255",
+ "dhcp": False,
+ }
+ ],
+ "physicalAddress": "aa:c1:ab:7e:76:36",
+ "burnedInAddress": "aa:c1:ab:7e:76:36",
+ "description": "P2P_LINK_TO_DC1-SPINE1_Ethernet1/1",
+ "bandwidth": 1000000000,
+ "mtu": 1500,
+ "l3MtuConfigured": True,
+ "l2Mru": 0,
+ "lastStatusChangeTimestamp": 1710234511.3085763,
+ "interfaceStatistics": {
+ "updateInterval": 300.0,
+ "inBitsRate": 2240.0023281094,
+ "inPktsRate": 3.8978070399448654,
+ "outBitsRate": 0.0,
+ "outPktsRate": 0.0,
+ },
+ "interfaceCounters": {
+ "inOctets": 5413008,
+ "inUcastPkts": 74693,
+ "inMulticastPkts": 643,
+ "inBroadcastPkts": 1,
+ "inDiscards": 0,
+ "inTotalPkts": 75337,
+ "outOctets": 0,
+ "outUcastPkts": 0,
+ "outMulticastPkts": 0,
+ "outBroadcastPkts": 0,
+ "outDiscards": 0,
+ "outTotalPkts": 0,
+ "linkStatusChanges": 2,
+ "totalInErrors": 0,
+ "inputErrorsDetail": {"runtFrames": 0, "giantFrames": 0, "fcsErrors": 0, "alignmentErrors": 0, "symbolErrors": 0, "rxPause": 0},
+ "totalOutErrors": 0,
+ "outputErrorsDetail": {"collisions": 0, "lateCollisions": 0, "deferredTransmissions": 0, "txPause": 0},
+ "counterRefreshTime": 1710253760.6489396,
+ },
+ "duplex": "duplexFull",
+ "autoNegotiate": "unknown",
+ "loopbackMode": "loopbackNone",
+ "lanes": 0,
+ },
+ "Port-Channel31": {
+ "name": "Port-Channel31",
+ "forwardingModel": "bridged",
+ "lineProtocolStatus": "up",
+ "interfaceStatus": "connected",
+ "hardware": "portChannel",
+ "interfaceAddress": [],
+ "physicalAddress": "aa:c1:ab:72:58:40",
+ "description": "MLAG_PEER_dc1-leaf1b_Po31",
+ "bandwidth": 2000000000,
+ "mtu": 9214,
+ "l3MtuConfigured": False,
+ "l2Mru": 0,
+ "lastStatusChangeTimestamp": 1710234510.1133935,
+ "interfaceStatistics": {
+ "updateInterval": 300.0,
+ "inBitsRate": 1854.287898883752,
+ "inPktsRate": 2.6902775246495665,
+ "outBitsRate": 1749.1141130864632,
+ "outPktsRate": 2.5565618978302362,
+ },
+ "interfaceCounters": {
+ "inOctets": 4475556,
+ "inUcastPkts": 48949,
+ "inMulticastPkts": 2579,
+ "inBroadcastPkts": 2,
+ "inDiscards": 0,
+ "inTotalPkts": 51530,
+ "outOctets": 4230011,
+ "outUcastPkts": 48982,
+ "outMulticastPkts": 6,
+ "outBroadcastPkts": 2,
+ "outDiscards": 0,
+ "outTotalPkts": 48990,
+ "linkStatusChanges": 2,
+ "totalInErrors": 0,
+ "totalOutErrors": 0,
+ "counterRefreshTime": 1710253760.6500373,
+ },
+ "memberInterfaces": {
+ "Ethernet3/1": {"bandwidth": 1000000000, "duplex": "duplexFull"},
+ "Ethernet4/1": {"bandwidth": 1000000000, "duplex": "duplexFull"},
+ },
+ "fallbackEnabled": False,
+ "fallbackEnabledType": "fallbackNone",
+ },
+ }
+ },
],
- "inputs": None,
- "expected": {"result": "failure", "messages": ["The following interfaces have a usage > 75%: {'Et1': '80.0%', 'Et4': '99.9%'}"]},
+ "inputs": {"threshold": 3.0},
+ "expected": {
+ "result": "failure",
+ "messages": ["The following interfaces have a usage > 3.0%: {'Ethernet1/1': {'inBpsRate': 10.0}, 'Port-Channel31': {'outBpsRate': 5.0}}"],
+ },
+ },
+ {
+ "name": "error-duplex-half",
+ "test": VerifyInterfaceUtilization,
+ "eos_data": [
+ {
+ "interfaces": {
+ "Ethernet1/1": {
+ "description": "P2P_LINK_TO_DC1-SPINE1_Ethernet1/1",
+ "interval": 300,
+ "inBpsRate": 2242.2497205060313,
+ "inPktsRate": 0.00028663359326985426,
+ "inPpsRate": 3.9005388262031966,
+ "outBpsRate": 0.0,
+ "outPktsRate": 0.0,
+ "outPpsRate": 0.0,
+ "lastUpdateTimestamp": 1710253727.138605,
+ },
+ "Port-Channel31": {
+ "description": "MLAG_PEER_dc1-leaf1b_Po31",
+ "interval": 300,
+ "inBpsRate": 1862.4876594267096,
+ "inPktsRate": 0.00011473185873493155,
+ "inPpsRate": 2.7009344704495084,
+ "outBpsRate": 1758.0044570479704,
+ "outPktsRate": 0.00010844978034772172,
+ "outPpsRate": 2.5686946869154013,
+ "lastUpdateTimestamp": 1710253726.4029949,
+ },
+ }
+ },
+ {
+ "interfaces": {
+ "Ethernet1/1": {
+ "name": "Ethernet1/1",
+ "forwardingModel": "routed",
+ "lineProtocolStatus": "up",
+ "interfaceStatus": "connected",
+ "hardware": "ethernet",
+ "interfaceAddress": [
+ {
+ "primaryIp": {"address": "10.255.255.1", "maskLen": 31},
+ "secondaryIps": {},
+ "secondaryIpsOrderedList": [],
+ "virtualIp": {"address": "0.0.0.0", "maskLen": 0},
+ "virtualSecondaryIps": {},
+ "virtualSecondaryIpsOrderedList": [],
+ "broadcastAddress": "255.255.255.255",
+ "dhcp": False,
+ }
+ ],
+ "physicalAddress": "aa:c1:ab:7e:76:36",
+ "burnedInAddress": "aa:c1:ab:7e:76:36",
+ "description": "P2P_LINK_TO_DC1-SPINE1_Ethernet1/1",
+ "bandwidth": 1000000000,
+ "mtu": 1500,
+ "l3MtuConfigured": True,
+ "l2Mru": 0,
+ "lastStatusChangeTimestamp": 1710234511.3085763,
+ "interfaceStatistics": {
+ "updateInterval": 300.0,
+ "inBitsRate": 2240.0023281094,
+ "inPktsRate": 3.8978070399448654,
+ "outBitsRate": 0.0,
+ "outPktsRate": 0.0,
+ },
+ "interfaceCounters": {
+ "inOctets": 5413008,
+ "inUcastPkts": 74693,
+ "inMulticastPkts": 643,
+ "inBroadcastPkts": 1,
+ "inDiscards": 0,
+ "inTotalPkts": 75337,
+ "outOctets": 0,
+ "outUcastPkts": 0,
+ "outMulticastPkts": 0,
+ "outBroadcastPkts": 0,
+ "outDiscards": 0,
+ "outTotalPkts": 0,
+ "linkStatusChanges": 2,
+ "totalInErrors": 0,
+ "inputErrorsDetail": {"runtFrames": 0, "giantFrames": 0, "fcsErrors": 0, "alignmentErrors": 0, "symbolErrors": 0, "rxPause": 0},
+ "totalOutErrors": 0,
+ "outputErrorsDetail": {"collisions": 0, "lateCollisions": 0, "deferredTransmissions": 0, "txPause": 0},
+ "counterRefreshTime": 1710253760.6489396,
+ },
+ "duplex": "duplexHalf",
+ "autoNegotiate": "unknown",
+ "loopbackMode": "loopbackNone",
+ "lanes": 0,
+ },
+ "Port-Channel31": {
+ "name": "Port-Channel31",
+ "forwardingModel": "bridged",
+ "lineProtocolStatus": "up",
+ "interfaceStatus": "connected",
+ "hardware": "portChannel",
+ "interfaceAddress": [],
+ "physicalAddress": "aa:c1:ab:72:58:40",
+ "description": "MLAG_PEER_dc1-leaf1b_Po31",
+ "bandwidth": 2000000000,
+ "mtu": 9214,
+ "l3MtuConfigured": False,
+ "l2Mru": 0,
+ "lastStatusChangeTimestamp": 1710234510.1133935,
+ "interfaceStatistics": {
+ "updateInterval": 300.0,
+ "inBitsRate": 1854.287898883752,
+ "inPktsRate": 2.6902775246495665,
+ "outBitsRate": 1749.1141130864632,
+ "outPktsRate": 2.5565618978302362,
+ },
+ "interfaceCounters": {
+ "inOctets": 4475556,
+ "inUcastPkts": 48949,
+ "inMulticastPkts": 2579,
+ "inBroadcastPkts": 2,
+ "inDiscards": 0,
+ "inTotalPkts": 51530,
+ "outOctets": 4230011,
+ "outUcastPkts": 48982,
+ "outMulticastPkts": 6,
+ "outBroadcastPkts": 2,
+ "outDiscards": 0,
+ "outTotalPkts": 48990,
+ "linkStatusChanges": 2,
+ "totalInErrors": 0,
+ "totalOutErrors": 0,
+ "counterRefreshTime": 1710253760.6500373,
+ },
+ "memberInterfaces": {
+ "Ethernet3/1": {"bandwidth": 1000000000, "duplex": "duplexFull"},
+ "Ethernet4/1": {"bandwidth": 1000000000, "duplex": "duplexFull"},
+ },
+ "fallbackEnabled": False,
+ "fallbackEnabledType": "fallbackNone",
+ },
+ }
+ },
+ ],
+ "inputs": {"threshold": 70.0},
+ "expected": {
+ "result": "error",
+ "messages": ["Interface Ethernet1/1 or one of its member interfaces is not Full-Duplex. VerifyInterfaceUtilization has not been implemented."],
+ },
+ },
+ {
+ "name": "error-duplex-half-po",
+ "test": VerifyInterfaceUtilization,
+ "eos_data": [
+ {
+ "interfaces": {
+ "Ethernet1/1": {
+ "description": "P2P_LINK_TO_DC1-SPINE1_Ethernet1/1",
+ "interval": 300,
+ "inBpsRate": 2242.2497205060313,
+ "inPktsRate": 0.00028663359326985426,
+ "inPpsRate": 3.9005388262031966,
+ "outBpsRate": 0.0,
+ "outPktsRate": 0.0,
+ "outPpsRate": 0.0,
+ "lastUpdateTimestamp": 1710253727.138605,
+ },
+ "Port-Channel31": {
+ "description": "MLAG_PEER_dc1-leaf1b_Po31",
+ "interval": 300,
+ "inBpsRate": 1862.4876594267096,
+ "inPktsRate": 0.00011473185873493155,
+ "inPpsRate": 2.7009344704495084,
+ "outBpsRate": 1758.0044570479704,
+ "outPktsRate": 0.00010844978034772172,
+ "outPpsRate": 2.5686946869154013,
+ "lastUpdateTimestamp": 1710253726.4029949,
+ },
+ }
+ },
+ {
+ "interfaces": {
+ "Ethernet1/1": {
+ "name": "Ethernet1/1",
+ "forwardingModel": "routed",
+ "lineProtocolStatus": "up",
+ "interfaceStatus": "connected",
+ "hardware": "ethernet",
+ "interfaceAddress": [
+ {
+ "primaryIp": {"address": "10.255.255.1", "maskLen": 31},
+ "secondaryIps": {},
+ "secondaryIpsOrderedList": [],
+ "virtualIp": {"address": "0.0.0.0", "maskLen": 0},
+ "virtualSecondaryIps": {},
+ "virtualSecondaryIpsOrderedList": [],
+ "broadcastAddress": "255.255.255.255",
+ "dhcp": False,
+ }
+ ],
+ "physicalAddress": "aa:c1:ab:7e:76:36",
+ "burnedInAddress": "aa:c1:ab:7e:76:36",
+ "description": "P2P_LINK_TO_DC1-SPINE1_Ethernet1/1",
+ "bandwidth": 1000000000,
+ "mtu": 1500,
+ "l3MtuConfigured": True,
+ "l2Mru": 0,
+ "lastStatusChangeTimestamp": 1710234511.3085763,
+ "interfaceStatistics": {
+ "updateInterval": 300.0,
+ "inBitsRate": 2240.0023281094,
+ "inPktsRate": 3.8978070399448654,
+ "outBitsRate": 0.0,
+ "outPktsRate": 0.0,
+ },
+ "interfaceCounters": {
+ "inOctets": 5413008,
+ "inUcastPkts": 74693,
+ "inMulticastPkts": 643,
+ "inBroadcastPkts": 1,
+ "inDiscards": 0,
+ "inTotalPkts": 75337,
+ "outOctets": 0,
+ "outUcastPkts": 0,
+ "outMulticastPkts": 0,
+ "outBroadcastPkts": 0,
+ "outDiscards": 0,
+ "outTotalPkts": 0,
+ "linkStatusChanges": 2,
+ "totalInErrors": 0,
+ "inputErrorsDetail": {"runtFrames": 0, "giantFrames": 0, "fcsErrors": 0, "alignmentErrors": 0, "symbolErrors": 0, "rxPause": 0},
+ "totalOutErrors": 0,
+ "outputErrorsDetail": {"collisions": 0, "lateCollisions": 0, "deferredTransmissions": 0, "txPause": 0},
+ "counterRefreshTime": 1710253760.6489396,
+ },
+ "duplex": "duplexFull",
+ "autoNegotiate": "unknown",
+ "loopbackMode": "loopbackNone",
+ "lanes": 0,
+ },
+ "Port-Channel31": {
+ "name": "Port-Channel31",
+ "forwardingModel": "bridged",
+ "lineProtocolStatus": "up",
+ "interfaceStatus": "connected",
+ "hardware": "portChannel",
+ "interfaceAddress": [],
+ "physicalAddress": "aa:c1:ab:72:58:40",
+ "description": "MLAG_PEER_dc1-leaf1b_Po31",
+ "bandwidth": 2000000000,
+ "mtu": 9214,
+ "l3MtuConfigured": False,
+ "l2Mru": 0,
+ "lastStatusChangeTimestamp": 1710234510.1133935,
+ "interfaceStatistics": {
+ "updateInterval": 300.0,
+ "inBitsRate": 1854.287898883752,
+ "inPktsRate": 2.6902775246495665,
+ "outBitsRate": 1749.1141130864632,
+ "outPktsRate": 2.5565618978302362,
+ },
+ "interfaceCounters": {
+ "inOctets": 4475556,
+ "inUcastPkts": 48949,
+ "inMulticastPkts": 2579,
+ "inBroadcastPkts": 2,
+ "inDiscards": 0,
+ "inTotalPkts": 51530,
+ "outOctets": 4230011,
+ "outUcastPkts": 48982,
+ "outMulticastPkts": 6,
+ "outBroadcastPkts": 2,
+ "outDiscards": 0,
+ "outTotalPkts": 48990,
+ "linkStatusChanges": 2,
+ "totalInErrors": 0,
+ "totalOutErrors": 0,
+ "counterRefreshTime": 1710253760.6500373,
+ },
+ "memberInterfaces": {
+ "Ethernet3/1": {"bandwidth": 1000000000, "duplex": "duplexHalf"},
+ "Ethernet4/1": {"bandwidth": 1000000000, "duplex": "duplexFull"},
+ },
+ "fallbackEnabled": False,
+ "fallbackEnabledType": "fallbackNone",
+ },
+ }
+ },
+ ],
+ "inputs": {"threshold": 70.0},
+ "expected": {
+ "result": "error",
+ "messages": ["Interface Port-Channel31 or one of its member interfaces is not Full-Duplex. VerifyInterfaceUtilization has not been implemented."],
+ },
},
{
"name": "success",
@@ -58,8 +808,8 @@ Et4 5:00 0.0 99.9% 0 0.0 0.0% 0
"interfaceErrorCounters": {
"Ethernet1": {"inErrors": 0, "frameTooLongs": 0, "outErrors": 0, "frameTooShorts": 0, "fcsErrors": 0, "alignmentErrors": 0, "symbolErrors": 0},
"Ethernet6": {"inErrors": 0, "frameTooLongs": 0, "outErrors": 0, "frameTooShorts": 0, "fcsErrors": 0, "alignmentErrors": 0, "symbolErrors": 0},
- }
- }
+ },
+ },
],
"inputs": None,
"expected": {"result": "success"},
@@ -72,8 +822,8 @@ Et4 5:00 0.0 99.9% 0 0.0 0.0% 0
"interfaceErrorCounters": {
"Ethernet1": {"inErrors": 42, "frameTooLongs": 0, "outErrors": 0, "frameTooShorts": 0, "fcsErrors": 0, "alignmentErrors": 0, "symbolErrors": 0},
"Ethernet6": {"inErrors": 0, "frameTooLongs": 0, "outErrors": 0, "frameTooShorts": 0, "fcsErrors": 0, "alignmentErrors": 666, "symbolErrors": 0},
- }
- }
+ },
+ },
],
"inputs": None,
"expected": {
@@ -81,7 +831,7 @@ Et4 5:00 0.0 99.9% 0 0.0 0.0% 0
"messages": [
"The following interface(s) have non-zero error counters: [{'Ethernet1': {'inErrors': 42, 'frameTooLongs': 0, 'outErrors': 0, 'frameTooShorts': 0,"
" 'fcsErrors': 0, 'alignmentErrors': 0, 'symbolErrors': 0}}, {'Ethernet6': {'inErrors': 0, 'frameTooLongs': 0, 'outErrors': 0, 'frameTooShorts':"
- " 0, 'fcsErrors': 0, 'alignmentErrors': 666, 'symbolErrors': 0}}]"
+ " 0, 'fcsErrors': 0, 'alignmentErrors': 666, 'symbolErrors': 0}}]",
],
},
},
@@ -93,8 +843,8 @@ Et4 5:00 0.0 99.9% 0 0.0 0.0% 0
"interfaceErrorCounters": {
"Ethernet1": {"inErrors": 42, "frameTooLongs": 0, "outErrors": 10, "frameTooShorts": 0, "fcsErrors": 0, "alignmentErrors": 0, "symbolErrors": 0},
"Ethernet6": {"inErrors": 0, "frameTooLongs": 0, "outErrors": 0, "frameTooShorts": 0, "fcsErrors": 0, "alignmentErrors": 6, "symbolErrors": 10},
- }
- }
+ },
+ },
],
"inputs": None,
"expected": {
@@ -102,7 +852,7 @@ Et4 5:00 0.0 99.9% 0 0.0 0.0% 0
"messages": [
"The following interface(s) have non-zero error counters: [{'Ethernet1': {'inErrors': 42, 'frameTooLongs': 0, 'outErrors': 10, 'frameTooShorts': 0,"
" 'fcsErrors': 0, 'alignmentErrors': 0, 'symbolErrors': 0}}, {'Ethernet6': {'inErrors': 0, 'frameTooLongs': 0, 'outErrors': 0, 'frameTooShorts':"
- " 0, 'fcsErrors': 0, 'alignmentErrors': 6, 'symbolErrors': 10}}]"
+ " 0, 'fcsErrors': 0, 'alignmentErrors': 6, 'symbolErrors': 10}}]",
],
},
},
@@ -113,15 +863,15 @@ Et4 5:00 0.0 99.9% 0 0.0 0.0% 0
{
"interfaceErrorCounters": {
"Ethernet1": {"inErrors": 42, "frameTooLongs": 0, "outErrors": 2, "frameTooShorts": 0, "fcsErrors": 0, "alignmentErrors": 0, "symbolErrors": 0},
- }
- }
+ },
+ },
],
"inputs": None,
"expected": {
"result": "failure",
"messages": [
"The following interface(s) have non-zero error counters: [{'Ethernet1': {'inErrors': 42, 'frameTooLongs': 0, 'outErrors': 2, 'frameTooShorts': 0,"
- " 'fcsErrors': 0, 'alignmentErrors': 0, 'symbolErrors': 0}}]"
+ " 'fcsErrors': 0, 'alignmentErrors': 0, 'symbolErrors': 0}}]",
],
},
},
@@ -136,7 +886,7 @@ Et4 5:00 0.0 99.9% 0 0.0 0.0% 0
"Ethernet1": {"outDiscards": 0, "inDiscards": 0},
},
"outDiscardsTotal": 0,
- }
+ },
],
"inputs": None,
"expected": {"result": "success"},
@@ -152,14 +902,14 @@ Et4 5:00 0.0 99.9% 0 0.0 0.0% 0
"Ethernet1": {"outDiscards": 0, "inDiscards": 42},
},
"outDiscardsTotal": 0,
- }
+ },
],
"inputs": None,
"expected": {
"result": "failure",
"messages": [
"The following interfaces have non 0 discard counter(s): [{'Ethernet2': {'outDiscards': 42, 'inDiscards': 0}},"
- " {'Ethernet1': {'outDiscards': 0, 'inDiscards': 42}}]"
+ " {'Ethernet1': {'outDiscards': 0, 'inDiscards': 42}}]",
],
},
},
@@ -175,8 +925,8 @@ Et4 5:00 0.0 99.9% 0 0.0 0.0% 0
"Ethernet8": {
"linkStatus": "connected",
},
- }
- }
+ },
+ },
],
"inputs": None,
"expected": {"result": "success"},
@@ -193,8 +943,8 @@ Et4 5:00 0.0 99.9% 0 0.0 0.0% 0
"Ethernet8": {
"linkStatus": "errdisabled",
},
- }
- }
+ },
+ },
],
"inputs": None,
"expected": {"result": "failure", "messages": ["The following interfaces are in error disabled state: ['Management1', 'Ethernet8']"]},
@@ -208,8 +958,8 @@ Et4 5:00 0.0 99.9% 0 0.0 0.0% 0
"Ethernet8": {"interfaceStatus": "up", "description": "", "lineProtocolStatus": "up"},
"Ethernet2": {"interfaceStatus": "adminDown", "description": "", "lineProtocolStatus": "down"},
"Ethernet3": {"interfaceStatus": "up", "description": "", "lineProtocolStatus": "up"},
- }
- }
+ },
+ },
],
"inputs": {"interfaces": [{"name": "Ethernet2", "status": "adminDown"}, {"name": "Ethernet8", "status": "up"}, {"name": "Ethernet3", "status": "up"}]},
"expected": {"result": "success"},
@@ -257,8 +1007,8 @@ Et4 5:00 0.0 99.9% 0 0.0 0.0% 0
"Ethernet8": {"interfaceStatus": "up", "description": "", "lineProtocolStatus": "up"},
"Ethernet2": {"interfaceStatus": "adminDown", "description": "", "lineProtocolStatus": "down"},
"Ethernet3": {"interfaceStatus": "up", "description": "", "lineProtocolStatus": "up"},
- }
- }
+ },
+ },
],
"inputs": {"interfaces": [{"name": "ethernet2", "status": "adminDown"}, {"name": "ethernet8", "status": "up"}, {"name": "ethernet3", "status": "up"}]},
"expected": {"result": "success"},
@@ -272,8 +1022,8 @@ Et4 5:00 0.0 99.9% 0 0.0 0.0% 0
"Ethernet8": {"interfaceStatus": "up", "description": "", "lineProtocolStatus": "up"},
"Ethernet2": {"interfaceStatus": "adminDown", "description": "", "lineProtocolStatus": "down"},
"Ethernet3": {"interfaceStatus": "up", "description": "", "lineProtocolStatus": "up"},
- }
- }
+ },
+ },
],
"inputs": {"interfaces": [{"name": "eth2", "status": "adminDown"}, {"name": "et8", "status": "up"}, {"name": "et3", "status": "up"}]},
"expected": {"result": "success"},
@@ -285,8 +1035,8 @@ Et4 5:00 0.0 99.9% 0 0.0 0.0% 0
{
"interfaceDescriptions": {
"Port-Channel100": {"interfaceStatus": "up", "description": "", "lineProtocolStatus": "up"},
- }
- }
+ },
+ },
],
"inputs": {"interfaces": [{"name": "po100", "status": "up"}]},
"expected": {"result": "success"},
@@ -298,8 +1048,8 @@ Et4 5:00 0.0 99.9% 0 0.0 0.0% 0
{
"interfaceDescriptions": {
"Ethernet52/1.1963": {"interfaceStatus": "up", "description": "", "lineProtocolStatus": "up"},
- }
- }
+ },
+ },
],
"inputs": {"interfaces": [{"name": "Ethernet52/1.1963", "status": "up"}]},
"expected": {"result": "success"},
@@ -351,8 +1101,8 @@ Et4 5:00 0.0 99.9% 0 0.0 0.0% 0
"interfaceDescriptions": {
"Ethernet2": {"interfaceStatus": "up", "description": "", "lineProtocolStatus": "up"},
"Ethernet3": {"interfaceStatus": "up", "description": "", "lineProtocolStatus": "up"},
- }
- }
+ },
+ },
],
"inputs": {"interfaces": [{"name": "Ethernet2", "status": "up"}, {"name": "Ethernet8", "status": "up"}, {"name": "Ethernet3", "status": "up"}]},
"expected": {
@@ -369,8 +1119,8 @@ Et4 5:00 0.0 99.9% 0 0.0 0.0% 0
"Ethernet8": {"interfaceStatus": "down", "description": "", "lineProtocolStatus": "down"},
"Ethernet2": {"interfaceStatus": "up", "description": "", "lineProtocolStatus": "up"},
"Ethernet3": {"interfaceStatus": "up", "description": "", "lineProtocolStatus": "up"},
- }
- }
+ },
+ },
],
"inputs": {"interfaces": [{"name": "Ethernet2", "status": "up"}, {"name": "Ethernet8", "status": "up"}, {"name": "Ethernet3", "status": "up"}]},
"expected": {
@@ -387,8 +1137,8 @@ Et4 5:00 0.0 99.9% 0 0.0 0.0% 0
"Ethernet8": {"interfaceStatus": "up", "description": "", "lineProtocolStatus": "down"},
"Ethernet2": {"interfaceStatus": "up", "description": "", "lineProtocolStatus": "up"},
"Ethernet3": {"interfaceStatus": "up", "description": "", "lineProtocolStatus": "up"},
- }
- }
+ },
+ },
],
"inputs": {
"interfaces": [
@@ -454,9 +1204,9 @@ Et4 5:00 0.0 99.9% 0 0.0 0.0% 0
"active": True,
"reason": "",
"errdisabled": False,
- }
+ },
},
- }
+ },
],
"inputs": None,
"expected": {"result": "success"},
@@ -473,9 +1223,9 @@ Et4 5:00 0.0 99.9% 0 0.0 0.0% 0
"active": True,
"reason": "",
"errdisabled": False,
- }
+ },
},
- }
+ },
],
"inputs": None,
"expected": {"result": "failure", "messages": ["The following interfaces have none 0 storm-control drop counters {'Ethernet1': {'broadcast': 666}}"]},
@@ -496,9 +1246,9 @@ Et4 5:00 0.0 99.9% 0 0.0 0.0% 0
"inactivePorts": {},
"activePorts": {},
"inactiveLag": False,
- }
- }
- }
+ },
+ },
+ },
],
"inputs": None,
"expected": {"result": "success"},
@@ -519,9 +1269,9 @@ Et4 5:00 0.0 99.9% 0 0.0 0.0% 0
"inactivePorts": {"Ethernet8": {"reasonUnconfigured": "waiting for LACP response"}},
"activePorts": {},
"inactiveLag": False,
- }
- }
- }
+ },
+ },
+ },
],
"inputs": None,
"expected": {"result": "failure", "messages": ["The following port-channels have inactive port(s): ['Port-Channel42']"]},
@@ -543,12 +1293,12 @@ Et4 5:00 0.0 99.9% 0 0.0 0.0% 0
"lacpdusTxCount": 454,
"markersTxCount": 0,
"markersRxCount": 0,
- }
- }
- }
+ },
+ },
+ },
},
"orphanPorts": {},
- }
+ },
],
"inputs": None,
"expected": {"result": "success"},
@@ -570,17 +1320,17 @@ Et4 5:00 0.0 99.9% 0 0.0 0.0% 0
"lacpdusTxCount": 454,
"markersTxCount": 0,
"markersRxCount": 0,
- }
- }
- }
+ },
+ },
+ },
},
"orphanPorts": {},
- }
+ },
],
"inputs": None,
"expected": {
"result": "failure",
- "messages": ["The following port-channels have recieved illegal lacp packets on the following ports: [{'Port-Channel42': 'Ethernet8'}]"],
+ "messages": ["The following port-channels have received illegal LACP packets on the following ports: [{'Port-Channel42': 'Ethernet8'}]"],
},
},
{
@@ -605,8 +1355,16 @@ Et4 5:00 0.0 99.9% 0 0.0 0.0% 0
"lineProtocolStatus": "up",
"mtu": 65535,
},
- }
- }
+ # Checking not loopbacks are skipped
+ "Ethernet666": {
+ "name": "Ethernet666",
+ "interfaceStatus": "connected",
+ "interfaceAddress": {"ipAddr": {"maskLen": 32, "address": "6.6.6.6"}},
+ "ipv4Routable240": False,
+ "lineProtocolStatus": "up",
+ },
+ },
+ },
],
"inputs": {"number": 2},
"expected": {"result": "success"},
@@ -633,8 +1391,8 @@ Et4 5:00 0.0 99.9% 0 0.0 0.0% 0
"lineProtocolStatus": "down",
"mtu": 65535,
},
- }
- }
+ },
+ },
],
"inputs": {"number": 2},
"expected": {"result": "failure", "messages": ["The following Loopbacks are not up: ['Loopback666']"]},
@@ -653,8 +1411,8 @@ Et4 5:00 0.0 99.9% 0 0.0 0.0% 0
"lineProtocolStatus": "up",
"mtu": 65535,
},
- }
- }
+ },
+ },
],
"inputs": {"number": 2},
"expected": {"result": "failure", "messages": ["Found 1 Loopbacks when expecting 2"]},
@@ -672,9 +1430,9 @@ Et4 5:00 0.0 99.9% 0 0.0 0.0% 0
"ipv4Routable240": False,
"lineProtocolStatus": "up",
"mtu": 1500,
- }
- }
- }
+ },
+ },
+ },
],
"inputs": None,
"expected": {"result": "success"},
@@ -692,9 +1450,9 @@ Et4 5:00 0.0 99.9% 0 0.0 0.0% 0
"ipv4Routable240": False,
"lineProtocolStatus": "lowerLayerDown",
"mtu": 1500,
- }
- }
- }
+ },
+ },
+ },
],
"inputs": None,
"expected": {"result": "failure", "messages": ["The following SVIs are not up: ['Vlan42']"]},
@@ -766,7 +1524,7 @@ Et4 5:00 0.0 99.9% 0 0.0 0.0% 0
"l2Mru": 0,
},
},
- }
+ },
],
"inputs": {"mtu": 1500},
"expected": {"result": "success"},
@@ -838,7 +1596,7 @@ Et4 5:00 0.0 99.9% 0 0.0 0.0% 0
"l2Mru": 0,
},
},
- }
+ },
],
"inputs": {"mtu": 1500, "ignored_interfaces": ["Loopback", "Port-Channel", "Management", "Vxlan"], "specific_mtu": [{"Ethernet10": 1501}]},
"expected": {"result": "success"},
@@ -910,7 +1668,7 @@ Et4 5:00 0.0 99.9% 0 0.0 0.0% 0
"l2Mru": 0,
},
},
- }
+ },
],
"inputs": {"mtu": 1500},
"expected": {"result": "failure", "messages": ["Some interfaces do not have correct MTU configured:\n[{'Ethernet2': 1600}]"]},
@@ -921,8 +1679,8 @@ Et4 5:00 0.0 99.9% 0 0.0 0.0% 0
"eos_data": [
{
"interfaces": {
- "Ethernet2": {
- "name": "Ethernet2",
+ "Ethernet2/1": {
+ "name": "Ethernet2/1",
"forwardingModel": "routed",
"lineProtocolStatus": "up",
"interfaceStatus": "connected",
@@ -982,9 +1740,9 @@ Et4 5:00 0.0 99.9% 0 0.0 0.0% 0
"l2Mru": 0,
},
},
- }
+ },
],
- "inputs": {"mtu": 9214},
+ "inputs": {"mtu": 9214, "ignored_interfaces": ["Loopback", "Port-Channel", "Management", "Vxlan"], "specific_mtu": [{"Ethernet10": 9214}]},
"expected": {"result": "success"},
},
{
@@ -1054,7 +1812,7 @@ Et4 5:00 0.0 99.9% 0 0.0 0.0% 0
"l2Mru": 0,
},
},
- }
+ },
],
"inputs": {"mtu": 1500},
"expected": {"result": "failure", "messages": ["Some L2 interfaces do not have correct MTU configured:\n[{'Ethernet10': 9214}, {'Port-Channel2': 9214}]"]},
@@ -1084,8 +1842,8 @@ Et4 5:00 0.0 99.9% 0 0.0 0.0% 0
"directedBroadcastEnabled": False,
"maxMssIngress": 0,
"maxMssEgress": 0,
- }
- }
+ },
+ },
},
{
"interfaces": {
@@ -1108,8 +1866,8 @@ Et4 5:00 0.0 99.9% 0 0.0 0.0% 0
"directedBroadcastEnabled": False,
"maxMssIngress": 0,
"maxMssEgress": 0,
- }
- }
+ },
+ },
},
],
"inputs": {"interfaces": ["Ethernet1", "Ethernet2"]},
@@ -1140,8 +1898,8 @@ Et4 5:00 0.0 99.9% 0 0.0 0.0% 0
"directedBroadcastEnabled": False,
"maxMssIngress": 0,
"maxMssEgress": 0,
- }
- }
+ },
+ },
},
{
"interfaces": {
@@ -1164,8 +1922,8 @@ Et4 5:00 0.0 99.9% 0 0.0 0.0% 0
"directedBroadcastEnabled": False,
"maxMssIngress": 0,
"maxMssEgress": 0,
- }
- }
+ },
+ },
},
],
"inputs": {"interfaces": ["Ethernet1", "Ethernet2"]},
@@ -1408,4 +2166,279 @@ Et4 5:00 0.0 99.9% 0 0.0 0.0% 0
"inputs": {"mac_address": "00:1c:73:00:dc:01"},
"expected": {"result": "failure", "messages": ["IP virtual router MAC address `00:1c:73:00:dc:01` is not configured."]},
},
+ {
+ "name": "success",
+ "test": VerifyInterfacesSpeed,
+ "eos_data": [
+ {
+ "interfaces": {
+ "Ethernet1": {
+ "bandwidth": 1000000000,
+ "autoNegotiate": "unknown",
+ "duplex": "duplexFull",
+ "lanes": 2,
+ },
+ "Ethernet1/1/2": {
+ "bandwidth": 1000000000,
+ "autoNegotiate": "unknown",
+ "duplex": "duplexFull",
+ "lanes": 2,
+ },
+ "Ethernet3": {
+ "bandwidth": 100000000000,
+ "autoNegotiate": "success",
+ "duplex": "duplexFull",
+ "lanes": 8,
+ },
+ "Ethernet4": {
+ "bandwidth": 2500000000,
+ "autoNegotiate": "unknown",
+ "duplex": "duplexFull",
+ "lanes": 8,
+ },
+ }
+ }
+ ],
+ "inputs": {
+ "interfaces": [
+ {"name": "Ethernet1", "auto": False, "speed": 1},
+ {"name": "Ethernet1", "auto": False, "speed": 1, "lanes": 2},
+ {"name": "Ethernet1/1/2", "auto": False, "speed": 1},
+ {"name": "Ethernet3", "auto": True, "speed": 100},
+ {"name": "Ethernet3", "auto": True, "speed": 100, "lanes": 8},
+ {"name": "Ethernet3", "auto": True, "speed": 100},
+ {"name": "Ethernet4", "auto": False, "speed": 2.5},
+ ]
+ },
+ "expected": {"result": "success"},
+ },
+ {
+ "name": "failure-incorrect-speed",
+ "test": VerifyInterfacesSpeed,
+ "eos_data": [
+ {
+ "interfaces": {
+ "Ethernet1": {
+ "bandwidth": 100000000000,
+ "autoNegotiate": "unknown",
+ "duplex": "duplexFull",
+ "lanes": 2,
+ },
+ "Ethernet1/1/1": {
+ "bandwidth": 100000000000,
+ "autoNegotiate": "unknown",
+ "duplex": "duplexFull",
+ "lanes": 2,
+ },
+ "Ethernet3": {
+ "bandwidth": 10000000000,
+ "autoNegotiate": "success",
+ "duplex": "duplexFull",
+ "lanes": 8,
+ },
+ "Ethernet4": {
+ "bandwidth": 25000000000,
+ "autoNegotiate": "unknown",
+ "duplex": "duplexFull",
+ "lanes": 8,
+ },
+ }
+ }
+ ],
+ "inputs": {
+ "interfaces": [
+ {"name": "Ethernet1", "auto": False, "speed": 1},
+ {"name": "Ethernet1/1/1", "auto": False, "speed": 1},
+ {"name": "Ethernet3", "auto": True, "speed": 100},
+ {"name": "Ethernet4", "auto": False, "speed": 2.5},
+ ]
+ },
+ "expected": {
+ "result": "failure",
+ "messages": [
+ "For interface Ethernet1:\nExpected `1Gbps` as the speed, but found `100Gbps` instead.",
+ "For interface Ethernet1/1/1:\nExpected `1Gbps` as the speed, but found `100Gbps` instead.",
+ "For interface Ethernet3:\nExpected `100Gbps` as the speed, but found `10Gbps` instead.",
+ "For interface Ethernet4:\nExpected `2.5Gbps` as the speed, but found `25Gbps` instead.",
+ ],
+ },
+ },
+ {
+ "name": "failure-incorrect-mode",
+ "test": VerifyInterfacesSpeed,
+ "eos_data": [
+ {
+ "interfaces": {
+ "Ethernet1": {
+ "bandwidth": 1000000000,
+ "autoNegotiate": "unknown",
+ "duplex": "duplexHalf",
+ "lanes": 2,
+ },
+ "Ethernet1/2/2": {
+ "bandwidth": 1000000000,
+ "autoNegotiate": "unknown",
+ "duplex": "duplexHalf",
+ "lanes": 2,
+ },
+ "Ethernet3": {
+ "bandwidth": 100000000000,
+ "autoNegotiate": "success",
+ "duplex": "duplexHalf",
+ "lanes": 8,
+ },
+ "Ethernet4": {
+ "bandwidth": 2500000000,
+ "autoNegotiate": "unknown",
+ "duplex": "duplexHalf",
+ "lanes": 8,
+ },
+ }
+ }
+ ],
+ "inputs": {
+ "interfaces": [
+ {"name": "Ethernet1", "auto": False, "speed": 1},
+ {"name": "Ethernet1/2/2", "auto": False, "speed": 1},
+ {"name": "Ethernet3", "auto": True, "speed": 100},
+ {"name": "Ethernet3", "auto": True, "speed": 100, "lanes": 8},
+ {"name": "Ethernet4", "auto": False, "speed": 2.5},
+ ]
+ },
+ "expected": {
+ "result": "failure",
+ "messages": [
+ "For interface Ethernet1:\nExpected `duplexFull` as the duplex mode, but found `duplexHalf` instead.",
+ "For interface Ethernet1/2/2:\nExpected `duplexFull` as the duplex mode, but found `duplexHalf` instead.",
+ "For interface Ethernet3:\nExpected `duplexFull` as the duplex mode, but found `duplexHalf` instead.",
+ "For interface Ethernet3:\nExpected `duplexFull` as the duplex mode, but found `duplexHalf` instead.",
+ "For interface Ethernet4:\nExpected `duplexFull` as the duplex mode, but found `duplexHalf` instead.",
+ ],
+ },
+ },
+ {
+ "name": "failure-incorrect-lane",
+ "test": VerifyInterfacesSpeed,
+ "eos_data": [
+ {
+ "interfaces": {
+ "Ethernet1": {
+ "bandwidth": 1000000000,
+ "autoNegotiate": "unknown",
+ "duplex": "duplexFull",
+ "lanes": 4,
+ },
+ "Ethernet2": {
+ "bandwidth": 10000000000,
+ "autoNegotiate": "unknown",
+ "duplex": "duplexFull",
+ "lanes": 4,
+ },
+ "Ethernet3": {
+ "bandwidth": 100000000000,
+ "autoNegotiate": "success",
+ "duplex": "duplexFull",
+ "lanes": 4,
+ },
+ "Ethernet4": {
+ "bandwidth": 2500000000,
+ "autoNegotiate": "unknown",
+ "duplex": "duplexFull",
+ "lanes": 6,
+ },
+ "Ethernet4/1/1": {
+ "bandwidth": 2500000000,
+ "autoNegotiate": "unknown",
+ "duplex": "duplexFull",
+ "lanes": 6,
+ },
+ }
+ }
+ ],
+ "inputs": {
+ "interfaces": [
+ {"name": "Ethernet1", "auto": False, "speed": 1, "lanes": 2},
+ {"name": "Ethernet3", "auto": True, "speed": 100, "lanes": 8},
+ {"name": "Ethernet4", "auto": False, "speed": 2.5, "lanes": 4},
+ {"name": "Ethernet4/1/1", "auto": False, "speed": 2.5, "lanes": 4},
+ ]
+ },
+ "expected": {
+ "result": "failure",
+ "messages": [
+ "For interface Ethernet1:\nExpected `2` as the lanes, but found `4` instead.",
+ "For interface Ethernet3:\nExpected `8` as the lanes, but found `4` instead.",
+ "For interface Ethernet4:\nExpected `4` as the lanes, but found `6` instead.",
+ "For interface Ethernet4/1/1:\nExpected `4` as the lanes, but found `6` instead.",
+ ],
+ },
+ },
+ {
+ "name": "failure-all-type",
+ "test": VerifyInterfacesSpeed,
+ "eos_data": [
+ {
+ "interfaces": {
+ "Ethernet1": {
+ "bandwidth": 10000000000,
+ "autoNegotiate": "unknown",
+ "duplex": "duplexHalf",
+ "lanes": 4,
+ },
+ "Ethernet2/1/2": {
+ "bandwidth": 1000000000,
+ "autoNegotiate": "unknown",
+ "duplex": "duplexHalf",
+ "lanes": 2,
+ },
+ "Ethernet3": {
+ "bandwidth": 10000000000,
+ "autoNegotiate": "unknown",
+ "duplex": "duplexHalf",
+ "lanes": 6,
+ },
+ "Ethernet4": {
+ "bandwidth": 25000000000,
+ "autoNegotiate": "unknown",
+ "duplex": "duplexHalf",
+ "lanes": 4,
+ },
+ }
+ }
+ ],
+ "inputs": {
+ "interfaces": [
+ {"name": "Ethernet1", "auto": False, "speed": 1},
+ {"name": "Ethernet1", "auto": False, "speed": 1, "lanes": 2},
+ {"name": "Ethernet2/1/2", "auto": False, "speed": 10},
+ {"name": "Ethernet3", "auto": True, "speed": 1},
+ {"name": "Ethernet3", "auto": True, "speed": 100, "lanes": 8},
+ {"name": "Ethernet3", "auto": True, "speed": 100},
+ {"name": "Ethernet4", "auto": False, "speed": 2.5},
+ ]
+ },
+ "expected": {
+ "result": "failure",
+ "messages": [
+ "For interface Ethernet1:\nExpected `duplexFull` as the duplex mode, but found `duplexHalf` instead.\n"
+ "Expected `1Gbps` as the speed, but found `10Gbps` instead.",
+ "For interface Ethernet1:\nExpected `duplexFull` as the duplex mode, but found `duplexHalf` instead.\n"
+ "Expected `1Gbps` as the speed, but found `10Gbps` instead.\n"
+ "Expected `2` as the lanes, but found `4` instead.",
+ "For interface Ethernet2/1/2:\nExpected `duplexFull` as the duplex mode, but found `duplexHalf` instead.\n"
+ "Expected `10Gbps` as the speed, but found `1Gbps` instead.",
+ "For interface Ethernet3:\nExpected `success` as the auto negotiation, but found `unknown` instead.\n"
+ "Expected `duplexFull` as the duplex mode, but found `duplexHalf` instead.",
+ "For interface Ethernet3:\nExpected `success` as the auto negotiation, but found `unknown` instead.\n"
+ "Expected `duplexFull` as the duplex mode, but found `duplexHalf` instead.\n"
+ "Expected `100Gbps` as the speed, but found `10Gbps` instead.\n"
+ "Expected `8` as the lanes, but found `6` instead.",
+ "For interface Ethernet3:\nExpected `success` as the auto negotiation, but found `unknown` instead.\n"
+ "Expected `duplexFull` as the duplex mode, but found `duplexHalf` instead.\n"
+ "Expected `100Gbps` as the speed, but found `10Gbps` instead.",
+ "For interface Ethernet4:\nExpected `duplexFull` as the duplex mode, but found `duplexHalf` instead.\n"
+ "Expected `2.5Gbps` as the speed, but found `25Gbps` instead.",
+ ],
+ },
+ },
]
diff --git a/tests/units/anta_tests/test_lanz.py b/tests/units/anta_tests/test_lanz.py
index 932d1ac..bfbf6ae 100644
--- a/tests/units/anta_tests/test_lanz.py
+++ b/tests/units/anta_tests/test_lanz.py
@@ -1,7 +1,8 @@
# Copyright (c) 2023-2024 Arista Networks, Inc.
# Use of this source code is governed by the Apache License 2.0
# that can be found in the LICENSE file.
-"""Data for testing anta.tests.configuration"""
+"""Data for testing anta.tests.lanz."""
+
from __future__ import annotations
from typing import Any
@@ -15,7 +16,7 @@ DATA: list[dict[str, Any]] = [
"test": VerifyLANZ,
"eos_data": [{"lanzEnabled": True}],
"inputs": None,
- "expected": {"result": "success", "messages": ["LANZ is enabled"]},
+ "expected": {"result": "success"},
},
{
"name": "failure",
diff --git a/tests/units/anta_tests/test_logging.py b/tests/units/anta_tests/test_logging.py
index 8ac2323..d46c865 100644
--- a/tests/units/anta_tests/test_logging.py
+++ b/tests/units/anta_tests/test_logging.py
@@ -1,7 +1,8 @@
# Copyright (c) 2023-2024 Arista Networks, Inc.
# Use of this source code is governed by the Apache License 2.0
# that can be found in the LICENSE file.
-"""Data for testing anta.tests.logging"""
+"""Data for testing anta.tests.logging."""
+
from __future__ import annotations
from typing import Any
@@ -77,7 +78,7 @@ DATA: list[dict[str, Any]] = [
Logging to '10.22.10.93' port 514 in VRF MGMT via tcp
Logging to '10.22.10.94' port 911 in VRF MGMT via udp
- """
+ """,
],
"inputs": {"interface": "Management0", "vrf": "MGMT"},
"expected": {"result": "success"},
@@ -92,7 +93,7 @@ DATA: list[dict[str, Any]] = [
Logging to '10.22.10.93' port 514 in VRF MGMT via tcp
Logging to '10.22.10.94' port 911 in VRF MGMT via udp
- """
+ """,
],
"inputs": {"interface": "Management0", "vrf": "MGMT"},
"expected": {"result": "failure", "messages": ["Source-interface 'Management0' is not configured in VRF MGMT"]},
@@ -107,7 +108,7 @@ DATA: list[dict[str, Any]] = [
Logging to '10.22.10.93' port 514 in VRF MGMT via tcp
Logging to '10.22.10.94' port 911 in VRF MGMT via udp
- """
+ """,
],
"inputs": {"interface": "Management0", "vrf": "MGMT"},
"expected": {"result": "failure", "messages": ["Source-interface 'Management0' is not configured in VRF MGMT"]},
@@ -122,7 +123,7 @@ DATA: list[dict[str, Any]] = [
Logging to '10.22.10.93' port 514 in VRF MGMT via tcp
Logging to '10.22.10.94' port 911 in VRF MGMT via udp
- """
+ """,
],
"inputs": {"hosts": ["10.22.10.92", "10.22.10.93", "10.22.10.94"], "vrf": "MGMT"},
"expected": {"result": "success"},
@@ -137,7 +138,7 @@ DATA: list[dict[str, Any]] = [
Logging to '10.22.10.103' port 514 in VRF MGMT via tcp
Logging to '10.22.10.104' port 911 in VRF MGMT via udp
- """
+ """,
],
"inputs": {"hosts": ["10.22.10.92", "10.22.10.93", "10.22.10.94"], "vrf": "MGMT"},
"expected": {"result": "failure", "messages": ["Syslog servers ['10.22.10.93', '10.22.10.94'] are not configured in VRF MGMT"]},
@@ -152,7 +153,7 @@ DATA: list[dict[str, Any]] = [
Logging to '10.22.10.93' port 514 in VRF default via tcp
Logging to '10.22.10.94' port 911 in VRF default via udp
- """
+ """,
],
"inputs": {"hosts": ["10.22.10.92", "10.22.10.93", "10.22.10.94"], "vrf": "MGMT"},
"expected": {"result": "failure", "messages": ["Syslog servers ['10.22.10.93', '10.22.10.94'] are not configured in VRF MGMT"]},
@@ -205,7 +206,9 @@ DATA: list[dict[str, Any]] = [
"eos_data": [
"",
"2023-05-10T15:41:44.680813-05:00 NW-CORE.example.org ConfigAgent: %SYS-6-LOGMSG_INFO: "
- "Message from arista on command-api (10.22.1.107): ANTA VerifyLoggingTimestamp validation\n",
+ "Message from arista on command-api (10.22.1.107): ANTA VerifyLoggingTimestamp validation\n"
+ "2023-05-10T15:42:44.680813-05:00 NW-CORE.example.org ConfigAgent: %SYS-6-LOGMSG_INFO: "
+ "Other log\n",
],
"inputs": None,
"expected": {"result": "success"},
@@ -222,6 +225,16 @@ DATA: list[dict[str, Any]] = [
"expected": {"result": "failure", "messages": ["Logs are not generated with the appropriate timestamp format"]},
},
{
+ "name": "failure-no-matching-log",
+ "test": VerifyLoggingTimestamp,
+ "eos_data": [
+ "",
+ "May 10 13:54:22 NE-CORE.example.org ConfigAgent: %SYS-6-LOGMSG_INFO: Message from arista on command-api (10.22.1.107): BLAH\n",
+ ],
+ "inputs": None,
+ "expected": {"result": "failure", "messages": ["Logs are not generated with the appropriate timestamp format"]},
+ },
+ {
"name": "success",
"test": VerifyLoggingAccounting,
"eos_data": ["2023 May 10 15:50:31 arista command-api 10.22.1.107 stop service=shell priv-lvl=15 cmd=show aaa accounting logs | tail\n"],
@@ -246,7 +259,7 @@ DATA: list[dict[str, Any]] = [
"name": "failure",
"test": VerifyLoggingErrors,
"eos_data": [
- "Aug 2 19:57:42 DC1-LEAF1A Mlag: %FWK-3-SOCKET_CLOSE_REMOTE: Connection to Mlag (pid:27200) at tbt://192.168.0.1:4432/+n closed by peer (EOF)"
+ "Aug 2 19:57:42 DC1-LEAF1A Mlag: %FWK-3-SOCKET_CLOSE_REMOTE: Connection to Mlag (pid:27200) at tbt://192.168.0.1:4432/+n closed by peer (EOF)",
],
"inputs": None,
"expected": {"result": "failure", "messages": ["Device has reported syslog messages with a severity of ERRORS or higher"]},
diff --git a/tests/units/anta_tests/test_mlag.py b/tests/units/anta_tests/test_mlag.py
index 90f3c7a..ae8ff7c 100644
--- a/tests/units/anta_tests/test_mlag.py
+++ b/tests/units/anta_tests/test_mlag.py
@@ -1,9 +1,8 @@
# Copyright (c) 2023-2024 Arista Networks, Inc.
# Use of this source code is governed by the Apache License 2.0
# that can be found in the LICENSE file.
-"""
-Tests for anta.tests.mlag.py
-"""
+"""Tests for anta.tests.mlag.py."""
+
from __future__ import annotations
from typing import Any
@@ -25,7 +24,7 @@ DATA: list[dict[str, Any]] = [
"eos_data": [
{
"state": "disabled",
- }
+ },
],
"inputs": None,
"expected": {"result": "skipped", "messages": ["MLAG is disabled"]},
@@ -47,7 +46,7 @@ DATA: list[dict[str, Any]] = [
{
"state": "active",
"mlagPorts": {"Disabled": 0, "Configured": 0, "Inactive": 0, "Active-partial": 0, "Active-full": 1},
- }
+ },
],
"inputs": None,
"expected": {"result": "success"},
@@ -58,7 +57,7 @@ DATA: list[dict[str, Any]] = [
"eos_data": [
{
"state": "disabled",
- }
+ },
],
"inputs": None,
"expected": {"result": "skipped", "messages": ["MLAG is disabled"]},
@@ -70,7 +69,7 @@ DATA: list[dict[str, Any]] = [
{
"state": "active",
"mlagPorts": {"Disabled": 0, "Configured": 0, "Inactive": 0, "Active-partial": 1, "Active-full": 1},
- }
+ },
],
"inputs": None,
"expected": {
@@ -85,7 +84,7 @@ DATA: list[dict[str, Any]] = [
{
"state": "active",
"mlagPorts": {"Disabled": 0, "Configured": 0, "Inactive": 1, "Active-partial": 1, "Active-full": 1},
- }
+ },
],
"inputs": None,
"expected": {
@@ -106,7 +105,7 @@ DATA: list[dict[str, Any]] = [
"eos_data": [
{
"mlagActive": False,
- }
+ },
],
"inputs": None,
"expected": {"result": "skipped", "messages": ["MLAG is disabled"]},
@@ -117,7 +116,7 @@ DATA: list[dict[str, Any]] = [
"eos_data": [
{
"dummy": False,
- }
+ },
],
"inputs": None,
"expected": {"result": "error", "messages": ["Incorrect JSON response - 'mlagActive' state was not found"]},
@@ -131,7 +130,7 @@ DATA: list[dict[str, Any]] = [
"interfaceConfiguration": {},
"mlagActive": True,
"mlagConnected": True,
- }
+ },
],
"inputs": None,
"expected": {
@@ -140,7 +139,7 @@ DATA: list[dict[str, Any]] = [
"MLAG config-sanity returned inconsistencies: "
"{'globalConfiguration': {'mlag': {'globalParameters': "
"{'dual-primary-detection-delay': {'localValue': '0', 'peerValue': '200'}}}}, "
- "'interfaceConfiguration': {}}"
+ "'interfaceConfiguration': {}}",
],
},
},
@@ -153,7 +152,7 @@ DATA: list[dict[str, Any]] = [
"interfaceConfiguration": {"trunk-native-vlan mlag30": {"interface": {"Port-Channel30": {"localValue": "123", "peerValue": "3700"}}}},
"mlagActive": True,
"mlagConnected": True,
- }
+ },
],
"inputs": None,
"expected": {
@@ -162,7 +161,7 @@ DATA: list[dict[str, Any]] = [
"MLAG config-sanity returned inconsistencies: "
"{'globalConfiguration': {}, "
"'interfaceConfiguration': {'trunk-native-vlan mlag30': "
- "{'interface': {'Port-Channel30': {'localValue': '123', 'peerValue': '3700'}}}}}"
+ "{'interface': {'Port-Channel30': {'localValue': '123', 'peerValue': '3700'}}}}}",
],
},
},
@@ -179,7 +178,7 @@ DATA: list[dict[str, Any]] = [
"eos_data": [
{
"state": "disabled",
- }
+ },
],
"inputs": {"reload_delay": 300, "reload_delay_non_mlag": 330},
"expected": {"result": "skipped", "messages": ["MLAG is disabled"]},
@@ -202,7 +201,7 @@ DATA: list[dict[str, Any]] = [
"dualPrimaryMlagRecoveryDelay": 60,
"dualPrimaryNonMlagRecoveryDelay": 0,
"detail": {"dualPrimaryDetectionDelay": 200, "dualPrimaryAction": "none"},
- }
+ },
],
"inputs": {"detection_delay": 200, "errdisabled": False, "recovery_delay": 60, "recovery_delay_non_mlag": 0},
"expected": {"result": "success"},
@@ -213,7 +212,7 @@ DATA: list[dict[str, Any]] = [
"eos_data": [
{
"state": "disabled",
- }
+ },
],
"inputs": {"detection_delay": 200, "errdisabled": False, "recovery_delay": 60, "recovery_delay_non_mlag": 0},
"expected": {"result": "skipped", "messages": ["MLAG is disabled"]},
@@ -226,7 +225,7 @@ DATA: list[dict[str, Any]] = [
"state": "active",
"dualPrimaryDetectionState": "disabled",
"dualPrimaryPortsErrdisabled": False,
- }
+ },
],
"inputs": {"detection_delay": 200, "errdisabled": False, "recovery_delay": 60, "recovery_delay_non_mlag": 0},
"expected": {"result": "failure", "messages": ["Dual-primary detection is disabled"]},
@@ -242,7 +241,7 @@ DATA: list[dict[str, Any]] = [
"dualPrimaryMlagRecoveryDelay": 160,
"dualPrimaryNonMlagRecoveryDelay": 0,
"detail": {"dualPrimaryDetectionDelay": 300, "dualPrimaryAction": "none"},
- }
+ },
],
"inputs": {"detection_delay": 200, "errdisabled": False, "recovery_delay": 60, "recovery_delay_non_mlag": 0},
"expected": {
@@ -254,7 +253,7 @@ DATA: list[dict[str, Any]] = [
"'detail.dualPrimaryAction': 'none', "
"'dualPrimaryMlagRecoveryDelay': 160, "
"'dualPrimaryNonMlagRecoveryDelay': 0}"
- )
+ ),
],
},
},
@@ -269,7 +268,7 @@ DATA: list[dict[str, Any]] = [
"dualPrimaryMlagRecoveryDelay": 60,
"dualPrimaryNonMlagRecoveryDelay": 0,
"detail": {"dualPrimaryDetectionDelay": 200, "dualPrimaryAction": "none"},
- }
+ },
],
"inputs": {"detection_delay": 200, "errdisabled": True, "recovery_delay": 60, "recovery_delay_non_mlag": 0},
"expected": {
@@ -281,7 +280,7 @@ DATA: list[dict[str, Any]] = [
"'detail.dualPrimaryAction': 'none', "
"'dualPrimaryMlagRecoveryDelay': 60, "
"'dualPrimaryNonMlagRecoveryDelay': 0}"
- )
+ ),
],
},
},
diff --git a/tests/units/anta_tests/test_multicast.py b/tests/units/anta_tests/test_multicast.py
index 9276a9f..a52a1d2 100644
--- a/tests/units/anta_tests/test_multicast.py
+++ b/tests/units/anta_tests/test_multicast.py
@@ -1,7 +1,8 @@
# Copyright (c) 2023-2024 Arista Networks, Inc.
# Use of this source code is governed by the Apache License 2.0
# that can be found in the LICENSE file.
-"""Test inputs for anta.tests.multicast"""
+"""Test inputs for anta.tests.multicast."""
+
from __future__ import annotations
from typing import Any
@@ -44,7 +45,7 @@ DATA: list[dict[str, Any]] = [
"robustness": 2,
"immediateLeave": "enabled",
"reportFloodingSwitchPorts": [],
- }
+ },
],
"inputs": {"vlans": {1: True, 42: True}},
"expected": {"result": "success"},
@@ -67,12 +68,12 @@ DATA: list[dict[str, Any]] = [
"maxGroups": 65534,
"immediateLeave": "default",
"floodingTraffic": True,
- }
+ },
},
"robustness": 2,
"immediateLeave": "enabled",
"reportFloodingSwitchPorts": [],
- }
+ },
],
"inputs": {"vlans": {42: False}},
"expected": {"result": "success"},
@@ -100,7 +101,7 @@ DATA: list[dict[str, Any]] = [
"robustness": 2,
"immediateLeave": "enabled",
"reportFloodingSwitchPorts": [],
- }
+ },
],
"inputs": {"vlans": {1: False, 42: False}},
"expected": {"result": "failure", "messages": ["IGMP state for vlan 1 is enabled", "Supplied vlan 42 is not present on the device."]},
@@ -128,7 +129,7 @@ DATA: list[dict[str, Any]] = [
"robustness": 2,
"immediateLeave": "enabled",
"reportFloodingSwitchPorts": [],
- }
+ },
],
"inputs": {"vlans": {1: True}},
"expected": {"result": "failure", "messages": ["IGMP state for vlan 1 is disabled"]},
@@ -143,7 +144,7 @@ DATA: list[dict[str, Any]] = [
"robustness": 2,
"immediateLeave": "enabled",
"reportFloodingSwitchPorts": [],
- }
+ },
],
"inputs": {"enabled": True},
"expected": {"result": "success"},
@@ -155,7 +156,7 @@ DATA: list[dict[str, Any]] = [
{
"reportFlooding": "disabled",
"igmpSnoopingState": "disabled",
- }
+ },
],
"inputs": {"enabled": False},
"expected": {"result": "success"},
@@ -167,7 +168,7 @@ DATA: list[dict[str, Any]] = [
{
"reportFlooding": "disabled",
"igmpSnoopingState": "disabled",
- }
+ },
],
"inputs": {"enabled": True},
"expected": {"result": "failure", "messages": ["IGMP state is not valid: disabled"]},
diff --git a/tests/units/anta_tests/test_path_selection.py b/tests/units/anta_tests/test_path_selection.py
new file mode 100644
index 0000000..c5fb079
--- /dev/null
+++ b/tests/units/anta_tests/test_path_selection.py
@@ -0,0 +1,327 @@
+# Copyright (c) 2023-2024 Arista Networks, Inc.
+# Use of this source code is governed by the Apache License 2.0
+# that can be found in the LICENSE file.
+"""Tests for anta.tests.path_selection.py."""
+
+from __future__ import annotations
+
+from typing import Any
+
+from anta.tests.path_selection import VerifyPathsHealth, VerifySpecificPath
+from tests.lib.anta import test # noqa: F401; pylint: disable=W0611
+
+DATA: list[dict[str, Any]] = [
+ {
+ "name": "success",
+ "test": VerifyPathsHealth,
+ "eos_data": [
+ {
+ "dpsPeers": {
+ "10.255.0.1": {
+ "dpsGroups": {
+ "internet": {
+ "dpsPaths": {
+ "path3": {"state": "routeResolved", "dpsSessions": {"0": {"active": True}}},
+ },
+ },
+ "mpls": {
+ "dpsPaths": {
+ "path4": {"state": "ipsecEstablished", "dpsSessions": {"0": {"active": True}}},
+ },
+ },
+ },
+ },
+ "10.255.0.2": {
+ "dpsGroups": {
+ "internet": {
+ "dpsPaths": {
+ "path1": {"state": "ipsecEstablished", "dpsSessions": {"0": {"active": True}}},
+ },
+ },
+ "mpls": {
+ "dpsPaths": {
+ "path2": {"state": "routeResolved", "dpsSessions": {"0": {"active": True}}},
+ },
+ },
+ },
+ },
+ }
+ },
+ ],
+ "inputs": {},
+ "expected": {"result": "success"},
+ },
+ {
+ "name": "failure-no-peer",
+ "test": VerifyPathsHealth,
+ "eos_data": [
+ {"dpsPeers": {}},
+ ],
+ "inputs": {},
+ "expected": {"result": "failure", "messages": ["No path configured for router path-selection."]},
+ },
+ {
+ "name": "failure-not-established",
+ "test": VerifyPathsHealth,
+ "eos_data": [
+ {
+ "dpsPeers": {
+ "10.255.0.1": {
+ "dpsGroups": {
+ "internet": {
+ "dpsPaths": {
+ "path3": {"state": "ipsecPending", "dpsSessions": {"0": {"active": False}}},
+ },
+ },
+ "mpls": {
+ "dpsPaths": {
+ "path4": {"state": "ipsecPending", "dpsSessions": {"0": {"active": False}}},
+ },
+ },
+ },
+ },
+ "10.255.0.2": {
+ "dpsGroups": {
+ "internet": {
+ "dpsPaths": {
+ "path1": {"state": "ipsecEstablished", "dpsSessions": {"0": {"active": True}}},
+ },
+ },
+ "mpls": {
+ "dpsPaths": {
+ "path2": {"state": "ipsecPending", "dpsSessions": {"0": {"active": False}}},
+ },
+ },
+ },
+ },
+ }
+ },
+ ],
+ "inputs": {},
+ "expected": {
+ "result": "failure",
+ "messages": [
+ "Path state for peer 10.255.0.1 in path-group internet is `ipsecPending`.",
+ "Path state for peer 10.255.0.1 in path-group mpls is `ipsecPending`.",
+ "Path state for peer 10.255.0.2 in path-group mpls is `ipsecPending`.",
+ ],
+ },
+ },
+ {
+ "name": "failure-inactive",
+ "test": VerifyPathsHealth,
+ "eos_data": [
+ {
+ "dpsPeers": {
+ "10.255.0.1": {
+ "dpsGroups": {
+ "internet": {
+ "dpsPaths": {
+ "path3": {"state": "routeResolved", "dpsSessions": {"0": {"active": False}}},
+ },
+ },
+ "mpls": {
+ "dpsPaths": {
+ "path4": {"state": "routeResolved", "dpsSessions": {"0": {"active": False}}},
+ },
+ },
+ },
+ },
+ "10.255.0.2": {
+ "dpsGroups": {
+ "internet": {
+ "dpsPaths": {
+ "path1": {"state": "routeResolved", "dpsSessions": {"0": {"active": True}}},
+ },
+ },
+ "mpls": {
+ "dpsPaths": {
+ "path2": {"state": "routeResolved", "dpsSessions": {"0": {"active": False}}},
+ },
+ },
+ },
+ },
+ }
+ },
+ ],
+ "inputs": {},
+ "expected": {
+ "result": "failure",
+ "messages": [
+ "Telemetry state for peer 10.255.0.1 in path-group internet is `inactive`.",
+ "Telemetry state for peer 10.255.0.1 in path-group mpls is `inactive`.",
+ "Telemetry state for peer 10.255.0.2 in path-group mpls is `inactive`.",
+ ],
+ },
+ },
+ {
+ "name": "success",
+ "test": VerifySpecificPath,
+ "eos_data": [
+ {
+ "dpsPeers": {
+ "10.255.0.1": {
+ "dpsGroups": {
+ "internet": {
+ "dpsPaths": {
+ "path3": {
+ "state": "ipsecEstablished",
+ "source": "172.18.13.2",
+ "destination": "172.18.15.2",
+ "dpsSessions": {"0": {"active": True}},
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ {
+ "dpsPeers": {
+ "10.255.0.2": {
+ "dpsGroups": {
+ "mpls": {
+ "dpsPaths": {
+ "path2": {
+ "state": "ipsecEstablished",
+ "source": "172.18.3.2",
+ "destination": "172.18.5.2",
+ "dpsSessions": {"0": {"active": True}},
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ ],
+ "inputs": {
+ "paths": [
+ {"peer": "10.255.0.1", "path_group": "internet", "source_address": "172.18.3.2", "destination_address": "172.18.5.2"},
+ {"peer": "10.255.0.2", "path_group": "mpls", "source_address": "172.18.13.2", "destination_address": "172.18.15.2"},
+ ]
+ },
+ "expected": {"result": "success"},
+ },
+ {
+ "name": "failure-no-peer",
+ "test": VerifySpecificPath,
+ "eos_data": [
+ {"dpsPeers": {}},
+ {"dpsPeers": {}},
+ ],
+ "inputs": {
+ "paths": [
+ {"peer": "10.255.0.1", "path_group": "internet", "source_address": "172.18.3.2", "destination_address": "172.18.5.2"},
+ {"peer": "10.255.0.2", "path_group": "mpls", "source_address": "172.18.13.2", "destination_address": "172.18.15.2"},
+ ]
+ },
+ "expected": {
+ "result": "failure",
+ "messages": [
+ "Path `peer: 10.255.0.1 source: 172.18.3.2 destination: 172.18.5.2` is not configured for path-group `internet`.",
+ "Path `peer: 10.255.0.2 source: 172.18.13.2 destination: 172.18.15.2` is not configured for path-group `mpls`.",
+ ],
+ },
+ },
+ {
+ "name": "failure-not-established",
+ "test": VerifySpecificPath,
+ "eos_data": [
+ {
+ "dpsPeers": {
+ "10.255.0.1": {
+ "dpsGroups": {
+ "internet": {
+ "dpsPaths": {
+ "path3": {"state": "ipsecPending", "source": "172.18.3.2", "destination": "172.18.5.2", "dpsSessions": {"0": {"active": True}}}
+ }
+ }
+ }
+ }
+ }
+ },
+ {
+ "dpsPeers": {
+ "10.255.0.2": {
+ "dpsGroups": {
+ "mpls": {
+ "dpsPaths": {
+ "path4": {
+ "state": "ipsecPending",
+ "source": "172.18.13.2",
+ "destination": "172.18.15.2",
+ "dpsSessions": {"0": {"active": False}},
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ ],
+ "inputs": {
+ "paths": [
+ {"peer": "10.255.0.1", "path_group": "internet", "source_address": "172.18.3.2", "destination_address": "172.18.5.2"},
+ {"peer": "10.255.0.2", "path_group": "mpls", "source_address": "172.18.13.2", "destination_address": "172.18.15.2"},
+ ]
+ },
+ "expected": {
+ "result": "failure",
+ "messages": [
+ "Path state for `peer: 10.255.0.1 source: 172.18.3.2 destination: 172.18.5.2` in path-group internet is `ipsecPending`.",
+ "Path state for `peer: 10.255.0.2 source: 172.18.13.2 destination: 172.18.15.2` in path-group mpls is `ipsecPending`.",
+ ],
+ },
+ },
+ {
+ "name": "failure-inactive",
+ "test": VerifySpecificPath,
+ "eos_data": [
+ {
+ "dpsPeers": {
+ "10.255.0.1": {
+ "dpsGroups": {
+ "internet": {
+ "dpsPaths": {
+ "path3": {"state": "routeResolved", "source": "172.18.3.2", "destination": "172.18.5.2", "dpsSessions": {"0": {"active": False}}}
+ }
+ }
+ }
+ }
+ }
+ },
+ {
+ "dpsPeers": {
+ "10.255.0.2": {
+ "dpsGroups": {
+ "mpls": {
+ "dpsPaths": {
+ "path4": {
+ "state": "routeResolved",
+ "source": "172.18.13.2",
+ "destination": "172.18.15.2",
+ "dpsSessions": {"0": {"active": False}},
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ ],
+ "inputs": {
+ "paths": [
+ {"peer": "10.255.0.1", "path_group": "internet", "source_address": "172.18.3.2", "destination_address": "172.18.5.2"},
+ {"peer": "10.255.0.2", "path_group": "mpls", "source_address": "172.18.13.2", "destination_address": "172.18.15.2"},
+ ]
+ },
+ "expected": {
+ "result": "failure",
+ "messages": [
+ "Telemetry state for path `peer: 10.255.0.1 source: 172.18.3.2 destination: 172.18.5.2` in path-group internet is `inactive`.",
+ "Telemetry state for path `peer: 10.255.0.2 source: 172.18.13.2 destination: 172.18.15.2` in path-group mpls is `inactive`.",
+ ],
+ },
+ },
+]
diff --git a/tests/units/anta_tests/test_profiles.py b/tests/units/anta_tests/test_profiles.py
index c0ebb57..d58e987 100644
--- a/tests/units/anta_tests/test_profiles.py
+++ b/tests/units/anta_tests/test_profiles.py
@@ -1,9 +1,8 @@
# Copyright (c) 2023-2024 Arista Networks, Inc.
# Use of this source code is governed by the Apache License 2.0
# that can be found in the LICENSE file.
-"""
-Tests for anta.tests.profiles.py
-"""
+"""Tests for anta.tests.profiles.py."""
+
from __future__ import annotations
from typing import Any
@@ -30,7 +29,7 @@ DATA: list[dict[str, Any]] = [
"name": "success",
"test": VerifyTcamProfile,
"eos_data": [
- {"pmfProfiles": {"FixedSystem": {"config": "test", "configType": "System Profile", "status": "test", "mode": "tcam"}}, "lastProgrammingStatus": {}}
+ {"pmfProfiles": {"FixedSystem": {"config": "test", "configType": "System Profile", "status": "test", "mode": "tcam"}}, "lastProgrammingStatus": {}},
],
"inputs": {"profile": "test"},
"expected": {"result": "success"},
@@ -39,7 +38,7 @@ DATA: list[dict[str, Any]] = [
"name": "failure",
"test": VerifyTcamProfile,
"eos_data": [
- {"pmfProfiles": {"FixedSystem": {"config": "test", "configType": "System Profile", "status": "default", "mode": "tcam"}}, "lastProgrammingStatus": {}}
+ {"pmfProfiles": {"FixedSystem": {"config": "test", "configType": "System Profile", "status": "default", "mode": "tcam"}}, "lastProgrammingStatus": {}},
],
"inputs": {"profile": "test"},
"expected": {"result": "failure", "messages": ["Incorrect profile running on device: default"]},
diff --git a/tests/units/anta_tests/test_ptp.py b/tests/units/anta_tests/test_ptp.py
index 3969c97..8f4c77f 100644
--- a/tests/units/anta_tests/test_ptp.py
+++ b/tests/units/anta_tests/test_ptp.py
@@ -1,17 +1,19 @@
# Copyright (c) 2023-2024 Arista Networks, Inc.
# Use of this source code is governed by the Apache License 2.0
# that can be found in the LICENSE file.
-"""Data for testing anta.tests.configuration"""
+"""Data for testing anta.tests.ptp."""
+
from __future__ import annotations
from typing import Any
-from anta.tests.ptp import VerifyPtpStatus
+from anta.tests.ptp import VerifyPtpGMStatus, VerifyPtpLockStatus, VerifyPtpModeStatus, VerifyPtpOffset, VerifyPtpPortModeStatus
+from tests.lib.anta import test # noqa: F401; pylint: disable=W0611
DATA: list[dict[str, Any]] = [
{
"name": "success",
- "test": VerifyPtpStatus,
+ "test": VerifyPtpModeStatus,
"eos_data": [
{
"ptpMode": "ptpBoundaryClock",
@@ -34,9 +36,305 @@ DATA: list[dict[str, Any]] = [
},
{
"name": "failure",
- "test": VerifyPtpStatus,
+ "test": VerifyPtpModeStatus,
+ "eos_data": [{"ptpMode": "ptpDisabled", "ptpIntfSummaries": {}}],
+ "inputs": None,
+ "expected": {"result": "failure", "messages": ["The device is not configured as a PTP Boundary Clock: 'ptpDisabled'"]},
+ },
+ {
+ "name": "skipped",
+ "test": VerifyPtpModeStatus,
+ "eos_data": [{"ptpIntfSummaries": {}}],
+ "inputs": None,
+ "expected": {"result": "skipped", "messages": ["PTP is not configured"]},
+ },
+ {
+ "name": "success",
+ "test": VerifyPtpGMStatus,
+ "eos_data": [
+ {
+ "ptpMode": "ptpBoundaryClock",
+ "ptpProfile": "ptpDefaultProfile",
+ "ptpClockSummary": {
+ "clockIdentity": "0x00:1c:73:ff:ff:14:00:01",
+ "gmClockIdentity": "0xec:46:70:ff:fe:00:ff:a8",
+ "numberOfSlavePorts": 1,
+ "numberOfMasterPorts": 8,
+ "slavePort": "Ethernet27/1",
+ "slaveVlanId": 0,
+ "offsetFromMaster": -11,
+ "meanPathDelay": 105,
+ "stepsRemoved": 2,
+ "skew": 1.0000015265007687,
+ "lastSyncTime": 1708599750,
+ "currentPtpSystemTime": 1708599750,
+ },
+ }
+ ],
+ "inputs": {"gmid": "0xec:46:70:ff:fe:00:ff:a8"},
+ "expected": {"result": "success"},
+ },
+ {
+ "name": "failure",
+ "test": VerifyPtpGMStatus,
+ "eos_data": [
+ {
+ "ptpMode": "ptpBoundaryClock",
+ "ptpProfile": "ptpDefaultProfile",
+ "ptpClockSummary": {
+ "clockIdentity": "0x00:1c:73:ff:ff:0a:00:01",
+ "gmClockIdentity": "0x00:1c:73:ff:ff:0a:00:01",
+ "numberOfSlavePorts": 0,
+ "numberOfMasterPorts": 4,
+ "offsetFromMaster": 3,
+ "meanPathDelay": 496,
+ "stepsRemoved": 0,
+ "skew": 1.0000074628720317,
+ "lastSyncTime": 1708600129,
+ "currentPtpSystemTime": 1708600153,
+ },
+ }
+ ],
+ "inputs": {"gmid": "0xec:46:70:ff:fe:00:ff:a8"},
+ "expected": {
+ "result": "failure",
+ "messages": [
+ "The device is locked to the following Grandmaster: '0x00:1c:73:ff:ff:0a:00:01', which differ from the expected one.",
+ ],
+ },
+ },
+ {
+ "name": "skipped",
+ "test": VerifyPtpGMStatus,
+ "eos_data": [{"ptpIntfSummaries": {}}],
+ "inputs": {"gmid": "0xec:46:70:ff:fe:00:ff:a8"},
+ "expected": {"result": "skipped", "messages": ["PTP is not configured"]},
+ },
+ {
+ "name": "success",
+ "test": VerifyPtpLockStatus,
+ "eos_data": [
+ {
+ "ptpMode": "ptpBoundaryClock",
+ "ptpProfile": "ptpDefaultProfile",
+ "ptpClockSummary": {
+ "clockIdentity": "0x00:1c:73:ff:ff:14:00:01",
+ "gmClockIdentity": "0xec:46:70:ff:fe:00:ff:a8",
+ "numberOfSlavePorts": 1,
+ "numberOfMasterPorts": 8,
+ "slavePort": "Ethernet27/1",
+ "slaveVlanId": 0,
+ "offsetFromMaster": -11,
+ "meanPathDelay": 105,
+ "stepsRemoved": 2,
+ "skew": 1.0000015265007687,
+ "lastSyncTime": 1708599750,
+ "currentPtpSystemTime": 1708599750,
+ },
+ }
+ ],
+ "inputs": None,
+ "expected": {"result": "success"},
+ },
+ {
+ "name": "failure",
+ "test": VerifyPtpLockStatus,
+ "eos_data": [
+ {
+ "ptpMode": "ptpBoundaryClock",
+ "ptpProfile": "ptpDefaultProfile",
+ "ptpClockSummary": {
+ "clockIdentity": "0x00:1c:73:ff:ff:0a:00:01",
+ "gmClockIdentity": "0x00:1c:73:ff:ff:0a:00:01",
+ "numberOfSlavePorts": 0,
+ "numberOfMasterPorts": 4,
+ "offsetFromMaster": 3,
+ "meanPathDelay": 496,
+ "stepsRemoved": 0,
+ "skew": 1.0000074628720317,
+ "lastSyncTime": 1708600129,
+ "currentPtpSystemTime": 1708600286,
+ },
+ }
+ ],
+ "inputs": None,
+ "expected": {"result": "failure", "messages": ["The device lock is more than 60s old: 157s"]},
+ },
+ {
+ "name": "skipped",
+ "test": VerifyPtpLockStatus,
+ "eos_data": [{"ptpIntfSummaries": {}}],
+ "inputs": None,
+ "expected": {
+ "result": "skipped",
+ "messages": [
+ "PTP is not configured",
+ ],
+ },
+ },
+ {
+ "name": "success",
+ "test": VerifyPtpOffset,
+ "eos_data": [
+ {
+ "monitorEnabled": True,
+ "ptpMode": "ptpBoundaryClock",
+ "offsetFromMasterThreshold": 250,
+ "meanPathDelayThreshold": 1500,
+ "ptpMonitorData": [
+ {
+ "intf": "Ethernet27/1",
+ "realLastSyncTime": 1708599815611398400,
+ "lastSyncSeqId": 44413,
+ "offsetFromMaster": 2,
+ "meanPathDelay": 105,
+ "skew": 1.000001614,
+ },
+ {
+ "intf": "Ethernet27/1",
+ "realLastSyncTime": 1708599815486101500,
+ "lastSyncSeqId": 44412,
+ "offsetFromMaster": -13,
+ "meanPathDelay": 105,
+ "skew": 1.000001614,
+ },
+ ],
+ }
+ ],
+ "inputs": None,
+ "expected": {"result": "success"},
+ },
+ {
+ "name": "failure",
+ "test": VerifyPtpOffset,
+ "eos_data": [
+ {
+ "monitorEnabled": True,
+ "ptpMode": "ptpBoundaryClock",
+ "offsetFromMasterThreshold": 250,
+ "meanPathDelayThreshold": 1500,
+ "ptpMonitorData": [
+ {
+ "intf": "Ethernet27/1",
+ "realLastSyncTime": 1708599815611398400,
+ "lastSyncSeqId": 44413,
+ "offsetFromMaster": 1200,
+ "meanPathDelay": 105,
+ "skew": 1.000001614,
+ },
+ {
+ "intf": "Ethernet27/1",
+ "realLastSyncTime": 1708599815486101500,
+ "lastSyncSeqId": 44412,
+ "offsetFromMaster": -1300,
+ "meanPathDelay": 105,
+ "skew": 1.000001614,
+ },
+ ],
+ }
+ ],
+ "inputs": None,
+ "expected": {
+ "result": "failure",
+ "messages": [("The device timing offset from master is greater than +/- 1000ns: {'Ethernet27/1': [1200, -1300]}")],
+ },
+ },
+ {
+ "name": "skipped",
+ "test": VerifyPtpOffset,
+ "eos_data": [
+ {
+ "monitorEnabled": True,
+ "ptpMonitorData": [],
+ },
+ ],
+ "inputs": None,
+ "expected": {"result": "skipped", "messages": ["PTP is not configured"]},
+ },
+ {
+ "name": "success",
+ "test": VerifyPtpPortModeStatus,
+ "eos_data": [
+ {
+ "ptpMode": "ptpBoundaryClock",
+ "ptpProfile": "ptpDefaultProfile",
+ "ptpClockSummary": {
+ "clockIdentity": "0x00:1c:73:ff:ff:0a:00:01",
+ "gmClockIdentity": "0x00:1c:73:ff:ff:0a:00:01",
+ "numberOfSlavePorts": 0,
+ "numberOfMasterPorts": 4,
+ "offsetFromMaster": 0,
+ "meanPathDelay": 0,
+ "stepsRemoved": 0,
+ "skew": 1.0,
+ },
+ "ptpIntfSummaries": {
+ "Ethernet53": {
+ "interface": "Ethernet53",
+ "ptpIntfVlanSummaries": [
+ {
+ "vlanId": 0,
+ "portState": "psDisabled",
+ "delayMechanism": "e2e",
+ "transportMode": "ipv4",
+ "mpassEnabled": False,
+ "mpassStatus": "active",
+ }
+ ],
+ },
+ "Ethernet1": {
+ "interface": "Ethernet1",
+ "ptpIntfVlanSummaries": [
+ {"vlanId": 0, "portState": "psMaster", "delayMechanism": "e2e", "transportMode": "ipv4", "mpassEnabled": False, "mpassStatus": "active"}
+ ],
+ },
+ },
+ }
+ ],
+ "inputs": None,
+ "expected": {"result": "success"},
+ },
+ {
+ "name": "failure",
+ "test": VerifyPtpPortModeStatus,
"eos_data": [{"ptpIntfSummaries": {}}],
"inputs": None,
- "expected": {"result": "failure"},
+ "expected": {"result": "failure", "messages": ["No interfaces are PTP enabled"]},
+ },
+ {
+ "name": "failure",
+ "test": VerifyPtpPortModeStatus,
+ "eos_data": [
+ {
+ "ptpMode": "ptpBoundaryClock",
+ "ptpProfile": "ptpDefaultProfile",
+ "ptpClockSummary": {
+ "clockIdentity": "0x00:1c:73:ff:ff:0a:00:01",
+ "gmClockIdentity": "0x00:1c:73:ff:ff:0a:00:01",
+ "numberOfSlavePorts": 0,
+ "numberOfMasterPorts": 4,
+ "offsetFromMaster": 0,
+ "meanPathDelay": 0,
+ "stepsRemoved": 0,
+ "skew": 1.0,
+ },
+ "ptpIntfSummaries": {
+ "Ethernet53": {
+ "interface": "Ethernet53",
+ "ptpIntfVlanSummaries": [
+ {"vlanId": 0, "portState": "none", "delayMechanism": "e2e", "transportMode": "ipv4", "mpassEnabled": False, "mpassStatus": "active"}
+ ],
+ },
+ "Ethernet1": {
+ "interface": "Ethernet1",
+ "ptpIntfVlanSummaries": [
+ {"vlanId": 0, "portState": "none", "delayMechanism": "e2e", "transportMode": "ipv4", "mpassEnabled": False, "mpassStatus": "active"}
+ ],
+ },
+ },
+ }
+ ],
+ "inputs": None,
+ "expected": {"result": "failure", "messages": ["The following interface(s) are not in a valid PTP state: '['Ethernet53', 'Ethernet1']'"]},
},
]
diff --git a/tests/units/anta_tests/test_security.py b/tests/units/anta_tests/test_security.py
index 17fa04e..3a732bd 100644
--- a/tests/units/anta_tests/test_security.py
+++ b/tests/units/anta_tests/test_security.py
@@ -1,9 +1,8 @@
# Copyright (c) 2023-2024 Arista Networks, Inc.
# Use of this source code is governed by the Apache License 2.0
# that can be found in the LICENSE file.
-"""
-Tests for anta.tests.security.py
-"""
+"""Tests for anta.tests.security.py."""
+
from __future__ import annotations
from typing import Any
@@ -16,7 +15,9 @@ from anta.tests.security import (
VerifyAPISSLCertificate,
VerifyBannerLogin,
VerifyBannerMotd,
+ VerifyIPSecConnHealth,
VerifyIPv4ACL,
+ VerifySpecificIPSecConn,
VerifySSHIPv4Acl,
VerifySSHIPv6Acl,
VerifySSHStatus,
@@ -33,7 +34,14 @@ DATA: list[dict[str, Any]] = [
"expected": {"result": "success"},
},
{
- "name": "failure",
+ "name": "error-missing-ssh-status",
+ "test": VerifySSHStatus,
+ "eos_data": ["SSH per host connection limit is 20\nFIPS status: disabled\n\n"],
+ "inputs": None,
+ "expected": {"result": "error", "messages": ["Could not find SSH status in returned output."]},
+ },
+ {
+ "name": "failure-ssh-disabled",
"test": VerifySSHStatus,
"eos_data": ["SSHD status for Default VRF is enabled\nSSH connection limit is 50\nSSH per host connection limit is 20\nFIPS status: disabled\n\n"],
"inputs": None,
@@ -107,7 +115,7 @@ DATA: list[dict[str, Any]] = [
"unixSocketServer": {"configured": False, "running": False},
"sslProfile": {"name": "API_SSL_Profile", "configured": True, "state": "valid"},
"tlsProtocol": ["1.2"],
- }
+ },
],
"inputs": None,
"expected": {"result": "success"},
@@ -124,7 +132,7 @@ DATA: list[dict[str, Any]] = [
"unixSocketServer": {"configured": False, "running": False},
"sslProfile": {"name": "API_SSL_Profile", "configured": True, "state": "valid"},
"tlsProtocol": ["1.2"],
- }
+ },
],
"inputs": None,
"expected": {"result": "failure", "messages": ["eAPI HTTP server is enabled globally"]},
@@ -141,7 +149,7 @@ DATA: list[dict[str, Any]] = [
"unixSocketServer": {"configured": False, "running": False},
"sslProfile": {"name": "API_SSL_Profile", "configured": True, "state": "valid"},
"tlsProtocol": ["1.2"],
- }
+ },
],
"inputs": {"profile": "API_SSL_Profile"},
"expected": {"result": "success"},
@@ -157,7 +165,7 @@ DATA: list[dict[str, Any]] = [
"httpsServer": {"configured": True, "running": True, "port": 443},
"unixSocketServer": {"configured": False, "running": False},
"tlsProtocol": ["1.2"],
- }
+ },
],
"inputs": {"profile": "API_SSL_Profile"},
"expected": {"result": "failure", "messages": ["eAPI HTTPS server SSL profile (API_SSL_Profile) is not configured"]},
@@ -174,7 +182,7 @@ DATA: list[dict[str, Any]] = [
"unixSocketServer": {"configured": False, "running": False},
"sslProfile": {"name": "Wrong_SSL_Profile", "configured": True, "state": "valid"},
"tlsProtocol": ["1.2"],
- }
+ },
],
"inputs": {"profile": "API_SSL_Profile"},
"expected": {"result": "failure", "messages": ["eAPI HTTPS server SSL profile (API_SSL_Profile) is misconfigured or invalid"]},
@@ -573,6 +581,40 @@ DATA: list[dict[str, Any]] = [
},
},
{
+ "name": "error-wrong-input-rsa",
+ "test": VerifyAPISSLCertificate,
+ "eos_data": [],
+ "inputs": {
+ "certificates": [
+ {
+ "certificate_name": "ARISTA_ROOT_CA.crt",
+ "expiry_threshold": 30,
+ "common_name": "Arista Networks Internal IT Root Cert Authority",
+ "encryption_algorithm": "RSA",
+ "key_size": 256,
+ },
+ ]
+ },
+ "expected": {"result": "error", "messages": ["Allowed sizes are (2048, 3072, 4096)."]},
+ },
+ {
+ "name": "error-wrong-input-ecdsa",
+ "test": VerifyAPISSLCertificate,
+ "eos_data": [],
+ "inputs": {
+ "certificates": [
+ {
+ "certificate_name": "ARISTA_SIGNING_CA.crt",
+ "expiry_threshold": 30,
+ "common_name": "AristaIT-ICA ECDSA Issuing Cert Authority",
+ "encryption_algorithm": "ECDSA",
+ "key_size": 2048,
+ },
+ ]
+ },
+ "expected": {"result": "error", "messages": ["Allowed sizes are (256, 384, 512)."]},
+ },
+ {
"name": "success",
"test": VerifyBannerLogin,
"eos_data": [
@@ -897,4 +939,278 @@ DATA: list[dict[str, Any]] = [
],
},
},
+ {
+ "name": "success",
+ "test": VerifyIPSecConnHealth,
+ "eos_data": [
+ {
+ "connections": {
+ "default-172.18.3.2-172.18.5.2-srcUnused-0": {
+ "pathDict": {"path9": "Established"},
+ },
+ "default-100.64.3.2-100.64.5.2-srcUnused-0": {
+ "pathDict": {"path10": "Established"},
+ },
+ }
+ }
+ ],
+ "inputs": {},
+ "expected": {"result": "success"},
+ },
+ {
+ "name": "failure-no-connection",
+ "test": VerifyIPSecConnHealth,
+ "eos_data": [{"connections": {}}],
+ "inputs": {},
+ "expected": {"result": "failure", "messages": ["No IPv4 security connection configured."]},
+ },
+ {
+ "name": "failure-not-established",
+ "test": VerifyIPSecConnHealth,
+ "eos_data": [
+ {
+ "connections": {
+ "default-172.18.3.2-172.18.5.2-srcUnused-0": {
+ "pathDict": {"path9": "Idle"},
+ "saddr": "172.18.3.2",
+ "daddr": "172.18.2.2",
+ "tunnelNs": "default",
+ },
+ "Guest-100.64.3.2-100.64.5.2-srcUnused-0": {"pathDict": {"path10": "Idle"}, "saddr": "100.64.3.2", "daddr": "100.64.5.2", "tunnelNs": "Guest"},
+ }
+ }
+ ],
+ "inputs": {},
+ "expected": {
+ "result": "failure",
+ "messages": [
+ "The following IPv4 security connections are not established:\n"
+ "source:172.18.3.2 destination:172.18.2.2 vrf:default\n"
+ "source:100.64.3.2 destination:100.64.5.2 vrf:Guest."
+ ],
+ },
+ },
+ {
+ "name": "success-with-connection",
+ "test": VerifySpecificIPSecConn,
+ "eos_data": [
+ {
+ "connections": {
+ "Guest-172.18.3.2-172.18.2.2-srcUnused-0": {
+ "pathDict": {"path9": "Established"},
+ "saddr": "172.18.3.2",
+ "daddr": "172.18.2.2",
+ "tunnelNs": "Guest",
+ },
+ "Guest-100.64.3.2-100.64.2.2-srcUnused-0": {
+ "pathDict": {"path10": "Established"},
+ "saddr": "100.64.3.2",
+ "daddr": "100.64.2.2",
+ "tunnelNs": "Guest",
+ },
+ }
+ }
+ ],
+ "inputs": {
+ "ip_security_connections": [
+ {
+ "peer": "10.255.0.1",
+ "vrf": "Guest",
+ "connections": [
+ {"source_address": "100.64.3.2", "destination_address": "100.64.2.2"},
+ {"source_address": "172.18.3.2", "destination_address": "172.18.2.2"},
+ ],
+ },
+ ]
+ },
+ "expected": {"result": "success"},
+ },
+ {
+ "name": "success-without-connection",
+ "test": VerifySpecificIPSecConn,
+ "eos_data": [
+ {
+ "connections": {
+ "default-172.18.3.2-172.18.2.2-srcUnused-0": {
+ "pathDict": {"path9": "Established"},
+ "saddr": "172.18.3.2",
+ "daddr": "172.18.2.2",
+ "tunnelNs": "default",
+ },
+ "default-100.64.3.2-100.64.2.2-srcUnused-0": {"pathDict": {"path10": "Established"}, "saddr": "100.64.3.2", "daddr": "100.64.2.2"},
+ }
+ }
+ ],
+ "inputs": {
+ "ip_security_connections": [
+ {
+ "peer": "10.255.0.1",
+ "vrf": "default",
+ },
+ ]
+ },
+ "expected": {"result": "success"},
+ },
+ {
+ "name": "failure-no-connection",
+ "test": VerifySpecificIPSecConn,
+ "eos_data": [
+ {"connections": {}},
+ {
+ "connections": {
+ "DATA-172.18.3.2-172.18.2.2-srcUnused-0": {
+ "pathDict": {"path9": "Established"},
+ "saddr": "172.18.3.2",
+ "daddr": "172.18.2.2",
+ "tunnelNs": "DATA",
+ },
+ "DATA-100.64.3.2-100.64.2.2-srcUnused-0": {
+ "pathDict": {"path10": "Established"},
+ "saddr": "100.64.3.2",
+ "daddr": "100.64.2.2",
+ "tunnelNs": "DATA",
+ },
+ }
+ },
+ ],
+ "inputs": {
+ "ip_security_connections": [
+ {
+ "peer": "10.255.0.1",
+ "vrf": "default",
+ },
+ {
+ "peer": "10.255.0.2",
+ "vrf": "DATA",
+ "connections": [
+ {"source_address": "100.64.3.2", "destination_address": "100.64.2.2"},
+ {"source_address": "172.18.3.2", "destination_address": "172.18.2.2"},
+ ],
+ },
+ ]
+ },
+ "expected": {"result": "failure", "messages": ["No IPv4 security connection configured for peer `10.255.0.1`."]},
+ },
+ {
+ "name": "failure-not-established",
+ "test": VerifySpecificIPSecConn,
+ "eos_data": [
+ {
+ "connections": {
+ "default-172.18.3.2-172.18.5.2-srcUnused-0": {
+ "pathDict": {"path9": "Idle"},
+ "saddr": "172.18.3.2",
+ "daddr": "172.18.2.2",
+ "tunnelNs": "default",
+ },
+ "default-100.64.3.2-100.64.5.2-srcUnused-0": {
+ "pathDict": {"path10": "Idle"},
+ "saddr": "100.64.2.2",
+ "daddr": "100.64.1.2",
+ "tunnelNs": "default",
+ },
+ },
+ },
+ {
+ "connections": {
+ "MGMT-172.18.2.2-172.18.1.2-srcUnused-0": {"pathDict": {"path9": "Idle"}, "saddr": "172.18.2.2", "daddr": "172.18.1.2", "tunnelNs": "MGMT"},
+ "MGMT-100.64.2.2-100.64.1.2-srcUnused-0": {"pathDict": {"path10": "Idle"}, "saddr": "100.64.2.2", "daddr": "100.64.1.2", "tunnelNs": "MGMT"},
+ }
+ },
+ ],
+ "inputs": {
+ "ip_security_connections": [
+ {
+ "peer": "10.255.0.1",
+ "vrf": "default",
+ },
+ {
+ "peer": "10.255.0.2",
+ "vrf": "MGMT",
+ "connections": [
+ {"source_address": "100.64.2.2", "destination_address": "100.64.1.2"},
+ {"source_address": "172.18.2.2", "destination_address": "172.18.1.2"},
+ ],
+ },
+ ]
+ },
+ "expected": {
+ "result": "failure",
+ "messages": [
+ "Expected state of IPv4 security connection `source:172.18.3.2 destination:172.18.2.2 vrf:default` for peer `10.255.0.1` is `Established` "
+ "but found `Idle` instead.",
+ "Expected state of IPv4 security connection `source:100.64.2.2 destination:100.64.1.2 vrf:default` for peer `10.255.0.1` is `Established` "
+ "but found `Idle` instead.",
+ "Expected state of IPv4 security connection `source:100.64.2.2 destination:100.64.1.2 vrf:MGMT` for peer `10.255.0.2` is `Established` "
+ "but found `Idle` instead.",
+ "Expected state of IPv4 security connection `source:172.18.2.2 destination:172.18.1.2 vrf:MGMT` for peer `10.255.0.2` is `Established` "
+ "but found `Idle` instead.",
+ ],
+ },
+ },
+ {
+ "name": "failure-missing-connection",
+ "test": VerifySpecificIPSecConn,
+ "eos_data": [
+ {
+ "connections": {
+ "default-172.18.3.2-172.18.5.2-srcUnused-0": {
+ "pathDict": {"path9": "Idle"},
+ "saddr": "172.18.3.2",
+ "daddr": "172.18.2.2",
+ "tunnelNs": "default",
+ },
+ "default-100.64.3.2-100.64.5.2-srcUnused-0": {
+ "pathDict": {"path10": "Idle"},
+ "saddr": "100.64.3.2",
+ "daddr": "100.64.2.2",
+ "tunnelNs": "default",
+ },
+ },
+ },
+ {
+ "connections": {
+ "default-172.18.2.2-172.18.1.2-srcUnused-0": {
+ "pathDict": {"path9": "Idle"},
+ "saddr": "172.18.2.2",
+ "daddr": "172.18.1.2",
+ "tunnelNs": "default",
+ },
+ "default-100.64.2.2-100.64.1.2-srcUnused-0": {
+ "pathDict": {"path10": "Idle"},
+ "saddr": "100.64.2.2",
+ "daddr": "100.64.1.2",
+ "tunnelNs": "default",
+ },
+ }
+ },
+ ],
+ "inputs": {
+ "ip_security_connections": [
+ {
+ "peer": "10.255.0.1",
+ "vrf": "default",
+ },
+ {
+ "peer": "10.255.0.2",
+ "vrf": "default",
+ "connections": [
+ {"source_address": "100.64.4.2", "destination_address": "100.64.1.2"},
+ {"source_address": "172.18.4.2", "destination_address": "172.18.1.2"},
+ ],
+ },
+ ]
+ },
+ "expected": {
+ "result": "failure",
+ "messages": [
+ "Expected state of IPv4 security connection `source:172.18.3.2 destination:172.18.2.2 vrf:default` for peer `10.255.0.1` is `Established` "
+ "but found `Idle` instead.",
+ "Expected state of IPv4 security connection `source:100.64.3.2 destination:100.64.2.2 vrf:default` for peer `10.255.0.1` is `Established` "
+ "but found `Idle` instead.",
+ "IPv4 security connection `source:100.64.4.2 destination:100.64.1.2 vrf:default` for peer `10.255.0.2` is not found.",
+ "IPv4 security connection `source:172.18.4.2 destination:172.18.1.2 vrf:default` for peer `10.255.0.2` is not found.",
+ ],
+ },
+ },
]
diff --git a/tests/units/anta_tests/test_services.py b/tests/units/anta_tests/test_services.py
index dcd1ee2..61c44d0 100644
--- a/tests/units/anta_tests/test_services.py
+++ b/tests/units/anta_tests/test_services.py
@@ -1,9 +1,8 @@
# Copyright (c) 2023-2024 Arista Networks, Inc.
# Use of this source code is governed by the Apache License 2.0
# that can be found in the LICENSE file.
-"""
-Tests for anta.tests.services.py
-"""
+"""Tests for anta.tests.services.py."""
+
from __future__ import annotations
from typing import Any
@@ -128,10 +127,12 @@ DATA: list[dict[str, Any]] = [
"name": "success",
"test": VerifyErrdisableRecovery,
"eos_data": [
+ # Adding empty line on purpose to verify they are skipped
"""
Errdisable Reason Timer Status Timer Interval
------------------------------ ----------------- --------------
acl Enabled 300
+
bpduguard Enabled 300
arp-inspection Enabled 30
"""
diff --git a/tests/units/anta_tests/test_snmp.py b/tests/units/anta_tests/test_snmp.py
index 7009689..b4d3152 100644
--- a/tests/units/anta_tests/test_snmp.py
+++ b/tests/units/anta_tests/test_snmp.py
@@ -1,9 +1,8 @@
# Copyright (c) 2023-2024 Arista Networks, Inc.
# Use of this source code is governed by the Apache License 2.0
# that can be found in the LICENSE file.
-"""
-Tests for anta.tests.snmp.py
-"""
+"""Tests for anta.tests.snmp.py."""
+
from __future__ import annotations
from typing import Any
diff --git a/tests/units/anta_tests/test_software.py b/tests/units/anta_tests/test_software.py
index 6d39c04..e46f526 100644
--- a/tests/units/anta_tests/test_software.py
+++ b/tests/units/anta_tests/test_software.py
@@ -1,7 +1,8 @@
# Copyright (c) 2023-2024 Arista Networks, Inc.
# Use of this source code is governed by the Apache License 2.0
# that can be found in the LICENSE file.
-"""Test inputs for anta.tests.hardware"""
+"""Test inputs for anta.tests.hardware."""
+
from __future__ import annotations
from typing import Any
@@ -18,7 +19,7 @@ DATA: list[dict[str, Any]] = [
"modelName": "vEOS-lab",
"internalVersion": "4.27.0F-24305004.4270F",
"version": "4.27.0F",
- }
+ },
],
"inputs": {"versions": ["4.27.0F", "4.28.0F"]},
"expected": {"result": "success"},
@@ -31,7 +32,7 @@ DATA: list[dict[str, Any]] = [
"modelName": "vEOS-lab",
"internalVersion": "4.27.0F-24305004.4270F",
"version": "4.27.0F",
- }
+ },
],
"inputs": {"versions": ["4.27.1F"]},
"expected": {"result": "failure", "messages": ["device is running version \"4.27.0F\" not in expected versions: ['4.27.1F']"]},
@@ -52,7 +53,7 @@ DATA: list[dict[str, Any]] = [
"TerminAttr-core": {"release": "1", "version": "v1.17.0"},
},
},
- }
+ },
],
"inputs": {"versions": ["v1.17.0", "v1.18.1"]},
"expected": {"result": "success"},
@@ -73,11 +74,12 @@ DATA: list[dict[str, Any]] = [
"TerminAttr-core": {"release": "1", "version": "v1.17.0"},
},
},
- }
+ },
],
"inputs": {"versions": ["v1.17.1", "v1.18.1"]},
"expected": {"result": "failure", "messages": ["device is running TerminAttr version v1.17.0 and is not in the allowed list: ['v1.17.1', 'v1.18.1']"]},
},
+ # TODO: add a test with a real extension?
{
"name": "success-no-extensions",
"test": VerifyEOSExtensions,
@@ -89,6 +91,16 @@ DATA: list[dict[str, Any]] = [
"expected": {"result": "success"},
},
{
+ "name": "success-empty-extension",
+ "test": VerifyEOSExtensions,
+ "eos_data": [
+ {"extensions": {}, "extensionStoredDir": "flash:", "warnings": ["No extensions are available"]},
+ {"extensions": [""]},
+ ],
+ "inputs": None,
+ "expected": {"result": "success"},
+ },
+ {
"name": "failure",
"test": VerifyEOSExtensions,
"eos_data": [
diff --git a/tests/units/anta_tests/test_stp.py b/tests/units/anta_tests/test_stp.py
index 26f0b90..64a1168 100644
--- a/tests/units/anta_tests/test_stp.py
+++ b/tests/units/anta_tests/test_stp.py
@@ -1,9 +1,8 @@
# Copyright (c) 2023-2024 Arista Networks, Inc.
# Use of this source code is governed by the Apache License 2.0
# that can be found in the LICENSE file.
-"""
-Tests for anta.tests.stp.py
-"""
+"""Tests for anta.tests.stp.py."""
+
from __future__ import annotations
from typing import Any
@@ -84,8 +83,8 @@ DATA: list[dict[str, Any]] = [
"interfaces": {
"Ethernet10": {"bpduSent": 201, "bpduReceived": 0, "bpduTaggedError": 3, "bpduOtherError": 0, "bpduRateLimitCount": 0},
"Ethernet11": {"bpduSent": 99, "bpduReceived": 0, "bpduTaggedError": 0, "bpduOtherError": 6, "bpduRateLimitCount": 0},
- }
- }
+ },
+ },
],
"inputs": None,
"expected": {"result": "failure", "messages": ["The following interfaces have STP BPDU packet errors: ['Ethernet10', 'Ethernet11']"]},
@@ -145,7 +144,7 @@ DATA: list[dict[str, Any]] = [
"inputs": {"vlans": [10, 20]},
"expected": {
"result": "failure",
- "messages": ["The following VLAN(s) have interface(s) that are not in a fowarding state: [{'VLAN 10': ['Ethernet10']}, {'VLAN 20': ['Ethernet10']}]"],
+ "messages": ["The following VLAN(s) have interface(s) that are not in a forwarding state: [{'VLAN 10': ['Ethernet10']}, {'VLAN 20': ['Ethernet10']}]"],
},
},
{
@@ -162,7 +161,7 @@ DATA: list[dict[str, Any]] = [
"helloTime": 2.0,
"maxAge": 20,
"forwardDelay": 15,
- }
+ },
},
"VL20": {
"rootBridge": {
@@ -172,7 +171,7 @@ DATA: list[dict[str, Any]] = [
"helloTime": 2.0,
"maxAge": 20,
"forwardDelay": 15,
- }
+ },
},
"VL30": {
"rootBridge": {
@@ -182,10 +181,10 @@ DATA: list[dict[str, Any]] = [
"helloTime": 2.0,
"maxAge": 20,
"forwardDelay": 15,
- }
+ },
},
- }
- }
+ },
+ },
],
"inputs": {"priority": 32768, "instances": [10, 20]},
"expected": {"result": "success"},
@@ -204,7 +203,7 @@ DATA: list[dict[str, Any]] = [
"helloTime": 2.0,
"maxAge": 20,
"forwardDelay": 15,
- }
+ },
},
"VL20": {
"rootBridge": {
@@ -214,7 +213,7 @@ DATA: list[dict[str, Any]] = [
"helloTime": 2.0,
"maxAge": 20,
"forwardDelay": 15,
- }
+ },
},
"VL30": {
"rootBridge": {
@@ -224,10 +223,10 @@ DATA: list[dict[str, Any]] = [
"helloTime": 2.0,
"maxAge": 20,
"forwardDelay": 15,
- }
+ },
},
- }
- }
+ },
+ },
],
"inputs": {"priority": 32768},
"expected": {"result": "success"},
@@ -246,10 +245,10 @@ DATA: list[dict[str, Any]] = [
"helloTime": 2.0,
"maxAge": 20,
"forwardDelay": 15,
- }
- }
- }
- }
+ },
+ },
+ },
+ },
],
"inputs": {"priority": 16384, "instances": [0]},
"expected": {"result": "success"},
@@ -268,10 +267,10 @@ DATA: list[dict[str, Any]] = [
"helloTime": 2.0,
"maxAge": 20,
"forwardDelay": 15,
- }
- }
- }
- }
+ },
+ },
+ },
+ },
],
"inputs": {"priority": 32768, "instances": [0]},
"expected": {"result": "failure", "messages": ["Unsupported STP instance type: WRONG0"]},
@@ -297,7 +296,7 @@ DATA: list[dict[str, Any]] = [
"helloTime": 2.0,
"maxAge": 20,
"forwardDelay": 15,
- }
+ },
},
"VL20": {
"rootBridge": {
@@ -307,7 +306,7 @@ DATA: list[dict[str, Any]] = [
"helloTime": 2.0,
"maxAge": 20,
"forwardDelay": 15,
- }
+ },
},
"VL30": {
"rootBridge": {
@@ -317,10 +316,10 @@ DATA: list[dict[str, Any]] = [
"helloTime": 2.0,
"maxAge": 20,
"forwardDelay": 15,
- }
+ },
},
- }
- }
+ },
+ },
],
"inputs": {"priority": 32768, "instances": [10, 20, 30]},
"expected": {"result": "failure", "messages": ["The following instance(s) have the wrong STP root priority configured: ['VL20', 'VL30']"]},
diff --git a/tests/units/anta_tests/test_stun.py b/tests/units/anta_tests/test_stun.py
new file mode 100644
index 0000000..2c87365
--- /dev/null
+++ b/tests/units/anta_tests/test_stun.py
@@ -0,0 +1,176 @@
+# Copyright (c) 2023-2024 Arista Networks, Inc.
+# Use of this source code is governed by the Apache License 2.0
+# that can be found in the LICENSE file.
+"""Test inputs for anta.tests.stun.py."""
+
+from __future__ import annotations
+
+from typing import Any
+
+from anta.tests.stun import VerifyStunClient
+from tests.lib.anta import test # noqa: F401; pylint: disable=W0611
+
+DATA: list[dict[str, Any]] = [
+ {
+ "name": "success",
+ "test": VerifyStunClient,
+ "eos_data": [
+ {
+ "bindings": {
+ "000000010a64ff0100000000": {
+ "sourceAddress": {"ip": "100.64.3.2", "port": 4500},
+ "publicAddress": {"ip": "192.64.3.2", "port": 6006},
+ }
+ }
+ },
+ {
+ "bindings": {
+ "000000040a64ff0100000000": {
+ "sourceAddress": {"ip": "172.18.3.2", "port": 4500},
+ "publicAddress": {"ip": "192.18.3.2", "port": 6006},
+ }
+ }
+ },
+ {
+ "bindings": {
+ "000000040a64ff0100000000": {
+ "sourceAddress": {"ip": "172.18.4.2", "port": 4500},
+ "publicAddress": {"ip": "192.18.4.2", "port": 6006},
+ }
+ }
+ },
+ {
+ "bindings": {
+ "000000040a64ff0100000000": {
+ "sourceAddress": {"ip": "172.18.6.2", "port": 4500},
+ "publicAddress": {"ip": "192.18.6.2", "port": 6006},
+ }
+ }
+ },
+ ],
+ "inputs": {
+ "stun_clients": [
+ {"source_address": "100.64.3.2", "public_address": "192.64.3.2", "source_port": 4500, "public_port": 6006},
+ {"source_address": "172.18.3.2"},
+ {"source_address": "172.18.4.2", "source_port": 4500, "public_address": "192.18.4.2"},
+ {"source_address": "172.18.6.2", "source_port": 4500, "public_port": 6006},
+ ]
+ },
+ "expected": {"result": "success"},
+ },
+ {
+ "name": "failure-incorrect-public-ip",
+ "test": VerifyStunClient,
+ "eos_data": [
+ {
+ "bindings": {
+ "000000010a64ff0100000000": {
+ "sourceAddress": {"ip": "100.64.3.2", "port": 4500},
+ "publicAddress": {"ip": "192.64.3.2", "port": 6006},
+ }
+ }
+ },
+ {
+ "bindings": {
+ "000000040a64ff0100000000": {
+ "sourceAddress": {"ip": "172.18.3.2", "port": 4500},
+ "publicAddress": {"ip": "192.18.3.2", "port": 6006},
+ }
+ }
+ },
+ ],
+ "inputs": {
+ "stun_clients": [
+ {"source_address": "100.64.3.2", "public_address": "192.164.3.2", "source_port": 4500, "public_port": 6006},
+ {"source_address": "172.18.3.2", "public_address": "192.118.3.2", "source_port": 4500, "public_port": 6006},
+ ]
+ },
+ "expected": {
+ "result": "failure",
+ "messages": [
+ "For STUN source `100.64.3.2:4500`:\nExpected `192.164.3.2` as the public ip, but found `192.64.3.2` instead.",
+ "For STUN source `172.18.3.2:4500`:\nExpected `192.118.3.2` as the public ip, but found `192.18.3.2` instead.",
+ ],
+ },
+ },
+ {
+ "name": "failure-no-client",
+ "test": VerifyStunClient,
+ "eos_data": [
+ {"bindings": {}},
+ {"bindings": {}},
+ ],
+ "inputs": {
+ "stun_clients": [
+ {"source_address": "100.64.3.2", "public_address": "192.164.3.2", "source_port": 4500, "public_port": 6006},
+ {"source_address": "172.18.3.2", "public_address": "192.118.3.2", "source_port": 4500, "public_port": 6006},
+ ]
+ },
+ "expected": {
+ "result": "failure",
+ "messages": ["STUN client transaction for source `100.64.3.2:4500` is not found.", "STUN client transaction for source `172.18.3.2:4500` is not found."],
+ },
+ },
+ {
+ "name": "failure-incorrect-public-port",
+ "test": VerifyStunClient,
+ "eos_data": [
+ {"bindings": {}},
+ {
+ "bindings": {
+ "000000040a64ff0100000000": {
+ "sourceAddress": {"ip": "172.18.3.2", "port": 4500},
+ "publicAddress": {"ip": "192.18.3.2", "port": 4800},
+ }
+ }
+ },
+ ],
+ "inputs": {
+ "stun_clients": [
+ {"source_address": "100.64.3.2", "public_address": "192.164.3.2", "source_port": 4500, "public_port": 6006},
+ {"source_address": "172.18.3.2", "public_address": "192.118.3.2", "source_port": 4500, "public_port": 6006},
+ ]
+ },
+ "expected": {
+ "result": "failure",
+ "messages": [
+ "STUN client transaction for source `100.64.3.2:4500` is not found.",
+ "For STUN source `172.18.3.2:4500`:\n"
+ "Expected `192.118.3.2` as the public ip, but found `192.18.3.2` instead.\n"
+ "Expected `6006` as the public port, but found `4800` instead.",
+ ],
+ },
+ },
+ {
+ "name": "failure-all-type",
+ "test": VerifyStunClient,
+ "eos_data": [
+ {"bindings": {}},
+ {
+ "bindings": {
+ "000000040a64ff0100000000": {
+ "sourceAddress": {"ip": "172.18.3.2", "port": 4500},
+ "publicAddress": {"ip": "192.18.3.2", "port": 4800},
+ }
+ }
+ },
+ ],
+ "inputs": {
+ "stun_clients": [
+ {"source_address": "100.64.3.2", "public_address": "192.164.3.2", "source_port": 4500, "public_port": 6006},
+ {"source_address": "172.18.4.2", "public_address": "192.118.3.2", "source_port": 4800, "public_port": 6006},
+ ]
+ },
+ "expected": {
+ "result": "failure",
+ "messages": [
+ "STUN client transaction for source `100.64.3.2:4500` is not found.",
+ "For STUN source `172.18.4.2:4800`:\n"
+ "Expected `172.18.4.2` as the source ip, but found `172.18.3.2` instead.\n"
+ "Expected `4800` as the source port, but found `4500` instead.\n"
+ "Expected `192.118.3.2` as the public ip, but found `192.18.3.2` instead.\n"
+ "Expected `6006` as the public port, but found `4800` instead.",
+ ],
+ },
+ },
+]
diff --git a/tests/units/anta_tests/test_system.py b/tests/units/anta_tests/test_system.py
index 62260fa..6965461 100644
--- a/tests/units/anta_tests/test_system.py
+++ b/tests/units/anta_tests/test_system.py
@@ -1,7 +1,8 @@
# Copyright (c) 2023-2024 Arista Networks, Inc.
# Use of this source code is governed by the Apache License 2.0
# that can be found in the LICENSE file.
-"""Test inputs for anta.tests.system"""
+"""Test inputs for anta.tests.system."""
+
from __future__ import annotations
from typing import Any
@@ -46,10 +47,15 @@ DATA: list[dict[str, Any]] = [
"eos_data": [
{
"resetCauses": [
- {"recommendedAction": "No action necessary.", "description": "Reload requested by the user.", "timestamp": 1683186892.0, "debugInfoIsDir": False}
+ {
+ "recommendedAction": "No action necessary.",
+ "description": "Reload requested by the user.",
+ "timestamp": 1683186892.0,
+ "debugInfoIsDir": False,
+ },
],
"full": False,
- }
+ },
],
"inputs": None,
"expected": {"result": "success"},
@@ -61,10 +67,10 @@ DATA: list[dict[str, Any]] = [
"eos_data": [
{
"resetCauses": [
- {"recommendedAction": "No action necessary.", "description": "Reload after crash.", "timestamp": 1683186892.0, "debugInfoIsDir": False}
+ {"recommendedAction": "No action necessary.", "description": "Reload after crash.", "timestamp": 1683186892.0, "debugInfoIsDir": False},
],
"full": False,
- }
+ },
],
"inputs": None,
"expected": {"result": "failure", "messages": ["Reload cause is: 'Reload after crash.'"]},
@@ -125,7 +131,7 @@ EntityManager::doBackoff waiting for remote sysdb version ....ok
===> /var/log/agents/Acl-830 Fri Jul 7 15:07:00 2023 <===
===== Output from /usr/bin/Acl [] (PID=830) started Jul 7 15:06:10.871700 ===
EntityManager::doBackoff waiting for remote sysdb version ...................ok
-"""
+""",
],
"inputs": None,
"expected": {
@@ -158,9 +164,9 @@ EntityManager::doBackoff waiting for remote sysdb version ...................ok
"activeTime": 360,
"virtMem": "6644",
"sharedMem": "3996",
- }
+ },
},
- }
+ },
],
"inputs": None,
"expected": {"result": "success"},
@@ -185,9 +191,9 @@ EntityManager::doBackoff waiting for remote sysdb version ...................ok
"activeTime": 360,
"virtMem": "6644",
"sharedMem": "3996",
- }
+ },
},
- }
+ },
],
"inputs": None,
"expected": {"result": "failure", "messages": ["Device has reported a high CPU utilization: 75.2%"]},
@@ -203,7 +209,7 @@ EntityManager::doBackoff waiting for remote sysdb version ...................ok
"memTotal": 2004568,
"memFree": 879004,
"version": "4.27.3F",
- }
+ },
],
"inputs": None,
"expected": {"result": "success"},
@@ -219,7 +225,7 @@ EntityManager::doBackoff waiting for remote sysdb version ...................ok
"memTotal": 2004568,
"memFree": 89004,
"version": "4.27.3F",
- }
+ },
],
"inputs": None,
"expected": {"result": "failure", "messages": ["Device has reported a high memory usage: 95.56%"]},
@@ -233,7 +239,7 @@ EntityManager::doBackoff waiting for remote sysdb version ...................ok
none 294M 78M 217M 27% /
none 294M 78M 217M 27% /.overlay
/dev/loop0 461M 461M 0 100% /rootfs-i386
-"""
+""",
],
"inputs": None,
"expected": {"result": "success"},
@@ -247,7 +253,7 @@ none 294M 78M 217M 27% /.overlay
none 294M 78M 217M 27% /
none 294M 78M 217M 84% /.overlay
/dev/loop0 461M 461M 0 100% /rootfs-i386
-"""
+""",
],
"inputs": None,
"expected": {
@@ -264,7 +270,7 @@ none 294M 78M 217M 84% /.overlay
"eos_data": [
"""synchronised
poll interval unknown
-"""
+""",
],
"inputs": None,
"expected": {"result": "success"},
@@ -275,7 +281,7 @@ poll interval unknown
"eos_data": [
"""unsynchronised
poll interval unknown
-"""
+""",
],
"inputs": None,
"expected": {"result": "failure", "messages": ["The device is not synchronized with the configured NTP server(s): 'unsynchronised'"]},
diff --git a/tests/units/anta_tests/test_vlan.py b/tests/units/anta_tests/test_vlan.py
index 93398f6..53bf92f 100644
--- a/tests/units/anta_tests/test_vlan.py
+++ b/tests/units/anta_tests/test_vlan.py
@@ -1,9 +1,8 @@
# Copyright (c) 2023-2024 Arista Networks, Inc.
# Use of this source code is governed by the Apache License 2.0
# that can be found in the LICENSE file.
-"""
-Tests for anta.tests.vlan.py
-"""
+"""Tests for anta.tests.vlan.py."""
+
from __future__ import annotations
from typing import Any
diff --git a/tests/units/anta_tests/test_vxlan.py b/tests/units/anta_tests/test_vxlan.py
index 2a9a875..f450897 100644
--- a/tests/units/anta_tests/test_vxlan.py
+++ b/tests/units/anta_tests/test_vxlan.py
@@ -1,9 +1,8 @@
# Copyright (c) 2023-2024 Arista Networks, Inc.
# Use of this source code is governed by the Apache License 2.0
# that can be found in the LICENSE file.
-"""
-Tests for anta.tests.vxlan.py
-"""
+"""Tests for anta.tests.vxlan.py."""
+
from __future__ import annotations
from typing import Any
@@ -107,7 +106,7 @@ DATA: list[dict[str, Any]] = [
},
},
"warnings": [],
- }
+ },
],
"inputs": None,
"expected": {"result": "success"},
@@ -172,7 +171,7 @@ DATA: list[dict[str, Any]] = [
},
},
"warnings": ["Your configuration contains warnings. This does not mean misconfigurations. But you may wish to re-check your configurations."],
- }
+ },
],
"inputs": None,
"expected": {
@@ -184,7 +183,7 @@ DATA: list[dict[str, Any]] = [
"'No VLAN-VNI mapping in Vxlan1'}, {'name': 'Flood List', 'checkPass': False, 'hasWarning': True, 'detail': "
"'No VXLAN VLANs in Vxlan1'}, {'name': 'Routing', 'checkPass': True, 'hasWarning': False, 'detail': ''}, {'name': "
"'VNI VRF ACL', 'checkPass': True, 'hasWarning': False, 'detail': ''}, {'name': 'VRF-VNI Dynamic VLAN', 'checkPass': True, "
- "'hasWarning': False, 'detail': ''}, {'name': 'Decap VRF-VNI Map', 'checkPass': True, 'hasWarning': False, 'detail': ''}]}}"
+ "'hasWarning': False, 'detail': ''}, {'name': 'Decap VRF-VNI Map', 'checkPass': True, 'hasWarning': False, 'detail': ''}]}}",
],
},
},
@@ -203,12 +202,12 @@ DATA: list[dict[str, Any]] = [
"vxlanIntfs": {
"Vxlan1": {
"vniBindings": {
- "10020": {"vlan": 20, "dynamicVlan": False, "source": "static", "interfaces": {"Ethernet31": {"dot1q": 0}, "Vxlan1": {"dot1q": 20}}}
+ "10020": {"vlan": 20, "dynamicVlan": False, "source": "static", "interfaces": {"Ethernet31": {"dot1q": 0}, "Vxlan1": {"dot1q": 20}}},
},
"vniBindingsToVrf": {"500": {"vrfName": "PROD", "vlan": 1199, "source": "evpn"}},
- }
- }
- }
+ },
+ },
+ },
],
"inputs": {"bindings": {10020: 20, 500: 1199}},
"expected": {"result": "success"},
@@ -221,12 +220,12 @@ DATA: list[dict[str, Any]] = [
"vxlanIntfs": {
"Vxlan1": {
"vniBindings": {
- "10020": {"vlan": 20, "dynamicVlan": False, "source": "static", "interfaces": {"Ethernet31": {"dot1q": 0}, "Vxlan1": {"dot1q": 20}}}
+ "10020": {"vlan": 20, "dynamicVlan": False, "source": "static", "interfaces": {"Ethernet31": {"dot1q": 0}, "Vxlan1": {"dot1q": 20}}},
},
"vniBindingsToVrf": {"500": {"vrfName": "PROD", "vlan": 1199, "source": "evpn"}},
- }
- }
- }
+ },
+ },
+ },
],
"inputs": {"bindings": {10010: 10, 10020: 20, 500: 1199}},
"expected": {"result": "failure", "messages": ["The following VNI(s) have no binding: ['10010']"]},
@@ -239,12 +238,12 @@ DATA: list[dict[str, Any]] = [
"vxlanIntfs": {
"Vxlan1": {
"vniBindings": {
- "10020": {"vlan": 30, "dynamicVlan": False, "source": "static", "interfaces": {"Ethernet31": {"dot1q": 0}, "Vxlan1": {"dot1q": 20}}}
+ "10020": {"vlan": 30, "dynamicVlan": False, "source": "static", "interfaces": {"Ethernet31": {"dot1q": 0}, "Vxlan1": {"dot1q": 20}}},
},
"vniBindingsToVrf": {"500": {"vrfName": "PROD", "vlan": 1199, "source": "evpn"}},
- }
- }
- }
+ },
+ },
+ },
],
"inputs": {"bindings": {10020: 20, 500: 1199}},
"expected": {"result": "failure", "messages": ["The following VNI(s) have the wrong VLAN binding: [{'10020': 30}]"]},
@@ -257,12 +256,12 @@ DATA: list[dict[str, Any]] = [
"vxlanIntfs": {
"Vxlan1": {
"vniBindings": {
- "10020": {"vlan": 30, "dynamicVlan": False, "source": "static", "interfaces": {"Ethernet31": {"dot1q": 0}, "Vxlan1": {"dot1q": 20}}}
+ "10020": {"vlan": 30, "dynamicVlan": False, "source": "static", "interfaces": {"Ethernet31": {"dot1q": 0}, "Vxlan1": {"dot1q": 20}}},
},
"vniBindingsToVrf": {"500": {"vrfName": "PROD", "vlan": 1199, "source": "evpn"}},
- }
- }
- }
+ },
+ },
+ },
],
"inputs": {"bindings": {10010: 10, 10020: 20, 500: 1199}},
"expected": {
diff --git a/tests/units/cli/__init__.py b/tests/units/cli/__init__.py
index e772bee..1d4cf6c 100644
--- a/tests/units/cli/__init__.py
+++ b/tests/units/cli/__init__.py
@@ -1,3 +1,4 @@
# Copyright (c) 2023-2024 Arista Networks, Inc.
# Use of this source code is governed by the Apache License 2.0
# that can be found in the LICENSE file.
+"""Test anta.cli submodule."""
diff --git a/tests/units/cli/check/__init__.py b/tests/units/cli/check/__init__.py
index e772bee..a116af4 100644
--- a/tests/units/cli/check/__init__.py
+++ b/tests/units/cli/check/__init__.py
@@ -1,3 +1,4 @@
# Copyright (c) 2023-2024 Arista Networks, Inc.
# Use of this source code is governed by the Apache License 2.0
# that can be found in the LICENSE file.
+"""Test anta.cli.check submodule."""
diff --git a/tests/units/cli/check/test__init__.py b/tests/units/cli/check/test__init__.py
index a3a770b..2501dc8 100644
--- a/tests/units/cli/check/test__init__.py
+++ b/tests/units/cli/check/test__init__.py
@@ -1,30 +1,28 @@
# Copyright (c) 2023-2024 Arista Networks, Inc.
# Use of this source code is governed by the Apache License 2.0
# that can be found in the LICENSE file.
-"""
-Tests for anta.cli.check
-"""
+"""Tests for anta.cli.check."""
+
from __future__ import annotations
-from click.testing import CliRunner
+from typing import TYPE_CHECKING
from anta.cli import anta
from anta.cli.utils import ExitCode
+if TYPE_CHECKING:
+ from click.testing import CliRunner
+
def test_anta_check(click_runner: CliRunner) -> None:
- """
- Test anta check
- """
+ """Test anta check."""
result = click_runner.invoke(anta, ["check"])
assert result.exit_code == ExitCode.OK
assert "Usage: anta check" in result.output
def test_anta_check_help(click_runner: CliRunner) -> None:
- """
- Test anta check --help
- """
+ """Test anta check --help."""
result = click_runner.invoke(anta, ["check", "--help"])
assert result.exit_code == ExitCode.OK
assert "Usage: anta check" in result.output
diff --git a/tests/units/cli/check/test_commands.py b/tests/units/cli/check/test_commands.py
index 746b315..11c2b5f 100644
--- a/tests/units/cli/check/test_commands.py
+++ b/tests/units/cli/check/test_commands.py
@@ -1,9 +1,8 @@
# Copyright (c) 2023-2024 Arista Networks, Inc.
# Use of this source code is governed by the Apache License 2.0
# that can be found in the LICENSE file.
-"""
-Tests for anta.cli.check.commands
-"""
+"""Tests for anta.cli.check.commands."""
+
from __future__ import annotations
from pathlib import Path
@@ -21,7 +20,7 @@ DATA_DIR: Path = Path(__file__).parents[3].resolve() / "data"
@pytest.mark.parametrize(
- "catalog_path, expected_exit, expected_output",
+ ("catalog_path", "expected_exit", "expected_output"),
[
pytest.param("ghost_catalog.yml", ExitCode.USAGE_ERROR, "Error: Invalid value for '--catalog'", id="catalog does not exist"),
pytest.param("test_catalog_with_undefined_module.yml", ExitCode.USAGE_ERROR, "Test catalog is invalid!", id="catalog is not valid"),
@@ -29,9 +28,7 @@ DATA_DIR: Path = Path(__file__).parents[3].resolve() / "data"
],
)
def test_catalog(click_runner: CliRunner, catalog_path: Path, expected_exit: int, expected_output: str) -> None:
- """
- Test `anta check catalog -c catalog
- """
+ """Test `anta check catalog -c catalog."""
result = click_runner.invoke(anta, ["check", "catalog", "-c", str(DATA_DIR / catalog_path)])
assert result.exit_code == expected_exit
assert expected_output in result.output
diff --git a/tests/units/cli/debug/__init__.py b/tests/units/cli/debug/__init__.py
index e772bee..ccce49c 100644
--- a/tests/units/cli/debug/__init__.py
+++ b/tests/units/cli/debug/__init__.py
@@ -1,3 +1,4 @@
# Copyright (c) 2023-2024 Arista Networks, Inc.
# Use of this source code is governed by the Apache License 2.0
# that can be found in the LICENSE file.
+"""Test anta.cli.debug submodule."""
diff --git a/tests/units/cli/debug/test__init__.py b/tests/units/cli/debug/test__init__.py
index 062182d..fd3663f 100644
--- a/tests/units/cli/debug/test__init__.py
+++ b/tests/units/cli/debug/test__init__.py
@@ -1,30 +1,28 @@
# Copyright (c) 2023-2024 Arista Networks, Inc.
# Use of this source code is governed by the Apache License 2.0
# that can be found in the LICENSE file.
-"""
-Tests for anta.cli.debug
-"""
+"""Tests for anta.cli.debug."""
+
from __future__ import annotations
-from click.testing import CliRunner
+from typing import TYPE_CHECKING
from anta.cli import anta
from anta.cli.utils import ExitCode
+if TYPE_CHECKING:
+ from click.testing import CliRunner
+
def test_anta_debug(click_runner: CliRunner) -> None:
- """
- Test anta debug
- """
+ """Test anta debug."""
result = click_runner.invoke(anta, ["debug"])
assert result.exit_code == ExitCode.OK
assert "Usage: anta debug" in result.output
def test_anta_debug_help(click_runner: CliRunner) -> None:
- """
- Test anta debug --help
- """
+ """Test anta debug --help."""
result = click_runner.invoke(anta, ["debug", "--help"])
assert result.exit_code == ExitCode.OK
assert "Usage: anta debug" in result.output
diff --git a/tests/units/cli/debug/test_commands.py b/tests/units/cli/debug/test_commands.py
index 6d9ac29..039e09e 100644
--- a/tests/units/cli/debug/test_commands.py
+++ b/tests/units/cli/debug/test_commands.py
@@ -1,9 +1,8 @@
# Copyright (c) 2023-2024 Arista Networks, Inc.
# Use of this source code is governed by the Apache License 2.0
# that can be found in the LICENSE file.
-"""
-Tests for anta.cli.debug.commands
-"""
+"""Tests for anta.cli.debug.commands."""
+
from __future__ import annotations
from typing import TYPE_CHECKING, Literal
@@ -18,7 +17,7 @@ if TYPE_CHECKING:
@pytest.mark.parametrize(
- "command, ofmt, version, revision, device, failed",
+ ("command", "ofmt", "version", "revision", "device", "failed"),
[
pytest.param("show version", "json", None, None, "dummy", False, id="json command"),
pytest.param("show version", "text", None, None, "dummy", False, id="text command"),
@@ -26,14 +25,19 @@ if TYPE_CHECKING:
pytest.param("show version", None, "1", None, "dummy", False, id="version"),
pytest.param("show version", None, None, 3, "dummy", False, id="revision"),
pytest.param("undefined", None, None, None, "dummy", True, id="command fails"),
+ pytest.param("undefined", None, None, None, "doesnotexist", True, id="Device does not exist"),
],
)
def test_run_cmd(
- click_runner: CliRunner, command: str, ofmt: Literal["json", "text"], version: Literal["1", "latest"] | None, revision: int | None, device: str, failed: bool
+ click_runner: CliRunner,
+ command: str,
+ ofmt: Literal["json", "text"],
+ version: Literal["1", "latest"] | None,
+ revision: int | None,
+ device: str,
+ failed: bool,
) -> None:
- """
- Test `anta debug run-cmd`
- """
+ """Test `anta debug run-cmd`."""
# pylint: disable=too-many-arguments
cli_args = ["-l", "debug", "debug", "run-cmd", "--command", command, "--device", device]
diff --git a/tests/units/cli/exec/__init__.py b/tests/units/cli/exec/__init__.py
index e772bee..4ed48bc 100644
--- a/tests/units/cli/exec/__init__.py
+++ b/tests/units/cli/exec/__init__.py
@@ -1,3 +1,4 @@
# Copyright (c) 2023-2024 Arista Networks, Inc.
# Use of this source code is governed by the Apache License 2.0
# that can be found in the LICENSE file.
+"""Test anta.cli.exec submodule."""
diff --git a/tests/units/cli/exec/test__init__.py b/tests/units/cli/exec/test__init__.py
index f8ad365..124d4af 100644
--- a/tests/units/cli/exec/test__init__.py
+++ b/tests/units/cli/exec/test__init__.py
@@ -1,30 +1,28 @@
# Copyright (c) 2023-2024 Arista Networks, Inc.
# Use of this source code is governed by the Apache License 2.0
# that can be found in the LICENSE file.
-"""
-Tests for anta.cli.exec
-"""
+"""Tests for anta.cli.exec."""
+
from __future__ import annotations
-from click.testing import CliRunner
+from typing import TYPE_CHECKING
from anta.cli import anta
from anta.cli.utils import ExitCode
+if TYPE_CHECKING:
+ from click.testing import CliRunner
+
def test_anta_exec(click_runner: CliRunner) -> None:
- """
- Test anta exec
- """
+ """Test anta exec."""
result = click_runner.invoke(anta, ["exec"])
assert result.exit_code == ExitCode.OK
assert "Usage: anta exec" in result.output
def test_anta_exec_help(click_runner: CliRunner) -> None:
- """
- Test anta exec --help
- """
+ """Test anta exec --help."""
result = click_runner.invoke(anta, ["exec", "--help"])
assert result.exit_code == ExitCode.OK
assert "Usage: anta exec" in result.output
diff --git a/tests/units/cli/exec/test_commands.py b/tests/units/cli/exec/test_commands.py
index f96d7f6..4a72d63 100644
--- a/tests/units/cli/exec/test_commands.py
+++ b/tests/units/cli/exec/test_commands.py
@@ -1,9 +1,7 @@
# Copyright (c) 2023-2024 Arista Networks, Inc.
# Use of this source code is governed by the Apache License 2.0
# that can be found in the LICENSE file.
-"""
-Tests for anta.cli.exec.commands
-"""
+"""Tests for anta.cli.exec.commands."""
from __future__ import annotations
@@ -21,27 +19,21 @@ if TYPE_CHECKING:
def test_clear_counters_help(click_runner: CliRunner) -> None:
- """
- Test `anta exec clear-counters --help`
- """
+ """Test `anta exec clear-counters --help`."""
result = click_runner.invoke(clear_counters, ["--help"])
assert result.exit_code == 0
assert "Usage" in result.output
def test_snapshot_help(click_runner: CliRunner) -> None:
- """
- Test `anta exec snapshot --help`
- """
+ """Test `anta exec snapshot --help`."""
result = click_runner.invoke(snapshot, ["--help"])
assert result.exit_code == 0
assert "Usage" in result.output
def test_collect_tech_support_help(click_runner: CliRunner) -> None:
- """
- Test `anta exec collect-tech-support --help`
- """
+ """Test `anta exec collect-tech-support --help`."""
result = click_runner.invoke(collect_tech_support, ["--help"])
assert result.exit_code == 0
assert "Usage" in result.output
@@ -55,9 +47,7 @@ def test_collect_tech_support_help(click_runner: CliRunner) -> None:
],
)
def test_clear_counters(click_runner: CliRunner, tags: str | None) -> None:
- """
- Test `anta exec clear-counters`
- """
+ """Test `anta exec clear-counters`."""
cli_args = ["exec", "clear-counters"]
if tags is not None:
cli_args.extend(["--tags", tags])
@@ -69,7 +59,7 @@ COMMAND_LIST_PATH_FILE = Path(__file__).parent.parent.parent.parent / "data" / "
@pytest.mark.parametrize(
- "commands_path, tags",
+ ("commands_path", "tags"),
[
pytest.param(None, None, id="missing command list"),
pytest.param(Path("/I/do/not/exist"), None, id="wrong path for command_list"),
@@ -78,9 +68,7 @@ COMMAND_LIST_PATH_FILE = Path(__file__).parent.parent.parent.parent / "data" / "
],
)
def test_snapshot(tmp_path: Path, click_runner: CliRunner, commands_path: Path | None, tags: str | None) -> None:
- """
- Test `anta exec snapshot`
- """
+ """Test `anta exec snapshot`."""
cli_args = ["exec", "snapshot", "--output", str(tmp_path)]
# Need to mock datetetime
if commands_path is not None:
@@ -99,7 +87,7 @@ def test_snapshot(tmp_path: Path, click_runner: CliRunner, commands_path: Path |
@pytest.mark.parametrize(
- "output, latest, configure, tags",
+ ("output", "latest", "configure", "tags"),
[
pytest.param(None, None, False, None, id="no params"),
pytest.param("/tmp/dummy", None, False, None, id="with output"),
@@ -109,9 +97,7 @@ def test_snapshot(tmp_path: Path, click_runner: CliRunner, commands_path: Path |
],
)
def test_collect_tech_support(click_runner: CliRunner, output: str | None, latest: str | None, configure: bool | None, tags: str | None) -> None:
- """
- Test `anta exec collect-tech-support`
- """
+ """Test `anta exec collect-tech-support`."""
cli_args = ["exec", "collect-tech-support"]
if output is not None:
cli_args.extend(["--output", output])
diff --git a/tests/units/cli/exec/test_utils.py b/tests/units/cli/exec/test_utils.py
index 6df1c86..ad1a78a 100644
--- a/tests/units/cli/exec/test_utils.py
+++ b/tests/units/cli/exec/test_utils.py
@@ -1,9 +1,7 @@
# Copyright (c) 2023-2024 Arista Networks, Inc.
# Use of this source code is governed by the Apache License 2.0
# that can be found in the LICENSE file.
-"""
-Tests for anta.cli.exec.utils
-"""
+"""Tests for anta.cli.exec.utils."""
from __future__ import annotations
@@ -12,83 +10,97 @@ from unittest.mock import call, patch
import pytest
-from anta.cli.exec.utils import clear_counters_utils # , collect_commands, collect_scheduled_show_tech
-from anta.device import AntaDevice
-from anta.inventory import AntaInventory
+from anta.cli.exec.utils import (
+ clear_counters,
+)
from anta.models import AntaCommand
+# , collect_commands, collect_scheduled_show_tech
+
if TYPE_CHECKING:
- from pytest import LogCaptureFixture
+ from anta.device import AntaDevice
+ from anta.inventory import AntaInventory
-# TODO complete test cases
-@pytest.mark.asyncio
+# TODO: complete test cases
+@pytest.mark.asyncio()
@pytest.mark.parametrize(
- "inventory_state, per_device_command_output, tags",
+ ("inventory_state", "per_device_command_output", "tags"),
[
pytest.param(
- {"dummy": {"is_online": False}, "dummy2": {"is_online": False}, "dummy3": {"is_online": False}},
+ {
+ "dummy": {"is_online": False},
+ "dummy2": {"is_online": False},
+ "dummy3": {"is_online": False},
+ },
{},
None,
id="no_connected_device",
),
pytest.param(
- {"dummy": {"is_online": True, "hw_model": "cEOSLab"}, "dummy2": {"is_online": True, "hw_model": "vEOS-lab"}, "dummy3": {"is_online": False}},
+ {
+ "dummy": {"is_online": True, "hw_model": "cEOSLab"},
+ "dummy2": {"is_online": True, "hw_model": "vEOS-lab"},
+ "dummy3": {"is_online": False},
+ },
{},
None,
id="cEOSLab and vEOS-lab devices",
),
pytest.param(
- {"dummy": {"is_online": True}, "dummy2": {"is_online": True}, "dummy3": {"is_online": False}},
+ {
+ "dummy": {"is_online": True},
+ "dummy2": {"is_online": True},
+ "dummy3": {"is_online": False},
+ },
{"dummy": None}, # None means the command failed to collect
None,
id="device with error",
),
pytest.param(
- {"dummy": {"is_online": True}, "dummy2": {"is_online": True}, "dummy3": {"is_online": True}},
+ {
+ "dummy": {"is_online": True},
+ "dummy2": {"is_online": True},
+ "dummy3": {"is_online": True},
+ },
{},
["spine"],
id="tags",
),
],
)
-async def test_clear_counters_utils(
- caplog: LogCaptureFixture,
+async def test_clear_counters(
+ caplog: pytest.LogCaptureFixture,
test_inventory: AntaInventory,
inventory_state: dict[str, Any],
per_device_command_output: dict[str, Any],
- tags: list[str] | None,
+ tags: set[str] | None,
) -> None:
- """
- Test anta.cli.exec.utils.clear_counters_utils
- """
+ """Test anta.cli.exec.utils.clear_counters."""
async def mock_connect_inventory() -> None:
- """
- mocking connect_inventory coroutine
- """
+ """Mock connect_inventory coroutine."""
for name, device in test_inventory.items():
device.is_online = inventory_state[name].get("is_online", True)
device.established = inventory_state[name].get("established", device.is_online)
device.hw_model = inventory_state[name].get("hw_model", "dummy")
- async def dummy_collect(self: AntaDevice, command: AntaCommand) -> None:
- """
- mocking collect coroutine
- """
+ async def collect(self: AntaDevice, command: AntaCommand, *args: Any, **kwargs: Any) -> None: # noqa: ARG001, ANN401 #pylint: disable=unused-argument
+ """Mock collect coroutine."""
command.output = per_device_command_output.get(self.name, "")
# Need to patch the child device class
- with patch("anta.device.AsyncEOSDevice.collect", side_effect=dummy_collect, autospec=True) as mocked_collect, patch(
- "anta.inventory.AntaInventory.connect_inventory",
- side_effect=mock_connect_inventory,
- ) as mocked_connect_inventory:
- print(mocked_collect)
- mocked_collect.side_effect = dummy_collect
- await clear_counters_utils(test_inventory, tags=tags)
+ with (
+ patch("anta.device.AsyncEOSDevice.collect", side_effect=collect, autospec=True) as mocked_collect,
+ patch(
+ "anta.inventory.AntaInventory.connect_inventory",
+ side_effect=mock_connect_inventory,
+ ) as mocked_connect_inventory,
+ ):
+ await clear_counters(test_inventory, tags=tags)
mocked_connect_inventory.assert_awaited_once()
- devices_established = list(test_inventory.get_inventory(established_only=True, tags=tags).values())
+ devices_established = test_inventory.get_inventory(established_only=True, tags=tags).devices
if devices_established:
# Building the list of calls
calls = []
@@ -96,32 +108,30 @@ async def test_clear_counters_utils(
calls.append(
call(
device,
- **{
- "command": AntaCommand(
- command="clear counters",
- version="latest",
- revision=None,
- ofmt="json",
- output=per_device_command_output.get(device.name, ""),
- errors=[],
- )
- },
- )
+ command=AntaCommand(
+ command="clear counters",
+ version="latest",
+ revision=None,
+ ofmt="json",
+ output=per_device_command_output.get(device.name, ""),
+ errors=[],
+ ),
+ collection_id=None,
+ ),
)
if device.hw_model not in ["cEOSLab", "vEOS-lab"]:
calls.append(
call(
device,
- **{
- "command": AntaCommand(
- command="clear hardware counter drop",
- version="latest",
- revision=None,
- ofmt="json",
- output=per_device_command_output.get(device.name, ""),
- )
- },
- )
+ command=AntaCommand(
+ command="clear hardware counter drop",
+ version="latest",
+ revision=None,
+ ofmt="json",
+ output=per_device_command_output.get(device.name, ""),
+ ),
+ collection_id=None,
+ ),
)
mocked_collect.assert_has_awaits(calls)
# Check error
diff --git a/tests/units/cli/get/__init__.py b/tests/units/cli/get/__init__.py
index e772bee..5517ded 100644
--- a/tests/units/cli/get/__init__.py
+++ b/tests/units/cli/get/__init__.py
@@ -1,3 +1,4 @@
# Copyright (c) 2023-2024 Arista Networks, Inc.
# Use of this source code is governed by the Apache License 2.0
# that can be found in the LICENSE file.
+"""Test anta.cli.get submodule."""
diff --git a/tests/units/cli/get/test__init__.py b/tests/units/cli/get/test__init__.py
index b18ef88..1ef65c2 100644
--- a/tests/units/cli/get/test__init__.py
+++ b/tests/units/cli/get/test__init__.py
@@ -1,30 +1,28 @@
# Copyright (c) 2023-2024 Arista Networks, Inc.
# Use of this source code is governed by the Apache License 2.0
# that can be found in the LICENSE file.
-"""
-Tests for anta.cli.get
-"""
+"""Tests for anta.cli.get."""
+
from __future__ import annotations
-from click.testing import CliRunner
+from typing import TYPE_CHECKING
-from anta.cli import anta
+from anta.cli._main import anta
from anta.cli.utils import ExitCode
+if TYPE_CHECKING:
+ from click.testing import CliRunner
+
def test_anta_get(click_runner: CliRunner) -> None:
- """
- Test anta get
- """
+ """Test anta get."""
result = click_runner.invoke(anta, ["get"])
assert result.exit_code == ExitCode.OK
assert "Usage: anta get" in result.output
def test_anta_get_help(click_runner: CliRunner) -> None:
- """
- Test anta get --help
- """
+ """Test anta get --help."""
result = click_runner.invoke(anta, ["get", "--help"])
assert result.exit_code == ExitCode.OK
assert "Usage: anta get" in result.output
diff --git a/tests/units/cli/get/test_commands.py b/tests/units/cli/get/test_commands.py
index aa6dc4f..e0b17a0 100644
--- a/tests/units/cli/get/test_commands.py
+++ b/tests/units/cli/get/test_commands.py
@@ -1,9 +1,8 @@
# Copyright (c) 2023-2024 Arista Networks, Inc.
# Use of this source code is governed by the Apache License 2.0
# that can be found in the LICENSE file.
-"""
-Tests for anta.cli.get.commands
-"""
+"""Tests for anta.cli.get.commands."""
+
from __future__ import annotations
import filecmp
@@ -12,20 +11,20 @@ from typing import TYPE_CHECKING
from unittest.mock import ANY, patch
import pytest
-from cvprac.cvp_client import CvpClient
from cvprac.cvp_client_errors import CvpApiError
-from anta.cli import anta
+from anta.cli._main import anta
from anta.cli.utils import ExitCode
if TYPE_CHECKING:
from click.testing import CliRunner
+ from cvprac.cvp_client import CvpClient
DATA_DIR: Path = Path(__file__).parents[3].resolve() / "data"
@pytest.mark.parametrize(
- "cvp_container, cvp_connect_failure",
+ ("cvp_container", "cvp_connect_failure"),
[
pytest.param(None, False, id="all devices"),
pytest.param("custom_container", False, id="custom container"),
@@ -38,28 +37,46 @@ def test_from_cvp(
cvp_container: str | None,
cvp_connect_failure: bool,
) -> None:
- """
- Test `anta get from-cvp`
+ """Test `anta get from-cvp`.
This test verifies that username and password are NOT mandatory to run this command
"""
output: Path = tmp_path / "output.yml"
- cli_args = ["get", "from-cvp", "--output", str(output), "--host", "42.42.42.42", "--username", "anta", "--password", "anta"]
+ cli_args = [
+ "get",
+ "from-cvp",
+ "--output",
+ str(output),
+ "--host",
+ "42.42.42.42",
+ "--username",
+ "anta",
+ "--password",
+ "anta",
+ ]
if cvp_container is not None:
cli_args.extend(["--container", cvp_container])
- def mock_cvp_connect(self: CvpClient, *args: str, **kwargs: str) -> None:
- # pylint: disable=unused-argument
+ def mock_cvp_connect(_self: CvpClient, *_args: str, **_kwargs: str) -> None:
if cvp_connect_failure:
raise CvpApiError(msg="mocked CvpApiError")
# always get a token
- with patch("anta.cli.get.commands.get_cv_token", return_value="dummy_token"), patch(
- "cvprac.cvp_client.CvpClient.connect", autospec=True, side_effect=mock_cvp_connect
- ) as mocked_cvp_connect, patch("cvprac.cvp_client.CvpApi.get_inventory", autospec=True, return_value=[]) as mocked_get_inventory, patch(
- "cvprac.cvp_client.CvpApi.get_devices_in_container", autospec=True, return_value=[]
- ) as mocked_get_devices_in_container:
+ with (
+ patch("anta.cli.get.commands.get_cv_token", return_value="dummy_token"),
+ patch(
+ "cvprac.cvp_client.CvpClient.connect",
+ autospec=True,
+ side_effect=mock_cvp_connect,
+ ) as mocked_cvp_connect,
+ patch("cvprac.cvp_client.CvpApi.get_inventory", autospec=True, return_value=[]) as mocked_get_inventory,
+ patch(
+ "cvprac.cvp_client.CvpApi.get_devices_in_container",
+ autospec=True,
+ return_value=[],
+ ) as mocked_get_devices_in_container,
+ ):
result = click_runner.invoke(anta, cli_args)
if not cvp_connect_failure:
@@ -79,12 +96,24 @@ def test_from_cvp(
@pytest.mark.parametrize(
- "ansible_inventory, ansible_group, expected_exit, expected_log",
+ ("ansible_inventory", "ansible_group", "expected_exit", "expected_log"),
[
pytest.param("ansible_inventory.yml", None, ExitCode.OK, None, id="no group"),
pytest.param("ansible_inventory.yml", "ATD_LEAFS", ExitCode.OK, None, id="group found"),
- pytest.param("ansible_inventory.yml", "DUMMY", ExitCode.USAGE_ERROR, "Group DUMMY not found in Ansible inventory", id="group not found"),
- pytest.param("empty_ansible_inventory.yml", None, ExitCode.USAGE_ERROR, "is empty", id="empty inventory"),
+ pytest.param(
+ "ansible_inventory.yml",
+ "DUMMY",
+ ExitCode.USAGE_ERROR,
+ "Group DUMMY not found in Ansible inventory",
+ id="group not found",
+ ),
+ pytest.param(
+ "empty_ansible_inventory.yml",
+ None,
+ ExitCode.USAGE_ERROR,
+ "is empty",
+ id="empty inventory",
+ ),
],
)
def test_from_ansible(
@@ -95,8 +124,8 @@ def test_from_ansible(
expected_exit: int,
expected_log: str | None,
) -> None:
- """
- Test `anta get from-ansible`
+ # pylint: disable=too-many-arguments
+ """Test `anta get from-ansible`.
This test verifies:
* the parsing of an ansible-inventory
@@ -107,7 +136,14 @@ def test_from_ansible(
output: Path = tmp_path / "output.yml"
ansible_inventory_path = DATA_DIR / ansible_inventory
# Init cli_args
- cli_args = ["get", "from-ansible", "--output", str(output), "--ansible-inventory", str(ansible_inventory_path)]
+ cli_args = [
+ "get",
+ "from-ansible",
+ "--output",
+ str(output),
+ "--ansible-inventory",
+ str(ansible_inventory_path),
+ ]
# Set --ansible-group
if ansible_group is not None:
@@ -122,14 +158,30 @@ def test_from_ansible(
assert expected_log in result.output
else:
assert output.exists()
- # TODO check size of generated inventory to validate the group functionality!
+ # TODO: check size of generated inventory to validate the group functionality!
@pytest.mark.parametrize(
- "env_set, overwrite, is_tty, prompt, expected_exit, expected_log",
+ ("env_set", "overwrite", "is_tty", "prompt", "expected_exit", "expected_log"),
[
- pytest.param(True, False, True, "y", ExitCode.OK, "", id="no-overwrite-tty-init-prompt-yes"),
- pytest.param(True, False, True, "N", ExitCode.INTERNAL_ERROR, "Aborted", id="no-overwrite-tty-init-prompt-no"),
+ pytest.param(
+ True,
+ False,
+ True,
+ "y",
+ ExitCode.OK,
+ "",
+ id="no-overwrite-tty-init-prompt-yes",
+ ),
+ pytest.param(
+ True,
+ False,
+ True,
+ "N",
+ ExitCode.INTERNAL_ERROR,
+ "Aborted",
+ id="no-overwrite-tty-init-prompt-no",
+ ),
pytest.param(
True,
False,
@@ -159,8 +211,7 @@ def test_from_ansible_overwrite(
expected_log: str | None,
) -> None:
# pylint: disable=too-many-arguments
- """
- Test `anta get from-ansible` overwrite mechanism
+ """Test `anta get from-ansible` overwrite mechanism.
The test uses a static ansible-inventory and output as these are tested in other functions
@@ -177,7 +228,12 @@ def test_from_ansible_overwrite(
ansible_inventory_path = DATA_DIR / "ansible_inventory.yml"
expected_anta_inventory_path = DATA_DIR / "expected_anta_inventory.yml"
tmp_output = tmp_path / "output.yml"
- cli_args = ["get", "from-ansible", "--ansible-inventory", str(ansible_inventory_path)]
+ cli_args = [
+ "get",
+ "from-ansible",
+ "--ansible-inventory",
+ str(ansible_inventory_path),
+ ]
if env_set:
tmp_inv = Path(str(temp_env["ANTA_INVENTORY"]))
diff --git a/tests/units/cli/get/test_utils.py b/tests/units/cli/get/test_utils.py
index b335880..7ce85dc 100644
--- a/tests/units/cli/get/test_utils.py
+++ b/tests/units/cli/get/test_utils.py
@@ -1,12 +1,11 @@
# Copyright (c) 2023-2024 Arista Networks, Inc.
# Use of this source code is governed by the Apache License 2.0
# that can be found in the LICENSE file.
-"""
-Tests for anta.cli.get.utils
-"""
+"""Tests for anta.cli.get.utils."""
+
from __future__ import annotations
-from contextlib import nullcontext
+from contextlib import AbstractContextManager, nullcontext
from pathlib import Path
from typing import Any
from unittest.mock import MagicMock, patch
@@ -21,10 +20,8 @@ DATA_DIR: Path = Path(__file__).parents[3].resolve() / "data"
def test_get_cv_token() -> None:
- """
- Test anta.get.utils.get_cv_token
- """
- ip = "42.42.42.42"
+ """Test anta.get.utils.get_cv_token."""
+ ip_addr = "42.42.42.42"
username = "ant"
password = "formica"
@@ -32,7 +29,7 @@ def test_get_cv_token() -> None:
mocked_ret = MagicMock(autospec=requests.Response)
mocked_ret.json.return_value = {"sessionId": "simple"}
patched_request.return_value = mocked_ret
- res = get_cv_token(ip, username, password)
+ res = get_cv_token(ip_addr, username, password)
patched_request.assert_called_once_with(
"POST",
"https://42.42.42.42/cvpservice/login/authenticate.do",
@@ -72,9 +69,7 @@ CVP_INVENTORY = [
],
)
def test_create_inventory_from_cvp(tmp_path: Path, inventory: list[dict[str, Any]]) -> None:
- """
- Test anta.get.utils.create_inventory_from_cvp
- """
+ """Test anta.get.utils.create_inventory_from_cvp."""
output = tmp_path / "output.yml"
create_inventory_from_cvp(inventory, output)
@@ -86,19 +81,63 @@ def test_create_inventory_from_cvp(tmp_path: Path, inventory: list[dict[str, Any
@pytest.mark.parametrize(
- "inventory_filename, ansible_group, expected_raise, expected_inv_length",
+ ("inventory_filename", "ansible_group", "expected_raise", "expected_log", "expected_inv_length"),
[
- pytest.param("ansible_inventory.yml", None, nullcontext(), 7, id="no group"),
- pytest.param("ansible_inventory.yml", "ATD_LEAFS", nullcontext(), 4, id="group found"),
- pytest.param("ansible_inventory.yml", "DUMMY", pytest.raises(ValueError, match="Group DUMMY not found in Ansible inventory"), 0, id="group not found"),
- pytest.param("empty_ansible_inventory.yml", None, pytest.raises(ValueError, match="Ansible inventory .* is empty"), 0, id="empty inventory"),
- pytest.param("wrong_ansible_inventory.yml", None, pytest.raises(ValueError, match="Could not parse"), 0, id="os error inventory"),
+ pytest.param("ansible_inventory.yml", None, nullcontext(), None, 7, id="no group"),
+ pytest.param("ansible_inventory.yml", "ATD_LEAFS", nullcontext(), None, 4, id="group found"),
+ pytest.param(
+ "ansible_inventory.yml",
+ "DUMMY",
+ pytest.raises(ValueError, match="Group DUMMY not found in Ansible inventory"),
+ None,
+ 0,
+ id="group not found",
+ ),
+ pytest.param(
+ "empty_ansible_inventory.yml",
+ None,
+ pytest.raises(ValueError, match="Ansible inventory .* is empty"),
+ None,
+ 0,
+ id="empty inventory",
+ ),
+ pytest.param(
+ "wrong_ansible_inventory.yml",
+ None,
+ pytest.raises(ValueError, match="Could not parse"),
+ None,
+ 0,
+ id="os error inventory",
+ ),
+ pytest.param(
+ "ansible_inventory_with_vault.yml",
+ None,
+ pytest.raises(ValueError, match="Could not parse"),
+ "`anta get from-ansible` does not support inline vaulted variables",
+ 0,
+ id="Vault variable in inventory",
+ ),
+ pytest.param(
+ "ansible_inventory_unknown_yaml_tag.yml",
+ None,
+ pytest.raises(ValueError, match="Could not parse"),
+ None,
+ 0,
+ id="Unknown YAML tag in inventory",
+ ),
],
)
-def test_create_inventory_from_ansible(tmp_path: Path, inventory_filename: Path, ansible_group: str | None, expected_raise: Any, expected_inv_length: int) -> None:
- """
- Test anta.get.utils.create_inventory_from_ansible
- """
+def test_create_inventory_from_ansible(
+ caplog: pytest.LogCaptureFixture,
+ tmp_path: Path,
+ inventory_filename: Path,
+ ansible_group: str | None,
+ expected_raise: AbstractContextManager[Exception],
+ expected_log: str | None,
+ expected_inv_length: int,
+) -> None:
+ """Test anta.get.utils.create_inventory_from_ansible."""
+ # pylint: disable=R0913
target_file = tmp_path / "inventory.yml"
inventory_file_path = DATA_DIR / inventory_filename
@@ -113,3 +152,5 @@ def test_create_inventory_from_ansible(tmp_path: Path, inventory_filename: Path,
assert len(inv) == expected_inv_length
if not isinstance(expected_raise, nullcontext):
assert not target_file.exists()
+ if expected_log:
+ assert expected_log in caplog.text
diff --git a/tests/units/cli/nrfu/__init__.py b/tests/units/cli/nrfu/__init__.py
index e772bee..db71b4d 100644
--- a/tests/units/cli/nrfu/__init__.py
+++ b/tests/units/cli/nrfu/__init__.py
@@ -1,3 +1,4 @@
# Copyright (c) 2023-2024 Arista Networks, Inc.
# Use of this source code is governed by the Apache License 2.0
# that can be found in the LICENSE file.
+"""Test anta.cli.nrfu submodule."""
diff --git a/tests/units/cli/nrfu/test__init__.py b/tests/units/cli/nrfu/test__init__.py
index fea641c..a9dcd9c 100644
--- a/tests/units/cli/nrfu/test__init__.py
+++ b/tests/units/cli/nrfu/test__init__.py
@@ -1,43 +1,56 @@
# Copyright (c) 2023-2024 Arista Networks, Inc.
# Use of this source code is governed by the Apache License 2.0
# that can be found in the LICENSE file.
-"""
-Tests for anta.cli.nrfu
-"""
+"""Tests for anta.cli.nrfu."""
+
from __future__ import annotations
-from click.testing import CliRunner
+from typing import TYPE_CHECKING
from anta.cli import anta
from anta.cli.utils import ExitCode
from tests.lib.utils import default_anta_env
+if TYPE_CHECKING:
+ from click.testing import CliRunner
+
# TODO: write unit tests for ignore-status and ignore-error
def test_anta_nrfu_help(click_runner: CliRunner) -> None:
- """
- Test anta nrfu --help
- """
+ """Test anta nrfu --help."""
result = click_runner.invoke(anta, ["nrfu", "--help"])
assert result.exit_code == ExitCode.OK
assert "Usage: anta nrfu" in result.output
+def test_anta_nrfu_wrong_subcommand(click_runner: CliRunner) -> None:
+ """Test anta nrfu toast."""
+ result = click_runner.invoke(anta, ["nrfu", "oook"])
+ assert result.exit_code == ExitCode.USAGE_ERROR
+ assert "Usage: anta nrfu" in result.output
+ assert "No such command 'oook'." in result.output
+
+
def test_anta_nrfu(click_runner: CliRunner) -> None:
- """
- Test anta nrfu, catalog is given via env
- """
+ """Test anta nrfu, catalog is given via env."""
result = click_runner.invoke(anta, ["nrfu"])
assert result.exit_code == ExitCode.OK
assert "ANTA Inventory contains 3 devices" in result.output
assert "Tests catalog contains 1 tests" in result.output
+def test_anta_nrfu_dry_run(click_runner: CliRunner) -> None:
+ """Test anta nrfu --dry-run, catalog is given via env."""
+ result = click_runner.invoke(anta, ["nrfu", "--dry-run"])
+ assert result.exit_code == ExitCode.OK
+ assert "ANTA Inventory contains 3 devices" in result.output
+ assert "Tests catalog contains 1 tests" in result.output
+ assert "Dry-run" in result.output
+
+
def test_anta_password_required(click_runner: CliRunner) -> None:
- """
- Test that password is provided
- """
+ """Test that password is provided."""
env = default_anta_env()
env["ANTA_PASSWORD"] = None
result = click_runner.invoke(anta, ["nrfu"], env=env)
@@ -47,9 +60,7 @@ def test_anta_password_required(click_runner: CliRunner) -> None:
def test_anta_password(click_runner: CliRunner) -> None:
- """
- Test that password can be provided either via --password or --prompt
- """
+ """Test that password can be provided either via --password or --prompt."""
env = default_anta_env()
env["ANTA_PASSWORD"] = None
result = click_runner.invoke(anta, ["nrfu", "--password", "secret"], env=env)
@@ -59,9 +70,7 @@ def test_anta_password(click_runner: CliRunner) -> None:
def test_anta_enable_password(click_runner: CliRunner) -> None:
- """
- Test that enable password can be provided either via --enable-password or --prompt
- """
+ """Test that enable password can be provided either via --enable-password or --prompt."""
# Both enable and enable-password
result = click_runner.invoke(anta, ["nrfu", "--enable", "--enable-password", "secret"])
assert result.exit_code == ExitCode.OK
@@ -78,7 +87,6 @@ def test_anta_enable_password(click_runner: CliRunner) -> None:
assert "Please enter a password to enter EOS privileged EXEC mode" not in result.output
assert result.exit_code == ExitCode.OK
- # enable and enable-password and prompt (redundant)
result = click_runner.invoke(anta, ["nrfu", "--enable", "--enable-password", "blah", "--prompt"], input="y\npassword\npassword\n")
assert "Is a password required to enter EOS privileged EXEC mode? [y/N]:" not in result.output
assert "Please enter a password to enter EOS privileged EXEC mode" not in result.output
@@ -91,17 +99,13 @@ def test_anta_enable_password(click_runner: CliRunner) -> None:
def test_anta_enable_alone(click_runner: CliRunner) -> None:
- """
- Test that enable can be provided either without enable-password
- """
+ """Test that enable can be provided either without enable-password."""
result = click_runner.invoke(anta, ["nrfu", "--enable"])
assert result.exit_code == ExitCode.OK
def test_disable_cache(click_runner: CliRunner) -> None:
- """
- Test that disable_cache is working on inventory
- """
+ """Test that disable_cache is working on inventory."""
result = click_runner.invoke(anta, ["nrfu", "--disable-cache"])
stdout_lines = result.stdout.split("\n")
# All caches should be disabled from the inventory
diff --git a/tests/units/cli/nrfu/test_commands.py b/tests/units/cli/nrfu/test_commands.py
index 4639671..e2b5031 100644
--- a/tests/units/cli/nrfu/test_commands.py
+++ b/tests/units/cli/nrfu/test_commands.py
@@ -1,97 +1,96 @@
# Copyright (c) 2023-2024 Arista Networks, Inc.
# Use of this source code is governed by the Apache License 2.0
# that can be found in the LICENSE file.
-"""
-Tests for anta.cli.nrfu.commands
-"""
+"""Tests for anta.cli.nrfu.commands."""
+
from __future__ import annotations
import json
import re
from pathlib import Path
-
-from click.testing import CliRunner
+from typing import TYPE_CHECKING
from anta.cli import anta
from anta.cli.utils import ExitCode
+if TYPE_CHECKING:
+ from click.testing import CliRunner
+
DATA_DIR: Path = Path(__file__).parent.parent.parent.parent.resolve() / "data"
def test_anta_nrfu_table_help(click_runner: CliRunner) -> None:
- """
- Test anta nrfu table --help
- """
+ """Test anta nrfu table --help."""
result = click_runner.invoke(anta, ["nrfu", "table", "--help"])
assert result.exit_code == ExitCode.OK
assert "Usage: anta nrfu table" in result.output
def test_anta_nrfu_text_help(click_runner: CliRunner) -> None:
- """
- Test anta nrfu text --help
- """
+ """Test anta nrfu text --help."""
result = click_runner.invoke(anta, ["nrfu", "text", "--help"])
assert result.exit_code == ExitCode.OK
assert "Usage: anta nrfu text" in result.output
def test_anta_nrfu_json_help(click_runner: CliRunner) -> None:
- """
- Test anta nrfu json --help
- """
+ """Test anta nrfu json --help."""
result = click_runner.invoke(anta, ["nrfu", "json", "--help"])
assert result.exit_code == ExitCode.OK
assert "Usage: anta nrfu json" in result.output
def test_anta_nrfu_template_help(click_runner: CliRunner) -> None:
- """
- Test anta nrfu tpl-report --help
- """
+ """Test anta nrfu tpl-report --help."""
result = click_runner.invoke(anta, ["nrfu", "tpl-report", "--help"])
assert result.exit_code == ExitCode.OK
assert "Usage: anta nrfu tpl-report" in result.output
def test_anta_nrfu_table(click_runner: CliRunner) -> None:
- """
- Test anta nrfu, catalog is given via env
- """
+ """Test anta nrfu, catalog is given via env."""
result = click_runner.invoke(anta, ["nrfu", "table"])
assert result.exit_code == ExitCode.OK
assert "dummy │ VerifyEOSVersion │ success" in result.output
+def test_anta_nrfu_table_group_by_device(click_runner: CliRunner) -> None:
+ """Test anta nrfu, catalog is given via env."""
+ result = click_runner.invoke(anta, ["nrfu", "table", "--group-by", "device"])
+ assert result.exit_code == ExitCode.OK
+ assert "Summary per device" in result.output
+
+
+def test_anta_nrfu_table_group_by_test(click_runner: CliRunner) -> None:
+ """Test anta nrfu, catalog is given via env."""
+ result = click_runner.invoke(anta, ["nrfu", "table", "--group-by", "test"])
+ assert result.exit_code == ExitCode.OK
+ assert "Summary per test" in result.output
+
+
def test_anta_nrfu_text(click_runner: CliRunner) -> None:
- """
- Test anta nrfu, catalog is given via env
- """
+ """Test anta nrfu, catalog is given via env."""
result = click_runner.invoke(anta, ["nrfu", "text"])
assert result.exit_code == ExitCode.OK
assert "dummy :: VerifyEOSVersion :: SUCCESS" in result.output
def test_anta_nrfu_json(click_runner: CliRunner) -> None:
- """
- Test anta nrfu, catalog is given via env
- """
+ """Test anta nrfu, catalog is given via env."""
result = click_runner.invoke(anta, ["nrfu", "json"])
assert result.exit_code == ExitCode.OK
- assert "JSON results of all tests" in result.output
- m = re.search(r"\[\n {[\s\S]+ }\n\]", result.output)
- assert m is not None
- result_list = json.loads(m.group())
- for r in result_list:
- if r["name"] == "dummy":
- assert r["test"] == "VerifyEOSVersion"
- assert r["result"] == "success"
+ assert "JSON results" in result.output
+ match = re.search(r"\[\n {2}{[\s\S]+ {2}}\n\]", result.output)
+ assert match is not None
+ result_list = json.loads(match.group())
+ for res in result_list:
+ if res["name"] == "dummy":
+ assert res["test"] == "VerifyEOSVersion"
+ assert res["result"] == "success"
def test_anta_nrfu_template(click_runner: CliRunner) -> None:
- """
- Test anta nrfu, catalog is given via env
- """
+ """Test anta nrfu, catalog is given via env."""
result = click_runner.invoke(anta, ["nrfu", "tpl-report", "--template", str(DATA_DIR / "template.j2")])
assert result.exit_code == ExitCode.OK
assert "* VerifyEOSVersion is SUCCESS for dummy" in result.output
diff --git a/tests/units/cli/test__init__.py b/tests/units/cli/test__init__.py
index 0e84e14..6e32664 100644
--- a/tests/units/cli/test__init__.py
+++ b/tests/units/cli/test__init__.py
@@ -1,58 +1,55 @@
# Copyright (c) 2023-2024 Arista Networks, Inc.
# Use of this source code is governed by the Apache License 2.0
# that can be found in the LICENSE file.
-"""
-Tests for anta.cli.__init__
-"""
+"""Tests for anta.cli._main."""
from __future__ import annotations
-from click.testing import CliRunner
+import sys
+from importlib import reload
+from typing import TYPE_CHECKING, Any
+from unittest.mock import patch
-from anta.cli import anta
-from anta.cli.utils import ExitCode
+import pytest
+import anta.cli
-def test_anta(click_runner: CliRunner) -> None:
- """
- Test anta main entrypoint
- """
- result = click_runner.invoke(anta)
- assert result.exit_code == ExitCode.OK
- assert "Usage" in result.output
+if TYPE_CHECKING:
+ from types import ModuleType
+builtins_import = __import__
-def test_anta_help(click_runner: CliRunner) -> None:
- """
- Test anta --help
- """
- result = click_runner.invoke(anta, ["--help"])
- assert result.exit_code == ExitCode.OK
- assert "Usage" in result.output
+# Tried to achieve this with mock
+# http://materials-scientist.com/blog/2021/02/11/mocking-failing-module-import-python/
+def import_mock(name: str, *args: Any) -> ModuleType: # noqa: ANN401
+ """Mock."""
+ if name == "click":
+ msg = "No module named 'click'"
+ raise ModuleNotFoundError(msg)
+ return builtins_import(name, *args)
-def test_anta_exec_help(click_runner: CliRunner) -> None:
- """
- Test anta exec --help
- """
- result = click_runner.invoke(anta, ["exec", "--help"])
- assert result.exit_code == ExitCode.OK
- assert "Usage: anta exec" in result.output
+def test_cli_error_missing(capsys: pytest.CaptureFixture[Any]) -> None:
+ """Test ANTA errors out when anta[cli] was not installed."""
+ with patch.dict(sys.modules) as sys_modules, patch("builtins.__import__", import_mock):
+ del sys_modules["anta.cli._main"]
+ reload(anta.cli)
-def test_anta_debug_help(click_runner: CliRunner) -> None:
- """
- Test anta debug --help
- """
- result = click_runner.invoke(anta, ["debug", "--help"])
- assert result.exit_code == ExitCode.OK
- assert "Usage: anta debug" in result.output
+ with pytest.raises(SystemExit) as e_info:
+ anta.cli.cli()
+ captured = capsys.readouterr()
+ assert "The ANTA command line client could not run because the required dependencies were not installed." in captured.out
+ assert "Make sure you've installed everything with: pip install 'anta[cli]'" in captured.out
+ assert e_info.value.code == 1
-def test_anta_get_help(click_runner: CliRunner) -> None:
- """
- Test anta get --help
- """
- result = click_runner.invoke(anta, ["get", "--help"])
- assert result.exit_code == ExitCode.OK
- assert "Usage: anta get" in result.output
+ # setting ANTA_DEBUG
+ with pytest.raises(SystemExit) as e_info, patch("anta.cli.__DEBUG__", new=True):
+ anta.cli.cli()
+
+ captured = capsys.readouterr()
+ assert "The ANTA command line client could not run because the required dependencies were not installed." in captured.out
+ assert "Make sure you've installed everything with: pip install 'anta[cli]'" in captured.out
+ assert "The caught exception was:" in captured.out
+ assert e_info.value.code == 1
diff --git a/tests/units/cli/test_main.py b/tests/units/cli/test_main.py
new file mode 100644
index 0000000..31a5e78
--- /dev/null
+++ b/tests/units/cli/test_main.py
@@ -0,0 +1,64 @@
+# Copyright (c) 2023-2024 Arista Networks, Inc.
+# Use of this source code is governed by the Apache License 2.0
+# that can be found in the LICENSE file.
+"""Tests for anta.cli._main."""
+
+from __future__ import annotations
+
+from typing import TYPE_CHECKING
+from unittest.mock import patch
+
+import pytest
+
+from anta.cli._main import anta, cli
+from anta.cli.utils import ExitCode
+
+if TYPE_CHECKING:
+ from click.testing import CliRunner
+
+
+def test_anta(click_runner: CliRunner) -> None:
+ """Test anta main entrypoint."""
+ result = click_runner.invoke(anta)
+ assert result.exit_code == ExitCode.OK
+ assert "Usage" in result.output
+
+
+def test_anta_help(click_runner: CliRunner) -> None:
+ """Test anta --help."""
+ result = click_runner.invoke(anta, ["--help"])
+ assert result.exit_code == ExitCode.OK
+ assert "Usage" in result.output
+
+
+def test_anta_exec_help(click_runner: CliRunner) -> None:
+ """Test anta exec --help."""
+ result = click_runner.invoke(anta, ["exec", "--help"])
+ assert result.exit_code == ExitCode.OK
+ assert "Usage: anta exec" in result.output
+
+
+def test_anta_debug_help(click_runner: CliRunner) -> None:
+ """Test anta debug --help."""
+ result = click_runner.invoke(anta, ["debug", "--help"])
+ assert result.exit_code == ExitCode.OK
+ assert "Usage: anta debug" in result.output
+
+
+def test_anta_get_help(click_runner: CliRunner) -> None:
+ """Test anta get --help."""
+ result = click_runner.invoke(anta, ["get", "--help"])
+ assert result.exit_code == ExitCode.OK
+ assert "Usage: anta get" in result.output
+
+
+def test_uncaught_failure_anta(caplog: pytest.LogCaptureFixture) -> None:
+ """Test uncaught failure when running ANTA cli."""
+ with (
+ pytest.raises(SystemExit) as e_info,
+ patch("anta.cli._main.anta", side_effect=ZeroDivisionError()),
+ ):
+ cli()
+ assert "CRITICAL" in caplog.text
+ assert "Uncaught Exception when running ANTA CLI" in caplog.text
+ assert e_info.value.code == 1
diff --git a/tests/units/inventory/__init__.py b/tests/units/inventory/__init__.py
index e772bee..70fbdda 100644
--- a/tests/units/inventory/__init__.py
+++ b/tests/units/inventory/__init__.py
@@ -1,3 +1,4 @@
# Copyright (c) 2023-2024 Arista Networks, Inc.
# Use of this source code is governed by the Apache License 2.0
# that can be found in the LICENSE file.
+"""Tests for inventory submodule."""
diff --git a/tests/units/inventory/test_inventory.py b/tests/units/inventory/test_inventory.py
index 7c62b5c..430ca21 100644
--- a/tests/units/inventory/test_inventory.py
+++ b/tests/units/inventory/test_inventory.py
@@ -2,23 +2,25 @@
# Use of this source code is governed by the Apache License 2.0
# that can be found in the LICENSE file.
"""ANTA Inventory unit tests."""
+
from __future__ import annotations
-import logging
-from pathlib import Path
-from typing import Any
+from typing import TYPE_CHECKING, Any
import pytest
import yaml
from pydantic import ValidationError
from anta.inventory import AntaInventory
-from anta.inventory.exceptions import InventoryIncorrectSchema, InventoryRootKeyError
+from anta.inventory.exceptions import InventoryIncorrectSchemaError, InventoryRootKeyError
from tests.data.json_data import ANTA_INVENTORY_TESTS_INVALID, ANTA_INVENTORY_TESTS_VALID
from tests.lib.utils import generate_test_ids_dict
+if TYPE_CHECKING:
+ from pathlib import Path
+
-class Test_AntaInventory:
+class TestAntaInventory:
"""Test AntaInventory class."""
def create_inventory(self, content: str, tmp_path: Path) -> str:
@@ -31,7 +33,7 @@ class Test_AntaInventory:
def check_parameter(self, parameter: str, test_definition: dict[Any, Any]) -> bool:
"""Check if parameter is configured in testbed."""
- return "parameters" in test_definition and parameter in test_definition["parameters"].keys()
+ return "parameters" in test_definition and parameter in test_definition["parameters"]
@pytest.mark.parametrize("test_definition", ANTA_INVENTORY_TESTS_VALID, ids=generate_test_ids_dict)
def test_init_valid(self, test_definition: dict[str, Any], tmp_path: Path) -> None:
@@ -55,8 +57,7 @@ class Test_AntaInventory:
try:
AntaInventory.parse(filename=inventory_file, username="arista", password="arista123")
except ValidationError as exc:
- logging.error("Exceptions is: %s", str(exc))
- assert False
+ raise AssertionError from exc
@pytest.mark.parametrize("test_definition", ANTA_INVENTORY_TESTS_INVALID, ids=generate_test_ids_dict)
def test_init_invalid(self, test_definition: dict[str, Any], tmp_path: Path) -> None:
@@ -77,5 +78,5 @@ class Test_AntaInventory:
"""
inventory_file = self.create_inventory(content=test_definition["input"], tmp_path=tmp_path)
- with pytest.raises((InventoryIncorrectSchema, InventoryRootKeyError, ValidationError)):
+ with pytest.raises((InventoryIncorrectSchemaError, InventoryRootKeyError, ValidationError)):
AntaInventory.parse(filename=inventory_file, username="arista", password="arista123")
diff --git a/tests/units/inventory/test_models.py b/tests/units/inventory/test_models.py
index 83f151c..0dccfb8 100644
--- a/tests/units/inventory/test_models.py
+++ b/tests/units/inventory/test_models.py
@@ -2,6 +2,7 @@
# Use of this source code is governed by the Apache License 2.0
# that can be found in the LICENSE file.
"""ANTA Inventory models unit tests."""
+
from __future__ import annotations
import logging
@@ -30,7 +31,7 @@ from tests.data.json_data import (
from tests.lib.utils import generate_test_ids_dict
-class Test_InventoryUnitModels:
+class TestInventoryUnitModels:
"""Test components of AntaInventoryInput model."""
@pytest.mark.parametrize("test_definition", INVENTORY_MODEL_HOST_VALID, ids=generate_test_ids_dict)
@@ -51,9 +52,8 @@ class Test_InventoryUnitModels:
host_inventory = AntaInventoryHost(host=test_definition["input"])
except ValidationError as exc:
logging.warning("Error: %s", str(exc))
- assert False
- else:
- assert test_definition["input"] == str(host_inventory.host)
+ raise AssertionError from exc
+ assert test_definition["input"] == str(host_inventory.host)
@pytest.mark.parametrize("test_definition", INVENTORY_MODEL_HOST_INVALID, ids=generate_test_ids_dict)
def test_anta_inventory_host_invalid(self, test_definition: dict[str, Any]) -> None:
@@ -110,9 +110,8 @@ class Test_InventoryUnitModels:
network_inventory = AntaInventoryNetwork(network=test_definition["input"])
except ValidationError as exc:
logging.warning("Error: %s", str(exc))
- assert False
- else:
- assert test_definition["input"] == str(network_inventory.network)
+ raise AssertionError from exc
+ assert test_definition["input"] == str(network_inventory.network)
@pytest.mark.parametrize("test_definition", INVENTORY_MODEL_NETWORK_INVALID, ids=generate_test_ids_dict)
def test_anta_inventory_network_invalid(self, test_definition: dict[str, Any]) -> None:
@@ -133,11 +132,11 @@ class Test_InventoryUnitModels:
except ValidationError as exc:
logging.warning("Error: %s", str(exc))
else:
- assert False
+ raise AssertionError
@pytest.mark.parametrize("test_definition", INVENTORY_MODEL_NETWORK_CACHE, ids=generate_test_ids_dict)
def test_anta_inventory_network_cache(self, test_definition: dict[str, Any]) -> None:
- """Test network disable_cache
+ """Test network disable_cache.
Test structure:
---------------
@@ -176,10 +175,9 @@ class Test_InventoryUnitModels:
)
except ValidationError as exc:
logging.warning("Error: %s", str(exc))
- assert False
- else:
- assert test_definition["input"]["start"] == str(range_inventory.start)
- assert test_definition["input"]["end"] == str(range_inventory.end)
+ raise AssertionError from exc
+ assert test_definition["input"]["start"] == str(range_inventory.start)
+ assert test_definition["input"]["end"] == str(range_inventory.end)
@pytest.mark.parametrize("test_definition", INVENTORY_MODEL_RANGE_INVALID, ids=generate_test_ids_dict)
def test_anta_inventory_range_invalid(self, test_definition: dict[str, Any]) -> None:
@@ -203,11 +201,11 @@ class Test_InventoryUnitModels:
except ValidationError as exc:
logging.warning("Error: %s", str(exc))
else:
- assert False
+ raise AssertionError
@pytest.mark.parametrize("test_definition", INVENTORY_MODEL_RANGE_CACHE, ids=generate_test_ids_dict)
def test_anta_inventory_range_cache(self, test_definition: dict[str, Any]) -> None:
- """Test range disable_cache
+ """Test range disable_cache.
Test structure:
---------------
@@ -221,22 +219,23 @@ class Test_InventoryUnitModels:
"""
if "disable_cache" in test_definition["input"]:
range_inventory = AntaInventoryRange(
- start=test_definition["input"]["start"], end=test_definition["input"]["end"], disable_cache=test_definition["input"]["disable_cache"]
+ start=test_definition["input"]["start"],
+ end=test_definition["input"]["end"],
+ disable_cache=test_definition["input"]["disable_cache"],
)
else:
range_inventory = AntaInventoryRange(start=test_definition["input"]["start"], end=test_definition["input"]["end"])
assert test_definition["expected_result"] == range_inventory.disable_cache
-class Test_AntaInventoryInputModel:
+class TestAntaInventoryInputModel:
"""Unit test of AntaInventoryInput model."""
def test_inventory_input_structure(self) -> None:
"""Test inventory keys are those expected."""
-
inventory = AntaInventoryInput()
logging.info("Inventory keys are: %s", str(inventory.model_dump().keys()))
- assert all(elem in inventory.model_dump().keys() for elem in ["hosts", "networks", "ranges"])
+ assert all(elem in inventory.model_dump() for elem in ["hosts", "networks", "ranges"])
@pytest.mark.parametrize("inventory_def", INVENTORY_MODEL_VALID, ids=generate_test_ids_dict)
def test_anta_inventory_intput_valid(self, inventory_def: dict[str, Any]) -> None:
@@ -265,10 +264,9 @@ class Test_AntaInventoryInputModel:
inventory = AntaInventoryInput(**inventory_def["input"])
except ValidationError as exc:
logging.warning("Error: %s", str(exc))
- assert False
- else:
- logging.info("Checking if all root keys are correctly lodaded")
- assert all(elem in inventory.model_dump().keys() for elem in inventory_def["input"].keys())
+ raise AssertionError from exc
+ logging.info("Checking if all root keys are correctly lodaded")
+ assert all(elem in inventory.model_dump() for elem in inventory_def["input"])
@pytest.mark.parametrize("inventory_def", INVENTORY_MODEL_INVALID, ids=generate_test_ids_dict)
def test_anta_inventory_intput_invalid(self, inventory_def: dict[str, Any]) -> None:
@@ -294,19 +292,19 @@ class Test_AntaInventoryInputModel:
"""
try:
- if "hosts" in inventory_def["input"].keys():
+ if "hosts" in inventory_def["input"]:
logging.info(
"Loading %s into AntaInventoryInput hosts section",
str(inventory_def["input"]["hosts"]),
)
AntaInventoryInput(hosts=inventory_def["input"]["hosts"])
- if "networks" in inventory_def["input"].keys():
+ if "networks" in inventory_def["input"]:
logging.info(
"Loading %s into AntaInventoryInput networks section",
str(inventory_def["input"]["networks"]),
)
AntaInventoryInput(networks=inventory_def["input"]["networks"])
- if "ranges" in inventory_def["input"].keys():
+ if "ranges" in inventory_def["input"]:
logging.info(
"Loading %s into AntaInventoryInput ranges section",
str(inventory_def["input"]["ranges"]),
@@ -315,10 +313,10 @@ class Test_AntaInventoryInputModel:
except ValidationError as exc:
logging.warning("Error: %s", str(exc))
else:
- assert False
+ raise AssertionError
-class Test_InventoryDeviceModel:
+class TestInventoryDeviceModel:
"""Unit test of InventoryDevice model."""
@pytest.mark.parametrize("test_definition", INVENTORY_DEVICE_MODEL_VALID, ids=generate_test_ids_dict)
@@ -349,12 +347,12 @@ class Test_InventoryDeviceModel:
if test_definition["expected_result"] == "invalid":
pytest.skip("Not concerned by the test")
- for entity in test_definition["input"]:
- try:
+ try:
+ for entity in test_definition["input"]:
AsyncEOSDevice(**entity)
- except TypeError as exc:
- logging.warning("Error: %s", str(exc))
- assert False
+ except TypeError as exc:
+ logging.warning("Error: %s", str(exc))
+ raise AssertionError from exc
@pytest.mark.parametrize("test_definition", INVENTORY_DEVICE_MODEL_INVALID, ids=generate_test_ids_dict)
def test_inventory_device_invalid(self, test_definition: dict[str, Any]) -> None:
@@ -384,10 +382,10 @@ class Test_InventoryDeviceModel:
if test_definition["expected_result"] == "valid":
pytest.skip("Not concerned by the test")
- for entity in test_definition["input"]:
- try:
+ try:
+ for entity in test_definition["input"]:
AsyncEOSDevice(**entity)
- except TypeError as exc:
- logging.info("Error: %s", str(exc))
- else:
- assert False
+ except TypeError as exc:
+ logging.info("Error: %s", str(exc))
+ else:
+ raise AssertionError
diff --git a/tests/units/reporter/__init__.py b/tests/units/reporter/__init__.py
index e772bee..6e606e5 100644
--- a/tests/units/reporter/__init__.py
+++ b/tests/units/reporter/__init__.py
@@ -1,3 +1,4 @@
# Copyright (c) 2023-2024 Arista Networks, Inc.
# Use of this source code is governed by the Apache License 2.0
# that can be found in the LICENSE file.
+"""Tests for anta.reporter submodule."""
diff --git a/tests/units/reporter/test__init__.py b/tests/units/reporter/test__init__.py
index 259942f..2fc62ce 100644
--- a/tests/units/reporter/test__init__.py
+++ b/tests/units/reporter/test__init__.py
@@ -1,44 +1,52 @@
# Copyright (c) 2023-2024 Arista Networks, Inc.
# Use of this source code is governed by the Apache License 2.0
# that can be found in the LICENSE file.
-"""
-Test anta.report.__init__.py
-"""
+"""Test anta.report.__init__.py."""
+
from __future__ import annotations
-from typing import Callable
+from pathlib import Path
+from typing import TYPE_CHECKING, Callable
import pytest
from rich.table import Table
from anta import RICH_COLOR_PALETTE
-from anta.custom_types import TestStatus
-from anta.reporter import ReportTable
-from anta.result_manager import ResultManager
+from anta.reporter import ReportJinja, ReportTable
+
+if TYPE_CHECKING:
+ from anta.custom_types import TestStatus
+ from anta.result_manager import ResultManager
-class Test_ReportTable:
- """
- Test ReportTable class
- """
+class TestReportTable:
+ """Test ReportTable class."""
# not testing __init__ as nothing is going on there
@pytest.mark.parametrize(
- "usr_list, delimiter, expected_output",
+ ("usr_list", "delimiter", "expected_output"),
[
pytest.param([], None, "", id="empty list no delimiter"),
pytest.param([], "*", "", id="empty list with delimiter"),
pytest.param(["elem1"], None, "elem1", id="one elem list no delimiter"),
pytest.param(["elem1"], "*", "* elem1", id="one elem list with delimiter"),
- pytest.param(["elem1", "elem2"], None, "elem1\nelem2", id="two elems list no delimiter"),
- pytest.param(["elem1", "elem2"], "&", "& elem1\n& elem2", id="two elems list with delimiter"),
+ pytest.param(
+ ["elem1", "elem2"],
+ None,
+ "elem1\nelem2",
+ id="two elems list no delimiter",
+ ),
+ pytest.param(
+ ["elem1", "elem2"],
+ "&",
+ "& elem1\n& elem2",
+ id="two elems list with delimiter",
+ ),
],
)
def test__split_list_to_txt_list(self, usr_list: list[str], delimiter: str | None, expected_output: str) -> None:
- """
- test _split_list_to_txt_list
- """
+ """Test _split_list_to_txt_list."""
# pylint: disable=protected-access
report = ReportTable()
assert report._split_list_to_txt_list(usr_list, delimiter) == expected_output
@@ -52,9 +60,7 @@ class Test_ReportTable:
],
)
def test__build_headers(self, headers: list[str]) -> None:
- """
- test _build_headers
- """
+ """Test _build_headers."""
# pylint: disable=protected-access
report = ReportTable()
table = Table()
@@ -65,7 +71,7 @@ class Test_ReportTable:
assert table.columns[table_column_before].style == RICH_COLOR_PALETTE.HEADER
@pytest.mark.parametrize(
- "status, expected_status",
+ ("status", "expected_status"),
[
pytest.param("unknown", "unknown", id="unknown status"),
pytest.param("unset", "[grey74]unset", id="unset status"),
@@ -76,48 +82,42 @@ class Test_ReportTable:
],
)
def test__color_result(self, status: TestStatus, expected_status: str) -> None:
- """
- test _build_headers
- """
+ """Test _build_headers."""
# pylint: disable=protected-access
report = ReportTable()
assert report._color_result(status) == expected_status
@pytest.mark.parametrize(
- "host, testcase, title, number_of_tests, expected_length",
+ ("title", "number_of_tests", "expected_length"),
[
- pytest.param(None, None, None, 5, 5, id="all results"),
- pytest.param("host1", None, None, 5, 0, id="result for host1 when no host1 test"),
- pytest.param(None, "VerifyTest3", None, 5, 1, id="result for test VerifyTest3"),
- pytest.param(None, None, "Custom title", 5, 5, id="Change table title"),
+ pytest.param(None, 5, 5, id="all results"),
+ pytest.param(None, 0, 0, id="result for host1 when no host1 test"),
+ pytest.param(None, 5, 5, id="result for test VerifyTest3"),
+ pytest.param("Custom title", 5, 5, id="Change table title"),
],
)
def test_report_all(
self,
result_manager_factory: Callable[[int], ResultManager],
- host: str | None,
- testcase: str | None,
title: str | None,
number_of_tests: int,
expected_length: int,
) -> None:
- """
- test report_all
- """
+ """Test report_all."""
# pylint: disable=too-many-arguments
- rm = result_manager_factory(number_of_tests)
+ manager = result_manager_factory(number_of_tests)
report = ReportTable()
- kwargs = {"host": host, "testcase": testcase, "title": title}
+ kwargs = {"title": title}
kwargs = {k: v for k, v in kwargs.items() if v is not None}
- res = report.report_all(rm, **kwargs) # type: ignore[arg-type]
+ res = report.report_all(manager, **kwargs) # type: ignore[arg-type]
assert isinstance(res, Table)
assert res.title == (title or "All tests results")
assert res.row_count == expected_length
@pytest.mark.parametrize(
- "testcase, title, number_of_tests, expected_length",
+ ("test", "title", "number_of_tests", "expected_length"),
[
pytest.param(None, None, 5, 5, id="all results"),
pytest.param("VerifyTest3", None, 5, 1, id="result for test VerifyTest3"),
@@ -127,67 +127,73 @@ class Test_ReportTable:
def test_report_summary_tests(
self,
result_manager_factory: Callable[[int], ResultManager],
- testcase: str | None,
+ test: str | None,
title: str | None,
number_of_tests: int,
expected_length: int,
) -> None:
- """
- test report_summary_tests
- """
+ """Test report_summary_tests."""
# pylint: disable=too-many-arguments
- # TODO refactor this later... this is injecting double test results by modyfing the device name
+ # TODO: refactor this later... this is injecting double test results by modyfing the device name
# should be a fixture
- rm = result_manager_factory(number_of_tests)
- new_results = [result.model_copy() for result in rm.get_results()]
+ manager = result_manager_factory(number_of_tests)
+ new_results = [result.model_copy() for result in manager.results]
for result in new_results:
result.name = "test_device"
result.result = "failure"
- rm.add_test_results(new_results)
report = ReportTable()
- kwargs = {"testcase": testcase, "title": title}
+ kwargs = {"tests": [test] if test is not None else None, "title": title}
kwargs = {k: v for k, v in kwargs.items() if v is not None}
- res = report.report_summary_tests(rm, **kwargs) # type: ignore[arg-type]
+ res = report.report_summary_tests(manager, **kwargs) # type: ignore[arg-type]
assert isinstance(res, Table)
- assert res.title == (title or "Summary per test case")
+ assert res.title == (title or "Summary per test")
assert res.row_count == expected_length
@pytest.mark.parametrize(
- "host, title, number_of_tests, expected_length",
+ ("dev", "title", "number_of_tests", "expected_length"),
[
- pytest.param(None, None, 5, 2, id="all results"),
- pytest.param("host1", None, 5, 1, id="result for host host1"),
- pytest.param(None, "Custom title", 5, 2, id="Change table title"),
+ pytest.param(None, None, 5, 1, id="all results"),
+ pytest.param("device1", None, 5, 1, id="result for host host1"),
+ pytest.param(None, "Custom title", 5, 1, id="Change table title"),
],
)
- def test_report_summary_hosts(
+ def test_report_summary_devices(
self,
result_manager_factory: Callable[[int], ResultManager],
- host: str | None,
+ dev: str | None,
title: str | None,
number_of_tests: int,
expected_length: int,
) -> None:
- """
- test report_summary_hosts
- """
+ """Test report_summary_devices."""
# pylint: disable=too-many-arguments
- # TODO refactor this later... this is injecting double test results by modyfing the device name
+ # TODO: refactor this later... this is injecting double test results by modyfing the device name
# should be a fixture
- rm = result_manager_factory(number_of_tests)
- new_results = [result.model_copy() for result in rm.get_results()]
+ manager = result_manager_factory(number_of_tests)
+ new_results = [result.model_copy() for result in manager.results]
for result in new_results:
- result.name = host or "test_device"
+ result.name = dev or "test_device"
result.result = "failure"
- rm.add_test_results(new_results)
+ manager.results = new_results
report = ReportTable()
- kwargs = {"host": host, "title": title}
+ kwargs = {"devices": [dev] if dev is not None else None, "title": title}
kwargs = {k: v for k, v in kwargs.items() if v is not None}
- res = report.report_summary_hosts(rm, **kwargs) # type: ignore[arg-type]
+ res = report.report_summary_devices(manager, **kwargs) # type: ignore[arg-type]
assert isinstance(res, Table)
- assert res.title == (title or "Summary per host")
+ assert res.title == (title or "Summary per device")
assert res.row_count == expected_length
+
+
+class TestReportJinja:
+ """Tests for ReportJinja class."""
+
+ # pylint: disable=too-few-public-methods
+
+ def test_fail__init__file_not_found(self) -> None:
+ """Test __init__ failure if file is not found."""
+ with pytest.raises(FileNotFoundError, match="template file is not found: /gnu/terry/pratchett"):
+ ReportJinja(Path("/gnu/terry/pratchett"))
diff --git a/tests/units/result_manager/__init__.py b/tests/units/result_manager/__init__.py
index e772bee..861145b 100644
--- a/tests/units/result_manager/__init__.py
+++ b/tests/units/result_manager/__init__.py
@@ -1,3 +1,4 @@
# Copyright (c) 2023-2024 Arista Networks, Inc.
# Use of this source code is governed by the Apache License 2.0
# that can be found in the LICENSE file.
+"""Tests for anta.result_manager submodule."""
diff --git a/tests/units/result_manager/test__init__.py b/tests/units/result_manager/test__init__.py
index c457c84..02c694c 100644
--- a/tests/units/result_manager/test__init__.py
+++ b/tests/units/result_manager/test__init__.py
@@ -1,204 +1,277 @@
# Copyright (c) 2023-2024 Arista Networks, Inc.
# Use of this source code is governed by the Apache License 2.0
# that can be found in the LICENSE file.
-"""
-Test anta.result_manager.__init__.py
-"""
+"""Test anta.result_manager.__init__.py."""
+
from __future__ import annotations
import json
-from contextlib import nullcontext
-from typing import TYPE_CHECKING, Any, Callable
+from contextlib import AbstractContextManager, nullcontext
+from typing import TYPE_CHECKING, Callable
import pytest
-from anta.custom_types import TestStatus
-from anta.result_manager import ResultManager
+from anta.result_manager import ResultManager, models
if TYPE_CHECKING:
+ from anta.custom_types import TestStatus
from anta.result_manager.models import TestResult
-class Test_ResultManager:
- """
- Test ResultManager class
- """
+class TestResultManager:
+ """Test ResultManager class."""
# not testing __init__ as nothing is going on there
def test__len__(self, list_result_factory: Callable[[int], list[TestResult]]) -> None:
- """
- test __len__
- """
+ """Test __len__."""
list_result = list_result_factory(3)
result_manager = ResultManager()
assert len(result_manager) == 0
for i in range(3):
- result_manager.add_test_result(list_result[i])
+ result_manager.add(list_result[i])
assert len(result_manager) == i + 1
+ def test_results_getter(self, result_manager_factory: Callable[[int], ResultManager]) -> None:
+ """Test ResultManager.results property getter."""
+ result_manager = result_manager_factory(3)
+ res = result_manager.results
+ assert len(res) == 3
+ assert isinstance(res, list)
+ for e in res:
+ assert isinstance(e, models.TestResult)
+
+ def test_results_setter(self, list_result_factory: Callable[[int], list[TestResult]], result_manager_factory: Callable[[int], ResultManager]) -> None:
+ """Test ResultManager.results property setter."""
+ result_manager = result_manager_factory(3)
+ assert len(result_manager) == 3
+ tests = list_result_factory(5)
+ result_manager.results = tests
+ assert len(result_manager) == 5
+
+ def test_json(self, list_result_factory: Callable[[int], list[TestResult]]) -> None:
+ """Test ResultManager.json property."""
+ result_manager = ResultManager()
+
+ success_list = list_result_factory(3)
+ for test in success_list:
+ test.result = "success"
+ result_manager.results = success_list
+
+ json_res = result_manager.json
+ assert isinstance(json_res, str)
+
+ # Verifies it can be deserialized back to a list of dict with the correct values types
+ res = json.loads(json_res)
+ for test in res:
+ assert isinstance(test, dict)
+ assert isinstance(test.get("test"), str)
+ assert isinstance(test.get("categories"), list)
+ assert isinstance(test.get("description"), str)
+ assert test.get("custom_field") is None
+ assert test.get("result") == "success"
+
@pytest.mark.parametrize(
- "starting_status, test_status, expected_status, expected_raise",
+ ("starting_status", "test_status", "expected_status", "expected_raise"),
[
pytest.param("unset", "unset", "unset", nullcontext(), id="unset->unset"),
pytest.param("unset", "success", "success", nullcontext(), id="unset->success"),
pytest.param("unset", "error", "unset", nullcontext(), id="set error"),
pytest.param("skipped", "skipped", "skipped", nullcontext(), id="skipped->skipped"),
pytest.param("skipped", "unset", "skipped", nullcontext(), id="skipped, add unset"),
- pytest.param("skipped", "success", "success", nullcontext(), id="skipped, add success"),
- pytest.param("skipped", "failure", "failure", nullcontext(), id="skipped, add failure"),
+ pytest.param(
+ "skipped",
+ "success",
+ "success",
+ nullcontext(),
+ id="skipped, add success",
+ ),
+ pytest.param(
+ "skipped",
+ "failure",
+ "failure",
+ nullcontext(),
+ id="skipped, add failure",
+ ),
pytest.param("success", "unset", "success", nullcontext(), id="success, add unset"),
- pytest.param("success", "skipped", "success", nullcontext(), id="success, add skipped"),
+ pytest.param(
+ "success",
+ "skipped",
+ "success",
+ nullcontext(),
+ id="success, add skipped",
+ ),
pytest.param("success", "success", "success", nullcontext(), id="success->success"),
pytest.param("success", "failure", "failure", nullcontext(), id="success->failure"),
pytest.param("failure", "unset", "failure", nullcontext(), id="failure->failure"),
pytest.param("failure", "skipped", "failure", nullcontext(), id="failure, add unset"),
- pytest.param("failure", "success", "failure", nullcontext(), id="failure, add skipped"),
- pytest.param("failure", "failure", "failure", nullcontext(), id="failure, add success"),
- pytest.param("unset", "unknown", None, pytest.raises(ValueError), id="wrong status"),
+ pytest.param(
+ "failure",
+ "success",
+ "failure",
+ nullcontext(),
+ id="failure, add skipped",
+ ),
+ pytest.param(
+ "failure",
+ "failure",
+ "failure",
+ nullcontext(),
+ id="failure, add success",
+ ),
+ pytest.param(
+ "unset", "unknown", None, pytest.raises(ValueError, match="Input should be 'unset', 'success', 'failure', 'error' or 'skipped'"), id="wrong status"
+ ),
],
)
- def test__update_status(self, starting_status: TestStatus, test_status: TestStatus, expected_status: str, expected_raise: Any) -> None:
- """
- Test ResultManager._update_status
- """
+ def test_add(
+ self,
+ test_result_factory: Callable[[], TestResult],
+ starting_status: TestStatus,
+ test_status: TestStatus,
+ expected_status: str,
+ expected_raise: AbstractContextManager[Exception],
+ ) -> None:
+ # pylint: disable=too-many-arguments
+ """Test ResultManager_update_status."""
result_manager = ResultManager()
result_manager.status = starting_status
assert result_manager.error_status is False
+ assert len(result_manager) == 0
+ test = test_result_factory()
+ test.result = test_status
with expected_raise:
- result_manager._update_status(test_status) # pylint: disable=protected-access
+ result_manager.add(test)
if test_status == "error":
assert result_manager.error_status is True
else:
assert result_manager.status == expected_status
-
- def test_add_test_result(self, test_result_factory: Callable[[int], TestResult]) -> None:
- """
- Test ResultManager.add_test_result
- """
- result_manager = ResultManager()
- assert result_manager.status == "unset"
- assert result_manager.error_status is False
- assert len(result_manager) == 0
-
- # Add one unset test
- unset_test = test_result_factory(0)
- unset_test.result = "unset"
- result_manager.add_test_result(unset_test)
- assert result_manager.status == "unset"
- assert result_manager.error_status is False
- assert len(result_manager) == 1
-
- # Add one success test
- success_test = test_result_factory(1)
- success_test.result = "success"
- result_manager.add_test_result(success_test)
- assert result_manager.status == "success"
- assert result_manager.error_status is False
- assert len(result_manager) == 2
-
- # Add one error test
- error_test = test_result_factory(1)
- error_test.result = "error"
- result_manager.add_test_result(error_test)
- assert result_manager.status == "success"
- assert result_manager.error_status is True
- assert len(result_manager) == 3
-
- # Add one failure test
- failure_test = test_result_factory(1)
- failure_test.result = "failure"
- result_manager.add_test_result(failure_test)
- assert result_manager.status == "failure"
- assert result_manager.error_status is True
- assert len(result_manager) == 4
-
- def test_add_test_results(self, list_result_factory: Callable[[int], list[TestResult]]) -> None:
- """
- Test ResultManager.add_test_results
- """
- result_manager = ResultManager()
- assert result_manager.status == "unset"
- assert result_manager.error_status is False
- assert len(result_manager) == 0
-
- # Add three success tests
- success_list = list_result_factory(3)
- for test in success_list:
- test.result = "success"
- result_manager.add_test_results(success_list)
- assert result_manager.status == "success"
- assert result_manager.error_status is False
- assert len(result_manager) == 3
-
- # Add one error test and one failure
- error_failure_list = list_result_factory(2)
- error_failure_list[0].result = "error"
- error_failure_list[1].result = "failure"
- result_manager.add_test_results(error_failure_list)
- assert result_manager.status == "failure"
- assert result_manager.error_status is True
- assert len(result_manager) == 5
+ assert len(result_manager) == 1
@pytest.mark.parametrize(
- "status, error_status, ignore_error, expected_status",
+ ("status", "error_status", "ignore_error", "expected_status"),
[
pytest.param("success", False, True, "success", id="no error"),
pytest.param("success", True, True, "success", id="error, ignore error"),
pytest.param("success", True, False, "error", id="error, do not ignore error"),
],
)
- def test_get_status(self, status: TestStatus, error_status: bool, ignore_error: bool, expected_status: str) -> None:
- """
- test ResultManager.get_status
- """
+ def test_get_status(
+ self,
+ status: TestStatus,
+ error_status: bool,
+ ignore_error: bool,
+ expected_status: str,
+ ) -> None:
+ """Test ResultManager.get_status."""
result_manager = ResultManager()
result_manager.status = status
result_manager.error_status = error_status
assert result_manager.get_status(ignore_error=ignore_error) == expected_status
- def test_get_results(self, list_result_factory: Callable[[int], list[TestResult]]) -> None:
- """
- test ResultManager.get_results
- """
+ def test_filter(self, test_result_factory: Callable[[], TestResult], list_result_factory: Callable[[int], list[TestResult]]) -> None:
+ """Test ResultManager.filter."""
result_manager = ResultManager()
success_list = list_result_factory(3)
for test in success_list:
test.result = "success"
- result_manager.add_test_results(success_list)
+ result_manager.results = success_list
- res = result_manager.get_results()
- assert isinstance(res, list)
+ test = test_result_factory()
+ test.result = "failure"
+ result_manager.add(test)
+
+ test = test_result_factory()
+ test.result = "error"
+ result_manager.add(test)
+
+ test = test_result_factory()
+ test.result = "skipped"
+ result_manager.add(test)
+
+ assert len(result_manager) == 6
+ assert len(result_manager.filter({"failure"})) == 5
+ assert len(result_manager.filter({"error"})) == 5
+ assert len(result_manager.filter({"skipped"})) == 5
+ assert len(result_manager.filter({"failure", "error"})) == 4
+ assert len(result_manager.filter({"failure", "error", "skipped"})) == 3
+ assert len(result_manager.filter({"success", "failure", "error", "skipped"})) == 0
+
+ def test_get_by_tests(self, test_result_factory: Callable[[], TestResult], result_manager_factory: Callable[[int], ResultManager]) -> None:
+ """Test ResultManager.get_by_tests."""
+ result_manager = result_manager_factory(3)
+
+ test = test_result_factory()
+ test.test = "Test1"
+ result_manager.add(test)
+
+ test = test_result_factory()
+ test.test = "Test2"
+ result_manager.add(test)
+
+ test = test_result_factory()
+ test.test = "Test2"
+ result_manager.add(test)
+
+ assert len(result_manager) == 6
+ assert len(result_manager.filter_by_tests({"Test1"})) == 1
+ rm = result_manager.filter_by_tests({"Test1", "Test2"})
+ assert len(rm) == 3
+ assert len(rm.filter_by_tests({"Test1"})) == 1
+
+ def test_get_by_devices(self, test_result_factory: Callable[[], TestResult], result_manager_factory: Callable[[int], ResultManager]) -> None:
+ """Test ResultManager.get_by_devices."""
+ result_manager = result_manager_factory(3)
+
+ test = test_result_factory()
+ test.name = "Device1"
+ result_manager.add(test)
+
+ test = test_result_factory()
+ test.name = "Device2"
+ result_manager.add(test)
- def test_get_json_results(self, list_result_factory: Callable[[int], list[TestResult]]) -> None:
- """
- test ResultManager.get_json_results
- """
+ test = test_result_factory()
+ test.name = "Device2"
+ result_manager.add(test)
+
+ assert len(result_manager) == 6
+ assert len(result_manager.filter_by_devices({"Device1"})) == 1
+ rm = result_manager.filter_by_devices({"Device1", "Device2"})
+ assert len(rm) == 3
+ assert len(rm.filter_by_devices({"Device1"})) == 1
+
+ def test_get_tests(self, test_result_factory: Callable[[], TestResult], list_result_factory: Callable[[int], list[TestResult]]) -> None:
+ """Test ResultManager.get_tests."""
result_manager = ResultManager()
- success_list = list_result_factory(3)
- for test in success_list:
- test.result = "success"
- result_manager.add_test_results(success_list)
+ tests = list_result_factory(3)
+ for test in tests:
+ test.test = "Test1"
+ result_manager.results = tests
- json_res = result_manager.get_json_results()
- assert isinstance(json_res, str)
+ test = test_result_factory()
+ test.test = "Test2"
+ result_manager.add(test)
- # Verifies it can be deserialized back to a list of dict with the correct values types
- res = json.loads(json_res)
- for test in res:
- assert isinstance(test, dict)
- assert isinstance(test.get("test"), str)
- assert isinstance(test.get("categories"), list)
- assert isinstance(test.get("description"), str)
- assert test.get("custom_field") is None
- assert test.get("result") == "success"
+ assert len(result_manager.get_tests()) == 2
+ assert all(t in result_manager.get_tests() for t in ["Test1", "Test2"])
+
+ def test_get_devices(self, test_result_factory: Callable[[], TestResult], list_result_factory: Callable[[int], list[TestResult]]) -> None:
+ """Test ResultManager.get_tests."""
+ result_manager = ResultManager()
+
+ tests = list_result_factory(3)
+ for test in tests:
+ test.name = "Device1"
+ result_manager.results = tests
+
+ test = test_result_factory()
+ test.name = "Device2"
+ result_manager.add(test)
- # TODO
- # get_result_by_test
- # get_result_by_host
- # get_testcases
- # get_hosts
+ assert len(result_manager.get_devices()) == 2
+ assert all(t in result_manager.get_devices() for t in ["Device1", "Device2"])
diff --git a/tests/units/result_manager/test_models.py b/tests/units/result_manager/test_models.py
index bc7ba8a..2276153 100644
--- a/tests/units/result_manager/test_models.py
+++ b/tests/units/result_manager/test_models.py
@@ -2,18 +2,21 @@
# Use of this source code is governed by the Apache License 2.0
# that can be found in the LICENSE file.
"""ANTA Result Manager models unit tests."""
+
from __future__ import annotations
-from typing import Any, Callable
+from typing import TYPE_CHECKING, Any, Callable
import pytest
# Import as Result to avoid pytest collection
-from anta.result_manager.models import TestResult as Result
from tests.data.json_data import TEST_RESULT_SET_STATUS
from tests.lib.fixture import DEVICE_NAME
from tests.lib.utils import generate_test_ids_dict
+if TYPE_CHECKING:
+ from anta.result_manager.models import TestResult as Result
+
class TestTestResultModels:
"""Test components of anta.result_manager.models."""
diff --git a/tests/units/test_catalog.py b/tests/units/test_catalog.py
index 22a2121..1c7ca8a 100644
--- a/tests/units/test_catalog.py
+++ b/tests/units/test_catalog.py
@@ -1,9 +1,8 @@
# Copyright (c) 2023-2024 Arista Networks, Inc.
# Use of this source code is governed by the Apache License 2.0
# that can be found in the LICENSE file.
-"""
-test anta.device.py
-"""
+"""test anta.device.py."""
+
from __future__ import annotations
from pathlib import Path
@@ -13,7 +12,7 @@ import pytest
from pydantic import ValidationError
from yaml import safe_load
-from anta.catalog import AntaCatalog, AntaTestDefinition
+from anta.catalog import AntaCatalog, AntaCatalogFile, AntaTestDefinition
from anta.models import AntaTest
from anta.tests.interfaces import VerifyL3MTU
from anta.tests.mlag import VerifyMlagStatus
@@ -51,14 +50,21 @@ INIT_CATALOG_DATA: list[dict[str, Any]] = [
VerifyUptime,
VerifyUptime.Input(
minimum=10,
- filters=VerifyUptime.Input.Filters(tags=["fabric"]),
+ filters=VerifyUptime.Input.Filters(tags={"fabric"}),
+ ),
+ ),
+ (
+ VerifyUptime,
+ VerifyUptime.Input(
+ minimum=9,
+ filters=VerifyUptime.Input.Filters(tags={"leaf"}),
),
),
(VerifyReloadCause, {"filters": {"tags": ["leaf", "spine"]}}),
(VerifyCoredump, VerifyCoredump.Input()),
(VerifyAgentLogs, AntaTest.Input()),
- (VerifyCPUUtilization, VerifyCPUUtilization.Input(filters=VerifyCPUUtilization.Input.Filters(tags=["leaf"]))),
- (VerifyMemoryUtilization, VerifyMemoryUtilization.Input(filters=VerifyMemoryUtilization.Input.Filters(tags=["testdevice"]))),
+ (VerifyCPUUtilization, VerifyCPUUtilization.Input(filters=VerifyCPUUtilization.Input.Filters(tags={"leaf"}))),
+ (VerifyMemoryUtilization, VerifyMemoryUtilization.Input(filters=VerifyMemoryUtilization.Input.Filters(tags={"testdevice"}))),
(VerifyFileSystemUtilization, None),
(VerifyNTP, {}),
(VerifyMlagStatus, None),
@@ -70,6 +76,11 @@ INIT_CATALOG_DATA: list[dict[str, Any]] = [
"filename": "test_empty_catalog.yml",
"tests": [],
},
+ {
+ "name": "test_empty_dict_catalog",
+ "filename": "test_empty_dict_catalog.yml",
+ "tests": [],
+ },
]
CATALOG_PARSE_FAIL_DATA: list[dict[str, Any]] = [
{
@@ -146,15 +157,14 @@ CATALOG_FROM_LIST_FAIL_DATA: list[dict[str, Any]] = [
{
"name": "no_input_when_required",
"tests": [(FakeTestWithInput, None)],
- "error": "Field required",
+ "error": "FakeTestWithInput test inputs are not valid: 1 validation error for Input\n\tstring\n\t Field required",
},
{
"name": "wrong_input_type",
- "tests": [(FakeTestWithInput, True)],
- "error": "Value error, Coud not instantiate inputs as type bool is not valid",
+ "tests": [(FakeTestWithInput, {"string": True})],
+ "error": "FakeTestWithInput test inputs are not valid: 1 validation error for Input\n\tstring\n\t Input should be a valid string",
},
]
-
TESTS_SETTER_FAIL_DATA: list[dict[str, Any]] = [
{
"name": "not_a_list",
@@ -169,99 +179,82 @@ TESTS_SETTER_FAIL_DATA: list[dict[str, Any]] = [
]
-class Test_AntaCatalog:
- """
- Test for anta.catalog.AntaCatalog
- """
+class TestAntaCatalog:
+ """Test for anta.catalog.AntaCatalog."""
@pytest.mark.parametrize("catalog_data", INIT_CATALOG_DATA, ids=generate_test_ids_list(INIT_CATALOG_DATA))
def test_parse(self, catalog_data: dict[str, Any]) -> None:
- """
- Instantiate AntaCatalog from a file
- """
- catalog: AntaCatalog = AntaCatalog.parse(str(DATA_DIR / catalog_data["filename"]))
+ """Instantiate AntaCatalog from a file."""
+ catalog: AntaCatalog = AntaCatalog.parse(DATA_DIR / catalog_data["filename"])
assert len(catalog.tests) == len(catalog_data["tests"])
- for test_id, (test, inputs) in enumerate(catalog_data["tests"]):
+ for test_id, (test, inputs_data) in enumerate(catalog_data["tests"]):
assert catalog.tests[test_id].test == test
- if inputs is not None:
- if isinstance(inputs, dict):
- inputs = test.Input(**inputs)
+ if inputs_data is not None:
+ inputs = test.Input(**inputs_data) if isinstance(inputs_data, dict) else inputs_data
assert inputs == catalog.tests[test_id].inputs
@pytest.mark.parametrize("catalog_data", INIT_CATALOG_DATA, ids=generate_test_ids_list(INIT_CATALOG_DATA))
def test_from_list(self, catalog_data: dict[str, Any]) -> None:
- """
- Instantiate AntaCatalog from a list
- """
+ """Instantiate AntaCatalog from a list."""
catalog: AntaCatalog = AntaCatalog.from_list(catalog_data["tests"])
assert len(catalog.tests) == len(catalog_data["tests"])
- for test_id, (test, inputs) in enumerate(catalog_data["tests"]):
+ for test_id, (test, inputs_data) in enumerate(catalog_data["tests"]):
assert catalog.tests[test_id].test == test
- if inputs is not None:
- if isinstance(inputs, dict):
- inputs = test.Input(**inputs)
+ if inputs_data is not None:
+ inputs = test.Input(**inputs_data) if isinstance(inputs_data, dict) else inputs_data
assert inputs == catalog.tests[test_id].inputs
@pytest.mark.parametrize("catalog_data", INIT_CATALOG_DATA, ids=generate_test_ids_list(INIT_CATALOG_DATA))
def test_from_dict(self, catalog_data: dict[str, Any]) -> None:
- """
- Instantiate AntaCatalog from a dict
- """
- with open(file=str(DATA_DIR / catalog_data["filename"]), mode="r", encoding="UTF-8") as file:
+ """Instantiate AntaCatalog from a dict."""
+ file = DATA_DIR / catalog_data["filename"]
+ with file.open(encoding="UTF-8") as file:
data = safe_load(file)
catalog: AntaCatalog = AntaCatalog.from_dict(data)
assert len(catalog.tests) == len(catalog_data["tests"])
- for test_id, (test, inputs) in enumerate(catalog_data["tests"]):
+ for test_id, (test, inputs_data) in enumerate(catalog_data["tests"]):
assert catalog.tests[test_id].test == test
- if inputs is not None:
- if isinstance(inputs, dict):
- inputs = test.Input(**inputs)
+ if inputs_data is not None:
+ inputs = test.Input(**inputs_data) if isinstance(inputs_data, dict) else inputs_data
assert inputs == catalog.tests[test_id].inputs
@pytest.mark.parametrize("catalog_data", CATALOG_PARSE_FAIL_DATA, ids=generate_test_ids_list(CATALOG_PARSE_FAIL_DATA))
def test_parse_fail(self, catalog_data: dict[str, Any]) -> None:
- """
- Errors when instantiating AntaCatalog from a file
- """
- with pytest.raises((ValidationError, ValueError)) as exec_info:
- AntaCatalog.parse(str(DATA_DIR / catalog_data["filename"]))
+ """Errors when instantiating AntaCatalog from a file."""
+ with pytest.raises((ValidationError, TypeError)) as exec_info:
+ AntaCatalog.parse(DATA_DIR / catalog_data["filename"])
if isinstance(exec_info.value, ValidationError):
assert catalog_data["error"] in exec_info.value.errors()[0]["msg"]
else:
assert catalog_data["error"] in str(exec_info)
def test_parse_fail_parsing(self, caplog: pytest.LogCaptureFixture) -> None:
- """
- Errors when instantiating AntaCatalog from a file
- """
- with pytest.raises(Exception) as exec_info:
- AntaCatalog.parse(str(DATA_DIR / "catalog_does_not_exist.yml"))
+ """Errors when instantiating AntaCatalog from a file."""
+ with pytest.raises(FileNotFoundError) as exec_info:
+ AntaCatalog.parse(DATA_DIR / "catalog_does_not_exist.yml")
assert "No such file or directory" in str(exec_info)
assert len(caplog.record_tuples) >= 1
_, _, message = caplog.record_tuples[0]
assert "Unable to parse ANTA Test Catalog file" in message
- assert "FileNotFoundError ([Errno 2] No such file or directory" in message
+ assert "FileNotFoundError: [Errno 2] No such file or directory" in message
@pytest.mark.parametrize("catalog_data", CATALOG_FROM_LIST_FAIL_DATA, ids=generate_test_ids_list(CATALOG_FROM_LIST_FAIL_DATA))
def test_from_list_fail(self, catalog_data: dict[str, Any]) -> None:
- """
- Errors when instantiating AntaCatalog from a list of tuples
- """
+ """Errors when instantiating AntaCatalog from a list of tuples."""
with pytest.raises(ValidationError) as exec_info:
AntaCatalog.from_list(catalog_data["tests"])
assert catalog_data["error"] in exec_info.value.errors()[0]["msg"]
@pytest.mark.parametrize("catalog_data", CATALOG_FROM_DICT_FAIL_DATA, ids=generate_test_ids_list(CATALOG_FROM_DICT_FAIL_DATA))
def test_from_dict_fail(self, catalog_data: dict[str, Any]) -> None:
- """
- Errors when instantiating AntaCatalog from a list of tuples
- """
- with open(file=str(DATA_DIR / catalog_data["filename"]), mode="r", encoding="UTF-8") as file:
+ """Errors when instantiating AntaCatalog from a list of tuples."""
+ file = DATA_DIR / catalog_data["filename"]
+ with file.open(encoding="UTF-8") as file:
data = safe_load(file)
- with pytest.raises((ValidationError, ValueError)) as exec_info:
+ with pytest.raises((ValidationError, TypeError)) as exec_info:
AntaCatalog.from_dict(data)
if isinstance(exec_info.value, ValidationError):
assert catalog_data["error"] in exec_info.value.errors()[0]["msg"]
@@ -269,9 +262,7 @@ class Test_AntaCatalog:
assert catalog_data["error"] in str(exec_info)
def test_filename(self) -> None:
- """
- Test filename
- """
+ """Test filename."""
catalog = AntaCatalog(filename="test")
assert catalog.filename == Path("test")
catalog = AntaCatalog(filename=Path("test"))
@@ -279,33 +270,97 @@ class Test_AntaCatalog:
@pytest.mark.parametrize("catalog_data", INIT_CATALOG_DATA, ids=generate_test_ids_list(INIT_CATALOG_DATA))
def test__tests_setter_success(self, catalog_data: dict[str, Any]) -> None:
- """
- Success when setting AntaCatalog.tests from a list of tuples
- """
+ """Success when setting AntaCatalog.tests from a list of tuples."""
catalog = AntaCatalog()
catalog.tests = [AntaTestDefinition(test=test, inputs=inputs) for test, inputs in catalog_data["tests"]]
assert len(catalog.tests) == len(catalog_data["tests"])
- for test_id, (test, inputs) in enumerate(catalog_data["tests"]):
+ for test_id, (test, inputs_data) in enumerate(catalog_data["tests"]):
assert catalog.tests[test_id].test == test
- if inputs is not None:
- if isinstance(inputs, dict):
- inputs = test.Input(**inputs)
+ if inputs_data is not None:
+ inputs = test.Input(**inputs_data) if isinstance(inputs_data, dict) else inputs_data
assert inputs == catalog.tests[test_id].inputs
@pytest.mark.parametrize("catalog_data", TESTS_SETTER_FAIL_DATA, ids=generate_test_ids_list(TESTS_SETTER_FAIL_DATA))
def test__tests_setter_fail(self, catalog_data: dict[str, Any]) -> None:
- """
- Errors when setting AntaCatalog.tests from a list of tuples
- """
+ """Errors when setting AntaCatalog.tests from a list of tuples."""
catalog = AntaCatalog()
- with pytest.raises(ValueError) as exec_info:
+ with pytest.raises(TypeError) as exec_info:
catalog.tests = catalog_data["tests"]
assert catalog_data["error"] in str(exec_info)
+ def test_build_indexes_all(self) -> None:
+ """Test AntaCatalog.build_indexes()."""
+ catalog: AntaCatalog = AntaCatalog.parse(DATA_DIR / "test_catalog_with_tags.yml")
+ catalog.build_indexes()
+ assert len(catalog.tests_without_tags) == 5
+ assert "leaf" in catalog.tag_to_tests
+ assert len(catalog.tag_to_tests["leaf"]) == 3
+ all_unique_tests = catalog.tests_without_tags
+ for tests in catalog.tag_to_tests.values():
+ all_unique_tests.update(tests)
+ assert len(all_unique_tests) == 11
+ assert catalog.indexes_built is True
+
+ def test_build_indexes_filtered(self) -> None:
+ """Test AntaCatalog.build_indexes()."""
+ catalog: AntaCatalog = AntaCatalog.parse(DATA_DIR / "test_catalog_with_tags.yml")
+ catalog.build_indexes({"VerifyUptime", "VerifyCoredump", "VerifyL3MTU"})
+ assert "leaf" in catalog.tag_to_tests
+ assert len(catalog.tag_to_tests["leaf"]) == 1
+ assert len(catalog.tests_without_tags) == 1
+ all_unique_tests = catalog.tests_without_tags
+ for tests in catalog.tag_to_tests.values():
+ all_unique_tests.update(tests)
+ assert len(all_unique_tests) == 4
+ assert catalog.indexes_built is True
+
def test_get_tests_by_tags(self) -> None:
- """
- Test AntaCatalog.test_get_tests_by_tags()
- """
- catalog: AntaCatalog = AntaCatalog.parse(str(DATA_DIR / "test_catalog_with_tags.yml"))
- tests: list[AntaTestDefinition] = catalog.get_tests_by_tags(tags=["leaf"])
- assert len(tests) == 2
+ """Test AntaCatalog.get_tests_by_tags()."""
+ catalog: AntaCatalog = AntaCatalog.parse(DATA_DIR / "test_catalog_with_tags.yml")
+ catalog.build_indexes()
+ tests: set[AntaTestDefinition] = catalog.get_tests_by_tags(tags={"leaf"})
+ assert len(tests) == 3
+ tests = catalog.get_tests_by_tags(tags={"leaf", "spine"}, strict=True)
+ assert len(tests) == 1
+
+ def test_merge(self) -> None:
+ """Test AntaCatalog.merge()."""
+ catalog1: AntaCatalog = AntaCatalog.parse(DATA_DIR / "test_catalog.yml")
+ assert len(catalog1.tests) == 1
+ catalog2: AntaCatalog = AntaCatalog.parse(DATA_DIR / "test_catalog.yml")
+ assert len(catalog2.tests) == 1
+ catalog3: AntaCatalog = AntaCatalog.parse(DATA_DIR / "test_catalog_medium.yml")
+ assert len(catalog3.tests) == 228
+
+ assert len(catalog1.merge(catalog2).tests) == 2
+ assert len(catalog1.tests) == 1
+ assert len(catalog2.tests) == 1
+
+ assert len(catalog2.merge(catalog3).tests) == 229
+ assert len(catalog2.tests) == 1
+ assert len(catalog3.tests) == 228
+
+ def test_dump(self) -> None:
+ """Test AntaCatalog.dump()."""
+ catalog: AntaCatalog = AntaCatalog.parse(DATA_DIR / "test_catalog.yml")
+ assert len(catalog.tests) == 1
+ file: AntaCatalogFile = catalog.dump()
+ assert sum(len(tests) for tests in file.root.values()) == 1
+
+ catalog = AntaCatalog.parse(DATA_DIR / "test_catalog_medium.yml")
+ assert len(catalog.tests) == 228
+ file = catalog.dump()
+ assert sum(len(tests) for tests in file.root.values()) == 228
+
+
+class TestAntaCatalogFile: # pylint: disable=too-few-public-methods
+ """Test for anta.catalog.AntaCatalogFile."""
+
+ def test_yaml(self) -> None:
+ """Test AntaCatalogFile.yaml()."""
+ file = DATA_DIR / "test_catalog_medium.yml"
+ catalog = AntaCatalog.parse(file)
+ assert len(catalog.tests) == 228
+ catalog_yaml_str = catalog.dump().yaml()
+ with file.open(encoding="UTF-8") as f:
+ assert catalog_yaml_str == f.read()
diff --git a/tests/units/test_custom_types.py b/tests/units/test_custom_types.py
new file mode 100644
index 0000000..8119849
--- /dev/null
+++ b/tests/units/test_custom_types.py
@@ -0,0 +1,264 @@
+# Copyright (c) 2023-2024 Arista Networks, Inc.
+# Use of this source code is governed by the Apache License 2.0
+# that can be found in the LICENSE file.
+"""Tests for `anta.custom_types`.
+
+The intention is only to test here what is not used already in other places.
+
+TODO: Expand later.
+"""
+
+from __future__ import annotations
+
+import re
+
+import pytest
+
+from anta.custom_types import (
+ REGEX_BGP_IPV4_MPLS_VPN,
+ REGEX_BGP_IPV4_UNICAST,
+ REGEXP_BGP_IPV4_MPLS_LABELS,
+ REGEXP_BGP_L2VPN_AFI,
+ REGEXP_EOS_BLACKLIST_CMDS,
+ REGEXP_INTERFACE_ID,
+ REGEXP_PATH_MARKERS,
+ REGEXP_TYPE_EOS_INTERFACE,
+ REGEXP_TYPE_HOSTNAME,
+ REGEXP_TYPE_VXLAN_SRC_INTERFACE,
+ aaa_group_prefix,
+ bgp_multiprotocol_capabilities_abbreviations,
+ interface_autocomplete,
+ interface_case_sensitivity,
+)
+
+# ------------------------------------------------------------------------------
+# TEST custom_types.py regular expressions
+# ------------------------------------------------------------------------------
+
+
+def test_regexp_path_markers() -> None:
+ """Test REGEXP_PATH_MARKERS."""
+ # Test strings that should match the pattern
+ assert re.search(REGEXP_PATH_MARKERS, "show/bgp/interfaces") is not None
+ assert re.search(REGEXP_PATH_MARKERS, "show\\bgp") is not None
+ assert re.search(REGEXP_PATH_MARKERS, "show bgp") is not None
+
+ # Test strings that should not match the pattern
+ assert re.search(REGEXP_PATH_MARKERS, "aaaa") is None
+ assert re.search(REGEXP_PATH_MARKERS, "11111") is None
+ assert re.search(REGEXP_PATH_MARKERS, ".[]?<>") is None
+
+
+def test_regexp_bgp_l2vpn_afi() -> None:
+ """Test REGEXP_BGP_L2VPN_AFI."""
+ # Test strings that should match the pattern
+ assert re.search(REGEXP_BGP_L2VPN_AFI, "l2vpn-evpn") is not None
+ assert re.search(REGEXP_BGP_L2VPN_AFI, "l2 vpn evpn") is not None
+ assert re.search(REGEXP_BGP_L2VPN_AFI, "l2-vpn evpn") is not None
+ assert re.search(REGEXP_BGP_L2VPN_AFI, "l2vpn evpn") is not None
+ assert re.search(REGEXP_BGP_L2VPN_AFI, "l2vpnevpn") is not None
+ assert re.search(REGEXP_BGP_L2VPN_AFI, "l2 vpnevpn") is not None
+
+ # Test strings that should not match the pattern
+ assert re.search(REGEXP_BGP_L2VPN_AFI, "al2vpn evpn") is None
+ assert re.search(REGEXP_BGP_L2VPN_AFI, "l2vpn-evpna") is None
+
+
+def test_regexp_bgp_ipv4_mpls_labels() -> None:
+ """Test REGEXP_BGP_IPV4_MPLS_LABELS."""
+ assert re.search(REGEXP_BGP_IPV4_MPLS_LABELS, "ipv4-mpls-label") is not None
+ assert re.search(REGEXP_BGP_IPV4_MPLS_LABELS, "ipv4 mpls labels") is not None
+ assert re.search(REGEXP_BGP_IPV4_MPLS_LABELS, "ipv4Mplslabel") is None
+
+
+def test_regex_bgp_ipv4_mpls_vpn() -> None:
+ """Test REGEX_BGP_IPV4_MPLS_VPN."""
+ assert re.search(REGEX_BGP_IPV4_MPLS_VPN, "ipv4-mpls-vpn") is not None
+ assert re.search(REGEX_BGP_IPV4_MPLS_VPN, "ipv4_mplsvpn") is None
+
+
+def test_regex_bgp_ipv4_unicast() -> None:
+ """Test REGEX_BGP_IPV4_UNICAST."""
+ assert re.search(REGEX_BGP_IPV4_UNICAST, "ipv4-uni-cast") is not None
+ assert re.search(REGEX_BGP_IPV4_UNICAST, "ipv4+unicast") is None
+
+
+def test_regexp_type_interface_id() -> None:
+ """Test REGEXP_INTERFACE_ID."""
+ intf_id_re = re.compile(f"{REGEXP_INTERFACE_ID}")
+
+ # Test strings that should match the pattern
+ assert intf_id_re.search("123") is not None
+ assert intf_id_re.search("123/456") is not None
+ assert intf_id_re.search("123.456") is not None
+ assert intf_id_re.search("123/456.789") is not None
+
+
+def test_regexp_type_eos_interface() -> None:
+ """Test REGEXP_TYPE_EOS_INTERFACE."""
+ # Test strings that should match the pattern
+ assert re.match(REGEXP_TYPE_EOS_INTERFACE, "Ethernet0") is not None
+ assert re.match(REGEXP_TYPE_EOS_INTERFACE, "Vlan100") is not None
+ assert re.match(REGEXP_TYPE_EOS_INTERFACE, "Port-Channel1/0") is not None
+ assert re.match(REGEXP_TYPE_EOS_INTERFACE, "Loopback0.1") is not None
+ assert re.match(REGEXP_TYPE_EOS_INTERFACE, "Management0/0/0") is not None
+ assert re.match(REGEXP_TYPE_EOS_INTERFACE, "Tunnel1") is not None
+ assert re.match(REGEXP_TYPE_EOS_INTERFACE, "Vxlan1") is not None
+ assert re.match(REGEXP_TYPE_EOS_INTERFACE, "Fabric1") is not None
+ assert re.match(REGEXP_TYPE_EOS_INTERFACE, "Dps1") is not None
+
+ # Test strings that should not match the pattern
+ assert re.match(REGEXP_TYPE_EOS_INTERFACE, "Ethernet") is None
+ assert re.match(REGEXP_TYPE_EOS_INTERFACE, "Vlan") is None
+ assert re.match(REGEXP_TYPE_EOS_INTERFACE, "Port-Channel") is None
+ assert re.match(REGEXP_TYPE_EOS_INTERFACE, "Loopback.") is None
+ assert re.match(REGEXP_TYPE_EOS_INTERFACE, "Management/") is None
+ assert re.match(REGEXP_TYPE_EOS_INTERFACE, "Tunnel") is None
+ assert re.match(REGEXP_TYPE_EOS_INTERFACE, "Vxlan") is None
+ assert re.match(REGEXP_TYPE_EOS_INTERFACE, "Fabric") is None
+ assert re.match(REGEXP_TYPE_EOS_INTERFACE, "Dps") is None
+
+ assert re.match(REGEXP_TYPE_EOS_INTERFACE, "Ethernet1/a") is None
+ assert re.match(REGEXP_TYPE_EOS_INTERFACE, "Port-Channel-100") is None
+ assert re.match(REGEXP_TYPE_EOS_INTERFACE, "Loopback.10") is None
+ assert re.match(REGEXP_TYPE_EOS_INTERFACE, "Management/10") is None
+
+
+def test_regexp_type_vxlan_src_interface() -> None:
+ """Test REGEXP_TYPE_VXLAN_SRC_INTERFACE."""
+ # Test strings that should match the pattern
+ assert re.match(REGEXP_TYPE_VXLAN_SRC_INTERFACE, "Loopback0") is not None
+ assert re.match(REGEXP_TYPE_VXLAN_SRC_INTERFACE, "Loopback1") is not None
+ assert re.match(REGEXP_TYPE_VXLAN_SRC_INTERFACE, "Loopback99") is not None
+ assert re.match(REGEXP_TYPE_VXLAN_SRC_INTERFACE, "Loopback100") is not None
+ assert re.match(REGEXP_TYPE_VXLAN_SRC_INTERFACE, "Loopback8190") is not None
+ assert re.match(REGEXP_TYPE_VXLAN_SRC_INTERFACE, "Loopback8199") is not None
+
+ # Test strings that should not match the pattern
+ assert re.match(REGEXP_TYPE_VXLAN_SRC_INTERFACE, "Loopback") is None
+ assert re.match(REGEXP_TYPE_VXLAN_SRC_INTERFACE, "Loopback9001") is None
+ assert re.match(REGEXP_TYPE_VXLAN_SRC_INTERFACE, "Loopback9000") is None
+
+
+def test_regexp_type_hostname() -> None:
+ """Test REGEXP_TYPE_HOSTNAME."""
+ # Test strings that should match the pattern
+ assert re.match(REGEXP_TYPE_HOSTNAME, "hostname") is not None
+ assert re.match(REGEXP_TYPE_HOSTNAME, "hostname.com") is not None
+ assert re.match(REGEXP_TYPE_HOSTNAME, "host-name.com") is not None
+ assert re.match(REGEXP_TYPE_HOSTNAME, "host.name.com") is not None
+ assert re.match(REGEXP_TYPE_HOSTNAME, "host-name1.com") is not None
+
+ # Test strings that should not match the pattern
+ assert re.match(REGEXP_TYPE_HOSTNAME, "-hostname.com") is None
+ assert re.match(REGEXP_TYPE_HOSTNAME, ".hostname.com") is None
+ assert re.match(REGEXP_TYPE_HOSTNAME, "hostname-.com") is None
+ assert re.match(REGEXP_TYPE_HOSTNAME, "hostname..com") is None
+
+
+@pytest.mark.parametrize(
+ ("test_string", "expected"),
+ [
+ ("reload", True), # matches "^reload.*"
+ ("reload now", True), # matches "^reload.*"
+ ("configure terminal", True), # matches "^conf\w*\s*(terminal|session)*"
+ ("conf t", True), # matches "^conf\w*\s*(terminal|session)*"
+ ("write memory", True), # matches "^wr\w*\s*\w+"
+ ("wr mem", True), # matches "^wr\w*\s*\w+"
+ ("show running-config", False), # does not match any regex
+ ("no shutdown", False), # does not match any regex
+ ("", False), # empty string does not match any regex
+ ],
+)
+def test_regexp_eos_blacklist_cmds(test_string: str, expected: bool) -> None:
+ """Test REGEXP_EOS_BLACKLIST_CMDS."""
+
+ def matches_any_regex(string: str, regex_list: list[str]) -> bool:
+ """
+ Check if a string matches at least one regular expression in a list.
+
+ :param string: The string to check.
+ :param regex_list: A list of regular expressions.
+ :return: True if the string matches at least one regular expression, False otherwise.
+ """
+ return any(re.match(regex, string) for regex in regex_list)
+
+ assert matches_any_regex(test_string, REGEXP_EOS_BLACKLIST_CMDS) == expected
+
+
+# ------------------------------------------------------------------------------
+# TEST custom_types.py functions
+# ------------------------------------------------------------------------------
+
+
+def test_interface_autocomplete_success() -> None:
+ """Test interface_autocomplete with valid inputs."""
+ assert interface_autocomplete("et1") == "Ethernet1"
+ assert interface_autocomplete("et1/1") == "Ethernet1/1"
+ assert interface_autocomplete("et1.1") == "Ethernet1.1"
+ assert interface_autocomplete("et1/1.1") == "Ethernet1/1.1"
+ assert interface_autocomplete("eth2") == "Ethernet2"
+ assert interface_autocomplete("po3") == "Port-Channel3"
+ assert interface_autocomplete("lo4") == "Loopback4"
+
+
+def test_interface_autocomplete_no_alias() -> None:
+ """Test interface_autocomplete with inputs that don't have aliases."""
+ assert interface_autocomplete("GigabitEthernet1") == "GigabitEthernet1"
+ assert interface_autocomplete("Vlan10") == "Vlan10"
+ assert interface_autocomplete("Tunnel100") == "Tunnel100"
+
+
+def test_interface_autocomplete_failure() -> None:
+ """Trigger ValueError for interface_autocomplete."""
+ with pytest.raises(ValueError, match="Could not parse interface ID in interface"):
+ interface_autocomplete("ThisIsNotAnInterface")
+
+
+@pytest.mark.parametrize(
+ ("str_input", "expected_output"),
+ [
+ pytest.param("L2VPNEVPN", "l2VpnEvpn", id="l2VpnEvpn"),
+ pytest.param("ipv4-mplsLabels", "ipv4MplsLabels", id="ipv4MplsLabels"),
+ pytest.param("ipv4-mpls-vpn", "ipv4MplsVpn", id="ipv4MplsVpn"),
+ pytest.param("ipv4-unicast", "ipv4Unicast", id="ipv4Unicast"),
+ pytest.param("BLAH", "BLAH", id="unmatched"),
+ ],
+)
+def test_bgp_multiprotocol_capabilities_abbreviationsh(str_input: str, expected_output: str) -> None:
+ """Test bgp_multiprotocol_capabilities_abbreviations."""
+ assert bgp_multiprotocol_capabilities_abbreviations(str_input) == expected_output
+
+
+def test_aaa_group_prefix_known_method() -> None:
+ """Test aaa_group_prefix with a known method."""
+ assert aaa_group_prefix("local") == "local"
+ assert aaa_group_prefix("none") == "none"
+ assert aaa_group_prefix("logging") == "logging"
+
+
+def test_aaa_group_prefix_unknown_method() -> None:
+ """Test aaa_group_prefix with an unknown method."""
+ assert aaa_group_prefix("demo") == "group demo"
+ assert aaa_group_prefix("group1") == "group group1"
+
+
+def test_interface_case_sensitivity_lowercase() -> None:
+ """Test interface_case_sensitivity with lowercase inputs."""
+ assert interface_case_sensitivity("ethernet") == "Ethernet"
+ assert interface_case_sensitivity("vlan") == "Vlan"
+ assert interface_case_sensitivity("loopback") == "Loopback"
+
+
+def test_interface_case_sensitivity_mixed_case() -> None:
+ """Test interface_case_sensitivity with mixed case inputs."""
+ assert interface_case_sensitivity("Ethernet") == "Ethernet"
+ assert interface_case_sensitivity("Vlan") == "Vlan"
+ assert interface_case_sensitivity("Loopback") == "Loopback"
+
+
+def test_interface_case_sensitivity_uppercase() -> None:
+ """Test interface_case_sensitivity with uppercase inputs."""
+ assert interface_case_sensitivity("ETHERNET") == "ETHERNET"
+ assert interface_case_sensitivity("VLAN") == "VLAN"
+ assert interface_case_sensitivity("LOOPBACK") == "LOOPBACK"
diff --git a/tests/units/test_device.py b/tests/units/test_device.py
index 845da2b..e8a0c5f 100644
--- a/tests/units/test_device.py
+++ b/tests/units/test_device.py
@@ -1,29 +1,29 @@
# Copyright (c) 2023-2024 Arista Networks, Inc.
# Use of this source code is governed by the Apache License 2.0
# that can be found in the LICENSE file.
-"""
-test anta.device.py
-"""
+"""test anta.device.py."""
from __future__ import annotations
import asyncio
from pathlib import Path
-from typing import Any
+from typing import TYPE_CHECKING, Any
from unittest.mock import patch
import httpx
import pytest
-from _pytest.mark.structures import ParameterSet
from asyncssh import SSHClientConnection, SSHClientConnectionOptions
from rich import print as rprint
-from anta import aioeapi
+import asynceapi
from anta.device import AntaDevice, AsyncEOSDevice
from anta.models import AntaCommand
from tests.lib.fixture import COMMAND_OUTPUT
from tests.lib.utils import generate_test_ids_list
+if TYPE_CHECKING:
+ from _pytest.mark.structures import ParameterSet
+
INIT_DATA: list[dict[str, Any]] = [
{
"name": "no name, no port",
@@ -128,7 +128,7 @@ EQUALITY_DATA: list[dict[str, Any]] = [
"expected": False,
},
]
-AIOEAPI_COLLECT_DATA: list[dict[str, Any]] = [
+ASYNCEAPI_COLLECT_DATA: list[dict[str, Any]] = [
{
"name": "command",
"device": {},
@@ -155,8 +155,8 @@ AIOEAPI_COLLECT_DATA: list[dict[str, Any]] = [
"memTotal": 8099732,
"memFree": 4989568,
"isIntlVersion": False,
- }
- ]
+ },
+ ],
},
},
"expected": {
@@ -211,7 +211,7 @@ AIOEAPI_COLLECT_DATA: list[dict[str, Any]] = [
"memFree": 4989568,
"isIntlVersion": False,
},
- ]
+ ],
},
},
"expected": {
@@ -266,7 +266,7 @@ AIOEAPI_COLLECT_DATA: list[dict[str, Any]] = [
"memFree": 4989568,
"isIntlVersion": False,
},
- ]
+ ],
},
},
"expected": {
@@ -322,7 +322,7 @@ AIOEAPI_COLLECT_DATA: list[dict[str, Any]] = [
"memFree": 4989568,
"isIntlVersion": False,
},
- ]
+ ],
},
},
"expected": {
@@ -350,14 +350,18 @@ AIOEAPI_COLLECT_DATA: list[dict[str, Any]] = [
},
},
{
- "name": "aioeapi.EapiCommandError",
+ "name": "asynceapi.EapiCommandError",
"device": {},
"command": {
"command": "show version",
"patch_kwargs": {
- "side_effect": aioeapi.EapiCommandError(
- passed=[], failed="show version", errors=["Authorization denied for command 'show version'"], errmsg="Invalid command", not_exec=[]
- )
+ "side_effect": asynceapi.EapiCommandError(
+ passed=[],
+ failed="show version",
+ errors=["Authorization denied for command 'show version'"],
+ errmsg="Invalid command",
+ not_exec=[],
+ ),
},
},
"expected": {"output": None, "errors": ["Authorization denied for command 'show version'"]},
@@ -369,7 +373,7 @@ AIOEAPI_COLLECT_DATA: list[dict[str, Any]] = [
"command": "show version",
"patch_kwargs": {"side_effect": httpx.HTTPError(message="404")},
},
- "expected": {"output": None, "errors": ["404"]},
+ "expected": {"output": None, "errors": ["HTTPError: 404"]},
},
{
"name": "httpx.ConnectError",
@@ -378,16 +382,16 @@ AIOEAPI_COLLECT_DATA: list[dict[str, Any]] = [
"command": "show version",
"patch_kwargs": {"side_effect": httpx.ConnectError(message="Cannot open port")},
},
- "expected": {"output": None, "errors": ["Cannot open port"]},
+ "expected": {"output": None, "errors": ["ConnectError: Cannot open port"]},
},
]
-AIOEAPI_COPY_DATA: list[dict[str, Any]] = [
+ASYNCEAPI_COPY_DATA: list[dict[str, Any]] = [
{
"name": "from",
"device": {},
"copy": {
"sources": [Path("/mnt/flash"), Path("/var/log/agents")],
- "destination": Path("."),
+ "destination": Path(),
"direction": "from",
},
},
@@ -396,7 +400,7 @@ AIOEAPI_COPY_DATA: list[dict[str, Any]] = [
"device": {},
"copy": {
"sources": [Path("/mnt/flash"), Path("/var/log/agents")],
- "destination": Path("."),
+ "destination": Path(),
"direction": "to",
},
},
@@ -405,7 +409,7 @@ AIOEAPI_COPY_DATA: list[dict[str, Any]] = [
"device": {},
"copy": {
"sources": [Path("/mnt/flash"), Path("/var/log/agents")],
- "destination": Path("."),
+ "destination": Path(),
"direction": "wrong",
},
},
@@ -417,26 +421,28 @@ REFRESH_DATA: list[dict[str, Any]] = [
"patch_kwargs": (
{"return_value": True},
{
- "return_value": {
- "mfgName": "Arista",
- "modelName": "DCS-7280CR3-32P4-F",
- "hardwareRevision": "11.00",
- "serialNumber": "JPE19500066",
- "systemMacAddress": "fc:bd:67:3d:13:c5",
- "hwMacAddress": "fc:bd:67:3d:13:c5",
- "configMacAddress": "00:00:00:00:00:00",
- "version": "4.31.1F-34361447.fraserrel (engineering build)",
- "architecture": "x86_64",
- "internalVersion": "4.31.1F-34361447.fraserrel",
- "internalBuildId": "4940d112-a2fc-4970-8b5a-a16cd03fd08c",
- "imageFormatVersion": "3.0",
- "imageOptimization": "Default",
- "bootupTimestamp": 1700729434.5892005,
- "uptime": 20666.78,
- "memTotal": 8099732,
- "memFree": 4989568,
- "isIntlVersion": False,
- }
+ "return_value": [
+ {
+ "mfgName": "Arista",
+ "modelName": "DCS-7280CR3-32P4-F",
+ "hardwareRevision": "11.00",
+ "serialNumber": "JPE19500066",
+ "systemMacAddress": "fc:bd:67:3d:13:c5",
+ "hwMacAddress": "fc:bd:67:3d:13:c5",
+ "configMacAddress": "00:00:00:00:00:00",
+ "version": "4.31.1F-34361447.fraserrel (engineering build)",
+ "architecture": "x86_64",
+ "internalVersion": "4.31.1F-34361447.fraserrel",
+ "internalBuildId": "4940d112-a2fc-4970-8b5a-a16cd03fd08c",
+ "imageFormatVersion": "3.0",
+ "imageOptimization": "Default",
+ "bootupTimestamp": 1700729434.5892005,
+ "uptime": 20666.78,
+ "memTotal": 8099732,
+ "memFree": 4989568,
+ "isIntlVersion": False,
+ }
+ ],
},
),
"expected": {"is_online": True, "established": True, "hw_model": "DCS-7280CR3-32P4-F"},
@@ -466,7 +472,7 @@ REFRESH_DATA: list[dict[str, Any]] = [
"memTotal": 8099732,
"memFree": 4989568,
"isIntlVersion": False,
- }
+ },
},
),
"expected": {"is_online": False, "established": False, "hw_model": None},
@@ -477,38 +483,44 @@ REFRESH_DATA: list[dict[str, Any]] = [
"patch_kwargs": (
{"return_value": True},
{
- "return_value": {
- "mfgName": "Arista",
- "hardwareRevision": "11.00",
- "serialNumber": "JPE19500066",
- "systemMacAddress": "fc:bd:67:3d:13:c5",
- "hwMacAddress": "fc:bd:67:3d:13:c5",
- "configMacAddress": "00:00:00:00:00:00",
- "version": "4.31.1F-34361447.fraserrel (engineering build)",
- "architecture": "x86_64",
- "internalVersion": "4.31.1F-34361447.fraserrel",
- "internalBuildId": "4940d112-a2fc-4970-8b5a-a16cd03fd08c",
- "imageFormatVersion": "3.0",
- "imageOptimization": "Default",
- "bootupTimestamp": 1700729434.5892005,
- "uptime": 20666.78,
- "memTotal": 8099732,
- "memFree": 4989568,
- "isIntlVersion": False,
- }
+ "return_value": [
+ {
+ "mfgName": "Arista",
+ "hardwareRevision": "11.00",
+ "serialNumber": "JPE19500066",
+ "systemMacAddress": "fc:bd:67:3d:13:c5",
+ "hwMacAddress": "fc:bd:67:3d:13:c5",
+ "configMacAddress": "00:00:00:00:00:00",
+ "version": "4.31.1F-34361447.fraserrel (engineering build)",
+ "architecture": "x86_64",
+ "internalVersion": "4.31.1F-34361447.fraserrel",
+ "internalBuildId": "4940d112-a2fc-4970-8b5a-a16cd03fd08c",
+ "imageFormatVersion": "3.0",
+ "imageOptimization": "Default",
+ "bootupTimestamp": 1700729434.5892005,
+ "uptime": 20666.78,
+ "memTotal": 8099732,
+ "memFree": 4989568,
+ "isIntlVersion": False,
+ }
+ ],
},
),
"expected": {"is_online": True, "established": False, "hw_model": None},
},
{
- "name": "aioeapi.EapiCommandError",
+ "name": "asynceapi.EapiCommandError",
"device": {},
"patch_kwargs": (
{"return_value": True},
{
- "side_effect": aioeapi.EapiCommandError(
- passed=[], failed="show version", errors=["Authorization denied for command 'show version'"], errmsg="Invalid command", not_exec=[]
- )
+ "side_effect": asynceapi.EapiCommandError(
+ passed=[],
+ failed="show version",
+ errors=["Authorization denied for command 'show version'"],
+ errmsg="Invalid command",
+ not_exec=[],
+ ),
},
),
"expected": {"is_online": True, "established": False, "hw_model": None},
@@ -599,21 +611,17 @@ CACHE_STATS_DATA: list[ParameterSet] = [
class TestAntaDevice:
- """
- Test for anta.device.AntaDevice Abstract class
- """
+ """Test for anta.device.AntaDevice Abstract class."""
- @pytest.mark.asyncio
+ @pytest.mark.asyncio()
@pytest.mark.parametrize(
- "device, command_data, expected_data",
- map(lambda d: (d["device"], d["command"], d["expected"]), COLLECT_DATA),
+ ("device", "command_data", "expected_data"),
+ ((d["device"], d["command"], d["expected"]) for d in COLLECT_DATA),
indirect=["device"],
ids=generate_test_ids_list(COLLECT_DATA),
)
async def test_collect(self, device: AntaDevice, command_data: dict[str, Any], expected_data: dict[str, Any]) -> None:
- """
- Test AntaDevice.collect behavior
- """
+ """Test AntaDevice.collect behavior."""
command = AntaCommand(command=command_data["command"], use_cache=command_data["use_cache"])
# Dummy output for cache hit
@@ -636,7 +644,7 @@ class TestAntaDevice:
assert current_cached_data == COMMAND_OUTPUT
assert device.cache.hit_miss_ratio["hits"] == 1
else: # command is not allowed to use cache
- device._collect.assert_called_once_with(command=command) # type: ignore[attr-defined] # pylint: disable=protected-access
+ device._collect.assert_called_once_with(command=command, collection_id=None) # type: ignore[attr-defined] # pylint: disable=protected-access
assert command.output == COMMAND_OUTPUT
if expected_data["cache_hit"] is True:
assert current_cached_data == cached_output
@@ -644,34 +652,23 @@ class TestAntaDevice:
assert current_cached_data is None
else: # device is disabled
assert device.cache is None
- device._collect.assert_called_once_with(command=command) # type: ignore[attr-defined] # pylint: disable=protected-access
+ device._collect.assert_called_once_with(command=command, collection_id=None) # type: ignore[attr-defined] # pylint: disable=protected-access
- @pytest.mark.parametrize("device, expected", CACHE_STATS_DATA, indirect=["device"])
+ @pytest.mark.parametrize(("device", "expected"), CACHE_STATS_DATA, indirect=["device"])
def test_cache_statistics(self, device: AntaDevice, expected: dict[str, Any] | None) -> None:
- """
- Verify that when cache statistics attribute does not exist
- TODO add a test where cache has some value
- """
- assert device.cache_statistics == expected
+ """Verify that when cache statistics attribute does not exist.
- def test_supports(self, device: AntaDevice) -> None:
+ TODO add a test where cache has some value.
"""
- Test if the supports() method
- """
- command = AntaCommand(command="show hardware counter drop", errors=["Unavailable command (not supported on this hardware platform) (at token 2: 'counter')"])
- assert device.supports(command) is False
- command = AntaCommand(command="show hardware counter drop")
- assert device.supports(command) is True
+ assert device.cache_statistics == expected
class TestAsyncEOSDevice:
- """
- Test for anta.device.AsyncEOSDevice
- """
+ """Test for anta.device.AsyncEOSDevice."""
@pytest.mark.parametrize("data", INIT_DATA, ids=generate_test_ids_list(INIT_DATA))
def test__init__(self, data: dict[str, Any]) -> None:
- """Test the AsyncEOSDevice constructor"""
+ """Test the AsyncEOSDevice constructor."""
device = AsyncEOSDevice(**data["device"])
assert device.name == data["expected"]["name"]
@@ -683,12 +680,12 @@ class TestAsyncEOSDevice:
assert device.cache_locks is not None
hash(device)
- with patch("anta.device.__DEBUG__", True):
+ with patch("anta.device.__DEBUG__", new=True):
rprint(device)
@pytest.mark.parametrize("data", EQUALITY_DATA, ids=generate_test_ids_list(EQUALITY_DATA))
def test__eq(self, data: dict[str, Any]) -> None:
- """Test the AsyncEOSDevice equality"""
+ """Test the AsyncEOSDevice equality."""
device1 = AsyncEOSDevice(**data["device1"])
device2 = AsyncEOSDevice(**data["device2"])
if data["expected"]:
@@ -696,49 +693,46 @@ class TestAsyncEOSDevice:
else:
assert device1 != device2
- @pytest.mark.asyncio
+ @pytest.mark.asyncio()
@pytest.mark.parametrize(
- "async_device, patch_kwargs, expected",
- map(lambda d: (d["device"], d["patch_kwargs"], d["expected"]), REFRESH_DATA),
+ ("async_device", "patch_kwargs", "expected"),
+ ((d["device"], d["patch_kwargs"], d["expected"]) for d in REFRESH_DATA),
ids=generate_test_ids_list(REFRESH_DATA),
indirect=["async_device"],
)
async def test_refresh(self, async_device: AsyncEOSDevice, patch_kwargs: list[dict[str, Any]], expected: dict[str, Any]) -> None:
# pylint: disable=protected-access
- """Test AsyncEOSDevice.refresh()"""
- with patch.object(async_device._session, "check_connection", **patch_kwargs[0]):
- with patch.object(async_device._session, "cli", **patch_kwargs[1]):
- await async_device.refresh()
- async_device._session.check_connection.assert_called_once()
- if expected["is_online"]:
- async_device._session.cli.assert_called_once()
- assert async_device.is_online == expected["is_online"]
- assert async_device.established == expected["established"]
- assert async_device.hw_model == expected["hw_model"]
+ """Test AsyncEOSDevice.refresh()."""
+ with patch.object(async_device._session, "check_connection", **patch_kwargs[0]), patch.object(async_device._session, "cli", **patch_kwargs[1]):
+ await async_device.refresh()
+ async_device._session.check_connection.assert_called_once() # type: ignore[attr-defined] # asynceapi.Device.check_connection is patched
+ if expected["is_online"]:
+ async_device._session.cli.assert_called_once() # type: ignore[attr-defined] # asynceapi.Device.cli is patched
+ assert async_device.is_online == expected["is_online"]
+ assert async_device.established == expected["established"]
+ assert async_device.hw_model == expected["hw_model"]
- @pytest.mark.asyncio
+ @pytest.mark.asyncio()
@pytest.mark.parametrize(
- "async_device, command, expected",
- map(lambda d: (d["device"], d["command"], d["expected"]), AIOEAPI_COLLECT_DATA),
- ids=generate_test_ids_list(AIOEAPI_COLLECT_DATA),
+ ("async_device", "command", "expected"),
+ ((d["device"], d["command"], d["expected"]) for d in ASYNCEAPI_COLLECT_DATA),
+ ids=generate_test_ids_list(ASYNCEAPI_COLLECT_DATA),
indirect=["async_device"],
)
async def test__collect(self, async_device: AsyncEOSDevice, command: dict[str, Any], expected: dict[str, Any]) -> None:
# pylint: disable=protected-access
- """Test AsyncEOSDevice._collect()"""
- if "revision" in command:
- cmd = AntaCommand(command=command["command"], revision=command["revision"])
- else:
- cmd = AntaCommand(command=command["command"])
+ """Test AsyncEOSDevice._collect()."""
+ cmd = AntaCommand(command=command["command"], revision=command["revision"]) if "revision" in command else AntaCommand(command=command["command"])
with patch.object(async_device._session, "cli", **command["patch_kwargs"]):
- await async_device.collect(cmd)
- commands = []
+ collection_id = "pytest"
+ await async_device.collect(cmd, collection_id=collection_id)
+ commands: list[dict[str, Any]] = []
if async_device.enable and async_device._enable_password is not None:
commands.append(
{
"cmd": "enable",
"input": str(async_device._enable_password),
- }
+ },
)
elif async_device.enable:
# No password
@@ -747,19 +741,19 @@ class TestAsyncEOSDevice:
commands.append({"cmd": cmd.command, "revision": cmd.revision})
else:
commands.append({"cmd": cmd.command})
- async_device._session.cli.assert_called_once_with(commands=commands, ofmt=cmd.ofmt, version=cmd.version)
+ async_device._session.cli.assert_called_once_with(commands=commands, ofmt=cmd.ofmt, version=cmd.version, req_id=f"ANTA-{collection_id}-{id(cmd)}") # type: ignore[attr-defined] # asynceapi.Device.cli is patched # pylint: disable=line-too-long
assert cmd.output == expected["output"]
assert cmd.errors == expected["errors"]
- @pytest.mark.asyncio
+ @pytest.mark.asyncio()
@pytest.mark.parametrize(
- "async_device, copy",
- map(lambda d: (d["device"], d["copy"]), AIOEAPI_COPY_DATA),
- ids=generate_test_ids_list(AIOEAPI_COPY_DATA),
+ ("async_device", "copy"),
+ ((d["device"], d["copy"]) for d in ASYNCEAPI_COPY_DATA),
+ ids=generate_test_ids_list(ASYNCEAPI_COPY_DATA),
indirect=["async_device"],
)
async def test_copy(self, async_device: AsyncEOSDevice, copy: dict[str, Any]) -> None:
- """Test AsyncEOSDevice.copy()"""
+ """Test AsyncEOSDevice.copy()."""
conn = SSHClientConnection(asyncio.get_event_loop(), SSHClientConnectionOptions())
with patch("asyncssh.connect") as connect_mock:
connect_mock.return_value.__aenter__.return_value = conn
diff --git a/tests/units/test_logger.py b/tests/units/test_logger.py
index 6e1e5b4..d9b7c76 100644
--- a/tests/units/test_logger.py
+++ b/tests/units/test_logger.py
@@ -1,53 +1,65 @@
# Copyright (c) 2023-2024 Arista Networks, Inc.
# Use of this source code is governed by the Apache License 2.0
# that can be found in the LICENSE file.
-"""
-Tests for anta.logger
-"""
+"""Tests for anta.logger."""
+
from __future__ import annotations
import logging
-from typing import TYPE_CHECKING
from unittest.mock import patch
import pytest
-from anta.logger import anta_log_exception
-
-if TYPE_CHECKING:
- from pytest import LogCaptureFixture
+from anta.logger import anta_log_exception, exc_to_str, tb_to_str
@pytest.mark.parametrize(
- "exception, message, calling_logger, __DEBUG__value, expected_message",
+ ("exception", "message", "calling_logger", "debug_value", "expected_message"),
[
- pytest.param(ValueError("exception message"), None, None, False, "ValueError (exception message)", id="exception only"),
- pytest.param(ValueError("exception message"), "custom message", None, False, "custom message\nValueError (exception message)", id="custom message"),
+ pytest.param(
+ ValueError("exception message"),
+ None,
+ None,
+ False,
+ "ValueError: exception message",
+ id="exception only",
+ ),
+ pytest.param(
+ ValueError("exception message"),
+ "custom message",
+ None,
+ False,
+ "custom message\nValueError: exception message",
+ id="custom message",
+ ),
pytest.param(
ValueError("exception message"),
"custom logger",
logging.getLogger("custom"),
False,
- "custom logger\nValueError (exception message)",
+ "custom logger\nValueError: exception message",
id="custom logger",
),
pytest.param(
- ValueError("exception message"), "Use with custom message", None, True, "Use with custom message\nValueError (exception message)", id="__DEBUG__ on"
+ ValueError("exception message"),
+ "Use with custom message",
+ None,
+ True,
+ "Use with custom message\nValueError: exception message",
+ id="__DEBUG__ on",
),
],
)
def test_anta_log_exception(
- caplog: LogCaptureFixture,
+ caplog: pytest.LogCaptureFixture,
exception: Exception,
message: str | None,
calling_logger: logging.Logger | None,
- __DEBUG__value: bool,
+ debug_value: bool,
expected_message: str,
) -> None:
- """
- Test anta_log_exception
- """
-
+ # pylint: disable=too-many-arguments
+ """Test anta_log_exception."""
if calling_logger is not None:
# https://github.com/pytest-dev/pytest/issues/3697
calling_logger.propagate = True
@@ -57,12 +69,12 @@ def test_anta_log_exception(
# Need to raise to trigger nice stacktrace for __DEBUG__ == True
try:
raise exception
- except ValueError as e:
- with patch("anta.logger.__DEBUG__", __DEBUG__value):
- anta_log_exception(e, message=message, calling_logger=calling_logger)
+ except ValueError as exc:
+ with patch("anta.logger.__DEBUG__", new=debug_value):
+ anta_log_exception(exc, message=message, calling_logger=calling_logger)
# Two log captured
- if __DEBUG__value:
+ if debug_value:
assert len(caplog.record_tuples) == 2
else:
assert len(caplog.record_tuples) == 1
@@ -76,5 +88,29 @@ def test_anta_log_exception(
assert level == logging.CRITICAL
assert message == expected_message
# the only place where we can see the stracktrace is in the capture.text
- if __DEBUG__value is True:
+ if debug_value:
assert "Traceback" in caplog.text
+
+
+def my_raising_function(exception: Exception) -> None:
+ """Raise Exception."""
+ raise exception
+
+
+@pytest.mark.parametrize(
+ ("exception", "expected_output"),
+ [(ValueError("test"), "ValueError: test"), (ValueError(), "ValueError")],
+)
+def test_exc_to_str(exception: Exception, expected_output: str) -> None:
+ """Test exc_to_str."""
+ assert exc_to_str(exception) == expected_output
+
+
+def test_tb_to_str() -> None:
+ """Test tb_to_str."""
+ try:
+ my_raising_function(ValueError("test"))
+ except ValueError as exc:
+ output = tb_to_str(exc)
+ assert "Traceback" in output
+ assert 'my_raising_function(ValueError("test"))' in output
diff --git a/tests/units/test_models.py b/tests/units/test_models.py
index c0585a4..180f6bf 100644
--- a/tests/units/test_models.py
+++ b/tests/units/test_models.py
@@ -1,209 +1,289 @@
# Copyright (c) 2023-2024 Arista Networks, Inc.
# Use of this source code is governed by the Apache License 2.0
# that can be found in the LICENSE file.
-"""
-test anta.models.py
-"""
+"""test anta.models.py."""
+
# Mypy does not understand AntaTest.Input typing
# mypy: disable-error-code=attr-defined
from __future__ import annotations
import asyncio
-from typing import Any
+from typing import TYPE_CHECKING, Any, ClassVar
import pytest
from anta.decorators import deprecated_test, skip_on_platforms
-from anta.device import AntaDevice
from anta.models import AntaCommand, AntaTemplate, AntaTest
from tests.lib.fixture import DEVICE_HW_MODEL
from tests.lib.utils import generate_test_ids
+if TYPE_CHECKING:
+ from anta.device import AntaDevice
+
class FakeTest(AntaTest):
- """ANTA test that always succeed"""
+ """ANTA test that always succeed."""
name = "FakeTest"
description = "ANTA test that always succeed"
- categories = []
- commands = []
+ categories: ClassVar[list[str]] = []
+ commands: ClassVar[list[AntaCommand | AntaTemplate]] = []
@AntaTest.anta_test
def test(self) -> None:
+ """Test function."""
self.result.is_success()
class FakeTestWithFailedCommand(AntaTest):
- """ANTA test with a command that failed"""
+ """ANTA test with a command that failed."""
name = "FakeTestWithFailedCommand"
description = "ANTA test with a command that failed"
- categories = []
- commands = [AntaCommand(command="show version", errors=["failed command"])]
+ categories: ClassVar[list[str]] = []
+ commands: ClassVar[list[AntaCommand | AntaTemplate]] = [AntaCommand(command="show version", errors=["failed command"])]
@AntaTest.anta_test
def test(self) -> None:
+ """Test function."""
self.result.is_success()
class FakeTestWithUnsupportedCommand(AntaTest):
- """ANTA test with an unsupported command"""
+ """ANTA test with an unsupported command."""
name = "FakeTestWithUnsupportedCommand"
description = "ANTA test with an unsupported command"
- categories = []
- commands = [AntaCommand(command="show hardware counter drop", errors=["Unavailable command (not supported on this hardware platform) (at token 2: 'counter')"])]
+ categories: ClassVar[list[str]] = []
+ commands: ClassVar[list[AntaCommand | AntaTemplate]] = [
+ AntaCommand(
+ command="show hardware counter drop",
+ errors=["Unavailable command (not supported on this hardware platform) (at token 2: 'counter')"],
+ )
+ ]
@AntaTest.anta_test
def test(self) -> None:
+ """Test function."""
self.result.is_success()
class FakeTestWithInput(AntaTest):
- """ANTA test with inputs that always succeed"""
+ """ANTA test with inputs that always succeed."""
name = "FakeTestWithInput"
description = "ANTA test with inputs that always succeed"
- categories = []
- commands = []
+ categories: ClassVar[list[str]] = []
+ commands: ClassVar[list[AntaCommand | AntaTemplate]] = []
+
+ class Input(AntaTest.Input):
+ """Inputs for FakeTestWithInput test."""
- class Input(AntaTest.Input): # pylint: disable=missing-class-docstring
string: str
@AntaTest.anta_test
def test(self) -> None:
+ """Test function."""
self.result.is_success(self.inputs.string)
class FakeTestWithTemplate(AntaTest):
- """ANTA test with template that always succeed"""
+ """ANTA test with template that always succeed."""
name = "FakeTestWithTemplate"
description = "ANTA test with template that always succeed"
- categories = []
- commands = [AntaTemplate(template="show interface {interface}")]
+ categories: ClassVar[list[str]] = []
+ commands: ClassVar[list[AntaCommand | AntaTemplate]] = [AntaTemplate(template="show interface {interface}")]
+
+ class Input(AntaTest.Input):
+ """Inputs for FakeTestWithTemplate test."""
- class Input(AntaTest.Input): # pylint: disable=missing-class-docstring
interface: str
def render(self, template: AntaTemplate) -> list[AntaCommand]:
+ """Render function."""
return [template.render(interface=self.inputs.interface)]
@AntaTest.anta_test
def test(self) -> None:
+ """Test function."""
self.result.is_success(self.instance_commands[0].command)
class FakeTestWithTemplateNoRender(AntaTest):
- """ANTA test with template that miss the render() method"""
+ """ANTA test with template that miss the render() method."""
name = "FakeTestWithTemplateNoRender"
description = "ANTA test with template that miss the render() method"
- categories = []
- commands = [AntaTemplate(template="show interface {interface}")]
+ categories: ClassVar[list[str]] = []
+ commands: ClassVar[list[AntaCommand | AntaTemplate]] = [AntaTemplate(template="show interface {interface}")]
+
+ class Input(AntaTest.Input):
+ """Inputs for FakeTestWithTemplateNoRender test."""
- class Input(AntaTest.Input): # pylint: disable=missing-class-docstring
interface: str
@AntaTest.anta_test
def test(self) -> None:
+ """Test function."""
self.result.is_success(self.instance_commands[0].command)
class FakeTestWithTemplateBadRender1(AntaTest):
- """ANTA test with template that raises a AntaTemplateRenderError exception"""
+ """ANTA test with template that raises a AntaTemplateRenderError exception."""
name = "FakeTestWithTemplateBadRender"
description = "ANTA test with template that raises a AntaTemplateRenderError exception"
- categories = []
- commands = [AntaTemplate(template="show interface {interface}")]
+ categories: ClassVar[list[str]] = []
+ commands: ClassVar[list[AntaCommand | AntaTemplate]] = [AntaTemplate(template="show interface {interface}")]
+
+ class Input(AntaTest.Input):
+ """Inputs for FakeTestWithTemplateBadRender1 test."""
- class Input(AntaTest.Input): # pylint: disable=missing-class-docstring
interface: str
def render(self, template: AntaTemplate) -> list[AntaCommand]:
+ """Render function."""
return [template.render(wrong_template_param=self.inputs.interface)]
@AntaTest.anta_test
def test(self) -> None:
+ """Test function."""
self.result.is_success(self.instance_commands[0].command)
class FakeTestWithTemplateBadRender2(AntaTest):
- """ANTA test with template that raises an arbitrary exception"""
+ """ANTA test with template that raises an arbitrary exception in render()."""
name = "FakeTestWithTemplateBadRender2"
- description = "ANTA test with template that raises an arbitrary exception"
- categories = []
- commands = [AntaTemplate(template="show interface {interface}")]
+ description = "ANTA test with template that raises an arbitrary exception in render()"
+ categories: ClassVar[list[str]] = []
+ commands: ClassVar[list[AntaCommand | AntaTemplate]] = [AntaTemplate(template="show interface {interface}")]
+
+ class Input(AntaTest.Input):
+ """Inputs for FakeTestWithTemplateBadRender2 test."""
- class Input(AntaTest.Input): # pylint: disable=missing-class-docstring
interface: str
def render(self, template: AntaTemplate) -> list[AntaCommand]:
- raise Exception() # pylint: disable=broad-exception-raised
+ """Render function."""
+ raise RuntimeError(template)
@AntaTest.anta_test
def test(self) -> None:
+ """Test function."""
self.result.is_success(self.instance_commands[0].command)
+class FakeTestWithTemplateBadRender3(AntaTest):
+ """ANTA test with template that gives extra template parameters in render()."""
+
+ name = "FakeTestWithTemplateBadRender3"
+ description = "ANTA test with template that gives extra template parameters in render()"
+ categories: ClassVar[list[str]] = []
+ commands: ClassVar[list[AntaCommand | AntaTemplate]] = [AntaTemplate(template="show interface {interface}")]
+
+ class Input(AntaTest.Input):
+ """Inputs for FakeTestWithTemplateBadRender3 test."""
+
+ interface: str
+
+ def render(self, template: AntaTemplate) -> list[AntaCommand]:
+ """Render function."""
+ return [template.render(interface=self.inputs.interface, extra="blah")]
+
+ @AntaTest.anta_test
+ def test(self) -> None:
+ """Test function."""
+ self.result.is_success(self.instance_commands[0].command)
+
+
+class FakeTestWithTemplateBadTest(AntaTest):
+ """ANTA test with template that tries to access an undefined template parameter in test()."""
+
+ name = "FakeTestWithTemplateBadTest"
+ description = "ANTA test with template that tries to access an undefined template parameter in test()"
+ categories: ClassVar[list[str]] = []
+ commands: ClassVar[list[AntaCommand | AntaTemplate]] = [AntaTemplate(template="show interface {interface}")]
+
+ class Input(AntaTest.Input):
+ """Inputs for FakeTestWithTemplateBadTest test."""
+
+ interface: str
+
+ def render(self, template: AntaTemplate) -> list[AntaCommand]:
+ """Render function."""
+ return [template.render(interface=self.inputs.interface)]
+
+ @AntaTest.anta_test
+ def test(self) -> None:
+ """Test function."""
+ # The following line must raise AttributeError at runtime
+ self.result.is_success(self.instance_commands[0].params.wrong_template_param)
+
+
class SkipOnPlatformTest(AntaTest):
- """ANTA test that is skipped"""
+ """ANTA test that is skipped."""
name = "SkipOnPlatformTest"
description = "ANTA test that is skipped on a specific platform"
- categories = []
- commands = []
+ categories: ClassVar[list[str]] = []
+ commands: ClassVar[list[AntaCommand | AntaTemplate]] = []
@skip_on_platforms([DEVICE_HW_MODEL])
@AntaTest.anta_test
def test(self) -> None:
+ """Test function."""
self.result.is_success()
class UnSkipOnPlatformTest(AntaTest):
- """ANTA test that is skipped"""
+ """ANTA test that is skipped."""
name = "UnSkipOnPlatformTest"
description = "ANTA test that is skipped on a specific platform"
- categories = []
- commands = []
+ categories: ClassVar[list[str]] = []
+ commands: ClassVar[list[AntaCommand | AntaTemplate]] = []
@skip_on_platforms(["dummy"])
@AntaTest.anta_test
def test(self) -> None:
+ """Test function."""
self.result.is_success()
class SkipOnPlatformTestWithInput(AntaTest):
- """ANTA test skipped on platforms but with Input"""
+ """ANTA test skipped on platforms but with Input."""
name = "SkipOnPlatformTestWithInput"
description = "ANTA test skipped on platforms but with Input"
- categories = []
- commands = []
+ categories: ClassVar[list[str]] = []
+ commands: ClassVar[list[AntaCommand | AntaTemplate]] = []
+
+ class Input(AntaTest.Input):
+ """Inputs for SkipOnPlatformTestWithInput test."""
- class Input(AntaTest.Input): # pylint: disable=missing-class-docstring
string: str
@skip_on_platforms([DEVICE_HW_MODEL])
@AntaTest.anta_test
def test(self) -> None:
+ """Test function."""
self.result.is_success(self.inputs.string)
class DeprecatedTestWithoutNewTest(AntaTest):
- """ANTA test that is deprecated without new test"""
+ """ANTA test that is deprecated without new test."""
name = "DeprecatedTestWitouthNewTest"
description = "ANTA test that is deprecated without new test"
- categories = []
- commands = []
+ categories: ClassVar[list[str]] = []
+ commands: ClassVar[list[AntaCommand | AntaTemplate]] = []
@deprecated_test()
@AntaTest.anta_test
def test(self) -> None:
+ """Test function."""
self.result.is_success()
@@ -212,52 +292,88 @@ class DeprecatedTestWithNewTest(AntaTest):
name = "DeprecatedTestWithNewTest"
description = "ANTA deprecated test with New Test"
- categories = []
- commands = []
+ categories: ClassVar[list[str]] = []
+ commands: ClassVar[list[AntaCommand | AntaTemplate]] = []
@deprecated_test(new_tests=["NewTest"])
@AntaTest.anta_test
def test(self) -> None:
+ """Test function."""
self.result.is_success()
ANTATEST_DATA: list[dict[str, Any]] = [
- {"name": "no input", "test": FakeTest, "inputs": None, "expected": {"__init__": {"result": "unset"}, "test": {"result": "success"}}},
+ {
+ "name": "no input",
+ "test": FakeTest,
+ "inputs": None,
+ "expected": {"__init__": {"result": "unset"}, "test": {"result": "success"}},
+ },
{
"name": "extra input",
"test": FakeTest,
"inputs": {"string": "culpa! veniam quas quas veniam molestias, esse"},
- "expected": {"__init__": {"result": "error", "messages": ["Extra inputs are not permitted"]}, "test": {"result": "error"}},
+ "expected": {
+ "__init__": {
+ "result": "error",
+ "messages": ["Extra inputs are not permitted"],
+ },
+ "test": {"result": "error"},
+ },
},
{
"name": "no input",
"test": FakeTestWithInput,
"inputs": None,
- "expected": {"__init__": {"result": "error", "messages": ["Field required"]}, "test": {"result": "error"}},
+ "expected": {
+ "__init__": {"result": "error", "messages": ["Field required"]},
+ "test": {"result": "error"},
+ },
},
{
"name": "wrong input type",
"test": FakeTestWithInput,
"inputs": {"string": 1},
- "expected": {"__init__": {"result": "error", "messages": ["Input should be a valid string"]}, "test": {"result": "error"}},
+ "expected": {
+ "__init__": {
+ "result": "error",
+ "messages": ["Input should be a valid string"],
+ },
+ "test": {"result": "error"},
+ },
},
{
"name": "good input",
"test": FakeTestWithInput,
"inputs": {"string": "culpa! veniam quas quas veniam molestias, esse"},
- "expected": {"__init__": {"result": "unset"}, "test": {"result": "success", "messages": ["culpa! veniam quas quas veniam molestias, esse"]}},
+ "expected": {
+ "__init__": {"result": "unset"},
+ "test": {
+ "result": "success",
+ "messages": ["culpa! veniam quas quas veniam molestias, esse"],
+ },
+ },
},
{
"name": "good input",
"test": FakeTestWithTemplate,
"inputs": {"interface": "Ethernet1"},
- "expected": {"__init__": {"result": "unset"}, "test": {"result": "success", "messages": ["show interface Ethernet1"]}},
+ "expected": {
+ "__init__": {"result": "unset"},
+ "test": {"result": "success", "messages": ["show interface Ethernet1"]},
+ },
},
{
"name": "wrong input type",
"test": FakeTestWithTemplate,
"inputs": {"interface": 1},
- "expected": {"__init__": {"result": "error", "messages": ["Input should be a valid string"]}, "test": {"result": "error"}},
+ "expected": {
+ "__init__": {
+ "result": "error",
+ "messages": ["Input should be a valid string"],
+ },
+ "test": {"result": "error"},
+ },
},
{
"name": "wrong render definition",
@@ -284,18 +400,43 @@ ANTATEST_DATA: list[dict[str, Any]] = [
},
},
{
- "name": "Exception in render()",
+ "name": "RuntimeError in render()",
"test": FakeTestWithTemplateBadRender2,
"inputs": {"interface": "Ethernet1"},
"expected": {
"__init__": {
"result": "error",
- "messages": ["Exception in tests.units.test_models.FakeTestWithTemplateBadRender2.render(): Exception"],
+ "messages": ["Exception in tests.units.test_models.FakeTestWithTemplateBadRender2.render(): RuntimeError"],
+ },
+ "test": {"result": "error"},
+ },
+ },
+ {
+ "name": "Extra template parameters in render()",
+ "test": FakeTestWithTemplateBadRender3,
+ "inputs": {"interface": "Ethernet1"},
+ "expected": {
+ "__init__": {
+ "result": "error",
+ "messages": [
+ "Exception in tests.units.test_models.FakeTestWithTemplateBadRender3.render(): ValidationError: 1 validation error for AntaParams\n"
+ "extra\n"
+ " Extra inputs are not permitted [type=extra_forbidden, input_value='blah', input_type=str]\n"
+ ],
},
"test": {"result": "error"},
},
},
{
+ "name": "Access undefined template param in test()",
+ "test": FakeTestWithTemplateBadTest,
+ "inputs": {"interface": "Ethernet1"},
+ "expected": {
+ "__init__": {"result": "unset"},
+ "test": {"result": "error", "messages": ["AttributeError: 'AntaParams' object has no attribute 'wrong_template_param'"]},
+ },
+ },
+ {
"name": "unskip on platforms",
"test": UnSkipOnPlatformTest,
"inputs": None,
@@ -317,7 +458,10 @@ ANTATEST_DATA: list[dict[str, Any]] = [
"name": "skip on platforms, not unset",
"test": SkipOnPlatformTestWithInput,
"inputs": None,
- "expected": {"__init__": {"result": "error", "messages": ["Field required"]}, "test": {"result": "error"}},
+ "expected": {
+ "__init__": {"result": "error", "messages": ["Field required"]},
+ "test": {"result": "error"},
+ },
},
{
"name": "deprecate test without new test",
@@ -341,7 +485,13 @@ ANTATEST_DATA: list[dict[str, Any]] = [
"name": "failed command",
"test": FakeTestWithFailedCommand,
"inputs": None,
- "expected": {"__init__": {"result": "unset"}, "test": {"result": "error", "messages": ["show version has failed: failed command"]}},
+ "expected": {
+ "__init__": {"result": "unset"},
+ "test": {
+ "result": "error",
+ "messages": ["show version has failed: failed command"],
+ },
+ },
},
{
"name": "unsupported command",
@@ -349,29 +499,30 @@ ANTATEST_DATA: list[dict[str, Any]] = [
"inputs": None,
"expected": {
"__init__": {"result": "unset"},
- "test": {"result": "skipped", "messages": ["Skipped because show hardware counter drop is not supported on pytest"]},
+ "test": {
+ "result": "skipped",
+ "messages": ["'show hardware counter drop' is not supported on pytest"],
+ },
},
},
]
-class Test_AntaTest:
- """
- Test for anta.models.AntaTest
- """
+class TestAntaTest:
+ """Test for anta.models.AntaTest."""
def test__init_subclass__name(self) -> None:
- """Test __init_subclass__"""
+ """Test __init_subclass__."""
# Pylint detects all the classes in here as unused which is on purpose
# pylint: disable=unused-variable
with pytest.raises(NotImplementedError) as exec_info:
class WrongTestNoName(AntaTest):
- """ANTA test that is missing a name"""
+ """ANTA test that is missing a name."""
description = "ANTA test that is missing a name"
- categories = []
- commands = []
+ categories: ClassVar[list[str]] = []
+ commands: ClassVar[list[AntaCommand | AntaTemplate]] = []
@AntaTest.anta_test
def test(self) -> None:
@@ -382,11 +533,11 @@ class Test_AntaTest:
with pytest.raises(NotImplementedError) as exec_info:
class WrongTestNoDescription(AntaTest):
- """ANTA test that is missing a description"""
+ """ANTA test that is missing a description."""
name = "WrongTestNoDescription"
- categories = []
- commands = []
+ categories: ClassVar[list[str]] = []
+ commands: ClassVar[list[AntaCommand | AntaTemplate]] = []
@AntaTest.anta_test
def test(self) -> None:
@@ -397,11 +548,11 @@ class Test_AntaTest:
with pytest.raises(NotImplementedError) as exec_info:
class WrongTestNoCategories(AntaTest):
- """ANTA test that is missing categories"""
+ """ANTA test that is missing categories."""
name = "WrongTestNoCategories"
description = "ANTA test that is missing categories"
- commands = []
+ commands: ClassVar[list[AntaCommand | AntaTemplate]] = []
@AntaTest.anta_test
def test(self) -> None:
@@ -412,11 +563,11 @@ class Test_AntaTest:
with pytest.raises(NotImplementedError) as exec_info:
class WrongTestNoCommands(AntaTest):
- """ANTA test that is missing commands"""
+ """ANTA test that is missing commands."""
name = "WrongTestNoCommands"
description = "ANTA test that is missing commands"
- categories = []
+ categories: ClassVar[list[str]] = []
@AntaTest.anta_test
def test(self) -> None:
@@ -432,14 +583,14 @@ class Test_AntaTest:
@pytest.mark.parametrize("data", ANTATEST_DATA, ids=generate_test_ids(ANTATEST_DATA))
def test__init__(self, device: AntaDevice, data: dict[str, Any]) -> None:
- """Test the AntaTest constructor"""
+ """Test the AntaTest constructor."""
expected = data["expected"]["__init__"]
test = data["test"](device, inputs=data["inputs"])
self._assert_test(test, expected)
@pytest.mark.parametrize("data", ANTATEST_DATA, ids=generate_test_ids(ANTATEST_DATA))
def test_test(self, device: AntaDevice, data: dict[str, Any]) -> None:
- """Test the AntaTest.test method"""
+ """Test the AntaTest.test method."""
expected = data["expected"]["test"]
test = data["test"](device, inputs=data["inputs"])
asyncio.run(test.test())
@@ -454,12 +605,12 @@ def test_blacklist(device: AntaDevice, data: str) -> None:
"""Test for blacklisting function."""
class FakeTestWithBlacklist(AntaTest):
- """Fake Test for blacklist"""
+ """Fake Test for blacklist."""
name = "FakeTestWithBlacklist"
description = "ANTA test that has blacklisted command"
- categories = []
- commands = [AntaCommand(command=data)]
+ categories: ClassVar[list[str]] = []
+ commands: ClassVar[list[AntaCommand | AntaTemplate]] = [AntaCommand(command=data)]
@AntaTest.anta_test
def test(self) -> None:
@@ -470,3 +621,60 @@ def test_blacklist(device: AntaDevice, data: str) -> None:
# Run the test() method
asyncio.run(test_instance.test())
assert test_instance.result.result == "error"
+
+
+class TestAntaComamnd:
+ """Test for anta.models.AntaCommand."""
+
+ # ruff: noqa: B018
+ # pylint: disable=pointless-statement
+
+ def test_empty_output_access(self) -> None:
+ """Test for both json and text ofmt."""
+ json_cmd = AntaCommand(command="show dummy")
+ text_cmd = AntaCommand(command="show dummy", ofmt="text")
+ msg = "There is no output for command 'show dummy'"
+ with pytest.raises(RuntimeError, match=msg):
+ json_cmd.json_output
+ with pytest.raises(RuntimeError, match=msg):
+ text_cmd.text_output
+
+ def test_wrong_format_output_access(self) -> None:
+ """Test for both json and text ofmt."""
+ json_cmd = AntaCommand(command="show dummy", output={})
+ json_cmd_2 = AntaCommand(command="show dummy", output="not_json")
+ text_cmd = AntaCommand(command="show dummy", ofmt="text", output="blah")
+ text_cmd_2 = AntaCommand(command="show dummy", ofmt="text", output={"not_a": "string"})
+ msg = "Output of command 'show dummy' is invalid"
+ with pytest.raises(RuntimeError, match=msg):
+ json_cmd.text_output
+ with pytest.raises(RuntimeError, match=msg):
+ text_cmd.json_output
+ with pytest.raises(RuntimeError, match=msg):
+ json_cmd_2.text_output
+ with pytest.raises(RuntimeError, match=msg):
+ text_cmd_2.json_output
+
+ def test_supported(self) -> None:
+ """Test if the supported property."""
+ command = AntaCommand(command="show hardware counter drop", errors=["Unavailable command (not supported on this hardware platform) (at token 2: 'counter')"])
+ assert command.supported is False
+ command = AntaCommand(
+ command="show hardware counter drop", output={"totalAdverseDrops": 0, "totalCongestionDrops": 0, "totalPacketProcessorDrops": 0, "dropEvents": {}}
+ )
+ assert command.supported is True
+
+ def test_requires_privileges(self) -> None:
+ """Test if the requires_privileges property."""
+ command = AntaCommand(command="show aaa methods accounting", errors=["Invalid input (privileged mode required)"])
+ assert command.requires_privileges is True
+ command = AntaCommand(
+ command="show aaa methods accounting",
+ output={
+ "commandsAcctMethods": {"privilege0-15": {"defaultMethods": [], "consoleMethods": []}},
+ "execAcctMethods": {"exec": {"defaultMethods": [], "consoleMethods": []}},
+ "systemAcctMethods": {"system": {"defaultMethods": [], "consoleMethods": []}},
+ "dot1xAcctMethods": {"dot1x": {"defaultMethods": [], "consoleMethods": []}},
+ },
+ )
+ assert command.requires_privileges is False
diff --git a/tests/units/test_runner.py b/tests/units/test_runner.py
index c353cbe..955149d 100644
--- a/tests/units/test_runner.py
+++ b/tests/units/test_runner.py
@@ -1,13 +1,14 @@
# Copyright (c) 2023-2024 Arista Networks, Inc.
# Use of this source code is governed by the Apache License 2.0
# that can be found in the LICENSE file.
-"""
-test anta.runner.py
-"""
+"""test anta.runner.py."""
+
from __future__ import annotations
import logging
-from typing import TYPE_CHECKING
+import resource
+from pathlib import Path
+from unittest.mock import patch
import pytest
@@ -15,20 +16,17 @@ from anta import logger
from anta.catalog import AntaCatalog
from anta.inventory import AntaInventory
from anta.result_manager import ResultManager
-from anta.runner import main
+from anta.runner import adjust_rlimit_nofile, main, prepare_tests
from .test_models import FakeTest
-if TYPE_CHECKING:
- from pytest import LogCaptureFixture
-
+DATA_DIR: Path = Path(__file__).parent.parent.resolve() / "data"
FAKE_CATALOG: AntaCatalog = AntaCatalog.from_list([(FakeTest, None)])
-@pytest.mark.asyncio
-async def test_runner_empty_tests(caplog: LogCaptureFixture, test_inventory: AntaInventory) -> None:
- """
- Test that when the list of tests is empty, a log is raised
+@pytest.mark.asyncio()
+async def test_runner_empty_tests(caplog: pytest.LogCaptureFixture, test_inventory: AntaInventory) -> None:
+ """Test that when the list of tests is empty, a log is raised.
caplog is the pytest fixture to capture logs
test_inventory is a fixture that gives a default inventory for tests
@@ -42,10 +40,9 @@ async def test_runner_empty_tests(caplog: LogCaptureFixture, test_inventory: Ant
assert "The list of tests is empty, exiting" in caplog.records[0].message
-@pytest.mark.asyncio
-async def test_runner_empty_inventory(caplog: LogCaptureFixture) -> None:
- """
- Test that when the Inventory is empty, a log is raised
+@pytest.mark.asyncio()
+async def test_runner_empty_inventory(caplog: pytest.LogCaptureFixture) -> None:
+ """Test that when the Inventory is empty, a log is raised.
caplog is the pytest fixture to capture logs
"""
@@ -54,14 +51,13 @@ async def test_runner_empty_inventory(caplog: LogCaptureFixture) -> None:
manager = ResultManager()
inventory = AntaInventory()
await main(manager, inventory, FAKE_CATALOG)
- assert len(caplog.record_tuples) == 1
- assert "The inventory is empty, exiting" in caplog.records[0].message
+ assert len(caplog.record_tuples) == 3
+ assert "The inventory is empty, exiting" in caplog.records[1].message
-@pytest.mark.asyncio
-async def test_runner_no_selected_device(caplog: LogCaptureFixture, test_inventory: AntaInventory) -> None:
- """
- Test that when the list of established device
+@pytest.mark.asyncio()
+async def test_runner_no_selected_device(caplog: pytest.LogCaptureFixture, test_inventory: AntaInventory) -> None:
+ """Test that when the list of established device.
caplog is the pytest fixture to capture logs
test_inventory is a fixture that gives a default inventory for tests
@@ -71,12 +67,140 @@ async def test_runner_no_selected_device(caplog: LogCaptureFixture, test_invento
manager = ResultManager()
await main(manager, test_inventory, FAKE_CATALOG)
- assert "No device in the established state 'True' was found. There is no device to run tests against, exiting" in [record.message for record in caplog.records]
+ assert "No reachable device was found." in [record.message for record in caplog.records]
# Reset logs and run with tags
caplog.clear()
- await main(manager, test_inventory, FAKE_CATALOG, tags=["toto"])
+ await main(manager, test_inventory, FAKE_CATALOG, tags={"toto"})
+
+ assert "No reachable device matching the tags {'toto'} was found." in [record.message for record in caplog.records]
+
+
+def test_adjust_rlimit_nofile_valid_env(caplog: pytest.LogCaptureFixture) -> None:
+ """Test adjust_rlimit_nofile with valid environment variables."""
+ with (
+ caplog.at_level(logging.DEBUG),
+ patch.dict("os.environ", {"ANTA_NOFILE": "20480"}),
+ patch("anta.runner.resource.getrlimit") as getrlimit_mock,
+ patch("anta.runner.resource.setrlimit") as setrlimit_mock,
+ ):
+ # Simulate the default system limits
+ system_limits = (8192, 1048576)
+
+ # Setup getrlimit mock return value
+ getrlimit_mock.return_value = system_limits
+
+ # Simulate setrlimit behavior
+ def side_effect_setrlimit(resource_id: int, limits: tuple[int, int]) -> None:
+ _ = resource_id
+ getrlimit_mock.return_value = (limits[0], limits[1])
+
+ setrlimit_mock.side_effect = side_effect_setrlimit
+
+ result = adjust_rlimit_nofile()
+
+ # Assert the limits were updated as expected
+ assert result == (20480, 1048576)
+ assert "Initial limit numbers for open file descriptors for the current ANTA process: Soft Limit: 8192 | Hard Limit: 1048576" in caplog.text
+ assert "Setting soft limit for open file descriptors for the current ANTA process to 20480" in caplog.text
+
+ setrlimit_mock.assert_called_once_with(resource.RLIMIT_NOFILE, (20480, 1048576))
+
+
+def test_adjust_rlimit_nofile_invalid_env(caplog: pytest.LogCaptureFixture) -> None:
+ """Test adjust_rlimit_nofile with valid environment variables."""
+ with (
+ caplog.at_level(logging.DEBUG),
+ patch.dict("os.environ", {"ANTA_NOFILE": "invalid"}),
+ patch("anta.runner.resource.getrlimit") as getrlimit_mock,
+ patch("anta.runner.resource.setrlimit") as setrlimit_mock,
+ ):
+ # Simulate the default system limits
+ system_limits = (8192, 1048576)
+
+ # Setup getrlimit mock return value
+ getrlimit_mock.return_value = system_limits
+
+ # Simulate setrlimit behavior
+ def side_effect_setrlimit(resource_id: int, limits: tuple[int, int]) -> None:
+ _ = resource_id
+ getrlimit_mock.return_value = (limits[0], limits[1])
+
+ setrlimit_mock.side_effect = side_effect_setrlimit
+
+ result = adjust_rlimit_nofile()
+
+ # Assert the limits were updated as expected
+ assert result == (16384, 1048576)
+ assert "The ANTA_NOFILE environment variable value is invalid" in caplog.text
+ assert caplog.records[0].levelname == "WARNING"
+ assert "Initial limit numbers for open file descriptors for the current ANTA process: Soft Limit: 8192 | Hard Limit: 1048576" in caplog.text
+ assert "Setting soft limit for open file descriptors for the current ANTA process to 16384" in caplog.text
+
+ setrlimit_mock.assert_called_once_with(resource.RLIMIT_NOFILE, (16384, 1048576))
+
+
+@pytest.mark.asyncio()
+@pytest.mark.parametrize(
+ ("tags", "expected_tests_count", "expected_devices_count"),
+ [
+ (None, 22, 3),
+ ({"leaf"}, 9, 3),
+ ({"invalid_tag"}, 0, 0),
+ ],
+ ids=["no_tags", "leaf_tag", "invalid_tag"],
+)
+async def test_prepare_tests(
+ caplog: pytest.LogCaptureFixture,
+ test_inventory: AntaInventory,
+ tags: set[str] | None,
+ expected_tests_count: int,
+ expected_devices_count: int,
+) -> None:
+ """Test the runner prepare_tests function."""
+ logger.setup_logging(logger.Log.INFO)
+ caplog.set_level(logging.INFO)
+
+ catalog: AntaCatalog = AntaCatalog.parse(str(DATA_DIR / "test_catalog_with_tags.yml"))
+ selected_tests = prepare_tests(inventory=test_inventory, catalog=catalog, tags=tags, tests=None)
+
+ if selected_tests is None:
+ assert expected_tests_count == 0
+ expected_log = f"There are no tests matching the tags {tags} to run in the current test catalog and device inventory, please verify your inputs."
+ assert expected_log in caplog.text
+ else:
+ assert len(selected_tests) == expected_devices_count
+ assert sum(len(tests) for tests in selected_tests.values()) == expected_tests_count
+
+
+@pytest.mark.asyncio()
+async def test_prepare_tests_with_specific_tests(caplog: pytest.LogCaptureFixture, test_inventory: AntaInventory) -> None:
+ """Test the runner prepare_tests function with specific tests."""
+ logger.setup_logging(logger.Log.INFO)
+ caplog.set_level(logging.INFO)
+
+ catalog: AntaCatalog = AntaCatalog.parse(str(DATA_DIR / "test_catalog_with_tags.yml"))
+ selected_tests = prepare_tests(inventory=test_inventory, catalog=catalog, tags=None, tests={"VerifyMlagStatus", "VerifyUptime"})
+
+ assert selected_tests is not None
+ assert len(selected_tests) == 3
+ assert sum(len(tests) for tests in selected_tests.values()) == 5
+
+
+@pytest.mark.asyncio()
+async def test_runner_dry_run(caplog: pytest.LogCaptureFixture, test_inventory: AntaInventory) -> None:
+ """Test that when dry_run is True, no tests are run.
+
+ caplog is the pytest fixture to capture logs
+ test_inventory is a fixture that gives a default inventory for tests
+ """
+ logger.setup_logging(logger.Log.INFO)
+ caplog.set_level(logging.INFO)
+ manager = ResultManager()
+ catalog_path = Path(__file__).parent.parent / "data" / "test_catalog.yml"
+ catalog = AntaCatalog.parse(catalog_path)
+
+ await main(manager, test_inventory, catalog, dry_run=True)
- assert "No device in the established state 'True' matching the tags ['toto'] was found. There is no device to run tests against, exiting" in [
- record.message for record in caplog.records
- ]
+ # Check that the last log contains Dry-run
+ assert "Dry-run" in caplog.records[-1].message
diff --git a/tests/units/test_tools.py b/tests/units/test_tools.py
new file mode 100644
index 0000000..c3a57e5
--- /dev/null
+++ b/tests/units/test_tools.py
@@ -0,0 +1,504 @@
+# Copyright (c) 2023-2024 Arista Networks, Inc.
+# Use of this source code is governed by the Apache License 2.0
+# that can be found in the LICENSE file.
+"""Tests for `anta.tools`."""
+
+from __future__ import annotations
+
+from contextlib import AbstractContextManager
+from contextlib import nullcontext as does_not_raise
+from typing import Any
+
+import pytest
+
+from anta.tools import custom_division, get_dict_superset, get_failed_logs, get_item, get_value
+
+TEST_GET_FAILED_LOGS_DATA = [
+ {"id": 1, "name": "Alice", "age": 30, "email": "alice@example.com"},
+ {"id": 2, "name": "Bob", "age": 35, "email": "bob@example.com"},
+ {"id": 3, "name": "Charlie", "age": 40, "email": "charlie@example.com"},
+ {"id": 4, "name": "Jon", "age": 25, "email": "Jon@example.com"},
+ {"id": 4, "name": "Rob", "age": 25, "email": "Jon@example.com"},
+]
+TEST_GET_DICT_SUPERSET_DATA = [
+ ("id", 0),
+ {
+ "id": 1,
+ "name": "Alice",
+ "age": 30,
+ "email": "alice@example.com",
+ },
+ {
+ "id": 2,
+ "name": "Bob",
+ "age": 35,
+ "email": "bob@example.com",
+ },
+ {
+ "id": 3,
+ "name": "Charlie",
+ "age": 40,
+ "email": "charlie@example.com",
+ },
+]
+TEST_GET_VALUE_DATA = {"test_value": 42, "nested_test": {"nested_value": 43}}
+TEST_GET_ITEM_DATA = [
+ ("id", 0),
+ {
+ "id": 1,
+ "name": "Alice",
+ "age": 30,
+ "email": "alice@example.com",
+ },
+ {
+ "id": 2,
+ "name": "Bob",
+ "age": 35,
+ "email": "bob@example.com",
+ },
+ {
+ "id": 3,
+ "name": "Charlie",
+ "age": 40,
+ "email": "charlie@example.com",
+ },
+]
+
+
+@pytest.mark.parametrize(
+ ("expected_output", "actual_output", "expected_result"),
+ [
+ pytest.param(
+ TEST_GET_FAILED_LOGS_DATA[0],
+ TEST_GET_FAILED_LOGS_DATA[0],
+ "",
+ id="no difference",
+ ),
+ pytest.param(
+ TEST_GET_FAILED_LOGS_DATA[0],
+ TEST_GET_FAILED_LOGS_DATA[1],
+ "\nExpected `1` as the id, but found `2` instead.\nExpected `Alice` as the name, but found `Bob` instead.\n"
+ "Expected `30` as the age, but found `35` instead.\nExpected `alice@example.com` as the email, but found `bob@example.com` instead.",
+ id="different data",
+ ),
+ pytest.param(
+ TEST_GET_FAILED_LOGS_DATA[0],
+ {},
+ "\nExpected `1` as the id, but it was not found in the actual output.\nExpected `Alice` as the name, but it was not found in the actual output.\n"
+ "Expected `30` as the age, but it was not found in the actual output.\nExpected `alice@example.com` as the email, but it was not found in "
+ "the actual output.",
+ id="empty actual output",
+ ),
+ pytest.param(
+ TEST_GET_FAILED_LOGS_DATA[3],
+ TEST_GET_FAILED_LOGS_DATA[4],
+ "\nExpected `Jon` as the name, but found `Rob` instead.",
+ id="different name",
+ ),
+ ],
+)
+def test_get_failed_logs(
+ expected_output: dict[Any, Any],
+ actual_output: dict[Any, Any],
+ expected_result: str,
+) -> None:
+ """Test get_failed_logs."""
+ assert get_failed_logs(expected_output, actual_output) == expected_result
+
+
+@pytest.mark.parametrize(
+ (
+ "list_of_dicts",
+ "input_dict",
+ "default",
+ "required",
+ "var_name",
+ "custom_error_msg",
+ "expected_result",
+ "expected_raise",
+ ),
+ [
+ pytest.param(
+ [],
+ {"id": 1, "name": "Alice"},
+ None,
+ False,
+ None,
+ None,
+ None,
+ does_not_raise(),
+ id="empty list",
+ ),
+ pytest.param(
+ [],
+ {"id": 1, "name": "Alice"},
+ None,
+ True,
+ None,
+ None,
+ None,
+ pytest.raises(ValueError, match="not found in the provided list."),
+ id="empty list and required",
+ ),
+ pytest.param(
+ TEST_GET_DICT_SUPERSET_DATA,
+ {"id": 10, "name": "Jack"},
+ None,
+ False,
+ None,
+ None,
+ None,
+ does_not_raise(),
+ id="missing item",
+ ),
+ pytest.param(
+ TEST_GET_DICT_SUPERSET_DATA,
+ {"id": 1, "name": "Alice"},
+ None,
+ False,
+ None,
+ None,
+ TEST_GET_DICT_SUPERSET_DATA[1],
+ does_not_raise(),
+ id="found item",
+ ),
+ pytest.param(
+ TEST_GET_DICT_SUPERSET_DATA,
+ {"id": 10, "name": "Jack"},
+ "default_value",
+ False,
+ None,
+ None,
+ "default_value",
+ does_not_raise(),
+ id="default value",
+ ),
+ pytest.param(
+ TEST_GET_DICT_SUPERSET_DATA,
+ {"id": 10, "name": "Jack"},
+ None,
+ True,
+ None,
+ None,
+ None,
+ pytest.raises(ValueError, match="not found in the provided list."),
+ id="required",
+ ),
+ pytest.param(
+ TEST_GET_DICT_SUPERSET_DATA,
+ {"id": 10, "name": "Jack"},
+ None,
+ True,
+ "custom_var_name",
+ None,
+ None,
+ pytest.raises(ValueError, match="custom_var_name not found in the provided list."),
+ id="custom var_name",
+ ),
+ pytest.param(
+ TEST_GET_DICT_SUPERSET_DATA,
+ {"id": 1, "name": "Alice"},
+ None,
+ True,
+ "custom_var_name",
+ "Custom error message",
+ TEST_GET_DICT_SUPERSET_DATA[1],
+ does_not_raise(),
+ id="custom error message",
+ ),
+ pytest.param(
+ TEST_GET_DICT_SUPERSET_DATA,
+ {"id": 10, "name": "Jack"},
+ None,
+ True,
+ "custom_var_name",
+ "Custom error message",
+ None,
+ pytest.raises(ValueError, match="Custom error message"),
+ id="custom error message and required",
+ ),
+ pytest.param(
+ TEST_GET_DICT_SUPERSET_DATA,
+ {"id": 1, "name": "Jack"},
+ None,
+ False,
+ None,
+ None,
+ None,
+ does_not_raise(),
+ id="id ok but name not ok",
+ ),
+ pytest.param(
+ "not a list",
+ {"id": 1, "name": "Alice"},
+ None,
+ True,
+ None,
+ None,
+ None,
+ pytest.raises(ValueError, match="not found in the provided list."),
+ id="non-list input for list_of_dicts",
+ ),
+ pytest.param(
+ TEST_GET_DICT_SUPERSET_DATA,
+ "not a dict",
+ None,
+ True,
+ None,
+ None,
+ None,
+ pytest.raises(ValueError, match="not found in the provided list."),
+ id="non-dictionary input",
+ ),
+ pytest.param(
+ TEST_GET_DICT_SUPERSET_DATA,
+ {},
+ None,
+ False,
+ None,
+ None,
+ None,
+ does_not_raise(),
+ id="empty dictionary input",
+ ),
+ pytest.param(
+ TEST_GET_DICT_SUPERSET_DATA,
+ {"id": 1, "name": "Alice", "extra_key": "extra_value"},
+ None,
+ True,
+ None,
+ None,
+ None,
+ pytest.raises(ValueError, match="not found in the provided list."),
+ id="input dictionary with extra keys",
+ ),
+ pytest.param(
+ TEST_GET_DICT_SUPERSET_DATA,
+ {"id": 1},
+ None,
+ False,
+ None,
+ None,
+ TEST_GET_DICT_SUPERSET_DATA[1],
+ does_not_raise(),
+ id="input dictionary is a subset of more than one dictionary in list_of_dicts",
+ ),
+ pytest.param(
+ TEST_GET_DICT_SUPERSET_DATA,
+ {
+ "id": 1,
+ "name": "Alice",
+ "age": 30,
+ "email": "alice@example.com",
+ "extra_key": "extra_value",
+ },
+ None,
+ True,
+ None,
+ None,
+ None,
+ pytest.raises(ValueError, match="not found in the provided list."),
+ id="input dictionary is a superset of a dictionary in list_of_dicts",
+ ),
+ ],
+)
+def test_get_dict_superset(
+ list_of_dicts: list[dict[Any, Any]],
+ input_dict: dict[Any, Any],
+ default: str | None,
+ required: bool,
+ var_name: str | None,
+ custom_error_msg: str | None,
+ expected_result: str,
+ expected_raise: AbstractContextManager[Exception],
+) -> None:
+ """Test get_dict_superset."""
+ # pylint: disable=too-many-arguments
+ with expected_raise:
+ assert get_dict_superset(list_of_dicts, input_dict, default, var_name, custom_error_msg, required=required) == expected_result
+
+
+@pytest.mark.parametrize(
+ (
+ "input_dict",
+ "key",
+ "default",
+ "required",
+ "org_key",
+ "separator",
+ "expected_result",
+ "expected_raise",
+ ),
+ [
+ pytest.param({}, "test", None, False, None, None, None, does_not_raise(), id="empty dict"),
+ pytest.param(
+ TEST_GET_VALUE_DATA,
+ "test_value",
+ None,
+ False,
+ None,
+ None,
+ 42,
+ does_not_raise(),
+ id="simple key",
+ ),
+ pytest.param(
+ TEST_GET_VALUE_DATA,
+ "nested_test.nested_value",
+ None,
+ False,
+ None,
+ None,
+ 43,
+ does_not_raise(),
+ id="nested_key",
+ ),
+ pytest.param(
+ TEST_GET_VALUE_DATA,
+ "missing_value",
+ None,
+ False,
+ None,
+ None,
+ None,
+ does_not_raise(),
+ id="missing_value",
+ ),
+ pytest.param(
+ TEST_GET_VALUE_DATA,
+ "missing_value_with_default",
+ "default_value",
+ False,
+ None,
+ None,
+ "default_value",
+ does_not_raise(),
+ id="default",
+ ),
+ pytest.param(
+ TEST_GET_VALUE_DATA,
+ "missing_required",
+ None,
+ True,
+ None,
+ None,
+ None,
+ pytest.raises(ValueError, match="missing_required"),
+ id="required",
+ ),
+ pytest.param(
+ TEST_GET_VALUE_DATA,
+ "missing_required",
+ None,
+ True,
+ "custom_org_key",
+ None,
+ None,
+ pytest.raises(ValueError, match="custom_org_key"),
+ id="custom org_key",
+ ),
+ pytest.param(
+ TEST_GET_VALUE_DATA,
+ "nested_test||nested_value",
+ None,
+ None,
+ None,
+ "||",
+ 43,
+ does_not_raise(),
+ id="custom separator",
+ ),
+ ],
+)
+def test_get_value(
+ input_dict: dict[Any, Any],
+ key: str,
+ default: str | None,
+ required: bool,
+ org_key: str | None,
+ separator: str | None,
+ expected_result: int | str | None,
+ expected_raise: AbstractContextManager[Exception],
+) -> None:
+ """Test get_value."""
+ # pylint: disable=too-many-arguments
+ kwargs = {
+ "default": default,
+ "required": required,
+ "org_key": org_key,
+ "separator": separator,
+ }
+ kwargs = {k: v for k, v in kwargs.items() if v is not None}
+ with expected_raise:
+ assert get_value(input_dict, key, **kwargs) == expected_result # type: ignore[arg-type]
+
+
+@pytest.mark.parametrize(
+ ("list_of_dicts", "key", "value", "default", "required", "case_sensitive", "var_name", "custom_error_msg", "expected_result", "expected_raise"),
+ [
+ pytest.param([], "name", "Bob", None, False, False, None, None, None, does_not_raise(), id="empty list"),
+ pytest.param([], "name", "Bob", None, True, False, None, None, None, pytest.raises(ValueError, match="name"), id="empty list and required"),
+ pytest.param(TEST_GET_ITEM_DATA, "name", "Jack", None, False, False, None, None, None, does_not_raise(), id="missing item"),
+ pytest.param(TEST_GET_ITEM_DATA, "name", "Alice", None, False, False, None, None, TEST_GET_ITEM_DATA[1], does_not_raise(), id="found item"),
+ pytest.param(TEST_GET_ITEM_DATA, "name", "Jack", "default_value", False, False, None, None, "default_value", does_not_raise(), id="default value"),
+ pytest.param(TEST_GET_ITEM_DATA, "name", "Jack", None, True, False, None, None, None, pytest.raises(ValueError, match="name"), id="required"),
+ pytest.param(TEST_GET_ITEM_DATA, "name", "Bob", None, False, True, None, None, TEST_GET_ITEM_DATA[2], does_not_raise(), id="case sensitive"),
+ pytest.param(TEST_GET_ITEM_DATA, "name", "charlie", None, False, False, None, None, TEST_GET_ITEM_DATA[3], does_not_raise(), id="case insensitive"),
+ pytest.param(
+ TEST_GET_ITEM_DATA,
+ "name",
+ "Jack",
+ None,
+ True,
+ False,
+ "custom_var_name",
+ None,
+ None,
+ pytest.raises(ValueError, match="custom_var_name"),
+ id="custom var_name",
+ ),
+ pytest.param(
+ TEST_GET_ITEM_DATA,
+ "name",
+ "Jack",
+ None,
+ True,
+ False,
+ None,
+ "custom_error_msg",
+ None,
+ pytest.raises(ValueError, match="custom_error_msg"),
+ id="custom error msg",
+ ),
+ ],
+)
+def test_get_item(
+ list_of_dicts: list[dict[Any, Any]],
+ key: str,
+ value: str | None,
+ default: str | None,
+ required: bool,
+ case_sensitive: bool,
+ var_name: str | None,
+ custom_error_msg: str | None,
+ expected_result: str,
+ expected_raise: AbstractContextManager[Exception],
+) -> None:
+ """Test get_item."""
+ # pylint: disable=too-many-arguments
+ with expected_raise:
+ assert get_item(list_of_dicts, key, value, default, var_name, custom_error_msg, required=required, case_sensitive=case_sensitive) == expected_result
+
+
+@pytest.mark.parametrize(
+ ("numerator", "denominator", "expected_result"),
+ [
+ pytest.param(4.0, 2.0, 2, id="int return for float input"),
+ pytest.param(4, 2, 2, id="int return for int input"),
+ pytest.param(5.0, 2.0, 2.5, id="float return for float input"),
+ pytest.param(5, 2, 2.5, id="float return for int input"),
+ ],
+)
+def test_custom_division(numerator: float, denominator: float, expected_result: str) -> None:
+ """Test custom_division."""
+ assert custom_division(numerator, denominator) == expected_result
diff --git a/tests/units/tools/test_get_dict_superset.py b/tests/units/tools/test_get_dict_superset.py
deleted file mode 100644
index 63e08b5..0000000
--- a/tests/units/tools/test_get_dict_superset.py
+++ /dev/null
@@ -1,149 +0,0 @@
-# Copyright (c) 2023-2024 Arista Networks, Inc.
-# Use of this source code is governed by the Apache License 2.0
-# that can be found in the LICENSE file.
-
-"""Tests for `anta.tools.get_dict_superset`."""
-from __future__ import annotations
-
-from contextlib import nullcontext as does_not_raise
-from typing import Any
-
-import pytest
-
-from anta.tools.get_dict_superset import get_dict_superset
-
-# pylint: disable=duplicate-code
-DUMMY_DATA = [
- ("id", 0),
- {
- "id": 1,
- "name": "Alice",
- "age": 30,
- "email": "alice@example.com",
- },
- {
- "id": 2,
- "name": "Bob",
- "age": 35,
- "email": "bob@example.com",
- },
- {
- "id": 3,
- "name": "Charlie",
- "age": 40,
- "email": "charlie@example.com",
- },
-]
-
-
-@pytest.mark.parametrize(
- "list_of_dicts, input_dict, default, required, var_name, custom_error_msg, expected_result, expected_raise",
- [
- pytest.param([], {"id": 1, "name": "Alice"}, None, False, None, None, None, does_not_raise(), id="empty list"),
- pytest.param(
- [],
- {"id": 1, "name": "Alice"},
- None,
- True,
- None,
- None,
- None,
- pytest.raises(ValueError, match="not found in the provided list."),
- id="empty list and required",
- ),
- pytest.param(DUMMY_DATA, {"id": 10, "name": "Jack"}, None, False, None, None, None, does_not_raise(), id="missing item"),
- pytest.param(DUMMY_DATA, {"id": 1, "name": "Alice"}, None, False, None, None, DUMMY_DATA[1], does_not_raise(), id="found item"),
- pytest.param(DUMMY_DATA, {"id": 10, "name": "Jack"}, "default_value", False, None, None, "default_value", does_not_raise(), id="default value"),
- pytest.param(
- DUMMY_DATA, {"id": 10, "name": "Jack"}, None, True, None, None, None, pytest.raises(ValueError, match="not found in the provided list."), id="required"
- ),
- pytest.param(
- DUMMY_DATA,
- {"id": 10, "name": "Jack"},
- None,
- True,
- "custom_var_name",
- None,
- None,
- pytest.raises(ValueError, match="custom_var_name not found in the provided list."),
- id="custom var_name",
- ),
- pytest.param(
- DUMMY_DATA, {"id": 1, "name": "Alice"}, None, True, "custom_var_name", "Custom error message", DUMMY_DATA[1], does_not_raise(), id="custom error message"
- ),
- pytest.param(
- DUMMY_DATA,
- {"id": 10, "name": "Jack"},
- None,
- True,
- "custom_var_name",
- "Custom error message",
- None,
- pytest.raises(ValueError, match="Custom error message"),
- id="custom error message and required",
- ),
- pytest.param(DUMMY_DATA, {"id": 1, "name": "Jack"}, None, False, None, None, None, does_not_raise(), id="id ok but name not ok"),
- pytest.param(
- "not a list",
- {"id": 1, "name": "Alice"},
- None,
- True,
- None,
- None,
- None,
- pytest.raises(ValueError, match="not found in the provided list."),
- id="non-list input for list_of_dicts",
- ),
- pytest.param(
- DUMMY_DATA, "not a dict", None, True, None, None, None, pytest.raises(ValueError, match="not found in the provided list."), id="non-dictionary input"
- ),
- pytest.param(DUMMY_DATA, {}, None, False, None, None, None, does_not_raise(), id="empty dictionary input"),
- pytest.param(
- DUMMY_DATA,
- {"id": 1, "name": "Alice", "extra_key": "extra_value"},
- None,
- True,
- None,
- None,
- None,
- pytest.raises(ValueError, match="not found in the provided list."),
- id="input dictionary with extra keys",
- ),
- pytest.param(
- DUMMY_DATA,
- {"id": 1},
- None,
- False,
- None,
- None,
- DUMMY_DATA[1],
- does_not_raise(),
- id="input dictionary is a subset of more than one dictionary in list_of_dicts",
- ),
- pytest.param(
- DUMMY_DATA,
- {"id": 1, "name": "Alice", "age": 30, "email": "alice@example.com", "extra_key": "extra_value"},
- None,
- True,
- None,
- None,
- None,
- pytest.raises(ValueError, match="not found in the provided list."),
- id="input dictionary is a superset of a dictionary in list_of_dicts",
- ),
- ],
-)
-def test_get_dict_superset(
- list_of_dicts: list[dict[Any, Any]],
- input_dict: Any,
- default: Any | None,
- required: bool,
- var_name: str | None,
- custom_error_msg: str | None,
- expected_result: str,
- expected_raise: Any,
-) -> None:
- """Test get_dict_superset."""
- # pylint: disable=too-many-arguments
- with expected_raise:
- assert get_dict_superset(list_of_dicts, input_dict, default, required, var_name, custom_error_msg) == expected_result
diff --git a/tests/units/tools/test_get_item.py b/tests/units/tools/test_get_item.py
deleted file mode 100644
index 7d75e9c..0000000
--- a/tests/units/tools/test_get_item.py
+++ /dev/null
@@ -1,72 +0,0 @@
-# Copyright (c) 2023-2024 Arista Networks, Inc.
-# Use of this source code is governed by the Apache License 2.0
-# that can be found in the LICENSE file.
-
-"""Tests for `anta.tools.get_item`."""
-from __future__ import annotations
-
-from contextlib import nullcontext as does_not_raise
-from typing import Any
-
-import pytest
-
-from anta.tools.get_item import get_item
-
-DUMMY_DATA = [
- ("id", 0),
- {
- "id": 1,
- "name": "Alice",
- "age": 30,
- "email": "alice@example.com",
- },
- {
- "id": 2,
- "name": "Bob",
- "age": 35,
- "email": "bob@example.com",
- },
- {
- "id": 3,
- "name": "Charlie",
- "age": 40,
- "email": "charlie@example.com",
- },
-]
-
-
-@pytest.mark.parametrize(
- "list_of_dicts, key, value, default, required, case_sensitive, var_name, custom_error_msg, expected_result, expected_raise",
- [
- pytest.param([], "name", "Bob", None, False, False, None, None, None, does_not_raise(), id="empty list"),
- pytest.param([], "name", "Bob", None, True, False, None, None, None, pytest.raises(ValueError, match="name"), id="empty list and required"),
- pytest.param(DUMMY_DATA, "name", "Jack", None, False, False, None, None, None, does_not_raise(), id="missing item"),
- pytest.param(DUMMY_DATA, "name", "Alice", None, False, False, None, None, DUMMY_DATA[1], does_not_raise(), id="found item"),
- pytest.param(DUMMY_DATA, "name", "Jack", "default_value", False, False, None, None, "default_value", does_not_raise(), id="default value"),
- pytest.param(DUMMY_DATA, "name", "Jack", None, True, False, None, None, None, pytest.raises(ValueError, match="name"), id="required"),
- pytest.param(DUMMY_DATA, "name", "Bob", None, False, True, None, None, DUMMY_DATA[2], does_not_raise(), id="case sensitive"),
- pytest.param(DUMMY_DATA, "name", "charlie", None, False, False, None, None, DUMMY_DATA[3], does_not_raise(), id="case insensitive"),
- pytest.param(
- DUMMY_DATA, "name", "Jack", None, True, False, "custom_var_name", None, None, pytest.raises(ValueError, match="custom_var_name"), id="custom var_name"
- ),
- pytest.param(
- DUMMY_DATA, "name", "Jack", None, True, False, None, "custom_error_msg", None, pytest.raises(ValueError, match="custom_error_msg"), id="custom error msg"
- ),
- ],
-)
-def test_get_item(
- list_of_dicts: list[dict[Any, Any]],
- key: Any,
- value: Any,
- default: Any | None,
- required: bool,
- case_sensitive: bool,
- var_name: str | None,
- custom_error_msg: str | None,
- expected_result: str,
- expected_raise: Any,
-) -> None:
- """Test get_item."""
- # pylint: disable=too-many-arguments
- with expected_raise:
- assert get_item(list_of_dicts, key, value, default, required, case_sensitive, var_name, custom_error_msg) == expected_result
diff --git a/tests/units/tools/test_get_value.py b/tests/units/tools/test_get_value.py
deleted file mode 100644
index 73344d1..0000000
--- a/tests/units/tools/test_get_value.py
+++ /dev/null
@@ -1,50 +0,0 @@
-# Copyright (c) 2023-2024 Arista Networks, Inc.
-# Use of this source code is governed by the Apache License 2.0
-# that can be found in the LICENSE file.
-"""
-Tests for anta.tools.get_value
-"""
-
-from __future__ import annotations
-
-from contextlib import nullcontext as does_not_raise
-from typing import Any
-
-import pytest
-
-from anta.tools.get_value import get_value
-
-INPUT_DICT = {"test_value": 42, "nested_test": {"nested_value": 43}}
-
-
-@pytest.mark.parametrize(
- "input_dict, key, default, required, org_key, separator, expected_result, expected_raise",
- [
- pytest.param({}, "test", None, False, None, None, None, does_not_raise(), id="empty dict"),
- pytest.param(INPUT_DICT, "test_value", None, False, None, None, 42, does_not_raise(), id="simple key"),
- pytest.param(INPUT_DICT, "nested_test.nested_value", None, False, None, None, 43, does_not_raise(), id="nested_key"),
- pytest.param(INPUT_DICT, "missing_value", None, False, None, None, None, does_not_raise(), id="missing_value"),
- pytest.param(INPUT_DICT, "missing_value_with_default", "default_value", False, None, None, "default_value", does_not_raise(), id="default"),
- pytest.param(INPUT_DICT, "missing_required", None, True, None, None, None, pytest.raises(ValueError), id="required"),
- pytest.param(INPUT_DICT, "missing_required", None, True, "custom_org_key", None, None, pytest.raises(ValueError), id="custom org_key"),
- pytest.param(INPUT_DICT, "nested_test||nested_value", None, None, None, "||", 43, does_not_raise(), id="custom separator"),
- ],
-)
-def test_get_value(
- input_dict: dict[Any, Any],
- key: str,
- default: str | None,
- required: bool,
- org_key: str | None,
- separator: str | None,
- expected_result: str,
- expected_raise: Any,
-) -> None:
- """
- Test get_value
- """
- # pylint: disable=too-many-arguments
- kwargs = {"default": default, "required": required, "org_key": org_key, "separator": separator}
- kwargs = {k: v for k, v in kwargs.items() if v is not None}
- with expected_raise:
- assert get_value(input_dict, key, **kwargs) == expected_result # type: ignore
diff --git a/tests/units/tools/test_misc.py b/tests/units/tools/test_misc.py
deleted file mode 100644
index c453c21..0000000
--- a/tests/units/tools/test_misc.py
+++ /dev/null
@@ -1,38 +0,0 @@
-# Copyright (c) 2023-2024 Arista Networks, Inc.
-# Use of this source code is governed by the Apache License 2.0
-# that can be found in the LICENSE file.
-"""
-Tests for anta.tools.misc
-"""
-from __future__ import annotations
-
-import pytest
-
-from anta.tools.misc import exc_to_str, tb_to_str
-
-
-def my_raising_function(exception: Exception) -> None:
- """
- dummy function to raise Exception
- """
- raise exception
-
-
-@pytest.mark.parametrize("exception, expected_output", [(ValueError("test"), "ValueError (test)"), (ValueError(), "ValueError")])
-def test_exc_to_str(exception: Exception, expected_output: str) -> None:
- """
- Test exc_to_str
- """
- assert exc_to_str(exception) == expected_output
-
-
-def test_tb_to_str() -> None:
- """
- Test tb_to_str
- """
- try:
- my_raising_function(ValueError("test"))
- except ValueError as e:
- output = tb_to_str(e)
- assert "Traceback" in output
- assert 'my_raising_function(ValueError("test"))' in output
diff --git a/tests/units/tools/test_utils.py b/tests/units/tools/test_utils.py
deleted file mode 100644
index 448324f..0000000
--- a/tests/units/tools/test_utils.py
+++ /dev/null
@@ -1,57 +0,0 @@
-# Copyright (c) 2023-2024 Arista Networks, Inc.
-# Use of this source code is governed by the Apache License 2.0
-# that can be found in the LICENSE file.
-
-"""Tests for `anta.tools.utils`."""
-from __future__ import annotations
-
-from contextlib import nullcontext as does_not_raise
-from typing import Any
-
-import pytest
-
-from anta.tools.utils import get_failed_logs
-
-EXPECTED_OUTPUTS = [
- {"id": 1, "name": "Alice", "age": 30, "email": "alice@example.com"},
- {"id": 2, "name": "Bob", "age": 35, "email": "bob@example.com"},
- {"id": 3, "name": "Charlie", "age": 40, "email": "charlie@example.com"},
- {"id": 4, "name": "Jon", "age": 25, "email": "Jon@example.com"},
-]
-
-ACTUAL_OUTPUTS = [
- {"id": 1, "name": "Alice", "age": 30, "email": "alice@example.com"},
- {"id": 2, "name": "Bob", "age": 35, "email": "bob@example.com"},
- {"id": 3, "name": "Charlie", "age": 40, "email": "charlie@example.com"},
- {"id": 4, "name": "Rob", "age": 25, "email": "Jon@example.com"},
-]
-
-
-@pytest.mark.parametrize(
- "expected_output, actual_output, expected_result, expected_raise",
- [
- pytest.param(EXPECTED_OUTPUTS[0], ACTUAL_OUTPUTS[0], "", does_not_raise(), id="no difference"),
- pytest.param(
- EXPECTED_OUTPUTS[0],
- ACTUAL_OUTPUTS[1],
- "\nExpected `1` as the id, but found `2` instead.\nExpected `Alice` as the name, but found `Bob` instead.\n"
- "Expected `30` as the age, but found `35` instead.\nExpected `alice@example.com` as the email, but found `bob@example.com` instead.",
- does_not_raise(),
- id="different data",
- ),
- pytest.param(
- EXPECTED_OUTPUTS[0],
- {},
- "\nExpected `1` as the id, but it was not found in the actual output.\nExpected `Alice` as the name, but it was not found in the actual output.\n"
- "Expected `30` as the age, but it was not found in the actual output.\nExpected `alice@example.com` as the email, but it was not found in "
- "the actual output.",
- does_not_raise(),
- id="empty actual output",
- ),
- pytest.param(EXPECTED_OUTPUTS[3], ACTUAL_OUTPUTS[3], "\nExpected `Jon` as the name, but found `Rob` instead.", does_not_raise(), id="different name"),
- ],
-)
-def test_get_failed_logs(expected_output: dict[Any, Any], actual_output: dict[Any, Any], expected_result: str, expected_raise: Any) -> None:
- """Test get_failed_logs."""
- with expected_raise:
- assert get_failed_logs(expected_output, actual_output) == expected_result