mirror of
https://github.com/netbox-community/netbox.git
synced 2025-12-18 19:32:24 -06:00
Ditched VMInterface in favor of reusing dcim.Interface
This commit is contained in:
@@ -3,10 +3,12 @@ from __future__ import unicode_literals
|
||||
from rest_framework import serializers
|
||||
|
||||
from dcim.api.serializers import NestedPlatformSerializer
|
||||
from dcim.constants import VIFACE_FF_CHOICES
|
||||
from dcim.models import Interface
|
||||
from extras.api.customfields import CustomFieldModelSerializer
|
||||
from tenancy.api.serializers import NestedTenantSerializer
|
||||
from utilities.api import ValidatedModelSerializer
|
||||
from virtualization.models import Cluster, ClusterGroup, ClusterType, VirtualMachine, VMInterface
|
||||
from utilities.api import ChoiceFieldSerializer, ValidatedModelSerializer
|
||||
from virtualization.models import Cluster, ClusterGroup, ClusterType, VirtualMachine
|
||||
|
||||
|
||||
#
|
||||
@@ -102,7 +104,7 @@ class NestedVirtualMachineSerializer(serializers.ModelSerializer):
|
||||
class WritableVirtualMachineSerializer(CustomFieldModelSerializer):
|
||||
|
||||
class Meta:
|
||||
model = Cluster
|
||||
model = VirtualMachine
|
||||
fields = [
|
||||
'id', 'name', 'cluster', 'tenant', 'platform', 'primary_ip4', 'primary_ip6', 'comments', 'custom_fields',
|
||||
]
|
||||
@@ -112,28 +114,29 @@ class WritableVirtualMachineSerializer(CustomFieldModelSerializer):
|
||||
# VM interfaces
|
||||
#
|
||||
|
||||
class VMInterfaceSerializer(serializers.ModelSerializer):
|
||||
class InterfaceSerializer(serializers.ModelSerializer):
|
||||
virtual_machine = NestedVirtualMachineSerializer()
|
||||
form_factor = ChoiceFieldSerializer(choices=VIFACE_FF_CHOICES)
|
||||
|
||||
class Meta:
|
||||
model = VMInterface
|
||||
model = Interface
|
||||
fields = [
|
||||
'id', 'name', 'virtual_machine', 'enabled', 'mac_address', 'mtu', 'description',
|
||||
'id', 'name', 'virtual_machine', 'form_factor', 'enabled', 'mac_address', 'mtu', 'description',
|
||||
]
|
||||
|
||||
|
||||
class NestedVMInterfaceSerializer(serializers.ModelSerializer):
|
||||
url = serializers.HyperlinkedIdentityField(view_name='virtualization-api:vminterface-detail')
|
||||
class NestedInterfaceSerializer(serializers.ModelSerializer):
|
||||
url = serializers.HyperlinkedIdentityField(view_name='virtualization-api:interface-detail')
|
||||
|
||||
class Meta:
|
||||
model = VMInterface
|
||||
model = Interface
|
||||
fields = ['id', 'url', 'name']
|
||||
|
||||
|
||||
class WritableVMInterfaceSerializer(ValidatedModelSerializer):
|
||||
class WritableInterfaceSerializer(ValidatedModelSerializer):
|
||||
|
||||
class Meta:
|
||||
model = VMInterface
|
||||
model = Interface
|
||||
fields = [
|
||||
'id', 'name', 'virtual_machine', 'enabled', 'mac_address', 'mtu', 'description',
|
||||
'id', 'name', 'virtual_machine', 'form_factor', 'enabled', 'mac_address', 'mtu', 'description',
|
||||
]
|
||||
|
||||
@@ -23,7 +23,7 @@ router.register(r'clusters', views.ClusterViewSet)
|
||||
|
||||
# VirtualMachines
|
||||
router.register(r'virtual-machines', views.VirtualMachineViewSet)
|
||||
router.register(r'vm-interfaces', views.VMInterfaceViewSet)
|
||||
router.register(r'interfaces', views.InterfaceViewSet)
|
||||
|
||||
app_name = 'virtualization-api'
|
||||
urlpatterns = router.urls
|
||||
|
||||
@@ -2,10 +2,11 @@ from __future__ import unicode_literals
|
||||
|
||||
from rest_framework.viewsets import ModelViewSet
|
||||
|
||||
from dcim.models import Interface
|
||||
from extras.api.views import CustomFieldModelViewSet
|
||||
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
|
||||
from . import serializers
|
||||
|
||||
|
||||
@@ -41,7 +42,7 @@ class VirtualMachineViewSet(WritableSerializerMixin, CustomFieldModelViewSet):
|
||||
filter_class = filters.VirtualMachineFilter
|
||||
|
||||
|
||||
class VMInterfaceViewSet(WritableSerializerMixin, ModelViewSet):
|
||||
queryset = VMInterface.objects.select_related('virtual_machine')
|
||||
serializer_class = serializers.VMInterfaceSerializer
|
||||
write_serializer_class = serializers.WritableVMInterfaceSerializer
|
||||
class InterfaceViewSet(WritableSerializerMixin, ModelViewSet):
|
||||
queryset = Interface.objects.filter(virtual_machine__isnull=False).select_related('virtual_machine')
|
||||
serializer_class = serializers.InterfaceSerializer
|
||||
write_serializer_class = serializers.WritableInterfaceSerializer
|
||||
|
||||
@@ -5,8 +5,9 @@ from mptt.forms import TreeNodeChoiceField
|
||||
from django import forms
|
||||
from django.db.models import Count
|
||||
|
||||
from dcim.constants import VIFACE_FF_CHOICES
|
||||
from dcim.formfields import MACAddressFormField
|
||||
from dcim.models import Device, Rack, Region, Site
|
||||
from dcim.models import Device, Interface, Rack, Region, Site
|
||||
from extras.forms import CustomFieldBulkEditForm, CustomFieldForm, CustomFieldFilterForm
|
||||
from tenancy.forms import TenancyForm
|
||||
from tenancy.models import Tenant
|
||||
@@ -15,7 +16,7 @@ from utilities.forms import (
|
||||
ChainedModelChoiceField, ChainedModelMultipleChoiceField, ComponentForm, ConfirmationForm, ExpandableNameField,
|
||||
FilterChoiceField, SlugField,
|
||||
)
|
||||
from .models import Cluster, ClusterGroup, ClusterType, VirtualMachine, VMInterface
|
||||
from .models import Cluster, ClusterGroup, ClusterType, VirtualMachine
|
||||
|
||||
|
||||
#
|
||||
@@ -230,18 +231,19 @@ class VirtualMachineFilterForm(BootstrapMixin, CustomFieldFilterForm):
|
||||
# VM interfaces
|
||||
#
|
||||
|
||||
class VMInterfaceForm(BootstrapMixin, forms.ModelForm):
|
||||
class InterfaceForm(BootstrapMixin, forms.ModelForm):
|
||||
|
||||
class Meta:
|
||||
model = VMInterface
|
||||
fields = ['virtual_machine', 'name', 'enabled', 'mac_address', 'mtu', 'description']
|
||||
model = Interface
|
||||
fields = ['virtual_machine', 'name', 'form_factor', 'enabled', 'mac_address', 'mtu', 'description']
|
||||
widgets = {
|
||||
'virtual_machine': forms.HiddenInput(),
|
||||
}
|
||||
|
||||
|
||||
class VMInterfaceCreateForm(ComponentForm):
|
||||
class InterfaceCreateForm(ComponentForm):
|
||||
name_pattern = ExpandableNameField(label='Name')
|
||||
form_factor = forms.ChoiceField(choices=VIFACE_FF_CHOICES)
|
||||
enabled = forms.BooleanField(required=False)
|
||||
mtu = forms.IntegerField(required=False, min_value=1, max_value=32767, label='MTU')
|
||||
mac_address = MACAddressFormField(required=False, label='MAC Address')
|
||||
@@ -253,11 +255,11 @@ class VMInterfaceCreateForm(ComponentForm):
|
||||
kwargs['initial'] = kwargs.get('initial', {}).copy()
|
||||
kwargs['initial'].update({'enabled': True})
|
||||
|
||||
super(VMInterfaceCreateForm, self).__init__(*args, **kwargs)
|
||||
super(InterfaceCreateForm, self).__init__(*args, **kwargs)
|
||||
|
||||
|
||||
class VMInterfaceBulkEditForm(BootstrapMixin, BulkEditForm):
|
||||
pk = forms.ModelMultipleChoiceField(queryset=VMInterface.objects.all(), widget=forms.MultipleHiddenInput)
|
||||
class InterfaceBulkEditForm(BootstrapMixin, BulkEditForm):
|
||||
pk = forms.ModelMultipleChoiceField(queryset=Interface.objects.all(), widget=forms.MultipleHiddenInput)
|
||||
virtual_machine = forms.ModelChoiceField(queryset=VirtualMachine.objects.all(), widget=forms.HiddenInput)
|
||||
enabled = forms.NullBooleanField(required=False, widget=BulkEditNullBooleanSelect)
|
||||
mtu = forms.IntegerField(required=False, min_value=1, max_value=32767, label='MTU')
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Generated by Django 1.11.4 on 2017-08-18 19:46
|
||||
# Generated by Django 1.11.4 on 2017-08-29 17:49
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import dcim.fields
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
import extras.models
|
||||
@@ -13,9 +12,9 @@ class Migration(migrations.Migration):
|
||||
initial = True
|
||||
|
||||
dependencies = [
|
||||
('dcim', '0041_napalm_integration'),
|
||||
('ipam', '0019_ipaddress_interface_to_gfk'),
|
||||
('tenancy', '0003_unicode_literals'),
|
||||
('ipam', '0018_remove_service_uniqueness_constraint'),
|
||||
('dcim', '0041_napalm_integration'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
@@ -77,22 +76,6 @@ class Migration(migrations.Migration):
|
||||
},
|
||||
bases=(models.Model, extras.models.CustomFieldModel),
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='VMInterface',
|
||||
fields=[
|
||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('name', models.CharField(max_length=30)),
|
||||
('enabled', models.BooleanField(default=True)),
|
||||
('mac_address', dcim.fields.MACAddressField(blank=True, null=True, verbose_name='MAC Address')),
|
||||
('mtu', models.PositiveSmallIntegerField(blank=True, null=True, verbose_name='MTU')),
|
||||
('description', models.CharField(blank=True, max_length=100)),
|
||||
('virtual_machine', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='interfaces', to='virtualization.VirtualMachine')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'VM interface',
|
||||
'ordering': ['virtual_machine', 'name'],
|
||||
},
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='cluster',
|
||||
name='group',
|
||||
@@ -103,8 +86,4 @@ class Migration(migrations.Migration):
|
||||
name='type',
|
||||
field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='clusters', to='virtualization.ClusterType'),
|
||||
),
|
||||
migrations.AlterUniqueTogether(
|
||||
name='vminterface',
|
||||
unique_together=set([('virtual_machine', 'name')]),
|
||||
),
|
||||
]
|
||||
@@ -188,49 +188,3 @@ class VirtualMachine(CreatedUpdatedModel, CustomFieldModel):
|
||||
|
||||
def get_absolute_url(self):
|
||||
return reverse('virtualization:virtualmachine', args=[self.pk])
|
||||
|
||||
|
||||
@python_2_unicode_compatible
|
||||
class VMInterface(models.Model):
|
||||
"""
|
||||
A virtual interface which belongs to a VirtualMachine. Like the dcim.Interface model, IPAddresses can be assigned to
|
||||
VMInterfaces.
|
||||
"""
|
||||
virtual_machine = models.ForeignKey(
|
||||
to=VirtualMachine,
|
||||
on_delete=models.CASCADE,
|
||||
related_name='interfaces'
|
||||
)
|
||||
name = models.CharField(
|
||||
max_length=30
|
||||
)
|
||||
enabled = models.BooleanField(
|
||||
default=True
|
||||
)
|
||||
mac_address = MACAddressField(
|
||||
blank=True,
|
||||
null=True,
|
||||
verbose_name='MAC Address'
|
||||
)
|
||||
mtu = models.PositiveSmallIntegerField(
|
||||
blank=True,
|
||||
null=True,
|
||||
verbose_name='MTU'
|
||||
)
|
||||
description = models.CharField(
|
||||
max_length=100,
|
||||
blank=True
|
||||
)
|
||||
ip_addresses = GenericRelation(
|
||||
to='ipam.IPAddress',
|
||||
content_type_field='interface_type',
|
||||
object_id_field='interface_id'
|
||||
)
|
||||
|
||||
class Meta:
|
||||
ordering = ['virtual_machine', 'name']
|
||||
unique_together = ['virtual_machine', 'name']
|
||||
verbose_name = 'VM interface'
|
||||
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
@@ -3,8 +3,9 @@ from __future__ import unicode_literals
|
||||
import django_tables2 as tables
|
||||
from django_tables2.utils import Accessor
|
||||
|
||||
from dcim.models import Interface
|
||||
from utilities.tables import BaseTable, ToggleColumn
|
||||
from .models import Cluster, ClusterGroup, ClusterType, VirtualMachine, VMInterface
|
||||
from .models import Cluster, ClusterGroup, ClusterType, VirtualMachine
|
||||
|
||||
|
||||
CLUSTERTYPE_ACTIONS = """
|
||||
@@ -89,8 +90,8 @@ class VirtualMachineTable(BaseTable):
|
||||
# VM components
|
||||
#
|
||||
|
||||
class VMInterfaceTable(BaseTable):
|
||||
class InterfaceTable(BaseTable):
|
||||
|
||||
class Meta(BaseTable.Meta):
|
||||
model = VMInterface
|
||||
model = Interface
|
||||
fields = ('name', 'enabled', 'description')
|
||||
|
||||
@@ -41,11 +41,11 @@ urlpatterns = [
|
||||
url(r'^virtual-machines/(?P<pk>\d+)/delete/$', views.VirtualMachineDeleteView.as_view(), name='virtualmachine_delete'),
|
||||
|
||||
# VM interfaces
|
||||
# url(r'^virtual-machines/interfaces/add/$', views.VMBulkAddVMInterfaceView.as_view(), name='vm_bulk_add_vminterface'),
|
||||
url(r'^virtual-machines/(?P<pk>\d+)/interfaces/add/$', views.VMInterfaceCreateView.as_view(), name='vminterface_add'),
|
||||
url(r'^virtual-machines/(?P<pk>\d+)/interfaces/edit/$', views.VMInterfaceBulkEditView.as_view(), name='vminterface_bulk_edit'),
|
||||
url(r'^virtual-machines/(?P<pk>\d+)/interfaces/delete/$', views.VMInterfaceBulkDeleteView.as_view(), name='vminterface_bulk_delete'),
|
||||
url(r'^vm-interfaces/(?P<pk>\d+)/edit/$', views.VMInterfaceEditView.as_view(), name='vminterface_edit'),
|
||||
url(r'^vm-interfaces/(?P<pk>\d+)/delete/$', views.VMInterfaceDeleteView.as_view(), name='vminterface_delete'),
|
||||
# url(r'^virtual-machines/interfaces/add/$', views.VMBulkAddInterfaceView.as_view(), name='vm_bulk_add_interface'),
|
||||
url(r'^virtual-machines/(?P<pk>\d+)/interfaces/add/$', views.InterfaceCreateView.as_view(), name='interface_add'),
|
||||
url(r'^virtual-machines/(?P<pk>\d+)/interfaces/edit/$', views.InterfaceBulkEditView.as_view(), name='interface_bulk_edit'),
|
||||
url(r'^virtual-machines/(?P<pk>\d+)/interfaces/delete/$', views.InterfaceBulkDeleteView.as_view(), name='interface_bulk_delete'),
|
||||
url(r'^vm-interfaces/(?P<pk>\d+)/edit/$', views.InterfaceEditView.as_view(), name='interface_edit'),
|
||||
url(r'^vm-interfaces/(?P<pk>\d+)/delete/$', views.InterfaceDeleteView.as_view(), name='interface_delete'),
|
||||
|
||||
]
|
||||
|
||||
@@ -7,13 +7,13 @@ from django.shortcuts import get_object_or_404, redirect, render
|
||||
from django.urls import reverse
|
||||
from django.views.generic import View
|
||||
|
||||
from dcim.models import Device
|
||||
from dcim.models import Device, Interface
|
||||
from dcim.tables import DeviceTable
|
||||
from utilities.views import (
|
||||
BulkDeleteView, BulkEditView, BulkImportView, ComponentCreateView, ComponentDeleteView, ComponentEditView,
|
||||
ObjectDeleteView, ObjectEditView, ObjectListView,
|
||||
)
|
||||
from .models import Cluster, ClusterGroup, ClusterType, VirtualMachine, VMInterface
|
||||
from .models import Cluster, ClusterGroup, ClusterType, VirtualMachine
|
||||
from . import filters
|
||||
from . import forms
|
||||
from . import tables
|
||||
@@ -235,7 +235,7 @@ class VirtualMachineView(View):
|
||||
def get(self, request, pk):
|
||||
|
||||
vm = get_object_or_404(VirtualMachine.objects.select_related('tenant__group'), pk=pk)
|
||||
interfaces = VMInterface.objects.filter(virtual_machine=vm)
|
||||
interfaces = Interface.objects.filter(virtual_machine=vm)
|
||||
|
||||
return render(request, 'virtualization/virtualmachine.html', {
|
||||
'vm': vm,
|
||||
@@ -282,39 +282,39 @@ class VirtualMachineBulkEditView(PermissionRequiredMixin, BulkEditView):
|
||||
# VM interfaces
|
||||
#
|
||||
|
||||
class VMInterfaceCreateView(PermissionRequiredMixin, ComponentCreateView):
|
||||
permission_required = 'virtualization.add_vminterface'
|
||||
class InterfaceCreateView(PermissionRequiredMixin, ComponentCreateView):
|
||||
permission_required = 'dcim.add_interface'
|
||||
parent_model = VirtualMachine
|
||||
parent_field = 'virtual_machine'
|
||||
model = VMInterface
|
||||
form = forms.VMInterfaceCreateForm
|
||||
model_form = forms.VMInterfaceForm
|
||||
model = Interface
|
||||
form = forms.InterfaceCreateForm
|
||||
model_form = forms.InterfaceForm
|
||||
template_name = 'virtualization/virtualmachine_component_add.html'
|
||||
|
||||
|
||||
class VMInterfaceEditView(PermissionRequiredMixin, ComponentEditView):
|
||||
permission_required = 'virtualization.change_vminterface'
|
||||
model = VMInterface
|
||||
class InterfaceEditView(PermissionRequiredMixin, ComponentEditView):
|
||||
permission_required = 'dcim.change_interface'
|
||||
model = Interface
|
||||
parent_field = 'virtual_machine'
|
||||
form_class = forms.VMInterfaceForm
|
||||
form_class = forms.InterfaceForm
|
||||
|
||||
|
||||
class VMInterfaceDeleteView(PermissionRequiredMixin, ComponentDeleteView):
|
||||
permission_required = 'virtualization.delete_vminterface'
|
||||
model = VMInterface
|
||||
class InterfaceDeleteView(PermissionRequiredMixin, ComponentDeleteView):
|
||||
permission_required = 'dcim.delete_interface'
|
||||
model = Interface
|
||||
parent_field = 'virtual_machine'
|
||||
|
||||
|
||||
class VMInterfaceBulkEditView(PermissionRequiredMixin, BulkEditView):
|
||||
permission_required = 'virtualization.change_vminterface'
|
||||
cls = VMInterface
|
||||
class InterfaceBulkEditView(PermissionRequiredMixin, BulkEditView):
|
||||
permission_required = 'dcim.change_interface'
|
||||
cls = Interface
|
||||
parent_cls = VirtualMachine
|
||||
table = tables.VMInterfaceTable
|
||||
form = forms.VMInterfaceBulkEditForm
|
||||
table = tables.InterfaceTable
|
||||
form = forms.InterfaceBulkEditForm
|
||||
|
||||
|
||||
class VMInterfaceBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
|
||||
permission_required = 'virtualization.delete_vminterface'
|
||||
cls = VMInterface
|
||||
class InterfaceBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
|
||||
permission_required = 'dcim.delete_interface'
|
||||
cls = Interface
|
||||
parent_cls = VirtualMachine
|
||||
table = tables.VMInterfaceTable
|
||||
table = tables.InterfaceTable
|
||||
|
||||
Reference in New Issue
Block a user