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

Closes #5139: Omit utilization statistics from RIR list

This commit is contained in:
Jeremy Stretch
2020-10-20 13:16:35 -04:00
parent 9cbfc0ce9a
commit 2e558ba031
4 changed files with 2 additions and 139 deletions

View File

@ -62,6 +62,7 @@ All end-to-end cable paths are now cached using the new CablePath model. This al
* [#4878](https://github.com/netbox-community/netbox/issues/4878) - Custom field data is now stored directly on each object
* [#4941](https://github.com/netbox-community/netbox/issues/4941) - `commit` argument is now required argument in a custom script's `run()` method
* [#5011](https://github.com/netbox-community/netbox/issues/5011) - Standardized name field lengths across all models
* [#5139](https://github.com/netbox-community/netbox/issues/5139) - Omit utilization statistics from RIR list
* [#5225](https://github.com/netbox-community/netbox/issues/5225) - Circuit termination port speed is now an optional field
### REST API Changes

View File

@ -12,25 +12,6 @@ from .models import Aggregate, IPAddress, Prefix, RIR, Role, RouteTarget, Servic
AVAILABLE_LABEL = mark_safe('<span class="label label-success">Available</span>')
RIR_UTILIZATION = """
<div class="progress">
{% if record.stats.total %}
<div class="progress-bar" role="progressbar" style="width: {{ record.stats.percentages.active }}%;">
<span class="sr-only">{{ record.stats.percentages.active }}%</span>
</div>
<div class="progress-bar progress-bar-info" role="progressbar" style="width: {{ record.stats.percentages.reserved }}%;">
<span class="sr-only">{{ record.stats.percentages.reserved }}%</span>
</div>
<div class="progress-bar progress-bar-danger" role="progressbar" style="width: {{ record.stats.percentages.deprecated }}%;">
<span class="sr-only">{{ record.stats.percentages.deprecated }}%</span>
</div>
<div class="progress-bar progress-bar-success" role="progressbar" style="width: {{ record.stats.percentages.available }}%;">
<span class="sr-only">{{ record.stats.percentages.available }}%</span>
</div>
{% endif %}
</div>
"""
UTILIZATION_GRAPH = """
{% load helpers %}
{% if record.pk %}{% utilization_graph record.get_utilization %}{% else %}&mdash;{% endif %}
@ -202,48 +183,6 @@ class RIRTable(BaseTable):
default_columns = ('pk', 'name', 'is_private', 'aggregate_count', 'description', 'actions')
class RIRDetailTable(RIRTable):
stats_total = tables.Column(
accessor='stats.total',
verbose_name='Total',
footer=lambda table: sum(r.stats['total'] for r in table.data)
)
stats_active = tables.Column(
accessor='stats.active',
verbose_name='Active',
footer=lambda table: sum(r.stats['active'] for r in table.data)
)
stats_reserved = tables.Column(
accessor='stats.reserved',
verbose_name='Reserved',
footer=lambda table: sum(r.stats['reserved'] for r in table.data)
)
stats_deprecated = tables.Column(
accessor='stats.deprecated',
verbose_name='Deprecated',
footer=lambda table: sum(r.stats['deprecated'] for r in table.data)
)
stats_available = tables.Column(
accessor='stats.available',
verbose_name='Available',
footer=lambda table: sum(r.stats['available'] for r in table.data)
)
utilization = tables.TemplateColumn(
template_code=RIR_UTILIZATION,
verbose_name='Utilization'
)
class Meta(RIRTable.Meta):
fields = (
'pk', 'name', 'slug', 'is_private', 'aggregate_count', 'stats_total', 'stats_active', 'stats_reserved',
'stats_deprecated', 'stats_available', 'utilization', 'actions',
)
default_columns = (
'pk', 'name', 'is_private', 'aggregate_count', 'stats_total', 'stats_active', 'stats_reserved',
'stats_deprecated', 'stats_available', 'utilization', 'actions',
)
#
# Aggregates
#

View File

@ -154,79 +154,9 @@ class RIRListView(ObjectListView):
queryset = RIR.objects.annotate(aggregate_count=Count('aggregates')).order_by(*RIR._meta.ordering)
filterset = filters.RIRFilterSet
filterset_form = forms.RIRFilterForm
table = tables.RIRDetailTable
table = tables.RIRTable
template_name = 'ipam/rir_list.html'
def alter_queryset(self, request):
if request.GET.get('family') == '6':
family = 6
denominator = 2 ** 64 # Count /64s for IPv6 rather than individual IPs
else:
family = 4
denominator = 1
rirs = []
for rir in self.queryset:
stats = {
'total': 0,
'active': 0,
'reserved': 0,
'deprecated': 0,
'available': 0,
}
aggregate_list = Aggregate.objects.restrict(request.user).filter(prefix__family=family, rir=rir)
for aggregate in aggregate_list:
queryset = Prefix.objects.restrict(request.user).filter(
prefix__net_contained_or_equal=str(aggregate.prefix)
)
# 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=PrefixStatusChoices.STATUS_ACTIVE)]
)
reserved_prefixes = netaddr.cidr_merge(
[p.prefix for p in queryset.filter(status=PrefixStatusChoices.STATUS_RESERVED)]
)
deprecated_prefixes = netaddr.cidr_merge(
[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.
available_prefixes = (
netaddr.IPSet([aggregate.prefix]) -
netaddr.IPSet(active_prefixes) -
netaddr.IPSet(reserved_prefixes) -
netaddr.IPSet(deprecated_prefixes)
)
# Add the size of each metric to the RIR total.
stats['total'] += int(aggregate.prefix.size / denominator)
stats['active'] += int(netaddr.IPSet(active_prefixes).size / denominator)
stats['reserved'] += int(netaddr.IPSet(reserved_prefixes).size / denominator)
stats['deprecated'] += int(netaddr.IPSet(deprecated_prefixes).size / denominator)
stats['available'] += int(available_prefixes.size / denominator)
# Calculate the percentage of total space for each prefix status.
total = float(stats['total'])
stats['percentages'] = {
'active': float('{:.2f}'.format(stats['active'] / total * 100)) if total else 0,
'reserved': float('{:.2f}'.format(stats['reserved'] / total * 100)) if total else 0,
'deprecated': float('{:.2f}'.format(stats['deprecated'] / total * 100)) if total else 0,
}
stats['percentages']['available'] = (
100 -
stats['percentages']['active'] -
stats['percentages']['reserved'] -
stats['percentages']['deprecated']
)
rir.stats = stats
rirs.append(rir)
return rirs
class RIREditView(ObjectEditView):
queryset = RIR.objects.all()

View File

@ -283,9 +283,6 @@ class ObjectListView(ObjectPermissionRequiredMixin, View):
response['Content-Disposition'] = 'attachment; filename="{}"'.format(filename)
return response
# Provide a hook to tweak the queryset based on the request immediately prior to rendering the object list
self.queryset = self.alter_queryset(request)
# Compile a dictionary indicating which permissions are available to the current user for this model
permissions = {}
for action in ('add', 'change', 'delete', 'view'):
@ -337,10 +334,6 @@ class ObjectListView(ObjectPermissionRequiredMixin, View):
return redirect(request.get_full_path())
def alter_queryset(self, request):
# .all() is necessary to avoid caching queries
return self.queryset.all()
def extra_context(self):
return {}