1
0
mirror of https://github.com/netbox-community/netbox.git synced 2024-05-10 07:54:54 +00:00

503 lines
16 KiB
Python
Raw Normal View History

from django.contrib import messages
from django.db import transaction
from django.db.models import Prefetch
from django.shortcuts import get_object_or_404, redirect, render
from django.urls import reverse
2020-06-22 13:10:56 -04:00
from dcim.models import Device
from dcim.tables import DeviceTable
from extras.views import ObjectConfigContextView
from ipam.models import IPAddress, Service
from ipam.tables import InterfaceIPAddressTable, InterfaceVLANTable
2020-11-11 16:07:38 -05:00
from netbox.views import generic
from utilities.tables import paginate_table
from utilities.utils import count_related
2021-04-29 16:38:56 -04:00
from . import filtersets, forms, tables
2020-06-23 13:16:21 -04:00
from .models import Cluster, ClusterGroup, ClusterType, VirtualMachine, VMInterface
#
# Cluster types
#
2020-11-11 16:07:38 -05:00
class ClusterTypeListView(generic.ObjectListView):
queryset = ClusterType.objects.annotate(
cluster_count=count_related(Cluster, 'type')
)
table = tables.ClusterTypeTable
class ClusterTypeView(generic.ObjectView):
queryset = ClusterType.objects.all()
def get_extra_context(self, request, instance):
clusters = Cluster.objects.restrict(request.user, 'view').filter(
type=instance
)
clusters_table = tables.ClusterTable(clusters)
clusters_table.columns.hide('type')
paginate_table(clusters_table, request)
return {
'clusters_table': clusters_table,
}
2020-11-11 16:07:38 -05:00
class ClusterTypeEditView(generic.ObjectEditView):
queryset = ClusterType.objects.all()
model_form = forms.ClusterTypeForm
2020-11-11 16:07:38 -05:00
class ClusterTypeDeleteView(generic.ObjectDeleteView):
queryset = ClusterType.objects.all()
2020-11-11 16:07:38 -05:00
class ClusterTypeBulkImportView(generic.BulkImportView):
2020-05-21 11:58:27 -04:00
queryset = ClusterType.objects.all()
model_form = forms.ClusterTypeCSVForm
table = tables.ClusterTypeTable
class ClusterTypeBulkEditView(generic.BulkEditView):
queryset = ClusterType.objects.annotate(
cluster_count=count_related(Cluster, 'type')
)
2021-04-29 16:38:56 -04:00
filterset = filtersets.ClusterTypeFilterSet
table = tables.ClusterTypeTable
form = forms.ClusterTypeBulkEditForm
2020-11-11 16:07:38 -05:00
class ClusterTypeBulkDeleteView(generic.BulkDeleteView):
queryset = ClusterType.objects.annotate(
cluster_count=count_related(Cluster, 'type')
)
table = tables.ClusterTypeTable
#
# Cluster groups
#
2020-11-11 16:07:38 -05:00
class ClusterGroupListView(generic.ObjectListView):
queryset = ClusterGroup.objects.annotate(
cluster_count=count_related(Cluster, 'group')
)
table = tables.ClusterGroupTable
class ClusterGroupView(generic.ObjectView):
queryset = ClusterGroup.objects.all()
def get_extra_context(self, request, instance):
clusters = Cluster.objects.restrict(request.user, 'view').filter(
group=instance
)
clusters_table = tables.ClusterTable(clusters)
clusters_table.columns.hide('group')
paginate_table(clusters_table, request)
return {
'clusters_table': clusters_table,
}
2020-11-11 16:07:38 -05:00
class ClusterGroupEditView(generic.ObjectEditView):
queryset = ClusterGroup.objects.all()
model_form = forms.ClusterGroupForm
2020-11-11 16:07:38 -05:00
class ClusterGroupDeleteView(generic.ObjectDeleteView):
queryset = ClusterGroup.objects.all()
2020-11-11 16:07:38 -05:00
class ClusterGroupBulkImportView(generic.BulkImportView):
queryset = ClusterGroup.objects.annotate(
cluster_count=count_related(Cluster, 'group')
)
model_form = forms.ClusterGroupCSVForm
table = tables.ClusterGroupTable
class ClusterGroupBulkEditView(generic.BulkEditView):
queryset = ClusterGroup.objects.annotate(
cluster_count=count_related(Cluster, 'group')
)
2021-04-29 16:38:56 -04:00
filterset = filtersets.ClusterGroupFilterSet
table = tables.ClusterGroupTable
form = forms.ClusterGroupBulkEditForm
2020-11-11 16:07:38 -05:00
class ClusterGroupBulkDeleteView(generic.BulkDeleteView):
queryset = ClusterGroup.objects.annotate(
cluster_count=count_related(Cluster, 'group')
)
table = tables.ClusterGroupTable
#
# Clusters
#
2020-11-11 16:07:38 -05:00
class ClusterListView(generic.ObjectListView):
2019-04-11 17:27:38 -04:00
permission_required = 'virtualization.view_cluster'
queryset = Cluster.objects.annotate(
device_count=count_related(Device, 'cluster'),
vm_count=count_related(VirtualMachine, 'cluster')
)
table = tables.ClusterTable
2021-04-29 16:38:56 -04:00
filterset = filtersets.ClusterFilterSet
filterset_form = forms.ClusterFilterForm
2020-11-11 16:07:38 -05:00
class ClusterView(generic.ObjectView):
queryset = Cluster.objects.all()
class ClusterVirtualMachinesView(generic.ObjectView):
queryset = Cluster.objects.all()
template_name = 'virtualization/cluster/virtual_machines.html'
def get_extra_context(self, request, instance):
virtualmachines = VirtualMachine.objects.restrict(request.user, 'view').filter(cluster=instance)
virtualmachines_table = tables.VirtualMachineTable(virtualmachines, orderable=False)
return {
'virtualmachines_table': virtualmachines_table,
'active_tab': 'virtual-machines',
}
class ClusterDevicesView(generic.ObjectView):
queryset = Cluster.objects.all()
template_name = 'virtualization/cluster/devices.html'
def get_extra_context(self, request, instance):
devices = Device.objects.restrict(request.user, 'view').filter(cluster=instance).prefetch_related(
'site', 'rack', 'tenant', 'device_type__manufacturer'
)
devices_table = DeviceTable(list(devices), orderable=False)
if request.user.has_perm('virtualization.change_cluster'):
devices_table.columns.show('pk')
return {
'devices_table': devices_table,
'active_tab': 'devices',
}
2020-11-11 16:07:38 -05:00
class ClusterEditView(generic.ObjectEditView):
queryset = Cluster.objects.all()
model_form = forms.ClusterForm
2020-11-11 16:07:38 -05:00
class ClusterDeleteView(generic.ObjectDeleteView):
queryset = Cluster.objects.all()
2020-11-11 16:07:38 -05:00
class ClusterBulkImportView(generic.BulkImportView):
2020-05-21 11:58:27 -04:00
queryset = Cluster.objects.all()
model_form = forms.ClusterCSVForm
table = tables.ClusterTable
2020-11-11 16:07:38 -05:00
class ClusterBulkEditView(generic.BulkEditView):
queryset = Cluster.objects.prefetch_related('type', 'group', 'site')
2021-04-29 16:38:56 -04:00
filterset = filtersets.ClusterFilterSet
2017-09-11 16:14:05 -04:00
table = tables.ClusterTable
form = forms.ClusterBulkEditForm
2020-11-11 16:07:38 -05:00
class ClusterBulkDeleteView(generic.BulkDeleteView):
queryset = Cluster.objects.prefetch_related('type', 'group', 'site')
2021-04-29 16:38:56 -04:00
filterset = filtersets.ClusterFilterSet
table = tables.ClusterTable
2020-11-11 16:07:38 -05:00
class ClusterAddDevicesView(generic.ObjectEditView):
queryset = Cluster.objects.all()
form = forms.ClusterAddDevicesForm
template_name = 'virtualization/cluster_add_devices.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():
device_pks = form.cleaned_data['devices']
with transaction.atomic():
# Assign the selected Devices to the Cluster
for device in Device.objects.filter(pk__in=device_pks):
device.cluster = cluster
device.save()
messages.success(request, "Added {} devices to cluster {}".format(
len(device_pks), cluster
))
return redirect(cluster.get_absolute_url())
return render(request, self.template_name, {
'cluster': cluster,
'form': form,
'return_url': cluster.get_absolute_url(),
})
2020-11-11 16:07:38 -05:00
class ClusterRemoveDevicesView(generic.ObjectEditView):
queryset = Cluster.objects.all()
form = forms.ClusterRemoveDevicesForm
2020-11-11 16:58:29 -05:00
template_name = 'generic/object_bulk_remove.html'
def post(self, request, pk):
cluster = get_object_or_404(self.queryset, pk=pk)
if '_confirm' in request.POST:
form = self.form(request.POST)
if form.is_valid():
device_pks = form.cleaned_data['pk']
with transaction.atomic():
# Remove the selected Devices from the Cluster
for device in Device.objects.filter(pk__in=device_pks):
device.cluster = None
device.save()
messages.success(request, "Removed {} devices from cluster {}".format(
len(device_pks), cluster
))
return redirect(cluster.get_absolute_url())
else:
form = self.form(initial={'pk': request.POST.getlist('pk')})
selected_objects = Device.objects.filter(pk__in=form.initial['pk'])
device_table = DeviceTable(list(selected_objects), orderable=False)
return render(request, self.template_name, {
'form': form,
'parent_obj': cluster,
'table': device_table,
'obj_type_plural': 'devices',
'return_url': cluster.get_absolute_url(),
})
#
# Virtual machines
#
2020-11-11 16:07:38 -05:00
class VirtualMachineListView(generic.ObjectListView):
queryset = VirtualMachine.objects.all()
2021-04-29 16:38:56 -04:00
filterset = filtersets.VirtualMachineFilterSet
filterset_form = forms.VirtualMachineFilterForm
table = tables.VirtualMachineDetailTable
template_name = 'virtualization/virtualmachine_list.html'
2020-11-11 16:07:38 -05:00
class VirtualMachineView(generic.ObjectView):
queryset = VirtualMachine.objects.prefetch_related('tenant__group')
def get_extra_context(self, request, instance):
# Interfaces
2020-10-16 17:01:55 -04:00
vminterfaces = VMInterface.objects.restrict(request.user, 'view').filter(
virtual_machine=instance
).prefetch_related(
Prefetch('ip_addresses', queryset=IPAddress.objects.restrict(request.user))
)
vminterface_table = tables.VirtualMachineVMInterfaceTable(vminterfaces, user=request.user, orderable=False)
2020-10-16 17:01:55 -04:00
if request.user.has_perm('virtualization.change_vminterface') or \
request.user.has_perm('virtualization.delete_vminterface'):
vminterface_table.columns.show('pk')
# Services
services = Service.objects.restrict(request.user, 'view').filter(
virtual_machine=instance
).prefetch_related(
Prefetch('ipaddresses', queryset=IPAddress.objects.restrict(request.user))
)
return {
2020-10-16 17:01:55 -04:00
'vminterface_table': vminterface_table,
2017-08-31 12:50:35 -04:00
'services': services,
}
class VirtualMachineInterfacesView(generic.ObjectView):
queryset = VirtualMachine.objects.all()
template_name = 'virtualization/virtualmachine/interfaces.html'
def get_extra_context(self, request, instance):
interfaces = instance.interfaces.restrict(request.user, 'view').prefetch_related(
Prefetch('ip_addresses', queryset=IPAddress.objects.restrict(request.user)),
'tags',
)
interface_table = tables.VirtualMachineVMInterfaceTable(
data=interfaces,
user=request.user,
orderable=False
)
if request.user.has_perm('virtualization.change_vminterface') or \
request.user.has_perm('virtualization.delete_vminterface'):
interface_table.columns.show('pk')
return {
'interface_table': interface_table,
'active_tab': 'interfaces',
}
class VirtualMachineConfigContextView(ObjectConfigContextView):
2020-10-23 01:18:04 -04:00
queryset = VirtualMachine.objects.annotate_config_context_data()
base_template = 'virtualization/virtualmachine.html'
2018-06-27 16:02:34 -04:00
2020-11-11 16:07:38 -05:00
class VirtualMachineEditView(generic.ObjectEditView):
queryset = VirtualMachine.objects.all()
model_form = forms.VirtualMachineForm
2020-11-11 16:07:38 -05:00
class VirtualMachineDeleteView(generic.ObjectDeleteView):
queryset = VirtualMachine.objects.all()
2020-11-11 16:07:38 -05:00
class VirtualMachineBulkImportView(generic.BulkImportView):
2020-05-21 11:58:27 -04:00
queryset = VirtualMachine.objects.all()
model_form = forms.VirtualMachineCSVForm
table = tables.VirtualMachineTable
2020-11-11 16:07:38 -05:00
class VirtualMachineBulkEditView(generic.BulkEditView):
queryset = VirtualMachine.objects.prefetch_related('cluster', 'tenant', 'role')
2021-04-29 16:38:56 -04:00
filterset = filtersets.VirtualMachineFilterSet
table = tables.VirtualMachineTable
form = forms.VirtualMachineBulkEditForm
2020-11-11 16:07:38 -05:00
class VirtualMachineBulkDeleteView(generic.BulkDeleteView):
queryset = VirtualMachine.objects.prefetch_related('cluster', 'tenant', 'role')
2021-04-29 16:38:56 -04:00
filterset = filtersets.VirtualMachineFilterSet
2017-09-11 16:14:05 -04:00
table = tables.VirtualMachineTable
#
# VM interfaces
#
2020-11-11 16:07:38 -05:00
class VMInterfaceListView(generic.ObjectListView):
queryset = VMInterface.objects.all()
2021-04-29 16:38:56 -04:00
filterset = filtersets.VMInterfaceFilterSet
2020-06-23 16:39:43 -04:00
filterset_form = forms.VMInterfaceFilterForm
table = tables.VMInterfaceTable
2020-06-23 16:52:05 -04:00
action_buttons = ('export',)
2020-06-22 13:10:56 -04:00
2020-11-11 16:07:38 -05:00
class VMInterfaceView(generic.ObjectView):
2020-06-23 13:16:21 -04:00
queryset = VMInterface.objects.all()
2020-06-22 13:10:56 -04:00
def get_extra_context(self, request, instance):
# Get assigned IP addresses
ipaddress_table = InterfaceIPAddressTable(
data=instance.ip_addresses.restrict(request.user, 'view').prefetch_related('vrf', 'tenant'),
orderable=False
)
# Get child interfaces
child_interfaces = VMInterface.objects.restrict(request.user, 'view').filter(parent=instance)
child_interfaces_tables = tables.VMInterfaceTable(
child_interfaces,
orderable=False
)
child_interfaces_tables.columns.hide('virtual_machine')
# Get assigned VLANs and annotate whether each is tagged or untagged
vlans = []
if instance.untagged_vlan is not None:
vlans.append(instance.untagged_vlan)
vlans[0].tagged = False
for vlan in instance.tagged_vlans.restrict(request.user).prefetch_related('site', 'group', 'tenant', 'role'):
vlan.tagged = True
vlans.append(vlan)
vlan_table = InterfaceVLANTable(
interface=instance,
data=vlans,
orderable=False
)
return {
'ipaddress_table': ipaddress_table,
'child_interfaces_table': child_interfaces_tables,
'vlan_table': vlan_table,
}
2020-06-22 13:10:56 -04:00
# TODO: This should not use ComponentCreateView
2020-11-11 16:07:38 -05:00
class VMInterfaceCreateView(generic.ComponentCreateView):
2020-06-23 13:16:21 -04:00
queryset = VMInterface.objects.all()
2020-06-23 16:39:43 -04:00
form = forms.VMInterfaceCreateForm
model_form = forms.VMInterfaceForm
2017-08-18 14:37:19 -04:00
template_name = 'virtualization/virtualmachine_component_add.html'
2020-11-11 16:07:38 -05:00
class VMInterfaceEditView(generic.ObjectEditView):
2020-06-23 13:16:21 -04:00
queryset = VMInterface.objects.all()
2020-06-23 16:39:43 -04:00
model_form = forms.VMInterfaceForm
2020-06-23 15:09:32 -04:00
template_name = 'virtualization/vminterface_edit.html'
2017-08-18 14:37:19 -04:00
2020-11-11 16:07:38 -05:00
class VMInterfaceDeleteView(generic.ObjectDeleteView):
2020-06-23 13:16:21 -04:00
queryset = VMInterface.objects.all()
2017-08-18 14:37:19 -04:00
2020-11-11 16:07:38 -05:00
class VMInterfaceBulkImportView(generic.BulkImportView):
2020-06-23 17:01:57 -04:00
queryset = VMInterface.objects.all()
model_form = forms.VMInterfaceCSVForm
table = tables.VMInterfaceTable
2020-11-11 16:07:38 -05:00
class VMInterfaceBulkEditView(generic.BulkEditView):
2020-06-23 13:16:21 -04:00
queryset = VMInterface.objects.all()
2020-06-23 16:39:43 -04:00
table = tables.VMInterfaceTable
form = forms.VMInterfaceBulkEditForm
2017-08-18 14:37:19 -04:00
2020-11-11 16:07:38 -05:00
class VMInterfaceBulkRenameView(generic.BulkRenameView):
queryset = VMInterface.objects.all()
form = forms.VMInterfaceBulkRenameForm
2020-11-11 16:07:38 -05:00
class VMInterfaceBulkDeleteView(generic.BulkDeleteView):
2020-06-23 13:16:21 -04:00
queryset = VMInterface.objects.all()
2020-06-23 16:39:43 -04:00
table = tables.VMInterfaceTable
#
# Bulk Device component creation
#
2020-11-11 16:07:38 -05:00
class VirtualMachineBulkAddInterfaceView(generic.BulkComponentCreateView):
parent_model = VirtualMachine
parent_field = 'virtual_machine'
2020-06-23 16:39:43 -04:00
form = forms.VMInterfaceBulkCreateForm
2020-06-23 13:16:21 -04:00
queryset = VMInterface.objects.all()
2020-06-23 16:39:43 -04:00
model_form = forms.VMInterfaceForm
2021-04-29 16:38:56 -04:00
filterset = filtersets.VirtualMachineFilterSet
table = tables.VirtualMachineTable
def get_required_permission(self):
return f'virtualization.add_vminterface'