filters.py 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888
  1. import django_filters
  2. from django.contrib.auth.models import User
  3. from django.db.models import Q
  4. from netaddr import EUI
  5. from netaddr.core import AddrFormatError
  6. from extras.filters import CustomFieldFilterSet
  7. from tenancy.models import Tenant
  8. from utilities.filters import NullableCharFieldFilter, NumericInFilter
  9. from virtualization.models import Cluster
  10. from .constants import (
  11. DEVICE_STATUS_CHOICES, IFACE_FF_LAG, NONCONNECTABLE_IFACE_TYPES, SITE_STATUS_CHOICES, VIRTUAL_IFACE_TYPES,
  12. WIRELESS_IFACE_TYPES,
  13. )
  14. from .models import (
  15. Cable, ConsolePort, ConsolePortTemplate, ConsoleServerPort, ConsoleServerPortTemplate, Device, DeviceBay,
  16. DeviceBayTemplate, DeviceRole, DeviceType, FrontPort, FrontPortTemplate, Interface, InterfaceTemplate,
  17. InventoryItem, Manufacturer, Platform, PowerOutlet, PowerOutletTemplate, PowerPort, PowerPortTemplate, Rack,
  18. RackGroup, RackReservation, RackRole, RearPort, RearPortTemplate, Region, Site, VirtualChassis,
  19. )
  20. class RegionFilter(django_filters.FilterSet):
  21. q = django_filters.CharFilter(
  22. method='search',
  23. label='Search',
  24. )
  25. parent_id = django_filters.ModelMultipleChoiceFilter(
  26. queryset=Region.objects.all(),
  27. label='Parent region (ID)',
  28. )
  29. parent = django_filters.ModelMultipleChoiceFilter(
  30. name='parent__slug',
  31. queryset=Region.objects.all(),
  32. to_field_name='slug',
  33. label='Parent region (slug)',
  34. )
  35. class Meta:
  36. model = Region
  37. fields = ['name', 'slug']
  38. def search(self, queryset, name, value):
  39. if not value.strip():
  40. return queryset
  41. qs_filter = (
  42. Q(name__icontains=value) |
  43. Q(slug__icontains=value)
  44. )
  45. return queryset.filter(qs_filter)
  46. class SiteFilter(CustomFieldFilterSet, django_filters.FilterSet):
  47. id__in = NumericInFilter(name='id', lookup_expr='in')
  48. q = django_filters.CharFilter(
  49. method='search',
  50. label='Search',
  51. )
  52. status = django_filters.MultipleChoiceFilter(
  53. choices=SITE_STATUS_CHOICES,
  54. null_value=None
  55. )
  56. region_id = django_filters.ModelMultipleChoiceFilter(
  57. queryset=Region.objects.all(),
  58. label='Region (ID)',
  59. )
  60. region = django_filters.ModelMultipleChoiceFilter(
  61. name='region__slug',
  62. queryset=Region.objects.all(),
  63. to_field_name='slug',
  64. label='Region (slug)',
  65. )
  66. tenant_id = django_filters.ModelMultipleChoiceFilter(
  67. queryset=Tenant.objects.all(),
  68. label='Tenant (ID)',
  69. )
  70. tenant = django_filters.ModelMultipleChoiceFilter(
  71. name='tenant__slug',
  72. queryset=Tenant.objects.all(),
  73. to_field_name='slug',
  74. label='Tenant (slug)',
  75. )
  76. tag = django_filters.CharFilter(
  77. name='tags__slug',
  78. )
  79. class Meta:
  80. model = Site
  81. fields = ['q', 'name', 'slug', 'facility', 'asn', 'contact_name', 'contact_phone', 'contact_email']
  82. def search(self, queryset, name, value):
  83. if not value.strip():
  84. return queryset
  85. qs_filter = (
  86. Q(name__icontains=value) |
  87. Q(facility__icontains=value) |
  88. Q(description__icontains=value) |
  89. Q(physical_address__icontains=value) |
  90. Q(shipping_address__icontains=value) |
  91. Q(contact_name__icontains=value) |
  92. Q(contact_phone__icontains=value) |
  93. Q(contact_email__icontains=value) |
  94. Q(comments__icontains=value)
  95. )
  96. try:
  97. qs_filter |= Q(asn=int(value.strip()))
  98. except ValueError:
  99. pass
  100. return queryset.filter(qs_filter)
  101. class RackGroupFilter(django_filters.FilterSet):
  102. q = django_filters.CharFilter(
  103. method='search',
  104. label='Search',
  105. )
  106. site_id = django_filters.ModelMultipleChoiceFilter(
  107. queryset=Site.objects.all(),
  108. label='Site (ID)',
  109. )
  110. site = django_filters.ModelMultipleChoiceFilter(
  111. name='site__slug',
  112. queryset=Site.objects.all(),
  113. to_field_name='slug',
  114. label='Site (slug)',
  115. )
  116. class Meta:
  117. model = RackGroup
  118. fields = ['site_id', 'name', 'slug']
  119. def search(self, queryset, name, value):
  120. if not value.strip():
  121. return queryset
  122. qs_filter = (
  123. Q(name__icontains=value) |
  124. Q(slug__icontains=value)
  125. )
  126. return queryset.filter(qs_filter)
  127. class RackRoleFilter(django_filters.FilterSet):
  128. class Meta:
  129. model = RackRole
  130. fields = ['name', 'slug', 'color']
  131. class RackFilter(CustomFieldFilterSet, django_filters.FilterSet):
  132. id__in = NumericInFilter(name='id', lookup_expr='in')
  133. q = django_filters.CharFilter(
  134. method='search',
  135. label='Search',
  136. )
  137. facility_id = NullableCharFieldFilter()
  138. site_id = django_filters.ModelMultipleChoiceFilter(
  139. queryset=Site.objects.all(),
  140. label='Site (ID)',
  141. )
  142. site = django_filters.ModelMultipleChoiceFilter(
  143. name='site__slug',
  144. queryset=Site.objects.all(),
  145. to_field_name='slug',
  146. label='Site (slug)',
  147. )
  148. group_id = django_filters.ModelMultipleChoiceFilter(
  149. queryset=RackGroup.objects.all(),
  150. label='Group (ID)',
  151. )
  152. group = django_filters.ModelMultipleChoiceFilter(
  153. name='group__slug',
  154. queryset=RackGroup.objects.all(),
  155. to_field_name='slug',
  156. label='Group',
  157. )
  158. tenant_id = django_filters.ModelMultipleChoiceFilter(
  159. queryset=Tenant.objects.all(),
  160. label='Tenant (ID)',
  161. )
  162. tenant = django_filters.ModelMultipleChoiceFilter(
  163. name='tenant__slug',
  164. queryset=Tenant.objects.all(),
  165. to_field_name='slug',
  166. label='Tenant (slug)',
  167. )
  168. role_id = django_filters.ModelMultipleChoiceFilter(
  169. queryset=RackRole.objects.all(),
  170. label='Role (ID)',
  171. )
  172. role = django_filters.ModelMultipleChoiceFilter(
  173. name='role__slug',
  174. queryset=RackRole.objects.all(),
  175. to_field_name='slug',
  176. label='Role (slug)',
  177. )
  178. tag = django_filters.CharFilter(
  179. name='tags__slug',
  180. )
  181. class Meta:
  182. model = Rack
  183. fields = ['name', 'serial', 'type', 'width', 'u_height', 'desc_units']
  184. def search(self, queryset, name, value):
  185. if not value.strip():
  186. return queryset
  187. return queryset.filter(
  188. Q(name__icontains=value) |
  189. Q(facility_id__icontains=value) |
  190. Q(serial__icontains=value.strip()) |
  191. Q(comments__icontains=value)
  192. )
  193. class RackReservationFilter(django_filters.FilterSet):
  194. id__in = NumericInFilter(name='id', lookup_expr='in')
  195. q = django_filters.CharFilter(
  196. method='search',
  197. label='Search',
  198. )
  199. rack_id = django_filters.ModelMultipleChoiceFilter(
  200. queryset=Rack.objects.all(),
  201. label='Rack (ID)',
  202. )
  203. site_id = django_filters.ModelMultipleChoiceFilter(
  204. name='rack__site',
  205. queryset=Site.objects.all(),
  206. label='Site (ID)',
  207. )
  208. site = django_filters.ModelMultipleChoiceFilter(
  209. name='rack__site__slug',
  210. queryset=Site.objects.all(),
  211. to_field_name='slug',
  212. label='Site (slug)',
  213. )
  214. group_id = django_filters.ModelMultipleChoiceFilter(
  215. name='rack__group',
  216. queryset=RackGroup.objects.all(),
  217. label='Group (ID)',
  218. )
  219. group = django_filters.ModelMultipleChoiceFilter(
  220. name='rack__group__slug',
  221. queryset=RackGroup.objects.all(),
  222. to_field_name='slug',
  223. label='Group',
  224. )
  225. tenant_id = django_filters.ModelMultipleChoiceFilter(
  226. queryset=Tenant.objects.all(),
  227. label='Tenant (ID)',
  228. )
  229. tenant = django_filters.ModelMultipleChoiceFilter(
  230. name='tenant__slug',
  231. queryset=Tenant.objects.all(),
  232. to_field_name='slug',
  233. label='Tenant (slug)',
  234. )
  235. user_id = django_filters.ModelMultipleChoiceFilter(
  236. queryset=User.objects.all(),
  237. label='User (ID)',
  238. )
  239. user = django_filters.ModelMultipleChoiceFilter(
  240. name='user',
  241. queryset=User.objects.all(),
  242. to_field_name='username',
  243. label='User (name)',
  244. )
  245. class Meta:
  246. model = RackReservation
  247. fields = ['created']
  248. def search(self, queryset, name, value):
  249. if not value.strip():
  250. return queryset
  251. return queryset.filter(
  252. Q(rack__name__icontains=value) |
  253. Q(rack__facility_id__icontains=value) |
  254. Q(user__username__icontains=value) |
  255. Q(description__icontains=value)
  256. )
  257. class ManufacturerFilter(django_filters.FilterSet):
  258. class Meta:
  259. model = Manufacturer
  260. fields = ['name', 'slug']
  261. class DeviceTypeFilter(CustomFieldFilterSet, django_filters.FilterSet):
  262. id__in = NumericInFilter(name='id', lookup_expr='in')
  263. q = django_filters.CharFilter(
  264. method='search',
  265. label='Search',
  266. )
  267. manufacturer_id = django_filters.ModelMultipleChoiceFilter(
  268. queryset=Manufacturer.objects.all(),
  269. label='Manufacturer (ID)',
  270. )
  271. manufacturer = django_filters.ModelMultipleChoiceFilter(
  272. name='manufacturer__slug',
  273. queryset=Manufacturer.objects.all(),
  274. to_field_name='slug',
  275. label='Manufacturer (slug)',
  276. )
  277. tag = django_filters.CharFilter(
  278. name='tags__slug',
  279. )
  280. class Meta:
  281. model = DeviceType
  282. fields = [
  283. 'model', 'slug', 'part_number', 'u_height', 'is_full_depth', 'is_console_server', 'is_pdu',
  284. 'is_network_device', 'subdevice_role',
  285. ]
  286. def search(self, queryset, name, value):
  287. if not value.strip():
  288. return queryset
  289. return queryset.filter(
  290. Q(manufacturer__name__icontains=value) |
  291. Q(model__icontains=value) |
  292. Q(part_number__icontains=value) |
  293. Q(comments__icontains=value)
  294. )
  295. class DeviceTypeComponentFilterSet(django_filters.FilterSet):
  296. devicetype_id = django_filters.ModelMultipleChoiceFilter(
  297. queryset=DeviceType.objects.all(),
  298. name='device_type_id',
  299. label='Device type (ID)',
  300. )
  301. class ConsolePortTemplateFilter(DeviceTypeComponentFilterSet):
  302. class Meta:
  303. model = ConsolePortTemplate
  304. fields = ['name']
  305. class ConsoleServerPortTemplateFilter(DeviceTypeComponentFilterSet):
  306. class Meta:
  307. model = ConsoleServerPortTemplate
  308. fields = ['name']
  309. class PowerPortTemplateFilter(DeviceTypeComponentFilterSet):
  310. class Meta:
  311. model = PowerPortTemplate
  312. fields = ['name']
  313. class PowerOutletTemplateFilter(DeviceTypeComponentFilterSet):
  314. class Meta:
  315. model = PowerOutletTemplate
  316. fields = ['name']
  317. class InterfaceTemplateFilter(DeviceTypeComponentFilterSet):
  318. class Meta:
  319. model = InterfaceTemplate
  320. fields = ['name', 'form_factor', 'mgmt_only']
  321. class FrontPortTemplateFilter(DeviceTypeComponentFilterSet):
  322. class Meta:
  323. model = FrontPortTemplate
  324. fields = ['name', 'type']
  325. class RearPortTemplateFilter(DeviceTypeComponentFilterSet):
  326. class Meta:
  327. model = RearPortTemplate
  328. fields = ['name', 'type']
  329. class DeviceBayTemplateFilter(DeviceTypeComponentFilterSet):
  330. class Meta:
  331. model = DeviceBayTemplate
  332. fields = ['name']
  333. class DeviceRoleFilter(django_filters.FilterSet):
  334. class Meta:
  335. model = DeviceRole
  336. fields = ['name', 'slug', 'color', 'vm_role']
  337. class PlatformFilter(django_filters.FilterSet):
  338. manufacturer_id = django_filters.ModelMultipleChoiceFilter(
  339. name='manufacturer',
  340. queryset=Manufacturer.objects.all(),
  341. label='Manufacturer (ID)',
  342. )
  343. manufacturer = django_filters.ModelMultipleChoiceFilter(
  344. name='manufacturer__slug',
  345. queryset=Manufacturer.objects.all(),
  346. to_field_name='slug',
  347. label='Manufacturer (slug)',
  348. )
  349. class Meta:
  350. model = Platform
  351. fields = ['name', 'slug']
  352. class DeviceFilter(CustomFieldFilterSet, django_filters.FilterSet):
  353. id__in = NumericInFilter(name='id', lookup_expr='in')
  354. q = django_filters.CharFilter(
  355. method='search',
  356. label='Search',
  357. )
  358. manufacturer_id = django_filters.ModelMultipleChoiceFilter(
  359. name='device_type__manufacturer',
  360. queryset=Manufacturer.objects.all(),
  361. label='Manufacturer (ID)',
  362. )
  363. manufacturer = django_filters.ModelMultipleChoiceFilter(
  364. name='device_type__manufacturer__slug',
  365. queryset=Manufacturer.objects.all(),
  366. to_field_name='slug',
  367. label='Manufacturer (slug)',
  368. )
  369. device_type_id = django_filters.ModelMultipleChoiceFilter(
  370. queryset=DeviceType.objects.all(),
  371. label='Device type (ID)',
  372. )
  373. role_id = django_filters.ModelMultipleChoiceFilter(
  374. name='device_role_id',
  375. queryset=DeviceRole.objects.all(),
  376. label='Role (ID)',
  377. )
  378. role = django_filters.ModelMultipleChoiceFilter(
  379. name='device_role__slug',
  380. queryset=DeviceRole.objects.all(),
  381. to_field_name='slug',
  382. label='Role (slug)',
  383. )
  384. tenant_id = django_filters.ModelMultipleChoiceFilter(
  385. queryset=Tenant.objects.all(),
  386. label='Tenant (ID)',
  387. )
  388. tenant = django_filters.ModelMultipleChoiceFilter(
  389. name='tenant__slug',
  390. queryset=Tenant.objects.all(),
  391. to_field_name='slug',
  392. label='Tenant (slug)',
  393. )
  394. platform_id = django_filters.ModelMultipleChoiceFilter(
  395. queryset=Platform.objects.all(),
  396. label='Platform (ID)',
  397. )
  398. platform = django_filters.ModelMultipleChoiceFilter(
  399. name='platform__slug',
  400. queryset=Platform.objects.all(),
  401. to_field_name='slug',
  402. label='Platform (slug)',
  403. )
  404. name = NullableCharFieldFilter()
  405. asset_tag = NullableCharFieldFilter()
  406. site_id = django_filters.ModelMultipleChoiceFilter(
  407. queryset=Site.objects.all(),
  408. label='Site (ID)',
  409. )
  410. site = django_filters.ModelMultipleChoiceFilter(
  411. name='site__slug',
  412. queryset=Site.objects.all(),
  413. to_field_name='slug',
  414. label='Site name (slug)',
  415. )
  416. rack_group_id = django_filters.ModelMultipleChoiceFilter(
  417. name='rack__group',
  418. queryset=RackGroup.objects.all(),
  419. label='Rack group (ID)',
  420. )
  421. rack_id = django_filters.ModelMultipleChoiceFilter(
  422. name='rack',
  423. queryset=Rack.objects.all(),
  424. label='Rack (ID)',
  425. )
  426. cluster_id = django_filters.ModelMultipleChoiceFilter(
  427. queryset=Cluster.objects.all(),
  428. label='VM cluster (ID)',
  429. )
  430. model = django_filters.ModelMultipleChoiceFilter(
  431. name='device_type__slug',
  432. queryset=DeviceType.objects.all(),
  433. to_field_name='slug',
  434. label='Device model (slug)',
  435. )
  436. status = django_filters.MultipleChoiceFilter(
  437. choices=DEVICE_STATUS_CHOICES,
  438. null_value=None
  439. )
  440. is_full_depth = django_filters.BooleanFilter(
  441. name='device_type__is_full_depth',
  442. label='Is full depth',
  443. )
  444. is_console_server = django_filters.BooleanFilter(
  445. name='device_type__is_console_server',
  446. label='Is a console server',
  447. )
  448. is_pdu = django_filters.BooleanFilter(
  449. name='device_type__is_pdu',
  450. label='Is a PDU',
  451. )
  452. is_network_device = django_filters.BooleanFilter(
  453. name='device_type__is_network_device',
  454. label='Is a network device',
  455. )
  456. mac_address = django_filters.CharFilter(
  457. method='_mac_address',
  458. label='MAC address',
  459. )
  460. has_primary_ip = django_filters.BooleanFilter(
  461. method='_has_primary_ip',
  462. label='Has a primary IP',
  463. )
  464. virtual_chassis_id = django_filters.ModelMultipleChoiceFilter(
  465. name='virtual_chassis',
  466. queryset=VirtualChassis.objects.all(),
  467. label='Virtual chassis (ID)',
  468. )
  469. tag = django_filters.CharFilter(
  470. name='tags__slug',
  471. )
  472. class Meta:
  473. model = Device
  474. fields = ['serial', 'position']
  475. def search(self, queryset, name, value):
  476. if not value.strip():
  477. return queryset
  478. return queryset.filter(
  479. Q(name__icontains=value) |
  480. Q(serial__icontains=value.strip()) |
  481. Q(inventory_items__serial__icontains=value.strip()) |
  482. Q(asset_tag__icontains=value.strip()) |
  483. Q(comments__icontains=value)
  484. ).distinct()
  485. def _mac_address(self, queryset, name, value):
  486. value = value.strip()
  487. if not value:
  488. return queryset
  489. try:
  490. mac = EUI(value.strip())
  491. return queryset.filter(interfaces__mac_address=mac).distinct()
  492. except AddrFormatError:
  493. return queryset.none()
  494. def _has_primary_ip(self, queryset, name, value):
  495. if value:
  496. return queryset.filter(
  497. Q(primary_ip4__isnull=False) |
  498. Q(primary_ip6__isnull=False)
  499. )
  500. else:
  501. return queryset.exclude(
  502. Q(primary_ip4__isnull=False) |
  503. Q(primary_ip6__isnull=False)
  504. )
  505. class DeviceComponentFilterSet(django_filters.FilterSet):
  506. device_id = django_filters.ModelChoiceFilter(
  507. queryset=Device.objects.all(),
  508. label='Device (ID)',
  509. )
  510. device = django_filters.ModelChoiceFilter(
  511. queryset=Device.objects.all(),
  512. to_field_name='name',
  513. label='Device (name)',
  514. )
  515. tag = django_filters.CharFilter(
  516. name='tags__slug',
  517. )
  518. class ConsolePortFilter(DeviceComponentFilterSet):
  519. class Meta:
  520. model = ConsolePort
  521. fields = ['name']
  522. class ConsoleServerPortFilter(DeviceComponentFilterSet):
  523. class Meta:
  524. model = ConsoleServerPort
  525. fields = ['name']
  526. class PowerPortFilter(DeviceComponentFilterSet):
  527. class Meta:
  528. model = PowerPort
  529. fields = ['name']
  530. class PowerOutletFilter(DeviceComponentFilterSet):
  531. class Meta:
  532. model = PowerOutlet
  533. fields = ['name']
  534. class InterfaceFilter(django_filters.FilterSet):
  535. """
  536. Not using DeviceComponentFilterSet for Interfaces because we need to glean the ordering logic from the parent
  537. Device's DeviceType.
  538. """
  539. device = django_filters.CharFilter(
  540. method='filter_device',
  541. name='name',
  542. label='Device',
  543. )
  544. device_id = django_filters.NumberFilter(
  545. method='filter_device',
  546. name='pk',
  547. label='Device (ID)',
  548. )
  549. type = django_filters.CharFilter(
  550. method='filter_type',
  551. label='Interface type',
  552. )
  553. lag_id = django_filters.ModelMultipleChoiceFilter(
  554. name='lag',
  555. queryset=Interface.objects.all(),
  556. label='LAG interface (ID)',
  557. )
  558. mac_address = django_filters.CharFilter(
  559. method='_mac_address',
  560. label='MAC address',
  561. )
  562. tag = django_filters.CharFilter(
  563. name='tags__slug',
  564. )
  565. class Meta:
  566. model = Interface
  567. fields = ['name', 'form_factor', 'enabled', 'mtu', 'mgmt_only']
  568. def filter_device(self, queryset, name, value):
  569. try:
  570. device = Device.objects.select_related('device_type').get(**{name: value})
  571. vc_interface_ids = [i['id'] for i in device.vc_interfaces.values('id')]
  572. ordering = device.device_type.interface_ordering
  573. return queryset.filter(pk__in=vc_interface_ids).order_naturally(ordering)
  574. except Device.DoesNotExist:
  575. return queryset.none()
  576. def filter_type(self, queryset, name, value):
  577. value = value.strip().lower()
  578. return {
  579. 'physical': queryset.exclude(form_factor__in=NONCONNECTABLE_IFACE_TYPES),
  580. 'virtual': queryset.filter(form_factor__in=VIRTUAL_IFACE_TYPES),
  581. 'wireless': queryset.filter(form_factor__in=WIRELESS_IFACE_TYPES),
  582. 'lag': queryset.filter(form_factor=IFACE_FF_LAG),
  583. }.get(value, queryset.none())
  584. def _mac_address(self, queryset, name, value):
  585. value = value.strip()
  586. if not value:
  587. return queryset
  588. try:
  589. mac = EUI(value.strip())
  590. return queryset.filter(mac_address=mac)
  591. except AddrFormatError:
  592. return queryset.none()
  593. class FrontPortFilter(DeviceComponentFilterSet):
  594. class Meta:
  595. model = FrontPort
  596. fields = ['name', 'type']
  597. class RearPortFilter(DeviceComponentFilterSet):
  598. class Meta:
  599. model = RearPort
  600. fields = ['name', 'type']
  601. class DeviceBayFilter(DeviceComponentFilterSet):
  602. class Meta:
  603. model = DeviceBay
  604. fields = ['name']
  605. class InventoryItemFilter(DeviceComponentFilterSet):
  606. q = django_filters.CharFilter(
  607. method='search',
  608. label='Search',
  609. )
  610. parent_id = django_filters.ModelMultipleChoiceFilter(
  611. queryset=InventoryItem.objects.all(),
  612. label='Parent inventory item (ID)',
  613. )
  614. manufacturer_id = django_filters.ModelMultipleChoiceFilter(
  615. queryset=Manufacturer.objects.all(),
  616. label='Manufacturer (ID)',
  617. )
  618. manufacturer = django_filters.ModelMultipleChoiceFilter(
  619. name='manufacturer__slug',
  620. queryset=Manufacturer.objects.all(),
  621. to_field_name='slug',
  622. label='Manufacturer (slug)',
  623. )
  624. asset_tag = NullableCharFieldFilter()
  625. class Meta:
  626. model = InventoryItem
  627. fields = ['name', 'part_id', 'serial', 'asset_tag', 'discovered']
  628. def search(self, queryset, name, value):
  629. if not value.strip():
  630. return queryset
  631. qs_filter = (
  632. Q(name__icontains=value) |
  633. Q(part_id__icontains=value) |
  634. Q(serial__iexact=value) |
  635. Q(asset_tag__iexact=value) |
  636. Q(description__icontains=value)
  637. )
  638. return queryset.filter(qs_filter)
  639. class VirtualChassisFilter(django_filters.FilterSet):
  640. q = django_filters.CharFilter(
  641. method='search',
  642. label='Search',
  643. )
  644. site_id = django_filters.ModelMultipleChoiceFilter(
  645. name='master__site',
  646. queryset=Site.objects.all(),
  647. label='Site (ID)',
  648. )
  649. site = django_filters.ModelMultipleChoiceFilter(
  650. name='master__site__slug',
  651. queryset=Site.objects.all(),
  652. to_field_name='slug',
  653. label='Site name (slug)',
  654. )
  655. tenant_id = django_filters.ModelMultipleChoiceFilter(
  656. name='master__tenant',
  657. queryset=Tenant.objects.all(),
  658. label='Tenant (ID)',
  659. )
  660. tenant = django_filters.ModelMultipleChoiceFilter(
  661. name='master__tenant__slug',
  662. queryset=Tenant.objects.all(),
  663. to_field_name='slug',
  664. label='Tenant (slug)',
  665. )
  666. tag = django_filters.CharFilter(
  667. name='tags__slug',
  668. )
  669. class Meta:
  670. model = VirtualChassis
  671. fields = ['domain']
  672. def search(self, queryset, name, value):
  673. if not value.strip():
  674. return queryset
  675. qs_filter = (
  676. Q(master__name__icontains=value) |
  677. Q(domain__icontains=value)
  678. )
  679. return queryset.filter(qs_filter)
  680. class CableFilter(django_filters.FilterSet):
  681. q = django_filters.CharFilter(
  682. method='search',
  683. label='Search',
  684. )
  685. class Meta:
  686. model = Cable
  687. fields = ['type', 'status', 'color', 'length', 'length_unit']
  688. def search(self, queryset, name, value):
  689. if not value.strip():
  690. return queryset
  691. return queryset.filter(label__icontains=value)
  692. class ConsoleConnectionFilter(django_filters.FilterSet):
  693. site = django_filters.CharFilter(
  694. method='filter_site',
  695. label='Site (slug)',
  696. )
  697. device = django_filters.CharFilter(
  698. method='filter_device',
  699. label='Device',
  700. )
  701. class Meta:
  702. model = ConsolePort
  703. fields = ['name', 'connection_status']
  704. def filter_site(self, queryset, name, value):
  705. if not value.strip():
  706. return queryset
  707. return queryset.filter(connected_endpoint__device__site__slug=value)
  708. def filter_device(self, queryset, name, value):
  709. if not value.strip():
  710. return queryset
  711. return queryset.filter(
  712. Q(device__name__icontains=value) |
  713. Q(connected_endpoint__device__name__icontains=value)
  714. )
  715. class PowerConnectionFilter(django_filters.FilterSet):
  716. site = django_filters.CharFilter(
  717. method='filter_site',
  718. label='Site (slug)',
  719. )
  720. device = django_filters.CharFilter(
  721. method='filter_device',
  722. label='Device',
  723. )
  724. class Meta:
  725. model = PowerPort
  726. fields = ['name', 'connection_status']
  727. def filter_site(self, queryset, name, value):
  728. if not value.strip():
  729. return queryset
  730. return queryset.filter(connected_endpoint__device__site__slug=value)
  731. def filter_device(self, queryset, name, value):
  732. if not value.strip():
  733. return queryset
  734. return queryset.filter(
  735. Q(device__name__icontains=value) |
  736. Q(connected_endpoint__device__name__icontains=value)
  737. )
  738. class InterfaceConnectionFilter(django_filters.FilterSet):
  739. site = django_filters.CharFilter(
  740. method='filter_site',
  741. label='Site (slug)',
  742. )
  743. device = django_filters.CharFilter(
  744. method='filter_device',
  745. label='Device',
  746. )
  747. class Meta:
  748. model = Interface
  749. fields = ['connection_status']
  750. def filter_site(self, queryset, name, value):
  751. if not value.strip():
  752. return queryset
  753. return queryset.filter(
  754. Q(device__site__slug=value) |
  755. Q(connected_endpoint__device__site__slug=value)
  756. )
  757. def filter_device(self, queryset, name, value):
  758. if not value.strip():
  759. return queryset
  760. return queryset.filter(
  761. Q(device__name__icontains=value) |
  762. Q(connected_endpoint__device__name__icontains=value)
  763. )