From fb92bab0eec81c69531bf88924da75d24b6eb523 Mon Sep 17 00:00:00 2001 From: william051200 Date: Fri, 6 Mar 2026 09:31:08 +0800 Subject: [PATCH 1/9] Generate vm list-usage --- .../vm/aaz/latest/vm/__init__.py | 1 + .../vm/aaz/latest/vm/_list_usage.py | 187 ++++++++++++++++++ 2 files changed, 188 insertions(+) create mode 100644 src/azure-cli/azure/cli/command_modules/vm/aaz/latest/vm/_list_usage.py diff --git a/src/azure-cli/azure/cli/command_modules/vm/aaz/latest/vm/__init__.py b/src/azure-cli/azure/cli/command_modules/vm/aaz/latest/vm/__init__.py index bd8a551b579..8f4bb878331 100644 --- a/src/azure-cli/azure/cli/command_modules/vm/aaz/latest/vm/__init__.py +++ b/src/azure-cli/azure/cli/command_modules/vm/aaz/latest/vm/__init__.py @@ -21,6 +21,7 @@ from ._list_all import * from ._list_sizes import * from ._list_skus import * +from ._list_usage import * from ._list_vm_resize_options import * from ._migrate_to_vmss import * from ._patch import * diff --git a/src/azure-cli/azure/cli/command_modules/vm/aaz/latest/vm/_list_usage.py b/src/azure-cli/azure/cli/command_modules/vm/aaz/latest/vm/_list_usage.py new file mode 100644 index 00000000000..f6b3eab0914 --- /dev/null +++ b/src/azure-cli/azure/cli/command_modules/vm/aaz/latest/vm/_list_usage.py @@ -0,0 +1,187 @@ +# -------------------------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# +# Code generated by aaz-dev-tools +# -------------------------------------------------------------------------------------------- + +# pylint: skip-file +# flake8: noqa + +from azure.cli.core.aaz import * + + +@register_command( + "vm list-usage", +) +class ListUsage(AAZCommand): + """List available usage resources for VMs. + + :example: Get the compute resource usage for the West US region. + az vm list-usage -l westus + """ + + _aaz_info = { + "version": "2024-11-01", + "resources": [ + ["mgmt-plane", "/subscriptions/{}/providers/microsoft.compute/locations/{}/usages", "2024-11-01"], + ] + } + + AZ_SUPPORT_PAGINATION = True + + def _handler(self, command_args): + super()._handler(command_args) + return self.build_paging(self._execute_operations, self._output) + + _args_schema = None + + @classmethod + def _build_arguments_schema(cls, *args, **kwargs): + if cls._args_schema is not None: + return cls._args_schema + cls._args_schema = super()._build_arguments_schema(*args, **kwargs) + + # define Arg Group "" + + _args_schema = cls._args_schema + _args_schema.location = AAZResourceLocationArg( + help="Location. Values from: `az account list-locations`. You can configure the default location using `az configure --defaults location=`.", + required=True, + ) + return cls._args_schema + + def _execute_operations(self): + self.pre_operations() + self.UsageList(ctx=self.ctx)() + self.post_operations() + + @register_callback + def pre_operations(self): + pass + + @register_callback + def post_operations(self): + pass + + def _output(self, *args, **kwargs): + result = self.deserialize_output(self.ctx.vars.instance.value, client_flatten=True) + next_link = self.deserialize_output(self.ctx.vars.instance.next_link) + return result, next_link + + class UsageList(AAZHttpOperation): + CLIENT_TYPE = "MgmtClient" + + def __call__(self, *args, **kwargs): + request = self.make_request() + session = self.client.send_request(request=request, stream=False, **kwargs) + if session.http_response.status_code in [200]: + return self.on_200(session) + + return self.on_error(session.http_response) + + @property + def url(self): + return self.client.format_url( + "/subscriptions/{subscriptionId}/providers/Microsoft.Compute/locations/{location}/usages", + **self.url_parameters + ) + + @property + def method(self): + return "GET" + + @property + def error_format(self): + return "ODataV4Format" + + @property + def url_parameters(self): + parameters = { + **self.serialize_url_param( + "location", self.ctx.args.location, + required=True, + ), + **self.serialize_url_param( + "subscriptionId", self.ctx.subscription_id, + required=True, + ), + } + return parameters + + @property + def query_parameters(self): + parameters = { + **self.serialize_query_param( + "api-version", "2024-11-01", + required=True, + ), + } + return parameters + + @property + def header_parameters(self): + parameters = { + **self.serialize_header_param( + "Accept", "application/json", + ), + } + return parameters + + def on_200(self, session): + data = self.deserialize_http_content(session) + self.ctx.set_var( + "instance", + data, + schema_builder=self._build_schema_on_200 + ) + + _schema_on_200 = None + + @classmethod + def _build_schema_on_200(cls): + if cls._schema_on_200 is not None: + return cls._schema_on_200 + + cls._schema_on_200 = AAZObjectType() + + _schema_on_200 = cls._schema_on_200 + _schema_on_200.next_link = AAZStrType( + serialized_name="nextLink", + ) + _schema_on_200.value = AAZListType( + flags={"required": True}, + ) + + value = cls._schema_on_200.value + value.Element = AAZObjectType() + + _element = cls._schema_on_200.value.Element + _element.current_value = AAZIntType( + serialized_name="currentValue", + flags={"required": True}, + ) + _element.limit = AAZIntType( + flags={"required": True}, + ) + _element.name = AAZObjectType( + flags={"required": True}, + ) + _element.unit = AAZStrType( + flags={"required": True}, + ) + + name = cls._schema_on_200.value.Element.name + name.localized_value = AAZStrType( + serialized_name="localizedValue", + ) + name.value = AAZStrType() + + return cls._schema_on_200 + + +class _ListUsageHelper: + """Helper class for ListUsage""" + + +__all__ = ["ListUsage"] From 3ae8f3a81e70b135b088797af335acc12d41fb29 Mon Sep 17 00:00:00 2001 From: william051200 Date: Fri, 6 Mar 2026 09:31:33 +0800 Subject: [PATCH 2/9] Migrate vm list-usage --- .../azure/cli/command_modules/vm/commands.py | 31 +++++++++---------- .../cli/command_modules/vm/operations/vm.py | 16 +++++++++- 2 files changed, 29 insertions(+), 18 deletions(-) diff --git a/src/azure-cli/azure/cli/command_modules/vm/commands.py b/src/azure-cli/azure/cli/command_modules/vm/commands.py index 165e8664a6c..b0e3121053a 100644 --- a/src/azure-cli/azure/cli/command_modules/vm/commands.py +++ b/src/azure-cli/azure/cli/command_modules/vm/commands.py @@ -282,32 +282,29 @@ def load_command_table(self, _): g.custom_show_command('show', 'show_vm_identity') with self.command_group('vm') as g: + g.custom_command('application set', 'set_vm_applications', validator=process_set_applications_namespace) + g.custom_command('application list', 'list_vm_applications') + g.custom_command('auto-shutdown', 'auto_shutdown_vm') g.custom_command('create', 'create_vm', transform=transform_vm_create_output, supports_no_wait=True, table_transformer=deployment_validate_table_format, validator=process_vm_create_namespace, exception_handler=handle_template_based_exception) - g.custom_command('list', 'list_vm', table_transformer=transform_vm_list) - g.custom_show_command('show', 'show_vm', table_transformer=transform_vm) - g.generic_update_command('update', getter_name='get_vm_to_update_by_aaz', setter_name='update_vm', setter_type=compute_custom, command_type=compute_custom, supports_no_wait=True, validator=process_vm_update_namespace) - g.custom_command('open-port', 'open_vm_port') - - with self.command_group('vm', compute_vm_sdk) as g: - g.custom_command('application set', 'set_vm_applications', validator=process_set_applications_namespace, min_api='2021-07-01') - g.custom_command('application list', 'list_vm_applications', min_api='2021-07-01') - g.custom_command('get-instance-view', 'get_instance_view', table_transformer='{Name:name, ResourceGroup:resourceGroup, Location:location, ProvisioningState:provisioningState, PowerState:instanceView.statuses[1].displayStatus}') + g.custom_command('install-patches', 'install_vm_patches', supports_no_wait=True) + g.custom_command('list', 'list_vm', table_transformer=transform_vm_list) g.custom_command('list-ip-addresses', 'list_vm_ip_addresses', table_transformer=transform_ip_addresses) - g.custom_command('list-skus', 'list_skus', table_transformer=transform_sku_for_table_output, min_api='2017-03-30') - g.command('list-usage', 'list', command_type=compute_vm_usage_sdk, transform=transform_vm_usage_list, table_transformer='[].{Name:localName, CurrentValue:currentValue, Limit:limit}') + g.custom_command('list-sizes', 'list_vm_sizes', deprecate_info=g.deprecate(redirect='az vm list-skus')) + g.custom_command('list-skus', 'list_skus', table_transformer=transform_sku_for_table_output) + g.custom_command('open-port', 'open_vm_port') g.custom_command('resize', 'resize_vm', supports_no_wait=True) g.custom_command('restart', 'restart_vm', supports_no_wait=True) - g.command('stop', 'begin_power_off', supports_no_wait=True, validator=process_vm_vmss_stop) + g.custom_show_command('show', 'show_vm', table_transformer=transform_vm) + g.generic_update_command('update', getter_name='get_vm_to_update_by_aaz', setter_name='update_vm', setter_type=compute_custom, command_type=compute_custom, supports_no_wait=True, validator=process_vm_update_namespace) g.wait_command('wait', getter_name='get_instance_view', getter_type=compute_custom) - g.custom_command('auto-shutdown', 'auto_shutdown_vm') - g.custom_command('list-sizes', 'list_vm_sizes', deprecate_info=g.deprecate(redirect='az vm list-skus')) - from .operations.vm import VMCapture + from .operations.vm import VMCapture, VMListUsage self.command_table['vm capture'] = VMCapture(loader=self) + self.command_table['vm list-usage'] = VMListUsage(loader=self) - with self.command_group('vm') as g: - g.custom_command('install-patches', 'install_vm_patches', supports_no_wait=True, min_api='2020-12-01') + with self.command_group('vm', compute_vm_sdk) as g: + g.command('stop', 'begin_power_off', supports_no_wait=True, validator=process_vm_vmss_stop) with self.command_group('vm availability-set', compute_availset_profile) as g: g.custom_command('create', 'create_av_set', table_transformer=deployment_validate_table_format, supports_no_wait=True, exception_handler=handle_template_based_exception) diff --git a/src/azure-cli/azure/cli/command_modules/vm/operations/vm.py b/src/azure-cli/azure/cli/command_modules/vm/operations/vm.py index 09f7244a3b8..a1ef8c4d51d 100644 --- a/src/azure-cli/azure/cli/command_modules/vm/operations/vm.py +++ b/src/azure-cli/azure/cli/command_modules/vm/operations/vm.py @@ -9,7 +9,8 @@ from azure.cli.core.aaz import AAZStrType from ..aaz.latest.vm import (Show as _VMShow, ListSizes as _VMListSizes, Patch as _VMPatch, - Update as _VMUpdate, Capture as _VMCapture, Create as _VMCreate) + Update as _VMUpdate, Capture as _VMCapture, Create as _VMCreate, + ListUsage as _VMListUsage) from .._vm_utils import IdentityType logger = get_logger(__name__) @@ -260,6 +261,19 @@ def __call__(self, *args, **kwargs): return self.on_error(session.http_response) +class VMListUsage(_VMListUsage): + def _output(self, *args, **kwargs): + result = self.deserialize_output(self.ctx.vars.instance.value, client_flatten=True) + next_link = self.deserialize_output(self.ctx.vars.instance.next_link) + + for item in result: + item['currentValue'] = str(item['currentValue']) + item['limit'] = str(item['limit']) + item['localizedValue'] = item['name']['localizedValue'] + + return result, next_link + + def convert_show_result_to_snake_case(result): new_result = {} if "id" in result: From 1b56d856074179f934611d3af295ba27d366cb31 Mon Sep 17 00:00:00 2001 From: william051200 Date: Fri, 6 Mar 2026 09:41:47 +0800 Subject: [PATCH 3/9] Generate vm stop --- .../vm/aaz/latest/vm/__init__.py | 3 +- .../command_modules/vm/aaz/latest/vm/_stop.py | 165 ++++++++++++++++++ 2 files changed, 167 insertions(+), 1 deletion(-) create mode 100644 src/azure-cli/azure/cli/command_modules/vm/aaz/latest/vm/_stop.py diff --git a/src/azure-cli/azure/cli/command_modules/vm/aaz/latest/vm/__init__.py b/src/azure-cli/azure/cli/command_modules/vm/aaz/latest/vm/__init__.py index 8f4bb878331..d8170f9639d 100644 --- a/src/azure-cli/azure/cli/command_modules/vm/aaz/latest/vm/__init__.py +++ b/src/azure-cli/azure/cli/command_modules/vm/aaz/latest/vm/__init__.py @@ -32,6 +32,7 @@ from ._show import * from ._simulate_eviction import * from ._start import * +from ._stop import * from ._update import * from ._wait import * -from ._restart import * \ No newline at end of file +from ._restart import * diff --git a/src/azure-cli/azure/cli/command_modules/vm/aaz/latest/vm/_stop.py b/src/azure-cli/azure/cli/command_modules/vm/aaz/latest/vm/_stop.py new file mode 100644 index 00000000000..86bbb78cae4 --- /dev/null +++ b/src/azure-cli/azure/cli/command_modules/vm/aaz/latest/vm/_stop.py @@ -0,0 +1,165 @@ +# -------------------------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# +# Code generated by aaz-dev-tools +# -------------------------------------------------------------------------------------------- + +# pylint: skip-file +# flake8: noqa + +from azure.cli.core.aaz import * + + +@register_command( + "vm stop", +) +class Stop(AAZCommand): + """Power off (stop) a running VM. + + The VM will continue to be billed. To avoid this, you can deallocate the VM through "az vm deallocate". + + :example: Power off (stop) a running VM. + az vm stop --resource-group MyResourceGroup --name MyVm + + :example: Power off a running VM without shutting down. + az vm stop --resource-group MyResourceGroup --name MyVm --skip-shutdow + + :example: Power off VMs in a resource group. + az vm stop --ids $(az vm list -g MyResourceGroup --query "[].id" -o tsv) + """ + + _aaz_info = { + "version": "2024-11-01", + "resources": [ + ["mgmt-plane", "/subscriptions/{}/resourcegroups/{}/providers/microsoft.compute/virtualmachines/{}/poweroff", "2024-11-01"], + ] + } + + AZ_SUPPORT_NO_WAIT = True + + def _handler(self, command_args): + super()._handler(command_args) + return self.build_lro_poller(self._execute_operations, None) + + _args_schema = None + + @classmethod + def _build_arguments_schema(cls, *args, **kwargs): + if cls._args_schema is not None: + return cls._args_schema + cls._args_schema = super()._build_arguments_schema(*args, **kwargs) + + # define Arg Group "" + + _args_schema = cls._args_schema + _args_schema.resource_group = AAZResourceGroupNameArg( + required=True, + ) + _args_schema.name = AAZStrArg( + options=["-n", "--name"], + help="The name of the virtual machine.", + required=True, + id_part="name", + ) + _args_schema.skip_shutdown = AAZBoolArg( + options=["--skip-shutdown"], + help="The parameter to request non-graceful VM shutdown. True value for this flag indicates non-graceful shutdown whereas false indicates otherwise. Default value for this flag is false if not specified", + ) + return cls._args_schema + + def _execute_operations(self): + self.pre_operations() + yield self.VirtualMachinesPowerOff(ctx=self.ctx)() + self.post_operations() + + @register_callback + def pre_operations(self): + pass + + @register_callback + def post_operations(self): + pass + + class VirtualMachinesPowerOff(AAZHttpOperation): + CLIENT_TYPE = "MgmtClient" + + def __call__(self, *args, **kwargs): + request = self.make_request() + session = self.client.send_request(request=request, stream=False, **kwargs) + if session.http_response.status_code in [202]: + return self.client.build_lro_polling( + self.ctx.args.no_wait, + session, + self.on_200, + self.on_error, + lro_options={"final-state-via": "location"}, + path_format_arguments=self.url_parameters, + ) + if session.http_response.status_code in [200]: + return self.client.build_lro_polling( + self.ctx.args.no_wait, + session, + self.on_200, + self.on_error, + lro_options={"final-state-via": "location"}, + path_format_arguments=self.url_parameters, + ) + + return self.on_error(session.http_response) + + @property + def url(self): + return self.client.format_url( + "/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Compute/virtualMachines/{vmName}/powerOff", + **self.url_parameters + ) + + @property + def method(self): + return "POST" + + @property + def error_format(self): + return "ODataV4Format" + + @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, + ), + **self.serialize_url_param( + "vmName", self.ctx.args.name, + required=True, + ), + } + return parameters + + @property + def query_parameters(self): + parameters = { + **self.serialize_query_param( + "skipShutdown", self.ctx.args.skip_shutdown, + ), + **self.serialize_query_param( + "api-version", "2024-11-01", + required=True, + ), + } + return parameters + + def on_200(self, session): + pass + + +class _StopHelper: + """Helper class for Stop""" + + +__all__ = ["Stop"] From cfc36e4d1d7a965e3c1e9a7ef9a4111ac9bc9a06 Mon Sep 17 00:00:00 2001 From: william051200 Date: Fri, 6 Mar 2026 09:41:56 +0800 Subject: [PATCH 4/9] Migrate vm stop --- src/azure-cli/azure/cli/command_modules/vm/commands.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/azure-cli/azure/cli/command_modules/vm/commands.py b/src/azure-cli/azure/cli/command_modules/vm/commands.py index b0e3121053a..2f0bc3ba2cb 100644 --- a/src/azure-cli/azure/cli/command_modules/vm/commands.py +++ b/src/azure-cli/azure/cli/command_modules/vm/commands.py @@ -303,8 +303,8 @@ def load_command_table(self, _): self.command_table['vm capture'] = VMCapture(loader=self) self.command_table['vm list-usage'] = VMListUsage(loader=self) - with self.command_group('vm', compute_vm_sdk) as g: - g.command('stop', 'begin_power_off', supports_no_wait=True, validator=process_vm_vmss_stop) + from .aaz.latest.vm import Stop as VMStop + self.command_table['vm stop'] = VMStop(loader=self, validator=process_vm_vmss_stop) with self.command_group('vm availability-set', compute_availset_profile) as g: g.custom_command('create', 'create_av_set', table_transformer=deployment_validate_table_format, supports_no_wait=True, exception_handler=handle_template_based_exception) From b49ed65f591a1147256dd4b48bf5bc3d0dfe4f7a Mon Sep 17 00:00:00 2001 From: william051200 Date: Fri, 6 Mar 2026 10:41:50 +0800 Subject: [PATCH 5/9] Update help message --- .../azure/cli/command_modules/vm/aaz/latest/vm/_stop.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/azure-cli/azure/cli/command_modules/vm/aaz/latest/vm/_stop.py b/src/azure-cli/azure/cli/command_modules/vm/aaz/latest/vm/_stop.py index 86bbb78cae4..4fb15697b7c 100644 --- a/src/azure-cli/azure/cli/command_modules/vm/aaz/latest/vm/_stop.py +++ b/src/azure-cli/azure/cli/command_modules/vm/aaz/latest/vm/_stop.py @@ -23,7 +23,7 @@ class Stop(AAZCommand): az vm stop --resource-group MyResourceGroup --name MyVm :example: Power off a running VM without shutting down. - az vm stop --resource-group MyResourceGroup --name MyVm --skip-shutdow + az vm stop --resource-group MyResourceGroup --name MyVm --skip-shutdown :example: Power off VMs in a resource group. az vm stop --ids $(az vm list -g MyResourceGroup --query "[].id" -o tsv) From a6ba7e3ac6b9e0bf9d4e5f8f666d5f61810dcbb2 Mon Sep 17 00:00:00 2001 From: william051200 Date: Fri, 6 Mar 2026 10:47:54 +0800 Subject: [PATCH 6/9] Update code --- src/azure-cli/azure/cli/command_modules/vm/_format.py | 9 --------- src/azure-cli/azure/cli/command_modules/vm/commands.py | 4 ++-- .../azure/cli/command_modules/vm/operations/vm.py | 2 +- 3 files changed, 3 insertions(+), 12 deletions(-) diff --git a/src/azure-cli/azure/cli/command_modules/vm/_format.py b/src/azure-cli/azure/cli/command_modules/vm/_format.py index 34d93f07609..fdd8c5a3b63 100644 --- a/src/azure-cli/azure/cli/command_modules/vm/_format.py +++ b/src/azure-cli/azure/cli/command_modules/vm/_format.py @@ -57,15 +57,6 @@ def transform_vm_create_output(result): return None if isinstance(result, ClientRawResponse) else result -def transform_vm_usage_list(result): - result = list(result) - for item in result: - item.current_value = str(item.current_value) - item.limit = str(item.limit) - item.local_name = item.name.localized_value - return result - - def transform_vm_list(vm_list): return [transform_vm(v) for v in vm_list] diff --git a/src/azure-cli/azure/cli/command_modules/vm/commands.py b/src/azure-cli/azure/cli/command_modules/vm/commands.py index 2f0bc3ba2cb..e1f54ea78ba 100644 --- a/src/azure-cli/azure/cli/command_modules/vm/commands.py +++ b/src/azure-cli/azure/cli/command_modules/vm/commands.py @@ -14,7 +14,7 @@ cf_capacity_reservation_groups, cf_capacity_reservations, cf_community_gallery) from azure.cli.command_modules.vm._format import ( - transform_ip_addresses, transform_vm, transform_vm_create_output, transform_vm_usage_list, transform_vm_list, + transform_ip_addresses, transform_vm, transform_vm_create_output, transform_vm_list, transform_disk_create_table_output, transform_sku_for_table_output, transform_disk_show_table_output, transform_extension_show_table_output, get_vmss_table_output_transformer, transform_vm_encryption_show_table_output, transform_log_analytics_query_output, @@ -301,7 +301,7 @@ def load_command_table(self, _): from .operations.vm import VMCapture, VMListUsage self.command_table['vm capture'] = VMCapture(loader=self) - self.command_table['vm list-usage'] = VMListUsage(loader=self) + self.command_table['vm list-usage'] = VMListUsage(loader=self, table_transformer='[].{Name:localName, CurrentValue:currentValue, Limit:limit}') from .aaz.latest.vm import Stop as VMStop self.command_table['vm stop'] = VMStop(loader=self, validator=process_vm_vmss_stop) diff --git a/src/azure-cli/azure/cli/command_modules/vm/operations/vm.py b/src/azure-cli/azure/cli/command_modules/vm/operations/vm.py index a1ef8c4d51d..aa2e7926d90 100644 --- a/src/azure-cli/azure/cli/command_modules/vm/operations/vm.py +++ b/src/azure-cli/azure/cli/command_modules/vm/operations/vm.py @@ -269,7 +269,7 @@ def _output(self, *args, **kwargs): for item in result: item['currentValue'] = str(item['currentValue']) item['limit'] = str(item['limit']) - item['localizedValue'] = item['name']['localizedValue'] + item['localName'] = item['name']['localizedValue'] return result, next_link From d80cfc47b0c850552f5fbe76dd2db2d6a7a89dc9 Mon Sep 17 00:00:00 2001 From: william051200 Date: Fri, 6 Mar 2026 10:58:11 +0800 Subject: [PATCH 7/9] Update code --- .../azure/cli/command_modules/vm/commands.py | 4 +--- src/azure-cli/azure/cli/command_modules/vm/custom.py | 11 +++++++++++ 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/src/azure-cli/azure/cli/command_modules/vm/commands.py b/src/azure-cli/azure/cli/command_modules/vm/commands.py index e1f54ea78ba..459402a3105 100644 --- a/src/azure-cli/azure/cli/command_modules/vm/commands.py +++ b/src/azure-cli/azure/cli/command_modules/vm/commands.py @@ -296,6 +296,7 @@ def load_command_table(self, _): g.custom_command('resize', 'resize_vm', supports_no_wait=True) g.custom_command('restart', 'restart_vm', supports_no_wait=True) g.custom_show_command('show', 'show_vm', table_transformer=transform_vm) + g.custom_command('stop', 'stop_vm', validator=process_vm_vmss_stop, supports_no_wait=True) g.generic_update_command('update', getter_name='get_vm_to_update_by_aaz', setter_name='update_vm', setter_type=compute_custom, command_type=compute_custom, supports_no_wait=True, validator=process_vm_update_namespace) g.wait_command('wait', getter_name='get_instance_view', getter_type=compute_custom) @@ -303,9 +304,6 @@ def load_command_table(self, _): self.command_table['vm capture'] = VMCapture(loader=self) self.command_table['vm list-usage'] = VMListUsage(loader=self, table_transformer='[].{Name:localName, CurrentValue:currentValue, Limit:limit}') - from .aaz.latest.vm import Stop as VMStop - self.command_table['vm stop'] = VMStop(loader=self, validator=process_vm_vmss_stop) - with self.command_group('vm availability-set', compute_availset_profile) as g: g.custom_command('create', 'create_av_set', table_transformer=deployment_validate_table_format, supports_no_wait=True, exception_handler=handle_template_based_exception) from .operations.vm_availability_set import AvailabilitySetUpdate, AvailabilitySetConvert diff --git a/src/azure-cli/azure/cli/command_modules/vm/custom.py b/src/azure-cli/azure/cli/command_modules/vm/custom.py index 6c6f602148b..272d96180d0 100644 --- a/src/azure-cli/azure/cli/command_modules/vm/custom.py +++ b/src/azure-cli/azure/cli/command_modules/vm/custom.py @@ -1751,6 +1751,17 @@ def restart_vm(cmd, resource_group_name, vm_name, no_wait=False, force=False): return _VMRestart(cli_ctx=cmd.cli_ctx)(command_args=command_args) +def stop_vm(cmd, resource_group_name, vm_name, no_wait=False, skip_shutdown=False): + from .aaz.latest.vm import Stop as VMStop + command_args = { + 'resource_group': resource_group_name, + 'name': vm_name, + 'skip_shutdown': skip_shutdown, + 'no_wait': no_wait + } + return VMStop(cli_ctx=cmd.cli_ctx)(command_args=command_args) + + def set_vm(cmd, instance, lro_operation=None, no_wait=False): instance.resources = None # Issue: https://github.com/Azure/autorest/issues/934 client = _compute_client_factory(cmd.cli_ctx) From afc30df3daeef65532c26b09dadc2c1fd203473b Mon Sep 17 00:00:00 2001 From: william051200 Date: Fri, 6 Mar 2026 11:02:57 +0800 Subject: [PATCH 8/9] Update code --- src/azure-cli/azure/cli/command_modules/vm/commands.py | 4 ++-- src/azure-cli/azure/cli/command_modules/vm/custom.py | 8 ++++++++ 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/azure-cli/azure/cli/command_modules/vm/commands.py b/src/azure-cli/azure/cli/command_modules/vm/commands.py index 459402a3105..9af515eb921 100644 --- a/src/azure-cli/azure/cli/command_modules/vm/commands.py +++ b/src/azure-cli/azure/cli/command_modules/vm/commands.py @@ -292,6 +292,7 @@ def load_command_table(self, _): g.custom_command('list-ip-addresses', 'list_vm_ip_addresses', table_transformer=transform_ip_addresses) g.custom_command('list-sizes', 'list_vm_sizes', deprecate_info=g.deprecate(redirect='az vm list-skus')) g.custom_command('list-skus', 'list_skus', table_transformer=transform_sku_for_table_output) + g.custom_command('list-usage', 'list_usage', table_transformer='[].{Name:localName, CurrentValue:currentValue, Limit:limit}') g.custom_command('open-port', 'open_vm_port') g.custom_command('resize', 'resize_vm', supports_no_wait=True) g.custom_command('restart', 'restart_vm', supports_no_wait=True) @@ -300,9 +301,8 @@ def load_command_table(self, _): g.generic_update_command('update', getter_name='get_vm_to_update_by_aaz', setter_name='update_vm', setter_type=compute_custom, command_type=compute_custom, supports_no_wait=True, validator=process_vm_update_namespace) g.wait_command('wait', getter_name='get_instance_view', getter_type=compute_custom) - from .operations.vm import VMCapture, VMListUsage + from .operations.vm import VMCapture self.command_table['vm capture'] = VMCapture(loader=self) - self.command_table['vm list-usage'] = VMListUsage(loader=self, table_transformer='[].{Name:localName, CurrentValue:currentValue, Limit:limit}') with self.command_group('vm availability-set', compute_availset_profile) as g: g.custom_command('create', 'create_av_set', table_transformer=deployment_validate_table_format, supports_no_wait=True, exception_handler=handle_template_based_exception) diff --git a/src/azure-cli/azure/cli/command_modules/vm/custom.py b/src/azure-cli/azure/cli/command_modules/vm/custom.py index 272d96180d0..9ca46c75035 100644 --- a/src/azure-cli/azure/cli/command_modules/vm/custom.py +++ b/src/azure-cli/azure/cli/command_modules/vm/custom.py @@ -1512,6 +1512,14 @@ def list_skus(cmd, location=None, size=None, zone=None, show_all=None, resource_ return result +def list_usage(cmd, location): + from .operations.vm import VMListUsage + command_args = { + 'location': location + } + return VMListUsage(cli_ctx=cmd.cli_ctx)(command_args=command_args) + + # pylint: disable=redefined-builtin def list_vm(cmd, resource_group_name=None, show_details=False, vmss=None): from azure.mgmt.core.tools import resource_id, is_valid_resource_id, parse_resource_id From 96989dfa7f3a1b542d8d3eafff3f31a0f27db048 Mon Sep 17 00:00:00 2001 From: william051200 Date: Fri, 6 Mar 2026 15:20:09 +0800 Subject: [PATCH 9/9] Remove unused import --- .../azure/cli/command_modules/vm/_client_factory.py | 4 ---- src/azure-cli/azure/cli/command_modules/vm/commands.py | 7 +------ 2 files changed, 1 insertion(+), 10 deletions(-) diff --git a/src/azure-cli/azure/cli/command_modules/vm/_client_factory.py b/src/azure-cli/azure/cli/command_modules/vm/_client_factory.py index ee6329e9129..f096f5667f4 100644 --- a/src/azure-cli/azure/cli/command_modules/vm/_client_factory.py +++ b/src/azure-cli/azure/cli/command_modules/vm/_client_factory.py @@ -35,10 +35,6 @@ def cf_vm_image_term(cli_ctx, _): return market_place_client.marketplace_agreements -def cf_usage(cli_ctx, _): - return _compute_client_factory(cli_ctx).usage - - def cf_vmss(cli_ctx, _): return _compute_client_factory(cli_ctx).virtual_machine_scale_sets diff --git a/src/azure-cli/azure/cli/command_modules/vm/commands.py b/src/azure-cli/azure/cli/command_modules/vm/commands.py index 9af515eb921..976eb4bea65 100644 --- a/src/azure-cli/azure/cli/command_modules/vm/commands.py +++ b/src/azure-cli/azure/cli/command_modules/vm/commands.py @@ -5,7 +5,7 @@ from azure.cli.command_modules.vm._client_factory import (cf_vm, cf_vm_ext, cf_vm_ext_image, - cf_vm_image, cf_vm_image_term, cf_usage, + cf_vm_image, cf_vm_image_term, cf_vmss, cf_images, cf_galleries, cf_gallery_images, cf_gallery_image_versions, cf_proximity_placement_groups, @@ -92,11 +92,6 @@ def load_command_table(self, _): client_factory=cf_vm_image_term ) - compute_vm_usage_sdk = CliCommandType( - operations_tmpl='azure.mgmt.compute.operations#UsageOperations.{}', - client_factory=cf_usage - ) - compute_vm_run_profile = CliCommandType( operations_tmpl='azure.mgmt.compute.operations#VirtualMachineRunCommandsOperations.{}' )