Просмотр исходного кода

Incorporate Owner fields/types into V1 classes

Brian Tiemann 3 месяцев назад
Родитель
Сommit
db3a4bc731

+ 8 - 6
netbox/circuits/graphql/types_v1.py

@@ -6,7 +6,9 @@ import strawberry_django
 from circuits import models
 from circuits import models
 from dcim.graphql.mixins_v1 import CabledObjectMixinV1
 from dcim.graphql.mixins_v1 import CabledObjectMixinV1
 from extras.graphql.mixins_v1 import ContactsMixinV1, CustomFieldsMixinV1, TagsMixinV1
 from extras.graphql.mixins_v1 import ContactsMixinV1, CustomFieldsMixinV1, TagsMixinV1
-from netbox.graphql.types_v1 import BaseObjectTypeV1, NetBoxObjectTypeV1, ObjectTypeV1, OrganizationalObjectTypeV1
+from netbox.graphql.types_v1 import (
+    BaseObjectTypeV1, ObjectTypeV1, OrganizationalObjectTypeV1, PrimaryObjectTypeV1
+)
 from tenancy.graphql.types_v1 import TenantTypeV1
 from tenancy.graphql.types_v1 import TenantTypeV1
 from .filters_v1 import *
 from .filters_v1 import *
 
 
@@ -35,7 +37,7 @@ __all__ = (
     filters=ProviderFilterV1,
     filters=ProviderFilterV1,
     pagination=True
     pagination=True
 )
 )
-class ProviderTypeV1(NetBoxObjectTypeV1, ContactsMixinV1):
+class ProviderTypeV1(ContactsMixinV1, PrimaryObjectTypeV1):
 
 
     networks: List[Annotated["ProviderNetworkTypeV1", strawberry.lazy('circuits.graphql.types_v1')]]
     networks: List[Annotated["ProviderNetworkTypeV1", strawberry.lazy('circuits.graphql.types_v1')]]
     circuits: List[Annotated["CircuitTypeV1", strawberry.lazy('circuits.graphql.types_v1')]]
     circuits: List[Annotated["CircuitTypeV1", strawberry.lazy('circuits.graphql.types_v1')]]
@@ -49,7 +51,7 @@ class ProviderTypeV1(NetBoxObjectTypeV1, ContactsMixinV1):
     filters=ProviderAccountFilterV1,
     filters=ProviderAccountFilterV1,
     pagination=True
     pagination=True
 )
 )
-class ProviderAccountTypeV1(ContactsMixinV1, NetBoxObjectTypeV1):
+class ProviderAccountTypeV1(ContactsMixinV1, PrimaryObjectTypeV1):
     provider: Annotated["ProviderTypeV1", strawberry.lazy('circuits.graphql.types_v1')]
     provider: Annotated["ProviderTypeV1", strawberry.lazy('circuits.graphql.types_v1')]
 
 
     circuits: List[Annotated["CircuitTypeV1", strawberry.lazy('circuits.graphql.types_v1')]]
     circuits: List[Annotated["CircuitTypeV1", strawberry.lazy('circuits.graphql.types_v1')]]
@@ -61,7 +63,7 @@ class ProviderAccountTypeV1(ContactsMixinV1, NetBoxObjectTypeV1):
     filters=ProviderNetworkFilterV1,
     filters=ProviderNetworkFilterV1,
     pagination=True
     pagination=True
 )
 )
-class ProviderNetworkTypeV1(NetBoxObjectTypeV1):
+class ProviderNetworkTypeV1(PrimaryObjectTypeV1):
     provider: Annotated["ProviderTypeV1", strawberry.lazy('circuits.graphql.types_v1')]
     provider: Annotated["ProviderTypeV1", strawberry.lazy('circuits.graphql.types_v1')]
 
 
     circuit_terminations: List[Annotated["CircuitTerminationTypeV1", strawberry.lazy('circuits.graphql.types_v1')]]
     circuit_terminations: List[Annotated["CircuitTerminationTypeV1", strawberry.lazy('circuits.graphql.types_v1')]]
@@ -105,7 +107,7 @@ class CircuitTypeTypeV1(OrganizationalObjectTypeV1):
     filters=CircuitFilterV1,
     filters=CircuitFilterV1,
     pagination=True
     pagination=True
 )
 )
-class CircuitTypeV1(NetBoxObjectTypeV1, ContactsMixinV1):
+class CircuitTypeV1(PrimaryObjectTypeV1, ContactsMixinV1):
     provider: ProviderTypeV1
     provider: ProviderTypeV1
     provider_account: ProviderAccountTypeV1 | None
     provider_account: ProviderAccountTypeV1 | None
     termination_a: CircuitTerminationTypeV1 | None
     termination_a: CircuitTerminationTypeV1 | None
@@ -178,7 +180,7 @@ class VirtualCircuitTerminationTypeV1(CustomFieldsMixinV1, TagsMixinV1, ObjectTy
     filters=VirtualCircuitFilterV1,
     filters=VirtualCircuitFilterV1,
     pagination=True
     pagination=True
 )
 )
-class VirtualCircuitTypeV1(NetBoxObjectTypeV1):
+class VirtualCircuitTypeV1(PrimaryObjectTypeV1):
     provider_network: ProviderNetworkTypeV1 = strawberry_django.field(select_related=["provider_network"])
     provider_network: ProviderNetworkTypeV1 = strawberry_django.field(select_related=["provider_network"])
     provider_account: ProviderAccountTypeV1 | None
     provider_account: ProviderAccountTypeV1 | None
     type: Annotated["VirtualCircuitTypeTypeV1", strawberry.lazy('circuits.graphql.types_v1')] = strawberry_django.field(
     type: Annotated["VirtualCircuitTypeTypeV1", strawberry.lazy('circuits.graphql.types_v1')] = strawberry_django.field(

+ 2 - 3
netbox/core/graphql/types_v1.py

@@ -5,7 +5,7 @@ import strawberry_django
 from django.contrib.contenttypes.models import ContentType as DjangoContentType
 from django.contrib.contenttypes.models import ContentType as DjangoContentType
 
 
 from core import models
 from core import models
-from netbox.graphql.types_v1 import BaseObjectTypeV1, NetBoxObjectTypeV1
+from netbox.graphql.types_v1 import BaseObjectTypeV1, PrimaryObjectTypeV1
 from .filters_v1 import *
 from .filters_v1 import *
 
 
 __all__ = (
 __all__ = (
@@ -32,8 +32,7 @@ class DataFileTypeV1(BaseObjectTypeV1):
     filters=DataSourceFilterV1,
     filters=DataSourceFilterV1,
     pagination=True
     pagination=True
 )
 )
-class DataSourceTypeV1(NetBoxObjectTypeV1):
-
+class DataSourceTypeV1(PrimaryObjectTypeV1):
     datafiles: List[Annotated["DataFileTypeV1", strawberry.lazy('core.graphql.types_v1')]]
     datafiles: List[Annotated["DataFileTypeV1", strawberry.lazy('core.graphql.types_v1')]]
 
 
 
 

+ 20 - 24
netbox/dcim/graphql/types_v1.py

@@ -8,13 +8,14 @@ from dcim import models
 from extras.graphql.mixins_v1 import (
 from extras.graphql.mixins_v1 import (
     ConfigContextMixinV1,
     ConfigContextMixinV1,
     ContactsMixinV1,
     ContactsMixinV1,
-    CustomFieldsMixinV1,
     ImageAttachmentsMixinV1,
     ImageAttachmentsMixinV1,
-    TagsMixinV1,
 )
 )
 from ipam.graphql.mixins_v1 import IPAddressesMixinV1, VLANGroupsMixinV1
 from ipam.graphql.mixins_v1 import IPAddressesMixinV1, VLANGroupsMixinV1
 from netbox.graphql.scalars import BigInt
 from netbox.graphql.scalars import BigInt
-from netbox.graphql.types_v1 import BaseObjectTypeV1, NetBoxObjectTypeV1, OrganizationalObjectTypeV1
+from netbox.graphql.types_v1 import (
+    BaseObjectTypeV1, NetBoxObjectTypeV1, OrganizationalObjectTypeV1, PrimaryObjectTypeV1
+)
+from users.graphql.mixins_v1 import OwnerMixinV1
 from .filters_v1 import *
 from .filters_v1 import *
 from .mixins_v1 import CabledObjectMixinV1, PathEndpointMixinV1
 from .mixins_v1 import CabledObjectMixinV1, PathEndpointMixinV1
 
 
@@ -91,12 +92,7 @@ __all__ = (
 
 
 
 
 @strawberry.type
 @strawberry.type
-class ComponentTypeV1(
-    ChangelogMixinV1,
-    CustomFieldsMixinV1,
-    TagsMixinV1,
-    BaseObjectTypeV1
-):
+class ComponentTypeV1(OwnerMixinV1, NetBoxObjectTypeV1):
     """
     """
     Base type for device/VM components
     Base type for device/VM components
     """
     """
@@ -159,7 +155,7 @@ class CableTerminationTypeV1(NetBoxObjectTypeV1):
     filters=CableFilterV1,
     filters=CableFilterV1,
     pagination=True
     pagination=True
 )
 )
-class CableTypeV1(NetBoxObjectTypeV1):
+class CableTypeV1(PrimaryObjectTypeV1):
     color: str
     color: str
     tenant: Annotated["TenantTypeV1", strawberry.lazy('tenancy.graphql.types_v1')] | None
     tenant: Annotated["TenantTypeV1", strawberry.lazy('tenancy.graphql.types_v1')] | None
 
 
@@ -236,7 +232,7 @@ class ConsoleServerPortTemplateTypeV1(ModularComponentTemplateTypeV1):
     filters=DeviceFilterV1,
     filters=DeviceFilterV1,
     pagination=True
     pagination=True
 )
 )
