diff --git a/src/servala/core/crd.py b/src/servala/core/crd.py index 2793d75..2c2b9fb 100644 --- a/src/servala/core/crd.py +++ b/src/servala/core/crd.py @@ -5,7 +5,6 @@ from django.core.validators import MaxValueValidator, MinValueValidator, RegexVa from django.db import models from django.forms.models import ModelForm, ModelFormMetaclass from django.utils.translation import gettext_lazy as _ -from jsonschema import validate from servala.core.models import ServiceInstance @@ -254,10 +253,14 @@ class CrdModelFormMixin: def validate_nested_data(self, data, schema): """Validate data against the provided OpenAPI v3 schema""" - try: - validate(instance=data, schema=schema) - except Exception as e: - raise forms.ValidationError(f"Validation error: {e.message}") + # TODO: actually validate the nested data. + # TODO: get jsonschema to give us a path to the failing field rather than just an error message, + # then add the validation error to that field (self.add_error()) + # try: + # validate(instance=data, schema=schema) + # except Exception as e: + # raise forms.ValidationError(f"Validation error: {e.message}") + pass def generate_model_form_class(model): diff --git a/src/servala/core/models/service.py b/src/servala/core/models/service.py index 5d34d80..9e282a6 100644 --- a/src/servala/core/models/service.py +++ b/src/servala/core/models/service.py @@ -191,6 +191,21 @@ class ControlPlane(ServalaModelMixin, models.Model): except Exception as e: return False, _("Connection error: {}").format(str(e)) + def get_or_create_namespace(self, name): + api_instance = kubernetes.client.CoreV1Api(self.get_kubernetes_client()) + try: + api_instance.read_namespace(name=name) + except kubernetes.client.ApiException as e: + if e.status == 404: + # Namespace does not exist, create it + body = kubernetes.client.V1Namespace( + metadata=kubernetes.client.V1ObjectMeta(name=name) + ) + api_instance.create_namespace(body=body) + else: + # If there's another error, raise it + raise + class CloudProvider(ServalaModelMixin, models.Model): """ @@ -465,27 +480,9 @@ class ServiceInstance(ServalaModelMixin, models.Model): base = "{self.organization.urls.instances}{self.name}/" @classmethod - def create_instance(cls, organization, context, created_by, spec_data): - name = spec_data.get("spec.name") - + def create_instance(cls, name, organization, context, created_by, spec_data): # Ensure the namespace exists - namespace_name = organization.namespace - api_instance = kubernetes.client.CoreV1Api( - context.control_plane.get_kubernetes_client() - ) - - try: - api_instance.read_namespace(name=namespace_name) - except kubernetes.client.ApiException as e: - if e.status == 404: - # Namespace does not exist, create it - body = kubernetes.client.V1Namespace( - metadata=kubernetes.client.V1ObjectMeta(name=namespace_name) - ) - api_instance.create_namespace(body=body) - else: - # If there's another error, raise it - raise + context.control_plane.get_or_create_namespace(organization.namespace) return cls.objects.create( name=name, diff --git a/src/servala/frontend/views/service.py b/src/servala/frontend/views/service.py index cfb1ff8..1803dd0 100644 --- a/src/servala/frontend/views/service.py +++ b/src/servala/frontend/views/service.py @@ -128,6 +128,7 @@ class ServiceOfferingDetailView(OrganizationViewMixin, HtmxViewMixin, DetailView try: service_instance = ServiceInstance.create_instance( organization=self.organization, + name=form.cleaned_data["name"], context=self.context_object, created_by=request.user, spec_data=form.get_nested_data(),