From 8e94eb67d23a93a05892a2167733ccbeda6d4b65 Mon Sep 17 00:00:00 2001 From: kkthxbye Date: Mon, 9 Jan 2023 09:01:14 +0100 Subject: [PATCH] Add the `enabled` filed to InterfaceTemplate --- netbox/dcim/api/serializers.py | 2 +- netbox/dcim/filtersets.py | 2 +- netbox/dcim/forms/bulk_edit.py | 4 ++++ netbox/dcim/forms/model_forms.py | 4 ++-- netbox/dcim/forms/object_import.py | 2 +- .../0168_interface_template_enabled.py | 18 ++++++++++++++++++ .../dcim/models/device_component_templates.py | 5 +++++ netbox/dcim/tables/devicetypes.py | 3 ++- netbox/dcim/tests/test_filtersets.py | 10 ++++++++-- netbox/dcim/tests/test_views.py | 5 +++++ 10 files changed, 47 insertions(+), 8 deletions(-) create mode 100644 netbox/dcim/migrations/0168_interface_template_enabled.py diff --git a/netbox/dcim/api/serializers.py b/netbox/dcim/api/serializers.py index e041d4c02..1f4f3ff5f 100644 --- a/netbox/dcim/api/serializers.py +++ b/netbox/dcim/api/serializers.py @@ -487,7 +487,7 @@ class InterfaceTemplateSerializer(ValidatedModelSerializer): class Meta: model = InterfaceTemplate fields = [ - 'id', 'url', 'display', 'device_type', 'module_type', 'name', 'label', 'type', 'mgmt_only', 'description', + 'id', 'url', 'display', 'device_type', 'module_type', 'name', 'label', 'type', 'enabled', 'mgmt_only', 'description', 'poe_mode', 'poe_type', 'created', 'last_updated', ] diff --git a/netbox/dcim/filtersets.py b/netbox/dcim/filtersets.py index c10ef44c3..83ae8bcc9 100644 --- a/netbox/dcim/filtersets.py +++ b/netbox/dcim/filtersets.py @@ -683,7 +683,7 @@ class InterfaceTemplateFilterSet(ChangeLoggedModelFilterSet, ModularDeviceTypeCo class Meta: model = InterfaceTemplate - fields = ['id', 'name', 'type', 'mgmt_only'] + fields = ['id', 'name', 'type', 'enabled', 'mgmt_only'] class FrontPortTemplateFilterSet(ChangeLoggedModelFilterSet, ModularDeviceTypeComponentFilterSet): diff --git a/netbox/dcim/forms/bulk_edit.py b/netbox/dcim/forms/bulk_edit.py index 38fa55738..8969b1e69 100644 --- a/netbox/dcim/forms/bulk_edit.py +++ b/netbox/dcim/forms/bulk_edit.py @@ -923,6 +923,10 @@ class InterfaceTemplateBulkEditForm(BulkEditForm): required=False, widget=StaticSelect() ) + enabled = forms.NullBooleanField( + required=False, + widget=BulkEditNullBooleanSelect + ) mgmt_only = forms.NullBooleanField( required=False, widget=BulkEditNullBooleanSelect, diff --git a/netbox/dcim/forms/model_forms.py b/netbox/dcim/forms/model_forms.py index 91e0266f0..703a7a6b4 100644 --- a/netbox/dcim/forms/model_forms.py +++ b/netbox/dcim/forms/model_forms.py @@ -1088,14 +1088,14 @@ class PowerOutletTemplateForm(ModularComponentTemplateForm): class InterfaceTemplateForm(ModularComponentTemplateForm): fieldsets = ( - (None, ('device_type', 'module_type', 'name', 'label', 'type', 'mgmt_only', 'description')), + (None, ('device_type', 'module_type', 'name', 'label', 'type', 'enabled', 'mgmt_only', 'description')), ('PoE', ('poe_mode', 'poe_type')) ) class Meta: model = InterfaceTemplate fields = [ - 'device_type', 'module_type', 'name', 'label', 'type', 'mgmt_only', 'description', 'poe_mode', 'poe_type', + 'device_type', 'module_type', 'name', 'label', 'type', 'mgmt_only', 'enabled', 'description', 'poe_mode', 'poe_type', ] widgets = { 'type': StaticSelect(), diff --git a/netbox/dcim/forms/object_import.py b/netbox/dcim/forms/object_import.py index dfa1a4c6a..9328a3f72 100644 --- a/netbox/dcim/forms/object_import.py +++ b/netbox/dcim/forms/object_import.py @@ -100,7 +100,7 @@ class InterfaceTemplateImportForm(ComponentTemplateImportForm): class Meta: model = InterfaceTemplate fields = [ - 'device_type', 'module_type', 'name', 'label', 'type', 'mgmt_only', 'description', 'poe_mode', 'poe_type', + 'device_type', 'module_type', 'name', 'label', 'type', 'enabled', 'mgmt_only', 'description', 'poe_mode', 'poe_type', ] diff --git a/netbox/dcim/migrations/0168_interface_template_enabled.py b/netbox/dcim/migrations/0168_interface_template_enabled.py new file mode 100644 index 000000000..604c1dde3 --- /dev/null +++ b/netbox/dcim/migrations/0168_interface_template_enabled.py @@ -0,0 +1,18 @@ +# Generated by Django 4.1.5 on 2023-01-09 07:03 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('dcim', '0167_module_status'), + ] + + operations = [ + migrations.AddField( + model_name='interfacetemplate', + name='enabled', + field=models.BooleanField(default=True), + ), + ] diff --git a/netbox/dcim/models/device_component_templates.py b/netbox/dcim/models/device_component_templates.py index 3b136987d..3d2d32509 100644 --- a/netbox/dcim/models/device_component_templates.py +++ b/netbox/dcim/models/device_component_templates.py @@ -344,6 +344,9 @@ class InterfaceTemplate(ModularComponentTemplateModel): max_length=50, choices=InterfaceTypeChoices ) + enabled = models.BooleanField( + default=True + ) mgmt_only = models.BooleanField( default=False, verbose_name='Management only' @@ -368,6 +371,7 @@ class InterfaceTemplate(ModularComponentTemplateModel): name=self.resolve_name(kwargs.get('module')), label=self.resolve_label(kwargs.get('module')), type=self.type, + enabled=self.enabled, mgmt_only=self.mgmt_only, poe_mode=self.poe_mode, poe_type=self.poe_type, @@ -378,6 +382,7 @@ class InterfaceTemplate(ModularComponentTemplateModel): return { 'name': self.name, 'type': self.type, + 'enabled': self.enabled, 'mgmt_only': self.mgmt_only, 'label': self.label, 'description': self.description, diff --git a/netbox/dcim/tables/devicetypes.py b/netbox/dcim/tables/devicetypes.py index c452c3efb..9bcc9c47f 100644 --- a/netbox/dcim/tables/devicetypes.py +++ b/netbox/dcim/tables/devicetypes.py @@ -174,6 +174,7 @@ class PowerOutletTemplateTable(ComponentTemplateTable): class InterfaceTemplateTable(ComponentTemplateTable): + enabled = columns.BooleanColumn() mgmt_only = columns.BooleanColumn( verbose_name='Management Only' ) @@ -184,7 +185,7 @@ class InterfaceTemplateTable(ComponentTemplateTable): class Meta(ComponentTemplateTable.Meta): model = models.InterfaceTemplate - fields = ('pk', 'name', 'label', 'mgmt_only', 'type', 'description', 'poe_mode', 'poe_type', 'actions') + fields = ('pk', 'name', 'label', 'enabled', 'mgmt_only', 'type', 'description', 'poe_mode', 'poe_type', 'actions') empty_text = "None" diff --git a/netbox/dcim/tests/test_filtersets.py b/netbox/dcim/tests/test_filtersets.py index 6fb3feb11..45d5797bd 100644 --- a/netbox/dcim/tests/test_filtersets.py +++ b/netbox/dcim/tests/test_filtersets.py @@ -1129,8 +1129,8 @@ class InterfaceTemplateTestCase(TestCase, ChangeLoggedFilterSetTests): DeviceType.objects.bulk_create(device_types) InterfaceTemplate.objects.bulk_create(( - InterfaceTemplate(device_type=device_types[0], name='Interface 1', type=InterfaceTypeChoices.TYPE_1GE_FIXED, mgmt_only=True, poe_mode=InterfacePoEModeChoices.MODE_PD, poe_type=InterfacePoETypeChoices.TYPE_1_8023AF), - InterfaceTemplate(device_type=device_types[1], name='Interface 2', type=InterfaceTypeChoices.TYPE_1GE_GBIC, mgmt_only=False, poe_mode=InterfacePoEModeChoices.MODE_PSE, poe_type=InterfacePoETypeChoices.TYPE_2_8023AT), + InterfaceTemplate(device_type=device_types[0], name='Interface 1', type=InterfaceTypeChoices.TYPE_1GE_FIXED, enabled=True, mgmt_only=True, poe_mode=InterfacePoEModeChoices.MODE_PD, poe_type=InterfacePoETypeChoices.TYPE_1_8023AF), + InterfaceTemplate(device_type=device_types[1], name='Interface 2', type=InterfaceTypeChoices.TYPE_1GE_GBIC, enabled=False, mgmt_only=False, poe_mode=InterfacePoEModeChoices.MODE_PSE, poe_type=InterfacePoETypeChoices.TYPE_2_8023AT), InterfaceTemplate(device_type=device_types[2], name='Interface 3', type=InterfaceTypeChoices.TYPE_1GE_SFP, mgmt_only=False), )) @@ -1147,6 +1147,12 @@ class InterfaceTemplateTestCase(TestCase, ChangeLoggedFilterSetTests): params = {'type': [InterfaceTypeChoices.TYPE_1GE_FIXED, InterfaceTypeChoices.TYPE_1GE_GBIC]} self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) + def test_enabled(self): + params = {'enabled': 'true'} + self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) + params = {'enabled': 'false'} + self.assertEqual(self.filterset(params, self.queryset).qs.count(), 1) + def test_mgmt_only(self): params = {'mgmt_only': 'true'} self.assertEqual(self.filterset(params, self.queryset).qs.count(), 1) diff --git a/netbox/dcim/tests/test_views.py b/netbox/dcim/tests/test_views.py index 4b39dc27e..6ea935bc8 100644 --- a/netbox/dcim/tests/test_views.py +++ b/netbox/dcim/tests/test_views.py @@ -718,6 +718,7 @@ interfaces: mgmt_only: true - name: Interface 2 type: 1000base-t + enabled: false - name: Interface 3 type: 1000base-t rear-ports: @@ -811,6 +812,10 @@ inventory-items: self.assertEqual(iface1.name, 'Interface 1') self.assertEqual(iface1.type, InterfaceTypeChoices.TYPE_1GE_FIXED) self.assertTrue(iface1.mgmt_only) + self.assertTrue(iface1.enabled) + + iface2 = InterfaceTemplate.objects.filter(name="Interface 2").first() + self.assertFalse(iface2.enabled) self.assertEqual(device_type.rearporttemplates.count(), 3) rp1 = RearPortTemplate.objects.first()