filters.py 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485
  1. import django_filters
  2. from netaddr.core import AddrFormatError
  3. from django.db.models import Q
  4. from extras.filters import CustomFieldFilterSet
  5. from tenancy.models import Tenant
  6. from utilities.filters import NullableModelMultipleChoiceFilter
  7. from .models import (
  8. ConsolePort, ConsoleServerPort, Device, DeviceRole, DeviceType, IFACE_FF_LAG, Interface, InterfaceConnection,
  9. Manufacturer, Platform, PowerOutlet, PowerPort, Rack, RackGroup, RackReservation, RackRole, Region, Site,
  10. VIRTUAL_IFACE_TYPES,
  11. )
  12. class SiteFilter(CustomFieldFilterSet, django_filters.FilterSet):
  13. q = django_filters.CharFilter(
  14. method='search',
  15. label='Search',
  16. )
  17. region_id = NullableModelMultipleChoiceFilter(
  18. name='region',
  19. queryset=Region.objects.all(),
  20. label='Region (ID)',
  21. )
  22. region = NullableModelMultipleChoiceFilter(
  23. name='region',
  24. queryset=Region.objects.all(),
  25. to_field_name='slug',
  26. label='Region (slug)',
  27. )
  28. tenant_id = NullableModelMultipleChoiceFilter(
  29. name='tenant',
  30. queryset=Tenant.objects.all(),
  31. label='Tenant (ID)',
  32. )
  33. tenant = NullableModelMultipleChoiceFilter(
  34. name='tenant',
  35. queryset=Tenant.objects.all(),
  36. to_field_name='slug',
  37. label='Tenant (slug)',
  38. )
  39. class Meta:
  40. model = Site
  41. fields = ['q', 'name', 'facility', 'asn']
  42. def search(self, queryset, name, value):
  43. if not value.strip():
  44. return queryset
  45. qs_filter = (
  46. Q(name__icontains=value) |
  47. Q(facility__icontains=value) |
  48. Q(physical_address__icontains=value) |
  49. Q(shipping_address__icontains=value) |
  50. Q(comments__icontains=value)
  51. )
  52. try:
  53. qs_filter |= Q(asn=int(value.strip()))
  54. except ValueError:
  55. pass
  56. return queryset.filter(qs_filter)
  57. class RackGroupFilter(django_filters.FilterSet):
  58. site_id = django_filters.ModelMultipleChoiceFilter(
  59. name='site',
  60. queryset=Site.objects.all(),
  61. label='Site (ID)',
  62. )
  63. site = django_filters.ModelMultipleChoiceFilter(
  64. name='site__slug',
  65. queryset=Site.objects.all(),
  66. to_field_name='slug',
  67. label='Site (slug)',
  68. )
  69. class Meta:
  70. model = RackGroup
  71. fields = ['name']
  72. class RackFilter(CustomFieldFilterSet, django_filters.FilterSet):
  73. q = django_filters.CharFilter(
  74. method='search',
  75. label='Search',
  76. )
  77. site_id = django_filters.ModelMultipleChoiceFilter(
  78. name='site',
  79. queryset=Site.objects.all(),
  80. label='Site (ID)',
  81. )
  82. site = django_filters.ModelMultipleChoiceFilter(
  83. name='site__slug',
  84. queryset=Site.objects.all(),
  85. to_field_name='slug',
  86. label='Site (slug)',
  87. )
  88. group_id = NullableModelMultipleChoiceFilter(
  89. name='group',
  90. queryset=RackGroup.objects.all(),
  91. label='Group (ID)',
  92. )
  93. group = NullableModelMultipleChoiceFilter(
  94. name='group',
  95. queryset=RackGroup.objects.all(),
  96. to_field_name='slug',
  97. label='Group',
  98. )
  99. tenant_id = NullableModelMultipleChoiceFilter(
  100. name='tenant',
  101. queryset=Tenant.objects.all(),
  102. label='Tenant (ID)',
  103. )
  104. tenant = NullableModelMultipleChoiceFilter(
  105. name='tenant',
  106. queryset=Tenant.objects.all(),
  107. to_field_name='slug',
  108. label='Tenant (slug)',
  109. )
  110. role_id = NullableModelMultipleChoiceFilter(
  111. name='role',
  112. queryset=RackRole.objects.all(),
  113. label='Role (ID)',
  114. )
  115. role = NullableModelMultipleChoiceFilter(
  116. name='role',
  117. queryset=RackRole.objects.all(),
  118. to_field_name='slug',
  119. label='Role (slug)',
  120. )
  121. class Meta:
  122. model = Rack
  123. fields = ['u_height']
  124. def search(self, queryset, name, value):
  125. if not value.strip():
  126. return queryset
  127. return queryset.filter(
  128. Q(name__icontains=value) |
  129. Q(facility_id__icontains=value) |
  130. Q(comments__icontains=value)
  131. )
  132. class RackReservationFilter(django_filters.FilterSet):
  133. rack_id = django_filters.ModelMultipleChoiceFilter(
  134. name='rack',
  135. queryset=Rack.objects.all(),
  136. label='Rack (ID)',
  137. )
  138. class Meta:
  139. model = RackReservation
  140. fields = ['rack', 'user']
  141. class DeviceTypeFilter(CustomFieldFilterSet, django_filters.FilterSet):
  142. q = django_filters.CharFilter(
  143. method='search',
  144. label='Search',
  145. )
  146. manufacturer_id = django_filters.ModelMultipleChoiceFilter(
  147. name='manufacturer',
  148. queryset=Manufacturer.objects.all(),
  149. label='Manufacturer (ID)',
  150. )
  151. manufacturer = django_filters.ModelMultipleChoiceFilter(
  152. name='manufacturer__slug',
  153. queryset=Manufacturer.objects.all(),
  154. to_field_name='slug',
  155. label='Manufacturer (slug)',
  156. )
  157. class Meta:
  158. model = DeviceType
  159. fields = [
  160. 'model', 'part_number', 'u_height', 'is_console_server', 'is_pdu', 'is_network_device', 'subdevice_role',
  161. ]
  162. def search(self, queryset, name, value):
  163. if not value.strip():
  164. return queryset
  165. return queryset.filter(
  166. Q(manufacturer__name__icontains=value) |
  167. Q(model__icontains=value) |
  168. Q(part_number__icontains=value) |
  169. Q(comments__icontains=value)
  170. )
  171. class DeviceFilter(CustomFieldFilterSet, django_filters.FilterSet):
  172. q = django_filters.CharFilter(
  173. method='search',
  174. label='Search',
  175. )
  176. mac_address = django_filters.CharFilter(
  177. method='_mac_address',
  178. label='MAC address',
  179. )
  180. site_id = django_filters.ModelMultipleChoiceFilter(
  181. name='site',
  182. queryset=Site.objects.all(),
  183. label='Site (ID)',
  184. )
  185. site = django_filters.ModelMultipleChoiceFilter(
  186. name='site__slug',
  187. queryset=Site.objects.all(),
  188. to_field_name='slug',
  189. label='Site name (slug)',
  190. )
  191. rack_group_id = django_filters.ModelMultipleChoiceFilter(
  192. name='rack__group',
  193. queryset=RackGroup.objects.all(),
  194. label='Rack group (ID)',
  195. )
  196. rack_id = NullableModelMultipleChoiceFilter(
  197. name='rack',
  198. queryset=Rack.objects.all(),
  199. label='Rack (ID)',
  200. )
  201. role_id = django_filters.ModelMultipleChoiceFilter(
  202. name='device_role',
  203. queryset=DeviceRole.objects.all(),
  204. label='Role (ID)',
  205. )
  206. role = django_filters.ModelMultipleChoiceFilter(
  207. name='device_role__slug',
  208. queryset=DeviceRole.objects.all(),
  209. to_field_name='slug',
  210. label='Role (slug)',
  211. )
  212. tenant_id = NullableModelMultipleChoiceFilter(
  213. name='tenant',
  214. queryset=Tenant.objects.all(),
  215. label='Tenant (ID)',
  216. )
  217. tenant = NullableModelMultipleChoiceFilter(
  218. name='tenant',
  219. queryset=Tenant.objects.all(),
  220. to_field_name='slug',
  221. label='Tenant (slug)',
  222. )
  223. device_type_id = django_filters.ModelMultipleChoiceFilter(
  224. name='device_type',
  225. queryset=DeviceType.objects.all(),
  226. label='Device type (ID)',
  227. )
  228. manufacturer_id = django_filters.ModelMultipleChoiceFilter(
  229. name='device_type__manufacturer',
  230. queryset=Manufacturer.objects.all(),
  231. label='Manufacturer (ID)',
  232. )
  233. manufacturer = django_filters.ModelMultipleChoiceFilter(
  234. name='device_type__manufacturer__slug',
  235. queryset=Manufacturer.objects.all(),
  236. to_field_name='slug',
  237. label='Manufacturer (slug)',
  238. )
  239. model = django_filters.ModelMultipleChoiceFilter(
  240. name='device_type__slug',
  241. queryset=DeviceType.objects.all(),
  242. to_field_name='slug',
  243. label='Device model (slug)',
  244. )
  245. platform_id = NullableModelMultipleChoiceFilter(
  246. name='platform',
  247. queryset=Platform.objects.all(),
  248. label='Platform (ID)',
  249. )
  250. platform = NullableModelMultipleChoiceFilter(
  251. name='platform',
  252. queryset=Platform.objects.all(),
  253. to_field_name='slug',
  254. label='Platform (slug)',
  255. )
  256. status = django_filters.BooleanFilter(
  257. name='status',
  258. label='Status',
  259. )
  260. is_console_server = django_filters.BooleanFilter(
  261. name='device_type__is_console_server',
  262. label='Is a console server',
  263. )
  264. is_pdu = django_filters.BooleanFilter(
  265. name='device_type__is_pdu',
  266. label='Is a PDU',
  267. )
  268. is_network_device = django_filters.BooleanFilter(
  269. name='device_type__is_network_device',
  270. label='Is a network device',
  271. )
  272. class Meta:
  273. model = Device
  274. fields = ['name', 'serial', 'asset_tag']
  275. def search(self, queryset, name, value):
  276. if not value.strip():
  277. return queryset
  278. return queryset.filter(
  279. Q(name__icontains=value) |
  280. Q(serial__icontains=value.strip()) |
  281. Q(modules__serial__icontains=value.strip()) |
  282. Q(asset_tag=value.strip()) |
  283. Q(comments__icontains=value)
  284. ).distinct()
  285. def _mac_address(self, queryset, name, value):
  286. value = value.strip()
  287. if not value:
  288. return queryset
  289. try:
  290. return queryset.filter(interfaces__mac_address=value).distinct()
  291. except AddrFormatError:
  292. return queryset.none()
  293. class ConsolePortFilter(django_filters.FilterSet):
  294. device_id = django_filters.ModelMultipleChoiceFilter(
  295. name='device',
  296. queryset=Device.objects.all(),
  297. label='Device (ID)',
  298. )
  299. device = django_filters.ModelMultipleChoiceFilter(
  300. name='device',
  301. queryset=Device.objects.all(),
  302. to_field_name='name',
  303. label='Device (name)',
  304. )
  305. class Meta:
  306. model = ConsolePort
  307. fields = ['name']
  308. class ConsoleServerPortFilter(django_filters.FilterSet):
  309. device_id = django_filters.ModelMultipleChoiceFilter(
  310. name='device',
  311. queryset=Device.objects.all(),
  312. label='Device (ID)',
  313. )
  314. device = django_filters.ModelMultipleChoiceFilter(
  315. name='device',
  316. queryset=Device.objects.all(),
  317. to_field_name='name',
  318. label='Device (name)',
  319. )
  320. class Meta:
  321. model = ConsoleServerPort
  322. fields = ['name']
  323. class PowerPortFilter(django_filters.FilterSet):
  324. device_id = django_filters.ModelMultipleChoiceFilter(
  325. name='device',
  326. queryset=Device.objects.all(),
  327. label='Device (ID)',
  328. )
  329. device = django_filters.ModelMultipleChoiceFilter(
  330. name='device',
  331. queryset=Device.objects.all(),
  332. to_field_name='name',
  333. label='Device (name)',
  334. )
  335. class Meta:
  336. model = PowerPort
  337. fields = ['name']
  338. class PowerOutletFilter(django_filters.FilterSet):
  339. device_id = django_filters.ModelMultipleChoiceFilter(
  340. name='device',
  341. queryset=Device.objects.all(),
  342. label='Device (ID)',
  343. )
  344. device = django_filters.ModelMultipleChoiceFilter(
  345. name='device',
  346. queryset=Device.objects.all(),
  347. to_field_name='name',
  348. label='Device (name)',
  349. )
  350. class Meta:
  351. model = PowerOutlet
  352. fields = ['name']
  353. class InterfaceFilter(django_filters.FilterSet):
  354. device_id = django_filters.ModelMultipleChoiceFilter(
  355. name='device',
  356. queryset=Device.objects.all(),
  357. label='Device (ID)',
  358. )
  359. device = django_filters.ModelMultipleChoiceFilter(
  360. name='device',
  361. queryset=Device.objects.all(),
  362. to_field_name='name',
  363. label='Device (name)',
  364. )
  365. type = django_filters.CharFilter(
  366. method='filter_type',
  367. label='Interface type',
  368. )
  369. mac_address = django_filters.CharFilter(
  370. method='_mac_address',
  371. label='MAC address',
  372. )
  373. class Meta:
  374. model = Interface
  375. fields = ['name']
  376. def filter_type(self, queryset, name, value):
  377. value = value.strip().lower()
  378. if value == 'physical':
  379. return queryset.exclude(form_factor__in=VIRTUAL_IFACE_TYPES)
  380. elif value == 'virtual':
  381. return queryset.filter(form_factor__in=VIRTUAL_IFACE_TYPES)
  382. elif value == 'lag':
  383. return queryset.filter(form_factor=IFACE_FF_LAG)
  384. return queryset
  385. def _mac_address(self, queryset, name, value):
  386. value = value.strip()
  387. if not value:
  388. return queryset
  389. try:
  390. return queryset.filter(mac_address=value).distinct()
  391. except AddrFormatError:
  392. return queryset.none()
  393. class ConsoleConnectionFilter(django_filters.FilterSet):
  394. site = django_filters.CharFilter(
  395. method='filter_site',
  396. label='Site (slug)',
  397. )
  398. class Meta:
  399. model = ConsoleServerPort
  400. fields = []
  401. def filter_site(self, queryset, name, value):
  402. if not value.strip():
  403. return queryset
  404. return queryset.filter(cs_port__device__site__slug=value)
  405. class PowerConnectionFilter(django_filters.FilterSet):
  406. site = django_filters.CharFilter(
  407. method='filter_site',
  408. label='Site (slug)',
  409. )
  410. class Meta:
  411. model = PowerOutlet
  412. fields = []
  413. def filter_site(self, queryset, name, value):
  414. if not value.strip():
  415. return queryset
  416. return queryset.filter(power_outlet__device__site__slug=value)
  417. class InterfaceConnectionFilter(django_filters.FilterSet):
  418. site = django_filters.CharFilter(
  419. method='filter_site',
  420. label='Site (slug)',
  421. )
  422. class Meta:
  423. model = InterfaceConnection
  424. fields = []
  425. def filter_site(self, queryset, name, value):
  426. if not value.strip():
  427. return queryset
  428. return queryset.filter(
  429. Q(interface_a__device__site__slug=value) |
  430. Q(interface_b__device__site__slug=value)
  431. )