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

feat!: Upgrade rev.2 #467

Merged
merged 5 commits into from
Dec 19, 2024
Merged
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
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
![Python](https://img.shields.io/pypi/pyversions/azure-cli.svg?maxAge=2592000)
![Build](https://github.com/azure/azure-iot-ops-cli-extension/actions/workflows/release_workflow.yml/badge.svg)

The **Azure IoT Operations extension for Azure CLI** aims to accelerate the development, management and automation of Azure IoT Operations solutions. It does this via addition of rich features and functionality to the official [Azure CLI](https://docs.microsoft.com/en-us/cli/azure).
The **Azure IoT Operations extension for Azure CLI** aims to accelerate the development, management and automation of Azure IoT Operations solutions. It does this via addition of rich features and functionality to the official [Azure CLI](https://learn.microsoft.com/en-us/cli/azure).

## Pre-requisites

Expand Down
2 changes: 1 addition & 1 deletion azext_edge/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

import os

VERSION = "1.0.1a1"
VERSION = "1.1.0a1"
EXTENSION_NAME = "azure-iot-ops"
EXTENSION_ROOT = os.path.dirname(os.path.abspath(__file__))
USER_AGENT = "IotOperationsCliExtension/{}".format(VERSION)
23 changes: 13 additions & 10 deletions azext_edge/edge/_help.py
Original file line number Diff line number Diff line change
Expand Up @@ -574,24 +574,27 @@ def load_iotops_help():
"iot ops upgrade"
] = """
type: command
short-summary: Upgrade an IoT Operations instance to the latest version.
short-summary: Upgrade an IoT Operations instance.
long-summary: |
WARNING: This command may fail and require you to delete and re-create your cluster and instance.

Upgrade an IoT Operations instance, including updating the extensions to the latest versions.
Use this command if `az iot ops show` or similiar commands are failing.

Schema registry resource Id is an optional parameter and may be required in specific scenarios.
By default, with no options, the command will evaluate versions of the
deployed cluster side services that make up IoT Operations and compare them
with the built-in deployment that would be executed with `az iot ops init`
and `az iot ops create`.
examples:
- name: Upgrade the instance with minimal inputs.
text: >
az iot ops upgrade --name myinstance -g myresourcegroup
- name: Skip the conformation prompt during instance upgrade.
- name: Skip the confirmation prompt for instance upgrade. Useful for CI scenarios.
text: >
az iot ops upgrade --name myinstance -g myresourcegroup -y
- name: Upgrade the instance and specify the schema registry resource Id.
- name: Set extension config settings that apply should be during upgrade.
To remove a setting provide the key with no value.
text: >
az iot ops upgrade --name myinstance -g myresourcegroup --ops-config key1=value1 deletekey
- name: Provide an explicit IoT Operations version or release train to upgrade to.
Not recommended for typical use cases.
text: >
az iot ops upgrade --name myinstance -g myresourcegroup --sr-resource-id $SCHEMA_REGISTRY_RESOURCE_ID
az iot ops upgrade --name myinstance -g myresourcegroup --ops-version x.y.z --ops-train preview
digimaun marked this conversation as resolved.
Show resolved Hide resolved
"""

helps[
Expand Down
2 changes: 1 addition & 1 deletion azext_edge/edge/command_map.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ def load_iotops_commands(self, _):
) as cmd_group:
cmd_group.command("check", "check", is_preview=True)
cmd_group.command("init", "init")
cmd_group.command("upgrade", "upgrade", deprecate_info=cmd_group.deprecate(hide=True))
cmd_group.command("create", "create_instance")
cmd_group.command("upgrade", "upgrade_instance")
cmd_group.command("update", "update_instance")
cmd_group.show_command("show", "show_instance")
cmd_group.command("list", "list_instances")
Expand Down
40 changes: 34 additions & 6 deletions azext_edge/edge/commands_edge.py
Original file line number Diff line number Diff line change
Expand Up @@ -220,24 +220,52 @@ def create_instance(
pass


def upgrade(
def upgrade_instance(
cmd,
resource_group_name: str,
instance_name: str,
schema_registry_resource_id: Optional[str] = None,
no_progress: Optional[bool] = None,
confirm_yes: Optional[bool] = None,
ops_config: Optional[List[str]] = None,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we have a list of key value pairs that are actually accepted by the service? or do we assume that the service teams are the main consumers for this (and they would know the kv pairs themselves)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some user kvp's are described in AIO learn documentation intended for end users. Kvp's can be provided and used both internally and externally (power uses, troubleshooting etc) for whatever reasons.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

would be nice to include these in the long help but not necessary

ops_version: Optional[str] = None,
ops_train: Optional[str] = None,
acs_config: Optional[List[str]] = None,
acs_version: Optional[str] = None,
acs_train: Optional[str] = None,
osm_config: Optional[List[str]] = None,
osm_version: Optional[str] = None,
osm_train: Optional[str] = None,
ssc_config: Optional[List[str]] = None,
ssc_version: Optional[str] = None,
ssc_train: Optional[str] = None,
plat_config: Optional[List[str]] = None,
plat_version: Optional[str] = None,
plat_train: Optional[str] = None,
**kwargs,
):
from .providers.orchestration.upgrade import upgrade_ops_resources
) -> Optional[List[dict]]:
from .providers.orchestration.upgrade2 import upgrade_ops_instance

return upgrade_ops_resources(
return upgrade_ops_instance(
cmd=cmd,
resource_group_name=resource_group_name,
instance_name=instance_name,
sr_resource_id=schema_registry_resource_id,
no_progress=no_progress,
confirm_yes=confirm_yes,
ops_config=ops_config,
ops_version=ops_version,
ops_train=ops_train,
acs_config=acs_config,
acs_version=acs_version,
acs_train=acs_train,
osm_config=osm_config,
osm_version=osm_version,
osm_train=osm_train,
ssc_config=ssc_config,
ssc_version=ssc_version,
ssc_train=ssc_train,
plat_config=plat_config,
plat_version=plat_version,
plat_train=plat_train,
**kwargs,
)

Expand Down
42 changes: 33 additions & 9 deletions azext_edge/edge/params.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,19 +18,27 @@
from azext_edge.edge.providers.edge_api.dataflow import DataflowResourceKinds

from ._validators import validate_namespace, validate_resource_name
from .common import FileType, OpsServiceType, SecurityModes, SecurityPolicies, TopicRetain, AEPAuthModes
from .common import (
AEPAuthModes,
FileType,
OpsServiceType,
SecurityModes,
SecurityPolicies,
TopicRetain,
)
from .providers.check.common import ResourceOutputDetailLevel
from .providers.edge_api import (
DeviceRegistryResourceKinds,
MqResourceKinds,
OpcuaResourceKinds,
)
from .providers.orchestration.common import (
EXTENSION_MONIKER_TO_ALIAS_MAP,
TRUST_SETTING_KEYS,
IdentityUsageType,
KubernetesDistroType,
MqMemoryProfile,
MqServiceType,
TRUST_SETTING_KEYS,
SchemaFormat,
SchemaType,
)
Expand Down Expand Up @@ -498,13 +506,29 @@ def load_iotops_arguments(self, _):
)

with self.argument_context("iot ops upgrade") as context:
# Schema Registry
context.argument(
"schema_registry_resource_id",
options_list=["--sr-resource-id"],
help="The schema registry resource Id to use with IoT Operations. Required if the schema registry "
"resource Id is no longer found within IoT Operations.",
)
for moniker in EXTENSION_MONIKER_TO_ALIAS_MAP:
alias = EXTENSION_MONIKER_TO_ALIAS_MAP[moniker]
context.argument(
f"{alias}_config",
options_list=[f"--{alias}-config"],
nargs="+",
action="extend",
help=f"{moniker} arc extension custom configuration. Format is space-separated key=value pairs "
f"or just the key. This option can be used one or more times.",
arg_group="Extension Config",
)
context.argument(
f"{alias}_version",
options_list=[f"--{alias}-version"],
help=f"Use to override the built-in {moniker} arc extension version. ",
arg_group="Extension Config",
)
context.argument(
f"{alias}_train",
options_list=[f"--{alias}-train"],
help=f"Use to override the built-in {moniker} arc extension release train. ",
arg_group="Extension Config",
)

with self.argument_context("iot ops delete") as context:
context.argument(
Expand Down
30 changes: 29 additions & 1 deletion azext_edge/edge/providers/orchestration/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
AIO_INSECURE_LISTENER_SERVICE_PORT = 1883

TRUST_ISSUER_KIND_KEY = "issuerKind"
TRUST_SETTING_KEYS = frozenset(["issuerName", TRUST_ISSUER_KIND_KEY, "configMapName", "configMapKey"])
TRUST_SETTING_KEYS = ["issuerName", TRUST_ISSUER_KIND_KEY, "configMapName", "configMapKey"]

EXTENSION_TYPE_PLATFORM = "microsoft.iotoperations.platform"
EXTENSION_TYPE_OSM = "microsoft.openservicemesh"
Expand All @@ -40,6 +40,34 @@

OPS_EXTENSION_DEPS = frozenset([EXTENSION_TYPE_PLATFORM, EXTENSION_TYPE_OSM, EXTENSION_TYPE_SSC, EXTENSION_TYPE_ACS])

EXTENSION_TYPE_TO_MONIKER_MAP = {
EXTENSION_TYPE_PLATFORM: "platform",
EXTENSION_TYPE_OSM: "openServiceMesh",
EXTENSION_TYPE_ACS: "containerStorage",
EXTENSION_TYPE_SSC: "secretStore",
EXTENSION_TYPE_OPS: "iotOperations",
}

EXTENSION_MONIKER_TO_ALIAS_MAP = {
"platform": "plat",
"openServiceMesh": "osm",
"secretStore": "ssc",
"containerStorage": "acs",
"iotOperations": "ops",
}

EXTENSION_ALIAS_TO_TYPE_MAP = {
"plat": EXTENSION_TYPE_PLATFORM,
"osm": EXTENSION_TYPE_OSM,
"ssc": EXTENSION_TYPE_SSC,
"acs": EXTENSION_TYPE_ACS,
"ops": EXTENSION_TYPE_OPS,
}
digimaun marked this conversation as resolved.
Show resolved Hide resolved


class ClusterConnectStatus(Enum):
CONNECTED = "Connected"


class MqMode(Enum):
auto = "auto"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ def update_cluster_extension(
cluster_name: str,
extension_name: str,
update_payload: dict,
**client_kwargs,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: can prob remove line 54

) -> Iterable[dict]:
return wait_for_terminal_state(
self.ops.begin_update(
Expand All @@ -67,5 +68,6 @@ def update_cluster_extension(
cluster_name=cluster_name,
extension_name=extension_name,
patch_extension=update_payload,
**client_kwargs,
)
)
Loading
Loading