mirror of
https://github.com/netbox-community/netbox.git
synced 2025-07-25 18:08:38 -06:00
Show virtual machines on Cluster page
This commit is contained in:
parent
e7f64334c0
commit
cfb81a8a01
@ -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">
|
||||
|
@ -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 %}
|
@ -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
|
||||
#
|
||||
|
@ -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'),
|
||||
|
@ -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
|
||||
#
|
||||
|
Loading…
Reference in New Issue
Block a user