From d417783bd4955a27c3f1c51d1432aa3e6f227504 Mon Sep 17 00:00:00 2001 From: Tasko Olevski Date: Wed, 10 Jul 2024 17:15:08 +0200 Subject: [PATCH 1/3] feat: update and expand apispec for environments --- Makefile | 4 +- .../renku_data_services/session/api.spec.yaml | 257 ++++++++++++------ .../renku_data_services/session/apispec.py | 211 +++++++------- 3 files changed, 297 insertions(+), 175 deletions(-) diff --git a/Makefile b/Makefile index 20331e859..c1e96c3d6 100644 --- a/Makefile +++ b/Makefile @@ -31,7 +31,7 @@ components/renku_data_services/connected_services/apispec.py: components/renku_d components/renku_data_services/repositories/apispec.py: components/renku_data_services/repositories/api.spec.yaml poetry run datamodel-codegen --input components/renku_data_services/repositories/api.spec.yaml --input-file-type openapi --output-model-type pydantic_v2.BaseModel --output components/renku_data_services/repositories/apispec.py --use-double-quotes --target-python-version 3.12 --collapse-root-models --field-constraints --strict-nullable --base-class renku_data_services.repositories.apispec_base.BaseAPISpec -schemas: components/renku_data_services/crc/apispec.py components/renku_data_services/storage/apispec.py components/renku_data_services/users/apispec.py components/renku_data_services/project/apispec.py components/renku_data_services/user_preferences/apispec.py components/renku_data_services/namespace/apispec.py components/renku_data_services/secrets/apispec.py components/renku_data_services/connected_services/apispec.py components/renku_data_services/repositories/apispec.py +schemas: components/renku_data_services/crc/apispec.py components/renku_data_services/storage/apispec.py components/renku_data_services/users/apispec.py components/renku_data_services/project/apispec.py components/renku_data_services/user_preferences/apispec.py components/renku_data_services/namespace/apispec.py components/renku_data_services/secrets/apispec.py components/renku_data_services/connected_services/apispec.py components/renku_data_services/repositories/apispec.py components/renku_data_services/session/apispec.py @echo "generated classes based on ApiSpec" download_avro: @@ -68,6 +68,8 @@ style_checks: @$(call test_apispec_up_to_date,"connected_services") @echo "checking repositories apispec is up to date" @$(call test_apispec_up_to_date,"repositories") + @echo "checking session apispec is up to date" + @$(call test_apispec_up_to_date,"session") poetry run mypy poetry run ruff format --check poetry run ruff check . diff --git a/components/renku_data_services/session/api.spec.yaml b/components/renku_data_services/session/api.spec.yaml index 0ef09676b..9885e22a5 100644 --- a/components/renku_data_services/session/api.spec.yaml +++ b/components/renku_data_services/session/api.spec.yaml @@ -221,32 +221,6 @@ paths: $ref: "#/components/responses/Error" tags: - session_launchers - /session_launchers/{launcher_id}/start: - post: - summary: Use a session launcher to start a session - parameters: - - in: path - name: launcher_id - required: true - schema: - type: string - requestBody: - required: true - content: - application/json: - schema: - $ref: "#/components/schemas/SessionStart" - responses: - "201": - description: The started session - content: - application/json: - schema: - $ref: "#/components/schemas/Session" - default: - $ref: "#/components/responses/Error" - tags: - - sessions /projects/{project_id}/session_launchers: get: summary: Get a project's session launchers @@ -290,11 +264,37 @@ components: $ref: "#/components/schemas/ContainerImage" default_url: $ref: "#/components/schemas/DefaultUrl" + owner_type: + $ref: "#/components/schemas/EnvironmentOwnerType" + owner_id: + $ref: "#/components/schemas/EnvironmentOwnerId" + uid: + $ref: "#/components/schemas/EnvironmentUid" + gid: + $ref: "#/components/schemas/EnvironmentGid" + working_directory: + $ref: "#/components/schemas/EnvironmentWorkingDirectory" + mount_directory: + $ref: "#/components/schemas/EnvironmentMountDirectory" + port: + $ref: "#/components/schemas/EnvironmentPort" + visibility: + $ref: "#/components/schemas/EnvironmentVisibility" required: - id - name - creation_date - container_image + - official + - port + - working_directory + - mount_directory + - uid + - gid + - default_url + - owner_type + - owner_id + - visibility example: id: 01AN4Z79ZS6XX96588FDX0H099 name: JupyterLab environment @@ -302,7 +302,15 @@ components: description: JupyterLab session environment container_image: renku-jupyter:latest default_url: "/lab" - EnvironmentPost: + port: 8080 + working_directory: /home/jovyan/work + mount_directory: /home/jovyan/work + uid: 1000 + gid: 1000 + owner_type: user + ownerId: 4fcd155c-fef5-48de-87f7-2facab8bf4c2 + visibility: private + EnvironmentPostInLauncher: description: Data required to create a session environment type: object properties: @@ -313,11 +321,49 @@ components: container_image: $ref: "#/components/schemas/ContainerImage" default_url: - $ref: "#/components/schemas/DefaultUrl" + allOf: + - $ref: "#/components/schemas/DefaultUrl" + - default: /lab + uid: + allOf: + - $ref: "#/components/schemas/EnvironmentUid" + - default: 1000 + gid: + allOf: + - $ref: "#/components/schemas/EnvironmentGid" + - default: 1000 + working_directory: + allOf: + - $ref: "#/components/schemas/EnvironmentWorkingDirectory" + - default: /home/jovyan/work + mount_directory: + allOf: + - $ref: "#/components/schemas/EnvironmentMountDirectory" + - default: /home/jovyan/work + port: + allOf: + - $ref: "#/components/schemas/EnvironmentPort" + - default: 8080 + visibility: + allOf: + - $ref: "#/components/schemas/EnvironmentVisibility" + - default: private required: - name - container_image - EnvironmentPatch: + EnvironmentPost: + allOf: + - $ref: "#/components/schemas/EnvironmentPostInLauncher" + - type: object + properties: + owner_id: + $ref: "#/components/schemas/EnvironmentOwnerId" + owner_type: + $ref: "#/components/schemas/EnvironmentOwnerType" + required: + - owner_id + - owner_type + EnvironmentPatchInLauncher: type: object description: Update a session environment additionalProperties: false @@ -330,6 +376,25 @@ components: $ref: "#/components/schemas/ContainerImage" default_url: $ref: "#/components/schemas/DefaultUrl" + uid: + $ref: "#/components/schemas/EnvironmentUid" + gid: + $ref: "#/components/schemas/EnvironmentGid" + working_directory: + $ref: "#/components/schemas/EnvironmentWorkingDirectory" + mount_directory: + $ref: "#/components/schemas/EnvironmentMountDirectory" + port: + $ref: "#/components/schemas/EnvironmentPort" + EnvironmentPatch: + allOf: + - $ref: "#/components/schemas/EnvironmentPatchInLauncher" + - type: object + properties: + owner_id: + $ref: "#/components/schemas/EnvironmentOwnerId" + owner_type: + $ref: "#/components/schemas/EnvironmentOwnerType" SessionLaunchersList: description: A list of Renku session launchers type: array @@ -350,30 +415,35 @@ components: $ref: "#/components/schemas/CreationDate" description: $ref: "#/components/schemas/Description" - environment_kind: - $ref: "#/components/schemas/EnvironmentKind" - environment_id: - $ref: "#/components/schemas/EnvironmentId" - resource_class_id: - $ref: "#/components/schemas/ResourceClassId" - container_image: - $ref: "#/components/schemas/ContainerImage" - default_url: - $ref: "#/components/schemas/DefaultUrl" + environment: + $ref: "#/components/schemas/Environment" required: - id - project_id - name - creation_date - - environment_kind + - environment example: id: 01AN4Z79ZS5XN0F25N3DB94T4R project_id: 01AN4Z79ZS5XN0F25N3DB94T4R name: Renku R Session creation_date: "2023-11-01T17:32:28Z" description: R compute session - environment_kind: global_environment - environment_id: 01AN4Z79ZS6XX96588FDX0H099 + environment: + id: 01AN4Z79ZS6XX96588FDX0H099 + name: Rstudio + creation_date: "2023-11-01T17:32:28Z" + description: JupyterLab session environment + container_image: rocker/rstudio + default_url: "/rstudio" + port: 8080 + working_directory: /home/rstudio/work + mount_directory: /home/rstudio/work + uid: 1000 + gid: 1000 + owner_type: project + ownerId: 01AN4Z79ZS5XN0F25N3DB94T4R + visibility: private SessionLauncherPost: description: Data required to create a session launcher type: object @@ -385,20 +455,16 @@ components: $ref: "#/components/schemas/Ulid" description: $ref: "#/components/schemas/Description" - environment_kind: - $ref: "#/components/schemas/EnvironmentKind" - environment_id: - $ref: "#/components/schemas/EnvironmentId" resource_class_id: $ref: "#/components/schemas/ResourceClassId" - container_image: - $ref: "#/components/schemas/ContainerImage" - default_url: - $ref: "#/components/schemas/DefaultUrl" + environment: + oneOf: + - $ref: "#/components/schemas/EnvironmentPostInLauncher" + - $ref: "#/components/schemas/EnvironmentIdOnlyPost" required: - name - project_id - - environment_kind + - environment SessionLauncherPatch: type: object description: Update a session launcher @@ -408,23 +474,12 @@ components: $ref: "#/components/schemas/SessionName" description: $ref: "#/components/schemas/Description" - environment_kind: - $ref: "#/components/schemas/EnvironmentKind" - environment_id: - $ref: "#/components/schemas/EnvironmentId" - resource_class_id: - $ref: "#/components/schemas/ResourceClassId" - container_image: - $ref: "#/components/schemas/ContainerImage" - default_url: - $ref: "#/components/schemas/DefaultUrl" - SessionStart: - type: object - description: Start a session - additionalProperties: true - properties: resource_class_id: $ref: "#/components/schemas/ResourceClassId" + environment: + oneOf: + - $ref: "#/components/schemas/EnvironmentPatchInLauncher" + - $ref: "#/components/schemas/EnvironmentIdOnlyPatch" Ulid: description: ULID identifier type: string @@ -437,13 +492,18 @@ components: minLength: 1 maxLength: 99 example: My Renku Session :) - EnvironmentKind: - description: Kind of environment to use - type: string - enum: - - global_environment - - container_image - example: container_image + EnvironmentIdOnlyPatch: + type: object + properties: + id: + $ref: "#/components/schemas/EnvironmentId" + EnvironmentIdOnlyPost: + type: object + properties: + id: + $ref: "#/components/schemas/EnvironmentId" + required: + - id EnvironmentId: description: Id of the environment to use type: string @@ -473,15 +533,48 @@ components: type: integer default: null nullable: true - Session: - description: A Renku session - type: object - additionalProperties: true - properties: - name: - $ref: "#/components/schemas/SessionName" - url: - type: string + EnvironmentPort: + type: integer + minimum: 0 + exclusiveMinimum: true + maximum: 65535 + description: The TCP port (on any container in the session) where user requests will be routed to from the ingress + EnvironmentUid: + type: integer + minimum: 0 + exclusiveMinimum: true + maximum: 65535 + description: The user ID used to run the session + EnvironmentGid: + type: integer + minimum: 0 + exclusiveMinimum: true + maximum: 65535 + description: The group ID used to run the session + EnvironmentWorkingDirectory: + type: string + description: The location where the session will start + minLength: 1 + EnvironmentMountDirectory: + type: string + description: The location where the persistent storage for the session will be mounted, usually it should be identical to or a parent of the working directory + minLength: 1 + EnvironmentOwnerType: + type: string + enum: + - user + - group + - project + - platform + description: The owner of the environment which is used to enforce authorization on it + EnvironmentOwnerId: + type: string + description: The id of the entity that owns the environment + EnvironmentVisibility: + type: string + enum: + - public + - private ErrorResponse: type: object properties: diff --git a/components/renku_data_services/session/apispec.py b/components/renku_data_services/session/apispec.py index 6be545731..23de693d3 100644 --- a/components/renku_data_services/session/apispec.py +++ b/components/renku_data_services/session/apispec.py @@ -1,34 +1,27 @@ # generated by datamodel-codegen: # filename: api.spec.yaml -# timestamp: 2024-06-10T13:14:40+00:00 +# timestamp: 2024-07-10T15:10:10+00:00 from __future__ import annotations from datetime import datetime from enum import Enum -from typing import List, Optional +from typing import List, Optional, Union from pydantic import ConfigDict, Field, RootModel from renku_data_services.session.apispec_base import BaseAPISpec -class EnvironmentKind(Enum): - global_environment = "global_environment" - container_image = "container_image" +class EnvironmentOwnerType(Enum): + user = "user" + group = "group" + project = "project" + platform = "platform" -class Session(BaseAPISpec): - model_config = ConfigDict( - extra="allow", - ) - name: Optional[str] = Field( - None, - description="Renku session name", - example="My Renku Session :)", - max_length=99, - min_length=1, - ) - url: Optional[str] = None +class EnvironmentVisibility(Enum): + public = "public" + private = "private" class Error(BaseAPISpec): @@ -72,15 +65,40 @@ class Environment(BaseAPISpec): example="renku/renkulab-py:3.10-0.18.1", max_length=500, ) - default_url: Optional[str] = Field( - None, + default_url: str = Field( + ..., description="The default path to open in a session", example="/lab", max_length=200, ) + owner_type: EnvironmentOwnerType + owner_id: str = Field( + ..., description="The id of the entity that owns the environment" + ) + uid: int = Field( + ..., description="The user ID used to run the session", gt=0, le=65535 + ) + gid: int = Field( + ..., description="The group ID used to run the session", gt=0, le=65535 + ) + working_directory: str = Field( + ..., description="The location where the session will start", min_length=1 + ) + mount_directory: str = Field( + ..., + description="The location where the persistent storage for the session will be mounted, usually it should be identical to or a parent of the working directory", + min_length=1, + ) + port: int = Field( + ..., + description="The TCP port (on any container in the session) where user requests will be routed to from the ingress", + gt=0, + le=65535, + ) + visibility: EnvironmentVisibility -class EnvironmentPost(BaseAPISpec): +class EnvironmentPostInLauncher(BaseAPISpec): name: str = Field( ..., description="Renku session name", @@ -103,9 +121,37 @@ class EnvironmentPost(BaseAPISpec): example="/lab", max_length=200, ) + uid: Optional[int] = Field( + None, description="The user ID used to run the session", gt=0, le=65535 + ) + gid: Optional[int] = Field( + None, description="The group ID used to run the session", gt=0, le=65535 + ) + working_directory: Optional[str] = Field( + None, description="The location where the session will start", min_length=1 + ) + mount_directory: Optional[str] = Field( + None, + description="The location where the persistent storage for the session will be mounted, usually it should be identical to or a parent of the working directory", + min_length=1, + ) + port: Optional[int] = Field( + None, + description="The TCP port (on any container in the session) where user requests will be routed to from the ingress", + gt=0, + le=65535, + ) + visibility: Optional[EnvironmentVisibility] = None + + +class EnvironmentPost(EnvironmentPostInLauncher): + owner_id: str = Field( + ..., description="The id of the entity that owns the environment" + ) + owner_type: EnvironmentOwnerType -class EnvironmentPatch(BaseAPISpec): +class EnvironmentPatchInLauncher(BaseAPISpec): model_config = ConfigDict( extra="forbid", ) @@ -131,6 +177,33 @@ class EnvironmentPatch(BaseAPISpec): example="/lab", max_length=200, ) + uid: Optional[int] = Field( + None, description="The user ID used to run the session", gt=0, le=65535 + ) + gid: Optional[int] = Field( + None, description="The group ID used to run the session", gt=0, le=65535 + ) + working_directory: Optional[str] = Field( + None, description="The location where the session will start", min_length=1 + ) + mount_directory: Optional[str] = Field( + None, + description="The location where the persistent storage for the session will be mounted, usually it should be identical to or a parent of the working directory", + min_length=1, + ) + port: Optional[int] = Field( + None, + description="The TCP port (on any container in the session) where user requests will be routed to from the ingress", + gt=0, + le=65535, + ) + + +class EnvironmentPatch(EnvironmentPatchInLauncher): + owner_id: Optional[str] = Field( + None, description="The id of the entity that owns the environment" + ) + owner_type: Optional[EnvironmentOwnerType] = None class SessionLauncher(BaseAPISpec): @@ -163,27 +236,34 @@ class SessionLauncher(BaseAPISpec): description: Optional[str] = Field( None, description="A description for the resource", max_length=500 ) - environment_kind: EnvironmentKind - environment_id: Optional[str] = Field( + environment: Environment + + +class EnvironmentIdOnlyPatch(BaseAPISpec): + id: Optional[str] = Field( None, description="Id of the environment to use", example="01AN4Z79ZS6XX96588FDX0H099", min_length=1, ) - resource_class_id: Optional[int] = Field( - None, description="The identifier of a resource class" - ) - container_image: Optional[str] = Field( - None, - description="A container image", - example="renku/renkulab-py:3.10-0.18.1", - max_length=500, + + +class EnvironmentIdOnlyPost(BaseAPISpec): + id: str = Field( + ..., + description="Id of the environment to use", + example="01AN4Z79ZS6XX96588FDX0H099", + min_length=1, ) - default_url: Optional[str] = Field( - None, - description="The default path to open in a session", - example="/lab", - max_length=200, + + +class EnvironmentList(RootModel[List[Environment]]): + root: List[Environment] = Field(..., description="A list of session environments") + + +class SessionLaunchersList(RootModel[List[SessionLauncher]]): + root: List[SessionLauncher] = Field( + ..., description="A list of Renku session launchers", min_length=0 ) @@ -208,28 +288,10 @@ class SessionLauncherPost(BaseAPISpec): description: Optional[str] = Field( None, description="A description for the resource", max_length=500 ) - environment_kind: EnvironmentKind - environment_id: Optional[str] = Field( - None, - description="Id of the environment to use", - example="01AN4Z79ZS6XX96588FDX0H099", - min_length=1, - ) resource_class_id: Optional[int] = Field( None, description="The identifier of a resource class" ) - container_image: Optional[str] = Field( - None, - description="A container image", - example="renku/renkulab-py:3.10-0.18.1", - max_length=500, - ) - default_url: Optional[str] = Field( - None, - description="The default path to open in a session", - example="/lab", - max_length=200, - ) + environment: Union[EnvironmentPostInLauncher, EnvironmentIdOnlyPost] class SessionLauncherPatch(BaseAPISpec): @@ -246,44 +308,9 @@ class SessionLauncherPatch(BaseAPISpec): description: Optional[str] = Field( None, description="A description for the resource", max_length=500 ) - environment_kind: Optional[EnvironmentKind] = None - environment_id: Optional[str] = Field( - None, - description="Id of the environment to use", - example="01AN4Z79ZS6XX96588FDX0H099", - min_length=1, - ) resource_class_id: Optional[int] = Field( None, description="The identifier of a resource class" ) - container_image: Optional[str] = Field( - None, - description="A container image", - example="renku/renkulab-py:3.10-0.18.1", - max_length=500, - ) - default_url: Optional[str] = Field( - None, - description="The default path to open in a session", - example="/lab", - max_length=200, - ) - - -class SessionStart(BaseAPISpec): - model_config = ConfigDict( - extra="allow", - ) - resource_class_id: Optional[int] = Field( - None, description="The identifier of a resource class" - ) - - -class EnvironmentList(RootModel[List[Environment]]): - root: List[Environment] = Field(..., description="A list of session environments") - - -class SessionLaunchersList(RootModel[List[SessionLauncher]]): - root: List[SessionLauncher] = Field( - ..., description="A list of Renku session launchers", min_length=0 + environment: Optional[Union[EnvironmentPatchInLauncher, EnvironmentIdOnlyPatch]] = ( + None ) From 559f07e28f6fd1c113c751b2ed16b1c318a32fbc Mon Sep 17 00:00:00 2001 From: Tasko Olevski Date: Thu, 11 Jul 2024 17:23:45 +0200 Subject: [PATCH 2/3] chore: filter environments by owner type --- components/renku_data_services/session/api.spec.yaml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/components/renku_data_services/session/api.spec.yaml b/components/renku_data_services/session/api.spec.yaml index 9885e22a5..21863933f 100644 --- a/components/renku_data_services/session/api.spec.yaml +++ b/components/renku_data_services/session/api.spec.yaml @@ -12,6 +12,12 @@ paths: /environments: get: summary: Get all environments + parameters: + - in: query + name: owner_type + schema: + $ref: "#/components/schemas/EnvironmentOwnerType" + description: Filter the environments by the owner type. responses: "200": description: List of environments From 86b8962fac9268477baab95493f9b31e61e65e47 Mon Sep 17 00:00:00 2001 From: Tasko Olevski Date: Fri, 12 Jul 2024 10:55:55 +0200 Subject: [PATCH 3/3] squashme: address comments --- .../renku_data_services/session/api.spec.yaml | 114 +++++++----------- .../renku_data_services/session/apispec.py | 53 +++----- 2 files changed, 64 insertions(+), 103 deletions(-) diff --git a/components/renku_data_services/session/api.spec.yaml b/components/renku_data_services/session/api.spec.yaml index 21863933f..d0c78fb21 100644 --- a/components/renku_data_services/session/api.spec.yaml +++ b/components/renku_data_services/session/api.spec.yaml @@ -11,16 +11,10 @@ servers: paths: /environments: get: - summary: Get all environments - parameters: - - in: query - name: owner_type - schema: - $ref: "#/components/schemas/EnvironmentOwnerType" - description: Filter the environments by the owner type. + summary: Get all global environments responses: "200": - description: List of environments + description: List of global environments content: application/json: schema: @@ -30,7 +24,7 @@ paths: tags: - environments post: - summary: Create a new session environment + summary: Create a new global session environment description: Requires admin permissions requestBody: required: true @@ -51,7 +45,7 @@ paths: - environments /environments/{environment_id}: get: - summary: Get a session environment + summary: Get a global session environment parameters: - in: path name: environment_id @@ -76,7 +70,7 @@ paths: tags: - environments patch: - summary: Update specific fields of an existing session environment + summary: Update specific fields of an existing global session environment description: Requires admin permissions parameters: - in: path @@ -108,7 +102,7 @@ paths: tags: - environments delete: - summary: Remove a session environment + summary: Remove a global session environment parameters: - in: path name: environment_id @@ -182,7 +176,7 @@ paths: tags: - session_launchers patch: - summary: Update specific fields of an existing session + summary: Update specific fields of an existing session launcher parameters: - in: path name: launcher_id @@ -270,10 +264,6 @@ components: $ref: "#/components/schemas/ContainerImage" default_url: $ref: "#/components/schemas/DefaultUrl" - owner_type: - $ref: "#/components/schemas/EnvironmentOwnerType" - owner_id: - $ref: "#/components/schemas/EnvironmentOwnerId" uid: $ref: "#/components/schemas/EnvironmentUid" gid: @@ -284,23 +274,17 @@ components: $ref: "#/components/schemas/EnvironmentMountDirectory" port: $ref: "#/components/schemas/EnvironmentPort" - visibility: - $ref: "#/components/schemas/EnvironmentVisibility" required: - id - name - creation_date - container_image - - official - port - working_directory - mount_directory - uid - gid - default_url - - owner_type - - owner_id - - visibility example: id: 01AN4Z79ZS6XX96588FDX0H099 name: JupyterLab environment @@ -313,10 +297,29 @@ components: mount_directory: /home/jovyan/work uid: 1000 gid: 1000 - owner_type: user - ownerId: 4fcd155c-fef5-48de-87f7-2facab8bf4c2 - visibility: private + EnvironmentGetInLauncher: + allOf: + - $ref: "#/components/schemas/Environment" + - type: object + properties: + environment_kind: + $ref: "#/components/schemas/EnvironmentKind" + required: + - environment_kind + example: + environment_kind: global_environment EnvironmentPostInLauncher: + allOf: + - $ref: "#/components/schemas/EnvironmentPost" + - type: object + properties: + environment_kind: + $ref: "#/components/schemas/EnvironmentKind" + required: + - environment_kind + example: + environment_kind: global_environment + EnvironmentPost: description: Data required to create a session environment type: object properties: @@ -350,26 +353,19 @@ components: allOf: - $ref: "#/components/schemas/EnvironmentPort" - default: 8080 - visibility: - allOf: - - $ref: "#/components/schemas/EnvironmentVisibility" - - default: private required: - name - container_image - EnvironmentPost: + EnvironmentPatchInLauncher: allOf: - - $ref: "#/components/schemas/EnvironmentPostInLauncher" + - $ref: "#/components/schemas/EnvironmentPatch" - type: object properties: - owner_id: - $ref: "#/components/schemas/EnvironmentOwnerId" - owner_type: - $ref: "#/components/schemas/EnvironmentOwnerType" - required: - - owner_id - - owner_type - EnvironmentPatchInLauncher: + environment_kind: + $ref: "#/components/schemas/EnvironmentKind" + example: + environment_kind: global_environment + EnvironmentPatch: type: object description: Update a session environment additionalProperties: false @@ -392,15 +388,6 @@ components: $ref: "#/components/schemas/EnvironmentMountDirectory" port: $ref: "#/components/schemas/EnvironmentPort" - EnvironmentPatch: - allOf: - - $ref: "#/components/schemas/EnvironmentPatchInLauncher" - - type: object - properties: - owner_id: - $ref: "#/components/schemas/EnvironmentOwnerId" - owner_type: - $ref: "#/components/schemas/EnvironmentOwnerType" SessionLaunchersList: description: A list of Renku session launchers type: array @@ -422,7 +409,7 @@ components: description: $ref: "#/components/schemas/Description" environment: - $ref: "#/components/schemas/Environment" + $ref: "#/components/schemas/EnvironmentGetInLauncher" required: - id - project_id @@ -440,6 +427,7 @@ components: name: Rstudio creation_date: "2023-11-01T17:32:28Z" description: JupyterLab session environment + environment_kind: global_environment container_image: rocker/rstudio default_url: "/rstudio" port: 8080 @@ -447,9 +435,6 @@ components: mount_directory: /home/rstudio/work uid: 1000 gid: 1000 - owner_type: project - ownerId: 01AN4Z79ZS5XN0F25N3DB94T4R - visibility: private SessionLauncherPost: description: Data required to create a session launcher type: object @@ -510,6 +495,13 @@ components: $ref: "#/components/schemas/EnvironmentId" required: - id + EnvironmentKind: + description: Kind of environment to use + type: string + enum: + - global_environment + - container_image + example: container_image EnvironmentId: description: Id of the environment to use type: string @@ -565,22 +557,6 @@ components: type: string description: The location where the persistent storage for the session will be mounted, usually it should be identical to or a parent of the working directory minLength: 1 - EnvironmentOwnerType: - type: string - enum: - - user - - group - - project - - platform - description: The owner of the environment which is used to enforce authorization on it - EnvironmentOwnerId: - type: string - description: The id of the entity that owns the environment - EnvironmentVisibility: - type: string - enum: - - public - - private ErrorResponse: type: object properties: diff --git a/components/renku_data_services/session/apispec.py b/components/renku_data_services/session/apispec.py index 23de693d3..1a266cf10 100644 --- a/components/renku_data_services/session/apispec.py +++ b/components/renku_data_services/session/apispec.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: api.spec.yaml -# timestamp: 2024-07-10T15:10:10+00:00 +# timestamp: 2024-07-12T08:57:02+00:00 from __future__ import annotations @@ -12,16 +12,9 @@ from renku_data_services.session.apispec_base import BaseAPISpec -class EnvironmentOwnerType(Enum): - user = "user" - group = "group" - project = "project" - platform = "platform" - - -class EnvironmentVisibility(Enum): - public = "public" - private = "private" +class EnvironmentKind(Enum): + global_environment = "global_environment" + container_image = "container_image" class Error(BaseAPISpec): @@ -71,10 +64,6 @@ class Environment(BaseAPISpec): example="/lab", max_length=200, ) - owner_type: EnvironmentOwnerType - owner_id: str = Field( - ..., description="The id of the entity that owns the environment" - ) uid: int = Field( ..., description="The user ID used to run the session", gt=0, le=65535 ) @@ -95,10 +84,13 @@ class Environment(BaseAPISpec): gt=0, le=65535, ) - visibility: EnvironmentVisibility -class EnvironmentPostInLauncher(BaseAPISpec): +class EnvironmentGetInLauncher(Environment): + environment_kind: EnvironmentKind + + +class EnvironmentPost(BaseAPISpec): name: str = Field( ..., description="Renku session name", @@ -141,17 +133,9 @@ class EnvironmentPostInLauncher(BaseAPISpec): gt=0, le=65535, ) - visibility: Optional[EnvironmentVisibility] = None - - -class EnvironmentPost(EnvironmentPostInLauncher): - owner_id: str = Field( - ..., description="The id of the entity that owns the environment" - ) - owner_type: EnvironmentOwnerType -class EnvironmentPatchInLauncher(BaseAPISpec): +class EnvironmentPatch(BaseAPISpec): model_config = ConfigDict( extra="forbid", ) @@ -199,13 +183,6 @@ class EnvironmentPatchInLauncher(BaseAPISpec): ) -class EnvironmentPatch(EnvironmentPatchInLauncher): - owner_id: Optional[str] = Field( - None, description="The id of the entity that owns the environment" - ) - owner_type: Optional[EnvironmentOwnerType] = None - - class SessionLauncher(BaseAPISpec): id: str = Field( ..., @@ -236,7 +213,7 @@ class SessionLauncher(BaseAPISpec): description: Optional[str] = Field( None, description="A description for the resource", max_length=500 ) - environment: Environment + environment: EnvironmentGetInLauncher class EnvironmentIdOnlyPatch(BaseAPISpec): @@ -261,6 +238,14 @@ class EnvironmentList(RootModel[List[Environment]]): root: List[Environment] = Field(..., description="A list of session environments") +class EnvironmentPostInLauncher(EnvironmentPost): + environment_kind: EnvironmentKind + + +class EnvironmentPatchInLauncher(EnvironmentPatch): + environment_kind: Optional[EnvironmentKind] = None + + class SessionLaunchersList(RootModel[List[SessionLauncher]]): root: List[SessionLauncher] = Field( ..., description="A list of Renku session launchers", min_length=0