forked from uncloud/uncloud
support creating disks
Signed-off-by: Nico Schottelius <nico@nico-notebook.schottelius.org>
This commit is contained in:
parent
6a38e4e0a4
commit
5c33bc5c02
4 changed files with 71 additions and 18 deletions
|
@ -26,14 +26,27 @@ router = routers.DefaultRouter()
|
|||
|
||||
# user / regular urls
|
||||
router.register(r'vm/snapshot', vmviews.VMSnapshotProductViewSet, basename='vmsnapshotproduct')
|
||||
router.register(r'vm/disk', vmviews.VMDiskProductViewSet, basename='vmdiskproduct')
|
||||
router.register(r'vm/image/mine', vmviews.VMDiskImageProductMineViewSet, basename='vmdiskimagemineproduct')
|
||||
router.register(r'vm/image/public', vmviews.VMDiskImageProductPublicViewSet, basename='vmdiskimagepublicproduct')
|
||||
|
||||
# images the provider provides :-)
|
||||
# router.register(r'vm/image/official', vmviews.VMDiskImageProductPublicViewSet, basename='vmdiskimagepublicproduct')
|
||||
|
||||
|
||||
|
||||
#router.register(r'vm/disk', vmviews.VMDiskProductViewSet, basename='vmdiskproduct')
|
||||
|
||||
router.register(r'vm/vm', vmviews.VMProductViewSet, basename='vmproduct')
|
||||
|
||||
# TBD
|
||||
#router.register(r'vm/disk', vmviews.VMDiskProductViewSet, basename='vmdiskproduct')
|
||||
|
||||
# creates VM from os image
|
||||
#router.register(r'vm/ipv6onlyvm', vmviews.VMProductViewSet, basename='vmproduct')
|
||||
# ... AND adds IPv4 mapping
|
||||
#router.register(r'vm/dualstackvm', vmviews.VMProductViewSet, basename='vmproduct')
|
||||
|
||||
# allow vm creation from own images
|
||||
|
||||
|
||||
# Pay
|
||||
|
|
|
@ -4,6 +4,16 @@ import uuid
|
|||
|
||||
from uncloud_pay.models import Product
|
||||
|
||||
STATUS_CHOICES = (
|
||||
('pending', 'Pending'), # Initial state
|
||||
('creating', 'Creating'), # Creating VM/image/etc.
|
||||
('active', 'Active'), # Is usable / active
|
||||
('disabled', 'Disabled'), # Is usable, but cannot be used for new things
|
||||
('unusable', 'Unusable'), # Has some kind of error
|
||||
('deleted', 'Deleted'), # Does not exist anymore, only DB entry as a log
|
||||
)
|
||||
|
||||
STATUS_DEFAULT='pending'
|
||||
|
||||
class VMHost(models.Model):
|
||||
uuid = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
|
||||
|
@ -22,13 +32,8 @@ class VMHost(models.Model):
|
|||
|
||||
|
||||
status = models.CharField(max_length=32,
|
||||
choices = (
|
||||
('pending', 'Pending'),
|
||||
('active', 'Active'),
|
||||
('unusable', 'Unusable'),
|
||||
('deleted', 'Deleted'),
|
||||
),
|
||||
default='pending'
|
||||
choices=STATUS_CHOICES,
|
||||
default=STATUS_DEFAULT
|
||||
)
|
||||
|
||||
|
||||
|
@ -80,13 +85,10 @@ class VMDiskImageProduct(models.Model):
|
|||
default='ssd'
|
||||
)
|
||||
|
||||
# source = models.CharField(max_length=32,
|
||||
# choices = (
|
||||
# ('url', 'HDD'),
|
||||
# ('ssd', 'SSD'),
|
||||
# ),
|
||||
# default='ssd'
|
||||
# )
|
||||
status = models.CharField(max_length=32,
|
||||
choices=STATUS_CHOICES,
|
||||
default=STATUS_DEFAULT
|
||||
)
|
||||
|
||||
class VMDiskProduct(models.Model):
|
||||
"""
|
||||
|
@ -105,7 +107,7 @@ class VMDiskProduct(models.Model):
|
|||
vm = models.ForeignKey(VMProduct, on_delete=models.CASCADE)
|
||||
image = models.ForeignKey(VMDiskImageProduct, on_delete=models.CASCADE)
|
||||
|
||||
size_in_gb = models.FloatField()
|
||||
size_in_gb = models.FloatField(blank=True)
|
||||
|
||||
|
||||
class VMNetworkCard(models.Model):
|
||||
|
|
|
@ -22,6 +22,8 @@ class VMProductSerializer(serializers.ModelSerializer):
|
|||
fields = '__all__'
|
||||
|
||||
class VMDiskProductSerializer(serializers.ModelSerializer):
|
||||
# vm = VMProductSerializer()
|
||||
|
||||
class Meta:
|
||||
model = VMDiskProduct
|
||||
fields = '__all__'
|
||||
|
|
|
@ -5,11 +5,13 @@ from django.shortcuts import get_object_or_404
|
|||
|
||||
from rest_framework import viewsets, permissions
|
||||
from rest_framework.response import Response
|
||||
from rest_framework.exceptions import ValidationError
|
||||
|
||||
|
||||
from .models import VMHost, VMProduct, VMSnapshotProduct, VMDiskProduct, VMDiskImageProduct
|
||||
from uncloud_pay.models import Order
|
||||
|
||||
from .serializers import VMHostSerializer, VMProductSerializer, VMSnapshotProductSerializer, VMDiskImageProductSerializer
|
||||
from .serializers import VMHostSerializer, VMProductSerializer, VMSnapshotProductSerializer, VMDiskImageProductSerializer, VMDiskProductSerializer
|
||||
|
||||
|
||||
import datetime
|
||||
|
@ -27,8 +29,14 @@ class VMDiskImageProductMineViewSet(viewsets.ModelViewSet):
|
|||
return VMDiskImageProduct.objects.filter(owner=self.request.user)
|
||||
|
||||
def create(self, request):
|
||||
serializer = VMProductSerializer(data=request.data, context={'request': request})
|
||||
serializer = VMDiskImageProductSerializer(data=request.data, context={'request': request})
|
||||
serializer.is_valid(raise_exception=True)
|
||||
|
||||
# did not specify size NOR import url?
|
||||
if not serializer.validated_data['size_in_gb']:
|
||||
if not serializer.validated_data['import_url']:
|
||||
raise ValidationError(detail={ 'error_mesage': 'Specify either import_url or size_in_gb' })
|
||||
|
||||
serializer.save(owner=request.user)
|
||||
return Response(serializer.data)
|
||||
|
||||
|
@ -40,6 +48,34 @@ class VMDiskImageProductPublicViewSet(viewsets.ReadOnlyModelViewSet):
|
|||
def get_queryset(self):
|
||||
return VMDiskImageProduct.objects.filter(is_public=True)
|
||||
|
||||
class VMDiskProductViewSet(viewsets.ModelViewSet):
|
||||
"""
|
||||
Let a user modify their own VMDisks
|
||||
"""
|
||||
permission_classes = [permissions.IsAuthenticated]
|
||||
serializer_class = VMDiskProductSerializer
|
||||
|
||||
def get_queryset(self):
|
||||
return VMDiskProduct.objects.filter(owner=self.request.user)
|
||||
|
||||
def create(self, request):
|
||||
serializer = VMDiskProductSerializer(data=request.data, context={'request': request})
|
||||
serializer.is_valid(raise_exception=True)
|
||||
|
||||
# get disk size from image, if not specified
|
||||
if not 'size_in_gb' in serializer.validated_data:
|
||||
size_in_gb = serializer.validated_data['image'].size_in_gb
|
||||
else:
|
||||
size_in_gb = serializer.validated_data['size_in_gb']
|
||||
|
||||
if size_in_gb < serializer.validated_data['image'].size_in_gb:
|
||||
raise ValidationError(detail={ 'error_mesage': 'Size is smaller than original image' })
|
||||
|
||||
|
||||
serializer.save(owner=request.user, size_in_gb=size_in_gb)
|
||||
return Response(serializer.data)
|
||||
|
||||
|
||||
|
||||
class VMProductViewSet(viewsets.ModelViewSet):
|
||||
permission_classes = [permissions.IsAuthenticated]
|
||||
|
|
Loading…
Reference in a new issue