Add position field for module bays

This commit is contained in:
jeremystretch 2021-12-20 09:51:55 -05:00
parent ed6a160372
commit eaa1165611
14 changed files with 65 additions and 31 deletions

View File

@ -432,7 +432,10 @@ class ModuleBayTemplateSerializer(ValidatedModelSerializer):
class Meta:
model = ModuleBayTemplate
fields = ['id', 'url', 'display', 'device_type', 'name', 'label', 'description', 'created', 'last_updated']
fields = [
'id', 'url', 'display', 'device_type', 'name', 'label', 'position', 'description', 'created',
'last_updated',
]
class DeviceBayTemplateSerializer(ValidatedModelSerializer):
@ -785,8 +788,8 @@ class ModuleBaySerializer(PrimaryModelSerializer):
class Meta:
model = ModuleBay
fields = [
'id', 'url', 'display', 'device', 'name', 'label', 'description', 'tags', 'custom_fields', 'created',
'last_updated',
'id', 'url', 'display', 'device', 'name', 'label', 'position', 'description', 'tags', 'custom_fields',
'created', 'last_updated',
]

View File

@ -886,7 +886,7 @@ class ModuleBayTemplateBulkEditForm(BulkEditForm):
)
class Meta:
nullable_fields = ('label', 'description')
nullable_fields = ('label', 'position', 'description')
class DeviceBayTemplateBulkEditForm(BulkEditForm):
@ -1153,7 +1153,7 @@ class ModuleBayBulkEditForm(
)
class Meta:
nullable_fields = ['label', 'description']
nullable_fields = ['label', 'position', 'description']
class DeviceBayBulkEditForm(

View File

@ -717,7 +717,7 @@ class ModuleBayCSVForm(CustomFieldModelCSVForm):
class Meta:
model = ModuleBay
fields = ('device', 'name', 'label', 'description')
fields = ('device', 'name', 'label', 'position', 'description')
class DeviceBayCSVForm(CustomFieldModelCSVForm):

View File

@ -1073,10 +1073,13 @@ class ModuleBayFilterForm(DeviceComponentFilterForm):
model = ModuleBay
field_groups = [
['q', 'tag'],
['name', 'label'],
['name', 'label', 'position'],
['region_id', 'site_group_id', 'site_id', 'location_id', 'virtual_chassis_id', 'device_id'],
]
tag = TagFilterField(model)
position = forms.CharField(
required=False
)
class DeviceBayFilterForm(DeviceComponentFilterForm):

View File

@ -1059,7 +1059,7 @@ class ModuleBayTemplateForm(BootstrapMixin, forms.ModelForm):
class Meta:
model = ModuleBayTemplate
fields = [
'device_type', 'name', 'label', 'description',
'device_type', 'name', 'label', 'position', 'description',
]
widgets = {
'device_type': forms.HiddenInput(),
@ -1313,7 +1313,7 @@ class ModuleBayForm(CustomFieldModelForm):
class Meta:
model = ModuleBay
fields = [
'device', 'name', 'label', 'description', 'tags',
'device', 'name', 'label', 'position', 'description', 'tags',
]
widgets = {
'device': forms.HiddenInput(),

View File

@ -163,6 +163,12 @@ class ComponentTemplateCreateForm(ComponentForm):
'manufacturer_id': '$manufacturer'
}
)
description = forms.CharField(
required=False
)
class ModularComponentTemplateCreateForm(ComponentTemplateCreateForm):
module_type = DynamicModelChoiceField(
queryset=ModuleType.objects.all(),
required=False,
@ -170,12 +176,9 @@ class ComponentTemplateCreateForm(ComponentForm):
'manufacturer_id': '$manufacturer'
}
)
description = forms.CharField(
required=False
)
class ConsolePortTemplateCreateForm(ComponentTemplateCreateForm):
class ConsolePortTemplateCreateForm(ModularComponentTemplateCreateForm):
type = forms.ChoiceField(
choices=add_blank_choice(ConsolePortTypeChoices),
widget=StaticSelect()
@ -185,7 +188,7 @@ class ConsolePortTemplateCreateForm(ComponentTemplateCreateForm):
)
class ConsoleServerPortTemplateCreateForm(ComponentTemplateCreateForm):
class ConsoleServerPortTemplateCreateForm(ModularComponentTemplateCreateForm):
type = forms.ChoiceField(
choices=add_blank_choice(ConsolePortTypeChoices),
widget=StaticSelect()
@ -195,7 +198,7 @@ class ConsoleServerPortTemplateCreateForm(ComponentTemplateCreateForm):
)
class PowerPortTemplateCreateForm(ComponentTemplateCreateForm):
class PowerPortTemplateCreateForm(ModularComponentTemplateCreateForm):
type = forms.ChoiceField(
choices=add_blank_choice(PowerPortTypeChoices),
required=False
@ -216,7 +219,7 @@ class PowerPortTemplateCreateForm(ComponentTemplateCreateForm):
)
class PowerOutletTemplateCreateForm(ComponentTemplateCreateForm):
class PowerOutletTemplateCreateForm(ModularComponentTemplateCreateForm):
type = forms.ChoiceField(
choices=add_blank_choice(PowerOutletTypeChoices),
required=False
@ -240,7 +243,7 @@ class PowerOutletTemplateCreateForm(ComponentTemplateCreateForm):
)
class InterfaceTemplateCreateForm(ComponentTemplateCreateForm):
class InterfaceTemplateCreateForm(ModularComponentTemplateCreateForm):
type = forms.ChoiceField(
choices=InterfaceTypeChoices,
widget=StaticSelect()
@ -255,7 +258,7 @@ class InterfaceTemplateCreateForm(ComponentTemplateCreateForm):
)
class FrontPortTemplateCreateForm(ComponentTemplateCreateForm):
class FrontPortTemplateCreateForm(ModularComponentTemplateCreateForm):
type = forms.ChoiceField(
choices=PortTypeChoices,
widget=StaticSelect()
@ -320,7 +323,7 @@ class FrontPortTemplateCreateForm(ComponentTemplateCreateForm):
}
class RearPortTemplateCreateForm(ComponentTemplateCreateForm):
class RearPortTemplateCreateForm(ModularComponentTemplateCreateForm):
type = forms.ChoiceField(
choices=PortTypeChoices,
widget=StaticSelect(),
@ -341,6 +344,7 @@ class RearPortTemplateCreateForm(ComponentTemplateCreateForm):
class ModuleBayTemplateCreateForm(ComponentTemplateCreateForm):
# TODO: Support patterned position assignment
field_order = ('manufacturer', 'device_type', 'name_pattern', 'label_pattern', 'description')

View File

@ -155,7 +155,7 @@ class ModuleBayTemplateImportForm(ComponentTemplateImportForm):
class Meta:
model = ModuleBayTemplate
fields = [
'device_type', 'name', 'label', 'description',
'device_type', 'name', 'label', 'position', 'description',
]

View File

@ -105,6 +105,7 @@ class Migration(migrations.Migration):
('name', models.CharField(max_length=64)),
('_name', utilities.fields.NaturalOrderingField('name', blank=True, max_length=100, naturalize_function=utilities.ordering.naturalize)),
('label', models.CharField(blank=True, max_length=64)),
('position', models.CharField(blank=True, max_length=30)),
('description', models.CharField(blank=True, max_length=200)),
('device', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='modulebays', to='dcim.device')),
('tags', taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag')),
@ -241,6 +242,7 @@ class Migration(migrations.Migration):
('name', models.CharField(max_length=64)),
('_name', utilities.fields.NaturalOrderingField('name', blank=True, max_length=100, naturalize_function=utilities.ordering.naturalize)),
('label', models.CharField(blank=True, max_length=64)),
('position', models.CharField(blank=True, max_length=30)),
('description', models.CharField(blank=True, max_length=200)),
('device_type', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='modulebaytemplates', to='dcim.devicetype')),
],

