| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675 |
- from collections import OrderedDict
- import re
- from django.conf import settings
- from django.contrib import messages
- from django.contrib.auth.mixins import PermissionRequiredMixin
- 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
- from django.forms import 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.http import is_safe_url
- 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 Prefix, VLAN
- from ipam.tables import InterfaceIPAddressTable, InterfaceVLANTable
- from utilities.forms import ConfirmationForm
- from utilities.paginator import EnhancedPaginator
- from utilities.utils import csv_format
- from utilities.views import (
- BulkComponentCreateView, BulkDeleteView, BulkEditView, BulkImportView, ComponentCreateView, GetReturnURLMixin,
- ObjectImportView, ObjectDeleteView, ObjectEditView, ObjectListView,
- )
- 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 BulkRenameView(GetReturnURLMixin, View):
- """
- An extendable view for renaming device components in bulk.
- """
- queryset = None
- form = None
- template_name = 'dcim/bulk_rename.html'
- def post(self, request):
- model = self.queryset.model
- if '_preview' in request.POST or '_apply' in request.POST:
- form = self.form(request.POST, initial={'pk': request.POST.getlist('pk')})
- selected_objects = self.queryset.filter(pk__in=form.initial['pk'])
- if form.is_valid():
- for obj in selected_objects:
- find = form.cleaned_data['find']
- replace = form.cleaned_data['replace']
- if form.cleaned_data['use_regex']:
- try:
- obj.new_name = re.sub(find, replace, obj.name)
- # Catch regex group reference errors
- except re.error:
- obj.new_name = obj.name
- else:
- obj.new_name = obj.name.replace(find, replace)
- if '_apply' in request.POST:
- for obj in selected_objects:
- obj.name = obj.new_name
- obj.save()
- messages.success(request, "Renamed {} {}".format(
- len(selected_objects),
- model._meta.verbose_name_plural
- ))
- return redirect(self.get_return_url(request))
- 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': model._meta.verbose_name_plural,
- 'selected_objects': selected_objects,
- 'return_url': self.get_return_url(request),
- })
- class BulkDisconnectView(GetReturnURLMixin, View):
- """
- An extendable view for disconnection console/power/interface components in bulk.
- """
- model = None
- form = None
- template_name = 'dcim/bulk_disconnect.html'
- 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.model.objects.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.model._meta.verbose_name_plural
- ))
- return redirect(return_url)
- else:
- form = self.form(initial={'pk': request.POST.getlist('pk')})
- selected_objects = self.model.objects.filter(pk__in=form.initial['pk'])
- return render(request, self.template_name, {
- 'form': form,
- 'obj_type_plural': self.model._meta.verbose_name_plural,
- 'selected_objects': selected_objects,
- 'return_url': return_url,
- })
- #
- # Regions
- #
- class RegionListView(PermissionRequiredMixin, ObjectListView):
- permission_required = 'dcim.view_region'
- 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 RegionCreateView(PermissionRequiredMixin, ObjectEditView):
- permission_required = 'dcim.add_region'
- model = Region
- model_form = forms.RegionForm
- default_return_url = 'dcim:region_list'
- class RegionEditView(RegionCreateView):
- permission_required = 'dcim.change_region'
- class RegionBulkImportView(PermissionRequiredMixin, BulkImportView):
- permission_required = 'dcim.add_region'
- model_form = forms.RegionCSVForm
- table = tables.RegionTable
- default_return_url = 'dcim:region_list'
- class RegionBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
- permission_required = 'dcim.delete_region'
- queryset = Region.objects.all()
- filterset = filters.RegionFilterSet
- table = tables.RegionTable
- default_return_url = 'dcim:region_list'
- #
- # Sites
- #
- class SiteListView(PermissionRequiredMixin, ObjectListView):
- permission_required = 'dcim.view_site'
- queryset = Site.objects.prefetch_related('region', 'tenant')
- filterset = filters.SiteFilterSet
- filterset_form = forms.SiteFilterForm
- table = tables.SiteTable
- class SiteView(PermissionRequiredMixin, View):
- permission_required = 'dcim.view_site'
- def get(self, request, slug):
- site = get_object_or_404(Site.objects.prefetch_related('region', 'tenant__group'), slug=slug)
- stats = {
- 'rack_count': Rack.objects.filter(site=site).count(),
- 'device_count': Device.objects.filter(site=site).count(),
- 'prefix_count': Prefix.objects.filter(site=site).count(),
- 'vlan_count': VLAN.objects.filter(site=site).count(),
- 'circuit_count': Circuit.objects.filter(terminations__site=site).count(),
- 'vm_count': VirtualMachine.objects.filter(cluster__site=site).count(),
- }
- rack_groups = RackGroup.objects.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 SiteCreateView(PermissionRequiredMixin, ObjectEditView):
- permission_required = 'dcim.add_site'
- model = Site
- model_form = forms.SiteForm
- template_name = 'dcim/site_edit.html'
- default_return_url = 'dcim:site_list'
- class SiteEditView(SiteCreateView):
- permission_required = 'dcim.change_site'
- class SiteDeleteView(PermissionRequiredMixin, ObjectDeleteView):
- permission_required = 'dcim.delete_site'
- model = Site
- default_return_url = 'dcim:site_list'
- class SiteBulkImportView(PermissionRequiredMixin, BulkImportView):
- permission_required = 'dcim.add_site'
- model_form = forms.SiteCSVForm
- table = tables.SiteTable
- default_return_url = 'dcim:site_list'
- class SiteBulkEditView(PermissionRequiredMixin, BulkEditView):
- permission_required = 'dcim.change_site'
- queryset = Site.objects.prefetch_related('region', 'tenant')
- filterset = filters.SiteFilterSet
- table = tables.SiteTable
- form = forms.SiteBulkEditForm
- default_return_url = 'dcim:site_list'
- class SiteBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
- permission_required = 'dcim.delete_site'
- queryset = Site.objects.prefetch_related('region', 'tenant')
- filterset = filters.SiteFilterSet
- table = tables.SiteTable
- default_return_url = 'dcim:site_list'
- #
- # Rack groups
- #
- class RackGroupListView(PermissionRequiredMixin, ObjectListView):
- permission_required = 'dcim.view_rackgroup'
- queryset = RackGroup.objects.prefetch_related('site').annotate(rack_count=Count('racks'))
- filterset = filters.RackGroupFilterSet
- filterset_form = forms.RackGroupFilterForm
- table = tables.RackGroupTable
- class RackGroupCreateView(PermissionRequiredMixin, ObjectEditView):
- permission_required = 'dcim.add_rackgroup'
- model = RackGroup
- model_form = forms.RackGroupForm
- default_return_url = 'dcim:rackgroup_list'
- class RackGroupEditView(RackGroupCreateView):
- permission_required = 'dcim.change_rackgroup'
- class RackGroupBulkImportView(PermissionRequiredMixin, BulkImportView):
- permission_required = 'dcim.add_rackgroup'
- model_form = forms.RackGroupCSVForm
- table = tables.RackGroupTable
- default_return_url = 'dcim:rackgroup_list'
- class RackGroupBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
- permission_required = 'dcim.delete_rackgroup'
- queryset = RackGroup.objects.prefetch_related('site').annotate(rack_count=Count('racks'))
- filterset = filters.RackGroupFilterSet
- table = tables.RackGroupTable
- default_return_url = 'dcim:rackgroup_list'
- #
- # Rack roles
- #
- class RackRoleListView(PermissionRequiredMixin, ObjectListView):
- permission_required = 'dcim.view_rackrole'
- queryset = RackRole.objects.annotate(rack_count=Count('racks'))
- table = tables.RackRoleTable
- class RackRoleCreateView(PermissionRequiredMixin, ObjectEditView):
- permission_required = 'dcim.add_rackrole'
- model = RackRole
- model_form = forms.RackRoleForm
- default_return_url = 'dcim:rackrole_list'
- class RackRoleEditView(RackRoleCreateView):
- permission_required = 'dcim.change_rackrole'
- class RackRoleBulkImportView(PermissionRequiredMixin, BulkImportView):
- permission_required = 'dcim.add_rackrole'
- model_form = forms.RackRoleCSVForm
- table = tables.RackRoleTable
- default_return_url = 'dcim:rackrole_list'
- class RackRoleBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
- permission_required = 'dcim.delete_rackrole'
- queryset = RackRole.objects.annotate(rack_count=Count('racks'))
- table = tables.RackRoleTable
- default_return_url = 'dcim:rackrole_list'
- #
- # Racks
- #
- class RackListView(PermissionRequiredMixin, ObjectListView):
- permission_required = 'dcim.view_rack'
- queryset = Rack.objects.prefetch_related(
- 'site', 'group', 'tenant', 'role', 'devices__device_type'
- ).annotate(
- device_count=Count('devices')
- )
- filterset = filters.RackFilterSet
- filterset_form = forms.RackFilterForm
- table = tables.RackDetailTable
- class RackElevationListView(PermissionRequiredMixin, View):
- """
- Display a set of rack elevations side-by-side.
- """
- permission_required = 'dcim.view_rack'
- def get(self, request):
- racks = Rack.objects.prefetch_related('role')
- racks = filters.RackFilterSet(request.GET, racks).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(PermissionRequiredMixin, View):
- permission_required = 'dcim.view_rack'
- def get(self, request, pk):
- rack = get_object_or_404(Rack.objects.prefetch_related('site__region', 'tenant__group', 'group', 'role'), pk=pk)
- nonracked_devices = Device.objects.filter(
- rack=rack,
- position__isnull=True,
- parent_bay__isnull=True
- ).prefetch_related('device_type__manufacturer')
- if rack.group:
- peer_racks = Rack.objects.filter(site=rack.site, group=rack.group)
- else:
- peer_racks = Rack.objects.filter(site=rack.site, 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.filter(rack=rack)
- power_feeds = PowerFeed.objects.filter(rack=rack).prefetch_related('power_panel')
- return render(request, 'dcim/rack.html', {
- 'rack': rack,
- 'reservations': reservations,
- 'power_feeds': power_feeds,
- 'nonracked_devices': nonracked_devices,
- 'next_rack': next_rack,
- 'prev_rack': prev_rack,
- })
- class RackCreateView(PermissionRequiredMixin, ObjectEditView):
- permission_required = 'dcim.add_rack'
- model = Rack
- model_form = forms.RackForm
- template_name = 'dcim/rack_edit.html'
- default_return_url = 'dcim:rack_list'
- class RackEditView(RackCreateView):
- permission_required = 'dcim.change_rack'
- class RackDeleteView(PermissionRequiredMixin, ObjectDeleteView):
- permission_required = 'dcim.delete_rack'
- model = Rack
- default_return_url = 'dcim:rack_list'
- class RackBulkImportView(PermissionRequiredMixin, BulkImportView):
- permission_required = 'dcim.add_rack'
- model_form = forms.RackCSVForm
- table = tables.RackTable
- default_return_url = 'dcim:rack_list'
- class RackBulkEditView(PermissionRequiredMixin, BulkEditView):
- permission_required = 'dcim.change_rack'
- queryset = Rack.objects.prefetch_related('site', 'group', 'tenant', 'role')
- filterset = filters.RackFilterSet
- table = tables.RackTable
- form = forms.RackBulkEditForm
- default_return_url = 'dcim:rack_list'
- class RackBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
- permission_required = 'dcim.delete_rack'
- queryset = Rack.objects.prefetch_related('site', 'group', 'tenant', 'role')
- filterset = filters.RackFilterSet
- table = tables.RackTable
- default_return_url = 'dcim:rack_list'
- #
- # Rack reservations
- #
- class RackReservationListView(PermissionRequiredMixin, ObjectListView):
- permission_required = 'dcim.view_rackreservation'
- queryset = RackReservation.objects.prefetch_related('rack__site')
- filterset = filters.RackReservationFilterSet
- filterset_form = forms.RackReservationFilterForm
- table = tables.RackReservationTable
- action_buttons = ('export',)
- class RackReservationCreateView(PermissionRequiredMixin, ObjectEditView):
- permission_required = 'dcim.add_rackreservation'
- model = RackReservation
- model_form = forms.RackReservationForm
- def alter_obj(self, obj, request, args, kwargs):
- if not obj.pk:
- obj.rack = get_object_or_404(Rack, pk=kwargs['rack'])
- obj.user = request.user
- return obj
- def get_return_url(self, request, obj):
- return obj.rack.get_absolute_url()
- class RackReservationEditView(RackReservationCreateView):
- permission_required = 'dcim.change_rackreservation'
- class RackReservationDeleteView(PermissionRequiredMixin, ObjectDeleteView):
- permission_required = 'dcim.delete_rackreservation'
- model = RackReservation
- def get_return_url(self, request, obj):
- return obj.rack.get_absolute_url()
- class RackReservationImportView(PermissionRequiredMixin, BulkImportView):
- permission_required = 'dcim.add_rackreservation'
- model_form = forms.RackReservationCSVForm
- table = tables.RackReservationTable
- default_return_url = 'dcim:rackreservation_list'
- 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(PermissionRequiredMixin, BulkEditView):
- permission_required = 'dcim.change_rackreservation'
- queryset = RackReservation.objects.prefetch_related('rack', 'user')
- filterset = filters.RackReservationFilterSet
- table = tables.RackReservationTable
- form = forms.RackReservationBulkEditForm
- default_return_url = 'dcim:rackreservation_list'
- class RackReservationBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
- permission_required = 'dcim.delete_rackreservation'
- queryset = RackReservation.objects.prefetch_related('rack', 'user')
- filterset = filters.RackReservationFilterSet
- table = tables.RackReservationTable
- default_return_url = 'dcim:rackreservation_list'
- #
- # Manufacturers
- #
- class ManufacturerListView(PermissionRequiredMixin, ObjectListView):
- permission_required = 'dcim.view_manufacturer'
- queryset = Manufacturer.objects.annotate(
- devicetype_count=Count('device_types', distinct=True),
- inventoryitem_count=Count('inventory_items', distinct=True),
- platform_count=Count('platforms', distinct=True),
- )
- table = tables.ManufacturerTable
- class ManufacturerCreateView(PermissionRequiredMixin, ObjectEditView):
- permission_required = 'dcim.add_manufacturer'
- model = Manufacturer
- model_form = forms.ManufacturerForm
- default_return_url = 'dcim:manufacturer_list'
- class ManufacturerEditView(ManufacturerCreateView):
- permission_required = 'dcim.change_manufacturer'
- class ManufacturerBulkImportView(PermissionRequiredMixin, BulkImportView):
- permission_required = 'dcim.add_manufacturer'
- model_form = forms.ManufacturerCSVForm
- table = tables.ManufacturerTable
- default_return_url = 'dcim:manufacturer_list'
- class ManufacturerBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
- permission_required = 'dcim.delete_manufacturer'
- queryset = Manufacturer.objects.annotate(devicetype_count=Count('device_types'))
- table = tables.ManufacturerTable
- default_return_url = 'dcim:manufacturer_list'
- #
- # Device types
- #
- class DeviceTypeListView(PermissionRequiredMixin, ObjectListView):
- permission_required = 'dcim.view_devicetype'
- queryset = DeviceType.objects.prefetch_related('manufacturer').annotate(instance_count=Count('instances'))
- filterset = filters.DeviceTypeFilterSet
- filterset_form = forms.DeviceTypeFilterForm
- table = tables.DeviceTypeTable
- class DeviceTypeView(PermissionRequiredMixin, View):
- permission_required = 'dcim.view_devicetype'
- def get(self, request, pk):
- devicetype = get_object_or_404(DeviceType, pk=pk)
- # Component tables
- consoleport_table = tables.ConsolePortTemplateTable(
- ConsolePortTemplate.objects.filter(device_type=devicetype),
- orderable=False
- )
- consoleserverport_table = tables.ConsoleServerPortTemplateTable(
- ConsoleServerPortTemplate.objects.filter(device_type=devicetype),
- orderable=False
- )
- powerport_table = tables.PowerPortTemplateTable(
- PowerPortTemplate.objects.filter(device_type=devicetype),
- orderable=False
- )
- poweroutlet_table = tables.PowerOutletTemplateTable(
- PowerOutletTemplate.objects.filter(device_type=devicetype),
- orderable=False
- )
- interface_table = tables.InterfaceTemplateTable(
- list(InterfaceTemplate.objects.filter(device_type=devicetype)),
- orderable=False
- )
- front_port_table = tables.FrontPortTemplateTable(
- FrontPortTemplate.objects.filter(device_type=devicetype),
- orderable=False
- )
- rear_port_table = tables.RearPortTemplateTable(
- RearPortTemplate.objects.filter(device_type=devicetype),
- orderable=False
- )
- devicebay_table = tables.DeviceBayTemplateTable(
- DeviceBayTemplate.objects.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,
- '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 DeviceTypeCreateView(PermissionRequiredMixin, ObjectEditView):
- permission_required = 'dcim.add_devicetype'
- model = DeviceType
- model_form = forms.DeviceTypeForm
- template_name = 'dcim/devicetype_edit.html'
- default_return_url = 'dcim:devicetype_list'
- class DeviceTypeEditView(DeviceTypeCreateView):
- permission_required = 'dcim.change_devicetype'
- class DeviceTypeDeleteView(PermissionRequiredMixin, ObjectDeleteView):
- permission_required = 'dcim.delete_devicetype'
- model = DeviceType
- default_return_url = 'dcim:devicetype_list'
- class DeviceTypeImportView(PermissionRequiredMixin, ObjectImportView):
- permission_required = [
- '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',
- ]
- model = DeviceType
- 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),
- ))
- default_return_url = 'dcim:devicetype_import'
- class DeviceTypeBulkEditView(PermissionRequiredMixin, BulkEditView):
- permission_required = 'dcim.change_devicetype'
- queryset = DeviceType.objects.prefetch_related('manufacturer').annotate(instance_count=Count('instances'))
- filterset = filters.DeviceTypeFilterSet
- table = tables.DeviceTypeTable
- form = forms.DeviceTypeBulkEditForm
- default_return_url = 'dcim:devicetype_list'
- class DeviceTypeBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
- permission_required = 'dcim.delete_devicetype'
- queryset = DeviceType.objects.prefetch_related('manufacturer').annotate(instance_count=Count('instances'))
- filterset = filters.DeviceTypeFilterSet
- table = tables.DeviceTypeTable
- default_return_url = 'dcim:devicetype_list'
- #
- # Console port templates
- #
- class ConsolePortTemplateCreateView(PermissionRequiredMixin, ComponentCreateView):
- permission_required = 'dcim.add_consoleporttemplate'
- model = ConsolePortTemplate
- form = forms.ConsolePortTemplateCreateForm
- model_form = forms.ConsolePortTemplateForm
- template_name = 'dcim/device_component_add.html'
- class ConsolePortTemplateEditView(PermissionRequiredMixin, ObjectEditView):
- permission_required = 'dcim.change_consoleporttemplate'
- model = ConsolePortTemplate
- model_form = forms.ConsolePortTemplateForm
- class ConsolePortTemplateDeleteView(PermissionRequiredMixin, ObjectDeleteView):
- permission_required = 'dcim.delete_consoleporttemplate'
- model = ConsolePortTemplate
- class ConsolePortTemplateBulkEditView(PermissionRequiredMixin, BulkEditView):
- permission_required = 'dcim.change_consoleporttemplate'
- queryset = ConsolePortTemplate.objects.all()
- table = tables.ConsolePortTemplateTable
- form = forms.ConsolePortTemplateBulkEditForm
- class ConsolePortTemplateBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
- permission_required = 'dcim.delete_consoleporttemplate'
- queryset = ConsolePortTemplate.objects.all()
- table = tables.ConsolePortTemplateTable
- #
- # Console server port templates
- #
- class ConsoleServerPortTemplateCreateView(PermissionRequiredMixin, ComponentCreateView):
- permission_required = 'dcim.add_consoleserverporttemplate'
- model = ConsoleServerPortTemplate
- form = forms.ConsoleServerPortTemplateCreateForm
- model_form = forms.ConsoleServerPortTemplateForm
- template_name = 'dcim/device_component_add.html'
- class ConsoleServerPortTemplateEditView(PermissionRequiredMixin, ObjectEditView):
- permission_required = 'dcim.change_consoleserverporttemplate'
- model = ConsoleServerPortTemplate
- model_form = forms.ConsoleServerPortTemplateForm
- class ConsoleServerPortTemplateDeleteView(PermissionRequiredMixin, ObjectDeleteView):
- permission_required = 'dcim.delete_consoleserverporttemplate'
- model = ConsoleServerPortTemplate
- class ConsoleServerPortTemplateBulkEditView(PermissionRequiredMixin, BulkEditView):
- permission_required = 'dcim.change_consoleserverporttemplate'
- queryset = ConsoleServerPortTemplate.objects.all()
- table = tables.ConsoleServerPortTemplateTable
- form = forms.ConsoleServerPortTemplateBulkEditForm
- class ConsoleServerPortTemplateBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
- permission_required = 'dcim.delete_consoleserverporttemplate'
- queryset = ConsoleServerPortTemplate.objects.all()
- table = tables.ConsoleServerPortTemplateTable
- #
- # Power port templates
- #
- class PowerPortTemplateCreateView(PermissionRequiredMixin, ComponentCreateView):
- permission_required = 'dcim.add_powerporttemplate'
- model = PowerPortTemplate
- form = forms.PowerPortTemplateCreateForm
- model_form = forms.PowerPortTemplateForm
- template_name = 'dcim/device_component_add.html'
- class PowerPortTemplateEditView(PermissionRequiredMixin, ObjectEditView):
- permission_required = 'dcim.change_powerporttemplate'
- model = PowerPortTemplate
- model_form = forms.PowerPortTemplateForm
- class PowerPortTemplateDeleteView(PermissionRequiredMixin, ObjectDeleteView):
- permission_required = 'dcim.delete_powerporttemplate'
- model = PowerPortTemplate
- class PowerPortTemplateBulkEditView(PermissionRequiredMixin, BulkEditView):
- permission_required = 'dcim.change_powerporttemplate'
- queryset = PowerPortTemplate.objects.all()
- table = tables.PowerPortTemplateTable
- form = forms.PowerPortTemplateBulkEditForm
- class PowerPortTemplateBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
- permission_required = 'dcim.delete_powerporttemplate'
- queryset = PowerPortTemplate.objects.all()
- table = tables.PowerPortTemplateTable
- #
- # Power outlet templates
- #
- class PowerOutletTemplateCreateView(PermissionRequiredMixin, ComponentCreateView):
- permission_required = 'dcim.add_poweroutlettemplate'
- model = PowerOutletTemplate
- form = forms.PowerOutletTemplateCreateForm
- model_form = forms.PowerOutletTemplateForm
- template_name = 'dcim/device_component_add.html'
- class PowerOutletTemplateEditView(PermissionRequiredMixin, ObjectEditView):
- permission_required = 'dcim.change_poweroutlettemplate'
- model = PowerOutletTemplate
- model_form = forms.PowerOutletTemplateForm
- class PowerOutletTemplateDeleteView(PermissionRequiredMixin, ObjectDeleteView):
- permission_required = 'dcim.delete_poweroutlettemplate'
- model = PowerOutletTemplate
- class PowerOutletTemplateBulkEditView(PermissionRequiredMixin, BulkEditView):
- permission_required = 'dcim.change_poweroutlettemplate'
- queryset = PowerOutletTemplate.objects.all()
- table = tables.PowerOutletTemplateTable
- form = forms.PowerOutletTemplateBulkEditForm
- class PowerOutletTemplateBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
- permission_required = 'dcim.delete_poweroutlettemplate'
- queryset = PowerOutletTemplate.objects.all()
- table = tables.PowerOutletTemplateTable
- #
- # Interface templates
- #
- class InterfaceTemplateCreateView(PermissionRequiredMixin, ComponentCreateView):
- permission_required = 'dcim.add_interfacetemplate'
- model = InterfaceTemplate
- form = forms.InterfaceTemplateCreateForm
- model_form = forms.InterfaceTemplateForm
- template_name = 'dcim/device_component_add.html'
- class InterfaceTemplateEditView(PermissionRequiredMixin, ObjectEditView):
- permission_required = 'dcim.change_interfacetemplate'
- model = InterfaceTemplate
- model_form = forms.InterfaceTemplateForm
- class InterfaceTemplateDeleteView(PermissionRequiredMixin, ObjectDeleteView):
- permission_required = 'dcim.delete_interfacetemplate'
- model = InterfaceTemplate
- class InterfaceTemplateBulkEditView(PermissionRequiredMixin, BulkEditView):
- permission_required = 'dcim.change_interfacetemplate'
- queryset = InterfaceTemplate.objects.all()
- table = tables.InterfaceTemplateTable
- form = forms.InterfaceTemplateBulkEditForm
- class InterfaceTemplateBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
- permission_required = 'dcim.delete_interfacetemplate'
- queryset = InterfaceTemplate.objects.all()
- table = tables.InterfaceTemplateTable
- #
- # Front port templates
- #
- class FrontPortTemplateCreateView(PermissionRequiredMixin, ComponentCreateView):
- permission_required = 'dcim.add_frontporttemplate'
- model = FrontPortTemplate
- form = forms.FrontPortTemplateCreateForm
- model_form = forms.FrontPortTemplateForm
- template_name = 'dcim/device_component_add.html'
- class FrontPortTemplateEditView(PermissionRequiredMixin, ObjectEditView):
- permission_required = 'dcim.change_frontporttemplate'
- model = FrontPortTemplate
- model_form = forms.FrontPortTemplateForm
- class FrontPortTemplateDeleteView(PermissionRequiredMixin, ObjectDeleteView):
- permission_required = 'dcim.delete_frontporttemplate'
- model = FrontPortTemplate
- class FrontPortTemplateBulkEditView(PermissionRequiredMixin, BulkEditView):
- permission_required = 'dcim.change_frontporttemplate'
- queryset = FrontPortTemplate.objects.all()
- table = tables.FrontPortTemplateTable
- form = forms.FrontPortTemplateBulkEditForm
- class FrontPortTemplateBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
- permission_required = 'dcim.delete_frontporttemplate'
- queryset = FrontPortTemplate.objects.all()
- table = tables.FrontPortTemplateTable
- #
- # Rear port templates
- #
- class RearPortTemplateCreateView(PermissionRequiredMixin, ComponentCreateView):
- permission_required = 'dcim.add_rearporttemplate'
- model = RearPortTemplate
- form = forms.RearPortTemplateCreateForm
- model_form = forms.RearPortTemplateForm
- template_name = 'dcim/device_component_add.html'
- class RearPortTemplateEditView(PermissionRequiredMixin, ObjectEditView):
- permission_required = 'dcim.change_rearporttemplate'
- model = RearPortTemplate
- model_form = forms.RearPortTemplateForm
- class RearPortTemplateDeleteView(PermissionRequiredMixin, ObjectDeleteView):
- permission_required = 'dcim.delete_rearporttemplate'
- model = RearPortTemplate
- class RearPortTemplateBulkEditView(PermissionRequiredMixin, BulkEditView):
- permission_required = 'dcim.change_rearporttemplate'
- queryset = RearPortTemplate.objects.all()
- table = tables.RearPortTemplateTable
- form = forms.RearPortTemplateBulkEditForm
- class RearPortTemplateBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
- permission_required = 'dcim.delete_rearporttemplate'
- queryset = RearPortTemplate.objects.all()
- table = tables.RearPortTemplateTable
- #
- # Device bay templates
- #
- class DeviceBayTemplateCreateView(PermissionRequiredMixin, ComponentCreateView):
- permission_required = 'dcim.add_devicebaytemplate'
- model = DeviceBayTemplate
- form = forms.DeviceBayTemplateCreateForm
- model_form = forms.DeviceBayTemplateForm
- template_name = 'dcim/device_component_add.html'
- class DeviceBayTemplateEditView(PermissionRequiredMixin, ObjectEditView):
- permission_required = 'dcim.change_devicebaytemplate'
- model = DeviceBayTemplate
- model_form = forms.DeviceBayTemplateForm
- class DeviceBayTemplateDeleteView(PermissionRequiredMixin, ObjectDeleteView):
- permission_required = 'dcim.delete_devicebaytemplate'
- model = DeviceBayTemplate
- # class DeviceBayTemplateBulkEditView(PermissionRequiredMixin, BulkEditView):
- # permission_required = 'dcim.change_devicebaytemplate'
- # queryset = DeviceBayTemplate.objects.all()
- # table = tables.DeviceBayTemplateTable
- # form = forms.DeviceBayTemplateBulkEditForm
- class DeviceBayTemplateBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
- permission_required = 'dcim.delete_devicebaytemplate'
- queryset = DeviceBayTemplate.objects.all()
- table = tables.DeviceBayTemplateTable
- #
- # Device roles
- #
- class DeviceRoleListView(PermissionRequiredMixin, ObjectListView):
- permission_required = 'dcim.view_devicerole'
- queryset = DeviceRole.objects.all()
- table = tables.DeviceRoleTable
- class DeviceRoleCreateView(PermissionRequiredMixin, ObjectEditView):
- permission_required = 'dcim.add_devicerole'
- model = DeviceRole
- model_form = forms.DeviceRoleForm
- default_return_url = 'dcim:devicerole_list'
- class DeviceRoleEditView(DeviceRoleCreateView):
- permission_required = 'dcim.change_devicerole'
- class DeviceRoleBulkImportView(PermissionRequiredMixin, BulkImportView):
- permission_required = 'dcim.add_devicerole'
- model_form = forms.DeviceRoleCSVForm
- table = tables.DeviceRoleTable
- default_return_url = 'dcim:devicerole_list'
- class DeviceRoleBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
- permission_required = 'dcim.delete_devicerole'
- queryset = DeviceRole.objects.all()
- table = tables.DeviceRoleTable
- default_return_url = 'dcim:devicerole_list'
- #
- # Platforms
- #
- class PlatformListView(PermissionRequiredMixin, ObjectListView):
- permission_required = 'dcim.view_platform'
- queryset = Platform.objects.all()
- table = tables.PlatformTable
- class PlatformCreateView(PermissionRequiredMixin, ObjectEditView):
- permission_required = 'dcim.add_platform'
- model = Platform
- model_form = forms.PlatformForm
- default_return_url = 'dcim:platform_list'
- class PlatformEditView(PlatformCreateView):
- permission_required = 'dcim.change_platform'
- class PlatformBulkImportView(PermissionRequiredMixin, BulkImportView):
- permission_required = 'dcim.add_platform'
- model_form = forms.PlatformCSVForm
- table = tables.PlatformTable
- default_return_url = 'dcim:platform_list'
- class PlatformBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
- permission_required = 'dcim.delete_platform'
- queryset = Platform.objects.all()
- table = tables.PlatformTable
- default_return_url = 'dcim:platform_list'
- #
- # Devices
- #
- class DeviceListView(PermissionRequiredMixin, ObjectListView):
- permission_required = 'dcim.view_device'
- 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.DeviceDetailTable
- template_name = 'dcim/device_list.html'
- class DeviceView(PermissionRequiredMixin, View):
- permission_required = 'dcim.view_device'
- def get(self, request, pk):
- device = get_object_or_404(Device.objects.prefetch_related(
- 'site__region', 'rack__group', 'tenant__group', 'device_role', 'platform'
- ), pk=pk)
- # VirtualChassis members
- if device.virtual_chassis is not None:
- vc_members = Device.objects.filter(
- virtual_chassis=device.virtual_chassis
- ).order_by('vc_position')
- else:
- vc_members = []
- # Console ports
- console_ports = device.consoleports.prefetch_related('connected_endpoint__device', 'cable')
- # Console server ports
- consoleserverports = device.consoleserverports.prefetch_related('connected_endpoint__device', 'cable')
- # Power ports
- power_ports = device.powerports.prefetch_related('_connected_poweroutlet__device', 'cable')
- # Power outlets
- poweroutlets = device.poweroutlets.prefetch_related('connected_endpoint__device', 'cable', 'power_port')
- # Interfaces
- interfaces = device.vc_interfaces.prefetch_related(
- 'lag', '_connected_interface__device', '_connected_circuittermination__circuit', 'cable',
- 'cable__termination_a', 'cable__termination_b', 'ip_addresses', 'tags'
- )
- # Front ports
- front_ports = device.frontports.prefetch_related('rear_port', 'cable')
- # Rear ports
- rear_ports = device.rearports.prefetch_related('cable')
- # Device bays
- device_bays = device.device_bays.prefetch_related('installed_device__device_type__manufacturer')
- # Services
- services = device.services.all()
- # Secrets
- secrets = device.secrets.all()
- # Find up to ten devices in the same site with the same functional role for quick reference.
- related_devices = Device.objects.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,
- 'console_ports': console_ports,
- 'consoleserverports': consoleserverports,
- 'power_ports': power_ports,
- 'poweroutlets': poweroutlets,
- 'interfaces': interfaces,
- 'device_bays': device_bays,
- 'front_ports': front_ports,
- 'rear_ports': rear_ports,
- '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(PermissionRequiredMixin, View):
- permission_required = 'dcim.view_device'
- def get(self, request, pk):
- device = get_object_or_404(Device, pk=pk)
- inventory_items = InventoryItem.objects.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(PermissionRequiredMixin, View):
- permission_required = ('dcim.view_device', 'dcim.napalm_read')
- def get(self, request, pk):
- device = get_object_or_404(Device, pk=pk)
- return render(request, 'dcim/device_status.html', {
- 'device': device,
- 'active_tab': 'status',
- })
- class DeviceLLDPNeighborsView(PermissionRequiredMixin, View):
- permission_required = ('dcim.view_device', 'dcim.napalm_read')
- def get(self, request, pk):
- device = get_object_or_404(Device, pk=pk)
- interfaces = device.vc_interfaces.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(PermissionRequiredMixin, View):
- permission_required = ('dcim.view_device', 'dcim.napalm_read')
- def get(self, request, pk):
- device = get_object_or_404(Device, pk=pk)
- return render(request, 'dcim/device_config.html', {
- 'device': device,
- 'active_tab': 'config',
- })
- class DeviceConfigContextView(PermissionRequiredMixin, ObjectConfigContextView):
- permission_required = 'dcim.view_device'
- object_class = Device
- base_template = 'dcim/device.html'
- class DeviceCreateView(PermissionRequiredMixin, ObjectEditView):
- permission_required = 'dcim.add_device'
- model = Device
- model_form = forms.DeviceForm
- template_name = 'dcim/device_edit.html'
- default_return_url = 'dcim:device_list'
- class DeviceEditView(DeviceCreateView):
- permission_required = 'dcim.change_device'
- class DeviceDeleteView(PermissionRequiredMixin, ObjectDeleteView):
- permission_required = 'dcim.delete_device'
- model = Device
- default_return_url = 'dcim:device_list'
- class DeviceBulkImportView(PermissionRequiredMixin, BulkImportView):
- permission_required = 'dcim.add_device'
- model_form = forms.DeviceCSVForm
- table = tables.DeviceImportTable
- template_name = 'dcim/device_import.html'
- default_return_url = 'dcim:device_list'
- class ChildDeviceBulkImportView(PermissionRequiredMixin, BulkImportView):
- permission_required = 'dcim.add_device'
- model_form = forms.ChildDeviceCSVForm
- table = tables.DeviceImportTable
- template_name = 'dcim/device_import_child.html'
- default_return_url = 'dcim:device_list'
- 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(PermissionRequiredMixin, BulkEditView):
- permission_required = 'dcim.change_device'
- queryset = Device.objects.prefetch_related('tenant', 'site', 'rack', 'device_role', 'device_type__manufacturer')
- filterset = filters.DeviceFilterSet
- table = tables.DeviceTable
- form = forms.DeviceBulkEditForm
- default_return_url = 'dcim:device_list'
- class DeviceBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
- permission_required = 'dcim.delete_device'
- queryset = Device.objects.prefetch_related('tenant', 'site', 'rack', 'device_role', 'device_type__manufacturer')
- filterset = filters.DeviceFilterSet
- table = tables.DeviceTable
- default_return_url = 'dcim:device_list'
- #
- # Console ports
- #
- class ConsolePortListView(PermissionRequiredMixin, ObjectListView):
- permission_required = 'dcim.view_consoleport'
- queryset = ConsolePort.objects.prefetch_related('device', 'device__tenant', 'device__site', 'cable')
- filterset = filters.ConsolePortFilterSet
- filterset_form = forms.ConsolePortFilterForm
- table = tables.ConsolePortDetailTable
- action_buttons = ('import', 'export')
- class ConsolePortCreateView(PermissionRequiredMixin, ComponentCreateView):
- permission_required = 'dcim.add_consoleport'
- model = ConsolePort
- form = forms.ConsolePortCreateForm
- model_form = forms.ConsolePortForm
- template_name = 'dcim/device_component_add.html'
- class ConsolePortEditView(PermissionRequiredMixin, ObjectEditView):
- permission_required = 'dcim.change_consoleport'
- model = ConsolePort
- model_form = forms.ConsolePortForm
- class ConsolePortDeleteView(PermissionRequiredMixin, ObjectDeleteView):
- permission_required = 'dcim.delete_consoleport'
- model = ConsolePort
- class ConsolePortBulkImportView(PermissionRequiredMixin, BulkImportView):
- permission_required = 'dcim.add_consoleport'
- model_form = forms.ConsolePortCSVForm
- table = tables.ConsolePortImportTable
- default_return_url = 'dcim:consoleport_list'
- class ConsolePortBulkEditView(PermissionRequiredMixin, BulkEditView):
- permission_required = 'dcim.change_consoleport'
- queryset = ConsolePort.objects.all()
- table = tables.ConsolePortTable
- form = forms.ConsolePortBulkEditForm
- class ConsolePortBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
- permission_required = 'dcim.delete_consoleport'
- queryset = ConsolePort.objects.all()
- table = tables.ConsolePortTable
- default_return_url = 'dcim:consoleport_list'
- #
- # Console server ports
- #
- class ConsoleServerPortListView(PermissionRequiredMixin, ObjectListView):
- permission_required = 'dcim.view_consoleserverport'
- queryset = ConsoleServerPort.objects.prefetch_related('device', 'device__tenant', 'device__site', 'cable')
- filterset = filters.ConsoleServerPortFilterSet
- filterset_form = forms.ConsoleServerPortFilterForm
- table = tables.ConsoleServerPortDetailTable
- action_buttons = ('import', 'export')
- class ConsoleServerPortCreateView(PermissionRequiredMixin, ComponentCreateView):
- permission_required = 'dcim.add_consoleserverport'
- model = ConsoleServerPort
- form = forms.ConsoleServerPortCreateForm
- model_form = forms.ConsoleServerPortForm
- template_name = 'dcim/device_component_add.html'
- class ConsoleServerPortEditView(PermissionRequiredMixin, ObjectEditView):
- permission_required = 'dcim.change_consoleserverport'
- model = ConsoleServerPort
- model_form = forms.ConsoleServerPortForm
- class ConsoleServerPortDeleteView(PermissionRequiredMixin, ObjectDeleteView):
- permission_required = 'dcim.delete_consoleserverport'
- model = ConsoleServerPort
- class ConsoleServerPortBulkImportView(PermissionRequiredMixin, BulkImportView):
- permission_required = 'dcim.add_consoleserverport'
- model_form = forms.ConsoleServerPortCSVForm
- table = tables.ConsoleServerPortImportTable
- default_return_url = 'dcim:consoleserverport_list'
- class ConsoleServerPortBulkEditView(PermissionRequiredMixin, BulkEditView):
- permission_required = 'dcim.change_consoleserverport'
- queryset = ConsoleServerPort.objects.all()
- table = tables.ConsoleServerPortTable
- form = forms.ConsoleServerPortBulkEditForm
- class ConsoleServerPortBulkRenameView(PermissionRequiredMixin, BulkRenameView):
- permission_required = 'dcim.change_consoleserverport'
- queryset = ConsoleServerPort.objects.all()
- form = forms.ConsoleServerPortBulkRenameForm
- class ConsoleServerPortBulkDisconnectView(PermissionRequiredMixin, BulkDisconnectView):
- permission_required = 'dcim.change_consoleserverport'
- model = ConsoleServerPort
- form = forms.ConsoleServerPortBulkDisconnectForm
- class ConsoleServerPortBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
- permission_required = 'dcim.delete_consoleserverport'
- queryset = ConsoleServerPort.objects.all()
- table = tables.ConsoleServerPortTable
- default_return_url = 'dcim:consoleserverport_list'
- #
- # Power ports
- #
- class PowerPortListView(PermissionRequiredMixin, ObjectListView):
- permission_required = 'dcim.view_powerport'
- queryset = PowerPort.objects.prefetch_related('device', 'device__tenant', 'device__site', 'cable')
- filterset = filters.PowerPortFilterSet
- filterset_form = forms.PowerPortFilterForm
- table = tables.PowerPortDetailTable
- action_buttons = ('import', 'export')
- class PowerPortCreateView(PermissionRequiredMixin, ComponentCreateView):
- permission_required = 'dcim.add_powerport'
- model = PowerPort
- form = forms.PowerPortCreateForm
- model_form = forms.PowerPortForm
- template_name = 'dcim/device_component_add.html'
- class PowerPortEditView(PermissionRequiredMixin, ObjectEditView):
- permission_required = 'dcim.change_powerport'
- model = PowerPort
- model_form = forms.PowerPortForm
- class PowerPortDeleteView(PermissionRequiredMixin, ObjectDeleteView):
- permission_required = 'dcim.delete_powerport'
- model = PowerPort
- class PowerPortBulkImportView(PermissionRequiredMixin, BulkImportView):
- permission_required = 'dcim.add_powerport'
- model_form = forms.PowerPortCSVForm
- table = tables.PowerPortImportTable
- default_return_url = 'dcim:powerport_list'
- class PowerPortBulkEditView(PermissionRequiredMixin, BulkEditView):
- permission_required = 'dcim.change_powerport'
- queryset = PowerPort.objects.all()
- table = tables.PowerPortTable
- form = forms.PowerPortBulkEditForm
- class PowerPortBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
- permission_required = 'dcim.delete_powerport'
- queryset = PowerPort.objects.all()
- table = tables.PowerPortTable
- default_return_url = 'dcim:powerport_list'
- #
- # Power outlets
- #
- class PowerOutletListView(PermissionRequiredMixin, ObjectListView):
- permission_required = 'dcim.view_poweroutlet'
- queryset = PowerOutlet.objects.prefetch_related('device', 'device__tenant', 'device__site', 'cable')
- filterset = filters.PowerOutletFilterSet
- filterset_form = forms.PowerOutletFilterForm
- table = tables.PowerOutletDetailTable
- action_buttons = ('import', 'export')
- class PowerOutletCreateView(PermissionRequiredMixin, ComponentCreateView):
- permission_required = 'dcim.add_poweroutlet'
- model = PowerOutlet
- form = forms.PowerOutletCreateForm
- model_form = forms.PowerOutletForm
- template_name = 'dcim/device_component_add.html'
- class PowerOutletEditView(PermissionRequiredMixin, ObjectEditView):
- permission_required = 'dcim.change_poweroutlet'
- model = PowerOutlet
- model_form = forms.PowerOutletForm
- class PowerOutletDeleteView(PermissionRequiredMixin, ObjectDeleteView):
- permission_required = 'dcim.delete_poweroutlet'
- model = PowerOutlet
- class PowerOutletBulkImportView(PermissionRequiredMixin, BulkImportView):
- permission_required = 'dcim.add_poweroutlet'
- model_form = forms.PowerOutletCSVForm
- table = tables.PowerOutletImportTable
- default_return_url = 'dcim:poweroutlet_list'
- class PowerOutletBulkEditView(PermissionRequiredMixin, BulkEditView):
- permission_required = 'dcim.change_poweroutlet'
- queryset = PowerOutlet.objects.all()
- table = tables.PowerOutletTable
- form = forms.PowerOutletBulkEditForm
- class PowerOutletBulkRenameView(PermissionRequiredMixin, BulkRenameView):
- permission_required = 'dcim.change_poweroutlet'
- queryset = PowerOutlet.objects.all()
- form = forms.PowerOutletBulkRenameForm
- class PowerOutletBulkDisconnectView(PermissionRequiredMixin, BulkDisconnectView):
- permission_required = 'dcim.change_poweroutlet'
- model = PowerOutlet
- form = forms.PowerOutletBulkDisconnectForm
- class PowerOutletBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
- permission_required = 'dcim.delete_poweroutlet'
- queryset = PowerOutlet.objects.all()
- table = tables.PowerOutletTable
- default_return_url = 'dcim:poweroutlet_list'
- #
- # Interfaces
- #
- class InterfaceListView(PermissionRequiredMixin, ObjectListView):
- permission_required = 'dcim.view_interface'
- queryset = Interface.objects.prefetch_related('device', 'device__tenant', 'device__site', 'cable')
- filterset = filters.InterfaceFilterSet
- filterset_form = forms.InterfaceFilterForm
- table = tables.InterfaceDetailTable
- action_buttons = ('import', 'export')
- class InterfaceView(PermissionRequiredMixin, View):
- permission_required = 'dcim.view_interface'
- def get(self, request, pk):
- interface = get_object_or_404(Interface, pk=pk)
- # Get assigned IP addresses
- ipaddress_table = InterfaceIPAddressTable(
- data=interface.ip_addresses.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.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', {
- 'interface': interface,
- 'connected_interface': interface._connected_interface,
- 'connected_circuittermination': interface._connected_circuittermination,
- 'ipaddress_table': ipaddress_table,
- 'vlan_table': vlan_table,
- })
- class InterfaceCreateView(PermissionRequiredMixin, ComponentCreateView):
- permission_required = 'dcim.add_interface'
- model = Interface
- form = forms.InterfaceCreateForm
- model_form = forms.InterfaceForm
- template_name = 'dcim/device_component_add.html'
- class InterfaceEditView(PermissionRequiredMixin, ObjectEditView):
- permission_required = 'dcim.change_interface'
- model = Interface
- model_form = forms.InterfaceForm
- template_name = 'dcim/interface_edit.html'
- class InterfaceDeleteView(PermissionRequiredMixin, ObjectDeleteView):
- permission_required = 'dcim.delete_interface'
- model = Interface
- class InterfaceBulkImportView(PermissionRequiredMixin, BulkImportView):
- permission_required = 'dcim.add_interface'
- model_form = forms.InterfaceCSVForm
- table = tables.InterfaceImportTable
- default_return_url = 'dcim:interface_list'
- class InterfaceBulkEditView(PermissionRequiredMixin, BulkEditView):
- permission_required = 'dcim.change_interface'
- queryset = Interface.objects.all()
- table = tables.InterfaceTable
- form = forms.InterfaceBulkEditForm
- class InterfaceBulkRenameView(PermissionRequiredMixin, BulkRenameView):
- permission_required = 'dcim.change_interface'
- queryset = Interface.objects.all()
- form = forms.InterfaceBulkRenameForm
- class InterfaceBulkDisconnectView(PermissionRequiredMixin, BulkDisconnectView):
- permission_required = 'dcim.change_interface'
- model = Interface
- form = forms.InterfaceBulkDisconnectForm
- class InterfaceBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
- permission_required = 'dcim.delete_interface'
- queryset = Interface.objects.all()
- table = tables.InterfaceTable
- default_return_url = 'dcim:interface_list'
- #
- # Front ports
- #
- class FrontPortListView(PermissionRequiredMixin, ObjectListView):
- permission_required = 'dcim.view_frontport'
- queryset = FrontPort.objects.prefetch_related('device', 'device__tenant', 'device__site', 'cable')
- filterset = filters.FrontPortFilterSet
- filterset_form = forms.FrontPortFilterForm
- table = tables.FrontPortDetailTable
- action_buttons = ('import', 'export')
- class FrontPortCreateView(PermissionRequiredMixin, ComponentCreateView):
- permission_required = 'dcim.add_frontport'
- model = FrontPort
- form = forms.FrontPortCreateForm
- model_form = forms.FrontPortForm
- template_name = 'dcim/device_component_add.html'
- class FrontPortEditView(PermissionRequiredMixin, ObjectEditView):
- permission_required = 'dcim.change_frontport'
- model = FrontPort
- model_form = forms.FrontPortForm
- class FrontPortDeleteView(PermissionRequiredMixin, ObjectDeleteView):
- permission_required = 'dcim.delete_frontport'
- model = FrontPort
- class FrontPortBulkImportView(PermissionRequiredMixin, BulkImportView):
- permission_required = 'dcim.add_frontport'
- model_form = forms.FrontPortCSVForm
- table = tables.FrontPortImportTable
- default_return_url = 'dcim:frontport_list'
- class FrontPortBulkEditView(PermissionRequiredMixin, BulkEditView):
- permission_required = 'dcim.change_frontport'
- queryset = FrontPort.objects.all()
- table = tables.FrontPortTable
- form = forms.FrontPortBulkEditForm
- class FrontPortBulkRenameView(PermissionRequiredMixin, BulkRenameView):
- permission_required = 'dcim.change_frontport'
- queryset = FrontPort.objects.all()
- form = forms.FrontPortBulkRenameForm
- class FrontPortBulkDisconnectView(PermissionRequiredMixin, BulkDisconnectView):
- permission_required = 'dcim.change_frontport'
- model = FrontPort
- form = forms.FrontPortBulkDisconnectForm
- class FrontPortBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
- permission_required = 'dcim.delete_frontport'
- queryset = FrontPort.objects.all()
- table = tables.FrontPortTable
- default_return_url = 'dcim:frontport_list'
- #
- # Rear ports
- #
- class RearPortListView(PermissionRequiredMixin, ObjectListView):
- permission_required = 'dcim.view_rearport'
- queryset = RearPort.objects.prefetch_related('device', 'device__tenant', 'device__site', 'cable')
- filterset = filters.RearPortFilterSet
- filterset_form = forms.RearPortFilterForm
- table = tables.RearPortDetailTable
- action_buttons = ('import', 'export')
- class RearPortCreateView(PermissionRequiredMixin, ComponentCreateView):
- permission_required = 'dcim.add_rearport'
- model = RearPort
- form = forms.RearPortCreateForm
- model_form = forms.RearPortForm
- template_name = 'dcim/device_component_add.html'
- class RearPortEditView(PermissionRequiredMixin, ObjectEditView):
- permission_required = 'dcim.change_rearport'
- model = RearPort
- model_form = forms.RearPortForm
- class RearPortDeleteView(PermissionRequiredMixin, ObjectDeleteView):
- permission_required = 'dcim.delete_rearport'
- model = RearPort
- class RearPortBulkImportView(PermissionRequiredMixin, BulkImportView):
- permission_required = 'dcim.add_rearport'
- model_form = forms.RearPortCSVForm
- table = tables.RearPortImportTable
- default_return_url = 'dcim:rearport_list'
- class RearPortBulkEditView(PermissionRequiredMixin, BulkEditView):
- permission_required = 'dcim.change_rearport'
- queryset = RearPort.objects.all()
- table = tables.RearPortTable
- form = forms.RearPortBulkEditForm
- class RearPortBulkRenameView(PermissionRequiredMixin, BulkRenameView):
- permission_required = 'dcim.change_rearport'
- queryset = RearPort.objects.all()
- form = forms.RearPortBulkRenameForm
- class RearPortBulkDisconnectView(PermissionRequiredMixin, BulkDisconnectView):
- permission_required = 'dcim.change_rearport'
- model = RearPort
- form = forms.RearPortBulkDisconnectForm
- class RearPortBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
- permission_required = 'dcim.delete_rearport'
- queryset = RearPort.objects.all()
- table = tables.RearPortTable
- default_return_url = 'dcim:rearport_list'
- #
- # Device bays
- #
- class DeviceBayListView(PermissionRequiredMixin, ObjectListView):
- permission_required = 'dcim.view_devicebay'
- queryset = DeviceBay.objects.prefetch_related(
- 'device', 'device__site', 'installed_device', 'installed_device__site'
- )
- filterset = filters.DeviceBayFilterSet
- filterset_form = forms.DeviceBayFilterForm
- table = tables.DeviceBayDetailTable
- action_buttons = ('import', 'export')
- class DeviceBayCreateView(PermissionRequiredMixin, ComponentCreateView):
- permission_required = 'dcim.add_devicebay'
- model = DeviceBay
- form = forms.DeviceBayCreateForm
- model_form = forms.DeviceBayForm
- template_name = 'dcim/device_component_add.html'
- class DeviceBayEditView(PermissionRequiredMixin, ObjectEditView):
- permission_required = 'dcim.change_devicebay'
- model = DeviceBay
- model_form = forms.DeviceBayForm
- class DeviceBayDeleteView(PermissionRequiredMixin, ObjectDeleteView):
- permission_required = 'dcim.delete_devicebay'
- model = DeviceBay
- class DeviceBayPopulateView(PermissionRequiredMixin, View):
- permission_required = 'dcim.change_devicebay'
- def get(self, request, pk):
- device_bay = get_object_or_404(DeviceBay, 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(DeviceBay, 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(PermissionRequiredMixin, View):
- permission_required = 'dcim.change_devicebay'
- def get(self, request, pk):
- device_bay = get_object_or_404(DeviceBay, 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(DeviceBay, 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(PermissionRequiredMixin, BulkImportView):
- permission_required = 'dcim.add_devicebay'
- model_form = forms.DeviceBayCSVForm
- table = tables.DeviceBayImportTable
- default_return_url = 'dcim:devicebay_list'
- class DeviceBayBulkRenameView(PermissionRequiredMixin, BulkRenameView):
- permission_required = 'dcim.change_devicebay'
- queryset = DeviceBay.objects.all()
- form = forms.DeviceBayBulkRenameForm
- class DeviceBayBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
- permission_required = 'dcim.delete_devicebay'
- queryset = DeviceBay.objects.all()
- table = tables.DeviceBayTable
- default_return_url = 'dcim:devicebay_list'
- #
- # Bulk Device component creation
- #
- class DeviceBulkAddConsolePortView(PermissionRequiredMixin, BulkComponentCreateView):
- permission_required = 'dcim.add_consoleport'
- parent_model = Device
- parent_field = 'device'
- form = forms.DeviceBulkAddComponentForm
- model = ConsolePort
- model_form = forms.ConsolePortForm
- filterset = filters.DeviceFilterSet
- table = tables.DeviceTable
- default_return_url = 'dcim:device_list'
- class DeviceBulkAddConsoleServerPortView(PermissionRequiredMixin, BulkComponentCreateView):
- permission_required = 'dcim.add_consoleserverport'
- parent_model = Device
- parent_field = 'device'
- form = forms.DeviceBulkAddComponentForm
- model = ConsoleServerPort
- model_form = forms.ConsoleServerPortForm
- filterset = filters.DeviceFilterSet
- table = tables.DeviceTable
- default_return_url = 'dcim:device_list'
- class DeviceBulkAddPowerPortView(PermissionRequiredMixin, BulkComponentCreateView):
- permission_required = 'dcim.add_powerport'
- parent_model = Device
- parent_field = 'device'
- form = forms.DeviceBulkAddComponentForm
- model = PowerPort
- model_form = forms.PowerPortForm
- filterset = filters.DeviceFilterSet
- table = tables.DeviceTable
- default_return_url = 'dcim:device_list'
- class DeviceBulkAddPowerOutletView(PermissionRequiredMixin, BulkComponentCreateView):
- permission_required = 'dcim.add_poweroutlet'
- parent_model = Device
- parent_field = 'device'
- form = forms.DeviceBulkAddComponentForm
- model = PowerOutlet
- model_form = forms.PowerOutletForm
- filterset = filters.DeviceFilterSet
- table = tables.DeviceTable
- default_return_url = 'dcim:device_list'
- class DeviceBulkAddInterfaceView(PermissionRequiredMixin, BulkComponentCreateView):
- permission_required = 'dcim.add_interface'
- parent_model = Device
- parent_field = 'device'
- form = forms.DeviceBulkAddInterfaceForm
- model = Interface
- model_form = forms.InterfaceForm
- filterset = filters.DeviceFilterSet
- table = tables.DeviceTable
- default_return_url = 'dcim:device_list'
- class DeviceBulkAddDeviceBayView(PermissionRequiredMixin, BulkComponentCreateView):
- permission_required = 'dcim.add_devicebay'
- parent_model = Device
- parent_field = 'device'
- form = forms.DeviceBulkAddComponentForm
- model = DeviceBay
- model_form = forms.DeviceBayForm
- filterset = filters.DeviceFilterSet
- table = tables.DeviceTable
- default_return_url = 'dcim:device_list'
- #
- # Cables
- #
- class CableListView(PermissionRequiredMixin, ObjectListView):
- permission_required = 'dcim.view_cable'
- 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(PermissionRequiredMixin, View):
- permission_required = 'dcim.view_cable'
- def get(self, request, pk):
- cable = get_object_or_404(Cable, pk=pk)
- return render(request, 'dcim/cable.html', {
- 'cable': cable,
- })
- class CableTraceView(PermissionRequiredMixin, View):
- """
- Trace a cable path beginning from the given termination.
- """
- permission_required = 'dcim.view_cable'
- def get(self, request, model, pk):
- obj = get_object_or_404(model, pk=pk)
- trace = obj.trace(follow_circuits=True)
- total_length = sum([entry[1]._abs_length for entry in trace if entry[1] and entry[1]._abs_length])
- return render(request, 'dcim/cable_trace.html', {
- 'obj': obj,
- 'trace': trace,
- 'total_length': total_length,
- })
- class CableCreateView(PermissionRequiredMixin, GetReturnURLMixin, View):
- permission_required = 'dcim.add_cable'
- template_name = 'dcim/cable_connect.html'
- def dispatch(self, request, *args, **kwargs):
- termination_a_type = kwargs.get('termination_a_type')
- termination_a_id = kwargs.get('termination_a_id')
- termination_b_type_name = kwargs.get('termination_b_type')
- self.termination_b_type = ContentType.objects.get(model=termination_b_type_name.replace('-', ''))
- self.obj = Cable(
- termination_a=termination_a_type.objects.get(pk=termination_a_id),
- termination_b_type=self.termination_b_type
- )
- self.form_class = {
- '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,
- }[termination_b_type_name]
- return super().dispatch(request, *args, **kwargs)
- def get(self, 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(self.obj.termination_a.parent, 'site', None)
- if 'termination_b_rack' not in initial_data:
- initial_data['termination_b_rack'] = getattr(self.obj.termination_a.parent, 'rack', None)
- form = self.form_class(instance=self.obj, initial=initial_data)
- return render(request, self.template_name, {
- 'obj': self.obj,
- 'obj_type': Cable._meta.verbose_name,
- 'termination_b_type': self.termination_b_type.name,
- 'form': form,
- 'return_url': self.get_return_url(request, self.obj),
- })
- def post(self, request, *args, **kwargs):
- form = self.form_class(request.POST, request.FILES, instance=self.obj)
- if form.is_valid():
- obj = form.save()
- msg = 'Created cable <a href="{}">{}</a>'.format(
- obj.get_absolute_url(),
- escape(obj)
- )
- messages.success(request, mark_safe(msg))
- if '_addanother' in request.POST:
- return redirect(request.get_full_path())
- return_url = form.cleaned_data.get('return_url')
- if return_url is not None and is_safe_url(url=return_url, allowed_hosts=request.get_host()):
- return redirect(return_url)
- else:
- return redirect(self.get_return_url(request, obj))
- return render(request, self.template_name, {
- 'obj': self.obj,
- 'obj_type': Cable._meta.verbose_name,
- 'termination_b_type': self.termination_b_type.name,
- 'form': form,
- 'return_url': self.get_return_url(request, self.obj),
- })
- class CableEditView(PermissionRequiredMixin, ObjectEditView):
- permission_required = 'dcim.change_cable'
- model = Cable
- model_form = forms.CableForm
- template_name = 'dcim/cable_edit.html'
- default_return_url = 'dcim:cable_list'
- class CableDeleteView(PermissionRequiredMixin, ObjectDeleteView):
- permission_required = 'dcim.delete_cable'
- model = Cable
- default_return_url = 'dcim:cable_list'
- class CableBulkImportView(PermissionRequiredMixin, BulkImportView):
- permission_required = 'dcim.add_cable'
- model_form = forms.CableCSVForm
- table = tables.CableTable
- default_return_url = 'dcim:cable_list'
- class CableBulkEditView(PermissionRequiredMixin, BulkEditView):
- permission_required = 'dcim.change_cable'
- queryset = Cable.objects.prefetch_related('termination_a', 'termination_b')
- filterset = filters.CableFilterSet
- table = tables.CableTable
- form = forms.CableBulkEditForm
- default_return_url = 'dcim:cable_list'
- class CableBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
- permission_required = 'dcim.delete_cable'
- queryset = Cable.objects.prefetch_related('termination_a', 'termination_b')
- filterset = filters.CableFilterSet
- table = tables.CableTable
- default_return_url = 'dcim:cable_list'
- #
- # Connections
- #
- class ConsoleConnectionsListView(PermissionRequiredMixin, ObjectListView):
- permission_required = ('dcim.view_consoleport', 'dcim.view_consoleserverport')
- 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(PermissionRequiredMixin, ObjectListView):
- permission_required = ('dcim.view_powerport', 'dcim.view_poweroutlet')
- 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(PermissionRequiredMixin, ObjectListView):
- permission_required = 'dcim.view_interface'
- 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', 'interface_a_description',
- 'device_b', 'interface_b', 'interface_b_description',
- '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.connected_endpoint.description if obj.connected_endpoint else None,
- obj.device.identifier,
- obj.name,
- obj.description,
- obj.get_connection_status_display(),
- ])
- csv_data.append(csv)
- return '\n'.join(csv_data)
- #
- # Inventory items
- #
- class InventoryItemListView(PermissionRequiredMixin, ObjectListView):
- permission_required = 'dcim.view_inventoryitem'
- queryset = InventoryItem.objects.prefetch_related('device', 'manufacturer')
- filterset = filters.InventoryItemFilterSet
- filterset_form = forms.InventoryItemFilterForm
- table = tables.InventoryItemTable
- action_buttons = ('import', 'export')
- class InventoryItemEditView(PermissionRequiredMixin, ObjectEditView):
- permission_required = 'dcim.change_inventoryitem'
- model = InventoryItem
- model_form = forms.InventoryItemForm
- class InventoryItemCreateView(PermissionRequiredMixin, ComponentCreateView):
- permission_required = 'dcim.add_inventoryitem'
- model = InventoryItem
- form = forms.InventoryItemCreateForm
- model_form = forms.InventoryItemForm
- template_name = 'dcim/device_component_add.html'
- class InventoryItemDeleteView(PermissionRequiredMixin, ObjectDeleteView):
- permission_required = 'dcim.delete_inventoryitem'
- model = InventoryItem
- class InventoryItemBulkImportView(PermissionRequiredMixin, BulkImportView):
- permission_required = 'dcim.add_inventoryitem'
- model_form = forms.InventoryItemCSVForm
- table = tables.InventoryItemTable
- default_return_url = 'dcim:inventoryitem_list'
- class InventoryItemBulkEditView(PermissionRequiredMixin, BulkEditView):
- permission_required = 'dcim.change_inventoryitem'
- queryset = InventoryItem.objects.prefetch_related('device', 'manufacturer')
- filterset = filters.InventoryItemFilterSet
- table = tables.InventoryItemTable
- form = forms.InventoryItemBulkEditForm
- default_return_url = 'dcim:inventoryitem_list'
- class InventoryItemBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
- permission_required = 'dcim.delete_inventoryitem'
- queryset = InventoryItem.objects.prefetch_related('device', 'manufacturer')
- table = tables.InventoryItemTable
- template_name = 'dcim/inventoryitem_bulk_delete.html'
- default_return_url = 'dcim:inventoryitem_list'
- #
- # Virtual chassis
- #
- class VirtualChassisListView(PermissionRequiredMixin, ObjectListView):
- permission_required = 'dcim.view_virtualchassis'
- queryset = VirtualChassis.objects.prefetch_related('master').annotate(member_count=Count('members'))
- table = tables.VirtualChassisTable
- filterset = filters.VirtualChassisFilterSet
- filterset_form = forms.VirtualChassisFilterForm
- action_buttons = ('export',)
- class VirtualChassisCreateView(PermissionRequiredMixin, View):
- permission_required = 'dcim.add_virtualchassis'
- def post(self, request):
- # Get the list of devices being added to a VirtualChassis
- pk_form = forms.DeviceSelectionForm(request.POST)
- pk_form.full_clean()
- if not pk_form.cleaned_data.get('pk'):
- messages.warning(request, "No devices were selected.")
- return redirect('dcim:device_list')
- device_queryset = Device.objects.filter(
- pk__in=pk_form.cleaned_data.get('pk')
- ).prefetch_related('rack').order_by('vc_position')
- VCMemberFormSet = modelformset_factory(
- model=Device,
- formset=forms.BaseVCMemberFormSet,
- form=forms.DeviceVCMembershipForm,
- extra=0
- )
- if '_create' in request.POST:
- vc_form = forms.VirtualChassisForm(request.POST)
- vc_form.fields['master'].queryset = device_queryset
- formset = VCMemberFormSet(request.POST, queryset=device_queryset)
- if vc_form.is_valid() and formset.is_valid():
- with transaction.atomic():
- # Assign each device to the VirtualChassis before saving
- virtual_chassis = vc_form.save()
- devices = formset.save(commit=False)
- for device in devices:
- device.virtual_chassis = virtual_chassis
- device.save()
- return redirect(vc_form.cleaned_data['master'].get_absolute_url())
- else:
- vc_form = forms.VirtualChassisForm()
- vc_form.fields['master'].queryset = device_queryset
- formset = VCMemberFormSet(queryset=device_queryset)
- return render(request, 'dcim/virtualchassis_edit.html', {
- 'pk_form': pk_form,
- 'vc_form': vc_form,
- 'formset': formset,
- 'return_url': reverse('dcim:device_list'),
- })
- class VirtualChassisEditView(PermissionRequiredMixin, GetReturnURLMixin, View):
- permission_required = 'dcim.change_virtualchassis'
- def get(self, request, pk):
- virtual_chassis = get_object_or_404(VirtualChassis, 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(VirtualChassis, 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(vc_form.cleaned_data['master'].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(PermissionRequiredMixin, ObjectDeleteView):
- permission_required = 'dcim.delete_virtualchassis'
- model = VirtualChassis
- default_return_url = 'dcim:device_list'
- class VirtualChassisAddMemberView(PermissionRequiredMixin, GetReturnURLMixin, View):
- permission_required = 'dcim.change_virtualchassis'
- def get(self, request, pk):
- virtual_chassis = get_object_or_404(VirtualChassis, 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(VirtualChassis, 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(PermissionRequiredMixin, GetReturnURLMixin, View):
- permission_required = 'dcim.change_virtualchassis'
- def get(self, request, pk):
- device = get_object_or_404(Device, 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(Device, 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),
- })
- #
- # Power panels
- #
- class PowerPanelListView(PermissionRequiredMixin, ObjectListView):
- permission_required = 'dcim.view_powerpanel'
- queryset = PowerPanel.objects.prefetch_related(
- 'site', 'rack_group'
- ).annotate(
- powerfeed_count=Count('powerfeeds')
- )
- filterset = filters.PowerPanelFilterSet
- filterset_form = forms.PowerPanelFilterForm
- table = tables.PowerPanelTable
- class PowerPanelView(PermissionRequiredMixin, View):
- permission_required = 'dcim.view_powerpanel'
- def get(self, request, pk):
- powerpanel = get_object_or_404(PowerPanel.objects.prefetch_related('site', 'rack_group'), pk=pk)
- powerfeed_table = tables.PowerFeedTable(
- data=PowerFeed.objects.filter(power_panel=powerpanel).prefetch_related('rack'),
- orderable=False
- )
- powerfeed_table.exclude = ['power_panel']
- return render(request, 'dcim/powerpanel.html', {
- 'powerpanel': powerpanel,
- 'powerfeed_table': powerfeed_table,
- })
- class PowerPanelCreateView(PermissionRequiredMixin, ObjectEditView):
- permission_required = 'dcim.add_powerpanel'
- model = PowerPanel
- model_form = forms.PowerPanelForm
- default_return_url = 'dcim:powerpanel_list'
- class PowerPanelEditView(PowerPanelCreateView):
- permission_required = 'dcim.change_powerpanel'
- class PowerPanelDeleteView(PermissionRequiredMixin, ObjectDeleteView):
- permission_required = 'dcim.delete_powerpanel'
- model = PowerPanel
- default_return_url = 'dcim:powerpanel_list'
- class PowerPanelBulkImportView(PermissionRequiredMixin, BulkImportView):
- permission_required = 'dcim.add_powerpanel'
- model_form = forms.PowerPanelCSVForm
- table = tables.PowerPanelTable
- default_return_url = 'dcim:powerpanel_list'
- class PowerPanelBulkEditView(PermissionRequiredMixin, BulkEditView):
- permission_required = 'dcim.change_powerpanel'
- queryset = PowerPanel.objects.prefetch_related('site', 'rack_group')
- filterset = filters.PowerPanelFilterSet
- table = tables.PowerPanelTable
- form = forms.PowerPanelBulkEditForm
- default_return_url = 'dcim:powerpanel_list'
- class PowerPanelBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
- permission_required = 'dcim.delete_powerpanel'
- queryset = PowerPanel.objects.prefetch_related(
- 'site', 'rack_group'
- ).annotate(
- rack_count=Count('powerfeeds')
- )
- filterset = filters.PowerPanelFilterSet
- table = tables.PowerPanelTable
- default_return_url = 'dcim:powerpanel_list'
- #
- # Power feeds
- #
- class PowerFeedListView(PermissionRequiredMixin, ObjectListView):
- permission_required = 'dcim.view_powerfeed'
- queryset = PowerFeed.objects.prefetch_related(
- 'power_panel', 'rack'
- )
- filterset = filters.PowerFeedFilterSet
- filterset_form = forms.PowerFeedFilterForm
- table = tables.PowerFeedTable
- class PowerFeedView(PermissionRequiredMixin, View):
- permission_required = 'dcim.view_powerfeed'
- def get(self, request, pk):
- powerfeed = get_object_or_404(PowerFeed.objects.prefetch_related('power_panel', 'rack'), pk=pk)
- return render(request, 'dcim/powerfeed.html', {
- 'powerfeed': powerfeed,
- })
- class PowerFeedCreateView(PermissionRequiredMixin, ObjectEditView):
- permission_required = 'dcim.add_powerfeed'
- model = PowerFeed
- model_form = forms.PowerFeedForm
- template_name = 'dcim/powerfeed_edit.html'
- default_return_url = 'dcim:powerfeed_list'
- class PowerFeedEditView(PowerFeedCreateView):
- permission_required = 'dcim.change_powerfeed'
- class PowerFeedDeleteView(PermissionRequiredMixin, ObjectDeleteView):
- permission_required = 'dcim.delete_powerfeed'
- model = PowerFeed
- default_return_url = 'dcim:powerfeed_list'
- class PowerFeedBulkImportView(PermissionRequiredMixin, BulkImportView):
- permission_required = 'dcim.add_powerfeed'
- model_form = forms.PowerFeedCSVForm
- table = tables.PowerFeedTable
- default_return_url = 'dcim:powerfeed_list'
- class PowerFeedBulkEditView(PermissionRequiredMixin, BulkEditView):
- permission_required = 'dcim.change_powerfeed'
- queryset = PowerFeed.objects.prefetch_related('power_panel', 'rack')
- filterset = filters.PowerFeedFilterSet
- table = tables.PowerFeedTable
- form = forms.PowerFeedBulkEditForm
- default_return_url = 'dcim:powerfeed_list'
- class PowerFeedBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
- permission_required = 'dcim.delete_powerfeed'
- queryset = PowerFeed.objects.prefetch_related('power_panel', 'rack')
- filterset = filters.PowerFeedFilterSet
- table = tables.PowerFeedTable
- default_return_url = 'dcim:powerfeed_list'
|