summaryrefslogtreecommitdiffstats
path: root/anta/cli/exec/utils.py
diff options
context:
space:
mode:
Diffstat (limited to 'anta/cli/exec/utils.py')
-rw-r--r--anta/cli/exec/utils.py65
1 files changed, 35 insertions, 30 deletions
diff --git a/anta/cli/exec/utils.py b/anta/cli/exec/utils.py
index 758072c..a5f7da2 100644
--- a/anta/cli/exec/utils.py
+++ b/anta/cli/exec/utils.py
@@ -14,12 +14,13 @@ import re
from pathlib import Path
from typing import TYPE_CHECKING, Literal
-from aioeapi import EapiCommandError
from click.exceptions import UsageError
from httpx import ConnectError, HTTPError
+from anta.custom_types import REGEXP_PATH_MARKERS
from anta.device import AntaDevice, AsyncEOSDevice
from anta.models import AntaCommand
+from asynceapi import EapiCommandError
if TYPE_CHECKING:
from anta.inventory import AntaInventory
@@ -29,7 +30,7 @@ INVALID_CHAR = "`~!@#$/"
logger = logging.getLogger(__name__)
-async def clear_counters_utils(anta_inventory: AntaInventory, tags: set[str] | None = None) -> None:
+async def clear_counters(anta_inventory: AntaInventory, tags: set[str] | None = None) -> None:
"""Clear counters."""
async def clear(dev: AntaDevice) -> None:
@@ -60,7 +61,7 @@ async def collect_commands(
async def collect(dev: AntaDevice, command: str, outformat: Literal["json", "text"]) -> None:
outdir = Path() / root_dir / dev.name / outformat
outdir.mkdir(parents=True, exist_ok=True)
- safe_command = re.sub(r"(/|\|$)", "_", command)
+ safe_command = re.sub(rf"{REGEXP_PATH_MARKERS}", "_", command)
c = AntaCommand(command=command, ofmt=outformat)
await dev.collect(c)
if not c.collected:
@@ -72,6 +73,9 @@ async def collect_commands(
elif c.ofmt == "text":
outfile = outdir / f"{safe_command}.log"
content = c.text_output
+ else:
+ logger.error("Command outformat is not in ['json', 'text'] for command '%s'", command)
+ return
with outfile.open(mode="w", encoding="UTF-8") as f:
f.write(content)
logger.info("Collected command '%s' from device %s (%s)", command, dev.name, dev.hw_model)
@@ -91,7 +95,7 @@ async def collect_commands(
logger.error("Error when collecting commands: %s", str(r))
-async def collect_scheduled_show_tech(inv: AntaInventory, root_dir: Path, *, configure: bool, tags: set[str] | None = None, latest: int | None = None) -> None:
+async def collect_show_tech(inv: AntaInventory, root_dir: Path, *, configure: bool, tags: set[str] | None = None, latest: int | None = None) -> None:
"""Collect scheduled show-tech on devices."""
async def collect(device: AntaDevice) -> None:
@@ -103,12 +107,12 @@ async def collect_scheduled_show_tech(inv: AntaInventory, root_dir: Path, *, con
cmd += f" | head -{latest}"
command = AntaCommand(command=cmd, ofmt="text")
await device.collect(command=command)
- if command.collected and command.text_output:
- filenames = [Path(f"{EOS_SCHEDULED_TECH_SUPPORT}/{f}") for f in command.text_output.splitlines()]
- else:
+ if not (command.collected and command.text_output):
logger.error("Unable to get tech-support filenames on %s: verify that %s is not empty", device.name, EOS_SCHEDULED_TECH_SUPPORT)
return
+ filenames = [Path(f"{EOS_SCHEDULED_TECH_SUPPORT}/{f}") for f in command.text_output.splitlines()]
+
# Create directories
outdir = Path() / root_dir / f"{device.name.lower()}"
outdir.mkdir(parents=True, exist_ok=True)
@@ -119,31 +123,32 @@ async def collect_scheduled_show_tech(inv: AntaInventory, root_dir: Path, *, con
if command.collected and not command.text_output:
logger.debug("'aaa authorization exec default local' is not configured on device %s", device.name)
- if configure:
- commands = []
- # TODO: @mtache - add `config` field to `AntaCommand` object to handle this use case.
- # Otherwise mypy complains about enable as it is only implemented for AsyncEOSDevice
- # TODO: Should enable be also included in AntaDevice?
- if not isinstance(device, AsyncEOSDevice):
- msg = "anta exec collect-tech-support is only supported with AsyncEOSDevice for now."
- raise UsageError(msg)
- if device.enable and device._enable_password is not None: # pylint: disable=protected-access
- commands.append({"cmd": "enable", "input": device._enable_password}) # pylint: disable=protected-access
- elif device.enable:
- commands.append({"cmd": "enable"})
- commands.extend(
- [
- {"cmd": "configure terminal"},
- {"cmd": "aaa authorization exec default local"},
- ],
- )
- logger.warning("Configuring 'aaa authorization exec default local' on device %s", device.name)
- command = AntaCommand(command="show running-config | include aaa authorization exec default local", ofmt="text")
- await device._session.cli(commands=commands) # pylint: disable=protected-access
- logger.info("Configured 'aaa authorization exec default local' on device %s", device.name)
- else:
+ if not configure:
logger.error("Unable to collect tech-support on %s: configuration 'aaa authorization exec default local' is not present", device.name)
return
+
+ commands = []
+ # TODO: @mtache - add `config` field to `AntaCommand` object to handle this use case.
+ # Otherwise mypy complains about enable as it is only implemented for AsyncEOSDevice
+ # TODO: Should enable be also included in AntaDevice?
+ if not isinstance(device, AsyncEOSDevice):
+ msg = "anta exec collect-tech-support is only supported with AsyncEOSDevice for now."
+ raise UsageError(msg)
+ if device.enable and device._enable_password is not None: # pylint: disable=protected-access
+ commands.append({"cmd": "enable", "input": device._enable_password}) # pylint: disable=protected-access
+ elif device.enable:
+ commands.append({"cmd": "enable"})
+ commands.extend(
+ [
+ {"cmd": "configure terminal"},
+ {"cmd": "aaa authorization exec default local"},
+ ],
+ )
+ logger.warning("Configuring 'aaa authorization exec default local' on device %s", device.name)
+ command = AntaCommand(command="show running-config | include aaa authorization exec default local", ofmt="text")
+ await device._session.cli(commands=commands) # pylint: disable=protected-access
+ logger.info("Configured 'aaa authorization exec default local' on device %s", device.name)
+
logger.debug("'aaa authorization exec default local' is already configured on device %s", device.name)
await device.copy(sources=filenames, destination=outdir, direction="from")