Closes #7598: GraphQL Filter Redesign

This commit is contained in:
Jeremy Sanders 2025-01-07 13:58:43 -06:00
parent b913661297
commit 999cae939e
34 changed files with 4490 additions and 623 deletions

View File

@ -0,0 +1,86 @@
from enum import Enum
import strawberry
__all__ = [
'CircuitStatusEnum',
'CircuitCommitRateEnum',
'CircuitTerminationSideEnum',
'CircuitTerminationPortSpeedEnum',
'CircuitPriorityEnum',
'VirtualCircuitTerminationRoleEnum',
]
#
# Circuits
#
@strawberry.enum
class CircuitStatusEnum(Enum):
STATUS_DEPROVISIONING = 'deprovisioning'
STATUS_ACTIVE = 'active'
STATUS_PLANNED = 'planned'
STATUS_PROVISIONING = 'provisioning'
STATUS_OFFLINE = 'offline'
STATUS_DECOMMISSIONED = 'decommissioned'
@strawberry.enum
class CircuitCommitRateEnum(Enum):
TEN_MBPS = 10000
HUNDRED_MBPS = 100000
ONE_GBPS = 1000000
TEN_GBPS = 10000000
TWENTY_FIVE_GBPS = 25000000
FORTY_GBPS = 40000000
HUNDRED_GBPS = 100000000
TWO_HUNDRED_GBPS = 200000000
FOUR_HUNDRED_GBPS = 400000000
T1 = 1544
E1 = 2048
#
# CircuitTerminations
#
@strawberry.enum
class CircuitTerminationSideEnum(Enum):
SIDE_A = 'A'
SIDE_Z = 'Z'
@strawberry.enum
class CircuitTerminationPortSpeedEnum(Enum):
TEN_MBPS = 10000
HUNDRED_MBPS = 100000
ONE_GBPS = 1000000
TEN_GBPS = 10000000
TWENTY_FIVE_GBPS = 25000000
FORTY_GBPS = 40000000
HUNDRED_GBPS = 100000000
TWO_HUNDRED_GBPS = 200000000
FOUR_HUNDRED_GBPS = 400000000
T1 = 1544
E1 = 2048
@strawberry.enum
class CircuitPriorityEnum(Enum):
PRIORITY_PRIMARY = 'primary'
PRIORITY_SECONDARY = 'secondary'
PRIORITY_TERTIARY = 'tertiary'
PRIORITY_INACTIVE = 'inactive'
#
# Virtual circuits
#
@strawberry.enum
class VirtualCircuitTerminationRoleEnum(Enum):
ROLE_PEER = 'peer'
ROLE_HUB = 'hub'
ROLE_SPOKE = 'spoke'

View File

@ -0,0 +1,17 @@
from dataclasses import dataclass
from typing import Annotated, TYPE_CHECKING
import strawberry
import strawberry_django
from netbox.graphql.filter_mixins import OrganizationalModelFilterMixin
if TYPE_CHECKING:
from .filters import *
from core.graphql.filter_lookups import *
from netbox.graphql.enums import *
__all__ = ['BaseCircuitTypeFilterMixin']
@dataclass
class BaseCircuitTypeFilterMixin(OrganizationalModelFilterMixin):
color: Annotated['ColorEnum', strawberry.lazy('netbox.graphql.enums')] | None = strawberry_django.filter_field()

View File

@ -1,7 +1,33 @@
from datetime import date
from typing import Annotated, TYPE_CHECKING
import strawberry
from strawberry.scalars import ID
import strawberry_django import strawberry_django
from strawberry_django import FilterLookup, DateFilterLookup
from extras.graphql.filter_mixins import *
from netbox.graphql.filter_mixins import *
from core.graphql.filter_mixins import *
from tenancy.graphql.filter_mixins import *
from dcim.graphql.filter_mixins import *
from .filter_mixins import *
from circuits import filtersets, models from circuits import models
from netbox.graphql.filter_mixins import autotype_decorator, BaseFilterMixin
if TYPE_CHECKING:
from .enums import *
from netbox.graphql.enums import *
from wireless.graphql.enums import *
from core.graphql.filter_lookups import *
from core.graphql.filters import *
from extras.graphql.filters import *
from circuits.graphql.filters import *
from dcim.graphql.filters import *
from ipam.graphql.filters import *
from tenancy.graphql.filters import *
from wireless.graphql.filters import *
from users.graphql.filters import *
from virtualization.graphql.filters import *
from vpn.graphql.filters import *
__all__ = ( __all__ = (
'CircuitFilter', 'CircuitFilter',
@ -19,66 +45,165 @@ __all__ = (
@strawberry_django.filter(models.CircuitTermination, lookups=True) @strawberry_django.filter(models.CircuitTermination, lookups=True)
@autotype_decorator(filtersets.CircuitTerminationFilterSet) class CircuitTerminationFilter(
class CircuitTerminationFilter(BaseFilterMixin): BaseObjectTypeFilterMixin,
pass CustomFieldsFilterMixin,
TagsFilterMixin,
ChangeLogFilterMixin,
CabledObjectModelFilterMixin,
):
circuit: Annotated['CircuitFilter', strawberry.lazy('circuits.graphql.filters')] | None = (
strawberry_django.filter_field()
)
term_side: Annotated['CircuitTerminationSideEnum', strawberry.lazy('circuits.graphql.enums')] | None = (
strawberry_django.filter_field()
)
termination_type: Annotated['ContentTypeFilter', strawberry.lazy('core.graphql.filters')] | None = (
strawberry_django.filter_field()
)
termination_id: ID | None = strawberry_django.filter_field()
port_speed: Annotated['IntegerLookup', strawberry.lazy('core.graphql.filter_lookups')] | None = (
strawberry_django.filter_field()
)
upstream_speed: Annotated['IntegerLookup', strawberry.lazy('core.graphql.filter_lookups')] | None = (
strawberry_django.filter_field()
)
xconnect_id: FilterLookup[str] | None = strawberry_django.filter_field()
pp_info: FilterLookup[str] | None = strawberry_django.filter_field()
description: FilterLookup[str] | None = strawberry_django.filter_field()
@strawberry_django.filter(models.Circuit, lookups=True) @strawberry_django.filter(models.Circuit, lookups=True)
@autotype_decorator(filtersets.CircuitFilterSet) class CircuitFilter(ContactFilterMixin, ImageAttachmentFilterMixin, DistanceFilterMixin, PrimaryModelFilterMixin):
class CircuitFilter(BaseFilterMixin): cid: FilterLookup[str] | None = strawberry_django.filter_field()
pass provider: Annotated['ProviderFilter', strawberry.lazy('circuits.graphql.filters')] | None = (
strawberry_django.filter_field()
)
provider_id: ID | None = strawberry_django.filter_field()
provider_account: Annotated['ProviderAccountFilter', strawberry.lazy('circuits.graphql.filters')] | None = (
strawberry_django.filter_field()
)
provider_account_id: ID | None = strawberry_django.filter_field()
type: Annotated['CircuitTypeFilter', strawberry.lazy('circuits.graphql.filters')] | None = (
strawberry_django.filter_field()
)
type_id: ID | None = strawberry_django.filter_field()
status: Annotated['CircuitStatusEnum', strawberry.lazy('circuits.graphql.enums')] | None = (
strawberry_django.filter_field()
)
tenant: Annotated['TenantFilter', strawberry.lazy('tenancy.graphql.filters')] | None = (
strawberry_django.filter_field()
)
tenant_id: ID | None = strawberry_django.filter_field()
install_date: DateFilterLookup[date] | None = strawberry_django.filter_field()
termination_date: DateFilterLookup[date] | None = strawberry_django.filter_field()
commit_rate: Annotated['IntegerLookup', strawberry.lazy('core.graphql.filter_lookups')] | None = (
strawberry_django.filter_field()
)
@strawberry_django.filter(models.CircuitType, lookups=True) @strawberry_django.filter(models.CircuitType, lookups=True)
@autotype_decorator(filtersets.CircuitTypeFilterSet) class CircuitTypeFilter(BaseCircuitTypeFilterMixin):
class CircuitTypeFilter(BaseFilterMixin):
pass pass
@strawberry_django.filter(models.CircuitGroup, lookups=True) @strawberry_django.filter(models.CircuitGroup, lookups=True)
@autotype_decorator(filtersets.CircuitGroupFilterSet) class CircuitGroupFilter(OrganizationalModelFilterMixin):
class CircuitGroupFilter(BaseFilterMixin): tenant: Annotated['TenantFilter', strawberry.lazy('tenancy.graphql.filters')] | None = (
pass strawberry_django.filter_field()
)
tenant_id: ID | None = strawberry_django.filter_field()
@strawberry_django.filter(models.CircuitGroupAssignment, lookups=True) @strawberry_django.filter(models.CircuitGroupAssignment, lookups=True)
@autotype_decorator(filtersets.CircuitGroupAssignmentFilterSet) class CircuitGroupAssignmentFilter(
class CircuitGroupAssignmentFilter(BaseFilterMixin): BaseObjectTypeFilterMixin, CustomFieldsFilterMixin, TagsFilterMixin, ChangeLogFilterMixin
pass ):
member_type: Annotated['ContentTypeFilter', strawberry.lazy('core.graphql.filters')] | None = (
strawberry_django.filter_field()
)
member_type_id: ID | None = strawberry_django.filter_field()
group: Annotated['CircuitGroupFilter', strawberry.lazy('circuits.graphql.filters')] | None = (
strawberry_django.filter_field()
)
group_id: ID | None = strawberry_django.filter_field()
priority: Annotated['CircuitPriorityEnum', strawberry.lazy('circuits.graphql.enums')] | None = (
strawberry_django.filter_field()
)
@strawberry_django.filter(models.Provider, lookups=True) @strawberry_django.filter(models.Provider, lookups=True)
@autotype_decorator(filtersets.ProviderFilterSet) class ProviderFilter(ContactFilterMixin, PrimaryModelFilterMixin):
class ProviderFilter(BaseFilterMixin): name: FilterLookup[str] | None = strawberry_django.filter_field()
pass slug: FilterLookup[str] | None = strawberry_django.filter_field()
asns: Annotated['ASNFilter', strawberry.lazy('ipam.graphql.filters')] | None = strawberry_django.filter_field()
@strawberry_django.filter(models.ProviderAccount, lookups=True) @strawberry_django.filter(models.ProviderAccount, lookups=True)
@autotype_decorator(filtersets.ProviderAccountFilterSet) class ProviderAccountFilter(ContactFilterMixin, PrimaryModelFilterMixin):
class ProviderAccountFilter(BaseFilterMixin): provider: Annotated['ProviderFilter', strawberry.lazy('circuits.graphql.filters')] | None = (
pass strawberry_django.filter_field()
)
provider_id: ID | None = strawberry_django.filter_field()
account: FilterLookup[str] | None = strawberry_django.filter_field()
name: FilterLookup[str] | None = strawberry_django.filter_field()
@strawberry_django.filter(models.ProviderNetwork, lookups=True) @strawberry_django.filter(models.ProviderNetwork, lookups=True)
@autotype_decorator(filtersets.ProviderNetworkFilterSet) class ProviderNetworkFilter(PrimaryModelFilterMixin):
class ProviderNetworkFilter(BaseFilterMixin): name: FilterLookup[str] | None = strawberry_django.filter_field()
pass provider: Annotated['ProviderFilter', strawberry.lazy('circuits.graphql.filters')] | None = (
strawberry_django.filter_field()
)
provider_id: ID | None = strawberry_django.filter_field()
service_id: FilterLookup[str] | None = strawberry_django.filter_field()
@strawberry_django.filter(models.VirtualCircuitType, lookups=True) @strawberry_django.filter(models.VirtualCircuitType, lookups=True)
@autotype_decorator(filtersets.VirtualCircuitTypeFilterSet) class VirtualCircuitTypeFilter(BaseCircuitTypeFilterMixin):
class VirtualCircuitTypeFilter(BaseFilterMixin):
pass pass
@strawberry_django.filter(models.VirtualCircuit, lookups=True) @strawberry_django.filter(models.VirtualCircuit, lookups=True)
@autotype_decorator(filtersets.VirtualCircuitFilterSet) class VirtualCircuitFilter(PrimaryModelFilterMixin):
class VirtualCircuitFilter(BaseFilterMixin): cid: FilterLookup[str] | None = strawberry_django.filter_field()
pass provider_network: Annotated['ProviderNetworkFilter', strawberry.lazy('circuits.graphql.filters')] | None = (
strawberry_django.filter_field()
)
provider_network_id: ID | None = strawberry_django.filter_field()
provider_account: Annotated['ProviderAccountFilter', strawberry.lazy('circuits.graphql.filters')] | None = (
strawberry_django.filter_field()
)
provider_account_id: ID | None = strawberry_django.filter_field()
type: Annotated['VirtualCircuitTypeFilter', strawberry.lazy('circuits.graphql.filters')] | None = (
strawberry_django.filter_field()
)
type_id: ID | None = strawberry_django.filter_field()
status: Annotated['CircuitStatusEnum', strawberry.lazy('circuits.graphql.enums')] | None = (
strawberry_django.filter_field()
)
tenant: Annotated['TenantFilter', strawberry.lazy('tenancy.graphql.filters')] | None = (
strawberry_django.filter_field()
)
tenant_id: ID | None = strawberry_django.filter_field()
group_assignments: Annotated['CircuitGroupAssignmentFilter', strawberry.lazy('circuits.graphql.filters')] | None = (
strawberry_django.filter_field()
)
@strawberry_django.filter(models.VirtualCircuitTermination, lookups=True) @strawberry_django.filter(models.VirtualCircuitTermination, lookups=True)
@autotype_decorator(filtersets.VirtualCircuitTerminationFilterSet) class VirtualCircuitTerminationFilter(
class VirtualCircuitTerminationFilter(BaseFilterMixin): BaseObjectTypeFilterMixin, CustomFieldsFilterMixin, TagsFilterMixin, ChangeLogFilterMixin
pass ):
virtual_circuit: Annotated['VirtualCircuitFilter', strawberry.lazy('circuits.graphql.filters')] | None = (
strawberry_django.filter_field()
)
virtual_circuit_id: ID | None = strawberry_django.filter_field()
role: Annotated['VirtualCircuitTerminationRoleEnum', strawberry.lazy('circuits.graphql.enums')] | None = (
strawberry_django.filter_field()
)
interface: Annotated['InterfaceFilter', strawberry.lazy('dcim.graphql.filters')] | None = (
strawberry_django.filter_field()
)
interface_id: ID | None = strawberry_django.filter_field()
description: FilterLookup[str] | None = strawberry_django.filter_field()

View File

@ -0,0 +1,218 @@
from enum import Enum
from typing import TypeVar, Tuple, Generic
from django.db.models import Q, QuerySet
from django.core.exceptions import FieldDoesNotExist
from django.db.models.fields.related import ForeignKey, ManyToManyField, ManyToManyRel, ManyToOneRel
import strawberry
from strawberry import ID
from strawberry.types import Info
import strawberry_django
from strawberry_django import (
process_filters,
FilterLookup,
RangeLookup,
ComparisonFilterLookup,
DateFilterLookup,
DatetimeFilterLookup,
TimeFilterLookup,
)
__all__ = [
'JSONFilter',
'TreeNodeFilter',
'IntegerLookup',
'FloatLookup',
'ArrayLookup',
'IntegerArrayLookup',
'FloatArrayLookup',
'StringArrayLookup',
]
T = TypeVar('T')
SKIP_MSG = 'Filter will be skipped on `null` value'
@strawberry.input(one_of=True, description='Lookup for JSON field. Only one of the lookup fields can be set.')
class JSONLookup:
string_lookup: FilterLookup[str] | None = strawberry_django.filter_field()
int_range_lookup: RangeLookup[int] | None = strawberry_django.filter_field()
int_comparison_lookup: ComparisonFilterLookup[int] | None = strawberry_django.filter_field()
float_range_lookup: RangeLookup[float] | None = strawberry_django.filter_field()
float_comparison_lookup: ComparisonFilterLookup[float] | None = strawberry_django.filter_field()
date_lookup: DateFilterLookup[str] | None = strawberry_django.filter_field()
datetime_lookup: DatetimeFilterLookup[str] | None = strawberry_django.filter_field()
time_lookup: TimeFilterLookup[str] | None = strawberry_django.filter_field()
boolean_lookup: FilterLookup[bool] | None = strawberry_django.filter_field()
def get_filter(self):
for field in self.__strawberry_definition__.fields:
value = getattr(self, field.name, None)
if value is not strawberry.UNSET:
return value
return None
@strawberry.input(one_of=True, description='Lookup for Integer fields. Only one of the lookup fields can be set.')
class IntegerLookup:
filter_lookup: FilterLookup[int] | None = strawberry_django.filter_field()
range_lookup: RangeLookup[int] | None = strawberry_django.filter_field()
comparison_lookup: ComparisonFilterLookup[int] | None = strawberry_django.filter_field()
def get_filter(self):
for field in self.__strawberry_definition__.fields:
value = getattr(self, field.name, None)
if value is not strawberry.UNSET:
return value
return None
@strawberry_django.filter_field
def filter(self, info: Info, queryset: QuerySet, prefix: str = '') -> Tuple[QuerySet, Q]:
filters = self.get_filter()
if not filters:
return queryset, Q()
return process_filters(filters=filters, queryset=queryset, info=info, prefix=prefix)
@strawberry.input(one_of=True, description='Lookup for Float fields. Only one of the lookup fields can be set.')
class FloatLookup:
filter_lookup: FilterLookup[float] | None = strawberry_django.filter_field()
range_lookup: RangeLookup[float] | None = strawberry_django.filter_field()
comparison_lookup: ComparisonFilterLookup[float] | None = strawberry_django.filter_field()
def get_filter(self):
for field in self.__strawberry_definition__.fields:
value = getattr(self, field.name, None)
if value is not strawberry.UNSET:
return value
return None
@strawberry_django.filter_field
def filter(self, info: Info, queryset: QuerySet, prefix: str = '') -> Tuple[QuerySet, Q]:
filters = self.get_filter()
if not filters:
return queryset, Q()
return process_filters(filters=filters, queryset=queryset, info=info, prefix=prefix)
@strawberry.input
class JSONFilter:
"""
Class for JSON field lookups with paths
"""
path: str
lookup: JSONLookup
@strawberry_django.filter_field
def filter(self, info: Info, queryset: QuerySet, prefix: str = '') -> Tuple[QuerySet, Q]:
filters = self.lookup.get_filter()
if not filters:
return queryset, Q()
json_path = f'{prefix}{self.path}__'
return process_filters(filters=filters, queryset=queryset, info=info, prefix=json_path)
@strawberry.enum
class TreeNodeMatch(Enum):
EXACT = 'exact' # Just the node itself
DESCENDANTS = 'descendants' # Node and all descendants
SELF_AND_DESCENDANTS = 'self_and_descendants' # Node and all descendants
CHILDREN = 'children' # Just immediate children
SIBLINGS = 'siblings' # Nodes with same parent
ANCESTORS = 'ancestors' # All parent nodes
PARENT = 'parent' # Just immediate parent
@strawberry.input
class TreeNodeFilter:
id: ID
match_type: TreeNodeMatch
@strawberry_django.filter_field
def filter(self, info: Info, queryset: QuerySet, prefix: str = '') -> Tuple[QuerySet, Q]:
model_field_name = prefix.removesuffix('__').removesuffix('_id')
model_field = None
try:
model_field = queryset.model._meta.get_field(model_field_name)
except FieldDoesNotExist:
try:
model_field = queryset.model._meta.get_field(f'{model_field_name}s')
except FieldDoesNotExist:
return queryset, Q(pk__in=[])
if hasattr(model_field, 'related_model'):
related_model = model_field.related_model
else:
return queryset, Q(pk__in=[])
# Generate base Q filter for the related model without prefix
q_filter = generate_tree_node_q_filter(related_model, self)
# Handle different relationship types
if isinstance(model_field, (ManyToManyField, ManyToManyRel)):
return queryset, Q(**{f'{model_field_name}__in': related_model.objects.filter(q_filter)})
elif isinstance(model_field, ForeignKey):
return queryset, Q(**{f'{model_field_name}__{k}': v for k, v in q_filter.children})
elif isinstance(model_field, ManyToOneRel):
return queryset, Q(**{f'{model_field_name}__in': related_model.objects.filter(q_filter)})
else:
return queryset, Q(**{f'{model_field_name}__{k}': v for k, v in q_filter.children})
def generate_tree_node_q_filter(model_class, filter_value: TreeNodeFilter) -> Q:
"""
Generate appropriate Q filter for MPTT tree filtering based on match type
"""
try:
node = model_class.objects.get(id=filter_value.id)
except model_class.DoesNotExist:
return Q(pk__in=[])
if filter_value.match_type == TreeNodeMatch.EXACT:
return Q(id=filter_value.id)
elif filter_value.match_type == TreeNodeMatch.DESCENDANTS:
return Q(tree_id=node.tree_id, lft__gt=node.lft, rght__lt=node.rght)
elif filter_value.match_type == TreeNodeMatch.SELF_AND_DESCENDANTS:
return Q(tree_id=node.tree_id, lft__gte=node.lft, rght__lte=node.rght)
elif filter_value.match_type == TreeNodeMatch.CHILDREN:
return Q(tree_id=node.tree_id, level=node.level + 1, lft__gt=node.lft, rght__lt=node.rght)
elif filter_value.match_type == TreeNodeMatch.SIBLINGS:
return Q(tree_id=node.tree_id, level=node.level, parent=node.parent) & ~Q(id=node.id)
elif filter_value.match_type == TreeNodeMatch.ANCESTORS:
return Q(tree_id=node.tree_id, lft__lt=node.lft, rght__gt=node.rght)
elif filter_value.match_type == TreeNodeMatch.PARENT:
return Q(id=node.parent_id) if node.parent_id else Q(pk__in=[])
return Q()
@strawberry.input(one_of=True, description='Lookup for Array fields. Only one of the lookup fields can be set.')
class ArrayLookup(Generic[T]):
"""
Class for Array field lookups
"""
contains: list[T] | None = strawberry_django.filter_field(description='Contains the value')
contained_by: list[T] | None = strawberry_django.filter_field(description='Contained by the value')
overlap: list[T] | None = strawberry_django.filter_field(description='Overlaps with the value')
length: int | None = strawberry_django.filter_field(description='Length of the array')
@strawberry.input(one_of=True, description='Lookup for Array fields. Only one of the lookup fields can be set.')
class IntegerArrayLookup(ArrayLookup[int]):
pass
@strawberry.input(one_of=True, description='Lookup for Array fields. Only one of the lookup fields can be set.')
class FloatArrayLookup(ArrayLookup[float]):
pass
@strawberry.input(one_of=True, description='Lookup for Array fields. Only one of the lookup fields can be set.')
class StringArrayLookup(ArrayLookup[str]):
pass

View File

@ -0,0 +1,31 @@
from dataclasses import dataclass
from datetime import datetime
from typing import Annotated, TYPE_CHECKING
import strawberry
from strawberry import ID
import strawberry_django
from strawberry_django import DatetimeFilterLookup
if TYPE_CHECKING:
from .filters import *
__all__ = ['BaseFilterMixin', 'BaseObjectTypeFilterMixin', 'ChangeLogFilterMixin']
# @strawberry.input
class BaseFilterMixin: ...
@dataclass
class BaseObjectTypeFilterMixin(BaseFilterMixin):
id: ID | None = strawberry.UNSET
@dataclass
class ChangeLogFilterMixin(BaseFilterMixin):
changelog: Annotated['ObjectChangeFilter', strawberry.lazy('core.graphql.filters')] | None = (
strawberry_django.filter_field()
)
created: DatetimeFilterLookup[datetime] | None = strawberry_django.filter_field()
last_updated: DatetimeFilterLookup[datetime] | None = strawberry_django.filter_field()

View File

@ -1,28 +1,93 @@
from datetime import datetime
from typing import Annotated, TYPE_CHECKING
import strawberry
from strawberry.scalars import ID
import strawberry_django import strawberry_django
from strawberry_django import (
DatetimeFilterLookup,
FilterLookup,
)
from django.contrib.contenttypes.models import ContentType as DjangoContentType
from core.graphql.filter_mixins import BaseFilterMixin
from core.graphql.filter_lookups import JSONFilter
from netbox.graphql.filter_mixins import (
PrimaryModelFilterMixin,
)
from core import models
if TYPE_CHECKING:
from core.graphql.filter_lookups import *
from users.graphql.filters import *
from core import filtersets, models
from netbox.graphql.filter_mixins import autotype_decorator, BaseFilterMixin
__all__ = ( __all__ = (
'DataFileFilter', 'DataFileFilter',
'DataSourceFilter', 'DataSourceFilter',
'ObjectChangeFilter', 'ObjectChangeFilter',
'ContentTypeFilter',
) )
@strawberry_django.filter(models.DataFile, lookups=True) @strawberry_django.filter(models.DataFile, lookups=True)
@autotype_decorator(filtersets.DataFileFilterSet)
class DataFileFilter(BaseFilterMixin): class DataFileFilter(BaseFilterMixin):
pass id: ID | None = strawberry_django.filter_field()
created: DatetimeFilterLookup[datetime] | None = strawberry_django.filter_field()
last_updated: DatetimeFilterLookup[datetime] | None = strawberry_django.filter_field()
source: Annotated['DataSourceFilter', strawberry.lazy('core.graphql.filters')] | None = (
strawberry_django.filter_field()
)
source_id: ID | None = strawberry_django.filter_field()
path: FilterLookup[str] | None = strawberry_django.filter_field()
size: Annotated['IntegerLookup', strawberry.lazy('core.graphql.filter_lookups')] | None = (
strawberry_django.filter_field()
)
hash: FilterLookup[str] | None = strawberry_django.filter_field()
@strawberry_django.filter(models.DataSource, lookups=True) @strawberry_django.filter(models.DataSource, lookups=True)
@autotype_decorator(filtersets.DataSourceFilterSet) class DataSourceFilter(PrimaryModelFilterMixin):
class DataSourceFilter(BaseFilterMixin): name: FilterLookup[str] | None = strawberry_django.filter_field()
pass type: FilterLookup[str] | None = strawberry_django.filter_field()
source_url: FilterLookup[str] | None = strawberry_django.filter_field()
status: FilterLookup[str] | None = strawberry_django.filter_field()
enabled: FilterLookup[bool] | None = strawberry_django.filter_field()
ignore_rules: FilterLookup[str] | None = strawberry_django.filter_field()
parameters: Annotated['JSONFilter', strawberry.lazy('core.graphql.filter_lookups')] | None = (
strawberry_django.filter_field()
)
last_synced: DatetimeFilterLookup[datetime] | None = strawberry_django.filter_field()
datafiles: Annotated['DataFileFilter', strawberry.lazy('core.graphql.filters')] | None = (
strawberry_django.filter_field()
)
@strawberry_django.filter(models.ObjectChange, lookups=True) @strawberry_django.filter(models.ObjectChange, lookups=True)
@autotype_decorator(filtersets.ObjectChangeFilterSet)
class ObjectChangeFilter(BaseFilterMixin): class ObjectChangeFilter(BaseFilterMixin):
pass id: ID | None = strawberry_django.filter_field()
time: DatetimeFilterLookup[datetime] | None = strawberry_django.filter_field()
user: Annotated['UserFilter', strawberry.lazy('users.graphql.filters')] | None = strawberry_django.filter_field()
user_name: FilterLookup[str] | None = strawberry_django.filter_field()
request_id: FilterLookup[str] | None = strawberry_django.filter_field()
action: FilterLookup[str] | None = strawberry_django.filter_field()
changed_object_type: Annotated['ContentTypeFilter', strawberry.lazy('core.graphql.filters')] | None = (
strawberry_django.filter_field()
)
changed_object_type_id: ID | None = strawberry_django.filter_field()
changed_object_id: ID | None = strawberry_django.filter_field()
related_object_type_id: ID | None = strawberry_django.filter_field()
related_object_id: ID | None = strawberry_django.filter_field()
object_repr: FilterLookup[str] | None = strawberry_django.filter_field()
prechange_data: Annotated['JSONFilter', strawberry.lazy('core.graphql.filter_lookups')] | None = (
strawberry_django.filter_field()
)
postchange_data: Annotated['JSONFilter', strawberry.lazy('core.graphql.filter_lookups')] | None = (
strawberry_django.filter_field()
)
@strawberry_django.filter(DjangoContentType, lookups=True)
class ContentTypeFilter(BaseFilterMixin):
id: ID | None = strawberry_django.filter_field()
app_label: FilterLookup[str] | None = strawberry_django.filter_field()
model: FilterLookup[str] | None = strawberry_django.filter_field()

View File

@ -1,4 +1,4 @@
from typing import Annotated, List from typing import Annotated, List, TYPE_CHECKING
import strawberry import strawberry
import strawberry_django import strawberry_django
@ -6,6 +6,9 @@ from django.contrib.contenttypes.models import ContentType
from core.models import ObjectChange from core.models import ObjectChange
if TYPE_CHECKING:
from netbox.core.graphql.types import ObjectChangeType
__all__ = ( __all__ = (
'ChangelogMixin', 'ChangelogMixin',
) )

View File

@ -2,7 +2,7 @@ from typing import Annotated, List
import strawberry import strawberry
import strawberry_django import strawberry_django
from django.contrib.contenttypes.models import ContentType as DjangoContentType
from core import models from core import models
from netbox.graphql.types import BaseObjectType, NetBoxObjectType from netbox.graphql.types import BaseObjectType, NetBoxObjectType
from .filters import * from .filters import *
@ -11,6 +11,7 @@ __all__ = (
'DataFileType', 'DataFileType',
'DataSourceType', 'DataSourceType',
'ObjectChangeType', 'ObjectChangeType',
'ContentType',
) )
@ -40,3 +41,8 @@ class DataSourceType(NetBoxObjectType):
) )
class ObjectChangeType(BaseObjectType): class ObjectChangeType(BaseObjectType):
pass pass
@strawberry_django.type(DjangoContentType, fields='__all__')
class ContentType:
pass

View File

