From 5d50a3bd59a37fcd50a21002a6c7dc89ef62c412 Mon Sep 17 00:00:00 2001 From: gmuloc Date: Fri, 7 Jun 2024 12:09:51 +0200 Subject: [PATCH 01/11] Feat(anta.cli): Make CV certs verified by default --- anta/cli/get/commands.py | 11 +++++++++-- anta/cli/get/utils.py | 21 +++++++++++++++++---- tests/units/cli/get/test_commands.py | 12 ++++++++---- tests/units/cli/get/test_utils.py | 13 ++++++++++--- 4 files changed, 44 insertions(+), 13 deletions(-) diff --git a/anta/cli/get/commands.py b/anta/cli/get/commands.py index a4125db67..4f1be7088 100644 --- a/anta/cli/get/commands.py +++ b/anta/cli/get/commands.py @@ -36,14 +36,21 @@ @click.option("--username", "-u", help="CloudVision username", type=str, required=True) @click.option("--password", "-p", help="CloudVision password", type=str, required=True) @click.option("--container", "-c", help="CloudVision container where devices are configured", type=str) -def from_cvp(ctx: click.Context, output: Path, host: str, username: str, password: str, container: str | None) -> None: +@click.option( + "--ignore-cert", + help="By default connection to CV will use HTTPS certificate, set this flag to disable it", + show_envvar=True, + is_flag=True, + default=False, +) +def from_cvp(ctx: click.Context, output: Path, host: str, username: str, password: str, container: str | None, *, ignore_cert: bool) -> None: # pylint: disable=too-many-arguments """Build ANTA inventory from Cloudvision. TODO - handle get_inventory and get_devices_in_container failure """ logger.info("Getting authentication token for user '%s' from CloudVision instance '%s'", username, host) - token = get_cv_token(cvp_ip=host, cvp_username=username, cvp_password=password) + token = get_cv_token(cvp_ip=host, cvp_username=username, cvp_password=password, verify_cert=not ignore_cert) clnt = CvpClient() try: diff --git a/anta/cli/get/utils.py b/anta/cli/get/utils.py index 1d56cfa23..87f8d5054 100644 --- a/anta/cli/get/utils.py +++ b/anta/cli/get/utils.py @@ -77,16 +77,29 @@ def wrapper( return wrapper -def get_cv_token(cvp_ip: str, cvp_username: str, cvp_password: str) -> str: - """Generate AUTH token from CVP using password.""" - # TODO: need to handle requests error +def get_cv_token(cvp_ip: str, cvp_username: str, cvp_password: str, *, verify_cert: bool) -> str: + """Generate AUTH token from CVP using password. + TODO: need to handle requests error + + Args: + ---- + cvp_ip: IP address of CloudVision. + cvp_username: Username to connect to CloudVision. + cvp_password: Password to connect to CloudVision. + verify_cert: Enable or disable certificate verification when connecting to CloudVision. + + Returns + ------- + token(str): The token to use in further API calls to CloudVision. + + """ # use CVP REST API to generate a token url = f"https://{cvp_ip}/cvpservice/login/authenticate.do" payload = json.dumps({"userId": cvp_username, "password": cvp_password}) headers = {"Content-Type": "application/json", "Accept": "application/json"} - response = requests.request("POST", url, headers=headers, data=payload, verify=False, timeout=10) + response = requests.request("POST", url, headers=headers, data=payload, verify=verify_cert, timeout=10) return response.json()["sessionId"] diff --git a/tests/units/cli/get/test_commands.py b/tests/units/cli/get/test_commands.py index e0b17a0cc..20e9edf3a 100644 --- a/tests/units/cli/get/test_commands.py +++ b/tests/units/cli/get/test_commands.py @@ -24,17 +24,19 @@ @pytest.mark.parametrize( - ("cvp_container", "cvp_connect_failure"), + ("cvp_container", "verify_cert", "cvp_connect_failure"), [ - pytest.param(None, False, id="all devices"), - pytest.param("custom_container", False, id="custom container"), - pytest.param(None, True, id="cvp connect failure"), + pytest.param(None, True, False, id="all devices - verify cert"), + pytest.param(None, False, False, id="all devices - do not verify cert"), + pytest.param("custom_container", False, False, id="custom container"), + pytest.param(None, False, True, id="cvp connect failure"), ], ) def test_from_cvp( tmp_path: Path, click_runner: CliRunner, cvp_container: str | None, + verify_cert: bool, cvp_connect_failure: bool, ) -> None: """Test `anta get from-cvp`. @@ -57,6 +59,8 @@ def test_from_cvp( if cvp_container is not None: cli_args.extend(["--container", cvp_container]) + if not verify_cert: + cli_args.extend(["--ignore-cert"]) def mock_cvp_connect(_self: CvpClient, *_args: str, **_kwargs: str) -> None: if cvp_connect_failure: diff --git a/tests/units/cli/get/test_utils.py b/tests/units/cli/get/test_utils.py index 7ce85dc5c..e105f9476 100644 --- a/tests/units/cli/get/test_utils.py +++ b/tests/units/cli/get/test_utils.py @@ -19,7 +19,14 @@ DATA_DIR: Path = Path(__file__).parents[3].resolve() / "data" -def test_get_cv_token() -> None: +@pytest.mark.parametrize( + "verify_cert", + [ + pytest.param(True, id="Verify cert enabled"), + pytest.param(False, id="Verify cert disabled"), + ], +) +def test_get_cv_token(verify_cert: bool) -> None: """Test anta.get.utils.get_cv_token.""" ip_addr = "42.42.42.42" username = "ant" @@ -29,13 +36,13 @@ def test_get_cv_token() -> None: mocked_ret = MagicMock(autospec=requests.Response) mocked_ret.json.return_value = {"sessionId": "simple"} patched_request.return_value = mocked_ret - res = get_cv_token(ip_addr, username, password) + res = get_cv_token(ip_addr, username, password, verify_cert=verify_cert) patched_request.assert_called_once_with( "POST", "https://42.42.42.42/cvpservice/login/authenticate.do", headers={"Content-Type": "application/json", "Accept": "application/json"}, data='{"userId": "ant", "password": "formica"}', - verify=False, + verify=verify_cert, timeout=10, ) assert res == "simple" From 7932fb28a169cf46ca2afda68dc8f38da05b10cf Mon Sep 17 00:00:00 2001 From: gmuloc Date: Fri, 7 Jun 2024 12:34:59 +0200 Subject: [PATCH 02/11] WIP --- anta/cli/get/commands.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/anta/cli/get/commands.py b/anta/cli/get/commands.py index 4f1be7088..1dae818aa 100644 --- a/anta/cli/get/commands.py +++ b/anta/cli/get/commands.py @@ -50,11 +50,17 @@ def from_cvp(ctx: click.Context, output: Path, host: str, username: str, passwor TODO - handle get_inventory and get_devices_in_container failure """ logger.info("Getting authentication token for user '%s' from CloudVision instance '%s'", username, host) - token = get_cv_token(cvp_ip=host, cvp_username=username, cvp_password=password, verify_cert=not ignore_cert) + is_cvaas = False + # TODO: This is not nice handling of authentication failure nor CVaaS detection + try: + token = get_cv_token(cvp_ip=host, cvp_username=username, cvp_password=password, verify_cert=not ignore_cert) + except Exception: + token = password + is_cvaas = True clnt = CvpClient() try: - clnt.connect(nodes=[host], username="", password="", api_token=token) + clnt.connect(nodes=[host], username="", password="", api_token=token, is_cvaas=is_cvaas) except CvpApiError as error: logger.error("Error connecting to CloudVision: %s", error) ctx.exit(ExitCode.USAGE_ERROR) From cfbebe4d48642ac2c803208b6aea778a8630a3c0 Mon Sep 17 00:00:00 2001 From: gmuloc Date: Fri, 7 Jun 2024 13:26:33 +0200 Subject: [PATCH 03/11] Revert "WIP" This reverts commit 7932fb28a169cf46ca2afda68dc8f38da05b10cf. --- anta/cli/get/commands.py | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/anta/cli/get/commands.py b/anta/cli/get/commands.py index 1dae818aa..4f1be7088 100644 --- a/anta/cli/get/commands.py +++ b/anta/cli/get/commands.py @@ -50,17 +50,11 @@ def from_cvp(ctx: click.Context, output: Path, host: str, username: str, passwor TODO - handle get_inventory and get_devices_in_container failure """ logger.info("Getting authentication token for user '%s' from CloudVision instance '%s'", username, host) - is_cvaas = False - # TODO: This is not nice handling of authentication failure nor CVaaS detection - try: - token = get_cv_token(cvp_ip=host, cvp_username=username, cvp_password=password, verify_cert=not ignore_cert) - except Exception: - token = password - is_cvaas = True + token = get_cv_token(cvp_ip=host, cvp_username=username, cvp_password=password, verify_cert=not ignore_cert) clnt = CvpClient() try: - clnt.connect(nodes=[host], username="", password="", api_token=token, is_cvaas=is_cvaas) + clnt.connect(nodes=[host], username="", password="", api_token=token) except CvpApiError as error: logger.error("Error connecting to CloudVision: %s", error) ctx.exit(ExitCode.USAGE_ERROR) From b131b6e775dd86357fe4e872e4a9baced0ad49b2 Mon Sep 17 00:00:00 2001 From: gmuloc Date: Fri, 7 Jun 2024 13:44:28 +0200 Subject: [PATCH 04/11] Refactor: Add limitation --- anta/cli/get/commands.py | 4 +++- docs/cli/inv-from-cvp.md | 29 +++++++++++++++++++++-------- 2 files changed, 24 insertions(+), 9 deletions(-) diff --git a/anta/cli/get/commands.py b/anta/cli/get/commands.py index 4f1be7088..5f5a563a3 100644 --- a/anta/cli/get/commands.py +++ b/anta/cli/get/commands.py @@ -47,7 +47,9 @@ def from_cvp(ctx: click.Context, output: Path, host: str, username: str, passwor # pylint: disable=too-many-arguments """Build ANTA inventory from Cloudvision. - TODO - handle get_inventory and get_devices_in_container failure + NOTE - CVaaS connection via token is not supported today in the code. + + TODO - handle get_cv_token, get_inventory and get_devices_in_container failures. """ logger.info("Getting authentication token for user '%s' from CloudVision instance '%s'", username, host) token = get_cv_token(cvp_ip=host, cvp_username=username, cvp_password=password, verify_cert=not ignore_cert) diff --git a/docs/cli/inv-from-cvp.md b/docs/cli/inv-from-cvp.md index 88973708d..e1b56ecc5 100644 --- a/docs/cli/inv-from-cvp.md +++ b/docs/cli/inv-from-cvp.md @@ -8,21 +8,34 @@ In large setups, it might be beneficial to construct your inventory based on CloudVision. The `from-cvp` entrypoint of the `get` command enables the user to create an ANTA inventory from CloudVision. +!!! info + The current implementation only work towards a local CloudVision instance, not for CVaaS. + ### Command overview ```bash -anta get from-cvp --help Usage: anta get from-cvp [OPTIONS] - Build ANTA inventory from Cloudvision + Build ANTA inventory from Cloudvision. + + NOTE - CVaaS connection via token is not supported today in the code. + + TODO - handle get_cv_token, get_inventory and get_devices_in_container + failures. Options: - -ip, --cvp-ip TEXT CVP IP Address [required] - -u, --cvp-username TEXT CVP Username [required] - -p, --cvp-password TEXT CVP Password / token [required] - -c, --cvp-container TEXT Container where devices are configured - -d, --inventory-directory PATH Path to save inventory file - --help Show this message and exit. + -o, --output FILE Path to save inventory file [env var: ANTA_INVENTORY; + required] + --overwrite Do not prompt when overriding current inventory [env + var: ANTA_GET_FROM_CVP_OVERWRITE] + -host, --host TEXT CloudVision instance FQDN or IP [required] + -u, --username TEXT CloudVision username [required] + -p, --password TEXT CloudVision password [required] + -c, --container TEXT CloudVision container where devices are configured + --ignore-cert By default connection to CV will use HTTPS + certificate, set this flag to disable it [env var: + ANTA_GET_FROM_CVP_IGNORE_CERT] + --help Show this message and exit. ``` The output is an inventory where the name of the container is added as a tag for each host: From cf9822c6a414cd1291a34a1346de5b9b95f6a9ce Mon Sep 17 00:00:00 2001 From: gmuloc Date: Fri, 7 Jun 2024 14:51:39 +0200 Subject: [PATCH 05/11] Fix: Cleaner inventory dump --- anta/cli/get/utils.py | 2 +- anta/inventory/models.py | 15 +++++++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/anta/cli/get/utils.py b/anta/cli/get/utils.py index 87f8d5054..0d6fedc4d 100644 --- a/anta/cli/get/utils.py +++ b/anta/cli/get/utils.py @@ -107,7 +107,7 @@ def write_inventory_to_file(hosts: list[AntaInventoryHost], output: Path) -> Non """Write a file inventory from pydantic models.""" i = AntaInventoryInput(hosts=hosts) with output.open(mode="w", encoding="UTF-8") as out_fd: - out_fd.write(yaml.dump({AntaInventory.INVENTORY_ROOT_KEY: i.model_dump(exclude_unset=True)})) + out_fd.write(yaml.dump({AntaInventory.INVENTORY_ROOT_KEY: yaml.safe_load(i.yaml())})) logger.info("ANTA inventory file has been created: '%s'", output) diff --git a/anta/inventory/models.py b/anta/inventory/models.py index e26ea001c..5796ef700 100644 --- a/anta/inventory/models.py +++ b/anta/inventory/models.py @@ -6,7 +6,9 @@ from __future__ import annotations import logging +import math +import yaml from pydantic import BaseModel, ConfigDict, IPvAnyAddress, IPvAnyNetwork from anta.custom_types import Hostname, Port @@ -82,3 +84,16 @@ class AntaInventoryInput(BaseModel): networks: list[AntaInventoryNetwork] | None = None hosts: list[AntaInventoryHost] | None = None ranges: list[AntaInventoryRange] | None = None + + def yaml(self) -> str: + """Return a YAML representation string of this model. + + Returns + ------- + The YAML representation string of this model. + """ + # TODO: Pydantic and YAML serialization/deserialization is not supported natively. + # This could be improved. + # https://github.com/pydantic/pydantic/issues/1043 + # Explore if this worth using this: https://github.com/NowanIlfideme/pydantic-yaml + return yaml.safe_dump(yaml.safe_load(self.model_dump_json(serialize_as_any=True, exclude_unset=True)), indent=2, width=math.inf) From b1f6a9a4a368f396d282b1847c3e9e13c6ec512b Mon Sep 17 00:00:00 2001 From: gmuloc Date: Fri, 7 Jun 2024 15:25:03 +0200 Subject: [PATCH 06/11] Refactor: Better error message for SSL failure --- anta/cli/get/commands.py | 7 ++++- anta/cli/get/utils.py | 4 +++ tests/units/cli/get/test_commands.py | 46 +++++++++++++++++++--------- 3 files changed, 41 insertions(+), 16 deletions(-) diff --git a/anta/cli/get/commands.py b/anta/cli/get/commands.py index 5f5a563a3..fb788dec1 100644 --- a/anta/cli/get/commands.py +++ b/anta/cli/get/commands.py @@ -13,6 +13,7 @@ from typing import TYPE_CHECKING, Any import click +import requests from cvprac.cvp_client import CvpClient from cvprac.cvp_client_errors import CvpApiError from rich.pretty import pretty_repr @@ -52,7 +53,11 @@ def from_cvp(ctx: click.Context, output: Path, host: str, username: str, passwor TODO - handle get_cv_token, get_inventory and get_devices_in_container failures. """ logger.info("Getting authentication token for user '%s' from CloudVision instance '%s'", username, host) - token = get_cv_token(cvp_ip=host, cvp_username=username, cvp_password=password, verify_cert=not ignore_cert) + try: + token = get_cv_token(cvp_ip=host, cvp_username=username, cvp_password=password, verify_cert=not ignore_cert) + except requests.exceptions.SSLError as error: + logger.error("Authentication to Cloudvison failed: %s.", error) + ctx.exit(ExitCode.USAGE_ERROR) clnt = CvpClient() try: diff --git a/anta/cli/get/utils.py b/anta/cli/get/utils.py index 0d6fedc4d..81487c1da 100644 --- a/anta/cli/get/utils.py +++ b/anta/cli/get/utils.py @@ -93,6 +93,10 @@ def get_cv_token(cvp_ip: str, cvp_username: str, cvp_password: str, *, verify_ce ------- token(str): The token to use in further API calls to CloudVision. + Raises + ------ + requests.ssl.SSLError: If the certificate verification fails + """ # use CVP REST API to generate a token url = f"https://{cvp_ip}/cvpservice/login/authenticate.do" diff --git a/tests/units/cli/get/test_commands.py b/tests/units/cli/get/test_commands.py index 20e9edf3a..babf509f8 100644 --- a/tests/units/cli/get/test_commands.py +++ b/tests/units/cli/get/test_commands.py @@ -11,6 +11,7 @@ from unittest.mock import ANY, patch import pytest +import requests from cvprac.cvp_client_errors import CvpApiError from anta.cli._main import anta @@ -24,12 +25,13 @@ @pytest.mark.parametrize( - ("cvp_container", "verify_cert", "cvp_connect_failure"), + ("cvp_container", "verify_cert", "cv_token_failure", "cvp_connect_failure"), [ - pytest.param(None, True, False, id="all devices - verify cert"), - pytest.param(None, False, False, id="all devices - do not verify cert"), - pytest.param("custom_container", False, False, id="custom container"), - pytest.param(None, False, True, id="cvp connect failure"), + pytest.param(None, True, False, False, id="all devices - verify cert"), + pytest.param(None, True, True, False, id="all devices - fail SSL check"), + pytest.param(None, False, False, False, id="all devices - do not verify cert"), + pytest.param("custom_container", False, False, False, id="custom container"), + pytest.param(None, False, False, True, id="cvp connect failure"), ], ) def test_from_cvp( @@ -37,8 +39,11 @@ def test_from_cvp( click_runner: CliRunner, cvp_container: str | None, verify_cert: bool, + cv_token_failure: bool, cvp_connect_failure: bool, ) -> None: + # pylint: disable=too-many-arguments + # ruff: noqa: C901 """Test `anta get from-cvp`. This test verifies that username and password are NOT mandatory to run this command @@ -62,13 +67,17 @@ def test_from_cvp( if not verify_cert: cli_args.extend(["--ignore-cert"]) + def mock_get_cv_token(*_args: str, **_kwargs: str) -> None: + if cv_token_failure: + raise requests.exceptions.SSLError + def mock_cvp_connect(_self: CvpClient, *_args: str, **_kwargs: str) -> None: if cvp_connect_failure: raise CvpApiError(msg="mocked CvpApiError") # always get a token with ( - patch("anta.cli.get.commands.get_cv_token", return_value="dummy_token"), + patch("anta.cli.get.commands.get_cv_token", autospec=True, side_effect=mock_get_cv_token), patch( "cvprac.cvp_client.CvpClient.connect", autospec=True, @@ -83,20 +92,27 @@ def mock_cvp_connect(_self: CvpClient, *_args: str, **_kwargs: str) -> None: ): result = click_runner.invoke(anta, cli_args) - if not cvp_connect_failure: + if not cvp_connect_failure and not cv_token_failure: assert output.exists() + if cv_token_failure: + assert "Authentication to Cloudvison failed" in result.output + assert result.exit_code == ExitCode.USAGE_ERROR + return + mocked_cvp_connect.assert_called_once() - if not cvp_connect_failure: - assert "Connected to CloudVision" in result.output - if cvp_container is not None: - mocked_get_devices_in_container.assert_called_once_with(ANY, cvp_container) - else: - mocked_get_inventory.assert_called_once() - assert result.exit_code == ExitCode.OK - else: + + if cvp_connect_failure: assert "Error connecting to CloudVision" in result.output assert result.exit_code == ExitCode.USAGE_ERROR + return + + assert "Connected to CloudVision" in result.output + if cvp_container is not None: + mocked_get_devices_in_container.assert_called_once_with(ANY, cvp_container) + else: + mocked_get_inventory.assert_called_once() + assert result.exit_code == ExitCode.OK @pytest.mark.parametrize( From 511caf24cd3c0a544146136d81a881a8a1965189 Mon Sep 17 00:00:00 2001 From: Guillaume Mulocher Date: Fri, 7 Jun 2024 17:54:07 +0200 Subject: [PATCH 07/11] Update anta/cli/get/commands.py Co-authored-by: Carl Baillargeon --- anta/cli/get/commands.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/anta/cli/get/commands.py b/anta/cli/get/commands.py index fb788dec1..7957e8a42 100644 --- a/anta/cli/get/commands.py +++ b/anta/cli/get/commands.py @@ -39,7 +39,7 @@ @click.option("--container", "-c", help="CloudVision container where devices are configured", type=str) @click.option( "--ignore-cert", - help="By default connection to CV will use HTTPS certificate, set this flag to disable it", + help="Ignore verifying the SSL certificate when connecting to CloudVision", show_envvar=True, is_flag=True, default=False, From ca229590193e3dfb195804f531da93dec0166d18 Mon Sep 17 00:00:00 2001 From: Guillaume Mulocher Date: Fri, 7 Jun 2024 17:54:15 +0200 Subject: [PATCH 08/11] Update anta/cli/get/commands.py Co-authored-by: Carl Baillargeon --- anta/cli/get/commands.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/anta/cli/get/commands.py b/anta/cli/get/commands.py index 7957e8a42..4a5457a56 100644 --- a/anta/cli/get/commands.py +++ b/anta/cli/get/commands.py @@ -56,7 +56,7 @@ def from_cvp(ctx: click.Context, output: Path, host: str, username: str, passwor try: token = get_cv_token(cvp_ip=host, cvp_username=username, cvp_password=password, verify_cert=not ignore_cert) except requests.exceptions.SSLError as error: - logger.error("Authentication to Cloudvison failed: %s.", error) + logger.error("Authentication to CloudVison failed: %s.", error) ctx.exit(ExitCode.USAGE_ERROR) clnt = CvpClient() From 3427340aebb9e95bf6883bfd1a5d73239f46f5ba Mon Sep 17 00:00:00 2001 From: gmuloc Date: Fri, 7 Jun 2024 17:56:31 +0200 Subject: [PATCH 09/11] test: Fix test after review --- tests/units/cli/get/test_commands.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/units/cli/get/test_commands.py b/tests/units/cli/get/test_commands.py index babf509f8..1e8c6e95d 100644 --- a/tests/units/cli/get/test_commands.py +++ b/tests/units/cli/get/test_commands.py @@ -96,7 +96,7 @@ def mock_cvp_connect(_self: CvpClient, *_args: str, **_kwargs: str) -> None: assert output.exists() if cv_token_failure: - assert "Authentication to Cloudvison failed" in result.output + assert "Authentication to CloudVison failed" in result.output assert result.exit_code == ExitCode.USAGE_ERROR return From ca6f4f33334420e3949b47a0b42c10791f6bbdbe Mon Sep 17 00:00:00 2001 From: Carl Baillargeon Date: Fri, 7 Jun 2024 12:35:38 -0400 Subject: [PATCH 10/11] Update docstrings and doc around CVaaS --- anta/cli/get/commands.py | 8 ++++---- anta/cli/get/utils.py | 2 +- docs/cli/inv-from-cvp.md | 8 +++----- 3 files changed, 8 insertions(+), 10 deletions(-) diff --git a/anta/cli/get/commands.py b/anta/cli/get/commands.py index 4a5457a56..bfe94e618 100644 --- a/anta/cli/get/commands.py +++ b/anta/cli/get/commands.py @@ -46,12 +46,12 @@ ) def from_cvp(ctx: click.Context, output: Path, host: str, username: str, password: str, container: str | None, *, ignore_cert: bool) -> None: # pylint: disable=too-many-arguments - """Build ANTA inventory from Cloudvision. + """Build ANTA inventory from CloudVision. - NOTE - CVaaS connection via token is not supported today in the code. - - TODO - handle get_cv_token, get_inventory and get_devices_in_container failures. + NOTE: Only username/password authentication is supported for on-premises CloudVision instances. + Token authentication for both on-premises and CloudVision as a Service (CVaaS) is not supported. """ + # TODO: - Handle get_cv_token, get_inventory and get_devices_in_container failures. logger.info("Getting authentication token for user '%s' from CloudVision instance '%s'", username, host) try: token = get_cv_token(cvp_ip=host, cvp_username=username, cvp_password=password, verify_cert=not ignore_cert) diff --git a/anta/cli/get/utils.py b/anta/cli/get/utils.py index 81487c1da..5308f4414 100644 --- a/anta/cli/get/utils.py +++ b/anta/cli/get/utils.py @@ -78,7 +78,7 @@ def wrapper( def get_cv_token(cvp_ip: str, cvp_username: str, cvp_password: str, *, verify_cert: bool) -> str: - """Generate AUTH token from CVP using password. + """Generate the authentication token from CloudVision using username and password. TODO: need to handle requests error diff --git a/docs/cli/inv-from-cvp.md b/docs/cli/inv-from-cvp.md index e1b56ecc5..d2bc45881 100644 --- a/docs/cli/inv-from-cvp.md +++ b/docs/cli/inv-from-cvp.md @@ -9,7 +9,7 @@ In large setups, it might be beneficial to construct your inventory based on CloudVision. The `from-cvp` entrypoint of the `get` command enables the user to create an ANTA inventory from CloudVision. !!! info - The current implementation only work towards a local CloudVision instance, not for CVaaS. + The current implementation only works with on-premises CloudVision instances, not with CloudVision as a Service (CVaaS). ### Command overview @@ -18,10 +18,8 @@ Usage: anta get from-cvp [OPTIONS] Build ANTA inventory from Cloudvision. - NOTE - CVaaS connection via token is not supported today in the code. - - TODO - handle get_cv_token, get_inventory and get_devices_in_container - failures. + NOTE: Only username/password authentication is supported for on-premises CloudVision instances. + Token authentication for both on-premises and CloudVision as a Service (CVaaS) is not supported. Options: -o, --output FILE Path to save inventory file [env var: ANTA_INVENTORY; From 237d472df85fd70dcf9b635be5b5fa8bfa442592 Mon Sep 17 00:00:00 2001 From: Carl Baillargeon Date: Fri, 7 Jun 2024 12:36:37 -0400 Subject: [PATCH 11/11] Update CloudVision --- docs/cli/inv-from-cvp.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/cli/inv-from-cvp.md b/docs/cli/inv-from-cvp.md index d2bc45881..a37af62f1 100644 --- a/docs/cli/inv-from-cvp.md +++ b/docs/cli/inv-from-cvp.md @@ -16,7 +16,7 @@ In large setups, it might be beneficial to construct your inventory based on Clo ```bash Usage: anta get from-cvp [OPTIONS] - Build ANTA inventory from Cloudvision. + Build ANTA inventory from CloudVision. NOTE: Only username/password authentication is supported for on-premises CloudVision instances. Token authentication for both on-premises and CloudVision as a Service (CVaaS) is not supported.