Make VM order-able again
This commit is contained in:
		
					parent
					
						
							
								df059fb00d
							
						
					
				
			
			
				commit
				
					
						d794b24c86
					
				
			
		
					 5 changed files with 70 additions and 34 deletions
				
			
		
							
								
								
									
										19
									
								
								uncloud_vm/migrations/0014_vmwithosproduct_primary_disk.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								uncloud_vm/migrations/0014_vmwithosproduct_primary_disk.py
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,19 @@
 | 
			
		|||
# Generated by Django 3.0.6 on 2020-05-08 14:01
 | 
			
		||||
 | 
			
		||||
from django.db import migrations, models
 | 
			
		||||
import django.db.models.deletion
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Migration(migrations.Migration):
 | 
			
		||||
 | 
			
		||||
    dependencies = [
 | 
			
		||||
        ('uncloud_vm', '0013_remove_vmproduct_primary_disk'),
 | 
			
		||||
    ]
 | 
			
		||||
 | 
			
		||||
    operations = [
 | 
			
		||||
        migrations.AddField(
 | 
			
		||||
            model_name='vmwithosproduct',
 | 
			
		||||
            name='primary_disk',
 | 
			
		||||
            field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='uncloud_vm.VMDiskProduct'),
 | 
			
		||||
        ),
 | 
			
		||||
    ]
 | 
			
		||||
| 
						 | 
				
			
			@ -69,7 +69,7 @@ class VMProduct(Product):
 | 
			
		|||
    cores = models.IntegerField()
 | 
			
		||||
    ram_in_gb = models.FloatField()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    # Default recurring price is PER_MONTH, see uncloud_pay.models.Product.
 | 
			
		||||
    @property
 | 
			
		||||
    def recurring_price(self):
 | 
			
		||||
        return self.cores * 3 + self.ram_in_gb * 4
 | 
			
		||||
| 
						 | 
				
			
			@ -99,7 +99,7 @@ class VMProduct(Product):
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
class VMWithOSProduct(VMProduct):
 | 
			
		||||
    pass
 | 
			
		||||
    primary_disk = models.ForeignKey('VMDiskProduct', on_delete=models.CASCADE, null=True)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class VMDiskImageProduct(UncloudModel):
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2,7 +2,7 @@ from django.contrib.auth import get_user_model
 | 
			
		|||
 | 
			
		||||
from rest_framework import serializers
 | 
			
		||||
 | 
			
		||||
from .models import VMHost, VMProduct, VMSnapshotProduct, VMDiskProduct, VMDiskImageProduct, VMCluster
 | 
			
		||||
from .models import *
 | 
			
		||||
from uncloud_pay.models import RecurringPeriod, BillingAddress
 | 
			
		||||
 | 
			
		||||
# XXX: does not seem to be used?
 | 
			
		||||
| 
						 | 
				
			
			@ -86,40 +86,33 @@ class ManagedVMProductSerializer(serializers.ModelSerializer):
 | 
			
		|||
    """
 | 
			
		||||
    primary_disk = CreateManagedVMDiskProductSerializer()
 | 
			
		||||
    class Meta:
 | 
			
		||||
        model = VMProduct
 | 
			
		||||
        model = VMWithOSProduct
 | 
			
		||||
        fields = [ 'cores', 'ram_in_gb', 'primary_disk']
 | 
			
		||||
 | 
			
		||||
class VMProductSerializer(serializers.HyperlinkedModelSerializer):
 | 
			
		||||
class VMProductSerializer(serializers.ModelSerializer):
 | 
			
		||||
    primary_disk = CreateVMDiskProductSerializer()
 | 
			
		||||
    snapshots = VMSnapshotProductSerializer(many=True, read_only=True)
 | 
			
		||||
    disks = VMDiskProductSerializer(many=True, read_only=True)
 | 
			
		||||
 | 
			
		||||
    class Meta:
 | 
			
		||||
        model = VMProduct
 | 
			
		||||
        model = VMWithOSProduct
 | 
			
		||||
        fields = ['uuid', 'order', 'owner', 'status', 'name', 'cores',
 | 
			
		||||
                'ram_in_gb', 'primary_disk', 'snapshots', 'disks', 'extra_data']
 | 
			
		||||
        read_only_fields = ['uuid', 'order', 'owner', 'status']
 | 
			
		||||
 | 
			
		||||
class OrderVMProductSerializer(VMProductSerializer):
 | 
			
		||||
    recurring_period = serializers.ChoiceField(
 | 
			
		||||
            choices=VMProduct.allowed_recurring_periods())
 | 
			
		||||
            choices=VMWithOSProduct.allowed_recurring_periods())
 | 
			
		||||
 | 
			
		||||
    def __init__(self, *args, **kwargs):
 | 
			
		||||
        super(VMProductSerializer, self).__init__(*args, **kwargs)
 | 
			
		||||
        self.fields['billing_address'] = serializers.ChoiceField(
 | 
			
		||||
                choices=BillingAddress.get_addresses_for(
 | 
			
		||||
                    self.context['request'].user)
 | 
			
		||||
                )
 | 
			
		||||
 | 
			
		||||
    class Meta:
 | 
			
		||||
        model = VMProductSerializer.Meta.model
 | 
			
		||||
        fields = VMProductSerializer.Meta.fields + [
 | 
			
		||||
                'recurring_period', 'billing_address'
 | 
			
		||||
                ]
 | 
			
		||||
        fields = VMProductSerializer.Meta.fields + [ 'recurring_period' ]
 | 
			
		||||
        read_only_fields = VMProductSerializer.Meta.read_only_fields
 | 
			
		||||
 | 
			
		||||
# Nico's playground.
 | 
			
		||||
 | 
			
		||||
class NicoVMProductSerializer(serializers.ModelSerializer):
 | 
			
		||||
    snapshots = VMSnapshotProductSerializer(many=True, read_only=True)
 | 
			
		||||
    order = serializers.StringRelatedField()
 | 
			
		||||
| 
						 | 
				
			
			@ -134,7 +127,6 @@ class NicoVMProductSerializer(serializers.ModelSerializer):
 | 
			
		|||
                                      'ram_in_gb'
 | 
			
		||||
        ]
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class DCLVMProductSerializer(serializers.HyperlinkedModelSerializer):
 | 
			
		||||
    """
 | 
			
		||||
    Create an interface similar to standard DCL
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -10,7 +10,7 @@ from rest_framework.response import Response
 | 
			
		|||