-class DeviceTypeV1(ConfigContextMixinV1, ImageAttachmentsMixinV1, ContactsMixinV1, NetBoxObjectTypeV1):
+class DeviceTypeV1(ConfigContextMixinV1, ImageAttachmentsMixinV1, ContactsMixinV1, PrimaryObjectTypeV1):
     console_port_count: BigInt
     console_port_count: BigInt
     console_server_port_count: BigInt
     console_server_port_count: BigInt
     power_port_count: BigInt
     power_port_count: BigInt
@@ -355,7 +351,7 @@ class DeviceRoleTypeV1(OrganizationalObjectTypeV1):
     filters=DeviceTypeFilterV1,
     filters=DeviceTypeFilterV1,
     pagination=True
     pagination=True
 )
 )
-class DeviceTypeTypeV1(NetBoxObjectTypeV1):
+class DeviceTypeTypeV1(PrimaryObjectTypeV1):
     console_port_template_count: BigInt
     console_port_template_count: BigInt
     console_server_port_template_count: BigInt
     console_server_port_template_count: BigInt
     power_port_template_count: BigInt
     power_port_template_count: BigInt
@@ -414,7 +410,7 @@ class FrontPortTemplateTypeV1(ModularComponentTemplateTypeV1):
     filters=MACAddressFilterV1,
     filters=MACAddressFilterV1,
     pagination=True
     pagination=True
 )
 )
-class MACAddressTypeV1(NetBoxObjectTypeV1):
+class MACAddressTypeV1(PrimaryObjectTypeV1):
     mac_address: str
     mac_address: str
 
 
     @strawberry_django.field
     @strawberry_django.field
@@ -557,7 +553,7 @@ class ManufacturerTypeV1(OrganizationalObjectTypeV1, ContactsMixinV1):
     filters=ModuleFilterV1,
     filters=ModuleFilterV1,
     pagination=True
     pagination=True
 )
 )
-class ModuleTypeV1(NetBoxObjectTypeV1):
+class ModuleTypeV1(PrimaryObjectTypeV1):
     device: Annotated["DeviceTypeV1", strawberry.lazy('dcim.graphql.types_v1')]
     device: Annotated["DeviceTypeV1", strawberry.lazy('dcim.graphql.types_v1')]
     module_bay: Annotated["ModuleBayTypeV1", strawberry.lazy('dcim.graphql.types_v1')]
     module_bay: Annotated["ModuleBayTypeV1", strawberry.lazy('dcim.graphql.types_v1')]
     module_type: Annotated["ModuleTypeTypeV1", strawberry.lazy('dcim.graphql.types_v1')]
     module_type: Annotated["ModuleTypeTypeV1", strawberry.lazy('dcim.graphql.types_v1')]
@@ -604,7 +600,7 @@ class ModuleBayTemplateTypeV1(ModularComponentTemplateTypeV1):
     filters=ModuleTypeProfileFilterV1,
     filters=ModuleTypeProfileFilterV1,
     pagination=True
     pagination=True
 )
 )
-class ModuleTypeProfileTypeV1(NetBoxObjectTypeV1):
+class ModuleTypeProfileTypeV1(PrimaryObjectTypeV1):
     module_types: List[Annotated["ModuleTypeV1", strawberry.lazy('dcim.graphql.types_v1')]]
     module_types: List[Annotated["ModuleTypeV1", strawberry.lazy('dcim.graphql.types_v1')]]
 
 
 
 
@@ -614,7 +610,7 @@ class ModuleTypeProfileTypeV1(NetBoxObjectTypeV1):
     filters=ModuleTypeFilterV1,
     filters=ModuleTypeFilterV1,
     pagination=True
     pagination=True
 )
 )
-class ModuleTypeTypeV1(NetBoxObjectTypeV1):
+class ModuleTypeTypeV1(PrimaryObjectTypeV1):
     profile: Annotated["ModuleTypeProfileTypeV1", strawberry.lazy('dcim.graphql.types_v1')] | None
     profile: Annotated["ModuleTypeProfileTypeV1", strawberry.lazy('dcim.graphql.types_v1')] | None
     manufacturer: Annotated["ManufacturerTypeV1", strawberry.lazy('dcim.graphql.types_v1')]
     manufacturer: Annotated["ManufacturerTypeV1", strawberry.lazy('dcim.graphql.types_v1')]
 
 
@@ -652,7 +648,7 @@ class PlatformTypeV1(OrganizationalObjectTypeV1):
     filters=PowerFeedFilterV1,
     filters=PowerFeedFilterV1,
     pagination=True
     pagination=True
 )
 )
-class PowerFeedTypeV1(NetBoxObjectTypeV1, CabledObjectMixinV1, PathEndpointMixinV1):
+class PowerFeedTypeV1(CabledObjectMixinV1, PathEndpointMixinV1, PrimaryObjectTypeV1):
     power_panel: Annotated["PowerPanelTypeV1", strawberry.lazy('dcim.graphql.types_v1')]
     power_panel: Annotated["PowerPanelTypeV1", strawberry.lazy('dcim.graphql.types_v1')]
     rack: Annotated["RackTypeV1", strawberry.lazy('dcim.graphql.types_v1')] | None
     rack: Annotated["RackTypeV1", strawberry.lazy('dcim.graphql.types_v1')] | None
     tenant: Annotated["TenantTypeV1", strawberry.lazy('tenancy.graphql.types_v1')] | None
     tenant: Annotated["TenantTypeV1", strawberry.lazy('tenancy.graphql.types_v1')] | None
@@ -686,7 +682,7 @@ class PowerOutletTemplateTypeV1(ModularComponentTemplateTypeV1):
     filters=PowerPanelFilterV1,
     filters=PowerPanelFilterV1,
     pagination=True
     pagination=True
 )
 )
-class PowerPanelTypeV1(NetBoxObjectTypeV1, ContactsMixinV1):
+class PowerPanelTypeV1(ContactsMixinV1, PrimaryObjectTypeV1):
     site: Annotated["SiteTypeV1", strawberry.lazy('dcim.graphql.types_v1')]
     site: Annotated["SiteTypeV1", strawberry.lazy('dcim.graphql.types_v1')]
     location: Annotated["LocationTypeV1", strawberry.lazy('dcim.graphql.types_v1')] | None
     location: Annotated["LocationTypeV1", strawberry.lazy('dcim.graphql.types_v1')] | None
 
 
