1
0
mirror of https://github.com/netbox-community/netbox.git synced 2024-05-10 07:54:54 +00:00

Closes #4857: Drop support for legacy numeric choice field values

This commit is contained in:
Jeremy Stretch
2020-07-15 16:54:33 -04:00
parent 7461e76606
commit 19d0d6ff10
9 changed files with 4 additions and 337 deletions

View File

@ -55,6 +55,7 @@ When running a report or custom script, the task is now queued for background pr
* extras.Script: Added `module` and `result` fields. The `result` field now conveys the nested representation of a JobResult.
* A `url` field is now included on all object representations, identifying the unique REST API URL for each object.
* A `_depth` field has been added to all objects which feature a self-recursive hierarchy (namely regions, rack groups, and tenant groups).
* Legacy numeric values for choice fields are no longer conveyed or accepted.
### Other Changes

View File

@ -23,15 +23,6 @@ class CircuitStatusChoices(ChoiceSet):
(STATUS_DECOMMISSIONED, 'Decommissioned'),
)
LEGACY_MAP = {
STATUS_DEPROVISIONING: 0,
STATUS_ACTIVE: 1,
STATUS_PLANNED: 2,
STATUS_PROVISIONING: 3,
STATUS_OFFLINE: 4,
STATUS_DECOMMISSIONED: 5,
}
#
# CircuitTerminations

View File

