mirror of
https://github.com/netbox-community/netbox.git
synced 2025-07-23 04:22:01 -06:00
Device.face to slug (#3569)
This commit is contained in:
parent
c79c29e769
commit
a8db07e0a8
@ -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)
|
||||
|
@ -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
|
||||
#
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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'
|
||||
)
|
||||
|
@ -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
|
||||
|
31
netbox/dcim/migrations/0079_device_choicefields_to_slugs.py
Normal file
31
netbox/dcim/migrations/0079_device_choicefields_to_slugs.py
Normal 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
|
||||
),
|
||||
]
|
@ -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.",
|
||||
})
|
||||
|
@ -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,
|
||||
|
@ -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)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user