Allow bridge when importing interface templates

Adding the field to the InterfaceTemplateImportForm is enough. The two
clean_*_type methods are for properly dynamically restricting what
values can be selected.
This commit is contained in:
Marko Hauptvogel 2025-08-22 09:53:51 +02:00
parent 16e284f03a
commit 18480668e0
2 changed files with 71 additions and 2 deletions

View File

@ -84,6 +84,12 @@ class InterfaceTemplateImportForm(forms.ModelForm):
label=_('Type'),
choices=InterfaceTypeChoices.CHOICES
)
bridge = forms.ModelChoiceField(
label=_('Bridge'),
queryset=InterfaceTemplate.objects.all(),
to_field_name='name',
required=False
)
poe_mode = forms.ChoiceField(
choices=InterfacePoEModeChoices,
required=False,
@ -103,10 +109,24 @@ class InterfaceTemplateImportForm(forms.ModelForm):
class Meta:
model = InterfaceTemplate
fields = [
'device_type', 'module_type', 'name', 'label', 'type', 'enabled', 'mgmt_only', 'description', 'poe_mode',
'poe_type', 'rf_role'
'device_type', 'module_type', 'name', 'label', 'type', 'enabled', 'mgmt_only', 'description', 'bridge',
'poe_mode', 'poe_type', 'rf_role'
]
def clean_device_type(self):
if device_type := self.cleaned_data['device_type']:
bridge = self.fields['bridge']
bridge.queryset = bridge.queryset.filter(device_type=device_type)
return device_type
def clean_module_type(self):
if module_type := self.cleaned_data['module_type']:
bridge = self.fields['bridge']
bridge.queryset = bridge.queryset.filter(module_type=module_type)
return module_type
class FrontPortTemplateImportForm(forms.ModelForm):
type = forms.ChoiceField(

View File

@ -1055,6 +1055,55 @@ console-ports:
self.assertHttpStatus(response, 200)
self.assertContains(response, "console-ports[0]: Must be a dictionary.")
@override_settings(EXEMPT_VIEW_PERMISSIONS=['*'])
def test_import_interfacebridge(self):
IMPORT_DATA = """
manufacturer: Manufacturer 1
model: TEST-4000
slug: test-4000
u_height: 1
interfaces:
- name: Bridge
type: 1000base-t
- name: Bridge Interface 1
type: 1000base-t
bridge: Bridge
"""
# Add all required permissions to the test user
self.add_permissions(
'dcim.view_devicetype',
'dcim.add_devicetype',
'dcim.add_consoleporttemplate',
'dcim.add_consoleserverporttemplate',
'dcim.add_powerporttemplate',
'dcim.add_poweroutlettemplate',
'dcim.add_interfacetemplate',
'dcim.add_frontporttemplate',
'dcim.add_rearporttemplate',
'dcim.add_modulebaytemplate',
'dcim.add_devicebaytemplate',
'dcim.add_inventoryitemtemplate',
)
form_data = {
'data': IMPORT_DATA,
'format': 'yaml'
}
response = self.client.post(reverse('dcim:devicetype_bulk_import'), data=form_data, follow=True)
self.assertHttpStatus(response, 200)
self.assertContains(response, "Imported 1 device types")
device_type = DeviceType.objects.get(model='TEST-4000')
self.assertEqual(device_type.interfacetemplates.count(), 2)
interfaces = InterfaceTemplate.objects.all().order_by('id')
self.assertEqual(interfaces[0].name, 'Bridge')
self.assertIsNone(interfaces[0].bridge)
self.assertEqual(interfaces[1].name, 'Bridge Interface 1')
self.assertEqual(interfaces[1].bridge.name, "Bridge")
def test_export_objects(self):
url = reverse('dcim:devicetype_list')
self.add_permissions('dcim.view_devicetype')