@ -0,0 +1,857 @@
from enum import Enum
import strawberry
#
# Sites
#
@strawberry.enum
class SiteStatusEnum(Enum):
STATUS_PLANNED = 'planned'
STATUS_STAGING = 'staging'
STATUS_ACTIVE = 'active'
STATUS_DECOMMISSIONING = 'decommissioning'
STATUS_RETIRED = 'retired'
#
# Locations
#
@strawberry.enum
class LocationStatusEnum(Enum):
STATUS_PLANNED = 'planned'
STATUS_STAGING = 'staging'
STATUS_ACTIVE = 'active'
STATUS_DECOMMISSIONING = 'decommissioning'
STATUS_RETIRED = 'retired'
#
# Racks
#
@strawberry.enum
class RackFormFactorEnum(Enum):
TYPE_2POST = '2-post-frame'
TYPE_4POST = '4-post-frame'
TYPE_CABINET = '4-post-cabinet'
TYPE_WALLFRAME = 'wall-frame'
TYPE_WALLFRAME_VERTICAL = 'wall-frame-vertical'
TYPE_WALLCABINET = 'wall-cabinet'
TYPE_WALLCABINET_VERTICAL = 'wall-cabinet-vertical'
@strawberry.enum
class RackWidthEnum(Enum):
WIDTH_10IN = 10
WIDTH_19IN = 19
WIDTH_21IN = 21
WIDTH_23IN = 23
@strawberry.enum
class RackStatusEnum(Enum):
STATUS_RESERVED = 'reserved'
STATUS_AVAILABLE = 'available'
STATUS_PLANNED = 'planned'
STATUS_ACTIVE = 'active'
STATUS_DEPRECATED = 'deprecated'
@strawberry.enum
class RackDimensionUnitEnum(Enum):
UNIT_MILLIMETER = 'mm'
UNIT_INCH = 'in'
@strawberry.enum
class RackElevationDetailRenderEnum(Enum):
RENDER_JSON = 'json'
RENDER_SVG = 'svg'
@strawberry.enum
class RackAirflowEnum(Enum):
FRONT_TO_REAR = 'front-to-rear'
REAR_TO_FRONT = 'rear-to-front'
#
# DeviceTypes
#
@strawberry.enum
class SubdeviceRoleEnum(Enum):
ROLE_PARENT = 'parent'
ROLE_CHILD = 'child'
#
# Devices
#
@strawberry.enum
class DeviceFaceEnum(Enum):
FACE_FRONT = 'front'
FACE_REAR = 'rear'
@strawberry.enum
class DeviceStatusEnum(Enum):
STATUS_OFFLINE = 'offline'
STATUS_ACTIVE = 'active'
STATUS_PLANNED = 'planned'
STATUS_STAGED = 'staged'
STATUS_FAILED = 'failed'
STATUS_INVENTORY = 'inventory'
STATUS_DECOMMISSIONING = 'decommissioning'
@strawberry.enum
class DeviceAirflowEnum(Enum):
AIRFLOW_FRONT_TO_REAR = 'front-to-rear'
AIRFLOW_REAR_TO_FRONT = 'rear-to-front'
AIRFLOW_LEFT_TO_RIGHT = 'left-to-right'
AIRFLOW_RIGHT_TO_LEFT = 'right-to-left'
AIRFLOW_SIDE_TO_REAR = 'side-to-rear'
AIRFLOW_REAR_TO_SIDE = 'rear-to-side'
AIRFLOW_BOTTOM_TO_TOP = 'bottom-to-top'
AIRFLOW_TOP_TO_BOTTOM = 'top-to-bottom'
AIRFLOW_PASSIVE = 'passive'
AIRFLOW_MIXED = 'mixed'
#
# Modules
#
@strawberry.enum
class ModuleStatusEnum(Enum):
key = 'Module.status'
STATUS_OFFLINE = 'offline'
STATUS_ACTIVE = 'active'
STATUS_PLANNED = 'planned'
STATUS_STAGED = 'staged'
STATUS_FAILED = 'failed'
STATUS_DECOMMISSIONING = 'decommissioning'
@strawberry.enum
class ModuleAirflowEnum(Enum):
FRONT_TO_REAR = 'front-to-rear'
REAR_TO_FRONT = 'rear-to-front'
LEFT_TO_RIGHT = 'left-to-right'
RIGHT_TO_LEFT = 'right-to-left'
SIDE_TO_REAR = 'side-to-rear'
PASSIVE = 'passive'
#
# ConsolePorts
#
@strawberry.enum
class ConsolePortTypeEnum(Enum):
TYPE_DE9 = 'de-9'
TYPE_DB25 = 'db-25'
TYPE_RJ11 = 'rj-11'
TYPE_RJ12 = 'rj-12'
TYPE_RJ45 = 'rj-45'
TYPE_MINI_DIN_8 = 'mini-din-8'
TYPE_USB_A = 'usb-a'
TYPE_USB_B = 'usb-b'
TYPE_USB_C = 'usb-c'
TYPE_USB_MINI_A = 'usb-mini-a'
TYPE_USB_MINI_B = 'usb-mini-b'
TYPE_USB_MICRO_A = 'usb-micro-a'
TYPE_USB_MICRO_B = 'usb-micro-b'
TYPE_USB_MICRO_AB = 'usb-micro-ab'
TYPE_OTHER = 'other'
@strawberry.enum
class ConsolePortSpeedEnum(Enum):
SPEED_1200 = 1200
SPEED_2400 = 2400
SPEED_4800 = 4800
SPEED_9600 = 9600
SPEED_19200 = 19200
SPEED_38400 = 38400
SPEED_57600 = 57600
SPEED_115200 = 115200
#
# PowerPorts
#
@strawberry.enum
class PowerPortTypeEnum(Enum):
# IEC 60320
TYPE_IEC_C6 = 'iec-60320-c6'
TYPE_IEC_C8 = 'iec-60320-c8'
TYPE_IEC_C14 = 'iec-60320-c14'
TYPE_IEC_C16 = 'iec-60320-c16'
TYPE_IEC_C20 = 'iec-60320-c20'
TYPE_IEC_C22 = 'iec-60320-c22'
# IEC 60309
TYPE_IEC_PNE4H = 'iec-60309-p-n-e-4h'
TYPE_IEC_PNE6H = 'iec-60309-p-n-e-6h'
TYPE_IEC_PNE9H = 'iec-60309-p-n-e-9h'
TYPE_IEC_2PE4H = 'iec-60309-2p-e-4h'
TYPE_IEC_2PE6H = 'iec-60309-2p-e-6h'
TYPE_IEC_2PE9H = 'iec-60309-2p-e-9h'
TYPE_IEC_3PE4H = 'iec-60309-3p-e-4h'
TYPE_IEC_3PE6H = 'iec-60309-3p-e-6h'
TYPE_IEC_3PE9H = 'iec-60309-3p-e-9h'
TYPE_IEC_3PNE4H = 'iec-60309-3p-n-e-4h'
TYPE_IEC_3PNE6H = 'iec-60309-3p-n-e-6h'
TYPE_IEC_3PNE9H = 'iec-60309-3p-n-e-9h'
# IEC 60906-1
TYPE_IEC_60906_1 = 'iec-60906-1'
TYPE_NBR_14136_10A = 'nbr-14136-10a'
TYPE_NBR_14136_20A = 'nbr-14136-20a'
# NEMA non-locking
TYPE_NEMA_115P = 'nema-1-15p'
TYPE_NEMA_515P = 'nema-5-15p'
TYPE_NEMA_520P = 'nema-5-20p'
TYPE_NEMA_530P = 'nema-5-30p'
TYPE_NEMA_550P = 'nema-5-50p'
TYPE_NEMA_615P = 'nema-6-15p'
TYPE_NEMA_620P = 'nema-6-20p'
TYPE_NEMA_630P = 'nema-6-30p'
TYPE_NEMA_650P = 'nema-6-50p'
TYPE_NEMA_1030P = 'nema-10-30p'
TYPE_NEMA_1050P = 'nema-10-50p'
TYPE_NEMA_1420P = 'nema-14-20p'
TYPE_NEMA_1430P = 'nema-14-30p'
TYPE_NEMA_1450P = 'nema-14-50p'
TYPE_NEMA_1460P = 'nema-14-60p'
TYPE_NEMA_1515P = 'nema-15-15p'
TYPE_NEMA_1520P = 'nema-15-20p'
TYPE_NEMA_1530P = 'nema-15-30p'
TYPE_NEMA_1550P = 'nema-15-50p'
TYPE_NEMA_1560P = 'nema-15-60p'
# NEMA locking
TYPE_NEMA_L115P = 'nema-l1-15p'
TYPE_NEMA_L515P = 'nema-l5-15p'
TYPE_NEMA_L520P = 'nema-l5-20p'
TYPE_NEMA_L530P = 'nema-l5-30p'
TYPE_NEMA_L550P = 'nema-l5-50p'
TYPE_NEMA_L615P = 'nema-l6-15p'
TYPE_NEMA_L620P = 'nema-l6-20p'
TYPE_NEMA_L630P = 'nema-l6-30p'
TYPE_NEMA_L650P = 'nema-l6-50p'
TYPE_NEMA_L1030P = 'nema-l10-30p'
TYPE_NEMA_L1420P = 'nema-l14-20p'
TYPE_NEMA_L1430P = 'nema-l14-30p'
TYPE_NEMA_L1450P = 'nema-l14-50p'
TYPE_NEMA_L1460P = 'nema-l14-60p'
TYPE_NEMA_L1520P = 'nema-l15-20p'
TYPE_NEMA_L1530P = 'nema-l15-30p'
TYPE_NEMA_L1550P = 'nema-l15-50p'
TYPE_NEMA_L1560P = 'nema-l15-60p'
TYPE_NEMA_L2120P = 'nema-l21-20p'
TYPE_NEMA_L2130P = 'nema-l21-30p'
TYPE_NEMA_L2220P = 'nema-l22-20p'
TYPE_NEMA_L2230P = 'nema-l22-30p'
# California style
TYPE_CS6361C = 'cs6361c'
TYPE_CS6365C = 'cs6365c'
TYPE_CS8165C = 'cs8165c'
TYPE_CS8265C = 'cs8265c'
TYPE_CS8365C = 'cs8365c'
TYPE_CS8465C = 'cs8465c'
# ITA/international
TYPE_ITA_C = 'ita-c'
TYPE_ITA_E = 'ita-e'
TYPE_ITA_F = 'ita-f'
TYPE_ITA_EF = 'ita-ef'
TYPE_ITA_G = 'ita-g'
TYPE_ITA_H = 'ita-h'
TYPE_ITA_I = 'ita-i'
TYPE_ITA_J = 'ita-j'
TYPE_ITA_K = 'ita-k'
TYPE_ITA_L = 'ita-l'
TYPE_ITA_M = 'ita-m'
TYPE_ITA_N = 'ita-n'
TYPE_ITA_O = 'ita-o'
# USB
TYPE_USB_A = 'usb-a'
TYPE_USB_B = 'usb-b'
TYPE_USB_C = 'usb-c'
TYPE_USB_MINI_A = 'usb-mini-a'
TYPE_USB_MINI_B = 'usb-mini-b'
TYPE_USB_MICRO_A = 'usb-micro-a'
TYPE_USB_MICRO_B = 'usb-micro-b'
TYPE_USB_MICRO_AB = 'usb-micro-ab'
TYPE_USB_3_B = 'usb-3-b'
TYPE_USB_3_MICROB = 'usb-3-micro-b'
# Molex
TYPE_MOLEX_MICRO_FIT_1X2 = 'molex-micro-fit-1x2'
TYPE_MOLEX_MICRO_FIT_2X2 = 'molex-micro-fit-2x2'
TYPE_MOLEX_MICRO_FIT_2X4 = 'molex-micro-fit-2x4'
# Direct current (DC)
TYPE_DC = 'dc-terminal'
# Proprietary
TYPE_SAF_D_GRID = 'saf-d-grid'
TYPE_NEUTRIK_POWERCON_20A = 'neutrik-powercon-20'
TYPE_NEUTRIK_POWERCON_32A = 'neutrik-powercon-32'
TYPE_NEUTRIK_POWERCON_TRUE1 = 'neutrik-powercon-true1'
TYPE_NEUTRIK_POWERCON_TRUE1_TOP = 'neutrik-powercon-true1-top'
TYPE_UBIQUITI_SMARTPOWER = 'ubiquiti-smartpower'
# Other
TYPE_HARDWIRED = 'hardwired'
TYPE_OTHER = 'other'
#
# PowerOutlets
#
@strawberry.enum
class PowerOutletTypeEnum(Enum):
# IEC 60320
TYPE_IEC_C5 = 'iec-60320-c5'
TYPE_IEC_C7 = 'iec-60320-c7'
TYPE_IEC_C13 = 'iec-60320-c13'
TYPE_IEC_C15 = 'iec-60320-c15'
TYPE_IEC_C19 = 'iec-60320-c19'
TYPE_IEC_C21 = 'iec-60320-c21'
# IEC 60309
TYPE_IEC_PNE4H = 'iec-60309-p-n-e-4h'
TYPE_IEC_PNE6H = 'iec-60309-p-n-e-6h'
TYPE_IEC_PNE9H = 'iec-60309-p-n-e-9h'
TYPE_IEC_2PE4H = 'iec-60309-2p-e-4h'
TYPE_IEC_2PE6H = 'iec-60309-2p-e-6h'
TYPE_IEC_2PE9H = 'iec-60309-2p-e-9h'
TYPE_IEC_3PE4H = 'iec-60309-3p-e-4h'
TYPE_IEC_3PE6H = 'iec-60309-3p-e-6h'
TYPE_IEC_3PE9H = 'iec-60309-3p-e-9h'
TYPE_IEC_3PNE4H = 'iec-60309-3p-n-e-4h'
TYPE_IEC_3PNE6H = 'iec-60309-3p-n-e-6h'
TYPE_IEC_3PNE9H = 'iec-60309-3p-n-e-9h'
# IEC 60906-1
TYPE_IEC_60906_1 = 'iec-60906-1'
TYPE_NBR_14136_10A = 'nbr-14136-10a'
TYPE_NBR_14136_20A = 'nbr-14136-20a'
# NEMA non-locking
TYPE_NEMA_115R = 'nema-1-15r'
TYPE_NEMA_515R = 'nema-5-15r'
TYPE_NEMA_520R = 'nema-5-20r'
TYPE_NEMA_530R = 'nema-5-30r'
TYPE_NEMA_550R = 'nema-5-50r'
TYPE_NEMA_615R = 'nema-6-15r'
TYPE_NEMA_620R = 'nema-6-20r'
TYPE_NEMA_630R = 'nema-6-30r'
TYPE_NEMA_650R = 'nema-6-50r'
TYPE_NEMA_1030R = 'nema-10-30r'
TYPE_NEMA_1050R = 'nema-10-50r'
TYPE_NEMA_1420R = 'nema-14-20r'
TYPE_NEMA_1430R = 'nema-14-30r'
TYPE_NEMA_1450R = 'nema-14-50r'
TYPE_NEMA_1460R = 'nema-14-60r'
TYPE_NEMA_1515R = 'nema-15-15r'
TYPE_NEMA_1520R = 'nema-15-20r'
TYPE_NEMA_1530R = 'nema-15-30r'
TYPE_NEMA_1550R = 'nema-15-50r'
TYPE_NEMA_1560R = 'nema-15-60r'
# NEMA locking
TYPE_NEMA_L115R = 'nema-l1-15r'
TYPE_NEMA_L515R = 'nema-l5-15r'
TYPE_NEMA_L520R = 'nema-l5-20r'
TYPE_NEMA_L530R = 'nema-l5-30r'
TYPE_NEMA_L550R = 'nema-l5-50r'
TYPE_NEMA_L615R = 'nema-l6-15r'
TYPE_NEMA_L620R = 'nema-l6-20r'
TYPE_NEMA_L630R = 'nema-l6-30r'
TYPE_NEMA_L650R = 'nema-l6-50r'
TYPE_NEMA_L1030R = 'nema-l10-30r'
TYPE_NEMA_L1420R = 'nema-l14-20r'
TYPE_NEMA_L1430R = 'nema-l14-30r'
TYPE_NEMA_L1450R = 'nema-l14-50r'
TYPE_NEMA_L1460R = 'nema-l14-60r'
TYPE_NEMA_L1520R = 'nema-l15-20r'
TYPE_NEMA_L1530R = 'nema-l15-30r'
TYPE_NEMA_L1550R = 'nema-l15-50r'
TYPE_NEMA_L1560R = 'nema-l15-60r'
TYPE_NEMA_L2120R = 'nema-l21-20r'
TYPE_NEMA_L2130R = 'nema-l21-30r'
TYPE_NEMA_L2220R = 'nema-l22-20r'
TYPE_NEMA_L2230R = 'nema-l22-30r'
# California style
TYPE_CS6360C = 'CS6360C'
TYPE_CS6364C = 'CS6364C'
TYPE_CS8164C = 'CS8164C'
TYPE_CS8264C = 'CS8264C'
TYPE_CS8364C = 'CS8364C'
TYPE_CS8464C = 'CS8464C'
# ITA/international
TYPE_ITA_E = 'ita-e'
TYPE_ITA_F = 'ita-f'
TYPE_ITA_G = 'ita-g'
TYPE_ITA_H = 'ita-h'
TYPE_ITA_I = 'ita-i'
TYPE_ITA_J = 'ita-j'
TYPE_ITA_K = 'ita-k'
TYPE_ITA_L = 'ita-l'
TYPE_ITA_M = 'ita-m'
TYPE_ITA_N = 'ita-n'
TYPE_ITA_O = 'ita-o'
TYPE_ITA_MULTISTANDARD = 'ita-multistandard'
# USB
TYPE_USB_A = 'usb-a'
TYPE_USB_MICROB = 'usb-micro-b'
TYPE_USB_C = 'usb-c'
# Molex
TYPE_MOLEX_MICRO_FIT_1X2 = 'molex-micro-fit-1x2'
TYPE_MOLEX_MICRO_FIT_2X2 = 'molex-micro-fit-2x2'
TYPE_MOLEX_MICRO_FIT_2X4 = 'molex-micro-fit-2x4'
# Direct current (DC)
TYPE_DC = 'dc-terminal'
# Proprietary
TYPE_EATON_C39 = 'eaton-c39'
TYPE_HDOT_CX = 'hdot-cx'
TYPE_SAF_D_GRID = 'saf-d-grid'
TYPE_NEUTRIK_POWERCON_20A = 'neutrik-powercon-20a'
TYPE_NEUTRIK_POWERCON_32A = 'neutrik-powercon-32a'
TYPE_NEUTRIK_POWERCON_TRUE1 = 'neutrik-powercon-true1'
TYPE_NEUTRIK_POWERCON_TRUE1_TOP = 'neutrik-powercon-true1-top'
TYPE_UBIQUITI_SMARTPOWER = 'ubiquiti-smartpower'
# Other
TYPE_HARDWIRED = 'hardwired'
TYPE_OTHER = 'other'
@strawberry.enum
class PowerOutletFeedLegEnum(Enum):
FEED_LEG_A = 'A'
FEED_LEG_B = 'B'
FEED_LEG_C = 'C'
#
# Interfaces
#
@strawberry.enum
class InterfaceKindEnum(Enum):
KIND_PHYSICAL = 'physical'
KIND_VIRTUAL = 'virtual'
KIND_WIRELESS = 'wireless'
@strawberry.enum
class InterfaceTypeEnum(Enum):
# Virtual
TYPE_VIRTUAL = 'virtual'
TYPE_BRIDGE = 'bridge'
TYPE_LAG = 'lag'
# Ethernet
TYPE_100ME_FX = '100base-fx'
TYPE_100ME_LFX = '100base-lfx'
TYPE_100ME_FIXED = '100base-tx'
TYPE_100ME_T1 = '100base-t1'
TYPE_100ME_SFP = '100base-x-sfp'
TYPE_1GE_FIXED = '1000base-t'
TYPE_1GE_LX_FIXED = '1000base-lx'
TYPE_1GE_TX_FIXED = '1000base-tx'
TYPE_1GE_GBIC = '1000base-x-gbic'
TYPE_1GE_SFP = '1000base-x-sfp'
TYPE_2GE_FIXED = '2.5gbase-t'
TYPE_5GE_FIXED = '5gbase-t'
TYPE_10GE_FIXED = '10gbase-t'
TYPE_10GE_CX4 = '10gbase-cx4'
TYPE_10GE_SFP_PLUS = '10gbase-x-sfpp'
TYPE_10GE_XFP = '10gbase-x-xfp'
TYPE_10GE_XENPAK = '10gbase-x-xenpak'
TYPE_10GE_X2 = '10gbase-x-x2'
TYPE_25GE_SFP28 = '25gbase-x-sfp28'
TYPE_50GE_SFP56 = '50gbase-x-sfp56'
TYPE_40GE_QSFP_PLUS = '40gbase-x-qsfpp'
TYPE_50GE_QSFP28 = '50gbase-x-sfp28'
TYPE_100GE_CFP = '100gbase-x-cfp'
TYPE_100GE_CFP2 = '100gbase-x-cfp2'
TYPE_100GE_CFP4 = '100gbase-x-cfp4'
TYPE_100GE_CXP = '100gbase-x-cxp'
TYPE_100GE_CPAK = '100gbase-x-cpak'
TYPE_100GE_DSFP = '100gbase-x-dsfp'
TYPE_100GE_SFP_DD = '100gbase-x-sfpdd'
TYPE_100GE_QSFP28 = '100gbase-x-qsfp28'
TYPE_100GE_QSFP_DD = '100gbase-x-qsfpdd'
TYPE_200GE_CFP2 = '200gbase-x-cfp2'
TYPE_200GE_QSFP56 = '200gbase-x-qsfp56'
TYPE_200GE_QSFP_DD = '200gbase-x-qsfpdd'
TYPE_400GE_CFP2 = '400gbase-x-cfp2'
TYPE_400GE_QSFP112 = '400gbase-x-qsfp112'
TYPE_400GE_QSFP_DD = '400gbase-x-qsfpdd'
TYPE_400GE_OSFP = '400gbase-x-osfp'
TYPE_400GE_OSFP_RHS = '400gbase-x-osfp-rhs'
TYPE_400GE_CDFP = '400gbase-x-cdfp'
TYPE_400GE_CFP8 = '400gbase-x-cfp8'
TYPE_800GE_QSFP_DD = '800gbase-x-qsfpdd'
TYPE_800GE_OSFP = '800gbase-x-osfp'
# Ethernet Backplane
TYPE_1GE_KX = '1000base-kx'
TYPE_2GE_KX = '2.5gbase-kx'
TYPE_5GE_KR = '5gbase-kr'
TYPE_10GE_KR = '10gbase-kr'
TYPE_10GE_KX4 = '10gbase-kx4'
TYPE_25GE_KR = '25gbase-kr'
TYPE_40GE_KR4 = '40gbase-kr4'
TYPE_50GE_KR = '50gbase-kr'
TYPE_100GE_KP4 = '100gbase-kp4'
TYPE_100GE_KR2 = '100gbase-kr2'
TYPE_100GE_KR4 = '100gbase-kr4'
# Wireless
TYPE_80211A = 'ieee802.11a'
TYPE_80211G = 'ieee802.11g'
TYPE_80211N = 'ieee802.11n'
TYPE_80211AC = 'ieee802.11ac'
TYPE_80211AD = 'ieee802.11ad'
TYPE_80211AX = 'ieee802.11ax'
TYPE_80211AY = 'ieee802.11ay'
TYPE_80211BE = 'ieee802.11be'
TYPE_802151 = 'ieee802.15.1'
TYPE_802154 = 'ieee802.15.4'
TYPE_OTHER_WIRELESS = 'other-wireless'
# Cellular
TYPE_GSM = 'gsm'
TYPE_CDMA = 'cdma'
TYPE_LTE = 'lte'
TYPE_4G = '4g'
TYPE_5G = '5g'
# SONET
TYPE_SONET_OC3 = 'sonet-oc3'
TYPE_SONET_OC12 = 'sonet-oc12'
TYPE_SONET_OC48 = 'sonet-oc48'
TYPE_SONET_OC192 = 'sonet-oc192'
TYPE_SONET_OC768 = 'sonet-oc768'
TYPE_SONET_OC1920 = 'sonet-oc1920'
TYPE_SONET_OC3840 = 'sonet-oc3840'
# Fibrechannel
TYPE_1GFC_SFP = '1gfc-sfp'
TYPE_2GFC_SFP = '2gfc-sfp'
TYPE_4GFC_SFP = '4gfc-sfp'
TYPE_8GFC_SFP_PLUS = '8gfc-sfpp'
TYPE_16GFC_SFP_PLUS = '16gfc-sfpp'
TYPE_32GFC_SFP28 = '32gfc-sfp28'
TYPE_32GFC_SFP_PLUS = '32gfc-sfpp'
TYPE_64GFC_QSFP_PLUS = '64gfc-qsfpp'
TYPE_64GFC_SFP_DD = '64gfc-sfpdd'
TYPE_64GFC_SFP_PLUS = '64gfc-sfpp'
TYPE_128GFC_QSFP28 = '128gfc-qsfp28'
# InfiniBand
TYPE_INFINIBAND_SDR = 'infiniband-sdr'
TYPE_INFINIBAND_DDR = 'infiniband-ddr'
TYPE_INFINIBAND_QDR = 'infiniband-qdr'
TYPE_INFINIBAND_FDR10 = 'infiniband-fdr10'
TYPE_INFINIBAND_FDR = 'infiniband-fdr'
TYPE_INFINIBAND_EDR = 'infiniband-edr'
TYPE_INFINIBAND_HDR = 'infiniband-hdr'
TYPE_INFINIBAND_NDR = 'infiniband-ndr'
TYPE_INFINIBAND_XDR = 'infiniband-xdr'
# Serial
TYPE_T1 = 't1'
TYPE_E1 = 'e1'
TYPE_T3 = 't3'
TYPE_E3 = 'e3'
# ATM/DSL
TYPE_XDSL = 'xdsl'
# Coaxial
TYPE_DOCSIS = 'docsis'
# PON
TYPE_BPON = 'bpon'
TYPE_EPON = 'epon'
TYPE_10G_EPON = '10g-epon'
TYPE_GPON = 'gpon'
TYPE_XG_PON = 'xg-pon'
TYPE_XGS_PON = 'xgs-pon'
TYPE_NG_PON2 = 'ng-pon2'
TYPE_25G_PON = '25g-pon'
TYPE_50G_PON = '50g-pon'
# Stacking
TYPE_STACKWISE = 'cisco-stackwise'
TYPE_STACKWISE_PLUS = 'cisco-stackwise-plus'
TYPE_FLEXSTACK = 'cisco-flexstack'
TYPE_FLEXSTACK_PLUS = 'cisco-flexstack-plus'
TYPE_STACKWISE80 = 'cisco-stackwise-80'
TYPE_STACKWISE160 = 'cisco-stackwise-160'
TYPE_STACKWISE320 = 'cisco-stackwise-320'
TYPE_STACKWISE480 = 'cisco-stackwise-480'
TYPE_STACKWISE1T = 'cisco-stackwise-1t'
TYPE_JUNIPER_VCP = 'juniper-vcp'
TYPE_SUMMITSTACK = 'extreme-summitstack'
TYPE_SUMMITSTACK128 = 'extreme-summitstack-128'
TYPE_SUMMITSTACK256 = 'extreme-summitstack-256'
TYPE_SUMMITSTACK512 = 'extreme-summitstack-512'
# Other
TYPE_OTHER = 'other'
@strawberry.enum
class InterfaceSpeedEnum(Enum):
SPEED_10MBPS = 10000
SPEED_100MBPS = 100000
SPEED_1GBPS = 1000000
SPEED_10GBPS = 10000000
SPEED_25GBPS = 25000000
SPEED_40GBPS = 40000000
SPEED_100GBPS = 100000000
SPEED_200GBPS = 200000000
SPEED_400GBPS = 400000000
@strawberry.enum
class InterfaceDuplexEnum(Enum):
DUPLEX_HALF = 'half'
DUPLEX_FULL = 'full'
DUPLEX_AUTO = 'auto'
@strawberry.enum
class InterfaceModeEnum(Enum):
MODE_ACCESS = 'access'
MODE_TAGGED = 'tagged'
MODE_TAGGED_ALL = 'tagged-all'
MODE_Q_IN_Q = 'q-in-q'
@strawberry.enum
class InterfacePoEModeEnum(Enum):
MODE_PD = 'pd'
MODE_PSE = 'pse'
@strawberry.enum
class InterfacePoETypeEnum(Enum):
TYPE_1_8023AF = 'type1-ieee802.3af'
TYPE_2_8023AT = 'type2-ieee802.3at'
TYPE_3_8023BT = 'type3-ieee802.3bt'
TYPE_4_8023BT = 'type4-ieee802.3bt'
PASSIVE_24V_2PAIR = 'passive-24v-2pair'
PASSIVE_24V_4PAIR = 'passive-24v-4pair'
PASSIVE_48V_2PAIR = 'passive-48v-2pair'
PASSIVE_48V_4PAIR = 'passive-48v-4pair'
#
# FrontPorts/RearPorts
#
@strawberry.enum
class PortTypeEnum(Enum):
TYPE_8P8C = '8p8c'
TYPE_8P6C = '8p6c'
TYPE_8P4C = '8p4c'
TYPE_8P2C = '8p2c'
TYPE_6P6C = '6p6c'
TYPE_6P4C = '6p4c'
TYPE_6P2C = '6p2c'
TYPE_4P4C = '4p4c'
TYPE_4P2C = '4p2c'
TYPE_GG45 = 'gg45'
TYPE_TERA4P = 'tera-4p'
TYPE_TERA2P = 'tera-2p'
TYPE_TERA1P = 'tera-1p'
TYPE_110_PUNCH = '110-punch'
TYPE_BNC = 'bnc'
TYPE_F = 'f'
TYPE_N = 'n'
TYPE_MRJ21 = 'mrj21'
TYPE_ST = 'st'
TYPE_SC = 'sc'
TYPE_SC_PC = 'sc-pc'
TYPE_SC_UPC = 'sc-upc'
TYPE_SC_APC = 'sc-apc'
TYPE_FC = 'fc'
TYPE_LC = 'lc'
TYPE_LC_PC = 'lc-pc'
TYPE_LC_UPC = 'lc-upc'
TYPE_LC_APC = 'lc-apc'
TYPE_MTRJ = 'mtrj'
TYPE_MPO = 'mpo'
TYPE_LSH = 'lsh'
TYPE_LSH_PC = 'lsh-pc'
TYPE_LSH_UPC = 'lsh-upc'
TYPE_LSH_APC = 'lsh-apc'
TYPE_LX5 = 'lx5'
TYPE_LX5_PC = 'lx5-pc'
TYPE_LX5_UPC = 'lx5-upc'
TYPE_LX5_APC = 'lx5-apc'
TYPE_SPLICE = 'splice'
TYPE_CS = 'cs'
TYPE_SN = 'sn'
TYPE_SMA_905 = 'sma-905'
TYPE_SMA_906 = 'sma-906'
TYPE_URM_P2 = 'urm-p2'
TYPE_URM_P4 = 'urm-p4'
TYPE_URM_P8 = 'urm-p8'
TYPE_USB_A = 'usb-a'
TYPE_USB_B = 'usb-b'
TYPE_USB_C = 'usb-c'
TYPE_USB_MINI_A = 'usb-mini-a'
TYPE_USB_MINI_B = 'usb-mini-b'
TYPE_USB_MICRO_A = 'usb-micro-a'
TYPE_USB_MICRO_B = 'usb-micro-b'
TYPE_USB_MICRO_AB = 'usb-micro-ab'
TYPE_OTHER = 'other'
#
# Cables/links
#
@strawberry.enum
class CableTypeEnum(Enum):
TYPE_CAT3 = 'cat3'
TYPE_CAT5 = 'cat5'
TYPE_CAT5E = 'cat5e'
TYPE_CAT6 = 'cat6'
TYPE_CAT6A = 'cat6a'
TYPE_CAT7 = 'cat7'
TYPE_CAT7A = 'cat7a'
TYPE_CAT8 = 'cat8'
TYPE_DAC_ACTIVE = 'dac-active'
TYPE_DAC_PASSIVE = 'dac-passive'
TYPE_MRJ21_TRUNK = 'mrj21-trunk'
TYPE_COAXIAL = 'coaxial'
TYPE_MMF = 'mmf'
TYPE_MMF_OM1 = 'mmf-om1'
TYPE_MMF_OM2 = 'mmf-om2'
TYPE_MMF_OM3 = 'mmf-om3'
TYPE_MMF_OM4 = 'mmf-om4'
TYPE_MMF_OM5 = 'mmf-om5'
TYPE_SMF = 'smf'
TYPE_SMF_OS1 = 'smf-os1'
TYPE_SMF_OS2 = 'smf-os2'
TYPE_AOC = 'aoc'
TYPE_POWER = 'power'
TYPE_USB = 'usb'
@strawberry.enum
class LinkStatusEnum(Enum):
STATUS_CONNECTED = 'connected'
STATUS_PLANNED = 'planned'
STATUS_DECOMMISSIONING = 'decommissioning'
@strawberry.enum
class CableLengthUnitEnum(Enum):
# Metric
UNIT_KILOMETER = 'km'
UNIT_METER = 'm'
UNIT_CENTIMETER = 'cm'
# Imperial
UNIT_MILE = 'mi'
UNIT_FOOT = 'ft'
UNIT_INCH = 'in'
#
# CableTerminations
#
@strawberry.enum
class CableEndEnum(Enum):
SIDE_A = 'A'
SIDE_B = 'B'
#
# PowerFeeds
#
@strawberry.enum
class PowerFeedStatusEnum(Enum):
key = 'PowerFeed.status'
STATUS_OFFLINE = 'offline'
STATUS_ACTIVE = 'active'
STATUS_PLANNED = 'planned'
STATUS_FAILED = 'failed'
@strawberry.enum
class PowerFeedTypeEnum(Enum):
TYPE_PRIMARY = 'primary'
TYPE_REDUNDANT = 'redundant'
@strawberry.enum
class PowerFeedSupplyEnum(Enum):
SUPPLY_AC = 'ac'
SUPPLY_DC = 'dc'
@strawberry.enum
class PowerFeedPhaseEnum(Enum):
PHASE_SINGLE = 'single-phase'
PHASE_3PHASE = 'three-phase'
#
# VDC
#
@strawberry.enum
class VirtualDeviceContextStatusEnum(Enum):
key = 'VirtualDeviceContext.status'
STATUS_ACTIVE = 'active'
STATUS_PLANNED = 'planned'
STATUS_OFFLINE = 'offline'
#
# InventoryItem
#
@strawberry.enum
class InventoryItemStatusEnum(Enum):
key = 'InventoryItem.status'
STATUS_OFFLINE = 'offline'
STATUS_ACTIVE = 'active'
STATUS_PLANNED = 'planned'
STATUS_STAGED = 'staged'
STATUS_FAILED = 'failed'
STATUS_DECOMMISSIONING = 'decommissioning'