@ -17,12 +17,6 @@ class SiteStatusChoices(ChoiceSet):
(STATUS_RETIRED, 'Retired'),
)
LEGACY_MAP = {
STATUS_ACTIVE: 1,
STATUS_PLANNED: 2,
STATUS_RETIRED: 4,
}
#
# Racks
@ -44,14 +38,6 @@ class RackTypeChoices(ChoiceSet):
(TYPE_WALLCABINET, 'Wall-mounted cabinet'),
)
LEGACY_MAP = {
TYPE_2POST: 100,
TYPE_4POST: 200,
TYPE_CABINET: 300,
TYPE_WALLFRAME: 1000,
TYPE_WALLCABINET: 1100,
}
class RackWidthChoices(ChoiceSet):
@ -84,14 +70,6 @@ class RackStatusChoices(ChoiceSet):
(STATUS_DEPRECATED, 'Deprecated'),
)
LEGACY_MAP = {
STATUS_RESERVED: 0,
STATUS_AVAILABLE: 1,
STATUS_PLANNED: 2,
STATUS_ACTIVE: 3,
STATUS_DEPRECATED: 4,
}
class RackDimensionUnitChoices(ChoiceSet):
@ -103,11 +81,6 @@ class RackDimensionUnitChoices(ChoiceSet):
(UNIT_INCH, 'Inches'),
)
LEGACY_MAP = {
UNIT_MILLIMETER: 1000,
UNIT_INCH: 2000,
}
class RackElevationDetailRenderChoices(ChoiceSet):
@ -134,11 +107,6 @@ class SubdeviceRoleChoices(ChoiceSet):
(ROLE_CHILD, 'Child'),
)
LEGACY_MAP = {
ROLE_PARENT: True,
ROLE_CHILD: False,
}
#
# Devices
@ -154,11 +122,6 @@ class DeviceFaceChoices(ChoiceSet):
(FACE_REAR, 'Rear'),
)
LEGACY_MAP = {
FACE_FRONT: 0,
FACE_REAR: 1,
}
class DeviceStatusChoices(ChoiceSet):
@ -180,16 +143,6 @@ class DeviceStatusChoices(ChoiceSet):
(STATUS_DECOMMISSIONING, 'Decommissioning'),
)
LEGACY_MAP = {
STATUS_OFFLINE: 0,
STATUS_ACTIVE: 1,
STATUS_PLANNED: 2,
STATUS_STAGED: 3,
STATUS_FAILED: 4,
STATUS_INVENTORY: 5,
STATUS_DECOMMISSIONING: 6,
}
#
# ConsolePorts
@ -571,12 +524,6 @@ class PowerOutletFeedLegChoices(ChoiceSet):
(FEED_LEG_C, 'C'),
)
LEGACY_MAP = {
FEED_LEG_A: 1,
FEED_LEG_B: 2,
FEED_LEG_C: 3,
}
#
# Interfaces
@ -806,80 +753,6 @@ class InterfaceTypeChoices(ChoiceSet):
),
)
LEGACY_MAP = {
TYPE_VIRTUAL: 0,
TYPE_LAG: 200,
TYPE_100ME_FIXED: 800,
TYPE_1GE_FIXED: 1000,
TYPE_1GE_GBIC: 1050,
TYPE_1GE_SFP: 1100,
TYPE_2GE_FIXED: 1120,
TYPE_5GE_FIXED: 1130,
TYPE_10GE_FIXED: 1150,
TYPE_10GE_CX4: 1170,
TYPE_10GE_SFP_PLUS: 1200,
TYPE_10GE_XFP: 1300,
TYPE_10GE_XENPAK: 1310,
TYPE_10GE_X2: 1320,
TYPE_25GE_SFP28: 1350,
TYPE_40GE_QSFP_PLUS: 1400,
TYPE_50GE_QSFP28: 1420,
TYPE_100GE_CFP: 1500,
TYPE_100GE_CFP2: 1510,
TYPE_100GE_CFP4: 1520,
TYPE_100GE_CPAK: 1550,
TYPE_100GE_QSFP28: 1600,
TYPE_200GE_CFP2: 1650,
TYPE_200GE_QSFP56: 1700,
TYPE_400GE_QSFP_DD: 1750,
TYPE_400GE_OSFP: 1800,
TYPE_80211A: 2600,
TYPE_80211G: 2610,
TYPE_80211N: 2620,
TYPE_80211AC: 2630,
TYPE_80211AD: 2640,
TYPE_GSM: 2810,
TYPE_CDMA: 2820,
TYPE_LTE: 2830,
TYPE_SONET_OC3: 6100,
TYPE_SONET_OC12: 6200,
TYPE_SONET_OC48: 6300,
TYPE_SONET_OC192: 6400,
TYPE_SONET_OC768: 6500,
TYPE_SONET_OC1920: 6600,
TYPE_SONET_OC3840: 6700,
TYPE_1GFC_SFP: 3010,
TYPE_2GFC_SFP: 3020,
TYPE_4GFC_SFP: 3040,
TYPE_8GFC_SFP_PLUS: 3080,
TYPE_16GFC_SFP_PLUS: 3160,
TYPE_32GFC_SFP28: 3320,
TYPE_128GFC_QSFP28: 3400,
TYPE_INFINIBAND_SDR: 7010,
TYPE_INFINIBAND_DDR: 7020,
TYPE_INFINIBAND_QDR: 7030,
TYPE_INFINIBAND_FDR10: 7040,
TYPE_INFINIBAND_FDR: 7050,
TYPE_INFINIBAND_EDR: 7060,
TYPE_INFINIBAND_HDR: 7070,
TYPE_INFINIBAND_NDR: 7080,
TYPE_INFINIBAND_XDR: 7090,
TYPE_T1: 4000,
TYPE_E1: 4010,
TYPE_T3: 4040,
TYPE_E3: 4050,
TYPE_STACKWISE: 5000,
TYPE_STACKWISE_PLUS: 5050,
TYPE_FLEXSTACK: 5100,
TYPE_FLEXSTACK_PLUS: 5150,
TYPE_JUNIPER_VCP: 5200,
TYPE_SUMMITSTACK: 5300,
TYPE_SUMMITSTACK128: 5310,
TYPE_SUMMITSTACK256: 5320,
TYPE_SUMMITSTACK512: 5330,
TYPE_OTHER: 32767,
}
class InterfaceModeChoices(ChoiceSet):
@ -893,12 +766,6 @@ class InterfaceModeChoices(ChoiceSet):
(MODE_TAGGED_ALL, 'Tagged (All)'),
)
LEGACY_MAP = {
MODE_ACCESS: 100,
MODE_TAGGED: 200,
MODE_TAGGED_ALL: 300,
}
#
# FrontPorts/RearPorts
@ -948,22 +815,6 @@ class PortTypeChoices(ChoiceSet):
)
)
LEGACY_MAP = {
TYPE_8P8C: 1000,
TYPE_110_PUNCH: 1100,
TYPE_BNC: 1200,
TYPE_ST: 2000,
TYPE_SC: 2100,
TYPE_SC_APC: 2110,
TYPE_FC: 2200,
TYPE_LC: 2300,
TYPE_LC_APC: 2310,
TYPE_MTRJ: 2400,
TYPE_MPO: 2500,
TYPE_LSH: 2600,
TYPE_LSH_APC: 2610,
}
#
# Cables
@ -1023,28 +874,6 @@ class CableTypeChoices(ChoiceSet):
(TYPE_POWER, 'Power'),
)
LEGACY_MAP = {
TYPE_CAT3: 1300,
TYPE_CAT5: 1500,
TYPE_CAT5E: 1510,
TYPE_CAT6: 1600,
TYPE_CAT6A: 1610,
TYPE_CAT7: 1700,
TYPE_DAC_ACTIVE: 1800,
TYPE_DAC_PASSIVE: 1810,
TYPE_COAXIAL: 1900,
TYPE_MMF: 3000,
TYPE_MMF_OM1: 3010,
TYPE_MMF_OM2: 3020,
TYPE_MMF_OM3: 3030,
TYPE_MMF_OM4: 3040,
TYPE_SMF: 3500,
TYPE_SMF_OS1: 3510,
TYPE_SMF_OS2: 3520,
TYPE_AOC: 3800,
TYPE_POWER: 5000,
}
class CableStatusChoices(ChoiceSet):
@ -1058,11 +887,6 @@ class CableStatusChoices(ChoiceSet):
(STATUS_DECOMMISSIONING, 'Decommissioning'),
)
LEGACY_MAP = {
STATUS_CONNECTED: True,
STATUS_PLANNED: False,
}
class CableLengthUnitChoices(ChoiceSet):
@ -1078,13 +902,6 @@ class CableLengthUnitChoices(ChoiceSet):
(UNIT_INCH, 'Inches'),
)
LEGACY_MAP = {
UNIT_METER: 1200,
UNIT_CENTIMETER: 1100,
UNIT_FOOT: 2100,
UNIT_INCH: 2000,
}
#
# PowerFeeds
@ -1104,13 +921,6 @@ class PowerFeedStatusChoices(ChoiceSet):
(STATUS_FAILED, 'Failed'),
)
LEGACY_MAP = {
STATUS_OFFLINE: 0,
STATUS_ACTIVE: 1,
STATUS_PLANNED: 2,
STATUS_FAILED: 4,
}
class PowerFeedTypeChoices(ChoiceSet):
@ -1122,11 +932,6 @@ class PowerFeedTypeChoices(ChoiceSet):
(TYPE_REDUNDANT, 'Redundant'),
)
LEGACY_MAP = {
TYPE_PRIMARY: 1,
TYPE_REDUNDANT: 2,
}
class PowerFeedSupplyChoices(ChoiceSet):
@ -1138,11 +943,6 @@ class PowerFeedSupplyChoices(ChoiceSet):
(SUPPLY_DC, 'DC'),
)
LEGACY_MAP = {
SUPPLY_AC: 1,
SUPPLY_DC: 2,
}
class PowerFeedPhaseChoices(ChoiceSet):
@ -1153,8 +953,3 @@ class PowerFeedPhaseChoices(ChoiceSet):
(PHASE_SINGLE, 'Single phase'),
(PHASE_3PHASE, 'Three-phase'),
)
LEGACY_MAP = {
PHASE_SINGLE: 1,
PHASE_3PHASE: 3,
}

