mirror of
https://github.com/netbox-community/netbox.git
synced 2025-08-25 08:46:10 -06:00
Post-review changes
* Remove VDC Type * Remove M2M Enforcement logic
This commit is contained in:
parent
0896b84bea
commit
0d3b85936e
@ -475,4 +475,4 @@ class NestedVirtualDeviceContextSerializer(WritableNestedSerializer):
|
|||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = models.VirtualDeviceContext
|
model = models.VirtualDeviceContext
|
||||||
fields = ['id', 'url', 'display', 'name', 'identifier', 'device', 'vdc_type']
|
fields = ['id', 'url', 'display', 'name', 'identifier', 'device']
|
||||||
|
@ -317,7 +317,6 @@ class DeviceTypeSerializer(NetBoxModelSerializer):
|
|||||||
)
|
)
|
||||||
subdevice_role = ChoiceField(choices=SubdeviceRoleChoices, allow_blank=True, required=False)
|
subdevice_role = ChoiceField(choices=SubdeviceRoleChoices, allow_blank=True, required=False)
|
||||||
airflow = ChoiceField(choices=DeviceAirflowChoices, allow_blank=True, required=False)
|
airflow = ChoiceField(choices=DeviceAirflowChoices, allow_blank=True, required=False)
|
||||||
vdc_type = ChoiceField(choices=VirtualDeviceContextTypeChoices, allow_blank=True, required=False)
|
|
||||||
weight_unit = ChoiceField(choices=WeightUnitChoices, allow_blank=True, required=False)
|
weight_unit = ChoiceField(choices=WeightUnitChoices, allow_blank=True, required=False)
|
||||||
device_count = serializers.IntegerField(read_only=True)
|
device_count = serializers.IntegerField(read_only=True)
|
||||||
|
|
||||||
@ -325,7 +324,7 @@ class DeviceTypeSerializer(NetBoxModelSerializer):
|
|||||||
model = DeviceType
|
model = DeviceType
|
||||||
fields = [
|
fields = [
|
||||||
'id', 'url', 'display', 'manufacturer', 'model', 'slug', 'part_number', 'u_height', 'is_full_depth',
|
'id', 'url', 'display', 'manufacturer', 'model', 'slug', 'part_number', 'u_height', 'is_full_depth',
|
||||||
'subdevice_role', 'vdc_type', 'airflow', 'weight', 'weight_unit', 'front_image', 'rear_image', 'comments',
|
'subdevice_role', 'airflow', 'weight', 'weight_unit', 'front_image', 'rear_image', 'comments',
|
||||||
'tags', 'custom_fields', 'created', 'last_updated', 'device_count',
|
'tags', 'custom_fields', 'created', 'last_updated', 'device_count',
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -435,9 +435,6 @@ class DeviceTypeFilterSet(NetBoxModelFilterSet):
|
|||||||
to_field_name='slug',
|
to_field_name='slug',
|
||||||
label='Manufacturer (slug)',
|
label='Manufacturer (slug)',
|
||||||
)
|
)
|
||||||
vdc_type = django_filters.MultipleChoiceFilter(
|
|
||||||
choices=VirtualDeviceContextTypeChoices
|
|
||||||
)
|
|
||||||
has_front_image = django_filters.BooleanFilter(
|
has_front_image = django_filters.BooleanFilter(
|
||||||
label='Has a front image',
|
label='Has a front image',
|
||||||
method='_has_front_image'
|
method='_has_front_image'
|
||||||
@ -486,7 +483,7 @@ class DeviceTypeFilterSet(NetBoxModelFilterSet):
|
|||||||
class Meta:
|
class Meta:
|
||||||
model = DeviceType
|
model = DeviceType
|
||||||
fields = [
|
fields = [
|
||||||
'id', 'model', 'slug', 'part_number', 'u_height', 'is_full_depth', 'subdevice_role', 'airflow', 'weight', 'weight_unit', 'vdc_type',
|
'id', 'model', 'slug', 'part_number', 'u_height', 'is_full_depth', 'subdevice_role', 'airflow', 'weight', 'weight_unit',
|
||||||
]
|
]
|
||||||
|
|
||||||
def search(self, queryset, name, value):
|
def search(self, queryset, name, value):
|
||||||
|
@ -373,7 +373,7 @@ class DeviceTypeFilterForm(NetBoxModelFilterSetForm):
|
|||||||
model = DeviceType
|
model = DeviceType
|
||||||
fieldsets = (
|
fieldsets = (
|
||||||
(None, ('q', 'tag')),
|
(None, ('q', 'tag')),
|
||||||
('Hardware', ('manufacturer_id', 'part_number', 'subdevice_role', 'airflow', 'vdc_type')),
|
('Hardware', ('manufacturer_id', 'part_number', 'subdevice_role', 'airflow')),
|
||||||
('Images', ('has_front_image', 'has_rear_image')),
|
('Images', ('has_front_image', 'has_rear_image')),
|
||||||
('Components', (
|
('Components', (
|
||||||
'console_ports', 'console_server_ports', 'power_ports', 'power_outlets', 'interfaces',
|
'console_ports', 'console_server_ports', 'power_ports', 'power_outlets', 'interfaces',
|
||||||
@ -397,10 +397,6 @@ class DeviceTypeFilterForm(NetBoxModelFilterSetForm):
|
|||||||
choices=add_blank_choice(DeviceAirflowChoices),
|
choices=add_blank_choice(DeviceAirflowChoices),
|
||||||
required=False
|
required=False
|
||||||
)
|
)
|
||||||
vdc_type = MultipleChoiceField(
|
|
||||||
choices=add_blank_choice(VirtualDeviceContextTypeChoices),
|
|
||||||
required=False
|
|
||||||
)
|
|
||||||
has_front_image = forms.NullBooleanField(
|
has_front_image = forms.NullBooleanField(
|
||||||
required=False,
|
required=False,
|
||||||
label='Has a front image',
|
label='Has a front image',
|
||||||
|
@ -387,7 +387,7 @@ class DeviceTypeForm(NetBoxModelForm):
|
|||||||
'manufacturer', 'model', 'slug', 'part_number', 'tags',
|
'manufacturer', 'model', 'slug', 'part_number', 'tags',
|
||||||
)),
|
)),
|
||||||
('Chassis', (
|
('Chassis', (
|
||||||
'u_height', 'is_full_depth', 'subdevice_role', 'airflow', 'vdc_type'
|
'u_height', 'is_full_depth', 'subdevice_role', 'airflow',
|
||||||
)),
|
)),
|
||||||
('Attributes', ('weight', 'weight_unit')),
|
('Attributes', ('weight', 'weight_unit')),
|
||||||
('Images', ('front_image', 'rear_image')),
|
('Images', ('front_image', 'rear_image')),
|
||||||
@ -397,7 +397,7 @@ class DeviceTypeForm(NetBoxModelForm):
|
|||||||
model = DeviceType
|
model = DeviceType
|
||||||
fields = [
|
fields = [
|
||||||
'manufacturer', 'model', 'slug', 'part_number', 'u_height', 'is_full_depth', 'subdevice_role', 'airflow',
|
'manufacturer', 'model', 'slug', 'part_number', 'u_height', 'is_full_depth', 'subdevice_role', 'airflow',
|
||||||
'vdc_type', 'weight', 'weight_unit', 'front_image', 'rear_image', 'comments', 'tags',
|
'weight', 'weight_unit', 'front_image', 'rear_image', 'comments', 'tags',
|
||||||
]
|
]
|
||||||
widgets = {
|
widgets = {
|
||||||
'airflow': StaticSelect(),
|
'airflow': StaticSelect(),
|
||||||
@ -1495,13 +1495,6 @@ class InterfaceForm(InterfaceCommonForm, ModularDeviceComponentForm):
|
|||||||
'rf_channel_width': "Populated by selected channel (if set)",
|
'rf_channel_width': "Populated by selected channel (if set)",
|
||||||
}
|
}
|
||||||
|
|
||||||
def clean_vdc(self):
|
|
||||||
device = self.cleaned_data.get('device')
|
|
||||||
if device.device_type.vdc_type not in [VirtualDeviceContextTypeChoices.CISCO_ASA_CONTEXT, VirtualDeviceContextTypeChoices.CISCO_FTD_INSTANCE]\
|
|
||||||
and len(self.cleaned_data.get('vdcs')) > 1:
|
|
||||||
raise forms.ValidationError(f"You cannot assign more then 1 VDC for {device.device_type}")
|
|
||||||
return self.cleaned_data.get('vdcs')
|
|
||||||
|
|
||||||
|
|
||||||
class FrontPortForm(ModularDeviceComponentForm):
|
class FrontPortForm(ModularDeviceComponentForm):
|
||||||
rear_port = DynamicModelChoiceField(
|
rear_port = DynamicModelChoiceField(
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
# Generated by Django 4.1.2 on 2022-11-01 19:38
|
# Generated by Django 4.1.2 on 2022-11-02 13:24
|
||||||
|
|
||||||
from django.db import migrations, models
|
from django.db import migrations, models
|
||||||
import django.db.models.deletion
|
import django.db.models.deletion
|
||||||
@ -16,11 +16,6 @@ class Migration(migrations.Migration):
|
|||||||
]
|
]
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
migrations.AddField(
|
|
||||||
model_name='devicetype',
|
|
||||||
name='vdc_type',
|
|
||||||
field=models.CharField(blank=True, max_length=50),
|
|
||||||
),
|
|
||||||
migrations.CreateModel(
|
migrations.CreateModel(
|
||||||
name='VirtualDeviceContext',
|
name='VirtualDeviceContext',
|
||||||
fields=[
|
fields=[
|
@ -1,142 +0,0 @@
|
|||||||
# Generated by Django 4.1.1 on 2022-11-01 18:05
|
|
||||||
|
|
||||||
from django.db import migrations, models
|
|
||||||
import django.db.models.deletion
|
|
||||||
import taggit.managers
|
|
||||||
import utilities.json
|
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
|
||||||
|
|
||||||
dependencies = [
|
|
||||||
('extras', '0082_exporttemplate_content_types'),
|
|
||||||
('tenancy', '0008_unique_constraints'),
|
|
||||||
('ipam', '0062_unique_constraints'),
|
|
||||||
('dcim', '0165_remove_consoleport_dcim_consoleport_unique_device_name_and_more'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
|
||||||
migrations.CreateModel(
|
|
||||||
name='VirtualDeviceContext',
|
|
||||||
fields=[
|
|
||||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False)),
|
|
||||||
('created', models.DateTimeField(auto_now_add=True, null=True)),
|
|
||||||
('last_updated', models.DateTimeField(auto_now=True, null=True)),
|
|
||||||
('custom_field_data', models.JSONField(blank=True, default=dict, encoder=utilities.json.CustomFieldJSONEncoder)),
|
|
||||||
('name', models.CharField(max_length=64)),
|
|
||||||
('status', models.CharField(blank=True, max_length=50)),
|
|
||||||
('identifier', models.PositiveSmallIntegerField(blank=True, null=True)),
|
|
||||||
('comments', models.TextField(blank=True)),
|
|
||||||
],
|
|
||||||
options={
|
|
||||||
'ordering': ['name'],
|
|
||||||
},
|
|
||||||
),
|
|
||||||
migrations.RemoveConstraint(
|
|
||||||
model_name='consoleport',
|
|
||||||
name='dcim_consoleport_unique_device_name',
|
|
||||||
),
|
|
||||||
migrations.RemoveConstraint(
|
|
||||||
model_name='consoleserverport',
|
|
||||||
name='dcim_consoleserverport_unique_device_name',
|
|
||||||
),
|
|
||||||
migrations.RemoveConstraint(
|
|
||||||
model_name='devicebay',
|
|
||||||
name='dcim_devicebay_unique_device_name',
|
|
||||||
),
|
|
||||||
migrations.RemoveConstraint(
|
|
||||||
model_name='interface',
|
|
||||||
name='dcim_interface_unique_device_name',
|
|
||||||
),
|
|
||||||
migrations.RemoveConstraint(
|
|
||||||
model_name='modulebay',
|
|
||||||
name='dcim_modulebay_unique_device_name',
|
|
||||||
),
|
|
||||||
migrations.RemoveConstraint(
|
|
||||||
model_name='poweroutlet',
|
|
||||||
name='dcim_poweroutlet_unique_device_name',
|
|
||||||
),
|
|
||||||
migrations.RemoveConstraint(
|
|
||||||
model_name='powerport',
|
|
||||||
name='dcim_powerport_unique_device_name',
|
|
||||||
),
|
|
||||||
migrations.RemoveConstraint(
|
|
||||||
model_name='rearport',
|
|
||||||
name='dcim_rearport_unique_device_name',
|
|
||||||
),
|
|
||||||
migrations.AddField(
|
|
||||||
model_name='devicetype',
|
|
||||||
name='vdc_type',
|
|
||||||
field=models.CharField(blank=True, max_length=50),
|
|
||||||
),
|
|
||||||
migrations.AddConstraint(
|
|
||||||
model_name='consoleport',
|
|
||||||
constraint=models.UniqueConstraint(fields=('device', 'name'), name='dcim_consoleport_unique_device_name'),
|
|
||||||
),
|
|
||||||
migrations.AddConstraint(
|
|
||||||
model_name='consoleserverport',
|
|
||||||
constraint=models.UniqueConstraint(fields=('device', 'name'), name='dcim_consoleserverport_unique_device_name'),
|
|
||||||
),
|
|
||||||
migrations.AddConstraint(
|
|
||||||
model_name='devicebay',
|
|
||||||
constraint=models.UniqueConstraint(fields=('device', 'name'), name='dcim_devicebay_unique_device_name'),
|
|
||||||
),
|
|
||||||
migrations.AddConstraint(
|
|
||||||
model_name='interface',
|
|
||||||
constraint=models.UniqueConstraint(fields=('device', 'name'), name='dcim_interface_unique_device_name'),
|
|
||||||
),
|
|
||||||
migrations.AddConstraint(
|
|
||||||
model_name='modulebay',
|
|
||||||
constraint=models.UniqueConstraint(fields=('device', 'name'), name='dcim_modulebay_unique_device_name'),
|
|
||||||
),
|
|
||||||
migrations.AddConstraint(
|
|
||||||
model_name='poweroutlet',
|
|
||||||
constraint=models.UniqueConstraint(fields=('device', 'name'), name='dcim_poweroutlet_unique_device_name'),
|
|
||||||
),
|
|
||||||
migrations.AddConstraint(
|
|
||||||
model_name='powerport',
|
|
||||||
constraint=models.UniqueConstraint(fields=('device', 'name'), name='dcim_powerport_unique_device_name'),
|
|
||||||
),
|
|
||||||
migrations.AddConstraint(
|
|
||||||
model_name='rearport',
|
|
||||||
constraint=models.UniqueConstraint(fields=('device', 'name'), name='dcim_rearport_unique_device_name'),
|
|
||||||
),
|
|
||||||
migrations.AddField(
|
|
||||||
model_name='virtualdevicecontext',
|
|
||||||
name='device',
|
|
||||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='vdcs', to='dcim.device'),
|
|
||||||
),
|
|
||||||
migrations.AddField(
|
|
||||||
model_name='virtualdevicecontext',
|
|
||||||
name='primary_ip4',
|
|
||||||
field=models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='ipam.ipaddress'),
|
|
||||||
),
|
|
||||||
migrations.AddField(
|
|
||||||
model_name='virtualdevicecontext',
|
|
||||||
name='primary_ip6',
|
|
||||||
field=models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='ipam.ipaddress'),
|
|
||||||
),
|
|
||||||
migrations.AddField(
|
|
||||||
model_name='virtualdevicecontext',
|
|
||||||
name='tags',
|
|
||||||
field=taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag'),
|
|
||||||
),
|
|
||||||
migrations.AddField(
|
|
||||||
model_name='virtualdevicecontext',
|
|
||||||
name='tenant',
|
|
||||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='vdcs', to='tenancy.tenant'),
|
|
||||||
),
|
|
||||||
migrations.AddField(
|
|
||||||
model_name='interface',
|
|
||||||
name='vdcs',
|
|
||||||
field=models.ManyToManyField(related_name='interfaces', to='dcim.virtualdevicecontext'),
|
|
||||||
),
|
|
||||||
migrations.AddConstraint(
|
|
||||||
model_name='virtualdevicecontext',
|
|
||||||
constraint=models.UniqueConstraint(fields=('device', 'identifier'), name='dcim_virtualdevicecontext_device_identifiers', violation_error_message='A VDC with this identifier already exists on this device.'),
|
|
||||||
),
|
|
||||||
migrations.AddConstraint(
|
|
||||||
model_name='virtualdevicecontext',
|
|
||||||
constraint=models.UniqueConstraint(fields=('device', 'name'), name='dcim_virtualdevicecontext_name', violation_error_message='A VDC with this name already exists on this device.'),
|
|
||||||
),
|
|
||||||
]
|
|
@ -129,12 +129,6 @@ class DeviceType(NetBoxModel, WeightMixin):
|
|||||||
choices=DeviceAirflowChoices,
|
choices=DeviceAirflowChoices,
|
||||||
blank=True
|
blank=True
|
||||||
)
|
)
|
||||||
vdc_type = models.CharField(
|
|
||||||
max_length=50,
|
|
||||||
blank=True,
|
|
||||||
choices=VirtualDeviceContextTypeChoices,
|
|
||||||
verbose_name='VDC Type'
|
|
||||||
)
|
|
||||||
front_image = models.ImageField(
|
front_image = models.ImageField(
|
||||||
upload_to='devicetype-images',
|
upload_to='devicetype-images',
|
||||||
blank=True
|
blank=True
|
||||||
@ -148,7 +142,7 @@ class DeviceType(NetBoxModel, WeightMixin):
|
|||||||
)
|
)
|
||||||
|
|
||||||
clone_fields = (
|
clone_fields = (
|
||||||
'manufacturer', 'u_height', 'is_full_depth', 'subdevice_role', 'airflow', 'weight', 'weight_unit', 'vdc_type'
|
'manufacturer', 'u_height', 'is_full_depth', 'subdevice_role', 'airflow', 'weight', 'weight_unit'
|
||||||
)
|
)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
@ -1216,7 +1210,3 @@ class VirtualDeviceContext(NetBoxModel):
|
|||||||
return self.primary_ip4
|
return self.primary_ip4
|
||||||
else:
|
else:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
@property
|
|
||||||
def vdc_type(self):
|
|
||||||
return self.device.device_type.vdc_type
|
|
||||||
|
@ -125,14 +125,3 @@ def nullify_connected_endpoints(instance, **kwargs):
|
|||||||
|
|
||||||
for cablepath in CablePath.objects.filter(_nodes__contains=instance.cable):
|
for cablepath in CablePath.objects.filter(_nodes__contains=instance.cable):
|
||||||
cablepath.retrace()
|
cablepath.retrace()
|
||||||
|
|
||||||
|
|
||||||
@receiver(m2m_changed, sender=Interface.vdcs.through)
|
|
||||||
def enforce_vdc_type_restrictions(instance, **kwargs):
|
|
||||||
if 'action' == 'post_add':
|
|
||||||
device = instance.device
|
|
||||||
if device.device_type.vdc_type not in [VirtualDeviceContextTypeChoices.CISCO_ASA_CONTEXT, VirtualDeviceContextTypeChoices.CISCO_FTD_INSTANCE] \
|
|
||||||
and len(instance.vdcs) > 1:
|
|
||||||
raise forms.ValidationError({
|
|
||||||
'vdcs': f"You cannot assign more then 1 VDC for {device.device_type}"
|
|
||||||
})
|
|
||||||
|
@ -57,12 +57,6 @@
|
|||||||
{{ object.get_airflow_display|placeholder }}
|
{{ object.get_airflow_display|placeholder }}
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
|
||||||
<td>VDC Type</td>
|
|
||||||
<td>
|
|
||||||
{{ object.get_vdc_type_display|placeholder }}
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
<tr>
|
||||||
<td>Front Image</td>
|
<td>Front Image</td>
|
||||||
<td>
|
<td>
|
||||||
|
@ -37,10 +37,6 @@
|
|||||||
<td>{{ object.identifier|placeholder }}</td>
|
<td>{{ object.identifier|placeholder }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
|
||||||
<th scope="row">VDC Type</th>
|
|
||||||
<td>{{ object.device.device_type.get_vdc_type_display |placeholder }}</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
<tr>
|
||||||
<th scope="row">Primary IPv4</th>
|
<th scope="row">Primary IPv4</th>
|
||||||
<td>
|
<td>
|
||||||
|
Loading…
Reference in New Issue
Block a user