@@ -720,7 +716,7 @@ class PowerPortTemplateTypeV1(ModularComponentTemplateTypeV1):
     filters=RackTypeFilterV1,
     filters=RackTypeFilterV1,
     pagination=True
     pagination=True
 )
 )
-class RackTypeTypeV1(NetBoxObjectTypeV1):
+class RackTypeTypeV1(PrimaryObjectTypeV1):
     manufacturer: Annotated["ManufacturerTypeV1", strawberry.lazy('dcim.graphql.types_v1')]
     manufacturer: Annotated["ManufacturerTypeV1", strawberry.lazy('dcim.graphql.types_v1')]
 
 
 
 
@@ -730,7 +726,7 @@ class RackTypeTypeV1(NetBoxObjectTypeV1):
     filters=RackFilterV1,
     filters=RackFilterV1,
     pagination=True
     pagination=True
 )
 )
-class RackTypeV1(VLANGroupsMixinV1, ImageAttachmentsMixinV1, ContactsMixinV1, NetBoxObjectTypeV1):
+class RackTypeV1(VLANGroupsMixinV1, ImageAttachmentsMixinV1, ContactsMixinV1, PrimaryObjectTypeV1):
     site: Annotated["SiteTypeV1", strawberry.lazy('dcim.graphql.types_v1')]
     site: Annotated["SiteTypeV1", strawberry.lazy('dcim.graphql.types_v1')]
     location: Annotated["LocationTypeV1", strawberry.lazy('dcim.graphql.types_v1')] | None
     location: Annotated["LocationTypeV1", strawberry.lazy('dcim.graphql.types_v1')] | None
     tenant: Annotated["TenantTypeV1", strawberry.lazy('tenancy.graphql.types_v1')] | None
     tenant: Annotated["TenantTypeV1", strawberry.lazy('tenancy.graphql.types_v1')] | None
@@ -749,7 +745,7 @@ class RackTypeV1(VLANGroupsMixinV1, ImageAttachmentsMixinV1, ContactsMixinV1, Ne
     filters=RackReservationFilterV1,
     filters=RackReservationFilterV1,
     pagination=True
     pagination=True
 )
 )
-class RackReservationTypeV1(NetBoxObjectTypeV1):
+class RackReservationTypeV1(PrimaryObjectTypeV1):
     units: List[int]
     units: List[int]
     rack: Annotated["RackTypeV1", strawberry.lazy('dcim.graphql.types_v1')]
     rack: Annotated["RackTypeV1", strawberry.lazy('dcim.graphql.types_v1')]
     tenant: Annotated["TenantTypeV1", strawberry.lazy('tenancy.graphql.types_v1')] | None
     tenant: Annotated["TenantTypeV1", strawberry.lazy('tenancy.graphql.types_v1')] | None
@@ -824,7 +820,7 @@ class RegionTypeV1(VLANGroupsMixinV1, ContactsMixinV1, OrganizationalObjectTypeV
     filters=SiteFilterV1,
     filters=SiteFilterV1,
     pagination=True
     pagination=True
 )
 )
-class SiteTypeV1(VLANGroupsMixinV1, ImageAttachmentsMixinV1, ContactsMixinV1, NetBoxObjectTypeV1):
+class SiteTypeV1(VLANGroupsMixinV1, ImageAttachmentsMixinV1, ContactsMixinV1, PrimaryObjectTypeV1):
     time_zone: str | None
     time_zone: str | None
     region: Annotated["RegionTypeV1", strawberry.lazy('dcim.graphql.types_v1')] | None
     region: Annotated["RegionTypeV1", strawberry.lazy('dcim.graphql.types_v1')] | None
     group: Annotated["SiteGroupTypeV1", strawberry.lazy('dcim.graphql.types_v1')] | None
     group: Annotated["SiteGroupTypeV1", strawberry.lazy('dcim.graphql.types_v1')] | None
@@ -885,7 +881,7 @@ class SiteGroupTypeV1(VLANGroupsMixinV1, ContactsMixinV1, OrganizationalObjectTy
     filters=VirtualChassisFilterV1,
     filters=VirtualChassisFilterV1,
     pagination=True
     pagination=True
 )
 )
-class VirtualChassisTypeV1(NetBoxObjectTypeV1):
+class VirtualChassisTypeV1(PrimaryObjectTypeV1):
     member_count: BigInt
     member_count: BigInt
     master: Annotated["DeviceTypeV1", strawberry.lazy('dcim.graphql.types_v1')] | None
     master: Annotated["DeviceTypeV1", strawberry.lazy('dcim.graphql.types_v1')] | None
 
 
@@ -898,7 +894,7 @@ class VirtualChassisTypeV1(NetBoxObjectTypeV1):
     filters=VirtualDeviceContextFilterV1,
     filters=VirtualDeviceContextFilterV1,
     pagination=True
     pagination=True
 )
 )
-class VirtualDeviceContextTypeV1(NetBoxObjectTypeV1):
+class VirtualDeviceContextTypeV1(PrimaryObjectTypeV1):
     device: Annotated["DeviceTypeV1", strawberry.lazy('dcim.graphql.types_v1')] | None
     device: Annotated["DeviceTypeV1", strawberry.lazy('dcim.graphql.types_v1')] | None
     primary_ip4: Annotated["IPAddressTypeV1", strawberry.lazy('ipam.graphql.types_v1')] | None
     primary_ip4: Annotated["IPAddressTypeV1", strawberry.lazy('ipam.graphql.types_v1')] | None
     primary_ip6: Annotated["IPAddressTypeV1", strawberry.lazy('ipam.graphql.types_v1')] | None
     primary_ip6: Annotated["IPAddressTypeV1", strawberry.lazy('ipam.graphql.types_v1')] | None

+ 11 - 10
netbox/extras/graphql/types_v1.py

@@ -7,8 +7,9 @@ from core.graphql.mixins_v1 import SyncedDataMixinV1
 from extras import models
 from extras import models
 from extras.graphql.mixins_v1 import CustomFieldsMixinV1, TagsMixinV1
 from extras.graphql.mixins_v1 import CustomFieldsMixinV1, TagsMixinV1
 from netbox.graphql.types_v1 import (
 from netbox.graphql.types_v1 import (
-    BaseObjectTypeV1, ContentTypeTypeV1, NetBoxObjectTypeV1, ObjectTypeV1, OrganizationalObjectTypeV1
+    BaseObjectTypeV1, ContentTypeTypeV1, ObjectTypeV1, OrganizationalObjectTypeV1, PrimaryObjectTypeV1
 )
 )
+from users.graphql.mixins_v1 import OwnerMixinV1
 from .filters_v1 import *
 from .filters_v1 import *
 
 
 if TYPE_CHECKING:
 if TYPE_CHECKING:
@@ -55,7 +56,7 @@ __all__ = (
     filters=ConfigContextProfileFilterV1,
     filters=ConfigContextProfileFilterV1,
     pagination=True
     pagination=True
 )
 )
-class ConfigContextProfileTypeV1(SyncedDataMixinV1, NetBoxObjectTypeV1):
+class ConfigContextProfileTypeV1(SyncedDataMixinV1, PrimaryObjectTypeV1):
     pass
     pass
 
 
 
 
@@ -65,7 +66,7 @@ class ConfigContextProfileTypeV1(SyncedDataMixinV1, NetBoxObjectTypeV1):
     filters=ConfigContextFilterV1,
     filters=ConfigContextFilterV1,
     pagination=True
     pagination=True
 )
 )
