From 5f5081f71909ddaffc2d9ce25223a8b63a0c50ba Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Thu, 21 Nov 2019 22:11:02 -0500 Subject: [PATCH] Interface.type to slug (#3569) --- netbox/dcim/api/serializers.py | 4 +- netbox/dcim/choices.py | 10 +- netbox/dcim/constants.py | 231 +----------------- netbox/dcim/filters.py | 2 +- netbox/dcim/forms.py | 26 +- .../migrations/0082_interface_type_to_slug.py | 114 +++++++++ netbox/dcim/models.py | 18 +- netbox/dcim/tests/test_api.py | 22 +- netbox/dcim/tests/test_models.py | 8 +- netbox/dcim/tests/test_views.py | 14 +- netbox/virtualization/api/serializers.py | 5 +- netbox/virtualization/forms.py | 9 +- netbox/virtualization/tests/test_api.py | 9 +- 13 files changed, 189 insertions(+), 283 deletions(-) create mode 100644 netbox/dcim/migrations/0082_interface_type_to_slug.py diff --git a/netbox/dcim/api/serializers.py b/netbox/dcim/api/serializers.py index 11450250c..7018a8fc9 100644 --- a/netbox/dcim/api/serializers.py +++ b/netbox/dcim/api/serializers.py @@ -257,7 +257,7 @@ class PowerOutletTemplateSerializer(ValidatedModelSerializer): class InterfaceTemplateSerializer(ValidatedModelSerializer): device_type = NestedDeviceTypeSerializer() - type = ChoiceField(choices=IFACE_TYPE_CHOICES, required=False) + type = ChoiceField(choices=InterfaceTypeChoices, required=False) class Meta: model = InterfaceTemplate @@ -467,7 +467,7 @@ class PowerPortSerializer(TaggitSerializer, ConnectedEndpointSerializer): class InterfaceSerializer(TaggitSerializer, ConnectedEndpointSerializer): device = NestedDeviceSerializer() - type = ChoiceField(choices=IFACE_TYPE_CHOICES, required=False) + type = ChoiceField(choices=InterfaceTypeChoices, required=False) lag = NestedInterfaceSerializer(required=False, allow_null=True) mode = ChoiceField(choices=IFACE_MODE_CHOICES, required=False, allow_null=True) untagged_vlan = NestedVLANSerializer(required=False, allow_null=True) diff --git a/netbox/dcim/choices.py b/netbox/dcim/choices.py index 58504ab34..12df4f701 100644 --- a/netbox/dcim/choices.py +++ b/netbox/dcim/choices.py @@ -107,7 +107,7 @@ class DeviceFaceChoices(ChoiceSet): # -# Console port type values +# ConsolePorts # class ConsolePortTypeChoices(ChoiceSet): @@ -148,7 +148,7 @@ class ConsolePortTypeChoices(ChoiceSet): # -# Power port types +# PowerPorts # class PowerPortTypeChoices(ChoiceSet): @@ -235,7 +235,7 @@ class PowerPortTypeChoices(ChoiceSet): # -# Power outlet types +# PowerOutlets # class PowerOutletTypeChoices(ChoiceSet): @@ -322,7 +322,7 @@ class PowerOutletTypeChoices(ChoiceSet): # -# Interface type values +# Interfaces # class InterfaceTypeChoices(ChoiceSet): @@ -624,7 +624,7 @@ class InterfaceTypeChoices(ChoiceSet): # -# Port type values +# FrontPorts/RearPorts # class PortTypeChoices(ChoiceSet): diff --git a/netbox/dcim/constants.py b/netbox/dcim/constants.py index bbe8d7c5e..4b199cf15 100644 --- a/netbox/dcim/constants.py +++ b/netbox/dcim/constants.py @@ -1,230 +1,21 @@ +from .choices import InterfaceTypeChoices + + # -# Numeric interface types +# Interface type groups # -# Virtual -IFACE_TYPE_VIRTUAL = 0 -IFACE_TYPE_LAG = 200 -# Ethernet -IFACE_TYPE_100ME_FIXED = 800 -IFACE_TYPE_1GE_FIXED = 1000 -IFACE_TYPE_1GE_GBIC = 1050 -IFACE_TYPE_1GE_SFP = 1100 -IFACE_TYPE_2GE_FIXED = 1120 -IFACE_TYPE_5GE_FIXED = 1130 -IFACE_TYPE_10GE_FIXED = 1150 -IFACE_TYPE_10GE_CX4 = 1170 -IFACE_TYPE_10GE_SFP_PLUS = 1200 -IFACE_TYPE_10GE_XFP = 1300 -IFACE_TYPE_10GE_XENPAK = 1310 -IFACE_TYPE_10GE_X2 = 1320 -IFACE_TYPE_25GE_SFP28 = 1350 -IFACE_TYPE_40GE_QSFP_PLUS = 1400 -IFACE_TYPE_50GE_QSFP28 = 1420 -IFACE_TYPE_100GE_CFP = 1500 -IFACE_TYPE_100GE_CFP2 = 1510 -IFACE_TYPE_100GE_CFP4 = 1520 -IFACE_TYPE_100GE_CPAK = 1550 -IFACE_TYPE_100GE_QSFP28 = 1600 -IFACE_TYPE_200GE_CFP2 = 1650 -IFACE_TYPE_200GE_QSFP56 = 1700 -IFACE_TYPE_400GE_QSFP_DD = 1750 -IFACE_TYPE_400GE_OSFP = 1800 -# Wireless -IFACE_TYPE_80211A = 2600 -IFACE_TYPE_80211G = 2610 -IFACE_TYPE_80211N = 2620 -IFACE_TYPE_80211AC = 2630 -IFACE_TYPE_80211AD = 2640 -# Cellular -IFACE_TYPE_GSM = 2810 -IFACE_TYPE_CDMA = 2820 -IFACE_TYPE_LTE = 2830 -# SONET -IFACE_TYPE_SONET_OC3 = 6100 -IFACE_TYPE_SONET_OC12 = 6200 -IFACE_TYPE_SONET_OC48 = 6300 -IFACE_TYPE_SONET_OC192 = 6400 -IFACE_TYPE_SONET_OC768 = 6500 -IFACE_TYPE_SONET_OC1920 = 6600 -IFACE_TYPE_SONET_OC3840 = 6700 -# Fibrechannel -IFACE_TYPE_1GFC_SFP = 3010 -IFACE_TYPE_2GFC_SFP = 3020 -IFACE_TYPE_4GFC_SFP = 3040 -IFACE_TYPE_8GFC_SFP_PLUS = 3080 -IFACE_TYPE_16GFC_SFP_PLUS = 3160 -IFACE_TYPE_32GFC_SFP28 = 3320 -IFACE_TYPE_128GFC_QSFP28 = 3400 -# InfiniBand -IFACE_TYPE_INFINIBAND_SDR = 7010 -IFACE_TYPE_INFINIBAND_DDR = 7020 -IFACE_TYPE_INFINIBAND_QDR = 7030 -IFACE_TYPE_INFINIBAND_FDR10 = 7040 -IFACE_TYPE_INFINIBAND_FDR = 7050 -IFACE_TYPE_INFINIBAND_EDR = 7060 -IFACE_TYPE_INFINIBAND_HDR = 7070 -IFACE_TYPE_INFINIBAND_NDR = 7080 -IFACE_TYPE_INFINIBAND_XDR = 7090 -# Serial -IFACE_TYPE_T1 = 4000 -IFACE_TYPE_E1 = 4010 -IFACE_TYPE_T3 = 4040 -IFACE_TYPE_E3 = 4050 -# Stacking -IFACE_TYPE_STACKWISE = 5000 -IFACE_TYPE_STACKWISE_PLUS = 5050 -IFACE_TYPE_FLEXSTACK = 5100 -IFACE_TYPE_FLEXSTACK_PLUS = 5150 -IFACE_TYPE_JUNIPER_VCP = 5200 -IFACE_TYPE_SUMMITSTACK = 5300 -IFACE_TYPE_SUMMITSTACK128 = 5310 -IFACE_TYPE_SUMMITSTACK256 = 5320 -IFACE_TYPE_SUMMITSTACK512 = 5330 - -# Other -IFACE_TYPE_OTHER = 32767 - -IFACE_TYPE_CHOICES = [ - [ - 'Virtual interfaces', - [ - [IFACE_TYPE_VIRTUAL, 'Virtual'], - [IFACE_TYPE_LAG, 'Link Aggregation Group (LAG)'], - ], - ], - [ - 'Ethernet (fixed)', - [ - [IFACE_TYPE_100ME_FIXED, '100BASE-TX (10/100ME)'], - [IFACE_TYPE_1GE_FIXED, '1000BASE-T (1GE)'], - [IFACE_TYPE_2GE_FIXED, '2.5GBASE-T (2.5GE)'], - [IFACE_TYPE_5GE_FIXED, '5GBASE-T (5GE)'], - [IFACE_TYPE_10GE_FIXED, '10GBASE-T (10GE)'], - [IFACE_TYPE_10GE_CX4, '10GBASE-CX4 (10GE)'], - ] - ], - [ - 'Ethernet (modular)', - [ - [IFACE_TYPE_1GE_GBIC, 'GBIC (1GE)'], - [IFACE_TYPE_1GE_SFP, 'SFP (1GE)'], - [IFACE_TYPE_10GE_SFP_PLUS, 'SFP+ (10GE)'], - [IFACE_TYPE_10GE_XFP, 'XFP (10GE)'], - [IFACE_TYPE_10GE_XENPAK, 'XENPAK (10GE)'], - [IFACE_TYPE_10GE_X2, 'X2 (10GE)'], - [IFACE_TYPE_25GE_SFP28, 'SFP28 (25GE)'], - [IFACE_TYPE_40GE_QSFP_PLUS, 'QSFP+ (40GE)'], - [IFACE_TYPE_50GE_QSFP28, 'QSFP28 (50GE)'], - [IFACE_TYPE_100GE_CFP, 'CFP (100GE)'], - [IFACE_TYPE_100GE_CFP2, 'CFP2 (100GE)'], - [IFACE_TYPE_200GE_CFP2, 'CFP2 (200GE)'], - [IFACE_TYPE_100GE_CFP4, 'CFP4 (100GE)'], - [IFACE_TYPE_100GE_CPAK, 'Cisco CPAK (100GE)'], - [IFACE_TYPE_100GE_QSFP28, 'QSFP28 (100GE)'], - [IFACE_TYPE_200GE_QSFP56, 'QSFP56 (200GE)'], - [IFACE_TYPE_400GE_QSFP_DD, 'QSFP-DD (400GE)'], - [IFACE_TYPE_400GE_OSFP, 'OSFP (400GE)'], - ] - ], - [ - 'Wireless', - [ - [IFACE_TYPE_80211A, 'IEEE 802.11a'], - [IFACE_TYPE_80211G, 'IEEE 802.11b/g'], - [IFACE_TYPE_80211N, 'IEEE 802.11n'], - [IFACE_TYPE_80211AC, 'IEEE 802.11ac'], - [IFACE_TYPE_80211AD, 'IEEE 802.11ad'], - ] - ], - [ - 'Cellular', - [ - [IFACE_TYPE_GSM, 'GSM'], - [IFACE_TYPE_CDMA, 'CDMA'], - [IFACE_TYPE_LTE, 'LTE'], - ] - ], - [ - 'SONET', - [ - [IFACE_TYPE_SONET_OC3, 'OC-3/STM-1'], - [IFACE_TYPE_SONET_OC12, 'OC-12/STM-4'], - [IFACE_TYPE_SONET_OC48, 'OC-48/STM-16'], - [IFACE_TYPE_SONET_OC192, 'OC-192/STM-64'], - [IFACE_TYPE_SONET_OC768, 'OC-768/STM-256'], - [IFACE_TYPE_SONET_OC1920, 'OC-1920/STM-640'], - [IFACE_TYPE_SONET_OC3840, 'OC-3840/STM-1234'], - ] - ], - [ - 'FibreChannel', - [ - [IFACE_TYPE_1GFC_SFP, 'SFP (1GFC)'], - [IFACE_TYPE_2GFC_SFP, 'SFP (2GFC)'], - [IFACE_TYPE_4GFC_SFP, 'SFP (4GFC)'], - [IFACE_TYPE_8GFC_SFP_PLUS, 'SFP+ (8GFC)'], - [IFACE_TYPE_16GFC_SFP_PLUS, 'SFP+ (16GFC)'], - [IFACE_TYPE_32GFC_SFP28, 'SFP28 (32GFC)'], - [IFACE_TYPE_128GFC_QSFP28, 'QSFP28 (128GFC)'], - ] - ], - [ - 'InfiniBand', - [ - [IFACE_TYPE_INFINIBAND_SDR, 'SDR (2 Gbps)'], - [IFACE_TYPE_INFINIBAND_DDR, 'DDR (4 Gbps)'], - [IFACE_TYPE_INFINIBAND_QDR, 'QDR (8 Gbps)'], - [IFACE_TYPE_INFINIBAND_FDR10, 'FDR10 (10 Gbps)'], - [IFACE_TYPE_INFINIBAND_FDR, 'FDR (13.5 Gbps)'], - [IFACE_TYPE_INFINIBAND_EDR, 'EDR (25 Gbps)'], - [IFACE_TYPE_INFINIBAND_HDR, 'HDR (50 Gbps)'], - [IFACE_TYPE_INFINIBAND_NDR, 'NDR (100 Gbps)'], - [IFACE_TYPE_INFINIBAND_XDR, 'XDR (250 Gbps)'], - ] - ], - [ - 'Serial', - [ - [IFACE_TYPE_T1, 'T1 (1.544 Mbps)'], - [IFACE_TYPE_E1, 'E1 (2.048 Mbps)'], - [IFACE_TYPE_T3, 'T3 (45 Mbps)'], - [IFACE_TYPE_E3, 'E3 (34 Mbps)'], - ] - ], - [ - 'Stacking', - [ - [IFACE_TYPE_STACKWISE, 'Cisco StackWise'], - [IFACE_TYPE_STACKWISE_PLUS, 'Cisco StackWise Plus'], - [IFACE_TYPE_FLEXSTACK, 'Cisco FlexStack'], - [IFACE_TYPE_FLEXSTACK_PLUS, 'Cisco FlexStack Plus'], - [IFACE_TYPE_JUNIPER_VCP, 'Juniper VCP'], - [IFACE_TYPE_SUMMITSTACK, 'Extreme SummitStack'], - [IFACE_TYPE_SUMMITSTACK128, 'Extreme SummitStack-128'], - [IFACE_TYPE_SUMMITSTACK256, 'Extreme SummitStack-256'], - [IFACE_TYPE_SUMMITSTACK512, 'Extreme SummitStack-512'], - ] - ], - [ - 'Other', - [ - [IFACE_TYPE_OTHER, 'Other'], - ] - ], -] - VIRTUAL_IFACE_TYPES = [ - IFACE_TYPE_VIRTUAL, - IFACE_TYPE_LAG, + InterfaceTypeChoices.TYPE_VIRTUAL, + InterfaceTypeChoices.TYPE_LAG, ] WIRELESS_IFACE_TYPES = [ - IFACE_TYPE_80211A, - IFACE_TYPE_80211G, - IFACE_TYPE_80211N, - IFACE_TYPE_80211AC, - IFACE_TYPE_80211AD, + InterfaceTypeChoices.TYPE_80211A, + InterfaceTypeChoices.TYPE_80211G, + InterfaceTypeChoices.TYPE_80211N, + InterfaceTypeChoices.TYPE_80211AC, + InterfaceTypeChoices.TYPE_80211AD, ] NONCONNECTABLE_IFACE_TYPES = VIRTUAL_IFACE_TYPES + WIRELESS_IFACE_TYPES diff --git a/netbox/dcim/filters.py b/netbox/dcim/filters.py index aa5113ff1..610a05bd9 100644 --- a/netbox/dcim/filters.py +++ b/netbox/dcim/filters.py @@ -748,7 +748,7 @@ class InterfaceFilter(django_filters.FilterSet): label='Assigned VID' ) type = django_filters.MultipleChoiceFilter( - choices=IFACE_TYPE_CHOICES, + choices=InterfaceTypeChoices, null_value=None ) diff --git a/netbox/dcim/forms.py b/netbox/dcim/forms.py index 5ab66bc47..0a4444907 100644 --- a/netbox/dcim/forms.py +++ b/netbox/dcim/forms.py @@ -1076,7 +1076,7 @@ class InterfaceTemplateCreateForm(ComponentForm): label='Name' ) type = forms.ChoiceField( - choices=IFACE_TYPE_CHOICES, + choices=InterfaceTypeChoices, widget=StaticSelect2() ) mgmt_only = forms.BooleanField( @@ -1091,7 +1091,7 @@ class InterfaceTemplateBulkEditForm(BootstrapMixin, BulkEditForm): widget=forms.MultipleHiddenInput() ) type = forms.ChoiceField( - choices=add_blank_choice(IFACE_TYPE_CHOICES), + choices=add_blank_choice(InterfaceTypeChoices), required=False, widget=StaticSelect2() ) @@ -1311,11 +1311,6 @@ class InterfaceTemplateImportForm(ComponentTemplateImportForm): 'device_type', 'name', 'type', 'mgmt_only', ] - def clean_type(self): - # Convert slug value to field integer value - slug = self.cleaned_data['type'] - return InterfaceTypeChoices.slug_to_id(slug) - class FrontPortTemplateImportForm(ComponentTemplateImportForm): type = forms.ChoiceField( @@ -2031,7 +2026,7 @@ class DeviceBulkAddComponentForm(BootstrapMixin, forms.Form): class DeviceBulkAddInterfaceForm(DeviceBulkAddComponentForm): type = forms.ChoiceField( - choices=IFACE_TYPE_CHOICES, + choices=InterfaceTypeChoices, widget=StaticSelect2() ) enabled = forms.BooleanField( @@ -2377,12 +2372,14 @@ class InterfaceForm(InterfaceCommonForm, BootstrapMixin, forms.ModelForm): if self.is_bound: device = Device.objects.get(pk=self.data['device']) self.fields['lag'].queryset = Interface.objects.filter( - device__in=[device, device.get_vc_master()], type=IFACE_TYPE_LAG + device__in=[device, device.get_vc_master()], + type=InterfaceTypeChoices.TYPE_LAG ) else: device = self.instance.device self.fields['lag'].queryset = Interface.objects.filter( - device__in=[self.instance.device, self.instance.device.get_vc_master()], type=IFACE_TYPE_LAG + device__in=[self.instance.device, self.instance.device.get_vc_master()], + type=InterfaceTypeChoices.TYPE_LAG ) # Limit VLan choices to those in: global vlans, global groups, the current site's group, the current site @@ -2421,7 +2418,7 @@ class InterfaceCreateForm(InterfaceCommonForm, ComponentForm, forms.Form): label='Name' ) type = forms.ChoiceField( - choices=IFACE_TYPE_CHOICES, + choices=InterfaceTypeChoices, widget=StaticSelect2(), ) enabled = forms.BooleanField( @@ -2490,7 +2487,8 @@ class InterfaceCreateForm(InterfaceCommonForm, ComponentForm, forms.Form): # Limit LAG choices to interfaces belonging to this device (or its VC master) if self.parent is not None: self.fields['lag'].queryset = Interface.objects.filter( - device__in=[self.parent, self.parent.get_vc_master()], type=IFACE_TYPE_LAG + device__in=[self.parent, self.parent.get_vc_master()], + type=InterfaceTypeChoices.TYPE_LAG ) else: self.fields['lag'].queryset = Interface.objects.none() @@ -2532,7 +2530,7 @@ class InterfaceBulkEditForm(InterfaceCommonForm, BootstrapMixin, AddRemoveTagsFo widget=forms.MultipleHiddenInput() ) type = forms.ChoiceField( - choices=add_blank_choice(IFACE_TYPE_CHOICES), + choices=add_blank_choice(InterfaceTypeChoices), required=False, widget=StaticSelect2() ) @@ -2602,7 +2600,7 @@ class InterfaceBulkEditForm(InterfaceCommonForm, BootstrapMixin, AddRemoveTagsFo if device is not None: self.fields['lag'].queryset = Interface.objects.filter( device__in=[device, device.get_vc_master()], - type=IFACE_TYPE_LAG + type=InterfaceTypeChoices.TYPE_LAG ) else: self.fields['lag'].choices = [] diff --git a/netbox/dcim/migrations/0082_interface_type_to_slug.py b/netbox/dcim/migrations/0082_interface_type_to_slug.py new file mode 100644 index 000000000..50885d461 --- /dev/null +++ b/netbox/dcim/migrations/0082_interface_type_to_slug.py @@ -0,0 +1,114 @@ +from django.db import migrations, models + + +INTERFACE_TYPE_CHOICES = ( + (0, 'virtual'), + (200, 'lag'), + (800, '100base-tx'), + (1000, '1000base-t'), + (1050, '1000base-x-gbic'), + (1100, '1000base-x-sfp'), + (1120, '2.5gbase-t'), + (1130, '5gbase-t'), + (1150, '10gbase-t'), + (1170, '10gbase-cx4'), + (1200, '10gbase-x-sfpp'), + (1300, '10gbase-x-xfp'), + (1310, '10gbase-x-xenpak'), + (1320, '10gbase-x-x2'), + (1350, '25gbase-x-sfp28'), + (1400, '40gbase-x-qsfpp'), + (1420, '50gbase-x-sfp28'), + (1500, '100gbase-x-cfp'), + (1510, '100gbase-x-cfp2'), + (1520, '100gbase-x-cfp4'), + (1550, '100gbase-x-cpak'), + (1600, '100gbase-x-qsfp28'), + (1650, '200gbase-x-cfp2'), + (1700, '200gbase-x-qsfp56'), + (1750, '400gbase-x-qsfpdd'), + (1800, '400gbase-x-osfp'), + (2600, 'ieee802.11a'), + (2610, 'ieee802.11g'), + (2620, 'ieee802.11n'), + (2630, 'ieee802.11ac'), + (2640, 'ieee802.11ad'), + (2810, 'gsm'), + (2820, 'cdma'), + (2830, 'lte'), + (6100, 'sonet-oc3'), + (6200, 'sonet-oc12'), + (6300, 'sonet-oc48'), + (6400, 'sonet-oc192'), + (6500, 'sonet-oc768'), + (6600, 'sonet-oc1920'), + (6700, 'sonet-oc3840'), + (3010, '1gfc-sfp'), + (3020, '2gfc-sfp'), + (3040, '4gfc-sfp'), + (3080, '8gfc-sfpp'), + (3160, '16gfc-sfpp'), + (3320, '32gfc-sfp28'), + (3400, '128gfc-sfp28'), + (7010, 'inifiband-sdr'), + (7020, 'inifiband-ddr'), + (7030, 'inifiband-qdr'), + (7040, 'inifiband-fdr10'), + (7050, 'inifiband-fdr'), + (7060, 'inifiband-edr'), + (7070, 'inifiband-hdr'), + (7080, 'inifiband-ndr'), + (7090, 'inifiband-xdr'), + (4000, 't1'), + (4010, 'e1'), + (4040, 't3'), + (4050, 'e3'), + (5000, 'cisco-stackwise'), + (5050, 'cisco-stackwise-plus'), + (5100, 'cisco-flexstack'), + (5150, 'cisco-flexstack-plus'), + (5200, 'juniper-vcp'), + (5300, 'extreme-summitstack'), + (5310, 'extreme-summitstack-128'), + (5320, 'extreme-summitstack-256'), + (5330, 'extreme-summitstack-512'), +) + + +def interfacetemplate_type_to_slug(apps, schema_editor): + InterfaceTemplate = apps.get_model('dcim', 'InterfaceTemplate') + for id, slug in INTERFACE_TYPE_CHOICES: + InterfaceTemplate.objects.filter(type=id).update(type=slug) + + +def interface_type_to_slug(apps, schema_editor): + Interface = apps.get_model('dcim', 'Interface') + for id, slug in INTERFACE_TYPE_CHOICES: + Interface.objects.filter(type=id).update(type=slug) + + +class Migration(migrations.Migration): + atomic = False + + dependencies = [ + ('dcim', '0081_devicetype_subdevicerole_to_slug'), + ] + + operations = [ + migrations.AlterField( + model_name='interfacetemplate', + name='type', + field=models.CharField(max_length=50), + ), + migrations.RunPython( + code=interfacetemplate_type_to_slug + ), + migrations.AlterField( + model_name='interface', + name='type', + field=models.CharField(max_length=50), + ), + migrations.RunPython( + code=interface_type_to_slug + ), + ] diff --git a/netbox/dcim/models.py b/netbox/dcim/models.py index 4b4087d9a..4e67f61cc 100644 --- a/netbox/dcim/models.py +++ b/netbox/dcim/models.py @@ -1206,9 +1206,9 @@ class InterfaceTemplate(ComponentTemplateModel): name = models.CharField( max_length=64 ) - type = models.PositiveSmallIntegerField( - choices=IFACE_TYPE_CHOICES, - default=IFACE_TYPE_10GE_SFP_PLUS + type = models.CharField( + max_length=50, + choices=InterfaceTypeChoices ) mgmt_only = models.BooleanField( default=False, @@ -2238,9 +2238,9 @@ class Interface(CableTermination, ComponentModel): blank=True, verbose_name='Parent LAG' ) - type = models.PositiveSmallIntegerField( - choices=IFACE_TYPE_CHOICES, - default=IFACE_TYPE_10GE_SFP_PLUS + type = models.CharField( + max_length=50, + choices=InterfaceTypeChoices ) enabled = models.BooleanField( default=True @@ -2323,7 +2323,7 @@ class Interface(CableTermination, ComponentModel): raise ValidationError("An interface must belong to either a device or a virtual machine.") # VM interfaces must be virtual - if self.virtual_machine and self.type is not IFACE_TYPE_VIRTUAL: + if self.virtual_machine and self.type is not InterfaceTypeChoices.TYPE_VIRTUAL: raise ValidationError({ 'type': "Virtual machines can only have virtual interfaces." }) @@ -2352,7 +2352,7 @@ class Interface(CableTermination, ComponentModel): }) # Only a LAG can have LAG members - if self.type != IFACE_TYPE_LAG and self.member_interfaces.exists(): + if self.type != InterfaceTypeChoices.TYPE_LAG and self.member_interfaces.exists(): raise ValidationError({ 'type': "Cannot change interface type; it has LAG members ({}).".format( ", ".join([iface.name for iface in self.member_interfaces.all()]) @@ -2435,7 +2435,7 @@ class Interface(CableTermination, ComponentModel): @property def is_lag(self): - return self.type == IFACE_TYPE_LAG + return self.type == InterfaceTypeChoices.TYPE_LAG @property def count_ipaddresses(self): diff --git a/netbox/dcim/tests/test_api.py b/netbox/dcim/tests/test_api.py index 2963f7329..730639704 100644 --- a/netbox/dcim/tests/test_api.py +++ b/netbox/dcim/tests/test_api.py @@ -2554,7 +2554,7 @@ class InterfaceTest(APITestCase): def test_update_interface(self): lag_interface = Interface.objects.create( - device=self.device, name='Test LAG Interface', type=IFACE_TYPE_LAG + device=self.device, name='Test LAG Interface', type=InterfaceTypeChoices.TYPE_LAG ) data = { @@ -2842,7 +2842,7 @@ class CableTest(APITestCase): ) for device in [self.device1, self.device2]: for i in range(0, 10): - Interface(device=device, type=IFACE_TYPE_1GE_FIXED, name='eth{}'.format(i)).save() + Interface(device=device, type=InterfaceTypeChoices.TYPE_1GE_FIXED, name='eth{}'.format(i)).save() self.cable1 = Cable( termination_a=self.device1.interfaces.get(name='eth0'), @@ -3411,23 +3411,23 @@ class VirtualChassisTest(APITestCase): device_type=device_type, device_role=device_role, name='StackSwitch9', site=site ) for i in range(0, 13): - Interface.objects.create(device=self.device1, name='1/{}'.format(i), type=IFACE_TYPE_1GE_FIXED) + Interface.objects.create(device=self.device1, name='1/{}'.format(i), type=InterfaceTypeChoices.TYPE_1GE_FIXED) for i in range(0, 13): - Interface.objects.create(device=self.device2, name='2/{}'.format(i), type=IFACE_TYPE_1GE_FIXED) + Interface.objects.create(device=self.device2, name='2/{}'.format(i), type=InterfaceTypeChoices.TYPE_1GE_FIXED) for i in range(0, 13): - Interface.objects.create(device=self.device3, name='3/{}'.format(i), type=IFACE_TYPE_1GE_FIXED) + Interface.objects.create(device=self.device3, name='3/{}'.format(i), type=InterfaceTypeChoices.TYPE_1GE_FIXED) for i in range(0, 13): - Interface.objects.create(device=self.device4, name='1/{}'.format(i), type=IFACE_TYPE_1GE_FIXED) + Interface.objects.create(device=self.device4, name='1/{}'.format(i), type=InterfaceTypeChoices.TYPE_1GE_FIXED) for i in range(0, 13): - Interface.objects.create(device=self.device5, name='2/{}'.format(i), type=IFACE_TYPE_1GE_FIXED) + Interface.objects.create(device=self.device5, name='2/{}'.format(i), type=InterfaceTypeChoices.TYPE_1GE_FIXED) for i in range(0, 13): - Interface.objects.create(device=self.device6, name='3/{}'.format(i), type=IFACE_TYPE_1GE_FIXED) + Interface.objects.create(device=self.device6, name='3/{}'.format(i), type=InterfaceTypeChoices.TYPE_1GE_FIXED) for i in range(0, 13): - Interface.objects.create(device=self.device7, name='1/{}'.format(i), type=IFACE_TYPE_1GE_FIXED) + Interface.objects.create(device=self.device7, name='1/{}'.format(i), type=InterfaceTypeChoices.TYPE_1GE_FIXED) for i in range(0, 13): - Interface.objects.create(device=self.device8, name='2/{}'.format(i), type=IFACE_TYPE_1GE_FIXED) + Interface.objects.create(device=self.device8, name='2/{}'.format(i), type=InterfaceTypeChoices.TYPE_1GE_FIXED) for i in range(0, 13): - Interface.objects.create(device=self.device9, name='3/{}'.format(i), type=IFACE_TYPE_1GE_FIXED) + Interface.objects.create(device=self.device9, name='3/{}'.format(i), type=InterfaceTypeChoices.TYPE_1GE_FIXED) # Create two VirtualChassis with three members each self.vc1 = VirtualChassis.objects.create(master=self.device1, domain='test-domain-1') diff --git a/netbox/dcim/tests/test_models.py b/netbox/dcim/tests/test_models.py index 5d1099029..fae6a589d 100644 --- a/netbox/dcim/tests/test_models.py +++ b/netbox/dcim/tests/test_models.py @@ -193,7 +193,7 @@ class DeviceTestCase(TestCase): InterfaceTemplate( device_type=self.device_type, name='Interface 1', - type=IFACE_TYPE_1GE_FIXED, + type=InterfaceTypeChoices.TYPE_1GE_FIXED, mgmt_only=True ).save() @@ -257,7 +257,7 @@ class DeviceTestCase(TestCase): Interface.objects.get( device=d, name='Interface 1', - type=IFACE_TYPE_1GE_FIXED, + type=InterfaceTypeChoices.TYPE_1GE_FIXED, mgmt_only=True ) @@ -379,7 +379,7 @@ class CableTestCase(TestCase): """ A cable cannot terminate to a virtual interface """ - virtual_interface = Interface(device=self.device1, name="V1", type=IFACE_TYPE_VIRTUAL) + virtual_interface = Interface(device=self.device1, name="V1", type=InterfaceTypeChoices.TYPE_VIRTUAL) cable = Cable(termination_a=self.interface2, termination_b=virtual_interface) with self.assertRaises(ValidationError): cable.clean() @@ -388,7 +388,7 @@ class CableTestCase(TestCase): """ A cable cannot terminate to a wireless interface """ - wireless_interface = Interface(device=self.device1, name="W1", type=IFACE_TYPE_80211A) + wireless_interface = Interface(device=self.device1, name="W1", type=InterfaceTypeChoices.TYPE_80211A) cable = Cable(termination_a=self.interface2, termination_b=wireless_interface) with self.assertRaises(ValidationError): cable.clean() diff --git a/netbox/dcim/tests/test_views.py b/netbox/dcim/tests/test_views.py index c556a6831..6bda7c6c5 100644 --- a/netbox/dcim/tests/test_views.py +++ b/netbox/dcim/tests/test_views.py @@ -348,7 +348,7 @@ device-bays: self.assertEqual(dt.interface_templates.count(), 3) iface1 = InterfaceTemplate.objects.first() self.assertEqual(iface1.name, 'Interface 1') - self.assertEqual(iface1.type, IFACE_TYPE_1GE_FIXED) + self.assertEqual(iface1.type, InterfaceTypeChoices.TYPE_1GE_FIXED) self.assertTrue(iface1.mgmt_only) self.assertEqual(dt.rearport_templates.count(), 3) @@ -514,17 +514,17 @@ class CableTestCase(TestCase): device2 = Device(name='Device 2', site=site, device_type=devicetype, device_role=devicerole) device2.save() - iface1 = Interface(device=device1, name='Interface 1', type=IFACE_TYPE_1GE_FIXED) + iface1 = Interface(device=device1, name='Interface 1', type=InterfaceTypeChoices.TYPE_1GE_FIXED) iface1.save() - iface2 = Interface(device=device1, name='Interface 2', type=IFACE_TYPE_1GE_FIXED) + iface2 = Interface(device=device1, name='Interface 2', type=InterfaceTypeChoices.TYPE_1GE_FIXED) iface2.save() - iface3 = Interface(device=device1, name='Interface 3', type=IFACE_TYPE_1GE_FIXED) + iface3 = Interface(device=device1, name='Interface 3', type=InterfaceTypeChoices.TYPE_1GE_FIXED) iface3.save() - iface4 = Interface(device=device2, name='Interface 1', type=IFACE_TYPE_1GE_FIXED) + iface4 = Interface(device=device2, name='Interface 1', type=InterfaceTypeChoices.TYPE_1GE_FIXED) iface4.save() - iface5 = Interface(device=device2, name='Interface 2', type=IFACE_TYPE_1GE_FIXED) + iface5 = Interface(device=device2, name='Interface 2', type=InterfaceTypeChoices.TYPE_1GE_FIXED) iface5.save() - iface6 = Interface(device=device2, name='Interface 3', type=IFACE_TYPE_1GE_FIXED) + iface6 = Interface(device=device2, name='Interface 3', type=InterfaceTypeChoices.TYPE_1GE_FIXED) iface6.save() Cable(termination_a=iface1, termination_b=iface4, type=CABLE_TYPE_CAT6).save() diff --git a/netbox/virtualization/api/serializers.py b/netbox/virtualization/api/serializers.py index 75f36fbb6..4b519e5e2 100644 --- a/netbox/virtualization/api/serializers.py +++ b/netbox/virtualization/api/serializers.py @@ -3,7 +3,8 @@ from rest_framework import serializers from taggit_serializer.serializers import TaggitSerializer, TagListSerializerField from dcim.api.nested_serializers import NestedDeviceRoleSerializer, NestedPlatformSerializer, NestedSiteSerializer -from dcim.constants import IFACE_TYPE_CHOICES, IFACE_TYPE_VIRTUAL, IFACE_MODE_CHOICES +from dcim.choices import InterfaceTypeChoices +from dcim.constants import IFACE_MODE_CHOICES from dcim.models import Interface from extras.api.customfields import CustomFieldModelSerializer from ipam.api.nested_serializers import NestedIPAddressSerializer, NestedVLANSerializer @@ -98,7 +99,7 @@ class VirtualMachineWithConfigContextSerializer(VirtualMachineSerializer): class InterfaceSerializer(TaggitSerializer, ValidatedModelSerializer): virtual_machine = NestedVirtualMachineSerializer() - type = ChoiceField(choices=IFACE_TYPE_CHOICES, default=IFACE_TYPE_VIRTUAL, required=False) + type = ChoiceField(choices=InterfaceTypeChoices, default=InterfaceTypeChoices.TYPE_VIRTUAL, required=False) mode = ChoiceField(choices=IFACE_MODE_CHOICES, required=False, allow_null=True) untagged_vlan = NestedVLANSerializer(required=False, allow_null=True) tagged_vlans = SerializedPKRelatedField( diff --git a/netbox/virtualization/forms.py b/netbox/virtualization/forms.py index 8094b0fbe..09848e0c7 100644 --- a/netbox/virtualization/forms.py +++ b/netbox/virtualization/forms.py @@ -2,7 +2,8 @@ from django import forms from django.core.exceptions import ValidationError from taggit.forms import TagField -from dcim.constants import IFACE_TYPE_VIRTUAL, IFACE_MODE_ACCESS, IFACE_MODE_TAGGED_ALL, IFACE_MODE_CHOICES +from dcim.choices import InterfaceTypeChoices +from dcim.constants import IFACE_MODE_ACCESS, IFACE_MODE_TAGGED_ALL, IFACE_MODE_CHOICES from dcim.forms import INTERFACE_MODE_HELP_TEXT from dcim.models import Device, DeviceRole, Interface, Platform, Rack, Region, Site from extras.forms import AddRemoveTagsForm, CustomFieldBulkEditForm, CustomFieldForm, CustomFieldFilterForm @@ -19,7 +20,7 @@ from .constants import * from .models import Cluster, ClusterGroup, ClusterType, VirtualMachine VIFACE_TYPE_CHOICES = ( - (IFACE_TYPE_VIRTUAL, 'Virtual'), + (InterfaceTypeChoices.TYPE_VIRTUAL, 'Virtual'), ) @@ -733,7 +734,7 @@ class InterfaceCreateForm(ComponentForm): ) type = forms.ChoiceField( choices=VIFACE_TYPE_CHOICES, - initial=IFACE_TYPE_VIRTUAL, + initial=InterfaceTypeChoices.TYPE_VIRTUAL, widget=forms.HiddenInput() ) enabled = forms.BooleanField( @@ -918,7 +919,7 @@ class VirtualMachineBulkAddComponentForm(BootstrapMixin, forms.Form): class VirtualMachineBulkAddInterfaceForm(VirtualMachineBulkAddComponentForm): type = forms.ChoiceField( choices=VIFACE_TYPE_CHOICES, - initial=IFACE_TYPE_VIRTUAL, + initial=InterfaceTypeChoices.TYPE_VIRTUAL, widget=forms.HiddenInput() ) enabled = forms.BooleanField( diff --git a/netbox/virtualization/tests/test_api.py b/netbox/virtualization/tests/test_api.py index f1e372dd4..64d9cf8b9 100644 --- a/netbox/virtualization/tests/test_api.py +++ b/netbox/virtualization/tests/test_api.py @@ -2,7 +2,8 @@ from django.urls import reverse from netaddr import IPNetwork from rest_framework import status -from dcim.constants import IFACE_TYPE_VIRTUAL, IFACE_MODE_TAGGED +from dcim.choices import InterfaceTypeChoices +from dcim.constants import IFACE_MODE_TAGGED from dcim.models import Interface from ipam.models import IPAddress, VLAN from utilities.testing import APITestCase @@ -489,17 +490,17 @@ class InterfaceTest(APITestCase): self.interface1 = Interface.objects.create( virtual_machine=self.virtualmachine, name='Test Interface 1', - type=IFACE_TYPE_VIRTUAL + type=InterfaceTypeChoices.TYPE_VIRTUAL ) self.interface2 = Interface.objects.create( virtual_machine=self.virtualmachine, name='Test Interface 2', - type=IFACE_TYPE_VIRTUAL + type=InterfaceTypeChoices.TYPE_VIRTUAL ) self.interface3 = Interface.objects.create( virtual_machine=self.virtualmachine, name='Test Interface 3', - type=IFACE_TYPE_VIRTUAL + type=InterfaceTypeChoices.TYPE_VIRTUAL ) self.vlan1 = VLAN.objects.create(name="Test VLAN 1", vid=1)