mirror of
https://github.com/netbox-community/netbox.git
synced 2024-05-10 07:54:54 +00:00
Device.face to slug (#3569)
This commit is contained in:
@ -325,7 +325,7 @@ class DeviceSerializer(TaggitSerializer, CustomFieldModelSerializer):
|
||||
site = NestedSiteSerializer()
|
||||
rack = NestedRackSerializer(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_ip4 = 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
|
||||
#
|
||||
|
@ -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
|
||||
STATUS_CLASSES = {
|
||||
0: 'warning',
|
||||
|
@ -511,7 +511,7 @@ class DeviceFilter(LocalConfigContextFilter, TenancyFilterSet, CustomFieldFilter
|
||||
label='Device model (slug)',
|
||||
)
|
||||
status = django_filters.MultipleChoiceFilter(
|
||||
choices=DEVICE_STATUS_CHOICES,
|
||||
choices=DeviceStatusChoices,
|
||||
null_value=None
|
||||
)
|
||||
is_full_depth = django_filters.BooleanFilter(
|
||||
|
@ -1665,7 +1665,7 @@ class BaseDeviceCSVForm(forms.ModelForm):
|
||||
}
|
||||
)
|
||||
status = CSVChoiceField(
|
||||
choices=DEVICE_STATUS_CHOICES,
|
||||
choices=DeviceStatusChoices,
|
||||
help_text='Operational status'
|
||||
)
|
||||
|
||||
@ -1833,7 +1833,7 @@ class DeviceBulkEditForm(BootstrapMixin, AddRemoveTagsForm, CustomFieldBulkEditF
|
||||
)
|
||||
)
|
||||
status = forms.ChoiceField(
|
||||
choices=add_blank_choice(DEVICE_STATUS_CHOICES),
|
||||
choices=add_blank_choice(DeviceStatusChoices),
|
||||
required=False,
|
||||
initial='',
|
||||
widget=StaticSelect2()
|
||||
@ -1944,7 +1944,7 @@ class DeviceFilterForm(BootstrapMixin, LocalConfigContextFilterForm, TenancyFilt
|
||||
)
|
||||
)
|
||||
status = forms.MultipleChoiceField(
|
||||
choices=DEVICE_STATUS_CHOICES,
|
||||
choices=DeviceStatusChoices,
|
||||
required=False,
|
||||
widget=StaticSelect2Multiple()
|
||||
)
|
||||
|
@ -5,6 +5,16 @@ DEVICE_FACE_CHOICES = (
|
||||
(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):
|
||||
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)
|
||||
|
||||
|
||||
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):
|
||||
atomic = False
|
||||
|
||||
@ -20,6 +36,8 @@ class Migration(migrations.Migration):
|
||||
]
|
||||
|
||||
operations = [
|
||||
|
||||
# Device.face
|
||||
migrations.AlterField(
|
||||
model_name='device',
|
||||
name='face',
|
||||
@ -33,4 +51,15 @@ class Migration(migrations.Migration):
|
||||
name='face',
|
||||
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,
|
||||
verbose_name='Rack face'
|
||||
)
|
||||
status = models.PositiveSmallIntegerField(
|
||||
choices=DEVICE_STATUS_CHOICES,
|
||||
default=DEVICE_STATUS_ACTIVE,
|
||||
verbose_name='Status'
|
||||
status = models.CharField(
|
||||
max_length=50,
|
||||
choices=DeviceStatusChoices,
|
||||
default=DeviceStatusChoices.STATUS_ACTIVE
|
||||
)
|
||||
primary_ip4 = models.OneToOneField(
|
||||
to='ipam.IPAddress',
|
||||
@ -1616,6 +1616,16 @@ class Device(ChangeLoggedModel, ConfigContextModel, CustomFieldModel):
|
||||
'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:
|
||||
ordering = ['name']
|
||||
unique_together = [
|
||||
@ -1869,7 +1879,7 @@ class Device(ChangeLoggedModel, ConfigContextModel, CustomFieldModel):
|
||||
return Device.objects.filter(parent_bay__device=self.pk)
|
||||
|
||||
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,
|
||||
'position': 41,
|
||||
'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.save())
|
||||
@ -41,7 +41,7 @@ class DeviceTestCase(TestCase):
|
||||
'face': DeviceFaceChoices.FACE_FRONT,
|
||||
'position': 1,
|
||||
'platform': get_id(Platform, 'juniper-junos'),
|
||||
'status': DEVICE_STATUS_ACTIVE,
|
||||
'status': DeviceStatusChoices.STATUS_ACTIVE,
|
||||
})
|
||||
self.assertFalse(test.is_valid())
|
||||
|
||||
@ -57,7 +57,7 @@ class DeviceTestCase(TestCase):
|
||||
'face': '',
|
||||
'position': None,
|
||||
'platform': None,
|
||||
'status': DEVICE_STATUS_ACTIVE,
|
||||
'status': DeviceStatusChoices.STATUS_ACTIVE,
|
||||
})
|
||||
self.assertTrue(test.is_valid())
|
||||
self.assertTrue(test.save())
|
||||
@ -74,7 +74,7 @@ class DeviceTestCase(TestCase):
|
||||
'face': DeviceFaceChoices.FACE_REAR,
|
||||
'position': None,
|
||||
'platform': None,
|
||||
'status': DEVICE_STATUS_ACTIVE,
|
||||
'status': DeviceStatusChoices.STATUS_ACTIVE,
|
||||
})
|
||||
self.assertTrue(test.is_valid())
|
||||
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)
|
||||
VM_STATUS_CHOICES = [
|
||||
[DEVICE_STATUS_ACTIVE, 'Active'],
|
||||
[DEVICE_STATUS_OFFLINE, 'Offline'],
|
||||
[DEVICE_STATUS_STAGED, 'Staged'],
|
||||
[1, 'Active'],
|
||||
[0, 'Offline'],
|
||||
[3, 'Staged'],
|
||||
]
|
||||
|
||||
# Bootstrap CSS classes for VirtualMachine statuses
|
||||
|
@ -195,7 +195,7 @@ class VirtualMachine(ChangeLoggedModel, ConfigContextModel, CustomFieldModel):
|
||||
)
|
||||
status = models.PositiveSmallIntegerField(
|
||||
choices=VM_STATUS_CHOICES,
|
||||
default=DEVICE_STATUS_ACTIVE,
|
||||
default=1, # TODO: Replace with ChoiceSet value
|
||||
verbose_name='Status'
|
||||
)
|
||||
role = models.ForeignKey(
|
||||
|
Reference in New Issue
Block a user