View File

@ -0,0 +1,138 @@
from dataclasses import dataclass
from typing import Annotated, TYPE_CHECKING
import strawberry
from strawberry import ID
import strawberry_django
from strawberry_django import FilterLookup
from core.graphql.filter_mixins import *
from netbox.graphql.filter_mixins import *
from .enums import *
if TYPE_CHECKING:
from .filters import *
from core.graphql.filter_lookups import *
from extras.graphql.filters import *
from ipam.graphql.filters import *
__all__ = [
'ComponentModelFilterMixin',
'ModularComponentModelFilterMixin',
'CabledObjectModelFilterMixin',
'ComponentTemplateFilterMixin',
'ModularComponentTemplateFilterMixin',
'RenderConfigFilterMixin',
'InterfaceBaseFilterMixin',
'RackBaseFilterMixin',
]
@dataclass
class ComponentModelFilterMixin(NetBoxModelFilterMixin):
device: Annotated['DeviceFilter', strawberry.lazy('dcim.graphql.filters')] | None = strawberry_django.filter_field()
device_id: ID | None = strawberry_django.filter_field()
name: FilterLookup[str] | None = strawberry_django.filter_field()
lable: FilterLookup[str] | None = strawberry_django.filter_field()
description: FilterLookup[str] | None = strawberry_django.filter_field()
@dataclass
class ModularComponentModelFilterMixin(ComponentModelFilterMixin):
module: Annotated['ModuleFilter', strawberry.lazy('dcim.graphql.filters')] | None = strawberry_django.filter_field()
module_id: ID | None = strawberry_django.filter_field()
inventory_items: Annotated['InventoryItemFilter', strawberry.lazy('dcim.graphql.filters')] | None = (
strawberry_django.filter_field()
)
@dataclass
class CabledObjectModelFilterMixin(BaseFilterMixin):
cable: Annotated['CableFilter', strawberry.lazy('dcim.graphql.filters')] | None = strawberry_django.filter_field()
cable_id: ID | None = strawberry_django.filter_field()
cable_end: CableEndEnum | None = strawberry_django.filter_field()
mark_connected: FilterLookup[bool] | None = strawberry_django.filter_field()
@dataclass
class ComponentTemplateFilterMixin(ChangeLogFilterMixin):
device_type: Annotated['DeviceTypeFilter', strawberry.lazy('dcim.graphql.filters')] | None = (
strawberry_django.filter_field()
)
device_type_id: ID | None = strawberry_django.filter_field()
name: FilterLookup[str] | None = strawberry_django.filter_field()
label: FilterLookup[str] | None = strawberry_django.filter_field()
description: FilterLookup[str] | None = strawberry_django.filter_field()
@dataclass
class ModularComponentTemplateFilterMixin(ComponentTemplateFilterMixin):
module_type: Annotated['ModuleTypeFilter', strawberry.lazy('dcim.graphql.filters')] | None = (
strawberry_django.filter_field()
)
@dataclass
class RenderConfigFilterMixin(BaseFilterMixin):
config_template: Annotated['ConfigTemplateFilter', strawberry.lazy('extras.graphql.filters')] | None = (
strawberry_django.filter_field()
)
config_template_id: ID | None = strawberry_django.filter_field()
@dataclass
class InterfaceBaseFilterMixin(BaseFilterMixin):
enabled: FilterLookup[bool] | None = strawberry_django.filter_field()
mtu: Annotated['IntegerLookup', strawberry.lazy('core.graphql.filter_lookups')] | None = (
strawberry_django.filter_field()
)
mode: InterfaceModeEnum | None = strawberry_django.filter_field()
parent: Annotated['InterfaceFilter', strawberry.lazy('dcim.graphql.filters')] | None = (
strawberry_django.filter_field()
)
parent_id: ID | None = strawberry_django.filter_field()
bridge: Annotated['InterfaceFilter', strawberry.lazy('dcim.graphql.filters')] | None = (
strawberry_django.filter_field()
)
bridge_id: ID | None = strawberry_django.filter_field()
untagged_vlan: Annotated['VLANFilter', strawberry.lazy('ipam.graphql.filters')] | None = (
strawberry_django.filter_field()
)
tagged_vlans: Annotated['VLANFilter', strawberry.lazy('ipam.graphql.filters')] | None = (
strawberry_django.filter_field()
)
qinq_svlan: Annotated['VLANFilter', strawberry.lazy('ipam.graphql.filters')] | None = (
strawberry_django.filter_field()
)
vlan_tranlation_policy: Annotated['VLANTranslationPolicyFilter', strawberry.lazy('ipam.graphql.filters')] | None = (
strawberry_django.filter_field()
)
primary_mac_address: Annotated['MACAddressFilter', strawberry.lazy('dcim.graphql.filters')] | None = (
strawberry_django.filter_field()
)
primary_mac_address_id: ID | None = strawberry_django.filter_field()
@dataclass
class RackBaseFilterMixin(WeightFilterMixin, PrimaryModelFilterMixin):
width: Annotated['RackWidthEnum', strawberry.lazy('dcim.graphql.enums')] | None = strawberry_django.filter_field()
u_height: Annotated['IntegerLookup', strawberry.lazy('core.graphql.filter_lookups')] | None = (
strawberry_django.filter_field()
)
starting_unit: Annotated['IntegerLookup', strawberry.lazy('core.graphql.filter_lookups')] | None = (
strawberry_django.filter_field()
)
desc_units: FilterLookup[bool] | None = strawberry_django.filter_field()
outer_width: Annotated['IntegerLookup', strawberry.lazy('core.graphql.filter_lookups')] | None = (
strawberry_django.filter_field()
)
outer_depth: Annotated['IntegerLookup', strawberry.lazy('core.graphql.filter_lookups')] | None = (
strawberry_django.filter_field()
)
outer_unit: Annotated['RackDimensionUnitEnum', strawberry.lazy('dcim.graphql.enums')] | None = (
strawberry_django.filter_field()
)
mounting_depth: Annotated['IntegerLookup', strawberry.lazy('core.graphql.filter_lookups')] | None = (
strawberry_django.filter_field()
)
max_weight: Annotated['IntegerLookup', strawberry.lazy('core.graphql.filter_lookups')] | None = (
strawberry_django.filter_field()
)

View File

