filtersets.py 81 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529
  1. import django_filters
  2. from django.contrib.contenttypes.models import ContentType
  3. from django.utils.translation import gettext as _
  4. from drf_spectacular.types import OpenApiTypes
  5. from drf_spectacular.utils import extend_schema_field
  6. from circuits.models import CircuitTermination, VirtualCircuit, VirtualCircuitTermination
  7. from extras.filtersets import LocalConfigContextFilterSet
  8. from extras.models import ConfigTemplate
  9. from ipam.filtersets import PrimaryIPFilterSet
  10. from ipam.models import ASN, IPAddress, VLANTranslationPolicy, VRF
  11. from netbox.choices import ColorChoices
  12. from netbox.filtersets import (
  13. BaseFilterSet, ChangeLoggedModelFilterSet, OrganizationalModelFilterSet, NetBoxModelFilterSet,
  14. )
  15. from tenancy.filtersets import TenancyFilterSet, ContactModelFilterSet
  16. from tenancy.models import *
  17. from users.models import User
  18. from utilities.filters import (
  19. ContentTypeFilter, MultiValueCharFilter, MultiValueMACAddressFilter, MultiValueNumberFilter, MultiValueWWNFilter,
  20. NumericArrayFilter, TreeNodeMultipleChoiceFilter,
  21. )
  22. from virtualization.models import Cluster, ClusterGroup, VMInterface, VirtualMachine
  23. from vpn.models import L2VPN
  24. from wireless.choices import WirelessRoleChoices, WirelessChannelChoices
  25. from wireless.models import WirelessLAN, WirelessLink
  26. from .choices import *
  27. from .constants import *
  28. from .models import *
  29. __all__ = (
  30. 'CableFilterSet',
  31. 'CabledObjectFilterSet',
  32. 'CableTerminationFilterSet',
  33. 'CommonInterfaceFilterSet',
  34. 'ConsoleConnectionFilterSet',
  35. 'ConsolePortFilterSet',
  36. 'ConsolePortTemplateFilterSet',
  37. 'ConsoleServerPortFilterSet',
  38. 'ConsoleServerPortTemplateFilterSet',
  39. 'DeviceBayFilterSet',
  40. 'DeviceBayTemplateFilterSet',
  41. 'DeviceFilterSet',
  42. 'DeviceRoleFilterSet',
  43. 'DeviceTypeFilterSet',
  44. 'FrontPortFilterSet',
  45. 'FrontPortTemplateFilterSet',
  46. 'InterfaceConnectionFilterSet',
  47. 'InterfaceFilterSet',
  48. 'InterfaceTemplateFilterSet',
  49. 'InventoryItemFilterSet',
  50. 'InventoryItemRoleFilterSet',
  51. 'InventoryItemTemplateFilterSet',
  52. 'LocationFilterSet',
  53. 'MACAddressFilterSet',
  54. 'ManufacturerFilterSet',
  55. 'ModuleBayFilterSet',
  56. 'ModuleBayTemplateFilterSet',
  57. 'ModuleFilterSet',
  58. 'ModuleTypeFilterSet',
  59. 'PathEndpointFilterSet',
  60. 'PlatformFilterSet',
  61. 'PowerConnectionFilterSet',
  62. 'PowerFeedFilterSet',
  63. 'PowerOutletFilterSet',
  64. 'PowerOutletTemplateFilterSet',
  65. 'PowerPanelFilterSet',
  66. 'PowerPortFilterSet',
  67. 'PowerPortTemplateFilterSet',
  68. 'RackFilterSet',
  69. 'RackReservationFilterSet',
  70. 'RackRoleFilterSet',
  71. 'RackTypeFilterSet',
  72. 'RearPortFilterSet',
  73. 'RearPortTemplateFilterSet',
  74. 'RegionFilterSet',
  75. 'SiteFilterSet',
  76. 'SiteGroupFilterSet',
  77. 'VirtualChassisFilterSet',
  78. 'VirtualDeviceContextFilterSet',
  79. )
  80. class RegionFilterSet(OrganizationalModelFilterSet, ContactModelFilterSet):
  81. parent_id = django_filters.ModelMultipleChoiceFilter(
  82. queryset=Region.objects.all(),
  83. label=_('Parent region (ID)'),
  84. )
  85. parent = django_filters.ModelMultipleChoiceFilter(
  86. field_name='parent__slug',
  87. queryset=Region.objects.all(),
  88. to_field_name='slug',
  89. label=_('Parent region (slug)'),
  90. )
  91. ancestor_id = TreeNodeMultipleChoiceFilter(
  92. queryset=Region.objects.all(),
  93. field_name='parent',
  94. lookup_expr='in',
  95. label=_('Region (ID)'),
  96. )
  97. ancestor = TreeNodeMultipleChoiceFilter(
  98. queryset=Region.objects.all(),
  99. field_name='parent',
  100. lookup_expr='in',
  101. to_field_name='slug',
  102. label=_('Region (slug)'),
  103. )
  104. class Meta:
  105. model = Region
  106. fields = ('id', 'name', 'slug', 'description')
  107. class SiteGroupFilterSet(OrganizationalModelFilterSet, ContactModelFilterSet):
  108. parent_id = django_filters.ModelMultipleChoiceFilter(
  109. queryset=SiteGroup.objects.all(),
  110. label=_('Parent site group (ID)'),
  111. )
  112. parent = django_filters.ModelMultipleChoiceFilter(
  113. field_name='parent__slug',
  114. queryset=SiteGroup.objects.all(),
  115. to_field_name='slug',
  116. label=_('Parent site group (slug)'),
  117. )
  118. ancestor_id = TreeNodeMultipleChoiceFilter(
  119. queryset=SiteGroup.objects.all(),
  120. field_name='parent',
  121. lookup_expr='in',
  122. label=_('Site group (ID)'),
  123. )
  124. ancestor = TreeNodeMultipleChoiceFilter(
  125. queryset=SiteGroup.objects.all(),
  126. field_name='parent',
  127. lookup_expr='in',
  128. to_field_name='slug',
  129. label=_('Site group (slug)'),
  130. )
  131. class Meta:
  132. model = SiteGroup
  133. fields = ('id', 'name', 'slug', 'description')
  134. class SiteFilterSet(NetBoxModelFilterSet, TenancyFilterSet, ContactModelFilterSet):
  135. status = django_filters.MultipleChoiceFilter(
  136. choices=SiteStatusChoices,
  137. null_value=None
  138. )
  139. region_id = TreeNodeMultipleChoiceFilter(
  140. queryset=Region.objects.all(),
  141. field_name='region',
  142. lookup_expr='in',
  143. label=_('Region (ID)'),
  144. )
  145. region = TreeNodeMultipleChoiceFilter(
  146. queryset=Region.objects.all(),
  147. lookup_expr='in',
  148. to_field_name='slug',
  149. label=_('Region (slug)'),
  150. )
  151. group_id = TreeNodeMultipleChoiceFilter(
  152. queryset=SiteGroup.objects.all(),
  153. field_name='group',
  154. lookup_expr='in',
  155. label=_('Group (ID)'),
  156. )
  157. group = TreeNodeMultipleChoiceFilter(
  158. queryset=SiteGroup.objects.all(),
  159. lookup_expr='in',
  160. to_field_name='slug',
  161. label=_('Group (slug)'),
  162. )
  163. asn = django_filters.ModelMultipleChoiceFilter(
  164. field_name='asns__asn',
  165. queryset=ASN.objects.all(),
  166. to_field_name='asn',
  167. label=_('AS (ID)'),
  168. )
  169. asn_id = django_filters.ModelMultipleChoiceFilter(
  170. field_name='asns',
  171. queryset=ASN.objects.all(),
  172. label=_('AS (ID)'),
  173. )
  174. time_zone = MultiValueCharFilter()
  175. class Meta:
  176. model = Site
  177. fields = ('id', 'name', 'slug', 'facility', 'latitude', 'longitude', 'description')
  178. def search(self, queryset, name, value):
  179. if not value.strip():
  180. return queryset
  181. qs_filter = (
  182. Q(name__icontains=value) |
  183. Q(facility__icontains=value) |
  184. Q(description__icontains=value) |
  185. Q(physical_address__icontains=value) |
  186. Q(shipping_address__icontains=value) |
  187. Q(comments__icontains=value)
  188. )
  189. try:
  190. qs_filter |= Q(asns__asn=int(value.strip()))
  191. except ValueError:
  192. pass
  193. return queryset.filter(qs_filter).distinct()
  194. class LocationFilterSet(TenancyFilterSet, ContactModelFilterSet, OrganizationalModelFilterSet):
  195. region_id = TreeNodeMultipleChoiceFilter(
  196. queryset=Region.objects.all(),
  197. field_name='site__region',
  198. lookup_expr='in',
  199. label=_('Region (ID)'),
  200. )
  201. region = TreeNodeMultipleChoiceFilter(
  202. queryset=Region.objects.all(),
  203. field_name='site__region',
  204. lookup_expr='in',
  205. to_field_name='slug',
  206. label=_('Region (slug)'),
  207. )
  208. site_group_id = TreeNodeMultipleChoiceFilter(
  209. queryset=SiteGroup.objects.all(),
  210. field_name='site__group',
  211. lookup_expr='in',
  212. label=_('Site group (ID)'),
  213. )
  214. site_group = TreeNodeMultipleChoiceFilter(
  215. queryset=SiteGroup.objects.all(),
  216. field_name='site__group',
  217. lookup_expr='in',
  218. to_field_name='slug',
  219. label=_('Site group (slug)'),
  220. )
  221. site_id = django_filters.ModelMultipleChoiceFilter(
  222. queryset=Site.objects.all(),
  223. label=_('Site (ID)'),
  224. )
  225. site = django_filters.ModelMultipleChoiceFilter(
  226. field_name='site__slug',
  227. queryset=Site.objects.all(),
  228. to_field_name='slug',
  229. label=_('Site (slug)'),
  230. )
  231. parent_id = django_filters.ModelMultipleChoiceFilter(
  232. queryset=Location.objects.all(),
  233. label=_('Parent location (ID)'),
  234. )
  235. parent = django_filters.ModelMultipleChoiceFilter(
  236. field_name='parent__slug',
  237. queryset=Location.objects.all(),
  238. to_field_name='slug',
  239. label=_('Parent location (slug)'),
  240. )
  241. ancestor_id = TreeNodeMultipleChoiceFilter(
  242. queryset=Location.objects.all(),
  243. field_name='parent',
  244. lookup_expr='in',
  245. label=_('Location (ID)'),
  246. )
  247. ancestor = TreeNodeMultipleChoiceFilter(
  248. queryset=Location.objects.all(),
  249. field_name='parent',
  250. lookup_expr='in',
  251. to_field_name='slug',
  252. label=_('Location (slug)'),
  253. )
  254. status = django_filters.MultipleChoiceFilter(
  255. choices=LocationStatusChoices,
  256. null_value=None
  257. )
  258. class Meta:
  259. model = Location
  260. fields = ('id', 'name', 'slug', 'facility', 'description')
  261. def search(self, queryset, name, value):
  262. if not value.strip():
  263. return queryset
  264. return queryset.filter(
  265. Q(name__icontains=value) |
  266. Q(facility__icontains=value) |
  267. Q(description__icontains=value)
  268. )
  269. class RackRoleFilterSet(OrganizationalModelFilterSet):
  270. class Meta:
  271. model = RackRole
  272. fields = ('id', 'name', 'slug', 'color', 'description')
  273. class RackTypeFilterSet(NetBoxModelFilterSet):
  274. manufacturer_id = django_filters.ModelMultipleChoiceFilter(
  275. queryset=Manufacturer.objects.all(),
  276. label=_('Manufacturer (ID)'),
  277. )
  278. manufacturer = django_filters.ModelMultipleChoiceFilter(
  279. field_name='manufacturer__slug',
  280. queryset=Manufacturer.objects.all(),
  281. to_field_name='slug',
  282. label=_('Manufacturer (slug)'),
  283. )
  284. form_factor = django_filters.MultipleChoiceFilter(
  285. choices=RackFormFactorChoices
  286. )
  287. width = django_filters.MultipleChoiceFilter(
  288. choices=RackWidthChoices
  289. )
  290. class Meta:
  291. model = RackType
  292. fields = (
  293. 'id', 'model', 'slug', 'u_height', 'starting_unit', 'desc_units', 'outer_width', 'outer_depth',
  294. 'outer_unit', 'mounting_depth', 'weight', 'max_weight', 'weight_unit', 'description',
  295. )
  296. def search(self, queryset, name, value):
  297. if not value.strip():
  298. return queryset
  299. return queryset.filter(
  300. Q(model__icontains=value) |
  301. Q(description__icontains=value) |
  302. Q(comments__icontains=value)
  303. )
  304. class RackFilterSet(NetBoxModelFilterSet, TenancyFilterSet, ContactModelFilterSet):
  305. region_id = TreeNodeMultipleChoiceFilter(
  306. queryset=Region.objects.all(),
  307. field_name='site__region',
  308. lookup_expr='in',
  309. label=_('Region (ID)'),
  310. )
  311. region = TreeNodeMultipleChoiceFilter(
  312. queryset=Region.objects.all(),
  313. field_name='site__region',
  314. lookup_expr='in',
  315. to_field_name='slug',
  316. label=_('Region (slug)'),
  317. )
  318. site_group_id = TreeNodeMultipleChoiceFilter(
  319. queryset=SiteGroup.objects.all(),
  320. field_name='site__group',
  321. lookup_expr='in',
  322. label=_('Site group (ID)'),
  323. )
  324. site_group = TreeNodeMultipleChoiceFilter(
  325. queryset=SiteGroup.objects.all(),
  326. field_name='site__group',
  327. lookup_expr='in',
  328. to_field_name='slug',
  329. label=_('Site group (slug)'),
  330. )
  331. site_id = django_filters.ModelMultipleChoiceFilter(
  332. queryset=Site.objects.all(),
  333. label=_('Site (ID)'),
  334. )
  335. site = django_filters.ModelMultipleChoiceFilter(
  336. field_name='site__slug',
  337. queryset=Site.objects.all(),
  338. to_field_name='slug',
  339. label=_('Site (slug)'),
  340. )
  341. location_id = TreeNodeMultipleChoiceFilter(
  342. queryset=Location.objects.all(),
  343. field_name='location',
  344. lookup_expr='in',
  345. label=_('Location (ID)'),
  346. )
  347. location = TreeNodeMultipleChoiceFilter(
  348. queryset=Location.objects.all(),
  349. field_name='location',
  350. lookup_expr='in',
  351. to_field_name='slug',
  352. label=_('Location (slug)'),
  353. )
  354. manufacturer_id = django_filters.ModelMultipleChoiceFilter(
  355. field_name='rack_type__manufacturer',
  356. queryset=Manufacturer.objects.all(),
  357. label=_('Manufacturer (ID)'),
  358. )
  359. manufacturer = django_filters.ModelMultipleChoiceFilter(
  360. field_name='rack_type__manufacturer__slug',
  361. queryset=Manufacturer.objects.all(),
  362. to_field_name='slug',
  363. label=_('Manufacturer (slug)'),
  364. )
  365. rack_type = django_filters.ModelMultipleChoiceFilter(
  366. field_name='rack_type__slug',
  367. queryset=RackType.objects.all(),
  368. to_field_name='slug',
  369. label=_('Rack type (slug)'),
  370. )
  371. rack_type_id = django_filters.ModelMultipleChoiceFilter(
  372. queryset=RackType.objects.all(),
  373. label=_('Rack type (ID)'),
  374. )
  375. status = django_filters.MultipleChoiceFilter(
  376. choices=RackStatusChoices,
  377. null_value=None
  378. )
  379. form_factor = django_filters.MultipleChoiceFilter(
  380. choices=RackFormFactorChoices
  381. )
  382. width = django_filters.MultipleChoiceFilter(
  383. choices=RackWidthChoices
  384. )
  385. role_id = django_filters.ModelMultipleChoiceFilter(
  386. queryset=RackRole.objects.all(),
  387. label=_('Role (ID)'),
  388. )
  389. role = django_filters.ModelMultipleChoiceFilter(
  390. field_name='role__slug',
  391. queryset=RackRole.objects.all(),
  392. to_field_name='slug',
  393. label=_('Role (slug)'),
  394. )
  395. serial = MultiValueCharFilter(
  396. lookup_expr='iexact'
  397. )
  398. class Meta:
  399. model = Rack
  400. fields = (
  401. 'id', 'name', 'facility_id', 'asset_tag', 'u_height', 'starting_unit', 'desc_units', 'outer_width',
  402. 'outer_depth', 'outer_unit', 'mounting_depth', 'airflow', 'weight', 'max_weight', 'weight_unit',
  403. 'description',
  404. )
  405. def search(self, queryset, name, value):
  406. if not value.strip():
  407. return queryset
  408. return queryset.filter(
  409. Q(name__icontains=value) |
  410. Q(facility_id__icontains=value) |
  411. Q(serial__icontains=value.strip()) |
  412. Q(asset_tag__icontains=value.strip()) |
  413. Q(description__icontains=value) |
  414. Q(comments__icontains=value)
  415. )
  416. class RackReservationFilterSet(NetBoxModelFilterSet, TenancyFilterSet):
  417. rack_id = django_filters.ModelMultipleChoiceFilter(
  418. queryset=Rack.objects.all(),
  419. label=_('Rack (ID)'),
  420. )
  421. site_id = django_filters.ModelMultipleChoiceFilter(
  422. field_name='rack__site',
  423. queryset=Site.objects.all(),
  424. label=_('Site (ID)'),
  425. )
  426. site = django_filters.ModelMultipleChoiceFilter(
  427. field_name='rack__site__slug',
  428. queryset=Site.objects.all(),
  429. to_field_name='slug',
  430. label=_('Site (slug)'),
  431. )
  432. region_id = TreeNodeMultipleChoiceFilter(
  433. queryset=Region.objects.all(),
  434. field_name='rack__site__region',
  435. lookup_expr='in',
  436. label=_('Region (ID)'),
  437. )
  438. region = TreeNodeMultipleChoiceFilter(
  439. queryset=Region.objects.all(),
  440. field_name='rack__site__region',
  441. lookup_expr='in',
  442. to_field_name='slug',
  443. label=_('Region (slug)'),
  444. )
  445. site_group_id = TreeNodeMultipleChoiceFilter(
  446. queryset=SiteGroup.objects.all(),
  447. field_name='rack__site__group',
  448. lookup_expr='in',
  449. label=_('Site group (ID)'),
  450. )
  451. site_group = TreeNodeMultipleChoiceFilter(
  452. queryset=SiteGroup.objects.all(),
  453. field_name='rack__site__group',
  454. lookup_expr='in',
  455. to_field_name='slug',
  456. label=_('Site group (slug)'),
  457. )
  458. location_id = TreeNodeMultipleChoiceFilter(
  459. queryset=Location.objects.all(),
  460. field_name='rack__location',
  461. lookup_expr='in',
  462. label=_('Location (ID)'),
  463. )
  464. location = TreeNodeMultipleChoiceFilter(
  465. queryset=Location.objects.all(),
  466. field_name='rack__location',
  467. lookup_expr='in',
  468. to_field_name='slug',
  469. label=_('Location (slug)'),
  470. )
  471. user_id = django_filters.ModelMultipleChoiceFilter(
  472. queryset=User.objects.all(),
  473. label=_('User (ID)'),
  474. )
  475. user = django_filters.ModelMultipleChoiceFilter(
  476. field_name='user__username',
  477. queryset=User.objects.all(),
  478. to_field_name='username',
  479. label=_('User (name)'),
  480. )
  481. unit = NumericArrayFilter(
  482. field_name='units',
  483. lookup_expr='contains'
  484. )
  485. class Meta:
  486. model = RackReservation
  487. fields = ('id', 'created', 'description')
  488. def search(self, queryset, name, value):
  489. if not value.strip():
  490. return queryset
  491. return queryset.filter(
  492. Q(rack__name__icontains=value) |
  493. Q(rack__facility_id__icontains=value) |
  494. Q(user__username__icontains=value) |
  495. Q(description__icontains=value)
  496. )
  497. class ManufacturerFilterSet(OrganizationalModelFilterSet, ContactModelFilterSet):
  498. class Meta:
  499. model = Manufacturer
  500. fields = ('id', 'name', 'slug', 'description')
  501. class DeviceTypeFilterSet(NetBoxModelFilterSet):
  502. manufacturer_id = django_filters.ModelMultipleChoiceFilter(
  503. queryset=Manufacturer.objects.all(),
  504. label=_('Manufacturer (ID)'),
  505. )
  506. manufacturer = django_filters.ModelMultipleChoiceFilter(
  507. field_name='manufacturer__slug',
  508. queryset=Manufacturer.objects.all(),
  509. to_field_name='slug',
  510. label=_('Manufacturer (slug)'),
  511. )
  512. default_platform_id = django_filters.ModelMultipleChoiceFilter(
  513. queryset=Platform.objects.all(),
  514. label=_('Default platform (ID)'),
  515. )
  516. default_platform = django_filters.ModelMultipleChoiceFilter(
  517. field_name='default_platform__slug',
  518. queryset=Platform.objects.all(),
  519. to_field_name='slug',
  520. label=_('Default platform (slug)'),
  521. )
  522. has_front_image = django_filters.BooleanFilter(
  523. label=_('Has a front image'),
  524. method='_has_front_image'
  525. )
  526. has_rear_image = django_filters.BooleanFilter(
  527. label=_('Has a rear image'),
  528. method='_has_rear_image'
  529. )
  530. console_ports = django_filters.BooleanFilter(
  531. method='_console_ports',
  532. label=_('Has console ports'),
  533. )
  534. console_server_ports = django_filters.BooleanFilter(
  535. method='_console_server_ports',
  536. label=_('Has console server ports'),
  537. )
  538. power_ports = django_filters.BooleanFilter(
  539. method='_power_ports',
  540. label=_('Has power ports'),
  541. )
  542. power_outlets = django_filters.BooleanFilter(
  543. method='_power_outlets',
  544. label=_('Has power outlets'),
  545. )
  546. interfaces = django_filters.BooleanFilter(
  547. method='_interfaces',
  548. label=_('Has interfaces'),
  549. )
  550. pass_through_ports = django_filters.BooleanFilter(
  551. method='_pass_through_ports',
  552. label=_('Has pass-through ports'),
  553. )
  554. module_bays = django_filters.BooleanFilter(
  555. method='_module_bays',
  556. label=_('Has module bays'),
  557. )
  558. device_bays = django_filters.BooleanFilter(
  559. method='_device_bays',
  560. label=_('Has device bays'),
  561. )
  562. inventory_items = django_filters.BooleanFilter(
  563. method='_inventory_items',
  564. label=_('Has inventory items'),
  565. )
  566. class Meta:
  567. model = DeviceType
  568. fields = (
  569. 'id', 'model', 'slug', 'part_number', 'u_height', 'exclude_from_utilization', 'is_full_depth',
  570. 'subdevice_role', 'airflow', 'weight', 'weight_unit', 'description',
  571. # Counters
  572. 'console_port_template_count',
  573. 'console_server_port_template_count',
  574. 'power_port_template_count',
  575. 'power_outlet_template_count',
  576. 'interface_template_count',
  577. 'front_port_template_count',
  578. 'rear_port_template_count',
  579. 'device_bay_template_count',
  580. 'module_bay_template_count',
  581. 'inventory_item_template_count',
  582. )
  583. def search(self, queryset, name, value):
  584. if not value.strip():
  585. return queryset
  586. return queryset.filter(
  587. Q(manufacturer__name__icontains=value) |
  588. Q(model__icontains=value) |
  589. Q(part_number__icontains=value) |
  590. Q(description__icontains=value) |
  591. Q(comments__icontains=value)
  592. )
  593. def _has_front_image(self, queryset, name, value):
  594. if value:
  595. return queryset.exclude(front_image='')
  596. else:
  597. return queryset.filter(front_image='')
  598. def _has_rear_image(self, queryset, name, value):
  599. if value:
  600. return queryset.exclude(rear_image='')
  601. else:
  602. return queryset.filter(rear_image='')
  603. def _console_ports(self, queryset, name, value):
  604. return queryset.exclude(consoleporttemplates__isnull=value)
  605. def _console_server_ports(self, queryset, name, value):
  606. return queryset.exclude(consoleserverporttemplates__isnull=value)
  607. def _power_ports(self, queryset, name, value):
  608. return queryset.exclude(powerporttemplates__isnull=value)
  609. def _power_outlets(self, queryset, name, value):
  610. return queryset.exclude(poweroutlettemplates__isnull=value)
  611. def _interfaces(self, queryset, name, value):
  612. return queryset.exclude(interfacetemplates__isnull=value)
  613. def _pass_through_ports(self, queryset, name, value):
  614. return queryset.exclude(
  615. frontporttemplates__isnull=value,
  616. rearporttemplates__isnull=value
  617. )
  618. def _module_bays(self, queryset, name, value):
  619. return queryset.exclude(modulebaytemplates__isnull=value)
  620. def _device_bays(self, queryset, name, value):
  621. return queryset.exclude(devicebaytemplates__isnull=value)
  622. def _inventory_items(self, queryset, name, value):
  623. return queryset.exclude(inventoryitemtemplates__isnull=value)
  624. class ModuleTypeFilterSet(NetBoxModelFilterSet):
  625. manufacturer_id = django_filters.ModelMultipleChoiceFilter(
  626. queryset=Manufacturer.objects.all(),
  627. label=_('Manufacturer (ID)'),
  628. )
  629. manufacturer = django_filters.ModelMultipleChoiceFilter(
  630. field_name='manufacturer__slug',
  631. queryset=Manufacturer.objects.all(),
  632. to_field_name='slug',
  633. label=_('Manufacturer (slug)'),
  634. )
  635. console_ports = django_filters.BooleanFilter(
  636. method='_console_ports',
  637. label=_('Has console ports'),
  638. )
  639. console_server_ports = django_filters.BooleanFilter(
  640. method='_console_server_ports',
  641. label=_('Has console server ports'),
  642. )
  643. power_ports = django_filters.BooleanFilter(
  644. method='_power_ports',
  645. label=_('Has power ports'),
  646. )
  647. power_outlets = django_filters.BooleanFilter(
  648. method='_power_outlets',
  649. label=_('Has power outlets'),
  650. )
  651. interfaces = django_filters.BooleanFilter(
  652. method='_interfaces',
  653. label=_('Has interfaces'),
  654. )
  655. pass_through_ports = django_filters.BooleanFilter(
  656. method='_pass_through_ports',
  657. label=_('Has pass-through ports'),
  658. )
  659. class Meta:
  660. model = ModuleType
  661. fields = ('id', 'model', 'part_number', 'airflow', 'weight', 'weight_unit', 'description')
  662. def search(self, queryset, name, value):
  663. if not value.strip():
  664. return queryset
  665. return queryset.filter(
  666. Q(manufacturer__name__icontains=value) |
  667. Q(model__icontains=value) |
  668. Q(part_number__icontains=value) |
  669. Q(description__icontains=value) |
  670. Q(comments__icontains=value)
  671. )
  672. def _console_ports(self, queryset, name, value):
  673. return queryset.exclude(consoleporttemplates__isnull=value)
  674. def _console_server_ports(self, queryset, name, value):
  675. return queryset.exclude(consoleserverporttemplates__isnull=value)
  676. def _power_ports(self, queryset, name, value):
  677. return queryset.exclude(powerporttemplates__isnull=value)
  678. def _power_outlets(self, queryset, name, value):
  679. return queryset.exclude(poweroutlettemplates__isnull=value)
  680. def _interfaces(self, queryset, name, value):
  681. return queryset.exclude(interfacetemplates__isnull=value)
  682. def _pass_through_ports(self, queryset, name, value):
  683. return queryset.exclude(
  684. frontporttemplates__isnull=value,
  685. rearporttemplates__isnull=value
  686. )
  687. class DeviceTypeComponentFilterSet(django_filters.FilterSet):
  688. q = django_filters.CharFilter(
  689. method='search',
  690. label=_('Search'),
  691. )
  692. device_type_id = django_filters.ModelMultipleChoiceFilter(
  693. queryset=DeviceType.objects.all(),
  694. field_name='device_type_id',
  695. label=_('Device type (ID)'),
  696. )
  697. def search(self, queryset, name, value):
  698. if not value.strip():
  699. return queryset
  700. return queryset.filter(
  701. Q(name__icontains=value) |
  702. Q(description__icontains=value)
  703. )
  704. class ModularDeviceTypeComponentFilterSet(DeviceTypeComponentFilterSet):
  705. module_type_id = django_filters.ModelMultipleChoiceFilter(
  706. queryset=ModuleType.objects.all(),
  707. field_name='module_type_id',
  708. label=_('Module type (ID)'),
  709. )
  710. class ConsolePortTemplateFilterSet(ChangeLoggedModelFilterSet, ModularDeviceTypeComponentFilterSet):
  711. class Meta:
  712. model = ConsolePortTemplate
  713. fields = ('id', 'name', 'label', 'type', 'description')
  714. class ConsoleServerPortTemplateFilterSet(ChangeLoggedModelFilterSet, ModularDeviceTypeComponentFilterSet):
  715. class Meta:
  716. model = ConsoleServerPortTemplate
  717. fields = ('id', 'name', 'label', 'type', 'description')
  718. class PowerPortTemplateFilterSet(ChangeLoggedModelFilterSet, ModularDeviceTypeComponentFilterSet):
  719. class Meta:
  720. model = PowerPortTemplate
  721. fields = ('id', 'name', 'label', 'type', 'maximum_draw', 'allocated_draw', 'description')
  722. class PowerOutletTemplateFilterSet(ChangeLoggedModelFilterSet, ModularDeviceTypeComponentFilterSet):
  723. feed_leg = django_filters.MultipleChoiceFilter(
  724. choices=PowerOutletFeedLegChoices,
  725. null_value=None
  726. )
  727. power_port_id = django_filters.ModelMultipleChoiceFilter(
  728. queryset=PowerPortTemplate.objects.all(),
  729. label=_('Power port (ID)'),
  730. )
  731. class Meta:
  732. model = PowerOutletTemplate
  733. fields = ('id', 'name', 'label', 'type', 'feed_leg', 'description')
  734. class InterfaceTemplateFilterSet(ChangeLoggedModelFilterSet, ModularDeviceTypeComponentFilterSet):
  735. type = django_filters.MultipleChoiceFilter(
  736. choices=InterfaceTypeChoices,
  737. null_value=None
  738. )
  739. bridge_id = django_filters.ModelMultipleChoiceFilter(
  740. field_name='bridge',
  741. queryset=InterfaceTemplate.objects.all()
  742. )
  743. poe_mode = django_filters.MultipleChoiceFilter(
  744. choices=InterfacePoEModeChoices
  745. )
  746. poe_type = django_filters.MultipleChoiceFilter(
  747. choices=InterfacePoETypeChoices
  748. )
  749. rf_role = django_filters.MultipleChoiceFilter(
  750. choices=WirelessRoleChoices
  751. )
  752. class Meta:
  753. model = InterfaceTemplate
  754. fields = ('id', 'name', 'label', 'type', 'enabled', 'mgmt_only', 'description')
  755. class FrontPortTemplateFilterSet(ChangeLoggedModelFilterSet, ModularDeviceTypeComponentFilterSet):
  756. type = django_filters.MultipleChoiceFilter(
  757. choices=PortTypeChoices,
  758. null_value=None
  759. )
  760. rear_port_id = django_filters.ModelMultipleChoiceFilter(
  761. queryset=RearPort.objects.all()
  762. )
  763. class Meta:
  764. model = FrontPortTemplate
  765. fields = ('id', 'name', 'label', 'type', 'color', 'rear_port_position', 'description')
  766. class RearPortTemplateFilterSet(ChangeLoggedModelFilterSet, ModularDeviceTypeComponentFilterSet):
  767. type = django_filters.MultipleChoiceFilter(
  768. choices=PortTypeChoices,
  769. null_value=None
  770. )
  771. class Meta:
  772. model = RearPortTemplate
  773. fields = ('id', 'name', 'label', 'type', 'color', 'positions', 'description')
  774. class ModuleBayTemplateFilterSet(ChangeLoggedModelFilterSet, ModularDeviceTypeComponentFilterSet):
  775. class Meta:
  776. model = ModuleBayTemplate
  777. fields = ('id', 'name', 'label', 'position', 'description')
  778. class DeviceBayTemplateFilterSet(ChangeLoggedModelFilterSet, DeviceTypeComponentFilterSet):
  779. class Meta:
  780. model = DeviceBayTemplate
  781. fields = ('id', 'name', 'label', 'description')
  782. class InventoryItemTemplateFilterSet(ChangeLoggedModelFilterSet, DeviceTypeComponentFilterSet):
  783. parent_id = django_filters.ModelMultipleChoiceFilter(
  784. queryset=InventoryItemTemplate.objects.all(),
  785. label=_('Parent inventory item (ID)'),
  786. )
  787. manufacturer_id = django_filters.ModelMultipleChoiceFilter(
  788. queryset=Manufacturer.objects.all(),
  789. label=_('Manufacturer (ID)'),
  790. )
  791. manufacturer = django_filters.ModelMultipleChoiceFilter(
  792. field_name='manufacturer__slug',
  793. queryset=Manufacturer.objects.all(),
  794. to_field_name='slug',
  795. label=_('Manufacturer (slug)'),
  796. )
  797. role_id = django_filters.ModelMultipleChoiceFilter(
  798. queryset=InventoryItemRole.objects.all(),
  799. label=_('Role (ID)'),
  800. )
  801. role = django_filters.ModelMultipleChoiceFilter(
  802. field_name='role__slug',
  803. queryset=InventoryItemRole.objects.all(),
  804. to_field_name='slug',
  805. label=_('Role (slug)'),
  806. )
  807. component_type = ContentTypeFilter()
  808. component_id = MultiValueNumberFilter()
  809. class Meta:
  810. model = InventoryItemTemplate
  811. fields = ('id', 'name', 'label', 'part_id', 'description')
  812. def search(self, queryset, name, value):
  813. if not value.strip():
  814. return queryset
  815. qs_filter = (
  816. Q(name__icontains=value) |
  817. Q(part_id__icontains=value) |
  818. Q(description__icontains=value)
  819. )
  820. return queryset.filter(qs_filter)
  821. class DeviceRoleFilterSet(OrganizationalModelFilterSet):
  822. config_template_id = django_filters.ModelMultipleChoiceFilter(
  823. queryset=ConfigTemplate.objects.all(),
  824. label=_('Config template (ID)'),
  825. )
  826. class Meta:
  827. model = DeviceRole
  828. fields = ('id', 'name', 'slug', 'color', 'vm_role', 'description')
  829. class PlatformFilterSet(OrganizationalModelFilterSet):
  830. manufacturer_id = django_filters.ModelMultipleChoiceFilter(
  831. field_name='manufacturer',
  832. queryset=Manufacturer.objects.all(),
  833. label=_('Manufacturer (ID)'),
  834. )
  835. manufacturer = django_filters.ModelMultipleChoiceFilter(
  836. field_name='manufacturer__slug',
  837. queryset=Manufacturer.objects.all(),
  838. to_field_name='slug',
  839. label=_('Manufacturer (slug)'),
  840. )
  841. available_for_device_type = django_filters.ModelChoiceFilter(
  842. queryset=DeviceType.objects.all(),
  843. method='get_for_device_type'
  844. )
  845. config_template_id = django_filters.ModelMultipleChoiceFilter(
  846. queryset=ConfigTemplate.objects.all(),
  847. label=_('Config template (ID)'),
  848. )
  849. class Meta:
  850. model = Platform
  851. fields = ('id', 'name', 'slug', 'description')
  852. @extend_schema_field(OpenApiTypes.STR)
  853. def get_for_device_type(self, queryset, name, value):
  854. """
  855. Return all Platforms available for a specific manufacturer based on device type and Platforms not assigned any
  856. manufacturer
  857. """
  858. return queryset.filter(Q(manufacturer=None) | Q(manufacturer__device_types=value))
  859. class DeviceFilterSet(
  860. NetBoxModelFilterSet,
  861. TenancyFilterSet,
  862. ContactModelFilterSet,
  863. LocalConfigContextFilterSet,
  864. PrimaryIPFilterSet,
  865. ):
  866. manufacturer_id = django_filters.ModelMultipleChoiceFilter(
  867. field_name='device_type__manufacturer',
  868. queryset=Manufacturer.objects.all(),
  869. label=_('Manufacturer (ID)'),
  870. )
  871. manufacturer = django_filters.ModelMultipleChoiceFilter(
  872. field_name='device_type__manufacturer__slug',
  873. queryset=Manufacturer.objects.all(),
  874. to_field_name='slug',
  875. label=_('Manufacturer (slug)'),
  876. )
  877. device_type = django_filters.ModelMultipleChoiceFilter(
  878. field_name='device_type__slug',
  879. queryset=DeviceType.objects.all(),
  880. to_field_name='slug',
  881. label=_('Device type (slug)'),
  882. )
  883. device_type_id = django_filters.ModelMultipleChoiceFilter(
  884. queryset=DeviceType.objects.all(),
  885. label=_('Device type (ID)'),
  886. )
  887. role_id = django_filters.ModelMultipleChoiceFilter(
  888. field_name='role_id',
  889. queryset=DeviceRole.objects.all(),
  890. label=_('Role (ID)'),
  891. )
  892. role = django_filters.ModelMultipleChoiceFilter(
  893. field_name='role__slug',
  894. queryset=DeviceRole.objects.all(),
  895. to_field_name='slug',
  896. label=_('Role (slug)'),
  897. )
  898. parent_device_id = django_filters.ModelMultipleChoiceFilter(
  899. field_name='parent_bay__device',
  900. queryset=Device.objects.all(),
  901. label=_('Parent Device (ID)'),
  902. )
  903. platform_id = django_filters.ModelMultipleChoiceFilter(
  904. queryset=Platform.objects.all(),
  905. label=_('Platform (ID)'),
  906. )
  907. platform = django_filters.ModelMultipleChoiceFilter(
  908. field_name='platform__slug',
  909. queryset=Platform.objects.all(),
  910. to_field_name='slug',
  911. label=_('Platform (slug)'),
  912. )
  913. region_id = TreeNodeMultipleChoiceFilter(
  914. queryset=Region.objects.all(),
  915. field_name='site__region',
  916. lookup_expr='in',
  917. label=_('Region (ID)'),
  918. )
  919. region = TreeNodeMultipleChoiceFilter(
  920. queryset=Region.objects.all(),
  921. field_name='site__region',
  922. lookup_expr='in',
  923. to_field_name='slug',
  924. label=_('Region (slug)'),
  925. )
  926. site_group_id = TreeNodeMultipleChoiceFilter(
  927. queryset=SiteGroup.objects.all(),
  928. field_name='site__group',
  929. lookup_expr='in',
  930. label=_('Site group (ID)'),
  931. )
  932. site_group = TreeNodeMultipleChoiceFilter(
  933. queryset=SiteGroup.objects.all(),
  934. field_name='site__group',
  935. lookup_expr='in',
  936. to_field_name='slug',
  937. label=_('Site group (slug)'),
  938. )
  939. site_id = django_filters.ModelMultipleChoiceFilter(
  940. queryset=Site.objects.all(),
  941. label=_('Site (ID)'),
  942. )
  943. site = django_filters.ModelMultipleChoiceFilter(
  944. field_name='site__slug',
  945. queryset=Site.objects.all(),
  946. to_field_name='slug',
  947. label=_('Site name (slug)'),
  948. )
  949. location_id = TreeNodeMultipleChoiceFilter(
  950. queryset=Location.objects.all(),
  951. field_name='location',
  952. lookup_expr='in',
  953. label=_('Location (ID)'),
  954. )
  955. location = TreeNodeMultipleChoiceFilter(
  956. queryset=Location.objects.all(),
  957. field_name='location',
  958. lookup_expr='in',
  959. to_field_name='slug',
  960. label=_('Location (slug)'),
  961. )
  962. rack_id = django_filters.ModelMultipleChoiceFilter(
  963. field_name='rack',
  964. queryset=Rack.objects.all(),
  965. label=_('Rack (ID)'),
  966. )
  967. parent_bay_id = django_filters.ModelMultipleChoiceFilter(
  968. field_name='parent_bay',
  969. queryset=DeviceBay.objects.all(),
  970. label=_('Parent bay (ID)'),
  971. )
  972. cluster_id = django_filters.ModelMultipleChoiceFilter(
  973. queryset=Cluster.objects.all(),
  974. label=_('VM cluster (ID)'),
  975. )
  976. cluster_group = django_filters.ModelMultipleChoiceFilter(
  977. field_name='cluster__group__slug',
  978. queryset=ClusterGroup.objects.all(),
  979. to_field_name='slug',
  980. label=_('Cluster group (slug)'),
  981. )
  982. cluster_group_id = django_filters.ModelMultipleChoiceFilter(
  983. field_name='cluster__group',
  984. queryset=ClusterGroup.objects.all(),
  985. label=_('Cluster group (ID)'),
  986. )
  987. model = django_filters.ModelMultipleChoiceFilter(
  988. field_name='device_type__slug',
  989. queryset=DeviceType.objects.all(),
  990. to_field_name='slug',
  991. label=_('Device model (slug)'),
  992. )
  993. name = MultiValueCharFilter(
  994. lookup_expr='iexact'
  995. )
  996. status = django_filters.MultipleChoiceFilter(
  997. choices=DeviceStatusChoices,
  998. null_value=None
  999. )
  1000. is_full_depth = django_filters.BooleanFilter(
  1001. field_name='device_type__is_full_depth',
  1002. label=_('Is full depth'),
  1003. )
  1004. mac_address = MultiValueMACAddressFilter(
  1005. field_name='interfaces__mac_addresses__mac_address',
  1006. label=_('MAC address'),
  1007. )
  1008. serial = MultiValueCharFilter(
  1009. lookup_expr='iexact'
  1010. )
  1011. has_primary_ip = django_filters.BooleanFilter(
  1012. method='_has_primary_ip',
  1013. label=_('Has a primary IP'),
  1014. )
  1015. has_oob_ip = django_filters.BooleanFilter(
  1016. method='_has_oob_ip',
  1017. label=_('Has an out-of-band IP'),
  1018. )
  1019. virtual_chassis_id = django_filters.ModelMultipleChoiceFilter(
  1020. field_name='virtual_chassis',
  1021. queryset=VirtualChassis.objects.all(),
  1022. label=_('Virtual chassis (ID)'),
  1023. )
  1024. virtual_chassis_member = django_filters.BooleanFilter(
  1025. method='_virtual_chassis_member',
  1026. label=_('Is a virtual chassis member')
  1027. )
  1028. config_template_id = django_filters.ModelMultipleChoiceFilter(
  1029. queryset=ConfigTemplate.objects.all(),
  1030. label=_('Config template (ID)'),
  1031. )
  1032. console_ports = django_filters.BooleanFilter(
  1033. method='_console_ports',
  1034. label=_('Has console ports'),
  1035. )
  1036. console_server_ports = django_filters.BooleanFilter(
  1037. method='_console_server_ports',
  1038. label=_('Has console server ports'),
  1039. )
  1040. power_ports = django_filters.BooleanFilter(
  1041. method='_power_ports',
  1042. label=_('Has power ports'),
  1043. )
  1044. power_outlets = django_filters.BooleanFilter(
  1045. method='_power_outlets',
  1046. label=_('Has power outlets'),
  1047. )
  1048. interfaces = django_filters.BooleanFilter(
  1049. method='_interfaces',
  1050. label=_('Has interfaces'),
  1051. )
  1052. pass_through_ports = django_filters.BooleanFilter(
  1053. method='_pass_through_ports',
  1054. label=_('Has pass-through ports'),
  1055. )
  1056. module_bays = django_filters.BooleanFilter(
  1057. method='_module_bays',
  1058. label=_('Has module bays'),
  1059. )
  1060. device_bays = django_filters.BooleanFilter(
  1061. method='_device_bays',
  1062. label=_('Has device bays'),
  1063. )
  1064. oob_ip_id = django_filters.ModelMultipleChoiceFilter(
  1065. field_name='oob_ip',
  1066. queryset=IPAddress.objects.all(),
  1067. label=_('OOB IP (ID)'),
  1068. )
  1069. has_virtual_device_context = django_filters.BooleanFilter(
  1070. method='_has_virtual_device_context',
  1071. label=_('Has virtual device context'),
  1072. )
  1073. class Meta:
  1074. model = Device
  1075. fields = (
  1076. 'id', 'asset_tag', 'face', 'position', 'latitude', 'longitude', 'airflow', 'vc_position', 'vc_priority',
  1077. 'description',
  1078. # Counters
  1079. 'console_port_count',
  1080. 'console_server_port_count',
  1081. 'power_port_count',
  1082. 'power_outlet_count',
  1083. 'interface_count',
  1084. 'front_port_count',
  1085. 'rear_port_count',
  1086. 'device_bay_count',
  1087. 'module_bay_count',
  1088. 'inventory_item_count',
  1089. )
  1090. def search(self, queryset, name, value):
  1091. if not value.strip():
  1092. return queryset
  1093. return queryset.filter(
  1094. Q(name__icontains=value) |
  1095. Q(virtual_chassis__name__icontains=value) |
  1096. Q(serial__icontains=value.strip()) |
  1097. Q(inventoryitems__serial__icontains=value.strip()) |
  1098. Q(asset_tag__icontains=value.strip()) |
  1099. Q(description__icontains=value.strip()) |
  1100. Q(comments__icontains=value) |
  1101. Q(primary_ip4__address__startswith=value) |
  1102. Q(primary_ip6__address__startswith=value)
  1103. ).distinct()
  1104. def _has_primary_ip(self, queryset, name, value):
  1105. params = Q(primary_ip4__isnull=False) | Q(primary_ip6__isnull=False)
  1106. if value:
  1107. return queryset.filter(params)
  1108. return queryset.exclude(params)
  1109. def _has_oob_ip(self, queryset, name, value):
  1110. params = Q(oob_ip__isnull=False)
  1111. if value:
  1112. return queryset.filter(params)
  1113. return queryset.exclude(params)
  1114. def _virtual_chassis_member(self, queryset, name, value):
  1115. return queryset.exclude(virtual_chassis__isnull=value)
  1116. def _console_ports(self, queryset, name, value):
  1117. return queryset.exclude(consoleports__isnull=value)
  1118. def _console_server_ports(self, queryset, name, value):
  1119. return queryset.exclude(consoleserverports__isnull=value)
  1120. def _power_ports(self, queryset, name, value):
  1121. return queryset.exclude(powerports__isnull=value)
  1122. def _power_outlets(self, queryset, name, value):
  1123. return queryset.exclude(poweroutlets__isnull=value)
  1124. def _interfaces(self, queryset, name, value):
  1125. return queryset.exclude(interfaces__isnull=value)
  1126. def _pass_through_ports(self, queryset, name, value):
  1127. return queryset.exclude(
  1128. frontports__isnull=value,
  1129. rearports__isnull=value
  1130. )
  1131. def _module_bays(self, queryset, name, value):
  1132. return queryset.exclude(modulebays__isnull=value)
  1133. def _device_bays(self, queryset, name, value):
  1134. return queryset.exclude(devicebays__isnull=value)
  1135. def _has_virtual_device_context(self, queryset, name, value):
  1136. params = Q(vdcs__isnull=False)
  1137. if value:
  1138. return queryset.filter(params).distinct()
  1139. return queryset.exclude(params)
  1140. class VirtualDeviceContextFilterSet(NetBoxModelFilterSet, TenancyFilterSet, PrimaryIPFilterSet):
  1141. device_id = django_filters.ModelMultipleChoiceFilter(
  1142. field_name='device',
  1143. queryset=Device.objects.all(),
  1144. label=_('VDC (ID)')
  1145. )
  1146. device = django_filters.ModelMultipleChoiceFilter(
  1147. field_name='device',
  1148. queryset=Device.objects.all(),
  1149. label=_('Device model')
  1150. )
  1151. interface_id = django_filters.ModelMultipleChoiceFilter(
  1152. field_name='interfaces',
  1153. queryset=Interface.objects.all(),
  1154. label=_('Interface (ID)')
  1155. )
  1156. status = django_filters.MultipleChoiceFilter(
  1157. choices=VirtualDeviceContextStatusChoices
  1158. )
  1159. has_primary_ip = django_filters.BooleanFilter(
  1160. method='_has_primary_ip',
  1161. label=_('Has a primary IP')
  1162. )
  1163. class Meta:
  1164. model = VirtualDeviceContext
  1165. fields = ('id', 'device', 'name', 'identifier', 'description')
  1166. def search(self, queryset, name, value):
  1167. if not value.strip():
  1168. return queryset
  1169. qs_filter = (
  1170. Q(name__icontains=value) |
  1171. Q(description__icontains=value)
  1172. )
  1173. try:
  1174. qs_filter |= Q(identifier=int(value))
  1175. except ValueError:
  1176. pass
  1177. return queryset.filter(qs_filter).distinct()
  1178. def _has_primary_ip(self, queryset, name, value):
  1179. params = Q(primary_ip4__isnull=False) | Q(primary_ip6__isnull=False)
  1180. if value:
  1181. return queryset.filter(params)
  1182. return queryset.exclude(params)
  1183. class ModuleFilterSet(NetBoxModelFilterSet):
  1184. manufacturer_id = django_filters.ModelMultipleChoiceFilter(
  1185. field_name='module_type__manufacturer',
  1186. queryset=Manufacturer.objects.all(),
  1187. label=_('Manufacturer (ID)'),
  1188. )
  1189. manufacturer = django_filters.ModelMultipleChoiceFilter(
  1190. field_name='module_type__manufacturer__slug',
  1191. queryset=Manufacturer.objects.all(),
  1192. to_field_name='slug',
  1193. label=_('Manufacturer (slug)'),
  1194. )
  1195. module_type_id = django_filters.ModelMultipleChoiceFilter(
  1196. field_name='module_type',
  1197. queryset=ModuleType.objects.all(),
  1198. label=_('Module type (ID)'),
  1199. )
  1200. module_type = django_filters.ModelMultipleChoiceFilter(
  1201. field_name='module_type__model',
  1202. queryset=ModuleType.objects.all(),
  1203. to_field_name='model',
  1204. label=_('Module type (model)'),
  1205. )
  1206. module_bay_id = TreeNodeMultipleChoiceFilter(
  1207. queryset=ModuleBay.objects.all(),
  1208. field_name='module_bay',
  1209. lookup_expr='in',
  1210. label=_('Module bay (ID)'),
  1211. )
  1212. region_id = TreeNodeMultipleChoiceFilter(
  1213. queryset=Region.objects.all(),
  1214. field_name='device__site__region',
  1215. lookup_expr='in',
  1216. label=_('Region (ID)'),
  1217. )
  1218. region = TreeNodeMultipleChoiceFilter(
  1219. queryset=Region.objects.all(),
  1220. field_name='device__site__region',
  1221. lookup_expr='in',
  1222. to_field_name='slug',
  1223. label=_('Region (slug)'),
  1224. )
  1225. site_group_id = TreeNodeMultipleChoiceFilter(
  1226. queryset=SiteGroup.objects.all(),
  1227. field_name='device__site__group',
  1228. lookup_expr='in',
  1229. label=_('Site group (ID)'),
  1230. )
  1231. site_group = TreeNodeMultipleChoiceFilter(
  1232. queryset=SiteGroup.objects.all(),
  1233. field_name='device__site__group',
  1234. lookup_expr='in',
  1235. to_field_name='slug',
  1236. label=_('Site group (slug)'),
  1237. )
  1238. site_id = django_filters.ModelMultipleChoiceFilter(
  1239. field_name='device__site',
  1240. queryset=Site.objects.all(),
  1241. label=_('Site (ID)'),
  1242. )
  1243. site = django_filters.ModelMultipleChoiceFilter(
  1244. field_name='device__site__slug',
  1245. queryset=Site.objects.all(),
  1246. to_field_name='slug',
  1247. label=_('Site name (slug)'),
  1248. )
  1249. location_id = django_filters.ModelMultipleChoiceFilter(
  1250. field_name='device__location',
  1251. queryset=Location.objects.all(),
  1252. label=_('Location (ID)'),
  1253. )
  1254. location = django_filters.ModelMultipleChoiceFilter(
  1255. field_name='device__location__slug',
  1256. queryset=Location.objects.all(),
  1257. to_field_name='slug',
  1258. label=_('Location (slug)'),
  1259. )
  1260. rack_id = django_filters.ModelMultipleChoiceFilter(
  1261. field_name='device__rack',
  1262. queryset=Rack.objects.all(),
  1263. label=_('Rack (ID)'),
  1264. )
  1265. rack = django_filters.ModelMultipleChoiceFilter(
  1266. field_name='device__rack__name',
  1267. queryset=Rack.objects.all(),
  1268. to_field_name='name',
  1269. label=_('Rack (name)'),
  1270. )
  1271. device_id = django_filters.ModelMultipleChoiceFilter(
  1272. queryset=Device.objects.all(),
  1273. label=_('Device (ID)'),
  1274. )
  1275. device = django_filters.ModelMultipleChoiceFilter(
  1276. field_name='device__name',
  1277. queryset=Device.objects.all(),
  1278. to_field_name='name',
  1279. label=_('Device (name)'),
  1280. )
  1281. status = django_filters.MultipleChoiceFilter(
  1282. choices=ModuleStatusChoices,
  1283. null_value=None
  1284. )
  1285. serial = MultiValueCharFilter(
  1286. lookup_expr='iexact'
  1287. )
  1288. class Meta:
  1289. model = Module
  1290. fields = ('id', 'status', 'asset_tag', 'description')
  1291. def search(self, queryset, name, value):
  1292. if not value.strip():
  1293. return queryset
  1294. return queryset.filter(
  1295. Q(device__name__icontains=value.strip()) |
  1296. Q(serial__icontains=value.strip()) |
  1297. Q(asset_tag__icontains=value.strip()) |
  1298. Q(description__icontains=value) |
  1299. Q(comments__icontains=value)
  1300. ).distinct()
  1301. class DeviceComponentFilterSet(django_filters.FilterSet):
  1302. q = django_filters.CharFilter(
  1303. method='search',
  1304. label=_('Search'),
  1305. )
  1306. region_id = TreeNodeMultipleChoiceFilter(
  1307. queryset=Region.objects.all(),
  1308. field_name='device__site__region',
  1309. lookup_expr='in',
  1310. label=_('Region (ID)'),
  1311. )
  1312. region = TreeNodeMultipleChoiceFilter(
  1313. queryset=Region.objects.all(),
  1314. field_name='device__site__region',
  1315. lookup_expr='in',
  1316. to_field_name='slug',
  1317. label=_('Region (slug)'),
  1318. )
  1319. site_group_id = TreeNodeMultipleChoiceFilter(
  1320. queryset=SiteGroup.objects.all(),
  1321. field_name='device__site__group',
  1322. lookup_expr='in',
  1323. label=_('Site group (ID)'),
  1324. )
  1325. site_group = TreeNodeMultipleChoiceFilter(
  1326. queryset=SiteGroup.objects.all(),
  1327. field_name='device__site__group',
  1328. lookup_expr='in',
  1329. to_field_name='slug',
  1330. label=_('Site group (slug)'),
  1331. )
  1332. site_id = django_filters.ModelMultipleChoiceFilter(
  1333. field_name='device__site',
  1334. queryset=Site.objects.all(),
  1335. label=_('Site (ID)'),
  1336. )
  1337. site = django_filters.ModelMultipleChoiceFilter(
  1338. field_name='device__site__slug',
  1339. queryset=Site.objects.all(),
  1340. to_field_name='slug',
  1341. label=_('Site name (slug)'),
  1342. )
  1343. location_id = django_filters.ModelMultipleChoiceFilter(
  1344. field_name='device__location',
  1345. queryset=Location.objects.all(),
  1346. label=_('Location (ID)'),
  1347. )
  1348. location = django_filters.ModelMultipleChoiceFilter(
  1349. field_name='device__location__slug',
  1350. queryset=Location.objects.all(),
  1351. to_field_name='slug',
  1352. label=_('Location (slug)'),
  1353. )
  1354. rack_id = django_filters.ModelMultipleChoiceFilter(
  1355. field_name='device__rack',
  1356. queryset=Rack.objects.all(),
  1357. label=_('Rack (ID)'),
  1358. )
  1359. rack = django_filters.ModelMultipleChoiceFilter(
  1360. field_name='device__rack__name',
  1361. queryset=Rack.objects.all(),
  1362. to_field_name='name',
  1363. label=_('Rack (name)'),
  1364. )
  1365. device_id = django_filters.ModelMultipleChoiceFilter(
  1366. queryset=Device.objects.all(),
  1367. label=_('Device (ID)'),
  1368. )
  1369. device = django_filters.ModelMultipleChoiceFilter(
  1370. field_name='device__name',
  1371. queryset=Device.objects.all(),
  1372. to_field_name='name',
  1373. label=_('Device (name)'),
  1374. )
  1375. device_type_id = django_filters.ModelMultipleChoiceFilter(
  1376. field_name='device__device_type',
  1377. queryset=DeviceType.objects.all(),
  1378. label=_('Device type (ID)'),
  1379. )
  1380. device_type = django_filters.ModelMultipleChoiceFilter(
  1381. field_name='device__device_type__model',
  1382. queryset=DeviceType.objects.all(),
  1383. to_field_name='model',
  1384. label=_('Device type (model)'),
  1385. )
  1386. device_role_id = django_filters.ModelMultipleChoiceFilter(
  1387. field_name='device__role',
  1388. queryset=DeviceRole.objects.all(),
  1389. label=_('Device role (ID)'),
  1390. )
  1391. device_role = django_filters.ModelMultipleChoiceFilter(
  1392. field_name='device__role__slug',
  1393. queryset=DeviceRole.objects.all(),
  1394. to_field_name='slug',
  1395. label=_('Device role (slug)'),
  1396. )
  1397. virtual_chassis_id = django_filters.ModelMultipleChoiceFilter(
  1398. field_name='device__virtual_chassis',
  1399. queryset=VirtualChassis.objects.all(),
  1400. label=_('Virtual Chassis (ID)')
  1401. )
  1402. virtual_chassis = django_filters.ModelMultipleChoiceFilter(
  1403. field_name='device__virtual_chassis__name',
  1404. queryset=VirtualChassis.objects.all(),
  1405. to_field_name='name',
  1406. label=_('Virtual Chassis'),
  1407. )
  1408. device_status = django_filters.MultipleChoiceFilter(
  1409. choices=DeviceStatusChoices,
  1410. field_name='device__status',
  1411. )
  1412. def search(self, queryset, name, value):
  1413. if not value.strip():
  1414. return queryset
  1415. return queryset.filter(
  1416. Q(name__icontains=value) |
  1417. Q(label__icontains=value) |
  1418. Q(description__icontains=value)
  1419. )
  1420. class ModularDeviceComponentFilterSet(DeviceComponentFilterSet):
  1421. """
  1422. Extends DeviceComponentFilterSet to add a module_id filter for components
  1423. which can be associated with a particular module within a device.
  1424. """
  1425. module_id = django_filters.ModelMultipleChoiceFilter(
  1426. queryset=Module.objects.all(),
  1427. label=_('Module (ID)'),
  1428. )
  1429. class CabledObjectFilterSet(django_filters.FilterSet):
  1430. cable_id = django_filters.ModelMultipleChoiceFilter(
  1431. queryset=Cable.objects.all(),
  1432. label=_('Cable (ID)'),
  1433. )
  1434. cabled = django_filters.BooleanFilter(
  1435. field_name='cable',
  1436. lookup_expr='isnull',
  1437. exclude=True
  1438. )
  1439. occupied = django_filters.BooleanFilter(
  1440. method='filter_occupied'
  1441. )
  1442. def filter_occupied(self, queryset, name, value):
  1443. if value:
  1444. return queryset.filter(Q(cable__isnull=False) | Q(mark_connected=True))
  1445. else:
  1446. return queryset.filter(cable__isnull=True, mark_connected=False)
  1447. class PathEndpointFilterSet(django_filters.FilterSet):
  1448. connected = django_filters.BooleanFilter(
  1449. method='filter_connected'
  1450. )
  1451. def filter_connected(self, queryset, name, value):
  1452. if value:
  1453. return queryset.filter(_path__is_active=True)
  1454. else:
  1455. return queryset.filter(Q(_path__isnull=True) | Q(_path__is_active=False))
  1456. class ConsolePortFilterSet(
  1457. ModularDeviceComponentFilterSet,
  1458. NetBoxModelFilterSet,
  1459. CabledObjectFilterSet,
  1460. PathEndpointFilterSet
  1461. ):
  1462. type = django_filters.MultipleChoiceFilter(
  1463. choices=ConsolePortTypeChoices,
  1464. null_value=None
  1465. )
  1466. class Meta:
  1467. model = ConsolePort
  1468. fields = ('id', 'name', 'label', 'speed', 'description', 'mark_connected', 'cable_end')
  1469. class ConsoleServerPortFilterSet(
  1470. ModularDeviceComponentFilterSet,
  1471. NetBoxModelFilterSet,
  1472. CabledObjectFilterSet,
  1473. PathEndpointFilterSet
  1474. ):
  1475. type = django_filters.MultipleChoiceFilter(
  1476. choices=ConsolePortTypeChoices,
  1477. null_value=None
  1478. )
  1479. class Meta:
  1480. model = ConsoleServerPort
  1481. fields = ('id', 'name', 'label', 'speed', 'description', 'mark_connected', 'cable_end')
  1482. class PowerPortFilterSet(
  1483. ModularDeviceComponentFilterSet,
  1484. NetBoxModelFilterSet,
  1485. CabledObjectFilterSet,
  1486. PathEndpointFilterSet
  1487. ):
  1488. type = django_filters.MultipleChoiceFilter(
  1489. choices=PowerPortTypeChoices,
  1490. null_value=None
  1491. )
  1492. class Meta:
  1493. model = PowerPort
  1494. fields = (
  1495. 'id', 'name', 'label', 'maximum_draw', 'allocated_draw', 'description', 'mark_connected', 'cable_end',
  1496. )
  1497. class PowerOutletFilterSet(
  1498. ModularDeviceComponentFilterSet,
  1499. NetBoxModelFilterSet,
  1500. CabledObjectFilterSet,
  1501. PathEndpointFilterSet
  1502. ):
  1503. type = django_filters.MultipleChoiceFilter(
  1504. choices=PowerOutletTypeChoices,
  1505. null_value=None
  1506. )
  1507. feed_leg = django_filters.MultipleChoiceFilter(
  1508. choices=PowerOutletFeedLegChoices,
  1509. null_value=None
  1510. )
  1511. power_port_id = django_filters.ModelMultipleChoiceFilter(
  1512. queryset=PowerPort.objects.all(),
  1513. label=_('Power port (ID)'),
  1514. )
  1515. class Meta:
  1516. model = PowerOutlet
  1517. fields = (
  1518. 'id', 'name', 'label', 'feed_leg', 'description', 'color', 'mark_connected', 'cable_end',
  1519. )
  1520. class MACAddressFilterSet(NetBoxModelFilterSet):
  1521. mac_address = MultiValueMACAddressFilter()
  1522. device = MultiValueCharFilter(
  1523. method='filter_device',
  1524. field_name='name',
  1525. label=_('Device (name)'),
  1526. )
  1527. device_id = MultiValueNumberFilter(
  1528. method='filter_device',
  1529. field_name='pk',
  1530. label=_('Device (ID)'),
  1531. )
  1532. virtual_machine = MultiValueCharFilter(
  1533. method='filter_virtual_machine',
  1534. field_name='name',
  1535. label=_('Virtual machine (name)'),
  1536. )
  1537. virtual_machine_id = MultiValueNumberFilter(
  1538. method='filter_virtual_machine',
  1539. field_name='pk',
  1540. label=_('Virtual machine (ID)'),
  1541. )
  1542. interface = django_filters.ModelMultipleChoiceFilter(
  1543. field_name='interface__name',
  1544. queryset=Interface.objects.all(),
  1545. to_field_name='name',
  1546. label=_('Interface (name)'),
  1547. )
  1548. interface_id = django_filters.ModelMultipleChoiceFilter(
  1549. field_name='interface',
  1550. queryset=Interface.objects.all(),
  1551. label=_('Interface (ID)'),
  1552. )
  1553. vminterface = django_filters.ModelMultipleChoiceFilter(
  1554. field_name='vminterface__name',
  1555. queryset=VMInterface.objects.all(),
  1556. to_field_name='name',
  1557. label=_('VM interface (name)'),
  1558. )
  1559. vminterface_id = django_filters.ModelMultipleChoiceFilter(
  1560. field_name='vminterface',
  1561. queryset=VMInterface.objects.all(),
  1562. label=_('VM interface (ID)'),
  1563. )
  1564. class Meta:
  1565. model = MACAddress
  1566. fields = ('id', 'description', 'assigned_object_type', 'assigned_object_id')
  1567. def search(self, queryset, name, value):
  1568. if not value.strip():
  1569. return queryset
  1570. qs_filter = (
  1571. Q(mac_address__icontains=value) |
  1572. Q(description__icontains=value)
  1573. )
  1574. return queryset.filter(qs_filter)
  1575. def filter_device(self, queryset, name, value):
  1576. devices = Device.objects.filter(**{f'{name}__in': value})
  1577. if not devices.exists():
  1578. return queryset.none()
  1579. interface_ids = []
  1580. for device in devices:
  1581. interface_ids.extend(device.vc_interfaces().values_list('id', flat=True))
  1582. return queryset.filter(
  1583. interface__in=interface_ids
  1584. )
  1585. def filter_virtual_machine(self, queryset, name, value):
  1586. virtual_machines = VirtualMachine.objects.filter(**{f'{name}__in': value})
  1587. if not virtual_machines.exists():
  1588. return queryset.none()
  1589. interface_ids = []
  1590. for vm in virtual_machines:
  1591. interface_ids.extend(vm.interfaces.values_list('id', flat=True))
  1592. return queryset.filter(
  1593. vminterface__in=interface_ids
  1594. )
  1595. class CommonInterfaceFilterSet(django_filters.FilterSet):
  1596. mode = django_filters.MultipleChoiceFilter(
  1597. choices=InterfaceModeChoices,
  1598. label=_('802.1Q Mode')
  1599. )
  1600. vlan_id = django_filters.CharFilter(
  1601. method='filter_vlan_id',
  1602. label=_('Assigned VLAN')
  1603. )
  1604. vlan = django_filters.CharFilter(
  1605. method='filter_vlan',
  1606. label=_('Assigned VID')
  1607. )
  1608. vrf_id = django_filters.ModelMultipleChoiceFilter(
  1609. field_name='vrf',
  1610. queryset=VRF.objects.all(),
  1611. label=_('VRF'),
  1612. )
  1613. vrf = django_filters.ModelMultipleChoiceFilter(
  1614. field_name='vrf__rd',
  1615. queryset=VRF.objects.all(),
  1616. to_field_name='rd',
  1617. label=_('VRF (RD)'),
  1618. )
  1619. l2vpn_id = django_filters.ModelMultipleChoiceFilter(
  1620. field_name='l2vpn_terminations__l2vpn',
  1621. queryset=L2VPN.objects.all(),
  1622. label=_('L2VPN (ID)'),
  1623. )
  1624. l2vpn = django_filters.ModelMultipleChoiceFilter(
  1625. field_name='l2vpn_terminations__l2vpn__identifier',
  1626. queryset=L2VPN.objects.all(),
  1627. to_field_name='identifier',
  1628. label=_('L2VPN'),
  1629. )
  1630. vlan_translation_policy_id = django_filters.ModelMultipleChoiceFilter(
  1631. field_name='vlan_translation_policy',
  1632. queryset=VLANTranslationPolicy.objects.all(),
  1633. label=_('VLAN Translation Policy (ID)'),
  1634. )
  1635. vlan_translation_policy = django_filters.ModelMultipleChoiceFilter(
  1636. field_name='vlan_translation_policy__name',
  1637. queryset=VLANTranslationPolicy.objects.all(),
  1638. to_field_name='name',
  1639. label=_('VLAN Translation Policy'),
  1640. )
  1641. def filter_vlan_id(self, queryset, name, value):
  1642. value = value.strip()
  1643. if not value:
  1644. return queryset
  1645. return queryset.filter(
  1646. Q(untagged_vlan_id=value) |
  1647. Q(tagged_vlans=value) |
  1648. Q(qinq_svlan=value)
  1649. )
  1650. def filter_vlan(self, queryset, name, value):
  1651. value = value.strip()
  1652. if not value:
  1653. return queryset
  1654. return queryset.filter(
  1655. Q(untagged_vlan_id__vid=value) |
  1656. Q(tagged_vlans__vid=value) |
  1657. Q(qinq_svlan__vid=value)
  1658. )
  1659. class InterfaceFilterSet(
  1660. ModularDeviceComponentFilterSet,
  1661. NetBoxModelFilterSet,
  1662. CabledObjectFilterSet,
  1663. PathEndpointFilterSet,
  1664. CommonInterfaceFilterSet
  1665. ):
  1666. virtual_chassis_member = MultiValueCharFilter(
  1667. method='filter_virtual_chassis_member',
  1668. field_name='name',
  1669. label=_('Virtual Chassis Interfaces for Device')
  1670. )
  1671. virtual_chassis_member_id = MultiValueNumberFilter(
  1672. method='filter_virtual_chassis_member',
  1673. field_name='pk',
  1674. label=_('Virtual Chassis Interfaces for Device (ID)')
  1675. )
  1676. kind = django_filters.CharFilter(
  1677. method='filter_kind',
  1678. label=_('Kind of interface'),
  1679. )
  1680. parent_id = django_filters.ModelMultipleChoiceFilter(
  1681. field_name='parent',
  1682. queryset=Interface.objects.all(),
  1683. label=_('Parent interface (ID)'),
  1684. )
  1685. bridge_id = django_filters.ModelMultipleChoiceFilter(
  1686. field_name='bridge',
  1687. queryset=Interface.objects.all(),
  1688. label=_('Bridged interface (ID)'),
  1689. )
  1690. lag_id = django_filters.ModelMultipleChoiceFilter(
  1691. field_name='lag',
  1692. queryset=Interface.objects.all(),
  1693. label=_('LAG interface (ID)'),
  1694. )
  1695. speed = MultiValueNumberFilter()
  1696. duplex = django_filters.MultipleChoiceFilter(
  1697. choices=InterfaceDuplexChoices
  1698. )
  1699. mac_address = MultiValueMACAddressFilter(
  1700. field_name='mac_addresses__mac_address',
  1701. label=_('MAC Address')
  1702. )
  1703. primary_mac_address_id = django_filters.ModelMultipleChoiceFilter(
  1704. field_name='primary_mac_address',
  1705. queryset=MACAddress.objects.all(),
  1706. label=_('Primary MAC address (ID)'),
  1707. )
  1708. primary_mac_address = django_filters.ModelMultipleChoiceFilter(
  1709. field_name='primary_mac_address__mac_address',
  1710. queryset=MACAddress.objects.all(),
  1711. to_field_name='mac_address',
  1712. label=_('Primary MAC address'),
  1713. )
  1714. wwn = MultiValueWWNFilter()
  1715. poe_mode = django_filters.MultipleChoiceFilter(
  1716. choices=InterfacePoEModeChoices
  1717. )
  1718. poe_type = django_filters.MultipleChoiceFilter(
  1719. choices=InterfacePoETypeChoices
  1720. )
  1721. type = django_filters.MultipleChoiceFilter(
  1722. choices=InterfaceTypeChoices,
  1723. null_value=None
  1724. )
  1725. rf_role = django_filters.MultipleChoiceFilter(
  1726. choices=WirelessRoleChoices
  1727. )
  1728. rf_channel = django_filters.MultipleChoiceFilter(
  1729. choices=WirelessChannelChoices
  1730. )
  1731. vdc_id = django_filters.ModelMultipleChoiceFilter(
  1732. field_name='vdcs',
  1733. queryset=VirtualDeviceContext.objects.all(),
  1734. label=_('Virtual Device Context')
  1735. )
  1736. vdc_identifier = django_filters.ModelMultipleChoiceFilter(
  1737. field_name='vdcs__identifier',
  1738. queryset=VirtualDeviceContext.objects.all(),
  1739. to_field_name='identifier',
  1740. label=_('Virtual Device Context (Identifier)')
  1741. )
  1742. vdc = django_filters.ModelMultipleChoiceFilter(
  1743. field_name='vdcs__name',
  1744. queryset=VirtualDeviceContext.objects.all(),
  1745. to_field_name='name',
  1746. label=_('Virtual Device Context')
  1747. )
  1748. wireless_lan_id = django_filters.ModelMultipleChoiceFilter(
  1749. field_name='wireless_lans',
  1750. queryset=WirelessLAN.objects.all(),
  1751. label=_('Wireless LAN')
  1752. )
  1753. wireless_link_id = django_filters.ModelMultipleChoiceFilter(
  1754. queryset=WirelessLink.objects.all(),
  1755. label=_('Wireless link')
  1756. )
  1757. virtual_circuit_id = django_filters.ModelMultipleChoiceFilter(
  1758. field_name='virtual_circuit_termination__virtual_circuit',
  1759. queryset=VirtualCircuit.objects.all(),
  1760. label=_('Virtual circuit (ID)'),
  1761. )
  1762. virtual_circuit_termination_id = django_filters.ModelMultipleChoiceFilter(
  1763. field_name='virtual_circuit_termination',
  1764. queryset=VirtualCircuitTermination.objects.all(),
  1765. label=_('Virtual circuit termination (ID)'),
  1766. )
  1767. class Meta:
  1768. model = Interface
  1769. fields = (
  1770. 'id', 'name', 'label', 'type', 'enabled', 'mtu', 'mgmt_only', 'poe_mode', 'poe_type', 'mode', 'rf_role',
  1771. 'rf_channel', 'rf_channel_frequency', 'rf_channel_width', 'tx_power', 'description', 'mark_connected',
  1772. 'cable_id', 'cable_end',
  1773. )
  1774. def filter_virtual_chassis_member(self, queryset, name, value):
  1775. try:
  1776. vc_interface_ids = []
  1777. for device in Device.objects.filter(**{f'{name}__in': value}):
  1778. vc_interface_ids.extend(device.vc_interfaces(if_master=False).values_list('id', flat=True))
  1779. return queryset.filter(pk__in=vc_interface_ids)
  1780. except Device.DoesNotExist:
  1781. return queryset.none()
  1782. def filter_kind(self, queryset, name, value):
  1783. value = value.strip().lower()
  1784. return {
  1785. 'physical': queryset.exclude(type__in=NONCONNECTABLE_IFACE_TYPES),
  1786. 'virtual': queryset.filter(type__in=VIRTUAL_IFACE_TYPES),
  1787. 'wireless': queryset.filter(type__in=WIRELESS_IFACE_TYPES),
  1788. }.get(value, queryset.none())
  1789. class FrontPortFilterSet(
  1790. ModularDeviceComponentFilterSet,
  1791. NetBoxModelFilterSet,
  1792. CabledObjectFilterSet
  1793. ):
  1794. type = django_filters.MultipleChoiceFilter(
  1795. choices=PortTypeChoices,
  1796. null_value=None
  1797. )
  1798. rear_port_id = django_filters.ModelMultipleChoiceFilter(
  1799. queryset=RearPort.objects.all()
  1800. )
  1801. class Meta:
  1802. model = FrontPort
  1803. fields = (
  1804. 'id', 'name', 'label', 'type', 'color', 'rear_port_position', 'description', 'mark_connected', 'cable_end',
  1805. )
  1806. class RearPortFilterSet(
  1807. ModularDeviceComponentFilterSet,
  1808. NetBoxModelFilterSet,
  1809. CabledObjectFilterSet
  1810. ):
  1811. type = django_filters.MultipleChoiceFilter(
  1812. choices=PortTypeChoices,
  1813. null_value=None
  1814. )
  1815. class Meta:
  1816. model = RearPort
  1817. fields = (
  1818. 'id', 'name', 'label', 'type', 'color', 'positions', 'description', 'mark_connected', 'cable_end',
  1819. )
  1820. class ModuleBayFilterSet(ModularDeviceComponentFilterSet, NetBoxModelFilterSet):
  1821. parent_id = django_filters.ModelMultipleChoiceFilter(
  1822. queryset=ModuleBay.objects.all(),
  1823. label=_('Parent module bay (ID)'),
  1824. )
  1825. installed_module_id = django_filters.ModelMultipleChoiceFilter(
  1826. field_name='installed_module',
  1827. queryset=ModuleBay.objects.all(),
  1828. label=_('Installed module (ID)'),
  1829. )
  1830. class Meta:
  1831. model = ModuleBay
  1832. fields = ('id', 'name', 'label', 'position', 'description')
  1833. class DeviceBayFilterSet(DeviceComponentFilterSet, NetBoxModelFilterSet):
  1834. installed_device_id = django_filters.ModelMultipleChoiceFilter(
  1835. queryset=Device.objects.all(),
  1836. label=_('Installed device (ID)'),
  1837. )
  1838. installed_device = django_filters.ModelMultipleChoiceFilter(
  1839. field_name='installed_device__name',
  1840. queryset=Device.objects.all(),
  1841. to_field_name='name',
  1842. label=_('Installed device (name)'),
  1843. )
  1844. class Meta:
  1845. model = DeviceBay
  1846. fields = ('id', 'name', 'label', 'description')
  1847. class InventoryItemFilterSet(DeviceComponentFilterSet, NetBoxModelFilterSet):
  1848. parent_id = django_filters.ModelMultipleChoiceFilter(
  1849. queryset=InventoryItem.objects.all(),
  1850. label=_('Parent inventory item (ID)'),
  1851. )
  1852. manufacturer_id = django_filters.ModelMultipleChoiceFilter(
  1853. queryset=Manufacturer.objects.all(),
  1854. label=_('Manufacturer (ID)'),
  1855. )
  1856. manufacturer = django_filters.ModelMultipleChoiceFilter(
  1857. field_name='manufacturer__slug',
  1858. queryset=Manufacturer.objects.all(),
  1859. to_field_name='slug',
  1860. label=_('Manufacturer (slug)'),
  1861. )
  1862. role_id = django_filters.ModelMultipleChoiceFilter(
  1863. queryset=InventoryItemRole.objects.all(),
  1864. label=_('Role (ID)'),
  1865. )
  1866. role = django_filters.ModelMultipleChoiceFilter(
  1867. field_name='role__slug',
  1868. queryset=InventoryItemRole.objects.all(),
  1869. to_field_name='slug',
  1870. label=_('Role (slug)'),
  1871. )
  1872. component_type = ContentTypeFilter()
  1873. component_id = MultiValueNumberFilter()
  1874. serial = MultiValueCharFilter(
  1875. lookup_expr='iexact'
  1876. )
  1877. status = django_filters.MultipleChoiceFilter(
  1878. choices=InventoryItemStatusChoices,
  1879. null_value=None
  1880. )
  1881. class Meta:
  1882. model = InventoryItem
  1883. fields = ('id', 'name', 'label', 'part_id', 'asset_tag', 'status', 'description', 'discovered')
  1884. def search(self, queryset, name, value):
  1885. if not value.strip():
  1886. return queryset
  1887. qs_filter = (
  1888. Q(name__icontains=value) |
  1889. Q(part_id__icontains=value) |
  1890. Q(serial__icontains=value) |
  1891. Q(asset_tag__icontains=value) |
  1892. Q(description__icontains=value)
  1893. )
  1894. return queryset.filter(qs_filter)
  1895. class InventoryItemRoleFilterSet(OrganizationalModelFilterSet):
  1896. class Meta:
  1897. model = InventoryItemRole
  1898. fields = ('id', 'name', 'slug', 'color', 'description')
  1899. class VirtualChassisFilterSet(NetBoxModelFilterSet):
  1900. master_id = django_filters.ModelMultipleChoiceFilter(
  1901. queryset=Device.objects.all(),
  1902. label=_('Master (ID)'),
  1903. )
  1904. master = django_filters.ModelMultipleChoiceFilter(
  1905. field_name='master__name',
  1906. queryset=Device.objects.all(),
  1907. to_field_name='name',
  1908. label=_('Master (name)'),
  1909. )
  1910. region_id = TreeNodeMultipleChoiceFilter(
  1911. queryset=Region.objects.all(),
  1912. field_name='master__site__region',
  1913. lookup_expr='in',
  1914. label=_('Region (ID)'),
  1915. )
  1916. region = TreeNodeMultipleChoiceFilter(
  1917. queryset=Region.objects.all(),
  1918. field_name='master__site__region',
  1919. lookup_expr='in',
  1920. to_field_name='slug',
  1921. label=_('Region (slug)'),
  1922. )
  1923. site_group_id = TreeNodeMultipleChoiceFilter(
  1924. queryset=SiteGroup.objects.all(),
  1925. field_name='master__site__group',
  1926. lookup_expr='in',
  1927. label=_('Site group (ID)'),
  1928. )
  1929. site_group = TreeNodeMultipleChoiceFilter(
  1930. queryset=SiteGroup.objects.all(),
  1931. field_name='master__site__group',
  1932. lookup_expr='in',
  1933. to_field_name='slug',
  1934. label=_('Site group (slug)'),
  1935. )
  1936. site_id = django_filters.ModelMultipleChoiceFilter(
  1937. field_name='master__site',
  1938. queryset=Site.objects.all(),
  1939. label=_('Site (ID)'),
  1940. )
  1941. site = django_filters.ModelMultipleChoiceFilter(
  1942. field_name='master__site__slug',
  1943. queryset=Site.objects.all(),
  1944. to_field_name='slug',
  1945. label=_('Site name (slug)'),
  1946. )
  1947. tenant_id = django_filters.ModelMultipleChoiceFilter(
  1948. field_name='master__tenant',
  1949. queryset=Tenant.objects.all(),
  1950. label=_('Tenant (ID)'),
  1951. )
  1952. tenant = django_filters.ModelMultipleChoiceFilter(
  1953. field_name='master__tenant__slug',
  1954. queryset=Tenant.objects.all(),
  1955. to_field_name='slug',
  1956. label=_('Tenant (slug)'),
  1957. )
  1958. class Meta:
  1959. model = VirtualChassis
  1960. fields = ('id', 'domain', 'name', 'description', 'member_count')
  1961. def search(self, queryset, name, value):
  1962. if not value.strip():
  1963. return queryset
  1964. qs_filter = (
  1965. Q(name__icontains=value) |
  1966. Q(description__icontains=value) |
  1967. Q(members__name__icontains=value) |
  1968. Q(domain__icontains=value)
  1969. )
  1970. return queryset.filter(qs_filter).distinct()
  1971. class CableFilterSet(TenancyFilterSet, NetBoxModelFilterSet):
  1972. termination_a_type = ContentTypeFilter(
  1973. field_name='terminations__termination_type'
  1974. )
  1975. termination_a_id = MultiValueNumberFilter(
  1976. method='filter_by_cable_end_a',
  1977. field_name='terminations__termination_id'
  1978. )
  1979. termination_b_type = ContentTypeFilter(
  1980. field_name='terminations__termination_type'
  1981. )
  1982. termination_b_id = MultiValueNumberFilter(
  1983. method='filter_by_cable_end_b',
  1984. field_name='terminations__termination_id'
  1985. )
  1986. unterminated = django_filters.BooleanFilter(
  1987. method='_unterminated',
  1988. label=_('Unterminated'),
  1989. )
  1990. type = django_filters.MultipleChoiceFilter(
  1991. choices=CableTypeChoices
  1992. )
  1993. status = django_filters.MultipleChoiceFilter(
  1994. choices=LinkStatusChoices
  1995. )
  1996. color = django_filters.MultipleChoiceFilter(
  1997. choices=ColorChoices
  1998. )
  1999. device_id = MultiValueNumberFilter(
  2000. method='filter_by_termination'
  2001. )
  2002. device = MultiValueCharFilter(
  2003. method='filter_by_termination',
  2004. field_name='device__name'
  2005. )
  2006. rack_id = MultiValueNumberFilter(
  2007. method='filter_by_termination',
  2008. field_name='rack_id'
  2009. )
  2010. rack = MultiValueCharFilter(
  2011. method='filter_by_termination',
  2012. field_name='rack__name'
  2013. )
  2014. location_id = MultiValueNumberFilter(
  2015. method='filter_by_termination',
  2016. field_name='location_id'
  2017. )
  2018. location = MultiValueCharFilter(
  2019. method='filter_by_termination',
  2020. field_name='location__name'
  2021. )
  2022. site_id = MultiValueNumberFilter(
  2023. method='filter_by_termination',
  2024. field_name='site_id'
  2025. )
  2026. site = MultiValueCharFilter(
  2027. method='filter_by_termination',
  2028. field_name='site__slug'
  2029. )
  2030. # Termination object filters
  2031. consoleport_id = MultiValueNumberFilter(
  2032. method='filter_by_consoleport'
  2033. )
  2034. consoleserverport_id = MultiValueNumberFilter(
  2035. method='filter_by_consoleserverport'
  2036. )
  2037. powerport_id = MultiValueNumberFilter(
  2038. method='filter_by_powerport'
  2039. )
  2040. poweroutlet_id = MultiValueNumberFilter(
  2041. method='filter_by_poweroutlet'
  2042. )
  2043. interface_id = MultiValueNumberFilter(
  2044. method='filter_by_interface'
  2045. )
  2046. frontport_id = MultiValueNumberFilter(
  2047. method='filter_by_frontport'
  2048. )
  2049. rearport_id = MultiValueNumberFilter(
  2050. method='filter_by_rearport'
  2051. )
  2052. powerfeed_id = MultiValueNumberFilter(
  2053. method='filter_by_powerfeed'
  2054. )
  2055. circuittermination_id = MultiValueNumberFilter(
  2056. method='filter_by_circuittermination'
  2057. )
  2058. class Meta:
  2059. model = Cable
  2060. fields = ('id', 'label', 'length', 'length_unit', 'description')
  2061. def search(self, queryset, name, value):
  2062. if not value.strip():
  2063. return queryset
  2064. qs_filter = (
  2065. Q(label__icontains=value) |
  2066. Q(description__icontains=value)
  2067. )
  2068. return queryset.filter(qs_filter)
  2069. def filter_by_termination(self, queryset, name, value):
  2070. # Filter by a related object cached on CableTermination. Note the underscore preceding the field name.
  2071. # Supported objects: device, rack, location, site
  2072. return queryset.filter(**{f'terminations___{name}__in': value}).distinct()
  2073. def filter_by_cable_end(self, queryset, name, value, side):
  2074. # Filter by termination id and cable_end type
  2075. return queryset.filter(**{f'{name}__in': value, 'terminations__cable_end': side}).distinct()
  2076. def filter_by_cable_end_a(self, queryset, name, value):
  2077. # Filter by termination id and cable_end type
  2078. return self.filter_by_cable_end(queryset, name, value, CableEndChoices.SIDE_A)
  2079. def filter_by_cable_end_b(self, queryset, name, value):
  2080. # Filter by termination id and cable_end type
  2081. return self.filter_by_cable_end(queryset, name, value, CableEndChoices.SIDE_B)
  2082. def _unterminated(self, queryset, name, value):
  2083. if value:
  2084. terminated_ids = (
  2085. queryset.filter(terminations__cable_end=CableEndChoices.SIDE_A)
  2086. .filter(terminations__cable_end=CableEndChoices.SIDE_B)
  2087. .values("id")
  2088. )
  2089. return queryset.exclude(id__in=terminated_ids)
  2090. else:
  2091. return queryset.filter(terminations__cable_end=CableEndChoices.SIDE_A).filter(
  2092. terminations__cable_end=CableEndChoices.SIDE_B
  2093. )
  2094. def filter_by_termination_object(self, queryset, model, value):
  2095. # Filter by specific termination object(s)
  2096. content_type = ContentType.objects.get_for_model(model)
  2097. cable_ids = CableTermination.objects.filter(
  2098. termination_type=content_type,
  2099. termination_id__in=value
  2100. ).values_list('cable', flat=True)
  2101. return queryset.filter(pk__in=cable_ids)
  2102. def filter_by_consoleport(self, queryset, name, value):
  2103. return self.filter_by_termination_object(queryset, ConsolePort, value)
  2104. def filter_by_consoleserverport(self, queryset, name, value):
  2105. return self.filter_by_termination_object(queryset, ConsoleServerPort, value)
  2106. def filter_by_powerport(self, queryset, name, value):
  2107. return self.filter_by_termination_object(queryset, PowerPort, value)
  2108. def filter_by_poweroutlet(self, queryset, name, value):
  2109. return self.filter_by_termination_object(queryset, PowerOutlet, value)
  2110. def filter_by_interface(self, queryset, name, value):
  2111. return self.filter_by_termination_object(queryset, Interface, value)
  2112. def filter_by_frontport(self, queryset, name, value):
  2113. return self.filter_by_termination_object(queryset, FrontPort, value)
  2114. def filter_by_rearport(self, queryset, name, value):
  2115. return self.filter_by_termination_object(queryset, RearPort, value)
  2116. def filter_by_powerfeed(self, queryset, name, value):
  2117. return self.filter_by_termination_object(queryset, PowerFeed, value)
  2118. def filter_by_circuittermination(self, queryset, name, value):
  2119. return self.filter_by_termination_object(queryset, CircuitTermination, value)
  2120. class CableTerminationFilterSet(ChangeLoggedModelFilterSet):
  2121. termination_type = ContentTypeFilter()
  2122. class Meta:
  2123. model = CableTermination
  2124. fields = ('id', 'cable', 'cable_end', 'termination_type', 'termination_id')
  2125. class PowerPanelFilterSet(NetBoxModelFilterSet, ContactModelFilterSet):
  2126. region_id = TreeNodeMultipleChoiceFilter(
  2127. queryset=Region.objects.all(),
  2128. field_name='site__region',
  2129. lookup_expr='in',
  2130. label=_('Region (ID)'),
  2131. )
  2132. region = TreeNodeMultipleChoiceFilter(
  2133. queryset=Region.objects.all(),
  2134. field_name='site__region',
  2135. lookup_expr='in',
  2136. to_field_name='slug',
  2137. label=_('Region (slug)'),
  2138. )
  2139. site_group_id = TreeNodeMultipleChoiceFilter(
  2140. queryset=SiteGroup.objects.all(),
  2141. field_name='site__group',
  2142. lookup_expr='in',
  2143. label=_('Site group (ID)'),
  2144. )
  2145. site_group = TreeNodeMultipleChoiceFilter(
  2146. queryset=SiteGroup.objects.all(),
  2147. field_name='site__group',
  2148. lookup_expr='in',
  2149. to_field_name='slug',
  2150. label=_('Site group (slug)'),
  2151. )
  2152. site_id = django_filters.ModelMultipleChoiceFilter(
  2153. queryset=Site.objects.all(),
  2154. label=_('Site (ID)'),
  2155. )
  2156. site = django_filters.ModelMultipleChoiceFilter(
  2157. field_name='site__slug',
  2158. queryset=Site.objects.all(),
  2159. to_field_name='slug',
  2160. label=_('Site name (slug)'),
  2161. )
  2162. location_id = TreeNodeMultipleChoiceFilter(
  2163. queryset=Location.objects.all(),
  2164. field_name='location',
  2165. lookup_expr='in',
  2166. label=_('Location (ID)'),
  2167. )
  2168. class Meta:
  2169. model = PowerPanel
  2170. fields = ('id', 'name', 'description')
  2171. def search(self, queryset, name, value):
  2172. if not value.strip():
  2173. return queryset
  2174. qs_filter = (
  2175. Q(name__icontains=value) |
  2176. Q(description__icontains=value)
  2177. )
  2178. return queryset.filter(qs_filter)
  2179. class PowerFeedFilterSet(NetBoxModelFilterSet, CabledObjectFilterSet, PathEndpointFilterSet, TenancyFilterSet):
  2180. region_id = TreeNodeMultipleChoiceFilter(
  2181. queryset=Region.objects.all(),
  2182. field_name='power_panel__site__region',
  2183. lookup_expr='in',
  2184. label=_('Region (ID)'),
  2185. )
  2186. region = TreeNodeMultipleChoiceFilter(
  2187. queryset=Region.objects.all(),
  2188. field_name='power_panel__site__region',
  2189. lookup_expr='in',
  2190. to_field_name='slug',
  2191. label=_('Region (slug)'),
  2192. )
  2193. site_group_id = TreeNodeMultipleChoiceFilter(
  2194. queryset=SiteGroup.objects.all(),
  2195. field_name='power_panel__site__group',
  2196. lookup_expr='in',
  2197. label=_('Site group (ID)'),
  2198. )
  2199. site_group = TreeNodeMultipleChoiceFilter(
  2200. queryset=SiteGroup.objects.all(),
  2201. field_name='power_panel__site__group',
  2202. lookup_expr='in',
  2203. to_field_name='slug',
  2204. label=_('Site group (slug)'),
  2205. )
  2206. site_id = django_filters.ModelMultipleChoiceFilter(
  2207. field_name='power_panel__site',
  2208. queryset=Site.objects.all(),
  2209. label=_('Site (ID)'),
  2210. )
  2211. site = django_filters.ModelMultipleChoiceFilter(
  2212. field_name='power_panel__site__slug',
  2213. queryset=Site.objects.all(),
  2214. to_field_name='slug',
  2215. label=_('Site name (slug)'),
  2216. )
  2217. power_panel_id = django_filters.ModelMultipleChoiceFilter(
  2218. queryset=PowerPanel.objects.all(),
  2219. label=_('Power panel (ID)'),
  2220. )
  2221. rack_id = django_filters.ModelMultipleChoiceFilter(
  2222. field_name='rack',
  2223. queryset=Rack.objects.all(),
  2224. label=_('Rack (ID)'),
  2225. )
  2226. status = django_filters.MultipleChoiceFilter(
  2227. choices=PowerFeedStatusChoices,
  2228. null_value=None
  2229. )
  2230. class Meta:
  2231. model = PowerFeed
  2232. fields = (
  2233. 'id', 'name', 'status', 'type', 'supply', 'phase', 'voltage', 'amperage', 'max_utilization',
  2234. 'available_power', 'mark_connected', 'cable_end', 'description',
  2235. )
  2236. def search(self, queryset, name, value):
  2237. if not value.strip():
  2238. return queryset
  2239. qs_filter = (
  2240. Q(name__icontains=value) |
  2241. Q(description__icontains=value) |
  2242. Q(power_panel__name__icontains=value) |
  2243. Q(comments__icontains=value)
  2244. )
  2245. return queryset.filter(qs_filter)
  2246. #
  2247. # Connection filter sets
  2248. #
  2249. class ConnectionFilterSet(BaseFilterSet):
  2250. q = django_filters.CharFilter(
  2251. method='search',
  2252. label=_('Search'),
  2253. )
  2254. site_id = MultiValueNumberFilter(
  2255. method='filter_connections',
  2256. field_name='device__site_id'
  2257. )
  2258. site = MultiValueCharFilter(
  2259. method='filter_connections',
  2260. field_name='device__site__slug'
  2261. )
  2262. device_id = MultiValueNumberFilter(
  2263. method='filter_connections',
  2264. field_name='device_id'
  2265. )
  2266. device = MultiValueCharFilter(
  2267. method='filter_connections',
  2268. field_name='device__name'
  2269. )
  2270. def filter_connections(self, queryset, name, value):
  2271. if not value:
  2272. return queryset
  2273. return queryset.filter(**{f'{name}__in': value})
  2274. def search(self, queryset, name, value):
  2275. if not value.strip():
  2276. return queryset
  2277. qs_filter = (
  2278. Q(device__name__icontains=value) |
  2279. Q(cable__label__icontains=value)
  2280. )
  2281. return queryset.filter(qs_filter)
  2282. class ConsoleConnectionFilterSet(ConnectionFilterSet):
  2283. class Meta:
  2284. model = ConsolePort
  2285. fields = ('name',)
  2286. class PowerConnectionFilterSet(ConnectionFilterSet):
  2287. class Meta:
  2288. model = PowerPort
  2289. fields = ('name',)
  2290. class InterfaceConnectionFilterSet(ConnectionFilterSet):
  2291. class Meta:
  2292. model = Interface
  2293. fields = tuple()