mirror of
https://github.com/netbox-community/netbox.git
synced 2025-08-23 07:56:44 -06:00
8356 add supplemental forms
This commit is contained in:
parent
5bcf351bdc
commit
12861a19a8
@ -10,7 +10,7 @@ from netbox.filtersets import OrganizationalModelFilterSet, NetBoxModelFilterSet
|
||||
from tenancy.filtersets import TenancyFilterSet, ContactModelFilterSet
|
||||
from utilities.filters import MultiValueCharFilter, MultiValueMACAddressFilter, TreeNodeMultipleChoiceFilter
|
||||
from .choices import *
|
||||
from .models import Cluster, ClusterGroup, ClusterType, VirtualMachine, VMInterface
|
||||
from .models import Cluster, ClusterGroup, ClusterType, VirtualDisk, VirtualMachine, VMInterface
|
||||
|
||||
__all__ = (
|
||||
'ClusterFilterSet',
|
||||
@ -303,3 +303,28 @@ class VMInterfaceFilterSet(NetBoxModelFilterSet, CommonInterfaceFilterSet):
|
||||
Q(name__icontains=value) |
|
||||
Q(description__icontains=value)
|
||||
)
|
||||
|
||||
|
||||
class VirtualDiskFilterSet(NetBoxModelFilterSet):
|
||||
virtual_machine_id = django_filters.ModelMultipleChoiceFilter(
|
||||
field_name='virtual_machine',
|
||||
queryset=VirtualMachine.objects.all(),
|
||||
label=_('Virtual machine (ID)'),
|
||||
)
|
||||
virtual_machine = django_filters.ModelMultipleChoiceFilter(
|
||||
field_name='virtual_machine__name',
|
||||
queryset=VirtualMachine.objects.all(),
|
||||
to_field_name='name',
|
||||
label=_('Virtual machine'),
|
||||
)
|
||||
|
||||
class Meta:
|
||||
model = VirtualDisk
|
||||
fields = ['id', 'name', 'size',]
|
||||
|
||||
def search(self, queryset, name, value):
|
||||
if not value.strip():
|
||||
return queryset
|
||||
return queryset.filter(
|
||||
Q(name__icontains=value)
|
||||
)
|
||||
|
@ -3,7 +3,7 @@ from django.utils.translation import gettext_lazy as _
|
||||
|
||||
from utilities.forms import BootstrapMixin, form_from_model
|
||||
from utilities.forms.fields import ExpandableNameField
|
||||
from virtualization.models import VMInterface, VirtualMachine
|
||||
from virtualization.models import VirtualDisk, VMInterface, VirtualMachine
|
||||
|
||||
__all__ = (
|
||||
'VMInterfaceBulkCreateForm',
|
||||
@ -30,3 +30,10 @@ class VMInterfaceBulkCreateForm(
|
||||
VirtualMachineBulkAddComponentForm
|
||||
):
|
||||
replication_fields = ('name',)
|
||||
|
||||
|
||||
class VirtualDiskBulkCreateForm(
|
||||
form_from_model(VirtualDisk, ['tags']),
|
||||
VirtualMachineBulkAddComponentForm
|
||||
):
|
||||
replication_fields = ('name', 'size')
|
||||
|
@ -18,6 +18,7 @@ __all__ = (
|
||||
'ClusterBulkEditForm',
|
||||
'ClusterGroupBulkEditForm',
|
||||
'ClusterTypeBulkEditForm',
|
||||
'VirtualDiskBulkEditForm',
|
||||
'VirtualMachineBulkEditForm',
|
||||
'VMInterfaceBulkEditForm',
|
||||
'VMInterfaceBulkRenameForm',
|
||||
@ -315,3 +316,19 @@ class VMInterfaceBulkRenameForm(BulkRenameForm):
|
||||
queryset=VMInterface.objects.all(),
|
||||
widget=forms.MultipleHiddenInput()
|
||||
)
|
||||
|
||||
|
||||
class VirtualDiskBulkEditForm(NetBoxModelBulkEditForm):
|
||||
virtual_machine = forms.ModelChoiceField(
|
||||
label=_('Virtual machine'),
|
||||
queryset=VirtualMachine.objects.all(),
|
||||
required=False,
|
||||
disabled=True,
|
||||
widget=forms.HiddenInput()
|
||||
)
|
||||
|
||||
model = VirtualDisk
|
||||
fieldsets = (
|
||||
(None, ('mtu', 'enabled', 'vrf', 'size')),
|
||||
)
|
||||
nullable_fields = ()
|
||||
|
@ -14,6 +14,7 @@ __all__ = (
|
||||
'ClusterImportForm',
|
||||
'ClusterGroupImportForm',
|
||||
'ClusterTypeImportForm',
|
||||
'VirtualDiskImportForm',
|
||||
'VirtualMachineImportForm',
|
||||
'VMInterfaceImportForm',
|
||||
)
|
||||
@ -199,3 +200,17 @@ class VMInterfaceImportForm(NetBoxModelImportForm):
|
||||
return True
|
||||
else:
|
||||
return self.cleaned_data['enabled']
|
||||
|
||||
|
||||
class VirtualDiskImportForm(NetBoxModelImportForm):
|
||||
virtual_machine = CSVModelChoiceField(
|
||||
label=_('Virtual machine'),
|
||||
queryset=VirtualMachine.objects.all(),
|
||||
to_field_name='name'
|
||||
)
|
||||
|
||||
class Meta:
|
||||
model = VirtualDisk
|
||||
fields = (
|
||||
'virtual_machine', 'name', 'size', 'tags'
|
||||
)
|
||||
|
@ -16,6 +16,7 @@ __all__ = (
|
||||
'ClusterFilterForm',
|
||||
'ClusterGroupFilterForm',
|
||||
'ClusterTypeFilterForm',
|
||||
'VirtualDiskFilterForm',
|
||||
'VirtualMachineFilterForm',
|
||||
'VMInterfaceFilterForm',
|
||||
)
|
||||
@ -221,3 +222,20 @@ class VMInterfaceFilterForm(NetBoxModelFilterSetForm):
|
||||
label=_('L2VPN')
|
||||
)
|
||||
tag = TagFilterField(model)
|
||||
|
||||
|
||||
class VirtualDiskFilterForm(NetBoxModelFilterSetForm):
|
||||
model = VirtualDisk
|
||||
fieldsets = (
|
||||
(None, ('q', 'filter_id', 'tag')),
|
||||
(_('Virtual Machine'), ('virtual_machine_id')),
|
||||
)
|
||||
virtual_machine_id = DynamicModelMultipleChoiceField(
|
||||
queryset=VirtualMachine.objects.all(),
|
||||
required=False,
|
||||
query_params={
|
||||
'cluster_id': '$cluster_id'
|
||||
},
|
||||
label=_('Virtual machine')
|
||||
)
|
||||
tag = TagFilterField(model)
|
||||
|
@ -22,6 +22,7 @@ __all__ = (
|
||||
'ClusterGroupForm',
|
||||
'ClusterRemoveDevicesForm',
|
||||
'ClusterTypeForm',
|
||||
'VirtualDiskForm',
|
||||
'VirtualMachineForm',
|
||||
'VMInterfaceForm',
|
||||
)
|
||||
@ -349,3 +350,28 @@ class VMInterfaceForm(InterfaceCommonForm, NetBoxModelForm):
|
||||
# Disable reassignment of VirtualMachine when editing an existing instance
|
||||
if self.instance.pk:
|
||||
self.fields['virtual_machine'].disabled = True
|
||||
|
||||
|
||||
class VirtualDiskForm(NetBoxModelForm):
|
||||
virtual_machine = DynamicModelChoiceField(
|
||||
label=_('Virtual machine'),
|
||||
queryset=VirtualMachine.objects.all(),
|
||||
selector=True
|
||||
)
|
||||
|
||||
fieldsets = (
|
||||
(_(''), ('virtual_machine', 'name', 'size', 'tags')),
|
||||
)
|
||||
|
||||
class Meta:
|
||||
model = VirtualDisk
|
||||
fields = [
|
||||
'virtual_machine', 'name', 'size', 'tags',
|
||||
]
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
# Disable reassignment of VirtualMachine when editing an existing instance
|
||||
if self.instance.pk:
|
||||
self.fields['virtual_machine'].disabled = True
|
||||
|
@ -21,6 +21,7 @@ from utilities.tracking import TrackingModelMixin
|
||||
from virtualization.choices import *
|
||||
|
||||
__all__ = (
|
||||
'VirtualDisk',
|
||||
'VirtualMachine',
|
||||
'VMInterface',
|
||||
)
|
||||
|
@ -4,9 +4,10 @@ from django.utils.translation import gettext_lazy as _
|
||||
from dcim.tables.devices import BaseInterfaceTable
|
||||
from netbox.tables import NetBoxTable, columns
|
||||
from tenancy.tables import ContactsColumnMixin, TenancyColumnsMixin
|
||||
from virtualization.models import VirtualMachine, VMInterface
|
||||
from virtualization.models import VirtualDisk, VirtualMachine, VMInterface
|
||||
|
||||
__all__ = (
|
||||
'VirtualDiskTable',
|
||||
'VirtualMachineTable',
|
||||
'VirtualMachineVMInterfaceTable',
|
||||
'VMInterfaceTable',
|
||||
@ -155,3 +156,19 @@ class VirtualMachineVMInterfaceTable(VMInterfaceTable):
|
||||
row_attrs = {
|
||||
'data-name': lambda record: record.name,
|
||||
}
|
||||
|
||||
|
||||
class VirtualDiskTable(VMInterfaceTable):
|
||||
actions = columns.ActionsColumn(
|
||||
actions=('edit', 'delete'),
|
||||
)
|
||||
|
||||
class Meta(NetBoxTable.Meta):
|
||||
model = VirtualDisk
|
||||
fields = (
|
||||
'pk', 'id', 'name', 'size', 'tags', 'actions',
|
||||
)
|
||||
default_columns = ('pk', 'name', 'size')
|
||||
row_attrs = {
|
||||
'data-name': lambda record: record.name,
|
||||
}
|
||||
|
@ -48,4 +48,13 @@ urlpatterns = [
|
||||
path('interfaces/<int:pk>/', include(get_model_urls('virtualization', 'vminterface'))),
|
||||
path('virtual-machines/interfaces/add/', views.VirtualMachineBulkAddInterfaceView.as_view(), name='virtualmachine_bulk_add_vminterface'),
|
||||
|
||||
# Virtual disks
|
||||
# path('disks/', views.VirtualDiskListView.as_view(), name='virtualdisk_list'),
|
||||
# path('disks/add/', views.VirtualDiskCreateView.as_view(), name='virtualdisk_add'),
|
||||
# path('disks/import/', views.VirtualDiskBulkImportView.as_view(), name='virtualdisk_import'),
|
||||
# path('disks/edit/', views.VirtualDiskBulkEditView.as_view(), name='virtualdisk_bulk_edit'),
|
||||
# path('disks/rename/', views.VirtualDiskBulkRenameView.as_view(), name='virtualdisk_bulk_rename'),
|
||||
# path('disks/delete/', views.VirtualDiskBulkDeleteView.as_view(), name='virtualdisk_bulk_delete'),
|
||||
# path('disks/<int:pk>/', include(get_model_urls('virtualization', 'virtualdisk'))),
|
||||
# path('virtual-machines/disks/add/', views.VirtualMachineBulkAddDiskView.as_view(), name='virtualmachine_bulk_add_disk'),
|
||||
]
|
||||
|
@ -21,7 +21,7 @@ from tenancy.views import ObjectContactsView
|
||||
from utilities.utils import count_related
|
||||
from utilities.views import ViewTab, register_model_view
|
||||
from . import filtersets, forms, tables
|
||||
from .models import Cluster, ClusterGroup, ClusterType, VirtualMachine, VMInterface
|
||||
from .models import Cluster, ClusterGroup, ClusterType, VirtualDisk, VirtualMachine, VMInterface
|
||||
|
||||
|
||||
#
|
||||
@ -574,3 +574,83 @@ class VirtualMachineBulkAddInterfaceView(generic.BulkComponentCreateView):
|
||||
|
||||
def get_required_permission(self):
|
||||
return f'virtualization.add_vminterface'
|
||||
|
||||
|
||||
#
|
||||
# Virtual Disk
|
||||
#
|
||||
|
||||
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()
|
||||
|
||||
def get_extra_context(self, request, instance):
|
||||
|
||||
# Get child interfaces
|
||||
child_interfaces = VirtualDisk.objects.restrict(request.user, 'view').filter(parent=instance)
|
||||
child_interfaces_tables = tables.VirtualDiskTable(
|
||||
child_interfaces,
|
||||
exclude=('virtual_machine',),
|
||||
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,
|
||||
}
|
||||
|
||||
|
||||
# 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()
|
||||
|
||||
|
||||
class VirtualDiskBulkImportView(generic.BulkImportView):
|
||||
queryset = VirtualDisk.objects.all()
|
||||
model_form = forms.VirtualDiskImportForm
|
||||
|
||||
|
||||
class VirtualDiskBulkEditView(generic.BulkEditView):
|
||||
queryset = VirtualDisk.objects.all()
|
||||
filterset = filtersets.VirtualDiskFilterSet
|
||||
table = tables.VirtualDiskTable
|
||||
form = forms.VirtualDiskBulkEditForm
|
||||
|
||||
|
||||
class VirtualDiskBulkDeleteView(generic.BulkDeleteView):
|
||||
queryset = VirtualDisk.objects.all()
|
||||
filterset = filtersets.VirtualDiskFilterSet
|
||||
table = tables.VirtualDiskTable
|
||||
|
Loading…
Reference in New Issue
Block a user