filtersets.py 52 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704
  1. import django_filters
  2. from django.contrib.auth.models import User
  3. from extras.filtersets import LocalConfigContextFilterSet
  4. from ipam.models import ASN, VRF
  5. from netbox.filtersets import (
  6. BaseFilterSet, ChangeLoggedModelFilterSet, OrganizationalModelFilterSet, NetBoxModelFilterSet,
  7. )
  8. from tenancy.filtersets import TenancyFilterSet, ContactModelFilterSet
  9. from tenancy.models import *
  10. from utilities.choices import ColorChoices
  11. from utilities.filters import (
  12. ContentTypeFilter, MultiValueCharFilter, MultiValueMACAddressFilter, MultiValueNumberFilter, MultiValueWWNFilter,
  13. TreeNodeMultipleChoiceFilter,
  14. )
  15. from virtualization.models import Cluster
  16. from wireless.choices import WirelessRoleChoices, WirelessChannelChoices
  17. from .choices import *
  18. from .constants import *
  19. from .models import *
  20. __all__ = (
  21. 'CableFilterSet',
  22. 'CableTerminationFilterSet',
  23. 'ConsoleConnectionFilterSet',
  24. 'ConsolePortFilterSet',
  25. 'ConsolePortTemplateFilterSet',
  26. 'ConsoleServerPortFilterSet',
  27. 'ConsoleServerPortTemplateFilterSet',
  28. 'DeviceBayFilterSet',
  29. 'DeviceBayTemplateFilterSet',
  30. 'DeviceFilterSet',
  31. 'DeviceRoleFilterSet',
  32. 'DeviceTypeFilterSet',
  33. 'FrontPortFilterSet',
  34. 'FrontPortTemplateFilterSet',
  35. 'InterfaceConnectionFilterSet',
  36. 'InterfaceFilterSet',
  37. 'InterfaceTemplateFilterSet',
  38. 'InventoryItemFilterSet',
  39. 'InventoryItemRoleFilterSet',
  40. 'InventoryItemTemplateFilterSet',
  41. 'LocationFilterSet',
  42. 'ManufacturerFilterSet',
  43. 'ModuleBayFilterSet',
  44. 'ModuleBayTemplateFilterSet',
  45. 'ModuleFilterSet',
  46. 'ModuleTypeFilterSet',
  47. 'PathEndpointFilterSet',
  48. 'PlatformFilterSet',
  49. 'PowerConnectionFilterSet',
  50. 'PowerFeedFilterSet',
  51. 'PowerOutletFilterSet',
  52. 'PowerOutletTemplateFilterSet',
  53. 'PowerPanelFilterSet',
  54. 'PowerPortFilterSet',
  55. 'PowerPortTemplateFilterSet',
  56. 'RackFilterSet',
  57. 'RackReservationFilterSet',
  58. 'RackRoleFilterSet',
  59. 'RearPortFilterSet',
  60. 'RearPortTemplateFilterSet',
  61. 'RegionFilterSet',
  62. 'SiteFilterSet',
  63. 'SiteGroupFilterSet',
  64. 'VirtualChassisFilterSet',
  65. )
  66. class RegionFilterSet(OrganizationalModelFilterSet, ContactModelFilterSet):
  67. parent_id = django_filters.ModelMultipleChoiceFilter(
  68. queryset=Region.objects.all(),
  69. label='Parent region (ID)',
  70. )
  71. parent = django_filters.ModelMultipleChoiceFilter(
  72. field_name='parent__slug',
  73. queryset=Region.objects.all(),
  74. to_field_name='slug',
  75. label='Parent region (slug)',
  76. )
  77. class Meta:
  78. model = Region
  79. fields = ['id', 'name', 'slug', 'description']
  80. class SiteGroupFilterSet(OrganizationalModelFilterSet, ContactModelFilterSet):
  81. parent_id = django_filters.ModelMultipleChoiceFilter(
  82. queryset=SiteGroup.objects.all(),
  83. label='Parent site group (ID)',
  84. )
  85. parent = django_filters.ModelMultipleChoiceFilter(
  86. field_name='parent__slug',
  87. queryset=SiteGroup.objects.all(),
  88. to_field_name='slug',
  89. label='Parent site group (slug)',
  90. )
  91. class Meta:
  92. model = SiteGroup
  93. fields = ['id', 'name', 'slug', 'description']
  94. class SiteFilterSet(NetBoxModelFilterSet, TenancyFilterSet, ContactModelFilterSet):
  95. status = django_filters.MultipleChoiceFilter(
  96. choices=SiteStatusChoices,
  97. null_value=None
  98. )
  99. region_id = TreeNodeMultipleChoiceFilter(
  100. queryset=Region.objects.all(),
  101. field_name='region',
  102. lookup_expr='in',
  103. label='Region (ID)',
  104. )
  105. region = TreeNodeMultipleChoiceFilter(
  106. queryset=Region.objects.all(),
  107. lookup_expr='in',
  108. to_field_name='slug',
  109. label='Region (slug)',
  110. )
  111. group_id = TreeNodeMultipleChoiceFilter(
  112. queryset=SiteGroup.objects.all(),
  113. field_name='group',
  114. lookup_expr='in',
  115. label='Group (ID)',
  116. )
  117. group = TreeNodeMultipleChoiceFilter(
  118. queryset=SiteGroup.objects.all(),
  119. lookup_expr='in',
  120. to_field_name='slug',
  121. label='Group (slug)',
  122. )
  123. asn = django_filters.ModelMultipleChoiceFilter(
  124. field_name='asns__asn',
  125. queryset=ASN.objects.all(),
  126. to_field_name='asn',
  127. label='AS (ID)',
  128. )
  129. asn_id = django_filters.ModelMultipleChoiceFilter(
  130. field_name='asns',
  131. queryset=ASN.objects.all(),
  132. label='AS (ID)',
  133. )
  134. class Meta:
  135. model = Site
  136. fields = (
  137. 'id', 'name', 'slug', 'facility', 'latitude', 'longitude', 'description'
  138. )
  139. def search(self, queryset, name, value):
  140. if not value.strip():
  141. return queryset
  142. qs_filter = (
  143. Q(name__icontains=value) |
  144. Q(facility__icontains=value) |
  145. Q(description__icontains=value) |
  146. Q(physical_address__icontains=value) |
  147. Q(shipping_address__icontains=value) |
  148. Q(comments__icontains=value)
  149. )
  150. try:
  151. qs_filter |= Q(asns__asn=int(value.strip()))
  152. except ValueError:
  153. pass
  154. return queryset.filter(qs_filter)
  155. class LocationFilterSet(TenancyFilterSet, ContactModelFilterSet, OrganizationalModelFilterSet):
  156. region_id = TreeNodeMultipleChoiceFilter(
  157. queryset=Region.objects.all(),
  158. field_name='site__region',
  159. lookup_expr='in',
  160. label='Region (ID)',
  161. )
  162. region = TreeNodeMultipleChoiceFilter(
  163. queryset=Region.objects.all(),
  164. field_name='site__region',
  165. lookup_expr='in',
  166. to_field_name='slug',
  167. label='Region (slug)',
  168. )
  169. site_group_id = TreeNodeMultipleChoiceFilter(
  170. queryset=SiteGroup.objects.all(),
  171. field_name='site__group',
  172. lookup_expr='in',
  173. label='Site group (ID)',
  174. )
  175. site_group = TreeNodeMultipleChoiceFilter(
  176. queryset=SiteGroup.objects.all(),
  177. field_name='site__group',
  178. lookup_expr='in',
  179. to_field_name='slug',
  180. label='Site group (slug)',
  181. )
  182. site_id = django_filters.ModelMultipleChoiceFilter(
  183. queryset=Site.objects.all(),
  184. label='Site (ID)',
  185. )
  186. site = django_filters.ModelMultipleChoiceFilter(
  187. field_name='site__slug',
  188. queryset=Site.objects.all(),
  189. to_field_name='slug',
  190. label='Site (slug)',
  191. )
  192. parent_id = TreeNodeMultipleChoiceFilter(
  193. queryset=Location.objects.all(),
  194. field_name='parent',
  195. lookup_expr='in',
  196. label='Location (ID)',
  197. )
  198. parent = TreeNodeMultipleChoiceFilter(
  199. queryset=Location.objects.all(),
  200. field_name='parent',
  201. lookup_expr='in',
  202. to_field_name='slug',
  203. label='Location (slug)',
  204. )
  205. class Meta:
  206. model = Location
  207. fields = ['id', 'name', 'slug', 'description']
  208. def search(self, queryset, name, value):
  209. if not value.strip():
  210. return queryset
  211. return queryset.filter(
  212. Q(name__icontains=value) |
  213. Q(description__icontains=value)
  214. )
  215. class RackRoleFilterSet(OrganizationalModelFilterSet):
  216. class Meta:
  217. model = RackRole
  218. fields = ['id', 'name', 'slug', 'color', 'description']
  219. class RackFilterSet(NetBoxModelFilterSet, TenancyFilterSet, ContactModelFilterSet):
  220. region_id = TreeNodeMultipleChoiceFilter(
  221. queryset=Region.objects.all(),
  222. field_name='site__region',
  223. lookup_expr='in',
  224. label='Region (ID)',
  225. )
  226. region = TreeNodeMultipleChoiceFilter(
  227. queryset=Region.objects.all(),
  228. field_name='site__region',
  229. lookup_expr='in',
  230. to_field_name='slug',
  231. label='Region (slug)',
  232. )
  233. site_group_id = TreeNodeMultipleChoiceFilter(
  234. queryset=SiteGroup.objects.all(),
  235. field_name='site__group',
  236. lookup_expr='in',
  237. label='Site group (ID)',
  238. )
  239. site_group = TreeNodeMultipleChoiceFilter(
  240. queryset=SiteGroup.objects.all(),
  241. field_name='site__group',
  242. lookup_expr='in',
  243. to_field_name='slug',
  244. label='Site group (slug)',
  245. )
  246. site_id = django_filters.ModelMultipleChoiceFilter(
  247. queryset=Site.objects.all(),
  248. label='Site (ID)',
  249. )
  250. site = django_filters.ModelMultipleChoiceFilter(
  251. field_name='site__slug',
  252. queryset=Site.objects.all(),
  253. to_field_name='slug',
  254. label='Site (slug)',
  255. )
  256. location_id = TreeNodeMultipleChoiceFilter(
  257. queryset=Location.objects.all(),
  258. field_name='location',
  259. lookup_expr='in',
  260. label='Location (ID)',
  261. )
  262. location = TreeNodeMultipleChoiceFilter(
  263. queryset=Location.objects.all(),
  264. field_name='location',
  265. lookup_expr='in',
  266. to_field_name='slug',
  267. label='Location (slug)',
  268. )
  269. status = django_filters.MultipleChoiceFilter(
  270. choices=RackStatusChoices,
  271. null_value=None
  272. )
  273. type = django_filters.MultipleChoiceFilter(
  274. choices=RackTypeChoices
  275. )
  276. width = django_filters.MultipleChoiceFilter(
  277. choices=RackWidthChoices
  278. )
  279. role_id = django_filters.ModelMultipleChoiceFilter(
  280. queryset=RackRole.objects.all(),
  281. label='Role (ID)',
  282. )
  283. role = django_filters.ModelMultipleChoiceFilter(
  284. field_name='role__slug',
  285. queryset=RackRole.objects.all(),
  286. to_field_name='slug',
  287. label='Role (slug)',
  288. )
  289. serial = django_filters.CharFilter(
  290. lookup_expr='iexact'
  291. )
  292. class Meta:
  293. model = Rack
  294. fields = [
  295. 'id', 'name', 'facility_id', 'asset_tag', 'u_height', 'desc_units', 'outer_width', 'outer_depth',
  296. 'outer_unit',
  297. ]
  298. def search(self, queryset, name, value):
  299. if not value.strip():
  300. return queryset
  301. return queryset.filter(
  302. Q(name__icontains=value) |
  303. Q(facility_id__icontains=value) |
  304. Q(serial__icontains=value.strip()) |
  305. Q(asset_tag__icontains=value.strip()) |
  306. Q(comments__icontains=value)
  307. )
  308. class RackReservationFilterSet(NetBoxModelFilterSet, TenancyFilterSet):
  309. rack_id = django_filters.ModelMultipleChoiceFilter(
  310. queryset=Rack.objects.all(),
  311. label='Rack (ID)',
  312. )
  313. site_id = django_filters.ModelMultipleChoiceFilter(
  314. field_name='rack__site',
  315. queryset=Site.objects.all(),
  316. label='Site (ID)',
  317. )
  318. site = django_filters.ModelMultipleChoiceFilter(
  319. field_name='rack__site__slug',
  320. queryset=Site.objects.all(),
  321. to_field_name='slug',
  322. label='Site (slug)',
  323. )
  324. location_id = TreeNodeMultipleChoiceFilter(
  325. queryset=Location.objects.all(),
  326. field_name='rack__location',
  327. lookup_expr='in',
  328. label='Location (ID)',
  329. )
  330. location = TreeNodeMultipleChoiceFilter(
  331. queryset=Location.objects.all(),
  332. field_name='rack__location',
  333. lookup_expr='in',
  334. to_field_name='slug',
  335. label='Location (slug)',
  336. )
  337. user_id = django_filters.ModelMultipleChoiceFilter(
  338. queryset=User.objects.all(),
  339. label='User (ID)',
  340. )
  341. user = django_filters.ModelMultipleChoiceFilter(
  342. field_name='user__username',
  343. queryset=User.objects.all(),
  344. to_field_name='username',
  345. label='User (name)',
  346. )
  347. class Meta:
  348. model = RackReservation
  349. fields = ['id', 'created', 'description']
  350. def search(self, queryset, name, value):
  351. if not value.strip():
  352. return queryset
  353. return queryset.filter(
  354. Q(rack__name__icontains=value) |
  355. Q(rack__facility_id__icontains=value) |
  356. Q(user__username__icontains=value) |
  357. Q(description__icontains=value)
  358. )
  359. class ManufacturerFilterSet(OrganizationalModelFilterSet, ContactModelFilterSet):
  360. class Meta:
  361. model = Manufacturer
  362. fields = ['id', 'name', 'slug', 'description']
  363. class DeviceTypeFilterSet(NetBoxModelFilterSet):
  364. manufacturer_id = django_filters.ModelMultipleChoiceFilter(
  365. queryset=Manufacturer.objects.all(),
  366. label='Manufacturer (ID)',
  367. )
  368. manufacturer = django_filters.ModelMultipleChoiceFilter(
  369. field_name='manufacturer__slug',
  370. queryset=Manufacturer.objects.all(),
  371. to_field_name='slug',
  372. label='Manufacturer (slug)',
  373. )
  374. console_ports = django_filters.BooleanFilter(
  375. method='_console_ports',
  376. label='Has console ports',
  377. )
  378. console_server_ports = django_filters.BooleanFilter(
  379. method='_console_server_ports',
  380. label='Has console server ports',
  381. )
  382. power_ports = django_filters.BooleanFilter(
  383. method='_power_ports',
  384. label='Has power ports',
  385. )
  386. power_outlets = django_filters.BooleanFilter(
  387. method='_power_outlets',
  388. label='Has power outlets',
  389. )
  390. interfaces = django_filters.BooleanFilter(
  391. method='_interfaces',
  392. label='Has interfaces',
  393. )
  394. pass_through_ports = django_filters.BooleanFilter(
  395. method='_pass_through_ports',
  396. label='Has pass-through ports',
  397. )
  398. module_bays = django_filters.BooleanFilter(
  399. method='_module_bays',
  400. label='Has module bays',
  401. )
  402. device_bays = django_filters.BooleanFilter(
  403. method='_device_bays',
  404. label='Has device bays',
  405. )
  406. class Meta:
  407. model = DeviceType
  408. fields = [
  409. 'id', 'model', 'slug', 'part_number', 'u_height', 'is_full_depth', 'subdevice_role', 'airflow',
  410. ]
  411. def search(self, queryset, name, value):
  412. if not value.strip():
  413. return queryset
  414. return queryset.filter(
  415. Q(manufacturer__name__icontains=value) |
  416. Q(model__icontains=value) |
  417. Q(part_number__icontains=value) |
  418. Q(comments__icontains=value)
  419. )
  420. def _console_ports(self, queryset, name, value):
  421. return queryset.exclude(consoleporttemplates__isnull=value)
  422. def _console_server_ports(self, queryset, name, value):
  423. return queryset.exclude(consoleserverporttemplates__isnull=value)
  424. def _power_ports(self, queryset, name, value):
  425. return queryset.exclude(powerporttemplates__isnull=value)
  426. def _power_outlets(self, queryset, name, value):
  427. return queryset.exclude(poweroutlettemplates__isnull=value)
  428. def _interfaces(self, queryset, name, value):
  429. return queryset.exclude(interfacetemplates__isnull=value)
  430. def _pass_through_ports(self, queryset, name, value):
  431. return queryset.exclude(
  432. frontporttemplates__isnull=value,
  433. rearporttemplates__isnull=value
  434. )
  435. def _module_bays(self, queryset, name, value):
  436. return queryset.exclude(modulebaytemplates__isnull=value)
  437. def _device_bays(self, queryset, name, value):
  438. return queryset.exclude(devicebaytemplates__isnull=value)
  439. class ModuleTypeFilterSet(NetBoxModelFilterSet):
  440. manufacturer_id = django_filters.ModelMultipleChoiceFilter(
  441. queryset=Manufacturer.objects.all(),
  442. label='Manufacturer (ID)',
  443. )
  444. manufacturer = django_filters.ModelMultipleChoiceFilter(
  445. field_name='manufacturer__slug',
  446. queryset=Manufacturer.objects.all(),
  447. to_field_name='slug',
  448. label='Manufacturer (slug)',
  449. )
  450. console_ports = django_filters.BooleanFilter(
  451. method='_console_ports',
  452. label='Has console ports',
  453. )
  454. console_server_ports = django_filters.BooleanFilter(
  455. method='_console_server_ports',
  456. label='Has console server ports',
  457. )
  458. power_ports = django_filters.BooleanFilter(
  459. method='_power_ports',
  460. label='Has power ports',
  461. )
  462. power_outlets = django_filters.BooleanFilter(
  463. method='_power_outlets',
  464. label='Has power outlets',
  465. )
  466. interfaces = django_filters.BooleanFilter(
  467. method='_interfaces',
  468. label='Has interfaces',
  469. )
  470. pass_through_ports = django_filters.BooleanFilter(
  471. method='_pass_through_ports',
  472. label='Has pass-through ports',
  473. )
  474. class Meta:
  475. model = ModuleType
  476. fields = ['id', 'model', 'part_number']
  477. def search(self, queryset, name, value):
  478. if not value.strip():
  479. return queryset
  480. return queryset.filter(
  481. Q(manufacturer__name__icontains=value) |
  482. Q(model__icontains=value) |
  483. Q(part_number__icontains=value) |
  484. Q(comments__icontains=value)
  485. )
  486. def _console_ports(self, queryset, name, value):
  487. return queryset.exclude(consoleporttemplates__isnull=value)
  488. def _console_server_ports(self, queryset, name, value):
  489. return queryset.exclude(consoleserverporttemplates__isnull=value)
  490. def _power_ports(self, queryset, name, value):
  491. return queryset.exclude(powerporttemplates__isnull=value)
  492. def _power_outlets(self, queryset, name, value):
  493. return queryset.exclude(poweroutlettemplates__isnull=value)
  494. def _interfaces(self, queryset, name, value):
  495. return queryset.exclude(interfacetemplates__isnull=value)
  496. def _pass_through_ports(self, queryset, name, value):
  497. return queryset.exclude(
  498. frontporttemplates__isnull=value,
  499. rearporttemplates__isnull=value
  500. )
  501. class DeviceTypeComponentFilterSet(django_filters.FilterSet):
  502. q = django_filters.CharFilter(
  503. method='search',
  504. label='Search',
  505. )
  506. devicetype_id = django_filters.ModelMultipleChoiceFilter(
  507. queryset=DeviceType.objects.all(),
  508. field_name='device_type_id',
  509. label='Device type (ID)',
  510. )
  511. def search(self, queryset, name, value):
  512. if not value.strip():
  513. return queryset
  514. return queryset.filter(name__icontains=value)
  515. class ModularDeviceTypeComponentFilterSet(DeviceTypeComponentFilterSet):
  516. moduletype_id = django_filters.ModelMultipleChoiceFilter(
  517. queryset=ModuleType.objects.all(),
  518. field_name='module_type_id',
  519. label='Module type (ID)',
  520. )
  521. class ConsolePortTemplateFilterSet(ChangeLoggedModelFilterSet, ModularDeviceTypeComponentFilterSet):
  522. class Meta:
  523. model = ConsolePortTemplate
  524. fields = ['id', 'name', 'type']
  525. class ConsoleServerPortTemplateFilterSet(ChangeLoggedModelFilterSet, ModularDeviceTypeComponentFilterSet):
  526. class Meta:
  527. model = ConsoleServerPortTemplate
  528. fields = ['id', 'name', 'type']
  529. class PowerPortTemplateFilterSet(ChangeLoggedModelFilterSet, ModularDeviceTypeComponentFilterSet):
  530. class Meta:
  531. model = PowerPortTemplate
  532. fields = ['id', 'name', 'type', 'maximum_draw', 'allocated_draw']
  533. class PowerOutletTemplateFilterSet(ChangeLoggedModelFilterSet, ModularDeviceTypeComponentFilterSet):
  534. feed_leg = django_filters.MultipleChoiceFilter(
  535. choices=PowerOutletFeedLegChoices,
  536. null_value=None
  537. )
  538. class Meta:
  539. model = PowerOutletTemplate
  540. fields = ['id', 'name', 'type', 'feed_leg']
  541. class InterfaceTemplateFilterSet(ChangeLoggedModelFilterSet, ModularDeviceTypeComponentFilterSet):
  542. type = django_filters.MultipleChoiceFilter(
  543. choices=InterfaceTypeChoices,
  544. null_value=None
  545. )
  546. class Meta:
  547. model = InterfaceTemplate
  548. fields = ['id', 'name', 'type', 'mgmt_only']
  549. class FrontPortTemplateFilterSet(ChangeLoggedModelFilterSet, ModularDeviceTypeComponentFilterSet):
  550. type = django_filters.MultipleChoiceFilter(
  551. choices=PortTypeChoices,
  552. null_value=None
  553. )
  554. class Meta:
  555. model = FrontPortTemplate
  556. fields = ['id', 'name', 'type', 'color']
  557. class RearPortTemplateFilterSet(ChangeLoggedModelFilterSet, ModularDeviceTypeComponentFilterSet):
  558. type = django_filters.MultipleChoiceFilter(
  559. choices=PortTypeChoices,
  560. null_value=None
  561. )
  562. class Meta:
  563. model = RearPortTemplate
  564. fields = ['id', 'name', 'type', 'color', 'positions']
  565. class ModuleBayTemplateFilterSet(ChangeLoggedModelFilterSet, DeviceTypeComponentFilterSet):
  566. class Meta:
  567. model = ModuleBayTemplate
  568. fields = ['id', 'name']
  569. class DeviceBayTemplateFilterSet(ChangeLoggedModelFilterSet, DeviceTypeComponentFilterSet):
  570. class Meta:
  571. model = DeviceBayTemplate
  572. fields = ['id', 'name']
  573. class InventoryItemTemplateFilterSet(ChangeLoggedModelFilterSet, DeviceTypeComponentFilterSet):
  574. parent_id = django_filters.ModelMultipleChoiceFilter(
  575. queryset=InventoryItemTemplate.objects.all(),
  576. label='Parent inventory item (ID)',
  577. )
  578. manufacturer_id = django_filters.ModelMultipleChoiceFilter(
  579. queryset=Manufacturer.objects.all(),
  580. label='Manufacturer (ID)',
  581. )
  582. manufacturer = django_filters.ModelMultipleChoiceFilter(
  583. field_name='manufacturer__slug',
  584. queryset=Manufacturer.objects.all(),
  585. to_field_name='slug',
  586. label='Manufacturer (slug)',
  587. )
  588. role_id = django_filters.ModelMultipleChoiceFilter(
  589. queryset=InventoryItemRole.objects.all(),
  590. label='Role (ID)',
  591. )
  592. role = django_filters.ModelMultipleChoiceFilter(
  593. field_name='role__slug',
  594. queryset=InventoryItemRole.objects.all(),
  595. to_field_name='slug',
  596. label='Role (slug)',
  597. )
  598. component_type = ContentTypeFilter()
  599. component_id = MultiValueNumberFilter()
  600. class Meta:
  601. model = InventoryItemTemplate
  602. fields = ['id', 'name', 'label', 'part_id']
  603. def search(self, queryset, name, value):
  604. if not value.strip():
  605. return queryset
  606. qs_filter = (
  607. Q(name__icontains=value) |
  608. Q(part_id__icontains=value) |
  609. Q(description__icontains=value)
  610. )
  611. return queryset.filter(qs_filter)
  612. class DeviceRoleFilterSet(OrganizationalModelFilterSet):
  613. class Meta:
  614. model = DeviceRole
  615. fields = ['id', 'name', 'slug', 'color', 'vm_role', 'description']
  616. class PlatformFilterSet(OrganizationalModelFilterSet):
  617. manufacturer_id = django_filters.ModelMultipleChoiceFilter(
  618. field_name='manufacturer',
  619. queryset=Manufacturer.objects.all(),
  620. label='Manufacturer (ID)',
  621. )
  622. manufacturer = django_filters.ModelMultipleChoiceFilter(
  623. field_name='manufacturer__slug',
  624. queryset=Manufacturer.objects.all(),
  625. to_field_name='slug',
  626. label='Manufacturer (slug)',
  627. )
  628. class Meta:
  629. model = Platform
  630. fields = ['id', 'name', 'slug', 'napalm_driver', 'description']
  631. class DeviceFilterSet(NetBoxModelFilterSet, TenancyFilterSet, ContactModelFilterSet, LocalConfigContextFilterSet):
  632. manufacturer_id = django_filters.ModelMultipleChoiceFilter(
  633. field_name='device_type__manufacturer',
  634. queryset=Manufacturer.objects.all(),
  635. label='Manufacturer (ID)',
  636. )
  637. manufacturer = django_filters.ModelMultipleChoiceFilter(
  638. field_name='device_type__manufacturer__slug',
  639. queryset=Manufacturer.objects.all(),
  640. to_field_name='slug',
  641. label='Manufacturer (slug)',
  642. )
  643. device_type_id = django_filters.ModelMultipleChoiceFilter(
  644. queryset=DeviceType.objects.all(),
  645. label='Device type (ID)',
  646. )
  647. role_id = django_filters.ModelMultipleChoiceFilter(
  648. field_name='device_role_id',
  649. queryset=DeviceRole.objects.all(),
  650. label='Role (ID)',
  651. )
  652. role = django_filters.ModelMultipleChoiceFilter(
  653. field_name='device_role__slug',
  654. queryset=DeviceRole.objects.all(),
  655. to_field_name='slug',
  656. label='Role (slug)',
  657. )
  658. parent_device_id = django_filters.ModelMultipleChoiceFilter(
  659. field_name='parent_bay__device',
  660. queryset=Device.objects.all(),
  661. label='Parent Device (ID)',
  662. )
  663. platform_id = django_filters.ModelMultipleChoiceFilter(
  664. queryset=Platform.objects.all(),
  665. label='Platform (ID)',
  666. )
  667. platform = django_filters.ModelMultipleChoiceFilter(
  668. field_name='platform__slug',
  669. queryset=Platform.objects.all(),
  670. to_field_name='slug',
  671. label='Platform (slug)',
  672. )
  673. region_id = TreeNodeMultipleChoiceFilter(
  674. queryset=Region.objects.all(),
  675. field_name='site__region',
  676. lookup_expr='in',
  677. label='Region (ID)',
  678. )
  679. region = TreeNodeMultipleChoiceFilter(
  680. queryset=Region.objects.all(),
  681. field_name='site__region',
  682. lookup_expr='in',
  683. to_field_name='slug',
  684. label='Region (slug)',
  685. )
  686. site_group_id = TreeNodeMultipleChoiceFilter(
  687. queryset=SiteGroup.objects.all(),
  688. field_name='site__group',
  689. lookup_expr='in',
  690. label='Site group (ID)',
  691. )
  692. site_group = TreeNodeMultipleChoiceFilter(
  693. queryset=SiteGroup.objects.all(),
  694. field_name='site__group',
  695. lookup_expr='in',
  696. to_field_name='slug',
  697. label='Site group (slug)',
  698. )
  699. site_id = django_filters.ModelMultipleChoiceFilter(
  700. queryset=Site.objects.all(),
  701. label='Site (ID)',
  702. )
  703. site = django_filters.ModelMultipleChoiceFilter(
  704. field_name='site__slug',
  705. queryset=Site.objects.all(),
  706. to_field_name='slug',
  707. label='Site name (slug)',
  708. )
  709. location_id = TreeNodeMultipleChoiceFilter(
  710. queryset=Location.objects.all(),
  711. field_name='location',
  712. lookup_expr='in',
  713. label='Location (ID)',
  714. )
  715. rack_id = django_filters.ModelMultipleChoiceFilter(
  716. field_name='rack',
  717. queryset=Rack.objects.all(),
  718. label='Rack (ID)',
  719. )
  720. cluster_id = django_filters.ModelMultipleChoiceFilter(
  721. queryset=Cluster.objects.all(),
  722. label='VM cluster (ID)',
  723. )
  724. model = django_filters.ModelMultipleChoiceFilter(
  725. field_name='device_type__slug',
  726. queryset=DeviceType.objects.all(),
  727. to_field_name='slug',
  728. label='Device model (slug)',
  729. )
  730. status = django_filters.MultipleChoiceFilter(
  731. choices=DeviceStatusChoices,
  732. null_value=None
  733. )
  734. is_full_depth = django_filters.BooleanFilter(
  735. field_name='device_type__is_full_depth',
  736. label='Is full depth',
  737. )
  738. mac_address = MultiValueMACAddressFilter(
  739. field_name='interfaces__mac_address',
  740. label='MAC address',
  741. )
  742. serial = MultiValueCharFilter(
  743. lookup_expr='iexact'
  744. )
  745. has_primary_ip = django_filters.BooleanFilter(
  746. method='_has_primary_ip',
  747. label='Has a primary IP',
  748. )
  749. virtual_chassis_id = django_filters.ModelMultipleChoiceFilter(
  750. field_name='virtual_chassis',
  751. queryset=VirtualChassis.objects.all(),
  752. label='Virtual chassis (ID)',
  753. )
  754. virtual_chassis_member = django_filters.BooleanFilter(
  755. method='_virtual_chassis_member',
  756. label='Is a virtual chassis member'
  757. )
  758. console_ports = django_filters.BooleanFilter(
  759. method='_console_ports',
  760. label='Has console ports',
  761. )
  762. console_server_ports = django_filters.BooleanFilter(
  763. method='_console_server_ports',
  764. label='Has console server ports',
  765. )
  766. power_ports = django_filters.BooleanFilter(
  767. method='_power_ports',
  768. label='Has power ports',
  769. )
  770. power_outlets = django_filters.BooleanFilter(
  771. method='_power_outlets',
  772. label='Has power outlets',
  773. )
  774. interfaces = django_filters.BooleanFilter(
  775. method='_interfaces',
  776. label='Has interfaces',
  777. )
  778. pass_through_ports = django_filters.BooleanFilter(
  779. method='_pass_through_ports',
  780. label='Has pass-through ports',
  781. )
  782. module_bays = django_filters.BooleanFilter(
  783. method='_module_bays',
  784. label='Has module bays',
  785. )
  786. device_bays = django_filters.BooleanFilter(
  787. method='_device_bays',
  788. label='Has device bays',
  789. )
  790. class Meta:
  791. model = Device
  792. fields = ['id', 'name', 'asset_tag', 'face', 'position', 'airflow', 'vc_position', 'vc_priority']
  793. def search(self, queryset, name, value):
  794. if not value.strip():
  795. return queryset
  796. return queryset.filter(
  797. Q(name__icontains=value) |
  798. Q(serial__icontains=value.strip()) |
  799. Q(inventoryitems__serial__icontains=value.strip()) |
  800. Q(asset_tag__icontains=value.strip()) |
  801. Q(comments__icontains=value)
  802. ).distinct()
  803. def _has_primary_ip(self, queryset, name, value):
  804. params = Q(primary_ip4__isnull=False) | Q(primary_ip6__isnull=False)
  805. if value:
  806. return queryset.filter(params)
  807. return queryset.exclude(params)
  808. def _virtual_chassis_member(self, queryset, name, value):
  809. return queryset.exclude(virtual_chassis__isnull=value)
  810. def _console_ports(self, queryset, name, value):
  811. return queryset.exclude(consoleports__isnull=value)
  812. def _console_server_ports(self, queryset, name, value):
  813. return queryset.exclude(consoleserverports__isnull=value)
  814. def _power_ports(self, queryset, name, value):
  815. return queryset.exclude(powerports__isnull=value)
  816. def _power_outlets(self, queryset, name, value):
  817. return queryset.exclude(poweroutlets__isnull=value)
  818. def _interfaces(self, queryset, name, value):
  819. return queryset.exclude(interfaces__isnull=value)
  820. def _pass_through_ports(self, queryset, name, value):
  821. return queryset.exclude(
  822. frontports__isnull=value,
  823. rearports__isnull=value
  824. )
  825. def _module_bays(self, queryset, name, value):
  826. return queryset.exclude(modulebays__isnull=value)
  827. def _device_bays(self, queryset, name, value):
  828. return queryset.exclude(devicebays__isnull=value)
  829. class ModuleFilterSet(NetBoxModelFilterSet):
  830. manufacturer_id = django_filters.ModelMultipleChoiceFilter(
  831. field_name='module_type__manufacturer',
  832. queryset=Manufacturer.objects.all(),
  833. label='Manufacturer (ID)',
  834. )
  835. manufacturer = django_filters.ModelMultipleChoiceFilter(
  836. field_name='module_type__manufacturer__slug',
  837. queryset=Manufacturer.objects.all(),
  838. to_field_name='slug',
  839. label='Manufacturer (slug)',
  840. )
  841. module_type_id = django_filters.ModelMultipleChoiceFilter(
  842. field_name='module_type',
  843. queryset=ModuleType.objects.all(),
  844. label='Module type (ID)',
  845. )
  846. module_type = django_filters.ModelMultipleChoiceFilter(
  847. field_name='module_type__model',
  848. queryset=ModuleType.objects.all(),
  849. to_field_name='model',
  850. label='Module type (model)',
  851. )
  852. device_id = django_filters.ModelMultipleChoiceFilter(
  853. queryset=Device.objects.all(),
  854. label='Device (ID)',
  855. )
  856. class Meta:
  857. model = Module
  858. fields = ['id', 'serial', 'asset_tag']
  859. def search(self, queryset, name, value):
  860. if not value.strip():
  861. return queryset
  862. return queryset.filter(
  863. Q(serial__icontains=value.strip()) |
  864. Q(asset_tag__icontains=value.strip()) |
  865. Q(comments__icontains=value)
  866. ).distinct()
  867. class DeviceComponentFilterSet(django_filters.FilterSet):
  868. q = django_filters.CharFilter(
  869. method='search',
  870. label='Search',
  871. )
  872. region_id = TreeNodeMultipleChoiceFilter(
  873. queryset=Region.objects.all(),
  874. field_name='device__site__region',
  875. lookup_expr='in',
  876. label='Region (ID)',
  877. )
  878. region = TreeNodeMultipleChoiceFilter(
  879. queryset=Region.objects.all(),
  880. field_name='device__site__region',
  881. lookup_expr='in',
  882. to_field_name='slug',
  883. label='Region (slug)',
  884. )
  885. site_group_id = TreeNodeMultipleChoiceFilter(
  886. queryset=SiteGroup.objects.all(),
  887. field_name='device__site__group',
  888. lookup_expr='in',
  889. label='Site group (ID)',
  890. )
  891. site_group = TreeNodeMultipleChoiceFilter(
  892. queryset=SiteGroup.objects.all(),
  893. field_name='device__site__group',
  894. lookup_expr='in',
  895. to_field_name='slug',
  896. label='Site group (slug)',
  897. )
  898. site_id = django_filters.ModelMultipleChoiceFilter(
  899. field_name='device__site',
  900. queryset=Site.objects.all(),
  901. label='Site (ID)',
  902. )
  903. site = django_filters.ModelMultipleChoiceFilter(
  904. field_name='device__site__slug',
  905. queryset=Site.objects.all(),
  906. to_field_name='slug',
  907. label='Site name (slug)',
  908. )
  909. location_id = django_filters.ModelMultipleChoiceFilter(
  910. field_name='device__location',
  911. queryset=Location.objects.all(),
  912. label='Location (ID)',
  913. )
  914. location = django_filters.ModelMultipleChoiceFilter(
  915. field_name='device__location__slug',
  916. queryset=Location.objects.all(),
  917. to_field_name='slug',
  918. label='Location (slug)',
  919. )
  920. device_id = django_filters.ModelMultipleChoiceFilter(
  921. queryset=Device.objects.all(),
  922. label='Device (ID)',
  923. )
  924. device = django_filters.ModelMultipleChoiceFilter(
  925. field_name='device__name',
  926. queryset=Device.objects.all(),
  927. to_field_name='name',
  928. label='Device (name)',
  929. )
  930. virtual_chassis_id = django_filters.ModelMultipleChoiceFilter(
  931. field_name='device__virtual_chassis',
  932. queryset=VirtualChassis.objects.all(),
  933. label='Virtual Chassis (ID)'
  934. )
  935. virtual_chassis = django_filters.ModelMultipleChoiceFilter(
  936. field_name='device__virtual_chassis__name',
  937. queryset=VirtualChassis.objects.all(),
  938. to_field_name='name',
  939. label='Virtual Chassis',
  940. )
  941. def search(self, queryset, name, value):
  942. if not value.strip():
  943. return queryset
  944. return queryset.filter(
  945. Q(name__icontains=value) |
  946. Q(label__icontains=value) |
  947. Q(description__icontains=value)
  948. )
  949. class ModularDeviceComponentFilterSet(DeviceComponentFilterSet):
  950. """
  951. Extends DeviceComponentFilterSet to add a module_id filter for components
  952. which can be associated with a particular module within a device.
  953. """
  954. module_id = django_filters.ModelMultipleChoiceFilter(
  955. queryset=Module.objects.all(),
  956. label='Module (ID)',
  957. )
  958. class CableTerminationFilterSet(django_filters.FilterSet):
  959. cabled = django_filters.BooleanFilter(
  960. field_name='cable',
  961. lookup_expr='isnull',
  962. exclude=True
  963. )
  964. class PathEndpointFilterSet(django_filters.FilterSet):
  965. connected = django_filters.BooleanFilter(
  966. method='filter_connected'
  967. )
  968. def filter_connected(self, queryset, name, value):
  969. if value:
  970. return queryset.filter(_path__is_active=True)
  971. else:
  972. return queryset.filter(Q(_path__isnull=True) | Q(_path__is_active=False))
  973. class ConsolePortFilterSet(
  974. ModularDeviceComponentFilterSet,
  975. NetBoxModelFilterSet,
  976. CableTerminationFilterSet,
  977. PathEndpointFilterSet
  978. ):
  979. type = django_filters.MultipleChoiceFilter(
  980. choices=ConsolePortTypeChoices,
  981. null_value=None
  982. )
  983. class Meta:
  984. model = ConsolePort
  985. fields = ['id', 'name', 'label', 'description']
  986. class ConsoleServerPortFilterSet(
  987. ModularDeviceComponentFilterSet,
  988. NetBoxModelFilterSet,
  989. CableTerminationFilterSet,
  990. PathEndpointFilterSet
  991. ):
  992. type = django_filters.MultipleChoiceFilter(
  993. choices=ConsolePortTypeChoices,
  994. null_value=None
  995. )
  996. class Meta:
  997. model = ConsoleServerPort
  998. fields = ['id', 'name', 'label', 'description']
  999. class PowerPortFilterSet(
  1000. ModularDeviceComponentFilterSet,
  1001. NetBoxModelFilterSet,
  1002. CableTerminationFilterSet,
  1003. PathEndpointFilterSet
  1004. ):
  1005. type = django_filters.MultipleChoiceFilter(
  1006. choices=PowerPortTypeChoices,
  1007. null_value=None
  1008. )
  1009. class Meta:
  1010. model = PowerPort
  1011. fields = ['id', 'name', 'label', 'maximum_draw', 'allocated_draw', 'description']
  1012. class PowerOutletFilterSet(
  1013. ModularDeviceComponentFilterSet,
  1014. NetBoxModelFilterSet,
  1015. CableTerminationFilterSet,
  1016. PathEndpointFilterSet
  1017. ):
  1018. type = django_filters.MultipleChoiceFilter(
  1019. choices=PowerOutletTypeChoices,
  1020. null_value=None
  1021. )
  1022. feed_leg = django_filters.MultipleChoiceFilter(
  1023. choices=PowerOutletFeedLegChoices,
  1024. null_value=None
  1025. )
  1026. class Meta:
  1027. model = PowerOutlet
  1028. fields = ['id', 'name', 'label', 'feed_leg', 'description']
  1029. class InterfaceFilterSet(
  1030. ModularDeviceComponentFilterSet,
  1031. NetBoxModelFilterSet,
  1032. CableTerminationFilterSet,
  1033. PathEndpointFilterSet
  1034. ):
  1035. # Override device and device_id filters from DeviceComponentFilterSet to match against any peer virtual chassis
  1036. # members
  1037. device = MultiValueCharFilter(
  1038. method='filter_device',
  1039. field_name='name',
  1040. label='Device',
  1041. )
  1042. device_id = MultiValueNumberFilter(
  1043. method='filter_device_id',
  1044. field_name='pk',
  1045. label='Device (ID)',
  1046. )
  1047. kind = django_filters.CharFilter(
  1048. method='filter_kind',
  1049. label='Kind of interface',
  1050. )
  1051. parent_id = django_filters.ModelMultipleChoiceFilter(
  1052. field_name='parent',
  1053. queryset=Interface.objects.all(),
  1054. label='Parent interface (ID)',
  1055. )
  1056. bridge_id = django_filters.ModelMultipleChoiceFilter(
  1057. field_name='bridge',
  1058. queryset=Interface.objects.all(),
  1059. label='Bridged interface (ID)',
  1060. )
  1061. lag_id = django_filters.ModelMultipleChoiceFilter(
  1062. field_name='lag',
  1063. queryset=Interface.objects.all(),
  1064. label='LAG interface (ID)',
  1065. )
  1066. speed = MultiValueNumberFilter()
  1067. duplex = django_filters.MultipleChoiceFilter(
  1068. choices=InterfaceDuplexChoices
  1069. )
  1070. mac_address = MultiValueMACAddressFilter()
  1071. wwn = MultiValueWWNFilter()
  1072. vlan_id = django_filters.CharFilter(
  1073. method='filter_vlan_id',
  1074. label='Assigned VLAN'
  1075. )
  1076. vlan = django_filters.CharFilter(
  1077. method='filter_vlan',
  1078. label='Assigned VID'
  1079. )
  1080. type = django_filters.MultipleChoiceFilter(
  1081. choices=InterfaceTypeChoices,
  1082. null_value=None
  1083. )
  1084. rf_role = django_filters.MultipleChoiceFilter(
  1085. choices=WirelessRoleChoices
  1086. )
  1087. rf_channel = django_filters.MultipleChoiceFilter(
  1088. choices=WirelessChannelChoices
  1089. )
  1090. vrf_id = django_filters.ModelMultipleChoiceFilter(
  1091. field_name='vrf',
  1092. queryset=VRF.objects.all(),
  1093. label='VRF',
  1094. )
  1095. vrf = django_filters.ModelMultipleChoiceFilter(
  1096. field_name='vrf__rd',
  1097. queryset=VRF.objects.all(),
  1098. to_field_name='rd',
  1099. label='VRF (RD)',
  1100. )
  1101. class Meta:
  1102. model = Interface
  1103. fields = [
  1104. 'id', 'name', 'label', 'type', 'enabled', 'mtu', 'mgmt_only', 'mode', 'rf_role', 'rf_channel',
  1105. 'rf_channel_frequency', 'rf_channel_width', 'tx_power', 'description',
  1106. ]
  1107. def filter_device(self, queryset, name, value):
  1108. try:
  1109. devices = Device.objects.filter(**{'{}__in'.format(name): value})
  1110. vc_interface_ids = []
  1111. for device in devices:
  1112. vc_interface_ids.extend(device.vc_interfaces().values_list('id', flat=True))
  1113. return queryset.filter(pk__in=vc_interface_ids)
  1114. except Device.DoesNotExist:
  1115. return queryset.none()
  1116. def filter_device_id(self, queryset, name, id_list):
  1117. # Include interfaces belonging to peer virtual chassis members
  1118. vc_interface_ids = []
  1119. try:
  1120. devices = Device.objects.filter(pk__in=id_list)
  1121. for device in devices:
  1122. vc_interface_ids += device.vc_interfaces().values_list('id', flat=True)
  1123. return queryset.filter(pk__in=vc_interface_ids)
  1124. except Device.DoesNotExist:
  1125. return queryset.none()
  1126. def filter_vlan_id(self, queryset, name, value):
  1127. value = value.strip()
  1128. if not value:
  1129. return queryset
  1130. return queryset.filter(
  1131. Q(untagged_vlan_id=value) |
  1132. Q(tagged_vlans=value)
  1133. )
  1134. def filter_vlan(self, queryset, name, value):
  1135. value = value.strip()
  1136. if not value:
  1137. return queryset
  1138. return queryset.filter(
  1139. Q(untagged_vlan_id__vid=value) |
  1140. Q(tagged_vlans__vid=value)
  1141. )
  1142. def filter_kind(self, queryset, name, value):
  1143. value = value.strip().lower()
  1144. return {
  1145. 'physical': queryset.exclude(type__in=NONCONNECTABLE_IFACE_TYPES),
  1146. 'virtual': queryset.filter(type__in=VIRTUAL_IFACE_TYPES),
  1147. 'wireless': queryset.filter(type__in=WIRELESS_IFACE_TYPES),
  1148. }.get(value, queryset.none())
  1149. class FrontPortFilterSet(
  1150. ModularDeviceComponentFilterSet,
  1151. NetBoxModelFilterSet,
  1152. CableTerminationFilterSet
  1153. ):
  1154. type = django_filters.MultipleChoiceFilter(
  1155. choices=PortTypeChoices,
  1156. null_value=None
  1157. )
  1158. class Meta:
  1159. model = FrontPort
  1160. fields = ['id', 'name', 'label', 'type', 'color', 'description']
  1161. class RearPortFilterSet(
  1162. ModularDeviceComponentFilterSet,
  1163. NetBoxModelFilterSet,
  1164. CableTerminationFilterSet
  1165. ):
  1166. type = django_filters.MultipleChoiceFilter(
  1167. choices=PortTypeChoices,
  1168. null_value=None
  1169. )
  1170. class Meta:
  1171. model = RearPort
  1172. fields = ['id', 'name', 'label', 'type', 'color', 'positions', 'description']
  1173. class ModuleBayFilterSet(DeviceComponentFilterSet, NetBoxModelFilterSet):
  1174. class Meta:
  1175. model = ModuleBay
  1176. fields = ['id', 'name', 'label', 'description']
  1177. class DeviceBayFilterSet(DeviceComponentFilterSet, NetBoxModelFilterSet):
  1178. class Meta:
  1179. model = DeviceBay
  1180. fields = ['id', 'name', 'label', 'description']
  1181. class InventoryItemFilterSet(DeviceComponentFilterSet, NetBoxModelFilterSet):
  1182. parent_id = django_filters.ModelMultipleChoiceFilter(
  1183. queryset=InventoryItem.objects.all(),
  1184. label='Parent inventory item (ID)',
  1185. )
  1186. manufacturer_id = django_filters.ModelMultipleChoiceFilter(
  1187. queryset=Manufacturer.objects.all(),
  1188. label='Manufacturer (ID)',
  1189. )
  1190. manufacturer = django_filters.ModelMultipleChoiceFilter(
  1191. field_name='manufacturer__slug',
  1192. queryset=Manufacturer.objects.all(),
  1193. to_field_name='slug',
  1194. label='Manufacturer (slug)',
  1195. )
  1196. role_id = django_filters.ModelMultipleChoiceFilter(
  1197. queryset=InventoryItemRole.objects.all(),
  1198. label='Role (ID)',
  1199. )
  1200. role = django_filters.ModelMultipleChoiceFilter(
  1201. field_name='role__slug',
  1202. queryset=InventoryItemRole.objects.all(),
  1203. to_field_name='slug',
  1204. label='Role (slug)',
  1205. )
  1206. component_type = ContentTypeFilter()
  1207. component_id = MultiValueNumberFilter()
  1208. serial = django_filters.CharFilter(
  1209. lookup_expr='iexact'
  1210. )
  1211. class Meta:
  1212. model = InventoryItem
  1213. fields = ['id', 'name', 'label', 'part_id', 'asset_tag', 'discovered']
  1214. def search(self, queryset, name, value):
  1215. if not value.strip():
  1216. return queryset
  1217. qs_filter = (
  1218. Q(name__icontains=value) |
  1219. Q(part_id__icontains=value) |
  1220. Q(serial__icontains=value) |
  1221. Q(asset_tag__icontains=value) |
  1222. Q(description__icontains=value)
  1223. )
  1224. return queryset.filter(qs_filter)
  1225. class InventoryItemRoleFilterSet(OrganizationalModelFilterSet):
  1226. class Meta:
  1227. model = InventoryItemRole
  1228. fields = ['id', 'name', 'slug', 'color']
  1229. class VirtualChassisFilterSet(NetBoxModelFilterSet):
  1230. master_id = django_filters.ModelMultipleChoiceFilter(
  1231. queryset=Device.objects.all(),
  1232. label='Master (ID)',
  1233. )
  1234. master = django_filters.ModelMultipleChoiceFilter(
  1235. field_name='master__name',
  1236. queryset=Device.objects.all(),
  1237. to_field_name='name',
  1238. label='Master (name)',
  1239. )
  1240. region_id = TreeNodeMultipleChoiceFilter(
  1241. queryset=Region.objects.all(),
  1242. field_name='master__site__region',
  1243. lookup_expr='in',
  1244. label='Region (ID)',
  1245. )
  1246. region = TreeNodeMultipleChoiceFilter(
  1247. queryset=Region.objects.all(),
  1248. field_name='master__site__region',
  1249. lookup_expr='in',
  1250. to_field_name='slug',
  1251. label='Region (slug)',
  1252. )
  1253. site_group_id = TreeNodeMultipleChoiceFilter(
  1254. queryset=SiteGroup.objects.all(),
  1255. field_name='master__site__group',
  1256. lookup_expr='in',
  1257. label='Site group (ID)',
  1258. )
  1259. site_group = TreeNodeMultipleChoiceFilter(
  1260. queryset=SiteGroup.objects.all(),
  1261. field_name='master__site__group',
  1262. lookup_expr='in',
  1263. to_field_name='slug',
  1264. label='Site group (slug)',
  1265. )
  1266. site_id = django_filters.ModelMultipleChoiceFilter(
  1267. field_name='master__site',
  1268. queryset=Site.objects.all(),
  1269. label='Site (ID)',
  1270. )
  1271. site = django_filters.ModelMultipleChoiceFilter(
  1272. field_name='master__site__slug',
  1273. queryset=Site.objects.all(),
  1274. to_field_name='slug',
  1275. label='Site name (slug)',
  1276. )
  1277. tenant_id = django_filters.ModelMultipleChoiceFilter(
  1278. field_name='master__tenant',
  1279. queryset=Tenant.objects.all(),
  1280. label='Tenant (ID)',
  1281. )
  1282. tenant = django_filters.ModelMultipleChoiceFilter(
  1283. field_name='master__tenant__slug',
  1284. queryset=Tenant.objects.all(),
  1285. to_field_name='slug',
  1286. label='Tenant (slug)',
  1287. )
  1288. class Meta:
  1289. model = VirtualChassis
  1290. fields = ['id', 'domain', 'name']
  1291. def search(self, queryset, name, value):
  1292. if not value.strip():
  1293. return queryset
  1294. qs_filter = (
  1295. Q(name__icontains=value) |
  1296. Q(members__name__icontains=value) |
  1297. Q(domain__icontains=value)
  1298. )
  1299. return queryset.filter(qs_filter).distinct()
  1300. class CableFilterSet(TenancyFilterSet, NetBoxModelFilterSet):
  1301. termination_a_type = ContentTypeFilter()
  1302. termination_a_id = MultiValueNumberFilter()
  1303. termination_b_type = ContentTypeFilter()
  1304. termination_b_id = MultiValueNumberFilter()
  1305. type = django_filters.MultipleChoiceFilter(
  1306. choices=CableTypeChoices
  1307. )
  1308. status = django_filters.MultipleChoiceFilter(
  1309. choices=LinkStatusChoices
  1310. )
  1311. color = django_filters.MultipleChoiceFilter(
  1312. choices=ColorChoices
  1313. )
  1314. device_id = MultiValueNumberFilter(
  1315. method='filter_device'
  1316. )
  1317. device = MultiValueCharFilter(
  1318. method='filter_device',
  1319. field_name='device__name'
  1320. )
  1321. rack_id = MultiValueNumberFilter(
  1322. method='filter_device',
  1323. field_name='device__rack_id'
  1324. )
  1325. rack = MultiValueCharFilter(
  1326. method='filter_device',
  1327. field_name='device__rack__name'
  1328. )
  1329. site_id = MultiValueNumberFilter(
  1330. method='filter_device',
  1331. field_name='device__site_id'
  1332. )
  1333. site = MultiValueCharFilter(
  1334. method='filter_device',
  1335. field_name='device__site__slug'
  1336. )
  1337. class Meta:
  1338. model = Cable
  1339. fields = ['id', 'label', 'length', 'length_unit', 'termination_a_id', 'termination_b_id']
  1340. def search(self, queryset, name, value):
  1341. if not value.strip():
  1342. return queryset
  1343. return queryset.filter(label__icontains=value)
  1344. def filter_device(self, queryset, name, value):
  1345. queryset = queryset.filter(
  1346. Q(**{'_termination_a_{}__in'.format(name): value}) |
  1347. Q(**{'_termination_b_{}__in'.format(name): value})
  1348. )
  1349. return queryset
  1350. class PowerPanelFilterSet(NetBoxModelFilterSet, ContactModelFilterSet):
  1351. region_id = TreeNodeMultipleChoiceFilter(
  1352. queryset=Region.objects.all(),
  1353. field_name='site__region',
  1354. lookup_expr='in',
  1355. label='Region (ID)',
  1356. )
  1357. region = TreeNodeMultipleChoiceFilter(
  1358. queryset=Region.objects.all(),
  1359. field_name='site__region',
  1360. lookup_expr='in',
  1361. to_field_name='slug',
  1362. label='Region (slug)',
  1363. )
  1364. site_group_id = TreeNodeMultipleChoiceFilter(
  1365. queryset=SiteGroup.objects.all(),
  1366. field_name='site__group',
  1367. lookup_expr='in',
  1368. label='Site group (ID)',
  1369. )
  1370. site_group = TreeNodeMultipleChoiceFilter(
  1371. queryset=SiteGroup.objects.all(),
  1372. field_name='site__group',
  1373. lookup_expr='in',
  1374. to_field_name='slug',
  1375. label='Site group (slug)',
  1376. )
  1377. site_id = django_filters.ModelMultipleChoiceFilter(
  1378. queryset=Site.objects.all(),
  1379. label='Site (ID)',
  1380. )
  1381. site = django_filters.ModelMultipleChoiceFilter(
  1382. field_name='site__slug',
  1383. queryset=Site.objects.all(),
  1384. to_field_name='slug',
  1385. label='Site name (slug)',
  1386. )
  1387. location_id = TreeNodeMultipleChoiceFilter(
  1388. queryset=Location.objects.all(),
  1389. field_name='location',
  1390. lookup_expr='in',
  1391. label='Location (ID)',
  1392. )
  1393. class Meta:
  1394. model = PowerPanel
  1395. fields = ['id', 'name']
  1396. def search(self, queryset, name, value):
  1397. if not value.strip():
  1398. return queryset
  1399. qs_filter = (
  1400. Q(name__icontains=value)
  1401. )
  1402. return queryset.filter(qs_filter)
  1403. class PowerFeedFilterSet(NetBoxModelFilterSet, CableTerminationFilterSet, PathEndpointFilterSet):
  1404. region_id = TreeNodeMultipleChoiceFilter(
  1405. queryset=Region.objects.all(),
  1406. field_name='power_panel__site__region',
  1407. lookup_expr='in',
  1408. label='Region (ID)',
  1409. )
  1410. region = TreeNodeMultipleChoiceFilter(
  1411. queryset=Region.objects.all(),
  1412. field_name='power_panel__site__region',
  1413. lookup_expr='in',
  1414. to_field_name='slug',
  1415. label='Region (slug)',
  1416. )
  1417. site_group_id = TreeNodeMultipleChoiceFilter(
  1418. queryset=SiteGroup.objects.all(),
  1419. field_name='power_panel__site__group',
  1420. lookup_expr='in',
  1421. label='Site group (ID)',
  1422. )
  1423. site_group = TreeNodeMultipleChoiceFilter(
  1424. queryset=SiteGroup.objects.all(),
  1425. field_name='power_panel__site__group',
  1426. lookup_expr='in',
  1427. to_field_name='slug',
  1428. label='Site group (slug)',
  1429. )
  1430. site_id = django_filters.ModelMultipleChoiceFilter(
  1431. field_name='power_panel__site',
  1432. queryset=Site.objects.all(),
  1433. label='Site (ID)',
  1434. )
  1435. site = django_filters.ModelMultipleChoiceFilter(
  1436. field_name='power_panel__site__slug',
  1437. queryset=Site.objects.all(),
  1438. to_field_name='slug',
  1439. label='Site name (slug)',
  1440. )
  1441. power_panel_id = django_filters.ModelMultipleChoiceFilter(
  1442. queryset=PowerPanel.objects.all(),
  1443. label='Power panel (ID)',
  1444. )
  1445. rack_id = django_filters.ModelMultipleChoiceFilter(
  1446. field_name='rack',
  1447. queryset=Rack.objects.all(),
  1448. label='Rack (ID)',
  1449. )
  1450. status = django_filters.MultipleChoiceFilter(
  1451. choices=PowerFeedStatusChoices,
  1452. null_value=None
  1453. )
  1454. class Meta:
  1455. model = PowerFeed
  1456. fields = ['id', 'name', 'status', 'type', 'supply', 'phase', 'voltage', 'amperage', 'max_utilization']
  1457. def search(self, queryset, name, value):
  1458. if not value.strip():
  1459. return queryset
  1460. qs_filter = (
  1461. Q(name__icontains=value) |
  1462. Q(comments__icontains=value)
  1463. )
  1464. return queryset.filter(qs_filter)
  1465. #
  1466. # Connection filter sets
  1467. #
  1468. class ConnectionFilterSet(BaseFilterSet):
  1469. q = django_filters.CharFilter(
  1470. method='search',
  1471. label='Search',
  1472. )
  1473. site_id = MultiValueNumberFilter(
  1474. method='filter_connections',
  1475. field_name='device__site_id'
  1476. )
  1477. site = MultiValueCharFilter(
  1478. method='filter_connections',
  1479. field_name='device__site__slug'
  1480. )
  1481. device_id = MultiValueNumberFilter(
  1482. method='filter_connections',
  1483. field_name='device_id'
  1484. )
  1485. device = MultiValueCharFilter(
  1486. method='filter_connections',
  1487. field_name='device__name'
  1488. )
  1489. def filter_connections(self, queryset, name, value):
  1490. if not value:
  1491. return queryset
  1492. return queryset.filter(**{f'{name}__in': value})
  1493. def search(self, queryset, name, value):
  1494. if not value.strip():
  1495. return queryset
  1496. qs_filter = (
  1497. Q(device__name__icontains=value) |
  1498. Q(cable__label__icontains=value)
  1499. )
  1500. return queryset.filter(qs_filter)
  1501. class ConsoleConnectionFilterSet(ConnectionFilterSet):
  1502. class Meta:
  1503. model = ConsolePort
  1504. fields = ['name']
  1505. class PowerConnectionFilterSet(ConnectionFilterSet):
  1506. class Meta:
  1507. model = PowerPort
  1508. fields = ['name']
  1509. class InterfaceConnectionFilterSet(ConnectionFilterSet):
  1510. class Meta:
  1511. model = Interface
  1512. fields = []