Browse Source

Finished bulk edit/delete views

Jeremy Stretch 7 years ago
parent
commit
ef2dd673ec

+ 1 - 1
netbox/templates/virtualization/cluster_list.html

@@ -17,7 +17,7 @@
 <h1>{% block title %}Clusters{% endblock %}</h1>
 <div class="row">
 	<div class="col-md-9">
-        {% include 'utilities/obj_table.html' %}
+        {% include 'utilities/obj_table.html' with bulk_edit_url='virtualization:cluster_bulk_edit' bulk_delete_url='virtualization:cluster_bulk_delete' %}
     </div>
     <div class="col-md-3">
 		{% include 'inc/search_panel.html' %}

+ 1 - 1
netbox/templates/virtualization/virtualmachine_list.html

@@ -17,7 +17,7 @@
 <h1>{% block title %}Virtual Machines{% endblock %}</h1>
 <div class="row">
 	<div class="col-md-9">
-        {% include 'utilities/obj_table.html' %}
+        {% include 'utilities/obj_table.html' with bulk_edit_url='virtualization:virtualmachine_bulk_edit' bulk_delete_url='virtualization:virtualmachine_bulk_delete' %}
     </div>
     <div class="col-md-3">
 		{% include 'inc/search_panel.html' %}

+ 18 - 4
netbox/virtualization/forms.py

@@ -13,8 +13,8 @@ from tenancy.forms import TenancyForm
 from tenancy.models import Tenant
 from utilities.forms import (
     APISelect, APISelectMultiple, BootstrapMixin, BulkEditForm, BulkEditNullBooleanSelect, ChainedFieldsMixin,
-    ChainedModelChoiceField, ChainedModelMultipleChoiceField, ComponentForm, ConfirmationForm, ExpandableNameField,
-    FilterChoiceField, SlugField,
+    ChainedModelChoiceField, ChainedModelMultipleChoiceField, CommentField, ComponentForm, ConfirmationForm,
+    ExpandableNameField, FilterChoiceField, SlugField, SmallTextarea,
 )
 from .models import Cluster, ClusterGroup, ClusterType, VirtualMachine
 
@@ -78,6 +78,15 @@ class ClusterCSVForm(forms.ModelForm):
         fields = ['name', 'type', 'group']
 
 
+class ClusterBulkEditForm(BootstrapMixin, CustomFieldBulkEditForm):
+    pk = forms.ModelMultipleChoiceField(queryset=Cluster.objects.all(), widget=forms.MultipleHiddenInput)
+    type = forms.ModelChoiceField(queryset=ClusterType.objects.all(), required=False)
+    group = forms.ModelChoiceField(queryset=ClusterGroup.objects.all(), required=False)
+
+    class Meta:
+        nullable_fields = ['group']
+
+
 class ClusterFilterForm(BootstrapMixin, CustomFieldFilterForm):
     model = Cluster
     q = forms.CharField(required=False, label='Search')
@@ -226,11 +235,16 @@ class VirtualMachineCSVForm(forms.ModelForm):
 
 class VirtualMachineBulkEditForm(BootstrapMixin, CustomFieldBulkEditForm):
     pk = forms.ModelMultipleChoiceField(queryset=VirtualMachine.objects.all(), widget=forms.MultipleHiddenInput)
-    cluster = forms.ModelChoiceField(queryset=Cluster.objects.all(), required=False, label='Cluster')
+    cluster = forms.ModelChoiceField(queryset=Cluster.objects.all(), required=False)
     tenant = forms.ModelChoiceField(queryset=Tenant.objects.all(), required=False)
+    platform = forms.ModelChoiceField(queryset=Platform.objects.all(), required=False)
+    vcpus = forms.IntegerField(required=False, label='vCPUs')
+    memory = forms.IntegerField(required=False, label='Memory (MB)')
+    disk = forms.IntegerField(required=False, label='Disk (GB)')
+    comments = CommentField(widget=SmallTextarea)
 
     class Meta:
-        nullable_fields = ['tenant']
+        nullable_fields = ['tenant', 'platform', 'vcpus', 'memory', 'disk']
 
 
 class VirtualMachineFilterForm(BootstrapMixin, CustomFieldFilterForm):

+ 4 - 2
netbox/virtualization/urls.py

