mirror of
https://github.com/netbox-community/netbox.git
synced 2025-07-16 12:12:53 -06:00
Converted all object views to class-based views
This commit is contained in:
parent
c454bfcd84
commit
fb85867d72
@ -12,7 +12,7 @@ urlpatterns = [
|
|||||||
url(r'^providers/import/$', views.ProviderBulkImportView.as_view(), name='provider_import'),
|
url(r'^providers/import/$', views.ProviderBulkImportView.as_view(), name='provider_import'),
|
||||||
url(r'^providers/edit/$', views.ProviderBulkEditView.as_view(), name='provider_bulk_edit'),
|
url(r'^providers/edit/$', views.ProviderBulkEditView.as_view(), name='provider_bulk_edit'),
|
||||||
url(r'^providers/delete/$', views.ProviderBulkDeleteView.as_view(), name='provider_bulk_delete'),
|
url(r'^providers/delete/$', views.ProviderBulkDeleteView.as_view(), name='provider_bulk_delete'),
|
||||||
url(r'^providers/(?P<slug>[\w-]+)/$', views.provider, name='provider'),
|
url(r'^providers/(?P<slug>[\w-]+)/$', views.ProviderView.as_view(), name='provider'),
|
||||||
url(r'^providers/(?P<slug>[\w-]+)/edit/$', views.ProviderEditView.as_view(), name='provider_edit'),
|
url(r'^providers/(?P<slug>[\w-]+)/edit/$', views.ProviderEditView.as_view(), name='provider_edit'),
|
||||||
url(r'^providers/(?P<slug>[\w-]+)/delete/$', views.ProviderDeleteView.as_view(), name='provider_delete'),
|
url(r'^providers/(?P<slug>[\w-]+)/delete/$', views.ProviderDeleteView.as_view(), name='provider_delete'),
|
||||||
|
|
||||||
@ -28,7 +28,7 @@ urlpatterns = [
|
|||||||
url(r'^circuits/import/$', views.CircuitBulkImportView.as_view(), name='circuit_import'),
|
url(r'^circuits/import/$', views.CircuitBulkImportView.as_view(), name='circuit_import'),
|
||||||
url(r'^circuits/edit/$', views.CircuitBulkEditView.as_view(), name='circuit_bulk_edit'),
|
url(r'^circuits/edit/$', views.CircuitBulkEditView.as_view(), name='circuit_bulk_edit'),
|
||||||
url(r'^circuits/delete/$', views.CircuitBulkDeleteView.as_view(), name='circuit_bulk_delete'),
|
url(r'^circuits/delete/$', views.CircuitBulkDeleteView.as_view(), name='circuit_bulk_delete'),
|
||||||
url(r'^circuits/(?P<pk>\d+)/$', views.circuit, name='circuit'),
|
url(r'^circuits/(?P<pk>\d+)/$', views.CircuitView.as_view(), name='circuit'),
|
||||||
url(r'^circuits/(?P<pk>\d+)/edit/$', views.CircuitEditView.as_view(), name='circuit_edit'),
|
url(r'^circuits/(?P<pk>\d+)/edit/$', views.CircuitEditView.as_view(), name='circuit_edit'),
|
||||||
url(r'^circuits/(?P<pk>\d+)/delete/$', views.CircuitDeleteView.as_view(), name='circuit_delete'),
|
url(r'^circuits/(?P<pk>\d+)/delete/$', views.CircuitDeleteView.as_view(), name='circuit_delete'),
|
||||||
url(r'^circuits/(?P<pk>\d+)/terminations/swap/$', views.circuit_terminations_swap, name='circuit_terminations_swap'),
|
url(r'^circuits/(?P<pk>\d+)/terminations/swap/$', views.circuit_terminations_swap, name='circuit_terminations_swap'),
|
||||||
|
@ -5,6 +5,7 @@ from django.db import transaction
|
|||||||
from django.db.models import Count
|
from django.db.models import Count
|
||||||
from django.shortcuts import get_object_or_404, redirect, render
|
from django.shortcuts import get_object_or_404, redirect, render
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
|
from django.views.generic import View
|
||||||
|
|
||||||
from extras.models import Graph, GRAPH_TYPE_PROVIDER
|
from extras.models import Graph, GRAPH_TYPE_PROVIDER
|
||||||
from utilities.forms import ConfirmationForm
|
from utilities.forms import ConfirmationForm
|
||||||
@ -28,18 +29,23 @@ class ProviderListView(ObjectListView):
|
|||||||
template_name = 'circuits/provider_list.html'
|
template_name = 'circuits/provider_list.html'
|
||||||
|
|
||||||
|
|
||||||
def provider(request, slug):
|
class ProviderView(View):
|
||||||
|
|
||||||
provider = get_object_or_404(Provider, slug=slug)
|
def get(self, request, slug):
|
||||||
circuits = Circuit.objects.filter(provider=provider).select_related('type', 'tenant')\
|
|
||||||
.prefetch_related('terminations__site')
|
|
||||||
show_graphs = Graph.objects.filter(type=GRAPH_TYPE_PROVIDER).exists()
|
|
||||||
|
|
||||||
return render(request, 'circuits/provider.html', {
|
provider = get_object_or_404(Provider, slug=slug)
|
||||||
'provider': provider,
|
circuits = Circuit.objects.filter(provider=provider).select_related(
|
||||||
'circuits': circuits,
|
'type', 'tenant'
|
||||||
'show_graphs': show_graphs,
|
).prefetch_related(
|
||||||
})
|
'terminations__site'
|
||||||
|
)
|
||||||
|
show_graphs = Graph.objects.filter(type=GRAPH_TYPE_PROVIDER).exists()
|
||||||
|
|
||||||
|
return render(request, 'circuits/provider.html', {
|
||||||
|
'provider': provider,
|
||||||
|
'circuits': circuits,
|
||||||
|
'show_graphs': show_graphs,
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
class ProviderEditView(PermissionRequiredMixin, ObjectEditView):
|
class ProviderEditView(PermissionRequiredMixin, ObjectEditView):
|
||||||
@ -117,25 +123,27 @@ class CircuitListView(ObjectListView):
|
|||||||
template_name = 'circuits/circuit_list.html'
|
template_name = 'circuits/circuit_list.html'
|
||||||
|
|
||||||
|
|
||||||
def circuit(request, pk):
|
class CircuitView(View):
|
||||||
|
|
||||||
circuit = get_object_or_404(Circuit.objects.select_related('provider', 'type', 'tenant__group'), pk=pk)
|
def get(self, request, pk):
|
||||||
termination_a = CircuitTermination.objects.select_related(
|
|
||||||
'site__region', 'interface__device'
|
|
||||||
).filter(
|
|
||||||
circuit=circuit, term_side=TERM_SIDE_A
|
|
||||||
).first()
|
|
||||||
termination_z = CircuitTermination.objects.select_related(
|
|
||||||
'site__region', 'interface__device'
|
|
||||||
).filter(
|
|
||||||
circuit=circuit, term_side=TERM_SIDE_Z
|
|
||||||
).first()
|
|
||||||
|
|
||||||
return render(request, 'circuits/circuit.html', {
|
circuit = get_object_or_404(Circuit.objects.select_related('provider', 'type', 'tenant__group'), pk=pk)
|
||||||
'circuit': circuit,
|
termination_a = CircuitTermination.objects.select_related(
|
||||||
'termination_a': termination_a,
|
'site__region', 'interface__device'
|
||||||
'termination_z': termination_z,
|
).filter(
|
||||||
})
|
circuit=circuit, term_side=TERM_SIDE_A
|
||||||
|
).first()
|
||||||
|
termination_z = CircuitTermination.objects.select_related(
|
||||||
|
'site__region', 'interface__device'
|
||||||
|
).filter(
|
||||||
|
circuit=circuit, term_side=TERM_SIDE_Z
|
||||||
|
).first()
|
||||||
|
|
||||||
|
return render(request, 'circuits/circuit.html', {
|
||||||
|
'circuit': circuit,
|
||||||
|
'termination_a': termination_a,
|
||||||
|
'termination_z': termination_z,
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
class CircuitEditView(PermissionRequiredMixin, ObjectEditView):
|
class CircuitEditView(PermissionRequiredMixin, ObjectEditView):
|
||||||
|
@ -22,7 +22,7 @@ urlpatterns = [
|
|||||||
url(r'^sites/add/$', views.SiteEditView.as_view(), name='site_add'),
|
url(r'^sites/add/$', views.SiteEditView.as_view(), name='site_add'),
|
||||||
url(r'^sites/import/$', views.SiteBulkImportView.as_view(), name='site_import'),
|
url(r'^sites/import/$', views.SiteBulkImportView.as_view(), name='site_import'),
|
||||||
url(r'^sites/edit/$', views.SiteBulkEditView.as_view(), name='site_bulk_edit'),
|
url(r'^sites/edit/$', views.SiteBulkEditView.as_view(), name='site_bulk_edit'),
|
||||||
url(r'^sites/(?P<slug>[\w-]+)/$', views.site, name='site'),
|
url(r'^sites/(?P<slug>[\w-]+)/$', views.SiteView.as_view(), name='site'),
|
||||||
url(r'^sites/(?P<slug>[\w-]+)/edit/$', views.SiteEditView.as_view(), name='site_edit'),
|
url(r'^sites/(?P<slug>[\w-]+)/edit/$', views.SiteEditView.as_view(), name='site_edit'),
|
||||||
url(r'^sites/(?P<slug>[\w-]+)/delete/$', views.SiteDeleteView.as_view(), name='site_delete'),
|
url(r'^sites/(?P<slug>[\w-]+)/delete/$', views.SiteDeleteView.as_view(), name='site_delete'),
|
||||||
url(r'^sites/(?P<object_id>\d+)/images/add/$', ImageAttachmentEditView.as_view(), name='site_add_image', kwargs={'model': Site}),
|
url(r'^sites/(?P<object_id>\d+)/images/add/$', ImageAttachmentEditView.as_view(), name='site_add_image', kwargs={'model': Site}),
|
||||||
@ -52,7 +52,7 @@ urlpatterns = [
|
|||||||
url(r'^racks/import/$', views.RackBulkImportView.as_view(), name='rack_import'),
|
url(r'^racks/import/$', views.RackBulkImportView.as_view(), name='rack_import'),
|
||||||
url(r'^racks/edit/$', views.RackBulkEditView.as_view(), name='rack_bulk_edit'),
|
url(r'^racks/edit/$', views.RackBulkEditView.as_view(), name='rack_bulk_edit'),
|
||||||
url(r'^racks/delete/$', views.RackBulkDeleteView.as_view(), name='rack_bulk_delete'),
|
url(r'^racks/delete/$', views.RackBulkDeleteView.as_view(), name='rack_bulk_delete'),
|
||||||
url(r'^racks/(?P<pk>\d+)/$', views.rack, name='rack'),
|
url(r'^racks/(?P<pk>\d+)/$', views.RackView.as_view(), name='rack'),
|
||||||
url(r'^racks/(?P<pk>\d+)/edit/$', views.RackEditView.as_view(), name='rack_edit'),
|
url(r'^racks/(?P<pk>\d+)/edit/$', views.RackEditView.as_view(), name='rack_edit'),
|
||||||
url(r'^racks/(?P<pk>\d+)/delete/$', views.RackDeleteView.as_view(), name='rack_delete'),
|
url(r'^racks/(?P<pk>\d+)/delete/$', views.RackDeleteView.as_view(), name='rack_delete'),
|
||||||
url(r'^racks/(?P<rack>\d+)/reservations/add/$', views.RackReservationEditView.as_view(), name='rack_add_reservation'),
|
url(r'^racks/(?P<rack>\d+)/reservations/add/$', views.RackReservationEditView.as_view(), name='rack_add_reservation'),
|
||||||
@ -69,7 +69,7 @@ urlpatterns = [
|
|||||||
url(r'^device-types/add/$', views.DeviceTypeEditView.as_view(), name='devicetype_add'),
|
url(r'^device-types/add/$', views.DeviceTypeEditView.as_view(), name='devicetype_add'),
|
||||||
url(r'^device-types/edit/$', views.DeviceTypeBulkEditView.as_view(), name='devicetype_bulk_edit'),
|
url(r'^device-types/edit/$', views.DeviceTypeBulkEditView.as_view(), name='devicetype_bulk_edit'),
|
||||||
url(r'^device-types/delete/$', views.DeviceTypeBulkDeleteView.as_view(), name='devicetype_bulk_delete'),
|
url(r'^device-types/delete/$', views.DeviceTypeBulkDeleteView.as_view(), name='devicetype_bulk_delete'),
|
||||||
url(r'^device-types/(?P<pk>\d+)/$', views.devicetype, name='devicetype'),
|
url(r'^device-types/(?P<pk>\d+)/$', views.DeviceTypeView.as_view(), name='devicetype'),
|
||||||
url(r'^device-types/(?P<pk>\d+)/edit/$', views.DeviceTypeEditView.as_view(), name='devicetype_edit'),
|
url(r'^device-types/(?P<pk>\d+)/edit/$', views.DeviceTypeEditView.as_view(), name='devicetype_edit'),
|
||||||
url(r'^device-types/(?P<pk>\d+)/delete/$', views.DeviceTypeDeleteView.as_view(), name='devicetype_delete'),
|
url(r'^device-types/(?P<pk>\d+)/delete/$', views.DeviceTypeDeleteView.as_view(), name='devicetype_delete'),
|
||||||
|
|
||||||
@ -117,11 +117,11 @@ urlpatterns = [
|
|||||||
url(r'^devices/import/child-devices/$', views.ChildDeviceBulkImportView.as_view(), name='device_import_child'),
|
url(r'^devices/import/child-devices/$', views.ChildDeviceBulkImportView.as_view(), name='device_import_child'),
|
||||||
url(r'^devices/edit/$', views.DeviceBulkEditView.as_view(), name='device_bulk_edit'),
|
url(r'^devices/edit/$', views.DeviceBulkEditView.as_view(), name='device_bulk_edit'),
|
||||||
url(r'^devices/delete/$', views.DeviceBulkDeleteView.as_view(), name='device_bulk_delete'),
|
url(r'^devices/delete/$', views.DeviceBulkDeleteView.as_view(), name='device_bulk_delete'),
|
||||||
url(r'^devices/(?P<pk>\d+)/$', views.device, name='device'),
|
url(r'^devices/(?P<pk>\d+)/$', views.DeviceView.as_view(), name='device'),
|
||||||
url(r'^devices/(?P<pk>\d+)/edit/$', views.DeviceEditView.as_view(), name='device_edit'),
|
url(r'^devices/(?P<pk>\d+)/edit/$', views.DeviceEditView.as_view(), name='device_edit'),
|
||||||
url(r'^devices/(?P<pk>\d+)/delete/$', views.DeviceDeleteView.as_view(), name='device_delete'),
|
url(r'^devices/(?P<pk>\d+)/delete/$', views.DeviceDeleteView.as_view(), name='device_delete'),
|
||||||
url(r'^devices/(?P<pk>\d+)/inventory/$', views.device_inventory, name='device_inventory'),
|
url(r'^devices/(?P<pk>\d+)/inventory/$', views.DeviceInventoryView.as_view(), name='device_inventory'),
|
||||||
url(r'^devices/(?P<pk>\d+)/lldp-neighbors/$', views.device_lldp_neighbors, name='device_lldp_neighbors'),
|
url(r'^devices/(?P<pk>\d+)/lldp-neighbors/$', views.DeviceLLDPNeighborsView.as_view(), name='device_lldp_neighbors'),
|
||||||
url(r'^devices/(?P<pk>\d+)/add-secret/$', secret_add, name='device_addsecret'),
|
url(r'^devices/(?P<pk>\d+)/add-secret/$', secret_add, name='device_addsecret'),
|
||||||
url(r'^devices/(?P<device>\d+)/services/assign/$', ServiceEditView.as_view(), name='service_assign'),
|
url(r'^devices/(?P<device>\d+)/services/assign/$', ServiceEditView.as_view(), name='service_assign'),
|
||||||
url(r'^devices/(?P<object_id>\d+)/images/add/$', ImageAttachmentEditView.as_view(), name='device_add_image', kwargs={'model': Device}),
|
url(r'^devices/(?P<object_id>\d+)/images/add/$', ImageAttachmentEditView.as_view(), name='device_add_image', kwargs={'model': Device}),
|
||||||
|
@ -178,27 +178,29 @@ class SiteListView(ObjectListView):
|
|||||||
template_name = 'dcim/site_list.html'
|
template_name = 'dcim/site_list.html'
|
||||||
|
|
||||||
|
|
||||||
def site(request, slug):
|
class SiteView(View):
|
||||||
|
|
||||||
site = get_object_or_404(Site.objects.select_related('region', 'tenant__group'), slug=slug)
|
def get(self, request, slug):
|
||||||
stats = {
|
|
||||||
'rack_count': Rack.objects.filter(site=site).count(),
|
|
||||||
'device_count': Device.objects.filter(site=site).count(),
|
|
||||||
'prefix_count': Prefix.objects.filter(site=site).count(),
|
|
||||||
'vlan_count': VLAN.objects.filter(site=site).count(),
|
|
||||||
'circuit_count': Circuit.objects.filter(terminations__site=site).count(),
|
|
||||||
}
|
|
||||||
rack_groups = RackGroup.objects.filter(site=site).annotate(rack_count=Count('racks'))
|
|
||||||
topology_maps = TopologyMap.objects.filter(site=site)
|
|
||||||
show_graphs = Graph.objects.filter(type=GRAPH_TYPE_SITE).exists()
|
|
||||||
|
|
||||||
return render(request, 'dcim/site.html', {
|
site = get_object_or_404(Site.objects.select_related('region', 'tenant__group'), slug=slug)
|
||||||
'site': site,
|
stats = {
|
||||||
'stats': stats,
|
'rack_count': Rack.objects.filter(site=site).count(),
|
||||||
'rack_groups': rack_groups,
|
'device_count': Device.objects.filter(site=site).count(),
|
||||||
'topology_maps': topology_maps,
|
'prefix_count': Prefix.objects.filter(site=site).count(),
|
||||||
'show_graphs': show_graphs,
|
'vlan_count': VLAN.objects.filter(site=site).count(),
|
||||||
})
|
'circuit_count': Circuit.objects.filter(terminations__site=site).count(),
|
||||||
|
}
|
||||||
|
rack_groups = RackGroup.objects.filter(site=site).annotate(rack_count=Count('racks'))
|
||||||
|
topology_maps = TopologyMap.objects.filter(site=site)
|
||||||
|
show_graphs = Graph.objects.filter(type=GRAPH_TYPE_SITE).exists()
|
||||||
|
|
||||||
|
return render(request, 'dcim/site.html', {
|
||||||
|
'site': site,
|
||||||
|
'stats': stats,
|
||||||
|
'rack_groups': rack_groups,
|
||||||
|
'topology_maps': topology_maps,
|
||||||
|
'show_graphs': show_graphs,
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
class SiteEditView(PermissionRequiredMixin, ObjectEditView):
|
class SiteEditView(PermissionRequiredMixin, ObjectEditView):
|
||||||
@ -290,8 +292,13 @@ class RackRoleBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
|
|||||||
#
|
#
|
||||||
|
|
||||||
class RackListView(ObjectListView):
|
class RackListView(ObjectListView):
|
||||||
queryset = Rack.objects.select_related('site', 'group', 'tenant', 'role').prefetch_related('devices__device_type')\
|
queryset = Rack.objects.select_related(
|
||||||
.annotate(device_count=Count('devices', distinct=True))
|
'site', 'group', 'tenant', 'role'
|
||||||
|
).prefetch_related(
|
||||||
|
'devices__device_type'
|
||||||
|
).annotate(
|
||||||
|
device_count=Count('devices', distinct=True)
|
||||||
|
)
|
||||||
filter = filters.RackFilter
|
filter = filters.RackFilter
|
||||||
filter_form = forms.RackFilterForm
|
filter_form = forms.RackFilterForm
|
||||||
table = tables.RackTable
|
table = tables.RackTable
|
||||||
@ -338,31 +345,33 @@ class RackElevationListView(View):
|
|||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
def rack(request, pk):
|
class RackView(View):
|
||||||
|
|
||||||
rack = get_object_or_404(Rack.objects.select_related('site__region', 'tenant__group', 'group', 'role'), pk=pk)
|
def get(self, request, pk):
|
||||||
|
|
||||||
nonracked_devices = Device.objects.filter(rack=rack, position__isnull=True, parent_bay__isnull=True)\
|
rack = get_object_or_404(Rack.objects.select_related('site__region', 'tenant__group', 'group', 'role'), pk=pk)
|
||||||
.select_related('device_type__manufacturer')
|
|
||||||
next_rack = Rack.objects.filter(site=rack.site, name__gt=rack.name).order_by('name').first()
|
|
||||||
prev_rack = Rack.objects.filter(site=rack.site, name__lt=rack.name).order_by('-name').first()
|
|
||||||
|
|
||||||
reservations = RackReservation.objects.filter(rack=rack)
|
nonracked_devices = Device.objects.filter(rack=rack, position__isnull=True, parent_bay__isnull=True)\
|
||||||
reserved_units = {}
|
.select_related('device_type__manufacturer')
|
||||||
for r in reservations:
|
next_rack = Rack.objects.filter(site=rack.site, name__gt=rack.name).order_by('name').first()
|
||||||
for u in r.units:
|
prev_rack = Rack.objects.filter(site=rack.site, name__lt=rack.name).order_by('-name').first()
|
||||||
reserved_units[u] = r
|
|
||||||
|
|
||||||
return render(request, 'dcim/rack.html', {
|
reservations = RackReservation.objects.filter(rack=rack)
|
||||||
'rack': rack,
|
reserved_units = {}
|
||||||
'reservations': reservations,
|
for r in reservations:
|
||||||
'reserved_units': reserved_units,
|
for u in r.units:
|
||||||
'nonracked_devices': nonracked_devices,
|
reserved_units[u] = r
|
||||||
'next_rack': next_rack,
|
|
||||||
'prev_rack': prev_rack,
|
return render(request, 'dcim/rack.html', {
|
||||||
'front_elevation': rack.get_front_elevation(),
|
'rack': rack,
|
||||||
'rear_elevation': rack.get_rear_elevation(),
|
'reservations': reservations,
|
||||||
})
|
'reserved_units': reserved_units,
|
||||||
|
'nonracked_devices': nonracked_devices,
|
||||||
|
'next_rack': next_rack,
|
||||||
|
'prev_rack': prev_rack,
|
||||||
|
'front_elevation': rack.get_front_elevation(),
|
||||||
|
'rear_elevation': rack.get_rear_elevation(),
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
class RackEditView(PermissionRequiredMixin, ObjectEditView):
|
class RackEditView(PermissionRequiredMixin, ObjectEditView):
|
||||||
@ -481,53 +490,57 @@ class DeviceTypeListView(ObjectListView):
|
|||||||
template_name = 'dcim/devicetype_list.html'
|
template_name = 'dcim/devicetype_list.html'
|
||||||
|
|
||||||
|
|
||||||
def devicetype(request, pk):
|
class DeviceTypeView(View):
|
||||||
|
|
||||||
devicetype = get_object_or_404(DeviceType, pk=pk)
|
def get(self, request, pk):
|
||||||
|
|
||||||
# Component tables
|
devicetype = get_object_or_404(DeviceType, pk=pk)
|
||||||
consoleport_table = tables.ConsolePortTemplateTable(
|
|
||||||
natsorted(ConsolePortTemplate.objects.filter(device_type=devicetype), key=attrgetter('name'))
|
|
||||||
)
|
|
||||||
consoleserverport_table = tables.ConsoleServerPortTemplateTable(
|
|
||||||
natsorted(ConsoleServerPortTemplate.objects.filter(device_type=devicetype), key=attrgetter('name'))
|
|
||||||
)
|
|
||||||
powerport_table = tables.PowerPortTemplateTable(
|
|
||||||
natsorted(PowerPortTemplate.objects.filter(device_type=devicetype), key=attrgetter('name'))
|
|
||||||
)
|
|
||||||
poweroutlet_table = tables.PowerOutletTemplateTable(
|
|
||||||
natsorted(PowerOutletTemplate.objects.filter(device_type=devicetype), key=attrgetter('name'))
|
|
||||||
)
|
|
||||||
mgmt_interface_table = tables.InterfaceTemplateTable(
|
|
||||||
list(InterfaceTemplate.objects.order_naturally(devicetype.interface_ordering).filter(device_type=devicetype,
|
|
||||||
mgmt_only=True))
|
|
||||||
)
|
|
||||||
interface_table = tables.InterfaceTemplateTable(
|
|
||||||
list(InterfaceTemplate.objects.order_naturally(devicetype.interface_ordering).filter(device_type=devicetype,
|
|
||||||
mgmt_only=False))
|
|
||||||
)
|
|
||||||
devicebay_table = tables.DeviceBayTemplateTable(
|
|
||||||
natsorted(DeviceBayTemplate.objects.filter(device_type=devicetype), key=attrgetter('name'))
|
|
||||||
)
|
|
||||||
if request.user.has_perm('dcim.change_devicetype'):
|
|
||||||
consoleport_table.base_columns['pk'].visible = True
|
|
||||||
consoleserverport_table.base_columns['pk'].visible = True
|
|
||||||
powerport_table.base_columns['pk'].visible = True
|
|
||||||
poweroutlet_table.base_columns['pk'].visible = True
|
|
||||||
mgmt_interface_table.base_columns['pk'].visible = True
|
|
||||||
interface_table.base_columns['pk'].visible = True
|
|
||||||
devicebay_table.base_columns['pk'].visible = True
|
|
||||||
|
|
||||||
return render(request, 'dcim/devicetype.html', {
|
# Component tables
|
||||||
'devicetype': devicetype,
|
consoleport_table = tables.ConsolePortTemplateTable(
|
||||||
'consoleport_table': consoleport_table,
|
natsorted(ConsolePortTemplate.objects.filter(device_type=devicetype), key=attrgetter('name'))
|
||||||
'consoleserverport_table': consoleserverport_table,
|
)
|
||||||
'powerport_table': powerport_table,
|
consoleserverport_table = tables.ConsoleServerPortTemplateTable(
|
||||||
'poweroutlet_table': poweroutlet_table,
|
natsorted(ConsoleServerPortTemplate.objects.filter(device_type=devicetype), key=attrgetter('name'))
|
||||||
'mgmt_interface_table': mgmt_interface_table,
|
)
|
||||||
'interface_table': interface_table,
|
powerport_table = tables.PowerPortTemplateTable(
|
||||||
'devicebay_table': devicebay_table,
|
natsorted(PowerPortTemplate.objects.filter(device_type=devicetype), key=attrgetter('name'))
|
||||||
})
|
)
|
||||||
|
poweroutlet_table = tables.PowerOutletTemplateTable(
|
||||||
|
natsorted(PowerOutletTemplate.objects.filter(device_type=devicetype), key=attrgetter('name'))
|
||||||
|
)
|
||||||
|
mgmt_interface_table = tables.InterfaceTemplateTable(
|
||||||
|
list(InterfaceTemplate.objects.order_naturally(devicetype.interface_ordering).filter(
|
||||||
|
device_type=devicetype, mgmt_only=True
|
||||||
|
))
|
||||||
|
)
|
||||||
|
interface_table = tables.InterfaceTemplateTable(
|
||||||
|
list(InterfaceTemplate.objects.order_naturally(devicetype.interface_ordering).filter(
|
||||||
|
device_type=devicetype, mgmt_only=False
|
||||||
|
))
|
||||||
|
)
|
||||||
|
devicebay_table = tables.DeviceBayTemplateTable(
|
||||||
|
natsorted(DeviceBayTemplate.objects.filter(device_type=devicetype), key=attrgetter('name'))
|
||||||
|
)
|
||||||
|
if request.user.has_perm('dcim.change_devicetype'):
|
||||||
|
consoleport_table.base_columns['pk'].visible = True
|
||||||
|
consoleserverport_table.base_columns['pk'].visible = True
|
||||||
|
powerport_table.base_columns['pk'].visible = True
|
||||||
|
poweroutlet_table.base_columns['pk'].visible = True
|
||||||
|
mgmt_interface_table.base_columns['pk'].visible = True
|
||||||
|
interface_table.base_columns['pk'].visible = True
|
||||||
|
devicebay_table.base_columns['pk'].visible = True
|
||||||
|
|
||||||
|
return render(request, 'dcim/devicetype.html', {
|
||||||
|
'devicetype': devicetype,
|
||||||
|
'consoleport_table': consoleport_table,
|
||||||
|
'consoleserverport_table': consoleserverport_table,
|
||||||
|
'powerport_table': powerport_table,
|
||||||
|
'poweroutlet_table': poweroutlet_table,
|
||||||
|
'mgmt_interface_table': mgmt_interface_table,
|
||||||
|
'interface_table': interface_table,
|
||||||
|
'devicebay_table': devicebay_table,
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
class DeviceTypeEditView(PermissionRequiredMixin, ObjectEditView):
|
class DeviceTypeEditView(PermissionRequiredMixin, ObjectEditView):
|
||||||
@ -727,70 +740,114 @@ class DeviceListView(ObjectListView):
|
|||||||
template_name = 'dcim/device_list.html'
|
template_name = 'dcim/device_list.html'
|
||||||
|
|
||||||
|
|
||||||
def device(request, pk):
|
class DeviceView(View):
|
||||||
|
|
||||||
device = get_object_or_404(Device.objects.select_related(
|
def get(self, request, pk):
|
||||||
'site__region', 'rack__group', 'tenant__group', 'device_role', 'platform'
|
|
||||||
), pk=pk)
|
|
||||||
console_ports = natsorted(
|
|
||||||
ConsolePort.objects.filter(device=device).select_related('cs_port__device'), key=attrgetter('name')
|
|
||||||
)
|
|
||||||
cs_ports = natsorted(
|
|
||||||
ConsoleServerPort.objects.filter(device=device).select_related('connected_console'), key=attrgetter('name')
|
|
||||||
)
|
|
||||||
power_ports = natsorted(
|
|
||||||
PowerPort.objects.filter(device=device).select_related('power_outlet__device'), key=attrgetter('name')
|
|
||||||
)
|
|
||||||
power_outlets = natsorted(
|
|
||||||
PowerOutlet.objects.filter(device=device).select_related('connected_port'), key=attrgetter('name')
|
|
||||||
)
|
|
||||||
interfaces = Interface.objects.order_naturally(device.device_type.interface_ordering)\
|
|
||||||
.filter(device=device, mgmt_only=False)\
|
|
||||||
.select_related('connected_as_a__interface_b__device', 'connected_as_b__interface_a__device',
|
|
||||||
'circuit_termination__circuit').prefetch_related('ip_addresses')
|
|
||||||
mgmt_interfaces = Interface.objects.order_naturally(device.device_type.interface_ordering)\
|
|
||||||
.filter(device=device, mgmt_only=True)\
|
|
||||||
.select_related('connected_as_a__interface_b__device', 'connected_as_b__interface_a__device',
|
|
||||||
'circuit_termination__circuit').prefetch_related('ip_addresses')
|
|
||||||
device_bays = natsorted(
|
|
||||||
DeviceBay.objects.filter(device=device).select_related('installed_device__device_type__manufacturer'),
|
|
||||||
key=attrgetter('name')
|
|
||||||
)
|
|
||||||
services = Service.objects.filter(device=device)
|
|
||||||
secrets = device.secrets.all()
|
|
||||||
|
|
||||||
# Find any related devices for convenient linking in the UI
|
device = get_object_or_404(Device.objects.select_related(
|
||||||
related_devices = []
|
'site__region', 'rack__group', 'tenant__group', 'device_role', 'platform'
|
||||||
if device.name:
|
), pk=pk)
|
||||||
if re.match('.+[0-9]+$', device.name):
|
console_ports = natsorted(
|
||||||
# Strip 1 or more trailing digits (e.g. core-switch1)
|
ConsolePort.objects.filter(device=device).select_related('cs_port__device'), key=attrgetter('name')
|
||||||
base_name = re.match('(.*?)[0-9]+$', device.name).group(1)
|
)
|
||||||
elif re.match('.+\d[a-z]$', device.name.lower()):
|
cs_ports = natsorted(
|
||||||
# Strip a trailing letter if preceded by a digit (e.g. dist-switch3a -> dist-switch3)
|
ConsoleServerPort.objects.filter(device=device).select_related('connected_console'), key=attrgetter('name')
|
||||||
base_name = re.match('(.*\d+)[a-z]$', device.name.lower()).group(1)
|
)
|
||||||
else:
|
power_ports = natsorted(
|
||||||
base_name = None
|
PowerPort.objects.filter(device=device).select_related('power_outlet__device'), key=attrgetter('name')
|
||||||
if base_name:
|
)
|
||||||
related_devices = Device.objects.filter(name__istartswith=base_name).exclude(pk=device.pk)\
|
power_outlets = natsorted(
|
||||||
.select_related('rack', 'device_type__manufacturer')[:10]
|
PowerOutlet.objects.filter(device=device).select_related('connected_port'), key=attrgetter('name')
|
||||||
|
)
|
||||||
|
interfaces = Interface.objects.order_naturally(device.device_type.interface_ordering).filter(
|
||||||
|
device=device, mgmt_only=False
|
||||||
|
).select_related(
|
||||||
|
'connected_as_a__interface_b__device', 'connected_as_b__interface_a__device',
|
||||||
|
'circuit_termination__circuit'
|
||||||
|
).prefetch_related('ip_addresses')
|
||||||
|
mgmt_interfaces = Interface.objects.order_naturally(device.device_type.interface_ordering).filter(
|
||||||
|
device=device, mgmt_only=True
|
||||||
|
).select_related(
|
||||||
|
'connected_as_a__interface_b__device', 'connected_as_b__interface_a__device',
|
||||||
|
'circuit_termination__circuit'
|
||||||
|
).prefetch_related('ip_addresses')
|
||||||
|
device_bays = natsorted(
|
||||||
|
DeviceBay.objects.filter(device=device).select_related('installed_device__device_type__manufacturer'),
|
||||||
|
key=attrgetter('name')
|
||||||
|
)
|
||||||
|
services = Service.objects.filter(device=device)
|
||||||
|
secrets = device.secrets.all()
|
||||||
|
|
||||||
# Show graph button on interfaces only if at least one graph has been created.
|
# Find any related devices for convenient linking in the UI
|
||||||
show_graphs = Graph.objects.filter(type=GRAPH_TYPE_INTERFACE).exists()
|
related_devices = []
|
||||||
|
if device.name:
|
||||||
|
if re.match('.+[0-9]+$', device.name):
|
||||||
|
# Strip 1 or more trailing digits (e.g. core-switch1)
|
||||||
|
base_name = re.match('(.*?)[0-9]+$', device.name).group(1)
|
||||||
|
elif re.match('.+\d[a-z]$', device.name.lower()):
|
||||||
|
# Strip a trailing letter if preceded by a digit (e.g. dist-switch3a -> dist-switch3)
|
||||||
|
base_name = re.match('(.*\d+)[a-z]$', device.name.lower()).group(1)
|
||||||
|
else:
|
||||||
|
base_name = None
|
||||||
|
if base_name:
|
||||||
|
related_devices = Device.objects.filter(name__istartswith=base_name).exclude(pk=device.pk)\
|
||||||
|
.select_related('rack', 'device_type__manufacturer')[:10]
|
||||||
|
|
||||||
return render(request, 'dcim/device.html', {
|
# Show graph button on interfaces only if at least one graph has been created.
|
||||||
'device': device,
|
show_graphs = Graph.objects.filter(type=GRAPH_TYPE_INTERFACE).exists()
|
||||||
'console_ports': console_ports,
|
|
||||||
'cs_ports': cs_ports,
|
return render(request, 'dcim/device.html', {
|
||||||
'power_ports': power_ports,
|
'device': device,
|
||||||
'power_outlets': power_outlets,
|
'console_ports': console_ports,
|
||||||
'interfaces': interfaces,
|
'cs_ports': cs_ports,
|
||||||
'mgmt_interfaces': mgmt_interfaces,
|
'power_ports': power_ports,
|
||||||
'device_bays': device_bays,
|
'power_outlets': power_outlets,
|
||||||
'services': services,
|
'interfaces': interfaces,
|
||||||
'secrets': secrets,
|
'mgmt_interfaces': mgmt_interfaces,
|
||||||
'related_devices': related_devices,
|
'device_bays': device_bays,
|
||||||
'show_graphs': show_graphs,
|
'services': services,
|
||||||
})
|
'secrets': secrets,
|
||||||
|
'related_devices': related_devices,
|
||||||
|
'show_graphs': show_graphs,
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
class DeviceInventoryView(View):
|
||||||
|
|
||||||
|
def get(self, request, pk):
|
||||||
|
|
||||||
|
device = get_object_or_404(Device, pk=pk)
|
||||||
|
inventory_items = InventoryItem.objects.filter(
|
||||||
|
device=device, parent=None
|
||||||
|
).select_related(
|
||||||
|
'manufacturer'
|
||||||
|
).prefetch_related(
|
||||||
|
'child_items'
|
||||||
|
)
|
||||||
|
|
||||||
|
return render(request, 'dcim/device_inventory.html', {
|
||||||
|
'device': device,
|
||||||
|
'inventory_items': inventory_items,
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
class DeviceLLDPNeighborsView(View):
|
||||||
|
|
||||||
|
def get(self, request, pk):
|
||||||
|
|
||||||
|
device = get_object_or_404(Device, pk=pk)
|
||||||
|
interfaces = Interface.objects.order_naturally(
|
||||||
|
device.device_type.interface_ordering
|
||||||
|
).filter(
|
||||||
|
device=device
|
||||||
|
).select_related(
|
||||||
|
'connected_as_a', 'connected_as_b'
|
||||||
|
)
|
||||||
|
|
||||||
|
return render(request, 'dcim/device_lldp_neighbors.html', {
|
||||||
|
'device': device,
|
||||||
|
'interfaces': interfaces,
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
class DeviceEditView(PermissionRequiredMixin, ObjectEditView):
|
class DeviceEditView(PermissionRequiredMixin, ObjectEditView):
|
||||||
@ -851,30 +908,6 @@ class DeviceBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
|
|||||||
default_return_url = 'dcim:device_list'
|
default_return_url = 'dcim:device_list'
|
||||||
|
|
||||||
|
|
||||||
def device_inventory(request, pk):
|
|
||||||
|
|
||||||
device = get_object_or_404(Device, pk=pk)
|
|
||||||
inventory_items = InventoryItem.objects.filter(device=device, parent=None).select_related('manufacturer')\
|
|
||||||
.prefetch_related('child_items')
|
|
||||||
|
|
||||||
return render(request, 'dcim/device_inventory.html', {
|
|
||||||
'device': device,
|
|
||||||
'inventory_items': inventory_items,
|
|
||||||
})
|
|
||||||
|
|
||||||
|
|
||||||
def device_lldp_neighbors(request, pk):
|
|
||||||
|
|
||||||
device = get_object_or_404(Device, pk=pk)
|
|
||||||
interfaces = Interface.objects.order_naturally(device.device_type.interface_ordering).filter(device=device)\
|
|
||||||
.select_related('connected_as_a', 'connected_as_b')
|
|
||||||
|
|
||||||
return render(request, 'dcim/device_lldp_neighbors.html', {
|
|
||||||
'device': device,
|
|
||||||
'interfaces': interfaces,
|
|
||||||
})
|
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Console ports
|
# Console ports
|
||||||
#
|
#
|
||||||
|
@ -12,7 +12,7 @@ urlpatterns = [
|
|||||||
url(r'^vrfs/import/$', views.VRFBulkImportView.as_view(), name='vrf_import'),
|
url(r'^vrfs/import/$', views.VRFBulkImportView.as_view(), name='vrf_import'),
|
||||||
url(r'^vrfs/edit/$', views.VRFBulkEditView.as_view(), name='vrf_bulk_edit'),
|
url(r'^vrfs/edit/$', views.VRFBulkEditView.as_view(), name='vrf_bulk_edit'),
|
||||||
url(r'^vrfs/delete/$', views.VRFBulkDeleteView.as_view(), name='vrf_bulk_delete'),
|
url(r'^vrfs/delete/$', views.VRFBulkDeleteView.as_view(), name='vrf_bulk_delete'),
|
||||||
url(r'^vrfs/(?P<pk>\d+)/$', views.vrf, name='vrf'),
|
url(r'^vrfs/(?P<pk>\d+)/$', views.VRFView.as_view(), name='vrf'),
|
||||||
url(r'^vrfs/(?P<pk>\d+)/edit/$', views.VRFEditView.as_view(), name='vrf_edit'),
|
url(r'^vrfs/(?P<pk>\d+)/edit/$', views.VRFEditView.as_view(), name='vrf_edit'),
|
||||||
url(r'^vrfs/(?P<pk>\d+)/delete/$', views.VRFDeleteView.as_view(), name='vrf_delete'),
|
url(r'^vrfs/(?P<pk>\d+)/delete/$', views.VRFDeleteView.as_view(), name='vrf_delete'),
|
||||||
|
|
||||||
@ -28,7 +28,7 @@ urlpatterns = [
|
|||||||
url(r'^aggregates/import/$', views.AggregateBulkImportView.as_view(), name='aggregate_import'),
|
url(r'^aggregates/import/$', views.AggregateBulkImportView.as_view(), name='aggregate_import'),
|
||||||
url(r'^aggregates/edit/$', views.AggregateBulkEditView.as_view(), name='aggregate_bulk_edit'),
|
url(r'^aggregates/edit/$', views.AggregateBulkEditView.as_view(), name='aggregate_bulk_edit'),
|
||||||
url(r'^aggregates/delete/$', views.AggregateBulkDeleteView.as_view(), name='aggregate_bulk_delete'),
|
url(r'^aggregates/delete/$', views.AggregateBulkDeleteView.as_view(), name='aggregate_bulk_delete'),
|
||||||
url(r'^aggregates/(?P<pk>\d+)/$', views.aggregate, name='aggregate'),
|
url(r'^aggregates/(?P<pk>\d+)/$', views.AggregateView.as_view(), name='aggregate'),
|
||||||
url(r'^aggregates/(?P<pk>\d+)/edit/$', views.AggregateEditView.as_view(), name='aggregate_edit'),
|
url(r'^aggregates/(?P<pk>\d+)/edit/$', views.AggregateEditView.as_view(), name='aggregate_edit'),
|
||||||
url(r'^aggregates/(?P<pk>\d+)/delete/$', views.AggregateDeleteView.as_view(), name='aggregate_delete'),
|
url(r'^aggregates/(?P<pk>\d+)/delete/$', views.AggregateDeleteView.as_view(), name='aggregate_delete'),
|
||||||
|
|
||||||
@ -44,10 +44,10 @@ urlpatterns = [
|
|||||||
url(r'^prefixes/import/$', views.PrefixBulkImportView.as_view(), name='prefix_import'),
|
url(r'^prefixes/import/$', views.PrefixBulkImportView.as_view(), name='prefix_import'),
|
||||||
url(r'^prefixes/edit/$', views.PrefixBulkEditView.as_view(), name='prefix_bulk_edit'),
|
url(r'^prefixes/edit/$', views.PrefixBulkEditView.as_view(), name='prefix_bulk_edit'),
|
||||||
url(r'^prefixes/delete/$', views.PrefixBulkDeleteView.as_view(), name='prefix_bulk_delete'),
|
url(r'^prefixes/delete/$', views.PrefixBulkDeleteView.as_view(), name='prefix_bulk_delete'),
|
||||||
url(r'^prefixes/(?P<pk>\d+)/$', views.prefix, name='prefix'),
|
url(r'^prefixes/(?P<pk>\d+)/$', views.PrefixView.as_view(), name='prefix'),
|
||||||
url(r'^prefixes/(?P<pk>\d+)/edit/$', views.PrefixEditView.as_view(), name='prefix_edit'),
|
url(r'^prefixes/(?P<pk>\d+)/edit/$', views.PrefixEditView.as_view(), name='prefix_edit'),
|
||||||
url(r'^prefixes/(?P<pk>\d+)/delete/$', views.PrefixDeleteView.as_view(), name='prefix_delete'),
|
url(r'^prefixes/(?P<pk>\d+)/delete/$', views.PrefixDeleteView.as_view(), name='prefix_delete'),
|
||||||
url(r'^prefixes/(?P<pk>\d+)/ip-addresses/$', views.prefix_ipaddresses, name='prefix_ipaddresses'),
|
url(r'^prefixes/(?P<pk>\d+)/ip-addresses/$', views.PrefixIPAddressesView.as_view(), name='prefix_ipaddresses'),
|
||||||
|
|
||||||
# IP addresses
|
# IP addresses
|
||||||
url(r'^ip-addresses/$', views.IPAddressListView.as_view(), name='ipaddress_list'),
|
url(r'^ip-addresses/$', views.IPAddressListView.as_view(), name='ipaddress_list'),
|
||||||
@ -56,7 +56,7 @@ urlpatterns = [
|
|||||||
url(r'^ip-addresses/import/$', views.IPAddressBulkImportView.as_view(), name='ipaddress_import'),
|
url(r'^ip-addresses/import/$', views.IPAddressBulkImportView.as_view(), name='ipaddress_import'),
|
||||||
url(r'^ip-addresses/edit/$', views.IPAddressBulkEditView.as_view(), name='ipaddress_bulk_edit'),
|
url(r'^ip-addresses/edit/$', views.IPAddressBulkEditView.as_view(), name='ipaddress_bulk_edit'),
|
||||||
url(r'^ip-addresses/delete/$', views.IPAddressBulkDeleteView.as_view(), name='ipaddress_bulk_delete'),
|
url(r'^ip-addresses/delete/$', views.IPAddressBulkDeleteView.as_view(), name='ipaddress_bulk_delete'),
|
||||||
url(r'^ip-addresses/(?P<pk>\d+)/$', views.ipaddress, name='ipaddress'),
|
url(r'^ip-addresses/(?P<pk>\d+)/$', views.IPAddressView.as_view(), name='ipaddress'),
|
||||||
url(r'^ip-addresses/(?P<pk>\d+)/edit/$', views.IPAddressEditView.as_view(), name='ipaddress_edit'),
|
url(r'^ip-addresses/(?P<pk>\d+)/edit/$', views.IPAddressEditView.as_view(), name='ipaddress_edit'),
|
||||||
url(r'^ip-addresses/(?P<pk>\d+)/delete/$', views.IPAddressDeleteView.as_view(), name='ipaddress_delete'),
|
url(r'^ip-addresses/(?P<pk>\d+)/delete/$', views.IPAddressDeleteView.as_view(), name='ipaddress_delete'),
|
||||||
|
|
||||||
@ -72,7 +72,7 @@ urlpatterns = [
|
|||||||
url(r'^vlans/import/$', views.VLANBulkImportView.as_view(), name='vlan_import'),
|
url(r'^vlans/import/$', views.VLANBulkImportView.as_view(), name='vlan_import'),
|
||||||
url(r'^vlans/edit/$', views.VLANBulkEditView.as_view(), name='vlan_bulk_edit'),
|
url(r'^vlans/edit/$', views.VLANBulkEditView.as_view(), name='vlan_bulk_edit'),
|
||||||
url(r'^vlans/delete/$', views.VLANBulkDeleteView.as_view(), name='vlan_bulk_delete'),
|
url(r'^vlans/delete/$', views.VLANBulkDeleteView.as_view(), name='vlan_bulk_delete'),
|
||||||
url(r'^vlans/(?P<pk>\d+)/$', views.vlan, name='vlan'),
|
url(r'^vlans/(?P<pk>\d+)/$', views.VLANView.as_view(), name='vlan'),
|
||||||
url(r'^vlans/(?P<pk>\d+)/edit/$', views.VLANEditView.as_view(), name='vlan_edit'),
|
url(r'^vlans/(?P<pk>\d+)/edit/$', views.VLANEditView.as_view(), name='vlan_edit'),
|
||||||
url(r'^vlans/(?P<pk>\d+)/delete/$', views.VLANDeleteView.as_view(), name='vlan_delete'),
|
url(r'^vlans/(?P<pk>\d+)/delete/$', views.VLANDeleteView.as_view(), name='vlan_delete'),
|
||||||
|
|
||||||
|
@ -6,6 +6,7 @@ from django.contrib.auth.mixins import PermissionRequiredMixin
|
|||||||
from django.db.models import Count, Q
|
from django.db.models import Count, Q
|
||||||
from django.shortcuts import get_object_or_404, render
|
from django.shortcuts import get_object_or_404, render
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
|
from django.views.generic import View
|
||||||
|
|
||||||
from dcim.models import Device
|
from dcim.models import Device
|
||||||
from utilities.paginator import EnhancedPaginator
|
from utilities.paginator import EnhancedPaginator
|
||||||
@ -96,18 +97,20 @@ class VRFListView(ObjectListView):
|
|||||||
template_name = 'ipam/vrf_list.html'
|
template_name = 'ipam/vrf_list.html'
|
||||||
|
|
||||||
|
|
||||||
def vrf(request, pk):
|
class VRFView(View):
|
||||||
|
|
||||||
vrf = get_object_or_404(VRF.objects.all(), pk=pk)
|
def get(self, request, pk):
|
||||||
prefix_table = tables.PrefixBriefTable(
|
|
||||||
list(Prefix.objects.filter(vrf=vrf).select_related('site', 'role'))
|
|
||||||
)
|
|
||||||
prefix_table.exclude = ('vrf',)
|
|
||||||
|
|
||||||
return render(request, 'ipam/vrf.html', {
|
vrf = get_object_or_404(VRF.objects.all(), pk=pk)
|
||||||
'vrf': vrf,
|
prefix_table = tables.PrefixBriefTable(
|
||||||
'prefix_table': prefix_table,
|
list(Prefix.objects.filter(vrf=vrf).select_related('site', 'role'))
|
||||||
})
|
)
|
||||||
|
prefix_table.exclude = ('vrf',)
|
||||||
|
|
||||||
|
return render(request, 'ipam/vrf.html', {
|
||||||
|
'vrf': vrf,
|
||||||
|
'prefix_table': prefix_table,
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
class VRFEditView(PermissionRequiredMixin, ObjectEditView):
|
class VRFEditView(PermissionRequiredMixin, ObjectEditView):
|
||||||
@ -281,37 +284,44 @@ class AggregateListView(ObjectListView):
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def aggregate(request, pk):
|
class AggregateView(View):
|
||||||
|
|
||||||
aggregate = get_object_or_404(Aggregate, pk=pk)
|
def get(self, request, pk):
|
||||||
|
|
||||||
# Find all child prefixes contained by this aggregate
|
aggregate = get_object_or_404(Aggregate, pk=pk)
|
||||||
child_prefixes = Prefix.objects.filter(prefix__net_contained_or_equal=str(aggregate.prefix))\
|
|
||||||
.select_related('site', 'role').annotate_depth(limit=0)
|
|
||||||
child_prefixes = add_available_prefixes(aggregate.prefix, child_prefixes)
|
|
||||||
|
|
||||||
prefix_table = tables.PrefixTable(child_prefixes)
|
# Find all child prefixes contained by this aggregate
|
||||||
if request.user.has_perm('ipam.change_prefix') or request.user.has_perm('ipam.delete_prefix'):
|
child_prefixes = Prefix.objects.filter(
|
||||||
prefix_table.base_columns['pk'].visible = True
|
prefix__net_contained_or_equal=str(aggregate.prefix)
|
||||||
|
).select_related(
|
||||||
|
'site', 'role'
|
||||||
|
).annotate_depth(
|
||||||
|
limit=0
|
||||||
|
)
|
||||||
|
child_prefixes = add_available_prefixes(aggregate.prefix, child_prefixes)
|
||||||
|
|
||||||
paginate = {
|
prefix_table = tables.PrefixTable(child_prefixes)
|
||||||
'klass': EnhancedPaginator,
|
if request.user.has_perm('ipam.change_prefix') or request.user.has_perm('ipam.delete_prefix'):
|
||||||
'per_page': request.GET.get('per_page', settings.PAGINATE_COUNT)
|
prefix_table.base_columns['pk'].visible = True
|
||||||
}
|
|
||||||
RequestConfig(request, paginate).configure(prefix_table)
|
|
||||||
|
|
||||||
# Compile permissions list for rendering the object table
|
paginate = {
|
||||||
permissions = {
|
'klass': EnhancedPaginator,
|
||||||
'add': request.user.has_perm('ipam.add_prefix'),
|
'per_page': request.GET.get('per_page', settings.PAGINATE_COUNT)
|
||||||
'change': request.user.has_perm('ipam.change_prefix'),
|
}
|
||||||
'delete': request.user.has_perm('ipam.delete_prefix'),
|
RequestConfig(request, paginate).configure(prefix_table)
|
||||||
}
|
|
||||||
|
|
||||||
return render(request, 'ipam/aggregate.html', {
|
# Compile permissions list for rendering the object table
|
||||||
'aggregate': aggregate,
|
permissions = {
|
||||||
'prefix_table': prefix_table,
|
'add': request.user.has_perm('ipam.add_prefix'),
|
||||||
'permissions': permissions,
|
'change': request.user.has_perm('ipam.change_prefix'),
|
||||||
})
|
'delete': request.user.has_perm('ipam.delete_prefix'),
|
||||||
|
}
|
||||||
|
|
||||||
|
return render(request, 'ipam/aggregate.html', {
|
||||||
|
'aggregate': aggregate,
|
||||||
|
'prefix_table': prefix_table,
|
||||||
|
'permissions': permissions,
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
class AggregateEditView(PermissionRequiredMixin, ObjectEditView):
|
class AggregateEditView(PermissionRequiredMixin, ObjectEditView):
|
||||||
@ -394,66 +404,120 @@ class PrefixListView(ObjectListView):
|
|||||||
return self.queryset.annotate_depth(limit=limit)
|
return self.queryset.annotate_depth(limit=limit)
|
||||||
|
|
||||||
|
|
||||||
def prefix(request, pk):
|
class PrefixView(View):
|
||||||
|
|
||||||
prefix = get_object_or_404(Prefix.objects.select_related(
|
def get(self, request, pk):
|
||||||
'vrf', 'site__region', 'tenant__group', 'vlan__group', 'role'
|
|
||||||
), pk=pk)
|
|
||||||
|
|
||||||
try:
|
prefix = get_object_or_404(Prefix.objects.select_related(
|
||||||
aggregate = Aggregate.objects.get(prefix__net_contains_or_equals=str(prefix.prefix))
|
'vrf', 'site__region', 'tenant__group', 'vlan__group', 'role'
|
||||||
except Aggregate.DoesNotExist:
|
), pk=pk)
|
||||||
aggregate = None
|
|
||||||
|
|
||||||
# Count child IP addresses
|
try:
|
||||||
ipaddress_count = IPAddress.objects.filter(vrf=prefix.vrf, address__net_host_contained=str(prefix.prefix))\
|
aggregate = Aggregate.objects.get(prefix__net_contains_or_equals=str(prefix.prefix))
|
||||||
.count()
|
except Aggregate.DoesNotExist:
|
||||||
|
aggregate = None
|
||||||
|
|
||||||
# Parent prefixes table
|
# Count child IP addresses
|
||||||
parent_prefixes = Prefix.objects.filter(Q(vrf=prefix.vrf) | Q(vrf__isnull=True))\
|
ipaddress_count = IPAddress.objects.filter(
|
||||||
.filter(prefix__net_contains=str(prefix.prefix))\
|
vrf=prefix.vrf, address__net_host_contained=str(prefix.prefix)
|
||||||
.select_related('site', 'role').annotate_depth()
|
).count()
|
||||||
parent_prefix_table = tables.PrefixBriefTable(parent_prefixes)
|
|
||||||
parent_prefix_table.exclude = ('vrf',)
|
|
||||||
|
|
||||||
# Duplicate prefixes table
|
# Parent prefixes table
|
||||||
duplicate_prefixes = Prefix.objects.filter(vrf=prefix.vrf, prefix=str(prefix.prefix)).exclude(pk=prefix.pk)\
|
parent_prefixes = Prefix.objects.filter(
|
||||||
.select_related('site', 'role')
|
Q(vrf=prefix.vrf) | Q(vrf__isnull=True)
|
||||||
duplicate_prefix_table = tables.PrefixBriefTable(list(duplicate_prefixes))
|
).filter(
|
||||||
duplicate_prefix_table.exclude = ('vrf',)
|
prefix__net_contains=str(prefix.prefix)
|
||||||
|
).select_related(
|
||||||
|
'site', 'role'
|
||||||
|
).annotate_depth()
|
||||||
|
parent_prefix_table = tables.PrefixBriefTable(parent_prefixes)
|
||||||
|
parent_prefix_table.exclude = ('vrf',)
|
||||||
|
|
||||||
# Child prefixes table
|
# Duplicate prefixes table
|
||||||
child_prefixes = Prefix.objects.filter(vrf=prefix.vrf, prefix__net_contained=str(prefix.prefix))\
|
duplicate_prefixes = Prefix.objects.filter(
|
||||||
.select_related('site', 'role').annotate_depth(limit=0)
|
vrf=prefix.vrf, prefix=str(prefix.prefix)
|
||||||
if child_prefixes:
|
).exclude(
|
||||||
child_prefixes = add_available_prefixes(prefix.prefix, child_prefixes)
|
pk=prefix.pk
|
||||||
child_prefix_table = tables.PrefixTable(child_prefixes)
|
).select_related(
|
||||||
if request.user.has_perm('ipam.change_prefix') or request.user.has_perm('ipam.delete_prefix'):
|
'site', 'role'
|
||||||
child_prefix_table.base_columns['pk'].visible = True
|
)
|
||||||
|
duplicate_prefix_table = tables.PrefixBriefTable(list(duplicate_prefixes))
|
||||||
|
duplicate_prefix_table.exclude = ('vrf',)
|
||||||
|
|
||||||
paginate = {
|
# Child prefixes table
|
||||||
'klass': EnhancedPaginator,
|
child_prefixes = Prefix.objects.filter(
|
||||||
'per_page': request.GET.get('per_page', settings.PAGINATE_COUNT)
|
vrf=prefix.vrf, prefix__net_contained=str(prefix.prefix)
|
||||||
}
|
).select_related(
|
||||||
RequestConfig(request, paginate).configure(child_prefix_table)
|
'site', 'role'
|
||||||
|
).annotate_depth(limit=0)
|
||||||
|
if child_prefixes:
|
||||||
|
child_prefixes = add_available_prefixes(prefix.prefix, child_prefixes)
|
||||||
|
child_prefix_table = tables.PrefixTable(child_prefixes)
|
||||||
|
if request.user.has_perm('ipam.change_prefix') or request.user.has_perm('ipam.delete_prefix'):
|
||||||
|
child_prefix_table.base_columns['pk'].visible = True
|
||||||
|
|
||||||
# Compile permissions list for rendering the object table
|
paginate = {
|
||||||
permissions = {
|
'klass': EnhancedPaginator,
|
||||||
'add': request.user.has_perm('ipam.add_prefix'),
|
'per_page': request.GET.get('per_page', settings.PAGINATE_COUNT)
|
||||||
'change': request.user.has_perm('ipam.change_prefix'),
|
}
|
||||||
'delete': request.user.has_perm('ipam.delete_prefix'),
|
RequestConfig(request, paginate).configure(child_prefix_table)
|
||||||
}
|
|
||||||
|
|
||||||
return render(request, 'ipam/prefix.html', {
|
# Compile permissions list for rendering the object table
|
||||||
'prefix': prefix,
|
permissions = {
|
||||||
'aggregate': aggregate,
|
'add': request.user.has_perm('ipam.add_prefix'),
|
||||||
'ipaddress_count': ipaddress_count,
|
'change': request.user.has_perm('ipam.change_prefix'),
|
||||||
'parent_prefix_table': parent_prefix_table,
|
'delete': request.user.has_perm('ipam.delete_prefix'),
|
||||||
'child_prefix_table': child_prefix_table,
|
}
|
||||||
'duplicate_prefix_table': duplicate_prefix_table,
|
|
||||||
'permissions': permissions,
|
return render(request, 'ipam/prefix.html', {
|
||||||
'return_url': prefix.get_absolute_url(),
|
'prefix': prefix,
|
||||||
})
|
'aggregate': aggregate,
|
||||||
|
'ipaddress_count': ipaddress_count,
|
||||||
|
'parent_prefix_table': parent_prefix_table,
|
||||||
|
'child_prefix_table': child_prefix_table,
|
||||||
|
'duplicate_prefix_table': duplicate_prefix_table,
|
||||||
|
'permissions': permissions,
|
||||||
|
'return_url': prefix.get_absolute_url(),
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
class PrefixIPAddressesView(View):
|
||||||
|
|
||||||
|
def get(self, request, pk):
|
||||||
|
|
||||||
|
prefix = get_object_or_404(Prefix.objects.all(), pk=pk)
|
||||||
|
|
||||||
|
# Find all IPAddresses belonging to this Prefix
|
||||||
|
ipaddresses = IPAddress.objects.filter(
|
||||||
|
vrf=prefix.vrf, address__net_host_contained=str(prefix.prefix)
|
||||||
|
).select_related(
|
||||||
|
'vrf', 'interface__device', 'primary_ip4_for', 'primary_ip6_for'
|
||||||
|
)
|
||||||
|
ipaddresses = add_available_ipaddresses(prefix.prefix, ipaddresses, prefix.is_pool)
|
||||||
|
|
||||||
|
ip_table = tables.IPAddressTable(ipaddresses)
|
||||||
|
if request.user.has_perm('ipam.change_ipaddress') or request.user.has_perm('ipam.delete_ipaddress'):
|
||||||
|
ip_table.base_columns['pk'].visible = True
|
||||||
|
|
||||||
|
paginate = {
|
||||||
|
'klass': EnhancedPaginator,
|
||||||
|
'per_page': request.GET.get('per_page', settings.PAGINATE_COUNT)
|
||||||
|
}
|
||||||
|
RequestConfig(request, paginate).configure(ip_table)
|
||||||
|
|
||||||
|
# Compile permissions list for rendering the object table
|
||||||
|
permissions = {
|
||||||
|
'add': request.user.has_perm('ipam.add_ipaddress'),
|
||||||
|
'change': request.user.has_perm('ipam.change_ipaddress'),
|
||||||
|
'delete': request.user.has_perm('ipam.delete_ipaddress'),
|
||||||
|
}
|
||||||
|
|
||||||
|
return render(request, 'ipam/prefix_ipaddresses.html', {
|
||||||
|
'prefix': prefix,
|
||||||
|
'ip_table': ip_table,
|
||||||
|
'permissions': permissions,
|
||||||
|
'bulk_querystring': 'vrf_id={}&parent={}'.format(prefix.vrf or '0', prefix.prefix),
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
class PrefixEditView(PermissionRequiredMixin, ObjectEditView):
|
class PrefixEditView(PermissionRequiredMixin, ObjectEditView):
|
||||||
@ -495,40 +559,6 @@ class PrefixBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
|
|||||||
default_return_url = 'ipam:prefix_list'
|
default_return_url = 'ipam:prefix_list'
|
||||||
|
|
||||||
|
|
||||||
def prefix_ipaddresses(request, pk):
|
|
||||||
|
|
||||||
prefix = get_object_or_404(Prefix.objects.all(), pk=pk)
|
|
||||||
|
|
||||||
# Find all IPAddresses belonging to this Prefix
|
|
||||||
ipaddresses = IPAddress.objects.filter(vrf=prefix.vrf, address__net_host_contained=str(prefix.prefix))\
|
|
||||||
.select_related('vrf', 'interface__device', 'primary_ip4_for', 'primary_ip6_for')
|
|
||||||
ipaddresses = add_available_ipaddresses(prefix.prefix, ipaddresses, prefix.is_pool)
|
|
||||||
|
|
||||||
ip_table = tables.IPAddressTable(ipaddresses)
|
|
||||||
if request.user.has_perm('ipam.change_ipaddress') or request.user.has_perm('ipam.delete_ipaddress'):
|
|
||||||
ip_table.base_columns['pk'].visible = True
|
|
||||||
|
|
||||||
paginate = {
|
|
||||||
'klass': EnhancedPaginator,
|
|
||||||
'per_page': request.GET.get('per_page', settings.PAGINATE_COUNT)
|
|
||||||
}
|
|
||||||
RequestConfig(request, paginate).configure(ip_table)
|
|
||||||
|
|
||||||
# Compile permissions list for rendering the object table
|
|
||||||
permissions = {
|
|
||||||
'add': request.user.has_perm('ipam.add_ipaddress'),
|
|
||||||
'change': request.user.has_perm('ipam.change_ipaddress'),
|
|
||||||
'delete': request.user.has_perm('ipam.delete_ipaddress'),
|
|
||||||
}
|
|
||||||
|
|
||||||
return render(request, 'ipam/prefix_ipaddresses.html', {
|
|
||||||
'prefix': prefix,
|
|
||||||
'ip_table': ip_table,
|
|
||||||
'permissions': permissions,
|
|
||||||
'bulk_querystring': 'vrf_id={}&parent={}'.format(prefix.vrf or '0', prefix.prefix),
|
|
||||||
})
|
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# IP addresses
|
# IP addresses
|
||||||
#
|
#
|
||||||
@ -541,32 +571,47 @@ class IPAddressListView(ObjectListView):
|
|||||||
template_name = 'ipam/ipaddress_list.html'
|
template_name = 'ipam/ipaddress_list.html'
|
||||||
|
|
||||||
|
|
||||||
def ipaddress(request, pk):
|
class IPAddressView(View):
|
||||||
|
|
||||||
ipaddress = get_object_or_404(IPAddress.objects.select_related('interface__device'), pk=pk)
|
def get(self, request, pk):
|
||||||
|
|
||||||
# Parent prefixes table
|
ipaddress = get_object_or_404(IPAddress.objects.select_related('interface__device'), pk=pk)
|
||||||
parent_prefixes = Prefix.objects.filter(vrf=ipaddress.vrf, prefix__net_contains=str(ipaddress.address.ip))\
|
|
||||||
.select_related('site', 'role')
|
|
||||||
parent_prefixes_table = tables.PrefixBriefTable(list(parent_prefixes))
|
|
||||||
parent_prefixes_table.exclude = ('vrf',)
|
|
||||||
|
|
||||||
# Duplicate IPs table
|
# Parent prefixes table
|
||||||
duplicate_ips = IPAddress.objects.filter(vrf=ipaddress.vrf, address=str(ipaddress.address))\
|
parent_prefixes = Prefix.objects.filter(
|
||||||
.exclude(pk=ipaddress.pk).select_related('interface__device', 'nat_inside')
|
vrf=ipaddress.vrf, prefix__net_contains=str(ipaddress.address.ip)
|
||||||
duplicate_ips_table = tables.IPAddressBriefTable(list(duplicate_ips))
|
).select_related(
|
||||||
|
'site', 'role'
|
||||||
|
)
|
||||||
|
parent_prefixes_table = tables.PrefixBriefTable(list(parent_prefixes))
|
||||||
|
parent_prefixes_table.exclude = ('vrf',)
|
||||||
|
|
||||||
# Related IP table
|
# Duplicate IPs table
|
||||||
related_ips = IPAddress.objects.select_related('interface__device').exclude(address=str(ipaddress.address))\
|
duplicate_ips = IPAddress.objects.filter(
|
||||||
.filter(vrf=ipaddress.vrf, address__net_contained_or_equal=str(ipaddress.address))
|
vrf=ipaddress.vrf, address=str(ipaddress.address)
|
||||||
related_ips_table = tables.IPAddressBriefTable(list(related_ips))
|
).exclude(
|
||||||
|
pk=ipaddress.pk
|
||||||
|
).select_related(
|
||||||
|
'interface__device', 'nat_inside'
|
||||||
|
)
|
||||||
|
duplicate_ips_table = tables.IPAddressBriefTable(list(duplicate_ips))
|
||||||
|
|
||||||
return render(request, 'ipam/ipaddress.html', {
|
# Related IP table
|
||||||
'ipaddress': ipaddress,
|
related_ips = IPAddress.objects.select_related(
|
||||||
'parent_prefixes_table': parent_prefixes_table,
|
'interface__device'
|
||||||
'duplicate_ips_table': duplicate_ips_table,
|
).exclude(
|
||||||
'related_ips_table': related_ips_table,
|
address=str(ipaddress.address)
|
||||||
})
|
).filter(
|
||||||
|
vrf=ipaddress.vrf, address__net_contained_or_equal=str(ipaddress.address)
|
||||||
|
)
|
||||||
|
related_ips_table = tables.IPAddressBriefTable(list(related_ips))
|
||||||
|
|
||||||
|
return render(request, 'ipam/ipaddress.html', {
|
||||||
|
'ipaddress': ipaddress,
|
||||||
|
'parent_prefixes_table': parent_prefixes_table,
|
||||||
|
'duplicate_ips_table': duplicate_ips_table,
|
||||||
|
'related_ips_table': related_ips_table,
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
class IPAddressEditView(PermissionRequiredMixin, ObjectEditView):
|
class IPAddressEditView(PermissionRequiredMixin, ObjectEditView):
|
||||||
@ -669,17 +714,21 @@ class VLANListView(ObjectListView):
|
|||||||
template_name = 'ipam/vlan_list.html'
|
template_name = 'ipam/vlan_list.html'
|
||||||
|
|
||||||
|
|
||||||
def vlan(request, pk):
|
class VLANView(View):
|
||||||
|
|
||||||
vlan = get_object_or_404(VLAN.objects.select_related('site__region', 'tenant__group', 'role'), pk=pk)
|
def get(self, request, pk):
|
||||||
prefixes = Prefix.objects.filter(vlan=vlan).select_related('vrf', 'site', 'role')
|
|
||||||
prefix_table = tables.PrefixBriefTable(list(prefixes))
|
|
||||||
prefix_table.exclude = ('vlan',)
|
|
||||||
|
|
||||||
return render(request, 'ipam/vlan.html', {
|
vlan = get_object_or_404(VLAN.objects.select_related(
|
||||||
'vlan': vlan,
|
'site__region', 'tenant__group', 'role'
|
||||||
'prefix_table': prefix_table,
|
), pk=pk)
|
||||||
})
|
prefixes = Prefix.objects.filter(vlan=vlan).select_related('vrf', 'site', 'role')
|
||||||
|
prefix_table = tables.PrefixBriefTable(list(prefixes))
|
||||||
|
prefix_table.exclude = ('vlan',)
|
||||||
|
|
||||||
|
return render(request, 'ipam/vlan.html', {
|
||||||
|
'vlan': vlan,
|
||||||
|
'prefix_table': prefix_table,
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
class VLANEditView(PermissionRequiredMixin, ObjectEditView):
|
class VLANEditView(PermissionRequiredMixin, ObjectEditView):
|
||||||
|
@ -17,7 +17,7 @@ urlpatterns = [
|
|||||||
url(r'^secrets/import/$', views.secret_import, name='secret_import'),
|
url(r'^secrets/import/$', views.secret_import, name='secret_import'),
|
||||||
url(r'^secrets/edit/$', views.SecretBulkEditView.as_view(), name='secret_bulk_edit'),
|
url(r'^secrets/edit/$', views.SecretBulkEditView.as_view(), name='secret_bulk_edit'),
|
||||||
url(r'^secrets/delete/$', views.SecretBulkDeleteView.as_view(), name='secret_bulk_delete'),
|
url(r'^secrets/delete/$', views.SecretBulkDeleteView.as_view(), name='secret_bulk_delete'),
|
||||||
url(r'^secrets/(?P<pk>\d+)/$', views.secret, name='secret'),
|
url(r'^secrets/(?P<pk>\d+)/$', views.SecretView.as_view(), name='secret'),
|
||||||
url(r'^secrets/(?P<pk>\d+)/edit/$', views.secret_edit, name='secret_edit'),
|
url(r'^secrets/(?P<pk>\d+)/edit/$', views.secret_edit, name='secret_edit'),
|
||||||
url(r'^secrets/(?P<pk>\d+)/delete/$', views.SecretDeleteView.as_view(), name='secret_delete'),
|
url(r'^secrets/(?P<pk>\d+)/delete/$', views.SecretDeleteView.as_view(), name='secret_delete'),
|
||||||
|
|
||||||
|
@ -8,6 +8,7 @@ from django.db.models import Count
|
|||||||
from django.shortcuts import get_object_or_404, redirect, render
|
from django.shortcuts import get_object_or_404, redirect, render
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
from django.utils.decorators import method_decorator
|
from django.utils.decorators import method_decorator
|
||||||
|
from django.views.generic import View
|
||||||
|
|
||||||
from dcim.models import Device
|
from dcim.models import Device
|
||||||
from utilities.views import BulkDeleteView, BulkEditView, ObjectDeleteView, ObjectEditView, ObjectListView
|
from utilities.views import BulkDeleteView, BulkEditView, ObjectDeleteView, ObjectEditView, ObjectListView
|
||||||
@ -65,14 +66,16 @@ class SecretListView(ObjectListView):
|
|||||||
template_name = 'secrets/secret_list.html'
|
template_name = 'secrets/secret_list.html'
|
||||||
|
|
||||||
|
|
||||||
@login_required
|
@method_decorator(login_required, name='dispatch')
|
||||||
def secret(request, pk):
|
class SecretView(View):
|
||||||
|
|
||||||
secret = get_object_or_404(Secret, pk=pk)
|
def get(self, request, pk):
|
||||||
|
|
||||||
return render(request, 'secrets/secret.html', {
|
secret = get_object_or_404(Secret, pk=pk)
|
||||||
'secret': secret,
|
|
||||||
})
|
return render(request, 'secrets/secret.html', {
|
||||||
|
'secret': secret,
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
@permission_required('secrets.add_secret')
|
@permission_required('secrets.add_secret')
|
||||||
|
@ -18,7 +18,7 @@ urlpatterns = [
|
|||||||
url(r'^tenants/import/$', views.TenantBulkImportView.as_view(), name='tenant_import'),
|
url(r'^tenants/import/$', views.TenantBulkImportView.as_view(), name='tenant_import'),
|
||||||
url(r'^tenants/edit/$', views.TenantBulkEditView.as_view(), name='tenant_bulk_edit'),
|
url(r'^tenants/edit/$', views.TenantBulkEditView.as_view(), name='tenant_bulk_edit'),
|
||||||
url(r'^tenants/delete/$', views.TenantBulkDeleteView.as_view(), name='tenant_bulk_delete'),
|
url(r'^tenants/delete/$', views.TenantBulkDeleteView.as_view(), name='tenant_bulk_delete'),
|
||||||
url(r'^tenants/(?P<slug>[\w-]+)/$', views.tenant, name='tenant'),
|
url(r'^tenants/(?P<slug>[\w-]+)/$', views.TenantView.as_view(), name='tenant'),
|
||||||
url(r'^tenants/(?P<slug>[\w-]+)/edit/$', views.TenantEditView.as_view(), name='tenant_edit'),
|
url(r'^tenants/(?P<slug>[\w-]+)/edit/$', views.TenantEditView.as_view(), name='tenant_edit'),
|
||||||
url(r'^tenants/(?P<slug>[\w-]+)/delete/$', views.TenantDeleteView.as_view(), name='tenant_delete'),
|
url(r'^tenants/(?P<slug>[\w-]+)/delete/$', views.TenantDeleteView.as_view(), name='tenant_delete'),
|
||||||
|
|
||||||
|
@ -2,6 +2,7 @@ from django.contrib.auth.mixins import PermissionRequiredMixin
|
|||||||
from django.db.models import Count, Q
|
from django.db.models import Count, Q
|
||||||
from django.shortcuts import get_object_or_404, render
|
from django.shortcuts import get_object_or_404, render
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
|
from django.views.generic import View
|
||||||
|
|
||||||
from circuits.models import Circuit
|
from circuits.models import Circuit
|
||||||
from dcim.models import Site, Rack, Device
|
from dcim.models import Site, Rack, Device
|
||||||
@ -51,30 +52,32 @@ class TenantListView(ObjectListView):
|
|||||||
template_name = 'tenancy/tenant_list.html'
|
template_name = 'tenancy/tenant_list.html'
|
||||||
|
|
||||||
|
|
||||||
def tenant(request, slug):
|
class TenantView(View):
|
||||||
|
|
||||||
tenant = get_object_or_404(Tenant, slug=slug)
|
def get(self, request, slug):
|
||||||
stats = {
|
|
||||||
'site_count': Site.objects.filter(tenant=tenant).count(),
|
|
||||||
'rack_count': Rack.objects.filter(tenant=tenant).count(),
|
|
||||||
'device_count': Device.objects.filter(tenant=tenant).count(),
|
|
||||||
'vrf_count': VRF.objects.filter(tenant=tenant).count(),
|
|
||||||
'prefix_count': Prefix.objects.filter(
|
|
||||||
Q(tenant=tenant) |
|
|
||||||
Q(tenant__isnull=True, vrf__tenant=tenant)
|
|
||||||
).count(),
|
|
||||||
'ipaddress_count': IPAddress.objects.filter(
|
|
||||||
Q(tenant=tenant) |
|
|
||||||
Q(tenant__isnull=True, vrf__tenant=tenant)
|
|
||||||
).count(),
|
|
||||||
'vlan_count': VLAN.objects.filter(tenant=tenant).count(),
|
|
||||||
'circuit_count': Circuit.objects.filter(tenant=tenant).count(),
|
|
||||||
}
|
|
||||||
|
|
||||||
return render(request, 'tenancy/tenant.html', {
|
tenant = get_object_or_404(Tenant, slug=slug)
|
||||||
'tenant': tenant,
|
stats = {
|
||||||
'stats': stats,
|
'site_count': Site.objects.filter(tenant=tenant).count(),
|
||||||
})
|
'rack_count': Rack.objects.filter(tenant=tenant).count(),
|
||||||
|
'device_count': Device.objects.filter(tenant=tenant).count(),
|
||||||
|
'vrf_count': VRF.objects.filter(tenant=tenant).count(),
|
||||||
|
'prefix_count': Prefix.objects.filter(
|
||||||
|
Q(tenant=tenant) |
|
||||||
|
Q(tenant__isnull=True, vrf__tenant=tenant)
|
||||||
|
).count(),
|
||||||
|
'ipaddress_count': IPAddress.objects.filter(
|
||||||
|
Q(tenant=tenant) |
|
||||||
|
Q(tenant__isnull=True, vrf__tenant=tenant)
|
||||||
|
).count(),
|
||||||
|
'vlan_count': VLAN.objects.filter(tenant=tenant).count(),
|
||||||
|
'circuit_count': Circuit.objects.filter(tenant=tenant).count(),
|
||||||
|
}
|
||||||
|
|
||||||
|
return render(request, 'tenancy/tenant.html', {
|
||||||
|
'tenant': tenant,
|
||||||
|
'stats': stats,
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
class TenantEditView(PermissionRequiredMixin, ObjectEditView):
|
class TenantEditView(PermissionRequiredMixin, ObjectEditView):
|
||||||
|
Loading…
Reference in New Issue
Block a user