1
0
Fork 0
mirror of https://github.com/retspen/webvirtcloud synced 2026-11-10 20:26:48 +00:00

fix(api): host API checks what the web forms check

- An API volume takes the name and size the web form takes. Its name went
  into the volume XML unchecked, so a name could add elements such as a
  backing store pointing at another VM's disk; the name is also escaped
  there now. A size of 0 and metadata preallocation on a non-qcow2 volume
  are refused or dropped, as on the web form.
- An API compute update with an empty or null password keeps the stored
  one, as the web form does; it emptied it and cut the host off.
- The architectures endpoint answers 404 for an unknown compute instead of
  500; an unrouted copy of it is removed.
This commit is contained in:
catborise 2026-10-26 17:07:05 +03:00
parent c69c65728b
commit 726f330dd0
7 changed files with 34 additions and 21 deletions

View file

@ -20,6 +20,10 @@ class ComputeSerializer(serializers.ModelSerializer):
)
type = serializers.ChoiceField(choices=conn_types)
def validate_password(self, value):
# as on the web form, an empty password on an edit keeps the stored one
return value or (self.instance.password if self.instance else value)
class Meta:
model = Compute
fields = ["id", "name", "hostname", "login", "password", "type", "details", "migration_address"]

View file

@ -1,5 +1,6 @@
from admin.permissions import IsSuperUser
from computes.models import Compute
from django.shortcuts import get_object_or_404
from drf_spectacular.types import OpenApiTypes
from drf_spectacular.utils import extend_schema
from logs.audit import audit, changed_fields, snapshot
@ -50,7 +51,7 @@ class ComputeArchitecturesView(viewsets.ViewSet):
"""
Return a list of supported host architectures.
"""
compute = Compute.objects.get(pk=compute_pk)
compute = get_object_or_404(Compute, pk=compute_pk)
conn = wvmCreate(
compute.hostname,
compute.login,
@ -61,7 +62,7 @@ class ComputeArchitecturesView(viewsets.ViewSet):
@extend_schema(responses={200: {"type": "array", "items": {"type": "string"}}})
def retrieve(self, request, compute_pk=None, pk=None):
compute = Compute.objects.get(pk=compute_pk)
compute = get_object_or_404(Compute, pk=compute_pk)
conn = wvmCreate(
compute.hostname,
compute.login,
@ -70,19 +71,3 @@ class ComputeArchitecturesView(viewsets.ViewSet):
)
return Response(conn.get_machine_types(pk))
class ComputeMachinesView(viewsets.ViewSet):
permission_classes = [IsSuperUser]
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))