From a58a3612544565178a77a81beec4e6dbfec591d3 Mon Sep 17 00:00:00 2001 From: Nico Schottelius Date: Thu, 27 Feb 2020 11:36:50 +0100 Subject: [PATCH] Move snapshot to _pay and _vm --- uncloud/README.md | 6 ++ uncloud/uncloud_api/models.py | 139 ----------------------------- uncloud/uncloud_api/serializers.py | 12 --- uncloud/uncloud_api/views.py | 42 +-------- uncloud/uncloud_pay/models.py | 28 ++++++ uncloud/uncloud_vm/models.py | 45 ++++++++++ uncloud/uncloud_vm/serializers.py | 10 +++ uncloud/uncloud_vm/views.py | 50 +++++++++++ 8 files changed, 140 insertions(+), 192 deletions(-) delete mode 100644 uncloud/uncloud_api/models.py diff --git a/uncloud/README.md b/uncloud/README.md index 67f960f..19896d9 100644 --- a/uncloud/README.md +++ b/uncloud/README.md @@ -51,6 +51,12 @@ Installing the postgresql service is os dependent, but some hints: * Alpine: `apk add postgresql-server && rc-update add postgresql && rc-service postgresql start` * Debian/Devuan: `apt install postgresql` +After postresql is started, apply the migrations: + +``` +python manage.py migrate +``` + ### Secrets cp `uncloud/secrets_sample.py` to `uncloud/secrets.py` and replace the diff --git a/uncloud/uncloud_api/models.py b/uncloud/uncloud_api/models.py deleted file mode 100644 index 6a6f9c8..0000000 --- a/uncloud/uncloud_api/models.py +++ /dev/null @@ -1,139 +0,0 @@ -import uuid - -from django.db import models -from django.contrib.auth import get_user_model - -# Product in DB vs. product in code -# DB: -# - need to define params (+param types) in db -> messy? -# - get /products/ is easy / automatic -# -# code -# - can have serializer/verification of fields easily in DRF -# - can have per product side effects / extra code running -# - might (??) make features easier?? -# - how to setup / query the recurring period (?) -# - could get products list via getattr() + re ...Product() classes -# -> this could include the url for ordering => /order/vm_snapshot (params) -# ---> this would work with urlpatterns - -# Combination: create specific product in DB (?) -# - a table per product (?) with 1 entry? - -# Orders -# define state in DB -# select a price from a product => product might change, order stays -# params: -# - the product uuid or name (?) => productuuid -# - the product parameters => for each feature -# - -# logs -# Should have a log = ... => 1:n field for most models! - -class Product(models.Model): - uuid = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False) - owner = models.ForeignKey(get_user_model(), - on_delete=models.CASCADE, - editable=False) - - # override these fields by default - - description = "" - recurring_period = "not_recurring" - - status = models.CharField(max_length=256, - choices = ( - ('pending', 'Pending'), - ('being_created', 'Being created'), - ('active', 'Active'), - ('deleted', 'Deleted') - ), - default='pending' - ) - - # This is calculated by each product and saved in the DB - recurring_price = models.FloatField(editable=False) - one_time_price = models.FloatField(editable=False) - - # FIXME: need recurring_time_frame - - class Meta: - abstract = True - - def __str__(self): - return "{}".format(self.name) - - -class VMSnapshotProduct(Product): - price_per_gb_ssd = 0.35 - price_per_gb_hdd = 1.5/100 - - # This we need to get from the VM - gb_ssd = models.FloatField(editable=False) - gb_hdd = models.FloatField(editable=False) - - vm_uuid = models.UUIDField() - - # Need to setup recurring_price and one_time_price and recurring period - - sample_ssd = 10 - sample_hdd = 100 - - def recurring_price(self): - return 0 - - def one_time_price(self): - return 0 - - @classmethod - def sample_price(cls): - return cls.sample_ssd * cls.price_per_gb_ssd + cls.sample_hdd * cls.price_per_gb_hdd - - description = "Create snapshot of a VM" - recurring_period = "monthly" - - @classmethod - def pricing_model(cls): - return """ -Pricing is on monthly basis and storage prices are equivalent to the storage -price in the VM. - -Price per GB SSD is: {} -Price per GB HDD is: {} - - -Sample price for a VM with {} GB SSD and {} GB HDD VM is: {}. -""".format(cls.price_per_gb_ssd, cls.price_per_gb_hdd, - cls.sample_ssd, cls.sample_hdd, cls.sample_price()) - - - - - - - - -class Feature(models.Model): - uuid = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False) - name = models.CharField(max_length=256) - - recurring_price = models.FloatField(default=0) - one_time_price = models.FloatField() - - product = models.ForeignKey(Product, on_delete=models.CASCADE) - - # params for "cpu": cpu_count -> int - # each feature can only have one parameters - # could call this "value" and set whether it is user usable - # has_value = True/False - # value = string -> int (?) - # value_int - # value_str - # value_float - - class Meta: - abstract = True - - def __str__(self): - return "'{}' - '{}'".format(self.product, self.name) diff --git a/uncloud/uncloud_api/serializers.py b/uncloud/uncloud_api/serializers.py index 7dc3686..cd7fd14 100644 --- a/uncloud/uncloud_api/serializers.py +++ b/uncloud/uncloud_api/serializers.py @@ -3,8 +3,6 @@ from django.contrib.auth import get_user_model from rest_framework import serializers -from .models import VMSnapshotProduct - class UserSerializer(serializers.ModelSerializer): class Meta: model = get_user_model() @@ -14,13 +12,3 @@ class GroupSerializer(serializers.HyperlinkedModelSerializer): class Meta: model = Group fields = ['url', 'name'] - -class VMSnapshotSerializer(serializers.HyperlinkedModelSerializer): - class Meta: - model = VMSnapshotProduct - fields = ['uuid', 'status', 'recurring_price', 'one_time_price' ] - -class VMSnapshotCreateSerializer(serializers.HyperlinkedModelSerializer): - class Meta: - model = VMSnapshotProduct - fields = '__all__' diff --git a/uncloud/uncloud_api/views.py b/uncloud/uncloud_api/views.py index eb4cc77..7e5c6f9 100644 --- a/uncloud/uncloud_api/views.py +++ b/uncloud/uncloud_api/views.py @@ -17,46 +17,6 @@ import sys import re -# POST /vm/snapshot/ vmuuid=... => create snapshot, returns snapshot uuid -# GET /vm/snapshot => list -# DEL /vm/snapshot/ => delete -# create-list -> get, post => ListCreateAPIView -# del on other! -class VMSnapshotView(viewsets.ViewSet): - permission_classes = [permissions.IsAuthenticated] - - def list(self, request): - queryset = VMSnapshotProduct.objects.filter(owner=request.user) - serializer = VMSnapshotSerializer(queryset, many=True, context={'request': request}) - return Response(serializer.data) - - def retrieve(self, request, pk=None): - queryset = VMSnapshotProduct.objects.filter(owner=request.user) - vm = get_object_or_404(queryset, pk=pk) - serializer = VMSnapshotSerializer(vm, context={'request': request}) - return Response(serializer.data) - - def create(self, request): - print(request.data) - serializer = VMSnapshotCreateSerializer(data=request.data) - - serializer.gb_ssd = 12 - serializer.gb_hdd = 120 - print("F") - serializer.is_valid(raise_exception=True) - - print(serializer) - print("A") - serializer.save() - print("B") - - - # snapshot = VMSnapshotProduct(owner=request.user, - # **serialzer.data) - - return Response(serializer.data) - - # maybe drop or not --- we need something to guide the user! # class ProductsViewSet(viewsets.ViewSet): @@ -91,4 +51,4 @@ class UserViewSet(viewsets.ModelViewSet): permission_classes = [permissions.IsAuthenticated] def get_queryset(self): - return self.request.user + return self.request.user \ No newline at end of file diff --git a/uncloud/uncloud_pay/models.py b/uncloud/uncloud_pay/models.py index 6910d58..831710b 100644 --- a/uncloud/uncloud_pay/models.py +++ b/uncloud/uncloud_pay/models.py @@ -89,3 +89,31 @@ class Payment(models.Model): ), default='unknown') timestamp = models.DateTimeField(editable=False) + + + + +class Product(models.Model): + uuid = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False) + owner = models.ForeignKey(get_user_model(), + on_delete=models.CASCADE, + editable=False) + + description = "" + + status = models.CharField(max_length=256, + choices = ( + ('pending', 'Pending'), + ('being_created', 'Being created'), + ('active', 'Active'), + ('deleted', 'Deleted') + ), + default='pending' + ) + + order = models.ForeignKey(Order, + on_delete=models.CASCADE, + editable=False) + + class Meta: + abstract = True diff --git a/uncloud/uncloud_vm/models.py b/uncloud/uncloud_vm/models.py index f4b68dd..12d188e 100644 --- a/uncloud/uncloud_vm/models.py +++ b/uncloud/uncloud_vm/models.py @@ -2,6 +2,8 @@ from django.db import models from django.contrib.auth import get_user_model import uuid +from uncloud_pay.models import Product + class VMHost(models.Model): uuid = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False) @@ -71,3 +73,46 @@ class OperatingSystemDisk(VMDiskProduct): class VMNetworkCard(models.Model): vm = models.ForeignKey(VMProduct, on_delete=models.CASCADE) mac_address = models.IntegerField() + + +class VMSnapshotProduct(Product): + price_per_gb_ssd = 0.35 + price_per_gb_hdd = 1.5/100 + + # This we need to get from the VM + gb_ssd = models.FloatField(editable=False) + gb_hdd = models.FloatField(editable=False) + + vm_uuid = models.UUIDField() + + # Need to setup recurring_price and one_time_price and recurring period + + sample_ssd = 10 + sample_hdd = 100 + + def recurring_price(self): + return 0 + + def one_time_price(self): + return 0 + + @classmethod + def sample_price(cls): + return cls.sample_ssd * cls.price_per_gb_ssd + cls.sample_hdd * cls.price_per_gb_hdd + + description = "Create snapshot of a VM" + recurring_period = "monthly" + + @classmethod + def pricing_model(cls): + return """ +Pricing is on monthly basis and storage prices are equivalent to the storage +price in the VM. + +Price per GB SSD is: {} +Price per GB HDD is: {} + + +Sample price for a VM with {} GB SSD and {} GB HDD VM is: {}. +""".format(cls.price_per_gb_ssd, cls.price_per_gb_hdd, + cls.sample_ssd, cls.sample_hdd, cls.sample_price()) diff --git a/uncloud/uncloud_vm/serializers.py b/uncloud/uncloud_vm/serializers.py index 4154aee..d5549ad 100644 --- a/uncloud/uncloud_vm/serializers.py +++ b/uncloud/uncloud_vm/serializers.py @@ -13,3 +13,13 @@ class VMProductSerializer(serializers.HyperlinkedModelSerializer): class Meta: model = VMProduct fields = '__all__' + +class VMSnapshotProductSerializer(serializers.HyperlinkedModelSerializer): + class Meta: + model = VMSnapshotProduct + fields = ['uuid', 'status', 'recurring_price', 'one_time_price' ] + +class VMSnapshotProductCreateSerializer(serializers.HyperlinkedModelSerializer): + class Meta: + model = VMSnapshotProduct + fields = '__all__' diff --git a/uncloud/uncloud_vm/views.py b/uncloud/uncloud_vm/views.py index 91e81e1..4f2f9f4 100644 --- a/uncloud/uncloud_vm/views.py +++ b/uncloud/uncloud_vm/views.py @@ -27,3 +27,53 @@ class VMProductViewSet(viewsets.ModelViewSet): serializer.save(owner=request.user) return Response(serializer.data) + + +class VMSnapshotProductViewSet(viewsets.ModelViewSet): + permission_classes = [permissions.IsAuthenticated] + serializer_class = VMSnapshotProductSerializer + + def get_queryset(self): + return VMSnapshotProduct.objects.filter(owner=self.request.user) + + def create(self, request): + serializer = VMProductSerializer(data=request.data, context={'request': request}) + serializer.is_valid(raise_exception=True) + serializer.save(owner=request.user) + + return Response(serializer.data) + + +class VMSnapshotProductView(viewsets.ViewSet): + permission_classes = [permissions.IsAuthenticated] + + def list(self, request): + queryset = VMSnapshotProduct.objects.filter(owner=request.user) + serializer = VMSnapshotSerializer(queryset, many=True, context={'request': request}) + return Response(serializer.data) + + def retrieve(self, request, pk=None): + queryset = VMSnapshotProduct.objects.filter(owner=request.user) + vm = get_object_or_404(queryset, pk=pk) + serializer = VMSnapshotSerializer(vm, context={'request': request}) + return Response(serializer.data) + + def create(self, request): + print(request.data) + serializer = VMSnapshotCreateSerializer(data=request.data) + + serializer.gb_ssd = 12 + serializer.gb_hdd = 120 + print("F") + serializer.is_valid(raise_exception=True) + + print(serializer) + print("A") + serializer.save() + print("B") + + + # snapshot = VMSnapshotProduct(owner=request.user, + # **serialzer.data) + + return Response(serializer.data)