View File

@ -23,15 +23,6 @@ class CustomFieldTypeChoices(ChoiceSet):
(TYPE_SELECT, 'Selection'),
)
LEGACY_MAP = {
TYPE_TEXT: 100,
TYPE_INTEGER: 200,
TYPE_BOOLEAN: 300,
TYPE_DATE: 400,
TYPE_URL: 500,
TYPE_SELECT: 600,
}
class CustomFieldFilterLogicChoices(ChoiceSet):
@ -45,12 +36,6 @@ class CustomFieldFilterLogicChoices(ChoiceSet):
(FILTER_EXACT, 'Exact'),
)
LEGACY_MAP = {
FILTER_DISABLED: 0,
FILTER_LOOSE: 1,
FILTER_EXACT: 2,
}
#
# CustomLinks
@ -93,12 +78,6 @@ class ObjectChangeActionChoices(ChoiceSet):
(ACTION_DELETE, 'Deleted'),
)
LEGACY_MAP = {
ACTION_CREATE: 1,
ACTION_UPDATE: 2,
ACTION_DELETE: 3,
}
#
# ExportTemplates
@ -114,11 +93,6 @@ class TemplateLanguageChoices(ChoiceSet):
(LANGUAGE_JINJA2, 'Jinja2'),
)
LEGACY_MAP = {
LANGUAGE_DJANGO: 10,
LANGUAGE_JINJA2: 20,
}
#
# Log Levels for Reports and Scripts
@ -148,14 +122,6 @@ class LogLevelChoices(ChoiceSet):
(LOG_FAILURE, 'danger'),
)
LEGACY_MAP = (
(LOG_DEFAULT, 0),
(LOG_SUCCESS, 10),
(LOG_INFO, 20),
(LOG_WARNING, 30),
(LOG_FAILURE, 40),
)
#
# Job results

View File

