types.py 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364
  1. from typing import TYPE_CHECKING, Annotated
  2. import strawberry
  3. import strawberry_django
  4. from circuits.graphql.types import ProviderType
  5. from dcim.graphql.types import SiteType
  6. from extras.graphql.mixins import ContactsMixin
  7. from ipam import models
  8. from netbox.graphql.scalars import BigInt
  9. from netbox.graphql.types import BaseObjectType, NetBoxObjectType, OrganizationalObjectType, PrimaryObjectType
  10. from .filters import *
  11. from .mixins import IPAddressesMixin
  12. if TYPE_CHECKING:
  13. from dcim.graphql.types import (
  14. DeviceType,
  15. InterfaceType,
  16. LocationType,
  17. RackType,
  18. RegionType,
  19. SiteGroupType,
  20. )
  21. from tenancy.graphql.types import TenantType
  22. from virtualization.graphql.types import ClusterGroupType, ClusterType, VirtualMachineType, VMInterfaceType
  23. from vpn.graphql.types import L2VPNType, TunnelTerminationType
  24. from wireless.graphql.types import WirelessLANType
  25. __all__ = (
  26. 'ASNRangeType',
  27. 'ASNType',
  28. 'AggregateType',
  29. 'FHRPGroupAssignmentType',
  30. 'FHRPGroupType',
  31. 'IPAddressType',
  32. 'IPRangeType',
  33. 'PrefixType',
  34. 'RIRType',
  35. 'RoleType',
  36. 'RouteTargetType',
  37. 'ServiceTemplateType',
  38. 'ServiceType',
  39. 'VLANGroupType',
  40. 'VLANTranslationPolicyType',
  41. 'VLANTranslationRuleType',
  42. 'VLANType',
  43. 'VRFType',
  44. )
  45. @strawberry.type
  46. class IPAddressFamilyType:
  47. value: int
  48. label: str
  49. @strawberry.type
  50. class BaseIPAddressFamilyType:
  51. """
  52. Base type for models that need to expose their IPAddress family type.
  53. """
  54. @strawberry.field
  55. def family(self) -> IPAddressFamilyType:
  56. # Note that self, is an instance of models.IPAddress
  57. # thus resolves to the address family value.
  58. return IPAddressFamilyType(value=self.family, label=f'IPv{self.family}')
  59. @strawberry_django.type(
  60. models.ASN,
  61. fields='__all__',
  62. filters=ASNFilter,
  63. pagination=True
  64. )
  65. class ASNType(ContactsMixin, PrimaryObjectType):
  66. asn: BigInt
  67. rir: Annotated["RIRType", strawberry.lazy('ipam.graphql.types')] | None
  68. role: Annotated["RoleType", strawberry.lazy('ipam.graphql.types')] | None
  69. tenant: Annotated["TenantType", strawberry.lazy('tenancy.graphql.types')] | None
  70. sites: list[SiteType]
  71. providers: list[ProviderType]
  72. @strawberry_django.type(
  73. models.ASNRange,
  74. fields='__all__',
  75. filters=ASNRangeFilter,
  76. pagination=True
  77. )
  78. class ASNRangeType(OrganizationalObjectType):
  79. start: BigInt
  80. end: BigInt
  81. rir: Annotated["RIRType", strawberry.lazy('ipam.graphql.types')] | None
  82. tenant: Annotated["TenantType", strawberry.lazy('tenancy.graphql.types')] | None
  83. @strawberry_django.type(
  84. models.Aggregate,
  85. fields='__all__',
  86. filters=AggregateFilter,
  87. pagination=True
  88. )
  89. class AggregateType(ContactsMixin, BaseIPAddressFamilyType, PrimaryObjectType):
  90. prefix: str
  91. rir: Annotated["RIRType", strawberry.lazy('ipam.graphql.types')] | None
  92. tenant: Annotated["TenantType", strawberry.lazy('tenancy.graphql.types')] | None
  93. @strawberry_django.type(
  94. models.FHRPGroup,
  95. fields='__all__',
  96. filters=FHRPGroupFilter,
  97. pagination=True
  98. )
  99. class FHRPGroupType(IPAddressesMixin, PrimaryObjectType):
  100. fhrpgroupassignment_set: list[Annotated["FHRPGroupAssignmentType", strawberry.lazy('ipam.graphql.types')]]
  101. @strawberry_django.type(
  102. models.FHRPGroupAssignment,
  103. exclude=['interface_type', 'interface_id'],
  104. filters=FHRPGroupAssignmentFilter,
  105. pagination=True
  106. )
  107. class FHRPGroupAssignmentType(BaseObjectType):
  108. group: Annotated['FHRPGroupType', strawberry.lazy('ipam.graphql.types')]
  109. @strawberry_django.field
  110. def interface(self) -> Annotated[
  111. Annotated['InterfaceType', strawberry.lazy('dcim.graphql.types')]
  112. | Annotated['VMInterfaceType', strawberry.lazy('virtualization.graphql.types')],
  113. strawberry.union('FHRPGroupInterfaceType'),
  114. ]:
  115. return self.interface
  116. @strawberry_django.type(
  117. models.IPAddress,
  118. exclude=['assigned_object_type', 'assigned_object_id', 'address'],
  119. filters=IPAddressFilter,
  120. pagination=True
  121. )
  122. class IPAddressType(ContactsMixin, BaseIPAddressFamilyType, PrimaryObjectType):
  123. address: str
  124. vrf: Annotated['VRFType', strawberry.lazy('ipam.graphql.types')] | None
  125. tenant: Annotated['TenantType', strawberry.lazy('tenancy.graphql.types')] | None
  126. nat_inside: Annotated['IPAddressType', strawberry.lazy('ipam.graphql.types')] | None
  127. nat_outside: list[Annotated['IPAddressType', strawberry.lazy('ipam.graphql.types')]]
  128. tunnel_terminations: list[Annotated['TunnelTerminationType', strawberry.lazy('vpn.graphql.types')]]
  129. services: list[Annotated['ServiceType', strawberry.lazy('ipam.graphql.types')]]
  130. @strawberry_django.field
  131. def assigned_object(self) -> Annotated[
  132. Annotated['InterfaceType', strawberry.lazy('dcim.graphql.types')]
  133. | Annotated['FHRPGroupType', strawberry.lazy('ipam.graphql.types')]
  134. | Annotated['VMInterfaceType', strawberry.lazy('virtualization.graphql.types')],
  135. strawberry.union('IPAddressAssignmentType'),
  136. ] | None:
  137. return self.assigned_object
  138. @strawberry_django.type(
  139. models.IPRange,
  140. fields='__all__',
  141. filters=IPRangeFilter,
  142. pagination=True
  143. )
  144. class IPRangeType(ContactsMixin, PrimaryObjectType):
  145. start_address: str
  146. end_address: str
  147. vrf: Annotated["VRFType", strawberry.lazy('ipam.graphql.types')] | None
  148. tenant: Annotated["TenantType", strawberry.lazy('tenancy.graphql.types')] | None
  149. role: Annotated["RoleType", strawberry.lazy('ipam.graphql.types')] | None
  150. @strawberry_django.type(
  151. models.Prefix,
  152. exclude=['scope_type', 'scope_id', '_location', '_region', '_site', '_site_group'],
  153. filters=PrefixFilter,
  154. pagination=True
  155. )
  156. class PrefixType(ContactsMixin, BaseIPAddressFamilyType, PrimaryObjectType):
  157. prefix: str
  158. vrf: Annotated['VRFType', strawberry.lazy('ipam.graphql.types')] | None
  159. tenant: Annotated['TenantType', strawberry.lazy('tenancy.graphql.types')] | None
  160. vlan: Annotated['VLANType', strawberry.lazy('ipam.graphql.types')] | None
  161. role: Annotated['RoleType', strawberry.lazy('ipam.graphql.types')] | None
  162. @strawberry_django.field
  163. def scope(self) -> Annotated[
  164. Annotated['LocationType', strawberry.lazy('dcim.graphql.types')]
  165. | Annotated['RegionType', strawberry.lazy('dcim.graphql.types')]
  166. | Annotated['SiteGroupType', strawberry.lazy('dcim.graphql.types')]
  167. | Annotated['SiteType', strawberry.lazy('dcim.graphql.types')],
  168. strawberry.union('PrefixScopeType'),
  169. ] | None:
  170. return self.scope
  171. @strawberry_django.type(
  172. models.RIR,
  173. fields='__all__',
  174. filters=RIRFilter,
  175. pagination=True
  176. )
  177. class RIRType(OrganizationalObjectType):
  178. asn_ranges: list[Annotated["ASNRangeType", strawberry.lazy('ipam.graphql.types')]]
  179. asns: list[Annotated["ASNType", strawberry.lazy('ipam.graphql.types')]]
  180. aggregates: list[Annotated["AggregateType", strawberry.lazy('ipam.graphql.types')]]
  181. @strawberry_django.type(
  182. models.Role,
  183. fields='__all__',
  184. filters=RoleFilter,
  185. pagination=True
  186. )
  187. class RoleType(OrganizationalObjectType):
  188. prefixes: list[Annotated["PrefixType", strawberry.lazy('ipam.graphql.types')]]
  189. ip_ranges: list[Annotated["IPRangeType", strawberry.lazy('ipam.graphql.types')]]
  190. vlans: list[Annotated["VLANType", strawberry.lazy('ipam.graphql.types')]]
  191. @strawberry_django.type(
  192. models.RouteTarget,
  193. fields='__all__',
  194. filters=RouteTargetFilter,
  195. pagination=True
  196. )
  197. class RouteTargetType(PrimaryObjectType):
  198. tenant: Annotated["TenantType", strawberry.lazy('tenancy.graphql.types')] | None
  199. importing_l2vpns: list[Annotated["L2VPNType", strawberry.lazy('vpn.graphql.types')]]
  200. exporting_l2vpns: list[Annotated["L2VPNType", strawberry.lazy('vpn.graphql.types')]]
  201. importing_vrfs: list[Annotated["VRFType", strawberry.lazy('ipam.graphql.types')]]
  202. exporting_vrfs: list[Annotated["VRFType", strawberry.lazy('ipam.graphql.types')]]
  203. @strawberry_django.type(
  204. models.Service,
  205. exclude=('parent_object_type', 'parent_object_id'),
  206. filters=ServiceFilter,
  207. pagination=True
  208. )
  209. class ServiceType(ContactsMixin, PrimaryObjectType):
  210. ports: list[int]
  211. ipaddresses: list[Annotated['IPAddressType', strawberry.lazy('ipam.graphql.types')]]
  212. @strawberry_django.field
  213. def parent(self) -> Annotated[
  214. Annotated['DeviceType', strawberry.lazy('dcim.graphql.types')]
  215. | Annotated['VirtualMachineType', strawberry.lazy('virtualization.graphql.types')]
  216. | Annotated['FHRPGroupType', strawberry.lazy('ipam.graphql.types')],
  217. strawberry.union('ServiceParentType'),
  218. ] | None:
  219. return self.parent
  220. @strawberry_django.type(
  221. models.ServiceTemplate,
  222. fields='__all__',
  223. filters=ServiceTemplateFilter,
  224. pagination=True
  225. )
  226. class ServiceTemplateType(PrimaryObjectType):
  227. ports: list[int]
  228. @strawberry_django.type(
  229. models.VLAN,
  230. exclude=['qinq_svlan'],
  231. filters=VLANFilter,
  232. pagination=True
  233. )
  234. class VLANType(PrimaryObjectType):
  235. site: Annotated["SiteType", strawberry.lazy('ipam.graphql.types')] | None
  236. group: Annotated["VLANGroupType", strawberry.lazy('ipam.graphql.types')] | None
  237. tenant: Annotated["TenantType", strawberry.lazy('tenancy.graphql.types')] | None
  238. role: Annotated["RoleType", strawberry.lazy('ipam.graphql.types')] | None
  239. interfaces_as_untagged: list[Annotated["InterfaceType", strawberry.lazy('dcim.graphql.types')]]
  240. vminterfaces_as_untagged: list[Annotated["VMInterfaceType", strawberry.lazy('virtualization.graphql.types')]]
  241. wirelesslan_set: list[Annotated["WirelessLANType", strawberry.lazy('wireless.graphql.types')]]
  242. prefixes: list[Annotated["PrefixType", strawberry.lazy('ipam.graphql.types')]]
  243. interfaces_as_tagged: list[Annotated["InterfaceType", strawberry.lazy('dcim.graphql.types')]]
  244. vminterfaces_as_tagged: list[Annotated["VMInterfaceType", strawberry.lazy('virtualization.graphql.types')]]
  245. @strawberry_django.field
  246. def qinq_svlan(self) -> Annotated["VLANType", strawberry.lazy('ipam.graphql.types')] | None:
  247. return self.qinq_svlan
  248. @strawberry_django.type(
  249. models.VLANGroup,
  250. exclude=['scope_type', 'scope_id'],
  251. filters=VLANGroupFilter,
  252. pagination=True
  253. )
  254. class VLANGroupType(OrganizationalObjectType):
  255. vlans: list[VLANType]
  256. vid_ranges: list[str]
  257. total_vlan_ids: BigInt
  258. tenant: Annotated['TenantType', strawberry.lazy('tenancy.graphql.types')] | None
  259. @strawberry_django.field
  260. def scope(self) -> Annotated[
  261. Annotated['ClusterType', strawberry.lazy('virtualization.graphql.types')]
  262. | Annotated['ClusterGroupType', strawberry.lazy('virtualization.graphql.types')]
  263. | Annotated['LocationType', strawberry.lazy('dcim.graphql.types')]
  264. | Annotated['RackType', strawberry.lazy('dcim.graphql.types')]
  265. | Annotated['RegionType', strawberry.lazy('dcim.graphql.types')]
  266. | Annotated['SiteType', strawberry.lazy('dcim.graphql.types')]
  267. | Annotated['SiteGroupType', strawberry.lazy('dcim.graphql.types')],
  268. strawberry.union('VLANGroupScopeType'),
  269. ] | None:
  270. return self.scope
  271. @strawberry_django.type(
  272. models.VLANTranslationPolicy,
  273. fields='__all__',
  274. filters=VLANTranslationPolicyFilter,
  275. pagination=True
  276. )
  277. class VLANTranslationPolicyType(PrimaryObjectType):
  278. rules: list[Annotated["VLANTranslationRuleType", strawberry.lazy('ipam.graphql.types')]]
  279. @strawberry_django.type(
  280. models.VLANTranslationRule,
  281. fields='__all__',
  282. filters=VLANTranslationRuleFilter,
  283. pagination=True
  284. )
  285. class VLANTranslationRuleType(NetBoxObjectType):
  286. policy: Annotated[
  287. "VLANTranslationPolicyType",
  288. strawberry.lazy('ipam.graphql.types')
  289. ] = strawberry_django.field(select_related=["policy"])
  290. @strawberry_django.type(
  291. models.VRF,
  292. fields='__all__',
  293. filters=VRFFilter,
  294. pagination=True
  295. )
  296. class VRFType(PrimaryObjectType):
  297. tenant: Annotated["TenantType", strawberry.lazy('tenancy.graphql.types')] | None
  298. interfaces: list[Annotated["InterfaceType", strawberry.lazy('dcim.graphql.types')]]
  299. ip_addresses: list[Annotated["IPAddressType", strawberry.lazy('ipam.graphql.types')]]
  300. vminterfaces: list[Annotated["VMInterfaceType", strawberry.lazy('virtualization.graphql.types')]]
  301. ip_ranges: list[Annotated["IPRangeType", strawberry.lazy('ipam.graphql.types')]]
  302. export_targets: list[Annotated["RouteTargetType", strawberry.lazy('ipam.graphql.types')]]
  303. import_targets: list[Annotated["RouteTargetType", strawberry.lazy('ipam.graphql.types')]]
  304. prefixes: list[Annotated["PrefixType", strawberry.lazy('ipam.graphql.types')]]