From f65e6e0de0c10615c282c7bab2f14d4fc937bff2 Mon Sep 17 00:00:00 2001 From: Tobias Kunze Date: Tue, 20 May 2025 22:24:18 +0200 Subject: [PATCH] Implement model updates --- src/servala/core/models/service.py | 48 ++++++++++++++++++++++++++++-- 1 file changed, 45 insertions(+), 3 deletions(-) diff --git a/src/servala/core/models/service.py b/src/servala/core/models/service.py index c38cac0..dab18db 100644 --- a/src/servala/core/models/service.py +++ b/src/servala/core/models/service.py @@ -188,6 +188,10 @@ class ControlPlane(ServalaModelMixin, models.Model): def get_kubernetes_client(self): return kubernetes.client.ApiClient(self.kubernetes_config) + @cached_property + def custom_objects_api(self): + return client.CustomObjectsApi(self.get_kubernetes_client()) + def test_connection(self): if not self.api_credentials: return False, _("No API credentials provided") @@ -540,9 +544,7 @@ class ServiceInstance(ServalaModelMixin, models.Model): } if label := context.control_plane.required_label: create_data["metadata"]["labels"] = {settings.DEFAULT_LABEL_KEY: label} - api_instance = client.CustomObjectsApi( - context.control_plane.get_kubernetes_client() - ) + api_instance = context.control_plane.custom_objects_api api_instance.create_namespaced_custom_object( group=context.group, version=context.version, @@ -562,6 +564,46 @@ class ServiceInstance(ServalaModelMixin, models.Model): raise ValidationError(_("Error creating instance: {}").format(str(e))) return instance + def update_spec(self, spec_data, updated_by): + try: + api_instance = self.context.control_plane.custom_objects_api + patch_body = {"spec": spec_data} + + api_instance.patch_namespaced_custom_object( + group=self.context.group, + version=self.context.version, + namespace=self.organization.namespace, + plural=self.context.kind_plural, + name=self.name, + body=patch_body, + ) + self._clear_kubernetes_caches() + except ApiException as e: + if e.status == 404: + raise ValidationError( + _( + "Service instance not found in Kubernetes. It may have been deleted externally." + ) + ) + try: + error_body = json.loads(e.body) + reason = error_body.get("message", str(e)) + raise ValidationError( + _("Kubernetes API error updating instance: {error}").format( + error=reason + ) + ) + except (ValueError, TypeError): + raise ValidationError( + _("Kubernetes API error updating instance: {error}").format( + error=str(e) + ) + ) + except Exception as e: + raise ValidationError( + _("Error updating instance: {error}").format(error=str(e)) + ) + @cached_property def kubernetes_object(self): """Fetch the Kubernetes custom resource object"""