Coverage for dcim/graphql/types.py: 83%
231 statements
« prev ^ index » next coverage.py v7.15.2, created at 2026-10-10 18:35 +0000
« prev ^ index » next coverage.py v7.15.2, created at 2026-10-10 18:35 +0000
1from typing import TYPE_CHECKING, Annotated
3import strawberry
4import strawberry_django
5from django.db.models import Func, IntegerField, Prefetch
7from circuits.models import CircuitTermination
8from core.graphql.mixins import ChangelogMixin
9from dcim import models
10from dcim.choices import CableEndChoices
11from extras.graphql.mixins import ConfigContextMixin, ContactsMixin, ImageAttachmentsMixin
12from ipam.graphql.mixins import IPAddressesMixin, VLANGroupsMixin
13from netbox.graphql.optimization import build_gfk_prefetch
14from netbox.graphql.scalars import BigInt
15from netbox.graphql.types import (
16 BaseObjectType,
17 LtreeNodeMixin,
18 NestedLtreeGroupObjectType,
19 NetBoxObjectType,
20 OrganizationalObjectType,
21 PrimaryObjectType,
22 register_type,
23)
24from users.graphql.mixins import OwnerMixin
25from utilities.querysets import RestrictedPrefetch
26from virtualization.models import Cluster, VMInterface
28from .filters import *
29from .mixins import CabledObjectMixin, PathEndpointMixin
31if TYPE_CHECKING: 31 ↛ 32line 31 didn't jump to line 32 because the condition on line 31 was never true
32 from circuits.graphql.types import CircuitTerminationType
33 from extras.graphql.types import ConfigTemplateType
34 from ipam.graphql.types import (
35 ASNType,
36 IPAddressType,
37 PrefixType,
38 ServiceType,
39 VLANTranslationPolicyType,
40 VLANType,
41 VRFType,
42 )
43 from tenancy.graphql.types import TenantType
44 from users.graphql.types import UserType
45 from virtualization.graphql.types import ClusterType, VirtualMachineType, VMInterfaceType
46 from vpn.graphql.types import L2VPNTerminationType
47 from wireless.graphql.types import WirelessLANType, WirelessLinkType
49__all__ = (
50 'CableBundleType',
51 'CableType',
52 'ComponentType',
53 'ConsolePortTemplateType',
54 'ConsolePortType',
55 'ConsoleServerPortTemplateType',
56 'ConsoleServerPortType',
57 'CoolingFeedType',
58 'CoolingIntakeTemplateType',
59 'CoolingIntakeType',
60 'CoolingOutflowTemplateType',
61 'CoolingOutflowType',
62 'CoolingSourceType',
63 'DeviceBayTemplateType',
64 'DeviceBayType',
65 'DeviceRoleType',
66 'DeviceType',
67 'DeviceTypeType',
68 'FrontPortTemplateType',
69 'FrontPortType',
70 'InterfaceTemplateType',
71 'InterfaceType',
72 'InventoryItemRoleType',
73 'InventoryItemTemplateType',
74 'InventoryItemType',
75 'LocationType',
76 'MACAddressType',
77 'ManufacturerType',
78 'ModularComponentType',
79 'ModuleBayTemplateType',
80 'ModuleBayType',
81 'ModuleBayTypeType',
82 'ModuleType',
83 'ModuleTypeProfileType',
84 'ModuleTypeType',
85 'PlatformType',
86 'PowerFeedType',
87 'PowerOutletTemplateType',
88 'PowerOutletType',
89 'PowerPanelType',
90 'PowerPortTemplateType',
91 'PowerPortType',
92 'RackGroupType',
93 'RackReservationType',
94 'RackRoleType',
95 'RackType',
96 'RackTypeType',
97 'RearPortTemplateType',
98 'RearPortType',
99 'RegionType',
100 'SiteGroupType',
101 'SiteType',
102 'VirtualChassisType',
103 'VirtualDeviceContextType',
104)
107#
108# Cable termination prefetching
109#
111# The concrete models which may terminate a cable, mirroring dcim.constants.CABLE_TERMINATION_MODELS
112_CABLE_TERMINATION_MODELS = (
113 CircuitTermination,
114 models.ConsolePort,
115 models.ConsoleServerPort,
116 models.FrontPort,
117 models.Interface,
118 models.PowerFeed,
119 models.PowerOutlet,
120 models.PowerPort,
121 models.RearPort,
122)
124_termination_gfk_prefetch = build_gfk_prefetch('termination', _CABLE_TERMINATION_MODELS)
127def _cable_terminations_prefetch(side, to_attr):
128 """
129 Return a callable which builds a selection-aware Prefetch of a cable's terminations for the
130 given cable end.
132 Each end is prefetched under its own `to_attr`: two prefetches of the same relation cannot be
133 merged by the query optimizer, so a shared lookup would break any query selecting both ends.
134 """
135 def prefetch(info):
136 return Prefetch(
137 'terminations',
138 queryset=models.CableTermination.objects.filter(cable_end=side).prefetch_related(
139 _termination_gfk_prefetch(info)
140 ),
141 to_attr=to_attr,
142 )
144 return prefetch
147def _resolve_cable_terminations(cable, side, to_attr):
148 """
149 Return the terminating objects for the given cable end, using the prefetched terminations if
150 available and falling back to the model property otherwise.
151 """
152 if (terminations := getattr(cable, to_attr, None)) is not None:
153 return [ct.termination for ct in terminations]
155 return cable._get_x_terminations(side)
158#
159# Base types
160#
163@strawberry.type
164class ComponentType(OwnerMixin, NetBoxObjectType):
165 """
166 Base type for device/VM components
167 """
168 device: Annotated["DeviceType", strawberry.lazy('dcim.graphql.types')]
171@strawberry.type
172class ModularComponentType(ComponentType):
173 module: Annotated["ModuleType", strawberry.lazy('dcim.graphql.types')] | None
176@strawberry.type
177class ComponentTemplateType(ChangelogMixin, BaseObjectType):
178 """
179 Base type for device/VM components
180 """
181 device_type: Annotated["DeviceTypeType", strawberry.lazy('dcim.graphql.types')]
184@strawberry.type
185class ModularComponentTemplateType(ComponentTemplateType):
186 """
187 Base type for ComponentTemplateModel which supports optional assignment to a ModuleType.
188 """
189 device_type: Annotated["DeviceTypeType", strawberry.lazy('dcim.graphql.types')] | None
190 module_type: Annotated["ModuleTypeType", strawberry.lazy('dcim.graphql.types')] | None
192#
193# Model types
194#
197@register_type(
198 models.CableBundle,
199 fields='__all__',
200 filters=CableBundleFilter,
201 pagination=True
202)
203class CableBundleType(PrimaryObjectType):
204 cables: list[Annotated['CableType', strawberry.lazy('dcim.graphql.types')]]
207@register_type(
208 models.CableTermination,
209 exclude=['termination_type', 'termination_id', '_device', '_rack', '_location', '_site'],
210 filters=CableTerminationFilter,
211 pagination=True
212)
213class CableTerminationType(NetBoxObjectType):
214 cable: Annotated['CableType', strawberry.lazy('dcim.graphql.types')] | None
216 @strawberry_django.field(
217 prefetch_related=_termination_gfk_prefetch,
218 only=['termination_type', 'termination_id'],
219 )
220 def termination(self) -> Annotated[
221 Annotated['CircuitTerminationType', strawberry.lazy('circuits.graphql.types')]
222 | Annotated['ConsolePortType', strawberry.lazy('dcim.graphql.types')]
223 | Annotated['ConsoleServerPortType', strawberry.lazy('dcim.graphql.types')]
224 | Annotated['FrontPortType', strawberry.lazy('dcim.graphql.types')]
225 | Annotated['InterfaceType', strawberry.lazy('dcim.graphql.types')]
226 | Annotated['PowerFeedType', strawberry.lazy('dcim.graphql.types')]
227 | Annotated['PowerOutletType', strawberry.lazy('dcim.graphql.types')]
228 | Annotated['PowerPortType', strawberry.lazy('dcim.graphql.types')]
229 | Annotated['RearPortType', strawberry.lazy('dcim.graphql.types')],
230 strawberry.union('CableTerminationTerminationType'),
231 ] | None:
232 return self.termination
235@register_type(
236 models.Cable,
237 fields='__all__',
238 filters=CableFilter,
239 pagination=True
240)
241class CableType(PrimaryObjectType):
242 color: str
243 tenant: Annotated['TenantType', strawberry.lazy('tenancy.graphql.types')] | None
244 bundle: Annotated['CableBundleType', strawberry.lazy('dcim.graphql.types')] | None
246 terminations: list[CableTerminationType]
248 @strawberry_django.field(
249 prefetch_related=_cable_terminations_prefetch(CableEndChoices.SIDE_A, '_prefetched_a_terminations'),
250 )
251 def a_terminations(self) -> list[Annotated[
252 Annotated['CircuitTerminationType', strawberry.lazy('circuits.graphql.types')]
253 | Annotated['ConsolePortType', strawberry.lazy('dcim.graphql.types')]
254 | Annotated['ConsoleServerPortType', strawberry.lazy('dcim.graphql.types')]
255 | Annotated['FrontPortType', strawberry.lazy('dcim.graphql.types')]
256 | Annotated['InterfaceType', strawberry.lazy('dcim.graphql.types')]
257 | Annotated['PowerFeedType', strawberry.lazy('dcim.graphql.types')]
258 | Annotated['PowerOutletType', strawberry.lazy('dcim.graphql.types')]
259 | Annotated['PowerPortType', strawberry.lazy('dcim.graphql.types')]
260 | Annotated['RearPortType', strawberry.lazy('dcim.graphql.types')],
261 strawberry.union('CableTerminationTerminationType'),
262 ]]:
263 return _resolve_cable_terminations(self, CableEndChoices.SIDE_A, '_prefetched_a_terminations')
265 @strawberry_django.field(
266 prefetch_related=_cable_terminations_prefetch(CableEndChoices.SIDE_B, '_prefetched_b_terminations'),
267 )
268 def b_terminations(self) -> list[Annotated[
269 Annotated['CircuitTerminationType', strawberry.lazy('circuits.graphql.types')]
270 | Annotated['ConsolePortType', strawberry.lazy('dcim.graphql.types')]
271 | Annotated['ConsoleServerPortType', strawberry.lazy('dcim.graphql.types')]
272 | Annotated['FrontPortType', strawberry.lazy('dcim.graphql.types')]
273 | Annotated['InterfaceType', strawberry.lazy('dcim.graphql.types')]
274 | Annotated['PowerFeedType', strawberry.lazy('dcim.graphql.types')]
275 | Annotated['PowerOutletType', strawberry.lazy('dcim.graphql.types')]
276 | Annotated['PowerPortType', strawberry.lazy('dcim.graphql.types')]
277 | Annotated['RearPortType', strawberry.lazy('dcim.graphql.types')],
278 strawberry.union('CableTerminationTerminationType'),
279 ]]:
280 return _resolve_cable_terminations(self, CableEndChoices.SIDE_B, '_prefetched_b_terminations')
283@register_type(
284 models.ConsolePort,
285 exclude=['_path'],
286 filters=ConsolePortFilter,
287 pagination=True
288)
289class ConsolePortType(ModularComponentType, CabledObjectMixin, PathEndpointMixin):
290 pass
293@register_type(
294 models.ConsolePortTemplate,
295 fields='__all__',
296 filters=ConsolePortTemplateFilter,
297 pagination=True
298)
299class ConsolePortTemplateType(ModularComponentTemplateType):
300 pass
303@register_type(
304 models.ConsoleServerPort,
305 exclude=['_path'],
306 filters=ConsoleServerPortFilter,
307 pagination=True
308)
309class ConsoleServerPortType(ModularComponentType, CabledObjectMixin, PathEndpointMixin):
310 pass
313@register_type(
314 models.ConsoleServerPortTemplate,
315 fields='__all__',
316 filters=ConsoleServerPortTemplateFilter,
317 pagination=True
318)
319class ConsoleServerPortTemplateType(ModularComponentTemplateType):
320 pass
323@register_type(
324 models.Device,
325 fields='__all__',
326 filters=DeviceFilter,
327 pagination=True
328)
329class DeviceType(ConfigContextMixin, ImageAttachmentsMixin, ContactsMixin, PrimaryObjectType):
330 console_port_count: BigInt
331 console_server_port_count: BigInt
332 power_port_count: BigInt
333 power_outlet_count: BigInt
334 cooling_intake_count: BigInt
335 cooling_outflow_count: BigInt
336 interface_count: BigInt
337 front_port_count: BigInt
338 rear_port_count: BigInt
339 device_bay_count: BigInt
340 module_bay_count: BigInt
341 inventory_item_count: BigInt
342 config_template: Annotated["ConfigTemplateType", strawberry.lazy('extras.graphql.types')] | None
343 device_type: Annotated["DeviceTypeType", strawberry.lazy('dcim.graphql.types')]
344 role: Annotated["DeviceRoleType", strawberry.lazy('dcim.graphql.types')]
345 tenant: Annotated["TenantType", strawberry.lazy('tenancy.graphql.types')] | None
346 platform: Annotated["PlatformType", strawberry.lazy('dcim.graphql.types')] | None
347 site: Annotated["SiteType", strawberry.lazy('dcim.graphql.types')]
348 location: Annotated["LocationType", strawberry.lazy('dcim.graphql.types')] | None
349 rack: Annotated["RackType", strawberry.lazy('dcim.graphql.types')] | None
350 primary_ip4: Annotated["IPAddressType", strawberry.lazy('ipam.graphql.types')] | None
351 primary_ip6: Annotated["IPAddressType", strawberry.lazy('ipam.graphql.types')] | None
352 oob_ip: Annotated["IPAddressType", strawberry.lazy('ipam.graphql.types')] | None
353 cluster: Annotated["ClusterType", strawberry.lazy('virtualization.graphql.types')] | None
354 virtual_chassis: Annotated["VirtualChassisType", strawberry.lazy('dcim.graphql.types')] | None
356 virtual_machines: list[Annotated["VirtualMachineType", strawberry.lazy('virtualization.graphql.types')]]
357 modules: list[Annotated["ModuleType", strawberry.lazy('dcim.graphql.types')]]
358 interfaces: list[Annotated["InterfaceType", strawberry.lazy('dcim.graphql.types')]]
359 rearports: list[Annotated["RearPortType", strawberry.lazy('dcim.graphql.types')]]
360 consoleports: list[Annotated["ConsolePortType", strawberry.lazy('dcim.graphql.types')]]
361 powerports: list[Annotated["PowerPortType", strawberry.lazy('dcim.graphql.types')]]
362 coolingintakes: list[Annotated["CoolingIntakeType", strawberry.lazy('dcim.graphql.types')]]
363 cabletermination_set: list[Annotated["CableTerminationType", strawberry.lazy('dcim.graphql.types')]]
364 consoleserverports: list[Annotated["ConsoleServerPortType", strawberry.lazy('dcim.graphql.types')]]
365 poweroutlets: list[Annotated["PowerOutletType", strawberry.lazy('dcim.graphql.types')]]
366 coolingoutflows: list[Annotated["CoolingOutflowType", strawberry.lazy('dcim.graphql.types')]]
367 frontports: list[Annotated["FrontPortType", strawberry.lazy('dcim.graphql.types')]]
368 devicebays: list[Annotated["DeviceBayType", strawberry.lazy('dcim.graphql.types')]]
369 modulebays: list[Annotated["ModuleBayType", strawberry.lazy('dcim.graphql.types')]]
370 services: list[Annotated["ServiceType", strawberry.lazy('ipam.graphql.types')]]
371 inventoryitems: list[Annotated["InventoryItemType", strawberry.lazy('dcim.graphql.types')]]
372 vdcs: list[Annotated["VirtualDeviceContextType", strawberry.lazy('dcim.graphql.types')]]
374 @strawberry_django.field(prefetch_related='vc_master_for')
375 def vc_master_for(self) -> Annotated["VirtualChassisType", strawberry.lazy('dcim.graphql.types')] | None:
376 return self.vc_master_for if hasattr(self, 'vc_master_for') else None
378 @strawberry_django.field(prefetch_related='parent_bay')
379 def parent_bay(self) -> Annotated["DeviceBayType", strawberry.lazy('dcim.graphql.types')] | None:
380 return self.parent_bay if hasattr(self, 'parent_bay') else None
383@register_type(
384 models.DeviceBay,
385 fields='__all__',
386 filters=DeviceBayFilter,
387 pagination=True
388)
389class DeviceBayType(ComponentType):
390 installed_device: Annotated["DeviceType", strawberry.lazy('dcim.graphql.types')] | None
393@register_type(
394 models.DeviceBayTemplate,
395 fields='__all__',
396 filters=DeviceBayTemplateFilter,
397 pagination=True
398)
399class DeviceBayTemplateType(ComponentTemplateType):
400 pass
403@register_type(
404 models.InventoryItemTemplate,
405 exclude=['component_type', 'component_id', 'parent', 'path'],
406 filters=InventoryItemTemplateFilter,
407 pagination=True
408)
409class InventoryItemTemplateType(LtreeNodeMixin, ComponentTemplateType):
410 role: Annotated['InventoryItemRoleType', strawberry.lazy('dcim.graphql.types')] | None
411 manufacturer: Annotated['ManufacturerType', strawberry.lazy('dcim.graphql.types')]
413 @strawberry_django.field(prefetch_related='parent', only=['parent_id'])
414 def parent(self) -> Annotated['InventoryItemTemplateType', strawberry.lazy('dcim.graphql.types')] | None:
415 return self.parent
417 child_items: list[Annotated['InventoryItemTemplateType', strawberry.lazy('dcim.graphql.types')]]
419 @strawberry_django.field(
420 prefetch_related=build_gfk_prefetch(
421 'component',
422 [
423 models.ConsolePortTemplate,
424 models.ConsoleServerPortTemplate,
425 models.FrontPortTemplate,
426 models.InterfaceTemplate,
427 models.PowerOutletTemplate,
428 models.PowerPortTemplate,
429 models.RearPortTemplate,
430 ],
431 ),
432 only=['component_type', 'component_id'],
433 )
434 def component(self) -> Annotated[
435 Annotated['ConsolePortTemplateType', strawberry.lazy('dcim.graphql.types')]
436 | Annotated['ConsoleServerPortTemplateType', strawberry.lazy('dcim.graphql.types')]
437 | Annotated['FrontPortTemplateType', strawberry.lazy('dcim.graphql.types')]
438 | Annotated['InterfaceTemplateType', strawberry.lazy('dcim.graphql.types')]
439 | Annotated['PowerOutletTemplateType', strawberry.lazy('dcim.graphql.types')]
440 | Annotated['PowerPortTemplateType', strawberry.lazy('dcim.graphql.types')]
441 | Annotated['RearPortTemplateType', strawberry.lazy('dcim.graphql.types')],
442 strawberry.union('InventoryItemTemplateComponentType'),
443 ] | None:
444 return self.component
447@register_type(
448 models.DeviceRole,
449 exclude=['path', 'sort_path'],
450 filters=DeviceRoleFilter,
451 pagination=True
452)
453class DeviceRoleType(NestedLtreeGroupObjectType):
454 parent: Annotated['DeviceRoleType', strawberry.lazy('dcim.graphql.types')] | None
455 children: list[Annotated['DeviceRoleType', strawberry.lazy('dcim.graphql.types')]]
456 color: str
457 config_template: Annotated["ConfigTemplateType", strawberry.lazy('extras.graphql.types')] | None
459 virtual_machines: list[Annotated["VirtualMachineType", strawberry.lazy('virtualization.graphql.types')]]
460 devices: list[Annotated["DeviceType", strawberry.lazy('dcim.graphql.types')]]
463@register_type(
464 models.DeviceType,
465 fields='__all__',
466 filters=DeviceTypeFilter,
467 pagination=True
468)
469class DeviceTypeType(PrimaryObjectType):
470 console_port_template_count: BigInt
471 console_server_port_template_count: BigInt
472 power_port_template_count: BigInt
473 power_outlet_template_count: BigInt
474 cooling_intake_template_count: BigInt
475 cooling_outflow_template_count: BigInt
476 interface_template_count: BigInt
477 front_port_template_count: BigInt
478 rear_port_template_count: BigInt
479 device_bay_template_count: BigInt
480 module_bay_template_count: BigInt
481 inventory_item_template_count: BigInt
482 device_count: BigInt
483 front_image: strawberry_django.fields.types.DjangoImageType | None
484 rear_image: strawberry_django.fields.types.DjangoImageType | None
485 manufacturer: Annotated["ManufacturerType", strawberry.lazy('dcim.graphql.types')]
486 default_platform: Annotated["PlatformType", strawberry.lazy('dcim.graphql.types')] | None
488 frontporttemplates: list[Annotated["FrontPortTemplateType", strawberry.lazy('dcim.graphql.types')]]
489 modulebaytemplates: list[Annotated["ModuleBayTemplateType", strawberry.lazy('dcim.graphql.types')]]
490 instances: list[Annotated["DeviceType", strawberry.lazy('dcim.graphql.types')]]
491 poweroutlettemplates: list[Annotated["PowerOutletTemplateType", strawberry.lazy('dcim.graphql.types')]]
492 powerporttemplates: list[Annotated["PowerPortTemplateType", strawberry.lazy('dcim.graphql.types')]]
493 coolingoutflowtemplates: list[Annotated["CoolingOutflowTemplateType", strawberry.lazy('dcim.graphql.types')]]
494 coolingintaketemplates: list[Annotated["CoolingIntakeTemplateType", strawberry.lazy('dcim.graphql.types')]]
495 inventoryitemtemplates: list[Annotated["InventoryItemTemplateType", strawberry.lazy('dcim.graphql.types')]]
496 rearporttemplates: list[Annotated["RearPortTemplateType", strawberry.lazy('dcim.graphql.types')]]
497 consoleserverporttemplates: list[Annotated["ConsoleServerPortTemplateType", strawberry.lazy('dcim.graphql.types')]]
498 interfacetemplates: list[Annotated["InterfaceTemplateType", strawberry.lazy('dcim.graphql.types')]]
499 devicebaytemplates: list[Annotated["DeviceBayTemplateType", strawberry.lazy('dcim.graphql.types')]]
500 consoleporttemplates: list[Annotated["ConsolePortTemplateType", strawberry.lazy('dcim.graphql.types')]]
503@register_type(
504 models.FrontPort,
505 fields='__all__',
506 filters=FrontPortFilter,
507 pagination=True
508)
509class FrontPortType(ModularComponentType, CabledObjectMixin):
510 color: str
512 mappings: list[Annotated["PortMappingType", strawberry.lazy('dcim.graphql.types')]]
515@register_type(
516 models.FrontPortTemplate,
517 fields='__all__',
518 filters=FrontPortTemplateFilter,
519 pagination=True
520)
521class FrontPortTemplateType(ModularComponentTemplateType):
522 color: str
524 mappings: list[Annotated["PortMappingTemplateType", strawberry.lazy('dcim.graphql.types')]]
527@register_type(
528 models.MACAddress,
529 exclude=['assigned_object_type', 'assigned_object_id'],
530 filters=MACAddressFilter,
531 pagination=True
532)
533class MACAddressType(PrimaryObjectType):
534 mac_address: str
536 @strawberry_django.field(
537 prefetch_related=build_gfk_prefetch(
538 'assigned_object',
539 [
540 models.Interface,
541 VMInterface,
542 ],
543 ),
544 only=['assigned_object_type', 'assigned_object_id'],
545 )
546 def assigned_object(self) -> Annotated[
547 Annotated['InterfaceType', strawberry.lazy('dcim.graphql.types')]
548 | Annotated['VMInterfaceType', strawberry.lazy('virtualization.graphql.types')],
549 strawberry.union('MACAddressAssignmentType'),
550 ] | None:
551 return self.assigned_object
554@register_type(
555 models.Interface,
556 exclude=['_path'],
557 filters=InterfaceFilter,
558 pagination=True
559)
560class InterfaceType(IPAddressesMixin, ModularComponentType, CabledObjectMixin, PathEndpointMixin):
561 _name: str
562 speed: BigInt | None
563 wwn: str | None
564 parent: Annotated["InterfaceType", strawberry.lazy('dcim.graphql.types')] | None
565 bridge: Annotated["InterfaceType", strawberry.lazy('dcim.graphql.types')] | None
566 lag: Annotated["InterfaceType", strawberry.lazy('dcim.graphql.types')] | None
567 wireless_link: Annotated["WirelessLinkType", strawberry.lazy('wireless.graphql.types')] | None
568 untagged_vlan: Annotated["VLANType", strawberry.lazy('ipam.graphql.types')] | None
569 vrf: Annotated["VRFType", strawberry.lazy('ipam.graphql.types')] | None
570 primary_mac_address: Annotated["MACAddressType", strawberry.lazy('dcim.graphql.types')] | None
571 qinq_svlan: Annotated["VLANType", strawberry.lazy('ipam.graphql.types')] | None
572 vlan_translation_policy: Annotated["VLANTranslationPolicyType", strawberry.lazy('ipam.graphql.types')] | None
573 l2vpn_termination: Annotated["L2VPNTerminationType", strawberry.lazy('vpn.graphql.types')] | None
575 vdcs: list[Annotated["VirtualDeviceContextType", strawberry.lazy('dcim.graphql.types')]]
576 tagged_vlans: list[Annotated["VLANType", strawberry.lazy('ipam.graphql.types')]]
577 bridge_interfaces: list[Annotated["InterfaceType", strawberry.lazy('dcim.graphql.types')]]
578 wireless_lans: list[Annotated["WirelessLANType", strawberry.lazy('wireless.graphql.types')]]
579 member_interfaces: list[Annotated["InterfaceType", strawberry.lazy('dcim.graphql.types')]]
580 child_interfaces: list[Annotated["InterfaceType", strawberry.lazy('dcim.graphql.types')]]
581 mac_addresses: list[Annotated["MACAddressType", strawberry.lazy('dcim.graphql.types')]]
584@register_type(
585 models.InterfaceTemplate,
586 fields='__all__',
587 filters=InterfaceTemplateFilter,
588 pagination=True
589)
590class InterfaceTemplateType(ModularComponentTemplateType):
591 _name: str
592 parent: Annotated["InterfaceTemplateType", strawberry.lazy('dcim.graphql.types')] | None
593 bridge: Annotated["InterfaceTemplateType", strawberry.lazy('dcim.graphql.types')] | None
595 bridge_interfaces: list[Annotated["InterfaceTemplateType", strawberry.lazy('dcim.graphql.types')]]
596 child_interfaces: list[Annotated["InterfaceTemplateType", strawberry.lazy('dcim.graphql.types')]]
599@register_type(
600 models.InventoryItem,
601 exclude=['component_type', 'component_id', 'parent', 'path'],
602 filters=InventoryItemFilter,
603 pagination=True
604)
605class InventoryItemType(LtreeNodeMixin, ComponentType):
606 role: Annotated['InventoryItemRoleType', strawberry.lazy('dcim.graphql.types')] | None
607 manufacturer: Annotated['ManufacturerType', strawberry.lazy('dcim.graphql.types')] | None
609 child_items: list[Annotated['InventoryItemType', strawberry.lazy('dcim.graphql.types')]]
611 @strawberry_django.field(prefetch_related='parent', only=['parent_id'])
612 def parent(self) -> Annotated['InventoryItemType', strawberry.lazy('dcim.graphql.types')] | None:
613 return self.parent
615 @strawberry_django.field(
616 prefetch_related=build_gfk_prefetch(
617 'component',
618 [
619 models.ConsolePort,
620 models.ConsoleServerPort,
621 models.FrontPort,
622 models.Interface,
623 models.PowerOutlet,
624 models.PowerPort,
625 models.RearPort,
626 ],
627 ),
628 only=['component_type', 'component_id'],
629 )
630 def component(self) -> Annotated[
631 Annotated['ConsolePortType', strawberry.lazy('dcim.graphql.types')]
632 | Annotated['ConsoleServerPortType', strawberry.lazy('dcim.graphql.types')]
633 | Annotated['FrontPortType', strawberry.lazy('dcim.graphql.types')]
634 | Annotated['InterfaceType', strawberry.lazy('dcim.graphql.types')]
635 | Annotated['PowerOutletType', strawberry.lazy('dcim.graphql.types')]
636 | Annotated['PowerPortType', strawberry.lazy('dcim.graphql.types')]
637 | Annotated['RearPortType', strawberry.lazy('dcim.graphql.types')],
638 strawberry.union('InventoryItemComponentType'),
639 ] | None:
640 return self.component
643@register_type(
644 models.InventoryItemRole,
645 fields='__all__',
646 filters=InventoryItemRoleFilter,
647 pagination=True
648)
649class InventoryItemRoleType(OrganizationalObjectType):
650 color: str
652 inventory_items: list[Annotated["InventoryItemType", strawberry.lazy('dcim.graphql.types')]]
653 inventory_item_templates: list[Annotated["InventoryItemTemplateType", strawberry.lazy('dcim.graphql.types')]]
656@register_type(
657 models.Location,
658 # fields='__all__',
659 exclude=['parent', 'path', 'sort_path'], # bug - temp
660 filters=LocationFilter,
661 pagination=True
662)
663class LocationType(VLANGroupsMixin, ImageAttachmentsMixin, ContactsMixin, NestedLtreeGroupObjectType):
664 site: Annotated["SiteType", strawberry.lazy('dcim.graphql.types')]
665 tenant: Annotated["TenantType", strawberry.lazy('tenancy.graphql.types')] | None
666 parent: Annotated["LocationType", strawberry.lazy('dcim.graphql.types')] | None
668 powerpanel_set: list[Annotated["PowerPanelType", strawberry.lazy('dcim.graphql.types')]]
669 cabletermination_set: list[Annotated["CableTerminationType", strawberry.lazy('dcim.graphql.types')]]
670 racks: list[Annotated["RackType", strawberry.lazy('dcim.graphql.types')]]
671 devices: list[Annotated["DeviceType", strawberry.lazy('dcim.graphql.types')]]
672 children: list[Annotated["LocationType", strawberry.lazy('dcim.graphql.types')]]
674 @strawberry_django.field(
675 prefetch_related=lambda info: RestrictedPrefetch(
676 'cluster_set', info.context.request.user, 'view', queryset=Cluster.objects.all()
677 ),
678 )
679 def clusters(self) -> list[Annotated["ClusterType", strawberry.lazy('virtualization.graphql.types')]]:
680 return self.cluster_set.all()
682 @strawberry_django.field(
683 prefetch_related=lambda info: RestrictedPrefetch(
684 'circuit_terminations', info.context.request.user, 'view',
685 queryset=CircuitTermination.objects.all()
686 ),
687 )
688 def circuit_terminations(self) -> list[
689 Annotated["CircuitTerminationType", strawberry.lazy('circuits.graphql.types')]
690 ]:
691 return self.circuit_terminations.all()
694@register_type(
695 models.Manufacturer,
696 fields='__all__',
697 filters=ManufacturerFilter,
698 pagination=True
699)
700class ManufacturerType(OrganizationalObjectType, ContactsMixin):
702 platforms: list[Annotated["PlatformType", strawberry.lazy('dcim.graphql.types')]]
703 device_types: list[Annotated["DeviceTypeType", strawberry.lazy('dcim.graphql.types')]]
704 inventory_item_templates: list[Annotated["InventoryItemTemplateType", strawberry.lazy('dcim.graphql.types')]]
705 inventory_items: list[Annotated["InventoryItemType", strawberry.lazy('dcim.graphql.types')]]
706 module_types: list[Annotated["ModuleTypeType", strawberry.lazy('dcim.graphql.types')]]
709@register_type(
710 models.Module,
711 fields='__all__',
712 filters=ModuleFilter,
713 pagination=True
714)
715class ModuleType(PrimaryObjectType):
716 device: Annotated["DeviceType", strawberry.lazy('dcim.graphql.types')]
717 module_bay: Annotated["ModuleBayType", strawberry.lazy('dcim.graphql.types')]
718 module_type: Annotated["ModuleTypeType", strawberry.lazy('dcim.graphql.types')]
720 interfaces: list[Annotated["InterfaceType", strawberry.lazy('dcim.graphql.types')]]
721 powerports: list[Annotated["PowerPortType", strawberry.lazy('dcim.graphql.types')]]
722 coolingintakes: list[Annotated["CoolingIntakeType", strawberry.lazy('dcim.graphql.types')]]
723 consoleserverports: list[Annotated["ConsoleServerPortType", strawberry.lazy('dcim.graphql.types')]]
724 consoleports: list[Annotated["ConsolePortType", strawberry.lazy('dcim.graphql.types')]]
725 poweroutlets: list[Annotated["PowerOutletType", strawberry.lazy('dcim.graphql.types')]]
726 coolingoutflows: list[Annotated["CoolingOutflowType", strawberry.lazy('dcim.graphql.types')]]
727 rearports: list[Annotated["RearPortType", strawberry.lazy('dcim.graphql.types')]]
728 frontports: list[Annotated["FrontPortType", strawberry.lazy('dcim.graphql.types')]]
731@register_type(
732 models.ModuleBay,
733 # fields='__all__',
734 exclude=['parent', 'path', 'sort_path'],
735 filters=ModuleBayFilter,
736 pagination=True
737)
738class ModuleBayType(LtreeNodeMixin, ModularComponentType):
740 installed_module: Annotated["ModuleType", strawberry.lazy('dcim.graphql.types')] | None
741 children: list[Annotated["ModuleBayType", strawberry.lazy('dcim.graphql.types')]]
742 module_bay_types: list[Annotated["ModuleBayTypeType", strawberry.lazy('dcim.graphql.types')]]
744 @strawberry_django.field(prefetch_related='parent', only=['parent_id'])
745 def parent(self) -> Annotated["ModuleBayType", strawberry.lazy('dcim.graphql.types')] | None:
746 return self.parent
749@register_type(
750 models.ModuleBayTemplate,
751 fields='__all__',
752 filters=ModuleBayTemplateFilter,
753 pagination=True
754)
755class ModuleBayTemplateType(ModularComponentTemplateType):
756 module_bay_types: list[Annotated["ModuleBayTypeType", strawberry.lazy('dcim.graphql.types')]]
759@register_type(
760 models.ModuleBayType,
761 fields='__all__',
762 filters=ModuleBayTypeFilter,
763 pagination=True
764)
765class ModuleBayTypeType(PrimaryObjectType):
766 color: str
767 manufacturer: Annotated["ManufacturerType", strawberry.lazy('dcim.graphql.types')] | None
768 module_types: list[Annotated["ModuleTypeType", strawberry.lazy('dcim.graphql.types')]]
769 module_bays: list[Annotated["ModuleBayType", strawberry.lazy('dcim.graphql.types')]]
770 module_bay_templates: list[Annotated["ModuleBayTemplateType", strawberry.lazy('dcim.graphql.types')]]
773@register_type(
774 models.ModuleTypeProfile,
775 fields='__all__',
776 filters=ModuleTypeProfileFilter,
777 pagination=True
778)
779class ModuleTypeProfileType(PrimaryObjectType):
780 module_types: list[Annotated["ModuleType", strawberry.lazy('dcim.graphql.types')]]
783@register_type(
784 models.ModuleType,
785 fields='__all__',
786 filters=ModuleTypeFilter,
787 pagination=True
788)
789class ModuleTypeType(PrimaryObjectType):
790 module_count: BigInt
791 console_port_template_count: BigInt
792 console_server_port_template_count: BigInt
793 power_port_template_count: BigInt
794 power_outlet_template_count: BigInt
795 cooling_intake_template_count: BigInt
796 cooling_outflow_template_count: BigInt
797 interface_template_count: BigInt
798 front_port_template_count: BigInt
799 rear_port_template_count: BigInt
800 module_bay_template_count: BigInt
801 profile: Annotated["ModuleTypeProfileType", strawberry.lazy('dcim.graphql.types')] | None
802 manufacturer: Annotated["ManufacturerType", strawberry.lazy('dcim.graphql.types')]
803 module_bay_types: list[Annotated["ModuleBayTypeType", strawberry.lazy('dcim.graphql.types')]]
805 frontporttemplates: list[Annotated["FrontPortTemplateType", strawberry.lazy('dcim.graphql.types')]]
806 consoleserverporttemplates: list[Annotated["ConsoleServerPortTemplateType", strawberry.lazy('dcim.graphql.types')]]
807 interfacetemplates: list[Annotated["InterfaceTemplateType", strawberry.lazy('dcim.graphql.types')]]
808 powerporttemplates: list[Annotated["PowerPortTemplateType", strawberry.lazy('dcim.graphql.types')]]
809 poweroutlettemplates: list[Annotated["PowerOutletTemplateType", strawberry.lazy('dcim.graphql.types')]]
810 coolingintaketemplates: list[Annotated["CoolingIntakeTemplateType", strawberry.lazy('dcim.graphql.types')]]
811 coolingoutflowtemplates: list[Annotated["CoolingOutflowTemplateType", strawberry.lazy('dcim.graphql.types')]]
812 rearporttemplates: list[Annotated["RearPortTemplateType", strawberry.lazy('dcim.graphql.types')]]
813 instances: list[Annotated["ModuleType", strawberry.lazy('dcim.graphql.types')]]
814 consoleporttemplates: list[Annotated["ConsolePortTemplateType", strawberry.lazy('dcim.graphql.types')]]
817@register_type(
818 models.Platform,
819 exclude=['path', 'sort_path'],
820 filters=PlatformFilter,
821 pagination=True
822)
823class PlatformType(NestedLtreeGroupObjectType):
824 parent: Annotated['PlatformType', strawberry.lazy('dcim.graphql.types')] | None
825 children: list[Annotated['PlatformType', strawberry.lazy('dcim.graphql.types')]]
826 manufacturer: Annotated["ManufacturerType", strawberry.lazy('dcim.graphql.types')] | None
827 config_template: Annotated["ConfigTemplateType", strawberry.lazy('extras.graphql.types')] | None
829 virtual_machines: list[Annotated["VirtualMachineType", strawberry.lazy('virtualization.graphql.types')]]
830 devices: list[Annotated["DeviceType", strawberry.lazy('dcim.graphql.types')]]
833@register_type(
834 models.PortMapping,
835 fields='__all__',
836 filters=PortMappingFilter,
837 pagination=True
838)
839class PortMappingType(ModularComponentTemplateType):
840 front_port: Annotated["FrontPortType", strawberry.lazy('dcim.graphql.types')]
841 rear_port: Annotated["RearPortType", strawberry.lazy('dcim.graphql.types')]
844@register_type(
845 models.PortTemplateMapping,
846 fields='__all__',
847 filters=PortTemplateMappingFilter,
848 pagination=True
849)
850class PortMappingTemplateType(ModularComponentTemplateType):
851 front_port: Annotated["FrontPortTemplateType", strawberry.lazy('dcim.graphql.types')]
852 rear_port: Annotated["RearPortTemplateType", strawberry.lazy('dcim.graphql.types')]
855@register_type(
856 models.PowerFeed,
857 exclude=['_path'],
858 filters=PowerFeedFilter,
859 pagination=True
860)
861class PowerFeedType(CabledObjectMixin, PathEndpointMixin, PrimaryObjectType):
862 power_panel: Annotated["PowerPanelType", strawberry.lazy('dcim.graphql.types')]
863 rack: Annotated["RackType", strawberry.lazy('dcim.graphql.types')] | None
864 tenant: Annotated["TenantType", strawberry.lazy('tenancy.graphql.types')] | None
867@register_type(
868 models.PowerOutlet,
869 exclude=['_path'],
870 filters=PowerOutletFilter,
871 pagination=True
872)
873class PowerOutletType(ModularComponentType, CabledObjectMixin, PathEndpointMixin):
874 power_port: Annotated["PowerPortType", strawberry.lazy('dcim.graphql.types')] | None
875 color: str
878@register_type(
879 models.PowerOutletTemplate,
880 fields='__all__',
881 filters=PowerOutletTemplateFilter,
882 pagination=True
883)
884class PowerOutletTemplateType(ModularComponentTemplateType):
885 power_port: Annotated["PowerPortTemplateType", strawberry.lazy('dcim.graphql.types')] | None
886 color: str
889@register_type(
890 models.PowerPanel,
891 fields='__all__',
892 filters=PowerPanelFilter,
893 pagination=True
894)
895class PowerPanelType(ContactsMixin, PrimaryObjectType):
896 site: Annotated["SiteType", strawberry.lazy('dcim.graphql.types')]
897 location: Annotated["LocationType", strawberry.lazy('dcim.graphql.types')] | None
899 powerfeeds: list[Annotated["PowerFeedType", strawberry.lazy('dcim.graphql.types')]]
902@register_type(
903 models.PowerPort,
904 exclude=['_path'],
905 filters=PowerPortFilter,
906 pagination=True
907)
908class PowerPortType(ModularComponentType, CabledObjectMixin, PathEndpointMixin):
910 poweroutlets: list[Annotated["PowerOutletType", strawberry.lazy('dcim.graphql.types')]]
913@register_type(
914 models.PowerPortTemplate,
915 fields='__all__',
916 filters=PowerPortTemplateFilter,
917 pagination=True
918)
919class PowerPortTemplateType(ModularComponentTemplateType):
920 poweroutlet_templates: list[Annotated["PowerOutletTemplateType", strawberry.lazy('dcim.graphql.types')]]
923@register_type(
924 models.CoolingFeed,
925 exclude=['_abs_max_flow'],
926 filters=CoolingFeedFilter,
927 pagination=True
928)
929class CoolingFeedType(PrimaryObjectType):
930 cooling_source: Annotated["CoolingSourceType", strawberry.lazy('dcim.graphql.types')]
931 rack: Annotated["RackType", strawberry.lazy('dcim.graphql.types')] | None
932 tenant: Annotated["TenantType", strawberry.lazy('tenancy.graphql.types')] | None
935@register_type(
936 models.CoolingOutflow,
937 exclude=['_abs_diameter'],
938 filters=CoolingOutflowFilter,
939 pagination=True
940)
941class CoolingOutflowType(ModularComponentType):
942 cooling_intake: Annotated["CoolingIntakeType", strawberry.lazy('dcim.graphql.types')] | None
945@register_type(
946 models.CoolingOutflowTemplate,
947 exclude=['_abs_diameter'],
948 filters=CoolingOutflowTemplateFilter,
949 pagination=True
950)
951class CoolingOutflowTemplateType(ModularComponentTemplateType):
952 cooling_intake: Annotated["CoolingIntakeTemplateType", strawberry.lazy('dcim.graphql.types')] | None
955@register_type(
956 models.CoolingIntake,
957 exclude=['_abs_diameter', '_abs_max_flow'],
958 filters=CoolingIntakeFilter,
959 pagination=True
960)
961class CoolingIntakeType(ModularComponentType):
962 cooling_outflow: Annotated["CoolingOutflowType", strawberry.lazy('dcim.graphql.types')] | None
964 coolingoutflows: list[Annotated["CoolingOutflowType", strawberry.lazy('dcim.graphql.types')]]
967@register_type(
968 models.CoolingIntakeTemplate,
969 exclude=['_abs_diameter', '_abs_max_flow'],
970 filters=CoolingIntakeTemplateFilter,
971 pagination=True
972)
973class CoolingIntakeTemplateType(ModularComponentTemplateType):
974 coolingoutflow_templates: list[Annotated["CoolingOutflowTemplateType", strawberry.lazy('dcim.graphql.types')]]
977@register_type(
978 models.CoolingSource,
979 fields='__all__',
980 filters=CoolingSourceFilter,
981 pagination=True
982)
983class CoolingSourceType(ContactsMixin, PrimaryObjectType):
984 site: Annotated["SiteType", strawberry.lazy('dcim.graphql.types')]
985 location: Annotated["LocationType", strawberry.lazy('dcim.graphql.types')] | None
987 cooling_feeds: list[Annotated["CoolingFeedType", strawberry.lazy('dcim.graphql.types')]]
990@register_type(
991 models.RackGroup,
992 fields='__all__',
993 filters=RackGroupFilter,
994 pagination=True
995)
996class RackGroupType(OrganizationalObjectType):
998 racks: list[Annotated["RackType", strawberry.lazy('dcim.graphql.types')]]
1001@register_type(
1002 models.RackType,
1003 fields='__all__',
1004 filters=RackTypeFilter,
1005 pagination=True
1006)
1007class RackTypeType(ImageAttachmentsMixin, PrimaryObjectType):
1008 rack_count: BigInt
1009 manufacturer: Annotated["ManufacturerType", strawberry.lazy('dcim.graphql.types')]
1012@register_type(
1013 models.Rack,
1014 fields='__all__',
1015 filters=RackFilter,
1016 pagination=True
1017)
1018class RackType(VLANGroupsMixin, ImageAttachmentsMixin, ContactsMixin, PrimaryObjectType):
1019 site: Annotated["SiteType", strawberry.lazy('dcim.graphql.types')]
1020 location: Annotated["LocationType", strawberry.lazy('dcim.graphql.types')] | None
1021 group: Annotated["RackGroupType", strawberry.lazy('dcim.graphql.types')] | None
1022 tenant: Annotated["TenantType", strawberry.lazy('tenancy.graphql.types')] | None
1023 role: Annotated["RackRoleType", strawberry.lazy('dcim.graphql.types')] | None
1025 rack_type: Annotated["RackTypeType", strawberry.lazy('dcim.graphql.types')] | None
1026 reservations: list[Annotated["RackReservationType", strawberry.lazy('dcim.graphql.types')]]
1027 devices: list[Annotated["DeviceType", strawberry.lazy('dcim.graphql.types')]]
1028 powerfeeds: list[Annotated["PowerFeedType", strawberry.lazy('dcim.graphql.types')]]
1029 cabletermination_set: list[Annotated["CableTerminationType", strawberry.lazy('dcim.graphql.types')]]
1032@register_type(
1033 models.RackReservation,
1034 fields='__all__',
1035 filters=RackReservationFilter,
1036 pagination=True
1037)
1038class RackReservationType(PrimaryObjectType):
1039 units: list[int]
1040 rack: Annotated["RackType", strawberry.lazy('dcim.graphql.types')]
1041 tenant: Annotated["TenantType", strawberry.lazy('tenancy.graphql.types')] | None
1042 user: Annotated["UserType", strawberry.lazy('users.graphql.types')]
1044 @classmethod
1045 def get_queryset(cls, queryset, info, **kwargs):
1046 queryset = super().get_queryset(queryset, info, **kwargs)
1047 # Annotate unit_count here so RackReservationFilter.unit_count can reference it. The field below
1048 # is resolved from `units` rather than from this annotation, which is not applied on every path
1049 # by which a RackReservation may be resolved.
1050 return queryset.annotate(
1051 unit_count=Func('units', function='CARDINALITY', output_field=IntegerField())
1052 )
1054 # Ensure `units` is fetched when `unit_count` is requested
1055 @strawberry_django.field(only=['units'])
1056 def unit_count(self) -> int:
1057 return len(self.units)
1060@register_type(
1061 models.RackRole,
1062 fields='__all__',
1063 filters=RackRoleFilter,
1064 pagination=True
1065)
1066class RackRoleType(OrganizationalObjectType):
1067 color: str
1069 racks: list[Annotated["RackType", strawberry.lazy('dcim.graphql.types')]]
1072@register_type(
1073 models.RearPort,
1074 fields='__all__',
1075 filters=RearPortFilter,
1076 pagination=True
1077)
1078class RearPortType(ModularComponentType, CabledObjectMixin):
1079 color: str
1081 mappings: list[Annotated["PortMappingType", strawberry.lazy('dcim.graphql.types')]]
1084@register_type(
1085 models.RearPortTemplate,
1086 fields='__all__',
1087 filters=RearPortTemplateFilter,
1088 pagination=True
1089)
1090class RearPortTemplateType(ModularComponentTemplateType):
1091 color: str
1093 mappings: list[Annotated["PortMappingTemplateType", strawberry.lazy('dcim.graphql.types')]]
1096@register_type(
1097 models.Region,
1098 exclude=['parent', 'path', 'sort_path'],
1099 filters=RegionFilter,
1100 pagination=True
1101)
1102class RegionType(VLANGroupsMixin, ContactsMixin, NestedLtreeGroupObjectType):
1104 sites: list[Annotated["SiteType", strawberry.lazy('dcim.graphql.types')]]
1105 children: list[Annotated["RegionType", strawberry.lazy('dcim.graphql.types')]]
1107 @strawberry_django.field(prefetch_related='parent', only=['parent_id'])
1108 def parent(self) -> Annotated["RegionType", strawberry.lazy('dcim.graphql.types')] | None:
1109 return self.parent
1111 @strawberry_django.field(
1112 prefetch_related=lambda info: RestrictedPrefetch(
1113 'cluster_set', info.context.request.user, 'view', queryset=Cluster.objects.all()
1114 ),
1115 )
1116 def clusters(self) -> list[Annotated["ClusterType", strawberry.lazy('virtualization.graphql.types')]]:
1117 return self.cluster_set.all()
1119 @strawberry_django.field(
1120 prefetch_related=lambda info: RestrictedPrefetch(
1121 'circuit_terminations', info.context.request.user, 'view',
1122 queryset=CircuitTermination.objects.all()
1123 ),
1124 )
1125 def circuit_terminations(self) -> list[
1126 Annotated["CircuitTerminationType", strawberry.lazy('circuits.graphql.types')]
1127 ]:
1128 return self.circuit_terminations.all()
1131@register_type(
1132 models.Site,
1133 fields='__all__',
1134 filters=SiteFilter,
1135 pagination=True
1136)
1137class SiteType(VLANGroupsMixin, ImageAttachmentsMixin, ContactsMixin, PrimaryObjectType):
1138 time_zone: str | None
1139 region: Annotated["RegionType", strawberry.lazy('dcim.graphql.types')] | None
1140 group: Annotated["SiteGroupType", strawberry.lazy('dcim.graphql.types')] | None
1141 tenant: Annotated["TenantType", strawberry.lazy('tenancy.graphql.types')] | None
1143 prefixes: list[Annotated["PrefixType", strawberry.lazy('ipam.graphql.types')]]
1144 virtual_machines: list[Annotated["VirtualMachineType", strawberry.lazy('virtualization.graphql.types')]]
1145 racks: list[Annotated["RackType", strawberry.lazy('dcim.graphql.types')]]
1146 cabletermination_set: list[Annotated["CableTerminationType", strawberry.lazy('dcim.graphql.types')]]
1147 powerpanel_set: list[Annotated["PowerPanelType", strawberry.lazy('dcim.graphql.types')]]
1148 devices: list[Annotated["DeviceType", strawberry.lazy('dcim.graphql.types')]]
1149 locations: list[Annotated["LocationType", strawberry.lazy('dcim.graphql.types')]]
1150 asns: list[Annotated["ASNType", strawberry.lazy('ipam.graphql.types')]]
1151 vlans: list[Annotated["VLANType", strawberry.lazy('ipam.graphql.types')]]
1153 @strawberry_django.field(
1154 prefetch_related=lambda info: RestrictedPrefetch(
1155 'cluster_set', info.context.request.user, 'view', queryset=Cluster.objects.all()
1156 ),
1157 )
1158 def clusters(self) -> list[Annotated["ClusterType", strawberry.lazy('virtualization.graphql.types')]]:
1159 return self.cluster_set.all()
1161 @strawberry_django.field(
1162 prefetch_related=lambda info: RestrictedPrefetch(
1163 'circuit_terminations', info.context.request.user, 'view',
1164 queryset=CircuitTermination.objects.all()
1165 ),
1166 )
1167 def circuit_terminations(self) -> list[
1168 Annotated["CircuitTerminationType", strawberry.lazy('circuits.graphql.types')]
1169 ]:
1170 return self.circuit_terminations.all()
1173@register_type(
1174 models.SiteGroup,
1175 exclude=['parent', 'path', 'sort_path'], # bug - temp
1176 filters=SiteGroupFilter,
1177 pagination=True
1178)
1179class SiteGroupType(VLANGroupsMixin, ContactsMixin, NestedLtreeGroupObjectType):
1181 sites: list[Annotated["SiteType", strawberry.lazy('dcim.graphql.types')]]
1182 children: list[Annotated["SiteGroupType", strawberry.lazy('dcim.graphql.types')]]
1184 @strawberry_django.field(prefetch_related='parent', only=['parent_id'])
1185 def parent(self) -> Annotated["SiteGroupType", strawberry.lazy('dcim.graphql.types')] | None:
1186 return self.parent
1188 @strawberry_django.field(
1189 prefetch_related=lambda info: RestrictedPrefetch(
1190 'cluster_set', info.context.request.user, 'view', queryset=Cluster.objects.all()
1191 ),
1192 )
1193 def clusters(self) -> list[Annotated["ClusterType", strawberry.lazy('virtualization.graphql.types')]]:
1194 return self.cluster_set.all()
1196 @strawberry_django.field(
1197 prefetch_related=lambda info: RestrictedPrefetch(
1198 'circuit_terminations', info.context.request.user, 'view',
1199 queryset=CircuitTermination.objects.all()
1200 ),
1201 )
1202 def circuit_terminations(self) -> list[
1203 Annotated["CircuitTerminationType", strawberry.lazy('circuits.graphql.types')]
1204 ]:
1205 return self.circuit_terminations.all()
1208@register_type(
1209 models.VirtualChassis,
1210 fields='__all__',
1211 filters=VirtualChassisFilter,
1212 pagination=True
1213)
1214class VirtualChassisType(PrimaryObjectType):
1215 member_count: BigInt
1216 master: Annotated["DeviceType", strawberry.lazy('dcim.graphql.types')] | None
1218 members: list[Annotated["DeviceType", strawberry.lazy('dcim.graphql.types')]]
1221@register_type(
1222 models.VirtualDeviceContext,
1223 fields='__all__',
1224 filters=VirtualDeviceContextFilter,
1225 pagination=True
1226)
1227class VirtualDeviceContextType(PrimaryObjectType):
1228 device: Annotated["DeviceType", strawberry.lazy('dcim.graphql.types')] | None
1229 primary_ip4: Annotated["IPAddressType", strawberry.lazy('ipam.graphql.types')] | None
1230 primary_ip6: Annotated["IPAddressType", strawberry.lazy('ipam.graphql.types')] | None
1231 tenant: Annotated["TenantType", strawberry.lazy('tenancy.graphql.types')] | None
1233 interfaces: list[Annotated["InterfaceType", strawberry.lazy('dcim.graphql.types')]]