filtersets.py 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590
  1. import django_filters
  2. from django.contrib.contenttypes.models import ContentType
  3. from django.db.models import Q
  4. from django.utils.translation import gettext as _
  5. from dcim.filtersets import CabledObjectFilterSet
  6. from dcim.models import Interface, Location, Region, Site, SiteGroup
  7. from ipam.models import ASN
  8. from netbox.filtersets import NetBoxModelFilterSet, OrganizationalModelFilterSet
  9. from tenancy.filtersets import ContactModelFilterSet, TenancyFilterSet
  10. from utilities.filters import (
  11. ContentTypeFilter, MultiValueCharFilter, MultiValueNumberFilter, TreeNodeMultipleChoiceFilter,
  12. )
  13. from .choices import *
  14. from .models import *
  15. __all__ = (
  16. 'CircuitFilterSet',
  17. 'CircuitGroupAssignmentFilterSet',
  18. 'CircuitGroupFilterSet',
  19. 'CircuitTerminationFilterSet',
  20. 'CircuitTypeFilterSet',
  21. 'ProviderNetworkFilterSet',
  22. 'ProviderAccountFilterSet',
  23. 'ProviderFilterSet',
  24. 'VirtualCircuitFilterSet',
  25. 'VirtualCircuitTerminationFilterSet',
  26. 'VirtualCircuitTypeFilterSet',
  27. )
  28. class ProviderFilterSet(NetBoxModelFilterSet, ContactModelFilterSet):
  29. region_id = TreeNodeMultipleChoiceFilter(
  30. queryset=Region.objects.all(),
  31. field_name='circuits__terminations___region',
  32. lookup_expr='in',
  33. label=_('Region (ID)'),
  34. )
  35. region = TreeNodeMultipleChoiceFilter(
  36. queryset=Region.objects.all(),
  37. field_name='circuits__terminations___region',
  38. lookup_expr='in',
  39. to_field_name='slug',
  40. label=_('Region (slug)'),
  41. )
  42. site_group_id = TreeNodeMultipleChoiceFilter(
  43. queryset=SiteGroup.objects.all(),
  44. field_name='circuits__terminations___site_group',
  45. lookup_expr='in',
  46. label=_('Site group (ID)'),
  47. )
  48. site_group = TreeNodeMultipleChoiceFilter(
  49. queryset=SiteGroup.objects.all(),
  50. field_name='circuits__terminations___site_group',
  51. lookup_expr='in',
  52. to_field_name='slug',
  53. label=_('Site group (slug)'),
  54. )
  55. site_id = django_filters.ModelMultipleChoiceFilter(
  56. field_name='circuits__terminations___site',
  57. queryset=Site.objects.all(),
  58. label=_('Site'),
  59. )
  60. site = django_filters.ModelMultipleChoiceFilter(
  61. field_name='circuits__terminations___site__slug',
  62. queryset=Site.objects.all(),
  63. to_field_name='slug',
  64. label=_('Site (slug)'),
  65. )
  66. asn_id = django_filters.ModelMultipleChoiceFilter(
  67. field_name='asns',
  68. queryset=ASN.objects.all(),
  69. label=_('ASN (ID)'),
  70. )
  71. asn = django_filters.ModelMultipleChoiceFilter(
  72. field_name='asns__asn',
  73. queryset=ASN.objects.all(),
  74. to_field_name='asn',
  75. label=_('ASN'),
  76. )
  77. class Meta:
  78. model = Provider
  79. fields = ('id', 'name', 'slug', 'description')
  80. def search(self, queryset, name, value):
  81. if not value.strip():
  82. return queryset
  83. return queryset.filter(
  84. Q(name__icontains=value) |
  85. Q(description__icontains=value) |
  86. Q(accounts__account__icontains=value) |
  87. Q(accounts__name__icontains=value) |
  88. Q(comments__icontains=value)
  89. )
  90. class ProviderAccountFilterSet(NetBoxModelFilterSet, ContactModelFilterSet):
  91. provider_id = django_filters.ModelMultipleChoiceFilter(
  92. queryset=Provider.objects.all(),
  93. label=_('Provider (ID)'),
  94. )
  95. provider = django_filters.ModelMultipleChoiceFilter(
  96. field_name='provider__slug',
  97. queryset=Provider.objects.all(),
  98. to_field_name='slug',
  99. label=_('Provider (slug)'),
  100. )
  101. class Meta:
  102. model = ProviderAccount
  103. fields = ('id', 'name', 'account', 'description')
  104. def search(self, queryset, name, value):
  105. if not value.strip():
  106. return queryset
  107. return queryset.filter(
  108. Q(name__icontains=value) |
  109. Q(description__icontains=value) |
  110. Q(account__icontains=value) |
  111. Q(comments__icontains=value)
  112. ).distinct()
  113. class ProviderNetworkFilterSet(NetBoxModelFilterSet):
  114. provider_id = django_filters.ModelMultipleChoiceFilter(
  115. queryset=Provider.objects.all(),
  116. label=_('Provider (ID)'),
  117. )
  118. provider = django_filters.ModelMultipleChoiceFilter(
  119. field_name='provider__slug',
  120. queryset=Provider.objects.all(),
  121. to_field_name='slug',
  122. label=_('Provider (slug)'),
  123. )
  124. class Meta:
  125. model = ProviderNetwork
  126. fields = ('id', 'name', 'service_id', 'description')
  127. def search(self, queryset, name, value):
  128. if not value.strip():
  129. return queryset
  130. return queryset.filter(
  131. Q(name__icontains=value) |
  132. Q(service_id__icontains=value) |
  133. Q(description__icontains=value) |
  134. Q(comments__icontains=value)
  135. ).distinct()
  136. class CircuitTypeFilterSet(OrganizationalModelFilterSet):
  137. class Meta:
  138. model = CircuitType
  139. fields = ('id', 'name', 'slug', 'color', 'description')
  140. class CircuitFilterSet(NetBoxModelFilterSet, TenancyFilterSet, ContactModelFilterSet):
  141. provider_id = django_filters.ModelMultipleChoiceFilter(
  142. queryset=Provider.objects.all(),
  143. label=_('Provider (ID)'),
  144. )
  145. provider = django_filters.ModelMultipleChoiceFilter(
  146. field_name='provider__slug',
  147. queryset=Provider.objects.all(),
  148. to_field_name='slug',
  149. label=_('Provider (slug)'),
  150. )
  151. provider_account_id = django_filters.ModelMultipleChoiceFilter(
  152. field_name='provider_account',
  153. queryset=ProviderAccount.objects.all(),
  154. label=_('Provider account (ID)'),
  155. )
  156. provider_account = django_filters.ModelMultipleChoiceFilter(
  157. field_name='provider_account__account',
  158. queryset=Provider.objects.all(),
  159. to_field_name='account',
  160. label=_('Provider account (account)'),
  161. )
  162. provider_network_id = django_filters.ModelMultipleChoiceFilter(
  163. field_name='terminations___provider_network',
  164. queryset=ProviderNetwork.objects.all(),
  165. label=_('Provider network (ID)'),
  166. )
  167. type_id = django_filters.ModelMultipleChoiceFilter(
  168. queryset=CircuitType.objects.all(),
  169. label=_('Circuit type (ID)'),
  170. )
  171. type = django_filters.ModelMultipleChoiceFilter(
  172. field_name='type__slug',
  173. queryset=CircuitType.objects.all(),
  174. to_field_name='slug',
  175. label=_('Circuit type (slug)'),
  176. )
  177. status = django_filters.MultipleChoiceFilter(
  178. choices=CircuitStatusChoices,
  179. null_value=None
  180. )
  181. region_id = TreeNodeMultipleChoiceFilter(
  182. queryset=Region.objects.all(),
  183. field_name='terminations___region',
  184. lookup_expr='in',
  185. label=_('Region (ID)'),
  186. )
  187. region = TreeNodeMultipleChoiceFilter(
  188. queryset=Region.objects.all(),
  189. field_name='terminations___region',
  190. lookup_expr='in',
  191. to_field_name='slug',
  192. label=_('Region (slug)'),
  193. )
  194. site_group_id = TreeNodeMultipleChoiceFilter(
  195. queryset=SiteGroup.objects.all(),
  196. field_name='terminations___site_group',
  197. lookup_expr='in',
  198. label=_('Site group (ID)'),
  199. )
  200. site_group = TreeNodeMultipleChoiceFilter(
  201. queryset=SiteGroup.objects.all(),
  202. field_name='terminations___site_group',
  203. lookup_expr='in',
  204. to_field_name='slug',
  205. label=_('Site group (slug)'),
  206. )
  207. site_id = django_filters.ModelMultipleChoiceFilter(
  208. field_name='terminations___site',
  209. queryset=Site.objects.all(),
  210. label=_('Site (ID)'),
  211. )
  212. site = django_filters.ModelMultipleChoiceFilter(
  213. field_name='terminations___site__slug',
  214. queryset=Site.objects.all(),
  215. to_field_name='slug',
  216. label=_('Site (slug)'),
  217. )
  218. location_id = django_filters.ModelMultipleChoiceFilter(
  219. field_name='terminations___location',
  220. label=_('Location (ID)'),
  221. queryset=Location.objects.all(),
  222. )
  223. termination_a_id = django_filters.ModelMultipleChoiceFilter(
  224. queryset=CircuitTermination.objects.all(),
  225. label=_('Termination A (ID)'),
  226. )
  227. termination_z_id = django_filters.ModelMultipleChoiceFilter(
  228. queryset=CircuitTermination.objects.all(),
  229. label=_('Termination A (ID)'),
  230. )
  231. class Meta:
  232. model = Circuit
  233. fields = (
  234. 'id', 'cid', 'description', 'install_date', 'termination_date', 'commit_rate', 'distance', 'distance_unit',
  235. )
  236. def search(self, queryset, name, value):
  237. if not value.strip():
  238. return queryset
  239. return queryset.filter(
  240. Q(cid__icontains=value) |
  241. Q(terminations__xconnect_id__icontains=value) |
  242. Q(terminations__pp_info__icontains=value) |
  243. Q(terminations__description__icontains=value) |
  244. Q(description__icontains=value) |
  245. Q(comments__icontains=value)
  246. ).distinct()
  247. class CircuitTerminationFilterSet(NetBoxModelFilterSet, CabledObjectFilterSet):
  248. q = django_filters.CharFilter(
  249. method='search',
  250. label=_('Search'),
  251. )
  252. circuit_id = django_filters.ModelMultipleChoiceFilter(
  253. queryset=Circuit.objects.all(),
  254. label=_('Circuit'),
  255. )
  256. termination_type = ContentTypeFilter()
  257. region_id = TreeNodeMultipleChoiceFilter(
  258. queryset=Region.objects.all(),
  259. field_name='_region',
  260. lookup_expr='in',
  261. label=_('Region (ID)'),
  262. )
  263. region = TreeNodeMultipleChoiceFilter(
  264. queryset=Region.objects.all(),
  265. field_name='_region',
  266. lookup_expr='in',
  267. to_field_name='slug',
  268. label=_('Region (slug)'),
  269. )
  270. site_group_id = TreeNodeMultipleChoiceFilter(
  271. queryset=SiteGroup.objects.all(),
  272. field_name='_site_group',
  273. lookup_expr='in',
  274. label=_('Site group (ID)'),
  275. )
  276. site_group = TreeNodeMultipleChoiceFilter(
  277. queryset=SiteGroup.objects.all(),
  278. field_name='_site_group',
  279. lookup_expr='in',
  280. to_field_name='slug',
  281. label=_('Site group (slug)'),
  282. )
  283. site_id = django_filters.ModelMultipleChoiceFilter(
  284. queryset=Site.objects.all(),
  285. field_name='_site',
  286. label=_('Site (ID)'),
  287. )
  288. site = django_filters.ModelMultipleChoiceFilter(
  289. field_name='_site__slug',
  290. queryset=Site.objects.all(),
  291. to_field_name='slug',
  292. label=_('Site (slug)'),
  293. )
  294. location_id = TreeNodeMultipleChoiceFilter(
  295. queryset=Location.objects.all(),
  296. field_name='_location',
  297. lookup_expr='in',
  298. label=_('Location (ID)'),
  299. )
  300. location = TreeNodeMultipleChoiceFilter(
  301. queryset=Location.objects.all(),
  302. field_name='_location',
  303. lookup_expr='in',
  304. to_field_name='slug',
  305. label=_('Location (slug)'),
  306. )
  307. provider_network_id = django_filters.ModelMultipleChoiceFilter(
  308. queryset=ProviderNetwork.objects.all(),
  309. field_name='_provider_network',
  310. label=_('ProviderNetwork (ID)'),
  311. )
  312. provider_id = django_filters.ModelMultipleChoiceFilter(
  313. field_name='circuit__provider_id',
  314. queryset=Provider.objects.all(),
  315. label=_('Provider (ID)'),
  316. )
  317. provider = django_filters.ModelMultipleChoiceFilter(
  318. field_name='circuit__provider__slug',
  319. queryset=Provider.objects.all(),
  320. to_field_name='slug',
  321. label=_('Provider (slug)'),
  322. )
  323. class Meta:
  324. model = CircuitTermination
  325. fields = (
  326. 'id', 'termination_id', 'term_side', 'port_speed', 'upstream_speed', 'xconnect_id', 'description',
  327. 'mark_connected', 'pp_info', 'cable_end',
  328. )
  329. def search(self, queryset, name, value):
  330. if not value.strip():
  331. return queryset
  332. return queryset.filter(
  333. Q(circuit__cid__icontains=value) |
  334. Q(xconnect_id__icontains=value) |
  335. Q(pp_info__icontains=value) |
  336. Q(description__icontains=value)
  337. ).distinct()
  338. class CircuitGroupFilterSet(OrganizationalModelFilterSet, TenancyFilterSet):
  339. class Meta:
  340. model = CircuitGroup
  341. fields = ('id', 'name', 'slug', 'description')
  342. class CircuitGroupAssignmentFilterSet(NetBoxModelFilterSet):
  343. q = django_filters.CharFilter(
  344. method='search',
  345. label=_('Search'),
  346. )
  347. member_type = ContentTypeFilter()
  348. circuit = MultiValueCharFilter(
  349. method='filter_circuit',
  350. field_name='cid',
  351. label=_('Circuit (CID)'),
  352. )
  353. circuit_id = MultiValueNumberFilter(
  354. method='filter_circuit',
  355. field_name='pk',
  356. label=_('Circuit (ID)'),
  357. )
  358. virtual_circuit = MultiValueCharFilter(
  359. method='filter_virtual_circuit',
  360. field_name='cid',
  361. label=_('Virtual circuit (CID)'),
  362. )
  363. virtual_circuit_id = MultiValueNumberFilter(
  364. method='filter_virtual_circuit',
  365. field_name='pk',
  366. label=_('Virtual circuit (ID)'),
  367. )
  368. provider = MultiValueCharFilter(
  369. method='filter_provider',
  370. field_name='slug',
  371. label=_('Provider (name)'),
  372. )
  373. provider_id = MultiValueNumberFilter(
  374. method='filter_provider',
  375. field_name='pk',
  376. label=_('Provider (ID)'),
  377. )
  378. group_id = django_filters.ModelMultipleChoiceFilter(
  379. queryset=CircuitGroup.objects.all(),
  380. label=_('Circuit group (ID)'),
  381. )
  382. group = django_filters.ModelMultipleChoiceFilter(
  383. field_name='group__slug',
  384. queryset=CircuitGroup.objects.all(),
  385. to_field_name='slug',
  386. label=_('Circuit group (slug)'),
  387. )
  388. class Meta:
  389. model = CircuitGroupAssignment
  390. fields = ('id', 'member_id', 'priority')
  391. def search(self, queryset, name, value):
  392. if not value.strip():
  393. return queryset
  394. return queryset.filter(
  395. Q(member__cid__icontains=value) |
  396. Q(group__name__icontains=value)
  397. )
  398. def filter_circuit(self, queryset, name, value):
  399. circuits = Circuit.objects.filter(**{f'{name}__in': value})
  400. if not circuits.exists():
  401. return queryset.none()
  402. return queryset.filter(
  403. Q(
  404. member_type=ContentType.objects.get_for_model(Circuit),
  405. member_id__in=circuits
  406. )
  407. )
  408. def filter_virtual_circuit(self, queryset, name, value):
  409. virtual_circuits = VirtualCircuit.objects.filter(**{f'{name}__in': value})
  410. if not virtual_circuits.exists():
  411. return queryset.none()
  412. return queryset.filter(
  413. Q(
  414. member_type=ContentType.objects.get_for_model(VirtualCircuit),
  415. member_id__in=virtual_circuits
  416. )
  417. )
  418. def filter_provider(self, queryset, name, value):
  419. providers = Provider.objects.filter(**{f'{name}__in': value})
  420. if not providers.exists():
  421. return queryset.none()
  422. circuits = Circuit.objects.filter(provider__in=providers)
  423. virtual_circuits = VirtualCircuit.objects.filter(provider_network__provider__in=providers)
  424. return queryset.filter(
  425. Q(
  426. member_type=ContentType.objects.get_for_model(Circuit),
  427. member_id__in=circuits
  428. ) |
  429. Q(
  430. member_type=ContentType.objects.get_for_model(VirtualCircuit),
  431. member_id__in=virtual_circuits
  432. )
  433. )
  434. class VirtualCircuitTypeFilterSet(OrganizationalModelFilterSet):
  435. class Meta:
  436. model = VirtualCircuitType
  437. fields = ('id', 'name', 'slug', 'color', 'description')
  438. class VirtualCircuitFilterSet(NetBoxModelFilterSet, TenancyFilterSet):
  439. provider_id = django_filters.ModelMultipleChoiceFilter(
  440. field_name='provider_network__provider',
  441. queryset=Provider.objects.all(),
  442. label=_('Provider (ID)'),
  443. )
  444. provider = django_filters.ModelMultipleChoiceFilter(
  445. field_name='provider_network__provider__slug',
  446. queryset=Provider.objects.all(),
  447. to_field_name='slug',
  448. label=_('Provider (slug)'),
  449. )
  450. provider_account_id = django_filters.ModelMultipleChoiceFilter(
  451. field_name='provider_account',
  452. queryset=ProviderAccount.objects.all(),
  453. label=_('Provider account (ID)'),
  454. )
  455. provider_account = django_filters.ModelMultipleChoiceFilter(
  456. field_name='provider_account__account',
  457. queryset=Provider.objects.all(),
  458. to_field_name='account',
  459. label=_('Provider account (account)'),
  460. )
  461. provider_network_id = django_filters.ModelMultipleChoiceFilter(
  462. queryset=ProviderNetwork.objects.all(),
  463. label=_('Provider network (ID)'),
  464. )
  465. type_id = django_filters.ModelMultipleChoiceFilter(
  466. queryset=VirtualCircuitType.objects.all(),
  467. label=_('Virtual circuit type (ID)'),
  468. )
  469. type = django_filters.ModelMultipleChoiceFilter(
  470. field_name='type__slug',
  471. queryset=VirtualCircuitType.objects.all(),
  472. to_field_name='slug',
  473. label=_('Virtual circuit type (slug)'),
  474. )
  475. status = django_filters.MultipleChoiceFilter(
  476. choices=CircuitStatusChoices,
  477. null_value=None
  478. )
  479. class Meta:
  480. model = VirtualCircuit
  481. fields = ('id', 'cid', 'description')
  482. def search(self, queryset, name, value):
  483. if not value.strip():
  484. return queryset
  485. return queryset.filter(
  486. Q(cid__icontains=value) |
  487. Q(description__icontains=value) |
  488. Q(comments__icontains=value)
  489. ).distinct()
  490. class VirtualCircuitTerminationFilterSet(NetBoxModelFilterSet):
  491. q = django_filters.CharFilter(
  492. method='search',
  493. label=_('Search'),
  494. )
  495. virtual_circuit_id = django_filters.ModelMultipleChoiceFilter(
  496. queryset=VirtualCircuit.objects.all(),
  497. label=_('Virtual circuit'),
  498. )
  499. role = django_filters.MultipleChoiceFilter(
  500. choices=VirtualCircuitTerminationRoleChoices,
  501. null_value=None
  502. )
  503. provider_id = django_filters.ModelMultipleChoiceFilter(
  504. field_name='virtual_circuit__provider_network__provider',
  505. queryset=Provider.objects.all(),
  506. label=_('Provider (ID)'),
  507. )
  508. provider = django_filters.ModelMultipleChoiceFilter(
  509. field_name='virtual_circuit__provider_network__provider__slug',
  510. queryset=Provider.objects.all(),
  511. to_field_name='slug',
  512. label=_('Provider (slug)'),
  513. )
  514. provider_account_id = django_filters.ModelMultipleChoiceFilter(
  515. field_name='virtual_circuit__provider_account',
  516. queryset=ProviderAccount.objects.all(),
  517. label=_('Provider account (ID)'),
  518. )
  519. provider_account = django_filters.ModelMultipleChoiceFilter(
  520. field_name='virtual_circuit__provider_account__account',
  521. queryset=ProviderAccount.objects.all(),
  522. to_field_name='account',
  523. label=_('Provider account (account)'),
  524. )
  525. provider_network_id = django_filters.ModelMultipleChoiceFilter(
  526. queryset=ProviderNetwork.objects.all(),
  527. field_name='virtual_circuit__provider_network',
  528. label=_('Provider network (ID)'),
  529. )
  530. interface_id = django_filters.ModelMultipleChoiceFilter(
  531. queryset=Interface.objects.all(),
  532. field_name='interface',
  533. label=_('Interface (ID)'),
  534. )
  535. class Meta:
  536. model = VirtualCircuitTermination
  537. fields = ('id', 'interface_id', 'description')
  538. def search(self, queryset, name, value):
  539. if not value.strip():
  540. return queryset
  541. return queryset.filter(
  542. Q(virtual_circuit__cid__icontains=value) |
  543. Q(description__icontains=value)
  544. ).distinct()