View File

@ -123,6 +123,11 @@ class ModularComponentTemplateModel(ComponentTemplateModel):
"A component template must be associated with either a device type or a module type."
)
def resolve_name(self, module):
if module:
return self.name.replace('{module}', module.module_bay.position)
return self.name
@extras_features('webhooks')
class ConsolePortTemplate(ModularComponentTemplateModel):
@ -144,7 +149,7 @@ class ConsolePortTemplate(ModularComponentTemplateModel):
def instantiate(self, **kwargs):
return ConsolePort(
name=self.name,
name=self.resolve_name(kwargs.get('module')),
label=self.label,
type=self.type,
**kwargs
@ -171,7 +176,7 @@ class ConsoleServerPortTemplate(ModularComponentTemplateModel):
def instantiate(self, **kwargs):
return ConsoleServerPort(
name=self.name,
name=self.resolve_name(kwargs.get('module')),
label=self.label,
type=self.type,
**kwargs
@ -210,7 +215,7 @@ class PowerPortTemplate(ModularComponentTemplateModel):
def instantiate(self, **kwargs):
return PowerPort(
name=self.name,
name=self.resolve_name(kwargs.get('module')),
label=self.label,
type=self.type,
maximum_draw=self.maximum_draw,
@ -279,7 +284,7 @@ class PowerOutletTemplate(ModularComponentTemplateModel):
else:
power_port = None
return PowerOutlet(
name=self.name,
name=self.resolve_name(kwargs.get('module')),
label=self.label,
type=self.type,
power_port=power_port,
@ -318,7 +323,7 @@ class InterfaceTemplate(ModularComponentTemplateModel):
def instantiate(self, **kwargs):
return Interface(
name=self.name,
name=self.resolve_name(kwargs.get('module')),
label=self.label,
type=self.type,
mgmt_only=self.mgmt_only,
@ -387,7 +392,7 @@ class FrontPortTemplate(ModularComponentTemplateModel):
else:
rear_port = None
return FrontPort(
name=self.name,
name=self.resolve_name(kwargs.get('module')),
label=self.label,
type=self.type,
color=self.color,
@ -426,7 +431,7 @@ class RearPortTemplate(ModularComponentTemplateModel):
def instantiate(self, **kwargs):
return RearPort(
name=self.name,
name=self.resolve_name(kwargs.get('module')),
label=self.label,
type=self.type,
color=self.color,
@ -440,6 +445,12 @@ class ModuleBayTemplate(ComponentTemplateModel):
"""
A template for a ModuleBay to be created for a new parent Device.
"""
position = models.CharField(
max_length=30,
blank=True,
help_text='Identifier to reference when renaming installed components'
)
class Meta:
ordering = ('device_type', '_name')
unique_together = ('device_type', 'name')
@ -448,7 +459,8 @@ class ModuleBayTemplate(ComponentTemplateModel):
return ModuleBay(
device=device,
name=self.name,
label=self.label
label=self.label,
position=self.position
)

View File

@ -880,6 +880,12 @@ class ModuleBay(ComponentModel):
"""
An empty space within a Device which can house a child device
"""
position = models.CharField(
max_length=30,
blank=True,
help_text='Identifier to reference when renaming installed components'
)
clone_fields = ['device']
class Meta:

View File

@ -749,7 +749,7 @@ class ModuleBayTable(DeviceComponentTable):
class Meta(DeviceComponentTable.Meta):
model = ModuleBay
fields = ('pk', 'id', 'name', 'device', 'label', 'installed_module', 'description', 'tags')
fields = ('pk', 'id', 'name', 'device', 'label', 'position', 'installed_module', 'description', 'tags')
default_columns = ('pk', 'name', 'device', 'label', 'installed_module', 'description')

View File

@ -217,7 +217,7 @@ class ModuleBayTemplateTable(ComponentTemplateTable):
class Meta(ComponentTemplateTable.Meta):
model = ModuleBayTemplate
fields = ('pk', 'name', 'label', 'description', 'actions')
fields = ('pk', 'name', 'label', 'position', 'description', 'actions')
empty_text = "None"

View File

@ -23,6 +23,10 @@
<th scope="row">Label</th>
<td>{{ object.label|placeholder }}</td>
</tr>
<tr>
<th scope="row">Position</th>
<td>{{ object.position|placeholder }}</td>
</tr>
<tr>
<th scope="row">Description</th>
<td>{{ object.description|placeholder }}</td>

View File

@ -45,7 +45,7 @@
{% block tab_items %}
<li role="presentation" class="nav-item">
<a href="{% url 'dcim:devicetype' pk=object.pk %}" class="nav-link{% if active_tab == 'moduletype' %} active{% endif %}">
<a href="{% url 'dcim:moduletype' pk=object.pk %}" class="nav-link{% if active_tab == 'moduletype' %} active{% endif %}">
Module Type
</a>
</li>