From e0c39d05cb265515c69b49d419a48177d54196e8 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Mon, 7 Oct 2024 19:19:43 +0000 Subject: [PATCH] Deployed 29e08cbb to main with MkDocs 1.6.1 and mike 2.1.3 --- main/404.html | 16 +- main/advanced_usages/as-python-lib/index.html | 268 +--- main/advanced_usages/caching/index.html | 38 +- main/advanced_usages/custom-tests/index.html | 48 +- main/api/catalog/index.html | 670 +++++---- main/api/device/index.html | 480 ++++--- main/api/inventory.models.input/index.html | 16 +- main/api/inventory/index.html | 48 +- main/api/models/index.html | 188 ++- main/api/report_manager/index.html | 24 +- main/api/result_manager/index.html | 156 +- main/api/result_manager_models/index.html | 40 +- main/api/runner/index.html | 128 +- main/api/tests.aaa/index.html | 16 +- main/api/tests.avt/index.html | 16 +- main/api/tests.bfd/index.html | 16 +- main/api/tests.configuration/index.html | 16 +- main/api/tests.connectivity/index.html | 16 +- main/api/tests.field_notices/index.html | 18 +- main/api/tests.flow_tracking/index.html | 16 +- main/api/tests.greent/index.html | 16 +- main/api/tests.hardware/index.html | 16 +- main/api/tests.interfaces/index.html | 20 +- main/api/tests.lanz/index.html | 16 +- main/api/tests.logging/index.html | 26 +- main/api/tests.mlag/index.html | 56 +- main/api/tests.multicast/index.html | 16 +- main/api/tests.path_selection/index.html | 16 +- main/api/tests.profiles/index.html | 16 +- main/api/tests.ptp/index.html | 16 +- main/api/tests.routing.bgp/index.html | 1271 ++++++++++++++--- main/api/tests.routing.generic/index.html | 104 +- main/api/tests.routing.isis/index.html | 66 +- main/api/tests.routing.ospf/index.html | 16 +- main/api/tests.security/index.html | 328 ++--- main/api/tests.services/index.html | 16 +- main/api/tests.snmp/index.html | 16 +- main/api/tests.software/index.html | 16 +- main/api/tests.stp/index.html | 285 +++- main/api/tests.stun/index.html | 16 +- main/api/tests.system/index.html | 94 +- main/api/tests.vlan/index.html | 16 +- main/api/tests.vxlan/index.html | 16 +- main/api/tests/index.html | 75 +- main/api/types/index.html | 18 +- .../assets/javascripts/bundle.525ec568.min.js | 16 + ....min.js.map => bundle.525ec568.min.js.map} | 8 +- .../assets/javascripts/bundle.56dfad97.min.js | 16 - ...07f07601.min.js => search.6ce7567c.min.js} | 6 +- ....min.js.map => search.6ce7567c.min.js.map} | 4 +- main/assets/stylesheets/main.35f28582.min.css | 1 - .../stylesheets/main.35f28582.min.css.map | 1 - main/assets/stylesheets/main.8c3ca2c6.min.css | 1 + .../stylesheets/main.8c3ca2c6.min.css.map | 1 + main/cli/check/index.html | 69 +- main/cli/debug/index.html | 81 +- main/cli/exec/index.html | 105 +- main/cli/get-inventory-information/index.html | 87 +- main/cli/inv-from-ansible/index.html | 83 +- main/cli/inv-from-cvp/index.html | 79 +- main/cli/nrfu/index.html | 193 +-- main/cli/overview/index.html | 99 +- main/cli/tag-management/index.html | 418 ++++-- main/contribution/index.html | 189 +-- main/faq/index.html | 20 +- main/getting-started/index.html | 109 +- main/index.html | 25 +- main/objects.inv | Bin 3485 -> 3536 bytes main/requirements-and-installation/index.html | 87 +- main/scripts/generate_svg.py | 3 +- main/search/search_index.json | 2 +- main/sitemap.xml.gz | Bin 127 -> 127 bytes main/troubleshooting/index.html | 81 +- main/usage-inventory-catalog/index.html | 95 +- 74 files changed, 3741 insertions(+), 2939 deletions(-) create mode 100644 main/assets/javascripts/bundle.525ec568.min.js rename main/assets/javascripts/{bundle.56dfad97.min.js.map => bundle.525ec568.min.js.map} (71%) delete mode 100644 main/assets/javascripts/bundle.56dfad97.min.js rename main/assets/javascripts/workers/{search.07f07601.min.js => search.6ce7567c.min.js} (94%) rename main/assets/javascripts/workers/{search.07f07601.min.js.map => search.6ce7567c.min.js.map} (78%) delete mode 100644 main/assets/stylesheets/main.35f28582.min.css delete mode 100644 main/assets/stylesheets/main.35f28582.min.css.map create mode 100644 main/assets/stylesheets/main.8c3ca2c6.min.css create mode 100644 main/assets/stylesheets/main.8c3ca2c6.min.css.map diff --git a/main/404.html b/main/404.html index 89b6e0c193..bc0f3cb561 100644 --- a/main/404.html +++ b/main/404.html @@ -16,7 +16,7 @@ - + @@ -24,7 +24,7 @@ - + @@ -339,7 +339,7 @@ - Inventory & Tests catalog + Inventory and Test catalog @@ -540,7 +540,7 @@ - Check + Check commands @@ -561,7 +561,7 @@ - Helpers + Debug commands @@ -1942,7 +1942,7 @@ - Troubleshooting + Troubleshooting ANTA @@ -2103,10 +2103,10 @@

