filtersets.py 27 KB

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