diff --git a/netbox/virtualization/filtersets.py b/netbox/virtualization/filtersets.py index 645ac6572..ec6d1d8fa 100644 --- a/netbox/virtualization/filtersets.py +++ b/netbox/virtualization/filtersets.py @@ -321,7 +321,7 @@ class VirtualDiskFilterSet(NetBoxModelFilterSet): class Meta: model = VirtualDisk - fields = ['id', 'name', 'size',] + fields = ['id', 'name', 'size'] def search(self, queryset, name, value): if not value.strip(): diff --git a/netbox/virtualization/forms/filtersets.py b/netbox/virtualization/forms/filtersets.py index bc3160e8b..5eb3fea1c 100644 --- a/netbox/virtualization/forms/filtersets.py +++ b/netbox/virtualization/forms/filtersets.py @@ -229,10 +229,16 @@ class VirtualDiskFilterForm(NetBoxModelFilterSetForm): fieldsets = ( (None, ('q', 'filter_id', 'tag')), (_('Virtual Machine'), ('virtual_machine_id',)), + (_('Attributes'), ('size',)), ) virtual_machine_id = DynamicModelMultipleChoiceField( queryset=VirtualMachine.objects.all(), required=False, label=_('Virtual machine') ) + size = forms.IntegerField( + label=_('Size (GB)'), + required=False, + min_value=1 + ) tag = TagFilterField(model) diff --git a/netbox/virtualization/migrations/0037_virtualmachine_virtual_disk_count_virtualdisk.py b/netbox/virtualization/migrations/0037_virtualmachine_virtual_disk_count_virtualdisk_and_more.py similarity index 82% rename from netbox/virtualization/migrations/0037_virtualmachine_virtual_disk_count_virtualdisk.py rename to netbox/virtualization/migrations/0037_virtualmachine_virtual_disk_count_virtualdisk_and_more.py index fef7d7a8f..bf15d9af6 100644 --- a/netbox/virtualization/migrations/0037_virtualmachine_virtual_disk_count_virtualdisk.py +++ b/netbox/virtualization/migrations/0037_virtualmachine_virtual_disk_count_virtualdisk_and_more.py @@ -1,7 +1,8 @@ -# Generated by Django 4.2.5 on 2023-10-19 21:51 +# Generated by Django 4.2.5 on 2023-10-23 15:13 from django.db import migrations, models import django.db.models.deletion +import django.db.models.functions.text import taggit.managers import utilities.fields import utilities.json @@ -40,7 +41,7 @@ class Migration(migrations.Migration): 'name', blank=True, max_length=100, naturalize_function=utilities.ordering.naturalize ), ), - ('size', models.PositiveIntegerField(blank=True, null=True)), + ('size', models.PositiveIntegerField()), ('tags', taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag')), ( 'virtual_machine', @@ -58,4 +59,12 @@ class Migration(migrations.Migration): }, bases=(models.Model, utilities.tracking.TrackingModelMixin), ), + migrations.AddConstraint( + model_name='virtualdisk', + constraint=models.UniqueConstraint( + django.db.models.functions.text.Lower('name'), + models.F('virtual_machine'), + name='virtualization_virtualdisk_unique_name_virtual_machine', + ), + ), ] diff --git a/netbox/virtualization/models/virtualmachines.py b/netbox/virtualization/models/virtualmachines.py index 7e02a43d4..0fdddf9be 100644 --- a/netbox/virtualization/models/virtualmachines.py +++ b/netbox/virtualization/models/virtualmachines.py @@ -396,12 +396,16 @@ class VirtualDisk(NetBoxModel, TrackingModelMixin): ) size = models.PositiveIntegerField( verbose_name=_('size (GB)'), - blank=True, - null=True, ) class Meta: ordering = ('_name', 'pk') # Name may be non-unique + constraints = ( + models.UniqueConstraint( + Lower('name'), 'virtual_machine', + name='%(app_label)s_%(class)s_unique_name_virtual_machine' + ), + ) verbose_name = _('virtual disk') verbose_name_plural = _('virtual disks') diff --git a/netbox/virtualization/tables/virtualmachines.py b/netbox/virtualization/tables/virtualmachines.py index 9a7e15a86..a9c815e10 100644 --- a/netbox/virtualization/tables/virtualmachines.py +++ b/netbox/virtualization/tables/virtualmachines.py @@ -191,12 +191,8 @@ class VirtualMachineVirtualDiskTable(VirtualDiskTable): actions=('edit', 'delete'), ) - class Meta(NetBoxTable.Meta): - model = VirtualDisk + class Meta(VirtualDiskTable.Meta): fields = ( 'pk', 'id', 'name', 'size', 'tags', 'actions', ) default_columns = ('pk', 'name', 'size') - row_attrs = { - 'data-name': lambda record: record.name, - } diff --git a/netbox/virtualization/tests/test_filtersets.py b/netbox/virtualization/tests/test_filtersets.py index 41f4f1500..f9eada9e7 100644 --- a/netbox/virtualization/tests/test_filtersets.py +++ b/netbox/virtualization/tests/test_filtersets.py @@ -6,7 +6,7 @@ from tenancy.models import Tenant, TenantGroup from utilities.testing import ChangeLoggedFilterSetTests, create_test_device from virtualization.choices import * from virtualization.filtersets import * -from virtualization.models import Cluster, ClusterGroup, ClusterType, VirtualDisk, VirtualMachine, VMInterface +from virtualization.models import * class ClusterTypeTestCase(TestCase, ChangeLoggedFilterSetTests): diff --git a/netbox/virtualization/tests/test_views.py b/netbox/virtualization/tests/test_views.py index 400714c35..cf0cd665d 100644 --- a/netbox/virtualization/tests/test_views.py +++ b/netbox/virtualization/tests/test_views.py @@ -7,7 +7,7 @@ from dcim.models import DeviceRole, Platform, Site from ipam.models import VLAN, VRF from utilities.testing import ViewTestCases, create_tags, create_test_device from virtualization.choices import * -from virtualization.models import Cluster, ClusterGroup, ClusterType, VirtualDisk, VirtualMachine, VMInterface +from virtualization.models import * class ClusterGroupTestCase(ViewTestCases.OrganizationalObjectViewTestCase): diff --git a/netbox/virtualization/views.py b/netbox/virtualization/views.py index cf4bba962..4d12dcdd1 100644 --- a/netbox/virtualization/views.py +++ b/netbox/virtualization/views.py @@ -22,13 +22,13 @@ from tenancy.views import ObjectContactsView from utilities.utils import count_related from utilities.views import ViewTab, register_model_view from . import filtersets, forms, tables -from .models import Cluster, ClusterGroup, ClusterType, VirtualDisk, VirtualMachine, VMInterface - +from .models import * # # Cluster types # + class ClusterTypeListView(generic.ObjectListView): queryset = ClusterType.objects.annotate( cluster_count=count_related(Cluster, 'type') @@ -391,19 +391,17 @@ class VirtualMachineVirtualDisksView(generic.ObjectChildrenView): permission='virtualization.view_virtual_disk', weight=500 ) - actions = ('add', 'import', 'export', 'bulk_edit', 'bulk_delete', 'bulk_rename') - action_perms = defaultdict(set, **{ + actions = { 'add': {'add'}, 'import': {'add'}, + 'export': {'view'}, 'bulk_edit': {'change'}, 'bulk_delete': {'delete'}, 'bulk_rename': {'change'}, - }) + } def get_children(self, request, parent): - return parent.virtualdisks.restrict(request.user, 'view').prefetch_related( - 'tags', - ) + return parent.virtualdisks.restrict(request.user, 'view').prefetch_related('tags',) @register_model_view(VirtualMachine, 'configcontext', path='config-context')