diff --git a/README.md b/README.md index e00b1ff..f917721 100644 --- a/README.md +++ b/README.md @@ -432,17 +432,6 @@ Now when you login with an LDAP user it will be assigned the rights defined. The If you'd like to move a user from ldap to WebVirtCloud, just change its password from the UI and (eventually) remove from the group in ldap - -## REST API / BETA -Webvirtcloud provides a REST API for programmatic access. -To access API methods open your browser and check them with Swagger interface -```bash -http:///swagger -``` -```bash -http:///redoc -``` - ## Screenshots Instance Detail: diff --git a/accounts/utils.py b/accounts/utils.py index 4507a54..da30c0a 100644 --- a/accounts/utils.py +++ b/accounts/utils.py @@ -30,7 +30,7 @@ def validate_ssh_key(key): username = array[2] # must have only valid rsa-ssh key characters ie binascii characters try: - data = base64.decodebytes(string) + data = base64.decodestring(string) except binascii.Error: return False # unpack the contents of data, from data[:4] , property of ssh key . diff --git a/computes/api/serializers.py b/computes/api/serializers.py deleted file mode 100644 index d7cd096..0000000 --- a/computes/api/serializers.py +++ /dev/null @@ -1,27 +0,0 @@ - -from rest_framework import serializers -from computes.models import Compute -from vrtManager.connection import ( - CONN_SOCKET, - CONN_SSH, - CONN_TCP, - CONN_TLS, -) - - -class ComputeSerializer(serializers.ModelSerializer): - # Use for the input. - password = serializers.CharField(style={'input_type': 'password'}) - # Use a radio input instead of a select input. - conn_types = ( - (CONN_SSH, 'SSH'), - (CONN_TCP, 'TCP'), - (CONN_TLS, 'TLS'), - (CONN_SOCKET, 'SOCK'), - ) - type = serializers.ChoiceField(choices=conn_types) - - - class Meta: - model = Compute - fields = ['id', 'name', 'hostname', 'login', 'password', 'type', 'details'] diff --git a/computes/api/viewsets.py b/computes/api/viewsets.py deleted file mode 100644 index c7d8acc..0000000 --- a/computes/api/viewsets.py +++ /dev/null @@ -1,58 +0,0 @@ -from computes.models import Compute -from rest_framework import viewsets -from rest_framework import permissions - -from vrtManager.create import wvmCreate -from .serializers import ComputeSerializer -from rest_framework.response import Response - - -class ComputeViewSet(viewsets.ModelViewSet): - """ - API endpoint that allows computes to be viewed or edited. - """ - queryset = Compute.objects.all().order_by('name') - serializer_class = ComputeSerializer - permission_classes = [permissions.IsAuthenticated] - - -class ComputeArchitecturesView(viewsets.ViewSet): - - def list(self, request, compute_pk=None): - """ - Return a list of supported host architectures. - """ - compute = Compute.objects.get(pk=compute_pk) - conn = wvmCreate( - compute.hostname, - compute.login, - compute.password, - compute.type, - ) - return Response(conn.get_hypervisors_machines()) - - def retrieve(self, request, compute_pk=None, pk=None): - compute = Compute.objects.get(pk=compute_pk) - conn = wvmCreate( - compute.hostname, - compute.login, - compute.password, - compute.type, - ) - return Response(conn.get_machine_types(pk)) - - -class ComputeMachinesView(viewsets.ViewSet): - - def list(self, request, compute_pk=None, archs_pk=None): - """ - Return a list of supported host architectures. - """ - compute = Compute.objects.get(pk=compute_pk) - conn = wvmCreate( - compute.hostname, - compute.login, - compute.password, - compute.type, - ) - return Response(conn.get_machine_types(archs_pk)) diff --git a/computes/urls.py b/computes/urls.py index 8938107..d69509a 100644 --- a/computes/urls.py +++ b/computes/urls.py @@ -1,6 +1,7 @@ from virtsecrets.views import secrets from django.urls import include, path +# from instances.views import create_instance, create_instance_select_type from interfaces.views import interface, interfaces from networks.views import network, networks from nwfilters.views import nwfilter, nwfilters @@ -33,6 +34,8 @@ urlpatterns = [ path('nwfilters/', nwfilters, name='nwfilters'), path('nwfilter//', nwfilter, name='nwfilter'), path('virtsecrets/', secrets, name='virtsecrets'), + # path('create/', create_instance_select_type, name='create_instance_select_type'), + # path('create/archs//machines//', create_instance, name='create_instance'), path('archs//machines/', views.get_compute_machine_types, name='machines'), path( 'archs//machines//disks//buses/', diff --git a/conf/requirements.txt b/conf/requirements.txt index d2bf6a7..04908bf 100644 --- a/conf/requirements.txt +++ b/conf/requirements.txt @@ -1,22 +1,17 @@ -Django==3.2.15 -django_bootstrap5==22.1 -django-icons==22.1 +Django==3.2.14 +django_bootstrap5==21.2 +django-icons==21.1 django-login-required-middleware==0.8 django-otp==1.1.3 django-qr-code==2.3.0 gunicorn==20.1.0 libsass==0.21.0 -libvirt-python==8.6.0 +libvirt-python==8.5.0 lxml==4.9.1 qrcode==7.3.1 rwlock==0.0.7 websockify==0.10.0 zipp==3.6.0 ldap3==2.9.1 -python-engineio==4.3.4 -python-socketio==5.7.1 -eventlet==0.33.1 -djangorestframework==3.13.1 -drf-nested-routers==0.93.4 -drf-yasg==1.21.3 -markdown==3.4.1 +python-socketio==5.7.0 +eventlet==0.33.1 \ No newline at end of file diff --git a/console/novncd b/console/novncd index 59ff686..4d3f94b 100755 --- a/console/novncd +++ b/console/novncd @@ -112,7 +112,7 @@ def get_connection_infos(token): connport = 22 connuser = instance.compute.login conntype = instance.compute.type - console_host = conn.get_console_listener_addr() + console_host = conn.get_console_listen_addr() console_port = conn.get_console_port() console_socket = conn.get_console_socket() except Exception as e: diff --git a/dev/requirements.txt b/dev/requirements.txt index 0e8ec79..3e8a789 100644 --- a/dev/requirements.txt +++ b/dev/requirements.txt @@ -1,7 +1,7 @@ -r ../conf/requirements.txt -coverage==6.4.4 -django-debug-toolbar==3.6.0 -pycodestyle==2.9.1 -pyflakes==2.5.0 -pylint==2.14.5 +coverage==6.2 +django-debug-toolbar==3.2.4 +pycodestyle==2.8.0 +pyflakes==2.4.0 +pylint==2.13.9 yapf==0.32.0 diff --git a/instances/api/serializers.py b/instances/api/serializers.py deleted file mode 100644 index 7e0c0d9..0000000 --- a/instances/api/serializers.py +++ /dev/null @@ -1,100 +0,0 @@ -from rest_framework import serializers - -from instances.models import Flavor, Instance, MigrateInstance, CreateInstance - - -class InstanceSerializer(serializers.ModelSerializer): - - class Meta: - model = Instance - fields = ['id', 'compute', 'name', 'uuid', 'is_template', 'created', 'drbd'] - - -class InstanceDetailsSerializer(serializers.ModelSerializer): - - class Meta: - model = Instance - fields = [ - 'id', - 'compute', - 'status', - 'uuid', - 'name', - 'title', - 'description', - 'is_template', - 'created', - 'drbd', - 'arch', - 'machine', - 'vcpu', - 'memory', - 'firmware', - 'nvram', - 'bootmenu', - 'boot_order', - 'disks', - 'media', - 'media_iso', - 'snapshots', - 'networks', - 'console_type', - 'console_port', - 'console_keymap', - 'console_listener_address', - 'video_model', - 'guest_agent_ready', - 'autostart'] - - -class FlavorSerializer(serializers.ModelSerializer): - - class Meta: - model = Flavor - fields = ['label', 'memory', 'vcpu', 'disk'] - - -class CreateInstanceSerializer(serializers.ModelSerializer): - firmware_choices = ( - ('', 'BIOS'), - #('UEFI', 'UEFI'), - ) - firmware = serializers.ChoiceField(choices = firmware_choices) - graphics = serializers.CharField(initial='vnc') - video = serializers.CharField(initial='vga') - storage = serializers.CharField(initial='default') - cache_mode = serializers.CharField(initial='none') - virtio = serializers.BooleanField(initial=True) - qemu_ga = serializers.BooleanField(initial=True) - - class Meta: - model = CreateInstance - fields = [ - 'name', - 'firmware', - 'vcpu', - 'vcpu_mode', - 'memory', - 'networks', - 'mac', - 'nwfilter', - 'storage', - 'hdd_size', - 'cache_mode', - 'meta_prealloc', - 'virtio', - 'qemu_ga', - 'console_pass', - 'graphics', - 'video', - 'listener_addr' - ] - - -class MigrateSerializer(serializers.ModelSerializer): - instance = Instance.objects.all().prefetch_related("userinstance_set") - live = serializers.BooleanField(initial=True) - xml_del = serializers.BooleanField(initial=True) - class Meta: - model = MigrateInstance - fields = ['instance', 'target_compute', 'live', 'xml_del', 'offline', 'autoconverge', 'compress', 'postcopy', 'unsafe'] diff --git a/instances/api/viewsets.py b/instances/api/viewsets.py deleted file mode 100644 index 4960f07..0000000 --- a/instances/api/viewsets.py +++ /dev/null @@ -1,224 +0,0 @@ -from django.shortcuts import get_object_or_404 -from appsettings.settings import app_settings -from computes.models import Compute -from computes import utils -from instances.models import Flavor, Instance -from instances.views import get_instance -from instances.utils import migrate_instance -from instances.views import poweron, powercycle, poweroff, force_off, suspend, resume, destroy as instance_destroy - -from rest_framework import status, viewsets, permissions -from rest_framework.decorators import action -from rest_framework.response import Response - -from vrtManager import util - -from vrtManager.create import wvmCreate -from .serializers import FlavorSerializer, InstanceSerializer, InstanceDetailsSerializer, MigrateSerializer, CreateInstanceSerializer - -class InstancesViewSet(viewsets.ViewSet): - """ - A simple ViewSet for listing or retrieving ALL/Compute Instances. - """ - permission_classes = [permissions.IsAuthenticated] - def list(self, request): - - if request.user.is_superuser or request.user.has_perm("instances.view_instances"): - queryset = Instance.objects.all().prefetch_related("userinstance_set") - else: - queryset = Instance.objects.filter(userinstance__user=request.user).prefetch_related("userinstance_set") - serializer = InstanceSerializer(queryset, many=True, context={'request': request}) - - return Response(serializer.data) - - def retrieve(self, request, pk=None, compute_pk=None): - queryset = get_instance(request.user, pk) - serializer = InstanceSerializer(queryset, context={'request': request}) - - return Response(serializer.data) - - -class InstanceViewSet(viewsets.ViewSet): - """ - A simple ViewSet for listing or retrieving Compute Instances. - """ - #serializer_class = CreateInstanceSerializer - permission_classes = [permissions.IsAuthenticated] - def list(self, request, compute_pk=None): - compute = get_object_or_404(Compute, pk=compute_pk) - - utils.refresh_instance_database(compute) - - queryset = Instance.objects.filter(compute=compute).prefetch_related("userinstance_set") - serializer = InstanceSerializer(queryset, many=True, context={'request': request}) - - return Response(serializer.data) - - - def retrieve(self, request, pk=None, compute_pk=None): - queryset = get_instance(request.user, pk) - serializer = InstanceDetailsSerializer(queryset, context={'request': request}) - - return Response(serializer.data) - - - def destroy(self, request, pk=None, compute_pk=None): - instance_destroy(request, pk) - return Response({'status': 'Instance is destroyed'}) - - @action(detail=True, methods=['post']) - def poweron(self, request, pk=None): - poweron(request, pk) - return Response({'status': 'poweron command send'}) - - @action(detail=True, methods=['post']) - def poweroff(self, request, pk=None): - poweroff(request, pk) - return Response({'status': 'poweroff command send'}) - - @action(detail=True, methods=['post']) - def powercycle(self, request, pk=None): - powercycle(request, pk) - return Response({'status': 'powercycle command send'}) - - @action(detail=True, methods=['post']) - def forceoff(self, request, pk=None): - force_off(request, pk) - return Response({'status': 'force off command send'}) - - @action(detail=True, methods=['post']) - def suspend(self, request, pk=None): - suspend(request, pk) - return Response({'status': 'suspend command send'}) - - @action(detail=True, methods=['post']) - def resume(self, request, pk=None): - resume(request, pk) - return Response({'status': 'resume command send'}) - - -class MigrateViewSet(viewsets.ViewSet): - """ - A viewset for migrating instances. - """ - serializer_class = MigrateSerializer - queryset = "" - - def create(self, request): - serializer = MigrateSerializer(data=request.data) - if serializer.is_valid(): - 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: - return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) - - - -class FlavorViewSet(viewsets.ModelViewSet): - """ - API endpoint that allows flavor to be viewed. - """ - queryset = Flavor.objects.all().order_by('id') - serializer_class = FlavorSerializer - permission_classes = [permissions.IsAuthenticated] - - -class CreateInstanceViewSet(viewsets.ViewSet): - """ - A viewset for creating instances. - """ - serializer_class = CreateInstanceSerializer - queryset = "" - - def create(self, request, compute_pk=None, arch=None, machine=None): - 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 - 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( - 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) - - if "UEFI" in serializer.validated_data['firmware']: - 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( - serializer.validated_data['name'], - serializer.validated_data['memory'], - serializer.validated_data['vcpu'], - serializer.validated_data['vcpu_mode'], - util.randomUUID(), - arch, - machine, - firmware, - volume_list, - serializer.validated_data['networks'], - serializer.validated_data['nwfilter'], - serializer.validated_data['graphics'], - serializer.validated_data['virtio'], - serializer.validated_data['listener_addr'], - serializer.validated_data['video'], - serializer.validated_data['console_pass'], - serializer.validated_data['mac'], - serializer.validated_data['qemu_ga'], - ) - msg = f"Instance {serializer.validated_data['name']} is created" - return Response({'status': msg }) - else: - return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) \ No newline at end of file diff --git a/instances/forms.py b/instances/forms.py index 14e0a9f..77433ba 100644 --- a/instances/forms.py +++ b/instances/forms.py @@ -4,9 +4,9 @@ from django import forms from django.utils.translation import gettext_lazy as _ from appsettings.models import AppSettings -from webvirtcloud.settings import QEMU_CONSOLE_LISTENER_ADDRESSES, QEMU_KEYMAPS +from webvirtcloud.settings import QEMU_CONSOLE_LISTEN_ADDRESSES, QEMU_KEYMAPS -from .models import CreateInstance, Flavor +from .models import Flavor class FlavorForm(forms.ModelForm): @@ -29,36 +29,32 @@ class ConsoleForm(forms.Form): type_choices = ((c, c) for c in AppSettings.objects.get(key="QEMU_CONSOLE_DEFAULT_TYPE").choices_as_list()) keymap_choices = [('auto', 'Auto')] + list((c, c) for c in QEMU_KEYMAPS) self.fields['type'] = forms.ChoiceField(choices=type_choices) - self.fields['listen_on'] = forms.ChoiceField(choices=QEMU_CONSOLE_LISTENER_ADDRESSES) + self.fields['listen_on'] = forms.ChoiceField(choices=QEMU_CONSOLE_LISTEN_ADDRESSES) self.fields['keymap'] = forms.ChoiceField(choices=keymap_choices) -class NewVMForm(forms.ModelForm): - # name = forms.CharField(error_messages={'required': _('No Virtual Machine name has been entered')}, max_length=64) - # firmware = forms.CharField(max_length=50, required=False) - # vcpu = forms.IntegerField(error_messages={'required': _('No VCPU has been entered')}) - # vcpu_mode = forms.CharField(max_length=20, required=False) - # disk = forms.IntegerField(required=False) - # memory = forms.IntegerField(error_messages={'required': _('No RAM size has been entered')}) - # networks = forms.CharField(error_messages={'required': _('No Network pool has been choosen')}) - # nwfilter = forms.CharField(required=False) - # storage = forms.CharField(max_length=20, required=False) - # template = forms.CharField(required=False) - # images = forms.CharField(required=False) - # cache_mode = forms.CharField(error_messages={'required': _('Please select HDD cache mode')}) - # hdd_size = forms.IntegerField(required=False) - # meta_prealloc = forms.BooleanField(required=False) - # virtio = forms.BooleanField(required=False) - # qemu_ga = forms.BooleanField(required=False) - # mac = forms.CharField(required=False) - # console_pass = forms.CharField(required=False, empty_value="", widget=forms.PasswordInput()) - # graphics = forms.CharField(error_messages={'required': _('Please select a graphics type')}) - # video = forms.CharField(error_messages={'required': _('Please select a video driver')}) - # listener_addr = forms.ChoiceField(required=True, widget=forms.RadioSelect, choices=QEMU_CONSOLE_LISTENER_ADDRESSES) - class Meta: - model = CreateInstance - fields = '__all__' - exclude = ['compute'] +class NewVMForm(forms.Form): + name = forms.CharField(error_messages={'required': _('No Virtual Machine name has been entered')}, max_length=64) + firmware = forms.CharField(max_length=50, required=False) + vcpu = forms.IntegerField(error_messages={'required': _('No VCPU has been entered')}) + vcpu_mode = forms.CharField(max_length=20, required=False) + disk = forms.IntegerField(required=False) + memory = forms.IntegerField(error_messages={'required': _('No RAM size has been entered')}) + networks = forms.CharField(error_messages={'required': _('No Network pool has been choosen')}) + nwfilter = forms.CharField(required=False) + storage = forms.CharField(max_length=20, required=False) + template = forms.CharField(required=False) + images = forms.CharField(required=False) + cache_mode = forms.CharField(error_messages={'required': _('Please select HDD cache mode')}) + hdd_size = forms.IntegerField(required=False) + meta_prealloc = forms.BooleanField(required=False) + virtio = forms.BooleanField(required=False) + qemu_ga = forms.BooleanField(required=False) + mac = forms.CharField(required=False) + console_pass = forms.CharField(required=False, empty_value="", widget=forms.PasswordInput()) + graphics = forms.CharField(error_messages={'required': _('Please select a graphics type')}) + video = forms.CharField(error_messages={'required': _('Please select a video driver')}) + listener_addr = forms.ChoiceField(required=True, widget=forms.RadioSelect, choices=QEMU_CONSOLE_LISTEN_ADDRESSES) def clean_name(self): name = self.cleaned_data['name'] diff --git a/instances/migrations/0010_auto_20220722_0812.py b/instances/migrations/0010_auto_20220722_0812.py deleted file mode 100644 index 6eb70f6..0000000 --- a/instances/migrations/0010_auto_20220722_0812.py +++ /dev/null @@ -1,22 +0,0 @@ -# Generated by Django 3.2.14 on 2022-07-22 08:12 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('instances', '0009_auto_20200717_0524'), - ] - - operations = [ - migrations.AlterModelOptions( - name='permissionset', - options={'default_permissions': (), 'managed': False, 'permissions': [('clone_instances', 'Can clone instances'), ('passwordless_console', 'Can access console without password'), ('view_instances', 'Can view instances'), ('snapshot_instances', 'Can snapshot instances')]}, - ), - migrations.AddField( - model_name='instance', - name='drbd', - field=models.CharField(default='None', max_length=24, verbose_name='drbd'), - ), - ] diff --git a/instances/models.py b/instances/models.py index cc15873..147b099 100644 --- a/instances/models.py +++ b/instances/models.py @@ -1,10 +1,7 @@ from django.db import models from django.utils.functional import cached_property from django.utils.translation import gettext_lazy as _ - from libvirt import VIR_DOMAIN_XML_SECURE -from vrtManager.create import wvmCreate -from webvirtcloud.settings import QEMU_CONSOLE_LISTENER_ADDRESSES from computes.models import Compute from vrtManager.instance import wvmInstance @@ -153,8 +150,8 @@ class Instance(models.Model): return self.proxy.get_console_keymap() @cached_property - def console_listener_address(self): - return self.proxy.get_console_listener_addr() + def console_listen_address(self): + return self.proxy.get_console_listen_addr() @cached_property def guest_agent(self): @@ -209,50 +206,6 @@ class Instance(models.Model): return self.proxy.get_image_formats() -class MigrateInstance(models.Model): - instance = models.ForeignKey(Instance, on_delete=models.DO_NOTHING) - target_compute = models.ForeignKey(Compute, related_name='target', on_delete=models.DO_NOTHING) - - live = models.BooleanField(_('Live'), blank=False) - xml_del = models.BooleanField(_('Undefine XML'), blank=False, default=True) - offline = models.BooleanField(_('Offline'), blank=False) - autoconverge = models.BooleanField(_('Auto Converge'), blank=False, default=True) - compress = models.BooleanField(_('Compress'), blank=False, default=False) - postcopy = models.BooleanField(_('Post Copy'), blank=False, default=False) - unsafe = models.BooleanField(_('Unsafe'), blank=False, default=False) - - class Meta: - managed = False - - -class CreateInstance(models.Model): - compute = models.ForeignKey(Compute, related_name='host', on_delete=models.DO_NOTHING) - name = models.CharField(max_length=64, error_messages={'required': _('No Virtual Machine name has been entered')}) - firmware = models.CharField(max_length=50) - vcpu = models.IntegerField(error_messages={'required': _('No VCPU has been entered')}) - vcpu_mode = models.CharField(max_length=20, blank=True) - disk = models.IntegerField(blank=True) - memory = models.IntegerField(error_messages={'required': _('No RAM size has been entered')}) - networks = models.CharField(max_length=256, error_messages={'required': _('No Network pool has been choosen')}) - nwfilter = models.CharField(max_length=256, blank=True) - storage = models.CharField(max_length=256, blank=True) - template = models.CharField(max_length=256, blank=True) - images = models.CharField(max_length=256, blank=True) - cache_mode = models.CharField(max_length=12, error_messages={'required': _('Please select HDD cache mode')}) - hdd_size = models.IntegerField(blank=True) - meta_prealloc = models.BooleanField(default=False, blank=True) - virtio = models.BooleanField(default=True) - qemu_ga = models.BooleanField(default=False) - mac = models.CharField(max_length=17, blank=True) - console_pass = models.CharField(max_length=64, blank=True) - graphics = models.CharField(max_length=12, error_messages={'required': _('Please select a graphics type')}) - video = models.CharField(max_length=12, error_messages={'required': _('Please select a video driver')}) - listener_addr = models.CharField(max_length=20, choices=QEMU_CONSOLE_LISTENER_ADDRESSES) - - class Meta: - managed = False - - class PermissionSet(models.Model): """ Dummy model for holding set of permissions we need to be automatically added by Django diff --git a/instances/templates/allinstances_index_grouped.html b/instances/templates/allinstances_index_grouped.html index 5d270d4..bdeda51 100644 --- a/instances/templates/allinstances_index_grouped.html +++ b/instances/templates/allinstances_index_grouped.html @@ -30,9 +30,9 @@ {% trans "Connected" %} - {% if app_settings.VM_DRBD_STATUS == 'True' %} - - {% endif %} + {% if app_settings.VM_DRBD_STATUS == 'True' %} + + {% endif %} {{ compute.cpu_count }} {{ compute.ram_size|filesizeformat }} @@ -68,11 +68,11 @@ {% trans "Suspended" %} {% endif %} - {% if app_settings.VM_DRBD_STATUS == 'True' %} - - {% if instance.drbd == "Primary/OK" or instance.drbd == "Secondary/OK" %}{% else %}{% endif %}{{ instance.drbd }} - - {% endif %} + {% if app_settings.VM_DRBD_STATUS == 'True' %} + + {% if instance.drbd == "Primary/OK" or instance.drbd == "Secondary/OK" %}{% else %}{% endif %}{{ instance.drbd }} + + {% endif %} {{ instance.proxy.instance.info.3 }} {{ instance.cur_memory }} MB diff --git a/instances/templates/create_instance_w1.html b/instances/templates/create_instance_w1.html index 93a915d..b655201 100644 --- a/instances/templates/create_instance_w1.html +++ b/instances/templates/create_instance_w1.html @@ -15,7 +15,7 @@ {% for field in form %} {% for error in field.errors %}
- {{ field.label }}: {{ error|escape }} + {{ error|escape }}
{% endfor %} {% endfor %} diff --git a/instances/templates/create_instance_w2.html b/instances/templates/create_instance_w2.html index 9c38670..499dd3e 100644 --- a/instances/templates/create_instance_w2.html +++ b/instances/templates/create_instance_w2.html @@ -19,7 +19,7 @@ {% for field in form %} {% for error in field.errors %}
- {{ field.label }}: {{ error|escape }} + {{ error|escape }}
{% endfor %} {% endfor %} diff --git a/instances/templates/instance.html b/instances/templates/instance.html index e602431..cb18556 100644 --- a/instances/templates/instance.html +++ b/instances/templates/instance.html @@ -269,9 +269,9 @@ }); $(document).ready(function () { // set current console listen address or fall back to default - var console_listener_address = "{{ console_listener_address }}"; - if (console_listener_address != '') { - $("#console_select_listener_address option[value='" + console_listener_address + "']").prop('selected', true); + var console_listen_address = "{{ console_listen_address }}"; + if (console_listen_address != '') { + $("#console_select_listen_address option[value='" + console_listen_address + "']").prop('selected', true); } }); $(document).ready(function () { diff --git a/instances/views.py b/instances/views.py index ca998e3..449fc7b 100644 --- a/instances/views.py +++ b/instances/views.py @@ -67,12 +67,12 @@ def instance(request, pk): console_form = ConsoleForm( initial={ "type": instance.console_type, - "listen_on": instance.console_listener_address, + "listen_on": instance.console_listen_address, "password": instance.console_passwd, "keymap": instance.console_keymap, } ) - console_listener_addresses = settings.QEMU_CONSOLE_LISTENER_ADDRESSES + console_listen_addresses = settings.QEMU_CONSOLE_LISTEN_ADDRESSES bottom_bar = app_settings.VIEW_INSTANCE_DETAIL_BOTTOM_BAR allow_admin_or_not_template = request.user.is_superuser or request.user.is_staff or not instance.is_template try: @@ -344,7 +344,7 @@ def destroy(request, pk): except Exception: userinstance = UserInstance(is_delete=request.user.is_superuser) - if request.method in ["POST", "DELETE"] and userinstance.is_delete: + if request.method == "POST" and userinstance.is_delete: if instance.proxy.get_status() == 1: instance.proxy.force_shutdown() @@ -390,7 +390,7 @@ def migrate(request, pk): target_host = Compute.objects.get(id=compute_id) try: - utils.migrate_instance(target_host, instance, request.user, live, unsafe, xml_del, offline, autoconverge, compress, postcopy) + utils.migrate_instance(target_host, instance, request.user, live, unsafe, xml_del, offline) except libvirtError as err: messages.error(request, err) @@ -1239,7 +1239,7 @@ def update_console(request, pk): addlogmsg(request.user.username, instance.compute.name, instance.name, msg) if "listen_on" in form.changed_data: - instance.proxy.set_console_listener_addr(form.cleaned_data["listen_on"]) + instance.proxy.set_console_listen_addr(form.cleaned_data["listen_on"]) msg = _("Set VNC listen address") addlogmsg(request.user.username, instance.compute.name, instance.name, msg) @@ -1385,7 +1385,7 @@ def create_instance(request, compute_id, arch, machine): default_disk_owner_uid = int(app_settings.INSTANCE_VOLUME_DEFAULT_OWNER_UID) default_disk_owner_gid = int(app_settings.INSTANCE_VOLUME_DEFAULT_OWNER_GID) default_scsi_disk_model = app_settings.INSTANCE_VOLUME_DEFAULT_SCSI_CONTROLLER - listener_addr = settings.QEMU_CONSOLE_LISTENER_ADDRESSES + listener_addr = settings.QEMU_CONSOLE_LISTEN_ADDRESSES mac_auto = util.randomMAC() disk_devices = conn.get_disk_device_types(arch, machine) disk_buses = conn.get_disk_bus_types(arch, machine) @@ -1545,7 +1545,7 @@ def create_instance(request, compute_id, arch, machine): volumes=volume_list, networks=data["networks"], virtio=data["virtio"], - listener_addr=data["listener_addr"], + listen_addr=data["listener_addr"], nwfilter=data["nwfilter"], graphics=data["graphics"], video=data["video"], @@ -1568,7 +1568,6 @@ def create_instance(request, compute_id, arch, machine): conn.close() except libvirtError as lib_err: messages.error(request, lib_err) - return render(request, "create_instance_w2.html", locals()) diff --git a/interfaces/api/serializers.py b/interfaces/api/serializers.py deleted file mode 100644 index e9a7bea..0000000 --- a/interfaces/api/serializers.py +++ /dev/null @@ -1,11 +0,0 @@ - -from rest_framework import serializers -from interfaces.models import Interfaces - - -class InterfacesSerializer(serializers.ModelSerializer): - - class Meta: - model = Interfaces - fields = ['name', 'type', 'state', 'mac'] - diff --git a/interfaces/api/viewsets.py b/interfaces/api/viewsets.py deleted file mode 100644 index 1b7a6e7..0000000 --- a/interfaces/api/viewsets.py +++ /dev/null @@ -1,32 +0,0 @@ -from django.shortcuts import get_object_or_404 -from computes.models import Compute -from rest_framework import status, viewsets - - -from vrtManager.interface import wvmInterfaces, wvmInterface - -from .serializers import InterfacesSerializer -from rest_framework.response import Response - - - -class InterfaceViewSet(viewsets.ViewSet): - """ - A viewset for listing retrieving interfaces. - """ - - def list(self, request, compute_pk=None): - queryset = [] - compute = get_object_or_404(Compute, pk=compute_pk) - - conn = wvmInterfaces(compute.hostname, compute.login, compute.password, compute.type) - ifaces = conn.get_ifaces() - - for iface in ifaces: - interf = wvmInterface(compute.hostname, compute.login, compute.password, compute.type, iface) - queryset.append(interf.get_details()) - - serializer = InterfacesSerializer(queryset, many=True, context={'request': request}) - - return Response(serializer.data) - diff --git a/interfaces/models.py b/interfaces/models.py index c2834e8..71a8362 100644 --- a/interfaces/models.py +++ b/interfaces/models.py @@ -1,13 +1,3 @@ from django.db import models -from django.utils.translation import gettext_lazy as _ - # Create your models here. -class Interfaces(models.Model): - name = models.CharField(_('name'), max_length=20, error_messages={'required': _('No interface name has been entered')}) - type = models.CharField(_('status'), max_length=12) - state = models.CharField(_('device'), max_length=100) - mac = models.CharField(_('forward'), max_length=24) - - class Meta: - managed = False diff --git a/networks/api/serializers.py b/networks/api/serializers.py deleted file mode 100644 index 8b26298..0000000 --- a/networks/api/serializers.py +++ /dev/null @@ -1,19 +0,0 @@ - -from rest_framework import serializers -from networks.models import Networks - - -class NetworksSerializer(serializers.ModelSerializer): - - class Meta: - model = Networks - fields = ['name', 'status', 'device', 'forward'] - - - -# class VolumeSerializer(serializers.ModelSerializer): -# allocation = serializers.ReadOnlyField() -# meta_prealloc = serializers.BooleanField(write_only=True) -# class Meta: -# model = Volume -# fields = ['name', 'type', 'allocation', 'size', 'meta_prealloc'] diff --git a/networks/api/viewsets.py b/networks/api/viewsets.py deleted file mode 100644 index 892511d..0000000 --- a/networks/api/viewsets.py +++ /dev/null @@ -1,26 +0,0 @@ -from django.shortcuts import get_object_or_404 -from computes.models import Compute -from rest_framework import status, viewsets - -from vrtManager.network import wvmNetworks - -from .serializers import NetworksSerializer -from rest_framework.response import Response - - -class NetworkViewSet(viewsets.ViewSet): - """ - A viewset for listing retrieving networks. - """ - - def list(self, request, compute_pk=None): - - compute = get_object_or_404(Compute, pk=compute_pk) - - conn = wvmNetworks(compute.hostname, compute.login, compute.password, compute.type) - queryset = conn.get_networks_info() - - serializer = NetworksSerializer(queryset, many=True, context={'request': request}) - - return Response(serializer.data) - diff --git a/networks/models.py b/networks/models.py index c52ceff..71a8362 100644 --- a/networks/models.py +++ b/networks/models.py @@ -1,13 +1,3 @@ from django.db import models -from django.utils.translation import gettext_lazy as _ - # Create your models here. -class Networks(models.Model): - name = models.CharField(_('name'), max_length=20, error_messages={'required': _('No network name has been entered')}) - status = models.CharField(_('status'), max_length=12) - device = models.CharField(_('device'), max_length=100) - forward = models.CharField(_('forward'), max_length=24) - - class Meta: - managed = False diff --git a/storages/api/serializers.py b/storages/api/serializers.py deleted file mode 100644 index 2584616..0000000 --- a/storages/api/serializers.py +++ /dev/null @@ -1,25 +0,0 @@ - -from rest_framework import serializers -from storages.models import Storages, Storage, Volume - - -class StoragesSerializer(serializers.ModelSerializer): - - class Meta: - model = Storages - fields = ['name', 'status', 'type', 'size', 'volumes'] - - -class StorageSerializer(serializers.ModelSerializer): - volumes = serializers.ReadOnlyField() - class Meta: - model = Storage - fields = ['state', 'size', 'free', 'status', 'path', 'type', 'autostart', 'volumes'] - - -class VolumeSerializer(serializers.ModelSerializer): - allocation = serializers.ReadOnlyField() - meta_prealloc = serializers.BooleanField(write_only=True) - class Meta: - model = Volume - fields = ['name', 'type', 'allocation', 'size', 'meta_prealloc'] diff --git a/storages/api/viewsets.py b/storages/api/viewsets.py deleted file mode 100644 index 023aaf9..0000000 --- a/storages/api/viewsets.py +++ /dev/null @@ -1,162 +0,0 @@ -from django.shortcuts import get_object_or_404 -from computes.models import Compute -from rest_framework import status, viewsets -from rest_framework.decorators import action -from appsettings.settings import app_settings - -from vrtManager.storage import wvmStorages, wvmStorage - -from .serializers import StoragesSerializer, StorageSerializer, VolumeSerializer -from rest_framework.response import Response - - - -class StorageViewSet(viewsets.ViewSet): - """ - A viewset for listing retrieving storages. - """ - - def list(self, request, compute_pk=None): - - compute = get_object_or_404(Compute, pk=compute_pk) - - conn = wvmStorages(compute.hostname, compute.login, compute.password, compute.type) - queryset = conn.get_storages_info() - - serializer = StoragesSerializer(queryset, many=True, context={'request': request}) - - return Response(serializer.data) - - def retrieve(self, request, pk=None, compute_pk=None): - compute = get_object_or_404(Compute, pk=compute_pk) - - conn = wvmStorage(compute.hostname, compute.login, compute.password, compute.type, pk) - - infoset = { - "state": conn.is_active(), - "size": conn.get_size()[0], - "free": conn.get_size()[1], - "status": conn.get_status(), - "path": conn.get_target_path(), - "type": conn.get_type(), - "autostart": conn.get_autostart(), - "volumes": conn.update_volumes() - } - - serializer = StorageSerializer(infoset, many=False, context={'request': request}) - return Response(serializer.data) - - - @action(detail=True, methods=['post']) - def start(self, request, pk=None, compute_pk=None): - compute = get_object_or_404(Compute, pk=compute_pk) - - conn = wvmStorage(compute.hostname, compute.login, compute.password, compute.type, pk) - ret = conn.start() - conn.close() - return Response({'status': 'Pool start command send: ' + str(ret)}) - - @action(detail=True, methods=['post']) - def stop(self, request, pk=None, compute_pk=None): - compute = get_object_or_404(Compute, pk=compute_pk) - - conn = wvmStorage(compute.hostname, compute.login, compute.password, compute.type, pk) - ret = conn.stop() - conn.close() - return Response({'status': 'Pool stop command send: ' + str(ret)}) - - @action(detail=True, methods=['post']) - def refresh(self, request, pk=None, compute_pk=None): - compute = get_object_or_404(Compute, pk=compute_pk) - - conn = wvmStorage(compute.hostname, compute.login, compute.password, compute.type, pk) - ret = conn.refresh() - conn.close() - return Response({'status': 'Pool refresh command send: ' + str(ret)}) - - @action(detail=True, methods=['post']) - def XML_description(self, request, pk=None, compute_pk=None): - compute = get_object_or_404(Compute, pk=compute_pk) - - conn = wvmStorage(compute.hostname, compute.login, compute.password, compute.type, pk) - ret = conn._XMLDesc(0) - conn.close() - return Response({'return': str(ret)}) - - -class VolumeViewSet(viewsets.ViewSet): - - """ - A simple ViewSet for listing or retrieving Storage Volumes. - """ - serializer_class = VolumeSerializer - lookup_value_regex = "[^/]+" - - def list(self, request, storage_pk=None, compute_pk=None): - - compute = get_object_or_404(Compute, pk=compute_pk) - - conn = wvmStorage(compute.hostname, compute.login, compute.password, compute.type, storage_pk) - state = conn.is_active() - - if state: - conn.refresh() - volume_queryset = conn.update_volumes() - else: - volume_queryset = None - conn.close() - serializer = VolumeSerializer(volume_queryset, many=True, context={'request': request}) - - return Response(serializer.data) - - def retrieve(self, request, storage_pk=None, compute_pk=None, pk=None): - compute = get_object_or_404(Compute, pk=compute_pk) - - conn = wvmStorage(compute.hostname, compute.login, compute.password, compute.type, storage_pk) - state = conn.is_active() - - if state: - volume_queryset = conn.get_volume_details(pk) - else: - volume_queryset = None - conn.close() - serializer = VolumeSerializer(volume_queryset, many=False, context={'request': request}) - - return Response(serializer.data) - - def create(self, request, storage_pk=None, compute_pk=None): - compute = get_object_or_404(Compute, pk=compute_pk) - - conn = wvmStorage(compute.hostname, compute.login, compute.password, compute.type, storage_pk) - - serializer = VolumeSerializer(data=request.data) - if serializer.is_valid(): - state = conn.is_active() - if state: - conn.refresh() - ret = conn.create_volume( - serializer.validated_data['name'], - serializer.validated_data['size'], - serializer.validated_data['type'], - serializer.validated_data['meta_prealloc'], - int(app_settings.INSTANCE_VOLUME_DEFAULT_OWNER_UID), - int(app_settings.INSTANCE_VOLUME_DEFAULT_OWNER_GID), - ) - conn.close() - return Response({'status': 'Volume: ' + ret + ' is created'}) - else: - return Response({'status': 'Pool is not active'}) - else: - return Response({'status': 'Data is not right for create volume'}) - - def destroy(self, request, storage_pk=None, compute_pk=None, pk=None): - compute = get_object_or_404(Compute, pk=compute_pk) - - conn = wvmStorage(compute.hostname, compute.login, compute.password, compute.type, storage_pk) - - if conn.is_active(): - conn.del_volume(pk) - conn.close() - return Response({'status': 'Volume: ' + pk + ' is deleted'}) - else: - return Response({'status': 'Pool is not active'}) diff --git a/storages/models.py b/storages/models.py index 0af474b..71a8362 100644 --- a/storages/models.py +++ b/storages/models.py @@ -1,47 +1,3 @@ from django.db import models -from django.utils.translation import gettext_lazy as _ # Create your models here. -class Storages(models.Model): - name = models.CharField(_('name'), max_length=20, error_messages={'required': _('No pool name has been entered')}) - status = models.IntegerField(_('status')) - type = models.CharField(_('type'), max_length=100) - size = models.IntegerField(_('size')) - volumes = models.IntegerField(_('volumes')) - - def __str__(self): - return f'{self.name}' - - class Meta: - managed = False - - -class Volume(models.Model): - name = models.CharField(_('name'), max_length=128) - type = models.CharField(_('format'), max_length=12, choices=(('qcow2', 'qcow2 (recommended)'), ('qcow', 'qcow'), ('raw', 'raw'))) - allocation = models.IntegerField(_('allocation')) - size = models.IntegerField(_('size')) - - def __str__(self): - return f'{self.name}' - - class Meta: - managed = False - verbose_name_plural = "Volumes" - - -class Storage(models.Model): - state = models.IntegerField(_('state')) - size = models.IntegerField(_('size')) - free = models.IntegerField(_('free')) - status = models.CharField(_('status'), max_length=128) - path = models.CharField(_('path'), max_length=128) - type = models.CharField(_('type'), max_length=128) - autostart = models.BooleanField(_('autostart')) - volumes = models.ForeignKey(Volume, on_delete=models.DO_NOTHING) - - def __str__(self): - return f'{self.path}' - - class Meta: - managed = False diff --git a/vrtManager/create.py b/vrtManager/create.py index 0044fe0..99ec7e7 100644 --- a/vrtManager/create.py +++ b/vrtManager/create.py @@ -45,7 +45,7 @@ class wvmCreate(wvmConnect): return util.get_xml_path(self.get_cap_xml(), "/capabilities/guest/os_type") def get_host_arch(self): - """Get host architecture""" + """Get guest capabilities""" return util.get_xml_path(self.get_cap_xml(), "/capabilities/host/cpu/arch") def create_volume(self, storage, name, size, image_format, metadata=False, disk_owner_uid=0, disk_owner_gid=0): @@ -160,7 +160,7 @@ class wvmCreate(wvmConnect): nwfilter, graphics, virtio, - listener_addr, + listen_addr, video="vga", console_pass="random", mac=None, @@ -332,7 +332,7 @@ class wvmCreate(wvmConnect): xml += """""" xml += f""" - + """ if qemu_ga and virtio: @@ -345,4 +345,4 @@ class wvmCreate(wvmConnect): """ - return self._defineXML(xml) + self._defineXML(xml) diff --git a/vrtManager/instance.py b/vrtManager/instance.py index b2a8dd2..8212aab 100644 --- a/vrtManager/instance.py +++ b/vrtManager/instance.py @@ -130,12 +130,12 @@ class wvmInstances(wvmConnect): def graphics_listen(self, name): inst = self.get_instance(name) - listener_addr = util.get_xml_path(inst.XMLDesc(0), "/domain/devices/graphics/@listen") - if listener_addr is None: - listener_addr = util.get_xml_path(inst.XMLDesc(0), "/domain/devices/graphics/listen/@address") - if listener_addr is None: + listen_addr = util.get_xml_path(inst.XMLDesc(0), "/domain/devices/graphics/@listen") + if listen_addr is None: + listen_addr = util.get_xml_path(inst.XMLDesc(0), "/domain/devices/graphics/listen/@address") + if listen_addr is None: return "None" - return listener_addr + return listen_addr def graphics_port(self, name): inst = self.get_instance(name) @@ -253,9 +253,6 @@ class wvmInstance(wvmConnect): else: return self.get_vcpu() - def get_vcpu_mode(self): - return util.get_xml_path(self._XMLDesc(0), "/domain/cpu/@current") - def get_arch(self): return util.get_xml_path(self._XMLDesc(0), "/domain/os/type/@arch") @@ -982,15 +979,15 @@ class wvmInstance(wvmConnect): telnet_port = service_port return telnet_port - def get_console_listener_addr(self): - listener_addr = util.get_xml_path(self._XMLDesc(0), "/domain/devices/graphics/@listen") - if listener_addr is None: - listener_addr = util.get_xml_path(self._XMLDesc(0), "/domain/devices/graphics/listen/@address") - if listener_addr is None: + def get_console_listen_addr(self): + listen_addr = util.get_xml_path(self._XMLDesc(0), "/domain/devices/graphics/@listen") + if listen_addr is None: + listen_addr = util.get_xml_path(self._XMLDesc(0), "/domain/devices/graphics/listen/@address") + if listen_addr is None: return "127.0.0.1" - return listener_addr + return listen_addr - def set_console_listener_addr(self, listener_addr): + def set_console_listen_addr(self, listen_addr): xml = self._XMLDesc(VIR_DOMAIN_XML_SECURE) root = ElementTree.fromstring(xml) console_type = self.get_console_type() @@ -1004,9 +1001,9 @@ class wvmInstance(wvmConnect): listen = graphic.find("listen[@type='address']") if listen is None: return False - if listener_addr: - graphic.set("listen", listener_addr) - listen.set("address", listener_addr) + if listen_addr: + graphic.set("listen", listen_addr) + listen.set("address", listen_addr) else: try: graphic.attrib.pop("listen") diff --git a/vrtManager/network.py b/vrtManager/network.py index ee93d91..45467f8 100644 --- a/vrtManager/network.py +++ b/vrtManager/network.py @@ -40,12 +40,7 @@ class wvmNetworks(wvmConnect): net_bridge = util.get_xml_path(net.XMLDesc(0), "/network/forward/interface/@dev") net_forward = util.get_xml_path(net.XMLDesc(0), "/network/forward/@mode") - networks.append({ - "name": network, - "status": net_status, - "device": net_bridge, - "forward": net_forward - }) + networks.append({"name": network, "status": net_status, "device": net_bridge, "forward": net_forward}) return networks diff --git a/vrtManager/storage.py b/vrtManager/storage.py index 64f303d..d2346ce 100644 --- a/vrtManager/storage.py +++ b/vrtManager/storage.py @@ -124,10 +124,10 @@ class wvmStorage(wvmConnect): return self.pool.UUIDString() def start(self): - return self.pool.create(0) + self.pool.create(0) def stop(self): - return self.pool.destroy() + self.pool.destroy() def delete(self): self.pool.undefine() @@ -224,27 +224,7 @@ class wvmStorage(wvmConnect): return util.get_xml_path(vol_xml, "/volume/@type") def refresh(self): - return self.pool.refresh(0) - - def get_volume_details(self, volname): - with contextlib.suppress(Exception): - self.refresh() - - vols = self.get_volumes() - return [{"name": volname, - "size": self.get_volume_size(volname), - "allocation": self.get_volume_allocation(volname), - "type": self.get_volume_format_type(volname)} for volname in vols] - - def get_volume_details(self, volname): - with contextlib.suppress(Exception): - self.refresh() - return { - "name": volname, - "size": self.get_volume_size(volname), - "allocation": self.get_volume_allocation(volname), - "type": self.get_volume_format_type(volname), - } + self.pool.refresh(0) def update_volumes(self): with contextlib.suppress(Exception): diff --git a/webvirtcloud/settings.py.template b/webvirtcloud/settings.py.template index 17156e1..9d050d8 100644 --- a/webvirtcloud/settings.py.template +++ b/webvirtcloud/settings.py.template @@ -26,7 +26,6 @@ INSTALLED_APPS = [ "django_icons", "django_otp", "django_otp.plugins.otp_totp", - "drf_yasg", "accounts", "admin", "appsettings", @@ -41,7 +40,6 @@ INSTALLED_APPS = [ "virtsecrets", "logs", "qr_code", - "rest_framework", ] MIDDLEWARE = [ @@ -213,7 +211,7 @@ SOCKETIO_PUBLIC_PORT = 6081 SOCKETIO_PUBLIC_PATH = "socket.io/" # List of console listen addresses -QEMU_CONSOLE_LISTENER_ADDRESSES = ( +QEMU_CONSOLE_LISTEN_ADDRESSES = ( ("127.0.0.1", "Localhost"), ("0.0.0.0", "All interfaces"), ) diff --git a/webvirtcloud/urls-api.py b/webvirtcloud/urls-api.py deleted file mode 100644 index 40dab63..0000000 --- a/webvirtcloud/urls-api.py +++ /dev/null @@ -1,37 +0,0 @@ -from django.urls import include, path -from rest_framework_nested import routers - -from computes.api.viewsets import ComputeArchitecturesView, ComputeViewSet -from networks.api.viewsets import NetworkViewSet -from interfaces.api.viewsets import InterfaceViewSet -from storages.api.viewsets import StorageViewSet, VolumeViewSet -from instances.api.viewsets import FlavorViewSet, \ - InstancesViewSet, \ - InstanceViewSet, \ - MigrateViewSet, \ - CreateInstanceViewSet - - -router = routers.SimpleRouter() -router.register(r'computes', ComputeViewSet) -router.register(r'migrate', MigrateViewSet, basename='instance-migrate') -router.register(r'flavor', FlavorViewSet, basename='instance-flavor') -router.register(r'instances', InstancesViewSet, basename='instance') - -compute_router = routers.NestedSimpleRouter(router, r'computes', lookup='compute') -compute_router.register(r'instances', InstanceViewSet, basename='compute-instance') -compute_router.register(r'instances/create/(?P[^/.]+)/(?P[^/.]+)', CreateInstanceViewSet, basename='instance-create') -compute_router.register(r'networks', NetworkViewSet, basename='compute-network') -compute_router.register(r'interfaces', InterfaceViewSet, basename='compute-interface') -compute_router.register(r'storages', StorageViewSet, basename='compute-storage') -compute_router.register(r'archs', ComputeArchitecturesView, basename='compute-archs') - -storage_router = routers.NestedSimpleRouter(compute_router, r'storages', lookup='storage') -storage_router.register(r'volumes', VolumeViewSet, basename='compute-storage-volumes') - - -urlpatterns = [ - path('', include(router.urls)), - path('', include(compute_router.urls)), - path('', include(storage_router.urls)), -] diff --git a/webvirtcloud/urls.py b/webvirtcloud/urls.py index 81000e3..42785ac 100644 --- a/webvirtcloud/urls.py +++ b/webvirtcloud/urls.py @@ -1,26 +1,9 @@ -from django.conf import settings -from django.urls import include, path, re_path -from rest_framework import permissions -from drf_yasg.views import get_schema_view -from drf_yasg import openapi from appsettings.views import appsettings from console.views import console +from django.conf import settings +from django.urls import include, path from instances.views import index - -schema_view = get_schema_view( - openapi.Info( - title="Webvirtcloud REST-API", - default_version='v1', - description="Webvirtcloud REST API", - terms_of_service="https://www.google.com/policies/terms/", - contact=openapi.Contact(email="catborise@gmail.com"), - license=openapi.License(name="BSD License"), - ), - public=True, - permission_classes=(permissions.AllowAny,), -) - urlpatterns = [ path("", index, name="index"), path("admin/", include(("admin.urls", "admin"), namespace="admin")), @@ -32,11 +15,6 @@ urlpatterns = [ path("instances/", include("instances.urls")), path("i18n/", include("django.conf.urls.i18n")), path("logs/", include("logs.urls")), - path('api-auth/', include('rest_framework.urls', namespace='rest_framework')), - path('api/v1/', include("webvirtcloud.urls-api")), - re_path(r'^swagger(?P\.json|\.yaml)$', schema_view.without_ui(cache_timeout=0), name='schema-json'), - re_path(r'^swagger/$', schema_view.with_ui('swagger', cache_timeout=0), name='schema-swagger-ui'), - re_path(r'^redoc/$', schema_view.with_ui('redoc', cache_timeout=0), name='schema-redoc'), ] if settings.DEBUG: @@ -48,4 +26,3 @@ if settings.DEBUG: ] except ImportError: pass -