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

3552 lines
110 KiB
Python
Raw Normal View History

import traceback
2016-03-01 11:23:03 -05:00
from django.contrib import messages
2019-03-21 17:47:43 -04:00
from django.contrib.contenttypes.models import ContentType
from django.core.paginator import EmptyPage, PageNotAnInteger
from django.db import transaction
2021-09-27 17:00:13 -04:00
from django.db.models import Prefetch
from django.forms import ModelMultipleChoiceField, MultipleHiddenInput, modelformset_factory
2016-03-01 11:23:03 -05:00
from django.shortcuts import get_object_or_404, redirect, render
from django.urls import reverse
from django.utils.html import escape
from django.utils.safestring import mark_safe
from django.utils.translation import gettext as _
from django.views.generic import View
from jinja2.exceptions import TemplateError
2016-03-01 11:23:03 -05:00
from circuits.models import Circuit, CircuitTermination
2021-12-17 16:12:03 -05:00
from extras.views import ObjectConfigContextView
from ipam.models import ASN, IPAddress, Prefix, VLAN, VLANGroup
from ipam.tables import InterfaceVLANTable
2020-11-11 16:07:38 -05:00
from netbox.views import generic
from utilities.forms import ConfirmationForm
from utilities.paginator import EnhancedPaginator, get_paginate_count
from utilities.permissions import get_permission_for_model
from utilities.utils import count_related
from utilities.views import GetReturnURLMixin, ObjectPermissionRequiredMixin, ViewTab, register_model_view
from virtualization.models import VirtualMachine
2021-04-29 16:38:56 -04:00
from . import filtersets, forms, tables
from .choices import DeviceFaceChoices
2021-12-21 10:48:10 -05:00
from .models import *
2016-03-01 11:23:03 -05:00
2022-07-07 12:48:44 -04:00
CABLE_TERMINATION_TYPES = {
'dcim.consoleport': ConsolePort,
'dcim.consoleserverport': ConsoleServerPort,
'dcim.powerport': PowerPort,
'dcim.poweroutlet': PowerOutlet,
'dcim.interface': Interface,
'dcim.frontport': FrontPort,
'dcim.rearport': RearPort,
'dcim.powerfeed': PowerFeed,
'circuits.circuittermination': CircuitTermination,
}
2016-03-01 11:23:03 -05:00
class DeviceComponentsView(generic.ObjectChildrenView):
2021-10-20 14:22:11 -04:00
queryset = Device.objects.all()
def get_children(self, request, parent):
return self.child_model.objects.restrict(request.user, 'view').filter(device=parent)
2021-10-20 14:22:11 -04:00
class DeviceTypeComponentsView(DeviceComponentsView):
queryset = DeviceType.objects.all()
template_name = 'dcim/devicetype/component_templates.html'
2021-12-21 10:28:28 -05:00
viewname = None # Used for return_url resolution
def get_children(self, request, parent):
return self.child_model.objects.restrict(request.user, 'view').filter(device_type=parent)
2021-12-21 10:28:28 -05:00
def get_extra_context(self, request, instance):
return {
'return_url': reverse(self.viewname, kwargs={'pk': instance.pk}),
}
2021-12-21 10:28:28 -05:00
2021-12-17 12:18:37 -05:00
class ModuleTypeComponentsView(DeviceComponentsView):
queryset = ModuleType.objects.all()
template_name = 'dcim/moduletype/component_templates.html'
viewname = None # Used for return_url resolution
2021-12-17 12:18:37 -05:00
def get_children(self, request, parent):
return self.child_model.objects.restrict(request.user, 'view').filter(module_type=parent)
def get_extra_context(self, request, instance):
return {
'return_url': reverse(self.viewname, kwargs={'pk': instance.pk}),
}
2021-12-17 12:18:37 -05:00
2020-05-21 16:34:15 -04:00
class BulkDisconnectView(GetReturnURLMixin, ObjectPermissionRequiredMixin, View):
"""
An extendable view for disconnection console/power/interface components in bulk.
"""
queryset = None
template_name = 'dcim/bulk_disconnect.html'
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
# Create a new Form class from ConfirmationForm
class _Form(ConfirmationForm):
pk = ModelMultipleChoiceField(
queryset=self.queryset,
widget=MultipleHiddenInput()
)
self.form = _Form
def get_required_permission(self):
return get_permission_for_model(self.queryset.model, 'change')
def post(self, request):
selected_objects = []
return_url = self.get_return_url(request)
if '_confirm' in request.POST:
form = self.form(request.POST)
if form.is_valid():
with transaction.atomic():
count = 0
for obj in self.queryset.filter(pk__in=form.cleaned_data['pk']):
if obj.cable is None:
continue
obj.cable.delete()
count += 1
messages.success(request, "Disconnected {} {}".format(
count, self.queryset.model._meta.verbose_name_plural
))
return redirect(return_url)
else:
form = self.form(initial={'pk': request.POST.getlist('pk')})
selected_objects = self.queryset.filter(pk__in=form.initial['pk'])
return render(request, self.template_name, {
'form': form,
'obj_type_plural': self.queryset.model._meta.verbose_name_plural,
'selected_objects': selected_objects,
'return_url': return_url,
})
class PathTraceView(generic.ObjectView):
"""
Trace a cable path beginning from the given path endpoint (origin).
"""
additional_permissions = ['dcim.view_cable']
template_name = 'dcim/cable_trace.html'
def dispatch(self, request, *args, **kwargs):
model = kwargs.pop('model')
self.queryset = model.objects.all()
return super().dispatch(request, *args, **kwargs)
def get_extra_context(self, request, instance):
related_paths = []
# If tracing a PathEndpoint, locate the CablePath (if one exists) by its origin
if isinstance(instance, PathEndpoint):
path = instance._path
# Otherwise, find all CablePaths which traverse the specified object
else:
related_paths = CablePath.objects.filter(_nodes__contains=instance)
# Check for specification of a particular path (when tracing pass-through ports)
try:
path_id = int(request.GET.get('cablepath_id'))
except TypeError:
path_id = None
if path_id in list(related_paths.values_list('pk', flat=True)):
path = CablePath.objects.get(pk=path_id)
else:
path = related_paths.first()
# No paths found
if path is None:
return {
'path': None
}
# Get the total length of the cable and whether the length is definitive (fully defined)
total_length, is_definitive = path.get_total_length() if path else (None, False)
# Determine the path to the SVG trace image
api_viewname = f"{path.origin_type.app_label}-api:{path.origin_type.model}-trace"
svg_url = f"{reverse(api_viewname, kwargs={'pk': path.origins[0].pk})}?render=svg"
return {
'path': path,
'related_paths': related_paths,
'total_length': total_length,
'is_definitive': is_definitive,
'svg_url': svg_url,
}
2017-02-28 12:11:43 -05:00
#
# Regions
#
2020-11-11 16:07:38 -05:00
class RegionListView(generic.ObjectListView):
queryset = Region.objects.add_related_count(
Region.objects.all(),
Site,
'region',
'site_count',
cumulative=True
)
2021-04-29 16:38:56 -04:00
filterset = filtersets.RegionFilterSet
filterset_form = forms.RegionFilterForm
2017-02-28 12:11:43 -05:00
table = tables.RegionTable
@register_model_view(Region)
class RegionView(generic.ObjectView):
queryset = Region.objects.all()
def get_extra_context(self, request, instance):
regions = instance.get_descendants(include_self=True)
related_models = (
(Site.objects.restrict(request.user, 'view').filter(region__in=regions), 'region_id'),
(Location.objects.restrict(request.user, 'view').filter(site__region__in=regions), 'region_id'),
(Rack.objects.restrict(request.user, 'view').filter(site__region__in=regions), 'region_id'),
)
return {
'related_models': related_models,
}
@register_model_view(Region, 'edit')
2020-11-11 16:07:38 -05:00
class RegionEditView(generic.ObjectEditView):
queryset = Region.objects.all()
form = forms.RegionForm
2017-02-28 12:11:43 -05:00
@register_model_view(Region, 'delete')
2020-11-11 16:07:38 -05:00
class RegionDeleteView(generic.ObjectDeleteView):
queryset = Region.objects.all()
2020-11-11 16:07:38 -05:00
class RegionBulkImportView(generic.BulkImportView):
2020-05-21 11:58:27 -04:00
queryset = Region.objects.all()
model_form = forms.RegionImportForm
2017-07-18 01:50:26 +03:00
class RegionBulkEditView(generic.BulkEditView):
queryset = Region.objects.add_related_count(
Region.objects.all(),
Site,
'region',
'site_count',
cumulative=True
)
2021-04-29 16:38:56 -04:00
filterset = filtersets.RegionFilterSet
table = tables.RegionTable
form = forms.RegionBulkEditForm
2020-11-11 16:07:38 -05:00
class RegionBulkDeleteView(generic.BulkDeleteView):
queryset = Region.objects.add_related_count(
Region.objects.all(),
Site,
'region',
'site_count',
cumulative=True
)
2021-04-29 16:38:56 -04:00
filterset = filtersets.RegionFilterSet
table = tables.RegionTable
2017-02-28 12:11:43 -05:00
#
# Site groups
#
class SiteGroupListView(generic.ObjectListView):
queryset = SiteGroup.objects.add_related_count(
SiteGroup.objects.all(),
Site,
'group',
'site_count',
cumulative=True
)
2021-04-29 16:38:56 -04:00
filterset = filtersets.SiteGroupFilterSet
filterset_form = forms.SiteGroupFilterForm
table = tables.SiteGroupTable
@register_model_view(SiteGroup)
class SiteGroupView(generic.ObjectView):
queryset = SiteGroup.objects.all()
def get_extra_context(self, request, instance):
groups = instance.get_descendants(include_self=True)
related_models = (
(Site.objects.restrict(request.user, 'view').filter(group__in=groups), 'group_id'),
(Location.objects.restrict(request.user, 'view').filter(site__group__in=groups), 'site_group_id'),
(Rack.objects.restrict(request.user, 'view').filter(site__group__in=groups), 'site_group_id'),
)
return {
'related_models': related_models,
}
@register_model_view(SiteGroup, 'edit')
class SiteGroupEditView(generic.ObjectEditView):
queryset = SiteGroup.objects.all()
form = forms.SiteGroupForm
@register_model_view(SiteGroup, 'delete')
class SiteGroupDeleteView(generic.ObjectDeleteView):
queryset = SiteGroup.objects.all()
class SiteGroupBulkImportView(generic.BulkImportView):
queryset = SiteGroup.objects.all()
model_form = forms.SiteGroupImportForm
class SiteGroupBulkEditView(generic.BulkEditView):
queryset = SiteGroup.objects.add_related_count(
SiteGroup.objects.all(),
Site,
'group',
'site_count',
cumulative=True
)
2021-04-29 16:38:56 -04:00
filterset = filtersets.SiteGroupFilterSet
table = tables.SiteGroupTable
form = forms.SiteGroupBulkEditForm
class SiteGroupBulkDeleteView(generic.BulkDeleteView):
queryset = SiteGroup.objects.add_related_count(
SiteGroup.objects.all(),
Site,
'group',
'site_count',
cumulative=True
)
2021-04-29 16:38:56 -04:00
filterset = filtersets.SiteGroupFilterSet
table = tables.SiteGroupTable
2016-03-01 11:23:03 -05:00
#
# Sites
#
2020-11-11 16:07:38 -05:00
class SiteListView(generic.ObjectListView):
queryset = Site.objects.all()
2021-04-29 16:38:56 -04:00
filterset = filtersets.SiteFilterSet
filterset_form = forms.SiteFilterForm
table = tables.SiteTable
2016-03-01 11:23:03 -05:00
@register_model_view(Site)
2020-11-11 16:07:38 -05:00
class SiteView(generic.ObjectView):
queryset = Site.objects.prefetch_related('tenant__group')
def get_extra_context(self, request, instance):
related_models = (
# DCIM
(Location.objects.restrict(request.user, 'view').filter(site=instance), 'site_id'),
(Rack.objects.restrict(request.user, 'view').filter(site=instance), 'site_id'),
(Device.objects.restrict(request.user, 'view').filter(site=instance), 'site_id'),
# Virtualization
(VirtualMachine.objects.restrict(request.user, 'view').filter(cluster__site=instance), 'site_id'),
# IPAM
(Prefix.objects.restrict(request.user, 'view').filter(site=instance), 'site_id'),
(ASN.objects.restrict(request.user, 'view').filter(sites=instance), 'site_id'),
(VLANGroup.objects.restrict(request.user, 'view').filter(
scope_type=ContentType.objects.get_for_model(Site),
scope_id=instance.pk
), 'site_id'),
(VLAN.objects.restrict(request.user, 'view').filter(site=instance), 'site_id'),
# Circuits
(Circuit.objects.restrict(request.user, 'view').filter(terminations__site=instance).distinct(), 'site_id'),
)
locations = Location.objects.add_related_count(
Location.objects.all(),
Rack,
'location',
'rack_count',
cumulative=True
2021-04-05 11:04:12 -04:00
)
locations = Location.objects.add_related_count(
locations,
Device,
'location',
'device_count',
cumulative=True
).restrict(request.user, 'view').filter(site=instance)
nonracked_devices = Device.objects.filter(
site=instance,
rack__isnull=True,
parent_bay__isnull=True
).prefetch_related('device_type__manufacturer', 'parent_bay', 'device_role')
return {
'related_models': related_models,
'locations': locations,
'nonracked_devices': nonracked_devices.order_by('-pk')[:10],
'total_nonracked_devices_count': nonracked_devices.count(),
}
2016-03-01 11:23:03 -05:00
@register_model_view(Site, 'edit')
2020-11-11 16:07:38 -05:00
class SiteEditView(generic.ObjectEditView):
queryset = Site.objects.all()
form = forms.SiteForm
2016-03-01 11:23:03 -05:00
@register_model_view(Site, 'delete')
2020-11-11 16:07:38 -05:00
class SiteDeleteView(generic.ObjectDeleteView):
queryset = Site.objects.all()
2016-03-01 11:23:03 -05:00
2020-11-11 16:07:38 -05:00
class SiteBulkImportView(generic.BulkImportView):
2020-05-21 11:58:27 -04:00
queryset = Site.objects.all()
model_form = forms.SiteImportForm
2016-03-01 11:23:03 -05:00
2020-11-11 16:07:38 -05:00
class SiteBulkEditView(generic.BulkEditView):
queryset = Site.objects.all()
2021-04-29 16:38:56 -04:00
filterset = filtersets.SiteFilterSet
table = tables.SiteTable
2016-07-28 15:30:29 -04:00
form = forms.SiteBulkEditForm
2020-11-11 16:07:38 -05:00
class SiteBulkDeleteView(generic.BulkDeleteView):
queryset = Site.objects.all()
2021-04-29 16:38:56 -04:00
filterset = filtersets.SiteFilterSet
table = tables.SiteTable
2016-03-30 12:26:37 -04:00
#
# Locations
2016-03-30 12:26:37 -04:00
#
class LocationListView(generic.ObjectListView):
queryset = Location.objects.add_related_count(
Location.objects.add_related_count(
Location.objects.all(),
Device,
'location',
'device_count',
cumulative=True
),
2020-03-11 14:40:29 -04:00
Rack,
'location',
2020-03-11 14:40:29 -04:00
'rack_count',
cumulative=True
)
2021-04-29 16:38:56 -04:00
filterset = filtersets.LocationFilterSet
filterset_form = forms.LocationFilterForm
table = tables.LocationTable
2016-03-30 12:26:37 -04:00
@register_model_view(Location)
class LocationView(generic.ObjectView):
queryset = Location.objects.all()
def get_extra_context(self, request, instance):
locations = instance.get_descendants(include_self=True)
related_models = (
(Rack.objects.restrict(request.user, 'view').filter(location__in=locations), 'location_id'),
(Device.objects.restrict(request.user, 'view').filter(location__in=locations), 'location_id'),
)
nonracked_devices = Device.objects.filter(
location=instance,
rack__isnull=True,
parent_bay__isnull=True
).prefetch_related('device_type__manufacturer', 'parent_bay', 'device_role')
return {
'related_models': related_models,
'nonracked_devices': nonracked_devices.order_by('-pk')[:10],
'total_nonracked_devices_count': nonracked_devices.count(),
}
@register_model_view(Location, 'edit')
class LocationEditView(generic.ObjectEditView):
queryset = Location.objects.all()
form = forms.LocationForm
2016-03-30 12:26:37 -04:00
@register_model_view(Location, 'delete')
class LocationDeleteView(generic.ObjectDeleteView):
queryset = Location.objects.all()
class LocationBulkImportView(generic.BulkImportView):
queryset = Location.objects.all()
model_form = forms.LocationImportForm
class LocationBulkEditView(generic.BulkEditView):
queryset = Location.objects.add_related_count(
Location.objects.all(),
Rack,
'location',
'rack_count',
cumulative=True
).prefetch_related('site')
2021-04-29 16:38:56 -04:00
filterset = filtersets.LocationFilterSet
table = tables.LocationTable
form = forms.LocationBulkEditForm
class LocationBulkDeleteView(generic.BulkDeleteView):
queryset = Location.objects.add_related_count(
Location.objects.all(),
Rack,
'location',
'rack_count',
cumulative=True
).prefetch_related('site')
2021-04-29 16:38:56 -04:00
filterset = filtersets.LocationFilterSet
table = tables.LocationTable
2016-03-30 12:26:37 -04:00
2016-08-10 11:52:27 -04:00
#
# Rack roles
#
2020-11-11 16:07:38 -05:00
class RackRoleListView(generic.ObjectListView):
queryset = RackRole.objects.annotate(
rack_count=count_related(Rack, 'role')
)
filterset = filtersets.RackRoleFilterSet
filterset_form = forms.RackRoleFilterForm
2016-08-10 11:52:27 -04:00
table = tables.RackRoleTable
@register_model_view(RackRole)
class RackRoleView(generic.ObjectView):
queryset = RackRole.objects.all()
def get_extra_context(self, request, instance):
related_models = (
(Rack.objects.restrict(request.user, 'view').filter(role=instance), 'role_id'),
)
return {
'related_models': related_models,
}
@register_model_view(RackRole, 'edit')
2020-11-11 16:07:38 -05:00
class RackRoleEditView(generic.ObjectEditView):
queryset = RackRole.objects.all()
form = forms.RackRoleForm
2016-08-10 11:52:27 -04:00
@register_model_view(RackRole, 'delete')
2020-11-11 16:07:38 -05:00
class RackRoleDeleteView(generic.ObjectDeleteView):
queryset = RackRole.objects.all()
2020-11-11 16:07:38 -05:00
class RackRoleBulkImportView(generic.BulkImportView):
2020-05-21 11:58:27 -04:00
queryset = RackRole.objects.all()
model_form = forms.RackRoleImportForm
class RackRoleBulkEditView(generic.BulkEditView):
queryset = RackRole.objects.annotate(
rack_count=count_related(Rack, 'role')
)
2021-04-29 16:38:56 -04:00
filterset = filtersets.RackRoleFilterSet
table = tables.RackRoleTable
form = forms.RackRoleBulkEditForm
2020-11-11 16:07:38 -05:00
class RackRoleBulkDeleteView(generic.BulkDeleteView):
queryset = RackRole.objects.annotate(
rack_count=count_related(Rack, 'role')
)
table = tables.RackRoleTable
2016-08-10 11:52:27 -04:00
2016-03-01 11:23:03 -05:00
#
# Racks
#
2020-11-11 16:07:38 -05:00
class RackListView(generic.ObjectListView):
queryset = Rack.objects.annotate(
device_count=count_related(Device, 'rack')
)
2021-04-29 16:38:56 -04:00
filterset = filtersets.RackFilterSet
filterset_form = forms.RackFilterForm
table = tables.RackTable
template_name = 'dcim/rack_list.html'
2016-03-01 11:23:03 -05:00
2020-11-11 16:07:38 -05:00
class RackElevationListView(generic.ObjectListView):
"""
Display a set of rack elevations side-by-side.
"""
queryset = Rack.objects.prefetch_related('role')
def get(self, request):
2021-04-29 16:38:56 -04:00
racks = filtersets.RackFilterSet(request.GET, self.queryset).qs
total_count = racks.count()
2022-11-30 15:22:13 -05:00
# Ordering
2022-09-01 11:12:01 -07:00
ORDERING_CHOICES = {
'name': 'Name (A-Z)',
'-name': 'Name (Z-A)',
'facility_id': 'Facility ID (A-Z)',
'-facility_id': 'Facility ID (Z-A)',
}
2022-11-30 15:22:13 -05:00
sort = request.GET.get('sort', 'name')
2022-09-01 11:12:01 -07:00
if sort not in ORDERING_CHOICES:
sort = 'name'
2022-11-30 15:22:13 -05:00
sort_field = sort.replace("name", "_name") # Use natural ordering
racks = racks.order_by(sort_field)
# Pagination
per_page = get_paginate_count(request)
page_number = request.GET.get('page', 1)
paginator = EnhancedPaginator(racks, per_page)
try:
page = paginator.page(page_number)
except PageNotAnInteger:
page = paginator.page(1)
except EmptyPage:
page = paginator.page(paginator.num_pages)
# Determine rack face
rack_face = request.GET.get('face', DeviceFaceChoices.FACE_FRONT)
if rack_face not in DeviceFaceChoices.values():
rack_face = DeviceFaceChoices.FACE_FRONT
return render(request, 'dcim/rack_elevation_list.html', {
'paginator': paginator,
'page': page,
'total_count': total_count,
'sort': sort,
2022-09-01 11:15:23 -07:00
'sort_display_name': ORDERING_CHOICES[sort],
2022-09-01 11:12:01 -07:00
'sort_choices': ORDERING_CHOICES,
'rack_face': rack_face,
'filter_form': forms.RackElevationFilterForm(request.GET),
'model': self.queryset.model,
})
@register_model_view(Rack)
2020-11-11 16:07:38 -05:00
class RackView(generic.ObjectView):
queryset = Rack.objects.prefetch_related('site__region', 'tenant__group', 'location', 'role')
2016-03-01 11:23:03 -05:00
def get_extra_context(self, request, instance):
related_models = (
(Device.objects.restrict(request.user, 'view').filter(rack=instance), 'rack_id'),
(PowerFeed.objects.restrict(request.user).filter(rack=instance), 'rack_id'),
)
# Get 0U devices located within the rack
nonracked_devices = Device.objects.filter(
rack=instance,
position__isnull=True,
parent_bay__isnull=True
).prefetch_related('device_type__manufacturer', 'parent_bay', 'device_role')
peer_racks = Rack.objects.restrict(request.user, 'view').filter(site=instance.site)
if instance.location:
peer_racks = peer_racks.filter(location=instance.location)
else:
peer_racks = peer_racks.filter(location__isnull=True)
next_rack = peer_racks.filter(_name__gt=instance._name).first()
prev_rack = peer_racks.filter(_name__lt=instance._name).reverse().first()
# Determine any additional parameters to pass when embedding the rack elevations
svg_extra = '&'.join([
f'highlight=id:{pk}' for pk in request.GET.getlist('device')
])
return {
'related_models': related_models,
'nonracked_devices': nonracked_devices,
'next_rack': next_rack,
'prev_rack': prev_rack,
'svg_extra': svg_extra,
}
2016-03-01 11:23:03 -05:00
@register_model_view(Rack, 'reservations')
class RackRackReservationsView(generic.ObjectChildrenView):
queryset = Rack.objects.all()
child_model = RackReservation
table = tables.RackReservationTable
filterset = filtersets.RackReservationFilterSet
template_name = 'dcim/rack/reservations.html'
tab = ViewTab(
label=_('Reservations'),
badge=lambda obj: obj.reservations.count(),
permission='dcim.view_rackreservation',
weight=510,
hide_if_empty=True
)
def get_children(self, request, parent):
return parent.reservations.restrict(request.user, 'view')
@register_model_view(Rack, 'edit')
2020-11-11 16:07:38 -05:00
class RackEditView(generic.ObjectEditView):
queryset = Rack.objects.all()
form = forms.RackForm
template_name = 'dcim/rack_edit.html'
2016-03-01 11:23:03 -05:00
@register_model_view(Rack, 'delete')
2020-11-11 16:07:38 -05:00
class RackDeleteView(generic.ObjectDeleteView):
queryset = Rack.objects.all()
2016-03-01 11:23:03 -05:00
2020-11-11 16:07:38 -05:00
class RackBulkImportView(generic.BulkImportView):
2020-05-21 11:58:27 -04:00
queryset = Rack.objects.all()
model_form = forms.RackImportForm
2016-03-01 11:23:03 -05:00
2020-11-11 16:07:38 -05:00
class RackBulkEditView(generic.BulkEditView):
queryset = Rack.objects.all()
2021-04-29 16:38:56 -04:00
filterset = filtersets.RackFilterSet
table = tables.RackTable
2016-05-18 16:02:53 -04:00
form = forms.RackBulkEditForm
2016-03-01 11:23:03 -05:00
2020-11-11 16:07:38 -05:00
class RackBulkDeleteView(generic.BulkDeleteView):
queryset = Rack.objects.all()
2021-04-29 16:38:56 -04:00
filterset = filtersets.RackFilterSet
table = tables.RackTable
2016-03-01 11:23:03 -05:00
#
# Rack reservations
#
2020-11-11 16:07:38 -05:00
class RackReservationListView(generic.ObjectListView):
queryset = RackReservation.objects.all()
2021-04-29 16:38:56 -04:00
filterset = filtersets.RackReservationFilterSet
filterset_form = forms.RackReservationFilterForm
table = tables.RackReservationTable
@register_model_view(RackReservation)
2020-11-11 16:07:38 -05:00
class RackReservationView(generic.ObjectView):
queryset = RackReservation.objects.all()
@register_model_view(RackReservation, 'edit')
2020-11-11 16:07:38 -05:00
class RackReservationEditView(generic.ObjectEditView):
queryset = RackReservation.objects.all()
form = forms.RackReservationForm
2021-12-14 11:28:13 -05:00
def alter_object(self, obj, request, args, kwargs):
if not obj.pk:
if 'rack' in request.GET:
obj.rack = get_object_or_404(Rack, pk=request.GET.get('rack'))
obj.user = request.user
return obj
@register_model_view(RackReservation, 'delete')
2020-11-11 16:07:38 -05:00
class RackReservationDeleteView(generic.ObjectDeleteView):
queryset = RackReservation.objects.all()
2020-11-11 16:07:38 -05:00
class RackReservationImportView(generic.BulkImportView):
2020-05-21 11:58:27 -04:00
queryset = RackReservation.objects.all()
model_form = forms.RackReservationImportForm
2020-03-06 17:14:26 -05:00
def save_object(self, object_form, request):
"""
Assign the currently authenticated user to the RackReservation.
"""
instance = object_form.save(commit=False)
instance.user = request.user
instance.save()
return instance
2020-03-06 17:14:26 -05:00
2020-11-11 16:07:38 -05:00
class RackReservationBulkEditView(generic.BulkEditView):
queryset = RackReservation.objects.all()
2021-04-29 16:38:56 -04:00
filterset = filtersets.RackReservationFilterSet
table = tables.RackReservationTable
form = forms.RackReservationBulkEditForm
2020-11-11 16:07:38 -05:00
class RackReservationBulkDeleteView(generic.BulkDeleteView):
queryset = RackReservation.objects.all()
2021-04-29 16:38:56 -04:00
filterset = filtersets.RackReservationFilterSet
table = tables.RackReservationTable
2016-05-13 15:22:31 -04:00
#
# Manufacturers
#
2020-11-11 16:07:38 -05:00
class ManufacturerListView(generic.ObjectListView):
queryset = Manufacturer.objects.annotate(
devicetype_count=count_related(DeviceType, 'manufacturer'),
moduletype_count=count_related(ModuleType, 'manufacturer'),
inventoryitem_count=count_related(InventoryItem, 'manufacturer'),
platform_count=count_related(Platform, 'manufacturer')
)
filterset = filtersets.ManufacturerFilterSet
filterset_form = forms.ManufacturerFilterForm
2016-05-18 16:02:53 -04:00
table = tables.ManufacturerTable
2016-05-13 15:22:31 -04:00
@register_model_view(Manufacturer)
class ManufacturerView(generic.ObjectView):
queryset = Manufacturer.objects.all()
def get_extra_context(self, request, instance):
related_models = (
(DeviceType.objects.restrict(request.user, 'view').filter(manufacturer=instance), 'manufacturer_id'),
(ModuleType.objects.restrict(request.user, 'view').filter(manufacturer=instance), 'manufacturer_id'),
(InventoryItem.objects.restrict(request.user, 'view').filter(manufacturer=instance), 'manufacturer_id'),
(Platform.objects.restrict(request.user, 'view').filter(manufacturer=instance), 'manufacturer_id'),
)
return {
'related_models': related_models,
}
@register_model_view(Manufacturer, 'edit')
2020-11-11 16:07:38 -05:00
class ManufacturerEditView(generic.ObjectEditView):
queryset = Manufacturer.objects.all()
form = forms.ManufacturerForm
2016-05-13 15:22:31 -04:00
@register_model_view(Manufacturer, 'delete')
2020-11-11 16:07:38 -05:00
class ManufacturerDeleteView(generic.ObjectDeleteView):
queryset = Manufacturer.objects.all()
2020-11-11 16:07:38 -05:00
class ManufacturerBulkImportView(generic.BulkImportView):
2020-05-21 11:58:27 -04:00
queryset = Manufacturer.objects.all()
model_form = forms.ManufacturerImportForm
class ManufacturerBulkEditView(generic.BulkEditView):
queryset = Manufacturer.objects.annotate(
devicetype_count=count_related(DeviceType, 'manufacturer'),
moduletype_count=count_related(ModuleType, 'manufacturer'),
inventoryitem_count=count_related(InventoryItem, 'manufacturer'),
platform_count=count_related(Platform, 'manufacturer')
)
2021-04-29 16:38:56 -04:00
filterset = filtersets.ManufacturerFilterSet
table = tables.ManufacturerTable
form = forms.ManufacturerBulkEditForm
2020-11-11 16:07:38 -05:00
class ManufacturerBulkDeleteView(generic.BulkDeleteView):
queryset = Manufacturer.objects.annotate(
devicetype_count=count_related(DeviceType, 'manufacturer'),
moduletype_count=count_related(ModuleType, 'manufacturer'),
inventoryitem_count=count_related(InventoryItem, 'manufacturer'),
platform_count=count_related(Platform, 'manufacturer')
)
table = tables.ManufacturerTable
2016-05-13 15:22:31 -04:00
#
# Device types
#
2020-11-11 16:07:38 -05:00
class DeviceTypeListView(generic.ObjectListView):
queryset = DeviceType.objects.annotate(
instance_count=count_related(Device, 'device_type')
)
2021-04-29 16:38:56 -04:00
filterset = filtersets.DeviceTypeFilterSet
filterset_form = forms.DeviceTypeFilterForm
table = tables.DeviceTypeTable
@register_model_view(DeviceType)
2020-11-11 16:07:38 -05:00
class DeviceTypeView(generic.ObjectView):
queryset = DeviceType.objects.all()
def get_extra_context(self, request, instance):
related_models = (
(Device.objects.restrict(request.user).filter(device_type=instance), 'device_type_id'),
)
return {
'related_models': related_models,
}
@register_model_view(DeviceType, 'edit')
class DeviceTypeEditView(generic.ObjectEditView):
queryset = DeviceType.objects.all()
form = forms.DeviceTypeForm
@register_model_view(DeviceType, 'delete')
class DeviceTypeDeleteView(generic.ObjectDeleteView):
queryset = DeviceType.objects.all()
@register_model_view(DeviceType, 'consoleports', path='console-ports')
class DeviceTypeConsolePortsView(DeviceTypeComponentsView):
child_model = ConsolePortTemplate
table = tables.ConsolePortTemplateTable
filterset = filtersets.ConsolePortTemplateFilterSet
2021-12-21 10:28:28 -05:00
viewname = 'dcim:devicetype_consoleports'
tab = ViewTab(
label=_('Console Ports'),
badge=lambda obj: obj.consoleporttemplates.count(),
permission='dcim.view_consoleporttemplate',
weight=550,
hide_if_empty=True
)
@register_model_view(DeviceType, 'consoleserverports', path='console-server-ports')
class DeviceTypeConsoleServerPortsView(DeviceTypeComponentsView):
child_model = ConsoleServerPortTemplate
table = tables.ConsoleServerPortTemplateTable
filterset = filtersets.ConsoleServerPortTemplateFilterSet
2021-12-21 10:28:28 -05:00
viewname = 'dcim:devicetype_consoleserverports'
tab = ViewTab(
label=_('Console Server Ports'),
badge=lambda obj: obj.consoleserverporttemplates.count(),
permission='dcim.view_consoleserverporttemplate',
weight=560,
hide_if_empty=True
)
@register_model_view(DeviceType, 'powerports', path='power-ports')
class DeviceTypePowerPortsView(DeviceTypeComponentsView):
child_model = PowerPortTemplate
table = tables.PowerPortTemplateTable
filterset = filtersets.PowerPortTemplateFilterSet
2021-12-21 10:28:28 -05:00
viewname = 'dcim:devicetype_powerports'
tab = ViewTab(
label=_('Power Ports'),
badge=lambda obj: obj.powerporttemplates.count(),
permission='dcim.view_powerporttemplate',
weight=570,
hide_if_empty=True
)
@register_model_view(DeviceType, 'poweroutlets', path='power-outlets')
class DeviceTypePowerOutletsView(DeviceTypeComponentsView):
child_model = PowerOutletTemplate
table = tables.PowerOutletTemplateTable
filterset = filtersets.PowerOutletTemplateFilterSet
2021-12-21 10:28:28 -05:00
viewname = 'dcim:devicetype_poweroutlets'
tab = ViewTab(
label=_('Power Outlets'),
badge=lambda obj: obj.poweroutlettemplates.count(),
permission='dcim.view_poweroutlettemplate',
weight=580,
hide_if_empty=True
)
@register_model_view(DeviceType, 'interfaces')
class DeviceTypeInterfacesView(DeviceTypeComponentsView):
child_model = InterfaceTemplate
table = tables.InterfaceTemplateTable
filterset = filtersets.InterfaceTemplateFilterSet
2021-12-21 10:28:28 -05:00
viewname = 'dcim:devicetype_interfaces'
tab = ViewTab(
label=_('Interfaces'),
badge=lambda obj: obj.interfacetemplates.count(),
permission='dcim.view_interfacetemplate',
weight=520,
hide_if_empty=True
)
@register_model_view(DeviceType, 'frontports', path='front-ports')
class DeviceTypeFrontPortsView(DeviceTypeComponentsView):
child_model = FrontPortTemplate
table = tables.FrontPortTemplateTable
filterset = filtersets.FrontPortTemplateFilterSet
2021-12-21 10:28:28 -05:00
viewname = 'dcim:devicetype_frontports'
tab = ViewTab(
label=_('Front Ports'),
badge=lambda obj: obj.frontporttemplates.count(),
permission='dcim.view_frontporttemplate',
weight=530,
hide_if_empty=True
)
@register_model_view(DeviceType, 'rearports', path='rear-ports')
class DeviceTypeRearPortsView(DeviceTypeComponentsView):
child_model = RearPortTemplate
table = tables.RearPortTemplateTable
filterset = filtersets.RearPortTemplateFilterSet
2021-12-21 10:28:28 -05:00
viewname = 'dcim:devicetype_rearports'
tab = ViewTab(
label=_('Rear Ports'),
badge=lambda obj: obj.rearporttemplates.count(),
permission='dcim.view_rearporttemplate',
weight=540,
hide_if_empty=True
)
@register_model_view(DeviceType, 'modulebays', path='module-bays')
class DeviceTypeModuleBaysView(DeviceTypeComponentsView):
child_model = ModuleBayTemplate
table = tables.ModuleBayTemplateTable
filterset = filtersets.ModuleBayTemplateFilterSet
viewname = 'dcim:devicetype_modulebays'
tab = ViewTab(
label=_('Module Bays'),
badge=lambda obj: obj.modulebaytemplates.count(),
permission='dcim.view_modulebaytemplate',
weight=510,
hide_if_empty=True
)
@register_model_view(DeviceType, 'devicebays', path='device-bays')
class DeviceTypeDeviceBaysView(DeviceTypeComponentsView):
child_model = DeviceBayTemplate
table = tables.DeviceBayTemplateTable
filterset = filtersets.DeviceBayTemplateFilterSet
2021-12-21 10:28:28 -05:00
viewname = 'dcim:devicetype_devicebays'
tab = ViewTab(
label=_('Device Bays'),
badge=lambda obj: obj.devicebaytemplates.count(),
permission='dcim.view_devicebaytemplate',
weight=500,
hide_if_empty=True
)
@register_model_view(DeviceType, 'inventoryitems', path='inventory-items')
2021-12-29 15:02:25 -05:00
class DeviceTypeInventoryItemsView(DeviceTypeComponentsView):
child_model = InventoryItemTemplate
table = tables.InventoryItemTemplateTable
filterset = filtersets.InventoryItemTemplateFilterSet
viewname = 'dcim:devicetype_inventoryitems'
tab = ViewTab(
label=_('Inventory Items'),
badge=lambda obj: obj.inventoryitemtemplates.count(),
permission='dcim.view_invenotryitemtemplate',
weight=590,
hide_if_empty=True
)
2021-12-29 15:02:25 -05:00
class DeviceTypeImportView(generic.BulkImportView):
additional_permissions = [
2019-10-01 16:54:10 -04:00
'dcim.add_devicetype',
'dcim.add_consoleporttemplate',
'dcim.add_consoleserverporttemplate',
'dcim.add_powerporttemplate',
'dcim.add_poweroutlettemplate',
'dcim.add_interfacetemplate',
'dcim.add_frontporttemplate',
'dcim.add_rearporttemplate',
'dcim.add_modulebaytemplate',
2019-10-01 16:54:10 -04:00
'dcim.add_devicebaytemplate',
2021-12-29 15:02:25 -05:00
'dcim.add_inventoryitemtemplate',
2019-10-01 16:54:10 -04:00
]
queryset = DeviceType.objects.all()
model_form = forms.DeviceTypeImportForm
related_object_forms = {
'console-ports': forms.ConsolePortTemplateImportForm,
'console-server-ports': forms.ConsoleServerPortTemplateImportForm,
'power-ports': forms.PowerPortTemplateImportForm,
'power-outlets': forms.PowerOutletTemplateImportForm,
'interfaces': forms.InterfaceTemplateImportForm,
'rear-ports': forms.RearPortTemplateImportForm,
'front-ports': forms.FrontPortTemplateImportForm,
'module-bays': forms.ModuleBayTemplateImportForm,
'device-bays': forms.DeviceBayTemplateImportForm,
'inventory-items': forms.InventoryItemTemplateImportForm,
}
2021-12-17 13:28:17 -05:00
def prep_related_object_data(self, parent, data):
data.update({'device_type': parent})
return data
2020-11-11 16:07:38 -05:00
class DeviceTypeBulkEditView(generic.BulkEditView):
queryset = DeviceType.objects.annotate(
instance_count=count_related(Device, 'device_type')
)
2021-04-29 16:38:56 -04:00
filterset = filtersets.DeviceTypeFilterSet
table = tables.DeviceTypeTable
2016-05-18 16:02:53 -04:00
form = forms.DeviceTypeBulkEditForm
2020-11-11 16:07:38 -05:00
class DeviceTypeBulkDeleteView(generic.BulkDeleteView):
queryset = DeviceType.objects.annotate(
instance_count=count_related(Device, 'device_type')
)
2021-04-29 16:38:56 -04:00
filterset = filtersets.DeviceTypeFilterSet
table = tables.DeviceTypeTable
2021-12-17 12:18:37 -05:00
#
# Module types
#
class ModuleTypeListView(generic.ObjectListView):
queryset = ModuleType.objects.annotate(
instance_count=count_related(Module, 'module_type')
2021-12-17 12:18:37 -05:00
)
filterset = filtersets.ModuleTypeFilterSet
filterset_form = forms.ModuleTypeFilterForm
table = tables.ModuleTypeTable
@register_model_view(ModuleType)
2021-12-17 12:18:37 -05:00
class ModuleTypeView(generic.ObjectView):
queryset = ModuleType.objects.all()
2021-12-17 12:18:37 -05:00
def get_extra_context(self, request, instance):
related_models = (
(Module.objects.restrict(request.user).filter(module_type=instance), 'module_type_id'),
)
2021-12-17 12:18:37 -05:00
return {
'related_models': related_models,
2021-12-17 12:18:37 -05:00
}
@register_model_view(ModuleType, 'edit')
class ModuleTypeEditView(generic.ObjectEditView):
queryset = ModuleType.objects.all()
form = forms.ModuleTypeForm
@register_model_view(ModuleType, 'delete')
class ModuleTypeDeleteView(generic.ObjectDeleteView):
queryset = ModuleType.objects.all()
@register_model_view(ModuleType, 'consoleports', path='console-ports')
2021-12-17 12:18:37 -05:00
class ModuleTypeConsolePortsView(ModuleTypeComponentsView):
child_model = ConsolePortTemplate
table = tables.ConsolePortTemplateTable
filterset = filtersets.ConsolePortTemplateFilterSet
viewname = 'dcim:moduletype_consoleports'
tab = ViewTab(
label=_('Console Ports'),
badge=lambda obj: obj.consoleporttemplates.count(),
permission='dcim.view_consoleporttemplate',
weight=530,
hide_if_empty=True
)
2021-12-17 12:18:37 -05:00
@register_model_view(ModuleType, 'consoleserverports', path='console-server-ports')
2021-12-17 12:18:37 -05:00
class ModuleTypeConsoleServerPortsView(ModuleTypeComponentsView):
child_model = ConsoleServerPortTemplate
table = tables.ConsoleServerPortTemplateTable
filterset = filtersets.ConsoleServerPortTemplateFilterSet
viewname = 'dcim:moduletype_consoleserverports'
tab = ViewTab(
label=_('Console Server Ports'),
badge=lambda obj: obj.consoleserverporttemplates.count(),
permission='dcim.view_consoleserverporttemplate',
weight=540,
hide_if_empty=True
)
2021-12-17 12:18:37 -05:00
@register_model_view(ModuleType, 'powerports', path='power-ports')
2021-12-17 12:18:37 -05:00
class ModuleTypePowerPortsView(ModuleTypeComponentsView):
child_model = PowerPortTemplate
table = tables.PowerPortTemplateTable
filterset = filtersets.PowerPortTemplateFilterSet
viewname = 'dcim:moduletype_powerports'
tab = ViewTab(
label=_('Power Ports'),
badge=lambda obj: obj.powerporttemplates.count(),
permission='dcim.view_powerporttemplate',
weight=550,
hide_if_empty=True
)
2021-12-17 12:18:37 -05:00
@register_model_view(ModuleType, 'poweroutlets', path='power-outlets')
2021-12-17 12:18:37 -05:00
class ModuleTypePowerOutletsView(ModuleTypeComponentsView):
child_model = PowerOutletTemplate
table = tables.PowerOutletTemplateTable
filterset = filtersets.PowerOutletTemplateFilterSet
viewname = 'dcim:moduletype_poweroutlets'
tab = ViewTab(
label=_('Power Outlets'),
badge=lambda obj: obj.poweroutlettemplates.count(),
permission='dcim.view_poweroutlettemplate',
weight=560,
hide_if_empty=True
)
2021-12-17 12:18:37 -05:00
@register_model_view(ModuleType, 'interfaces')
2021-12-17 12:18:37 -05:00
class ModuleTypeInterfacesView(ModuleTypeComponentsView):
child_model = InterfaceTemplate
table = tables.InterfaceTemplateTable
filterset = filtersets.InterfaceTemplateFilterSet
viewname = 'dcim:moduletype_interfaces'
tab = ViewTab(
label=_('Interfaces'),
badge=lambda obj: obj.interfacetemplates.count(),
permission='dcim.view_interfacetemplate',
weight=500,
hide_if_empty=True
)
2021-12-17 12:18:37 -05:00
@register_model_view(ModuleType, 'frontports', path='front-ports')
2021-12-17 12:18:37 -05:00
class ModuleTypeFrontPortsView(ModuleTypeComponentsView):
child_model = FrontPortTemplate
table = tables.FrontPortTemplateTable
filterset = filtersets.FrontPortTemplateFilterSet
viewname = 'dcim:moduletype_frontports'
tab = ViewTab(
label=_('Front Ports'),
badge=lambda obj: obj.frontporttemplates.count(),
permission='dcim.view_frontporttemplate',
weight=510,
hide_if_empty=True
)
2021-12-17 12:18:37 -05:00
@register_model_view(ModuleType, 'rearports', path='rear-ports')
2021-12-17 12:18:37 -05:00
class ModuleTypeRearPortsView(ModuleTypeComponentsView):
child_model = RearPortTemplate
table = tables.RearPortTemplateTable
filterset = filtersets.RearPortTemplateFilterSet
viewname = 'dcim:moduletype_rearports'
tab = ViewTab(
label=_('Rear Ports'),
badge=lambda obj: obj.rearporttemplates.count(),
permission='dcim.view_rearporttemplate',
weight=520,
hide_if_empty=True
)
2021-12-17 12:18:37 -05:00
class ModuleTypeImportView(generic.BulkImportView):
2021-12-17 12:18:37 -05:00
additional_permissions = [
'dcim.add_moduletype',
'dcim.add_consoleporttemplate',
'dcim.add_consoleserverporttemplate',
'dcim.add_powerporttemplate',
'dcim.add_poweroutlettemplate',
'dcim.add_interfacetemplate',
'dcim.add_frontporttemplate',
'dcim.add_rearporttemplate',
]
queryset = ModuleType.objects.all()
model_form = forms.ModuleTypeImportForm
related_object_forms = {
'console-ports': forms.ConsolePortTemplateImportForm,
'console-server-ports': forms.ConsoleServerPortTemplateImportForm,
'power-ports': forms.PowerPortTemplateImportForm,
'power-outlets': forms.PowerOutletTemplateImportForm,
'interfaces': forms.InterfaceTemplateImportForm,
'rear-ports': forms.RearPortTemplateImportForm,
'front-ports': forms.FrontPortTemplateImportForm,
}
2021-12-17 12:18:37 -05:00
2021-12-17 13:28:17 -05:00
def prep_related_object_data(self, parent, data):
data.update({'module_type': parent})
return data
2021-12-17 12:18:37 -05:00
class ModuleTypeBulkEditView(generic.BulkEditView):
queryset = ModuleType.objects.annotate(
instance_count=count_related(Module, 'module_type')
2021-12-17 12:18:37 -05:00
)
filterset = filtersets.ModuleTypeFilterSet
table = tables.ModuleTypeTable
form = forms.ModuleTypeBulkEditForm
class ModuleTypeBulkDeleteView(generic.BulkDeleteView):
queryset = ModuleType.objects.annotate(
instance_count=count_related(Module, 'module_type')
2021-12-17 12:18:37 -05:00
)
filterset = filtersets.ModuleTypeFilterSet
table = tables.ModuleTypeTable
#
# Console port templates
#
2020-11-11 16:07:38 -05:00
class ConsolePortTemplateCreateView(generic.ComponentCreateView):
queryset = ConsolePortTemplate.objects.all()
form = forms.ConsolePortTemplateCreateForm
model_form = forms.ConsolePortTemplateForm
@register_model_view(ConsolePortTemplate, 'edit')
2020-11-11 16:07:38 -05:00
class ConsolePortTemplateEditView(generic.ObjectEditView):
queryset = ConsolePortTemplate.objects.all()
form = forms.ConsolePortTemplateForm
@register_model_view(ConsolePortTemplate, 'delete')
2020-11-11 16:07:38 -05:00
class ConsolePortTemplateDeleteView(generic.ObjectDeleteView):
queryset = ConsolePortTemplate.objects.all()
2020-11-11 16:07:38 -05:00
class ConsolePortTemplateBulkEditView(generic.BulkEditView):
queryset = ConsolePortTemplate.objects.all()
table = tables.ConsolePortTemplateTable
form = forms.ConsolePortTemplateBulkEditForm
2020-11-11 16:07:38 -05:00
class ConsolePortTemplateBulkRenameView(generic.BulkRenameView):
queryset = ConsolePortTemplate.objects.all()
2020-11-11 16:07:38 -05:00
class ConsolePortTemplateBulkDeleteView(generic.BulkDeleteView):
queryset = ConsolePortTemplate.objects.all()
table = tables.ConsolePortTemplateTable
#
# Console server port templates
#
2020-11-11 16:07:38 -05:00
class ConsoleServerPortTemplateCreateView(generic.ComponentCreateView):
queryset = ConsoleServerPortTemplate.objects.all()
form = forms.ConsoleServerPortTemplateCreateForm
model_form = forms.ConsoleServerPortTemplateForm
@register_model_view(ConsoleServerPortTemplate, 'edit')
2020-11-11 16:07:38 -05:00
class ConsoleServerPortTemplateEditView(generic.ObjectEditView):
queryset = ConsoleServerPortTemplate.objects.all()
form = forms.ConsoleServerPortTemplateForm
@register_model_view(ConsoleServerPortTemplate, 'delete')
2020-11-11 16:07:38 -05:00
class ConsoleServerPortTemplateDeleteView(generic.ObjectDeleteView):
queryset = ConsoleServerPortTemplate.objects.all()
2020-11-11 16:07:38 -05:00
class ConsoleServerPortTemplateBulkEditView(generic.BulkEditView):
queryset = ConsoleServerPortTemplate.objects.all()
table = tables.ConsoleServerPortTemplateTable
form = forms.ConsoleServerPortTemplateBulkEditForm
2020-11-11 16:07:38 -05:00
class ConsoleServerPortTemplateBulkRenameView(generic.BulkRenameView):
queryset = ConsoleServerPortTemplate.objects.all()
2020-11-11 16:07:38 -05:00
class ConsoleServerPortTemplateBulkDeleteView(generic.BulkDeleteView):
queryset = ConsoleServerPortTemplate.objects.all()
table = tables.ConsoleServerPortTemplateTable
#
# Power port templates
#
2020-11-11 16:07:38 -05:00
class PowerPortTemplateCreateView(generic.ComponentCreateView):
queryset = PowerPortTemplate.objects.all()
form = forms.PowerPortTemplateCreateForm
model_form = forms.PowerPortTemplateForm
@register_model_view(PowerPortTemplate, 'edit')
2020-11-11 16:07:38 -05:00
class PowerPortTemplateEditView(generic.ObjectEditView):
queryset = PowerPortTemplate.objects.all()
form = forms.PowerPortTemplateForm
@register_model_view(PowerPortTemplate, 'delete')
2020-11-11 16:07:38 -05:00
class PowerPortTemplateDeleteView(generic.ObjectDeleteView):
queryset = PowerPortTemplate.objects.all()
2020-11-11 16:07:38 -05:00
class PowerPortTemplateBulkEditView(generic.BulkEditView):
queryset = PowerPortTemplate.objects.all()
table = tables.PowerPortTemplateTable
form = forms.PowerPortTemplateBulkEditForm
2020-11-11 16:07:38 -05:00
class PowerPortTemplateBulkRenameView(generic.BulkRenameView):
queryset = PowerPortTemplate.objects.all()
2020-11-11 16:07:38 -05:00
class PowerPortTemplateBulkDeleteView(generic.BulkDeleteView):
queryset = PowerPortTemplate.objects.all()
table = tables.PowerPortTemplateTable
#
# Power outlet templates
#
2020-11-11 16:07:38 -05:00
class PowerOutletTemplateCreateView(generic.ComponentCreateView):
queryset = PowerOutletTemplate.objects.all()
form = forms.PowerOutletTemplateCreateForm
model_form = forms.PowerOutletTemplateForm
@register_model_view(PowerOutletTemplate, 'edit')
2020-11-11 16:07:38 -05:00
class PowerOutletTemplateEditView(generic.ObjectEditView):
queryset = PowerOutletTemplate.objects.all()
form = forms.PowerOutletTemplateForm
@register_model_view(PowerOutletTemplate, 'delete')
2020-11-11 16:07:38 -05:00
class PowerOutletTemplateDeleteView(generic.ObjectDeleteView):
queryset = PowerOutletTemplate.objects.all()
2020-11-11 16:07:38 -05:00
class PowerOutletTemplateBulkEditView(generic.BulkEditView):
queryset = PowerOutletTemplate.objects.all()
table = tables.PowerOutletTemplateTable
form = forms.PowerOutletTemplateBulkEditForm
2020-11-11 16:07:38 -05:00
class PowerOutletTemplateBulkRenameView(generic.BulkRenameView):
queryset = PowerOutletTemplate.objects.all()
2020-11-11 16:07:38 -05:00
class PowerOutletTemplateBulkDeleteView(generic.BulkDeleteView):
queryset = PowerOutletTemplate.objects.all()
table = tables.PowerOutletTemplateTable
#
# Interface templates
#
2020-11-11 16:07:38 -05:00
class InterfaceTemplateCreateView(generic.ComponentCreateView):
queryset = InterfaceTemplate.objects.all()
form = forms.InterfaceTemplateCreateForm
model_form = forms.InterfaceTemplateForm
@register_model_view(InterfaceTemplate, 'edit')
2020-11-11 16:07:38 -05:00
class InterfaceTemplateEditView(generic.ObjectEditView):
queryset = InterfaceTemplate.objects.all()
form = forms.InterfaceTemplateForm
@register_model_view(InterfaceTemplate, 'delete')
2020-11-11 16:07:38 -05:00
class InterfaceTemplateDeleteView(generic.ObjectDeleteView):
queryset = InterfaceTemplate.objects.all()
2020-11-11 16:07:38 -05:00
class InterfaceTemplateBulkEditView(generic.BulkEditView):
queryset = InterfaceTemplate.objects.all()
table = tables.InterfaceTemplateTable
form = forms.InterfaceTemplateBulkEditForm
2020-11-11 16:07:38 -05:00
class InterfaceTemplateBulkRenameView(generic.BulkRenameView):
queryset = InterfaceTemplate.objects.all()
2020-11-11 16:07:38 -05:00
class InterfaceTemplateBulkDeleteView(generic.BulkDeleteView):
queryset = InterfaceTemplate.objects.all()
table = tables.InterfaceTemplateTable
#
# Front port templates
#
2020-11-11 16:07:38 -05:00
class FrontPortTemplateCreateView(generic.ComponentCreateView):
queryset = FrontPortTemplate.objects.all()
2021-12-28 09:53:56 -05:00
form = forms.FrontPortTemplateCreateForm
model_form = forms.FrontPortTemplateForm
2021-12-28 09:53:56 -05:00
2018-10-03 14:04:16 -04:00
@register_model_view(FrontPortTemplate, 'edit')
2020-11-11 16:07:38 -05:00
class FrontPortTemplateEditView(generic.ObjectEditView):
queryset = FrontPortTemplate.objects.all()
form = forms.FrontPortTemplateForm
@register_model_view(FrontPortTemplate, 'delete')
2020-11-11 16:07:38 -05:00
class FrontPortTemplateDeleteView(generic.ObjectDeleteView):
queryset = FrontPortTemplate.objects.all()
2020-11-11 16:07:38 -05:00
class FrontPortTemplateBulkEditView(generic.BulkEditView):
queryset = FrontPortTemplate.objects.all()
table = tables.FrontPortTemplateTable
form = forms.FrontPortTemplateBulkEditForm
2020-11-11 16:07:38 -05:00
class FrontPortTemplateBulkRenameView(generic.BulkRenameView):
queryset = FrontPortTemplate.objects.all()
2020-11-11 16:07:38 -05:00
class FrontPortTemplateBulkDeleteView(generic.BulkDeleteView):
queryset = FrontPortTemplate.objects.all()
table = tables.FrontPortTemplateTable
2018-10-03 14:04:16 -04:00
#
# Rear port templates
#
2020-11-11 16:07:38 -05:00
class RearPortTemplateCreateView(generic.ComponentCreateView):
queryset = RearPortTemplate.objects.all()
form = forms.RearPortTemplateCreateForm
model_form = forms.RearPortTemplateForm
2018-10-03 14:04:16 -04:00
@register_model_view(RearPortTemplate, 'edit')
2020-11-11 16:07:38 -05:00
class RearPortTemplateEditView(generic.ObjectEditView):
queryset = RearPortTemplate.objects.all()
form = forms.RearPortTemplateForm
@register_model_view(RearPortTemplate, 'delete')
2020-11-11 16:07:38 -05:00
class RearPortTemplateDeleteView(generic.ObjectDeleteView):
queryset = RearPortTemplate.objects.all()
2020-11-11 16:07:38 -05:00
class RearPortTemplateBulkEditView(generic.BulkEditView):
queryset = RearPortTemplate.objects.all()
table = tables.RearPortTemplateTable
form = forms.RearPortTemplateBulkEditForm
2020-11-11 16:07:38 -05:00
class RearPortTemplateBulkRenameView(generic.BulkRenameView):
queryset = RearPortTemplate.objects.all()
2020-11-11 16:07:38 -05:00
class RearPortTemplateBulkDeleteView(generic.BulkDeleteView):
queryset = RearPortTemplate.objects.all()
table = tables.RearPortTemplateTable
2018-10-03 14:04:16 -04:00
#
# Module bay templates
#
class ModuleBayTemplateCreateView(generic.ComponentCreateView):
queryset = ModuleBayTemplate.objects.all()
form = forms.ModuleBayTemplateCreateForm
model_form = forms.ModuleBayTemplateForm
@register_model_view(ModuleBayTemplate, 'edit')
class ModuleBayTemplateEditView(generic.ObjectEditView):
queryset = ModuleBayTemplate.objects.all()
form = forms.ModuleBayTemplateForm
@register_model_view(ModuleBayTemplate, 'delete')
class ModuleBayTemplateDeleteView(generic.ObjectDeleteView):
queryset = ModuleBayTemplate.objects.all()
class ModuleBayTemplateBulkEditView(generic.BulkEditView):
queryset = ModuleBayTemplate.objects.all()
table = tables.ModuleBayTemplateTable
form = forms.ModuleBayTemplateBulkEditForm
class ModuleBayTemplateBulkRenameView(generic.BulkRenameView):
queryset = ModuleBayTemplate.objects.all()
class ModuleBayTemplateBulkDeleteView(generic.BulkDeleteView):
queryset = ModuleBayTemplate.objects.all()
table = tables.ModuleBayTemplateTable
#
# Device bay templates
#
2020-11-11 16:07:38 -05:00
class DeviceBayTemplateCreateView(generic.ComponentCreateView):
queryset = DeviceBayTemplate.objects.all()
form = forms.DeviceBayTemplateCreateForm
model_form = forms.DeviceBayTemplateForm
@register_model_view(DeviceBayTemplate, 'edit')
2020-11-11 16:07:38 -05:00
class DeviceBayTemplateEditView(generic.ObjectEditView):
queryset = DeviceBayTemplate.objects.all()
form = forms.DeviceBayTemplateForm
@register_model_view(DeviceBayTemplate, 'delete')
2020-11-11 16:07:38 -05:00
class DeviceBayTemplateDeleteView(generic.ObjectDeleteView):
queryset = DeviceBayTemplate.objects.all()
2020-11-11 16:07:38 -05:00
class DeviceBayTemplateBulkEditView(generic.BulkEditView):
queryset = DeviceBayTemplate.objects.all()
table = tables.DeviceBayTemplateTable
form = forms.DeviceBayTemplateBulkEditForm
2020-11-11 16:07:38 -05:00
class DeviceBayTemplateBulkRenameView(generic.BulkRenameView):
queryset = DeviceBayTemplate.objects.all()
2020-11-11 16:07:38 -05:00
class DeviceBayTemplateBulkDeleteView(generic.BulkDeleteView):
queryset = DeviceBayTemplate.objects.all()
table = tables.DeviceBayTemplateTable
2021-12-29 15:02:25 -05:00
#
# Inventory item templates
#
class InventoryItemTemplateCreateView(generic.ComponentCreateView):
queryset = InventoryItemTemplate.objects.all()
form = forms.InventoryItemTemplateCreateForm
2021-12-29 15:02:25 -05:00
model_form = forms.InventoryItemTemplateForm
def alter_object(self, instance, request):
# Set component (if any)
component_type = request.GET.get('component_type')
component_id = request.GET.get('component_id')
if component_type and component_id:
content_type = get_object_or_404(ContentType, pk=component_type)
instance.component = get_object_or_404(content_type.model_class(), pk=component_id)
return instance
@register_model_view(InventoryItemTemplate, 'edit')
2021-12-29 15:02:25 -05:00
class InventoryItemTemplateEditView(generic.ObjectEditView):
queryset = InventoryItemTemplate.objects.all()
form = forms.InventoryItemTemplateForm
2021-12-29 15:02:25 -05:00
@register_model_view(InventoryItemTemplate, 'delete')
2021-12-29 15:02:25 -05:00
class InventoryItemTemplateDeleteView(generic.ObjectDeleteView):
queryset = InventoryItemTemplate.objects.all()
class InventoryItemTemplateBulkEditView(generic.BulkEditView):
queryset = InventoryItemTemplate.objects.all()
table = tables.InventoryItemTemplateTable
form = forms.InventoryItemTemplateBulkEditForm
class InventoryItemTemplateBulkRenameView(generic.BulkRenameView):
queryset = InventoryItemTemplate.objects.all()
class InventoryItemTemplateBulkDeleteView(generic.BulkDeleteView):
queryset = InventoryItemTemplate.objects.all()
table = tables.InventoryItemTemplateTable
2016-05-12 14:38:34 -04:00
#
# Device roles
#
2020-11-11 16:07:38 -05:00
class DeviceRoleListView(generic.ObjectListView):
queryset = DeviceRole.objects.annotate(
device_count=count_related(Device, 'device_role'),
vm_count=count_related(VirtualMachine, 'role')
)
filterset = filtersets.DeviceRoleFilterSet
filterset_form = forms.DeviceRoleFilterForm
2016-05-18 16:02:53 -04:00
table = tables.DeviceRoleTable
2016-05-12 14:38:34 -04:00
@register_model_view(DeviceRole)
class DeviceRoleView(generic.ObjectView):
queryset = DeviceRole.objects.all()
def get_extra_context(self, request, instance):
related_models = (
(Device.objects.restrict(request.user, 'view').filter(device_role=instance), 'role_id'),
(VirtualMachine.objects.restrict(request.user, 'view').filter(role=instance), 'role_id'),
)
return {
'related_models': related_models,
}
@register_model_view(DeviceRole, 'edit')
2020-11-11 16:07:38 -05:00
class DeviceRoleEditView(generic.ObjectEditView):
queryset = DeviceRole.objects.all()
form = forms.DeviceRoleForm
2016-05-12 14:38:34 -04:00
@register_model_view(DeviceRole, 'delete')
2020-11-11 16:07:38 -05:00
class DeviceRoleDeleteView(generic.ObjectDeleteView):
queryset = DeviceRole.objects.all()
2020-11-11 16:07:38 -05:00
class DeviceRoleBulkImportView(generic.BulkImportView):
2020-05-21 11:58:27 -04:00
queryset = DeviceRole.objects.all()
model_form = forms.DeviceRoleImportForm
class DeviceRoleBulkEditView(generic.BulkEditView):
queryset = DeviceRole.objects.annotate(
device_count=count_related(Device, 'device_role'),
vm_count=count_related(VirtualMachine, 'role')
)
2021-04-29 16:38:56 -04:00
filterset = filtersets.DeviceRoleFilterSet
table = tables.DeviceRoleTable
form = forms.DeviceRoleBulkEditForm
2020-11-11 16:07:38 -05:00
class DeviceRoleBulkDeleteView(generic.BulkDeleteView):
queryset = DeviceRole.objects.annotate(
device_count=count_related(Device, 'device_role'),
vm_count=count_related(VirtualMachine, 'role')
)
table = tables.DeviceRoleTable
2016-05-12 14:38:34 -04:00
2016-05-16 11:54:17 -04:00
#
# Platforms
#
2020-11-11 16:07:38 -05:00
class PlatformListView(generic.ObjectListView):
queryset = Platform.objects.annotate(
device_count=count_related(Device, 'platform'),
vm_count=count_related(VirtualMachine, 'platform')
)
2016-05-18 16:02:53 -04:00
table = tables.PlatformTable
filterset = filtersets.PlatformFilterSet
filterset_form = forms.PlatformFilterForm
2016-05-16 11:54:17 -04:00
@register_model_view(Platform)
class PlatformView(generic.ObjectView):
queryset = Platform.objects.all()
def get_extra_context(self, request, instance):
related_models = (
(Device.objects.restrict(request.user, 'view').filter(platform=instance), 'platform_id'),
(VirtualMachine.objects.restrict(request.user, 'view').filter(platform=instance), 'platform_id'),
)
return {
'related_models': related_models,
}
@register_model_view(Platform, 'edit')
2020-11-11 16:07:38 -05:00
class PlatformEditView(generic.ObjectEditView):
queryset = Platform.objects.all()
form = forms.PlatformForm
2016-05-16 11:54:17 -04:00
@register_model_view(Platform, 'delete')
2020-11-11 16:07:38 -05:00
class PlatformDeleteView(generic.ObjectDeleteView):
queryset = Platform.objects.all()
2020-11-11 16:07:38 -05:00
class PlatformBulkImportView(generic.BulkImportView):
2020-05-21 11:58:27 -04:00
queryset = Platform.objects.all()
model_form = forms.PlatformImportForm
class PlatformBulkEditView(generic.BulkEditView):
queryset = Platform.objects.all()
2021-04-29 16:38:56 -04:00
filterset = filtersets.PlatformFilterSet
table = tables.PlatformTable
form = forms.PlatformBulkEditForm
2020-11-11 16:07:38 -05:00
class PlatformBulkDeleteView(generic.BulkDeleteView):
queryset = Platform.objects.all()
table = tables.PlatformTable
2016-05-16 11:54:17 -04:00
2016-03-01 11:23:03 -05:00
#
# Devices
#
2020-11-11 16:07:38 -05:00
class DeviceListView(generic.ObjectListView):
queryset = Device.objects.all()
2021-04-29 16:38:56 -04:00
filterset = filtersets.DeviceFilterSet
filterset_form = forms.DeviceFilterForm
2020-04-29 10:58:08 -04:00
table = tables.DeviceTable
template_name = 'dcim/device_list.html'
2016-03-01 11:23:03 -05:00
@register_model_view(Device)
2020-11-11 16:07:38 -05:00
class DeviceView(generic.ObjectView):
queryset = Device.objects.all()
def get_extra_context(self, request, instance):
# VirtualChassis members
if instance.virtual_chassis is not None:
2020-06-01 11:43:49 -04:00
vc_members = Device.objects.restrict(request.user, 'view').filter(
virtual_chassis=instance.virtual_chassis
).order_by('vc_position')
else:
vc_members = []
return {
'vc_members': vc_members,
'svg_extra': f'highlight=id:{instance.pk}'
}
@register_model_view(Device, 'edit')
class DeviceEditView(generic.ObjectEditView):
queryset = Device.objects.all()
form = forms.DeviceForm
template_name = 'dcim/device_edit.html'
@register_model_view(Device, 'delete')
class DeviceDeleteView(generic.ObjectDeleteView):
queryset = Device.objects.all()
@register_model_view(Device, 'consoleports', path='console-ports')
2021-10-20 14:22:11 -04:00
class DeviceConsolePortsView(DeviceComponentsView):
child_model = ConsolePort
2021-10-20 14:22:11 -04:00
table = tables.DeviceConsolePortTable
filterset = filtersets.ConsolePortFilterSet
template_name = 'dcim/device/consoleports.html',
tab = ViewTab(
label=_('Console Ports'),
badge=lambda obj: obj.consoleports.count(),
permission='dcim.view_consoleport',
weight=550,
hide_if_empty=True
)
@register_model_view(Device, 'consoleserverports', path='console-server-ports')
2021-10-20 14:22:11 -04:00
class DeviceConsoleServerPortsView(DeviceComponentsView):
child_model = ConsoleServerPort
2021-10-20 14:22:11 -04:00
table = tables.DeviceConsoleServerPortTable
filterset = filtersets.ConsoleServerPortFilterSet
template_name = 'dcim/device/consoleserverports.html'
tab = ViewTab(
label=_('Console Server Ports'),
badge=lambda obj: obj.consoleserverports.count(),
permission='dcim.view_consoleserverport',
weight=560,
hide_if_empty=True
)
@register_model_view(Device, 'powerports', path='power-ports')
2021-10-20 14:22:11 -04:00
class DevicePowerPortsView(DeviceComponentsView):
child_model = PowerPort
2021-10-20 14:22:11 -04:00
table = tables.DevicePowerPortTable
filterset = filtersets.PowerPortFilterSet
template_name = 'dcim/device/powerports.html'
tab = ViewTab(
label=_('Power Ports'),
badge=lambda obj: obj.powerports.count(),
permission='dcim.view_powerport',
weight=570,
hide_if_empty=True
)
@register_model_view(Device, 'poweroutlets', path='power-outlets')
2021-10-20 14:22:11 -04:00
class DevicePowerOutletsView(DeviceComponentsView):
child_model = PowerOutlet
2021-10-20 14:22:11 -04:00
table = tables.DevicePowerOutletTable
filterset = filtersets.PowerOutletFilterSet
template_name = 'dcim/device/poweroutlets.html'
tab = ViewTab(
label=_('Power Outlets'),
badge=lambda obj: obj.poweroutlets.count(),
permission='dcim.view_poweroutlet',
weight=580,
hide_if_empty=True
)
@register_model_view(Device, 'interfaces')
2021-10-20 14:22:11 -04:00
class DeviceInterfacesView(DeviceComponentsView):
child_model = Interface
2021-10-20 14:22:11 -04:00
table = tables.DeviceInterfaceTable
filterset = filtersets.InterfaceFilterSet
template_name = 'dcim/device/interfaces.html'
tab = ViewTab(
label=_('Interfaces'),
badge=lambda obj: obj.vc_interfaces().count(),
permission='dcim.view_interface',
weight=520,
hide_if_empty=True
)
def get_children(self, request, parent):
return parent.vc_interfaces().restrict(request.user, 'view').prefetch_related(
Prefetch('ip_addresses', queryset=IPAddress.objects.restrict(request.user)),
2021-10-20 14:22:11 -04:00
Prefetch('member_interfaces', queryset=Interface.objects.restrict(request.user))
)
@register_model_view(Device, 'frontports', path='front-ports')
2021-10-20 14:22:11 -04:00
class DeviceFrontPortsView(DeviceComponentsView):
child_model = FrontPort
2021-10-20 14:22:11 -04:00
table = tables.DeviceFrontPortTable
filterset = filtersets.FrontPortFilterSet
template_name = 'dcim/device/frontports.html'
tab = ViewTab(
label=_('Front Ports'),
badge=lambda obj: obj.frontports.count(),
permission='dcim.view_frontport',
weight=530,
hide_if_empty=True
)
2018-10-03 14:04:16 -04:00
@register_model_view(Device, 'rearports', path='rear-ports')
2021-10-20 14:22:11 -04:00
class DeviceRearPortsView(DeviceComponentsView):
child_model = RearPort
2021-10-20 14:22:11 -04:00
table = tables.DeviceRearPortTable
filterset = filtersets.RearPortFilterSet
template_name = 'dcim/device/rearports.html'
tab = ViewTab(
label=_('Rear Ports'),
badge=lambda obj: obj.rearports.count(),
permission='dcim.view_rearport',
weight=540,
hide_if_empty=True
)
@register_model_view(Device, 'modulebays', path='module-bays')
class DeviceModuleBaysView(DeviceComponentsView):
child_model = ModuleBay
table = tables.DeviceModuleBayTable
filterset = filtersets.ModuleBayFilterSet
template_name = 'dcim/device/modulebays.html'
tab = ViewTab(
label=_('Module Bays'),
badge=lambda obj: obj.modulebays.count(),
permission='dcim.view_modulebay',
weight=510,
hide_if_empty=True
)
@register_model_view(Device, 'devicebays', path='device-bays')
2021-10-20 14:22:11 -04:00
class DeviceDeviceBaysView(DeviceComponentsView):
child_model = DeviceBay
2021-10-20 14:22:11 -04:00
table = tables.DeviceDeviceBayTable
filterset = filtersets.DeviceBayFilterSet
template_name = 'dcim/device/devicebays.html'
tab = ViewTab(
label=_('Device Bays'),
badge=lambda obj: obj.devicebays.count(),
permission='dcim.view_devicebay',
weight=500,
hide_if_empty=True
)
@register_model_view(Device, 'inventory')
2021-10-20 14:22:11 -04:00
class DeviceInventoryView(DeviceComponentsView):
child_model = InventoryItem
2021-10-20 14:22:11 -04:00
table = tables.DeviceInventoryItemTable
filterset = filtersets.InventoryItemFilterSet
template_name = 'dcim/device/inventory.html'
tab = ViewTab(
label=_('Inventory Items'),
badge=lambda obj: obj.inventoryitems.count(),
permission='dcim.view_inventoryitem',
weight=590,
hide_if_empty=True
)
@register_model_view(Device, 'configcontext', path='config-context')
class DeviceConfigContextView(ObjectConfigContextView):
queryset = Device.objects.annotate_config_context_data()
base_template = 'dcim/device/base.html'
tab = ViewTab(
label=_('Config Context'),
permission='extras.view_configcontext',
weight=2000
)
@register_model_view(Device, 'render-config')
class DeviceRenderConfigView(generic.ObjectView):
queryset = Device.objects.all()
template_name = 'dcim/device/render_config.html'
tab = ViewTab(
label=_('Render Config'),
permission='extras.view_configtemplate',
weight=2100
)
def get_extra_context(self, request, instance):
# Compile context data
context_data = {
'device': instance,
}
context_data.update(**instance.get_config_context())
# Render the config template
rendered_config = None
if config_template := instance.get_config_template():
try:
rendered_config = config_template.render(context=context_data)
except TemplateError as e:
messages.error(request, f"An error occurred while rendering the template: {e}")
rendered_config = traceback.format_exc()
return {
'config_template': config_template,
'context_data': context_data,
'rendered_config': rendered_config,
}
2020-11-11 16:07:38 -05:00
class DeviceBulkImportView(generic.BulkImportView):
2020-05-21 11:58:27 -04:00
queryset = Device.objects.all()
model_form = forms.DeviceImportForm
def save_object(self, object_form, request):
obj = object_form.save()
# For child devices, save the reverse relation to the parent device bay
if getattr(obj, 'parent_bay', None):
device_bay = obj.parent_bay
device_bay.installed_device = obj
device_bay.save()
return obj
2020-11-11 16:07:38 -05:00
class DeviceBulkEditView(generic.BulkEditView):
queryset = Device.objects.prefetch_related('device_type__manufacturer')
2021-04-29 16:38:56 -04:00
filterset = filtersets.DeviceFilterSet
table = tables.DeviceTable
2016-05-18 16:02:53 -04:00
form = forms.DeviceBulkEditForm
2016-03-01 11:23:03 -05:00
2020-11-11 16:07:38 -05:00
class DeviceBulkDeleteView(generic.BulkDeleteView):
queryset = Device.objects.prefetch_related('device_type__manufacturer')
2021-04-29 16:38:56 -04:00
filterset = filtersets.DeviceFilterSet
table = tables.DeviceTable
2016-03-01 11:23:03 -05:00
2022-06-30 01:38:38 -04:00
class DeviceBulkRenameView(generic.BulkRenameView):
2022-08-11 15:16:01 -04:00
queryset = Device.objects.all()
2022-06-30 01:38:38 -04:00
filterset = filtersets.DeviceFilterSet
table = tables.DeviceTable
2022-10-07 14:17:18 -04:00
#
# Modules
2021-12-17 16:12:03 -05:00
#
class ModuleListView(generic.ObjectListView):
queryset = Module.objects.prefetch_related('module_type__manufacturer')
2021-12-17 16:12:03 -05:00
filterset = filtersets.ModuleFilterSet
filterset_form = forms.ModuleFilterForm
table = tables.ModuleTable
@register_model_view(Module)
2021-12-17 16:12:03 -05:00
class ModuleView(generic.ObjectView):
queryset = Module.objects.all()
def get_extra_context(self, request, instance):
related_models = (
(Interface.objects.restrict(request.user, 'view').filter(module=instance), 'module_id'),
(ConsolePort.objects.restrict(request.user, 'view').filter(module=instance), 'module_id'),
(ConsoleServerPort.objects.restrict(request.user, 'view').filter(module=instance), 'module_id'),
(PowerPort.objects.restrict(request.user, 'view').filter(module=instance), 'module_id'),
(PowerOutlet.objects.restrict(request.user, 'view').filter(module=instance), 'module_id'),
(FrontPort.objects.restrict(request.user, 'view').filter(module=instance), 'module_id'),
(RearPort.objects.restrict(request.user, 'view').filter(module=instance), 'module_id'),
)
return {
'related_models': related_models,
}
2021-12-17 16:12:03 -05:00
@register_model_view(Module, 'edit')
2021-12-17 16:12:03 -05:00
class ModuleEditView(generic.ObjectEditView):
queryset = Module.objects.all()
form = forms.ModuleForm
2021-12-17 16:12:03 -05:00
@register_model_view(Module, 'delete')
2021-12-17 16:12:03 -05:00
class ModuleDeleteView(generic.ObjectDeleteView):
queryset = Module.objects.all()
class ModuleBulkImportView(generic.BulkImportView):
queryset = Module.objects.all()
model_form = forms.ModuleImportForm
2021-12-17 16:12:03 -05:00
class ModuleBulkEditView(generic.BulkEditView):
queryset = Module.objects.prefetch_related('module_type__manufacturer')
2021-12-17 16:12:03 -05:00
filterset = filtersets.ModuleFilterSet
table = tables.ModuleTable
form = forms.ModuleBulkEditForm
class ModuleBulkDeleteView(generic.BulkDeleteView):
queryset = Module.objects.prefetch_related('module_type__manufacturer')
2021-12-17 16:12:03 -05:00
filterset = filtersets.ModuleFilterSet
table = tables.ModuleTable
2016-12-21 15:26:56 -05:00
#
# Console ports
#
2020-11-11 16:07:38 -05:00
class ConsolePortListView(generic.ObjectListView):
queryset = ConsolePort.objects.all()
2021-04-29 16:38:56 -04:00
filterset = filtersets.ConsolePortFilterSet
filterset_form = forms.ConsolePortFilterForm
table = tables.ConsolePortTable
actions = ('import', 'export', 'bulk_edit', 'bulk_delete')
@register_model_view(ConsolePort)
2020-11-11 16:07:38 -05:00
class ConsolePortView(generic.ObjectView):
queryset = ConsolePort.objects.all()
2020-11-11 16:07:38 -05:00
class ConsolePortCreateView(generic.ComponentCreateView):
queryset = ConsolePort.objects.all()
form = forms.ConsolePortCreateForm
2016-12-21 15:26:56 -05:00
model_form = forms.ConsolePortForm
2016-03-01 11:23:03 -05:00
@register_model_view(ConsolePort, 'edit')
2020-11-11 16:07:38 -05:00
class ConsolePortEditView(generic.ObjectEditView):
queryset = ConsolePort.objects.all()
form = forms.ConsolePortForm
2016-03-01 11:23:03 -05:00
@register_model_view(ConsolePort, 'delete')
2020-11-11 16:07:38 -05:00
class ConsolePortDeleteView(generic.ObjectDeleteView):
queryset = ConsolePort.objects.all()
2016-03-01 11:23:03 -05:00
2020-11-11 16:07:38 -05:00
class ConsolePortBulkImportView(generic.BulkImportView):
2020-05-21 11:58:27 -04:00
queryset = ConsolePort.objects.all()
model_form = forms.ConsolePortImportForm
2020-11-11 16:07:38 -05:00
class ConsolePortBulkEditView(generic.BulkEditView):
queryset = ConsolePort.objects.all()
2021-04-29 16:38:56 -04:00
filterset = filtersets.ConsolePortFilterSet
table = tables.ConsolePortTable
form = forms.ConsolePortBulkEditForm
2020-11-11 16:07:38 -05:00
class ConsolePortBulkRenameView(generic.BulkRenameView):
queryset = ConsolePort.objects.all()
class ConsolePortBulkDisconnectView(BulkDisconnectView):
queryset = ConsolePort.objects.all()
2020-11-11 16:07:38 -05:00
class ConsolePortBulkDeleteView(generic.BulkDeleteView):
queryset = ConsolePort.objects.all()
2021-04-29 16:38:56 -04:00
filterset = filtersets.ConsolePortFilterSet
table = tables.ConsolePortTable
# Trace view
register_model_view(ConsolePort, 'trace', kwargs={'model': ConsolePort})(PathTraceView)
2016-03-01 11:23:03 -05:00
#
# Console server ports
#
2020-11-11 16:07:38 -05:00
class ConsoleServerPortListView(generic.ObjectListView):
queryset = ConsoleServerPort.objects.all()
2021-04-29 16:38:56 -04:00
filterset = filtersets.ConsoleServerPortFilterSet
filterset_form = forms.ConsoleServerPortFilterForm
table = tables.ConsoleServerPortTable
actions = ('import', 'export', 'bulk_edit', 'bulk_delete')
@register_model_view(ConsoleServerPort)
2020-11-11 16:07:38 -05:00
class ConsoleServerPortView(generic.ObjectView):
queryset = ConsoleServerPort.objects.all()
2020-11-11 16:07:38 -05:00
class ConsoleServerPortCreateView(generic.ComponentCreateView):
queryset = ConsoleServerPort.objects.all()
form = forms.ConsoleServerPortCreateForm
2016-12-21 15:26:56 -05:00
model_form = forms.ConsoleServerPortForm
2016-03-01 11:23:03 -05:00
@register_model_view(ConsoleServerPort, 'edit')
2020-11-11 16:07:38 -05:00
class ConsoleServerPortEditView(generic.ObjectEditView):
queryset = ConsoleServerPort.objects.all()
form = forms.ConsoleServerPortForm
2016-03-01 11:23:03 -05:00
@register_model_view(ConsoleServerPort, 'delete')
2020-11-11 16:07:38 -05:00
class ConsoleServerPortDeleteView(generic.ObjectDeleteView):
queryset = ConsoleServerPort.objects.all()
2016-03-01 11:23:03 -05:00
2020-11-11 16:07:38 -05:00
class ConsoleServerPortBulkImportView(generic.BulkImportView):
2020-05-21 11:58:27 -04:00
queryset = ConsoleServerPort.objects.all()
model_form = forms.ConsoleServerPortImportForm
2020-11-11 16:07:38 -05:00
class ConsoleServerPortBulkEditView(generic.BulkEditView):
queryset = ConsoleServerPort.objects.all()
2021-04-29 16:38:56 -04:00
filterset = filtersets.ConsoleServerPortFilterSet
table = tables.ConsoleServerPortTable
form = forms.ConsoleServerPortBulkEditForm
2020-11-11 16:07:38 -05:00
class ConsoleServerPortBulkRenameView(generic.BulkRenameView):
queryset = ConsoleServerPort.objects.all()
class ConsoleServerPortBulkDisconnectView(BulkDisconnectView):
queryset = ConsoleServerPort.objects.all()
2020-11-11 16:07:38 -05:00
class ConsoleServerPortBulkDeleteView(generic.BulkDeleteView):
queryset = ConsoleServerPort.objects.all()
2021-04-29 16:38:56 -04:00
filterset = filtersets.ConsoleServerPortFilterSet
table = tables.ConsoleServerPortTable
# Trace view
register_model_view(ConsoleServerPort, 'trace', kwargs={'model': ConsoleServerPort})(PathTraceView)
2016-03-01 11:23:03 -05:00
#
# Power ports
#
2020-11-11 16:07:38 -05:00
class PowerPortListView(generic.ObjectListView):
queryset = PowerPort.objects.all()
2021-04-29 16:38:56 -04:00
filterset = filtersets.PowerPortFilterSet
filterset_form = forms.PowerPortFilterForm
table = tables.PowerPortTable
actions = ('import', 'export', 'bulk_edit', 'bulk_delete')
@register_model_view(PowerPort)
2020-11-11 16:07:38 -05:00
class PowerPortView(generic.ObjectView):
queryset = PowerPort.objects.all()
2020-11-11 16:07:38 -05:00
class PowerPortCreateView(generic.ComponentCreateView):
queryset = PowerPort.objects.all()
form = forms.PowerPortCreateForm
2016-12-21 15:26:56 -05:00
model_form = forms.PowerPortForm
2016-03-01 11:23:03 -05:00
@register_model_view(PowerPort, 'edit')
2020-11-11 16:07:38 -05:00
class PowerPortEditView(generic.ObjectEditView):
queryset = PowerPort.objects.all()
form = forms.PowerPortForm
2016-03-01 11:23:03 -05:00
@register_model_view(PowerPort, 'delete')
2020-11-11 16:07:38 -05:00
class PowerPortDeleteView(generic.ObjectDeleteView):
queryset = PowerPort.objects.all()
2016-03-01 11:23:03 -05:00
2020-11-11 16:07:38 -05:00
class PowerPortBulkImportView(generic.BulkImportView):
2020-05-21 11:58:27 -04:00
queryset = PowerPort.objects.all()
model_form = forms.PowerPortImportForm
2020-11-11 16:07:38 -05:00
class PowerPortBulkEditView(generic.BulkEditView):
queryset = PowerPort.objects.all()
2021-04-29 16:38:56 -04:00
filterset = filtersets.PowerPortFilterSet
table = tables.PowerPortTable
form = forms.PowerPortBulkEditForm
2020-11-11 16:07:38 -05:00
class PowerPortBulkRenameView(generic.BulkRenameView):
queryset = PowerPort.objects.all()
class PowerPortBulkDisconnectView(BulkDisconnectView):
queryset = PowerPort.objects.all()
2020-11-11 16:07:38 -05:00
class PowerPortBulkDeleteView(generic.BulkDeleteView):
queryset = PowerPort.objects.all()
2021-04-29 16:38:56 -04:00
filterset = filtersets.PowerPortFilterSet
table = tables.PowerPortTable
# Trace view
register_model_view(PowerPort, 'trace', kwargs={'model': PowerPort})(PathTraceView)
2016-03-01 11:23:03 -05:00
#
# Power outlets
#
2020-11-11 16:07:38 -05:00
class PowerOutletListView(generic.ObjectListView):
queryset = PowerOutlet.objects.all()
2021-04-29 16:38:56 -04:00
filterset = filtersets.PowerOutletFilterSet
filterset_form = forms.PowerOutletFilterForm
table = tables.PowerOutletTable
actions = ('import', 'export', 'bulk_edit', 'bulk_delete')
@register_model_view(PowerOutlet)
2020-11-11 16:07:38 -05:00
class PowerOutletView(generic.ObjectView):
queryset = PowerOutlet.objects.all()
2020-11-11 16:07:38 -05:00
class PowerOutletCreateView(generic.ComponentCreateView):
queryset = PowerOutlet.objects.all()
form = forms.PowerOutletCreateForm
2016-12-21 15:26:56 -05:00
model_form = forms.PowerOutletForm
2016-03-01 11:23:03 -05:00
@register_model_view(PowerOutlet, 'edit')
2020-11-11 16:07:38 -05:00
class PowerOutletEditView(generic.ObjectEditView):
queryset = PowerOutlet.objects.all()
form = forms.PowerOutletForm
2016-03-01 11:23:03 -05:00
@register_model_view(PowerOutlet, 'delete')
2020-11-11 16:07:38 -05:00
class PowerOutletDeleteView(generic.ObjectDeleteView):
queryset = PowerOutlet.objects.all()
2016-03-01 11:23:03 -05:00
2020-11-11 16:07:38 -05:00
class PowerOutletBulkImportView(generic.BulkImportView):
2020-05-21 11:58:27 -04:00
queryset = PowerOutlet.objects.all()
model_form = forms.PowerOutletImportForm
2020-11-11 16:07:38 -05:00
class PowerOutletBulkEditView(generic.BulkEditView):
queryset = PowerOutlet.objects.all()
2021-04-29 16:38:56 -04:00
filterset = filtersets.PowerOutletFilterSet
table = tables.PowerOutletTable
form = forms.PowerOutletBulkEditForm
2020-11-11 16:07:38 -05:00
class PowerOutletBulkRenameView(generic.BulkRenameView):
queryset = PowerOutlet.objects.all()
class PowerOutletBulkDisconnectView(BulkDisconnectView):
queryset = PowerOutlet.objects.all()
2020-11-11 16:07:38 -05:00
class PowerOutletBulkDeleteView(generic.BulkDeleteView):
queryset = PowerOutlet.objects.all()
2021-04-29 16:38:56 -04:00
filterset = filtersets.PowerOutletFilterSet
table = tables.PowerOutletTable
# Trace view
register_model_view(PowerOutlet, 'trace', kwargs={'model': PowerOutlet})(PathTraceView)
2016-03-01 11:23:03 -05:00
#
# Interfaces
#
2020-11-11 16:07:38 -05:00
class InterfaceListView(generic.ObjectListView):
queryset = Interface.objects.all()
2021-04-29 16:38:56 -04:00
filterset = filtersets.InterfaceFilterSet
filterset_form = forms.InterfaceFilterForm
table = tables.InterfaceTable
actions = ('import', 'export', 'bulk_edit', 'bulk_delete')
@register_model_view(Interface)
2020-11-11 16:07:38 -05:00
class InterfaceView(generic.ObjectView):
queryset = Interface.objects.all()
2018-07-11 15:30:54 -04:00
def get_extra_context(self, request, instance):
Closes: #7854 - Add VDC/Instances/etc (#10787) * Work on #7854 * Move to new URL scheme. * Fix PEP8 errors * Fix PEP8 errors * Add GraphQL and fix primary_ip missing * Fix PEP8 on GQL Type * Fix missing NestedSerializer. * Fix missing NestedSerializer & rename VDC to VDCs * Fix migration * Change Validation for identifier * Fix missing migration * Rebase to feature * Post-review changes * Remove VDC Type * Remove M2M Enforcement logic * Interface related changes * Add filter fields to filterset for Interface filter * Add form field to filterset form for Interface filter * Add VDC display to interface detail template * Remove VirtualDeviceContextTypeChoices * Accommodate recent changes in feature branch * Add tests Add missing search() * Update tests, and fix model form * Update test_api * Update test_api.InterfaceTest create_data * Fix issue with tests * Update interface serializer * Update serializer and tests * Update status to be required * Remove error message for constraint * Remove extraneous import * Re-ordered devices menu to place VDC below virtual chassis * Add helptext for `identifier` field * Fix breadcrumb link * Remove add interface link * Add missing tenant and status fields * Changes to tests as per Jeremy * Change for #9623 Co-authored-by: Jeremy Stretch <jstretch@ns1.com> * Update filterset form for status field * Remove Rename View * Change tabs to spaces * Update netbox/dcim/tables/devices.py Co-authored-by: Jeremy Stretch <jstretch@ns1.com> * Update netbox/dcim/tables/devices.py Co-authored-by: Jeremy Stretch <jstretch@ns1.com> * Fix tenant in bulk_edit * Apply suggestions from code review Co-authored-by: Jeremy Stretch <jstretch@ns1.com> * Add status field to table. * Re-order table fields. Co-authored-by: Jeremy Stretch <jstretch@ns1.com>
2022-11-11 06:55:49 -06:00
# Get assigned VDC's
vdc_table = tables.VirtualDeviceContextTable(
data=instance.vdcs.restrict(request.user, 'view').prefetch_related('device'),
exclude=('tenant', 'tenant_group', 'primary_ip', 'primary_ip4', 'primary_ip6', 'comments', 'tags',
'created', 'last_updated', 'actions', ),
orderable=False
)
# Get bridge interfaces
bridge_interfaces = Interface.objects.restrict(request.user, 'view').filter(bridge=instance)
bridge_interfaces_tables = tables.InterfaceTable(
bridge_interfaces,
exclude=('device', 'parent'),
orderable=False
)
# Get child interfaces
child_interfaces = Interface.objects.restrict(request.user, 'view').filter(parent=instance)
child_interfaces_tables = tables.InterfaceTable(
child_interfaces,
exclude=('device', 'parent'),
orderable=False
)
2018-07-11 15:30:54 -04:00
# Get assigned VLANs and annotate whether each is tagged or untagged
vlans = []
if instance.untagged_vlan is not None:
vlans.append(instance.untagged_vlan)
2018-07-11 15:30:54 -04:00
vlans[0].tagged = False
for vlan in instance.tagged_vlans.restrict(request.user).prefetch_related('site', 'group', 'tenant', 'role'):
2018-07-11 15:30:54 -04:00
vlan.tagged = True
vlans.append(vlan)
vlan_table = InterfaceVLANTable(
interface=instance,
2018-07-11 15:30:54 -04:00
data=vlans,
orderable=False
)
return {
Closes: #7854 - Add VDC/Instances/etc (#10787) * Work on #7854 * Move to new URL scheme. * Fix PEP8 errors * Fix PEP8 errors * Add GraphQL and fix primary_ip missing * Fix PEP8 on GQL Type * Fix missing NestedSerializer. * Fix missing NestedSerializer & rename VDC to VDCs * Fix migration * Change Validation for identifier * Fix missing migration * Rebase to feature * Post-review changes * Remove VDC Type * Remove M2M Enforcement logic * Interface related changes * Add filter fields to filterset for Interface filter * Add form field to filterset form for Interface filter * Add VDC display to interface detail template * Remove VirtualDeviceContextTypeChoices * Accommodate recent changes in feature branch * Add tests Add missing search() * Update tests, and fix model form * Update test_api * Update test_api.InterfaceTest create_data * Fix issue with tests * Update interface serializer * Update serializer and tests * Update status to be required * Remove error message for constraint * Remove extraneous import * Re-ordered devices menu to place VDC below virtual chassis * Add helptext for `identifier` field * Fix breadcrumb link * Remove add interface link * Add missing tenant and status fields * Changes to tests as per Jeremy * Change for #9623 Co-authored-by: Jeremy Stretch <jstretch@ns1.com> * Update filterset form for status field * Remove Rename View * Change tabs to spaces * Update netbox/dcim/tables/devices.py Co-authored-by: Jeremy Stretch <jstretch@ns1.com> * Update netbox/dcim/tables/devices.py Co-authored-by: Jeremy Stretch <jstretch@ns1.com> * Fix tenant in bulk_edit * Apply suggestions from code review Co-authored-by: Jeremy Stretch <jstretch@ns1.com> * Add status field to table. * Re-order table fields. Co-authored-by: Jeremy Stretch <jstretch@ns1.com>
2022-11-11 06:55:49 -06:00
'vdc_table': vdc_table,
'bridge_interfaces_table': bridge_interfaces_tables,
'child_interfaces_table': child_interfaces_tables,
2018-07-11 15:30:54 -04:00
'vlan_table': vlan_table,
}
2018-07-11 15:30:54 -04:00
2020-11-11 16:07:38 -05:00
class InterfaceCreateView(generic.ComponentCreateView):
queryset = Interface.objects.all()
form = forms.InterfaceCreateForm
2016-12-21 15:26:56 -05:00
model_form = forms.InterfaceForm
2016-03-01 11:23:03 -05:00
@register_model_view(Interface, 'edit')
2020-11-11 16:07:38 -05:00
class InterfaceEditView(generic.ObjectEditView):
queryset = Interface.objects.all()
form = forms.InterfaceForm
2016-03-01 11:23:03 -05:00
@register_model_view(Interface, 'delete')
2020-11-11 16:07:38 -05:00
class InterfaceDeleteView(generic.ObjectDeleteView):
queryset = Interface.objects.all()
2016-03-01 11:23:03 -05:00
2020-11-11 16:07:38 -05:00
class InterfaceBulkImportView(generic.BulkImportView):
2020-05-21 11:58:27 -04:00
queryset = Interface.objects.all()
model_form = forms.InterfaceImportForm
2020-11-11 16:07:38 -05:00
class InterfaceBulkEditView(generic.BulkEditView):
queryset = Interface.objects.all()
2021-04-29 16:38:56 -04:00
filterset = filtersets.InterfaceFilterSet
table = tables.InterfaceTable
2016-10-14 16:38:46 -04:00
form = forms.InterfaceBulkEditForm
2020-11-11 16:07:38 -05:00
class InterfaceBulkRenameView(generic.BulkRenameView):
queryset = Interface.objects.all()
class InterfaceBulkDisconnectView(BulkDisconnectView):
queryset = Interface.objects.all()
2020-11-11 16:07:38 -05:00
class InterfaceBulkDeleteView(generic.BulkDeleteView):
queryset = Interface.objects.all()
2021-04-29 16:38:56 -04:00
filterset = filtersets.InterfaceFilterSet
table = tables.InterfaceTable
# Trace view
register_model_view(Interface, 'trace', kwargs={'model': Interface})(PathTraceView)
2018-10-03 14:04:16 -04:00
#
# Front ports
2018-10-03 14:04:16 -04:00
#
2020-11-11 16:07:38 -05:00
class FrontPortListView(generic.ObjectListView):
queryset = FrontPort.objects.all()
2021-04-29 16:38:56 -04:00
filterset = filtersets.FrontPortFilterSet
filterset_form = forms.FrontPortFilterForm
table = tables.FrontPortTable
actions = ('import', 'export', 'bulk_edit', 'bulk_delete')
@register_model_view(FrontPort)
2020-11-11 16:07:38 -05:00
class FrontPortView(generic.ObjectView):
queryset = FrontPort.objects.all()
2020-11-11 16:07:38 -05:00
class FrontPortCreateView(generic.ComponentCreateView):
queryset = FrontPort.objects.all()
2021-12-28 09:53:56 -05:00
form = forms.FrontPortCreateForm
model_form = forms.FrontPortForm
2018-10-03 14:04:16 -04:00
@register_model_view(FrontPort, 'edit')
2020-11-11 16:07:38 -05:00
class FrontPortEditView(generic.ObjectEditView):
queryset = FrontPort.objects.all()
form = forms.FrontPortForm
2018-10-03 14:04:16 -04:00
@register_model_view(FrontPort, 'delete')
2020-11-11 16:07:38 -05:00
class FrontPortDeleteView(generic.ObjectDeleteView):
queryset = FrontPort.objects.all()
2018-10-03 14:04:16 -04:00
2020-11-11 16:07:38 -05:00
class FrontPortBulkImportView(generic.BulkImportView):
2020-05-21 11:58:27 -04:00
queryset = FrontPort.objects.all()
model_form = forms.FrontPortImportForm
2020-11-11 16:07:38 -05:00
class FrontPortBulkEditView(generic.BulkEditView):
queryset = FrontPort.objects.all()
2021-04-29 16:38:56 -04:00
filterset = filtersets.FrontPortFilterSet
table = tables.FrontPortTable
form = forms.FrontPortBulkEditForm
2020-11-11 16:07:38 -05:00
class FrontPortBulkRenameView(generic.BulkRenameView):
queryset = FrontPort.objects.all()
2018-10-03 14:04:16 -04:00
class FrontPortBulkDisconnectView(BulkDisconnectView):
queryset = FrontPort.objects.all()
2020-11-11 16:07:38 -05:00
class FrontPortBulkDeleteView(generic.BulkDeleteView):
queryset = FrontPort.objects.all()
2021-04-29 16:38:56 -04:00
filterset = filtersets.FrontPortFilterSet
table = tables.FrontPortTable
2018-10-03 14:04:16 -04:00
# Trace view
register_model_view(FrontPort, 'trace', kwargs={'model': FrontPort})(PathTraceView)
2018-10-03 14:04:16 -04:00
#
# Rear ports
2018-10-03 14:04:16 -04:00
#
2020-11-11 16:07:38 -05:00
class RearPortListView(generic.ObjectListView):
queryset = RearPort.objects.all()
2021-04-29 16:38:56 -04:00
filterset = filtersets.RearPortFilterSet
filterset_form = forms.RearPortFilterForm
table = tables.RearPortTable
actions = ('import', 'export', 'bulk_edit', 'bulk_delete')
@register_model_view(RearPort)
2020-11-11 16:07:38 -05:00
class RearPortView(generic.ObjectView):
queryset = RearPort.objects.all()
2020-11-11 16:07:38 -05:00
class RearPortCreateView(generic.ComponentCreateView):
queryset = RearPort.objects.all()
form = forms.RearPortCreateForm
model_form = forms.RearPortForm
2018-10-03 14:04:16 -04:00
@register_model_view(RearPort, 'edit')
2020-11-11 16:07:38 -05:00
class RearPortEditView(generic.ObjectEditView):
queryset = RearPort.objects.all()
form = forms.RearPortForm
2018-10-03 14:04:16 -04:00
@register_model_view(RearPort, 'delete')
2020-11-11 16:07:38 -05:00
class RearPortDeleteView(generic.ObjectDeleteView):
queryset = RearPort.objects.all()
2018-10-03 14:04:16 -04:00
2020-11-11 16:07:38 -05:00
class RearPortBulkImportView(generic.BulkImportView):
2020-05-21 11:58:27 -04:00
queryset = RearPort.objects.all()
model_form = forms.RearPortImportForm
2020-11-11 16:07:38 -05:00
class RearPortBulkEditView(generic.BulkEditView):
queryset = RearPort.objects.all()
2021-04-29 16:38:56 -04:00
filterset = filtersets.RearPortFilterSet
table = tables.RearPortTable
form = forms.RearPortBulkEditForm
2020-11-11 16:07:38 -05:00
class RearPortBulkRenameView(generic.BulkRenameView):
queryset = RearPort.objects.all()
2018-10-03 14:04:16 -04:00
class RearPortBulkDisconnectView(BulkDisconnectView):
queryset = RearPort.objects.all()
2020-11-11 16:07:38 -05:00
class RearPortBulkDeleteView(generic.BulkDeleteView):
queryset = RearPort.objects.all()
2021-04-29 16:38:56 -04:00
filterset = filtersets.RearPortFilterSet
table = tables.RearPortTable
2018-10-03 14:04:16 -04:00
# Trace view
register_model_view(RearPort, 'trace', kwargs={'model': RearPort})(PathTraceView)
#
# Module bays
#
class ModuleBayListView(generic.ObjectListView):
2021-12-17 16:27:03 -05:00
queryset = ModuleBay.objects.select_related('installed_module__module_type')
filterset = filtersets.ModuleBayFilterSet
filterset_form = forms.ModuleBayFilterForm
table = tables.ModuleBayTable
actions = ('import', 'export', 'bulk_edit', 'bulk_delete')
@register_model_view(ModuleBay)
class ModuleBayView(generic.ObjectView):
queryset = ModuleBay.objects.all()
class ModuleBayCreateView(generic.ComponentCreateView):
queryset = ModuleBay.objects.all()
form = forms.ModuleBayCreateForm
model_form = forms.ModuleBayForm
@register_model_view(ModuleBay, 'edit')
class ModuleBayEditView(generic.ObjectEditView):
queryset = ModuleBay.objects.all()
form = forms.ModuleBayForm
@register_model_view(ModuleBay, 'delete')
class ModuleBayDeleteView(generic.ObjectDeleteView):
queryset = ModuleBay.objects.all()
class ModuleBayBulkImportView(generic.BulkImportView):
queryset = ModuleBay.objects.all()
model_form = forms.ModuleBayImportForm
class ModuleBayBulkEditView(generic.BulkEditView):
queryset = ModuleBay.objects.all()
filterset = filtersets.ModuleBayFilterSet
table = tables.ModuleBayTable
form = forms.ModuleBayBulkEditForm
class ModuleBayBulkRenameView(generic.BulkRenameView):
queryset = ModuleBay.objects.all()
class ModuleBayBulkDeleteView(generic.BulkDeleteView):
queryset = ModuleBay.objects.all()
filterset = filtersets.ModuleBayFilterSet
table = tables.ModuleBayTable
#
# Device bays
#
2020-11-11 16:07:38 -05:00
class DeviceBayListView(generic.ObjectListView):
queryset = DeviceBay.objects.all()
2021-04-29 16:38:56 -04:00
filterset = filtersets.DeviceBayFilterSet
filterset_form = forms.DeviceBayFilterForm
table = tables.DeviceBayTable
actions = ('import', 'export', 'bulk_edit', 'bulk_delete')
@register_model_view(DeviceBay)
2020-11-11 16:07:38 -05:00
class DeviceBayView(generic.ObjectView):
queryset = DeviceBay.objects.all()
2020-11-11 16:07:38 -05:00
class DeviceBayCreateView(generic.ComponentCreateView):
queryset = DeviceBay.objects.all()
form = forms.DeviceBayCreateForm
2016-12-21 15:26:56 -05:00
model_form = forms.DeviceBayForm
@register_model_view(DeviceBay, 'edit')
2020-11-11 16:07:38 -05:00
class DeviceBayEditView(generic.ObjectEditView):
queryset = DeviceBay.objects.all()
form = forms.DeviceBayForm
@register_model_view(DeviceBay, 'delete')
2020-11-11 16:07:38 -05:00
class DeviceBayDeleteView(generic.ObjectDeleteView):
queryset = DeviceBay.objects.all()
@register_model_view(DeviceBay, 'populate')
2020-11-11 16:07:38 -05:00
class DeviceBayPopulateView(generic.ObjectEditView):
queryset = DeviceBay.objects.all()
def get(self, request, pk):
device_bay = get_object_or_404(self.queryset, pk=pk)
form = forms.PopulateDeviceBayForm(device_bay)
return render(request, 'dcim/devicebay_populate.html', {
'device_bay': device_bay,
'form': form,
'return_url': self.get_return_url(request, device_bay),
})
def post(self, request, pk):
device_bay = get_object_or_404(self.queryset, pk=pk)
form = forms.PopulateDeviceBayForm(device_bay, request.POST)
if form.is_valid():
device_bay.snapshot()
device_bay.installed_device = form.cleaned_data['installed_device']
device_bay.save()
messages.success(request, "Added {} to {}.".format(device_bay.installed_device, device_bay))
return_url = self.get_return_url(request)
return redirect(return_url)
return render(request, 'dcim/devicebay_populate.html', {
'device_bay': device_bay,
'form': form,
'return_url': self.get_return_url(request, device_bay),
})
@register_model_view(DeviceBay, 'depopulate')
2020-11-11 16:07:38 -05:00
class DeviceBayDepopulateView(generic.ObjectEditView):
queryset = DeviceBay.objects.all()
def get(self, request, pk):
device_bay = get_object_or_404(self.queryset, pk=pk)
form = ConfirmationForm()
return render(request, 'dcim/devicebay_depopulate.html', {
'device_bay': device_bay,
'form': form,
'return_url': self.get_return_url(request, device_bay),
})
def post(self, request, pk):
device_bay = get_object_or_404(self.queryset, pk=pk)
form = ConfirmationForm(request.POST)
if form.is_valid():
device_bay.snapshot()
removed_device = device_bay.installed_device
device_bay.installed_device = None
device_bay.save()
messages.success(request, f"{removed_device} has been removed from {device_bay}.")
return_url = self.get_return_url(request, device_bay.device)
return redirect(return_url)
return render(request, 'dcim/devicebay_depopulate.html', {
'device_bay': device_bay,
'form': form,
'return_url': self.get_return_url(request, device_bay),
})
2020-11-11 16:07:38 -05:00
class DeviceBayBulkImportView(generic.BulkImportView):
2020-05-21 11:58:27 -04:00
queryset = DeviceBay.objects.all()
model_form = forms.DeviceBayImportForm
2020-11-11 16:07:38 -05:00
class DeviceBayBulkEditView(generic.BulkEditView):
queryset = DeviceBay.objects.all()
2021-04-29 16:38:56 -04:00
filterset = filtersets.DeviceBayFilterSet
table = tables.DeviceBayTable
form = forms.DeviceBayBulkEditForm
2020-11-11 16:07:38 -05:00
class DeviceBayBulkRenameView(generic.BulkRenameView):
queryset = DeviceBay.objects.all()
2020-11-11 16:07:38 -05:00
class DeviceBayBulkDeleteView(generic.BulkDeleteView):
queryset = DeviceBay.objects.all()
2021-04-29 16:38:56 -04:00
filterset = filtersets.DeviceBayFilterSet
table = tables.DeviceBayTable
#
# Inventory items
#
2020-11-11 16:07:38 -05:00
class InventoryItemListView(generic.ObjectListView):
queryset = InventoryItem.objects.all()
2021-04-29 16:38:56 -04:00
filterset = filtersets.InventoryItemFilterSet
filterset_form = forms.InventoryItemFilterForm
table = tables.InventoryItemTable
actions = ('import', 'export', 'bulk_edit', 'bulk_delete')
@register_model_view(InventoryItem)
2020-11-11 16:07:38 -05:00
class InventoryItemView(generic.ObjectView):
queryset = InventoryItem.objects.all()
@register_model_view(InventoryItem, 'edit')
2020-11-11 16:07:38 -05:00
class InventoryItemEditView(generic.ObjectEditView):
queryset = InventoryItem.objects.all()
form = forms.InventoryItemForm
template_name = 'dcim/inventoryitem_edit.html'
2020-11-11 16:07:38 -05:00
class InventoryItemCreateView(generic.ComponentCreateView):
queryset = InventoryItem.objects.all()
form = forms.InventoryItemCreateForm
model_form = forms.InventoryItemForm
template_name = 'dcim/inventoryitem_edit.html'
@register_model_view(InventoryItem, 'delete')
2020-11-11 16:07:38 -05:00
class InventoryItemDeleteView(generic.ObjectDeleteView):
queryset = InventoryItem.objects.all()
2020-11-11 16:07:38 -05:00
class InventoryItemBulkImportView(generic.BulkImportView):
queryset = InventoryItem.objects.all()
model_form = forms.InventoryItemImportForm
2020-11-11 16:07:38 -05:00
class InventoryItemBulkEditView(generic.BulkEditView):
queryset = InventoryItem.objects.all()
2021-04-29 16:38:56 -04:00
filterset = filtersets.InventoryItemFilterSet
table = tables.InventoryItemTable
form = forms.InventoryItemBulkEditForm
2020-11-11 16:07:38 -05:00
class InventoryItemBulkRenameView(generic.BulkRenameView):
queryset = InventoryItem.objects.all()
2020-11-11 16:07:38 -05:00
class InventoryItemBulkDeleteView(generic.BulkDeleteView):
queryset = InventoryItem.objects.all()
table = tables.InventoryItemTable
template_name = 'dcim/inventoryitem_bulk_delete.html'
2021-12-27 10:18:39 -05:00
#
# Inventory item roles
#
class InventoryItemRoleListView(generic.ObjectListView):
queryset = InventoryItemRole.objects.annotate(
inventoryitem_count=count_related(InventoryItem, 'role'),
)
filterset = filtersets.InventoryItemRoleFilterSet
filterset_form = forms.InventoryItemRoleFilterForm
table = tables.InventoryItemRoleTable
@register_model_view(InventoryItemRole)
2021-12-27 10:18:39 -05:00
class InventoryItemRoleView(generic.ObjectView):
queryset = InventoryItemRole.objects.all()
def get_extra_context(self, request, instance):
return {
'inventoryitem_count': InventoryItem.objects.filter(role=instance).count(),
}
@register_model_view(InventoryItemRole, 'edit')
2021-12-27 10:18:39 -05:00
class InventoryItemRoleEditView(generic.ObjectEditView):
queryset = InventoryItemRole.objects.all()
form = forms.InventoryItemRoleForm
2021-12-27 10:18:39 -05:00
@register_model_view(InventoryItemRole, 'delete')
2021-12-27 10:18:39 -05:00
class InventoryItemRoleDeleteView(generic.ObjectDeleteView):
queryset = InventoryItemRole.objects.all()
class InventoryItemRoleBulkImportView(generic.BulkImportView):
queryset = InventoryItemRole.objects.all()
model_form = forms.InventoryItemRoleImportForm
2021-12-27 10:18:39 -05:00
class InventoryItemRoleBulkEditView(generic.BulkEditView):
queryset = InventoryItemRole.objects.annotate(
inventoryitem_count=count_related(InventoryItem, 'role'),
)
filterset = filtersets.InventoryItemRoleFilterSet
table = tables.InventoryItemRoleTable
form = forms.InventoryItemRoleBulkEditForm
class InventoryItemRoleBulkDeleteView(generic.BulkDeleteView):
queryset = InventoryItemRole.objects.annotate(
inventoryitem_count=count_related(InventoryItem, 'role'),
)
table = tables.InventoryItemRoleTable
2016-12-21 15:26:56 -05:00
#
# Bulk Device component creation
2016-12-21 15:26:56 -05:00
#
2020-11-11 16:07:38 -05:00
class DeviceBulkAddConsolePortView(generic.BulkComponentCreateView):
parent_model = Device
parent_field = 'device'
form = forms.ConsolePortBulkCreateForm
queryset = ConsolePort.objects.all()
2016-12-21 15:26:56 -05:00
model_form = forms.ConsolePortForm
2021-04-29 16:38:56 -04:00
filterset = filtersets.DeviceFilterSet
table = tables.DeviceTable
default_return_url = 'dcim:device_list'
2016-12-21 15:26:56 -05:00
2020-11-11 16:07:38 -05:00
class DeviceBulkAddConsoleServerPortView(generic.BulkComponentCreateView):
parent_model = Device
parent_field = 'device'
form = forms.ConsoleServerPortBulkCreateForm
queryset = ConsoleServerPort.objects.all()
2016-12-21 15:26:56 -05:00
model_form = forms.ConsoleServerPortForm
2021-04-29 16:38:56 -04:00
filterset = filtersets.DeviceFilterSet
table = tables.DeviceTable
default_return_url = 'dcim:device_list'
2016-12-21 15:26:56 -05:00
2020-11-11 16:07:38 -05:00
class DeviceBulkAddPowerPortView(generic.BulkComponentCreateView):
parent_model = Device
parent_field = 'device'
form = forms.PowerPortBulkCreateForm
queryset = PowerPort.objects.all()
2016-12-21 15:26:56 -05:00
model_form = forms.PowerPortForm
2021-04-29 16:38:56 -04:00
filterset = filtersets.DeviceFilterSet
table = tables.DeviceTable
default_return_url = 'dcim:device_list'
2016-12-21 15:26:56 -05:00
2020-11-11 16:07:38 -05:00
class DeviceBulkAddPowerOutletView(generic.BulkComponentCreateView):
parent_model = Device
parent_field = 'device'
form = forms.PowerOutletBulkCreateForm
queryset = PowerOutlet.objects.all()
2016-12-21 15:26:56 -05:00
model_form = forms.PowerOutletForm
2021-04-29 16:38:56 -04:00
filterset = filtersets.DeviceFilterSet
table = tables.DeviceTable
default_return_url = 'dcim:device_list'
2016-12-21 15:26:56 -05:00
2020-11-11 16:07:38 -05:00
class DeviceBulkAddInterfaceView(generic.BulkComponentCreateView):
parent_model = Device
parent_field = 'device'
form = forms.InterfaceBulkCreateForm
queryset = Interface.objects.all()
2016-12-21 15:26:56 -05:00
model_form = forms.InterfaceForm
2021-04-29 16:38:56 -04:00
filterset = filtersets.DeviceFilterSet
table = tables.DeviceTable
default_return_url = 'dcim:device_list'
2016-12-21 15:26:56 -05:00
2020-11-11 16:07:38 -05:00
# class DeviceBulkAddFrontPortView(generic.BulkComponentCreateView):
2020-04-22 11:26:04 -04:00
# parent_model = Device
# parent_field = 'device'
# form = forms.FrontPortBulkCreateForm
# queryset = FrontPort.objects.all()
2020-04-22 11:26:04 -04:00
# model_form = forms.FrontPortForm
2021-04-29 16:38:56 -04:00
# filterset = filtersets.DeviceFilterSet
2020-04-22 11:26:04 -04:00
# table = tables.DeviceTable
# default_return_url = 'dcim:device_list'
2020-11-11 16:07:38 -05:00
class DeviceBulkAddRearPortView(generic.BulkComponentCreateView):
2020-04-22 11:26:04 -04:00
parent_model = Device
parent_field = 'device'
form = forms.RearPortBulkCreateForm
queryset = RearPort.objects.all()
2020-04-22 11:26:04 -04:00
model_form = forms.RearPortForm
2021-04-29 16:38:56 -04:00
filterset = filtersets.DeviceFilterSet
2020-04-22 11:26:04 -04:00
table = tables.DeviceTable
default_return_url = 'dcim:device_list'
class DeviceBulkAddModuleBayView(generic.BulkComponentCreateView):
parent_model = Device
parent_field = 'device'
form = forms.ModuleBayBulkCreateForm
queryset = ModuleBay.objects.all()
model_form = forms.ModuleBayForm
filterset = filtersets.DeviceFilterSet
table = tables.DeviceTable
default_return_url = 'dcim:device_list'
2020-11-11 16:07:38 -05:00
class DeviceBulkAddDeviceBayView(generic.BulkComponentCreateView):
parent_model = Device
parent_field = 'device'
form = forms.DeviceBayBulkCreateForm
queryset = DeviceBay.objects.all()
2016-12-21 15:26:56 -05:00
model_form = forms.DeviceBayForm
2021-04-29 16:38:56 -04:00
filterset = filtersets.DeviceFilterSet
table = tables.DeviceTable
default_return_url = 'dcim:device_list'
2016-12-21 15:26:56 -05:00
2020-11-11 16:07:38 -05:00
class DeviceBulkAddInventoryItemView(generic.BulkComponentCreateView):
parent_model = Device
parent_field = 'device'
form = forms.InventoryItemBulkCreateForm
queryset = InventoryItem.objects.all()
model_form = forms.InventoryItemForm
2021-04-29 16:38:56 -04:00
filterset = filtersets.DeviceFilterSet
table = tables.DeviceTable
default_return_url = 'dcim:device_list'
2018-10-24 14:24:02 -04:00
#
# Cables
#
2020-11-11 16:07:38 -05:00
class CableListView(generic.ObjectListView):
queryset = Cable.objects.prefetch_related(
'terminations__termination', 'terminations___device', 'terminations___rack', 'terminations___location',
'terminations___site',
)
2021-04-29 16:38:56 -04:00
filterset = filtersets.CableFilterSet
filterset_form = forms.CableFilterForm
2018-10-24 14:24:02 -04:00
table = tables.CableTable
actions = ('import', 'export', 'bulk_edit', 'bulk_delete')
2018-10-24 14:24:02 -04:00
@register_model_view(Cable)
2020-11-11 16:07:38 -05:00
class CableView(generic.ObjectView):
queryset = Cable.objects.all()
2018-10-25 15:51:12 -04:00
@register_model_view(Cable, 'edit')
class CableEditView(generic.ObjectEditView):
queryset = Cable.objects.all()
template_name = 'dcim/cable_edit.html'
2018-10-24 14:24:02 -04:00
2019-03-21 17:47:43 -04:00
def dispatch(self, request, *args, **kwargs):
2018-10-24 14:24:02 -04:00
# If creating a new Cable, initialize the form class using URL query params
if 'pk' not in kwargs:
2022-07-07 12:48:44 -04:00
self.form = forms.get_cable_form(
a_type=CABLE_TERMINATION_TYPES.get(request.GET.get('a_terminations_type')),
b_type=CABLE_TERMINATION_TYPES.get(request.GET.get('b_terminations_type'))
)
2019-03-21 17:47:43 -04:00
return super().dispatch(request, *args, **kwargs)
def get_object(self, **kwargs):
"""
Hack into get_object() to set the form class when editing an existing Cable, since ObjectEditView
doesn't currently provide a hook for dynamic class resolution.
"""
obj = super().get_object(**kwargs)
2018-10-24 14:24:02 -04:00
if obj.pk:
# TODO: Optimize this logic
termination_a = obj.terminations.filter(cable_end='A').first()
a_type = termination_a.termination._meta.model if termination_a else None
termination_b = obj.terminations.filter(cable_end='B').first()
2022-07-16 09:42:01 +02:00
b_type = termination_b.termination._meta.model if termination_b else None
self.form = forms.get_cable_form(a_type, b_type)
2018-10-24 14:24:02 -04:00
return obj
2018-10-25 15:51:12 -04:00
@register_model_view(Cable, 'delete')
2020-11-11 16:07:38 -05:00
class CableDeleteView(generic.ObjectDeleteView):
queryset = Cable.objects.all()
2018-10-24 14:24:02 -04:00
2020-11-11 16:07:38 -05:00
class CableBulkImportView(generic.BulkImportView):
2020-05-21 11:58:27 -04:00
queryset = Cable.objects.all()
model_form = forms.CableImportForm
2020-11-11 16:07:38 -05:00
class CableBulkEditView(generic.BulkEditView):
queryset = Cable.objects.prefetch_related(
'terminations__termination', 'terminations___device', 'terminations___rack', 'terminations___location',
'terminations___site',
)
2021-04-29 16:38:56 -04:00
filterset = filtersets.CableFilterSet
table = tables.CableTable
form = forms.CableBulkEditForm
2020-11-11 16:07:38 -05:00
class CableBulkDeleteView(generic.BulkDeleteView):
queryset = Cable.objects.prefetch_related(
'terminations__termination', 'terminations___device', 'terminations___rack', 'terminations___location',
'terminations___site',
)
2021-04-29 16:38:56 -04:00
filterset = filtersets.CableFilterSet
table = tables.CableTable
2016-03-01 11:23:03 -05:00
#
# Connections
#
2020-11-11 16:07:38 -05:00
class ConsoleConnectionsListView(generic.ObjectListView):
queryset = ConsolePort.objects.filter(_path__is_complete=True)
2021-04-29 16:38:56 -04:00
filterset = filtersets.ConsoleConnectionFilterSet
filterset_form = forms.ConsoleConnectionFilterForm
2016-05-18 16:02:53 -04:00
table = tables.ConsoleConnectionTable
2020-11-10 16:00:21 -05:00
template_name = 'dcim/connections_list.html'
actions = ('export',)
2016-03-01 11:23:03 -05:00
2021-12-14 11:28:13 -05:00
def get_extra_context(self, request):
2020-11-10 16:00:21 -05:00
return {
'title': 'Console Connections'
}
2016-03-01 11:23:03 -05:00
2020-11-11 16:07:38 -05:00
class PowerConnectionsListView(generic.ObjectListView):
queryset = PowerPort.objects.filter(_path__is_complete=True)
2021-04-29 16:38:56 -04:00
filterset = filtersets.PowerConnectionFilterSet
filterset_form = forms.PowerConnectionFilterForm
2016-05-18 16:02:53 -04:00
table = tables.PowerConnectionTable
2020-11-10 16:00:21 -05:00
template_name = 'dcim/connections_list.html'
actions = ('export',)
2016-03-01 11:23:03 -05:00
2021-12-14 11:28:13 -05:00
def get_extra_context(self, request):
2020-11-10 16:00:21 -05:00
return {
'title': 'Power Connections'
}
2016-03-01 11:23:03 -05:00
2020-11-11 16:07:38 -05:00
class InterfaceConnectionsListView(generic.ObjectListView):
queryset = Interface.objects.filter(_path__is_complete=True)
2021-04-29 16:38:56 -04:00
filterset = filtersets.InterfaceConnectionFilterSet
filterset_form = forms.InterfaceConnectionFilterForm
2016-05-18 16:02:53 -04:00
table = tables.InterfaceConnectionTable
2020-11-10 16:00:21 -05:00
template_name = 'dcim/connections_list.html'
actions = ('export',)
2016-03-01 11:23:03 -05:00
2021-12-14 11:28:13 -05:00
def get_extra_context(self, request):
2020-11-10 16:00:21 -05:00
return {
'title': 'Interface Connections'
}
2016-03-01 11:23:03 -05:00
#
# Virtual chassis
#
2020-11-11 16:07:38 -05:00
class VirtualChassisListView(generic.ObjectListView):
queryset = VirtualChassis.objects.annotate(
member_count=count_related(Device, 'virtual_chassis')
)
table = tables.VirtualChassisTable
2021-04-29 16:38:56 -04:00
filterset = filtersets.VirtualChassisFilterSet
filterset_form = forms.VirtualChassisFilterForm
@register_model_view(VirtualChassis)
2020-11-11 16:07:38 -05:00
class VirtualChassisView(generic.ObjectView):
queryset = VirtualChassis.objects.all()
def get_extra_context(self, request, instance):
members = Device.objects.restrict(request.user).filter(virtual_chassis=instance)
return {
'members': members,
}
2020-11-11 16:07:38 -05:00
class VirtualChassisCreateView(generic.ObjectEditView):
queryset = VirtualChassis.objects.all()
form = forms.VirtualChassisCreateForm
template_name = 'dcim/virtualchassis_add.html'
@register_model_view(VirtualChassis, 'edit')
class VirtualChassisEditView(ObjectPermissionRequiredMixin, GetReturnURLMixin, View):
queryset = VirtualChassis.objects.all()
def get_required_permission(self):
return 'dcim.change_virtualchassis'
def get(self, request, pk):
virtual_chassis = get_object_or_404(self.queryset, pk=pk)
2018-02-14 12:05:00 -05:00
VCMemberFormSet = modelformset_factory(
model=Device,
form=forms.DeviceVCMembershipForm,
formset=forms.BaseVCMemberFormSet,
extra=0
)
members_queryset = virtual_chassis.members.prefetch_related('rack').order_by('vc_position')
vc_form = forms.VirtualChassisForm(instance=virtual_chassis)
2018-02-14 12:05:00 -05:00
vc_form.fields['master'].queryset = members_queryset
formset = VCMemberFormSet(queryset=members_queryset)
return render(request, 'dcim/virtualchassis_edit.html', {
'vc_form': vc_form,
'formset': formset,
'return_url': self.get_return_url(request, virtual_chassis),
})
def post(self, request, pk):
virtual_chassis = get_object_or_404(self.queryset, pk=pk)
2018-02-14 12:05:00 -05:00
VCMemberFormSet = modelformset_factory(
model=Device,
form=forms.DeviceVCMembershipForm,
formset=forms.BaseVCMemberFormSet,
extra=0
)
members_queryset = virtual_chassis.members.prefetch_related('rack').order_by('vc_position')
vc_form = forms.VirtualChassisForm(request.POST, instance=virtual_chassis)
2018-02-14 12:05:00 -05:00
vc_form.fields['master'].queryset = members_queryset
formset = VCMemberFormSet(request.POST, queryset=members_queryset)
if vc_form.is_valid() and formset.is_valid():
2018-02-01 15:53:59 -05:00
with transaction.atomic():
# Save the VirtualChassis
vc_form.save()
# Nullify the vc_position of each member first to allow reordering without raising an IntegrityError on
# duplicate positions. Then save each member instance.
members = formset.save(commit=False)
2019-08-20 17:16:00 -04:00
devices = Device.objects.filter(pk__in=[m.pk for m in members])
for device in devices:
device.vc_position = None
device.save()
2018-02-01 15:53:59 -05:00
for member in members:
member.save()
return redirect(virtual_chassis.get_absolute_url())
2018-02-01 11:39:13 -05:00
return render(request, 'dcim/virtualchassis_edit.html', {
'vc_form': vc_form,
'formset': formset,
'return_url': self.get_return_url(request, virtual_chassis),
})
@register_model_view(VirtualChassis, 'delete')
2020-11-11 16:07:38 -05:00
class VirtualChassisDeleteView(generic.ObjectDeleteView):
queryset = VirtualChassis.objects.all()
2018-02-01 11:39:13 -05:00
@register_model_view(VirtualChassis, 'add_member', path='add-member')
class VirtualChassisAddMemberView(ObjectPermissionRequiredMixin, GetReturnURLMixin, View):
queryset = VirtualChassis.objects.all()
def get_required_permission(self):
return 'dcim.change_virtualchassis'
2018-02-01 11:39:13 -05:00
def get(self, request, pk):
virtual_chassis = get_object_or_404(self.queryset, pk=pk)
2018-02-01 11:39:13 -05:00
initial_data = {k: request.GET[k] for k in request.GET}
member_select_form = forms.VCMemberSelectForm(initial=initial_data)
membership_form = forms.DeviceVCMembershipForm(initial=initial_data)
return render(request, 'dcim/virtualchassis_add_member.html', {
'virtual_chassis': virtual_chassis,
'member_select_form': member_select_form,
'membership_form': membership_form,
'return_url': self.get_return_url(request, virtual_chassis),
})
def post(self, request, pk):
virtual_chassis = get_object_or_404(self.queryset, pk=pk)
2018-02-01 11:39:13 -05:00
member_select_form = forms.VCMemberSelectForm(request.POST)
if member_select_form.is_valid():
device = member_select_form.cleaned_data['device']
device.virtual_chassis = virtual_chassis
data = {k: request.POST[k] for k in ['vc_position', 'vc_priority']}
membership_form = forms.DeviceVCMembershipForm(data=data, validate_vc_position=True, instance=device)
2018-02-01 11:39:13 -05:00
if membership_form.is_valid():
membership_form.save()
2022-08-08 10:47:07 -04:00
msg = f'Added member <a href="{device.get_absolute_url()}">{escape(device)}</a>'
2018-02-01 11:39:13 -05:00
messages.success(request, mark_safe(msg))
if '_addanother' in request.POST:
return redirect(request.get_full_path())
return redirect(self.get_return_url(request, device))
else:
membership_form = forms.DeviceVCMembershipForm(data=request.POST)
2018-02-01 11:39:13 -05:00
return render(request, 'dcim/virtualchassis_add_member.html', {
'virtual_chassis': virtual_chassis,
'member_select_form': member_select_form,
'membership_form': membership_form,
'return_url': self.get_return_url(request, virtual_chassis),
})
class VirtualChassisRemoveMemberView(ObjectPermissionRequiredMixin, GetReturnURLMixin, View):
queryset = Device.objects.all()
def get_required_permission(self):
return 'dcim.change_device'
def get(self, request, pk):
device = get_object_or_404(self.queryset, pk=pk, virtual_chassis__isnull=False)
form = ConfirmationForm(initial=request.GET)
return render(request, 'dcim/virtualchassis_remove_member.html', {
'device': device,
'form': form,
'return_url': self.get_return_url(request, device),
})
def post(self, request, pk):
device = get_object_or_404(self.queryset, pk=pk, virtual_chassis__isnull=False)
form = ConfirmationForm(request.POST)
# Protect master device from being removed
virtual_chassis = VirtualChassis.objects.filter(master=device).first()
if virtual_chassis is not None:
2022-08-08 10:47:07 -04:00
messages.error(request, f'Unable to remove master device {device} from the virtual chassis.')
return redirect(device.get_absolute_url())
if form.is_valid():
2019-08-20 17:16:00 -04:00
devices = Device.objects.filter(pk=device.pk)
for device in devices:
device.virtual_chassis = None
device.vc_position = None
device.vc_priority = None
device.save()
msg = 'Removed {} from virtual chassis {}'.format(device, device.virtual_chassis)
messages.success(request, msg)
return redirect(self.get_return_url(request, device))
return render(request, 'dcim/virtualchassis_remove_member.html', {
'device': device,
'form': form,
'return_url': self.get_return_url(request, device),
})
2019-03-11 22:40:52 -04:00
2020-11-11 16:07:38 -05:00
class VirtualChassisBulkImportView(generic.BulkImportView):
2020-06-24 15:29:25 -04:00
queryset = VirtualChassis.objects.all()
model_form = forms.VirtualChassisImportForm
2020-06-24 15:29:25 -04:00
2020-11-11 16:07:38 -05:00
class VirtualChassisBulkEditView(generic.BulkEditView):
queryset = VirtualChassis.objects.all()
2021-04-29 16:38:56 -04:00
filterset = filtersets.VirtualChassisFilterSet
table = tables.VirtualChassisTable
form = forms.VirtualChassisBulkEditForm
2020-11-11 16:07:38 -05:00
class VirtualChassisBulkDeleteView(generic.BulkDeleteView):
queryset = VirtualChassis.objects.all()
2021-04-29 16:38:56 -04:00
filterset = filtersets.VirtualChassisFilterSet
table = tables.VirtualChassisTable
2019-03-11 22:40:52 -04:00
#
# Power panels
#
2020-11-11 16:07:38 -05:00
class PowerPanelListView(generic.ObjectListView):
queryset = PowerPanel.objects.annotate(
powerfeed_count=count_related(PowerFeed, 'power_panel')
)
2021-04-29 16:38:56 -04:00
filterset = filtersets.PowerPanelFilterSet
filterset_form = forms.PowerPanelFilterForm
2019-03-11 22:40:52 -04:00
table = tables.PowerPanelTable
@register_model_view(PowerPanel)
2020-11-11 16:07:38 -05:00
class PowerPanelView(generic.ObjectView):
queryset = PowerPanel.objects.all()
2019-03-12 10:15:56 -04:00
def get_extra_context(self, request, instance):
related_models = (
(PowerFeed.objects.restrict(request.user).filter(power_panel=instance), 'power_panel_id'),
)
return {
'related_models': related_models,
}
2019-03-12 10:15:56 -04:00
@register_model_view(PowerPanel, 'edit')
2020-11-11 16:07:38 -05:00
class PowerPanelEditView(generic.ObjectEditView):
queryset = PowerPanel.objects.all()
form = forms.PowerPanelForm
2019-03-11 22:40:52 -04:00
@register_model_view(PowerPanel, 'delete')
2020-11-11 16:07:38 -05:00
class PowerPanelDeleteView(generic.ObjectDeleteView):
queryset = PowerPanel.objects.all()
2019-03-12 10:15:56 -04:00
2020-11-11 16:07:38 -05:00
class PowerPanelBulkImportView(generic.BulkImportView):
2020-05-21 11:58:27 -04:00
queryset = PowerPanel.objects.all()
model_form = forms.PowerPanelImportForm
2019-03-11 22:40:52 -04:00
2020-11-11 16:07:38 -05:00
class PowerPanelBulkEditView(generic.BulkEditView):
queryset = PowerPanel.objects.all()
2021-04-29 16:38:56 -04:00
filterset = filtersets.PowerPanelFilterSet
table = tables.PowerPanelTable
form = forms.PowerPanelBulkEditForm
2020-11-11 16:07:38 -05:00
class PowerPanelBulkDeleteView(generic.BulkDeleteView):
queryset = PowerPanel.objects.annotate(
powerfeed_count=count_related(PowerFeed, 'power_panel')
)
2021-04-29 16:38:56 -04:00
filterset = filtersets.PowerPanelFilterSet
2019-03-11 22:40:52 -04:00
table = tables.PowerPanelTable
#
# Power feeds
#
2020-11-11 16:07:38 -05:00
class PowerFeedListView(generic.ObjectListView):
queryset = PowerFeed.objects.all()
2021-04-29 16:38:56 -04:00
filterset = filtersets.PowerFeedFilterSet
filterset_form = forms.PowerFeedFilterForm
2019-03-11 22:40:52 -04:00
table = tables.PowerFeedTable
@register_model_view(PowerFeed)
2020-11-11 16:07:38 -05:00
class PowerFeedView(generic.ObjectView):
queryset = PowerFeed.objects.all()
2019-03-11 22:40:52 -04:00
@register_model_view(PowerFeed, 'edit')
2020-11-11 16:07:38 -05:00
class PowerFeedEditView(generic.ObjectEditView):
queryset = PowerFeed.objects.all()
form = forms.PowerFeedForm
2019-03-11 22:40:52 -04:00
@register_model_view(PowerFeed, 'delete')
2020-11-11 16:07:38 -05:00
class PowerFeedDeleteView(generic.ObjectDeleteView):
queryset = PowerFeed.objects.all()
2019-03-11 22:40:52 -04:00
2020-11-11 16:07:38 -05:00
class PowerFeedBulkImportView(generic.BulkImportView):
2020-05-21 11:58:27 -04:00
queryset = PowerFeed.objects.all()
model_form = forms.PowerFeedImportForm
2019-03-11 22:40:52 -04:00
2020-11-11 16:07:38 -05:00
class PowerFeedBulkEditView(generic.BulkEditView):
queryset = PowerFeed.objects.all()
2021-04-29 16:38:56 -04:00
filterset = filtersets.PowerFeedFilterSet
2019-03-11 22:40:52 -04:00
table = tables.PowerFeedTable
form = forms.PowerFeedBulkEditForm
class PowerFeedBulkDisconnectView(BulkDisconnectView):
queryset = PowerFeed.objects.all()
2020-11-11 16:07:38 -05:00
class PowerFeedBulkDeleteView(generic.BulkDeleteView):
queryset = PowerFeed.objects.all()
2021-04-29 16:38:56 -04:00
filterset = filtersets.PowerFeedFilterSet
2019-03-11 22:40:52 -04:00
table = tables.PowerFeedTable
# Trace view
register_model_view(PowerFeed, 'trace', kwargs={'model': PowerFeed})(PathTraceView)
Closes: #7854 - Add VDC/Instances/etc (#10787) * Work on #7854 * Move to new URL scheme. * Fix PEP8 errors * Fix PEP8 errors * Add GraphQL and fix primary_ip missing * Fix PEP8 on GQL Type * Fix missing NestedSerializer. * Fix missing NestedSerializer & rename VDC to VDCs * Fix migration * Change Validation for identifier * Fix missing migration * Rebase to feature * Post-review changes * Remove VDC Type * Remove M2M Enforcement logic * Interface related changes * Add filter fields to filterset for Interface filter * Add form field to filterset form for Interface filter * Add VDC display to interface detail template * Remove VirtualDeviceContextTypeChoices * Accommodate recent changes in feature branch * Add tests Add missing search() * Update tests, and fix model form * Update test_api * Update test_api.InterfaceTest create_data * Fix issue with tests * Update interface serializer * Update serializer and tests * Update status to be required * Remove error message for constraint * Remove extraneous import * Re-ordered devices menu to place VDC below virtual chassis * Add helptext for `identifier` field * Fix breadcrumb link * Remove add interface link * Add missing tenant and status fields * Changes to tests as per Jeremy * Change for #9623 Co-authored-by: Jeremy Stretch <jstretch@ns1.com> * Update filterset form for status field * Remove Rename View * Change tabs to spaces * Update netbox/dcim/tables/devices.py Co-authored-by: Jeremy Stretch <jstretch@ns1.com> * Update netbox/dcim/tables/devices.py Co-authored-by: Jeremy Stretch <jstretch@ns1.com> * Fix tenant in bulk_edit * Apply suggestions from code review Co-authored-by: Jeremy Stretch <jstretch@ns1.com> * Add status field to table. * Re-order table fields. Co-authored-by: Jeremy Stretch <jstretch@ns1.com>
2022-11-11 06:55:49 -06:00
# VDC
class VirtualDeviceContextListView(generic.ObjectListView):
2022-12-12 12:34:05 -05:00
queryset = VirtualDeviceContext.objects.annotate(
interface_count=count_related(Interface, 'vdcs'),
)
Closes: #7854 - Add VDC/Instances/etc (#10787) * Work on #7854 * Move to new URL scheme. * Fix PEP8 errors * Fix PEP8 errors * Add GraphQL and fix primary_ip missing * Fix PEP8 on GQL Type * Fix missing NestedSerializer. * Fix missing NestedSerializer & rename VDC to VDCs * Fix migration * Change Validation for identifier * Fix missing migration * Rebase to feature * Post-review changes * Remove VDC Type * Remove M2M Enforcement logic * Interface related changes * Add filter fields to filterset for Interface filter * Add form field to filterset form for Interface filter * Add VDC display to interface detail template * Remove VirtualDeviceContextTypeChoices * Accommodate recent changes in feature branch * Add tests Add missing search() * Update tests, and fix model form * Update test_api * Update test_api.InterfaceTest create_data * Fix issue with tests * Update interface serializer * Update serializer and tests * Update status to be required * Remove error message for constraint * Remove extraneous import * Re-ordered devices menu to place VDC below virtual chassis * Add helptext for `identifier` field * Fix breadcrumb link * Remove add interface link * Add missing tenant and status fields * Changes to tests as per Jeremy * Change for #9623 Co-authored-by: Jeremy Stretch <jstretch@ns1.com> * Update filterset form for status field * Remove Rename View * Change tabs to spaces * Update netbox/dcim/tables/devices.py Co-authored-by: Jeremy Stretch <jstretch@ns1.com> * Update netbox/dcim/tables/devices.py Co-authored-by: Jeremy Stretch <jstretch@ns1.com> * Fix tenant in bulk_edit * Apply suggestions from code review Co-authored-by: Jeremy Stretch <jstretch@ns1.com> * Add status field to table. * Re-order table fields. Co-authored-by: Jeremy Stretch <jstretch@ns1.com>
2022-11-11 06:55:49 -06:00
filterset = filtersets.VirtualDeviceContextFilterSet
filterset_form = forms.VirtualDeviceContextFilterForm
table = tables.VirtualDeviceContextTable
@register_model_view(VirtualDeviceContext)
class VirtualDeviceContextView(generic.ObjectView):
queryset = VirtualDeviceContext.objects.all()
def get_extra_context(self, request, instance):
related_models = (
(Interface.objects.restrict(request.user, 'view').filter(vdcs__in=[instance]), 'vdc_id'),
)
return {
'related_models': related_models,
}
Closes: #7854 - Add VDC/Instances/etc (#10787) * Work on #7854 * Move to new URL scheme. * Fix PEP8 errors * Fix PEP8 errors * Add GraphQL and fix primary_ip missing * Fix PEP8 on GQL Type * Fix missing NestedSerializer. * Fix missing NestedSerializer & rename VDC to VDCs * Fix migration * Change Validation for identifier * Fix missing migration * Rebase to feature * Post-review changes * Remove VDC Type * Remove M2M Enforcement logic * Interface related changes * Add filter fields to filterset for Interface filter * Add form field to filterset form for Interface filter * Add VDC display to interface detail template * Remove VirtualDeviceContextTypeChoices * Accommodate recent changes in feature branch * Add tests Add missing search() * Update tests, and fix model form * Update test_api * Update test_api.InterfaceTest create_data * Fix issue with tests * Update interface serializer * Update serializer and tests * Update status to be required * Remove error message for constraint * Remove extraneous import * Re-ordered devices menu to place VDC below virtual chassis * Add helptext for `identifier` field * Fix breadcrumb link * Remove add interface link * Add missing tenant and status fields * Changes to tests as per Jeremy * Change for #9623 Co-authored-by: Jeremy Stretch <jstretch@ns1.com> * Update filterset form for status field * Remove Rename View * Change tabs to spaces * Update netbox/dcim/tables/devices.py Co-authored-by: Jeremy Stretch <jstretch@ns1.com> * Update netbox/dcim/tables/devices.py Co-authored-by: Jeremy Stretch <jstretch@ns1.com> * Fix tenant in bulk_edit * Apply suggestions from code review Co-authored-by: Jeremy Stretch <jstretch@ns1.com> * Add status field to table. * Re-order table fields. Co-authored-by: Jeremy Stretch <jstretch@ns1.com>
2022-11-11 06:55:49 -06:00
@register_model_view(VirtualDeviceContext, 'edit')
class VirtualDeviceContextEditView(generic.ObjectEditView):
queryset = VirtualDeviceContext.objects.all()
form = forms.VirtualDeviceContextForm
@register_model_view(VirtualDeviceContext, 'delete')
class VirtualDeviceContextDeleteView(generic.ObjectDeleteView):
queryset = VirtualDeviceContext.objects.all()
class VirtualDeviceContextBulkImportView(generic.BulkImportView):
queryset = VirtualDeviceContext.objects.all()
model_form = forms.VirtualDeviceContextImportForm
Closes: #7854 - Add VDC/Instances/etc (#10787) * Work on #7854 * Move to new URL scheme. * Fix PEP8 errors * Fix PEP8 errors * Add GraphQL and fix primary_ip missing * Fix PEP8 on GQL Type * Fix missing NestedSerializer. * Fix missing NestedSerializer & rename VDC to VDCs * Fix migration * Change Validation for identifier * Fix missing migration * Rebase to feature * Post-review changes * Remove VDC Type * Remove M2M Enforcement logic * Interface related changes * Add filter fields to filterset for Interface filter * Add form field to filterset form for Interface filter * Add VDC display to interface detail template * Remove VirtualDeviceContextTypeChoices * Accommodate recent changes in feature branch * Add tests Add missing search() * Update tests, and fix model form * Update test_api * Update test_api.InterfaceTest create_data * Fix issue with tests * Update interface serializer * Update serializer and tests * Update status to be required * Remove error message for constraint * Remove extraneous import * Re-ordered devices menu to place VDC below virtual chassis * Add helptext for `identifier` field * Fix breadcrumb link * Remove add interface link * Add missing tenant and status fields * Changes to tests as per Jeremy * Change for #9623 Co-authored-by: Jeremy Stretch <jstretch@ns1.com> * Update filterset form for status field * Remove Rename View * Change tabs to spaces * Update netbox/dcim/tables/devices.py Co-authored-by: Jeremy Stretch <jstretch@ns1.com> * Update netbox/dcim/tables/devices.py Co-authored-by: Jeremy Stretch <jstretch@ns1.com> * Fix tenant in bulk_edit * Apply suggestions from code review Co-authored-by: Jeremy Stretch <jstretch@ns1.com> * Add status field to table. * Re-order table fields. Co-authored-by: Jeremy Stretch <jstretch@ns1.com>
2022-11-11 06:55:49 -06:00
class VirtualDeviceContextBulkEditView(generic.BulkEditView):
queryset = VirtualDeviceContext.objects.all()
filterset = filtersets.VirtualDeviceContextFilterSet
table = tables.VirtualDeviceContextTable
form = forms.VirtualDeviceContextBulkEditForm
class VirtualDeviceContextBulkDeleteView(generic.BulkDeleteView):
queryset = VirtualDeviceContext.objects.all()
filterset = filtersets.VirtualDeviceContextFilterSet
table = tables.VirtualDeviceContextTable