diff --git a/azext_edge/constants.py b/azext_edge/constants.py index c51a8bd8b..01dbbcd62 100644 --- a/azext_edge/constants.py +++ b/azext_edge/constants.py @@ -7,7 +7,7 @@ import os -VERSION = "0.7.0a5" +VERSION = "0.7.0a6" EXTENSION_NAME = "azure-iot-ops" EXTENSION_ROOT = os.path.dirname(os.path.abspath(__file__)) USER_AGENT = "IotOperationsCliExtension/{}".format(VERSION) diff --git a/azext_edge/edge/providers/orchestration/connected_cluster.py b/azext_edge/edge/providers/orchestration/connected_cluster.py index 425c853db..5da0c5104 100644 --- a/azext_edge/edge/providers/orchestration/connected_cluster.py +++ b/azext_edge/edge/providers/orchestration/connected_cluster.py @@ -24,7 +24,7 @@ | where properties.ExtensionType startswith 'microsoft.iotoperations' or properties.ExtensionType =~ 'microsoft.deviceregistry.assets' or properties.ExtensionType =~ 'microsoft.azurekeyvaultsecretsprovider' - or properties.ExtensionType =~ 'microsoft.secretsynccontroller' + or properties.ExtensionType =~ 'microsoft.azure.secretstore' or properties.ExtensionType =~ 'microsoft.openservicemesh' or properties.ExtensionType =~ 'microsoft.arc.containerstorage' | project id, name, apiVersion diff --git a/azext_edge/edge/providers/orchestration/deletion.py b/azext_edge/edge/providers/orchestration/deletion.py index 12a02347e..6dd8186bd 100644 --- a/azext_edge/edge/providers/orchestration/deletion.py +++ b/azext_edge/edge/providers/orchestration/deletion.py @@ -92,7 +92,7 @@ def do_work(self, confirm_yes: Optional[bool] = None, force: Optional[bool] = No def _display_resource_tree(self): if self._render_progress: - print(self.resource_map.build_tree(hide_extensions=True)) + print(self.resource_map.build_tree(hide_extensions=not self.include_dependencies)) def _render_display(self, description: str): if self._render_progress: diff --git a/azext_edge/edge/providers/orchestration/targets.py b/azext_edge/edge/providers/orchestration/targets.py index 4e7a5e50b..93b8ffc9a 100644 --- a/azext_edge/edge/providers/orchestration/targets.py +++ b/azext_edge/edge/providers/orchestration/targets.py @@ -135,16 +135,9 @@ def _handle_apply_targets( def iot_operations_version(self): return IOT_OPERATIONS_VERSION_MONIKER - def get_extension_versions(self, in_display_format: bool = False) -> dict: + def get_extension_versions(self) -> dict: # Don't need a deep copy here. - version_map = M2_ENABLEMENT_TEMPLATE.content["variables"]["VERSIONS"].copy() - if not in_display_format: - return version_map - - display_desc = "[dim]" - for ver in version_map: - display_desc += f"• {ver}: {version_map[ver]}\n" - return display_desc[:-1] + "" + return M2_ENABLEMENT_TEMPLATE.content["variables"]["VERSIONS"].copy() def get_ops_enablement_template( self, @@ -324,8 +317,3 @@ def get_instance_kpis(self) -> dict: } return instance_kpis - - def get_enablement_kpis(self) -> dict: - enablement_kpis = {} - - return enablement_kpis diff --git a/azext_edge/edge/providers/orchestration/template.py b/azext_edge/edge/providers/orchestration/template.py index 770872bec..6672ecab5 100644 --- a/azext_edge/edge/providers/orchestration/template.py +++ b/azext_edge/edge/providers/orchestration/template.py @@ -50,13 +50,13 @@ def copy(self) -> "TemplateBlueprint": IOT_OPERATIONS_VERSION_MONIKER = "v0.7.0-preview" M2_ENABLEMENT_TEMPLATE = TemplateBlueprint( - commit_id="dec7ce40c138904c3cdfd593e27ddeaebfedf171", + commit_id="3e0da5b1e224df788b8db865a19ead150d5dcd1f", content={ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", "languageVersion": "2.0", "contentVersion": "1.0.0.0", "metadata": { - "_generator": {"name": "bicep", "version": "0.29.47.4906", "templateHash": "16646818348298548028"} + "_generator": {"name": "bicep", "version": "0.29.47.4906", "templateHash": "15814050749892782988"} }, "definitions": { "_1.AdvancedConfig": { @@ -217,9 +217,9 @@ def copy(self) -> "TemplateBlueprint": "AIO_EXTENSION_SCOPE": {"cluster": {"releaseNamespace": "azure-iot-operations"}}, "AIO_EXTENSION_SUFFIX": "[take(uniqueString(resourceId('Microsoft.Kubernetes/connectedClusters', parameters('clusterName'))), 5)]", "VERSIONS": { - "platform": "0.7.0-preview-rc20240816.2", - "aio": "0.7.6", - "secretSyncController": "0.5.1-100124415", + "platform": "0.7.5", + "aio": "0.7.13", + "secretSyncController": "0.6.4", "edgeStorageAccelerator": "2.1.0-preview", "openServiceMesh": "1.2.9", }, @@ -241,6 +241,7 @@ def copy(self) -> "TemplateBlueprint": "nonFaultTolerantStorageClass": "[coalesce(tryGet(tryGet(parameters('advancedConfig'), 'edgeStorageAccelerator'), 'diskStorageClass'), 'default,local-path')]", "kubernetesStorageClass": "[if(equals(tryGet(tryGet(parameters('advancedConfig'), 'edgeStorageAccelerator'), 'faultToleranceEnabled'), true()), variables('faultTolerantStorageClass'), variables('nonFaultTolerantStorageClass'))]", "defaultAioConfigurationSettings": { + "AgentOperationTimeoutInMinutes": 120, "connectors.values.mqttBroker.address": "[format('mqtts://{0}.{1}:{2}', variables('MQTT_SETTINGS').brokerListenerServiceName, variables('AIO_EXTENSION_SCOPE').cluster.releaseNamespace, variables('MQTT_SETTINGS').brokerListenerPort)]", "connectors.values.mqttBroker.serviceAccountTokenAudience": "[variables('MQTT_SETTINGS').serviceAccountAudience]", "connectors.values.opcPlcSimulation.deploy": "false", @@ -288,11 +289,9 @@ def copy(self) -> "TemplateBlueprint": "version": "[coalesce(tryGet(tryGet(parameters('advancedConfig'), 'platform'), 'version'), variables('VERSIONS').platform)]", "releaseTrain": "[coalesce(tryGet(tryGet(parameters('advancedConfig'), 'platform'), 'train'), variables('TRAINS').platform)]", "autoUpgradeMinorVersion": False, - "scope": "[variables('AIO_EXTENSION_SCOPE')]", + "scope": {"cluster": {"releaseNamespace": "cert-manager"}}, "configurationSettings": { - "rbac.cluster.admin": "true", - "aioTrust.enabled": "false", - "cert-manager.install": "[if(equals(parameters('trustConfig').source, 'SelfSigned'), 'true', 'false')]", + "installCertManager": "[if(equals(parameters('trustConfig').source, 'SelfSigned'), 'true', 'false')]", "installTrustManager": "[if(equals(parameters('trustConfig').source, 'SelfSigned'), 'true', 'false')]", }, }, @@ -305,11 +304,10 @@ def copy(self) -> "TemplateBlueprint": "name": "azure-secret-store", "identity": {"type": "SystemAssigned"}, "properties": { - "extensionType": "microsoft.secretsynccontroller", + "extensionType": "microsoft.azure.secretstore", "version": "[coalesce(tryGet(tryGet(parameters('advancedConfig'), 'secretSyncController'), 'version'), variables('VERSIONS').secretSyncController)]", "releaseTrain": "[coalesce(tryGet(tryGet(parameters('advancedConfig'), 'secretSyncController'), 'train'), variables('TRAINS').secretSyncController)]", "autoUpgradeMinorVersion": False, - "scope": "[variables('AIO_EXTENSION_SCOPE')]", "configurationSettings": { "rotationPollIntervalInSeconds": "120", "validatingAdmissionPolicies.applyPolicies": "false", @@ -369,6 +367,7 @@ def copy(self) -> "TemplateBlueprint": "value": [ "[extensionResourceId(resourceId('Microsoft.Kubernetes/connectedClusters', parameters('clusterName')), 'Microsoft.KubernetesConfiguration/extensions', format('azure-iot-operations-platform-{0}', variables('AIO_EXTENSION_SUFFIX')))]", "[extensionResourceId(resourceId('Microsoft.Kubernetes/connectedClusters', parameters('clusterName')), 'Microsoft.KubernetesConfiguration/extensions', format('azure-iot-operations-{0}', variables('AIO_EXTENSION_SUFFIX')))]", + "[extensionResourceId(resourceId('Microsoft.Kubernetes/connectedClusters', parameters('clusterName')), 'Microsoft.KubernetesConfiguration/extensions', 'azure-secret-store')]", ], }, "extensions": { @@ -416,7 +415,7 @@ def copy(self) -> "TemplateBlueprint": ) M2_INSTANCE_TEMPLATE = TemplateBlueprint( - commit_id="dec7ce40c138904c3cdfd593e27ddeaebfedf171", + commit_id="a8b2a062ec924104180751b8c279fad9370ccefb", content={ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", "languageVersion": "2.0", diff --git a/azext_edge/edge/providers/orchestration/work.py b/azext_edge/edge/providers/orchestration/work.py index bae6e77ec..128af2e72 100644 --- a/azext_edge/edge/providers/orchestration/work.py +++ b/azext_edge/edge/providers/orchestration/work.py @@ -61,6 +61,7 @@ def __init__(self, title: str, description: Optional[str] = None): CONNECTIVITY_STATUS_CONNECTED = "Connected" IOT_OPS_EXTENSION_TYPE = "microsoft.iotoperations" IOT_OPS_PLAT_EXTENSION_TYPE = "microsoft.iotoperations.platform" +SECRET_SYNC_EXTENSION_TYPE = "microsoft.azure.secretstore" CONTRIBUTOR_ROLE_ID = "b24988ac-6180-42a0-ab88-20f7382dd24c" @@ -109,6 +110,20 @@ def _bootstrap_ux(self, show_progress: bool = False): self._show_progress = show_progress self._progress_shown = False + def _format_enablement_desc(self) -> str: + version_map = self._targets.get_extension_versions() + display_desc = "[dim]" + for ver in version_map: + display_desc += f"• {ver}: {version_map[ver]}\n" + return display_desc[:-1] + "" + + def _format_instance_desc(self) -> str: + instance_config = {"resource sync": "enabled" if self._targets.deploy_resource_sync_rules else "disabled"} + display_desc = "" + for c in instance_config: + display_desc += f"• {c}: {instance_config[c]}\n" + return display_desc[:-1] + "" + def _build_display(self): pre_check_cat_desc = "Pre-Flight" self._display.add_category(WorkCategoryKey.PRE_FLIGHT, pre_check_cat_desc, skipped=not self._pre_flight) @@ -122,23 +137,22 @@ def _build_display(self): self._display.add_step( WorkCategoryKey.ENABLE_IOT_OPS, WorkStepKey.WHAT_IF_ENABLEMENT, "What-If evaluation" ) - ext_version_display = self._targets.get_extension_versions(in_display_format=True) self._display.add_step( WorkCategoryKey.ENABLE_IOT_OPS, WorkStepKey.DEPLOY_ENABLEMENT, "Install foundation layer", - ext_version_display, + self._format_enablement_desc(), ) if self._targets.instance_name: - create_instance_desc = f"Create instance: [cyan]{self._targets.instance_name}" - self._display.add_category( + self._display.add_category(WorkCategoryKey.DEPLOY_IOT_OPS, "Deploy IoT Operations") + self._display.add_step(WorkCategoryKey.DEPLOY_IOT_OPS, WorkStepKey.WHAT_IF_INSTANCE, "What-If evaluation") + self._display.add_step( WorkCategoryKey.DEPLOY_IOT_OPS, - f"Deploy IoT Operations: [dark_orange3]{self._targets.iot_operations_version}", - skipped=not self._targets.instance_name, + WorkStepKey.DEPLOY_INSTANCE, + f"Create instance [cyan]{self._targets.instance_name}", + self._format_instance_desc(), ) - self._display.add_step(WorkCategoryKey.DEPLOY_IOT_OPS, WorkStepKey.WHAT_IF_INSTANCE, "What-If evaluation") - self._display.add_step(WorkCategoryKey.DEPLOY_IOT_OPS, WorkStepKey.DEPLOY_INSTANCE, create_instance_desc) def _process_connected_cluster(self) -> ConnectedCluster: connected_cluster = ConnectedCluster( @@ -202,7 +216,7 @@ def execute_ops_init( ): self._bootstrap_ux(show_progress=show_progress) self._work_id = uuid4().hex - self._work_format_str = f"aziotops.init.{{op}}.{self._work_id}" + self._work_format_str = f"aziotops.{{op}}.{self._work_id}" self._apply_foundation = apply_foundation self._pre_flight = pre_flight @@ -304,7 +318,7 @@ def _do_work(self): # noqa: C901 _ = wait_for_terminal_state(enablement_poller) self._extension_map = connected_cluster.get_extensions_by_type( - IOT_OPS_EXTENSION_TYPE, IOT_OPS_PLAT_EXTENSION_TYPE + IOT_OPS_EXTENSION_TYPE, IOT_OPS_PLAT_EXTENSION_TYPE, SECRET_SYNC_EXTENSION_TYPE ) self.permission_manager.apply_role_assignment( scope=self._targets.schema_registry_resource_id, @@ -327,7 +341,7 @@ def _do_work(self): # noqa: C901 if self._targets.instance_name: if not self._extension_map: self._extension_map = connected_cluster.get_extensions_by_type( - IOT_OPS_EXTENSION_TYPE, IOT_OPS_PLAT_EXTENSION_TYPE + IOT_OPS_EXTENSION_TYPE, IOT_OPS_PLAT_EXTENSION_TYPE, SECRET_SYNC_EXTENSION_TYPE ) # TODO - @digmaun revisit if any(not v for v in self._extension_map.values()): diff --git a/azext_edge/tests/edge/orchestration/test_connected_cluster_unit.py b/azext_edge/tests/edge/orchestration/test_connected_cluster_unit.py index 3d701862e..f37b637e1 100644 --- a/azext_edge/tests/edge/orchestration/test_connected_cluster_unit.py +++ b/azext_edge/tests/edge/orchestration/test_connected_cluster_unit.py @@ -84,7 +84,7 @@ def _assert_query_result( | where properties.ExtensionType startswith 'microsoft.iotoperations' or properties.ExtensionType =~ 'microsoft.deviceregistry.assets' or properties.ExtensionType =~ 'microsoft.azurekeyvaultsecretsprovider' - or properties.ExtensionType =~ 'microsoft.secretsynccontroller' + or properties.ExtensionType =~ 'microsoft.azure.secretstore' or properties.ExtensionType =~ 'microsoft.openservicemesh' or properties.ExtensionType =~ 'microsoft.arc.containerstorage' | project id, name, apiVersion