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: init changes for 0.0.4* #46

Merged
merged 9 commits into from
Oct 13, 2023
Merged
Show file tree
Hide file tree
Changes from 5 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
3 changes: 0 additions & 3 deletions azext_edge/edge/commands_edge.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@

from .providers.base import load_config_context
from .providers.support.base import get_bundle_path
from .common import DeployablePasVersions
from .providers.check.common import ResourceOutputDetailLevel

logger = get_logger(__name__)
Expand Down Expand Up @@ -69,7 +68,6 @@ def init(
resource_group_name: str,
cluster_namespace: str = "default",
custom_location_namespace: Optional[str] = None,
pas_version: str = DeployablePasVersions.v012.value,
custom_location_name: Optional[str] = None,
show_pas_version: Optional[bool] = None,
custom_version: Optional[List[str]] = None,
Expand Down Expand Up @@ -116,7 +114,6 @@ def init(
custom_location_name=custom_location_name,
custom_location_namespace=custom_location_namespace,
resource_group_name=resource_group_name,
pas_version=pas_version,
location=location,
show_pas_version=show_pas_version,
custom_version=custom_version,
Expand Down
16 changes: 5 additions & 11 deletions azext_edge/edge/params.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
from azure.cli.core.commands.parameters import get_three_state_flag, get_enum_type
from knack.arguments import CaseInsensitiveList

from .common import DeployablePasVersions, SupportForEdgeServiceType
from .common import SupportForEdgeServiceType
from .providers.edge_api import E4kResourceKinds
from .providers.orchestration.pas_versions import EdgeServiceMoniker
from .providers.check.common import ResourceOutputDetailLevel
Expand Down Expand Up @@ -230,33 +230,27 @@ def load_iotedge_arguments(self, _):
help="Flag when set, will output the generated template intended for deployment.",
arg_group="Template",
)
context.argument(
"pas_version",
options_list=["--pas-version"],
help="The PAS bundle version to deploy.",
choices=CaseInsensitiveList(DeployablePasVersions.list()),
arg_group="PAS Version",
)
context.argument(
"show_pas_version",
options_list=["--show-version"],
options_list=["--pas-version"],
help="Summarize and show the versions of deployable components.",
arg_type=get_three_state_flag(),
arg_group="PAS Version",
)
context.argument(
"custom_version",
nargs="+",
options_list=["--custom-version"],
options_list=[context.deprecate(hide=True, target="--custom-version")],
help="Customize PAS deployment by specifying edge service versions. Usage takes "
"precedence over --aio-version. Use space-separated {key}={value} pairs where {key} "
"is the edge service moniker and {value} is the desired version. The following monikers "
f"may be used: {', '.join(EdgeServiceMoniker.list())}. Example: e4k=0.5.0 bluefin=0.3.0",
arg_group="PAS Version",
deprecate_info=context.deprecate(hide=True),
digimaun marked this conversation as resolved.
Show resolved Hide resolved
)
context.argument(
"only_deploy_custom",
options_list=["--only-custom"],
options_list=[context.deprecate(hide=True, target="--only-custom")],
arg_type=get_three_state_flag(),
help="Only deploy the edge services specified in --custom-version.",
arg_group="PAS Version",
Expand Down
5 changes: 5 additions & 0 deletions azext_edge/edge/providers/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,11 @@ def load_config_context(context_name: Optional[str] = None):
"""
Load default config using a specific context or 'current-context' if not specified.
"""
from ..util import set_log_level

# This will ensure --debug works with http(s) k8s interactions
set_log_level("urllib3.connectionpool")

config.load_kube_config(context=context_name)
_, current_config = config.list_kube_config_contexts()
global DEFAULT_NAMESPACE
Expand Down
2 changes: 2 additions & 0 deletions azext_edge/edge/providers/orchestration/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
EdgeExtensionName,
extension_name_to_type_map,
moniker_to_extension_type_map,
DEPLOYABLE_PAS_VERSION,
)


Expand All @@ -23,4 +24,5 @@
"EdgeExtensionName",
"extension_name_to_type_map",
"moniker_to_extension_type_map",
"DEPLOYABLE_PAS_VERSION",
]
53 changes: 36 additions & 17 deletions azext_edge/edge/providers/orchestration/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
get_pas_version_def,
extension_name_to_type_map,
EdgeExtensionName,
DEPLOYABLE_PAS_VERSION,
)
from ...util import get_timestamp_now_utc