from rest_framework.exceptions import ValidationError
 | 
			
		||||
 | 
			
		||||
from .models import VMHost, VMProduct, VMSnapshotProduct, VMDiskProduct, VMDiskImageProduct, VMCluster
 | 
			
		||||
from uncloud_pay.models import Order
 | 
			
		||||
from uncloud_pay.models import Order, BillingAddress
 | 
			
		||||
 | 
			
		||||
from .serializers import *
 | 
			
		||||
from uncloud_pay.helpers import ProductViewSet
 | 
			
		||||
| 
						 | 
				
			
			@ -136,9 +136,9 @@ class VMProductViewSet(ProductViewSet):
 | 
			
		|||
 | 
			
		||||
    def get_queryset(self):
 | 
			
		||||
        if self.request.user.is_superuser:
 | 
			
		||||
            obj = VMProduct.objects.all()
 | 
			
		||||
            obj = VMWithOSProduct.objects.all()
 | 
			
		||||
        else:
 | 
			
		||||
            obj = VMProduct.objects.filter(owner=self.request.user)
 | 
			
		||||
            obj = VMWithOSProduct.objects.filter(owner=self.request.user)
 | 
			
		||||
 | 
			
		||||
        return obj
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -156,29 +156,39 @@ class VMProductViewSet(ProductViewSet):
 | 
			
		|||
        serializer = self.get_serializer(data=request.data)
 | 
			
		||||
        serializer.is_valid(raise_exception=True)
 | 
			
		||||
        order_recurring_period = serializer.validated_data.pop("recurring_period")
 | 
			
		||||
        order_billing_address = serializer.validated_data.pop("billing_address")
 | 
			
		||||
 | 
			
		||||
        # Create base order.
 | 
			
		||||
        order = Order(
 | 
			
		||||
                recurring_period=order_recurring_period,
 | 
			
		||||
                billing_address=order_billing_address,
 | 
			
		||||
                owner=request.user,
 | 
			
		||||
                starting_date=timezone.now()
 | 
			
		||||
                )
 | 
			
		||||
        order.save()
 | 
			
		||||
 | 
			
		||||
        # Create disk image.
 | 
			
		||||
        disk = VMDiskProduct(owner=request.user, order=order,
 | 
			
		||||
        disk = VMDiskProduct(owner=request.user,
 | 
			
		||||
                **serializer.validated_data.pop("primary_disk"))
 | 
			
		||||
        vm = VMWithOSProduct(owner=request.user, primary_disk=disk,
 | 
			
		||||
                **serializer.validated_data)
 | 
			
		||||
        disk.vm = vm # XXX: Is this really needed?
 | 
			
		||||
 | 
			
		||||
        # Create VM.
 | 
			
		||||
        vm = serializer.save(owner=request.user, order=order, primary_disk=disk)
 | 
			
		||||
        disk.vm = vm
 | 
			
		||||
        # Create VM and Disk orders.
 | 
			
		||||
        vm_order = Order.from_product(
 | 
			
		||||
                vm,
 | 
			
		||||
                recurring_period=order_recurring_period,
 | 
			
		||||
                starting_date=timezone.now()
 | 
			
		||||
                )
 | 
			
		||||
 | 
			
		||||
        disk_order = Order.from_product(
 | 
			
		||||
                disk,
 | 
			
		||||
                recurring_period=order_recurring_period,
 | 
			
		||||
                starting_date=timezone.now()
 | 
			
		||||
                )
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        # Commit to DB.
 | 
			
		||||
        vm.order = vm_order
 | 
			
		||||
        vm.save()
 | 
			
		||||
        vm_order.save()
 | 
			
		||||
 | 
			
		||||
        disk.order = disk_order
 | 
			
		||||
        disk_order.save()
 | 
			
		||||
        disk.save()
 | 
			
		||||
 | 
			
		||||
        return Response(VMProductSerializer(vm, context={'request': request}).data)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class NicoVMProductViewSet(ProductViewSet):
 | 
			
		||||
    permission_classes = [permissions.IsAuthenticated]
 | 
			
		||||
    serializer_class = NicoVMProductSerializer
 | 
			
		||||
| 
						 | 
				
			
			@ -194,6 +204,7 @@ class NicoVMProductViewSet(ProductViewSet):
 | 
			
		|||
 | 
			
		||||
        return Response(serializer.data)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
###
 | 
			
		||||
# Admin stuff.
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue