diff --git a/.github/scripts/anta_test.py b/.github/scripts/anta_test.py
deleted file mode 100644
index a1164c06f..000000000
--- a/.github/scripts/anta_test.py
+++ /dev/null
@@ -1,44 +0,0 @@
-"""
-This sccript can be used to test the tests defined in the nata package
-"""
-
-import logging
-import os
-import sys
-from yaml import safe_load
-from anta.inventory import AntaInventory
-import anta.tests
-import anta.loader
-
-logging.disable(level=logging.WARNING)
-dir_path = os.path.dirname(os.path.realpath(__file__))
-
-username = input("username: ")
-password = input("password: ")
-enable_password = input("enable_password: ")
-
-print("connecting to devices ... please be patient ...")
-
-inventory = AntaInventory(
- inventory_file=f"{dir_path}/../../examples/inventory.yml",
- username=username,
- password=password,
- enable_password=enable_password,
- auto_connect=True,
- timeout=2,
-)
-
-devices = inventory.get_inventory(established_only=True)
-
-try:
- with open(f"{dir_path}/../../examples/tests.yaml", "r", encoding="utf8") as file:
- test_catalog = safe_load(file)
-except FileNotFoundError:
- print("Error opening tests_catalog")
- sys.exit(1)
-
-tests = anta.loader.parse_catalog(test_catalog)
-
-for device in devices:
- for test in tests:
- print(test[0](device, **test[1]))
diff --git a/README.md b/README.md
index a5f18dc2a..16f4451c3 100755
--- a/README.md
+++ b/README.md
@@ -18,6 +18,8 @@ This repository comes with a set of [scripts](./scripts) to run __Arista Network
- `collect-eos-commands.py` to collect commands output from devices
- `collect-sheduled-show-tech.py` to collect the scheduled show tech-support files from devices
+
+
In addition you have also some useful scripts to help around testing:
- `clear-counters.py` to clear counters on devices
@@ -28,7 +30,7 @@ In addition you have also some useful scripts to help around testing:
# Documentation
-The documentation is published on https://arista-netdevops-community.github.io/network-test-automation/
+The documentation is published on [ANTA package website](https://arista-netdevops-community.github.io/network-test-automation/)
# Contribution guide
diff --git a/demo.json b/demo.json
new file mode 100644
index 000000000..c36f9b200
--- /dev/null
+++ b/demo.json
@@ -0,0 +1,62 @@
+[
+ {
+ "host": "10.73.252.11",
+ "test": "verify_eos_version",
+ "result": "failure",
+ "messages": "[\"device is running version 4.27.2F-26069621.4272F (engineering build) not in expected versions: ['4.25.4M', '4.26.1F']\"]"
+ },
+ {
+ "host": "10.73.252.11",
+ "test": "verify_field_notice_44_resolution",
+ "result": "skipped",
+ "messages": "['verify_field_notice_44_resolution test is not supported on cEOSLab.']"
+ },
+ {
+ "host": "10.73.252.11",
+ "test": "verify_uptime",
+ "result": "success",
+ "messages": "[]"
+ },
+ {
+ "host": "10.73.252.11",
+ "test": "verify_zerotouch",
+ "result": "success",
+ "messages": "[]"
+ },
+ {
+ "host": "10.73.252.11",
+ "test": "verify_running_config_diffs",
+ "result": "success",
+ "messages": "[]"
+ },
+ {
+ "host": "10.73.252.11",
+ "test": "verify_mlag_status",
+ "result": "success",
+ "messages": "[]"
+ },
+ {
+ "host": "10.73.252.11",
+ "test": "verify_mlag_interfaces",
+ "result": "success",
+ "messages": "[]"
+ },
+ {
+ "host": "10.73.252.11",
+ "test": "verify_mlag_config_sanity",
+ "result": "success",
+ "messages": "[]"
+ },
+ {
+ "host": "10.73.252.11",
+ "test": "verify_routing_protocol_model",
+ "result": "success",
+ "messages": "[]"
+ },
+ {
+ "host": "10.73.252.11",
+ "test": "verify_bgp_ipv4_unicast_state",
+ "result": "success",
+ "messages": "[]"
+ }
+]
\ No newline at end of file
diff --git a/docs/README.md b/docs/README.md
index 1fe5aeadd..a6d1d0897 100644
--- a/docs/README.md
+++ b/docs/README.md
@@ -2,6 +2,8 @@
This website provides generic documentation related to the Arista Network Test Automation framework (ANTA)
+
+
# Arista Network Test Automation (ANTA) Framework
This repository is a Python package to automate tests on Arista devices.
diff --git a/docs/api/tests.md b/docs/api/tests.md
new file mode 100644
index 000000000..9c99d4e45
--- /dev/null
+++ b/docs/api/tests.md
@@ -0,0 +1,18 @@
+# ANTA Tests landing page
+
+This section describes all the available tests provided by ANTA package.
+
+
+- [Configuration](tests.configuration.md)
+- [Hardware](tests.hardware.md)
+- [interfaces](tests.interfaces.md)
+- [MLAG](tests.mlag.md)
+- [Multicast](tests.multicast.md)
+- [Profiles](tests.profiles.md)
+- [System](tests.system.md)
+- [Software](tests.software.md)
+- [Routing Generic](tests.routing.generic.md)
+- [Routing BGP](tests.routing.bgp.md)
+- [Routing OSPF](tests.routing.ospf.md)
+
+Al these tests can be imported in a [catalog](../usage-inventory-catalog.md) to be used by [`check-devices.py`](../usage-check-devices.md) script.
\ No newline at end of file
diff --git a/docs/contribution.md b/docs/contribution.md
new file mode 100644
index 000000000..503a2acc7
--- /dev/null
+++ b/docs/contribution.md
@@ -0,0 +1,91 @@
+# How to contribute to ANTA
+
+!!! warning
+ Still a work in progress, feel free to reach out to the team.
+
+## Install repository
+
+`python setup.py install` is used to install packages that you're not going to modify yourself.
+If you want to install the package and then be able to edit the code without having to re-install the package every time for the changes take effect, you can use `python setup.py develop`
+
+you can also use `pip install -e .`
+The `.` refers to the current working directory (the directory where is the setup.py file).
+The `-e` flag specifies that we want to install in editable mode, which means that when we edit the files in our package we do not need to re-install the package before the changes come into effect. You will need to reload the package though!
+
+Run these commands to install:
+
+- The package [ANTA](https://github.com/arista-netdevops-community/network-test-automation/blob/master/anta) and its dependencies
+- These [scripts](https://github.com/arista-netdevops-community/network-test-automation/blob/master/scripts) and the packages they required
+
+```shell
+git clone https://github.com/arista-netdevops-community/network-test-automation.git
+cd network-test-automation
+```
+
+```shell
+python setup.py develop
+```
+
+or
+
+```shell
+pip install -e .
+```
+
+Run these commands to verify:
+
+```bash
+pip list
+check-devices-reachability.py --help
+which check-devices-reachability.py
+```
+
+### Clone & Install package requirements
+
+Run these commands to install the packages indicated in the [requirements.txt](https://github.com/arista-netdevops-community/network-test-automation/blob/master/requirements.txt) file.
+
+```shell
+# Clone repository
+git clone https://github.com/arista-netdevops-community/network-test-automation.git
+
+# Enter into the repository
+cd network-test-automation
+
+# Install requirements
+pip install -r requirements.txt
+```
+
+These packages are required by:
+
+- These [scripts](https://github.com/arista-netdevops-community/network-test-automation/blob/master/scripts)
+- The package [ANTA](https://github.com/arista-netdevops-community/network-test-automation/blob/master/anta)
+
+But this will **not** install:
+
+- The [ANTA](https://github.com/arista-netdevops-community/network-test-automation/blob/master/anta) package
+- These [scripts](https://github.com/arista-netdevops-community/network-test-automation/blob/master/scripts)
+
+Run this command to verify:
+
+```shell
+# Check ANTA has been installed in your python path
+pip list | grep anta
+
+# Check scripts are in your $PATH
+check-devices-reachability.py --help
+
+# Find where the script is located
+which check-devices-reachability.py
+```
+
+### Install dev requirements
+
+Run the following command to install all required packages for the development process.
+
+```shell
+# Install dev requirements
+pip install -r requirements-dev.txt
+
+# Install pre-commit hook
+pre-commit install
+```
\ No newline at end of file
diff --git a/docs/getting-started.md b/docs/getting-started.md
index a4dc1891f..b85891cb5 100644
--- a/docs/getting-started.md
+++ b/docs/getting-started.md
@@ -7,7 +7,8 @@ This section shows how to use ANTA with basic configuration.
The easiest way to intall ANTA package is to run Python (`>=3.7`) and its pip package to install:
```bash
-pip install git+https://github.com/arista-netdevops-community/network-test-automation.git
+pip install \
+ git+https://github.com/arista-netdevops-community/network-test-automation.git
```
For more details about how to install package, please see the [requirements and intallation](./requirements-and-installation.md) section.
@@ -17,15 +18,19 @@ For more details about how to install package, please see the [requirements and
First, you need to configure your management interface
```eos
+vrf instance MGMT
+!
interface Management1
description oob_management
vrf MGMT
ip address 10.73.1.105/24
+!
```
Then, configure access to eAPI:
```eos
+!
management api http-commands
protocol https port 443
no shutdown
@@ -42,46 +47,9 @@ First, we need to list devices we want to test. You can create a file manually w
```yaml
anta_inventory:
hosts:
- - host: 192.168.0.10
- - host: 192.168.0.11
- # Optional tag to assign to this device
- tags: ['tag01', 'tag02']
- - host: 192.168.0.12
- - host: 192.168.0.13
- - host: 192.168.0.14
- - host: 192.168.0.15
- networks:
- - network: '192.168.110.0/24'
- # Optional tag to assign to all devices in this subnet
- tags: ['tag01', 'tag02']
- ranges:
- - start: 10.0.0.9
- end: 10.0.0.11
- # Optional tag to assign to all devices in this range
- tags: ['tag01', 'tag02']
- - start: 10.0.0.100
- end: 10.0.0.101
+ - host: 10.73.1.105
```
-Or you can use [create-devices-inventory-from-cvp.py](https://github.com/arista-netdevops-community/network-test-automation/blob/master/scripts/create-devices-inventory-from-cvp.py) script to generate from Cloudvision
-
-```bash
-# Available options
-create-devices-inventory-from-cvp.py -h
-usage: create-devices-inventory-from-cvp.py [-h] -cvp CVP -u USERNAME [-c CONTAINER] -o OUTPUT_DIRECTORY
-
-Create devices inventory based on CVP containers
-
-optional arguments:
- -h, --help show this help message and exit
- -cvp CVP CVP address
- -u USERNAME CVP username
- -c CONTAINER CVP container
- -o OUTPUT_DIRECTORY Output directory
-
-# Example
-$ create-devices-inventory-from-cvp.py -cvp 192.168.0.5 -u arista -o inventory -c Spine
-```
## Test Catalog
To test your network, it is important to define a test catalog to list all the tests to run against your inventory. Test catalog references python functions into a yaml file. This file can be loaded by anta.loader.py
@@ -193,3 +161,5 @@ $ check-devices.py -i .personal/avd-lab.yml -c .personal/ceos-catalog.yml --tabl
│ 10.73.252.21 │ 0 │ 1 │ 0 │ 0 │ [] │
└──────────────┴──────────────┴──────────────┴──────────────┴─────────────┴────────────────────────────┘
```
+
+You can find more information under the __usage__ section of the website
\ No newline at end of file
diff --git a/docs/imgs/anta-check-devices-by-host-demo.png b/docs/imgs/anta-check-devices-by-host-demo.png
new file mode 100644
index 000000000..29947bb3d
Binary files /dev/null and b/docs/imgs/anta-check-devices-by-host-demo.png differ
diff --git a/docs/imgs/anta-check-devices-by-test-demo.png b/docs/imgs/anta-check-devices-by-test-demo.png
new file mode 100644
index 000000000..f06e66076
Binary files /dev/null and b/docs/imgs/anta-check-devices-by-test-demo.png differ
diff --git a/docs/imgs/anta-check-devices-table-demo.png b/docs/imgs/anta-check-devices-table-demo.png
new file mode 100644
index 000000000..d6126a13d
Binary files /dev/null and b/docs/imgs/anta-check-devices-table-demo.png differ
diff --git a/docs/imgs/anta-getting-started.png b/docs/imgs/anta-getting-started.png
new file mode 100644
index 000000000..4abcb6fb9
Binary files /dev/null and b/docs/imgs/anta-getting-started.png differ
diff --git a/docs/requirements-and-installation.md b/docs/requirements-and-installation.md
index 38573c4b6..edb353cd3 100644
--- a/docs/requirements-and-installation.md
+++ b/docs/requirements-and-installation.md
@@ -1,37 +1,27 @@
-**Table of Contents**
+# ANTA Requirements
-- [Requirements on your laptop](#requirements-on-your-laptop)
- - [Install the package ANTA and the scripts and the requirements](#install-the-package-anta-and-the-scripts-and-the-requirements)
- - [Use the `pip install` command with the Git URL](#use-the-pip-install-command-with-the-git-url)
- - [Clone the repository and install the package](#clone-the-repository-and-install-the-package)
- - [Using the `pip install .` command](#using-the-pip-install--command)
- - [Using `python setup.py` commands](#using-python-setuppy-commands)
- - [Clone the repository and install the package in editable mode](#clone-the-repository-and-install-the-package-in-editable-mode)
- - [Clone the repository and use the `pip install -r requirements.txt` command](#clone-the-repository-and-use-the-pip-install--r-requirementstxt-command)
- - [Update your PATH environment variable if it is required](#update-your-path-environment-variable-if-it-is-required)
-- [Requirements on the switches](#requirements-on-the-switches)
-- [Quick checks](#quick-checks)
-# Requirements on your laptop
+## Python version
-Python 3 (at least 3.3) is required:
+Python 3 (`>=3.7` and `=<3.10`) is required:
```shell
-python -V
+python --version
+Python 3.9.9
```
-## Install the package ANTA and the scripts and the requirements
+## Install ANTA package
+
+This installation will deploy tests collection, scripts and all their Python requirements.
The ANTA package and the scripts require some packages that are not part of the Python standard library. They are indicated in the [requirements.txt](https://github.com/arista-netdevops-community/network-test-automation/blob/master/requirements.txt) file
There are several ways to installt the [ANTA](https://github.com/arista-netdevops-community/network-test-automation/blob/master/anta) and the [scripts](https://github.com/arista-netdevops-community/network-test-automation/blob/master/scripts) and the [requirements](https://github.com/arista-netdevops-community/network-test-automation/blob/master/requirements.txt). This is described below.
-### Use the `pip install` command with the Git URL
-
Run this command to install:
- The package [ANTA](https://github.com/arista-netdevops-community/network-test-automation/blob/master/anta) and its dependencies
-- These [scripts](https://github.com/arista-netdevops-community/network-test-automation/blob/master/scripts) and the packages they required
+- These [scripts](https://github.com/arista-netdevops-community/network-test-automation/blob/master/scripts) and packages they required
```shell
pip install git+https://github.com/arista-netdevops-community/network-test-automation.git
@@ -41,161 +31,35 @@ You can even specify the commit you would like to install.
Run these commands to verify:
-```bash
-pip list
-check-devices-reachability.py --help
-which check-devices-reachability.py
-```
-
-To update, run this command:
-
-```shell
-pip install -U git+https://github.com/arista-netdevops-community/network-test-automation.git
-```
-
-### Clone the repository and install the package
-
-Run these commands to clone the repository and to move to the new folder:
-
-```shell
-git clone https://github.com/arista-netdevops-community/network-test-automation.git
-cd network-test-automation
-```
-
-#### Using the `pip install .` command
-
-Run this command to install:
-
-- The package [ANTA](https://github.com/arista-netdevops-community/network-test-automation/blob/master/anta) and its dependencies
-- These [scripts](https://github.com/arista-netdevops-community/network-test-automation/blob/master/scripts) and the packages they required
-
-```shell
-pip install .
-```
-
-Run these commands to verify:
-
-```bash
-pip list
-check-devices-reachability.py --help
-which check-devices-reachability.py
-```
-
-#### Using `python setup.py` commands
-
-Run this command to build the package [ANTA](https://github.com/arista-netdevops-community/network-test-automation/blob/master/anta):
-
-```shell
-python setup.py build
-```
-
-Run this command to install:
-
-- The package [ANTA](https://github.com/arista-netdevops-community/network-test-automation/blob/master/anta) and its dependencies
-- These [scripts](https://github.com/arista-netdevops-community/network-test-automation/blob/master/scripts) and the packages they required
-
```shell
-python setup.py install
-```
-
-Run these commands to verify:
+# Check ANTA has been installed in your python path
+pip list | grep anta
-```bash
-pip list
+# Check scripts are in your $PATH
check-devices-reachability.py --help
-which check-devices-reachability.py
-```
-### Clone the repository and install the package in editable mode
-
-`python setup.py install` is used to install packages that you're not going to modify yourself.
-If you want to install the package and then be able to edit the code without having to re-install the package every time for the changes take effect, you can use `python setup.py develop`
-
-you can also use `pip install -e .`
-The `.` refers to the current working directory (the directory where is the setup.py file).
-The `-e` flag specifies that we want to install in editable mode, which means that when we edit the files in our package we do not need to re-install the package before the changes come into effect. You will need to reload the package though!
-
-Run these commands to install:
-
-- The package [ANTA](https://github.com/arista-netdevops-community/network-test-automation/blob/master/anta) and its dependencies
-- These [scripts](https://github.com/arista-netdevops-community/network-test-automation/blob/master/scripts) and the packages they required
-
-```shell
-git clone https://github.com/arista-netdevops-community/network-test-automation.git
-cd network-test-automation
-```
-
-```shell
-python setup.py develop
-```
-
-or
-
-```shell
-pip install -e .
-```
-
-Run these commands to verify:
-
-```bash
-pip list
-check-devices-reachability.py --help
+# Find where the script is located
which check-devices-reachability.py
```
-### Clone the repository and use the `pip install -r requirements.txt` command
-
-Run these commands to install the packages indicated in the [requirements.txt](https://github.com/arista-netdevops-community/network-test-automation/blob/master/requirements.txt) file.
+To update, simply run pip with `-U` option:
```shell
-git clone https://github.com/arista-netdevops-community/network-test-automation.git
-cd network-test-automation
-pip install -r requirements.txt
-```
-
-These packages are required by:
-
-- These [scripts](https://github.com/arista-netdevops-community/network-test-automation/blob/master/scripts)
-- The package [ANTA](https://github.com/arista-netdevops-community/network-test-automation/blob/master/anta)
-
-But this will **not** install:
-
-- The [ANTA](https://github.com/arista-netdevops-community/network-test-automation/blob/master/anta) package
-- These [scripts](https://github.com/arista-netdevops-community/network-test-automation/blob/master/scripts)
-
-Run this command to verify:
-
-```bash
-pip list
-```
-
-## Update your PATH environment variable if it is required
-
-If the path where the scripts are installed is not yet include in your PATH environment variable, please update it.
-
-Here's an example if the scripts are installed here:
-
-```bash
-ls -l /home/arista/.local/bin/
-```
-
-Run this command to update path to update your PATH environment variable:
-
-```bash
-echo $HOME
-echo $PATH
-export PATH="$HOME/.local/bin:$PATH"
-echo $PATH
+pip install -U git+https://github.com/arista-netdevops-community/network-test-automation.git
```
-# Requirements on the switches
+## EOS Requirements
```eos
configure
+!
+vrf instance MGMT
+!
interface Management1
description oob_management
vrf MGMT
ip address 10.73.1.105/24
+!
end
```
@@ -203,11 +67,13 @@ Enable eAPI on the MGMT vrf:
```eos
configure
+!
management api http-commands
protocol https port 443
no shutdown
vrf MGMT
no shutdown
+!
end
```
@@ -223,7 +89,7 @@ switch1#show management http-server
switch1#show management api http-commands
```
-# Quick checks
+## Check eAPI and ANTA
Execute this python script to validate:
@@ -234,22 +100,25 @@ Use your device credentials and IP address.
```python
import ssl
from jsonrpclib import Server
+from anta.tests.system import verify_ntp
+
ssl._create_default_https_context = ssl._create_unverified_context
+
+# Update credentials accordingly
USERNAME = "arista"
PASSWORD = "aristatwfn"
ENABLE_PASSWORD = "aristatwfn"
+
+# Change IP address with an Arista EOS device
IP = "192.168.0.12"
-URL=f'https://{USERNAME}:{PASSWORD}@{IP}/command-api'
-switch = Server(URL)
+
+url=f'https://{USERNAME}:{PASSWORD}@{IP}/command-api'
+switch = Server(url)
result=switch.runCmds(1,['show version'], 'json')
-print(result[0]['uptime'])
-```
-Run these python commands to validate you can import and use the [ANTA](anta) package
+# Check eAPI is reachable
+print(result[0]['uptime'])
-```python
-from anta.tests.system import *
-dir()
-help(verify_ntp)
-exit()
+# Check ANTA package is correctly installed
+print(verify_ntp.__doc__)
```
diff --git a/docs/stylesheets/extra.material.css b/docs/stylesheets/extra.material.css
index 057ef8ace..5fc73bf47 100644
--- a/docs/stylesheets/extra.material.css
+++ b/docs/stylesheets/extra.material.css
@@ -188,5 +188,10 @@
width: 100%;
text-align: center;
}
-
+ .img_center {
+ display: block;
+ margin-left: auto;
+ margin-right: auto;
+ /* width: 50%; */
+ }
}
diff --git a/docs/usage-as-python-lib.md b/docs/usage-as-python-lib.md
new file mode 100644
index 000000000..4fa8dc04d
--- /dev/null
+++ b/docs/usage-as-python-lib.md
@@ -0,0 +1,174 @@
+# How to use ANTA as a Python Library
+
+ANTA has been built to allow user to embeded its tools in your own application. This section describes how you can leverage ANTA modules to help you create your own NRFU solution.
+
+## Inventory Manager
+
+Inventory class is in charge of creating a list of hosts with their information and an eAPI session ready to be consummed. To do that, it connects to all devices to check reachability and ensure eAPI is running.
+
+```python
+from anta.inventory import AntaInventory
+
+inventory = AntaInventory(
+ inventory_file="inventory.yml",
+ username="username",
+ password="password",
+ enable_password="enable",
+ auto_connect=True,
+ timeout=1,
+)
+```
+
+Then it is easy to get all devices or only active devices with the following method:
+
+```python
+# print the non reachable devices
+for device in inventory.get_inventory(established_only=False):
+ if device.established is False:
+ print(f"Could not connect to device {device.host}")
+
+# run an EOS commands list on the reachable devices from the inventory
+for device in inventory.get_inventory(established_only=True):
+ device.session.runCmds(
+ 1, ["show version", "show ip bgp summary"]
+ )
+```
+
+You can find data model for [anta.inventory.AntaInventory](./api/inventory.md) in the [auto-generated documentation](./api/inventory.models.md).
+
+??? note "How to create your inventory file"
+ Please visit this [dedicated section](./usage-inventory-catalog.md) for how to use inventory and catalog files.
+
+
+## Use tests from ANTA
+
+All the test functions are based on the exact same input and returns a generic structure with different information.
+
+### Test input
+
+Any test input is based on an `InventoryDevice` object and a list of options. Here is an example to check uptime and check it is higher than `minimum` option.
+
+```python
+def verify_uptime(device: InventoryDevice, minimum: int = None) -> TestResult:
+```
+
+In general, [`InventoryDevice`](./api/inventory.models.md) is an object created by `AntaInventory`. But it can be manually generated by following required data model.
+
+Here is an example of a list of `InventoryDevice`
+
+```python
+[
+ {
+ "InventoryDevice(host=IPv4Address('192.168.0.17')",
+ "username='ansible'",
+ "password='ansible'",
+ "session=",
+ "url='https://ansible:ansible@192.168.0.17/command-api'",
+ "established=True",
+ "is_online=True",
+ "hw_model=cEOS-LAB",
+ },
+
+ {
+ "InventoryDevice(host=IPv4Address('192.168.0.2')",
+ "username='ansible'",
+ "password='ansible'",
+ "session=None",
+ "url='https://ansible:ansible@192.168.0.2/command-api'",
+ "established=False"
+ "is_online=False",
+ "tags": ['dc1', 'spine', 'pod01'],
+ "hw_model=unset",
+ }
+]
+```
+
+### Test output
+
+All tests return a TestResult structure with the following elements:
+
+- `result`: Can be `success`, `skipped`, `failure`, `error` and report result of the test
+- `host`: IP address of the tested device
+- `test`: Test name runs on `host`
+- `message`: Optional message returned by the test.
+
+### Test structure
+
+All tests are based on this structure:
+
+```python
+def (device: InventoryDevice, ) -> TestResult:
+ """
+ dosctring desccription
+
+ Args:
+ device (InventoryDevice): InventoryDevice instance containing all devices information.
+
+ Returns:
+ TestResult instance with
+ * result = "unset" if the test has not been executed
+ * result = "skipped" if the `minimum` parameter is missing
+ * result = "success" if uptime is greater than minimun
+ * result = "failure" otherwise.
+ * result = "error" if any exception is caught
+
+ """
+ function_name = inspect.stack()[0][3]
+
+ # Test if options are valid (optional)
+ if not minimum:
+ result.is_skipped("verify_uptime was not run as no minimum were given")
+ return result
+ # Try to connect and execute command on device
+ try:
+ response = device.session.runCmds(1, ["show uptime"], "json")
+ logger.debug(f'query result is: {response}')
+ response_data = response[0]["upTime"]
+ # Check conditions
+ # ...
+
+ # Capture any exception to return failure reason
+ except (jsonrpc.AppError, KeyError, socket.timeout) as e:
+ logger.error(
+ f'exception raised for \
+ {inspect.stack()[0][3]} - {device.host}: {str(e)}')
+ result.is_error(str(e))
+
+ # Return data to caller
+ return result
+```
+
+## Get test function documentation
+
+Open an interactive python shell and run following commands:
+
+```python
+>>> from anta.tests.system import *
+
+>>> help(verify_ntp)
+
+Help on function verify_ntp in module anta.tests.system:
+
+verify_ntp(device: anta.inventory.models.InventoryDevice) -> anta.result_manager.models.TestResult
+ Verifies NTP is synchronised.
+
+ Args:
+ device (InventoryDevice): InventoryDevice instance containing all devices information.
+
+ Returns:
+ TestResult instance with
+ * result = "unset" if the test has not been executed
+ * result = "success" if synchronized with NTP server
+ * result = "failure" otherwise.
+ * result = "error" if any exception is caught
+
+>>> exit()
+```
+
+If you need to expose test description, you can use this workaround:
+
+```python
+from anta.tests.system import *
+
+print(f'{verify_ntp.__doc__.split("\n")[0]}')
+```
diff --git a/docs/usage-check-devices.md b/docs/usage-check-devices.md
new file mode 100644
index 000000000..47b1f6f6f
--- /dev/null
+++ b/docs/usage-check-devices.md
@@ -0,0 +1,89 @@
+# How to use ANTA scripts
+
+ANTA comes with some scripts to leverage network testing immediatly or if you don't want to create your own application. This page describes how to use `check-devices.py` script to run your network testing.
+
+??? note "Create inventory & tests catalog"
+ Please visit this [dedicated section](./usage-inventory-catalog.md) for how to use inventory and catalog files.
+
+## Check devices script
+
+The `check-devices.py` script comes with a number of options you can use for the testing. Some are mandatory where some others are optionals.
+
+### Required options
+
+#### Specify inventory and test catalog
+
+There is no default file for inventory and tests catalog, so you have to provide paths in CLI using following triggers:
+
+```bash
+check-devices.py -i .personal/avd-lab.yml \
+ -c .personal/ceos-catalog.yml
+```
+
+#### Specify username and password
+
+The script needs your credentials to connect to devices and they have to be provided in the CLI directly. So it is easy to execute this script in a CI pipeline by sending secrets using an environment variable.
+
+```bash
+check-devices.py -i .personal/avd-lab.yml \
+ -c .personal/ceos-catalog.yml \
+ --username admin \
+ --password admin123
+```
+
+#### Specify output format
+
+Since this script can be used for human reporting or within a more complete scenario, user is free to select either `table`, `list` or `json` output format.
+
+```bash
+check-devices.py -i .personal/avd-lab.yml \
+ -c .personal/ceos-catalog.yml \
+ --username admin \
+ --password admin123 \
+ --(table|list|json)
+```
+
+This `--table` option provides a nice human readable format where `--list` is more a grepable output and `--json` is more to send output to another script
+
+
+
+### Available options
+
+Then, besides the mandatory keys, some options are available such as:
+
+- Tag (`--tag`): to run tests against a subset of your inventory.
+- Timeout (`--timeout`): if some devices are not close to your tester, it might be useful to increase response delay.
+- Enable Password (`--enable_password`): Allow to configure optional `enable` password required for some tests.
+- Run tests for a specific host (`--hostip`)
+- Run tests for a specific test (`--test`)
+
+Also, when you use `--table` for output, you can get some report summaries:
+
+- Per host overview (`--by-host`): list number of sucessful, skipped, failed tests and list all failed tests.
+
+
+
+- Per test overview (`--by-test`): list number of sucessful, skipped, failed hosts and list all failed hosts.
+
+
+
+- Save JSON format to a file: use the `--save ` option.
+
+```bash
+# Run testing
+check-devices.py -i .personal/avd-lab.yml \
+ -c .personal/ceos-catalog.yml \
+ --username admin \
+ --password admin123 \
+ --(table|list|json)
+
+# Display saved results
+head -n 8 demo.json
+[
+ {
+ "host": "10.73.252.11",
+ "test": "verify_eos_version",
+ "result": "failure",
+ "messages": "[\"device is running version 4.27.2F-26069621.4272F (engineering build) not in expected versions: ['4.25.4M', '4.26.1F']\"]"
+ },
+```
diff --git a/docs/usage-inventory-catalog.md b/docs/usage-inventory-catalog.md
new file mode 100644
index 000000000..bb5228a94
--- /dev/null
+++ b/docs/usage-inventory-catalog.md
@@ -0,0 +1,96 @@
+# Inventory & Catalog definition
+
+This page describes how to create an inventory and a tests catalog.
+
+## Create an inventory file
+
+`check-devices` needs an inventory file to list all devices to tests. This inventory is a YAML file with the folowing keys:
+
+```yaml
+anta_inventory:
+ hosts:
+ - host: 1.1.1.1
+ networks:
+ - network: '1.1.2.0/24'
+ ranges:
+ - start: 1.1.3.10
+ end: 1.1.3.21
+```
+
+In this configuration file, you can use different device definitions:
+
+- __hosts__: is a list of single Arista EOS host to check.
+- __networks__: is a list of networks where check-devices.py will search for active EOS devices.
+- __ranges__: is a range of IP addresses where check-devices.py will search for active EOS devices.
+
+Your inventory file can be based on any of these 3 keys and shall start with `anta_inventory` key.
+
+Besides this standard definition, you can also define some tags to target a subset of devices during your tests exeution. it can be useful to only run test about VXLAN on leaf only and skip underlay devices.
+
+```yaml
+anta_inventory:
+ hosts:
+ - host: 1.1.1.1
+ tags: ['leaf', 'border']
+ networks:
+ - network: '1.1.2.0/24'
+ tags: ['leaf']
+ ranges:
+ - start: 1.1.3.10
+ end: 1.1.3.21
+ tags: ['spines']
+```
+
+Tag definition is a list of string you defined according your own setup. If not defined, a default tag (`default`) is generated during script execution.
+
+## Test Catalog
+
+In addition to your inventory file, you also have to define a catalog of tests to execute against all your devices. This catalogue list all your tests and their parameters.
+
+Its format is a YAML file and keys are tests functions inherited from the python path. Let's take an example below:
+
+All tests are located under `anta.tests` module and are categorised per family (one submodule). So to run test for software version, you can do:
+
+```yaml
+software:
+ - verify_eos_version:
+```
+
+It will load the test `verify_eos_version` located in `anta.tests.software`. But since this function has parameters, we will create a catalog with the following structure:
+
+```yaml
+software:
+ - verify_eos_version:
+ # List of allowed EOS versions.
+ versions:
+ - 4.25.4M
+ - 4.26.1F
+```
+
+To get a list of all available tests and their respective parameters, you can read the [tests section](./api/tests.md) of this website.
+
+The following example gives a very minimal tests catalog you can use in almost any situation
+
+```yaml
+---
+# Load anta.tests.software
+software:
+ # Verifies the device is running one of the allowed EOS version.
+ - verify_eos_version:
+ # List of allowed EOS versions.
+ versions:
+ - 4.25.4M
+ - 4.26.1F
+
+# Load anta.tests.system
+system:
+ # Verifies the device uptime is higher than a value.
+ - verify_uptime:
+ minimum: 1
+
+# Load anta.tests.configuration
+configuration:
+ # Verifies ZeroTouch is disabled.
+ - verify_zerotouch:
+ - verify_running_config_diffs:
+```
diff --git a/docs/usage.md b/docs/usage.md
index 2a64d6fcf..fc26d3296 100644
--- a/docs/usage.md
+++ b/docs/usage.md
@@ -26,22 +26,14 @@ cat inventory/Spine.yml
### How to check devices state
-The python script [check-devices.py](https://github.com/arista-netdevops-community/network-test-automation/blob/master/scripts/check-devices.py) uses the python functions defined in the package [ANTA](api/README.md) to test devices:
-
-- Update the devices [inventory](https://github.com/arista-netdevops-community/network-test-automation/blob/master/examples/inventory.yml)
-- Update the file [tests.yaml](https://github.com/arista-netdevops-community/network-test-automation/blob/master/examples/tests.yaml) to indicate the tests you would like to run. Some tests require an argument. In that case, provide it using the same YAML file
-- Execute the script [check-devices.py](https://github.com/arista-netdevops-community/network-test-automation/blob/master/scripts/check-devices.py)
-- Check the tests result in the output file
-
-```shell
-vi inventory.yml
-vi tests.yaml
-./check-devices.py --help
-./check-devices.py -i inventory.yml -c tests.yaml --table -u username -p password
-```
+!!! info
+ Please visit this [dedicated section](./usage-check-devices.md) for __check-devices.py__ script
### How to collect commands output
+!!! info
+ Please visit this [dedicated section](./usage-inventory-catalog.md) for how to use inventory file.
+
The python script [collect-eos-commands.py](https://github.com/arista-netdevops-community/network-test-automation/blob/master/scripts/collect-eos-commands.py) runs show commands on devices and collects the output:
- Update the devices [inventory](https://github.com/arista-netdevops-community/network-test-automation/blob/master/examples/inventory.yml)
@@ -59,6 +51,9 @@ ls outdir
### How to collect the scheduled show tech-support files
+!!! info
+ Please visit this [dedicated section](./usage-inventory-catalog.md) for how to use inventory file.
+
The python script [collect-sheduled-show-tech.py](https://github.com/arista-netdevops-community/network-test-automation/blob/master/scripts/collect-sheduled-show-tech.py) collects the scheduled show tech-support files:
- Update the devices [inventory](https://github.com/arista-netdevops-community/network-test-automation/blob/master/examples/inventory.yml)
@@ -76,6 +71,9 @@ ls outdir
The python script [clear-counters.py](https://github.com/arista-netdevops-community/network-test-automation/blob/master/scripts/clear-counters.py) clears counters:
+!!! info
+ Please visit this [dedicated section](./usage-inventory-catalog.md) for how to use inventory file.
+
- Update the devices [inventory](https://github.com/arista-netdevops-community/network-test-automation/blob/master/examples/inventory.yml)
- Run the python script [clear-counters.py](https://github.com/arista-netdevops-community/network-test-automation/blob/master/scripts/clear-counters.py)
@@ -89,6 +87,9 @@ vi inventory.yml
The python script [evpn-blacklist-recovery.py](https://github.com/arista-netdevops-community/network-test-automation/blob/master/scripts/evpn-blacklist-recovery.py) clears the MAC addresses which are blacklisted in EVPN:
+!!! info
+ Please visit this [dedicated section](./usage-inventory-catalog.md) for how to use inventory file.
+
- Update the devices [inventory](https://github.com/arista-netdevops-community/network-test-automation/blob/master/examples/inventory.yml)
- Run the python script [evpn-blacklist-recovery.py](https://github.com/arista-netdevops-community/network-test-automation/blob/master/scripts/evpn-blacklist-recovery.py)
@@ -97,58 +98,3 @@ vi inventory.yml
./evpn-blacklist-recovery.py --help
./evpn-blacklist-recovery.py -i inventory.yml -u username
```
-
-## How to use the ANTA package
-
-### How to instantiate the class `Server` of `jsonrpclib` for an EOS device
-
-```python
->>> import ssl
->>> from jsonrpclib import Server
->>> ssl._create_default_https_context = ssl._create_unverified_context
->>> USERNAME = "arista"
->>> PASSWORD = "aristatwfn"
->>> ENABLE_PASSWORD = "aristatwfn"
->>> IP = "192.168.0.12"
->>> URL=f'https://{USERNAME}:{PASSWORD}@{IP}/command-api'
->>> switch = Server(URL)
-```
-
-### How to import and use the inventory
-
-```python
-from anta.inventory import AntaInventory
-
-inventory = AntaInventory(
- inventory_file="inventory.yml",
- username="username",
- password="password",
- enable_password="enable",
- auto_connect=True,
- timeout=1,
-)
-
-# print the non reachable devices
-devices = inventory.get_inventory(established_only=False)
-for device in devices:
- if device.established is False:
- host = str(device.host)
- print(f"Could not connect to device {host}")
-
-# run an EOS commands list on the reachable devices from the inventory
-devices = inventory.get_inventory(established_only=True)
-for device in devices:
- switch = device.session
- switch.runCmds(
- 1, ["show version", "show ip bgp summary"]
- )
-```
-
-### How to import and use the tests functions
-
-```python
->>> from anta.tests.system import *
->>> dir()
->>> help(verify_ntp)
->>> exit()
-```
diff --git a/mkdocs.yml b/mkdocs.yml
index 9ee1af31d..0c8b4f4d1 100644
--- a/mkdocs.yml
+++ b/mkdocs.yml
@@ -70,6 +70,10 @@ plugins:
# minify_js: true
markdown_extensions:
+ - attr_list
+ - pymdownx.emoji:
+ emoji_index: !!python/name:materialx.emoji.twemoji
+ emoji_generator: !!python/name:materialx.emoji.to_svg
- mdx_truly_sane_lists
- smarty
- pymdownx.arithmatex
@@ -105,9 +109,14 @@ docs_dir: docs/
nav:
- Home: README.md
- Getting Started: getting-started.md
- - Requirements and installation: requirements-and-installation.md
- - Usage: usage.md
+ - Installation: requirements-and-installation.md
+ - Usage:
+ - Inventory & Tests catalog: usage-inventory-catalog.md
+ - Check Devices: usage-check-devices.md
+ - ANTA as python lib: usage-as-python-lib.md
+ - Other scripts: usage.md
- Tests Catalog Documentation:
+ - Overview: api/tests.md
- Configuration: api/tests.configuration.md
- Hardware: api/tests.hardware.md
- Interfaces: api/tests.interfaces.md
@@ -127,3 +136,4 @@ nav:
- Generated Inventory data model: api/inventory.models.md
- Result Manager module: api/result_manager.md
- Result Manager models: api/result_manager.models.md
+ - Contributions: contribution.md
diff --git a/report.txt b/report.txt
deleted file mode 100644
index 2d9bd86bc..000000000
--- a/report.txt
+++ /dev/null
@@ -1,198 +0,0 @@
- Summary per host
-┏━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
-┃ Host IP ┃ # of success ┃ # of failure ┃ # of errors ┃ List of failed ortest case ┃
-┡━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩
-│ 192.168.0.10 │ 2 │ 2 │ 1 │ ['verify_eos_version', 'verify_reload_cause', 'verify_agent_logs'] │
-│ 192.168.0.11 │ 3 │ 1 │ 1 │ ['verify_eos_version', 'verify_reload_cause'] │
-│ 192.168.0.12 │ 2 │ 2 │ 1 │ ['verify_eos_version', 'verify_reload_cause', 'verify_agent_logs'] │
-│ 192.168.0.13 │ 3 │ 1 │ 1 │ ['verify_eos_version', 'verify_reload_cause'] │
-│ 192.168.0.14 │ 3 │ 1 │ 1 │ ['verify_eos_version', 'verify_reload_cause'] │
-│ 192.168.0.15 │ 3 │ 1 │ 1 │ ['verify_eos_version', 'verify_reload_cause'] │
-└──────────────┴──────────────┴──────────────┴─────────────┴────────────────────────────────────────────────────────────────────┘
-────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
- Summary per test case
-┏━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
-┃ Test Case ┃ # of success ┃ # of failure ┃ # of errors ┃ List of failed or error nodes ┃
-┡━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩
-│ verify_eos_version │ 0 │ 6 │ 0 │ ['192.168.0.10', '192.168.0.11', '192.168.0.12', '192.168.0.13', '192.168.0.14', '192.168.0.15'] │
-│ verify_uptime │ 6 │ 0 │ 0 │ [] │
-│ verify_reload_cause │ 0 │ 0 │ 6 │ ['192.168.0.10', '192.168.0.11', '192.168.0.12', '192.168.0.13', '192.168.0.14', '192.168.0.15'] │
-│ verify_coredump │ 6 │ 0 │ 0 │ [] │
-│ verify_agent_logs │ 4 │ 2 │ 0 │ ['192.168.0.10', '192.168.0.12'] │
-└─────────────────────┴──────────────┴──────────────┴─────────────┴──────────────────────────────────────────────────────────────────────────────────────────────────┘
-────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
- All tests results
-┏━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
-┃ Device IP ┃ Test Name ┃ Test Status ┃ Message(s) ┃
-┡━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩
-│ 192.168.0.10 │ verify_eos_version │ failure │ device is running version 4.27.3F-26379303.4273F (engineering build) not in expected version │
-│ 192.168.0.10 │ verify_uptime │ success │ │
-│ 192.168.0.10 │ verify_reload_cause │ error │ 'response' │
-│ 192.168.0.10 │ verify_coredump │ success │ │
-│ 192.168.0.10 │ verify_agent_logs │ failure │ device reported some agent crashes: ===> /var/log/agents/ConfigAgent-681 Fri Jul 22 12:29:29 2022 <=== │
-│ │ │ │ ===== Output from /usr/bin/ConfigAgent [] (PID=681) started Jul 22 12:28:50.103186 === │
-│ │ │ │ EntityManager::doBackoff waiting for connection .....ok │
-│ │ │ │ 2022-07-22 12:29:44.118906 1170 Log 0 %SYS-5-CONFIG_E: Enter configuration mode from console by root on vty22 (UnknownIpAddr) │
-│ │ │ │ 2022-07-22 12:29:48.637460 1170 Log 0 %SYS-5-CONFIG_STARTUP: Startup config saved from system:/running-config by root on vty22 (UnknownIpAddr). │
-│ │ │ │ 2022-07-22 12:29:48.861016 1170 Log 0 %SYS-5-CONFIG_I: Configured from console by root on vty22 (UnknownIpAddr) │
-│ │ │ │ CLI Exception: Internal error : Authorization denied for command 'show logging last 7 days threshold warnings': Cannot authorize command for unknown sessionId 121 │
-│ │ │ │ CLI Exception: Traceback (most recent call last): │
-│ │ │ │ CLI Exception: File "/usr/lib/python2.7/site-packages/CliApi.py", line 515, in _execute │
-│ │ │ │ CLI Exception: result = self._runCmd( command, expandAliases ) │
-│ │ │ │ CLI Exception: File "/usr/lib/python2.7/site-packages/CliApi.py", line 489, in _runCmd │
-│ │ │ │ CLI Exception: return self.session_.runTokenizedCmd( expandedTokens, aaa=aaa, fromCapi=True ) │
-│ │ │ │ CLI Exception: File "/usr/lib/python2.7/site-packages/BasicCliSession.py", line 1142, in runTokenizedCmd │
-│ │ │ │ CLI Exception: authz=aaa, acct=aaa ) │
-│ │ │ │ CLI Exception: File "/usr/lib/python2.7/site-packages/BasicCliSession.py", line 196, in wrapper │
-│ │ │ │ CLI Exception: return func( *args, **kwargs ) │
-│ │ │ │ CLI Exception: File "/usr/lib/python2.7/site-packages/BasicCliSession.py", line 923, in _invokeValueFunc │
-│ │ │ │ CLI Exception: self.performAaa( authz, acct, mode, parseResults ) │
-│ │ │ │ CLI Exception: File "/usr/lib/python2.7/site-packages/BasicCliSession.py", line 1044, in performAaa │
-│ │ │ │ CLI Exception: raise CliParser.AuthzDeniedError( cmd, message ) │
-│ │ │ │ CLI Exception: AuthzDeniedError: Authorization denied for command 'show logging last 7 days threshold warnings': Cannot authorize command for unknown sessionId 121 │
-│ │ │ │ CLI Exception: │
-│ │ │ │ ERROR: [Errno 32] Broken pipe │
-│ │ │ │ Traceback (most recent call last): │
-│ │ │ │ File "/usr/lib/python2.7/site-packages/JsonRpcBase.py", line 108, in processRequest │
-│ │ │ │ self._processRequestInternal( request ) │
-│ │ │ │ File "/usr/lib/python2.7/site-packages/JsonRpcBase.py", line 138, in _processRequestInternal │
-│ │ │ │ self._processRequestNonStreaming( procedure, params ) │
-│ │ │ │ File "/usr/lib/python2.7/site-packages/JsonRpcBase.py", line 174, in _processRequestNonStreaming │
-│ │ │ │ os.write( self.outputFd_, i ) │
-│ │ │ │ OSError: [Errno 32] Broken pipe │
-│ │ │ │ CLI Exception: Internal error : Authorization denied for command 'show processes top once': Cannot authorize command for unknown sessionId 131 │
-│ │ │ │ CLI Exception: Traceback (most recent call last): │
-│ │ │ │ CLI Exception: File "/usr/lib/python2.7/site-packages/CliApi.py", line 515, in _execute │
-│ │ │ │ CLI Exception: result = self._runCmd( command, expandAliases ) │
-│ │ │ │ CLI Exception: File "/usr/lib/python2.7/site-packages/CliApi.py", line 489, in _runCmd │
-│ │ │ │ CLI Exception: return self.session_.runTokenizedCmd( expandedTokens, aaa=aaa, fromCapi=True ) │
-│ │ │ │ CLI Exception: File "/usr/lib/python2.7/site-packages/BasicCliSession.py", line 1142, in runTokenizedCmd │
-│ │ │ │ CLI Exception: authz=aaa, acct=aaa ) │
-│ │ │ │ CLI Exception: File "/usr/lib/python2.7/site-packages/BasicCliSession.py", line 196, in wrapper │
-│ │ │ │ CLI Exception: return func( *args, **kwargs ) │
-│ │ │ │ CLI Exception: File "/usr/lib/python2.7/site-packages/BasicCliSession.py", line 923, in _invokeValueFunc │
-│ │ │ │ CLI Exception: self.performAaa( authz, acct, mode, parseResults ) │
-│ │ │ │ CLI Exception: File "/usr/lib/python2.7/site-packages/BasicCliSession.py", line 1044, in performAaa │
-│ │ │ │ CLI Exception: raise CliParser.AuthzDeniedError( cmd, message ) │
-│ │ │ │ CLI Exception: AuthzDeniedError: Authorization denied for command 'show processes top once': Cannot authorize command for unknown sessionId 131 │
-│ │ │ │ CLI Exception: │
-│ │ │ │ ERROR: [Errno 32] Broken pipe │
-│ │ │ │ Traceback (most recent call last): │
-│ │ │ │ File "/usr/lib/python2.7/site-packages/JsonRpcBase.py", line 108, in processRequest │
-│ │ │ │ self._processRequestInternal( request ) │
-│ │ │ │ File "/usr/lib/python2.7/site-packages/JsonRpcBase.py", line 138, in _processRequestInternal │
-│ │ │ │ self._processRequestNonStreaming( procedure, params ) │
-│ │ │ │ File "/usr/lib/python2.7/site-packages/JsonRpcBase.py", line 174, in _processRequestNonStreaming │
-│ │ │ │ os.write( self.outputFd_, i ) │
-│ │ │ │ OSError: [Errno 32] Broken pipe │
-│ │ │ │ CLI Exception: Internal error : Authorization denied for command 'show ntp status': Cannot authorize command for unknown sessionId 141 │
-│ │ │ │ CLI Exception: Traceback (most recent call last): │
-│ │ │ │ CLI Exception: File "/usr/lib/python2.7/site-packages/CliApi.py", line 515, in _execute │
-│ │ │ │ CLI Exception: result = self._runCmd( command, expandAliases ) │
-│ │ │ │ CLI Exception: File "/usr/lib/python2.7/site-packages/CliApi.py", line 489, in _runCmd │
-│ │ │ │ CLI Exception: return self.session_.runTokenizedCmd( expandedTokens, aaa=aaa, fromCapi=True ) │
-│ │ │ │ CLI Exception: File "/usr/lib/python2.7/site-packages/BasicCliSession.py", line 1142, in runTokenizedCmd │
-│ │ │ │ CLI Exception: authz=aaa, acct=aaa ) │
-│ │ │ │ CLI Exception: File "/usr/lib/python2.7/site-packages/BasicCliSession.py", line 196, in wrapper │
-│ │ │ │ CLI Exception: return func( *args, **kwargs ) │
-│ │ │ │ CLI Exception: File "/usr/lib/python2.7/site-packages/BasicCliSession.py", line 923, in _invokeValueFunc │
-│ │ │ │ CLI Exception: self.performAaa( authz, acct, mode, parseResults ) │
-│ │ │ │ CLI Exception: File "/usr/lib/python2.7/site-packages/BasicCliSession.py", line 1044, in performAaa │
-│ │ │ │ CLI Exception: raise CliParser.AuthzDeniedError( cmd, message ) │
-│ │ │ │ CLI Exception: AuthzDeniedError: Authorization denied for command 'show ntp status': Cannot authorize command for unknown sessionId 141 │
-│ │ │ │ CLI Exception: │
-│ │ │ │ ERROR: [Errno 32] Broken pipe │
-│ │ │ │ Traceback (most recent call last): │
-│ │ │ │ File "/usr/lib/python2.7/site-packages/JsonRpcBase.py", line 108, in processRequest │
-│ │ │ │ self._processRequestInternal( request ) │
-│ │ │ │ File "/usr/lib/python2.7/site-packages/JsonRpcBase.py", line 138, in _processRequestInternal │
-│ │ │ │ self._processRequestNonStreaming( procedure, params ) │
-│ │ │ │ File "/usr/lib/python2.7/site-packages/JsonRpcBase.py", line 174, in _processRequestNonStreaming │
-│ │ │ │ os.write( self.outputFd_, i ) │
-│ │ │ │ OSError: [Errno 32] Broken pipe │
-│ │ │ │ CLI Exception: Internal error : Authorization denied for command 'show ip route summary': Cannot authorize command for unknown sessionId 156 │
-│ │ │ │ CLI Exception: Traceback (most recent call last): │
-│ │ │ │ CLI Exception: File "/usr/lib/python2.7/site-packages/CliApi.py", line 515, in _execute │
-│ │ │ │ CLI Exception: result = self._runCmd( command, expandAliases ) │
-│ │ │ │ CLI Exception: File "/usr/lib/python2.7/site-packages/CliApi.py", line 489, in _runCmd │
-│ │ │ │ CLI Exception: return self.session_.runTokenizedCmd( expandedTokens, aaa=aaa, fromCapi=True ) │
-│ │ │ │ CLI Exception: File "/usr/lib/python2.7/site-packages/BasicCliSession.py", line 1142, in runTokenizedCmd │
-│ │ │ │ CLI Exception: authz=aaa, acct=aaa ) │
-│ │ │ │ CLI Exception: File "/usr/lib/python2.7/site-packages/BasicCliSession.py", line 196, in wrapper │
-│ │ │ │ CLI Exception: return func( *args, **kwargs ) │
-│ │ │ │ CLI Exception: File "/usr/lib/python2.7/site-packages/BasicCliSession.py", line 923, in _invokeValueFunc │
-│ │ │ │ CLI Exception: self.performAaa( authz, acct, mode, parseResults ) │
-│ │ │ │ CLI Exception: File "/usr/lib/python2.7/site-packages/BasicCliSession.py", line 1044, in performAaa │
-│ │ │ │ CLI Exception: raise CliParser.AuthzDeniedError( cmd, message ) │
-│ │ │ │ CLI Exception: AuthzDeniedError: Authorization denied for command 'show ip route summary': Cannot authorize command for unknown sessionId 156 │
-│ │ │ │ CLI Exception: │
-│ │ │ │ ERROR: [Errno 32] Broken pipe │
-│ │ │ │ Traceback (most recent call last): │
-│ │ │ │ File "/usr/lib/python2.7/site-packages/JsonRpcBase.py", line 108, in processRequest │
-│ │ │ │ self._processRequestInternal( request ) │
-│ │ │ │ File "/usr/lib/python2.7/site-packages/JsonRpcBase.py", line 138, in _processRequestInternal │
-│ │ │ │ self._processRequestNonStreaming( procedure, params ) │
-│ │ │ │ File "/usr/lib/python2.7/site-packages/JsonRpcBase.py", line 174, in _processRequestNonStreaming │
-│ │ │ │ os.write( self.outputFd_, i ) │
-│ │ │ │ OSError: [Errno 32] Broken pipe │
-│ │ │ │ │
-│ │ │ │ │
-│ 192.168.0.11 │ verify_eos_version │ failure │ device is running version 4.27.3F-26379303.4273F (engineering build) not in expected version │
-│ 192.168.0.11 │ verify_uptime │ success │ │
-│ 192.168.0.11 │ verify_reload_cause │ error │ 'response' │
-│ 192.168.0.11 │ verify_coredump │ success │ │
-│ 192.168.0.11 │ verify_agent_logs │ success │ │
-│ 192.168.0.12 │ verify_eos_version │ failure │ device is running version 4.27.3F-26379303.4273F (engineering build) not in expected version │
-│ 192.168.0.12 │ verify_uptime │ success │ │
-│ 192.168.0.12 │ verify_reload_cause │ error │ 'response' │
-│ 192.168.0.12 │ verify_coredump │ success │ │
-│ 192.168.0.12 │ verify_agent_logs │ failure │ device reported some agent crashes: ===> /var/log/agents/ConfigAgent-682 Fri Jul 22 12:29:39 2022 <=== │
-│ │ │ │ ===== Output from /usr/bin/ConfigAgent [] (PID=682) started Jul 22 12:28:53.051363 === │
-│ │ │ │ EntityManager::doBackoff waiting for connection .......ok │
-│ │ │ │ 2022-07-22 12:29:48.920598 1161 Log 0 %SYS-5-CONFIG_E: Enter configuration mode from console by root on vty20 (UnknownIpAddr) │
-│ │ │ │ 2022-07-22 12:29:52.078253 1161 Log 0 %SYS-5-CONFIG_STARTUP: Startup config saved from system:/running-config by root on vty20 (UnknownIpAddr). │
-│ │ │ │ 2022-07-22 12:29:52.302700 1161 Log 0 %SYS-5-CONFIG_I: Configured from console by root on vty20 (UnknownIpAddr) │
-│ │ │ │ CLI Exception: Internal error : Authorization denied for command 'show version': Cannot authorize command for unknown sessionId 4 │
-│ │ │ │ CLI Exception: Traceback (most recent call last): │
-│ │ │ │ CLI Exception: File "/usr/lib/python2.7/site-packages/CliApi.py", line 515, in _execute │
-│ │ │ │ CLI Exception: result = self._runCmd( command, expandAliases ) │
-│ │ │ │ CLI Exception: File "/usr/lib/python2.7/site-packages/CliApi.py", line 489, in _runCmd │
-│ │ │ │ CLI Exception: return self.session_.runTokenizedCmd( expandedTokens, aaa=aaa, fromCapi=True ) │
-│ │ │ │ CLI Exception: File "/usr/lib/python2.7/site-packages/BasicCliSession.py", line 1142, in runTokenizedCmd │
-│ │ │ │ CLI Exception: authz=aaa, acct=aaa ) │
-│ │ │ │ CLI Exception: File "/usr/lib/python2.7/site-packages/BasicCliSession.py", line 196, in wrapper │
-│ │ │ │ CLI Exception: return func( *args, **kwargs ) │
-│ │ │ │ CLI Exception: File "/usr/lib/python2.7/site-packages/BasicCliSession.py", line 923, in _invokeValueFunc │
-│ │ │ │ CLI Exception: self.performAaa( authz, acct, mode, parseResults ) │
-│ │ │ │ CLI Exception: File "/usr/lib/python2.7/site-packages/BasicCliSession.py", line 1044, in performAaa │
-│ │ │ │ CLI Exception: raise CliParser.AuthzDeniedError( cmd, message ) │
-│ │ │ │ CLI Exception: AuthzDeniedError: Authorization denied for command 'show version': Cannot authorize command for unknown sessionId 4 │
-│ │ │ │ CLI Exception: │
-│ │ │ │ ERROR: [Errno 32] Broken pipe │
-│ │ │ │ Traceback (most recent call last): │
-│ │ │ │ File "/usr/lib/python2.7/site-packages/JsonRpcBase.py", line 108, in processRequest │
-│ │ │ │ self._processRequestInternal( request ) │
-│ │ │ │ File "/usr/lib/python2.7/site-packages/JsonRpcBase.py", line 138, in _processRequestInternal │
-│ │ │ │ self._processRequestNonStreaming( procedure, params ) │
-│ │ │ │ File "/usr/lib/python2.7/site-packages/JsonRpcBase.py", line 174, in _processRequestNonStreaming │
-│ │ │ │ os.write( self.outputFd_, i ) │
-│ │ │ │ OSError: [Errno 32] Broken pipe │
-│ │ │ │ │
-│ │ │ │ │
-│ 192.168.0.13 │ verify_eos_version │ failure │ device is running version 4.27.3F-26379303.4273F (engineering build) not in expected version │
-│ 192.168.0.13 │ verify_uptime │ success │ │
-│ 192.168.0.13 │ verify_reload_cause │ error │ 'response' │
-│ 192.168.0.13 │ verify_coredump │ success │ │
-│ 192.168.0.13 │ verify_agent_logs │ success │ │
-│ 192.168.0.14 │ verify_eos_version │ failure │ device is running version 4.27.3F-26379303.4273F (engineering build) not in expected version │
-│ 192.168.0.14 │ verify_uptime │ success │ │
-│ 192.168.0.14 │ verify_reload_cause │ error │ 'response' │
-│ 192.168.0.14 │ verify_coredump │ success │ │
-│ 192.168.0.14 │ verify_agent_logs │ success │ │
-│ 192.168.0.15 │ verify_eos_version │ failure │ device is running version 4.27.3F-26379303.4273F (engineering build) not in expected version │
-│ 192.168.0.15 │ verify_uptime │ success │ │
-│ 192.168.0.15 │ verify_reload_cause │ error │ 'response' │
-│ 192.168.0.15 │ verify_coredump │ success │ │
-│ 192.168.0.15 │ verify_agent_logs │ success │ │
-└──────────────┴─────────────────────┴─────────────┴──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
-────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────