From 08631217bec5bdd21b38c35c31db2a1cf343e16e Mon Sep 17 00:00:00 2001 From: william051200 Date: Thu, 12 Mar 2026 14:51:08 +0800 Subject: [PATCH 1/5] Migrate servicefabric --- .../command_modules/servicefabric/custom.py | 273 +++++++++++------- .../cli/command_modules/vm/operations/vmss.py | 28 +- 2 files changed, 197 insertions(+), 104 deletions(-) diff --git a/src/azure-cli/azure/cli/command_modules/servicefabric/custom.py b/src/azure-cli/azure/cli/command_modules/servicefabric/custom.py index fa76b4e8804..1d9f4354011 100644 --- a/src/azure-cli/azure/cli/command_modules/servicefabric/custom.py +++ b/src/azure-cli/azure/cli/command_modules/servicefabric/custom.py @@ -461,27 +461,29 @@ def _remove_common_name(cluster, certificate_common_name, certificate_issuer_thu def add_cluster_node(cmd, client, resource_group_name, cluster_name, node_type, number_of_nodes_to_add): + from ..vm.operations.vmss import VMSSCreate cli_ctx = cmd.cli_ctx number_of_nodes_to_add = int(number_of_nodes_to_add) if number_of_nodes_to_add <= 0: raise CLIError("--number-of-nodes-to-add must be greater than 0") - compute_client = compute_client_factory(cli_ctx) cluster = client.get(resource_group_name, cluster_name) node_types = [n for n in cluster.node_types if n.name.lower() == node_type.lower()] if node_types is None: raise CLIError("Failed to find the node type in the cluster") node_type = node_types[0] - vmss = _get_cluster_vmss_by_node_type(compute_client, resource_group_name, cluster.cluster_id, node_type.name) - vmss.sku.capacity = vmss.sku.capacity + number_of_nodes_to_add + vmss = _get_cluster_vmss_by_node_type(cmd, resource_group_name, cluster.cluster_id, node_type.name) + + vmss['sku']['capacity'] = vmss['sku']['capacity'] + number_of_nodes_to_add + vmss['resource_group'] = resource_group_name + vmss['vm_scale_set_name'] = vmss.name # update vmss - vmss_poll = compute_client.virtual_machine_scale_sets.begin_create_or_update( - resource_group_name, vmss.name, vmss) + vmss_poll = VMSSCreate(cli_ctx=cli_ctx)(command_args=vmss) LongRunningOperation(cli_ctx)(vmss_poll) # update cluster - node_type.vm_instance_count = vmss.sku.capacity + node_type.vm_instance_count = vmss['sku']['capacity'] patch_request = ClusterUpdateParameters(node_types=cluster.node_types) update_cluster_poll = client.begin_update(resource_group_name, cluster_name, patch_request) @@ -489,11 +491,11 @@ def add_cluster_node(cmd, client, resource_group_name, cluster_name, node_type, def remove_cluster_node(cmd, client, resource_group_name, cluster_name, node_type, number_of_nodes_to_remove): + from ..vm.operations.vmss import VMSSCreate cli_ctx = cmd.cli_ctx number_of_nodes_to_remove = int(number_of_nodes_to_remove) if number_of_nodes_to_remove <= 0: raise CLIError("--number-of-nodes-to-remove must be greater than 0") - compute_client = compute_client_factory(cli_ctx) cluster = client.get(resource_group_name, cluster_name) node_types = [n for n in cluster.node_types if n.name.lower() == node_type.lower()] if node_types is None or len(node_types) == 0: @@ -501,16 +503,17 @@ def remove_cluster_node(cmd, client, resource_group_name, cluster_name, node_typ node_type = node_types[0] reliability_required_instance_count = _get_target_instance(cluster.reliability_level) - vmss = _get_cluster_vmss_by_node_type(compute_client, resource_group_name, cluster.cluster_id, node_type.name) - vmss.sku.capacity = vmss.sku.capacity - number_of_nodes_to_remove - if vmss.sku.capacity < reliability_required_instance_count: + vmss = _get_cluster_vmss_by_node_type(cmd, resource_group_name, cluster.cluster_id, node_type.name) + vmss['sku']['capacity'] = vmss['sku']['capacity'] - number_of_nodes_to_remove + if vmss['sku']['capacity'] < reliability_required_instance_count: raise CLIError("Can't delete node since current reliability level is {} requires at least {} nodes.".format( cluster.reliability_level, reliability_required_instance_count)) # update vmss - vmss_poll = compute_client.virtual_machine_scale_sets.begin_create_or_update( - resource_group_name, vmss.name, vmss) + vmss['resource_group'] = resource_group_name + vmss['vm_scale_set_name'] = vmss.name + vmss_poll = VMSSCreate(cli_ctx=cli_ctx)(command_args=vmss) LongRunningOperation(cli_ctx)(vmss_poll) # update cluster @@ -533,14 +536,13 @@ def update_cluster_durability(cmd, client, resource_group_name, cluster_name, no curr_node_type_durability = node_type_ref.durability_level # get vmss extension durability - compute_client = compute_client_factory(cli_ctx) - vmss = _get_cluster_vmss_by_node_type(compute_client, resource_group_name, cluster.cluster_id, node_type) + vmss = _get_cluster_vmss_by_node_type(cmd, resource_group_name, cluster.cluster_id, node_type) fabric_ext_ref = _get_sf_vm_extension(vmss) if fabric_ext_ref is None: raise CLIError("Failed to find service fabric extension.") - curr_vmss_durability_level = fabric_ext_ref.settings['durabilityLevel'] + curr_vmss_durability_level = fabric_ext_ref.get('settings', {}).get('durabilityLevel', '') # check upgrade if curr_node_type_durability.lower() != curr_vmss_durability_level.lower(): @@ -557,10 +559,13 @@ def update_cluster_durability(cmd, client, resource_group_name, cluster_name, no LongRunningOperation(cli_ctx)(update_cluster_poll) # update vmss sf extension durability - if curr_vmss_durability_level.lower() != durability_level.lower(): - fabric_ext_ref.settings['durabilityLevel'] = durability_level - fabric_ext_ref.settings['enableParallelJobs'] = True - vmss_poll = compute_client.virtual_machine_scale_sets.begin_create_or_update(resource_group_name, vmss.name, vmss) + if curr_vmss_durability_level.lower() != durability_level.lower() and fabric_ext_ref.get('settings'): + from ..vm.operations.vmss import VMSSCreate + fabric_ext_ref['settings']['durabilityLevel'] = durability_level + fabric_ext_ref['settings']['enableParallelJobs'] = True + vmss['resource_group'] = resource_group_name + vmss['vm_scale_set_name'] = vmss.name + vmss_poll = VMSSCreate(cli_ctx=cmd.cli_ctx)(command_args=vmss) LongRunningOperation(cli_ctx)(vmss_poll) return client.get(resource_group_name, cluster_name) @@ -682,21 +687,23 @@ def update_cluster_reliability_level(cmd, if node_types is None: raise CLIError("Failed to find the node type in the cluster") node_type = node_types[0] - compute_client = compute_client_factory(cli_ctx) - vmss = _get_cluster_vmss_by_node_type(compute_client, resource_group_name, cluster.cluster_id, node_type.name) + vmss = _get_cluster_vmss_by_node_type(cmd, resource_group_name, cluster.cluster_id, node_type.name) if instance_target == instance_now: return cluster if instance_target > instance_now: - if vmss.sku.capacity < instance_target: + if vmss.get('sku', {}).get('capacity') and vmss.get('sku', {}).get('capacity') < instance_target: if auto_add_node is not True: raise CLIError('Please use --auto_add_node to automatically increase the nodes,{} requires {} nodes, but currenty there are {}'. format(reliability_level, instance_target, vmss.sku.capacity)) - vmss.sku.capacity = instance_target - vmss_poll = compute_client.virtual_machine_scale_sets.begin_create_or_update( - resource_group_name, vmss.name, vmss) + vmss['sku']['capacity'] = instance_target + from ..vm.operations.vmss import VMSSCreate + vmss['resource_group'] = resource_group_name + vmss['vm_scale_set_name'] = vmss.name + vmss_poll = VMSSCreate(cli_ctx=cmd.cli_ctx)(command_args=vmss) LongRunningOperation(cli_ctx)(vmss_poll) - node_type.vm_instance_count = vmss.sku.capacity + if vmss.get('sku', {}).get('capacity'): + node_type.vm_instance_count = vmss['sku']['capacity'] patch_request = ClusterUpdateParameters( node_types=cluster.node_types, reliability_level=reliability_level) update_cluster_poll = client.begin_update(resource_group_name, cluster_name, patch_request) @@ -750,6 +757,7 @@ def _create_vmss(cmd, resource_group_name, cluster_name, cluster, node_type_name from .aaz.latest.network.public_ip import Create as PublicIPCreate from .aaz.latest.network.vnet import List as VNetList from .aaz.latest.network.vnet.subnet import Create as SubnetCreate, List as SubnetList + from ..vm.operations.vmss import VMSSCreate cli_ctx = cmd.cli_ctx subnet_name = "subnet_{}".format(1) @@ -876,9 +884,9 @@ def _create_vmss(cmd, resource_group_name, cluster_name, cluster, node_type_name backend_address_pools = [] inbound_nat_pools = [] for p in new_load_balancer["backendAddressPools"]: - backend_address_pools.append(SubResource(id=p["id"])) + backend_address_pools.append({'id': p["id"]}) for p in new_load_balancer["inboundNatPools"]: - inbound_nat_pools.append(SubResource(id=p["id"])) + inbound_nat_pools.append({'id': p["id"]}) network_config_name = 'NIC-{}-{}'.format(node_type_name.lower(), node_type_name.lower()) if len(network_config_name) >= 24: @@ -887,16 +895,24 @@ def _create_vmss(cmd, resource_group_name, cluster_name, cluster, node_type_name ip_config_name = 'Nic-{}'.format(node_type_name.lower()) if len(ip_config_name) >= 24: ip_config_name = network_config_name[0:22] - vm_network_profile = VirtualMachineScaleSetNetworkProfile(network_interface_configurations=[VirtualMachineScaleSetNetworkConfiguration(name=network_config_name, - primary=True, - ip_configurations=[VirtualMachineScaleSetIPConfiguration(name=ip_config_name, - load_balancer_backend_address_pools=backend_address_pools, - load_balancer_inbound_nat_pools=inbound_nat_pools, - subnet=ApiEntityReference(id=subnet["id"]))])]) - compute_client = compute_client_factory(cli_ctx) + + vm_network_profile = { + 'network_interface_configurations': [{ + 'name': network_config_name, + 'ip_configurations': [{ + 'name': ip_config_name, + 'load_balancer_backend_address_pools': backend_address_pools, + 'load_balancer_inbound_nat_pools': inbound_nat_pools, + 'subnet': { + 'id': subnet["id"] + } + }], + 'primary': True + }] + } node_type_name_ref = cluster.node_types[0].name - vmss_reference = _get_cluster_vmss_by_node_type(compute_client, resource_group_name, cluster.cluster_id, node_type_name_ref) + vmss_reference = _get_cluster_vmss_by_node_type(cmd, resource_group_name, cluster.cluster_id, node_type_name_ref) def create_vhd(cli_ctx, resource_group_name, cluster_name, node_type, location): storage_name = '{}{}'.format(cluster_name.lower(), node_type.lower()) @@ -939,29 +955,39 @@ def create_storage_account(cli_ctx, resource_group_name, storage_name, location) offer = 'UbuntuServer' version = 'latest' sku = os_dic['UbuntuServer1604'] - storage_profile = VirtualMachineScaleSetStorageProfile(image_reference=ImageReference(publisher=publisher, - offer=offer, - sku=sku, - version=version), - os_disk=VirtualMachineScaleSetOSDisk(caching='ReadOnly', - create_option='FromImage', - name='vmssosdisk', - vhd_containers=create_vhd(cli_ctx, resource_group_name, cluster_name, node_type_name, location))) - - os_profile = VirtualMachineScaleSetOSProfile(computer_name_prefix=node_type_name, - admin_password=vm_password, - admin_username=vm_user_name, - secrets=vmss_reference.virtual_machine_profile.os_profile.secrets) + + storage_profile = { + 'image_reference': { + 'offer': offer, + 'publisher': publisher, + 'sku': sku, + 'version': version + }, + 'os_disk': { + 'caching': 'ReadOnly', + 'create_option': 'FromImage', + 'name': 'vmssosdisk', + 'vhd_containers': create_vhd(cli_ctx, resource_group_name, cluster_name, node_type_name, location) + } + } + + os_profile = { + 'admin_password': vm_password, + 'admin_username': vm_user_name, + 'computer_name_prefix': node_type_name, + 'secrets': vmss_reference.get('virtual_machine_profile', {}).get('os_profile', {}).get('secrets', []) + } diagnostics_storage_name = cluster.diagnostics_storage_account_config.storage_account_name diagnostics_ext = None fabric_ext = None - diagnostics_exts = [e for e in vmss_reference.virtual_machine_profile.extension_profile.extensions if e.type_properties_type.lower( - ) == 'IaaSDiagnostics'.lower()] + diagnostics_exts = [ + e for e in vmss_reference.get('virtual_machine_profile', {}).get('extension_profile', {}).get('extensions', []) + if e.get('type', '').lower() == 'IaaSDiagnostics'.lower()] if any(diagnostics_exts): diagnostics_ext = diagnostics_exts[0] - diagnostics_account = diagnostics_ext.settings['StorageAccount'] + diagnostics_account = diagnostics_ext.get('settings', {}).get('StorageAccount') storage_client = storage_client_factory(cli_ctx) list_results = storage_client.storage_accounts.list_keys( resource_group_name, diagnostics_account) @@ -971,62 +997,85 @@ def create_storage_account(cli_ctx, resource_group_name, storage_name, location) json_data['storageAccountName'] = diagnostics_account json_data['storageAccountKey'] = list_results.keys[0].value json_data['storageAccountEndPoint'] = "https://core.windows.net/" - diagnostics_ext.protected_settings = json_data + diagnostics_ext['protectedSettings'] = json_data + + fabric_exts = [ + e for e in vmss_reference.get('virtual_machine_profile', {}).get('extension_profile', {}).get('extensions', []) + if e.get('type', '').lower() in [SERVICE_FABRIC_WINDOWS_NODE_EXT_NAME, SERVICE_FABRIC_LINUX_NODE_EXT_NAME]] - fabric_exts = [e for e in vmss_reference.virtual_machine_profile.extension_profile.extensions if e.type_properties_type.lower( - ) == SERVICE_FABRIC_WINDOWS_NODE_EXT_NAME or e.type_properties_type.lower() == SERVICE_FABRIC_LINUX_NODE_EXT_NAME] if any(fabric_exts): fabric_ext = fabric_exts[0] if fabric_ext is None: raise CLIError("No valid fabric extension found") - fabric_ext.settings['nodeTypeRef'] = node_type_name - fabric_ext.settings['durabilityLevel'] = durability_level - if 'nicPrefixOverride' not in fabric_ext.settings: - fabric_ext.settings['nicPrefixOverride'] = address_prefix + if not fabric_ext.get('settings'): + fabric_ext['settings'] = {} + + fabric_ext['settings']['nodeTypeRef'] = node_type_name + fabric_ext['settings']['durabilityLevel'] = durability_level + if 'nicPrefixOverride' not in fabric_ext['settings']: + fabric_ext['settings']['nicPrefixOverride'] = address_prefix storage_client = storage_client_factory(cli_ctx) list_results = storage_client.storage_accounts.list_keys( resource_group_name, diagnostics_storage_name) import json json_data = json.loads( '{"StorageAccountKey1": "", "StorageAccountKey2": ""}') - fabric_ext.protected_settings = json_data - fabric_ext.protected_settings['StorageAccountKey1'] = list_results.keys[0].value - fabric_ext.protected_settings['StorageAccountKey2'] = list_results.keys[1].value + fabric_ext['protected_settings'] = json_data + fabric_ext['protected_settings']['StorageAccountKey1'] = list_results.keys[0].value + fabric_ext['protected_settings']['StorageAccountKey2'] = list_results.keys[1].value extensions = [fabric_ext] if diagnostics_ext: extensions.append(diagnostics_ext) - vm_ext_profile = VirtualMachineScaleSetExtensionProfile( - extensions=extensions) - - virtual_machine_scale_set_profile = VirtualMachineScaleSetVMProfile(extension_profile=vm_ext_profile, - os_profile=os_profile, - storage_profile=storage_profile, - network_profile=vm_network_profile) - - poller = compute_client.virtual_machine_scale_sets.begin_create_or_update(resource_group_name, - node_type_name, - VirtualMachineScaleSet(location=location, - sku=ComputeSku(name=vm_sku, tier=vm_tier, capacity=capacity), - overprovision=False, - upgrade_policy=UpgradePolicy(mode=UpgradeMode.automatic), - virtual_machine_profile=virtual_machine_scale_set_profile)) - LongRunningOperation(cli_ctx)(poller) + vm_ext_profile = { + 'extensions': extensions + } + + virtual_machine_scale_set_profile = { + 'extension_profile': vm_ext_profile, + 'network_profile': vm_network_profile, + 'os_profile': os_profile, + 'storage_profile': storage_profile + } -def _get_cluster_vmss_by_node_type(compute_client, resource_group_name, cluster_id, node_type_name): + command_args = { + 'resource_group': resource_group_name, + 'vm_scale_set_name': node_type_name, + 'location': location, + 'sku': { + 'capacity': capacity, + 'name': vm_sku, + 'tier': vm_tier + }, + 'overprovision': False, + 'upgrade_policy': { + 'mode': 'Automatic' + }, + 'virtual_machine_profile': virtual_machine_scale_set_profile + } + poller = VMSSCreate(cli_ctx=cmd.cli_ctx)(command_args=command_args) + LongRunningOperation(cli_ctx)(poller) - vmsses = list(compute_client.virtual_machine_scale_sets.list(resource_group_name)) + +def _get_cluster_vmss_by_node_type(cmd, resource_group_name, cluster_id, node_type_name): + from ..vm.operations.vmss import VMSSList, convert_show_result_to_snake_case + vmsses = VMSSList(cli_ctx=cmd.cli_ctx)(command_args={ + 'resource_group': resource_group_name + }) for vmss in vmsses: + vmss = convert_show_result_to_snake_case(vmss) fabric_ext = _get_sf_vm_extension(vmss) if fabric_ext is not None: curr_cluster_id = _get_cluster_id_in_sf_extension(fabric_ext) - if curr_cluster_id.lower() == cluster_id.lower() and fabric_ext.settings["nodeTypeRef"].lower() == node_type_name.lower(): + if (curr_cluster_id.lower() == cluster_id.lower() and + fabric_ext.get('settings', {}).get('nodeTypeRef', '').lower() == node_type_name.lower()): return vmss - raise CLIError("Failed to find vmss in resource group {} for cluster id {} and node type {}".format(resource_group_name, cluster_id, node_type_name)) + raise CLIError("Failed to find vmss in resource group {} for cluster id {} and node type {}".format( + resource_group_name, cluster_id, node_type_name)) def _verify_cert_function_parameter(certificate_file=None, @@ -1159,17 +1208,28 @@ def _create_certificate(cmd, # pylint: disable=inconsistent-return-statements def _add_cert_to_vmss(cli_ctx, vmss, resource_group_name, vault_id, secret_url): - compute_client = compute_client_factory(cli_ctx) - secrets = [ - s for s in vmss.virtual_machine_profile.os_profile.secrets if s.source_vault.id == vault_id] + from ..vm.operations.vmss import VMSSCreate + + secrets = [s for s in vmss.get('virtual_machine_profile', {}).get('os_profile', {}).get('secrets', []) + if s.get('source_vault', {}).get('id') == vault_id] if secrets is None or secrets == []: - if vmss.virtual_machine_profile.os_profile.secrets is None: - vmss.virtual_machine_profile.os_profile.secrets = [] + if vmss.get('virtual_machine_profile', {}).get('os_profile', {}).get('secrets') is None: + if not vmss.get('virtual_machine_profile'): + vmss['virtual_machine_profile'] = {} + if not vmss['virtual_machine_profile'].get('os_profile'): + vmss['virtual_machine_profile']['os_profile'] = {} + vmss['virtual_machine_profile']['os_profile']['secrets'] = [] new_vault_certificates = [] - new_vault_certificates.append(VaultCertificate(certificate_url=secret_url, certificate_store='my')) - new_source_vault = SubResource(id=vault_id) - vmss.virtual_machine_profile.os_profile.secrets.append(VaultSecretGroup(source_vault=new_source_vault, - vault_certificates=new_vault_certificates)) + new_vault_certificates.append({ + 'certificate_store': 'my', + 'certificate_url': secret_url + }) + vmss['virtual_machine_profile']['os_profile']['secrets'].append({ + 'source_vault': { + 'id': vault_id + }, + 'vault_certificates': new_vault_certificates + }) else: if secrets[0].vault_certificates is not None: certs = [ @@ -1184,19 +1244,20 @@ def _add_cert_to_vmss(cli_ctx, vmss, resource_group_name, vault_id, secret_url): secrets[0].vault_certificates.append( VaultCertificate(secret_url, 'my')) - poller = compute_client.virtual_machine_scale_sets.begin_create_or_update( - resource_group_name, vmss.name, vmss) + vmss['resource_group'] = resource_group_name + vmss['vm_scale_set_name'] = vmss.name + poller = VMSSCreate(cli_ctx=cli_ctx)(command_args=vmss) return LongRunningOperation(cli_ctx)(poller) def _get_sf_vm_extension(vmss): fabric_ext = None - for ext in vmss.virtual_machine_profile.extension_profile.extensions: + for ext in vmss.get('virtual_machine_profile', {}).get('extension_profile', {}).get('extensions', []): extension_type = None - if hasattr(ext, 'type1') and ext.type1 is not None: - extension_type = ext.type1.lower() - elif hasattr(ext, 'type_properties_type') and ext.type_properties_type is not None: - extension_type = ext.type_properties_type.lower() + if ext.get('type1'): + extension_type = ext['type1'].lower() + if ext.get('type'): + extension_type = ext['type'].lower() if extension_type is not None and extension_type in (SERVICE_FABRIC_WINDOWS_NODE_EXT_NAME, SERVICE_FABRIC_LINUX_NODE_EXT_NAME): fabric_ext = ext @@ -1208,19 +1269,22 @@ def _get_sf_vm_extension(vmss): def _get_cluster_id_in_sf_extension(fabric_ext): - cluster_endpoint = fabric_ext.settings["clusterEndpoint"] + cluster_endpoint = fabric_ext.get('settings', {}).get('clusterEndpoint') endpoint_list = cluster_endpoint.split('/') cluster_id = endpoint_list[len(endpoint_list) - 1] return cluster_id def _add_cert_to_all_vmss(cli_ctx, resource_group_name, cluster_id, vault_id, secret_url, is_cluster_cert=False, thumbprint=None): - threads = [] + from ..vm.operations.vmss import VMSSList, convert_show_result_to_snake_case import threading - compute_client = compute_client_factory(cli_ctx) - vmsses = list(compute_client.virtual_machine_scale_sets.list(resource_group_name)) + threads = [] + vmsses = VMSSList(cli_ctx=cli_ctx)(command_args={ + 'resource_group': resource_group_name + }) if vmsses is not None: for vmss in vmsses: + vmss = convert_show_result_to_snake_case(vmss) fabric_ext = _get_sf_vm_extension(vmss) if fabric_ext is not None and (cluster_id is None or _get_cluster_id_in_sf_extension(fabric_ext).lower() == cluster_id.lower()): @@ -1229,7 +1293,10 @@ def _add_cert_to_all_vmss(cli_ctx, resource_group_name, cluster_id, vault_id, se import json secondary_setting = json.loads( '{{"thumbprint":"{0}","x509StoreName":"{1}"}}'.format(thumbprint, 'my')) - fabric_ext.settings["certificateSecondary"] = secondary_setting + + if not fabric_ext.get('settings'): + fabric_ext['settings'] = {} + fabric_ext["settings"]["certificateSecondary"] = secondary_setting t = threading.Thread(target=_add_cert_to_vmss, args=[cli_ctx, vmss, resource_group_name, vault_id, secret_url]) t.start() diff --git a/src/azure-cli/azure/cli/command_modules/vm/operations/vmss.py b/src/azure-cli/azure/cli/command_modules/vm/operations/vmss.py index d2969fd73b6..7115d510dec 100644 --- a/src/azure-cli/azure/cli/command_modules/vm/operations/vmss.py +++ b/src/azure-cli/azure/cli/command_modules/vm/operations/vmss.py @@ -10,7 +10,8 @@ Start as _Start, Create as _VMSSCreate, Show as _VMSSShow, - Patch as _VMSSPatch) + Patch as _VMSSPatch, + List as _VMSSList) from azure.cli.core.aaz import AAZUndefined, has_value from .._vm_utils import IdentityType @@ -133,6 +134,31 @@ def __call__(self, *args, **kwargs): return self.on_error(session.http_response) +class VMSSList(_VMSSList): + class VirtualMachineScaleSetsList(_VMSSList.VirtualMachineScaleSetsList): + def _output(self, *args, **kwargs): + # Resolve flatten conflict + # When the type field conflicts, the type in inner layer is ignored and the outer layer is applied + for value in self.ctx.vars.instance.value: + if has_value(value.properties.virtual_machine_profile.extension_profile.extensions): + for extension in value.properties.virtual_machine_profile.extension_profile.extensions: + if has_value(extension.type): + extension.type = AAZUndefined + + return self.deserialize_output(self.ctx.vars.instance, client_flatten=True) + + class VirtualMachineScaleSetsListAll(_VMSSList.VirtualMachineScaleSetsListAll): + def _output(self, *args, **kwargs): + # Resolve flatten conflict + # When the type field conflicts, the type in inner layer is ignored and the outer layer is applied + for value in self.ctx.vars.instance.value: + if has_value(value.properties.virtual_machine_profile.extension_profile.extensions): + for extension in value.properties.virtual_machine_profile.extension_profile.extensions: + if has_value(extension.type): + extension.type = AAZUndefined + + return self.deserialize_output(self.ctx.vars.instance, client_flatten=True) + def convert_show_result_to_snake_case(result): new_result = {} if "extendedLocation" in result: From 71f2c9d1c356bbb2c9344539150a4cbe7d43a317 Mon Sep 17 00:00:00 2001 From: william051200 Date: Fri, 13 Mar 2026 10:19:41 +0800 Subject: [PATCH 2/5] Update code --- .../command_modules/servicefabric/custom.py | 67 +++++++------------ .../cli/command_modules/vm/operations/vmss.py | 1 + 2 files changed, 26 insertions(+), 42 deletions(-) diff --git a/src/azure-cli/azure/cli/command_modules/servicefabric/custom.py b/src/azure-cli/azure/cli/command_modules/servicefabric/custom.py index 1d9f4354011..23905128724 100644 --- a/src/azure-cli/azure/cli/command_modules/servicefabric/custom.py +++ b/src/azure-cli/azure/cli/command_modules/servicefabric/custom.py @@ -28,30 +28,12 @@ SettingsParameterDescription, NodeTypeDescription, EndpointRangeDescription) -from azure.mgmt.compute.models import (VaultCertificate, - Sku as ComputeSku, - UpgradePolicy, - ImageReference, - ApiEntityReference, - VaultSecretGroup, - VirtualMachineScaleSetOSDisk, - VirtualMachineScaleSetVMProfile, - VirtualMachineScaleSetExtensionProfile, - VirtualMachineScaleSetOSProfile, - VirtualMachineScaleSetStorageProfile, - VirtualMachineScaleSet, - VirtualMachineScaleSetNetworkConfiguration, - VirtualMachineScaleSetIPConfiguration, - VirtualMachineScaleSetNetworkProfile, - SubResource, - UpgradeMode) from azure.mgmt.storage.models import StorageAccountCreateParameters from knack.log import get_logger from ._client_factory import (resource_client_factory, keyvault_client_factory, - compute_client_factory, storage_client_factory) logger = get_logger(__name__) @@ -476,7 +458,7 @@ def add_cluster_node(cmd, client, resource_group_name, cluster_name, node_type, vmss['sku']['capacity'] = vmss['sku']['capacity'] + number_of_nodes_to_add vmss['resource_group'] = resource_group_name - vmss['vm_scale_set_name'] = vmss.name + vmss['vm_scale_set_name'] = vmss['name'] # update vmss vmss_poll = VMSSCreate(cli_ctx=cli_ctx)(command_args=vmss) @@ -512,7 +494,7 @@ def remove_cluster_node(cmd, client, resource_group_name, cluster_name, node_typ # update vmss vmss['resource_group'] = resource_group_name - vmss['vm_scale_set_name'] = vmss.name + vmss['vm_scale_set_name'] = vmss['name'] vmss_poll = VMSSCreate(cli_ctx=cli_ctx)(command_args=vmss) LongRunningOperation(cli_ctx)(vmss_poll) @@ -564,7 +546,7 @@ def update_cluster_durability(cmd, client, resource_group_name, cluster_name, no fabric_ext_ref['settings']['durabilityLevel'] = durability_level fabric_ext_ref['settings']['enableParallelJobs'] = True vmss['resource_group'] = resource_group_name - vmss['vm_scale_set_name'] = vmss.name + vmss['vm_scale_set_name'] = vmss['name'] vmss_poll = VMSSCreate(cli_ctx=cmd.cli_ctx)(command_args=vmss) LongRunningOperation(cli_ctx)(vmss_poll) @@ -691,18 +673,18 @@ def update_cluster_reliability_level(cmd, if instance_target == instance_now: return cluster if instance_target > instance_now: - if vmss.get('sku', {}).get('capacity') and vmss.get('sku', {}).get('capacity') < instance_target: + if vmss.get('sku', {}).get('capacity') is not None and vmss.get('sku', {}).get('capacity') < instance_target: if auto_add_node is not True: raise CLIError('Please use --auto_add_node to automatically increase the nodes,{} requires {} nodes, but currenty there are {}'. - format(reliability_level, instance_target, vmss.sku.capacity)) + format(reliability_level, instance_target, vmss['sku']['capacity'])) vmss['sku']['capacity'] = instance_target from ..vm.operations.vmss import VMSSCreate vmss['resource_group'] = resource_group_name - vmss['vm_scale_set_name'] = vmss.name + vmss['vm_scale_set_name'] = vmss['name'] vmss_poll = VMSSCreate(cli_ctx=cmd.cli_ctx)(command_args=vmss) LongRunningOperation(cli_ctx)(vmss_poll) - if vmss.get('sku', {}).get('capacity'): + if vmss.get('sku', {}).get('capacity') is not None: node_type.vm_instance_count = vmss['sku']['capacity'] patch_request = ClusterUpdateParameters( node_types=cluster.node_types, reliability_level=reliability_level) @@ -991,13 +973,11 @@ def create_storage_account(cli_ctx, resource_group_name, storage_name, location) storage_client = storage_client_factory(cli_ctx) list_results = storage_client.storage_accounts.list_keys( resource_group_name, diagnostics_account) - import json - json_data = json.loads( - '{"storageAccountName": "", "storageAccountKey": "", "storageAccountEndPoint": ""}') - json_data['storageAccountName'] = diagnostics_account - json_data['storageAccountKey'] = list_results.keys[0].value - json_data['storageAccountEndPoint'] = "https://core.windows.net/" - diagnostics_ext['protectedSettings'] = json_data + diagnostics_ext['protected_settings'] = { + 'storageAccountName': diagnostics_account, + 'storageAccountKey': list_results.keys[0].value, + 'storageAccountEndPoint': 'https://core.windows.net/' + } fabric_exts = [ e for e in vmss_reference.get('virtual_machine_profile', {}).get('extension_profile', {}).get('extensions', []) @@ -1231,21 +1211,24 @@ def _add_cert_to_vmss(cli_ctx, vmss, resource_group_name, vault_id, secret_url): 'vault_certificates': new_vault_certificates }) else: - if secrets[0].vault_certificates is not None: - certs = [ - c for c in secrets[0].vault_certificates if c.certificate_url == secret_url] + if secrets[0].get('vault_certificates') is not None: + certs = [c for c in secrets[0]['vault_certificates'] if c.get('certificate_url') == secret_url] if certs is None or certs == []: - secrets[0].vault_certificates.append( - VaultCertificate(certificate_url=secret_url, certificate_store='my')) + secrets[0]['vault_certificates'].append({ + 'certificate_store': 'my', + 'certificate_url': secret_url + }) else: return else: - secrets[0].vault_certificates = [] - secrets[0].vault_certificates.append( - VaultCertificate(secret_url, 'my')) + secrets[0]['vault_certificates'] = [] + secrets[0]['vault_certificates'].append({ + 'certificate_store': 'my', + 'certificate_url': secret_url + }) vmss['resource_group'] = resource_group_name - vmss['vm_scale_set_name'] = vmss.name + vmss['vm_scale_set_name'] = vmss['name'] poller = VMSSCreate(cli_ctx=cli_ctx)(command_args=vmss) return LongRunningOperation(cli_ctx)(poller) @@ -1256,7 +1239,7 @@ def _get_sf_vm_extension(vmss): extension_type = None if ext.get('type1'): extension_type = ext['type1'].lower() - if ext.get('type'): + elif ext.get('type'): extension_type = ext['type'].lower() if extension_type is not None and extension_type in (SERVICE_FABRIC_WINDOWS_NODE_EXT_NAME, SERVICE_FABRIC_LINUX_NODE_EXT_NAME): diff --git a/src/azure-cli/azure/cli/command_modules/vm/operations/vmss.py b/src/azure-cli/azure/cli/command_modules/vm/operations/vmss.py index 7115d510dec..d0315410bc6 100644 --- a/src/azure-cli/azure/cli/command_modules/vm/operations/vmss.py +++ b/src/azure-cli/azure/cli/command_modules/vm/operations/vmss.py @@ -159,6 +159,7 @@ def _output(self, *args, **kwargs): return self.deserialize_output(self.ctx.vars.instance, client_flatten=True) + def convert_show_result_to_snake_case(result): new_result = {} if "extendedLocation" in result: From 06d119c5d40516c3615f1ea181d97f987557c4da Mon Sep 17 00:00:00 2001 From: william051200 Date: Fri, 13 Mar 2026 12:05:09 +0800 Subject: [PATCH 3/5] Update code --- .../azure/cli/command_modules/servicefabric/custom.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/azure-cli/azure/cli/command_modules/servicefabric/custom.py b/src/azure-cli/azure/cli/command_modules/servicefabric/custom.py index 23905128724..5b6ad963a5b 100644 --- a/src/azure-cli/azure/cli/command_modules/servicefabric/custom.py +++ b/src/azure-cli/azure/cli/command_modules/servicefabric/custom.py @@ -1223,9 +1223,9 @@ def _add_cert_to_vmss(cli_ctx, vmss, resource_group_name, vault_id, secret_url): else: secrets[0]['vault_certificates'] = [] secrets[0]['vault_certificates'].append({ - 'certificate_store': 'my', - 'certificate_url': secret_url - }) + 'certificate_store': 'my', + 'certificate_url': secret_url + }) vmss['resource_group'] = resource_group_name vmss['vm_scale_set_name'] = vmss['name'] From 82fa9c277dd54fa56bb56eb6095d822d12f9a9e7 Mon Sep 17 00:00:00 2001 From: william051200 Date: Mon, 16 Mar 2026 08:21:42 +0800 Subject: [PATCH 4/5] Upgrade vmss list version --- .../vm/aaz/latest/vmss/_list.py | 440 +++++++++--------- 1 file changed, 217 insertions(+), 223 deletions(-) diff --git a/src/azure-cli/azure/cli/command_modules/vm/aaz/latest/vmss/_list.py b/src/azure-cli/azure/cli/command_modules/vm/aaz/latest/vmss/_list.py index 8a1b4e08957..a5d81f8e60f 100644 --- a/src/azure-cli/azure/cli/command_modules/vm/aaz/latest/vmss/_list.py +++ b/src/azure-cli/azure/cli/command_modules/vm/aaz/latest/vmss/_list.py @@ -22,10 +22,10 @@ class List(AAZCommand): """ _aaz_info = { - "version": "2023-09-01", + "version": "2024-11-01", "resources": [ - ["mgmt-plane", "/subscriptions/{}/providers/microsoft.compute/virtualmachinescalesets", "2023-09-01"], - ["mgmt-plane", "/subscriptions/{}/resourcegroups/{}/providers/microsoft.compute/virtualmachinescalesets", "2023-09-01"], + ["mgmt-plane", "/subscriptions/{}/providers/microsoft.compute/virtualmachinescalesets", "2024-11-01"], + ["mgmt-plane", "/subscriptions/{}/resourcegroups/{}/providers/microsoft.compute/virtualmachinescalesets", "2024-11-01"], ] } @@ -51,12 +51,12 @@ def _build_arguments_schema(cls, *args, **kwargs): def _execute_operations(self): self.pre_operations() - condition_0 = has_value(self.ctx.args.resource_group) and has_value(self.ctx.subscription_id) - condition_1 = has_value(self.ctx.subscription_id) and has_value(self.ctx.args.resource_group) is not True + condition_0 = has_value(self.ctx.subscription_id) and has_value(self.ctx.args.resource_group) is not True + condition_1 = has_value(self.ctx.args.resource_group) and has_value(self.ctx.subscription_id) if condition_0: - self.VirtualMachineScaleSetsList(ctx=self.ctx)() - if condition_1: self.VirtualMachineScaleSetsListAll(ctx=self.ctx)() + if condition_1: + self.VirtualMachineScaleSetsList(ctx=self.ctx)() self.post_operations() @register_callback @@ -72,7 +72,7 @@ def _output(self, *args, **kwargs): next_link = self.deserialize_output(self.ctx.vars.instance.next_link) return result, next_link - class VirtualMachineScaleSetsList(AAZHttpOperation): + class VirtualMachineScaleSetsListAll(AAZHttpOperation): CLIENT_TYPE = "MgmtClient" def __call__(self, *args, **kwargs): @@ -86,7 +86,7 @@ def __call__(self, *args, **kwargs): @property def url(self): return self.client.format_url( - "/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Compute/virtualMachineScaleSets", + "/subscriptions/{subscriptionId}/providers/Microsoft.Compute/virtualMachineScaleSets", **self.url_parameters ) @@ -101,10 +101,6 @@ def error_format(self): @property def url_parameters(self): parameters = { - **self.serialize_url_param( - "resourceGroupName", self.ctx.args.resource_group, - required=True, - ), **self.serialize_url_param( "subscriptionId", self.ctx.subscription_id, required=True, @@ -116,7 +112,7 @@ def url_parameters(self): def query_parameters(self): parameters = { **self.serialize_query_param( - "api-version", "2023-09-01", + "api-version", "2024-11-01", required=True, ), } @@ -267,9 +263,15 @@ def _build_schema_on_200(cls): properties.scale_in_policy = AAZObjectType( serialized_name="scaleInPolicy", ) + properties.scheduled_events_policy = AAZObjectType( + serialized_name="scheduledEventsPolicy", + ) properties.single_placement_group = AAZBoolType( serialized_name="singlePlacementGroup", ) + properties.sku_profile = AAZObjectType( + serialized_name="skuProfile", + ) properties.spot_restore_policy = AAZObjectType( serialized_name="spotRestorePolicy", ) @@ -287,6 +289,9 @@ def _build_schema_on_200(cls): properties.virtual_machine_profile = AAZObjectType( serialized_name="virtualMachineProfile", ) + properties.zonal_platform_fault_domain_align_mode = AAZStrType( + serialized_name="zonalPlatformFaultDomainAlignMode", + ) properties.zone_balance = AAZBoolType( serialized_name="zoneBalance", ) @@ -317,6 +322,9 @@ def _build_schema_on_200(cls): ) resiliency_policy = cls._schema_on_200.value.Element.properties.resiliency_policy + resiliency_policy.automatic_zone_rebalancing_policy = AAZObjectType( + serialized_name="automaticZoneRebalancingPolicy", + ) resiliency_policy.resilient_vm_creation_policy = AAZObjectType( serialized_name="resilientVMCreationPolicy", ) @@ -324,6 +332,15 @@ def _build_schema_on_200(cls): serialized_name="resilientVMDeletionPolicy", ) + automatic_zone_rebalancing_policy = cls._schema_on_200.value.Element.properties.resiliency_policy.automatic_zone_rebalancing_policy + automatic_zone_rebalancing_policy.enabled = AAZBoolType() + automatic_zone_rebalancing_policy.rebalance_behavior = AAZStrType( + serialized_name="rebalanceBehavior", + ) + automatic_zone_rebalancing_policy.rebalance_strategy = AAZStrType( + serialized_name="rebalanceStrategy", + ) + resilient_vm_creation_policy = cls._schema_on_200.value.Element.properties.resiliency_policy.resilient_vm_creation_policy resilient_vm_creation_policy.enabled = AAZBoolType() @@ -334,11 +351,58 @@ def _build_schema_on_200(cls): scale_in_policy.force_deletion = AAZBoolType( serialized_name="forceDeletion", ) + scale_in_policy.prioritize_unhealthy_v_ms = AAZBoolType( + serialized_name="prioritizeUnhealthyVMs", + ) scale_in_policy.rules = AAZListType() rules = cls._schema_on_200.value.Element.properties.scale_in_policy.rules rules.Element = AAZStrType() + scheduled_events_policy = cls._schema_on_200.value.Element.properties.scheduled_events_policy + scheduled_events_policy.scheduled_events_additional_publishing_targets = AAZObjectType( + serialized_name="scheduledEventsAdditionalPublishingTargets", + ) + scheduled_events_policy.user_initiated_reboot = AAZObjectType( + serialized_name="userInitiatedReboot", + ) + scheduled_events_policy.user_initiated_redeploy = AAZObjectType( + serialized_name="userInitiatedRedeploy", + ) + + scheduled_events_additional_publishing_targets = cls._schema_on_200.value.Element.properties.scheduled_events_policy.scheduled_events_additional_publishing_targets + scheduled_events_additional_publishing_targets.event_grid_and_resource_graph = AAZObjectType( + serialized_name="eventGridAndResourceGraph", + ) + + event_grid_and_resource_graph = cls._schema_on_200.value.Element.properties.scheduled_events_policy.scheduled_events_additional_publishing_targets.event_grid_and_resource_graph + event_grid_and_resource_graph.enable = AAZBoolType() + + user_initiated_reboot = cls._schema_on_200.value.Element.properties.scheduled_events_policy.user_initiated_reboot + user_initiated_reboot.automatically_approve = AAZBoolType( + serialized_name="automaticallyApprove", + ) + + user_initiated_redeploy = cls._schema_on_200.value.Element.properties.scheduled_events_policy.user_initiated_redeploy + user_initiated_redeploy.automatically_approve = AAZBoolType( + serialized_name="automaticallyApprove", + ) + + sku_profile = cls._schema_on_200.value.Element.properties.sku_profile + sku_profile.allocation_strategy = AAZStrType( + serialized_name="allocationStrategy", + ) + sku_profile.vm_sizes = AAZListType( + serialized_name="vmSizes", + ) + + vm_sizes = cls._schema_on_200.value.Element.properties.sku_profile.vm_sizes + vm_sizes.Element = AAZObjectType() + + _element = cls._schema_on_200.value.Element.properties.sku_profile.vm_sizes.Element + _element.name = AAZStrType() + _element.rank = AAZIntType() + spot_restore_policy = cls._schema_on_200.value.Element.properties.spot_restore_policy spot_restore_policy.enabled = AAZBoolType() spot_restore_policy.restore_timeout = AAZStrType( @@ -527,13 +591,12 @@ def _build_schema_on_200(cls): properties.force_update_tag = AAZStrType( serialized_name="forceUpdateTag", ) - properties.protected_settings = AAZObjectType( + properties.protected_settings = AAZFreeFormDictType( serialized_name="protectedSettings", ) properties.protected_settings_from_key_vault = AAZObjectType( serialized_name="protectedSettingsFromKeyVault", ) - _ListHelper._build_schema_key_vault_secret_reference_read(properties.protected_settings_from_key_vault) properties.provision_after_extensions = AAZListType( serialized_name="provisionAfterExtensions", ) @@ -542,7 +605,7 @@ def _build_schema_on_200(cls): flags={"read_only": True}, ) properties.publisher = AAZStrType() - properties.settings = AAZObjectType() + properties.settings = AAZFreeFormDictType() properties.suppress_failures = AAZBoolType( serialized_name="suppressFailures", ) @@ -551,6 +614,17 @@ def _build_schema_on_200(cls): serialized_name="typeHandlerVersion", ) + protected_settings_from_key_vault = cls._schema_on_200.value.Element.properties.virtual_machine_profile.extension_profile.extensions.Element.properties.protected_settings_from_key_vault + protected_settings_from_key_vault.secret_url = AAZStrType( + serialized_name="secretUrl", + flags={"required": True}, + ) + protected_settings_from_key_vault.source_vault = AAZObjectType( + serialized_name="sourceVault", + flags={"required": True}, + ) + _ListHelper._build_schema_sub_resource_read(protected_settings_from_key_vault.source_vault) + provision_after_extensions = cls._schema_on_200.value.Element.properties.virtual_machine_profile.extension_profile.extensions.Element.properties.provision_after_extensions provision_after_extensions.Element = AAZStrType() @@ -843,6 +917,7 @@ def _build_schema_on_200(cls): ) windows_configuration.enable_vm_agent_platform_updates = AAZBoolType( serialized_name="enableVMAgentPlatformUpdates", + flags={"read_only": True}, ) windows_configuration.patch_settings = AAZObjectType( serialized_name="patchSettings", @@ -930,86 +1005,15 @@ def _build_schema_on_200(cls): security_posture_reference.exclude_extensions = AAZListType( serialized_name="excludeExtensions", ) - security_posture_reference.id = AAZStrType() - - exclude_extensions = cls._schema_on_200.value.Element.properties.virtual_machine_profile.security_posture_reference.exclude_extensions - exclude_extensions.Element = AAZObjectType() - - _element = cls._schema_on_200.value.Element.properties.virtual_machine_profile.security_posture_reference.exclude_extensions.Element - _element.id = AAZStrType( - flags={"read_only": True}, - ) - _element.location = AAZStrType() - _element.name = AAZStrType( - flags={"read_only": True}, - ) - _element.properties = AAZObjectType( - flags={"client_flatten": True}, - ) - _element.tags = AAZDictType() - _element.type = AAZStrType( - flags={"read_only": True}, - ) - - properties = cls._schema_on_200.value.Element.properties.virtual_machine_profile.security_posture_reference.exclude_extensions.Element.properties - properties.auto_upgrade_minor_version = AAZBoolType( - serialized_name="autoUpgradeMinorVersion", - ) - properties.enable_automatic_upgrade = AAZBoolType( - serialized_name="enableAutomaticUpgrade", - ) - properties.force_update_tag = AAZStrType( - serialized_name="forceUpdateTag", - ) - properties.instance_view = AAZObjectType( - serialized_name="instanceView", - ) - properties.protected_settings = AAZObjectType( - serialized_name="protectedSettings", - ) - properties.protected_settings_from_key_vault = AAZObjectType( - serialized_name="protectedSettingsFromKeyVault", - ) - _ListHelper._build_schema_key_vault_secret_reference_read(properties.protected_settings_from_key_vault) - properties.provision_after_extensions = AAZListType( - serialized_name="provisionAfterExtensions", - ) - properties.provisioning_state = AAZStrType( - serialized_name="provisioningState", - flags={"read_only": True}, - ) - properties.publisher = AAZStrType() - properties.settings = AAZObjectType() - properties.suppress_failures = AAZBoolType( - serialized_name="suppressFailures", + security_posture_reference.id = AAZStrType( + flags={"required": True}, ) - properties.type = AAZStrType() - properties.type_handler_version = AAZStrType( - serialized_name="typeHandlerVersion", + security_posture_reference.is_overridable = AAZBoolType( + serialized_name="isOverridable", ) - instance_view = cls._schema_on_200.value.Element.properties.virtual_machine_profile.security_posture_reference.exclude_extensions.Element.properties.instance_view - instance_view.name = AAZStrType() - instance_view.statuses = AAZListType() - instance_view.substatuses = AAZListType() - instance_view.type = AAZStrType() - instance_view.type_handler_version = AAZStrType( - serialized_name="typeHandlerVersion", - ) - - statuses = cls._schema_on_200.value.Element.properties.virtual_machine_profile.security_posture_reference.exclude_extensions.Element.properties.instance_view.statuses - statuses.Element = AAZObjectType() - _ListHelper._build_schema_instance_view_status_read(statuses.Element) - - substatuses = cls._schema_on_200.value.Element.properties.virtual_machine_profile.security_posture_reference.exclude_extensions.Element.properties.instance_view.substatuses - substatuses.Element = AAZObjectType() - _ListHelper._build_schema_instance_view_status_read(substatuses.Element) - - provision_after_extensions = cls._schema_on_200.value.Element.properties.virtual_machine_profile.security_posture_reference.exclude_extensions.Element.properties.provision_after_extensions - provision_after_extensions.Element = AAZStrType() - - tags = cls._schema_on_200.value.Element.properties.virtual_machine_profile.security_posture_reference.exclude_extensions.Element.tags - tags.Element = AAZStrType() + exclude_extensions = cls._schema_on_200.value.Element.properties.virtual_machine_profile.security_posture_reference.exclude_extensions + exclude_extensions.Element = AAZStrType() security_profile = cls._schema_on_200.value.Element.properties.virtual_machine_profile.security_profile security_profile.encryption_at_host = AAZBoolType( @@ -1035,10 +1039,16 @@ def _build_schema_on_200(cls): proxy_agent_settings = cls._schema_on_200.value.Element.properties.virtual_machine_profile.security_profile.proxy_agent_settings proxy_agent_settings.enabled = AAZBoolType() + proxy_agent_settings.imds = AAZObjectType() + _ListHelper._build_schema_host_endpoint_settings_read(proxy_agent_settings.imds) proxy_agent_settings.key_incarnation_id = AAZIntType( serialized_name="keyIncarnationId", ) proxy_agent_settings.mode = AAZStrType() + proxy_agent_settings.wire_server = AAZObjectType( + serialized_name="wireServer", + ) + _ListHelper._build_schema_host_endpoint_settings_read(proxy_agent_settings.wire_server) uefi_settings = cls._schema_on_200.value.Element.properties.virtual_machine_profile.security_profile.uefi_settings uefi_settings.secure_boot_enabled = AAZBoolType( @@ -1169,7 +1179,7 @@ def _build_schema_on_200(cls): return cls._schema_on_200 - class VirtualMachineScaleSetsListAll(AAZHttpOperation): + class VirtualMachineScaleSetsList(AAZHttpOperation): CLIENT_TYPE = "MgmtClient" def __call__(self, *args, **kwargs): @@ -1183,7 +1193,7 @@ def __call__(self, *args, **kwargs): @property def url(self): return self.client.format_url( - "/subscriptions/{subscriptionId}/providers/Microsoft.Compute/virtualMachineScaleSets", + "/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Compute/virtualMachineScaleSets", **self.url_parameters ) @@ -1198,6 +1208,10 @@ def error_format(self): @property def url_parameters(self): parameters = { + **self.serialize_url_param( + "resourceGroupName", self.ctx.args.resource_group, + required=True, + ), **self.serialize_url_param( "subscriptionId", self.ctx.subscription_id, required=True, @@ -1209,7 +1223,7 @@ def url_parameters(self): def query_parameters(self): parameters = { **self.serialize_query_param( - "api-version", "2023-09-01", + "api-version", "2024-11-01", required=True, ), } @@ -1360,9 +1374,15 @@ def _build_schema_on_200(cls): properties.scale_in_policy = AAZObjectType( serialized_name="scaleInPolicy", ) + properties.scheduled_events_policy = AAZObjectType( + serialized_name="scheduledEventsPolicy", + ) properties.single_placement_group = AAZBoolType( serialized_name="singlePlacementGroup", ) + properties.sku_profile = AAZObjectType( + serialized_name="skuProfile", + ) properties.spot_restore_policy = AAZObjectType( serialized_name="spotRestorePolicy", ) @@ -1380,6 +1400,9 @@ def _build_schema_on_200(cls): properties.virtual_machine_profile = AAZObjectType( serialized_name="virtualMachineProfile", ) + properties.zonal_platform_fault_domain_align_mode = AAZStrType( + serialized_name="zonalPlatformFaultDomainAlignMode", + ) properties.zone_balance = AAZBoolType( serialized_name="zoneBalance", ) @@ -1410,6 +1433,9 @@ def _build_schema_on_200(cls): ) resiliency_policy = cls._schema_on_200.value.Element.properties.resiliency_policy + resiliency_policy.automatic_zone_rebalancing_policy = AAZObjectType( + serialized_name="automaticZoneRebalancingPolicy", + ) resiliency_policy.resilient_vm_creation_policy = AAZObjectType( serialized_name="resilientVMCreationPolicy", ) @@ -1417,6 +1443,15 @@ def _build_schema_on_200(cls): serialized_name="resilientVMDeletionPolicy", ) + automatic_zone_rebalancing_policy = cls._schema_on_200.value.Element.properties.resiliency_policy.automatic_zone_rebalancing_policy + automatic_zone_rebalancing_policy.enabled = AAZBoolType() + automatic_zone_rebalancing_policy.rebalance_behavior = AAZStrType( + serialized_name="rebalanceBehavior", + ) + automatic_zone_rebalancing_policy.rebalance_strategy = AAZStrType( + serialized_name="rebalanceStrategy", + ) + resilient_vm_creation_policy = cls._schema_on_200.value.Element.properties.resiliency_policy.resilient_vm_creation_policy resilient_vm_creation_policy.enabled = AAZBoolType() @@ -1427,11 +1462,58 @@ def _build_schema_on_200(cls): scale_in_policy.force_deletion = AAZBoolType( serialized_name="forceDeletion", ) + scale_in_policy.prioritize_unhealthy_v_ms = AAZBoolType( + serialized_name="prioritizeUnhealthyVMs", + ) scale_in_policy.rules = AAZListType() rules = cls._schema_on_200.value.Element.properties.scale_in_policy.rules rules.Element = AAZStrType() + scheduled_events_policy = cls._schema_on_200.value.Element.properties.scheduled_events_policy + scheduled_events_policy.scheduled_events_additional_publishing_targets = AAZObjectType( + serialized_name="scheduledEventsAdditionalPublishingTargets", + ) + scheduled_events_policy.user_initiated_reboot = AAZObjectType( + serialized_name="userInitiatedReboot", + ) + scheduled_events_policy.user_initiated_redeploy = AAZObjectType( + serialized_name="userInitiatedRedeploy", + ) + + scheduled_events_additional_publishing_targets = cls._schema_on_200.value.Element.properties.scheduled_events_policy.scheduled_events_additional_publishing_targets + scheduled_events_additional_publishing_targets.event_grid_and_resource_graph = AAZObjectType( + serialized_name="eventGridAndResourceGraph", + ) + + event_grid_and_resource_graph = cls._schema_on_200.value.Element.properties.scheduled_events_policy.scheduled_events_additional_publishing_targets.event_grid_and_resource_graph + event_grid_and_resource_graph.enable = AAZBoolType() + + user_initiated_reboot = cls._schema_on_200.value.Element.properties.scheduled_events_policy.user_initiated_reboot + user_initiated_reboot.automatically_approve = AAZBoolType( + serialized_name="automaticallyApprove", + ) + + user_initiated_redeploy = cls._schema_on_200.value.Element.properties.scheduled_events_policy.user_initiated_redeploy + user_initiated_redeploy.automatically_approve = AAZBoolType( + serialized_name="automaticallyApprove", + ) + + sku_profile = cls._schema_on_200.value.Element.properties.sku_profile + sku_profile.allocation_strategy = AAZStrType( + serialized_name="allocationStrategy", + ) + sku_profile.vm_sizes = AAZListType( + serialized_name="vmSizes", + ) + + vm_sizes = cls._schema_on_200.value.Element.properties.sku_profile.vm_sizes + vm_sizes.Element = AAZObjectType() + + _element = cls._schema_on_200.value.Element.properties.sku_profile.vm_sizes.Element + _element.name = AAZStrType() + _element.rank = AAZIntType() + spot_restore_policy = cls._schema_on_200.value.Element.properties.spot_restore_policy spot_restore_policy.enabled = AAZBoolType() spot_restore_policy.restore_timeout = AAZStrType( @@ -1620,13 +1702,12 @@ def _build_schema_on_200(cls): properties.force_update_tag = AAZStrType( serialized_name="forceUpdateTag", ) - properties.protected_settings = AAZObjectType( + properties.protected_settings = AAZFreeFormDictType( serialized_name="protectedSettings", ) properties.protected_settings_from_key_vault = AAZObjectType( serialized_name="protectedSettingsFromKeyVault", ) - _ListHelper._build_schema_key_vault_secret_reference_read(properties.protected_settings_from_key_vault) properties.provision_after_extensions = AAZListType( serialized_name="provisionAfterExtensions", ) @@ -1635,7 +1716,7 @@ def _build_schema_on_200(cls): flags={"read_only": True}, ) properties.publisher = AAZStrType() - properties.settings = AAZObjectType() + properties.settings = AAZFreeFormDictType() properties.suppress_failures = AAZBoolType( serialized_name="suppressFailures", ) @@ -1644,6 +1725,17 @@ def _build_schema_on_200(cls): serialized_name="typeHandlerVersion", ) + protected_settings_from_key_vault = cls._schema_on_200.value.Element.properties.virtual_machine_profile.extension_profile.extensions.Element.properties.protected_settings_from_key_vault + protected_settings_from_key_vault.secret_url = AAZStrType( + serialized_name="secretUrl", + flags={"required": True}, + ) + protected_settings_from_key_vault.source_vault = AAZObjectType( + serialized_name="sourceVault", + flags={"required": True}, + ) + _ListHelper._build_schema_sub_resource_read(protected_settings_from_key_vault.source_vault) + provision_after_extensions = cls._schema_on_200.value.Element.properties.virtual_machine_profile.extension_profile.extensions.Element.properties.provision_after_extensions provision_after_extensions.Element = AAZStrType() @@ -1936,6 +2028,7 @@ def _build_schema_on_200(cls): ) windows_configuration.enable_vm_agent_platform_updates = AAZBoolType( serialized_name="enableVMAgentPlatformUpdates", + flags={"read_only": True}, ) windows_configuration.patch_settings = AAZObjectType( serialized_name="patchSettings", @@ -2023,86 +2116,15 @@ def _build_schema_on_200(cls): security_posture_reference.exclude_extensions = AAZListType( serialized_name="excludeExtensions", ) - security_posture_reference.id = AAZStrType() - - exclude_extensions = cls._schema_on_200.value.Element.properties.virtual_machine_profile.security_posture_reference.exclude_extensions - exclude_extensions.Element = AAZObjectType() - - _element = cls._schema_on_200.value.Element.properties.virtual_machine_profile.security_posture_reference.exclude_extensions.Element - _element.id = AAZStrType( - flags={"read_only": True}, - ) - _element.location = AAZStrType() - _element.name = AAZStrType( - flags={"read_only": True}, - ) - _element.properties = AAZObjectType( - flags={"client_flatten": True}, - ) - _element.tags = AAZDictType() - _element.type = AAZStrType( - flags={"read_only": True}, - ) - - properties = cls._schema_on_200.value.Element.properties.virtual_machine_profile.security_posture_reference.exclude_extensions.Element.properties - properties.auto_upgrade_minor_version = AAZBoolType( - serialized_name="autoUpgradeMinorVersion", - ) - properties.enable_automatic_upgrade = AAZBoolType( - serialized_name="enableAutomaticUpgrade", - ) - properties.force_update_tag = AAZStrType( - serialized_name="forceUpdateTag", - ) - properties.instance_view = AAZObjectType( - serialized_name="instanceView", - ) - properties.protected_settings = AAZObjectType( - serialized_name="protectedSettings", - ) - properties.protected_settings_from_key_vault = AAZObjectType( - serialized_name="protectedSettingsFromKeyVault", - ) - _ListHelper._build_schema_key_vault_secret_reference_read(properties.protected_settings_from_key_vault) - properties.provision_after_extensions = AAZListType( - serialized_name="provisionAfterExtensions", - ) - properties.provisioning_state = AAZStrType( - serialized_name="provisioningState", - flags={"read_only": True}, - ) - properties.publisher = AAZStrType() - properties.settings = AAZObjectType() - properties.suppress_failures = AAZBoolType( - serialized_name="suppressFailures", + security_posture_reference.id = AAZStrType( + flags={"required": True}, ) - properties.type = AAZStrType() - properties.type_handler_version = AAZStrType( - serialized_name="typeHandlerVersion", + security_posture_reference.is_overridable = AAZBoolType( + serialized_name="isOverridable", ) - instance_view = cls._schema_on_200.value.Element.properties.virtual_machine_profile.security_posture_reference.exclude_extensions.Element.properties.instance_view - instance_view.name = AAZStrType() - instance_view.statuses = AAZListType() - instance_view.substatuses = AAZListType() - instance_view.type = AAZStrType() - instance_view.type_handler_version = AAZStrType( - serialized_name="typeHandlerVersion", - ) - - statuses = cls._schema_on_200.value.Element.properties.virtual_machine_profile.security_posture_reference.exclude_extensions.Element.properties.instance_view.statuses - statuses.Element = AAZObjectType() - _ListHelper._build_schema_instance_view_status_read(statuses.Element) - - substatuses = cls._schema_on_200.value.Element.properties.virtual_machine_profile.security_posture_reference.exclude_extensions.Element.properties.instance_view.substatuses - substatuses.Element = AAZObjectType() - _ListHelper._build_schema_instance_view_status_read(substatuses.Element) - - provision_after_extensions = cls._schema_on_200.value.Element.properties.virtual_machine_profile.security_posture_reference.exclude_extensions.Element.properties.provision_after_extensions - provision_after_extensions.Element = AAZStrType() - - tags = cls._schema_on_200.value.Element.properties.virtual_machine_profile.security_posture_reference.exclude_extensions.Element.tags - tags.Element = AAZStrType() + exclude_extensions = cls._schema_on_200.value.Element.properties.virtual_machine_profile.security_posture_reference.exclude_extensions + exclude_extensions.Element = AAZStrType() security_profile = cls._schema_on_200.value.Element.properties.virtual_machine_profile.security_profile security_profile.encryption_at_host = AAZBoolType( @@ -2128,10 +2150,16 @@ def _build_schema_on_200(cls): proxy_agent_settings = cls._schema_on_200.value.Element.properties.virtual_machine_profile.security_profile.proxy_agent_settings proxy_agent_settings.enabled = AAZBoolType() + proxy_agent_settings.imds = AAZObjectType() + _ListHelper._build_schema_host_endpoint_settings_read(proxy_agent_settings.imds) proxy_agent_settings.key_incarnation_id = AAZIntType( serialized_name="keyIncarnationId", ) proxy_agent_settings.mode = AAZStrType() + proxy_agent_settings.wire_server = AAZObjectType( + serialized_name="wireServer", + ) + _ListHelper._build_schema_host_endpoint_settings_read(proxy_agent_settings.wire_server) uefi_settings = cls._schema_on_200.value.Element.properties.virtual_machine_profile.security_profile.uefi_settings uefi_settings.secure_boot_enabled = AAZBoolType( @@ -2296,59 +2324,25 @@ def _build_schema_disk_encryption_set_parameters_read(cls, _schema): _schema.id = cls._schema_disk_encryption_set_parameters_read.id - _schema_instance_view_status_read = None - - @classmethod - def _build_schema_instance_view_status_read(cls, _schema): - if cls._schema_instance_view_status_read is not None: - _schema.code = cls._schema_instance_view_status_read.code - _schema.display_status = cls._schema_instance_view_status_read.display_status - _schema.level = cls._schema_instance_view_status_read.level - _schema.message = cls._schema_instance_view_status_read.message - _schema.time = cls._schema_instance_view_status_read.time - return - - cls._schema_instance_view_status_read = _schema_instance_view_status_read = AAZObjectType() - - instance_view_status_read = _schema_instance_view_status_read - instance_view_status_read.code = AAZStrType() - instance_view_status_read.display_status = AAZStrType( - serialized_name="displayStatus", - ) - instance_view_status_read.level = AAZStrType() - instance_view_status_read.message = AAZStrType() - instance_view_status_read.time = AAZStrType() - - _schema.code = cls._schema_instance_view_status_read.code - _schema.display_status = cls._schema_instance_view_status_read.display_status - _schema.level = cls._schema_instance_view_status_read.level - _schema.message = cls._schema_instance_view_status_read.message - _schema.time = cls._schema_instance_view_status_read.time - - _schema_key_vault_secret_reference_read = None + _schema_host_endpoint_settings_read = None @classmethod - def _build_schema_key_vault_secret_reference_read(cls, _schema): - if cls._schema_key_vault_secret_reference_read is not None: - _schema.secret_url = cls._schema_key_vault_secret_reference_read.secret_url - _schema.source_vault = cls._schema_key_vault_secret_reference_read.source_vault + def _build_schema_host_endpoint_settings_read(cls, _schema): + if cls._schema_host_endpoint_settings_read is not None: + _schema.in_vm_access_control_profile_reference_id = cls._schema_host_endpoint_settings_read.in_vm_access_control_profile_reference_id + _schema.mode = cls._schema_host_endpoint_settings_read.mode return - cls._schema_key_vault_secret_reference_read = _schema_key_vault_secret_reference_read = AAZObjectType() + cls._schema_host_endpoint_settings_read = _schema_host_endpoint_settings_read = AAZObjectType() - key_vault_secret_reference_read = _schema_key_vault_secret_reference_read - key_vault_secret_reference_read.secret_url = AAZStrType( - serialized_name="secretUrl", - flags={"required": True}, - ) - key_vault_secret_reference_read.source_vault = AAZObjectType( - serialized_name="sourceVault", - flags={"required": True}, + host_endpoint_settings_read = _schema_host_endpoint_settings_read + host_endpoint_settings_read.in_vm_access_control_profile_reference_id = AAZStrType( + serialized_name="inVMAccessControlProfileReferenceId", ) - cls._build_schema_sub_resource_read(key_vault_secret_reference_read.source_vault) + host_endpoint_settings_read.mode = AAZStrType() - _schema.secret_url = cls._schema_key_vault_secret_reference_read.secret_url - _schema.source_vault = cls._schema_key_vault_secret_reference_read.source_vault + _schema.in_vm_access_control_profile_reference_id = cls._schema_host_endpoint_settings_read.in_vm_access_control_profile_reference_id + _schema.mode = cls._schema_host_endpoint_settings_read.mode _schema_sub_resource_read = None From 77706371588f610301de0627c953b0ab426d5731 Mon Sep 17 00:00:00 2001 From: william051200 Date: Mon, 16 Mar 2026 09:28:38 +0800 Subject: [PATCH 5/5] Update test case recording --- .../latest/recordings/test_vmss_create_and_modify.yaml | 6 +++--- .../tests/latest/recordings/test_vmss_create_options.yaml | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/azure-cli/azure/cli/command_modules/vm/tests/latest/recordings/test_vmss_create_and_modify.yaml b/src/azure-cli/azure/cli/command_modules/vm/tests/latest/recordings/test_vmss_create_and_modify.yaml index 3487ab84c1a..62974298a0e 100644 --- a/src/azure-cli/azure/cli/command_modules/vm/tests/latest/recordings/test_vmss_create_and_modify.yaml +++ b/src/azure-cli/azure/cli/command_modules/vm/tests/latest/recordings/test_vmss_create_and_modify.yaml @@ -1120,7 +1120,7 @@ interactions: User-Agent: - AZURECLI/2.83.0 azsdk-python-core/1.38.0 Python/3.12.10 (Windows-11-10.0.26200-SP0) method: GET - uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/providers/Microsoft.Compute/virtualMachineScaleSets?api-version=2023-09-01 + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/providers/Microsoft.Compute/virtualMachineScaleSets?api-version=2024-11-01 response: body: string: '{"value":[{"name":"vmss1","id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/ZYTEST/providers/Microsoft.Compute/virtualMachineScaleSets/vmss1","type":"Microsoft.Compute/virtualMachineScaleSets","location":"eastus","tags":{},"sku":{"name":"Standard_B2ms","tier":"Standard","capacity":2},"etag":"\"10\"","properties":{"singlePlacementGroup":false,"orchestrationMode":"Flexible","upgradePolicy":{"mode":"Manual"},"virtualMachineProfile":{"osProfile":{"computerNamePrefix":"vmss1","adminUsername":"zhuyan","linuxConfiguration":{"disablePasswordAuthentication":true,"ssh":{"publicKeys":[{"path":"/home/zhuyan/.ssh/authorized_keys","keyData":"ssh-rsa @@ -1171,7 +1171,7 @@ interactions: User-Agent: - AZURECLI/2.83.0 azsdk-python-core/1.38.0 Python/3.12.10 (Windows-11-10.0.26200-SP0) method: GET - uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/cli_test_vmss_create_and_modify000001/providers/Microsoft.Compute/virtualMachineScaleSets?api-version=2023-09-01 + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/cli_test_vmss_create_and_modify000001/providers/Microsoft.Compute/virtualMachineScaleSets?api-version=2024-11-01 response: body: string: '{"value":[{"name":"vmss1","id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/cli_test_vmss_create_and_modify000001/providers/Microsoft.Compute/virtualMachineScaleSets/vmss1","type":"Microsoft.Compute/virtualMachineScaleSets","location":"westus","tags":{},"sku":{"name":"Standard_B1ls","tier":"Standard","capacity":5},"etag":"\"2\"","properties":{"singlePlacementGroup":true,"orchestrationMode":"Uniform","upgradePolicy":{"mode":"Manual"},"virtualMachineProfile":{"osProfile":{"computerNamePrefix":"vmss1abe4","adminUsername":"myadmin","windowsConfiguration":{"provisionVMAgent":true,"enableAutomaticUpdates":true},"secrets":[],"allowExtensionOperations":true,"requireGuestProvisionSignal":true},"storageProfile":{"osDisk":{"osType":"Windows","createOption":"FromImage","caching":"ReadWrite","managedDisk":{"storageAccountType":"Premium_LRS"},"diskSizeGB":127},"imageReference":{"publisher":"MicrosoftWindowsServer","offer":"WindowsServer","sku":"2022-datacenter-g2","version":"latest"},"diskControllerType":"SCSI"},"networkProfile":{"networkInterfaceConfigurations":[{"name":"vmss1abe4Nic","properties":{"primary":true,"disableTcpStateTracking":false,"networkSecurityGroup":{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/cli_test_vmss_create_and_modify000001/providers/Microsoft.Network/networkSecurityGroups/vmss1NSG"},"dnsSettings":{"dnsServers":[]},"enableIPForwarding":false,"ipConfigurations":[{"name":"vmss1abe4IPConfig","properties":{"subnet":{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/cli_test_vmss_create_and_modify000001/providers/Microsoft.Network/virtualNetworks/vmss1VNET/subnets/vmss1Subnet"},"privateIPAddressVersion":"IPv4","loadBalancerBackendAddressPools":[{"id":"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/cli_test_vmss_create_and_modify000001/providers/Microsoft.Network/loadBalancers/vmss1LB/backendAddressPools/vmss1LBBEPool"}]}}]}}]},"timeCreated":"2026-02-16T02:12:56.5735737+00:00"},"provisioningState":"Succeeded","overprovision":true,"doNotRunExtensionsOnOverprovisionedVMs":false,"uniqueId":"4aed7d17-f7d4-41a5-9201-e88c5ae2f168","platformFaultDomainCount":5,"timeCreated":"2026-02-16T02:12:56.5735737+00:00"}}]}' @@ -9047,7 +9047,7 @@ interactions: User-Agent: - AZURECLI/2.83.0 azsdk-python-core/1.38.0 Python/3.12.10 (Windows-11-10.0.26200-SP0) method: GET - uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/cli_test_vmss_create_and_modify000001/providers/Microsoft.Compute/virtualMachineScaleSets?api-version=2023-09-01 + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/cli_test_vmss_create_and_modify000001/providers/Microsoft.Compute/virtualMachineScaleSets?api-version=2024-11-01 response: body: string: '{"value":[]}' diff --git a/src/azure-cli/azure/cli/command_modules/vm/tests/latest/recordings/test_vmss_create_options.yaml b/src/azure-cli/azure/cli/command_modules/vm/tests/latest/recordings/test_vmss_create_options.yaml index ebf0e0c6405..699dfa75280 100644 --- a/src/azure-cli/azure/cli/command_modules/vm/tests/latest/recordings/test_vmss_create_options.yaml +++ b/src/azure-cli/azure/cli/command_modules/vm/tests/latest/recordings/test_vmss_create_options.yaml @@ -6133,7 +6133,7 @@ interactions: User-Agent: - AZURECLI/2.63.0 azsdk-python-core/1.28.0 Python/3.10.11 (Windows-10-10.0.22631-SP0) method: GET - uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/cli_test_vmss_create_options000001/providers/Microsoft.Compute/virtualMachineScaleSets?api-version=2023-09-01 + uri: https://management.azure.com/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/cli_test_vmss_create_options000001/providers/Microsoft.Compute/virtualMachineScaleSets?api-version=2024-11-01 response: body: string: "{\r\n \"value\": [\r\n {\r\n \"name\": \"vrfvmss\",\r\n \