diff --git a/components/renku_data_services/platform/blueprints.py b/components/renku_data_services/platform/blueprints.py index 880432ce5..ecb452fbb 100644 --- a/components/renku_data_services/platform/blueprints.py +++ b/components/renku_data_services/platform/blueprints.py @@ -12,6 +12,7 @@ from renku_data_services.base_api.etag import extract_if_none_match, if_match_required from renku_data_services.base_models.validation import validated_json from renku_data_services.platform import apispec +from renku_data_services.platform.core import validate_platform_config_patch from renku_data_services.platform.db import PlatformRepository @@ -54,8 +55,8 @@ def patch_singleton_configuration(self) -> BlueprintFactoryResponse: async def _patch_singleton_configuration( _: Request, user: base_models.APIUser, body: apispec.PlatformConfigPatch, etag: str ) -> JSONResponse: - body_dict = body.model_dump(exclude_none=True) - config = await self.platform_repo.update_config(user=user, etag=etag, **body_dict) + platform_config_patch = validate_platform_config_patch(body) + config = await self.platform_repo.update_config(user=user, etag=etag, patch=platform_config_patch) headers = {"ETag": config.etag} return validated_json( apispec.PlatformConfig, diff --git a/components/renku_data_services/platform/core.py b/components/renku_data_services/platform/core.py new file mode 100644 index 000000000..6653bbbeb --- /dev/null +++ b/components/renku_data_services/platform/core.py @@ -0,0 +1,8 @@ +"""Business logic for the platform configuration.""" + +from renku_data_services.platform import apispec, models + + +def validate_platform_config_patch(patch: apispec.PlatformConfigPatch) -> models.PlatformConfigPatch: + """Validate the update to the platform configuration.""" + return models.PlatformConfigPatch(incident_banner=patch.incident_banner) diff --git a/components/renku_data_services/platform/db.py b/components/renku_data_services/platform/db.py index b18f1d8c3..60370bb43 100644 --- a/components/renku_data_services/platform/db.py +++ b/components/renku_data_services/platform/db.py @@ -30,7 +30,9 @@ async def get_or_create_config(self) -> models.PlatformConfig: await session.refresh(config) return config.dump() - async def update_config(self, user: base_models.APIUser, etag: str, **kwargs: dict) -> models.PlatformConfig: + async def update_config( + self, user: base_models.APIUser, etag: str, patch: models.PlatformConfigPatch + ) -> models.PlatformConfig: """Update the platform configuration.""" if user.id is None: raise errors.UnauthorizedError(message="You do not have the required permissions for this operation.") @@ -47,9 +49,8 @@ async def update_config(self, user: base_models.APIUser, etag: str, **kwargs: di if current_etag != etag: raise errors.ConflictError(message=f"Current ETag is {current_etag}, not {etag}.") - for key, value in kwargs.items(): - if key in ["incident_banner"]: - setattr(config, key, value) + if patch.incident_banner is not None: + config.incident_banner = patch.incident_banner await session.flush() await session.refresh(config) diff --git a/components/renku_data_services/platform/models.py b/components/renku_data_services/platform/models.py index aec29c60a..04a31800b 100644 --- a/components/renku_data_services/platform/models.py +++ b/components/renku_data_services/platform/models.py @@ -1,4 +1,4 @@ -"""Models for Sessions.""" +"""Models for the platform configuration.""" from dataclasses import dataclass, field from datetime import UTC, datetime @@ -26,3 +26,10 @@ class PlatformConfig: def etag(self) -> str: """Entity tag value for this project object.""" return compute_etag_from_timestamp(self.updated_at, include_quotes=True) + + +@dataclass(frozen=True, eq=True, kw_only=True) +class PlatformConfigPatch: + """Model for changes requested on the platform configuration.""" + + incident_banner: str | None = None