From 96f18196c53267dbd72cd28e6fbadf06448db93a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thorsten=20Ro=C3=9Fner?= Date: Thu, 7 Nov 2024 16:50:05 +0100 Subject: [PATCH] feat(notes): Integrate Preview of Notes app --- .gitlab-ci.yml | 37 ++- .gitlab/lint/lint-kyverno.yml | 1 + docs/getting-started.md | 6 +- docs/migrations.md | 14 ++ .../apps/notes/helmfile-child.yaml.gotmpl | 31 +++ helmfile/apps/notes/helmfile.yaml.gotmpl | 11 + helmfile/apps/notes/values.yaml.gotmpl | 230 ++++++++++++++++++ helmfile/apps/nubus/values-nubus.yaml.gotmpl | 6 +- ...es-opendesk-keycloak-bootstrap.yaml.gotmpl | 84 ++++++- .../values-minio.yaml.gotmpl | 21 ++ .../values-postgresql.yaml.gotmpl | 5 + helmfile/environments/default/ai.yaml.gotmpl | 8 + .../environments/default/cache.yaml.gotmpl | 4 + .../environments/default/charts.yaml.gotmpl | 12 +- .../default/customization.yaml.gotmpl | 2 + .../environments/default/database.yaml.gotmpl | 7 + .../environments/default/global.yaml.gotmpl | 1 + .../environments/default/images.yaml.gotmpl | 32 ++- .../default/objectstores.yaml.gotmpl | 6 + .../default/opendesk_main.yaml.gotmpl | 3 + .../environments/default/replicas.yaml.gotmpl | 8 + .../default/resources.yaml.gotmpl | 21 ++ .../environments/default/secrets.yaml.gotmpl | 8 + .../environments/default/selinux.yaml.gotmpl | 3 + .../environments/default/theme.yaml.gotmpl | 1 + helmfile/files/portal-tiles/misc_notes.svg | 16 ++ helmfile/files/theme/portalStylesheet.css | 35 +++ helmfile_generic.yaml.gotmpl | 2 + 28 files changed, 597 insertions(+), 18 deletions(-) create mode 100644 helmfile/apps/notes/helmfile-child.yaml.gotmpl create mode 100644 helmfile/apps/notes/helmfile.yaml.gotmpl create mode 100644 helmfile/apps/notes/values.yaml.gotmpl create mode 100644 helmfile/environments/default/ai.yaml.gotmpl create mode 100644 helmfile/files/portal-tiles/misc_notes.svg diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 465dd832..d7ab68b9 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -70,7 +70,7 @@ variables: - "no" DEBUG_ENABLED: description: "Allows to set `debug.enabled` to true for a deployment, needs to be supported by stage specific\ - configuration containting: `debug.enabled: {{ env \"DEBUG_ENABLED\" | default false }}`" + configuration containing: `debug.enabled: {{ env \"DEBUG_ENABLED\" | default false }}`" value: "no" options: - "yes" @@ -154,6 +154,12 @@ variables: options: - "yes" - "no" + DEPLOY_NOTES: + description: "Enable Notes deployment." + value: "no" + options: + - "yes" + - "no" RUN_TESTS: description: "Triggers execution of E2E-tests." value: "no" @@ -183,10 +189,17 @@ variables: GRACE_PERIOD is the period in seconds that should be waited before running the tests." value: "0" +# Declare .environments which is in `opendesk-env` repository. In case it is not available +# 'cache' is used because job as a dummy key, as the job is not allowed to be empty. +.environments: + cache: {} + .deploy-common: cache: {} dependencies: [] extends: ".environments" + environment: + name: "${NAMESPACE}" image: "registry.opencode.de/bmi/opendesk/components/platform-development/images/helm:1.1.0\ @sha256:74f349066ac5d20e3afaa6abd28781b4c8dc086f67e3d3c1b8345e4a9c3371b1" script: @@ -208,9 +221,6 @@ variables: env-cleanup: extends: ".deploy-common" - environment: - name: "${NAMESPACE}" - action: "stop" needs: [] rules: - if: > @@ -444,6 +454,18 @@ jitsi-deploy: variables: COMPONENT: "jitsi" +notes-deploy: + stage: "050-components" + extends: ".deploy-common" + rules: + - if: > + $CI_PIPELINE_SOURCE =~ "web|schedules|trigger|api" && + $NAMESPACE =~ /.+/ && + ($DEPLOY_ALL_COMPONENTS != "no" || $DEPLOY_NOTES != "no") + when: "on_success" + variables: + COMPONENT: "notes" + element-deploy: stage: "050-components" extends: ".deploy-common" @@ -458,8 +480,6 @@ element-deploy: fetch-administrator-credentials: extends: ".deploy-common" - environment: - name: "${NAMESPACE}" stage: "post-prepare" rules: - if: > @@ -613,11 +633,6 @@ avscan-start: job: "avscan-prepare" strategy: "depend" -# Declare .environments which is in `opendesk-env` repository. In case it is not available -# 'cache' is used because job as a dummy key, as the job is not allowed to be empty. -.environments: - cache: {} - # Overwrite shared settings .common-semantic-release: image: "registry.opencode.de/bmi/opendesk/components/platform-development/images/semantic-release:1.1.0" diff --git a/.gitlab/lint/lint-kyverno.yml b/.gitlab/lint/lint-kyverno.yml index 0962a2ab..c918786c 100644 --- a/.gitlab/lint/lint-kyverno.yml +++ b/.gitlab/lint/lint-kyverno.yml @@ -16,6 +16,7 @@ lint-kyverno: - "element" - "jitsi" - "nextcloud" + - "notes" - "nubus" - "open-xchange" - "opendesk-migrations-post" diff --git a/docs/getting-started.md b/docs/getting-started.md index 3e1332d6..26939f8e 100644 --- a/docs/getting-started.md +++ b/docs/getting-started.md @@ -49,7 +49,7 @@ Before deploying openDesk, you must configure the deployment to fit your environ To keep your deployment up to date, we recommend customizing in `dev`, `test`, or `prod` and not in `default` environment files. -> All configuration options and their default values can be found in files at `helmfile/environments/default/` +> All configuration options and their default values can be found in files at [`helmfile/environments/default/`](../helmfile/environments/default/) For the following guide, we will use `dev` as environment where variables can be set in `helmfile/environments/dev/values.yaml.gotmpl`. @@ -141,7 +141,7 @@ like Docker Hub. Doing a test deployment will be fine with this setup. In case you want to deploy multiple times a day and fetch from the same IP address, you might run into rate limits at Docker Hub. In that case and in cases you prefer the use of a private image registry, you can configure such for -[your target environment](./../helmfile/environments/dev/values.yaml.gotmpl.sample) by setting +[your target environment](../helmfile/environments/dev/values.yaml.gotmpl.sample) by setting - `global.imageRegistry` for a private image registry and - `global.helmRegistry` for a private Helm chart registry. @@ -221,7 +221,7 @@ cluster: By default, the `ingressClassName` is empty to select your default ingress controller. You may want to customize it by setting the following attribute to the name of the currently only supported ingress controller `ingress-nginx` (see -[requirements.md](./requirements.md)) for reference) within your deployment if that is not the cluster's default ingress. +[requirements.md](requirements.md)) for reference) within your deployment if that is not the cluster's default ingress. ```yaml ingress: diff --git a/docs/migrations.md b/docs/migrations.md index 61b4d3ff..f016b298 100644 --- a/docs/migrations.md +++ b/docs/migrations.md @@ -24,6 +24,7 @@ SPDX-License-Identifier: Apache-2.0 * [Pre-upgrade: Manual steps](#pre-upgrade-manual-steps) * [Configuration Cleanup: Removal of unnecessary OX-Profiles in Nubus](#configuration-cleanup-removal-of-unnecessary-ox-profiles-in-nubus) * [Configuration Cleanup: Updated `global.imagePullSecrets`](#configuration-cleanup-updated-globalimagepullsecrets) + * [Changed openDesk defaults: Matrix presence status disabled](#changed-opendesk-defaults-matrix-presence-status-disabled) * [Changed openDesk defaults: Matrix ID](#changed-opendesk-defaults-matrix-id) * [Changed openDesk defaults: File-share configurability](#changed-opendesk-defaults-file-share-configurability) * [Changed openDesk defaults: Updated default subdomains in `global.hosts`](#changed-opendesk-defaults-updated-default-subdomains-in-globalhosts) @@ -285,6 +286,19 @@ global: - "external-registry" ``` +#### Changed openDesk defaults: Matrix presence status disabled + +Show other user's Matrix presence status is now disabled by default to comply with data protection requirements. + +To enable it or keep the v0.9.0 default please set: + +```yaml +functional: + dataProtection: + matrixPresence: + enabled: true +``` + #### Changed openDesk defaults: Matrix ID Until 0.9.0 openDesk used the LDAP entryUUID of a user to generate the user's Matrix ID. Due to restrictions on the diff --git a/helmfile/apps/notes/helmfile-child.yaml.gotmpl b/helmfile/apps/notes/helmfile-child.yaml.gotmpl new file mode 100644 index 00000000..60a359fe --- /dev/null +++ b/helmfile/apps/notes/helmfile-child.yaml.gotmpl @@ -0,0 +1,31 @@ +# SPDX-FileCopyrightText: 2024 Zentrum für Digitale Souveränität der Öffentlichen Verwaltung (ZenDiS) GmbH +# SPDX-License-Identifier: Apache-2.0 +--- +repositories: + # Notes + # Source: https://github.com/numerique-gouv/impress + - name: "notes-repo" + keyring: "../../files/gpg-pubkeys/opencode.gpg" + verify: {{ .Values.charts.notes.verify }} + username: {{ env "OD_PRIVATE_REGISTRY_USERNAME" | quote }} + password: {{ env "OD_PRIVATE_REGISTRY_PASSWORD" | quote }} + oci: true + url: "{{ .Values.global.helmRegistry | default .Values.charts.notes.registry }}/{{ .Values.charts.notes.repository }}" + +releases: + - name: "impress" + chart: "notes-repo/{{ .Values.charts.notes.name }}" + version: "{{ .Values.charts.notes.version }}" + wait: true + values: + - "values.yaml.gotmpl" + {{ range .Values.customization.release.notes }} + - {{ . }} + {{ end }} + installed: {{ .Values.notes.enabled }} + timeout: 1800 + +commonLabels: + deploy-stage: "component-1" + component: "notes" +... diff --git a/helmfile/apps/notes/helmfile.yaml.gotmpl b/helmfile/apps/notes/helmfile.yaml.gotmpl new file mode 100644 index 00000000..2021af07 --- /dev/null +++ b/helmfile/apps/notes/helmfile.yaml.gotmpl @@ -0,0 +1,11 @@ +# SPDX-FileCopyrightText: 2024 Zentrum für Digitale Souveränität der Öffentlichen Verwaltung (ZenDiS) GmbH +# SPDX-License-Identifier: Apache-2.0 +--- +bases: + - "../../bases/environments.yaml" +--- +helmfiles: + - path: "./helmfile-child.yaml.gotmpl" + values: + - {{ toYaml .Values | nindent 8 }} +... diff --git a/helmfile/apps/notes/values.yaml.gotmpl b/helmfile/apps/notes/values.yaml.gotmpl new file mode 100644 index 00000000..916e63b3 --- /dev/null +++ b/helmfile/apps/notes/values.yaml.gotmpl @@ -0,0 +1,230 @@ +{{/* +SPDX-FileCopyrightText: 2024 Zentrum für Digitale Souveränität der Öffentlichen Verwaltung (ZenDiS) GmbH +SPDX-License-Identifier: Apache-2.0 +*/}} +--- +image: + repository: {{ printf "%s/%s" (coalesce .Values.repositories.image.dockerHub .Values.global.imageRegistry .Values.images.notesBackend.registry) (.Values.images.notesBackend.repository) | quote }} + pullPolicy: {{ .Values.global.imagePullPolicy | quote }} + tag: {{ .Values.images.notesBackend.tag }} + credentials: + name: {{ .Values.global.imagePullSecrets | first | quote }} + +ingress: + enabled: {{ .Values.ingress.enabled }} + className: {{ .Values.ingress.ingressClassName }} + host: "{{ .Values.global.hosts.notes }}.{{ .Values.global.domain }}" + tls: + enabled: "{{ .Values.ingress.tls.enabled }}" + secretName: {{ .Values.ingress.tls.secretName | quote }} + +ingressCollaborationWS: + enabled: {{ .Values.ingress.enabled }} + className: {{ .Values.ingress.ingressClassName }} + host: "{{ .Values.global.hosts.notes }}.{{ .Values.global.domain }}" + path: "/collaboration/ws/" + tls: + enabled: "{{ .Values.ingress.tls.enabled }}" + secretName: {{ .Values.ingress.tls.secretName | quote }} + annotations: + nginx.ingress.kubernetes.io/auth-response-headers: "Authorization, X-Can-Edit, X-User-Id" + nginx.ingress.kubernetes.io/auth-url: https://{{ .Values.global.hosts.notes }}.{{ .Values.global.domain }}/api/v1.0/documents/collaboration-auth/ + nginx.ingress.kubernetes.io/enable-websocket: "true" + nginx.ingress.kubernetes.io/proxy-read-timeout: "86400" + nginx.ingress.kubernetes.io/proxy-send-timeout: "86400" + nginx.ingress.kubernetes.io/upstream-hash-by: $arg_room + +ingressAdmin: + enabled: {{ .Values.ingress.enabled }} + className: {{ .Values.ingress.ingressClassName }} + host: "{{ .Values.global.hosts.notes }}.{{ .Values.global.domain }}" + tls: + enabled: "{{ .Values.ingress.tls.enabled }}" + secretName: {{ .Values.ingress.tls.secretName | quote }} + +ingressMedia: + enabled: {{ .Values.ingress.enabled }} + className: {{ .Values.ingress.ingressClassName }} + host: "{{ .Values.global.hosts.notes }}.{{ .Values.global.domain }}" + annotations: + nginx.ingress.kubernetes.io/auth-response-headers: "Authorization, X-Amz-Date, X-Amz-Content-SHA256" + nginx.ingress.kubernetes.io/auth-url: "https://{{ .Values.global.hosts.notes }}.{{ .Values.global.domain }}/api/v1.0/documents/retrieve-auth/" + nginx.ingress.kubernetes.io/upstream-vhost: {{ .Values.objectstores.notes.endpoint | default (printf "%s.%s" .Values.global.hosts.minioApi .Values.global.domain) | quote }} + nginx.ingress.kubernetes.io/backend-protocol: "HTTPS" + nginx.ingress.kubernetes.io/use-regex: "true" + nginx.ingress.kubernetes.io/rewrite-target: /{{ .Values.objectstores.notes.bucket }}/$1 + nginx.ingress.kubernetes.io/session-cookie-path: /media + tls: + enabled: "{{ .Values.ingress.tls.enabled }}" + secretName: {{ .Values.ingress.tls.secretName | quote }} + +ingressCollaborationApi: + enabled: {{ .Values.ingress.enabled }} + className: {{ .Values.ingress.ingressClassName }} + host: "{{ .Values.global.hosts.notes }}.{{ .Values.global.domain }}" + path: /collaboration/api/ + tls: + enabled: "{{ .Values.ingress.tls.enabled }}" + secretName: {{ .Values.ingress.tls.secretName | quote }} + + +serviceMedia: + host: {{ .Values.objectstores.notes.endpoint | default (printf "%s.%s" .Values.global.hosts.minioApi .Values.global.domain) | quote }} + port: {{ .Values.objectstores.notes.port | default 443 }} + +frontend: + image: + repository: {{ printf "%s/%s" (coalesce .Values.repositories.image.registryOpencodeDe .Values.global.imageRegistry .Values.images.notesFrontend.registry) (.Values.images.notesFrontend.repository) | quote }} + pullPolicy: {{ .Values.global.imagePullPolicy | quote }} + tag: {{ .Values.images.notesFrontend.tag }} + envVars: + PORT: 8080 + NEXT_PUBLIC_API_ORIGIN: {{ printf "https://%s.%s" .Values.global.hosts.notes .Values.global.domain | quote }} + NEXT_PUBLIC_Y_PROVIDER_URL: {{ printf "wss://%s.%s/ws" .Values.global.hosts.notes .Values.global.domain | quote }} + NEXT_PUBLIC_MEDIA_URL: {{ .Values.objectstores.notes.endpoint | default (printf "https://%s.%s" .Values.global.hosts.minioApi .Values.global.domain) | quote }} + runtimeEnvs: + ICS_BASE_URL: {{ printf "https://%s.%s" .Values.global.hosts.intercomService .Values.global.domain | quote }} + PORTAL_BASE_URL: {{ printf "https://%s.%s" .Values.global.hosts.nubus .Values.global.domain | quote }} + replicas: {{ .Values.replicas.notesFrontend }} + resources: + {{ .Values.resources.notesFrontend | toYaml | nindent 4 }} + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - "ALL" + privileged: false + runAsUser: 1001 + runAsGroup: 1001 + seccompProfile: + type: "RuntimeDefault" + readOnlyRootFilesystem: true + runAsNonRoot: true + seLinuxOptions: + {{ .Values.seLinuxOptions.notesFrontend | toYaml | nindent 6 }} + +yProvider: + image: + repository: {{ printf "%s/%s" (coalesce .Values.repositories.image.dockerHub .Values.global.imageRegistry .Values.images.notesYProvider.registry) (.Values.images.notesYProvider.repository) | quote }} + pullPolicy: {{ .Values.global.imagePullPolicy | quote }} + tag: {{ .Values.images.notesYProvider.tag }} + resources: + {{ .Values.resources.notesYProvider | toYaml | nindent 4 }} + replicas: {{ .Values.replicas.notesYProvider }} + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - "ALL" + privileged: false + runAsUser: 1001 + runAsGroup: 1001 + seccompProfile: + type: "RuntimeDefault" + readOnlyRootFilesystem: true + runAsNonRoot: true + seLinuxOptions: + {{ .Values.seLinuxOptions.notesBackend | toYaml | nindent 6 }} + envVars: + COLLABORATION_LOGGING: {{ if .Values.debug.enabled }}"true"{{ else }}"false"{{ end }} + COLLABORATION_SERVER_ORIGIN: {{ printf "https://%s.%s" .Values.global.hosts.notes .Values.global.domain | quote }} + COLLABORATION_SERVER_SECRET: {{ .Values.secrets.notes.collaborationSecret | quote }} + Y_PROVIDER_API_KEY: {{ .Values.secrets.notes.collaborationSecret | quote }} + +oidc: + clientId: "opendesk-notes" + clientSecret: {{ .Values.secrets.keycloak.clientSecret.notes | quote }} + +aiApiKey: {{ .Values.ai.apiKey }} +aiBaseUrl: {{ .Values.ai.endpoint }} + +djangoSuperUserEmail: "default.admin@{{ .Values.global.domain }}" +djangoSuperUserPass: {{ .Values.secrets.notes.superuser }} +djangoSecretKey: {{ .Values.secrets.notes.djangoSecretKey }} + +backend: + replicas: {{ .Values.replicas.notesBackend }} + envVars: + DB_HOST: {{ .Values.databases.notes.host | quote }} + DB_NAME: {{ .Values.databases.notes.name | quote }} + DB_USER: {{ .Values.databases.notes.username | quote }} + DB_PASSWORD: {{ .Values.databases.notes.password | default .Values.secrets.postgresql.notesUser | quote }} + DB_PORT: {{ .Values.databases.notes.port | quote }} + POSTGRES_DB: {{ .Values.databases.notes.name | quote }} + POSTGRES_USER: {{ .Values.databases.notes.username | quote }} + POSTGRES_PASSWORD: {{ .Values.databases.notes.password | default .Values.secrets.postgresql.notesUser | quote }} + FRONTEND_THEME: "openDesk" + REDIS_URL: "redis://default:{{ .Values.cache.notes.password | default .Values.secrets.redis.password }}@{{ .Values.cache.notes.host }}:{{ .Values.cache.notes.port }}/7" + AWS_S3_ENDPOINT_URL: {{ .Values.objectstores.notes.endpoint | default (printf "https://%s.%s" .Values.global.hosts.minioApi .Values.global.domain) | quote }} + AWS_S3_ACCESS_KEY_ID: {{ .Values.objectstores.notes.username }} + AWS_S3_SECRET_ACCESS_KEY: {{ .Values.objectstores.notes.secretKey | default .Values.secrets.minio.notesUser | quote }} + AWS_STORAGE_BUCKET_NAME: {{ .Values.objectstores.notes.bucket }} + DJANGO_CSRF_TRUSTED_ORIGINS: {{ printf "https://%s.%s" .Values.global.hosts.notes .Values.global.domain | quote }} + DJANGO_CONFIGURATION: Production + DJANGO_ALLOWED_HOSTS: "*" + DJANGO_SECRET_KEY: {{ .Values.secrets.notes.djangoSecretKey }} + DJANGO_SETTINGS_MODULE: impress.settings + DJANGO_SUPERUSER_PASSWORD: {{ .Values.secrets.notes.superuser }} + DJANGO_EMAIL_HOST: "postfix" + DJANGO_EMAIL_PORT: 25 + DJANGO_EMAIL_USE_SSL: False + OIDC_RP_CLIENT_ID: "opendesk-notes" + OIDC_RP_CLIENT_SECRET: {{ .Values.secrets.keycloak.clientSecret.notes | quote }} + OIDC_OP_JWKS_ENDPOINT: "https://{{ .Values.global.hosts.keycloak }}.{{ .Values.global.domain }}/realms/{{ .Values.platform.realm }}/protocol/openid-connect/certs" + OIDC_OP_AUTHORIZATION_ENDPOINT: "https://{{ .Values.global.hosts.keycloak }}.{{ .Values.global.domain }}/realms/{{ .Values.platform.realm }}/protocol/openid-connect/auth" + OIDC_OP_TOKEN_ENDPOINT: "https://{{ .Values.global.hosts.keycloak }}.{{ .Values.global.domain }}/realms/{{ .Values.platform.realm }}/protocol/openid-connect/token" + OIDC_OP_USER_ENDPOINT: "https://{{ .Values.global.hosts.keycloak }}.{{ .Values.global.domain }}/realms/{{ .Values.platform.realm }}/protocol/openid-connect/userinfo" + OIDC_OP_LOGOUT_ENDPOINT: "https://{{ .Values.global.hosts.keycloak }}.{{ .Values.global.domain }}/realms/{{ .Values.platform.realm }}/protocol/openid-connect/logout" + OIDC_RP_SIGN_ALGO: RS256 + OIDC_RP_SCOPES: "openid opendesk-notes-scope" + USER_OIDC_FIELD_TO_SHORTNAME: "given_name" + USER_OIDC_FIELDS_TO_FULLNAME: "given_name family_name" + OIDC_REDIRECT_ALLOWED_HOSTS: {{ printf "https://%s.%s/*" .Values.global.hosts.notes .Values.global.domain | quote }} + OIDC_AUTH_REQUEST_EXTRA_PARAMS: "{}" + OIDC_RENEW_ID_TOKEN: "False" + LOGIN_REDIRECT_URL: {{ printf "https://%s.%s" .Values.global.hosts.notes .Values.global.domain | quote }} + LOGIN_REDIRECT_URL_FAILURE: {{ printf "https://%s.%s" .Values.global.hosts.nubus .Values.global.domain | quote }} + LOGOUT_REDIRECT_URL: {{ printf "https://%s.%s" .Values.global.hosts.nubus .Values.global.domain | quote }} + AI_BASE_URL: {{ .Values.ai.endpoint | quote }} + AI_API_KEY: {{ .Values.ai.apiKey | quote }} + AI_MODEL: {{ .Values.ai.model | quote }} + Y_PROVIDER_API_KEY: {{ .Values.secrets.notes.collaborationSecret | quote }} + Y_PROVIDER_API_BASE_URL: {{ printf "https://%s.%s/api/" .Values.global.hosts.notes .Values.global.domain | quote }} + COLLABORATION_API_URL: {{ printf "https://%s.%s/collaboration/api/" .Values.global.hosts.notes .Values.global.domain | quote }} + COLLABORATION_SERVER_ORIGIN: {{ printf "https://%s.%s" .Values.global.hosts.notes .Values.global.domain | quote }} + COLLABORATION_SERVER_SECRET: {{ .Values.secrets.notes.collaborationSecret | quote }} + COLLABORATION_WS_URL: {{ printf "wss://%s.%s/collaboration/ws/" .Values.global.hosts.notes .Values.global.domain | quote }} + migrate: + command: + - "/bin/sh" + - "-c" + - | + python manage.py migrate --no-input && + python manage.py create_demo --force + restartPolicy: Never + + createsuperuser: + command: + - "/bin/sh" + - "-c" + - | + python manage.py createsuperuser --email default.admin@{{ .Values.global.domain }} --password {{ .Values.secrets.notes.superuser }} + restartPolicy: Never + + resources: + {{ .Values.resources.notesBackend | toYaml | nindent 4 }} + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - "ALL" + privileged: false + runAsUser: 1001 + runAsGroup: 1001 + seccompProfile: + type: "RuntimeDefault" + readOnlyRootFilesystem: true + runAsNonRoot: true + seLinuxOptions: + {{ .Values.seLinuxOptions.notesBackend | toYaml | nindent 6 }} +... diff --git a/helmfile/apps/nubus/values-nubus.yaml.gotmpl b/helmfile/apps/nubus/values-nubus.yaml.gotmpl index 2e4030d5..4ec97c8d 100644 --- a/helmfile/apps/nubus/values-nubus.yaml.gotmpl +++ b/helmfile/apps/nubus/values-nubus.yaml.gotmpl @@ -442,9 +442,12 @@ nubusStackDataUms: portalManagementKnowledgeLinkBase: {{ printf "https://%s.%s" .Values.global.hosts.xwiki .Values.global.domain }} portalGroupwareLinkBase: {{ printf "https://%s.%s" .Values.global.hosts.openxchange .Values.global.domain }} portalFileshareLinkBase: {{ printf "https://%s.%s" .Values.global.hosts.nextcloud .Values.global.domain }} + portalNotesLinkBase: {{ printf "https://%s.%s" .Values.global.hosts.notes .Values.global.domain }} portalTitleDE: "openDesk Portal" portalTitleEN: "openDesk Portal" oxDefaultContext: "1" + componentEnabled: + notes: {{ .Values.notes.enabled }} ldapSearchUsers: {{- range $username, $password := .Values.secrets.nubus.ldapSearch }} - username: {{ printf "ldapsearch_%s" $username | quote }} @@ -454,7 +457,6 @@ nubusStackDataUms: ldapSystemUsers: [] portaltileGroupUserStandard: - 'cn=Domain Users,cn=groups,{{ .Values.ldap.baseDn }}' - - 'cn=Domain Users,cn=groups,{{ .Values.ldap.baseDn }}' portaltileGroupUserAdmin: - 'cn=Domain Admins,cn=groups,{{ .Values.ldap.baseDn }}' - 'cn=Support,cn=groups,{{ .Values.ldap.baseDn }}' @@ -475,6 +477,8 @@ nubusStackDataUms: - 'cn=managed-by-attribute-Livecollaboration,cn=groups,{{ .Values.ldap.baseDn }}' portaltileGroupVideoconference: - 'cn=managed-by-attribute-Videoconference,cn=groups,{{ .Values.ldap.baseDn }}' + portaltileGroupNotes: + - 'cn=managed-by-attribute-Notes,cn=groups,{{ .Values.ldap.baseDn }}' systemInformation: releaseVersion: "Release: {{ .Values.global.systemInformation.releaseVersion }}" {{- if .Values.functional.admin.portal.deploymentTimestamp.enabled }} diff --git a/helmfile/apps/nubus/values-opendesk-keycloak-bootstrap.yaml.gotmpl b/helmfile/apps/nubus/values-opendesk-keycloak-bootstrap.yaml.gotmpl index 308c67f7..f118186e 100644 --- a/helmfile/apps/nubus/values-opendesk-keycloak-bootstrap.yaml.gotmpl +++ b/helmfile/apps/nubus/values-opendesk-keycloak-bootstrap.yaml.gotmpl @@ -21,6 +21,8 @@ cleanup: keepPVCOnDelete: {{ .Values.debug.cleanup.keepPVCOnDelete }} config: + componentEnabled: + notes: {{ .Values.notes.enabled }} custom: clientScopes: {{ .Values.functional.authentication.oidc.clientScopes | toYaml | nindent 6 }} @@ -42,7 +44,6 @@ config: # We use client specific scopes as we bind them to Keycloak role membership which itself is linked # to LDAP group membership to ensure a user cannot access an application without the required # group membership. - # ToDo: Ensure all applications verify the token's signature to ensure it is not tampered. clientScopes: - name: "read_contacts" protocol: "openid-connect" @@ -374,6 +375,48 @@ config: access.token.claim: true claim.name: "opendesk_username" jsonType.label: "String" +{{ if .Values.notes.enabled }} + - name: "opendesk-notes-scope" + description: "Scope for the claims required by openDesk's Notes instance." + protocol: "openid-connect" + protocolMappers: + - name: "email" + protocol: "openid-connect" + protocolMapper: "oidc-usermodel-attribute-mapper" + consentRequired: false + config: + introspection.token.claim: true + userinfo.token.claim: true + user.attribute: "email" + id.token.claim: true + access.token.claim: true + claim.name: "email" + jsonType.label: "String" + - name: "given name" + protocol: "openid-connect" + protocolMapper: "oidc-usermodel-attribute-mapper" + consentRequired: false + config: + introspection.token.claim: true + userinfo.token.claim: true + user.attribute: "firstName" + id.token.claim: true + access.token.claim: true + claim.name: "given_name" + jsonType.label: "String" + - name: "family name" + protocol: "openid-connect" + protocolMapper: "oidc-usermodel-attribute-mapper" + consentRequired: false + config: + introspection.token.claim: true + userinfo.token.claim: true + user.attribute: "lastName" + id.token.claim: true + access.token.claim: true + claim.name: "family_name" + jsonType.label: "String" +{{ end }} clients: - name: "opendesk-intercom" clientId: "opendesk-intercom" @@ -440,6 +483,45 @@ config: jsonType.label: "String" defaultClientScopes: - "offline_access" +{{ if .Values.notes.enabled }} + - name: "opendesk-notes" + clientId: "opendesk-notes" + protocol: "openid-connect" + clientAuthenticatorType: "client-secret" + secret: {{ .Values.secrets.keycloak.clientSecret.notes | quote }} + redirectUris: + - "https://{{ .Values.global.hosts.notes }}.{{ .Values.global.domain }}/api/v1.0/callback/" + standardFlowEnabled: true + implicitFlowEnabled: false + alwaysDisplayInConsole: false + bearerOnly: false + directAccessGrantsEnabled: true + serviceAccountsEnabled: false + consentRequired: false + frontchannelLogout: false + publicClient: false + authorizationServicesEnabled: false + surrogateAuthRequired: false + attributes: + backchannel.logout.revoke.offline.tokens: false + backchannel.logout.session.required: false + client.introspection.response.allow.jwt.claim.enabled: false + client.use.lightweight.access.token.enabled: false + client_credentials.use_refresh_token: false + display.on.consent.screen: false + oauth2.device.authorization.grant.enabled: false + oidc.ciba.grant.enabled: false + post.logout.redirect.uris: "https://{{ .Values.global.hosts.nubus }}.{{ .Values.global.domain }}/*##https://{{ .Values.global.hosts.notes }}.{{ .Values.global.domain }}/*" + require.pushed.authorization.requests: false + tls.client.certificate.bound.access.tokens: false + token.response.type.bearer.lower-case: false + use.jwks.url: false + use.refresh.tokens: false + # it is probably not even required to set this value explicitly. + user.info.response.signature.alg: "RS256" + defaultClientScopes: + - "opendesk-notes-scope" +{{ end }} - name: "opendesk-dovecot" clientId: "opendesk-dovecot" protocol: "openid-connect" diff --git a/helmfile/apps/services-external/values-minio.yaml.gotmpl b/helmfile/apps/services-external/values-minio.yaml.gotmpl index 1f5595de..0d196178 100644 --- a/helmfile/apps/services-external/values-minio.yaml.gotmpl +++ b/helmfile/apps/services-external/values-minio.yaml.gotmpl @@ -99,6 +99,9 @@ provisioning: - name: {{ .Values.objectstores.nextcloud.bucket | quote }} versioning: true withLock: false + - name: {{ .Values.objectstores.notes.bucket | quote }} + versioning: true + withLock: false - name: {{ .Values.objectstores.openproject.bucket | quote }} versioning: true withLock: false @@ -130,6 +133,18 @@ provisioning: effect: "Allow" actions: - "s3:*" + - name: "notes-bucket-policy" + statements: + - resources: + - "arn:aws:s3:::notes" + effect: "Allow" + actions: + - "s3:*" + - resources: + - "arn:aws:s3:::notes/*" + effect: "Allow" + actions: + - "s3:*" - name: "openproject-bucket-policy" statements: - resources: @@ -167,6 +182,12 @@ provisioning: policies: - "nextcloud-bucket-policy" setPolicies: true + - username: {{ .Values.objectstores.notes.username | quote }} + password: {{ .Values.secrets.minio.notesUser | quote }} + disabled: false + policies: + - "notes-bucket-policy" + setPolicies: true - username: {{ .Values.objectstores.openproject.username | quote }} password: {{ .Values.secrets.minio.openprojectUser | quote }} disabled: false diff --git a/helmfile/apps/services-external/values-postgresql.yaml.gotmpl b/helmfile/apps/services-external/values-postgresql.yaml.gotmpl index 7ba5ed09..8a26fd9a 100644 --- a/helmfile/apps/services-external/values-postgresql.yaml.gotmpl +++ b/helmfile/apps/services-external/values-postgresql.yaml.gotmpl @@ -48,6 +48,9 @@ job: - username: {{ .Values.databases.keycloak.username | quote }} password: {{ .Values.secrets.postgresql.keycloakUser | quote }} connectionLimit: {{ .Values.databases.keycloak.connectionLimit | default .Values.databases.defaults.userConnectionLimit }} + - username: {{ .Values.databases.notes.username | quote }} + password: {{ .Values.secrets.postgresql.notesUser | quote }} + connectionLimit: {{ .Values.databases.notes.connectionLimit | default .Values.databases.defaults.userConnectionLimit }} - username: {{ .Values.databases.openproject.username | quote }} password: {{ .Values.secrets.postgresql.openprojectUser | quote }} connectionLimit: {{ .Values.databases.openproject.connectionLimit | default .Values.databases.defaults.userConnectionLimit }} @@ -71,6 +74,8 @@ job: user: {{ .Values.databases.keycloak.username | quote }} - name: {{ .Values.databases.keycloakExtension.name | quote }} user: {{ .Values.databases.keycloakExtension.username | quote }} + - name: {{ .Values.databases.notes.name | quote }} + user: {{ .Values.databases.notes.username | quote }} - name: {{ .Values.databases.openproject.name | quote }} user: {{ .Values.databases.openproject.username | quote }} - name: {{ .Values.databases.synapse.name | quote }} diff --git a/helmfile/environments/default/ai.yaml.gotmpl b/helmfile/environments/default/ai.yaml.gotmpl new file mode 100644 index 00000000..577a665e --- /dev/null +++ b/helmfile/environments/default/ai.yaml.gotmpl @@ -0,0 +1,8 @@ +# SPDX-FileCopyrightText: 2024 Zentrum für Digitale Souveränität der Öffentlichen Verwaltung (ZenDiS) GmbH +# SPDX-License-Identifier: Apache-2.0 +--- +ai: + endpoint: "" + apiKey: "" + model: "" +... diff --git a/helmfile/environments/default/cache.yaml.gotmpl b/helmfile/environments/default/cache.yaml.gotmpl index 3de72787..e445490d 100644 --- a/helmfile/environments/default/cache.yaml.gotmpl +++ b/helmfile/environments/default/cache.yaml.gotmpl @@ -13,6 +13,10 @@ cache: username: "default" password: "" tls: false + notes: + host: "redis-headless" + port: 6379 + password: "" openproject: host: "memcached" port: 11211 diff --git a/helmfile/environments/default/charts.yaml.gotmpl b/helmfile/environments/default/charts.yaml.gotmpl index 0203c0ef..29550058 100644 --- a/helmfile/environments/default/charts.yaml.gotmpl +++ b/helmfile/environments/default/charts.yaml.gotmpl @@ -281,6 +281,16 @@ charts: name: "nginx-s3-gateway" version: "1.0.1" verify: true + notes: + # providerCategory: "Supplier" + # providerResponsible: "openDesk" + # upstreamRegistry: "https://gitlab.opencode.de" + # packageName=bmi/opendesk/components/supplier/dinum/charts/notes + registry: "registry.opencode.de" + repository: "bmi/opendesk/components/supplier/dinum/charts/notes" + name: "impress" + version: "2.0.0" + verify: true nubus: # providerCategory: "Supplier" # providerResponsible: "Univention" @@ -321,7 +331,7 @@ charts: registry: "registry.opencode.de" repository: "bmi/opendesk/components/platform-development/charts/opendesk-keycloak-bootstrap" name: "opendesk-keycloak-bootstrap" - version: "2.1.4" + version: "2.2.0" verify: true openproject: # providerCategory: "Supplier" diff --git a/helmfile/environments/default/customization.yaml.gotmpl b/helmfile/environments/default/customization.yaml.gotmpl index 67ffd038..2a9e0e9f 100644 --- a/helmfile/environments/default/customization.yaml.gotmpl +++ b/helmfile/environments/default/customization.yaml.gotmpl @@ -34,6 +34,8 @@ customization: # nextcloud opendeskNextcloudManagement: {} opendeskNextcloud: {} + # notes + notes: {} # nubus ums: {} intercomService: {} diff --git a/helmfile/environments/default/database.yaml.gotmpl b/helmfile/environments/default/database.yaml.gotmpl index fa6d7cfa..8550b538 100644 --- a/helmfile/environments/default/database.yaml.gotmpl +++ b/helmfile/environments/default/database.yaml.gotmpl @@ -25,6 +25,13 @@ databases: username: "nextcloud_user" password: "" connectionLimit: ~ + notes: + name: "notes" + host: "postgresql" + port: 5432 + username: "notes_user" + password: "" + connectionLimit: ~ openproject: name: "openproject" host: "postgresql" diff --git a/helmfile/environments/default/global.yaml.gotmpl b/helmfile/environments/default/global.yaml.gotmpl index cd6656d6..bc8cac76 100644 --- a/helmfile/environments/default/global.yaml.gotmpl +++ b/helmfile/environments/default/global.yaml.gotmpl @@ -44,6 +44,7 @@ global: minioApi: "objectstore" minioConsole: "objectstore-ui" nextcloud: "files" + notes: "notes" nubus: "portal" openproject: "projects" openxchange: "webmail" diff --git a/helmfile/environments/default/images.yaml.gotmpl b/helmfile/environments/default/images.yaml.gotmpl index 00afd13e..98dba65f 100644 --- a/helmfile/environments/default/images.yaml.gotmpl +++ b/helmfile/environments/default/images.yaml.gotmpl @@ -252,6 +252,36 @@ images: registry: "registry-1.docker.io" repository: "nginxinc/nginx-s3-gateway" tag: "unprivileged-oss-20241111@sha256:20d6b6ec5fc987b18c3e345de33674374a8335c593d6d0841ac64eb49ae2dea4" + notesBackend: + # providerCategory: "Supplier" + # providerResponsible: "DINUM" + # upstreamRegistry: "https://registry-1.docker.io" + # upstreamRepository: "lasuite/impress-backend" + # upstreamMirrorTagFilterRegEx: '^v(\d+)\.(\d+)\.(\d+)\$' + # upstreamMirrorStartFrom: ["1", "7", "0"] + registry: "registry-1.docker.io" + repository: "lasuite/impress-backend" + tag: "v1.10.0-docs-production@sha256:62f31bf18335fec031f9ea3af828b84a8bb811793b63bc1c484e4ce14d437198" + notesFrontend: + # providerCategory: "Supplier" + # providerResponsible: "DINUM" + # upstreamRegistry: "https://registry-1.docker.io" + # upstreamRepository: "lasuite/impress-frontend" + # upstreamMirrorTagFilterRegEx: '^v(\d+)\.(\d+)\.(\d+)\$' + # upstreamMirrorStartFrom: ["1", "7", "0"] + registry: "registry.opencode.de" + repository: "bmi/opendesk/components/platform-development/images/opendesk-notes" + tag: "1.5.1@sha256:dad7dd60a5eb39b71b4911558cf7eac9ed6dc050593a046f5da0eaa75c65d344" + notesYProvider: + # providerCategory: "Supplier" + # providerResponsible: "DINUM" + # upstreamRegistry: "https://registry-1.docker.io" + # upstreamRepository: "lasuite/impress-y-provider" + # upstreamMirrorTagFilterRegEx: '^v(\d+)\.(\d+)\.(\d+)\$' + # upstreamMirrorStartFrom: ["1", "7", "0"] + registry: "registry-1.docker.io" + repository: "lasuite/impress-y-provider" + tag: "v1.10.0-docs-production@sha256:9fcdb1fe7b20f0026b94765d64d83a2fe76cbe6e59c43d098fa21a7ea0c74803" nubusDataLoader: # providerCategory: "Supplier" # providerResponsible: "Univention" @@ -421,7 +451,7 @@ images: # upstreamRepository: "bmi/opendesk/components/platform-development/images/opendesk-nubus" registry: "registry.opencode.de" repository: "bmi/opendesk/components/platform-development/images/opendesk-nubus" - tag: "1.8.2-trossner-nubus1-3@sha256:d8d7d851233e1360968417844c73b1b3822b4e8876194fd4dc3088112c66530a" + tag: "1.9.0@sha256:1a84ae2f21849934d3ff24c066fce21c4bc811521b615cc0071432d3fb1848c1" nubusOpenPolicyAgent: # providerCategory: "Supplier" # providerResponsible: "Univention" diff --git a/helmfile/environments/default/objectstores.yaml.gotmpl b/helmfile/environments/default/objectstores.yaml.gotmpl index ac98652d..a5a96cc4 100644 --- a/helmfile/environments/default/objectstores.yaml.gotmpl +++ b/helmfile/environments/default/objectstores.yaml.gotmpl @@ -23,6 +23,12 @@ objectstores: useSSL: true pathStyle: true port: 443 + notes: + bucket: "notes" + endpoint: "" + secretKey: "" + username: "notes_user" + port: 443 openproject: bucket: "openproject" directUploads: true diff --git a/helmfile/environments/default/opendesk_main.yaml.gotmpl b/helmfile/environments/default/opendesk_main.yaml.gotmpl index e5e9d19e..e8310664 100644 --- a/helmfile/environments/default/opendesk_main.yaml.gotmpl +++ b/helmfile/environments/default/opendesk_main.yaml.gotmpl @@ -49,6 +49,9 @@ minio: nextcloud: enabled: true namespace: ~ +notes: + enabled: false + namespace: ~ nubus: enabled: true namespace: ~ diff --git a/helmfile/environments/default/replicas.yaml.gotmpl b/helmfile/environments/default/replicas.yaml.gotmpl index a6bf6c57..998d7f78 100644 --- a/helmfile/environments/default/replicas.yaml.gotmpl +++ b/helmfile/environments/default/replicas.yaml.gotmpl @@ -191,4 +191,12 @@ replicas: # -- component: Knowledge management (XWiki) # -- scalable: false xwiki: 1 + + # -- component: Note taking (Notes) + # -- scalable: true + notesBackend: 1 + # -- scalable: true + notesFrontend: 1 + # -- scalable: true + notesYProvider: 1 ... diff --git a/helmfile/environments/default/resources.yaml.gotmpl b/helmfile/environments/default/resources.yaml.gotmpl index 49cb1a62..d08b60fc 100644 --- a/helmfile/environments/default/resources.yaml.gotmpl +++ b/helmfile/environments/default/resources.yaml.gotmpl @@ -106,6 +106,27 @@ resources: requests: cpu: 0.1 memory: "384Mi" + notesBackend: + limits: + cpu: 99 + memory: "768Mi" + requests: + cpu: 0.1 + memory: "512Mi" + notesFrontend: + limits: + cpu: 99 + memory: "128Mi" + requests: + cpu: 0.1 + memory: "32Mi" + notesYProvider: + limits: + cpu: 99 + memory: "256Mi" + requests: + cpu: 0.1 + memory: "128Mi" opendeskKeycloakBootstrap: limits: cpu: 99 diff --git a/helmfile/environments/default/secrets.yaml.gotmpl b/helmfile/environments/default/secrets.yaml.gotmpl index e9eb5bc1..8dbe6935 100644 --- a/helmfile/environments/default/secrets.yaml.gotmpl +++ b/helmfile/environments/default/secrets.yaml.gotmpl @@ -59,6 +59,7 @@ secrets: keycloakUser: {{ derivePassword 1 "long" (env "MASTER_PASSWORD" | default "sovereign-workplace") "postgres" "keycloak_user" | sha1sum | quote }} keycloakExtensionUser: {{ derivePassword 1 "long" (env "MASTER_PASSWORD" | default "sovereign-workplace") "postgres" "keycloak_extensions_user" | sha1sum | quote }} matrixUser: {{ derivePassword 1 "long" (env "MASTER_PASSWORD" | default "sovereign-workplace") "postgres" "matrix_user" | sha1sum | quote }} + notesUser: {{ derivePassword 1 "long" (env "MASTER_PASSWORD" | default "sovereign-workplace") "postgres" "notes_user" | sha1sum | quote }} openprojectUser: {{ derivePassword 1 "long" (env "MASTER_PASSWORD" | default "sovereign-workplace") "postgres" "openproject_user" | sha1sum | quote }} umsNotificationsApiUser: {{ derivePassword 1 "long" (env "MASTER_PASSWORD" | default "sovereign-workplace") "postgres" "notificationsapi_user" | sha1sum | quote }} umsGuardianManagementApiUser: {{ derivePassword 1 "long" (env "MASTER_PASSWORD" | default "sovereign-workplace") "postgres" "guardianmanagementapi_user" | sha1sum | quote }} @@ -72,6 +73,7 @@ secrets: rootPassword: {{ (derivePassword 1 "long" (env "MASTER_PASSWORD" | default "sovereign-workplace") "minio" "root_password" | sha1sum | quote) }} migrationsUser: {{ (derivePassword 1 "long" (env "MASTER_PASSWORD" | default "sovereign-workplace") "minio" "migrations_user" | sha1sum | quote) }} nextcloudUser: {{ (derivePassword 1 "long" (env "MASTER_PASSWORD" | default "sovereign-workplace") "minio" "nextcloud_user" | sha1sum | quote) }} + notesUser: {{ (derivePassword 1 "long" (env "MASTER_PASSWORD" | default "sovereign-workplace") "minio" "notes_user" | sha1sum | quote) }} openprojectUser: {{ (derivePassword 1 "long" (env "MASTER_PASSWORD" | default "sovereign-workplace") "minio" "openproject_user" | sha1sum | quote) }} umsUser: {{ (derivePassword 1 "long" (env "MASTER_PASSWORD" | default "sovereign-workplace") "minio" "ums_user" | sha1sum | quote) }} keycloak: @@ -80,12 +82,14 @@ secrets: dovecot: {{ derivePassword 1 "long" (env "MASTER_PASSWORD" | default "sovereign-workplace") "keycloak" "dovecot_client_secret" | sha1sum | quote }} intercom: {{ derivePassword 1 "long" (env "MASTER_PASSWORD" | default "sovereign-workplace") "keycloak" "intercom_client_secret" | sha1sum | quote }} matrix: {{ derivePassword 1 "long" (env "MASTER_PASSWORD" | default "sovereign-workplace") "keycloak" "matrix_client_secret" | sha1sum | quote }} + notes: {{ derivePassword 1 "long" (env "MASTER_PASSWORD" | default "sovereign-workplace") "keycloak" "notes_client_secret" | sha1sum | quote }} jitsi: {{ derivePassword 1 "long" (env "MASTER_PASSWORD" | default "sovereign-workplace") "keycloak" "jitsi_plain_client_secret" | sha1sum | quote }} ncoidc: {{ derivePassword 1 "long" (env "MASTER_PASSWORD" | default "sovereign-workplace") "keycloak" "ncoidc_client_secret" | sha1sum | quote }} openproject: {{ derivePassword 1 "long" (env "MASTER_PASSWORD" | default "sovereign-workplace") "keycloak" "openproject_client_secret" | sha1sum | quote }} xwiki: {{ derivePassword 1 "long" (env "MASTER_PASSWORD" | default "sovereign-workplace") "keycloak" "xwiki_client_secret" | sha1sum | quote }} as8oidc: {{ derivePassword 1 "long" (env "MASTER_PASSWORD" | default "sovereign-workplace") "keycloak" "as8oidc_client_secret" | sha1sum | quote }} guardian: {{ derivePassword 1 "long" (env "MASTER_PASSWORD" | default "sovereign-workplace") "keycloak" "guardian_client_secret" | sha1sum | quote }} + notes: {{ derivePassword 1 "long" (env "MASTER_PASSWORD" | default "sovereign-workplace") "keycloak" "notes_client_secret" | sha1sum | quote }} nextcloud: adminPassword: {{ derivePassword 1 "long" (env "MASTER_PASSWORD" | default "sovereign-workplace") "nextcloud" "nextcloud_admin_user" | sha1sum | quote }} metricsToken: {{ derivePassword 1 "long" (env "MASTER_PASSWORD" | default "sovereign-workplace") "nextcloud" "metricsToken" | sha1sum | quote }} @@ -121,4 +125,8 @@ secrets: password: {{ derivePassword 1 "long" (env "MASTER_PASSWORD" | default "sovereign-workplace") "matrix-user-verification-service" "password" | sha1sum | quote }} certificates: password: {{ derivePassword 1 "long" (env "MASTER_PASSWORD" | default "sovereign-workplace") "certificates" "password" | sha1sum | quote }} + notes: + djangoSecretKey: {{ derivePassword 1 "long" (env "MASTER_PASSWORD" | default "sovereign-workplace") "notes" "djangoSecretKey" | sha256sum | quote }} + superuser: {{ derivePassword 1 "long" (env "MASTER_PASSWORD" | default "sovereign-workplace") "notes" "superuser" | sha1sum | quote }} + collaborationSecret: {{ derivePassword 1 "long" (env "MASTER_PASSWORD" | default "sovereign-workplace") "notes" "collaborationSecret" | sha1sum | quote }} ... diff --git a/helmfile/environments/default/selinux.yaml.gotmpl b/helmfile/environments/default/selinux.yaml.gotmpl index 11c40566..4b5ae0e5 100644 --- a/helmfile/environments/default/selinux.yaml.gotmpl +++ b/helmfile/environments/default/selinux.yaml.gotmpl @@ -37,6 +37,9 @@ seLinuxOptions: nextcloud: ~ nextcloudExporter: ~ nextcloudManagement: ~ + notesBackend: ~ + notesFrontend: ~ + notesYProvider: ~ opendeskKeycloakBootstrap: ~ openproject: ~ openprojectBootstrap: ~ diff --git a/helmfile/environments/default/theme.yaml.gotmpl b/helmfile/environments/default/theme.yaml.gotmpl index 450a9807..6a64a0f0 100644 --- a/helmfile/environments/default/theme.yaml.gotmpl +++ b/helmfile/environments/default/theme.yaml.gotmpl @@ -72,6 +72,7 @@ theme: groupwareTasks: {{ readFile "./../../files/portal-tiles/groupware_tasks.svg" | b64enc | quote }} managementKnowledge: {{ readFile "./../../files/portal-tiles/management_knowledge.svg" | b64enc | quote }} managementProject: {{ readFile "./../../files/portal-tiles/management_project.svg" | b64enc | quote }} + notes: {{ readFile "./../../files/portal-tiles/misc_notes.svg" | b64enc | quote }} realtimeCollaboration: {{ readFile "./../../files/portal-tiles/realtime_collaboration.svg" | b64enc | quote }} realtimeVideoconference: {{ readFile "./../../files/portal-tiles/realtime_videoconference.svg" | b64enc | quote }} selfserviceChangepassword: {{ readFile "./../../files/portal-tiles/selfservice_changepassword.svg" | b64enc | quote }} diff --git a/helmfile/files/portal-tiles/misc_notes.svg b/helmfile/files/portal-tiles/misc_notes.svg new file mode 100644 index 00000000..8e4821d8 --- /dev/null +++ b/helmfile/files/portal-tiles/misc_notes.svg @@ -0,0 +1,16 @@ + + + + + + + + \ No newline at end of file diff --git a/helmfile/files/theme/portalStylesheet.css b/helmfile/files/theme/portalStylesheet.css index 3a0e7efa..fc033cb5 100644 --- a/helmfile/files/theme/portalStylesheet.css +++ b/helmfile/files/theme/portalStylesheet.css @@ -97,6 +97,41 @@ --login-logo: url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz48c3ZnIGlkPSJFYmVuZV8xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA2OTMuMjUgMjE0LjAyIj4gPGRlZnM+IDxzdHlsZT4gLmNscy0xIHsgZmlsbDogIzU3MWVmYTsgfSAuY2xzLTIgeyBmaWxsOiAjOTI3YWZhOyB9IDwvc3R5bGU+IDwvZGVmcz4gPGc+IDxwYXRoIGNsYXNzPSJjbHMtMiIgZD0iTTEyNi4xNCwxNDAuMzJ2Mi4xM2MwLDguOTktNy4zMSwxNi4zLTE2LjMsMTYuM2gtMzguMjZjLTguOTksMC0xNi4zLTcuMzEtMTYuMy0xNi4zdi0zOC4yNmMwLTguOTksNy4zMS0xNi4zLDE2LjMtMTYuM2gyLjEzdjUyLjQ0aDUyLjQ0WiIvPiA8cGF0aCBjbGFzcz0iY2xzLTEiIGQ9Ik0xMjYuODUsMTI3LjU2aC00MC4zOXYtNDQuNjVjMC0xNS4yNCwxMi40LTI3LjY0LDI3LjY0LTI3LjY0aDEyLjc2YzE3LjU4LDAsMzEuODksMTQuMzEsMzEuODksMzEuODl2OC41YzAsMTcuNTgtMTQuMzEsMzEuODktMzEuODksMzEuODlaTTEwNC44OCwxMDkuMTNoMjEuOTdjNy40MiwwLDEzLjQ2LTYuMDQsMTMuNDYtMTMuNDZ2LTguNWMwLTcuNDItNi4wNC0xMy40Ni0xMy40Ni0xMy40NmgtMTIuNzZjLTUuMDgsMC05LjIxLDQuMTMtOS4yMSw5LjIxdjI2LjIyWiIvPiA8L2c+IDxnPiA8cGF0aCBkPSJNMjEwLjgyLDkwLjc2YzE0Ljg1LDAsMjQuMzQsMTAuOSwyNC4zNCwyNC4yNXMtOS40OSwyNC4yNS0yNC4zNCwyNC4yNS0yNC40NC0xMC45LTI0LjQ0LTI0LjI1LDkuNDktMjQuMjUsMjQuNDQtMjQuMjVaTTIxMC44MiwxMzMuMzRjMTEuMzcsMCwxNy4zOS04LjQ2LDE3LjM5LTE4LjMzcy02LjAyLTE4LjMzLTE3LjM5LTE4LjMzLTE3LjQ4LDguNDYtMTcuNDgsMTguMzMsNi4wMSwxOC4zMywxNy40OCwxOC4zM1oiLz4gPHBhdGggZD0iTTI0NC4xOSw5MS43aDYuOTZ2MTEuODRjMy4yOS03LjgsMTAuMjUtMTIuNzgsMjAuNC0xMi43OCwxMy4wNywwLDIxLjksOS44NywyMS45LDI0LjM0cy04LjgzLDI0LjE2LTIxLjksMjQuMTZjLTEwLjM0LDAtMTcuMi01LjE3LTIwLjQtMTIuNzh2MjguOTVoLTYuOTZ2LTYzLjczWk0yNjkuMzgsMTMzLjM0YzkuNCwwLDE3LjExLTUuODMsMTcuMTEtMTguMjRzLTcuNzEtMTguNDItMTcuMTEtMTguNDItMTcuOTUsNi4xMS0xNy45NSwxOC40Miw4LjY1LDE4LjI0LDE3Ljk1LDE4LjI0WiIvPiA8cGF0aCBkPSJNMzIyLjk2LDkwLjc2YzEzLjM1LDAsMjIuMjgsOC4zNywyMi4yOCwyMi42NXYyLjgyaC0zNy41Yy4yOCw5Ljc4LDUuMjYsMTcuMjksMTUuNiwxNy4yOSw4LjU1LDAsMTMuNTQtNC41MSwxNS4yMy0xMS40N2g2Ljg2Yy0xLjk3LDguMjctNy42MSwxNy4yLTIxLjksMTcuMi0xNS4xMywwLTIyLjQ2LTExLjI4LTIyLjQ2LTI0LjkxLDAtMTUuMDQsOC43NC0yMy41OSwyMS45LTIzLjU5Wk0zMzguMzcsMTEwLjc4Yy0uNjYtOS4xMi02Ljc3LTE0LjI5LTE1LjUxLTE0LjI5LTguMTgsMC0xNC4yOSw1LjI2LTE1LjA0LDE0LjI5aDMwLjU1WiIvPiA8cGF0aCBkPSJNMzU1LjAxLDkxLjdoNi45NnYxMi45N2MyLjU0LTguNjUsOS4xMi0xMy45MSwxOS4zNi0xMy45MXMxNi43Myw2Ljc3LDE2LjczLDE4Ljk5djI4LjU3aC03LjA1di0yOC4wMWMwLTkuNjgtMy43Ni0xMy42My0xMi4wMy0xMy42My0xMC41MywwLTE3LjAxLDguODQtMTcuMDEsMjEuMzR2MjAuM2gtNi45NnYtNDYuNjJaIi8+IDxwYXRoIGQ9Ik00MDkuODEsNzIuMDVoMjQuMzVjNi44OSwwLDEyLjk3Ljg1LDE4LjI0LDIuNTQsNS4yNiwxLjY5LDkuNTcsNC45OCwxMi45Miw5Ljg3LDMuMzUsNC44OSw1LjAzLDExLjc4LDUuMDMsMjAuNjhzLTEuNjgsMTUuODktNS4wMywyMC43N2MtMy4zNSw0Ljg5LTcuNjYsOC4xOC0xMi45Miw5Ljg3LTUuMjcsMS42OS0xMS4zNCwyLjU0LTE4LjI0LDIuNTRoLTI0LjM1di02Ni4yN1pNNDM0LjE2LDEyNS4wN2M0Ljc2LDAsOC41Ny0uMzgsMTEuNDItMS4xM3M1LjE3LTIuNTUsNi45Ni01LjQxYzEuNzktMi44NSwyLjY4LTcuMzIsMi42OC0xMy4zOXMtLjkxLTEwLjQ2LTIuNzItMTMuMzVjLTEuODItMi44OC00LjE0LTQuNy02Ljk2LTUuNDVzLTYuNjEtMS4xMy0xMS4zNy0xLjEzaC05LjMxdjM5Ljg2aDkuMzFaIi8+IDxwYXRoIGQ9Ik00ODAuMTcsMTAxLjMzYzIuMS0zLjY3LDUuMDEtNi40Nyw4Ljc0LTguNDFzOC4wMS0yLjkxLDEyLjgzLTIuOTFjNy45LDAsMTQuMDcsMi4xLDE4LjUyLDYuMyw0LjQ1LDQuMiw2LjY3LDEwLDYuNjcsMTcuMzl2My45NWgtMzUuNTNjLjI1LDMuMzgsMS4zMiw2LjAzLDMuMiw3Ljk0LDEuODgsMS45MSw0LjQ1LDIuODcsNy43MSwyLjg3LDIuODIsMCw1LjE1LS41OSw3LTEuNzksMS44NS0xLjE5LDMuMDItMi44OCwzLjUzLTUuMDhoMTQuMTljLS43NSw1LjI2LTMuMjgsOS41My03LjU3LDEyLjc4LTQuMjksMy4yNi05Ljk4LDQuODktMTcuMDYsNC44OS01LjIsMC05LjcxLTEuMDUtMTMuNTQtMy4xNS0zLjgyLTIuMS02Ljc1LTUuMDMtOC43OS04Ljc5LTIuMDQtMy43Ni0zLjA1LTguMDgtMy4wNS0xMi45N3MxLjA1LTkuMzUsMy4xNS0xMy4wMlpNNTEzLjAyLDEwOS45M2MtLjI1LTMuMDEtMS4zNi01LjMzLTMuMzQtNi45Ni0xLjk3LTEuNjMtNC41My0yLjQ0LTcuNjYtMi40NHMtNS41Ni44Mi03LjQ3LDIuNDRjLTEuOTEsMS42My0yLjk5LDMuOTUtMy4yNCw2Ljk2aDIxLjcxWiIvPiA8cGF0aCBkPSJNNTM5LjYyLDEzNC42NWMtNC4xNC0zLjA3LTYuMjEtNy41OC02LjIxLTEzLjU0aDE0LjI5YzAsMi43Ljg1LDQuNjksMi41NCw1Ljk3LDEuNjksMS4yOSw0LjI5LDEuOTMsNy44LDEuOTMsMi41NywwLDQuNDMtLjMzLDUuNTktLjk5LDEuMTYtLjY2LDEuNzQtMS43MSwxLjc0LTMuMTUsMC0xLS4zNC0xLjgyLTEuMDMtMi40NC0uNjktLjYzLTEuNzktMS4xNi0zLjI5LTEuNmwtMTQuNDgtMy45NWMtMy4yLS44MS01Ljk1LTIuMjctOC4yNy00LjM3LTIuMzItMi4xLTMuNDgtNS0zLjQ4LTguNywwLTQuNDUsMS44My03Ljg2LDUuNS0xMC4yNSwzLjY3LTIuMzgsOC43OS0zLjU3LDE1LjM3LTMuNTcsNy4yNywwLDEyLjk0LDEuNDYsMTcuMDEsNC4zN3M2LjExLDcuMTMsNi4xMSwxMi42NGgtMTQuMjljMC00LjU3LTIuOTEtNi44Ni04Ljc0LTYuODYtMi4wNywwLTMuNy4zNS00Ljg5LDEuMDMtMS4xOS42OS0xLjc5LDEuNi0xLjc5LDIuNzMsMCwxLjk0LDEuNzIsMy4zNSw1LjE3LDQuMjNsMTEuMDksMi43M2M0LjMyLDEuMDcsNy43OSwyLjcxLDEwLjM5LDQuOTQsMi42LDIuMjIsMy45LDUuMzQsMy45LDkuMzUsMCw0LjU4LTEuODMsOC4wNy01LjUsMTAuNDgtMy42NywyLjQxLTkuMSwzLjYyLTE2LjMxLDMuNjItOC4wMiwwLTE0LjEtMS41NC0xOC4yNC00LjYxWiIvPiA8cGF0aCBkPSJNNTg3LjU2LDY5LjIzaDE0LjI5djQwLjA0bDE4Ljg5LTE4LjMzaDE3LjQ4bC0yMy41OSwyMy4wMywyMy41LDI0LjM1aC0xNy4zOWwtMTguODktMTkuOTN2MTkuOTNoLTE0LjI5di02OS4wOVoiLz4gPC9nPjwvc3ZnPg==") no-repeat center; } +/* Beta overlay for Notes */ +.portal-tile[target="tab_notes"]:before { + position: absolute; + content: "Beta"; + color: #571EFA; + transform: rotate(45deg); + top: 8px; + right: 0px; + font-size: var(--font-size-5); + font-weight: bold; + z-index: 1; +} + +@media screen and (max-width: 748px) { + .portal-tile[target="tab_notes"]:before { + top: 5px; + font-size: 10px; + } + .portal-tile__name { + font-size: 13px; + } +} + +.portal-tile[target="tab_notes"]:after { + position: absolute; + content: ""; + top: 1px; + right: 1px; + border-style: solid; + border-width: 0 calc(var(--app-tile-side-length) / 2) calc(var(--app-tile-side-length) / 2) 0; + border-color: transparent #E9E4FC transparent transparent; + z-index: 0; + border-top-right-radius: calc(var(--border-radius-apptile) - 1px); +} + /* Keycloak user screens begin */ #kc-login, #kc-logout, diff --git a/helmfile_generic.yaml.gotmpl b/helmfile_generic.yaml.gotmpl index 113d7314..e1fa5105 100644 --- a/helmfile_generic.yaml.gotmpl +++ b/helmfile_generic.yaml.gotmpl @@ -32,6 +32,8 @@ helmfiles: values: *values - path: "helmfile/apps/xwiki/helmfile-child.yaml.gotmpl" values: *values + - path: "helmfile/apps/notes/helmfile-child.yaml.gotmpl" + values: *values - path: "helmfile/apps/opendesk-openproject-bootstrap/helmfile-child.yaml.gotmpl" values: *values - path: "helmfile/apps/opendesk-migrations-post/helmfile-child.yaml.gotmpl"