-class ConfigContextTypeV1(SyncedDataMixinV1, ObjectTypeV1):
+class ConfigContextTypeV1(SyncedDataMixinV1, OwnerMixinV1, ObjectTypeV1):
     profile: ConfigContextProfileTypeV1 | None
     profile: ConfigContextProfileTypeV1 | None
     roles: List[Annotated["DeviceRoleTypeV1", strawberry.lazy('dcim.graphql.types_v1')]]
     roles: List[Annotated["DeviceRoleTypeV1", strawberry.lazy('dcim.graphql.types_v1')]]
     device_types: List[Annotated["DeviceTypeTypeV1", strawberry.lazy('dcim.graphql.types_v1')]]
     device_types: List[Annotated["DeviceTypeTypeV1", strawberry.lazy('dcim.graphql.types_v1')]]
@@ -88,7 +89,7 @@ class ConfigContextTypeV1(SyncedDataMixinV1, ObjectTypeV1):
     filters=ConfigTemplateFilterV1,
     filters=ConfigTemplateFilterV1,
     pagination=True
     pagination=True
 )
 )
-class ConfigTemplateTypeV1(SyncedDataMixinV1, TagsMixinV1, ObjectTypeV1):
+class ConfigTemplateTypeV1(SyncedDataMixinV1, OwnerMixinV1, TagsMixinV1, ObjectTypeV1):
     virtualmachines: List[Annotated["VirtualMachineTypeV1", strawberry.lazy('virtualization.graphql.types_v1')]]
     virtualmachines: List[Annotated["VirtualMachineTypeV1", strawberry.lazy('virtualization.graphql.types_v1')]]
     devices: List[Annotated["DeviceTypeV1", strawberry.lazy('dcim.graphql.types_v1')]]
     devices: List[Annotated["DeviceTypeV1", strawberry.lazy('dcim.graphql.types_v1')]]
     platforms: List[Annotated["PlatformTypeV1", strawberry.lazy('dcim.graphql.types_v1')]]
     platforms: List[Annotated["PlatformTypeV1", strawberry.lazy('dcim.graphql.types_v1')]]
@@ -101,7 +102,7 @@ class ConfigTemplateTypeV1(SyncedDataMixinV1, TagsMixinV1, ObjectTypeV1):
     filters=CustomFieldFilterV1,
     filters=CustomFieldFilterV1,
     pagination=True
     pagination=True
 )
 )
-class CustomFieldTypeV1(ObjectTypeV1):
+class CustomFieldTypeV1(OwnerMixinV1, ObjectTypeV1):
     related_object_type: Annotated["ContentTypeTypeV1", strawberry.lazy('netbox.graphql.types_v1')] | None
     related_object_type: Annotated["ContentTypeTypeV1", strawberry.lazy('netbox.graphql.types_v1')] | None
     choice_set: Annotated["CustomFieldChoiceSetTypeV1", strawberry.lazy('extras.graphql.types_v1')] | None
     choice_set: Annotated["CustomFieldChoiceSetTypeV1", strawberry.lazy('extras.graphql.types_v1')] | None
 
 
@@ -112,7 +113,7 @@ class CustomFieldTypeV1(ObjectTypeV1):
     filters=CustomFieldChoiceSetFilterV1,
     filters=CustomFieldChoiceSetFilterV1,
     pagination=True
     pagination=True
 )
 )
-class CustomFieldChoiceSetTypeV1(ObjectTypeV1):
+class CustomFieldChoiceSetTypeV1(OwnerMixinV1, ObjectTypeV1):
 
 
     choices_for: List[Annotated["CustomFieldTypeV1", strawberry.lazy('extras.graphql.types_v1')]]
     choices_for: List[Annotated["CustomFieldTypeV1", strawberry.lazy('extras.graphql.types_v1')]]
     extra_choices: List[List[str]] | None
     extra_choices: List[List[str]] | None
@@ -124,7 +125,7 @@ class CustomFieldChoiceSetTypeV1(ObjectTypeV1):
     filters=CustomLinkFilterV1,
     filters=CustomLinkFilterV1,
     pagination=True
     pagination=True
 )
 )
-class CustomLinkTypeV1(ObjectTypeV1):
+class CustomLinkTypeV1(OwnerMixinV1, ObjectTypeV1):
     pass
     pass
 
 
 
 
@@ -134,7 +135,7 @@ class CustomLinkTypeV1(ObjectTypeV1):
     filters=ExportTemplateFilterV1,
     filters=ExportTemplateFilterV1,
     pagination=True
     pagination=True
 )
 )
-class ExportTemplateTypeV1(SyncedDataMixinV1, ObjectTypeV1):
+class ExportTemplateTypeV1(SyncedDataMixinV1, OwnerMixinV1, ObjectTypeV1):
     pass
     pass
 
 
 
 
@@ -184,7 +185,7 @@ class NotificationGroupTypeV1(ObjectTypeV1):
     filters=SavedFilterFilterV1,
     filters=SavedFilterFilterV1,
     pagination=True
     pagination=True
 )
 )
-class SavedFilterTypeV1(ObjectTypeV1):
+class SavedFilterTypeV1(OwnerMixinV1, ObjectTypeV1):
     user: Annotated["UserTypeV1", strawberry.lazy('users.graphql.types_v1')] | None
     user: Annotated["UserTypeV1", strawberry.lazy('users.graphql.types_v1')] | None
 
 
 
 
@@ -213,7 +214,7 @@ class TableConfigTypeV1(ObjectTypeV1):
     filters=TagFilterV1,
     filters=TagFilterV1,
     pagination=True
     pagination=True
 )
 )
-class TagTypeV1(ObjectTypeV1):
+class TagTypeV1(OwnerMixinV1, ObjectTypeV1):
     color: str
     color: str
 
 
     object_types: List[ContentTypeTypeV1]
     object_types: List[ContentTypeTypeV1]

+ 16 - 15
netbox/ipam/graphql/types_v1.py

@@ -8,7 +8,9 @@ from dcim.graphql.types_v1 import SiteTypeV1
 from extras.graphql.mixins_v1 import ContactsMixinV1
 from extras.graphql.mixins_v1 import ContactsMixinV1
 from ipam import models
 from ipam import models
 from netbox.graphql.scalars import BigInt
 from netbox.graphql.scalars import BigInt
-from netbox.graphql.types_v1 import BaseObjectTypeV1, NetBoxObjectTypeV1, OrganizationalObjectTypeV1
+from netbox.graphql.types_v1 import (
+    BaseObjectTypeV1, NetBoxObjectTypeV1, OrganizationalObjectTypeV1, PrimaryObjectTypeV1
+)
 from .filters_v1 import *
 from .filters_v1 import *
 from .mixins_v1 import IPAddressesMixinV1
 from .mixins_v1 import IPAddressesMixinV1
 
 
@@ -76,7 +78,7 @@ class BaseIPAddressFamilyTypeV1:
     filters=ASNFilterV1,
     filters=ASNFilterV1,
     pagination=True
     pagination=True
 )
 )
-class ASNTypeV1(NetBoxObjectTypeV1, ContactsMixinV1):
+class ASNTypeV1(ContactsMixinV1, PrimaryObjectTypeV1):
     asn: BigInt
     asn: BigInt
     rir: Annotated["RIRTypeV1", strawberry.lazy('ipam.graphql.types_v1')] | None
     rir: Annotated["RIRTypeV1", strawberry.lazy('ipam.graphql.types_v1')] | None
     tenant: Annotated["TenantTypeV1", strawberry.lazy('tenancy.graphql.types_v1')] | None
     tenant: Annotated["TenantTypeV1", strawberry.lazy('tenancy.graphql.types_v1')] | None
@@ -91,7 +93,7 @@ class ASNTypeV1(NetBoxObjectTypeV1, ContactsMixinV1):
     filters=ASNRangeFilterV1,
     filters=ASNRangeFilterV1,
     pagination=True
     pagination=True
 )
 )
-class ASNRangeTypeV1(NetBoxObjectTypeV1):
+class ASNRangeTypeV1(OrganizationalObjectTypeV1):
     start: BigInt
     start: BigInt
     end: BigInt
     end: BigInt
     rir: Annotated["RIRTypeV1", strawberry.lazy('ipam.graphql.types_v1')] | None
     rir: Annotated["RIRTypeV1", strawberry.lazy('ipam.graphql.types_v1')] | None
