diff --git a/docs/release-notes/version-2.9.md b/docs/release-notes/version-2.9.md index dc9139986..944badaf3 100644 --- a/docs/release-notes/version-2.9.md +++ b/docs/release-notes/version-2.9.md @@ -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 diff --git a/netbox/circuits/choices.py b/netbox/circuits/choices.py index 94a765d11..1b5e69cb5 100644 --- a/netbox/circuits/choices.py +++ b/netbox/circuits/choices.py @@ -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 diff --git a/netbox/dcim/choices.py b/netbox/dcim/choices.py index 59f30a206..276d6bd27 100644 --- a/netbox/dcim/choices.py +++ b/netbox/dcim/choices.py @@ -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, - } diff --git a/netbox/extras/choices.py b/netbox/extras/choices.py index fe5c74fa5..69ff1460b 100644 --- a/netbox/extras/choices.py +++ b/netbox/extras/choices.py @@ -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 diff --git a/netbox/ipam/choices.py b/netbox/ipam/choices.py index 9e211ab6d..68fdfd9df 100644 --- a/netbox/ipam/choices.py +++ b/netbox/ipam/choices.py @@ -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, - } diff --git a/netbox/utilities/api.py b/netbox/utilities/api.py index 9a41edbe5..980de7672 100644 --- a/netbox/utilities/api.py +++ b/netbox/utilities/api.py @@ -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): diff --git a/netbox/utilities/choices.py b/netbox/utilities/choices.py index ce0929a8b..3d1002105 100644 --- a/netbox/utilities/choices.py +++ b/netbox/utilities/choices.py @@ -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): """ diff --git a/netbox/utilities/tests/test_choices.py b/netbox/utilities/tests/test_choices.py index adff4eb60..bbf75e40e 100644 --- a/netbox/utilities/tests/test_choices.py +++ b/netbox/utilities/tests/test_choices.py @@ -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') diff --git a/netbox/virtualization/choices.py b/netbox/virtualization/choices.py index 3795ddb76..083470bd9 100644 --- a/netbox/virtualization/choices.py +++ b/netbox/virtualization/choices.py @@ -22,9 +22,3 @@ class VirtualMachineStatusChoices(ChoiceSet): (STATUS_FAILED, 'Failed'), (STATUS_DECOMMISSIONING, 'Decommissioning'), ) - - LEGACY_MAP = { - STATUS_OFFLINE: 0, - STATUS_ACTIVE: 1, - STATUS_STAGED: 3, - }