Device.face to slug (#3569)

This commit is contained in:
Jeremy Stretch 2019-11-16 21:46:07 -05:00
parent c79c29e769
commit a8db07e0a8
10 changed files with 80 additions and 43 deletions

View File

@ -324,7 +324,7 @@ class DeviceSerializer(TaggitSerializer, CustomFieldModelSerializer):
platform = NestedPlatformSerializer(required=False, allow_null=True)
site = NestedSiteSerializer()
rack = NestedRackSerializer(required=False, allow_null=True)
face = ChoiceField(choices=RACK_FACE_CHOICES, required=False, allow_null=True)
face = ChoiceField(choices=DeviceFaceChoices, required=False, allow_null=True)
status = ChoiceField(choices=DEVICE_STATUS_CHOICES, required=False)
primary_ip = NestedIPAddressSerializer(read_only=True)
primary_ip4 = NestedIPAddressSerializer(required=False, allow_null=True)

View File

@ -66,6 +66,26 @@ class RackStatusChoices(ChoiceSet):
}
#
# Devices
#
class DeviceFaceChoices(ChoiceSet):
FACE_FRONT = 'front'
FACE_REAR = 'rear'
CHOICES = (
(FACE_FRONT, 'Front'),
(FACE_REAR, 'Rear'),
)
LEGACY_MAP = {
FACE_FRONT: 0,
FACE_REAR: 1,
}
#
# Console port type values
#

View File

@ -1,17 +1,3 @@
# Device rack faces
RACK_FACE_FRONT = 0
RACK_FACE_REAR = 1
RACK_FACE_CHOICES = [
[RACK_FACE_FRONT, 'Front'],
[RACK_FACE_REAR, 'Rear'],
]
# Device rack position
DEVICE_POSITION_CHOICES = [
# Rack.u_height is limited to 100
(i, 'Unit {}'.format(i)) for i in range(1, 101)
]
# Parent/child device roles
SUBDEVICE_ROLE_PARENT = True
SUBDEVICE_ROLE_CHILD = False

View File

@ -1910,7 +1910,7 @@
"site": 1,
"rack": 1,
"position": 1,
"face": 0,
"face": "front",
"status": true,
"primary_ip4": 1,
"primary_ip6": null,
@ -1931,7 +1931,7 @@
"site": 1,
"rack": 1,
"position": 17,
"face": 0,
"face": "rear",
"status": true,
"primary_ip4": 5,
"primary_ip6": null,
@ -1952,7 +1952,7 @@
"site": 1,
"rack": 1,
"position": 33,
"face": 0,
"face": "rear",
"status": true,
"primary_ip4": null,
"primary_ip6": null,
@ -1973,7 +1973,7 @@
"site": 1,
"rack": 1,
"position": 34,
"face": 0,
"face": "rear",
"status": true,
"primary_ip4": null,
"primary_ip6": null,
@ -1994,7 +1994,7 @@
"site": 1,
"rack": 2,
"position": 34,
"face": 0,
"face": "rear",
"status": true,
"primary_ip4": null,
"primary_ip6": null,
@ -2015,7 +2015,7 @@
"site": 1,
"rack": 2,
"position": 33,
"face": 0,
"face": "rear",
"status": true,
"primary_ip4": null,
"primary_ip6": null,
@ -2036,7 +2036,7 @@
"site": 1,
"rack": 2,
"position": 1,
"face": 0,
"face": "rear",
"status": true,
"primary_ip4": 3,
"primary_ip6": null,
@ -2057,7 +2057,7 @@
"site": 1,
"rack": 2,
"position": 17,
"face": 0,
"face": "rear",
"status": true,
"primary_ip4": 19,
"primary_ip6": null,
@ -2078,7 +2078,7 @@
"site": 1,
"rack": 1,
"position": 42,
"face": 0,
"face": "rear",
"status": true,
"primary_ip4": null,
"primary_ip6": null,
@ -2099,7 +2099,7 @@
"site": 1,
"rack": 1,
"position": null,
"face": null,
"face": "",
"status": true,
"primary_ip4": null,
"primary_ip6": null,
@ -2120,7 +2120,7 @@
"site": 1,
"rack": 2,
"position": null,
"face": null,
"face": "",
"status": true,
"primary_ip4": null,
"primary_ip6": null,

View File

@ -1716,7 +1716,7 @@ class DeviceCSVForm(BaseDeviceCSVForm):
help_text='Name of parent rack'
)
face = CSVChoiceField(
choices=RACK_FACE_CHOICES,
choices=DeviceFaceChoices,
required=False,
help_text='Mounted rack face'
)

View File

