mirror of
https://github.com/netbox-community/netbox.git
synced 2025-07-23 04:22:01 -06:00
Added virtualization filters
This commit is contained in:
parent
4ef55502b4
commit
9acd792abe
@ -17,7 +17,7 @@
|
|||||||
<input type="text" name="q" class="form-control" placeholder="Search virtual machines" />
|
<input type="text" name="q" class="form-control" placeholder="Search virtual machines" />
|
||||||
<span class="input-group-btn">
|
<span class="input-group-btn">
|
||||||
<button type="submit" class="btn btn-primary">
|
<button type="submit" class="btn btn-primary">
|
||||||
<span class="fa fa-search" aria-hidden="true"></span>
|
<span class="fa fa-search"></span>
|
||||||
</button>
|
</button>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
@ -27,13 +27,13 @@
|
|||||||
<div class="pull-right">
|
<div class="pull-right">
|
||||||
{% if perms.virtualization.change_virtualmachine %}
|
{% if perms.virtualization.change_virtualmachine %}
|
||||||
<a href="{% url 'virtualization:virtualmachine_edit' pk=vm.pk %}" class="btn btn-warning">
|
<a href="{% url 'virtualization:virtualmachine_edit' pk=vm.pk %}" class="btn btn-warning">
|
||||||
<span class="fa fa-pencil" aria-hidden="true"></span>
|
<span class="fa fa-pencil"></span>
|
||||||
Edit this VM
|
Edit this VM
|
||||||
</a>
|
</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if perms.virtualization.delete_virtualmachine %}
|
{% if perms.virtualization.delete_virtualmachine %}
|
||||||
<a href="{% url 'virtualization:virtualmachine_delete' pk=vm.pk %}" class="btn btn-danger">
|
<a href="{% url 'virtualization:virtualmachine_delete' pk=vm.pk %}" class="btn btn-danger">
|
||||||
<span class="fa fa-trash" aria-hidden="true"></span>
|
<span class="fa fa-trash"></span>
|
||||||
Delete this VM
|
Delete this VM
|
||||||
</a>
|
</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
@ -53,7 +53,68 @@
|
|||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Cluster</td>
|
<td>Cluster</td>
|
||||||
<td><a href="{{ vm.cluster.get_absolute_url }}">{{ vm.cluster }}</a></td>
|
<td>
|
||||||
|
{% if vm.cluster.group %}
|
||||||
|
<a href="{{ vm.cluster.group.get_absolute_url }}">{{ vm.cluster.group }}</a>
|
||||||
|
<i class="fa fa-angle-right"></i>
|
||||||
|
{% endif %}
|
||||||
|
<a href="{{ vm.cluster.get_absolute_url }}">{{ vm.cluster }}</a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Cluster Type</td>
|
||||||
|
<td>{{ vm.cluster.type }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Tenant</td>
|
||||||
|
<td>
|
||||||
|
{% if vm.tenant %}
|
||||||
|
{% if vm.tenant.group %}
|
||||||
|
<a href="{{ vm.tenant.group.get_absolute_url }}">{{ vm.tenant.group.name }}</a>
|
||||||
|
<i class="fa fa-angle-right"></i>
|
||||||
|
{% endif %}
|
||||||
|
<a href="{{ vm.tenant.get_absolute_url }}">{{ vm.tenant }}</a>
|
||||||
|
{% else %}
|
||||||
|
<span class="text-muted">None</span>
|
||||||
|
{% endif %}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
<div class="panel panel-default">
|
||||||
|
<div class="panel-heading">
|
||||||
|
<strong>Resources</strong>
|
||||||
|
</div>
|
||||||
|
<table class="table table-hover panel-body attr-table">
|
||||||
|
<tr>
|
||||||
|
<td>Virtual CPUs</td>
|
||||||
|
<td>
|
||||||
|
{% if vm.vcpus %}
|
||||||
|
{{ vm.vcpus }}
|
||||||
|
{% else %}
|
||||||
|
<span class="text-muted">N/A</span>
|
||||||
|
{% endif %}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Memory</td>
|
||||||
|
<td>
|
||||||
|
{% if vm.memory %}
|
||||||
|
{{ vm.memory }} MB
|
||||||
|
{% else %}
|
||||||
|
<span class="text-muted">N/A</span>
|
||||||
|
{% endif %}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Disk Space</td>
|
||||||
|
<td>
|
||||||
|
{% if vm.disk %}
|
||||||
|
{{ vm.disk }} GB
|
||||||
|
{% else %}
|
||||||
|
<span class="text-muted">N/A</span>
|
||||||
|
{% endif %}
|
||||||
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
@ -6,13 +6,17 @@
|
|||||||
<div class="panel-heading"><strong>Virtual Machine</strong></div>
|
<div class="panel-heading"><strong>Virtual Machine</strong></div>
|
||||||
<div class="panel-body">
|
<div class="panel-body">
|
||||||
{% render_field form.name %}
|
{% render_field form.name %}
|
||||||
|
{% render_field form.cluster_group %}
|
||||||
|
{% render_field form.cluster %}
|
||||||
{% render_field form.platform %}
|
{% render_field form.platform %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="panel panel-default">
|
<div class="panel panel-default">
|
||||||
<div class="panel-heading"><strong>Cluster</strong></div>
|
<div class="panel-heading"><strong>Resources</strong></div>
|
||||||
<div class="panel-body">
|
<div class="panel-body">
|
||||||
{% render_field form.cluster %}
|
{% render_field form.vcpus %}
|
||||||
|
{% render_field form.memory %}
|
||||||
|
{% render_field form.disk %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="panel panel-default">
|
<div class="panel panel-default">
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
Import virtual machines
|
Import virtual machines
|
||||||
</a>
|
</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% include 'inc/export_button.html' with obj_type='virtualmachines' %}
|
{% include 'inc/export_button.html' with obj_type='virtual machines' %}
|
||||||
</div>
|
</div>
|
||||||
<h1>{% block title %}Virtual Machines{% endblock %}</h1>
|
<h1>{% block title %}Virtual Machines{% endblock %}</h1>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
@ -24,3 +24,32 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block javascript %}
|
||||||
|
<script type="text/javascript">
|
||||||
|
$(document).ready(function() {
|
||||||
|
|
||||||
|
var cluster_group_list = $('#id_cluster_group');
|
||||||
|
var cluster_list = $('#id_cluster_id');
|
||||||
|
|
||||||
|
// Update cluster options based on selected group
|
||||||
|
cluster_group_list.change(function() {
|
||||||
|
var selected_groups = $(this).val();
|
||||||
|
if (selected_groups) {
|
||||||
|
cluster_list.empty();
|
||||||
|
$.ajax({
|
||||||
|
url: netbox_api_path + 'virtualization/clusters/?limit=500&group=' + selected_groups.join('&group='),
|
||||||
|
dataType: 'json',
|
||||||
|
success: function (response, status) {
|
||||||
|
$.each(response["results"], function (index, cluster) {
|
||||||
|
var option = $("<option></option>").attr("value", cluster.id).text(cluster.name);
|
||||||
|
cluster_list.append(option);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
{% endblock %}
|
||||||
|
@ -4,6 +4,7 @@ from rest_framework.viewsets import ModelViewSet
|
|||||||
|
|
||||||
from extras.api.views import CustomFieldModelViewSet
|
from extras.api.views import CustomFieldModelViewSet
|
||||||
from utilities.api import WritableSerializerMixin
|
from utilities.api import WritableSerializerMixin
|
||||||
|
from virtualization import filters
|
||||||
from virtualization.models import Cluster, ClusterGroup, ClusterType, VirtualMachine, VMInterface
|
from virtualization.models import Cluster, ClusterGroup, ClusterType, VirtualMachine, VMInterface
|
||||||
from . import serializers
|
from . import serializers
|
||||||
|
|
||||||
@ -26,6 +27,7 @@ class ClusterViewSet(WritableSerializerMixin, CustomFieldModelViewSet):
|
|||||||
queryset = Cluster.objects.select_related('type', 'group')
|
queryset = Cluster.objects.select_related('type', 'group')
|
||||||
serializer_class = serializers.ClusterSerializer
|
serializer_class = serializers.ClusterSerializer
|
||||||
write_serializer_class = serializers.WritableClusterSerializer
|
write_serializer_class = serializers.WritableClusterSerializer
|
||||||
|
filter_class = filters.ClusterFilter
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
@ -36,6 +38,7 @@ class VirtualMachineViewSet(WritableSerializerMixin, CustomFieldModelViewSet):
|
|||||||
queryset = VirtualMachine.objects.all()
|
queryset = VirtualMachine.objects.all()
|
||||||
serializer_class = serializers.VirtualMachineSerializer
|
serializer_class = serializers.VirtualMachineSerializer
|
||||||
write_serializer_class = serializers.WritableVirtualMachineSerializer
|
write_serializer_class = serializers.WritableVirtualMachineSerializer
|
||||||
|
filter_class = filters.VirtualMachineFilter
|
||||||
|
|
||||||
|
|
||||||
class VMInterfaceViewSet(WritableSerializerMixin, ModelViewSet):
|
class VMInterfaceViewSet(WritableSerializerMixin, ModelViewSet):
|
||||||
|
99
netbox/virtualization/filters.py
Normal file
99
netbox/virtualization/filters.py
Normal file
@ -0,0 +1,99 @@
|
|||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
import django_filters
|
||||||
|
from django.db.models import Q
|
||||||
|
|
||||||
|
from dcim.models import Platform
|
||||||
|
from extras.filters import CustomFieldFilterSet
|
||||||
|
from tenancy.models import Tenant
|
||||||
|
from utilities.filters import NullableModelMultipleChoiceFilter, NumericInFilter
|
||||||
|
from .models import Cluster, ClusterGroup, ClusterType, VirtualMachine
|
||||||
|
|
||||||
|
|
||||||
|
class ClusterFilter(CustomFieldFilterSet):
|
||||||
|
id__in = NumericInFilter(name='id', lookup_expr='in')
|
||||||
|
q = django_filters.CharFilter(
|
||||||
|
method='search',
|
||||||
|
label='Search',
|
||||||
|
)
|
||||||
|
group_id = NullableModelMultipleChoiceFilter(
|
||||||
|
queryset=ClusterGroup.objects.all(),
|
||||||
|
label='Parent group (ID)',
|
||||||
|
)
|
||||||
|
group = NullableModelMultipleChoiceFilter(
|
||||||
|
queryset=ClusterGroup.objects.all(),
|
||||||
|
to_field_name='slug',
|
||||||
|
label='Parent group (slug)',
|
||||||
|
)
|
||||||
|
type_id = django_filters.ModelMultipleChoiceFilter(
|
||||||
|
queryset=ClusterType.objects.all(),
|
||||||
|
label='Cluster type (ID)',
|
||||||
|
)
|
||||||
|
type = django_filters.ModelMultipleChoiceFilter(
|
||||||
|
name='type__slug',
|
||||||
|
queryset=ClusterType.objects.all(),
|
||||||
|
to_field_name='slug',
|
||||||
|
label='Cluster type (slug)',
|
||||||
|
)
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
model = Cluster
|
||||||
|
fields = ['name']
|
||||||
|
|
||||||
|
def search(self, queryset, name, value):
|
||||||
|
if not value.strip():
|
||||||
|
return queryset
|
||||||
|
return queryset.filter(
|
||||||
|
Q(name__icontains=value) |
|
||||||
|
Q(comments__icontains=value)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class VirtualMachineFilter(CustomFieldFilterSet):
|
||||||
|
id__in = NumericInFilter(name='id', lookup_expr='in')
|
||||||
|
q = django_filters.CharFilter(
|
||||||
|
method='search',
|
||||||
|
label='Search',
|
||||||
|
)
|
||||||
|
cluster_group_id = NullableModelMultipleChoiceFilter(
|
||||||
|
name='cluster__group',
|
||||||
|
queryset=ClusterGroup.objects.all(),
|
||||||
|
label='Cluster group (ID)',
|
||||||
|
)
|
||||||
|
cluster_group = NullableModelMultipleChoiceFilter(
|
||||||
|
name='cluster__group__slug',
|
||||||
|
queryset=ClusterGroup.objects.all(),
|
||||||
|
to_field_name='slug',
|
||||||
|
label='Cluster group (slug)',
|
||||||
|
)
|
||||||
|
tenant_id = NullableModelMultipleChoiceFilter(
|
||||||
|
queryset=Tenant.objects.all(),
|
||||||
|
label='Tenant (ID)',
|
||||||
|
)
|
||||||
|
tenant = NullableModelMultipleChoiceFilter(
|
||||||
|
queryset=Tenant.objects.all(),
|
||||||
|
to_field_name='slug',
|
||||||
|
label='Tenant (slug)',
|
||||||
|
)
|
||||||
|
platform_id = NullableModelMultipleChoiceFilter(
|
||||||
|
queryset=Platform.objects.all(),
|
||||||
|
label='Platform (ID)',
|
||||||
|
)
|
||||||
|
platform = NullableModelMultipleChoiceFilter(
|
||||||
|
name='platform',
|
||||||
|
queryset=Platform.objects.all(),
|
||||||
|
to_field_name='slug',
|
||||||
|
label='Platform (slug)',
|
||||||
|
)
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
model = VirtualMachine
|
||||||
|
fields = ['name', 'cluster']
|
||||||
|
|
||||||
|
def search(self, queryset, name, value):
|
||||||
|
if not value.strip():
|
||||||
|
return queryset
|
||||||
|
return queryset.filter(
|
||||||
|
Q(name__icontains=value) |
|
||||||
|
Q(comments__icontains=value)
|
||||||
|
)
|
@ -1,11 +1,12 @@
|
|||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
from django import forms
|
from django import forms
|
||||||
|
from django.db.models import Count
|
||||||
|
|
||||||
from extras.forms import CustomFieldBulkEditForm, CustomFieldForm
|
from extras.forms import CustomFieldBulkEditForm, CustomFieldForm, CustomFieldFilterForm
|
||||||
from tenancy.forms import TenancyForm
|
from tenancy.forms import TenancyForm
|
||||||
from tenancy.models import Tenant
|
from tenancy.models import Tenant
|
||||||
from utilities.forms import BootstrapMixin, SlugField
|
from utilities.forms import APISelect, BootstrapMixin, ChainedModelChoiceField, FilterChoiceField, SlugField
|
||||||
from .models import Cluster, ClusterGroup, ClusterType, VirtualMachine
|
from .models import Cluster, ClusterGroup, ClusterType, VirtualMachine
|
||||||
|
|
||||||
|
|
||||||
@ -67,15 +68,58 @@ class ClusterCSVForm(forms.ModelForm):
|
|||||||
fields = ['name', 'type', 'group']
|
fields = ['name', 'type', 'group']
|
||||||
|
|
||||||
|
|
||||||
|
class ClusterFilterForm(BootstrapMixin, CustomFieldFilterForm):
|
||||||
|
model = Cluster
|
||||||
|
q = forms.CharField(required=False, label='Search')
|
||||||
|
group = FilterChoiceField(
|
||||||
|
queryset=ClusterGroup.objects.annotate(filter_count=Count('clusters')),
|
||||||
|
to_field_name='slug',
|
||||||
|
null_option=(0, 'None'),
|
||||||
|
required=False,
|
||||||
|
)
|
||||||
|
type = FilterChoiceField(
|
||||||
|
queryset=ClusterType.objects.annotate(filter_count=Count('clusters')),
|
||||||
|
to_field_name='slug',
|
||||||
|
required=False,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Virtual Machines
|
# Virtual Machines
|
||||||
#
|
#
|
||||||
|
|
||||||
class VirtualMachineForm(BootstrapMixin, TenancyForm, CustomFieldForm):
|
class VirtualMachineForm(BootstrapMixin, TenancyForm, CustomFieldForm):
|
||||||
|
cluster_group = forms.ModelChoiceField(
|
||||||
|
queryset=ClusterGroup.objects.all(),
|
||||||
|
required=False,
|
||||||
|
widget=forms.Select(
|
||||||
|
attrs={'filter-for': 'cluster', 'nullable': 'true'}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
cluster = ChainedModelChoiceField(
|
||||||
|
queryset=Cluster.objects.all(),
|
||||||
|
chains=(
|
||||||
|
('group', 'cluster_group'),
|
||||||
|
),
|
||||||
|
widget=APISelect(
|
||||||
|
api_url='/api/virtualization/clusters/?group_id={{cluster_group}}'
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = VirtualMachine
|
model = VirtualMachine
|
||||||
fields = ['name', 'cluster', 'tenant', 'platform', 'comments']
|
fields = ['name', 'cluster_group', 'cluster', 'tenant', 'platform', 'vcpus', 'memory', 'disk', 'comments']
|
||||||
|
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
|
||||||
|
# Initialize helper selector
|
||||||
|
instance = kwargs.get('instance')
|
||||||
|
if instance.pk and instance.cluster is not None:
|
||||||
|
initial = kwargs.get('initial', {}).copy()
|
||||||
|
initial['cluster_group'] = instance.cluster.group
|
||||||
|
kwargs['initial'] = initial
|
||||||
|
|
||||||
|
super(VirtualMachineForm, self).__init__(*args, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
class VirtualMachineCSVForm(forms.ModelForm):
|
class VirtualMachineCSVForm(forms.ModelForm):
|
||||||
@ -89,7 +133,7 @@ class VirtualMachineCSVForm(forms.ModelForm):
|
|||||||
)
|
)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
fields = ['cluster', 'name', 'tenant']
|
fields = ['cluster', 'name', 'tenant', 'platform', 'vcpus', 'memory', 'disk', 'comments']
|
||||||
|
|
||||||
|
|
||||||
class VirtualMachineBulkEditForm(BootstrapMixin, CustomFieldBulkEditForm):
|
class VirtualMachineBulkEditForm(BootstrapMixin, CustomFieldBulkEditForm):
|
||||||
@ -99,3 +143,17 @@ class VirtualMachineBulkEditForm(BootstrapMixin, CustomFieldBulkEditForm):
|
|||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
nullable_fields = ['tenant']
|
nullable_fields = ['tenant']
|
||||||
|
|
||||||
|
|
||||||
|
class VirtualMachineFilterForm(BootstrapMixin, CustomFieldFilterForm):
|
||||||
|
model = VirtualMachine
|
||||||
|
q = forms.CharField(required=False, label='Search')
|
||||||
|
cluster_group = FilterChoiceField(
|
||||||
|
queryset=ClusterGroup.objects.all(),
|
||||||
|
to_field_name='slug',
|
||||||
|
null_option=(0, 'None'),
|
||||||
|
)
|
||||||
|
cluster_id = FilterChoiceField(
|
||||||
|
queryset=Cluster.objects.annotate(filter_count=Count('virtual_machines')),
|
||||||
|
label='Cluster'
|
||||||
|
)
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
# Generated by Django 1.11.4 on 2017-08-16 19:22
|
# Generated by Django 1.11.4 on 2017-08-16 19:27
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
import dcim.fields
|
import dcim.fields
|
||||||
@ -13,9 +13,9 @@ class Migration(migrations.Migration):
|
|||||||
initial = True
|
initial = True
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
('dcim', '0041_napalm_integration'),
|
|
||||||
('ipam', '0018_remove_service_uniqueness_constraint'),
|
('ipam', '0018_remove_service_uniqueness_constraint'),
|
||||||
('tenancy', '0003_unicode_literals'),
|
('tenancy', '0003_unicode_literals'),
|
||||||
|
('dcim', '0041_napalm_integration'),
|
||||||
]
|
]
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
@ -63,9 +63,9 @@ class Migration(migrations.Migration):
|
|||||||
('created', models.DateField(auto_now_add=True)),
|
('created', models.DateField(auto_now_add=True)),
|
||||||
('last_updated', models.DateTimeField(auto_now=True)),
|
('last_updated', models.DateTimeField(auto_now=True)),
|
||||||
('name', models.CharField(max_length=64, unique=True)),
|
('name', models.CharField(max_length=64, unique=True)),
|
||||||
('vcpus', models.PositiveSmallIntegerField(blank=True, verbose_name='vCPUs')),
|
('vcpus', models.PositiveSmallIntegerField(blank=True, null=True, verbose_name='vCPUs')),
|
||||||
('memory', models.PositiveIntegerField(blank=True, verbose_name='Memory (MB)')),
|
('memory', models.PositiveIntegerField(blank=True, null=True, verbose_name='Memory (MB)')),
|
||||||
('disk', models.PositiveIntegerField(blank=True, verbose_name='Disk (GB)')),
|
('disk', models.PositiveIntegerField(blank=True, null=True, verbose_name='Disk (GB)')),
|
||||||
('comments', models.TextField(blank=True)),
|
('comments', models.TextField(blank=True)),
|
||||||
('cluster', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='virtual_machines', to='virtualization.Cluster')),
|
('cluster', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='virtual_machines', to='virtualization.Cluster')),
|
||||||
('platform', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='virtual_machines', to='dcim.Platform')),
|
('platform', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='virtual_machines', to='dcim.Platform')),
|
||||||
|
@ -161,14 +161,17 @@ class VirtualMachine(CreatedUpdatedModel, CustomFieldModel):
|
|||||||
)
|
)
|
||||||
vcpus = models.PositiveSmallIntegerField(
|
vcpus = models.PositiveSmallIntegerField(
|
||||||
blank=True,
|
blank=True,
|
||||||
|
null=True,
|
||||||
verbose_name='vCPUs'
|
verbose_name='vCPUs'
|
||||||
)
|
)
|
||||||
memory = models.PositiveIntegerField(
|
memory = models.PositiveIntegerField(
|
||||||
blank=True,
|
blank=True,
|
||||||
|
null=True,
|
||||||
verbose_name='Memory (MB)'
|
verbose_name='Memory (MB)'
|
||||||
)
|
)
|
||||||
disk = models.PositiveIntegerField(
|
disk = models.PositiveIntegerField(
|
||||||
blank=True,
|
blank=True,
|
||||||
|
null=True,
|
||||||
verbose_name='Disk (GB)'
|
verbose_name='Disk (GB)'
|
||||||
)
|
)
|
||||||
comments = models.TextField(
|
comments = models.TextField(
|
||||||
|
@ -77,8 +77,9 @@ class ClusterTable(BaseTable):
|
|||||||
class VirtualMachineTable(BaseTable):
|
class VirtualMachineTable(BaseTable):
|
||||||
pk = ToggleColumn()
|
pk = ToggleColumn()
|
||||||
name = tables.LinkColumn()
|
name = tables.LinkColumn()
|
||||||
|
cluster = tables.LinkColumn('virtualization:cluster', args=[Accessor('cluster.pk')])
|
||||||
tenant = tables.LinkColumn('tenancy:tenant', args=[Accessor('tenant.slug')])
|
tenant = tables.LinkColumn('tenancy:tenant', args=[Accessor('tenant.slug')])
|
||||||
|
|
||||||
class Meta(BaseTable.Meta):
|
class Meta(BaseTable.Meta):
|
||||||
model = VirtualMachine
|
model = VirtualMachine
|
||||||
fields = ('pk', 'name', 'tenant')
|
fields = ('pk', 'name', 'cluster', 'tenant', 'vcpus', 'memory', 'disk')
|
||||||
|
@ -11,6 +11,7 @@ from utilities.views import (
|
|||||||
ObjectDeleteView, ObjectEditView, ObjectListView,
|
ObjectDeleteView, ObjectEditView, ObjectListView,
|
||||||
)
|
)
|
||||||
from .models import Cluster, ClusterGroup, ClusterType, VirtualMachine, VMInterface
|
from .models import Cluster, ClusterGroup, ClusterType, VirtualMachine, VMInterface
|
||||||
|
from . import filters
|
||||||
from . import forms
|
from . import forms
|
||||||
from . import tables
|
from . import tables
|
||||||
|
|
||||||
@ -84,6 +85,8 @@ class ClusterGroupBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
|
|||||||
class ClusterListView(ObjectListView):
|
class ClusterListView(ObjectListView):
|
||||||
queryset = Cluster.objects.annotate(vm_count=Count('virtual_machines'))
|
queryset = Cluster.objects.annotate(vm_count=Count('virtual_machines'))
|
||||||
table = tables.ClusterTable
|
table = tables.ClusterTable
|
||||||
|
filter = filters.ClusterFilter
|
||||||
|
filter_form = forms.ClusterFilterForm
|
||||||
template_name = 'virtualization/cluster_list.html'
|
template_name = 'virtualization/cluster_list.html'
|
||||||
|
|
||||||
|
|
||||||
@ -138,8 +141,8 @@ class ClusterBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
|
|||||||
|
|
||||||
class VirtualMachineListView(ObjectListView):
|
class VirtualMachineListView(ObjectListView):
|
||||||
queryset = VirtualMachine.objects.select_related('tenant')
|
queryset = VirtualMachine.objects.select_related('tenant')
|
||||||
# filter = filters.VirtualMachineFilter
|
filter = filters.VirtualMachineFilter
|
||||||
# filter_form = forms.VirtualMachineFilterForm
|
filter_form = forms.VirtualMachineFilterForm
|
||||||
table = tables.VirtualMachineTable
|
table = tables.VirtualMachineTable
|
||||||
template_name = 'virtualization/virtualmachine_list.html'
|
template_name = 'virtualization/virtualmachine_list.html'
|
||||||
|
|
||||||
@ -184,7 +187,7 @@ class VirtualMachineBulkEditView(PermissionRequiredMixin, BulkEditView):
|
|||||||
permission_required = 'virtualization.change_virtualmachine'
|
permission_required = 'virtualization.change_virtualmachine'
|
||||||
cls = VirtualMachine
|
cls = VirtualMachine
|
||||||
queryset = VirtualMachine.objects.select_related('tenant')
|
queryset = VirtualMachine.objects.select_related('tenant')
|
||||||
# filter = filters.VirtualMachineFilter
|
filter = filters.VirtualMachineFilter
|
||||||
table = tables.VirtualMachineTable
|
table = tables.VirtualMachineTable
|
||||||
form = forms.VirtualMachineBulkEditForm
|
form = forms.VirtualMachineBulkEditForm
|
||||||
default_return_url = 'virtualization:virtualmachine_list'
|
default_return_url = 'virtualization:virtualmachine_list'
|
||||||
|
Loading…
Reference in New Issue
Block a user