From 6c48a88f59538457d8e209ddfd1c223c03f1100e Mon Sep 17 00:00:00 2001
From: "github-actions[bot]" Tip If you are unfamiliar with asyncio, refer to the Python documentation relevant to your Python version - https://docs.python.org/3/library/asyncio.html A device is represented in ANTA as a instance of a subclass of the AntaDevice abstract class.
+ A device is represented in ANTA as a instance of a subclass of the AntaDevice abstract class.
There are few abstract methods that needs to be implemented by child classes: The copy() coroutine is used to copy files to and from the device. It does not need to be implemented if tests are not using it. The AsyncEOSDevice class is an implementation of AntaDevice for Arista EOS.
It uses the aio-eapi eAPI client and the AsyncSSH library. The AntaInventory class is a subclass of the standard Python type dict. The keys of this dictionary are the device names, the values are AntaDevice instances. AntaInventory provides methods to interact with the ANTA inventory:ANTA as a Python Library
AntaDevice Abstract Class¶
-AntaDevice Abstract Class¶
+
AsyncEOSDevice Class¶
+AsyncEOSDevice Class¶
-
-is_online
attribute accordingly. If the TCP connection succeeds, it sends a show version
command to gather the hardware model of the device and updates the established
and hw_model
attributes.AntaInventory Class¶
+AntaInventory Class¶
-
(res)
pprint
All the test classes inherit from the same abstract Base Class AntaTest. The Class definition indicates which commands are required for the test and the user should focus only on writing the test
function with optional keywords argument. The instance of the class upon creation instantiates a TestResult object that can be accessed later on to check the status of the test ([unset, skipped, success, failure, error]).
All tests are built on a class named AntaTest
which provides a complete toolset for a test:
To make it easier to get data, ANTA defines 2 different classes to manage commands to send to devices:
-Represent a command with following information:
Because some command can require more dynamic than just a command with no parameter provided by user, ANTA supports command template: you define a template in your test class and user provide parameters when creating test object.
class RunArbitraryTemplateCommand(AntaTest):
"""
@@ -2636,7 +2636,7 @@
- April 10, 2024
+ September 11, 2024
diff --git a/main/advanced_usages/caching/index.html b/main/advanced_usages/caching/index.html
index 618c6c896..4a1c0d164 100644
--- a/main/advanced_usages/caching/index.html
+++ b/main/advanced_usages/caching/index.html
@@ -1083,7 +1083,7 @@
-
-
+
@@ -2236,7 +2236,7 @@
Caching in ANTA
-->
ANTA is a streamlined Python framework designed for efficient interaction with network devices. This section outlines how ANTA incorporates caching mechanisms to collect command outputs from network devices.
-Configuration¶
+Configuration¶
By default, ANTA utilizes aiocache’s memory cache backend, also called SimpleMemoryCache
. This library aims for simplicity and supports asynchronous operations to go along with Python asyncio
used in ANTA.
The _init_cache()
method of the AntaDevice abstract class initializes the cache. Child classes can override this method to tweak the cache configuration:
def _init_cache(self) -> None:
@@ -2247,14 +2247,14 @@ Configurationself.cache_locks = defaultdict(asyncio.Lock)
The cache is also configured with aiocache
’s HitMissRatioPlugin
plugin to calculate the ratio of hits the cache has and give useful statistics for logging purposes in ANTA.
-Cache key design¶
+Cache key design¶
The cache is initialized per AntaDevice
and uses the following cache key design:
<device_name>:<uid>
The uid
is an attribute of AntaCommand, which is a unique identifier generated from the command, version, revision and output format.
Each UID has its own asyncio lock. This design allows coroutines that need to access the cache for different UIDs to do so concurrently. The locks are managed by the self.cache_locks
dictionary.
-Mechanisms¶
+Mechanisms¶
By default, once the cache is initialized, it is used in the collect()
method of AntaDevice
. The collect()
method prioritizes retrieving the output of the command from the cache. If the output is not in the cache, the private _collect()
method will retrieve and then store it for future access.
-How to disable caching¶
+How to disable caching¶
Caching is enabled by default in ANTA following the previous configuration and mechanisms.
There might be scenarios where caching is not wanted. You can disable caching in multiple ways in ANTA:
@@ -2262,7 +2262,7 @@ How to disable cachinganta --disable-cache --username arista --password arista nrfu table
Caching can be disabled per device, network or range by setting the disable_cache
key to True
when defining the ANTA Inventory file:
+
Caching can be disabled per device, network or range by setting the disable_cache
key to True
when defining the ANTA Inventory file:
anta_inventory:
hosts:
- host: 172.20.20.101
@@ -2289,7 +2289,7 @@ How to disable cachingFor tests developers, caching can be disabled for a specific AntaCommand
or AntaTemplate
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
¶
+Disable caching in a child class of AntaDevice
¶
Since caching is implemented at the AntaDevice
abstract class level, all subclasses will inherit that default behavior. As a result, if you need to disable caching in any custom implementation of AntaDevice
outside of the ANTA framework, you must initialize AntaDevice
with disable_cache
set to True
:
class AnsibleEOSDevice(AntaDevice):
"""
@@ -2318,7 +2318,7 @@ Disable caching in a chi
April 3, 2024
+ September 11, 2024
diff --git a/main/advanced_usages/custom-tests/index.html b/main/advanced_usages/custom-tests/index.html
index 35532211b..bb72459b9 100644
--- a/main/advanced_usages/custom-tests/index.html
+++ b/main/advanced_usages/custom-tests/index.html
@@ -1247,7 +1247,7 @@
- -
-
+
@@ -2567,7 +2567,7 @@
Developing ANTA tests
This documentation applies for both creating tests in ANTA or creating your own test package.
ANTA is not only a Python library with a CLI and a collection of built-in tests, it is also a framework you can extend by building your own tests.
-Generic approach¶
+Generic approach¶
A test is a Python class where a test function is defined and will be run by the framework.
ANTA provides an abstract class AntaTest. This class does the heavy lifting and provide the logic to define, collect and test data. The code below is an example of a simple test in ANTA, which is an AntaTest subclass:
from anta.models import AntaTest, AntaCommand
@@ -2607,9 +2607,9 @@ Generic approachself.result.is_failure(f"Device temperature exceeds acceptable limits. Current system status: '{temperature_status}'")
AntaTest also provide more advanced capabilities like AntaCommand templating using the AntaTemplate class or test inputs definition and validation using AntaTest.Input pydantic model. This will be discussed in the sections below.
-AntaTest structure¶
+AntaTest structure¶
Full AntaTest API documentation is available in the API documentation section
-Class Attributes¶
+Class Attributes¶
name
(str
): Name of the test. Used during reporting.
description
(str
): A human readable description of your test.
@@ -2620,14 +2620,12 @@ Class AttributesInfo
All these class attributes are mandatory. If any attribute is missing, a NotImplementedError
exception will be raised during class instantiation.
Info
You can access an instance attribute in your code using the self
reference. E.g. you can access the test input values using self.inputs
.
device
AntaDevice instance on which this test is run
+ AntaDevice
+ AntaDevice instance on which this test is run.
+inputs
Input
+ AntaTest.Input instance carrying the test inputs.
+instance_commands
list[AntaCommand]
+ List of AntaCommand instances of this test.
+result
TestResult
+ TestResult instance representing the result of this test.
+logger
Logger
inputs: AntaTest.Input instance carrying the test inputs -instance_commands: List of AntaCommand instances of this test -result: TestResult instance representing the result of this test -logger: Python logger for this test instance
+Python logger for this test instance.
Even if device
is not a private attribute, you should not need to access this object in your code.
AntaTest.Input is a pydantic model that allow test developers to define their test inputs. pydantic provides out of the box error handling for test input validation based on the type hints defined by the test developer.
The base definition of AntaTest.Input provides common test inputs for all AntaTest instances:
-Full Input
model documentation is available in API documentation section
result_overwrite
Define fields to overwrite in the TestResult object
+ ResultOverwrite | None
Define fields to overwrite in the TestResult object.
Full ResultOverwrite
model documentation is available in API documentation section
description
overwrite TestResult.description
+ str | None
+ Overwrite TestResult.description
.
categories
list[str] | None
+ Overwrite TestResult.categories
.
custom_field
str | None
categories: overwrite TestResult.categories -custom_field: a free string that will be included in the TestResult object
+A free string that will be included in the TestResult object.
The pydantic model is configured using the extra=forbid
that will fail input validation if extra fields are provided.
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.commands
class attribute. It will be called for every AntaTemplate occurrence and must return a list of AntaCommand using the AntaTemplate.render() method. It can access test inputs using the inputs
instance attribute.Below is a high level description of the test execution flow in ANTA:
In this section, we will go into all the details of writing an AntaTest subclass.
-Import anta.models.AntaTest and define your own class. Define the mandatory class attributes using anta.models.AntaCommand, anta.models.AntaTemplate or both.
If the user needs to provide inputs for your test, you need to define a pydantic model that defines the schema of the test inputs:
class <YourTestName>(AntaTest):
"""Verifies ...
@@ -2917,7 +2974,7 @@ Inputs definitionNote
All the pydantic
features are supported. For instance you can define validators for complex input validation.
Define the render()
method if you have AntaTemplate instances in your commands
class attribute:
class <YourTestName>(AntaTest):
...
@@ -2925,7 +2982,7 @@ Template renderingreturn [template.render(<template param>=input_value) for input_value in self.inputs.<input_field>]
You can access test inputs and render as many AntaCommand as desired.
-Implement the test()
method with your test logic:
class <YourTestName>(AntaTest):
...
@@ -2971,7 +3028,7 @@ Test definition$ ANTA_DEBUG=true anta nrfu --catalog test_custom.yml text
In addition to the required AntaTest.anta_tests
decorator, ANTA offers a set of optional decorators for further test customization:
anta.decorators.deprecated_test
: Use this to log a message of WARNING severity when a test is deprecated.This section is required only if you are not merging your development into ANTA. Otherwise, just follow contribution guide.
Class representing an ANTA Catalog.
It can be instantiated using its constructor or one of the static methods: parse()
, from_list()
or from_dict()
Parameters:
+Name | +Type | +Description | +Default | +
---|---|---|---|
tests |
+
+ list[AntaTestDefinition] | None
+ |
+
+
+
+ A list of AntaTestDefinition instances. + |
+
+ None
+ |
+
filename |
+
+ str | Path | None
+ |
+
+
+
+ The path from which the catalog is loaded. + |
+
+ None
+ |
+
anta/catalog.py
261 -262 -263 -264 -265 -266 -267 -268 + |