Expand Down Expand Up @@ -267,7 +268,6 @@ def deploy(
resource_group_name: str,
custom_location_name: str,
custom_location_namespace: str,
pas_version: str,
**kwargs,
):
from uuid import uuid4
Expand All @@ -276,11 +276,12 @@ def deploy(
from azure.core.exceptions import HttpResponseError
from azure.identity import DefaultAzureCredential
from azure.mgmt.resource import ResourceManagementClient
from rich.console import Console
from rich.console import Console, NewLine
from rich.progress import Progress, SpinnerColumn, TimeElapsedColumn
from rich.table import Table
from rich.live import Live

version_def = process_deployable_version(pas_version, **kwargs)
version_def = process_deployable_version(**kwargs)
show_pas_version = kwargs.get("show_pas_version", False)
if show_pas_version:
console = Console()
Expand Down Expand Up @@ -356,14 +357,17 @@ def deploy(
no_progress: bool = kwargs.get("no_progress", False)
block: bool = kwargs.get("block", True)

with Progress(
SpinnerColumn(),
*Progress.get_default_columns(),
"Elapsed:",
TimeElapsedColumn(),
transient=False,
disable=(no_progress is True) or (block is False),
) as progress:
grid = Table.grid(expand=False)
with Live(grid, transient=True, refresh_per_second=8) as live:
init_progress = Progress(
SpinnerColumn(),
*Progress.get_default_columns(),
"Elapsed:",
TimeElapsedColumn(),
transient=False,
disable=(no_progress is True) or (block is False),
)

deployment_name = f"azedge.init.pas.{str(uuid4()).replace('-', '')}"
deployment_params = {
"properties": {
Expand All @@ -372,21 +376,36 @@ def deploy(
}
}

what_if = kwargs.get("what_if")
header = "Deployment: {} in progress..."
if what_if:
header = header.format("[orange3]What-If? analysis[/orange3]")
else:
header = header.format(f"[medium_purple4]{deployment_name}[/medium_purple4]")

grid = Table.grid(expand=False)
grid.add_column()

grid.add_row(NewLine(1))
grid.add_row(header)
grid.add_row(NewLine(1))
grid.add_row(init_progress)
live.update(grid, refresh=True)

try:
if kwargs.get("what_if"):
init_progress.add_task(description=f"PAS version: {version_def.version}", total=None)
if what_if:
from azure.cli.command_modules.resource.custom import format_what_if_operation_result

progress.add_task(description=f"What-if of deploying PAS version: {version_def.version}", total=None)
what_if_deployment = resource_client.deployments.begin_what_if(
resource_group_name=resource_group_name,
deployment_name=deployment_name,
parameters=deployment_params,
).result()
progress.stop()
init_progress.stop()
print(format_what_if_operation_result(what_if_operation_result=what_if_deployment))
return

progress.add_task(description=f"Deploying PAS version: {version_def.version}", total=None)
deployment = resource_client.deployments.begin_create_or_update(
resource_group_name=resource_group_name,
deployment_name=deployment_name,
Expand Down Expand Up @@ -422,10 +441,10 @@ def deploy(
return


def process_deployable_version(aio_version: str, **kwargs) -> PasVersionDef:
def process_deployable_version(**kwargs) -> PasVersionDef:
from ...util import assemble_nargs_to_dict

base_version_def = get_pas_version_def(version=aio_version)
base_version_def = get_pas_version_def(version=DEPLOYABLE_PAS_VERSION)
custom_version = kwargs.get("custom_version")
only_deploy_custom = kwargs.get("only_deploy_custom")

Expand Down
3 changes: 3 additions & 0 deletions azext_edge/edge/providers/orchestration/pas_versions.py
Original file line number Diff line number Diff line change
Expand Up @@ -120,3 +120,6 @@ def get_pas_version_def(version: str) -> PasVersionDef:
EdgeExtensionName.assets.value: "microsoft.deviceregistry.assets",
EdgeExtensionName.akri.value: "microsoft.akri",
}


DEPLOYABLE_PAS_VERSION = DeployablePasVersions.v012.value
4 changes: 2 additions & 2 deletions azext_edge/edge/util/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@
# Private distribution for NDA customers only. Governed by license terms at https://preview.e4k.dev/docs/use-terms/
# --------------------------------------------------------------------------------------------

from .common import assemble_nargs_to_dict, scantree, get_timestamp_now_utc
from .common import assemble_nargs_to_dict, scantree, get_timestamp_now_utc, set_log_level

__all__ = ["assemble_nargs_to_dict", "scantree", "get_timestamp_now_utc"]
__all__ = ["assemble_nargs_to_dict", "scantree", "get_timestamp_now_utc", "set_log_level"]
8 changes: 7 additions & 1 deletion azext_edge/edge/util/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,12 @@
# --------------------------------------------------------------------------------------------

"""
utility: Defines common utility functions and components.
common: Defines common utility functions and components.

"""

import os
import logging
from typing import List, Dict
from knack.log import get_logger

Expand Down Expand Up @@ -52,3 +53,8 @@ def get_timestamp_now_utc(format: str = "%Y-%m-%dT%H:%M:%S") -> str:

timestamp = datetime.now(timezone.utc).strftime(format)
return timestamp


def set_log_level(log_name: str, log_level: int = logging.DEBUG):
test = logging.getLogger(log_name)
test.setLevel(log_level)
26 changes: 11 additions & 15 deletions azext_edge/tests/edge/init/test_init_unit.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,24 @@
# Private distribution for NDA customers only. Governed by license terms at https://preview.e4k.dev/docs/use-terms/
# --------------------------------------------------------------------------------------------

from functools import partial
from typing import Dict, Optional

import pytest

from azext_edge.edge.commands_edge import init
from azext_edge.edge.common import DeployablePasVersions
from azext_edge.edge.providers.orchestration import EdgeServiceMoniker, extension_name_to_type_map, get_pas_version_def
from azext_edge.edge.providers.orchestration import (
EdgeServiceMoniker,
extension_name_to_type_map,
get_pas_version_def,
DEPLOYABLE_PAS_VERSION,
)
from azext_edge.edge.util import assemble_nargs_to_dict

from ...generators import generate_generic_id


@pytest.mark.parametrize(
"cluster_name,cluster_namespace,rg,custom_location_name,custom_location_namespace,location,pas_version,"
"cluster_name,cluster_namespace,rg,custom_location_name,custom_location_namespace,location,"
digimaun marked this conversation as resolved.
Show resolved Hide resolved
"processor_instance_name,simulate_plc,opcua_discovery_endpoint,create_sync_rules,"
"custom_version,target_name",
[
Expand All @@ -29,7 +32,6 @@
generate_generic_id(), # custom_location_name
generate_generic_id(), # custom_location_namespace
generate_generic_id(), # location
DeployablePasVersions.v012.value,
generate_generic_id(), # processor_instance_name
False, # simulate_plc
generate_generic_id(), # opcua_discovery_endpoint
Expand All @@ -44,7 +46,6 @@
None, # custom_location_name
None, # custom_location_namespace
None, # location
DeployablePasVersions.v012.value,
None, # processor_instance_name
True, # simulate_plc
None, # opcua_discovery_endpoint
Expand All @@ -63,16 +64,14 @@ def test_init_show_template(
custom_location_name,
custom_location_namespace,
location,
pas_version,
processor_instance_name,
simulate_plc,
opcua_discovery_endpoint,
create_sync_rules,
custom_version,
target_name,
):
partial_init = partial(
init,
template = init(
cmd=mocked_cmd,
cluster_name=cluster_name,
cluster_namespace=cluster_namespace,
Expand All @@ -86,16 +85,13 @@ def test_init_show_template(
create_sync_rules=create_sync_rules,
custom_version=custom_version,
target_name=target_name,
)

template = partial_init(
show_template=True,
pas_version=pas_version,
)

assert template["$schema"] == "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#"
assert template["metadata"]["description"] == "Az Edge CLI PAS deployment."
# TODO template versioning. Think about custom.
assert template["contentVersion"] == f"{pas_version}.0"
assert template["contentVersion"] == f"{DEPLOYABLE_PAS_VERSION}.0"

assert_template_variables(
variables=template["variables"],
Expand All @@ -110,7 +106,7 @@ def test_init_show_template(
cluster_namespace=cluster_namespace,
custom_location_name=custom_location_name,
custom_location_namespace=custom_location_namespace,
pas_version=pas_version,
pas_version=DEPLOYABLE_PAS_VERSION,
processor_instance_name=processor_instance_name,
simulate_plc=simulate_plc,
opcua_discovery_endpoint=opcua_discovery_endpoint,
Expand Down