diff --git a/src/ralph/assets/api/views.py b/src/ralph/assets/api/views.py index a1109c5df7..b0c25e25a2 100644 --- a/src/ralph/assets/api/views.py +++ b/src/ralph/assets/api/views.py @@ -1,7 +1,8 @@ # -*- coding: utf-8 -*- import django_filters from django.db.models import Prefetch -from rest_framework.exceptions import ValidationError +from rest_framework.exceptions import NotFound, ValidationError +from rest_framework.permissions import SAFE_METHODS from ralph.api import RalphAPIViewSet from ralph.api.filters import BooleanFilter @@ -10,9 +11,12 @@ from ralph.assets.api import serializers from ralph.assets.api.filters import NetworkableObjectFilters from ralph.assets.models import BaseObject +from ralph.data_center.models import Cluster, DataCenterAsset +from ralph.lib.api.utils import renderer_classes_without_form from ralph.licences.api import BaseObjectLicenceViewSet from ralph.licences.models import BaseObjectLicence from ralph.networks.models import IPAddress +from ralph.virtual.models import CloudHost, VirtualServer class BusinessSegmentViewSet(RalphAPIViewSet): @@ -258,7 +262,8 @@ class DCHostViewSet(BaseObjectViewSetMixin, RalphAPIViewSet): BaseObject.polymorphic_objects ) serializer_class = serializers.DCHostSerializer - http_method_names = ["get", "options", "head"] + renderer_classes = renderer_classes_without_form(RalphAPIViewSet.renderer_classes) + http_method_names = ["get", "options", "head", "patch", "post"] filter_fields = [ "id", "service_env", @@ -296,6 +301,28 @@ class DCHostViewSet(BaseObjectViewSetMixin, RalphAPIViewSet): } additional_filter_class = DCHostFilterSet + def get_serializer_class(self, *args, **kwargs): + if self.request.method not in SAFE_METHODS: + try: + obj_ = self.get_object() + if isinstance(obj_, VirtualServer): + from ralph.virtual.api import VirtualServerSaveSerializer + return VirtualServerSaveSerializer + elif isinstance(obj_, DataCenterAsset): + from ralph.data_center.api.serializers import DataCenterAssetSaveSerializer + return DataCenterAssetSaveSerializer + elif isinstance(obj_, CloudHost): + from ralph.virtual.api import SaveCloudHostSerializer + return SaveCloudHostSerializer + elif isinstance(obj_, Cluster): + from ralph.data_center.api.serializers import ClusterSerializer + return ClusterSerializer + else: + raise NotFound() + except AssertionError: # for some reason when opening browsable api this raises + pass + return serializers.DCHostSerializer + def get_queryset(self): return ( self.queryset.dc_hosts() diff --git a/src/ralph/assets/tests/test_api.py b/src/ralph/assets/tests/test_api.py index cb3cd229fd..b30b507be1 100644 --- a/src/ralph/assets/tests/test_api.py +++ b/src/ralph/assets/tests/test_api.py @@ -1089,6 +1089,31 @@ def test_filter_by_env_name(self): self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(response.data['count'], 1) + def test_patch_dchost_virtual_server(self): + new_hypervisor = DataCenterAssetFullFactory() + url = reverse('dchost-detail', args=(self.virtual.id,)) + data = { + 'hostname': 'new-hostname', + 'hypervisor': new_hypervisor.id, + } + response = self.client.patch(url, data, format='json') + self.assertEqual(response.status_code, status.HTTP_200_OK) + self.virtual.refresh_from_db() + self.assertEqual(self.virtual.hostname, 'new-hostname') + self.assertEqual(self.virtual.parent.id, new_hypervisor.id) + + def test_patch_dchost_cloudhost(self): + new_hypervisor = DataCenterAssetFullFactory() + url = reverse('dchost-detail', args=(self.cloud_host.id,)) + data = { + 'hostname': 'new-hostname', + 'hypervisor': new_hypervisor.id, + } + response = self.client.patch(url, data, format='json') + self.assertEqual(response.status_code, status.HTTP_200_OK) + self.cloud_host.refresh_from_db() + self.assertEqual(self.cloud_host.hostname, 'new-hostname') + self.assertEqual(self.cloud_host.hypervisor.id, new_hypervisor.id) class ConfigurationModuleAPITests(RalphAPITestCase): def setUp(self):