Ditched VMInterface in favor of reusing dcim.Interface

This commit is contained in:
Jeremy Stretch
2017-08-29 14:24:58 -04:00
parent cb9404f29a
commit d52e5981a6
17 changed files with 158 additions and 237 deletions

View File

@@ -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',
]

View File

@@ -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

View File

@@ -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

View File

@@ -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')

View File

@@ -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')]),
),
]

View File

@@ -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

View File

@@ -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')

View File

@@ -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'),
]

View File

@@ -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