Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Compute] az vm disk detach: Add parameter --force-detach to support force-detaching managed data disks from a VM #23346

Merged
merged 4 commits into from
Jul 28, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions src/azure-cli/azure/cli/command_modules/vm/_help.py
Original file line number Diff line number Diff line change
Expand Up @@ -1821,6 +1821,9 @@
- name: Detach a data disk from a VM.
text: >
az vm disk detach -g MyResourceGroup --vm-name MyVm --name disk_name
- name: Force detach a data disk from a VM.
text: >
az vm disk detach -g MyResourceGroup --vm-name MyVm --name disk_name --force-detach
"""

helps['vm encryption'] = """
Expand Down
1 change: 1 addition & 0 deletions src/azure-cli/azure/cli/command_modules/vm/_params.py
Original file line number Diff line number Diff line change
Expand Up @@ -504,6 +504,7 @@ def load_arguments(self, _):

with self.argument_context('vm disk detach') as c:
c.argument('disk_name', arg_type=name_arg_type, help='The data disk name.')
c.argument('force_detach', action='store_true', min_api='2020-12-01', help='Force detach managed data disks from a VM.')

with self.argument_context('vm encryption enable') as c:
c.argument('encrypt_format_all', action='store_true', help='Encrypts-formats data disks instead of encrypting them. Encrypt-formatting is a lot faster than in-place encryption but wipes out the partition getting encrypt-formatted. (Only supported for Linux virtual machines.)')
Expand Down
4 changes: 2 additions & 2 deletions src/azure-cli/azure/cli/command_modules/vm/commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -388,7 +388,7 @@ def load_command_table(self, _):

with self.command_group('vm disk', compute_vm_sdk, min_api='2017-03-30') as g:
g.custom_command('attach', 'attach_managed_data_disk', validator=process_vm_disk_attach_namespace)
g.custom_command('detach', 'detach_data_disk')
g.custom_command('detach', 'detach_managed_data_disk')

with self.command_group('vm encryption', custom_command_type=compute_disk_encryption_custom) as g:
g.custom_command('enable', 'encrypt_vm', validator=process_disk_encryption_namespace)
Expand Down Expand Up @@ -446,7 +446,7 @@ def load_command_table(self, _):

with self.command_group('vm unmanaged-disk', compute_vm_sdk) as g:
g.custom_command('attach', 'attach_unmanaged_data_disk')
g.custom_command('detach', 'detach_data_disk')
g.custom_command('detach', 'detach_unmanaged_data_disk')
g.custom_command('list', 'list_unmanaged_disks')

with self.command_group('vm user', compute_vm_sdk, supports_no_wait=True) as g:
Expand Down
30 changes: 28 additions & 2 deletions src/azure-cli/azure/cli/command_modules/vm/custom.py
Original file line number Diff line number Diff line change
Expand Up @@ -1916,8 +1916,8 @@ def attach_managed_data_disk(cmd, resource_group_name, vm_name, disk=None, ids=N
set_vm(cmd, vm)


def detach_data_disk(cmd, resource_group_name, vm_name, disk_name):
# here we handle both unmanaged or managed disk
def detach_unmanaged_data_disk(cmd, resource_group_name, vm_name, disk_name):
# here we handle unmanaged disk
vm = get_vm_to_update(cmd, resource_group_name, vm_name)
# pylint: disable=no-member
leftovers = [d for d in vm.storage_profile.data_disks if d.name.lower() != disk_name.lower()]
Expand All @@ -1928,6 +1928,32 @@ def detach_data_disk(cmd, resource_group_name, vm_name, disk_name):
# endregion


def detach_managed_data_disk(cmd, resource_group_name, vm_name, disk_name, force_detach=None):
# here we handle managed disk
vm = get_vm_to_update(cmd, resource_group_name, vm_name)
if not force_detach:
# pylint: disable=no-member
leftovers = [d for d in vm.storage_profile.data_disks if d.name.lower() != disk_name.lower()]
if len(vm.storage_profile.data_disks) == len(leftovers):
raise ResourceNotFoundError("No disk with the name '{}' was found".format(disk_name))
else:
DiskDetachOptionTypes = cmd.get_models('DiskDetachOptionTypes', resource_type=ResourceType.MGMT_COMPUTE,
operation_group='virtual_machines')
leftovers = vm.storage_profile.data_disks
is_contains = False
for d in leftovers:
if d.name.lower() == disk_name.lower():
d.to_be_detached = True
d.detach_option = DiskDetachOptionTypes.FORCE_DETACH
is_contains = True
break
if not is_contains:
raise ResourceNotFoundError("No disk with the name '{}' was found".format(disk_name))
vm.storage_profile.data_disks = leftovers
set_vm(cmd, vm)
# endregion


# region VirtualMachines Extensions
def list_extensions(cmd, resource_group_name, vm_name):
vm = get_vm(cmd, resource_group_name, vm_name)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
_get_extension_instance_name,
get_boot_log)
from azure.cli.command_modules.vm.custom import \
(attach_unmanaged_data_disk, detach_data_disk, get_vmss_instance_view)
(attach_unmanaged_data_disk, detach_unmanaged_data_disk, get_vmss_instance_view)

from azure.cli.core import AzCommandsLoader
from azure.cli.core.commands import AzCliCommand
Expand Down Expand Up @@ -206,7 +206,7 @@ def test_deattach_disk_on_vm(self, mock_vm_set, mock_vm_get_to_update):
mock_vm_get_to_update.return_value = vm

# execute
detach_data_disk(cmd, 'rg1', 'vm1', 'd1')
detach_unmanaged_data_disk(cmd, 'rg1', 'vm1', 'd1')

# assert
self.assertTrue(mock_vm_get_to_update.called)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
_get_extension_instance_name,
get_boot_log)
from azure.cli.command_modules.vm.custom import \
(attach_unmanaged_data_disk, detach_data_disk, get_vmss_instance_view)
(attach_unmanaged_data_disk, detach_unmanaged_data_disk, get_vmss_instance_view)

from azure.cli.core import AzCommandsLoader
from azure.cli.core.commands import AzCliCommand
Expand Down Expand Up @@ -206,7 +206,7 @@ def test_deattach_disk_on_vm(self, mock_vm_set, mock_vm_get_to_update):
mock_vm_get_to_update.return_value = vm

# execute
detach_data_disk(cmd, 'rg1', 'vm1', 'd1')
detach_unmanaged_data_disk(cmd, 'rg1', 'vm1', 'd1')

# assert
self.assertTrue(mock_vm_get_to_update.called)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
_get_extension_instance_name,
get_boot_log)
from azure.cli.command_modules.vm.custom import \
(attach_unmanaged_data_disk, detach_data_disk, get_vmss_instance_view)
(attach_unmanaged_data_disk, detach_unmanaged_data_disk, get_vmss_instance_view)

from azure.cli.core import AzCommandsLoader
from azure.cli.core.commands import AzCliCommand
Expand Down Expand Up @@ -218,7 +218,7 @@ def test_deattach_disk_on_vm(self, mock_vm_set, mock_vm_get_to_update):
mock_vm_get_to_update.return_value = vm

# execute
detach_data_disk(cmd, 'rg1', 'vm1', 'd1')
detach_unmanaged_data_disk(cmd, 'rg1', 'vm1', 'd1')

# assert
self.assertTrue(mock_vm_get_to_update.called)
Expand Down
Loading