Fixes #9330: Add missing module_type field to REST API serializers for modular device component templates

This commit is contained in:
jeremystretch 2022-05-11 08:57:19 -04:00
parent e759e123ac
commit bdb21da26e
3 changed files with 167 additions and 35 deletions

View File

@ -17,6 +17,7 @@
* [#9306](https://github.com/netbox-community/netbox/issues/9306) - Include VC master interfaces when selecting a LAG/bridge for a VC member interface * [#9306](https://github.com/netbox-community/netbox/issues/9306) - Include VC master interfaces when selecting a LAG/bridge for a VC member interface
* [#9311](https://github.com/netbox-community/netbox/issues/9311) - Permit creating contact assignment without a priority via the REST API * [#9311](https://github.com/netbox-community/netbox/issues/9311) - Permit creating contact assignment without a priority via the REST API
* [#9313](https://github.com/netbox-community/netbox/issues/9313) - Remove HTML code from CSV output of many-to-many relationships * [#9313](https://github.com/netbox-community/netbox/issues/9313) - Remove HTML code from CSV output of many-to-many relationships
* [#9330](https://github.com/netbox-community/netbox/issues/9330) - Add missing `module_type` field to REST API serializers for modular device component templates
--- ---

View File

@ -315,7 +315,16 @@ class ModuleTypeSerializer(NetBoxModelSerializer):
class ConsolePortTemplateSerializer(ValidatedModelSerializer): class ConsolePortTemplateSerializer(ValidatedModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:consoleporttemplate-detail') url = serializers.HyperlinkedIdentityField(view_name='dcim-api:consoleporttemplate-detail')
device_type = NestedDeviceTypeSerializer() device_type = NestedDeviceTypeSerializer(
required=False,
allow_null=True,
default=None
)
module_type = NestedModuleTypeSerializer(
required=False,
allow_null=True,
default=None
)
type = ChoiceField( type = ChoiceField(
choices=ConsolePortTypeChoices, choices=ConsolePortTypeChoices,
allow_blank=True, allow_blank=True,
@ -325,13 +334,23 @@ class ConsolePortTemplateSerializer(ValidatedModelSerializer):
class Meta: class Meta:
model = ConsolePortTemplate model = ConsolePortTemplate
fields = [ fields = [
'id', 'url', 'display', 'device_type', 'name', 'label', 'type', 'description', 'created', 'last_updated', 'id', 'url', 'display', 'device_type', 'module_type', 'name', 'label', 'type', 'description', 'created',
'last_updated',
] ]
class ConsoleServerPortTemplateSerializer(ValidatedModelSerializer): class ConsoleServerPortTemplateSerializer(ValidatedModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:consoleserverporttemplate-detail') url = serializers.HyperlinkedIdentityField(view_name='dcim-api:consoleserverporttemplate-detail')
device_type = NestedDeviceTypeSerializer() device_type = NestedDeviceTypeSerializer(
required=False,
allow_null=True,
default=None
)
module_type = NestedModuleTypeSerializer(
required=False,
allow_null=True,
default=None
)
type = ChoiceField( type = ChoiceField(
choices=ConsolePortTypeChoices, choices=ConsolePortTypeChoices,
allow_blank=True, allow_blank=True,
@ -341,13 +360,23 @@ class ConsoleServerPortTemplateSerializer(ValidatedModelSerializer):
class Meta: class Meta:
model = ConsoleServerPortTemplate model = ConsoleServerPortTemplate
fields = [ fields = [
'id', 'url', 'display', 'device_type', 'name', 'label', 'type', 'description', 'created', 'last_updated', 'id', 'url', 'display', 'device_type', 'module_type', 'name', 'label', 'type', 'description', 'created',
'last_updated',
] ]
class PowerPortTemplateSerializer(ValidatedModelSerializer): class PowerPortTemplateSerializer(ValidatedModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:powerporttemplate-detail') url = serializers.HyperlinkedIdentityField(view_name='dcim-api:powerporttemplate-detail')
device_type = NestedDeviceTypeSerializer() device_type = NestedDeviceTypeSerializer(
required=False,
allow_null=True,
default=None
)
module_type = NestedModuleTypeSerializer(
required=False,
allow_null=True,
default=None
)
type = ChoiceField( type = ChoiceField(
choices=PowerPortTypeChoices, choices=PowerPortTypeChoices,
allow_blank=True, allow_blank=True,
@ -357,14 +386,23 @@ class PowerPortTemplateSerializer(ValidatedModelSerializer):
class Meta: class Meta:
model = PowerPortTemplate model = PowerPortTemplate
fields = [ fields = [
'id', 'url', 'display', 'device_type', 'name', 'label', 'type', 'maximum_draw', 'allocated_draw', 'id', 'url', 'display', 'device_type', 'module_type', 'name', 'label', 'type', 'maximum_draw',
'description', 'created', 'last_updated', 'allocated_draw', 'description', 'created', 'last_updated',
] ]
class PowerOutletTemplateSerializer(ValidatedModelSerializer): class PowerOutletTemplateSerializer(ValidatedModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:poweroutlettemplate-detail') url = serializers.HyperlinkedIdentityField(view_name='dcim-api:poweroutlettemplate-detail')
device_type = NestedDeviceTypeSerializer() device_type = NestedDeviceTypeSerializer(
required=False,
allow_null=True,
default=None
)
module_type = NestedModuleTypeSerializer(
required=False,
allow_null=True,
default=None
)
type = ChoiceField( type = ChoiceField(
choices=PowerOutletTypeChoices, choices=PowerOutletTypeChoices,
allow_blank=True, allow_blank=True,
@ -383,48 +421,75 @@ class PowerOutletTemplateSerializer(ValidatedModelSerializer):
class Meta: class Meta:
model = PowerOutletTemplate model = PowerOutletTemplate
fields = [ fields = [
'id', 'url', 'display', 'device_type', 'name', 'label', 'type', 'power_port', 'feed_leg', 'description', 'id', 'url', 'display', 'device_type', 'module_type', 'name', 'label', 'type', 'power_port', 'feed_leg',
'created', 'last_updated', 'description', 'created', 'last_updated',
] ]
class InterfaceTemplateSerializer(ValidatedModelSerializer): class InterfaceTemplateSerializer(ValidatedModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:interfacetemplate-detail') url = serializers.HyperlinkedIdentityField(view_name='dcim-api:interfacetemplate-detail')
device_type = NestedDeviceTypeSerializer() device_type = NestedDeviceTypeSerializer(
required=False,
allow_null=True,
default=None
)
module_type = NestedModuleTypeSerializer(
required=False,
allow_null=True,
default=None
)
type = ChoiceField(choices=InterfaceTypeChoices) type = ChoiceField(choices=InterfaceTypeChoices)
class Meta: class Meta:
model = InterfaceTemplate model = InterfaceTemplate
fields = [ fields = [
'id', 'url', 'display', 'device_type', 'name', 'label', 'type', 'mgmt_only', 'description', 'created', 'id', 'url', 'display', 'device_type', 'module_type', 'name', 'label', 'type', 'mgmt_only', 'description',
'last_updated', 'created', 'last_updated',
] ]
class RearPortTemplateSerializer(ValidatedModelSerializer): class RearPortTemplateSerializer(ValidatedModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:rearporttemplate-detail') url = serializers.HyperlinkedIdentityField(view_name='dcim-api:rearporttemplate-detail')
device_type = NestedDeviceTypeSerializer() device_type = NestedDeviceTypeSerializer(
required=False,
allow_null=True,
default=None
)
module_type = NestedModuleTypeSerializer(
required=False,
allow_null=True,
default=None
)
type = ChoiceField(choices=PortTypeChoices) type = ChoiceField(choices=PortTypeChoices)
class Meta: class Meta:
model = RearPortTemplate model = RearPortTemplate
fields = [ fields = [
'id', 'url', 'display', 'device_type', 'name', 'label', 'type', 'color', 'positions', 'description', 'id', 'url', 'display', 'device_type', 'module_type', 'name', 'label', 'type', 'color', 'positions',
'created', 'last_updated', 'description', 'created', 'last_updated',
] ]
class FrontPortTemplateSerializer(ValidatedModelSerializer): class FrontPortTemplateSerializer(ValidatedModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:frontporttemplate-detail') url = serializers.HyperlinkedIdentityField(view_name='dcim-api:frontporttemplate-detail')
device_type = NestedDeviceTypeSerializer() device_type = NestedDeviceTypeSerializer(
required=False,
allow_null=True,
default=None
)
module_type = NestedModuleTypeSerializer(
required=False,
allow_null=True,
default=None
)
type = ChoiceField(choices=PortTypeChoices) type = ChoiceField(choices=PortTypeChoices)
rear_port = NestedRearPortTemplateSerializer() rear_port = NestedRearPortTemplateSerializer()
class Meta: class Meta:
model = FrontPortTemplate model = FrontPortTemplate
fields = [ fields = [
'id', 'url', 'display', 'device_type', 'name', 'label', 'type', 'color', 'rear_port', 'rear_port_position', 'id', 'url', 'display', 'device_type', 'module_type', 'name', 'label', 'type', 'color', 'rear_port',
'description', 'created', 'last_updated', 'rear_port_position', 'description', 'created', 'last_updated',
] ]

View File

@ -523,6 +523,9 @@ class ConsolePortTemplateTest(APIViewTestCases.APIViewTestCase):
devicetype = DeviceType.objects.create( devicetype = DeviceType.objects.create(
manufacturer=manufacturer, model='Device Type 1', slug='device-type-1' manufacturer=manufacturer, model='Device Type 1', slug='device-type-1'
) )
moduletype = ModuleType.objects.create(
manufacturer=manufacturer, model='Module Type 1'
)
console_port_templates = ( console_port_templates = (
ConsolePortTemplate(device_type=devicetype, name='Console Port Template 1'), ConsolePortTemplate(device_type=devicetype, name='Console Port Template 1'),
@ -541,9 +544,13 @@ class ConsolePortTemplateTest(APIViewTestCases.APIViewTestCase):
'name': 'Console Port Template 5', 'name': 'Console Port Template 5',
}, },
{ {
'device_type': devicetype.pk, 'module_type': moduletype.pk,
'name': 'Console Port Template 6', 'name': 'Console Port Template 6',
}, },
{
'module_type': moduletype.pk,
'name': 'Console Port Template 7',
},
] ]
@ -560,6 +567,9 @@ class ConsoleServerPortTemplateTest(APIViewTestCases.APIViewTestCase):
devicetype = DeviceType.objects.create( devicetype = DeviceType.objects.create(
manufacturer=manufacturer, model='Device Type 1', slug='device-type-1' manufacturer=manufacturer, model='Device Type 1', slug='device-type-1'
) )
moduletype = ModuleType.objects.create(
manufacturer=manufacturer, model='Module Type 1'
)
console_server_port_templates = ( console_server_port_templates = (
ConsoleServerPortTemplate(device_type=devicetype, name='Console Server Port Template 1'), ConsoleServerPortTemplate(device_type=devicetype, name='Console Server Port Template 1'),
@ -578,9 +588,13 @@ class ConsoleServerPortTemplateTest(APIViewTestCases.APIViewTestCase):
'name': 'Console Server Port Template 5', 'name': 'Console Server Port Template 5',
}, },
{ {
'device_type': devicetype.pk, 'module_type': moduletype.pk,
'name': 'Console Server Port Template 6', 'name': 'Console Server Port Template 6',
}, },
{
'module_type': moduletype.pk,
'name': 'Console Server Port Template 7',
},
] ]
@ -597,6 +611,9 @@ class PowerPortTemplateTest(APIViewTestCases.APIViewTestCase):
devicetype = DeviceType.objects.create( devicetype = DeviceType.objects.create(
manufacturer=manufacturer, model='Device Type 1', slug='device-type-1' manufacturer=manufacturer, model='Device Type 1', slug='device-type-1'
) )
moduletype = ModuleType.objects.create(
manufacturer=manufacturer, model='Module Type 1'
)
power_port_templates = ( power_port_templates = (
PowerPortTemplate(device_type=devicetype, name='Power Port Template 1'), PowerPortTemplate(device_type=devicetype, name='Power Port Template 1'),
@ -615,9 +632,13 @@ class PowerPortTemplateTest(APIViewTestCases.APIViewTestCase):
'name': 'Power Port Template 5', 'name': 'Power Port Template 5',
}, },
{ {
'device_type': devicetype.pk, 'module_type': moduletype.pk,
'name': 'Power Port Template 6', 'name': 'Power Port Template 6',
}, },
{
'module_type': moduletype.pk,
'name': 'Power Port Template 7',
},
] ]
@ -634,6 +655,9 @@ class PowerOutletTemplateTest(APIViewTestCases.APIViewTestCase):
devicetype = DeviceType.objects.create( devicetype = DeviceType.objects.create(
manufacturer=manufacturer, model='Device Type 1', slug='device-type-1' manufacturer=manufacturer, model='Device Type 1', slug='device-type-1'
) )
moduletype = ModuleType.objects.create(
manufacturer=manufacturer, model='Module Type 1'
)
power_port_templates = ( power_port_templates = (
PowerPortTemplate(device_type=devicetype, name='Power Port Template 1'), PowerPortTemplate(device_type=devicetype, name='Power Port Template 1'),
@ -664,6 +688,14 @@ class PowerOutletTemplateTest(APIViewTestCases.APIViewTestCase):
'name': 'Power Outlet Template 6', 'name': 'Power Outlet Template 6',
'power_port': None, 'power_port': None,
}, },
{
'module_type': moduletype.pk,
'name': 'Power Outlet Template 7',
},
{
'module_type': moduletype.pk,
'name': 'Power Outlet Template 8',
},
] ]
@ -680,6 +712,9 @@ class InterfaceTemplateTest(APIViewTestCases.APIViewTestCase):
devicetype = DeviceType.objects.create( devicetype = DeviceType.objects.create(
manufacturer=manufacturer, model='Device Type 1', slug='device-type-1' manufacturer=manufacturer, model='Device Type 1', slug='device-type-1'
) )
moduletype = ModuleType.objects.create(
manufacturer=manufacturer, model='Module Type 1'
)
interface_templates = ( interface_templates = (
InterfaceTemplate(device_type=devicetype, name='Interface Template 1', type='1000base-t'), InterfaceTemplate(device_type=devicetype, name='Interface Template 1', type='1000base-t'),
@ -700,10 +735,15 @@ class InterfaceTemplateTest(APIViewTestCases.APIViewTestCase):
'type': '1000base-t', 'type': '1000base-t',
}, },
{ {
'device_type': devicetype.pk, 'module_type': moduletype.pk,
'name': 'Interface Template 6', 'name': 'Interface Template 6',
'type': '1000base-t', 'type': '1000base-t',
}, },
{
'module_type': moduletype.pk,
'name': 'Interface Template 7',
'type': '1000base-t',
},
] ]
@ -720,14 +760,19 @@ class FrontPortTemplateTest(APIViewTestCases.APIViewTestCase):
devicetype = DeviceType.objects.create( devicetype = DeviceType.objects.create(
manufacturer=manufacturer, model='Device Type 1', slug='device-type-1' manufacturer=manufacturer, model='Device Type 1', slug='device-type-1'
) )
moduletype = ModuleType.objects.create(
manufacturer=manufacturer, model='Module Type 1'
)
rear_port_templates = ( rear_port_templates = (
RearPortTemplate(device_type=devicetype, name='Rear Port Template 1', type=PortTypeChoices.TYPE_8P8C), RearPortTemplate(device_type=devicetype, name='Rear Port Template 1', type=PortTypeChoices.TYPE_8P8C),
RearPortTemplate(device_type=devicetype, name='Rear Port Template 2', type=PortTypeChoices.TYPE_8P8C), RearPortTemplate(device_type=devicetype, name='Rear Port Template 2', type=PortTypeChoices.TYPE_8P8C),
RearPortTemplate(device_type=devicetype, name='Rear Port Template 3', type=PortTypeChoices.TYPE_8P8C), RearPortTemplate(device_type=devicetype, name='Rear Port Template 3', type=PortTypeChoices.TYPE_8P8C),
RearPortTemplate(device_type=devicetype, name='Rear Port Template 4', type=PortTypeChoices.TYPE_8P8C), RearPortTemplate(device_type=devicetype, name='Rear Port Template 4', type=PortTypeChoices.TYPE_8P8C),
RearPortTemplate(device_type=devicetype, name='Rear Port Template 5', type=PortTypeChoices.TYPE_8P8C), RearPortTemplate(module_type=moduletype, name='Rear Port Template 5', type=PortTypeChoices.TYPE_8P8C),
RearPortTemplate(device_type=devicetype, name='Rear Port Template 6', type=PortTypeChoices.TYPE_8P8C), RearPortTemplate(module_type=moduletype, name='Rear Port Template 6', type=PortTypeChoices.TYPE_8P8C),
RearPortTemplate(module_type=moduletype, name='Rear Port Template 7', type=PortTypeChoices.TYPE_8P8C),
RearPortTemplate(module_type=moduletype, name='Rear Port Template 8', type=PortTypeChoices.TYPE_8P8C),
) )
RearPortTemplate.objects.bulk_create(rear_port_templates) RearPortTemplate.objects.bulk_create(rear_port_templates)
@ -745,15 +790,28 @@ class FrontPortTemplateTest(APIViewTestCases.APIViewTestCase):
rear_port=rear_port_templates[1] rear_port=rear_port_templates[1]
), ),
FrontPortTemplate( FrontPortTemplate(
device_type=devicetype, module_type=moduletype,
name='Front Port Template 3', name='Front Port Template 5',
type=PortTypeChoices.TYPE_8P8C, type=PortTypeChoices.TYPE_8P8C,
rear_port=rear_port_templates[2] rear_port=rear_port_templates[4]
),
FrontPortTemplate(
module_type=moduletype,
name='Front Port Template 6',
type=PortTypeChoices.TYPE_8P8C,
rear_port=rear_port_templates[5]
), ),
) )
FrontPortTemplate.objects.bulk_create(front_port_templates) FrontPortTemplate.objects.bulk_create(front_port_templates)
cls.create_data = [ cls.create_data = [
{
'device_type': devicetype.pk,
'name': 'Front Port Template 3',
'type': PortTypeChoices.TYPE_8P8C,
'rear_port': rear_port_templates[2].pk,
'rear_port_position': 1,
},
{ {
'device_type': devicetype.pk, 'device_type': devicetype.pk,
'name': 'Front Port Template 4', 'name': 'Front Port Template 4',
@ -762,17 +820,17 @@ class FrontPortTemplateTest(APIViewTestCases.APIViewTestCase):
'rear_port_position': 1, 'rear_port_position': 1,
}, },
{ {
'device_type': devicetype.pk, 'module_type': moduletype.pk,
'name': 'Front Port Template 5', 'name': 'Front Port Template 7',
'type': PortTypeChoices.TYPE_8P8C, 'type': PortTypeChoices.TYPE_8P8C,
'rear_port': rear_port_templates[4].pk, 'rear_port': rear_port_templates[6].pk,
'rear_port_position': 1, 'rear_port_position': 1,
}, },
{ {
'device_type': devicetype.pk, 'module_type': moduletype.pk,
'name': 'Front Port Template 6', 'name': 'Front Port Template 8',
'type': PortTypeChoices.TYPE_8P8C, 'type': PortTypeChoices.TYPE_8P8C,
'rear_port': rear_port_templates[5].pk, 'rear_port': rear_port_templates[7].pk,
'rear_port_position': 1, 'rear_port_position': 1,
}, },
] ]
@ -791,6 +849,9 @@ class RearPortTemplateTest(APIViewTestCases.APIViewTestCase):
devicetype = DeviceType.objects.create( devicetype = DeviceType.objects.create(
manufacturer=manufacturer, model='Device Type 1', slug='device-type-1' manufacturer=manufacturer, model='Device Type 1', slug='device-type-1'
) )
moduletype = ModuleType.objects.create(
manufacturer=manufacturer, model='Module Type 1'
)
rear_port_templates = ( rear_port_templates = (
RearPortTemplate(device_type=devicetype, name='Rear Port Template 1', type=PortTypeChoices.TYPE_8P8C), RearPortTemplate(device_type=devicetype, name='Rear Port Template 1', type=PortTypeChoices.TYPE_8P8C),
@ -811,10 +872,15 @@ class RearPortTemplateTest(APIViewTestCases.APIViewTestCase):
'type': PortTypeChoices.TYPE_8P8C, 'type': PortTypeChoices.TYPE_8P8C,
}, },
{ {
'device_type': devicetype.pk, 'module_type': moduletype.pk,
'name': 'Rear Port Template 6', 'name': 'Rear Port Template 6',
'type': PortTypeChoices.TYPE_8P8C, 'type': PortTypeChoices.TYPE_8P8C,
}, },
{
'module_type': moduletype.pk,
'name': 'Rear Port Template 7',
'type': PortTypeChoices.TYPE_8P8C,
},
] ]