diff --git a/netbox/dcim/graphql/enums.py b/netbox/dcim/graphql/enums.py index 5f888cfb51a..62a666b4544 100644 --- a/netbox/dcim/graphql/enums.py +++ b/netbox/dcim/graphql/enums.py @@ -12,6 +12,7 @@ 'DeviceFaceEnum', 'DeviceStatusEnum', 'InterfaceDuplexEnum', + 'InterfaceKindEnum', 'InterfaceModeEnum', 'InterfacePoEModeEnum', 'InterfacePoETypeEnum', @@ -48,6 +49,7 @@ DeviceFaceEnum = strawberry.enum(DeviceFaceChoices.as_enum(prefix='face')) DeviceStatusEnum = strawberry.enum(DeviceStatusChoices.as_enum(prefix='status')) InterfaceDuplexEnum = strawberry.enum(InterfaceDuplexChoices.as_enum(prefix='duplex')) +InterfaceKindEnum = strawberry.enum(InterfaceKindChoices.as_enum(prefix='kind')) InterfaceModeEnum = strawberry.enum(InterfaceModeChoices.as_enum(prefix='mode')) InterfacePoEModeEnum = strawberry.enum(InterfacePoEModeChoices.as_enum(prefix='mode')) InterfacePoETypeEnum = strawberry.enum(InterfacePoETypeChoices.as_enum()) diff --git a/netbox/dcim/graphql/filters.py b/netbox/dcim/graphql/filters.py index a8a6c2a5e03..af2922e1362 100644 --- a/netbox/dcim/graphql/filters.py +++ b/netbox/dcim/graphql/filters.py @@ -1,5 +1,6 @@ from typing import Annotated, TYPE_CHECKING +from django.db.models import Q import strawberry import strawberry_django from strawberry.scalars import ID @@ -7,6 +8,8 @@ from core.graphql.filter_mixins import ChangeLogFilterMixin from dcim import models +from dcim.constants import * +from dcim.graphql.enums import InterfaceKindEnum from extras.graphql.filter_mixins import ConfigContextFilterMixin from netbox.graphql.filter_mixins import ( PrimaryModelFilterMixin, @@ -485,6 +488,27 @@ class InterfaceFilter(ModularComponentModelFilterMixin, InterfaceBaseFilterMixin strawberry_django.filter_field() ) + @strawberry_django.filter_field + def connected(self, queryset, value: bool, prefix: str): + if value is True: + return queryset, Q(**{f"{prefix}_path__is_active": True}) + else: + return queryset, Q(**{f"{prefix}_path__isnull": True}) | Q(**{f"{prefix}_path__is_active": False}) + + @strawberry_django.filter_field + def kind( + self, + queryset, + value: Annotated['InterfaceKindEnum', strawberry.lazy('dcim.graphql.enums')], + prefix: str + ): + if value == InterfaceKindEnum.KIND_PHYSICAL: + return queryset, ~Q(**{f"{prefix}type__in": NONCONNECTABLE_IFACE_TYPES}) + elif value == InterfaceKindEnum.KIND_VIRTUAL: + return queryset, Q(**{f"{prefix}type__in": VIRTUAL_IFACE_TYPES}) + elif value == InterfaceKindEnum.KIND_WIRELESS: + return queryset, Q(**{f"{prefix}type__in": WIRELESS_IFACE_TYPES}) + @strawberry_django.filter_type(models.InterfaceTemplate, lookups=True) class InterfaceTemplateFilter(ModularComponentTemplateFilterMixin):