|
|
@@ -1,3 +1,4 @@
|
|
|
+from __future__ import unicode_literals
|
|
|
from copy import deepcopy
|
|
|
import re
|
|
|
from natsort import natsorted
|
|
|
@@ -24,7 +25,6 @@ from utilities.paginator import EnhancedPaginator
|
|
|
from utilities.views import (
|
|
|
BulkDeleteView, BulkEditView, BulkImportView, ObjectDeleteView, ObjectEditView, ObjectListView,
|
|
|
)
|
|
|
-
|
|
|
from . import filters, forms, tables
|
|
|
from .models import (
|
|
|
CONNECTION_STATUS_CONNECTED, ConsolePort, ConsolePortTemplate, ConsoleServerPort, ConsoleServerPortTemplate, Device,
|
|
|
@@ -109,11 +109,11 @@ class ComponentCreateView(View):
|
|
|
if field == 'name':
|
|
|
field = 'name_pattern'
|
|
|
for e in errors:
|
|
|
- form.add_error(field, u'{}: {}'.format(name, ', '.join(e)))
|
|
|
+ form.add_error(field, '{}: {}'.format(name, ', '.join(e)))
|
|
|
|
|
|
if not form.errors:
|
|
|
self.model.objects.bulk_create(new_components)
|
|
|
- messages.success(request, u"Added {} {} to {}.".format(
|
|
|
+ messages.success(request, "Added {} {} to {}.".format(
|
|
|
len(new_components), self.model._meta.verbose_name_plural, parent
|
|
|
))
|
|
|
if '_addanother' in request.POST:
|
|
|
@@ -178,27 +178,29 @@ class SiteListView(ObjectListView):
|
|
|
template_name = 'dcim/site_list.html'
|
|
|
|
|
|
|
|
|
-def site(request, slug):
|
|
|
-
|
|
|
- site = get_object_or_404(Site.objects.select_related('region', 'tenant__group'), slug=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': site,
|
|
|
- 'stats': stats,
|
|
|
- 'rack_groups': rack_groups,
|
|
|
- 'topology_maps': topology_maps,
|
|
|
- 'show_graphs': show_graphs,
|
|
|
- })
|
|
|
+class SiteView(View):
|
|
|
+
|
|
|
+ def get(self, request, slug):
|
|
|
+
|
|
|
+ site = get_object_or_404(Site.objects.select_related('region', 'tenant__group'), slug=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': site,
|
|
|
+ 'stats': stats,
|
|
|
+ 'rack_groups': rack_groups,
|
|
|
+ 'topology_maps': topology_maps,
|
|
|
+ 'show_graphs': show_graphs,
|
|
|
+ })
|
|
|
|
|
|
|
|
|
class SiteEditView(PermissionRequiredMixin, ObjectEditView):
|
|
|
@@ -290,8 +292,13 @@ class RackRoleBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
|
|
|
#
|
|
|
|
|
|
class RackListView(ObjectListView):
|
|
|
- queryset = Rack.objects.select_related('site', 'group', 'tenant', 'role').prefetch_related('devices__device_type')\
|
|
|
- .annotate(device_count=Count('devices', distinct=True))
|
|
|
+ queryset = Rack.objects.select_related(
|
|
|
+ 'site', 'group', 'tenant', 'role'
|
|
|
+ ).prefetch_related(
|
|
|
+ 'devices__device_type'
|
|
|
+ ).annotate(
|
|
|
+ device_count=Count('devices', distinct=True)
|
|
|
+ )
|
|
|
filter = filters.RackFilter
|
|
|
filter_form = forms.RackFilterForm
|
|
|
table = tables.RackTable
|
|
|
@@ -338,31 +345,33 @@ class RackElevationListView(View):
|
|
|
})
|
|
|
|
|
|
|
|
|
-def rack(request, pk):
|
|
|
-
|
|
|
- rack = get_object_or_404(Rack.objects.select_related('site__region', 'tenant__group', 'group', 'role'), pk=pk)
|
|
|
+class RackView(View):
|
|
|
|
|
|
- nonracked_devices = Device.objects.filter(rack=rack, position__isnull=True, parent_bay__isnull=True)\
|
|
|
- .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)
|
|
|
- reserved_units = {}
|
|
|
- for r in reservations:
|
|
|
- for u in r.units:
|
|
|
- reserved_units[u] = r
|
|
|
+ def get(self, request, pk):
|
|
|
|
|
|
- return render(request, 'dcim/rack.html', {
|
|
|
- 'rack': rack,
|
|
|
- '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(),
|
|
|
- })
|
|
|
+ rack = get_object_or_404(Rack.objects.select_related('site__region', 'tenant__group', 'group', 'role'), pk=pk)
|
|
|
+
|
|
|
+ nonracked_devices = Device.objects.filter(rack=rack, position__isnull=True, parent_bay__isnull=True)\
|
|
|
+ .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)
|
|
|
+ reserved_units = {}
|
|
|
+ for r in reservations:
|
|
|
+ for u in r.units:
|
|
|
+ reserved_units[u] = r
|
|
|
+
|
|
|
+ return render(request, 'dcim/rack.html', {
|
|
|
+ 'rack': rack,
|
|
|
+ '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):
|
|
|
@@ -481,53 +490,57 @@ class DeviceTypeListView(ObjectListView):
|
|
|
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
|
|
|
- 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', {
|
|
|
- '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,
|
|
|
- })
|
|
|
+ devicetype = get_object_or_404(DeviceType, pk=pk)
|
|
|
+
|
|
|
+ # Component tables
|
|
|
+ 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', {
|
|
|
+ '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):
|
|
|
@@ -727,70 +740,114 @@ class DeviceListView(ObjectListView):
|
|
|
template_name = 'dcim/device_list.html'
|
|
|
|
|
|
|
|
|
-def device(request, pk):
|
|
|
+class DeviceView(View):
|
|
|
|
|
|
- device = get_object_or_404(Device.objects.select_related(
|
|
|
- '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
|
|
|
- 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]
|
|
|
+ def get(self, request, pk):
|
|
|
|
|
|
- # Show graph button on interfaces only if at least one graph has been created.
|
|
|
- show_graphs = Graph.objects.filter(type=GRAPH_TYPE_INTERFACE).exists()
|
|
|
+ device = get_object_or_404(Device.objects.select_related(
|
|
|
+ '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
|
|
|
+ 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]
|
|
|
+
|
|
|
+ # Show graph button on interfaces only if at least one graph has been created.
|
|
|
+ show_graphs = Graph.objects.filter(type=GRAPH_TYPE_INTERFACE).exists()
|
|
|
+
|
|
|
+ return render(request, 'dcim/device.html', {
|
|
|
+ 'device': device,
|
|
|
+ 'console_ports': console_ports,
|
|
|
+ 'cs_ports': cs_ports,
|
|
|
+ 'power_ports': power_ports,
|
|
|
+ 'power_outlets': power_outlets,
|
|
|
+ 'interfaces': interfaces,
|
|
|
+ 'mgmt_interfaces': mgmt_interfaces,
|
|
|
+ 'device_bays': device_bays,
|
|
|
+ 'services': services,
|
|
|
+ 'secrets': secrets,
|
|
|
+ 'related_devices': related_devices,
|
|
|
+ 'show_graphs': show_graphs,
|
|
|
+ })
|
|
|
|
|
|
- return render(request, 'dcim/device.html', {
|
|
|
- 'device': device,
|
|
|
- 'console_ports': console_ports,
|
|
|
- 'cs_ports': cs_ports,
|
|
|
- 'power_ports': power_ports,
|
|
|
- 'power_outlets': power_outlets,
|
|
|
- 'interfaces': interfaces,
|
|
|
- 'mgmt_interfaces': mgmt_interfaces,
|
|
|
- 'device_bays': device_bays,
|
|
|
- '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):
|
|
|
@@ -851,30 +908,6 @@ class DeviceBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
|
|
|
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
|
|
|
#
|
|
|
@@ -897,7 +930,7 @@ def consoleport_connect(request, pk):
|
|
|
form = forms.ConsolePortConnectionForm(request.POST, instance=consoleport)
|
|
|
if form.is_valid():
|
|
|
consoleport = form.save()
|
|
|
- msg = u'Connected <a href="{}">{}</a> {} to <a href="{}">{}</a> {}'.format(
|
|
|
+ msg = 'Connected <a href="{}">{}</a> {} to <a href="{}">{}</a> {}'.format(
|
|
|
consoleport.device.get_absolute_url(),
|
|
|
escape(consoleport.device),
|
|
|
escape(consoleport.name),
|
|
|
@@ -911,9 +944,9 @@ def consoleport_connect(request, pk):
|
|
|
|
|
|
else:
|
|
|
form = forms.ConsolePortConnectionForm(instance=consoleport, initial={
|
|
|
- 'site': request.GET.get('site', consoleport.device.site),
|
|
|
- 'rack': request.GET.get('rack', None),
|
|
|
- 'console_server': request.GET.get('console_server', None),
|
|
|
+ 'site': request.GET.get('site'),
|
|
|
+ 'rack': request.GET.get('rack'),
|
|
|
+ 'console_server': request.GET.get('console_server'),
|
|
|
'connection_status': CONNECTION_STATUS_CONNECTED,
|
|
|
})
|
|
|
|
|
|
@@ -931,7 +964,7 @@ def consoleport_disconnect(request, pk):
|
|
|
|
|
|
if not consoleport.cs_port:
|
|
|
messages.warning(
|
|
|
- request, u"Cannot disconnect console port {}: It is not connected to anything.".format(consoleport)
|
|
|
+ request, "Cannot disconnect console port {}: It is not connected to anything.".format(consoleport)
|
|
|
)
|
|
|
return redirect('dcim:device', pk=consoleport.device.pk)
|
|
|
|
|
|
@@ -942,7 +975,7 @@ def consoleport_disconnect(request, pk):
|
|
|
consoleport.cs_port = None
|
|
|
consoleport.connection_status = None
|
|
|
consoleport.save()
|
|
|
- msg = u'Disconnected <a href="{}">{}</a> {} from <a href="{}">{}</a> {}'.format(
|
|
|
+ msg = 'Disconnected <a href="{}">{}</a> {} from <a href="{}">{}</a> {}'.format(
|
|
|
consoleport.device.get_absolute_url(),
|
|
|
escape(consoleport.device),
|
|
|
escape(consoleport.name),
|
|
|
@@ -1014,7 +1047,7 @@ def consoleserverport_connect(request, pk):
|
|
|
consoleport.cs_port = consoleserverport
|
|
|
consoleport.connection_status = form.cleaned_data['connection_status']
|
|
|
consoleport.save()
|
|
|
- msg = u'Connected <a href="{}">{}</a> {} to <a href="{}">{}</a> {}'.format(
|
|
|
+ msg = 'Connected <a href="{}">{}</a> {} to <a href="{}">{}</a> {}'.format(
|
|
|
consoleport.device.get_absolute_url(),
|
|
|
escape(consoleport.device),
|
|
|
escape(consoleport.name),
|
|
|
@@ -1028,9 +1061,9 @@ def consoleserverport_connect(request, pk):
|
|
|
|
|
|
else:
|
|
|
form = forms.ConsoleServerPortConnectionForm(initial={
|
|
|
- 'site': request.GET.get('site', consoleserverport.device.site),
|
|
|
- 'rack': request.GET.get('rack', None),
|
|
|
- 'device': request.GET.get('device', None),
|
|
|
+ 'site': request.GET.get('site'),
|
|
|
+ 'rack': request.GET.get('rack'),
|
|
|
+ 'device': request.GET.get('device'),
|
|
|
'connection_status': CONNECTION_STATUS_CONNECTED,
|
|
|
})
|
|
|
|
|
|
@@ -1048,7 +1081,7 @@ def consoleserverport_disconnect(request, pk):
|
|
|
|
|
|
if not hasattr(consoleserverport, 'connected_console'):
|
|
|
messages.warning(
|
|
|
- request, u"Cannot disconnect console server port {}: Nothing is connected to it.".format(consoleserverport)
|
|
|
+ request, "Cannot disconnect console server port {}: Nothing is connected to it.".format(consoleserverport)
|
|
|
)
|
|
|
return redirect('dcim:device', pk=consoleserverport.device.pk)
|
|
|
|
|
|
@@ -1059,7 +1092,7 @@ def consoleserverport_disconnect(request, pk):
|
|
|
consoleport.cs_port = None
|
|
|
consoleport.connection_status = None
|
|
|
consoleport.save()
|
|
|
- msg = u'Disconnected <a href="{}">{}</a> {} from <a href="{}">{}</a> {}'.format(
|
|
|
+ msg = 'Disconnected <a href="{}">{}</a> {} from <a href="{}">{}</a> {}'.format(
|
|
|
consoleport.device.get_absolute_url(),
|
|
|
escape(consoleport.device),
|
|
|
escape(consoleport.name),
|
|
|
@@ -1120,7 +1153,7 @@ def powerport_connect(request, pk):
|
|
|
form = forms.PowerPortConnectionForm(request.POST, instance=powerport)
|
|
|
if form.is_valid():
|
|
|
powerport = form.save()
|
|
|
- msg = u'Connected <a href="{}">{}</a> {} to <a href="{}">{}</a> {}'.format(
|
|
|
+ msg = 'Connected <a href="{}">{}</a> {} to <a href="{}">{}</a> {}'.format(
|
|
|
powerport.device.get_absolute_url(),
|
|
|
escape(powerport.device),
|
|
|
escape(powerport.name),
|
|
|
@@ -1134,9 +1167,9 @@ def powerport_connect(request, pk):
|
|
|
|
|
|
else:
|
|
|
form = forms.PowerPortConnectionForm(instance=powerport, initial={
|
|
|
- 'site': request.GET.get('site', powerport.device.site),
|
|
|
- 'rack': request.GET.get('rack', None),
|
|
|
- 'pdu': request.GET.get('pdu', None),
|
|
|
+ 'site': request.GET.get('site'),
|
|
|
+ 'rack': request.GET.get('rack'),
|
|
|
+ 'pdu': request.GET.get('pdu'),
|
|
|
'connection_status': CONNECTION_STATUS_CONNECTED,
|
|
|
})
|
|
|
|
|
|
@@ -1154,7 +1187,7 @@ def powerport_disconnect(request, pk):
|
|
|
|
|
|
if not powerport.power_outlet:
|
|
|
messages.warning(
|
|
|
- request, u"Cannot disconnect power port {}: It is not connected to an outlet.".format(powerport)
|
|
|
+ request, "Cannot disconnect power port {}: It is not connected to an outlet.".format(powerport)
|
|
|
)
|
|
|
return redirect('dcim:device', pk=powerport.device.pk)
|
|
|
|
|
|
@@ -1165,7 +1198,7 @@ def powerport_disconnect(request, pk):
|
|
|
powerport.power_outlet = None
|
|
|
powerport.connection_status = None
|
|
|
powerport.save()
|
|
|
- msg = u'Disconnected <a href="{}">{}</a> {} from <a href="{}">{}</a> {}'.format(
|
|
|
+ msg = 'Disconnected <a href="{}">{}</a> {} from <a href="{}">{}</a> {}'.format(
|
|
|
powerport.device.get_absolute_url(),
|
|
|
escape(powerport.device),
|
|
|
escape(powerport.name),
|
|
|
@@ -1237,7 +1270,7 @@ def poweroutlet_connect(request, pk):
|
|
|
powerport.power_outlet = poweroutlet
|
|
|
powerport.connection_status = form.cleaned_data['connection_status']
|
|
|
powerport.save()
|
|
|
- msg = u'Connected <a href="{}">{}</a> {} to <a href="{}">{}</a> {}'.format(
|
|
|
+ msg = 'Connected <a href="{}">{}</a> {} to <a href="{}">{}</a> {}'.format(
|
|
|
powerport.device.get_absolute_url(),
|
|
|
escape(powerport.device),
|
|
|
escape(powerport.name),
|
|
|
@@ -1251,9 +1284,9 @@ def poweroutlet_connect(request, pk):
|
|
|
|
|
|
else:
|
|
|
form = forms.PowerOutletConnectionForm(initial={
|
|
|
- 'site': request.GET.get('site', poweroutlet.device.site),
|
|
|
- 'rack': request.GET.get('rack', None),
|
|
|
- 'device': request.GET.get('device', None),
|
|
|
+ 'site': request.GET.get('site'),
|
|
|
+ 'rack': request.GET.get('rack'),
|
|
|
+ 'device': request.GET.get('device'),
|
|
|
'connection_status': CONNECTION_STATUS_CONNECTED,
|
|
|
})
|
|
|
|
|
|
@@ -1271,7 +1304,7 @@ def poweroutlet_disconnect(request, pk):
|
|
|
|
|
|
if not hasattr(poweroutlet, 'connected_port'):
|
|
|
messages.warning(
|
|
|
- request, u"Cannot disconnect power outlet {}: Nothing is connected to it.".format(poweroutlet)
|
|
|
+ request, "Cannot disconnect power outlet {}: Nothing is connected to it.".format(poweroutlet)
|
|
|
)
|
|
|
return redirect('dcim:device', pk=poweroutlet.device.pk)
|
|
|
|
|
|
@@ -1282,7 +1315,7 @@ def poweroutlet_disconnect(request, pk):
|
|
|
powerport.power_outlet = None
|
|
|
powerport.connection_status = None
|
|
|
powerport.save()
|
|
|
- msg = u'Disconnected <a href="{}">{}</a> {} from <a href="{}">{}</a> {}'.format(
|
|
|
+ msg = 'Disconnected <a href="{}">{}</a> {} from <a href="{}">{}</a> {}'.format(
|
|
|
powerport.device.get_absolute_url(),
|
|
|
escape(powerport.device),
|
|
|
escape(powerport.name),
|
|
|
@@ -1396,7 +1429,7 @@ def devicebay_populate(request, pk):
|
|
|
device_bay.save()
|
|
|
|
|
|
if not form.errors:
|
|
|
- messages.success(request, u"Added {} to {}.".format(device_bay.installed_device, device_bay))
|
|
|
+ messages.success(request, "Added {} to {}.".format(device_bay.installed_device, device_bay))
|
|
|
return redirect('dcim:device', pk=device_bay.device.pk)
|
|
|
|
|
|
else:
|
|
|
@@ -1420,7 +1453,7 @@ def devicebay_depopulate(request, pk):
|
|
|
removed_device = device_bay.installed_device
|
|
|
device_bay.installed_device = None
|
|
|
device_bay.save()
|
|
|
- messages.success(request, u"{} has been removed from {}.".format(removed_device, device_bay))
|
|
|
+ messages.success(request, "{} has been removed from {}.".format(removed_device, device_bay))
|
|
|
return redirect('dcim:device', pk=device_bay.device.pk)
|
|
|
|
|
|
else:
|
|
|
@@ -1483,11 +1516,11 @@ class DeviceBulkAddComponentView(View):
|
|
|
else:
|
|
|
for field, errors in component_form.errors.as_data().items():
|
|
|
for e in errors:
|
|
|
- form.add_error(field, u'{} {}: {}'.format(device, name, ', '.join(e)))
|
|
|
+ form.add_error(field, '{} {}: {}'.format(device, name, ', '.join(e)))
|
|
|
|
|
|
if not form.errors:
|
|
|
self.model.objects.bulk_create(new_components)
|
|
|
- messages.success(request, u"Added {} {} to {} devices.".format(
|
|
|
+ messages.success(request, "Added {} {} to {} devices.".format(
|
|
|
len(new_components), self.model._meta.verbose_name_plural, len(form.cleaned_data['pk'])
|
|
|
))
|
|
|
return redirect('dcim:device_list')
|
|
|
@@ -1497,7 +1530,7 @@ class DeviceBulkAddComponentView(View):
|
|
|
|
|
|
selected_devices = Device.objects.filter(pk__in=pk_list)
|
|
|
if not selected_devices:
|
|
|
- messages.warning(request, u"No devices were selected.")
|
|
|
+ messages.warning(request, "No devices were selected.")
|
|
|
return redirect('dcim:device_list')
|
|
|
|
|
|
return render(request, 'dcim/device_bulk_add_component.html', {
|
|
|
@@ -1559,7 +1592,7 @@ def interfaceconnection_add(request, pk):
|
|
|
if form.is_valid():
|
|
|
|
|
|
interfaceconnection = form.save()
|
|
|
- msg = u'Connected <a href="{}">{}</a> {} to <a href="{}">{}</a> {}'.format(
|
|
|
+ msg = 'Connected <a href="{}">{}</a> {} to <a href="{}">{}</a> {}'.format(
|
|
|
interfaceconnection.interface_a.device.get_absolute_url(),
|
|
|
escape(interfaceconnection.interface_a.device),
|
|
|
escape(interfaceconnection.interface_a.name),
|
|
|
@@ -1583,11 +1616,11 @@ def interfaceconnection_add(request, pk):
|
|
|
|
|
|
else:
|
|
|
form = forms.InterfaceConnectionForm(device, initial={
|
|
|
- 'interface_a': request.GET.get('interface_a', None),
|
|
|
- 'site_b': request.GET.get('site_b', device.site),
|
|
|
- 'rack_b': request.GET.get('rack_b', None),
|
|
|
- 'device_b': request.GET.get('device_b', None),
|
|
|
- 'interface_b': request.GET.get('interface_b', None),
|
|
|
+ 'interface_a': request.GET.get('interface_a'),
|
|
|
+ 'site_b': request.GET.get('site_b'),
|
|
|
+ 'rack_b': request.GET.get('rack_b'),
|
|
|
+ 'device_b': request.GET.get('device_b'),
|
|
|
+ 'interface_b': request.GET.get('interface_b'),
|
|
|
})
|
|
|
|
|
|
return render(request, 'dcim/interfaceconnection_edit.html', {
|
|
|
@@ -1607,7 +1640,7 @@ def interfaceconnection_delete(request, pk):
|
|
|
form = forms.InterfaceConnectionDeletionForm(request.POST)
|
|
|
if form.is_valid():
|
|
|
interfaceconnection.delete()
|
|
|
- msg = u'Disconnected <a href="{}">{}</a> {} from <a href="{}">{}</a> {}'.format(
|
|
|
+ msg = 'Disconnected <a href="{}">{}</a> {} from <a href="{}">{}</a> {}'.format(
|
|
|
interfaceconnection.interface_a.device.get_absolute_url(),
|
|
|
escape(interfaceconnection.interface_a.device),
|
|
|
escape(interfaceconnection.interface_a.name),
|