@@ -25,7 +25,8 @@ urlpatterns = [
     url(r'^clusters/$', views.ClusterListView.as_view(), name='cluster_list'),
     url(r'^clusters/add/$', views.ClusterCreateView.as_view(), name='cluster_add'),
     url(r'^clusters/import/$', views.ClusterBulkImportView.as_view(), name='cluster_import'),
-    # url(r'^clusters/edit/$', views.ClusterBulkEditView.as_view(), name='cluster_bulk_edit'),
+    url(r'^clusters/edit/$', views.ClusterBulkEditView.as_view(), name='cluster_bulk_edit'),
+    url(r'^clusters/delete/$', views.ClusterBulkDeleteView.as_view(), name='cluster_bulk_delete'),
     url(r'^clusters/(?P<pk>\d+)/$', views.ClusterView.as_view(), name='cluster'),
     url(r'^clusters/(?P<pk>\d+)/edit/$', views.ClusterEditView.as_view(), name='cluster_edit'),
     url(r'^clusters/(?P<pk>\d+)/delete/$', views.ClusterDeleteView.as_view(), name='cluster_delete'),
@@ -36,7 +37,8 @@ urlpatterns = [
     url(r'^virtual-machines/$', views.VirtualMachineListView.as_view(), name='virtualmachine_list'),
     url(r'^virtual-machines/add/$', views.VirtualMachineCreateView.as_view(), name='virtualmachine_add'),
     url(r'^virtual-machines/import/$', views.VirtualMachineBulkImportView.as_view(), name='virtualmachine_import'),
-    # url(r'^virtual-machines/edit/$', views.VirtualMachineBulkEditView.as_view(), name='virtualmachine_bulk_edit'),
+    url(r'^virtual-machines/edit/$', views.VirtualMachineBulkEditView.as_view(), name='virtualmachine_bulk_edit'),
+    url(r'^virtual-machines/delete/$', views.VirtualMachineBulkDeleteView.as_view(), name='virtualmachine_bulk_delete'),
     url(r'^virtual-machines/(?P<pk>\d+)/$', views.VirtualMachineView.as_view(), name='virtualmachine'),
     url(r'^virtual-machines/(?P<pk>\d+)/edit/$', views.VirtualMachineEditView.as_view(), name='virtualmachine_edit'),
     url(r'^virtual-machines/(?P<pk>\d+)/delete/$', views.VirtualMachineDeleteView.as_view(), name='virtualmachine_delete'),

+ 23 - 3
netbox/virtualization/views.py

@@ -138,10 +138,22 @@ class ClusterBulkImportView(PermissionRequiredMixin, BulkImportView):
     default_return_url = 'virtualization:cluster_list'
 
 
+class ClusterBulkEditView(PermissionRequiredMixin, BulkEditView):
+    permission_required = 'virtualization.change_cluster'
+    cls = Cluster
+    filter = filters.ClusterFilter
+    table = tables.ClusterTable
+    form = forms.ClusterBulkEditForm
+    default_return_url = 'virtualization:cluster_list'
+
+
 class ClusterBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
     permission_required = 'virtualization.delete_cluster'
     cls = Cluster
-    queryset = Cluster.objects.annotate(vm_count=Count('virtual_machines'))
+    queryset = Cluster.objects.annotate(
+        device_count=Count('devices', distinct=True),
+        vm_count=Count('virtual_machines', distinct=True)
+    )
     table = tables.ClusterTable
     default_return_url = 'virtualization:cluster_list'
 
@@ -227,7 +239,7 @@ class ClusterRemoveDevicesView(PermissionRequiredMixin, View):
 #
 
 class VirtualMachineListView(ObjectListView):
-    queryset = VirtualMachine.objects.select_related('tenant')
+    queryset = VirtualMachine.objects.select_related('cluster', 'tenant')
     filter = filters.VirtualMachineFilter
     filter_form = forms.VirtualMachineFilterForm
     table = tables.VirtualMachineTable
@@ -277,13 +289,21 @@ class VirtualMachineBulkImportView(PermissionRequiredMixin, BulkImportView):
 class VirtualMachineBulkEditView(PermissionRequiredMixin, BulkEditView):
     permission_required = 'virtualization.change_virtualmachine'
     cls = VirtualMachine
-    queryset = VirtualMachine.objects.select_related('tenant')
+    queryset = VirtualMachine.objects.select_related('cluster', 'tenant')
     filter = filters.VirtualMachineFilter
     table = tables.VirtualMachineTable
     form = forms.VirtualMachineBulkEditForm
     default_return_url = 'virtualization:virtualmachine_list'
 
 
+class VirtualMachineBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
+    permission_required = 'virtualization.delete_virtualmachine'
+    cls = VirtualMachine
+    queryset = VirtualMachine.objects.select_related('cluster', 'tenant')
+    table = tables.VirtualMachineTable
+    default_return_url = 'virtualization:virtualmachine_list'
+
+
 #
 # VM interfaces
 #