diff --git a/README-penguinpay.md b/README-penguinpay.md deleted file mode 100644 index 3229bc5..0000000 --- a/README-penguinpay.md +++ /dev/null @@ -1,42 +0,0 @@ -## How to place a order with penguin pay - -### Requirements - -* An ungleich account - can be registered for free on - https://account.ungleich.ch -* httpie installed (provides the http command) - -## Get a membership - - -## Registering a payment method - -To be able to pay for the membership, you will need to register a -credit card or apply for payment on bill (TO BE IMPLEMENTED). - -### Register credit card - -``` -http POST https://api.ungleich.ch/membership \ - username=nico password=yourpassword \ - cc_number=.. \ - cc_ - -``` - - - -### Request payment via bill - - - - -## Create the membership - - -``` -http POST https://api.ungleich.ch/membership username=nico password=yourpassword - -``` - -## List available products diff --git a/README.md b/meow-payv1/README.md similarity index 100% rename from README.md rename to meow-payv1/README.md diff --git a/config.py b/meow-payv1/config.py similarity index 100% rename from config.py rename to meow-payv1/config.py diff --git a/hack-a-vpn.py b/meow-payv1/hack-a-vpn.py similarity index 100% rename from hack-a-vpn.py rename to meow-payv1/hack-a-vpn.py diff --git a/helper.py b/meow-payv1/helper.py similarity index 100% rename from helper.py rename to meow-payv1/helper.py diff --git a/ldaptest.py b/meow-payv1/ldaptest.py similarity index 100% rename from ldaptest.py rename to meow-payv1/ldaptest.py diff --git a/products/ipv6-only-django.json b/meow-payv1/products/ipv6-only-django.json similarity index 100% rename from products/ipv6-only-django.json rename to meow-payv1/products/ipv6-only-django.json diff --git a/products/ipv6-only-vm.json b/meow-payv1/products/ipv6-only-vm.json similarity index 100% rename from products/ipv6-only-vm.json rename to meow-payv1/products/ipv6-only-vm.json diff --git a/products/ipv6-only-vpn.json b/meow-payv1/products/ipv6-only-vpn.json similarity index 100% rename from products/ipv6-only-vpn.json rename to meow-payv1/products/ipv6-only-vpn.json diff --git a/products/ipv6box.json b/meow-payv1/products/ipv6box.json similarity index 100% rename from products/ipv6box.json rename to meow-payv1/products/ipv6box.json diff --git a/products/membership.json b/meow-payv1/products/membership.json similarity index 100% rename from products/membership.json rename to meow-payv1/products/membership.json diff --git a/requirements.txt b/meow-payv1/requirements.txt similarity index 100% rename from requirements.txt rename to meow-payv1/requirements.txt diff --git a/sample-pay.conf b/meow-payv1/sample-pay.conf similarity index 100% rename from sample-pay.conf rename to meow-payv1/sample-pay.conf diff --git a/schemas.py b/meow-payv1/schemas.py similarity index 100% rename from schemas.py rename to meow-payv1/schemas.py diff --git a/stripe_hack.py b/meow-payv1/stripe_hack.py similarity index 100% rename from stripe_hack.py rename to meow-payv1/stripe_hack.py diff --git a/stripe_utils.py b/meow-payv1/stripe_utils.py similarity index 100% rename from stripe_utils.py rename to meow-payv1/stripe_utils.py diff --git a/ucloud_pay.py b/meow-payv1/ucloud_pay.py similarity index 100% rename from ucloud_pay.py rename to meow-payv1/ucloud_pay.py diff --git a/nicohack202002/uncloud/opennebula/migrations/0001_initial.py b/nicohack202002/uncloud/opennebula/migrations/0001_initial.py deleted file mode 100644 index e2c6a1f..0000000 --- a/nicohack202002/uncloud/opennebula/migrations/0001_initial.py +++ /dev/null @@ -1,23 +0,0 @@ -# Generated by Django 3.0.3 on 2020-02-21 10:22 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - initial = True - - dependencies = [ - ] - - operations = [ - migrations.CreateModel( - name='VM', - fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('vmid', models.IntegerField()), - ('owner', models.CharField(max_length=128)), - ('data', models.CharField(max_length=65536)), - ], - ), - ] diff --git a/nicohack202002/uncloud/opennebula/migrations/0002_auto_20200221_1024.py b/nicohack202002/uncloud/opennebula/migrations/0002_auto_20200221_1024.py deleted file mode 100644 index 43b7442..0000000 --- a/nicohack202002/uncloud/opennebula/migrations/0002_auto_20200221_1024.py +++ /dev/null @@ -1,23 +0,0 @@ -# Generated by Django 3.0.3 on 2020-02-21 10:24 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('opennebula', '0001_initial'), - ] - - operations = [ - migrations.AlterField( - model_name='vm', - name='data', - field=models.CharField(max_length=65536, null=True), - ), - migrations.AlterField( - model_name='vm', - name='owner', - field=models.CharField(max_length=128, null=True), - ), - ] diff --git a/nicohack202002/uncloud/opennebula/migrations/0003_auto_20200221_1113.py b/nicohack202002/uncloud/opennebula/migrations/0003_auto_20200221_1113.py deleted file mode 100644 index 9ccc22e..0000000 --- a/nicohack202002/uncloud/opennebula/migrations/0003_auto_20200221_1113.py +++ /dev/null @@ -1,21 +0,0 @@ -# Generated by Django 3.0.3 on 2020-02-21 11:13 - -from django.conf import settings -from django.db import migrations, models -import django.db.models.deletion - - -class Migration(migrations.Migration): - - dependencies = [ - migrations.swappable_dependency(settings.AUTH_USER_MODEL), - ('opennebula', '0002_auto_20200221_1024'), - ] - - operations = [ - migrations.AlterField( - model_name='vm', - name='owner', - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL), - ), - ] diff --git a/nicohack202002/uncloud/opennebula/serializers.py b/nicohack202002/uncloud/opennebula/serializers.py deleted file mode 100644 index ac40725..0000000 --- a/nicohack202002/uncloud/opennebula/serializers.py +++ /dev/null @@ -1,8 +0,0 @@ -from rest_framework import serializers -from opennebula.models import VM - - -class VMSerializer(serializers.HyperlinkedModelSerializer): - class Meta: - model = VM - fields = ['uuid', 'vmid', 'owner', 'data'] diff --git a/nicohack202002/uncloud/uncloud_api/migrations/0001_initial.py b/nicohack202002/uncloud/uncloud_api/migrations/0001_initial.py deleted file mode 100644 index 33be28d..0000000 --- a/nicohack202002/uncloud/uncloud_api/migrations/0001_initial.py +++ /dev/null @@ -1,50 +0,0 @@ -# Generated by Django 3.0.3 on 2020-02-21 10:42 - -from django.conf import settings -from django.db import migrations, models -import django.db.models.deletion -import uuid - - -class Migration(migrations.Migration): - - initial = True - - dependencies = [ - migrations.swappable_dependency(settings.AUTH_USER_MODEL), - ] - - operations = [ - migrations.CreateModel( - name='OrderReference', - fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ], - ), - migrations.CreateModel( - name='Product', - fields=[ - ('uuid', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)), - ('name', models.CharField(max_length=256)), - ('recurring_period', models.CharField(choices=[('per_year', 'Per Year'), ('per_month', 'Per Month'), ('per_week', 'Per Week'), ('per_day', 'Per Day'), ('per_hour', 'Per Hour'), ('not_recurring', 'Not recurring')], default='not_recurring', max_length=256)), - ], - ), - migrations.CreateModel( - name='Order', - fields=[ - ('uuid', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)), - ('owner', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), - ('product', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='uncloud_api.Product')), - ], - ), - migrations.CreateModel( - name='Feature', - fields=[ - ('uuid', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)), - ('name', models.CharField(max_length=256)), - ('recurring_price', models.FloatField(default=0)), - ('one_time_price', models.FloatField()), - ('product', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='uncloud_api.Product')), - ], - ), - ] diff --git a/notes-nico.org b/notes-nico.org index 93e0c00..03c1b97 100644 --- a/notes-nico.org +++ b/notes-nico.org @@ -49,3 +49,52 @@ password=... * Django rest framework ** viewset: .list and .create ** view: .get .post +* TODO register CC +* TODO list products +* ahmed +** schemas +*** field: is_valid? - used by schemas +*** definition of a "schema" +* penguin pay +## How to place a order with penguin pay + +### Requirements + +* An ungleich account - can be registered for free on + https://account.ungleich.ch +* httpie installed (provides the http command) + +## Get a membership + + +## Registering a payment method + +To be able to pay for the membership, you will need to register a +credit card or apply for payment on bill (TO BE IMPLEMENTED). + +### Register credit card + +``` +http POST https://api.ungleich.ch/membership \ + username=nico password=yourpassword \ + cc_number=.. \ + cc_ + +``` + + + +### Request payment via bill + + + + +## Create the membership + + +``` +http POST https://api.ungleich.ch/membership username=nico password=yourpassword + +``` + +## List available products diff --git a/nicohack202002/uncloud/.gitignore b/uncloud/.gitignore similarity index 100% rename from nicohack202002/uncloud/.gitignore rename to uncloud/.gitignore diff --git a/uncloud/README.md b/uncloud/README.md new file mode 100644 index 0000000..9db1c5c --- /dev/null +++ b/uncloud/README.md @@ -0,0 +1,47 @@ +## Install + +### OS package requirements + +Alpine: + +``` +apk add openldap-dev postgresql-dev +``` + +### Python requirements + +If you prefer using a venv, use: + +``` +python -m venv venv +. ./venv/bin/activate +``` + +Then install the requirements + +``` +pip install -r requirements.txt +``` + +### Database requirements + +Due to the use of the JSONField, postgresql is required. + +First create a role to be used: + +``` +postgres=# create role nico login; +``` + +Then create the database owner by the new role: + +``` +postgres=# create database uncloud owner nico; +``` + + + +### Secrets + +cp `uncloud/secrets_sample.py` to `uncloud/secrets.py` and replace the +sample values with real values. diff --git a/nicohack202002/uncloud/manage.py b/uncloud/manage.py similarity index 100% rename from nicohack202002/uncloud/manage.py rename to uncloud/manage.py diff --git a/nicohack202002/uncloud/opennebula/__init__.py b/uncloud/opennebula/__init__.py similarity index 100% rename from nicohack202002/uncloud/opennebula/__init__.py rename to uncloud/opennebula/__init__.py diff --git a/nicohack202002/uncloud/opennebula/admin.py b/uncloud/opennebula/admin.py similarity index 100% rename from nicohack202002/uncloud/opennebula/admin.py rename to uncloud/opennebula/admin.py diff --git a/nicohack202002/uncloud/opennebula/apps.py b/uncloud/opennebula/apps.py similarity index 100% rename from nicohack202002/uncloud/opennebula/apps.py rename to uncloud/opennebula/apps.py diff --git a/nicohack202002/uncloud/opennebula/management/commands/syncvm.py b/uncloud/opennebula/management/commands/syncvm.py similarity index 84% rename from nicohack202002/uncloud/opennebula/management/commands/syncvm.py rename to uncloud/opennebula/management/commands/syncvm.py index e68a4a4..136e145 100644 --- a/nicohack202002/uncloud/opennebula/management/commands/syncvm.py +++ b/uncloud/opennebula/management/commands/syncvm.py @@ -31,8 +31,12 @@ class Command(BaseCommand): user = get_user_model().objects.get(username=vm_owner) except get_user_model().DoesNotExist: user = get_user_model().objects.create_user(username=vm_owner) - vm = json.dumps(vm, ensure_ascii=True) - vm_object = VMModel.objects.create(vmid=vm_id, owner=user, data=vm) - vm_object.save() + + VMModel.objects.update_or_create( + defaults= { 'data': vm, + 'owner': user }, + vmid=vm_id + ) + else: print(response) diff --git a/uncloud/opennebula/migrations/0001_initial.py b/uncloud/opennebula/migrations/0001_initial.py new file mode 100644 index 0000000..f1d3d6b --- /dev/null +++ b/uncloud/opennebula/migrations/0001_initial.py @@ -0,0 +1,26 @@ +# Generated by Django 3.0.3 on 2020-02-23 10:02 + +from django.conf import settings +import django.contrib.postgres.fields.jsonb +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ] + + operations = [ + migrations.CreateModel( + name='VM', + fields=[ + ('vmid', models.IntegerField(primary_key=True, serialize=False)), + ('data', django.contrib.postgres.fields.jsonb.JSONField()), + ('owner', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), + ], + ), + ] diff --git a/uncloud/opennebula/migrations/0002_vm_uuid.py b/uncloud/opennebula/migrations/0002_vm_uuid.py new file mode 100644 index 0000000..595fd05 --- /dev/null +++ b/uncloud/opennebula/migrations/0002_vm_uuid.py @@ -0,0 +1,19 @@ +# Generated by Django 3.0.3 on 2020-02-23 10:55 + +from django.db import migrations, models +import uuid + + +class Migration(migrations.Migration): + + dependencies = [ + ('opennebula', '0001_initial'), + ] + + operations = [ + migrations.AddField( + model_name='vm', + name='uuid', + field=models.UUIDField(default=uuid.uuid4, editable=False), + ), + ] diff --git a/uncloud/opennebula/migrations/0003_auto_20200223_1058.py b/uncloud/opennebula/migrations/0003_auto_20200223_1058.py new file mode 100644 index 0000000..d2173da --- /dev/null +++ b/uncloud/opennebula/migrations/0003_auto_20200223_1058.py @@ -0,0 +1,19 @@ +# Generated by Django 3.0.3 on 2020-02-23 10:58 + +from django.db import migrations, models +import uuid + + +class Migration(migrations.Migration): + + dependencies = [ + ('opennebula', '0002_vm_uuid'), + ] + + operations = [ + migrations.AlterField( + model_name='vm', + name='uuid', + field=models.UUIDField(default=uuid.uuid4, editable=False, unique=True), + ), + ] diff --git a/nicohack202002/uncloud/opennebula/migrations/0004_auto_20200222_0713.py b/uncloud/opennebula/migrations/0004_auto_20200222_0713.py similarity index 100% rename from nicohack202002/uncloud/opennebula/migrations/0004_auto_20200222_0713.py rename to uncloud/opennebula/migrations/0004_auto_20200222_0713.py diff --git a/nicohack202002/uncloud/opennebula/migrations/__init__.py b/uncloud/opennebula/migrations/__init__.py similarity index 100% rename from nicohack202002/uncloud/opennebula/migrations/__init__.py rename to uncloud/opennebula/migrations/__init__.py diff --git a/uncloud/opennebula/models.py b/uncloud/opennebula/models.py new file mode 100644 index 0000000..0b0f307 --- /dev/null +++ b/uncloud/opennebula/models.py @@ -0,0 +1,50 @@ +import uuid +from django.db import models +from django.contrib.auth import get_user_model + +from django.contrib.postgres.fields import JSONField + +class VM(models.Model): + vmid = models.IntegerField(primary_key=True) + uuid = models.UUIDField(default=uuid.uuid4, editable=False, unique=True) + owner = models.ForeignKey(get_user_model(), on_delete=models.CASCADE) + data = JSONField() + + + @property + def cores(self): + return int(self.data['TEMPLATE']['VCPU']) + + @property + def ram_in_gb(self): + return (int(self.data['TEMPLATE']['MEMORY'])/1024.) + + @property + def disks(self): + """ + If there is no disk then the key DISK does not exist. + + If there is only one disk, we have a dictionary in the database. + + If there are multiple disks, we have a list of dictionaries in the database. + """ + + disks = [] + + if 'DISK' in self.data['TEMPLATE']: + + if type(self.data['TEMPLATE']['DISK']) is dict: + disks = [ self.data['TEMPLATE']['DISK'] ] + else: + disks = self.data['TEMPLATE']['DISK'] + + disks = [ + { + 'size_in_gb': int(d['SIZE'])/1024. , + 'opennebula_source': d['SOURCE'], + 'opennebula_name': d['IMAGE'], + } + for d in disks + ] + + return disks diff --git a/uncloud/opennebula/serializers.py b/uncloud/opennebula/serializers.py new file mode 100644 index 0000000..30bd20a --- /dev/null +++ b/uncloud/opennebula/serializers.py @@ -0,0 +1,14 @@ +from rest_framework import serializers +from opennebula.models import VM + + +class VMSerializer(serializers.HyperlinkedModelSerializer): + class Meta: + model = VM + fields = ['vmid', 'owner', 'data'] + + +class OpenNebulaVMSerializer(serializers.HyperlinkedModelSerializer): + class Meta: + model = VM + fields = ['vmid', 'owner', 'cores', 'ram_in_gb', 'disks' ] diff --git a/nicohack202002/uncloud/opennebula/tests.py b/uncloud/opennebula/tests.py similarity index 100% rename from nicohack202002/uncloud/opennebula/tests.py rename to uncloud/opennebula/tests.py diff --git a/uncloud/opennebula/views.py b/uncloud/opennebula/views.py new file mode 100644 index 0000000..5505b32 --- /dev/null +++ b/uncloud/opennebula/views.py @@ -0,0 +1,22 @@ +from rest_framework import viewsets, generics, permissions +from .models import VM +from .serializers import VMSerializer, OpenNebulaVMSerializer + + +#class VMList(generics.ListAPIView): +# queryset = VM.objects.all() +# serializer_class = VMSerializer + + +class RawVMViewSet(viewsets.ModelViewSet): +# lookup_field = 'vmid' + queryset = VM.objects.all() + serializer_class = VMSerializer + permission_classes = [permissions.IsAuthenticated] + + +class VMViewSet(viewsets.ModelViewSet): + queryset = VM.objects.all() + serializer_class = OpenNebulaVMSerializer + + permission_classes = [permissions.IsAuthenticated] diff --git a/nicohack202002/uncloud/requirements.txt b/uncloud/requirements.txt similarity index 100% rename from nicohack202002/uncloud/requirements.txt rename to uncloud/requirements.txt diff --git a/nicohack202002/uncloud/uncloud/.gitignore b/uncloud/uncloud/.gitignore similarity index 100% rename from nicohack202002/uncloud/uncloud/.gitignore rename to uncloud/uncloud/.gitignore diff --git a/nicohack202002/uncloud/uncloud/__init__.py b/uncloud/uncloud/__init__.py similarity index 100% rename from nicohack202002/uncloud/uncloud/__init__.py rename to uncloud/uncloud/__init__.py diff --git a/nicohack202002/uncloud/uncloud/asgi.py b/uncloud/uncloud/asgi.py similarity index 100% rename from nicohack202002/uncloud/uncloud/asgi.py rename to uncloud/uncloud/asgi.py diff --git a/nicohack202002/uncloud/uncloud/secrets_sample.py b/uncloud/uncloud/secrets_sample.py similarity index 100% rename from nicohack202002/uncloud/uncloud/secrets_sample.py rename to uncloud/uncloud/secrets_sample.py diff --git a/nicohack202002/uncloud/uncloud/settings.py b/uncloud/uncloud/settings.py similarity index 94% rename from nicohack202002/uncloud/uncloud/settings.py rename to uncloud/uncloud/settings.py index edd7c19..17a46d9 100644 --- a/nicohack202002/uncloud/uncloud/settings.py +++ b/uncloud/uncloud/settings.py @@ -83,15 +83,6 @@ TEMPLATES = [ WSGI_APPLICATION = 'uncloud.wsgi.application' -# Database -# https://docs.djangoproject.com/en/3.0/ref/settings/#databases - -DATABASES = { - 'default': { - 'ENGINE': 'django.db.backends.sqlite3', - 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), - } -} # Password validation @@ -168,6 +159,7 @@ STATIC_URL = '/static/' stripe.api_key = secrets.STRIPE_KEY +<<<<<<< HEAD:nicohack202002/uncloud/uncloud/settings.py LOGGING = { 'version': 1, 'disable_existing_loggers': False, @@ -190,4 +182,18 @@ LOGGING = { 'propagate': True } }, +======= +# Uncommitted file with secrets +import uncloud.secrets + + +# Database +# https://docs.djangoproject.com/en/3.0/ref/settings/#databases + +DATABASES = { + 'default': { + 'ENGINE': 'django.db.backends.postgresql', + 'NAME': uncloud.secrets.POSTGRESQL_DB_NAME, + } +>>>>>>> nico/meow-pay-master:uncloud/uncloud/settings.py } diff --git a/nicohack202002/uncloud/uncloud/stripe.py b/uncloud/uncloud/stripe.py similarity index 100% rename from nicohack202002/uncloud/uncloud/stripe.py rename to uncloud/uncloud/stripe.py diff --git a/nicohack202002/uncloud/uncloud/urls.py b/uncloud/uncloud/urls.py similarity index 77% rename from nicohack202002/uncloud/uncloud/urls.py rename to uncloud/uncloud/urls.py index cd8c333..2b90055 100644 --- a/nicohack202002/uncloud/uncloud/urls.py +++ b/uncloud/uncloud/urls.py @@ -24,6 +24,8 @@ from opennebula import views as oneviews router = routers.DefaultRouter() router.register(r'users', views.UserViewSet) router.register(r'groups', views.GroupViewSet) +router.register(r'opennebula', oneviews.VMViewSet) +router.register(r'opennebula_raw', oneviews.RawVMViewSet) # Wire up our API using automatic URL routing. # Additionally, we include login URLs for the browsable API. @@ -31,8 +33,15 @@ urlpatterns = [ path('', include(router.urls)), path('admin/', admin.site.urls), path('products/', views.ProductsView.as_view(), name='products'), +<<<<<<< HEAD:nicohack202002/uncloud/uncloud/urls.py path('api-auth/', include('rest_framework.urls', namespace='rest_framework')), path('opennebula/vm/list/', oneviews.VMList.as_view(), name='vm_list'), path('opennebula/vm/detail//', oneviews.VMDetail.as_view(), name='vm_detail'), path('vm/list/', oneviews.UserVMList.as_view(), name='user_vm_list'), +======= + path('api-auth/', include('rest_framework.urls', namespace='rest_framework')) +# path('vm/list/', oneviews.VMList.as_view(), name='vm_list'), +# path('vm/detail//', oneviews.VMDetail.as_view(), name='vm_detail'), + +>>>>>>> nico/meow-pay-master:uncloud/uncloud/urls.py ] diff --git a/nicohack202002/uncloud/uncloud/wsgi.py b/uncloud/uncloud/wsgi.py similarity index 100% rename from nicohack202002/uncloud/uncloud/wsgi.py rename to uncloud/uncloud/wsgi.py diff --git a/nicohack202002/uncloud/uncloud_api/__init__.py b/uncloud/uncloud_api/__init__.py similarity index 100% rename from nicohack202002/uncloud/uncloud_api/__init__.py rename to uncloud/uncloud_api/__init__.py diff --git a/nicohack202002/uncloud/uncloud_api/admin.py b/uncloud/uncloud_api/admin.py similarity index 54% rename from nicohack202002/uncloud/uncloud_api/admin.py rename to uncloud/uncloud_api/admin.py index f9f5589..d242668 100644 --- a/nicohack202002/uncloud/uncloud_api/admin.py +++ b/uncloud/uncloud_api/admin.py @@ -2,5 +2,5 @@ from django.contrib import admin from .models import Product, Feature -admin.site.register(Product) -admin.site.register(Feature) +#admin.site.register(Product) +#admin.site.register(Feature) diff --git a/nicohack202002/uncloud/uncloud_api/apps.py b/uncloud/uncloud_api/apps.py similarity index 100% rename from nicohack202002/uncloud/uncloud_api/apps.py rename to uncloud/uncloud_api/apps.py diff --git a/nicohack202002/uncloud/uncloud_api/management/__init__.py b/uncloud/uncloud_api/management/__init__.py similarity index 100% rename from nicohack202002/uncloud/uncloud_api/management/__init__.py rename to uncloud/uncloud_api/management/__init__.py diff --git a/nicohack202002/uncloud/uncloud_api/management/commands/__init__.py b/uncloud/uncloud_api/management/commands/__init__.py similarity index 100% rename from nicohack202002/uncloud/uncloud_api/management/commands/__init__.py rename to uncloud/uncloud_api/management/commands/__init__.py diff --git a/nicohack202002/uncloud/uncloud_api/management/commands/hack.py b/uncloud/uncloud_api/management/commands/hack.py similarity index 100% rename from nicohack202002/uncloud/uncloud_api/management/commands/hack.py rename to uncloud/uncloud_api/management/commands/hack.py diff --git a/nicohack202002/uncloud/uncloud_api/management/commands/snapshot.py b/uncloud/uncloud_api/management/commands/snapshot.py similarity index 100% rename from nicohack202002/uncloud/uncloud_api/management/commands/snapshot.py rename to uncloud/uncloud_api/management/commands/snapshot.py diff --git a/uncloud/uncloud_api/migrations/0001_initial.py b/uncloud/uncloud_api/migrations/0001_initial.py new file mode 100644 index 0000000..d8d9630 --- /dev/null +++ b/uncloud/uncloud_api/migrations/0001_initial.py @@ -0,0 +1,31 @@ +# Generated by Django 3.0.3 on 2020-02-23 10:16 + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion +import uuid + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ] + + operations = [ + migrations.CreateModel( + name='VMSnapshotProduct', + fields=[ + ('uuid', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)), + ('status', models.CharField(choices=[('pending', 'Pending'), ('being_created', 'Being created'), ('created_active', 'Created'), ('deleted', 'Deleted')], default='pending', max_length=256)), + ('gb_ssd', models.FloatField()), + ('gb_hdd', models.FloatField()), + ('owner', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), + ], + options={ + 'abstract': False, + }, + ), + ] diff --git a/nicohack202002/uncloud/uncloud_api/migrations/0002_auto_20200222_0719.py b/uncloud/uncloud_api/migrations/0002_auto_20200222_0719.py similarity index 100% rename from nicohack202002/uncloud/uncloud_api/migrations/0002_auto_20200222_0719.py rename to uncloud/uncloud_api/migrations/0002_auto_20200222_0719.py diff --git a/nicohack202002/uncloud/uncloud_api/migrations/__init__.py b/uncloud/uncloud_api/migrations/__init__.py similarity index 100% rename from nicohack202002/uncloud/uncloud_api/migrations/__init__.py rename to uncloud/uncloud_api/migrations/__init__.py diff --git a/uncloud/uncloud_api/models.py b/uncloud/uncloud_api/models.py new file mode 100644 index 0000000..11a7560 --- /dev/null +++ b/uncloud/uncloud_api/models.py @@ -0,0 +1,132 @@ +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) + + # override these fields by default + + description = "" + recurring_period = "not_recurring" + + status = models.CharField(max_length=256, + choices = ( + ('pending', 'Pending'), + ('being_created', 'Being created'), + ('created_active', 'Created'), + ('deleted', 'Deleted') + ), + default='pending' + ) + + 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 + + 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()) + + gb_ssd = models.FloatField() + gb_hdd = models.FloatField() + + + +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) + + +# class Order(models.Model): +# uuid = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False) + +# owner = models.ForeignKey(get_user_model(), +# on_delete=models.CASCADE) + +# product = models.ForeignKey(Product, +# on_delete=models.CASCADE) diff --git a/nicohack202002/uncloud/uncloud_api/serializers.py b/uncloud/uncloud_api/serializers.py similarity index 100% rename from nicohack202002/uncloud/uncloud_api/serializers.py rename to uncloud/uncloud_api/serializers.py diff --git a/nicohack202002/uncloud/uncloud_api/tests.py b/uncloud/uncloud_api/tests.py similarity index 100% rename from nicohack202002/uncloud/uncloud_api/tests.py rename to uncloud/uncloud_api/tests.py diff --git a/uncloud/uncloud_api/views.py b/uncloud/uncloud_api/views.py new file mode 100644 index 0000000..68963ff --- /dev/null +++ b/uncloud/uncloud_api/views.py @@ -0,0 +1,83 @@ +from django.shortcuts import render +from django.contrib.auth import get_user_model +from django.contrib.auth.models import Group + +from rest_framework import viewsets, permissions, generics +from .serializers import UserSerializer, GroupSerializer +from rest_framework.views import APIView +from rest_framework.response import Response + + +class CreditCardViewSet(viewsets.ModelViewSet): + + """ + API endpoint that allows credit cards to be listed + """ + queryset = get_user_model().objects.all().order_by('-date_joined') + serializer_class = UserSerializer + + permission_classes = [permissions.IsAuthenticated] + + +class UserViewSet(viewsets.ModelViewSet): + + """ + API endpoint that allows users to be viewed or edited. + """ + queryset = get_user_model().objects.all().order_by('-date_joined') + serializer_class = UserSerializer + + permission_classes = [permissions.IsAuthenticated] + +class GroupViewSet(viewsets.ModelViewSet): + """ + API endpoint that allows groups to be viewed or edited. + """ + queryset = Group.objects.all() + serializer_class = GroupSerializer + + permission_classes = [permissions.IsAuthenticated] + +class GroupViewSet(viewsets.ModelViewSet): + """ + API endpoint that allows groups to be viewed or edited. + """ + queryset = Group.objects.all() + serializer_class = GroupSerializer + + permission_classes = [permissions.IsAuthenticated] + + +# 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(generics.ListCreateAPIView): + #lookup_field = 'uuid' + permission_classes = [permissions.IsAuthenticated] + +import inspect +import sys +import re + +# Next: create /order/ urls +# Next: strip off "Product" at the end +class ProductsView(APIView): + def get(self, request, format=None): + clsmembers = inspect.getmembers(sys.modules['uncloud_api.models'], inspect.isclass) + products = [] + for name, c in clsmembers: + # Include everything that ends in Product, but not Product itself + m = re.match(r'(?P.+)Product$', name) + if m: + products.append({ + 'name': m.group('pname'), + 'description': c.description, + 'recurring_period': c.recurring_period, + 'pricing_model': c.pricing_model() + } + ) + + + return Response(products) diff --git a/nicohack202002/uncloud/uncloud_auth/__init__.py b/uncloud/uncloud_auth/__init__.py similarity index 100% rename from nicohack202002/uncloud/uncloud_auth/__init__.py rename to uncloud/uncloud_auth/__init__.py diff --git a/nicohack202002/uncloud/uncloud_auth/admin.py b/uncloud/uncloud_auth/admin.py similarity index 100% rename from nicohack202002/uncloud/uncloud_auth/admin.py rename to uncloud/uncloud_auth/admin.py diff --git a/nicohack202002/uncloud/uncloud_auth/apps.py b/uncloud/uncloud_auth/apps.py similarity index 100% rename from nicohack202002/uncloud/uncloud_auth/apps.py rename to uncloud/uncloud_auth/apps.py diff --git a/nicohack202002/uncloud/uncloud_auth/migrations/0001_initial.py b/uncloud/uncloud_auth/migrations/0001_initial.py similarity index 98% rename from nicohack202002/uncloud/uncloud_auth/migrations/0001_initial.py rename to uncloud/uncloud_auth/migrations/0001_initial.py index 267adf2..a3ade55 100644 --- a/nicohack202002/uncloud/uncloud_auth/migrations/0001_initial.py +++ b/uncloud/uncloud_auth/migrations/0001_initial.py @@ -1,4 +1,4 @@ -# Generated by Django 3.0.3 on 2020-02-21 10:41 +# Generated by Django 3.0.3 on 2020-02-23 10:02 import django.contrib.auth.models import django.contrib.auth.validators diff --git a/nicohack202002/uncloud/uncloud_auth/migrations/__init__.py b/uncloud/uncloud_auth/migrations/__init__.py similarity index 100% rename from nicohack202002/uncloud/uncloud_auth/migrations/__init__.py rename to uncloud/uncloud_auth/migrations/__init__.py diff --git a/nicohack202002/uncloud/uncloud_auth/models.py b/uncloud/uncloud_auth/models.py similarity index 100% rename from nicohack202002/uncloud/uncloud_auth/models.py rename to uncloud/uncloud_auth/models.py diff --git a/uncloud/uncloud_vm/__init__.py b/uncloud/uncloud_vm/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/uncloud/uncloud_vm/admin.py b/uncloud/uncloud_vm/admin.py new file mode 100644 index 0000000..8c38f3f --- /dev/null +++ b/uncloud/uncloud_vm/admin.py @@ -0,0 +1,3 @@ +from django.contrib import admin + +# Register your models here. diff --git a/uncloud/uncloud_vm/apps.py b/uncloud/uncloud_vm/apps.py new file mode 100644 index 0000000..c5e94a5 --- /dev/null +++ b/uncloud/uncloud_vm/apps.py @@ -0,0 +1,5 @@ +from django.apps import AppConfig + + +class UncloudVmConfig(AppConfig): + name = 'uncloud_vm' diff --git a/uncloud/uncloud_vm/migrations/__init__.py b/uncloud/uncloud_vm/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/uncloud/uncloud_vm/models.py b/uncloud/uncloud_vm/models.py new file mode 100644 index 0000000..b1aab40 --- /dev/null +++ b/uncloud/uncloud_vm/models.py @@ -0,0 +1,12 @@ +from django.db import models + + +class VM(models.Model): + uuid = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False) + owner = models.ForeignKey(get_user_model(), on_delete=models.CASCADE) + + cores = models.IntegerField() + ram = models.FloatField() + + +class VMDisk(models.Model): diff --git a/uncloud/uncloud_vm/tests.py b/uncloud/uncloud_vm/tests.py new file mode 100644 index 0000000..7ce503c --- /dev/null +++ b/uncloud/uncloud_vm/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/uncloud/uncloud_vm/views.py b/uncloud/uncloud_vm/views.py new file mode 100644 index 0000000..aa5855c --- /dev/null +++ b/uncloud/uncloud_vm/views.py @@ -0,0 +1,24 @@ +from django.shortcuts import render + + +from django.contrib.auth.models import User +from django.shortcuts import get_object_or_404 +from myapps.serializers import UserSerializer +from rest_framework import viewsets +from rest_framework.response import Response + +from opennebula.models import VM as OpenNebulaVM + +class VMViewSet(viewsets.ViewSet): + def list(self, request): + queryset = User.objects.all() + serializer = UserSerializer(queryset, many=True) + return Response(serializer.data) + + def retrieve(self, request, pk=None): + queryset = User.objects.all() + user = get_object_or_404(queryset, pk=pk) + serializer = UserSerializer(user) + return Response(serializer.data) + + permission_classes = [permissions.IsAuthenticated]