import django_filters from django.contrib.contenttypes.models import ContentType from django.utils.translation import gettext as _ from drf_spectacular.types import OpenApiTypes from drf_spectacular.utils import extend_schema_field from circuits.models import CircuitTermination from extras.filtersets import LocalConfigContextFilterSet from extras.models import ConfigTemplate from ipam.filtersets import PrimaryIPFilterSet from ipam.models import ASN, IPAddress, VRF from netbox.choices import ColorChoices from netbox.filtersets import ( BaseFilterSet, ChangeLoggedModelFilterSet, OrganizationalModelFilterSet, NetBoxModelFilterSet, ) from tenancy.filtersets import TenancyFilterSet, ContactModelFilterSet from tenancy.models import * from users.models import User from utilities.filters import ( ContentTypeFilter, MultiValueCharFilter, MultiValueMACAddressFilter, MultiValueNumberFilter, MultiValueWWNFilter, NumericArrayFilter, TreeNodeMultipleChoiceFilter, ) from virtualization.models import Cluster, ClusterGroup from vpn.models import L2VPN from wireless.choices import WirelessRoleChoices, WirelessChannelChoices from wireless.models import WirelessLAN, WirelessLink from .choices import * from .constants import * from .models import * __all__ = ( 'CableFilterSet', 'CabledObjectFilterSet', 'CableTerminationFilterSet', 'CommonInterfaceFilterSet', 'ConsoleConnectionFilterSet', 'ConsolePortFilterSet', 'ConsolePortTemplateFilterSet', 'ConsoleServerPortFilterSet', 'ConsoleServerPortTemplateFilterSet', 'DeviceBayFilterSet', 'DeviceBayTemplateFilterSet', 'DeviceFilterSet', 'DeviceRoleFilterSet', 'DeviceTypeFilterSet', 'FrontPortFilterSet', 'FrontPortTemplateFilterSet', 'InterfaceConnectionFilterSet', 'InterfaceFilterSet', 'InterfaceTemplateFilterSet', 'InventoryItemFilterSet', 'InventoryItemRoleFilterSet', 'InventoryItemTemplateFilterSet', 'LocationFilterSet', 'ManufacturerFilterSet', 'ModuleBayFilterSet', 'ModuleBayTemplateFilterSet', 'ModuleFilterSet', 'ModuleTypeFilterSet', 'PathEndpointFilterSet', 'PlatformFilterSet', 'PowerConnectionFilterSet', 'PowerFeedFilterSet', 'PowerOutletFilterSet', 'PowerOutletTemplateFilterSet', 'PowerPanelFilterSet', 'PowerPortFilterSet', 'PowerPortTemplateFilterSet', 'RackFilterSet', 'RackReservationFilterSet', 'RackRoleFilterSet', 'RackTypeFilterSet', 'RearPortFilterSet', 'RearPortTemplateFilterSet', 'RegionFilterSet', 'SiteFilterSet', 'SiteGroupFilterSet', 'VirtualChassisFilterSet', 'VirtualDeviceContextFilterSet', ) class RegionFilterSet(OrganizationalModelFilterSet, ContactModelFilterSet): parent_id = django_filters.ModelMultipleChoiceFilter( queryset=Region.objects.all(), label=_('Parent region (ID)'), ) parent = django_filters.ModelMultipleChoiceFilter( field_name='parent__slug', queryset=Region.objects.all(), to_field_name='slug', label=_('Parent region (slug)'), ) ancestor_id = TreeNodeMultipleChoiceFilter( queryset=Region.objects.all(), field_name='parent', lookup_expr='in', label=_('Region (ID)'), ) ancestor = TreeNodeMultipleChoiceFilter( queryset=Region.objects.all(), field_name='parent', lookup_expr='in', to_field_name='slug', label=_('Region (slug)'), ) class Meta: model = Region fields = ('id', 'name', 'slug', 'description') class SiteGroupFilterSet(OrganizationalModelFilterSet, ContactModelFilterSet): parent_id = django_filters.ModelMultipleChoiceFilter( queryset=SiteGroup.objects.all(), label=_('Parent site group (ID)'), ) parent = django_filters.ModelMultipleChoiceFilter( field_name='parent__slug', queryset=SiteGroup.objects.all(), to_field_name='slug', label=_('Parent site group (slug)'), ) ancestor_id = TreeNodeMultipleChoiceFilter( queryset=SiteGroup.objects.all(), field_name='parent', lookup_expr='in', label=_('Site group (ID)'), ) ancestor = TreeNodeMultipleChoiceFilter( queryset=SiteGroup.objects.all(), field_name='parent', lookup_expr='in', to_field_name='slug', label=_('Site group (slug)'), ) class Meta: model = SiteGroup fields = ('id', 'name', 'slug', 'description') class SiteFilterSet(NetBoxModelFilterSet, TenancyFilterSet, ContactModelFilterSet): status = django_filters.MultipleChoiceFilter( choices=SiteStatusChoices, null_value=None ) region_id = TreeNodeMultipleChoiceFilter( queryset=Region.objects.all(), field_name='region', lookup_expr='in', label=_('Region (ID)'), ) region = TreeNodeMultipleChoiceFilter( queryset=Region.objects.all(), lookup_expr='in', to_field_name='slug', label=_('Region (slug)'), ) group_id = TreeNodeMultipleChoiceFilter( queryset=SiteGroup.objects.all(), field_name='group', lookup_expr='in', label=_('Group (ID)'), ) group = TreeNodeMultipleChoiceFilter( queryset=SiteGroup.objects.all(), lookup_expr='in', to_field_name='slug', label=_('Group (slug)'), ) asn = django_filters.ModelMultipleChoiceFilter( field_name='asns__asn', queryset=ASN.objects.all(), to_field_name='asn', label=_('AS (ID)'), ) asn_id = django_filters.ModelMultipleChoiceFilter( field_name='asns', queryset=ASN.objects.all(), label=_('AS (ID)'), ) time_zone = MultiValueCharFilter() class Meta: model = Site fields = ('id', 'name', 'slug', 'facility', 'latitude', 'longitude', 'description') def search(self, queryset, name, value): if not value.strip(): return queryset qs_filter = ( Q(name__icontains=value) | Q(facility__icontains=value) | Q(description__icontains=value) | Q(physical_address__icontains=value) | Q(shipping_address__icontains=value) | Q(comments__icontains=value) ) try: qs_filter |= Q(asns__asn=int(value.strip())) except ValueError: pass return queryset.filter(qs_filter).distinct() class LocationFilterSet(TenancyFilterSet, ContactModelFilterSet, OrganizationalModelFilterSet): region_id = TreeNodeMultipleChoiceFilter( queryset=Region.objects.all(), field_name='site__region', lookup_expr='in', label=_('Region (ID)'), ) region = TreeNodeMultipleChoiceFilter( queryset=Region.objects.all(), field_name='site__region', lookup_expr='in', to_field_name='slug', label=_('Region (slug)'), ) site_group_id = TreeNodeMultipleChoiceFilter( queryset=SiteGroup.objects.all(), field_name='site__group', lookup_expr='in', label=_('Site group (ID)'), ) site_group = TreeNodeMultipleChoiceFilter( queryset=SiteGroup.objects.all(), field_name='site__group', lookup_expr='in', to_field_name='slug', label=_('Site group (slug)'), ) site_id = django_filters.ModelMultipleChoiceFilter( queryset=Site.objects.all(), label=_('Site (ID)'), ) site = django_filters.ModelMultipleChoiceFilter( field_name='site__slug', queryset=Site.objects.all(), to_field_name='slug', label=_('Site (slug)'), ) parent_id = django_filters.ModelMultipleChoiceFilter( queryset=Location.objects.all(), label=_('Parent location (ID)'), ) parent = django_filters.ModelMultipleChoiceFilter( field_name='parent__slug', queryset=Location.objects.all(), to_field_name='slug', label=_('Parent location (slug)'), ) ancestor_id = TreeNodeMultipleChoiceFilter( queryset=Location.objects.all(), field_name='parent', lookup_expr='in', label=_('Location (ID)'), ) ancestor = TreeNodeMultipleChoiceFilter( queryset=Location.objects.all(), field_name='parent', lookup_expr='in', to_field_name='slug', label=_('Location (slug)'), ) status = django_filters.MultipleChoiceFilter( choices=LocationStatusChoices, null_value=None ) class Meta: model = Location fields = ('id', 'name', 'slug', 'facility', 'description') def search(self, queryset, name, value): if not value.strip(): return queryset return queryset.filter( Q(name__icontains=value) | Q(facility__icontains=value) | Q(description__icontains=value) ) class RackRoleFilterSet(OrganizationalModelFilterSet): class Meta: model = RackRole fields = ('id', 'name', 'slug', 'color', 'description') class RackTypeFilterSet(NetBoxModelFilterSet): manufacturer_id = django_filters.ModelMultipleChoiceFilter( queryset=Manufacturer.objects.all(), label=_('Manufacturer (ID)'), ) manufacturer = django_filters.ModelMultipleChoiceFilter( field_name='manufacturer__slug', queryset=Manufacturer.objects.all(), to_field_name='slug', label=_('Manufacturer (slug)'), ) form_factor = django_filters.MultipleChoiceFilter( choices=RackFormFactorChoices ) width = django_filters.MultipleChoiceFilter( choices=RackWidthChoices ) class Meta: model = RackType fields = ( 'id', 'model', 'slug', 'u_height', 'starting_unit', 'desc_units', 'outer_width', 'outer_depth', 'outer_unit', 'mounting_depth', 'weight', 'max_weight', 'weight_unit', 'description', ) def search(self, queryset, name, value): if not value.strip(): return queryset return queryset.filter( Q(model__icontains=value) | Q(description__icontains=value) | Q(comments__icontains=value) ) class RackFilterSet(NetBoxModelFilterSet, TenancyFilterSet, ContactModelFilterSet): region_id = TreeNodeMultipleChoiceFilter( queryset=Region.objects.all(), field_name='site__region', lookup_expr='in', label=_('Region (ID)'), ) region = TreeNodeMultipleChoiceFilter( queryset=Region.objects.all(), field_name='site__region', lookup_expr='in', to_field_name='slug', label=_('Region (slug)'), ) site_group_id = TreeNodeMultipleChoiceFilter( queryset=SiteGroup.objects.all(), field_name='site__group', lookup_expr='in', label=_('Site group (ID)'), ) site_group = TreeNodeMultipleChoiceFilter( queryset=SiteGroup.objects.all(), field_name='site__group', lookup_expr='in', to_field_name='slug', label=_('Site group (slug)'), ) site_id = django_filters.ModelMultipleChoiceFilter( queryset=Site.objects.all(), label=_('Site (ID)'), ) site = django_filters.ModelMultipleChoiceFilter( field_name='site__slug', queryset=Site.objects.all(), to_field_name='slug', label=_('Site (slug)'), ) location_id = TreeNodeMultipleChoiceFilter( queryset=Location.objects.all(), field_name='location', lookup_expr='in', label=_('Location (ID)'), ) location = TreeNodeMultipleChoiceFilter( queryset=Location.objects.all(), field_name='location', lookup_expr='in', to_field_name='slug', label=_('Location (slug)'), ) manufacturer_id = django_filters.ModelMultipleChoiceFilter( field_name='rack_type__manufacturer', queryset=Manufacturer.objects.all(), label=_('Manufacturer (ID)'), ) manufacturer = django_filters.ModelMultipleChoiceFilter( field_name='rack_type__manufacturer__slug', queryset=Manufacturer.objects.all(), to_field_name='slug', label=_('Manufacturer (slug)'), ) rack_type = django_filters.ModelMultipleChoiceFilter( field_name='rack_type__slug', queryset=RackType.objects.all(), to_field_name='slug', label=_('Rack type (slug)'), ) rack_type_id = django_filters.ModelMultipleChoiceFilter( queryset=RackType.objects.all(), label=_('Rack type (ID)'), ) status = django_filters.MultipleChoiceFilter( choices=RackStatusChoices, null_value=None ) form_factor = django_filters.MultipleChoiceFilter( choices=RackFormFactorChoices ) width = django_filters.MultipleChoiceFilter( choices=RackWidthChoices ) role_id = django_filters.ModelMultipleChoiceFilter( queryset=RackRole.objects.all(), label=_('Role (ID)'), ) role = django_filters.ModelMultipleChoiceFilter( field_name='role__slug', queryset=RackRole.objects.all(), to_field_name='slug', label=_('Role (slug)'), ) serial = MultiValueCharFilter( lookup_expr='iexact' ) class Meta: model = Rack fields = ( 'id', 'name', 'facility_id', 'asset_tag', 'u_height', 'starting_unit', 'desc_units', 'outer_width', 'outer_depth', 'outer_unit', 'mounting_depth', 'airflow', 'weight', 'max_weight', 'weight_unit', 'description', ) def search(self, queryset, name, value): if not value.strip(): return queryset return queryset.filter( Q(name__icontains=value) | Q(facility_id__icontains=value) | Q(serial__icontains=value.strip()) | Q(asset_tag__icontains=value.strip()) | Q(description__icontains=value) | Q(comments__icontains=value) ) class RackReservationFilterSet(NetBoxModelFilterSet, TenancyFilterSet): rack_id = django_filters.ModelMultipleChoiceFilter( queryset=Rack.objects.all(), label=_('Rack (ID)'), ) site_id = django_filters.ModelMultipleChoiceFilter( field_name='rack__site', queryset=Site.objects.all(), label=_('Site (ID)'), ) site = django_filters.ModelMultipleChoiceFilter( field_name='rack__site__slug', queryset=Site.objects.all(), to_field_name='slug', label=_('Site (slug)'), ) region_id = TreeNodeMultipleChoiceFilter( queryset=Region.objects.all(), field_name='rack__site__region', lookup_expr='in', label=_('Region (ID)'), ) region = TreeNodeMultipleChoiceFilter( queryset=Region.objects.all(), field_name='rack__site__region', lookup_expr='in', to_field_name='slug', label=_('Region (slug)'), ) site_group_id = TreeNodeMultipleChoiceFilter( queryset=SiteGroup.objects.all(), field_name='rack__site__group', lookup_expr='in', label=_('Site group (ID)'), ) site_group = TreeNodeMultipleChoiceFilter( queryset=SiteGroup.objects.all(), field_name='rack__site__group', lookup_expr='in', to_field_name='slug', label=_('Site group (slug)'), ) location_id = TreeNodeMultipleChoiceFilter( queryset=Location.objects.all(), field_name='rack__location', lookup_expr='in', label=_('Location (ID)'), ) location = TreeNodeMultipleChoiceFilter( queryset=Location.objects.all(), field_name='rack__location', lookup_expr='in', to_field_name='slug', label=_('Location (slug)'), ) user_id = django_filters.ModelMultipleChoiceFilter( queryset=User.objects.all(), label=_('User (ID)'), ) user = django_filters.ModelMultipleChoiceFilter( field_name='user__username', queryset=User.objects.all(), to_field_name='username', label=_('User (name)'), ) unit = NumericArrayFilter( field_name='units', lookup_expr='contains' ) class Meta: model = RackReservation fields = ('id', 'created', 'description') def search(self, queryset, name, value): if not value.strip(): return queryset return queryset.filter( Q(rack__name__icontains=value) | Q(rack__facility_id__icontains=value) | Q(user__username__icontains=value) | Q(description__icontains=value) ) class ManufacturerFilterSet(OrganizationalModelFilterSet, ContactModelFilterSet): class Meta: model = Manufacturer fields = ('id', 'name', 'slug', 'description') class DeviceTypeFilterSet(NetBoxModelFilterSet): manufacturer_id = django_filters.ModelMultipleChoiceFilter( queryset=Manufacturer.objects.all(), label=_('Manufacturer (ID)'), ) manufacturer = django_filters.ModelMultipleChoiceFilter( field_name='manufacturer__slug', queryset=Manufacturer.objects.all(), to_field_name='slug', label=_('Manufacturer (slug)'), ) default_platform_id = django_filters.ModelMultipleChoiceFilter( queryset=Platform.objects.all(), label=_('Default platform (ID)'), ) default_platform = django_filters.ModelMultipleChoiceFilter( field_name='default_platform__slug', queryset=Platform.objects.all(), to_field_name='slug', label=_('Default platform (slug)'), ) has_front_image = django_filters.BooleanFilter( label=_('Has a front image'), method='_has_front_image' ) has_rear_image = django_filters.BooleanFilter( label=_('Has a rear image'), method='_has_rear_image' ) console_ports = django_filters.BooleanFilter( method='_console_ports', label=_('Has console ports'), ) console_server_ports = django_filters.BooleanFilter( method='_console_server_ports', label=_('Has console server ports'), ) power_ports = django_filters.BooleanFilter( method='_power_ports', label=_('Has power ports'), ) power_outlets = django_filters.BooleanFilter( method='_power_outlets', label=_('Has power outlets'), ) interfaces = django_filters.BooleanFilter( method='_interfaces', label=_('Has interfaces'), ) pass_through_ports = django_filters.BooleanFilter( method='_pass_through_ports', label=_('Has pass-through ports'), ) module_bays = django_filters.BooleanFilter( method='_module_bays', label=_('Has module bays'), ) device_bays = django_filters.BooleanFilter( method='_device_bays', label=_('Has device bays'), ) inventory_items = django_filters.BooleanFilter( method='_inventory_items', label=_('Has inventory items'), ) class Meta: model = DeviceType fields = ( 'id', 'model', 'slug', 'part_number', 'u_height', 'exclude_from_utilization', 'is_full_depth', 'subdevice_role', 'airflow', 'weight', 'weight_unit', 'description', # Counters 'console_port_template_count', 'console_server_port_template_count', 'power_port_template_count', 'power_outlet_template_count', 'interface_template_count', 'front_port_template_count', 'rear_port_template_count', 'device_bay_template_count', 'module_bay_template_count', 'inventory_item_template_count', ) def search(self, queryset, name, value): if not value.strip(): return queryset return queryset.filter( Q(manufacturer__name__icontains=value) | Q(model__icontains=value) | Q(part_number__icontains=value) | Q(description__icontains=value) | Q(comments__icontains=value) ) def _has_front_image(self, queryset, name, value): if value: return queryset.exclude(front_image='') else: return queryset.filter(front_image='') def _has_rear_image(self, queryset, name, value): if value: return queryset.exclude(rear_image='') else: return queryset.filter(rear_image='') def _console_ports(self, queryset, name, value): return queryset.exclude(consoleporttemplates__isnull=value) def _console_server_ports(self, queryset, name, value): return queryset.exclude(consoleserverporttemplates__isnull=value) def _power_ports(self, queryset, name, value): return queryset.exclude(powerporttemplates__isnull=value) def _power_outlets(self, queryset, name, value): return queryset.exclude(poweroutlettemplates__isnull=value) def _interfaces(self, queryset, name, value): return queryset.exclude(interfacetemplates__isnull=value) def _pass_through_ports(self, queryset, name, value): return queryset.exclude( frontporttemplates__isnull=value, rearporttemplates__isnull=value ) def _module_bays(self, queryset, name, value): return queryset.exclude(modulebaytemplates__isnull=value) def _device_bays(self, queryset, name, value): return queryset.exclude(devicebaytemplates__isnull=value) def _inventory_items(self, queryset, name, value): return queryset.exclude(inventoryitemtemplates__isnull=value) class ModuleTypeFilterSet(NetBoxModelFilterSet): manufacturer_id = django_filters.ModelMultipleChoiceFilter( queryset=Manufacturer.objects.all(), label=_('Manufacturer (ID)'), ) manufacturer = django_filters.ModelMultipleChoiceFilter( field_name='manufacturer__slug', queryset=Manufacturer.objects.all(), to_field_name='slug', label=_('Manufacturer (slug)'), ) console_ports = django_filters.BooleanFilter( method='_console_ports', label=_('Has console ports'), ) console_server_ports = django_filters.BooleanFilter( method='_console_server_ports', label=_('Has console server ports'), ) power_ports = django_filters.BooleanFilter( method='_power_ports', label=_('Has power ports'), ) power_outlets = django_filters.BooleanFilter( method='_power_outlets', label=_('Has power outlets'), ) interfaces = django_filters.BooleanFilter( method='_interfaces', label=_('Has interfaces'), ) pass_through_ports = django_filters.BooleanFilter( method='_pass_through_ports', label=_('Has pass-through ports'), ) class Meta: model = ModuleType fields = ('id', 'model', 'part_number', 'airflow', 'weight', 'weight_unit', 'description') def search(self, queryset, name, value): if not value.strip(): return queryset return queryset.filter( Q(manufacturer__name__icontains=value) | Q(model__icontains=value) | Q(part_number__icontains=value) | Q(description__icontains=value) | Q(comments__icontains=value) ) def _console_ports(self, queryset, name, value): return queryset.exclude(consoleporttemplates__isnull=value) def _console_server_ports(self, queryset, name, value): return queryset.exclude(consoleserverporttemplates__isnull=value) def _power_ports(self, queryset, name, value): return queryset.exclude(powerporttemplates__isnull=value) def _power_outlets(self, queryset, name, value): return queryset.exclude(poweroutlettemplates__isnull=value) def _interfaces(self, queryset, name, value): return queryset.exclude(interfacetemplates__isnull=value) def _pass_through_ports(self, queryset, name, value): return queryset.exclude( frontporttemplates__isnull=value, rearporttemplates__isnull=value ) class DeviceTypeComponentFilterSet(django_filters.FilterSet): q = django_filters.CharFilter( method='search', label=_('Search'), ) device_type_id = django_filters.ModelMultipleChoiceFilter( queryset=DeviceType.objects.all(), field_name='device_type_id', label=_('Device type (ID)'), ) def search(self, queryset, name, value): if not value.strip(): return queryset return queryset.filter( Q(name__icontains=value) | Q(description__icontains=value) ) class ModularDeviceTypeComponentFilterSet(DeviceTypeComponentFilterSet): module_type_id = django_filters.ModelMultipleChoiceFilter( queryset=ModuleType.objects.all(), field_name='module_type_id', label=_('Module type (ID)'), ) class ConsolePortTemplateFilterSet(ChangeLoggedModelFilterSet, ModularDeviceTypeComponentFilterSet): class Meta: model = ConsolePortTemplate fields = ('id', 'name', 'label', 'type', 'description') class ConsoleServerPortTemplateFilterSet(ChangeLoggedModelFilterSet, ModularDeviceTypeComponentFilterSet): class Meta: model = ConsoleServerPortTemplate fields = ('id', 'name', 'label', 'type', 'description') class PowerPortTemplateFilterSet(ChangeLoggedModelFilterSet, ModularDeviceTypeComponentFilterSet): class Meta: model = PowerPortTemplate fields = ('id', 'name', 'label', 'type', 'maximum_draw', 'allocated_draw', 'description') class PowerOutletTemplateFilterSet(ChangeLoggedModelFilterSet, ModularDeviceTypeComponentFilterSet): feed_leg = django_filters.MultipleChoiceFilter( choices=PowerOutletFeedLegChoices, null_value=None ) power_port_id = django_filters.ModelMultipleChoiceFilter( queryset=PowerPortTemplate.objects.all(), label=_('Power port (ID)'), ) class Meta: model = PowerOutletTemplate fields = ('id', 'name', 'label', 'type', 'feed_leg', 'description') class InterfaceTemplateFilterSet(ChangeLoggedModelFilterSet, ModularDeviceTypeComponentFilterSet): type = django_filters.MultipleChoiceFilter( choices=InterfaceTypeChoices, null_value=None ) bridge_id = django_filters.ModelMultipleChoiceFilter( field_name='bridge', queryset=InterfaceTemplate.objects.all() ) poe_mode = django_filters.MultipleChoiceFilter( choices=InterfacePoEModeChoices ) poe_type = django_filters.MultipleChoiceFilter( choices=InterfacePoETypeChoices ) rf_role = django_filters.MultipleChoiceFilter( choices=WirelessRoleChoices ) class Meta: model = InterfaceTemplate fields = ('id', 'name', 'label', 'type', 'enabled', 'mgmt_only', 'description') class FrontPortTemplateFilterSet(ChangeLoggedModelFilterSet, ModularDeviceTypeComponentFilterSet): type = django_filters.MultipleChoiceFilter( choices=PortTypeChoices, null_value=None ) rear_port_id = django_filters.ModelMultipleChoiceFilter( queryset=RearPort.objects.all() ) class Meta: model = FrontPortTemplate fields = ('id', 'name', 'label', 'type', 'color', 'rear_port_position', 'description') class RearPortTemplateFilterSet(ChangeLoggedModelFilterSet, ModularDeviceTypeComponentFilterSet): type = django_filters.MultipleChoiceFilter( choices=PortTypeChoices, null_value=None ) class Meta: model = RearPortTemplate fields = ('id', 'name', 'label', 'type', 'color', 'positions', 'description') class ModuleBayTemplateFilterSet(ChangeLoggedModelFilterSet, ModularDeviceTypeComponentFilterSet): class Meta: model = ModuleBayTemplate fields = ('id', 'name', 'label', 'position', 'description') class DeviceBayTemplateFilterSet(ChangeLoggedModelFilterSet, DeviceTypeComponentFilterSet): class Meta: model = DeviceBayTemplate fields = ('id', 'name', 'label', 'description') class InventoryItemTemplateFilterSet(ChangeLoggedModelFilterSet, DeviceTypeComponentFilterSet): parent_id = django_filters.ModelMultipleChoiceFilter( queryset=InventoryItemTemplate.objects.all(), label=_('Parent inventory item (ID)'), ) manufacturer_id = django_filters.ModelMultipleChoiceFilter( queryset=Manufacturer.objects.all(), label=_('Manufacturer (ID)'), ) manufacturer = django_filters.ModelMultipleChoiceFilter( field_name='manufacturer__slug', queryset=Manufacturer.objects.all(), to_field_name='slug', label=_('Manufacturer (slug)'), ) role_id = django_filters.ModelMultipleChoiceFilter( queryset=InventoryItemRole.objects.all(), label=_('Role (ID)'), ) role = django_filters.ModelMultipleChoiceFilter( field_name='role__slug', queryset=InventoryItemRole.objects.all(), to_field_name='slug', label=_('Role (slug)'), ) component_type = ContentTypeFilter() component_id = MultiValueNumberFilter() class Meta: model = InventoryItemTemplate fields = ('id', 'name', 'label', 'part_id', 'description') def search(self, queryset, name, value): if not value.strip(): return queryset qs_filter = ( Q(name__icontains=value) | Q(part_id__icontains=value) | Q(description__icontains=value) ) return queryset.filter(qs_filter) class DeviceRoleFilterSet(OrganizationalModelFilterSet): config_template_id = django_filters.ModelMultipleChoiceFilter( queryset=ConfigTemplate.objects.all(), label=_('Config template (ID)'), ) class Meta: model = DeviceRole fields = ('id', 'name', 'slug', 'color', 'vm_role', 'description') class PlatformFilterSet(OrganizationalModelFilterSet): manufacturer_id = django_filters.ModelMultipleChoiceFilter( field_name='manufacturer', queryset=Manufacturer.objects.all(), label=_('Manufacturer (ID)'), ) manufacturer = django_filters.ModelMultipleChoiceFilter( field_name='manufacturer__slug', queryset=Manufacturer.objects.all(), to_field_name='slug', label=_('Manufacturer (slug)'), ) available_for_device_type = django_filters.ModelChoiceFilter( queryset=DeviceType.objects.all(), method='get_for_device_type' ) config_template_id = django_filters.ModelMultipleChoiceFilter( queryset=ConfigTemplate.objects.all(), label=_('Config template (ID)'), ) class Meta: model = Platform fields = ('id', 'name', 'slug', 'description') @extend_schema_field(OpenApiTypes.STR) def get_for_device_type(self, queryset, name, value): """ Return all Platforms available for a specific manufacturer based on device type and Platforms not assigned any manufacturer """ return queryset.filter(Q(manufacturer=None) | Q(manufacturer__device_types=value)) class DeviceFilterSet( NetBoxModelFilterSet, TenancyFilterSet, ContactModelFilterSet, LocalConfigContextFilterSet, PrimaryIPFilterSet, ): manufacturer_id = django_filters.ModelMultipleChoiceFilter( field_name='device_type__manufacturer', queryset=Manufacturer.objects.all(), label=_('Manufacturer (ID)'), ) manufacturer = django_filters.ModelMultipleChoiceFilter( field_name='device_type__manufacturer__slug', queryset=Manufacturer.objects.all(), to_field_name='slug', label=_('Manufacturer (slug)'), ) device_type = django_filters.ModelMultipleChoiceFilter( field_name='device_type__slug', queryset=DeviceType.objects.all(), to_field_name='slug', label=_('Device type (slug)'), ) device_type_id = django_filters.ModelMultipleChoiceFilter( queryset=DeviceType.objects.all(), label=_('Device type (ID)'), ) role_id = django_filters.ModelMultipleChoiceFilter( field_name='role_id', queryset=DeviceRole.objects.all(), label=_('Role (ID)'), ) role = django_filters.ModelMultipleChoiceFilter( field_name='role__slug', queryset=DeviceRole.objects.all(), to_field_name='slug', label=_('Role (slug)'), ) parent_device_id = django_filters.ModelMultipleChoiceFilter( field_name='parent_bay__device', queryset=Device.objects.all(), label=_('Parent Device (ID)'), ) platform_id = django_filters.ModelMultipleChoiceFilter( queryset=Platform.objects.all(), label=_('Platform (ID)'), ) platform = django_filters.ModelMultipleChoiceFilter( field_name='platform__slug', queryset=Platform.objects.all(), to_field_name='slug', label=_('Platform (slug)'), ) region_id = TreeNodeMultipleChoiceFilter( queryset=Region.objects.all(), field_name='site__region', lookup_expr='in', label=_('Region (ID)'), ) region = TreeNodeMultipleChoiceFilter( queryset=Region.objects.all(), field_name='site__region', lookup_expr='in', to_field_name='slug', label=_('Region (slug)'), ) site_group_id = TreeNodeMultipleChoiceFilter( queryset=SiteGroup.objects.all(), field_name='site__group', lookup_expr='in', label=_('Site group (ID)'), ) site_group = TreeNodeMultipleChoiceFilter( queryset=SiteGroup.objects.all(), field_name='site__group', lookup_expr='in', to_field_name='slug', label=_('Site group (slug)'), ) site_id = django_filters.ModelMultipleChoiceFilter( queryset=Site.objects.all(), label=_('Site (ID)'), ) site = django_filters.ModelMultipleChoiceFilter( field_name='site__slug', queryset=Site.objects.all(), to_field_name='slug', label=_('Site name (slug)'), ) location_id = TreeNodeMultipleChoiceFilter( queryset=Location.objects.all(), field_name='location', lookup_expr='in', label=_('Location (ID)'), ) rack_id = django_filters.ModelMultipleChoiceFilter( field_name='rack', queryset=Rack.objects.all(), label=_('Rack (ID)'), ) parent_bay_id = django_filters.ModelMultipleChoiceFilter( field_name='parent_bay', queryset=DeviceBay.objects.all(), label=_('Parent bay (ID)'), ) cluster_id = django_filters.ModelMultipleChoiceFilter( queryset=Cluster.objects.all(), label=_('VM cluster (ID)'), ) cluster_group = django_filters.ModelMultipleChoiceFilter( field_name='cluster__group__slug', queryset=ClusterGroup.objects.all(), to_field_name='slug', label=_('Cluster group (slug)'), ) cluster_group_id = django_filters.ModelMultipleChoiceFilter( field_name='cluster__group', queryset=ClusterGroup.objects.all(), label=_('Cluster group (ID)'), ) model = django_filters.ModelMultipleChoiceFilter( field_name='device_type__slug', queryset=DeviceType.objects.all(), to_field_name='slug', label=_('Device model (slug)'), ) name = MultiValueCharFilter( lookup_expr='iexact' ) status = django_filters.MultipleChoiceFilter( choices=DeviceStatusChoices, null_value=None ) is_full_depth = django_filters.BooleanFilter( field_name='device_type__is_full_depth', label=_('Is full depth'), ) mac_address = MultiValueMACAddressFilter( field_name='interfaces__mac_address', label=_('MAC address'), ) serial = MultiValueCharFilter( lookup_expr='iexact' ) has_primary_ip = django_filters.BooleanFilter( method='_has_primary_ip', label=_('Has a primary IP'), ) has_oob_ip = django_filters.BooleanFilter( method='_has_oob_ip', label=_('Has an out-of-band IP'), ) virtual_chassis_id = django_filters.ModelMultipleChoiceFilter( field_name='virtual_chassis', queryset=VirtualChassis.objects.all(), label=_('Virtual chassis (ID)'), ) virtual_chassis_member = django_filters.BooleanFilter( method='_virtual_chassis_member', label=_('Is a virtual chassis member') ) config_template_id = django_filters.ModelMultipleChoiceFilter( queryset=ConfigTemplate.objects.all(), label=_('Config template (ID)'), ) console_ports = django_filters.BooleanFilter( method='_console_ports', label=_('Has console ports'), ) console_server_ports = django_filters.BooleanFilter( method='_console_server_ports', label=_('Has console server ports'), ) power_ports = django_filters.BooleanFilter( method='_power_ports', label=_('Has power ports'), ) power_outlets = django_filters.BooleanFilter( method='_power_outlets', label=_('Has power outlets'), ) interfaces = django_filters.BooleanFilter( method='_interfaces', label=_('Has interfaces'), ) pass_through_ports = django_filters.BooleanFilter( method='_pass_through_ports', label=_('Has pass-through ports'), ) module_bays = django_filters.BooleanFilter( method='_module_bays', label=_('Has module bays'), ) device_bays = django_filters.BooleanFilter( method='_device_bays', label=_('Has device bays'), ) oob_ip_id = django_filters.ModelMultipleChoiceFilter( field_name='oob_ip', queryset=IPAddress.objects.all(), label=_('OOB IP (ID)'), ) has_virtual_device_context = django_filters.BooleanFilter( method='_has_virtual_device_context', label=_('Has virtual device context'), ) class Meta: model = Device fields = ( 'id', 'asset_tag', 'face', 'position', 'latitude', 'longitude', 'airflow', 'vc_position', 'vc_priority', 'description', # Counters 'console_port_count', 'console_server_port_count', 'power_port_count', 'power_outlet_count', 'interface_count', 'front_port_count', 'rear_port_count', 'device_bay_count', 'module_bay_count', 'inventory_item_count', ) def search(self, queryset, name, value): if not value.strip(): return queryset return queryset.filter( Q(name__icontains=value) | Q(serial__icontains=value.strip()) | Q(inventoryitems__serial__icontains=value.strip()) | Q(asset_tag__icontains=value.strip()) | Q(description__icontains=value.strip()) | Q(comments__icontains=value) | Q(primary_ip4__address__startswith=value) | Q(primary_ip6__address__startswith=value) ).distinct() def _has_primary_ip(self, queryset, name, value): params = Q(primary_ip4__isnull=False) | Q(primary_ip6__isnull=False) if value: return queryset.filter(params) return queryset.exclude(params) def _has_oob_ip(self, queryset, name, value): params = Q(oob_ip__isnull=False) if value: return queryset.filter(params) return queryset.exclude(params) def _virtual_chassis_member(self, queryset, name, value): return queryset.exclude(virtual_chassis__isnull=value) def _console_ports(self, queryset, name, value): return queryset.exclude(consoleports__isnull=value) def _console_server_ports(self, queryset, name, value): return queryset.exclude(consoleserverports__isnull=value) def _power_ports(self, queryset, name, value): return queryset.exclude(powerports__isnull=value) def _power_outlets(self, queryset, name, value): return queryset.exclude(poweroutlets__isnull=value) def _interfaces(self, queryset, name, value): return queryset.exclude(interfaces__isnull=value) def _pass_through_ports(self, queryset, name, value): return queryset.exclude( frontports__isnull=value, rearports__isnull=value ) def _module_bays(self, queryset, name, value): return queryset.exclude(modulebays__isnull=value) def _device_bays(self, queryset, name, value): return queryset.exclude(devicebays__isnull=value) def _has_virtual_device_context(self, queryset, name, value): params = Q(vdcs__isnull=False) if value: return queryset.filter(params).distinct() return queryset.exclude(params) class VirtualDeviceContextFilterSet(NetBoxModelFilterSet, TenancyFilterSet, PrimaryIPFilterSet): device_id = django_filters.ModelMultipleChoiceFilter( field_name='device', queryset=Device.objects.all(), label=_('VDC (ID)') ) device = django_filters.ModelMultipleChoiceFilter( field_name='device', queryset=Device.objects.all(), label=_('Device model') ) interface_id = django_filters.ModelMultipleChoiceFilter( field_name='interfaces', queryset=Interface.objects.all(), label=_('Interface (ID)') ) status = django_filters.MultipleChoiceFilter( choices=VirtualDeviceContextStatusChoices ) has_primary_ip = django_filters.BooleanFilter( method='_has_primary_ip', label=_('Has a primary IP') ) class Meta: model = VirtualDeviceContext fields = ('id', 'device', 'name', 'identifier', 'description') def search(self, queryset, name, value): if not value.strip(): return queryset qs_filter = ( Q(name__icontains=value) | Q(description__icontains=value) ) try: qs_filter |= Q(identifier=int(value)) except ValueError: pass return queryset.filter(qs_filter).distinct() def _has_primary_ip(self, queryset, name, value): params = Q(primary_ip4__isnull=False) | Q(primary_ip6__isnull=False) if value: return queryset.filter(params) return queryset.exclude(params) class ModuleFilterSet(NetBoxModelFilterSet): manufacturer_id = django_filters.ModelMultipleChoiceFilter( field_name='module_type__manufacturer', queryset=Manufacturer.objects.all(), label=_('Manufacturer (ID)'), ) manufacturer = django_filters.ModelMultipleChoiceFilter( field_name='module_type__manufacturer__slug', queryset=Manufacturer.objects.all(), to_field_name='slug', label=_('Manufacturer (slug)'), ) module_type_id = django_filters.ModelMultipleChoiceFilter( field_name='module_type', queryset=ModuleType.objects.all(), label=_('Module type (ID)'), ) module_type = django_filters.ModelMultipleChoiceFilter( field_name='module_type__model', queryset=ModuleType.objects.all(), to_field_name='model', label=_('Module type (model)'), ) module_bay_id = TreeNodeMultipleChoiceFilter( queryset=ModuleBay.objects.all(), field_name='module_bay', lookup_expr='in', label=_('Module bay (ID)'), ) device_id = django_filters.ModelMultipleChoiceFilter( queryset=Device.objects.all(), label=_('Device (ID)'), ) status = django_filters.MultipleChoiceFilter( choices=ModuleStatusChoices, null_value=None ) serial = MultiValueCharFilter( lookup_expr='iexact' ) class Meta: model = Module fields = ('id', 'status', 'asset_tag', 'description') def search(self, queryset, name, value): if not value.strip(): return queryset return queryset.filter( Q(device__name__icontains=value.strip()) | Q(serial__icontains=value.strip()) | Q(asset_tag__icontains=value.strip()) | Q(description__icontains=value) | Q(comments__icontains=value) ).distinct() class DeviceComponentFilterSet(django_filters.FilterSet): q = django_filters.CharFilter( method='search', label=_('Search'), ) region_id = TreeNodeMultipleChoiceFilter( queryset=Region.objects.all(), field_name='device__site__region', lookup_expr='in', label=_('Region (ID)'), ) region = TreeNodeMultipleChoiceFilter( queryset=Region.objects.all(), field_name='device__site__region', lookup_expr='in', to_field_name='slug', label=_('Region (slug)'), ) site_group_id = TreeNodeMultipleChoiceFilter( queryset=SiteGroup.objects.all(), field_name='device__site__group', lookup_expr='in', label=_('Site group (ID)'), ) site_group = TreeNodeMultipleChoiceFilter( queryset=SiteGroup.objects.all(), field_name='device__site__group', lookup_expr='in', to_field_name='slug', label=_('Site group (slug)'), ) site_id = django_filters.ModelMultipleChoiceFilter( field_name='device__site', queryset=Site.objects.all(), label=_('Site (ID)'), ) site = django_filters.ModelMultipleChoiceFilter( field_name='device__site__slug', queryset=Site.objects.all(), to_field_name='slug', label=_('Site name (slug)'), ) location_id = django_filters.ModelMultipleChoiceFilter( field_name='device__location', queryset=Location.objects.all(), label=_('Location (ID)'), ) location = django_filters.ModelMultipleChoiceFilter( field_name='device__location__slug', queryset=Location.objects.all(), to_field_name='slug', label=_('Location (slug)'), ) rack_id = django_filters.ModelMultipleChoiceFilter( field_name='device__rack', queryset=Rack.objects.all(), label=_('Rack (ID)'), ) rack = django_filters.ModelMultipleChoiceFilter( field_name='device__rack__name', queryset=Rack.objects.all(), to_field_name='name', label=_('Rack (name)'), ) device_id = django_filters.ModelMultipleChoiceFilter( queryset=Device.objects.all(), label=_('Device (ID)'), ) device = django_filters.ModelMultipleChoiceFilter( field_name='device__name', queryset=Device.objects.all(), to_field_name='name', label=_('Device (name)'), ) device_type_id = django_filters.ModelMultipleChoiceFilter( field_name='device__device_type', queryset=DeviceType.objects.all(), label=_('Device type (ID)'), ) device_type = django_filters.ModelMultipleChoiceFilter( field_name='device__device_type__model', queryset=DeviceType.objects.all(), to_field_name='model', label=_('Device type (model)'), ) device_role_id = django_filters.ModelMultipleChoiceFilter( field_name='device__role', queryset=DeviceRole.objects.all(), label=_('Device role (ID)'), ) device_role = django_filters.ModelMultipleChoiceFilter( field_name='device__role__slug', queryset=DeviceRole.objects.all(), to_field_name='slug', label=_('Device role (slug)'), ) virtual_chassis_id = django_filters.ModelMultipleChoiceFilter( field_name='device__virtual_chassis', queryset=VirtualChassis.objects.all(), label=_('Virtual Chassis (ID)') ) virtual_chassis = django_filters.ModelMultipleChoiceFilter( field_name='device__virtual_chassis__name', queryset=VirtualChassis.objects.all(), to_field_name='name', label=_('Virtual Chassis'), ) device_status = django_filters.MultipleChoiceFilter( choices=DeviceStatusChoices, field_name='device__status', ) def search(self, queryset, name, value): if not value.strip(): return queryset return queryset.filter( Q(name__icontains=value) | Q(label__icontains=value) | Q(description__icontains=value) ) class ModularDeviceComponentFilterSet(DeviceComponentFilterSet): """ Extends DeviceComponentFilterSet to add a module_id filter for components which can be associated with a particular module within a device. """ module_id = django_filters.ModelMultipleChoiceFilter( queryset=Module.objects.all(), label=_('Module (ID)'), ) class CabledObjectFilterSet(django_filters.FilterSet): cable_id = django_filters.ModelMultipleChoiceFilter( queryset=Cable.objects.all(), label=_('Cable (ID)'), ) cabled = django_filters.BooleanFilter( field_name='cable', lookup_expr='isnull', exclude=True ) occupied = django_filters.BooleanFilter( method='filter_occupied' ) def filter_occupied(self, queryset, name, value): if value: return queryset.filter(Q(cable__isnull=False) | Q(mark_connected=True)) else: return queryset.filter(cable__isnull=True, mark_connected=False) class PathEndpointFilterSet(django_filters.FilterSet): connected = django_filters.BooleanFilter( method='filter_connected' ) def filter_connected(self, queryset, name, value): if value: return queryset.filter(_path__is_active=True) else: return queryset.filter(Q(_path__isnull=True) | Q(_path__is_active=False)) class ConsolePortFilterSet( ModularDeviceComponentFilterSet, NetBoxModelFilterSet, CabledObjectFilterSet, PathEndpointFilterSet ): type = django_filters.MultipleChoiceFilter( choices=ConsolePortTypeChoices, null_value=None ) class Meta: model = ConsolePort fields = ('id', 'name', 'label', 'speed', 'description', 'mark_connected', 'cable_end') class ConsoleServerPortFilterSet( ModularDeviceComponentFilterSet, NetBoxModelFilterSet, CabledObjectFilterSet, PathEndpointFilterSet ): type = django_filters.MultipleChoiceFilter( choices=ConsolePortTypeChoices, null_value=None ) class Meta: model = ConsoleServerPort fields = ('id', 'name', 'label', 'speed', 'description', 'mark_connected', 'cable_end') class PowerPortFilterSet( ModularDeviceComponentFilterSet, NetBoxModelFilterSet, CabledObjectFilterSet, PathEndpointFilterSet ): type = django_filters.MultipleChoiceFilter( choices=PowerPortTypeChoices, null_value=None ) class Meta: model = PowerPort fields = ( 'id', 'name', 'label', 'maximum_draw', 'allocated_draw', 'description', 'mark_connected', 'cable_end', ) class PowerOutletFilterSet( ModularDeviceComponentFilterSet, NetBoxModelFilterSet, CabledObjectFilterSet, PathEndpointFilterSet ): type = django_filters.MultipleChoiceFilter( choices=PowerOutletTypeChoices, null_value=None ) feed_leg = django_filters.MultipleChoiceFilter( choices=PowerOutletFeedLegChoices, null_value=None ) power_port_id = django_filters.ModelMultipleChoiceFilter( queryset=PowerPort.objects.all(), label=_('Power port (ID)'), ) class Meta: model = PowerOutlet fields = ( 'id', 'name', 'label', 'feed_leg', 'description', 'mark_connected', 'cable_end', ) class CommonInterfaceFilterSet(django_filters.FilterSet): vlan_id = django_filters.CharFilter( method='filter_vlan_id', label=_('Assigned VLAN') ) vlan = django_filters.CharFilter( method='filter_vlan', label=_('Assigned VID') ) vrf_id = django_filters.ModelMultipleChoiceFilter( field_name='vrf', queryset=VRF.objects.all(), label=_('VRF'), ) vrf = django_filters.ModelMultipleChoiceFilter( field_name='vrf__rd', queryset=VRF.objects.all(), to_field_name='rd', label=_('VRF (RD)'), ) l2vpn_id = django_filters.ModelMultipleChoiceFilter( field_name='l2vpn_terminations__l2vpn', queryset=L2VPN.objects.all(), label=_('L2VPN (ID)'), ) l2vpn = django_filters.ModelMultipleChoiceFilter( field_name='l2vpn_terminations__l2vpn__identifier', queryset=L2VPN.objects.all(), to_field_name='identifier', label=_('L2VPN'), ) def filter_vlan_id(self, queryset, name, value): value = value.strip() if not value: return queryset return queryset.filter( Q(untagged_vlan_id=value) | Q(tagged_vlans=value) ) def filter_vlan(self, queryset, name, value): value = value.strip() if not value: return queryset return queryset.filter( Q(untagged_vlan_id__vid=value) | Q(tagged_vlans__vid=value) ) class InterfaceFilterSet( ModularDeviceComponentFilterSet, NetBoxModelFilterSet, CabledObjectFilterSet, PathEndpointFilterSet, CommonInterfaceFilterSet ): virtual_chassis_member = MultiValueCharFilter( method='filter_virtual_chassis_member', field_name='name', label=_('Virtual Chassis Interfaces for Device') ) virtual_chassis_member_id = MultiValueNumberFilter( method='filter_virtual_chassis_member', field_name='pk', label=_('Virtual Chassis Interfaces for Device (ID)') ) kind = django_filters.CharFilter( method='filter_kind', label=_('Kind of interface'), ) parent_id = django_filters.ModelMultipleChoiceFilter( field_name='parent', queryset=Interface.objects.all(), label=_('Parent interface (ID)'), ) bridge_id = django_filters.ModelMultipleChoiceFilter( field_name='bridge', queryset=Interface.objects.all(), label=_('Bridged interface (ID)'), ) lag_id = django_filters.ModelMultipleChoiceFilter( field_name='lag', queryset=Interface.objects.all(), label=_('LAG interface (ID)'), ) speed = MultiValueNumberFilter() duplex = django_filters.MultipleChoiceFilter( choices=InterfaceDuplexChoices ) mac_address = MultiValueMACAddressFilter() wwn = MultiValueWWNFilter() poe_mode = django_filters.MultipleChoiceFilter( choices=InterfacePoEModeChoices ) poe_type = django_filters.MultipleChoiceFilter( choices=InterfacePoETypeChoices ) type = django_filters.MultipleChoiceFilter( choices=InterfaceTypeChoices, null_value=None ) rf_role = django_filters.MultipleChoiceFilter( choices=WirelessRoleChoices ) rf_channel = django_filters.MultipleChoiceFilter( choices=WirelessChannelChoices ) vdc_id = django_filters.ModelMultipleChoiceFilter( field_name='vdcs', queryset=VirtualDeviceContext.objects.all(), label=_('Virtual Device Context') ) vdc_identifier = django_filters.ModelMultipleChoiceFilter( field_name='vdcs__identifier', queryset=VirtualDeviceContext.objects.all(), to_field_name='identifier', label=_('Virtual Device Context (Identifier)') ) vdc = django_filters.ModelMultipleChoiceFilter( field_name='vdcs__name', queryset=VirtualDeviceContext.objects.all(), to_field_name='name', label=_('Virtual Device Context') ) wireless_lan_id = django_filters.ModelMultipleChoiceFilter( field_name='wireless_lans', queryset=WirelessLAN.objects.all(), label=_('Wireless LAN') ) wireless_link_id = django_filters.ModelMultipleChoiceFilter( queryset=WirelessLink.objects.all(), label=_('Wireless link') ) class Meta: model = Interface fields = ( 'id', 'name', 'label', 'type', 'enabled', 'mtu', 'mgmt_only', 'poe_mode', 'poe_type', 'mode', 'rf_role', 'rf_channel', 'rf_channel_frequency', 'rf_channel_width', 'tx_power', 'description', 'mark_connected', 'cable_id', 'cable_end', ) def filter_virtual_chassis_member(self, queryset, name, value): try: vc_interface_ids = [] for device in Device.objects.filter(**{f'{name}__in': value}): vc_interface_ids.extend(device.vc_interfaces(if_master=False).values_list('id', flat=True)) return queryset.filter(pk__in=vc_interface_ids) except Device.DoesNotExist: return queryset.none() def filter_kind(self, queryset, name, value): value = value.strip().lower() return { 'physical': queryset.exclude(type__in=NONCONNECTABLE_IFACE_TYPES), 'virtual': queryset.filter(type__in=VIRTUAL_IFACE_TYPES), 'wireless': queryset.filter(type__in=WIRELESS_IFACE_TYPES), }.get(value, queryset.none()) class FrontPortFilterSet( ModularDeviceComponentFilterSet, NetBoxModelFilterSet, CabledObjectFilterSet ): type = django_filters.MultipleChoiceFilter( choices=PortTypeChoices, null_value=None ) rear_port_id = django_filters.ModelMultipleChoiceFilter( queryset=RearPort.objects.all() ) class Meta: model = FrontPort fields = ( 'id', 'name', 'label', 'type', 'color', 'rear_port_position', 'description', 'mark_connected', 'cable_end', ) class RearPortFilterSet( ModularDeviceComponentFilterSet, NetBoxModelFilterSet, CabledObjectFilterSet ): type = django_filters.MultipleChoiceFilter( choices=PortTypeChoices, null_value=None ) class Meta: model = RearPort fields = ( 'id', 'name', 'label', 'type', 'color', 'positions', 'description', 'mark_connected', 'cable_end', ) class ModuleBayFilterSet(ModularDeviceComponentFilterSet, NetBoxModelFilterSet): parent_id = django_filters.ModelMultipleChoiceFilter( queryset=ModuleBay.objects.all(), label=_('Parent module bay (ID)'), ) installed_module_id = django_filters.ModelMultipleChoiceFilter( field_name='installed_module', queryset=ModuleBay.objects.all(), label=_('Installed module (ID)'), ) class Meta: model = ModuleBay fields = ('id', 'name', 'label', 'position', 'description') class DeviceBayFilterSet(DeviceComponentFilterSet, NetBoxModelFilterSet): installed_device_id = django_filters.ModelMultipleChoiceFilter( queryset=Device.objects.all(), label=_('Installed device (ID)'), ) installed_device = django_filters.ModelMultipleChoiceFilter( field_name='installed_device__name', queryset=Device.objects.all(), to_field_name='name', label=_('Installed device (name)'), ) class Meta: model = DeviceBay fields = ('id', 'name', 'label', 'description') class InventoryItemFilterSet(DeviceComponentFilterSet, NetBoxModelFilterSet): parent_id = django_filters.ModelMultipleChoiceFilter( queryset=InventoryItem.objects.all(), label=_('Parent inventory item (ID)'), ) manufacturer_id = django_filters.ModelMultipleChoiceFilter( queryset=Manufacturer.objects.all(), label=_('Manufacturer (ID)'), ) manufacturer = django_filters.ModelMultipleChoiceFilter( field_name='manufacturer__slug', queryset=Manufacturer.objects.all(), to_field_name='slug', label=_('Manufacturer (slug)'), ) role_id = django_filters.ModelMultipleChoiceFilter( queryset=InventoryItemRole.objects.all(), label=_('Role (ID)'), ) role = django_filters.ModelMultipleChoiceFilter( field_name='role__slug', queryset=InventoryItemRole.objects.all(), to_field_name='slug', label=_('Role (slug)'), ) component_type = ContentTypeFilter() component_id = MultiValueNumberFilter() serial = MultiValueCharFilter( lookup_expr='iexact' ) class Meta: model = InventoryItem fields = ('id', 'name', 'label', 'part_id', 'asset_tag', 'description', 'discovered') def search(self, queryset, name, value): if not value.strip(): return queryset qs_filter = ( Q(name__icontains=value) | Q(part_id__icontains=value) | Q(serial__icontains=value) | Q(asset_tag__icontains=value) | Q(description__icontains=value) ) return queryset.filter(qs_filter) class InventoryItemRoleFilterSet(OrganizationalModelFilterSet): class Meta: model = InventoryItemRole fields = ('id', 'name', 'slug', 'color', 'description') class VirtualChassisFilterSet(NetBoxModelFilterSet): master_id = django_filters.ModelMultipleChoiceFilter( queryset=Device.objects.all(), label=_('Master (ID)'), ) master = django_filters.ModelMultipleChoiceFilter( field_name='master__name', queryset=Device.objects.all(), to_field_name='name', label=_('Master (name)'), ) region_id = TreeNodeMultipleChoiceFilter( queryset=Region.objects.all(), field_name='master__site__region', lookup_expr='in', label=_('Region (ID)'), ) region = TreeNodeMultipleChoiceFilter( queryset=Region.objects.all(), field_name='master__site__region', lookup_expr='in', to_field_name='slug', label=_('Region (slug)'), ) site_group_id = TreeNodeMultipleChoiceFilter( queryset=SiteGroup.objects.all(), field_name='master__site__group', lookup_expr='in', label=_('Site group (ID)'), ) site_group = TreeNodeMultipleChoiceFilter( queryset=SiteGroup.objects.all(), field_name='master__site__group', lookup_expr='in', to_field_name='slug', label=_('Site group (slug)'), ) site_id = django_filters.ModelMultipleChoiceFilter( field_name='master__site', queryset=Site.objects.all(), label=_('Site (ID)'), ) site = django_filters.ModelMultipleChoiceFilter( field_name='master__site__slug', queryset=Site.objects.all(), to_field_name='slug', label=_('Site name (slug)'), ) tenant_id = django_filters.ModelMultipleChoiceFilter( field_name='master__tenant', queryset=Tenant.objects.all(), label=_('Tenant (ID)'), ) tenant = django_filters.ModelMultipleChoiceFilter( field_name='master__tenant__slug', queryset=Tenant.objects.all(), to_field_name='slug', label=_('Tenant (slug)'), ) class Meta: model = VirtualChassis fields = ('id', 'domain', 'name', 'description', 'member_count') def search(self, queryset, name, value): if not value.strip(): return queryset qs_filter = ( Q(name__icontains=value) | Q(description__icontains=value) | Q(members__name__icontains=value) | Q(domain__icontains=value) ) return queryset.filter(qs_filter).distinct() class CableFilterSet(TenancyFilterSet, NetBoxModelFilterSet): termination_a_type = ContentTypeFilter( field_name='terminations__termination_type' ) termination_a_id = MultiValueNumberFilter( method='filter_by_cable_end_a', field_name='terminations__termination_id' ) termination_b_type = ContentTypeFilter( field_name='terminations__termination_type' ) termination_b_id = MultiValueNumberFilter( method='filter_by_cable_end_b', field_name='terminations__termination_id' ) unterminated = django_filters.BooleanFilter( method='_unterminated', label=_('Unterminated'), ) type = django_filters.MultipleChoiceFilter( choices=CableTypeChoices ) status = django_filters.MultipleChoiceFilter( choices=LinkStatusChoices ) color = django_filters.MultipleChoiceFilter( choices=ColorChoices ) device_id = MultiValueNumberFilter( method='filter_by_termination' ) device = MultiValueCharFilter( method='filter_by_termination', field_name='device__name' ) rack_id = MultiValueNumberFilter( method='filter_by_termination', field_name='rack_id' ) rack = MultiValueCharFilter( method='filter_by_termination', field_name='rack__name' ) location_id = MultiValueNumberFilter( method='filter_by_termination', field_name='location_id' ) location = MultiValueCharFilter( method='filter_by_termination', field_name='location__name' ) site_id = MultiValueNumberFilter( method='filter_by_termination', field_name='site_id' ) site = MultiValueCharFilter( method='filter_by_termination', field_name='site__slug' ) # Termination object filters consoleport_id = MultiValueNumberFilter( method='filter_by_consoleport' ) consoleserverport_id = MultiValueNumberFilter( method='filter_by_consoleserverport' ) powerport_id = MultiValueNumberFilter( method='filter_by_powerport' ) poweroutlet_id = MultiValueNumberFilter( method='filter_by_poweroutlet' ) interface_id = MultiValueNumberFilter( method='filter_by_interface' ) frontport_id = MultiValueNumberFilter( method='filter_by_frontport' ) rearport_id = MultiValueNumberFilter( method='filter_by_rearport' ) powerfeed_id = MultiValueNumberFilter( method='filter_by_powerfeed' ) circuittermination_id = MultiValueNumberFilter( method='filter_by_circuittermination' ) class Meta: model = Cable fields = ('id', 'label', 'length', 'length_unit', 'description') def search(self, queryset, name, value): if not value.strip(): return queryset qs_filter = ( Q(label__icontains=value) | Q(description__icontains=value) ) return queryset.filter(qs_filter) def filter_by_termination(self, queryset, name, value): # Filter by a related object cached on CableTermination. Note the underscore preceding the field name. # Supported objects: device, rack, location, site return queryset.filter(**{f'terminations___{name}__in': value}).distinct() def filter_by_cable_end(self, queryset, name, value, side): # Filter by termination id and cable_end type return queryset.filter(**{f'{name}__in': value, 'terminations__cable_end': side}).distinct() def filter_by_cable_end_a(self, queryset, name, value): # Filter by termination id and cable_end type return self.filter_by_cable_end(queryset, name, value, CableEndChoices.SIDE_A) def filter_by_cable_end_b(self, queryset, name, value): # Filter by termination id and cable_end type return self.filter_by_cable_end(queryset, name, value, CableEndChoices.SIDE_B) def _unterminated(self, queryset, name, value): if value: terminated_ids = ( queryset.filter(terminations__cable_end=CableEndChoices.SIDE_A) .filter(terminations__cable_end=CableEndChoices.SIDE_B) .values("id") ) return queryset.exclude(id__in=terminated_ids) else: return queryset.filter(terminations__cable_end=CableEndChoices.SIDE_A).filter( terminations__cable_end=CableEndChoices.SIDE_B ) def filter_by_termination_object(self, queryset, model, value): # Filter by specific termination object(s) content_type = ContentType.objects.get_for_model(model) cable_ids = CableTermination.objects.filter( termination_type=content_type, termination_id__in=value ).values_list('cable', flat=True) return queryset.filter(pk__in=cable_ids) def filter_by_consoleport(self, queryset, name, value): return self.filter_by_termination_object(queryset, ConsolePort, value) def filter_by_consoleserverport(self, queryset, name, value): return self.filter_by_termination_object(queryset, ConsoleServerPort, value) def filter_by_powerport(self, queryset, name, value): return self.filter_by_termination_object(queryset, PowerPort, value) def filter_by_poweroutlet(self, queryset, name, value): return self.filter_by_termination_object(queryset, PowerOutlet, value) def filter_by_interface(self, queryset, name, value): return self.filter_by_termination_object(queryset, Interface, value) def filter_by_frontport(self, queryset, name, value): return self.filter_by_termination_object(queryset, FrontPort, value) def filter_by_rearport(self, queryset, name, value): return self.filter_by_termination_object(queryset, RearPort, value) def filter_by_powerfeed(self, queryset, name, value): return self.filter_by_termination_object(queryset, PowerFeed, value) def filter_by_circuittermination(self, queryset, name, value): return self.filter_by_termination_object(queryset, CircuitTermination, value) class CableTerminationFilterSet(ChangeLoggedModelFilterSet): termination_type = ContentTypeFilter() class Meta: model = CableTermination fields = ('id', 'cable', 'cable_end', 'termination_type', 'termination_id') class PowerPanelFilterSet(NetBoxModelFilterSet, ContactModelFilterSet): region_id = TreeNodeMultipleChoiceFilter( queryset=Region.objects.all(), field_name='site__region', lookup_expr='in', label=_('Region (ID)'), ) region = TreeNodeMultipleChoiceFilter( queryset=Region.objects.all(), field_name='site__region', lookup_expr='in', to_field_name='slug', label=_('Region (slug)'), ) site_group_id = TreeNodeMultipleChoiceFilter( queryset=SiteGroup.objects.all(), field_name='site__group', lookup_expr='in', label=_('Site group (ID)'), ) site_group = TreeNodeMultipleChoiceFilter( queryset=SiteGroup.objects.all(), field_name='site__group', lookup_expr='in', to_field_name='slug', label=_('Site group (slug)'), ) site_id = django_filters.ModelMultipleChoiceFilter( queryset=Site.objects.all(), label=_('Site (ID)'), ) site = django_filters.ModelMultipleChoiceFilter( field_name='site__slug', queryset=Site.objects.all(), to_field_name='slug', label=_('Site name (slug)'), ) location_id = TreeNodeMultipleChoiceFilter( queryset=Location.objects.all(), field_name='location', lookup_expr='in', label=_('Location (ID)'), ) class Meta: model = PowerPanel fields = ('id', 'name', 'description') def search(self, queryset, name, value): if not value.strip(): return queryset qs_filter = ( Q(name__icontains=value) | Q(description__icontains=value) ) return queryset.filter(qs_filter) class PowerFeedFilterSet(NetBoxModelFilterSet, CabledObjectFilterSet, PathEndpointFilterSet, TenancyFilterSet): region_id = TreeNodeMultipleChoiceFilter( queryset=Region.objects.all(), field_name='power_panel__site__region', lookup_expr='in', label=_('Region (ID)'), ) region = TreeNodeMultipleChoiceFilter( queryset=Region.objects.all(), field_name='power_panel__site__region', lookup_expr='in', to_field_name='slug', label=_('Region (slug)'), ) site_group_id = TreeNodeMultipleChoiceFilter( queryset=SiteGroup.objects.all(), field_name='power_panel__site__group', lookup_expr='in', label=_('Site group (ID)'), ) site_group = TreeNodeMultipleChoiceFilter( queryset=SiteGroup.objects.all(), field_name='power_panel__site__group', lookup_expr='in', to_field_name='slug', label=_('Site group (slug)'), ) site_id = django_filters.ModelMultipleChoiceFilter( field_name='power_panel__site', queryset=Site.objects.all(), label=_('Site (ID)'), ) site = django_filters.ModelMultipleChoiceFilter( field_name='power_panel__site__slug', queryset=Site.objects.all(), to_field_name='slug', label=_('Site name (slug)'), ) power_panel_id = django_filters.ModelMultipleChoiceFilter( queryset=PowerPanel.objects.all(), label=_('Power panel (ID)'), ) rack_id = django_filters.ModelMultipleChoiceFilter( field_name='rack', queryset=Rack.objects.all(), label=_('Rack (ID)'), ) status = django_filters.MultipleChoiceFilter( choices=PowerFeedStatusChoices, null_value=None ) class Meta: model = PowerFeed fields = ( 'id', 'name', 'status', 'type', 'supply', 'phase', 'voltage', 'amperage', 'max_utilization', 'available_power', 'mark_connected', 'cable_end', 'description', ) def search(self, queryset, name, value): if not value.strip(): return queryset qs_filter = ( Q(name__icontains=value) | Q(description__icontains=value) | Q(power_panel__name__icontains=value) | Q(comments__icontains=value) ) return queryset.filter(qs_filter) # # Connection filter sets # class ConnectionFilterSet(BaseFilterSet): q = django_filters.CharFilter( method='search', label=_('Search'), ) site_id = MultiValueNumberFilter( method='filter_connections', field_name='device__site_id' ) site = MultiValueCharFilter( method='filter_connections', field_name='device__site__slug' ) device_id = MultiValueNumberFilter( method='filter_connections', field_name='device_id' ) device = MultiValueCharFilter( method='filter_connections', field_name='device__name' ) def filter_connections(self, queryset, name, value): if not value: return queryset return queryset.filter(**{f'{name}__in': value}) def search(self, queryset, name, value): if not value.strip(): return queryset qs_filter = ( Q(device__name__icontains=value) | Q(cable__label__icontains=value) ) return queryset.filter(qs_filter) class ConsoleConnectionFilterSet(ConnectionFilterSet): class Meta: model = ConsolePort fields = ('name',) class PowerConnectionFilterSet(ConnectionFilterSet): class Meta: model = PowerPort fields = ('name',) class InterfaceConnectionFilterSet(ConnectionFilterSet): class Meta: model = Interface fields = tuple()