From 1401779a9db47001b25c40ca825748f4ab27700e Mon Sep 17 00:00:00 2001 From: Kevin Veen-Birkenbach Date: Wed, 27 Aug 2025 23:19:42 +0200 Subject: [PATCH] web-app-taiga: add manage/init flow and idempotent admin bootstrap; fix OIDC config and env quoting config/main.yml: convert oidc from empty mapping to block; indent flavor under oidc; enable javascript feature. tasks/main.yml: use path_join for taiga settings; create docker-compose-inits via TAIGA_DOCKER_COMPOSE_INIT_PATH; flush handlers; add idempotent createsuperuser via taiga-manage with async/poll and masked logs. templates/docker-compose-inits.yml.j2: include compose/container base to inherit env and project settings. templates/env.j2: quote WEB_PROTOCOL and WEBSOCKET_PROTOCOL. templates/javascript.js.j2: add SSO warning include. users/main.yml: add administrator email stub. vars/main.yml: add js_application_name; restructure OIDC flavor flags; add compose PATH vars; expose TAIGA_SUPERUSER_* vars. Chat reference: https://chatgpt.com/share/68af7637-225c-800f-b670-2b948f5dea54 --- roles/web-app-taiga/config/main.yml | 5 +-- roles/web-app-taiga/tasks/main.yml | 34 ++++++++++++++++-- .../templates/docker-compose-inits.yml.j2 | 3 +- roles/web-app-taiga/templates/env.j2 | 4 +-- .../web-app-taiga/templates/javascript.js.j2 | 1 + roles/web-app-taiga/users/main.yml | 3 ++ roles/web-app-taiga/vars/main.yml | 35 ++++++++++--------- 7 files changed, 61 insertions(+), 24 deletions(-) create mode 100644 roles/web-app-taiga/templates/javascript.js.j2 create mode 100644 roles/web-app-taiga/users/main.yml diff --git a/roles/web-app-taiga/config/main.yml b/roles/web-app-taiga/config/main.yml index a241875f..f49c2224 100644 --- a/roles/web-app-taiga/config/main.yml +++ b/roles/web-app-taiga/config/main.yml @@ -1,10 +1,10 @@ -oidc: {} +oidc: # Taiga doesn't have a functioning oidc support at the moment # See # - https://community.taiga.io/t/taiga-and-oidc-plugin/4866 # # Due to this reason this plutin is deactivated atm -flavor: 'taigaio' # Potential flavors: robrotheram, taigaio + flavor: 'taigaio' # Potential flavors: robrotheram, taigaio features: matomo: true css: true @@ -12,6 +12,7 @@ features: oidc: false central_database: true logout: true + javascript: true docker: services: database: diff --git a/roles/web-app-taiga/tasks/main.yml b/roles/web-app-taiga/tasks/main.yml index 0176300d..d5958001 100644 --- a/roles/web-app-taiga/tasks/main.yml +++ b/roles/web-app-taiga/tasks/main.yml @@ -2,18 +2,46 @@ - name: "load docker, db and proxy for {{ application_id }}" include_role: name: cmp-db-docker-proxy + vars: + docker_compose_flush_handlers: false - name: "copy templates {{ TAIGA_SETTING_FILES }} for taiga-contrib-oidc-auth" template: src: "taiga/{{item}}.py.j2" - dest: "{{ docker_compose.directories.config }}taiga-{{item}}.py" + dest: "{{ [ docker_compose.directories.config, 'taiga-' ~ item ~ '.py'] | path_join }}" when: TAIGA_TAIGAIO_ENABLED | bool notify: docker compose up loop: "{{ TAIGA_SETTING_FILES }}" -- name: "create {{ TAIGA_DOCKER_COMPOSE_INIT }}" +- name: "create {{ TAIGA_DOCKER_COMPOSE_INIT_PATH }}" template: src: "docker-compose-inits.yml.j2" - dest: "{{ TAIGA_DOCKER_COMPOSE_INIT }}" + dest: "{{ TAIGA_DOCKER_COMPOSE_INIT_PATH }}" notify: docker compose up +- name: "Flush Taiga handlers" + meta: flush_handlers + +- name: "Create Taiga admin user (idempotent)" + command: > + docker compose + -f {{ TAIGA_DOCKER_COMPOSE_PATH }} + -f {{ TAIGA_DOCKER_COMPOSE_INIT_PATH }} + run --rm taiga-manage + createsuperuser --noinput + --username {{ TAIGA_SUPERUSER_NAME }} + --email {{ TAIGA_SUPERUSER_EMAIL }} + environment: + DJANGO_SUPERUSER_PASSWORD: "{{ TAIGA_SUPERUSER_PASSWORD }}" + args: + chdir: "{{ docker_compose.directories.instance }}" + register: taiga_create_admin + changed_when: taiga_create_admin.rc == 0 + failed_when: > + taiga_create_admin.rc != 0 and + ('already taken' not in (taiga_create_admin.stdout + taiga_create_admin.stderr) | lower) and + ('already exists' not in (taiga_create_admin.stdout + taiga_create_admin.stderr) | lower) and + ('integrityerror' not in (taiga_create_admin.stdout + taiga_create_admin.stderr) | lower) + no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}" + async: "{{ ASYNC_TIME if ASYNC_ENABLED | bool else omit }}" + poll: "{{ ASYNC_POLL if ASYNC_ENABLED | bool else omit }}" \ No newline at end of file diff --git a/roles/web-app-taiga/templates/docker-compose-inits.yml.j2 b/roles/web-app-taiga/templates/docker-compose-inits.yml.j2 index c1e5ca0c..a5db2c00 100644 --- a/roles/web-app-taiga/templates/docker-compose-inits.yml.j2 +++ b/roles/web-app-taiga/templates/docker-compose-inits.yml.j2 @@ -1,5 +1,6 @@ -services: +{% include 'roles/docker-compose/templates/base.yml.j2' %} taiga-manage: +{% include 'roles/docker-container/templates/base.yml.j2' %} image: taigaio/taiga-back:latest environment: CELERY_ENABLED: "False" diff --git a/roles/web-app-taiga/templates/env.j2 b/roles/web-app-taiga/templates/env.j2 index 1658e7f6..0f4f3d33 100644 --- a/roles/web-app-taiga/templates/env.j2 +++ b/roles/web-app-taiga/templates/env.j2 @@ -1,9 +1,9 @@ # Taiga's URLs - Variables to define where Taiga should be served -TAIGA_SITES_SCHEME = {{ WEB_PROTOCOL }} # serve Taiga using "http" or "https" (secured) connection +TAIGA_SITES_SCHEME = "{{ WEB_PROTOCOL }}" # serve Taiga using "http" or "https" (secured) connection TAIGA_SITES_DOMAIN = "{{ domains | get_domain(application_id) }}" # Taiga's base URL TAIGA_SUBPATH = "" # it'll be appended to the TAIGA_DOMAIN (use either "" or a "/subpath") -WEBSOCKETS_SCHEME = {{ WEBSOCKET_PROTOCOL }} # events connection protocol (use either "ws" or "wss") +WEBSOCKETS_SCHEME = "{{ WEBSOCKET_PROTOCOL }}" # events connection protocol (use either "ws" or "wss") # Taiga's Secret Key - Variable to provide cryptographic signing TAIGA_SECRET_KEY = "{{ applications | get_app_conf(application_id, 'credentials.secret_key') }}" diff --git a/roles/web-app-taiga/templates/javascript.js.j2 b/roles/web-app-taiga/templates/javascript.js.j2 new file mode 100644 index 00000000..26bb609c --- /dev/null +++ b/roles/web-app-taiga/templates/javascript.js.j2 @@ -0,0 +1 @@ +{% include 'templates/roles/web-app/templates/javascripts/sso_warning.js.j2' %} diff --git a/roles/web-app-taiga/users/main.yml b/roles/web-app-taiga/users/main.yml new file mode 100644 index 00000000..6374b715 --- /dev/null +++ b/roles/web-app-taiga/users/main.yml @@ -0,0 +1,3 @@ +users: + administrator: + email: "administrator@{{ PRIMARY_DOMAIN }}" \ No newline at end of file diff --git a/roles/web-app-taiga/vars/main.yml b/roles/web-app-taiga/vars/main.yml index ba0f9ebf..4f742087 100644 --- a/roles/web-app-taiga/vars/main.yml +++ b/roles/web-app-taiga/vars/main.yml @@ -1,24 +1,27 @@ # General application_id: "web-app-taiga" database_type: "postgres" +js_application_name: "Taiga" # Docker docker_repository_address: "https://github.com/taigaio/taiga-docker" docker_pull_git_repository: true -# Taiga -TAIGA_OIDC_ENABLED: "{{ applications | get_app_conf(application_id, 'features.oidc') }}" -TAIGA_FLAVOR_ROBROTHERAM: "{{ applications | get_app_conf(application_id, 'oidc.flavor') == 'robrotheram' }}" -TAIGA_ROBROTHERAM_ENABLED: "{{ TAIGA_OIDC_ENABLED and TAIGA_FLAVOR_ROBROTHERAM }}" -TAIGA_FLAVOR_TAIGAIO: "{{ applications | get_app_conf(application_id, 'oidc.flavor') == 'taigaio' }}" -TAIGA_TAIGAIO_ENABLED: "{{ TAIGA_OIDC_ENABLED and TAIGA_FLAVOR_TAIGAIO }}" -TAIGA_EMAIL_BACKEND: "{{ 'smtp' if SYSTEM_EMAIL.SMTP else 'console' }}" ## use an SMTP server or display the emails in the console (either "smtp" or "console") -TAIGA_DOCKER_COMPOSE_INIT: "{{ [ docker_compose.directories.instance,'docker-compose-inits.yml.j2' ] | path_join }}" -TAIGA_DOCKER_IMAGE_BACKEND: "{{ 'robrotheram/taiga-back-openid' if TAIGA_ROBROTHERAM_ENABLED else 'taigaio/taiga-back' }}" -TAIGA_DOCKER_IMAGE_FRONTEND: "{{ 'robrotheram/taiga-front-openid' if TAIGA_ROBROTHERAM_ENABLED else 'taigaio/taiga-front' }}" -TAIGA_FRONTEND_CONF_PATH: "{{ [ docker_compose.directories.config,'conf.json' ] | path_join }}" -TAIGA_SETTING_FILES: -- urls -- local - -TAIGA_VERSION: "{{ applications | get_app_conf(application_id, 'docker.services.taiga.version') }}" \ No newline at end of file +# Taiga +TAIGA_OIDC_ENABLED: "{{ applications | get_app_conf(application_id, 'features.oidc') }}" +TAIGA_OIDC_FLAVOR: "{{ applications | get_app_conf(application_id, 'oidc.flavor') }}" +TAIGA_FLAVOR_ROBROTHERAM: "{{ TAIGA_OIDC_FLAVOR == 'robrotheram' }}" +TAIGA_ROBROTHERAM_ENABLED: "{{ TAIGA_OIDC_ENABLED and TAIGA_FLAVOR_ROBROTHERAM }}" +TAIGA_FLAVOR_TAIGAIO: "{{ TAIGA_OIDC_FLAVOR == 'taigaio' }}" +TAIGA_TAIGAIO_ENABLED: "{{ TAIGA_OIDC_ENABLED and TAIGA_FLAVOR_TAIGAIO }}" +TAIGA_EMAIL_BACKEND: "{{ 'smtp' if SYSTEM_EMAIL.SMTP else 'console' }}" ## use an SMTP server or display the emails in the console (either "smtp" or "console") +TAIGA_DOCKER_COMPOSE_INIT_PATH: "{{ [ docker_compose.directories.instance,'docker-compose-inits.yml' ] | path_join }}" +TAIGA_DOCKER_COMPOSE_PATH: "{{ [ docker_compose.directories.instance,'docker-compose.yml' ] | path_join }}" +TAIGA_DOCKER_IMAGE_BACKEND: "{{ 'robrotheram/taiga-back-openid' if TAIGA_ROBROTHERAM_ENABLED else 'taigaio/taiga-back' }}" +TAIGA_DOCKER_IMAGE_FRONTEND: "{{ 'robrotheram/taiga-front-openid' if TAIGA_ROBROTHERAM_ENABLED else 'taigaio/taiga-front' }}" +TAIGA_FRONTEND_CONF_PATH: "{{ [ docker_compose.directories.config,'conf.json' ] | path_join }}" +TAIGA_VERSION: "{{ applications | get_app_conf(application_id, 'docker.services.taiga.version') }}" +TAIGA_SUPERUSER_NAME: "{{ users.administrator.username }}" +TAIGA_SUPERUSER_PASSWORD: "{{ users.administrator.password }}" +TAIGA_SUPERUSER_EMAIL: "{{ users.administrator.email }}" +TAIGA_SETTING_FILES: ['urls','local']