Commit 2cd38e18 by Chif Gergő

Merge DEV to instance_view

parents e28c1606 b50c79c7
.vscode/
.idea/
recircle/db.sqlite3
recircle/clouds.yaml
environment.sh
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class
# C extensions
*.so
# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
pip-wheel-metadata/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST
example.py
# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
# Unit test / coverage reports
htmlcov/
.tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
.hypothesis/
.pytest_cache/
# Translations
*.mo
*.pot
# Django stuff:
*.log
local_settings.py
db.sqlite3
# Flask stuff:
.webassets-cache
# Scrapy stuff:
.scrapy
# Sphinx documentation
docs/_build/
# PyBuilder
target/
# Jupyter Notebook
.ipynb_checkpoints
# IPython
profile_default/
ipython_config.py
# pyenv
.python-version
# pipenv
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
# However, in case of collaboration, if having platform-specific dependencies or dependencies
# having no cross-platform support, pipenv may install dependencies that don’t work, or not
# install all needed dependencies.
#Pipfile.lock
# celery beat schedule file
celerybeat-schedule
# SageMath parsed files
*.sage.py
# Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/
# Spyder project settings
.spyderproject
.spyproject
# Rope project settings
.ropeproject
# mkdocs documentation
/site
# mypy
.mypy_cache/
.dmypy.json
dmypy.json
# Pyre type checker
.pyre/
# Cloud configure
clouds.yaml
# pyc files
*.pyc
.idea/
{
"_meta": {
"hash": {
"sha256": "2adbcb2f6437576c7ac5794c996bf94a73714555a6ccc0e393fcb24bf184c1da"
"sha256": "f991f85fb7c006559ee78cb35cc3a18089dfd0065a565f2b194c197cbf772a50"
},
"pipfile-spec": 6,
"requires": {
......@@ -144,11 +144,11 @@
},
"djangorestframework": {
"hashes": [
"sha256:376f4b50340a46c15ae15ddd0c853085f4e66058f97e4dbe7d43ed62f5e60651",
"sha256:c12869cfd83c33d579b17b3cb28a2ae7322a53c3ce85580c2a2ebe4e3f56c4fb"
"sha256:1ca4a5599a5ec31f3d6238a687fcc1dd4c41b1d90edab9ad398fcbf87872b7ba",
"sha256:c3c5edfdbc5dd33f9121bb84305bfd603d2c791f20cff9782772f44a7684a4e4"
],
"index": "pypi",
"version": "==3.9.4"
"version": "==3.10.1"
},
"djoser": {
"hashes": [
......@@ -202,11 +202,11 @@
},
"keystoneauth1": {
"hashes": [
"sha256:b14f363d02142177c968cfffeb9eb37113682c03ac3c65d483424e203dd602c3",
"sha256:b1e3910e09b01f88e84ce4c873f271f2b076b4ad266c2815c16ee3aef8319192"
"sha256:3fabba6a87b64ec9a7ec09522e508a849f255cc8a8b6f7ad87d894a4bcc9ae58",
"sha256:439f7dcf6edde5ea5a16ef90603d198e118a03f529aba0f8a6d19d5f6433de95"
],
"index": "pypi",
"version": "==3.14.0"
"version": "==3.15.0"
},
"msgpack": {
"hashes": [
......@@ -308,10 +308,10 @@
},
"pbr": {
"hashes": [
"sha256:36ebd78196e8c9588c972f5571230a059ff83783fabbbbedecc07be263ccd7e6",
"sha256:5a03f59455ad54f01a94c15829b8b70065462b7bd8d5d7e983306b59127fc841"
"sha256:0ca44dc9fd3b04a22297c2a91082d8df2894862e8f4c86a49dac69eae9e85ca0",
"sha256:4aed6c1b1fa5020def0f22aed663d87b81bb3235f112490b07d2643d7a98c5b5"
],
"version": "==5.4.0"
"version": "==5.4.1"
},
"prettytable": {
"hashes": [
......@@ -329,18 +329,18 @@
},
"pyparsing": {
"hashes": [
"sha256:1873c03321fc118f4e9746baf201ff990ceb915f433f23b395f5580d1840cb2a",
"sha256:9b6323ef4ab914af344ba97510e966d64ba91055d6b9afa6b30799340e89cc03"
"sha256:530d8bf8cc93a34019d08142593cf4d78a05c890da8cf87ffa3120af53772238",
"sha256:f78e99616b6f1a4745c0580e170251ef1bbafc0d0513e270c4bd281bf29d2800"
],
"version": "==2.4.0"
"version": "==2.4.1"
},
"python-novaclient": {
"hashes": [
"sha256:882ae865ff5cebfaa0c323978da20486876ea17e500466cdabcd91038906a86b",
"sha256:9a4477862a77155e1267207685a4ae487ce12f0e9e37cff56a6c1b43fe390e79"
"sha256:42f4cabc151850c2b2a590e4253866523abaf669dca310b58a439352972a02d2",
"sha256:5cb54a23e3413d4bf63bcacee8fd6b7b5ec33a4eb4183a95c86f6241c071959e"
],
"index": "pypi",
"version": "==14.1.0"
"version": "==14.2.0"
},
"pytz": {
"hashes": [
......@@ -507,11 +507,11 @@
},
"djangorestframework": {
"hashes": [
"sha256:376f4b50340a46c15ae15ddd0c853085f4e66058f97e4dbe7d43ed62f5e60651",
"sha256:c12869cfd83c33d579b17b3cb28a2ae7322a53c3ce85580c2a2ebe4e3f56c4fb"
"sha256:1ca4a5599a5ec31f3d6238a687fcc1dd4c41b1d90edab9ad398fcbf87872b7ba",
"sha256:c3c5edfdbc5dd33f9121bb84305bfd603d2c791f20cff9782772f44a7684a4e4"
],
"index": "pypi",
"version": "==3.9.4"
"version": "==3.10.1"
},
"entrypoints": {
"hashes": [
......@@ -522,11 +522,11 @@
},
"flake8": {
"hashes": [
"sha256:859996073f341f2670741b51ec1e67a01da142831aa1fdc6242dbf88dffbe661",
"sha256:a796a115208f5c03b18f332f7c11729812c8c3ded6c46319c59b53efd3819da8"
"sha256:19241c1cbc971b9962473e4438a2ca19749a7dd002dd1a946eaba171b4114548",
"sha256:8e9dfa3cecb2400b3738a42c54c3043e821682b9c840b0448c0503f781130696"
],
"index": "pypi",
"version": "==3.7.7"
"version": "==3.7.8"
},
"httpie": {
"hashes": [
......
# from django.contrib import admin
from django.contrib import admin
# Register your models here.
from image.models import Image
from image.models import Disk
admin.site.register(Image)
admin.site.register(Disk)
# Generated by Django 2.2.3 on 2019-07-15 13:54
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('image', '0001_initial'),
]
operations = [
migrations.CreateModel(
name='Image',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(help_text='Human readable name of image.', max_length=100, verbose_name='name')),
('description', models.TextField(blank=True, help_text='Description of the image.', verbose_name='description')),
('remote_ID', models.CharField(help_text='ID, which helps access the image.', max_length=40, unique=True, verbose_name='remote_ID')),
('created_at', models.DateTimeField(auto_now_add=True, help_text='Date, when the image created.')),
],
),
]
# Generated by Django 2.2.3 on 2019-07-16 11:51
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),
('image', '0002_image'),
]
operations = [
migrations.RenameField(
model_name='disk',
old_name='remote_ID',
new_name='remote_id',
),
migrations.RenameField(
model_name='image',
old_name='remote_ID',
new_name='remote_id',
),
migrations.AddField(
model_name='image',
name='created_by',
field=models.ForeignKey(default=0, help_text='The user, who create the image', on_delete=django.db.models.deletion.DO_NOTHING, related_name='created_images', to=settings.AUTH_USER_MODEL),
preserve_default=False,
),
migrations.AddField(
model_name='image',
name='uploaded_by_user',
field=models.BooleanField(default=True, editable=False, help_text='The field is false if the image created from instance'),
),
]
from django.db import models
from django.contrib.auth.models import User
from django.conf import settings
from interface_openstack.implementation.vm.instance import OSVirtualMachineManager
from interface_openstack.implementation.image.openstack_image_manager import OpenstackImageManager
class Disk(models.Model):
......@@ -9,9 +14,86 @@ class Disk(models.Model):
name = models.CharField(
blank=True, max_length=100, verbose_name="name", help_text="Name of the disk"
)
remote_ID = models.CharField(
remote_id = models.CharField(
max_length=40,
unique=True,
verbose_name="remote_ID",
help_text="ID, which helps access the disk",
)
class Image(models.Model):
"""A virtual image.
"""
name = models.CharField(
max_length=100,
verbose_name="name",
help_text="Human readable name of image."
)
description = models.TextField(
verbose_name="description",
blank=True,
help_text="Description of the image."
)
remote_id = models.CharField(
max_length=40,
unique=True,
verbose_name="remote_ID",
help_text="ID, which helps access the image."
)
created_at = models.DateTimeField(
auto_now_add=True,
editable=False,
help_text="Date, when the image created."
)
uploaded_by_user = models.BooleanField(
default=True,
editable=False,
help_text="The field is false if the image created from instance"
)
created_by = models.ForeignKey(
User,
on_delete=models.DO_NOTHING,
related_name="created_images",
help_text="The user, who create the image"
)
@classmethod
def create(cls, name, description, remote_id, uploaded_by_user, created_by):
inst = cls(name=name, description=description, uploaded_by_user=uploaded_by_user,
remote_id=remote_id, created_by=created_by)
inst.full_clean()
inst.save()
return inst
@classmethod
def create_from_instance(cls, user, instance, description):
interface = OSVirtualMachineManager(settings.CONNECTION)
remote_image = interface.create_image(instance.remote_id)
remote_id = remote_image.id
name = remote_image.name
new_image = cls.create(
name=name,
remote_id=remote_id,
created_by=user,
uploaded_by_user=False,
description=description
)
return new_image
@classmethod
def create_from_user(cls, description, file_format, image_file, name, user):
interface = OpenstackImageManager(settings.CONNECTION)
remote_image = interface.upload_file(name=name, path=image_file.temporary_file_path(),
format=file_format)
new_image = cls.create(
name=name,
remote_id=remote_image.id,
created_by=user,
uploaded_by_user=True,
description=description
)
return new_image
from rest_framework import serializers
from .models import Disk
from .models import Image
class DiskSerializer(serializers.ModelSerializer):
class ImageSerializer(serializers.ModelSerializer):
image_file = serializers.FileField(write_only=True)
file_format = serializers.CharField(max_length=10, write_only=True)
class Meta:
model = Disk
fields = ("name", "remote_ID")
model = Image
fields = (
"name",
"remote_id",
"description",
"image_file",
"file_format",
"created_at",
"uploaded_by_user",
"created_by",
)
read_only_fields = ("created_at", "uploaded_by_user", "created_by", "remote_id", )
from django.urls import path
from rest_framework.urlpatterns import format_suffix_patterns
from rest_framework import routers
from image import views
urlpatterns = [path("", views.DiskList.as_view())]
router = routers.DefaultRouter()
router.register(r"images", views.ImageViewSet, basename="image")
urlpatterns = format_suffix_patterns(urlpatterns)
urlpatterns = router.urls
from image.models import Disk
from image.serializers import DiskSerializer
# from django.shortcuts import render
from rest_framework.views import APIView
from rest_framework.viewsets import ModelViewSet
from rest_framework.response import Response
from interface_openstack.implementation.image.openstack_image_manager import (
OpenstackImageManager,
)
from django.conf import settings
from image.models import Image
from image.serializers import ImageSerializer
class DiskList(APIView):
def get(self, request, format=None):
# OpenStack
interface = OpenstackImageManager(settings.CONNECTION)
return Response([disk.__dict__ for disk in interface.list()])
# Create response
disks = Disk.object.all()
serializer = DiskSerializer(disks, many=True)
class ImageViewSet(ModelViewSet):
serializer_class = ImageSerializer
queryset = Image.objects.all()
# def list(self, request):
# return HttpResponse("list")
def create(self, request):
serializer = ImageSerializer(data=request.data)
serializer.is_valid(raise_exception=True)
data = serializer.validated_data
new_image = Image.create_from_user(
description=data['description'],
file_format=data['file_format'],
image_file=data['image_file'],
name=data['name'],
user=request.user
)
serializer = ImageSerializer(instance=new_image)
return Response(serializer.data)
# def retrieve(self, request, pk=None):
# return HttpResponse("retrive")
# def update(self, request, pk=None):
# return HttpResponse("update")
# def partial_update(self, request, pk=None):
# return HttpResponse("patch")
# def destroy(self, request, pk=None):
# return HttpResponse("delete")
# Generated by Django 2.2.3 on 2019-07-15 13:54
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('instance', '0008_auto_20190704_1310'),
]
operations = [
migrations.AlterField(
model_name='instance',
name='flavor',
field=models.ForeignKey(help_text='Reasources given to the vm', on_delete='CASCADE', related_name='instances', to='instance.Flavor', verbose_name='flavor'),
),
migrations.AlterField(
model_name='instance',
name='lease',
field=models.ForeignKey(on_delete='CASCADE', related_name='instances', to='instance.Lease'),
),
]
......@@ -4,11 +4,13 @@ from django.conf import settings
from rest_framework.viewsets import ViewSet, ModelViewSet
from rest_framework.response import Response
from rest_framework import status
from interface_openstack.implementation.vm.instance import (
OSVirtualMachineManager
)
from template.models import InstanceTemplate
from instance.models import Instance, Flavor, Lease
from instance.serializers import InstanceSerializer, FlavorSerializer
from template.models import ImageTemplate
class InstanceViewSet(ViewSet):
......@@ -25,7 +27,7 @@ class InstanceViewSet(ViewSet):
def create(self, request):
data = request.data
template = InstanceTemplate.objects.get(pk=data["template"])
template = ImageTemplate.objects.get(pk=data["template"])
flavor = Flavor.objects.get(pk=data["flavor"])
lease = Lease.objects.get(pk=data["lease"])
......
......@@ -21,8 +21,9 @@ from rest_framework_swagger.views import get_swagger_view
schema_view = get_swagger_view(title="RECIRCLE API")
urlpatterns = [
path("images/", include("image.urls")),
path("api/v1/", include("image.urls")),
path("api/v1/", include("instance.urls")),
path("api/v1/", include("template.urls")),
path("admin/", admin.site.urls),
re_path(r"^auth/", include("djoser.urls")),
re_path(r"^auth/", include("djoser.urls.authtoken")),
......
# from django.contrib import admin
from django.contrib import admin
# Register your models here.
from template.models import ImageTemplate
admin.site.register(ImageTemplate)
# Generated by Django 2.2.1 on 2019-07-04 12:12
# Generated by Django 2.2.3 on 2019-07-03 12:09
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
......@@ -8,16 +9,26 @@ class Migration(migrations.Migration):
initial = True
dependencies = [
('image', '0001_initial'),
]
operations = [
migrations.CreateModel(
name='InstanceTemplate',
name='BaseTemplate',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(help_text='Human readable name of template.', max_length=100, verbose_name='name')),
('description', models.TextField(blank=True, help_text='Description of the template.', verbose_name='description')),
('remote_ID', models.CharField(help_text='ID, which helps access the template.', max_length=40, unique=True, verbose_name='remote_ID')),
('created_at', models.DateTimeField(auto_now_add=True, help_text='Date, when the template created.')),
],
),
migrations.CreateModel(
name='Template',
fields=[
('basetemplate_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='template.BaseTemplate')),
('disk', models.ForeignKey(help_text='The disk where the template is located.', on_delete=django.db.models.deletion.CASCADE, related_name='templates', to='image.Disk')),
],
bases=('template.basetemplate',),
),
]
# Generated by Django 2.2.3 on 2019-07-15 13:54
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('image', '0002_image'),
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('template', '0001_initial'),
]
operations = [
migrations.AddField(
model_name='basetemplate',
name='created_by',
field=models.ForeignKey(default=1, on_delete=django.db.models.deletion.DO_NOTHING, related_name='created_templates', to=settings.AUTH_USER_MODEL),
preserve_default=False,
),
migrations.CreateModel(
name='PureTemplate',
fields=[
('basetemplate_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='template.BaseTemplate')),
('images', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='templates', to='image.Image')),
],
bases=('template.basetemplate',),
),
]
# Generated by Django 2.2.3 on 2019-07-16 11:51
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('image', '0003_auto_20190716_1151'),
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('template', '0002_auto_20190715_1354'),
]
operations = [
migrations.RenameModel(
old_name='Template',
new_name='DiskTemplate',
),
migrations.RenameModel(
old_name='PureTemplate',
new_name='ImageTemplate',
),
migrations.RemoveField(
model_name='basetemplate',
name='remote_ID',
),
migrations.AlterField(
model_name='basetemplate',
name='created_by',
field=models.ForeignKey(help_text='The user, who create the template', on_delete=django.db.models.deletion.DO_NOTHING, related_name='created_templates', to=settings.AUTH_USER_MODEL),
),
]
# Generated by Django 2.2.3 on 2019-07-16 12:27
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('template', '0003_auto_20190716_1151'),
]
operations = [
migrations.RenameField(
model_name='imagetemplate',
old_name='images',
new_name='image',
),
]
# Generated by Django 2.2.3 on 2019-07-17 09:48
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('instance', '0009_auto_20190715_1354'),
('template', '0004_auto_20190716_1227'),
]
operations = [
migrations.AddField(
model_name='basetemplate',
name='flavor',
field=models.ForeignKey(default=1, help_text='Reasources given to the vm', on_delete='CASCADE', related_name='templates', to='instance.Flavor', verbose_name='flavor'),
preserve_default=False,
),
migrations.AddField(
model_name='basetemplate',
name='lease',
field=models.ForeignKey(default=1, on_delete='CASCADE', related_name='templates', to='instance.Lease'),
preserve_default=False,
),
migrations.AddField(
model_name='imagetemplate',
name='type',
field=models.CharField(choices=[('U', 'User create the template from image'), ('I', 'Template created from instance'), ('D', 'Default "Pure" template')], default='I', max_length=10),
preserve_default=False,
),
]
# Generated by Django 2.2.3 on 2019-07-19 14:16
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('template', '0005_auto_20190717_0948'),
]
operations = [
migrations.AlterField(
model_name='imagetemplate',
name='type',
field=models.CharField(choices=[('U', 'User create the template from image'), ('I', 'Template created from instance'), ('P', '"Pure" template')], default='U', max_length=10),
),
]
from django.db import models
from django.contrib.auth.models import User
from django.conf import settings
from image.models import Disk
from image.models import Image
from instance.models import Lease
from instance.models import Flavor
from interface_openstack.implementation.storage.openstack_snapshot_manager import SnapshotManager
class InstanceTemplate(models.Model):
class BaseTemplate(models.Model):
"""Virtual machine template.
"""
......@@ -9,15 +17,93 @@ class InstanceTemplate(models.Model):
name = models.CharField(
max_length=100,
verbose_name="name",
help_text="Human readable name of template.",
help_text="Human readable name of template."
)
description = models.TextField(
verbose_name="description", blank=True, help_text="Description of the template."
verbose_name="description",
blank=True,
help_text="Description of the template."
)
# remote_id = models.CharField(
# max_length=40,
# unique=True,
# verbose_name="remote_ID",
# help_text="ID, which helps access the template."
# )
created_at = models.DateTimeField(
auto_now_add=True,
editable=False,
help_text="Date, when the template created."
)
created_by = models.ForeignKey(
User,
on_delete=models.DO_NOTHING,
related_name="created_templates",
help_text="The user, who create the template"
)
flavor = models.ForeignKey(Flavor, help_text="Reasources given to the vm",
verbose_name="flavor", on_delete="CASCADE",
related_name='templates')
lease = models.ForeignKey(Lease, on_delete="CASCADE",
related_name='templates')
class DiskTemplate(BaseTemplate):
disk = models.ForeignKey(
Disk,
related_name="templates",
on_delete=models.CASCADE,
help_text="The disk where the template is located."
)
@classmethod
def create_from_volume(cls, name, description, disk, user):
interface = SnapshotManager(settings.CONNECTION)
remote_template = interface.create_from_volume(disk.remote_id)
remote_id = remote_template.id
new_template = cls.create(
name=name,
description=description,
disk=disk,
remote_id=remote_id,
created_by=user
)
# owner = models.ForeignKey(User)
remote_ID = models.CharField(
max_length=40,
unique=True,
verbose_name="remote_ID",
help_text="ID, which helps access the template.",
return new_template
class ImageTemplate(BaseTemplate):
TYPES = (
('U', 'User create the template from image'),
('I', 'Template created from instance'),
('P', '"Pure" template'),
)
image = models.ForeignKey(
Image,
related_name="templates",
on_delete=models.CASCADE,
help_text=""
)
type = models.CharField(max_length=10, choices=TYPES, default="U")
@classmethod
def create(cls, name, description, image, lease, flavor, created_by, type='U'):
inst = cls(name=name, description=description, image=image, lease=lease,
flavor=flavor, created_by=created_by, type=type)
inst.full_clean()
inst.save()
return inst
@classmethod
def create_from_instance(cls, name, description, instance, user):
image = Image.create_from_instance(user, instance, description)
new_template = cls.create(
name=name,
description=description,
created_by=user,
image=image,
lease=instance.lease,
flavor=instance.flavor,
type="I"
)
return new_template
from rest_framework import serializers
from .models import InstanceTemplate
from template.models import ImageTemplate
class InstanceTemplateSerializer(serializers.ModelSerializer):
class InstanceFromTemplateSerializer(serializers.Serializer):
name = serializers.CharField()
description = serializers.CharField()
class ImageTemplateModelSerializer(serializers.ModelSerializer):
class Meta:
model = InstanceTemplate
fields = ("name", "description", "owner", "remote_ID")
model = ImageTemplate
fields = (
"name",
"description",
"created_at",
"created_by",
"image",
"flavor",
"lease",
"type",
)
read_only_fields = (
"created_at",
"created_by",
"type",
)
from rest_framework import routers
from template import views
router = routers.DefaultRouter()
router.register(r"templates/image-templates", views.ImageTemplateViewSet, basename="image-template")
urlpatterns = router.urls
# from django.shortcuts import render
from rest_framework.response import Response
from rest_framework.viewsets import ModelViewSet
from rest_framework.decorators import action
# Create your views here.
from template.serializers import InstanceFromTemplateSerializer
from template.serializers import ImageTemplateModelSerializer
from template.models import ImageTemplate
class ImageTemplateViewSet(ModelViewSet):
serializer_class = ImageTemplateModelSerializer
queryset = ImageTemplate.objects.all()
def create(self, request):
serializer = ImageTemplateModelSerializer(data=request.data)
serializer.is_valid(raise_exception=True)
data = serializer.validated_data
new_template = ImageTemplate.create(
name=data["name"],
description=data["description"],
created_by=request.user,
image=data["image"],
lease=data["lease"],
flavor=data["flavor"],
type="U"
)
serializer = ImageTemplateModelSerializer(instance=new_template)
return Response(serializer.data)
def update(self, request, *args, **kwargs):
# only the name, description, lease, flavor can be updated
allowed_keys = ["name", "description", "lease", "flavor"]
# delete not allowed key
for key in request.data.keys():
if key not in allowed_keys:
request.data.pop(key, None)
return super(ImageTemplateViewSet, self).update(request, partial=True)
@action(detail=True, methods=["post"])
def template(self, request, pk):
instance = self.get_object(pk)
serializer = InstanceFromTemplateSerializer(data=request.data)
serializer.is_valid(raise_exception=True)
data = serializer.validated_data
new_template = ImageTemplate.create_from_instance(data["name"], data["description"],
instance, request.user)
serializer = ImageTemplateModelSerializer(instance=new_template)
return Response(serializer.data)
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment