filtersets.py 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835
  1. import django_filters
  2. import netaddr
  3. from django.contrib.contenttypes.models import ContentType
  4. from django.core.exceptions import ValidationError
  5. from django.db.models import Q
  6. from netaddr.core import AddrFormatError
  7. from dcim.models import Device, Interface, Region, Site, SiteGroup
  8. from extras.filters import TagFilter
  9. from netbox.filtersets import OrganizationalModelFilterSet, PrimaryModelFilterSet
  10. from tenancy.filtersets import TenancyFilterSet
  11. from tenancy.models import Tenant
  12. from utilities.filters import (
  13. ContentTypeFilter, MultiValueCharFilter, MultiValueNumberFilter, NumericArrayFilter, TreeNodeMultipleChoiceFilter,
  14. )
  15. from virtualization.models import VirtualMachine, VMInterface
  16. from .choices import *
  17. from .models import *
  18. __all__ = (
  19. 'AggregateFilterSet',
  20. 'ASNFilterSet',
  21. 'IPAddressFilterSet',
  22. 'IPRangeFilterSet',
  23. 'PrefixFilterSet',
  24. 'RIRFilterSet',
  25. 'RoleFilterSet',
  26. 'RouteTargetFilterSet',
  27. 'ServiceFilterSet',
  28. 'VLANFilterSet',
  29. 'VLANGroupFilterSet',
  30. 'VRFFilterSet',
  31. )
  32. class VRFFilterSet(PrimaryModelFilterSet, TenancyFilterSet):
  33. q = django_filters.CharFilter(
  34. method='search',
  35. label='Search',
  36. )
  37. import_target_id = django_filters.ModelMultipleChoiceFilter(
  38. field_name='import_targets',
  39. queryset=RouteTarget.objects.all(),
  40. label='Import target',
  41. )
  42. import_target = django_filters.ModelMultipleChoiceFilter(
  43. field_name='import_targets__name',
  44. queryset=RouteTarget.objects.all(),
  45. to_field_name='name',
  46. label='Import target (name)',
  47. )
  48. export_target_id = django_filters.ModelMultipleChoiceFilter(
  49. field_name='export_targets',
  50. queryset=RouteTarget.objects.all(),
  51. label='Export target',
  52. )
  53. export_target = django_filters.ModelMultipleChoiceFilter(
  54. field_name='export_targets__name',
  55. queryset=RouteTarget.objects.all(),
  56. to_field_name='name',
  57. label='Export target (name)',
  58. )
  59. tag = TagFilter()
  60. def search(self, queryset, name, value):
  61. if not value.strip():
  62. return queryset
  63. return queryset.filter(
  64. Q(name__icontains=value) |
  65. Q(rd__icontains=value) |
  66. Q(description__icontains=value)
  67. )
  68. class Meta:
  69. model = VRF
  70. fields = ['id', 'name', 'rd', 'enforce_unique']
  71. class RouteTargetFilterSet(PrimaryModelFilterSet, TenancyFilterSet):
  72. q = django_filters.CharFilter(
  73. method='search',
  74. label='Search',
  75. )
  76. importing_vrf_id = django_filters.ModelMultipleChoiceFilter(
  77. field_name='importing_vrfs',
  78. queryset=VRF.objects.all(),
  79. label='Importing VRF',
  80. )
  81. importing_vrf = django_filters.ModelMultipleChoiceFilter(
  82. field_name='importing_vrfs__rd',
  83. queryset=VRF.objects.all(),
  84. to_field_name='rd',
  85. label='Import VRF (RD)',
  86. )
  87. exporting_vrf_id = django_filters.ModelMultipleChoiceFilter(
  88. field_name='exporting_vrfs',
  89. queryset=VRF.objects.all(),
  90. label='Exporting VRF',
  91. )
  92. exporting_vrf = django_filters.ModelMultipleChoiceFilter(
  93. field_name='exporting_vrfs__rd',
  94. queryset=VRF.objects.all(),
  95. to_field_name='rd',
  96. label='Export VRF (RD)',
  97. )
  98. tag = TagFilter()
  99. def search(self, queryset, name, value):
  100. if not value.strip():
  101. return queryset
  102. return queryset.filter(
  103. Q(name__icontains=value) |
  104. Q(description__icontains=value)
  105. )
  106. class Meta:
  107. model = RouteTarget
  108. fields = ['id', 'name']
  109. class RIRFilterSet(OrganizationalModelFilterSet):
  110. tag = TagFilter()
  111. class Meta:
  112. model = RIR
  113. fields = ['id', 'name', 'slug', 'is_private', 'description']
  114. class AggregateFilterSet(PrimaryModelFilterSet, TenancyFilterSet):
  115. q = django_filters.CharFilter(
  116. method='search',
  117. label='Search',
  118. )
  119. family = django_filters.NumberFilter(
  120. field_name='prefix',
  121. lookup_expr='family'
  122. )
  123. prefix = django_filters.CharFilter(
  124. method='filter_prefix',
  125. label='Prefix',
  126. )
  127. rir_id = django_filters.ModelMultipleChoiceFilter(
  128. queryset=RIR.objects.all(),
  129. label='RIR (ID)',
  130. )
  131. rir = django_filters.ModelMultipleChoiceFilter(
  132. field_name='rir__slug',
  133. queryset=RIR.objects.all(),
  134. to_field_name='slug',
  135. label='RIR (slug)',
  136. )
  137. tag = TagFilter()
  138. class Meta:
  139. model = Aggregate
  140. fields = ['id', 'date_added']
  141. def search(self, queryset, name, value):
  142. if not value.strip():
  143. return queryset
  144. qs_filter = Q(description__icontains=value)
  145. try:
  146. prefix = str(netaddr.IPNetwork(value.strip()).cidr)
  147. qs_filter |= Q(prefix__net_contains_or_equals=prefix)
  148. except (AddrFormatError, ValueError):
  149. pass
  150. return queryset.filter(qs_filter)
  151. def filter_prefix(self, queryset, name, value):
  152. if not value.strip():
  153. return queryset
  154. try:
  155. query = str(netaddr.IPNetwork(value).cidr)
  156. return queryset.filter(prefix=query)
  157. except (AddrFormatError, ValueError):
  158. return queryset.none()
  159. class ASNFilterSet(OrganizationalModelFilterSet, TenancyFilterSet):
  160. rir_id = django_filters.ModelMultipleChoiceFilter(
  161. queryset=RIR.objects.all(),
  162. label='RIR (ID)',
  163. )
  164. rir = django_filters.ModelMultipleChoiceFilter(
  165. field_name='rir__slug',
  166. queryset=RIR.objects.all(),
  167. to_field_name='slug',
  168. label='RIR (slug)',
  169. )
  170. site_id = django_filters.ModelMultipleChoiceFilter(
  171. field_name='sites',
  172. queryset=Site.objects.all(),
  173. label='Site (ID)',
  174. )
  175. site = django_filters.ModelMultipleChoiceFilter(
  176. field_name='sites__slug',
  177. queryset=Site.objects.all(),
  178. to_field_name='slug',
  179. label='Site (slug)',
  180. )
  181. class Meta:
  182. model = ASN
  183. fields = ['id', 'asn']
  184. def search(self, queryset, name, value):
  185. if not value.strip():
  186. return queryset
  187. qs_filter = Q(Q(description__icontains=value) | Q(asn__icontains=value))
  188. return queryset.filter(qs_filter)
  189. class RoleFilterSet(OrganizationalModelFilterSet):
  190. q = django_filters.CharFilter(
  191. method='search',
  192. label='Search',
  193. )
  194. tag = TagFilter()
  195. class Meta:
  196. model = Role
  197. fields = ['id', 'name', 'slug']
  198. class PrefixFilterSet(PrimaryModelFilterSet, TenancyFilterSet):
  199. q = django_filters.CharFilter(
  200. method='search',
  201. label='Search',
  202. )
  203. family = django_filters.NumberFilter(
  204. field_name='prefix',
  205. lookup_expr='family'
  206. )
  207. prefix = MultiValueCharFilter(
  208. method='filter_prefix',
  209. label='Prefix',
  210. )
  211. within = django_filters.CharFilter(
  212. method='search_within',
  213. label='Within prefix',
  214. )
  215. within_include = django_filters.CharFilter(
  216. method='search_within_include',
  217. label='Within and including prefix',
  218. )
  219. contains = django_filters.CharFilter(
  220. method='search_contains',
  221. label='Prefixes which contain this prefix or IP',
  222. )
  223. depth = MultiValueNumberFilter(
  224. field_name='_depth'
  225. )
  226. children = MultiValueNumberFilter(
  227. field_name='_children'
  228. )
  229. mask_length = MultiValueNumberFilter(
  230. field_name='prefix',
  231. lookup_expr='net_mask_length'
  232. )
  233. mask_length__gte = django_filters.NumberFilter(
  234. field_name='prefix',
  235. lookup_expr='net_mask_length__gte'
  236. )
  237. mask_length__lte = django_filters.NumberFilter(
  238. field_name='prefix',
  239. lookup_expr='net_mask_length__lte'
  240. )
  241. vrf_id = django_filters.ModelMultipleChoiceFilter(
  242. queryset=VRF.objects.all(),
  243. label='VRF',
  244. )
  245. vrf = django_filters.ModelMultipleChoiceFilter(
  246. field_name='vrf__rd',
  247. queryset=VRF.objects.all(),
  248. to_field_name='rd',
  249. label='VRF (RD)',
  250. )
  251. present_in_vrf_id = django_filters.ModelChoiceFilter(
  252. queryset=VRF.objects.all(),
  253. method='filter_present_in_vrf',
  254. label='VRF'
  255. )
  256. present_in_vrf = django_filters.ModelChoiceFilter(
  257. queryset=VRF.objects.all(),
  258. method='filter_present_in_vrf',
  259. to_field_name='rd',
  260. label='VRF (RD)',
  261. )
  262. region_id = TreeNodeMultipleChoiceFilter(
  263. queryset=Region.objects.all(),
  264. field_name='site__region',
  265. lookup_expr='in',
  266. label='Region (ID)',
  267. )
  268. region = TreeNodeMultipleChoiceFilter(
  269. queryset=Region.objects.all(),
  270. field_name='site__region',
  271. lookup_expr='in',
  272. to_field_name='slug',
  273. label='Region (slug)',
  274. )
  275. site_group_id = TreeNodeMultipleChoiceFilter(
  276. queryset=SiteGroup.objects.all(),
  277. field_name='site__group',
  278. lookup_expr='in',
  279. label='Site group (ID)',
  280. )
  281. site_group = TreeNodeMultipleChoiceFilter(
  282. queryset=SiteGroup.objects.all(),
  283. field_name='site__group',
  284. lookup_expr='in',
  285. to_field_name='slug',
  286. label='Site group (slug)',
  287. )
  288. site_id = django_filters.ModelMultipleChoiceFilter(
  289. queryset=Site.objects.all(),
  290. label='Site (ID)',
  291. )
  292. site = django_filters.ModelMultipleChoiceFilter(
  293. field_name='site__slug',
  294. queryset=Site.objects.all(),
  295. to_field_name='slug',
  296. label='Site (slug)',
  297. )
  298. vlan_id = django_filters.ModelMultipleChoiceFilter(
  299. queryset=VLAN.objects.all(),
  300. label='VLAN (ID)',
  301. )
  302. vlan_vid = django_filters.NumberFilter(
  303. field_name='vlan__vid',
  304. label='VLAN number (1-4095)',
  305. )
  306. role_id = django_filters.ModelMultipleChoiceFilter(
  307. queryset=Role.objects.all(),
  308. label='Role (ID)',
  309. )
  310. role = django_filters.ModelMultipleChoiceFilter(
  311. field_name='role__slug',
  312. queryset=Role.objects.all(),
  313. to_field_name='slug',
  314. label='Role (slug)',
  315. )
  316. status = django_filters.MultipleChoiceFilter(
  317. choices=PrefixStatusChoices,
  318. null_value=None
  319. )
  320. tag = TagFilter()
  321. class Meta:
  322. model = Prefix
  323. fields = ['id', 'is_pool', 'mark_utilized']
  324. def search(self, queryset, name, value):
  325. if not value.strip():
  326. return queryset
  327. qs_filter = Q(description__icontains=value)
  328. try:
  329. prefix = str(netaddr.IPNetwork(value.strip()).cidr)
  330. qs_filter |= Q(prefix__net_contains_or_equals=prefix)
  331. except (AddrFormatError, ValueError):
  332. pass
  333. return queryset.filter(qs_filter)
  334. def filter_prefix(self, queryset, name, value):
  335. query_values = []
  336. for v in value:
  337. try:
  338. query_values.append(netaddr.IPNetwork(v))
  339. except (AddrFormatError, ValueError):
  340. pass
  341. return queryset.filter(prefix__in=query_values)
  342. def search_within(self, queryset, name, value):
  343. value = value.strip()
  344. if not value:
  345. return queryset
  346. try:
  347. query = str(netaddr.IPNetwork(value).cidr)
  348. return queryset.filter(prefix__net_contained=query)
  349. except (AddrFormatError, ValueError):
  350. return queryset.none()
  351. def search_within_include(self, queryset, name, value):
  352. value = value.strip()
  353. if not value:
  354. return queryset
  355. try:
  356. query = str(netaddr.IPNetwork(value).cidr)
  357. return queryset.filter(prefix__net_contained_or_equal=query)
  358. except (AddrFormatError, ValueError):
  359. return queryset.none()
  360. def search_contains(self, queryset, name, value):
  361. value = value.strip()
  362. if not value:
  363. return queryset
  364. try:
  365. # Searching by prefix
  366. if '/' in value:
  367. return queryset.filter(prefix__net_contains_or_equals=str(netaddr.IPNetwork(value).cidr))
  368. # Searching by IP address
  369. else:
  370. return queryset.filter(prefix__net_contains=str(netaddr.IPAddress(value)))
  371. except (AddrFormatError, ValueError):
  372. return queryset.none()
  373. def filter_present_in_vrf(self, queryset, name, vrf):
  374. if vrf is None:
  375. return queryset.none
  376. return queryset.filter(
  377. Q(vrf=vrf) |
  378. Q(vrf__export_targets__in=vrf.import_targets.all())
  379. )
  380. class IPRangeFilterSet(TenancyFilterSet, PrimaryModelFilterSet):
  381. q = django_filters.CharFilter(
  382. method='search',
  383. label='Search',
  384. )
  385. family = django_filters.NumberFilter(
  386. field_name='start_address',
  387. lookup_expr='family'
  388. )
  389. contains = django_filters.CharFilter(
  390. method='search_contains',
  391. label='Ranges which contain this prefix or IP',
  392. )
  393. vrf_id = django_filters.ModelMultipleChoiceFilter(
  394. queryset=VRF.objects.all(),
  395. label='VRF',
  396. )
  397. vrf = django_filters.ModelMultipleChoiceFilter(
  398. field_name='vrf__rd',
  399. queryset=VRF.objects.all(),
  400. to_field_name='rd',
  401. label='VRF (RD)',
  402. )
  403. role_id = django_filters.ModelMultipleChoiceFilter(
  404. queryset=Role.objects.all(),
  405. label='Role (ID)',
  406. )
  407. role = django_filters.ModelMultipleChoiceFilter(
  408. field_name='role__slug',
  409. queryset=Role.objects.all(),
  410. to_field_name='slug',
  411. label='Role (slug)',
  412. )
  413. status = django_filters.MultipleChoiceFilter(
  414. choices=IPRangeStatusChoices,
  415. null_value=None
  416. )
  417. tag = TagFilter()
  418. class Meta:
  419. model = IPRange
  420. fields = ['id']
  421. def search(self, queryset, name, value):
  422. if not value.strip():
  423. return queryset
  424. qs_filter = Q(description__icontains=value)
  425. try:
  426. ipaddress = str(netaddr.IPNetwork(value.strip()).cidr)
  427. qs_filter |= Q(start_address=ipaddress)
  428. qs_filter |= Q(end_address=ipaddress)
  429. except (AddrFormatError, ValueError):
  430. pass
  431. return queryset.filter(qs_filter)
  432. def search_contains(self, queryset, name, value):
  433. value = value.strip()
  434. if not value:
  435. return queryset
  436. try:
  437. # Strip mask
  438. ipaddress = netaddr.IPNetwork(value)
  439. return queryset.filter(start_address__lte=ipaddress, end_address__gte=ipaddress)
  440. except (AddrFormatError, ValueError):
  441. return queryset.none()
  442. class IPAddressFilterSet(PrimaryModelFilterSet, TenancyFilterSet):
  443. q = django_filters.CharFilter(
  444. method='search',
  445. label='Search',
  446. )
  447. family = django_filters.NumberFilter(
  448. field_name='address',
  449. lookup_expr='family'
  450. )
  451. parent = django_filters.CharFilter(
  452. method='search_by_parent',
  453. label='Parent prefix',
  454. )
  455. address = MultiValueCharFilter(
  456. method='filter_address',
  457. label='Address',
  458. )
  459. mask_length = django_filters.NumberFilter(
  460. method='filter_mask_length',
  461. label='Mask length',
  462. )
  463. vrf_id = django_filters.ModelMultipleChoiceFilter(
  464. queryset=VRF.objects.all(),
  465. label='VRF',
  466. )
  467. vrf = django_filters.ModelMultipleChoiceFilter(
  468. field_name='vrf__rd',
  469. queryset=VRF.objects.all(),
  470. to_field_name='rd',
  471. label='VRF (RD)',
  472. )
  473. present_in_vrf_id = django_filters.ModelChoiceFilter(
  474. queryset=VRF.objects.all(),
  475. method='filter_present_in_vrf',
  476. label='VRF'
  477. )
  478. present_in_vrf = django_filters.ModelChoiceFilter(
  479. queryset=VRF.objects.all(),
  480. method='filter_present_in_vrf',
  481. to_field_name='rd',
  482. label='VRF (RD)',
  483. )
  484. device = MultiValueCharFilter(
  485. method='filter_device',
  486. field_name='name',
  487. label='Device (name)',
  488. )
  489. device_id = MultiValueNumberFilter(
  490. method='filter_device',
  491. field_name='pk',
  492. label='Device (ID)',
  493. )
  494. virtual_machine = MultiValueCharFilter(
  495. method='filter_virtual_machine',
  496. field_name='name',
  497. label='Virtual machine (name)',
  498. )
  499. virtual_machine_id = MultiValueNumberFilter(
  500. method='filter_virtual_machine',
  501. field_name='pk',
  502. label='Virtual machine (ID)',
  503. )
  504. interface = django_filters.ModelMultipleChoiceFilter(
  505. field_name='interface__name',
  506. queryset=Interface.objects.all(),
  507. to_field_name='name',
  508. label='Interface (name)',
  509. )
  510. interface_id = django_filters.ModelMultipleChoiceFilter(
  511. field_name='interface',
  512. queryset=Interface.objects.all(),
  513. label='Interface (ID)',
  514. )
  515. vminterface = django_filters.ModelMultipleChoiceFilter(
  516. field_name='vminterface__name',
  517. queryset=VMInterface.objects.all(),
  518. to_field_name='name',
  519. label='VM interface (name)',
  520. )
  521. vminterface_id = django_filters.ModelMultipleChoiceFilter(
  522. field_name='vminterface',
  523. queryset=VMInterface.objects.all(),
  524. label='VM interface (ID)',
  525. )
  526. assigned_to_interface = django_filters.BooleanFilter(
  527. method='_assigned_to_interface',
  528. label='Is assigned to an interface',
  529. )
  530. status = django_filters.MultipleChoiceFilter(
  531. choices=IPAddressStatusChoices,
  532. null_value=None
  533. )
  534. role = django_filters.MultipleChoiceFilter(
  535. choices=IPAddressRoleChoices
  536. )
  537. tag = TagFilter()
  538. class Meta:
  539. model = IPAddress
  540. fields = ['id', 'dns_name', 'description']
  541. def search(self, queryset, name, value):
  542. if not value.strip():
  543. return queryset
  544. qs_filter = (
  545. Q(dns_name__icontains=value) |
  546. Q(description__icontains=value) |
  547. Q(address__istartswith=value)
  548. )
  549. return queryset.filter(qs_filter)
  550. def search_by_parent(self, queryset, name, value):
  551. value = value.strip()
  552. if not value:
  553. return queryset
  554. try:
  555. query = str(netaddr.IPNetwork(value.strip()).cidr)
  556. return queryset.filter(address__net_host_contained=query)
  557. except (AddrFormatError, ValueError):
  558. return queryset.none()
  559. def filter_address(self, queryset, name, value):
  560. try:
  561. return queryset.filter(address__net_in=value)
  562. except ValidationError:
  563. return queryset.none()
  564. def filter_mask_length(self, queryset, name, value):
  565. if not value:
  566. return queryset
  567. return queryset.filter(address__net_mask_length=value)
  568. def filter_present_in_vrf(self, queryset, name, vrf):
  569. if vrf is None:
  570. return queryset.none
  571. return queryset.filter(
  572. Q(vrf=vrf) |
  573. Q(vrf__export_targets__in=vrf.import_targets.all())
  574. )
  575. def filter_device(self, queryset, name, value):
  576. devices = Device.objects.filter(**{'{}__in'.format(name): value})
  577. if not devices.exists():
  578. return queryset.none()
  579. interface_ids = []
  580. for device in devices:
  581. interface_ids.extend(device.vc_interfaces().values_list('id', flat=True))
  582. return queryset.filter(
  583. interface__in=interface_ids
  584. )
  585. def filter_virtual_machine(self, queryset, name, value):
  586. virtual_machines = VirtualMachine.objects.filter(**{'{}__in'.format(name): value})
  587. if not virtual_machines.exists():
  588. return queryset.none()
  589. interface_ids = []
  590. for vm in virtual_machines:
  591. interface_ids.extend(vm.interfaces.values_list('id', flat=True))
  592. return queryset.filter(
  593. vminterface__in=interface_ids
  594. )
  595. def _assigned_to_interface(self, queryset, name, value):
  596. return queryset.exclude(assigned_object_id__isnull=value)
  597. class VLANGroupFilterSet(OrganizationalModelFilterSet):
  598. q = django_filters.CharFilter(
  599. method='search',
  600. label='Search',
  601. )
  602. scope_type = ContentTypeFilter()
  603. region = django_filters.NumberFilter(
  604. method='filter_scope'
  605. )
  606. sitegroup = django_filters.NumberFilter(
  607. method='filter_scope'
  608. )
  609. site = django_filters.NumberFilter(
  610. method='filter_scope'
  611. )
  612. location = django_filters.NumberFilter(
  613. method='filter_scope'
  614. )
  615. rack = django_filters.NumberFilter(
  616. method='filter_scope'
  617. )
  618. clustergroup = django_filters.NumberFilter(
  619. method='filter_scope'
  620. )
  621. cluster = django_filters.NumberFilter(
  622. method='filter_scope'
  623. )
  624. tag = TagFilter()
  625. class Meta:
  626. model = VLANGroup
  627. fields = ['id', 'name', 'slug', 'description', 'scope_id']
  628. def search(self, queryset, name, value):
  629. if not value.strip():
  630. return queryset
  631. qs_filter = (
  632. Q(name__icontains=value) |
  633. Q(description__icontains=value)
  634. )
  635. return queryset.filter(qs_filter)
  636. def filter_scope(self, queryset, name, value):
  637. return queryset.filter(
  638. scope_type=ContentType.objects.get(model=name),
  639. scope_id=value
  640. )
  641. class VLANFilterSet(PrimaryModelFilterSet, TenancyFilterSet):
  642. q = django_filters.CharFilter(
  643. method='search',
  644. label='Search',
  645. )
  646. region_id = TreeNodeMultipleChoiceFilter(
  647. queryset=Region.objects.all(),
  648. field_name='site__region',
  649. lookup_expr='in',
  650. label='Region (ID)',
  651. )
  652. region = TreeNodeMultipleChoiceFilter(
  653. queryset=Region.objects.all(),
  654. field_name='site__region',
  655. lookup_expr='in',
  656. to_field_name='slug',
  657. label='Region (slug)',
  658. )
  659. site_group_id = TreeNodeMultipleChoiceFilter(
  660. queryset=SiteGroup.objects.all(),
  661. field_name='site__group',
  662. lookup_expr='in',
  663. label='Site group (ID)',
  664. )
  665. site_group = TreeNodeMultipleChoiceFilter(
  666. queryset=SiteGroup.objects.all(),
  667. field_name='site__group',
  668. lookup_expr='in',
  669. to_field_name='slug',
  670. label='Site group (slug)',
  671. )
  672. site_id = django_filters.ModelMultipleChoiceFilter(
  673. queryset=Site.objects.all(),
  674. label='Site (ID)',
  675. )
  676. site = django_filters.ModelMultipleChoiceFilter(
  677. field_name='site__slug',
  678. queryset=Site.objects.all(),
  679. to_field_name='slug',
  680. label='Site (slug)',
  681. )
  682. group_id = django_filters.ModelMultipleChoiceFilter(
  683. queryset=VLANGroup.objects.all(),
  684. label='Group (ID)',
  685. )
  686. group = django_filters.ModelMultipleChoiceFilter(
  687. field_name='group__slug',
  688. queryset=VLANGroup.objects.all(),
  689. to_field_name='slug',
  690. label='Group',
  691. )
  692. role_id = django_filters.ModelMultipleChoiceFilter(
  693. queryset=Role.objects.all(),
  694. label='Role (ID)',
  695. )
  696. role = django_filters.ModelMultipleChoiceFilter(
  697. field_name='role__slug',
  698. queryset=Role.objects.all(),
  699. to_field_name='slug',
  700. label='Role (slug)',
  701. )
  702. status = django_filters.MultipleChoiceFilter(
  703. choices=VLANStatusChoices,
  704. null_value=None
  705. )
  706. available_on_device = django_filters.ModelChoiceFilter(
  707. queryset=Device.objects.all(),
  708. method='get_for_device'
  709. )
  710. available_on_virtualmachine = django_filters.ModelChoiceFilter(
  711. queryset=VirtualMachine.objects.all(),
  712. method='get_for_virtualmachine'
  713. )
  714. tag = TagFilter()
  715. class Meta:
  716. model = VLAN
  717. fields = ['id', 'vid', 'name']
  718. def search(self, queryset, name, value):
  719. if not value.strip():
  720. return queryset
  721. qs_filter = Q(name__icontains=value) | Q(description__icontains=value)
  722. try:
  723. qs_filter |= Q(vid=int(value.strip()))
  724. except ValueError:
  725. pass
  726. return queryset.filter(qs_filter)
  727. def get_for_device(self, queryset, name, value):
  728. return queryset.get_for_device(value)
  729. def get_for_virtualmachine(self, queryset, name, value):
  730. return queryset.get_for_virtualmachine(value)
  731. class ServiceFilterSet(PrimaryModelFilterSet):
  732. q = django_filters.CharFilter(
  733. method='search',
  734. label='Search',
  735. )
  736. device_id = django_filters.ModelMultipleChoiceFilter(
  737. queryset=Device.objects.all(),
  738. label='Device (ID)',
  739. )
  740. device = django_filters.ModelMultipleChoiceFilter(
  741. field_name='device__name',
  742. queryset=Device.objects.all(),
  743. to_field_name='name',
  744. label='Device (name)',
  745. )
  746. virtual_machine_id = django_filters.ModelMultipleChoiceFilter(
  747. queryset=VirtualMachine.objects.all(),
  748. label='Virtual machine (ID)',
  749. )
  750. virtual_machine = django_filters.ModelMultipleChoiceFilter(
  751. field_name='virtual_machine__name',
  752. queryset=VirtualMachine.objects.all(),
  753. to_field_name='name',
  754. label='Virtual machine (name)',
  755. )
  756. port = NumericArrayFilter(
  757. field_name='ports',
  758. lookup_expr='contains'
  759. )
  760. tag = TagFilter()
  761. class Meta:
  762. model = Service
  763. fields = ['id', 'name', 'protocol']
  764. def search(self, queryset, name, value):
  765. if not value.strip():
  766. return queryset
  767. qs_filter = Q(name__icontains=value) | Q(description__icontains=value)
  768. return queryset.filter(qs_filter)