Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion charts/eduide/Chart.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ 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.5
version: 2.2.0
# 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.
Expand Down
12 changes: 11 additions & 1 deletion charts/eduide/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# eduide

![Version: 2.1.5](https://img.shields.io/badge/Version-2.1.5-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 1.2.0](https://img.shields.io/badge/AppVersion-1.2.0-informational?style=flat-square)
![Version: 2.2.0](https://img.shields.io/badge/Version-2.2.0-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 1.2.0](https://img.shields.io/badge/AppVersion-1.2.0-informational?style=flat-square)

EduIDE tenant release: operator, REST service, landing page and routes for one
environment. Requires eduide-cluster to be installed on the cluster first.
Expand Down Expand Up @@ -84,6 +84,16 @@ environment. Requires eduide-cluster to be installed on the cluster first.
| landingPage.logo | string | `"logos/theiablueprint.svg"` | The logo of the application that should be displayed on the landing pages |
| landingPage.logoData | string | `nil` | set landingPage.logoData=$(cat path/to/file.svg | base64 -w 0 -) Another way is to directly add the base64 string to the values file. |
| landingPage.logoFileExtension | string | `"svg"` | The file extension of the logo. Must be set to match the logo respectively the logoData. This is required because browsers cannot show a binary image (e.g. png) with a svg ending and vice-versa. |
| landingPage.privacy | object | (see details below) | What the privacy page states about this installation. Only the research clause lives here. The retention and session figures the page shows are DERIVED in the landing page config map from the settings that actually produce them - `theia-workspace-garbage-collector.env.WORKSPACE_TTL`, `landingPage.ephemeralStorage` and `appDefinitions.defaults.timeout` - so changing a retention period cannot leave the privacy statement claiming something untrue. Do not restate those numbers here. |
| landingPage.privacy.controller | object | (see details below) | Who is accountable for the data, named on the privacy page. The defaults are deliberately obvious placeholders. Whoever deploys this is the controller, and a privacy statement naming somebody else's university is worse than one that visibly has not been filled in. |
| landingPage.privacy.controller.address | string | `""` | Postal address of that person, e.g. "1 Example Street, 00000 Example City". Optional; omitted when empty. |
| landingPage.privacy.controller.email | string | `""` | Where data protection enquiries go, e.g. "privacy@example.edu". |
| landingPage.privacy.controller.organisation | string | `""` | The legal entity responsible under the GDPR, e.g. "Example University". Empty by default on purpose: the page then says plainly that no controller has been configured, rather than presenting a placeholder as though it were this installation's real contact. |
| landingPage.privacy.controller.representative | string | `""` | The person accountable for this service, as named on the imprint, e.g. "Prof. Dr. Example Person". |
| landingPage.privacy.dataProtectionOfficer | object | (see details below) | The data protection officer, named separately from the controller because the GDPR requires a distinct contact point. Empty by default for the same reason as above. |
| landingPage.privacy.dataProtectionOfficer.email | string | `""` | Where the data protection officer is reached, e.g. "dpo@example.edu". |
| landingPage.privacy.dataProtectionOfficer.name | string | `""` | Optional name. Most institutions publish only the address. |
| landingPage.privacy.scientificUse | bool | `false` | State that anonymised usage data may also be used for scientific research. Leave off unless this installation has a legal basis for it: this is a processing purpose, not a cosmetic string. |
| landingPage.sentry | object | (see details below) | Values related to Sentry on the landing page. |
| landingPage.sentry.enable | bool | `false` | Set SENTRY_ENABLE=true in the landing page deployment. Off by default: the DSN is compiled into the published images and points at TUM's Sentry, so enabling this outside TUM sends your hostnames and namespace names there. |
| monitor | object | (see details below) | Values to influence the monitor initialization on the operator |
Expand Down
77 changes: 77 additions & 0 deletions charts/eduide/templates/landing-page-config-map.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,83 @@ data:
loadingText: "{{ tpl (.Values.landingPage.loadingText | toString) . }}",
{{- end }}
sentryEnable: {{ tpl (.Values.landingPage.sentry.enable | toString) . }},
{{- /*
What the privacy page is allowed to state about this installation.

DERIVED, deliberately. Every number below is computed from the value that
actually produces the behaviour it describes, so raising a retention
period cannot leave the privacy statement asserting the old one. The
alternative - restating the figures in a second place - is how a privacy
statement quietly becomes false.

workspacePersistent landingPage.ephemeralStorage, inverted
workspaceRetentionDays theia-workspace-garbage-collector.env.WORKSPACE_TTL
sessionMaxMinutes appDefinitions.defaults.timeout
sessionIdleMinutes appDefinitions.defaults.monitor.activityTracker.timeoutAfter

The last two mirror the fallbacks in appdefinitions.yaml, which is where
the operator actually reads them, so the page cannot disagree with the
AppDefinition the sessions run under.

scientificUse is the one policy choice, not a derivation.
*/}}
{{- $gc := (index .Values "theia-workspace-garbage-collector") | default dict }}
{{- $gcEnabled := true }}
{{- if hasKey $gc "enabled" }}{{ $gcEnabled = $gc.enabled }}{{ end }}
{{- $ttl := ((($gc.env).WORKSPACE_TTL) | default "1209600s") | toString | trimSuffix "s" }}
{{- $appDefaults := (.Values.appDefinitions).defaults | default dict }}
{{- /*
Session limits are the WORST CASE across everything a user can pick, not
the defaults. appdefinitions.yaml resolves each app's own timeout before
falling back to the defaults, so an app overriding it would otherwise make
the page understate how long a session can live. Nothing overrides these
today; taking the maximum keeps the statement true if something does.
*/}}
{{- $maxSession := ($appDefaults.timeout | default 1440) | int }}
{{- $maxIdle := (((($appDefaults.monitor).activityTracker).timeoutAfter) | default 60) | int }}
{{- range $name, $app := (.Values.appDefinitions).apps | default dict }}
{{- if and $app $app.landingPage }}
{{- $t := ($app.timeout | default $appDefaults.timeout | default 1440) | int }}
{{- if gt $t $maxSession }}{{ $maxSession = $t }}{{ end }}
{{- $i := ((($app.monitor).activityTracker).timeoutAfter) | default ((($appDefaults.monitor).activityTracker).timeoutAfter) | default 60 | int }}
{{- if gt $i $maxIdle }}{{ $maxIdle = $i }}{{ end }}
{{- end }}
{{- end }}
privacy: {
workspacePersistent: {{ not .Values.landingPage.ephemeralStorage }},
workspaceGarbageCollected: {{ $gcEnabled }},
{{- if $gcEnabled }}
{{- /*
Seconds, not days: helm's `div` is integer division, so a TTL that is
not a whole number of days would be silently rounded down and the page
would claim a shorter retention than the deployment actually keeps.
The page formats it.
*/}}
workspaceRetentionSeconds: {{ atoi $ttl }},
{{- end }}
sessionMaxMinutes: {{ $maxSession }},
sessionIdleMinutes: {{ $maxIdle }},
scientificUse: {{ ((.Values.landingPage).privacy).scientificUse | default false }},
{{- /*
Who is accountable, named on the privacy page. Unlike the figures above
these cannot be derived from anything - only the operator knows who the
controller is - so they are values, and their defaults are obvious
placeholders. A statement naming the wrong institution is worse than
one that visibly has not been filled in.
*/}}
{{- $ctrl := ((.Values.landingPage).privacy).controller | default dict }}
{{- $dpo := ((.Values.landingPage).privacy).dataProtectionOfficer | default dict }}
controller: {
organisation: {{ $ctrl.organisation | quote }},
representative: {{ $ctrl.representative | quote }},
address: {{ $ctrl.address | default "" | quote }},
email: {{ $ctrl.email | quote }},
},
dataProtectionOfficer: {
name: {{ $dpo.name | default "" | quote }},
email: {{ $dpo.email | quote }},
},
},
{{- if .Values.landingPage.footerLinks }}
footerLinks: {
{{- if .Values.landingPage.footerLinks.attribution }}
Expand Down
41 changes: 41 additions & 0 deletions charts/eduide/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,47 @@ landingPage:
# -- If set to true no persisted storage is used when creating sessions on the landing page.
# Set to false if you want to use persisted storage.
ephemeralStorage: true
# -- What the privacy page states about this installation.
# Only the research clause lives here. The retention and session figures the
# page shows are DERIVED in the landing page config map from the settings that
# actually produce them - `theia-workspace-garbage-collector.env.WORKSPACE_TTL`,
# `landingPage.ephemeralStorage` and `appDefinitions.defaults.timeout` - so
# changing a retention period cannot leave the privacy statement claiming
# something untrue. Do not restate those numbers here.
# @default -- (see details below)
privacy:
# -- State that anonymised usage data may also be used for scientific
# research. Leave off unless this installation has a legal basis for it:
# this is a processing purpose, not a cosmetic string.
scientificUse: false
# -- Who is accountable for the data, named on the privacy page.
# The defaults are deliberately obvious placeholders. Whoever deploys this
# is the controller, and a privacy statement naming somebody else's
# university is worse than one that visibly has not been filled in.
# @default -- (see details below)
controller:
# -- The legal entity responsible under the GDPR, e.g. "Example University".
# Empty by default on purpose: the page then says plainly that no
# controller has been configured, rather than presenting a placeholder as
# though it were this installation's real contact.
organisation: ""
# -- The person accountable for this service, as named on the imprint,
# e.g. "Prof. Dr. Example Person".
representative: ""
# -- Postal address of that person, e.g. "1 Example Street, 00000 Example
# City". Optional; omitted when empty.
address: ""
# -- Where data protection enquiries go, e.g. "privacy@example.edu".
email: ""
# -- The data protection officer, named separately from the controller
# because the GDPR requires a distinct contact point. Empty by default for
# the same reason as above.
# @default -- (see details below)
dataProtectionOfficer:
# -- Optional name. Most institutions publish only the address.
name: ""
# -- Where the data protection officer is reached, e.g. "dpo@example.edu".
email: ""
# -- The page may show these additional apps in a drop down. This is a map.
# The key maps to the app definition name
# The value contains the label shown in the UI and may optionally contain
Expand Down
Loading