Show virtual machines on Cluster page

This commit is contained in:
Marcus Furlong 2020-12-07 19:02:58 -05:00
parent e7f64334c0
commit cfb81a8a01
5 changed files with 129 additions and 2 deletions

View File

@ -151,8 +151,25 @@
</form>
{% endif %}
</div>
<div class="panel panel-default">
<div class="panel-heading">
<strong>Virtual Machines</strong>
</div>
{% include 'responsive_table.html' with table=virtual_machine_table %}
{% if perms.virtualization.change_cluster %}
<div class="panel-footer noprint">
<div class="pull-right">
<a href="{% url 'virtualization:cluster_add_virtualmachines' pk=cluster.pk %}?site={{ cluster.site.pk }}" class="btn btn-primary btn-xs">
<span class="glyphicon glyphicon-plus" aria-hidden="true"></span>
Add virtual machines
</a>
</div>
<div class="clearfix"></div>
</div>
{% endif %}
</div>
{% plugin_right_page cluster %}
</div>
</div>
</div>
<div class="row">
<div class="col-md-12">

View File

@ -0,0 +1,37 @@
{% extends 'base.html' %}
{% load static %}
{% load form_helpers %}
{% block content %}
<form action="." method="post" class="form form-horizontal">
{% csrf_token %}
{% for field in form.hidden_fields %}
{{ field }}
{% endfor %}
<div class="row">
<div class="col-md-6 col-md-offset-3">
<h3>{% block title %}Add Virtual Machines to Cluster {{ cluster }}{% endblock %}</h3>
{% if form.non_field_errors %}
<div class="panel panel-danger">
<div class="panel-heading"><strong>Errors</strong></div>
<div class="panel-body">
{{ form.non_field_errors }}
</div>
</div>
{% endif %}
<div class="panel panel-default">
<div class="panel-heading"><strong>Virtual Machine Selection</strong></div>
<div class="panel-body">
{% render_form form %}
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-md-6 col-md-offset-3 text-right noprint">
<button type="submit" name="_add" class="btn btn-primary">Add Virtual Machines</button>
<a href="{{ return_url }}" class="btn btn-default">Cancel</a>
</div>
</div>
</form>
{% endblock %}

View File

@ -276,6 +276,28 @@ class ClusterRemoveDevicesForm(ConfirmationForm):
)
class ClusterAddVirtualMachinesForm(BootstrapMixin, forms.Form):
virtualmachines = DynamicModelMultipleChoiceField(
queryset=VirtualMachine.objects.all(),
)
class Meta:
fields = [
'virtualmachines',
]
def __init__(self, cluster, *args, **kwargs):
self.cluster = cluster
super().__init__(*args, **kwargs)
self.fields['virtualmachines'].choices = []
def clean(self):
super().clean()
#
# Virtual Machines
#

View File

@ -38,6 +38,7 @@ urlpatterns = [
path('clusters/<int:pk>/changelog/', ObjectChangeLogView.as_view(), name='cluster_changelog', kwargs={'model': Cluster}),
path('clusters/<int:pk>/devices/add/', views.ClusterAddDevicesView.as_view(), name='cluster_add_devices'),
path('clusters/<int:pk>/devices/remove/', views.ClusterRemoveDevicesView.as_view(), name='cluster_remove_devices'),
path('clusters/<int:pk>/virtual-machines/add/', views.ClusterAddVirtualMachinesView.as_view(), name='cluster_add_virtualmachines'),
# Virtual machines
path('virtual-machines/', views.VirtualMachineListView.as_view(), name='virtualmachine_list'),

View File

@ -14,6 +14,7 @@ from utilities.views import (
BulkComponentCreateView, BulkDeleteView, BulkEditView, BulkImportView, BulkRenameView, ComponentCreateView,
ObjectView, ObjectDeleteView, ObjectEditView, ObjectListView,
)
from virtualization.tables import VirtualMachineTable
from . import filters, forms, tables
from .models import Cluster, ClusterGroup, ClusterType, VirtualMachine, VMInterface
@ -103,11 +104,18 @@ class ClusterView(ObjectView):
queryset = Cluster.objects.all()
def get(self, request, pk):
virtual_machines = VirtualMachine.objects.restrict(request.user)
self.queryset = self.queryset.prefetch_related(
Prefetch('virtual_machines', queryset=VirtualMachine.objects.restrict(request.user))
Prefetch('virtual_machines', queryset=virtual_machines)
)
cluster = get_object_or_404(self.queryset, pk=pk)
virtual_machine_table = VirtualMachineTable(list(virtual_machines.filter(cluster=cluster)), orderable=False)
if request.user.has_perm('virtualization.change_cluster'):
virtual_machine_table.columns.show('pk')
devices = Device.objects.restrict(request.user, 'view').filter(cluster=cluster).prefetch_related(
'site', 'rack', 'tenant', 'device_type__manufacturer'
)
@ -118,6 +126,7 @@ class ClusterView(ObjectView):
return render(request, 'virtualization/cluster.html', {
'cluster': cluster,
'device_table': device_table,
'virtual_machine_table': virtual_machine_table,
})
@ -232,6 +241,47 @@ class ClusterRemoveDevicesView(ObjectEditView):
})
class ClusterAddVirtualMachinesView(ObjectEditView):
queryset = Cluster.objects.all()
form = forms.ClusterAddVirtualMachinesForm
template_name = 'virtualization/cluster_add_virtualmachines.html'
def get(self, request, pk):
cluster = get_object_or_404(self.queryset, pk=pk)
form = self.form(cluster, initial=request.GET)
return render(request, self.template_name, {
'cluster': cluster,
'form': form,
'return_url': reverse('virtualization:cluster', kwargs={'pk': pk}),
})
def post(self, request, pk):
cluster = get_object_or_404(self.queryset, pk=pk)
form = self.form(cluster, request.POST)
if form.is_valid():
virtualmachine_pks = form.cleaned_data['virtualmachines']
with transaction.atomic():
# Assign the selected VirtualMachines to the Cluster
for virtualmachine in VirtualMachine.objects.filter(pk__in=virtualmachine_pks):
virtualmachine.cluster = cluster
virtualmachine.save()
messages.success(request, "Added {} virtual machines to cluster {}".format(
len(virtualmachine_pks), cluster
))
return redirect(cluster.get_absolute_url())
return render(request, self.template_name, {
'cluster': cluster,
'form': form,
'return_url': cluster.get_absolute_url(),
})
#
# Virtual machines
#