1
0
Fork 0
mirror of https://github.com/retspen/webvirtcloud synced 2024-12-26 08:05:22 +00:00
webvirtcloud/instances/api/viewsets.py

266 lines
9.3 KiB
Python
Raw Normal View History

from appsettings.settings import app_settings
from computes import utils
2022-11-02 13:05:41 +00:00
from computes.models import Compute
from django.shortcuts import get_object_or_404
from instances.models import Flavor, Instance
from instances.utils import migrate_instance
2022-11-02 13:05:41 +00:00
from instances.views import destroy as instance_destroy
2022-11-02 05:54:35 +00:00
from instances.views import (
2022-11-02 13:05:41 +00:00
force_off,
get_instance,
2022-11-02 05:54:35 +00:00
powercycle,
poweroff,
2022-11-02 13:05:41 +00:00
poweron,
2022-11-02 05:54:35 +00:00
resume,
2022-11-02 13:05:41 +00:00
suspend,
2022-11-02 05:54:35 +00:00
)
2022-11-02 13:05:41 +00:00
from rest_framework import permissions, status, viewsets
from rest_framework.decorators import action
from rest_framework.response import Response
from vrtManager import util
from vrtManager.create import wvmCreate
2022-11-02 13:05:41 +00:00
2022-11-02 05:54:35 +00:00
from .serializers import (
2022-11-02 13:05:41 +00:00
CreateInstanceSerializer,
2022-11-02 05:54:35 +00:00
FlavorSerializer,
InstanceDetailsSerializer,
2022-11-02 13:05:41 +00:00
InstanceSerializer,
2022-11-02 05:54:35 +00:00
MigrateSerializer,
)
class InstancesViewSet(viewsets.ViewSet):
"""
A simple ViewSet for listing or retrieving ALL/Compute Instances.
"""
2022-11-02 05:54:35 +00:00
permission_classes = [permissions.IsAuthenticated]
2022-11-02 05:54:35 +00:00
def list(self, request):
2022-11-02 13:05:41 +00:00
if request.user.is_superuser or request.user.has_perm(
"instances.view_instances"
):
queryset = Instance.objects.all().prefetch_related("userinstance_set")
else:
2022-11-02 13:05:41 +00:00
queryset = Instance.objects.filter(
userinstance__user=request.user
).prefetch_related("userinstance_set")
2022-11-02 05:54:35 +00:00
serializer = InstanceSerializer(
2022-11-02 13:05:41 +00:00
queryset, many=True, context={"request": request}
2022-11-02 05:54:35 +00:00
)
return Response(serializer.data)
def retrieve(self, request, pk=None, compute_pk=None):
queryset = get_instance(request.user, pk)
2022-11-02 05:54:35 +00:00
serializer = InstanceSerializer(queryset, context={"request": request})
return Response(serializer.data)
class InstanceViewSet(viewsets.ViewSet):
"""
A simple ViewSet for listing or retrieving Compute Instances.
"""
2022-11-02 05:54:35 +00:00
# serializer_class = CreateInstanceSerializer
permission_classes = [permissions.IsAuthenticated]
2022-11-02 05:54:35 +00:00
def list(self, request, compute_pk=None):
compute = get_object_or_404(Compute, pk=compute_pk)
utils.refresh_instance_database(compute)
2022-11-02 05:54:35 +00:00
2022-11-02 13:05:41 +00:00
queryset = Instance.objects.filter(compute=compute).prefetch_related(
"userinstance_set"
)
2022-11-02 05:54:35 +00:00
serializer = InstanceSerializer(
2022-11-02 13:05:41 +00:00
queryset, many=True, context={"request": request}
2022-11-02 05:54:35 +00:00
)
2022-11-02 05:54:35 +00:00
return Response(serializer.data)
def retrieve(self, request, pk=None, compute_pk=None):
queryset = get_instance(request.user, pk)
2022-11-02 05:54:35 +00:00
serializer = InstanceDetailsSerializer(queryset, context={"request": request})
return Response(serializer.data)
def destroy(self, request, pk=None, compute_pk=None):
instance_destroy(request, pk)
2022-11-02 05:54:35 +00:00
return Response({"status": "Instance is destroyed"})
2022-11-02 05:54:35 +00:00
@action(detail=True, methods=["post"])
def poweron(self, request, pk=None):
poweron(request, pk)
2022-11-02 05:54:35 +00:00
return Response({"status": "poweron command send"})
@action(detail=True, methods=["post"])
def poweroff(self, request, pk=None):
poweroff(request, pk)
2022-11-02 05:54:35 +00:00
return Response({"status": "poweroff command send"})
@action(detail=True, methods=["post"])
def powercycle(self, request, pk=None):
powercycle(request, pk)
2022-11-02 05:54:35 +00:00
return Response({"status": "powercycle command send"})
@action(detail=True, methods=["post"])
def forceoff(self, request, pk=None):
force_off(request, pk)
2022-11-02 05:54:35 +00:00
return Response({"status": "force off command send"})
2022-11-02 05:54:35 +00:00
@action(detail=True, methods=["post"])
def suspend(self, request, pk=None):
suspend(request, pk)
2022-11-02 05:54:35 +00:00
return Response({"status": "suspend command send"})
2022-11-02 05:54:35 +00:00
@action(detail=True, methods=["post"])
def resume(self, request, pk=None):
resume(request, pk)
2022-11-02 05:54:35 +00:00
return Response({"status": "resume command send"})
class MigrateViewSet(viewsets.ViewSet):
"""
A viewset for migrating instances.
"""
2022-11-02 05:54:35 +00:00
serializer_class = MigrateSerializer
queryset = ""
def create(self, request):
serializer = MigrateSerializer(data=request.data)
if serializer.is_valid():
2022-11-02 05:54:35 +00:00
instance = serializer.validated_data["instance"]
target_host = serializer.validated_data["target_compute"]
live = serializer.validated_data["live"]
unsafe = serializer.validated_data["unsafe"]
xml_del = serializer.validated_data["xml_del"]
offline = serializer.validated_data["offline"]
autoconverge = serializer.validated_data["autoconverge"]
postcopy = serializer.validated_data["postcopy"]
compress = serializer.validated_data["compress"]
migrate_instance(
target_host,
instance,
request.user,
live,
unsafe,
xml_del,
offline,
autoconverge,
compress,
postcopy,
)
return Response({"status": "instance migrate is started"})
else:
2022-11-02 05:54:35 +00:00
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
class FlavorViewSet(viewsets.ModelViewSet):
"""
API endpoint that allows flavor to be viewed.
"""
2022-11-02 05:54:35 +00:00
queryset = Flavor.objects.all().order_by("id")
serializer_class = FlavorSerializer
permission_classes = [permissions.IsAuthenticated]
class CreateInstanceViewSet(viewsets.ViewSet):
"""
A viewset for creating instances.
"""
2022-11-02 05:54:35 +00:00
serializer_class = CreateInstanceSerializer
queryset = ""
2022-11-02 05:54:35 +00:00
def create(self, request, compute_pk=None, arch=None, machine=None):
2022-11-02 05:54:35 +00:00
serializer = CreateInstanceSerializer(
data=request.data,
context={"compute_pk": compute_pk, "arch": arch, "machine": machine},
)
if serializer.is_valid():
volume_list = []
default_bus = app_settings.INSTANCE_VOLUME_DEFAULT_BUS
default_io = app_settings.INSTANCE_VOLUME_DEFAULT_IO
default_discard = app_settings.INSTANCE_VOLUME_DEFAULT_DISCARD
default_zeroes = app_settings.INSTANCE_VOLUME_DEFAULT_DETECT_ZEROES
2022-11-02 13:05:41 +00:00
default_scsi_disk_model = (
app_settings.INSTANCE_VOLUME_DEFAULT_SCSI_CONTROLLER
)
default_disk_format = app_settings.INSTANCE_VOLUME_DEFAULT_FORMAT
default_disk_owner_uid = int(app_settings.INSTANCE_VOLUME_DEFAULT_OWNER_UID)
default_disk_owner_gid = int(app_settings.INSTANCE_VOLUME_DEFAULT_OWNER_GID)
compute = Compute.objects.get(pk=compute_pk)
conn = wvmCreate(
compute.hostname,
compute.login,
compute.password,
compute.type,
)
path = conn.create_volume(
2022-11-02 05:54:35 +00:00
serializer.validated_data["storage"],
serializer.validated_data["name"],
serializer.validated_data["hdd_size"],
default_disk_format,
serializer.validated_data["meta_prealloc"],
default_disk_owner_uid,
default_disk_owner_gid,
)
volume = {}
firmware = {}
volume["device"] = "disk"
volume["path"] = path
volume["type"] = conn.get_volume_format_type(path)
volume["cache_mode"] = serializer.validated_data["cache_mode"]
volume["bus"] = default_bus
if volume["bus"] == "scsi":
volume["scsi_model"] = default_scsi_disk_model
volume["discard_mode"] = default_discard
volume["detect_zeroes_mode"] = default_zeroes
volume["io_mode"] = default_io
volume_list.append(volume)
2022-11-02 05:54:35 +00:00
if "UEFI" in serializer.validated_data["firmware"]:
2022-11-02 13:05:41 +00:00
firmware["loader"] = (
serializer.validated_data["firmware"].split(":")[1].strip()
)
firmware["secure"] = "no"
firmware["readonly"] = "yes"
firmware["type"] = "pflash"
if "secboot" in firmware["loader"] and machine != "q35":
machine = "q35"
firmware["secure"] = "yes"
ret = conn.create_instance(
2022-11-02 05:54:35 +00:00
name=serializer.validated_data["name"],
memory=serializer.validated_data["memory"],
vcpu=serializer.validated_data["vcpu"],
vcpu_mode=serializer.validated_data["vcpu_mode"],
2022-09-05 12:35:51 +00:00
uuid=util.randomUUID(),
arch=arch,
machine=machine,
firmware=firmware,
volumes=volume_list,
2022-11-02 05:54:35 +00:00
networks=serializer.validated_data["networks"],
nwfilter=serializer.validated_data["nwfilter"],
graphics=serializer.validated_data["graphics"],
virtio=serializer.validated_data["virtio"],
listener_addr=serializer.validated_data["listener_addr"],
video=serializer.validated_data["video"],
console_pass=serializer.validated_data["console_pass"],
mac=serializer.validated_data["mac"],
qemu_ga=serializer.validated_data["qemu_ga"],
)
msg = f"Instance {serializer.validated_data['name']} is created"
2022-11-02 05:54:35 +00:00
return Response({"status": msg})
else:
2022-11-02 05:54:35 +00:00
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)