@@ -104,7 +106,7 @@ class ASNRangeTypeV1(NetBoxObjectTypeV1):
     filters=AggregateFilterV1,
     filters=AggregateFilterV1,
     pagination=True
     pagination=True
 )
 )
-class AggregateTypeV1(NetBoxObjectTypeV1, ContactsMixinV1, BaseIPAddressFamilyTypeV1):
+class AggregateTypeV1(ContactsMixinV1, BaseIPAddressFamilyTypeV1, PrimaryObjectTypeV1):
     prefix: str
     prefix: str
     rir: Annotated["RIRTypeV1", strawberry.lazy('ipam.graphql.types_v1')] | None
     rir: Annotated["RIRTypeV1", strawberry.lazy('ipam.graphql.types_v1')] | None
     tenant: Annotated["TenantTypeV1", strawberry.lazy('tenancy.graphql.types_v1')] | None
     tenant: Annotated["TenantTypeV1", strawberry.lazy('tenancy.graphql.types_v1')] | None
@@ -116,8 +118,7 @@ class AggregateTypeV1(NetBoxObjectTypeV1, ContactsMixinV1, BaseIPAddressFamilyTy
     filters=FHRPGroupFilterV1,
     filters=FHRPGroupFilterV1,
     pagination=True
     pagination=True
 )
 )
-class FHRPGroupTypeV1(NetBoxObjectTypeV1, IPAddressesMixinV1):
-
+class FHRPGroupTypeV1(IPAddressesMixinV1, PrimaryObjectTypeV1):
     fhrpgroupassignment_set: List[Annotated["FHRPGroupAssignmentTypeV1", strawberry.lazy('ipam.graphql.types_v1')]]
     fhrpgroupassignment_set: List[Annotated["FHRPGroupAssignmentTypeV1", strawberry.lazy('ipam.graphql.types_v1')]]
 
 
 
 
@@ -144,7 +145,7 @@ class FHRPGroupAssignmentTypeV1(BaseObjectTypeV1):
     filters=IPAddressFilterV1,
     filters=IPAddressFilterV1,
     pagination=True
     pagination=True
 )
 )
-class IPAddressTypeV1(NetBoxObjectTypeV1, ContactsMixinV1, BaseIPAddressFamilyTypeV1):
+class IPAddressTypeV1(ContactsMixinV1, BaseIPAddressFamilyTypeV1, PrimaryObjectTypeV1):
     address: str
     address: str
     vrf: Annotated["VRFTypeV1", strawberry.lazy('ipam.graphql.types_v1')] | None
     vrf: Annotated["VRFTypeV1", strawberry.lazy('ipam.graphql.types_v1')] | None
     tenant: Annotated["TenantTypeV1", strawberry.lazy('tenancy.graphql.types_v1')] | None
     tenant: Annotated["TenantTypeV1", strawberry.lazy('tenancy.graphql.types_v1')] | None
@@ -169,7 +170,7 @@ class IPAddressTypeV1(NetBoxObjectTypeV1, ContactsMixinV1, BaseIPAddressFamilyTy
     filters=IPRangeFilterV1,
     filters=IPRangeFilterV1,
     pagination=True
     pagination=True
 )
 )
-class IPRangeTypeV1(NetBoxObjectTypeV1, ContactsMixinV1):
+class IPRangeTypeV1(ContactsMixinV1, PrimaryObjectTypeV1):
     start_address: str
     start_address: str
     end_address: str
     end_address: str
     vrf: Annotated["VRFTypeV1", strawberry.lazy('ipam.graphql.types_v1')] | None
     vrf: Annotated["VRFTypeV1", strawberry.lazy('ipam.graphql.types_v1')] | None
@@ -183,7 +184,7 @@ class IPRangeTypeV1(NetBoxObjectTypeV1, ContactsMixinV1):
     filters=PrefixFilterV1,
     filters=PrefixFilterV1,
     pagination=True
     pagination=True
 )
 )
-class PrefixTypeV1(NetBoxObjectTypeV1, ContactsMixinV1, BaseIPAddressFamilyTypeV1):
+class PrefixTypeV1(ContactsMixinV1, BaseIPAddressFamilyTypeV1, PrimaryObjectTypeV1):
     prefix: str
     prefix: str
     vrf: Annotated["VRFTypeV1", strawberry.lazy('ipam.graphql.types_v1')] | None
     vrf: Annotated["VRFTypeV1", strawberry.lazy('ipam.graphql.types_v1')] | None
     tenant: Annotated["TenantTypeV1", strawberry.lazy('tenancy.graphql.types_v1')] | None
     tenant: Annotated["TenantTypeV1", strawberry.lazy('tenancy.graphql.types_v1')] | None
@@ -232,7 +233,7 @@ class RoleTypeV1(OrganizationalObjectTypeV1):
     filters=RouteTargetFilterV1,
     filters=RouteTargetFilterV1,
     pagination=True
     pagination=True
 )
 )
-class RouteTargetTypeV1(NetBoxObjectTypeV1):
+class RouteTargetTypeV1(PrimaryObjectTypeV1):
     tenant: Annotated["TenantTypeV1", strawberry.lazy('tenancy.graphql.types_v1')] | None
     tenant: Annotated["TenantTypeV1", strawberry.lazy('tenancy.graphql.types_v1')] | None
 
 
     importing_l2vpns: List[Annotated["L2VPNTypeV1", strawberry.lazy('vpn.graphql.types_v1')]]
     importing_l2vpns: List[Annotated["L2VPNTypeV1", strawberry.lazy('vpn.graphql.types_v1')]]
@@ -247,7 +248,7 @@ class RouteTargetTypeV1(NetBoxObjectTypeV1):
     filters=ServiceFilterV1,
     filters=ServiceFilterV1,
     pagination=True
     pagination=True
 )
 )
-class ServiceTypeV1(NetBoxObjectTypeV1, ContactsMixinV1):
+class ServiceTypeV1(ContactsMixinV1, PrimaryObjectTypeV1):
     ports: List[int]
     ports: List[int]
     ipaddresses: List[Annotated["IPAddressTypeV1", strawberry.lazy('ipam.graphql.types_v1')]]
     ipaddresses: List[Annotated["IPAddressTypeV1", strawberry.lazy('ipam.graphql.types_v1')]]
 
 
@@ -266,7 +267,7 @@ class ServiceTypeV1(NetBoxObjectTypeV1, ContactsMixinV1):
     filters=ServiceTemplateFilterV1,
     filters=ServiceTemplateFilterV1,
     pagination=True
     pagination=True
 )
 )
-class ServiceTemplateTypeV1(NetBoxObjectTypeV1):
+class ServiceTemplateTypeV1(PrimaryObjectTypeV1):
     ports: List[int]
     ports: List[int]
 
 
 
 
@@ -276,7 +277,7 @@ class ServiceTemplateTypeV1(NetBoxObjectTypeV1):
     filters=VLANFilterV1,
     filters=VLANFilterV1,
     pagination=True
     pagination=True
 )
 )
-class VLANTypeV1(NetBoxObjectTypeV1):
+class VLANTypeV1(PrimaryObjectTypeV1):
     site: Annotated["SiteTypeV1", strawberry.lazy('ipam.graphql.types_v1')] | None
     site: Annotated["SiteTypeV1", strawberry.lazy('ipam.graphql.types_v1')] | None
     group: Annotated["VLANGroupTypeV1", strawberry.lazy('ipam.graphql.types_v1')] | None
     group: Annotated["VLANGroupTypeV1", strawberry.lazy('ipam.graphql.types_v1')] | None
     tenant: Annotated["TenantTypeV1", strawberry.lazy('tenancy.graphql.types_v1')] | None
     tenant: Annotated["TenantTypeV1", strawberry.lazy('tenancy.graphql.types_v1')] | None
@@ -325,7 +326,7 @@ class VLANGroupTypeV1(OrganizationalObjectTypeV1):
     filters=VLANTranslationPolicyFilterV1,
     filters=VLANTranslationPolicyFilterV1,
     pagination=True
     pagination=True
 )
 )
