From 555462a99ed0739cb7ef33cb64d9ef1819d236c2 Mon Sep 17 00:00:00 2001 From: Tobias Kunze Date: Thu, 27 Mar 2025 17:44:25 +0100 Subject: [PATCH] Extract and reuse kubernetes name validator --- src/servala/core/models/organization.py | 13 ++----------- src/servala/core/models/service.py | 8 +++++++- src/servala/core/validators.py | 12 ++++++++++++ 3 files changed, 21 insertions(+), 12 deletions(-) create mode 100644 src/servala/core/validators.py diff --git a/src/servala/core/models/organization.py b/src/servala/core/models/organization.py index cc5eae7..a3c9a15 100644 --- a/src/servala/core/models/organization.py +++ b/src/servala/core/models/organization.py @@ -1,7 +1,6 @@ import rules import urlman from django.conf import settings -from django.core.validators import RegexValidator from django.db import models from django.utils.functional import cached_property from django.utils.text import slugify @@ -10,6 +9,7 @@ from django_scopes import ScopedManager, scopes_disabled from servala.core import rules as perms from servala.core.models.mixins import ServalaModelMixin +from servala.core.validators import kubernetes_name_validator class Organization(ServalaModelMixin, models.Model): @@ -21,16 +21,7 @@ class Organization(ServalaModelMixin, models.Model): help_text=_( "This namespace will be used for all Kubernetes resources. Cannot be changed after creation." ), - validators=[ - RegexValidator( - regex=r"^[a-z0-9]([-a-z0-9]*[a-z0-9])?$", - message=_( - 'Namespace must consist of lowercase alphanumeric characters or "-", ' - "must start and end with an alphanumeric character." - ), - code="invalid_namespace", - ) - ], + validators=[kubernetes_name_validator], ) billing_entity = models.ForeignKey( diff --git a/src/servala/core/models/service.py b/src/servala/core/models/service.py index 22fc83e..04a6f8f 100644 --- a/src/servala/core/models/service.py +++ b/src/servala/core/models/service.py @@ -9,6 +9,7 @@ from kubernetes import config from kubernetes.client.rest import ApiException from servala.core.models.mixins import ServalaModelMixin +from servala.core.validators import kubernetes_name_validator class ServiceCategory(ServalaModelMixin, models.Model): @@ -16,7 +17,9 @@ class ServiceCategory(ServalaModelMixin, models.Model): Categories for services, e.g. "Databases", "Storage", "Compute". """ - name = models.CharField(max_length=100, verbose_name=_("Name")) + name = models.CharField( + max_length=100, verbose_name=_("Name"), validators=[kubernetes_name_validator] + ) description = models.TextField(blank=True, verbose_name=_("Description")) logo = models.ImageField( upload_to="public/service_categories", @@ -446,3 +449,6 @@ class ServiceInstance(ServalaModelMixin, models.Model): class Meta: verbose_name = _("Service instance") verbose_name_plural = _("Service instances") + # Names are unique per de-facto namespace, which is defined by the + # Organization + ServiceDefinition (group, version) + the ControlPlane. + unique_together = [("name", "organization", "context")] diff --git a/src/servala/core/validators.py b/src/servala/core/validators.py new file mode 100644 index 0000000..1723bb5 --- /dev/null +++ b/src/servala/core/validators.py @@ -0,0 +1,12 @@ +from django.core.validators import RegexValidator +from django.utils.translation import gettext_lazy as _ + +# Kubernetes resource name validator - follows the same rules as namespace names +kubernetes_name_validator = RegexValidator( + regex=r"^[a-z0-9]([-a-z0-9]*[a-z0-9])?$", + message=_( + 'Name must consist of lowercase alphanumeric characters or "-", ' + "must start and end with an alphanumeric character." + ), + code="invalid_kubernetes_name", +)