|
|
@@ -1,5 +1,6 @@
|
|
|
import platform
|
|
|
import sys
|
|
|
+from collections import namedtuple
|
|
|
|
|
|
from django.conf import settings
|
|
|
from django.contrib.contenttypes.models import ContentType
|
|
|
@@ -8,6 +9,7 @@ from django.http import HttpResponseServerError
|
|
|
from django.shortcuts import redirect, render
|
|
|
from django.template import loader
|
|
|
from django.template.exceptions import TemplateDoesNotExist
|
|
|
+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
|
|
|
@@ -26,102 +28,91 @@ from netbox.forms import SearchForm
|
|
|
from netbox.search import LookupTypes
|
|
|
from netbox.search.backends import search_backend
|
|
|
from netbox.tables import SearchTable
|
|
|
-from tenancy.models import Tenant
|
|
|
+from tenancy.models import Contact, Tenant
|
|
|
from utilities.htmx import is_htmx
|
|
|
from utilities.paginator import EnhancedPaginator, get_paginate_count
|
|
|
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
|