VRE Backend API and Scheduler
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

243 lines
10 KiB

from django.conf import settings
from django.http.response import Http404
from drf_yasg.utils import swagger_auto_schema
from rest_framework.generics import GenericAPIView, get_object_or_404
from rest_framework.viewsets import ReadOnlyModelViewSet
from rest_framework.decorators import action
from rest_framework.response import Response
from .serializers import (VirtualMachineProviderSerializer, VirtualMachineSerializer, VirtualMachineDetailSerializer,
VirtualMachineOperatingSystemSerializer,
VirtualMachineProfileSerializer,
VirtualMachineMemorySerializer,
VirtualMachineNetworkSerializer,
VirtualMachineStorageSerializer,
VirtualMachineGPUSerializer)
from apps.virtual_machine.models import (VirtualMachine,
VirtualMachineOperatingSystem,
VirtualMachineProfile,
VirtualMachineMemory,
VirtualMachineNetwork,
VirtualMachineStorage,
VirtualMachineGPU)
from lib.api.base import BaseViewSet, BaseReadOnlyViewSet
class VirtualMachineViewSet(BaseViewSet):
"""
API endpoint for creating/reading/updating/deleting virtual machines.
"""
queryset = VirtualMachine.objects.all().order_by('name')
serializer_class = VirtualMachineDetailSerializer
http_method_names = ['head', 'get', 'post', 'put', 'delete']
serializer_class_by_action = {
'create': VirtualMachineSerializer,
'update': VirtualMachineSerializer,
}
def get_serializer_class(self):
if hasattr(self, 'serializer_class_by_action'):
return self.serializer_class_by_action.get(self.action, self.serializer_class)
return super().get_serializer_class()
def perform_create(self, serializer):
serializer.save(researcher=self.request.user.researcher)
def get_queryset(self):
"""
This view should return a list of all the virtual machines for the currently authenticated user ordered by name.
"""
if getattr(self, 'swagger_fake_view', False):
return self.queryset
data = self.queryset.filter(researcher=self.request.user.researcher).select_related('researcher') \
.select_related('profile') \
.select_related('operating_system') \
.select_related('base_memory_type') \
.select_related('base_storage_type') \
.select_related('additional_gpu_type') \
.select_related('additional_memory_type') \
.select_related('additional_storage_type')
if self.request.query_params.get('provider'):
data.filter(provider=self.request.query_params.get('provider'))
return data
@swagger_auto_schema(request_body=VirtualMachineSerializer(many=False), responses={200: VirtualMachineDetailSerializer(many=False)})
def create(self, request, *args, **kwargs):
virtual_machine_response = super().create(request, *args, **kwargs)
# Get the created study and reload it for different serializer
virtual_machine = get_object_or_404(VirtualMachine, pk=virtual_machine_response.data['id'])
return Response(VirtualMachineDetailSerializer(virtual_machine).data, status=virtual_machine_response.status_code)
@swagger_auto_schema(request_body=VirtualMachineSerializer(many=False), responses={200: VirtualMachineDetailSerializer(many=False)})
def update(self, request, *args, **kwargs):
virtual_machine_response = super().update(request, *args, **kwargs)
# Get the created study and reload it for different serializer
virtual_machine = get_object_or_404(VirtualMachine, pk=virtual_machine_response.data['id'])
return Response(VirtualMachineDetailSerializer(virtual_machine).data, status=virtual_machine_response.status_code)
# TODO: Figure out how to add the pagination to the schema output...
@swagger_auto_schema(responses={200: VirtualMachineProviderSerializer(many=True)})
@action(detail=False, methods=['get'])
def providers(self, request):
"""Get all the availabe providers for creating virtual machines.
Args:
request ([type]): The incoming web request
Returns:
VirtualMachineProviderSerializer: A list of zero or more study roles
"""
providers = []
for provider, provider_data in settings.CLOUD_PROVIDERS.items():
providers.append({'id': provider, 'name': provider_data['name']})
page = self.paginate_queryset(providers)
if page is not None:
serializer = VirtualMachineProviderSerializer(page, many=True)
return self.get_paginated_response(serializer.data)
serializer = VirtualMachineProviderSerializer(providers, many=True)
return Response(serializer.data)
class VirtualMachineProfileViewSet(ReadOnlyModelViewSet):
"""
API endpoint for listing virtual machines available profiles. This is a readonly endpoint.
"""
queryset = VirtualMachineProfile.objects.filter(is_available=True).order_by('name')
serializer_class = VirtualMachineProfileSerializer
def get_queryset(self):
"""
Overrule default queryset by selecting related tables at once ordered by name.
"""
return self.queryset.select_related('memory_type').select_related('storage_type').select_related('gpu_type')
class VirtualMachineProfileProviderViewSet(VirtualMachineProfileViewSet):
"""
API endpoint for listing virtual machines available profiles filtered per provider. This is a readonly endpoint.
"""
def get_queryset(self):
if self.kwargs.get('provider') is None or self.kwargs.get('provider') not in settings.CLOUD_PROVIDERS:
# Provider is not valid / loaded
raise Http404
return super().get_queryset().filter(provider=self.kwargs['provider'])
class VirtualMachineOperatingSystemViewSet(ReadOnlyModelViewSet):
"""
API endpoint for listing virtual machines available operating systems. This is a readonly endpoint.
"""
queryset = VirtualMachineOperatingSystem.objects.filter(is_available=True).order_by('name')
serializer_class = VirtualMachineOperatingSystemSerializer
class VirtualMachineOperatingSystemProviderViewSet(VirtualMachineOperatingSystemViewSet):
"""
API endpoint for listing virtual machines available operating systems filtered per provider. This is a readonly endpoint.
"""
def get_queryset(self):
if self.kwargs.get('provider') is None or self.kwargs.get('provider') not in settings.CLOUD_PROVIDERS:
# Provider is not valid / loaded
raise Http404
return super().get_queryset().filter(provider=self.kwargs['provider'])
class VirtualMachineMemoryViewSet(ReadOnlyModelViewSet):
"""
API endpoint for listing virtual machines available memory types. This is a readonly endpoint.
"""
queryset = VirtualMachineMemory.objects.filter(is_available=True).order_by('name')
serializer_class = VirtualMachineMemorySerializer
class VirtualMachineMemoryProviderViewSet(VirtualMachineMemoryViewSet):
"""
API endpoint for listing virtual machines available memory types filtered per provider. This is a readonly endpoint.
"""
def get_queryset(self):
if self.kwargs.get('provider') is None or self.kwargs.get('provider') not in settings.CLOUD_PROVIDERS:
# Provider is not valid / loaded
raise Http404
return super().get_queryset().filter(provider=self.kwargs['provider'])
class VirtualMachineNetworkViewSet(ReadOnlyModelViewSet):
"""
API endpoint for listing virtual machines available network types. This is a readonly endpoint.
"""
queryset = VirtualMachineNetwork.objects.filter(is_available=True).order_by('name')
serializer_class = VirtualMachineNetworkSerializer
class VirtualMachineNetworkProviderViewSet(VirtualMachineNetworkViewSet):
"""
API endpoint for listing virtual machines available network types filtered per provider. This is a readonly endpoint.
"""
def get_queryset(self):
if self.kwargs.get('provider') is None or self.kwargs.get('provider') not in settings.CLOUD_PROVIDERS:
# Provider is not valid / loaded
raise Http404
return super().get_queryset().filter(provider=self.kwargs['provider'])
class VirtualMachineStorageViewSet(ReadOnlyModelViewSet):
"""
API endpoint for listing virtual machines available storage types. This is a readonly endpoint.
"""
queryset = VirtualMachineStorage.objects.filter(is_available=True).order_by('name')
serializer_class = VirtualMachineStorageSerializer
class VirtualMachineStorageProviderViewSet(VirtualMachineStorageViewSet):
"""
API endpoint for listing virtual machines available storage types filtered per provider. This is a readonly endpoint.
"""
def get_queryset(self):
if self.kwargs.get('provider') is None or self.kwargs.get('provider') not in settings.CLOUD_PROVIDERS:
# Provider is not valid / loaded
raise Http404
return super().get_queryset().filter(provider=self.kwargs['provider'])
class VirtualMachineGPUViewSet(ReadOnlyModelViewSet):
"""
API endpoint for listing virtual machines available GPU types. This is a readonly endpoint.
"""
queryset = VirtualMachineGPU.objects.filter(is_available=True).order_by('name')
serializer_class = VirtualMachineGPUSerializer
class VirtualMachineGPUProviderViewSet(VirtualMachineGPUViewSet):
"""
API endpoint for listing virtual machines available GPU types filtered per provider. This is a readonly endpoint.
"""
def get_queryset(self):
if self.kwargs.get('provider') is None or self.kwargs.get('provider') not in settings.CLOUD_PROVIDERS:
# Provider is not valid / loaded
raise Http404
return super().get_queryset().filter(provider=self.kwargs['provider'])