@ -30,13 +30,6 @@ class PrefixStatusChoices(ChoiceSet):
(STATUS_DEPRECATED, 'Deprecated'),
)
LEGACY_MAP = {
STATUS_CONTAINER: 0,
STATUS_ACTIVE: 1,
STATUS_RESERVED: 2,
STATUS_DEPRECATED: 3,
}
#
# IPAddresses
@ -56,13 +49,6 @@ class IPAddressStatusChoices(ChoiceSet):
(STATUS_DHCP, 'DHCP'),
)
LEGACY_MAP = {
STATUS_ACTIVE: 1,
STATUS_RESERVED: 2,
STATUS_DEPRECATED: 3,
STATUS_DHCP: 5,
}
class IPAddressRoleChoices(ChoiceSet):
@ -86,17 +72,6 @@ class IPAddressRoleChoices(ChoiceSet):
(ROLE_CARP, 'CARP'),
)
LEGACY_MAP = {
ROLE_LOOPBACK: 10,
ROLE_SECONDARY: 20,
ROLE_ANYCAST: 30,
ROLE_VIP: 40,
ROLE_VRRP: 41,
ROLE_HSRP: 42,
ROLE_GLBP: 43,
ROLE_CARP: 44,
}
#
# VLANs
@ -114,12 +89,6 @@ class VLANStatusChoices(ChoiceSet):
(STATUS_DEPRECATED, 'Deprecated'),
)
LEGACY_MAP = {
STATUS_ACTIVE: 1,
STATUS_RESERVED: 2,
STATUS_DEPRECATED: 3,
}
#
# Services
@ -134,8 +103,3 @@ class ServiceProtocolChoices(ChoiceSet):
(PROTOCOL_TCP, 'TCP'),
(PROTOCOL_UDP, 'UDP'),
)
LEGACY_MAP = {
PROTOCOL_TCP: 6,
PROTOCOL_UDP: 17,
}

View File

@ -103,18 +103,11 @@ class ChoiceField(serializers.Field):
def to_representation(self, obj):
if obj is '':
return None
data = OrderedDict([
return OrderedDict([
('value', obj),
('label', self._choices[obj])
])
# TODO: Remove in v2.8
# Include legacy numeric ID (where applicable)
if hasattr(self.choiceset, 'LEGACY_MAP') and obj in self.choiceset.LEGACY_MAP:
data['id'] = self.choiceset.LEGACY_MAP.get(obj)
return data
def to_internal_value(self, data):
if data is '':
if self.allow_blank:
@ -140,14 +133,10 @@ class ChoiceField(serializers.Field):
try:
if data in self._choices:
return data
# Check if data is a legacy numeric ID
slug = self.choiceset.id_to_slug(data)
if slug is not None:
return slug
except TypeError: # Input is an unhashable type
pass
raise ValidationError("{} is not a valid choice.".format(data))
raise ValidationError(f"{data} is not a valid choice.")
@property
def choices(self):

View File

@ -14,7 +14,6 @@ class ChoiceSetMeta(type):
class ChoiceSet(metaclass=ChoiceSetMeta):
CHOICES = list()
LEGACY_MAP = dict()
@classmethod
def values(cls):
@ -25,25 +24,6 @@ class ChoiceSet(metaclass=ChoiceSetMeta):
# Unpack grouped choices before casting as a dict
return dict(unpack_grouped_choices(cls.CHOICES))
@classmethod
def slug_to_id(cls, slug):
"""
Return the legacy integer value corresponding to a slug.
"""
return cls.LEGACY_MAP.get(slug)
@classmethod
def id_to_slug(cls, legacy_id):
"""
Return the slug value corresponding to a legacy integer value.
"""
if legacy_id in cls.LEGACY_MAP.values():
# Invert the legacy map to allow lookup by integer
legacy_map = dict([
(id, slug) for slug, id in cls.LEGACY_MAP.items()
])
return legacy_map.get(legacy_id)
def unpack_grouped_choices(choices):
"""

View File

@ -11,6 +11,7 @@ class ExampleChoices(ChoiceSet):
CHOICE_1 = 1
CHOICE_2 = 2
CHOICE_3 = 3
CHOICES = (
('Letters', (
(CHOICE_A, 'A'),
@ -23,14 +24,6 @@ class ExampleChoices(ChoiceSet):
(CHOICE_3, 'Three'),
)),
)
LEGACY_MAP = {
CHOICE_A: 101,
CHOICE_B: 102,
CHOICE_C: 103,
CHOICE_1: 201,
CHOICE_2: 202,
CHOICE_3: 203,
}
class ChoiceSetTestCase(TestCase):
@ -42,9 +35,3 @@ class ChoiceSetTestCase(TestCase):
self.assertEqual(ExampleChoices.as_dict(), {
'a': 'A', 'b': 'B', 'c': 'C', 1: 'One', 2: 'Two', 3: 'Three'
})
def test_slug_to_id(self):
self.assertEqual(ExampleChoices.slug_to_id('a'), 101)
def test_id_to_slug(self):
self.assertEqual(ExampleChoices.id_to_slug(101), 'a')

View File

@ -22,9 +22,3 @@ class VirtualMachineStatusChoices(ChoiceSet):
(STATUS_FAILED, 'Failed'),
(STATUS_DECOMMISSIONING, 'Decommissioning'),
)
LEGACY_MAP = {
STATUS_OFFLINE: 0,
STATUS_ACTIVE: 1,
STATUS_STAGED: 3,
}