Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion netbox/ipam/api/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -218,12 +218,13 @@ class VLANGroupSerializer(NetBoxModelSerializer):
scope_id = serializers.IntegerField(allow_null=True, required=False, default=None)
scope = serializers.SerializerMethodField(read_only=True)
vlan_count = serializers.IntegerField(read_only=True)
utilization = serializers.CharField(read_only=True)

class Meta:
model = VLANGroup
fields = [
'id', 'url', 'display', 'name', 'slug', 'scope_type', 'scope_id', 'scope', 'min_vid', 'max_vid',
'description', 'tags', 'custom_fields', 'created', 'last_updated', 'vlan_count',
'description', 'tags', 'custom_fields', 'created', 'last_updated', 'vlan_count', 'utilization'
]
validators = []

Expand Down
6 changes: 3 additions & 3 deletions netbox/ipam/api/views.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
from django.core.exceptions import ObjectDoesNotExist, PermissionDenied
from django.db import transaction
from django.db.models import F
from django.db.models.functions import Round
from django.shortcuts import get_object_or_404
from django_pglocks import advisory_lock
from drf_spectacular.utils import extend_schema
Expand Down Expand Up @@ -145,9 +147,7 @@ class FHRPGroupAssignmentViewSet(NetBoxModelViewSet):


class VLANGroupViewSet(NetBoxModelViewSet):
queryset = VLANGroup.objects.annotate(
vlan_count=count_related(VLAN, 'group')
).prefetch_related('tags')
queryset = VLANGroup.objects.annotate_utilization().prefetch_related('tags')
serializer_class = serializers.VLANGroupSerializer
filterset_class = filtersets.VLANGroupFilterSet

Expand Down
4 changes: 3 additions & 1 deletion netbox/ipam/models/vlans.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
from dcim.models import Interface
from ipam.choices import *
from ipam.constants import *
from ipam.querysets import VLANQuerySet
from ipam.querysets import VLANQuerySet, VLANGroupQuerySet
from netbox.models import OrganizationalModel, PrimaryModel
from virtualization.models import VMInterface

Expand Down Expand Up @@ -63,6 +63,8 @@ class VLANGroup(OrganizationalModel):
help_text=_('Highest permissible ID of a child VLAN')
)

objects = VLANGroupQuerySet.as_manager()

class Meta:
ordering = ('name', 'pk') # Name may be non-unique
constraints = (
Expand Down
15 changes: 14 additions & 1 deletion netbox/ipam/querysets.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
from django.contrib.contenttypes.models import ContentType
from django.db.models import Count, OuterRef, Q, Subquery, Value
from django.db.models import Count, F, OuterRef, Q, Subquery, Value
from django.db.models.expressions import RawSQL
from django.db.models.functions import Round

from utilities.querysets import RestrictedQuerySet
from utilities.utils import count_related

__all__ = (
'ASNRangeQuerySet',
Expand Down Expand Up @@ -54,6 +56,17 @@ def annotate_hierarchy(self):
)


class VLANGroupQuerySet(RestrictedQuerySet):

def annotate_utilization(self):
from .models import VLAN

return self.annotate(
vlan_count=count_related(VLAN, 'group'),
utilization=Round(F('vlan_count') / (F('max_vid') - F('min_vid') + 1.0) * 100, 2)
)


class VLANQuerySet(RestrictedQuerySet):

def get_for_device(self, device):
Expand Down
8 changes: 6 additions & 2 deletions netbox/ipam/tables/vlans.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,10 @@ class VLANGroupTable(NetBoxTable):
url_params={'group_id': 'pk'},
verbose_name='VLANs'
)
utilization = columns.UtilizationColumn(
orderable=False,
verbose_name='Utilization'
)
tags = columns.TagColumn(
url_name='ipam:vlangroup_list'
)
Expand All @@ -81,9 +85,9 @@ class Meta(NetBoxTable.Meta):
model = VLANGroup
fields = (
'pk', 'id', 'name', 'scope_type', 'scope', 'min_vid', 'max_vid', 'vlan_count', 'slug', 'description',
'tags', 'created', 'last_updated', 'actions',
'tags', 'created', 'last_updated', 'actions', 'utilization',
)
default_columns = ('pk', 'name', 'scope_type', 'scope', 'vlan_count', 'description')
default_columns = ('pk', 'name', 'scope_type', 'scope', 'vlan_count', 'utilization', 'description')


#
Expand Down
17 changes: 6 additions & 11 deletions netbox/ipam/views.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from django.contrib.contenttypes.models import ContentType
from django.db.models import Prefetch
from django.db.models import F, Prefetch
from django.db.models.expressions import RawSQL
from django.db.models.functions import Round
from django.shortcuts import get_object_or_404, redirect, render
from django.urls import reverse
from django.utils.translation import gettext as _
Expand Down Expand Up @@ -882,17 +883,15 @@ def get_children(self, request, parent):
#

class VLANGroupListView(generic.ObjectListView):
queryset = VLANGroup.objects.annotate(
vlan_count=count_related(VLAN, 'group')
)
queryset = VLANGroup.objects.annotate_utilization().prefetch_related('tags')
filterset = filtersets.VLANGroupFilterSet
filterset_form = forms.VLANGroupFilterForm
table = tables.VLANGroupTable


@register_model_view(VLANGroup)
class VLANGroupView(generic.ObjectView):
queryset = VLANGroup.objects.all()
queryset = VLANGroup.objects.annotate_utilization().prefetch_related('tags')

def get_extra_context(self, request, instance):
related_models = (
Expand Down Expand Up @@ -934,18 +933,14 @@ class VLANGroupBulkImportView(generic.BulkImportView):


class VLANGroupBulkEditView(generic.BulkEditView):
queryset = VLANGroup.objects.annotate(
vlan_count=count_related(VLAN, 'group')
)
queryset = VLANGroup.objects.annotate_utilization().prefetch_related('tags')
filterset = filtersets.VLANGroupFilterSet
table = tables.VLANGroupTable
form = forms.VLANGroupBulkEditForm


class VLANGroupBulkDeleteView(generic.BulkDeleteView):
queryset = VLANGroup.objects.annotate(
vlan_count=count_related(VLAN, 'group')
)
queryset = VLANGroup.objects.annotate_utilization().prefetch_related('tags')
filterset = filtersets.VLANGroupFilterSet
table = tables.VLANGroupTable

Expand Down
4 changes: 4 additions & 0 deletions netbox/templates/ipam/vlangroup.html
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,10 @@ <h5 class="card-header">VLAN Group</h5>
<th scope="row">Permitted VIDs</th>
<td>{{ object.min_vid }} - {{ object.max_vid }}</td>
</tr>
<tr>
<th scope="row">Utilization</th>
<td>{% utilization_graph object.utilization %}</td>
</tr>
</table>
</div>
</div>
Expand Down