filtersets.py 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861
  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. assigned_to_interface = django_filters.BooleanFilter(
  497. method='_assigned_to_interface',
  498. label='Is assigned to an interface',
  499. )
  500. status = django_filters.MultipleChoiceFilter(
  501. choices=IPAddressStatusChoices,
  502. null_value=None
  503. )
  504. role = django_filters.MultipleChoiceFilter(
  505. choices=IPAddressRoleChoices
  506. )
  507. class Meta:
  508. model = IPAddress
  509. fields = ['id', 'dns_name', 'description']
  510. def search(self, queryset, name, value):
  511. if not value.strip():
  512. return queryset
  513. qs_filter = (
  514. Q(dns_name__icontains=value) |
  515. Q(description__icontains=value) |
  516. Q(address__istartswith=value)
  517. )
  518. return queryset.filter(qs_filter)
  519. def search_by_parent(self, queryset, name, value):
  520. value = value.strip()
  521. if not value:
  522. return queryset
  523. try:
  524. query = str(netaddr.IPNetwork(value.strip()).cidr)
  525. return queryset.filter(address__net_host_contained=query)
  526. except (AddrFormatError, ValueError):
  527. return queryset.none()
  528. def filter_address(self, queryset, name, value):
  529. try:
  530. return queryset.filter(address__net_in=value)
  531. except ValidationError:
  532. return queryset.none()
  533. def filter_mask_length(self, queryset, name, value):
  534. if not value:
  535. return queryset
  536. return queryset.filter(address__net_mask_length=value)
  537. def filter_present_in_vrf(self, queryset, name, vrf):
  538. if vrf is None:
  539. return queryset.none
  540. return queryset.filter(
  541. Q(vrf=vrf) |
  542. Q(vrf__export_targets__in=vrf.import_targets.all())
  543. )
  544. def filter_device(self, queryset, name, value):
  545. devices = Device.objects.filter(**{'{}__in'.format(name): value})
  546. if not devices.exists():
  547. return queryset.none()
  548. interface_ids = []
  549. for device in devices:
  550. interface_ids.extend(device.vc_interfaces().values_list('id', flat=True))
  551. return queryset.filter(
  552. interface__in=interface_ids
  553. )
  554. def filter_virtual_machine(self, queryset, name, value):
  555. virtual_machines = VirtualMachine.objects.filter(**{'{}__in'.format(name): value})
  556. if not virtual_machines.exists():
  557. return queryset.none()
  558. interface_ids = []
  559. for vm in virtual_machines:
  560. interface_ids.extend(vm.interfaces.values_list('id', flat=True))
  561. return queryset.filter(
  562. vminterface__in=interface_ids
  563. )
  564. def _assigned_to_interface(self, queryset, name, value):
  565. return queryset.exclude(assigned_object_id__isnull=value)
  566. class FHRPGroupFilterSet(NetBoxModelFilterSet):
  567. protocol = django_filters.MultipleChoiceFilter(
  568. choices=FHRPGroupProtocolChoices
  569. )
  570. auth_type = django_filters.MultipleChoiceFilter(
  571. choices=FHRPGroupAuthTypeChoices
  572. )
  573. related_ip = django_filters.ModelMultipleChoiceFilter(
  574. queryset=IPAddress.objects.all(),
  575. method='filter_related_ip'
  576. )
  577. class Meta:
  578. model = FHRPGroup
  579. fields = ['id', 'group_id', 'auth_key']
  580. def search(self, queryset, name, value):
  581. if not value.strip():
  582. return queryset
  583. return queryset.filter(
  584. Q(description__icontains=value)
  585. )
  586. def filter_related_ip(self, queryset, name, value):
  587. """
  588. Filter by VRF & prefix of assigned IP addresses.
  589. """
  590. ip_filter = Q()
  591. for ipaddress in value:
  592. if ipaddress.vrf:
  593. q = Q(
  594. ip_addresses__address__net_contained_or_equal=ipaddress.address,
  595. ip_addresses__vrf=ipaddress.vrf
  596. )
  597. else:
  598. q = Q(
  599. ip_addresses__address__net_contained_or_equal=ipaddress.address,
  600. ip_addresses__vrf__isnull=True
  601. )
  602. ip_filter |= q
  603. return queryset.filter(ip_filter)
  604. class FHRPGroupAssignmentFilterSet(ChangeLoggedModelFilterSet):
  605. interface_type = ContentTypeFilter()
  606. group_id = django_filters.ModelMultipleChoiceFilter(
  607. queryset=FHRPGroup.objects.all(),
  608. label='Group (ID)',
  609. )
  610. class Meta:
  611. model = FHRPGroupAssignment
  612. fields = ['id', 'group_id', 'interface_type', 'interface_id', 'priority']
  613. class VLANGroupFilterSet(OrganizationalModelFilterSet):
  614. scope_type = ContentTypeFilter()
  615. region = django_filters.NumberFilter(
  616. method='filter_scope'
  617. )
  618. sitegroup = django_filters.NumberFilter(
  619. method='filter_scope'
  620. )
  621. site = django_filters.NumberFilter(
  622. method='filter_scope'
  623. )
  624. location = django_filters.NumberFilter(
  625. method='filter_scope'
  626. )
  627. rack = django_filters.NumberFilter(
  628. method='filter_scope'
  629. )
  630. clustergroup = django_filters.NumberFilter(
  631. method='filter_scope'
  632. )
  633. cluster = django_filters.NumberFilter(
  634. method='filter_scope'
  635. )
  636. class Meta:
  637. model = VLANGroup
  638. fields = ['id', 'name', 'slug', 'min_vid', 'max_vid', 'description', 'scope_id']
  639. def search(self, queryset, name, value):
  640. if not value.strip():
  641. return queryset
  642. qs_filter = (
  643. Q(name__icontains=value) |
  644. Q(description__icontains=value)
  645. )
  646. return queryset.filter(qs_filter)
  647. def filter_scope(self, queryset, name, value):
  648. return queryset.filter(
  649. scope_type=ContentType.objects.get(model=name),
  650. scope_id=value
  651. )
  652. class VLANFilterSet(NetBoxModelFilterSet, TenancyFilterSet):
  653. region_id = TreeNodeMultipleChoiceFilter(
  654. queryset=Region.objects.all(),
  655. field_name='site__region',
  656. lookup_expr='in',
  657. label='Region (ID)',
  658. )
  659. region = TreeNodeMultipleChoiceFilter(
  660. queryset=Region.objects.all(),
  661. field_name='site__region',
  662. lookup_expr='in',
  663. to_field_name='slug',
  664. label='Region (slug)',
  665. )
  666. site_group_id = TreeNodeMultipleChoiceFilter(
  667. queryset=SiteGroup.objects.all(),
  668. field_name='site__group',
  669. lookup_expr='in',
  670. label='Site group (ID)',
  671. )
  672. site_group = TreeNodeMultipleChoiceFilter(
  673. queryset=SiteGroup.objects.all(),
  674. field_name='site__group',
  675. lookup_expr='in',
  676. to_field_name='slug',
  677. label='Site group (slug)',
  678. )
  679. site_id = django_filters.ModelMultipleChoiceFilter(
  680. queryset=Site.objects.all(),
  681. label='Site (ID)',
  682. )
  683. site = django_filters.ModelMultipleChoiceFilter(
  684. field_name='site__slug',
  685. queryset=Site.objects.all(),
  686. to_field_name='slug',
  687. label='Site (slug)',
  688. )
  689. group_id = django_filters.ModelMultipleChoiceFilter(
  690. queryset=VLANGroup.objects.all(),
  691. label='Group (ID)',
  692. )
  693. group = django_filters.ModelMultipleChoiceFilter(
  694. field_name='group__slug',
  695. queryset=VLANGroup.objects.all(),
  696. to_field_name='slug',
  697. label='Group',
  698. )
  699. role_id = django_filters.ModelMultipleChoiceFilter(
  700. queryset=Role.objects.all(),
  701. label='Role (ID)',
  702. )
  703. role = django_filters.ModelMultipleChoiceFilter(
  704. field_name='role__slug',
  705. queryset=Role.objects.all(),
  706. to_field_name='slug',
  707. label='Role (slug)',
  708. )
  709. status = django_filters.MultipleChoiceFilter(
  710. choices=VLANStatusChoices,
  711. null_value=None
  712. )
  713. available_on_device = django_filters.ModelChoiceFilter(
  714. queryset=Device.objects.all(),
  715. method='get_for_device'
  716. )
  717. available_on_virtualmachine = django_filters.ModelChoiceFilter(
  718. queryset=VirtualMachine.objects.all(),
  719. method='get_for_virtualmachine'
  720. )
  721. class Meta:
  722. model = VLAN
  723. fields = ['id', 'vid', 'name', 'description']
  724. def search(self, queryset, name, value):
  725. if not value.strip():
  726. return queryset
  727. qs_filter = Q(name__icontains=value) | Q(description__icontains=value)
  728. try:
  729. qs_filter |= Q(vid=int(value.strip()))
  730. except ValueError:
  731. pass
  732. return queryset.filter(qs_filter)
  733. def get_for_device(self, queryset, name, value):
  734. return queryset.get_for_device(value)
  735. def get_for_virtualmachine(self, queryset, name, value):
  736. return queryset.get_for_virtualmachine(value)
  737. class ServiceTemplateFilterSet(NetBoxModelFilterSet):
  738. port = NumericArrayFilter(
  739. field_name='ports',
  740. lookup_expr='contains'
  741. )
  742. class Meta:
  743. model = ServiceTemplate
  744. fields = ['id', 'name', 'protocol']
  745. def search(self, queryset, name, value):
  746. if not value.strip():
  747. return queryset
  748. qs_filter = Q(name__icontains=value) | Q(description__icontains=value)
  749. return queryset.filter(qs_filter)
  750. class ServiceFilterSet(NetBoxModelFilterSet):
  751. device_id = django_filters.ModelMultipleChoiceFilter(
  752. queryset=Device.objects.all(),
  753. label='Device (ID)',
  754. )
  755. device = django_filters.ModelMultipleChoiceFilter(
  756. field_name='device__name',
  757. queryset=Device.objects.all(),
  758. to_field_name='name',
  759. label='Device (name)',
  760. )
  761. virtual_machine_id = django_filters.ModelMultipleChoiceFilter(
  762. queryset=VirtualMachine.objects.all(),
  763. label='Virtual machine (ID)',
  764. )
  765. virtual_machine = django_filters.ModelMultipleChoiceFilter(
  766. field_name='virtual_machine__name',
  767. queryset=VirtualMachine.objects.all(),
  768. to_field_name='name',
  769. label='Virtual machine (name)',
  770. )
  771. port = NumericArrayFilter(
  772. field_name='ports',
  773. lookup_expr='contains'
  774. )
  775. class Meta:
  776. model = Service
  777. fields = ['id', 'name', 'protocol', 'description']
  778. def search(self, queryset, name, value):
  779. if not value.strip():
  780. return queryset
  781. qs_filter = Q(name__icontains=value) | Q(description__icontains=value)
  782. return queryset.filter(qs_filter)