filters.py 14 KB

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