mirror of
https://github.com/netbox-community/netbox.git
synced 2025-07-20 10:16:42 -06:00
Move device and device_type ForeignKeys to abstract component models
This commit is contained in:
parent
d03d302eef
commit
1f9cdc71d4
@ -384,28 +384,28 @@ class DeviceTypeFilterSet(BaseFilterSet, CustomFieldFilterSet, CreatedUpdatedFil
|
|||||||
)
|
)
|
||||||
|
|
||||||
def _console_ports(self, queryset, name, value):
|
def _console_ports(self, queryset, name, value):
|
||||||
return queryset.exclude(consoleport_templates__isnull=value)
|
return queryset.exclude(consoleporttemplates__isnull=value)
|
||||||
|
|
||||||
def _console_server_ports(self, queryset, name, value):
|
def _console_server_ports(self, queryset, name, value):
|
||||||
return queryset.exclude(consoleserverport_templates__isnull=value)
|
return queryset.exclude(consoleserverporttemplates__isnull=value)
|
||||||
|
|
||||||
def _power_ports(self, queryset, name, value):
|
def _power_ports(self, queryset, name, value):
|
||||||
return queryset.exclude(powerport_templates__isnull=value)
|
return queryset.exclude(powerporttemplates__isnull=value)
|
||||||
|
|
||||||
def _power_outlets(self, queryset, name, value):
|
def _power_outlets(self, queryset, name, value):
|
||||||
return queryset.exclude(poweroutlet_templates__isnull=value)
|
return queryset.exclude(poweroutlettemplates__isnull=value)
|
||||||
|
|
||||||
def _interfaces(self, queryset, name, value):
|
def _interfaces(self, queryset, name, value):
|
||||||
return queryset.exclude(interface_templates__isnull=value)
|
return queryset.exclude(interfacetemplates__isnull=value)
|
||||||
|
|
||||||
def _pass_through_ports(self, queryset, name, value):
|
def _pass_through_ports(self, queryset, name, value):
|
||||||
return queryset.exclude(
|
return queryset.exclude(
|
||||||
frontport_templates__isnull=value,
|
frontporttemplates__isnull=value,
|
||||||
rearport_templates__isnull=value
|
rearporttemplates__isnull=value
|
||||||
)
|
)
|
||||||
|
|
||||||
def _device_bays(self, queryset, name, value):
|
def _device_bays(self, queryset, name, value):
|
||||||
return queryset.exclude(device_bay_templates__isnull=value)
|
return queryset.exclude(devicebaytemplates__isnull=value)
|
||||||
|
|
||||||
|
|
||||||
class DeviceTypeComponentFilterSet(NameSlugSearchFilterSet):
|
class DeviceTypeComponentFilterSet(NameSlugSearchFilterSet):
|
||||||
@ -656,7 +656,7 @@ class DeviceFilterSet(
|
|||||||
return queryset.filter(
|
return queryset.filter(
|
||||||
Q(name__icontains=value) |
|
Q(name__icontains=value) |
|
||||||
Q(serial__icontains=value.strip()) |
|
Q(serial__icontains=value.strip()) |
|
||||||
Q(inventory_items__serial__icontains=value.strip()) |
|
Q(inventoryitems__serial__icontains=value.strip()) |
|
||||||
Q(asset_tag__icontains=value.strip()) |
|
Q(asset_tag__icontains=value.strip()) |
|
||||||
Q(comments__icontains=value)
|
Q(comments__icontains=value)
|
||||||
).distinct()
|
).distinct()
|
||||||
@ -698,7 +698,7 @@ class DeviceFilterSet(
|
|||||||
)
|
)
|
||||||
|
|
||||||
def _device_bays(self, queryset, name, value):
|
def _device_bays(self, queryset, name, value):
|
||||||
return queryset.exclude(device_bays__isnull=value)
|
return queryset.exclude(devicebays__isnull=value)
|
||||||
|
|
||||||
|
|
||||||
class DeviceComponentFilterSet(django_filters.FilterSet):
|
class DeviceComponentFilterSet(django_filters.FilterSet):
|
||||||
|
@ -1392,7 +1392,7 @@ class FrontPortTemplateCreateForm(ComponentTemplateCreateForm):
|
|||||||
# Determine which rear port positions are occupied. These will be excluded from the list of available mappings.
|
# Determine which rear port positions are occupied. These will be excluded from the list of available mappings.
|
||||||
occupied_port_positions = [
|
occupied_port_positions = [
|
||||||
(front_port.rear_port_id, front_port.rear_port_position)
|
(front_port.rear_port_id, front_port.rear_port_position)
|
||||||
for front_port in device_type.frontport_templates.all()
|
for front_port in device_type.frontporttemplates.all()
|
||||||
]
|
]
|
||||||
|
|
||||||
# Populate rear port choices
|
# Populate rear port choices
|
||||||
|
@ -1,68 +0,0 @@
|
|||||||
# Generated by Django 3.0.6 on 2020-07-02 16:02
|
|
||||||
|
|
||||||
from django.db import migrations, models
|
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
|
||||||
|
|
||||||
dependencies = [
|
|
||||||
('dcim', '0111_component_template_description'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
|
||||||
migrations.AlterField(
|
|
||||||
model_name='consoleport',
|
|
||||||
name='name',
|
|
||||||
field=models.CharField(max_length=64),
|
|
||||||
),
|
|
||||||
migrations.AlterField(
|
|
||||||
model_name='consoleporttemplate',
|
|
||||||
name='name',
|
|
||||||
field=models.CharField(max_length=64),
|
|
||||||
),
|
|
||||||
migrations.AlterField(
|
|
||||||
model_name='consoleserverport',
|
|
||||||
name='name',
|
|
||||||
field=models.CharField(max_length=64),
|
|
||||||
),
|
|
||||||
migrations.AlterField(
|
|
||||||
model_name='consoleserverporttemplate',
|
|
||||||
name='name',
|
|
||||||
field=models.CharField(max_length=64),
|
|
||||||
),
|
|
||||||
migrations.AlterField(
|
|
||||||
model_name='devicebay',
|
|
||||||
name='name',
|
|
||||||
field=models.CharField(max_length=64),
|
|
||||||
),
|
|
||||||
migrations.AlterField(
|
|
||||||
model_name='devicebaytemplate',
|
|
||||||
name='name',
|
|
||||||
field=models.CharField(max_length=64),
|
|
||||||
),
|
|
||||||
migrations.AlterField(
|
|
||||||
model_name='inventoryitem',
|
|
||||||
name='name',
|
|
||||||
field=models.CharField(max_length=64),
|
|
||||||
),
|
|
||||||
migrations.AlterField(
|
|
||||||
model_name='poweroutlet',
|
|
||||||
name='name',
|
|
||||||
field=models.CharField(max_length=64),
|
|
||||||
),
|
|
||||||
migrations.AlterField(
|
|
||||||
model_name='poweroutlettemplate',
|
|
||||||
name='name',
|
|
||||||
field=models.CharField(max_length=64),
|
|
||||||
),
|
|
||||||
migrations.AlterField(
|
|
||||||
model_name='powerport',
|
|
||||||
name='name',
|
|
||||||
field=models.CharField(max_length=64),
|
|
||||||
),
|
|
||||||
migrations.AlterField(
|
|
||||||
model_name='powerporttemplate',
|
|
||||||
name='name',
|
|
||||||
field=models.CharField(max_length=64),
|
|
||||||
),
|
|
||||||
]
|
|
120
netbox/dcim/migrations/0112_standardize_components.py
Normal file
120
netbox/dcim/migrations/0112_standardize_components.py
Normal file
@ -0,0 +1,120 @@
|
|||||||
|
from django.db import migrations, models
|
||||||
|
import django.db.models.deletion
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('dcim', '0111_component_template_description'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
# Set max_length=64 for all name fields
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='consoleport',
|
||||||
|
name='name',
|
||||||
|
field=models.CharField(max_length=64),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='consoleporttemplate',
|
||||||
|
name='name',
|
||||||
|
field=models.CharField(max_length=64),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='consoleserverport',
|
||||||
|
name='name',
|
||||||
|
field=models.CharField(max_length=64),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='consoleserverporttemplate',
|
||||||
|
name='name',
|
||||||
|
field=models.CharField(max_length=64),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='devicebay',
|
||||||
|
name='name',
|
||||||
|
field=models.CharField(max_length=64),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='devicebaytemplate',
|
||||||
|
name='name',
|
||||||
|
field=models.CharField(max_length=64),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='inventoryitem',
|
||||||
|
name='name',
|
||||||
|
field=models.CharField(max_length=64),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='poweroutlet',
|
||||||
|
name='name',
|
||||||
|
field=models.CharField(max_length=64),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='poweroutlettemplate',
|
||||||
|
name='name',
|
||||||
|
field=models.CharField(max_length=64),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='powerport',
|
||||||
|
name='name',
|
||||||
|
field=models.CharField(max_length=64),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='powerporttemplate',
|
||||||
|
name='name',
|
||||||
|
field=models.CharField(max_length=64),
|
||||||
|
),
|
||||||
|
|
||||||
|
# Update related_name for necessary component and component template models
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='consoleporttemplate',
|
||||||
|
name='device_type',
|
||||||
|
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='consoleporttemplates', to='dcim.DeviceType'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='consoleserverporttemplate',
|
||||||
|
name='device_type',
|
||||||
|
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='consoleserverporttemplates', to='dcim.DeviceType'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='devicebay',
|
||||||
|
name='device',
|
||||||
|
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='devicebays', to='dcim.Device'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='devicebaytemplate',
|
||||||
|
name='device_type',
|
||||||
|
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='devicebaytemplates', to='dcim.DeviceType'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='frontporttemplate',
|
||||||
|
name='device_type',
|
||||||
|
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='frontporttemplates', to='dcim.DeviceType'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='interfacetemplate',
|
||||||
|
name='device_type',
|
||||||
|
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='interfacetemplates', to='dcim.DeviceType'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='inventoryitem',
|
||||||
|
name='device',
|
||||||
|
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='inventoryitems', to='dcim.Device'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='poweroutlettemplate',
|
||||||
|
name='device_type',
|
||||||
|
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='poweroutlettemplates', to='dcim.DeviceType'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='powerporttemplate',
|
||||||
|
name='device_type',
|
||||||
|
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='powerporttemplates', to='dcim.DeviceType'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='rearporttemplate',
|
||||||
|
name='device_type',
|
||||||
|
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='rearporttemplates', to='dcim.DeviceType'),
|
||||||
|
),
|
||||||
|
]
|
@ -678,7 +678,7 @@ class Rack(ChangeLoggedModel, CustomFieldModel):
|
|||||||
'device_type__manufacturer',
|
'device_type__manufacturer',
|
||||||
'device_role'
|
'device_role'
|
||||||
).annotate(
|
).annotate(
|
||||||
devicebay_count=Count('device_bays')
|
devicebay_count=Count('devicebays')
|
||||||
).exclude(
|
).exclude(
|
||||||
pk=exclude
|
pk=exclude
|
||||||
).filter(
|
).filter(
|
||||||
@ -1049,23 +1049,23 @@ class DeviceType(ChangeLoggedModel, CustomFieldModel):
|
|||||||
))
|
))
|
||||||
|
|
||||||
# Component templates
|
# Component templates
|
||||||
if self.consoleport_templates.exists():
|
if self.consoleporttemplates.exists():
|
||||||
data['console-ports'] = [
|
data['console-ports'] = [
|
||||||
{
|
{
|
||||||
'name': c.name,
|
'name': c.name,
|
||||||
'type': c.type,
|
'type': c.type,
|
||||||
}
|
}
|
||||||
for c in self.consoleport_templates.all()
|
for c in self.consoleporttemplates.all()
|
||||||
]
|
]
|
||||||
if self.consoleserverport_templates.exists():
|
if self.consoleserverporttemplates.exists():
|
||||||
data['console-server-ports'] = [
|
data['console-server-ports'] = [
|
||||||
{
|
{
|
||||||
'name': c.name,
|
'name': c.name,
|
||||||
'type': c.type,
|
'type': c.type,
|
||||||
}
|
}
|
||||||
for c in self.consoleserverport_templates.all()
|
for c in self.consoleserverporttemplates.all()
|
||||||
]
|
]
|
||||||
if self.powerport_templates.exists():
|
if self.powerporttemplates.exists():
|
||||||
data['power-ports'] = [
|
data['power-ports'] = [
|
||||||
{
|
{
|
||||||
'name': c.name,
|
'name': c.name,
|
||||||
@ -1073,9 +1073,9 @@ class DeviceType(ChangeLoggedModel, CustomFieldModel):
|
|||||||
'maximum_draw': c.maximum_draw,
|
'maximum_draw': c.maximum_draw,
|
||||||
'allocated_draw': c.allocated_draw,
|
'allocated_draw': c.allocated_draw,
|
||||||
}
|
}
|
||||||
for c in self.powerport_templates.all()
|
for c in self.powerporttemplates.all()
|
||||||
]
|
]
|
||||||
if self.poweroutlet_templates.exists():
|
if self.poweroutlettemplates.exists():
|
||||||
data['power-outlets'] = [
|
data['power-outlets'] = [
|
||||||
{
|
{
|
||||||
'name': c.name,
|
'name': c.name,
|
||||||
@ -1083,18 +1083,18 @@ class DeviceType(ChangeLoggedModel, CustomFieldModel):
|
|||||||
'power_port': c.power_port.name if c.power_port else None,
|
'power_port': c.power_port.name if c.power_port else None,
|
||||||
'feed_leg': c.feed_leg,
|
'feed_leg': c.feed_leg,
|
||||||
}
|
}
|
||||||
for c in self.poweroutlet_templates.all()
|
for c in self.poweroutlettemplates.all()
|
||||||
]
|
]
|
||||||
if self.interface_templates.exists():
|
if self.interfacetemplates.exists():
|
||||||
data['interfaces'] = [
|
data['interfaces'] = [
|
||||||
{
|
{
|
||||||
'name': c.name,
|
'name': c.name,
|
||||||
'type': c.type,
|
'type': c.type,
|
||||||
'mgmt_only': c.mgmt_only,
|
'mgmt_only': c.mgmt_only,
|
||||||
}
|
}
|
||||||
for c in self.interface_templates.all()
|
for c in self.interfacetemplates.all()
|
||||||
]
|
]
|
||||||
if self.frontport_templates.exists():
|
if self.frontporttemplates.exists():
|
||||||
data['front-ports'] = [
|
data['front-ports'] = [
|
||||||
{
|
{
|
||||||
'name': c.name,
|
'name': c.name,
|
||||||
@ -1102,23 +1102,23 @@ class DeviceType(ChangeLoggedModel, CustomFieldModel):
|
|||||||
'rear_port': c.rear_port.name,
|
'rear_port': c.rear_port.name,
|
||||||
'rear_port_position': c.rear_port_position,
|
'rear_port_position': c.rear_port_position,
|
||||||
}
|
}
|
||||||
for c in self.frontport_templates.all()
|
for c in self.frontporttemplates.all()
|
||||||
]
|
]
|
||||||
if self.rearport_templates.exists():
|
if self.rearporttemplates.exists():
|
||||||
data['rear-ports'] = [
|
data['rear-ports'] = [
|
||||||
{
|
{
|
||||||
'name': c.name,
|
'name': c.name,
|
||||||
'type': c.type,
|
'type': c.type,
|
||||||
'positions': c.positions,
|
'positions': c.positions,
|
||||||
}
|
}
|
||||||
for c in self.rearport_templates.all()
|
for c in self.rearporttemplates.all()
|
||||||
]
|
]
|
||||||
if self.device_bay_templates.exists():
|
if self.devicebaytemplates.exists():
|
||||||
data['device-bays'] = [
|
data['device-bays'] = [
|
||||||
{
|
{
|
||||||
'name': c.name,
|
'name': c.name,
|
||||||
}
|
}
|
||||||
for c in self.device_bay_templates.all()
|
for c in self.devicebaytemplates.all()
|
||||||
]
|
]
|
||||||
|
|
||||||
return yaml.dump(dict(data), sort_keys=False)
|
return yaml.dump(dict(data), sort_keys=False)
|
||||||
@ -1159,7 +1159,7 @@ class DeviceType(ChangeLoggedModel, CustomFieldModel):
|
|||||||
|
|
||||||
if (
|
if (
|
||||||
self.subdevice_role != SubdeviceRoleChoices.ROLE_PARENT
|
self.subdevice_role != SubdeviceRoleChoices.ROLE_PARENT
|
||||||
) and self.device_bay_templates.count():
|
) and self.devicebaytemplates.count():
|
||||||
raise ValidationError({
|
raise ValidationError({
|
||||||
'subdevice_role': "Must delete all device bay templates associated with this device before "
|
'subdevice_role': "Must delete all device bay templates associated with this device before "
|
||||||
"declassifying it as a parent device."
|
"declassifying it as a parent device."
|
||||||
@ -1634,28 +1634,28 @@ class Device(ChangeLoggedModel, ConfigContextModel, CustomFieldModel):
|
|||||||
# If this is a new Device, instantiate all of the related components per the DeviceType definition
|
# If this is a new Device, instantiate all of the related components per the DeviceType definition
|
||||||
if is_new:
|
if is_new:
|
||||||
ConsolePort.objects.bulk_create(
|
ConsolePort.objects.bulk_create(
|
||||||
[x.instantiate(self) for x in self.device_type.consoleport_templates.unrestricted()]
|
[x.instantiate(self) for x in self.device_type.consoleporttemplates.unrestricted()]
|
||||||
)
|
)
|
||||||
ConsoleServerPort.objects.bulk_create(
|
ConsoleServerPort.objects.bulk_create(
|
||||||
[x.instantiate(self) for x in self.device_type.consoleserverport_templates.unrestricted()]
|
[x.instantiate(self) for x in self.device_type.consoleserverporttemplates.unrestricted()]
|
||||||
)
|
)
|
||||||
PowerPort.objects.bulk_create(
|
PowerPort.objects.bulk_create(
|
||||||
[x.instantiate(self) for x in self.device_type.powerport_templates.unrestricted()]
|
[x.instantiate(self) for x in self.device_type.powerporttemplates.unrestricted()]
|
||||||
)
|
)
|
||||||
PowerOutlet.objects.bulk_create(
|
PowerOutlet.objects.bulk_create(
|
||||||
[x.instantiate(self) for x in self.device_type.poweroutlet_templates.unrestricted()]
|
[x.instantiate(self) for x in self.device_type.poweroutlettemplates.unrestricted()]
|
||||||
)
|
)
|
||||||
Interface.objects.bulk_create(
|
Interface.objects.bulk_create(
|
||||||
[x.instantiate(self) for x in self.device_type.interface_templates.unrestricted()]
|
[x.instantiate(self) for x in self.device_type.interfacetemplates.unrestricted()]
|
||||||
)
|
)
|
||||||
RearPort.objects.bulk_create(
|
RearPort.objects.bulk_create(
|
||||||
[x.instantiate(self) for x in self.device_type.rearport_templates.unrestricted()]
|
[x.instantiate(self) for x in self.device_type.rearporttemplates.unrestricted()]
|
||||||
)
|
)
|
||||||
FrontPort.objects.bulk_create(
|
FrontPort.objects.bulk_create(
|
||||||
[x.instantiate(self) for x in self.device_type.frontport_templates.unrestricted()]
|
[x.instantiate(self) for x in self.device_type.frontporttemplates.unrestricted()]
|
||||||
)
|
)
|
||||||
DeviceBay.objects.bulk_create(
|
DeviceBay.objects.bulk_create(
|
||||||
[x.instantiate(self) for x in self.device_type.device_bay_templates.unrestricted()]
|
[x.instantiate(self) for x in self.device_type.devicebaytemplates.unrestricted()]
|
||||||
)
|
)
|
||||||
|
|
||||||
# Update Site and Rack assignment for any child Devices
|
# Update Site and Rack assignment for any child Devices
|
||||||
|
@ -27,6 +27,11 @@ __all__ = (
|
|||||||
|
|
||||||
|
|
||||||
class ComponentTemplateModel(models.Model):
|
class ComponentTemplateModel(models.Model):
|
||||||
|
device_type = models.ForeignKey(
|
||||||
|
to='dcim.DeviceType',
|
||||||
|
on_delete=models.CASCADE,
|
||||||
|
related_name='%(class)ss'
|
||||||
|
)
|
||||||
name = models.CharField(
|
name = models.CharField(
|
||||||
max_length=64
|
max_length=64
|
||||||
)
|
)
|
||||||
@ -81,11 +86,6 @@ class ConsolePortTemplate(ComponentTemplateModel):
|
|||||||
"""
|
"""
|
||||||
A template for a ConsolePort to be created for a new Device.
|
A template for a ConsolePort to be created for a new Device.
|
||||||
"""
|
"""
|
||||||
device_type = models.ForeignKey(
|
|
||||||
to='dcim.DeviceType',
|
|
||||||
on_delete=models.CASCADE,
|
|
||||||
related_name='consoleport_templates'
|
|
||||||
)
|
|
||||||
type = models.CharField(
|
type = models.CharField(
|
||||||
max_length=50,
|
max_length=50,
|
||||||
choices=ConsolePortTypeChoices,
|
choices=ConsolePortTypeChoices,
|
||||||
@ -108,11 +108,6 @@ class ConsoleServerPortTemplate(ComponentTemplateModel):
|
|||||||
"""
|
"""
|
||||||
A template for a ConsoleServerPort to be created for a new Device.
|
A template for a ConsoleServerPort to be created for a new Device.
|
||||||
"""
|
"""
|
||||||
device_type = models.ForeignKey(
|
|
||||||
to='dcim.DeviceType',
|
|
||||||
on_delete=models.CASCADE,
|
|
||||||
related_name='consoleserverport_templates'
|
|
||||||
)
|
|
||||||
type = models.CharField(
|
type = models.CharField(
|
||||||
max_length=50,
|
max_length=50,
|
||||||
choices=ConsolePortTypeChoices,
|
choices=ConsolePortTypeChoices,
|
||||||
@ -135,11 +130,6 @@ class PowerPortTemplate(ComponentTemplateModel):
|
|||||||
"""
|
"""
|
||||||
A template for a PowerPort to be created for a new Device.
|
A template for a PowerPort to be created for a new Device.
|
||||||
"""
|
"""
|
||||||
device_type = models.ForeignKey(
|
|
||||||
to='dcim.DeviceType',
|
|
||||||
on_delete=models.CASCADE,
|
|
||||||
related_name='powerport_templates'
|
|
||||||
)
|
|
||||||
type = models.CharField(
|
type = models.CharField(
|
||||||
max_length=50,
|
max_length=50,
|
||||||
choices=PowerPortTypeChoices,
|
choices=PowerPortTypeChoices,
|
||||||
@ -176,11 +166,6 @@ class PowerOutletTemplate(ComponentTemplateModel):
|
|||||||
"""
|
"""
|
||||||
A template for a PowerOutlet to be created for a new Device.
|
A template for a PowerOutlet to be created for a new Device.
|
||||||
"""
|
"""
|
||||||
device_type = models.ForeignKey(
|
|
||||||
to='dcim.DeviceType',
|
|
||||||
on_delete=models.CASCADE,
|
|
||||||
related_name='poweroutlet_templates'
|
|
||||||
)
|
|
||||||
type = models.CharField(
|
type = models.CharField(
|
||||||
max_length=50,
|
max_length=50,
|
||||||
choices=PowerOutletTypeChoices,
|
choices=PowerOutletTypeChoices,
|
||||||
@ -230,11 +215,7 @@ class InterfaceTemplate(ComponentTemplateModel):
|
|||||||
"""
|
"""
|
||||||
A template for a physical data interface on a new Device.
|
A template for a physical data interface on a new Device.
|
||||||
"""
|
"""
|
||||||
device_type = models.ForeignKey(
|
# Override ComponentTemplateModel._name to specify naturalize_interface function
|
||||||
to='dcim.DeviceType',
|
|
||||||
on_delete=models.CASCADE,
|
|
||||||
related_name='interface_templates'
|
|
||||||
)
|
|
||||||
_name = NaturalOrderingField(
|
_name = NaturalOrderingField(
|
||||||
target_field='name',
|
target_field='name',
|
||||||
naturalize_function=naturalize_interface,
|
naturalize_function=naturalize_interface,
|
||||||
@ -267,11 +248,6 @@ class FrontPortTemplate(ComponentTemplateModel):
|
|||||||
"""
|
"""
|
||||||
Template for a pass-through port on the front of a new Device.
|
Template for a pass-through port on the front of a new Device.
|
||||||
"""
|
"""
|
||||||
device_type = models.ForeignKey(
|
|
||||||
to='dcim.DeviceType',
|
|
||||||
on_delete=models.CASCADE,
|
|
||||||
related_name='frontport_templates'
|
|
||||||
)
|
|
||||||
type = models.CharField(
|
type = models.CharField(
|
||||||
max_length=50,
|
max_length=50,
|
||||||
choices=PortTypeChoices
|
choices=PortTypeChoices
|
||||||
@ -327,11 +303,6 @@ class RearPortTemplate(ComponentTemplateModel):
|
|||||||
"""
|
"""
|
||||||
Template for a pass-through port on the rear of a new Device.
|
Template for a pass-through port on the rear of a new Device.
|
||||||
"""
|
"""
|
||||||
device_type = models.ForeignKey(
|
|
||||||
to='dcim.DeviceType',
|
|
||||||
on_delete=models.CASCADE,
|
|
||||||
related_name='rearport_templates'
|
|
||||||
)
|
|
||||||
type = models.CharField(
|
type = models.CharField(
|
||||||
max_length=50,
|
max_length=50,
|
||||||
choices=PortTypeChoices
|
choices=PortTypeChoices
|
||||||
@ -358,12 +329,6 @@ class DeviceBayTemplate(ComponentTemplateModel):
|
|||||||
"""
|
"""
|
||||||
A template for a DeviceBay to be created for a new parent Device.
|
A template for a DeviceBay to be created for a new parent Device.
|
||||||
"""
|
"""
|
||||||
device_type = models.ForeignKey(
|
|
||||||
to='dcim.DeviceType',
|
|
||||||
on_delete=models.CASCADE,
|
|
||||||
related_name='device_bay_templates'
|
|
||||||
)
|
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
ordering = ('device_type', '_name')
|
ordering = ('device_type', '_name')
|
||||||
unique_together = ('device_type', 'name')
|
unique_together = ('device_type', 'name')
|
||||||
|
@ -36,6 +36,11 @@ __all__ = (
|
|||||||
|
|
||||||
|
|
||||||
class ComponentModel(models.Model):
|
class ComponentModel(models.Model):
|
||||||
|
device = models.ForeignKey(
|
||||||
|
to='dcim.Device',
|
||||||
|
on_delete=models.CASCADE,
|
||||||
|
related_name='%(class)ss'
|
||||||
|
)
|
||||||
name = models.CharField(
|
name = models.CharField(
|
||||||
max_length=64
|
max_length=64
|
||||||
)
|
)
|
||||||
@ -246,11 +251,6 @@ class ConsolePort(CableTermination, ComponentModel):
|
|||||||
"""
|
"""
|
||||||
A physical console port within a Device. ConsolePorts connect to ConsoleServerPorts.
|
A physical console port within a Device. ConsolePorts connect to ConsoleServerPorts.
|
||||||
"""
|
"""
|
||||||
device = models.ForeignKey(
|
|
||||||
to='dcim.Device',
|
|
||||||
on_delete=models.CASCADE,
|
|
||||||
related_name='consoleports'
|
|
||||||
)
|
|
||||||
type = models.CharField(
|
type = models.CharField(
|
||||||
max_length=50,
|
max_length=50,
|
||||||
choices=ConsolePortTypeChoices,
|
choices=ConsolePortTypeChoices,
|
||||||
@ -298,11 +298,6 @@ class ConsoleServerPort(CableTermination, ComponentModel):
|
|||||||
"""
|
"""
|
||||||
A physical port within a Device (typically a designated console server) which provides access to ConsolePorts.
|
A physical port within a Device (typically a designated console server) which provides access to ConsolePorts.
|
||||||
"""
|
"""
|
||||||
device = models.ForeignKey(
|
|
||||||
to='dcim.Device',
|
|
||||||
on_delete=models.CASCADE,
|
|
||||||
related_name='consoleserverports'
|
|
||||||
)
|
|
||||||
type = models.CharField(
|
type = models.CharField(
|
||||||
max_length=50,
|
max_length=50,
|
||||||
choices=ConsolePortTypeChoices,
|
choices=ConsolePortTypeChoices,
|
||||||
@ -343,11 +338,6 @@ class PowerPort(CableTermination, ComponentModel):
|
|||||||
"""
|
"""
|
||||||
A physical power supply (intake) port within a Device. PowerPorts connect to PowerOutlets.
|
A physical power supply (intake) port within a Device. PowerPorts connect to PowerOutlets.
|
||||||
"""
|
"""
|
||||||
device = models.ForeignKey(
|
|
||||||
to='dcim.Device',
|
|
||||||
on_delete=models.CASCADE,
|
|
||||||
related_name='powerports'
|
|
||||||
)
|
|
||||||
type = models.CharField(
|
type = models.CharField(
|
||||||
max_length=50,
|
max_length=50,
|
||||||
choices=PowerPortTypeChoices,
|
choices=PowerPortTypeChoices,
|
||||||
@ -496,11 +486,6 @@ class PowerOutlet(CableTermination, ComponentModel):
|
|||||||
"""
|
"""
|
||||||
A physical power outlet (output) within a Device which provides power to a PowerPort.
|
A physical power outlet (output) within a Device which provides power to a PowerPort.
|
||||||
"""
|
"""
|
||||||
device = models.ForeignKey(
|
|
||||||
to='dcim.Device',
|
|
||||||
on_delete=models.CASCADE,
|
|
||||||
related_name='poweroutlets'
|
|
||||||
)
|
|
||||||
type = models.CharField(
|
type = models.CharField(
|
||||||
max_length=50,
|
max_length=50,
|
||||||
choices=PowerOutletTypeChoices,
|
choices=PowerOutletTypeChoices,
|
||||||
@ -560,6 +545,9 @@ class PowerOutlet(CableTermination, ComponentModel):
|
|||||||
#
|
#
|
||||||
|
|
||||||
class BaseInterface(models.Model):
|
class BaseInterface(models.Model):
|
||||||
|
"""
|
||||||
|
Abstract base class for fields shared by dcim.Interface and virtualization.VMInterface.
|
||||||
|
"""
|
||||||
enabled = models.BooleanField(
|
enabled = models.BooleanField(
|
||||||
default=True
|
default=True
|
||||||
)
|
)
|
||||||
@ -589,13 +577,7 @@ class Interface(CableTermination, ComponentModel, BaseInterface):
|
|||||||
"""
|
"""
|
||||||
A network interface within a Device. A physical Interface can connect to exactly one other Interface.
|
A network interface within a Device. A physical Interface can connect to exactly one other Interface.
|
||||||
"""
|
"""
|
||||||
device = models.ForeignKey(
|
# Override ComponentModel._name to specify naturalize_interface function
|
||||||
to='Device',
|
|
||||||
on_delete=models.CASCADE,
|
|
||||||
related_name='interfaces',
|
|
||||||
null=True,
|
|
||||||
blank=True
|
|
||||||
)
|
|
||||||
_name = NaturalOrderingField(
|
_name = NaturalOrderingField(
|
||||||
target_field='name',
|
target_field='name',
|
||||||
naturalize_function=naturalize_interface,
|
naturalize_function=naturalize_interface,
|
||||||
@ -807,11 +789,6 @@ class FrontPort(CableTermination, ComponentModel):
|
|||||||
"""
|
"""
|
||||||
A pass-through port on the front of a Device.
|
A pass-through port on the front of a Device.
|
||||||
"""
|
"""
|
||||||
device = models.ForeignKey(
|
|
||||||
to='dcim.Device',
|
|
||||||
on_delete=models.CASCADE,
|
|
||||||
related_name='frontports'
|
|
||||||
)
|
|
||||||
type = models.CharField(
|
type = models.CharField(
|
||||||
max_length=50,
|
max_length=50,
|
||||||
choices=PortTypeChoices
|
choices=PortTypeChoices
|
||||||
@ -872,11 +849,6 @@ class RearPort(CableTermination, ComponentModel):
|
|||||||
"""
|
"""
|
||||||
A pass-through port on the rear of a Device.
|
A pass-through port on the rear of a Device.
|
||||||
"""
|
"""
|
||||||
device = models.ForeignKey(
|
|
||||||
to='dcim.Device',
|
|
||||||
on_delete=models.CASCADE,
|
|
||||||
related_name='rearports'
|
|
||||||
)
|
|
||||||
type = models.CharField(
|
type = models.CharField(
|
||||||
max_length=50,
|
max_length=50,
|
||||||
choices=PortTypeChoices
|
choices=PortTypeChoices
|
||||||
@ -916,11 +888,6 @@ class DeviceBay(ComponentModel):
|
|||||||
"""
|
"""
|
||||||
An empty space within a Device which can house a child device
|
An empty space within a Device which can house a child device
|
||||||
"""
|
"""
|
||||||
device = models.ForeignKey(
|
|
||||||
to='dcim.Device',
|
|
||||||
on_delete=models.CASCADE,
|
|
||||||
related_name='device_bays'
|
|
||||||
)
|
|
||||||
installed_device = models.OneToOneField(
|
installed_device = models.OneToOneField(
|
||||||
to='dcim.Device',
|
to='dcim.Device',
|
||||||
on_delete=models.SET_NULL,
|
on_delete=models.SET_NULL,
|
||||||
@ -981,11 +948,6 @@ class InventoryItem(ComponentModel):
|
|||||||
An InventoryItem represents a serialized piece of hardware within a Device, such as a line card or power supply.
|
An InventoryItem represents a serialized piece of hardware within a Device, such as a line card or power supply.
|
||||||
InventoryItems are used only for inventory purposes.
|
InventoryItems are used only for inventory purposes.
|
||||||
"""
|
"""
|
||||||
device = models.ForeignKey(
|
|
||||||
to='dcim.Device',
|
|
||||||
on_delete=models.CASCADE,
|
|
||||||
related_name='inventory_items'
|
|
||||||
)
|
|
||||||
parent = models.ForeignKey(
|
parent = models.ForeignKey(
|
||||||
to='self',
|
to='self',
|
||||||
on_delete=models.CASCADE,
|
on_delete=models.CASCADE,
|
||||||
|
@ -481,45 +481,45 @@ device-bays:
|
|||||||
self.assertEqual(dt.comments, 'test comment')
|
self.assertEqual(dt.comments, 'test comment')
|
||||||
|
|
||||||
# Verify all of the components were created
|
# Verify all of the components were created
|
||||||
self.assertEqual(dt.consoleport_templates.count(), 3)
|
self.assertEqual(dt.consoleporttemplates.count(), 3)
|
||||||
cp1 = ConsolePortTemplate.objects.first()
|
cp1 = ConsolePortTemplate.objects.first()
|
||||||
self.assertEqual(cp1.name, 'Console Port 1')
|
self.assertEqual(cp1.name, 'Console Port 1')
|
||||||
self.assertEqual(cp1.type, ConsolePortTypeChoices.TYPE_DE9)
|
self.assertEqual(cp1.type, ConsolePortTypeChoices.TYPE_DE9)
|
||||||
|
|
||||||
self.assertEqual(dt.consoleserverport_templates.count(), 3)
|
self.assertEqual(dt.consoleserverporttemplates.count(), 3)
|
||||||
csp1 = ConsoleServerPortTemplate.objects.first()
|
csp1 = ConsoleServerPortTemplate.objects.first()
|
||||||
self.assertEqual(csp1.name, 'Console Server Port 1')
|
self.assertEqual(csp1.name, 'Console Server Port 1')
|
||||||
self.assertEqual(csp1.type, ConsolePortTypeChoices.TYPE_RJ45)
|
self.assertEqual(csp1.type, ConsolePortTypeChoices.TYPE_RJ45)
|
||||||
|
|
||||||
self.assertEqual(dt.powerport_templates.count(), 3)
|
self.assertEqual(dt.powerporttemplates.count(), 3)
|
||||||
pp1 = PowerPortTemplate.objects.first()
|
pp1 = PowerPortTemplate.objects.first()
|
||||||
self.assertEqual(pp1.name, 'Power Port 1')
|
self.assertEqual(pp1.name, 'Power Port 1')
|
||||||
self.assertEqual(pp1.type, PowerPortTypeChoices.TYPE_IEC_C14)
|
self.assertEqual(pp1.type, PowerPortTypeChoices.TYPE_IEC_C14)
|
||||||
|
|
||||||
self.assertEqual(dt.poweroutlet_templates.count(), 3)
|
self.assertEqual(dt.poweroutlettemplates.count(), 3)
|
||||||
po1 = PowerOutletTemplate.objects.first()
|
po1 = PowerOutletTemplate.objects.first()
|
||||||
self.assertEqual(po1.name, 'Power Outlet 1')
|
self.assertEqual(po1.name, 'Power Outlet 1')
|
||||||
self.assertEqual(po1.type, PowerOutletTypeChoices.TYPE_IEC_C13)
|
self.assertEqual(po1.type, PowerOutletTypeChoices.TYPE_IEC_C13)
|
||||||
self.assertEqual(po1.power_port, pp1)
|
self.assertEqual(po1.power_port, pp1)
|
||||||
self.assertEqual(po1.feed_leg, PowerOutletFeedLegChoices.FEED_LEG_A)
|
self.assertEqual(po1.feed_leg, PowerOutletFeedLegChoices.FEED_LEG_A)
|
||||||
|
|
||||||
self.assertEqual(dt.interface_templates.count(), 3)
|
self.assertEqual(dt.interfacetemplates.count(), 3)
|
||||||
iface1 = InterfaceTemplate.objects.first()
|
iface1 = InterfaceTemplate.objects.first()
|
||||||
self.assertEqual(iface1.name, 'Interface 1')
|
self.assertEqual(iface1.name, 'Interface 1')
|
||||||
self.assertEqual(iface1.type, InterfaceTypeChoices.TYPE_1GE_FIXED)
|
self.assertEqual(iface1.type, InterfaceTypeChoices.TYPE_1GE_FIXED)
|
||||||
self.assertTrue(iface1.mgmt_only)
|
self.assertTrue(iface1.mgmt_only)
|
||||||
|
|
||||||
self.assertEqual(dt.rearport_templates.count(), 3)
|
self.assertEqual(dt.rearporttemplates.count(), 3)
|
||||||
rp1 = RearPortTemplate.objects.first()
|
rp1 = RearPortTemplate.objects.first()
|
||||||
self.assertEqual(rp1.name, 'Rear Port 1')
|
self.assertEqual(rp1.name, 'Rear Port 1')
|
||||||
|
|
||||||
self.assertEqual(dt.frontport_templates.count(), 3)
|
self.assertEqual(dt.frontporttemplates.count(), 3)
|
||||||
fp1 = FrontPortTemplate.objects.first()
|
fp1 = FrontPortTemplate.objects.first()
|
||||||
self.assertEqual(fp1.name, 'Front Port 1')
|
self.assertEqual(fp1.name, 'Front Port 1')
|
||||||
self.assertEqual(fp1.rear_port, rp1)
|
self.assertEqual(fp1.rear_port, rp1)
|
||||||
self.assertEqual(fp1.rear_port_position, 1)
|
self.assertEqual(fp1.rear_port_position, 1)
|
||||||
|
|
||||||
self.assertEqual(dt.device_bay_templates.count(), 3)
|
self.assertEqual(dt.devicebaytemplates.count(), 3)
|
||||||
db1 = DeviceBayTemplate.objects.first()
|
db1 = DeviceBayTemplate.objects.first()
|
||||||
self.assertEqual(db1.name, 'Device Bay 1')
|
self.assertEqual(db1.name, 'Device Bay 1')
|
||||||
|
|
||||||
|
@ -101,7 +101,7 @@
|
|||||||
</li>
|
</li>
|
||||||
<li role="presentation"{% if active_tab == 'inventory' %} class="active"{% endif %}>
|
<li role="presentation"{% if active_tab == 'inventory' %} class="active"{% endif %}>
|
||||||
<a href="{% url 'dcim:device_inventory' pk=device.pk %}">
|
<a href="{% url 'dcim:device_inventory' pk=device.pk %}">
|
||||||
Inventory <span class="badge">{{ device.inventory_items.count }}</span>
|
Inventory <span class="badge">{{ device.inventoryitems.count }}</span>
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
{% if perms.dcim.napalm_read_device %}
|
{% if perms.dcim.napalm_read_device %}
|
||||||
|
@ -155,7 +155,7 @@
|
|||||||
{% plugin_right_page devicetype %}
|
{% plugin_right_page devicetype %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% if devicetype.consoleport_templates.exists or devicetype.powerport_templates.exists %}
|
{% if devicetype.consoleporttemplates.exists or devicetype.powerporttemplates.exists %}
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-md-6">
|
<div class="col-md-6">
|
||||||
{% include 'dcim/inc/devicetype_component_table.html' with table=consoleport_table title='Console Ports' add_url='dcim:consoleporttemplate_add' edit_url='dcim:consoleporttemplate_bulk_edit' delete_url='dcim:consoleporttemplate_bulk_delete' %}
|
{% include 'dcim/inc/devicetype_component_table.html' with table=consoleport_table title='Console Ports' add_url='dcim:consoleporttemplate_add' edit_url='dcim:consoleporttemplate_bulk_edit' delete_url='dcim:consoleporttemplate_bulk_delete' %}
|
||||||
@ -177,28 +177,28 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if devicetype.consoleserverport_templates.exists %}
|
{% if devicetype.consoleserverporttemplates.exists %}
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-md-12">
|
<div class="col-md-12">
|
||||||
{% include 'dcim/inc/devicetype_component_table.html' with table=consoleserverport_table title='Console Server Ports' add_url='dcim:consoleserverporttemplate_add' edit_url='dcim:consoleserverporttemplate_bulk_edit' delete_url='dcim:consoleserverporttemplate_bulk_delete' %}
|
{% include 'dcim/inc/devicetype_component_table.html' with table=consoleserverport_table title='Console Server Ports' add_url='dcim:consoleserverporttemplate_add' edit_url='dcim:consoleserverporttemplate_bulk_edit' delete_url='dcim:consoleserverporttemplate_bulk_delete' %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if devicetype.poweroutlet_templates.exists %}
|
{% if devicetype.poweroutlettemplates.exists %}
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-md-12">
|
<div class="col-md-12">
|
||||||
{% include 'dcim/inc/devicetype_component_table.html' with table=poweroutlet_table title='Power Outlets' add_url='dcim:poweroutlettemplate_add' edit_url='dcim:poweroutlettemplate_bulk_edit' delete_url='dcim:poweroutlettemplate_bulk_delete' %}
|
{% include 'dcim/inc/devicetype_component_table.html' with table=poweroutlet_table title='Power Outlets' add_url='dcim:poweroutlettemplate_add' edit_url='dcim:poweroutlettemplate_bulk_edit' delete_url='dcim:poweroutlettemplate_bulk_delete' %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if devicetype.interface_templates.exists %}
|
{% if devicetype.interfacetemplates.exists %}
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-md-12">
|
<div class="col-md-12">
|
||||||
{% include 'dcim/inc/devicetype_component_table.html' with table=interface_table title='Interfaces' add_url='dcim:interfacetemplate_add' edit_url='dcim:interfacetemplate_bulk_edit' delete_url='dcim:interfacetemplate_bulk_delete' %}
|
{% include 'dcim/inc/devicetype_component_table.html' with table=interface_table title='Interfaces' add_url='dcim:interfacetemplate_add' edit_url='dcim:interfacetemplate_bulk_edit' delete_url='dcim:interfacetemplate_bulk_delete' %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if devicetype.frontport_templates.exists or devicetype.rearport_templates.exists %}
|
{% if devicetype.frontporttemplates.exists or devicetype.rearporttemplates.exists %}
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-md-6">
|
<div class="col-md-6">
|
||||||
{% include 'dcim/inc/devicetype_component_table.html' with table=front_port_table title='Front Ports' add_url='dcim:frontporttemplate_add' edit_url='dcim:frontporttemplate_bulk_edit' delete_url='dcim:frontporttemplate_bulk_delete' %}
|
{% include 'dcim/inc/devicetype_component_table.html' with table=front_port_table title='Front Ports' add_url='dcim:frontporttemplate_add' edit_url='dcim:frontporttemplate_bulk_edit' delete_url='dcim:frontporttemplate_bulk_delete' %}
|
||||||
|
Loading…
Reference in New Issue
Block a user