From d6fda266d40146e2b2ba80409a39fd08c340150d Mon Sep 17 00:00:00 2001 From: Abhimanyu Saharan Date: Sat, 13 May 2023 03:23:26 +0530 Subject: [PATCH] adds db annotation to calculate utilization --- netbox/ipam/api/serializers.py | 2 +- netbox/ipam/api/views.py | 4 +++- netbox/ipam/models/vlans.py | 9 --------- netbox/ipam/tables/vlans.py | 6 +++--- netbox/ipam/views.py | 21 +++++++++++++-------- netbox/templates/ipam/vlangroup.html | 6 ++---- 6 files changed, 22 insertions(+), 26 deletions(-) diff --git a/netbox/ipam/api/serializers.py b/netbox/ipam/api/serializers.py index a5605751c..1501f16dc 100644 --- a/netbox/ipam/api/serializers.py +++ b/netbox/ipam/api/serializers.py @@ -218,7 +218,7 @@ 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(source='get_utilization', read_only=True) + utilization = serializers.CharField(read_only=True) class Meta: model = VLANGroup diff --git a/netbox/ipam/api/views.py b/netbox/ipam/api/views.py index f432e0e6b..266461654 100644 --- a/netbox/ipam/api/views.py +++ b/netbox/ipam/api/views.py @@ -1,5 +1,6 @@ from django.core.exceptions import ObjectDoesNotExist, PermissionDenied from django.db import transaction +from django.db.models import F from django.shortcuts import get_object_or_404 from django_pglocks import advisory_lock from drf_spectacular.utils import extend_schema @@ -146,7 +147,8 @@ class FHRPGroupAssignmentViewSet(NetBoxModelViewSet): class VLANGroupViewSet(NetBoxModelViewSet): queryset = VLANGroup.objects.annotate( - vlan_count=count_related(VLAN, 'group') + vlan_count=count_related(VLAN, 'group'), + utilization=count_related(VLAN, 'group') / (F('max_vid') - F('min_vid') + 1.0) * 100 ).prefetch_related('tags') serializer_class = serializers.VLANGroupSerializer filterset_class = filtersets.VLANGroupFilterSet diff --git a/netbox/ipam/models/vlans.py b/netbox/ipam/models/vlans.py index 90bb73f5c..7d4777da9 100644 --- a/netbox/ipam/models/vlans.py +++ b/netbox/ipam/models/vlans.py @@ -114,15 +114,6 @@ class VLANGroup(OrganizationalModel): return available_vids[0] return None - def get_utilization(self): - """ - Return the percentage of utilization for this vlan group. - """ - assigned_vlan = VLAN.objects.filter(group=self.id).count() - if assigned_vlan != 0: - return round(assigned_vlan / (self.max_vid - self.min_vid + 1) * 100, 2) - return 0.0 - class VLAN(PrimaryModel): """ diff --git a/netbox/ipam/tables/vlans.py b/netbox/ipam/tables/vlans.py index b2d9d5c2b..5d9828531 100644 --- a/netbox/ipam/tables/vlans.py +++ b/netbox/ipam/tables/vlans.py @@ -70,7 +70,7 @@ class VLANGroupTable(NetBoxTable): url_params={'group_id': 'pk'}, verbose_name='VLANs' ) - get_utilization = columns.UtilizationColumn( + utilization = columns.UtilizationColumn( orderable=False, verbose_name='Utilization' ) @@ -85,9 +85,9 @@ class VLANGroupTable(NetBoxTable): model = VLANGroup fields = ( 'pk', 'id', 'name', 'scope_type', 'scope', 'min_vid', 'max_vid', 'vlan_count', 'slug', 'description', - 'tags', 'created', 'last_updated', 'actions', 'get_utilization', + 'tags', 'created', 'last_updated', 'actions', 'utilization', ) - default_columns = ('pk', 'name', 'scope_type', 'scope', 'vlan_count', 'get_utilization', 'description') + default_columns = ('pk', 'name', 'scope_type', 'scope', 'vlan_count', 'utilization', 'description') # diff --git a/netbox/ipam/views.py b/netbox/ipam/views.py index a49c4aab3..c9f488acf 100644 --- a/netbox/ipam/views.py +++ b/netbox/ipam/views.py @@ -1,5 +1,5 @@ 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.shortcuts import get_object_or_404, redirect, render from django.urls import reverse @@ -877,8 +877,9 @@ class IPAddressBulkDeleteView(generic.BulkDeleteView): class VLANGroupListView(generic.ObjectListView): queryset = VLANGroup.objects.annotate( - vlan_count=count_related(VLAN, 'group') - ) + vlan_count=count_related(VLAN, 'group'), + utilization=count_related(VLAN, 'group') / (F('max_vid') - F('min_vid') + 1.0) * 100 + ).prefetch_related('tags') filterset = filtersets.VLANGroupFilterSet filterset_form = forms.VLANGroupFilterForm table = tables.VLANGroupTable @@ -886,7 +887,9 @@ class VLANGroupListView(generic.ObjectListView): @register_model_view(VLANGroup) class VLANGroupView(generic.ObjectView): - queryset = VLANGroup.objects.all() + queryset = VLANGroup.objects.annotate( + utilization=count_related(VLAN, 'group') / (F('max_vid') - F('min_vid') + 1.0) * 100 + ).prefetch_related('tags') def get_extra_context(self, request, instance): related_models = ( @@ -929,8 +932,9 @@ class VLANGroupBulkImportView(generic.BulkImportView): class VLANGroupBulkEditView(generic.BulkEditView): queryset = VLANGroup.objects.annotate( - vlan_count=count_related(VLAN, 'group') - ) + vlan_count=count_related(VLAN, 'group'), + utilization=count_related(VLAN, 'group') / (F('max_vid') - F('min_vid') + 1.0) * 100 + ).prefetch_related('tags') filterset = filtersets.VLANGroupFilterSet table = tables.VLANGroupTable form = forms.VLANGroupBulkEditForm @@ -938,8 +942,9 @@ class VLANGroupBulkEditView(generic.BulkEditView): class VLANGroupBulkDeleteView(generic.BulkDeleteView): queryset = VLANGroup.objects.annotate( - vlan_count=count_related(VLAN, 'group') - ) + vlan_count=count_related(VLAN, 'group'), + utilization=count_related(VLAN, 'group') / (F('max_vid') - F('min_vid') + 1.0) * 100 + ).prefetch_related('tags') filterset = filtersets.VLANGroupFilterSet table = tables.VLANGroupTable diff --git a/netbox/templates/ipam/vlangroup.html b/netbox/templates/ipam/vlangroup.html index 822b4a046..7decbb983 100644 --- a/netbox/templates/ipam/vlangroup.html +++ b/netbox/templates/ipam/vlangroup.html @@ -43,10 +43,8 @@ {{ object.min_vid }} - {{ object.max_vid }} - VLANs - - {{ vlans_count }} - + Utilization + {% utilization_graph object.utilization %}