-class VLANTranslationPolicyTypeV1(NetBoxObjectTypeV1):
+class VLANTranslationPolicyTypeV1(PrimaryObjectTypeV1):
     rules: List[Annotated["VLANTranslationRuleTypeV1", strawberry.lazy('ipam.graphql.types_v1')]]
     rules: List[Annotated["VLANTranslationRuleTypeV1", strawberry.lazy('ipam.graphql.types_v1')]]
 
 
 
 
@@ -348,7 +349,7 @@ class VLANTranslationRuleTypeV1(NetBoxObjectTypeV1):
     filters=VRFFilterV1,
     filters=VRFFilterV1,
     pagination=True
     pagination=True
 )
 )
-class VRFTypeV1(NetBoxObjectTypeV1):
+class VRFTypeV1(PrimaryObjectTypeV1):
     tenant: Annotated["TenantTypeV1", strawberry.lazy('tenancy.graphql.types_v1')] | None
     tenant: Annotated["TenantTypeV1", strawberry.lazy('tenancy.graphql.types_v1')] | None
 
 
     interfaces: List[Annotated["InterfaceTypeV1", strawberry.lazy('dcim.graphql.types_v1')]]
     interfaces: List[Annotated["InterfaceTypeV1", strawberry.lazy('dcim.graphql.types_v1')]]

+ 23 - 23
netbox/netbox/graphql/types_v1.py

@@ -3,10 +3,10 @@ import strawberry_django
 from strawberry.types import Info
 from strawberry.types import Info
 from django.contrib.contenttypes.models import ContentType
 from django.contrib.contenttypes.models import ContentType
 
 
-from core.graphql.mixins import ChangelogMixin
+from core.graphql.mixins_v1 import ChangelogMixinV1
 from core.models import ObjectType as ObjectType_
 from core.models import ObjectType as ObjectType_
