Merge pull request #22015 from netbox-community/21990-device
#21990 fix deletion of device from Virtual Machines
This commit is contained in:
commit
6a675d7fa7
|
|
@ -1754,6 +1754,13 @@ class VirtualDeviceContextBulkEditForm(PrimaryModelBulkEditForm):
|
|||
)
|
||||
nullable_fields = ('device', 'tenant', )
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
# The ?device=<id> GET param is navigation context (filter), not an intent to change the
|
||||
# device field — drop it from initial so Django's changed_data doesn't treat it as an edit.
|
||||
self.initial.pop('device', None)
|
||||
|
||||
|
||||
#
|
||||
# Addressing
|
||||
|
|
|
|||
|
|
@ -4027,6 +4027,33 @@ class VirtualDeviceContextTestCase(ViewTestCases.PrimaryObjectViewTestCase):
|
|||
'status': VirtualDeviceContextStatusChoices.STATUS_OFFLINE,
|
||||
}
|
||||
|
||||
def test_bulk_edit_device_context_preserves_device(self):
|
||||
"""
|
||||
Regression test: Bulk editing VDCs from the Device's VDCs tab (URL contains
|
||||
?device=<id>) must not clear the device field on those VDCs.
|
||||
"""
|
||||
self.add_permissions('dcim.view_virtualdevicecontext', 'dcim.change_virtualdevicecontext')
|
||||
|
||||
device = VirtualDeviceContext.objects.filter(device__isnull=False).first().device
|
||||
vdcs = list(VirtualDeviceContext.objects.filter(device=device)[:3])
|
||||
pk_list = [vdc.pk for vdc in vdcs]
|
||||
|
||||
data = {
|
||||
'pk': pk_list,
|
||||
'_apply': True,
|
||||
# Only change status — device is intentionally omitted
|
||||
'status': VirtualDeviceContextStatusChoices.STATUS_PLANNED,
|
||||
}
|
||||
|
||||
# Simulate navigation from Device -> VDCs tab by passing ?device=<id> as GET param
|
||||
url = reverse('dcim:virtualdevicecontext_bulk_edit') + f'?device={device.pk}'
|
||||
response = self.client.post(url, data)
|
||||
self.assertHttpStatus(response, 302)
|
||||
|
||||
for vdc in VirtualDeviceContext.objects.filter(pk__in=pk_list):
|
||||
self.assertEqual(vdc.device, device, msg=f"Device was unexpectedly cleared on VDC '{vdc.name}'")
|
||||
self.assertEqual(vdc.status, VirtualDeviceContextStatusChoices.STATUS_PLANNED)
|
||||
|
||||
|
||||
class MACAddressTestCase(ViewTestCases.PrimaryObjectViewTestCase):
|
||||
model = MACAddress
|
||||
|
|
|
|||
|
|
@ -164,6 +164,10 @@ class VirtualMachineBulkEditForm(PrimaryModelBulkEditForm):
|
|||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
# The ?device=<id> GET param is navigation context (filter), not an intent to change the
|
||||
# device field — drop it from initial so Django's changed_data doesn't treat it as an edit.
|
||||
self.initial.pop('device', None)
|
||||
|
||||
# Set unit labels based on configured RAM_BASE_UNIT / DISK_BASE_UNIT (MB vs MiB)
|
||||
self.fields['memory'].label = _('Memory ({unit})').format(unit=get_capacity_unit_label(settings.RAM_BASE_UNIT))
|
||||
self.fields['disk'].label = _('Disk ({unit})').format(unit=get_capacity_unit_label(settings.DISK_BASE_UNIT))
|
||||
|
|
|
|||
|
|
@ -335,6 +335,33 @@ class VirtualMachineTestCase(ViewTestCases.PrimaryObjectViewTestCase):
|
|||
url = reverse('virtualization:virtualmachine_interfaces', kwargs={'pk': virtualmachine.pk})
|
||||
self.assertHttpStatus(self.client.get(url), 200)
|
||||
|
||||
def test_bulk_edit_device_context_preserves_device(self):
|
||||
"""
|
||||
Regression test for #21990: Bulk editing VMs from the Device's VMs tab (URL contains
|
||||
?device=<id>) must not clear the device field on those VMs.
|
||||
"""
|
||||
self.add_permissions('virtualization.view_virtualmachine', 'virtualization.change_virtualmachine')
|
||||
|
||||
device = VirtualMachine.objects.filter(device__isnull=False).first().device
|
||||
vms = list(VirtualMachine.objects.filter(device=device)[:3])
|
||||
pk_list = [vm.pk for vm in vms]
|
||||
|
||||
data = {
|
||||
'pk': pk_list,
|
||||
'_apply': True,
|
||||
# Only change status — device is intentionally omitted
|
||||
'status': VirtualMachineStatusChoices.STATUS_STAGED,
|
||||
}
|
||||
|
||||
# Simulate navigation from Device -> Virtual Machines tab by passing ?device=<id> as GET param
|
||||
url = reverse('virtualization:virtualmachine_bulk_edit') + f'?device={device.pk}'
|
||||
response = self.client.post(url, data)
|
||||
self.assertHttpStatus(response, 302)
|
||||
|
||||
for vm in VirtualMachine.objects.filter(pk__in=pk_list):
|
||||
self.assertEqual(vm.device, device, msg=f"Device was unexpectedly cleared on VM '{vm.name}'")
|
||||
self.assertEqual(vm.status, VirtualMachineStatusChoices.STATUS_STAGED)
|
||||
|
||||
def test_virtualmachine_renderconfig(self):
|
||||
configtemplate = ConfigTemplate.objects.create(
|
||||
name='Test Config Template',
|
||||
|
|
|
|||
Loading…
Reference in New Issue