mirror of
https://github.com/netbox-community/netbox.git
synced 2025-07-16 04:02:52 -06:00
Device.face to slug (#3569)
This commit is contained in:
parent
5c95927a43
commit
bcc34f6099
@ -325,7 +325,7 @@ class DeviceSerializer(TaggitSerializer, CustomFieldModelSerializer):
|
|||||||
site = NestedSiteSerializer()
|
site = NestedSiteSerializer()
|
||||||
rack = NestedRackSerializer(required=False, allow_null=True)
|
rack = NestedRackSerializer(required=False, allow_null=True)
|
||||||
face = ChoiceField(choices=DeviceFaceChoices, required=False, allow_null=True)
|
face = ChoiceField(choices=DeviceFaceChoices, required=False, allow_null=True)
|
||||||
status = ChoiceField(choices=DEVICE_STATUS_CHOICES, required=False)
|
status = ChoiceField(choices=DeviceStatusChoices, required=False)
|
||||||
primary_ip = NestedIPAddressSerializer(read_only=True)
|
primary_ip = NestedIPAddressSerializer(read_only=True)
|
||||||
primary_ip4 = NestedIPAddressSerializer(required=False, allow_null=True)
|
primary_ip4 = NestedIPAddressSerializer(required=False, allow_null=True)
|
||||||
primary_ip6 = NestedIPAddressSerializer(required=False, allow_null=True)
|
primary_ip6 = NestedIPAddressSerializer(required=False, allow_null=True)
|
||||||
|
@ -129,6 +129,37 @@ class DeviceFaceChoices(ChoiceSet):
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class DeviceStatusChoices(ChoiceSet):
|
||||||
|
|
||||||
|
STATUS_OFFLINE = 'offline'
|
||||||
|
STATUS_ACTIVE = 'active'
|
||||||
|
STATUS_PLANNED = 'planned'
|
||||||
|
STATUS_STAGED = 'staged'
|
||||||
|
STATUS_FAILED = 'failed'
|
||||||
|
STATUS_INVENTORY = 'inventory'
|
||||||
|
STATUS_DECOMMISSIONING = 'decommissioning'
|
||||||
|
|
||||||
|
CHOICES = (
|
||||||
|
(STATUS_OFFLINE, 'Offline'),
|
||||||
|
(STATUS_ACTIVE, 'Active'),
|
||||||
|
(STATUS_PLANNED, 'Planned'),
|
||||||
|
(STATUS_STAGED, 'Staged'),
|
||||||
|
(STATUS_FAILED, 'Failed'),
|
||||||
|
(STATUS_INVENTORY, 'Inventory'),
|
||||||
|
(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
|
# ConsolePorts
|
||||||
#
|
#
|
||||||
|
@ -61,24 +61,6 @@ PORT_TYPE_CHOICES = [
|
|||||||
]
|
]
|
||||||
]
|
]
|
||||||
|
|
||||||
# Device statuses
|
|
||||||
DEVICE_STATUS_OFFLINE = 0
|
|
||||||
DEVICE_STATUS_ACTIVE = 1
|
|
||||||
DEVICE_STATUS_PLANNED = 2
|
|
||||||
DEVICE_STATUS_STAGED = 3
|
|
||||||
DEVICE_STATUS_FAILED = 4
|
|
||||||
DEVICE_STATUS_INVENTORY = 5
|
|
||||||
DEVICE_STATUS_DECOMMISSIONING = 6
|
|
||||||
DEVICE_STATUS_CHOICES = [
|
|
||||||
[DEVICE_STATUS_ACTIVE, 'Active'],
|
|
||||||
[DEVICE_STATUS_OFFLINE, 'Offline'],
|
|
||||||
[DEVICE_STATUS_PLANNED, 'Planned'],
|
|
||||||
[DEVICE_STATUS_STAGED, 'Staged'],
|
|
||||||
[DEVICE_STATUS_FAILED, 'Failed'],
|
|
||||||
[DEVICE_STATUS_INVENTORY, 'Inventory'],
|
|
||||||
[DEVICE_STATUS_DECOMMISSIONING, 'Decommissioning'],
|
|
||||||
]
|
|
||||||
|
|
||||||
# Bootstrap CSS classes for device/rack statuses
|
# Bootstrap CSS classes for device/rack statuses
|
||||||
STATUS_CLASSES = {
|
STATUS_CLASSES = {
|
||||||
0: 'warning',
|
0: 'warning',
|
||||||
|
@ -511,7 +511,7 @@ class DeviceFilter(LocalConfigContextFilter, TenancyFilterSet, CustomFieldFilter
|
|||||||
label='Device model (slug)',
|
label='Device model (slug)',
|
||||||
)
|
)
|
||||||
status = django_filters.MultipleChoiceFilter(
|
status = django_filters.MultipleChoiceFilter(
|
||||||
choices=DEVICE_STATUS_CHOICES,
|
choices=DeviceStatusChoices,
|
||||||
null_value=None
|
null_value=None
|
||||||
)
|
)
|
||||||
is_full_depth = django_filters.BooleanFilter(
|
is_full_depth = django_filters.BooleanFilter(
|
||||||
|
@ -1665,7 +1665,7 @@ class BaseDeviceCSVForm(forms.ModelForm):
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
status = CSVChoiceField(
|
status = CSVChoiceField(
|
||||||
choices=DEVICE_STATUS_CHOICES,
|
choices=DeviceStatusChoices,
|
||||||
help_text='Operational status'
|
help_text='Operational status'
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -1833,7 +1833,7 @@ class DeviceBulkEditForm(BootstrapMixin, AddRemoveTagsForm, CustomFieldBulkEditF
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
status = forms.ChoiceField(
|
status = forms.ChoiceField(
|
||||||
choices=add_blank_choice(DEVICE_STATUS_CHOICES),
|
choices=add_blank_choice(DeviceStatusChoices),
|
||||||
required=False,
|
required=False,
|
||||||
initial='',
|
initial='',
|
||||||
widget=StaticSelect2()
|
widget=StaticSelect2()
|
||||||
@ -1944,7 +1944,7 @@ class DeviceFilterForm(BootstrapMixin, LocalConfigContextFilterForm, TenancyFilt
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
status = forms.MultipleChoiceField(
|
status = forms.MultipleChoiceField(
|
||||||
choices=DEVICE_STATUS_CHOICES,
|
choices=DeviceStatusChoices,
|
||||||
required=False,
|
required=False,
|
||||||
widget=StaticSelect2Multiple()
|
widget=StaticSelect2Multiple()
|
||||||
)
|
)
|
||||||
|
@ -5,6 +5,16 @@ DEVICE_FACE_CHOICES = (
|
|||||||
(1, 'rear'),
|
(1, 'rear'),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
DEVICE_STATUS_CHOICES = (
|
||||||
|
(0, 'offline'),
|
||||||
|
(1, 'active'),
|
||||||
|
(2, 'planned'),
|
||||||
|
(3, 'staged'),
|
||||||
|
(4, 'failed'),
|
||||||
|
(5, 'inventory'),
|
||||||
|
(6, 'decommissioning'),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def device_face_to_slug(apps, schema_editor):
|
def device_face_to_slug(apps, schema_editor):
|
||||||
Device = apps.get_model('dcim', 'Device')
|
Device = apps.get_model('dcim', 'Device')
|
||||||
@ -12,6 +22,12 @@ def device_face_to_slug(apps, schema_editor):
|
|||||||
Device.objects.filter(face=str(id)).update(face=slug)
|
Device.objects.filter(face=str(id)).update(face=slug)
|
||||||
|
|
||||||
|
|
||||||
|
def device_status_to_slug(apps, schema_editor):
|
||||||
|
Device = apps.get_model('dcim', 'Device')
|
||||||
|
for id, slug in DEVICE_STATUS_CHOICES:
|
||||||
|
Device.objects.filter(status=str(id)).update(status=slug)
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
atomic = False
|
atomic = False
|
||||||
|
|
||||||
@ -20,6 +36,8 @@ class Migration(migrations.Migration):
|
|||||||
]
|
]
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
|
|
||||||
|
# Device.face
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='device',
|
model_name='device',
|
||||||
name='face',
|
name='face',
|
||||||
@ -33,4 +51,15 @@ class Migration(migrations.Migration):
|
|||||||
name='face',
|
name='face',
|
||||||
field=models.CharField(blank=True, max_length=50),
|
field=models.CharField(blank=True, max_length=50),
|
||||||
),
|
),
|
||||||
|
|
||||||
|
# Device.status
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='device',
|
||||||
|
name='status',
|
||||||
|
field=models.CharField(default='active', max_length=50),
|
||||||
|
),
|
||||||
|
migrations.RunPython(
|
||||||
|
code=device_status_to_slug
|
||||||
|
),
|
||||||
|
|
||||||
]
|
]
|
||||||
|
@ -1551,10 +1551,10 @@ class Device(ChangeLoggedModel, ConfigContextModel, CustomFieldModel):
|
|||||||
choices=DeviceFaceChoices,
|
choices=DeviceFaceChoices,
|
||||||
verbose_name='Rack face'
|
verbose_name='Rack face'
|
||||||
)
|
)
|
||||||
status = models.PositiveSmallIntegerField(
|
status = models.CharField(
|
||||||
choices=DEVICE_STATUS_CHOICES,
|
max_length=50,
|
||||||
default=DEVICE_STATUS_ACTIVE,
|
choices=DeviceStatusChoices,
|
||||||
verbose_name='Status'
|
default=DeviceStatusChoices.STATUS_ACTIVE
|
||||||
)
|
)
|
||||||
primary_ip4 = models.OneToOneField(
|
primary_ip4 = models.OneToOneField(
|
||||||
to='ipam.IPAddress',
|
to='ipam.IPAddress',
|
||||||
@ -1616,6 +1616,16 @@ class Device(ChangeLoggedModel, ConfigContextModel, CustomFieldModel):
|
|||||||
'site', 'rack_group', 'rack_name', 'position', 'face', 'comments',
|
'site', 'rack_group', 'rack_name', 'position', 'face', 'comments',
|
||||||
]
|
]
|
||||||
|
|
||||||
|
STATUS_CLASS_MAP = {
|
||||||
|
DeviceStatusChoices.STATUS_OFFLINE: 'warning',
|
||||||
|
DeviceStatusChoices.STATUS_ACTIVE: 'success',
|
||||||
|
DeviceStatusChoices.STATUS_PLANNED: 'info',
|
||||||
|
DeviceStatusChoices.STATUS_STAGED: 'primary',
|
||||||
|
DeviceStatusChoices.STATUS_FAILED: 'danger',
|
||||||
|
DeviceStatusChoices.STATUS_INVENTORY: 'default',
|
||||||
|
DeviceStatusChoices.STATUS_DECOMMISSIONING: 'warning',
|
||||||
|
}
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
ordering = ['name']
|
ordering = ['name']
|
||||||
unique_together = [
|
unique_together = [
|
||||||
@ -1869,7 +1879,7 @@ class Device(ChangeLoggedModel, ConfigContextModel, CustomFieldModel):
|
|||||||
return Device.objects.filter(parent_bay__device=self.pk)
|
return Device.objects.filter(parent_bay__device=self.pk)
|
||||||
|
|
||||||
def get_status_class(self):
|
def get_status_class(self):
|
||||||
return STATUS_CLASSES[self.status]
|
return self.STATUS_CLASS_MAP.get(self.status)
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
|
@ -24,7 +24,7 @@ class DeviceTestCase(TestCase):
|
|||||||
'face': DeviceFaceChoices.FACE_FRONT,
|
'face': DeviceFaceChoices.FACE_FRONT,
|
||||||
'position': 41,
|
'position': 41,
|
||||||
'platform': get_id(Platform, 'juniper-junos'),
|
'platform': get_id(Platform, 'juniper-junos'),
|
||||||
'status': DEVICE_STATUS_ACTIVE,
|
'status': DeviceStatusChoices.STATUS_ACTIVE,
|
||||||
})
|
})
|
||||||
self.assertTrue(test.is_valid(), test.fields['position'].choices)
|
self.assertTrue(test.is_valid(), test.fields['position'].choices)
|
||||||
self.assertTrue(test.save())
|
self.assertTrue(test.save())
|
||||||
@ -41,7 +41,7 @@ class DeviceTestCase(TestCase):
|
|||||||
'face': DeviceFaceChoices.FACE_FRONT,
|
'face': DeviceFaceChoices.FACE_FRONT,
|
||||||
'position': 1,
|
'position': 1,
|
||||||
'platform': get_id(Platform, 'juniper-junos'),
|
'platform': get_id(Platform, 'juniper-junos'),
|
||||||
'status': DEVICE_STATUS_ACTIVE,
|
'status': DeviceStatusChoices.STATUS_ACTIVE,
|
||||||
})
|
})
|
||||||
self.assertFalse(test.is_valid())
|
self.assertFalse(test.is_valid())
|
||||||
|
|
||||||
@ -57,7 +57,7 @@ class DeviceTestCase(TestCase):
|
|||||||
'face': '',
|
'face': '',
|
||||||
'position': None,
|
'position': None,
|
||||||
'platform': None,
|
'platform': None,
|
||||||
'status': DEVICE_STATUS_ACTIVE,
|
'status': DeviceStatusChoices.STATUS_ACTIVE,
|
||||||
})
|
})
|
||||||
self.assertTrue(test.is_valid())
|
self.assertTrue(test.is_valid())
|
||||||
self.assertTrue(test.save())
|
self.assertTrue(test.save())
|
||||||
@ -74,7 +74,7 @@ class DeviceTestCase(TestCase):
|
|||||||
'face': DeviceFaceChoices.FACE_REAR,
|
'face': DeviceFaceChoices.FACE_REAR,
|
||||||
'position': None,
|
'position': None,
|
||||||
'platform': None,
|
'platform': None,
|
||||||
'status': DEVICE_STATUS_ACTIVE,
|
'status': DeviceStatusChoices.STATUS_ACTIVE,
|
||||||
})
|
})
|
||||||
self.assertTrue(test.is_valid())
|
self.assertTrue(test.is_valid())
|
||||||
self.assertTrue(test.save())
|
self.assertTrue(test.save())
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
from dcim.constants import DEVICE_STATUS_ACTIVE, DEVICE_STATUS_OFFLINE, DEVICE_STATUS_STAGED
|
from dcim.choices import DeviceStatusChoices
|
||||||
|
|
||||||
# VirtualMachine statuses (replicated from Device statuses)
|
# VirtualMachine statuses (replicated from Device statuses)
|
||||||
VM_STATUS_CHOICES = [
|
VM_STATUS_CHOICES = [
|
||||||
[DEVICE_STATUS_ACTIVE, 'Active'],
|
[1, 'Active'],
|
||||||
[DEVICE_STATUS_OFFLINE, 'Offline'],
|
[0, 'Offline'],
|
||||||
[DEVICE_STATUS_STAGED, 'Staged'],
|
[3, 'Staged'],
|
||||||
]
|
]
|
||||||
|
|
||||||
# Bootstrap CSS classes for VirtualMachine statuses
|
# Bootstrap CSS classes for VirtualMachine statuses
|
||||||
|
@ -195,7 +195,7 @@ class VirtualMachine(ChangeLoggedModel, ConfigContextModel, CustomFieldModel):
|
|||||||
)
|
)
|
||||||
status = models.PositiveSmallIntegerField(
|
status = models.PositiveSmallIntegerField(
|
||||||
choices=VM_STATUS_CHOICES,
|
choices=VM_STATUS_CHOICES,
|
||||||
default=DEVICE_STATUS_ACTIVE,
|
default=1, # TODO: Replace with ChoiceSet value
|
||||||
verbose_name='Status'
|
verbose_name='Status'
|
||||||
)
|
)
|
||||||
role = models.ForeignKey(
|
role = models.ForeignKey(
|
||||||
|
Loading…
Reference in New Issue
Block a user