Merging upstream version 0.12.0.
Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
parent
f45bc3d463
commit
8d2f70e3c7
77 changed files with 23610 additions and 2331 deletions
|
@ -2,252 +2,385 @@
|
|||
# coding: utf-8 -*-
|
||||
# pylint: disable=no-value-for-parameter
|
||||
# pylint: disable=too-many-arguments
|
||||
# pylint: disable=too-many-positional-arguments
|
||||
# pylint: disable=line-too-long
|
||||
# pylint: disable=redefined-builtin
|
||||
# pylint: disable=broad-exception-caught
|
||||
# flake8: noqa E501
|
||||
|
||||
"""
|
||||
Commands for ARDL CLI to get data.
|
||||
"""
|
||||
"""CLI commands for listing Arista package information."""
|
||||
|
||||
import os
|
||||
import sys
|
||||
from typing import Union
|
||||
|
||||
import click
|
||||
from loguru import logger
|
||||
from rich.console import Console
|
||||
from eos_downloader.models.data import RTYPE_FEATURE
|
||||
from eos_downloader.logics.download import SoftManager
|
||||
from eos_downloader.logics.arista_server import AristaServer
|
||||
from eos_downloader.logics.arista_xml_server import (
|
||||
EosXmlObject,
|
||||
AristaXmlQuerier,
|
||||
CvpXmlObject,
|
||||
)
|
||||
|
||||
import eos_downloader.eos
|
||||
from eos_downloader.models.version import BASE_VERSION_STR, RTYPE_FEATURE, RTYPES
|
||||
|
||||
EOS_IMAGE_TYPE = [
|
||||
"64",
|
||||
"INT",
|
||||
"2GB-INT",
|
||||
"cEOS",
|
||||
"cEOS64",
|
||||
"vEOS",
|
||||
"vEOS-lab",
|
||||
"EOS-2GB",
|
||||
"default",
|
||||
]
|
||||
CVP_IMAGE_TYPE = ["ova", "rpm", "kvm", "upgrade"]
|
||||
from .utils import initialize, search_version, download_files, handle_docker_import
|
||||
|
||||
|
||||
@click.command(no_args_is_help=True)
|
||||
@click.pass_context
|
||||
@click.option(
|
||||
"--image-type",
|
||||
default="default",
|
||||
help="EOS Image type",
|
||||
type=click.Choice(EOS_IMAGE_TYPE),
|
||||
required=True,
|
||||
)
|
||||
@click.option("--version", default=None, help="EOS version", type=str, required=False)
|
||||
@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(
|
||||
"--docker-name",
|
||||
default="arista/ceos",
|
||||
help="Docker image name (default: arista/ceos)",
|
||||
type=str,
|
||||
show_default=True,
|
||||
)
|
||||
@click.command()
|
||||
@click.option("--format", default="vmdk", help="Image format", show_default=True)
|
||||
@click.option(
|
||||
"--output",
|
||||
default=str(os.path.relpath(os.getcwd(), start=os.curdir)),
|
||||
help="Path to save image",
|
||||
type=click.Path(),
|
||||
show_default=True,
|
||||
show_envvar=True,
|
||||
)
|
||||
# Debugging
|
||||
@click.option(
|
||||
"--log-level",
|
||||
"--log",
|
||||
help="Logging level of the command",
|
||||
default=None,
|
||||
type=click.Choice(
|
||||
["debug", "info", "warning", "error", "critical"], case_sensitive=False
|
||||
),
|
||||
"--latest",
|
||||
is_flag=True,
|
||||
help="Get latest version. If --branch is not use, get the latest branch with specific release type",
|
||||
default=False,
|
||||
show_envvar=True,
|
||||
)
|
||||
# Boolean triggers
|
||||
@click.option(
|
||||
"--eve-ng",
|
||||
is_flag=True,
|
||||
help="Run EVE-NG vEOS provisioning (only if CLI runs on an EVE-NG server)",
|
||||
default=False,
|
||||
)
|
||||
@click.option(
|
||||
"--disable-ztp",
|
||||
is_flag=True,
|
||||
help="Disable ZTP process in vEOS image (only available with --eve-ng)",
|
||||
default=False,
|
||||
show_envvar=True,
|
||||
)
|
||||
@click.option(
|
||||
"--import-docker",
|
||||
is_flag=True,
|
||||
help="Import docker image (only available with --image_type cEOSlab)",
|
||||
help="Import docker image to local docker",
|
||||
default=False,
|
||||
show_envvar=True,
|
||||
)
|
||||
@click.option(
|
||||
"--skip-download",
|
||||
is_flag=True,
|
||||
help="Skip download process - for debug only",
|
||||
default=False,
|
||||
)
|
||||
@click.option(
|
||||
"--docker-name",
|
||||
default="arista/ceos",
|
||||
help="Docker image name",
|
||||
show_default=True,
|
||||
show_envvar=True,
|
||||
)
|
||||
@click.option(
|
||||
"--docker-tag",
|
||||
default=None,
|
||||
help="Docker image tag",
|
||||
show_default=True,
|
||||
show_envvar=True,
|
||||
)
|
||||
@click.option(
|
||||
"--version",
|
||||
default=None,
|
||||
help="EOS version to download",
|
||||
show_default=True,
|
||||
show_envvar=True,
|
||||
)
|
||||
@click.option(
|
||||
"--release-type",
|
||||
default=RTYPE_FEATURE,
|
||||
help="Release type (M for Maintenance, F for Feature)",
|
||||
show_default=True,
|
||||
show_envvar=True,
|
||||
)
|
||||
@click.option(
|
||||
"--branch",
|
||||
default=None,
|
||||
help="Branch to download",
|
||||
show_default=True,
|
||||
show_envvar=True,
|
||||
)
|
||||
@click.option(
|
||||
"--dry-run",
|
||||
is_flag=True,
|
||||
help="Enable dry-run mode: only run code without system changes",
|
||||
default=False,
|
||||
)
|
||||
@click.pass_context
|
||||
def eos(
|
||||
ctx: click.Context,
|
||||
image_type: str,
|
||||
format: str,
|
||||
output: str,
|
||||
log_level: str,
|
||||
eve_ng: bool,
|
||||
disable_ztp: bool,
|
||||
import_docker: bool,
|
||||
skip_download: bool,
|
||||
docker_name: str,
|
||||
version: Union[str, None] = None,
|
||||
release_type: str = RTYPE_FEATURE,
|
||||
latest: bool = False,
|
||||
branch: Union[str, None] = None,
|
||||
docker_tag: str,
|
||||
version: Union[str, None],
|
||||
release_type: str,
|
||||
latest: bool,
|
||||
branch: Union[str, None],
|
||||
dry_run: bool,
|
||||
) -> int:
|
||||
# pylint: disable=R0917
|
||||
"""Download EOS image from Arista website"""
|
||||
console = Console()
|
||||
# Get from Context
|
||||
token = ctx.obj["token"]
|
||||
is_latest: bool = False
|
||||
if token is None or token == "":
|
||||
console.print(
|
||||
"❗ Token is unset ! Please configure ARISTA_TOKEN or use --token option",
|
||||
style="bold red",
|
||||
)
|
||||
sys.exit(1)
|
||||
|
||||
logger.remove()
|
||||
if log_level is not None:
|
||||
logger.add("eos-downloader.log", rotation="10 MB", level=log_level.upper())
|
||||
|
||||
console.print(
|
||||
"🪐 [bold blue]eos-downloader[/bold blue] is starting...",
|
||||
"""Download EOS image from Arista server."""
|
||||
# pylint: disable=unused-variable
|
||||
console, token, debug, log_level = initialize(ctx)
|
||||
version = search_version(
|
||||
console, token, version, latest, branch, format, release_type
|
||||
)
|
||||
console.print(f" - Image Type: {image_type}")
|
||||
console.print(f" - Version: {version}")
|
||||
|
||||
if version is not None:
|
||||
my_download = eos_downloader.eos.EOSDownloader(
|
||||
image=image_type,
|
||||
software="EOS",
|
||||
version=version,
|
||||
token=token,
|
||||
hash_method="sha512sum",
|
||||
if version is None:
|
||||
raise ValueError("Version is not set correctly")
|
||||
try:
|
||||
eos_dl_obj = EosXmlObject(
|
||||
searched_version=version, token=token, image_type=format
|
||||
)
|
||||
my_download.authenticate()
|
||||
except Exception:
|
||||
console.print_exception(show_locals=True)
|
||||
return 1
|
||||
|
||||
elif latest:
|
||||
is_latest = True
|
||||
my_download = eos_downloader.eos.EOSDownloader(
|
||||
image=image_type,
|
||||
software="EOS",
|
||||
version="unset",
|
||||
token=token,
|
||||
hash_method="sha512sum",
|
||||
)
|
||||
my_download.authenticate()
|
||||
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"
|
||||
cli = SoftManager(dry_run=dry_run)
|
||||
|
||||
if not skip_download:
|
||||
if not eve_ng:
|
||||
download_files(
|
||||
console, cli, eos_dl_obj, output, rich_interface=True, debug=debug
|
||||
)
|
||||
sys.exit(1)
|
||||
my_download.version = str(latest_version)
|
||||
|
||||
if eve_ng:
|
||||
my_download.provision_eve(noztp=disable_ztp, checksum=True)
|
||||
else:
|
||||
my_download.download_local(file_path=output, checksum=True)
|
||||
else:
|
||||
try:
|
||||
cli.provision_eve(eos_dl_obj, noztp=True)
|
||||
except Exception as e:
|
||||
if debug:
|
||||
console.print_exception(show_locals=True)
|
||||
else:
|
||||
console.print(f"\n[red]Exception raised: {e}[/red]")
|
||||
return 1
|
||||
|
||||
if import_docker:
|
||||
my_download.docker_import(image_name=docker_name, is_latest=is_latest)
|
||||
console.print("✅ processing done !")
|
||||
sys.exit(0)
|
||||
return handle_docker_import(
|
||||
console, cli, eos_dl_obj, output, docker_name, docker_tag, debug
|
||||
)
|
||||
|
||||
return 0
|
||||
|
||||
|
||||
@click.command(no_args_is_help=True)
|
||||
@click.pass_context
|
||||
@click.command()
|
||||
@click.option(
|
||||
"--format",
|
||||
default="upgrade",
|
||||
help="CVP Image type",
|
||||
type=click.Choice(CVP_IMAGE_TYPE),
|
||||
required=True,
|
||||
default="ova",
|
||||
help="Image format",
|
||||
show_default=True,
|
||||
show_envvar=True,
|
||||
)
|
||||
@click.option("--version", default=None, help="CVP version", type=str, required=True)
|
||||
@click.option(
|
||||
"--output",
|
||||
default=str(os.path.relpath(os.getcwd(), start=os.curdir)),
|
||||
help="Path to save image",
|
||||
type=click.Path(),
|
||||
show_default=True,
|
||||
show_envvar=True,
|
||||
)
|
||||
@click.option(
|
||||
"--log-level",
|
||||
"--log",
|
||||
help="Logging level of the command",
|
||||
default=None,
|
||||
type=click.Choice(
|
||||
["debug", "info", "warning", "error", "critical"], case_sensitive=False
|
||||
),
|
||||
"--latest",
|
||||
is_flag=True,
|
||||
help="Get latest version. If --branch is not use, get the latest branch with specific release type",
|
||||
default=False,
|
||||
show_envvar=True,
|
||||
)
|
||||
@click.option(
|
||||
"--version",
|
||||
default=None,
|
||||
help="EOS version to download",
|
||||
show_default=True,
|
||||
show_envvar=True,
|
||||
)
|
||||
@click.option(
|
||||
"--branch",
|
||||
default=None,
|
||||
help="Branch to download",
|
||||
show_default=True,
|
||||
show_envvar=True,
|
||||
)
|
||||
@click.option(
|
||||
"--dry-run",
|
||||
is_flag=True,
|
||||
help="Enable dry-run mode: only run code without system changes",
|
||||
default=False,
|
||||
)
|
||||
@click.pass_context
|
||||
def cvp(
|
||||
ctx: click.Context, version: str, format: str, output: str, log_level: str
|
||||
ctx: click.Context,
|
||||
latest: bool,
|
||||
format: str,
|
||||
output: str,
|
||||
version: Union[str, None],
|
||||
branch: Union[str, None],
|
||||
dry_run: bool = False,
|
||||
) -> int:
|
||||
"""Download CVP image from Arista website"""
|
||||
console = Console()
|
||||
# Get from Context
|
||||
token = ctx.obj["token"]
|
||||
if token is None or token == "":
|
||||
"""Download CVP image from Arista server."""
|
||||
# pylint: disable=unused-variable
|
||||
console, token, debug, log_level = initialize(ctx)
|
||||
|
||||
if version is not None:
|
||||
console.print(
|
||||
"❗ Token is unset ! Please configure ARISTA_TOKEN or use --token option",
|
||||
style="bold red",
|
||||
f"Searching for EOS version [green]{version}[/green] for [blue]{format}[/blue] format..."
|
||||
)
|
||||
elif latest:
|
||||
console.print(
|
||||
f"Searching for [blue]latest[/blue] EOS version for [blue]{format}[/blue] format..."
|
||||
)
|
||||
elif branch is not None:
|
||||
console.print(
|
||||
f"Searching for EOS [b]latest[/b] version for [blue]{branch}[/blue] branch for [blue]{format}[/blue] format..."
|
||||
)
|
||||
sys.exit(1)
|
||||
|
||||
logger.remove()
|
||||
if log_level is not None:
|
||||
logger.add("eos-downloader.log", rotation="10 MB", level=log_level.upper())
|
||||
if branch is not None or latest:
|
||||
try:
|
||||
querier = AristaXmlQuerier(token=token)
|
||||
version_obj = querier.latest(package="cvp", branch=branch)
|
||||
version = str(version_obj)
|
||||
except Exception as e:
|
||||
console.print(f"Token is set to: {token}")
|
||||
console.print_exception(show_locals=True)
|
||||
return 1
|
||||
|
||||
console.print(
|
||||
"🪐 [bold blue]eos-downloader[/bold blue] is starting...",
|
||||
)
|
||||
console.print(f" - Image Type: {format}")
|
||||
console.print(f" - Version: {version}")
|
||||
console.print(f"version to download is {version}")
|
||||
|
||||
my_download = eos_downloader.eos.EOSDownloader(
|
||||
image=format,
|
||||
software="CloudVision",
|
||||
version=version,
|
||||
token=token,
|
||||
hash_method="md5sum",
|
||||
if version is None:
|
||||
raise ValueError("Version is not set correctly")
|
||||
try:
|
||||
cvp_dl_obj = CvpXmlObject(
|
||||
searched_version=version, token=token, image_type=format
|
||||
)
|
||||
except Exception as e:
|
||||
if debug:
|
||||
console.print_exception(show_locals=True)
|
||||
else:
|
||||
console.print(f"\n[red]Exception raised: {e}[/red]")
|
||||
return 1
|
||||
|
||||
cli = SoftManager(dry_run=dry_run)
|
||||
download_files(
|
||||
console,
|
||||
cli,
|
||||
cvp_dl_obj,
|
||||
output,
|
||||
rich_interface=True,
|
||||
debug=debug,
|
||||
checksum_format="md5sum",
|
||||
)
|
||||
|
||||
my_download.authenticate()
|
||||
console.print(f"CVP file is saved under: {output}")
|
||||
return 0
|
||||
|
||||
my_download.download_local(file_path=output, checksum=False)
|
||||
console.print("✅ processing done !")
|
||||
sys.exit(0)
|
||||
|
||||
@click.command()
|
||||
@click.option(
|
||||
"--source",
|
||||
"-s",
|
||||
help="Image path to download from Arista Website",
|
||||
type=str,
|
||||
show_default=False,
|
||||
show_envvar=False,
|
||||
)
|
||||
@click.option(
|
||||
"--output",
|
||||
"-o",
|
||||
default=str(os.path.relpath(os.getcwd(), start=os.curdir)),
|
||||
help="Path to save downloaded package",
|
||||
type=click.Path(),
|
||||
show_default=True,
|
||||
show_envvar=True,
|
||||
)
|
||||
@click.option(
|
||||
"--import-docker",
|
||||
is_flag=True,
|
||||
help="Import docker image to local docker",
|
||||
default=False,
|
||||
show_envvar=True,
|
||||
)
|
||||
@click.option(
|
||||
"--docker-name",
|
||||
default="arista/ceos:raw",
|
||||
help="Docker image name",
|
||||
show_default=True,
|
||||
show_envvar=True,
|
||||
)
|
||||
@click.option(
|
||||
"--docker-tag",
|
||||
default="dev",
|
||||
help="Docker image tag",
|
||||
show_default=True,
|
||||
show_envvar=True,
|
||||
)
|
||||
@click.pass_context
|
||||
# pylint: disable=too-many-branches
|
||||
def path(
|
||||
ctx: click.Context,
|
||||
output: str,
|
||||
source: str,
|
||||
import_docker: bool,
|
||||
docker_name: str,
|
||||
docker_tag: str,
|
||||
) -> int:
|
||||
"""Download image from Arista server using direct path."""
|
||||
console, token, debug, log_level = initialize(ctx)
|
||||
|
||||
if source is None:
|
||||
console.print("[red]Source is not set correctly ![/red]")
|
||||
return 1
|
||||
|
||||
filename = os.path.basename(source)
|
||||
|
||||
console.print(f"Downloading file {filename} from source: {source}")
|
||||
console.print(f"Saving file to: {output}")
|
||||
|
||||
ar_server = AristaServer(token=token)
|
||||
|
||||
try:
|
||||
file_url = ar_server.get_url(source)
|
||||
if log_level == "debug":
|
||||
console.print(f"URL to download file is: {file_url}")
|
||||
except Exception as e:
|
||||
if debug:
|
||||
console.print_exception(show_locals=True)
|
||||
else:
|
||||
console.print(f"\n[red]Exception raised: {e}[/red]")
|
||||
return 1
|
||||
|
||||
if file_url is None:
|
||||
console.print("File URL is set to None when we expect a string")
|
||||
return 1
|
||||
|
||||
cli = SoftManager(dry_run=False)
|
||||
|
||||
try:
|
||||
cli.download_file(file_url, output, filename=filename)
|
||||
except Exception as e:
|
||||
if debug:
|
||||
console.print_exception(show_locals=True)
|
||||
else:
|
||||
console.print(f"\n[red]Exception raised: {e}[/red]")
|
||||
return 1
|
||||
|
||||
if import_docker:
|
||||
console.print(
|
||||
f"Importing docker image [green]{docker_name}:{docker_tag}[/green] from [blue]{os.path.join(output, filename)}[/blue]..."
|
||||
)
|
||||
|
||||
try:
|
||||
cli.import_docker(
|
||||
local_file_path=os.path.join(output, filename),
|
||||
docker_name=docker_name,
|
||||
docker_tag=docker_tag,
|
||||
)
|
||||
except FileNotFoundError:
|
||||
if debug:
|
||||
console.print_exception(show_locals=True)
|
||||
else:
|
||||
console.print(
|
||||
f"\n[red]File not found: {os.path.join(output, filename)}[/red]"
|
||||
)
|
||||
return 1
|
||||
|
||||
console.print(
|
||||
f"Docker image imported successfully: [green]{docker_name}:{docker_tag}[/green]"
|
||||
)
|
||||
|
||||
return 0
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue