| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568 |
- 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 .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
- template_name = 'dcim/region_list.html'
- 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
- template_name = 'dcim/site_list.html'
- 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
- template_name = 'dcim/rackgroup_list.html'
- 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
- template_name = 'dcim/rackrole_list.html'
- 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
- template_name = 'dcim/rack_list.html'
- 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('site', 'group', 'tenant', 'role', 'devices__device_type')
- 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
- if request.GET.get('face') == '1':
- face_id = 1
- else:
- face_id = 0
- return render(request, 'dcim/rack_elevation_list.html', {
- 'paginator': paginator,
- 'page': page,
- 'total_count': total_count,
- 'face_id': face_id,
- '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
- template_name = 'dcim/rackreservation_list.html'
- 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 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
- template_name = 'dcim/manufacturer_list.html'
- 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
- template_name = 'dcim/devicetype_list.html'
- 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'
- #
- # Device type components
- #
- class ConsolePortTemplateCreateView(PermissionRequiredMixin, ComponentCreateView):
- permission_required = 'dcim.add_consoleporttemplate'
- parent_model = DeviceType
- parent_field = 'device_type'
- 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 ConsolePortTemplateBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
- permission_required = 'dcim.delete_consoleporttemplate'
- queryset = ConsolePortTemplate.objects.all()
- parent_model = DeviceType
- table = tables.ConsolePortTemplateTable
- class ConsoleServerPortTemplateCreateView(PermissionRequiredMixin, ComponentCreateView):
- permission_required = 'dcim.add_consoleserverporttemplate'
- parent_model = DeviceType
- parent_field = 'device_type'
- 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 ConsoleServerPortTemplateBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
- permission_required = 'dcim.delete_consoleserverporttemplate'
- queryset = ConsoleServerPortTemplate.objects.all()
- parent_model = DeviceType
- table = tables.ConsoleServerPortTemplateTable
- class PowerPortTemplateCreateView(PermissionRequiredMixin, ComponentCreateView):
- permission_required = 'dcim.add_powerporttemplate'
- parent_model = DeviceType
- parent_field = 'device_type'
- 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 PowerPortTemplateBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
- permission_required = 'dcim.delete_powerporttemplate'
- queryset = PowerPortTemplate.objects.all()
- parent_model = DeviceType
- table = tables.PowerPortTemplateTable
- class PowerOutletTemplateCreateView(PermissionRequiredMixin, ComponentCreateView):
- permission_required = 'dcim.add_poweroutlettemplate'
- parent_model = DeviceType
- parent_field = 'device_type'
- 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 PowerOutletTemplateBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
- permission_required = 'dcim.delete_poweroutlettemplate'
- queryset = PowerOutletTemplate.objects.all()
- parent_model = DeviceType
- table = tables.PowerOutletTemplateTable
- class InterfaceTemplateCreateView(PermissionRequiredMixin, ComponentCreateView):
- permission_required = 'dcim.add_interfacetemplate'
- parent_model = DeviceType
- parent_field = 'device_type'
- 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 InterfaceTemplateBulkEditView(PermissionRequiredMixin, BulkEditView):
- permission_required = 'dcim.change_interfacetemplate'
- queryset = InterfaceTemplate.objects.all()
- parent_model = DeviceType
- table = tables.InterfaceTemplateTable
- form = forms.InterfaceTemplateBulkEditForm
- class InterfaceTemplateBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
- permission_required = 'dcim.delete_interfacetemplate'
- queryset = InterfaceTemplate.objects.all()
- parent_model = DeviceType
- table = tables.InterfaceTemplateTable
- class FrontPortTemplateCreateView(PermissionRequiredMixin, ComponentCreateView):
- permission_required = 'dcim.add_frontporttemplate'
- parent_model = DeviceType
- parent_field = 'device_type'
- 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 FrontPortTemplateBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
- permission_required = 'dcim.delete_frontporttemplate'
- queryset = FrontPortTemplate.objects.all()
- parent_model = DeviceType
- table = tables.FrontPortTemplateTable
- class RearPortTemplateCreateView(PermissionRequiredMixin, ComponentCreateView):
- permission_required = 'dcim.add_rearporttemplate'
- parent_model = DeviceType
- parent_field = 'device_type'
- 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 RearPortTemplateBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
- permission_required = 'dcim.delete_rearporttemplate'
- queryset = RearPortTemplate.objects.all()
- parent_model = DeviceType
- table = tables.RearPortTemplateTable
- class DeviceBayTemplateCreateView(PermissionRequiredMixin, ComponentCreateView):
- permission_required = 'dcim.add_devicebaytemplate'
- parent_model = DeviceType
- parent_field = 'device_type'
- 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 DeviceBayTemplateBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
- permission_required = 'dcim.delete_devicebaytemplate'
- queryset = DeviceBayTemplate.objects.all()
- parent_model = DeviceType
- table = tables.DeviceBayTemplateTable
- #
- # Device roles
- #
- class DeviceRoleListView(PermissionRequiredMixin, ObjectListView):
- permission_required = 'dcim.view_devicerole'
- queryset = DeviceRole.objects.all()
- table = tables.DeviceRoleTable
- template_name = 'dcim/devicerole_list.html'
- 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
- template_name = 'dcim/platform_list.html'
- 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.connectable().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):
- 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
- template_name = 'dcim/device_component_list.html'
- class ConsolePortCreateView(PermissionRequiredMixin, ComponentCreateView):
- permission_required = 'dcim.add_consoleport'
- parent_model = Device
- parent_field = 'device'
- 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 ConsolePortBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
- permission_required = 'dcim.delete_consoleport'
- queryset = ConsolePort.objects.all()
- parent_model = Device
- table = tables.ConsolePortTable
- #
- # 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
- template_name = 'dcim/device_component_list.html'
- class ConsoleServerPortCreateView(PermissionRequiredMixin, ComponentCreateView):
- permission_required = 'dcim.add_consoleserverport'
- parent_model = Device
- parent_field = 'device'
- 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()
- parent_model = Device
- 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()
- parent_model = Device
- table = tables.ConsoleServerPortTable
- #
- # 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
- template_name = 'dcim/device_component_list.html'
- class PowerPortCreateView(PermissionRequiredMixin, ComponentCreateView):
- permission_required = 'dcim.add_powerport'
- parent_model = Device
- parent_field = 'device'
- 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 PowerPortBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
- permission_required = 'dcim.delete_powerport'
- queryset = PowerPort.objects.all()
- parent_model = Device
- table = tables.PowerPortTable
- #
- # 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
- template_name = 'dcim/device_component_list.html'
- class PowerOutletCreateView(PermissionRequiredMixin, ComponentCreateView):
- permission_required = 'dcim.add_poweroutlet'
- parent_model = Device
- parent_field = 'device'
- 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()
- parent_model = Device
- 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()
- parent_model = Device
- table = tables.PowerOutletTable
- #
- # 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
- template_name = 'dcim/device_component_list.html'
- 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'
- parent_model = Device
- parent_field = 'device'
- 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()
- parent_model = Device
- 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()
- parent_model = Device
- table = tables.InterfaceTable
- #
- # 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
- template_name = 'dcim/device_component_list.html'
- class FrontPortCreateView(PermissionRequiredMixin, ComponentCreateView):
- permission_required = 'dcim.add_frontport'
- parent_model = Device
- parent_field = 'device'
- 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()
- parent_model = Device
- 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()
- parent_model = Device
- table = tables.FrontPortTable
- #
- # 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
- template_name = 'dcim/device_component_list.html'
- class RearPortCreateView(PermissionRequiredMixin, ComponentCreateView):
- permission_required = 'dcim.add_rearport'
- parent_model = Device
- parent_field = 'device'
- 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()
- parent_model = Device
- 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()
- parent_model = Device
- table = tables.RearPortTable
- #
- # 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
- template_name = 'dcim/device_component_list.html'
- class DeviceBayCreateView(PermissionRequiredMixin, ComponentCreateView):
- permission_required = 'dcim.add_devicebay'
- parent_model = Device
- parent_field = 'device'
- 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()
- parent_model = Device
- table = tables.DeviceBayTable
- #
- # 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
- template_name = 'dcim/cable_list.html'
- 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}
- 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
- template_name = 'dcim/inventoryitem_list.html'
- class InventoryItemEditView(PermissionRequiredMixin, ObjectEditView):
- permission_required = 'dcim.change_inventoryitem'
- model = InventoryItem
- model_form = forms.InventoryItemForm
- def alter_obj(self, obj, request, url_args, url_kwargs):
- if 'device' in url_kwargs:
- obj.device = get_object_or_404(Device, pk=url_kwargs['device'])
- return obj
- def get_return_url(self, request, obj):
- return reverse('dcim:device_inventory', kwargs={'pk': obj.device.pk})
- 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
- template_name = 'dcim/virtualchassis_list.html'
- 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
- template_name = 'dcim/powerpanel_list.html'
- 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 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
- template_name = 'dcim/powerfeed_list.html'
- 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'
|