Move field validation to model, for API compatibility
This commit is contained in:
parent
8a8745f1fd
commit
0eb01457f4
2 changed files with 37 additions and 21 deletions
|
@ -1,5 +1,4 @@
|
|||
from django import forms
|
||||
from django.core.exceptions import ValidationError
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
from servala.core.models import ControlPlane
|
||||
|
@ -40,35 +39,31 @@ class ControlPlaneAdminForm(forms.ModelForm):
|
|||
def clean(self):
|
||||
cleaned_data = super().clean()
|
||||
|
||||
# Get the three credential fields
|
||||
ca_data = cleaned_data.get("certificate_authority_data")
|
||||
server = cleaned_data.get("server")
|
||||
token = cleaned_data.get("token")
|
||||
|
||||
# Check if any of the fields are filled
|
||||
has_ca = bool(ca_data)
|
||||
has_server = bool(server)
|
||||
has_token = bool(token)
|
||||
|
||||
# If some but not all fields are filled, raise validation error
|
||||
if (has_ca or has_server or has_token) and not (
|
||||
has_ca and has_server and has_token
|
||||
):
|
||||
raise ValidationError(
|
||||
_(
|
||||
"All credential fields (certificate authority data, server, and token) must be provided together or left empty."
|
||||
)
|
||||
)
|
||||
|
||||
# If all fields are filled, create the api_credentials JSON
|
||||
if has_ca and has_server and has_token:
|
||||
if ca_data and server and token:
|
||||
cleaned_data["api_credentials"] = {
|
||||
"certificate-authority-data": ca_data,
|
||||
"server": server,
|
||||
"token": token,
|
||||
}
|
||||
else:
|
||||
cleaned_data["api_credentials"] = {}
|
||||
if not (ca_data or server or token):
|
||||
cleaned_data["api_credentials"] = {}
|
||||
else:
|
||||
# Some fields are filled but not all - validation will fail at model level,
|
||||
# as model field validators are also called by the API.
|
||||
# We still create the JSON with whatever we have so the model validator can run.
|
||||
credentials = {}
|
||||
if ca_data:
|
||||
credentials["certificate-authority-data"] = ca_data
|
||||
if server:
|
||||
credentials["server"] = server
|
||||
if token:
|
||||
credentials["token"] = token
|
||||
cleaned_data["api_credentials"] = credentials
|
||||
|
||||
return cleaned_data
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
from django.core.exceptions import ValidationError
|
||||
from django.db import models
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from encrypted_fields.fields import EncryptedJSONField
|
||||
|
@ -63,14 +64,34 @@ class Service(models.Model):
|
|||
return self.name
|
||||
|
||||
|
||||
def validate_api_credentials(value):
|
||||
"""
|
||||
Validates that api_credentials either contains all required fields or is empty.
|
||||
"""
|
||||
# If empty dict, that's valid
|
||||
if not value:
|
||||
return
|
||||
|
||||
# Check for required fields
|
||||
required_fields = ("certificate-authority-data", "server", "token")
|
||||
missing_fields = required_fields - set(value)
|
||||
|
||||
if missing_fields:
|
||||
raise ValidationError(
|
||||
_("Missing required fields in API credentials: %(fields)s"),
|
||||
params={"fields": ", ".join(missing_fields)},
|
||||
)
|
||||
|
||||
|
||||
class ControlPlane(models.Model):
|
||||
name = models.CharField(max_length=100, verbose_name=_("Name"))
|
||||
description = models.TextField(blank=True, verbose_name=_("Description"))
|
||||
k8s_api_endpoint = models.URLField(verbose_name=_("Kubernetes API endpoint"))
|
||||
# TODO: schema
|
||||
# Either contains the fields "certificate_authority_data", "server" and "token", or is empty
|
||||
api_credentials = EncryptedJSONField(
|
||||
verbose_name=_("API credentials"),
|
||||
help_text="Required fields: certificate-authority-data, server (URL), token",
|
||||
validators=[validate_api_credentials],
|
||||
)
|
||||
|
||||
cloud_provider = models.ForeignKey(
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue