Interface.type to slug (#3569)

This commit is contained in:
Jeremy Stretch 2019-11-21 22:11:02 -05:00
parent 180d3d0029
commit 5f5081f719
13 changed files with 189 additions and 283 deletions

View File

@ -257,7 +257,7 @@ class PowerOutletTemplateSerializer(ValidatedModelSerializer):
class InterfaceTemplateSerializer(ValidatedModelSerializer): class InterfaceTemplateSerializer(ValidatedModelSerializer):
device_type = NestedDeviceTypeSerializer() device_type = NestedDeviceTypeSerializer()
type = ChoiceField(choices=IFACE_TYPE_CHOICES, required=False) type = ChoiceField(choices=InterfaceTypeChoices, required=False)
class Meta: class Meta:
model = InterfaceTemplate model = InterfaceTemplate
@ -467,7 +467,7 @@ class PowerPortSerializer(TaggitSerializer, ConnectedEndpointSerializer):
class InterfaceSerializer(TaggitSerializer, ConnectedEndpointSerializer): class InterfaceSerializer(TaggitSerializer, ConnectedEndpointSerializer):
device = NestedDeviceSerializer() device = NestedDeviceSerializer()
type = ChoiceField(choices=IFACE_TYPE_CHOICES, required=False) type = ChoiceField(choices=InterfaceTypeChoices, required=False)
lag = NestedInterfaceSerializer(required=False, allow_null=True) lag = NestedInterfaceSerializer(required=False, allow_null=True)
mode = ChoiceField(choices=IFACE_MODE_CHOICES, required=False, allow_null=True) mode = ChoiceField(choices=IFACE_MODE_CHOICES, required=False, allow_null=True)
untagged_vlan = NestedVLANSerializer(required=False, allow_null=True) untagged_vlan = NestedVLANSerializer(required=False, allow_null=True)

View File

@ -107,7 +107,7 @@ class DeviceFaceChoices(ChoiceSet):
# #
# Console port type values # ConsolePorts
# #
class ConsolePortTypeChoices(ChoiceSet): class ConsolePortTypeChoices(ChoiceSet):
@ -148,7 +148,7 @@ class ConsolePortTypeChoices(ChoiceSet):
# #
# Power port types # PowerPorts
# #
class PowerPortTypeChoices(ChoiceSet): class PowerPortTypeChoices(ChoiceSet):
@ -235,7 +235,7 @@ class PowerPortTypeChoices(ChoiceSet):
# #
# Power outlet types # PowerOutlets
# #
class PowerOutletTypeChoices(ChoiceSet): class PowerOutletTypeChoices(ChoiceSet):
@ -322,7 +322,7 @@ class PowerOutletTypeChoices(ChoiceSet):
# #
# Interface type values # Interfaces
# #
class InterfaceTypeChoices(ChoiceSet): class InterfaceTypeChoices(ChoiceSet):
@ -624,7 +624,7 @@ class InterfaceTypeChoices(ChoiceSet):
# #
# Port type values # FrontPorts/RearPorts
# #
class PortTypeChoices(ChoiceSet): class PortTypeChoices(ChoiceSet):

View File

@ -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 = [ VIRTUAL_IFACE_TYPES = [
IFACE_TYPE_VIRTUAL, InterfaceTypeChoices.TYPE_VIRTUAL,
IFACE_TYPE_LAG, InterfaceTypeChoices.TYPE_LAG,
] ]
WIRELESS_IFACE_TYPES = [ WIRELESS_IFACE_TYPES = [
IFACE_TYPE_80211A, InterfaceTypeChoices.TYPE_80211A,
IFACE_TYPE_80211G, InterfaceTypeChoices.TYPE_80211G,
IFACE_TYPE_80211N, InterfaceTypeChoices.TYPE_80211N,
IFACE_TYPE_80211AC, InterfaceTypeChoices.TYPE_80211AC,
IFACE_TYPE_80211AD, InterfaceTypeChoices.TYPE_80211AD,
] ]
NONCONNECTABLE_IFACE_TYPES = VIRTUAL_IFACE_TYPES + WIRELESS_IFACE_TYPES NONCONNECTABLE_IFACE_TYPES = VIRTUAL_IFACE_TYPES + WIRELESS_IFACE_TYPES

View File

@ -748,7 +748,7 @@ class InterfaceFilter(django_filters.FilterSet):
label='Assigned VID' label='Assigned VID'
) )
type = django_filters.MultipleChoiceFilter( type = django_filters.MultipleChoiceFilter(
choices=IFACE_TYPE_CHOICES, choices=InterfaceTypeChoices,
null_value=None null_value=None
) )

