summaryrefslogtreecommitdiffstats
path: root/anta/device.py
diff options
context:
space:
mode:
Diffstat (limited to 'anta/device.py')
-rw-r--r--anta/device.py43
1 files changed, 23 insertions, 20 deletions
diff --git a/anta/device.py b/anta/device.py
index d517b8f..f0ec6a0 100644
--- a/anta/device.py
+++ b/anta/device.py
@@ -18,7 +18,8 @@ from aiocache.plugins import HitMissRatioPlugin
from asyncssh import SSHClientConnection, SSHClientConnectionOptions
from httpx import ConnectError, HTTPError, TimeoutException
-from anta import __DEBUG__, aioeapi
+import asynceapi
+from anta import __DEBUG__
from anta.logger import anta_log_exception, exc_to_str
from anta.models import AntaCommand
@@ -116,7 +117,7 @@ class AntaDevice(ABC):
yield "disable_cache", self.cache is None
@abstractmethod
- async def _collect(self, command: AntaCommand) -> None:
+ async def _collect(self, command: AntaCommand, *, collection_id: str | None = None) -> None:
"""Collect device command output.
This abstract coroutine can be used to implement any command collection method
@@ -131,11 +132,11 @@ class AntaDevice(ABC):
Args:
----
- command: the command to collect
-
+ command: The command to collect.
+ collection_id: An identifier used to build the eAPI request ID.
"""
- async def collect(self, command: AntaCommand) -> None:
+ async def collect(self, command: AntaCommand, *, collection_id: str | None = None) -> None:
"""Collect the output for a specified command.
When caching is activated on both the device and the command,
@@ -148,8 +149,8 @@ class AntaDevice(ABC):
Args:
----
- command (AntaCommand): The command to process.
-
+ command: The command to collect.
+ collection_id: An identifier used to build the eAPI request ID.
"""
# Need to ignore pylint no-member as Cache is a proxy class and pylint is not smart enough
# https://github.com/pylint-dev/pylint/issues/7258
@@ -161,20 +162,20 @@ class AntaDevice(ABC):
logger.debug("Cache hit for %s on %s", command.command, self.name)
command.output = cached_output
else:
- await self._collect(command=command)
+ await self._collect(command=command, collection_id=collection_id)
await self.cache.set(command.uid, command.output) # pylint: disable=no-member
else:
- await self._collect(command=command)
+ await self._collect(command=command, collection_id=collection_id)
- async def collect_commands(self, commands: list[AntaCommand]) -> None:
+ async def collect_commands(self, commands: list[AntaCommand], *, collection_id: str | None = None) -> None:
"""Collect multiple commands.
Args:
----
- commands: the commands to collect
-
+ commands: The commands to collect.
+ collection_id: An identifier used to build the eAPI request ID.
"""
- await asyncio.gather(*(self.collect(command=command) for command in commands))
+ await asyncio.gather(*(self.collect(command=command, collection_id=collection_id) for command in commands))
@abstractmethod
async def refresh(self) -> None:
@@ -270,7 +271,7 @@ class AsyncEOSDevice(AntaDevice):
raise ValueError(message)
self.enable = enable
self._enable_password = enable_password
- self._session: aioeapi.Device = aioeapi.Device(host=host, port=port, username=username, password=password, proto=proto, timeout=timeout)
+ self._session: asynceapi.Device = asynceapi.Device(host=host, port=port, username=username, password=password, proto=proto, timeout=timeout)
ssh_params: dict[str, Any] = {}
if insecure:
ssh_params["known_hosts"] = None
@@ -305,7 +306,7 @@ class AsyncEOSDevice(AntaDevice):
"""
return (self._session.host, self._session.port)
- async def _collect(self, command: AntaCommand) -> None: # noqa: C901 function is too complex - because of many required except blocks
+ async def _collect(self, command: AntaCommand, *, collection_id: str | None = None) -> None: # noqa: C901 function is too complex - because of many required except blocks #pylint: disable=line-too-long
"""Collect device command output from EOS using aio-eapi.
Supports outformat `json` and `text` as output structure.
@@ -314,9 +315,10 @@ class AsyncEOSDevice(AntaDevice):
Args:
----
- command: the AntaCommand to collect.
+ command: The command to collect.
+ collection_id: An identifier used to build the eAPI request ID.
"""
- commands: list[dict[str, Any]] = []
+ commands: list[dict[str, str | int]] = []
if self.enable and self._enable_password is not None:
commands.append(
{
@@ -329,14 +331,15 @@ class AsyncEOSDevice(AntaDevice):
commands.append({"cmd": "enable"})
commands += [{"cmd": command.command, "revision": command.revision}] if command.revision else [{"cmd": command.command}]
try:
- response: list[dict[str, Any]] = await self._session.cli(
+ response: list[dict[str, Any] | str] = await self._session.cli(
commands=commands,
ofmt=command.ofmt,
version=command.version,
- )
+ req_id=f"ANTA-{collection_id}-{id(command)}" if collection_id else f"ANTA-{id(command)}",
+ ) # type: ignore[assignment] # multiple commands returns a list
# Do not keep response of 'enable' command
command.output = response[-1]
- except aioeapi.EapiCommandError as e:
+ except asynceapi.EapiCommandError as e:
# This block catches exceptions related to EOS issuing an error.
command.errors = e.errors
if command.requires_privileges: