mirror of
https://github.com/netbox-community/netbox.git
synced 2025-07-21 03:27:21 -06:00
Merge pull request #3067 from digitalocean/2920-interface-type
Rename Interface.form_factor to Interface.type
This commit is contained in:
commit
b1c160f9d4
@ -56,8 +56,14 @@ to now use "Extras | Tag."
|
|||||||
* [#2324](https://github.com/digitalocean/netbox/issues/2324) - Add `color` option for tags
|
* [#2324](https://github.com/digitalocean/netbox/issues/2324) - Add `color` option for tags
|
||||||
* [#2643](https://github.com/digitalocean/netbox/issues/2643) - Add `description` field to console/power components and device bays
|
* [#2643](https://github.com/digitalocean/netbox/issues/2643) - Add `description` field to console/power components and device bays
|
||||||
* [#2791](https://github.com/digitalocean/netbox/issues/2791) - Add a `comment` field for tags
|
* [#2791](https://github.com/digitalocean/netbox/issues/2791) - Add a `comment` field for tags
|
||||||
|
* [#2920](https://github.com/digitalocean/netbox/issues/2920) - Rename Interface `form_factor` to `type`
|
||||||
* [#2926](https://github.com/digitalocean/netbox/issues/2926) - Add changelog to the Tag model
|
* [#2926](https://github.com/digitalocean/netbox/issues/2926) - Add changelog to the Tag model
|
||||||
|
|
||||||
|
## API Changes
|
||||||
|
|
||||||
|
* dcim.Interface: `form_factor` has been renamed to `type`. Backward-compatibile support for `form_factor` will be maintained until NetBox v2.7.
|
||||||
|
* dcim.Interface: The `type` filter has been renamed to `kind`.
|
||||||
|
|
||||||
## Bug Fixes
|
## Bug Fixes
|
||||||
|
|
||||||
* [#2968](https://github.com/digitalocean/netbox/issues/2968) - Correct API documentation for SerializerMethodFields
|
* [#2968](https://github.com/digitalocean/netbox/issues/2968) - Correct API documentation for SerializerMethodFields
|
||||||
|
@ -81,7 +81,7 @@ Power ports connect only to power outlets. Power connections can be marked as ei
|
|||||||
|
|
||||||
Interfaces connect to one another in a symmetric manner: If interface A connects to interface B, interface B therefore connects to interface A. Each type of connection can be classified as either *planned* or *connected*.
|
Interfaces connect to one another in a symmetric manner: If interface A connects to interface B, interface B therefore connects to interface A. Each type of connection can be classified as either *planned* or *connected*.
|
||||||
|
|
||||||
Each interface is a assigned a form factor denoting its physical properties. Two special form factors exist: the "virtual" form factor can be used to designate logical interfaces (such as SVIs), and the "LAG" form factor can be used to desinate link aggregation groups to which physical interfaces can be assigned.
|
Each interface is a assigned a type denoting its physical properties. Two special types exist: the "virtual" type can be used to designate logical interfaces (such as SVIs), and the "LAG" type can be used to desinate link aggregation groups to which physical interfaces can be assigned.
|
||||||
|
|
||||||
Each interface can also be enabled or disabled, and optionally designated as management-only (for out-of-band management). Fields are also provided to store an interface's MTU and MAC address.
|
Each interface can also be enabled or disabled, and optionally designated as management-only (for out-of-band management). Fields are also provided to store an interface's MTU and MAC address.
|
||||||
|
|
||||||
|
@ -231,11 +231,13 @@ class PowerOutletTemplateSerializer(ValidatedModelSerializer):
|
|||||||
|
|
||||||
class InterfaceTemplateSerializer(ValidatedModelSerializer):
|
class InterfaceTemplateSerializer(ValidatedModelSerializer):
|
||||||
device_type = NestedDeviceTypeSerializer()
|
device_type = NestedDeviceTypeSerializer()
|
||||||
form_factor = ChoiceField(choices=IFACE_FF_CHOICES, required=False)
|
type = ChoiceField(choices=IFACE_TYPE_CHOICES, required=False)
|
||||||
|
# TODO: Remove in v2.7 (backward-compatibility for form_factor)
|
||||||
|
form_factor = ChoiceField(choices=IFACE_TYPE_CHOICES, required=False)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = InterfaceTemplate
|
model = InterfaceTemplate
|
||||||
fields = ['id', 'device_type', 'name', 'form_factor', 'mgmt_only']
|
fields = ['id', 'device_type', 'name', 'type', 'form_factor', 'mgmt_only']
|
||||||
|
|
||||||
|
|
||||||
class RearPortTemplateSerializer(ValidatedModelSerializer):
|
class RearPortTemplateSerializer(ValidatedModelSerializer):
|
||||||
@ -418,7 +420,9 @@ class PowerPortSerializer(TaggitSerializer, ConnectedEndpointSerializer):
|
|||||||
|
|
||||||
class InterfaceSerializer(TaggitSerializer, ConnectedEndpointSerializer):
|
class InterfaceSerializer(TaggitSerializer, ConnectedEndpointSerializer):
|
||||||
device = NestedDeviceSerializer()
|
device = NestedDeviceSerializer()
|
||||||
form_factor = ChoiceField(choices=IFACE_FF_CHOICES, required=False)
|
type = ChoiceField(choices=IFACE_TYPE_CHOICES, required=False)
|
||||||
|
# TODO: Remove in v2.7 (backward-compatibility for form_factor)
|
||||||
|
form_factor = ChoiceField(choices=IFACE_TYPE_CHOICES, 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)
|
||||||
@ -434,9 +438,9 @@ class InterfaceSerializer(TaggitSerializer, ConnectedEndpointSerializer):
|
|||||||
class Meta:
|
class Meta:
|
||||||
model = Interface
|
model = Interface
|
||||||
fields = [
|
fields = [
|
||||||
'id', 'device', 'name', 'form_factor', 'enabled', 'lag', 'mtu', 'mac_address', 'mgmt_only', 'description',
|
'id', 'device', 'name', 'type', 'form_factor', 'enabled', 'lag', 'mtu', 'mac_address', 'mgmt_only',
|
||||||
'connected_endpoint_type', 'connected_endpoint', 'connection_status', 'cable', 'mode', 'untagged_vlan',
|
'description', 'connected_endpoint_type', 'connected_endpoint', 'connection_status', 'cable', 'mode',
|
||||||
'tagged_vlans', 'tags', 'count_ipaddresses',
|
'untagged_vlan', 'tagged_vlans', 'tags', 'count_ipaddresses',
|
||||||
]
|
]
|
||||||
|
|
||||||
# TODO: This validation should be handled by Interface.clean()
|
# TODO: This validation should be handled by Interface.clean()
|
||||||
|
@ -42,8 +42,8 @@ class DCIMFieldChoicesViewSet(FieldChoicesViewSet):
|
|||||||
(DeviceType, ['subdevice_role']),
|
(DeviceType, ['subdevice_role']),
|
||||||
(FrontPort, ['type']),
|
(FrontPort, ['type']),
|
||||||
(FrontPortTemplate, ['type']),
|
(FrontPortTemplate, ['type']),
|
||||||
(Interface, ['form_factor', 'mode']),
|
(Interface, ['type', 'mode']),
|
||||||
(InterfaceTemplate, ['form_factor']),
|
(InterfaceTemplate, ['type']),
|
||||||
(PowerOutlet, ['feed_leg']),
|
(PowerOutlet, ['feed_leg']),
|
||||||
(PowerOutletTemplate, ['feed_leg']),
|
(PowerOutletTemplate, ['feed_leg']),
|
||||||
(PowerPort, ['connection_status']),
|
(PowerPort, ['connection_status']),
|
||||||
|
@ -66,200 +66,200 @@ IFACE_ORDERING_CHOICES = [
|
|||||||
[IFACE_ORDERING_NAME, 'Name (alphabetically)']
|
[IFACE_ORDERING_NAME, 'Name (alphabetically)']
|
||||||
]
|
]
|
||||||
|
|
||||||
# Interface form factors
|
# Interface types
|
||||||
# Virtual
|
# Virtual
|
||||||
IFACE_FF_VIRTUAL = 0
|
IFACE_TYPE_VIRTUAL = 0
|
||||||
IFACE_FF_LAG = 200
|
IFACE_TYPE_LAG = 200
|
||||||
# Ethernet
|
# Ethernet
|
||||||
IFACE_FF_100ME_FIXED = 800
|
IFACE_TYPE_100ME_FIXED = 800
|
||||||
IFACE_FF_1GE_FIXED = 1000
|
IFACE_TYPE_1GE_FIXED = 1000
|
||||||
IFACE_FF_1GE_GBIC = 1050
|
IFACE_TYPE_1GE_GBIC = 1050
|
||||||
IFACE_FF_1GE_SFP = 1100
|
IFACE_TYPE_1GE_SFP = 1100
|
||||||
IFACE_FF_10GE_FIXED = 1150
|
IFACE_TYPE_10GE_FIXED = 1150
|
||||||
IFACE_FF_10GE_CX4 = 1170
|
IFACE_TYPE_10GE_CX4 = 1170
|
||||||
IFACE_FF_10GE_SFP_PLUS = 1200
|
IFACE_TYPE_10GE_SFP_PLUS = 1200
|
||||||
IFACE_FF_10GE_XFP = 1300
|
IFACE_TYPE_10GE_XFP = 1300
|
||||||
IFACE_FF_10GE_XENPAK = 1310
|
IFACE_TYPE_10GE_XENPAK = 1310
|
||||||
IFACE_FF_10GE_X2 = 1320
|
IFACE_TYPE_10GE_X2 = 1320
|
||||||
IFACE_FF_25GE_SFP28 = 1350
|
IFACE_TYPE_25GE_SFP28 = 1350
|
||||||
IFACE_FF_40GE_QSFP_PLUS = 1400
|
IFACE_TYPE_40GE_QSFP_PLUS = 1400
|
||||||
IFACE_FF_50GE_QSFP28 = 1420
|
IFACE_TYPE_50GE_QSFP28 = 1420
|
||||||
IFACE_FF_100GE_CFP = 1500
|
IFACE_TYPE_100GE_CFP = 1500
|
||||||
IFACE_FF_100GE_CFP2 = 1510
|
IFACE_TYPE_100GE_CFP2 = 1510
|
||||||
IFACE_FF_100GE_CFP4 = 1520
|
IFACE_TYPE_100GE_CFP4 = 1520
|
||||||
IFACE_FF_100GE_CPAK = 1550
|
IFACE_TYPE_100GE_CPAK = 1550
|
||||||
IFACE_FF_100GE_QSFP28 = 1600
|
IFACE_TYPE_100GE_QSFP28 = 1600
|
||||||
IFACE_FF_200GE_CFP2 = 1650
|
IFACE_TYPE_200GE_CFP2 = 1650
|
||||||
IFACE_FF_200GE_QSFP56 = 1700
|
IFACE_TYPE_200GE_QSFP56 = 1700
|
||||||
IFACE_FF_400GE_QSFP_DD = 1750
|
IFACE_TYPE_400GE_QSFP_DD = 1750
|
||||||
# Wireless
|
# Wireless
|
||||||
IFACE_FF_80211A = 2600
|
IFACE_TYPE_80211A = 2600
|
||||||
IFACE_FF_80211G = 2610
|
IFACE_TYPE_80211G = 2610
|
||||||
IFACE_FF_80211N = 2620
|
IFACE_TYPE_80211N = 2620
|
||||||
IFACE_FF_80211AC = 2630
|
IFACE_TYPE_80211AC = 2630
|
||||||
IFACE_FF_80211AD = 2640
|
IFACE_TYPE_80211AD = 2640
|
||||||
# Cellular
|
# Cellular
|
||||||
IFACE_FF_GSM = 2810
|
IFACE_TYPE_GSM = 2810
|
||||||
IFACE_FF_CDMA = 2820
|
IFACE_TYPE_CDMA = 2820
|
||||||
IFACE_FF_LTE = 2830
|
IFACE_TYPE_LTE = 2830
|
||||||
# SONET
|
# SONET
|
||||||
IFACE_FF_SONET_OC3 = 6100
|
IFACE_TYPE_SONET_OC3 = 6100
|
||||||
IFACE_FF_SONET_OC12 = 6200
|
IFACE_TYPE_SONET_OC12 = 6200
|
||||||
IFACE_FF_SONET_OC48 = 6300
|
IFACE_TYPE_SONET_OC48 = 6300
|
||||||
IFACE_FF_SONET_OC192 = 6400
|
IFACE_TYPE_SONET_OC192 = 6400
|
||||||
IFACE_FF_SONET_OC768 = 6500
|
IFACE_TYPE_SONET_OC768 = 6500
|
||||||
IFACE_FF_SONET_OC1920 = 6600
|
IFACE_TYPE_SONET_OC1920 = 6600
|
||||||
IFACE_FF_SONET_OC3840 = 6700
|
IFACE_TYPE_SONET_OC3840 = 6700
|
||||||
# Fibrechannel
|
# Fibrechannel
|
||||||
IFACE_FF_1GFC_SFP = 3010
|
IFACE_TYPE_1GFC_SFP = 3010
|
||||||
IFACE_FF_2GFC_SFP = 3020
|
IFACE_TYPE_2GFC_SFP = 3020
|
||||||
IFACE_FF_4GFC_SFP = 3040
|
IFACE_TYPE_4GFC_SFP = 3040
|
||||||
IFACE_FF_8GFC_SFP_PLUS = 3080
|
IFACE_TYPE_8GFC_SFP_PLUS = 3080
|
||||||
IFACE_FF_16GFC_SFP_PLUS = 3160
|
IFACE_TYPE_16GFC_SFP_PLUS = 3160
|
||||||
IFACE_FF_32GFC_SFP28 = 3320
|
IFACE_TYPE_32GFC_SFP28 = 3320
|
||||||
IFACE_FF_128GFC_QSFP28 = 3400
|
IFACE_TYPE_128GFC_QSFP28 = 3400
|
||||||
# Serial
|
# Serial
|
||||||
IFACE_FF_T1 = 4000
|
IFACE_TYPE_T1 = 4000
|
||||||
IFACE_FF_E1 = 4010
|
IFACE_TYPE_E1 = 4010
|
||||||
IFACE_FF_T3 = 4040
|
IFACE_TYPE_T3 = 4040
|
||||||
IFACE_FF_E3 = 4050
|
IFACE_TYPE_E3 = 4050
|
||||||
# Stacking
|
# Stacking
|
||||||
IFACE_FF_STACKWISE = 5000
|
IFACE_TYPE_STACKWISE = 5000
|
||||||
IFACE_FF_STACKWISE_PLUS = 5050
|
IFACE_TYPE_STACKWISE_PLUS = 5050
|
||||||
IFACE_FF_FLEXSTACK = 5100
|
IFACE_TYPE_FLEXSTACK = 5100
|
||||||
IFACE_FF_FLEXSTACK_PLUS = 5150
|
IFACE_TYPE_FLEXSTACK_PLUS = 5150
|
||||||
IFACE_FF_JUNIPER_VCP = 5200
|
IFACE_TYPE_JUNIPER_VCP = 5200
|
||||||
IFACE_FF_SUMMITSTACK = 5300
|
IFACE_TYPE_SUMMITSTACK = 5300
|
||||||
IFACE_FF_SUMMITSTACK128 = 5310
|
IFACE_TYPE_SUMMITSTACK128 = 5310
|
||||||
IFACE_FF_SUMMITSTACK256 = 5320
|
IFACE_TYPE_SUMMITSTACK256 = 5320
|
||||||
IFACE_FF_SUMMITSTACK512 = 5330
|
IFACE_TYPE_SUMMITSTACK512 = 5330
|
||||||
|
|
||||||
# Other
|
# Other
|
||||||
IFACE_FF_OTHER = 32767
|
IFACE_TYPE_OTHER = 32767
|
||||||
|
|
||||||
IFACE_FF_CHOICES = [
|
IFACE_TYPE_CHOICES = [
|
||||||
[
|
[
|
||||||
'Virtual interfaces',
|
'Virtual interfaces',
|
||||||
[
|
[
|
||||||
[IFACE_FF_VIRTUAL, 'Virtual'],
|
[IFACE_TYPE_VIRTUAL, 'Virtual'],
|
||||||
[IFACE_FF_LAG, 'Link Aggregation Group (LAG)'],
|
[IFACE_TYPE_LAG, 'Link Aggregation Group (LAG)'],
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
'Ethernet (fixed)',
|
'Ethernet (fixed)',
|
||||||
[
|
[
|
||||||
[IFACE_FF_100ME_FIXED, '100BASE-TX (10/100ME)'],
|
[IFACE_TYPE_100ME_FIXED, '100BASE-TX (10/100ME)'],
|
||||||
[IFACE_FF_1GE_FIXED, '1000BASE-T (1GE)'],
|
[IFACE_TYPE_1GE_FIXED, '1000BASE-T (1GE)'],
|
||||||
[IFACE_FF_10GE_FIXED, '10GBASE-T (10GE)'],
|
[IFACE_TYPE_10GE_FIXED, '10GBASE-T (10GE)'],
|
||||||
[IFACE_FF_10GE_CX4, '10GBASE-CX4 (10GE)'],
|
[IFACE_TYPE_10GE_CX4, '10GBASE-CX4 (10GE)'],
|
||||||
]
|
]
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
'Ethernet (modular)',
|
'Ethernet (modular)',
|
||||||
[
|
[
|
||||||
[IFACE_FF_1GE_GBIC, 'GBIC (1GE)'],
|
[IFACE_TYPE_1GE_GBIC, 'GBIC (1GE)'],
|
||||||
[IFACE_FF_1GE_SFP, 'SFP (1GE)'],
|
[IFACE_TYPE_1GE_SFP, 'SFP (1GE)'],
|
||||||
[IFACE_FF_10GE_SFP_PLUS, 'SFP+ (10GE)'],
|
[IFACE_TYPE_10GE_SFP_PLUS, 'SFP+ (10GE)'],
|
||||||
[IFACE_FF_10GE_XFP, 'XFP (10GE)'],
|
[IFACE_TYPE_10GE_XFP, 'XFP (10GE)'],
|
||||||
[IFACE_FF_10GE_XENPAK, 'XENPAK (10GE)'],
|
[IFACE_TYPE_10GE_XENPAK, 'XENPAK (10GE)'],
|
||||||
[IFACE_FF_10GE_X2, 'X2 (10GE)'],
|
[IFACE_TYPE_10GE_X2, 'X2 (10GE)'],
|
||||||
[IFACE_FF_25GE_SFP28, 'SFP28 (25GE)'],
|
[IFACE_TYPE_25GE_SFP28, 'SFP28 (25GE)'],
|
||||||
[IFACE_FF_40GE_QSFP_PLUS, 'QSFP+ (40GE)'],
|
[IFACE_TYPE_40GE_QSFP_PLUS, 'QSFP+ (40GE)'],
|
||||||
[IFACE_FF_50GE_QSFP28, 'QSFP28 (50GE)'],
|
[IFACE_TYPE_50GE_QSFP28, 'QSFP28 (50GE)'],
|
||||||
[IFACE_FF_100GE_CFP, 'CFP (100GE)'],
|
[IFACE_TYPE_100GE_CFP, 'CFP (100GE)'],
|
||||||
[IFACE_FF_100GE_CFP2, 'CFP2 (100GE)'],
|
[IFACE_TYPE_100GE_CFP2, 'CFP2 (100GE)'],
|
||||||
[IFACE_FF_200GE_CFP2, 'CFP2 (200GE)'],
|
[IFACE_TYPE_200GE_CFP2, 'CFP2 (200GE)'],
|
||||||
[IFACE_FF_100GE_CFP4, 'CFP4 (100GE)'],
|
[IFACE_TYPE_100GE_CFP4, 'CFP4 (100GE)'],
|
||||||
[IFACE_FF_100GE_CPAK, 'Cisco CPAK (100GE)'],
|
[IFACE_TYPE_100GE_CPAK, 'Cisco CPAK (100GE)'],
|
||||||
[IFACE_FF_100GE_QSFP28, 'QSFP28 (100GE)'],
|
[IFACE_TYPE_100GE_QSFP28, 'QSFP28 (100GE)'],
|
||||||
[IFACE_FF_200GE_QSFP56, 'QSFP56 (200GE)'],
|
[IFACE_TYPE_200GE_QSFP56, 'QSFP56 (200GE)'],
|
||||||
[IFACE_FF_400GE_QSFP_DD, 'QSFP-DD (400GE)'],
|
[IFACE_TYPE_400GE_QSFP_DD, 'QSFP-DD (400GE)'],
|
||||||
]
|
]
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
'Wireless',
|
'Wireless',
|
||||||
[
|
[
|
||||||
[IFACE_FF_80211A, 'IEEE 802.11a'],
|
[IFACE_TYPE_80211A, 'IEEE 802.11a'],
|
||||||
[IFACE_FF_80211G, 'IEEE 802.11b/g'],
|
[IFACE_TYPE_80211G, 'IEEE 802.11b/g'],
|
||||||
[IFACE_FF_80211N, 'IEEE 802.11n'],
|
[IFACE_TYPE_80211N, 'IEEE 802.11n'],
|
||||||
[IFACE_FF_80211AC, 'IEEE 802.11ac'],
|
[IFACE_TYPE_80211AC, 'IEEE 802.11ac'],
|
||||||
[IFACE_FF_80211AD, 'IEEE 802.11ad'],
|
[IFACE_TYPE_80211AD, 'IEEE 802.11ad'],
|
||||||
]
|
]
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
'Cellular',
|
'Cellular',
|
||||||
[
|
[
|
||||||
[IFACE_FF_GSM, 'GSM'],
|
[IFACE_TYPE_GSM, 'GSM'],
|
||||||
[IFACE_FF_CDMA, 'CDMA'],
|
[IFACE_TYPE_CDMA, 'CDMA'],
|
||||||
[IFACE_FF_LTE, 'LTE'],
|
[IFACE_TYPE_LTE, 'LTE'],
|
||||||
]
|
]
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
'SONET',
|
'SONET',
|
||||||
[
|
[
|
||||||
[IFACE_FF_SONET_OC3, 'OC-3/STM-1'],
|
[IFACE_TYPE_SONET_OC3, 'OC-3/STM-1'],
|
||||||
[IFACE_FF_SONET_OC12, 'OC-12/STM-4'],
|
[IFACE_TYPE_SONET_OC12, 'OC-12/STM-4'],
|
||||||
[IFACE_FF_SONET_OC48, 'OC-48/STM-16'],
|
[IFACE_TYPE_SONET_OC48, 'OC-48/STM-16'],
|
||||||
[IFACE_FF_SONET_OC192, 'OC-192/STM-64'],
|
[IFACE_TYPE_SONET_OC192, 'OC-192/STM-64'],
|
||||||
[IFACE_FF_SONET_OC768, 'OC-768/STM-256'],
|
[IFACE_TYPE_SONET_OC768, 'OC-768/STM-256'],
|
||||||
[IFACE_FF_SONET_OC1920, 'OC-1920/STM-640'],
|
[IFACE_TYPE_SONET_OC1920, 'OC-1920/STM-640'],
|
||||||
[IFACE_FF_SONET_OC3840, 'OC-3840/STM-1234'],
|
[IFACE_TYPE_SONET_OC3840, 'OC-3840/STM-1234'],
|
||||||
]
|
]
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
'FibreChannel',
|
'FibreChannel',
|
||||||
[
|
[
|
||||||
[IFACE_FF_1GFC_SFP, 'SFP (1GFC)'],
|
[IFACE_TYPE_1GFC_SFP, 'SFP (1GFC)'],
|
||||||
[IFACE_FF_2GFC_SFP, 'SFP (2GFC)'],
|
[IFACE_TYPE_2GFC_SFP, 'SFP (2GFC)'],
|
||||||
[IFACE_FF_4GFC_SFP, 'SFP (4GFC)'],
|
[IFACE_TYPE_4GFC_SFP, 'SFP (4GFC)'],
|
||||||
[IFACE_FF_8GFC_SFP_PLUS, 'SFP+ (8GFC)'],
|
[IFACE_TYPE_8GFC_SFP_PLUS, 'SFP+ (8GFC)'],
|
||||||
[IFACE_FF_16GFC_SFP_PLUS, 'SFP+ (16GFC)'],
|
[IFACE_TYPE_16GFC_SFP_PLUS, 'SFP+ (16GFC)'],
|
||||||
[IFACE_FF_32GFC_SFP28, 'SFP28 (32GFC)'],
|
[IFACE_TYPE_32GFC_SFP28, 'SFP28 (32GFC)'],
|
||||||
[IFACE_FF_128GFC_QSFP28, 'QSFP28 (128GFC)'],
|
[IFACE_TYPE_128GFC_QSFP28, 'QSFP28 (128GFC)'],
|
||||||
]
|
]
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
'Serial',
|
'Serial',
|
||||||
[
|
[
|
||||||
[IFACE_FF_T1, 'T1 (1.544 Mbps)'],
|
[IFACE_TYPE_T1, 'T1 (1.544 Mbps)'],
|
||||||
[IFACE_FF_E1, 'E1 (2.048 Mbps)'],
|
[IFACE_TYPE_E1, 'E1 (2.048 Mbps)'],
|
||||||
[IFACE_FF_T3, 'T3 (45 Mbps)'],
|
[IFACE_TYPE_T3, 'T3 (45 Mbps)'],
|
||||||
[IFACE_FF_E3, 'E3 (34 Mbps)'],
|
[IFACE_TYPE_E3, 'E3 (34 Mbps)'],
|
||||||
]
|
]
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
'Stacking',
|
'Stacking',
|
||||||
[
|
[
|
||||||
[IFACE_FF_STACKWISE, 'Cisco StackWise'],
|
[IFACE_TYPE_STACKWISE, 'Cisco StackWise'],
|
||||||
[IFACE_FF_STACKWISE_PLUS, 'Cisco StackWise Plus'],
|
[IFACE_TYPE_STACKWISE_PLUS, 'Cisco StackWise Plus'],
|
||||||
[IFACE_FF_FLEXSTACK, 'Cisco FlexStack'],
|
[IFACE_TYPE_FLEXSTACK, 'Cisco FlexStack'],
|
||||||
[IFACE_FF_FLEXSTACK_PLUS, 'Cisco FlexStack Plus'],
|
[IFACE_TYPE_FLEXSTACK_PLUS, 'Cisco FlexStack Plus'],
|
||||||
[IFACE_FF_JUNIPER_VCP, 'Juniper VCP'],
|
[IFACE_TYPE_JUNIPER_VCP, 'Juniper VCP'],
|
||||||
[IFACE_FF_SUMMITSTACK, 'Extreme SummitStack'],
|
[IFACE_TYPE_SUMMITSTACK, 'Extreme SummitStack'],
|
||||||
[IFACE_FF_SUMMITSTACK128, 'Extreme SummitStack-128'],
|
[IFACE_TYPE_SUMMITSTACK128, 'Extreme SummitStack-128'],
|
||||||
[IFACE_FF_SUMMITSTACK256, 'Extreme SummitStack-256'],
|
[IFACE_TYPE_SUMMITSTACK256, 'Extreme SummitStack-256'],
|
||||||
[IFACE_FF_SUMMITSTACK512, 'Extreme SummitStack-512'],
|
[IFACE_TYPE_SUMMITSTACK512, 'Extreme SummitStack-512'],
|
||||||
]
|
]
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
'Other',
|
'Other',
|
||||||
[
|
[
|
||||||
[IFACE_FF_OTHER, 'Other'],
|
[IFACE_TYPE_OTHER, 'Other'],
|
||||||
]
|
]
|
||||||
],
|
],
|
||||||
]
|
]
|
||||||
|
|
||||||
VIRTUAL_IFACE_TYPES = [
|
VIRTUAL_IFACE_TYPES = [
|
||||||
IFACE_FF_VIRTUAL,
|
IFACE_TYPE_VIRTUAL,
|
||||||
IFACE_FF_LAG,
|
IFACE_TYPE_LAG,
|
||||||
]
|
]
|
||||||
|
|
||||||
WIRELESS_IFACE_TYPES = [
|
WIRELESS_IFACE_TYPES = [
|
||||||
IFACE_FF_80211A,
|
IFACE_TYPE_80211A,
|
||||||
IFACE_FF_80211G,
|
IFACE_TYPE_80211G,
|
||||||
IFACE_FF_80211N,
|
IFACE_TYPE_80211N,
|
||||||
IFACE_FF_80211AC,
|
IFACE_TYPE_80211AC,
|
||||||
IFACE_FF_80211AD,
|
IFACE_TYPE_80211AD,
|
||||||
]
|
]
|
||||||
|
|
||||||
NONCONNECTABLE_IFACE_TYPES = VIRTUAL_IFACE_TYPES + WIRELESS_IFACE_TYPES
|
NONCONNECTABLE_IFACE_TYPES = VIRTUAL_IFACE_TYPES + WIRELESS_IFACE_TYPES
|
||||||
|
@ -400,7 +400,7 @@ class InterfaceTemplateFilter(DeviceTypeComponentFilterSet):
|
|||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = InterfaceTemplate
|
model = InterfaceTemplate
|
||||||
fields = ['name', 'form_factor', 'mgmt_only']
|
fields = ['name', 'type', 'mgmt_only']
|
||||||
|
|
||||||
|
|
||||||
class FrontPortTemplateFilter(DeviceTypeComponentFilterSet):
|
class FrontPortTemplateFilter(DeviceTypeComponentFilterSet):
|
||||||
@ -753,9 +753,9 @@ class InterfaceFilter(django_filters.FilterSet):
|
|||||||
lookup_expr='isnull',
|
lookup_expr='isnull',
|
||||||
exclude=True
|
exclude=True
|
||||||
)
|
)
|
||||||
type = django_filters.CharFilter(
|
kind = django_filters.CharFilter(
|
||||||
method='filter_type',
|
method='filter_kind',
|
||||||
label='Interface type',
|
label='Kind of interface',
|
||||||
)
|
)
|
||||||
lag_id = django_filters.ModelMultipleChoiceFilter(
|
lag_id = django_filters.ModelMultipleChoiceFilter(
|
||||||
field_name='lag',
|
field_name='lag',
|
||||||
@ -775,14 +775,14 @@ class InterfaceFilter(django_filters.FilterSet):
|
|||||||
method='filter_vlan',
|
method='filter_vlan',
|
||||||
label='Assigned VID'
|
label='Assigned VID'
|
||||||
)
|
)
|
||||||
form_factor = django_filters.MultipleChoiceFilter(
|
type = django_filters.MultipleChoiceFilter(
|
||||||
choices=IFACE_FF_CHOICES,
|
choices=IFACE_TYPE_CHOICES,
|
||||||
null_value=None
|
null_value=None
|
||||||
)
|
)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Interface
|
model = Interface
|
||||||
fields = ['name', 'connection_status', 'form_factor', 'enabled', 'mtu', 'mgmt_only', 'description']
|
fields = ['name', 'connection_status', 'type', 'enabled', 'mtu', 'mgmt_only', 'description']
|
||||||
|
|
||||||
def search(self, queryset, name, value):
|
def search(self, queryset, name, value):
|
||||||
if not value.strip():
|
if not value.strip():
|
||||||
@ -818,13 +818,12 @@ class InterfaceFilter(django_filters.FilterSet):
|
|||||||
Q(tagged_vlans__vid=value)
|
Q(tagged_vlans__vid=value)
|
||||||
)
|
)
|
||||||
|
|
||||||
def filter_type(self, queryset, name, value):
|
def filter_kind(self, queryset, name, value):
|
||||||
value = value.strip().lower()
|
value = value.strip().lower()
|
||||||
return {
|
return {
|
||||||
'physical': queryset.exclude(form_factor__in=NONCONNECTABLE_IFACE_TYPES),
|
'physical': queryset.exclude(type__in=NONCONNECTABLE_IFACE_TYPES),
|
||||||
'virtual': queryset.filter(form_factor__in=VIRTUAL_IFACE_TYPES),
|
'virtual': queryset.filter(type__in=VIRTUAL_IFACE_TYPES),
|
||||||
'wireless': queryset.filter(form_factor__in=WIRELESS_IFACE_TYPES),
|
'wireless': queryset.filter(type__in=WIRELESS_IFACE_TYPES),
|
||||||
'lag': queryset.filter(form_factor=IFACE_FF_LAG),
|
|
||||||
}.get(value, queryset.none())
|
}.get(value, queryset.none())
|
||||||
|
|
||||||
def _mac_address(self, queryset, name, value):
|
def _mac_address(self, queryset, name, value):
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -1012,11 +1012,11 @@ class InterfaceTemplateForm(BootstrapMixin, forms.ModelForm):
|
|||||||
class Meta:
|
class Meta:
|
||||||
model = InterfaceTemplate
|
model = InterfaceTemplate
|
||||||
fields = [
|
fields = [
|
||||||
'device_type', 'name', 'form_factor', 'mgmt_only',
|
'device_type', 'name', 'type', 'mgmt_only',
|
||||||
]
|
]
|
||||||
widgets = {
|
widgets = {
|
||||||
'device_type': forms.HiddenInput(),
|
'device_type': forms.HiddenInput(),
|
||||||
'form_factor': StaticSelect2(),
|
'type': StaticSelect2(),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1024,8 +1024,8 @@ class InterfaceTemplateCreateForm(ComponentForm):
|
|||||||
name_pattern = ExpandableNameField(
|
name_pattern = ExpandableNameField(
|
||||||
label='Name'
|
label='Name'
|
||||||
)
|
)
|
||||||
form_factor = forms.ChoiceField(
|
type = forms.ChoiceField(
|
||||||
choices=IFACE_FF_CHOICES,
|
choices=IFACE_TYPE_CHOICES,
|
||||||
widget=StaticSelect2()
|
widget=StaticSelect2()
|
||||||
)
|
)
|
||||||
mgmt_only = forms.BooleanField(
|
mgmt_only = forms.BooleanField(
|
||||||
@ -1039,8 +1039,8 @@ class InterfaceTemplateBulkEditForm(BootstrapMixin, BulkEditForm):
|
|||||||
queryset=InterfaceTemplate.objects.all(),
|
queryset=InterfaceTemplate.objects.all(),
|
||||||
widget=forms.MultipleHiddenInput()
|
widget=forms.MultipleHiddenInput()
|
||||||
)
|
)
|
||||||
form_factor = forms.ChoiceField(
|
type = forms.ChoiceField(
|
||||||
choices=add_blank_choice(IFACE_FF_CHOICES),
|
choices=add_blank_choice(IFACE_TYPE_CHOICES),
|
||||||
required=False,
|
required=False,
|
||||||
widget=StaticSelect2()
|
widget=StaticSelect2()
|
||||||
)
|
)
|
||||||
@ -1830,8 +1830,8 @@ class DeviceBulkAddComponentForm(BootstrapMixin, forms.Form):
|
|||||||
|
|
||||||
|
|
||||||
class DeviceBulkAddInterfaceForm(DeviceBulkAddComponentForm):
|
class DeviceBulkAddInterfaceForm(DeviceBulkAddComponentForm):
|
||||||
form_factor = forms.ChoiceField(
|
type = forms.ChoiceField(
|
||||||
choices=IFACE_FF_CHOICES,
|
choices=IFACE_TYPE_CHOICES,
|
||||||
widget=StaticSelect2()
|
widget=StaticSelect2()
|
||||||
)
|
)
|
||||||
enabled = forms.BooleanField(
|
enabled = forms.BooleanField(
|
||||||
@ -2070,12 +2070,12 @@ class InterfaceForm(BootstrapMixin, forms.ModelForm):
|
|||||||
class Meta:
|
class Meta:
|
||||||
model = Interface
|
model = Interface
|
||||||
fields = [
|
fields = [
|
||||||
'device', 'name', 'form_factor', 'enabled', 'lag', 'mac_address', 'mtu', 'mgmt_only', 'description',
|
'device', 'name', 'type', 'enabled', 'lag', 'mac_address', 'mtu', 'mgmt_only', 'description',
|
||||||
'mode', 'untagged_vlan', 'tagged_vlans', 'tags',
|
'mode', 'untagged_vlan', 'tagged_vlans', 'tags',
|
||||||
]
|
]
|
||||||
widgets = {
|
widgets = {
|
||||||
'device': forms.HiddenInput(),
|
'device': forms.HiddenInput(),
|
||||||
'form_factor': StaticSelect2(),
|
'type': StaticSelect2(),
|
||||||
'lag': StaticSelect2(),
|
'lag': StaticSelect2(),
|
||||||
'mode': StaticSelect2(),
|
'mode': StaticSelect2(),
|
||||||
}
|
}
|
||||||
@ -2093,12 +2093,12 @@ class InterfaceForm(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()], form_factor=IFACE_FF_LAG
|
device__in=[device, device.get_vc_master()], type=IFACE_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()], form_factor=IFACE_FF_LAG
|
device__in=[self.instance.device, self.instance.device.get_vc_master()], type=IFACE_TYPE_LAG
|
||||||
)
|
)
|
||||||
|
|
||||||
def clean(self):
|
def clean(self):
|
||||||
@ -2210,8 +2210,8 @@ class InterfaceCreateForm(ComponentForm, forms.Form):
|
|||||||
name_pattern = ExpandableNameField(
|
name_pattern = ExpandableNameField(
|
||||||
label='Name'
|
label='Name'
|
||||||
)
|
)
|
||||||
form_factor = forms.ChoiceField(
|
type = forms.ChoiceField(
|
||||||
choices=IFACE_FF_CHOICES,
|
choices=IFACE_TYPE_CHOICES,
|
||||||
widget=StaticSelect2(),
|
widget=StaticSelect2(),
|
||||||
)
|
)
|
||||||
enabled = forms.BooleanField(
|
enabled = forms.BooleanField(
|
||||||
@ -2262,7 +2262,7 @@ class InterfaceCreateForm(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()], form_factor=IFACE_FF_LAG
|
device__in=[self.parent, self.parent.get_vc_master()], type=IFACE_TYPE_LAG
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
self.fields['lag'].queryset = Interface.objects.none()
|
self.fields['lag'].queryset = Interface.objects.none()
|
||||||
@ -2273,8 +2273,8 @@ class InterfaceBulkEditForm(BootstrapMixin, AddRemoveTagsForm, BulkEditForm):
|
|||||||
queryset=Interface.objects.all(),
|
queryset=Interface.objects.all(),
|
||||||
widget=forms.MultipleHiddenInput()
|
widget=forms.MultipleHiddenInput()
|
||||||
)
|
)
|
||||||
form_factor = forms.ChoiceField(
|
type = forms.ChoiceField(
|
||||||
choices=add_blank_choice(IFACE_FF_CHOICES),
|
choices=add_blank_choice(IFACE_TYPE_CHOICES),
|
||||||
required=False,
|
required=False,
|
||||||
widget=StaticSelect2()
|
widget=StaticSelect2()
|
||||||
)
|
)
|
||||||
@ -2326,7 +2326,7 @@ class InterfaceBulkEditForm(BootstrapMixin, AddRemoveTagsForm, BulkEditForm):
|
|||||||
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()],
|
||||||
form_factor=IFACE_FF_LAG
|
type=IFACE_TYPE_LAG
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
self.fields['lag'].choices = []
|
self.fields['lag'].choices = []
|
||||||
|
@ -37,7 +37,7 @@ class InterfaceQuerySet(QuerySet):
|
|||||||
Return only physical interfaces which are capable of being connected to other interfaces (i.e. not virtual or
|
Return only physical interfaces which are capable of being connected to other interfaces (i.e. not virtual or
|
||||||
wireless).
|
wireless).
|
||||||
"""
|
"""
|
||||||
return self.exclude(form_factor__in=NONCONNECTABLE_IFACE_TYPES)
|
return self.exclude(type__in=NONCONNECTABLE_IFACE_TYPES)
|
||||||
|
|
||||||
|
|
||||||
class InterfaceManager(Manager):
|
class InterfaceManager(Manager):
|
||||||
|
23
netbox/dcim/migrations/0073_interface_form_factor_to_type.py
Normal file
23
netbox/dcim/migrations/0073_interface_form_factor_to_type.py
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
# Generated by Django 2.1.7 on 2019-04-12 17:27
|
||||||
|
|
||||||
|
from django.db import migrations
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('dcim', '0072_powerfeeds'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.RenameField(
|
||||||
|
model_name='interface',
|
||||||
|
old_name='form_factor',
|
||||||
|
new_name='type',
|
||||||
|
),
|
||||||
|
migrations.RenameField(
|
||||||
|
model_name='interfacetemplate',
|
||||||
|
old_name='form_factor',
|
||||||
|
new_name='type',
|
||||||
|
),
|
||||||
|
]
|
@ -1132,9 +1132,9 @@ class InterfaceTemplate(ComponentTemplateModel):
|
|||||||
name = models.CharField(
|
name = models.CharField(
|
||||||
max_length=64
|
max_length=64
|
||||||
)
|
)
|
||||||
form_factor = models.PositiveSmallIntegerField(
|
type = models.PositiveSmallIntegerField(
|
||||||
choices=IFACE_FF_CHOICES,
|
choices=IFACE_TYPE_CHOICES,
|
||||||
default=IFACE_FF_10GE_SFP_PLUS
|
default=IFACE_TYPE_10GE_SFP_PLUS
|
||||||
)
|
)
|
||||||
mgmt_only = models.BooleanField(
|
mgmt_only = models.BooleanField(
|
||||||
default=False,
|
default=False,
|
||||||
@ -1150,6 +1150,22 @@ class InterfaceTemplate(ComponentTemplateModel):
|
|||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.name
|
return self.name
|
||||||
|
|
||||||
|
# TODO: Remove in v2.7
|
||||||
|
@property
|
||||||
|
def form_factor(self):
|
||||||
|
"""
|
||||||
|
Backward-compatibility for form_factor
|
||||||
|
"""
|
||||||
|
return self.type
|
||||||
|
|
||||||
|
# TODO: Remove in v2.7
|
||||||
|
@form_factor.setter
|
||||||
|
def form_factor(self, value):
|
||||||
|
"""
|
||||||
|
Backward-compatibility for form_factor
|
||||||
|
"""
|
||||||
|
self.type = value
|
||||||
|
|
||||||
|
|
||||||
class FrontPortTemplate(ComponentTemplateModel):
|
class FrontPortTemplate(ComponentTemplateModel):
|
||||||
"""
|
"""
|
||||||
@ -1647,7 +1663,7 @@ class Device(ChangeLoggedModel, ConfigContextModel, CustomFieldModel):
|
|||||||
self.device_type.poweroutlet_templates.all()]
|
self.device_type.poweroutlet_templates.all()]
|
||||||
)
|
)
|
||||||
Interface.objects.bulk_create(
|
Interface.objects.bulk_create(
|
||||||
[Interface(device=self, name=template.name, form_factor=template.form_factor,
|
[Interface(device=self, name=template.name, type=template.type,
|
||||||
mgmt_only=template.mgmt_only) for template in self.device_type.interface_templates.all()]
|
mgmt_only=template.mgmt_only) for template in self.device_type.interface_templates.all()]
|
||||||
)
|
)
|
||||||
RearPort.objects.bulk_create([
|
RearPort.objects.bulk_create([
|
||||||
@ -2092,9 +2108,9 @@ class Interface(CableTermination, ComponentModel):
|
|||||||
blank=True,
|
blank=True,
|
||||||
verbose_name='Parent LAG'
|
verbose_name='Parent LAG'
|
||||||
)
|
)
|
||||||
form_factor = models.PositiveSmallIntegerField(
|
type = models.PositiveSmallIntegerField(
|
||||||
choices=IFACE_FF_CHOICES,
|
choices=IFACE_TYPE_CHOICES,
|
||||||
default=IFACE_FF_10GE_SFP_PLUS
|
default=IFACE_TYPE_10GE_SFP_PLUS
|
||||||
)
|
)
|
||||||
enabled = models.BooleanField(
|
enabled = models.BooleanField(
|
||||||
default=True
|
default=True
|
||||||
@ -2139,7 +2155,7 @@ class Interface(CableTermination, ComponentModel):
|
|||||||
tags = TaggableManager(through=TaggedItem)
|
tags = TaggableManager(through=TaggedItem)
|
||||||
|
|
||||||
csv_headers = [
|
csv_headers = [
|
||||||
'device', 'virtual_machine', 'name', 'lag', 'form_factor', 'enabled', 'mac_address', 'mtu', 'mgmt_only',
|
'device', 'virtual_machine', 'name', 'lag', 'type', 'enabled', 'mac_address', 'mtu', 'mgmt_only',
|
||||||
'description', 'mode',
|
'description', 'mode',
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -2159,7 +2175,7 @@ class Interface(CableTermination, ComponentModel):
|
|||||||
self.virtual_machine.name if self.virtual_machine else None,
|
self.virtual_machine.name if self.virtual_machine else None,
|
||||||
self.name,
|
self.name,
|
||||||
self.lag.name if self.lag else None,
|
self.lag.name if self.lag else None,
|
||||||
self.get_form_factor_display(),
|
self.get_type_display(),
|
||||||
self.enabled,
|
self.enabled,
|
||||||
self.mac_address,
|
self.mac_address,
|
||||||
self.mtu,
|
self.mtu,
|
||||||
@ -2177,18 +2193,18 @@ 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.form_factor is not IFACE_FF_VIRTUAL:
|
if self.virtual_machine and self.type is not IFACE_TYPE_VIRTUAL:
|
||||||
raise ValidationError({
|
raise ValidationError({
|
||||||
'form_factor': "Virtual machines can only have virtual interfaces."
|
'type': "Virtual machines can only have virtual interfaces."
|
||||||
})
|
})
|
||||||
|
|
||||||
# Virtual interfaces cannot be connected
|
# Virtual interfaces cannot be connected
|
||||||
if self.form_factor in NONCONNECTABLE_IFACE_TYPES and (
|
if self.type in NONCONNECTABLE_IFACE_TYPES and (
|
||||||
self.cable or getattr(self, 'circuit_termination', False)
|
self.cable or getattr(self, 'circuit_termination', False)
|
||||||
):
|
):
|
||||||
raise ValidationError({
|
raise ValidationError({
|
||||||
'form_factor': "Virtual and wireless interfaces cannot be connected to another interface or circuit. "
|
'type': "Virtual and wireless interfaces cannot be connected to another interface or circuit. "
|
||||||
"Disconnect the interface or choose a suitable form factor."
|
"Disconnect the interface or choose a suitable type."
|
||||||
})
|
})
|
||||||
|
|
||||||
# An interface's LAG must belong to the same device (or VC master)
|
# An interface's LAG must belong to the same device (or VC master)
|
||||||
@ -2200,15 +2216,15 @@ class Interface(CableTermination, ComponentModel):
|
|||||||
})
|
})
|
||||||
|
|
||||||
# A virtual interface cannot have a parent LAG
|
# A virtual interface cannot have a parent LAG
|
||||||
if self.form_factor in NONCONNECTABLE_IFACE_TYPES and self.lag is not None:
|
if self.type in NONCONNECTABLE_IFACE_TYPES and self.lag is not None:
|
||||||
raise ValidationError({
|
raise ValidationError({
|
||||||
'lag': "{} interfaces cannot have a parent LAG interface.".format(self.get_form_factor_display())
|
'lag': "{} interfaces cannot have a parent LAG interface.".format(self.get_type_display())
|
||||||
})
|
})
|
||||||
|
|
||||||
# Only a LAG can have LAG members
|
# Only a LAG can have LAG members
|
||||||
if self.form_factor != IFACE_FF_LAG and self.member_interfaces.exists():
|
if self.type != IFACE_TYPE_LAG and self.member_interfaces.exists():
|
||||||
raise ValidationError({
|
raise ValidationError({
|
||||||
'form_factor': "Cannot change interface form factor; 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()])
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
@ -2254,6 +2270,22 @@ class Interface(CableTermination, ComponentModel):
|
|||||||
object_data=serialize_object(self)
|
object_data=serialize_object(self)
|
||||||
).save()
|
).save()
|
||||||
|
|
||||||
|
# TODO: Remove in v2.7
|
||||||
|
@property
|
||||||
|
def form_factor(self):
|
||||||
|
"""
|
||||||
|
Backward-compatibility for form_factor
|
||||||
|
"""
|
||||||
|
return self.type
|
||||||
|
|
||||||
|
# TODO: Remove in v2.7
|
||||||
|
@form_factor.setter
|
||||||
|
def form_factor(self, value):
|
||||||
|
"""
|
||||||
|
Backward-compatibility for form_factor
|
||||||
|
"""
|
||||||
|
self.type = value
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def connected_endpoint(self):
|
def connected_endpoint(self):
|
||||||
if self._connected_interface:
|
if self._connected_interface:
|
||||||
@ -2284,19 +2316,19 @@ class Interface(CableTermination, ComponentModel):
|
|||||||
|
|
||||||
@property
|
@property
|
||||||
def is_connectable(self):
|
def is_connectable(self):
|
||||||
return self.form_factor not in NONCONNECTABLE_IFACE_TYPES
|
return self.type not in NONCONNECTABLE_IFACE_TYPES
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def is_virtual(self):
|
def is_virtual(self):
|
||||||
return self.form_factor in VIRTUAL_IFACE_TYPES
|
return self.type in VIRTUAL_IFACE_TYPES
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def is_wireless(self):
|
def is_wireless(self):
|
||||||
return self.form_factor in WIRELESS_IFACE_TYPES
|
return self.type in WIRELESS_IFACE_TYPES
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def is_lag(self):
|
def is_lag(self):
|
||||||
return self.form_factor == IFACE_FF_LAG
|
return self.type == IFACE_TYPE_LAG
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def count_ipaddresses(self):
|
def count_ipaddresses(self):
|
||||||
@ -2740,11 +2772,11 @@ class Cable(ChangeLoggedModel):
|
|||||||
if (
|
if (
|
||||||
(
|
(
|
||||||
isinstance(endpoint_a, Interface) and
|
isinstance(endpoint_a, Interface) and
|
||||||
endpoint_a.form_factor == IFACE_FF_VIRTUAL
|
endpoint_a.type == IFACE_TYPE_VIRTUAL
|
||||||
) or
|
) or
|
||||||
(
|
(
|
||||||
isinstance(endpoint_b, Interface) and
|
isinstance(endpoint_b, Interface) and
|
||||||
endpoint_b.form_factor == IFACE_FF_VIRTUAL
|
endpoint_b.type == IFACE_TYPE_VIRTUAL
|
||||||
)
|
)
|
||||||
):
|
):
|
||||||
raise ValidationError("Cannot connect to a virtual interface")
|
raise ValidationError("Cannot connect to a virtual interface")
|
||||||
|
@ -415,7 +415,7 @@ class InterfaceTemplateTable(BaseTable):
|
|||||||
|
|
||||||
class Meta(BaseTable.Meta):
|
class Meta(BaseTable.Meta):
|
||||||
model = InterfaceTemplate
|
model = InterfaceTemplate
|
||||||
fields = ('pk', 'name', 'mgmt_only', 'form_factor')
|
fields = ('pk', 'name', 'mgmt_only', 'type')
|
||||||
empty_text = "None"
|
empty_text = "None"
|
||||||
|
|
||||||
|
|
||||||
@ -593,7 +593,7 @@ class InterfaceTable(BaseTable):
|
|||||||
|
|
||||||
class Meta(BaseTable.Meta):
|
class Meta(BaseTable.Meta):
|
||||||
model = Interface
|
model = Interface
|
||||||
fields = ('name', 'form_factor', 'lag', 'enabled', 'mgmt_only', 'description')
|
fields = ('name', 'type', 'lag', 'enabled', 'mgmt_only', 'description')
|
||||||
|
|
||||||
|
|
||||||
class FrontPortTable(BaseTable):
|
class FrontPortTable(BaseTable):
|
||||||
|
@ -2553,7 +2553,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', form_factor=IFACE_FF_LAG
|
device=self.device, name='Test LAG Interface', type=IFACE_TYPE_LAG
|
||||||
)
|
)
|
||||||
|
|
||||||
data = {
|
data = {
|
||||||
@ -2841,7 +2841,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, form_factor=IFACE_FF_1GE_FIXED, name='eth{}'.format(i)).save()
|
Interface(device=device, type=IFACE_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'),
|
||||||
@ -3410,23 +3410,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), form_factor=IFACE_FF_1GE_FIXED)
|
Interface.objects.create(device=self.device1, name='1/{}'.format(i), type=IFACE_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), form_factor=IFACE_FF_1GE_FIXED)
|
Interface.objects.create(device=self.device2, name='2/{}'.format(i), type=IFACE_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), form_factor=IFACE_FF_1GE_FIXED)
|
Interface.objects.create(device=self.device3, name='3/{}'.format(i), type=IFACE_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), form_factor=IFACE_FF_1GE_FIXED)
|
Interface.objects.create(device=self.device4, name='1/{}'.format(i), type=IFACE_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), form_factor=IFACE_FF_1GE_FIXED)
|
Interface.objects.create(device=self.device5, name='2/{}'.format(i), type=IFACE_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), form_factor=IFACE_FF_1GE_FIXED)
|
Interface.objects.create(device=self.device6, name='3/{}'.format(i), type=IFACE_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), form_factor=IFACE_FF_1GE_FIXED)
|
Interface.objects.create(device=self.device7, name='1/{}'.format(i), type=IFACE_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), form_factor=IFACE_FF_1GE_FIXED)
|
Interface.objects.create(device=self.device8, name='2/{}'.format(i), type=IFACE_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), form_factor=IFACE_FF_1GE_FIXED)
|
Interface.objects.create(device=self.device9, name='3/{}'.format(i), type=IFACE_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')
|
||||||
|
@ -249,7 +249,7 @@ class CableTestCase(TestCase):
|
|||||||
"""
|
"""
|
||||||
A cable connection cannot include a virtual interface
|
A cable connection cannot include a virtual interface
|
||||||
"""
|
"""
|
||||||
virtual_interface = Interface(device=self.device1, name="V1", form_factor=0)
|
virtual_interface = Interface(device=self.device1, name="V1", type=0)
|
||||||
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()
|
||||||
|
@ -3,7 +3,7 @@ import urllib.parse
|
|||||||
from django.test import Client, TestCase
|
from django.test import Client, TestCase
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
|
|
||||||
from dcim.constants import CABLE_TYPE_CAT6, IFACE_FF_1GE_FIXED
|
from dcim.constants import CABLE_TYPE_CAT6, IFACE_TYPE_1GE_FIXED
|
||||||
from dcim.models import (
|
from dcim.models import (
|
||||||
Cable, Device, DeviceRole, DeviceType, Interface, InventoryItem, Manufacturer, Platform, Rack, RackGroup,
|
Cable, Device, DeviceRole, DeviceType, Interface, InventoryItem, Manufacturer, Platform, Rack, RackGroup,
|
||||||
RackReservation, RackRole, Site, Region, VirtualChassis,
|
RackReservation, RackRole, Site, Region, VirtualChassis,
|
||||||
@ -370,17 +370,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', form_factor=IFACE_FF_1GE_FIXED)
|
iface1 = Interface(device=device1, name='Interface 1', type=IFACE_TYPE_1GE_FIXED)
|
||||||
iface1.save()
|
iface1.save()
|
||||||
iface2 = Interface(device=device1, name='Interface 2', form_factor=IFACE_FF_1GE_FIXED)
|
iface2 = Interface(device=device1, name='Interface 2', type=IFACE_TYPE_1GE_FIXED)
|
||||||
iface2.save()
|
iface2.save()
|
||||||
iface3 = Interface(device=device1, name='Interface 3', form_factor=IFACE_FF_1GE_FIXED)
|
iface3 = Interface(device=device1, name='Interface 3', type=IFACE_TYPE_1GE_FIXED)
|
||||||
iface3.save()
|
iface3.save()
|
||||||
iface4 = Interface(device=device2, name='Interface 1', form_factor=IFACE_FF_1GE_FIXED)
|
iface4 = Interface(device=device2, name='Interface 1', type=IFACE_TYPE_1GE_FIXED)
|
||||||
iface4.save()
|
iface4.save()
|
||||||
iface5 = Interface(device=device2, name='Interface 2', form_factor=IFACE_FF_1GE_FIXED)
|
iface5 = Interface(device=device2, name='Interface 2', type=IFACE_TYPE_1GE_FIXED)
|
||||||
iface5.save()
|
iface5.save()
|
||||||
iface6 = Interface(device=device2, name='Interface 3', form_factor=IFACE_FF_1GE_FIXED)
|
iface6 = Interface(device=device2, name='Interface 3', type=IFACE_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()
|
||||||
|
@ -27,7 +27,7 @@
|
|||||||
<a href="{% url 'dcim:device' pk=iface.connected_endpoint.device.pk %}">{{ iface.connected_endpoint.device }}</a>
|
<a href="{% url 'dcim:device' pk=iface.connected_endpoint.device.pk %}">{{ iface.connected_endpoint.device }}</a>
|
||||||
</td>
|
</td>
|
||||||
<td class="configured_interface" data="{{ iface.connected_endpoint }}">
|
<td class="configured_interface" data="{{ iface.connected_endpoint }}">
|
||||||
<span title="{{ iface.connected_endpoint.get_form_factor_display }}">{{ iface.connected_endpoint }}</span>
|
<span title="{{ iface.connected_endpoint.get_type_display }}">{{ iface.connected_endpoint }}</span>
|
||||||
</td>
|
</td>
|
||||||
{% elif iface.connected_endpoint.circuit %}
|
{% elif iface.connected_endpoint.circuit %}
|
||||||
{% with circuit=iface.connected_endpoint.circuit %}
|
{% with circuit=iface.connected_endpoint.circuit %}
|
||||||
|
@ -20,7 +20,7 @@
|
|||||||
{% with model=end|model_name %}
|
{% with model=end|model_name %}
|
||||||
<strong>{{ model|bettertitle }} {{ end }}</strong><br />
|
<strong>{{ model|bettertitle }} {{ end }}</strong><br />
|
||||||
{% if model == 'interface' %}
|
{% if model == 'interface' %}
|
||||||
{{ end.get_form_factor_display }}
|
{{ end.get_type_display }}
|
||||||
{% elif model == 'front port' or model == 'rear port' %}
|
{% elif model == 'front port' or model == 'rear port' %}
|
||||||
{{ end.get_type_display }}
|
{{ end.get_type_display }}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
|
|
||||||
{# Icon and name #}
|
{# Icon and name #}
|
||||||
<td class="text-nowrap">
|
<td class="text-nowrap">
|
||||||
<span title="{{ iface.get_form_factor_display }}">
|
<span title="{{ iface.get_type_display }}">
|
||||||
<i class="fa fa-fw fa-{% if iface.mgmt_only %}wrench{% elif iface.is_lag %}align-justify{% elif iface.is_virtual %}circle{% elif iface.is_wireless %}wifi{% else %}exchange{% endif %}"></i>
|
<i class="fa fa-fw fa-{% if iface.mgmt_only %}wrench{% elif iface.is_lag %}align-justify{% elif iface.is_virtual %}circle{% elif iface.is_wireless %}wifi{% else %}exchange{% endif %}"></i>
|
||||||
<a href="{{ iface.get_absolute_url }}">{{ iface }}</a>
|
<a href="{{ iface.get_absolute_url }}">{{ iface }}</a>
|
||||||
</span>
|
</span>
|
||||||
@ -81,7 +81,7 @@
|
|||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<a href="{% url 'dcim:interface' pk=iface.connected_endpoint.pk %}">
|
<a href="{% url 'dcim:interface' pk=iface.connected_endpoint.pk %}">
|
||||||
<span title="{{ iface.connected_endpoint.get_form_factor_display }}">
|
<span title="{{ iface.connected_endpoint.get_type_display }}">
|
||||||
{{ iface.connected_endpoint }}
|
{{ iface.connected_endpoint }}
|
||||||
</span>
|
</span>
|
||||||
</a>
|
</a>
|
||||||
|
@ -60,7 +60,7 @@
|
|||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Type</td>
|
<td>Type</td>
|
||||||
<td>{{ interface.get_form_factor_display }}</td>
|
<td>{{ interface.get_type_display }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Enabled</td>
|
<td>Enabled</td>
|
||||||
@ -125,7 +125,7 @@
|
|||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Type</td>
|
<td>Type</td>
|
||||||
<td>{{ connected_interface.get_form_factor_display }}</td>
|
<td>{{ connected_interface.get_type_display }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Enabled</td>
|
<td>Enabled</td>
|
||||||
@ -227,7 +227,7 @@
|
|||||||
<a href="{{ member.get_absolute_url }}">{{ member }}</a>
|
<a href="{{ member.get_absolute_url }}">{{ member }}</a>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
{{ member.get_form_factor_display }}
|
{{ member.get_type_display }}
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
{% empty %}
|
{% empty %}
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
<div class="panel-heading"><strong>Interface</strong></div>
|
<div class="panel-heading"><strong>Interface</strong></div>
|
||||||
<div class="panel-body">
|
<div class="panel-body">
|
||||||
{% render_field form.name %}
|
{% render_field form.name %}
|
||||||
{% render_field form.form_factor %}
|
{% render_field form.type %}
|
||||||
{% render_field form.enabled %}
|
{% render_field form.enabled %}
|
||||||
{% render_field form.lag %}
|
{% render_field form.lag %}
|
||||||
{% render_field form.mac_address %}
|
{% render_field form.mac_address %}
|
||||||
|
@ -3,7 +3,7 @@ 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_FF_CHOICES, IFACE_FF_VIRTUAL, IFACE_MODE_CHOICES
|
from dcim.constants import IFACE_TYPE_CHOICES, IFACE_TYPE_VIRTUAL, 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
|
||||||
@ -92,7 +92,7 @@ class VirtualMachineWithConfigContextSerializer(VirtualMachineSerializer):
|
|||||||
|
|
||||||
class InterfaceSerializer(TaggitSerializer, ValidatedModelSerializer):
|
class InterfaceSerializer(TaggitSerializer, ValidatedModelSerializer):
|
||||||
virtual_machine = NestedVirtualMachineSerializer()
|
virtual_machine = NestedVirtualMachineSerializer()
|
||||||
form_factor = ChoiceField(choices=IFACE_FF_CHOICES, default=IFACE_FF_VIRTUAL, required=False)
|
type = ChoiceField(choices=IFACE_TYPE_CHOICES, default=IFACE_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(
|
||||||
@ -106,6 +106,6 @@ class InterfaceSerializer(TaggitSerializer, ValidatedModelSerializer):
|
|||||||
class Meta:
|
class Meta:
|
||||||
model = Interface
|
model = Interface
|
||||||
fields = [
|
fields = [
|
||||||
'id', 'virtual_machine', 'name', 'form_factor', 'enabled', 'mtu', 'mac_address', 'description', 'mode',
|
'id', 'virtual_machine', 'name', 'type', 'enabled', 'mtu', 'mac_address', 'description', 'mode',
|
||||||
'untagged_vlan', 'tagged_vlans', 'tags',
|
'untagged_vlan', 'tagged_vlans', 'tags',
|
||||||
]
|
]
|
||||||
|
@ -2,7 +2,7 @@ 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_FF_VIRTUAL, IFACE_MODE_ACCESS, IFACE_MODE_TAGGED_ALL
|
from dcim.constants import IFACE_TYPE_VIRTUAL, IFACE_MODE_ACCESS, IFACE_MODE_TAGGED_ALL
|
||||||
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
|
||||||
@ -18,8 +18,8 @@ from utilities.forms import (
|
|||||||
from .constants import VM_STATUS_CHOICES
|
from .constants import VM_STATUS_CHOICES
|
||||||
from .models import Cluster, ClusterGroup, ClusterType, VirtualMachine
|
from .models import Cluster, ClusterGroup, ClusterType, VirtualMachine
|
||||||
|
|
||||||
VIFACE_FF_CHOICES = (
|
VIFACE_TYPE_CHOICES = (
|
||||||
(IFACE_FF_VIRTUAL, 'Virtual'),
|
(IFACE_TYPE_VIRTUAL, 'Virtual'),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@ -625,12 +625,12 @@ class InterfaceForm(BootstrapMixin, forms.ModelForm):
|
|||||||
class Meta:
|
class Meta:
|
||||||
model = Interface
|
model = Interface
|
||||||
fields = [
|
fields = [
|
||||||
'virtual_machine', 'name', 'form_factor', 'enabled', 'mac_address', 'mtu', 'description', 'mode', 'tags',
|
'virtual_machine', 'name', 'type', 'enabled', 'mac_address', 'mtu', 'description', 'mode', 'tags',
|
||||||
'untagged_vlan', 'tagged_vlans',
|
'untagged_vlan', 'tagged_vlans',
|
||||||
]
|
]
|
||||||
widgets = {
|
widgets = {
|
||||||
'virtual_machine': forms.HiddenInput(),
|
'virtual_machine': forms.HiddenInput(),
|
||||||
'form_factor': forms.HiddenInput(),
|
'type': forms.HiddenInput(),
|
||||||
'mode': StaticSelect2()
|
'mode': StaticSelect2()
|
||||||
}
|
}
|
||||||
labels = {
|
labels = {
|
||||||
@ -661,9 +661,9 @@ class InterfaceCreateForm(ComponentForm):
|
|||||||
name_pattern = ExpandableNameField(
|
name_pattern = ExpandableNameField(
|
||||||
label='Name'
|
label='Name'
|
||||||
)
|
)
|
||||||
form_factor = forms.ChoiceField(
|
type = forms.ChoiceField(
|
||||||
choices=VIFACE_FF_CHOICES,
|
choices=VIFACE_TYPE_CHOICES,
|
||||||
initial=IFACE_FF_VIRTUAL,
|
initial=IFACE_TYPE_VIRTUAL,
|
||||||
widget=forms.HiddenInput()
|
widget=forms.HiddenInput()
|
||||||
)
|
)
|
||||||
enabled = forms.BooleanField(
|
enabled = forms.BooleanField(
|
||||||
@ -737,9 +737,9 @@ class VirtualMachineBulkAddComponentForm(BootstrapMixin, forms.Form):
|
|||||||
|
|
||||||
|
|
||||||
class VirtualMachineBulkAddInterfaceForm(VirtualMachineBulkAddComponentForm):
|
class VirtualMachineBulkAddInterfaceForm(VirtualMachineBulkAddComponentForm):
|
||||||
form_factor = forms.ChoiceField(
|
type = forms.ChoiceField(
|
||||||
choices=VIFACE_FF_CHOICES,
|
choices=VIFACE_TYPE_CHOICES,
|
||||||
initial=IFACE_FF_VIRTUAL,
|
initial=IFACE_TYPE_VIRTUAL,
|
||||||
widget=forms.HiddenInput()
|
widget=forms.HiddenInput()
|
||||||
)
|
)
|
||||||
enabled = forms.BooleanField(
|
enabled = forms.BooleanField(
|
||||||
|
@ -2,7 +2,7 @@ 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_FF_VIRTUAL, IFACE_MODE_TAGGED
|
from dcim.constants import IFACE_TYPE_VIRTUAL, 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 +489,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',
|
||||||
form_factor=IFACE_FF_VIRTUAL
|
type=IFACE_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',
|
||||||
form_factor=IFACE_FF_VIRTUAL
|
type=IFACE_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',
|
||||||
form_factor=IFACE_FF_VIRTUAL
|
type=IFACE_TYPE_VIRTUAL
|
||||||
)
|
)
|
||||||
|
|
||||||
self.vlan1 = VLAN.objects.create(name="Test VLAN 1", vid=1)
|
self.vlan1 = VLAN.objects.create(name="Test VLAN 1", vid=1)
|
||||||
|
Loading…
Reference in New Issue
Block a user