mirror of
https://github.com/netbox-community/netbox.git
synced 2024-05-10 07:54:54 +00:00
Merge branch 'feature' of https://github.com/netbox-community/netbox into feature
# Conflicts: # netbox/project-static/js/forms.js # netbox/templates/dcim/location.html # netbox/templates/generic/object_list.html
This commit is contained in:
@@ -376,6 +376,7 @@ class VirtualMachineForm(BootstrapMixin, TenancyForm, CustomFieldModelForm):
|
||||
fieldsets = (
|
||||
('Virtual Machine', ('name', 'role', 'status', 'tags')),
|
||||
('Cluster', ('cluster_group', 'cluster')),
|
||||
('Tenancy', ('tenant_group', 'tenant')),
|
||||
('Management', ('platform', 'primary_ip4', 'primary_ip6')),
|
||||
('Resources', ('vcpus', 'memory', 'disk')),
|
||||
('Config Context', ('local_context_data',)),
|
||||
@@ -666,7 +667,6 @@ class VMInterfaceCreateForm(BootstrapMixin, InterfaceCommonForm):
|
||||
parent = DynamicModelChoiceField(
|
||||
queryset=VMInterface.objects.all(),
|
||||
required=False,
|
||||
display_field='display_name',
|
||||
query_params={
|
||||
'virtualmachine_id': 'virtual_machine',
|
||||
}
|
||||
@@ -702,6 +702,10 @@ class VMInterfaceCreateForm(BootstrapMixin, InterfaceCommonForm):
|
||||
queryset=Tag.objects.all(),
|
||||
required=False
|
||||
)
|
||||
field_order = (
|
||||
'virtual_machine', 'name_pattern', 'enabled', 'parent', 'mtu', 'mac_address', 'description', 'mode',
|
||||
'untagged_vlan', 'tagged_vlans', 'tags'
|
||||
)
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
@@ -751,8 +755,7 @@ class VMInterfaceBulkEditForm(BootstrapMixin, AddRemoveTagsForm, BulkEditForm):
|
||||
)
|
||||
parent = DynamicModelChoiceField(
|
||||
queryset=VMInterface.objects.all(),
|
||||
required=False,
|
||||
display_field='display_name'
|
||||
required=False
|
||||
)
|
||||
enabled = forms.NullBooleanField(
|
||||
required=False,
|
||||
|
@@ -0,0 +1,32 @@
|
||||
from django.db import migrations
|
||||
import utilities.fields
|
||||
import utilities.ordering
|
||||
|
||||
|
||||
def naturalize_virtualmachines(apps, schema_editor):
|
||||
VirtualMachine = apps.get_model('virtualization', 'VirtualMachine')
|
||||
for name in VirtualMachine.objects.values_list('name', flat=True).order_by('name').distinct():
|
||||
VirtualMachine.objects.filter(name=name).update(_name=utilities.ordering.naturalize(name, max_length=100))
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('virtualization', '0022_vminterface_parent'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterModelOptions(
|
||||
name='virtualmachine',
|
||||
options={'ordering': ('_name', 'pk')},
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='virtualmachine',
|
||||
name='_name',
|
||||
field=utilities.fields.NaturalOrderingField('name', max_length=100, blank=True, naturalize_function=utilities.ordering.naturalize),
|
||||
),
|
||||
migrations.RunPython(
|
||||
code=naturalize_virtualmachines,
|
||||
reverse_code=migrations.RunPython.noop
|
||||
),
|
||||
]
|
@@ -226,6 +226,11 @@ class VirtualMachine(PrimaryModel, ConfigContextModel):
|
||||
name = models.CharField(
|
||||
max_length=64
|
||||
)
|
||||
_name = NaturalOrderingField(
|
||||
target_field='name',
|
||||
max_length=100,
|
||||
blank=True
|
||||
)
|
||||
status = models.CharField(
|
||||
max_length=50,
|
||||
choices=VirtualMachineStatusChoices,
|
||||
@@ -296,7 +301,7 @@ class VirtualMachine(PrimaryModel, ConfigContextModel):
|
||||
]
|
||||
|
||||
class Meta:
|
||||
ordering = ('name', 'pk') # Name may be non-unique
|
||||
ordering = ('_name', 'pk') # Name may be non-unique
|
||||
unique_together = [
|
||||
['cluster', 'tenant', 'name']
|
||||
]
|
||||
@@ -463,6 +468,10 @@ class VMInterface(PrimaryModel, BaseInterface):
|
||||
f"({self.parent.virtual_machine})."
|
||||
})
|
||||
|
||||
# An interface cannot be its own parent
|
||||
if self.pk and self.parent_id == self.pk:
|
||||
raise ValidationError({'parent': "An interface cannot be its own parent."})
|
||||
|
||||
# Validate untagged VLAN
|
||||
if self.untagged_vlan and self.untagged_vlan.site not in [self.virtual_machine.site, None]:
|
||||
raise ValidationError({
|
||||
|
Reference in New Issue
Block a user