| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895 |
- import netaddr
- from django.db.models import Prefetch
- from django.db.models.expressions import RawSQL
- from django.shortcuts import get_object_or_404, redirect, render
- from django_tables2 import RequestConfig
- from dcim.models import Device, Interface
- from utilities.paginator import EnhancedPaginator, get_paginate_count
- from utilities.utils import get_subquery
- from utilities.views import (
- BulkCreateView, BulkDeleteView, BulkEditView, BulkImportView, ObjectView, ObjectDeleteView, ObjectEditView,
- ObjectListView,
- )
- from virtualization.models import VirtualMachine, VMInterface
- from . import filters, forms, tables
- from .choices import *
- from .constants import *
- from .models import Aggregate, IPAddress, Prefix, RIR, Role, Service, VLAN, VLANGroup, VRF
- from .utils import add_available_ipaddresses, add_available_prefixes, add_available_vlans
- #
- # VRFs
- #
- class VRFListView(ObjectListView):
- queryset = VRF.objects.prefetch_related('tenant')
- filterset = filters.VRFFilterSet
- filterset_form = forms.VRFFilterForm
- table = tables.VRFTable
- class VRFView(ObjectView):
- queryset = VRF.objects.all()
- def get(self, request, pk):
- vrf = get_object_or_404(self.queryset, pk=pk)
- prefix_count = Prefix.objects.restrict(request.user, 'view').filter(vrf=vrf).count()
- return render(request, 'ipam/vrf.html', {
- 'vrf': vrf,
- 'prefix_count': prefix_count,
- })
- class VRFEditView(ObjectEditView):
- queryset = VRF.objects.all()
- model_form = forms.VRFForm
- template_name = 'ipam/vrf_edit.html'
- class VRFDeleteView(ObjectDeleteView):
- queryset = VRF.objects.all()
- class VRFBulkImportView(BulkImportView):
- queryset = VRF.objects.all()
- model_form = forms.VRFCSVForm
- table = tables.VRFTable
- class VRFBulkEditView(BulkEditView):
- queryset = VRF.objects.prefetch_related('tenant')
- filterset = filters.VRFFilterSet
- table = tables.VRFTable
- form = forms.VRFBulkEditForm
- class VRFBulkDeleteView(BulkDeleteView):
- queryset = VRF.objects.prefetch_related('tenant')
- filterset = filters.VRFFilterSet
- table = tables.VRFTable
- #
- # RIRs
- #
- class RIRListView(ObjectListView):
- queryset = RIR.objects.annotate(
- aggregate_count=get_subquery(Aggregate, 'rir')
- )
- filterset = filters.RIRFilterSet
- filterset_form = forms.RIRFilterForm
- table = tables.RIRDetailTable
- template_name = 'ipam/rir_list.html'
- def alter_queryset(self, request):
- if request.GET.get('family') == '6':
- family = 6
- denominator = 2 ** 64 # Count /64s for IPv6 rather than individual IPs
- else:
- family = 4
- denominator = 1
- rirs = []
- for rir in self.queryset:
- stats = {
- 'total': 0,
- 'active': 0,
- 'reserved': 0,
- 'deprecated': 0,
- 'available': 0,
- }
- aggregate_list = Aggregate.objects.restrict(request.user).filter(prefix__family=family, rir=rir)
- for aggregate in aggregate_list:
- queryset = Prefix.objects.restrict(request.user).filter(
- prefix__net_contained_or_equal=str(aggregate.prefix)
- )
- # Find all consumed space for each prefix status (we ignore containers for this purpose).
- active_prefixes = netaddr.cidr_merge(
- [p.prefix for p in queryset.filter(status=PrefixStatusChoices.STATUS_ACTIVE)]
- )
- reserved_prefixes = netaddr.cidr_merge(
- [p.prefix for p in queryset.filter(status=PrefixStatusChoices.STATUS_RESERVED)]
- )
- deprecated_prefixes = netaddr.cidr_merge(
- [p.prefix for p in queryset.filter(status=PrefixStatusChoices.STATUS_DEPRECATED)]
- )
- # Find all available prefixes by subtracting each of the existing prefix sets from the aggregate prefix.
- available_prefixes = (
- netaddr.IPSet([aggregate.prefix]) -
- netaddr.IPSet(active_prefixes) -
- netaddr.IPSet(reserved_prefixes) -
- netaddr.IPSet(deprecated_prefixes)
- )
- # Add the size of each metric to the RIR total.
- stats['total'] += int(aggregate.prefix.size / denominator)
- stats['active'] += int(netaddr.IPSet(active_prefixes).size / denominator)
- stats['reserved'] += int(netaddr.IPSet(reserved_prefixes).size / denominator)
- stats['deprecated'] += int(netaddr.IPSet(deprecated_prefixes).size / denominator)
- stats['available'] += int(available_prefixes.size / denominator)
- # Calculate the percentage of total space for each prefix status.
- total = float(stats['total'])
- stats['percentages'] = {
- 'active': float('{:.2f}'.format(stats['active'] / total * 100)) if total else 0,
- 'reserved': float('{:.2f}'.format(stats['reserved'] / total * 100)) if total else 0,
- 'deprecated': float('{:.2f}'.format(stats['deprecated'] / total * 100)) if total else 0,
- }
- stats['percentages']['available'] = (
- 100 -
- stats['percentages']['active'] -
- stats['percentages']['reserved'] -
- stats['percentages']['deprecated']
- )
- rir.stats = stats
- rirs.append(rir)
- return rirs
- class RIREditView(ObjectEditView):
- queryset = RIR.objects.all()
- model_form = forms.RIRForm
- class RIRDeleteView(ObjectDeleteView):
- queryset = RIR.objects.all()
- class RIRBulkImportView(BulkImportView):
- queryset = RIR.objects.all()
- model_form = forms.RIRCSVForm
- table = tables.RIRTable
- class RIRBulkDeleteView(BulkDeleteView):
- queryset = RIR.objects.annotate(
- aggregate_count=get_subquery(Aggregate, 'rir')
- )
- filterset = filters.RIRFilterSet
- table = tables.RIRTable
- #
- # Aggregates
- #
- class AggregateListView(ObjectListView):
- queryset = Aggregate.objects.prefetch_related('rir').annotate(
- child_count=RawSQL('SELECT COUNT(*) FROM ipam_prefix WHERE ipam_prefix.prefix <<= ipam_aggregate.prefix', ())
- )
- filterset = filters.AggregateFilterSet
- filterset_form = forms.AggregateFilterForm
- table = tables.AggregateDetailTable
- template_name = 'ipam/aggregate_list.html'
- def extra_context(self):
- ipv4_total = 0
- ipv6_total = 0
- for aggregate in self.queryset:
- if aggregate.prefix.version == 6:
- # Report equivalent /64s for IPv6 to keep things sane
- ipv6_total += int(aggregate.prefix.size / 2 ** 64)
- else:
- ipv4_total += aggregate.prefix.size
- return {
- 'ipv4_total': ipv4_total,
- 'ipv6_total': ipv6_total,
- }
- class AggregateView(ObjectView):
- queryset = Aggregate.objects.all()
- def get(self, request, pk):
- aggregate = get_object_or_404(self.queryset, pk=pk)
- # Find all child prefixes contained by this aggregate
- child_prefixes = Prefix.objects.restrict(request.user, 'view').filter(
- prefix__net_contained_or_equal=str(aggregate.prefix)
- ).prefetch_related(
- 'site', 'role'
- ).order_by(
- 'prefix'
- ).annotate_tree()
- # Add available prefixes to the table if requested
- if request.GET.get('show_available', 'true') == 'true':
- child_prefixes = add_available_prefixes(aggregate.prefix, child_prefixes)
- prefix_table = tables.PrefixDetailTable(child_prefixes)
- if request.user.has_perm('ipam.change_prefix') or request.user.has_perm('ipam.delete_prefix'):
- prefix_table.columns.show('pk')
- paginate = {
- 'paginator_class': EnhancedPaginator,
- 'per_page': get_paginate_count(request)
- }
- RequestConfig(request, paginate).configure(prefix_table)
- # Compile permissions list for rendering the object table
- permissions = {
- 'add': request.user.has_perm('ipam.add_prefix'),
- 'change': request.user.has_perm('ipam.change_prefix'),
- 'delete': request.user.has_perm('ipam.delete_prefix'),
- }
- return render(request, 'ipam/aggregate.html', {
- 'aggregate': aggregate,
- 'prefix_table': prefix_table,
- 'permissions': permissions,
- 'show_available': request.GET.get('show_available', 'true') == 'true',
- })
- class AggregateEditView(ObjectEditView):
- queryset = Aggregate.objects.all()
- model_form = forms.AggregateForm
- template_name = 'ipam/aggregate_edit.html'
- class AggregateDeleteView(ObjectDeleteView):
- queryset = Aggregate.objects.all()
- class AggregateBulkImportView(BulkImportView):
- queryset = Aggregate.objects.all()
- model_form = forms.AggregateCSVForm
- table = tables.AggregateTable
- class AggregateBulkEditView(BulkEditView):
- queryset = Aggregate.objects.prefetch_related('rir')
- filterset = filters.AggregateFilterSet
- table = tables.AggregateTable
- form = forms.AggregateBulkEditForm
- class AggregateBulkDeleteView(BulkDeleteView):
- queryset = Aggregate.objects.prefetch_related('rir')
- filterset = filters.AggregateFilterSet
- table = tables.AggregateTable
- #
- # Prefix/VLAN roles
- #
- class RoleListView(ObjectListView):
- queryset = Role.objects.annotate(
- prefix_count=get_subquery(Prefix, 'role'),
- vlan_count=get_subquery(VLAN, 'role')
- )
- table = tables.RoleTable
- class RoleEditView(ObjectEditView):
- queryset = Role.objects.all()
- model_form = forms.RoleForm
- class RoleDeleteView(ObjectDeleteView):
- queryset = Role.objects.all()
- class RoleBulkImportView(BulkImportView):
- queryset = Role.objects.all()
- model_form = forms.RoleCSVForm
- table = tables.RoleTable
- class RoleBulkDeleteView(BulkDeleteView):
- queryset = Role.objects.all()
- table = tables.RoleTable
- #
- # Prefixes
- #
- class PrefixListView(ObjectListView):
- queryset = Prefix.objects.prefetch_related('site', 'vrf__tenant', 'tenant', 'vlan', 'role').annotate_tree()
- filterset = filters.PrefixFilterSet
- filterset_form = forms.PrefixFilterForm
- table = tables.PrefixDetailTable
- template_name = 'ipam/prefix_list.html'
- class PrefixView(ObjectView):
- queryset = Prefix.objects.prefetch_related('vrf', 'site__region', 'tenant__group', 'vlan__group', 'role')
- def get(self, request, pk):
- prefix = get_object_or_404(self.queryset, pk=pk)
- try:
- aggregate = Aggregate.objects.restrict(request.user, 'view').get(
- prefix__net_contains_or_equals=str(prefix.prefix)
- )
- except Aggregate.DoesNotExist:
- aggregate = None
- # Parent prefixes table
- parent_prefixes = Prefix.objects.restrict(request.user, 'view').filter(
- Q(vrf=prefix.vrf) | Q(vrf__isnull=True)
- ).filter(
- prefix__net_contains=str(prefix.prefix)
- ).prefetch_related(
- 'site', 'role'
- ).annotate_tree()
- parent_prefix_table = tables.PrefixTable(list(parent_prefixes), orderable=False)
- parent_prefix_table.exclude = ('vrf',)
- # Duplicate prefixes table
- duplicate_prefixes = Prefix.objects.restrict(request.user, 'view').filter(
- vrf=prefix.vrf, prefix=str(prefix.prefix)
- ).exclude(
- pk=prefix.pk
- ).prefetch_related(
- 'site', 'role'
- )
- duplicate_prefix_table = tables.PrefixTable(list(duplicate_prefixes), orderable=False)
- duplicate_prefix_table.exclude = ('vrf',)
- return render(request, 'ipam/prefix.html', {
- 'prefix': prefix,
- 'aggregate': aggregate,
- 'parent_prefix_table': parent_prefix_table,
- 'duplicate_prefix_table': duplicate_prefix_table,
- })
- class PrefixPrefixesView(ObjectView):
- queryset = Prefix.objects.all()
- def get(self, request, pk):
- prefix = get_object_or_404(self.queryset, pk=pk)
- # Child prefixes table
- child_prefixes = prefix.get_child_prefixes().restrict(request.user, 'view').prefetch_related(
- 'site', 'vlan', 'role',
- ).annotate_tree()
- # Add available prefixes to the table if requested
- if child_prefixes and request.GET.get('show_available', 'true') == 'true':
- child_prefixes = add_available_prefixes(prefix.prefix, child_prefixes)
- prefix_table = tables.PrefixDetailTable(child_prefixes)
- if request.user.has_perm('ipam.change_prefix') or request.user.has_perm('ipam.delete_prefix'):
- prefix_table.columns.show('pk')
- paginate = {
- 'paginator_class': EnhancedPaginator,
- 'per_page': get_paginate_count(request)
- }
- RequestConfig(request, paginate).configure(prefix_table)
- # Compile permissions list for rendering the object table
- permissions = {
- 'add': request.user.has_perm('ipam.add_prefix'),
- 'change': request.user.has_perm('ipam.change_prefix'),
- 'delete': request.user.has_perm('ipam.delete_prefix'),
- }
- return render(request, 'ipam/prefix_prefixes.html', {
- 'prefix': prefix,
- 'first_available_prefix': prefix.get_first_available_prefix(),
- 'prefix_table': prefix_table,
- 'permissions': permissions,
- 'bulk_querystring': 'vrf_id={}&within={}'.format(prefix.vrf.pk if prefix.vrf else '0', prefix.prefix),
- 'active_tab': 'prefixes',
- 'show_available': request.GET.get('show_available', 'true') == 'true',
- })
- class PrefixIPAddressesView(ObjectView):
- queryset = Prefix.objects.all()
- def get(self, request, pk):
- prefix = get_object_or_404(self.queryset, pk=pk)
- # Find all IPAddresses belonging to this Prefix
- ipaddresses = prefix.get_child_ips().restrict(request.user, 'view').prefetch_related(
- 'vrf', 'primary_ip4_for', 'primary_ip6_for'
- )
- # Add available IP addresses to the table if requested
- if request.GET.get('show_available', 'true') == 'true':
- ipaddresses = add_available_ipaddresses(prefix.prefix, ipaddresses, prefix.is_pool)
- ip_table = tables.IPAddressTable(ipaddresses)
- if request.user.has_perm('ipam.change_ipaddress') or request.user.has_perm('ipam.delete_ipaddress'):
- ip_table.columns.show('pk')
- paginate = {
- 'paginator_class': EnhancedPaginator,
- 'per_page': get_paginate_count(request)
- }
- RequestConfig(request, paginate).configure(ip_table)
- # Compile permissions list for rendering the object table
- permissions = {
- 'add': request.user.has_perm('ipam.add_ipaddress'),
- 'change': request.user.has_perm('ipam.change_ipaddress'),
- 'delete': request.user.has_perm('ipam.delete_ipaddress'),
- }
- return render(request, 'ipam/prefix_ipaddresses.html', {
- 'prefix': prefix,
- 'first_available_ip': prefix.get_first_available_ip(),
- 'ip_table': ip_table,
- 'permissions': permissions,
- 'bulk_querystring': 'vrf_id={}&parent={}'.format(prefix.vrf.pk if prefix.vrf else '0', prefix.prefix),
- 'active_tab': 'ip-addresses',
- 'show_available': request.GET.get('show_available', 'true') == 'true',
- })
- class PrefixEditView(ObjectEditView):
- queryset = Prefix.objects.all()
- model_form = forms.PrefixForm
- template_name = 'ipam/prefix_edit.html'
- class PrefixDeleteView(ObjectDeleteView):
- queryset = Prefix.objects.all()
- template_name = 'ipam/prefix_delete.html'
- class PrefixBulkImportView(BulkImportView):
- queryset = Prefix.objects.all()
- model_form = forms.PrefixCSVForm
- table = tables.PrefixTable
- class PrefixBulkEditView(BulkEditView):
- queryset = Prefix.objects.prefetch_related('site', 'vrf__tenant', 'tenant', 'vlan', 'role')
- filterset = filters.PrefixFilterSet
- table = tables.PrefixTable
- form = forms.PrefixBulkEditForm
- class PrefixBulkDeleteView(BulkDeleteView):
- queryset = Prefix.objects.prefetch_related('site', 'vrf__tenant', 'tenant', 'vlan', 'role')
- filterset = filters.PrefixFilterSet
- table = tables.PrefixTable
- #
- # IP addresses
- #
- class IPAddressListView(ObjectListView):
- queryset = IPAddress.objects.prefetch_related(
- 'vrf__tenant', 'tenant', 'nat_inside', 'assigned_object'
- )
- filterset = filters.IPAddressFilterSet
- filterset_form = forms.IPAddressFilterForm
- table = tables.IPAddressDetailTable
- class IPAddressView(ObjectView):
- queryset = IPAddress.objects.prefetch_related('vrf__tenant', 'tenant')
- def get(self, request, pk):
- ipaddress = get_object_or_404(self.queryset, pk=pk)
- # Parent prefixes table
- parent_prefixes = Prefix.objects.restrict(request.user, 'view').filter(
- vrf=ipaddress.vrf, prefix__net_contains=str(ipaddress.address.ip)
- ).prefetch_related(
- 'site', 'role'
- )
- parent_prefixes_table = tables.PrefixTable(list(parent_prefixes), orderable=False)
- parent_prefixes_table.exclude = ('vrf',)
- # Duplicate IPs table
- duplicate_ips = IPAddress.objects.restrict(request.user, 'view').filter(
- vrf=ipaddress.vrf, address=str(ipaddress.address)
- ).exclude(
- pk=ipaddress.pk
- ).prefetch_related(
- 'nat_inside'
- )
- # Exclude anycast IPs if this IP is anycast
- if ipaddress.role == IPAddressRoleChoices.ROLE_ANYCAST:
- duplicate_ips = duplicate_ips.exclude(role=IPAddressRoleChoices.ROLE_ANYCAST)
- # Limit to a maximum of 10 duplicates displayed here
- duplicate_ips_table = tables.IPAddressTable(duplicate_ips[:10], orderable=False)
- # Related IP table
- related_ips = IPAddress.objects.restrict(request.user, 'view').exclude(
- address=str(ipaddress.address)
- ).filter(
- vrf=ipaddress.vrf, address__net_contained_or_equal=str(ipaddress.address)
- )
- related_ips_table = tables.IPAddressTable(related_ips, orderable=False)
- paginate = {
- 'paginator_class': EnhancedPaginator,
- 'per_page': get_paginate_count(request)
- }
- RequestConfig(request, paginate).configure(related_ips_table)
- return render(request, 'ipam/ipaddress.html', {
- 'ipaddress': ipaddress,
- 'parent_prefixes_table': parent_prefixes_table,
- 'duplicate_ips_table': duplicate_ips_table,
- 'more_duplicate_ips': duplicate_ips.count() > 10,
- 'related_ips_table': related_ips_table,
- })
- class IPAddressEditView(ObjectEditView):
- queryset = IPAddress.objects.all()
- model_form = forms.IPAddressForm
- template_name = 'ipam/ipaddress_edit.html'
- def alter_obj(self, obj, request, url_args, url_kwargs):
- if 'interface' in request.GET:
- try:
- obj.assigned_object = Interface.objects.get(pk=request.GET['interface'])
- except (ValueError, Interface.DoesNotExist):
- pass
- elif 'vminterface' in request.GET:
- try:
- obj.assigned_object = VMInterface.objects.get(pk=request.GET['vminterface'])
- except (ValueError, VMInterface.DoesNotExist):
- pass
- return obj
- class IPAddressAssignView(ObjectView):
- """
- Search for IPAddresses to be assigned to an Interface.
- """
- queryset = IPAddress.objects.all()
- def dispatch(self, request, *args, **kwargs):
- # Redirect user if an interface has not been provided
- if 'interface' not in request.GET and 'vminterface' not in request.GET:
- return redirect('ipam:ipaddress_add')
- return super().dispatch(request, *args, **kwargs)
- def get(self, request):
- form = forms.IPAddressAssignForm()
- return render(request, 'ipam/ipaddress_assign.html', {
- 'form': form,
- 'return_url': request.GET.get('return_url', ''),
- })
- def post(self, request):
- form = forms.IPAddressAssignForm(request.POST)
- table = None
- if form.is_valid():
- addresses = self.queryset.prefetch_related('vrf', 'tenant')
- # Limit to 100 results
- addresses = filters.IPAddressFilterSet(request.POST, addresses).qs[:100]
- table = tables.IPAddressAssignTable(addresses)
- return render(request, 'ipam/ipaddress_assign.html', {
- 'form': form,
- 'table': table,
- 'return_url': request.GET.get('return_url'),
- })
- class IPAddressDeleteView(ObjectDeleteView):
- queryset = IPAddress.objects.all()
- class IPAddressBulkCreateView(BulkCreateView):
- queryset = IPAddress.objects.all()
- form = forms.IPAddressBulkCreateForm
- model_form = forms.IPAddressBulkAddForm
- pattern_target = 'address'
- template_name = 'ipam/ipaddress_bulk_add.html'
- class IPAddressBulkImportView(BulkImportView):
- queryset = IPAddress.objects.all()
- model_form = forms.IPAddressCSVForm
- table = tables.IPAddressTable
- class IPAddressBulkEditView(BulkEditView):
- queryset = IPAddress.objects.prefetch_related('vrf__tenant', 'tenant')
- filterset = filters.IPAddressFilterSet
- table = tables.IPAddressTable
- form = forms.IPAddressBulkEditForm
- class IPAddressBulkDeleteView(BulkDeleteView):
- queryset = IPAddress.objects.prefetch_related('vrf__tenant', 'tenant')
- filterset = filters.IPAddressFilterSet
- table = tables.IPAddressTable
- #
- # VLAN groups
- #
- class VLANGroupListView(ObjectListView):
- queryset = VLANGroup.objects.prefetch_related('site').annotate(
- vlan_count=get_subquery(VLAN, 'group')
- )
- filterset = filters.VLANGroupFilterSet
- filterset_form = forms.VLANGroupFilterForm
- table = tables.VLANGroupTable
- class VLANGroupEditView(ObjectEditView):
- queryset = VLANGroup.objects.all()
- model_form = forms.VLANGroupForm
- class VLANGroupDeleteView(ObjectDeleteView):
- queryset = VLANGroup.objects.all()
- class VLANGroupBulkImportView(BulkImportView):
- queryset = VLANGroup.objects.all()
- model_form = forms.VLANGroupCSVForm
- table = tables.VLANGroupTable
- class VLANGroupBulkDeleteView(BulkDeleteView):
- queryset = VLANGroup.objects.prefetch_related('site').annotate(
- vlan_count=get_subquery(VLAN, 'group')
- )
- filterset = filters.VLANGroupFilterSet
- table = tables.VLANGroupTable
- class VLANGroupVLANsView(ObjectView):
- queryset = VLANGroup.objects.all()
- def get(self, request, pk):
- vlan_group = get_object_or_404(self.queryset, pk=pk)
- vlans = VLAN.objects.restrict(request.user, 'view').filter(group_id=pk).prefetch_related(
- Prefetch('prefixes', queryset=Prefix.objects.restrict(request.user))
- )
- vlans = add_available_vlans(vlan_group, vlans)
- vlan_table = tables.VLANDetailTable(vlans)
- if request.user.has_perm('ipam.change_vlan') or request.user.has_perm('ipam.delete_vlan'):
- vlan_table.columns.show('pk')
- vlan_table.columns.hide('site')
- vlan_table.columns.hide('group')
- paginate = {
- 'paginator_class': EnhancedPaginator,
- 'per_page': get_paginate_count(request),
- }
- RequestConfig(request, paginate).configure(vlan_table)
- # Compile permissions list for rendering the object table
- permissions = {
- 'add': request.user.has_perm('ipam.add_vlan'),
- 'change': request.user.has_perm('ipam.change_vlan'),
- 'delete': request.user.has_perm('ipam.delete_vlan'),
- }
- return render(request, 'ipam/vlangroup_vlans.html', {
- 'vlan_group': vlan_group,
- 'first_available_vlan': vlan_group.get_next_available_vid(),
- 'bulk_querystring': 'group_id={}'.format(vlan_group.pk),
- 'vlan_table': vlan_table,
- 'permissions': permissions,
- })
- #
- # VLANs
- #
- class VLANListView(ObjectListView):
- queryset = VLAN.objects.prefetch_related(
- 'site', 'group', 'tenant', 'role', 'prefixes'
- )
- filterset = filters.VLANFilterSet
- filterset_form = forms.VLANFilterForm
- table = tables.VLANDetailTable
- class VLANView(ObjectView):
- queryset = VLAN.objects.prefetch_related('site__region', 'tenant__group', 'role')
- def get(self, request, pk):
- vlan = get_object_or_404(self.queryset, pk=pk)
- prefixes = Prefix.objects.restrict(request.user, 'view').filter(vlan=vlan).prefetch_related(
- 'vrf', 'site', 'role'
- )
- prefix_table = tables.PrefixTable(list(prefixes), orderable=False)
- prefix_table.exclude = ('vlan',)
- return render(request, 'ipam/vlan.html', {
- 'vlan': vlan,
- 'prefix_table': prefix_table,
- })
- class VLANInterfacesView(ObjectView):
- queryset = VLAN.objects.all()
- def get(self, request, pk):
- vlan = get_object_or_404(self.queryset, pk=pk)
- interfaces = vlan.get_interfaces().prefetch_related('device')
- members_table = tables.VLANDevicesTable(interfaces)
- paginate = {
- 'paginator_class': EnhancedPaginator,
- 'per_page': get_paginate_count(request)
- }
- RequestConfig(request, paginate).configure(members_table)
- return render(request, 'ipam/vlan_interfaces.html', {
- 'vlan': vlan,
- 'members_table': members_table,
- 'active_tab': 'interfaces',
- })
- class VLANVMInterfacesView(ObjectView):
- queryset = VLAN.objects.all()
- def get(self, request, pk):
- vlan = get_object_or_404(self.queryset, pk=pk)
- interfaces = vlan.get_vminterfaces().prefetch_related('virtual_machine')
- members_table = tables.VLANVirtualMachinesTable(interfaces)
- paginate = {
- 'paginator_class': EnhancedPaginator,
- 'per_page': get_paginate_count(request)
- }
- RequestConfig(request, paginate).configure(members_table)
- return render(request, 'ipam/vlan_vminterfaces.html', {
- 'vlan': vlan,
- 'members_table': members_table,
- 'active_tab': 'vminterfaces',
- })
- class VLANEditView(ObjectEditView):
- queryset = VLAN.objects.all()
- model_form = forms.VLANForm
- template_name = 'ipam/vlan_edit.html'
- class VLANDeleteView(ObjectDeleteView):
- queryset = VLAN.objects.all()
- class VLANBulkImportView(BulkImportView):
- queryset = VLAN.objects.all()
- model_form = forms.VLANCSVForm
- table = tables.VLANTable
- class VLANBulkEditView(BulkEditView):
- queryset = VLAN.objects.prefetch_related('site', 'group', 'tenant', 'role')
- filterset = filters.VLANFilterSet
- table = tables.VLANTable
- form = forms.VLANBulkEditForm
- class VLANBulkDeleteView(BulkDeleteView):
- queryset = VLAN.objects.prefetch_related('site', 'group', 'tenant', 'role')
- filterset = filters.VLANFilterSet
- table = tables.VLANTable
- #
- # Services
- #
- class ServiceListView(ObjectListView):
- queryset = Service.objects.prefetch_related('device', 'virtual_machine')
- filterset = filters.ServiceFilterSet
- filterset_form = forms.ServiceFilterForm
- table = tables.ServiceTable
- action_buttons = ('export',)
- class ServiceView(ObjectView):
- queryset = Service.objects.prefetch_related('ipaddresses')
- def get(self, request, pk):
- service = get_object_or_404(self.queryset, pk=pk)
- return render(request, 'ipam/service.html', {
- 'service': service,
- })
- class ServiceEditView(ObjectEditView):
- queryset = Service.objects.prefetch_related('ipaddresses')
- model_form = forms.ServiceForm
- template_name = 'ipam/service_edit.html'
- def alter_obj(self, obj, request, url_args, url_kwargs):
- if 'device' in url_kwargs:
- obj.device = get_object_or_404(
- Device.objects.restrict(request.user),
- pk=url_kwargs['device']
- )
- elif 'virtualmachine' in url_kwargs:
- obj.virtual_machine = get_object_or_404(
- VirtualMachine.objects.restrict(request.user),
- pk=url_kwargs['virtualmachine']
- )
- return obj
- def get_return_url(self, request, service):
- return service.parent.get_absolute_url()
- class ServiceBulkImportView(BulkImportView):
- queryset = Service.objects.all()
- model_form = forms.ServiceCSVForm
- table = tables.ServiceTable
- class ServiceDeleteView(ObjectDeleteView):
- queryset = Service.objects.all()
- class ServiceBulkEditView(BulkEditView):
- queryset = Service.objects.prefetch_related('device', 'virtual_machine')
- filterset = filters.ServiceFilterSet
- table = tables.ServiceTable
- form = forms.ServiceBulkEditForm
- class ServiceBulkDeleteView(BulkDeleteView):
- queryset = Service.objects.prefetch_related('device', 'virtual_machine')
- filterset = filters.ServiceFilterSet
- table = tables.ServiceTable
|