filters.py 13 KB

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