diff --git a/src/azure-cli/azure/cli/command_modules/vm/_help.py b/src/azure-cli/azure/cli/command_modules/vm/_help.py index fc47438fcf2..41df694f2e0 100644 --- a/src/azure-cli/azure/cli/command_modules/vm/_help.py +++ b/src/azure-cli/azure/cli/command_modules/vm/_help.py @@ -2800,16 +2800,6 @@ crafted: true """ -helps['vmss start'] = """ -type: command -short-summary: Start VMs within a VMSS. -examples: - - name: Start VMs within a VMSS. (autogenerated) - text: | - az vmss start --instance-ids 1 --name MyScaleSet --resource-group MyResourceGroup - crafted: true -""" - helps['vmss stop'] = """ type: command short-summary: Power off (stop) VMs within a VMSS. diff --git a/src/azure-cli/azure/cli/command_modules/vm/_params.py b/src/azure-cli/azure/cli/command_modules/vm/_params.py index a01356314c7..627fe3c4d67 100644 --- a/src/azure-cli/azure/cli/command_modules/vm/_params.py +++ b/src/azure-cli/azure/cli/command_modules/vm/_params.py @@ -705,7 +705,7 @@ def load_arguments(self, _): c.argument('host_group', min_api='2020-06-01', help='Name or ID of dedicated host group that the virtual machine scale set resides in') - for scope in ['vmss deallocate', 'vmss delete-instances', 'vmss restart', 'vmss start', 'vmss stop', 'vmss show', 'vmss update-instances', 'vmss simulate-eviction']: + for scope in ['vmss deallocate', 'vmss delete-instances', 'vmss restart', 'vmss stop', 'vmss show', 'vmss update-instances', 'vmss simulate-eviction']: with self.argument_context(scope) as c: for dest in scaleset_name_aliases: c.argument(dest, vmss_name_type, id_part=None) # due to instance-ids parameter diff --git a/src/azure-cli/azure/cli/command_modules/vm/aaz/latest/vmss/__init__.py b/src/azure-cli/azure/cli/command_modules/vm/aaz/latest/vmss/__init__.py index a929ea23832..68e941b7436 100644 --- a/src/azure-cli/azure/cli/command_modules/vm/aaz/latest/vmss/__init__.py +++ b/src/azure-cli/azure/cli/command_modules/vm/aaz/latest/vmss/__init__.py @@ -18,6 +18,7 @@ from ._patch import * from ._perform_maintenance import * from ._simulate_eviction import * +from ._start import * from ._update import * from ._update_domain_walk import * from ._wait import * diff --git a/src/azure-cli/azure/cli/command_modules/vm/aaz/latest/vmss/_start.py b/src/azure-cli/azure/cli/command_modules/vm/aaz/latest/vmss/_start.py new file mode 100644 index 00000000000..9cbaa96bf4d --- /dev/null +++ b/src/azure-cli/azure/cli/command_modules/vm/aaz/latest/vmss/_start.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( + "vmss start", +) +class Start(AAZCommand): + """Start VMs within a VMSS. + + :example: Start VMs within a VMSS. + az vmss start --instance-ids 1 --name MyScaleSet --resource-group MyResourceGroup + """ + + _aaz_info = { + "version": "2024-11-01", + "resources": [ + ["mgmt-plane", "/subscriptions/{}/resourcegroups/{}/providers/microsoft.compute/virtualmachinescalesets/{}/start", "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( + help="Name of resource group. You can configure the default group using `az configure --defaults group=`", + required=True, + ) + _args_schema.name = AAZStrArg( + options=["-n", "--name"], + help="Scale set name. You can configure the default using `az configure --defaults vmss=`", + required=True, + id_part="name", + ) + + # define Arg Group "VmInstanceIDs" + + _args_schema = cls._args_schema + _args_schema.instance_ids = AAZListArg( + options=["--instance-ids"], + arg_group="VmInstanceIDs", + help="Space-separated list of IDs (ex: 1 2 3 ...) or * for all instances. If not provided, the action will be applied on the scaleset itself.", + ) + + instance_ids = cls._args_schema.instance_ids + instance_ids.Element = AAZStrArg() + return cls._args_schema + + def _execute_operations(self): + self.pre_operations() + yield self.VirtualMachineScaleSetsStart(ctx=self.ctx)() + self.post_operations() + + @register_callback + def pre_operations(self): + pass + + @register_callback + def post_operations(self): + pass + + class VirtualMachineScaleSetsStart(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/virtualMachineScaleSets/{vmScaleSetName}/start", + **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( + "vmScaleSetName", self.ctx.args.name, + 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( + "Content-Type", "application/json", + ), + } + return parameters + + @property + def content(self): + _content_value, _builder = self.new_content_builder( + self.ctx.args, + typ=AAZObjectType, + typ_kwargs={"flags": {"client_flatten": True}} + ) + _builder.set_prop("instanceIds", AAZListType, ".instance_ids") + + instance_ids = _builder.get(".instanceIds") + if instance_ids is not None: + instance_ids.set_elements(AAZStrType, ".") + + return self.serialize_content(_content_value) + + def on_200(self, session): + pass + + +class _StartHelper: + """Helper class for Start""" + + +__all__ = ["Start"] 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 9525be18d94..d38ba5559e4 100644 --- a/src/azure-cli/azure/cli/command_modules/vm/commands.py +++ b/src/azure-cli/azure/cli/command_modules/vm/commands.py @@ -430,7 +430,6 @@ def load_command_table(self, _): g.custom_command('restart', 'restart_vmss', supports_no_wait=True) g.custom_command('scale', 'scale_vmss', supports_no_wait=True) g.custom_show_command('show', 'get_vmss', table_transformer=get_vmss_table_output_transformer(self, False)) - g.custom_command('start', 'start_vmss', supports_no_wait=True) g.custom_command('stop', 'stop_vmss', supports_no_wait=True, validator=process_vm_vmss_stop) g.generic_update_command('update', getter_name='get_vmss_modified', setter_name='update_vmss', supports_no_wait=True, command_type=compute_custom, validator=validate_vmss_update_namespace) g.custom_command('update-instances', 'update_vmss_instances', supports_no_wait=True) 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 ec1e4854815..464cd81d058 100644 --- a/src/azure-cli/azure/cli/command_modules/vm/custom.py +++ b/src/azure-cli/azure/cli/command_modules/vm/custom.py @@ -4052,16 +4052,6 @@ def scale_vmss(cmd, resource_group_name, vm_scale_set_name, new_capacity, no_wai resource_group_name, vm_scale_set_name, vmss_new) -def start_vmss(cmd, resource_group_name, vm_scale_set_name, instance_ids=None, no_wait=False): - client = _compute_client_factory(cmd.cli_ctx) - VirtualMachineScaleSetVMInstanceRequiredIDs = cmd.get_models('VirtualMachineScaleSetVMInstanceRequiredIDs') - if instance_ids is None: - instance_ids = ['*'] - instance_ids = VirtualMachineScaleSetVMInstanceRequiredIDs(instance_ids=instance_ids) - return sdk_no_wait(no_wait, client.virtual_machine_scale_sets.begin_start, - resource_group_name, vm_scale_set_name, vm_instance_i_ds=instance_ids) - - def stop_vmss(cmd, resource_group_name, vm_scale_set_name, instance_ids=None, no_wait=False, skip_shutdown=False): client = _compute_client_factory(cmd.cli_ctx) VirtualMachineScaleSetVMInstanceRequiredIDs = cmd.get_models('VirtualMachineScaleSetVMInstanceRequiredIDs') 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 bd393a750af..75d42dff23f 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 @@ -6,13 +6,14 @@ from knack.log import get_logger from ..aaz.latest.vmss import ListInstances as _VMSSListInstances +from ..aaz.latest.vmss import Start as _Start +from azure.cli.core.aaz import AAZUndefined, has_value logger = get_logger(__name__) class VMSSListInstances(_VMSSListInstances): def _output(self, *args, **kwargs): - from azure.cli.core.aaz import AAZUndefined, has_value # Resolve flatten conflict # When the type field conflicts, the type in inner layer is ignored and the outer layer is applied @@ -25,3 +26,13 @@ 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 VMSSStart(_Start): + + def pre_operations(self): + args = self.ctx.args + + if not has_value(args.instance_ids): + # if instance id is not provide, override with '*' + args.instance_ids = ["*"]