View File

@ -1076,7 +1076,7 @@ class InterfaceTemplateCreateForm(ComponentForm):
label='Name' label='Name'
) )
type = forms.ChoiceField( type = forms.ChoiceField(
choices=IFACE_TYPE_CHOICES, choices=InterfaceTypeChoices,
widget=StaticSelect2() widget=StaticSelect2()
) )
mgmt_only = forms.BooleanField( mgmt_only = forms.BooleanField(
@ -1091,7 +1091,7 @@ class InterfaceTemplateBulkEditForm(BootstrapMixin, BulkEditForm):
widget=forms.MultipleHiddenInput() widget=forms.MultipleHiddenInput()
) )
type = forms.ChoiceField( type = forms.ChoiceField(
choices=add_blank_choice(IFACE_TYPE_CHOICES), choices=add_blank_choice(InterfaceTypeChoices),
required=False, required=False,
widget=StaticSelect2() widget=StaticSelect2()
) )
@ -1311,11 +1311,6 @@ class InterfaceTemplateImportForm(ComponentTemplateImportForm):
'device_type', 'name', 'type', 'mgmt_only', '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): class FrontPortTemplateImportForm(ComponentTemplateImportForm):
type = forms.ChoiceField( type = forms.ChoiceField(
@ -2031,7 +2026,7 @@ class DeviceBulkAddComponentForm(BootstrapMixin, forms.Form):
class DeviceBulkAddInterfaceForm(DeviceBulkAddComponentForm): class DeviceBulkAddInterfaceForm(DeviceBulkAddComponentForm):
type = forms.ChoiceField( type = forms.ChoiceField(
choices=IFACE_TYPE_CHOICES, choices=InterfaceTypeChoices,
widget=StaticSelect2() widget=StaticSelect2()
) )
enabled = forms.BooleanField( enabled = forms.BooleanField(
@ -2377,12 +2372,14 @@ class InterfaceForm(InterfaceCommonForm, BootstrapMixin, forms.ModelForm):
if self.is_bound: if self.is_bound:
device = Device.objects.get(pk=self.data['device']) device = Device.objects.get(pk=self.data['device'])
self.fields['lag'].queryset = Interface.objects.filter( 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: else:
device = self.instance.device device = self.instance.device
self.fields['lag'].queryset = Interface.objects.filter( 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 # 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' label='Name'
) )
type = forms.ChoiceField( type = forms.ChoiceField(
choices=IFACE_TYPE_CHOICES, choices=InterfaceTypeChoices,
widget=StaticSelect2(), widget=StaticSelect2(),
) )
enabled = forms.BooleanField( 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) # Limit LAG choices to interfaces belonging to this device (or its VC master)
if self.parent is not None: if self.parent is not None:
self.fields['lag'].queryset = Interface.objects.filter( 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: else:
self.fields['lag'].queryset = Interface.objects.none() self.fields['lag'].queryset = Interface.objects.none()
@ -2532,7 +2530,7 @@ class InterfaceBulkEditForm(InterfaceCommonForm, BootstrapMixin, AddRemoveTagsFo
widget=forms.MultipleHiddenInput() widget=forms.MultipleHiddenInput()
) )
type = forms.ChoiceField( type = forms.ChoiceField(
choices=add_blank_choice(IFACE_TYPE_CHOICES), choices=add_blank_choice(InterfaceTypeChoices),
required=False, required=False,
widget=StaticSelect2() widget=StaticSelect2()
) )
@ -2602,7 +2600,7 @@ class InterfaceBulkEditForm(InterfaceCommonForm, BootstrapMixin, AddRemoveTagsFo
if device is not None: if device is not None:
self.fields['lag'].queryset = Interface.objects.filter( self.fields['lag'].queryset = Interface.objects.filter(
device__in=[device, device.get_vc_master()], device__in=[device, device.get_vc_master()],
type=IFACE_TYPE_LAG type=InterfaceTypeChoices.TYPE_LAG
) )
else: else:
self.fields['lag'].choices = [] self.fields['lag'].choices = []

View File

@ -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
),
]

View File

@ -1206,9 +1206,9 @@ class InterfaceTemplate(ComponentTemplateModel):
name = models.CharField( name = models.CharField(
max_length=64 max_length=64
) )
type = models.PositiveSmallIntegerField( type = models.CharField(
choices=IFACE_TYPE_CHOICES, max_length=50,
default=IFACE_TYPE_10GE_SFP_PLUS choices=InterfaceTypeChoices
) )
mgmt_only = models.BooleanField( mgmt_only = models.BooleanField(
default=False, default=False,
@ -2238,9 +2238,9 @@ class Interface(CableTermination, ComponentModel):
blank=True, blank=True,
verbose_name='Parent LAG' verbose_name='Parent LAG'
) )
type = models.PositiveSmallIntegerField( type = models.CharField(
choices=IFACE_TYPE_CHOICES, max_length=50,
default=IFACE_TYPE_10GE_SFP_PLUS choices=InterfaceTypeChoices
) )
enabled = models.BooleanField( enabled = models.BooleanField(
default=True default=True
@ -2323,7 +2323,7 @@ class Interface(CableTermination, ComponentModel):
raise ValidationError("An interface must belong to either a device or a virtual machine.") raise ValidationError("An interface must belong to either a device or a virtual machine.")
# VM interfaces must be virtual # 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({ raise ValidationError({
'type': "Virtual machines can only have virtual interfaces." 'type': "Virtual machines can only have virtual interfaces."
}) })
@ -2352,7 +2352,7 @@ class Interface(CableTermination, ComponentModel):
}) })
# Only a LAG can have LAG members # 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({ raise ValidationError({
'type': "Cannot change interface type; it has LAG members ({}).".format( 'type': "Cannot change interface type; it has LAG members ({}).".format(
", ".join([iface.name for iface in self.member_interfaces.all()]) ", ".join([iface.name for iface in self.member_interfaces.all()])
@ -2435,7 +2435,7 @@ class Interface(CableTermination, ComponentModel):
@property @property
def is_lag(self): def is_lag(self):
return self.type == IFACE_TYPE_LAG return self.type == InterfaceTypeChoices.TYPE_LAG
@property @property
def count_ipaddresses(self): def count_ipaddresses(self):

View File

@ -2554,7 +2554,7 @@ class InterfaceTest(APITestCase):
def test_update_interface(self): def test_update_interface(self):
lag_interface = Interface.objects.create( 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 = { data = {
@ -2842,7 +2842,7 @@ class CableTest(APITestCase):
) )
for device in [self.device1, self.device2]: for device in [self.device1, self.device2]:
for i in range(0, 10): 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( self.cable1 = Cable(
termination_a=self.device1.interfaces.get(name='eth0'), 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 device_type=device_type, device_role=device_role, name='StackSwitch9', site=site
) )
for i in range(0, 13): 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): 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): 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): 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): 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): 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): 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): 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): 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 # Create two VirtualChassis with three members each
self.vc1 = VirtualChassis.objects.create(master=self.device1, domain='test-domain-1') self.vc1 = VirtualChassis.objects.create(master=self.device1, domain='test-domain-1')

