| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524 |
- from collections import OrderedDict
- from django.conf import settings
- from django.contrib import messages
- from django.contrib.contenttypes.models import ContentType
- from django.core.paginator import EmptyPage, PageNotAnInteger
- from django.db import transaction
- from django.db.models import Count, F, Prefetch
- from django.forms import ModelMultipleChoiceField, MultipleHiddenInput, modelformset_factory
- 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.views.generic import View
- from circuits.models import Circuit
- from extras.models import Graph
- from extras.views import ObjectConfigContextView
- from ipam.models import IPAddress, Prefix, Service, VLAN
- from ipam.tables import InterfaceIPAddressTable, InterfaceVLANTable
- from secrets.models import Secret
- from utilities.forms import ConfirmationForm
- from utilities.paginator import EnhancedPaginator
- from utilities.permissions import get_permission_for_model
- from utilities.utils import csv_format, get_subquery
- from utilities.views import (
- BulkComponentCreateView, BulkDeleteView, BulkEditView, BulkImportView, BulkRenameView, ComponentCreateView,
- GetReturnURLMixin, ObjectView, ObjectImportView, ObjectDeleteView, ObjectEditView, ObjectListView,
- ObjectPermissionRequiredMixin,
- )
- from virtualization.models import VirtualMachine
- from . import filters, forms, tables
- from .choices import DeviceFaceChoices
- from .constants import NONCONNECTABLE_IFACE_TYPES
- from .models import (
- Cable, ConsolePort, ConsolePortTemplate, ConsoleServerPort, ConsoleServerPortTemplate, Device, DeviceBay,
- DeviceBayTemplate, DeviceRole, DeviceType, FrontPort, FrontPortTemplate, Interface, InterfaceTemplate,
- InventoryItem, Manufacturer, Platform, PowerFeed, PowerOutlet, PowerOutletTemplate, PowerPanel, PowerPort,
- PowerPortTemplate, Rack, RackGroup, RackReservation, RackRole, RearPort, RearPortTemplate, Region, Site,
- VirtualChassis,
- )
- 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,
- })
- #
- # Regions
- #
- class RegionListView(ObjectListView):
- queryset = Region.objects.add_related_count(
- Region.objects.all(),
- Site,
- 'region',
- 'site_count',
- cumulative=True
- )
- filterset = filters.RegionFilterSet
- filterset_form = forms.RegionFilterForm
- table = tables.RegionTable
- class RegionEditView(ObjectEditView):
- queryset = Region.objects.all()
- model_form = forms.RegionForm
- class RegionDeleteView(ObjectDeleteView):
- queryset = Region.objects.all()
- class RegionBulkImportView(BulkImportView):
- queryset = Region.objects.all()
- model_form = forms.RegionCSVForm
- table = tables.RegionTable
- class RegionBulkDeleteView(BulkDeleteView):
- queryset = Region.objects.add_related_count(
- Region.objects.all(),
- Site,
- 'region',
- 'site_count',
- cumulative=True
- )
- filterset = filters.RegionFilterSet
- table = tables.RegionTable
- #
- # Sites
- #
- class SiteListView(ObjectListView):
- queryset = Site.objects.prefetch_related('region', 'tenant')
- filterset = filters.SiteFilterSet
- filterset_form = forms.SiteFilterForm
- table = tables.SiteTable
- class SiteView(ObjectView):
- queryset = Site.objects.prefetch_related('region', 'tenant__group')
- def get(self, request, slug):
- site = get_object_or_404(self.queryset, slug=slug)
- stats = {
- 'rack_count': Rack.objects.restrict(request.user, 'view').filter(site=site).count(),
- 'device_count': Device.objects.restrict(request.user, 'view').filter(site=site).count(),
- 'prefix_count': Prefix.objects.restrict(request.user, 'view').filter(site=site).count(),
- 'vlan_count': VLAN.objects.restrict(request.user, 'view').filter(site=site).count(),
- 'circuit_count': Circuit.objects.restrict(request.user, 'view').filter(terminations__site=site).count(),
- 'vm_count': VirtualMachine.objects.restrict(request.user, 'view').filter(cluster__site=site).count(),
- }
- rack_groups = RackGroup.objects.restrict(request.user, 'view').filter(site=site).annotate(
- rack_count=Count('racks')
- )
- show_graphs = Graph.objects.filter(type__model='site').exists()
- return render(request, 'dcim/site.html', {
- 'site': site,
- 'stats': stats,
- 'rack_groups': rack_groups,
- 'show_graphs': show_graphs,
- })
- class SiteEditView(ObjectEditView):
- queryset = Site.objects.all()
- model_form = forms.SiteForm
- template_name = 'dcim/site_edit.html'
- class SiteDeleteView(ObjectDeleteView):
- queryset = Site.objects.all()
- class SiteBulkImportView(BulkImportView):
- queryset = Site.objects.all()
- model_form = forms.SiteCSVForm
- table = tables.SiteTable
- class SiteBulkEditView(BulkEditView):
- queryset = Site.objects.prefetch_related('region', 'tenant')
- filterset = filters.SiteFilterSet
- table = tables.SiteTable
- form = forms.SiteBulkEditForm
- class SiteBulkDeleteView(BulkDeleteView):
- queryset = Site.objects.prefetch_related('region', 'tenant')
- filterset = filters.SiteFilterSet
- table = tables.SiteTable
- #
- # Rack groups
- #
- class RackGroupListView(ObjectListView):
- queryset = RackGroup.objects.add_related_count(
- RackGroup.objects.all(),
- Rack,
- 'group',
- 'rack_count',
- cumulative=True
- ).prefetch_related('site')
- filterset = filters.RackGroupFilterSet
- filterset_form = forms.RackGroupFilterForm
- table = tables.RackGroupTable
- class RackGroupEditView(ObjectEditView):
- queryset = RackGroup.objects.all()
- model_form = forms.RackGroupForm
- class RackGroupDeleteView(ObjectDeleteView):
- queryset = RackGroup.objects.all()
- class RackGroupBulkImportView(BulkImportView):
- queryset = RackGroup.objects.all()
- model_form = forms.RackGroupCSVForm
- table = tables.RackGroupTable
- class RackGroupBulkDeleteView(BulkDeleteView):
- queryset = RackGroup.objects.add_related_count(
- RackGroup.objects.all(),
- Rack,
- 'group',
- 'rack_count',
- cumulative=True
- ).prefetch_related('site')
- filterset = filters.RackGroupFilterSet
- table = tables.RackGroupTable
- #
- # Rack roles
- #
- class RackRoleListView(ObjectListView):
- queryset = RackRole.objects.annotate(rack_count=Count('racks')).order_by(*RackRole._meta.ordering)
- table = tables.RackRoleTable
- class RackRoleEditView(ObjectEditView):
- queryset = RackRole.objects.all()
- model_form = forms.RackRoleForm
- class RackRoleDeleteView(ObjectDeleteView):
- queryset = RackRole.objects.all()
- class RackRoleBulkImportView(BulkImportView):
- queryset = RackRole.objects.all()
- model_form = forms.RackRoleCSVForm
- table = tables.RackRoleTable
- class RackRoleBulkDeleteView(BulkDeleteView):
- queryset = RackRole.objects.annotate(rack_count=Count('racks')).order_by(*RackRole._meta.ordering)
- table = tables.RackRoleTable
- #
- # Racks
- #
- class RackListView(ObjectListView):
- queryset = Rack.objects.prefetch_related(
- 'site', 'group', 'tenant', 'role', 'devices__device_type'
- ).annotate(
- device_count=Count('devices')
- ).order_by(*Rack._meta.ordering)
- filterset = filters.RackFilterSet
- filterset_form = forms.RackFilterForm
- table = tables.RackDetailTable
- class RackElevationListView(ObjectListView):
- """
- Display a set of rack elevations side-by-side.
- """
- queryset = Rack.objects.prefetch_related('role')
- def get(self, request):
- racks = filters.RackFilterSet(request.GET, self.queryset).qs
- total_count = racks.count()
- # Pagination
- per_page = request.GET.get('per_page', settings.PAGINATE_COUNT)
- 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,
- 'rack_face': rack_face,
- 'filter_form': forms.RackElevationFilterForm(request.GET),
- })
- class RackView(ObjectView):
- queryset = Rack.objects.prefetch_related('site__region', 'tenant__group', 'group', 'role')
- def get(self, request, pk):
- rack = get_object_or_404(self.queryset, pk=pk)
- # Get 0U and child devices located within the rack
- nonracked_devices = Device.objects.filter(
- rack=rack,
- position__isnull=True
- ).prefetch_related('device_type__manufacturer')
- peer_racks = Rack.objects.restrict(request.user, 'view').filter(site=rack.site)
- if rack.group:
- peer_racks = peer_racks.filter(group=rack.group)
- else:
- peer_racks = peer_racks.filter(group__isnull=True)
- next_rack = peer_racks.filter(name__gt=rack.name).order_by('name').first()
- prev_rack = peer_racks.filter(name__lt=rack.name).order_by('-name').first()
- reservations = RackReservation.objects.restrict(request.user, 'view').filter(rack=rack)
- power_feeds = PowerFeed.objects.restrict(request.user, 'view').filter(rack=rack).prefetch_related('power_panel')
- return render(request, 'dcim/rack.html', {
- 'rack': rack,
- 'device_count': Device.objects.restrict(request.user, 'view').filter(rack=rack).count(),
- 'reservations': reservations,
- 'power_feeds': power_feeds,
- 'nonracked_devices': nonracked_devices,
- 'next_rack': next_rack,
- 'prev_rack': prev_rack,
- })
- class RackEditView(ObjectEditView):
- queryset = Rack.objects.all()
- model_form = forms.RackForm
- template_name = 'dcim/rack_edit.html'
- class RackDeleteView(ObjectDeleteView):
- queryset = Rack.objects.all()
- class RackBulkImportView(BulkImportView):
- queryset = Rack.objects.all()
- model_form = forms.RackCSVForm
- table = tables.RackTable
- class RackBulkEditView(BulkEditView):
- queryset = Rack.objects.prefetch_related('site', 'group', 'tenant', 'role')
- filterset = filters.RackFilterSet
- table = tables.RackTable
- form = forms.RackBulkEditForm
- class RackBulkDeleteView(BulkDeleteView):
- queryset = Rack.objects.prefetch_related('site', 'group', 'tenant', 'role')
- filterset = filters.RackFilterSet
- table = tables.RackTable
- #
- # Rack reservations
- #
- class RackReservationListView(ObjectListView):
- queryset = RackReservation.objects.prefetch_related('rack__site')
- filterset = filters.RackReservationFilterSet
- filterset_form = forms.RackReservationFilterForm
- table = tables.RackReservationTable
- action_buttons = ('export',)
- class RackReservationView(ObjectView):
- queryset = RackReservation.objects.prefetch_related('rack')
- def get(self, request, pk):
- rackreservation = get_object_or_404(self.queryset, pk=pk)
- return render(request, 'dcim/rackreservation.html', {
- 'rackreservation': rackreservation,
- })
- class RackReservationEditView(ObjectEditView):
- queryset = RackReservation.objects.all()
- model_form = forms.RackReservationForm
- template_name = 'dcim/rackreservation_edit.html'
- def alter_obj(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
- class RackReservationDeleteView(ObjectDeleteView):
- queryset = RackReservation.objects.all()
- class RackReservationImportView(BulkImportView):
- queryset = RackReservation.objects.all()
- model_form = forms.RackReservationCSVForm
- table = tables.RackReservationTable
- def _save_obj(self, obj_form, request):
- """
- Assign the currently authenticated user to the RackReservation.
- """
- instance = obj_form.save(commit=False)
- instance.user = request.user
- instance.save()
- return instance
- class RackReservationBulkEditView(BulkEditView):
- queryset = RackReservation.objects.prefetch_related('rack', 'user')
- filterset = filters.RackReservationFilterSet
- table = tables.RackReservationTable
- form = forms.RackReservationBulkEditForm
- class RackReservationBulkDeleteView(BulkDeleteView):
- queryset = RackReservation.objects.prefetch_related('rack', 'user')
- filterset = filters.RackReservationFilterSet
- table = tables.RackReservationTable
- #
- # Manufacturers
- #
- class ManufacturerListView(ObjectListView):
- queryset = Manufacturer.objects.annotate(
- devicetype_count=get_subquery(DeviceType, 'manufacturer'),
- inventoryitem_count=get_subquery(InventoryItem, 'manufacturer'),
- platform_count=get_subquery(Platform, 'manufacturer')
- )
- table = tables.ManufacturerTable
- class ManufacturerEditView(ObjectEditView):
- queryset = Manufacturer.objects.all()
- model_form = forms.ManufacturerForm
- class ManufacturerDeleteView(ObjectDeleteView):
- queryset = Manufacturer.objects.all()
- class ManufacturerBulkImportView(BulkImportView):
- queryset = Manufacturer.objects.all()
- model_form = forms.ManufacturerCSVForm
- table = tables.ManufacturerTable
- class ManufacturerBulkDeleteView(BulkDeleteView):
- queryset = Manufacturer.objects.annotate(
- devicetype_count=Count('device_types')
- ).order_by(*Manufacturer._meta.ordering)
- table = tables.ManufacturerTable
- #
- # Device types
- #
- class DeviceTypeListView(ObjectListView):
- queryset = DeviceType.objects.prefetch_related('manufacturer').annotate(
- instance_count=Count('instances')
- ).order_by(*DeviceType._meta.ordering)
- filterset = filters.DeviceTypeFilterSet
- filterset_form = forms.DeviceTypeFilterForm
- table = tables.DeviceTypeTable
- class DeviceTypeView(ObjectView):
- queryset = DeviceType.objects.prefetch_related('manufacturer')
- def get(self, request, pk):
- devicetype = get_object_or_404(self.queryset, pk=pk)
- instance_count = Device.objects.restrict(request.user).filter(device_type=devicetype).count()
- # Component tables
- consoleport_table = tables.ConsolePortTemplateTable(
- ConsolePortTemplate.objects.restrict(request.user, 'view').filter(device_type=devicetype),
- orderable=False
- )
- consoleserverport_table = tables.ConsoleServerPortTemplateTable(
- ConsoleServerPortTemplate.objects.restrict(request.user, 'view').filter(device_type=devicetype),
- orderable=False
- )
- powerport_table = tables.PowerPortTemplateTable(
- PowerPortTemplate.objects.restrict(request.user, 'view').filter(device_type=devicetype),
- orderable=False
- )
- poweroutlet_table = tables.PowerOutletTemplateTable(
- PowerOutletTemplate.objects.restrict(request.user, 'view').filter(device_type=devicetype),
- orderable=False
- )
- interface_table = tables.InterfaceTemplateTable(
- list(InterfaceTemplate.objects.restrict(request.user, 'view').filter(device_type=devicetype)),
- orderable=False
- )
- front_port_table = tables.FrontPortTemplateTable(
- FrontPortTemplate.objects.restrict(request.user, 'view').filter(device_type=devicetype),
- orderable=False
- )
- rear_port_table = tables.RearPortTemplateTable(
- RearPortTemplate.objects.restrict(request.user, 'view').filter(device_type=devicetype),
- orderable=False
- )
- devicebay_table = tables.DeviceBayTemplateTable(
- DeviceBayTemplate.objects.restrict(request.user, 'view').filter(device_type=devicetype),
- orderable=False
- )
- if request.user.has_perm('dcim.change_devicetype'):
- consoleport_table.columns.show('pk')
- consoleserverport_table.columns.show('pk')
- powerport_table.columns.show('pk')
- poweroutlet_table.columns.show('pk')
- interface_table.columns.show('pk')
- front_port_table.columns.show('pk')
- rear_port_table.columns.show('pk')
- devicebay_table.columns.show('pk')
- return render(request, 'dcim/devicetype.html', {
- 'devicetype': devicetype,
- 'instance_count': instance_count,
- 'consoleport_table': consoleport_table,
- 'consoleserverport_table': consoleserverport_table,
- 'powerport_table': powerport_table,
- 'poweroutlet_table': poweroutlet_table,
- 'interface_table': interface_table,
- 'front_port_table': front_port_table,
- 'rear_port_table': rear_port_table,
- 'devicebay_table': devicebay_table,
- })
- class DeviceTypeEditView(ObjectEditView):
- queryset = DeviceType.objects.all()
- model_form = forms.DeviceTypeForm
- template_name = 'dcim/devicetype_edit.html'
- class DeviceTypeDeleteView(ObjectDeleteView):
- queryset = DeviceType.objects.all()
- class DeviceTypeImportView(ObjectImportView):
- additional_permissions = [
- '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_devicebaytemplate',
- ]
- queryset = DeviceType.objects.all()
- model_form = forms.DeviceTypeImportForm
- related_object_forms = OrderedDict((
- ('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),
- ('device-bays', forms.DeviceBayTemplateImportForm),
- ))
- class DeviceTypeBulkEditView(BulkEditView):
- queryset = DeviceType.objects.prefetch_related('manufacturer').annotate(
- instance_count=Count('instances')
- ).order_by(*DeviceType._meta.ordering)
- filterset = filters.DeviceTypeFilterSet
- table = tables.DeviceTypeTable
- form = forms.DeviceTypeBulkEditForm
- class DeviceTypeBulkDeleteView(BulkDeleteView):
- queryset = DeviceType.objects.prefetch_related('manufacturer').annotate(
- instance_count=Count('instances')
- ).order_by(*DeviceType._meta.ordering)
- filterset = filters.DeviceTypeFilterSet
- table = tables.DeviceTypeTable
- #
- # Console port templates
- #
- class ConsolePortTemplateCreateView(ComponentCreateView):
- queryset = ConsolePortTemplate.objects.all()
- form = forms.ConsolePortTemplateCreateForm
- model_form = forms.ConsolePortTemplateForm
- template_name = 'dcim/device_component_add.html'
- class ConsolePortTemplateEditView(ObjectEditView):
- queryset = ConsolePortTemplate.objects.all()
- model_form = forms.ConsolePortTemplateForm
- class ConsolePortTemplateDeleteView(ObjectDeleteView):
- queryset = ConsolePortTemplate.objects.all()
- class ConsolePortTemplateBulkEditView(BulkEditView):
- queryset = ConsolePortTemplate.objects.all()
- table = tables.ConsolePortTemplateTable
- form = forms.ConsolePortTemplateBulkEditForm
- class ConsolePortTemplateBulkRenameView(BulkRenameView):
- queryset = ConsolePortTemplate.objects.all()
- class ConsolePortTemplateBulkDeleteView(BulkDeleteView):
- queryset = ConsolePortTemplate.objects.all()
- table = tables.ConsolePortTemplateTable
- #
- # Console server port templates
- #
- class ConsoleServerPortTemplateCreateView(ComponentCreateView):
- queryset = ConsoleServerPortTemplate.objects.all()
- form = forms.ConsoleServerPortTemplateCreateForm
- model_form = forms.ConsoleServerPortTemplateForm
- template_name = 'dcim/device_component_add.html'
- class ConsoleServerPortTemplateEditView(ObjectEditView):
- queryset = ConsoleServerPortTemplate.objects.all()
- model_form = forms.ConsoleServerPortTemplateForm
- class ConsoleServerPortTemplateDeleteView(ObjectDeleteView):
- queryset = ConsoleServerPortTemplate.objects.all()
- class ConsoleServerPortTemplateBulkEditView(BulkEditView):
- queryset = ConsoleServerPortTemplate.objects.all()
- table = tables.ConsoleServerPortTemplateTable
- form = forms.ConsoleServerPortTemplateBulkEditForm
- class ConsoleServerPortTemplateBulkRenameView(BulkRenameView):
- queryset = ConsoleServerPortTemplate.objects.all()
- class ConsoleServerPortTemplateBulkDeleteView(BulkDeleteView):
- queryset = ConsoleServerPortTemplate.objects.all()
- table = tables.ConsoleServerPortTemplateTable
- #
- # Power port templates
- #
- class PowerPortTemplateCreateView(ComponentCreateView):
- queryset = PowerPortTemplate.objects.all()
- form = forms.PowerPortTemplateCreateForm
- model_form = forms.PowerPortTemplateForm
- template_name = 'dcim/device_component_add.html'
- class PowerPortTemplateEditView(ObjectEditView):
- queryset = PowerPortTemplate.objects.all()
- model_form = forms.PowerPortTemplateForm
- class PowerPortTemplateDeleteView(ObjectDeleteView):
- queryset = PowerPortTemplate.objects.all()
- class PowerPortTemplateBulkEditView(BulkEditView):
- queryset = PowerPortTemplate.objects.all()
- table = tables.PowerPortTemplateTable
- form = forms.PowerPortTemplateBulkEditForm
- class PowerPortTemplateBulkRenameView(BulkRenameView):
- queryset = PowerPortTemplate.objects.all()
- class PowerPortTemplateBulkDeleteView(BulkDeleteView):
- queryset = PowerPortTemplate.objects.all()
- table = tables.PowerPortTemplateTable
- #
- # Power outlet templates
- #
- class PowerOutletTemplateCreateView(ComponentCreateView):
- queryset = PowerOutletTemplate.objects.all()
- form = forms.PowerOutletTemplateCreateForm
- model_form = forms.PowerOutletTemplateForm
- template_name = 'dcim/device_component_add.html'
- class PowerOutletTemplateEditView(ObjectEditView):
- queryset = PowerOutletTemplate.objects.all()
- model_form = forms.PowerOutletTemplateForm
- class PowerOutletTemplateDeleteView(ObjectDeleteView):
- queryset = PowerOutletTemplate.objects.all()
- class PowerOutletTemplateBulkEditView(BulkEditView):
- queryset = PowerOutletTemplate.objects.all()
- table = tables.PowerOutletTemplateTable
- form = forms.PowerOutletTemplateBulkEditForm
- class PowerOutletTemplateBulkRenameView(BulkRenameView):
- queryset = PowerOutletTemplate.objects.all()
- class PowerOutletTemplateBulkDeleteView(BulkDeleteView):
- queryset = PowerOutletTemplate.objects.all()
- table = tables.PowerOutletTemplateTable
- #
- # Interface templates
- #
- class InterfaceTemplateCreateView(ComponentCreateView):
- queryset = InterfaceTemplate.objects.all()
- form = forms.InterfaceTemplateCreateForm
- model_form = forms.InterfaceTemplateForm
- template_name = 'dcim/device_component_add.html'
- class InterfaceTemplateEditView(ObjectEditView):
- queryset = InterfaceTemplate.objects.all()
- model_form = forms.InterfaceTemplateForm
- class InterfaceTemplateDeleteView(ObjectDeleteView):
- queryset = InterfaceTemplate.objects.all()
- class InterfaceTemplateBulkEditView(BulkEditView):
- queryset = InterfaceTemplate.objects.all()
- table = tables.InterfaceTemplateTable
- form = forms.InterfaceTemplateBulkEditForm
- class InterfaceTemplateBulkRenameView(BulkRenameView):
- queryset = InterfaceTemplate.objects.all()
- class InterfaceTemplateBulkDeleteView(BulkDeleteView):
- queryset = InterfaceTemplate.objects.all()
- table = tables.InterfaceTemplateTable
- #
- # Front port templates
- #
- class FrontPortTemplateCreateView(ComponentCreateView):
- queryset = FrontPortTemplate.objects.all()
- form = forms.FrontPortTemplateCreateForm
- model_form = forms.FrontPortTemplateForm
- template_name = 'dcim/device_component_add.html'
- class FrontPortTemplateEditView(ObjectEditView):
- queryset = FrontPortTemplate.objects.all()
- model_form = forms.FrontPortTemplateForm
- class FrontPortTemplateDeleteView(ObjectDeleteView):
- queryset = FrontPortTemplate.objects.all()
- class FrontPortTemplateBulkEditView(BulkEditView):
- queryset = FrontPortTemplate.objects.all()
- table = tables.FrontPortTemplateTable
- form = forms.FrontPortTemplateBulkEditForm
- class FrontPortTemplateBulkRenameView(BulkRenameView):
- queryset = FrontPortTemplate.objects.all()
- class FrontPortTemplateBulkDeleteView(BulkDeleteView):
- queryset = FrontPortTemplate.objects.all()
- table = tables.FrontPortTemplateTable
- #
- # Rear port templates
- #
- class RearPortTemplateCreateView(ComponentCreateView):
- queryset = RearPortTemplate.objects.all()
- form = forms.RearPortTemplateCreateForm
- model_form = forms.RearPortTemplateForm
- template_name = 'dcim/device_component_add.html'
- class RearPortTemplateEditView(ObjectEditView):
- queryset = RearPortTemplate.objects.all()
- model_form = forms.RearPortTemplateForm
- class RearPortTemplateDeleteView(ObjectDeleteView):
- queryset = RearPortTemplate.objects.all()
- class RearPortTemplateBulkEditView(BulkEditView):
- queryset = RearPortTemplate.objects.all()
- table = tables.RearPortTemplateTable
- form = forms.RearPortTemplateBulkEditForm
- class RearPortTemplateBulkRenameView(BulkRenameView):
- queryset = RearPortTemplate.objects.all()
- class RearPortTemplateBulkDeleteView(BulkDeleteView):
- queryset = RearPortTemplate.objects.all()
- table = tables.RearPortTemplateTable
- #
- # Device bay templates
- #
- class DeviceBayTemplateCreateView(ComponentCreateView):
- queryset = DeviceBayTemplate.objects.all()
- form = forms.DeviceBayTemplateCreateForm
- model_form = forms.DeviceBayTemplateForm
- template_name = 'dcim/device_component_add.html'
- class DeviceBayTemplateEditView(ObjectEditView):
- queryset = DeviceBayTemplate.objects.all()
- model_form = forms.DeviceBayTemplateForm
- class DeviceBayTemplateDeleteView(ObjectDeleteView):
- queryset = DeviceBayTemplate.objects.all()
- class DeviceBayTemplateBulkEditView(BulkEditView):
- queryset = DeviceBayTemplate.objects.all()
- table = tables.DeviceBayTemplateTable
- form = forms.DeviceBayTemplateBulkEditForm
- class DeviceBayTemplateBulkRenameView(BulkRenameView):
- queryset = DeviceBayTemplate.objects.all()
- class DeviceBayTemplateBulkDeleteView(BulkDeleteView):
- queryset = DeviceBayTemplate.objects.all()
- table = tables.DeviceBayTemplateTable
- #
- # Device roles
- #
- class DeviceRoleListView(ObjectListView):
- queryset = DeviceRole.objects.annotate(
- device_count=get_subquery(Device, 'device_role'),
- vm_count=get_subquery(VirtualMachine, 'role')
- )
- table = tables.DeviceRoleTable
- class DeviceRoleEditView(ObjectEditView):
- queryset = DeviceRole.objects.all()
- model_form = forms.DeviceRoleForm
- class DeviceRoleDeleteView(ObjectDeleteView):
- queryset = DeviceRole.objects.all()
- class DeviceRoleBulkImportView(BulkImportView):
- queryset = DeviceRole.objects.all()
- model_form = forms.DeviceRoleCSVForm
- table = tables.DeviceRoleTable
- class DeviceRoleBulkDeleteView(BulkDeleteView):
- queryset = DeviceRole.objects.all()
- table = tables.DeviceRoleTable
- #
- # Platforms
- #
- class PlatformListView(ObjectListView):
- queryset = Platform.objects.annotate(
- device_count=get_subquery(Device, 'device_role'),
- vm_count=get_subquery(VirtualMachine, 'role')
- )
- table = tables.PlatformTable
- class PlatformEditView(ObjectEditView):
- queryset = Platform.objects.all()
- model_form = forms.PlatformForm
- class PlatformDeleteView(ObjectDeleteView):
- queryset = Platform.objects.all()
- class PlatformBulkImportView(BulkImportView):
- queryset = Platform.objects.all()
- model_form = forms.PlatformCSVForm
- table = tables.PlatformTable
- class PlatformBulkDeleteView(BulkDeleteView):
- queryset = Platform.objects.all()
- table = tables.PlatformTable
- #
- # Devices
- #
- class DeviceListView(ObjectListView):
- queryset = Device.objects.prefetch_related(
- 'device_type__manufacturer', 'device_role', 'tenant', 'site', 'rack', 'primary_ip4', 'primary_ip6'
- )
- filterset = filters.DeviceFilterSet
- filterset_form = forms.DeviceFilterForm
- table = tables.DeviceTable
- template_name = 'dcim/device_list.html'
- class DeviceView(ObjectView):
- queryset = Device.objects.prefetch_related(
- 'site__region', 'rack__group', 'tenant__group', 'device_role', 'platform', 'primary_ip4', 'primary_ip6'
- )
- def get(self, request, pk):
- device = get_object_or_404(self.queryset, pk=pk)
- # VirtualChassis members
- if device.virtual_chassis is not None:
- vc_members = Device.objects.restrict(request.user, 'view').filter(
- virtual_chassis=device.virtual_chassis
- ).order_by('vc_position')
- else:
- vc_members = []
- # Console ports
- consoleports = ConsolePort.objects.restrict(request.user, 'view').filter(device=device).prefetch_related(
- 'connected_endpoint__device', 'cable',
- )
- # Console server ports
- consoleserverports = ConsoleServerPort.objects.restrict(request.user, 'view').filter(
- device=device
- ).prefetch_related(
- 'connected_endpoint__device', 'cable',
- )
- # Power ports
- powerports = PowerPort.objects.restrict(request.user, 'view').filter(device=device).prefetch_related(
- '_connected_poweroutlet__device', 'cable',
- )
- # Power outlets
- poweroutlets = PowerOutlet.objects.restrict(request.user, 'view').filter(device=device).prefetch_related(
- 'connected_endpoint__device', 'cable', 'power_port',
- )
- # Interfaces
- interfaces = device.vc_interfaces.restrict(request.user, 'view').filter(device=device).prefetch_related(
- Prefetch('ip_addresses', queryset=IPAddress.objects.restrict(request.user)),
- Prefetch('member_interfaces', queryset=Interface.objects.restrict(request.user)),
- 'lag', '_connected_interface__device', '_connected_circuittermination__circuit', 'cable',
- 'cable__termination_a', 'cable__termination_b', 'tags'
- )
- # Front ports
- frontports = FrontPort.objects.restrict(request.user, 'view').filter(device=device).prefetch_related(
- 'rear_port', 'cable',
- )
- # Rear ports
- rearports = RearPort.objects.restrict(request.user, 'view').filter(device=device).prefetch_related('cable')
- # Device bays
- devicebays = DeviceBay.objects.restrict(request.user, 'view').filter(device=device).prefetch_related(
- 'installed_device__device_type__manufacturer',
- )
- # Services
- services = Service.objects.restrict(request.user, 'view').filter(device=device)
- # Secrets
- secrets = Secret.objects.restrict(request.user, 'view').filter(device=device)
- # Find up to ten devices in the same site with the same functional role for quick reference.
- related_devices = Device.objects.restrict(request.user, 'view').filter(
- site=device.site, device_role=device.device_role
- ).exclude(
- pk=device.pk
- ).prefetch_related(
- 'rack', 'device_type__manufacturer'
- )[:10]
- return render(request, 'dcim/device.html', {
- 'device': device,
- 'consoleports': consoleports,
- 'consoleserverports': consoleserverports,
- 'powerports': powerports,
- 'poweroutlets': poweroutlets,
- 'interfaces': interfaces,
- 'devicebays': devicebays,
- 'frontports': frontports,
- 'rearports': rearports,
- 'services': services,
- 'secrets': secrets,
- 'vc_members': vc_members,
- 'related_devices': related_devices,
- 'show_graphs': Graph.objects.filter(type__model='device').exists(),
- 'show_interface_graphs': Graph.objects.filter(type__model='interface').exists(),
- })
- class DeviceInventoryView(ObjectView):
- queryset = Device.objects.all()
- def get(self, request, pk):
- device = get_object_or_404(self.queryset, pk=pk)
- inventory_items = InventoryItem.objects.restrict(request.user, 'view').filter(
- device=device, parent=None
- ).prefetch_related(
- 'manufacturer', 'child_items'
- )
- return render(request, 'dcim/device_inventory.html', {
- 'device': device,
- 'inventory_items': inventory_items,
- 'active_tab': 'inventory',
- })
- class DeviceStatusView(ObjectView):
- additional_permissions = ['dcim.napalm_read_device']
- queryset = Device.objects.all()
- def get(self, request, pk):
- device = get_object_or_404(self.queryset, pk=pk)
- return render(request, 'dcim/device_status.html', {
- 'device': device,
- 'active_tab': 'status',
- })
- class DeviceLLDPNeighborsView(ObjectView):
- additional_permissions = ['dcim.napalm_read_device']
- queryset = Device.objects.all()
- def get(self, request, pk):
- device = get_object_or_404(self.queryset, pk=pk)
- interfaces = device.vc_interfaces.restrict(request.user, 'view').exclude(
- type__in=NONCONNECTABLE_IFACE_TYPES
- ).prefetch_related(
- '_connected_interface__device'
- )
- return render(request, 'dcim/device_lldp_neighbors.html', {
- 'device': device,
- 'interfaces': interfaces,
- 'active_tab': 'lldp-neighbors',
- })
- class DeviceConfigView(ObjectView):
- additional_permissions = ['dcim.napalm_read_device']
- queryset = Device.objects.all()
- def get(self, request, pk):
- device = get_object_or_404(self.queryset, pk=pk)
- return render(request, 'dcim/device_config.html', {
- 'device': device,
- 'active_tab': 'config',
- })
- class DeviceConfigContextView(ObjectConfigContextView):
- queryset = Device.objects.all()
- base_template = 'dcim/device.html'
- class DeviceEditView(ObjectEditView):
- queryset = Device.objects.all()
- model_form = forms.DeviceForm
- template_name = 'dcim/device_edit.html'
- class DeviceDeleteView(ObjectDeleteView):
- queryset = Device.objects.all()
- class DeviceBulkImportView(BulkImportView):
- queryset = Device.objects.all()
- model_form = forms.DeviceCSVForm
- table = tables.DeviceImportTable
- template_name = 'dcim/device_import.html'
- class ChildDeviceBulkImportView(BulkImportView):
- queryset = Device.objects.all()
- model_form = forms.ChildDeviceCSVForm
- table = tables.DeviceImportTable
- template_name = 'dcim/device_import_child.html'
- def _save_obj(self, obj_form, request):
- obj = obj_form.save()
- # Save the reverse relation to the parent device bay
- device_bay = obj.parent_bay
- device_bay.installed_device = obj
- device_bay.save()
- return obj
- class DeviceBulkEditView(BulkEditView):
- queryset = Device.objects.prefetch_related('tenant', 'site', 'rack', 'device_role', 'device_type__manufacturer')
- filterset = filters.DeviceFilterSet
- table = tables.DeviceTable
- form = forms.DeviceBulkEditForm
- class DeviceBulkDeleteView(BulkDeleteView):
- queryset = Device.objects.prefetch_related('tenant', 'site', 'rack', 'device_role', 'device_type__manufacturer')
- filterset = filters.DeviceFilterSet
- table = tables.DeviceTable
- #
- # Console ports
- #
- class ConsolePortListView(ObjectListView):
- queryset = ConsolePort.objects.prefetch_related('device', 'cable')
- filterset = filters.ConsolePortFilterSet
- filterset_form = forms.ConsolePortFilterForm
- table = tables.ConsolePortTable
- action_buttons = ('import', 'export')
- class ConsolePortView(ObjectView):
- queryset = ConsolePort.objects.all()
- class ConsolePortCreateView(ComponentCreateView):
- queryset = ConsolePort.objects.all()
- form = forms.ConsolePortCreateForm
- model_form = forms.ConsolePortForm
- template_name = 'dcim/device_component_add.html'
- class ConsolePortEditView(ObjectEditView):
- queryset = ConsolePort.objects.all()
- model_form = forms.ConsolePortForm
- class ConsolePortDeleteView(ObjectDeleteView):
- queryset = ConsolePort.objects.all()
- class ConsolePortBulkImportView(BulkImportView):
- queryset = ConsolePort.objects.all()
- model_form = forms.ConsolePortCSVForm
- table = tables.ConsolePortTable
- class ConsolePortBulkEditView(BulkEditView):
- queryset = ConsolePort.objects.all()
- filterset = filters.ConsolePortFilterSet
- table = tables.ConsolePortTable
- form = forms.ConsolePortBulkEditForm
- class ConsolePortBulkRenameView(BulkRenameView):
- queryset = ConsolePort.objects.all()
- class ConsolePortBulkDisconnectView(BulkDisconnectView):
- queryset = ConsolePort.objects.all()
- class ConsolePortBulkDeleteView(BulkDeleteView):
- queryset = ConsolePort.objects.all()
- filterset = filters.ConsolePortFilterSet
- table = tables.ConsolePortTable
- #
- # Console server ports
- #
- class ConsoleServerPortListView(ObjectListView):
- queryset = ConsoleServerPort.objects.prefetch_related('device', 'cable')
- filterset = filters.ConsoleServerPortFilterSet
- filterset_form = forms.ConsoleServerPortFilterForm
- table = tables.ConsoleServerPortTable
- action_buttons = ('import', 'export')
- class ConsoleServerPortView(ObjectView):
- queryset = ConsoleServerPort.objects.all()
- class ConsoleServerPortCreateView(ComponentCreateView):
- queryset = ConsoleServerPort.objects.all()
- form = forms.ConsoleServerPortCreateForm
- model_form = forms.ConsoleServerPortForm
- template_name = 'dcim/device_component_add.html'
- class ConsoleServerPortEditView(ObjectEditView):
- queryset = ConsoleServerPort.objects.all()
- model_form = forms.ConsoleServerPortForm
- class ConsoleServerPortDeleteView(ObjectDeleteView):
- queryset = ConsoleServerPort.objects.all()
- class ConsoleServerPortBulkImportView(BulkImportView):
- queryset = ConsoleServerPort.objects.all()
- model_form = forms.ConsoleServerPortCSVForm
- table = tables.ConsoleServerPortTable
- class ConsoleServerPortBulkEditView(BulkEditView):
- queryset = ConsoleServerPort.objects.all()
- filterset = filters.ConsoleServerPortFilterSet
- table = tables.ConsoleServerPortTable
- form = forms.ConsoleServerPortBulkEditForm
- class ConsoleServerPortBulkRenameView(BulkRenameView):
- queryset = ConsoleServerPort.objects.all()
- class ConsoleServerPortBulkDisconnectView(BulkDisconnectView):
- queryset = ConsoleServerPort.objects.all()
- class ConsoleServerPortBulkDeleteView(BulkDeleteView):
- queryset = ConsoleServerPort.objects.all()
- filterset = filters.ConsoleServerPortFilterSet
- table = tables.ConsoleServerPortTable
- #
- # Power ports
- #
- class PowerPortListView(ObjectListView):
- queryset = PowerPort.objects.prefetch_related('device', 'cable')
- filterset = filters.PowerPortFilterSet
- filterset_form = forms.PowerPortFilterForm
- table = tables.PowerPortTable
- action_buttons = ('import', 'export')
- class PowerPortView(ObjectView):
- queryset = PowerPort.objects.all()
- class PowerPortCreateView(ComponentCreateView):
- queryset = PowerPort.objects.all()
- form = forms.PowerPortCreateForm
- model_form = forms.PowerPortForm
- template_name = 'dcim/device_component_add.html'
- class PowerPortEditView(ObjectEditView):
- queryset = PowerPort.objects.all()
- model_form = forms.PowerPortForm
- class PowerPortDeleteView(ObjectDeleteView):
- queryset = PowerPort.objects.all()
- class PowerPortBulkImportView(BulkImportView):
- queryset = PowerPort.objects.all()
- model_form = forms.PowerPortCSVForm
- table = tables.PowerPortTable
- class PowerPortBulkEditView(BulkEditView):
- queryset = PowerPort.objects.all()
- filterset = filters.PowerPortFilterSet
- table = tables.PowerPortTable
- form = forms.PowerPortBulkEditForm
- class PowerPortBulkRenameView(BulkRenameView):
- queryset = PowerPort.objects.all()
- class PowerPortBulkDisconnectView(BulkDisconnectView):
- queryset = PowerPort.objects.all()
- class PowerPortBulkDeleteView(BulkDeleteView):
- queryset = PowerPort.objects.all()
- filterset = filters.PowerPortFilterSet
- table = tables.PowerPortTable
- #
- # Power outlets
- #
- class PowerOutletListView(ObjectListView):
- queryset = PowerOutlet.objects.prefetch_related('device', 'cable')
- filterset = filters.PowerOutletFilterSet
- filterset_form = forms.PowerOutletFilterForm
- table = tables.PowerOutletTable
- action_buttons = ('import', 'export')
- class PowerOutletView(ObjectView):
- queryset = PowerOutlet.objects.all()
- class PowerOutletCreateView(ComponentCreateView):
- queryset = PowerOutlet.objects.all()
- form = forms.PowerOutletCreateForm
- model_form = forms.PowerOutletForm
- template_name = 'dcim/device_component_add.html'
- class PowerOutletEditView(ObjectEditView):
- queryset = PowerOutlet.objects.all()
- model_form = forms.PowerOutletForm
- class PowerOutletDeleteView(ObjectDeleteView):
- queryset = PowerOutlet.objects.all()
- class PowerOutletBulkImportView(BulkImportView):
- queryset = PowerOutlet.objects.all()
- model_form = forms.PowerOutletCSVForm
- table = tables.PowerOutletTable
- class PowerOutletBulkEditView(BulkEditView):
- queryset = PowerOutlet.objects.all()
- filterset = filters.PowerOutletFilterSet
- table = tables.PowerOutletTable
- form = forms.PowerOutletBulkEditForm
- class PowerOutletBulkRenameView(BulkRenameView):
- queryset = PowerOutlet.objects.all()
- class PowerOutletBulkDisconnectView(BulkDisconnectView):
- queryset = PowerOutlet.objects.all()
- class PowerOutletBulkDeleteView(BulkDeleteView):
- queryset = PowerOutlet.objects.all()
- filterset = filters.PowerOutletFilterSet
- table = tables.PowerOutletTable
- #
- # Interfaces
- #
- class InterfaceListView(ObjectListView):
- queryset = Interface.objects.prefetch_related('device', 'cable')
- filterset = filters.InterfaceFilterSet
- filterset_form = forms.InterfaceFilterForm
- table = tables.InterfaceTable
- action_buttons = ('import', 'export')
- class InterfaceView(ObjectView):
- queryset = Interface.objects.all()
- def get(self, request, pk):
- interface = get_object_or_404(self.queryset, pk=pk)
- # Get assigned IP addresses
- ipaddress_table = InterfaceIPAddressTable(
- data=interface.ip_addresses.restrict(request.user, 'view').prefetch_related('vrf', 'tenant'),
- orderable=False
- )
- # Get assigned VLANs and annotate whether each is tagged or untagged
- vlans = []
- if interface.untagged_vlan is not None:
- vlans.append(interface.untagged_vlan)
- vlans[0].tagged = False
- for vlan in interface.tagged_vlans.restrict(request.user).prefetch_related('site', 'group', 'tenant', 'role'):
- vlan.tagged = True
- vlans.append(vlan)
- vlan_table = InterfaceVLANTable(
- interface=interface,
- data=vlans,
- orderable=False
- )
- return render(request, 'dcim/interface.html', {
- 'instance': interface,
- 'connected_interface': interface._connected_interface,
- 'connected_circuittermination': interface._connected_circuittermination,
- 'ipaddress_table': ipaddress_table,
- 'vlan_table': vlan_table,
- })
- class InterfaceCreateView(ComponentCreateView):
- queryset = Interface.objects.all()
- form = forms.InterfaceCreateForm
- model_form = forms.InterfaceForm
- template_name = 'dcim/device_component_add.html'
- class InterfaceEditView(ObjectEditView):
- queryset = Interface.objects.all()
- model_form = forms.InterfaceForm
- template_name = 'dcim/interface_edit.html'
- class InterfaceDeleteView(ObjectDeleteView):
- queryset = Interface.objects.all()
- class InterfaceBulkImportView(BulkImportView):
- queryset = Interface.objects.all()
- model_form = forms.InterfaceCSVForm
- table = tables.InterfaceTable
- class InterfaceBulkEditView(BulkEditView):
- queryset = Interface.objects.all()
- filterset = filters.InterfaceFilterSet
- table = tables.InterfaceTable
- form = forms.InterfaceBulkEditForm
- class InterfaceBulkRenameView(BulkRenameView):
- queryset = Interface.objects.all()
- class InterfaceBulkDisconnectView(BulkDisconnectView):
- queryset = Interface.objects.all()
- class InterfaceBulkDeleteView(BulkDeleteView):
- queryset = Interface.objects.all()
- filterset = filters.InterfaceFilterSet
- table = tables.InterfaceTable
- #
- # Front ports
- #
- class FrontPortListView(ObjectListView):
- queryset = FrontPort.objects.prefetch_related('device', 'cable')
- filterset = filters.FrontPortFilterSet
- filterset_form = forms.FrontPortFilterForm
- table = tables.FrontPortTable
- action_buttons = ('import', 'export')
- class FrontPortView(ObjectView):
- queryset = FrontPort.objects.all()
- class FrontPortCreateView(ComponentCreateView):
- queryset = FrontPort.objects.all()
- form = forms.FrontPortCreateForm
- model_form = forms.FrontPortForm
- template_name = 'dcim/device_component_add.html'
- class FrontPortEditView(ObjectEditView):
- queryset = FrontPort.objects.all()
- model_form = forms.FrontPortForm
- class FrontPortDeleteView(ObjectDeleteView):
- queryset = FrontPort.objects.all()
- class FrontPortBulkImportView(BulkImportView):
- queryset = FrontPort.objects.all()
- model_form = forms.FrontPortCSVForm
- table = tables.FrontPortTable
- class FrontPortBulkEditView(BulkEditView):
- queryset = FrontPort.objects.all()
- filterset = filters.FrontPortFilterSet
- table = tables.FrontPortTable
- form = forms.FrontPortBulkEditForm
- class FrontPortBulkRenameView(BulkRenameView):
- queryset = FrontPort.objects.all()
- class FrontPortBulkDisconnectView(BulkDisconnectView):
- queryset = FrontPort.objects.all()
- class FrontPortBulkDeleteView(BulkDeleteView):
- queryset = FrontPort.objects.all()
- filterset = filters.FrontPortFilterSet
- table = tables.FrontPortTable
- #
- # Rear ports
- #
- class RearPortListView(ObjectListView):
- queryset = RearPort.objects.prefetch_related('device', 'cable')
- filterset = filters.RearPortFilterSet
- filterset_form = forms.RearPortFilterForm
- table = tables.RearPortTable
- action_buttons = ('import', 'export')
- class RearPortView(ObjectView):
- queryset = RearPort.objects.all()
- class RearPortCreateView(ComponentCreateView):
- queryset = RearPort.objects.all()
- form = forms.RearPortCreateForm
- model_form = forms.RearPortForm
- template_name = 'dcim/device_component_add.html'
- class RearPortEditView(ObjectEditView):
- queryset = RearPort.objects.all()
- model_form = forms.RearPortForm
- class RearPortDeleteView(ObjectDeleteView):
- queryset = RearPort.objects.all()
- class RearPortBulkImportView(BulkImportView):
- queryset = RearPort.objects.all()
- model_form = forms.RearPortCSVForm
- table = tables.RearPortTable
- class RearPortBulkEditView(BulkEditView):
- queryset = RearPort.objects.all()
- filterset = filters.RearPortFilterSet
- table = tables.RearPortTable
- form = forms.RearPortBulkEditForm
- class RearPortBulkRenameView(BulkRenameView):
- queryset = RearPort.objects.all()
- class RearPortBulkDisconnectView(BulkDisconnectView):
- queryset = RearPort.objects.all()
- class RearPortBulkDeleteView(BulkDeleteView):
- queryset = RearPort.objects.all()
- filterset = filters.RearPortFilterSet
- table = tables.RearPortTable
- #
- # Device bays
- #
- class DeviceBayListView(ObjectListView):
- queryset = DeviceBay.objects.prefetch_related('device', 'installed_device')
- filterset = filters.DeviceBayFilterSet
- filterset_form = forms.DeviceBayFilterForm
- table = tables.DeviceBayTable
- action_buttons = ('import', 'export')
- class DeviceBayView(ObjectView):
- queryset = DeviceBay.objects.all()
- class DeviceBayCreateView(ComponentCreateView):
- queryset = DeviceBay.objects.all()
- form = forms.DeviceBayCreateForm
- model_form = forms.DeviceBayForm
- template_name = 'dcim/device_component_add.html'
- class DeviceBayEditView(ObjectEditView):
- queryset = DeviceBay.objects.all()
- model_form = forms.DeviceBayForm
- class DeviceBayDeleteView(ObjectDeleteView):
- queryset = DeviceBay.objects.all()
- class DeviceBayPopulateView(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': reverse('dcim:device', kwargs={'pk': device_bay.device.pk}),
- })
- 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.installed_device = form.cleaned_data['installed_device']
- device_bay.save()
- messages.success(request, "Added {} to {}.".format(device_bay.installed_device, device_bay))
- return redirect('dcim:device', pk=device_bay.device.pk)
- return render(request, 'dcim/devicebay_populate.html', {
- 'device_bay': device_bay,
- 'form': form,
- 'return_url': reverse('dcim:device', kwargs={'pk': device_bay.device.pk}),
- })
- class DeviceBayDepopulateView(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': reverse('dcim:device', kwargs={'pk': device_bay.device.pk}),
- })
- def post(self, request, pk):
- device_bay = get_object_or_404(self.queryset, pk=pk)
- form = ConfirmationForm(request.POST)
- if form.is_valid():
- removed_device = device_bay.installed_device
- device_bay.installed_device = None
- device_bay.save()
- messages.success(request, "{} has been removed from {}.".format(removed_device, device_bay))
- return redirect('dcim:device', pk=device_bay.device.pk)
- return render(request, 'dcim/devicebay_depopulate.html', {
- 'device_bay': device_bay,
- 'form': form,
- 'return_url': reverse('dcim:device', kwargs={'pk': device_bay.device.pk}),
- })
- class DeviceBayBulkImportView(BulkImportView):
- queryset = DeviceBay.objects.all()
- model_form = forms.DeviceBayCSVForm
- table = tables.DeviceBayTable
- class DeviceBayBulkEditView(BulkEditView):
- queryset = DeviceBay.objects.all()
- filterset = filters.DeviceBayFilterSet
- table = tables.DeviceBayTable
- form = forms.DeviceBayBulkEditForm
- class DeviceBayBulkRenameView(BulkRenameView):
- queryset = DeviceBay.objects.all()
- class DeviceBayBulkDeleteView(BulkDeleteView):
- queryset = DeviceBay.objects.all()
- filterset = filters.DeviceBayFilterSet
- table = tables.DeviceBayTable
- #
- # Inventory items
- #
- class InventoryItemListView(ObjectListView):
- queryset = InventoryItem.objects.prefetch_related('device', 'manufacturer')
- filterset = filters.InventoryItemFilterSet
- filterset_form = forms.InventoryItemFilterForm
- table = tables.InventoryItemTable
- action_buttons = ('import', 'export')
- class InventoryItemView(ObjectView):
- queryset = InventoryItem.objects.all()
- class InventoryItemEditView(ObjectEditView):
- queryset = InventoryItem.objects.all()
- model_form = forms.InventoryItemForm
- class InventoryItemCreateView(ComponentCreateView):
- queryset = InventoryItem.objects.all()
- form = forms.InventoryItemCreateForm
- model_form = forms.InventoryItemForm
- template_name = 'dcim/device_component_add.html'
- class InventoryItemDeleteView(ObjectDeleteView):
- queryset = InventoryItem.objects.all()
- class InventoryItemBulkImportView(BulkImportView):
- queryset = InventoryItem.objects.all()
- model_form = forms.InventoryItemCSVForm
- table = tables.InventoryItemTable
- class InventoryItemBulkEditView(BulkEditView):
- queryset = InventoryItem.objects.prefetch_related('device', 'manufacturer')
- filterset = filters.InventoryItemFilterSet
- table = tables.InventoryItemTable
- form = forms.InventoryItemBulkEditForm
- class InventoryItemBulkRenameView(BulkRenameView):
- queryset = InventoryItem.objects.all()
- class InventoryItemBulkDeleteView(BulkDeleteView):
- queryset = InventoryItem.objects.prefetch_related('device', 'manufacturer')
- table = tables.InventoryItemTable
- template_name = 'dcim/inventoryitem_bulk_delete.html'
- #
- # Bulk Device component creation
- #
- class DeviceBulkAddConsolePortView(BulkComponentCreateView):
- parent_model = Device
- parent_field = 'device'
- form = forms.ConsolePortBulkCreateForm
- queryset = ConsolePort.objects.all()
- model_form = forms.ConsolePortForm
- filterset = filters.DeviceFilterSet
- table = tables.DeviceTable
- default_return_url = 'dcim:device_list'
- class DeviceBulkAddConsoleServerPortView(BulkComponentCreateView):
- parent_model = Device
- parent_field = 'device'
- form = forms.ConsoleServerPortBulkCreateForm
- queryset = ConsoleServerPort.objects.all()
- model_form = forms.ConsoleServerPortForm
- filterset = filters.DeviceFilterSet
- table = tables.DeviceTable
- default_return_url = 'dcim:device_list'
- class DeviceBulkAddPowerPortView(BulkComponentCreateView):
- parent_model = Device
- parent_field = 'device'
- form = forms.PowerPortBulkCreateForm
- queryset = PowerPort.objects.all()
- model_form = forms.PowerPortForm
- filterset = filters.DeviceFilterSet
- table = tables.DeviceTable
- default_return_url = 'dcim:device_list'
- class DeviceBulkAddPowerOutletView(BulkComponentCreateView):
- parent_model = Device
- parent_field = 'device'
- form = forms.PowerOutletBulkCreateForm
- queryset = PowerOutlet.objects.all()
- model_form = forms.PowerOutletForm
- filterset = filters.DeviceFilterSet
- table = tables.DeviceTable
- default_return_url = 'dcim:device_list'
- class DeviceBulkAddInterfaceView(BulkComponentCreateView):
- parent_model = Device
- parent_field = 'device'
- form = forms.InterfaceBulkCreateForm
- queryset = Interface.objects.all()
- model_form = forms.InterfaceForm
- filterset = filters.DeviceFilterSet
- table = tables.DeviceTable
- default_return_url = 'dcim:device_list'
- # class DeviceBulkAddFrontPortView(BulkComponentCreateView):
- # parent_model = Device
- # parent_field = 'device'
- # form = forms.FrontPortBulkCreateForm
- # queryset = FrontPort.objects.all()
- # model_form = forms.FrontPortForm
- # filterset = filters.DeviceFilterSet
- # table = tables.DeviceTable
- # default_return_url = 'dcim:device_list'
- class DeviceBulkAddRearPortView(BulkComponentCreateView):
- parent_model = Device
- parent_field = 'device'
- form = forms.RearPortBulkCreateForm
- queryset = RearPort.objects.all()
- model_form = forms.RearPortForm
- filterset = filters.DeviceFilterSet
- table = tables.DeviceTable
- default_return_url = 'dcim:device_list'
- class DeviceBulkAddDeviceBayView(BulkComponentCreateView):
- parent_model = Device
- parent_field = 'device'
- form = forms.DeviceBayBulkCreateForm
- queryset = DeviceBay.objects.all()
- model_form = forms.DeviceBayForm
- filterset = filters.DeviceFilterSet
- table = tables.DeviceTable
- default_return_url = 'dcim:device_list'
- class DeviceBulkAddInventoryItemView(BulkComponentCreateView):
- parent_model = Device
- parent_field = 'device'
- form = forms.InventoryItemBulkCreateForm
- queryset = InventoryItem.objects.all()
- model_form = forms.InventoryItemForm
- filterset = filters.DeviceFilterSet
- table = tables.DeviceTable
- default_return_url = 'dcim:device_list'
- #
- # Cables
- #
- class CableListView(ObjectListView):
- queryset = Cable.objects.prefetch_related(
- 'termination_a', 'termination_b'
- )
- filterset = filters.CableFilterSet
- filterset_form = forms.CableFilterForm
- table = tables.CableTable
- action_buttons = ('import', 'export')
- class CableView(ObjectView):
- queryset = Cable.objects.all()
- def get(self, request, pk):
- cable = get_object_or_404(self.queryset, pk=pk)
- return render(request, 'dcim/cable.html', {
- 'cable': cable,
- })
- class CableTraceView(ObjectView):
- """
- Trace a cable path beginning from the given termination.
- """
- additional_permissions = ['dcim.view_cable']
- def dispatch(self, request, *args, **kwargs):
- model = kwargs.pop('model')
- self.queryset = model.objects.all()
- return super().dispatch(request, *args, **kwargs)
- def get(self, request, pk):
- obj = get_object_or_404(self.queryset, pk=pk)
- path, split_ends, position_stack = obj.trace()
- total_length = sum(
- [entry[1]._abs_length for entry in path if entry[1] and entry[1]._abs_length]
- )
- return render(request, 'dcim/cable_trace.html', {
- 'obj': obj,
- 'trace': path,
- 'split_ends': split_ends,
- 'position_stack': position_stack,
- 'total_length': total_length,
- })
- class CableCreateView(ObjectEditView):
- queryset = Cable.objects.all()
- template_name = 'dcim/cable_connect.html'
- def dispatch(self, request, *args, **kwargs):
- # Set the model_form class based on the type of component being connected
- self.model_form = {
- 'console-port': forms.ConnectCableToConsolePortForm,
- 'console-server-port': forms.ConnectCableToConsoleServerPortForm,
- 'power-port': forms.ConnectCableToPowerPortForm,
- 'power-outlet': forms.ConnectCableToPowerOutletForm,
- 'interface': forms.ConnectCableToInterfaceForm,
- 'front-port': forms.ConnectCableToFrontPortForm,
- 'rear-port': forms.ConnectCableToRearPortForm,
- 'power-feed': forms.ConnectCableToPowerFeedForm,
- 'circuit-termination': forms.ConnectCableToCircuitTerminationForm,
- }[kwargs.get('termination_b_type')]
- return super().dispatch(request, *args, **kwargs)
- def alter_obj(self, obj, request, url_args, url_kwargs):
- termination_a_type = url_kwargs.get('termination_a_type')
- termination_a_id = url_kwargs.get('termination_a_id')
- termination_b_type_name = url_kwargs.get('termination_b_type')
- self.termination_b_type = ContentType.objects.get(model=termination_b_type_name.replace('-', ''))
- # Initialize Cable termination attributes
- obj.termination_a = termination_a_type.objects.get(pk=termination_a_id)
- obj.termination_b_type = self.termination_b_type
- return obj
- def get(self, request, *args, **kwargs):
- obj = self.alter_obj(self.get_object(kwargs), request, args, kwargs)
- # Parse initial data manually to avoid setting field values as lists
- initial_data = {k: request.GET[k] for k in request.GET}
- # Set initial site and rack based on side A termination (if not already set)
- if 'termination_b_site' not in initial_data:
- initial_data['termination_b_site'] = getattr(obj.termination_a.parent, 'site', None)
- if 'termination_b_rack' not in initial_data:
- initial_data['termination_b_rack'] = getattr(obj.termination_a.parent, 'rack', None)
- form = self.model_form(instance=obj, initial=initial_data)
- return render(request, self.template_name, {
- 'obj': obj,
- 'obj_type': Cable._meta.verbose_name,
- 'termination_b_type': self.termination_b_type.name,
- 'form': form,
- 'return_url': self.get_return_url(request, obj),
- })
- class CableEditView(ObjectEditView):
- queryset = Cable.objects.all()
- model_form = forms.CableForm
- template_name = 'dcim/cable_edit.html'
- class CableDeleteView(ObjectDeleteView):
- queryset = Cable.objects.all()
- class CableBulkImportView(BulkImportView):
- queryset = Cable.objects.all()
- model_form = forms.CableCSVForm
- table = tables.CableTable
- class CableBulkEditView(BulkEditView):
- queryset = Cable.objects.prefetch_related('termination_a', 'termination_b')
- filterset = filters.CableFilterSet
- table = tables.CableTable
- form = forms.CableBulkEditForm
- class CableBulkDeleteView(BulkDeleteView):
- queryset = Cable.objects.prefetch_related('termination_a', 'termination_b')
- filterset = filters.CableFilterSet
- table = tables.CableTable
- #
- # Connections
- #
- class ConsoleConnectionsListView(ObjectListView):
- queryset = ConsolePort.objects.prefetch_related(
- 'device', 'connected_endpoint__device'
- ).filter(
- connected_endpoint__isnull=False
- ).order_by(
- 'cable', 'connected_endpoint__device__name', 'connected_endpoint__name'
- )
- filterset = filters.ConsoleConnectionFilterSet
- filterset_form = forms.ConsoleConnectionFilterForm
- table = tables.ConsoleConnectionTable
- template_name = 'dcim/console_connections_list.html'
- def queryset_to_csv(self):
- csv_data = [
- # Headers
- ','.join(['console_server', 'port', 'device', 'console_port', 'connection_status'])
- ]
- for obj in self.queryset:
- csv = csv_format([
- obj.connected_endpoint.device.identifier if obj.connected_endpoint else None,
- obj.connected_endpoint.name if obj.connected_endpoint else None,
- obj.device.identifier,
- obj.name,
- obj.get_connection_status_display(),
- ])
- csv_data.append(csv)
- return '\n'.join(csv_data)
- class PowerConnectionsListView(ObjectListView):
- queryset = PowerPort.objects.prefetch_related(
- 'device', '_connected_poweroutlet__device'
- ).filter(
- _connected_poweroutlet__isnull=False
- ).order_by(
- 'cable', '_connected_poweroutlet__device__name', '_connected_poweroutlet__name'
- )
- filterset = filters.PowerConnectionFilterSet
- filterset_form = forms.PowerConnectionFilterForm
- table = tables.PowerConnectionTable
- template_name = 'dcim/power_connections_list.html'
- def queryset_to_csv(self):
- csv_data = [
- # Headers
- ','.join(['pdu', 'outlet', 'device', 'power_port', 'connection_status'])
- ]
- for obj in self.queryset:
- csv = csv_format([
- obj.connected_endpoint.device.identifier if obj.connected_endpoint else None,
- obj.connected_endpoint.name if obj.connected_endpoint else None,
- obj.device.identifier,
- obj.name,
- obj.get_connection_status_display(),
- ])
- csv_data.append(csv)
- return '\n'.join(csv_data)
- class InterfaceConnectionsListView(ObjectListView):
- queryset = Interface.objects.prefetch_related(
- 'device', 'cable', '_connected_interface__device'
- ).filter(
- # Avoid duplicate connections by only selecting the lower PK in a connected pair
- _connected_interface__isnull=False,
- pk__lt=F('_connected_interface')
- ).order_by(
- 'device'
- )
- filterset = filters.InterfaceConnectionFilterSet
- filterset_form = forms.InterfaceConnectionFilterForm
- table = tables.InterfaceConnectionTable
- template_name = 'dcim/interface_connections_list.html'
- def queryset_to_csv(self):
- csv_data = [
- # Headers
- ','.join([
- 'device_a', 'interface_a', 'device_b', 'interface_b', 'connection_status'
- ])
- ]
- for obj in self.queryset:
- csv = csv_format([
- obj.connected_endpoint.device.identifier if obj.connected_endpoint else None,
- obj.connected_endpoint.name if obj.connected_endpoint else None,
- obj.device.identifier,
- obj.name,
- obj.get_connection_status_display(),
- ])
- csv_data.append(csv)
- return '\n'.join(csv_data)
- #
- # Virtual chassis
- #
- class VirtualChassisListView(ObjectListView):
- queryset = VirtualChassis.objects.prefetch_related('master').annotate(
- member_count=Count('members')
- ).order_by(*VirtualChassis._meta.ordering)
- table = tables.VirtualChassisTable
- filterset = filters.VirtualChassisFilterSet
- filterset_form = forms.VirtualChassisFilterForm
- class VirtualChassisView(ObjectView):
- queryset = VirtualChassis.objects.all()
- def get(self, request, pk):
- virtualchassis = get_object_or_404(self.queryset, pk=pk)
- members = Device.objects.restrict(request.user).filter(virtual_chassis=virtualchassis)
- return render(request, 'dcim/virtualchassis.html', {
- 'virtualchassis': virtualchassis,
- 'members': members,
- })
- class VirtualChassisCreateView(ObjectEditView):
- queryset = VirtualChassis.objects.all()
- model_form = forms.VirtualChassisCreateForm
- template_name = 'dcim/virtualchassis_add.html'
- 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)
- 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)
- 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)
- 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)
- vc_form.fields['master'].queryset = members_queryset
- formset = VCMemberFormSet(request.POST, queryset=members_queryset)
- if vc_form.is_valid() and formset.is_valid():
- 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)
- devices = Device.objects.filter(pk__in=[m.pk for m in members])
- for device in devices:
- device.vc_position = None
- device.save()
- for member in members:
- member.save()
- return redirect(virtual_chassis.get_absolute_url())
- return render(request, 'dcim/virtualchassis_edit.html', {
- 'vc_form': vc_form,
- 'formset': formset,
- 'return_url': self.get_return_url(request, virtual_chassis),
- })
- class VirtualChassisDeleteView(ObjectDeleteView):
- queryset = VirtualChassis.objects.all()
- class VirtualChassisAddMemberView(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)
- 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)
- 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)
- if membership_form.is_valid():
- membership_form.save()
- msg = 'Added member <a href="{}">{}</a>'.format(device.get_absolute_url(), escape(device))
- 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)
- 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:
- msg = 'Unable to remove master device {} from the virtual chassis.'.format(escape(device))
- messages.error(request, mark_safe(msg))
- return redirect(device.get_absolute_url())
- if form.is_valid():
- 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),
- })
- class VirtualChassisBulkImportView(BulkImportView):
- queryset = VirtualChassis.objects.all()
- model_form = forms.VirtualChassisCSVForm
- table = tables.VirtualChassisTable
- class VirtualChassisBulkEditView(BulkEditView):
- queryset = VirtualChassis.objects.all()
- filterset = filters.VirtualChassisFilterSet
- table = tables.VirtualChassisTable
- form = forms.VirtualChassisBulkEditForm
- class VirtualChassisBulkDeleteView(BulkDeleteView):
- queryset = VirtualChassis.objects.all()
- filterset = filters.VirtualChassisFilterSet
- table = tables.VirtualChassisTable
- #
- # Power panels
- #
- class PowerPanelListView(ObjectListView):
- queryset = PowerPanel.objects.prefetch_related(
- 'site', 'rack_group'
- ).annotate(
- powerfeed_count=Count('powerfeeds')
- ).order_by(*PowerPanel._meta.ordering)
- filterset = filters.PowerPanelFilterSet
- filterset_form = forms.PowerPanelFilterForm
- table = tables.PowerPanelTable
- class PowerPanelView(ObjectView):
- queryset = PowerPanel.objects.prefetch_related('site', 'rack_group')
- def get(self, request, pk):
- powerpanel = get_object_or_404(self.queryset, pk=pk)
- power_feeds = PowerFeed.objects.restrict(request.user).filter(power_panel=powerpanel).prefetch_related('rack')
- powerfeed_table = tables.PowerFeedTable(
- data=power_feeds,
- orderable=False
- )
- powerfeed_table.exclude = ['power_panel']
- return render(request, 'dcim/powerpanel.html', {
- 'powerpanel': powerpanel,
- 'powerfeed_table': powerfeed_table,
- })
- class PowerPanelEditView(ObjectEditView):
- queryset = PowerPanel.objects.all()
- model_form = forms.PowerPanelForm
- class PowerPanelDeleteView(ObjectDeleteView):
- queryset = PowerPanel.objects.all()
- class PowerPanelBulkImportView(BulkImportView):
- queryset = PowerPanel.objects.all()
- model_form = forms.PowerPanelCSVForm
- table = tables.PowerPanelTable
- class PowerPanelBulkEditView(BulkEditView):
- queryset = PowerPanel.objects.prefetch_related('site', 'rack_group')
- filterset = filters.PowerPanelFilterSet
- table = tables.PowerPanelTable
- form = forms.PowerPanelBulkEditForm
- class PowerPanelBulkDeleteView(BulkDeleteView):
- queryset = PowerPanel.objects.prefetch_related(
- 'site', 'rack_group'
- ).annotate(
- rack_count=Count('powerfeeds')
- ).order_by(*PowerPanel._meta.ordering)
- filterset = filters.PowerPanelFilterSet
- table = tables.PowerPanelTable
- #
- # Power feeds
- #
- class PowerFeedListView(ObjectListView):
- queryset = PowerFeed.objects.prefetch_related(
- 'power_panel', 'rack'
- )
- filterset = filters.PowerFeedFilterSet
- filterset_form = forms.PowerFeedFilterForm
- table = tables.PowerFeedTable
- class PowerFeedView(ObjectView):
- queryset = PowerFeed.objects.prefetch_related('power_panel', 'rack')
- def get(self, request, pk):
- powerfeed = get_object_or_404(self.queryset, pk=pk)
- return render(request, 'dcim/powerfeed.html', {
- 'powerfeed': powerfeed,
- })
- class PowerFeedEditView(ObjectEditView):
- queryset = PowerFeed.objects.all()
- model_form = forms.PowerFeedForm
- template_name = 'dcim/powerfeed_edit.html'
- class PowerFeedDeleteView(ObjectDeleteView):
- queryset = PowerFeed.objects.all()
- class PowerFeedBulkImportView(BulkImportView):
- queryset = PowerFeed.objects.all()
- model_form = forms.PowerFeedCSVForm
- table = tables.PowerFeedTable
- class PowerFeedBulkEditView(BulkEditView):
- queryset = PowerFeed.objects.prefetch_related('power_panel', 'rack')
- filterset = filters.PowerFeedFilterSet
- table = tables.PowerFeedTable
- form = forms.PowerFeedBulkEditForm
- class PowerFeedBulkDeleteView(BulkDeleteView):
- queryset = PowerFeed.objects.prefetch_related('power_panel', 'rack')
- filterset = filters.PowerFeedFilterSet
- table = tables.PowerFeedTable
|