diff --git a/README.md b/README.md index aeea3ea0a..ea6a0a49a 100755 --- a/README.md +++ b/README.md @@ -36,6 +36,8 @@ Options: ANTA_TIMEOUT; default: 5] --insecure Disable SSH Host Key validation [env var: ANTA_INSECURE] + --enable Add enable mode towards the devices if + required to connect [env var: ANTA_ENABLE] --enable-password TEXT Enable password if required to connect [env var: ANTA_ENABLE_PASSWORD] -i, --inventory FILE Path to the inventory YAML file [env var: diff --git a/anta/cli/__init__.py b/anta/cli/__init__.py index 08ea2aaba..71593f2b1 100644 --- a/anta/cli/__init__.py +++ b/anta/cli/__init__.py @@ -49,10 +49,18 @@ help="Disable SSH Host Key validation", show_default=True, ) +@click.option( + "--enable", + show_envvar=True, + is_flag=True, + default=False, + help="Add enable mode towards the devices if required to connect", + show_default=True, +) @click.option( "--enable-password", show_envvar=True, - help="Enable password if required to connect", + help="Enable password if required to connect, --enable MUST be set", ) @click.option( "--inventory", diff --git a/anta/cli/utils.py b/anta/cli/utils.py index 6ee3912ac..9c4a488d4 100644 --- a/anta/cli/utils.py +++ b/anta/cli/utils.py @@ -53,6 +53,7 @@ def parse_inventory(ctx: click.Context, path: Path) -> AntaInventory: inventory_file=str(path), username=ctx.params["username"], password=ctx.params["password"], + enable=ctx.params["enable"], enable_password=ctx.params["enable_password"], timeout=ctx.params["timeout"], insecure=ctx.params["insecure"], @@ -62,7 +63,7 @@ def parse_inventory(ctx: click.Context, path: Path) -> AntaInventory: if __DEBUG__: logger.exception(message) else: - logger.error(message + f": {exc_to_str(e)}") + logger.error(f"{message}: {exc_to_str(e)}") ctx.fail(message) return inventory diff --git a/anta/device.py b/anta/device.py index 5b862b587..5387de2d2 100644 --- a/anta/device.py +++ b/anta/device.py @@ -286,7 +286,7 @@ async def collect(self, command: AntaCommand) -> None: if __DEBUG__: logger.exception(message) else: - logger.error(message + f": {exc_to_str(e)}") + logger.error(f"{message}: {exc_to_str(e)}") command.failed = e logger.debug(command) diff --git a/anta/inventory/__init__.py b/anta/inventory/__init__.py index 617651bb6..49f41b792 100644 --- a/anta/inventory/__init__.py +++ b/anta/inventory/__init__.py @@ -44,7 +44,13 @@ def __str__(self) -> str: @staticmethod def parse( - inventory_file: str, username: str, password: str, enable_password: Optional[str] = None, timeout: Optional[float] = None, insecure: bool = False + inventory_file: str, + username: str, + password: str, + enable: bool = False, + enable_password: Optional[str] = None, + timeout: Optional[float] = None, + insecure: bool = False, ) -> AntaInventory: # pylint: disable=too-many-arguments """ @@ -55,6 +61,7 @@ def parse( inventory_file (str): Path to inventory YAML file where user has described his inputs username (str): Username to use to connect to devices password (str): Password to use to connect to devices + enable (bool): Whether or not the commands need to be run in enable mode towards the devices timeout (float, optional): timeout in seconds for every API call. Raises: @@ -64,7 +71,14 @@ def parse( """ inventory = AntaInventory() - kwargs: Dict[str, Any] = {"username": username, "password": password, "enable_password": enable_password, "timeout": timeout, "insecure": insecure} + kwargs: Dict[str, Any] = { + "username": username, + "password": password, + "enable": enable, + "enable_password": enable_password, + "timeout": timeout, + "insecure": insecure, + } kwargs = {k: v for k, v in kwargs.items() if v is not None} with open(inventory_file, "r", encoding="UTF-8") as file: diff --git a/anta/tools/misc.py b/anta/tools/misc.py index f19880044..7c72abc10 100644 --- a/anta/tools/misc.py +++ b/anta/tools/misc.py @@ -14,7 +14,13 @@ def exc_to_str(exception: Exception) -> str: """ Helper function that returns a human readable string from an Exception object """ - return f"{type(exception).__name__}{f' ({str(exception)})' if str(exception) else ''}" + res = f"{type(exception).__name__}" + if str(exception): + res += f" ({str(exception)})" + elif hasattr(exception, "errmsg"): + # TODO - remove when we bump aio-eapi once our PR is merged there + res += f" ({exception.errmsg})" + return res def tb_to_str(exception: Exception) -> str: diff --git a/docs/README.md b/docs/README.md index 7664f8142..7ee156a7a 100644 --- a/docs/README.md +++ b/docs/README.md @@ -16,6 +16,8 @@ This repository is a Python package to automate tests on Arista devices. This repository comes with a [cli](cli/overview.md) to run __Arista Network Test Automation__ (ANTA) framework using your preferred shell: +!!! info username/password/enable/enable-password are the same for all devices + ```bash # Install ANTA pip install anta @@ -36,6 +38,8 @@ Options: ANTA_TIMEOUT; default: 5] --insecure Disable SSH Host Key validation [env var: ANTA_INSECURE] + --enable Add enable mode towards the devices if + required to connect [env var: ANTA_ENABLE] --enable-password TEXT Enable password if required to connect [env var: ANTA_ENABLE_PASSWORD] -i, --inventory FILE Path to the inventory YAML file [env var: