views.py 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320
  1. from __future__ import unicode_literals
  2. from django.contrib import messages
  3. from django.contrib.auth.mixins import PermissionRequiredMixin
  4. from django.db.models import Count
  5. from django.shortcuts import get_object_or_404, redirect, render
  6. from django.urls import reverse
  7. from django.views.generic import View
  8. from dcim.models import Device, Interface
  9. from dcim.tables import DeviceTable
  10. from utilities.views import (
  11. BulkDeleteView, BulkEditView, BulkImportView, ComponentCreateView, ComponentDeleteView, ComponentEditView,
  12. ObjectDeleteView, ObjectEditView, ObjectListView,
  13. )
  14. from .models import Cluster, ClusterGroup, ClusterType, VirtualMachine
  15. from . import filters
  16. from . import forms
  17. from . import tables
  18. #
  19. # Cluster types
  20. #
  21. class ClusterTypeListView(ObjectListView):
  22. queryset = ClusterType.objects.annotate(cluster_count=Count('clusters'))
  23. table = tables.ClusterTypeTable
  24. template_name = 'virtualization/clustertype_list.html'
  25. class ClusterTypeCreateView(PermissionRequiredMixin, ObjectEditView):
  26. permission_required = 'virtualization.add_clustertype'
  27. model = ClusterType
  28. form_class = forms.ClusterTypeForm
  29. def get_return_url(self, request, obj):
  30. return reverse('virtualization:clustertype_list')
  31. class ClusterTypeEditView(ClusterTypeCreateView):
  32. permission_required = 'virtualization.change_clustertype'
  33. class ClusterTypeBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
  34. permission_required = 'virtualization.delete_clustertype'
  35. cls = ClusterType
  36. queryset = ClusterType.objects.annotate(cluster_count=Count('clusters'))
  37. table = tables.ClusterTypeTable
  38. default_return_url = 'virtualization:clustertype_list'
  39. #
  40. # Cluster groups
  41. #
  42. class ClusterGroupListView(ObjectListView):
  43. queryset = ClusterGroup.objects.annotate(cluster_count=Count('clusters'))
  44. table = tables.ClusterGroupTable
  45. template_name = 'virtualization/clustergroup_list.html'
  46. class ClusterGroupCreateView(PermissionRequiredMixin, ObjectEditView):
  47. permission_required = 'virtualization.add_clustergroup'
  48. model = ClusterGroup
  49. form_class = forms.ClusterGroupForm
  50. def get_return_url(self, request, obj):
  51. return reverse('virtualization:clustergroup_list')
  52. class ClusterGroupEditView(ClusterGroupCreateView):
  53. permission_required = 'virtualization.change_clustergroup'
  54. class ClusterGroupBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
  55. permission_required = 'virtualization.delete_clustergroup'
  56. cls = ClusterGroup
  57. queryset = ClusterGroup.objects.annotate(cluster_count=Count('clusters'))
  58. table = tables.ClusterGroupTable
  59. default_return_url = 'virtualization:clustergroup_list'
  60. #
  61. # Clusters
  62. #
  63. class ClusterListView(ObjectListView):
  64. queryset = Cluster.objects.annotate(vm_count=Count('virtual_machines'))
  65. table = tables.ClusterTable
  66. filter = filters.ClusterFilter
  67. filter_form = forms.ClusterFilterForm
  68. template_name = 'virtualization/cluster_list.html'
  69. class ClusterView(View):
  70. def get(self, request, pk):
  71. cluster = get_object_or_404(Cluster, pk=pk)
  72. devices = Device.objects.filter(cluster=cluster).select_related(
  73. 'site', 'rack', 'tenant', 'device_type__manufacturer'
  74. )
  75. device_table = DeviceTable(list(devices), orderable=False)
  76. if request.user.has_perm('virtualization:change_cluster'):
  77. device_table.columns.show('pk')
  78. return render(request, 'virtualization/cluster.html', {
  79. 'cluster': cluster,
  80. 'device_table': device_table,
  81. })
  82. class ClusterCreateView(PermissionRequiredMixin, ObjectEditView):
  83. permission_required = 'virtualization.add_cluster'
  84. model = Cluster
  85. form_class = forms.ClusterForm
  86. class ClusterEditView(ClusterCreateView):
  87. permission_required = 'virtualization.change_cluster'
  88. class ClusterDeleteView(PermissionRequiredMixin, ObjectDeleteView):
  89. permission_required = 'virtualization.delete_cluster'
  90. model = Cluster
  91. default_return_url = 'virtualization:cluster_list'
  92. class ClusterBulkImportView(PermissionRequiredMixin, BulkImportView):
  93. permission_required = 'virtualization.add_cluster'
  94. model_form = forms.ClusterCSVForm
  95. table = tables.ClusterTable
  96. default_return_url = 'virtualization:cluster_list'
  97. class ClusterBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
  98. permission_required = 'virtualization.delete_cluster'
  99. cls = Cluster
  100. queryset = Cluster.objects.annotate(vm_count=Count('virtual_machines'))
  101. table = tables.ClusterTable
  102. default_return_url = 'virtualization:cluster_list'
  103. class ClusterAddDevicesView(PermissionRequiredMixin, View):
  104. permission_required = 'virtualization.change_cluster'
  105. form = forms.ClusterAddDevicesForm
  106. template_name = 'virtualization/cluster_add_devices.html'
  107. def get(self, request, pk):
  108. cluster = get_object_or_404(Cluster, pk=pk)
  109. form = self.form()
  110. return render(request, self.template_name, {
  111. 'cluster': cluster,
  112. 'form': form,
  113. 'return_url': reverse('virtualization:cluster', kwargs={'pk': pk}),
  114. })
  115. def post(self, request, pk):
  116. cluster = get_object_or_404(Cluster, pk=pk)
  117. form = self.form(request.POST)
  118. if form.is_valid():
  119. # Assign the selected Devices to the Cluster
  120. devices = form.cleaned_data['devices']
  121. Device.objects.filter(pk__in=devices).update(cluster=cluster)
  122. messages.success(request, "Added {} devices to cluster {}".format(
  123. len(devices), cluster
  124. ))
  125. return redirect(cluster.get_absolute_url())
  126. return render(request, self.template_name, {
  127. 'cluser': cluster,
  128. 'form': form,
  129. 'return_url': cluster.get_absolute_url(),
  130. })
  131. class ClusterRemoveDevicesView(PermissionRequiredMixin, View):
  132. permission_required = 'virtualization.change_cluster'
  133. form = forms.ClusterRemoveDevicesForm
  134. template_name = 'utilities/obj_bulk_remove.html'
  135. def post(self, request, pk):
  136. cluster = get_object_or_404(Cluster, pk=pk)
  137. if '_confirm' in request.POST:
  138. form = self.form(request.POST)
  139. if form.is_valid():
  140. # Remove the selected Devices from the Cluster
  141. devices = form.cleaned_data['pk']
  142. Device.objects.filter(pk__in=devices).update(cluster=None)
  143. messages.success(request, "Removed {} devices from cluster {}".format(
  144. len(devices), cluster
  145. ))
  146. return redirect(cluster.get_absolute_url())
  147. else:
  148. form = self.form(initial={'pk': request.POST.getlist('pk')})
  149. selected_objects = Device.objects.filter(pk__in=form.initial['pk'])
  150. device_table = DeviceTable(list(selected_objects), orderable=False)
  151. return render(request, self.template_name, {
  152. 'form': form,
  153. 'parent_obj': cluster,
  154. 'table': device_table,
  155. 'obj_type_plural': 'devices',
  156. 'return_url': cluster.get_absolute_url(),
  157. })
  158. #
  159. # Virtual machines
  160. #
  161. class VirtualMachineListView(ObjectListView):
  162. queryset = VirtualMachine.objects.select_related('tenant')
  163. filter = filters.VirtualMachineFilter
  164. filter_form = forms.VirtualMachineFilterForm
  165. table = tables.VirtualMachineTable
  166. template_name = 'virtualization/virtualmachine_list.html'
  167. class VirtualMachineView(View):
  168. def get(self, request, pk):
  169. vm = get_object_or_404(VirtualMachine.objects.select_related('tenant__group'), pk=pk)
  170. interfaces = Interface.objects.filter(virtual_machine=vm)
  171. return render(request, 'virtualization/virtualmachine.html', {
  172. 'vm': vm,
  173. 'interfaces': interfaces,
  174. })
  175. class VirtualMachineCreateView(PermissionRequiredMixin, ObjectEditView):
  176. permission_required = 'virtualization.add_virtualmachine'
  177. model = VirtualMachine
  178. form_class = forms.VirtualMachineForm
  179. template_name = 'virtualization/virtualmachine_edit.html'
  180. default_return_url = 'virtualization:virtualmachine_list'
  181. class VirtualMachineEditView(VirtualMachineCreateView):
  182. permission_required = 'virtualization.change_virtualmachine'
  183. class VirtualMachineDeleteView(PermissionRequiredMixin, ObjectDeleteView):
  184. permission_required = 'virtualization.delete_virtualmachine'
  185. model = VirtualMachine
  186. default_return_url = 'virtualization:virtualmachine_list'
  187. class VirtualMachineBulkImportView(PermissionRequiredMixin, BulkImportView):
  188. permission_required = 'virtualization.add_virtualmachine'
  189. model_form = forms.VirtualMachineCSVForm
  190. table = tables.VirtualMachineTable
  191. default_return_url = 'virtualization:virtualmachine_list'
  192. class VirtualMachineBulkEditView(PermissionRequiredMixin, BulkEditView):
  193. permission_required = 'virtualization.change_virtualmachine'
  194. cls = VirtualMachine
  195. queryset = VirtualMachine.objects.select_related('tenant')
  196. filter = filters.VirtualMachineFilter
  197. table = tables.VirtualMachineTable
  198. form = forms.VirtualMachineBulkEditForm
  199. default_return_url = 'virtualization:virtualmachine_list'
  200. #
  201. # VM interfaces
  202. #
  203. class InterfaceCreateView(PermissionRequiredMixin, ComponentCreateView):
  204. permission_required = 'dcim.add_interface'
  205. parent_model = VirtualMachine
  206. parent_field = 'virtual_machine'
  207. model = Interface
  208. form = forms.InterfaceCreateForm
  209. model_form = forms.InterfaceForm
  210. template_name = 'virtualization/virtualmachine_component_add.html'
  211. class InterfaceEditView(PermissionRequiredMixin, ComponentEditView):
  212. permission_required = 'dcim.change_interface'
  213. model = Interface
  214. parent_field = 'virtual_machine'
  215. form_class = forms.InterfaceForm
  216. class InterfaceDeleteView(PermissionRequiredMixin, ComponentDeleteView):
  217. permission_required = 'dcim.delete_interface'
  218. model = Interface
  219. parent_field = 'virtual_machine'
  220. class InterfaceBulkEditView(PermissionRequiredMixin, BulkEditView):
  221. permission_required = 'dcim.change_interface'
  222. cls = Interface
  223. parent_cls = VirtualMachine
  224. table = tables.InterfaceTable
  225. form = forms.InterfaceBulkEditForm
  226. class InterfaceBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
  227. permission_required = 'dcim.delete_interface'
  228. cls = Interface
  229. parent_cls = VirtualMachine
  230. table = tables.InterfaceTable