types.py 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363
  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. tenant: Annotated["TenantType", strawberry.lazy('tenancy.graphql.types')] | None
  69. sites: list[SiteType]
  70. providers: list[ProviderType]
  71. @strawberry_django.type(
  72. models.ASNRange,
  73. fields='__all__',
  74. filters=ASNRangeFilter,
  75. pagination=True
  76. )
  77. class ASNRangeType(OrganizationalObjectType):
  78. start: BigInt
  79. end: BigInt
  80. rir: Annotated["RIRType", strawberry.lazy('ipam.graphql.types')] | None
  81. tenant: Annotated["TenantType", strawberry.lazy('tenancy.graphql.types')] | None
  82. @strawberry_django.type(
  83. models.Aggregate,
  84. fields='__all__',
  85. filters=AggregateFilter,
  86. pagination=True
  87. )
  88. class AggregateType(ContactsMixin, BaseIPAddressFamilyType, PrimaryObjectType):
  89. prefix: str
  90. rir: Annotated["RIRType", strawberry.lazy('ipam.graphql.types')] | None
  91. tenant: Annotated["TenantType", strawberry.lazy('tenancy.graphql.types')] | None
  92. @strawberry_django.type(
  93. models.FHRPGroup,
  94. fields='__all__',
  95. filters=FHRPGroupFilter,
  96. pagination=True
  97. )
  98. class FHRPGroupType(IPAddressesMixin, PrimaryObjectType):
  99. fhrpgroupassignment_set: list[Annotated["FHRPGroupAssignmentType", strawberry.lazy('ipam.graphql.types')]]
  100. @strawberry_django.type(
  101. models.FHRPGroupAssignment,
  102. exclude=['interface_type', 'interface_id'],
  103. filters=FHRPGroupAssignmentFilter,
  104. pagination=True
  105. )
  106. class FHRPGroupAssignmentType(BaseObjectType):
  107. group: Annotated['FHRPGroupType', strawberry.lazy('ipam.graphql.types')]
  108. @strawberry_django.field
  109. def interface(self) -> Annotated[
  110. Annotated['InterfaceType', strawberry.lazy('dcim.graphql.types')]
  111. | Annotated['VMInterfaceType', strawberry.lazy('virtualization.graphql.types')],
  112. strawberry.union('FHRPGroupInterfaceType'),
  113. ]:
  114. return self.interface
  115. @strawberry_django.type(
  116. models.IPAddress,
  117. exclude=['assigned_object_type', 'assigned_object_id', 'address'],
  118. filters=IPAddressFilter,
  119. pagination=True
  120. )
  121. class IPAddressType(ContactsMixin, BaseIPAddressFamilyType, PrimaryObjectType):
  122. address: str
  123. vrf: Annotated['VRFType', strawberry.lazy('ipam.graphql.types')] | None
  124. tenant: Annotated['TenantType', strawberry.lazy('tenancy.graphql.types')] | None
  125. nat_inside: Annotated['IPAddressType', strawberry.lazy('ipam.graphql.types')] | None
  126. nat_outside: list[Annotated['IPAddressType', strawberry.lazy('ipam.graphql.types')]]
  127. tunnel_terminations: list[Annotated['TunnelTerminationType', strawberry.lazy('vpn.graphql.types')]]
  128. services: list[Annotated['ServiceType', strawberry.lazy('ipam.graphql.types')]]
  129. @strawberry_django.field
  130. def assigned_object(self) -> Annotated[
  131. Annotated['InterfaceType', strawberry.lazy('dcim.graphql.types')]
  132. | Annotated['FHRPGroupType', strawberry.lazy('ipam.graphql.types')]
  133. | Annotated['VMInterfaceType', strawberry.lazy('virtualization.graphql.types')],
  134. strawberry.union('IPAddressAssignmentType'),
  135. ] | None:
  136. return self.assigned_object
  137. @strawberry_django.type(
  138. models.IPRange,
  139. fields='__all__',
  140. filters=IPRangeFilter,
  141. pagination=True
  142. )
  143. class IPRangeType(ContactsMixin, PrimaryObjectType):
  144. start_address: str
  145. end_address: str
  146. vrf: Annotated["VRFType", strawberry.lazy('ipam.graphql.types')] | None
  147. tenant: Annotated["TenantType", strawberry.lazy('tenancy.graphql.types')] | None
  148. role: Annotated["RoleType", strawberry.lazy('ipam.graphql.types')] | None
  149. @strawberry_django.type(
  150. models.Prefix,
  151. exclude=['scope_type', 'scope_id', '_location', '_region', '_site', '_site_group'],
  152. filters=PrefixFilter,
  153. pagination=True
  154. )
  155. class PrefixType(ContactsMixin, BaseIPAddressFamilyType, PrimaryObjectType):
  156. prefix: str
  157. vrf: Annotated['VRFType', strawberry.lazy('ipam.graphql.types')] | None
  158. tenant: Annotated['TenantType', strawberry.lazy('tenancy.graphql.types')] | None
  159. vlan: Annotated['VLANType', strawberry.lazy('ipam.graphql.types')] | None
  160. role: Annotated['RoleType', strawberry.lazy('ipam.graphql.types')] | None
  161. @strawberry_django.field
  162. def scope(self) -> Annotated[
  163. Annotated['LocationType', strawberry.lazy('dcim.graphql.types')]
  164. | Annotated['RegionType', strawberry.lazy('dcim.graphql.types')]
  165. | Annotated['SiteGroupType', strawberry.lazy('dcim.graphql.types')]
  166. | Annotated['SiteType', strawberry.lazy('dcim.graphql.types')],
  167. strawberry.union('PrefixScopeType'),
  168. ] | None:
  169. return self.scope
  170. @strawberry_django.type(
  171. models.RIR,
  172. fields='__all__',
  173. filters=RIRFilter,
  174. pagination=True
  175. )
  176. class RIRType(OrganizationalObjectType):
  177. asn_ranges: list[Annotated["ASNRangeType", strawberry.lazy('ipam.graphql.types')]]
  178. asns: list[Annotated["ASNType", strawberry.lazy('ipam.graphql.types')]]
  179. aggregates: list[Annotated["AggregateType", strawberry.lazy('ipam.graphql.types')]]
  180. @strawberry_django.type(
  181. models.Role,
  182. fields='__all__',
  183. filters=RoleFilter,
  184. pagination=True
  185. )
  186. class RoleType(OrganizationalObjectType):
  187. prefixes: list[Annotated["PrefixType", strawberry.lazy('ipam.graphql.types')]]
  188. ip_ranges: list[Annotated["IPRangeType", strawberry.lazy('ipam.graphql.types')]]
  189. vlans: list[Annotated["VLANType", strawberry.lazy('ipam.graphql.types')]]
  190. @strawberry_django.type(
  191. models.RouteTarget,
  192. fields='__all__',
  193. filters=RouteTargetFilter,
  194. pagination=True
  195. )
  196. class RouteTargetType(PrimaryObjectType):
  197. tenant: Annotated["TenantType", strawberry.lazy('tenancy.graphql.types')] | None
  198. importing_l2vpns: list[Annotated["L2VPNType", strawberry.lazy('vpn.graphql.types')]]
  199. exporting_l2vpns: list[Annotated["L2VPNType", strawberry.lazy('vpn.graphql.types')]]
  200. importing_vrfs: list[Annotated["VRFType", strawberry.lazy('ipam.graphql.types')]]
  201. exporting_vrfs: list[Annotated["VRFType", strawberry.lazy('ipam.graphql.types')]]
  202. @strawberry_django.type(
  203. models.Service,
  204. exclude=('parent_object_type', 'parent_object_id'),
  205. filters=ServiceFilter,
  206. pagination=True
  207. )
  208. class ServiceType(ContactsMixin, PrimaryObjectType):
  209. ports: list[int]
  210. ipaddresses: list[Annotated['IPAddressType', strawberry.lazy('ipam.graphql.types')]]
  211. @strawberry_django.field
  212. def parent(self) -> Annotated[
  213. Annotated['DeviceType', strawberry.lazy('dcim.graphql.types')]
  214. | Annotated['VirtualMachineType', strawberry.lazy('virtualization.graphql.types')]
  215. | Annotated['FHRPGroupType', strawberry.lazy('ipam.graphql.types')],
  216. strawberry.union('ServiceParentType'),
  217. ] | None:
  218. return self.parent
  219. @strawberry_django.type(
  220. models.ServiceTemplate,
  221. fields='__all__',
  222. filters=ServiceTemplateFilter,
  223. pagination=True
  224. )
  225. class ServiceTemplateType(PrimaryObjectType):
  226. ports: list[int]
  227. @strawberry_django.type(
  228. models.VLAN,
  229. exclude=['qinq_svlan'],
  230. filters=VLANFilter,
  231. pagination=True
  232. )
  233. class VLANType(PrimaryObjectType):
  234. site: Annotated["SiteType", strawberry.lazy('ipam.graphql.types')] | None
  235. group: Annotated["VLANGroupType", strawberry.lazy('ipam.graphql.types')] | None
  236. tenant: Annotated["TenantType", strawberry.lazy('tenancy.graphql.types')] | None
  237. role: Annotated["RoleType", strawberry.lazy('ipam.graphql.types')] | None
  238. interfaces_as_untagged: list[Annotated["InterfaceType", strawberry.lazy('dcim.graphql.types')]]
  239. vminterfaces_as_untagged: list[Annotated["VMInterfaceType", strawberry.lazy('virtualization.graphql.types')]]
  240. wirelesslan_set: list[Annotated["WirelessLANType", strawberry.lazy('wireless.graphql.types')]]
  241. prefixes: list[Annotated["PrefixType", strawberry.lazy('ipam.graphql.types')]]
  242. interfaces_as_tagged: list[Annotated["InterfaceType", strawberry.lazy('dcim.graphql.types')]]
  243. vminterfaces_as_tagged: list[Annotated["VMInterfaceType", strawberry.lazy('virtualization.graphql.types')]]
  244. @strawberry_django.field
  245. def qinq_svlan(self) -> Annotated["VLANType", strawberry.lazy('ipam.graphql.types')] | None:
  246. return self.qinq_svlan
  247. @strawberry_django.type(
  248. models.VLANGroup,
  249. exclude=['scope_type', 'scope_id'],
  250. filters=VLANGroupFilter,
  251. pagination=True
  252. )
  253. class VLANGroupType(OrganizationalObjectType):
  254. vlans: list[VLANType]
  255. vid_ranges: list[str]
  256. total_vlan_ids: BigInt
  257. tenant: Annotated['TenantType', strawberry.lazy('tenancy.graphql.types')] | None
  258. @strawberry_django.field
  259. def scope(self) -> Annotated[
  260. Annotated['ClusterType', strawberry.lazy('virtualization.graphql.types')]
  261. | Annotated['ClusterGroupType', strawberry.lazy('virtualization.graphql.types')]
  262. | Annotated['LocationType', strawberry.lazy('dcim.graphql.types')]
  263. | Annotated['RackType', strawberry.lazy('dcim.graphql.types')]
  264. | Annotated['RegionType', strawberry.lazy('dcim.graphql.types')]
  265. | Annotated['SiteType', strawberry.lazy('dcim.graphql.types')]
  266. | Annotated['SiteGroupType', strawberry.lazy('dcim.graphql.types')],
  267. strawberry.union('VLANGroupScopeType'),
  268. ] | None:
  269. return self.scope
  270. @strawberry_django.type(
  271. models.VLANTranslationPolicy,
  272. fields='__all__',
  273. filters=VLANTranslationPolicyFilter,
  274. pagination=True
  275. )
  276. class VLANTranslationPolicyType(PrimaryObjectType):
  277. rules: list[Annotated["VLANTranslationRuleType", strawberry.lazy('ipam.graphql.types')]]
  278. @strawberry_django.type(
  279. models.VLANTranslationRule,
  280. fields='__all__',
  281. filters=VLANTranslationRuleFilter,
  282. pagination=True
  283. )
  284. class VLANTranslationRuleType(NetBoxObjectType):
  285. policy: Annotated[
  286. "VLANTranslationPolicyType",
  287. strawberry.lazy('ipam.graphql.types')
  288. ] = strawberry_django.field(select_related=["policy"])
  289. @strawberry_django.type(
  290. models.VRF,
  291. fields='__all__',
  292. filters=VRFFilter,
  293. pagination=True
  294. )
  295. class VRFType(PrimaryObjectType):
  296. tenant: Annotated["TenantType", strawberry.lazy('tenancy.graphql.types')] | None
  297. interfaces: list[Annotated["InterfaceType", strawberry.lazy('dcim.graphql.types')]]
  298. ip_addresses: list[Annotated["IPAddressType", strawberry.lazy('ipam.graphql.types')]]
  299. vminterfaces: list[Annotated["VMInterfaceType", strawberry.lazy('virtualization.graphql.types')]]
  300. ip_ranges: list[Annotated["IPRangeType", strawberry.lazy('ipam.graphql.types')]]
  301. export_targets: list[Annotated["RouteTargetType", strawberry.lazy('ipam.graphql.types')]]
  302. import_targets: list[Annotated["RouteTargetType", strawberry.lazy('ipam.graphql.types')]]
  303. prefixes: list[Annotated["PrefixType", strawberry.lazy('ipam.graphql.types')]]