diff --git a/netbox/circuits/search_indexes.py b/netbox/circuits/search_indexes.py new file mode 100644 index 000000000..91cc291da --- /dev/null +++ b/netbox/circuits/search_indexes.py @@ -0,0 +1,41 @@ +import dcim.filtersets +import dcim.tables +from circuits.models import Circuit, Provider, ProviderNetwork +from django.db import models +from search.models import SearchMixin + + +class ProviderIndex(SearchMixin): + def __init__(self): + self.model = Provider + self.queryset = (Provider.objects.annotate(count_circuits=count_related(Circuit, 'provider')),) + self.filterset = circuits.filtersets.ProviderFilterSet + self.table = circuits.tables.ProviderTable + self.url = 'circuits:provider_list' + + +class CircuitIndex(SearchMixin): + def __init__(self): + self.model = Circuit + self.queryset = Circuit.objects.prefetch_related( + 'type', 'provider', 'tenant', 'tenant__group', 'terminations__site' + ) + self.filterset = circuits.filtersets.CircuitFilterSet + self.table = circuits.tables.CircuitTable + self.url = 'circuits:circuit_list' + + +class ProviderNetworkIndex(SearchMixin): + def __init__(self): + self.model = ProviderNetwork + self.queryset = ProviderNetwork.objects.prefetch_related('provider') + self.filterset = circuits.filtersets.ProviderNetworkFilterSet + self.table = circuits.tables.ProviderNetworkTable + self.url = 'circuits:providernetwork_list' + + +CIRCUIT_SEARCH_TYPES = { + 'provider': ProviderIndex(), + 'circuit': CircuitIndex(), + 'providernetwork': ProviderNetworkIndex(), +} diff --git a/netbox/dcim/search_indexes.py b/netbox/dcim/search_indexes.py index 9ec82fe4e..b95768c79 100644 --- a/netbox/dcim/search_indexes.py +++ b/netbox/dcim/search_indexes.py @@ -19,130 +19,152 @@ from search.models import SearchMixin class SiteIndex(SearchMixin): - model = Site - queryset = Site.objects.prefetch_related('region', 'tenant', 'tenant__group') - filterset = dcim.filtersets.SiteFilterSet - table = dcim.tables.SiteTable - url = 'dcim:site_list' + + def __init__(self): + self.model = Site + self.queryset = Site.objects.prefetch_related('region', 'tenant', 'tenant__group') + self.filterset = dcim.filtersets.SiteFilterSet + self.table = dcim.tables.SiteTable + self.url = 'dcim:site_list' class RackIndex(SearchMixin): - model = Rack - queryset = Rack.objects.prefetch_related('site', 'location', 'tenant', 'tenant__group', 'role').annotate( - device_count=count_related(Device, 'rack') - ) - filterset = dcim.filtersets.RackFilterSet - table = dcim.tables.RackTable - url = 'dcim:rack_list' + + def __init__(self): + self.model = Rack + self.queryset = Rack.objects.prefetch_related('site', 'location', 'tenant', 'tenant__group', 'role').annotate( + device_count=count_related(Device, 'rack') + ) + self.filterset = dcim.filtersets.RackFilterSet + self.table = dcim.tables.RackTable + self.url = 'dcim:rack_list' class RackReservationIndex(SearchMixin): - model = RackReservation - queryset = RackReservation.objects.prefetch_related('rack', 'user') - filterset = dcim.filtersets.RackReservationFilterSet - table = dcim.tables.RackReservationTable - url = 'dcim:rackreservation_list' + + def __init__(self): + self.model = RackReservation + self.queryset = RackReservation.objects.prefetch_related('rack', 'user') + self.filterset = dcim.filtersets.RackReservationFilterSet + self.table = dcim.tables.RackReservationTable + self.url = 'dcim:rackreservation_list' class LocationIndex(SearchMixin): - model = Site - queryset = Location.objects.add_related_count( - Location.objects.add_related_count(Location.objects.all(), Device, 'location', 'device_count', cumulative=True), - Rack, - 'location', - 'rack_count', - cumulative=True, - ).prefetch_related('site') - filterset = dcim.filtersets.LocationFilterSet - table = dcim.tables.LocationTable - url = 'dcim:location_list' + + def __init__(self): + self.model = Site + self.queryset = Location.objects.add_related_count( + Location.objects.add_related_count(Location.objects.all(), Device, 'location', 'device_count', cumulative=True), + Rack, + 'location', + 'rack_count', + cumulative=True, + ).prefetch_related('site') + self.filterset = dcim.filtersets.LocationFilterSet + self.table = dcim.tables.LocationTable + self.url = 'dcim:location_list' class DeviceTypeIndex(SearchMixin): - model = DeviceType - queryset = DeviceType.objects.prefetch_related('manufacturer').annotate( - instance_count=count_related(Device, 'device_type') - ) - filterset = dcim.filtersets.DeviceTypeFilterSet - table = dcim.tables.DeviceTypeTable - url = 'dcim:devicetype_list' + + def __init__(self): + self.model = DeviceType + self.queryset = DeviceType.objects.prefetch_related('manufacturer').annotate( + instance_count=count_related(Device, 'device_type') + ) + self.filterset = dcim.filtersets.DeviceTypeFilterSet + self.table = dcim.tables.DeviceTypeTable + self.url = 'dcim:devicetype_list' class DeviceIndex(SearchMixin): - model = DeviceIndex - queryset = Device.objects.prefetch_related( - 'device_type__manufacturer', - 'device_role', - 'tenant', - 'tenant__group', - 'site', - 'rack', - 'primary_ip4', - 'primary_ip6', - ) - filterset = dcim.filtersets.DeviceFilterSet - table = dcim.tables.DeviceTable - url = 'dcim:device_list' + + def __init__(self): + self.model = DeviceIndex + self.queryset = Device.objects.prefetch_related( + 'device_type__manufacturer', + 'device_role', + 'tenant', + 'tenant__group', + 'site', + 'rack', + 'primary_ip4', + 'primary_ip6', + ) + self.filterset = dcim.filtersets.DeviceFilterSet + self.table = dcim.tables.DeviceTable + self.url = 'dcim:device_list' class ModuleTypeIndex(SearchMixin): - model = ModuleType - queryset = ModuleType.objects.prefetch_related('manufacturer').annotate( - instance_count=count_related(Module, 'module_type') - ) - filterset = dcim.filtersets.ModuleTypeFilterSet - table = dcim.tables.ModuleTypeTable - url = 'dcim:moduletype_list' + + def __init__(self): + self.model = ModuleType + self.queryset = ModuleType.objects.prefetch_related('manufacturer').annotate( + instance_count=count_related(Module, 'module_type') + ) + self.filterset = dcim.filtersets.ModuleTypeFilterSet + self.table = dcim.tables.ModuleTypeTable + self.url = 'dcim:moduletype_list' class ModuleIndex(SearchMixin): - model = Module - queryset = Module.objects.prefetch_related( - 'module_type__manufacturer', - 'device', - 'module_bay', - ) - filterset = dcim.filtersets.ModuleFilterSet - table = dcim.tables.ModuleTable - url = 'dcim:module_list' + + def __init__(self): + self.model = Module + self.queryset = Module.objects.prefetch_related( + 'module_type__manufacturer', + 'device', + 'module_bay', + ) + self.filterset = dcim.filtersets.ModuleFilterSet + self.table = dcim.tables.ModuleTable + self.url = 'dcim:module_list' class VirtualChassisIndex(SearchMixin): - model = VirtualChassis - queryset = VirtualChassis.objects.prefetch_related('master').annotate( - member_count=count_related(Device, 'virtual_chassis') - ) - filterset = dcim.filtersets.VirtualChassisFilterSet - table = dcim.tables.VirtualChassisTable - url = 'dcim:virtualchassis_list' + + def __init__(self): + self.model = VirtualChassis + self.queryset = VirtualChassis.objects.prefetch_related('master').annotate( + member_count=count_related(Device, 'virtual_chassis') + ) + self.filterset = dcim.filtersets.VirtualChassisFilterSet + self.table = dcim.tables.VirtualChassisTable + self.url = 'dcim:virtualchassis_list' class CableIndex(SearchMixin): - model = Cable - queryset = Cable.objects.all() - filterset = dcim.filtersets.CableFilterSet - table = dcim.tables.CableTable - url = 'dcim:cable_list' + + def __init__(self): + self.model = Cable + self.queryset = Cable.objects.all() + self.filterset = dcim.filtersets.CableFilterSet + self.table = dcim.tables.CableTable + self.url = 'dcim:cable_list' class PowerFeedIndex(SearchMixin): - model = PowerFeed - queryset = PowerFeed.objects.all() - filterset = dcim.filtersets.PowerFeedFilterSet - table = dcim.tables.PowerFeedTable - url = 'dcim:powerfeed_list' + + def __init__(self): + self.model = PowerFeed + self.queryset = PowerFeed.objects.all() + self.filterset = dcim.filtersets.PowerFeedFilterSet + self.table = dcim.tables.PowerFeedTable + self.url = 'dcim:powerfeed_list' -DCIM_SEARCH_ORDERING = [ - SiteIndex, - RackIndex, - RackReservationIndex, - LocationIndex, - DeviceTypeIndex, - DeviceIndex, - ModuleTypeIndex, - ModuleIndex, - VirtualChassisIndex, - CableIndex, - PowerFeedIndex, -] +DCIM_SEARCH_TYPES = { + 'site': SiteIndex(), + 'rack': RackIndex(), + 'rackreservation': RackReservationIndex(), + 'location': LocationIndex(), + 'devicetype': DeviceTypeIndex(), + 'device': DeviceIndex(), + 'moduletype': ModuleTypeIndex(), + 'module': ModuleIndex(), + 'virtualchassis': VirtualChassisIndex(), + 'cable': CableIndex(), + 'powerfeed': PowerFeedIndex(), +} diff --git a/netbox/ipam/search_indexes.py b/netbox/ipam/search_indexes.py new file mode 100644 index 000000000..e8f759713 --- /dev/null +++ b/netbox/ipam/search_indexes.py @@ -0,0 +1,81 @@ +import dcim.filtersets +import dcim.tables +from dcim.models import ASN, VLAN, VRF, Aggregate, IPAddress, Prefix, Service +from django.db import models +from search.models import SearchMixin + + +class VRFIndex(SearchMixin): + def __init__(self): + self.model = VRF + self.queryset = VRF.objects.prefetch_related('tenant', 'tenant__group') + self.filterset = ipam.filtersets.VRFFilterSet + self.table = ipam.tables.VRFTable + self.url = 'ipam:vrf_list' + + +class AggregateIndex(SearchMixin): + def __init__(self): + self.model = Aggregate + self.queryset = Aggregate.objects.prefetch_related('rir') + self.filterset = ipam.filtersets.AggregateFilterSet + self.table = ipam.tables.AggregateTable + self.url = 'ipam:aggregate_list' + + +class PrefixIndex(SearchMixin): + def __init__(self): + self.model = Prefix + self.queryset = Prefix.objects.prefetch_related( + 'site', 'vrf__tenant', 'tenant', 'tenant__group', 'vlan', 'role' + ) + self.filterset = ipam.filtersets.PrefixFilterSet + self.table = ipam.tables.PrefixTable + self.url = 'ipam:prefix_list' + + +class IPAddressIndex(SearchMixin): + def __init__(self): + self.model = IPAddress + self.queryset = IPAddress.objects.prefetch_related('vrf__tenant', 'tenant', 'tenant__group') + self.filterset = ipam.filtersets.IPAddressFilterSet + self.table = ipam.tables.IPAddressTable + self.url = 'ipam:ipaddress_list' + + +class VLANIndex(SearchMixin): + def __init__(self): + self.model = VLAN + self.queryset = VLAN.objects.prefetch_related('site', 'group', 'tenant', 'tenant__group', 'role') + self.filterset = ipam.filtersets.VLANFilterSet + self.table = ipam.tables.VLANTable + self.url = 'ipam:vlan_list' + + +class ASNIndex(SearchMixin): + def __init__(self): + self.model = ASN + self.queryset = ASN.objects.prefetch_related('rir', 'tenant', 'tenant__group') + self.filterset = ipam.filtersets.ASNFilterSet + self.table = ipam.tables.ASNTable + self.url = 'ipam:asn_list' + + +class ServiceIndex(SearchMixin): + def __init__(self): + self.model = Service + self.queryset = Service.objects.prefetch_related('device', 'virtual_machine') + self.filterset = ipam.filtersets.ServiceFilterSet + self.table = ipam.tables.ServiceTable + self.url = 'ipam:service_list' + + +IPAM_SEARCH_TYPES = { + 'vrf': VRFIndex(), + 'aggregate': AggregateIndex(), + 'prefix': PrefixIndex(), + 'ipaddress': IPAddressIndex(), + 'vlan': VLANIndex(), + 'asn': ASNIndex(), + 'service': ServiceIndex(), +} diff --git a/netbox/search/models.py b/netbox/search/models.py index 78f65d8c0..248c1e3ca 100644 --- a/netbox/search/models.py +++ b/netbox/search/models.py @@ -2,19 +2,17 @@ from django.core.exceptions import ImproperlyConfigured from django.db import models -class SearchMixin(models.Model): +class SearchMixin(object): """ Base class for building search indexes. """ - model = None - queryset = None - filterset = None - table = None - url = None - - class Meta: - abstract = True + def __init__(self, model=None, queryset=None, filterset=None, table=None, url=None): + self.model = model + self.queryset = queryset + self.filterset = filterset + self.table = table + self.url = url def get_model(self): """ @@ -26,8 +24,7 @@ class SearchMixin(models.Model): model = self.model else: raise ImproperlyConfigured( - f"{self.__class__.__name__}s is missing a Model. Define " - f"{self.__class__.__name__}s.model or override " + f"{self.__class__.__name__}s is missing a Model. Set model in init or override" f"{self.__class__.__name__}s.get_model()." ) @@ -43,8 +40,7 @@ class SearchMixin(models.Model): queryset = self.queryset else: raise ImproperlyConfigured( - f"{self.__class__.__name__}s is missing a QuerySet. Define " - f"{self.__class__.__name__}s.queryset or override " + f"{self.__class__.__name__}s is missing a QuerySet. Set queryset in init or override " f"{self.__class__.__name__}s.get_queryset()." ) @@ -60,8 +56,7 @@ class SearchMixin(models.Model): filterset = self.filterset else: raise ImproperlyConfigured( - f"{self.__class__.__name__}s is missing a FilterSet. Define " - f"{self.__class__.__name__}s.filterset or override " + f"{self.__class__.__name__}s is missing a FilterSet. Set filterset in init or override " f"{self.__class__.__name__}s.get_filterset()." ) @@ -77,8 +72,7 @@ class SearchMixin(models.Model): table = self.table else: raise ImproperlyConfigured( - f"{self.__class__.__name__}s is missing a Table. Define " - f"{self.__class__.__name__}s.table or override " + f"{self.__class__.__name__}s is missing a Table. Set table in init or override " f"{self.__class__.__name__}s.get_table()." ) @@ -94,8 +88,7 @@ class SearchMixin(models.Model): url = self.url else: raise ImproperlyConfigured( - f"{self.__class__.__name__}s is missing a URL. Define " - f"{self.__class__.__name__}s.url or override " + f"{self.__class__.__name__}s is missing a URL. Set url in init or override " f"{self.__class__.__name__}s.get_url()." )