diff --git a/docs/helm/science-platform/deployment.md b/docs/helm/science-platform/deployment.md index a2cc00c9..0f5e7a47 100644 --- a/docs/helm/science-platform/deployment.md +++ b/docs/helm/science-platform/deployment.md @@ -450,10 +450,6 @@ deployment: # Space delimited list of allowed Image Registry hosts. These hosts should match the hosts in the User Session images. registryHosts: "images.canfar.net" - # The IVOA GMS Group URI to verify users against for permission to use the Science Platform. - # See https://www.ivoa.net/documents/GMS/20220222/REC-GMS-1.0.html#tth_sEc3.2 - usersGroup: "ivo://example.org/gms?skaha-platform-users" - # The IVOA GMS Group URI to verify images without contacting Harbor. # See https://www.ivoa.net/documents/GMS/20220222/REC-GMS-1.0.html#tth_sEc3.2 adminsGroup: "ivo://example.org/gms?skaha-admin-users" @@ -510,6 +506,21 @@ deployment: minEphemeralStorage: "20Gi" # The initial requested amount of ephemeral (local) storage. Does NOT apply to Desktop sessions. maxEphemeralStorage: "200Gi" # The maximum amount of ephemeral (local) storage to allow a Session to extend to. Does NOT apply to Desktop sessions. + # Platform access — prefer deployment.skaha.sessions.authorization; deployment.skaha.usersGroup is deprecated when group.enabled / permissionsAPI.enabled are unset. + # Deployments receive SKAHA_SESSIONS_AUTHORIZATION_GROUP_ENABLED and SKAHA_SESSIONS_AUTHORIZATION_PERMISSIONS_API_ENABLED plus mode-specific env vars. + # See https://www.ivoa.net/documents/GMS/20220222/REC-GMS-1.0.html#tth_sEc3.2 + authorization: + group: + enabled: true + uri: "ivo://example.org/gms?skaha-platform-users" + # Alternative (Permissions API instead of GMS group): + # authorization: + # permissionsAPI: + # enabled: true + # baseURL: "https://permissions.example.org/api" + # type: "route" + # name: "skaha" + # Optionally setup a separate host for User Sessions for Skaha to redirect to. The HTTPS scheme is assumed. Defaults to the Skaha hostname (.Values.deployment.hostname). # Example: # hostname: myhost.example.org diff --git a/helm/applications/posix-mapper/templates/posix-mapper-tomcat-deployment.yaml b/helm/applications/posix-mapper/templates/posix-mapper-tomcat-deployment.yaml index 0d3859a8..b663562e 100644 --- a/helm/applications/posix-mapper/templates/posix-mapper-tomcat-deployment.yaml +++ b/helm/applications/posix-mapper/templates/posix-mapper-tomcat-deployment.yaml @@ -25,8 +25,10 @@ spec: securityContext: {{- toYaml . | nindent 8 }} {{- end }} + {{- with .Values.deployment.posixMapper.imagePullSecrets }} imagePullSecrets: - - name: regcred + {{- toYaml . | nindent 8 }} + {{- end }} containers: - image: {{ .Values.deployment.posixMapper.image }} imagePullPolicy: {{ .Values.deployment.posixMapper.imagePullPolicy }} diff --git a/helm/applications/posix-mapper/values.yaml b/helm/applications/posix-mapper/values.yaml index 77c64dfd..c4e77a6c 100644 --- a/helm/applications/posix-mapper/values.yaml +++ b/helm/applications/posix-mapper/values.yaml @@ -33,6 +33,14 @@ deployment: posixMapper: image: registry.gitlab.com/ska-telescope/src/src-ugm/ska-src-ugm-posix-mapper:0.4.0 imagePullPolicy: Always + + # Optional. Pull secrets for private container registries (spec.template.spec.imagePullSecrets). + # @see https://kubernetes.io/docs/concepts/containers/images/#specifying-imagepullsecrets-on-a-pod + # + # Example: + # imagePullSecrets: + # - name: regcred + imagePullSecrets: [] resourceID: ivo://opencadc.org/posix-mapper # URI or URL of the OIDC (IAM) server. Used to validate incoming tokens. diff --git a/helm/applications/science-portal/Chart.yaml b/helm/applications/science-portal/Chart.yaml index a15d4a17..ebe22c3c 100644 --- a/helm/applications/science-portal/Chart.yaml +++ b/helm/applications/science-portal/Chart.yaml @@ -15,10 +15,10 @@ type: application # This is the chart version. This version number should be incremented each time you make changes # to the chart and its templates, including the app version. # Versions are expected to follow Semantic Versioning (https://semver.org/) -version: 2.1.0 +version: 2.1.1 # This is the version number of the application being deployed. This version number should be # incremented each time you make changes to the application. Versions are not expected to # follow Semantic Versioning. They should reflect the version the application is using. # It is recommended to use it with quotes. -appVersion: "eca70d91f45fe6578207c7bd70e67b91d2654700" +appVersion: "e9517a949cf840f50d26d953a5bc602f54911653" diff --git a/helm/applications/science-portal/values.yaml b/helm/applications/science-portal/values.yaml index 9763c85e..bfbd0275 100644 --- a/helm/applications/science-portal/values.yaml +++ b/helm/applications/science-portal/values.yaml @@ -7,7 +7,7 @@ replicaCount: 1 image: repository: ghcr.io/canfar/science-portal pullPolicy: IfNotPresent - tag: eca70d91f45fe6578207c7bd70e67b91d2654700 + tag: e9517a949cf840f50d26d953a5bc602f54911653 imagePullSecrets: [] nameOverride: "" diff --git a/helm/applications/skaha/Chart.yaml b/helm/applications/skaha/Chart.yaml index 24a10d76..92eb6b33 100644 --- a/helm/applications/skaha/Chart.yaml +++ b/helm/applications/skaha/Chart.yaml @@ -21,13 +21,13 @@ type: application # This is the chart version. This version number should be incremented each time you make changes # to the chart and its templates, including the app version. # Versions are expected to follow Semantic Versioning (https://semver.org/) -version: 1.6.0 +version: 1.6.1 # This is the version number of the application being deployed. This version number should be # incremented each time you make changes to the application. Versions are not expected to # follow Semantic Versioning. They should reflect the version the application is using. # It is recommended to use it with quotes. -appVersion: "1.2.1" +appVersion: "1.3.0" dependencies: - name: "redis" diff --git a/helm/applications/skaha/README.md b/helm/applications/skaha/README.md index 7218ad87..a8c36af2 100644 --- a/helm/applications/skaha/README.md +++ b/helm/applications/skaha/README.md @@ -42,6 +42,11 @@ A Helm chart to install the Skaha web service of the CANFAR Science Platform | deployment.skaha.resources.limits.memory | string | `"3Gi"` | Memory limit for the Skaha API container. | | deployment.skaha.resources.requests.cpu | string | `"1000m"` | CPU request for the Skaha API container. | | deployment.skaha.resources.requests.memory | string | `"2Gi"` | Memory request for the Skaha API container. | +| deployment.skaha.sessions | object | `{"authorization":{"group":{"enabled":false,"uri":""},"permissionsAPI":{"authAPIBaseURL":"","baseURL":"","enabled":false,"method":"","name":"skaha","route":"","type":"route","version":""}},"expirySeconds":"345600","flexResourceRequests":{"headless":{"cpuCores":"1","memoryInGB":"4"}},"imagePullPolicy":"Always","ingress":{"customResponseHeaders":{},"tls":{}},"initContainerImage":"redis:8.2.2-bookworm","kueue":{"rbac":{"create":false}},"limitRange":{"enabled":false},"maxCount":"5","maxEphemeralStorage":"200Gi","minEphemeralStorage":"20Gi","nodeLabelSelector":null,"tolerations":[],"userStorage":{"admin":{"auth":null},"homeDirectory":"home","projectsDirectory":"projects","spec":{},"topLevelDirectory":"/cavern"}}` | @deprecated Prefer deployment.skaha.sessions.authorization or deprecated usersGroup alone. Still honoured when sessions.authorization.group.enabled is false. The IVOA GMS Group URI to verify users against for permission to use the Science Platform. See https://www.ivoa.net/documents/GMS/20220222/REC-GMS-1.0.html#tth_sEc3.2 usersGroup: "ivo://example.org/gms?prototyping-groups/mini-src/platform-users" Group URI for users to ensure priority for their headless jobs. See https://www.ivoa.net/documents/GMS/20220222/REC-GMS-1.0.html#tth_sEc3.2 headlessPriorityGroup: "ivo://example.org/gms?skaha-priority-headless-users" Array of GMS Group URIs allowed to set the logging level. If none set, then nobody can change the log level. See https://www.ivoa.net/documents/GMS/20220222/REC-GMS-1.0.html#tth_sEc3.2 for GMS Group URIs See https://github.com/opencadc/core/tree/main/cadc-log for Logging control loggingGroups: - "ivo://example.org/gms?prototyping-groups/mini-src/platform-users" The Resource ID (URI) of the Service that contains the Posix Mapping information posixMapperResourceID: "ivo://example.org/posix-mapper" URI or URL of the OIDC (IAM) server. Used to validate incoming tokens. oidcURI: https://iam.example.org/ The Resource ID (URI) of the GMS Service. gmsID: ivo://example.org/gms The absolute URL of the IVOA Registry where services are registered registryURL: https://spsrc27.iaa.csic.es/reg This applies to Skaha itself. Meaning, this Pod will be scheduled as described by the nodeAffinity clause. Note the different indentation level compared to the sessions.nodeAffinity. See https://kubernetes.io/docs/tasks/configure-pod-container/assign-pods-nodes-using-node-affinity/ nodeAffinity: {} Settings for User Sessions. Sensible defaults supplied, but can be overridden. For units of storage, see https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/#meaning-of-memory. | +| deployment.skaha.sessions.authorization.group.enabled | bool | `false` | When true, SKAHA_USERS_GROUP is set from uri. Required uri when enabled (Helm validates). The Skaha service enforces mutually exclusive authorization modes at runtime. | +| deployment.skaha.sessions.authorization.permissionsAPI.authAPIBaseURL | string | `""` | Base URL for the IAM/OIDC auth API used by the permissions client. Required when enabled is true (Helm validates). | +| deployment.skaha.sessions.authorization.permissionsAPI.baseURL | string | `""` | Required when enabled is true (Helm validates). | +| deployment.skaha.sessions.authorization.permissionsAPI.enabled | bool | `false` | When true, SKAHA_PERMISSIONS_API_*_ENABLED is set from baseURL, authAPIBaseURL, type, route, name, version, and method. Required baseURL and authAPIBaseURL when enabled (Helm validates). The Skaha service enforces mutually exclusive authorization modes at runtime. | | deployment.skaha.sessions.expirySeconds | string | `"345600"` | Session lifetime in seconds before expiry and shutdown. | | deployment.skaha.sessions.flexResourceRequests.headless.cpuCores | string | `"1"` | Default CPU request (cores) for flex headless sessions. | | deployment.skaha.sessions.flexResourceRequests.headless.memoryInGB | string | `"4"` | Default memory request (GiB) for flex headless sessions. | @@ -59,7 +64,6 @@ A Helm chart to install the Skaha web service of the CANFAR Science Platform | deployment.skaha.sessions.userStorage.admin.auth | string | `nil` | Authentication settings used for user-storage admin operations. | | deployment.skaha.sessions.userStorage.homeDirectory | string | `"home"` | Relative path under topLevelDirectory for user home directories. | | deployment.skaha.sessions.userStorage.projectsDirectory | string | `"projects"` | Relative path under topLevelDirectory for shared projects storage. | -| deployment.skaha.sessions.userStorage.spec | object | `{}` | | | deployment.skaha.sessions.userStorage.topLevelDirectory | string | `"/cavern"` | Absolute mount path containing user home and projects directories. | | experimentalFeatures.enabled | bool | `false` | Enable processing of experimental feature gates. | | ingress.enabled | bool | `true` | Enable ingress routing for the Skaha API. | diff --git a/helm/applications/skaha/templates/NOTES.txt b/helm/applications/skaha/templates/NOTES.txt index bb991ed2..b873dc53 100644 --- a/helm/applications/skaha/templates/NOTES.txt +++ b/helm/applications/skaha/templates/NOTES.txt @@ -9,6 +9,9 @@ Skaha workload namespace: {{ include "skaha.workloadNamespace" . }} {{- $userStorage := .Values.deployment.skaha.sessions.userStorage | default dict }} {{- $legacyPVCName := hasKey $userStorage "persistentVolumeClaimName" }} +{{- $platformAuth := mergeOverwrite (.Values.deployment.skaha.authorization | default dict) (.Values.deployment.skaha.sessions.authorization | default dict) }} +{{- $platformGroup := $platformAuth.group | default dict }} +{{- $legacyUsersGroupDepr := and (.Values.deployment.skaha.usersGroup | default "" | trim) (not ($platformGroup.enabled | default false)) }} {{- if $legacyPVCName }} ################################################################################ @@ -23,6 +26,20 @@ Skaha workload namespace: {{ include "skaha.workloadNamespace" . }} {{- end }} +{{- if $legacyUsersGroupDepr }} + +################################################################################ +# # +# PLATFORM ACCESS — configuration notice # +# # +# deployment.skaha.usersGroup is deprecated. Prefer # +# deployment.skaha.sessions.authorization.group / permissionsAPI, # +# usersGroup remains honoured until removed in a future chart major. # +# # +################################################################################ + +{{- end }} + User Sessions: - Ensure CARTA images being used are at version 5.0.3 or higher. @@ -75,6 +92,9 @@ You are using deprecated top-level skahaWorkload.namespace; the chart still appl {{- if $legacyPVCName }} Your values still set deployment.skaha.sessions.userStorage.persistentVolumeClaimName — migrate to userStorage.spec (see notice above). The legacy field remains honoured when spec is unset or empty. {{- end }} +{{- if $legacyUsersGroupDepr }} +You still set deployment.skaha.usersGroup — migrate to deployment.skaha.sessions.authorization (group or permissionsAPI; see notice above). +{{- end }} Experimental Features Configured: {{- if and .Values.experimentalFeatures .Values.experimentalFeatures.enabled }} diff --git a/helm/applications/skaha/templates/_helpers.tpl b/helm/applications/skaha/templates/_helpers.tpl index 071a0bda..1d8648f7 100644 --- a/helm/applications/skaha/templates/_helpers.tpl +++ b/helm/applications/skaha/templates/_helpers.tpl @@ -160,6 +160,29 @@ Headless jobs PriorityClass name for SKAHA_HEADLESS_PRIORITY_CLASS from the effe {{- $h.name -}} {{- end -}} +{{/* +Structural validation only; Skaha rejects conflicting modes at runtime. +*/}} +{{- define "skaha.validatePlatformAccess" }} +{{- $auth := mergeOverwrite (.Values.deployment.skaha.authorization | default dict) (.Values.deployment.skaha.sessions.authorization | default dict) }} +{{- $g := $auth.group | default dict -}} +{{- $p := $auth.permissionsAPI | default dict -}} +{{- $permURL := trim (default "" $p.baseURL) -}} +{{- $permAuthURL := trim (default "" $p.authAPIBaseURL) -}} +{{- $permEn := $p.enabled | default false -}} +{{- $uri := trim (default "" $g.uri) -}} +{{- $groupEn := $g.enabled | default false -}} +{{- if and $permEn (not $permURL) }} +{{- fail "deployment.skaha.sessions.authorization.permissionsAPI.enabled is true but permissionsAPI.baseURL is empty." }} +{{- end }} +{{- if and $permEn (not $permAuthURL) }} +{{- fail "deployment.skaha.sessions.authorization.permissionsAPI.enabled is true but permissionsAPI.authAPIBaseURL is empty." }} +{{- end }} +{{- if and $groupEn (not $uri) }} +{{- fail "deployment.skaha.sessions.authorization.group.enabled is true but authorization.group.uri is empty." }} +{{- end }} +{{- end }} + {{/* USER SESSION TEMPLATE DEFINITIONS */}} diff --git a/helm/applications/skaha/templates/skaha-tomcat-deployment.yaml b/helm/applications/skaha/templates/skaha-tomcat-deployment.yaml index 1e99368b..1be9e54a 100644 --- a/helm/applications/skaha/templates/skaha-tomcat-deployment.yaml +++ b/helm/applications/skaha/templates/skaha-tomcat-deployment.yaml @@ -33,6 +33,7 @@ spec: {{- end }} containers: - env: + {{- include "skaha.validatePlatformAccess" . }} {{ $userStorage := required "Missing .Values.deployment.skaha.sessions.userStorage configuration" .Values.deployment.skaha.sessions.userStorage }} {{- with $userStorage }} {{ $userStorageAdmin := required "Missing .Values.deployment.skaha.sessions.userStorage.admin configuration" .admin }} @@ -98,10 +99,55 @@ spec: value: "{{ .Values.deployment.skaha.defaultQuotaGB }}" - name: skaha.harborhosts value: "{{ .Values.deployment.skaha.registryHosts }}" - - name: skaha.usersgroup - value: "{{ .Values.deployment.skaha.usersGroup }}" - - name: skaha.headlessgroup - value: "{{ .Values.deployment.skaha.headlessGroup }}" + {{- $authorization := mergeOverwrite (.Values.deployment.skaha.authorization | default dict) (.Values.deployment.skaha.sessions.authorization | default dict) }} + {{- $grp := $authorization.group | default dict }} + {{- $permAPI := $authorization.permissionsAPI | default dict }} + {{- $groupEnabled := $grp.enabled | default false }} + {{- $permEnabled := $permAPI.enabled | default false }} + {{- $legacyUsersGroupTrim := trim (.Values.deployment.skaha.usersGroup | default "" | toString) }} + - name: SKAHA_SESSIONS_AUTHORIZATION_GROUP_ENABLED + value: "{{ $groupEnabled }}" + - name: SKAHA_SESSIONS_AUTHORIZATION_PERMISSIONS_API_ENABLED + value: "{{ $permEnabled }}" + {{- if $groupEnabled }} + - name: SKAHA_USERS_GROUP + value: {{ trim ($grp.uri | default "" | toString) | quote }} + {{- end }} + {{- if $permEnabled }} + {{- $permURL := trim (default "" $permAPI.baseURL) }} + {{- $permAuthURL := trim (default "" $permAPI.authAPIBaseURL) }} + {{- if $permURL }} + - name: SKAHA_PERMISSIONS_API_BASE_URL + value: {{ $permURL | quote }} + {{- end }} + {{- if $permAuthURL }} + - name: SKAHA_PERMISSIONS_API_AUTH_BASE_URL + value: {{ $permAuthURL | quote }} + {{- end }} + - name: SKAHA_PERMISSIONS_API_TYPE + value: {{ ($permAPI.type | default "route") | quote }} + - name: SKAHA_PERMISSIONS_API_NAME + value: {{ ($permAPI.name | default "skaha") | quote }} + {{- if eq (($permAPI.type | default "route") | lower) "route" }} + {{- $rte := trim (default "" $permAPI.route) }} + {{- if $rte }} + - name: SKAHA_PERMISSIONS_API_ROUTE + value: {{ $rte | quote }} + {{- end }} + {{- end }} + {{- with trim (default "" $permAPI.version) }} + - name: SKAHA_PERMISSIONS_API_VERSION + value: {{ . | quote }} + {{- end }} + {{- with trim (default "" $permAPI.method) }} + - name: SKAHA_PERMISSIONS_API_METHOD + value: {{ . | quote }} + {{- end }} + {{- end }} + {{- if and (not $groupEnabled) (not $permEnabled) $legacyUsersGroupTrim }} + - name: SKAHA_USERS_GROUP + value: {{ $legacyUsersGroupTrim | quote }} + {{- end }} {{- with .Values.deployment.skaha.headlessPriorityGroup }} - name: skaha.headlessprioritygroup value: "{{ . }}" @@ -145,8 +191,6 @@ spec: {{- end }} {{- end }} {{- end }} - - name: skaha.adminsgroup - value: "{{ .Values.deployment.skaha.adminsGroup }}" - name: skaha.posixmapper.resourceid value: "{{ .Values.deployment.skaha.posixMapperResourceID }}" - name: REDIS_HOST diff --git a/helm/applications/skaha/values.yaml b/helm/applications/skaha/values.yaml index 12623f92..4bf574c5 100644 --- a/helm/applications/skaha/values.yaml +++ b/helm/applications/skaha/values.yaml @@ -77,18 +77,11 @@ deployment: # -- TTL in seconds for cached POSIX mapper entries. posixMapperCacheTTLSeconds: "86400" + # -- @deprecated Prefer deployment.skaha.sessions.authorization or deprecated usersGroup alone. Still honoured when sessions.authorization.group.enabled is false. # The IVOA GMS Group URI to verify users against for permission to use the Science Platform. # See https://www.ivoa.net/documents/GMS/20220222/REC-GMS-1.0.html#tth_sEc3.2 # usersGroup: "ivo://example.org/gms?prototyping-groups/mini-src/platform-users" - # The IVOA GMS Group URI to verify images without contacting Harbor. - # See https://www.ivoa.net/documents/GMS/20220222/REC-GMS-1.0.html#tth_sEc3.2 - # adminsGroup: "ivo://example.org/gms?prototyping-groups/mini-src/platform-users" - - # Group URI for users to preempt headless jobs. - # See https://www.ivoa.net/documents/GMS/20220222/REC-GMS-1.0.html#tth_sEc3.2 - # headlessGroup: "ivo://example.org/gms?prototyping-groups/mini-src/platform-users" - # Group URI for users to ensure priority for their headless jobs. # See https://www.ivoa.net/documents/GMS/20220222/REC-GMS-1.0.html#tth_sEc3.2 # headlessPriorityGroup: "ivo://example.org/gms?skaha-priority-headless-users" @@ -138,6 +131,32 @@ deployment: # -- Maximum ephemeral storage limit for sessions (non-desktop). maxEphemeralStorage: "200Gi" + # Platform access for Skaha sessions: set authorization.group, authorization.permissionsAPI, or deprecated deployment.skaha.usersGroup. + # The Deployment receives SKAHA_SESSIONS_AUTHORIZATION_*_ENABLED and mode-specific vars; only fields for modes with enabled: true are set. + authorization: + group: + # -- When true, SKAHA_USERS_GROUP is set from uri. Required uri when enabled (Helm validates). The Skaha service enforces mutually exclusive authorization modes at runtime. + enabled: false + uri: "" + permissionsAPI: + # @see https://permissions.srcnet.skao.int/api/openapi.json for the API specification. + # -- When true, SKAHA_PERMISSIONS_API_* vars are set from baseURL, authAPIBaseURL, type, route, name, version, and method. Required baseURL and authAPIBaseURL when enabled (Helm validates). The Skaha service enforces mutually exclusive authorization modes at runtime. + enabled: false + # -- Required when enabled is true (Helm validates). + baseURL: "" + # -- Base URL for the SRCNet Auth API used by the permissions client. + authAPIBaseURL: "" + # -- Type of the permissions API. + type: "route" + # -- Route of the permissions API. + route: "" + # -- Name of the permissions API. + name: "skaha" + # -- Version of the permissions API. + version: "" + # -- Method of the permissions API. + method: "" + # YAML to pass to a LimitRange object called "{{ .Release.Name }}-session-limit-range" in the workload Namespace to define the resource limits. # These limits will be applied to Container objects (User Sessions). # **NOTE**: Pay attention to the deployment.skaha.sessions.flexResourceRequests above as these two features can conflict.