Compare commits

...

2 commits

Author SHA1 Message Date
da69666389 Refactor namespace handling
Some checks failed
Tests / test (push) Failing after 24s
2025-03-31 13:52:57 +02:00
70b8303fdb Defer validation 2025-03-31 13:52:44 +02:00
3 changed files with 26 additions and 25 deletions

View file

@ -5,7 +5,6 @@ from django.core.validators import MaxValueValidator, MinValueValidator, RegexVa
from django.db import models from django.db import models
from django.forms.models import ModelForm, ModelFormMetaclass from django.forms.models import ModelForm, ModelFormMetaclass
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
from jsonschema import validate
from servala.core.models import ServiceInstance from servala.core.models import ServiceInstance
@ -254,10 +253,14 @@ class CrdModelFormMixin:
def validate_nested_data(self, data, schema): def validate_nested_data(self, data, schema):
"""Validate data against the provided OpenAPI v3 schema""" """Validate data against the provided OpenAPI v3 schema"""
try: # TODO: actually validate the nested data.
validate(instance=data, schema=schema) # TODO: get jsonschema to give us a path to the failing field rather than just an error message,
except Exception as e: # then add the validation error to that field (self.add_error())
raise forms.ValidationError(f"Validation error: {e.message}") # 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): def generate_model_form_class(model):

View file

@ -191,6 +191,21 @@ class ControlPlane(ServalaModelMixin, models.Model):
except Exception as e: except Exception as e:
return False, _("Connection error: {}").format(str(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): class CloudProvider(ServalaModelMixin, models.Model):
""" """
@ -465,27 +480,9 @@ class ServiceInstance(ServalaModelMixin, models.Model):
base = "{self.organization.urls.instances}{self.name}/" base = "{self.organization.urls.instances}{self.name}/"
@classmethod @classmethod
def create_instance(cls, organization, context, created_by, spec_data): def create_instance(cls, name, organization, context, created_by, spec_data):
name = spec_data.get("spec.name")
# Ensure the namespace exists # Ensure the namespace exists
namespace_name = organization.namespace context.control_plane.get_or_create_namespace(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
return cls.objects.create( return cls.objects.create(
name=name, name=name,

View file

@ -128,6 +128,7 @@ class ServiceOfferingDetailView(OrganizationViewMixin, HtmxViewMixin, DetailView
try: try:
service_instance = ServiceInstance.create_instance( service_instance = ServiceInstance.create_instance(
organization=self.organization, organization=self.organization,
name=form.cleaned_data["name"],
context=self.context_object, context=self.context_object,
created_by=request.user, created_by=request.user,
spec_data=form.get_nested_data(), spec_data=form.get_nested_data(),