Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: Sonar issues #2

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ ARG IMG_OPTION=alpine

### BUILDER

FROM python:${PYTHON_VER}-${IMG_OPTION} as BUILDER
FROM python:${PYTHON_VER}-${IMG_OPTION} AS BUILDER

RUN pip install --upgrade pip

Expand All @@ -19,7 +19,7 @@ RUN pip --no-cache-dir install --user .

### BASE

FROM python:${PYTHON_VER}-${IMG_OPTION} as BASE
FROM python:${PYTHON_VER}-${IMG_OPTION} AS BASE

# Opencontainer labels
# Labels version and revision will be updating
Expand Down
8 changes: 4 additions & 4 deletions anta/catalog.py
Original file line number Diff line number Diff line change
Expand Up @@ -176,12 +176,12 @@ def flatten_modules(data: dict[str, Any], package: str | None = None) -> dict[Mo
if isinstance(tests, dict):
# This is an inner Python module
modules.update(AntaCatalogFile.flatten_modules(data=tests, package=module.__name__))
else:
if not isinstance(tests, list):
msg = f"Syntax error when parsing: {tests}\nIt must be a list of ANTA tests. Check the test catalog."
raise ValueError(msg) # noqa: TRY004 pydantic catches ValueError or AssertionError, no TypeError
elif isinstance(tests, list):
# This is a list of AntaTestDefinition
modules[module] = tests
else:
msg = f"Syntax error when parsing: {tests}\nIt must be a list of ANTA tests. Check the test catalog."
raise ValueError(msg) # noqa: TRY004 pydantic catches ValueError or AssertionError, no TypeError
return modules

# ANN401 - Any ok for this validator as we are validating the received data
Expand Down
53 changes: 27 additions & 26 deletions anta/cli/exec/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,12 +106,12 @@ async def collect(device: AntaDevice) -> None:
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)
Expand All @@ -122,31 +122,32 @@ async def collect(device: AntaDevice) -> None:

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")
Expand Down
5 changes: 2 additions & 3 deletions anta/cli/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
from typing import TYPE_CHECKING, Any, Callable

import click
from pydantic import ValidationError
from yaml import YAMLError

from anta.catalog import AntaCatalog
Expand Down Expand Up @@ -254,7 +253,7 @@ def wrapper(
insecure=insecure,
disable_cache=disable_cache,
)
except (ValidationError, TypeError, ValueError, YAMLError, OSError, InventoryIncorrectSchemaError, InventoryRootKeyError):
except (TypeError, ValueError, YAMLError, OSError, InventoryIncorrectSchemaError, InventoryRootKeyError):
ctx.exit(ExitCode.USAGE_ERROR)
return f(*args, inventory=i, tags=tags, **kwargs)

Expand Down Expand Up @@ -292,7 +291,7 @@ def wrapper(
return f(*args, catalog=None, **kwargs)
try:
c = AntaCatalog.parse(catalog)
except (ValidationError, TypeError, ValueError, YAMLError, OSError):
except (TypeError, ValueError, YAMLError, OSError):
ctx.exit(ExitCode.USAGE_ERROR)
return f(*args, catalog=c, **kwargs)

Expand Down
8 changes: 2 additions & 6 deletions anta/custom_types.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ def interface_autocomplete(v: str) -> str:
- `po` will be changed to `Port-Channel`
- `lo` will be changed to `Loopback`
"""
intf_id_re = re.compile(r"[0-9]+(\/[0-9]+)*(\.[0-9]+)?")
intf_id_re = re.compile(r"\d+(\/\d+)*(\.\d+)?")
m = intf_id_re.search(v)
if m is None:
msg = f"Could not parse interface ID in interface '{v}'"
Expand All @@ -33,11 +33,7 @@ def interface_autocomplete(v: str) -> str:

alias_map = {"et": "Ethernet", "eth": "Ethernet", "po": "Port-Channel", "lo": "Loopback"}

for alias, full_name in alias_map.items():
if v.lower().startswith(alias):
return f"{full_name}{intf_id}"

return v
return next((f"{full_name}{intf_id}" for alias, full_name in alias_map.items() if v.lower().startswith(alias)), v)


def interface_case_sensitivity(v: str) -> str:
Expand Down
1 change: 0 additions & 1 deletion anta/tests/field_notices.py
Original file line number Diff line number Diff line change
Expand Up @@ -197,4 +197,3 @@ def test(self) -> None:
return
# We should never hit this point
self.result.is_error("Error in running test - FixedSystemvrm1 not found")
return
4 changes: 2 additions & 2 deletions docs/faq.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
---
toc_depth: 4
toc_depth: 2
---
<!--
~ Copyright (c) 2023-2024 Arista Networks, Inc.
~ Use of this source code is governed by the Apache License 2.0
~ that can be found in the LICENSE file.
-->
<style>
h4 {
.md-typeset h2 {
visibility: hidden;
font-size: 0em;
height: 0em;
Expand Down
9 changes: 0 additions & 9 deletions docs/stylesheets/extra.material.css
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,8 @@
--md-code-bg-color: #E6E6E6;
--md-code-border-color: #0000004f;
--block-code-bg-color: #e4e4e4;
/* --md-code-fg-color: ...; */

font-size: 1.1rem;
/* min-height: 100%;
position: relative;
width: 100%; */
font-feature-settings: "kern","liga";
font-family: var(--md-text-font-family,_),-apple-system,BlinkMacSystemFont,Helvetica,Arial,sans-serif;
-webkit-font-smoothing: antialiased;
Expand All @@ -62,9 +58,7 @@
--md-typeset-a-color-bg: #27569B;

/* Code block color shades */
/* --md-code-bg-color: #E6E6E6; */
--md-code-border-color: #aec6db4f;
/* --block-code-bg-color: #e4e4e4; */
}

@media only screen and (min-width: 76.25em) {
Expand Down Expand Up @@ -230,8 +224,6 @@
.md-typeset table:not([class]) th {
min-width: 5rem;
padding: .6rem .8rem;
/* color: var(--md-primary-fg-color--light); */
bg: var(--md-footer-fg-color--lighter);
}

.md-footer-copyright {
Expand All @@ -247,7 +239,6 @@
margin-left: auto;
margin-right: auto;
border-radius: 1%;
/* width: 50%; */
}
}

Expand Down
2 changes: 1 addition & 1 deletion tests/units/cli/nrfu/test_commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ def test_anta_nrfu_json(click_runner: CliRunner) -> None:
result = click_runner.invoke(anta, ["nrfu", "json"])
assert result.exit_code == ExitCode.OK
assert "JSON results" in result.output
match = re.search(r"\[\n {[\s\S]+ }\n\]", result.output)
match = re.search(r"\[\n {2}{[\s\S]+ {2}}\n\]", result.output)
assert match is not None
result_list = json.loads(match.group())
for res in result_list:
Expand Down
1 change: 0 additions & 1 deletion tests/units/test_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -646,7 +646,6 @@ def test_wrong_format_output_access(self) -> None:
text_cmd = AntaCommand(command="show dummy", ofmt="text", output="blah")
text_cmd_2 = AntaCommand(command="show dummy", ofmt="text", output={"not_a": "string"})
msg = "Output of command 'show dummy' is invalid"
msg = "Output of command 'show dummy' is invalid"
with pytest.raises(RuntimeError, match=msg):
json_cmd.text_output
with pytest.raises(RuntimeError, match=msg):
Expand Down
Loading