Skip to content

Commit

Permalink
Fixes #10682: Correct home view links to connection lists
Browse files Browse the repository at this point in the history
  • Loading branch information
jeremystretch committed Oct 26, 2022
1 parent 7b3ef2a commit 658c934
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 63 deletions.
1 change: 1 addition & 0 deletions docs/release-notes/version-3.3.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
* [#10643](https://github.com/netbox-community/netbox/issues/10643) - Ensure consistent display of custom fields for all model forms
* [#10646](https://github.com/netbox-community/netbox/issues/10646) - Fix filtering of power feed by power panel when connecting a cable
* [#10655](https://github.com/netbox-community/netbox/issues/10655) - Correct display of assigned contacts in object tables
* [#10682](https://github.com/netbox-community/netbox/issues/10682) - Correct home view links to connection lists
* [#10712](https://github.com/netbox-community/netbox/issues/10712) - Fix ModuleNotFoundError exception when generating API schema under Python 3.9+
* [#10716](https://github.com/netbox-community/netbox/issues/10716) - Add left/right page plugin content embeds for tag view
* [#10719](https://github.com/netbox-community/netbox/issues/10719) - Prevent user without sufficient permission from creating an IP address via FHRP group creation
Expand Down
114 changes: 53 additions & 61 deletions netbox/netbox/views/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import platform
import sys
from collections import namedtuple

from django.conf import settings
from django.core.cache import cache
Expand All @@ -8,6 +9,7 @@
from django.template import loader
from django.template.exceptions import TemplateDoesNotExist
from django.urls import reverse
from django.utils.translation import gettext as _
from django.views.decorators.csrf import requires_csrf_token
from django.views.defaults import ERROR_500_TEMPLATE_NAME, page_not_found
from django.views.generic import View
Expand All @@ -24,100 +26,90 @@
from netbox.constants import SEARCH_MAX_RESULTS
from netbox.forms import SearchForm
from netbox.search import SEARCH_TYPES
from tenancy.models import Tenant
from tenancy.models import Contact, Tenant
from virtualization.models import Cluster, VirtualMachine
from wireless.models import WirelessLAN, WirelessLink


Link = namedtuple('Link', ('label', 'viewname', 'permission', 'count'))


class HomeView(View):
template_name = 'home.html'

def get(self, request):
if settings.LOGIN_REQUIRED and not request.user.is_authenticated:
return redirect("login")
return redirect('login')

connected_consoleports = ConsolePort.objects.restrict(request.user, 'view').prefetch_related('_path').filter(
console_connections = ConsolePort.objects.restrict(request.user, 'view').prefetch_related('_path').filter(
_path__is_complete=True
)
connected_powerports = PowerPort.objects.restrict(request.user, 'view').prefetch_related('_path').filter(
).count
power_connections = PowerPort.objects.restrict(request.user, 'view').prefetch_related('_path').filter(
_path__is_complete=True
)
connected_interfaces = Interface.objects.restrict(request.user, 'view').prefetch_related('_path').filter(
).count
interface_connections = Interface.objects.restrict(request.user, 'view').prefetch_related('_path').filter(
_path__is_complete=True
)
).count

def get_count_queryset(model):
return model.objects.restrict(request.user, 'view').count

def build_stats():
org = (
("dcim.view_site", "Sites", Site.objects.restrict(request.user, 'view').count),
("tenancy.view_tenant", "Tenants", Tenant.objects.restrict(request.user, 'view').count),
Link(_('Sites'), 'dcim:site_list', 'dcim.view_site', get_count_queryset(Site)),
Link(_('Tenants'), 'tenancy:tenant_list', 'tenancy.view_tenant', get_count_queryset(Tenant)),
Link(_('Contacts'), 'tenancy:contact_list', 'tenancy.view_contact', get_count_queryset(Contact)),
)
dcim = (
("dcim.view_rack", "Racks", Rack.objects.restrict(request.user, 'view').count),
("dcim.view_devicetype", "Device Types", DeviceType.objects.restrict(request.user, 'view').count),
("dcim.view_device", "Devices", Device.objects.restrict(request.user, 'view').count),
Link(_('Racks'), 'dcim:rack_list', 'dcim.view_rack', get_count_queryset(Rack)),
Link(_('Device Types'), 'dcim:devicetype_list', 'dcim.view_devicetype', get_count_queryset(DeviceType)),
Link(_('Devices'), 'dcim:device_list', 'dcim.view_device', get_count_queryset(Device)),
)
ipam = (
("ipam.view_vrf", "VRFs", VRF.objects.restrict(request.user, 'view').count),
("ipam.view_aggregate", "Aggregates", Aggregate.objects.restrict(request.user, 'view').count),
("ipam.view_prefix", "Prefixes", Prefix.objects.restrict(request.user, 'view').count),
("ipam.view_iprange", "IP Ranges", IPRange.objects.restrict(request.user, 'view').count),
("ipam.view_ipaddress", "IP Addresses", IPAddress.objects.restrict(request.user, 'view').count),
("ipam.view_vlan", "VLANs", VLAN.objects.restrict(request.user, 'view').count)

Link(_('VRFs'), 'ipam:vrf_list', 'ipam.view_vrf', get_count_queryset(VRF)),
Link(_('Aggregates'), 'ipam:aggregate_list', 'ipam.view_aggregate', get_count_queryset(Aggregate)),
Link(_('Prefixes'), 'ipam:prefix_list', 'ipam.view_prefix', get_count_queryset(Prefix)),
Link(_('IP Ranges'), 'ipam:iprange_list', 'ipam.view_iprange', get_count_queryset(IPRange)),
Link(_('IP Addresses'), 'ipam:ipaddress_list', 'ipam.view_ipaddress', get_count_queryset(IPAddress)),
Link(_('VLANs'), 'ipam:vlan_list', 'ipam.view_vlan', get_count_queryset(VLAN)),
)
circuits = (
("circuits.view_provider", "Providers", Provider.objects.restrict(request.user, 'view').count),
("circuits.view_circuit", "Circuits", Circuit.objects.restrict(request.user, 'view').count),
Link(_('Providers'), 'circuits:provider_list', 'circuits.view_provider', get_count_queryset(Provider)),
Link(_('Circuits'), 'circuits:circuit_list', 'circuits.view_circuit', get_count_queryset(Circuit))
)
virtualization = (
("virtualization.view_cluster", "Clusters", Cluster.objects.restrict(request.user, 'view').count),
("virtualization.view_virtualmachine", "Virtual Machines", VirtualMachine.objects.restrict(request.user, 'view').count),

Link(_('Clusters'), 'virtualization:cluster_list', 'virtualization.view_cluster',
get_count_queryset(Cluster)),
Link(_('Virtual Machines'), 'virtualization:virtualmachine_list', 'virtualization.view_virtualmachine',
get_count_queryset(VirtualMachine)),
)
connections = (
("dcim.view_cable", "Cables", Cable.objects.restrict(request.user, 'view').count),
("dcim.view_consoleport", "Console", connected_consoleports.count),
("dcim.view_interface", "Interfaces", connected_interfaces.count),
("dcim.view_powerport", "Power Connections", connected_powerports.count),
Link(_('Cables'), 'dcim:cable_list', 'dcim.view_cable', get_count_queryset(Cable)),
Link(_('Interfaces'), 'dcim:interface_connections_list', 'dcim.view_interface', interface_connections),
Link(_('Console'), 'dcim:console_connections_list', 'dcim.view_consoleport', console_connections),
Link(_('Power'), 'dcim:power_connections_list', 'dcim.view_powerport', power_connections),
)
power = (
("dcim.view_powerpanel", "Power Panels", PowerPanel.objects.restrict(request.user, 'view').count),
("dcim.view_powerfeed", "Power Feeds", PowerFeed.objects.restrict(request.user, 'view').count),
Link(_('Power Panels'), 'dcim:powerpanel_list', 'dcim.view_powerpanel', get_count_queryset(PowerPanel)),
Link(_('Power Feeds'), 'dcim:powerfeed_list', 'dcim.view_powerfeed', get_count_queryset(PowerFeed)),
)
wireless = (
("wireless.view_wirelesslan", "Wireless LANs", WirelessLAN.objects.restrict(request.user, 'view').count),
("wireless.view_wirelesslink", "Wireless Links", WirelessLink.objects.restrict(request.user, 'view').count),
Link(_('Wireless LANs'), 'wireless:wirelesslan_list', 'wireless.view_wirelesslan',
get_count_queryset(WirelessLAN)),
Link(_('Wireless Links'), 'wireless:wirelesslink_list', 'wireless.view_wirelesslink',
get_count_queryset(WirelessLink)),
)
sections = (
("Organization", org, "domain"),
("IPAM", ipam, "counter"),
("Virtualization", virtualization, "monitor"),
("Inventory", dcim, "server"),
("Circuits", circuits, "transit-connection-variant"),
("Connections", connections, "cable-data"),
("Power", power, "flash"),
("Wireless", wireless, "wifi"),
stats = (
(_('Organization'), org, 'domain'),
(_('IPAM'), ipam, 'counter'),
(_('Virtualization'), virtualization, 'monitor'),
(_('Inventory'), dcim, 'server'),
(_('Circuits'), circuits, 'transit-connection-variant'),
(_('Connections'), connections, 'cable-data'),
(_('Power'), power, 'flash'),
(_('Wireless'), wireless, 'wifi'),
)

stats = []
for section_label, section_items, icon_class in sections:
items = []
for perm, item_label, get_count in section_items:
app, scope = perm.split(".")
url = ":".join((app, scope.replace("view_", "") + "_list"))
item = {
"label": item_label,
"count": None,
"url": url,
"disabled": True,
"icon": icon_class,
}
if request.user.has_perm(perm):
item["count"] = get_count()
item["disabled"] = False
items.append(item)
stats.append((section_label, items, icon_class))

return stats

# Compile changelog table
Expand Down
4 changes: 2 additions & 2 deletions netbox/templates/home.html
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@ <h6 class="card-header text-center">
<div class="card-body">
<div class="list-group list-group-flush">
{% for item in items %}
{% if not item.disabled %}
<a href="{% url item.url %}" class="list-group-item list-group-item-action">
{% if item.permission in perms %}
<a href="{% url item.viewname %}" class="list-group-item list-group-item-action">
<div class="d-flex w-100 justify-content-between align-items-center">
{{ item.label }}
<h4 class="mb-1">{{ item.count }}</h4>
Expand Down

0 comments on commit 658c934

Please sign in to comment.