1
0
mirror of https://github.com/netbox-community/netbox.git synced 2024-05-10 07:54:54 +00:00

Prefix.status to slug (#3569)

This commit is contained in:
Jeremy Stretch
2019-11-27 21:46:53 -05:00
parent 21fe5902a8
commit 929c0648d0
9 changed files with 91 additions and 29 deletions

View File

@ -8,6 +8,7 @@ from taggit_serializer.serializers import TaggitSerializer, TagListSerializerFie
from dcim.api.nested_serializers import NestedDeviceSerializer, NestedSiteSerializer
from dcim.models import Interface
from extras.api.customfields import CustomFieldModelSerializer
from ipam.choices import *
from ipam.constants import *
from ipam.models import Aggregate, IPAddress, Prefix, RIR, Role, Service, VLAN, VLANGroup, VRF
from tenancy.api.nested_serializers import NestedTenantSerializer
@ -140,7 +141,7 @@ class PrefixSerializer(TaggitSerializer, CustomFieldModelSerializer):
vrf = NestedVRFSerializer(required=False, allow_null=True)
tenant = NestedTenantSerializer(required=False, allow_null=True)
vlan = NestedVLANSerializer(required=False, allow_null=True)
status = ChoiceField(choices=PREFIX_STATUS_CHOICES, required=False)
status = ChoiceField(choices=PrefixStatusChoices, required=False)
role = NestedRoleSerializer(required=False, allow_null=True)
tags = TagListSerializerField(required=False)

27
netbox/ipam/choices.py Normal file
View File

@ -0,0 +1,27 @@
from utilities.choices import ChoiceSet
#
# Prefixes
#
class PrefixStatusChoices(ChoiceSet):
STATUS_CONTAINER = 'container'
STATUS_ACTIVE = 'active'
STATUS_RESERVED = 'reserved'
STATUS_DEPRECATED = 'deprecated'
CHOICES = (
(STATUS_CONTAINER, 'Container'),
(STATUS_ACTIVE, 'Active'),
(STATUS_RESERVED, 'Reserved'),
(STATUS_DEPRECATED, 'Deprecated'),
)
LEGACY_MAP = {
STATUS_CONTAINER: 0,
STATUS_ACTIVE: 1,
STATUS_RESERVED: 2,
STATUS_DEPRECATED: 3,
}

View File

@ -4,18 +4,6 @@ AF_CHOICES = (
(6, 'IPv6'),
)
# Prefix statuses
PREFIX_STATUS_CONTAINER = 0
PREFIX_STATUS_ACTIVE = 1
PREFIX_STATUS_RESERVED = 2
PREFIX_STATUS_DEPRECATED = 3
PREFIX_STATUS_CHOICES = (
(PREFIX_STATUS_CONTAINER, 'Container'),
(PREFIX_STATUS_ACTIVE, 'Active'),
(PREFIX_STATUS_RESERVED, 'Reserved'),
(PREFIX_STATUS_DEPRECATED, 'Deprecated')
)
# IP address statuses
IPADDRESS_STATUS_ACTIVE = 1
IPADDRESS_STATUS_RESERVED = 2

View File

@ -9,6 +9,7 @@ from extras.filters import CustomFieldFilterSet
from tenancy.filtersets import TenancyFilterSet
from utilities.filters import NameSlugSearchFilterSet, NumericInFilter, TagFilter
from virtualization.models import VirtualMachine
from .choices import *
from .constants import *
from .models import Aggregate, IPAddress, Prefix, RIR, Role, Service, VLAN, VLANGroup, VRF
@ -178,7 +179,7 @@ class PrefixFilter(TenancyFilterSet, CustomFieldFilterSet):
label='Role (slug)',
)
status = django_filters.MultipleChoiceFilter(
choices=PREFIX_STATUS_CHOICES,
choices=PrefixStatusChoices,
null_value=None
)
tag = TagFilter()

View File

@ -40,7 +40,7 @@
"site": 1,
"vrf": null,
"vlan": null,
"status": 1,
"status": "active",
"role": 1,
"description": ""
}
@ -56,7 +56,7 @@
"site": 1,
"vrf": null,
"vlan": null,
"status": 1,
"status": "active",
"role": 1,
"description": ""
}

View File

@ -13,6 +13,7 @@ from utilities.forms import (
StaticSelect2, StaticSelect2Multiple, BOOLEAN_WITH_BLANK_CHOICES
)
from virtualization.models import VirtualMachine
from .choices import *
from .constants import *
from .models import Aggregate, IPAddress, Prefix, RIR, Role, Service, VLAN, VLANGroup, VRF
@ -374,7 +375,7 @@ class PrefixCSVForm(forms.ModelForm):
required=False
)
status = CSVChoiceField(
choices=PREFIX_STATUS_CHOICES,
choices=PrefixStatusChoices,
help_text='Operational status'
)
role = forms.ModelChoiceField(
@ -459,7 +460,7 @@ class PrefixBulkEditForm(BootstrapMixin, AddRemoveTagsForm, CustomFieldBulkEditF
)
)
status = forms.ChoiceField(
choices=add_blank_choice(PREFIX_STATUS_CHOICES),
choices=add_blank_choice(PrefixStatusChoices),
required=False,
widget=StaticSelect2()
)
@ -527,7 +528,7 @@ class PrefixFilterForm(BootstrapMixin, TenancyFilterForm, CustomFieldFilterForm)
)
)
status = forms.MultipleChoiceField(
choices=PREFIX_STATUS_CHOICES,
choices=PrefixStatusChoices,
required=False,
widget=StaticSelect2Multiple()
)

View File

