diff --git a/.github/workflows/docker-hub.yml b/.github/workflows/docker-hub.yml index b04ff69a3..e53ffc70f 100644 --- a/.github/workflows/docker-hub.yml +++ b/.github/workflows/docker-hub.yml @@ -9,12 +9,17 @@ on: tags: - "v*" pull_request: + types: + - opened + - synchronize + - reopened + - labeled branches: - "main" env: DOCKER_USER: 1001:127 - SHOULD_PUSH: ${{ github.event_name != 'pull_request' }} + SHOULD_PUSH: ${{ github.event_name != 'pull_request' || contains(github.event.pull_request.labels.*.name, 'preview') }} jobs: build-and-push-backend: @@ -101,7 +106,7 @@ jobs: - build-and-push-frontend - build-and-push-backend runs-on: ubuntu-latest - if: github.event_name != 'pull_request' + if: github.event_name != 'pull_request' || contains(github.event.pull_request.labels.*.name, 'preview') steps: - uses: numerique-gouv/action-argocd-webhook-notification@main id: notify diff --git a/.github/workflows/label_preview.yml b/.github/workflows/label_preview.yml new file mode 100644 index 000000000..568fbd259 --- /dev/null +++ b/.github/workflows/label_preview.yml @@ -0,0 +1,27 @@ +name: Label Preview + +on: + pull_request: + types: [labeled, opened] + +permissions: + pull-requests: write + +jobs: + comment: + runs-on: ubuntu-latest + if: contains(github.event.pull_request.labels.*.name, 'preview') + steps: + - uses: thollander/actions-comment-pull-request@24bffb9b452ba05a4f3f77933840a6a841d1b32b # v3 + with: + message: | + :rocket: Preview will be available at [https://${{ github.event.pull_request.number }}-drive.ppr-fichiers.beta.numerique.gouv.fr/](https://${{ github.event.pull_request.number }}-drive.ppr-fichiers.beta.numerique.gouv.fr/) + + You can use the existing account with these credentials: + - username: `drive` + - password: `drive` + + You can also create a new account if you want to. + + Once this Pull Request is merged, the preview will be destroyed. + comment-tag: preview-url diff --git a/src/helm/env.d/dev/values.dev-backend.yaml.gotmpl b/src/helm/env.d/dev/values.dev-backend.yaml.gotmpl new file mode 100644 index 000000000..22cb5531b --- /dev/null +++ b/src/helm/env.d/dev/values.dev-backend.yaml.gotmpl @@ -0,0 +1,105 @@ +postgres: + enabled: true + name: postgres + #serviceNameOverride: postgres + image: postgres:16-alpine + username: dinum + password: pass + database: dinum + size: 1Gi +redis: + enabled: true + name: redis + #serviceNameOverride: redis + image: redis:8.2-alpine + username: user + password: pass +minio: + enabled: true + image: minio/minio + name: minio + # serviceNameOverride: drive-minio + ingress: + enabled: true + hostname: drive-minio.127.0.0.1.nip.io + tls: + enabled: true + secretName: drive-tls + consoleIngress: + enabled: true + hostname: drive-minio-console.127.0.0.1.nip.io + tls: + enabled: true + secretName: drive-tls + api: + port: 80 + username: dinum + password: password + bucket: drive-media-storage + versioning: true + size: 1Gi +keycloak: + enabled: true + image: quay.io/keycloak/keycloak:20.0.1 + name: keycloak + #serviceNameOverride: keycloak + hostname: drive-keycloak.127.0.0.1.nip.io + username: admin + password: pass + tls: + enabled: true + secretName: drive-tls + db: + username: dinum + password: pass + database: keycloak + size: 1Gi + image: postgres:16-alpine + realm: + name: drive + username: drive + password: drive + email: drive@example.com +dsproxy: + enabled: false + aws_url: https://drive-minio.127.0.0.1.nip.io + image: demarchenumerique/ds-proxy:v2.0.0-alpha.2 + command: + - /bin/sh + - "-c" + - | + /dsproxy/ds_proxy proxy --address=0.0.0.0:4444 --verify-ssl-certificate=false --password-file /etc/dsproxy/PASSWORD \ + --salt "$SALT" --keyring-file /etc/dsproxy/keyring.toml --upstream-url ${AWS_URL} \ + --local-encryption-directory /var/tmp/local_encryption/ --s3-access-key ${AWS_ACCESS_KEY} \ + --s3-secret-key ${AWS_SECRET_KEY} --s3-region ${AWS_REGION} + # Extra volume mounts to manage our local custom CA and avoid to set ssl_verify: false + ingress: + enabled: true + hostname: drive-dsproxy.127.0.0.1.nip.io + tls: + enabled: true + localSecret: + enabled: true + envVars: + RUST_LOG: debug,ds_proxy::http::handlers::fetch=trace,ds_proxy::http::handlers::forward=trace,ds_proxy::config=trace + RUST_BACKTRACE: full + SALT: + secretKeyRef: + name: dev-backend-dsproxy + key: SALT + AWS_ACCESS_KEY: + secretKeyRef: + name: dev-backend-dsproxy + key: AWS_ACCESS_KEY + AWS_SECRET_KEY: + secretKeyRef: + name: dev-backend-dsproxy + key: AWS_SECRET_KEY + AWS_URL: + secretKeyRef: + name: dev-backend-dsproxy + key: AWS_URL + AWS_REGION: + secretKeyRef: + name: dev-backend-dsproxy + key: AWS_REGION diff --git a/src/helm/env.d/feature/values.dev-backend.yaml.gotmpl b/src/helm/env.d/feature/values.dev-backend.yaml.gotmpl new file mode 100644 index 000000000..b3b006c5f --- /dev/null +++ b/src/helm/env.d/feature/values.dev-backend.yaml.gotmpl @@ -0,0 +1,63 @@ +postgres: + enabled: true + name: postgres + #serviceNameOverride: postgres + image: postgres:16-alpine + username: dinum + password: pass + database: dinum + size: 1Gi +redis: + enabled: true + name: redis + #serviceNameOverride: redis + image: redis:8.2-alpine + username: user + password: pass +minio: + enabled: true + image: minio/minio + name: minio + ingress: + enabled: true + hostname: {{ .Values.feature }}-drive-minio.{{ .Values.domain }} + tls: + enabled: true + secretName: drive-tls + consoleIngress: + enabled: true + hostname: {{ .Values.feature }}-drive-minio-console.{{ .Values.domain }} + tls: + enabled: true + secretName: drive-tls + username: dinum + password: password + bucket: drive-media-storage + versioning: true + size: 1Gi +keycloak: + enabled: true + image: quay.io/keycloak/keycloak:20.0.1 + name: keycloak + annotations: + cert-manager.io/cluster-issuer: letsencrypt + #serviceNameOverride: keycloak + hostname: {{ .Values.feature }}-drive-keycloak.{{ .Values.domain }} + username: admin + password: pass + tls: + enabled: true + secretName: drive-tls + db: + username: dinum + password: pass + database: keycloak + size: 1Gi + image: postgres:16-alpine + realm: + name: drive + username: drive + password: drive + email: drive@example.com +dsproxy: + enabled: false diff --git a/src/helm/env.d/feature/values.drive.yaml.gotmpl b/src/helm/env.d/feature/values.drive.yaml.gotmpl new file mode 100644 index 000000000..901910385 --- /dev/null +++ b/src/helm/env.d/feature/values.drive.yaml.gotmpl @@ -0,0 +1,224 @@ +djangoSecretKey: &djangoSecretKey "lkjsdlfkjsldkfjslkdfjslkdjfslkdjf" +tag: &tag "{{ .Values.imageTag }}" +djangoSuperUserEmail: admin@example.com +djangoSuperUserPass: admin +oidc: + clientId: drive + clientSecret: ThisIsAnExampleKeyForDevPurposeOnly + +image: + repository: lasuite/drive-backend + pullPolicy: Always + tag: *tag + +backend: + replicas: 1 + envVars: + DJANGO_CSRF_TRUSTED_ORIGINS: https://{{ .Values.feature }}-drive.{{ .Values.domain }} + DJANGO_CONFIGURATION: Feature + DJANGO_ALLOWED_HOSTS: {{ .Values.feature }}-drive.{{ .Values.domain }} + DJANGO_SERVER_TO_SERVER_API_TOKENS: secret-api-key + DJANGO_SECRET_KEY: *djangoSecretKey + DJANGO_SETTINGS_MODULE: drive.settings + DJANGO_SUPERUSER_PASSWORD: admin + DJANGO_EMAIL_BRAND_NAME: "La Suite Numérique" + DJANGO_EMAIL_HOST: "mailcatcher" + DJANGO_EMAIL_LOGO_IMG: https://{{ .Values.feature }}-drive.{{ .Values.domain }}/assets/logo-suite-numerique.png + DJANGO_EMAIL_PORT: 1025 + DJANGO_EMAIL_URL_APP: https://{{ .Values.feature }}-drive.{{ .Values.domain }} + DJANGO_EMAIL_USE_SSL: False + USER_RECONCILIATION_FORM_URL: https://{{ .Values.feature }}-drive.{{ .Values.domain }} + LOGGING_LEVEL_LOGGERS_ROOT: DEBUG + LOGGING_LEVEL_LOGGERS_APP: DEBUG + OIDC_OP_JWKS_ENDPOINT: https://{{ .Values.feature }}-drive-keycloak.{{ .Values.domain }}/realms/drive/protocol/openid-connect/certs + OIDC_OP_AUTHORIZATION_ENDPOINT: https://{{ .Values.feature }}-drive-keycloak.{{ .Values.domain }}/realms/drive/protocol/openid-connect/auth + OIDC_OP_TOKEN_ENDPOINT: https://{{ .Values.feature }}-drive-keycloak.{{ .Values.domain }}/realms/drive/protocol/openid-connect/token + OIDC_OP_USER_ENDPOINT: https://{{ .Values.feature }}-drive-keycloak.{{ .Values.domain }}/realms/drive/protocol/openid-connect/userinfo + OIDC_OP_LOGOUT_ENDPOINT: https://{{ .Values.feature }}-drive-keycloak.{{ .Values.domain }}/realms/drive/protocol/openid-connect/logout + OIDC_RP_CLIENT_ID: drive + OIDC_RP_CLIENT_SECRET: ThisIsAnExampleKeyForDevPurposeOnly + OIDC_RP_SIGN_ALGO: RS256 + OIDC_RP_SCOPES: "openid email" + OIDC_USER_FIELD_TO_SHORTNAME: "given_name" + OIDC_USER_FIELDS_TO_FULLNAME: "given_name,usual_name" + LOGIN_REDIRECT_URL: https://{{ .Values.feature }}-drive.{{ .Values.domain }} + LOGIN_REDIRECT_URL_FAILURE: https://{{ .Values.feature }}-drive.{{ .Values.domain }} + LOGOUT_REDIRECT_URL: https://{{ .Values.feature }}-drive.{{ .Values.domain }} + DB_HOST: dev-backend-postgres + DB_NAME: + secretKeyRef: + name: dev-backend-postgres + key: database + DB_USER: + secretKeyRef: + name: dev-backend-postgres + key: username + DB_PASSWORD: + secretKeyRef: + name: dev-backend-postgres + key: password + DB_PORT: 5432 + REDIS_URL: redis://user:pass@dev-backend-redis:6379/1 + DJANGO_CELERY_BROKER_URL: redis://user:pass@dev-backend-redis:6379/1 + AWS_S3_ENDPOINT_URL: http://dev-backend-minio.{{ .Namespace }}.svc.cluster.local:9000 + AWS_S3_ACCESS_KEY_ID: dinum + AWS_S3_SECRET_ACCESS_KEY: password + AWS_S3_SIGNATURE_VERSION: s3v4 + AWS_S3_REGION_NAME: eu-east-1 + AWS_STORAGE_BUCKET_NAME: drive-media-storage + STORAGES_STATICFILES_BACKEND: django.contrib.staticfiles.storage.StaticFilesStorage + MEDIA_BASE_URL: https://{{ .Values.feature }}-drive.{{ .Values.domain }} + DJANGO_CELERY_TASK_ROUTES: "{'core.tasks.storage.mirror_file': {'queue': 'mirror'}, 'lasuite.malware_detection.tasks.*': {'queue': 'malware_detection'}}" + WOPI_CLIENTS: "onlyoffice" + WOPI_ONLYOFFICE_CONVERT_JWT_SECRET: ThisIsAnExampleKeyForDevPurposeOnly + WOPI_ONLYOFFICE_DISCOVERY_URL: https://onlyoffice-feature.{{ .Values.domain }}/hosting/discovery + WOPI_SRC_BASE_URL: https://{{ .Values.feature }}-drive.{{ .Values.domain }} + WOPI_ONLYOFFICE_OPTIONS: '{"ForceConvertExtensions": ["doc", "xls", "ppt"], "ConvertServiceUrl": "https://onlyoffice-feature.{{ .Values.domain }}/converter"}' + CACHES_DEFAULT_KEY_PREFIX: "{{ .Values.imageTag }}" + migrate: + command: + - "/bin/sh" + - "-c" + - | + while ! python manage.py check --database default > /dev/null 2>&1 + do + echo "Database not ready" + sleep 2 + done + + echo "Database is ready" + + python manage.py migrate --no-input + restartPolicy: Never + + command: + - "gunicorn" + - "-c" + - "/usr/local/etc/gunicorn/drive.py" + - "drive.wsgi:application" + + createsuperuser: + command: + - "/bin/sh" + - "-c" + - | + while ! python manage.py check --database default > /dev/null 2>&1 + do + echo "Database not ready" + sleep 2 + done + + echo "Database is ready" + python manage.py createsuperuser --email admin@example.com --password admin + restartPolicy: Never + + # Extra volume mounts to manage our local custom CA and avoid to set ssl_verify: false + extraVolumeMounts: {} + + # Extra volumes to manage our local custom CA and avoid to set ssl_verify: false + extraVolumes: {} + + celeryWorkers: + - name: default + replicas: 1 + command: [] + args: ["celery", "-A", "drive.celery_app", "worker", "-l", "INFO", "-n", "drive@%h"] + resources: {} + probes: + liveness: + exec: + command: ["/bin/sh", "-c", "celery -A drive.celery_app inspect ping -d drive@$HOSTNAME"] + initialDelaySeconds: 60 + timeoutSeconds: 5 + readiness: + exec: + command: ["/bin/sh", "-c", "celery -A drive.celery_app inspect ping -d drive@$HOSTNAME"] + initialDelaySeconds: 15 + timeoutSeconds: 5 + - name: mirror + replicas: 1 + command: [] + args: ["celery", "-A", "drive.celery_app", "worker", "-l", "INFO", "-Q", "mirror", "-n", "drive@%h"] + resources: {} + probes: + liveness: + exec: + command: ["/bin/sh", "-c", "celery -A drive.celery_app inspect ping -d drive@$HOSTNAME"] + initialDelaySeconds: 60 + timeoutSeconds: 5 + readiness: + exec: + command: ["/bin/sh", "-c", "celery -A drive.celery_app inspect ping -d drive@$HOSTNAME"] + initialDelaySeconds: 15 + timeoutSeconds: 5 + - name: malware-detection + replicas: 1 + command: [] + args: ["celery", "-A", "drive.celery_app", "worker", "-l", "INFO", "-Q", "malware_detection", "-n", "drive@%h"] + resources: {} + probes: + liveness: + exec: + command: ["/bin/sh", "-c", "celery -A drive.celery_app inspect ping -d drive@$HOSTNAME"] + initialDelaySeconds: 60 + timeoutSeconds: 5 + readiness: + exec: + command: ["/bin/sh", "-c", "celery -A drive.celery_app inspect ping -d drive@$HOSTNAME"] + initialDelaySeconds: 15 + timeoutSeconds: 5 + +frontend: + envVars: + PORT: 8080 + NEXT_PUBLIC_API_ORIGIN: https://{{ .Values.feature }}-drive.{{ .Values.domain }} + + replicas: 1 + + image: + repository: lasuite/drive-frontend + pullPolicy: Always + tag: *tag + + +ingress: + enabled: true + host: {{ .Values.feature }}-drive.{{ .Values.domain }} + annotations: + nginx.ingress.kubernetes.io/proxy-body-size: 150m + cert-manager.io/cluster-issuer: letsencrypt + +ingressAdmin: + enabled: true + host: {{ .Values.feature }}-drive.{{ .Values.domain }} + +posthog: + ingress: + enabled: false + + ingressAssets: + enabled: false + +ingressMedia: + enabled: true + host: {{ .Values.feature }}-drive.{{ .Values.domain }} + + annotations: + nginx.ingress.kubernetes.io/auth-url: https://{{ .Values.feature }}-drive.{{ .Values.domain }}/api/v1.0/items/media-auth/ + nginx.ingress.kubernetes.io/auth-response-headers: "Authorization, X-Amz-Date, X-Amz-Content-SHA256" + nginx.ingress.kubernetes.io/upstream-vhost: dev-backend-minio.{{ .Namespace }}.svc.cluster.local:9000 + nginx.ingress.kubernetes.io/rewrite-target: /drive-media-storage/$1 + +ingressMediaPreview: + enabled: true + host: {{ .Values.feature }}-drive.{{ .Values.domain }} + + annotations: + nginx.ingress.kubernetes.io/auth-url: https://{{ .Values.feature }}-drive.{{ .Values.domain }}/api/v1.0/items/media-auth/ + nginx.ingress.kubernetes.io/auth-response-headers: "Authorization, X-Amz-Date, X-Amz-Content-SHA256" + nginx.ingress.kubernetes.io/upstream-vhost: dev-backend-minio.{{ .Namespace }}.svc.cluster.local:9000 + nginx.ingress.kubernetes.io/rewrite-target: /drive-media-storage/$1 + +serviceMedia: + host: dev-backend-minio.{{ .Namespace }}.svc.cluster.local + port: 9000 diff --git a/src/helm/helmfile.yaml.gotmpl b/src/helm/helmfile.yaml.gotmpl index 818397eb4..9fa5a704f 100644 --- a/src/helm/helmfile.yaml.gotmpl +++ b/src/helm/helmfile.yaml.gotmpl @@ -2,6 +2,12 @@ environments: dev: values: - version: 0.21.0 + feature: + values: + - version: 0.21.0 + feature: ci + domain: example.com + imageTag: demo --- repositories: - name: dev-backends @@ -14,111 +20,7 @@ releases: chart: dev-backends/dev-backend version: 0.0.6 values: - - postgres: - enabled: true - name: postgres - #serviceNameOverride: postgres - image: postgres:16-alpine - username: dinum - password: pass - database: dinum - size: 1Gi - - redis: - enabled: true - name: redis - #serviceNameOverride: redis - image: redis:8.2-alpine - username: user - password: pass - - minio: - enabled: true - image: minio/minio - name: minio - # serviceNameOverride: drive-minio - ingress: - enabled: true - hostname: drive-minio.127.0.0.1.nip.io - tls: - enabled: true - secretName: drive-tls - consoleIngress: - enabled: true - hostname: drive-minio-console.127.0.0.1.nip.io - tls: - enabled: true - secretName: drive-tls - api: - port: 80 - username: dinum - password: password - bucket: drive-media-storage - versioning: true - size: 1Gi - - keycloak: - enabled: true - image: quay.io/keycloak/keycloak:20.0.1 - name: keycloak - #serviceNameOverride: keycloak - hostname: drive-keycloak.127.0.0.1.nip.io - username: admin - password: pass - tls: - enabled: true - secretName: drive-tls - db: - username: dinum - password: pass - database: keycloak - size: 1Gi - image: postgres:16-alpine - realm: - name: drive - username: drive - password: drive - email: drive@example.com - - dsproxy: - enabled: false - aws_url: https://drive-minio.127.0.0.1.nip.io - image: demarchenumerique/ds-proxy:v2.0.0-alpha.2 - command: - - /bin/sh - - "-c" - - | - /dsproxy/ds_proxy proxy --address=0.0.0.0:4444 --verify-ssl-certificate=false --password-file /etc/dsproxy/PASSWORD \ - --salt "$SALT" --keyring-file /etc/dsproxy/keyring.toml --upstream-url ${AWS_URL} \ - --local-encryption-directory /var/tmp/local_encryption/ --s3-access-key ${AWS_ACCESS_KEY} \ - --s3-secret-key ${AWS_SECRET_KEY} --s3-region ${AWS_REGION} - # Extra volume mounts to manage our local custom CA and avoid to set ssl_verify: false - ingress: - enabled: true - hostname: drive-dsproxy.127.0.0.1.nip.io - tls: - enabled: true - localSecret: - enabled: true - envVars: - RUST_LOG: debug,ds_proxy::http::handlers::fetch=trace,ds_proxy::http::handlers::forward=trace,ds_proxy::config=trace - RUST_BACKTRACE: full - SALT: - secretKeyRef: - name: dev-backend-dsproxy - key: SALT - AWS_ACCESS_KEY: - secretKeyRef: - name: dev-backend-dsproxy - key: AWS_ACCESS_KEY - AWS_SECRET_KEY: - secretKeyRef: - name: dev-backend-dsproxy - key: AWS_SECRET_KEY - AWS_URL: - secretKeyRef: - name: dev-backend-dsproxy - key: AWS_URL - AWS_REGION: - secretKeyRef: - name: dev-backend-dsproxy - key: AWS_REGION + - env.d/{{ .Environment.Name }}/values.dev-backend.yaml.gotmpl - name: drive version: {{ .Values.version }}