@ -1,7 +1,41 @@
from typing import Annotated, TYPE_CHECKING
import strawberry
from strawberry.scalars import ID
import strawberry_django import strawberry_django
from strawberry_django import (
FilterLookup,
)
from extras.graphql.filter_mixins import (
ConfigContextFilterMixin,
)
from netbox.graphql.filter_mixins import (
PrimaryModelFilterMixin,
OrganizationalModelFilterMixin,
NestedGroupModelFilterMixin,
ImageAttachmentFilterMixin,
WeightFilterMixin,
)
from .filter_mixins import *
from dcim import models
from core.graphql.filter_mixins import *
from tenancy.graphql.filter_mixins import TenancyFilterMixin, ContactFilterMixin
if TYPE_CHECKING:
from .enums import *
from netbox.graphql.enums import *
from wireless.graphql.enums import *
from core.graphql.filter_lookups import *
from core.graphql.filters import *
from extras.graphql.filters import *
from circuits.graphql.filters import *
from dcim.graphql.filters import *
from ipam.graphql.filters import *
from tenancy.graphql.filters import *
from wireless.graphql.filters import *
from users.graphql.filters import *
from virtualization.graphql.filters import *
from vpn.graphql.filters import *
from dcim import filtersets, models
from netbox.graphql.filter_mixins import autotype_decorator, BaseFilterMixin
__all__ = ( __all__ = (
'CableFilter', 'CableFilter',
@ -51,258 +85,766 @@ __all__ = (
@strawberry_django.filter(models.Cable, lookups=True) @strawberry_django.filter(models.Cable, lookups=True)
@autotype_decorator(filtersets.CableFilterSet) class CableFilter(PrimaryModelFilterMixin, TenancyFilterMixin):
class CableFilter(BaseFilterMixin): type: Annotated['CableTypeEnum', strawberry.lazy('dcim.graphql.enums')] | None = strawberry_django.filter_field()
pass status: Annotated['LinkStatusEnum', strawberry.lazy('dcim.graphql.enums')] | None = strawberry_django.filter_field()
label: FilterLookup[str] | None = strawberry_django.filter_field()
color: Annotated['ColorEnum', strawberry.lazy('netbox.graphql.enums')] | None = strawberry_django.filter_field()
length: Annotated['FloatLookup', strawberry.lazy('core.graphql.filter_lookups')] | None = (
strawberry_django.filter_field()
)
length_unit: Annotated['CableLengthUnitEnum', strawberry.lazy('dcim.graphql.enums')] | None = (
strawberry_django.filter_field()
)
terminations: Annotated['CableTerminationFilter', strawberry.lazy('dcim.graphql.filters')] | None = (
strawberry_django.filter_field()
)
@strawberry_django.filter(models.CableTermination, lookups=True) @strawberry_django.filter(models.CableTermination, lookups=True)
@autotype_decorator(filtersets.CableTerminationFilterSet) class CableTerminationFilter(ChangeLogFilterMixin):
class CableTerminationFilter(BaseFilterMixin): cable: Annotated['CableFilter', strawberry.lazy('dcim.graphql.filters')] | None = strawberry_django.filter_field()
pass cable_id: ID | None = strawberry_django.filter_field()
cable_end: Annotated['CableEndEnum', strawberry.lazy('dcim.graphql.enums')] | None = (
strawberry_django.filter_field()
)
termination_type: Annotated['CableTerminationFilter', strawberry.lazy('dcim.graphql.filters')] | None = (
strawberry_django.filter_field()
)
termination_id: ID | None = strawberry_django.filter_field()
@strawberry_django.filter(models.ConsolePort, lookups=True) @strawberry_django.filter(models.ConsolePort, lookups=True)
@autotype_decorator(filtersets.ConsolePortFilterSet) class ConsolePortFilter(ModularComponentModelFilterMixin, CabledObjectModelFilterMixin):
class ConsolePortFilter(BaseFilterMixin): type: Annotated['ConsolePortTypeEnum', strawberry.lazy('dcim.graphql.enums')] | None = (
pass strawberry_django.filter_field()
)
speed: Annotated['ConsolePortSpeedEnum', strawberry.lazy('dcim.graphql.enums')] | None = (
strawberry_django.filter_field()
)
@strawberry_django.filter(models.ConsolePortTemplate, lookups=True) @strawberry_django.filter(models.ConsolePortTemplate, lookups=True)
@autotype_decorator(filtersets.ConsolePortTemplateFilterSet) class ConsolePortTemplateFilter(ModularComponentTemplateFilterMixin):
class ConsolePortTemplateFilter(BaseFilterMixin): type: Annotated['ConsolePortTypeEnum', strawberry.lazy('dcim.graphql.enums')] | None = (
pass strawberry_django.filter_field()
)
@strawberry_django.filter(models.ConsoleServerPort, lookups=True) @strawberry_django.filter(models.ConsoleServerPort, lookups=True)
@autotype_decorator(filtersets.ConsoleServerPortFilterSet) class ConsoleServerPortFilter(ModularComponentModelFilterMixin, CabledObjectModelFilterMixin):
class ConsoleServerPortFilter(BaseFilterMixin): type: Annotated['ConsolePortTypeEnum', strawberry.lazy('dcim.graphql.enums')] | None = (
pass strawberry_django.filter_field()
)
speed: Annotated['ConsolePortSpeedEnum', strawberry.lazy('dcim.graphql.enums')] | None = (
strawberry_django.filter_field()
)
@strawberry_django.filter(models.ConsoleServerPortTemplate, lookups=True) @strawberry_django.filter(models.ConsoleServerPortTemplate, lookups=True)
@autotype_decorator(filtersets.ConsoleServerPortTemplateFilterSet) class ConsoleServerPortTemplateFilter(ModularComponentTemplateFilterMixin):
class ConsoleServerPortTemplateFilter(BaseFilterMixin): type: Annotated['ConsolePortTypeEnum', strawberry.lazy('dcim.graphql.enums')] | None = (
pass strawberry_django.filter_field()
)
@strawberry_django.filter(models.Device, lookups=True) @strawberry_django.filter(models.Device, lookups=True)
@autotype_decorator(filtersets.DeviceFilterSet) class DeviceFilter(
class DeviceFilter(BaseFilterMixin): ContactFilterMixin,
pass TenancyFilterMixin,
ImageAttachmentFilterMixin,
RenderConfigFilterMixin,
ConfigContextFilterMixin,
PrimaryModelFilterMixin,
):
device_type: Annotated['DeviceTypeFilter', strawberry.lazy('dcim.graphql.filters')] | None = (
strawberry_django.filter_field()
)
device_type_id: ID | None = strawberry_django.filter_field()
role: Annotated['DeviceRoleFilter', strawberry.lazy('dcim.graphql.filters')] | None = (
strawberry_django.filter_field()
)
role_id: ID | None = strawberry_django.filter_field()
platform: Annotated['PlatformFilter', strawberry.lazy('dcim.graphql.filters')] | None = (
strawberry_django.filter_field()
)
name: FilterLookup[str] | None = strawberry_django.filter_field()
serial: FilterLookup[str] | None = strawberry_django.filter_field()
asset_tag: FilterLookup[str] | None = strawberry_django.filter_field()
site: Annotated['SiteFilter', strawberry.lazy('dcim.graphql.filters')] | None = strawberry_django.filter_field()
site_id: ID | None = strawberry_django.filter_field()
location: Annotated['LocationFilter', strawberry.lazy('dcim.graphql.filters')] | None = (
strawberry_django.filter_field()
)
location_id: Annotated['TreeNodeFilter', strawberry.lazy('core.graphql.filter_lookups')] | None = (
strawberry_django.filter_field()
)
rack: Annotated['RackFilter', strawberry.lazy('dcim.graphql.filters')] | None = strawberry_django.filter_field()
rack_id: ID | None = strawberry_django.filter_field()
position: Annotated['FloatLookup', strawberry.lazy('core.graphql.filter_lookups')] | None = (
strawberry_django.filter_field()
)
face: Annotated['DeviceFaceEnum', strawberry.lazy('dcim.graphql.enums')] | None = strawberry_django.filter_field()
status: Annotated['DeviceStatusEnum', strawberry.lazy('dcim.graphql.enums')] | None = (
strawberry_django.filter_field()
)
airflow: Annotated['DeviceAirflowEnum', strawberry.lazy('dcim.graphql.enums')] | None = (
strawberry_django.filter_field()
)
primary_ip4: Annotated['IPAddressFilter', strawberry.lazy('ipam.graphql.filters')] | None = (
strawberry_django.filter_field()
)
primary_ip4_id: ID | None = strawberry_django.filter_field()
primary_ip6: Annotated['IPAddressFilter', strawberry.lazy('ipam.graphql.filters')] | None = (
strawberry_django.filter_field()
)
primary_ip6_id: ID | None = strawberry_django.filter_field()
oob_ip: Annotated['IPAddressFilter', strawberry.lazy('ipam.graphql.filters')] | None = (
strawberry_django.filter_field()
)
oob_ip_id: ID | None = strawberry_django.filter_field()
cluster: Annotated['ClusterFilter', strawberry.lazy('virtualization.graphql.filters')] | None = (
strawberry_django.filter_field()
)
cluster_id: ID | None = strawberry_django.filter_field()
virtual_chassis: Annotated['VirtualChassisFilter', strawberry.lazy('dcim.graphql.filters')] | None = (
strawberry_django.filter_field()
)
virtual_chassis_id: ID | None = strawberry_django.filter_field()
vc_position: Annotated['IntegerLookup', strawberry.lazy('core.graphql.filter_lookups')] | None = (
strawberry_django.filter_field()
)
vc_priority: Annotated['IntegerLookup', strawberry.lazy('core.graphql.filter_lookups')] | None = (
strawberry_django.filter_field()
)
latitude: Annotated['FloatLookup', strawberry.lazy('core.graphql.filter_lookups')] | None = (
strawberry_django.filter_field()
)
longitude: Annotated['FloatLookup', strawberry.lazy('core.graphql.filter_lookups')] | None = (
strawberry_django.filter_field()
)
interfaces: Annotated['InterfaceFilter', strawberry.lazy('dcim.graphql.filters')] | None = (
strawberry_django.filter_field()
)
consoleports: Annotated['ConsolePortFilter', strawberry.lazy('dcim.graphql.filters')] | None = (
strawberry_django.filter_field()
)
consoleserverports: Annotated['ConsoleServerPortFilter', strawberry.lazy('dcim.graphql.filters')] | None = (
strawberry_django.filter_field()
)
poweroutlets: Annotated['PowerOutletFilter', strawberry.lazy('dcim.graphql.filters')] | None = (
strawberry_django.filter_field()
)
powerports: Annotated['PowerPortFilter', strawberry.lazy('dcim.graphql.filters')] | None = (
strawberry_django.filter_field()
)
devicebays: Annotated['DeviceBayFilter', strawberry.lazy('dcim.graphql.filters')] | None = (
strawberry_django.filter_field()
)
frontports: Annotated['FrontPortFilter', strawberry.lazy('dcim.graphql.filters')] | None = (
strawberry_django.filter_field()
)
rearports: Annotated['RearPortFilter', strawberry.lazy('dcim.graphql.filters')] | None = (
strawberry_django.filter_field()
)
modulebays: Annotated['ModuleBayFilter', strawberry.lazy('dcim.graphql.filters')] | None = (
strawberry_django.filter_field()
)
modules: Annotated['ModuleFilter', strawberry.lazy('dcim.graphql.filters')] | None = (
strawberry_django.filter_field()
)
@strawberry_django.filter(models.DeviceBay, lookups=True) @strawberry_django.filter(models.DeviceBay, lookups=True)
@autotype_decorator(filtersets.DeviceBayFilterSet) class DeviceBayFilter(ComponentModelFilterMixin):
class DeviceBayFilter(BaseFilterMixin): installed_device: Annotated['DeviceFilter', strawberry.lazy('dcim.graphql.filters')] | None = (
pass strawberry_django.filter_field()
)
installed_device_id: ID | None = strawberry_django.filter_field()
@strawberry_django.filter(models.DeviceBayTemplate, lookups=True) @strawberry_django.filter(models.DeviceBayTemplate, lookups=True)
@autotype_decorator(filtersets.DeviceBayTemplateFilterSet) class DeviceBayTemplateFilter(ComponentTemplateFilterMixin):
class DeviceBayTemplateFilter(BaseFilterMixin):
pass pass
@strawberry_django.filter(models.InventoryItemTemplate, lookups=True) @strawberry_django.filter(models.InventoryItemTemplate, lookups=True)
@autotype_decorator(filtersets.InventoryItemTemplateFilterSet) class InventoryItemTemplateFilter(ComponentTemplateFilterMixin):
class InventoryItemTemplateFilter(BaseFilterMixin): parent: Annotated['InventoryItemTemplateFilter', strawberry.lazy('dcim.graphql.filters')] | None = (
pass strawberry_django.filter_field()
)
component_type: Annotated['ContentTypeFilter', strawberry.lazy('core.graphql.filters')] | None = (
strawberry_django.filter_field()
)
component_id: ID | None = strawberry_django.filter_field()
role: Annotated['InventoryItemRoleFilter', strawberry.lazy('dcim.graphql.filters')] | None = (
strawberry_django.filter_field()
)
role_id: ID | None = strawberry_django.filter_field()
manufacturer: Annotated['ManufacturerFilter', strawberry.lazy('dcim.graphql.filters')] | None = (
strawberry_django.filter_field()
)
manufacturer_id: ID | None = strawberry_django.filter_field()
part_id: FilterLookup[str] | None = strawberry_django.filter_field()
@strawberry_django.filter(models.DeviceRole, lookups=True) @strawberry_django.filter(models.DeviceRole, lookups=True)
@autotype_decorator(filtersets.DeviceRoleFilterSet) class DeviceRoleFilter(OrganizationalModelFilterMixin, RenderConfigFilterMixin):
class DeviceRoleFilter(BaseFilterMixin): color: Annotated['ColorEnum', strawberry.lazy('netbox.graphql.enums')] | None = strawberry_django.filter_field()
pass vm_role: FilterLookup[bool] | None = strawberry_django.filter_field()
@strawberry_django.filter(models.DeviceType, lookups=True) @strawberry_django.filter(models.DeviceType, lookups=True)
@autotype_decorator(filtersets.DeviceTypeFilterSet) class DeviceTypeFilter(ImageAttachmentFilterMixin, PrimaryModelFilterMixin, WeightFilterMixin):
class DeviceTypeFilter(BaseFilterMixin): manufacturer: Annotated['ManufacturerFilter', strawberry.lazy('dcim.graphql.filters')] | None = (
pass strawberry_django.filter_field()
)
manufacturer_id: ID | None = strawberry_django.filter_field()
model: FilterLookup[str] | None = strawberry_django.filter_field()
slug: FilterLookup[str] | None = strawberry_django.filter_field()
default_platform: Annotated['PlatformFilter', strawberry.lazy('dcim.graphql.filters')] | None = (
strawberry_django.filter_field()
)
default_platform_id: ID | None = strawberry_django.filter_field()
part_number: FilterLookup[str] | None = strawberry_django.filter_field()
u_height: Annotated['FloatLookup', strawberry.lazy('core.graphql.filter_lookups')] | None = (
strawberry_django.filter_field()
)
exclude_from_utilization: FilterLookup[bool] | None = strawberry_django.filter_field()
is_full_depth: FilterLookup[bool] | None = strawberry_django.filter_field()
subdevice_role: Annotated['SubdeviceRoleEnum', strawberry.lazy('dcim.graphql.enums')] | None = (
strawberry_django.filter_field()
)
airflow: Annotated['DeviceAirflowEnum', strawberry.lazy('dcim.graphql.enums')] | None = (
strawberry_django.filter_field()
)
front_image: Annotated['ImageAttachmentFilter', strawberry.lazy('extras.graphql.filters')] | None = (
strawberry_django.filter_field()
)
rear_image: Annotated['ImageAttachmentFilter', strawberry.lazy('extras.graphql.filters')] | None = (
strawberry_django.filter_field()
)
@strawberry_django.filter(models.FrontPort, lookups=True) @strawberry_django.filter(models.FrontPort, lookups=True)
@autotype_decorator(filtersets.FrontPortFilterSet) class FrontPortFilter(ModularComponentModelFilterMixin, CabledObjectModelFilterMixin):
class FrontPortFilter(BaseFilterMixin): type: Annotated['PortTypeEnum', strawberry.lazy('dcim.graphql.enums')] | None = strawberry_django.filter_field()
pass color: Annotated['ColorEnum', strawberry.lazy('netbox.graphql.enums')] | None = strawberry_django.filter_field()
rear_port: Annotated['RearPortFilter', strawberry.lazy('dcim.graphql.filters')] | None = (
strawberry_django.filter_field()
)
rear_port_id: ID | None = strawberry_django.filter_field()
rear_port_position: Annotated['IntegerLookup', strawberry.lazy('core.graphql.filter_lookups')] | None = (
strawberry_django.filter_field()
)
@strawberry_django.filter(models.FrontPortTemplate, lookups=True) @strawberry_django.filter(models.FrontPortTemplate, lookups=True)
@autotype_decorator(filtersets.FrontPortTemplateFilterSet) class FrontPortTemplateFilter(ModularComponentTemplateFilterMixin):
class FrontPortTemplateFilter(BaseFilterMixin): type: Annotated['PortTypeEnum', strawberry.lazy('dcim.graphql.enums')] | None = strawberry_django.filter_field()
pass color: Annotated['ColorEnum', strawberry.lazy('netbox.graphql.enums')] | None = strawberry_django.filter_field()
rear_port: Annotated['RearPortTemplateFilter', strawberry.lazy('dcim.graphql.filters')] | None = (
strawberry_django.filter_field()
)
rear_port_id: ID | None = strawberry_django.filter_field()
rear_port_position: Annotated['IntegerLookup', strawberry.lazy('core.graphql.filter_lookups')] | None = (
strawberry_django.filter_field()
)
@strawberry_django.filter(models.MACAddress, lookups=True) @strawberry_django.filter(models.MACAddress, lookups=True)
@autotype_decorator(filtersets.MACAddressFilterSet) class MACAddressFilter(PrimaryModelFilterMixin):
class MACAddressFilter(BaseFilterMixin): mac_address: FilterLookup[str] | None = strawberry_django.filter_field()
pass assigned_object_type: Annotated['ContentTypeFilter', strawberry.lazy('core.graphql.filters')] | None = (
strawberry_django.filter_field()
)
assigned_object_id: ID | None = strawberry_django.filter_field()
@strawberry_django.filter(models.Interface, lookups=True) @strawberry_django.filter(models.Interface, lookups=True)
@autotype_decorator(filtersets.InterfaceFilterSet) class InterfaceFilter(ModularComponentModelFilterMixin, InterfaceBaseFilterMixin, CabledObjectModelFilterMixin):
class InterfaceFilter(BaseFilterMixin): vcdcs: Annotated['VirtualDeviceContextFilter', strawberry.lazy('dcim.graphql.filters')] | None = (
pass strawberry_django.filter_field()
)
lag: Annotated['InterfaceFilter', strawberry.lazy('dcim.graphql.filters')] | None = strawberry_django.filter_field()
lag_id: ID | None = strawberry_django.filter_field()
type: Annotated['InterfaceTypeEnum', strawberry.lazy('dcim.graphql.enums')] | None = (
strawberry_django.filter_field()
)
mgmt_only: FilterLookup[bool] | None = strawberry_django.filter_field()
speed: Annotated['IntegerLookup', strawberry.lazy('core.graphql.filter_lookups')] | None = (
strawberry_django.filter_field()
)
duplex: Annotated['InterfaceDuplexEnum', strawberry.lazy('dcim.graphql.enums')] | None = (
strawberry_django.filter_field()
)
wwn: FilterLookup[str] | None = strawberry_django.filter_field()
rf_role: Annotated['WirelessRoleEnum', strawberry.lazy('wireless.graphql.enums')] | None = (
strawberry_django.filter_field()
)
rf_channel: Annotated['WirelessChannelEnum', strawberry.lazy('wireless.graphql.enums')] | None = (
strawberry_django.filter_field()
)
rf_channel_frequency: Annotated['FloatLookup', strawberry.lazy('core.graphql.filter_lookups')] | None = (
strawberry_django.filter_field()
)
rf_channel_width: Annotated['FloatLookup', strawberry.lazy('core.graphql.filter_lookups')] | None = (
strawberry_django.filter_field()
)
tx_power: Annotated['IntegerLookup', strawberry.lazy('core.graphql.filter_lookups')] | None = (
strawberry_django.filter_field()
)
poe_mode: Annotated['InterfacePoEModeEnum', strawberry.lazy('dcim.graphql.enums')] | None = (
strawberry_django.filter_field()
)
poe_type: Annotated['InterfacePoETypeEnum', strawberry.lazy('dcim.graphql.enums')] | None = (
strawberry_django.filter_field()
)
wireless_link: Annotated['WirelessLinkFilter', strawberry.lazy('wireless.graphql.filters')] | None = (
strawberry_django.filter_field()
)
wireless_link_id: ID | None = strawberry_django.filter_field()
wireless_lans: Annotated['WirelessLANFilter', strawberry.lazy('wireless.graphql.filters')] | None = (
strawberry_django.filter_field()
)
vrf: Annotated['VRFFilter', strawberry.lazy('ipam.graphql.filters')] | None = strawberry_django.filter_field()
vrf_id: ID | None = strawberry_django.filter_field()
ip_addresses: Annotated['IPAddressFilter', strawberry.lazy('ipam.graphql.filters')] | None = (
strawberry_django.filter_field()
)
mac_addresses: Annotated['MACAddressFilter', strawberry.lazy('dcim.graphql.filters')] | None = (
strawberry_django.filter_field()
)
fhrp_group_assignments: Annotated['FHRPGroupAssignmentFilter', strawberry.lazy('ipam.graphql.filters')] | None = (
strawberry_django.filter_field()
)
tunnel_terminations: Annotated['TunnelTerminationFilter', strawberry.lazy('vpn.graphql.filters')] | None = (
strawberry_django.filter_field()
)
l2vpn_terminations: Annotated['L2VPNFilter', strawberry.lazy('vpn.graphql.filters')] | None = (
strawberry_django.filter_field()
)
@strawberry_django.filter(models.InterfaceTemplate, lookups=True) @strawberry_django.filter(models.InterfaceTemplate, lookups=True)
@autotype_decorator(filtersets.InterfaceTemplateFilterSet) class InterfaceTemplateFilter(ModularComponentTemplateFilterMixin):
class InterfaceTemplateFilter(BaseFilterMixin): type: Annotated['InterfaceTypeEnum', strawberry.lazy('dcim.graphql.enums')] | None = (
pass strawberry_django.filter_field()
)
enabled: FilterLookup[bool] | None = strawberry_django.filter_field()
mgmt_only: FilterLookup[bool] | None = strawberry_django.filter_field()
bridge: Annotated['InterfaceTemplateFilter', strawberry.lazy('dcim.graphql.filters')] | None = (
strawberry_django.filter_field()
)
bridge_id: ID | None = strawberry_django.filter_field()
poe_mode: Annotated['InterfacePoEModeEnum', strawberry.lazy('dcim.graphql.enums')] | None = (
strawberry_django.filter_field()
)
poe_type: Annotated['InterfacePoETypeEnum', strawberry.lazy('dcim.graphql.enums')] | None = (
strawberry_django.filter_field()
)
rf_role: Annotated['WirelessRoleEnum', strawberry.lazy('wireless.graphql.enums')] | None = (
strawberry_django.filter_field()
)
@strawberry_django.filter(models.InventoryItem, lookups=True) @strawberry_django.filter(models.InventoryItem, lookups=True)
@autotype_decorator(filtersets.InventoryItemFilterSet) class InventoryItemFilter(ComponentModelFilterMixin):
class InventoryItemFilter(BaseFilterMixin): parent: Annotated['InventoryItemFilter', strawberry.lazy('dcim.graphql.filters')] | None = (
pass strawberry_django.filter_field()
)
parent_id: ID | None = strawberry_django.filter_field()
component_type: Annotated['ContentTypeFilter', strawberry.lazy('core.graphql.filters')] | None = (
strawberry_django.filter_field()
)
component_id: ID | None = strawberry_django.filter_field()
status: Annotated['InventoryItemStatusEnum', strawberry.lazy('dcim.graphql.enums')] | None = (
strawberry_django.filter_field()
)
role: Annotated['InventoryItemRoleFilter', strawberry.lazy('dcim.graphql.filters')] | None = (
strawberry_django.filter_field()
)
role_id: ID | None = strawberry_django.filter_field()
manufacturer: Annotated['ManufacturerFilter', strawberry.lazy('dcim.graphql.filters')] | None = (
strawberry_django.filter_field()
)
manufacturer_id: ID | None = strawberry_django.filter_field()
part_id: FilterLookup[str] | None = strawberry_django.filter_field()
serial: FilterLookup[str] | None = strawberry_django.filter_field()
asset_tag: FilterLookup[str] | None = strawberry_django.filter_field()
discovered: FilterLookup[bool] | None = strawberry_django.filter_field()
@strawberry_django.filter(models.InventoryItemRole, lookups=True) @strawberry_django.filter(models.InventoryItemRole, lookups=True)
@autotype_decorator(filtersets.InventoryItemRoleFilterSet) class InventoryItemRoleFilter(OrganizationalModelFilterMixin):
class InventoryItemRoleFilter(BaseFilterMixin): color: Annotated['ColorEnum', strawberry.lazy('netbox.graphql.enums')] | None = strawberry_django.filter_field()
pass
@strawberry_django.filter(models.Location, lookups=True) @strawberry_django.filter(models.Location, lookups=True)
@autotype_decorator(filtersets.LocationFilterSet) class LocationFilter(ContactFilterMixin, ImageAttachmentFilterMixin, NestedGroupModelFilterMixin):
class LocationFilter(BaseFilterMixin): site: Annotated['SiteFilter', strawberry.lazy('dcim.graphql.filters')] | None = strawberry_django.filter_field()
pass site_id: ID | None = strawberry_django.filter_field()
status: Annotated['LocationStatusEnum', strawberry.lazy('dcim.graphql.enums')] | None = (
strawberry_django.filter_field()
)
tenant: Annotated['TenantFilter', strawberry.lazy('tenancy.graphql.filters')] | None = (
strawberry_django.filter_field()
)
tenant_id: ID | None = strawberry_django.filter_field()
facility: FilterLookup[str] | None = strawberry_django.filter_field()
prefixes: Annotated['PrefixFilter', strawberry.lazy('ipam.graphql.filters')] | None = (
strawberry_django.filter_field()
)
vlan_groups: Annotated['VLANGroupFilter', strawberry.lazy('ipam.graphql.filters')] | None = (
strawberry_django.filter_field()
)
@strawberry_django.filter(models.Manufacturer, lookups=True) @strawberry_django.filter(models.Manufacturer, lookups=True)
@autotype_decorator(filtersets.ManufacturerFilterSet) class ManufacturerFilter(ContactFilterMixin, OrganizationalModelFilterMixin):
class ManufacturerFilter(BaseFilterMixin):
pass pass
@strawberry_django.filter(models.Module, lookups=True) @strawberry_django.filter(models.Module, lookups=True)
@autotype_decorator(filtersets.ModuleFilterSet) class ModuleFilter(PrimaryModelFilterMixin, ConfigContextFilterMixin):
class ModuleFilter(BaseFilterMixin): device: Annotated['DeviceFilter', strawberry.lazy('dcim.graphql.filters')] | None = strawberry_django.filter_field()
pass device_id: ID | None = strawberry_django.filter_field()
module_bay: Annotated['ModuleBayFilter', strawberry.lazy('dcim.graphql.filters')] | None = (
strawberry_django.filter_field()
)
module_bay_id: ID | None = strawberry_django.filter_field()
module_type: Annotated['ModuleTypeFilter', strawberry.lazy('dcim.graphql.filters')] | None = (
strawberry_django.filter_field()
)
module_type_id: ID | None = strawberry_django.filter_field()
status: Annotated['ModuleStatusEnum', strawberry.lazy('dcim.graphql.enums')] | None = (
strawberry_django.filter_field()
)
serial: FilterLookup[str] | None = strawberry_django.filter_field()
asset_tag: FilterLookup[str] | None = strawberry_django.filter_field()
@strawberry_django.filter(models.ModuleBay, lookups=True) @strawberry_django.filter(models.ModuleBay, lookups=True)
@autotype_decorator(filtersets.ModuleBayFilterSet) class ModuleBayFilter(ModularComponentModelFilterMixin):
class ModuleBayFilter(BaseFilterMixin): parent: Annotated['ModuleBayFilter', strawberry.lazy('dcim.graphql.filters')] | None = (
pass strawberry_django.filter_field()
)
parent_id: ID | None = strawberry_django.filter_field()
position: FilterLookup[str] | None = strawberry_django.filter_field()
@strawberry_django.filter(models.ModuleBayTemplate, lookups=True) @strawberry_django.filter(models.ModuleBayTemplate, lookups=True)
@autotype_decorator(filtersets.ModuleBayTemplateFilterSet) class ModuleBayTemplateFilter(ModularComponentTemplateFilterMixin):
class ModuleBayTemplateFilter(BaseFilterMixin): position: FilterLookup[str] | None = strawberry_django.filter_field()
pass
@strawberry_django.filter(models.ModuleType, lookups=True) @strawberry_django.filter(models.ModuleType, lookups=True)
@autotype_decorator(filtersets.ModuleTypeFilterSet) class ModuleTypeFilter(ImageAttachmentFilterMixin, PrimaryModelFilterMixin, WeightFilterMixin):
class ModuleTypeFilter(BaseFilterMixin): manufacturer: Annotated['ManufacturerFilter', strawberry.lazy('dcim.graphql.filters')] | None = (
pass strawberry_django.filter_field()
)
manufacturer_id: ID | None = strawberry_django.filter_field()
model: FilterLookup[str] | None = strawberry_django.filter_field()
part_number: FilterLookup[str] | None = strawberry_django.filter_field()
airflow: Annotated['ModuleAirflowEnum', strawberry.lazy('dcim.graphql.enums')] | None = (
strawberry_django.filter_field()
)
@strawberry_django.filter(models.Platform, lookups=True) @strawberry_django.filter(models.Platform, lookups=True)
@autotype_decorator(filtersets.PlatformFilterSet) class PlatformFilter(OrganizationalModelFilterMixin):
class PlatformFilter(BaseFilterMixin): manufacturer: Annotated['ManufacturerFilter', strawberry.lazy('dcim.graphql.filters')] | None = (
pass strawberry_django.filter_field()
)
manufacturer_id: ID | None = strawberry_django.filter_field()
config_template: Annotated['ConfigTemplateFilter', strawberry.lazy('extras.graphql.filters')] | None = (
strawberry_django.filter_field()
)
config_template_id: ID | None = strawberry_django.filter_field()
@strawberry_django.filter(models.PowerFeed, lookups=True) @strawberry_django.filter(models.PowerFeed, lookups=True)
@autotype_decorator(filtersets.PowerFeedFilterSet) class PowerFeedFilter(PrimaryModelFilterMixin, CabledObjectModelFilterMixin):
class PowerFeedFilter(BaseFilterMixin): power_panel: Annotated['PowerPanelFilter', strawberry.lazy('dcim.graphql.filters')] | None = (
pass strawberry_django.filter_field()
)
power_panel_id: ID | None = strawberry_django.filter_field()
rack: Annotated['RackFilter', strawberry.lazy('dcim.graphql.filters')] | None = strawberry_django.filter_field()
rack_id: ID | None = strawberry_django.filter_field()
name: FilterLookup[str] | None = strawberry_django.filter_field()
status: Annotated['PowerFeedStatusEnum', strawberry.lazy('dcim.graphql.enums')] | None = (
strawberry_django.filter_field()
)
type: Annotated['PowerFeedTypeEnum', strawberry.lazy('dcim.graphql.enums')] | None = (
strawberry_django.filter_field()
)
supply: Annotated['PowerFeedSupplyEnum', strawberry.lazy('dcim.graphql.enums')] | None = (
strawberry_django.filter_field()
)
phase: Annotated['PowerFeedPhaseEnum', strawberry.lazy('dcim.graphql.enums')] | None = (
strawberry_django.filter_field()
)
voltage: Annotated['IntegerLookup', strawberry.lazy('core.graphql.filter_lookups')] | None = (
strawberry_django.filter_field()
)
amperage: Annotated['IntegerLookup', strawberry.lazy('core.graphql.filter_lookups')] | None = (
strawberry_django.filter_field()
)
max_utilization: Annotated['IntegerLookup', strawberry.lazy('core.graphql.filter_lookups')] | None = (
strawberry_django.filter_field()
)
available_power: Annotated['IntegerLookup', strawberry.lazy('core.graphql.filter_lookups')] | None = (
strawberry_django.filter_field()
)
tenant: Annotated['TenantFilter', strawberry.lazy('tenancy.graphql.filters')] | None = (
strawberry_django.filter_field()
)
tenant_id: ID | None = strawberry_django.filter_field()
@strawberry_django.filter(models.PowerOutlet, lookups=True) @strawberry_django.filter(models.PowerOutlet, lookups=True)
@autotype_decorator(filtersets.PowerOutletFilterSet) class PowerOutletFilter(ModularComponentModelFilterMixin, CabledObjectModelFilterMixin):
class PowerOutletFilter(BaseFilterMixin): type: Annotated['PowerOutletTypeEnum', strawberry.lazy('dcim.graphql.enums')] | None = (
pass strawberry_django.filter_field()
)
power_port: Annotated['PowerPortFilter', strawberry.lazy('dcim.graphql.filters')] | None = (
strawberry_django.filter_field()
)
power_port_id: ID | None = strawberry_django.filter_field()
feed_leg: Annotated['PowerOutletFeedLegEnum', strawberry.lazy('dcim.graphql.enums')] | None = (
strawberry_django.filter_field()
)
color: Annotated['ColorEnum', strawberry.lazy('netbox.graphql.enums')] | None = strawberry_django.filter_field()
@strawberry_django.filter(models.PowerOutletTemplate, lookups=True) @strawberry_django.filter(models.PowerOutletTemplate, lookups=True)
@autotype_decorator(filtersets.PowerOutletTemplateFilterSet) class PowerOutletTemplateFilter(ModularComponentModelFilterMixin):
class PowerOutletTemplateFilter(BaseFilterMixin): type: Annotated['PowerOutletTypeEnum', strawberry.lazy('dcim.graphql.enums')] | None = (
pass strawberry_django.filter_field()
)
power_port: Annotated['PowerPortTemplateFilter', strawberry.lazy('dcim.graphql.filters')] | None = (
strawberry_django.filter_field()
)
power_port_id: ID | None = strawberry_django.filter_field()
feed_leg: Annotated['PowerOutletFeedLegEnum', strawberry.lazy('dcim.graphql.enums')] | None = (
strawberry_django.filter_field()
)
@strawberry_django.filter(models.PowerPanel, lookups=True) @strawberry_django.filter(models.PowerPanel, lookups=True)
@autotype_decorator(filtersets.PowerPanelFilterSet) class PowerPanelFilter(ContactFilterMixin, ImageAttachmentFilterMixin, PrimaryModelFilterMixin):
class PowerPanelFilter(BaseFilterMixin): site: Annotated['SiteFilter', strawberry.lazy('dcim.graphql.filters')] | None = strawberry_django.filter_field()
pass site_id: ID | None = strawberry_django.filter_field()
location: Annotated['LocationFilter', strawberry.lazy('dcim.graphql.filters')] | None = (
strawberry_django.filter_field()
)
location_id: Annotated['TreeNodeFilter', strawberry.lazy('core.graphql.filter_lookups')] | None = (
strawberry_django.filter_field()
)
name: FilterLookup[str] | None = strawberry_django.filter_field()
@strawberry_django.filter(models.PowerPort, lookups=True) @strawberry_django.filter(models.PowerPort, lookups=True)
@autotype_decorator(filtersets.PowerPortFilterSet) class PowerPortFilter(ModularComponentModelFilterMixin, CabledObjectModelFilterMixin):
class PowerPortFilter(BaseFilterMixin): type: Annotated['PowerPortTypeEnum', strawberry.lazy('dcim.graphql.enums')] | None = (
pass strawberry_django.filter_field()
)
maximum_draw: Annotated['IntegerLookup', strawberry.lazy('core.graphql.filter_lookups')] | None = (
strawberry_django.filter_field()
)
allocated_draw: Annotated['IntegerLookup', strawberry.lazy('core.graphql.filter_lookups')] | None = (
strawberry_django.filter_field()
)
@strawberry_django.filter(models.PowerPortTemplate, lookups=True) @strawberry_django.filter(models.PowerPortTemplate, lookups=True)
@autotype_decorator(filtersets.PowerPortTemplateFilterSet) class PowerPortTemplateFilter(ModularComponentTemplateFilterMixin):
class PowerPortTemplateFilter(BaseFilterMixin): type: Annotated['PowerPortTypeEnum', strawberry.lazy('dcim.graphql.enums')] | None = (
pass strawberry_django.filter_field()
)
maximum_draw: Annotated['IntegerLookup', strawberry.lazy('core.graphql.filter_lookups')] | None = (
strawberry_django.filter_field()
)
allocated_draw: Annotated['IntegerLookup', strawberry.lazy('core.graphql.filter_lookups')] | None = (
strawberry_django.filter_field()
)
@strawberry_django.filter(models.RackType, lookups=True) @strawberry_django.filter(models.RackType, lookups=True)
@autotype_decorator(filtersets.RackTypeFilterSet) class RackTypeFilter(RackBaseFilterMixin):
class RackTypeFilter(BaseFilterMixin): form_factor: Annotated['RackFormFactorEnum', strawberry.lazy('dcim.graphql.enums')] | None = (
pass strawberry_django.filter_field()
)
manufacturer: Annotated['ManufacturerFilter', strawberry.lazy('dcim.graphql.filters')] | None = (
strawberry_django.filter_field()
)
manufacturer_id: ID | None = strawberry_django.filter_field()
model: FilterLookup[str] | None = strawberry_django.filter_field()
slug: FilterLookup[str] | None = strawberry_django.filter_field()
@strawberry_django.filter(models.Rack, lookups=True) @strawberry_django.filter(models.Rack, lookups=True)
@autotype_decorator(filtersets.RackFilterSet) class RackFilter(ContactFilterMixin, ImageAttachmentFilterMixin, RackBaseFilterMixin):
class RackFilter(BaseFilterMixin): form_factor: Annotated['RackFormFactorEnum', strawberry.lazy('dcim.graphql.enums')] | None = (
pass strawberry_django.filter_field()
)
rack_type: Annotated['RackTypeFilter', strawberry.lazy('dcim.graphql.filters')] | None = (
strawberry_django.filter_field()
)
rack_type_id: ID | None = strawberry_django.filter_field()
name: FilterLookup[str] | None = strawberry_django.filter_field()
facility_id: FilterLookup[str] | None = strawberry_django.filter_field()
site: Annotated['SiteFilter', strawberry.lazy('dcim.graphql.filters')] | None = strawberry_django.filter_field()
site_id: ID | None = strawberry_django.filter_field()
location: Annotated['LocationFilter', strawberry.lazy('dcim.graphql.filters')] | None = (
strawberry_django.filter_field()
)
location_id: Annotated['TreeNodeFilter', strawberry.lazy('core.graphql.filter_lookups')] | None = (
strawberry_django.filter_field()
)
tenant: Annotated['TenantFilter', strawberry.lazy('tenancy.graphql.filters')] | None = (
strawberry_django.filter_field()
)
tenant_id: ID | None = strawberry_django.filter_field()
status: Annotated['RackStatusEnum', strawberry.lazy('dcim.graphql.enums')] | None = strawberry_django.filter_field()
role: Annotated['RackRoleFilter', strawberry.lazy('dcim.graphql.filters')] | None = strawberry_django.filter_field()
role_id: ID | None = strawberry_django.filter_field()
serial: FilterLookup[str] | None = strawberry_django.filter_field()
asset_tag: FilterLookup[str] | None = strawberry_django.filter_field()
airflow: Annotated['RackAirflowEnum', strawberry.lazy('dcim.graphql.enums')] | None = (
strawberry_django.filter_field()
)
vlan_groups: Annotated['VLANGroupFilter', strawberry.lazy('ipam.graphql.filters')] | None = (
strawberry_django.filter_field()
)
@strawberry_django.filter(models.RackReservation, lookups=True) @strawberry_django.filter(models.RackReservation, lookups=True)
@autotype_decorator(filtersets.RackReservationFilterSet) class RackReservationFilter(PrimaryModelFilterMixin):
class RackReservationFilter(BaseFilterMixin): rack: Annotated['RackFilter', strawberry.lazy('dcim.graphql.filters')] | None = strawberry_django.filter_field()
pass rack_id: ID | None = strawberry_django.filter_field()
units: Annotated['IntegerArrayLookup', strawberry.lazy('core.graphql.filter_lookups')] | None = (
strawberry_django.filter_field()
)
tenant: Annotated['TenantFilter', strawberry.lazy('tenancy.graphql.filters')] | None = (
strawberry_django.filter_field()
)
tenant_id: ID | None = strawberry_django.filter_field()
user: Annotated['UserFilter', strawberry.lazy('users.graphql.filters')] | None = strawberry_django.filter_field()
user_id: ID | None = strawberry_django.filter_field()
description: FilterLookup[str] | None = strawberry_django.filter_field()
@strawberry_django.filter(models.RackRole, lookups=True) @strawberry_django.filter(models.RackRole, lookups=True)
@autotype_decorator(filtersets.RackRoleFilterSet) class RackRoleFilter(OrganizationalModelFilterMixin):
class RackRoleFilter(BaseFilterMixin): color: Annotated['ColorEnum', strawberry.lazy('netbox.graphql.enums')] | None = strawberry_django.filter_field()
pass
@strawberry_django.filter(models.RearPort, lookups=True) @strawberry_django.filter(models.RearPort, lookups=True)
@autotype_decorator(filtersets.RearPortFilterSet) class RearPortFilter(ModularComponentModelFilterMixin, CabledObjectModelFilterMixin):
class RearPortFilter(BaseFilterMixin): type: Annotated['PortTypeEnum', strawberry.lazy('dcim.graphql.enums')] | None = strawberry_django.filter_field()
pass color: Annotated['ColorEnum', strawberry.lazy('netbox.graphql.enums')] | None = strawberry_django.filter_field()
positions: Annotated['IntegerLookup', strawberry.lazy('core.graphql.filter_lookups')] | None = (
strawberry_django.filter_field()
)
@strawberry_django.filter(models.RearPortTemplate, lookups=True) @strawberry_django.filter(models.RearPortTemplate, lookups=True)
@autotype_decorator(filtersets.RearPortTemplateFilterSet) class RearPortTemplateFilter(ModularComponentTemplateFilterMixin):
class RearPortTemplateFilter(BaseFilterMixin): type: Annotated['PortTypeEnum', strawberry.lazy('dcim.graphql.enums')] | None = strawberry_django.filter_field()
pass color: Annotated['ColorEnum', strawberry.lazy('netbox.graphql.enums')] | None = strawberry_django.filter_field()
positions: Annotated['IntegerLookup', strawberry.lazy('core.graphql.filter_lookups')] | None = (
strawberry_django.filter_field()
)
@strawberry_django.filter(models.Region, lookups=True) @strawberry_django.filter(models.Region, lookups=True)
@autotype_decorator(filtersets.RegionFilterSet) class RegionFilter(ContactFilterMixin, NestedGroupModelFilterMixin):
class RegionFilter(BaseFilterMixin): prefixes: Annotated['PrefixFilter', strawberry.lazy('ipam.graphql.filters')] | None = (
pass strawberry_django.filter_field()
)
vlan_groups: Annotated['VLANGroupFilter', strawberry.lazy('ipam.graphql.filters')] | None = (
strawberry_django.filter_field()
)
@strawberry_django.filter(models.Site, lookups=True) @strawberry_django.filter(models.Site, lookups=True)
@autotype_decorator(filtersets.SiteFilterSet) class SiteFilter(ContactFilterMixin, ImageAttachmentFilterMixin, PrimaryModelFilterMixin):
class SiteFilter(BaseFilterMixin): name: FilterLookup[str] | None = strawberry_django.filter_field()
pass slug: FilterLookup[str] | None = strawberry_django.filter_field()
status: Annotated['SiteStatusEnum', strawberry.lazy('dcim.graphql.enums')] | None = strawberry_django.filter_field()
region: Annotated['RegionFilter', strawberry.lazy('dcim.graphql.filters')] | None = strawberry_django.filter_field()
region_id: Annotated['TreeNodeFilter', strawberry.lazy('core.graphql.filter_lookups')] | None = (
strawberry_django.filter_field()
)
group: Annotated['SiteGroupFilter', strawberry.lazy('dcim.graphql.filters')] | None = (
strawberry_django.filter_field()
)
group_id: Annotated['TreeNodeFilter', strawberry.lazy('core.graphql.filter_lookups')] | None = (
strawberry_django.filter_field()
)
tenant: Annotated['TenantFilter', strawberry.lazy('tenancy.graphql.filters')] | None = (
strawberry_django.filter_field()
)
tenant_id: ID | None = strawberry_django.filter_field()
facility: FilterLookup[str] | None = strawberry_django.filter_field()
asns: Annotated['ASNFilter', strawberry.lazy('ipam.graphql.filters')] | None = strawberry_django.filter_field()
time_zone: FilterLookup[str] | None = strawberry_django.filter_field()
physical_address: FilterLookup[str] | None = strawberry_django.filter_field()
shipping_address: FilterLookup[str] | None = strawberry_django.filter_field()
latitude: Annotated['FloatLookup', strawberry.lazy('core.graphql.filter_lookups')] | None = (
strawberry_django.filter_field()
)
longitude: Annotated['FloatLookup', strawberry.lazy('core.graphql.filter_lookups')] | None = (
strawberry_django.filter_field()
)
prefixes: Annotated['PrefixFilter', strawberry.lazy('ipam.graphql.filters')] | None = (
strawberry_django.filter_field()
)
vlan_groups: Annotated['VLANGroupFilter', strawberry.lazy('ipam.graphql.filters')] | None = (
strawberry_django.filter_field()
)
@strawberry_django.filter(models.SiteGroup, lookups=True) @strawberry_django.filter(models.SiteGroup, lookups=True)
@autotype_decorator(filtersets.SiteGroupFilterSet) class SiteGroupFilter(ContactFilterMixin, NestedGroupModelFilterMixin):
class SiteGroupFilter(BaseFilterMixin): prefixes: Annotated['PrefixFilter', strawberry.lazy('ipam.graphql.filters')] | None = (
pass strawberry_django.filter_field()
)
vlan_groups: Annotated['VLANGroupFilter', strawberry.lazy('ipam.graphql.filters')] | None = (
strawberry_django.filter_field()
)
@strawberry_django.filter(models.VirtualChassis, lookups=True) @strawberry_django.filter(models.VirtualChassis, lookups=True)
@autotype_decorator(filtersets.VirtualChassisFilterSet) class VirtualChassisFilter(PrimaryModelFilterMixin):
class VirtualChassisFilter(BaseFilterMixin): master: Annotated['DeviceFilter', strawberry.lazy('dcim.graphql.filters')] | None = strawberry_django.filter_field()
pass master_id: ID | None = strawberry_django.filter_field()
name: FilterLookup[str] | None = strawberry_django.filter_field()
domain: FilterLookup[str] | None = strawberry_django.filter_field()
@strawberry_django.filter(models.VirtualDeviceContext, lookups=True) @strawberry_django.filter(models.VirtualDeviceContext, lookups=True)
@autotype_decorator(filtersets.VirtualDeviceContextFilterSet) class VirtualDeviceContextFilter(PrimaryModelFilterMixin):
class VirtualDeviceContextFilter(BaseFilterMixin): device: Annotated['DeviceFilter', strawberry.lazy('dcim.graphql.filters')] | None = strawberry_django.filter_field()
pass device_id: ID | None = strawberry_django.filter_field()
name: FilterLookup[str] | None = strawberry_django.filter_field()
status: Annotated['VirtualDeviceContextStatusEnum', strawberry.lazy('dcim.graphql.enums')] | None = (
strawberry_django.filter_field()
)
identifier: Annotated['IntegerLookup', strawberry.lazy('core.graphql.filter_lookups')] | None = (
strawberry_django.filter_field()
)
primary_ip4: Annotated['IPAddressFilter', strawberry.lazy('ipam.graphql.filters')] | None = (
strawberry_django.filter_field()
)
primary_ip4_id: ID | None = strawberry_django.filter_field()
primary_ip6: Annotated['IPAddressFilter', strawberry.lazy('ipam.graphql.filters')] | None = (
strawberry_django.filter_field()
)
primary_ip6_id: ID | None = strawberry_django.filter_field()
tenant: Annotated['TenantFilter', strawberry.lazy('tenancy.graphql.filters')] | None = (
strawberry_django.filter_field()
)
tenant_id: ID | None = strawberry_django.filter_field()
comments: FilterLookup[str] | None = strawberry_django.filter_field()

View File

@ -0,0 +1,190 @@
from enum import Enum
import strawberry
__all__ = [
'CustomFieldTypeEnum',
'CustomFieldFilterLogicEnum',
'CustomFieldUIVisibleEnum',
'CustomFieldUIEditableEnum',
'CustomFieldChoiceSetBaseEnum',
'CustomLinkButtonClassEnum',
'BookmarkOrderingEnum',
'JournalEntryKindEnum',
'LogLevelEnum',
'DurationEnum',
'WebhookHttpMethodEnum',
'ChangeActionEnum',
'DashboardWidgetColorEnum',
'EventRuleActionEnum',
]
#
# CustomFields
#
@strawberry.enum
class CustomFieldTypeEnum(Enum):
TYPE_TEXT = 'text'
TYPE_LONGTEXT = 'longtext'
TYPE_INTEGER = 'integer'
TYPE_DECIMAL = 'decimal'
TYPE_BOOLEAN = 'boolean'
TYPE_DATE = 'date'
TYPE_DATETIME = 'datetime'
TYPE_URL = 'url'
TYPE_JSON = 'json'
TYPE_SELECT = 'select'
TYPE_MULTISELECT = 'multiselect'
TYPE_OBJECT = 'object'
TYPE_MULTIOBJECT = 'multiobject'
@strawberry.enum
class CustomFieldFilterLogicEnum(Enum):
FILTER_DISABLED = 'disabled'
FILTER_LOOSE = 'loose'
FILTER_EXACT = 'exact'
@strawberry.enum
class CustomFieldUIVisibleEnum(Enum):
ALWAYS = 'always'
IF_SET = 'if-set'
HIDDEN = 'hidden'
@strawberry.enum
class CustomFieldUIEditableEnum(Enum):
YES = 'yes'
NO = 'no'
HIDDEN = 'hidden'
@strawberry.enum
class CustomFieldChoiceSetBaseEnum(Enum):
IATA = 'IATA'
ISO_3166 = 'ISO_3166'
UN_LOCODE = 'UN_LOCODE'
#
# CustomLinks
#
@strawberry.enum
class CustomLinkButtonClassEnum(Enum):
LINK = 'ghost-dark'
#
# Bookmarks
#
@strawberry.enum
class BookmarkOrderingEnum(Enum):
ORDERING_NEWEST = '-created'
ORDERING_OLDEST = 'created'
ORDERING_ALPHABETICAL_AZ = 'name'
ORDERING_ALPHABETICAL_ZA = '-name'
#
# Journal entries
#
@strawberry.enum
class JournalEntryKindEnum(Enum):
key = 'JournalEntry.kind'
KIND_INFO = 'info'
KIND_SUCCESS = 'success'
KIND_WARNING = 'warning'
KIND_DANGER = 'danger'
#
# Reports and Scripts
#
@strawberry.enum
class LogLevelEnum(Enum):
LOG_DEBUG = 'debug'
LOG_DEFAULT = 'default'
LOG_INFO = 'info'
LOG_SUCCESS = 'success'
LOG_WARNING = 'warning'
LOG_FAILURE = 'failure'
@strawberry.enum
class DurationEnum(Enum):
HOURLY = 60
TWELVE_HOURS = 720
DAILY = 1440
WEEKLY = 10080
THIRTY_DAYS = 43200
#
# Webhooks
#
@strawberry.enum
class WebhookHttpMethodEnum(Enum):
METHOD_GET = 'GET'
METHOD_POST = 'POST'
METHOD_PUT = 'PUT'
METHOD_PATCH = 'PATCH'
METHOD_DELETE = 'DELETE'
#
# Staging
#
@strawberry.enum
class ChangeActionEnum(Enum):
ACTION_CREATE = 'create'
ACTION_UPDATE = 'update'
ACTION_DELETE = 'delete'
#
# Dashboard widgets
#
@strawberry.enum
class DashboardWidgetColorEnum(Enum):
BLUE = 'blue'
INDIGO = 'indigo'
PURPLE = 'purple'
PINK = 'pink'
RED = 'red'
ORANGE = 'orange'
YELLOW = 'yellow'
GREEN = 'green'
TEAL = 'teal'
CYAN = 'cyan'
GRAY = 'gray'
BLACK = 'black'
WHITE = 'white'
#
# Event Rules
#
@strawberry.enum
class EventRuleActionEnum(Enum):
WEBHOOK = 'webhook'
SCRIPT = 'script'
NOTIFICATION = 'notification'

View File

@ -0,0 +1,53 @@
from dataclasses import dataclass
from typing import Annotated, TYPE_CHECKING
import strawberry
import strawberry_django
from strawberry_django import FilterLookup
from core.graphql.filter_mixins import BaseFilterMixin
if TYPE_CHECKING:
from core.graphql.filter_lookups import *
from .filters import *
__all__ = [
'CustomFieldsFilterMixin',
'JournalEntriesFilterMixin',
'TagsFilterMixin',
'ConfigContextFilterMixin',
'TagBaseFilterMixin',
]
@dataclass
class CustomFieldsFilterMixin(BaseFilterMixin):
custom_field_data: Annotated['JSONFilter', strawberry.lazy('core.graphql.filter_lookups')] | None = (
strawberry_django.filter_field()
)
@dataclass
class JournalEntriesFilterMixin(BaseFilterMixin):
journal_entries: Annotated['JournalEntryFilter', strawberry.lazy('extras.graphql.filters')] | None = (
strawberry_django.filter_field()
)
@dataclass
class TagsFilterMixin(BaseFilterMixin):
tags: Annotated['TagFilter', strawberry.lazy('extras.graphql.filters')] | None = strawberry_django.filter_field()
@dataclass
class ConfigContextFilterMixin(BaseFilterMixin):
local_config_context: Annotated['ConfigContextFilter', strawberry.lazy('extras.graphql.filters')] | None = (
strawberry_django.filter_field()
)
config_context: Annotated['ConfigContextFilter', strawberry.lazy('extras.graphql.filters')] | None = (
strawberry_django.filter_field()
)
@dataclass
class TagBaseFilterMixin(BaseFilterMixin):
name: FilterLookup[str] | None = strawberry_django.filter_field()
slug: FilterLookup[str] | None = strawberry_django.filter_field()

View File

@ -1,7 +1,33 @@
from typing import Annotated, TYPE_CHECKING
import strawberry
from strawberry.scalars import ID
import strawberry_django import strawberry_django
from strawberry_django import (
FilterLookup,
)
from netbox.graphql.filter_mixins import (
BaseObjectTypeFilterMixin,
ChangeLogFilterMixin,
SyncedDataFilterMixin,
)
from extras import models
from extras.graphql.filter_mixins import TagBaseFilterMixin, CustomFieldsFilterMixin, TagsFilterMixin
if TYPE_CHECKING:
from .enums import *
from netbox.graphql.enums import *
from wireless.graphql.enums import *
from core.graphql.filter_lookups import *
from extras.graphql.filters import *
from circuits.graphql.filters import *
from dcim.graphql.filters import *
from ipam.graphql.filters import *
from tenancy.graphql.filters import *
from wireless.graphql.filters import *
from users.graphql.filters import *
from virtualization.graphql.filters import *
from vpn.graphql.filters import *
from extras import filtersets, models
from netbox.graphql.filter_mixins import autotype_decorator, BaseFilterMixin
__all__ = ( __all__ = (
'ConfigContextFilter', 'ConfigContextFilter',
@ -21,78 +47,253 @@ __all__ = (
@strawberry_django.filter(models.ConfigContext, lookups=True) @strawberry_django.filter(models.ConfigContext, lookups=True)
@autotype_decorator(filtersets.ConfigContextFilterSet) class ConfigContextFilter(BaseObjectTypeFilterMixin, SyncedDataFilterMixin, ChangeLogFilterMixin):
class ConfigContextFilter(BaseFilterMixin): name: FilterLookup[str] = strawberry_django.filter_field()
pass weight: Annotated['IntegerLookup', strawberry.lazy('core.graphql.filter_lookups')] | None = (
strawberry_django.filter_field()
)
description: FilterLookup[str] = strawberry_django.filter_field()
is_active: FilterLookup[bool] = strawberry_django.filter_field()
regions: Annotated['RegionFilter', strawberry.lazy('dcim.graphql.filters')] | None = (
strawberry_django.filter_field()
)
region_id: Annotated['TreeNodeFilter', strawberry.lazy('core.graphql.filter_lookups')] | None = (
strawberry_django.filter_field()
)
site_groups: Annotated['SiteGroupFilter', strawberry.lazy('dcim.graphql.filters')] | None = (
strawberry_django.filter_field()
)
site_group_id: Annotated['TreeNodeFilter', strawberry.lazy('core.graphql.filter_lookups')] | None = (
strawberry_django.filter_field()
)
sites: Annotated['SiteFilter', strawberry.lazy('dcim.graphql.filters')] | None = strawberry_django.filter_field()
locations: Annotated['LocationFilter', strawberry.lazy('dcim.graphql.filters')] | None = (
strawberry_django.filter_field()
)
device_types: Annotated['DeviceTypeFilter', strawberry.lazy('dcim.graphql.filters')] | None = (
strawberry_django.filter_field()
)
roles: Annotated['DeviceRoleFilter', strawberry.lazy('dcim.graphql.filters')] | None = (
strawberry_django.filter_field()
)
platforms: Annotated['PlatformFilter', strawberry.lazy('dcim.graphql.filters')] | None = (
strawberry_django.filter_field()
)
cluster_types: Annotated['ClusterTypeFilter', strawberry.lazy('virtualization.graphql.filters')] | None = (
strawberry_django.filter_field()
)
cluster_groups: Annotated['ClusterGroupFilter', strawberry.lazy('virtualization.graphql.filters')] | None = (
strawberry_django.filter_field()
)
clusters: Annotated['ClusterFilter', strawberry.lazy('virtualization.graphql.filters')] | None = (
strawberry_django.filter_field()
)
tenant_groups: Annotated['TenantGroupFilter', strawberry.lazy('tenancy.graphql.filters')] | None = (
strawberry_django.filter_field()
)
tenant_group_id: Annotated['TreeNodeFilter', strawberry.lazy('core.graphql.filter_lookups')] | None = (
strawberry_django.filter_field()
)
tenants: Annotated['TenantFilter', strawberry.lazy('tenancy.graphql.filters')] | None = (
strawberry_django.filter_field()
)
tags: Annotated['TagFilter', strawberry.lazy('extras.graphql.filters')] | None = strawberry_django.filter_field()
data: Annotated['JSONFilter', strawberry.lazy('core.graphql.filter_lookups')] | None = (
strawberry_django.filter_field()
)
@strawberry_django.filter(models.ConfigTemplate, lookups=True) @strawberry_django.filter(models.ConfigTemplate, lookups=True)
@autotype_decorator(filtersets.ConfigTemplateFilterSet) class ConfigTemplateFilter(BaseObjectTypeFilterMixin, SyncedDataFilterMixin, ChangeLogFilterMixin):
class ConfigTemplateFilter(BaseFilterMixin): name: FilterLookup[str] | None = strawberry_django.filter_field()
pass description: FilterLookup[str] | None = strawberry_django.filter_field()
template_code: FilterLookup[str] | None = strawberry_django.filter_field()
environment_params: Annotated['JSONFilter', strawberry.lazy('core.graphql.filter_lookups')] | None = (
strawberry_django.filter_field()
)
@strawberry_django.filter(models.CustomField, lookups=True) @strawberry_django.filter(models.CustomField, lookups=True)
@autotype_decorator(filtersets.CustomFieldFilterSet) class CustomFieldFilter(BaseObjectTypeFilterMixin, ChangeLogFilterMixin):
class CustomFieldFilter(BaseFilterMixin): type: Annotated['CustomFieldTypeEnum', strawberry.lazy('extras.graphql.enums')] | None = (
pass strawberry_django.filter_field()
)
related_object_type_id: ID | None = strawberry_django.filter_field()
name: FilterLookup[str] | None = strawberry_django.filter_field()
label: FilterLookup[str] | None = strawberry_django.filter_field()
group_name: FilterLookup[str] | None = strawberry_django.filter_field()
description: FilterLookup[str] | None = strawberry_django.filter_field()
required: FilterLookup[bool] | None = strawberry_django.filter_field()
unique: FilterLookup[bool] | None = strawberry_django.filter_field()
search_weight: Annotated['IntegerLookup', strawberry.lazy('core.graphql.filter_lookups')] | None = (
strawberry_django.filter_field()
)
filter_logic: Annotated['CustomFieldFilterLogicEnum', strawberry.lazy('extras.graphql.enums')] | None = (
strawberry_django.filter_field()
)
default: Annotated['JSONFilter', strawberry.lazy('core.graphql.filter_lookups')] | None = (
strawberry_django.filter_field()
)
related_object_filter: Annotated['JSONFilter', strawberry.lazy('core.graphql.filter_lookups')] | None = (
strawberry_django.filter_field()
)
weight: Annotated['IntegerLookup', strawberry.lazy('core.graphql.filter_lookups')] | None = (
strawberry_django.filter_field()
)
validation_minimum: Annotated['IntegerLookup', strawberry.lazy('core.graphql.filter_lookups')] | None = (
strawberry_django.filter_field()
)
validation_maximum: Annotated['IntegerLookup', strawberry.lazy('core.graphql.filter_lookups')] | None = (
strawberry_django.filter_field()
)
validation_regex: FilterLookup[str] | None = strawberry_django.filter_field()
choice_set: Annotated['CustomFieldChoiceSetFilter', strawberry.lazy('extras.graphql.filters')] | None = (
strawberry_django.filter_field()
)
choice_set_id: ID | None = strawberry_django.filter_field()
ui_visible: Annotated['CustomFieldUIVisibleEnum', strawberry.lazy('extras.graphql.enums')] | None = (
strawberry_django.filter_field()
)
ui_editable: Annotated['CustomFieldUIEditableEnum', strawberry.lazy('extras.graphql.enums')] | None = (
strawberry_django.filter_field()
)
is_cloneable: FilterLookup[bool] | None = strawberry_django.filter_field()
comments: FilterLookup[str] | None = strawberry_django.filter_field()
@strawberry_django.filter(models.CustomFieldChoiceSet, lookups=True) @strawberry_django.filter(models.CustomFieldChoiceSet, lookups=True)
@autotype_decorator(filtersets.CustomFieldChoiceSetFilterSet) class CustomFieldChoiceSetFilter(BaseObjectTypeFilterMixin, ChangeLogFilterMixin):
class CustomFieldChoiceSetFilter(BaseFilterMixin): name: FilterLookup[str] | None = strawberry_django.filter_field()
pass description: FilterLookup[str] | None = strawberry_django.filter_field()
base_choices: Annotated['CustomFieldChoiceSetBaseEnum', strawberry.lazy('extras.graphql.enums')] | None = (
strawberry_django.filter_field()
)
extra_choices: Annotated['StringArrayLookup', strawberry.lazy('core.graphql.filter_lookups')] | None = (
strawberry_django.filter_field()
)
order_alphabetically: FilterLookup[bool] | None = strawberry_django.filter_field()
@strawberry_django.filter(models.CustomLink, lookups=True) @strawberry_django.filter(models.CustomLink, lookups=True)
@autotype_decorator(filtersets.CustomLinkFilterSet) class CustomLinkFilter(BaseObjectTypeFilterMixin, ChangeLogFilterMixin):
class CustomLinkFilter(BaseFilterMixin): name: FilterLookup[str] | None = strawberry_django.filter_field()
pass enabled: FilterLookup[bool] | None = strawberry_django.filter_field()
link_text: FilterLookup[str] | None = strawberry_django.filter_field()
link_url: FilterLookup[str] | None = strawberry_django.filter_field()
weight: Annotated['IntegerLookup', strawberry.lazy('core.graphql.filter_lookups')] | None = (
strawberry_django.filter_field()
)
group_name: FilterLookup[str] | None = strawberry_django.filter_field()
button_class: FilterLookup[str] | None = strawberry_django.filter_field()
new_window: FilterLookup[bool] | None = strawberry_django.filter_field()
@strawberry_django.filter(models.ExportTemplate, lookups=True) @strawberry_django.filter(models.ExportTemplate, lookups=True)
@autotype_decorator(filtersets.ExportTemplateFilterSet) class ExportTemplateFilter(BaseObjectTypeFilterMixin, SyncedDataFilterMixin, ChangeLogFilterMixin):
class ExportTemplateFilter(BaseFilterMixin): name: FilterLookup[str] | None = strawberry_django.filter_field()
pass description: FilterLookup[str] | None = strawberry_django.filter_field()
template_code: FilterLookup[str] | None = strawberry_django.filter_field()
mime_type: FilterLookup[str] | None = strawberry_django.filter_field()
file_extension: FilterLookup[str] | None = strawberry_django.filter_field()
as_attachment: FilterLookup[bool] | None = strawberry_django.filter_field()
@strawberry_django.filter(models.ImageAttachment, lookups=True) @strawberry_django.filter(models.ImageAttachment, lookups=True)
@autotype_decorator(filtersets.ImageAttachmentFilterSet) class ImageAttachmentFilter(BaseObjectTypeFilterMixin, ChangeLogFilterMixin):
class ImageAttachmentFilter(BaseFilterMixin): object_id: ID | None = strawberry_django.filter_field()
pass image_height: Annotated['IntegerLookup', strawberry.lazy('core.graphql.filter_lookups')] | None = (
strawberry_django.filter_field()
)
image_width: Annotated['IntegerLookup', strawberry.lazy('core.graphql.filter_lookups')] | None = (
strawberry_django.filter_field()
)
name: FilterLookup[str] | None = strawberry_django.filter_field()
@strawberry_django.filter(models.JournalEntry, lookups=True) @strawberry_django.filter(models.JournalEntry, lookups=True)
@autotype_decorator(filtersets.JournalEntryFilterSet) class JournalEntryFilter(BaseObjectTypeFilterMixin, CustomFieldsFilterMixin, TagsFilterMixin, ChangeLogFilterMixin):
class JournalEntryFilter(BaseFilterMixin): assigned_object_type: Annotated['ContentTypeFilter', strawberry.lazy('core.graphql.filters')] | None = (
pass strawberry_django.filter_field()
)
assigned_object_type_id: ID | None = strawberry_django.filter_field()
assigned_object_id: ID | None = strawberry_django.filter_field()
created_by: Annotated['UserFilter', strawberry.lazy('users.graphql.filters')] | None = (
strawberry_django.filter_field()
)
kind: Annotated['JournalEntryKindEnum', strawberry.lazy('extras.graphql.enums')] | None = (
strawberry_django.filter_field()
)
comments: FilterLookup[str] | None = strawberry_django.filter_field()
@strawberry_django.filter(models.NotificationGroup, lookups=True) @strawberry_django.filter(models.NotificationGroup, lookups=True)
@autotype_decorator(filtersets.NotificationGroupFilterSet) class NotificationGroupFilter(BaseObjectTypeFilterMixin, ChangeLogFilterMixin):
class NotificationGroupFilter(BaseFilterMixin): name: FilterLookup[str] | None = strawberry_django.filter_field()
pass description: FilterLookup[str] | None = strawberry_django.filter_field()
groups: Annotated['GroupFilter', strawberry.lazy('users.graphql.filters')] | None = strawberry_django.filter_field()
users: Annotated['UserFilter', strawberry.lazy('users.graphql.filters')] | None = strawberry_django.filter_field()
@strawberry_django.filter(models.SavedFilter, lookups=True) @strawberry_django.filter(models.SavedFilter, lookups=True)
@autotype_decorator(filtersets.SavedFilterFilterSet) class SavedFilterFilter(BaseObjectTypeFilterMixin, ChangeLogFilterMixin):
class SavedFilterFilter(BaseFilterMixin): name: FilterLookup[str] | None = strawberry_django.filter_field()
pass slug: FilterLookup[str] | None = strawberry_django.filter_field()
description: FilterLookup[str] | None = strawberry_django.filter_field()
user: Annotated['UserFilter', strawberry.lazy('users.graphql.filters')] | None = strawberry_django.filter_field()
user_id: ID | None = strawberry_django.filter_field()
weight: Annotated['IntegerLookup', strawberry.lazy('core.graphql.filter_lookups')] | None = (
strawberry_django.filter_field()
)
enabled: FilterLookup[bool] | None = strawberry_django.filter_field()
shared: FilterLookup[bool] | None = strawberry_django.filter_field()
parameters: Annotated['JSONFilter', strawberry.lazy('core.graphql.filter_lookups')] | None = (
strawberry_django.filter_field()
)
@strawberry_django.filter(models.Tag, lookups=True) @strawberry_django.filter(models.Tag, lookups=True)
@autotype_decorator(filtersets.TagFilterSet) class TagFilter(BaseObjectTypeFilterMixin, ChangeLogFilterMixin, TagBaseFilterMixin):
class TagFilter(BaseFilterMixin): color: Annotated['ColorEnum', strawberry.lazy('netbox.graphql.enums')] | None = strawberry_django.filter_field()
pass description: FilterLookup[str] | None = strawberry_django.filter_field()
@strawberry_django.filter(models.Webhook, lookups=True) @strawberry_django.filter(models.Webhook, lookups=True)
@autotype_decorator(filtersets.WebhookFilterSet) class WebhookFilter(BaseObjectTypeFilterMixin, CustomFieldsFilterMixin, TagsFilterMixin, ChangeLogFilterMixin):
class WebhookFilter(BaseFilterMixin): name: FilterLookup[str] | None = strawberry_django.filter_field()
pass description: FilterLookup[str] | None = strawberry_django.filter_field()
payload_url: FilterLookup[str] | None = strawberry_django.filter_field()
http_method: Annotated['WebhookHttpMethodEnum', strawberry.lazy('extras.graphql.enums')] | None = (
strawberry_django.filter_field()
)
http_content_type: FilterLookup[str] | None = strawberry_django.filter_field()
additional_headers: FilterLookup[str] | None = strawberry_django.filter_field()
body_template: FilterLookup[str] | None = strawberry_django.filter_field()
secret: FilterLookup[str] | None = strawberry_django.filter_field()
ssl_verification: FilterLookup[bool] | None = strawberry_django.filter_field()
ca_file_path: FilterLookup[str] | None = strawberry_django.filter_field()
events: Annotated['EventRuleFilter', strawberry.lazy('extras.graphql.filters')] | None = (
strawberry_django.filter_field()
)
@strawberry_django.filter(models.EventRule, lookups=True) @strawberry_django.filter(models.EventRule, lookups=True)
@autotype_decorator(filtersets.EventRuleFilterSet) class EventRuleFilter(BaseObjectTypeFilterMixin, CustomFieldsFilterMixin, TagsFilterMixin, ChangeLogFilterMixin):
class EventRuleFilter(BaseFilterMixin): name: FilterLookup[str] | None = strawberry_django.filter_field()
pass description: FilterLookup[str] | None = strawberry_django.filter_field()
event_types: Annotated['StringArrayLookup', strawberry.lazy('core.graphql.filter_lookups')] | None = (
strawberry_django.filter_field()
)
enabled: FilterLookup[bool] | None = strawberry_django.filter_field()
conditions: Annotated['JSONFilter', strawberry.lazy('core.graphql.filter_lookups')] | None = (
strawberry_django.filter_field()
)
action_type: Annotated['EventRuleActionEnum', strawberry.lazy('extras.graphql.enums')] | None = (
strawberry_django.filter_field()
)
action_object_type: FilterLookup[str] | None = strawberry_django.filter_field()
action_object_type_id: ID | None = strawberry_django.filter_field()
action_object_id: ID | None = strawberry_django.filter_field()
action_data: Annotated['JSONFilter', strawberry.lazy('core.graphql.filter_lookups')] | None = (
strawberry_django.filter_field()
)
comments: FilterLookup[str] | None = strawberry_django.filter_field()

View File

@ -0,0 +1,132 @@
from enum import Enum
import strawberry
__all__ = [
'IPAddressFamilyEnum',
'PrefixStatusEnum',
'IPRangeStatusEnum',
'IPAddressStatusEnum',
'IPAddressRoleEnum',
'FHRPGroupProtocolEnum',
'FHRPGroupAuthTypeEnum',
'VLANStatusEnum',
'VLANQinQRoleEnum',
'ServiceProtocolEnum',
]
@strawberry.enum
class IPAddressFamilyEnum(Enum):
FAMILY_4 = 4
FAMILY_6 = 6
#
# Prefixes
#
@strawberry.enum
class PrefixStatusEnum(Enum):
key = 'Prefix.status'
STATUS_CONTAINER = 'container'
STATUS_ACTIVE = 'active'
STATUS_RESERVED = 'reserved'
STATUS_DEPRECATED = 'deprecated'
#
# IP Ranges
#
@strawberry.enum
class IPRangeStatusEnum(Enum):
key = 'IPRange.status'
STATUS_ACTIVE = 'active'
STATUS_RESERVED = 'reserved'
STATUS_DEPRECATED = 'deprecated'
#
# IP Addresses
#
@strawberry.enum
class IPAddressStatusEnum(Enum):
key = 'IPAddress.status'
STATUS_ACTIVE = 'active'
STATUS_RESERVED = 'reserved'
STATUS_DEPRECATED = 'deprecated'
STATUS_DHCP = 'dhcp'
STATUS_SLAAC = 'slaac'
@strawberry.enum
class IPAddressRoleEnum(Enum):
ROLE_LOOPBACK = 'loopback'
ROLE_SECONDARY = 'secondary'
ROLE_ANYCAST = 'anycast'
ROLE_VIP = 'vip'
ROLE_VRRP = 'vrrp'
ROLE_HSRP = 'hsrp'
ROLE_GLBP = 'glbp'
ROLE_CARP = 'carp'
#
# FHRP
#
@strawberry.enum
class FHRPGroupProtocolEnum(Enum):
PROTOCOL_VRRP2 = 'vrrp2'
PROTOCOL_VRRP3 = 'vrrp3'
PROTOCOL_HSRP = 'hsrp'
PROTOCOL_GLBP = 'glbp'
PROTOCOL_CARP = 'carp'
PROTOCOL_CLUSTERXL = 'clusterxl'
PROTOCOL_OTHER = 'other'
@strawberry.enum
class FHRPGroupAuthTypeEnum(Enum):
AUTHENTICATION_PLAINTEXT = 'plaintext'
AUTHENTICATION_MD5 = 'md5'
#
# VLANs
#
@strawberry.enum
class VLANStatusEnum(Enum):
key = 'VLAN.status'
STATUS_ACTIVE = 'active'
STATUS_RESERVED = 'reserved'
STATUS_DEPRECATED = 'deprecated'
@strawberry.enum
class VLANQinQRoleEnum(Enum):
ROLE_SERVICE = 'svlan'
ROLE_CUSTOMER = 'cvlan'
#
# Services
#
@strawberry.enum
class ServiceProtocolEnum(Enum):
PROTOCOL_TCP = 'tcp'
PROTOCOL_UDP = 'udp'
PROTOCOL_SCTP = 'sctp'

View File

@ -0,0 +1,22 @@
from dataclasses import dataclass
from typing import Annotated, TYPE_CHECKING
import strawberry
import strawberry_django
from core.graphql.filter_mixins import *
if TYPE_CHECKING:
from .enums import *
from core.graphql.filter_lookups import *
__all__ = ['ServiceBaseFilterMixin']
@dataclass
class ServiceBaseFilterMixin(BaseFilterMixin):
protocol: Annotated['ServiceProtocolEnum', strawberry.lazy('ipam.graphql.enums')] | None = (
strawberry_django.filter_field()
)
ports: Annotated['IntegerLookup', strawberry.lazy('core.graphql.filter_lookups')] | None = (
strawberry_django.filter_field()
)

View File

@ -1,7 +1,37 @@
from datetime import date
from typing import Annotated, TYPE_CHECKING
import netaddr
from netaddr.core import AddrFormatError
from django.db.models import Q
import strawberry
from strawberry.scalars import ID
import strawberry_django import strawberry_django
from strawberry_django import (
FilterLookup,
DateFilterLookup,
)
from core.graphql.filter_mixins import *
from netbox.graphql.filter_mixins import *
from tenancy.graphql.filter_mixins import *
from ipam import filtersets, models from ipam import models
from netbox.graphql.filter_mixins import autotype_decorator, BaseFilterMixin from ipam.graphql.filter_mixins import *
if TYPE_CHECKING:
from .enums import *
from netbox.graphql.enums import *
from wireless.graphql.enums import *
from core.graphql.filter_lookups import *
from core.graphql.filters import *
from extras.graphql.filters import *
from circuits.graphql.filters import *
from dcim.graphql.filters import *
from ipam.graphql.filters import *
from tenancy.graphql.filters import *
from wireless.graphql.filters import *
from users.graphql.filters import *
from virtualization.graphql.filters import *
from vpn.graphql.filters import *
__all__ = ( __all__ = (
'ASNFilter', 'ASNFilter',
@ -26,108 +56,303 @@ __all__ = (
@strawberry_django.filter(models.ASN, lookups=True) @strawberry_django.filter(models.ASN, lookups=True)
@autotype_decorator(filtersets.ASNFilterSet) class ASNFilter(PrimaryModelFilterMixin):
class ASNFilter(BaseFilterMixin): rir: Annotated['RIRFilter', strawberry.lazy('ipam.graphql.filters')] | None = strawberry_django.filter_field()
pass rir_id: ID | None = strawberry_django.filter_field()
asn: Annotated['IntegerLookup', strawberry.lazy('core.graphql.filter_lookups')] | None = (
strawberry_django.filter_field()
)
tenant: Annotated['TenantFilter', strawberry.lazy('tenancy.graphql.filters')] | None = (
strawberry_django.filter_field()
)
tenant_id: ID | None = strawberry_django.filter_field()
@strawberry_django.filter(models.ASNRange, lookups=True) @strawberry_django.filter(models.ASNRange, lookups=True)
@autotype_decorator(filtersets.ASNRangeFilterSet) class ASNRangeFilter(OrganizationalModelFilterMixin):
class ASNRangeFilter(BaseFilterMixin): name: FilterLookup[str] | None = strawberry_django.filter_field()
pass slug: FilterLookup[str] | None = strawberry_django.filter_field()
rir: Annotated['RIRFilter', strawberry.lazy('ipam.graphql.filters')] | None = strawberry_django.filter_field()
rir_id: ID | None = strawberry_django.filter_field()
start: Annotated['IntegerLookup', strawberry.lazy('core.graphql.filter_lookups')] | None = (
strawberry_django.filter_field()
)
end: Annotated['IntegerLookup', strawberry.lazy('core.graphql.filter_lookups')] | None = (
strawberry_django.filter_field()
)
tenant: Annotated['TenantFilter', strawberry.lazy('tenancy.graphql.filters')] | None = (
strawberry_django.filter_field()
)
tenant_id: ID | None = strawberry_django.filter_field()
@strawberry_django.filter(models.Aggregate, lookups=True) @strawberry_django.filter(models.Aggregate, lookups=True)
@autotype_decorator(filtersets.AggregateFilterSet) class AggregateFilter(ContactFilterMixin, PrimaryModelFilterMixin):
class AggregateFilter(BaseFilterMixin): prefix: Annotated['PrefixFilter', strawberry.lazy('ipam.graphql.filters')] | None = strawberry_django.filter_field()
pass prefix_id: ID | None = strawberry_django.filter_field()
rir: Annotated['RIRFilter', strawberry.lazy('ipam.graphql.filters')] | None = strawberry_django.filter_field()
rir_id: ID | None = strawberry_django.filter_field()
tenant: Annotated['TenantFilter', strawberry.lazy('tenancy.graphql.filters')] | None = (
strawberry_django.filter_field()
)
tenant_id: ID | None = strawberry_django.filter_field()
date_added: DateFilterLookup[date] | None = strawberry_django.filter_field()
@strawberry_django.filter(models.FHRPGroup, lookups=True) @strawberry_django.filter(models.FHRPGroup, lookups=True)
@autotype_decorator(filtersets.FHRPGroupFilterSet) class FHRPGroupFilter(PrimaryModelFilterMixin):
class FHRPGroupFilter(BaseFilterMixin): group_id: Annotated['IntegerLookup', strawberry.lazy('core.graphql.filter_lookups')] | None = (
pass strawberry_django.filter_field()
)
name: FilterLookup[str] | None = strawberry_django.filter_field()
protocol: Annotated['FHRPGroupProtocolEnum', strawberry.lazy('ipam.graphql.enums')] | None = (
strawberry_django.filter_field()
)
auth_type: Annotated['FHRPGroupAuthTypeEnum', strawberry.lazy('ipam.graphql.enums')] | None = (
strawberry_django.filter_field()
)
auth_key: FilterLookup[str] | None = strawberry_django.filter_field()
ip_addresses: Annotated['IPAddressFilter', strawberry.lazy('ipam.graphql.filters')] | None = (
strawberry_django.filter_field()
)
@strawberry_django.filter(models.FHRPGroupAssignment, lookups=True) @strawberry_django.filter(models.FHRPGroupAssignment, lookups=True)
@autotype_decorator(filtersets.FHRPGroupAssignmentFilterSet) class FHRPGroupAssignmentFilter(BaseObjectTypeFilterMixin, ChangeLogFilterMixin):
class FHRPGroupAssignmentFilter(BaseFilterMixin): inteface_type: Annotated['ContentTypeFilter', strawberry.lazy('core.graphql.filters')] | None = (
pass strawberry_django.filter_field()
)
interface_id: FilterLookup[str] | None = strawberry_django.filter_field()
group: Annotated['FHRPGroupFilter', strawberry.lazy('ipam.graphql.filters')] | None = (
strawberry_django.filter_field()
)
group_id: ID | None = strawberry_django.filter_field()
priority: Annotated['IntegerLookup', strawberry.lazy('core.graphql.filter_lookups')] | None = (
strawberry_django.filter_field()
)
@strawberry_django.filter(models.IPAddress, lookups=True) @strawberry_django.filter(models.IPAddress, lookups=True)
@autotype_decorator(filtersets.IPAddressFilterSet) class IPAddressFilter(ContactFilterMixin, PrimaryModelFilterMixin):
class IPAddressFilter(BaseFilterMixin): address: FilterLookup[str] | None = strawberry_django.filter_field()
pass vrf: Annotated['VRFFilter', strawberry.lazy('ipam.graphql.filters')] | None = strawberry_django.filter_field()
vrf_id: ID | None = strawberry_django.filter_field()
tenant: Annotated['TenantFilter', strawberry.lazy('tenancy.graphql.filters')] | None = (
strawberry_django.filter_field()
)
tenant_id: ID | None = strawberry_django.filter_field()
status: Annotated['IPAddressStatusEnum', strawberry.lazy('ipam.graphql.enums')] | None = (
strawberry_django.filter_field()
)
role: Annotated['IPAddressRoleEnum', strawberry.lazy('ipam.graphql.enums')] | None = (
strawberry_django.filter_field()
)
assigned_object_type: Annotated['ContentTypeFilter', strawberry.lazy('core.graphql.filters')] | None = (
strawberry_django.filter_field()
)
assigned_object_id: ID | None = strawberry_django.filter_field()
nat_inside: Annotated['IPAddressFilter', strawberry.lazy('ipam.graphql.filters')] | None = (
strawberry_django.filter_field()
)
nat_inside_id: ID | None = strawberry_django.filter_field()
nat_outside: Annotated['IPAddressFilter', strawberry.lazy('ipam.graphql.filters')] | None = (
strawberry_django.filter_field()
)
nat_outside_id: ID | None = strawberry_django.filter_field()
dns_name: FilterLookup[str] | None = strawberry_django.filter_field()
@strawberry_django.filter_field()
def parent(self, value: list[str], prefix) -> Q:
if not value:
return Q()
q = Q()
for subnet in value:
try:
query = str(netaddr.IPNetwork(subnet.strip()).cidr)
q |= Q(address__net_host_contained=query)
except (AddrFormatError, ValueError):
return Q()
return q
@strawberry_django.filter(models.IPRange, lookups=True) @strawberry_django.filter(models.IPRange, lookups=True)
@autotype_decorator(filtersets.IPRangeFilterSet) class IPRangeFilter(ContactFilterMixin, PrimaryModelFilterMixin):
class IPRangeFilter(BaseFilterMixin): start_address: FilterLookup[str] | None = strawberry_django.filter_field()
pass end_address: FilterLookup[str] | None = strawberry_django.filter_field()
size: Annotated['IntegerLookup', strawberry.lazy('core.graphql.filter_lookups')] | None = (
strawberry_django.filter_field()
)
vrf: Annotated['VRFFilter', strawberry.lazy('ipam.graphql.filters')] | None = strawberry_django.filter_field()
vrf_id: ID | None = strawberry_django.filter_field()
tenant: Annotated['TenantFilter', strawberry.lazy('tenancy.graphql.filters')] | None = (
strawberry_django.filter_field()
)
tenant_id: ID | None = strawberry_django.filter_field()
status: Annotated['IPRangeStatusEnum', strawberry.lazy('ipam.graphql.enums')] | None = (
strawberry_django.filter_field()
)
role: Annotated['IPAddressRoleEnum', strawberry.lazy('ipam.graphql.enums')] | None = (
strawberry_django.filter_field()
)
mark_utilized: FilterLookup[bool] | None = strawberry_django.filter_field()
@strawberry_django.filter_field()
def parent(self, value: list[str], prefix) -> Q:
if not value:
return Q()
q = Q()
for subnet in value:
try:
query = str(netaddr.IPNetwork(subnet.strip()).cidr)
q |= Q(start_address__net_host_contained=query, end_address__net_host_contained=query)
except (AddrFormatError, ValueError):
return Q()
return q
@strawberry_django.filter(models.Prefix, lookups=True) @strawberry_django.filter(models.Prefix, lookups=True)
@autotype_decorator(filtersets.PrefixFilterSet) class PrefixFilter(ContactFilterMixin, PrimaryModelFilterMixin):
class PrefixFilter(BaseFilterMixin): prefix: FilterLookup[str] | None = strawberry_django.filter_field()
pass vrf: Annotated['VRFFilter', strawberry.lazy('ipam.graphql.filters')] | None = strawberry_django.filter_field()
vrf_id: ID | None = strawberry_django.filter_field()
tenant: Annotated['TenantFilter', strawberry.lazy('tenancy.graphql.filters')] | None = (
strawberry_django.filter_field()
)
tenant_id: ID | None = strawberry_django.filter_field()
vlan: Annotated['VLANFilter', strawberry.lazy('ipam.graphql.filters')] | None = strawberry_django.filter_field()
vlan_id: ID | None = strawberry_django.filter_field()
status: Annotated['PrefixStatusEnum', strawberry.lazy('ipam.graphql.enums')] | None = (
strawberry_django.filter_field()
)
role: Annotated['RoleFilter', strawberry.lazy('ipam.graphql.filters')] | None = strawberry_django.filter_field()
role_id: ID | None = strawberry_django.filter_field()
is_pool: FilterLookup[bool] | None = strawberry_django.filter_field()
mark_utilized: FilterLookup[bool] | None = strawberry_django.filter_field()
scope_type: Annotated['ContentTypeFilter', strawberry.lazy('core.graphql.filters')] | None = (
strawberry_django.filter_field()
)
scope_id: ID | None = strawberry_django.filter_field()
@strawberry_django.filter(models.RIR, lookups=True) @strawberry_django.filter(models.RIR, lookups=True)
@autotype_decorator(filtersets.RIRFilterSet) class RIRFilter(OrganizationalModelFilterMixin):
class RIRFilter(BaseFilterMixin): is_private: FilterLookup[bool] | None = strawberry_django.filter_field()
pass
@strawberry_django.filter(models.Role, lookups=True) @strawberry_django.filter(models.Role, lookups=True)
@autotype_decorator(filtersets.RoleFilterSet) class RoleFilter(OrganizationalModelFilterMixin):
class RoleFilter(BaseFilterMixin): weight: Annotated['IntegerLookup', strawberry.lazy('core.graphql.filter_lookups')] | None = (
pass strawberry_django.filter_field()
)
@strawberry_django.filter(models.RouteTarget, lookups=True) @strawberry_django.filter(models.RouteTarget, lookups=True)
@autotype_decorator(filtersets.RouteTargetFilterSet) class RouteTargetFilter(PrimaryModelFilterMixin):
class RouteTargetFilter(BaseFilterMixin): name: FilterLookup[str] | None = strawberry_django.filter_field()
pass tenant: Annotated['TenantFilter', strawberry.lazy('tenancy.graphql.filters')] | None = (
strawberry_django.filter_field()
)
tenant_id: ID | None = strawberry_django.filter_field()
@strawberry_django.filter(models.Service, lookups=True) @strawberry_django.filter(models.Service, lookups=True)
@autotype_decorator(filtersets.ServiceFilterSet) class ServiceFilter(ContactFilterMixin, ServiceBaseFilterMixin, PrimaryModelFilterMixin):
class ServiceFilter(BaseFilterMixin): device: Annotated['DeviceFilter', strawberry.lazy('dcim.graphql.filters')] | None = strawberry_django.filter_field()
pass device_id: ID | None = strawberry_django.filter_field()
virtual_machine: Annotated['VirtualMachineFilter', strawberry.lazy('virtualization.graphql.filters')] | None = (
strawberry_django.filter_field()
)
virtual_machine_id: ID | None = strawberry_django.filter_field()
name: FilterLookup[str] | None = strawberry_django.filter_field()
ipaddresses: Annotated['IPAddressFilter', strawberry.lazy('ipam.graphql.filters')] | None = (
strawberry_django.filter_field()
)
@strawberry_django.filter(models.ServiceTemplate, lookups=True) @strawberry_django.filter(models.ServiceTemplate, lookups=True)
@autotype_decorator(filtersets.ServiceTemplateFilterSet) class ServiceTemplateFilter(ServiceBaseFilterMixin, PrimaryModelFilterMixin):
class ServiceTemplateFilter(BaseFilterMixin): name: FilterLookup[str] | None = strawberry_django.filter_field()
pass
@strawberry_django.filter(models.VLAN, lookups=True) @strawberry_django.filter(models.VLAN, lookups=True)
@autotype_decorator(filtersets.VLANFilterSet) class VLANFilter(PrimaryModelFilterMixin):
class VLANFilter(BaseFilterMixin): site: Annotated['SiteFilter', strawberry.lazy('dcim.graphql.filters')] | None = strawberry_django.filter_field()
pass site_id: ID | None = strawberry_django.filter_field()
group: Annotated['VLANGroupFilter', strawberry.lazy('ipam.graphql.filters')] | None = (
strawberry_django.filter_field()
)
group_id: ID | None = strawberry_django.filter_field()
vid: Annotated['IntegerLookup', strawberry.lazy('core.graphql.filter_lookups')] | None = (
strawberry_django.filter_field()
)
name: FilterLookup[str] | None = strawberry_django.filter_field()
tenant: Annotated['TenantFilter', strawberry.lazy('tenancy.graphql.filters')] | None = (
strawberry_django.filter_field()
)
tenant_id: ID | None = strawberry_django.filter_field()
status: Annotated['VLANStatusEnum', strawberry.lazy('ipam.graphql.enums')] | None = strawberry_django.filter_field()
role: Annotated['RoleFilter', strawberry.lazy('ipam.graphql.filters')] | None = strawberry_django.filter_field()
role_id: ID | None = strawberry_django.filter_field()
qinq_svlan: Annotated['VLANFilter', strawberry.lazy('ipam.graphql.filters')] | None = (
strawberry_django.filter_field()
)
qinq_svlan_id: ID | None = strawberry_django.filter_field()
qinq_cvlan: Annotated['VLANFilter', strawberry.lazy('ipam.graphql.filters')] | None = (
strawberry_django.filter_field()
)
qinq_cvlan_id: ID | None = strawberry_django.filter_field()
qinq_role: Annotated['VLANQinQRoleEnum', strawberry.lazy('ipam.graphql.enums')] | None = (
strawberry_django.filter_field()
)
l2vpn_terminations: Annotated['L2VPNFilter', strawberry.lazy('vpn.graphql.filters')] | None = (
strawberry_django.filter_field()
)
@strawberry_django.filter(models.VLANGroup, lookups=True) @strawberry_django.filter(models.VLANGroup, lookups=True)
@autotype_decorator(filtersets.VLANGroupFilterSet) class VLANGroupFilter(OrganizationalModelFilterMixin):
class VLANGroupFilter(BaseFilterMixin): scope_type: Annotated['ContentTypeFilter', strawberry.lazy('core.graphql.filters')] | None = (
pass strawberry_django.filter_field()
)
scope_type_id: ID | None = strawberry_django.filter_field()
scope_id: ID | None = strawberry_django.filter_field()
vid_ranges: Annotated['IntegerArrayLookup', strawberry.lazy('core.graphql.filter_lookups')] | None = (
strawberry_django.filter_field()
)
@strawberry_django.filter(models.VLANTranslationPolicy, lookups=True) @strawberry_django.filter(models.VLANTranslationPolicy, lookups=True)
@autotype_decorator(filtersets.VLANTranslationPolicyFilterSet) class VLANTranslationPolicyFilter(PrimaryModelFilterMixin):
class VLANTranslationPolicyFilter(BaseFilterMixin): name: FilterLookup[str] | None = strawberry_django.filter_field()
pass
@strawberry_django.filter(models.VLANTranslationRule, lookups=True) @strawberry_django.filter(models.VLANTranslationRule, lookups=True)
@autotype_decorator(filtersets.VLANTranslationRuleFilterSet) class VLANTranslationRuleFilter(NetBoxModelFilterMixin):
class VLANTranslationRuleFilter(BaseFilterMixin): policy: Annotated['VLANTranslationPolicyFilter', strawberry.lazy('ipam.graphql.filters')] | None = (
pass strawberry_django.filter_field()
)
policy_id: ID | None = strawberry_django.filter_field()
description: FilterLookup[str] | None = strawberry_django.filter_field()
local_vid: Annotated['IntegerLookup', strawberry.lazy('core.graphql.filter_lookups')] | None = (
strawberry_django.filter_field()
)
remote_vid: Annotated['IntegerLookup', strawberry.lazy('core.graphql.filter_lookups')] | None = (
strawberry_django.filter_field()
)
@strawberry_django.filter(models.VRF, lookups=True) @strawberry_django.filter(models.VRF, lookups=True)
@autotype_decorator(filtersets.VRFFilterSet) class VRFFilter(PrimaryModelFilterMixin):
class VRFFilter(BaseFilterMixin): name: FilterLookup[str] | None = strawberry_django.filter_field()
pass rd: FilterLookup[str] | None = strawberry_django.filter_field()
tenant: Annotated['TenantFilter', strawberry.lazy('tenancy.graphql.filters')] | None = (
strawberry_django.filter_field()
)
tenant_id: ID | None = strawberry_django.filter_field()
enforce_unique: FilterLookup[bool] | None = strawberry_django.filter_field()
import_targets: Annotated['RouteTargetFilter', strawberry.lazy('ipam.graphql.filters')] | None = (
strawberry_django.filter_field()
)
export_targets: Annotated['RouteTargetFilter', strawberry.lazy('ipam.graphql.filters')] | None = (
strawberry_django.filter_field()
)

View File

@ -0,0 +1,120 @@
from enum import Enum
import strawberry
__all__ = [
'ColorEnum',
'ButtonColorEnum',
'ImportMethodEnumEnum',
'ImportFormatEnum',
'DistanceUnitEnum',
'WeightUnitEnum',
]
#
# Generic color choices
#
@strawberry.enum
class ColorEnum(Enum):
COLOR_DARK_RED = 'aa1409'
COLOR_RED = 'f44336'
COLOR_PINK = 'e91e63'
COLOR_ROSE = 'ffe4e1'
COLOR_FUCHSIA = 'ff66ff'
COLOR_PURPLE = '9c27b0'
COLOR_DARK_PURPLE = '673ab7'
COLOR_INDIGO = '3f51b5'
COLOR_BLUE = '2196f3'
COLOR_LIGHT_BLUE = '03a9f4'
COLOR_CYAN = '00bcd4'
COLOR_TEAL = '009688'
COLOR_AQUA = '00ffff'
COLOR_DARK_GREEN = '2f6a31'
COLOR_GREEN = '4caf50'
COLOR_LIGHT_GREEN = '8bc34a'
COLOR_LIME = 'cddc39'
COLOR_YELLOW = 'ffeb3b'
COLOR_AMBER = 'ffc107'
COLOR_ORANGE = 'ff9800'
COLOR_DARK_ORANGE = 'ff5722'
COLOR_BROWN = '795548'
COLOR_LIGHT_GREY = 'c0c0c0'
COLOR_GREY = '9e9e9e'
COLOR_DARK_GREY = '607d8b'
COLOR_BLACK = '111111'
COLOR_WHITE = 'ffffff'
#
# Button color choices
#
@strawberry.enum
class ButtonColorEnum(Enum):
DEFAULT = 'default'
BLUE = 'blue'
INDIGO = 'indigo'
PURPLE = 'purple'
PINK = 'pink'
RED = 'red'
ORANGE = 'orange'
YELLOW = 'yellow'
GREEN = 'green'
TEAL = 'teal'
CYAN = 'cyan'
GRAY = 'gray'
GREY = 'gray' # Backward compatability for <3.2
BLACK = 'black'
WHITE = 'white'
#
# Import
#
@strawberry.enum
class ImportMethodEnumEnum(Enum):
DIRECT = 'direct'
UPLOAD = 'upload'
DATA_FILE = 'datafile'
@strawberry.enum
class ImportFormatEnum(Enum):
AUTO = 'auto'
CSV = 'csv'
JSON = 'json'
YAML = 'yaml'
# @strawberry.enum
# class CSVDelimiterEnum(Enum):
# AUTO = 'auto'
# COMMA = CSV_DELIMITERS['comma']
# SEMICOLON = CSV_DELIMITERS['semicolon']
# TAB = CSV_DELIMITERS['tab']
@strawberry.enum
class DistanceUnitEnum(Enum):
# Metric
UNIT_KILOMETER = 'km'
UNIT_METER = 'm'
# Imperial
UNIT_MILE = 'mi'
UNIT_FOOT = 'ft'
@strawberry.enum
class WeightUnitEnum(Enum):
# Metric
UNIT_KILOGRAM = 'kg'
UNIT_GRAM = 'g'
# Imperial
UNIT_POUND = 'lb'
UNIT_OUNCE = 'oz'

View File

@ -1,209 +1,114 @@
from functools import partialmethod from dataclasses import dataclass
from typing import List from typing import TypeVar, TYPE_CHECKING, Annotated
import django_filters
from datetime import datetime
import strawberry import strawberry
from strawberry import ID
import strawberry_django import strawberry_django
from django.core.exceptions import FieldDoesNotExist from strawberry_django import FilterLookup, DatetimeFilterLookup
from strawberry import auto
from ipam.fields import ASNField from extras.models import *
from netbox.graphql.scalars import BigInt
from utilities.fields import ColorField, CounterCacheField
from utilities.filters import * from utilities.filters import *
from core.graphql.filter_lookups import *
from core.graphql.filter_mixins import *
from extras.graphql.filter_mixins import *
__all__ = [
'NetBoxModelFilterMixin',
'OrganizationalModelFilterMixin',
'PrimaryModelFilterMixin',
# 'autotype_decorator',
'NestedGroupModelFilterMixin',
'ImageAttachmentFilterMixin',
'WeightFilterMixin',
'SyncedDataFilterMixin',
'DistanceFilterMixin',
]
T = TypeVar('T')
def map_strawberry_type(field): if TYPE_CHECKING:
should_create_function = False from .enums import *
attr_type = None from core.graphql.filters import *
from tenancy.graphql.filters import *
# NetBox Filter types - put base classes after derived classes from extras.graphql.filters import *
if isinstance(field, ContentTypeFilter):
should_create_function = True
attr_type = str | None
elif isinstance(field, MultiValueArrayFilter):
pass
elif isinstance(field, MultiValueCharFilter):
# Note: Need to use the legacy FilterLookup from filters, not from
# strawberry_django.FilterLookup as we currently have USE_DEPRECATED_FILTERS
attr_type = strawberry_django.filters.FilterLookup[str] | None
elif isinstance(field, MultiValueDateFilter):
attr_type = auto
elif isinstance(field, MultiValueDateTimeFilter):
attr_type = auto
elif isinstance(field, MultiValueDecimalFilter):
pass
elif isinstance(field, MultiValueMACAddressFilter):
should_create_function = True
attr_type = List[str] | None
elif isinstance(field, MultiValueNumberFilter):
should_create_function = True
attr_type = List[str] | None
elif isinstance(field, MultiValueTimeFilter):
pass
elif isinstance(field, MultiValueWWNFilter):
should_create_function = True
attr_type = List[str] | None
elif isinstance(field, NullableCharFieldFilter):
pass
elif isinstance(field, NumericArrayFilter):
should_create_function = True
attr_type = int | None
elif isinstance(field, TreeNodeMultipleChoiceFilter):
should_create_function = True
attr_type = List[str] | None
# From django_filters - ordering of these matters as base classes must
# come after derived classes so the base class doesn't get matched first
# a pass for the check (no attr_type) means we don't currently handle
# or use that type
elif issubclass(type(field), django_filters.OrderingFilter):
pass
elif issubclass(type(field), django_filters.BaseRangeFilter):
pass
elif issubclass(type(field), django_filters.BaseInFilter):
pass
elif issubclass(type(field), django_filters.LookupChoiceFilter):
pass
elif issubclass(type(field), django_filters.AllValuesMultipleFilter):
pass
elif issubclass(type(field), django_filters.AllValuesFilter):
pass
elif issubclass(type(field), django_filters.TimeRangeFilter):
pass
elif issubclass(type(field), django_filters.IsoDateTimeFromToRangeFilter):
should_create_function = True
attr_type = str | None
elif issubclass(type(field), django_filters.DateTimeFromToRangeFilter):
should_create_function = True
attr_type = str | None
elif issubclass(type(field), django_filters.DateFromToRangeFilter):
should_create_function = True
attr_type = str | None
elif issubclass(type(field), django_filters.DateRangeFilter):
should_create_function = True
attr_type = str | None
elif issubclass(type(field), django_filters.RangeFilter):
pass
elif issubclass(type(field), django_filters.NumericRangeFilter):
pass
elif issubclass(type(field), django_filters.NumberFilter):
should_create_function = True
attr_type = int | None
elif issubclass(type(field), django_filters.ModelMultipleChoiceFilter):
should_create_function = True
attr_type = List[str] | None
elif issubclass(type(field), django_filters.ModelChoiceFilter):
should_create_function = True
attr_type = str | None
elif issubclass(type(field), django_filters.DurationFilter):
pass
elif issubclass(type(field), django_filters.IsoDateTimeFilter):
pass
elif issubclass(type(field), django_filters.DateTimeFilter):
attr_type = auto
elif issubclass(type(field), django_filters.TimeFilter):
attr_type = auto
elif issubclass(type(field), django_filters.DateFilter):
attr_type = auto
elif issubclass(type(field), django_filters.TypedMultipleChoiceFilter):
pass
elif issubclass(type(field), django_filters.MultipleChoiceFilter):
attr_type = str | None
elif issubclass(type(field), django_filters.TypedChoiceFilter):
pass
elif issubclass(type(field), django_filters.ChoiceFilter):
pass
elif issubclass(type(field), django_filters.BooleanFilter):
should_create_function = True
attr_type = bool | None
elif issubclass(type(field), django_filters.UUIDFilter):
should_create_function = True
attr_type = str | None
elif issubclass(type(field), django_filters.CharFilter):
# looks like only used by 'q'
should_create_function = True
attr_type = str | None
return should_create_function, attr_type
def autotype_decorator(filterset): class NetBoxModelFilterMixin(
""" ChangeLogFilterMixin,
Decorator used to auto creates a dataclass used by Strawberry based on a filterset. CustomFieldsFilterMixin,
Must go after the Strawberry decorator as follows: JournalEntriesFilterMixin,
TagsFilterMixin,
@strawberry_django.filter(models.Example, lookups=True) BaseObjectTypeFilterMixin,
@autotype_decorator(filtersets.ExampleFilterSet) ):
class ExampleFilter(BaseFilterMixin):
pass pass
The Filter itself must be derived from BaseFilterMixin. For items listed in meta.fields
of the filterset, usually just a type specifier is generated, so for
`fields = [created, ]` the dataclass would be:
class ExampleFilter(BaseFilterMixin): @dataclass
created: auto class NestedGroupModelFilterMixin(NetBoxModelFilterMixin):
name: FilterLookup[str] | None = strawberry_django.filter_field()
For other filter fields a function needs to be created for Strawberry with the slug: FilterLookup[str] | None = strawberry_django.filter_field()
naming convention `filter_{fieldname}` which is auto detected and called by description: FilterLookup[str] | None = strawberry_django.filter_field()
Strawberry, this function uses the filterset to handle the query. lft: IntegerLookup | None = strawberry_django.filter_field()
""" rght: IntegerLookup | None = strawberry_django.filter_field()
def create_attribute_and_function(cls, fieldname, attr_type, should_create_function): tree_id: IntegerLookup | None = strawberry_django.filter_field()
if fieldname not in cls.__annotations__ and attr_type: level: IntegerLookup | None = strawberry_django.filter_field()
cls.__annotations__[fieldname] = attr_type parent_id: ID | None = strawberry_django.filter_field()
filter_name = f"filter_{fieldname}"
if should_create_function and not hasattr(cls, filter_name):
filter_by_filterset = getattr(cls, 'filter_by_filterset')
setattr(cls, filter_name, partialmethod(filter_by_filterset, key=fieldname))
def wrapper(cls):
cls.filterset = filterset
fields = filterset.get_fields()
model = filterset._meta.model
for fieldname in fields.keys():
should_create_function = False
attr_type = auto
if fieldname not in cls.__annotations__:
try:
field = model._meta.get_field(fieldname)
except FieldDoesNotExist:
continue
if isinstance(field, CounterCacheField):
should_create_function = True
attr_type = BigInt | None
elif isinstance(field, ASNField):
should_create_function = True
attr_type = List[str] | None
elif isinstance(field, ColorField):
should_create_function = True
attr_type = List[str] | None
create_attribute_and_function(cls, fieldname, attr_type, should_create_function)
declared_filters = filterset.declared_filters
for fieldname, field in declared_filters.items():
should_create_function, attr_type = map_strawberry_type(field)
if attr_type is None:
raise NotImplementedError(f"GraphQL Filter field unknown: {fieldname}: {field}")
create_attribute_and_function(cls, fieldname, attr_type, should_create_function)
return cls
return wrapper
@strawberry.input @dataclass
class BaseFilterMixin: class OrganizationalModelFilterMixin(
ChangeLogFilterMixin,
CustomFieldsFilterMixin,
TagsFilterMixin,
BaseObjectTypeFilterMixin,
):
name: FilterLookup[str] | None = strawberry_django.filter_field()
slug: FilterLookup[str] | None = strawberry_django.filter_field()
description: FilterLookup[str] | None = strawberry_django.filter_field()
def filter_by_filterset(self, queryset, key):
filterset = self.filterset(data={key: getattr(self, key)}, queryset=queryset) @dataclass
if not filterset.is_valid(): class PrimaryModelFilterMixin(NetBoxModelFilterMixin):
# We could raise validation error but strawberry logs it all to the description: FilterLookup[str] | None = strawberry_django.filter_field()
# console i.e. raise ValidationError(f"{k}: {v[0]}") comments: FilterLookup[str] | None = strawberry_django.filter_field()
return filterset.qs.none()
return filterset.qs
@dataclass
class ImageAttachmentFilterMixin(BaseFilterMixin):
images: Annotated['ImageAttachmentFilter', strawberry.lazy('extras.graphql.filters')] | None = (
strawberry_django.filter_field()
)
@dataclass
class WeightFilterMixin(BaseFilterMixin):
weight: FilterLookup[float] | None = strawberry_django.filter_field()
weight_unit: Annotated['WeightUnitEnum', strawberry.lazy('netbox.graphql.enums')] | None = (
strawberry_django.filter_field()
)
@dataclass
class SyncedDataFilterMixin(BaseFilterMixin):
data_source: Annotated['DataSourceFilter', strawberry.lazy('core.graphql.filters')] | None = (
strawberry_django.filter_field()
)
data_source_id: FilterLookup[int] | None = strawberry_django.filter_field()
data_file: Annotated['DataFileFilter', strawberry.lazy('core.graphql.filters')] | None = (
strawberry_django.filter_field()
)
data_file_id: FilterLookup[int] | None = strawberry_django.filter_field()
data_path: FilterLookup[str] | None = strawberry_django.filter_field()
auto_sync_enabled: FilterLookup[bool] | None = strawberry_django.filter_field()
data_synced: DatetimeFilterLookup[datetime] | None = strawberry_django.filter_field()
@dataclass
class DistanceFilterMixin(BaseFilterMixin):
distance: FilterLookup[float] | None = strawberry_django.filter_field()
distance_unit: Annotated['DistanceUnitEnum', strawberry.lazy('netbox.graphql.enums')] | None = (
strawberry_django.filter_field()
)

View File

@ -38,7 +38,8 @@ schema = strawberry.Schema(
query=Query, query=Query,
config=StrawberryConfig(auto_camel_case=False), config=StrawberryConfig(auto_camel_case=False),
extensions=[ extensions=[
DjangoOptimizerExtension(prefetch_custom_queryset=True), # DjangoOptimizerExtension(prefetch_custom_queryset=True),
DjangoOptimizerExtension(prefetch_custom_queryset=True, enable_prefetch_related_optimization=False),
MaxAliasesLimiter(max_alias_count=settings.GRAPHQL_MAX_ALIASES), MaxAliasesLimiter(max_alias_count=settings.GRAPHQL_MAX_ALIASES),
] ]
) )

View File

@ -775,7 +775,7 @@ LOCALE_PATHS = (
STRAWBERRY_DJANGO = { STRAWBERRY_DJANGO = {
"DEFAULT_PK_FIELD_NAME": "id", "DEFAULT_PK_FIELD_NAME": "id",
"TYPE_DESCRIPTION_FROM_MODEL_DOCSTRING": True, "TYPE_DESCRIPTION_FROM_MODEL_DOCSTRING": True,
"USE_DEPRECATED_FILTERS": True, "USE_DEPRECATED_FILTERS": False,
} }
# #

View File

@ -99,12 +99,13 @@ class GraphQLAPITestCase(APITestCase):
# Test OR logic # Test OR logic
query = """{ query = """{
location_list( filters: { location_list( filters: {
status: \"""" + LocationStatusChoices.STATUS_PLANNED + """\", status: STATUS_PLANNED,
OR: {status: \"""" + LocationStatusChoices.STATUS_STAGING + """\"} OR: {status: STATUS_STAGING}
}) { }) {
id site {id} id site {id}
} }
}""" }"""
print(query)
response = self.client.post(url, data={'query': query}, format="json", **self.header) response = self.client.post(url, data={'query': query}, format="json", **self.header)
self.assertHttpStatus(response, status.HTTP_200_OK) self.assertHttpStatus(response, status.HTTP_200_OK)
data = json.loads(response.content) data = json.loads(response.content)

View File

@ -0,0 +1,33 @@
from dataclasses import dataclass
from typing import Annotated, TYPE_CHECKING
import strawberry
from strawberry import ID
import strawberry_django
from core.graphql.filter_mixins import BaseFilterMixin
if TYPE_CHECKING:
from .filters import *
from core.graphql.filter_lookups import *
__all__ = ['TenancyFilterMixin', 'ContactFilterMixin']
@dataclass
class ContactFilterMixin(BaseFilterMixin):
contacts: Annotated['ContactFilter', strawberry.lazy('tenancy.graphql.filters')] | None = (
strawberry_django.filter_field()
)
@dataclass
class TenancyFilterMixin(BaseFilterMixin):
tenant: Annotated['TenantFilter', strawberry.lazy('tenancy.graphql.filters')] | None = (
strawberry_django.filter_field()
)
tenant_id: ID | None = strawberry_django.filter_field()
group: Annotated['TenantGroupFilter', strawberry.lazy('tenancy.graphql.filters')] | None = (
strawberry_django.filter_field()
)
group_id: Annotated['TreeNodeFilter', strawberry.lazy('core.graphql.filter_lookups')] | None = (
strawberry_django.filter_field()
)

View File

@ -1,7 +1,28 @@
from typing import Annotated, TYPE_CHECKING
import strawberry
from strawberry.scalars import ID
import strawberry_django import strawberry_django
from strawberry_django import (
FilterLookup,
)
from netbox.graphql.filter_mixins import (
PrimaryModelFilterMixin,
OrganizationalModelFilterMixin,
NestedGroupModelFilterMixin,
)
from extras.graphql.filter_mixins import CustomFieldsFilterMixin, TagsFilterMixin
from core.graphql.filter_mixins import ChangeLogFilterMixin
from tenancy import models
from .filter_mixins import ContactFilterMixin
from netbox.graphql.filter_mixins import autotype_decorator, BaseFilterMixin if TYPE_CHECKING:
from tenancy import filtersets, models from core.graphql.filter_lookups import TreeNodeFilter
from circuits.graphql.filters import *
from dcim.graphql.filters import *
from ipam.graphql.filters import *
from wireless.graphql.filters import *
from virtualization.graphql.filters import *
from vpn.graphql.filters import *
__all__ = ( __all__ = (
'TenantFilter', 'TenantFilter',
@ -14,36 +35,127 @@ __all__ = (
@strawberry_django.filter(models.Tenant, lookups=True) @strawberry_django.filter(models.Tenant, lookups=True)
@autotype_decorator(filtersets.TenantFilterSet) class TenantFilter(PrimaryModelFilterMixin, ContactFilterMixin):
class TenantFilter(BaseFilterMixin): name: FilterLookup[str] | None = strawberry_django.filter_field()
pass slug: FilterLookup[str] | None = strawberry_django.filter_field()
group: Annotated['TenantGroupFilter', strawberry.lazy('tenancy.graphql.filters')] | None = (
strawberry_django.filter_field()
)
group_id: Annotated['TreeNodeFilter', strawberry.lazy('core.graphql.filter_lookups')] | None = (
strawberry_django.filter_field()
)
asns: Annotated['ASNFilter', strawberry.lazy('ipam.graphql.filters')] | None = strawberry_django.filter_field()
circuits: Annotated['CircuitFilter', strawberry.lazy('circuits.graphql.filters')] | None = (
strawberry_django.filter_field()
)
sites: Annotated['SiteFilter', strawberry.lazy('dcim.graphql.filters')] | None = strawberry_django.filter_field()
vlans: Annotated['VLANFilter', strawberry.lazy('ipam.graphql.filters')] | None = strawberry_django.filter_field()
wireless_lans: Annotated['WirelessLANFilter', strawberry.lazy('wireless.graphql.filters')] | None = (
strawberry_django.filter_field()
)
route_targets: Annotated['RouteTargetFilter', strawberry.lazy('ipam.graphql.filters')] | None = (
strawberry_django.filter_field()
)
locations: Annotated['LocationFilter', strawberry.lazy('dcim.graphql.filters')] | None = (
strawberry_django.filter_field()
)
ip_ranges: Annotated['IPRangeFilter', strawberry.lazy('ipam.graphql.filters')] | None = (
strawberry_django.filter_field()
)
rackreservations: Annotated['RackReservationFilter', strawberry.lazy('dcim.graphql.filters')] | None = (
strawberry_django.filter_field()
)
racks: Annotated['RackFilter', strawberry.lazy('dcim.graphql.filters')] | None = strawberry_django.filter_field()
vdcs: Annotated['VirtualDeviceContextFilter', strawberry.lazy('dcim.graphql.filters')] | None = (
strawberry_django.filter_field()
)
prefixes: Annotated['PrefixFilter', strawberry.lazy('ipam.graphql.filters')] | None = (
strawberry_django.filter_field()
)
cables: Annotated['CableFilter', strawberry.lazy('dcim.graphql.filters')] | None = strawberry_django.filter_field()
virtual_machines: Annotated['VirtualMachineFilter', strawberry.lazy('virtualization.graphql.filters')] | None = (
strawberry_django.filter_field()
)
vrfs: Annotated['VRFFilter', strawberry.lazy('ipam.graphql.filters')] | None = strawberry_django.filter_field()
asn_ranges: Annotated['ASNRangeFilter', strawberry.lazy('ipam.graphql.filters')] | None = (
strawberry_django.filter_field()
)
wireless_links: Annotated['WirelessLinkFilter', strawberry.lazy('wireless.graphql.filters')] | None = (
strawberry_django.filter_field()
)
aggregates: Annotated['AggregateFilter', strawberry.lazy('ipam.graphql.filters')] | None = (
strawberry_django.filter_field()
)
power_feeds: Annotated['PowerFeedFilter', strawberry.lazy('dcim.graphql.filters')] | None = (
strawberry_django.filter_field()
)
devices: Annotated['DeviceFilter', strawberry.lazy('dcim.graphql.filters')] | None = (
strawberry_django.filter_field()
)
tunnels: Annotated['TunnelFilter', strawberry.lazy('vpn.graphql.filters')] | None = strawberry_django.filter_field()
ip_addresses: Annotated['IPAddressFilter', strawberry.lazy('ipam.graphql.filters')] | None = (
strawberry_django.filter_field()
)
clusters: Annotated['ClusterFilter', strawberry.lazy('virtualization.graphql.filters')] | None = (
strawberry_django.filter_field()
)
l2vpns: Annotated['L2VPNFilter', strawberry.lazy('vpn.graphql.filters')] | None = strawberry_django.filter_field()
@strawberry_django.filter(models.TenantGroup, lookups=True) @strawberry_django.filter(models.TenantGroup, lookups=True)
@autotype_decorator(filtersets.TenantGroupFilterSet) class TenantGroupFilter(OrganizationalModelFilterMixin):
class TenantGroupFilter(BaseFilterMixin): parent: Annotated['TenantGroupFilter', strawberry.lazy('tenancy.graphql.filters')] | None = (
pass strawberry_django.filter_field()
)
parent_id: ID | None = strawberry.UNSET
tenants: Annotated['TenantFilter', strawberry.lazy('tenancy.graphql.filters')] | None = (
strawberry_django.filter_field()
)
children: Annotated['TenantGroupFilter', strawberry.lazy('tenancy.graphql.filters'), True] | None = (
strawberry_django.filter_field()
)
@strawberry_django.filter(models.Contact, lookups=True) @strawberry_django.filter(models.Contact, lookups=True)
@autotype_decorator(filtersets.ContactFilterSet) class ContactFilter(PrimaryModelFilterMixin):
class ContactFilter(BaseFilterMixin): name: FilterLookup[str] | None = strawberry_django.filter_field()
pass title: FilterLookup[str] | None = strawberry_django.filter_field()
phone: FilterLookup[str] | None = strawberry_django.filter_field()
email: FilterLookup[str] | None = strawberry_django.filter_field()
address: FilterLookup[str] | None = strawberry_django.filter_field()
link: FilterLookup[str] | None = strawberry_django.filter_field()
group: Annotated['ContactGroupFilter', strawberry.lazy('tenancy.graphql.filters')] | None = (
strawberry_django.filter_field()
)
group_id: Annotated['TreeNodeFilter', strawberry.lazy('core.graphql.filter_lookups')] | None = (
strawberry_django.filter_field()
)
assignments: Annotated['ContactAssignmentFilter', strawberry.lazy('tenancy.graphql.filters')] | None = (
strawberry_django.filter_field()
)
@strawberry_django.filter(models.ContactRole, lookups=True) @strawberry_django.filter(models.ContactRole, lookups=True)
@autotype_decorator(filtersets.ContactRoleFilterSet) class ContactRoleFilter(OrganizationalModelFilterMixin):
class ContactRoleFilter(BaseFilterMixin):
pass pass
@strawberry_django.filter(models.ContactGroup, lookups=True) @strawberry_django.filter(models.ContactGroup, lookups=True)
@autotype_decorator(filtersets.ContactGroupFilterSet) class ContactGroupFilter(NestedGroupModelFilterMixin):
class ContactGroupFilter(BaseFilterMixin): parent: Annotated['ContactGroupFilter', strawberry.lazy('tenancy.graphql.filters')] | None = (
pass strawberry_django.filter_field()
)
@strawberry_django.filter(models.ContactAssignment, lookups=True) @strawberry_django.filter(models.ContactAssignment, lookups=True)
@autotype_decorator(filtersets.ContactAssignmentFilterSet) class ContactAssignmentFilter(CustomFieldsFilterMixin, TagsFilterMixin, ChangeLogFilterMixin):
class ContactAssignmentFilter(BaseFilterMixin): object_id: ID | None = strawberry_django.filter_field()
pass contact: Annotated['ContactFilter', strawberry.lazy('tenancy.graphql.filters')] | None = (
strawberry_django.filter_field()
)
contact_id: ID | None = strawberry_django.filter_field()
role: Annotated['ContactRoleFilter', strawberry.lazy('tenancy.graphql.filters')] | None = (
strawberry_django.filter_field()
)
role_id: ID | None = strawberry_django.filter_field()
priority: FilterLookup[str] | None = strawberry_django.filter_field()

View File

@ -1,4 +1,4 @@
from typing import Annotated, List from typing import Annotated, List, TYPE_CHECKING
import strawberry import strawberry
import strawberry_django import strawberry_django
@ -9,6 +9,14 @@ from tenancy import models
from .mixins import ContactAssignmentsMixin from .mixins import ContactAssignmentsMixin
from .filters import * from .filters import *
if TYPE_CHECKING:
from circuits.graphql.types import *
from dcim.graphql.types import *
from ipam.graphql.types import *
from wireless.graphql.types import *
from virtualization.graphql.types import *
from vpn.graphql.types import *
__all__ = ( __all__ = (
'ContactAssignmentType', 'ContactAssignmentType',
'ContactGroupType', 'ContactGroupType',
@ -23,92 +31,70 @@ __all__ = (
# Tenants # Tenants
# #
@strawberry_django.type(
models.Tenant, @strawberry_django.type(models.Tenant, fields='__all__', filters=TenantFilter)
fields='__all__',
filters=TenantFilter
)
class TenantType(NetBoxObjectType): class TenantType(NetBoxObjectType):
group: Annotated["TenantGroupType", strawberry.lazy('tenancy.graphql.types')] | None group: Annotated['TenantGroupType', strawberry.lazy('tenancy.graphql.types')]
contacts: List[Annotated['ContactType', strawberry.lazy('tenancy.graphql.types')]]
asns: List[Annotated["ASNType", strawberry.lazy('ipam.graphql.types')]] asns: List[Annotated['ASNType', strawberry.lazy('ipam.graphql.types')]]
circuits: List[Annotated["CircuitType", strawberry.lazy('circuits.graphql.types')]] circuits: List[Annotated['CircuitType', strawberry.lazy('circuits.graphql.types')]]
sites: List[Annotated["SiteType", strawberry.lazy('dcim.graphql.types')]] sites: List[Annotated['SiteType', strawberry.lazy('dcim.graphql.types')]]
vlans: List[Annotated["VLANType", strawberry.lazy('ipam.graphql.types')]] vlans: List[Annotated['VLANType', strawberry.lazy('ipam.graphql.types')]]
wireless_lans: List[Annotated["WirelessLANType", strawberry.lazy('wireless.graphql.types')]] wireless_lans: List[Annotated['WirelessLANType', strawberry.lazy('wireless.graphql.types')]]
route_targets: List[Annotated["RouteTargetType", strawberry.lazy('ipam.graphql.types')]] route_targets: List[Annotated['RouteTargetType', strawberry.lazy('ipam.graphql.types')]]
locations: List[Annotated["LocationType", strawberry.lazy('dcim.graphql.types')]] locations: List[Annotated['LocationType', strawberry.lazy('dcim.graphql.types')]]
ip_ranges: List[Annotated["IPRangeType", strawberry.lazy('ipam.graphql.types')]] ip_ranges: List[Annotated['IPRangeType', strawberry.lazy('ipam.graphql.types')]]
rackreservations: List[Annotated["RackReservationType", strawberry.lazy('dcim.graphql.types')]] rackreservations: List[Annotated['RackReservationType', strawberry.lazy('dcim.graphql.types')]]
racks: List[Annotated["RackType", strawberry.lazy('dcim.graphql.types')]] racks: List[Annotated['RackType', strawberry.lazy('dcim.graphql.types')]]
vdcs: List[Annotated["VirtualDeviceContextType", strawberry.lazy('dcim.graphql.types')]] vdcs: List[Annotated['VirtualDeviceContextType', strawberry.lazy('dcim.graphql.types')]]
prefixes: List[Annotated["PrefixType", strawberry.lazy('ipam.graphql.types')]] prefixes: List[Annotated['PrefixType', strawberry.lazy('ipam.graphql.types')]]
cables: List[Annotated["CableType", strawberry.lazy('dcim.graphql.types')]] cables: List[Annotated['CableType', strawberry.lazy('dcim.graphql.types')]]
virtual_machines: List[Annotated["VirtualMachineType", strawberry.lazy('virtualization.graphql.types')]] virtual_machines: List[Annotated['VirtualMachineType', strawberry.lazy('virtualization.graphql.types')]]
vrfs: List[Annotated["VRFType", strawberry.lazy('ipam.graphql.types')]] vrfs: List[Annotated['VRFType', strawberry.lazy('ipam.graphql.types')]]
asn_ranges: List[Annotated["ASNRangeType", strawberry.lazy('ipam.graphql.types')]] asn_ranges: List[Annotated['ASNRangeType', strawberry.lazy('ipam.graphql.types')]]
wireless_links: List[Annotated["WirelessLinkType", strawberry.lazy('wireless.graphql.types')]] wireless_links: List[Annotated['WirelessLinkType', strawberry.lazy('wireless.graphql.types')]]
aggregates: List[Annotated["AggregateType", strawberry.lazy('ipam.graphql.types')]] aggregates: List[Annotated['AggregateType', strawberry.lazy('ipam.graphql.types')]]
power_feeds: List[Annotated["PowerFeedType", strawberry.lazy('dcim.graphql.types')]] power_feeds: List[Annotated['PowerFeedType', strawberry.lazy('dcim.graphql.types')]]
devices: List[Annotated["DeviceType", strawberry.lazy('dcim.graphql.types')]] devices: List[Annotated['DeviceType', strawberry.lazy('dcim.graphql.types')]]
tunnels: List[Annotated["TunnelType", strawberry.lazy('vpn.graphql.types')]] tunnels: List[Annotated['TunnelType', strawberry.lazy('vpn.graphql.types')]]
ip_addresses: List[Annotated["IPAddressType", strawberry.lazy('ipam.graphql.types')]] ip_addresses: List[Annotated['IPAddressType', strawberry.lazy('ipam.graphql.types')]]
clusters: List[Annotated["ClusterType", strawberry.lazy('virtualization.graphql.types')]] clusters: List[Annotated['ClusterType', strawberry.lazy('virtualization.graphql.types')]]
l2vpns: List[Annotated["L2VPNType", strawberry.lazy('vpn.graphql.types')]] l2vpns: List[Annotated['L2VPNType', strawberry.lazy('vpn.graphql.types')]]
@strawberry_django.type( @strawberry_django.type(models.TenantGroup, fields='__all__', filters=TenantGroupFilter)
models.TenantGroup,
fields='__all__',
filters=TenantGroupFilter
)
class TenantGroupType(OrganizationalObjectType): class TenantGroupType(OrganizationalObjectType):
parent: Annotated["TenantGroupType", strawberry.lazy('tenancy.graphql.types')] | None parent: Annotated['TenantGroupType', strawberry.lazy('tenancy.graphql.types')] | None
tenants: List[TenantType] tenants: List[TenantType]
children: List[Annotated["TenantGroupType", strawberry.lazy('tenancy.graphql.types')]] children: List[Annotated['TenantGroupType', strawberry.lazy('tenancy.graphql.types')]]
# #
# Contacts # Contacts
# #
@strawberry_django.type(
models.Contact, @strawberry_django.type(models.Contact, fields='__all__', filters=ContactFilter)
fields='__all__',
filters=ContactFilter
)
class ContactType(ContactAssignmentsMixin, NetBoxObjectType): class ContactType(ContactAssignmentsMixin, NetBoxObjectType):
group: Annotated["ContactGroupType", strawberry.lazy('tenancy.graphql.types')] | None group: Annotated['ContactGroupType', strawberry.lazy('tenancy.graphql.types')] | None
@strawberry_django.type( @strawberry_django.type(models.ContactRole, fields='__all__', filters=ContactRoleFilter)
models.ContactRole,
fields='__all__',
filters=ContactRoleFilter
)
class ContactRoleType(ContactAssignmentsMixin, OrganizationalObjectType): class ContactRoleType(ContactAssignmentsMixin, OrganizationalObjectType):
pass pass
@strawberry_django.type( @strawberry_django.type(models.ContactGroup, fields='__all__', filters=ContactGroupFilter)
models.ContactGroup,
fields='__all__',
filters=ContactGroupFilter
)
class ContactGroupType(OrganizationalObjectType): class ContactGroupType(OrganizationalObjectType):
parent: Annotated["ContactGroupType", strawberry.lazy('tenancy.graphql.types')] | None parent: Annotated['ContactGroupType', strawberry.lazy('tenancy.graphql.types')] | None
contacts: List[ContactType] contacts: List[ContactType]
children: List[Annotated["ContactGroupType", strawberry.lazy('tenancy.graphql.types')]] children: List[Annotated['ContactGroupType', strawberry.lazy('tenancy.graphql.types')]]
@strawberry_django.type( @strawberry_django.type(models.ContactAssignment, fields='__all__', filters=ContactAssignmentFilter)
models.ContactAssignment,
fields='__all__',
filters=ContactAssignmentFilter
)
class ContactAssignmentType(CustomFieldsMixin, TagsMixin, BaseObjectType): class ContactAssignmentType(CustomFieldsMixin, TagsMixin, BaseObjectType):
object_type: Annotated["ContentTypeType", strawberry.lazy('netbox.graphql.types')] | None object_type: Annotated['ContentTypeType', strawberry.lazy('netbox.graphql.types')] | None
contact: Annotated["ContactType", strawberry.lazy('tenancy.graphql.types')] | None contact: Annotated['ContactType', strawberry.lazy('tenancy.graphql.types')] | None
role: Annotated["ContactRoleType", strawberry.lazy('tenancy.graphql.types')] | None role: Annotated['ContactRoleType', strawberry.lazy('tenancy.graphql.types')] | None

View File

@ -1,7 +1,31 @@
from datetime import datetime
from typing import Annotated, TYPE_CHECKING
import strawberry
import strawberry_django import strawberry_django
from strawberry_django import (
FilterLookup,
DatetimeFilterLookup,
)
from core.graphql.filter_mixins import *
from netbox.graphql.filter_mixins import *
from tenancy.graphql.filter_mixins import *
from netbox.graphql.filter_mixins import autotype_decorator, BaseFilterMixin from users import models
from users import filtersets, models
if TYPE_CHECKING:
from .enums import *
from netbox.graphql.enums import *
from wireless.graphql.enums import *
from core.graphql.filter_lookups import *
from extras.graphql.filters import *
from circuits.graphql.filters import *
from dcim.graphql.filters import *
from ipam.graphql.filters import *
from tenancy.graphql.filters import *
from wireless.graphql.filters import *
from users.graphql.filters import *
from virtualization.graphql.filters import *
from vpn.graphql.filters import *
__all__ = ( __all__ = (
'GroupFilter', 'GroupFilter',
@ -10,12 +34,18 @@ __all__ = (
@strawberry_django.filter(models.Group, lookups=True) @strawberry_django.filter(models.Group, lookups=True)
@autotype_decorator(filtersets.GroupFilterSet) class GroupFilter(BaseObjectTypeFilterMixin):
class GroupFilter(BaseFilterMixin): name: FilterLookup[str] | None = strawberry_django.filter_field()
pass description: FilterLookup[str] | None = strawberry_django.filter_field()
@strawberry_django.filter(models.User, lookups=True) @strawberry_django.filter(models.User, lookups=True)
@autotype_decorator(filtersets.UserFilterSet) class UserFilter(BaseObjectTypeFilterMixin):
class UserFilter(BaseFilterMixin): username: FilterLookup[str] | None = strawberry_django.filter_field()
pass first_name: FilterLookup[str] | None = strawberry_django.filter_field()
last_name: FilterLookup[str] | None = strawberry_django.filter_field()
email: FilterLookup[str] | None = strawberry_django.filter_field()
is_staff: FilterLookup[bool] | None = strawberry_django.filter_field()
is_active: FilterLookup[bool] | None = strawberry_django.filter_field()
date_joined: DatetimeFilterLookup[datetime] | None = strawberry_django.filter_field()
groups: Annotated['GroupFilter', strawberry.lazy('users.graphql.filters')] | None = strawberry_django.filter_field()

View File

@ -0,0 +1,33 @@
from enum import Enum
import strawberry
__all__ = ['ClusterStatusEnum', 'VirtualMachineStatusEnum']
#
# Clusters
#
@strawberry.enum
class ClusterStatusEnum(Enum):
STATUS_PLANNED = 'planned'
STATUS_STAGING = 'staging'
STATUS_ACTIVE = 'active'
STATUS_DECOMMISSIONING = 'decommissioning'
STATUS_OFFLINE = 'offline'
#
# VirtualMachines
#
@strawberry.enum
class VirtualMachineStatusEnum(Enum):
STATUS_OFFLINE = 'offline'
STATUS_ACTIVE = 'active'
STATUS_PLANNED = 'planned'
STATUS_STAGED = 'staged'
STATUS_FAILED = 'failed'
STATUS_DECOMMISSIONING = 'decommissioning'

View File

@ -0,0 +1,23 @@
from dataclasses import dataclass
from typing import Annotated, TYPE_CHECKING
import strawberry
from strawberry import ID
import strawberry_django
from strawberry_django import FilterLookup
from netbox.graphql.filter_mixins import NetBoxModelFilterMixin
if TYPE_CHECKING:
from .filters import *
__all__ = ['VMComponentFilterMixin']
@dataclass
class VMComponentFilterMixin(NetBoxModelFilterMixin):
virtual_manchine: Annotated['VirtualMachineFilter', strawberry.lazy('virtualization.graphql.filters')] | None = (
strawberry_django.filter_field()
)
virtual_machine_id: ID | None = strawberry_django.filter_field()
name: FilterLookup[str] | None = strawberry_django.filter_field()
description: FilterLookup[str] | None = strawberry_django.filter_field()

View File

@ -1,7 +1,33 @@
from typing import Annotated, TYPE_CHECKING
import strawberry
from strawberry.scalars import ID
import strawberry_django import strawberry_django
from strawberry_django import (
FilterLookup,
)
from core.graphql.filter_mixins import *
from netbox.graphql.filter_mixins import *
from tenancy.graphql.filter_mixins import *
from dcim.graphql.filter_mixins import *
from extras.graphql.filter_mixins import *
from virtualization.graphql.filter_mixins import *
from netbox.graphql.filter_mixins import autotype_decorator, BaseFilterMixin from virtualization import models
from virtualization import filtersets, models
if TYPE_CHECKING:
from .enums import *
from netbox.graphql.enums import *
from wireless.graphql.enums import *
from core.graphql.filter_lookups import *
from extras.graphql.filters import *
from circuits.graphql.filters import *
from dcim.graphql.filters import *
from ipam.graphql.filters import *
from tenancy.graphql.filters import *
from wireless.graphql.filters import *
from users.graphql.filters import *
from virtualization.graphql.filters import *
from vpn.graphql.filters import *
__all__ = ( __all__ = (
'ClusterFilter', 'ClusterFilter',
@ -14,36 +40,123 @@ __all__ = (
@strawberry_django.filter(models.Cluster, lookups=True) @strawberry_django.filter(models.Cluster, lookups=True)
@autotype_decorator(filtersets.ClusterFilterSet) class ClusterFilter(ContactFilterMixin, PrimaryModelFilterMixin):
class ClusterFilter(BaseFilterMixin): name: FilterLookup[str] | None = strawberry_django.filter_field()
pass type: Annotated['ClusterTypeFilter', strawberry.lazy('virtualization.graphql.filters')] | None = (
strawberry_django.filter_field()
)
type_id: ID | None = strawberry_django.filter_field()
group: Annotated['ClusterGroupFilter', strawberry.lazy('virtualization.graphql.filters')] | None = (
strawberry_django.filter_field()
)
group_id: ID | None = strawberry_django.filter_field()
status: Annotated['ClusterStatusEnum', strawberry.lazy('virtualization.graphql.enums')] | None = (
strawberry_django.filter_field()
)
tenant: Annotated['TenantFilter', strawberry.lazy('tenancy.graphql.filters')] | None = (
strawberry_django.filter_field()
)
tenant_id: ID | None = strawberry_django.filter_field()
vlan_groups: Annotated['VLANGroupFilter', strawberry.lazy('ipam.graphql.filters')] | None = (
strawberry_django.filter_field()
)
@strawberry_django.filter(models.ClusterGroup, lookups=True) @strawberry_django.filter(models.ClusterGroup, lookups=True)
@autotype_decorator(filtersets.ClusterGroupFilterSet) class ClusterGroupFilter(ContactFilterMixin, OrganizationalModelFilterMixin):
class ClusterGroupFilter(BaseFilterMixin): vlan_groups: Annotated['VLANGroupFilter', strawberry.lazy('ipam.graphql.filters')] | None = (
pass strawberry_django.filter_field()
)
@strawberry_django.filter(models.ClusterType, lookups=True) @strawberry_django.filter(models.ClusterType, lookups=True)
@autotype_decorator(filtersets.ClusterTypeFilterSet) class ClusterTypeFilter(OrganizationalModelFilterMixin):
class ClusterTypeFilter(BaseFilterMixin):
pass pass
@strawberry_django.filter(models.VirtualMachine, lookups=True) @strawberry_django.filter(models.VirtualMachine, lookups=True)
@autotype_decorator(filtersets.VirtualMachineFilterSet) class VirtualMachineFilter(
class VirtualMachineFilter(BaseFilterMixin): ContactFilterMixin,
pass ImageAttachmentFilterMixin,
RenderConfigFilterMixin,
ConfigContextFilterMixin,
PrimaryModelFilterMixin,
):
site: Annotated['SiteFilter', strawberry.lazy('dcim.graphql.filters')] | None = strawberry_django.filter_field()
site_id: ID | None = strawberry_django.filter_field()
cluster: Annotated['ClusterFilter', strawberry.lazy('virtualization.graphql.filters')] | None = (
strawberry_django.filter_field()
)
cluster_id: ID | None = strawberry_django.filter_field()
device: Annotated['DeviceFilter', strawberry.lazy('dcim.graphql.filters')] | None = strawberry_django.filter_field()
device_id: ID | None = strawberry_django.filter_field()
tenant: Annotated['TenantFilter', strawberry.lazy('tenancy.graphql.filters')] | None = (
strawberry_django.filter_field()
)
tenant_id: ID | None = strawberry_django.filter_field()
platform: Annotated['PlatformFilter', strawberry.lazy('dcim.graphql.filters')] | None = (
strawberry_django.filter_field()
)
platform_id: ID | None = strawberry_django.filter_field()
status: Annotated['VirtualMachineStatusEnum', strawberry.lazy('virtualization.graphql.enums')] | None = (
strawberry_django.filter_field()
)
role: Annotated['DeviceRoleFilter', strawberry.lazy('dcim.graphql.filters')] | None = (
strawberry_django.filter_field()
)
role_id: ID | None = strawberry_django.filter_field()
primary_ip4: Annotated['IPAddressFilter', strawberry.lazy('ipam.graphql.filters')] | None = (
strawberry_django.filter_field()
)
primary_ip4_id: ID | None = strawberry_django.filter_field()
primary_ip6: Annotated['IPAddressFilter', strawberry.lazy('ipam.graphql.filters')] | None = (
strawberry_django.filter_field()
)
primary_ip6_id: ID | None = strawberry_django.filter_field()
vcpus: Annotated['FloatLookup', strawberry.lazy('core.graphql.filter_lookups')] | None = (
strawberry_django.filter_field()
)
memory: Annotated['IntegerLookup', strawberry.lazy('core.graphql.filter_lookups')] | None = (
strawberry_django.filter_field()
)
disk: Annotated['IntegerLookup', strawberry.lazy('core.graphql.filter_lookups')] | None = (
strawberry_django.filter_field()
)
serial: FilterLookup[str] | None = strawberry_django.filter_field()
interfaces: Annotated['VMInterfaceFilter', strawberry.lazy('virtualization.graphql.filters')] | None = (
strawberry_django.filter_field()
)
services: Annotated['ServiceFilter', strawberry.lazy('ipam.graphql.filters')] | None = (
strawberry_django.filter_field()
)
virtual_disks: Annotated['VirtualDiskFilter', strawberry.lazy('virtualization.graphql.filters')] | None = (
strawberry_django.filter_field()
)
@strawberry_django.filter(models.VMInterface, lookups=True) @strawberry_django.filter(models.VMInterface, lookups=True)
@autotype_decorator(filtersets.VMInterfaceFilterSet) class VMInterfaceFilter(VMComponentFilterMixin, InterfaceBaseFilterMixin):
class VMInterfaceFilter(BaseFilterMixin): ip_addresses: Annotated['IPAddressFilter', strawberry.lazy('ipam.graphql.filters')] | None = (
pass strawberry_django.filter_field()
)
vrf: Annotated['VRFFilter', strawberry.lazy('ipam.graphql.filters')] | None = strawberry_django.filter_field()
vrf_id: ID | None = strawberry_django.filter_field()
fhrp_group_assignments: Annotated['FHRPGroupAssignmentFilter', strawberry.lazy('ipam.graphql.filters')] | None = (
strawberry_django.filter_field()
)
tunnel_terminations: Annotated['TunnelTerminationFilter', strawberry.lazy('vpn.graphql.filters')] | None = (
strawberry_django.filter_field()
)
l2vpn_terminations: Annotated['L2VPNFilter', strawberry.lazy('vpn.graphql.filters')] | None = (
strawberry_django.filter_field()
)
mac_addresses: Annotated['MACAddressFilter', strawberry.lazy('dcim.graphql.filters')] | None = (
strawberry_django.filter_field()
)
@strawberry_django.filter(models.VirtualDisk, lookups=True) @strawberry_django.filter(models.VirtualDisk, lookups=True)
@autotype_decorator(filtersets.VirtualDiskFilterSet) class VirtualDiskFilter(VMComponentFilterMixin):
class VirtualDiskFilter(BaseFilterMixin): size: Annotated['IntegerLookup', strawberry.lazy('core.graphql.filter_lookups')] | None = (
pass strawberry_django.filter_field()
)

161
netbox/vpn/graphql/enums.py Normal file
View File

@ -0,0 +1,161 @@
from enum import Enum
import strawberry
__all__ = [
'TunnelStatusEnum',
'TunnelEncapsulationEnum',
'TunnelTerminationTypeEnum',
'TunnelTerminationRoleEnum',
'IKEVersionEnum',
'IKEModeEnum',
'AuthenticationMethodEnum',
'IPSecModeEnum',
'EncryptionAlgorithmEnum',
'AuthenticationAlgorithmEnum',
'DHGroupEnum',
'L2VPNTypeEnum',
]
#
# Tunnels
#
@strawberry.enum
class TunnelStatusEnum(Enum):
key = 'Tunnel.status'
STATUS_PLANNED = 'planned'
STATUS_ACTIVE = 'active'
STATUS_DISABLED = 'disabled'
@strawberry.enum
class TunnelEncapsulationEnum(Enum):
ENCAP_GRE = 'gre'
ENCAP_IPSEC_TRANSPORT = 'ipsec-transport'
ENCAP_IPSEC_TUNNEL = 'ipsec-tunnel'
ENCAP_IP_IP = 'ip-ip'
ENCAP_L2TP = 'l2tp'
ENCAP_OPENVPN = 'openvpn'
ENCAP_PPTP = 'pptp'
ENCAP_WIREGUARD = 'wireguard'
@strawberry.enum
class TunnelTerminationTypeEnum(Enum):
# For TunnelCreateForm
TYPE_DEVICE = 'dcim.device'
TYPE_VIRTUALMACHINE = 'virtualization.virtualmachine'
@strawberry.enum
class TunnelTerminationRoleEnum(Enum):
ROLE_PEER = 'peer'
ROLE_HUB = 'hub'
ROLE_SPOKE = 'spoke'
#
# Crypto
#
@strawberry.enum
class IKEVersionEnum(Enum):
VERSION_1 = 1
VERSION_2 = 2
@strawberry.enum
class IKEModeEnum(Enum):
AGGRESSIVE = 'aggressive'
MAIN = 'main'
@strawberry.enum
class AuthenticationMethodEnum(Enum):
PRESHARED_KEYS = 'preshared-keys'
CERTIFICATES = 'certificates'
RSA_SIGNATURES = 'rsa-signatures'
DSA_SIGNATURES = 'dsa-signatures'
@strawberry.enum
class IPSecModeEnum(Enum):
ESP = 'esp'
AH = 'ah'
@strawberry.enum
class EncryptionAlgorithmEnum(Enum):
ENCRYPTION_AES128_CBC = 'aes-128-cbc'
ENCRYPTION_AES128_GCM = 'aes-128-gcm'
ENCRYPTION_AES192_CBC = 'aes-192-cbc'
ENCRYPTION_AES192_GCM = 'aes-192-gcm'
ENCRYPTION_AES256_CBC = 'aes-256-cbc'
ENCRYPTION_AES256_GCM = 'aes-256-gcm'
ENCRYPTION_3DES = '3des-cbc'
ENCRYPTION_DES = 'des-cbc'
@strawberry.enum
class AuthenticationAlgorithmEnum(Enum):
AUTH_HMAC_SHA1 = 'hmac-sha1'
AUTH_HMAC_SHA256 = 'hmac-sha256'
AUTH_HMAC_SHA384 = 'hmac-sha384'
AUTH_HMAC_SHA512 = 'hmac-sha512'
AUTH_HMAC_MD5 = 'hmac-md5'
@strawberry.enum
class DHGroupEnum(Enum):
# https://www.iana.org/assignments/ikev2-parameters/ikev2-parameters.xhtml#ikev2-parameters-8
GROUP_1 = 1 # 768-bit MODP
GROUP_2 = 2 # 1024-but MODP
# Groups 3-4 reserved
GROUP_5 = 5 # 1536-bit MODP
# Groups 6-13 unassigned
GROUP_14 = 14 # 2048-bit MODP
GROUP_15 = 15 # 3072-bit MODP
GROUP_16 = 16 # 4096-bit MODP
GROUP_17 = 17 # 6144-bit MODP
GROUP_18 = 18 # 8192-bit MODP
GROUP_19 = 19 # 256-bit random ECP
GROUP_20 = 20 # 384-bit random ECP
GROUP_21 = 21 # 521-bit random ECP (521 is not a typo)
GROUP_22 = 22 # 1024-bit MODP w/160-bit prime
GROUP_23 = 23 # 2048-bit MODP w/224-bit prime
GROUP_24 = 24 # 2048-bit MODP w/256-bit prime
GROUP_25 = 25 # 192-bit ECP
GROUP_26 = 26 # 224-bit ECP
GROUP_27 = 27 # brainpoolP224r1
GROUP_28 = 28 # brainpoolP256r1
GROUP_29 = 29 # brainpoolP384r1
GROUP_30 = 30 # brainpoolP512r1
GROUP_31 = 31 # Curve25519
GROUP_32 = 32 # Curve448
GROUP_33 = 33 # GOST3410_2012_256
GROUP_34 = 34 # GOST3410_2012_512
#
# L2VPN
#
@strawberry.enum
class L2VPNTypeEnum(Enum):
TYPE_VPLS = 'vpls'
TYPE_VPWS = 'vpws'
TYPE_EPL = 'epl'
TYPE_EVPL = 'evpl'
TYPE_EPLAN = 'ep-lan'
TYPE_EVPLAN = 'evp-lan'
TYPE_EPTREE = 'ep-tree'
TYPE_EVPTREE = 'evp-tree'
TYPE_VXLAN = 'vxlan'
TYPE_VXLAN_EVPN = 'vxlan-evpn'
TYPE_MPLS_EVPN = 'mpls-evpn'
TYPE_PBB_EVPN = 'pbb-evpn'
TYPE_EVPN_VPWS = 'evpn-vpws'

View File

@ -1,7 +1,34 @@
from typing import Annotated, TYPE_CHECKING
import strawberry
from strawberry.scalars import ID
import strawberry_django import strawberry_django
from strawberry_django import (
FilterLookup,
)
from extras.graphql.filter_mixins import *
from netbox.graphql.filter_mixins import *
from core.graphql.filter_mixins import *
from tenancy.graphql.filter_mixins import *
# from .filter_mixins import *
from vpn import models
if TYPE_CHECKING:
from .enums import *
from netbox.graphql.enums import *
from wireless.graphql.enums import *
from core.graphql.filter_lookups import *
from core.graphql.filters import *
from extras.graphql.filters import *
from circuits.graphql.filters import *
from dcim.graphql.filters import *
from ipam.graphql.filters import *
from tenancy.graphql.filters import *
from wireless.graphql.filters import *
from users.graphql.filters import *
from virtualization.graphql.filters import *
from vpn.graphql.filters import *
from netbox.graphql.filter_mixins import autotype_decorator, BaseFilterMixin
from vpn import filtersets, models
__all__ = ( __all__ = (
'TunnelGroupFilter', 'TunnelGroupFilter',
@ -18,60 +45,151 @@ __all__ = (
@strawberry_django.filter(models.TunnelGroup, lookups=True) @strawberry_django.filter(models.TunnelGroup, lookups=True)
@autotype_decorator(filtersets.TunnelGroupFilterSet) class TunnelGroupFilter(OrganizationalModelFilterMixin):
class TunnelGroupFilter(BaseFilterMixin):
pass pass
@strawberry_django.filter(models.TunnelTermination, lookups=True) @strawberry_django.filter(models.TunnelTermination, lookups=True)
@autotype_decorator(filtersets.TunnelTerminationFilterSet) class TunnelTerminationFilter(
class TunnelTerminationFilter(BaseFilterMixin): BaseObjectTypeFilterMixin, CustomFieldsFilterMixin, TagsFilterMixin, ChangeLogFilterMixin
pass ):
tunnel: Annotated['TunnelFilter', strawberry.lazy('vpn.graphql.filters')] | None = strawberry_django.filter_field()
tunnel_id: ID | None = strawberry_django.filter_field()
role: Annotated['TunnelTerminationRoleEnum', strawberry.lazy('vpn.graphql.enums')] | None = (
strawberry_django.filter_field()
)
termination_type: Annotated['TunnelTerminationTypeEnum', strawberry.lazy('vpn.graphql.enums')] | None = (
strawberry_django.filter_field()
)
termination_type_id: ID | None = strawberry_django.filter_field()
termination_id: ID | None = strawberry_django.filter_field()
outside_ip: Annotated['IPAddressFilter', strawberry.lazy('ipam.graphql.filters')] | None = (
strawberry_django.filter_field()
)
outside_ip_id: ID | None = strawberry_django.filter_field()
@strawberry_django.filter(models.Tunnel, lookups=True) @strawberry_django.filter(models.Tunnel, lookups=True)
@autotype_decorator(filtersets.TunnelFilterSet) class TunnelFilter(PrimaryModelFilterMixin):
class TunnelFilter(BaseFilterMixin): name: FilterLookup[str] | None = strawberry_django.filter_field()
pass status: Annotated['TunnelStatusEnum', strawberry.lazy('vpn.graphql.enums')] | None = (
strawberry_django.filter_field()
)
group: Annotated['TunnelGroupFilter', strawberry.lazy('vpn.graphql.filters')] | None = (
strawberry_django.filter_field()
)
group_id: ID | None = strawberry_django.filter_field()
encapsulation: Annotated['TunnelEncapsulationEnum', strawberry.lazy('vpn.graphql.enums')] | None = (
strawberry_django.filter_field()
)
ipsec_profile: Annotated['IPSecProfileFilter', strawberry.lazy('vpn.graphql.filters')] | None = (
strawberry_django.filter_field()
)
tenant: Annotated['TenantFilter', strawberry.lazy('tenancy.graphql.filters')] | None = (
strawberry_django.filter_field()
)
tenant_id: ID | None = strawberry_django.filter_field()
tunnel_id: Annotated['IntegerLookup', strawberry.lazy('core.graphql.filter_lookups')] | None = (
strawberry_django.filter_field()
)
@strawberry_django.filter(models.IKEProposal, lookups=True) @strawberry_django.filter(models.IKEProposal, lookups=True)
@autotype_decorator(filtersets.IKEProposalFilterSet) class IKEProposalFilter(PrimaryModelFilterMixin):
class IKEProposalFilter(BaseFilterMixin): name: FilterLookup[str] | None = strawberry_django.filter_field()
pass authentication_method: Annotated['AuthenticationMethodEnum', strawberry.lazy('vpn.graphql.enums')] | None = (
strawberry_django.filter_field()
)
encryption_algorithm: Annotated['EncryptionAlgorithmEnum', strawberry.lazy('vpn.graphql.enums')] | None = (
strawberry_django.filter_field()
)
authentication_algorithm: Annotated['AuthenticationAlgorithmEnum', strawberry.lazy('vpn.graphql.enums')] | None = (
strawberry_django.filter_field()
)
group: Annotated['DHGroupEnum', strawberry.lazy('vpn.graphql.enums')] | None = strawberry_django.filter_field()
sa_lifetime: Annotated['IntegerLookup', strawberry.lazy('core.graphql.filter_lookups')] | None = (
strawberry_django.filter_field()
)
@strawberry_django.filter(models.IKEPolicy, lookups=True) @strawberry_django.filter(models.IKEPolicy, lookups=True)
@autotype_decorator(filtersets.IKEPolicyFilterSet) class IKEPolicyFilter(PrimaryModelFilterMixin):
class IKEPolicyFilter(BaseFilterMixin): name: FilterLookup[str] | None = strawberry_django.filter_field()
pass version: Annotated['IKEVersionEnum', strawberry.lazy('vpn.graphql.enums')] | None = strawberry_django.filter_field()
mode: Annotated['IKEModeEnum', strawberry.lazy('vpn.graphql.enums')] | None = strawberry_django.filter_field()
proposals: Annotated['IKEProposalFilter', strawberry.lazy('vpn.graphql.filters')] | None = (
strawberry_django.filter_field()
)
preshared_key: FilterLookup[str] | None = strawberry_django.filter_field()
@strawberry_django.filter(models.IPSecProposal, lookups=True) @strawberry_django.filter(models.IPSecProposal, lookups=True)
@autotype_decorator(filtersets.IPSecProposalFilterSet) class IPSecProposalFilter(PrimaryModelFilterMixin):
class IPSecProposalFilter(BaseFilterMixin): name: FilterLookup[str] | None = strawberry_django.filter_field()
pass encryption_algorithm: Annotated['EncryptionAlgorithmEnum', strawberry.lazy('vpn.graphql.enums')] | None = (
strawberry_django.filter_field()
)
authentication_algorithm: Annotated['AuthenticationAlgorithmEnum', strawberry.lazy('vpn.graphql.enums')] | None = (
strawberry_django.filter_field()
)
sa_lifetime_seconds: Annotated['IntegerLookup', strawberry.lazy('core.graphql.filter_lookups')] | None = (
strawberry_django.filter_field()
)
sa_lifetime_data: Annotated['IntegerLookup', strawberry.lazy('core.graphql.filter_lookups')] | None = (
strawberry_django.filter_field()
)
@strawberry_django.filter(models.IPSecPolicy, lookups=True) @strawberry_django.filter(models.IPSecPolicy, lookups=True)
@autotype_decorator(filtersets.IPSecPolicyFilterSet) class IPSecPolicyFilter(PrimaryModelFilterMixin):
class IPSecPolicyFilter(BaseFilterMixin): name: FilterLookup[str] | None = strawberry_django.filter_field()
pass proposals: Annotated['IPSecProposalFilter', strawberry.lazy('vpn.graphql.filters')] | None = (
strawberry_django.filter_field()
)
pfs_group: Annotated['DHGroupEnum', strawberry.lazy('vpn.graphql.enums')] | None = strawberry_django.filter_field()
@strawberry_django.filter(models.IPSecProfile, lookups=True) @strawberry_django.filter(models.IPSecProfile, lookups=True)
@autotype_decorator(filtersets.IPSecProfileFilterSet) class IPSecProfileFilter(PrimaryModelFilterMixin):
class IPSecProfileFilter(BaseFilterMixin): name: FilterLookup[str] | None = strawberry_django.filter_field()
pass mode: Annotated['IPSecModeEnum', strawberry.lazy('vpn.graphql.enums')] | None = strawberry_django.filter_field()
ike_policy: Annotated['IKEPolicyFilter', strawberry.lazy('vpn.graphql.filters')] | None = (
strawberry_django.filter_field()
)
ike_policy_id: ID | None = strawberry_django.filter_field()
ipsec_policy: Annotated['IPSecPolicyFilter', strawberry.lazy('vpn.graphql.filters')] | None = (
strawberry_django.filter_field()
)
ipsec_policy_id: ID | None = strawberry_django.filter_field()
@strawberry_django.filter(models.L2VPN, lookups=True) @strawberry_django.filter(models.L2VPN, lookups=True)
@autotype_decorator(filtersets.L2VPNFilterSet) class L2VPNFilter(ContactFilterMixin, PrimaryModelFilterMixin):
class L2VPNFilter(BaseFilterMixin): name: FilterLookup[str] | None = strawberry_django.filter_field()
pass slug: FilterLookup[str] | None = strawberry_django.filter_field()
type: Annotated['L2VPNTypeEnum', strawberry.lazy('vpn.graphql.enums')] | None = strawberry_django.filter_field()
identifier: Annotated['IntegerLookup', strawberry.lazy('core.graphql.filter_lookups')] | None = (
strawberry_django.filter_field()
)
import_targets: Annotated['RouteTargetFilter', strawberry.lazy('ipam.graphql.filters')] | None = (
strawberry_django.filter_field()
)
export_targets: Annotated['RouteTargetFilter', strawberry.lazy('ipam.graphql.filters')] | None = (
strawberry_django.filter_field()
)
tenant: Annotated['TenantFilter', strawberry.lazy('tenancy.graphql.filters')] | None = (
strawberry_django.filter_field()
)
tenant_id: ID | None = strawberry_django.filter_field()
@strawberry_django.filter(models.L2VPNTermination, lookups=True) @strawberry_django.filter(models.L2VPNTermination, lookups=True)
@autotype_decorator(filtersets.L2VPNTerminationFilterSet) class L2VPNTerminationFilter(NetBoxModelFilterMixin):
class L2VPNTerminationFilter(BaseFilterMixin): l2vpn: Annotated['L2VPNFilter', strawberry.lazy('vpn.graphql.filters')] | None = strawberry_django.filter_field()
pass l2vpn_id: ID | None = strawberry_django.filter_field()
assigned_object_type: Annotated['ContentTypeFilter', strawberry.lazy('core.graphql.filters')] | None = (
strawberry_django.filter_field()
)
assigned_object_id: Annotated['IntegerLookup', strawberry.lazy('core.graphql.filter_lookups')] | None = (
strawberry_django.filter_field()
)

View File

@ -0,0 +1,249 @@
from enum import Enum
import strawberry
__all__ = [
'WirelessRoleEnum',
'WirelessLANStatusEnum',
'WirelessChannelEnum',
'WirelessAuthTypeEnum',
'WirelessAuthCipherEnum',
]
@strawberry.enum
class WirelessRoleEnum(Enum):
ROLE_AP = 'ap'
ROLE_STATION = 'station'
@strawberry.enum
class WirelessLANStatusEnum(Enum):
key = 'WirelessLAN.status'
STATUS_ACTIVE = 'active'
STATUS_RESERVED = 'reserved'
STATUS_DISABLED = 'disabled'
STATUS_DEPRECATED = 'deprecated'
@strawberry.enum
class WirelessChannelEnum(Enum):
# 2.4 GHz
CHANNEL_24G_1 = '2.4g-1-2412-22'
CHANNEL_24G_2 = '2.4g-2-2417-22'
CHANNEL_24G_3 = '2.4g-3-2422-22'
CHANNEL_24G_4 = '2.4g-4-2427-22'
CHANNEL_24G_5 = '2.4g-5-2432-22'
CHANNEL_24G_6 = '2.4g-6-2437-22'
CHANNEL_24G_7 = '2.4g-7-2442-22'
CHANNEL_24G_8 = '2.4g-8-2447-22'
CHANNEL_24G_9 = '2.4g-9-2452-22'
CHANNEL_24G_10 = '2.4g-10-2457-22'
CHANNEL_24G_11 = '2.4g-11-2462-22'
CHANNEL_24G_12 = '2.4g-12-2467-22'
CHANNEL_24G_13 = '2.4g-13-2472-22'
# 5 GHz
CHANNEL_5G_32 = '5g-32-5160-20'
CHANNEL_5G_34 = '5g-34-5170-40'
CHANNEL_5G_36 = '5g-36-5180-20'
CHANNEL_5G_38 = '5g-38-5190-40'
CHANNEL_5G_40 = '5g-40-5200-20'
CHANNEL_5G_42 = '5g-42-5210-80'
CHANNEL_5G_44 = '5g-44-5220-20'
CHANNEL_5G_46 = '5g-46-5230-40'
CHANNEL_5G_48 = '5g-48-5240-20'
CHANNEL_5G_50 = '5g-50-5250-160'
CHANNEL_5G_52 = '5g-52-5260-20'
CHANNEL_5G_54 = '5g-54-5270-40'
CHANNEL_5G_56 = '5g-56-5280-20'
CHANNEL_5G_58 = '5g-58-5290-80'
CHANNEL_5G_60 = '5g-60-5300-20'
CHANNEL_5G_62 = '5g-62-5310-40'
CHANNEL_5G_64 = '5g-64-5320-20'
CHANNEL_5G_100 = '5g-100-5500-20'
CHANNEL_5G_102 = '5g-102-5510-40'
CHANNEL_5G_104 = '5g-104-5520-20'
CHANNEL_5G_106 = '5g-106-5530-80'
CHANNEL_5G_108 = '5g-108-5540-20'
CHANNEL_5G_110 = '5g-110-5550-40'
CHANNEL_5G_112 = '5g-112-5560-20'
CHANNEL_5G_114 = '5g-114-5570-160'
CHANNEL_5G_116 = '5g-116-5580-20'
CHANNEL_5G_118 = '5g-118-5590-40'
CHANNEL_5G_120 = '5g-120-5600-20'
CHANNEL_5G_122 = '5g-122-5610-80'
CHANNEL_5G_124 = '5g-124-5620-20'
CHANNEL_5G_126 = '5g-126-5630-40'
CHANNEL_5G_128 = '5g-128-5640-20'
CHANNEL_5G_132 = '5g-132-5660-20'
CHANNEL_5G_134 = '5g-134-5670-40'
CHANNEL_5G_136 = '5g-136-5680-20'
CHANNEL_5G_138 = '5g-138-5690-80'
CHANNEL_5G_140 = '5g-140-5700-20'
CHANNEL_5G_142 = '5g-142-5710-40'
CHANNEL_5G_144 = '5g-144-5720-20'
CHANNEL_5G_149 = '5g-149-5745-20'
CHANNEL_5G_151 = '5g-151-5755-40'
CHANNEL_5G_153 = '5g-153-5765-20'
CHANNEL_5G_155 = '5g-155-5775-80'
CHANNEL_5G_157 = '5g-157-5785-20'
CHANNEL_5G_159 = '5g-159-5795-40'
CHANNEL_5G_161 = '5g-161-5805-20'
CHANNEL_5G_163 = '5g-163-5815-160'
CHANNEL_5G_165 = '5g-165-5825-20'
CHANNEL_5G_167 = '5g-167-5835-40'
CHANNEL_5G_169 = '5g-169-5845-20'
CHANNEL_5G_171 = '5g-171-5855-80'
CHANNEL_5G_173 = '5g-173-5865-20'
CHANNEL_5G_175 = '5g-175-5875-40'
CHANNEL_5G_177 = '5g-177-5885-20'
# 6 GHz
CHANNEL_6G_1 = '6g-1-5955-20'
CHANNEL_6G_3 = '6g-3-5965-40'
CHANNEL_6G_5 = '6g-5-5975-20'
CHANNEL_6G_7 = '6g-7-5985-80'
CHANNEL_6G_9 = '6g-9-5995-20'
CHANNEL_6G_11 = '6g-11-6005-40'
CHANNEL_6G_13 = '6g-13-6015-20'
CHANNEL_6G_15 = '6g-15-6025-160'
CHANNEL_6G_17 = '6g-17-6035-20'
CHANNEL_6G_19 = '6g-19-6045-40'
CHANNEL_6G_21 = '6g-21-6055-20'
CHANNEL_6G_23 = '6g-23-6065-80'
CHANNEL_6G_25 = '6g-25-6075-20'
CHANNEL_6G_27 = '6g-27-6085-40'
CHANNEL_6G_29 = '6g-29-6095-20'
CHANNEL_6G_31 = '6g-31-6105-320'
CHANNEL_6G_33 = '6g-33-6115-20'
CHANNEL_6G_35 = '6g-35-6125-40'
CHANNEL_6G_37 = '6g-37-6135-20'
CHANNEL_6G_39 = '6g-39-6145-80'
CHANNEL_6G_41 = '6g-41-6155-20'
CHANNEL_6G_43 = '6g-43-6165-40'
CHANNEL_6G_45 = '6g-45-6175-20'
CHANNEL_6G_47 = '6g-47-6185-160'
CHANNEL_6G_49 = '6g-49-6195-20'
CHANNEL_6G_51 = '6g-51-6205-40'
CHANNEL_6G_53 = '6g-53-6215-20'
CHANNEL_6G_55 = '6g-55-6225-80'
CHANNEL_6G_57 = '6g-57-6235-20'
CHANNEL_6G_59 = '6g-59-6245-40'
CHANNEL_6G_61 = '6g-61-6255-20'
CHANNEL_6G_65 = '6g-65-6275-20'
CHANNEL_6G_67 = '6g-67-6285-40'
CHANNEL_6G_69 = '6g-69-6295-20'
CHANNEL_6G_71 = '6g-71-6305-80'
CHANNEL_6G_73 = '6g-73-6315-20'
CHANNEL_6G_75 = '6g-75-6325-40'
CHANNEL_6G_77 = '6g-77-6335-20'
CHANNEL_6G_79 = '6g-79-6345-160'
CHANNEL_6G_81 = '6g-81-6355-20'
CHANNEL_6G_83 = '6g-83-6365-40'
CHANNEL_6G_85 = '6g-85-6375-20'
CHANNEL_6G_87 = '6g-87-6385-80'
CHANNEL_6G_89 = '6g-89-6395-20'
CHANNEL_6G_91 = '6g-91-6405-40'
CHANNEL_6G_93 = '6g-93-6415-20'
CHANNEL_6G_95 = '6g-95-6425-320'
CHANNEL_6G_97 = '6g-97-6435-20'
CHANNEL_6G_99 = '6g-99-6445-40'
CHANNEL_6G_101 = '6g-101-6455-20'
CHANNEL_6G_103 = '6g-103-6465-80'
CHANNEL_6G_105 = '6g-105-6475-20'
CHANNEL_6G_107 = '6g-107-6485-40'
CHANNEL_6G_109 = '6g-109-6495-20'
CHANNEL_6G_111 = '6g-111-6505-160'
CHANNEL_6G_113 = '6g-113-6515-20'
CHANNEL_6G_115 = '6g-115-6525-40'
CHANNEL_6G_117 = '6g-117-6535-20'
CHANNEL_6G_119 = '6g-119-6545-80'
CHANNEL_6G_121 = '6g-121-6555-20'
CHANNEL_6G_123 = '6g-123-6565-40'
CHANNEL_6G_125 = '6g-125-6575-20'
CHANNEL_6G_129 = '6g-129-6595-20'
CHANNEL_6G_131 = '6g-131-6605-40'
CHANNEL_6G_133 = '6g-133-6615-20'
CHANNEL_6G_135 = '6g-135-6625-80'
CHANNEL_6G_137 = '6g-137-6635-20'
CHANNEL_6G_139 = '6g-139-6645-40'
CHANNEL_6G_141 = '6g-141-6655-20'
CHANNEL_6G_143 = '6g-143-6665-160'
CHANNEL_6G_145 = '6g-145-6675-20'
CHANNEL_6G_147 = '6g-147-6685-40'
CHANNEL_6G_149 = '6g-149-6695-20'
CHANNEL_6G_151 = '6g-151-6705-80'
CHANNEL_6G_153 = '6g-153-6715-20'
CHANNEL_6G_155 = '6g-155-6725-40'
CHANNEL_6G_157 = '6g-157-6735-20'
CHANNEL_6G_159 = '6g-159-6745-320'
CHANNEL_6G_161 = '6g-161-6755-20'
CHANNEL_6G_163 = '6g-163-6765-40'
CHANNEL_6G_165 = '6g-165-6775-20'
CHANNEL_6G_167 = '6g-167-6785-80'
CHANNEL_6G_169 = '6g-169-6795-20'
CHANNEL_6G_171 = '6g-171-6805-40'
CHANNEL_6G_173 = '6g-173-6815-20'
CHANNEL_6G_175 = '6g-175-6825-160'
CHANNEL_6G_177 = '6g-177-6835-20'
CHANNEL_6G_179 = '6g-179-6845-40'
CHANNEL_6G_181 = '6g-181-6855-20'
CHANNEL_6G_183 = '6g-183-6865-80'
CHANNEL_6G_185 = '6g-185-6875-20'
CHANNEL_6G_187 = '6g-187-6885-40'
CHANNEL_6G_189 = '6g-189-6895-20'
CHANNEL_6G_193 = '6g-193-6915-20'
CHANNEL_6G_195 = '6g-195-6925-40'
CHANNEL_6G_197 = '6g-197-6935-20'
CHANNEL_6G_199 = '6g-199-6945-80'
CHANNEL_6G_201 = '6g-201-6955-20'
CHANNEL_6G_203 = '6g-203-6965-40'
CHANNEL_6G_205 = '6g-205-6975-20'
CHANNEL_6G_207 = '6g-207-6985-160'
CHANNEL_6G_209 = '6g-209-6995-20'
CHANNEL_6G_211 = '6g-211-7005-40'
CHANNEL_6G_213 = '6g-213-7015-20'
CHANNEL_6G_215 = '6g-215-7025-80'
CHANNEL_6G_217 = '6g-217-7035-20'
CHANNEL_6G_219 = '6g-219-7045-40'
CHANNEL_6G_221 = '6g-221-7055-20'
CHANNEL_6G_225 = '6g-225-7075-20'
CHANNEL_6G_227 = '6g-227-7085-40'
CHANNEL_6G_229 = '6g-229-7095-20'
CHANNEL_6G_233 = '6g-233-7115-20'
# 60 GHz
CHANNEL_60G_1 = '60g-1-58320-2160'
CHANNEL_60G_2 = '60g-2-60480-2160'
CHANNEL_60G_3 = '60g-3-62640-2160'
CHANNEL_60G_4 = '60g-4-64800-2160'
CHANNEL_60G_5 = '60g-5-66960-2160'
CHANNEL_60G_6 = '60g-6-69120-2160'
CHANNEL_60G_9 = '60g-9-59400-4320'
CHANNEL_60G_10 = '60g-10-61560-4320'
CHANNEL_60G_11 = '60g-11-63720-4320'
CHANNEL_60G_12 = '60g-12-65880-4320'
CHANNEL_60G_13 = '60g-13-68040-4320'
CHANNEL_60G_17 = '60g-17-60480-6480'
CHANNEL_60G_18 = '60g-18-62640-6480'
CHANNEL_60G_19 = '60g-19-64800-6480'
CHANNEL_60G_20 = '60g-20-66960-6480'
CHANNEL_60G_25 = '60g-25-61560-6480'
CHANNEL_60G_26 = '60g-26-63720-6480'
CHANNEL_60G_27 = '60g-27-65880-6480'
@strawberry.enum
class WirelessAuthTypeEnum(Enum):
TYPE_OPEN = 'open'
TYPE_WEP = 'wep'
TYPE_WPA_PERSONAL = 'wpa-personal'
TYPE_WPA_ENTERPRISE = 'wpa-enterprise'
@strawberry.enum
class WirelessAuthCipherEnum(Enum):
CIPHER_AUTO = 'auto'
CIPHER_TKIP = 'tkip'
CIPHER_AES = 'aes'

View File

@ -0,0 +1,24 @@
from dataclasses import dataclass
from typing import Annotated, TYPE_CHECKING
import strawberry
import strawberry_django
from strawberry_django import FilterLookup
from core.graphql.filter_mixins import BaseFilterMixin
if TYPE_CHECKING:
from .filters import *
from .enums import *
__all__ = ['WirelessAuthenticationBaseFilterMixin']
@dataclass
class WirelessAuthenticationBaseFilterMixin(BaseFilterMixin):
auth_type: Annotated['WirelessAuthTypeEnum', strawberry.lazy('wireless.graphql.enums')] | None = (
strawberry_django.filter_field()
)
auth_cipher: Annotated['WirelessAuthCipherEnum', strawberry.lazy('wireless.graphql.enums')] | None = (
strawberry_django.filter_field()
)
auth_psk: FilterLookup[str] | None = strawberry_django.filter_field()

View File

@ -1,7 +1,32 @@
from typing import Annotated, TYPE_CHECKING
import strawberry
from strawberry.scalars import ID
import strawberry_django import strawberry_django
from strawberry_django import (
FilterLookup,
)
from extras.graphql.filter_mixins import *
from netbox.graphql.filter_mixins import *
from core.graphql.filter_mixins import *
from tenancy.graphql.filter_mixins import *
from .filter_mixins import *
from netbox.graphql.filter_mixins import autotype_decorator, BaseFilterMixin from wireless import models
from wireless import filtersets, models
if TYPE_CHECKING:
from .enums import *
from netbox.graphql.enums import *
from wireless.graphql.enums import *
from core.graphql.filter_lookups import *
from extras.graphql.filters import *
from circuits.graphql.filters import *
from dcim.graphql.filters import *
from ipam.graphql.filters import *
from tenancy.graphql.filters import *
from wireless.graphql.filters import *
from users.graphql.filters import *
from virtualization.graphql.filters import *
from vpn.graphql.filters import *
__all__ = ( __all__ = (
'WirelessLANGroupFilter', 'WirelessLANGroupFilter',
@ -11,18 +36,40 @@ __all__ = (
@strawberry_django.filter(models.WirelessLANGroup, lookups=True) @strawberry_django.filter(models.WirelessLANGroup, lookups=True)
@autotype_decorator(filtersets.WirelessLANGroupFilterSet) class WirelessLANGroupFilter(NestedGroupModelFilterMixin):
class WirelessLANGroupFilter(BaseFilterMixin):
pass pass
@strawberry_django.filter(models.WirelessLAN, lookups=True) @strawberry_django.filter(models.WirelessLAN, lookups=True)
@autotype_decorator(filtersets.WirelessLANFilterSet) class WirelessLANFilter(WirelessAuthenticationBaseFilterMixin, PrimaryModelFilterMixin):
class WirelessLANFilter(BaseFilterMixin): ssid: FilterLookup[str] | None = strawberry_django.filter_field()
pass group: Annotated['WirelessLANGroupFilter', strawberry.lazy('wireless.graphql.filters')] | None = (
strawberry_django.filter_field()
)
group_id: ID | None = strawberry_django.filter_field()
vlan: Annotated['VLANFilter', strawberry.lazy('ipam.graphql.filters')] | None = strawberry_django.filter_field()
vlan_id: ID | None = strawberry_django.filter_field()
tenant: Annotated['TenantFilter', strawberry.lazy('tenancy.graphql.filters')] | None = (
strawberry_django.filter_field()
)
tenant_id: ID | None = strawberry_django.filter_field()
@strawberry_django.filter(models.WirelessLink, lookups=True) @strawberry_django.filter(models.WirelessLink, lookups=True)
@autotype_decorator(filtersets.WirelessLinkFilterSet) class WirelessLinkFilter(WirelessAuthenticationBaseFilterMixin, DistanceFilterMixin, PrimaryModelFilterMixin):
class WirelessLinkFilter(BaseFilterMixin): interface_a: Annotated['InterfaceFilter', strawberry.lazy('dcim.graphql.filters')] | None = (
pass strawberry_django.filter_field()
)
interface_a_id: ID | None = strawberry_django.filter_field()
interface_b: Annotated['InterfaceFilter', strawberry.lazy('dcim.graphql.filters')] | None = (
strawberry_django.filter_field()
)
interface_b_id: ID | None = strawberry_django.filter_field()
ssid: FilterLookup[str] | None = strawberry_django.filter_field()
status: Annotated['WirelessLANStatusEnum', strawberry.lazy('wireless.graphql.enums')] | None = (
strawberry_django.filter_field()
)
tenant: Annotated['TenantFilter', strawberry.lazy('tenancy.graphql.filters')] | None = (
strawberry_django.filter_field()
)
tenant_id: ID | None = strawberry_django.filter_field()