Move snapshot to _pay and _vm

This commit is contained in:
Nico Schottelius 2020-02-27 11:36:50 +01:00
parent 1ca247148c
commit a58a361254
8 changed files with 140 additions and 192 deletions

View file

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

View file

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

View file

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

View file

@ -17,46 +17,6 @@ import sys
import re
# POST /vm/snapshot/ vmuuid=... => create snapshot, returns snapshot uuid
# GET /vm/snapshot => list
# DEL /vm/snapshot/<uuid:uuid> => 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

View file

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

View file

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

View file

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

View file

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