from django.contrib.contenttypes.models import ContentType 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.urls import reverse from circuits.models import Provider from circuits.tables import ProviderTable from dcim.filtersets import InterfaceFilterSet from dcim.models import Interface, Site from dcim.tables import SiteTable from netbox.views import generic from utilities.utils import count_related from virtualization.filtersets import VMInterfaceFilterSet from virtualization.models import VMInterface from . import filtersets, forms, tables from .constants import * from .models import * from .models import ASN from .utils import add_requested_prefixes, add_available_ipaddresses, add_available_vlans # # VRFs # class VRFListView(generic.ObjectListView): queryset = VRF.objects.all() filterset = filtersets.VRFFilterSet filterset_form = forms.VRFFilterForm table = tables.VRFTable class VRFView(generic.ObjectView): queryset = VRF.objects.all() def get_extra_context(self, request, instance): prefix_count = Prefix.objects.restrict(request.user, 'view').filter(vrf=instance).count() ipaddress_count = IPAddress.objects.restrict(request.user, 'view').filter(vrf=instance).count() import_targets_table = tables.RouteTargetTable( instance.import_targets.prefetch_related('tenant'), orderable=False ) export_targets_table = tables.RouteTargetTable( instance.export_targets.prefetch_related('tenant'), orderable=False ) return { 'prefix_count': prefix_count, 'ipaddress_count': ipaddress_count, 'import_targets_table': import_targets_table, 'export_targets_table': export_targets_table, } class VRFEditView(generic.ObjectEditView): queryset = VRF.objects.all() form = forms.VRFForm class VRFDeleteView(generic.ObjectDeleteView): queryset = VRF.objects.all() class VRFBulkImportView(generic.BulkImportView): queryset = VRF.objects.all() model_form = forms.VRFCSVForm table = tables.VRFTable class VRFBulkEditView(generic.BulkEditView): queryset = VRF.objects.prefetch_related('tenant') filterset = filtersets.VRFFilterSet table = tables.VRFTable form = forms.VRFBulkEditForm class VRFBulkDeleteView(generic.BulkDeleteView): queryset = VRF.objects.prefetch_related('tenant') filterset = filtersets.VRFFilterSet table = tables.VRFTable # # Route targets # class RouteTargetListView(generic.ObjectListView): queryset = RouteTarget.objects.all() filterset = filtersets.RouteTargetFilterSet filterset_form = forms.RouteTargetFilterForm table = tables.RouteTargetTable class RouteTargetView(generic.ObjectView): queryset = RouteTarget.objects.all() def get_extra_context(self, request, instance): importing_vrfs_table = tables.VRFTable( instance.importing_vrfs.prefetch_related('tenant'), orderable=False ) exporting_vrfs_table = tables.VRFTable( instance.exporting_vrfs.prefetch_related('tenant'), orderable=False ) return { 'importing_vrfs_table': importing_vrfs_table, 'exporting_vrfs_table': exporting_vrfs_table, } class RouteTargetEditView(generic.ObjectEditView): queryset = RouteTarget.objects.all() form = forms.RouteTargetForm class RouteTargetDeleteView(generic.ObjectDeleteView): queryset = RouteTarget.objects.all() class RouteTargetBulkImportView(generic.BulkImportView): queryset = RouteTarget.objects.all() model_form = forms.RouteTargetCSVForm table = tables.RouteTargetTable class RouteTargetBulkEditView(generic.BulkEditView): queryset = RouteTarget.objects.prefetch_related('tenant') filterset = filtersets.RouteTargetFilterSet table = tables.RouteTargetTable form = forms.RouteTargetBulkEditForm class RouteTargetBulkDeleteView(generic.BulkDeleteView): queryset = RouteTarget.objects.prefetch_related('tenant') filterset = filtersets.RouteTargetFilterSet table = tables.RouteTargetTable # # RIRs # class RIRListView(generic.ObjectListView): queryset = RIR.objects.annotate( aggregate_count=count_related(Aggregate, 'rir') ) filterset = filtersets.RIRFilterSet filterset_form = forms.RIRFilterForm table = tables.RIRTable class RIRView(generic.ObjectView): queryset = RIR.objects.all() def get_extra_context(self, request, instance): aggregates = Aggregate.objects.restrict(request.user, 'view').filter(rir=instance).annotate( child_count=RawSQL('SELECT COUNT(*) FROM ipam_prefix WHERE ipam_prefix.prefix <<= ipam_aggregate.prefix', ()) ) aggregates_table = tables.AggregateTable(aggregates, exclude=('rir', 'utilization')) aggregates_table.configure(request) return { 'aggregates_table': aggregates_table, } class RIREditView(generic.ObjectEditView): queryset = RIR.objects.all() form = forms.RIRForm class RIRDeleteView(generic.ObjectDeleteView): queryset = RIR.objects.all() class RIRBulkImportView(generic.BulkImportView): queryset = RIR.objects.all() model_form = forms.RIRCSVForm table = tables.RIRTable class RIRBulkEditView(generic.BulkEditView): queryset = RIR.objects.annotate( aggregate_count=count_related(Aggregate, 'rir') ) filterset = filtersets.RIRFilterSet table = tables.RIRTable form = forms.RIRBulkEditForm class RIRBulkDeleteView(generic.BulkDeleteView): queryset = RIR.objects.annotate( aggregate_count=count_related(Aggregate, 'rir') ) filterset = filtersets.RIRFilterSet table = tables.RIRTable # # ASNs # class ASNListView(generic.ObjectListView): queryset = ASN.objects.annotate( site_count=count_related(Site, 'asns'), provider_count=count_related(Provider, 'asns') ) filterset = filtersets.ASNFilterSet filterset_form = forms.ASNFilterForm table = tables.ASNTable class ASNView(generic.ObjectView): queryset = ASN.objects.all() def get_extra_context(self, request, instance): # Gather assigned Sites sites = instance.sites.restrict(request.user, 'view') sites_table = SiteTable(sites) sites_table.configure(request) # Gather assigned Providers providers = instance.providers.restrict(request.user, 'view') providers_table = ProviderTable(providers) providers_table.configure(request) return { 'sites_table': sites_table, 'sites_count': sites.count(), 'providers_table': providers_table, 'providers_count': providers.count(), } class ASNEditView(generic.ObjectEditView): queryset = ASN.objects.all() form = forms.ASNForm class ASNDeleteView(generic.ObjectDeleteView): queryset = ASN.objects.all() class ASNBulkImportView(generic.BulkImportView): queryset = ASN.objects.all() model_form = forms.ASNCSVForm table = tables.ASNTable class ASNBulkEditView(generic.BulkEditView): queryset = ASN.objects.annotate( site_count=count_related(Site, 'asns') ) filterset = filtersets.ASNFilterSet table = tables.ASNTable form = forms.ASNBulkEditForm class ASNBulkDeleteView(generic.BulkDeleteView): queryset = ASN.objects.annotate( site_count=count_related(Site, 'asns') ) filterset = filtersets.ASNFilterSet table = tables.ASNTable # # Aggregates # class AggregateListView(generic.ObjectListView): queryset = Aggregate.objects.annotate( child_count=RawSQL('SELECT COUNT(*) FROM ipam_prefix WHERE ipam_prefix.prefix <<= ipam_aggregate.prefix', ()) ) filterset = filtersets.AggregateFilterSet filterset_form = forms.AggregateFilterForm table = tables.AggregateTable class AggregateView(generic.ObjectView): queryset = Aggregate.objects.all() class AggregatePrefixesView(generic.ObjectChildrenView): queryset = Aggregate.objects.all() child_model = Prefix table = tables.PrefixTable filterset = filtersets.PrefixFilterSet template_name = 'ipam/aggregate/prefixes.html' def get_children(self, request, parent): return Prefix.objects.restrict(request.user, 'view').filter( prefix__net_contained_or_equal=str(parent.prefix) ).prefetch_related('site', 'role', 'tenant', 'vlan') def prep_table_data(self, request, queryset, parent): # Determine whether to show assigned prefixes, available prefixes, or both show_available = bool(request.GET.get('show_available', 'true') == 'true') show_assigned = bool(request.GET.get('show_assigned', 'true') == 'true') return add_requested_prefixes(parent.prefix, queryset, show_available, show_assigned) def get_extra_context(self, request, instance): return { 'bulk_querystring': f'within={instance.prefix}', 'active_tab': 'prefixes', 'first_available_prefix': instance.get_first_available_prefix(), 'show_available': bool(request.GET.get('show_available', 'true') == 'true'), 'show_assigned': bool(request.GET.get('show_assigned', 'true') == 'true'), } class AggregateEditView(generic.ObjectEditView): queryset = Aggregate.objects.all() form = forms.AggregateForm class AggregateDeleteView(generic.ObjectDeleteView): queryset = Aggregate.objects.all() class AggregateBulkImportView(generic.BulkImportView): queryset = Aggregate.objects.all() model_form = forms.AggregateCSVForm table = tables.AggregateTable class AggregateBulkEditView(generic.BulkEditView): queryset = Aggregate.objects.prefetch_related('rir') filterset = filtersets.AggregateFilterSet table = tables.AggregateTable form = forms.AggregateBulkEditForm class AggregateBulkDeleteView(generic.BulkDeleteView): queryset = Aggregate.objects.prefetch_related('rir') filterset = filtersets.AggregateFilterSet table = tables.AggregateTable # # Prefix/VLAN roles # class RoleListView(generic.ObjectListView): queryset = Role.objects.annotate( prefix_count=count_related(Prefix, 'role'), iprange_count=count_related(IPRange, 'role'), vlan_count=count_related(VLAN, 'role') ) filterset = filtersets.RoleFilterSet filterset_form = forms.RoleFilterForm table = tables.RoleTable class RoleView(generic.ObjectView): queryset = Role.objects.all() def get_extra_context(self, request, instance): prefixes = Prefix.objects.restrict(request.user, 'view').filter( role=instance ) prefixes_table = tables.PrefixTable(prefixes, exclude=('role', 'utilization')) prefixes_table.configure(request) return { 'prefixes_table': prefixes_table, } class RoleEditView(generic.ObjectEditView): queryset = Role.objects.all() form = forms.RoleForm class RoleDeleteView(generic.ObjectDeleteView): queryset = Role.objects.all() class RoleBulkImportView(generic.BulkImportView): queryset = Role.objects.all() model_form = forms.RoleCSVForm table = tables.RoleTable class RoleBulkEditView(generic.BulkEditView): queryset = Role.objects.all() filterset = filtersets.RoleFilterSet table = tables.RoleTable form = forms.RoleBulkEditForm class RoleBulkDeleteView(generic.BulkDeleteView): queryset = Role.objects.all() table = tables.RoleTable # # Prefixes # class PrefixListView(generic.ObjectListView): queryset = Prefix.objects.all() filterset = filtersets.PrefixFilterSet filterset_form = forms.PrefixFilterForm table = tables.PrefixTable template_name = 'ipam/prefix_list.html' class PrefixView(generic.ObjectView): queryset = Prefix.objects.prefetch_related('vrf', 'site__region', 'tenant__group', 'vlan__group', 'role') def get_extra_context(self, request, instance): try: aggregate = Aggregate.objects.restrict(request.user, 'view').get( prefix__net_contains_or_equals=str(instance.prefix) ) except Aggregate.DoesNotExist: aggregate = None # Parent prefixes table parent_prefixes = Prefix.objects.restrict(request.user, 'view').filter( Q(vrf=instance.vrf) | Q(vrf__isnull=True) ).filter( prefix__net_contains=str(instance.prefix) ).prefetch_related( 'site', 'role', 'tenant' ) parent_prefix_table = tables.PrefixTable( list(parent_prefixes), exclude=('vrf', 'utilization'), orderable=False ) # Duplicate prefixes table duplicate_prefixes = Prefix.objects.restrict(request.user, 'view').filter( vrf=instance.vrf, prefix=str(instance.prefix) ).exclude( pk=instance.pk ).prefetch_related( 'site', 'role' ) duplicate_prefix_table = tables.PrefixTable( list(duplicate_prefixes), exclude=('vrf', 'utilization'), orderable=False ) return { 'aggregate': aggregate, 'parent_prefix_table': parent_prefix_table, 'duplicate_prefix_table': duplicate_prefix_table, } class PrefixPrefixesView(generic.ObjectChildrenView): queryset = Prefix.objects.all() child_model = Prefix table = tables.PrefixTable filterset = filtersets.PrefixFilterSet template_name = 'ipam/prefix/prefixes.html' def get_children(self, request, parent): return parent.get_child_prefixes().restrict(request.user, 'view').prefetch_related( 'site', 'vrf', 'vlan', 'role', 'tenant', ) def prep_table_data(self, request, queryset, parent): # Determine whether to show assigned prefixes, available prefixes, or both show_available = bool(request.GET.get('show_available', 'true') == 'true') show_assigned = bool(request.GET.get('show_assigned', 'true') == 'true') return add_requested_prefixes(parent.prefix, queryset, show_available, show_assigned) def get_extra_context(self, request, instance): return { 'bulk_querystring': f"vrf_id={instance.vrf.pk if instance.vrf else '0'}&within={instance.prefix}", 'active_tab': 'prefixes', 'first_available_prefix': instance.get_first_available_prefix(), 'show_available': bool(request.GET.get('show_available', 'true') == 'true'), 'show_assigned': bool(request.GET.get('show_assigned', 'true') == 'true'), } class PrefixIPRangesView(generic.ObjectChildrenView): queryset = Prefix.objects.all() child_model = IPRange table = tables.IPRangeTable filterset = filtersets.IPRangeFilterSet template_name = 'ipam/prefix/ip_ranges.html' def get_children(self, request, parent): return parent.get_child_ranges().restrict(request.user, 'view').prefetch_related( 'vrf', 'role', 'tenant', ) def get_extra_context(self, request, instance): return { 'bulk_querystring': f"vrf_id={instance.vrf.pk if instance.vrf else '0'}&parent={instance.prefix}", 'active_tab': 'ip-ranges', 'first_available_ip': instance.get_first_available_ip(), } class PrefixIPAddressesView(generic.ObjectChildrenView): queryset = Prefix.objects.all() child_model = IPAddress table = tables.IPAddressTable filterset = filtersets.IPAddressFilterSet template_name = 'ipam/prefix/ip_addresses.html' def get_children(self, request, parent): return parent.get_child_ips().restrict(request.user, 'view').prefetch_related('vrf', 'tenant') def prep_table_data(self, request, queryset, parent): show_available = bool(request.GET.get('show_available', 'true') == 'true') if show_available: return add_available_ipaddresses(parent.prefix, queryset, parent.is_pool) return queryset def get_extra_context(self, request, instance): return { 'bulk_querystring': f"vrf_id={instance.vrf.pk if instance.vrf else '0'}&parent={instance.prefix}", 'active_tab': 'ip-addresses', 'first_available_ip': instance.get_first_available_ip(), } class PrefixEditView(generic.ObjectEditView): queryset = Prefix.objects.all() form = forms.PrefixForm class PrefixDeleteView(generic.ObjectDeleteView): queryset = Prefix.objects.all() class PrefixBulkImportView(generic.BulkImportView): queryset = Prefix.objects.all() model_form = forms.PrefixCSVForm table = tables.PrefixTable class PrefixBulkEditView(generic.BulkEditView): queryset = Prefix.objects.prefetch_related('site', 'vrf__tenant', 'tenant', 'vlan', 'role') filterset = filtersets.PrefixFilterSet table = tables.PrefixTable form = forms.PrefixBulkEditForm class PrefixBulkDeleteView(generic.BulkDeleteView): queryset = Prefix.objects.prefetch_related('site', 'vrf__tenant', 'tenant', 'vlan', 'role') filterset = filtersets.PrefixFilterSet table = tables.PrefixTable # # IP Ranges # class IPRangeListView(generic.ObjectListView): queryset = IPRange.objects.all() filterset = filtersets.IPRangeFilterSet filterset_form = forms.IPRangeFilterForm table = tables.IPRangeTable class IPRangeView(generic.ObjectView): queryset = IPRange.objects.all() class IPRangeIPAddressesView(generic.ObjectChildrenView): queryset = IPRange.objects.all() child_model = IPAddress table = tables.IPAddressTable filterset = filtersets.IPAddressFilterSet template_name = 'ipam/iprange/ip_addresses.html' def get_children(self, request, parent): return parent.get_child_ips().restrict(request.user, 'view').prefetch_related( 'vrf', 'role', 'tenant', ) def get_extra_context(self, request, instance): return { 'active_tab': 'ip-addresses', } class IPRangeEditView(generic.ObjectEditView): queryset = IPRange.objects.all() form = forms.IPRangeForm class IPRangeDeleteView(generic.ObjectDeleteView): queryset = IPRange.objects.all() class IPRangeBulkImportView(generic.BulkImportView): queryset = IPRange.objects.all() model_form = forms.IPRangeCSVForm table = tables.IPRangeTable class IPRangeBulkEditView(generic.BulkEditView): queryset = IPRange.objects.prefetch_related('vrf', 'tenant') filterset = filtersets.IPRangeFilterSet table = tables.IPRangeTable form = forms.IPRangeBulkEditForm class IPRangeBulkDeleteView(generic.BulkDeleteView): queryset = IPRange.objects.prefetch_related('vrf', 'tenant') filterset = filtersets.IPRangeFilterSet table = tables.IPRangeTable # # IP addresses # class IPAddressListView(generic.ObjectListView): queryset = IPAddress.objects.all() filterset = filtersets.IPAddressFilterSet filterset_form = forms.IPAddressFilterForm table = tables.IPAddressTable class IPAddressView(generic.ObjectView): queryset = IPAddress.objects.prefetch_related('vrf__tenant', 'tenant') def get_extra_context(self, request, instance): # Parent prefixes table parent_prefixes = Prefix.objects.restrict(request.user, 'view').filter( vrf=instance.vrf, prefix__net_contains_or_equals=str(instance.address.ip) ).prefetch_related( 'site', 'role' ) parent_prefixes_table = tables.PrefixTable( list(parent_prefixes), exclude=('vrf', 'utilization'), orderable=False ) # Duplicate IPs table duplicate_ips = IPAddress.objects.restrict(request.user, 'view').filter( vrf=instance.vrf, address=str(instance.address) ).exclude( pk=instance.pk ).prefetch_related( 'nat_inside' ) # Exclude anycast IPs if this IP is anycast if instance.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(instance.address) ).filter( vrf=instance.vrf, address__net_contained_or_equal=str(instance.address) ) related_ips_table = tables.IPAddressTable(related_ips, orderable=False) related_ips_table.configure(request) return { '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(generic.ObjectEditView): queryset = IPAddress.objects.all() form = forms.IPAddressForm template_name = 'ipam/ipaddress_edit.html' def alter_object(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 elif 'fhrpgroup' in request.GET: try: obj.assigned_object = FHRPGroup.objects.get(pk=request.GET['fhrpgroup']) except (ValueError, FHRPGroup.DoesNotExist): pass return obj # TODO: Standardize or remove this view class IPAddressAssignView(generic.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 = filtersets.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(generic.ObjectDeleteView): queryset = IPAddress.objects.all() class IPAddressBulkCreateView(generic.BulkCreateView): queryset = IPAddress.objects.all() form = forms.IPAddressBulkCreateForm model_form = forms.IPAddressBulkAddForm pattern_target = 'address' template_name = 'ipam/ipaddress_bulk_add.html' class IPAddressBulkImportView(generic.BulkImportView): queryset = IPAddress.objects.all() model_form = forms.IPAddressCSVForm table = tables.IPAddressTable class IPAddressBulkEditView(generic.BulkEditView): queryset = IPAddress.objects.prefetch_related('vrf__tenant', 'tenant') filterset = filtersets.IPAddressFilterSet table = tables.IPAddressTable form = forms.IPAddressBulkEditForm class IPAddressBulkDeleteView(generic.BulkDeleteView): queryset = IPAddress.objects.prefetch_related('vrf__tenant', 'tenant') filterset = filtersets.IPAddressFilterSet table = tables.IPAddressTable # # VLAN groups # class VLANGroupListView(generic.ObjectListView): queryset = VLANGroup.objects.annotate( vlan_count=count_related(VLAN, 'group') ) filterset = filtersets.VLANGroupFilterSet filterset_form = forms.VLANGroupFilterForm table = tables.VLANGroupTable class VLANGroupView(generic.ObjectView): queryset = VLANGroup.objects.all() def get_extra_context(self, request, instance): vlans = VLAN.objects.restrict(request.user, 'view').filter(group=instance).prefetch_related( Prefetch('prefixes', queryset=Prefix.objects.restrict(request.user)) ).order_by('vid') vlans_count = vlans.count() vlans = add_available_vlans(vlans, vlan_group=instance) vlans_table = tables.VLANTable(vlans, exclude=('group',)) if request.user.has_perm('ipam.change_vlan') or request.user.has_perm('ipam.delete_vlan'): vlans_table.columns.show('pk') vlans_table.configure(request) # 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 { 'vlans_count': vlans_count, 'vlans_table': vlans_table, 'permissions': permissions, } class VLANGroupEditView(generic.ObjectEditView): queryset = VLANGroup.objects.all() form = forms.VLANGroupForm class VLANGroupDeleteView(generic.ObjectDeleteView): queryset = VLANGroup.objects.all() class VLANGroupBulkImportView(generic.BulkImportView): queryset = VLANGroup.objects.all() model_form = forms.VLANGroupCSVForm table = tables.VLANGroupTable class VLANGroupBulkEditView(generic.BulkEditView): queryset = VLANGroup.objects.annotate( vlan_count=count_related(VLAN, 'group') ) filterset = filtersets.VLANGroupFilterSet table = tables.VLANGroupTable form = forms.VLANGroupBulkEditForm class VLANGroupBulkDeleteView(generic.BulkDeleteView): queryset = VLANGroup.objects.annotate( vlan_count=count_related(VLAN, 'group') ) filterset = filtersets.VLANGroupFilterSet table = tables.VLANGroupTable # # FHRP groups # class FHRPGroupListView(generic.ObjectListView): queryset = FHRPGroup.objects.annotate( member_count=count_related(FHRPGroupAssignment, 'group') ) filterset = filtersets.FHRPGroupFilterSet filterset_form = forms.FHRPGroupFilterForm table = tables.FHRPGroupTable class FHRPGroupView(generic.ObjectView): queryset = FHRPGroup.objects.all() def get_extra_context(self, request, instance): # Get assigned IP addresses ipaddress_table = tables.AssignedIPAddressesTable( data=instance.ip_addresses.restrict(request.user, 'view').prefetch_related('vrf', 'tenant'), orderable=False ) # Get assigned interfaces members_table = tables.FHRPGroupAssignmentTable( data=FHRPGroupAssignment.objects.restrict(request.user, 'view').filter(group=instance), orderable=False ) members_table.columns.hide('group') return { 'ipaddress_table': ipaddress_table, 'members_table': members_table, 'member_count': FHRPGroupAssignment.objects.filter(group=instance).count(), } class FHRPGroupEditView(generic.ObjectEditView): queryset = FHRPGroup.objects.all() form = forms.FHRPGroupForm template_name = 'ipam/fhrpgroup_edit.html' def get_return_url(self, request, obj=None): return_url = super().get_return_url(request, obj) # If we're redirecting the user to the FHRPGroupAssignment creation form, # initialize the group field with the FHRPGroup we just saved. if return_url.startswith(reverse('ipam:fhrpgroupassignment_add')): return_url += f'&group={obj.pk}' return return_url class FHRPGroupDeleteView(generic.ObjectDeleteView): queryset = FHRPGroup.objects.all() class FHRPGroupBulkImportView(generic.BulkImportView): queryset = FHRPGroup.objects.all() model_form = forms.FHRPGroupCSVForm table = tables.FHRPGroupTable class FHRPGroupBulkEditView(generic.BulkEditView): queryset = FHRPGroup.objects.all() filterset = filtersets.FHRPGroupFilterSet table = tables.FHRPGroupTable form = forms.FHRPGroupBulkEditForm class FHRPGroupBulkDeleteView(generic.BulkDeleteView): queryset = FHRPGroup.objects.all() filterset = filtersets.FHRPGroupFilterSet table = tables.FHRPGroupTable # # FHRP group assignments # class FHRPGroupAssignmentEditView(generic.ObjectEditView): queryset = FHRPGroupAssignment.objects.all() form = forms.FHRPGroupAssignmentForm template_name = 'ipam/fhrpgroupassignment_edit.html' def alter_object(self, instance, request, args, kwargs): if not instance.pk: # Assign the interface based on URL kwargs content_type = get_object_or_404(ContentType, pk=request.GET.get('interface_type')) instance.interface = get_object_or_404(content_type.model_class(), pk=request.GET.get('interface_id')) return instance class FHRPGroupAssignmentDeleteView(generic.ObjectDeleteView): queryset = FHRPGroupAssignment.objects.all() # # VLANs # class VLANListView(generic.ObjectListView): queryset = VLAN.objects.all() filterset = filtersets.VLANFilterSet filterset_form = forms.VLANFilterForm table = tables.VLANTable class VLANView(generic.ObjectView): queryset = VLAN.objects.prefetch_related('site__region', 'tenant__group', 'role') def get_extra_context(self, request, instance): prefixes = Prefix.objects.restrict(request.user, 'view').filter(vlan=instance).prefetch_related( 'vrf', 'site', 'role' ) prefix_table = tables.PrefixTable(list(prefixes), exclude=('vlan', 'utilization'), orderable=False) return { 'prefix_table': prefix_table, } class VLANInterfacesView(generic.ObjectChildrenView): queryset = VLAN.objects.all() child_model = Interface table = tables.VLANDevicesTable filterset = InterfaceFilterSet template_name = 'ipam/vlan/interfaces.html' def get_children(self, request, parent): return parent.get_interfaces().restrict(request.user, 'view') def get_extra_context(self, request, instance): return { 'active_tab': 'interfaces', } class VLANVMInterfacesView(generic.ObjectChildrenView): queryset = VLAN.objects.all() child_model = VMInterface table = tables.VLANVirtualMachinesTable filterset = VMInterfaceFilterSet template_name = 'ipam/vlan/vminterfaces.html' def get_children(self, request, parent): return parent.get_vminterfaces().restrict(request.user, 'view') def get_extra_context(self, request, instance): return { 'active_tab': 'vminterfaces', } class VLANEditView(generic.ObjectEditView): queryset = VLAN.objects.all() form = forms.VLANForm template_name = 'ipam/vlan_edit.html' class VLANDeleteView(generic.ObjectDeleteView): queryset = VLAN.objects.all() class VLANBulkImportView(generic.BulkImportView): queryset = VLAN.objects.all() model_form = forms.VLANCSVForm table = tables.VLANTable class VLANBulkEditView(generic.BulkEditView): queryset = VLAN.objects.prefetch_related('site', 'group', 'tenant', 'role') filterset = filtersets.VLANFilterSet table = tables.VLANTable form = forms.VLANBulkEditForm class VLANBulkDeleteView(generic.BulkDeleteView): queryset = VLAN.objects.prefetch_related('site', 'group', 'tenant', 'role') filterset = filtersets.VLANFilterSet table = tables.VLANTable # # Service templates # class ServiceTemplateListView(generic.ObjectListView): queryset = ServiceTemplate.objects.all() filterset = filtersets.ServiceTemplateFilterSet filterset_form = forms.ServiceTemplateFilterForm table = tables.ServiceTemplateTable class ServiceTemplateView(generic.ObjectView): queryset = ServiceTemplate.objects.all() class ServiceTemplateEditView(generic.ObjectEditView): queryset = ServiceTemplate.objects.all() form = forms.ServiceTemplateForm class ServiceTemplateDeleteView(generic.ObjectDeleteView): queryset = ServiceTemplate.objects.all() class ServiceTemplateBulkImportView(generic.BulkImportView): queryset = ServiceTemplate.objects.all() model_form = forms.ServiceTemplateCSVForm table = tables.ServiceTemplateTable class ServiceTemplateBulkEditView(generic.BulkEditView): queryset = ServiceTemplate.objects.all() filterset = filtersets.ServiceTemplateFilterSet table = tables.ServiceTemplateTable form = forms.ServiceTemplateBulkEditForm class ServiceTemplateBulkDeleteView(generic.BulkDeleteView): queryset = ServiceTemplate.objects.all() filterset = filtersets.ServiceTemplateFilterSet table = tables.ServiceTemplateTable # # Services # class ServiceListView(generic.ObjectListView): queryset = Service.objects.all() filterset = filtersets.ServiceFilterSet filterset_form = forms.ServiceFilterForm table = tables.ServiceTable class ServiceView(generic.ObjectView): queryset = Service.objects.prefetch_related('ipaddresses') class ServiceCreateView(generic.ObjectEditView): queryset = Service.objects.all() form = forms.ServiceCreateForm template_name = 'ipam/service_create.html' class ServiceEditView(generic.ObjectEditView): queryset = Service.objects.prefetch_related('ipaddresses') form = forms.ServiceForm template_name = 'ipam/service_edit.html' class ServiceDeleteView(generic.ObjectDeleteView): queryset = Service.objects.all() class ServiceBulkImportView(generic.BulkImportView): queryset = Service.objects.all() model_form = forms.ServiceCSVForm table = tables.ServiceTable class ServiceBulkEditView(generic.BulkEditView): queryset = Service.objects.prefetch_related('device', 'virtual_machine') filterset = filtersets.ServiceFilterSet table = tables.ServiceTable form = forms.ServiceBulkEditForm class ServiceBulkDeleteView(generic.BulkDeleteView): queryset = Service.objects.prefetch_related('device', 'virtual_machine') filterset = filtersets.ServiceFilterSet table = tables.ServiceTable