@ -49,7 +49,7 @@ class Migration(migrations.Migration):
migrations.AlterField(
model_name='rack',
name='status',
field=models.CharField(blank=True, max_length=50),
field=models.CharField(blank=True, default='active', max_length=50),
),
migrations.RunPython(
code=rack_status_to_slug

View File

@ -0,0 +1,31 @@
from django.db import migrations, models
DEVICE_FACE_CHOICES = (
(0, 'front'),
(1, 'rear'),
)
def rack_type_to_slug(apps, schema_editor):
Device = apps.get_model('dcim', 'Device')
for id, slug in DEVICE_FACE_CHOICES:
Device.objects.filter(face=str(id)).update(face=slug)
class Migration(migrations.Migration):
dependencies = [
('dcim', '0078_rack_choicefields_to_slugs'),
]
operations = [
# Device.face
migrations.AlterField(
model_name='device',
name='face',
field=models.CharField(blank=True, max_length=50),
),
migrations.RunPython(
code=rack_type_to_slug
),
]

View File

@ -655,7 +655,7 @@ class Rack(ChangeLoggedModel, CustomFieldModel):
def get_status_class(self):
return self.STATUS_CLASS_MAP.get(self.status)
def get_rack_units(self, face=RACK_FACE_FRONT, exclude=None, remove_redundant=False):
def get_rack_units(self, face=DeviceFaceChoices.FACE_FRONT, exclude=None, remove_redundant=False):
"""
Return a list of rack units as dictionaries. Example: {'device': None, 'face': 0, 'id': 48, 'name': 'U48'}
Each key 'device' is either a Device or None. By default, multi-U devices are repeated for each U they occupy.
@ -687,10 +687,10 @@ class Rack(ChangeLoggedModel, CustomFieldModel):
return [u for u in elevation.values()]
def get_front_elevation(self):
return self.get_rack_units(face=RACK_FACE_FRONT, remove_redundant=True)
return self.get_rack_units(face=DeviceFaceChoices.FACE_FRONT, remove_redundant=True)
def get_rear_elevation(self):
return self.get_rack_units(face=RACK_FACE_REAR, remove_redundant=True)
return self.get_rack_units(face=DeviceFaceChoices.FACE_REAR, remove_redundant=True)
def get_available_units(self, u_height=1, rack_face=None, exclude=list()):
"""
@ -1535,10 +1535,10 @@ class Device(ChangeLoggedModel, ConfigContextModel, CustomFieldModel):
verbose_name='Position (U)',
help_text='The lowest-numbered unit occupied by the device'
)
face = models.PositiveSmallIntegerField(
face = models.CharField(
max_length=50,
blank=True,
null=True,
choices=RACK_FACE_CHOICES,
choices=DeviceFaceChoices,
verbose_name='Rack face'
)
status = models.PositiveSmallIntegerField(
@ -1634,7 +1634,7 @@ class Device(ChangeLoggedModel, ConfigContextModel, CustomFieldModel):
})
if self.rack is None:
if self.face is not None:
if self.face:
raise ValidationError({
'face': "Cannot select a rack face without assigning a rack.",
})
@ -1644,7 +1644,7 @@ class Device(ChangeLoggedModel, ConfigContextModel, CustomFieldModel):
})
# Validate position/face combination
if self.position and self.face is None:
if self.position and not self.face:
raise ValidationError({
'face': "Must specify rack face when defining rack position.",
})

View File

@ -21,7 +21,7 @@ class DeviceTestCase(TestCase):
'device_type': get_id(DeviceType, 'qfx5100-48s'),
'site': get_id(Site, 'test1'),
'rack': '1',
'face': RACK_FACE_FRONT,
'face': DeviceFaceChoices.FACE_FRONT,
'position': 41,
'platform': get_id(Platform, 'juniper-junos'),
'status': DEVICE_STATUS_ACTIVE,
@ -38,7 +38,7 @@ class DeviceTestCase(TestCase):
'device_type': get_id(DeviceType, 'qfx5100-48s'),
'site': get_id(Site, 'test1'),
'rack': '1',
'face': RACK_FACE_FRONT,
'face': DeviceFaceChoices.FACE_FRONT,
'position': 1,
'platform': get_id(Platform, 'juniper-junos'),
'status': DEVICE_STATUS_ACTIVE,
@ -54,7 +54,7 @@ class DeviceTestCase(TestCase):
'device_type': get_id(DeviceType, 'cwg-24vym415c9'),
'site': get_id(Site, 'test1'),
'rack': '1',
'face': None,
'face': '',
'position': None,
'platform': None,
'status': DEVICE_STATUS_ACTIVE,
@ -71,7 +71,7 @@ class DeviceTestCase(TestCase):
'device_type': get_id(DeviceType, 'cwg-24vym415c9'),
'site': get_id(Site, 'test1'),
'rack': '1',
'face': RACK_FACE_REAR,
'face': DeviceFaceChoices.FACE_REAR,
'position': None,
'platform': None,
'status': DEVICE_STATUS_ACTIVE,

View File

@ -87,7 +87,7 @@ class RackTestCase(TestCase):
site=self.site1,
rack=rack1,
position=43,
face=RACK_FACE_FRONT,
face=DeviceFaceChoices.FACE_FRONT,
)
device1.save()
@ -117,7 +117,7 @@ class RackTestCase(TestCase):
site=self.site1,
rack=self.rack,
position=10,
face=RACK_FACE_REAR,
face=DeviceFaceChoices.FACE_REAR,
)
device1.save()
@ -146,7 +146,7 @@ class RackTestCase(TestCase):
site=self.site1,
rack=self.rack,
position=None,
face=None,
face='',
)
self.assertTrue(pdu)