404 - Not found

- + - + diff --git a/main/advanced_usages/as-python-lib/index.html b/main/advanced_usages/as-python-lib/index.html index 13b885cfaa..f70c2ec972 100644 --- a/main/advanced_usages/as-python-lib/index.html +++ b/main/advanced_usages/as-python-lib/index.html @@ -20,7 +20,7 @@ - + @@ -28,7 +28,7 @@ - + @@ -357,7 +357,7 @@ - Inventory & Tests catalog + Inventory and Test catalog @@ -558,7 +558,7 @@ - Check + Check commands @@ -579,7 +579,7 @@ - Helpers + Debug commands @@ -798,23 +798,23 @@
  • - + - Use tests from ANTA + Examples -
  • @@ -2122,7 +2088,7 @@ - Troubleshooting + Troubleshooting ANTA @@ -2241,23 +2207,23 @@
  • - + - Use tests from ANTA + Examples -
  • The parse() static method creates an AntaInventory instance from a YAML file and returns it. The devices are AsyncEOSDevice instances.
  • -

    To parse a YAML inventory file and print the devices connection status:

    +

    Examples

    +

    Parse an ANTA inventory file

    """
    -Example
    +This script parses an ANTA inventory file, connects to devices and print their status.
     """
     import asyncio
     
    @@ -2415,9 +2348,9 @@ 

    dedicated section for how to use inventory and catalog files.

    -

    To run an EOS commands list on the reachable devices from the inventory: +

    Run EOS commands

    """
    -Example
    +This script runs a list of EOS commands on reachable devices.
     """
     # This is needed to run the script for python < 3.10 for typing annotations
     from __future__ import annotations
    @@ -2470,152 +2403,7 @@ 

    res = asyncio.run(main(inventory, commands)) pprint(res) -

    -

    Use tests from ANTA

    -

    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]).

    -

    Test structure

    -

    All tests are built on a class named AntaTest which provides a complete toolset for a test:

    -
      -
    • Object creation
    • -
    • Test definition
    • -
    • TestResult definition
    • -
    • Abstracted method to collect data
    • -
    -

    This approach means each time you create a test it will be based on this AntaTest class. Besides that, you will have to provide some elements:

    -
      -
    • name: Name of the test
    • -
    • description: A human readable description of your test
    • -
    • categories: a list of categories to sort test.
    • -
    • commands: a list of command to run. This list must be a list of AntaCommand which is described in the next part of this document.
    • -
    -

    Here is an example of a hardware test related to device temperature:

    -
    from __future__ import annotations
    -
    -import logging
    -from typing import Any, Dict, List, Optional, cast
    -
    -from anta.models import AntaTest, AntaCommand
    -
    -
    -class VerifyTemperature(AntaTest):
    -    """
    -    Verifies device temparture is currently OK.
    -    """
    -
    -    # The test name
    -    name = "VerifyTemperature"
    -    # A small description of the test, usually the first line of the class docstring
    -    description = "Verifies device temparture is currently OK"
    -    # The category of the test, usually the module name
    -    categories = ["hardware"]
    -    # The command(s) used for the test. Could be a template instead
    -    commands = [AntaCommand(command="show system environment temperature", ofmt="json")]
    -
    -    # Decorator
    -    @AntaTest.anta_test
    -    # abstract method that must be defined by the child Test class
    -    def test(self) -> None:
    -        """Run VerifyTemperature validation"""
    -        command_output = cast(Dict[str, Dict[Any, Any]], self.instance_commands[0].output)
    -        temperature_status = command_output["systemStatus"] if "systemStatus" in command_output.keys() else ""
    -        if temperature_status == "temperatureOk":
    -            self.result.is_success()
    -        else:
    -            self.result.is_failure(f"Device temperature is not OK, systemStatus: {temperature_status }")
    -
    -

    When you run the test, object will automatically call its anta.models.AntaTest.collect() method to get device output for each command if no pre-collected data was given to the test. This method does a loop to call anta.inventory.models.InventoryDevice.collect() methods which is in charge of managing device connection and how to get data.

    -
    -run test offline -

    You can also pass eos data directly to your test if you want to validate data collected in a different workflow. An example is provided below just for information:

    -
    test = VerifyTemperature(device, eos_data=test_data["eos_data"])
    -asyncio.run(test.test())
    -
    -
    -

    The test function is always the same and must be defined with the @AntaTest.anta_test decorator. This function takes at least one argument which is a anta.inventory.models.InventoryDevice object. -In some cases a test would rely on some additional inputs from the user, for instance the number of expected peers or some expected numbers. All parameters must come with a default value and the test function should validate the parameters values (at this stage this is the only place where validation can be done but there are future plans to make this better).

    -
    class VerifyTemperature(AntaTest):
    -    ...
    -    @AntaTest.anta_test
    -    def test(self) -> None:
    -        pass
    -
    -class VerifyTransceiversManufacturers(AntaTest):
    -    ...
    -    @AntaTest.anta_test
    -    def test(self, manufacturers: Optional[List[str]] = None) -> None:
    -        # validate the manufactures parameter
    -        pass
    -
    -

    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.
    • -
    • test (str): Test name runs on the device.
    • -
    • categories (List[str]): List of categories the TestResult belongs to, by default the AntaTest categories.
    • -
    • description (str): TestResult description, by default the AntaTest description.
    • -
    • results (str): Result of the test. Can be one of [“unset”, “success”, “failure”, “error”, “skipped”].
    • -
    • message (str, optional): Message to report after the test if any.
    • -
    • custom_field (str, optional): Custom field to store a string for flexibility in integrating with ANTA
    • -
    -
    from anta.tests.hardware import VerifyTemperature
    -
    -test = VerifyTemperature(device, eos_data=test_data["eos_data"])
    -asyncio.run(test.test())
    -assert test.result.result == "success"
    -
    -

    Classes for commands

    -

    To make it easier to get data, ANTA defines 2 different classes to manage commands to send to devices:

    -
    AntaCommand Class
    -

    Represent a command with following information:

    -
      -
    • Command to run
    • -
    • Output format expected
    • -
    • eAPI version
    • -
    • Output of the command
    • -
    -

    Usage example:

    -
    from anta.models import AntaCommand
    -
    -cmd1 = AntaCommand(command="show zerotouch")
    -cmd2 = AntaCommand(command="show running-config diffs", ofmt="text")
    -
    -
    -

    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 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, integrations with existing tools are not broken. This is done by using by default version=1 in eAPI calls.
    • -
    -

    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 VerifyBFDPeersHealth test leverages the first revision of show bfd peers:

    -
    # revision 1 as later revision introduce additional nesting for type
    -commands = [AntaCommand(command="show bfd peers", revision=1)]
    -
    -
    -
    AntaTemplate Class
    -

    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):
    -    """
    -    Run an EOS command and return result
    -    Based on AntaTest to build relevant output for pytest
    -    """
    -
    -    name = "Run aributrary EOS command"
    -    description = "To be used only with anta debug commands"
    -    template = AntaTemplate(template="show interfaces {ifd}")
    -    categories = ["debug"]
    -
    -    @AntaTest.anta_test
    -    def test(self) -> None:
    -        errdisabled_interfaces = [interface for interface, value in response["interfaceStatuses"].items() if value["linkStatus"] == "errdisabled"]
    -        ...
    -
    -
    -params = [{"ifd": "Ethernet2"}, {"ifd": "Ethernet49/1"}]
    -run_command1 = RunArbitraryTemplateCommand(device_anta, params)
     
    -

    In this example, test waits for interfaces to check from user setup and will only check for interfaces in params

    @@ -2636,7 +2424,7 @@
    - September 11, 2024 + October 2, 2024 @@ -2732,10 +2520,10 @@
    - + - + diff --git a/main/advanced_usages/caching/index.html b/main/advanced_usages/caching/index.html index 4a1c0d1648..2e316d99b6 100644 --- a/main/advanced_usages/caching/index.html +++ b/main/advanced_usages/caching/index.html @@ -20,7 +20,7 @@ - + @@ -28,7 +28,7 @@ - + @@ -357,7 +357,7 @@ - Inventory & Tests catalog + Inventory and Test catalog @@ -558,7 +558,7 @@ - Check + Check commands @@ -579,7 +579,7 @@ - Helpers + Debug commands @@ -2066,7 +2066,7 @@ - Troubleshooting + Troubleshooting ANTA @@ -2238,7 +2238,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

    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:

    +

    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:
         """
         Initialize cache for the device, can be overridden by subclasses to manipulate how it works
    @@ -2250,7 +2250,7 @@ 

    ConfigurationCache 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.

    +

    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

    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.

    @@ -2258,12 +2258,14 @@

    How to disable cachingCaching 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:

      -
    1. Caching can be disabled globally, for ALL commands on ALL devices, using the --disable-cache global flag when invoking anta at the CLI: -
      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 defining the ANTA Inventory file: -

      anta_inventory:
      +

      Caching can be disabled globally, for ALL commands on ALL devices, using the --disable-cache global flag when invoking anta at the CLI:

      +
      anta --disable-cache --username arista --password arista nrfu table
      +
      +
    3. +
    4. +

      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
           name: DC1-SPINE1
      @@ -2283,10 +2285,10 @@ 

      How to disable caching end: 172.22.22.19 disable_cache: True

      - This approach effectively disables caching for ALL commands sent to devices targeted by the disable_cache key.

      +

      This approach effectively disables caching for ALL commands sent to devices targeted by the disable_cache key.

    5. -

      For 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.

      +

      For 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

    @@ -2318,7 +2320,7 @@

    Disable caching in a chi - September 11, 2024 + October 2, 2024 @@ -2414,10 +2416,10 @@

    Disable caching in a chi

    - + - + diff --git a/main/advanced_usages/custom-tests/index.html b/main/advanced_usages/custom-tests/index.html index bb72459b94..99085152cb 100644 --- a/main/advanced_usages/custom-tests/index.html +++ b/main/advanced_usages/custom-tests/index.html @@ -20,7 +20,7 @@ - + @@ -28,7 +28,7 @@ - + @@ -357,7 +357,7 @@ - Inventory & Tests catalog + Inventory and Test catalog @@ -558,7 +558,7 @@ - Check + Check commands @@ -579,7 +579,7 @@ - Helpers + Debug commands @@ -2230,7 +2230,7 @@ - Troubleshooting + Troubleshooting ANTA @@ -2564,6 +2564,7 @@

    Developing ANTA tests

    -->
    +

    Info

    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.

    @@ -2943,6 +2944,21 @@

    Class definition) ]

    +
    +

    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 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, integrations with existing tools are not broken. This is done by using by default version=1 in eAPI calls.
    • +
    +

    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 VerifyBFDPeersHealth test leverages the first revision of show bfd peers:

    +
    # revision 1 as later revision introduce additional nesting for type
    +commands = [AntaCommand(command="show bfd peers", revision=1)]
    +
    +

    Inputs definition

    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):
    @@ -2990,10 +3006,12 @@ 

    Test definitiondef test(self) -> None: pass

    -

    The logic usually includes the following different stages: -1. Parse the command outputs using the self.instance_commands instance attribute. -2. If needed, access the test inputs using the self.inputs instance attribute and write your conditional logic. -3. Set the result instance attribute to reflect the test result by either calling self.result.is_success() or self.result.is_failure("<FAILURE REASON>"). Sometimes, setting the test result to skipped using self.result.is_skipped("<SKIPPED REASON>") can make sense (e.g. testing the OSPF neighbor states but no neighbor was found). However, you should not need to catch any exception and set the test result to error since the error handling is done by the framework, see below.

    +

    The logic usually includes the following different stages:

    +
      +
    1. Parse the command outputs using the self.instance_commands instance attribute.
    2. +
    3. If needed, access the test inputs using the self.inputs instance attribute and write your conditional logic.
    4. +
    5. Set the result instance attribute to reflect the test result by either calling self.result.is_success() or self.result.is_failure("<FAILURE REASON>"). Sometimes, setting the test result to skipped using self.result.is_skipped("<SKIPPED REASON>") can make sense (e.g. testing the OSPF neighbor states but no neighbor was found). However, you should not need to catch any exception and set the test result to error since the error handling is done by the framework, see below.
    6. +

    The example below is based on the VerifyTemperature test.

    class VerifyTemperature(AntaTest):
         ...
    @@ -3050,11 +3068,11 @@ 

    Access your custom tests i

    For that, you need to create your own Python package as described in this hitchhiker’s guide to package Python code. We assume it is well known and we won’t focus on this aspect. Thus, your package must be impartable by ANTA hence available in the module search path sys.path (you can use PYTHONPATH for example).

    It is very similar to what is documented in catalog section but you have to use your own package name.2

    Let say the custom Python package is anta_custom and the test is defined in anta_custom.dc_project Python module, the test catalog would look like:

    -

    anta_custom.dc_project:
    +
    anta_custom.dc_project:
       - VerifyFeatureX:
           minimum: 1
     
    -And now you can run your NRFU tests with the CLI:

    +

    And now you can run your NRFU tests with the CLI:

    anta nrfu text --catalog test_custom.yml
     spine01 :: verify_dynamic_vlan :: FAILURE (Device has 0 configured, we expect at least 1)
     spine02 :: verify_dynamic_vlan :: FAILURE (Device has 0 configured, we expect at least 1)
    @@ -3083,7 +3101,7 @@ 

    Access your custom tests i - June 11, 2024 + October 2, 2024 @@ -3179,10 +3197,10 @@

    Access your custom tests i

    - + - + diff --git a/main/api/catalog/index.html b/main/api/catalog/index.html index 0e852e6891..feb1a2f7e8 100644 --- a/main/api/catalog/index.html +++ b/main/api/catalog/index.html @@ -20,7 +20,7 @@ - + @@ -28,7 +28,7 @@ - + @@ -357,7 +357,7 @@ - Inventory & Tests catalog + Inventory and Test catalog @@ -558,7 +558,7 @@ - Check + Check commands @@ -579,7 +579,7 @@ - Helpers + Debug commands @@ -1803,6 +1803,20 @@ + +
  • + + + clear_indexes + + + + + +
  • + + +
  • @@ -2290,7 +2304,7 @@ - Troubleshooting + Troubleshooting ANTA @@ -2419,6 +2433,20 @@ + +
  • + + + clear_indexes + + + + + +
  • + + +
  • @@ -2749,13 +2777,7 @@

    Source code in anta/catalog.py -
    268
    -269
    -270
    -271
    -272
    -273
    -274
    +                    
    274
     275
     276
     277
    @@ -2778,7 +2800,12 @@ 

    294 295 296 -297

    def __init__(
    +297
    +298
    +299
    +300
    +301
    +302
    def __init__(
         self,
         tests: list[AntaTestDefinition] | None = None,
         filename: str | Path | None = None,
    @@ -2803,11 +2830,10 @@ 

    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 + self.indexes_built: bool + self.tag_to_tests: defaultdict[str | None, set[AntaTestDefinition]] + self._tests_without_tags: set[AntaTestDefinition] + self._init_indexes()

    @@ -2892,40 +2918,40 @@

    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.

    +

    _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.

    Source code in anta/catalog.py -
    460
    -461
    -462
    -463
    -464
    -465
    -466
    -467
    -468
    -469
    -470
    -471
    -472
    -473
    -474
    -475
    -476
    -477
    -478
    -479
    -480
    -481
    -482
    -483
    -484
    +              
    484
     485
    -486
    def build_indexes(self, filtered_tests: set[str] | None = None) -> None:
    +486
    +487
    +488
    +489
    +490
    +491
    +492
    +493
    +494
    +495
    +496
    +497
    +498
    +499
    +500
    +501
    +502
    +503
    +504
    +505
    +506
    +507
    +508
    +509
    +510
    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.
    @@ -2934,7 +2960,7 @@ 

    - 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. + - _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. """ @@ -2948,9 +2974,9 @@

    for tag in test_tags: self.tag_to_tests[tag].add(test) else: - self.tests_without_tags.add(test) + self._tests_without_tags.add(test) - self.tag_to_tests[None] = self.tests_without_tags + self.tag_to_tests[None] = self._tests_without_tags self.indexes_built = True

    @@ -2961,6 +2987,34 @@

    +

    + clear_indexes + + +

    +
    clear_indexes() -> None
    +
    + +
    + +

    Clear this AntaCatalog instance indexes.

    + +
    + Source code in anta/catalog.py +
    512
    +513
    +514
    def clear_indexes(self) -> None:
    +    """Clear this AntaCatalog instance indexes."""
    +    self._init_indexes()
    +
    +
    +
    + +
    + +
    + +

    dump @@ -2998,19 +3052,19 @@

    Source code in anta/catalog.py -
    446
    -447
    -448
    -449
    -450
    -451
    -452
    -453
    -454
    -455
    -456
    -457
    -458
    def dump(self) -> AntaCatalogFile:
    +              
    + + + + + + + +
    470
    +471
    +472
    +473
    +474
    +475
    +476
    +477
    +478
    +479
    +480
    +481
    +482
    def dump(self) -> AntaCatalogFile:
         """Return an AntaCatalogFile instance from this AntaCatalog instance.
     
         Returns
    @@ -3070,35 +3124,56 @@ 

    -

    Python dictionary used to instantiate the AntaCatalog instance. -filename: value to be set as AntaCatalog instance attribute

    +

    Python dictionary used to instantiate the AntaCatalog instance.

    required
    filename + str | Path | None + +
    +

    value to be set as AntaCatalog instance attribute

    +
    +
    + None +
    + + +

    Returns:

    + + + + + + + + + + + +
    TypeDescription
    + AntaCatalog + +
    +

    An AntaCatalog populated with the ‘data’ dictionary content.

    +
    +
    Source code in anta/catalog.py -
    347
    -348
    -349
    -350
    -351
    -352
    -353
    -354
    -355
    -356
    -357
    -358
    -359
    -360
    -361
    -362
    +              
    362
     363
     364
     365
    @@ -3118,7 +3193,27 @@ 

    379 380 381 -382

    @staticmethod
    +382
    +383
    +384
    +385
    +386
    +387
    +388
    +389
    +390
    +391
    +392
    +393
    +394
    +395
    +396
    +397
    +398
    +399
    +400
    +401
    +402
    @staticmethod
     def from_dict(data: RawCatalogInput, filename: str | Path | None = None) -> AntaCatalog:
         """Create an AntaCatalog instance from a dictionary data structure.
     
    @@ -3130,8 +3225,13 @@ 

    ---------- data Python dictionary used to instantiate the AntaCatalog instance. - filename: value to be set as AntaCatalog instance attribute + filename + value to be set as AntaCatalog instance attribute + Returns + ------- + AntaCatalog + An AntaCatalog populated with the 'data' dictionary content. """ tests: list[AntaTestDefinition] = [] if data is None: @@ -3209,27 +3309,54 @@

    + +

    Returns:

    + + + + + + + + + + + + + +
    TypeDescription
    + AntaCatalog + +
    +

    An AntaCatalog populated with the ‘data’ list content.

    +
    +
    +
    Source code in anta/catalog.py -
    384
    -385
    -386
    -387
    -388
    -389
    -390
    -391
    -392
    -393
    -394
    -395
    -396
    -397
    -398
    -399
    -400
    -401
    -402
    @staticmethod
    +              
    404
    +405
    +406
    +407
    +408
    +409
    +410
    +411
    +412
    +413
    +414
    +415
    +416
    +417
    +418
    +419
    +420
    +421
    +422
    +423
    +424
    +425
    +426
    @staticmethod
     def from_list(data: ListAntaTestTuples) -> AntaCatalog:
         """Create an AntaCatalog instance from a list data structure.
     
    @@ -3240,6 +3367,10 @@ 

    data Python list used to instantiate the AntaCatalog instance. + Returns + ------- + AntaCatalog + An AntaCatalog populated with the 'data' list content. """ tests: list[AntaTestDefinition] = [] try: @@ -3361,40 +3492,40 @@

    Source code in anta/catalog.py -
    488
    -489
    -490
    -491
    -492
    -493
    -494
    -495
    -496
    -497
    -498
    -499
    -500
    -501
    -502
    -503
    -504
    -505
    -506
    -507
    -508
    -509
    -510
    -511
    -512
    -513
    -514
    -515
    -516
    +              
    516
     517
     518
     519
     520
    -521
    def get_tests_by_tags(self, tags: set[str], *, strict: bool = False) -> set[AntaTestDefinition]:
    +521
    +522
    +523
    +524
    +525
    +526
    +527
    +528
    +529
    +530
    +531
    +532
    +533
    +534
    +535
    +536
    +537
    +538
    +539
    +540
    +541
    +542
    +543
    +544
    +545
    +546
    +547
    +548
    +549
    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.
     
         Parameters
    @@ -3508,30 +3639,30 @@ 

    Source code in anta/catalog.py -
    421
    -422
    -423
    -424
    -425
    -426
    -427
    -428
    -429
    -430
    -431
    -432
    -433
    -434
    -435
    -436
    -437
    -438
    -439
    -440
    -441
    -442
    -443
    -444
    def merge(self, catalog: AntaCatalog) -> AntaCatalog:
    +              
    445
    +446
    +447
    +448
    +449
    +450
    +451
    +452
    +453
    +454
    +455
    +456
    +457
    +458
    +459
    +460
    +461
    +462
    +463
    +464
    +465
    +466
    +467
    +468
    def merge(self, catalog: AntaCatalog) -> AntaCatalog:
         """Merge two AntaCatalog instances.
     
         Warning
    @@ -3634,22 +3765,22 @@ 

    Source code in anta/catalog.py -
    404
    -405
    -406
    -407
    -408
    -409
    -410
    -411
    -412
    -413
    -414
    -415
    -416
    -417
    -418
    -419
    @classmethod
    +              
    428
    +429
    +430
    +431
    +432
    +433
    +434
    +435
    +436
    +437
    +438
    +439
    +440
    +441
    +442
    +443
    @classmethod
     def merge_catalogs(cls, catalogs: list[AntaCatalog]) -> AntaCatalog:
         """Merge multiple AntaCatalog instances.
     
    @@ -3733,20 +3864,32 @@ 

    + +

    Returns:

    + + + + + + + + + + + + + +
    TypeDescription
    + AntaCatalog + +
    +

    An AntaCatalog populated with the file content.

    +
    +
    +
    Source code in anta/catalog.py -
    320
    -321
    -322
    -323
    -324
    -325
    -326
    -327
    -328
    -329
    -330
    -331
    +              
    331
     332
     333
     334
    @@ -3760,7 +3903,22 @@ 

    342 343 344 -345

    @staticmethod
    +345
    +346
    +347
    +348
    +349
    +350
    +351
    +352
    +353
    +354
    +355
    +356
    +357
    +358
    +359
    +360
    @staticmethod
     def parse(filename: str | Path, file_format: Literal["yaml", "json"] = "yaml") -> AntaCatalog:
         """Create an AntaCatalog instance from a test catalog file.
     
    @@ -3771,6 +3929,10 @@ 

    file_format Format of the file, either 'yaml' or 'json'. + Returns + ------- + AntaCatalog + An AntaCatalog populated with the file content. """ if file_format not in ["yaml", "json"]: message = f"'{file_format}' is not a valid format for an AntaCatalog file. Only 'yaml' and 'json' are supported." @@ -3860,17 +4022,17 @@

    Source code in anta/catalog.py -
    72
    -73
    -74
    -75
    -76
    -77
    -78
    +                    
    78
     79
     80
     81
    -82
    def __init__(self, **data: type[AntaTest] | AntaTest.Input | dict[str, Any] | None) -> None:
    +82
    +83
    +84
    +85
    +86
    +87
    +88
    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.
    @@ -3905,7 +4067,7 @@ 

    -
    check_inputs() -> AntaTestDefinition
    +
    check_inputs() -> Self
     
    @@ -3915,17 +4077,17 @@

    Source code in anta/catalog.py -
    125
    -126
    -127
    -128
    -129
    -130
    -131
    +              
    131
     132
     133
    -134
    @model_validator(mode="after")
    -def check_inputs(self) -> AntaTestDefinition:
    +134
    +135
    +136
    +137
    +138
    +139
    +140
    @model_validator(mode="after")
    +def check_inputs(self) -> Self:
         """Check the `inputs` field typing.
     
         The `inputs` class attribute needs to be an instance of the AntaTest.Input subclass defined in the class `test`.
    @@ -3964,13 +4126,7 @@ 

    Source code in anta/catalog.py -
     84
    - 85
    - 86
    - 87
    - 88
    - 89
    - 90
    +              
     90
      91
      92
      93
    @@ -4003,7 +4159,13 @@ 

    120 121 122 -123

    @field_validator("inputs", mode="before")
    +123
    +124
    +125
    +126
    +127
    +128
    +129
    @field_validator("inputs", mode="before")
     @classmethod
     def instantiate_inputs(
         cls: type[AntaTestDefinition],
    @@ -4093,13 +4255,7 @@ 

    Source code in anta/catalog.py -
    55
    -56
    -57
    -58
    -59
    -60
    -61
    +              
    61
     62
     63
     64
    @@ -4108,7 +4264,13 @@ 

    67 68 69 -70

    @model_serializer()
    +70
    +71
    +72
    +73
    +74
    +75
    +76
    @model_serializer()
     def serialize_model(self) -> dict[str, AntaTest.Input]:
         """Serialize the AntaTestDefinition model.
     
    @@ -4204,13 +4366,7 @@ 

    Source code in anta/catalog.py -
    196
    -197
    -198
    -199
    -200
    -201
    -202
    +              
    202
     203
     204
     205
    @@ -4243,7 +4399,13 @@ 

    232 233 234 -235

    @model_validator(mode="before")
    +235
    +236
    +237
    +238
    +239
    +240
    +241
    @model_validator(mode="before")
     @classmethod
     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.
    @@ -4321,13 +4483,7 @@ 

    Source code in anta/catalog.py -
    153
    -154
    -155
    -156
    -157
    -158
    -159
    +              
    159
     160
     161
     162
    @@ -4360,7 +4516,13 @@ 

    189 190 191 -192

    @staticmethod
    +192
    +193
    +194
    +195
    +196
    +197
    +198
    @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.
     
    @@ -4383,7 +4545,7 @@ 

    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 + except Exception as e: # 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 ''}" @@ -4446,15 +4608,15 @@

    Source code in anta/catalog.py -
    251
    -252
    -253
    -254
    -255
    -256
    -257
    +              
    257
     258
    -259
    def to_json(self) -> str:
    +259
    +260
    +261
    +262
    +263
    +264
    +265
    def to_json(self) -> str:
         """Return a JSON representation string of this model.
     
         Returns
    @@ -4509,19 +4671,19 @@ 

    Source code in anta/catalog.py -
    237
    -238
    -239
    -240
    -241
    -242
    -243
    +              
    243
     244
     245
     246
     247
     248
    -249
    def yaml(self) -> str:
    +249
    +250
    +251
    +252
    +253
    +254
    +255
    def yaml(self) -> str:
         """Return a YAML representation string of this model.
     
         Returns
    @@ -4568,7 +4730,7 @@ 

    - January 9, 2024 + October 2, 2024 @@ -4664,10 +4826,10 @@

    - + - + diff --git a/main/api/device/index.html b/main/api/device/index.html index be2118fadf..4f319bece2 100644 --- a/main/api/device/index.html +++ b/main/api/device/index.html @@ -20,7 +20,7 @@ - + @@ -28,7 +28,7 @@ - + @@ -357,7 +357,7 @@ - Inventory & Tests catalog + Inventory and Test catalog @@ -558,7 +558,7 @@ - Check + Check commands @@ -579,7 +579,7 @@ - Helpers + Debug commands @@ -1691,6 +1691,20 @@ + +
  • + + + __repr__ + + + + + +
  • + + +
  • @@ -1799,6 +1813,20 @@