From 1fd6a618b60d7168fd8f37585d5d39d22d775afd Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Thu, 28 Mar 2024 07:11:39 +0100 Subject: Adding upstream version 0.13.0. Signed-off-by: Daniel Baumann --- docs/advanced_usages/caching.md | 87 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 87 insertions(+) create mode 100644 docs/advanced_usages/caching.md (limited to 'docs/advanced_usages/caching.md') diff --git a/docs/advanced_usages/caching.md b/docs/advanced_usages/caching.md new file mode 100644 index 0000000..cec2467 --- /dev/null +++ b/docs/advanced_usages/caching.md @@ -0,0 +1,87 @@ + + +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](https://github.com/aio-libs/aiocache)'s memory cache backend, also called [`SimpleMemoryCache`](https://aiocache.aio-libs.org/en/v0.12.2/caches.html#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](../advanced_usages/as-python-lib.md#antadevice-abstract-class) abstract class initializes the cache. Child classes can override this method to tweak the cache configuration: + +```python +def _init_cache(self) -> None: + """ + Initialize cache for the device, can be overridden by subclasses to manipulate how it works + """ + self.cache = Cache(cache_class=Cache.MEMORY, ttl=60, namespace=self.name, plugins=[HitMissRatioPlugin()]) + self.cache_locks = defaultdict(asyncio.Lock) +``` + +The cache is also configured with `aiocache`'s [`HitMissRatioPlugin`](https://aiocache.aio-libs.org/en/v0.12.2/plugins.html#hitmissratioplugin) plugin to calculate the ratio of hits the cache has and give useful statistics for logging purposes in ANTA. + +## Cache key design + +The cache is initialized per `AntaDevice` and uses the following cache key design: + +`:` + +The `uid` is an attribute of [AntaCommand](../advanced_usages/as-python-lib.md#antacommand-class), 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. + +## 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: + +1. Caching can be disabled globally, for **ALL** commands on **ALL** devices, using the `--disable-cache` global flag when invoking anta at the [CLI](../cli/overview.md#invoking-anta-cli): + ```bash + anta --disable-cache --username arista --password arista nrfu table + ``` +2. Caching can be disabled per device, network or range by setting the `disable_cache` key to `True` when definining the ANTA [Inventory](../usage-inventory-catalog.md#create-an-inventory-file) file: + ```yaml + anta_inventory: + hosts: + - host: 172.20.20.101 + name: DC1-SPINE1 + tags: ["SPINE", "DC1"] + disable_cache: True # Set this key to True + - host: 172.20.20.102 + name: DC1-SPINE2 + tags: ["SPINE", "DC1"] + disable_cache: False # Optional since it's the default + + networks: + - network: "172.21.21.0/24" + disable_cache: True + + ranges: + - start: 172.22.22.10 + 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. + +3. For tests developpers, caching can be disabled for a specific [`AntaCommand`](../advanced_usages/as-python-lib.md#antacommand-class) or [`AntaTemplate`](../advanced_usages/as-python-lib.md#antatemplate-class) by setting the `use_cache` attribute to `False`. That means the command output will always be collected on the device and therefore, never use caching. + +### 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`: + +```python +class AnsibleEOSDevice(AntaDevice): + """ + Implementation of an AntaDevice using Ansible HttpApi plugin for EOS. + """ + def __init__(self, name: str, connection: ConnectionBase, tags: list = None) -> None: + super().__init__(name, tags, disable_cache=True) +``` -- cgit v1.2.3