filters.py 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371
  1. import django_filters
  2. from netaddr import IPNetwork
  3. from netaddr.core import AddrFormatError
  4. from django.db.models import Q
  5. from dcim.models import Site, Device, Interface
  6. from extras.filters import CustomFieldFilterSet
  7. from tenancy.models import Tenant
  8. from utilities.filters import NullableModelMultipleChoiceFilter, NumericInFilter
  9. from .models import Aggregate, IPAddress, Prefix, RIR, Role, Service, VLAN, VLANGroup, VRF
  10. class VRFFilter(CustomFieldFilterSet, django_filters.FilterSet):
  11. id__in = NumericInFilter(name='id', lookup_expr='in')
  12. q = django_filters.CharFilter(
  13. method='search',
  14. label='Search',
  15. )
  16. tenant_id = NullableModelMultipleChoiceFilter(
  17. name='tenant',
  18. queryset=Tenant.objects.all(),
  19. label='Tenant (ID)',
  20. )
  21. tenant = NullableModelMultipleChoiceFilter(
  22. name='tenant',
  23. queryset=Tenant.objects.all(),
  24. to_field_name='slug',
  25. label='Tenant (slug)',
  26. )
  27. def search(self, queryset, name, value):
  28. if not value.strip():
  29. return queryset
  30. return queryset.filter(
  31. Q(name__icontains=value) |
  32. Q(rd__icontains=value) |
  33. Q(description__icontains=value)
  34. )
  35. class Meta:
  36. model = VRF
  37. fields = ['name', 'rd']
  38. class RIRFilter(django_filters.FilterSet):
  39. id__in = NumericInFilter(name='id', lookup_expr='in')
  40. class Meta:
  41. model = RIR
  42. fields = ['is_private']
  43. class AggregateFilter(CustomFieldFilterSet, django_filters.FilterSet):
  44. id__in = NumericInFilter(name='id', lookup_expr='in')
  45. q = django_filters.CharFilter(
  46. method='search',
  47. label='Search',
  48. )
  49. rir_id = django_filters.ModelMultipleChoiceFilter(
  50. name='rir',
  51. queryset=RIR.objects.all(),
  52. label='RIR (ID)',
  53. )
  54. rir = django_filters.ModelMultipleChoiceFilter(
  55. name='rir__slug',
  56. queryset=RIR.objects.all(),
  57. to_field_name='slug',
  58. label='RIR (slug)',
  59. )
  60. class Meta:
  61. model = Aggregate
  62. fields = ['family', 'date_added']
  63. def search(self, queryset, name, value):
  64. if not value.strip():
  65. return queryset
  66. qs_filter = Q(description__icontains=value)
  67. try:
  68. prefix = str(IPNetwork(value.strip()).cidr)
  69. qs_filter |= Q(prefix__net_contains_or_equals=prefix)
  70. except AddrFormatError:
  71. pass
  72. return queryset.filter(qs_filter)
  73. class PrefixFilter(CustomFieldFilterSet, django_filters.FilterSet):
  74. id__in = NumericInFilter(name='id', lookup_expr='in')
  75. q = django_filters.CharFilter(
  76. method='search',
  77. label='Search',
  78. )
  79. parent = django_filters.CharFilter(
  80. method='search_by_parent',
  81. label='Parent prefix',
  82. )
  83. mask_length = django_filters.NumberFilter(
  84. method='filter_mask_length',
  85. label='Mask length',
  86. )
  87. vrf_id = NullableModelMultipleChoiceFilter(
  88. name='vrf_id',
  89. queryset=VRF.objects.all(),
  90. label='VRF',
  91. )
  92. vrf = NullableModelMultipleChoiceFilter(
  93. name='vrf',
  94. queryset=VRF.objects.all(),
  95. to_field_name='rd',
  96. label='VRF (RD)',
  97. )
  98. tenant_id = NullableModelMultipleChoiceFilter(
  99. name='tenant',
  100. queryset=Tenant.objects.all(),
  101. label='Tenant (ID)',
  102. )
  103. tenant = NullableModelMultipleChoiceFilter(
  104. name='tenant',
  105. queryset=Tenant.objects.all(),
  106. to_field_name='slug',
  107. label='Tenant (slug)',
  108. )
  109. site_id = NullableModelMultipleChoiceFilter(
  110. name='site',
  111. queryset=Site.objects.all(),
  112. label='Site (ID)',
  113. )
  114. site = NullableModelMultipleChoiceFilter(
  115. name='site',
  116. queryset=Site.objects.all(),
  117. to_field_name='slug',
  118. label='Site (slug)',
  119. )
  120. vlan_id = NullableModelMultipleChoiceFilter(
  121. name='vlan',
  122. queryset=VLAN.objects.all(),
  123. label='VLAN (ID)',
  124. )
  125. vlan_vid = django_filters.NumberFilter(
  126. name='vlan__vid',
  127. label='VLAN number (1-4095)',
  128. )
  129. role_id = NullableModelMultipleChoiceFilter(
  130. name='role',
  131. queryset=Role.objects.all(),
  132. label='Role (ID)',
  133. )
  134. role = NullableModelMultipleChoiceFilter(
  135. name='role',
  136. queryset=Role.objects.all(),
  137. to_field_name='slug',
  138. label='Role (slug)',
  139. )
  140. class Meta:
  141. model = Prefix
  142. fields = ['family', 'status']
  143. def search(self, queryset, name, value):
  144. if not value.strip():
  145. return queryset
  146. qs_filter = Q(description__icontains=value)
  147. try:
  148. prefix = str(IPNetwork(value.strip()).cidr)
  149. qs_filter |= Q(prefix__net_contains_or_equals=prefix)
  150. except AddrFormatError:
  151. pass
  152. return queryset.filter(qs_filter)
  153. def search_by_parent(self, queryset, name, value):
  154. value = value.strip()
  155. if not value:
  156. return queryset
  157. try:
  158. query = str(IPNetwork(value).cidr)
  159. return queryset.filter(prefix__net_contained_or_equal=query)
  160. except AddrFormatError:
  161. return queryset.none()
  162. def filter_mask_length(self, queryset, name, value):
  163. if not value:
  164. return queryset
  165. return queryset.filter(prefix__net_mask_length=value)
  166. class IPAddressFilter(CustomFieldFilterSet, django_filters.FilterSet):
  167. id__in = NumericInFilter(name='id', lookup_expr='in')
  168. q = django_filters.CharFilter(
  169. method='search',
  170. label='Search',
  171. )
  172. parent = django_filters.CharFilter(
  173. method='search_by_parent',
  174. label='Parent prefix',
  175. )
  176. mask_length = django_filters.NumberFilter(
  177. method='filter_mask_length',
  178. label='Mask length',
  179. )
  180. vrf_id = NullableModelMultipleChoiceFilter(
  181. name='vrf_id',
  182. queryset=VRF.objects.all(),
  183. label='VRF',
  184. )
  185. vrf = NullableModelMultipleChoiceFilter(
  186. name='vrf',
  187. queryset=VRF.objects.all(),
  188. to_field_name='rd',
  189. label='VRF (RD)',
  190. )
  191. tenant_id = NullableModelMultipleChoiceFilter(
  192. name='tenant',
  193. queryset=Tenant.objects.all(),
  194. label='Tenant (ID)',
  195. )
  196. tenant = NullableModelMultipleChoiceFilter(
  197. name='tenant',
  198. queryset=Tenant.objects.all(),
  199. to_field_name='slug',
  200. label='Tenant (slug)',
  201. )
  202. device_id = django_filters.ModelMultipleChoiceFilter(
  203. name='interface__device',
  204. queryset=Device.objects.all(),
  205. label='Device (ID)',
  206. )
  207. device = django_filters.ModelMultipleChoiceFilter(
  208. name='interface__device__name',
  209. queryset=Device.objects.all(),
  210. to_field_name='name',
  211. label='Device (name)',
  212. )
  213. interface_id = django_filters.ModelMultipleChoiceFilter(
  214. name='interface',
  215. queryset=Interface.objects.all(),
  216. label='Interface (ID)',
  217. )
  218. class Meta:
  219. model = IPAddress
  220. fields = ['family', 'status']
  221. def search(self, queryset, name, value):
  222. if not value.strip():
  223. return queryset
  224. qs_filter = Q(description__icontains=value)
  225. try:
  226. ipaddress = str(IPNetwork(value.strip()))
  227. qs_filter |= Q(address__net_host=ipaddress)
  228. except AddrFormatError:
  229. pass
  230. return queryset.filter(qs_filter)
  231. def search_by_parent(self, queryset, name, value):
  232. value = value.strip()
  233. if not value:
  234. return queryset
  235. try:
  236. query = str(IPNetwork(value.strip()).cidr)
  237. return queryset.filter(address__net_host_contained=query)
  238. except AddrFormatError:
  239. return queryset.none()
  240. def filter_mask_length(self, queryset, name, value):
  241. if not value:
  242. return queryset
  243. return queryset.filter(address__net_mask_length=value)
  244. class VLANGroupFilter(django_filters.FilterSet):
  245. site_id = NullableModelMultipleChoiceFilter(
  246. name='site',
  247. queryset=Site.objects.all(),
  248. label='Site (ID)',
  249. )
  250. site = NullableModelMultipleChoiceFilter(
  251. name='site',
  252. queryset=Site.objects.all(),
  253. to_field_name='slug',
  254. label='Site (slug)',
  255. )
  256. class Meta:
  257. model = VLANGroup
  258. fields = ['name']
  259. class VLANFilter(CustomFieldFilterSet, django_filters.FilterSet):
  260. id__in = NumericInFilter(name='id', lookup_expr='in')
  261. q = django_filters.CharFilter(
  262. method='search',
  263. label='Search',
  264. )
  265. site_id = NullableModelMultipleChoiceFilter(
  266. name='site',
  267. queryset=Site.objects.all(),
  268. label='Site (ID)',
  269. )
  270. site = NullableModelMultipleChoiceFilter(
  271. name='site',
  272. queryset=Site.objects.all(),
  273. to_field_name='slug',
  274. label='Site (slug)',
  275. )
  276. group_id = NullableModelMultipleChoiceFilter(
  277. name='group',
  278. queryset=VLANGroup.objects.all(),
  279. label='Group (ID)',
  280. )
  281. group = NullableModelMultipleChoiceFilter(
  282. name='group',
  283. queryset=VLANGroup.objects.all(),
  284. to_field_name='slug',
  285. label='Group',
  286. )
  287. tenant_id = NullableModelMultipleChoiceFilter(
  288. name='tenant',
  289. queryset=Tenant.objects.all(),
  290. label='Tenant (ID)',
  291. )
  292. tenant = NullableModelMultipleChoiceFilter(
  293. name='tenant',
  294. queryset=Tenant.objects.all(),
  295. to_field_name='slug',
  296. label='Tenant (slug)',
  297. )
  298. role_id = NullableModelMultipleChoiceFilter(
  299. name='role',
  300. queryset=Role.objects.all(),
  301. label='Role (ID)',
  302. )
  303. role = NullableModelMultipleChoiceFilter(
  304. name='role',
  305. queryset=Role.objects.all(),
  306. to_field_name='slug',
  307. label='Role (slug)',
  308. )
  309. class Meta:
  310. model = VLAN
  311. fields = ['name', 'vid', 'status']
  312. def search(self, queryset, name, value):
  313. if not value.strip():
  314. return queryset
  315. qs_filter = Q(name__icontains=value) | Q(description__icontains=value)
  316. try:
  317. qs_filter |= Q(vid=int(value.strip()))
  318. except ValueError:
  319. pass
  320. return queryset.filter(qs_filter)
  321. class ServiceFilter(django_filters.FilterSet):
  322. device_id = django_filters.ModelMultipleChoiceFilter(
  323. name='device',
  324. queryset=Device.objects.all(),
  325. label='Device (ID)',
  326. )
  327. device = django_filters.ModelMultipleChoiceFilter(
  328. name='device__name',
  329. queryset=Device.objects.all(),
  330. to_field_name='name',
  331. label='Device (name)',
  332. )
  333. class Meta:
  334. model = Service
  335. fields = ['name', 'protocol', 'port']