View File

@ -193,7 +193,7 @@ class DeviceTestCase(TestCase):
InterfaceTemplate( InterfaceTemplate(
device_type=self.device_type, device_type=self.device_type,
name='Interface 1', name='Interface 1',
type=IFACE_TYPE_1GE_FIXED, type=InterfaceTypeChoices.TYPE_1GE_FIXED,
mgmt_only=True mgmt_only=True
).save() ).save()
@ -257,7 +257,7 @@ class DeviceTestCase(TestCase):
Interface.objects.get( Interface.objects.get(
device=d, device=d,
name='Interface 1', name='Interface 1',
type=IFACE_TYPE_1GE_FIXED, type=InterfaceTypeChoices.TYPE_1GE_FIXED,
mgmt_only=True mgmt_only=True
) )
@ -379,7 +379,7 @@ class CableTestCase(TestCase):
""" """
A cable cannot terminate to a virtual interface 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) cable = Cable(termination_a=self.interface2, termination_b=virtual_interface)
with self.assertRaises(ValidationError): with self.assertRaises(ValidationError):
cable.clean() cable.clean()
@ -388,7 +388,7 @@ class CableTestCase(TestCase):
""" """
A cable cannot terminate to a wireless interface 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) cable = Cable(termination_a=self.interface2, termination_b=wireless_interface)
with self.assertRaises(ValidationError): with self.assertRaises(ValidationError):
cable.clean() cable.clean()

