1
0
mirror of https://github.com/netbox-community/netbox.git synced 2024-05-10 07:54:54 +00:00

#2269: Allow non-unique VirtualMachine names

This commit is contained in:
Jeremy Stretch
2019-12-09 11:59:30 -05:00
parent a8dd060e32
commit 2e37b19e9f
3 changed files with 85 additions and 2 deletions

View File

@ -0,0 +1,23 @@
# Generated by Django 2.2.6 on 2019-12-09 16:57
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('tenancy', '0006_custom_tag_models'),
('virtualization', '0011_3569_virtualmachine_fields'),
]
operations = [
migrations.AlterField(
model_name='virtualmachine',
name='name',
field=models.CharField(max_length=64),
),
migrations.AlterUniqueTogether(
name='virtualmachine',
unique_together={('cluster', 'tenant', 'name')},
),
]

View File

@ -193,8 +193,7 @@ class VirtualMachine(ChangeLoggedModel, ConfigContextModel, CustomFieldModel):
null=True
)
name = models.CharField(
max_length=64,
unique=True
max_length=64
)
status = models.CharField(
max_length=50,
@ -267,6 +266,9 @@ class VirtualMachine(ChangeLoggedModel, ConfigContextModel, CustomFieldModel):
class Meta:
ordering = ['name']
unique_together = [
['cluster', 'tenant', 'name']
]
def __str__(self):
return self.name
@ -274,6 +276,20 @@ class VirtualMachine(ChangeLoggedModel, ConfigContextModel, CustomFieldModel):
def get_absolute_url(self):
return reverse('virtualization:virtualmachine', args=[self.pk])
def validate_unique(self, exclude=None):
# Check for a duplicate name on a VM assigned to the same Cluster and no Tenant. This is necessary
# because Django does not consider two NULL fields to be equal, and thus will not trigger a violation
# of the uniqueness constraint without manual intervention.
if self.tenant is None and VirtualMachine.objects.exclude(pk=self.pk).filter(
name=self.name, tenant__isnull=True
):
raise ValidationError({
'name': 'A virtual machine with this name already exists.'
})
super().validate_unique(exclude)
def clean(self):
super().clean()

View File

@ -0,0 +1,44 @@
from django.test import TestCase
from virtualization.models import *
from tenancy.models import Tenant
class VirtualMachineTestCase(TestCase):
def setUp(self):
cluster_type = ClusterType.objects.create(name='Test Cluster Type 1', slug='Test Cluster Type 1')
self.cluster = Cluster.objects.create(name='Test Cluster 1', type=cluster_type)
def test_vm_duplicate_name_per_cluster(self):
vm1 = VirtualMachine(
cluster=self.cluster,
name='Test VM 1'
)
vm1.save()
vm2 = VirtualMachine(
cluster=vm1.cluster,
name=vm1.name
)
# Two VMs assigned to the same Cluster and no Tenant should fail validation
with self.assertRaises(ValidationError):
vm2.full_clean()
tenant = Tenant.objects.create(name='Test Tenant 1', slug='test-tenant-1')
vm1.tenant = tenant
vm1.save()
vm2.tenant = tenant
# Two VMs assigned to the same Cluster and the same Tenant should fail validation
with self.assertRaises(ValidationError):
vm2.full_clean()
vm2.tenant = None
# Two VMs assigned to the same Cluster and different Tenants should pass validation
vm2.full_clean()
vm2.save()