-from extras.graphql.mixins import CustomFieldsMixin, JournalEntriesMixin, TagsMixin
-from users.graphql.mixins import OwnerMixin
+from extras.graphql.mixins_v1 import CustomFieldsMixinV1, JournalEntriesMixinV1, TagsMixinV1
+from users.graphql.mixins_v1 import OwnerMixinV1
 
 
 __all__ = (
 __all__ = (
     'BaseObjectTypeV1',
     'BaseObjectTypeV1',
@@ -47,7 +47,7 @@ class BaseObjectTypeV1:
 
 
 
 
 class ObjectTypeV1(
 class ObjectTypeV1(
-    ChangelogMixin,
+    ChangelogMixinV1,
     BaseObjectTypeV1
     BaseObjectTypeV1
 ):
 ):
     """
     """
@@ -57,11 +57,11 @@ class ObjectTypeV1(
 
 
 
 
 class PrimaryObjectTypeV1(
 class PrimaryObjectTypeV1(
-    ChangelogMixin,
-    CustomFieldsMixin,
-    JournalEntriesMixin,
-    TagsMixin,
-    OwnerMixin,
+    ChangelogMixinV1,
+    CustomFieldsMixinV1,
+    JournalEntriesMixinV1,
+    TagsMixinV1,
+    OwnerMixinV1,
     BaseObjectTypeV1
     BaseObjectTypeV1
 ):
 ):
     """
     """
@@ -71,11 +71,11 @@ class PrimaryObjectTypeV1(
 
 
 
 
 class OrganizationalObjectTypeV1(
 class OrganizationalObjectTypeV1(
-    ChangelogMixin,
-    CustomFieldsMixin,
-    JournalEntriesMixin,
-    TagsMixin,
-    OwnerMixin,
+    ChangelogMixinV1,
+    CustomFieldsMixinV1,
+    JournalEntriesMixinV1,
+    TagsMixinV1,
+    OwnerMixinV1,
     BaseObjectTypeV1
     BaseObjectTypeV1
 ):
 ):
     """
     """
@@ -85,11 +85,11 @@ class OrganizationalObjectTypeV1(
 
 
 
 
 class NestedGroupObjectTypeV1(
 class NestedGroupObjectTypeV1(
-    ChangelogMixin,
-    CustomFieldsMixin,
-    JournalEntriesMixin,
-    TagsMixin,
-    OwnerMixin,
+    ChangelogMixinV1,
+    CustomFieldsMixinV1,
+    JournalEntriesMixinV1,
+    TagsMixinV1,
+    OwnerMixinV1,
     BaseObjectTypeV1
     BaseObjectTypeV1
 ):
 ):
     """
     """
@@ -99,10 +99,10 @@ class NestedGroupObjectTypeV1(
 
 
 
 
 class NetBoxObjectTypeV1(
 class NetBoxObjectTypeV1(
-    ChangelogMixin,
-    CustomFieldsMixin,
-    JournalEntriesMixin,
-    TagsMixin,
+    ChangelogMixinV1,
+    CustomFieldsMixinV1,
+    JournalEntriesMixinV1,
+    TagsMixinV1,
     BaseObjectTypeV1
     BaseObjectTypeV1
 ):
 ):
     """
     """

+ 5 - 3
netbox/tenancy/graphql/types_v1.py

@@ -4,7 +4,9 @@ import strawberry
 import strawberry_django
 import strawberry_django
 
 
 from extras.graphql.mixins_v1 import CustomFieldsMixinV1, TagsMixinV1, ContactsMixinV1
 from extras.graphql.mixins_v1 import CustomFieldsMixinV1, TagsMixinV1, ContactsMixinV1
-from netbox.graphql.types_v1 import BaseObjectTypeV1, OrganizationalObjectTypeV1, NetBoxObjectTypeV1
+from netbox.graphql.types_v1 import (
+    BaseObjectTypeV1, OrganizationalObjectTypeV1, PrimaryObjectTypeV1
+)
 from tenancy import models
 from tenancy import models
 from .filters_v1 import *
 from .filters_v1 import *
 from .mixins_v1 import ContactAssignmentsMixinV1
 from .mixins_v1 import ContactAssignmentsMixinV1
@@ -57,7 +59,7 @@ __all__ = (
     filters=TenantFilterV1,
     filters=TenantFilterV1,
     pagination=True
     pagination=True
 )
 )
-class TenantTypeV1(ContactsMixinV1, NetBoxObjectTypeV1):
+class TenantTypeV1(ContactsMixinV1, PrimaryObjectTypeV1):
     group: Annotated['TenantGroupTypeV1', strawberry.lazy('tenancy.graphql.types_v1')] | None
     group: Annotated['TenantGroupTypeV1', strawberry.lazy('tenancy.graphql.types_v1')] | None
     asns: List[Annotated['ASNTypeV1', strawberry.lazy('ipam.graphql.types_v1')]]
     asns: List[Annotated['ASNTypeV1', strawberry.lazy('ipam.graphql.types_v1')]]
     circuits: List[Annotated['CircuitTypeV1', strawberry.lazy('circuits.graphql.types_v1')]]
     circuits: List[Annotated['CircuitTypeV1', strawberry.lazy('circuits.graphql.types_v1')]]
@@ -108,7 +110,7 @@ class TenantGroupTypeV1(OrganizationalObjectTypeV1):
     filters=ContactFilterV1,
     filters=ContactFilterV1,
     pagination=True
     pagination=True
 )
 )
-class ContactTypeV1(ContactAssignmentsMixinV1, NetBoxObjectTypeV1):
+class ContactTypeV1(ContactAssignmentsMixinV1, PrimaryObjectTypeV1):
     groups: List[Annotated['ContactGroupTypeV1', strawberry.lazy('tenancy.graphql.types_v1')]]
     groups: List[Annotated['ContactGroupTypeV1', strawberry.lazy('tenancy.graphql.types_v1')]]
 
 
 
 

+ 23 - 0
netbox/users/graphql/filters_v1.py

@@ -10,6 +10,8 @@ from users import models
 
 
 __all__ = (
 __all__ = (
     'GroupFilterV1',
     'GroupFilterV1',
+    'OwnerFilterV1',
+    'OwnerGroupFilterV1',
     'UserFilterV1',
     'UserFilterV1',
 )
 )
 
 
@@ -32,3 +34,24 @@ class UserFilterV1(BaseObjectTypeFilterMixinV1):
     last_login: DatetimeFilterLookup[datetime] | None = strawberry_django.filter_field()
     last_login: DatetimeFilterLookup[datetime] | None = strawberry_django.filter_field()
     groups: Annotated['GroupFilterV1', strawberry.lazy('users.graphql.filters_v1')] | None = (
     groups: Annotated['GroupFilterV1', strawberry.lazy('users.graphql.filters_v1')] | None = (
         strawberry_django.filter_field())
         strawberry_django.filter_field())
+
+
+@strawberry_django.filter_type(models.Owner, lookups=True)
+class OwnerFilterV1(BaseObjectTypeFilterMixinV1):
+    name: FilterLookup[str] | None = strawberry_django.filter_field()
+    description: FilterLookup[str] | None = strawberry_django.filter_field()
+    group: Annotated['OwnerGroupFilterV1', strawberry.lazy('users.graphql.filters_v1')] | None = (
+        strawberry_django.filter_field()
+    )
+    user_groups: Annotated['GroupFilterV1', strawberry.lazy('users.graphql.filters_v1')] | None = (
+        strawberry_django.filter_field()
+    )
+    users: Annotated['UserFilterV1', strawberry.lazy('users.graphql.filters_v1')] | None = (
+        strawberry_django.filter_field()
+    )
+
+
+@strawberry_django.filter_type(models.OwnerGroup, lookups=True)
+class OwnerGroupFilterV1(BaseObjectTypeFilterMixinV1):
+    name: FilterLookup[str] | None = strawberry_django.filter_field()
+    description: FilterLookup[str] | None = strawberry_django.filter_field()

+ 15 - 0
netbox/users/graphql/mixins_v1.py

@@ -0,0 +1,15 @@
+from typing import Annotated, TYPE_CHECKING
+
+import strawberry
+
+if TYPE_CHECKING:
+    from users.graphql.types_v1 import OwnerTypeV1
+
+__all__ = (
+    'OwnerMixinV1',
+)
+
+
+@strawberry.type
+class OwnerMixinV1:
+    owner: Annotated['OwnerTypeV1', strawberry.lazy('users.graphql.types_v1')] | None

+ 6 - 0
netbox/users/graphql/schema_v1.py

@@ -13,3 +13,9 @@ class UsersQueryV1:
 
 
     user: UserTypeV1 = strawberry_django.field()
     user: UserTypeV1 = strawberry_django.field()
     user_list: List[UserTypeV1] = strawberry_django.field()
     user_list: List[UserTypeV1] = strawberry_django.field()
+
+    owner_group: OwnerGroupTypeV1 = strawberry_django.field()
+    owner_group_list: List[OwnerGroupTypeV1] = strawberry_django.field()
+
+    owner: OwnerTypeV1 = strawberry_django.field()
+    owner_list: List[OwnerTypeV1] = strawberry_django.field()

+ 23 - 1
netbox/users/graphql/types_v1.py

@@ -3,11 +3,13 @@ from typing import List
 import strawberry_django
 import strawberry_django
 
 
 from netbox.graphql.types_v1 import BaseObjectTypeV1
 from netbox.graphql.types_v1 import BaseObjectTypeV1
-from users.models import Group, User
+from users.models import Group, Owner, OwnerGroup, User
 from .filters_v1 import *
 from .filters_v1 import *
 
 
 __all__ = (
 __all__ = (
     'GroupTypeV1',
     'GroupTypeV1',
+    'OwnerGroupTypeV1',
+    'OwnerTypeV1',
     'UserTypeV1',
     'UserTypeV1',
 )
 )
 
 
@@ -32,3 +34,23 @@ class GroupTypeV1(BaseObjectTypeV1):
 )
 )
 class UserTypeV1(BaseObjectTypeV1):
 class UserTypeV1(BaseObjectTypeV1):
     groups: List[GroupTypeV1]
     groups: List[GroupTypeV1]
+
+
+@strawberry_django.type(
+    OwnerGroup,
+    fields=['id', 'name', 'description'],
+    filters=OwnerGroupFilterV1,
+    pagination=True
+)
+class OwnerGroupTypeV1(BaseObjectTypeV1):
+    pass
+
+
+@strawberry_django.type(
+    Owner,
+    fields=['id', 'group', 'name', 'description', 'user_groups', 'users'],
+    filters=OwnerFilterV1,
+    pagination=True
+)
+class OwnerTypeV1(BaseObjectTypeV1):
+    group: OwnerGroupTypeV1 | None

+ 5 - 4
netbox/virtualization/graphql/types_v1.py

@@ -6,7 +6,8 @@ import strawberry_django
 from extras.graphql.mixins_v1 import ConfigContextMixinV1, ContactsMixinV1
 from extras.graphql.mixins_v1 import ConfigContextMixinV1, ContactsMixinV1
 from ipam.graphql.mixins_v1 import IPAddressesMixinV1, VLANGroupsMixinV1
 from ipam.graphql.mixins_v1 import IPAddressesMixinV1, VLANGroupsMixinV1
 from netbox.graphql.scalars import BigInt
 from netbox.graphql.scalars import BigInt
-from netbox.graphql.types_v1 import OrganizationalObjectTypeV1, NetBoxObjectTypeV1
+from netbox.graphql.types_v1 import OrganizationalObjectTypeV1, NetBoxObjectTypeV1, PrimaryObjectTypeV1
+from users.graphql.mixins_v1 import OwnerMixinV1
 from virtualization import models
 from virtualization import models
 from .filters_v1 import *
 from .filters_v1 import *
 
 
@@ -36,7 +37,7 @@ __all__ = (
 
 
 
 
 @strawberry.type
 @strawberry.type
-class ComponentTypeV1(NetBoxObjectTypeV1):
+class ComponentTypeV1(OwnerMixinV1, NetBoxObjectTypeV1):
     """
     """
     Base type for device/VM components
     Base type for device/VM components
     """
     """
@@ -49,7 +50,7 @@ class ComponentTypeV1(NetBoxObjectTypeV1):
     filters=ClusterFilterV1,
     filters=ClusterFilterV1,
     pagination=True
     pagination=True
 )
 )
-class ClusterTypeV1(ContactsMixinV1, VLANGroupsMixinV1, NetBoxObjectTypeV1):
+class ClusterTypeV1(ContactsMixinV1, VLANGroupsMixinV1, PrimaryObjectTypeV1):
     type: Annotated["ClusterTypeTypeV1", strawberry.lazy('virtualization.graphql.types_v1')] | None
     type: Annotated["ClusterTypeTypeV1", strawberry.lazy('virtualization.graphql.types_v1')] | None
     group: Annotated["ClusterGroupTypeV1", strawberry.lazy('virtualization.graphql.types_v1')] | None
     group: Annotated["ClusterGroupTypeV1", strawberry.lazy('virtualization.graphql.types_v1')] | None
     tenant: Annotated["TenantTypeV1", strawberry.lazy('tenancy.graphql.types_v1')] | None
     tenant: Annotated["TenantTypeV1", strawberry.lazy('tenancy.graphql.types_v1')] | None
@@ -94,7 +95,7 @@ class ClusterTypeTypeV1(OrganizationalObjectTypeV1):
     filters=VirtualMachineFilterV1,
     filters=VirtualMachineFilterV1,
     pagination=True
     pagination=True
 )
 )
-class VirtualMachineTypeV1(ConfigContextMixinV1, ContactsMixinV1, NetBoxObjectTypeV1):
+class VirtualMachineTypeV1(ConfigContextMixinV1, ContactsMixinV1, PrimaryObjectTypeV1):
     interface_count: BigInt
     interface_count: BigInt
     virtual_disk_count: BigInt
     virtual_disk_count: BigInt
     interface_count: BigInt
     interface_count: BigInt

