filtersets.py 26 KB

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