filtersets.py 42 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333
  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 django.utils.translation import gettext as _
  7. from drf_spectacular.types import OpenApiTypes
  8. from drf_spectacular.utils import extend_schema_field
  9. from netaddr.core import AddrFormatError
  10. from circuits.models import Provider
  11. from dcim.base_filtersets import ScopedFilterSet
  12. from dcim.models import Device, Interface, Region, Site, SiteGroup
  13. from netbox.filtersets import (
  14. ChangeLoggedModelFilterSet,
  15. NetBoxModelFilterSet,
  16. OrganizationalModelFilterSet,
  17. PrimaryModelFilterSet,
  18. )
  19. from tenancy.filtersets import ContactModelFilterSet, TenancyFilterSet
  20. from utilities.filters import (
  21. MultiValueCharFilter,
  22. MultiValueContentTypeFilter,
  23. MultiValueNumberFilter,
  24. NumericArrayFilter,
  25. TreeNodeMultipleChoiceFilter,
  26. )
  27. from utilities.filtersets import register_filterset
  28. from virtualization.models import VirtualMachine, VMInterface
  29. from vpn.models import L2VPN
  30. from .choices import *
  31. from .models import *
  32. __all__ = (
  33. 'ASNFilterSet',
  34. 'ASNRangeFilterSet',
  35. 'AggregateFilterSet',
  36. 'FHRPGroupAssignmentFilterSet',
  37. 'FHRPGroupFilterSet',
  38. 'IPAddressFilterSet',
  39. 'IPRangeFilterSet',
  40. 'PrefixFilterSet',
  41. 'PrimaryIPFilterSet',
  42. 'RIRFilterSet',
  43. 'RoleFilterSet',
  44. 'RouteTargetFilterSet',
  45. 'ServiceFilterSet',
  46. 'ServiceTemplateFilterSet',
  47. 'VLANFilterSet',
  48. 'VLANGroupFilterSet',
  49. 'VLANTranslationPolicyFilterSet',
  50. 'VLANTranslationRuleFilterSet',
  51. 'VRFFilterSet',
  52. )
  53. @register_filterset
  54. class VRFFilterSet(PrimaryModelFilterSet, TenancyFilterSet):
  55. import_target_id = django_filters.ModelMultipleChoiceFilter(
  56. field_name='import_targets',
  57. queryset=RouteTarget.objects.all(),
  58. label=_('Import target'),
  59. )
  60. import_target = django_filters.ModelMultipleChoiceFilter(
  61. field_name='import_targets__name',
  62. queryset=RouteTarget.objects.all(),
  63. to_field_name='name',
  64. label=_('Import target (name)'),
  65. )
  66. export_target_id = django_filters.ModelMultipleChoiceFilter(
  67. field_name='export_targets',
  68. queryset=RouteTarget.objects.all(),
  69. label=_('Export target'),
  70. )
  71. export_target = django_filters.ModelMultipleChoiceFilter(
  72. field_name='export_targets__name',
  73. queryset=RouteTarget.objects.all(),
  74. to_field_name='name',
  75. label=_('Export target (name)'),
  76. )
  77. def search(self, queryset, name, value):
  78. if not value.strip():
  79. return queryset
  80. return queryset.filter(
  81. Q(name__icontains=value) |
  82. Q(rd__icontains=value) |
  83. Q(description__icontains=value)
  84. )
  85. class Meta:
  86. model = VRF
  87. fields = ('id', 'name', 'rd', 'enforce_unique', 'description')
  88. @register_filterset
  89. class RouteTargetFilterSet(PrimaryModelFilterSet, TenancyFilterSet):
  90. importing_vrf_id = django_filters.ModelMultipleChoiceFilter(
  91. field_name='importing_vrfs',
  92. queryset=VRF.objects.all(),
  93. label=_('Importing VRF'),
  94. )
  95. importing_vrf = django_filters.ModelMultipleChoiceFilter(
  96. field_name='importing_vrfs__rd',
  97. queryset=VRF.objects.all(),
  98. to_field_name='rd',
  99. label=_('Import VRF (RD)'),
  100. )
  101. exporting_vrf_id = django_filters.ModelMultipleChoiceFilter(
  102. field_name='exporting_vrfs',
  103. queryset=VRF.objects.all(),
  104. label=_('Exporting VRF'),
  105. )
  106. exporting_vrf = django_filters.ModelMultipleChoiceFilter(
  107. field_name='exporting_vrfs__rd',
  108. queryset=VRF.objects.all(),
  109. to_field_name='rd',
  110. label=_('Export VRF (RD)'),
  111. )
  112. importing_l2vpn_id = django_filters.ModelMultipleChoiceFilter(
  113. field_name='importing_l2vpns',
  114. queryset=L2VPN.objects.all(),
  115. label=_('Importing L2VPN'),
  116. )
  117. importing_l2vpn = django_filters.ModelMultipleChoiceFilter(
  118. field_name='importing_l2vpns__identifier',
  119. queryset=L2VPN.objects.all(),
  120. to_field_name='identifier',
  121. label=_('Importing L2VPN (identifier)'),
  122. )
  123. exporting_l2vpn_id = django_filters.ModelMultipleChoiceFilter(
  124. field_name='exporting_l2vpns',
  125. queryset=L2VPN.objects.all(),
  126. label=_('Exporting L2VPN'),
  127. )
  128. exporting_l2vpn = django_filters.ModelMultipleChoiceFilter(
  129. field_name='exporting_l2vpns__identifier',
  130. queryset=L2VPN.objects.all(),
  131. to_field_name='identifier',
  132. label=_('Exporting L2VPN (identifier)'),
  133. )
  134. def search(self, queryset, name, value):
  135. if not value.strip():
  136. return queryset
  137. return queryset.filter(
  138. Q(name__icontains=value) |
  139. Q(description__icontains=value)
  140. )
  141. class Meta:
  142. model = RouteTarget
  143. fields = ('id', 'name', 'description')
  144. @register_filterset
  145. class RIRFilterSet(OrganizationalModelFilterSet):
  146. class Meta:
  147. model = RIR
  148. fields = ('id', 'name', 'slug', 'is_private', 'description')
  149. @register_filterset
  150. class AggregateFilterSet(PrimaryModelFilterSet, TenancyFilterSet, ContactModelFilterSet):
  151. family = django_filters.NumberFilter(
  152. field_name='prefix',
  153. lookup_expr='family'
  154. )
  155. prefix = django_filters.CharFilter(
  156. method='filter_prefix',
  157. label=_('Prefix'),
  158. )
  159. rir_id = django_filters.ModelMultipleChoiceFilter(
  160. queryset=RIR.objects.all(),
  161. distinct=False,
  162. label=_('RIR (ID)'),
  163. )
  164. rir = django_filters.ModelMultipleChoiceFilter(
  165. field_name='rir__slug',
  166. queryset=RIR.objects.all(),
  167. distinct=False,
  168. to_field_name='slug',
  169. label=_('RIR (slug)'),
  170. )
  171. class Meta:
  172. model = Aggregate
  173. fields = ('id', 'date_added', 'description')
  174. def search(self, queryset, name, value):
  175. if not value.strip():
  176. return queryset
  177. qs_filter = Q(description__icontains=value)
  178. qs_filter |= Q(prefix__contains=value.strip())
  179. try:
  180. prefix = str(netaddr.IPNetwork(value.strip()).cidr)
  181. qs_filter |= Q(prefix__net_contains_or_equals=prefix)
  182. qs_filter |= Q(prefix__contains=value.strip())
  183. except (AddrFormatError, ValueError):
  184. pass
  185. return queryset.filter(qs_filter)
  186. def filter_prefix(self, queryset, name, value):
  187. if not value.strip():
  188. return queryset
  189. try:
  190. query = str(netaddr.IPNetwork(value).cidr)
  191. return queryset.filter(prefix=query)
  192. except (AddrFormatError, ValueError):
  193. return queryset.none()
  194. @register_filterset
  195. class ASNRangeFilterSet(OrganizationalModelFilterSet, TenancyFilterSet):
  196. rir_id = django_filters.ModelMultipleChoiceFilter(
  197. queryset=RIR.objects.all(),
  198. distinct=False,
  199. label=_('RIR (ID)'),
  200. )
  201. rir = django_filters.ModelMultipleChoiceFilter(
  202. field_name='rir__slug',
  203. queryset=RIR.objects.all(),
  204. distinct=False,
  205. to_field_name='slug',
  206. label=_('RIR (slug)'),
  207. )
  208. class Meta:
  209. model = ASNRange
  210. fields = ('id', 'name', 'slug', 'start', 'end', 'description')
  211. def search(self, queryset, name, value):
  212. if not value.strip():
  213. return queryset
  214. return queryset.filter(
  215. Q(name__icontains=value) |
  216. Q(description__icontains=value)
  217. )
  218. @register_filterset
  219. class ASNFilterSet(PrimaryModelFilterSet, TenancyFilterSet):
  220. rir_id = django_filters.ModelMultipleChoiceFilter(
  221. queryset=RIR.objects.all(),
  222. distinct=False,
  223. label=_('RIR (ID)'),
  224. )
  225. rir = django_filters.ModelMultipleChoiceFilter(
  226. field_name='rir__slug',
  227. queryset=RIR.objects.all(),
  228. distinct=False,
  229. to_field_name='slug',
  230. label=_('RIR (slug)'),
  231. )
  232. site_group_id = TreeNodeMultipleChoiceFilter(
  233. queryset=SiteGroup.objects.all(),
  234. field_name='sites__group',
  235. lookup_expr='in',
  236. label=_('Site group (ID)'),
  237. )
  238. site_group = TreeNodeMultipleChoiceFilter(
  239. queryset=SiteGroup.objects.all(),
  240. field_name='sites__group',
  241. lookup_expr='in',
  242. to_field_name='slug',
  243. label=_('Site group (slug)'),
  244. )
  245. site_id = django_filters.ModelMultipleChoiceFilter(
  246. field_name='sites',
  247. queryset=Site.objects.all(),
  248. label=_('Site (ID)'),
  249. )
  250. site = django_filters.ModelMultipleChoiceFilter(
  251. field_name='sites__slug',
  252. queryset=Site.objects.all(),
  253. to_field_name='slug',
  254. label=_('Site (slug)'),
  255. )
  256. provider_id = django_filters.ModelMultipleChoiceFilter(
  257. field_name='providers',
  258. queryset=Provider.objects.all(),
  259. label=_('Provider (ID)'),
  260. )
  261. provider = django_filters.ModelMultipleChoiceFilter(
  262. field_name='providers__slug',
  263. queryset=Provider.objects.all(),
  264. to_field_name='slug',
  265. label=_('Provider (slug)'),
  266. )
  267. class Meta:
  268. model = ASN
  269. fields = ('id', 'asn', 'description')
  270. def search(self, queryset, name, value):
  271. if not value.strip():
  272. return queryset
  273. qs_filter = Q(description__icontains=value)
  274. try:
  275. qs_filter |= Q(asn=int(value))
  276. except ValueError:
  277. pass
  278. return queryset.filter(qs_filter)
  279. @register_filterset
  280. class RoleFilterSet(OrganizationalModelFilterSet):
  281. class Meta:
  282. model = Role
  283. fields = ('id', 'name', 'slug', 'description', 'weight')
  284. @register_filterset
  285. class PrefixFilterSet(PrimaryModelFilterSet, ScopedFilterSet, TenancyFilterSet, ContactModelFilterSet):
  286. family = django_filters.NumberFilter(
  287. field_name='prefix',
  288. lookup_expr='family'
  289. )
  290. prefix = MultiValueCharFilter(
  291. method='filter_prefix',
  292. label=_('Prefix'),
  293. )
  294. within = django_filters.CharFilter(
  295. method='search_within',
  296. label=_('Within prefix'),
  297. )
  298. within_include = django_filters.CharFilter(
  299. method='search_within_include',
  300. label=_('Within and including prefix'),
  301. )
  302. contains = django_filters.CharFilter(
  303. method='search_contains',
  304. label=_('Prefixes which contain this prefix or IP'),
  305. )
  306. depth = MultiValueNumberFilter(
  307. field_name='_depth'
  308. )
  309. children = MultiValueNumberFilter(
  310. field_name='_children'
  311. )
  312. mask_length = MultiValueNumberFilter(
  313. field_name='prefix',
  314. lookup_expr='net_mask_length',
  315. label=_('Mask length')
  316. )
  317. mask_length__gte = django_filters.NumberFilter(
  318. field_name='prefix',
  319. lookup_expr='net_mask_length__gte'
  320. )
  321. mask_length__lte = django_filters.NumberFilter(
  322. field_name='prefix',
  323. lookup_expr='net_mask_length__lte'
  324. )
  325. vrf_id = django_filters.ModelMultipleChoiceFilter(
  326. queryset=VRF.objects.all(),
  327. distinct=False,
  328. label=_('VRF'),
  329. )
  330. vrf = django_filters.ModelMultipleChoiceFilter(
  331. field_name='vrf__rd',
  332. queryset=VRF.objects.all(),
  333. distinct=False,
  334. to_field_name='rd',
  335. label=_('VRF (RD)'),
  336. )
  337. present_in_vrf_id = django_filters.ModelChoiceFilter(
  338. queryset=VRF.objects.all(),
  339. method='filter_present_in_vrf',
  340. label=_('VRF')
  341. )
  342. present_in_vrf = django_filters.ModelChoiceFilter(
  343. queryset=VRF.objects.all(),
  344. method='filter_present_in_vrf',
  345. to_field_name='rd',
  346. label=_('VRF (RD)'),
  347. )
  348. vlan_group_id = django_filters.ModelMultipleChoiceFilter(
  349. field_name='vlan__group',
  350. queryset=VLANGroup.objects.all(),
  351. distinct=False,
  352. to_field_name='id',
  353. label=_('VLAN Group (ID)'),
  354. )
  355. vlan_group = django_filters.ModelMultipleChoiceFilter(
  356. field_name='vlan__group__slug',
  357. queryset=VLANGroup.objects.all(),
  358. distinct=False,
  359. to_field_name='slug',
  360. label=_('VLAN Group (slug)'),
  361. )
  362. vlan_id = django_filters.ModelMultipleChoiceFilter(
  363. queryset=VLAN.objects.all(),
  364. distinct=False,
  365. label=_('VLAN (ID)'),
  366. )
  367. vlan_vid = django_filters.NumberFilter(
  368. field_name='vlan__vid',
  369. label=_('VLAN number (1-4094)'),
  370. )
  371. role_id = django_filters.ModelMultipleChoiceFilter(
  372. queryset=Role.objects.all(),
  373. distinct=False,
  374. label=_('Role (ID)'),
  375. )
  376. role = django_filters.ModelMultipleChoiceFilter(
  377. field_name='role__slug',
  378. queryset=Role.objects.all(),
  379. distinct=False,
  380. to_field_name='slug',
  381. label=_('Role (slug)'),
  382. )
  383. status = django_filters.MultipleChoiceFilter(
  384. choices=PrefixStatusChoices,
  385. distinct=False,
  386. null_value=None
  387. )
  388. class Meta:
  389. model = Prefix
  390. fields = ('id', 'scope_id', 'is_pool', 'mark_utilized', 'description')
  391. def search(self, queryset, name, value):
  392. if not value.strip():
  393. return queryset
  394. qs_filter = Q(description__icontains=value)
  395. qs_filter |= Q(prefix__contains=value.strip())
  396. try:
  397. prefix = str(netaddr.IPNetwork(value.strip()).cidr)
  398. qs_filter |= Q(prefix__net_contains_or_equals=prefix)
  399. qs_filter |= Q(prefix__contains=value.strip())
  400. except (AddrFormatError, ValueError):
  401. pass
  402. return queryset.filter(qs_filter)
  403. def filter_prefix(self, queryset, name, value):
  404. query_values = []
  405. for v in value:
  406. try:
  407. query_values.append(netaddr.IPNetwork(v))
  408. except (AddrFormatError, ValueError):
  409. pass
  410. return queryset.filter(prefix__in=query_values)
  411. def search_within(self, queryset, name, value):
  412. value = value.strip()
  413. if not value:
  414. return queryset
  415. try:
  416. query = str(netaddr.IPNetwork(value).cidr)
  417. return queryset.filter(prefix__net_contained=query)
  418. except (AddrFormatError, ValueError):
  419. return queryset.none()
  420. def search_within_include(self, queryset, name, value):
  421. value = value.strip()
  422. if not value:
  423. return queryset
  424. try:
  425. query = str(netaddr.IPNetwork(value).cidr)
  426. return queryset.filter(prefix__net_contained_or_equal=query)
  427. except (AddrFormatError, ValueError):
  428. return queryset.none()
  429. def search_contains(self, queryset, name, value):
  430. value = value.strip()
  431. if not value:
  432. return queryset
  433. try:
  434. # Searching by prefix
  435. if '/' in value:
  436. return queryset.filter(prefix__net_contains_or_equals=str(netaddr.IPNetwork(value).cidr))
  437. # Searching by IP address
  438. return queryset.filter(prefix__net_contains=str(netaddr.IPAddress(value)))
  439. except (AddrFormatError, ValueError):
  440. return queryset.none()
  441. @extend_schema_field(OpenApiTypes.STR)
  442. def filter_present_in_vrf(self, queryset, name, vrf):
  443. if vrf is None:
  444. return queryset.none()
  445. return queryset.filter(
  446. Q(vrf=vrf) |
  447. Q(vrf__export_targets__in=vrf.import_targets.all())
  448. ).distinct()
  449. @register_filterset
  450. class IPRangeFilterSet(PrimaryModelFilterSet, TenancyFilterSet, ContactModelFilterSet):
  451. family = django_filters.NumberFilter(
  452. field_name='start_address',
  453. lookup_expr='family'
  454. )
  455. start_address = MultiValueCharFilter(
  456. method='filter_address',
  457. label=_('Address'),
  458. )
  459. end_address = MultiValueCharFilter(
  460. method='filter_address',
  461. label=_('Address'),
  462. )
  463. contains = django_filters.CharFilter(
  464. method='search_contains',
  465. label=_('Ranges which contain this prefix or IP'),
  466. )
  467. vrf_id = django_filters.ModelMultipleChoiceFilter(
  468. queryset=VRF.objects.all(),
  469. distinct=False,
  470. label=_('VRF'),
  471. )
  472. vrf = django_filters.ModelMultipleChoiceFilter(
  473. field_name='vrf__rd',
  474. queryset=VRF.objects.all(),
  475. distinct=False,
  476. to_field_name='rd',
  477. label=_('VRF (RD)'),
  478. )
  479. role_id = django_filters.ModelMultipleChoiceFilter(
  480. queryset=Role.objects.all(),
  481. distinct=False,
  482. label=_('Role (ID)'),
  483. )
  484. role = django_filters.ModelMultipleChoiceFilter(
  485. field_name='role__slug',
  486. queryset=Role.objects.all(),
  487. distinct=False,
  488. to_field_name='slug',
  489. label=_('Role (slug)'),
  490. )
  491. status = django_filters.MultipleChoiceFilter(
  492. choices=IPRangeStatusChoices,
  493. distinct=False,
  494. null_value=None
  495. )
  496. parent = MultiValueCharFilter(
  497. method='search_by_parent',
  498. label=_('Parent prefix'),
  499. )
  500. class Meta:
  501. model = IPRange
  502. fields = ('id', 'mark_populated', 'mark_utilized', 'size', 'description')
  503. def search(self, queryset, name, value):
  504. if not value.strip():
  505. return queryset
  506. qs_filter = Q(description__icontains=value) | Q(start_address__contains=value) | Q(end_address__contains=value)
  507. try:
  508. ipaddress = str(netaddr.IPNetwork(value.strip()))
  509. qs_filter |= Q(start_address=ipaddress)
  510. qs_filter |= Q(end_address=ipaddress)
  511. except (AddrFormatError, ValueError):
  512. pass
  513. return queryset.filter(qs_filter)
  514. def search_contains(self, queryset, name, value):
  515. value = value.strip()
  516. if not value:
  517. return queryset
  518. try:
  519. # Strip mask
  520. ipaddress = netaddr.IPNetwork(value)
  521. return queryset.filter(start_address__lte=ipaddress, end_address__gte=ipaddress)
  522. except (AddrFormatError, ValueError):
  523. return queryset.none()
  524. def filter_address(self, queryset, name, value):
  525. try:
  526. return queryset.filter(**{f'{name}__net_in': value})
  527. except ValidationError:
  528. return queryset.none()
  529. def search_by_parent(self, queryset, name, value):
  530. if not value:
  531. return queryset
  532. q = Q()
  533. for prefix in value:
  534. try:
  535. query = str(netaddr.IPNetwork(prefix.strip()).cidr)
  536. q |= Q(start_address__net_host_contained=query, end_address__net_host_contained=query)
  537. except (AddrFormatError, ValueError):
  538. return queryset.none()
  539. return queryset.filter(q)
  540. @register_filterset
  541. class IPAddressFilterSet(PrimaryModelFilterSet, TenancyFilterSet, ContactModelFilterSet):
  542. family = django_filters.NumberFilter(
  543. field_name='address',
  544. lookup_expr='family'
  545. )
  546. parent = MultiValueCharFilter(
  547. method='search_by_parent',
  548. label=_('Parent prefix'),
  549. )
  550. address = MultiValueCharFilter(
  551. method='filter_address',
  552. label=_('Address'),
  553. )
  554. mask_length = MultiValueNumberFilter(
  555. field_name='address',
  556. lookup_expr='net_mask_length',
  557. label=_('Mask length')
  558. )
  559. mask_length__gte = django_filters.NumberFilter(
  560. field_name='address',
  561. lookup_expr='net_mask_length__gte'
  562. )
  563. mask_length__lte = django_filters.NumberFilter(
  564. field_name='address',
  565. lookup_expr='net_mask_length__lte'
  566. )
  567. vrf_id = django_filters.ModelMultipleChoiceFilter(
  568. queryset=VRF.objects.all(),
  569. distinct=False,
  570. label=_('VRF'),
  571. )
  572. vrf = django_filters.ModelMultipleChoiceFilter(
  573. field_name='vrf__rd',
  574. queryset=VRF.objects.all(),
  575. distinct=False,
  576. to_field_name='rd',
  577. label=_('VRF (RD)'),
  578. )
  579. present_in_vrf_id = django_filters.ModelChoiceFilter(
  580. queryset=VRF.objects.all(),
  581. method='filter_present_in_vrf',
  582. label=_('VRF')
  583. )
  584. present_in_vrf = django_filters.ModelChoiceFilter(
  585. queryset=VRF.objects.all(),
  586. method='filter_present_in_vrf',
  587. to_field_name='rd',
  588. label=_('VRF (RD)'),
  589. )
  590. assigned_object_type = MultiValueContentTypeFilter()
  591. device = MultiValueCharFilter(
  592. method='filter_device',
  593. field_name='name',
  594. label=_('Device (name)'),
  595. )
  596. device_id = MultiValueNumberFilter(
  597. method='filter_device',
  598. field_name='pk',
  599. label=_('Device (ID)'),
  600. )
  601. virtual_machine = MultiValueCharFilter(
  602. method='filter_virtual_machine',
  603. field_name='name',
  604. label=_('Virtual machine (name)'),
  605. )
  606. virtual_machine_id = MultiValueNumberFilter(
  607. method='filter_virtual_machine',
  608. field_name='pk',
  609. label=_('Virtual machine (ID)'),
  610. )
  611. interface = django_filters.ModelMultipleChoiceFilter(
  612. field_name='interface__name',
  613. queryset=Interface.objects.all(),
  614. to_field_name='name',
  615. label=_('Interface (name)'),
  616. )
  617. interface_id = django_filters.ModelMultipleChoiceFilter(
  618. field_name='interface',
  619. queryset=Interface.objects.all(),
  620. label=_('Interface (ID)'),
  621. )
  622. vminterface = django_filters.ModelMultipleChoiceFilter(
  623. field_name='vminterface__name',
  624. queryset=VMInterface.objects.all(),
  625. to_field_name='name',
  626. label=_('VM interface (name)'),
  627. )
  628. vminterface_id = django_filters.ModelMultipleChoiceFilter(
  629. field_name='vminterface',
  630. queryset=VMInterface.objects.all(),
  631. label=_('VM interface (ID)'),
  632. )
  633. fhrpgroup_id = django_filters.ModelMultipleChoiceFilter(
  634. field_name='fhrpgroup',
  635. queryset=FHRPGroup.objects.all(),
  636. label=_('FHRP group (ID)'),
  637. )
  638. assigned_to_interface = django_filters.BooleanFilter(
  639. method='_assigned_to_interface',
  640. label=_('Is assigned to an interface'),
  641. )
  642. assigned = django_filters.BooleanFilter(
  643. method='_assigned',
  644. label=_('Is assigned'),
  645. )
  646. status = django_filters.MultipleChoiceFilter(
  647. choices=IPAddressStatusChoices,
  648. distinct=False,
  649. null_value=None
  650. )
  651. role = django_filters.MultipleChoiceFilter(
  652. choices=IPAddressRoleChoices,
  653. distinct=False,
  654. )
  655. service_id = django_filters.ModelMultipleChoiceFilter(
  656. field_name='services',
  657. queryset=Service.objects.all(),
  658. label=_('Application Service (ID)'),
  659. )
  660. nat_inside_id = django_filters.ModelMultipleChoiceFilter(
  661. field_name='nat_inside',
  662. queryset=IPAddress.objects.all(),
  663. distinct=False,
  664. label=_('NAT inside IP address (ID)'),
  665. )
  666. class Meta:
  667. model = IPAddress
  668. fields = ('id', 'dns_name', 'description', 'assigned_object_type', 'assigned_object_id')
  669. def search(self, queryset, name, value):
  670. if not value.strip():
  671. return queryset
  672. qs_filter = (
  673. Q(dns_name__icontains=value) |
  674. Q(description__icontains=value) |
  675. Q(address__istartswith=value)
  676. )
  677. return queryset.filter(qs_filter)
  678. def search_by_parent(self, queryset, name, value):
  679. if not value:
  680. return queryset
  681. q = Q()
  682. for prefix in value:
  683. try:
  684. query = str(netaddr.IPNetwork(prefix.strip()).cidr)
  685. q |= Q(address__net_host_contained=query)
  686. except (AddrFormatError, ValueError):
  687. return queryset.none()
  688. return queryset.filter(q)
  689. def parse_inet_addresses(self, value):
  690. """
  691. Parse networks or IP addresses and cast to a format
  692. acceptable by the Postgres inet type.
  693. Skips invalid values.
  694. """
  695. parsed = []
  696. for addr in value:
  697. if netaddr.valid_ipv4(addr) or netaddr.valid_ipv6(addr):
  698. parsed.append(addr)
  699. continue
  700. try:
  701. network = netaddr.IPNetwork(addr)
  702. parsed.append(str(network))
  703. except (AddrFormatError, ValueError):
  704. continue
  705. return parsed
  706. def filter_address(self, queryset, name, value):
  707. # Let's first parse the addresses passed
  708. # as argument. If they are all invalid,
  709. # we return an empty queryset
  710. value = self.parse_inet_addresses(value)
  711. if len(value) == 0:
  712. return queryset.none()
  713. try:
  714. return queryset.filter(address__net_in=value)
  715. except ValidationError:
  716. return queryset.none()
  717. @extend_schema_field(OpenApiTypes.STR)
  718. def filter_present_in_vrf(self, queryset, name, vrf):
  719. if vrf is None:
  720. return queryset.none()
  721. return queryset.filter(
  722. Q(vrf=vrf) |
  723. Q(vrf__export_targets__in=vrf.import_targets.all())
  724. ).distinct()
  725. def filter_device(self, queryset, name, value):
  726. devices = Device.objects.filter(**{'{}__in'.format(name): value})
  727. if not devices.exists():
  728. return queryset.none()
  729. interface_ids = []
  730. for device in devices:
  731. interface_ids.extend(device.vc_interfaces().values_list('id', flat=True))
  732. return queryset.filter(
  733. interface__in=interface_ids
  734. )
  735. def filter_virtual_machine(self, queryset, name, value):
  736. virtual_machines = VirtualMachine.objects.filter(**{'{}__in'.format(name): value})
  737. if not virtual_machines.exists():
  738. return queryset.none()
  739. interface_ids = []
  740. for vm in virtual_machines:
  741. interface_ids.extend(vm.interfaces.values_list('id', flat=True))
  742. return queryset.filter(
  743. vminterface__in=interface_ids
  744. )
  745. def _assigned_to_interface(self, queryset, name, value):
  746. content_types = ContentType.objects.get_for_models(Interface, VMInterface).values()
  747. if value:
  748. return queryset.filter(
  749. assigned_object_type__in=content_types,
  750. assigned_object_id__isnull=False
  751. )
  752. return queryset.exclude(
  753. assigned_object_type__in=content_types,
  754. assigned_object_id__isnull=False
  755. )
  756. def _assigned(self, queryset, name, value):
  757. if value:
  758. return queryset.exclude(
  759. assigned_object_type__isnull=True,
  760. assigned_object_id__isnull=True
  761. )
  762. return queryset.filter(
  763. assigned_object_type__isnull=True,
  764. assigned_object_id__isnull=True
  765. )
  766. @register_filterset
  767. class FHRPGroupFilterSet(PrimaryModelFilterSet):
  768. protocol = django_filters.MultipleChoiceFilter(
  769. choices=FHRPGroupProtocolChoices,
  770. distinct=False,
  771. )
  772. auth_type = django_filters.MultipleChoiceFilter(
  773. choices=FHRPGroupAuthTypeChoices,
  774. distinct=False,
  775. )
  776. related_ip = django_filters.ModelMultipleChoiceFilter(
  777. queryset=IPAddress.objects.all(),
  778. method='filter_related_ip'
  779. )
  780. class Meta:
  781. model = FHRPGroup
  782. fields = ('id', 'group_id', 'name', 'auth_key', 'description')
  783. def search(self, queryset, name, value):
  784. if not value.strip():
  785. return queryset
  786. return queryset.filter(
  787. Q(description__icontains=value) |
  788. Q(group_id__contains=value) |
  789. Q(name__icontains=value)
  790. )
  791. @extend_schema_field(OpenApiTypes.STR)
  792. def filter_related_ip(self, queryset, name, value):
  793. """
  794. Filter by VRF & prefix of assigned IP addresses.
  795. """
  796. ip_filter = Q()
  797. for ipaddress in value:
  798. if ipaddress.vrf:
  799. q = Q(
  800. ip_addresses__address__net_contained_or_equal=ipaddress.address,
  801. ip_addresses__vrf=ipaddress.vrf
  802. )
  803. else:
  804. q = Q(
  805. ip_addresses__address__net_contained_or_equal=ipaddress.address,
  806. ip_addresses__vrf__isnull=True
  807. )
  808. ip_filter |= q
  809. return queryset.filter(ip_filter)
  810. @register_filterset
  811. class FHRPGroupAssignmentFilterSet(ChangeLoggedModelFilterSet):
  812. interface_type = MultiValueContentTypeFilter()
  813. group_id = django_filters.ModelMultipleChoiceFilter(
  814. queryset=FHRPGroup.objects.all(),
  815. distinct=False,
  816. label=_('Group (ID)'),
  817. )
  818. device = MultiValueCharFilter(
  819. method='filter_device',
  820. field_name='name',
  821. label=_('Device (name)'),
  822. )
  823. device_id = MultiValueNumberFilter(
  824. method='filter_device',
  825. field_name='pk',
  826. label=_('Device (ID)'),
  827. )
  828. virtual_machine = MultiValueCharFilter(
  829. method='filter_virtual_machine',
  830. field_name='name',
  831. label=_('Virtual machine (name)'),
  832. )
  833. virtual_machine_id = MultiValueNumberFilter(
  834. method='filter_virtual_machine',
  835. field_name='pk',
  836. label=_('Virtual machine (ID)'),
  837. )
  838. class Meta:
  839. model = FHRPGroupAssignment
  840. fields = ('id', 'group_id', 'interface_type', 'interface_id', 'priority')
  841. def filter_device(self, queryset, name, value):
  842. devices = Device.objects.filter(**{f'{name}__in': value})
  843. if not devices.exists():
  844. return queryset.none()
  845. interface_ids = []
  846. for device in devices:
  847. interface_ids.extend(device.vc_interfaces().values_list('id', flat=True))
  848. return queryset.filter(
  849. Q(interface_type=ContentType.objects.get_for_model(Interface), interface_id__in=interface_ids)
  850. )
  851. def filter_virtual_machine(self, queryset, name, value):
  852. virtual_machines = VirtualMachine.objects.filter(**{f'{name}__in': value})
  853. if not virtual_machines.exists():
  854. return queryset.none()
  855. interface_ids = []
  856. for vm in virtual_machines:
  857. interface_ids.extend(vm.interfaces.values_list('id', flat=True))
  858. return queryset.filter(
  859. Q(interface_type=ContentType.objects.get_for_model(VMInterface), interface_id__in=interface_ids)
  860. )
  861. @register_filterset
  862. class VLANGroupFilterSet(OrganizationalModelFilterSet, TenancyFilterSet):
  863. scope_type = MultiValueContentTypeFilter()
  864. region = django_filters.NumberFilter(
  865. method='filter_scope'
  866. )
  867. site_group = django_filters.NumberFilter(
  868. method='filter_scope'
  869. )
  870. site = django_filters.NumberFilter(
  871. method='filter_scope'
  872. )
  873. location = django_filters.NumberFilter(
  874. method='filter_scope'
  875. )
  876. rack = django_filters.NumberFilter(
  877. method='filter_scope'
  878. )
  879. cluster_group = django_filters.NumberFilter(
  880. method='filter_scope'
  881. )
  882. cluster = django_filters.NumberFilter(
  883. method='filter_scope'
  884. )
  885. contains_vid = django_filters.NumberFilter(
  886. field_name='vid_ranges',
  887. lookup_expr='range_contains',
  888. )
  889. class Meta:
  890. model = VLANGroup
  891. fields = ('id', 'name', 'slug', 'description', 'scope_id')
  892. def search(self, queryset, name, value):
  893. if not value.strip():
  894. return queryset
  895. qs_filter = (
  896. Q(name__icontains=value) |
  897. Q(description__icontains=value)
  898. )
  899. return queryset.filter(qs_filter)
  900. def filter_scope(self, queryset, name, value):
  901. model_name = name.replace('_', '')
  902. return queryset.filter(
  903. scope_type=ContentType.objects.get(model=model_name),
  904. scope_id=value
  905. )
  906. @register_filterset
  907. class VLANFilterSet(PrimaryModelFilterSet, TenancyFilterSet):
  908. region_id = TreeNodeMultipleChoiceFilter(
  909. queryset=Region.objects.all(),
  910. field_name='site__region',
  911. lookup_expr='in',
  912. label=_('Region (ID)'),
  913. )
  914. region = TreeNodeMultipleChoiceFilter(
  915. queryset=Region.objects.all(),
  916. field_name='site__region',
  917. lookup_expr='in',
  918. to_field_name='slug',
  919. label=_('Region (slug)'),
  920. )
  921. site_group_id = TreeNodeMultipleChoiceFilter(
  922. queryset=SiteGroup.objects.all(),
  923. field_name='site__group',
  924. lookup_expr='in',
  925. label=_('Site group (ID)'),
  926. )
  927. site_group = TreeNodeMultipleChoiceFilter(
  928. queryset=SiteGroup.objects.all(),
  929. field_name='site__group',
  930. lookup_expr='in',
  931. to_field_name='slug',
  932. label=_('Site group (slug)'),
  933. )
  934. site_id = django_filters.ModelMultipleChoiceFilter(
  935. queryset=Site.objects.all(),
  936. distinct=False,
  937. label=_('Site (ID)'),
  938. )
  939. site = django_filters.ModelMultipleChoiceFilter(
  940. field_name='site__slug',
  941. queryset=Site.objects.all(),
  942. distinct=False,
  943. to_field_name='slug',
  944. label=_('Site (slug)'),
  945. )
  946. group_id = django_filters.ModelMultipleChoiceFilter(
  947. queryset=VLANGroup.objects.all(),
  948. distinct=False,
  949. label=_('Group (ID)'),
  950. )
  951. group = django_filters.ModelMultipleChoiceFilter(
  952. field_name='group__slug',
  953. queryset=VLANGroup.objects.all(),
  954. distinct=False,
  955. to_field_name='slug',
  956. label=_('Group'),
  957. )
  958. role_id = django_filters.ModelMultipleChoiceFilter(
  959. queryset=Role.objects.all(),
  960. distinct=False,
  961. label=_('Role (ID)'),
  962. )
  963. role = django_filters.ModelMultipleChoiceFilter(
  964. field_name='role__slug',
  965. queryset=Role.objects.all(),
  966. distinct=False,
  967. to_field_name='slug',
  968. label=_('Role (slug)'),
  969. )
  970. status = django_filters.MultipleChoiceFilter(
  971. choices=VLANStatusChoices,
  972. distinct=False,
  973. null_value=None
  974. )
  975. available_at_site = django_filters.ModelChoiceFilter(
  976. queryset=Site.objects.all(),
  977. method='get_for_site'
  978. )
  979. available_on_device = django_filters.ModelChoiceFilter(
  980. queryset=Device.objects.all(),
  981. method='get_for_device'
  982. )
  983. available_on_virtualmachine = django_filters.ModelChoiceFilter(
  984. queryset=VirtualMachine.objects.all(),
  985. method='get_for_virtualmachine'
  986. )
  987. qinq_role = django_filters.MultipleChoiceFilter(
  988. choices=VLANQinQRoleChoices,
  989. distinct=False,
  990. )
  991. qinq_svlan_id = django_filters.ModelMultipleChoiceFilter(
  992. queryset=VLAN.objects.all(),
  993. distinct=False,
  994. label=_('Q-in-Q SVLAN (ID)'),
  995. )
  996. qinq_svlan_vid = MultiValueNumberFilter(
  997. field_name='qinq_svlan__vid',
  998. label=_('Q-in-Q SVLAN number (1-4094)'),
  999. )
  1000. l2vpn_id = django_filters.ModelMultipleChoiceFilter(
  1001. field_name='l2vpn_terminations__l2vpn',
  1002. queryset=L2VPN.objects.all(),
  1003. label=_('L2VPN (ID)'),
  1004. )
  1005. l2vpn = django_filters.ModelMultipleChoiceFilter(
  1006. field_name='l2vpn_terminations__l2vpn__identifier',
  1007. queryset=L2VPN.objects.all(),
  1008. to_field_name='identifier',
  1009. label=_('L2VPN'),
  1010. )
  1011. interface_id = django_filters.ModelChoiceFilter(
  1012. queryset=Interface.objects.all(),
  1013. method='filter_interface_id',
  1014. label=_('Assigned interface')
  1015. )
  1016. vminterface_id = django_filters.ModelChoiceFilter(
  1017. queryset=VMInterface.objects.all(),
  1018. method='filter_vminterface_id',
  1019. label=_('Assigned VM interface')
  1020. )
  1021. class Meta:
  1022. model = VLAN
  1023. fields = ('id', 'vid', 'name', 'description')
  1024. def search(self, queryset, name, value):
  1025. if not value.strip():
  1026. return queryset
  1027. qs_filter = Q(name__icontains=value) | Q(description__icontains=value)
  1028. try:
  1029. qs_filter |= Q(vid=int(value.strip()))
  1030. except ValueError:
  1031. pass
  1032. return queryset.filter(qs_filter)
  1033. @extend_schema_field(OpenApiTypes.STR)
  1034. def get_for_site(self, queryset, name, value):
  1035. return queryset.get_for_site(value)
  1036. @extend_schema_field(OpenApiTypes.STR)
  1037. def get_for_device(self, queryset, name, value):
  1038. return queryset.get_for_device(value)
  1039. @extend_schema_field(OpenApiTypes.STR)
  1040. def get_for_virtualmachine(self, queryset, name, value):
  1041. return queryset.get_for_virtualmachine(value)
  1042. @extend_schema_field(OpenApiTypes.INT)
  1043. def filter_interface_id(self, queryset, name, value):
  1044. if value is None:
  1045. return queryset.none()
  1046. return queryset.filter(
  1047. Q(interfaces_as_tagged=value) |
  1048. Q(interfaces_as_untagged=value)
  1049. ).distinct()
  1050. @extend_schema_field(OpenApiTypes.INT)
  1051. def filter_vminterface_id(self, queryset, name, value):
  1052. if value is None:
  1053. return queryset.none()
  1054. return queryset.filter(
  1055. Q(vminterfaces_as_tagged=value) |
  1056. Q(vminterfaces_as_untagged=value)
  1057. ).distinct()
  1058. @register_filterset
  1059. class VLANTranslationPolicyFilterSet(PrimaryModelFilterSet):
  1060. class Meta:
  1061. model = VLANTranslationPolicy
  1062. fields = ('id', 'name', 'description')
  1063. def search(self, queryset, name, value):
  1064. if not value.strip():
  1065. return queryset
  1066. qs_filter = (
  1067. Q(name__icontains=value) |
  1068. Q(description__icontains=value)
  1069. )
  1070. return queryset.filter(qs_filter)
  1071. @register_filterset
  1072. class VLANTranslationRuleFilterSet(NetBoxModelFilterSet):
  1073. policy_id = django_filters.ModelMultipleChoiceFilter(
  1074. queryset=VLANTranslationPolicy.objects.all(),
  1075. distinct=False,
  1076. label=_('VLAN Translation Policy (ID)'),
  1077. )
  1078. policy = django_filters.ModelMultipleChoiceFilter(
  1079. field_name='policy__name',
  1080. queryset=VLANTranslationPolicy.objects.all(),
  1081. distinct=False,
  1082. to_field_name='name',
  1083. label=_('VLAN Translation Policy (name)'),
  1084. )
  1085. class Meta:
  1086. model = VLANTranslationRule
  1087. fields = ('id', 'policy_id', 'policy', 'local_vid', 'remote_vid', 'description')
  1088. def search(self, queryset, name, value):
  1089. if not value.strip():
  1090. return queryset
  1091. qs_filter = (
  1092. Q(policy__name__icontains=value)
  1093. )
  1094. try:
  1095. int_value = int(value.strip())
  1096. qs_filter |= Q(local_vid=int_value)
  1097. qs_filter |= Q(remote_vid=int_value)
  1098. except ValueError:
  1099. pass
  1100. return queryset.filter(qs_filter)
  1101. @register_filterset
  1102. class ServiceTemplateFilterSet(PrimaryModelFilterSet):
  1103. port = NumericArrayFilter(
  1104. field_name='ports',
  1105. lookup_expr='contains'
  1106. )
  1107. class Meta:
  1108. model = ServiceTemplate
  1109. fields = ('id', 'name', 'protocol', 'description')
  1110. def search(self, queryset, name, value):
  1111. if not value.strip():
  1112. return queryset
  1113. qs_filter = (
  1114. Q(name__icontains=value) |
  1115. Q(description__icontains=value)
  1116. )
  1117. return queryset.filter(qs_filter)
  1118. @register_filterset
  1119. class ServiceFilterSet(ContactModelFilterSet, PrimaryModelFilterSet):
  1120. parent_object_type = MultiValueContentTypeFilter()
  1121. device = MultiValueCharFilter(
  1122. method='filter_device',
  1123. field_name='name',
  1124. label=_('Device (name)'),
  1125. )
  1126. device_id = MultiValueNumberFilter(
  1127. method='filter_device',
  1128. field_name='pk',
  1129. label=_('Device (ID)'),
  1130. )
  1131. virtual_machine = MultiValueCharFilter(
  1132. method='filter_virtual_machine',
  1133. field_name='name',
  1134. label=_('Virtual machine (name)'),
  1135. )
  1136. virtual_machine_id = MultiValueNumberFilter(
  1137. method='filter_virtual_machine',
  1138. field_name='pk',
  1139. label=_('Virtual machine (ID)'),
  1140. )
  1141. fhrpgroup = MultiValueCharFilter(
  1142. method='filter_fhrp_group',
  1143. field_name='name',
  1144. label=_('FHRP Group (name)'),
  1145. )
  1146. fhrpgroup_id = MultiValueNumberFilter(
  1147. method='filter_fhrp_group',
  1148. field_name='pk',
  1149. label=_('FHRP Group (ID)'),
  1150. )
  1151. ip_address_id = django_filters.ModelMultipleChoiceFilter(
  1152. field_name='ipaddresses',
  1153. queryset=IPAddress.objects.all(),
  1154. label=_('IP address (ID)'),
  1155. )
  1156. ip_address = django_filters.ModelMultipleChoiceFilter(
  1157. field_name='ipaddresses__address',
  1158. queryset=IPAddress.objects.all(),
  1159. to_field_name='address',
  1160. label=_('IP address'),
  1161. )
  1162. port = NumericArrayFilter(
  1163. field_name='ports',
  1164. lookup_expr='contains'
  1165. )
  1166. class Meta:
  1167. model = Service
  1168. fields = ('id', 'name', 'protocol', 'description', 'parent_object_type', 'parent_object_id')
  1169. def search(self, queryset, name, value):
  1170. if not value.strip():
  1171. return queryset
  1172. qs_filter = Q(name__icontains=value) | Q(description__icontains=value)
  1173. return queryset.filter(qs_filter)
  1174. def filter_device(self, queryset, name, value):
  1175. devices = Device.objects.filter(**{'{}__in'.format(name): value})
  1176. if not devices.exists():
  1177. return queryset.none()
  1178. service_ids = []
  1179. for device in devices:
  1180. service_ids.extend(device.services.values_list('id', flat=True))
  1181. return queryset.filter(id__in=service_ids)
  1182. def filter_fhrp_group(self, queryset, name, value):
  1183. groups = FHRPGroup.objects.filter(**{'{}__in'.format(name): value})
  1184. if not groups.exists():
  1185. return queryset.none()
  1186. service_ids = []
  1187. for group in groups:
  1188. service_ids.extend(group.services.values_list('id', flat=True))
  1189. return queryset.filter(id__in=service_ids)
  1190. def filter_virtual_machine(self, queryset, name, value):
  1191. virtual_machines = VirtualMachine.objects.filter(**{'{}__in'.format(name): value})
  1192. if not virtual_machines.exists():
  1193. return queryset.none()
  1194. service_ids = []
  1195. for vm in virtual_machines:
  1196. service_ids.extend(vm.services.values_list('id', flat=True))
  1197. return queryset.filter(id__in=service_ids)
  1198. class PrimaryIPFilterSet(django_filters.FilterSet):
  1199. """
  1200. An inheritable FilterSet for models which support primary IP assignment.
  1201. """
  1202. primary_ip4_id = django_filters.ModelMultipleChoiceFilter(
  1203. field_name='primary_ip4',
  1204. queryset=IPAddress.objects.all(),
  1205. distinct=False,
  1206. label=_('Primary IPv4 (ID)'),
  1207. )
  1208. primary_ip4 = django_filters.ModelMultipleChoiceFilter(
  1209. field_name='primary_ip4__address',
  1210. queryset=IPAddress.objects.all(),
  1211. distinct=False,
  1212. to_field_name='address',
  1213. label=_('Primary IPv4 (address)'),
  1214. )
  1215. primary_ip6_id = django_filters.ModelMultipleChoiceFilter(
  1216. field_name='primary_ip6',
  1217. queryset=IPAddress.objects.all(),
  1218. distinct=False,
  1219. label=_('Primary IPv6 (ID)'),
  1220. )
  1221. primary_ip6 = django_filters.ModelMultipleChoiceFilter(
  1222. field_name='primary_ip6__address',
  1223. queryset=IPAddress.objects.all(),
  1224. distinct=False,
  1225. to_field_name='address',
  1226. label=_('Primary IPv6 (address)'),
  1227. )