+ 5 - 6
netbox/vpn/graphql/types_v1.py

@@ -4,7 +4,7 @@ import strawberry
 import strawberry_django
 import strawberry_django
 
 
 from extras.graphql.mixins_v1 import ContactsMixinV1, CustomFieldsMixinV1, TagsMixinV1
 from extras.graphql.mixins_v1 import ContactsMixinV1, CustomFieldsMixinV1, TagsMixinV1
-from netbox.graphql.types_v1 import ObjectTypeV1, OrganizationalObjectTypeV1, NetBoxObjectTypeV1
+from netbox.graphql.types_v1 import ObjectTypeV1, OrganizationalObjectTypeV1, NetBoxObjectTypeV1, PrimaryObjectTypeV1
 from vpn import models
 from vpn import models
 from .filters_v1 import *
 from .filters_v1 import *
 
 
@@ -58,7 +58,7 @@ class TunnelTerminationTypeV1(CustomFieldsMixinV1, TagsMixinV1, ObjectTypeV1):
     filters=TunnelFilterV1,
     filters=TunnelFilterV1,
     pagination=True
     pagination=True
 )
 )
-class TunnelTypeV1(ContactsMixinV1, NetBoxObjectTypeV1):
+class TunnelTypeV1(ContactsMixinV1, PrimaryObjectTypeV1):
     group: Annotated["TunnelGroupTypeV1", strawberry.lazy('vpn.graphql.types_v1')] | None
     group: Annotated["TunnelGroupTypeV1", strawberry.lazy('vpn.graphql.types_v1')] | None
     ipsec_profile: Annotated["IPSecProfileTypeV1", strawberry.lazy('vpn.graphql.types_v1')] | None
     ipsec_profile: Annotated["IPSecProfileTypeV1", strawberry.lazy('vpn.graphql.types_v1')] | None
     tenant: Annotated["TenantTypeV1", strawberry.lazy('tenancy.graphql.types_v1')] | None
     tenant: Annotated["TenantTypeV1", strawberry.lazy('tenancy.graphql.types_v1')] | None
@@ -72,8 +72,7 @@ class TunnelTypeV1(ContactsMixinV1, NetBoxObjectTypeV1):
     filters=IKEProposalFilterV1,
     filters=IKEProposalFilterV1,
     pagination=True
     pagination=True
 )
 )
-class IKEProposalTypeV1(OrganizationalObjectTypeV1):
-
+class IKEProposalTypeV1(PrimaryObjectTypeV1):
     ike_policies: List[Annotated["IKEPolicyTypeV1", strawberry.lazy('vpn.graphql.types_v1')]]
     ike_policies: List[Annotated["IKEPolicyTypeV1", strawberry.lazy('vpn.graphql.types_v1')]]
 
 
 
 
@@ -95,7 +94,7 @@ class IKEPolicyTypeV1(OrganizationalObjectTypeV1):
     filters=IPSecProposalFilterV1,
     filters=IPSecProposalFilterV1,
     pagination=True
     pagination=True
 )
 )
-class IPSecProposalTypeV1(OrganizationalObjectTypeV1):
+class IPSecProposalTypeV1(PrimaryObjectTypeV1):
 
 
     ipsec_policies: List[Annotated["IPSecPolicyTypeV1", strawberry.lazy('vpn.graphql.types_v1')]]
     ipsec_policies: List[Annotated["IPSecPolicyTypeV1", strawberry.lazy('vpn.graphql.types_v1')]]
 
 
@@ -131,7 +130,7 @@ class IPSecProfileTypeV1(OrganizationalObjectTypeV1):
     filters=L2VPNFilterV1,
     filters=L2VPNFilterV1,
     pagination=True
     pagination=True
 )
 )
-class L2VPNTypeV1(ContactsMixinV1, NetBoxObjectTypeV1):
+class L2VPNTypeV1(ContactsMixinV1, PrimaryObjectTypeV1):
     tenant: Annotated["TenantTypeV1", strawberry.lazy('tenancy.graphql.types_v1')] | None
     tenant: Annotated["TenantTypeV1", strawberry.lazy('tenancy.graphql.types_v1')] | None
 
 
     export_targets: List[Annotated["RouteTargetTypeV1", strawberry.lazy('ipam.graphql.types_v1')]]
     export_targets: List[Annotated["RouteTargetTypeV1", strawberry.lazy('ipam.graphql.types_v1')]]

+ 4 - 4
netbox/wireless/graphql/types_v1.py

@@ -3,7 +3,7 @@ from typing import Annotated, List, TYPE_CHECKING, Union
 import strawberry
 import strawberry
 import strawberry_django
 import strawberry_django
 
 
-from netbox.graphql.types_v1 import OrganizationalObjectTypeV1, NetBoxObjectTypeV1
+from netbox.graphql.types_v1 import PrimaryObjectTypeV1, NestedGroupObjectTypeV1
 from wireless import models
 from wireless import models
 from .filters_v1 import *
 from .filters_v1 import *
 
 
@@ -27,7 +27,7 @@ __all__ = (
     filters=WirelessLANGroupFilterV1,
     filters=WirelessLANGroupFilterV1,
     pagination=True
     pagination=True
 )
 )
-class WirelessLANGroupTypeV1(OrganizationalObjectTypeV1):
+class WirelessLANGroupTypeV1(NestedGroupObjectTypeV1):
     parent: Annotated["WirelessLANGroupTypeV1", strawberry.lazy('wireless.graphql.types_v1')] | None
     parent: Annotated["WirelessLANGroupTypeV1", strawberry.lazy('wireless.graphql.types_v1')] | None
 
 
     wireless_lans: List[Annotated["WirelessLANTypeV1", strawberry.lazy('wireless.graphql.types_v1')]]
     wireless_lans: List[Annotated["WirelessLANTypeV1", strawberry.lazy('wireless.graphql.types_v1')]]
@@ -40,7 +40,7 @@ class WirelessLANGroupTypeV1(OrganizationalObjectTypeV1):
     filters=WirelessLANFilterV1,
     filters=WirelessLANFilterV1,
     pagination=True
     pagination=True
 )
 )
-class WirelessLANTypeV1(NetBoxObjectTypeV1):
+class WirelessLANTypeV1(PrimaryObjectTypeV1):
     group: Annotated["WirelessLANGroupTypeV1", strawberry.lazy('wireless.graphql.types_v1')] | None
     group: Annotated["WirelessLANGroupTypeV1", strawberry.lazy('wireless.graphql.types_v1')] | None
     vlan: Annotated["VLANTypeV1", strawberry.lazy('ipam.graphql.types_v1')] | None
     vlan: Annotated["VLANTypeV1", strawberry.lazy('ipam.graphql.types_v1')] | None
     tenant: Annotated["TenantTypeV1", strawberry.lazy('tenancy.graphql.types_v1')] | None
     tenant: Annotated["TenantTypeV1", strawberry.lazy('tenancy.graphql.types_v1')] | None
@@ -63,7 +63,7 @@ class WirelessLANTypeV1(NetBoxObjectTypeV1):
     filters=WirelessLinkFilterV1,
     filters=WirelessLinkFilterV1,
     pagination=True
     pagination=True
 )
 )
-class WirelessLinkTypeV1(NetBoxObjectTypeV1):
+class WirelessLinkTypeV1(PrimaryObjectTypeV1):
     interface_a: Annotated["InterfaceTypeV1", strawberry.lazy('dcim.graphql.types_v1')]
     interface_a: Annotated["InterfaceTypeV1", strawberry.lazy('dcim.graphql.types_v1')]
     interface_b: Annotated["InterfaceTypeV1", strawberry.lazy('dcim.graphql.types_v1')]
     interface_b: Annotated["InterfaceTypeV1", strawberry.lazy('dcim.graphql.types_v1')]
     tenant: Annotated["TenantTypeV1", strawberry.lazy('tenancy.graphql.types_v1')] | None
     tenant: Annotated["TenantTypeV1", strawberry.lazy('tenancy.graphql.types_v1')] | None