View File

@ -348,7 +348,7 @@ device-bays:
self.assertEqual(dt.interface_templates.count(), 3) self.assertEqual(dt.interface_templates.count(), 3)
iface1 = InterfaceTemplate.objects.first() iface1 = InterfaceTemplate.objects.first()
self.assertEqual(iface1.name, 'Interface 1') 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.assertTrue(iface1.mgmt_only)
self.assertEqual(dt.rearport_templates.count(), 3) 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 = Device(name='Device 2', site=site, device_type=devicetype, device_role=devicerole)
device2.save() 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() 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() 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() 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() 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() 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() iface6.save()
Cable(termination_a=iface1, termination_b=iface4, type=CABLE_TYPE_CAT6).save() Cable(termination_a=iface1, termination_b=iface4, type=CABLE_TYPE_CAT6).save()

View File

@ -3,7 +3,8 @@ from rest_framework import serializers
from taggit_serializer.serializers import TaggitSerializer, TagListSerializerField from taggit_serializer.serializers import TaggitSerializer, TagListSerializerField
from dcim.api.nested_serializers import NestedDeviceRoleSerializer, NestedPlatformSerializer, NestedSiteSerializer 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 dcim.models import Interface
from extras.api.customfields import CustomFieldModelSerializer from extras.api.customfields import CustomFieldModelSerializer
from ipam.api.nested_serializers import NestedIPAddressSerializer, NestedVLANSerializer from ipam.api.nested_serializers import NestedIPAddressSerializer, NestedVLANSerializer
@ -98,7 +99,7 @@ class VirtualMachineWithConfigContextSerializer(VirtualMachineSerializer):
class InterfaceSerializer(TaggitSerializer, ValidatedModelSerializer): class InterfaceSerializer(TaggitSerializer, ValidatedModelSerializer):
virtual_machine = NestedVirtualMachineSerializer() 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) mode = ChoiceField(choices=IFACE_MODE_CHOICES, required=False, allow_null=True)
untagged_vlan = NestedVLANSerializer(required=False, allow_null=True) untagged_vlan = NestedVLANSerializer(required=False, allow_null=True)
tagged_vlans = SerializedPKRelatedField( tagged_vlans = SerializedPKRelatedField(

View File

@ -2,7 +2,8 @@ from django import forms
from django.core.exceptions import ValidationError from django.core.exceptions import ValidationError
from taggit.forms import TagField 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.forms import INTERFACE_MODE_HELP_TEXT
from dcim.models import Device, DeviceRole, Interface, Platform, Rack, Region, Site from dcim.models import Device, DeviceRole, Interface, Platform, Rack, Region, Site
from extras.forms import AddRemoveTagsForm, CustomFieldBulkEditForm, CustomFieldForm, CustomFieldFilterForm from extras.forms import AddRemoveTagsForm, CustomFieldBulkEditForm, CustomFieldForm, CustomFieldFilterForm
@ -19,7 +20,7 @@ from .constants import *
from .models import Cluster, ClusterGroup, ClusterType, VirtualMachine from .models import Cluster, ClusterGroup, ClusterType, VirtualMachine
VIFACE_TYPE_CHOICES = ( VIFACE_TYPE_CHOICES = (
(IFACE_TYPE_VIRTUAL, 'Virtual'), (InterfaceTypeChoices.TYPE_VIRTUAL, 'Virtual'),
) )
@ -733,7 +734,7 @@ class InterfaceCreateForm(ComponentForm):
) )
type = forms.ChoiceField( type = forms.ChoiceField(
choices=VIFACE_TYPE_CHOICES, choices=VIFACE_TYPE_CHOICES,
initial=IFACE_TYPE_VIRTUAL, initial=InterfaceTypeChoices.TYPE_VIRTUAL,
widget=forms.HiddenInput() widget=forms.HiddenInput()
) )
enabled = forms.BooleanField( enabled = forms.BooleanField(
@ -918,7 +919,7 @@ class VirtualMachineBulkAddComponentForm(BootstrapMixin, forms.Form):
class VirtualMachineBulkAddInterfaceForm(VirtualMachineBulkAddComponentForm): class VirtualMachineBulkAddInterfaceForm(VirtualMachineBulkAddComponentForm):
type = forms.ChoiceField( type = forms.ChoiceField(
choices=VIFACE_TYPE_CHOICES, choices=VIFACE_TYPE_CHOICES,
initial=IFACE_TYPE_VIRTUAL, initial=InterfaceTypeChoices.TYPE_VIRTUAL,
widget=forms.HiddenInput() widget=forms.HiddenInput()
) )
enabled = forms.BooleanField( enabled = forms.BooleanField(

View File

@ -2,7 +2,8 @@ from django.urls import reverse
from netaddr import IPNetwork from netaddr import IPNetwork
from rest_framework import status 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 dcim.models import Interface
from ipam.models import IPAddress, VLAN from ipam.models import IPAddress, VLAN
from utilities.testing import APITestCase from utilities.testing import APITestCase
@ -489,17 +490,17 @@ class InterfaceTest(APITestCase):
self.interface1 = Interface.objects.create( self.interface1 = Interface.objects.create(
virtual_machine=self.virtualmachine, virtual_machine=self.virtualmachine,
name='Test Interface 1', name='Test Interface 1',
type=IFACE_TYPE_VIRTUAL type=InterfaceTypeChoices.TYPE_VIRTUAL
) )
self.interface2 = Interface.objects.create( self.interface2 = Interface.objects.create(
virtual_machine=self.virtualmachine, virtual_machine=self.virtualmachine,
name='Test Interface 2', name='Test Interface 2',
type=IFACE_TYPE_VIRTUAL type=InterfaceTypeChoices.TYPE_VIRTUAL
) )
self.interface3 = Interface.objects.create( self.interface3 = Interface.objects.create(
virtual_machine=self.virtualmachine, virtual_machine=self.virtualmachine,
name='Test Interface 3', name='Test Interface 3',
type=IFACE_TYPE_VIRTUAL type=InterfaceTypeChoices.TYPE_VIRTUAL
) )
self.vlan1 = VLAN.objects.create(name="Test VLAN 1", vid=1) self.vlan1 = VLAN.objects.create(name="Test VLAN 1", vid=1)