668 lines
22 KiB
Python
Raw Normal View History

from django.contrib import messages
from django.db import transaction
from django.db.models import Prefetch, Sum
from django.shortcuts import get_object_or_404, redirect, render
from django.urls import reverse
from django.utils.translation import gettext_lazy as _
from dcim.filtersets import DeviceFilterSet
from dcim.forms import DeviceFilterForm
2020-06-22 13:10:56 -04:00
from dcim.models import Device
from dcim.tables import DeviceTable
from extras.views import ObjectConfigContextView, ObjectRenderConfigView
from ipam.models import IPAddress
Fixes: #7336 - VLAN Translation (#17745) * VLANTranslationPolicy and VLANTranslationRule models and all associated UI classes * Change VLANTranslationPolicy to a PrimaryModel and make name unique * Add serializer classes to InterfaceSerializer * Remake migrations * Add GraphQL typing * Skip tagged models in test * Missing migration * Remove get_absolute_url methods * Remove package-lock.json * Rebuild migration and add constraints and field options * Rebuild migrations * Use DynamicModelChoiceField for policy field * Make vlan_translation_policy fields on filtersets more consistent with existing __name convention * Add vlan_translation_table to VMInterface detail page * Add vlan_translation_policy to VMInterfaceSerializer * Move vlan_translation_policy fields to model and filterset mixins * Protect in-use policies against deletion * Add vlan_translation_policy to fields in VMInterfaceSerializer * Cleanup indentation * Remove unnecessary ordering column * Rebuild migrations * Search methods and registration * Ensure 'id' column is present by default * Add graphql types/filters/schema for VLANTranslationRule * Filterset tests * View tests * API and viewset tests (incomplete) * Add tags to VLANTranslationRuleForm * Complete viewset tests for VLANTranslationRule * Make VLANTranslationRule.policy nullable (but still required) * Revert "Make VLANTranslationRule.policy nullable (but still required)" This reverts commit 4c1bb437ef1a0a3593e5fbb87f08a0f158ea8c47. * Revert nullability * Explicitly prefetch policy in graphql * Documentation of new and affected models * Add note about select_related in graphql * Rework policy/rule documentation * Move vlan_translation_policy into 802.1Q Switching fieldset * Remove redundant InterfaceVLANTranslationTable * Conditionally include vlan_translation_table in interface.html and vminterface.html * Add description field to VLANTranslationRule * Define vlan_translation_table conditionally * Add policy (name) filter to VLANTranslationRuleFilterSet * Revert changes to adding-models.md (moved to another PR) * Dynamic table for linked rules in vlantranslationpolicy.html * Misc cleanup --------- Co-authored-by: Jeremy Stretch <jstretch@netboxlabs.com>
2024-10-30 17:09:46 -04:00
from ipam.tables import InterfaceVLANTable, VLANTranslationRuleTable
from netbox.constants import DEFAULT_ACTION_PERMISSIONS
2020-11-11 16:07:38 -05:00
from netbox.views import generic
from tenancy.views import ObjectContactsView
from utilities.query import count_related
from utilities.query_functions import CollateAsChar
from utilities.views import GetRelatedModelsMixin, ViewTab, register_model_view
2021-04-29 16:38:56 -04:00
from . import filtersets, forms, tables
from .models import *
#
# Cluster types
#
@register_model_view(ClusterType, 'list', path='', detail=False)
2020-11-11 16:07:38 -05:00
class ClusterTypeListView(generic.ObjectListView):
queryset = ClusterType.objects.annotate(
cluster_count=count_related(Cluster, 'type')
)
filterset = filtersets.ClusterTypeFilterSet
filterset_form = forms.ClusterTypeFilterForm
table = tables.ClusterTypeTable
@register_model_view(ClusterType)
class ClusterTypeView(GetRelatedModelsMixin, generic.ObjectView):
queryset = ClusterType.objects.all()
def get_extra_context(self, request, instance):
return {
'related_models': self.get_related_models(request, instance),
}
@register_model_view(ClusterType, 'add', detail=False)
@register_model_view(ClusterType, 'edit')
2020-11-11 16:07:38 -05:00
class ClusterTypeEditView(generic.ObjectEditView):
queryset = ClusterType.objects.all()
form = forms.ClusterTypeForm
@register_model_view(ClusterType, 'delete')
2020-11-11 16:07:38 -05:00
class ClusterTypeDeleteView(generic.ObjectDeleteView):
queryset = ClusterType.objects.all()
@register_model_view(ClusterType, 'bulk_import', detail=False)
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.ClusterTypeImportForm
@register_model_view(ClusterType, 'bulk_edit', path='edit', detail=False)
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
@register_model_view(ClusterType, 'bulk_delete', path='delete', detail=False)
2020-11-11 16:07:38 -05:00
class ClusterTypeBulkDeleteView(generic.BulkDeleteView):
queryset = ClusterType.objects.annotate(
cluster_count=count_related(Cluster, 'type')
)
filterset = filtersets.ClusterTypeFilterSet
table = tables.ClusterTypeTable
#
# Cluster groups
#
@register_model_view(ClusterGroup, 'list', path='', detail=False)
2020-11-11 16:07:38 -05:00
class ClusterGroupListView(generic.ObjectListView):
queryset = ClusterGroup.objects.annotate(
cluster_count=count_related(Cluster, 'group')
)
filterset = filtersets.ClusterGroupFilterSet
filterset_form = forms.ClusterGroupFilterForm
table = tables.ClusterGroupTable
@register_model_view(ClusterGroup)
class ClusterGroupView(GetRelatedModelsMixin, generic.ObjectView):
queryset = ClusterGroup.objects.all()
def get_extra_context(self, request, instance):
return {
'related_models': self.get_related_models(request, instance),
}
@register_model_view(ClusterGroup, 'add', detail=False)
@register_model_view(ClusterGroup, 'edit')
2020-11-11 16:07:38 -05:00
class ClusterGroupEditView(generic.ObjectEditView):
queryset = ClusterGroup.objects.all()
form = forms.ClusterGroupForm
@register_model_view(ClusterGroup, 'delete')
2020-11-11 16:07:38 -05:00
class ClusterGroupDeleteView(generic.ObjectDeleteView):
queryset = ClusterGroup.objects.all()
@register_model_view(ClusterGroup, 'bulk_import', detail=False)
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.ClusterGroupImportForm
@register_model_view(ClusterGroup, 'bulk_edit', path='edit', detail=False)
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
@register_model_view(ClusterGroup, 'bulk_delete', path='delete', detail=False)
2020-11-11 16:07:38 -05:00
class ClusterGroupBulkDeleteView(generic.BulkDeleteView):
queryset = ClusterGroup.objects.annotate(
cluster_count=count_related(Cluster, 'group')
)
filterset = filtersets.ClusterGroupFilterSet
table = tables.ClusterGroupTable
@register_model_view(ClusterGroup, 'contacts')
class ClusterGroupContactsView(ObjectContactsView):
queryset = ClusterGroup.objects.all()
#
# Clusters
#
@register_model_view(Cluster, 'list', path='', detail=False)
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
@register_model_view(Cluster)
2020-11-11 16:07:38 -05:00
class ClusterView(generic.ObjectView):
queryset = Cluster.objects.all()
def get_extra_context(self, request, instance):
return instance.virtual_machines.aggregate(
vcpus_sum=Sum('vcpus'),
memory_sum=Sum('memory'),
disk_sum=Sum('disk')
)
@register_model_view(Cluster, 'virtualmachines', path='virtual-machines')
class ClusterVirtualMachinesView(generic.ObjectChildrenView):
queryset = Cluster.objects.all()
child_model = VirtualMachine
table = tables.VirtualMachineTable
filterset = filtersets.VirtualMachineFilterSet
filterset_form = forms.VirtualMachineFilterForm
tab = ViewTab(
label=_('Virtual Machines'),
badge=lambda obj: obj.virtual_machines.count(),
permission='virtualization.view_virtualmachine',
weight=500
)
def get_children(self, request, parent):
return VirtualMachine.objects.restrict(request.user, 'view').filter(cluster=parent)
@register_model_view(Cluster, 'devices')
class ClusterDevicesView(generic.ObjectChildrenView):
queryset = Cluster.objects.all()
child_model = Device
table = DeviceTable
filterset = DeviceFilterSet
filterset_form = DeviceFilterForm
template_name = 'virtualization/cluster/devices.html'
actions = {
'add': {'add'},
'export': {'view'},
'bulk_import': {'add'},
'bulk_edit': {'change'},
'bulk_remove_devices': {'change'},
}
tab = ViewTab(
label=_('Devices'),
badge=lambda obj: obj.devices.count(),
permission='virtualization.view_virtualmachine',
weight=600
)
def get_children(self, request, parent):
return Device.objects.restrict(request.user, 'view').filter(cluster=parent)
@register_model_view(Cluster, 'add', detail=False)
@register_model_view(Cluster, 'edit')
2020-11-11 16:07:38 -05:00
class ClusterEditView(generic.ObjectEditView):
queryset = Cluster.objects.all()
form = forms.ClusterForm
@register_model_view(Cluster, 'delete')
2020-11-11 16:07:38 -05:00
class ClusterDeleteView(generic.ObjectDeleteView):
queryset = Cluster.objects.all()
@register_model_view(Cluster, 'bulk_import', detail=False)
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.ClusterImportForm
@register_model_view(Cluster, 'bulk_edit', path='edit', detail=False)
2020-11-11 16:07:38 -05:00
class ClusterBulkEditView(generic.BulkEditView):
queryset = Cluster.objects.all()
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
@register_model_view(Cluster, 'bulk_delete', path='delete', detail=False)
2020-11-11 16:07:38 -05:00
class ClusterBulkDeleteView(generic.BulkDeleteView):
queryset = Cluster.objects.all()
2021-04-29 16:38:56 -04:00
filterset = filtersets.ClusterFilterSet
table = tables.ClusterTable
@register_model_view(Cluster, 'add_devices', path='devices/add')
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 {count} devices to cluster {cluster}").format(
count=len(device_pks),
cluster=cluster
))
return redirect(cluster.get_absolute_url())
return render(request, self.template_name, {
'cluster': cluster,
'form': form,
'return_url': cluster.get_absolute_url(),
})
@register_model_view(Cluster, 'remove_devices', path='devices/remove')
2020-11-11 16:07:38 -05:00
class ClusterRemoveDevicesView(generic.ObjectEditView):
queryset = Cluster.objects.all()
form = forms.ClusterRemoveDevicesForm
2022-02-08 11:49:18 -05:00
template_name = 'generic/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 {count} devices from cluster {cluster}").format(
count=len(device_pks),
cluster=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(),
})
@register_model_view(Cluster, 'contacts')
class ClusterContactsView(ObjectContactsView):
queryset = Cluster.objects.all()
#
# Virtual machines
#
@register_model_view(VirtualMachine, 'list', path='', detail=False)
2020-11-11 16:07:38 -05:00
class VirtualMachineListView(generic.ObjectListView):
queryset = VirtualMachine.objects.prefetch_related('primary_ip4', 'primary_ip6')
2021-04-29 16:38:56 -04:00
filterset = filtersets.VirtualMachineFilterSet
filterset_form = forms.VirtualMachineFilterForm
table = tables.VirtualMachineTable
template_name = 'virtualization/virtualmachine_list.html'
@register_model_view(VirtualMachine)
2020-11-11 16:07:38 -05:00
class VirtualMachineView(generic.ObjectView):
queryset = VirtualMachine.objects.all()
@register_model_view(VirtualMachine, 'interfaces')
class VirtualMachineInterfacesView(generic.ObjectChildrenView):
queryset = VirtualMachine.objects.all()
child_model = VMInterface
table = tables.VirtualMachineVMInterfaceTable
filterset = filtersets.VMInterfaceFilterSet
filterset_form = forms.VMInterfaceFilterForm
template_name = 'virtualization/virtualmachine/interfaces.html'
actions = {
**DEFAULT_ACTION_PERMISSIONS,
'bulk_rename': {'change'},
}
tab = ViewTab(
label=_('Interfaces'),
badge=lambda obj: obj.interface_count,
permission='virtualization.view_vminterface',
weight=500
)
def get_children(self, request, parent):
return parent.interfaces.restrict(request.user, 'view').prefetch_related(
Prefetch('ip_addresses', queryset=IPAddress.objects.restrict(request.user)),
'tags',
)
@register_model_view(VirtualMachine, 'disks')
class VirtualMachineVirtualDisksView(generic.ObjectChildrenView):
queryset = VirtualMachine.objects.all()
child_model = VirtualDisk
table = tables.VirtualMachineVirtualDiskTable
filterset = filtersets.VirtualDiskFilterSet
filterset_form = forms.VirtualDiskFilterForm
template_name = 'virtualization/virtualmachine/virtual_disks.html'
tab = ViewTab(
label=_('Virtual Disks'),
badge=lambda obj: obj.virtual_disk_count,
permission='virtualization.view_virtualdisk',
weight=500
)
actions = {
**DEFAULT_ACTION_PERMISSIONS,
'bulk_rename': {'change'},
}
def get_children(self, request, parent):
return parent.virtualdisks.restrict(request.user, 'view').prefetch_related('tags')
@register_model_view(VirtualMachine, 'configcontext', path='config-context')
class VirtualMachineConfigContextView(ObjectConfigContextView):
2020-10-23 01:18:04 -04:00
queryset = VirtualMachine.objects.annotate_config_context_data()
base_template = 'virtualization/virtualmachine.html'
tab = ViewTab(
label=_('Config Context'),
weight=2000
)
2018-06-27 16:02:34 -04:00
@register_model_view(VirtualMachine, 'render-config')
class VirtualMachineRenderConfigView(ObjectRenderConfigView):
queryset = VirtualMachine.objects.all()
base_template = 'virtualization/virtualmachine/base.html'
tab = ViewTab(
label=_('Render Config'),
weight=2100,
)
@register_model_view(VirtualMachine, 'add', detail=False)
@register_model_view(VirtualMachine, 'edit')
2020-11-11 16:07:38 -05:00
class VirtualMachineEditView(generic.ObjectEditView):
queryset = VirtualMachine.objects.all()
form = forms.VirtualMachineForm
@register_model_view(VirtualMachine, 'delete')
2020-11-11 16:07:38 -05:00
class VirtualMachineDeleteView(generic.ObjectDeleteView):
queryset = VirtualMachine.objects.all()
@register_model_view(VirtualMachine, 'bulk_import', detail=False)
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.VirtualMachineImportForm
@register_model_view(VirtualMachine, 'bulk_edit', path='edit', detail=False)
2020-11-11 16:07:38 -05:00
class VirtualMachineBulkEditView(generic.BulkEditView):
queryset = VirtualMachine.objects.prefetch_related('primary_ip4', 'primary_ip6')
2021-04-29 16:38:56 -04:00
filterset = filtersets.VirtualMachineFilterSet
table = tables.VirtualMachineTable
form = forms.VirtualMachineBulkEditForm
@register_model_view(VirtualMachine, 'bulk_delete', path='delete', detail=False)
2020-11-11 16:07:38 -05:00
class VirtualMachineBulkDeleteView(generic.BulkDeleteView):
queryset = VirtualMachine.objects.prefetch_related('primary_ip4', 'primary_ip6')
2021-04-29 16:38:56 -04:00
filterset = filtersets.VirtualMachineFilterSet
2017-09-11 16:14:05 -04:00
table = tables.VirtualMachineTable
@register_model_view(VirtualMachine, 'contacts')
class VirtualMachineContactsView(ObjectContactsView):
queryset = VirtualMachine.objects.all()
#
# VM interfaces
#
@register_model_view(VMInterface, 'list', path='', detail=False)
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-22 13:10:56 -04:00
@register_model_view(VMInterface)
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 child interfaces
child_interfaces = VMInterface.objects.restrict(request.user, 'view').filter(parent=instance)
child_interfaces_tables = tables.VMInterfaceTable(
child_interfaces,
exclude=('virtual_machine',),
orderable=False
)
Fixes: #7336 - VLAN Translation (#17745) * VLANTranslationPolicy and VLANTranslationRule models and all associated UI classes * Change VLANTranslationPolicy to a PrimaryModel and make name unique * Add serializer classes to InterfaceSerializer * Remake migrations * Add GraphQL typing * Skip tagged models in test * Missing migration * Remove get_absolute_url methods * Remove package-lock.json * Rebuild migration and add constraints and field options * Rebuild migrations * Use DynamicModelChoiceField for policy field * Make vlan_translation_policy fields on filtersets more consistent with existing __name convention * Add vlan_translation_table to VMInterface detail page * Add vlan_translation_policy to VMInterfaceSerializer * Move vlan_translation_policy fields to model and filterset mixins * Protect in-use policies against deletion * Add vlan_translation_policy to fields in VMInterfaceSerializer * Cleanup indentation * Remove unnecessary ordering column * Rebuild migrations * Search methods and registration * Ensure 'id' column is present by default * Add graphql types/filters/schema for VLANTranslationRule * Filterset tests * View tests * API and viewset tests (incomplete) * Add tags to VLANTranslationRuleForm * Complete viewset tests for VLANTranslationRule * Make VLANTranslationRule.policy nullable (but still required) * Revert "Make VLANTranslationRule.policy nullable (but still required)" This reverts commit 4c1bb437ef1a0a3593e5fbb87f08a0f158ea8c47. * Revert nullability * Explicitly prefetch policy in graphql * Documentation of new and affected models * Add note about select_related in graphql * Rework policy/rule documentation * Move vlan_translation_policy into 802.1Q Switching fieldset * Remove redundant InterfaceVLANTranslationTable * Conditionally include vlan_translation_table in interface.html and vminterface.html * Add description field to VLANTranslationRule * Define vlan_translation_table conditionally * Add policy (name) filter to VLANTranslationRuleFilterSet * Revert changes to adding-models.md (moved to another PR) * Dynamic table for linked rules in vlantranslationpolicy.html * Misc cleanup --------- Co-authored-by: Jeremy Stretch <jstretch@netboxlabs.com>
2024-10-30 17:09:46 -04:00
# Get VLAN translation rules
vlan_translation_table = None
if instance.vlan_translation_policy:
vlan_translation_table = VLANTranslationRuleTable(
data=instance.vlan_translation_policy.rules.all(),
orderable=False
)
# 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 {
'child_interfaces_table': child_interfaces_tables,
'vlan_table': vlan_table,
Fixes: #7336 - VLAN Translation (#17745) * VLANTranslationPolicy and VLANTranslationRule models and all associated UI classes * Change VLANTranslationPolicy to a PrimaryModel and make name unique * Add serializer classes to InterfaceSerializer * Remake migrations * Add GraphQL typing * Skip tagged models in test * Missing migration * Remove get_absolute_url methods * Remove package-lock.json * Rebuild migration and add constraints and field options * Rebuild migrations * Use DynamicModelChoiceField for policy field * Make vlan_translation_policy fields on filtersets more consistent with existing __name convention * Add vlan_translation_table to VMInterface detail page * Add vlan_translation_policy to VMInterfaceSerializer * Move vlan_translation_policy fields to model and filterset mixins * Protect in-use policies against deletion * Add vlan_translation_policy to fields in VMInterfaceSerializer * Cleanup indentation * Remove unnecessary ordering column * Rebuild migrations * Search methods and registration * Ensure 'id' column is present by default * Add graphql types/filters/schema for VLANTranslationRule * Filterset tests * View tests * API and viewset tests (incomplete) * Add tags to VLANTranslationRuleForm * Complete viewset tests for VLANTranslationRule * Make VLANTranslationRule.policy nullable (but still required) * Revert "Make VLANTranslationRule.policy nullable (but still required)" This reverts commit 4c1bb437ef1a0a3593e5fbb87f08a0f158ea8c47. * Revert nullability * Explicitly prefetch policy in graphql * Documentation of new and affected models * Add note about select_related in graphql * Rework policy/rule documentation * Move vlan_translation_policy into 802.1Q Switching fieldset * Remove redundant InterfaceVLANTranslationTable * Conditionally include vlan_translation_table in interface.html and vminterface.html * Add description field to VLANTranslationRule * Define vlan_translation_table conditionally * Add policy (name) filter to VLANTranslationRuleFilterSet * Revert changes to adding-models.md (moved to another PR) * Dynamic table for linked rules in vlantranslationpolicy.html * Misc cleanup --------- Co-authored-by: Jeremy Stretch <jstretch@netboxlabs.com>
2024-10-30 17:09:46 -04:00
'vlan_translation_table': vlan_translation_table,
}
2020-06-22 13:10:56 -04:00
@register_model_view(VMInterface, 'add', detail=False)
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
@register_model_view(VMInterface, 'edit')
2020-11-11 16:07:38 -05:00
class VMInterfaceEditView(generic.ObjectEditView):
2020-06-23 13:16:21 -04:00
queryset = VMInterface.objects.all()
form = forms.VMInterfaceForm
2017-08-18 14:37:19 -04:00
@register_model_view(VMInterface, 'delete')
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
@register_model_view(VMInterface, 'bulk_import', detail=False)
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.VMInterfaceImportForm
2020-06-23 17:01:57 -04:00
@register_model_view(VMInterface, 'bulk_edit', path='edit', detail=False)
2020-11-11 16:07:38 -05:00
class VMInterfaceBulkEditView(generic.BulkEditView):
2020-06-23 13:16:21 -04:00
queryset = VMInterface.objects.all()
filterset = filtersets.VMInterfaceFilterSet
2020-06-23 16:39:43 -04:00
table = tables.VMInterfaceTable
form = forms.VMInterfaceBulkEditForm
2017-08-18 14:37:19 -04:00
@register_model_view(VMInterface, 'bulk_rename', path='rename', detail=False)
2020-11-11 16:07:38 -05:00
class VMInterfaceBulkRenameView(generic.BulkRenameView):
queryset = VMInterface.objects.all()
form = forms.VMInterfaceBulkRenameForm
@register_model_view(VMInterface, 'bulk_delete', path='delete', detail=False)
2020-11-11 16:07:38 -05:00
class VMInterfaceBulkDeleteView(generic.BulkDeleteView):
# Ensure child interfaces are deleted prior to their parents
queryset = VMInterface.objects.order_by('virtual_machine', 'parent', CollateAsChar('_name'))
filterset = filtersets.VMInterfaceFilterSet
2020-06-23 16:39:43 -04:00
table = tables.VMInterfaceTable
#
# Virtual disks
#
@register_model_view(VirtualDisk, 'list', path='', detail=False)
class VirtualDiskListView(generic.ObjectListView):
queryset = VirtualDisk.objects.all()
filterset = filtersets.VirtualDiskFilterSet
filterset_form = forms.VirtualDiskFilterForm
table = tables.VirtualDiskTable
@register_model_view(VirtualDisk)
class VirtualDiskView(generic.ObjectView):
queryset = VirtualDisk.objects.all()
@register_model_view(VirtualDisk, 'add', detail=False)
class VirtualDiskCreateView(generic.ComponentCreateView):
queryset = VirtualDisk.objects.all()
form = forms.VirtualDiskCreateForm
model_form = forms.VirtualDiskForm
@register_model_view(VirtualDisk, 'edit')
class VirtualDiskEditView(generic.ObjectEditView):
queryset = VirtualDisk.objects.all()
form = forms.VirtualDiskForm
@register_model_view(VirtualDisk, 'delete')
class VirtualDiskDeleteView(generic.ObjectDeleteView):
queryset = VirtualDisk.objects.all()
@register_model_view(VirtualDisk, 'bulk_import', detail=False)
class VirtualDiskBulkImportView(generic.BulkImportView):
queryset = VirtualDisk.objects.all()
model_form = forms.VirtualDiskImportForm
@register_model_view(VirtualDisk, 'bulk_edit', path='edit', detail=False)
class VirtualDiskBulkEditView(generic.BulkEditView):
queryset = VirtualDisk.objects.all()
filterset = filtersets.VirtualDiskFilterSet
table = tables.VirtualDiskTable
form = forms.VirtualDiskBulkEditForm
@register_model_view(VirtualDisk, 'bulk_rename', path='rename', detail=False)
class VirtualDiskBulkRenameView(generic.BulkRenameView):
queryset = VirtualDisk.objects.all()
form = forms.VirtualDiskBulkRenameForm
@register_model_view(VirtualDisk, 'bulk_delete', path='delete', detail=False)
class VirtualDiskBulkDeleteView(generic.BulkDeleteView):
queryset = VirtualDisk.objects.all()
filterset = filtersets.VirtualDiskFilterSet
table = tables.VirtualDiskTable
#
# 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
default_return_url = 'virtualization:virtualmachine_list'
def get_required_permission(self):
return 'virtualization.add_vminterface'
class VirtualMachineBulkAddVirtualDiskView(generic.BulkComponentCreateView):
parent_model = VirtualMachine
parent_field = 'virtual_machine'
form = forms.VirtualDiskBulkCreateForm
queryset = VirtualDisk.objects.all()
model_form = forms.VirtualDiskForm
filterset = filtersets.VirtualMachineFilterSet
table = tables.VirtualMachineTable
default_return_url = 'virtualization:virtualmachine_list'
def get_required_permission(self):
return 'virtualization.add_virtualdisk'