@ -0,0 +1,34 @@
from django.db import migrations, models
PREFIX_STATUS_CHOICES = (
(0, 'container'),
(1, 'active'),
(2, 'reserved'),
(3, 'deprecated'),
)
def prefix_status_to_slug(apps, schema_editor):
Prefix = apps.get_model('ipam', 'Prefix')
for id, slug in PREFIX_STATUS_CHOICES:
Prefix.objects.filter(status=str(id)).update(status=slug)
class Migration(migrations.Migration):
atomic = False
dependencies = [
('ipam', '0027_ipaddress_add_dns_name'),
]
operations = [
migrations.AlterField(
model_name='prefix',
name='status',
field=models.CharField(default='active', max_length=50),
),
migrations.RunPython(
code=prefix_status_to_slug
),
]

View File

@ -14,6 +14,7 @@ from extras.models import CustomFieldModel, ObjectChange, TaggedItem
from utilities.models import ChangeLoggedModel
from utilities.utils import serialize_object
from virtualization.models import VirtualMachine
from .choices import *
from .constants import *
from .fields import IPNetworkField, IPAddressField
from .querysets import PrefixQuerySet
@ -297,9 +298,10 @@ class Prefix(ChangeLoggedModel, CustomFieldModel):
null=True,
verbose_name='VLAN'
)
status = models.PositiveSmallIntegerField(
choices=PREFIX_STATUS_CHOICES,
default=PREFIX_STATUS_ACTIVE,
status = models.CharField(
max_length=50,
choices=PrefixStatusChoices,
default=PrefixStatusChoices.STATUS_ACTIVE,
verbose_name='Status',
help_text='Operational status of this prefix'
)
@ -333,6 +335,13 @@ class Prefix(ChangeLoggedModel, CustomFieldModel):
'prefix', 'vrf', 'tenant', 'site', 'vlan_group', 'vlan_vid', 'status', 'role', 'is_pool', 'description',
]
STATUS_CLASS_MAP = {
'container': 'default',
'active': 'primary',
'reserved': 'info',
'deprecated': 'danger',
}
class Meta:
ordering = [F('vrf').asc(nulls_first=True), 'family', 'prefix']
verbose_name_plural = 'prefixes'
@ -404,7 +413,7 @@ class Prefix(ChangeLoggedModel, CustomFieldModel):
prefix_length = property(fset=_set_prefix_length)
def get_status_class(self):
return STATUS_CHOICE_CLASSES[self.status]
return self.STATUS_CLASS_MAP.get(self.status)
def get_duplicates(self):
return Prefix.objects.filter(vrf=self.vrf, prefix=str(self.prefix)).exclude(pk=self.pk)
@ -414,7 +423,7 @@ class Prefix(ChangeLoggedModel, CustomFieldModel):
Return all Prefixes within this Prefix and VRF. If this Prefix is a container in the global table, return child
Prefixes belonging to any VRF.
"""
if self.vrf is None and self.status == PREFIX_STATUS_CONTAINER:
if self.vrf is None and self.status == PrefixStatusChoices.STATUS_CONTAINER:
return Prefix.objects.filter(prefix__net_contained=str(self.prefix))
else:
return Prefix.objects.filter(prefix__net_contained=str(self.prefix), vrf=self.vrf)
@ -424,7 +433,7 @@ class Prefix(ChangeLoggedModel, CustomFieldModel):
Return all IPAddresses within this Prefix and VRF. If this Prefix is a container in the global table, return
child IPAddresses belonging to any VRF.
"""
if self.vrf is None and self.status == PREFIX_STATUS_CONTAINER:
if self.vrf is None and self.status == PrefixStatusChoices.STATUS_CONTAINER:
return IPAddress.objects.filter(address__net_host_contained=str(self.prefix))
else:
return IPAddress.objects.filter(address__net_host_contained=str(self.prefix), vrf=self.vrf)
@ -490,7 +499,7 @@ class Prefix(ChangeLoggedModel, CustomFieldModel):
Determine the utilization of the prefix and return it as a percentage. For Prefixes with a status of
"container", calculate utilization based on child prefixes. For all others, count child IP addresses.
"""
if self.status == PREFIX_STATUS_CONTAINER:
if self.status == PrefixStatusChoices.STATUS_CONTAINER:
queryset = Prefix.objects.filter(prefix__net_contained=str(self.prefix), vrf=self.vrf)
child_prefixes = netaddr.IPSet([p.prefix for p in queryset])
return int(float(child_prefixes.size) / self.prefix.size * 100)

View File

@ -14,6 +14,7 @@ from utilities.views import (
)
from virtualization.models import VirtualMachine
from . import filters, forms, tables
from .choices import PrefixStatusChoices
from .constants import *
from .models import Aggregate, IPAddress, Prefix, RIR, Role, Service, VLAN, VLANGroup, VRF
@ -217,13 +218,13 @@ class RIRListView(PermissionRequiredMixin, ObjectListView):
# Find all consumed space for each prefix status (we ignore containers for this purpose).
active_prefixes = netaddr.cidr_merge(
[p.prefix for p in queryset.filter(status=PREFIX_STATUS_ACTIVE)]
[p.prefix for p in queryset.filter(status=PrefixStatusChoices.STATUS_ACTIVE)]
)
reserved_prefixes = netaddr.cidr_merge(
[p.prefix for p in queryset.filter(status=PREFIX_STATUS_RESERVED)]
[p.prefix for p in queryset.filter(status=PrefixStatusChoices.STATUS_RESERVED)]
)
deprecated_prefixes = netaddr.cidr_merge(
[p.prefix for p in queryset.filter(status=PREFIX_STATUS_DEPRECATED)]
[p.prefix for p in queryset.filter(status=PrefixStatusChoices.STATUS_DEPRECATED)]
)
# Find all available prefixes by subtracting each of the existing prefix sets from the aggregate prefix.