filters.py 13 KB

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