mirror of
https://github.com/netbox-community/netbox.git
synced 2025-07-14 01:41:22 -06:00
parent
bbf4eea76c
commit
c35f5f829a
@ -76,11 +76,13 @@ Create the following for each model:
|
||||
|
||||
## 13. GraphQL API components
|
||||
|
||||
Create a GraphQL object type for the model in `graphql/types.py` by subclassing the appropriate class from `netbox.graphql.types`.
|
||||
Create the following for each model:
|
||||
|
||||
**Note:** GraphQL unit tests may fail citing null values on a non-nullable field if related objects are prefetched. You may need to fix this by setting the type annotation to be `= strawberry_django.field(select_related=["policy"])` or similar.
|
||||
* GraphQL object type for the model in `graphql/types.py` (subclass the appropriate class from `netbox.graphql.types`)
|
||||
* Add a GraphQL filter for the model in `graphql/filters.py`
|
||||
* Extend the query class for the app in `graphql/schema.py` with the individual object and object list fields
|
||||
|
||||
Also extend the schema class defined in `graphql/schema.py` with the individual object and object list fields per the established convention.
|
||||
**Note:** GraphQL unit tests may fail citing null values on a non-nullable field if related objects are prefetched. You may need to fix this by setting the type annotation to be `= strawberry_django.field(select_related=["foo"])` or similar.
|
||||
|
||||
## 14. Add tests
|
||||
|
||||
|
@ -11,7 +11,7 @@ curl -H "Authorization: Token $TOKEN" \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "Accept: application/json" \
|
||||
http://netbox/graphql/ \
|
||||
--data '{"query": "query {circuit_list(status:\"active\") {cid provider {name}}}"}'
|
||||
--data '{"query": "query {circuit_list(filters:{status: STATUS_ACTIVE}) {cid provider {name}}}"}'
|
||||
```
|
||||
|
||||
The response will include the requested data formatted as JSON:
|
||||
@ -51,19 +51,48 @@ For more detail on constructing GraphQL queries, see the [GraphQL queries docume
|
||||
|
||||
## Filtering
|
||||
|
||||
The GraphQL API employs the same filtering logic as the UI and REST API. Filters can be specified as key-value pairs within parentheses immediately following the query name. For example, the following will return only sites within the North Carolina region with a status of active:
|
||||
!!! note "Changed in NetBox v4.3"
|
||||
The filtering syntax fo the GraphQL API has changed substantially in NetBox v4.3.
|
||||
|
||||
Filters can be specified as key-value pairs within parentheses immediately following the query name. For example, the following will return only active sites:
|
||||
|
||||
```
|
||||
query {
|
||||
site_list(filters: {region: "us-nc", status: "active"}) {
|
||||
site_list(
|
||||
filters: {
|
||||
status: STATUS_ACTIVE
|
||||
}
|
||||
) {
|
||||
name
|
||||
}
|
||||
}
|
||||
```
|
||||
In addition, filtering can be done on list of related objects as shown in the following query:
|
||||
|
||||
Filters can be combined with logical operators, such as `OR` and `NOT`. For example, the following will return every site that is planned _or_ assigned to a tenant named Foo:
|
||||
|
||||
```
|
||||
{
|
||||
query {
|
||||
site_list(
|
||||
filters: {
|
||||
status: STATUS_PLANNED,
|
||||
OR: {
|
||||
tenant: {
|
||||
name: {
|
||||
exact: "Foo"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
) {
|
||||
name
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Filtering can also be applied to related objects. For example, the following query will return only enabled interfaces for each device:
|
||||
|
||||
```
|
||||
query {
|
||||
device_list {
|
||||
id
|
||||
name
|
||||
|
@ -1,6 +1,6 @@
|
||||
# Filters & Filter Sets
|
||||
|
||||
Filter sets define the mechanisms available for filtering or searching through a set of objects in NetBox. For instance, sites can be filtered by their parent region or group, status, facility ID, and so on. The same filter set is used consistently for a model whether the request is made via the UI, REST API, or GraphQL API. NetBox employs the [django-filters2](https://django-tables2.readthedocs.io/en/latest/) library to define filter sets.
|
||||
Filter sets define the mechanisms available for filtering or searching through a set of objects in NetBox. For instance, sites can be filtered by their parent region or group, status, facility ID, and so on. The same filter set is used consistently for a model whether the request is made via the UI or REST API. (Note that the GraphQL API uses a separate filter class.) NetBox employs the [django-filters2](https://django-tables2.readthedocs.io/en/latest/) library to define filter sets.
|
||||
|
||||
## FilterSet Classes
|
||||
|
||||
|
20
netbox/circuits/graphql/enums.py
Normal file
20
netbox/circuits/graphql/enums.py
Normal file
@ -0,0 +1,20 @@
|
||||
import strawberry
|
||||
|
||||
from circuits.choices import *
|
||||
|
||||
__all__ = (
|
||||
'CircuitStatusEnum',
|
||||
'CircuitCommitRateEnum',
|
||||
'CircuitTerminationSideEnum',
|
||||
'CircuitTerminationPortSpeedEnum',
|
||||
'CircuitPriorityEnum',
|
||||
'VirtualCircuitTerminationRoleEnum',
|
||||
)
|
||||
|
||||
|
||||
CircuitCommitRateEnum = strawberry.enum(CircuitCommitRateChoices.as_enum())
|
||||
CircuitPriorityEnum = strawberry.enum(CircuitPriorityChoices.as_enum())
|
||||
CircuitStatusEnum = strawberry.enum(CircuitStatusChoices.as_enum())
|
||||
CircuitTerminationSideEnum = strawberry.enum(CircuitTerminationSideChoices.as_enum())
|
||||
CircuitTerminationPortSpeedEnum = strawberry.enum(CircuitTerminationPortSpeedChoices.as_enum())
|
||||
VirtualCircuitTerminationRoleEnum = strawberry.enum(VirtualCircuitTerminationRoleChoices.as_enum())
|
19
netbox/circuits/graphql/filter_mixins.py
Normal file
19
netbox/circuits/graphql/filter_mixins.py
Normal file
@ -0,0 +1,19 @@
|
||||
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 netbox.graphql.enums import ColorEnum
|
||||
|
||||
__all__ = (
|
||||
'BaseCircuitTypeFilterMixin',
|
||||
)
|
||||
|
||||
|
||||
@dataclass
|
||||
class BaseCircuitTypeFilterMixin(OrganizationalModelFilterMixin):
|
||||
color: Annotated['ColorEnum', strawberry.lazy('netbox.graphql.enums')] | None = strawberry_django.filter_field()
|
@ -1,7 +1,30 @@
|
||||
import strawberry_django
|
||||
from datetime import date
|
||||
from typing import Annotated, TYPE_CHECKING
|
||||
|
||||
from circuits import filtersets, models
|
||||
from netbox.graphql.filter_mixins import autotype_decorator, BaseFilterMixin
|
||||
import strawberry
|
||||
import strawberry_django
|
||||
from strawberry.scalars import ID
|
||||
from strawberry_django import FilterLookup, DateFilterLookup
|
||||
|
||||
from circuits import models
|
||||
from core.graphql.filter_mixins import BaseObjectTypeFilterMixin, ChangeLogFilterMixin
|
||||
from dcim.graphql.filter_mixins import CabledObjectModelFilterMixin
|
||||
from extras.graphql.filter_mixins import CustomFieldsFilterMixin, TagsFilterMixin
|
||||
from netbox.graphql.filter_mixins import (
|
||||
DistanceFilterMixin,
|
||||
ImageAttachmentFilterMixin,
|
||||
OrganizationalModelFilterMixin,
|
||||
PrimaryModelFilterMixin,
|
||||
)
|
||||
from tenancy.graphql.filter_mixins import ContactFilterMixin, TenancyFilterMixin
|
||||
from .filter_mixins import BaseCircuitTypeFilterMixin
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from core.graphql.filters import ContentTypeFilter
|
||||
from dcim.graphql.filters import InterfaceFilter
|
||||
from ipam.graphql.filters import ASNFilter
|
||||
from netbox.graphql.filter_lookups import IntegerLookup
|
||||
from .enums import *
|
||||
|
||||
__all__ = (
|
||||
'CircuitFilter',
|
||||
@ -19,66 +42,160 @@ __all__ = (
|
||||
|
||||
|
||||
@strawberry_django.filter(models.CircuitTermination, lookups=True)
|
||||
@autotype_decorator(filtersets.CircuitTerminationFilterSet)
|
||||
class CircuitTerminationFilter(BaseFilterMixin):
|
||||
pass
|
||||
class CircuitTerminationFilter(
|
||||
BaseObjectTypeFilterMixin,
|
||||
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('netbox.graphql.filter_lookups')] | None = (
|
||||
strawberry_django.filter_field()
|
||||
)
|
||||
upstream_speed: Annotated['IntegerLookup', strawberry.lazy('netbox.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)
|
||||
@autotype_decorator(filtersets.CircuitFilterSet)
|
||||
class CircuitFilter(BaseFilterMixin):
|
||||
pass
|
||||
class CircuitFilter(
|
||||
ContactFilterMixin,
|
||||
ImageAttachmentFilterMixin,
|
||||
DistanceFilterMixin,
|
||||
TenancyFilterMixin,
|
||||
PrimaryModelFilterMixin
|
||||
):
|
||||
cid: FilterLookup[str] | None = strawberry_django.filter_field()
|
||||
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()
|
||||
)
|
||||
install_date: DateFilterLookup[date] | None = strawberry_django.filter_field()
|
||||
termination_date: DateFilterLookup[date] | None = strawberry_django.filter_field()
|
||||
commit_rate: Annotated['IntegerLookup', strawberry.lazy('netbox.graphql.filter_lookups')] | None = (
|
||||
strawberry_django.filter_field()
|
||||
)
|
||||
|
||||
|
||||
@strawberry_django.filter(models.CircuitType, lookups=True)
|
||||
@autotype_decorator(filtersets.CircuitTypeFilterSet)
|
||||
class CircuitTypeFilter(BaseFilterMixin):
|
||||
class CircuitTypeFilter(BaseCircuitTypeFilterMixin):
|
||||
pass
|
||||
|
||||
|
||||
@strawberry_django.filter(models.CircuitGroup, lookups=True)
|
||||
@autotype_decorator(filtersets.CircuitGroupFilterSet)
|
||||
class CircuitGroupFilter(BaseFilterMixin):
|
||||
class CircuitGroupFilter(TenancyFilterMixin, OrganizationalModelFilterMixin):
|
||||
pass
|
||||
|
||||
|
||||
@strawberry_django.filter(models.CircuitGroupAssignment, lookups=True)
|
||||
@autotype_decorator(filtersets.CircuitGroupAssignmentFilterSet)
|
||||
class CircuitGroupAssignmentFilter(BaseFilterMixin):
|
||||
pass
|
||||
class CircuitGroupAssignmentFilter(
|
||||
BaseObjectTypeFilterMixin, CustomFieldsFilterMixin, TagsFilterMixin, ChangeLogFilterMixin
|
||||
):
|
||||
member_type: Annotated['ContentTypeFilter', strawberry.lazy('core.graphql.filters')] | None = (
|
||||
strawberry_django.filter_field()
|
||||
)
|
||||
member_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)
|
||||
@autotype_decorator(filtersets.ProviderFilterSet)
|
||||
class ProviderFilter(BaseFilterMixin):
|
||||
pass
|
||||
class ProviderFilter(ContactFilterMixin, PrimaryModelFilterMixin):
|
||||
name: FilterLookup[str] | None = strawberry_django.filter_field()
|
||||
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)
|
||||
@autotype_decorator(filtersets.ProviderAccountFilterSet)
|
||||
class ProviderAccountFilter(BaseFilterMixin):
|
||||
pass
|
||||
class ProviderAccountFilter(ContactFilterMixin, PrimaryModelFilterMixin):
|
||||
provider: Annotated['ProviderFilter', strawberry.lazy('circuits.graphql.filters')] | None = (
|
||||
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)
|
||||
@autotype_decorator(filtersets.ProviderNetworkFilterSet)
|
||||
class ProviderNetworkFilter(BaseFilterMixin):
|
||||
pass
|
||||
class ProviderNetworkFilter(PrimaryModelFilterMixin):
|
||||
name: FilterLookup[str] | None = strawberry_django.filter_field()
|
||||
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)
|
||||
@autotype_decorator(filtersets.VirtualCircuitTypeFilterSet)
|
||||
class VirtualCircuitTypeFilter(BaseFilterMixin):
|
||||
class VirtualCircuitTypeFilter(BaseCircuitTypeFilterMixin):
|
||||
pass
|
||||
|
||||
|
||||
@strawberry_django.filter(models.VirtualCircuit, lookups=True)
|
||||
@autotype_decorator(filtersets.VirtualCircuitFilterSet)
|
||||
class VirtualCircuitFilter(BaseFilterMixin):
|
||||
pass
|
||||
class VirtualCircuitFilter(TenancyFilterMixin, PrimaryModelFilterMixin):
|
||||
cid: FilterLookup[str] | None = strawberry_django.filter_field()
|
||||
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()
|
||||
)
|
||||
group_assignments: Annotated['CircuitGroupAssignmentFilter', strawberry.lazy('circuits.graphql.filters')] | None = (
|
||||
strawberry_django.filter_field()
|
||||
)
|
||||
|
||||
|
||||
@strawberry_django.filter(models.VirtualCircuitTermination, lookups=True)
|
||||
@autotype_decorator(filtersets.VirtualCircuitTerminationFilterSet)
|
||||
class VirtualCircuitTerminationFilter(BaseFilterMixin):
|
||||
pass
|
||||
class VirtualCircuitTerminationFilter(
|
||||
BaseObjectTypeFilterMixin, CustomFieldsFilterMixin, TagsFilterMixin, ChangeLogFilterMixin
|
||||
):
|
||||
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()
|
||||
|
@ -1,4 +1,4 @@
|
||||
from typing import Annotated, List, Union
|
||||
from typing import Annotated, List, TYPE_CHECKING, Union
|
||||
|
||||
import strawberry
|
||||
import strawberry_django
|
||||
@ -10,11 +10,15 @@ from netbox.graphql.types import BaseObjectType, NetBoxObjectType, ObjectType, O
|
||||
from tenancy.graphql.types import TenantType
|
||||
from .filters import *
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from dcim.graphql.types import InterfaceType, LocationType, RegionType, SiteGroupType, SiteType
|
||||
from ipam.graphql.types import ASNType
|
||||
|
||||
__all__ = (
|
||||
'CircuitTerminationType',
|
||||
'CircuitType',
|
||||
'CircuitGroupAssignmentType',
|
||||
'CircuitGroupType',
|
||||
'CircuitTerminationType',
|
||||
'CircuitType',
|
||||
'CircuitTypeType',
|
||||
'ProviderType',
|
||||
'ProviderAccountType',
|
||||
@ -62,7 +66,7 @@ class ProviderNetworkType(NetBoxObjectType):
|
||||
|
||||
@strawberry_django.type(
|
||||
models.CircuitTermination,
|
||||
exclude=('termination_type', 'termination_id', '_location', '_region', '_site', '_site_group', '_provider_network'),
|
||||
exclude=['termination_type', 'termination_id', '_location', '_region', '_site', '_site_group', '_provider_network'],
|
||||
filters=CircuitTerminationFilter
|
||||
)
|
||||
class CircuitTerminationType(CustomFieldsMixin, TagsMixin, CabledObjectMixin, ObjectType):
|
||||
@ -117,7 +121,7 @@ class CircuitGroupType(OrganizationalObjectType):
|
||||
|
||||
@strawberry_django.type(
|
||||
models.CircuitGroupAssignment,
|
||||
exclude=('member_type', 'member_id'),
|
||||
exclude=['member_type', 'member_id'],
|
||||
filters=CircuitGroupAssignmentFilter
|
||||
)
|
||||
class CircuitGroupAssignmentType(TagsMixin, BaseObjectType):
|
||||
|
36
netbox/core/graphql/filter_mixins.py
Normal file
36
netbox/core/graphql/filter_mixins.py
Normal file
@ -0,0 +1,36 @@
|
||||
from dataclasses import dataclass
|
||||
from datetime import datetime
|
||||
from typing import Annotated, TYPE_CHECKING
|
||||
|
||||
import strawberry
|
||||
import strawberry_django
|
||||
from strawberry import ID
|
||||
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):
|
||||
id: ID | None = strawberry.UNSET
|
||||
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()
|
@ -1,28 +1,89 @@
|
||||
import strawberry_django
|
||||
from datetime import datetime
|
||||
from typing import Annotated, TYPE_CHECKING
|
||||
|
||||
from core import filtersets, models
|
||||
from netbox.graphql.filter_mixins import autotype_decorator, BaseFilterMixin
|
||||
import strawberry
|
||||
import strawberry_django
|
||||
from django.contrib.contenttypes.models import ContentType as DjangoContentType
|
||||
from strawberry.scalars import ID
|
||||
from strawberry_django import DatetimeFilterLookup, FilterLookup
|
||||
|
||||
from core import models
|
||||
from core.graphql.filter_mixins import BaseFilterMixin
|
||||
from netbox.graphql.filter_mixins import PrimaryModelFilterMixin
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from netbox.graphql.filter_lookups import IntegerLookup, JSONFilter
|
||||
from users.graphql.filters import UserFilter
|
||||
|
||||
__all__ = (
|
||||
'DataFileFilter',
|
||||
'DataSourceFilter',
|
||||
'ObjectChangeFilter',
|
||||
'ContentTypeFilter',
|
||||
)
|
||||
|
||||
|
||||
@strawberry_django.filter(models.DataFile, lookups=True)
|
||||
@autotype_decorator(filtersets.DataFileFilterSet)
|
||||
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('netbox.graphql.filter_lookups')] | None = (
|
||||
strawberry_django.filter_field()
|
||||
)
|
||||
hash: FilterLookup[str] | None = strawberry_django.filter_field()
|
||||
|
||||
|
||||
@strawberry_django.filter(models.DataSource, lookups=True)
|
||||
@autotype_decorator(filtersets.DataSourceFilterSet)
|
||||
class DataSourceFilter(BaseFilterMixin):
|
||||
pass
|
||||
class DataSourceFilter(PrimaryModelFilterMixin):
|
||||
name: FilterLookup[str] | None = strawberry_django.filter_field()
|
||||
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('netbox.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)
|
||||
@autotype_decorator(filtersets.ObjectChangeFilterSet)
|
||||
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: Annotated['ContentTypeFilter', strawberry.lazy('core.graphql.filters')] | 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('netbox.graphql.filter_lookups')] | None = (
|
||||
strawberry_django.filter_field()
|
||||
)
|
||||
postchange_data: Annotated['JSONFilter', strawberry.lazy('netbox.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()
|
||||
|
@ -1,4 +1,4 @@
|
||||
from typing import Annotated, List
|
||||
from typing import Annotated, List, TYPE_CHECKING
|
||||
|
||||
import strawberry
|
||||
import strawberry_django
|
||||
@ -6,6 +6,9 @@ from django.contrib.contenttypes.models import ContentType
|
||||
|
||||
from core.models import ObjectChange
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from netbox.core.graphql.types import ObjectChangeType
|
||||
|
||||
__all__ = (
|
||||
'ChangelogMixin',
|
||||
)
|
||||
|
@ -2,12 +2,14 @@ from typing import Annotated, List
|
||||
|
||||
import strawberry
|
||||
import strawberry_django
|
||||
from django.contrib.contenttypes.models import ContentType as DjangoContentType
|
||||
|
||||
from core import models
|
||||
from netbox.graphql.types import BaseObjectType, NetBoxObjectType
|
||||
from .filters import *
|
||||
|
||||
__all__ = (
|
||||
'ContentType',
|
||||
'DataFileType',
|
||||
'DataSourceType',
|
||||
'ObjectChangeType',
|
||||
@ -40,3 +42,8 @@ class DataSourceType(NetBoxObjectType):
|
||||
)
|
||||
class ObjectChangeType(BaseObjectType):
|
||||
pass
|
||||
|
||||
|
||||
@strawberry_django.type(DjangoContentType, fields='__all__')
|
||||
class ContentType:
|
||||
pass
|
||||
|
77
netbox/dcim/graphql/enums.py
Normal file
77
netbox/dcim/graphql/enums.py
Normal file
@ -0,0 +1,77 @@
|
||||
import strawberry
|
||||
|
||||
from dcim.choices import *
|
||||
|
||||
__all__ = (
|
||||
'CableEndEnum',
|
||||
'CableLengthUnitEnum',
|
||||
'CableTypeEnum',
|
||||
'ConsolePortSpeedEnum',
|
||||
'ConsolePortTypeEnum',
|
||||
'DeviceAirflowEnum',
|
||||
'DeviceFaceEnum',
|
||||
'DeviceStatusEnum',
|
||||
'InterfaceDuplexEnum',
|
||||
'InterfaceModeEnum',
|
||||
'InterfacePoEModeEnum',
|
||||
'InterfacePoETypeEnum',
|
||||
'InterfaceSpeedEnum',
|
||||
'InterfaceTypeEnum',
|
||||
'InventoryItemStatusEnum',
|
||||
'LinkStatusEnum',
|
||||
'LocationStatusEnum',
|
||||
'ModuleAirflowEnum',
|
||||
'ModuleStatusEnum',
|
||||
'PortTypeEnum',
|
||||
'PowerFeedPhaseEnum',
|
||||
'PowerFeedStatusEnum',
|
||||
'PowerFeedSupplyEnum',
|
||||
'PowerFeedTypeEnum',
|
||||
'PowerOutletFeedLegEnum',
|
||||
'PowerOutletTypeEnum',
|
||||
'PowerPortTypeEnum',
|
||||
'RackAirflowEnum',
|
||||
'RackDimensionUnitEnum',
|
||||
'RackFormFactorEnum',
|
||||
'RackStatusEnum',
|
||||
'RackWidthEnum',
|
||||
'SiteStatusEnum',
|
||||
'SubdeviceRoleEnum',
|
||||
'VirtualDeviceContextStatusEnum',
|
||||
)
|
||||
|
||||
CableEndEnum = strawberry.enum(CableEndChoices.as_enum())
|
||||
CableLengthUnitEnum = strawberry.enum(CableLengthUnitChoices.as_enum())
|
||||
CableTypeEnum = strawberry.enum(CableTypeChoices.as_enum())
|
||||
ConsolePortSpeedEnum = strawberry.enum(ConsolePortSpeedChoices.as_enum())
|
||||
ConsolePortTypeEnum = strawberry.enum(ConsolePortTypeChoices.as_enum())
|
||||
DeviceAirflowEnum = strawberry.enum(DeviceAirflowChoices.as_enum())
|
||||
DeviceFaceEnum = strawberry.enum(DeviceFaceChoices.as_enum())
|
||||
DeviceStatusEnum = strawberry.enum(DeviceStatusChoices.as_enum())
|
||||
InterfaceDuplexEnum = strawberry.enum(InterfaceDuplexChoices.as_enum())
|
||||
InterfaceModeEnum = strawberry.enum(InterfaceModeChoices.as_enum())
|
||||
InterfacePoEModeEnum = strawberry.enum(InterfacePoEModeChoices.as_enum())
|
||||
InterfacePoETypeEnum = strawberry.enum(InterfacePoETypeChoices.as_enum())
|
||||
InterfaceSpeedEnum = strawberry.enum(InterfaceSpeedChoices.as_enum())
|
||||
InterfaceTypeEnum = strawberry.enum(InterfaceTypeChoices.as_enum())
|
||||
InventoryItemStatusEnum = strawberry.enum(InventoryItemStatusChoices.as_enum())
|
||||
LinkStatusEnum = strawberry.enum(LinkStatusChoices.as_enum())
|
||||
LocationStatusEnum = strawberry.enum(LocationStatusChoices.as_enum())
|
||||
ModuleAirflowEnum = strawberry.enum(ModuleAirflowChoices.as_enum())
|
||||
ModuleStatusEnum = strawberry.enum(ModuleStatusChoices.as_enum())
|
||||
PortTypeEnum = strawberry.enum(PortTypeChoices.as_enum())
|
||||
PowerFeedPhaseEnum = strawberry.enum(PowerFeedPhaseChoices.as_enum())
|
||||
PowerFeedStatusEnum = strawberry.enum(PowerFeedStatusChoices.as_enum())
|
||||
PowerFeedSupplyEnum = strawberry.enum(PowerFeedSupplyChoices.as_enum())
|
||||
PowerFeedTypeEnum = strawberry.enum(PowerFeedTypeChoices.as_enum())
|
||||
PowerOutletFeedLegEnum = strawberry.enum(PowerOutletFeedLegChoices.as_enum())
|
||||
PowerOutletTypeEnum = strawberry.enum(PowerOutletTypeChoices.as_enum())
|
||||
PowerPortTypeEnum = strawberry.enum(PowerPortTypeChoices.as_enum())
|
||||
RackAirflowEnum = strawberry.enum(RackAirflowChoices.as_enum())
|
||||
RackDimensionUnitEnum = strawberry.enum(RackDimensionUnitChoices.as_enum())
|
||||
RackFormFactorEnum = strawberry.enum(RackFormFactorChoices.as_enum())
|
||||
RackStatusEnum = strawberry.enum(RackStatusChoices.as_enum())
|
||||
RackWidthEnum = strawberry.enum(RackWidthChoices.as_enum())
|
||||
SiteStatusEnum = strawberry.enum(SiteStatusChoices.as_enum())
|
||||
SubdeviceRoleEnum = strawberry.enum(SubdeviceRoleChoices.as_enum())
|
||||
VirtualDeviceContextStatusEnum = strawberry.enum(VirtualDeviceContextStatusChoices.as_enum())
|
149
netbox/dcim/graphql/filter_mixins.py
Normal file
149
netbox/dcim/graphql/filter_mixins.py
Normal file
@ -0,0 +1,149 @@
|
||||
from dataclasses import dataclass
|
||||
from typing import Annotated, TYPE_CHECKING
|
||||
|
||||
import strawberry
|
||||
import strawberry_django
|
||||
from strawberry import ID
|
||||
from strawberry_django import FilterLookup
|
||||
|
||||
from core.graphql.filter_mixins import BaseFilterMixin, ChangeLogFilterMixin
|
||||
from core.graphql.filters import ContentTypeFilter
|
||||
from netbox.graphql.filter_mixins import NetBoxModelFilterMixin, PrimaryModelFilterMixin, WeightFilterMixin
|
||||
from .enums import *
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from netbox.graphql.filter_lookups import IntegerLookup
|
||||
from extras.graphql.filters import ConfigTemplateFilter
|
||||
from ipam.graphql.filters import VLANFilter, VLANTranslationPolicyFilter
|
||||
from .filters import *
|
||||
|
||||
__all__ = (
|
||||
'CabledObjectModelFilterMixin',
|
||||
'ComponentModelFilterMixin',
|
||||
'ComponentTemplateFilterMixin',
|
||||
'InterfaceBaseFilterMixin',
|
||||
'ModularComponentModelFilterMixin',
|
||||
'ModularComponentTemplateFilterMixin',
|
||||
'RackBaseFilterMixin',
|
||||
'RenderConfigFilterMixin',
|
||||
'ScopedFilterMixin',
|
||||
)
|
||||
|
||||
|
||||
@dataclass
|
||||
class ScopedFilterMixin(BaseFilterMixin):
|
||||
scope_type: Annotated['ContentTypeFilter', strawberry.lazy('core.graphql.filters')] | None = (
|
||||
strawberry_django.filter_field()
|
||||
)
|
||||
scope_id: ID | None = strawberry_django.filter_field()
|
||||
|
||||
|
||||
@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()
|
||||
label: 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('netbox.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_translation_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('netbox.graphql.filter_lookups')] | None = (
|
||||
strawberry_django.filter_field()
|
||||
)
|
||||
starting_unit: Annotated['IntegerLookup', strawberry.lazy('netbox.graphql.filter_lookups')] | None = (
|
||||
strawberry_django.filter_field()
|
||||
)
|
||||
desc_units: FilterLookup[bool] | None = strawberry_django.filter_field()
|
||||
outer_width: Annotated['IntegerLookup', strawberry.lazy('netbox.graphql.filter_lookups')] | None = (
|
||||
strawberry_django.filter_field()
|
||||
)
|
||||
outer_depth: Annotated['IntegerLookup', strawberry.lazy('netbox.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('netbox.graphql.filter_lookups')] | None = (
|
||||
strawberry_django.filter_field()
|
||||
)
|
||||
max_weight: Annotated['IntegerLookup', strawberry.lazy('netbox.graphql.filter_lookups')] | None = (
|
||||
strawberry_django.filter_field()
|
||||
)
|
@ -1,7 +1,46 @@
|
||||
import strawberry_django
|
||||
from typing import Annotated, TYPE_CHECKING
|
||||
|
||||
from dcim import filtersets, models
|
||||
from netbox.graphql.filter_mixins import autotype_decorator, BaseFilterMixin
|
||||
import strawberry
|
||||
import strawberry_django
|
||||
from strawberry.scalars import ID
|
||||
from strawberry_django import FilterLookup
|
||||
|
||||
from core.graphql.filter_mixins import ChangeLogFilterMixin
|
||||
from dcim import models
|
||||
from extras.graphql.filter_mixins import ConfigContextFilterMixin
|
||||
from netbox.graphql.filter_mixins import (
|
||||
PrimaryModelFilterMixin,
|
||||
OrganizationalModelFilterMixin,
|
||||
NestedGroupModelFilterMixin,
|
||||
ImageAttachmentFilterMixin,
|
||||
WeightFilterMixin,
|
||||
)
|
||||
from tenancy.graphql.filter_mixins import TenancyFilterMixin, ContactFilterMixin
|
||||
from .filter_mixins import (
|
||||
CabledObjectModelFilterMixin,
|
||||
ComponentModelFilterMixin,
|
||||
ComponentTemplateFilterMixin,
|
||||
InterfaceBaseFilterMixin,
|
||||
ModularComponentModelFilterMixin,
|
||||
ModularComponentTemplateFilterMixin,
|
||||
RackBaseFilterMixin,
|
||||
RenderConfigFilterMixin,
|
||||
)
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from core.graphql.filters import ContentTypeFilter
|
||||
from extras.graphql.filters import ConfigTemplateFilter, ImageAttachmentFilter
|
||||
from ipam.graphql.filters import (
|
||||
ASNFilter, FHRPGroupAssignmentFilter, IPAddressFilter, PrefixFilter, VLANGroupFilter, VRFFilter,
|
||||
)
|
||||
from netbox.graphql.enums import ColorEnum
|
||||
from netbox.graphql.filter_lookups import FloatLookup, IntegerArrayLookup, IntegerLookup, TreeNodeFilter
|
||||
from users.graphql.filters import UserFilter
|
||||
from virtualization.graphql.filters import ClusterFilter
|
||||
from vpn.graphql.filters import L2VPNFilter, TunnelTerminationFilter
|
||||
from wireless.graphql.enums import WirelessChannelEnum, WirelessRoleEnum
|
||||
from wireless.graphql.filters import WirelessLANFilter, WirelessLinkFilter
|
||||
from .enums import *
|
||||
|
||||
__all__ = (
|
||||
'CableFilter',
|
||||
@ -13,7 +52,6 @@ __all__ = (
|
||||
'DeviceFilter',
|
||||
'DeviceBayFilter',
|
||||
'DeviceBayTemplateFilter',
|
||||
'InventoryItemTemplateFilter',
|
||||
'DeviceRoleFilter',
|
||||
'DeviceTypeFilter',
|
||||
'FrontPortFilter',
|
||||
@ -22,6 +60,7 @@ __all__ = (
|
||||
'InterfaceTemplateFilter',
|
||||
'InventoryItemFilter',
|
||||
'InventoryItemRoleFilter',
|
||||
'InventoryItemTemplateFilter',
|
||||
'LocationFilter',
|
||||
'MACAddressFilter',
|
||||
'ManufacturerFilter',
|
||||
@ -51,258 +90,763 @@ __all__ = (
|
||||
|
||||
|
||||
@strawberry_django.filter(models.Cable, lookups=True)
|
||||
@autotype_decorator(filtersets.CableFilterSet)
|
||||
class CableFilter(BaseFilterMixin):
|
||||
pass
|
||||
class CableFilter(PrimaryModelFilterMixin, TenancyFilterMixin):
|
||||
type: Annotated['CableTypeEnum', strawberry.lazy('dcim.graphql.enums')] | None = strawberry_django.filter_field()
|
||||
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('netbox.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)
|
||||
@autotype_decorator(filtersets.CableTerminationFilterSet)
|
||||
class CableTerminationFilter(BaseFilterMixin):
|
||||
pass
|
||||
class CableTerminationFilter(ChangeLogFilterMixin):
|
||||
cable: Annotated['CableFilter', strawberry.lazy('dcim.graphql.filters')] | None = strawberry_django.filter_field()
|
||||
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)
|
||||
@autotype_decorator(filtersets.ConsolePortFilterSet)
|
||||
class ConsolePortFilter(BaseFilterMixin):
|
||||
pass
|
||||
class ConsolePortFilter(ModularComponentModelFilterMixin, CabledObjectModelFilterMixin):
|
||||
type: Annotated['ConsolePortTypeEnum', strawberry.lazy('dcim.graphql.enums')] | None = (
|
||||
strawberry_django.filter_field()
|
||||
)
|
||||
speed: Annotated['ConsolePortSpeedEnum', strawberry.lazy('dcim.graphql.enums')] | None = (
|
||||
strawberry_django.filter_field()
|
||||
)
|
||||
|
||||
|
||||
@strawberry_django.filter(models.ConsolePortTemplate, lookups=True)
|
||||
@autotype_decorator(filtersets.ConsolePortTemplateFilterSet)
|
||||
class ConsolePortTemplateFilter(BaseFilterMixin):
|
||||
pass
|
||||
class ConsolePortTemplateFilter(ModularComponentTemplateFilterMixin):
|
||||
type: Annotated['ConsolePortTypeEnum', strawberry.lazy('dcim.graphql.enums')] | None = (
|
||||
strawberry_django.filter_field()
|
||||
)
|
||||
|
||||
|
||||
@strawberry_django.filter(models.ConsoleServerPort, lookups=True)
|
||||
@autotype_decorator(filtersets.ConsoleServerPortFilterSet)
|
||||
class ConsoleServerPortFilter(BaseFilterMixin):
|
||||
pass
|
||||
class ConsoleServerPortFilter(ModularComponentModelFilterMixin, CabledObjectModelFilterMixin):
|
||||
type: Annotated['ConsolePortTypeEnum', strawberry.lazy('dcim.graphql.enums')] | None = (
|
||||
strawberry_django.filter_field()
|
||||
)
|
||||
speed: Annotated['ConsolePortSpeedEnum', strawberry.lazy('dcim.graphql.enums')] | None = (
|
||||
strawberry_django.filter_field()
|
||||
)
|
||||
|
||||
|
||||
@strawberry_django.filter(models.ConsoleServerPortTemplate, lookups=True)
|
||||
@autotype_decorator(filtersets.ConsoleServerPortTemplateFilterSet)
|
||||
class ConsoleServerPortTemplateFilter(BaseFilterMixin):
|
||||
pass
|
||||
class ConsoleServerPortTemplateFilter(ModularComponentTemplateFilterMixin):
|
||||
type: Annotated['ConsolePortTypeEnum', strawberry.lazy('dcim.graphql.enums')] | None = (
|
||||
strawberry_django.filter_field()
|
||||
)
|
||||
|
||||
|
||||
@strawberry_django.filter(models.Device, lookups=True)
|
||||
@autotype_decorator(filtersets.DeviceFilterSet)
|
||||
class DeviceFilter(BaseFilterMixin):
|
||||
pass
|
||||
class DeviceFilter(
|
||||
ContactFilterMixin,
|
||||
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('netbox.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('netbox.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('netbox.graphql.filter_lookups')] | None = (
|
||||
strawberry_django.filter_field()
|
||||
)
|
||||
vc_priority: Annotated['IntegerLookup', strawberry.lazy('netbox.graphql.filter_lookups')] | None = (
|
||||
strawberry_django.filter_field()
|
||||
)
|
||||
latitude: Annotated['FloatLookup', strawberry.lazy('netbox.graphql.filter_lookups')] | None = (
|
||||
strawberry_django.filter_field()
|
||||
)
|
||||
longitude: Annotated['FloatLookup', strawberry.lazy('netbox.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()
|
||||
)
|
||||
console_port_count: FilterLookup[int] | None = strawberry_django.filter_field()
|
||||
console_server_port_count: FilterLookup[int] | None = strawberry_django.filter_field()
|
||||
power_port_count: FilterLookup[int] | None = strawberry_django.filter_field()
|
||||
power_outlet_count: FilterLookup[int] | None = strawberry_django.filter_field()
|
||||
interface_count: FilterLookup[int] | None = strawberry_django.filter_field()
|
||||
front_port_count: FilterLookup[int] | None = strawberry_django.filter_field()
|
||||
rear_port_count: FilterLookup[int] | None = strawberry_django.filter_field()
|
||||
device_bay_count: FilterLookup[int] | None = strawberry_django.filter_field()
|
||||
module_bay_count: FilterLookup[int] | None = strawberry_django.filter_field()
|
||||
inventory_item_count: FilterLookup[int] | None = strawberry_django.filter_field()
|
||||
|
||||
|
||||
@strawberry_django.filter(models.DeviceBay, lookups=True)
|
||||
@autotype_decorator(filtersets.DeviceBayFilterSet)
|
||||
class DeviceBayFilter(BaseFilterMixin):
|
||||
pass
|
||||
class DeviceBayFilter(ComponentModelFilterMixin):
|
||||
installed_device: Annotated['DeviceFilter', strawberry.lazy('dcim.graphql.filters')] | None = (
|
||||
strawberry_django.filter_field()
|
||||
)
|
||||
installed_device_id: ID | None = strawberry_django.filter_field()
|
||||
|
||||
|
||||
@strawberry_django.filter(models.DeviceBayTemplate, lookups=True)
|
||||
@autotype_decorator(filtersets.DeviceBayTemplateFilterSet)
|
||||
class DeviceBayTemplateFilter(BaseFilterMixin):
|
||||
class DeviceBayTemplateFilter(ComponentTemplateFilterMixin):
|
||||
pass
|
||||
|
||||
|
||||
@strawberry_django.filter(models.InventoryItemTemplate, lookups=True)
|
||||
@autotype_decorator(filtersets.InventoryItemTemplateFilterSet)
|
||||
class InventoryItemTemplateFilter(BaseFilterMixin):
|
||||
pass
|
||||
class InventoryItemTemplateFilter(ComponentTemplateFilterMixin):
|
||||
parent: Annotated['InventoryItemTemplateFilter', strawberry.lazy('dcim.graphql.filters')] | 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()
|
||||
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)
|
||||
@autotype_decorator(filtersets.DeviceRoleFilterSet)
|
||||
class DeviceRoleFilter(BaseFilterMixin):
|
||||
pass
|
||||
class DeviceRoleFilter(OrganizationalModelFilterMixin, RenderConfigFilterMixin):
|
||||
color: Annotated['ColorEnum', strawberry.lazy('netbox.graphql.enums')] | None = strawberry_django.filter_field()
|
||||
vm_role: FilterLookup[bool] | None = strawberry_django.filter_field()
|
||||
|
||||
|
||||
@strawberry_django.filter(models.DeviceType, lookups=True)
|
||||
@autotype_decorator(filtersets.DeviceTypeFilterSet)
|
||||
class DeviceTypeFilter(BaseFilterMixin):
|
||||
pass
|
||||
class DeviceTypeFilter(ImageAttachmentFilterMixin, PrimaryModelFilterMixin, WeightFilterMixin):
|
||||
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()
|
||||
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('netbox.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()
|
||||
)
|
||||
console_port_template_count: FilterLookup[int] | None = strawberry_django.filter_field()
|
||||
console_server_port_template_count: FilterLookup[int] | None = strawberry_django.filter_field()
|
||||
power_port_template_count: FilterLookup[int] | None = strawberry_django.filter_field()
|
||||
power_outlet_template_count: FilterLookup[int] | None = strawberry_django.filter_field()
|
||||
interface_template_count: FilterLookup[int] | None = strawberry_django.filter_field()
|
||||
front_port_template_count: FilterLookup[int] | None = strawberry_django.filter_field()
|
||||
rear_port_template_count: FilterLookup[int] | None = strawberry_django.filter_field()
|
||||
device_bay_template_count: FilterLookup[int] | None = strawberry_django.filter_field()
|
||||
module_bay_template_count: FilterLookup[int] | None = strawberry_django.filter_field()
|
||||
inventory_item_template_count: FilterLookup[int] | None = strawberry_django.filter_field()
|
||||
|
||||
|
||||
@strawberry_django.filter(models.FrontPort, lookups=True)
|
||||
@autotype_decorator(filtersets.FrontPortFilterSet)
|
||||
class FrontPortFilter(BaseFilterMixin):
|
||||
pass
|
||||
class FrontPortFilter(ModularComponentModelFilterMixin, CabledObjectModelFilterMixin):
|
||||
type: Annotated['PortTypeEnum', strawberry.lazy('dcim.graphql.enums')] | None = strawberry_django.filter_field()
|
||||
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('netbox.graphql.filter_lookups')] | None = (
|
||||
strawberry_django.filter_field()
|
||||
)
|
||||
|
||||
|
||||
@strawberry_django.filter(models.FrontPortTemplate, lookups=True)
|
||||
@autotype_decorator(filtersets.FrontPortTemplateFilterSet)
|
||||
class FrontPortTemplateFilter(BaseFilterMixin):
|
||||
pass
|
||||
class FrontPortTemplateFilter(ModularComponentTemplateFilterMixin):
|
||||
type: Annotated['PortTypeEnum', strawberry.lazy('dcim.graphql.enums')] | None = strawberry_django.filter_field()
|
||||
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('netbox.graphql.filter_lookups')] | None = (
|
||||
strawberry_django.filter_field()
|
||||
)
|
||||
|
||||
|
||||
@strawberry_django.filter(models.MACAddress, lookups=True)
|
||||
@autotype_decorator(filtersets.MACAddressFilterSet)
|
||||
class MACAddressFilter(BaseFilterMixin):
|
||||
pass
|
||||
class MACAddressFilter(PrimaryModelFilterMixin):
|
||||
mac_address: FilterLookup[str] | 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()
|
||||
|
||||
|
||||
@strawberry_django.filter(models.Interface, lookups=True)
|
||||
@autotype_decorator(filtersets.InterfaceFilterSet)
|
||||
class InterfaceFilter(BaseFilterMixin):
|
||||
pass
|
||||
class InterfaceFilter(ModularComponentModelFilterMixin, InterfaceBaseFilterMixin, CabledObjectModelFilterMixin):
|
||||
vcdcs: Annotated['VirtualDeviceContextFilter', strawberry.lazy('dcim.graphql.filters')] | None = (
|
||||
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('netbox.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('netbox.graphql.filter_lookups')] | None = (
|
||||
strawberry_django.filter_field()
|
||||
)
|
||||
rf_channel_width: Annotated['FloatLookup', strawberry.lazy('netbox.graphql.filter_lookups')] | None = (
|
||||
strawberry_django.filter_field()
|
||||
)
|
||||
tx_power: Annotated['IntegerLookup', strawberry.lazy('netbox.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)
|
||||
@autotype_decorator(filtersets.InterfaceTemplateFilterSet)
|
||||
class InterfaceTemplateFilter(BaseFilterMixin):
|
||||
pass
|
||||
class InterfaceTemplateFilter(ModularComponentTemplateFilterMixin):
|
||||
type: Annotated['InterfaceTypeEnum', strawberry.lazy('dcim.graphql.enums')] | None = (
|
||||
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)
|
||||
@autotype_decorator(filtersets.InventoryItemFilterSet)
|
||||
class InventoryItemFilter(BaseFilterMixin):
|
||||
pass
|
||||
class InventoryItemFilter(ComponentModelFilterMixin):
|
||||
parent: Annotated['InventoryItemFilter', strawberry.lazy('dcim.graphql.filters')] | None = (
|
||||
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)
|
||||
@autotype_decorator(filtersets.InventoryItemRoleFilterSet)
|
||||
class InventoryItemRoleFilter(BaseFilterMixin):
|
||||
pass
|
||||
class InventoryItemRoleFilter(OrganizationalModelFilterMixin):
|
||||
color: Annotated['ColorEnum', strawberry.lazy('netbox.graphql.enums')] | None = strawberry_django.filter_field()
|
||||
|
||||
|
||||
@strawberry_django.filter(models.Location, lookups=True)
|
||||
@autotype_decorator(filtersets.LocationFilterSet)
|
||||
class LocationFilter(BaseFilterMixin):
|
||||
pass
|
||||
class LocationFilter(ContactFilterMixin, ImageAttachmentFilterMixin, TenancyFilterMixin, NestedGroupModelFilterMixin):
|
||||
site: Annotated['SiteFilter', strawberry.lazy('dcim.graphql.filters')] | None = strawberry_django.filter_field()
|
||||
site_id: ID | None = strawberry_django.filter_field()
|
||||
status: Annotated['LocationStatusEnum', strawberry.lazy('dcim.graphql.enums')] | 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)
|
||||
@autotype_decorator(filtersets.ManufacturerFilterSet)
|
||||
class ManufacturerFilter(BaseFilterMixin):
|
||||
class ManufacturerFilter(ContactFilterMixin, OrganizationalModelFilterMixin):
|
||||
pass
|
||||
|
||||
|
||||
@strawberry_django.filter(models.Module, lookups=True)
|
||||
@autotype_decorator(filtersets.ModuleFilterSet)
|
||||
class ModuleFilter(BaseFilterMixin):
|
||||
pass
|
||||
class ModuleFilter(PrimaryModelFilterMixin, ConfigContextFilterMixin):
|
||||
device: Annotated['DeviceFilter', strawberry.lazy('dcim.graphql.filters')] | None = strawberry_django.filter_field()
|
||||
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)
|
||||
@autotype_decorator(filtersets.ModuleBayFilterSet)
|
||||
class ModuleBayFilter(BaseFilterMixin):
|
||||
pass
|
||||
class ModuleBayFilter(ModularComponentModelFilterMixin):
|
||||
parent: Annotated['ModuleBayFilter', strawberry.lazy('dcim.graphql.filters')] | None = (
|
||||
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)
|
||||
@autotype_decorator(filtersets.ModuleBayTemplateFilterSet)
|
||||
class ModuleBayTemplateFilter(BaseFilterMixin):
|
||||
pass
|
||||
class ModuleBayTemplateFilter(ModularComponentTemplateFilterMixin):
|
||||
position: FilterLookup[str] | None = strawberry_django.filter_field()
|
||||
|
||||
|
||||
@strawberry_django.filter(models.ModuleType, lookups=True)
|
||||
@autotype_decorator(filtersets.ModuleTypeFilterSet)
|
||||
class ModuleTypeFilter(BaseFilterMixin):
|
||||
pass
|
||||
class ModuleTypeFilter(ImageAttachmentFilterMixin, PrimaryModelFilterMixin, WeightFilterMixin):
|
||||
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()
|
||||
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)
|
||||
@autotype_decorator(filtersets.PlatformFilterSet)
|
||||
class PlatformFilter(BaseFilterMixin):
|
||||
pass
|
||||
class PlatformFilter(OrganizationalModelFilterMixin):
|
||||
manufacturer: Annotated['ManufacturerFilter', strawberry.lazy('dcim.graphql.filters')] | None = (
|
||||
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)
|
||||
@autotype_decorator(filtersets.PowerFeedFilterSet)
|
||||
class PowerFeedFilter(BaseFilterMixin):
|
||||
pass
|
||||
class PowerFeedFilter(CabledObjectModelFilterMixin, TenancyFilterMixin, PrimaryModelFilterMixin):
|
||||
power_panel: Annotated['PowerPanelFilter', strawberry.lazy('dcim.graphql.filters')] | None = (
|
||||
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('netbox.graphql.filter_lookups')] | None = (
|
||||
strawberry_django.filter_field()
|
||||
)
|
||||
amperage: Annotated['IntegerLookup', strawberry.lazy('netbox.graphql.filter_lookups')] | None = (
|
||||
strawberry_django.filter_field()
|
||||
)
|
||||
max_utilization: Annotated['IntegerLookup', strawberry.lazy('netbox.graphql.filter_lookups')] | None = (
|
||||
strawberry_django.filter_field()
|
||||
)
|
||||
available_power: Annotated['IntegerLookup', strawberry.lazy('netbox.graphql.filter_lookups')] | None = (
|
||||
strawberry_django.filter_field()
|
||||
)
|
||||
|
||||
|
||||
@strawberry_django.filter(models.PowerOutlet, lookups=True)
|
||||
@autotype_decorator(filtersets.PowerOutletFilterSet)
|
||||
class PowerOutletFilter(BaseFilterMixin):
|
||||
pass
|
||||
class PowerOutletFilter(ModularComponentModelFilterMixin, CabledObjectModelFilterMixin):
|
||||
type: Annotated['PowerOutletTypeEnum', strawberry.lazy('dcim.graphql.enums')] | None = (
|
||||
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)
|
||||
@autotype_decorator(filtersets.PowerOutletTemplateFilterSet)
|
||||
class PowerOutletTemplateFilter(BaseFilterMixin):
|
||||
pass
|
||||
class PowerOutletTemplateFilter(ModularComponentModelFilterMixin):
|
||||
type: Annotated['PowerOutletTypeEnum', strawberry.lazy('dcim.graphql.enums')] | None = (
|
||||
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)
|
||||
@autotype_decorator(filtersets.PowerPanelFilterSet)
|
||||
class PowerPanelFilter(BaseFilterMixin):
|
||||
pass
|
||||
class PowerPanelFilter(ContactFilterMixin, ImageAttachmentFilterMixin, PrimaryModelFilterMixin):
|
||||
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('netbox.graphql.filter_lookups')] | None = (
|
||||
strawberry_django.filter_field()
|
||||
)
|
||||
name: FilterLookup[str] | None = strawberry_django.filter_field()
|
||||
|
||||
|
||||
@strawberry_django.filter(models.PowerPort, lookups=True)
|
||||
@autotype_decorator(filtersets.PowerPortFilterSet)
|
||||
class PowerPortFilter(BaseFilterMixin):
|
||||
pass
|
||||
class PowerPortFilter(ModularComponentModelFilterMixin, CabledObjectModelFilterMixin):
|
||||
type: Annotated['PowerPortTypeEnum', strawberry.lazy('dcim.graphql.enums')] | None = (
|
||||
strawberry_django.filter_field()
|
||||
)
|
||||
maximum_draw: Annotated['IntegerLookup', strawberry.lazy('netbox.graphql.filter_lookups')] | None = (
|
||||
strawberry_django.filter_field()
|
||||
)
|
||||
allocated_draw: Annotated['IntegerLookup', strawberry.lazy('netbox.graphql.filter_lookups')] | None = (
|
||||
strawberry_django.filter_field()
|
||||
)
|
||||
|
||||
|
||||
@strawberry_django.filter(models.PowerPortTemplate, lookups=True)
|
||||
@autotype_decorator(filtersets.PowerPortTemplateFilterSet)
|
||||
class PowerPortTemplateFilter(BaseFilterMixin):
|
||||
pass
|
||||
class PowerPortTemplateFilter(ModularComponentTemplateFilterMixin):
|
||||
type: Annotated['PowerPortTypeEnum', strawberry.lazy('dcim.graphql.enums')] | None = (
|
||||
strawberry_django.filter_field()
|
||||
)
|
||||
maximum_draw: Annotated['IntegerLookup', strawberry.lazy('netbox.graphql.filter_lookups')] | None = (
|
||||
strawberry_django.filter_field()
|
||||
)
|
||||
allocated_draw: Annotated['IntegerLookup', strawberry.lazy('netbox.graphql.filter_lookups')] | None = (
|
||||
strawberry_django.filter_field()
|
||||
)
|
||||
|
||||
|
||||
@strawberry_django.filter(models.RackType, lookups=True)
|
||||
@autotype_decorator(filtersets.RackTypeFilterSet)
|
||||
class RackTypeFilter(BaseFilterMixin):
|
||||
pass
|
||||
class RackTypeFilter(RackBaseFilterMixin):
|
||||
form_factor: Annotated['RackFormFactorEnum', strawberry.lazy('dcim.graphql.enums')] | 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()
|
||||
model: FilterLookup[str] | None = strawberry_django.filter_field()
|
||||
slug: FilterLookup[str] | None = strawberry_django.filter_field()
|
||||
|
||||
|
||||
@strawberry_django.filter(models.Rack, lookups=True)
|
||||
@autotype_decorator(filtersets.RackFilterSet)
|
||||
class RackFilter(BaseFilterMixin):
|
||||
pass
|
||||
class RackFilter(ContactFilterMixin, ImageAttachmentFilterMixin, TenancyFilterMixin, RackBaseFilterMixin):
|
||||
form_factor: Annotated['RackFormFactorEnum', strawberry.lazy('dcim.graphql.enums')] | None = (
|
||||
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('netbox.graphql.filter_lookups')] | 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)
|
||||
@autotype_decorator(filtersets.RackReservationFilterSet)
|
||||
class RackReservationFilter(BaseFilterMixin):
|
||||
pass
|
||||
class RackReservationFilter(TenancyFilterMixin, PrimaryModelFilterMixin):
|
||||
rack: Annotated['RackFilter', strawberry.lazy('dcim.graphql.filters')] | None = strawberry_django.filter_field()
|
||||
rack_id: ID | None = strawberry_django.filter_field()
|
||||
units: Annotated['IntegerArrayLookup', strawberry.lazy('netbox.graphql.filter_lookups')] | 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)
|
||||
@autotype_decorator(filtersets.RackRoleFilterSet)
|
||||
class RackRoleFilter(BaseFilterMixin):
|
||||
pass
|
||||
class RackRoleFilter(OrganizationalModelFilterMixin):
|
||||
color: Annotated['ColorEnum', strawberry.lazy('netbox.graphql.enums')] | None = strawberry_django.filter_field()
|
||||
|
||||
|
||||
@strawberry_django.filter(models.RearPort, lookups=True)
|
||||
@autotype_decorator(filtersets.RearPortFilterSet)
|
||||
class RearPortFilter(BaseFilterMixin):
|
||||
pass
|
||||
class RearPortFilter(ModularComponentModelFilterMixin, CabledObjectModelFilterMixin):
|
||||
type: Annotated['PortTypeEnum', strawberry.lazy('dcim.graphql.enums')] | None = strawberry_django.filter_field()
|
||||
color: Annotated['ColorEnum', strawberry.lazy('netbox.graphql.enums')] | None = strawberry_django.filter_field()
|
||||
positions: Annotated['IntegerLookup', strawberry.lazy('netbox.graphql.filter_lookups')] | None = (
|
||||
strawberry_django.filter_field()
|
||||
)
|
||||
|
||||
|
||||
@strawberry_django.filter(models.RearPortTemplate, lookups=True)
|
||||
@autotype_decorator(filtersets.RearPortTemplateFilterSet)
|
||||
class RearPortTemplateFilter(BaseFilterMixin):
|
||||
pass
|
||||
class RearPortTemplateFilter(ModularComponentTemplateFilterMixin):
|
||||
type: Annotated['PortTypeEnum', strawberry.lazy('dcim.graphql.enums')] | None = strawberry_django.filter_field()
|
||||
color: Annotated['ColorEnum', strawberry.lazy('netbox.graphql.enums')] | None = strawberry_django.filter_field()
|
||||
positions: Annotated['IntegerLookup', strawberry.lazy('netbox.graphql.filter_lookups')] | None = (
|
||||
strawberry_django.filter_field()
|
||||
)
|
||||
|
||||
|
||||
@strawberry_django.filter(models.Region, lookups=True)
|
||||
@autotype_decorator(filtersets.RegionFilterSet)
|
||||
class RegionFilter(BaseFilterMixin):
|
||||
pass
|
||||
class RegionFilter(ContactFilterMixin, NestedGroupModelFilterMixin):
|
||||
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.Site, lookups=True)
|
||||
@autotype_decorator(filtersets.SiteFilterSet)
|
||||
class SiteFilter(BaseFilterMixin):
|
||||
pass
|
||||
class SiteFilter(ContactFilterMixin, ImageAttachmentFilterMixin, TenancyFilterMixin, PrimaryModelFilterMixin):
|
||||
name: FilterLookup[str] | None = strawberry_django.filter_field()
|
||||
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('netbox.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('netbox.graphql.filter_lookups')] | 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('netbox.graphql.filter_lookups')] | None = (
|
||||
strawberry_django.filter_field()
|
||||
)
|
||||
longitude: Annotated['FloatLookup', strawberry.lazy('netbox.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)
|
||||
@autotype_decorator(filtersets.SiteGroupFilterSet)
|
||||
class SiteGroupFilter(BaseFilterMixin):
|
||||
pass
|
||||
class SiteGroupFilter(ContactFilterMixin, NestedGroupModelFilterMixin):
|
||||
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.VirtualChassis, lookups=True)
|
||||
@autotype_decorator(filtersets.VirtualChassisFilterSet)
|
||||
class VirtualChassisFilter(BaseFilterMixin):
|
||||
pass
|
||||
class VirtualChassisFilter(PrimaryModelFilterMixin):
|
||||
master: Annotated['DeviceFilter', strawberry.lazy('dcim.graphql.filters')] | None = strawberry_django.filter_field()
|
||||
master_id: ID | None = strawberry_django.filter_field()
|
||||
name: FilterLookup[str] | None = strawberry_django.filter_field()
|
||||
domain: FilterLookup[str] | None = strawberry_django.filter_field()
|
||||
member_count: FilterLookup[int] | None = strawberry_django.filter_field()
|
||||
|
||||
|
||||
@strawberry_django.filter(models.VirtualDeviceContext, lookups=True)
|
||||
@autotype_decorator(filtersets.VirtualDeviceContextFilterSet)
|
||||
class VirtualDeviceContextFilter(BaseFilterMixin):
|
||||
pass
|
||||
class VirtualDeviceContextFilter(TenancyFilterMixin, PrimaryModelFilterMixin):
|
||||
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()
|
||||
status: Annotated['VirtualDeviceContextStatusEnum', strawberry.lazy('dcim.graphql.enums')] | None = (
|
||||
strawberry_django.filter_field()
|
||||
)
|
||||
identifier: Annotated['IntegerLookup', strawberry.lazy('netbox.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()
|
||||
comments: FilterLookup[str] | None = strawberry_django.filter_field()
|
||||
|
@ -1,4 +1,4 @@
|
||||
from typing import Annotated, List, Union
|
||||
from typing import Annotated, List, TYPE_CHECKING, Union
|
||||
|
||||
import strawberry
|
||||
import strawberry_django
|
||||
@ -6,7 +6,11 @@ import strawberry_django
|
||||
from core.graphql.mixins import ChangelogMixin
|
||||
from dcim import models
|
||||
from extras.graphql.mixins import (
|
||||
ConfigContextMixin, ContactsMixin, CustomFieldsMixin, ImageAttachmentsMixin, TagsMixin,
|
||||
ConfigContextMixin,
|
||||
ContactsMixin,
|
||||
CustomFieldsMixin,
|
||||
ImageAttachmentsMixin,
|
||||
TagsMixin,
|
||||
)
|
||||
from ipam.graphql.mixins import IPAddressesMixin, VLANGroupsMixin
|
||||
from netbox.graphql.scalars import BigInt
|
||||
@ -14,6 +18,23 @@ from netbox.graphql.types import BaseObjectType, NetBoxObjectType, Organizationa
|
||||
from .filters import *
|
||||
from .mixins import CabledObjectMixin, PathEndpointMixin
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from circuits.graphql.types import CircuitTerminationType
|
||||
from extras.graphql.types import ConfigTemplateType
|
||||
from ipam.graphql.types import (
|
||||
ASNType,
|
||||
IPAddressType,
|
||||
PrefixType,
|
||||
ServiceType,
|
||||
VLANTranslationPolicyType,
|
||||
VLANType,
|
||||
VRFType,
|
||||
)
|
||||
from tenancy.graphql.types import TenantType
|
||||
from users.graphql.types import UserType
|
||||
from virtualization.graphql.types import ClusterType, VMInterfaceType, VirtualMachineType
|
||||
from wireless.graphql.types import WirelessLANType, WirelessLinkType
|
||||
|
||||
__all__ = (
|
||||
'CableType',
|
||||
'ComponentType',
|
||||
@ -111,7 +132,7 @@ class ModularComponentTemplateType(ComponentTemplateType):
|
||||
|
||||
@strawberry_django.type(
|
||||
models.CableTermination,
|
||||
exclude=('termination_type', 'termination_id', '_device', '_rack', '_location', '_site'),
|
||||
exclude=['termination_type', 'termination_id', '_device', '_rack', '_location', '_site'],
|
||||
filters=CableTerminationFilter
|
||||
)
|
||||
class CableTerminationType(NetBoxObjectType):
|
||||
@ -167,7 +188,7 @@ class CableType(NetBoxObjectType):
|
||||
|
||||
@strawberry_django.type(
|
||||
models.ConsolePort,
|
||||
exclude=('_path',),
|
||||
exclude=['_path'],
|
||||
filters=ConsolePortFilter
|
||||
)
|
||||
class ConsolePortType(ModularComponentType, CabledObjectMixin, PathEndpointMixin):
|
||||
@ -185,7 +206,7 @@ class ConsolePortTemplateType(ModularComponentTemplateType):
|
||||
|
||||
@strawberry_django.type(
|
||||
models.ConsoleServerPort,
|
||||
exclude=('_path',),
|
||||
exclude=['_path'],
|
||||
filters=ConsoleServerPortFilter
|
||||
)
|
||||
class ConsoleServerPortType(ModularComponentType, CabledObjectMixin, PathEndpointMixin):
|
||||
@ -276,7 +297,7 @@ class DeviceBayTemplateType(ComponentTemplateType):
|
||||
|
||||
@strawberry_django.type(
|
||||
models.InventoryItemTemplate,
|
||||
exclude=('component_type', 'component_id', 'parent'),
|
||||
exclude=['component_type', 'component_id', 'parent'],
|
||||
filters=InventoryItemTemplateFilter
|
||||
)
|
||||
class InventoryItemTemplateType(ComponentTemplateType):
|
||||
@ -369,7 +390,7 @@ class FrontPortTemplateType(ModularComponentTemplateType):
|
||||
|
||||
@strawberry_django.type(
|
||||
models.MACAddress,
|
||||
exclude=('assigned_object_type', 'assigned_object_id'),
|
||||
exclude=['assigned_object_type', 'assigned_object_id'],
|
||||
filters=MACAddressFilter
|
||||
)
|
||||
class MACAddressType(NetBoxObjectType):
|
||||
@ -385,7 +406,7 @@ class MACAddressType(NetBoxObjectType):
|
||||
|
||||
@strawberry_django.type(
|
||||
models.Interface,
|
||||
exclude=('_path',),
|
||||
exclude=['_path'],
|
||||
filters=InterfaceFilter
|
||||
)
|
||||
class InterfaceType(IPAddressesMixin, ModularComponentType, CabledObjectMixin, PathEndpointMixin):
|
||||
@ -424,7 +445,7 @@ class InterfaceTemplateType(ModularComponentTemplateType):
|
||||
|
||||
@strawberry_django.type(
|
||||
models.InventoryItem,
|
||||
exclude=('component_type', 'component_id', 'parent'),
|
||||
exclude=['component_type', 'component_id', 'parent'],
|
||||
filters=InventoryItemFilter
|
||||
)
|
||||
class InventoryItemType(ComponentType):
|
||||
@ -463,7 +484,7 @@ class InventoryItemRoleType(OrganizationalObjectType):
|
||||
@strawberry_django.type(
|
||||
models.Location,
|
||||
# fields='__all__',
|
||||
exclude=('parent',), # bug - temp
|
||||
exclude=['parent'], # bug - temp
|
||||
filters=LocationFilter
|
||||
)
|
||||
class LocationType(VLANGroupsMixin, ImageAttachmentsMixin, ContactsMixin, OrganizationalObjectType):
|
||||
@ -524,7 +545,7 @@ class ModuleType(NetBoxObjectType):
|
||||
@strawberry_django.type(
|
||||
models.ModuleBay,
|
||||
# fields='__all__',
|
||||
exclude=('parent',),
|
||||
exclude=['parent'],
|
||||
filters=ModuleBayFilter
|
||||
)
|
||||
class ModuleBayType(ModularComponentType):
|
||||
@ -579,7 +600,7 @@ class PlatformType(OrganizationalObjectType):
|
||||
|
||||
@strawberry_django.type(
|
||||
models.PowerFeed,
|
||||
exclude=('_path',),
|
||||
exclude=['_path'],
|
||||
filters=PowerFeedFilter
|
||||
)
|
||||
class PowerFeedType(NetBoxObjectType, CabledObjectMixin, PathEndpointMixin):
|
||||
@ -590,7 +611,7 @@ class PowerFeedType(NetBoxObjectType, CabledObjectMixin, PathEndpointMixin):
|
||||
|
||||
@strawberry_django.type(
|
||||
models.PowerOutlet,
|
||||
exclude=('_path',),
|
||||
exclude=['_path'],
|
||||
filters=PowerOutletFilter
|
||||
)
|
||||
class PowerOutletType(ModularComponentType, CabledObjectMixin, PathEndpointMixin):
|
||||
@ -621,7 +642,7 @@ class PowerPanelType(NetBoxObjectType, ContactsMixin):
|
||||
|
||||
@strawberry_django.type(
|
||||
models.PowerPort,
|
||||
exclude=('_path',),
|
||||
exclude=['_path'],
|
||||
filters=PowerPortFilter
|
||||
)
|
||||
class PowerPortType(ModularComponentType, CabledObjectMixin, PathEndpointMixin):
|
||||
@ -712,8 +733,7 @@ class RearPortTemplateType(ModularComponentTemplateType):
|
||||
|
||||
@strawberry_django.type(
|
||||
models.Region,
|
||||
exclude=('parent',),
|
||||
# fields='__all__',
|
||||
exclude=['parent'],
|
||||
filters=RegionFilter
|
||||
)
|
||||
class RegionType(VLANGroupsMixin, ContactsMixin, OrganizationalObjectType):
|
||||
@ -772,8 +792,7 @@ class SiteType(VLANGroupsMixin, ImageAttachmentsMixin, ContactsMixin, NetBoxObje
|
||||
|
||||
@strawberry_django.type(
|
||||
models.SiteGroup,
|
||||
# fields='__all__',
|
||||
exclude=('parent',), # bug - temp
|
||||
exclude=['parent'], # bug - temp
|
||||
filters=SiteGroupFilter
|
||||
)
|
||||
class SiteGroupType(VLANGroupsMixin, ContactsMixin, OrganizationalObjectType):
|
||||
|
26
netbox/extras/graphql/enums.py
Normal file
26
netbox/extras/graphql/enums.py
Normal file
@ -0,0 +1,26 @@
|
||||
import strawberry
|
||||
|
||||
from extras.choices import *
|
||||
|
||||
__all__ = (
|
||||
'CustomFieldChoiceSetBaseEnum',
|
||||
'CustomFieldFilterLogicEnum',
|
||||
'CustomFieldTypeEnum',
|
||||
'CustomFieldUIEditableEnum',
|
||||
'CustomFieldUIVisibleEnum',
|
||||
'CustomLinkButtonClassEnum',
|
||||
'EventRuleActionEnum',
|
||||
'JournalEntryKindEnum',
|
||||
'WebhookHttpMethodEnum',
|
||||
)
|
||||
|
||||
|
||||
CustomFieldChoiceSetBaseEnum = strawberry.enum(CustomFieldChoiceSetBaseChoices.as_enum())
|
||||
CustomFieldFilterLogicEnum = strawberry.enum(CustomFieldFilterLogicChoices.as_enum())
|
||||
CustomFieldTypeEnum = strawberry.enum(CustomFieldTypeChoices.as_enum())
|
||||
CustomFieldUIEditableEnum = strawberry.enum(CustomFieldUIEditableChoices.as_enum())
|
||||
CustomFieldUIVisibleEnum = strawberry.enum(CustomFieldUIVisibleChoices.as_enum())
|
||||
CustomLinkButtonClassEnum = strawberry.enum(CustomLinkButtonClassChoices.as_enum())
|
||||
EventRuleActionEnum = strawberry.enum(EventRuleActionChoices.as_enum())
|
||||
JournalEntryKindEnum = strawberry.enum(JournalEntryKindChoices.as_enum())
|
||||
WebhookHttpMethodEnum = strawberry.enum(WebhookHttpMethodChoices.as_enum())
|
52
netbox/extras/graphql/filter_mixins.py
Normal file
52
netbox/extras/graphql/filter_mixins.py
Normal file
@ -0,0 +1,52 @@
|
||||
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 netbox.graphql.filter_lookups import JSONFilter
|
||||
from .filters import *
|
||||
|
||||
__all__ = (
|
||||
'CustomFieldsFilterMixin',
|
||||
'JournalEntriesFilterMixin',
|
||||
'TagsFilterMixin',
|
||||
'ConfigContextFilterMixin',
|
||||
'TagBaseFilterMixin',
|
||||
)
|
||||
|
||||
|
||||
@dataclass
|
||||
class CustomFieldsFilterMixin(BaseFilterMixin):
|
||||
custom_field_data: Annotated['JSONFilter', strawberry.lazy('netbox.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_context_data: Annotated['JSONFilter', strawberry.lazy('netbox.graphql.filter_lookups')] | 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()
|
@ -1,7 +1,26 @@
|
||||
import strawberry_django
|
||||
from typing import Annotated, TYPE_CHECKING
|
||||
|
||||
from extras import filtersets, models
|
||||
from netbox.graphql.filter_mixins import autotype_decorator, BaseFilterMixin
|
||||
import strawberry
|
||||
import strawberry_django
|
||||
from strawberry.scalars import ID
|
||||
from strawberry_django import FilterLookup
|
||||
|
||||
from core.graphql.filter_mixins import BaseObjectTypeFilterMixin, ChangeLogFilterMixin
|
||||
from extras import models
|
||||
from extras.graphql.filter_mixins import TagBaseFilterMixin, CustomFieldsFilterMixin, TagsFilterMixin
|
||||
from netbox.graphql.filter_mixins import SyncedDataFilterMixin
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from core.graphql.filters import ContentTypeFilter
|
||||
from dcim.graphql.filters import (
|
||||
DeviceRoleFilter, DeviceTypeFilter, LocationFilter, PlatformFilter, RegionFilter, SiteFilter, SiteGroupFilter,
|
||||
)
|
||||
from tenancy.graphql.filters import TenantFilter, TenantGroupFilter
|
||||
from netbox.graphql.enums import ColorEnum
|
||||
from netbox.graphql.filter_lookups import IntegerLookup, JSONFilter, StringArrayLookup, TreeNodeFilter
|
||||
from users.graphql.filters import GroupFilter, UserFilter
|
||||
from virtualization.graphql.filters import ClusterFilter, ClusterGroupFilter, ClusterTypeFilter
|
||||
from .enums import *
|
||||
|
||||
__all__ = (
|
||||
'ConfigContextFilter',
|
||||
@ -21,78 +40,263 @@ __all__ = (
|
||||
|
||||
|
||||
@strawberry_django.filter(models.ConfigContext, lookups=True)
|
||||
@autotype_decorator(filtersets.ConfigContextFilterSet)
|
||||
class ConfigContextFilter(BaseFilterMixin):
|
||||
pass
|
||||
class ConfigContextFilter(BaseObjectTypeFilterMixin, SyncedDataFilterMixin, ChangeLogFilterMixin):
|
||||
name: FilterLookup[str] = strawberry_django.filter_field()
|
||||
weight: Annotated['IntegerLookup', strawberry.lazy('netbox.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('netbox.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('netbox.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('netbox.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('netbox.graphql.filter_lookups')] | None = (
|
||||
strawberry_django.filter_field()
|
||||
)
|
||||
|
||||
|
||||
@strawberry_django.filter(models.ConfigTemplate, lookups=True)
|
||||
@autotype_decorator(filtersets.ConfigTemplateFilterSet)
|
||||
class ConfigTemplateFilter(BaseFilterMixin):
|
||||
pass
|
||||
class ConfigTemplateFilter(BaseObjectTypeFilterMixin, SyncedDataFilterMixin, ChangeLogFilterMixin):
|
||||
name: FilterLookup[str] | None = strawberry_django.filter_field()
|
||||
description: FilterLookup[str] | None = strawberry_django.filter_field()
|
||||
template_code: FilterLookup[str] | None = strawberry_django.filter_field()
|
||||
environment_params: Annotated['JSONFilter', strawberry.lazy('netbox.graphql.filter_lookups')] | None = (
|
||||
strawberry_django.filter_field()
|
||||
)
|
||||
|
||||
|
||||
@strawberry_django.filter(models.CustomField, lookups=True)
|
||||
@autotype_decorator(filtersets.CustomFieldFilterSet)
|
||||
class CustomFieldFilter(BaseFilterMixin):
|
||||
pass
|
||||
class CustomFieldFilter(BaseObjectTypeFilterMixin, ChangeLogFilterMixin):
|
||||
type: Annotated['CustomFieldTypeEnum', strawberry.lazy('extras.graphql.enums')] | None = (
|
||||
strawberry_django.filter_field()
|
||||
)
|
||||
object_types: Annotated['ContentTypeFilter', strawberry.lazy('core.graphql.filters')] | None = (
|
||||
strawberry_django.filter_field()
|
||||
)
|
||||
related_object_type: Annotated['ContentTypeFilter', strawberry.lazy('core.graphql.filters')] | 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('netbox.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('netbox.graphql.filter_lookups')] | None = (
|
||||
strawberry_django.filter_field()
|
||||
)
|
||||
related_object_filter: Annotated['JSONFilter', strawberry.lazy('netbox.graphql.filter_lookups')] | None = (
|
||||
strawberry_django.filter_field()
|
||||
)
|
||||
weight: Annotated['IntegerLookup', strawberry.lazy('netbox.graphql.filter_lookups')] | None = (
|
||||
strawberry_django.filter_field()
|
||||
)
|
||||
validation_minimum: Annotated['IntegerLookup', strawberry.lazy('netbox.graphql.filter_lookups')] | None = (
|
||||
strawberry_django.filter_field()
|
||||
)
|
||||
validation_maximum: Annotated['IntegerLookup', strawberry.lazy('netbox.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)
|
||||
@autotype_decorator(filtersets.CustomFieldChoiceSetFilterSet)
|
||||
class CustomFieldChoiceSetFilter(BaseFilterMixin):
|
||||
pass
|
||||
class CustomFieldChoiceSetFilter(BaseObjectTypeFilterMixin, ChangeLogFilterMixin):
|
||||
name: FilterLookup[str] | None = strawberry_django.filter_field()
|
||||
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('netbox.graphql.filter_lookups')] | None = (
|
||||
strawberry_django.filter_field()
|
||||
)
|
||||
order_alphabetically: FilterLookup[bool] | None = strawberry_django.filter_field()
|
||||
|
||||
|
||||
@strawberry_django.filter(models.CustomLink, lookups=True)
|
||||
@autotype_decorator(filtersets.CustomLinkFilterSet)
|
||||
class CustomLinkFilter(BaseFilterMixin):
|
||||
pass
|
||||
class CustomLinkFilter(BaseObjectTypeFilterMixin, ChangeLogFilterMixin):
|
||||
name: FilterLookup[str] | None = strawberry_django.filter_field()
|
||||
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('netbox.graphql.filter_lookups')] | None = (
|
||||
strawberry_django.filter_field()
|
||||
)
|
||||
group_name: FilterLookup[str] | None = strawberry_django.filter_field()
|
||||
button_class: Annotated['CustomLinkButtonClassEnum', strawberry.lazy('extras.graphql.enums')] | None = (
|
||||
strawberry_django.filter_field()
|
||||
)
|
||||
new_window: FilterLookup[bool] | None = strawberry_django.filter_field()
|
||||
|
||||
|
||||
@strawberry_django.filter(models.ExportTemplate, lookups=True)
|
||||
@autotype_decorator(filtersets.ExportTemplateFilterSet)
|
||||
class ExportTemplateFilter(BaseFilterMixin):
|
||||
pass
|
||||
class ExportTemplateFilter(BaseObjectTypeFilterMixin, SyncedDataFilterMixin, ChangeLogFilterMixin):
|
||||
name: FilterLookup[str] | None = strawberry_django.filter_field()
|
||||
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)
|
||||
@autotype_decorator(filtersets.ImageAttachmentFilterSet)
|
||||
class ImageAttachmentFilter(BaseFilterMixin):
|
||||
pass
|
||||
class ImageAttachmentFilter(BaseObjectTypeFilterMixin, ChangeLogFilterMixin):
|
||||
object_type: Annotated['ContentTypeFilter', strawberry.lazy('core.graphql.filters')] | None = (
|
||||
strawberry_django.filter_field()
|
||||
)
|
||||
object_id: ID | None = strawberry_django.filter_field()
|
||||
image_height: Annotated['IntegerLookup', strawberry.lazy('netbox.graphql.filter_lookups')] | None = (
|
||||
strawberry_django.filter_field()
|
||||
)
|
||||
image_width: Annotated['IntegerLookup', strawberry.lazy('netbox.graphql.filter_lookups')] | None = (
|
||||
strawberry_django.filter_field()
|
||||
)
|
||||
name: FilterLookup[str] | None = strawberry_django.filter_field()
|
||||
|
||||
|
||||
@strawberry_django.filter(models.JournalEntry, lookups=True)
|
||||
@autotype_decorator(filtersets.JournalEntryFilterSet)
|
||||
class JournalEntryFilter(BaseFilterMixin):
|
||||
pass
|
||||
class JournalEntryFilter(BaseObjectTypeFilterMixin, CustomFieldsFilterMixin, TagsFilterMixin, ChangeLogFilterMixin):
|
||||
assigned_object_type: Annotated['ContentTypeFilter', strawberry.lazy('core.graphql.filters')] | None = (
|
||||
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)
|
||||
@autotype_decorator(filtersets.NotificationGroupFilterSet)
|
||||
class NotificationGroupFilter(BaseFilterMixin):
|
||||
pass
|
||||
class NotificationGroupFilter(BaseObjectTypeFilterMixin, ChangeLogFilterMixin):
|
||||
name: FilterLookup[str] | None = strawberry_django.filter_field()
|
||||
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)
|
||||
@autotype_decorator(filtersets.SavedFilterFilterSet)
|
||||
class SavedFilterFilter(BaseFilterMixin):
|
||||
pass
|
||||
class SavedFilterFilter(BaseObjectTypeFilterMixin, ChangeLogFilterMixin):
|
||||
name: FilterLookup[str] | None = strawberry_django.filter_field()
|
||||
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('netbox.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('netbox.graphql.filter_lookups')] | None = (
|
||||
strawberry_django.filter_field()
|
||||
)
|
||||
|
||||
|
||||
@strawberry_django.filter(models.Tag, lookups=True)
|
||||
@autotype_decorator(filtersets.TagFilterSet)
|
||||
class TagFilter(BaseFilterMixin):
|
||||
pass
|
||||
class TagFilter(BaseObjectTypeFilterMixin, ChangeLogFilterMixin, TagBaseFilterMixin):
|
||||
color: Annotated['ColorEnum', strawberry.lazy('netbox.graphql.enums')] | None = strawberry_django.filter_field()
|
||||
description: FilterLookup[str] | None = strawberry_django.filter_field()
|
||||
|
||||
|
||||
@strawberry_django.filter(models.Webhook, lookups=True)
|
||||
@autotype_decorator(filtersets.WebhookFilterSet)
|
||||
class WebhookFilter(BaseFilterMixin):
|
||||
pass
|
||||
class WebhookFilter(BaseObjectTypeFilterMixin, CustomFieldsFilterMixin, TagsFilterMixin, ChangeLogFilterMixin):
|
||||
name: FilterLookup[str] | None = strawberry_django.filter_field()
|
||||
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)
|
||||
@autotype_decorator(filtersets.EventRuleFilterSet)
|
||||
class EventRuleFilter(BaseFilterMixin):
|
||||
pass
|
||||
class EventRuleFilter(BaseObjectTypeFilterMixin, CustomFieldsFilterMixin, TagsFilterMixin, ChangeLogFilterMixin):
|
||||
name: FilterLookup[str] | None = strawberry_django.filter_field()
|
||||
description: FilterLookup[str] | None = strawberry_django.filter_field()
|
||||
event_types: Annotated['StringArrayLookup', strawberry.lazy('netbox.graphql.filter_lookups')] | None = (
|
||||
strawberry_django.filter_field()
|
||||
)
|
||||
enabled: FilterLookup[bool] | None = strawberry_django.filter_field()
|
||||
conditions: Annotated['JSONFilter', strawberry.lazy('netbox.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('netbox.graphql.filter_lookups')] | None = (
|
||||
strawberry_django.filter_field()
|
||||
)
|
||||
comments: FilterLookup[str] | None = strawberry_django.filter_field()
|
||||
|
@ -1,4 +1,4 @@
|
||||
from typing import Annotated, List
|
||||
from typing import Annotated, List, TYPE_CHECKING
|
||||
|
||||
import strawberry
|
||||
import strawberry_django
|
||||
@ -8,6 +8,22 @@ from extras.graphql.mixins import CustomFieldsMixin, TagsMixin
|
||||
from netbox.graphql.types import BaseObjectType, ContentTypeType, ObjectType, OrganizationalObjectType
|
||||
from .filters import *
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from core.graphql.types import DataFileType, DataSourceType
|
||||
from dcim.graphql.types import (
|
||||
DeviceRoleType,
|
||||
DeviceType,
|
||||
DeviceTypeType,
|
||||
LocationType,
|
||||
PlatformType,
|
||||
RegionType,
|
||||
SiteGroupType,
|
||||
SiteType,
|
||||
)
|
||||
from tenancy.graphql.types import TenantGroupType, TenantType
|
||||
from users.graphql.types import GroupType, UserType
|
||||
from virtualization.graphql.types import ClusterGroupType, ClusterType, ClusterTypeType, VirtualMachineType
|
||||
|
||||
__all__ = (
|
||||
'ConfigContextType',
|
||||
'ConfigTemplateType',
|
||||
@ -35,7 +51,6 @@ __all__ = (
|
||||
class ConfigContextType(ObjectType):
|
||||
data_source: Annotated["DataSourceType", strawberry.lazy('core.graphql.types')] | None
|
||||
data_file: Annotated["DataFileType", strawberry.lazy('core.graphql.types')] | None
|
||||
|
||||
roles: List[Annotated["DeviceRoleType", strawberry.lazy('dcim.graphql.types')]]
|
||||
device_types: List[Annotated["DeviceTypeType", strawberry.lazy('dcim.graphql.types')]]
|
||||
tags: List[Annotated["TagType", strawberry.lazy('extras.graphql.types')]]
|
||||
@ -78,7 +93,7 @@ class CustomFieldType(ObjectType):
|
||||
|
||||
@strawberry_django.type(
|
||||
models.CustomFieldChoiceSet,
|
||||
exclude=('extra_choices', ),
|
||||
exclude=['extra_choices'],
|
||||
filters=CustomFieldChoiceSetFilter
|
||||
)
|
||||
class CustomFieldChoiceSetType(ObjectType):
|
||||
|
27
netbox/ipam/graphql/enums.py
Normal file
27
netbox/ipam/graphql/enums.py
Normal file
@ -0,0 +1,27 @@
|
||||
import strawberry
|
||||
|
||||
from ipam.choices import *
|
||||
|
||||
__all__ = (
|
||||
'FHRPGroupAuthTypeEnum',
|
||||
'FHRPGroupProtocolEnum',
|
||||
'IPAddressFamilyEnum',
|
||||
'IPAddressRoleEnum',
|
||||
'IPAddressStatusEnum',
|
||||
'IPRangeStatusEnum',
|
||||
'PrefixStatusEnum',
|
||||
'ServiceProtocolEnum',
|
||||
'VLANStatusEnum',
|
||||
'VLANQinQRoleEnum',
|
||||
)
|
||||
|
||||
FHRPGroupAuthTypeEnum = strawberry.enum(FHRPGroupAuthTypeChoices.as_enum())
|
||||
FHRPGroupProtocolEnum = strawberry.enum(FHRPGroupProtocolChoices.as_enum())
|
||||
IPAddressFamilyEnum = strawberry.enum(IPAddressFamilyChoices.as_enum())
|
||||
IPAddressRoleEnum = strawberry.enum(IPAddressRoleChoices.as_enum())
|
||||
IPAddressStatusEnum = strawberry.enum(IPAddressStatusChoices.as_enum())
|
||||
IPRangeStatusEnum = strawberry.enum(IPRangeStatusChoices.as_enum())
|
||||
PrefixStatusEnum = strawberry.enum(PrefixStatusChoices.as_enum())
|
||||
ServiceProtocolEnum = strawberry.enum(ServiceProtocolChoices.as_enum())
|
||||
VLANStatusEnum = strawberry.enum(VLANStatusChoices.as_enum())
|
||||
VLANQinQRoleEnum = strawberry.enum(VLANQinQRoleChoices.as_enum())
|
25
netbox/ipam/graphql/filter_mixins.py
Normal file
25
netbox/ipam/graphql/filter_mixins.py
Normal file
@ -0,0 +1,25 @@
|
||||
from dataclasses import dataclass
|
||||
from typing import Annotated, TYPE_CHECKING
|
||||
|
||||
import strawberry
|
||||
import strawberry_django
|
||||
|
||||
from core.graphql.filter_mixins import BaseFilterMixin
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from netbox.graphql.filter_lookups import IntegerLookup
|
||||
from .enums 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('netbox.graphql.filter_lookups')] | None = (
|
||||
strawberry_django.filter_field()
|
||||
)
|
@ -1,7 +1,28 @@
|
||||
import strawberry_django
|
||||
from datetime import date
|
||||
from typing import Annotated, TYPE_CHECKING
|
||||
|
||||
from ipam import filtersets, models
|
||||
from netbox.graphql.filter_mixins import autotype_decorator, BaseFilterMixin
|
||||
import netaddr
|
||||
import strawberry
|
||||
import strawberry_django
|
||||
from django.db.models import Q
|
||||
from netaddr.core import AddrFormatError
|
||||
from strawberry.scalars import ID
|
||||
from strawberry_django import FilterLookup, DateFilterLookup
|
||||
|
||||
from core.graphql.filter_mixins import BaseObjectTypeFilterMixin, ChangeLogFilterMixin
|
||||
from dcim.graphql.filter_mixins import ScopedFilterMixin
|
||||
from ipam import models
|
||||
from ipam.graphql.filter_mixins import ServiceBaseFilterMixin
|
||||
from netbox.graphql.filter_mixins import NetBoxModelFilterMixin, OrganizationalModelFilterMixin, PrimaryModelFilterMixin
|
||||
from tenancy.graphql.filter_mixins import ContactFilterMixin, TenancyFilterMixin
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from netbox.graphql.filter_lookups import IntegerArrayLookup, IntegerLookup
|
||||
from core.graphql.filters import ContentTypeFilter
|
||||
from dcim.graphql.filters import DeviceFilter, SiteFilter
|
||||
from virtualization.graphql.filters import VirtualMachineFilter
|
||||
from vpn.graphql.filters import L2VPNFilter
|
||||
from .enums import *
|
||||
|
||||
__all__ = (
|
||||
'ASNFilter',
|
||||
@ -26,108 +47,258 @@ __all__ = (
|
||||
|
||||
|
||||
@strawberry_django.filter(models.ASN, lookups=True)
|
||||
@autotype_decorator(filtersets.ASNFilterSet)
|
||||
class ASNFilter(BaseFilterMixin):
|
||||
pass
|
||||
class ASNFilter(TenancyFilterMixin, PrimaryModelFilterMixin):
|
||||
rir: Annotated['RIRFilter', strawberry.lazy('ipam.graphql.filters')] | None = strawberry_django.filter_field()
|
||||
rir_id: ID | None = strawberry_django.filter_field()
|
||||
asn: Annotated['IntegerLookup', strawberry.lazy('netbox.graphql.filter_lookups')] | None = (
|
||||
strawberry_django.filter_field()
|
||||
)
|
||||
|
||||
|
||||
@strawberry_django.filter(models.ASNRange, lookups=True)
|
||||
@autotype_decorator(filtersets.ASNRangeFilterSet)
|
||||
class ASNRangeFilter(BaseFilterMixin):
|
||||
pass
|
||||
class ASNRangeFilter(TenancyFilterMixin, OrganizationalModelFilterMixin):
|
||||
name: FilterLookup[str] | None = strawberry_django.filter_field()
|
||||
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('netbox.graphql.filter_lookups')] | None = (
|
||||
strawberry_django.filter_field()
|
||||
)
|
||||
end: Annotated['IntegerLookup', strawberry.lazy('netbox.graphql.filter_lookups')] | None = (
|
||||
strawberry_django.filter_field()
|
||||
)
|
||||
|
||||
|
||||
@strawberry_django.filter(models.Aggregate, lookups=True)
|
||||
@autotype_decorator(filtersets.AggregateFilterSet)
|
||||
class AggregateFilter(BaseFilterMixin):
|
||||
pass
|
||||
class AggregateFilter(ContactFilterMixin, TenancyFilterMixin, PrimaryModelFilterMixin):
|
||||
prefix: Annotated['PrefixFilter', strawberry.lazy('ipam.graphql.filters')] | None = strawberry_django.filter_field()
|
||||
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()
|
||||
date_added: DateFilterLookup[date] | None = strawberry_django.filter_field()
|
||||
|
||||
|
||||
@strawberry_django.filter(models.FHRPGroup, lookups=True)
|
||||
@autotype_decorator(filtersets.FHRPGroupFilterSet)
|
||||
class FHRPGroupFilter(BaseFilterMixin):
|
||||
pass
|
||||
class FHRPGroupFilter(PrimaryModelFilterMixin):
|
||||
group_id: Annotated['IntegerLookup', strawberry.lazy('netbox.graphql.filter_lookups')] | None = (
|
||||
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)
|
||||
@autotype_decorator(filtersets.FHRPGroupAssignmentFilterSet)
|
||||
class FHRPGroupAssignmentFilter(BaseFilterMixin):
|
||||
pass
|
||||
class FHRPGroupAssignmentFilter(BaseObjectTypeFilterMixin, ChangeLogFilterMixin):
|
||||
interface_type: Annotated['ContentTypeFilter', strawberry.lazy('core.graphql.filters')] | None = (
|
||||
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('netbox.graphql.filter_lookups')] | None = (
|
||||
strawberry_django.filter_field()
|
||||
)
|
||||
|
||||
|
||||
@strawberry_django.filter(models.IPAddress, lookups=True)
|
||||
@autotype_decorator(filtersets.IPAddressFilterSet)
|
||||
class IPAddressFilter(BaseFilterMixin):
|
||||
pass
|
||||
class IPAddressFilter(ContactFilterMixin, TenancyFilterMixin, PrimaryModelFilterMixin):
|
||||
address: FilterLookup[str] | 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()
|
||||
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)
|
||||
@autotype_decorator(filtersets.IPRangeFilterSet)
|
||||
class IPRangeFilter(BaseFilterMixin):
|
||||
pass
|
||||
class IPRangeFilter(ContactFilterMixin, TenancyFilterMixin, PrimaryModelFilterMixin):
|
||||
start_address: FilterLookup[str] | None = strawberry_django.filter_field()
|
||||
end_address: FilterLookup[str] | None = strawberry_django.filter_field()
|
||||
size: Annotated['IntegerLookup', strawberry.lazy('netbox.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()
|
||||
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)
|
||||
@autotype_decorator(filtersets.PrefixFilterSet)
|
||||
class PrefixFilter(BaseFilterMixin):
|
||||
pass
|
||||
class PrefixFilter(ContactFilterMixin, ScopedFilterMixin, TenancyFilterMixin, PrimaryModelFilterMixin):
|
||||
prefix: FilterLookup[str] | 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()
|
||||
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()
|
||||
|
||||
|
||||
@strawberry_django.filter(models.RIR, lookups=True)
|
||||
@autotype_decorator(filtersets.RIRFilterSet)
|
||||
class RIRFilter(BaseFilterMixin):
|
||||
pass
|
||||
class RIRFilter(OrganizationalModelFilterMixin):
|
||||
is_private: FilterLookup[bool] | None = strawberry_django.filter_field()
|
||||
|
||||
|
||||
@strawberry_django.filter(models.Role, lookups=True)
|
||||
@autotype_decorator(filtersets.RoleFilterSet)
|
||||
class RoleFilter(BaseFilterMixin):
|
||||
pass
|
||||
class RoleFilter(OrganizationalModelFilterMixin):
|
||||
weight: Annotated['IntegerLookup', strawberry.lazy('netbox.graphql.filter_lookups')] | None = (
|
||||
strawberry_django.filter_field()
|
||||
)
|
||||
|
||||
|
||||
@strawberry_django.filter(models.RouteTarget, lookups=True)
|
||||
@autotype_decorator(filtersets.RouteTargetFilterSet)
|
||||
class RouteTargetFilter(BaseFilterMixin):
|
||||
pass
|
||||
class RouteTargetFilter(TenancyFilterMixin, PrimaryModelFilterMixin):
|
||||
name: FilterLookup[str] | None = strawberry_django.filter_field()
|
||||
|
||||
|
||||
@strawberry_django.filter(models.Service, lookups=True)
|
||||
@autotype_decorator(filtersets.ServiceFilterSet)
|
||||
class ServiceFilter(BaseFilterMixin):
|
||||
pass
|
||||
class ServiceFilter(ContactFilterMixin, ServiceBaseFilterMixin, PrimaryModelFilterMixin):
|
||||
device: Annotated['DeviceFilter', strawberry.lazy('dcim.graphql.filters')] | None = strawberry_django.filter_field()
|
||||
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)
|
||||
@autotype_decorator(filtersets.ServiceTemplateFilterSet)
|
||||
class ServiceTemplateFilter(BaseFilterMixin):
|
||||
pass
|
||||
class ServiceTemplateFilter(ServiceBaseFilterMixin, PrimaryModelFilterMixin):
|
||||
name: FilterLookup[str] | None = strawberry_django.filter_field()
|
||||
|
||||
|
||||
@strawberry_django.filter(models.VLAN, lookups=True)
|
||||
@autotype_decorator(filtersets.VLANFilterSet)
|
||||
class VLANFilter(BaseFilterMixin):
|
||||
pass
|
||||
class VLANFilter(TenancyFilterMixin, PrimaryModelFilterMixin):
|
||||
site: Annotated['SiteFilter', strawberry.lazy('dcim.graphql.filters')] | None = strawberry_django.filter_field()
|
||||
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('netbox.graphql.filter_lookups')] | None = (
|
||||
strawberry_django.filter_field()
|
||||
)
|
||||
name: FilterLookup[str] | 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)
|
||||
@autotype_decorator(filtersets.VLANGroupFilterSet)
|
||||
class VLANGroupFilter(BaseFilterMixin):
|
||||
pass
|
||||
class VLANGroupFilter(ScopedFilterMixin, OrganizationalModelFilterMixin):
|
||||
vid_ranges: Annotated['IntegerArrayLookup', strawberry.lazy('netbox.graphql.filter_lookups')] | None = (
|
||||
strawberry_django.filter_field()
|
||||
)
|
||||
|
||||
|
||||
@strawberry_django.filter(models.VLANTranslationPolicy, lookups=True)
|
||||
@autotype_decorator(filtersets.VLANTranslationPolicyFilterSet)
|
||||
class VLANTranslationPolicyFilter(BaseFilterMixin):
|
||||
pass
|
||||
class VLANTranslationPolicyFilter(PrimaryModelFilterMixin):
|
||||
name: FilterLookup[str] | None = strawberry_django.filter_field()
|
||||
|
||||
|
||||
@strawberry_django.filter(models.VLANTranslationRule, lookups=True)
|
||||
@autotype_decorator(filtersets.VLANTranslationRuleFilterSet)
|
||||
class VLANTranslationRuleFilter(BaseFilterMixin):
|
||||
pass
|
||||
class VLANTranslationRuleFilter(NetBoxModelFilterMixin):
|
||||
policy: Annotated['VLANTranslationPolicyFilter', strawberry.lazy('ipam.graphql.filters')] | None = (
|
||||
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('netbox.graphql.filter_lookups')] | None = (
|
||||
strawberry_django.filter_field()
|
||||
)
|
||||
remote_vid: Annotated['IntegerLookup', strawberry.lazy('netbox.graphql.filter_lookups')] | None = (
|
||||
strawberry_django.filter_field()
|
||||
)
|
||||
|
||||
|
||||
@strawberry_django.filter(models.VRF, lookups=True)
|
||||
@autotype_decorator(filtersets.VRFFilterSet)
|
||||
class VRFFilter(BaseFilterMixin):
|
||||
pass
|
||||
class VRFFilter(TenancyFilterMixin, PrimaryModelFilterMixin):
|
||||
name: FilterLookup[str] | None = strawberry_django.filter_field()
|
||||
rd: FilterLookup[str] | 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()
|
||||
)
|
||||
|
@ -1,4 +1,4 @@
|
||||
from typing import Annotated, List, Union
|
||||
from typing import Annotated, List, TYPE_CHECKING, Union
|
||||
|
||||
import strawberry
|
||||
import strawberry_django
|
||||
@ -11,6 +11,21 @@ from netbox.graphql.types import BaseObjectType, NetBoxObjectType, Organizationa
|
||||
from .filters import *
|
||||
from .mixins import IPAddressesMixin
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from dcim.graphql.types import (
|
||||
DeviceType,
|
||||
InterfaceType,
|
||||
LocationType,
|
||||
RackType,
|
||||
RegionType,
|
||||
SiteGroupType,
|
||||
SiteType,
|
||||
)
|
||||
from tenancy.graphql.types import TenantType
|
||||
from virtualization.graphql.types import ClusterGroupType, ClusterType, VMInterfaceType, VirtualMachineType
|
||||
from vpn.graphql.types import L2VPNType, TunnelTerminationType
|
||||
from wireless.graphql.types import WirelessLANType
|
||||
|
||||
__all__ = (
|
||||
'ASNType',
|
||||
'ASNRangeType',
|
||||
@ -101,7 +116,7 @@ class FHRPGroupType(NetBoxObjectType, IPAddressesMixin):
|
||||
|
||||
@strawberry_django.type(
|
||||
models.FHRPGroupAssignment,
|
||||
exclude=('interface_type', 'interface_id'),
|
||||
exclude=['interface_type', 'interface_id'],
|
||||
filters=FHRPGroupAssignmentFilter
|
||||
)
|
||||
class FHRPGroupAssignmentType(BaseObjectType):
|
||||
@ -117,7 +132,7 @@ class FHRPGroupAssignmentType(BaseObjectType):
|
||||
|
||||
@strawberry_django.type(
|
||||
models.IPAddress,
|
||||
exclude=('assigned_object_type', 'assigned_object_id', 'address'),
|
||||
exclude=['assigned_object_type', 'assigned_object_id', 'address'],
|
||||
filters=IPAddressFilter
|
||||
)
|
||||
class IPAddressType(NetBoxObjectType, BaseIPAddressFamilyType):
|
||||
@ -154,7 +169,7 @@ class IPRangeType(NetBoxObjectType):
|
||||
|
||||
@strawberry_django.type(
|
||||
models.Prefix,
|
||||
exclude=('scope_type', 'scope_id', '_location', '_region', '_site', '_site_group'),
|
||||
exclude=['scope_type', 'scope_id', '_location', '_region', '_site', '_site_group'],
|
||||
filters=PrefixFilter
|
||||
)
|
||||
class PrefixType(NetBoxObjectType, BaseIPAddressFamilyType):
|
||||
@ -236,7 +251,7 @@ class ServiceTemplateType(NetBoxObjectType):
|
||||
|
||||
@strawberry_django.type(
|
||||
models.VLAN,
|
||||
exclude=('qinq_svlan',),
|
||||
exclude=['qinq_svlan'],
|
||||
filters=VLANFilter
|
||||
)
|
||||
class VLANType(NetBoxObjectType):
|
||||
@ -259,7 +274,7 @@ class VLANType(NetBoxObjectType):
|
||||
|
||||
@strawberry_django.type(
|
||||
models.VLANGroup,
|
||||
exclude=('scope_type', 'scope_id'),
|
||||
exclude=['scope_type', 'scope_id'],
|
||||
filters=VLANGroupFilter
|
||||
)
|
||||
class VLANGroupType(OrganizationalObjectType):
|
||||
|
13
netbox/netbox/graphql/enums.py
Normal file
13
netbox/netbox/graphql/enums.py
Normal file
@ -0,0 +1,13 @@
|
||||
import strawberry
|
||||
|
||||
from netbox.choices import *
|
||||
|
||||
__all__ = (
|
||||
'ColorEnum',
|
||||
'DistanceUnitEnum',
|
||||
'WeightUnitEnum',
|
||||
)
|
||||
|
||||
ColorEnum = strawberry.enum(ColorChoices.as_enum())
|
||||
DistanceUnitEnum = strawberry.enum(DistanceUnitChoices.as_enum())
|
||||
WeightUnitEnum = strawberry.enum(WeightUnitChoices.as_enum())
|
219
netbox/netbox/graphql/filter_lookups.py
Normal file
219
netbox/netbox/graphql/filter_lookups.py
Normal file
@ -0,0 +1,219 @@
|
||||
from enum import Enum
|
||||
from typing import TypeVar, Tuple, Generic
|
||||
|
||||
import strawberry
|
||||
import strawberry_django
|
||||
from django.core.exceptions import FieldDoesNotExist
|
||||
from django.db.models import Q, QuerySet
|
||||
from django.db.models.fields.related import ForeignKey, ManyToManyField, ManyToManyRel, ManyToOneRel
|
||||
from strawberry import ID
|
||||
from strawberry.types import Info
|
||||
from strawberry_django import (
|
||||
ComparisonFilterLookup,
|
||||
DateFilterLookup,
|
||||
DatetimeFilterLookup,
|
||||
FilterLookup,
|
||||
RangeLookup,
|
||||
TimeFilterLookup,
|
||||
process_filters,
|
||||
)
|
||||
|
||||
__all__ = (
|
||||
'ArrayLookup',
|
||||
'FloatArrayLookup',
|
||||
'FloatLookup',
|
||||
'IntegerArrayLookup',
|
||||
'IntegerLookup',
|
||||
'JSONFilter',
|
||||
'StringArrayLookup',
|
||||
'TreeNodeFilter',
|
||||
)
|
||||
|
||||
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
|
@ -1,209 +1,109 @@
|
||||
from functools import partialmethod
|
||||
from typing import List
|
||||
from dataclasses import dataclass
|
||||
from datetime import datetime
|
||||
from typing import TypeVar, TYPE_CHECKING, Annotated
|
||||
|
||||
import django_filters
|
||||
import strawberry
|
||||
import strawberry_django
|
||||
from django.core.exceptions import FieldDoesNotExist
|
||||
from strawberry import auto
|
||||
from strawberry import ID
|
||||
from strawberry_django import FilterLookup, DatetimeFilterLookup
|
||||
|
||||
from ipam.fields import ASNField
|
||||
from netbox.graphql.scalars import BigInt
|
||||
from utilities.fields import ColorField, CounterCacheField
|
||||
from utilities.filters import *
|
||||
from core.graphql.filter_mixins import BaseFilterMixin, BaseObjectTypeFilterMixin, ChangeLogFilterMixin
|
||||
from extras.graphql.filter_mixins import CustomFieldsFilterMixin, JournalEntriesFilterMixin, TagsFilterMixin
|
||||
from netbox.graphql.filter_lookups import IntegerLookup
|
||||
|
||||
__all__ = (
|
||||
'DistanceFilterMixin',
|
||||
'ImageAttachmentFilterMixin',
|
||||
'NestedGroupModelFilterMixin',
|
||||
'NetBoxModelFilterMixin',
|
||||
'OrganizationalModelFilterMixin',
|
||||
'PrimaryModelFilterMixin',
|
||||
'SyncedDataFilterMixin',
|
||||
'WeightFilterMixin',
|
||||
)
|
||||
|
||||
T = TypeVar('T')
|
||||
|
||||
|
||||
def map_strawberry_type(field):
|
||||
should_create_function = False
|
||||
attr_type = None
|
||||
|
||||
# NetBox Filter types - put base classes after derived classes
|
||||
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
|
||||
if TYPE_CHECKING:
|
||||
from .enums import *
|
||||
from core.graphql.filters import *
|
||||
from extras.graphql.filters import *
|
||||
|
||||
|
||||
def autotype_decorator(filterset):
|
||||
"""
|
||||
Decorator used to auto creates a dataclass used by Strawberry based on a filterset.
|
||||
Must go after the Strawberry decorator as follows:
|
||||
|
||||
@strawberry_django.filter(models.Example, lookups=True)
|
||||
@autotype_decorator(filtersets.ExampleFilterSet)
|
||||
class ExampleFilter(BaseFilterMixin):
|
||||
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):
|
||||
created: auto
|
||||
|
||||
For other filter fields a function needs to be created for Strawberry with the
|
||||
naming convention `filter_{fieldname}` which is auto detected and called by
|
||||
Strawberry, this function uses the filterset to handle the query.
|
||||
"""
|
||||
def create_attribute_and_function(cls, fieldname, attr_type, should_create_function):
|
||||
if fieldname not in cls.__annotations__ and attr_type:
|
||||
cls.__annotations__[fieldname] = attr_type
|
||||
|
||||
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
|
||||
class NetBoxModelFilterMixin(
|
||||
ChangeLogFilterMixin,
|
||||
CustomFieldsFilterMixin,
|
||||
JournalEntriesFilterMixin,
|
||||
TagsFilterMixin,
|
||||
BaseObjectTypeFilterMixin,
|
||||
):
|
||||
pass
|
||||
|
||||
|
||||
@strawberry.input
|
||||
class BaseFilterMixin:
|
||||
@dataclass
|
||||
class NestedGroupModelFilterMixin(NetBoxModelFilterMixin):
|
||||
name: FilterLookup[str] | None = strawberry_django.filter_field()
|
||||
slug: FilterLookup[str] | None = strawberry_django.filter_field()
|
||||
description: FilterLookup[str] | None = strawberry_django.filter_field()
|
||||
lft: IntegerLookup | None = strawberry_django.filter_field()
|
||||
rght: IntegerLookup | None = strawberry_django.filter_field()
|
||||
tree_id: IntegerLookup | None = strawberry_django.filter_field()
|
||||
level: IntegerLookup | None = strawberry_django.filter_field()
|
||||
parent_id: ID | None = strawberry_django.filter_field()
|
||||
|
||||
def filter_by_filterset(self, queryset, key):
|
||||
filterset = self.filterset(data={key: getattr(self, key)}, queryset=queryset)
|
||||
if not filterset.is_valid():
|
||||
# We could raise validation error but strawberry logs it all to the
|
||||
# console i.e. raise ValidationError(f"{k}: {v[0]}")
|
||||
return filterset.qs.none()
|
||||
return filterset.qs
|
||||
|
||||
@dataclass
|
||||
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()
|
||||
|
||||
|
||||
@dataclass
|
||||
class PrimaryModelFilterMixin(NetBoxModelFilterMixin):
|
||||
description: FilterLookup[str] | None = strawberry_django.filter_field()
|
||||
comments: FilterLookup[str] | None = strawberry_django.filter_field()
|
||||
|
||||
|
||||
@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()
|
||||
)
|
||||
|
@ -8,6 +8,7 @@ from extras.graphql.mixins import CustomFieldsMixin, JournalEntriesMixin, TagsMi
|
||||
|
||||
__all__ = (
|
||||
'BaseObjectType',
|
||||
'ContentTypeType',
|
||||
'ObjectType',
|
||||
'OrganizationalObjectType',
|
||||
'NetBoxObjectType',
|
||||
|
@ -787,7 +787,6 @@ LOCALE_PATHS = (
|
||||
STRAWBERRY_DJANGO = {
|
||||
"DEFAULT_PK_FIELD_NAME": "id",
|
||||
"TYPE_DESCRIPTION_FROM_MODEL_DOCSTRING": True,
|
||||
"USE_DEPRECATED_FILTERS": True,
|
||||
}
|
||||
|
||||
#
|
||||
|
@ -99,8 +99,8 @@ class GraphQLAPITestCase(APITestCase):
|
||||
# Test OR logic
|
||||
query = """{
|
||||
location_list( filters: {
|
||||
status: \"""" + LocationStatusChoices.STATUS_PLANNED + """\",
|
||||
OR: {status: \"""" + LocationStatusChoices.STATUS_STAGING + """\"}
|
||||
status: STATUS_PLANNED,
|
||||
OR: {status: STATUS_STAGING}
|
||||
}) {
|
||||
id site {id}
|
||||
}
|
||||
|
9
netbox/tenancy/graphql/enums.py
Normal file
9
netbox/tenancy/graphql/enums.py
Normal file
@ -0,0 +1,9 @@
|
||||
import strawberry
|
||||
|
||||
from tenancy.choices import *
|
||||
|
||||
__all__ = (
|
||||
'ContactPriorityEnum',
|
||||
)
|
||||
|
||||
ContactPriorityEnum = strawberry.enum(ContactPriorityChoices.as_enum())
|
38
netbox/tenancy/graphql/filter_mixins.py
Normal file
38
netbox/tenancy/graphql/filter_mixins.py
Normal file
@ -0,0 +1,38 @@
|
||||
from dataclasses import dataclass
|
||||
from typing import Annotated, TYPE_CHECKING
|
||||
|
||||
import strawberry
|
||||
import strawberry_django
|
||||
from strawberry import ID
|
||||
|
||||
from core.graphql.filter_mixins import BaseFilterMixin
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from netbox.graphql.filter_lookups import TreeNodeFilter
|
||||
from .filters import ContactFilter, TenantFilter, TenantGroupFilter
|
||||
|
||||
__all__ = (
|
||||
'ContactFilterMixin',
|
||||
'TenancyFilterMixin',
|
||||
)
|
||||
|
||||
|
||||
@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()
|
||||
tenant_group: Annotated['TenantGroupFilter', strawberry.lazy('tenancy.graphql.filters')] | None = (
|
||||
strawberry_django.filter_field()
|
||||
)
|
||||
tenant_group_id: Annotated['TreeNodeFilter', strawberry.lazy('netbox.graphql.filter_lookups')] | None = (
|
||||
strawberry_django.filter_field()
|
||||
)
|
@ -1,7 +1,49 @@
|
||||
import strawberry_django
|
||||
from typing import Annotated, TYPE_CHECKING
|
||||
|
||||
from netbox.graphql.filter_mixins import autotype_decorator, BaseFilterMixin
|
||||
from tenancy import filtersets, models
|
||||
import strawberry
|
||||
import strawberry_django
|
||||
from strawberry.scalars import ID
|
||||
from strawberry_django import FilterLookup
|
||||
|
||||
from core.graphql.filter_mixins import ChangeLogFilterMixin
|
||||
from extras.graphql.filter_mixins import CustomFieldsFilterMixin, TagsFilterMixin
|
||||
from netbox.graphql.filter_mixins import (
|
||||
NestedGroupModelFilterMixin,
|
||||
OrganizationalModelFilterMixin,
|
||||
PrimaryModelFilterMixin,
|
||||
)
|
||||
from tenancy import models
|
||||
from .filter_mixins import ContactFilterMixin
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from core.graphql.filters import ContentTypeFilter
|
||||
from circuits.graphql.filters import CircuitFilter
|
||||
from dcim.graphql.filters import (
|
||||
CableFilter,
|
||||
DeviceFilter,
|
||||
LocationFilter,
|
||||
PowerFeedFilter,
|
||||
RackFilter,
|
||||
RackReservationFilter,
|
||||
SiteFilter,
|
||||
VirtualDeviceContextFilter,
|
||||
)
|
||||
from ipam.graphql.filters import (
|
||||
AggregateFilter,
|
||||
ASNFilter,
|
||||
ASNRangeFilter,
|
||||
IPAddressFilter,
|
||||
IPRangeFilter,
|
||||
PrefixFilter,
|
||||
RouteTargetFilter,
|
||||
VLANFilter,
|
||||
VRFFilter,
|
||||
)
|
||||
from netbox.graphql.filter_lookups import TreeNodeFilter
|
||||
from wireless.graphql.filters import WirelessLANFilter, WirelessLinkFilter
|
||||
from virtualization.graphql.filters import ClusterFilter, VirtualMachineFilter
|
||||
from vpn.graphql.filters import L2VPNFilter, TunnelFilter
|
||||
from .enums import *
|
||||
|
||||
__all__ = (
|
||||
'TenantFilter',
|
||||
@ -14,36 +56,132 @@ __all__ = (
|
||||
|
||||
|
||||
@strawberry_django.filter(models.Tenant, lookups=True)
|
||||
@autotype_decorator(filtersets.TenantFilterSet)
|
||||
class TenantFilter(BaseFilterMixin):
|
||||
pass
|
||||
class TenantFilter(PrimaryModelFilterMixin, ContactFilterMixin):
|
||||
name: FilterLookup[str] | None = strawberry_django.filter_field()
|
||||
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('netbox.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)
|
||||
@autotype_decorator(filtersets.TenantGroupFilterSet)
|
||||
class TenantGroupFilter(BaseFilterMixin):
|
||||
pass
|
||||
class TenantGroupFilter(OrganizationalModelFilterMixin):
|
||||
parent: Annotated['TenantGroupFilter', strawberry.lazy('tenancy.graphql.filters')] | None = (
|
||||
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)
|
||||
@autotype_decorator(filtersets.ContactFilterSet)
|
||||
class ContactFilter(BaseFilterMixin):
|
||||
pass
|
||||
class ContactFilter(PrimaryModelFilterMixin):
|
||||
name: FilterLookup[str] | None = strawberry_django.filter_field()
|
||||
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('netbox.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)
|
||||
@autotype_decorator(filtersets.ContactRoleFilterSet)
|
||||
class ContactRoleFilter(BaseFilterMixin):
|
||||
class ContactRoleFilter(OrganizationalModelFilterMixin):
|
||||
pass
|
||||
|
||||
|
||||
@strawberry_django.filter(models.ContactGroup, lookups=True)
|
||||
@autotype_decorator(filtersets.ContactGroupFilterSet)
|
||||
class ContactGroupFilter(BaseFilterMixin):
|
||||
pass
|
||||
class ContactGroupFilter(NestedGroupModelFilterMixin):
|
||||
parent: Annotated['ContactGroupFilter', strawberry.lazy('tenancy.graphql.filters')] | None = (
|
||||
strawberry_django.filter_field()
|
||||
)
|
||||
|
||||
|
||||
@strawberry_django.filter(models.ContactAssignment, lookups=True)
|
||||
@autotype_decorator(filtersets.ContactAssignmentFilterSet)
|
||||
class ContactAssignmentFilter(BaseFilterMixin):
|
||||
pass
|
||||
class ContactAssignmentFilter(CustomFieldsFilterMixin, TagsFilterMixin, ChangeLogFilterMixin):
|
||||
object_type: Annotated['ContentTypeFilter', strawberry.lazy('core.graphql.filters')] | None = (
|
||||
strawberry_django.filter_field()
|
||||
)
|
||||
object_id: ID | None = strawberry_django.filter_field()
|
||||
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: Annotated['ContactPriorityEnum', strawberry.lazy('tenancy.graphql.enums')] | None = (
|
||||
strawberry_django.filter_field()
|
||||
)
|
||||
|
@ -9,5 +9,4 @@ __all__ = (
|
||||
|
||||
@strawberry.type
|
||||
class ContactAssignmentsMixin:
|
||||
|
||||
assignments: List[Annotated["ContactAssignmentType", strawberry.lazy('tenancy.graphql.types')]] # noqa: F821
|
||||
|
@ -1,4 +1,4 @@
|
||||
from typing import Annotated, List
|
||||
from typing import Annotated, List, TYPE_CHECKING
|
||||
|
||||
import strawberry
|
||||
import strawberry_django
|
||||
@ -6,8 +6,36 @@ import strawberry_django
|
||||
from extras.graphql.mixins import CustomFieldsMixin, TagsMixin
|
||||
from netbox.graphql.types import BaseObjectType, OrganizationalObjectType, NetBoxObjectType
|
||||
from tenancy import models
|
||||
from .mixins import ContactAssignmentsMixin
|
||||
from .filters import *
|
||||
from .mixins import ContactAssignmentsMixin
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from circuits.graphql.types import CircuitType
|
||||
from dcim.graphql.types import (
|
||||
CableType,
|
||||
DeviceType,
|
||||
LocationType,
|
||||
PowerFeedType,
|
||||
RackType,
|
||||
RackReservationType,
|
||||
SiteType,
|
||||
VirtualDeviceContextType,
|
||||
)
|
||||
from ipam.graphql.types import (
|
||||
AggregateType,
|
||||
ASNType,
|
||||
ASNRangeType,
|
||||
IPAddressType,
|
||||
IPRangeType,
|
||||
PrefixType,
|
||||
RouteTargetType,
|
||||
VLANType,
|
||||
VRFType,
|
||||
)
|
||||
from netbox.graphql.types import ContentTypeType
|
||||
from wireless.graphql.types import WirelessLANType, WirelessLinkType
|
||||
from virtualization.graphql.types import ClusterType, VirtualMachineType
|
||||
from vpn.graphql.types import L2VPNType, TunnelType
|
||||
|
||||
__all__ = (
|
||||
'ContactAssignmentType',
|
||||
@ -23,92 +51,70 @@ __all__ = (
|
||||
# Tenants
|
||||
#
|
||||
|
||||
@strawberry_django.type(
|
||||
models.Tenant,
|
||||
fields='__all__',
|
||||
filters=TenantFilter
|
||||
)
|
||||
|
||||
@strawberry_django.type(models.Tenant, fields='__all__', filters=TenantFilter)
|
||||
class TenantType(NetBoxObjectType):
|
||||
group: Annotated["TenantGroupType", strawberry.lazy('tenancy.graphql.types')] | None
|
||||
|
||||
asns: List[Annotated["ASNType", strawberry.lazy('ipam.graphql.types')]]
|
||||
circuits: List[Annotated["CircuitType", strawberry.lazy('circuits.graphql.types')]]
|
||||
sites: List[Annotated["SiteType", strawberry.lazy('dcim.graphql.types')]]
|
||||
vlans: List[Annotated["VLANType", strawberry.lazy('ipam.graphql.types')]]
|
||||
wireless_lans: List[Annotated["WirelessLANType", strawberry.lazy('wireless.graphql.types')]]
|
||||
route_targets: List[Annotated["RouteTargetType", strawberry.lazy('ipam.graphql.types')]]
|
||||
locations: List[Annotated["LocationType", strawberry.lazy('dcim.graphql.types')]]
|
||||
ip_ranges: List[Annotated["IPRangeType", strawberry.lazy('ipam.graphql.types')]]
|
||||
rackreservations: List[Annotated["RackReservationType", strawberry.lazy('dcim.graphql.types')]]
|
||||
racks: List[Annotated["RackType", strawberry.lazy('dcim.graphql.types')]]
|
||||
vdcs: List[Annotated["VirtualDeviceContextType", strawberry.lazy('dcim.graphql.types')]]
|
||||
prefixes: List[Annotated["PrefixType", strawberry.lazy('ipam.graphql.types')]]
|
||||
cables: List[Annotated["CableType", strawberry.lazy('dcim.graphql.types')]]
|
||||
virtual_machines: List[Annotated["VirtualMachineType", strawberry.lazy('virtualization.graphql.types')]]
|
||||
vrfs: List[Annotated["VRFType", 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')]]
|
||||
aggregates: List[Annotated["AggregateType", strawberry.lazy('ipam.graphql.types')]]
|
||||
power_feeds: List[Annotated["PowerFeedType", strawberry.lazy('dcim.graphql.types')]]
|
||||
devices: List[Annotated["DeviceType", strawberry.lazy('dcim.graphql.types')]]
|
||||
tunnels: List[Annotated["TunnelType", strawberry.lazy('vpn.graphql.types')]]
|
||||
ip_addresses: List[Annotated["IPAddressType", strawberry.lazy('ipam.graphql.types')]]
|
||||
clusters: List[Annotated["ClusterType", strawberry.lazy('virtualization.graphql.types')]]
|
||||
l2vpns: List[Annotated["L2VPNType", strawberry.lazy('vpn.graphql.types')]]
|
||||
group: Annotated['TenantGroupType', strawberry.lazy('tenancy.graphql.types')] | None
|
||||
contacts: List[Annotated['ContactType', strawberry.lazy('tenancy.graphql.types')]]
|
||||
asns: List[Annotated['ASNType', strawberry.lazy('ipam.graphql.types')]]
|
||||
circuits: List[Annotated['CircuitType', strawberry.lazy('circuits.graphql.types')]]
|
||||
sites: List[Annotated['SiteType', strawberry.lazy('dcim.graphql.types')]]
|
||||
vlans: List[Annotated['VLANType', strawberry.lazy('ipam.graphql.types')]]
|
||||
wireless_lans: List[Annotated['WirelessLANType', strawberry.lazy('wireless.graphql.types')]]
|
||||
route_targets: List[Annotated['RouteTargetType', strawberry.lazy('ipam.graphql.types')]]
|
||||
locations: List[Annotated['LocationType', strawberry.lazy('dcim.graphql.types')]]
|
||||
ip_ranges: List[Annotated['IPRangeType', strawberry.lazy('ipam.graphql.types')]]
|
||||
rackreservations: List[Annotated['RackReservationType', strawberry.lazy('dcim.graphql.types')]]
|
||||
racks: List[Annotated['RackType', strawberry.lazy('dcim.graphql.types')]]
|
||||
vdcs: List[Annotated['VirtualDeviceContextType', strawberry.lazy('dcim.graphql.types')]]
|
||||
prefixes: List[Annotated['PrefixType', strawberry.lazy('ipam.graphql.types')]]
|
||||
cables: List[Annotated['CableType', strawberry.lazy('dcim.graphql.types')]]
|
||||
virtual_machines: List[Annotated['VirtualMachineType', strawberry.lazy('virtualization.graphql.types')]]
|
||||
vrfs: List[Annotated['VRFType', 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')]]
|
||||
aggregates: List[Annotated['AggregateType', strawberry.lazy('ipam.graphql.types')]]
|
||||
power_feeds: List[Annotated['PowerFeedType', strawberry.lazy('dcim.graphql.types')]]
|
||||
devices: List[Annotated['DeviceType', strawberry.lazy('dcim.graphql.types')]]
|
||||
tunnels: List[Annotated['TunnelType', strawberry.lazy('vpn.graphql.types')]]
|
||||
ip_addresses: List[Annotated['IPAddressType', strawberry.lazy('ipam.graphql.types')]]
|
||||
clusters: List[Annotated['ClusterType', strawberry.lazy('virtualization.graphql.types')]]
|
||||
l2vpns: List[Annotated['L2VPNType', strawberry.lazy('vpn.graphql.types')]]
|
||||
|
||||
|
||||
@strawberry_django.type(
|
||||
models.TenantGroup,
|
||||
fields='__all__',
|
||||
filters=TenantGroupFilter
|
||||
)
|
||||
@strawberry_django.type(models.TenantGroup, fields='__all__', filters=TenantGroupFilter)
|
||||
class TenantGroupType(OrganizationalObjectType):
|
||||
parent: Annotated["TenantGroupType", strawberry.lazy('tenancy.graphql.types')] | None
|
||||
parent: Annotated['TenantGroupType', strawberry.lazy('tenancy.graphql.types')] | None
|
||||
|
||||
tenants: List[TenantType]
|
||||
children: List[Annotated["TenantGroupType", strawberry.lazy('tenancy.graphql.types')]]
|
||||
children: List[Annotated['TenantGroupType', strawberry.lazy('tenancy.graphql.types')]]
|
||||
|
||||
|
||||
#
|
||||
# Contacts
|
||||
#
|
||||
|
||||
@strawberry_django.type(
|
||||
models.Contact,
|
||||
fields='__all__',
|
||||
filters=ContactFilter
|
||||
)
|
||||
|
||||
@strawberry_django.type(models.Contact, fields='__all__', filters=ContactFilter)
|
||||
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(
|
||||
models.ContactRole,
|
||||
fields='__all__',
|
||||
filters=ContactRoleFilter
|
||||
)
|
||||
@strawberry_django.type(models.ContactRole, fields='__all__', filters=ContactRoleFilter)
|
||||
class ContactRoleType(ContactAssignmentsMixin, OrganizationalObjectType):
|
||||
pass
|
||||
|
||||
|
||||
@strawberry_django.type(
|
||||
models.ContactGroup,
|
||||
fields='__all__',
|
||||
filters=ContactGroupFilter
|
||||
)
|
||||
@strawberry_django.type(models.ContactGroup, fields='__all__', filters=ContactGroupFilter)
|
||||
class ContactGroupType(OrganizationalObjectType):
|
||||
parent: Annotated["ContactGroupType", strawberry.lazy('tenancy.graphql.types')] | None
|
||||
parent: Annotated['ContactGroupType', strawberry.lazy('tenancy.graphql.types')] | None
|
||||
|
||||
contacts: List[ContactType]
|
||||
children: List[Annotated["ContactGroupType", strawberry.lazy('tenancy.graphql.types')]]
|
||||
children: List[Annotated['ContactGroupType', strawberry.lazy('tenancy.graphql.types')]]
|
||||
|
||||
|
||||
@strawberry_django.type(
|
||||
models.ContactAssignment,
|
||||
fields='__all__',
|
||||
filters=ContactAssignmentFilter
|
||||
)
|
||||
@strawberry_django.type(models.ContactAssignment, fields='__all__', filters=ContactAssignmentFilter)
|
||||
class ContactAssignmentType(CustomFieldsMixin, TagsMixin, BaseObjectType):
|
||||
object_type: Annotated["ContentTypeType", strawberry.lazy('netbox.graphql.types')] | None
|
||||
contact: Annotated["ContactType", strawberry.lazy('tenancy.graphql.types')] | None
|
||||
role: Annotated["ContactRoleType", strawberry.lazy('tenancy.graphql.types')] | None
|
||||
object_type: Annotated['ContentTypeType', strawberry.lazy('netbox.graphql.types')] | None
|
||||
contact: Annotated['ContactType', strawberry.lazy('tenancy.graphql.types')] | None
|
||||
role: Annotated['ContactRoleType', strawberry.lazy('tenancy.graphql.types')] | None
|
||||
|
@ -1,7 +1,12 @@
|
||||
import strawberry_django
|
||||
from datetime import datetime
|
||||
from typing import Annotated
|
||||
|
||||
from netbox.graphql.filter_mixins import autotype_decorator, BaseFilterMixin
|
||||
from users import filtersets, models
|
||||
import strawberry
|
||||
import strawberry_django
|
||||
from strawberry_django import DatetimeFilterLookup, FilterLookup
|
||||
|
||||
from core.graphql.filter_mixins import BaseObjectTypeFilterMixin
|
||||
from users import models
|
||||
|
||||
__all__ = (
|
||||
'GroupFilter',
|
||||
@ -10,12 +15,20 @@ __all__ = (
|
||||
|
||||
|
||||
@strawberry_django.filter(models.Group, lookups=True)
|
||||
@autotype_decorator(filtersets.GroupFilterSet)
|
||||
class GroupFilter(BaseFilterMixin):
|
||||
pass
|
||||
class GroupFilter(BaseObjectTypeFilterMixin):
|
||||
name: FilterLookup[str] | None = strawberry_django.filter_field()
|
||||
description: FilterLookup[str] | None = strawberry_django.filter_field()
|
||||
|
||||
|
||||
@strawberry_django.filter(models.User, lookups=True)
|
||||
@autotype_decorator(filtersets.UserFilterSet)
|
||||
class UserFilter(BaseFilterMixin):
|
||||
pass
|
||||
class UserFilter(BaseObjectTypeFilterMixin):
|
||||
username: FilterLookup[str] | None = strawberry_django.filter_field()
|
||||
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_superuser: FilterLookup[bool] | 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()
|
||||
last_login: DatetimeFilterLookup[datetime] | None = strawberry_django.filter_field()
|
||||
groups: Annotated['GroupFilter', strawberry.lazy('users.graphql.filters')] | None = strawberry_django.filter_field()
|
||||
|
@ -1,3 +1,5 @@
|
||||
import enum
|
||||
|
||||
from django.conf import settings
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
@ -65,6 +67,23 @@ class ChoiceSet(metaclass=ChoiceSetMeta):
|
||||
def values(cls):
|
||||
return [c[0] for c in unpack_grouped_choices(cls._choices)]
|
||||
|
||||
@classmethod
|
||||
def as_enum(cls, name=None):
|
||||
"""
|
||||
Return the ChoiceSet as an Enum. If no name is provided, "Choices" will be stripped from the class name (if
|
||||
present) and "Enum" will be appended. For example, "CircuitStatusChoices" will become "CircuitStatusEnum".
|
||||
"""
|
||||
name = name or f"{cls.__name__.split('Choices')[0]}Enum"
|
||||
data = {}
|
||||
choices = cls.values()
|
||||
|
||||
for attr in dir(cls):
|
||||
value = getattr(cls, attr)
|
||||
if attr.isupper() and value in choices:
|
||||
data[attr] = value
|
||||
|
||||
return enum.Enum(name, data)
|
||||
|
||||
|
||||
def unpack_grouped_choices(choices):
|
||||
"""
|
||||
|
11
netbox/virtualization/graphql/enums.py
Normal file
11
netbox/virtualization/graphql/enums.py
Normal file
@ -0,0 +1,11 @@
|
||||
import strawberry
|
||||
|
||||
from virtualization.choices import *
|
||||
|
||||
__all__ = (
|
||||
'ClusterStatusEnum',
|
||||
'VirtualMachineStatusEnum',
|
||||
)
|
||||
|
||||
ClusterStatusEnum = strawberry.enum(ClusterStatusChoices.as_enum())
|
||||
VirtualMachineStatusEnum = strawberry.enum(VirtualMachineStatusChoices.as_enum())
|
26
netbox/virtualization/graphql/filter_mixins.py
Normal file
26
netbox/virtualization/graphql/filter_mixins.py
Normal file
@ -0,0 +1,26 @@
|
||||
from dataclasses import dataclass
|
||||
from typing import Annotated, TYPE_CHECKING
|
||||
|
||||
import strawberry
|
||||
import strawberry_django
|
||||
from strawberry import ID
|
||||
from strawberry_django import FilterLookup
|
||||
|
||||
from netbox.graphql.filter_mixins import NetBoxModelFilterMixin
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from .filters import VirtualMachineFilter
|
||||
|
||||
__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()
|
@ -1,7 +1,33 @@
|
||||
import strawberry_django
|
||||
from typing import Annotated, TYPE_CHECKING
|
||||
|
||||
from netbox.graphql.filter_mixins import autotype_decorator, BaseFilterMixin
|
||||
from virtualization import filtersets, models
|
||||
import strawberry
|
||||
import strawberry_django
|
||||
from strawberry.scalars import ID
|
||||
from strawberry_django import FilterLookup
|
||||
|
||||
from dcim.graphql.filter_mixins import InterfaceBaseFilterMixin, RenderConfigFilterMixin, ScopedFilterMixin
|
||||
from extras.graphql.filter_mixins import ConfigContextFilterMixin
|
||||
from netbox.graphql.filter_mixins import (
|
||||
ImageAttachmentFilterMixin,
|
||||
OrganizationalModelFilterMixin,
|
||||
PrimaryModelFilterMixin,
|
||||
)
|
||||
from tenancy.graphql.filter_mixins import ContactFilterMixin, TenancyFilterMixin
|
||||
from virtualization import models
|
||||
from virtualization.graphql.filter_mixins import VMComponentFilterMixin
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from .enums import *
|
||||
from netbox.graphql.filter_lookups import FloatLookup, IntegerLookup
|
||||
from dcim.graphql.filters import DeviceFilter, DeviceRoleFilter, MACAddressFilter, PlatformFilter, SiteFilter
|
||||
from ipam.graphql.filters import (
|
||||
FHRPGroupAssignmentFilter,
|
||||
IPAddressFilter,
|
||||
ServiceFilter,
|
||||
VLANGroupFilter,
|
||||
VRFFilter,
|
||||
)
|
||||
from vpn.graphql.filters import L2VPNFilter, TunnelTerminationFilter
|
||||
|
||||
__all__ = (
|
||||
'ClusterFilter',
|
||||
@ -14,36 +40,119 @@ __all__ = (
|
||||
|
||||
|
||||
@strawberry_django.filter(models.Cluster, lookups=True)
|
||||
@autotype_decorator(filtersets.ClusterFilterSet)
|
||||
class ClusterFilter(BaseFilterMixin):
|
||||
pass
|
||||
class ClusterFilter(ContactFilterMixin, ScopedFilterMixin, TenancyFilterMixin, PrimaryModelFilterMixin):
|
||||
name: FilterLookup[str] | None = strawberry_django.filter_field()
|
||||
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()
|
||||
)
|
||||
vlan_groups: Annotated['VLANGroupFilter', strawberry.lazy('ipam.graphql.filters')] | None = (
|
||||
strawberry_django.filter_field()
|
||||
)
|
||||
|
||||
|
||||
@strawberry_django.filter(models.ClusterGroup, lookups=True)
|
||||
@autotype_decorator(filtersets.ClusterGroupFilterSet)
|
||||
class ClusterGroupFilter(BaseFilterMixin):
|
||||
pass
|
||||
class ClusterGroupFilter(ContactFilterMixin, OrganizationalModelFilterMixin):
|
||||
vlan_groups: Annotated['VLANGroupFilter', strawberry.lazy('ipam.graphql.filters')] | None = (
|
||||
strawberry_django.filter_field()
|
||||
)
|
||||
|
||||
|
||||
@strawberry_django.filter(models.ClusterType, lookups=True)
|
||||
@autotype_decorator(filtersets.ClusterTypeFilterSet)
|
||||
class ClusterTypeFilter(BaseFilterMixin):
|
||||
class ClusterTypeFilter(OrganizationalModelFilterMixin):
|
||||
pass
|
||||
|
||||
|
||||
@strawberry_django.filter(models.VirtualMachine, lookups=True)
|
||||
@autotype_decorator(filtersets.VirtualMachineFilterSet)
|
||||
class VirtualMachineFilter(BaseFilterMixin):
|
||||
pass
|
||||
class VirtualMachineFilter(
|
||||
ContactFilterMixin,
|
||||
ImageAttachmentFilterMixin,
|
||||
RenderConfigFilterMixin,
|
||||
ConfigContextFilterMixin,
|
||||
TenancyFilterMixin,
|
||||
PrimaryModelFilterMixin,
|
||||
):
|
||||
name: 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()
|
||||
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()
|
||||
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('netbox.graphql.filter_lookups')] | None = (
|
||||
strawberry_django.filter_field()
|
||||
)
|
||||
memory: Annotated['IntegerLookup', strawberry.lazy('netbox.graphql.filter_lookups')] | None = (
|
||||
strawberry_django.filter_field()
|
||||
)
|
||||
disk: Annotated['IntegerLookup', strawberry.lazy('netbox.graphql.filter_lookups')] | None = (
|
||||
strawberry_django.filter_field()
|
||||
)
|
||||
serial: FilterLookup[str] | None = strawberry_django.filter_field()
|
||||
interface_count: FilterLookup[int] | None = strawberry_django.filter_field()
|
||||
virtual_disk_count: FilterLookup[int] | 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)
|
||||
@autotype_decorator(filtersets.VMInterfaceFilterSet)
|
||||
class VMInterfaceFilter(BaseFilterMixin):
|
||||
pass
|
||||
class VMInterfaceFilter(VMComponentFilterMixin, InterfaceBaseFilterMixin):
|
||||
ip_addresses: Annotated['IPAddressFilter', strawberry.lazy('ipam.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()
|
||||
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)
|
||||
@autotype_decorator(filtersets.VirtualDiskFilterSet)
|
||||
class VirtualDiskFilter(BaseFilterMixin):
|
||||
pass
|
||||
class VirtualDiskFilter(VMComponentFilterMixin):
|
||||
size: Annotated['IntegerLookup', strawberry.lazy('netbox.graphql.filter_lookups')] | None = (
|
||||
strawberry_django.filter_field()
|
||||
)
|
||||
|
@ -1,4 +1,4 @@
|
||||
from typing import Annotated, List, Union
|
||||
from typing import Annotated, List, TYPE_CHECKING, Union
|
||||
|
||||
import strawberry
|
||||
import strawberry_django
|
||||
@ -10,6 +10,21 @@ from netbox.graphql.types import OrganizationalObjectType, NetBoxObjectType
|
||||
from virtualization import models
|
||||
from .filters import *
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from dcim.graphql.types import (
|
||||
DeviceRoleType,
|
||||
DeviceType,
|
||||
LocationType,
|
||||
MACAddressType,
|
||||
PlatformType,
|
||||
RegionType,
|
||||
SiteGroupType,
|
||||
SiteType,
|
||||
)
|
||||
from extras.graphql.types import ConfigTemplateType
|
||||
from ipam.graphql.types import IPAddressType, ServiceType, VLANTranslationPolicyType, VLANType, VRFType
|
||||
from tenancy.graphql.types import TenantType
|
||||
|
||||
__all__ = (
|
||||
'ClusterType',
|
||||
'ClusterGroupType',
|
||||
@ -30,7 +45,7 @@ class ComponentType(NetBoxObjectType):
|
||||
|
||||
@strawberry_django.type(
|
||||
models.Cluster,
|
||||
exclude=('scope_type', 'scope_id', '_location', '_region', '_site', '_site_group'),
|
||||
exclude=['scope_type', 'scope_id', '_location', '_region', '_site', '_site_group'],
|
||||
filters=ClusterFilter
|
||||
)
|
||||
class ClusterType(VLANGroupsMixin, NetBoxObjectType):
|
||||
|
31
netbox/vpn/graphql/enums.py
Normal file
31
netbox/vpn/graphql/enums.py
Normal file
@ -0,0 +1,31 @@
|
||||
import strawberry
|
||||
|
||||
from vpn.choices import *
|
||||
|
||||
__all__ = (
|
||||
'AuthenticationAlgorithmEnum',
|
||||
'AuthenticationMethodEnum',
|
||||
'DHGroupEnum',
|
||||
'EncryptionAlgorithmEnum',
|
||||
'IKEModeEnum',
|
||||
'IKEVersionEnum',
|
||||
'IPSecModeEnum',
|
||||
'L2VPNTypeEnum',
|
||||
'TunnelEncapsulationEnum',
|
||||
'TunnelStatusEnum',
|
||||
'TunnelTerminationRoleEnum',
|
||||
'TunnelTerminationTypeEnum',
|
||||
)
|
||||
|
||||
AuthenticationAlgorithmEnum = strawberry.enum(AuthenticationAlgorithmChoices.as_enum())
|
||||
AuthenticationMethodEnum = strawberry.enum(AuthenticationMethodChoices.as_enum())
|
||||
DHGroupEnum = strawberry.enum(DHGroupChoices.as_enum())
|
||||
EncryptionAlgorithmEnum = strawberry.enum(EncryptionAlgorithmChoices.as_enum())
|
||||
IKEModeEnum = strawberry.enum(IKEModeChoices.as_enum())
|
||||
IKEVersionEnum = strawberry.enum(IKEVersionChoices.as_enum())
|
||||
IPSecModeEnum = strawberry.enum(IPSecModeChoices.as_enum())
|
||||
L2VPNTypeEnum = strawberry.enum(L2VPNTypeChoices.as_enum())
|
||||
TunnelEncapsulationEnum = strawberry.enum(TunnelEncapsulationChoices.as_enum())
|
||||
TunnelStatusEnum = strawberry.enum(TunnelStatusChoices.as_enum())
|
||||
TunnelTerminationRoleEnum = strawberry.enum(TunnelTerminationRoleChoices.as_enum())
|
||||
TunnelTerminationTypeEnum = strawberry.enum(TunnelTerminationTypeChoices.as_enum())
|
@ -1,7 +1,21 @@
|
||||
import strawberry_django
|
||||
from typing import Annotated, TYPE_CHECKING
|
||||
|
||||
from netbox.graphql.filter_mixins import autotype_decorator, BaseFilterMixin
|
||||
from vpn import filtersets, models
|
||||
import strawberry
|
||||
import strawberry_django
|
||||
from strawberry.scalars import ID
|
||||
from strawberry_django import FilterLookup
|
||||
|
||||
from core.graphql.filter_mixins import BaseObjectTypeFilterMixin, ChangeLogFilterMixin
|
||||
from extras.graphql.filter_mixins import CustomFieldsFilterMixin, TagsFilterMixin
|
||||
from netbox.graphql.filter_mixins import NetBoxModelFilterMixin, OrganizationalModelFilterMixin, PrimaryModelFilterMixin
|
||||
from tenancy.graphql.filter_mixins import ContactFilterMixin, TenancyFilterMixin
|
||||
from vpn import models
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from core.graphql.filters import ContentTypeFilter
|
||||
from ipam.graphql.filters import IPAddressFilter, RouteTargetFilter
|
||||
from netbox.graphql.filter_lookups import IntegerLookup
|
||||
from .enums import *
|
||||
|
||||
__all__ = (
|
||||
'TunnelGroupFilter',
|
||||
@ -18,60 +32,143 @@ __all__ = (
|
||||
|
||||
|
||||
@strawberry_django.filter(models.TunnelGroup, lookups=True)
|
||||
@autotype_decorator(filtersets.TunnelGroupFilterSet)
|
||||
class TunnelGroupFilter(BaseFilterMixin):
|
||||
class TunnelGroupFilter(OrganizationalModelFilterMixin):
|
||||
pass
|
||||
|
||||
|
||||
@strawberry_django.filter(models.TunnelTermination, lookups=True)
|
||||
@autotype_decorator(filtersets.TunnelTerminationFilterSet)
|
||||
class TunnelTerminationFilter(BaseFilterMixin):
|
||||
pass
|
||||
class TunnelTerminationFilter(
|
||||
BaseObjectTypeFilterMixin, CustomFieldsFilterMixin, TagsFilterMixin, ChangeLogFilterMixin
|
||||
):
|
||||
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)
|
||||
@autotype_decorator(filtersets.TunnelFilterSet)
|
||||
class TunnelFilter(BaseFilterMixin):
|
||||
pass
|
||||
class TunnelFilter(TenancyFilterMixin, PrimaryModelFilterMixin):
|
||||
name: FilterLookup[str] | None = strawberry_django.filter_field()
|
||||
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()
|
||||
)
|
||||
tunnel_id: Annotated['IntegerLookup', strawberry.lazy('netbox.graphql.filter_lookups')] | None = (
|
||||
strawberry_django.filter_field()
|
||||
)
|
||||
|
||||
|
||||
@strawberry_django.filter(models.IKEProposal, lookups=True)
|
||||
@autotype_decorator(filtersets.IKEProposalFilterSet)
|
||||
class IKEProposalFilter(BaseFilterMixin):
|
||||
pass
|
||||
class IKEProposalFilter(PrimaryModelFilterMixin):
|
||||
name: FilterLookup[str] | None = strawberry_django.filter_field()
|
||||
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('netbox.graphql.filter_lookups')] | None = (
|
||||
strawberry_django.filter_field()
|
||||
)
|
||||
|
||||
|
||||
@strawberry_django.filter(models.IKEPolicy, lookups=True)
|
||||
@autotype_decorator(filtersets.IKEPolicyFilterSet)
|
||||
class IKEPolicyFilter(BaseFilterMixin):
|
||||
pass
|
||||
class IKEPolicyFilter(PrimaryModelFilterMixin):
|
||||
name: FilterLookup[str] | None = strawberry_django.filter_field()
|
||||
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)
|
||||
@autotype_decorator(filtersets.IPSecProposalFilterSet)
|
||||
class IPSecProposalFilter(BaseFilterMixin):
|
||||
pass
|
||||
class IPSecProposalFilter(PrimaryModelFilterMixin):
|
||||
name: FilterLookup[str] | 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()
|
||||
)
|
||||
sa_lifetime_seconds: Annotated['IntegerLookup', strawberry.lazy('netbox.graphql.filter_lookups')] | None = (
|
||||
strawberry_django.filter_field()
|
||||
)
|
||||
sa_lifetime_data: Annotated['IntegerLookup', strawberry.lazy('netbox.graphql.filter_lookups')] | None = (
|
||||
strawberry_django.filter_field()
|
||||
)
|
||||
|
||||
|
||||
@strawberry_django.filter(models.IPSecPolicy, lookups=True)
|
||||
@autotype_decorator(filtersets.IPSecPolicyFilterSet)
|
||||
class IPSecPolicyFilter(BaseFilterMixin):
|
||||
pass
|
||||
class IPSecPolicyFilter(PrimaryModelFilterMixin):
|
||||
name: FilterLookup[str] | None = strawberry_django.filter_field()
|
||||
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)
|
||||
@autotype_decorator(filtersets.IPSecProfileFilterSet)
|
||||
class IPSecProfileFilter(BaseFilterMixin):
|
||||
pass
|
||||
class IPSecProfileFilter(PrimaryModelFilterMixin):
|
||||
name: FilterLookup[str] | None = strawberry_django.filter_field()
|
||||
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)
|
||||
@autotype_decorator(filtersets.L2VPNFilterSet)
|
||||
class L2VPNFilter(BaseFilterMixin):
|
||||
pass
|
||||
class L2VPNFilter(ContactFilterMixin, TenancyFilterMixin, PrimaryModelFilterMixin):
|
||||
name: FilterLookup[str] | None = strawberry_django.filter_field()
|
||||
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('netbox.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()
|
||||
)
|
||||
|
||||
|
||||
@strawberry_django.filter(models.L2VPNTermination, lookups=True)
|
||||
@autotype_decorator(filtersets.L2VPNTerminationFilterSet)
|
||||
class L2VPNTerminationFilter(BaseFilterMixin):
|
||||
pass
|
||||
class L2VPNTerminationFilter(NetBoxModelFilterMixin):
|
||||
l2vpn: Annotated['L2VPNFilter', strawberry.lazy('vpn.graphql.filters')] | None = strawberry_django.filter_field()
|
||||
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('netbox.graphql.filter_lookups')] | None = (
|
||||
strawberry_django.filter_field()
|
||||
)
|
||||
|
@ -1,4 +1,4 @@
|
||||
from typing import Annotated, List, Union
|
||||
from typing import Annotated, List, TYPE_CHECKING, Union
|
||||
|
||||
import strawberry
|
||||
import strawberry_django
|
||||
@ -8,6 +8,13 @@ from netbox.graphql.types import ObjectType, OrganizationalObjectType, NetBoxObj
|
||||
from vpn import models
|
||||
from .filters import *
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from dcim.graphql.types import InterfaceType
|
||||
from ipam.graphql.types import IPAddressType, RouteTargetType, VLANType
|
||||
from netbox.graphql.types import ContentTypeType
|
||||
from tenancy.graphql.types import TenantType
|
||||
from virtualization.graphql.types import VMInterfaceType
|
||||
|
||||
__all__ = (
|
||||
'IKEPolicyType',
|
||||
'IKEProposalType',
|
||||
@ -125,7 +132,7 @@ class L2VPNType(ContactsMixin, NetBoxObjectType):
|
||||
|
||||
@strawberry_django.type(
|
||||
models.L2VPNTermination,
|
||||
exclude=('assigned_object_type', 'assigned_object_id'),
|
||||
exclude=['assigned_object_type', 'assigned_object_id'],
|
||||
filters=L2VPNTerminationFilter
|
||||
)
|
||||
class L2VPNTerminationType(NetBoxObjectType):
|
||||
|
17
netbox/wireless/graphql/enums.py
Normal file
17
netbox/wireless/graphql/enums.py
Normal file
@ -0,0 +1,17 @@
|
||||
import strawberry
|
||||
|
||||
from wireless.choices import *
|
||||
|
||||
__all__ = (
|
||||
'WirelessAuthCipherEnum',
|
||||
'WirelessAuthTypeEnum',
|
||||
'WirelessChannelEnum',
|
||||
'WirelessLANStatusEnum',
|
||||
'WirelessRoleEnum',
|
||||
)
|
||||
|
||||
WirelessAuthCipherEnum = strawberry.enum(WirelessAuthCipherChoices.as_enum())
|
||||
WirelessAuthTypeEnum = strawberry.enum(WirelessAuthTypeChoices.as_enum())
|
||||
WirelessChannelEnum = strawberry.enum(WirelessChannelChoices.as_enum())
|
||||
WirelessLANStatusEnum = strawberry.enum(WirelessLANStatusChoices.as_enum())
|
||||
WirelessRoleEnum = strawberry.enum(WirelessRoleChoices.as_enum())
|
26
netbox/wireless/graphql/filter_mixins.py
Normal file
26
netbox/wireless/graphql/filter_mixins.py
Normal file
@ -0,0 +1,26 @@
|
||||
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 .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()
|
@ -1,7 +1,20 @@
|
||||
import strawberry_django
|
||||
from typing import Annotated, TYPE_CHECKING
|
||||
|
||||
from netbox.graphql.filter_mixins import autotype_decorator, BaseFilterMixin
|
||||
from wireless import filtersets, models
|
||||
import strawberry
|
||||
import strawberry_django
|
||||
from strawberry.scalars import ID
|
||||
from strawberry_django import FilterLookup
|
||||
|
||||
from dcim.graphql.filter_mixins import ScopedFilterMixin
|
||||
from netbox.graphql.filter_mixins import DistanceFilterMixin, PrimaryModelFilterMixin, NestedGroupModelFilterMixin
|
||||
from tenancy.graphql.filter_mixins import TenancyFilterMixin
|
||||
from wireless import models
|
||||
from .filter_mixins import WirelessAuthenticationBaseFilterMixin
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from dcim.graphql.filters import InterfaceFilter
|
||||
from ipam.graphql.filters import VLANFilter
|
||||
from .enums import *
|
||||
|
||||
__all__ = (
|
||||
'WirelessLANGroupFilter',
|
||||
@ -11,18 +24,45 @@ __all__ = (
|
||||
|
||||
|
||||
@strawberry_django.filter(models.WirelessLANGroup, lookups=True)
|
||||
@autotype_decorator(filtersets.WirelessLANGroupFilterSet)
|
||||
class WirelessLANGroupFilter(BaseFilterMixin):
|
||||
class WirelessLANGroupFilter(NestedGroupModelFilterMixin):
|
||||
pass
|
||||
|
||||
|
||||
@strawberry_django.filter(models.WirelessLAN, lookups=True)
|
||||
@autotype_decorator(filtersets.WirelessLANFilterSet)
|
||||
class WirelessLANFilter(BaseFilterMixin):
|
||||
pass
|
||||
class WirelessLANFilter(
|
||||
WirelessAuthenticationBaseFilterMixin,
|
||||
ScopedFilterMixin,
|
||||
TenancyFilterMixin,
|
||||
PrimaryModelFilterMixin
|
||||
):
|
||||
ssid: FilterLookup[str] | None = strawberry_django.filter_field()
|
||||
status: Annotated['WirelessLANStatusEnum', strawberry.lazy('wireless.graphql.enums')] | None = (
|
||||
strawberry_django.filter_field()
|
||||
)
|
||||
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()
|
||||
|
||||
|
||||
@strawberry_django.filter(models.WirelessLink, lookups=True)
|
||||
@autotype_decorator(filtersets.WirelessLinkFilterSet)
|
||||
class WirelessLinkFilter(BaseFilterMixin):
|
||||
pass
|
||||
class WirelessLinkFilter(
|
||||
WirelessAuthenticationBaseFilterMixin,
|
||||
DistanceFilterMixin,
|
||||
TenancyFilterMixin,
|
||||
PrimaryModelFilterMixin
|
||||
):
|
||||
interface_a: Annotated['InterfaceFilter', strawberry.lazy('dcim.graphql.filters')] | None = (
|
||||
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()
|
||||
)
|
||||
|
@ -1,4 +1,4 @@
|
||||
from typing import Annotated, List, Union
|
||||
from typing import Annotated, List, TYPE_CHECKING, Union
|
||||
|
||||
import strawberry
|
||||
import strawberry_django
|
||||
@ -7,6 +7,11 @@ from netbox.graphql.types import OrganizationalObjectType, NetBoxObjectType
|
||||
from wireless import models
|
||||
from .filters import *
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from dcim.graphql.types import DeviceType, InterfaceType, LocationType, RegionType, SiteGroupType, SiteType
|
||||
from ipam.graphql.types import VLANType
|
||||
from tenancy.graphql.types import TenantType
|
||||
|
||||
__all__ = (
|
||||
'WirelessLANType',
|
||||
'WirelessLANGroupType',
|
||||
@ -28,7 +33,7 @@ class WirelessLANGroupType(OrganizationalObjectType):
|
||||
|
||||
@strawberry_django.type(
|
||||
models.WirelessLAN,
|
||||
exclude=('scope_type', 'scope_id', '_location', '_region', '_site', '_site_group'),
|
||||
exclude=['scope_type', 'scope_id', '_location', '_region', '_site', '_site_group'],
|
||||
filters=WirelessLANFilter
|
||||
)
|
||||
class WirelessLANType(NetBoxObjectType):
|
||||
|
Loading…
Reference in New Issue
Block a user