Parcourir la source

Closes #1298: Calculate prefix utilization based on its status (container or non-container)

Jeremy Stretch il y a 7 ans
Parent
commit
3f82be7192
2 fichiers modifiés avec 19 ajouts et 15 suppressions
  1. 18 14
      netbox/ipam/models.py
  2. 1 1
      netbox/ipam/tables.py

+ 18 - 14
netbox/ipam/models.py

@@ -1,6 +1,6 @@
 from __future__ import unicode_literals
 
-from netaddr import IPNetwork, cidr_merge
+from netaddr import IPNetwork, IPSet
 
 from django.conf import settings
 from django.contrib.contenttypes.fields import GenericRelation
@@ -206,13 +206,9 @@ class Aggregate(CreatedUpdatedModel, CustomFieldModel):
         """
         Determine the prefix utilization of the aggregate and return it as a percentage.
         """
-        child_prefixes = Prefix.objects.filter(prefix__net_contained_or_equal=str(self.prefix))
-        # Remove overlapping prefixes from list of children
-        networks = cidr_merge([c.prefix for c in child_prefixes])
-        children_size = float(0)
-        for p in networks:
-            children_size += p.size
-        return int(children_size / self.prefix.size * 100)
+        queryset = Prefix.objects.filter(prefix__net_contained_or_equal=str(self.prefix))
+        child_prefixes = IPSet([p.prefix for p in queryset])
+        return int(float(child_prefixes.size) / self.prefix.size * 100)
 
 
 @python_2_unicode_compatible
@@ -370,13 +366,21 @@ class Prefix(CreatedUpdatedModel, CustomFieldModel):
 
     def get_utilization(self):
         """
-        Determine the utilization of the prefix and return it as a percentage.
+        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.
         """
-        child_count = IPAddress.objects.filter(address__net_contained_or_equal=str(self.prefix), vrf=self.vrf).count()
-        prefix_size = self.prefix.size
-        if self.family == 4 and self.prefix.prefixlen < 31 and not self.is_pool:
-            prefix_size -= 2
-        return int(float(child_count) / prefix_size * 100)
+        if self.status == PREFIX_STATUS_CONTAINER:
+            queryset = Prefix.objects.filter(prefix__net_contained=str(self.prefix), vrf=self.vrf)
+            child_prefixes = IPSet([p.prefix for p in queryset])
+            return int(float(child_prefixes.size) / self.prefix.size * 100)
+        else:
+            child_count = IPAddress.objects.filter(
+                address__net_contained_or_equal=str(self.prefix), vrf=self.vrf
+            ).count()
+            prefix_size = self.prefix.size
+            if self.family == 4 and self.prefix.prefixlen < 31 and not self.is_pool:
+                prefix_size -= 2
+            return int(float(child_count) / prefix_size * 100)
 
     @property
     def new_subnet(self):

+ 1 - 1
netbox/ipam/tables.py

@@ -241,7 +241,7 @@ class PrefixTable(BaseTable):
     prefix = tables.TemplateColumn(PREFIX_LINK, attrs={'th': {'style': 'padding-left: 17px'}})
     status = tables.TemplateColumn(STATUS_LABEL)
     vrf = tables.TemplateColumn(VRF_LINK, verbose_name='VRF')
-    get_utilization = tables.TemplateColumn(UTILIZATION_GRAPH, orderable=False, verbose_name='IP Usage')
+    get_utilization = tables.TemplateColumn(UTILIZATION_GRAPH, orderable=False, verbose_name='Utilization')
     tenant = tables.TemplateColumn(TENANT_LINK)
     site = tables.LinkColumn('dcim:site', args=[Accessor('site.slug')])
     vlan = tables.LinkColumn('ipam:vlan', args=[Accessor('vlan.pk')], verbose_name='VLAN')