1
0
Fork 0

Merging upstream version 0.12.0.

Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
Daniel Baumann 2025-02-10 06:39:52 +01:00
parent f45bc3d463
commit 8d2f70e3c7
Signed by: daniel
GPG key ID: FBB4F0E80A80222F
77 changed files with 23610 additions and 2331 deletions

View file

@ -6,130 +6,235 @@
# pylint: disable=redefined-builtin
# flake8: noqa E501
"""
Commands for ARDL CLI to list data.
"""CLI commands for listing Arista package information.
This module provides CLI commands to query and display version information for Arista packages (EOS and CVP).
It includes commands to:
- List all available versions with filtering options
- Get the latest version for a given package/branch
The commands use Click for CLI argument parsing and support both text and JSON output formats.
Authentication is handled via a token passed through Click context.
Commands:
versions: Lists all available versions with optional filtering
latest: Shows the latest version matching the filter criteria
Dependencies:
click: CLI framework
rich: For pretty JSON output
eos_downloader.logics.arista_server: Core logic for querying Arista servers
"""
import sys
from typing import Union
import json
import click
from loguru import logger
from rich.console import Console
from rich.pretty import pprint
from rich import print_json
from rich.panel import Panel
import eos_downloader.eos
from eos_downloader.models.version import BASE_VERSION_STR, RTYPE_FEATURE, RTYPES
from eos_downloader.models.data import software_mapping
from eos_downloader.models.types import AristaPackage, ReleaseType, AristaMapping
import eos_downloader.logics.arista_xml_server
from eos_downloader.cli.utils import console_configuration
from eos_downloader.cli.utils import cli_logging
# """
# Commands for ARDL CLI to list data.
# """
@click.command(no_args_is_help=True)
@click.command()
@click.option(
"--format",
type=click.Choice(["json", "text", "fancy"]),
default="fancy",
help="Output format",
)
@click.option(
"--package", type=click.Choice(["eos", "cvp"]), default="eos", required=False
)
@click.option("--branch", "-b", type=str, required=False)
@click.option("--release-type", type=str, required=False)
@click.pass_context
@click.option(
"--latest",
"-l",
is_flag=True,
type=click.BOOL,
default=False,
help="Get latest version in given branch. If --branch is not use, get the latest branch with specific release type",
)
@click.option(
"--release-type",
"-rtype",
type=click.Choice(RTYPES, case_sensitive=False),
default=RTYPE_FEATURE,
help="EOS release type to search",
)
@click.option(
"--branch",
"-b",
type=click.STRING,
default=None,
help="EOS Branch to list releases",
)
@click.option(
"--verbose",
"-v",
is_flag=True,
type=click.BOOL,
default=False,
help="Human readable output. Default is none to use output in script)",
)
@click.option(
"--log-level",
"--log",
help="Logging level of the command",
default="warning",
type=click.Choice(
["debug", "info", "warning", "error", "critical"], case_sensitive=False
),
)
def eos_versions(
def versions(
ctx: click.Context,
log_level: str,
branch: Union[str, None] = None,
release_type: str = RTYPE_FEATURE,
latest: bool = False,
verbose: bool = False,
package: AristaPackage,
branch: str,
release_type: ReleaseType,
format: str,
) -> None:
# pylint: disable = too-many-branches, R0917
"""
List Available EOS version on Arista.com website.
"""List available package versions from Arista server."""
Comes with some filters to get latest release (F or M) as well as branch filtering
- To get latest M release available (without any branch): ardl info eos-versions --latest -rtype m
- To get latest F release available: ardl info eos-versions --latest -rtype F
"""
console = Console()
# Get from Context
console = console_configuration()
token = ctx.obj["token"]
debug = ctx.obj["debug"]
log_level = ctx.obj["log_level"]
cli_logging(log_level)
logger.remove()
if log_level is not None:
logger.add("eos-downloader.log", rotation="10 MB", level=log_level.upper())
querier = eos_downloader.logics.arista_xml_server.AristaXmlQuerier(token=token)
my_download = eos_downloader.eos.EOSDownloader(
image="unset",
software="EOS",
version="unset",
token=token,
hash_method="sha512sum",
)
auth = my_download.authenticate()
if verbose and auth:
console.print("✅ Authenticated on arista.com")
if release_type is not None:
release_type = release_type.upper()
if latest:
if branch is None:
branch = str(my_download.latest_branch(rtype=release_type).branch)
latest_version = my_download.latest_eos(branch, rtype=release_type)
if str(latest_version) == BASE_VERSION_STR:
console.print(
f"[red]Error[/red], cannot find any version in {branch} for {release_type} release type"
)
sys.exit(1)
if verbose:
console.print(
f"Branch {branch} has been selected with release type {release_type}"
)
if branch is not None:
console.print(f"Latest release for {branch}: {latest_version}")
else:
console.print(f"Latest EOS release: {latest_version}")
received_versions = None
try:
received_versions = querier.available_public_versions(
package=package, branch=branch, rtype=release_type
)
except ValueError:
if debug:
console.print_exception(show_locals=True)
else:
console.print(f"{ latest_version }")
else:
versions = my_download.get_eos_versions(branch=branch, rtype=release_type)
if verbose:
console.print(
f'List of available versions for {branch if branch is not None else "all branches"}'
)
for version in versions:
console.print(f"{str(version)}")
console.print("[red]No versions found[/red]")
return
if format == "text":
console.print("Listing available versions")
if received_versions is None:
console.print("[red]No versions found[/red]")
return
for version in received_versions:
console.print(f" - version: [blue]{version}[/blue]")
elif format == "fancy":
lines_output = []
if received_versions is None:
console.print("[red]No versions found[/red]")
return
for version in received_versions:
lines_output.append(f" - version: [blue]{version}[/blue]")
console.print("")
console.print(
Panel("\n".join(lines_output), title="Available versions", padding=1)
)
elif format == "json":
response = []
if received_versions is None:
console.print("[red]No versions found[/red]")
return
for version in received_versions:
out = {}
out["version"] = str(version)
out["branch"] = str(version.branch)
response.append(out)
response = json.dumps(response) # type: ignore
print_json(response)
@click.command()
@click.option(
"--format",
type=click.Choice(["json", "text", "fancy"]),
default="fancy",
help="Output format",
)
@click.option(
"--package", type=click.Choice(["eos", "cvp"]), default="eos", required=False
)
@click.option("--branch", "-b", type=str, required=False)
@click.option("--release-type", type=str, required=False)
@click.pass_context
def latest(
ctx: click.Context,
package: AristaPackage,
branch: str,
release_type: ReleaseType,
format: str,
) -> None:
"""List available versions of Arista packages (eos or CVP) packages."""
console = console_configuration()
token = ctx.obj["token"]
debug = ctx.obj["debug"]
log_level = ctx.obj["log_level"]
cli_logging(log_level)
querier = eos_downloader.logics.arista_xml_server.AristaXmlQuerier(token=token)
received_version = None
try:
received_version = querier.latest(
package=package, branch=branch, rtype=release_type
)
except ValueError:
if debug:
console.print_exception(show_locals=True)
else:
pprint([str(version) for version in versions])
console.print("[red]No versions found[/red]")
if format in ["text", "fancy"]:
version_info = f"Latest version for [green]{package}[/green]: [blue]{received_version}[/blue]"
if branch:
version_info += f" for branch [blue]{branch}[/blue]"
if format == "text":
console.print("")
console.print(version_info)
else: # fancy format
console.print("")
console.print(Panel(version_info, title="Latest version", padding=1))
else: # json format
print_json(json.dumps({"version": str(received_version)}))
@click.command()
@click.option(
"--package", type=click.Choice(["eos", "cvp"]), default="eos", required=False
)
@click.option(
"--format",
type=click.Choice(["json", "text", "fancy"]),
default="fancy",
help="Output format",
)
@click.option(
"--details",
is_flag=True,
show_default=True,
default=False,
help="Show details for each flavor",
)
@click.pass_context
def mapping(
ctx: click.Context, package: AristaPackage, details: bool, format: str
) -> None:
"""List available flavors of Arista packages (eos or CVP) packages."""
mapping_pkg_name: AristaMapping = "EOS"
if package == "eos":
mapping_pkg_name = "EOS"
elif package == "cvp":
mapping_pkg_name = "CloudVision"
console = console_configuration()
log_level = ctx.obj["log_level"]
console.print(f"Log Level is: {log_level}")
cli_logging(log_level)
if mapping_pkg_name in software_mapping.model_fields:
mapping_entries = getattr(software_mapping, mapping_pkg_name, None)
if format == "text":
console.print(
f"Following flavors for [red]{package}/{mapping_pkg_name}[/red] have been found:"
)
if mapping_entries is None:
console.print("[red]No flavors found[/red]")
return
for mapping_entry in mapping_entries:
console.print(f" * Flavor: [blue]{mapping_entry}[/blue]")
if details:
console.print(
f" - Information: [black]{mapping_entries[mapping_entry]}[/black]"
)
console.print("\n")
elif format == "fancy":
lines_output = []
if mapping_entries is None:
lines_output.append("[red]No flavors found[/red]")
console.print("\n".join(lines_output))
return
for mapping_entry in mapping_entries:
lines_output.append(f" * Flavor: [blue]{mapping_entry}[/blue]")
if details:
lines_output.append(
f" - Information: [black]{mapping_entries[mapping_entry]}[/black]"
)
console.print("")
console.print(Panel("\n".join(lines_output), title="Flavors", padding=1))
console.print("\n")
elif format == "json":
mapping_json = software_mapping.model_dump()[package.upper()]
print_json(json.dumps(mapping_json))